1 #using scripts\codescripts\struct;
3 #using scripts\shared\callbacks_shared;
4 #using scripts\shared\challenges_shared;
5 #using scripts\shared\clientfield_shared;
6 #using scripts\shared\scoreevents_shared;
7 #using scripts\shared\system_shared;
8 #using scripts\shared\util_shared;
9 #using scripts\shared\weapons\_weaponobjects;
11 #insert scripts\shared\shared.gsh;
12 #insert scripts\shared\version.gsh;
14 #define BETTY_DESTROYED_DAMAGE_RADIUS 128
15 #define BETTY_DESTROYED_DAMAGE_MAX 110
16 #define BETTY_DESTROYED_DAMAGE_MIN 10
18 #precache( "fx", "weapon/fx_betty_exp_destroyed" );
19 #precache( "fx", "weapon/fx_betty_light_blue" );
20 #precache( "fx", "weapon/fx_betty_light_orng" );
22 #precache( "model", "wpn_t7_grenade_incendiary_world" );
25 #using_animtree ( "bouncing_betty" );
28 #namespace bouncingbetty;
32 level.bettyDestroyedFX =
"weapon/fx_betty_exp_destroyed";
34 level._effect[
"fx_betty_friendly_light"] =
"weapon/fx_betty_light_blue";
35 level._effect[
"fx_betty_enemy_light"] =
"weapon/fx_betty_light_orng";
37 level.bettyMinDist = 20;
38 level.bettyStunTime = 1;
40 bettyExplodeAnim = %o_spider_mine_detonate;
41 bettyDeployAnim = %o_spider_mine_deploy;
43 level.bettyRadius = getDvarInt(
"betty_detect_radius", 180 );
44 level.bettyActivationDelay = getDvarFloat(
"betty_activation_delay", 1 );
45 level.bettyGracePeriod = getDvarFloat(
"betty_grace_period", 0.0 );
46 level.bettyDamageRadius = getDvarInt(
"betty_damage_radius", 180 );
47 level.bettyDamageMax = getDvarInt(
"betty_damage_max", 180 );
48 level.bettyDamageMin = getDvarInt(
"betty_damage_min", 70 );
49 level.bettyDamageHeight = getDvarInt(
"betty_damage_cylinder_height", 200 );
51 level.bettyJumpHeight = getDvarInt(
"betty_jump_height_onground", 55 );
52 level.bettyJumpHeightWall = getDvarInt(
"betty_jump_height_wall", 20 );
53 level.bettyJumpHeightWallAngle = getDvarInt(
"betty_onground_angle_threshold", 30 );
54 level.bettyJumpHeightWallAngleCos = cos( level.bettyJumpHeightWallAngle );
55 level.bettyJumpTime = getDvarFloat(
"betty_jump_time", 0.7 );
57 level.bettyBombletSpawnDistance = 20;
58 level.bettyBombletCount = 4;
60 level thread
register();
80 watcher.watchForFire =
true;
84 watcher.activateSound =
"wpn_betty_alert";
85 watcher.hackable =
true;
86 watcher.hackerToolRadius = level.equipmentHackerToolRadius;
87 watcher.hackerToolTimeMs = level.equipmentHackerToolTimeMs;
88 watcher.ownerGetsAssist =
true;
89 watcher.ignoreDirection =
true;
90 watcher.immediateDetonation =
true;
91 watcher.immunespecialty =
"specialty_immunetriggerbetty";
93 watcher.detectionMinDist = level.bettyMinDist;
94 watcher.detectionGracePeriod = level.bettyGracePeriod;
95 watcher.detonateRadius = level.bettyRadius;
99 watcher.stunTime = level.bettyStunTime;
101 watcher.activationDelay = level.bettyActivationDelay;
106 if ( isdefined(
self.mineMover ) )
108 if ( isdefined(
self.mineMover.killcament ) )
110 self.mineMover.killcament
delete();
112 self.mineMover
delete();
124 self.originalOwner = owner;
134 self endon(
"do_not_track_used" );
135 self waittill(
"death" );
137 if ( isdefined(
self.owner ) )
141 self notify(
"end_doNoTrackUsedOnPickup" );
142 self notify(
"end_doNoTrackUsedOnHacked" );
147 self endon(
"end_doNoTrackUsedOnPickup" );
148 self waittill(
"picked_up" );
149 self notify(
"do_not_track_used" );
154 self endon(
"end_doNoTrackUsedOnHacked" );
155 self waittill(
"hacked" );
157 self notify(
"do_not_track_used" );
162 if ( IsPlayer(
self ) )
164 self AddWeaponStat( GetWeapon(
"bouncingbetty" ),
"used", 1 );
170 if ( level.trackBouncingBettiesOnOwner ===
true )
172 if ( !isdefined( owner ) )
175 if ( !isdefined( owner.activeBouncingBetties ) )
177 owner.activeBouncingBetties = [];
181 ArrayRemoveValue( owner.activeBouncingBetties, undefined );
184 owner.activeBouncingBetties[ owner.activeBouncingBetties.size ] =
self;
194 self endon(
"death" );
198 self UseAnimTree( #animtree );
199 self SetAnim( %o_spider_mine_deploy, 1.0, 0.0, 1.0 );
201 mineMover =
spawn(
"script_model",
self.origin );
202 mineMover.angles =
self.angles;
203 mineMover SetModel(
"tag_origin" );
204 mineMover.owner =
self.owner;
205 mineUp = AnglesToUp( mineMover.angles );
206 z_offset = GetDvarFloat(
"scr_bouncing_betty_killcam_offset", 18.0 );
207 mineMover.killCamOffset = VectorScale( mineUp, z_offset );
208 mineMover.weapon =
self.weapon;
209 mineMover playsound (
"wpn_betty_arm");
211 killcamEnt =
spawn(
"script_model", mineMover.origin + mineMover.killCamOffset );
212 killcamEnt.angles = ( 0,0,0 );
213 killcamEnt SetModel(
"tag_origin" );
214 killcamEnt SetWeapon(
self.weapon );
216 mineMover.killcamEnt = killcamEnt;
218 self.mineMover = mineMover;
229 self.mineMover endon(
"death" );
242 if ( isdefined(
self.mineMover ))
244 if ( isdefined(
self.mineMover.killcamEnt ) )
246 self.mineMover.killcamEnt
delete();
248 self.mineMover
delete();
258 if ( IsDefined( weapon ) && weapon.isValid )
260 self.destroyedBy = attacker;
261 if ( isdefined( attacker ) )
272 else if ( isdefined(
self.mineMover ))
274 self.mineMover.ignore_team_kills =
true;
275 self.mineMover SetModel(
self.model );
293 PlayFX( level.bettyDestroyedFX,
self.origin );
294 PlaySoundAtPosition (
"dst_equipment_destroy",
self.origin );
296 if ( isdefined(
self.trigger ) )
298 self.trigger
delete();
314 jumpDir = VectorNormalize( AnglesToUp(
self.angles ) );
316 if ( jumpDir[2] > level.bettyJumpHeightWallAngleCos )
318 jumpHeight = level.bettyJumpHeight;
322 jumpHeight = level.bettyJumpHeightWall;
325 explodePos =
self.origin + jumpDir * jumpHeight;
327 self.killCamEnt MoveTo( explodePos +
self.killCamOffset, level.bettyJumpTime, 0, level.bettyJumpTime );
331 wait( level.bettyJumpTime );
339 if ( !isdefined(
self ) || !isdefined(
self.owner ) )
342 self playsound(
"wpn_betty_explo" );
347 if ( !isdefined(
self ) || !isdefined(
self.owner) )
350 self CylinderDamage( explosionDir * level.bettyDamageHeight, explodePos, level.bettyDamageRadius, level.bettyDamageRadius, level.bettyDamageMax, level.bettyDamageMin,
self.owner,
"MOD_EXPLOSIVE",
self.weapon );
356 if ( !isdefined(
self ) || !isdefined(
self.owner) )
359 if ( isdefined(
self.trigger ) )
360 self.trigger
delete();
362 self.killCamEnt
delete();