2 #using scripts\shared\ai_shared;
3 #using scripts\shared\array_shared;
4 #using scripts\shared\callbacks_shared;
5 #using scripts\shared\clientfield_shared;
6 #using scripts\shared\fx_shared;
7 #using scripts\shared\math_shared;
8 #using scripts\shared\scene_shared;
9 #using scripts\shared\spawner_shared;
10 #using scripts\shared\util_shared;
11 #using scripts\shared\visionset_mgr_shared;
13 #using scripts\shared\ai\systems\animation_state_machine_utility;
14 #using scripts\shared\ai\systems\animation_state_machine_notetracks;
15 #using scripts\shared\ai\systems\animation_state_machine_mocomp;
16 #using scripts\shared\ai\archetype_utility;
17 #using scripts\shared\ai\systems\behavior_tree_utility;
18 #using scripts\shared\ai\systems\blackboard;
19 #using scripts\shared\ai\systems\debug;
20 #using scripts\shared\ai\systems\gib;
21 #using scripts\shared\ai\zombie_utility;
22 #using scripts\shared\ai\archetype_mocomps_utility;
23 #using scripts\zm\_zm_behavior; //*! \details **Description:**
24 <br/>Temp - Should
use callback functions to keep
this shared
25 #using scripts\zm\_zm_spawner;
26 #using scripts\zm\_zm_utility;
28 #using scripts\shared\weapons\_weaponobjects;
30 #insert scripts\shared\archetype_shared\archetype_shared.gsh;
31 #insert scripts\shared\ai\systems\animation_state_machine.gsh;
32 #insert scripts\shared\ai\systems\behavior.gsh;
33 #insert scripts\shared\ai\systems\behavior_tree.gsh;
34 #insert scripts\shared\ai\systems\blackboard.gsh;
35 #insert scripts\shared\ai\systems\gib.gsh;
36 #insert scripts\shared\ai\raz.gsh;
37 #insert scripts\shared\ai\utility.gsh;
38 #insert scripts\shared\shared.gsh;
39 #insert scripts\shared\version.gsh;
41 #define PERK_JUGGERNOG "specialty_armorvest"
43 #precache( "xmodel", RAZ_TORPEDO_MODEL );
44 #precache( "xmodel", RAZ_GUN_MODEL );
45 #precache( "xmodel", RAZ_GUN_CORE_MODEL );
46 #precache( "xmodel", RAZ_HELMET_MODEL );
47 #precache( "xmodel", RAZ_CHEST_ARMOR_MODEL );
48 #precache( "xmodel", RAZ_L_SHOULDER_ARMOR_MODEL );
49 #precache( "xmodel", RAZ_R_THIGH_ARMOR_MODEL );
50 #precache( "xmodel", RAZ_L_THIGH_ARMOR_MODEL );
52 #namespace RazBehavior;
136 entity.__blackboard = undefined;
141 if(
IS_TRUE( entity.started_running ))
143 entity.invoke_sprint_time = undefined;
147 if(!
IS_TRUE(entity.razHasGunAttached))
155 if( IsDefined(
self.should_turn ) &&
self.should_turn )
175 behaviorTreeEntity.entrance_nodes = [];
177 if( IsDefined( behaviorTreeEntity.find_flesh_struct_string ) )
179 if ( behaviorTreeEntity.find_flesh_struct_string ==
"find_flesh" )
184 for( i=0; i<level.exterior_goals.size; i++ )
186 if( IsDefined(level.exterior_goals[i].script_string) && level.exterior_goals[i].script_string == behaviorTreeEntity.find_flesh_struct_string )
188 node = level.exterior_goals[i];
193 behaviorTreeEntity.entrance_nodes[behaviorTreeEntity.entrance_nodes.size] = node;
195 assert( IsDefined( node ),
"Did not find an entrance node with .script_string:" + behaviorTreeEntity.find_flesh_struct_string+
"!!! [Fix this!]" );
197 behaviorTreeEntity.first_node = node;
199 behaviorTreeEntity.goalradius = 80;
201 behaviorTreeEntity.mocomp_barricade_offset = GetDvarInt(
"raz_node_origin_offset", -22);
202 node_origin = node.origin + AnglesToForward(node.angles) * behaviorTreeEntity.mocomp_barricade_offset;
204 behaviorTreeEntity SetGoal( node_origin );
209 behaviorTreeEntity.got_to_entrance =
true;
218 if(
IS_TRUE(entity.destroying_window))
223 if(!isdefined(entity.script_string) || entity.script_string ==
"find_flesh")
235 if( isdefined(
self.first_node) )
245 if( !
IS_TRUE(b_destroy_actual_pieces) )
247 entity.got_to_entrance =
false;
248 entity.destroying_window =
true;
249 entity ForceTeleport( entity.origin, entity.first_node.angles);
253 if( !isdefined(chunks) || chunks.size == 0 )
255 entity.jump_through_window =
true;
256 entity.jump_through_window_angle = entity.angles;
260 if(
IS_TRUE(entity.razHasGunAttached) )
262 entity.destroy_window_by_torpedo =
true;
266 entity.destroy_window_by_melee =
true;
272 entity.jump_through_window =
true;
273 entity.jump_through_window_angle = entity.angles;
275 if( isdefined(entity.first_node) )
279 if ( isdefined( chunks ) )
281 for(i = 0; i < chunks.size; i++)
283 entity.first_node.zbarrier SetZBarrierPieceState( chunks[i],
"opening", 0.2 );
297 if(
IS_TRUE(entity.jump_through_window) )
304 if(
IS_TRUE(entity.got_to_entrance))
321 if ( level.zombie_poi_array.size > 0 )
325 if(isdefined(zombie_poi))
329 entity.zombie_poi = zombie_poi;
330 entity.enemyoverride = zombie_poi;
332 if(isdefined(targetPos) )
334 self SetGoal( targetPos );
338 self SetGoal( zombie_poi[0] );
345 entity.zombie_poi = undefined;
346 entity.enemyoverride = undefined;
351 entity.zombie_poi = undefined;
352 entity.enemyoverride = undefined;
357 entity.favoriteenemy = player;
359 if( !IsDefined( player ) || player IsNoTarget() )
361 if( IsDefined(
self.ignore_player ) )
363 if(isDefined(level._should_skip_ignore_player_logic) && [[level._should_skip_ignore_player_logic]]() )
367 self.ignore_player = [];
370 self SetGoal(
self.origin );
376 if ( IsDefined( targetPos ) )
378 entity SetGoal( targetPos );
383 entity SetGoal( entity.origin );
391 if(
IS_TRUE(entity.started_running))
396 if(!isdefined(entity.invoke_sprint_time))
401 if(GetTime() > entity.invoke_sprint_time)
403 entity.invoke_sprint_time = undefined;
404 entity.started_running =
true;
405 entity.berserk =
true;
417 if(
IS_TRUE(entity.destroy_window_by_melee))
422 if( !IsDefined( entity.enemy ) )
432 yaw = abs( zombie_utility::getYawToEnemy() );
455 if(gib_location ==
"right_arm")
465 if( gib_location ==
"head" ||
466 gib_location ==
"arms" ||
467 gib_location ==
"right_leg" ||
468 gib_location ==
"left_leg" ||
469 gib_location ==
"left_arm"
480 if( isdefined(entity.damageWeapon) && isdefined(entity.damageWeapon.name) )
482 return ( entity.damageWeapon.name ==
"dragonshield" );
500 return IS_TRUE(entity.jump_through_window);
505 entity.razHasGoneBerserk =
true;
513 raz_dir = AnglesToForward( entity.first_node.angles );
514 raz_dir = VectorScale(raz_dir, 100);
515 entity SetGoal( entity.origin + raz_dir );
520 entity SetGoal( entity.origin );
521 entity.jump_through_window = undefined;
522 entity.first_node = undefined;
524 if( !
IS_TRUE(entity.completed_emerging_into_playable_area) )
539 entity playsoundontag(
"zmb_raz_death",
"tag_eye" );
541 if(
IS_TRUE( entity.razHasGunAttached ) )
544 entity.razHasGunAttached =
false;
546 entity detach(
"c_zom_dlc3_raz_cannon_arm" );
553 if(isdefined( entity) )
559 if(isdefined( entity) )
561 if(
IS_TRUE( entity.razHasHelmet ) )
565 entity.razHasHelmet =
false;
568 if(
IS_TRUE( entity.razHasChestArmor ) )
577 entity.razHasChestArmor =
false;
580 if(
IS_TRUE( entity.razHasLeftShoulderArmor ) )
586 entity.razHasLeftShoulderArmor =
false;
589 if(
IS_TRUE( entity.razHasLeftThighArmor ) )
594 entity.razHasLeftThighArmor =
false;
597 if(
IS_TRUE( entity.razHasRightThighArmor ) )
602 entity.razHasRightThighArmor =
false;
610 if(
IS_TRUE(entity.destroy_window_by_torpedo))
615 if( !IsDefined( entity.enemy ) )
620 if( !
IS_TRUE( entity.razHasGunAttached ))
626 if( time < entity.next_torpedo_time )
631 enemy_dist_sq = DistanceSquared( entity.origin, entity.enemy.origin );
638 if( isdefined(entity.check_point_in_enabled_zone ) )
640 in_enabled_zone = [[entity.check_point_in_enabled_zone]](entity.origin);
655 target_point = enemy.origin + (0,0,48);
657 forward_vect = AnglesToForward(
self.angles );
658 vect_to_enemy = target_point - origin_point;
660 if( VectorDot(forward_vect, vect_to_enemy) <= 0 )
666 right_vect = AnglesToRight(
self.angles );
668 projected_distance = VectorDot(vect_to_enemy, right_vect);
690 trace = BulletTrace( origin_point, target_point,
false,
self );
692 if(
trace[
"position" ] === target_point )
707 if(
IS_TRUE(entity.destroy_window_by_melee) )
716 entity.destroy_window_by_melee = undefined;
721 entity.destroy_window_by_torpedo = undefined;
728 if( !isdefined( entity.enemy) && !
IS_TRUE(entity.destroy_window_by_torpedo) )
730 /#println(
"RAZ does not have an enemy to shoot Ground Torpedo at" );#/
734 if(
IS_TRUE(entity.destroy_window_by_torpedo))
738 raz_dir = AnglesToForward( entity.first_node.angles );
754 vec_to_enemy = torpedo_target_pos - torpedo_pos;
755 vec_to_enemy_normal = VectorNormalize(vec_to_enemy);
757 angle_to_enemy = VectorDot(forward_dir, vec_to_enemy_normal);
759 if( angle_to_enemy >= max_angle )
761 return vec_to_enemy_normal;
767 plane_normal = VectorCross(forward_dir, vec_to_enemy_normal);
768 perpendicular_normal = VectorCross(plane_normal, forward_dir);
770 torpedo_dir = forward_dir * cos(max_angle) + perpendicular_normal * sin(max_angle);
779 torpedo_target_pos = torpedo_target.origin + torpedo_target_offset;
780 torpedo =
Spawn(
"script_model", torpedo_pos );
783 torpedo.torpedo_trail_iterations = 0;
784 torpedo.raz_torpedo_owner =
self;
788 angles_to_enemy = VectorToAngles( vec_to_enemy );
789 torpedo.angles = angles_to_enemy;
790 normal_vector = VectorNormalize( vec_to_enemy );
791 torpedo.torpedo_old_normal_vector = normal_vector;
792 torpedo.knockdown_iterations = 0;
800 while( isDefined( torpedo ))
802 if( !isdefined( torpedo_target) || torpedo.torpedo_trail_iterations >= max_trail_iterations )
810 torpedo.torpedo_trail_iterations += 1;
819 self endon(
"death" );
820 self endon(
"detonated" );
823 While( isdefined( torpedo) && isdefined( torpedo_target ))
825 torpedo_target_pos = torpedo_target.origin + torpedo_target_offset;
839 self endon(
"death" );
840 self endon(
"detonated" );
842 if( !isDefined(
self.torpedo_max_yaw_cos ) )
845 self.torpedo_max_yaw_cos = Cos( torpedo_yaw_per_interval );
848 if( isDefined(
self.torpedo_old_normal_vector ) )
850 torpedo_target_point = torpedo_target.origin + (0,0, 48);
851 if( isPlayer( torpedo_target ))
853 torpedo_target_point = torpedo_target GetPlayerCameraPos();
855 vector_to_target = torpedo_target_point -
self.origin;
856 normal_vector = VectorNormalize( vector_to_target );
858 flat_mapped_normal_vector = VectorNormalize( (normal_vector[0], normal_vector[1], 0) );
859 flat_mapped_old_normal_vector = VectorNormalize( (
self.torpedo_old_normal_vector[0],
self.torpedo_old_normal_vector[1], 0) );
860 dot = VectorDot( flat_mapped_normal_vector, flat_mapped_old_normal_vector );
871 if( dot <
self.torpedo_max_yaw_cos )
873 new_vector = normal_vector -
self.torpedo_old_normal_vector;
874 angle_between_vectors = Acos( dot );
876 if( !isDefined( angle_between_vectors ))
878 angle_between_vectors = 180;
881 if(angle_between_vectors == 0)
883 angle_between_vectors = 0.0001;
888 ratio = max_angle_per_interval / angle_between_vectors;
895 new_vector = new_vector * ratio;
896 new_vector = new_vector +
self.torpedo_old_normal_vector;
897 normal_vector = VectorNormalize( new_vector );
901 normal_vector =
self.torpedo_old_normal_vector;
906 move_vector = move_distance * normal_vector;
908 move_to_point =
self.origin + move_vector;
918 trace = BulletTrace(
self.origin, move_to_point,
false,
self );
919 if(
trace[
"surfacetype" ] !==
"none" )
921 detonate_point =
trace[
"position" ];
923 dist_sq = DistanceSquared( detonate_point,
self.origin );
924 move_dist_sq = move_distance * move_distance;
925 ratio = dist_sq / move_dist_sq;
932 self.torpedo_old_normal_vector = normal_vector;
939 self endon(
"death" );
940 self endon(
"detonated" );
943 if(
self.torpedo_trail_iterations >= 1 )
945 trace = BulletTrace(
self.origin + (0,0,10),
self.origin - (0,0,surface_check_offset),
false,
self );
946 if(
trace[
"surfacetype" ] !==
"none" )
955 self endon(
"death" );
957 While( isDefined(
self ))
959 if(isdefined(target))
961 if( IsPlayer( target ) )
963 torpedo_target_position = target.origin + ( 0,0,48 );
967 torpedo_target_position = target.origin;
970 prediction_time = 0.3;
973 if( isDefined(
self.knockdown_iterations ) &&
self.knockdown_iterations < 3 )
975 if(
self.knockdown_iterations == 0 )
977 prediction_time = 0.075;
980 if(
self.knockdown_iterations == 1 )
982 prediction_time = 0.15;
985 if(
self.knockdown_iterations == 2 )
987 prediction_time = 0.225;
991 self.knockdown_iterations += 1;
993 vector_to_target = torpedo_target_position -
self.origin;
994 normal_vector = VectorNormalize( vector_to_target );
996 move_vector = move_distance * normal_vector;
998 self.angles = VectorToAngles( move_vector );
1002 velocity =
self GetVelocity();
1003 velocityMag = Length(velocity);
1005 b_sprinting = velocityMag >= 40;
1010 move_vector = velocity * predict_time;
1015 if(!isdefined(b_sprinting) || b_sprinting ==
true)
1017 predicted_pos =
self.origin + move_vector;
1032 if( a_filtered_zombies.size > 0 )
1036 foreach( zombie
in a_filtered_zombies )
1038 zombie.knockdown =
true;
1040 zombie_to_target =
self.origin - zombie.origin;
1041 zombie_to_target_2d = VectorNormalize( ( zombie_to_target[0], zombie_to_target[1], 0 ) );
1043 zombie_forward = AnglesToForward( zombie.angles );
1044 zombie_forward_2d = VectorNormalize( ( zombie_forward[0], zombie_forward[1], 0 ) );
1046 zombie_right = AnglesToRight( zombie.angles );
1047 zombie_right_2d = VectorNormalize( ( zombie_right[0], zombie_right[1], 0 ) );
1049 dot = VectorDot( zombie_to_target_2d, zombie_forward_2d );
1053 zombie.knockdown_direction =
"front";
1056 else if ( dot < 0.5 && dot > -0.5 )
1058 dot = VectorDot( zombie_to_target_2d, zombie_right_2d );
1061 zombie.knockdown_direction =
"right";
1074 zombie.knockdown_direction =
"left";
1080 zombie.knockdown_direction =
"back";
1091 self endon(
"death" );
1092 self endon(
"detonated" );
1099 self endon(
"death" );
1101 self notify(
"razSprintKnockdownZombies");
1102 self endon(
"razSprintKnockdownZombies");
1110 self notify(
"detonated" );
1113 raz_torpedo_owner =
self.raz_torpedo_owner;
1120 if( isdefined(
self ) )
1124 w_weapon = GetWeapon(
"none" );
1125 explosion_point = torpedo.origin;
1133 if( isdefined( raz_torpedo_owner ) &&
IS_TRUE( level.b_raz_ignore_mangler_cooldown ))
1135 raz_torpedo_owner.next_torpedo_time = GetTime();
1138 if ( isdefined(
self ) )
1148 players = GetPlayers();
1150 v_length =
SQR(100);
1152 for( i = 0; i < players.size; i++ )
1154 player = players[i];
1156 if( !IsAlive( player ) )
1161 if( player.sessionstate ==
"spectator" )
1166 if( player.sessionstate ==
"intermission" )
1176 if( player IsNoTarget() )
1181 if ( !player IsOnGround() )
1187 n_distance = Distance2DSquared( torpedo_origin, player.origin );
1189 if( n_distance < 0.01 )
1194 if( n_distance < v_length)
1196 v_dir = player.origin - torpedo_origin;
1197 v_dir = (v_dir[0], v_dir[1], 0.1);
1198 v_dir = VectorNormalize( v_dir );
1200 n_push_strength = GetDvarInt(
"raz_n_push_strength", 500);
1201 n_push_strength = 200 + RandomInt( n_push_strength - 200 );
1203 v_player_velocity = player GetVelocity();
1204 player SetVelocity( v_player_velocity + (v_dir * n_push_strength) );
1211 Earthquake( 0.4, 0.8,
self.origin, 300 );
1213 for(i = 0;i < level.activeplayers.size; i++)
1215 distanceSq = DistanceSquared(
self.origin, level.activeplayers[i].origin + (0, 0, 48));
1223 level.activeplayers[i] playrumbleonentity(
"damage_heavy");
1229 if( zombie.knockdown ===
true )
1239 knockdown_dist = 48;
1240 check_pos = zombie.origin;
1242 if( !isActor( target ))
1244 check_pos = zombie GetCentroid();
1245 knockdown_dist = 64;
1248 knockdown_dist_sq = knockdown_dist * knockdown_dist;
1249 dist_sq = DistanceSquared( predicted_pos, check_pos );
1251 if( dist_sq > knockdown_dist_sq )
1256 origin = target.origin;
1258 facing_vec = AnglesToForward( target.angles );
1259 enemy_vec = zombie.origin - origin;
1261 enemy_yaw_vec = (enemy_vec[0], enemy_vec[1], 0);
1262 facing_yaw_vec = (facing_vec[0], facing_vec[1], 0);
1264 enemy_yaw_vec = VectorNormalize( enemy_yaw_vec );
1265 facing_yaw_vec = VectorNormalize( facing_yaw_vec );
1267 enemy_dot = VectorDot( facing_yaw_vec, enemy_yaw_vec );
1280 #namespace razServerUtils;
1285 self.next_torpedo_time = GetTime();
1286 self.razHasGunAttached =
true;
1287 self.razHasHelmet =
true;
1288 self.razHasLeftShoulderArmor =
true;
1289 self.razHasChestArmor =
true;
1290 self.razHasRightThighArmor =
true;
1291 self.razHasLeftThighArmor =
true;
1292 self.razHasGoneBerserk =
false;
1293 if( !isDefined( level.razGunHealth ) )
1297 if( !isDefined( level.razMaxHealth ) )
1299 level.razMaxHealth =
self.health;
1301 if( !isDefined( level.razHelmetHealth ))
1305 if( !isDefined( level.razLeftShoulderArmorHealth ))
1309 if( !isDefined( level.razChestArmorHealth ))
1313 if( !isDefined( level.razThighArmorHealth ))
1317 self.maxHealth = level.razMaxHealth;
1318 self.razGunHealth = level.razGunHealth;
1319 self.razHelmetHealth = level.razHelmetHealth;
1320 self.razChestArmorHealth = level.razChestArmorHealth;
1321 self.razRightThighHealth = level.razThighArmorHealth;
1322 self.razLeftThighHealth = level.razThighArmorHealth;
1323 self.razLeftShoulderArmorHealth = level.razLeftShoulderArmorHealth;
1325 self.canBeTargetedByTurnedZombies=
true;
1326 self.no_widows_wine =
true;
1327 self.flame_fx_timeout = 3;
1337 self endon(
"death");
1338 self endon(
"disconnect");
1342 self waittill(
"melee_fire");
1345 foreach( zombie
in a_zombies )
1350 heightDiff = abs(zombie.origin[2] -
self.origin[2]);
1355 distance2DSq = Distance2DSquared(zombie.origin,
self.origin);
1357 if( distance2DSq >
SQR(90) )
1360 raz_forward = AnglesToForward(
self.angles );
1361 vect_to_enemy = zombie.origin -
self.origin;
1363 if( VectorDot(raz_forward, vect_to_enemy) <= 0 )
1369 right_vect = AnglesToRight(
self.angles );
1371 projected_distance = VectorDot(vect_to_enemy, right_vect);
1373 if(abs(projected_distance) > 35)
1380 val = randomint( 100 );
1387 val = randomint( 100 );
1397 val = randomint( 100 );
1428 if( !
IS_TRUE(
self.razHasGunAttached ))
1434 if( !
IS_TRUE(
self.razHasChestArmor ))
1444 if( !
IS_TRUE(
self.razHasLeftShoulderArmor ))
1451 if( !
IS_TRUE(
self.razHasRightThighArmor ))
1457 if( !
IS_TRUE(
self.razHasLeftThighArmor ))
1463 if( !
IS_TRUE(
self.razHasHelmet ) )
1469 function private razDamageCallback( inflictor, attacker,
damage, dFlags, mod, weapon, point, dir, hitLoc, offsetTime, boneIndex, modelIndex )
1473 entity.last_damage_hit_armor =
false;
1475 if( isDefined( attacker ) && attacker == entity )
1480 if( mod !==
"MOD_PROJECTILE_SPLASH" )
1482 if(
IS_TRUE( entity.razHasGunAttached ))
1486 if (
IS_TRUE( b_hit_shoulder_weakpoint ))
1492 if( !
IS_TRUE(entity.razHasGunAttached))
1494 post_hit_health = entity.health -
damage;
1496 post_hit_health_percent = ( post_hit_health - gun_detach_damage ) / entity.maxHealth;
1505 return gun_detach_damage;
1513 if(
IS_TRUE( entity.razHasChestArmor ))
1517 if( b_hit_chest || hitloc ===
"torso_lower" || hitloc ===
"torso_mid" )
1520 entity.last_damage_hit_armor =
true;
1526 if(
IS_TRUE( entity.razHasLeftShoulderArmor ))
1530 if( b_hit_l_shoulder_armor )
1533 entity.last_damage_hit_armor =
true;
1539 if(
IS_TRUE( entity.razHasRightThighArmor ))
1543 if( b_hit_r_thigh_armor )
1546 entity.last_damage_hit_armor =
true;
1552 if(
IS_TRUE( entity.razHasLeftThighArmor ))
1556 if( b_hit_l_thigh_armor )
1559 entity.last_damage_hit_armor =
true;
1566 if(
IS_TRUE( entity.razHasHelmet ) )
1570 if( b_hit_head || hitloc ===
"neck" || hitloc ===
"helmet" )
1573 entity.last_damage_hit_armor =
true;
1586 b_hit_location =
false;
1588 if ( isDefined( hitloc) && hitloc !=
"none" )
1590 if ( hitLoc == location )
1592 b_hit_location =
true;
1597 dist_sq = DistanceSquared( point, entity GetTagOrigin( tag ));
1599 if( dist_sq <= hit_radius_sq )
1601 b_hit_location =
true;
1605 return b_hit_location;
1611 entity.razGunHealth = entity.razGunHealth -
damage;
1613 post_hit_health = entity.health -
damage;
1614 post_hit_health_percent = post_hit_health / entity.maxHealth;
1616 if( entity.razGunHealth > 0 )
1621 if( entity.razGunHealth <= 0 )
1623 entity.razGunHealth = 0;
1625 entity.razHasGunAttached =
false;
1626 entity.invoke_sprint_time = undefined;
1627 entity.started_running =
true;
1636 weapon = GetWeapon(
"raz_melee" );
1638 RadiusDamage(
self.origin + (0,0,18),
RAZ_GUN_DETACH_EXPLOSION_RADIUS, explosion_max_damage, explosion_min_damage, entity,
"MOD_PROJECTILE_SPLASH", weapon );
1640 self detach(
"c_zom_dlc3_raz_cannon_arm" );
1647 level notify(
"raz_arm_detach", attacker );
1648 self notify(
"raz_arm_detach", attacker );
1656 entity.razHelmetHealth = entity.razHelmetHealth -
damage;
1657 if( entity.razHelmetHealth <= 0 )
1661 entity.razHasHelmet =
false;
1664 level notify(
"raz_mask_destroyed", attacker );
1672 entity.razChestArmorHealth = entity.razChestArmorHealth -
damage;
1673 if( entity.razChestArmorHealth <= 0 )
1682 entity.razHasChestArmor =
false;
1691 entity.razLeftShoulderArmorHealth = entity.razLeftShoulderArmorHealth -
damage;
1692 if( entity.razLeftShoulderArmorHealth <= 0 )
1698 entity.razHasLeftShoulderArmor =
false;
1707 entity.razLeftThighHealth = entity.razLeftThighHealth -
damage;
1708 if( entity.razLeftThighHealth <= 0 )
1713 entity.razHasLeftThighArmor =
false;
1722 entity.razRightThighHealth = entity.razRightThighHealth -
damage;
1723 if( entity.razRightThighHealth <= 0 )
1728 entity.razHasRightThighArmor =
false;