//checked includes match cerberus output #include maps/mp/killstreaks/_helicopter; #include maps/mp/gametypes/_hostmigration; #include maps/mp/_tacticalinsertion; #include maps/mp/gametypes/_weaponobjects; #include maps/mp/_scoreevents; #include maps/mp/_challenges; #include maps/mp/_hacker_tool; #include maps/mp/killstreaks/_emp; #include maps/mp/killstreaks/_supplydrop; #include maps/mp/_entityheadicons; #include maps/mp/gametypes/_gameobjects; #include maps/mp/killstreaks/_killstreakrules; #include maps/mp/killstreaks/_killstreak_weapons; #include maps/mp/gametypes/_weapons; #include maps/mp/_popups; #include maps/mp/gametypes/_callbacksetup; #include maps/mp/killstreaks/_ai_tank; #include maps/mp/killstreaks/_killstreaks; #include maps/mp/killstreaks/_airsupport; #include maps/mp/gametypes/_hud_util; #include maps/mp/_utility; #include common_scripts/utility; #using_animtree( "mp_vehicles" ); //remove when compiling will cause issues otherwise because the compiler doesn't support it init() //checked changed to match cerberus output { level.cratemodelfriendly = "t6_wpn_supply_drop_ally"; level.cratemodelenemy = "t6_wpn_supply_drop_axis"; level.cratemodelhacker = "t6_wpn_supply_drop_detect"; level.cratemodeltank = "t6_wpn_drop_box"; level.cratemodelboobytrapped = "t6_wpn_supply_drop_trap"; level.supplydrophelicopterfriendly = "veh_t6_drone_supply"; level.supplydrophelicopterenemy = "veh_t6_drone_supply_alt"; level.suppydrophelicoptervehicleinfo = "heli_supplydrop_mp"; level.crateownerusetime = 500; level.cratenonownerusetime = getgametypesetting( "crateCaptureTime" ) * 1000; level.crate_headicon_offset = vectorScale( ( 0, 0, 1 ), 15 ); level.supplydropdisarmcrate = &"KILLSTREAK_SUPPLY_DROP_DISARM_HINT"; level.disarmingcrate = &"KILLSTREAK_SUPPLY_DROP_DISARMING_CRATE"; level.supplydropcarepackageidleanim = %o_drone_supply_care_idle; level.supplydropcarepackagedropanim = %o_drone_supply_care_drop; level.supplydropaitankidleanim = %o_drone_supply_agr_idle; level.supplydropaitankdropanim = %o_drone_supply_agr_drop; precachemodel( level.cratemodelfriendly ); precachemodel( level.cratemodelenemy ); precachemodel( level.cratemodelhacker ); precachemodel( level.cratemodeltank ); precachemodel( level.cratemodelboobytrapped ); precachemodel( level.supplydrophelicopterfriendly ); precachemodel( level.supplydrophelicopterenemy ); precachevehicle( level.suppydrophelicoptervehicleinfo ); precacheshader( "compass_supply_drop_black" ); precacheshader( "compass_supply_drop_green" ); precacheshader( "compass_supply_drop_red" ); precacheshader( "waypoint_recon_artillery_strike" ); precacheshader( "hud_ks_minigun" ); precacheshader( "hud_ks_minigun_drop" ); precacheshader( "hud_ks_m32" ); precacheshader( "hud_ks_m32_drop" ); precacheshader( "hud_ks_m202" ); precacheshader( "hud_ks_m202_drop" ); precacheshader( "hud_ammo_refill" ); precacheshader( "hud_ammo_refill_drop" ); precacheshader( "hud_ks_ai_tank_drop" ); precachestring( &"KILLSTREAK_CAPTURING_CRATE" ); precachestring( &"KILLSTREAK_SUPPLY_DROP_DISARM_HINT" ); precachestring( &"KILLSTREAK_SUPPLY_DROP_DISARMING_CRATE" ); precacheshader( "headicon_dead" ); registerclientfield( "helicopter", "supplydrop_care_package_state", 1, 1, "int" ); registerclientfield( "helicopter", "supplydrop_ai_tank_state", 1, 1, "int" ); level._supply_drop_smoke_fx = loadfx( "env/smoke/fx_smoke_supply_drop_blue_mp" ); level._supply_drop_explosion_fx = loadfx( "explosions/fx_grenadeexp_default" ); maps/mp/killstreaks/_killstreaks::registerkillstreak( "inventory_supply_drop_mp", "inventory_supplydrop_mp", "killstreak_supply_drop", "supply_drop_used", ::usekillstreaksupplydrop, undefined, 1 ); maps/mp/killstreaks/_killstreaks::registerkillstreakstrings( "inventory_supply_drop_mp", &"KILLSTREAK_EARNED_SUPPLY_DROP", &"KILLSTREAK_AIRSPACE_FULL", &"KILLSTREAK_SUPPLY_DROP_INBOUND" ); maps/mp/killstreaks/_killstreaks::registerkillstreakdialog( "inventory_supply_drop_mp", "mpl_killstreak_supply", "kls_supply_used", "", "kls_supply_enemy", "", "kls_supply_ready" ); maps/mp/killstreaks/_killstreaks::registerkillstreakaltweapon( "inventory_supply_drop_mp", "mp40_blinged_mp" ); maps/mp/killstreaks/_killstreaks::allowkillstreakassists( "inventory_supply_drop_mp", 1 ); maps/mp/killstreaks/_killstreaks::registerkillstreakdevdvar( "inventory_supply_drop_mp", "scr_givesupplydrop" ); maps/mp/killstreaks/_killstreaks::registerkillstreak( "supply_drop_mp", "supplydrop_mp", "killstreak_supply_drop", "supply_drop_used", ::usekillstreaksupplydrop, undefined, 1 ); maps/mp/killstreaks/_killstreaks::registerkillstreakstrings( "supply_drop_mp", &"KILLSTREAK_EARNED_SUPPLY_DROP", &"KILLSTREAK_AIRSPACE_FULL", &"KILLSTREAK_SUPPLY_DROP_INBOUND" ); maps/mp/killstreaks/_killstreaks::registerkillstreakdialog( "supply_drop_mp", "mpl_killstreak_supply", "kls_supply_used", "", "kls_supply_enemy", "", "kls_supply_ready" ); maps/mp/killstreaks/_killstreaks::registerkillstreakaltweapon( "supply_drop_mp", "mp40_blinged_mp" ); maps/mp/killstreaks/_killstreaks::allowkillstreakassists( "supply_drop_mp", 1 ); level.cratetypes = []; level.categorytypeweight = []; registercratetype( "ai_tank_drop_mp", "killstreak", "ai_tank_mp", 1, &"KILLSTREAK_AI_TANK_CRATE", undefined, undefined, undefined, maps/mp/killstreaks/_ai_tank::crateland ); registercratetype( "inventory_ai_tank_drop_mp", "killstreak", "ai_tank_mp", 1, &"KILLSTREAK_AI_TANK_CRATE", undefined, undefined, undefined, maps/mp/killstreaks/_ai_tank::crateland ); registercratetype( "minigun_drop_mp", "killstreak", "minigun_mp", 1, &"KILLSTREAK_MINIGUN_CRATE", &"PLATFORM_MINIGUN_GAMBLER", "share_package_death_machine", ::givecrateweapon ); registercratetype( "inventory_minigun_drop_mp", "killstreak", "minigun_mp", 1, &"KILLSTREAK_MINIGUN_CRATE", &"PLATFORM_MINIGUN_GAMBLER", "share_package_death_machine", ::givecrateweapon ); registercratetype( "m32_drop_mp", "killstreak", "m32_mp", 1, &"KILLSTREAK_M32_CRATE", &"PLATFORM_M32_GAMBLER", "share_package_multiple_grenade_launcher", ::givecrateweapon ); registercratetype( "inventory_m32_drop_mp", "killstreak", "m32_mp", 1, &"KILLSTREAK_M32_CRATE", &"PLATFORM_M32_GAMBLER", "share_package_multiple_grenade_launcher", ::givecrateweapon ); registercratetype( "supplydrop_mp", "killstreak", "radar_mp", 100, &"KILLSTREAK_RADAR_CRATE", &"PLATFORM_RADAR_GAMBLER", "share_package_uav", ::givecratekillstreak ); registercratetype( "supplydrop_mp", "killstreak", "rcbomb_mp", 100, &"KILLSTREAK_RCBOMB_CRATE", &"PLATFORM_RCBOMB_GAMBLER", "share_package_rcbomb", ::givecratekillstreak ); registercratetype( "supplydrop_mp", "killstreak", "inventory_missile_drone_mp", 100, &"KILLSTREAK_MISSILE_DRONE_CRATE", &"PLATFORM_MISSILE_DRONE_GAMBLER", "share_package_missile_drone", ::givecratekillstreak ); registercratetype( "supplydrop_mp", "killstreak", "counteruav_mp", 100, &"KILLSTREAK_COUNTERU2_CRATE", &"PLATFORM_COUNTERU2_GAMBLER", "share_package_counter_uav", ::givecratekillstreak ); registercratetype( "supplydrop_mp", "killstreak", "remote_missile_mp", 85, &"KILLSTREAK_REMOTE_MISSILE_CRATE", &"PLATFORM_REMOTE_MISSILE_GAMBLER", "share_package_remote_missile", ::givecratekillstreak ); registercratetype( "supplydrop_mp", "killstreak", "planemortar_mp", 80, &"KILLSTREAK_PLANE_MORTAR_CRATE", &"PLATFORM_PLANE_MORTAR_GAMBLER", "share_package_plane_mortar", ::givecratekillstreak ); registercratetype( "supplydrop_mp", "killstreak", "autoturret_mp", 80, &"KILLSTREAK_AUTO_TURRET_CRATE", &"PLATFORM_AUTO_TURRET_GAMBLER", "share_package_sentry_gun", ::givecratekillstreak ); registercratetype( "supplydrop_mp", "killstreak", "microwaveturret_mp", 120, &"KILLSTREAK_MICROWAVE_TURRET_CRATE", &"PLATFORM_MICROWAVE_TURRET_GAMBLER", "share_package_microwave_turret", ::givecratekillstreak ); registercratetype( "supplydrop_mp", "killstreak", "inventory_minigun_mp", 60, &"KILLSTREAK_MINIGUN_CRATE", &"PLATFORM_MINIGUN_GAMBLER", "share_package_death_machine", ::givecratekillstreak ); registercratetype( "supplydrop_mp", "killstreak", "inventory_m32_mp", 60, &"KILLSTREAK_M32_CRATE", &"PLATFORM_M32_GAMBLER", "share_package_multiple_grenade_launcher", ::givecratekillstreak ); registercratetype( "supplydrop_mp", "killstreak", "helicopter_guard_mp", 20, &"KILLSTREAK_HELICOPTER_GUARD_CRATE", &"PLATFORM_HELICOPTER_GUARD_GAMBLER", "share_package_helicopter_guard", ::givecratekillstreak ); registercratetype( "supplydrop_mp", "killstreak", "radardirection_mp", 20, &"KILLSTREAK_SATELLITE_CRATE", &"PLATFORM_SATELLITE_GAMBLER", "share_package_satellite", ::givecratekillstreak ); registercratetype( "supplydrop_mp", "killstreak", "qrdrone_mp", 20, &"KILLSTREAK_QRDRONE_CRATE", &"PLATFORM_QRDRONE_GAMBLER", "share_package_qrdrone", ::givecratekillstreak ); registercratetype( "supplydrop_mp", "killstreak", "inventory_ai_tank_drop_mp", 20, &"KILLSTREAK_AI_TANK_CRATE", &"PLATFORM_AI_TANK_GAMBLER", "share_package_aitank", ::givecratekillstreak ); registercratetype( "supplydrop_mp", "killstreak", "helicopter_comlink_mp", 20, &"KILLSTREAK_HELICOPTER_CRATE", &"PLATFORM_HELICOPTER_GAMBLER", "share_package_helicopter_comlink", ::givecratekillstreak ); registercratetype( "supplydrop_mp", "killstreak", "emp_mp", 5, &"KILLSTREAK_EMP_CRATE", &"PLATFORM_EMP_GAMBLER", "share_package_emp", ::givecratekillstreak ); registercratetype( "supplydrop_mp", "killstreak", "remote_mortar_mp", 2, &"KILLSTREAK_REMOTE_MORTAR_CRATE", &"PLATFORM_REMOTE_MORTAR_GAMBLER", "share_package_remote_mortar", ::givecratekillstreak ); registercratetype( "supplydrop_mp", "killstreak", "helicopter_player_gunner_mp", 2, &"KILLSTREAK_HELICOPTER_GUNNER_CRATE", &"PLATFORM_HELICOPTER_GUNNER_GAMBLER", "share_package_helicopter_gunner", ::givecratekillstreak ); registercratetype( "supplydrop_mp", "killstreak", "dogs_mp", 2, &"KILLSTREAK_DOGS_CRATE", &"PLATFORM_DOGS_GAMBLER", "share_package_dogs", ::givecratekillstreak ); registercratetype( "supplydrop_mp", "killstreak", "straferun_mp", 2, &"KILLSTREAK_STRAFERUN_CRATE", &"PLATFORM_STRAFERUN_GAMBLER", "share_package_strafe_run", ::givecratekillstreak ); registercratetype( "supplydrop_mp", "killstreak", "missile_swarm_mp", 2, &"KILLSTREAK_MISSILE_SWARM_CRATE", &"PLATFORM_MISSILE_SWARM_GAMBLER", "share_package_missile_swarm", ::givecratekillstreak ); registercratetype( "inventory_supplydrop_mp", "killstreak", "radar_mp", 100, &"KILLSTREAK_RADAR_CRATE", &"PLATFORM_RADAR_GAMBLER", "share_package_uav", ::givecratekillstreak ); registercratetype( "inventory_supplydrop_mp", "killstreak", "counteruav_mp", 100, &"KILLSTREAK_COUNTERU2_CRATE", &"PLATFORM_COUNTERU2_GAMBLER", "share_package_counter_uav", ::givecratekillstreak ); registercratetype( "inventory_supplydrop_mp", "killstreak", "rcbomb_mp", 100, &"KILLSTREAK_RCBOMB_CRATE", &"PLATFORM_RCBOMB_GAMBLER", "share_package_rcbomb", ::givecratekillstreak ); registercratetype( "inventory_supplydrop_mp", "killstreak", "inventory_missile_drone_mp", 100, &"KILLSTREAK_MISSILE_DRONE_CRATE", &"PLATFORM_MISSILE_DRONE_GAMBLER", "share_package_missile_drone", ::givecratekillstreak ); registercratetype( "inventory_supplydrop_mp", "killstreak", "qrdrone_mp", 20, &"KILLSTREAK_QRDRONE_CRATE", &"PLATFORM_QRDRONE_GAMBLER", "share_package_qrdrone", ::givecratekillstreak ); registercratetype( "inventory_supplydrop_mp", "killstreak", "remote_missile_mp", 85, &"KILLSTREAK_REMOTE_MISSILE_CRATE", &"PLATFORM_REMOTE_MISSILE_GAMBLER", "share_package_remote_missile", ::givecratekillstreak ); registercratetype( "inventory_supplydrop_mp", "killstreak", "planemortar_mp", 80, &"KILLSTREAK_PLANE_MORTAR_CRATE", &"PLATFORM_PLANE_MORTAR_GAMBLER", "share_package_plane_mortar", ::givecratekillstreak ); registercratetype( "inventory_supplydrop_mp", "killstreak", "autoturret_mp", 80, &"KILLSTREAK_AUTO_TURRET_CRATE", &"PLATFORM_AUTO_TURRET_GAMBLER", "share_package_sentry_gun", ::givecratekillstreak ); registercratetype( "inventory_supplydrop_mp", "killstreak", "microwaveturret_mp", 120, &"KILLSTREAK_MICROWAVE_TURRET_CRATE", &"PLATFORM_MICROWAVE_TURRET_GAMBLER", "share_package_microwave_turret", ::givecratekillstreak ); registercratetype( "inventory_supplydrop_mp", "killstreak", "inventory_minigun_mp", 60, &"KILLSTREAK_MINIGUN_CRATE", &"PLATFORM_MINIGUN_GAMBLER", "share_package_death_machine", ::givecratekillstreak ); registercratetype( "inventory_supplydrop_mp", "killstreak", "inventory_m32_mp", 60, &"KILLSTREAK_M32_CRATE", &"PLATFORM_M32_GAMBLER", "share_package_multiple_grenade_launcher", ::givecratekillstreak ); registercratetype( "inventory_supplydrop_mp", "killstreak", "remote_mortar_mp", 2, &"KILLSTREAK_REMOTE_MORTAR_CRATE", &"PLATFORM_REMOTE_MORTAR_GAMBLER", "share_package_remote_mortar", ::givecratekillstreak ); registercratetype( "inventory_supplydrop_mp", "killstreak", "helicopter_guard_mp", 20, &"KILLSTREAK_HELICOPTER_GUARD_CRATE", &"PLATFORM_HELICOPTER_GUARD_GAMBLER", "share_package_helicopter_guard", ::givecratekillstreak ); registercratetype( "inventory_supplydrop_mp", "killstreak", "radardirection_mp", 20, &"KILLSTREAK_SATELLITE_CRATE", &"PLATFORM_SATELLITE_GAMBLER", "share_package_satellite", ::givecratekillstreak ); registercratetype( "inventory_supplydrop_mp", "killstreak", "inventory_ai_tank_drop_mp", 20, &"KILLSTREAK_AI_TANK_CRATE", &"PLATFORM_AI_TANK_GAMBLER", "share_package_aitank", ::givecratekillstreak ); registercratetype( "inventory_supplydrop_mp", "killstreak", "helicopter_comlink_mp", 20, &"KILLSTREAK_HELICOPTER_CRATE", &"PLATFORM_HELICOPTER_GAMBLER", "share_package_helicopter_comlink", ::givecratekillstreak ); registercratetype( "inventory_supplydrop_mp", "killstreak", "emp_mp", 5, &"KILLSTREAK_EMP_CRATE", &"PLATFORM_EMP_GAMBLER", "share_package_emp", ::givecratekillstreak ); registercratetype( "inventory_supplydrop_mp", "killstreak", "helicopter_player_gunner_mp", 2, &"KILLSTREAK_HELICOPTER_GUNNER_CRATE", &"PLATFORM_HELICOPTER_GUNNER_GAMBLER", "share_package_helicopter_gunner", ::givecratekillstreak ); registercratetype( "inventory_supplydrop_mp", "killstreak", "dogs_mp", 2, &"KILLSTREAK_DOGS_CRATE", &"PLATFORM_DOGS_GAMBLER", "share_package_dogs", ::givecratekillstreak ); registercratetype( "inventory_supplydrop_mp", "killstreak", "straferun_mp", 2, &"KILLSTREAK_STRAFERUN_CRATE", &"PLATFORM_STRAFERUN_GAMBLER", "share_package_strafe_run", ::givecratekillstreak ); registercratetype( "inventory_supplydrop_mp", "killstreak", "missile_swarm_mp", 2, &"KILLSTREAK_MISSILE_SWARM_CRATE", &"PLATFORM_MISSILE_SWARM_GAMBLER", "share_package_missile_swarm", ::givecratekillstreak ); registercratetype( "gambler_mp", "killstreak", "radar_mp", 80, &"KILLSTREAK_RADAR_CRATE", undefined, "share_package_uav", ::givecratekillstreak ); registercratetype( "gambler_mp", "killstreak", "counteruav_mp", 80, &"KILLSTREAK_COUNTERU2_CRATE", undefined, "share_package_counter_uav", ::givecratekillstreak ); registercratetype( "gambler_mp", "killstreak", "rcbomb_mp", 80, &"KILLSTREAK_RCBOMB_CRATE", undefined, "share_package_rcbomb", ::givecratekillstreak ); registercratetype( "gambler_mp", "killstreak", "inventory_missile_drone_mp", 90, &"KILLSTREAK_MISSILE_DRONE_CRATE", undefined, "share_package_missile_drone", ::givecratekillstreak ); registercratetype( "gambler_mp", "killstreak", "qrdrone_mp", 30, &"KILLSTREAK_QRDRONE_CRATE", undefined, "share_package_qrdrone", ::givecratekillstreak ); registercratetype( "gambler_mp", "killstreak", "microwaveturret_mp", 100, &"KILLSTREAK_MICROWAVE_TURRET_CRATE", undefined, "share_package_microwave_turret", ::givecratekillstreak ); registercratetype( "gambler_mp", "killstreak", "remote_missile_mp", 90, &"KILLSTREAK_REMOTE_MISSILE_CRATE", undefined, "share_package_remote_missile", ::givecratekillstreak ); registercratetype( "gambler_mp", "killstreak", "planemortar_mp", 90, &"KILLSTREAK_PLANE_MORTAR_CRATE", undefined, "share_package_plane_mortar", ::givecratekillstreak ); registercratetype( "gambler_mp", "killstreak", "autoturret_mp", 90, &"KILLSTREAK_AUTO_TURRET_CRATE", undefined, "share_package_sentry_gun", ::givecratekillstreak ); registercratetype( "gambler_mp", "killstreak", "inventory_minigun_mp", 60, &"KILLSTREAK_MINIGUN_CRATE", undefined, "share_package_death_machine", ::givecratekillstreak ); registercratetype( "gambler_mp", "killstreak", "inventory_m32_mp", 60, &"KILLSTREAK_M32_CRATE", undefined, "share_package_multiple_grenade_launcher", ::givecratekillstreak ); registercratetype( "gambler_mp", "killstreak", "remote_mortar_mp", 2, &"KILLSTREAK_REMOTE_MORTAR_CRATE", undefined, "share_package_remote_mortar", ::givecratekillstreak ); registercratetype( "gambler_mp", "killstreak", "helicopter_guard_mp", 30, &"KILLSTREAK_HELICOPTER_GUARD_CRATE", undefined, "share_package_helicopter_guard", ::givecratekillstreak ); registercratetype( "gambler_mp", "killstreak", "radardirection_mp", 30, &"KILLSTREAK_SATELLITE_CRATE", undefined, "share_package_satellite", ::givecratekillstreak ); registercratetype( "gambler_mp", "killstreak", "inventory_ai_tank_drop_mp", 30, &"KILLSTREAK_AI_TANK_CRATE", undefined, "share_package_aitank", ::givecratekillstreak ); registercratetype( "gambler_mp", "killstreak", "helicopter_comlink_mp", 30, &"KILLSTREAK_HELICOPTER_CRATE", undefined, "share_package_helicopter_comlink", ::givecratekillstreak ); registercratetype( "gambler_mp", "killstreak", "straferun_mp", 2, &"KILLSTREAK_STRAFERUN_CRATE", undefined, "share_package_strafe_run", ::givecratekillstreak ); registercratetype( "gambler_mp", "killstreak", "emp_mp", 10, &"KILLSTREAK_EMP_CRATE", undefined, "share_package_emp", ::givecratekillstreak ); registercratetype( "gambler_mp", "killstreak", "helicopter_player_gunner_mp", 2, &"KILLSTREAK_HELICOPTER_GUNNER_CRATE", undefined, "share_package_helicopter_gunner", ::givecratekillstreak ); registercratetype( "gambler_mp", "killstreak", "dogs_mp", 2, &"KILLSTREAK_DOGS_CRATE", undefined, "share_package_dogs", ::givecratekillstreak ); registercratetype( "gambler_mp", "killstreak", "missile_swarm_mp", 2, &"KILLSTREAK_MISSILE_SWARM_CRATE", undefined, "share_package_missile_swarm", ::givecratekillstreak ); level.cratecategoryweights = []; level.cratecategorytypeweights = []; foreach ( category in level.cratetypes ) { finalizecratecategory( categorykey ); } /* /# level thread supply_drop_dev_gui(); getdvarintdefault( "scr_crate_notimeout", 0 ); #/ */ } finalizecratecategory( category ) //checked changed to match cerberus output { level.cratecategoryweights[ category ] = 0; cratetypekeys = getarraykeys( level.cratetypes[ category ] ); for ( cratetype = 0; cratetype < cratetypekeys.size; cratetype++ ) { typekey = cratetypekeys[ cratetype ]; level.cratetypes[ category ][ typekey ].previousweight = level.cratecategoryweights[ category ]; level.cratecategoryweights[ category ] += level.cratetypes[ category ][ typekey ].weight; level.cratetypes[ category ][ typekey ].weight = level.cratecategoryweights[ category ]; } } advancedfinalizecratecategory( category ) //checked changed to match cerberus output { level.cratecategorytypeweights[ category ] = 0; cratetypekeys = getarraykeys( level.categorytypeweight[ category ] ); for ( cratetype = 0; cratetype < cratetypekeys.size; cratetype++ ) { typekey = cratetypekeys[ cratetype ]; level.cratecategorytypeweights[ category ] += level.categorytypeweight[ category ][ typekey ].weight; level.categorytypeweight[ category ][ typekey ].weight = level.cratecategorytypeweights[ category ]; } finalizecratecategory( category ); } setcategorytypeweight( category, type, weight ) //checked changed to match cerberus output { if ( !isDefined( level.categorytypeweight[ category ] ) ) { level.categorytypeweight[ category ] = []; } level.categorytypeweight[ category ][ type ] = spawnstruct(); level.categorytypeweight[ category ][ type ].weight = weight; count = 0; totalweight = 0; startindex = undefined; finalindex = undefined; cratenamekeys = getarraykeys( level.cratetypes[ category ] ); for ( cratename = 0; cratename < cratenamekeys.size; cratename++ ) { namekey = cratenamekeys[ cratename ]; if ( level.cratetypes[ category ][ namekey ].type == type ) { count++; totalweight += level.cratetypes[ category ][ namekey ].weight; if ( !isDefined( startindex ) ) { startindex = cratename; } if ( isDefined( finalindex ) && ( finalindex + 1 ) != cratename ) { /* /# maps/mp/_utility::error( "Crate type declaration must be contiguous" ); #/ */ maps/mp/gametypes/_callbacksetup::abortlevel(); return; } finalindex = cratename; } } level.categorytypeweight[ category ][ type ].totalcrateweight = totalweight; level.categorytypeweight[ category ][ type ].cratecount = count; level.categorytypeweight[ category ][ type ].startindex = startindex; level.categorytypeweight[ category ][ type ].finalindex = finalindex; } registercratetype( category, type, name, weight, hint, hint_gambler, sharestat, givefunction, landfunctionoverride ) //checked matches cerberus output { if ( !isDefined( level.cratetypes[ category ] ) ) { level.cratetypes[ category ] = []; } cratetype = spawnstruct(); cratetype.type = type; cratetype.name = name; cratetype.weight = weight; cratetype.hint = hint; cratetype.hint_gambler = hint_gambler; cratetype.sharestat = sharestat; cratetype.givefunction = givefunction; if ( isDefined( landfunctionoverride ) ) { cratetype.landfunctionoverride = landfunctionoverride; } level.cratetypes[ category ][ name ] = cratetype; game[ "strings" ][ name + "_hint" ] = hint; } getrandomcratetype( category, gambler_crate_name ) //checked partially changed to match cerberus output see compiler_limitations.md No. 2 { /* /# assert( isDefined( level.cratetypes ) ); #/ /# assert( isDefined( level.cratetypes[ category ] ) ); #/ /# assert( isDefined( level.cratecategoryweights[ category ] ) ); #/ */ typekey = undefined; cratetypestart = 0; randomweightend = randomintrange( 1, level.cratecategoryweights[ category ] + 1 ); find_another = 0; cratenamekeys = getarraykeys( level.cratetypes[ category ] ); if ( isDefined( level.categorytypeweight[ category ] ) ) { randomweightend = randomint( level.cratecategorytypeweights[ category ] ) + 1; cratetypekeys = getarraykeys( level.categorytypeweight[ category ] ); for ( cratetype = 0; cratetype < cratetypekeys.size; cratetype++ ) { typekey = cratetypekeys[ cratetype ]; if ( level.categorytypeweight[ category ][ typekey ].weight < randomweightend ) { cratetype++; } else { cratetypestart = level.categorytypeweight[ category ][ typekey ].startindex; randomweightend = randomint( level.categorytypeweight[ category ][ typekey ].totalcrateweight ) + 1; randomweightend += level.cratetypes[ category ][ cratenamekeys[ cratetypestart ] ].previousweight; break; } } } cratetype = cratetypestart; while ( cratetype < cratenamekeys.size ) { typekey = cratenamekeys[ cratetype ]; if ( level.cratetypes[ category ][ typekey ].weight < randomweightend ) { cratetype++; continue; } if ( isDefined( gambler_crate_name ) && level.cratetypes[ category ][ typekey ].name == gambler_crate_name ) { find_another = 1; } if ( find_another ) { if ( cratetype < ( cratenamekeys.size - 1 ) ) { cratetype++; } else if ( cratetype > 0 ) { cratetype--; } typekey = cratenamekeys[ cratetype ]; } break; } /# if ( isDefined( level.dev_gui_supply_drop ) && level.dev_gui_supply_drop != "random" ) { typekey = level.dev_gui_supply_drop; } #/ return level.cratetypes[ category ][ typekey ]; } validate_crate_type( killstreak_name, weapon_name, crate_type_name ) //checked partially changed to match cerberus output see compiler_limitations.md No. 2 { players = get_players(); for ( i = 0; i < players.size; i++ ) { if ( isalive( players[ i ] ) ) { for ( j = 0; j < players[i].pers["killstreaks"].size; j++ ) { if ( players[ i ].pers[ "killstreaks" ][ j ] == killstreak_name ) { return 1; } } primary_weapons = players[ i ] getweaponslistprimaries(); for ( j = 0; j < primary_weapons.size; j++ ) { if ( primary_weapons[ j ] == weapon_name ) { return 1; } } ents = getentarray( "weapon_" + weapon_name, "classname" ); if ( isDefined( ents ) && ents.size > 0 ) { return 1; } crate_ents = getentarray( "care_package", "script_noteworthy" ); for ( j = 0; j < crate_ents.size; j++ ) { if ( !isDefined( crate_ents[ j ].cratetype ) ) { } else { if ( isDefined( crate_ents[ j ].cratetype.name ) ) { if ( crate_ents[ j ].cratetype.name == crate_type_name ) { return 1; } } } } } } return 0; } givecrateitem( crate ) //checked matches cerberus output { if ( !isalive( self ) ) { return; } return [[ crate.cratetype.givefunction ]]( crate.cratetype.name ); } givecratekillstreakwaiter( event, removecrate, extraendon ) //checked matches cerberus output { self endon( "give_crate_killstreak_done" ); if ( isDefined( extraendon ) ) { self endon( extraendon ); } self waittill( event ); self notify( "give_crate_killstreak_done" ); } givecratekillstreak( killstreak ) //checked matches cerberus output { self maps/mp/killstreaks/_killstreaks::givekillstreak( killstreak ); } givespecializedcrateweapon( weapon ) //checked matches cerberus output { switch( weapon ) { case "minigun_mp": level thread maps/mp/_popups::displayteammessagetoall( &"KILLSTREAK_MINIGUN_INBOUND", self ); level maps/mp/gametypes/_weapons::addlimitedweapon( weapon, self, 3 ); break; case "m32_mp": level thread maps/mp/_popups::displayteammessagetoall( &"KILLSTREAK_M32_INBOUND", self ); level maps/mp/gametypes/_weapons::addlimitedweapon( weapon, self, 3 ); break; case "m202_flash_mp": level thread maps/mp/_popups::displayteammessagetoall( &"KILLSTREAK_M202_FLASH_INBOUND", self ); level maps/mp/gametypes/_weapons::addlimitedweapon( weapon, self, 3 ); break; case "m220_tow_mp": level thread maps/mp/_popups::displayteammessagetoall( &"KILLSTREAK_M220_TOW_INBOUND", self ); level maps/mp/gametypes/_weapons::addlimitedweapon( weapon, self, 3 ); break; case "mp40_blinged_mp": level thread maps/mp/_popups::displayteammessagetoall( &"KILLSTREAK_MP40_INBOUND", self ); level maps/mp/gametypes/_weapons::addlimitedweapon( weapon, self, 3 ); break; default: break; } } givecrateweapon( weapon ) //checked changed to match cerberus output { currentweapon = self getcurrentweapon(); if ( currentweapon == weapon || self hasweapon( weapon ) ) { self givemaxammo( weapon ); return 1; } if ( !issupplydropweapon( currentweapon ) || isDefined( level.grenade_array[ currentweapon ] ) || isDefined( level.inventory_array[ currentweapon ] ) ) { self takeweapon( self.lastdroppableweapon ); self giveweapon( weapon ); self switchtoweapon( weapon ); return 1; } self addweaponstat( weapon, "used", 1 ); givespecializedcrateweapon( weapon ); self giveweapon( weapon ); self switchtoweapon( weapon ); self waittill( "weapon_change", newweapon ); self maps/mp/killstreaks/_killstreak_weapons::usekillstreakweaponfromcrate( weapon ); return 1; } givecrateammo( ammo ) //checked partially changed to match cerberus output changed at own discretion see compiler_limitations.md No. 2 { weaponslist = self getweaponslist(); idx = 0; while ( idx < weaponslist.size ) { weapon = weaponslist[ idx ]; if ( maps/mp/killstreaks/_killstreaks::iskillstreakweapon( weapon ) ) { continue; } switch( weapon ) { case "inventory_supplydrop_mp": case "m202_flash_mp": case "m220_tow_mp": case "m32_mp": case "minigun_mp": case "mp40_blinged_mp": case "supplydrop_mp": break; idx++; continue; case "bouncingbetty_mp": case "claymore_mp": case "frag_grenade_mp": case "hatchet_mp": case "satchel_charge_mp": case "sticky_grenade_mp": stock = self getweaponammostock( weapon ); maxammo = self.grenadetypeprimarycount; if ( !isDefined( maxammo ) ) { maxammo = 0; } if ( stock < maxammo ) { self setweaponammostock( weapon, maxammo ); } break; case "concussion_grenade_mp": case "emp_grenade_mp": case "flash_grenade_mp": case "nightingale_mp": case "proximity_grenade_mp": case "tabun_gas_mp": case "willy_pete_mp": stock = self getweaponammostock( weapon ); maxammo = self.tacticalgrenadecount; if ( !isDefined( maxammo ) ) { maxammo = 0; } if ( stock < maxammo ) { self setweaponammostock( weapon, maxammo ); } break; default: self givemaxammo( weapon ); break; } idx++; } } waitforgrenadefire() //checked matches cerberus output { self endon( "weapon_change" ); self waittill( "grenade_fire" ); return "grenade_fire"; } usesupplydropmarker( package_contents_id ) //checked matches cerberus output { self endon( "disconnect" ); self endon( "spawned_player" ); self thread supplydropwatcher( package_contents_id ); self.supplygrenadedeathdrop = 0; supplydropweapon = undefined; currentweapon = self getcurrentweapon(); prevweapon = currentweapon; if ( issupplydropweapon( currentweapon ) ) { supplydropweapon = currentweapon; } notifystring = self waitforgrenadefire(); if ( !isDefined( notifystring ) || notifystring != "grenade_fire" ) { return 0; } if ( !isDefined( supplydropweapon ) ) { return 0; } if ( isDefined( self ) ) { notifystring = self waittill_any_return( "weapon_change", "death" ); self takeweapon( supplydropweapon ); if ( self hasweapon( supplydropweapon ) || self getammocount( supplydropweapon ) ) { return 0; } } return 1; } issupplydropgrenadeallowed( hardpointtype, killstreakweapon ) //checked matches cerberus output { if ( !isDefined( killstreakweapon ) ) { killstreakweapon = hardpointtype; } if ( self maps/mp/killstreaks/_killstreakrules::iskillstreakallowed( hardpointtype, self.team ) == 0 ) { self switchtoweapon( self getlastweapon() ); return 0; } return 1; } usekillstreaksupplydrop( hardpointtype ) //checked matches cerberus output { if ( self issupplydropgrenadeallowed( hardpointtype, "supplydrop_mp" ) == 0 ) { return 0; } result = self usesupplydropmarker(); self notify( "supply_drop_marker_done" ); if ( !isDefined( result ) || !result ) { return 0; } return result; } use_killstreak_death_machine( hardpointtype ) //checked changed to match cerberus output { if ( self maps/mp/killstreaks/_killstreakrules::iskillstreakallowed( hardpointtype, self.team ) == 0 ) { return 0; } weapon = "minigun_mp"; currentweapon = self getcurrentweapon(); if ( !issupplydropweapon( currentweapon ) || isDefined( level.grenade_array[ currentweapon ] ) || isDefined( level.inventory_array[ currentweapon ] ) ) { self takeweapon( self.lastdroppableweapon ); self giveweapon( weapon ); self switchtoweapon( weapon ); self setblockweaponpickup( weapon, 1 ); return 1; } level thread maps/mp/_popups::displayteammessagetoall( &"KILLSTREAK_MINIGUN_INBOUND", self ); level maps/mp/gametypes/_weapons::addlimitedweapon( weapon, self, 3 ); self takeweapon( currentweapon ); self giveweapon( weapon ); self switchtoweapon( weapon ); self setblockweaponpickup( weapon, 1 ); return 1; } use_killstreak_grim_reaper( hardpointtype ) //checked changed to match cerberus output { if ( self maps/mp/killstreaks/_killstreakrules::iskillstreakallowed( hardpointtype, self.team ) == 0 ) { return 0; } weapon = "m202_flash_mp"; currentweapon = self getcurrentweapon(); if ( !issupplydropweapon( currentweapon ) || isDefined( level.grenade_array[ currentweapon ] ) || isDefined( level.inventory_array[ currentweapon ] ) ) { self takeweapon( self.lastdroppableweapon ); self giveweapon( weapon ); self switchtoweapon( weapon ); self setblockweaponpickup( weapon, 1 ); return 1; } level thread maps/mp/_popups::displayteammessagetoall( &"KILLSTREAK_M202_FLASH_INBOUND", self ); level maps/mp/gametypes/_weapons::addlimitedweapon( weapon, self, 3 ); self takeweapon( currentweapon ); self giveweapon( weapon ); self switchtoweapon( weapon ); self setblockweaponpickup( weapon, 1 ); return 1; } use_killstreak_tv_guided_missile( hardpointtype ) //checked changed to match cerberus output { if ( maps/mp/killstreaks/_killstreakrules::iskillstreakallowed( hardpointtype, self.team ) == 0 ) { self iprintlnbold( level.killstreaks[ hardpointtype ].notavailabletext ); return 0; } weapon = "m220_tow_mp"; currentweapon = self getcurrentweapon(); if ( !issupplydropweapon( currentweapon ) || isDefined( level.grenade_array[ currentweapon ] ) || isDefined( level.inventory_array[ currentweapon ] ) ) { self takeweapon( self.lastdroppableweapon ); self giveweapon( weapon ); self switchtoweapon( weapon ); self setblockweaponpickup( weapon, 1 ); return 1; } level thread maps/mp/_popups::displayteammessagetoall( &"KILLSTREAK_M220_TOW_INBOUND", self ); level maps/mp/gametypes/_weapons::addlimitedweapon( weapon, self, 3 ); self takeweapon( currentweapon ); self giveweapon( weapon ); self switchtoweapon( weapon ); self setblockweaponpickup( weapon, 1 ); return 1; } use_killstreak_mp40( hardpointtype ) //checked changed to match cerberus output { if ( maps/mp/killstreaks/_killstreakrules::iskillstreakallowed( hardpointtype, self.team ) == 0 ) { self iprintlnbold( level.killstreaks[ hardpointtype ].notavailabletext ); return 0; } weapon = "mp40_blinged_mp"; currentweapon = self getcurrentweapon(); if ( !issupplydropweapon( currentweapon ) || isDefined( level.grenade_array[ currentweapon ] ) || isDefined( level.inventory_array[ currentweapon ] ) ) { self takeweapon( self.lastdroppableweapon ); self giveweapon( weapon ); self switchtoweapon( weapon ); self setblockweaponpickup( weapon, 1 ); return 1; } level thread maps/mp/_popups::displayteammessagetoall( &"KILLSTREAK_MP40_INBOUND", self ); level maps/mp/gametypes/_weapons::addlimitedweapon( weapon, self, 3 ); self takeweapon( currentweapon ); self giveweapon( weapon ); self switchtoweapon( weapon ); self setblockweaponpickup( weapon, 1 ); return 1; } cleanupwatcherondeath( team, killstreak_id ) //checked matches cerberus output { self endon( "disconnect" ); self endon( "supplyDropWatcher" ); self endon( "grenade_fire" ); self endon( "spawned_player" ); self endon( "weapon_change" ); self waittill( "death" ); maps/mp/killstreaks/_killstreakrules::killstreakstop( "supply_drop_mp", team, killstreak_id ); } supplydropwatcher( package_contents_id ) //checked matches cerberus output { self notify( "supplyDropWatcher" ); self endon( "supplyDropWatcher" ); self endon( "spawned_player" ); self endon( "disconnect" ); self endon( "weapon_change" ); team = self.team; killstreak_id = maps/mp/killstreaks/_killstreakrules::killstreakstart( "supply_drop_mp", team, 0, 0 ); if ( killstreak_id == -1 ) { return; } self thread checkforemp(); self thread checkweaponchange( team, killstreak_id ); self thread cleanupwatcherondeath( team, killstreak_id ); self waittill( "grenade_fire", weapon, weapname ); if ( isDefined( self ) && issupplydropweapon( weapname ) ) { self thread dosupplydrop( weapon, weapname, self, killstreak_id, package_contents_id ); weapon thread do_supply_drop_detonation( weapname, self ); weapon thread supplydropgrenadetimeout( team, killstreak_id, weapname ); self maps/mp/killstreaks/_killstreaks::switchtolastnonkillstreakweapon(); } else { maps/mp/killstreaks/_killstreakrules::killstreakstop( "supply_drop_mp", team, killstreak_id ); } } checkforemp() //checked matches cerberus output { self endon( "supplyDropWatcher" ); self endon( "spawned_player" ); self endon( "disconnect" ); self endon( "weapon_change" ); self endon( "death" ); self endon( "grenade_fire" ); self waittill( "emp_jammed" ); self maps/mp/killstreaks/_killstreaks::switchtolastnonkillstreakweapon(); } supplydropgrenadetimeout( team, killstreak_id, weapname ) //checked changed to match cerberus output { self endon( "death" ); self endon( "stationary" ); grenade_lifetime = 10; wait grenade_lifetime; if ( !isDefined( self ) ) { return; } self notify( "grenade_timeout" ); maps/mp/killstreaks/_killstreakrules::killstreakstop( "supply_drop_mp", team, killstreak_id ); if ( weapname == "ai_tank_drop_mp" ) { maps/mp/killstreaks/_killstreakrules::killstreakstop( "ai_tank_drop_mp", team, killstreak_id ); } else if ( weapname == "inventory_ai_tank_drop_mp" ) { maps/mp/killstreaks/_killstreakrules::killstreakstop( "inventory_ai_tank_drop_mp", team, killstreak_id ); } self delete(); } checkweaponchange( team, killstreak_id ) //checked matches cerberus output { self endon( "supplyDropWatcher" ); self endon( "spawned_player" ); self endon( "disconnect" ); self endon( "grenade_fire" ); self endon( "death" ); self waittill( "weapon_change" ); maps/mp/killstreaks/_killstreakrules::killstreakstop( "supply_drop_mp", team, killstreak_id ); } supplydropgrenadepullwatcher( killstreak_id ) //checked matches cerberus output { self endon( "disconnect" ); self endon( "weapon_change" ); self waittill( "grenade_pullback", weapon ); self _disableusability(); self thread watchforgrenadeputdown(); self waittill( "death" ); killstreak = "supply_drop_mp"; self.supplygrenadedeathdrop = 1; if ( issupplydropweapon( weapon ) ) { killstreak = maps/mp/killstreaks/_killstreaks::getkillstreakforweapon( weapon ); } if ( !isDefined( self.usingkillstreakfrominventory ) || self.usingkillstreakfrominventory == 0 ) { self changekillstreakquantity( weapon, -1 ); } else { maps/mp/killstreaks/_killstreaks::removeusedkillstreak( killstreak, killstreak_id ); } } watchforgrenadeputdown() //checked matches cerberus output { self notify( "watchForGrenadePutDown" ); self endon( "watchForGrenadePutDown" ); self endon( "death" ); self endon( "disconnect" ); self waittill_any( "grenade_fire", "weapon_change" ); self _enableusability(); } abortsupplydropmarkerwaiter( waittillstring ) //checked matches cerberus output { self endon( "supply_drop_marker_done" ); self waittill( waittillstring ); self notify( "supply_drop_marker_done" ); } playerchangeweaponwaiter() //checked matches cerberus output { self endon( "supply_drop_marker_done" ); self endon( "disconnect" ); self endon( "spawned_player" ); currentweapon = self getcurrentweapon(); while ( issupplydropweapon( currentweapon ) ) { self waittill( "weapon_change", currentweapon ); } waittillframeend; self notify( "supply_drop_marker_done" ); } issupplydropweapon( weapon ) //checked converted to switch for my sanity { switch ( weapon ) { case "supplystation_mp": case "supplydrop_mp": case "inventory_supplydrop_mp": case "turret_drop_mp": case "ai_tank_drop_mp": case "inventory_ai_tank_drop_mp": case "minigun_drop_mp": case "inventory_minigun_drop_mp": case "m32_drop_mp": case "inventory_m32_drop_mp": case "tow_turret_drop_mp": case "m220_tow_drop_mp": return 1; default: return 0; } } geticonforcrate() //checked matches cerberus output { icon = undefined; switch( self.cratetype.type ) { case "killstreak": if ( self.cratetype.name == "inventory_ai_tank_drop_mp" ) { icon = "hud_ks_ai_tank"; } else { killstreak = maps/mp/killstreaks/_killstreaks::getkillstreakmenuname( self.cratetype.name ); icon = level.killstreakicons[ killstreak ]; } break; case "weapon": switch( self.cratetype.name ) { case "minigun_mp": icon = "hud_ks_minigun"; break; case "m32_mp": icon = "hud_ks_m32"; break; case "m202_flash_mp": icon = "hud_ks_m202"; break; case "m220_tow_mp": icon = "hud_ks_tv_guided_missile"; break; case "mp40_drop_mp": icon = "hud_mp40"; break; default: icon = "waypoint_recon_artillery_strike"; break; } break; case "ammo": icon = "hud_ammo_refill"; break; default: return undefined; } return icon + "_drop"; // may not be right but seems logical :/ } crateactivate( hacker ) //checked partially changed to match cerberus output see compiler_limitations.md No. 2 { self makeusable(); self setcursorhint( "HINT_NOICON" ); self sethintstring( self.cratetype.hint ); if ( isDefined( self.cratetype.hint_gambler ) ) { self sethintstringforperk( "specialty_showenemyequipment", self.cratetype.hint_gambler ); } crateobjid = maps/mp/gametypes/_gameobjects::getnextobjid(); objective_add( crateobjid, "invisible", self.origin ); objective_icon( crateobjid, "compass_supply_drop_green" ); objective_state( crateobjid, "active" ); self.friendlyobjid = crateobjid; self.enemyobjid = []; icon = self geticonforcrate(); if ( isDefined( hacker ) ) { self thread attachreconmodel( level.cratemodelhacker, hacker ); } if ( level.teambased ) { objective_team( crateobjid, self.team ); foreach ( team in level.teams ) { if ( self.team == team ) { } else { crateobjid = maps/mp/gametypes/_gameobjects::getnextobjid(); objective_add( crateobjid, "invisible", self.origin ); if ( isDefined( self.hacker ) ) { objective_icon( crateobjid, "compass_supply_drop_black" ); } else { objective_icon( crateobjid, "compass_supply_drop_red" ); } objective_team( crateobjid, team ); objective_state( crateobjid, "active" ); self.enemyobjid[ self.enemyobjid.size ] = crateobjid; } } } else if ( !self.visibletoall ) { objective_setinvisibletoall( crateobjid ); enemycrateobjid = maps/mp/gametypes/_gameobjects::getnextobjid(); objective_add( enemycrateobjid, "invisible", self.origin ); objective_icon( enemycrateobjid, "compass_supply_drop_red" ); objective_state( enemycrateobjid, "active" ); if ( isplayer( self.owner ) ) { objective_setinvisibletoplayer( enemycrateobjid, self.owner ); } self.enemyobjid[ self.enemyobjid.size ] = enemycrateobjid; } if ( isplayer( self.owner ) ) { objective_setvisibletoplayer( crateobjid, self.owner ); } if ( isDefined( self.hacker ) ) { objective_setinvisibletoplayer( crateobjid, self.hacker ); crateobjid = maps/mp/gametypes/_gameobjects::getnextobjid(); objective_add( crateobjid, "invisible", self.origin ); objective_icon( crateobjid, "compass_supply_drop_black" ); objective_state( crateobjid, "active" ); objective_setinvisibletoall( crateobjid ); objective_setvisibletoplayer( crateobjid, self.hacker ); self.hackerobjid = crateobjid; } if ( !self.visibletoall && isDefined( icon ) ) { self thread maps/mp/_entityheadicons::setentityheadicon( self.team, self, level.crate_headicon_offset, icon, 1 ); } if ( isDefined( self.owner ) && isplayer( self.owner ) && self.owner is_bot() ) { self.owner notify( "bot_crate_landed" ); } if ( isDefined( self.owner ) ) { self.owner notify( "crate_landed" ); } } cratedeactivate() //checked changed to match cerberus output { self makeunusable(); if ( isDefined( self.friendlyobjid ) ) { objective_delete( self.friendlyobjid ); maps/mp/gametypes/_gameobjects::releaseobjid( self.friendlyobjid ); self.friendlyobjid = undefined; } if ( isDefined( self.enemyobjid ) ) { foreach ( objid in self.enemyobjid ) { objective_delete( objid ); maps/mp/gametypes/_gameobjects::releaseobjid( objid ); } self.enemyobjid = []; } if ( isDefined( self.hackerobjid ) ) { objective_delete( self.hackerobjid ); maps/mp/gametypes/_gameobjects::releaseobjid( self.hackerobjid ); self.hackerobjid = undefined; } } ownerteamchangewatcher() //checked matches cerberus output { self endon( "death" ); if ( !level.teambased || !isDefined( self.owner ) ) { return; } self.owner waittill( "joined_team" ); self.owner = undefined; } dropalltoground( origin, radius, stickyobjectradius ) //checked matches cerberus output { physicsexplosionsphere( origin, radius, radius, 0 ); wait 0.05; maps/mp/gametypes/_weapons::dropweaponstoground( origin, radius ); maps/mp/killstreaks/_supplydrop::dropcratestoground( origin, radius ); level notify( "drop_objects_to_ground" ); } dropeverythingtouchingcrate( origin ) //checked matches cerberus output { dropalltoground( origin, 70, 70 ); } dropalltogroundaftercratedelete( crate, crate_origin ) //checked matches cerberus output { crate waittill( "death" ); wait 0.1; crate dropeverythingtouchingcrate( crate_origin ); } dropcratestoground( origin, radius ) //checked changed to match cerberus output { crate_ents = getentarray( "care_package", "script_noteworthy" ); radius_sq = radius * radius; for ( i = 0; i < crate_ents.size; i++ ) { if ( distancesquared( origin, crate_ents[ i ].origin ) < radius_sq ) { crate_ents[ i ] thread dropcratetoground(); } } } dropcratetoground() { self endon( "death" ); if ( isDefined( self.droppingtoground ) ) { return; } self.droppingtoground = 1; dropeverythingtouchingcrate( self.origin ); self cratedeactivate(); self thread cratedroptogroundkill(); self crateredophysics(); self crateactivate(); self.droppingtoground = undefined; } cratespawn( category, owner, team, drop_origin, drop_angle ) //checked matches cerberus output { crate = spawn( "script_model", drop_origin, 1 ); crate.angles = drop_angle; crate.team = team; crate.visibletoall = 0; crate setteam( team ); if ( isplayer( owner ) ) { crate setowner( owner ); } crate.script_noteworthy = "care_package"; if ( !level.teambased || isDefined( owner ) && owner.team == team ) { crate.owner = owner; } crate thread ownerteamchangewatcher(); if ( category == "ai_tank_drop_mp" || category == "inventory_ai_tank_drop_mp" ) { crate setmodel( level.cratemodeltank ); crate setenemymodel( level.cratemodeltank ); } else { crate setmodel( level.cratemodelfriendly ); crate setenemymodel( level.cratemodelenemy ); } switch( category ) { case "turret_drop_mp": crate.cratetype = level.cratetypes[ category ][ "autoturret_mp" ]; break; case "tow_turret_drop_mp": crate.cratetype = level.cratetypes[ category ][ "auto_tow_mp" ]; break; case "m220_tow_drop_mp": crate.cratetype = level.cratetypes[ category ][ "m220_tow_mp" ]; break; case "ai_tank_drop_mp": case "inventory_ai_tank_drop_mp": crate.cratetype = level.cratetypes[ category ][ "ai_tank_mp" ]; break; case "inventory_minigun_drop_mp": case "minigun_drop_mp": crate.cratetype = level.cratetypes[ category ][ "minigun_mp" ]; break; case "inventory_m32_drop_mp": case "m32_drop_mp": crate.cratetype = level.cratetypes[ category ][ "m32_mp" ]; break; default: crate.cratetype = getrandomcratetype( category ); break; } return crate; } cratedelete( drop_all_to_ground ) //checked changed to match cerberus output { if ( !isDefined( drop_all_to_ground ) ) { drop_all_to_ground = 1; } if ( isDefined( self.friendlyobjid ) ) { objective_delete( self.friendlyobjid ); maps/mp/gametypes/_gameobjects::releaseobjid( self.friendlyobjid ); self.friendlyobjid = undefined; } if ( isDefined( self.enemyobjid ) ) { foreach ( objid in self.enemyobjid ) { objective_delete( objid ); maps/mp/gametypes/_gameobjects::releaseobjid( objid ); } self.enemyobjid = undefined; } if ( isDefined( self.hackerobjid ) ) { objective_delete( self.hackerobjid ); maps/mp/gametypes/_gameobjects::releaseobjid( self.hackerobjid ); self.hackerobjid = undefined; } if ( drop_all_to_ground ) { level thread dropalltogroundaftercratedelete( self, self.origin ); } if ( isDefined( self.killcament ) ) { self.killcament thread deleteaftertime( 5 ); } self delete(); } timeoutcratewaiter() //checked matches cerberus output { self endon( "death" ); self endon( "stationary" ); wait 20; self cratedelete(); } cratephysics() //checked matches cerberus output { forcepointvariance = 200; vertvelocitymin = -100; vertvelocitymax = 100; forcepointx = randomfloatrange( 0 - forcepointvariance, forcepointvariance ); forcepointy = randomfloatrange( 0 - forcepointvariance, forcepointvariance ); forcepoint = ( forcepointx, forcepointy, 0 ); forcepoint += self.origin; initialvelocityz = randomfloatrange( vertvelocitymin, vertvelocitymax ); initialvelocity = ( 0, 0, initialvelocityz ); self physicslaunch( forcepoint, initialvelocity ); self thread timeoutcratewaiter(); self thread update_crate_velocity(); self thread play_impact_sound(); self waittill( "stationary" ); } play_impact_sound() //checked matches cerberus output { self endon( "entityshutdown" ); self endon( "stationary" ); self endon( "death" ); wait 0.5; while ( abs( self.velocity[ 2 ] ) > 5 ) { wait 0.1; } self playsound( "phy_impact_supply" ); } update_crate_velocity() //checked changed to match cerberus output { self endon( "entityshutdown" ); self endon( "stationary" ); self.velocity = ( 0, 0, 0 ); self.old_origin = self.origin; while ( isDefined( self ) ) { self.velocity = self.origin - self.old_origin; self.old_origin = self.origin; wait 0.05; } } crateredophysics() //checked changed to match cerberus output { forcepoint = self.origin; initialvelocity = ( 0, 0, 0 ); self physicslaunch( forcepoint, initialvelocity ); self thread timeoutcratewaiter(); self waittill( "stationary" ); } do_supply_drop_detonation( weapname, owner ) //checked matches cerberus output { self notify( "supplyDropWatcher" ); self endon( "supplyDropWatcher" ); self endon( "spawned_player" ); self endon( "disconnect" ); self endon( "death" ); self endon( "grenade_timeout" ); self waittillnotmoving(); self.angles = ( 0, self.angles[ 1 ], 90 ); fuse_time = getweaponfusetime( weapname ) / 1000; wait fuse_time; if ( !isDefined( owner ) || owner maps/mp/killstreaks/_emp::isenemyempkillstreakactive() == 0 ) { thread playsmokesound( self.origin, 6, level.sound_smoke_start, level.sound_smoke_stop, level.sound_smoke_loop ); playfxontag( level._supply_drop_smoke_fx, self, "tag_fx" ); proj_explosion_sound = getweaponprojexplosionsound( weapname ); play_sound_in_space( proj_explosion_sound, self.origin ); } wait 3; self delete(); } dosupplydrop( weapon, weaponname, owner, killstreak_id, package_contents_id ) //checked matches cerberus output { weapon endon( "explode" ); weapon endon( "grenade_timeout" ); self endon( "disconnect" ); team = owner.team; weapon thread watchexplode( weaponname, owner, killstreak_id, package_contents_id ); weapon waittillnotmoving(); weapon notify( "stoppedMoving" ); self thread helidelivercrate( weapon.origin, weaponname, owner, team, killstreak_id, package_contents_id ); } watchexplode( weaponname, owner, killstreak_id, package_contents_id ) //checked matches cerberus output { self endon( "stoppedMoving" ); team = owner.team; self waittill( "explode", position ); owner thread helidelivercrate( position, weaponname, owner, team, killstreak_id, package_contents_id ); } cratetimeoutthreader() //checked matches cerberus output { /* /# if ( getdvarintdefault( "scr_crate_notimeout", 0 ) ) { return; #/ } */ self thread cratetimeout( 90 ); } dropcrate( origin, angle, category, owner, team, killcament, killstreak_id, package_contents_id, crate ) //checked matches cerberus output { angle = ( angle[ 0 ] * 0.5, angle[ 1 ] * 0.5, angle[ 2 ] * 0.5 ); if ( isDefined( crate ) ) { origin = crate.origin; angle = crate.angles; crate delete(); } crate = cratespawn( category, owner, team, origin, angle ); killcament unlink(); killcament linkto( crate ); crate.killcament = killcament; crate.killstreak_id = killstreak_id; crate.package_contents_id = package_contents_id; killcament thread deleteaftertime( 15 ); killcament thread unlinkonrotation( crate ); crate endon( "death" ); crate thread cratekill(); crate cratephysics(); crate cratetimeoutthreader(); crate thread maps/mp/_hacker_tool::registerwithhackertool( level.carepackagehackertoolradius, level.carepackagehackertooltimems ); if ( isDefined( crate.cratetype.landfunctionoverride ) ) { [[ crate.cratetype.landfunctionoverride ]]( crate, category, owner, team ); } else { crate crateactivate(); crate thread crateusethink(); crate thread crateusethinkowner(); if ( isDefined( crate.cratetype.hint_gambler ) ) { crate thread crategamblerthink(); } default_land_function( crate, category, owner, team ); } } unlinkonrotation( crate ) //checked matches cerberus output { self endon( "delete" ); crate endon( "entityshutdown" ); crate endon( "stationary" ); waitbeforerotationcheck = getdvarfloatdefault( "scr_supplydrop_killcam_rot_wait", 0.5 ); wait waitbeforerotationcheck; mincos = getdvarintdefault( "scr_supplydrop_killcam_max_rot", 0.999 ); cosine = 1; currentdirection = vectornormalize( anglesToForward( crate.angles ) ); while ( cosine > mincos ) { olddirection = currentdirection; wait 0.05; currentdirection = vectornormalize( anglesToForward( crate.angles ) ); cosine = vectordot( olddirection, currentdirection ); } self unlink(); } default_land_function( crate, weaponname, owner, team ) //checked partially changed to match cerberus output see compiler_limitations.md No. 5 { while ( 1 ) { crate waittill( "captured", player, remote_hack ); player maps/mp/_challenges::capturedcrate(); deletecrate = player givecrateitem( crate ); if ( isDefined( deletecrate ) && !deletecrate ) { continue; } if ( player hasperk( "specialty_showenemyequipment" ) || remote_hack == 1 && owner != player ) { if ( level.teambased && team != player.team || !level.teambased ) { spawn_explosive_crate( crate.origin, crate.angles, weaponname, owner, team, player ); crate cratedelete( 0 ); } } else { crate cratedelete(); } return; } } spawn_explosive_crate( origin, angle, weaponname, owner, team, hacker ) //checked matches cerberus output { crate = cratespawn( weaponname, owner, team, origin, angle ); crate setowner( owner ); crate setteam( team ); if ( level.teambased ) { crate setenemymodel( level.cratemodelboobytrapped ); crate makeusable( team ); } else { crate setenemymodel( level.cratemodelenemy ); } crate.hacker = hacker; crate.visibletoall = 0; crate crateactivate( hacker ); crate sethintstringforperk( "specialty_showenemyequipment", level.supplydropdisarmcrate ); crate thread crateusethink(); crate thread crateusethinkowner(); crate thread watch_explosive_crate(); crate cratetimeoutthreader(); } watch_explosive_crate() //checked matches cerberus output { killcament = spawn( "script_model", self.origin + vectorScale( ( 0, 0, 1 ), 60 ) ); self.killcament = killcament; self waittill( "captured", player, remote_hack ); if ( !player hasperk( "specialty_showenemyequipment" ) && !remote_hack ) { self thread maps/mp/_entityheadicons::setentityheadicon( player.team, player, level.crate_headicon_offset, "headicon_dead", 1 ); self loop_sound( "wpn_semtex_alert", 0.15 ); if ( !isDefined( self.hacker ) ) { self.hacker = self; } self radiusdamage( self.origin, 256, 300, 75, self.hacker, "MOD_EXPLOSIVE", "supplydrop_mp" ); playfx( level._supply_drop_explosion_fx, self.origin ); playsoundatposition( "wpn_grenade_explode", self.origin ); } else { playsoundatposition( "mpl_turret_alert", self.origin ); maps/mp/_scoreevents::processscoreevent( "disarm_hacked_care_package", player ); player maps/mp/_challenges::disarmedhackedcarepackage(); } wait 0.1; self cratedelete(); killcament thread deleteaftertime( 5 ); } loop_sound( alias, interval ) //checked changed to match cerberus output { self endon( "death" ); while ( 1 ) { playsoundatposition( alias, self.origin ); wait interval; interval /= 1.2; if ( interval < 0.08 ) { return; } } } cratekill() //checked matches cerberus output { self endon( "death" ); stationarythreshold = 2; killthreshold = 15; maxframestillstationary = 20; numframesstationary = 0; while ( 1 ) { vel = 0; if ( isDefined( self.velocity ) ) { vel = abs( self.velocity[ 2 ] ); } if ( vel > killthreshold ) { self is_touching_crate(); } if ( vel < stationarythreshold ) { numframesstationary++; } else { numframesstationary = 0; } if ( numframesstationary >= maxframestillstationary ) { return; } else { wait 0.01; } } } cratedroptogroundkill() //checked partially changed to match cerberus output see compiler_limitations.md No. 2 { self endon( "death" ); self endon( "stationary" ); for ( ;; ) { players = get_players(); dotrace = 0; i = 0; while ( i < players.size ) { if ( players[ i ].sessionstate != "playing" ) { i++; continue; } else if ( players[ i ].team == "spectator" ) { i++; continue; } self is_equipment_touching_crate( players[ i ] ); if ( !isalive( players[ i ] ) ) { i++; continue; } flattenedselforigin = ( self.origin[ 0 ], self.origin[ 1 ], 0 ); flattenedplayerorigin = ( players[ i ].origin[ 0 ], players[ i ].origin[ 1 ], 0 ); if ( distancesquared( flattenedselforigin, flattenedplayerorigin ) > 4096 ) { i++; continue; } else { dotrace = 1; break; } i++; } if ( dotrace ) { start = self.origin; cratedroptogroundtrace( start ); start = self getpointinbounds( 1, 0, 0 ); cratedroptogroundtrace( start ); start = self getpointinbounds( -1, 0, 0 ); cratedroptogroundtrace( start ); start = self getpointinbounds( 0, -1, 0 ); cratedroptogroundtrace( start ); start = self getpointinbounds( 0, 1, 0 ); cratedroptogroundtrace( start ); start = self getpointinbounds( 1, 1, 0 ); cratedroptogroundtrace( start ); start = self getpointinbounds( -1, 1, 0 ); cratedroptogroundtrace( start ); start = self getpointinbounds( 1, -1, 0 ); cratedroptogroundtrace( start ); start = self getpointinbounds( -1, -1, 0 ); cratedroptogroundtrace( start ); wait 0.2; continue; } wait 0.5; } } cratedroptogroundtrace( start ) //checked changed to match cerberus output { end = start + vectorScale( ( 0, 0, -1 ), 8000 ); trace = bullettrace( start, end, 1, self, 1, 1 ); if ( isDefined( trace[ "entity" ] ) && isplayer( trace[ "entity" ] ) && isalive( trace[ "entity" ] ) ) { player = trace[ "entity" ]; if ( player.sessionstate != "playing" ) { return; } if ( player.team == "spectator" ) { return; } if ( distancesquared( start, trace[ "position" ] ) < 144 || self istouching( player ) ) { player dodamage( player.health + 1, player.origin, self.owner, self, "none", "MOD_HIT_BY_OBJECT", 0, "supplydrop_mp" ); player playsound( "mpl_supply_crush" ); player playsound( "phy_impact_supply" ); } } } is_touching_crate() //checked changed to match cerberus output removed empty if statements which probably contained comments { extraboundary = vectorScale( ( 1, 1, 1 ), 10 ); players = get_players(); for ( i = 0; i < players.size; i++ ) { if ( isDefined( players[ i ] ) && isalive( players[ i ] ) && self istouching( players[ i ], extraboundary ) ) { attacker = self; players[ i ] dodamage( players[ i ].health + 1, players[ i ].origin, attacker, self, "none", "MOD_HIT_BY_OBJECT", 0, "supplydrop_mp" ); players[ i ] playsound( "mpl_supply_crush" ); players[ i ] playsound( "phy_impact_supply" ); } self is_equipment_touching_crate( players[ i ] ); } } is_equipment_touching_crate( player ) //checked partially changed to match cerberus output see compiler_limitations.md No. 2 { extraboundary = vectorScale( ( 0, 0, 1 ), 10 ); if ( isDefined( player ) && isDefined( player.weaponobjectwatcherarray ) ) { for ( watcher = 0; watcher < player.weaponobjectwatcherarray.size; watcher++ ) { objectwatcher = player.weaponobjectwatcherarray[ watcher ]; objectarray = objectwatcher.objectarray; if ( isDefined( objectarray ) ) { for ( weaponobject = 0; weaponobject < objectarray.size; weaponobject++ ) { if ( isDefined( objectarray[ weaponobject ] ) && self istouching( objectarray[ weaponobject ], extraboundary ) ) { if ( isDefined( objectwatcher.detonate ) ) { objectwatcher thread maps/mp/gametypes/_weaponobjects::waitanddetonate( objectarray[ weaponobject ], 0 ); } else { maps/mp/gametypes/_weaponobjects::deleteweaponobject( objectwatcher, objectarray[ weaponobject ] ); } } } } } } extraboundary = vectorScale( ( 1, 1, 1 ), 15 ); if ( isDefined( player ) && isDefined( player.tacticalinsertion ) && self istouching( player.tacticalinsertion, extraboundary ) ) { player.tacticalinsertion thread maps/mp/_tacticalinsertion::fizzle(); } } cratetimeout( time ) //checked matches cerberus output { self endon( "death" ); wait time; self cratedelete(); } spawnuseent() //checked matches cerberus output { useent = spawn( "script_origin", self.origin ); useent.curprogress = 0; useent.inuse = 0; useent.userate = 0; useent.usetime = 0; useent.owner = self; useent thread useentownerdeathwaiter( self ); return useent; } useentownerdeathwaiter( owner ) //checked matches cerberus output { self endon( "death" ); owner waittill( "death" ); self delete(); } crateusethink() //checked changed to match cerberus output { while ( isDefined( self ) ) { self waittill( "trigger", player ); if ( !isalive( player ) ) { continue; } if ( !player isonground() ) { continue; } if ( isDefined( self.owner ) && self.owner == player ) { continue; } useent = self spawnuseent(); result = 0; if ( isDefined( self.hacker ) ) { useent.hacker = self.hacker; } self.useent = useent; result = useent useholdthink( player, level.cratenonownerusetime ); if ( isDefined( useent ) ) { useent delete(); } if ( result ) { givecratecapturemedal( self, player ); self notify( "captured", player, 0 ); } } } givecratecapturemedal( crate, capturer ) //checked changed to match cerberus output { if ( isDefined( crate.owner ) && isplayer( crate.owner ) ) { if ( level.teambased ) { if ( capturer.team != crate.owner.team ) { crate.owner playlocalsound( "mpl_crate_enemy_steals" ); if ( !isDefined( crate.hacker ) ) { maps/mp/_scoreevents::processscoreevent( "capture_enemy_crate", capturer ); } } else if ( isDefined( crate.owner ) && capturer != crate.owner ) { crate.owner playlocalsound( "mpl_crate_friendly_steals" ); if ( !isDefined( crate.hacker ) ) { level.globalsharepackages++; maps/mp/_scoreevents::processscoreevent( crate.cratetype.sharestat, crate.owner ); } } } else if ( capturer != crate.owner ) { crate.owner playlocalsound( "mpl_crate_enemy_steals" ); if ( !isDefined( crate.hacker ) ) { maps/mp/_scoreevents::processscoreevent( "capture_enemy_crate", capturer ); } } } } crateusethinkowner() //checked changed to match cerberus output { self endon( "joined_team" ); while ( isDefined( self ) ) { self waittill( "trigger", player ); if ( !isalive( player ) ) { continue; } if ( !player isonground() ) { continue; } if ( !isDefined( self.owner ) ) { continue; } if ( self.owner != player ) { continue; } result = self useholdthink( player, level.crateownerusetime ); if ( result ) { self notify( "captured", player, 0 ); } } } useholdthink( player, usetime ) //checked matches cerberus output { player notify( "use_hold" ); player freeze_player_controls( 1 ); player _disableweapon(); self.curprogress = 0; self.inuse = 1; self.userate = 0; self.usetime = usetime; player thread personalusebar( self ); result = useholdthinkloop( player ); if ( isDefined( player ) ) { player notify( "done_using" ); } if ( isDefined( player ) ) { if ( isalive( player ) ) { player _enableweapon(); player freeze_player_controls( 0 ); } } if ( isDefined( self ) ) { self.inuse = 0; } if ( isDefined( result ) && result ) { return 1; } return 0; } continueholdthinkloop( player ) //checked matches cerberus output { if ( !isDefined( self ) ) { return 0; } if ( self.curprogress >= self.usetime ) { return 0; } if ( !isalive( player ) ) { return 0; } if ( player.throwinggrenade ) { return 0; } if ( !player usebuttonpressed() ) { return 0; } if ( player meleebuttonpressed() ) { return 0; } if ( player isinvehicle() ) { return 0; } if ( player isweaponviewonlylinked() ) { return 0; } if ( player isremotecontrolling() ) { return 0; } return 1; } useholdthinkloop( player ) //checked matches cerberus output { level endon( "game_ended" ); self endon( "disabled" ); self.owner endon( "crate_use_interrupt" ); timedout = 0; while ( self continueholdthinkloop( player ) ) { timedout += 0.05; self.curprogress += 50 * self.userate; self.userate = 1; if ( self.curprogress >= self.usetime ) { self.inuse = 0; wait 0.05; return isalive( player ); } wait 0.05; maps/mp/gametypes/_hostmigration::waittillhostmigrationdone(); } return 0; } crategamblerthink() //checked changed to match cerberus output { self endon( "death" ); for ( ;; ) { self waittill( "trigger_use_doubletap", player ); if ( !player hasperk( "specialty_showenemyequipment" ) ) { continue; } if ( isDefined( self.useent ) && self.useent.inuse ) { if ( isDefined( self.owner ) && self.owner != player ) { continue; } } player playlocalsound( "uin_gamble_perk" ); self.cratetype = getrandomcratetype( "gambler_mp", self.cratetype.name ); self cratereactivate(); self sethintstringforperk( "specialty_showenemyequipment", self.cratetype.hint ); self notify( "crate_use_interrupt" ); level notify( "use_interrupt" ); return; } } cratereactivate() //checked matches cerberus output { self sethintstring( self.cratetype.hint ); icon = self geticonforcrate(); self thread maps/mp/_entityheadicons::setentityheadicon( self.team, self, level.crate_headicon_offset, icon, 1 ); } personalusebar( object ) //checked partially changed to match cerberus output see compiler_limitations.md No. 5 { self endon( "disconnect" ); if ( isDefined( self.usebar ) ) { return; } self.usebar = createsecondaryprogressbar(); self.usebartext = createsecondaryprogressbartext(); if ( self hasperk( "specialty_showenemyequipment" ) && object.owner != self && !isDefined( object.hacker ) ) { if ( level.teambased && object.owner.team != self.team || !level.teambased ) { self.usebartext settext( &"KILLSTREAK_HACKING_CRATE" ); self playlocalsound( "evt_hacker_hacking" ); } else { self.usebartext settext( &"KILLSTREAK_CAPTURING_CRATE" ); } } else if ( self hasperk( "specialty_showenemyequipment" ) && isDefined( object.hacker ) ) { if ( object.owner == self || level.teambased && object.owner.team == self.team ) { self.usebartext settext( level.disarmingcrate ); self playlocalsound( "evt_hacker_hacking" ); } else { self.usebartext settext( &"KILLSTREAK_CAPTURING_CRATE" ); } } else { self.usebartext settext( &"KILLSTREAK_CAPTURING_CRATE" ); } lastrate = -1; while ( isalive( self ) && isDefined( object ) && object.inuse && !level.gameended ) { if ( lastrate != object.userate ) { if ( object.curprogress > object.usetime ) { object.curprogress = object.usetime; } self.usebar updatebar( object.curprogress / object.usetime, ( 1000 / object.usetime ) * object.userate ); if ( !object.userate ) { self.usebar hideelem(); self.usebartext hideelem(); } else { self.usebar showelem(); self.usebartext showelem(); } } lastrate = object.userate; wait 0.05; } self.usebar destroyelem(); self.usebartext destroyelem(); } spawn_helicopter( owner, team, origin, angles, model, targetname, killstreak_id ) //checked changed to match cerberus output { chopper = spawnhelicopter( owner, origin, angles, model, targetname ); if ( !isDefined( chopper ) ) { if ( isplayer( owner ) ) { maps/mp/killstreaks/_killstreakrules::killstreakstop( "supply_drop_mp", team, killstreak_id ); } return undefined; } chopper.owner = owner; chopper.maxhealth = 1500; chopper.health = 999999; chopper.rocketdamageoneshot = chopper.maxhealth + 1; chopper.damagetaken = 0; chopper thread maps/mp/killstreaks/_helicopter::heli_damage_monitor( "supply_drop_mp" ); chopper.spawntime = getTime(); supplydropspeed = getdvarintdefault( "scr_supplydropSpeedStarting", 125 ); supplydropaccel = getdvarintdefault( "scr_supplydropAccelStarting", 100 ); chopper setspeed( supplydropspeed, supplydropaccel ); maxpitch = getdvarintdefault( "scr_supplydropMaxPitch", 25 ); maxroll = getdvarintdefault( "scr_supplydropMaxRoll", 45 ); chopper setmaxpitchroll( 0, maxroll ); chopper.team = team; chopper setdrawinfrared( 1 ); target_set( chopper, vectorScale( ( 0, 0, -1 ), 25 ) ); if ( isplayer( owner ) ) { chopper thread refcountdecchopper( team, killstreak_id ); } chopper thread helidestroyed(); return chopper; } getdropheight( origin ) //checked matches cerberus output { return getminimumflyheight(); } getdropdirection() //checked matches cerberus output { return ( 0, randomint( 360 ), 0 ); } getnextdropdirection( drop_direction, degrees ) //checked matches cerberus output { drop_direction = ( 0, drop_direction[ 1 ] + degrees, 0 ); if ( drop_direction[ 1 ] >= 360 ) { drop_direction = ( 0, drop_direction[ 1 ] - 360, 0 ); } return drop_direction; } gethelistart( drop_origin, drop_direction ) //checked matches cerberus output { dist = -1 * getdvarintdefault( "scr_supplydropIncomingDistance", 10000 ); pathrandomness = 100; direction = drop_direction + ( 0, randomintrange( -2, 3 ), 0 ); start_origin = drop_origin + ( anglesToForward( direction ) * dist ); start_origin += ( ( randomfloat( 2 ) - 1 ) * pathrandomness, ( randomfloat( 2 ) - 1 ) * pathrandomness, 0 ); /* /# if ( getdvarintdefault( "scr_noflyzones_debug", 0 ) ) { if ( level.noflyzones.size ) { index = randomintrange( 0, level.noflyzones.size ); delta = drop_origin - level.noflyzones[ index ].origin; delta = ( delta[ 0 ] + randomint( 10 ), delta[ 1 ] + randomint( 10 ), 0 ); delta = vectornormalize( delta ); start_origin = drop_origin + ( delta * dist ); #/ } } */ return start_origin; } getheliend( drop_origin, drop_direction ) //checked matches cerberus output { pathrandomness = 150; dist = -1 * getdvarintdefault( "scr_supplydropOutgoingDistance", 15000 ); if ( randomintrange( 0, 2 ) == 0 ) { turn = randomintrange( 60, 121 ); } else { turn = -1 * randomintrange( 60, 121 ); } direction = drop_direction + ( 0, turn, 0 ); end_origin = drop_origin + ( anglesToForward( direction ) * dist ); end_origin += ( ( randomfloat( 2 ) - 1 ) * pathrandomness, ( randomfloat( 2 ) - 1 ) * pathrandomness, 0 ); return end_origin; } addoffsetontopoint( point, direction, offset ) //checked matches cerberus output { angles = vectorToAngles( ( direction[ 0 ], direction[ 1 ], 0 ) ); offset_world = rotatepoint( offset, angles ); return point + offset_world; } supplydrophelistartpath( goal, goal_offset ) //checked matches cerberus output { total_tries = 12; tries = 0; goalpath = spawnstruct(); drop_direction = getdropdirection(); while ( tries < total_tries ) { goalpath.start = gethelistart( goal, drop_direction ); goalpath.path = gethelipath( goalpath.start, goal ); startnoflyzones = insidenoflyzones( goalpath.start, 0 ); if ( isDefined( goalpath.path ) && startnoflyzones.size == 0 ) { if ( goalpath.path.size > 1 ) { direction = goalpath.path[ goalpath.path.size - 1 ] - goalpath.path[ goalpath.path.size - 2 ]; } else { direction = goalpath.path[ goalpath.path.size - 1 ] - goalpath.start; } goalpath.path[ goalpath.path.size - 1 ] = addoffsetontopoint( goalpath.path[ goalpath.path.size - 1 ], direction, goal_offset ); /* /# sphere( goalpath.path[ goalpath.path.size - 1 ], 10, ( 0, 0, 1 ), 1, 1, 10, 1000 ); #/ */ return goalpath; } drop_direction = getnextdropdirection( drop_direction, 30 ); tries++; } drop_direction = getdropdirection(); goalpath.start = gethelistart( goal, drop_direction ); direction = goal - goalpath.start; goalpath.path = []; goalpath.path[ 0 ] = addoffsetontopoint( goal, direction, goal_offset ); return goalpath; } supplydropheliendpath( origin, drop_direction ) //checked changed to match cerberus output { total_tries = 5; tries = 0; goalpath = spawnstruct(); while ( tries < total_tries ) { goal = getheliend( origin, drop_direction ); goalpath.path = gethelipath( origin, goal ); if ( isDefined( goalpath.path ) ) { return goalpath; } tries++; } leave_nodes = getentarray( "heli_leave", "targetname" ); foreach ( node in leave_nodes ) { goalpath.path = gethelipath( origin, node.origin ); if ( isDefined( goalpath.path ) ) { return goalpath; } } goalpath.path = []; goalpath.path[ 0 ] = getheliend( origin, drop_direction ); return goalpath; } inccratekillstreakusagestat( weaponname ) //checked changed to match cerberus output { if ( !isDefined( weaponname ) ) { return; } if ( weaponname == "turret_drop_mp" ) { self maps/mp/killstreaks/_killstreaks::playkillstreakstartdialog( "turret_drop_mp", self.pers[ "team" ] ); } else if ( weaponname == "tow_turret_drop_mp" ) { self maps/mp/killstreaks/_killstreaks::playkillstreakstartdialog( "tow_turret_drop_mp", self.pers[ "team" ] ); } else if ( weaponname == "supplydrop_mp" || weaponname == "inventory_supplydrop_mp" ) { self maps/mp/killstreaks/_killstreaks::playkillstreakstartdialog( "supply_drop_mp", self.pers[ "team" ] ); level thread maps/mp/_popups::displaykillstreakteammessagetoall( "supply_drop_mp", self ); self maps/mp/_challenges::calledincarepackage(); level.globalkillstreakscalled++; self addweaponstat( "supplydrop_mp", "used", 1 ); } else if ( weaponname == "ai_tank_drop_mp" || weaponname == "inventory_ai_tank_drop_mp" ) { self maps/mp/killstreaks/_killstreaks::playkillstreakstartdialog( "ai_tank_drop_mp", self.pers[ "team" ] ); level thread maps/mp/_popups::displaykillstreakteammessagetoall( "ai_tank_drop_mp", self ); level.globalkillstreakscalled++; self addweaponstat( "ai_tank_drop_mp", "used", 1 ); return; } else if ( weaponname == "inventory_minigun_drop_mp" || weaponname == "minigun_drop_mp" ) { self maps/mp/killstreaks/_killstreaks::playkillstreakstartdialog( "minigun_mp", self.pers[ "team" ] ); return; } else if ( weaponname == "m32_drop_mp" || weaponname == "inventory_m32_drop_mp" ) { self maps/mp/killstreaks/_killstreaks::playkillstreakstartdialog( "m32_mp", self.pers[ "team" ] ); } } helidelivercrate( origin, weaponname, owner, team, killstreak_id, package_contents_id, exact ) //checked matches cerberus output { if ( owner maps/mp/killstreaks/_emp::isenemyempkillstreakactive() && owner hasperk( "specialty_immuneemp" ) == 0 ) { maps/mp/killstreaks/_killstreakrules::killstreakstop( "supply_drop_mp", team, killstreak_id ); return; } inccratekillstreakusagestat( weaponname ); rear_hatch_offset_local = getdvarintdefault( "scr_supplydropOffset", 0 ); drop_origin = origin; drop_height = getdropheight( drop_origin ); heli_drop_goal = ( drop_origin[ 0 ], drop_origin[ 1 ], drop_height ); /* /# sphere( heli_drop_goal, 10, ( 0, 0, 1 ), 1, 1, 10, 1000 ); #/ */ goalpath = supplydrophelistartpath( heli_drop_goal, ( rear_hatch_offset_local, 0, 0 ) ); drop_direction = vectorToAngles( ( heli_drop_goal[ 0 ], heli_drop_goal[ 1 ], 0 ) - ( goalpath.start[ 0 ], goalpath.start[ 1 ], 0 ) ); chopper = spawn_helicopter( owner, team, goalpath.start, drop_direction, level.suppydrophelicoptervehicleinfo, level.supplydrophelicopterfriendly, killstreak_id ); chopper setenemymodel( level.supplydrophelicopterenemy ); chopper setteam( team ); chopper.numflares = 0; if ( isplayer( owner ) ) { chopper setowner( owner ); } killcament = spawn( "script_model", chopper.origin + vectorScale( ( 0, 0, 1 ), 800 ) ); killcament.angles = ( 100, chopper.angles[ 1 ], chopper.angles[ 2 ] ); killcament.starttime = getTime(); killcament linkto( chopper ); if ( isplayer( owner ) ) { target_setturretaquire( self, 0 ); chopper thread samturretwatcher( drop_origin ); } if ( !isDefined( chopper ) ) { return; } chopper thread helidropcrate( weaponname, owner, rear_hatch_offset_local, killcament, killstreak_id, package_contents_id ); chopper endon( "death" ); chopper thread followpath( goalpath.path, "drop_goal", 1 ); chopper thread speedregulator( heli_drop_goal ); chopper waittill( "drop_goal" ); /* /# println( "Chopper Incoming Time: " + ( getTime() - chopper.spawntime ) ); #/ */ wait 1.2; chopper notify( "drop_crate" ); chopper.droptime = getTime(); chopper playsound( "veh_supply_drop" ); wait 0.7; supplydropspeed = getdvarintdefault( "scr_supplydropSpeedLeaving", 150 ); supplydropaccel = getdvarintdefault( "scr_supplydropAccelLeaving", 40 ); chopper setspeed( supplydropspeed, supplydropaccel ); goalpath = supplydropheliendpath( chopper.origin, ( 0, chopper.angles[ 1 ], 0 ) ); chopper followpath( goalpath.path, undefined, 0 ); /* /# println( "Chopper Outgoing Time: " + ( getTime() - chopper.droptime ) ); #/ */ chopper notify( "leaving" ); chopper delete(); } samturretwatcher( destination ) //checked changed to match cerberus output { self endon( "leaving" ); self endon( "helicopter_gone" ); self endon( "death" ); sam_turret_aquire_dist = 1500; while ( 1 ) { if ( distance( destination, self.origin ) < sam_turret_aquire_dist ) { break; } if ( ( self.origin[ 0 ] > level.spawnmins[ 0 ] ) && ( self.origin[ 0 ] < level.spawnmaxs[ 0 ] ) && ( self.origin[ 1 ] > level.spawnmins[ 1 ] ) && ( self.origin[ 1 ] < level.spawnmaxs[ 1 ] ) ) { break; } wait 0.1; } target_setturretaquire( self, 1 ); } speedregulator( goal ) //checked matches cerberus output { self endon( "drop_goal" ); self endon( "death" ); wait 3; supplydropspeed = getdvarintdefault( "scr_supplydropSpeed", 75 ); supplydropaccel = getdvarintdefault( "scr_supplydropAccel", 40 ); self setyawspeed( 100, 60, 60 ); self setspeed( supplydropspeed, supplydropaccel ); wait 1; maxpitch = getdvarintdefault( "scr_supplydropMaxPitch", 25 ); maxroll = getdvarintdefault( "scr_supplydropMaxRoll", 35 ); self setmaxpitchroll( maxpitch, maxroll ); } helidropcrate( category, owner, offset, killcament, killstreak_id, package_contents_id ) //checked changed to match cerberus output { owner endon( "disconnect" ); crate = cratespawn( category, owner, self.team, self.origin, self.angles ); if ( category == "inventory_supplydrop_mp" || category == "supplydrop_mp" ) { crate linkto( self, "tag_care_package", ( 0, 0, 0 ) ); self setclientfield( "supplydrop_care_package_state", 1 ); } else if ( category == "inventory_ai_tank_drop_mp" || category == "ai_tank_drop_mp" ) { crate linkto( self, "tag_drop_box", ( 0, 0, 0 ) ); self setclientfield( "supplydrop_ai_tank_state", 1 ); } team = self.team; self waittill( "drop_crate", origin, angles ); if ( isDefined( self ) ) { if ( category == "inventory_supplydrop_mp" || category == "supplydrop_mp" ) { self setclientfield( "supplydrop_care_package_state", 0 ); } else { if ( category == "inventory_ai_tank_drop_mp" || category == "ai_tank_drop_mp" ) { self setclientfield( "supplydrop_ai_tank_state", 0 ); } } } rear_hatch_offset_height = getdvarintdefault( "scr_supplydropOffsetHeight", 200 ); rear_hatch_offset_world = rotatepoint( ( offset, 0, 0 ), angles ); drop_origin = origin - ( 0, 0, rear_hatch_offset_height ) - rear_hatch_offset_world; thread dropcrate( drop_origin, angles, category, owner, team, killcament, killstreak_id, package_contents_id, crate ); } helidestroyed() //checked changed to match cerberus output { self endon( "leaving" ); self endon( "helicopter_gone" ); self endon( "death" ); while ( 1 ) { if ( self.damagetaken > self.maxhealth ) { break; } wait 0.05; } if ( !isDefined( self ) ) { return; } self setspeed( 25, 5 ); self thread lbspin( randomintrange( 180, 220 ) ); wait randomfloatrange( 0.5, 1.5 ); self notify( "drop_crate" ); lbexplode(); } lbexplode() //checked matches cerberus output { forward = ( self.origin + ( 0, 0, 1 ) ) - self.origin; playfx( level.chopper_fx[ "explode" ][ "death" ], self.origin, forward ); self playsound( level.heli_sound[ "crash" ] ); self notify( "explode" ); self delete(); } lbspin( speed ) //checked matches cerberus output { self endon( "explode" ); playfxontag( level.chopper_fx[ "explode" ][ "large" ], self, "tail_rotor_jnt" ); playfxontag( level.chopper_fx[ "fire" ][ "trail" ][ "large" ], self, "tail_rotor_jnt" ); self setyawspeed( speed, speed, speed ); while ( isDefined( self ) ) { self settargetyaw( self.angles[ 1 ] + ( speed * 0.9 ) ); wait 1; } } refcountdecchopper( team, killstreak_id ) //checked matches cerberus output { self waittill( "death" ); maps/mp/killstreaks/_killstreakrules::killstreakstop( "supply_drop_mp", team, killstreak_id ); } attachreconmodel( modelname, owner ) //checked matches cerberus output { if ( !isDefined( self ) ) { return; } reconmodel = spawn( "script_model", self.origin ); reconmodel.angles = self.angles; reconmodel setmodel( modelname ); reconmodel.model_name = modelname; reconmodel linkto( self ); reconmodel setcontents( 0 ); reconmodel resetreconmodelvisibility( owner ); reconmodel thread watchreconmodelfordeath( self ); reconmodel thread resetreconmodelonevent( "joined_team", owner ); reconmodel thread resetreconmodelonevent( "player_spawned", owner ); } resetreconmodelvisibility( owner ) //checked partially changed to match cerberus output see compiler_limitations.md No. 2 { if ( !isDefined( self ) ) { return; } self setinvisibletoall(); self setforcenocull(); if ( !isDefined( owner ) ) { return; } i = 0; while ( i < level.players.size ) { if ( !level.players[ i ] hasperk( "specialty_detectexplosive" ) && !level.players[ i ] hasperk( "specialty_showenemyequipment" ) ) { i++; continue; } if ( level.players[ i ].team == "spectator" ) { i++; continue; } isenemy = 1; if ( level.teambased ) { if ( level.players[ i ].team == owner.team ) { isenemy = 0; } } else if ( level.players[ i ] == owner ) { isenemy = 0; } if ( isenemy ) { self setvisibletoplayer( level.players[ i ] ); } i++; } } watchreconmodelfordeath( parentent ) //checked matches cerberus output { self endon( "death" ); parentent waittill_any( "death", "captured" ); self delete(); } resetreconmodelonevent( eventname, owner ) //checked matches cerberus output { self endon( "death" ); for ( ;; ) { level waittill( eventname, newowner ); if ( isDefined( newowner ) ) { owner = newowner; } self resetreconmodelvisibility( owner ); } } supply_drop_dev_gui() //dev call commented out { /* /# setdvar( "scr_supply_drop_gui", "" ); while ( 1 ) { wait 0,5; devgui_string = getDvar( "scr_supply_drop_gui" ); switch( devgui_string ) { case "ammo": level.dev_gui_supply_drop = "ammo"; break; continue; case "spyplane": level.dev_gui_supply_drop = "radar_mp"; break; continue; case "counter_u2": level.dev_gui_supply_drop = "counteruav_mp"; break; continue; case "airstrike": level.dev_gui_supply_drop = "airstrike_mp"; break; continue; case "artillery": level.dev_gui_supply_drop = "artillery_mp"; break; continue; case "autoturret": level.dev_gui_supply_drop = "autoturret_mp"; break; continue; case "microwave_turret": level.dev_gui_supply_drop = "microwaveturret_mp"; break; continue; case "tow_turret": level.dev_gui_supply_drop = "auto_tow_mp"; break; continue; case "dogs": level.dev_gui_supply_drop = "dogs_mp"; break; continue; case "rc_bomb": level.dev_gui_supply_drop = "rcbomb_mp"; break; continue; case "plane_mortar": level.dev_gui_supply_drop = "planemortar_mp"; break; continue; case "heli": level.dev_gui_supply_drop = "helicopter_comlink_mp"; break; continue; case "heli_gunner": level.dev_gui_supply_drop = "helicopter_player_gunner_mp"; break; continue; case "straferun": level.dev_gui_supply_drop = "straferun_mp"; break; continue; case "missile_swarm": level.dev_gui_supply_drop = "missile_swarm_mp"; break; continue; case "missile_drone": level.dev_gui_supply_drop = "inventory_missile_drone_mp"; break; continue; case "satellite": level.dev_gui_supply_drop = "radardirection_mp"; break; continue; case "remote_missile": level.dev_gui_supply_drop = "remote_missile_mp"; break; continue; case "helicopter_guard": level.dev_gui_supply_drop = "helicopter_guard_mp"; break; continue; case "emp": level.dev_gui_supply_drop = "emp_mp"; break; continue; case "remote_mortar": level.dev_gui_supply_drop = "remote_mortar_mp"; break; continue; case "qrdrone": level.dev_gui_supply_drop = "qrdrone_mp"; break; continue; case "ai_tank": level.dev_gui_supply_drop = "inventory_ai_tank_drop_mp"; break; continue; case "minigun": level.dev_gui_supply_drop = "inventory_minigun_mp"; break; continue; case "m32": level.dev_gui_supply_drop = "inventory_m32_mp"; break; continue; case "random": level.dev_gui_supply_drop = "random"; break; continue; default: } #/ } } */ }