// ------------------------------------------------------- // Special Weapon code (Deathmatch only) // // The main procedure is at the end, this is called every // frame during a special attack. // ------------------------------------------------------- void() SpecialWeaponChange = { if (self.character == CHAR_WOLVERINE) { if (!self.special_weapon) sprint(self, "Claw Attack selected.\n"); else sprint(self, "Jump Attack selected.\n"); } else if (self.character == CHAR_STORM) { if (!self.special_weapon) sprint(self, "Wind Attack selected.\n"); else sprint(self, "Lightning Attack selected.\n"); } else if (self.character == CHAR_CYCLOPS) { if (!self.special_weapon) sprint(self, "Fast Laser selected.\n"); else sprint(self, "Mega-Laser selected.\n"); } else if (self.character == CHAR_PSYLOCKE) { if (!self.special_weapon) sprint(self, "Sword Attack selected.\n"); else sprint(self, "Psychic Paralyze selected.\n"); } else if (self.character == CHAR_ANGEL) { if (!self.special_weapon) sprint(self, "Dart Spray selected.\n"); else sprint(self, "Wing Defense selected.\n"); } else if (self.character == CHAR_BEAST) { if (!self.special_weapon) sprint(self, "Triple Punch selected.\n"); else sprint(self, "Floor Pound selected.\n"); } else if (self.character == CHAR_GAMBIT) { if (!self.special_weapon) sprint(self, "Staff Attack selected.\n"); else sprint(self, "Throwing Cards selected.\n"); } else if (self.character == CHAR_ICEMAN) { if (!self.special_weapon) sprint(self, "Shard Attack selected.\n"); else sprint(self, "Freeze Blast selected.\n"); } else if (self.character == CHAR_BISHOP) { if (!self.special_weapon) sprint(self, "Gun Attack selected.\n"); else sprint(self, "Energy Blast selected.\n"); } else if (self.character == CHAR_ROGUE) { if (!self.special_weapon) sprint(self, "Single Punch selected.\n"); else sprint(self, "Super Punch selected.\n"); } else if (self.character == CHAR_CANNONBALL) { if (!self.special_weapon) sprint(self, "Punch Attack selected.\n"); else sprint(self, "Flying Punch selected.\n"); } else if (self.character == CHAR_PHOENIX) { if (!self.special_weapon) sprint(self, "Tractor Beam selected.\n"); else sprint(self, "Homing Blast selected.\n"); } }; void(float side) Wolvy_Melee = { local entity other; makevectors (self.angles); traceline(self.origin, self.origin + v_forward * 48, FALSE, self); if ((trace_ent != world) && (trace_ent.takedamage != DAMAGE_NO)) other = trace_ent; else return; sound (self, CHAN_WEAPON, "demon/dhit2.wav", 1, ATTN_NORM); T_Damage (other, self, self, 15); SpawnMeatSpray (self.origin + v_forward*16, side * v_right); }; void() Wolvy_JumpThink = { local float ldmg; local vector dir; if (self.health <= 0) return; // check for enemy getting hit makevectors(self.v_angle); dir = v_forward; traceline(self.origin, self.origin + dir * 128, FALSE, self); if ((trace_ent != world) && (trace_ent.takedamage != DAMAGE_NO)) { ldmg = 8 + 5*random(); T_Damage (trace_ent, self, self, ldmg); trace_ent.punchangle_x = -10; sound (self, CHAN_WEAPON, "demon/dhit2.wav", 1, ATTN_NORM); } }; void() Wolvy_Jump = { if (!(self.flags & FL_ONGROUND)) return; makevectors (self.v_angle); self.origin_z = self.origin_z + 1; self.velocity = v_forward * 700 + '0 0 210'; if (self.velocity_z > 350) self.velocity_z = 350; sound (self, CHAN_BODY, "player/plyrjmp8.wav", 1, ATTN_NORM); if (self.flags & FL_ONGROUND) self.flags = self.flags - FL_ONGROUND; }; void() Storm_Lightning = { local vector dir; self.effects = self.effects | EF_MUZZLEFLASH; makevectors(self.v_angle); dir = v_forward; traceline (self.origin + '0 0 16', self.origin + dir*600 + '0 0 16', TRUE, self); msg_entity = self; WriteByte (MSG_ONE, SVC_TEMPENTITY); WriteByte (MSG_ONE, TE_LIGHTNING1); WriteEntity (MSG_ONE, self); WriteCoord (MSG_ONE, self.origin_x); WriteCoord (MSG_ONE, self.origin_y); WriteCoord (MSG_ONE, self.origin_z + 8); WriteCoord (MSG_ONE, trace_endpos_x); WriteCoord (MSG_ONE, trace_endpos_y); WriteCoord (MSG_ONE, trace_endpos_z); // show lightning differently for others msg_entity = find(msg_entity, classname, "player"); if (msg_entity == world) msg_entity = find(msg_entity, classname, "player"); while (msg_entity != self) { WriteByte (MSG_ONE, SVC_TEMPENTITY); WriteByte (MSG_ONE, TE_LIGHTNING1); WriteEntity (MSG_ONE, self); WriteCoord (MSG_ONE, self.origin_x); WriteCoord (MSG_ONE, self.origin_y); WriteCoord (MSG_ONE, self.origin_z + 20); WriteCoord (MSG_ONE, trace_endpos_x); WriteCoord (MSG_ONE, trace_endpos_y); WriteCoord (MSG_ONE, trace_endpos_z); msg_entity = find(msg_entity, classname, "player"); if (msg_entity == world) msg_entity = find(msg_entity, classname, "player"); } LightningDamage (self.origin + '0 0 16', trace_endpos, self, 15); }; void() Storm_Wind = { local entity trav; local float strength, dist; local vector vect, vect_angle; sound (self, CHAN_WEAPON, "storm/w_attack.wav", 1, ATTN_NORM); trav = findradius(self.origin, 256); while (trav != world) { // check that the object is damage-able and is infront of self vect = normalize(trav.origin - self.origin); vect_angle = vectoangles(vect); if ((trav != self) && ((trav.takedamage) && (trav.movetype)) && (fabs( angle_diff( vect_angle_y, self.angles_y)) < 35)) { // give em some wind strength = 200; dist = vlen(trav.origin - self.origin); if (dist > 128) { // reduce strength of blast strength = ((dist - 128) / 128) * strength; } // blast now trav.flags = trav.flags - (trav.flags & FL_ONGROUND); trav.velocity = (trav.velocity * 0.5) + (vect * 600); trav.velocity_z = 300; trav.angles = trav.v_angle = self.angles; trav.punchangle_x = -20; trav.fixangle = TRUE; } trav = trav.chain; } self.last_wind = time; }; void() LaserTouch; void() DM_Cyclops_Fast_Laser = { local entity missile; local vector vect; self.effects = self.effects | EF_MUZZLEFLASH; stuffcmd(self, "rf\n"); // flash screen red sound (self, CHAN_VOICE, "items/inv1.wav", 1, ATTN_NORM); missile = spawn (); missile.owner = self; missile.movetype = MOVETYPE_BOUNCE; missile.solid = SOLID_BBOX; missile.classname = "laser"; makevectors(self.v_angle); missile.velocity = v_forward * 1700; missile.angles = vectoangles(missile.velocity); missile.old_velocity = missile.velocity; missile.touch = LaserTouch; missile.last_touch = 0; missile.oldorigin = missile.origin; missile.nextthink = time + 2; missile.think = SUB_Remove; setmodel (missile, "progs/claser1.mdl"); setsize (missile, '0 0 0', '0 0 0'); setorigin (missile, self.origin + v_forward * 16 + '0 0 22'); }; void() DM_Big_Laser_Touch = { if (other == self.owner) return; if (other.takedamage == DAMAGE_AIM) { spawn_touchblood (20); T_Damage(other, self, self.owner, 30); remove(self); return; } self.last_touch = time; sound (self, CHAN_WEAPON, "doors/airdoor2.wav", 1, ATTN_NORM); if (self.velocity == '0 0 0') remove(self); }; void() DM_Cyclops_Big_Laser = { local entity missile; local vector vect; self.effects = self.effects | EF_MUZZLEFLASH; stuffcmd(self, "rf\n"); // flash screen red sound (self, CHAN_VOICE, "items/inv1.wav", 1, ATTN_NORM); missile = spawn (); missile.owner = self; missile.movetype = MOVETYPE_BOUNCE; missile.solid = SOLID_BBOX; missile.classname = "laser"; makevectors(self.v_angle); missile.velocity = v_forward * 1200; missile.angles = vectoangles(missile.velocity); missile.old_velocity = missile.velocity; missile.touch = DM_Big_Laser_Touch; missile.last_touch = 0; missile.oldorigin = missile.origin; missile.nextthink = time + 2; missile.think = SUB_Remove; setmodel (missile, "progs/claser1.mdl"); setsize (missile, '0 0 0', '0 0 0'); setorigin (missile, self.origin + v_forward * 16 + '0 0 22'); }; void() DM_Psylocke_Sword = { local entity plyr; local vector delta; local float ldmg; makevectors(self.v_angle); traceline(self.origin, self.origin + v_forward*55, FALSE, self); if (trace_ent.takedamage == DAMAGE_AIM) plyr = trace_ent; else return; // if ((plyr = FindSightEnemy(self.origin, v_forward, 60, 40, "player", self)) == world) // return; /* delta = plyr.origin - self.origin; if (vlen(delta) > 70) return; */ ldmg = 15 + random() * 5; T_Damage (plyr, self, self, ldmg); }; void() DM_Psylocke_Parallize = { makevectors(self.v_angle); traceline(self.origin, self.origin + v_forward*48, FALSE, self); if (trace_ent.takedamage == DAMAGE_AIM) { // got 'em sound(self, CHAN_WEAPON, "player/what_1.wav", 1, ATTN_NORM); trace_ent.parallize_time = time + 3; trace_ent.x_flags = trace_ent.x_flags | X_PARALLIZED; trace_ent.parallized_velocity = '0 0 0'; centerprint(trace_ent, "You have been paralyzed"); stuffcmd(trace_ent, "pl\n"); } }; void(float heading_ofs) DM_AngelFeather = { local vector newangle, targ_vect; local entity missile; newangle = self.v_angle; newangle_y = anglemod(newangle_y + heading_ofs); newangle_x = newangle_x + (random() * 10) - 5; makevectors(newangle); launch_spike (self.origin + '0 0 16' + v_forward*14, v_forward); newmis.classname = "angel_dart"; setmodel (newmis, "progs/dart.mdl"); setsize(newmis, '0 0 0', '0 0 0'); }; void() DM_BeastPunch = { local vector delta; local float ldmg; local entity plyr; makevectors(self.v_angle); traceline(self.origin, self.origin + v_forward*55, FALSE, self); if (trace_ent.takedamage == DAMAGE_AIM) plyr = trace_ent; else return; ldmg = 9 + random() * 3; T_Damage (plyr, self, self, ldmg); if (random() < 0.5) sound(self, CHAN_WEAPON, "generic/punch2.wav", 1, ATTN_NORM); else sound(self, CHAN_WEAPON, "generic/punch3.wav", 1, ATTN_NORM); }; void() BeastPowTouch; void() BeastPowThink; void() DM_BeastPound = { local entity trav, plyr; local entity missile; local vector vec; missile = spawn(); missile.classname = "beast_power"; missile.owner = self; missile.solid = SOLID_TRIGGER; missile.movetype = MOVETYPE_FLY; setsize(missile, '0 0 0', '0 0 0'); setmodel(missile, "progs/pow.mdl"); makevectors(self.angles); if ((plyr = FindSightEnemy(self.origin, v_forward, 256, 20, "player", self)) != world) missile.velocity = normalize(plyr.origin - self.origin + plyr.velocity * 0.5) * 750; else { missile.velocity = v_forward * 750; } missile.velocity_z = 0; setorigin(missile, self.origin + v_forward * 16); vec = missile.velocity; traceline(missile.origin + vec*frametime*2 + '0 0 32', missile.origin + vec*frametime*2 - '0 0 48', TRUE, world); if (trace_fraction <= 1) { missile.velocity = normalize(trace_endpos + '0 0 24' - missile.origin) * 750; traceline(missile.origin + '0 0 32', missile.origin - '0 0 48', TRUE, world); setorigin(missile, trace_endpos + '0 0 24'); } missile.touch = BeastPowTouch; missile.think = BeastPowThink; missile.nextthink = time + 0.05; missile.spawn_time = time; sound (self, CHAN_BODY, "weapons/r_exp3.wav", 0.4, ATTN_NORM); sound (self, CHAN_WEAPON, "doors/stndr1.wav", 1, ATTN_NORM); // send players airbourne trav = find(world, classname, "player"); while (trav != world) { if ((trav.flags & FL_ONGROUND) && (vlen(trav.origin - self.origin) < 256)) trav.velocity_z = 200; trav = find(trav, classname, "player"); } }; void() DM_Gambit_Strike = { local entity plyr; local vector vect; local float damg; makevectors(self.v_angle); traceline(self.origin, self.origin + v_forward*55, FALSE, self); if (trace_ent.takedamage == DAMAGE_AIM) plyr = trace_ent; else return; damg = 20 + random() * 5; T_Damage (plyr, self, self, damg); }; void(float heading_ofs, float zofs) DM_GambitCard = { local vector newangle, targ_vect, ofs; local entity missile; makevectors(self.v_angle); targ_vect = v_forward; newangle = vectoangles(targ_vect); newangle_x = -1 * newangle_x; newangle_y = anglemod(newangle_y + heading_ofs); makevectors(newangle); ofs = '0 0 0'; ofs_z = zofs; launch_spike (self.origin + ofs + v_forward*14, v_forward); newmis.classname = "gambit_card"; setmodel (newmis, "progs/card.mdl"); setsize(newmis, '0 0 0', '0 0 0'); }; void(vector org, vector dir) spawn_shard; void(float offs) DM_Iceman_Shard = { local vector org, vect, ang; ang = self.v_angle; ang_y = anglemod(ang_y + offs); makevectors (ang); vect = v_forward; org = self.origin + '0 0 12'; spawn_shard(org, vect); }; void(vector org, vector dir) spawn_iceball; void() DM_Iceman_Iceball = { local vector org,o2; makevectors (self.v_angle); org = self.origin + v_forward * 12 + '0 0 16'; spawn_iceball(org, v_forward); }; void(float r_ofs) DM_Bishop_Shoot = { local vector vect; local entity missile; self.effects = self.effects | EF_MUZZLEFLASH; makevectors(self.v_angle); sound (self, CHAN_WEAPON, "doors/airdoor2.wav", 1, ATTN_NORM); launch_spike (self.origin + '0 0 10' + v_forward*14 + v_right * r_ofs, v_forward); newmis.dmg = 15 + random() * 5; newmis.classname = "bishop_laser"; newmis.velocity = v_forward * 2000; setmodel (newmis, "progs/laser.mdl"); setsize(newmis, '0 0 0', '0 0 0'); }; void() BishopSpecialTouch; void() DM_Bishop_Special = { local vector vect; local entity missile; self.effects = self.effects | EF_MUZZLEFLASH; sound (self, CHAN_WEAPON, "boss1/throw.wav", 1, ATTN_NORM); makevectors(self.v_angle); vect = v_forward; launch_spike (self.origin + '0 0 12' + v_forward*14, vect); newmis.velocity = newmis.velocity * 0.75; newmis.classname = "bishop_special"; newmis.touch = BishopSpecialTouch; newmis.avelocity_z = 300; setmodel (newmis, "progs/bisblast.mdl"); setsize(newmis, '0 0 0', '0 0 0'); }; void(float damage) DM_Rogue_Punch = { local entity plyr; local float damg; makevectors(self.v_angle); traceline(self.origin, self.origin + v_forward*55, FALSE, self); if (trace_ent.takedamage == DAMAGE_AIM) plyr = trace_ent; else return; // hurt enemy T_Damage(plyr, self, self, damage); sound(self, CHAN_WEAPON, "zombie/z_hit.wav", 1, ATTN_NORM); }; void() DM_Rogue_Fly = { local float vspeed, maxspeed; makevectors(self.v_angle); vspeed = vlen(self.velocity); maxspeed = cvar("sv_maxspeed"); if (vspeed < maxspeed) { self.velocity = self.old_velocity + v_forward * 2000 * frametime; if (vlen(self.velocity) > (maxspeed + 100)) self.velocity = normalize(self.velocity) * (maxspeed + 50); } else { self.velocity = v_forward * (maxspeed + 50); } self.old_velocity = self.velocity; // check for punch traceline(self.origin + '0 0 24', self.origin + '0 0 24' + v_forward*64, FALSE, self); if (trace_ent.takedamage == DAMAGE_AIM) { T_Damage(trace_ent, self, self, 40 + random()*8); sound(self, CHAN_WEAPON, "zombie/z_hit.wav", 1, ATTN_NORM); } }; void(float damage) DM_Cannon_Punch = { local entity plyr; local float damg; sound (self, CHAN_ITEM, "generic/swing1.wav", 1, ATTN_NORM); makevectors(self.v_angle); traceline(self.origin, self.origin + v_forward*55, FALSE, self); if (trace_ent.takedamage == DAMAGE_AIM) plyr = trace_ent; else return; // hurt enemy T_Damage(plyr, self, self, damage); if (random() < 0.5) sound(self, CHAN_WEAPON, "generic/punch2.wav", 1, ATTN_NORM); else sound(self, CHAN_WEAPON, "generic/punch3.wav", 1, ATTN_NORM); }; void() DM_Cannon_Fly = { local float vspeed, maxspeed; makevectors(self.v_angle); vspeed = vlen(self.velocity); maxspeed = cvar("sv_maxspeed"); if (vspeed < maxspeed) { self.velocity = self.old_velocity + v_forward * 2000 * frametime; if (vlen(self.velocity) > (maxspeed + 100)) self.velocity = normalize(self.velocity) * (maxspeed + 150); } else { self.velocity = v_forward * (maxspeed + 150); } if (self.last_flame_sound < (time - 0.75)) { if (self.last_weapon_channel != CHAN_ITEM) { sound (self, CHAN_ITEM, "cannon/flyloop.wav", 1, ATTN_NORM); self.last_weapon_channel = CHAN_ITEM; } else { sound (self, CHAN_VOICE, "cannon/flyloop.wav", 1, ATTN_NORM); self.last_weapon_channel = CHAN_VOICE; } self.last_flame_sound = time; } self.old_velocity = self.velocity; // check for punch traceline(self.origin + '0 0 24', self.origin + '0 0 24' + v_forward*64, FALSE, self); if (trace_ent.takedamage == DAMAGE_AIM) { T_Damage(trace_ent, self, self, 40 + random()*8); sound (self, CHAN_BODY, "generic/swing1.wav", 1, ATTN_NORM); if (random() < 0.5) sound(self, CHAN_WEAPON, "generic/punch2.wav", 1, ATTN_NORM); else sound(self, CHAN_WEAPON, "generic/punch3.wav", 1, ATTN_NORM); } if (trace_fraction < 1) { self.weaponframe = 14; // abort fly } }; void() BeamPlayerTouch = { local float vspeed, damg; if (self.last_wall_hit > (time - 1)) return; if (other != world) return; if (self.enemy.enemy != self) { self.enemy = world; self.touch = SUB_Null; return; } vspeed = vlen(self.velocity); if (vspeed < 100) return; // make sure player is travelling somewhat sideways if (fabs(self.velocity_z) > 40) return; // find out which wall was likely to have been hit traceline(self.origin, self.origin + self.velocity * 2, TRUE, self); if (trace_fraction == 1) return; if (fabs(trace_plane_normal_z) > 0.3) return; //bprint(ftos(vspeed)); //bprint("\n"); damg = vspeed / 200; if (damg > 25) damg = 25; // wall damage T_Damage(self, self.enemy, self.enemy, damg); self.last_wall_hit = time; }; void() DM_TractorThink = { local vector ideal_pos; makevectors(self.owner.v_angle); ideal_pos = self.owner.origin + v_forward * self.owner.tractor_dist; if (vlen(ideal_pos - self.owner.enemy.origin) > 8) self.owner.enemy.velocity = self.owner.enemy.tractor_vel = (ideal_pos - self.owner.enemy.origin) * 4; else self.owner.enemy.velocity = self.owner.enemy.tractor_vel = '0 0 0'; self.owner.enemy.flags = self.owner.enemy.flags - (self.owner.enemy.flags & FL_ONGROUND); self.nextthink = time + 0.05; }; void() TractorParticleThink; void() DM_PhoenixStartBeam = { // if player is already in a beam, abort attack if ((self.enemy.x_flags & X_TRACTOR_BEAM_HOLD) && (self.enemy.flags & FL_GODMODE)) { self.enemy = world; return; } sound(self.enemy, CHAN_WEAPON, "items/damage3.wav", 1, ATTN_NORM); self.flags = self.flags | FL_GODMODE; self.last_special = time; self.start_attack_health = self.health; self.tractor_dist = vlen(self.enemy.origin - self.origin); self.enemy.enemy = self; self.enemy.touch = BeamPlayerTouch; self.enemy.x_flags = self.enemy.x_flags | X_TRACTOR_BEAM_HOLD; self.enemy.velocity = self.enemy.tractor_vel = '0 0 100'; setorigin(self.enemy, self.enemy.origin + '0 0 1'); self.enemy.flags = self.enemy.flags - (self.enemy.flags & FL_ONGROUND); self.start_tractor_time = time; self.enemy.start_tractor_time = time; self.move_ent = spawn(); self.move_ent.owner = self; self = self.move_ent; self.flame_ent1 = spawn(); self.flame_ent2 = spawn(); self.flame_ent3 = spawn(); setmodel(self.flame_ent1, "progs/beampart.mdl"); setmodel(self.flame_ent2, "progs/beampart.mdl"); setmodel(self.flame_ent3, "progs/beampart.mdl"); setorigin(self.flame_ent1, self.origin); setorigin(self.flame_ent2, self.origin); setorigin(self.flame_ent3, self.origin); self.flame_ent1.nextthink = time + 0.05; self.flame_ent2.nextthink = time + 0.05; self.flame_ent3.nextthink = time + 0.05; // speed to travel self.flame_ent1.speed = 800; self.flame_ent2.speed = 400; self.flame_ent3.speed = 200; // distance from Phoenix self.flame_ent1.t_length = 0; self.flame_ent2.t_length = 0; self.flame_ent3.t_length = 0; // distance from center of tractor beam self.flame_ent1.z_ofs = 10; self.flame_ent2.z_ofs = 5; self.flame_ent3.z_ofs = 0; // 1 = travelling away from center, -1 = travelling towards center self.flame_ent1.z_ofs_vel = -2; self.flame_ent2.z_ofs_vel = 2.5; self.flame_ent3.z_ofs_vel = 1; self.flame_ent1.think = TractorParticleThink; self.flame_ent2.think = TractorParticleThink; self.flame_ent3.think = TractorParticleThink; self.flame_ent1.owner = self.owner; self.flame_ent2.owner = self.owner; self.flame_ent3.owner = self.owner; self.think = DM_TractorThink; self.nextthink = time + 0.05; self = self.owner; }; void() DM_PhoenixBeamEnd = { if (self.enemy != world) { self.enemy.x_flags = self.enemy.x_flags - (self.enemy.x_flags & X_TRACTOR_BEAM_HOLD); self.enemy.velocity = normalize(self.enemy.origin - self.origin) * 250 + '0 0 100'; // hurt enemy // damage is now inflicted by smashing them against a wall T_Damage(self.enemy, self, self, 10); self.enemy.touch = SUB_Null; self.enemy.punchangle_x = -8; self.enemy = world; } if (self.move_ent != world) { remove(self.move_ent.flame_ent1); remove(self.move_ent.flame_ent2); remove(self.move_ent.flame_ent3); remove(self.move_ent); self.move_ent = world; } }; void() DM_PhoenixFireHoming = { local entity missile, missile_enemy; local vector dir; missile = spawn (); missile.classname = "dm_phoenix_blast"; missile.attack_finished = time + 3; missile.owner = self; missile.movetype = MOVETYPE_FLYMISSILE; missile.solid = SOLID_BBOX; missile.think = GuidedRocketThink; missile.last_guided_search = time; missile.nextthink = time + 0.05; // set missile speed makevectors(self.v_angle); missile.velocity = v_forward; missile.velocity = missile.velocity * 800; missile.angles = vectoangles(missile.velocity); missile.angles_x = -1 * missile.angles_x; missile.touch = T_GuidedMissileTouch; missile.avelocity_z = 300; setmodel (missile, "progs/psyblast.mdl"); setsize (missile, '0 0 0', '0 0 0'); setorigin (missile, self.origin + dir*8 + '0 0 12'); sound(self, CHAN_WEAPON, "cannon/takeoff.wav", 1, ATTN_NORM); }; // ************************************************************************** void() DoSpecialWeaponStuff = { local float frame_num; frame_num = self.weaponframe - 6; if (self.character == CHAR_WOLVERINE) { if (!self.special_weapon) { if (frame_num == 5) Wolvy_Melee(200); else if (frame_num == 9) Wolvy_Melee(-200); } else { if (frame_num == 1) // jump now Wolvy_Jump(); else if ((frame_num >= 7) && (frame_num <= 10)) Wolvy_JumpThink (); } } else if (self.character == CHAR_STORM) { if (!self.special_weapon) { if (frame_num == 5) Storm_Wind(); } else { if ((frame_num >= 7) && (frame_num <= 10)) Storm_Lightning(); if (frame_num == 7) sound (self, CHAN_WEAPON, "storm/l_attack.wav", 1, ATTN_NORM); } } else if (self.character == CHAR_CYCLOPS) { if (!self.special_weapon) { // Fast Laser if ((frame_num == 2) || (frame_num == 7)) DM_Cyclops_Fast_Laser(); } else { // Big Laser Blast if (frame_num == 8) DM_Cyclops_Big_Laser(); } } else if (self.character == CHAR_PSYLOCKE) { if (!self.special_weapon) { // Sword Attack if ((frame_num == 2) || (frame_num == 7)) DM_Psylocke_Sword(); } else { // Parallize Attack if (frame_num == 8) DM_Psylocke_Parallize(); } } else if (self.character == CHAR_ANGEL) { if (!self.special_weapon) { // Throw Darts if ((frame_num >= 3) && (frame_num <= 9)) { DM_AngelFeather( (frame_num - 6) * 5 ); } } else { // Wing Defense if (frame_num == 5) { self.x_flags = self.x_flags | X_ANGEL_DEFENSE; self.flags = self.flags | FL_GODMODE; } else if ((frame_num == 10) && (self.button0)) // stay at this frame while button down self.weaponframe = self.weaponframe - 1; else if (frame_num == 11) { self.x_flags = self.x_flags - (self.x_flags & X_ANGEL_DEFENSE); self.flags = self.flags - (self.flags & FL_GODMODE); } } } else if (self.character == CHAR_BEAST) { if (!self.special_weapon) { // Double Punch if ((frame_num == 4) || (frame_num == 7) || (frame_num == 10)) { DM_BeastPunch(); } } else { // Floor Pound if (frame_num == 4) { // give some jump if (self.flags & FL_ONGROUND) self.velocity_z = 190; } else if (frame_num == 11) { DM_BeastPound(); } } } else if (self.character == CHAR_GAMBIT) { if (!self.special_weapon) { // Staff Attack if (frame_num == 7) DM_Gambit_Strike(); else if (frame_num == 3) sound (self, CHAN_WEAPON, "generic/swing1.wav", 1, ATTN_NORM); } else { // Throw Cards if ((frame_num >= 5) && (frame_num <= 7)) { DM_GambitCard( (frame_num - 6) * -5, 12 ); } if (frame_num == 4) sound (self, CHAN_WEAPON, "boss1/throw.wav", 1, ATTN_NORM); } } else if (self.character == CHAR_ICEMAN) { if (!self.special_weapon) { // Small Shards if ((frame_num >= 3) && (frame_num <= 8)) { DM_Iceman_Shard( (frame_num - 6) * 4 ); } } else { // Big Freeze if (frame_num == 10) DM_Iceman_Iceball(); } } else if (self.character == CHAR_BISHOP) { if (!self.special_weapon) { // Dual Guns if (frame_num == 2) DM_Bishop_Shoot(6); else if (frame_num == 7) DM_Bishop_Shoot(-6); } else { if (frame_num == 5) DM_Bishop_Special(); } } else if (self.character == CHAR_ROGUE) { if (!self.special_weapon) { // Dual Punch if ((frame_num == 4) || (frame_num == 10)) DM_Rogue_Punch(10); } else { // Flying Punch if (frame_num == 2) { self.last_special = time; } else if (frame_num == 3) { if (self.button0) { self.x_flags = self.x_flags | X_FLYING; self.flags = self.flags | FL_ONGROUND; DM_Rogue_Fly(); if (self.last_special > (time - 5) && (trace_ent.classname != "player")) self.weaponframe = self.weaponframe - 1; } } else if (frame_num == 6) { self.x_flags = self.x_flags - (self.x_flags & X_FLYING); } } } else if (self.character == CHAR_CANNONBALL) { if (!self.special_weapon) { // Punch if (frame_num == 6) DM_Cannon_Punch(10); } else { // Flying Punch if (frame_num == 1) { sound(self, CHAN_ITEM, "cannon/takeoff.wav", 1, ATTN_NORM); } if (frame_num < 6) { self.last_special = time; self.x_flags = self.x_flags | X_FLYING; self.effects = self.effects | EF_DIMLIGHT; self.velocity_z = self.old_velocity_z = 100; } else if (frame_num < 9) { self.flags = self.flags | FL_ONGROUND; DM_Cannon_Fly(); if ((self.button0) && (trace_fraction == 1) && (frame_num == 8) && (self.last_special > (time - 5))) { self.weaponframe = self.weaponframe - 3; } } else if (frame_num == 9) { self.last_special2 = time; self.attack_finished = time + 2; self.effects = self.effects - (self.effects & EF_DIMLIGHT); // DM_Cannon_Punch(30 + random()*15); self.x_flags = self.x_flags - (self.x_flags & X_FLYING); } } } else if (self.character == CHAR_PHOENIX) { if (!self.special_weapon) { // Tractor Beam if (frame_num == 1) self.enemy = world; else if (frame_num < 6) { if (self.enemy == world) { makevectors(self.v_angle); traceline(self.origin + '0 0 16', self.origin + '0 0 16' + v_forward * 512, FALSE, self); if (((trace_ent.touch == ammo_touch) || (trace_ent.classname == "guided_rocket") || (trace_ent.classname == "orb") || (trace_ent.flags & FL_MONSTER) || (trace_ent.classname == "player")) && (trace_ent != self)) self.enemy = trace_ent; else self.enemy = world; } } else if (frame_num == 6) { if (self.enemy != world) { DM_PhoenixStartBeam(); } } else if (frame_num == 8) { if ((self.enemy != world) && (self.start_attack_health <= self.health) && (self.start_tractor_time > (time - 4)) && (self.button0) && (self.flags & FL_GODMODE)) { traceline(self.origin, self.enemy.origin, TRUE, world); if (trace_fraction == 1) self.weaponframe = self.weaponframe - 1; } } else if (frame_num == 9) { DM_PhoenixBeamEnd(); self.flags = self.flags - (self.flags & FL_GODMODE); self.enemy = world; } } else { // Homing missile if (frame_num == 4) DM_PhoenixFireHoming(); } } };