From c7ddc423f67236a99956960cf9fe89abf077839b Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Fri, 5 Sep 2008 00:02:14 +0000 Subject: Reformat (beautify) Raven sources and add GPL headers. Subversion-branch: /branches/raven-branch Subversion-revision: 1197 --- src/hexen/p_enemy.c | 7579 ++++++++++++++++++++++++++------------------------- 1 file changed, 3832 insertions(+), 3747 deletions(-) (limited to 'src/hexen/p_enemy.c') diff --git a/src/hexen/p_enemy.c b/src/hexen/p_enemy.c index f9ad16eb..4651d630 100644 --- a/src/hexen/p_enemy.c +++ b/src/hexen/p_enemy.c @@ -1,14 +1,26 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright(C) 1993-1996 Id Software, Inc. +// Copyright(C) 1993-2008 Raven Software +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// +//----------------------------------------------------------------------------- -//************************************************************************** -//** -//** p_enemy.c : Heretic 2 : Raven Software, Corp. -//** -//** $RCSfile: p_enemy.c,v $ -//** $Revision: 1.170 $ -//** $Date: 96/01/06 03:23:28 $ -//** $Author: bgokey $ -//** -//************************************************************************** #include "h2def.h" #include "p_local.h" @@ -29,52 +41,53 @@ extern fixed_t FloatBobOffsets[64]; mobj_t *soundtarget; -void P_RecursiveSound(sector_t *sec, int soundblocks) -{ - int i; - line_t *check; - sector_t *other; - - // Wake up all monsters in this sector - if(sec->validcount == validcount && sec->soundtraversed <= soundblocks+1) - { // Already flooded - return; - } - sec->validcount = validcount; - sec->soundtraversed = soundblocks+1; - sec->soundtarget = soundtarget; - for(i = 0; i < sec->linecount; i++) - { - check = sec->lines[i]; - if(!(check->flags&ML_TWOSIDED)) - { - continue; - } - P_LineOpening(check); - if(openrange <= 0) - { // Closed door - continue; - } - if(sides[check->sidenum[0]].sector == sec) - { - other = sides[check->sidenum[1]].sector; - } - else - { - other = sides[check->sidenum[0]].sector; - } - if(check->flags&ML_SOUNDBLOCK) - { - if(!soundblocks) - { - P_RecursiveSound(other, 1); - } - } - else - { - P_RecursiveSound(other, soundblocks); - } - } +void P_RecursiveSound(sector_t * sec, int soundblocks) +{ + int i; + line_t *check; + sector_t *other; + + // Wake up all monsters in this sector + if (sec->validcount == validcount + && sec->soundtraversed <= soundblocks + 1) + { // Already flooded + return; + } + sec->validcount = validcount; + sec->soundtraversed = soundblocks + 1; + sec->soundtarget = soundtarget; + for (i = 0; i < sec->linecount; i++) + { + check = sec->lines[i]; + if (!(check->flags & ML_TWOSIDED)) + { + continue; + } + P_LineOpening(check); + if (openrange <= 0) + { // Closed door + continue; + } + if (sides[check->sidenum[0]].sector == sec) + { + other = sides[check->sidenum[1]].sector; + } + else + { + other = sides[check->sidenum[0]].sector; + } + if (check->flags & ML_SOUNDBLOCK) + { + if (!soundblocks) + { + P_RecursiveSound(other, 1); + } + } + else + { + P_RecursiveSound(other, soundblocks); + } + } } //---------------------------------------------------------------------------- @@ -86,11 +99,11 @@ void P_RecursiveSound(sector_t *sec, int soundblocks) // //---------------------------------------------------------------------------- -void P_NoiseAlert(mobj_t *target, mobj_t *emmiter) +void P_NoiseAlert(mobj_t * target, mobj_t * emmiter) { - soundtarget = target; - validcount++; - P_RecursiveSound(emmiter->subsector->sector, 0); + soundtarget = target; + validcount++; + P_RecursiveSound(emmiter->subsector->sector, 0); } //---------------------------------------------------------------------------- @@ -99,34 +112,34 @@ void P_NoiseAlert(mobj_t *target, mobj_t *emmiter) // //---------------------------------------------------------------------------- -boolean P_CheckMeleeRange(mobj_t *actor) -{ - mobj_t *mo; - fixed_t dist; - - if(!actor->target) - { - return(false); - } - mo = actor->target; - dist = P_AproxDistance(mo->x-actor->x, mo->y-actor->y); - if(dist >= MELEERANGE) - { - return(false); - } - if(!P_CheckSight(actor, mo)) - { - return(false); - } - if(mo->z > actor->z+actor->height) - { // Target is higher than the attacker - return(false); - } - else if(actor->z > mo->z+mo->height) - { // Attacker is higher - return(false); - } - return(true); +boolean P_CheckMeleeRange(mobj_t * actor) +{ + mobj_t *mo; + fixed_t dist; + + if (!actor->target) + { + return (false); + } + mo = actor->target; + dist = P_AproxDistance(mo->x - actor->x, mo->y - actor->y); + if (dist >= MELEERANGE) + { + return (false); + } + if (!P_CheckSight(actor, mo)) + { + return (false); + } + if (mo->z > actor->z + actor->height) + { // Target is higher than the attacker + return (false); + } + else if (actor->z > mo->z + mo->height) + { // Attacker is higher + return (false); + } + return (true); } //---------------------------------------------------------------------------- @@ -135,34 +148,34 @@ boolean P_CheckMeleeRange(mobj_t *actor) // //---------------------------------------------------------------------------- -boolean P_CheckMeleeRange2(mobj_t *actor) -{ - mobj_t *mo; - fixed_t dist; - - if(!actor->target) - { - return(false); - } - mo = actor->target; - dist = P_AproxDistance(mo->x-actor->x, mo->y-actor->y); - if(dist >= MELEERANGE*2 || dist < MELEERANGE) - { - return(false); - } - if(!P_CheckSight(actor, mo)) - { - return(false); - } - if(mo->z > actor->z+actor->height) - { // Target is higher than the attacker - return(false); - } - else if(actor->z > mo->z+mo->height) - { // Attacker is higher - return(false); - } - return(true); +boolean P_CheckMeleeRange2(mobj_t * actor) +{ + mobj_t *mo; + fixed_t dist; + + if (!actor->target) + { + return (false); + } + mo = actor->target; + dist = P_AproxDistance(mo->x - actor->x, mo->y - actor->y); + if (dist >= MELEERANGE * 2 || dist < MELEERANGE) + { + return (false); + } + if (!P_CheckSight(actor, mo)) + { + return (false); + } + if (mo->z > actor->z + actor->height) + { // Target is higher than the attacker + return (false); + } + else if (actor->z > mo->z + mo->height) + { // Attacker is higher + return (false); + } + return (true); } //---------------------------------------------------------------------------- @@ -171,38 +184,38 @@ boolean P_CheckMeleeRange2(mobj_t *actor) // //---------------------------------------------------------------------------- -boolean P_CheckMissileRange(mobj_t *actor) -{ - fixed_t dist; - - if(!P_CheckSight(actor, actor->target)) - { - return(false); - } - if(actor->flags&MF_JUSTHIT) - { // The target just hit the enemy, so fight back! - actor->flags &= ~MF_JUSTHIT; - return(true); - } - if(actor->reactiontime) - { // Don't attack yet - return(false); - } - dist = (P_AproxDistance(actor->x-actor->target->x, - actor->y-actor->target->y)>>FRACBITS)-64; - if(!actor->info->meleestate) - { // No melee attack, so fire more frequently - dist -= 128; - } - if(dist > 200) - { - dist = 200; - } - if(P_Random() < dist) - { - return(false); - } - return(true); +boolean P_CheckMissileRange(mobj_t * actor) +{ + fixed_t dist; + + if (!P_CheckSight(actor, actor->target)) + { + return (false); + } + if (actor->flags & MF_JUSTHIT) + { // The target just hit the enemy, so fight back! + actor->flags &= ~MF_JUSTHIT; + return (true); + } + if (actor->reactiontime) + { // Don't attack yet + return (false); + } + dist = (P_AproxDistance(actor->x - actor->target->x, + actor->y - actor->target->y) >> FRACBITS) - 64; + if (!actor->info->meleestate) + { // No melee attack, so fire more frequently + dist -= 128; + } + if (dist > 200) + { + dist = 200; + } + if (P_Random() < dist) + { + return (false); + } + return (true); } /* @@ -215,77 +228,80 @@ boolean P_CheckMissileRange(mobj_t *actor) ================ */ -fixed_t xspeed[8] = {FRACUNIT,47000,0,-47000,-FRACUNIT,-47000,0,47000}; -fixed_t yspeed[8] = {0,47000,FRACUNIT,47000,0,-47000,-FRACUNIT,-47000}; +fixed_t xspeed[8] = + { FRACUNIT, 47000, 0, -47000, -FRACUNIT, -47000, 0, 47000 }; +fixed_t yspeed[8] = + { 0, 47000, FRACUNIT, 47000, 0, -47000, -FRACUNIT, -47000 }; #define MAXSPECIALCROSS 8 -extern line_t *spechit[MAXSPECIALCROSS]; -extern int numspechit; - -boolean P_Move(mobj_t *actor) -{ - fixed_t tryx, tryy; - line_t *ld; - boolean good; - - if(actor->flags2&MF2_BLASTED) return(true); - if(actor->movedir == DI_NODIR) - { - return(false); - } - tryx = actor->x+actor->info->speed*xspeed[actor->movedir]; - tryy = actor->y+actor->info->speed*yspeed[actor->movedir]; - if(!P_TryMove(actor, tryx, tryy)) - { // open any specials - if(actor->flags&MF_FLOAT && floatok) - { // must adjust height - if(actor->z < tmfloorz) - { - actor->z += FLOATSPEED; - } - else - { - actor->z -= FLOATSPEED; - } - actor->flags |= MF_INFLOAT; - return(true); - } - if(!numspechit) - { - return false; - } - actor->movedir = DI_NODIR; - good = false; - while(numspechit--) - { - ld = spechit[numspechit]; - // if the special isn't a door that can be opened, return false - if(P_ActivateLine(ld, actor, 0, SPAC_USE)) - { - good = true; - } +extern line_t *spechit[MAXSPECIALCROSS]; +extern int numspechit; + +boolean P_Move(mobj_t * actor) +{ + fixed_t tryx, tryy; + line_t *ld; + boolean good; + + if (actor->flags2 & MF2_BLASTED) + return (true); + if (actor->movedir == DI_NODIR) + { + return (false); + } + tryx = actor->x + actor->info->speed * xspeed[actor->movedir]; + tryy = actor->y + actor->info->speed * yspeed[actor->movedir]; + if (!P_TryMove(actor, tryx, tryy)) + { // open any specials + if (actor->flags & MF_FLOAT && floatok) + { // must adjust height + if (actor->z < tmfloorz) + { + actor->z += FLOATSPEED; + } + else + { + actor->z -= FLOATSPEED; + } + actor->flags |= MF_INFLOAT; + return (true); + } + if (!numspechit) + { + return false; + } + actor->movedir = DI_NODIR; + good = false; + while (numspechit--) + { + ld = spechit[numspechit]; + // if the special isn't a door that can be opened, return false + if (P_ActivateLine(ld, actor, 0, SPAC_USE)) + { + good = true; + } /* Old version before use/cross/impact specials were combined if(P_UseSpecialLine(actor, ld)) { good = true; } */ - } - return(good); - } - else - { - actor->flags &= ~MF_INFLOAT; - } - if(!(actor->flags&MF_FLOAT)) - { - if(actor->z > actor->floorz) - { - P_HitFloor(actor); - } - actor->z = actor->floorz; - } - return(true); + } + return (good); + } + else + { + actor->flags &= ~MF_INFLOAT; + } + if (!(actor->flags & MF_FLOAT)) + { + if (actor->z > actor->floorz) + { + P_HitFloor(actor); + } + actor->z = actor->floorz; + } + return (true); } //---------------------------------------------------------------------------- @@ -299,14 +315,14 @@ boolean P_Move(mobj_t *actor) // //---------------------------------------------------------------------------- -boolean P_TryWalk(mobj_t *actor) +boolean P_TryWalk(mobj_t * actor) { - if(!P_Move(actor)) - { - return(false); - } - actor->movecount = P_Random()&15; - return(true); + if (!P_Move(actor)) + { + return (false); + } + actor->movecount = P_Random() & 15; + return (true); } /* @@ -318,115 +334,117 @@ boolean P_TryWalk(mobj_t *actor) */ dirtype_t opposite[] = -{DI_WEST, DI_SOUTHWEST, DI_SOUTH, DI_SOUTHEAST, DI_EAST, DI_NORTHEAST, -DI_NORTH, DI_NORTHWEST, DI_NODIR}; - -dirtype_t diags[] = {DI_NORTHWEST,DI_NORTHEAST,DI_SOUTHWEST,DI_SOUTHEAST}; - -void P_NewChaseDir (mobj_t *actor) -{ - fixed_t deltax,deltay; - dirtype_t d[3]; - dirtype_t tdir, olddir, turnaround; - - if (!actor->target) - I_Error ("P_NewChaseDir: called with no target"); - - olddir = actor->movedir; - turnaround=opposite[olddir]; - - deltax = actor->target->x - actor->x; - deltay = actor->target->y - actor->y; - if (deltax>10*FRACUNIT) - d[1]= DI_EAST; - else if (deltax<-10*FRACUNIT) - d[1]= DI_WEST; - else - d[1]=DI_NODIR; - if (deltay<-10*FRACUNIT) - d[2]= DI_SOUTH; - else if (deltay>10*FRACUNIT) - d[2]= DI_NORTH; - else - d[2]=DI_NODIR; + { DI_WEST, DI_SOUTHWEST, DI_SOUTH, DI_SOUTHEAST, DI_EAST, DI_NORTHEAST, + DI_NORTH, DI_NORTHWEST, DI_NODIR +}; + +dirtype_t diags[] = + { DI_NORTHWEST, DI_NORTHEAST, DI_SOUTHWEST, DI_SOUTHEAST }; + +void P_NewChaseDir(mobj_t * actor) +{ + fixed_t deltax, deltay; + dirtype_t d[3]; + dirtype_t tdir, olddir, turnaround; + + if (!actor->target) + I_Error("P_NewChaseDir: called with no target"); + + olddir = actor->movedir; + turnaround = opposite[olddir]; + + deltax = actor->target->x - actor->x; + deltay = actor->target->y - actor->y; + if (deltax > 10 * FRACUNIT) + d[1] = DI_EAST; + else if (deltax < -10 * FRACUNIT) + d[1] = DI_WEST; + else + d[1] = DI_NODIR; + if (deltay < -10 * FRACUNIT) + d[2] = DI_SOUTH; + else if (deltay > 10 * FRACUNIT) + d[2] = DI_NORTH; + else + d[2] = DI_NODIR; // try direct route - if (d[1] != DI_NODIR && d[2] != DI_NODIR) - { - actor->movedir = diags[((deltay<0)<<1)+(deltax>0)]; - if (actor->movedir != turnaround && P_TryWalk(actor)) - return; - } + if (d[1] != DI_NODIR && d[2] != DI_NODIR) + { + actor->movedir = diags[((deltay < 0) << 1) + (deltax > 0)]; + if (actor->movedir != turnaround && P_TryWalk(actor)) + return; + } // try other directions - if (P_Random() > 200 || abs(deltay)>abs(deltax)) - { - tdir=d[1]; - d[1]=d[2]; - d[2]=tdir; - } - - if (d[1]==turnaround) - d[1]=DI_NODIR; - if (d[2]==turnaround) - d[2]=DI_NODIR; - - if (d[1]!=DI_NODIR) - { - actor->movedir = d[1]; - if (P_TryWalk(actor)) - return; /*either moved forward or attacked*/ - } - - if (d[2]!=DI_NODIR) - { - actor->movedir =d[2]; - if (P_TryWalk(actor)) - return; - } + if (P_Random() > 200 || abs(deltay) > abs(deltax)) + { + tdir = d[1]; + d[1] = d[2]; + d[2] = tdir; + } + + if (d[1] == turnaround) + d[1] = DI_NODIR; + if (d[2] == turnaround) + d[2] = DI_NODIR; + + if (d[1] != DI_NODIR) + { + actor->movedir = d[1]; + if (P_TryWalk(actor)) + return; /*either moved forward or attacked */ + } + + if (d[2] != DI_NODIR) + { + actor->movedir = d[2]; + if (P_TryWalk(actor)) + return; + } /* there is no direct path to the player, so pick another direction */ - if (olddir!=DI_NODIR) - { - actor->movedir =olddir; - if (P_TryWalk(actor)) - return; - } - - if (P_Random()&1) /*randomly determine direction of search*/ - { - for (tdir=DI_EAST ; tdir<=DI_SOUTHEAST ; tdir++) - { - if (tdir!=turnaround) - { - actor->movedir =tdir; - if ( P_TryWalk(actor) ) - return; - } - } - } - else - { - for (tdir=DI_SOUTHEAST ; tdir >= DI_EAST;tdir--) - { - if (tdir!=turnaround) - { - actor->movedir =tdir; - if ( P_TryWalk(actor) ) - return; - } - } - } - - if (turnaround != DI_NODIR) - { - actor->movedir =turnaround; - if ( P_TryWalk(actor) ) - return; - } - - actor->movedir = DI_NODIR; // can't move + if (olddir != DI_NODIR) + { + actor->movedir = olddir; + if (P_TryWalk(actor)) + return; + } + + if (P_Random() & 1) /*randomly determine direction of search */ + { + for (tdir = DI_EAST; tdir <= DI_SOUTHEAST; tdir++) + { + if (tdir != turnaround) + { + actor->movedir = tdir; + if (P_TryWalk(actor)) + return; + } + } + } + else + { + for (tdir = DI_SOUTHEAST; tdir >= DI_EAST; tdir--) + { + if (tdir != turnaround) + { + actor->movedir = tdir; + if (P_TryWalk(actor)) + return; + } + } + } + + if (turnaround != DI_NODIR) + { + actor->movedir = turnaround; + if (P_TryWalk(actor)) + return; + } + + actor->movedir = DI_NODIR; // can't move } //--------------------------------------------------------------------------- @@ -438,58 +456,58 @@ void P_NewChaseDir (mobj_t *actor) #define MONS_LOOK_RANGE (16*64*FRACUNIT) #define MONS_LOOK_LIMIT 64 -boolean P_LookForMonsters(mobj_t *actor) -{ - int count; - mobj_t *mo; - thinker_t *think; - - if(!P_CheckSight(players[0].mo, actor)) - { // Player can't see monster - return(false); - } - count = 0; - for(think = thinkercap.next; think != &thinkercap; think = think->next) - { - if(think->function != P_MobjThinker) - { // Not a mobj thinker - continue; - } - mo = (mobj_t *)think; - if(!(mo->flags&MF_COUNTKILL) || (mo == actor) || (mo->health <= 0)) - { // Not a valid monster - continue; - } - if(P_AproxDistance(actor->x-mo->x, actor->y-mo->y) - > MONS_LOOK_RANGE) - { // Out of range - continue; - } - if(P_Random() < 16) - { // Skip - continue; - } - if(count++ > MONS_LOOK_LIMIT) - { // Stop searching - return(false); - } - if(!P_CheckSight(actor, mo)) - { // Out of sight - continue; - } - if (actor->type == MT_MINOTAUR) - { - if ((mo->type == MT_MINOTAUR) && - (mo->target != ((player_t *)actor->special1)->mo)) - { - continue; - } - } - // Found a target monster - actor->target = mo; - return(true); - } - return(false); +boolean P_LookForMonsters(mobj_t * actor) +{ + int count; + mobj_t *mo; + thinker_t *think; + + if (!P_CheckSight(players[0].mo, actor)) + { // Player can't see monster + return (false); + } + count = 0; + for (think = thinkercap.next; think != &thinkercap; think = think->next) + { + if (think->function != P_MobjThinker) + { // Not a mobj thinker + continue; + } + mo = (mobj_t *) think; + if (!(mo->flags & MF_COUNTKILL) || (mo == actor) || (mo->health <= 0)) + { // Not a valid monster + continue; + } + if (P_AproxDistance(actor->x - mo->x, actor->y - mo->y) + > MONS_LOOK_RANGE) + { // Out of range + continue; + } + if (P_Random() < 16) + { // Skip + continue; + } + if (count++ > MONS_LOOK_LIMIT) + { // Stop searching + return (false); + } + if (!P_CheckSight(actor, mo)) + { // Out of sight + continue; + } + if (actor->type == MT_MINOTAUR) + { + if ((mo->type == MT_MINOTAUR) && + (mo->target != ((player_t *) actor->special1)->mo)) + { + continue; + } + } + // Found a target monster + actor->target = mo; + return (true); + } + return (false); } /* @@ -502,75 +520,75 @@ boolean P_LookForMonsters(mobj_t *actor) ================ */ -boolean P_LookForPlayers(mobj_t *actor, boolean allaround) -{ - int c; - int stop; - player_t *player; - sector_t *sector; - angle_t an; - fixed_t dist; - - if(!netgame && players[0].health <= 0) - { // Single player game and player is dead, look for monsters - return(P_LookForMonsters(actor)); - } - sector = actor->subsector->sector; - c = 0; - stop = (actor->lastlook-1)&3; - for( ; ; actor->lastlook = (actor->lastlook+1)&3 ) - { - if (!playeringame[actor->lastlook]) - continue; - - if (c++ == 2 || actor->lastlook == stop) - return false; // done looking - - player = &players[actor->lastlook]; - if (player->health <= 0) - continue; // dead - if (!P_CheckSight (actor, player->mo)) - continue; // out of sight - - if (!allaround) - { - an = R_PointToAngle2 (actor->x, actor->y, - player->mo->x, player->mo->y) - actor->angle; - if (an > ANG90 && an < ANG270) - { - dist = P_AproxDistance (player->mo->x - actor->x, - player->mo->y - actor->y); - // if real close, react anyway - if (dist > MELEERANGE) - continue; // behind back - } - } - if(player->mo->flags&MF_SHADOW) - { // Player is invisible - if((P_AproxDistance(player->mo->x-actor->x, - player->mo->y-actor->y) > 2*MELEERANGE) - && P_AproxDistance(player->mo->momx, player->mo->momy) - < 5*FRACUNIT) - { // Player is sneaking - can't detect - return(false); - } - if(P_Random() < 225) - { // Player isn't sneaking, but still didn't detect - return(false); - } - } - if (actor->type == MT_MINOTAUR) - { - if(((player_t *)(actor->special1)) == player) - { - continue; // Don't target master - } - } - - actor->target = player->mo; - return(true); - } - return(false); +boolean P_LookForPlayers(mobj_t * actor, boolean allaround) +{ + int c; + int stop; + player_t *player; + sector_t *sector; + angle_t an; + fixed_t dist; + + if (!netgame && players[0].health <= 0) + { // Single player game and player is dead, look for monsters + return (P_LookForMonsters(actor)); + } + sector = actor->subsector->sector; + c = 0; + stop = (actor->lastlook - 1) & 3; + for (;; actor->lastlook = (actor->lastlook + 1) & 3) + { + if (!playeringame[actor->lastlook]) + continue; + + if (c++ == 2 || actor->lastlook == stop) + return false; // done looking + + player = &players[actor->lastlook]; + if (player->health <= 0) + continue; // dead + if (!P_CheckSight(actor, player->mo)) + continue; // out of sight + + if (!allaround) + { + an = R_PointToAngle2(actor->x, actor->y, + player->mo->x, player->mo->y) - actor->angle; + if (an > ANG90 && an < ANG270) + { + dist = P_AproxDistance(player->mo->x - actor->x, + player->mo->y - actor->y); + // if real close, react anyway + if (dist > MELEERANGE) + continue; // behind back + } + } + if (player->mo->flags & MF_SHADOW) + { // Player is invisible + if ((P_AproxDistance(player->mo->x - actor->x, + player->mo->y - actor->y) > 2 * MELEERANGE) + && P_AproxDistance(player->mo->momx, player->mo->momy) + < 5 * FRACUNIT) + { // Player is sneaking - can't detect + return (false); + } + if (P_Random() < 225) + { // Player isn't sneaking, but still didn't detect + return (false); + } + } + if (actor->type == MT_MINOTAUR) + { + if (((player_t *) (actor->special1)) == player) + { + continue; // Don't target master + } + } + + actor->target = player->mo; + return (true); + } + return (false); } /* @@ -591,45 +609,45 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround) ============== */ -void A_Look (mobj_t *actor) +void A_Look(mobj_t * actor) { - mobj_t *targ; + mobj_t *targ; - actor->threshold = 0; // any shot will wake up - targ = actor->subsector->sector->soundtarget; - if (targ && (targ->flags & MF_SHOOTABLE) ) - { - actor->target = targ; - if ( actor->flags & MF_AMBUSH ) - { - if (P_CheckSight (actor, actor->target)) - goto seeyou; - } - else - goto seeyou; - } + actor->threshold = 0; // any shot will wake up + targ = actor->subsector->sector->soundtarget; + if (targ && (targ->flags & MF_SHOOTABLE)) + { + actor->target = targ; + if (actor->flags & MF_AMBUSH) + { + if (P_CheckSight(actor, actor->target)) + goto seeyou; + } + else + goto seeyou; + } - if (!P_LookForPlayers (actor, false) ) - return; + if (!P_LookForPlayers(actor, false)) + return; // go into chase state -seeyou: - if (actor->info->seesound) - { - int sound; - - sound = actor->info->seesound; - if(actor->flags2&MF2_BOSS) - { // Full volume - S_StartSound(NULL, sound); - } - else - { - S_StartSound(actor, sound); - } - } - P_SetMobjState(actor, actor->info->seestate); + seeyou: + if (actor->info->seesound) + { + int sound; + + sound = actor->info->seesound; + if (actor->flags2 & MF2_BOSS) + { // Full volume + S_StartSound(NULL, sound); + } + else + { + S_StartSound(actor, sound); + } + } + P_SetMobjState(actor, actor->info->seestate); } @@ -643,135 +661,135 @@ seeyou: ============== */ -void A_Chase(mobj_t *actor) +void A_Chase(mobj_t * actor) { - int delta; + int delta; - if(actor->reactiontime) - { - actor->reactiontime--; - } + if (actor->reactiontime) + { + actor->reactiontime--; + } - // Modify target threshold - if(actor->threshold) - { - actor->threshold--; - } + // Modify target threshold + if (actor->threshold) + { + actor->threshold--; + } - if(gameskill == sk_nightmare) - { // Monsters move faster in nightmare mode - actor->tics -= actor->tics/2; - if(actor->tics < 3) - { - actor->tics = 3; - } - } + if (gameskill == sk_nightmare) + { // Monsters move faster in nightmare mode + actor->tics -= actor->tics / 2; + if (actor->tics < 3) + { + actor->tics = 3; + } + } // // turn towards movement direction if not there yet // - if(actor->movedir < 8) - { - actor->angle &= (7<<29); - delta = actor->angle-(actor->movedir << 29); - if(delta > 0) - { - actor->angle -= ANG90/2; - } - else if(delta < 0) - { - actor->angle += ANG90/2; - } - } - - if(!actor->target || !(actor->target->flags&MF_SHOOTABLE)) - { // look for a new target - if(P_LookForPlayers(actor, true)) - { // got a new target - return; - } - P_SetMobjState(actor, actor->info->spawnstate); - return; - } + if (actor->movedir < 8) + { + actor->angle &= (7 << 29); + delta = actor->angle - (actor->movedir << 29); + if (delta > 0) + { + actor->angle -= ANG90 / 2; + } + else if (delta < 0) + { + actor->angle += ANG90 / 2; + } + } + + if (!actor->target || !(actor->target->flags & MF_SHOOTABLE)) + { // look for a new target + if (P_LookForPlayers(actor, true)) + { // got a new target + return; + } + P_SetMobjState(actor, actor->info->spawnstate); + return; + } // // don't attack twice in a row // - if(actor->flags & MF_JUSTATTACKED) - { - actor->flags &= ~MF_JUSTATTACKED; - if (gameskill != sk_nightmare) - P_NewChaseDir (actor); - return; - } + if (actor->flags & MF_JUSTATTACKED) + { + actor->flags &= ~MF_JUSTATTACKED; + if (gameskill != sk_nightmare) + P_NewChaseDir(actor); + return; + } // // check for melee attack // - if (actor->info->meleestate && P_CheckMeleeRange (actor)) - { - if(actor->info->attacksound) - { - S_StartSound (actor, actor->info->attacksound); - } - P_SetMobjState (actor, actor->info->meleestate); - return; - } + if (actor->info->meleestate && P_CheckMeleeRange(actor)) + { + if (actor->info->attacksound) + { + S_StartSound(actor, actor->info->attacksound); + } + P_SetMobjState(actor, actor->info->meleestate); + return; + } // // check for missile attack // - if (actor->info->missilestate) - { - if (gameskill < sk_nightmare && actor->movecount) - goto nomissile; - if (!P_CheckMissileRange (actor)) - goto nomissile; - P_SetMobjState (actor, actor->info->missilestate); - actor->flags |= MF_JUSTATTACKED; - return; - } -nomissile: + if (actor->info->missilestate) + { + if (gameskill < sk_nightmare && actor->movecount) + goto nomissile; + if (!P_CheckMissileRange(actor)) + goto nomissile; + P_SetMobjState(actor, actor->info->missilestate); + actor->flags |= MF_JUSTATTACKED; + return; + } + nomissile: // // possibly choose another target // - if (netgame && !actor->threshold && !P_CheckSight (actor, actor->target) ) - { - if (P_LookForPlayers(actor,true)) - return; // got a new target - } + if (netgame && !actor->threshold && !P_CheckSight(actor, actor->target)) + { + if (P_LookForPlayers(actor, true)) + return; // got a new target + } // // chase towards player // - if (--actor->movecount<0 || !P_Move (actor)) - { - P_NewChaseDir (actor); - } + if (--actor->movecount < 0 || !P_Move(actor)) + { + P_NewChaseDir(actor); + } // // make active sound // - if(actor->info->activesound && P_Random() < 3) - { - if(actor->type == MT_BISHOP && P_Random() < 128) - { - S_StartSound(actor, actor->info->seesound); - } - else if(actor->type == MT_PIG) - { - S_StartSound(actor, SFX_PIG_ACTIVE1+(P_Random()&1)); - } - else if(actor->flags2&MF2_BOSS) - { - S_StartSound(NULL, actor->info->activesound); - } - else - { - S_StartSound(actor, actor->info->activesound); - } - } + if (actor->info->activesound && P_Random() < 3) + { + if (actor->type == MT_BISHOP && P_Random() < 128) + { + S_StartSound(actor, actor->info->seesound); + } + else if (actor->type == MT_PIG) + { + S_StartSound(actor, SFX_PIG_ACTIVE1 + (P_Random() & 1)); + } + else if (actor->flags2 & MF2_BOSS) + { + S_StartSound(NULL, actor->info->activesound); + } + else + { + S_StartSound(actor, actor->info->activesound); + } + } } //---------------------------------------------------------------------------- @@ -780,19 +798,19 @@ nomissile: // //---------------------------------------------------------------------------- -void A_FaceTarget(mobj_t *actor) +void A_FaceTarget(mobj_t * actor) { - if(!actor->target) - { - return; - } - actor->flags &= ~MF_AMBUSH; - actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, - actor->target->y); - if(actor->target->flags&MF_SHADOW) - { // Target is a ghost - actor->angle += (P_Random()-P_Random())<<21; - } + if (!actor->target) + { + return; + } + actor->flags &= ~MF_AMBUSH; + actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, + actor->target->y); + if (actor->target->flags & MF_SHADOW) + { // Target is a ghost + actor->angle += (P_Random() - P_Random()) << 21; + } } //---------------------------------------------------------------------------- @@ -801,12 +819,12 @@ void A_FaceTarget(mobj_t *actor) // //---------------------------------------------------------------------------- -void A_Pain(mobj_t *actor) +void A_Pain(mobj_t * actor) { - if(actor->info->painsound) - { - S_StartSound(actor, actor->info->painsound); - } + if (actor->info->painsound) + { + S_StartSound(actor, actor->info->painsound); + } } //============================================================================ @@ -815,9 +833,9 @@ void A_Pain(mobj_t *actor) // //============================================================================ -void A_SetInvulnerable(mobj_t *actor) +void A_SetInvulnerable(mobj_t * actor) { - actor->flags2 |= MF2_INVULNERABLE; + actor->flags2 |= MF2_INVULNERABLE; } //============================================================================ @@ -826,9 +844,9 @@ void A_SetInvulnerable(mobj_t *actor) // //============================================================================ -void A_UnSetInvulnerable(mobj_t *actor) +void A_UnSetInvulnerable(mobj_t * actor) { - actor->flags2 &= ~MF2_INVULNERABLE; + actor->flags2 &= ~MF2_INVULNERABLE; } //============================================================================ @@ -837,15 +855,14 @@ void A_UnSetInvulnerable(mobj_t *actor) // //============================================================================ -void A_SetReflective(mobj_t *actor) +void A_SetReflective(mobj_t * actor) { - actor->flags2 |= MF2_REFLECTIVE; + actor->flags2 |= MF2_REFLECTIVE; - if ((actor->type == MT_CENTAUR) || - (actor->type == MT_CENTAURLEADER)) - { - A_SetInvulnerable(actor); - } + if ((actor->type == MT_CENTAUR) || (actor->type == MT_CENTAURLEADER)) + { + A_SetInvulnerable(actor); + } } //============================================================================ @@ -854,15 +871,14 @@ void A_SetReflective(mobj_t *actor) // //============================================================================ -void A_UnSetReflective(mobj_t *actor) +void A_UnSetReflective(mobj_t * actor) { - actor->flags2 &= ~MF2_REFLECTIVE; + actor->flags2 &= ~MF2_REFLECTIVE; - if ((actor->type == MT_CENTAUR) || - (actor->type == MT_CENTAURLEADER)) - { - A_UnSetInvulnerable(actor); - } + if ((actor->type == MT_CENTAUR) || (actor->type == MT_CENTAURLEADER)) + { + A_UnSetInvulnerable(actor); + } } @@ -874,66 +890,66 @@ void A_UnSetReflective(mobj_t *actor) // //---------------------------------------------------------------------------- -boolean P_UpdateMorphedMonster(mobj_t *actor, int tics) -{ - mobj_t *fog; - fixed_t x; - fixed_t y; - fixed_t z; - mobjtype_t moType; - mobj_t *mo; - mobj_t oldMonster; - - actor->special1 -= tics; - if(actor->special1 > 0) - { - return(false); - } - moType = actor->special2; - switch(moType) - { - case MT_WRAITHB: // These must remain morphed - case MT_SERPENT: - case MT_SERPENTLEADER: - case MT_MINOTAUR: - return(false); - default: - break; - } - x = actor->x; - y = actor->y; - z = actor->z; - oldMonster = *actor; // Save pig vars - - P_RemoveMobjFromTIDList(actor); - P_SetMobjState(actor, S_FREETARGMOBJ); - mo = P_SpawnMobj(x, y, z, moType); - - if(P_TestMobjLocation(mo) == false) - { // Didn't fit - P_RemoveMobj(mo); - mo = P_SpawnMobj(x, y, z, oldMonster.type); - mo->angle = oldMonster.angle; - mo->flags = oldMonster.flags; - mo->health = oldMonster.health; - mo->target = oldMonster.target; - mo->special = oldMonster.special; - mo->special1 = 5*35; // Next try in 5 seconds - mo->special2 = moType; - mo->tid = oldMonster.tid; - memcpy(mo->args, oldMonster.args, 5); - P_InsertMobjIntoTIDList(mo, oldMonster.tid); - return(false); - } - mo->angle = oldMonster.angle; - mo->target = oldMonster.target; - mo->tid = oldMonster.tid; - mo->special = oldMonster.special; - memcpy(mo->args, oldMonster.args, 5); - P_InsertMobjIntoTIDList(mo, oldMonster.tid); - fog = P_SpawnMobj(x, y, z+TELEFOGHEIGHT, MT_TFOG); - S_StartSound(fog, SFX_TELEPORT); - return(true); +boolean P_UpdateMorphedMonster(mobj_t * actor, int tics) +{ + mobj_t *fog; + fixed_t x; + fixed_t y; + fixed_t z; + mobjtype_t moType; + mobj_t *mo; + mobj_t oldMonster; + + actor->special1 -= tics; + if (actor->special1 > 0) + { + return (false); + } + moType = actor->special2; + switch (moType) + { + case MT_WRAITHB: // These must remain morphed + case MT_SERPENT: + case MT_SERPENTLEADER: + case MT_MINOTAUR: + return (false); + default: + break; + } + x = actor->x; + y = actor->y; + z = actor->z; + oldMonster = *actor; // Save pig vars + + P_RemoveMobjFromTIDList(actor); + P_SetMobjState(actor, S_FREETARGMOBJ); + mo = P_SpawnMobj(x, y, z, moType); + + if (P_TestMobjLocation(mo) == false) + { // Didn't fit + P_RemoveMobj(mo); + mo = P_SpawnMobj(x, y, z, oldMonster.type); + mo->angle = oldMonster.angle; + mo->flags = oldMonster.flags; + mo->health = oldMonster.health; + mo->target = oldMonster.target; + mo->special = oldMonster.special; + mo->special1 = 5 * 35; // Next try in 5 seconds + mo->special2 = moType; + mo->tid = oldMonster.tid; + memcpy(mo->args, oldMonster.args, 5); + P_InsertMobjIntoTIDList(mo, oldMonster.tid); + return (false); + } + mo->angle = oldMonster.angle; + mo->target = oldMonster.target; + mo->tid = oldMonster.tid; + mo->special = oldMonster.special; + memcpy(mo->args, oldMonster.args, 5); + P_InsertMobjIntoTIDList(mo, oldMonster.tid); + fog = P_SpawnMobj(x, y, z + TELEFOGHEIGHT, MT_TFOG); + S_StartSound(fog, SFX_TELEPORT); + return (true); } //---------------------------------------------------------------------------- @@ -942,13 +958,13 @@ boolean P_UpdateMorphedMonster(mobj_t *actor, int tics) // //---------------------------------------------------------------------------- -void A_PigLook(mobj_t *actor) +void A_PigLook(mobj_t * actor) { - if(P_UpdateMorphedMonster(actor, 10)) - { - return; - } - A_Look(actor); + if (P_UpdateMorphedMonster(actor, 10)) + { + return; + } + A_Look(actor); } //---------------------------------------------------------------------------- @@ -957,13 +973,13 @@ void A_PigLook(mobj_t *actor) // //---------------------------------------------------------------------------- -void A_PigChase(mobj_t *actor) +void A_PigChase(mobj_t * actor) { - if(P_UpdateMorphedMonster(actor, 3)) - { - return; - } - A_Chase(actor); + if (P_UpdateMorphedMonster(actor, 3)) + { + return; + } + A_Chase(actor); } //============================================================================ @@ -972,21 +988,21 @@ void A_PigChase(mobj_t *actor) // //============================================================================ -void A_PigAttack(mobj_t *actor) +void A_PigAttack(mobj_t * actor) { - if(P_UpdateMorphedMonster(actor, 18)) - { - return; - } - if(!actor->target) - { - return; - } - if(P_CheckMeleeRange(actor)) - { - P_DamageMobj(actor->target, actor, actor, 2+(P_Random()&1)); - S_StartSound(actor, SFX_PIG_ATTACK); - } + if (P_UpdateMorphedMonster(actor, 18)) + { + return; + } + if (!actor->target) + { + return; + } + if (P_CheckMeleeRange(actor)) + { + P_DamageMobj(actor->target, actor, actor, 2 + (P_Random() & 1)); + S_StartSound(actor, SFX_PIG_ATTACK); + } } //============================================================================ @@ -995,46 +1011,46 @@ void A_PigAttack(mobj_t *actor) // //============================================================================ -void A_PigPain(mobj_t *actor) +void A_PigPain(mobj_t * actor) { - A_Pain(actor); - if(actor->z <= actor->floorz) - { - actor->momz = 3.5*FRACUNIT; - } + A_Pain(actor); + if (actor->z <= actor->floorz) + { + actor->momz = 3.5 * FRACUNIT; + } } -void FaceMovementDirection(mobj_t *actor) +void FaceMovementDirection(mobj_t * actor) { - switch(actor->movedir) - { - case DI_EAST: - actor->angle = 0<<24; - break; - case DI_NORTHEAST: - actor->angle = 32<<24; - break; - case DI_NORTH: - actor->angle = 64<<24; - break; - case DI_NORTHWEST: - actor->angle = 96<<24; - break; - case DI_WEST: - actor->angle = 128<<24; - break; - case DI_SOUTHWEST: - actor->angle = 160<<24; - break; - case DI_SOUTH: - actor->angle = 192<<24; - break; - case DI_SOUTHEAST: - actor->angle = 224<<24; - break; - } + switch (actor->movedir) + { + case DI_EAST: + actor->angle = 0 << 24; + break; + case DI_NORTHEAST: + actor->angle = 32 << 24; + break; + case DI_NORTH: + actor->angle = 64 << 24; + break; + case DI_NORTHWEST: + actor->angle = 96 << 24; + break; + case DI_WEST: + actor->angle = 128 << 24; + break; + case DI_SOUTHWEST: + actor->angle = 160 << 24; + break; + case DI_SOUTH: + actor->angle = 192 << 24; + break; + case DI_SOUTHEAST: + actor->angle = 224 << 24; + break; + } } @@ -1042,33 +1058,33 @@ void FaceMovementDirection(mobj_t *actor) // // Minotaur variables // -// special1 pointer to player that spawned it (mobj_t) -// special2 internal to minotaur AI -// args[0] args[0]-args[3] together make up minotaur start time -// args[1] | -// args[2] | -// args[3] V -// args[4] charge duration countdown +// special1 pointer to player that spawned it (mobj_t) +// special2 internal to minotaur AI +// args[0] args[0]-args[3] together make up minotaur start time +// args[1] | +// args[2] | +// args[3] V +// args[4] charge duration countdown //---------------------------------------------------------------------------- -void A_MinotaurFade0(mobj_t *actor) +void A_MinotaurFade0(mobj_t * actor) { - actor->flags &= ~MF_ALTSHADOW; - actor->flags |= MF_SHADOW; + actor->flags &= ~MF_ALTSHADOW; + actor->flags |= MF_SHADOW; } -void A_MinotaurFade1(mobj_t *actor) +void A_MinotaurFade1(mobj_t * actor) { - // Second level of transparency - actor->flags &= ~MF_SHADOW; - actor->flags |= MF_ALTSHADOW; + // Second level of transparency + actor->flags &= ~MF_SHADOW; + actor->flags |= MF_ALTSHADOW; } -void A_MinotaurFade2(mobj_t *actor) +void A_MinotaurFade2(mobj_t * actor) { - // Make fully visible - actor->flags &= ~MF_SHADOW; - actor->flags &= ~MF_ALTSHADOW; + // Make fully visible + actor->flags &= ~MF_SHADOW; + actor->flags &= ~MF_ALTSHADOW; } @@ -1079,172 +1095,184 @@ void A_MinotaurFade2(mobj_t *actor) // //---------------------------------------------------------------------------- -void A_MinotaurLook(mobj_t *actor); +void A_MinotaurLook(mobj_t * actor); -void A_MinotaurRoam(mobj_t *actor) +void A_MinotaurRoam(mobj_t * actor) { - unsigned int *starttime = (unsigned int *)actor->args; + unsigned int *starttime = (unsigned int *) actor->args; - actor->flags &= ~MF_SHADOW; // In case pain caused him to - actor->flags &= ~MF_ALTSHADOW; // skip his fade in. + actor->flags &= ~MF_SHADOW; // In case pain caused him to + actor->flags &= ~MF_ALTSHADOW; // skip his fade in. - if ((leveltime - *starttime) >= MAULATORTICS) - { - P_DamageMobj(actor,NULL,NULL,10000); - return; - } + if ((leveltime - *starttime) >= MAULATORTICS) + { + P_DamageMobj(actor, NULL, NULL, 10000); + return; + } - if (P_Random()<30) - A_MinotaurLook(actor); // adjust to closest target + if (P_Random() < 30) + A_MinotaurLook(actor); // adjust to closest target - if (P_Random()<6) - { - //Choose new direction - actor->movedir = P_Random() % 8; - FaceMovementDirection(actor); - } - if (!P_Move(actor)) - { - // Turn - if (P_Random() & 1) - actor->movedir = (++actor->movedir)%8; - else - actor->movedir = (actor->movedir+7)%8; - FaceMovementDirection(actor); - } + if (P_Random() < 6) + { + //Choose new direction + actor->movedir = P_Random() % 8; + FaceMovementDirection(actor); + } + if (!P_Move(actor)) + { + // Turn + if (P_Random() & 1) + actor->movedir = (++actor->movedir) % 8; + else + actor->movedir = (actor->movedir + 7) % 8; + FaceMovementDirection(actor); + } } //---------------------------------------------------------------------------- // -// PROC A_MinotaurLook +// PROC A_MinotaurLook // // Look for enemy of player //---------------------------------------------------------------------------- #define MINOTAUR_LOOK_DIST (16*54*FRACUNIT) -void A_MinotaurLook(mobj_t *actor) -{ - mobj_t *mo=NULL; - player_t *player; - thinker_t *think; - fixed_t dist; - int i; - mobj_t *master = (mobj_t *)(actor->special1); - - actor->target = NULL; - if (deathmatch) // Quick search for players - { - for (i=0; imo; - if (mo == master) continue; - if (mo->health <= 0) continue; - dist = P_AproxDistance(actor->x - mo->x, actor->y - mo->y); - if (dist > MINOTAUR_LOOK_DIST) continue; - actor->target = mo; - break; - } - } - - if (!actor->target) // Near player monster search - { - if (master && (master->health>0) && (master->player)) - mo = P_RoughMonsterSearch(master, 20); - else - mo = P_RoughMonsterSearch(actor, 20); - actor->target = mo; - } - - if (!actor->target) // Normal monster search - { - for(think = thinkercap.next; think != &thinkercap; think = think->next) - { - if(think->function != P_MobjThinker) continue; - mo = (mobj_t *)think; - if (!(mo->flags&MF_COUNTKILL)) continue; - if (mo->health <= 0) continue; - if (!(mo->flags&MF_SHOOTABLE)) continue; - dist = P_AproxDistance(actor->x - mo->x, actor->y - mo->y); - if (dist > MINOTAUR_LOOK_DIST) continue; - if ((mo == master) || (mo == actor)) continue; - if ((mo->type == MT_MINOTAUR) && - (mo->special1 == actor->special1)) continue; - actor->target = mo; - break; // Found mobj to attack - } - } - - if (actor->target) - { - P_SetMobjStateNF(actor, S_MNTR_WALK1); - } - else - { - P_SetMobjStateNF(actor, S_MNTR_ROAM1); - } -} - - - - -void A_MinotaurChase(mobj_t *actor) -{ - unsigned int *starttime = (unsigned int *)actor->args; - - actor->flags &= ~MF_SHADOW; // In case pain caused him to - actor->flags &= ~MF_ALTSHADOW; // skip his fade in. - - if ((leveltime - *starttime) >= MAULATORTICS) - { - P_DamageMobj(actor,NULL,NULL,10000); - return; - } - - if (P_Random()<30) - A_MinotaurLook(actor); // adjust to closest target - - if (!actor->target || (actor->target->health <= 0) || - !(actor->target->flags&MF_SHOOTABLE)) - { // look for a new target - P_SetMobjState(actor, S_MNTR_LOOK1); - return; - } - - FaceMovementDirection(actor); - actor->reactiontime=0; - - // Melee attack - if (actor->info->meleestate && P_CheckMeleeRange(actor)) - { - if(actor->info->attacksound) - { - S_StartSound (actor, actor->info->attacksound); - } - P_SetMobjState (actor, actor->info->meleestate); - return; - } - - // Missile attack - if (actor->info->missilestate && P_CheckMissileRange(actor)) - { - P_SetMobjState (actor, actor->info->missilestate); - return; - } - - // chase towards target - if (!P_Move(actor)) - { - P_NewChaseDir(actor); - } - - // Active sound - if(actor->info->activesound && P_Random() < 6) - { - S_StartSound(actor, actor->info->activesound); - } +void A_MinotaurLook(mobj_t * actor) +{ + mobj_t *mo = NULL; + player_t *player; + thinker_t *think; + fixed_t dist; + int i; + mobj_t *master = (mobj_t *) (actor->special1); + + actor->target = NULL; + if (deathmatch) // Quick search for players + { + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + player = &players[i]; + mo = player->mo; + if (mo == master) + continue; + if (mo->health <= 0) + continue; + dist = P_AproxDistance(actor->x - mo->x, actor->y - mo->y); + if (dist > MINOTAUR_LOOK_DIST) + continue; + actor->target = mo; + break; + } + } + + if (!actor->target) // Near player monster search + { + if (master && (master->health > 0) && (master->player)) + mo = P_RoughMonsterSearch(master, 20); + else + mo = P_RoughMonsterSearch(actor, 20); + actor->target = mo; + } + + if (!actor->target) // Normal monster search + { + for (think = thinkercap.next; think != &thinkercap; + think = think->next) + { + if (think->function != P_MobjThinker) + continue; + mo = (mobj_t *) think; + if (!(mo->flags & MF_COUNTKILL)) + continue; + if (mo->health <= 0) + continue; + if (!(mo->flags & MF_SHOOTABLE)) + continue; + dist = P_AproxDistance(actor->x - mo->x, actor->y - mo->y); + if (dist > MINOTAUR_LOOK_DIST) + continue; + if ((mo == master) || (mo == actor)) + continue; + if ((mo->type == MT_MINOTAUR) && + (mo->special1 == actor->special1)) + continue; + actor->target = mo; + break; // Found mobj to attack + } + } + + if (actor->target) + { + P_SetMobjStateNF(actor, S_MNTR_WALK1); + } + else + { + P_SetMobjStateNF(actor, S_MNTR_ROAM1); + } +} + + + + +void A_MinotaurChase(mobj_t * actor) +{ + unsigned int *starttime = (unsigned int *) actor->args; + + actor->flags &= ~MF_SHADOW; // In case pain caused him to + actor->flags &= ~MF_ALTSHADOW; // skip his fade in. + + if ((leveltime - *starttime) >= MAULATORTICS) + { + P_DamageMobj(actor, NULL, NULL, 10000); + return; + } + + if (P_Random() < 30) + A_MinotaurLook(actor); // adjust to closest target + + if (!actor->target || (actor->target->health <= 0) || + !(actor->target->flags & MF_SHOOTABLE)) + { // look for a new target + P_SetMobjState(actor, S_MNTR_LOOK1); + return; + } + + FaceMovementDirection(actor); + actor->reactiontime = 0; + + // Melee attack + if (actor->info->meleestate && P_CheckMeleeRange(actor)) + { + if (actor->info->attacksound) + { + S_StartSound(actor, actor->info->attacksound); + } + P_SetMobjState(actor, actor->info->meleestate); + return; + } + + // Missile attack + if (actor->info->missilestate && P_CheckMissileRange(actor)) + { + P_SetMobjState(actor, actor->info->missilestate); + return; + } + + // chase towards target + if (!P_Move(actor)) + { + P_NewChaseDir(actor); + } + + // Active sound + if (actor->info->activesound && P_Random() < 6) + { + S_StartSound(actor, actor->info->activesound); + } } @@ -1257,15 +1285,16 @@ void A_MinotaurChase(mobj_t *actor) // //---------------------------------------------------------------------------- -void A_MinotaurAtk1(mobj_t *actor) +void A_MinotaurAtk1(mobj_t * actor) { - if (!actor->target) return; + if (!actor->target) + return; - S_StartSound(actor, SFX_MAULATOR_HAMMER_SWING); - if(P_CheckMeleeRange(actor)) - { - P_DamageMobj(actor->target, actor, actor, HITDICE(4)); - } + S_StartSound(actor, SFX_MAULATOR_HAMMER_SWING); + if (P_CheckMeleeRange(actor)) + { + P_DamageMobj(actor->target, actor, actor, HITDICE(4)); + } } //---------------------------------------------------------------------------- @@ -1278,43 +1307,42 @@ void A_MinotaurAtk1(mobj_t *actor) #define MNTR_CHARGE_SPEED (23*FRACUNIT) -void A_MinotaurDecide(mobj_t *actor) -{ - angle_t angle; - mobj_t *target = actor->target; - int dist; - - if (!target) return; - dist = P_AproxDistance(actor->x-target->x, actor->y-target->y); - - if(target->z+target->height > actor->z - && target->z+target->height < actor->z+actor->height - && dist < 16*64*FRACUNIT - && dist > 1*64*FRACUNIT - && P_Random() < 230) - { // Charge attack - // Don't call the state function right away - P_SetMobjStateNF(actor, S_MNTR_ATK4_1); - actor->flags |= MF_SKULLFLY; - A_FaceTarget(actor); - angle = actor->angle>>ANGLETOFINESHIFT; - actor->momx = FixedMul(MNTR_CHARGE_SPEED, finecosine[angle]); - actor->momy = FixedMul(MNTR_CHARGE_SPEED, finesine[angle]); - actor->args[4] = 35/2; // Charge duration - } - else if(target->z == target->floorz - && dist < 9*64*FRACUNIT - && P_Random() < 100) - { // Floor fire attack - P_SetMobjState(actor, S_MNTR_ATK3_1); - actor->special2 = 0; - } - else - { // Swing attack - A_FaceTarget(actor); - // Don't need to call P_SetMobjState because the current state - // falls through to the swing attack - } +void A_MinotaurDecide(mobj_t * actor) +{ + angle_t angle; + mobj_t *target = actor->target; + int dist; + + if (!target) + return; + dist = P_AproxDistance(actor->x - target->x, actor->y - target->y); + + if (target->z + target->height > actor->z + && target->z + target->height < actor->z + actor->height + && dist < 16 * 64 * FRACUNIT + && dist > 1 * 64 * FRACUNIT && P_Random() < 230) + { // Charge attack + // Don't call the state function right away + P_SetMobjStateNF(actor, S_MNTR_ATK4_1); + actor->flags |= MF_SKULLFLY; + A_FaceTarget(actor); + angle = actor->angle >> ANGLETOFINESHIFT; + actor->momx = FixedMul(MNTR_CHARGE_SPEED, finecosine[angle]); + actor->momy = FixedMul(MNTR_CHARGE_SPEED, finesine[angle]); + actor->args[4] = 35 / 2; // Charge duration + } + else if (target->z == target->floorz + && dist < 9 * 64 * FRACUNIT && P_Random() < 100) + { // Floor fire attack + P_SetMobjState(actor, S_MNTR_ATK3_1); + actor->special2 = 0; + } + else + { // Swing attack + A_FaceTarget(actor); + // Don't need to call P_SetMobjState because the current state + // falls through to the swing attack + } } //---------------------------------------------------------------------------- @@ -1323,23 +1351,24 @@ void A_MinotaurDecide(mobj_t *actor) // //---------------------------------------------------------------------------- -void A_MinotaurCharge(mobj_t *actor) +void A_MinotaurCharge(mobj_t * actor) { - mobj_t *puff; + mobj_t *puff; - if (!actor->target) return; + if (!actor->target) + return; - if(actor->args[4] > 0) - { - puff = P_SpawnMobj(actor->x, actor->y, actor->z, MT_PUNCHPUFF); - puff->momz = 2*FRACUNIT; - actor->args[4]--; - } - else - { - actor->flags &= ~MF_SKULLFLY; - P_SetMobjState(actor, actor->info->seestate); - } + if (actor->args[4] > 0) + { + puff = P_SpawnMobj(actor->x, actor->y, actor->z, MT_PUNCHPUFF); + puff->momz = 2 * FRACUNIT; + actor->args[4]--; + } + else + { + actor->flags &= ~MF_SKULLFLY; + P_SetMobjState(actor, actor->info->seestate); + } } //---------------------------------------------------------------------------- @@ -1350,32 +1379,33 @@ void A_MinotaurCharge(mobj_t *actor) // //---------------------------------------------------------------------------- -void A_MinotaurAtk2(mobj_t *actor) -{ - mobj_t *mo; - angle_t angle; - fixed_t momz; - - if(!actor->target) return; - - S_StartSound(actor, SFX_MAULATOR_HAMMER_SWING); - if(P_CheckMeleeRange(actor)) - { - P_DamageMobj(actor->target, actor, actor, HITDICE(3)); - return; - } - mo = P_SpawnMissile(actor, actor->target, MT_MNTRFX1); - if(mo) - { - //S_StartSound(mo, sfx_minat2); - momz = mo->momz; - angle = mo->angle; - P_SpawnMissileAngle(actor, MT_MNTRFX1, angle-(ANG45/8), momz); - P_SpawnMissileAngle(actor, MT_MNTRFX1, angle+(ANG45/8), momz); - P_SpawnMissileAngle(actor, MT_MNTRFX1, angle-(ANG45/16), momz); - P_SpawnMissileAngle(actor, MT_MNTRFX1, angle+(ANG45/16), momz); - } -} +void A_MinotaurAtk2(mobj_t * actor) +{ + mobj_t *mo; + angle_t angle; + fixed_t momz; + + if (!actor->target) + return; + + S_StartSound(actor, SFX_MAULATOR_HAMMER_SWING); + if (P_CheckMeleeRange(actor)) + { + P_DamageMobj(actor->target, actor, actor, HITDICE(3)); + return; + } + mo = P_SpawnMissile(actor, actor->target, MT_MNTRFX1); + if (mo) + { + //S_StartSound(mo, sfx_minat2); + momz = mo->momz; + angle = mo->angle; + P_SpawnMissileAngle(actor, MT_MNTRFX1, angle - (ANG45 / 8), momz); + P_SpawnMissileAngle(actor, MT_MNTRFX1, angle + (ANG45 / 8), momz); + P_SpawnMissileAngle(actor, MT_MNTRFX1, angle - (ANG45 / 16), momz); + P_SpawnMissileAngle(actor, MT_MNTRFX1, angle + (ANG45 / 16), momz); + } +} //---------------------------------------------------------------------------- // @@ -1385,36 +1415,36 @@ void A_MinotaurAtk2(mobj_t *actor) // //---------------------------------------------------------------------------- -void A_MinotaurAtk3(mobj_t *actor) -{ - mobj_t *mo; - player_t *player; - - if(!actor->target) - { - return; - } - if(P_CheckMeleeRange(actor)) - { - P_DamageMobj(actor->target, actor, actor, HITDICE(3)); - if((player = actor->target->player) != NULL) - { // Squish the player - player->deltaviewheight = -16*FRACUNIT; - } - } - else - { - mo = P_SpawnMissile(actor, actor->target, MT_MNTRFX2); - if(mo != NULL) - { - S_StartSound(mo, SFX_MAULATOR_HAMMER_HIT); - } - } - if(P_Random() < 192 && actor->special2 == 0) - { - P_SetMobjState(actor, S_MNTR_ATK3_4); - actor->special2 = 1; - } +void A_MinotaurAtk3(mobj_t * actor) +{ + mobj_t *mo; + player_t *player; + + if (!actor->target) + { + return; + } + if (P_CheckMeleeRange(actor)) + { + P_DamageMobj(actor->target, actor, actor, HITDICE(3)); + if ((player = actor->target->player) != NULL) + { // Squish the player + player->deltaviewheight = -16 * FRACUNIT; + } + } + else + { + mo = P_SpawnMissile(actor, actor->target, MT_MNTRFX2); + if (mo != NULL) + { + S_StartSound(mo, SFX_MAULATOR_HAMMER_HIT); + } + } + if (P_Random() < 192 && actor->special2 == 0) + { + P_SetMobjState(actor, S_MNTR_ATK3_4); + actor->special2 = 1; + } } //---------------------------------------------------------------------------- @@ -1423,16 +1453,17 @@ void A_MinotaurAtk3(mobj_t *actor) // //---------------------------------------------------------------------------- -void A_MntrFloorFire(mobj_t *actor) +void A_MntrFloorFire(mobj_t * actor) { - mobj_t *mo; + mobj_t *mo; - actor->z = actor->floorz; - mo = P_SpawnMobj(actor->x+((P_Random()-P_Random())<<10), - actor->y+((P_Random()-P_Random())<<10), ONFLOORZ, MT_MNTRFX3); - mo->target = actor->target; - mo->momx = 1; // Force block checking - P_CheckMissileSpawn(mo); + actor->z = actor->floorz; + mo = P_SpawnMobj(actor->x + ((P_Random() - P_Random()) << 10), + actor->y + ((P_Random() - P_Random()) << 10), ONFLOORZ, + MT_MNTRFX3); + mo->target = actor->target; + mo->momx = 1; // Force block checking + P_CheckMissileSpawn(mo); } @@ -1442,86 +1473,86 @@ void A_MntrFloorFire(mobj_t *actor) // //---------------------------------------------------------------------------- -void A_Scream(mobj_t *actor) -{ - int sound; - - S_StopSound(actor); - if(actor->player) - { - if(actor->player->morphTics) - { - S_StartSound(actor, actor->info->deathsound); - } - else - { - // Handle the different player death screams - if(actor->momz <= -39*FRACUNIT) - { // Falling splat - sound = SFX_PLAYER_FALLING_SPLAT; - } - else if(actor->health > -50) - { // Normal death sound - switch(actor->player->class) - { - case PCLASS_FIGHTER: - sound = SFX_PLAYER_FIGHTER_NORMAL_DEATH; - break; - case PCLASS_CLERIC: - sound = SFX_PLAYER_CLERIC_NORMAL_DEATH; - break; - case PCLASS_MAGE: - sound = SFX_PLAYER_MAGE_NORMAL_DEATH; - break; - default: - sound = SFX_NONE; - break; - } - } - else if(actor->health > -100) - { // Crazy death sound - switch(actor->player->class) - { - case PCLASS_FIGHTER: - sound = SFX_PLAYER_FIGHTER_CRAZY_DEATH; - break; - case PCLASS_CLERIC: - sound = SFX_PLAYER_CLERIC_CRAZY_DEATH; - break; - case PCLASS_MAGE: - sound = SFX_PLAYER_MAGE_CRAZY_DEATH; - break; - default: - sound = SFX_NONE; - break; - } - } - else - { // Extreme death sound - switch(actor->player->class) - { - case PCLASS_FIGHTER: - sound = SFX_PLAYER_FIGHTER_EXTREME1_DEATH; - break; - case PCLASS_CLERIC: - sound = SFX_PLAYER_CLERIC_EXTREME1_DEATH; - break; - case PCLASS_MAGE: - sound = SFX_PLAYER_MAGE_EXTREME1_DEATH; - break; - default: - sound = SFX_NONE; - break; - } - sound += P_Random()%3; // Three different extreme deaths - } - S_StartSound(actor, sound); - } - } - else - { - S_StartSound(actor, actor->info->deathsound); - } +void A_Scream(mobj_t * actor) +{ + int sound; + + S_StopSound(actor); + if (actor->player) + { + if (actor->player->morphTics) + { + S_StartSound(actor, actor->info->deathsound); + } + else + { + // Handle the different player death screams + if (actor->momz <= -39 * FRACUNIT) + { // Falling splat + sound = SFX_PLAYER_FALLING_SPLAT; + } + else if (actor->health > -50) + { // Normal death sound + switch (actor->player->class) + { + case PCLASS_FIGHTER: + sound = SFX_PLAYER_FIGHTER_NORMAL_DEATH; + break; + case PCLASS_CLERIC: + sound = SFX_PLAYER_CLERIC_NORMAL_DEATH; + break; + case PCLASS_MAGE: + sound = SFX_PLAYER_MAGE_NORMAL_DEATH; + break; + default: + sound = SFX_NONE; + break; + } + } + else if (actor->health > -100) + { // Crazy death sound + switch (actor->player->class) + { + case PCLASS_FIGHTER: + sound = SFX_PLAYER_FIGHTER_CRAZY_DEATH; + break; + case PCLASS_CLERIC: + sound = SFX_PLAYER_CLERIC_CRAZY_DEATH; + break; + case PCLASS_MAGE: + sound = SFX_PLAYER_MAGE_CRAZY_DEATH; + break; + default: + sound = SFX_NONE; + break; + } + } + else + { // Extreme death sound + switch (actor->player->class) + { + case PCLASS_FIGHTER: + sound = SFX_PLAYER_FIGHTER_EXTREME1_DEATH; + break; + case PCLASS_CLERIC: + sound = SFX_PLAYER_CLERIC_EXTREME1_DEATH; + break; + case PCLASS_MAGE: + sound = SFX_PLAYER_MAGE_EXTREME1_DEATH; + break; + default: + sound = SFX_NONE; + break; + } + sound += P_Random() % 3; // Three different extreme deaths + } + S_StartSound(actor, sound); + } + } + else + { + S_StartSound(actor, actor->info->deathsound); + } } //--------------------------------------------------------------------------- @@ -1555,11 +1586,11 @@ void P_DropItem(mobj_t *source, mobjtype_t type, int special, int chance) // //---------------------------------------------------------------------------- -void A_NoBlocking(mobj_t *actor) +void A_NoBlocking(mobj_t * actor) { - actor->flags &= ~MF_SOLID; + actor->flags &= ~MF_SOLID; - // Check for monsters dropping things + // Check for monsters dropping things /* switch(actor->type) { // Add the monster dropped items here @@ -1580,87 +1611,87 @@ void A_NoBlocking(mobj_t *actor) // //---------------------------------------------------------------------------- -void A_Explode(mobj_t *actor) -{ - int damage; - int distance; - boolean damageSelf; - - damage = 128; - distance = 128; - damageSelf = true; - switch(actor->type) - { - case MT_FIREBOMB: // Time Bombs - actor->z += 32*FRACUNIT; - actor->flags &= ~MF_SHADOW; - break; - case MT_MNTRFX2: // Minotaur floor fire - damage = 24; - break; - case MT_BISHOP: // Bishop radius death - damage = 25+(P_Random()&15); - break; - case MT_HAMMER_MISSILE: // Fighter Hammer - damage = 128; - damageSelf = false; - break; - case MT_FSWORD_MISSILE: // Fighter Runesword - damage = 64; - damageSelf = false; - break; - case MT_CIRCLEFLAME: // Cleric Flame secondary flames - damage = 20; - damageSelf = false; - break; - case MT_SORCBALL1: // Sorcerer balls - case MT_SORCBALL2: - case MT_SORCBALL3: - distance = 255; - damage = 255; - actor->args[0] = 1; // don't play bounce - break; - case MT_SORCFX1: // Sorcerer spell 1 - damage = 30; - break; - case MT_SORCFX4: // Sorcerer spell 4 - damage = 20; - break; - case MT_TREEDESTRUCTIBLE: - damage = 10; - break; - case MT_DRAGON_FX2: - damage = 80; - damageSelf = false; - break; - case MT_MSTAFF_FX: - damage = 64; - distance = 192; - damageSelf = false; - break; - case MT_MSTAFF_FX2: - damage = 80; - distance = 192; - damageSelf = false; - break; - case MT_POISONCLOUD: - damage = 4; - distance = 40; - break; - case MT_ZXMAS_TREE: - case MT_ZSHRUB2: - damage = 30; - distance = 64; - break; - default: - break; - } - P_RadiusAttack(actor, actor->target, damage, distance, damageSelf); - if(actor->z <= actor->floorz+(distance<type != MT_POISONCLOUD) - { - P_HitFloor(actor); - } +void A_Explode(mobj_t * actor) +{ + int damage; + int distance; + boolean damageSelf; + + damage = 128; + distance = 128; + damageSelf = true; + switch (actor->type) + { + case MT_FIREBOMB: // Time Bombs + actor->z += 32 * FRACUNIT; + actor->flags &= ~MF_SHADOW; + break; + case MT_MNTRFX2: // Minotaur floor fire + damage = 24; + break; + case MT_BISHOP: // Bishop radius death + damage = 25 + (P_Random() & 15); + break; + case MT_HAMMER_MISSILE: // Fighter Hammer + damage = 128; + damageSelf = false; + break; + case MT_FSWORD_MISSILE: // Fighter Runesword + damage = 64; + damageSelf = false; + break; + case MT_CIRCLEFLAME: // Cleric Flame secondary flames + damage = 20; + damageSelf = false; + break; + case MT_SORCBALL1: // Sorcerer balls + case MT_SORCBALL2: + case MT_SORCBALL3: + distance = 255; + damage = 255; + actor->args[0] = 1; // don't play bounce + break; + case MT_SORCFX1: // Sorcerer spell 1 + damage = 30; + break; + case MT_SORCFX4: // Sorcerer spell 4 + damage = 20; + break; + case MT_TREEDESTRUCTIBLE: + damage = 10; + break; + case MT_DRAGON_FX2: + damage = 80; + damageSelf = false; + break; + case MT_MSTAFF_FX: + damage = 64; + distance = 192; + damageSelf = false; + break; + case MT_MSTAFF_FX2: + damage = 80; + distance = 192; + damageSelf = false; + break; + case MT_POISONCLOUD: + damage = 4; + distance = 40; + break; + case MT_ZXMAS_TREE: + case MT_ZSHRUB2: + damage = 30; + distance = 64; + break; + default: + break; + } + P_RadiusAttack(actor, actor->target, damage, distance, damageSelf); + if (actor->z <= actor->floorz + (distance << FRACBITS) + && actor->type != MT_POISONCLOUD) + { + P_HitFloor(actor); + } } //---------------------------------------------------------------------------- @@ -1673,28 +1704,27 @@ void A_Explode(mobj_t *actor) int P_Massacre(void) { - int count; - mobj_t *mo; - thinker_t *think; + int count; + mobj_t *mo; + thinker_t *think; - count = 0; - for(think = thinkercap.next; think != &thinkercap; - think = think->next) - { - if(think->function != P_MobjThinker) - { // Not a mobj thinker - continue; - } - mo = (mobj_t *)think; - if((mo->flags&MF_COUNTKILL) && (mo->health > 0)) - { - mo->flags2 &= ~(MF2_NONSHOOTABLE+MF2_INVULNERABLE); - mo->flags |= MF_SHOOTABLE; - P_DamageMobj(mo, NULL, NULL, 10000); - count++; - } - } - return count; + count = 0; + for (think = thinkercap.next; think != &thinkercap; think = think->next) + { + if (think->function != P_MobjThinker) + { // Not a mobj thinker + continue; + } + mo = (mobj_t *) think; + if ((mo->flags & MF_COUNTKILL) && (mo->health > 0)) + { + mo->flags2 &= ~(MF2_NONSHOOTABLE + MF2_INVULNERABLE); + mo->flags |= MF_SHOOTABLE; + P_DamageMobj(mo, NULL, NULL, 10000); + count++; + } + } + return count; } @@ -1705,32 +1735,32 @@ int P_Massacre(void) // //---------------------------------------------------------------------------- -void A_SkullPop(mobj_t *actor) -{ - mobj_t *mo; - player_t *player; - - if(!actor->player) - { - return; - } - actor->flags &= ~MF_SOLID; - mo = P_SpawnMobj(actor->x, actor->y, actor->z+48*FRACUNIT, - MT_BLOODYSKULL); - //mo->target = actor; - mo->momx = (P_Random()-P_Random())<<9; - mo->momy = (P_Random()-P_Random())<<9; - mo->momz = FRACUNIT*2+(P_Random()<<6); - // Attach player mobj to bloody skull - player = actor->player; - actor->player = NULL; - actor->special1 = player->class; - mo->player = player; - mo->health = actor->health; - mo->angle = actor->angle; - player->mo = mo; - player->lookdir = 0; - player->damagecount = 32; +void A_SkullPop(mobj_t * actor) +{ + mobj_t *mo; + player_t *player; + + if (!actor->player) + { + return; + } + actor->flags &= ~MF_SOLID; + mo = P_SpawnMobj(actor->x, actor->y, actor->z + 48 * FRACUNIT, + MT_BLOODYSKULL); + //mo->target = actor; + mo->momx = (P_Random() - P_Random()) << 9; + mo->momy = (P_Random() - P_Random()) << 9; + mo->momz = FRACUNIT * 2 + (P_Random() << 6); + // Attach player mobj to bloody skull + player = actor->player; + actor->player = NULL; + actor->special1 = player->class; + mo->player = player; + mo->health = actor->health; + mo->angle = actor->angle; + player->mo = mo; + player->lookdir = 0; + player->damagecount = 32; } //---------------------------------------------------------------------------- @@ -1739,13 +1769,13 @@ void A_SkullPop(mobj_t *actor) // //---------------------------------------------------------------------------- -void A_CheckSkullFloor(mobj_t *actor) +void A_CheckSkullFloor(mobj_t * actor) { - if(actor->z <= actor->floorz) - { - P_SetMobjState(actor, S_BLOODYSKULLX1); - S_StartSound(actor, SFX_DRIP); - } + if (actor->z <= actor->floorz) + { + P_SetMobjState(actor, S_BLOODYSKULLX1); + S_StartSound(actor, SFX_DRIP); + } } //---------------------------------------------------------------------------- @@ -1754,12 +1784,12 @@ void A_CheckSkullFloor(mobj_t *actor) // //---------------------------------------------------------------------------- -void A_CheckSkullDone(mobj_t *actor) +void A_CheckSkullDone(mobj_t * actor) { - if(actor->special2 == 666) - { - P_SetMobjState(actor, S_BLOODYSKULLX2); - } + if (actor->special2 == 666) + { + P_SetMobjState(actor, S_BLOODYSKULLX2); + } } //---------------------------------------------------------------------------- @@ -1768,12 +1798,12 @@ void A_CheckSkullDone(mobj_t *actor) // //---------------------------------------------------------------------------- -void A_CheckBurnGone(mobj_t *actor) +void A_CheckBurnGone(mobj_t * actor) { - if(actor->special2 == 666) - { - P_SetMobjState(actor, S_PLAY_FDTH20); - } + if (actor->special2 == 666) + { + P_SetMobjState(actor, S_PLAY_FDTH20); + } } //---------------------------------------------------------------------------- @@ -1782,16 +1812,17 @@ void A_CheckBurnGone(mobj_t *actor) // //---------------------------------------------------------------------------- -void A_FreeTargMobj(mobj_t *mo) +void A_FreeTargMobj(mobj_t * mo) { - mo->momx = mo->momy = mo->momz = 0; - mo->z = mo->ceilingz+4*FRACUNIT; - mo->flags &= ~(MF_SHOOTABLE|MF_FLOAT|MF_SKULLFLY|MF_SOLID|MF_COUNTKILL); - mo->flags |= MF_CORPSE|MF_DROPOFF|MF_NOGRAVITY; - mo->flags2 &= ~(MF2_PASSMOBJ|MF2_LOGRAV); - mo->flags2 |= MF2_DONTDRAW; - mo->player = NULL; - mo->health = -1000; // Don't resurrect + mo->momx = mo->momy = mo->momz = 0; + mo->z = mo->ceilingz + 4 * FRACUNIT; + mo->flags &= + ~(MF_SHOOTABLE | MF_FLOAT | MF_SKULLFLY | MF_SOLID | MF_COUNTKILL); + mo->flags |= MF_CORPSE | MF_DROPOFF | MF_NOGRAVITY; + mo->flags2 &= ~(MF2_PASSMOBJ | MF2_LOGRAV); + mo->flags2 |= MF2_DONTDRAW; + mo->player = NULL; + mo->health = -1000; // Don't resurrect } @@ -1807,84 +1838,89 @@ mobj_t *corpseQueue[CORPSEQUEUESIZE]; int corpseQueueSlot; // throw another corpse on the queue -void A_QueueCorpse(mobj_t *actor) +void A_QueueCorpse(mobj_t * actor) { - mobj_t *corpse; + mobj_t *corpse; - if(corpseQueueSlot >= CORPSEQUEUESIZE) - { // Too many corpses - remove an old one - corpse = corpseQueue[corpseQueueSlot%CORPSEQUEUESIZE]; - if (corpse) P_RemoveMobj(corpse); - } - corpseQueue[corpseQueueSlot%CORPSEQUEUESIZE] = actor; - corpseQueueSlot++; + if (corpseQueueSlot >= CORPSEQUEUESIZE) + { // Too many corpses - remove an old one + corpse = corpseQueue[corpseQueueSlot % CORPSEQUEUESIZE]; + if (corpse) + P_RemoveMobj(corpse); + } + corpseQueue[corpseQueueSlot % CORPSEQUEUESIZE] = actor; + corpseQueueSlot++; } // Remove a mobj from the queue (for resurrection) -void A_DeQueueCorpse(mobj_t *actor) +void A_DeQueueCorpse(mobj_t * actor) { - int slot; + int slot; - for (slot=0; slotnext) - { - if(think->function != P_MobjThinker) continue; - mo = (mobj_t *)think; - if (!(mo->flags&MF_CORPSE)) continue; // Must be a corpse - if (mo->flags&MF_ICECORPSE) continue; // Not ice corpses - // Only corpses that call A_QueueCorpse from death routine - switch(mo->type) - { - case MT_CENTAUR: - case MT_CENTAURLEADER: - case MT_DEMON: - case MT_DEMON2: - case MT_WRAITH: - case MT_WRAITHB: - case MT_BISHOP: - case MT_ETTIN: - case MT_PIG: - case MT_CENTAUR_SHIELD: - case MT_CENTAUR_SWORD: - case MT_DEMONCHUNK1: - case MT_DEMONCHUNK2: - case MT_DEMONCHUNK3: - case MT_DEMONCHUNK4: - case MT_DEMONCHUNK5: - case MT_DEMON2CHUNK1: - case MT_DEMON2CHUNK2: - case MT_DEMON2CHUNK3: - case MT_DEMON2CHUNK4: - case MT_DEMON2CHUNK5: - case MT_FIREDEMON_SPLOTCH1: - case MT_FIREDEMON_SPLOTCH2: - A_QueueCorpse(mo); // Add corpse to queue - break; - default: - break; - } - } + thinker_t *think; + mobj_t *mo; + + // Initialize queue + corpseQueueSlot = 0; + memset(corpseQueue, 0, sizeof(mobj_t *) * CORPSEQUEUESIZE); + + if (!corpseScan) + return; + + // Search mobj list for corpses and place them in this queue + for (think = thinkercap.next; think != &thinkercap; think = think->next) + { + if (think->function != P_MobjThinker) + continue; + mo = (mobj_t *) think; + if (!(mo->flags & MF_CORPSE)) + continue; // Must be a corpse + if (mo->flags & MF_ICECORPSE) + continue; // Not ice corpses + // Only corpses that call A_QueueCorpse from death routine + switch (mo->type) + { + case MT_CENTAUR: + case MT_CENTAURLEADER: + case MT_DEMON: + case MT_DEMON2: + case MT_WRAITH: + case MT_WRAITHB: + case MT_BISHOP: + case MT_ETTIN: + case MT_PIG: + case MT_CENTAUR_SHIELD: + case MT_CENTAUR_SWORD: + case MT_DEMONCHUNK1: + case MT_DEMONCHUNK2: + case MT_DEMONCHUNK3: + case MT_DEMONCHUNK4: + case MT_DEMONCHUNK5: + case MT_DEMON2CHUNK1: + case MT_DEMON2CHUNK2: + case MT_DEMON2CHUNK3: + case MT_DEMON2CHUNK4: + case MT_DEMON2CHUNK5: + case MT_FIREDEMON_SPLOTCH1: + case MT_FIREDEMON_SPLOTCH2: + A_QueueCorpse(mo); // Add corpse to queue + break; + default: + break; + } + } } @@ -1898,14 +1934,14 @@ void P_InitCreatureCorpseQueue(boolean corpseScan) mobj_t *bodyque[BODYQUESIZE]; int bodyqueslot; -void A_AddPlayerCorpse(mobj_t *actor) +void A_AddPlayerCorpse(mobj_t * actor) { - if(bodyqueslot >= BODYQUESIZE) - { // Too many player corpses - remove an old one - P_RemoveMobj(bodyque[bodyqueslot%BODYQUESIZE]); - } - bodyque[bodyqueslot%BODYQUESIZE] = actor; - bodyqueslot++; + if (bodyqueslot >= BODYQUESIZE) + { // Too many player corpses - remove an old one + P_RemoveMobj(bodyque[bodyqueslot % BODYQUESIZE]); + } + bodyque[bodyqueslot % BODYQUESIZE] = actor; + bodyqueslot++; } //============================================================================ @@ -1914,10 +1950,10 @@ void A_AddPlayerCorpse(mobj_t *actor) // //============================================================================ -void A_SerpentUnHide(mobj_t *actor) +void A_SerpentUnHide(mobj_t * actor) { - actor->flags2 &= ~MF2_DONTDRAW; - actor->floorclip = 24*FRACUNIT; + actor->flags2 &= ~MF2_DONTDRAW; + actor->floorclip = 24 * FRACUNIT; } //============================================================================ @@ -1926,125 +1962,126 @@ void A_SerpentUnHide(mobj_t *actor) // //============================================================================ -void A_SerpentHide(mobj_t *actor) +void A_SerpentHide(mobj_t * actor) { - actor->flags2 |= MF2_DONTDRAW; - actor->floorclip = 0; + actor->flags2 |= MF2_DONTDRAW; + actor->floorclip = 0; } + //============================================================================ // // A_SerpentChase // //============================================================================ -void A_SerpentChase(mobj_t *actor) +void A_SerpentChase(mobj_t * actor) { - int delta; - int oldX, oldY, oldFloor; + int delta; + int oldX, oldY, oldFloor; - if(actor->reactiontime) - { - actor->reactiontime--; - } + if (actor->reactiontime) + { + actor->reactiontime--; + } - // Modify target threshold - if(actor->threshold) - { - actor->threshold--; - } + // Modify target threshold + if (actor->threshold) + { + actor->threshold--; + } - if(gameskill == sk_nightmare) - { // Monsters move faster in nightmare mode - actor->tics -= actor->tics/2; - if(actor->tics < 3) - { - actor->tics = 3; - } - } + if (gameskill == sk_nightmare) + { // Monsters move faster in nightmare mode + actor->tics -= actor->tics / 2; + if (actor->tics < 3) + { + actor->tics = 3; + } + } // // turn towards movement direction if not there yet // - if(actor->movedir < 8) - { - actor->angle &= (7<<29); - delta = actor->angle-(actor->movedir << 29); - if(delta > 0) - { - actor->angle -= ANG90/2; - } - else if(delta < 0) - { - actor->angle += ANG90/2; - } - } - - if(!actor->target || !(actor->target->flags&MF_SHOOTABLE)) - { // look for a new target - if(P_LookForPlayers(actor, true)) - { // got a new target - return; - } - P_SetMobjState(actor, actor->info->spawnstate); - return; - } + if (actor->movedir < 8) + { + actor->angle &= (7 << 29); + delta = actor->angle - (actor->movedir << 29); + if (delta > 0) + { + actor->angle -= ANG90 / 2; + } + else if (delta < 0) + { + actor->angle += ANG90 / 2; + } + } + + if (!actor->target || !(actor->target->flags & MF_SHOOTABLE)) + { // look for a new target + if (P_LookForPlayers(actor, true)) + { // got a new target + return; + } + P_SetMobjState(actor, actor->info->spawnstate); + return; + } // // don't attack twice in a row // - if(actor->flags & MF_JUSTATTACKED) - { - actor->flags &= ~MF_JUSTATTACKED; - if (gameskill != sk_nightmare) - P_NewChaseDir (actor); - return; - } + if (actor->flags & MF_JUSTATTACKED) + { + actor->flags &= ~MF_JUSTATTACKED; + if (gameskill != sk_nightmare) + P_NewChaseDir(actor); + return; + } // // check for melee attack // - if (actor->info->meleestate && P_CheckMeleeRange (actor)) - { - if(actor->info->attacksound) - { - S_StartSound (actor, actor->info->attacksound); - } - P_SetMobjState (actor, actor->info->meleestate); - return; - } + if (actor->info->meleestate && P_CheckMeleeRange(actor)) + { + if (actor->info->attacksound) + { + S_StartSound(actor, actor->info->attacksound); + } + P_SetMobjState(actor, actor->info->meleestate); + return; + } // // possibly choose another target // - if (netgame && !actor->threshold && !P_CheckSight (actor, actor->target) ) - { - if (P_LookForPlayers(actor,true)) - return; // got a new target - } + if (netgame && !actor->threshold && !P_CheckSight(actor, actor->target)) + { + if (P_LookForPlayers(actor, true)) + return; // got a new target + } // // chase towards player // - oldX = actor->x; - oldY = actor->y; - oldFloor = actor->subsector->sector->floorpic; - if (--actor->movecount<0 || !P_Move (actor)) - { - P_NewChaseDir (actor); - } - if(actor->subsector->sector->floorpic != oldFloor) - { - P_TryMove(actor, oldX, oldY); - P_NewChaseDir (actor); - } + oldX = actor->x; + oldY = actor->y; + oldFloor = actor->subsector->sector->floorpic; + if (--actor->movecount < 0 || !P_Move(actor)) + { + P_NewChaseDir(actor); + } + if (actor->subsector->sector->floorpic != oldFloor) + { + P_TryMove(actor, oldX, oldY); + P_NewChaseDir(actor); + } // // make active sound // - if(actor->info->activesound && P_Random() < 3) - { - S_StartSound(actor, actor->info->activesound); - } + if (actor->info->activesound && P_Random() < 3) + { + S_StartSound(actor, actor->info->activesound); + } } //============================================================================ @@ -2054,9 +2091,9 @@ void A_SerpentChase(mobj_t *actor) // Raises the hump above the surface by raising the floorclip level //============================================================================ -void A_SerpentRaiseHump(mobj_t *actor) +void A_SerpentRaiseHump(mobj_t * actor) { - actor->floorclip -= 4*FRACUNIT; + actor->floorclip -= 4 * FRACUNIT; } //============================================================================ @@ -2065,49 +2102,49 @@ void A_SerpentRaiseHump(mobj_t *actor) // //============================================================================ -void A_SerpentLowerHump(mobj_t *actor) +void A_SerpentLowerHump(mobj_t * actor) { - actor->floorclip += 4*FRACUNIT; + actor->floorclip += 4 * FRACUNIT; } //============================================================================ // // A_SerpentHumpDecide // -// Decided whether to hump up, or if the mobj is a serpent leader, -// to missile attack -//============================================================================ - -void A_SerpentHumpDecide(mobj_t *actor) -{ - if(actor->type == MT_SERPENTLEADER) - { - if(P_Random() > 30) - { - return; - } - else if(P_Random() < 40) - { // Missile attack - P_SetMobjState(actor, S_SERPENT_SURFACE1); - return; - } - } - else if(P_Random() > 3) - { - return; - } - if(!P_CheckMeleeRange(actor)) - { // The hump shouldn't occur when within melee range - if(actor->type == MT_SERPENTLEADER && P_Random() < 128) - { - P_SetMobjState(actor, S_SERPENT_SURFACE1); - } - else - { - P_SetMobjState(actor, S_SERPENT_HUMP1); - S_StartSound(actor, SFX_SERPENT_ACTIVE); - } - } +// Decided whether to hump up, or if the mobj is a serpent leader, +// to missile attack +//============================================================================ + +void A_SerpentHumpDecide(mobj_t * actor) +{ + if (actor->type == MT_SERPENTLEADER) + { + if (P_Random() > 30) + { + return; + } + else if (P_Random() < 40) + { // Missile attack + P_SetMobjState(actor, S_SERPENT_SURFACE1); + return; + } + } + else if (P_Random() > 3) + { + return; + } + if (!P_CheckMeleeRange(actor)) + { // The hump shouldn't occur when within melee range + if (actor->type == MT_SERPENTLEADER && P_Random() < 128) + { + P_SetMobjState(actor, S_SERPENT_SURFACE1); + } + else + { + P_SetMobjState(actor, S_SERPENT_HUMP1); + S_StartSound(actor, SFX_SERPENT_ACTIVE); + } + } } //============================================================================ @@ -2116,9 +2153,9 @@ void A_SerpentHumpDecide(mobj_t *actor) // //============================================================================ -void A_SerpentBirthScream(mobj_t *actor) +void A_SerpentBirthScream(mobj_t * actor) { - S_StartSound(actor, SFX_SERPENT_BIRTH); + S_StartSound(actor, SFX_SERPENT_BIRTH); } //============================================================================ @@ -2127,9 +2164,9 @@ void A_SerpentBirthScream(mobj_t *actor) // //============================================================================ -void A_SerpentDiveSound(mobj_t *actor) +void A_SerpentDiveSound(mobj_t * actor) { - S_StartSound(actor, SFX_SERPENT_ACTIVE); + S_StartSound(actor, SFX_SERPENT_ACTIVE); } //============================================================================ @@ -2139,96 +2176,96 @@ void A_SerpentDiveSound(mobj_t *actor) // Similar to A_Chase, only has a hardcoded entering of meleestate //============================================================================ -void A_SerpentWalk(mobj_t *actor) +void A_SerpentWalk(mobj_t * actor) { - int delta; + int delta; - if(actor->reactiontime) - { - actor->reactiontime--; - } + if (actor->reactiontime) + { + actor->reactiontime--; + } - // Modify target threshold - if(actor->threshold) - { - actor->threshold--; - } + // Modify target threshold + if (actor->threshold) + { + actor->threshold--; + } - if(gameskill == sk_nightmare) - { // Monsters move faster in nightmare mode - actor->tics -= actor->tics/2; - if(actor->tics < 3) - { - actor->tics = 3; - } - } + if (gameskill == sk_nightmare) + { // Monsters move faster in nightmare mode + actor->tics -= actor->tics / 2; + if (actor->tics < 3) + { + actor->tics = 3; + } + } // // turn towards movement direction if not there yet // - if(actor->movedir < 8) - { - actor->angle &= (7<<29); - delta = actor->angle-(actor->movedir << 29); - if(delta > 0) - { - actor->angle -= ANG90/2; - } - else if(delta < 0) - { - actor->angle += ANG90/2; - } - } - - if(!actor->target || !(actor->target->flags&MF_SHOOTABLE)) - { // look for a new target - if(P_LookForPlayers(actor, true)) - { // got a new target - return; - } - P_SetMobjState(actor, actor->info->spawnstate); - return; - } + if (actor->movedir < 8) + { + actor->angle &= (7 << 29); + delta = actor->angle - (actor->movedir << 29); + if (delta > 0) + { + actor->angle -= ANG90 / 2; + } + else if (delta < 0) + { + actor->angle += ANG90 / 2; + } + } + + if (!actor->target || !(actor->target->flags & MF_SHOOTABLE)) + { // look for a new target + if (P_LookForPlayers(actor, true)) + { // got a new target + return; + } + P_SetMobjState(actor, actor->info->spawnstate); + return; + } // // don't attack twice in a row // - if(actor->flags & MF_JUSTATTACKED) - { - actor->flags &= ~MF_JUSTATTACKED; - if (gameskill != sk_nightmare) - P_NewChaseDir (actor); - return; - } + if (actor->flags & MF_JUSTATTACKED) + { + actor->flags &= ~MF_JUSTATTACKED; + if (gameskill != sk_nightmare) + P_NewChaseDir(actor); + return; + } // // check for melee attack // - if (actor->info->meleestate && P_CheckMeleeRange (actor)) - { - if (actor->info->attacksound) - { - S_StartSound (actor, actor->info->attacksound); - } - P_SetMobjState(actor, S_SERPENT_ATK1); - return; - } + if (actor->info->meleestate && P_CheckMeleeRange(actor)) + { + if (actor->info->attacksound) + { + S_StartSound(actor, actor->info->attacksound); + } + P_SetMobjState(actor, S_SERPENT_ATK1); + return; + } // // possibly choose another target // - if (netgame && !actor->threshold && !P_CheckSight (actor, actor->target) ) - { - if (P_LookForPlayers(actor,true)) - return; // got a new target - } + if (netgame && !actor->threshold && !P_CheckSight(actor, actor->target)) + { + if (P_LookForPlayers(actor, true)) + return; // got a new target + } // // chase towards player // - if (--actor->movecount<0 || !P_Move (actor)) - { - P_NewChaseDir (actor); - } + if (--actor->movecount < 0 || !P_Move(actor)) + { + P_NewChaseDir(actor); + } } //============================================================================ @@ -2237,35 +2274,35 @@ void A_SerpentWalk(mobj_t *actor) // //============================================================================ -void A_SerpentCheckForAttack(mobj_t *actor) -{ - if(!actor->target) - { - return; - } - if(actor->type == MT_SERPENTLEADER) - { - if(!P_CheckMeleeRange(actor)) - { - P_SetMobjState(actor, S_SERPENT_ATK1); - return; - } - } - if(P_CheckMeleeRange2(actor)) - { - P_SetMobjState(actor, S_SERPENT_WALK1); - } - else if(P_CheckMeleeRange(actor)) - { - if(P_Random() < 32) - { - P_SetMobjState(actor, S_SERPENT_WALK1); - } - else - { - P_SetMobjState(actor, S_SERPENT_ATK1); - } - } +void A_SerpentCheckForAttack(mobj_t * actor) +{ + if (!actor->target) + { + return; + } + if (actor->type == MT_SERPENTLEADER) + { + if (!P_CheckMeleeRange(actor)) + { + P_SetMobjState(actor, S_SERPENT_ATK1); + return; + } + } + if (P_CheckMeleeRange2(actor)) + { + P_SetMobjState(actor, S_SERPENT_WALK1); + } + else if (P_CheckMeleeRange(actor)) + { + if (P_Random() < 32) + { + P_SetMobjState(actor, S_SERPENT_WALK1); + } + else + { + P_SetMobjState(actor, S_SERPENT_ATK1); + } + } } //============================================================================ @@ -2274,39 +2311,39 @@ void A_SerpentCheckForAttack(mobj_t *actor) // //============================================================================ -void A_SerpentChooseAttack(mobj_t *actor) +void A_SerpentChooseAttack(mobj_t * actor) { - if(!actor->target || P_CheckMeleeRange(actor)) - { - return; - } - if(actor->type == MT_SERPENTLEADER) - { - P_SetMobjState(actor, S_SERPENT_MISSILE1); - } + if (!actor->target || P_CheckMeleeRange(actor)) + { + return; + } + if (actor->type == MT_SERPENTLEADER) + { + P_SetMobjState(actor, S_SERPENT_MISSILE1); + } } - + //============================================================================ // // A_SerpentMeleeAttack // //============================================================================ -void A_SerpentMeleeAttack(mobj_t *actor) +void A_SerpentMeleeAttack(mobj_t * actor) { - if(!actor->target) - { - return; - } - if(P_CheckMeleeRange(actor)) - { - P_DamageMobj(actor->target, actor, actor, HITDICE(5)); - S_StartSound(actor, SFX_SERPENT_MELEEHIT); - } - if(P_Random() < 96) - { - A_SerpentCheckForAttack(actor); - } + if (!actor->target) + { + return; + } + if (P_CheckMeleeRange(actor)) + { + P_DamageMobj(actor->target, actor, actor, HITDICE(5)); + S_StartSound(actor, SFX_SERPENT_MELEEHIT); + } + if (P_Random() < 96) + { + A_SerpentCheckForAttack(actor); + } } //============================================================================ @@ -2314,16 +2351,16 @@ void A_SerpentMeleeAttack(mobj_t *actor) // A_SerpentMissileAttack // //============================================================================ - -void A_SerpentMissileAttack(mobj_t *actor) + +void A_SerpentMissileAttack(mobj_t * actor) { - mobj_t *mo; + mobj_t *mo; - if(!actor->target) - { - return; - } - mo = P_SpawnMissile(actor, actor->target, MT_SERPENTFX); + if (!actor->target) + { + return; + } + mo = P_SpawnMissile(actor, actor->target, MT_SERPENTFX); } //============================================================================ @@ -2332,9 +2369,10 @@ void A_SerpentMissileAttack(mobj_t *actor) // //============================================================================ -void A_SerpentHeadPop(mobj_t *actor) +void A_SerpentHeadPop(mobj_t * actor) { - P_SpawnMobj(actor->x, actor->y, actor->z+45*FRACUNIT, MT_SERPENT_HEAD); + P_SpawnMobj(actor->x, actor->y, actor->z + 45 * FRACUNIT, + MT_SERPENT_HEAD); } //============================================================================ @@ -2343,37 +2381,37 @@ void A_SerpentHeadPop(mobj_t *actor) // //============================================================================ -void A_SerpentSpawnGibs(mobj_t *actor) +void A_SerpentSpawnGibs(mobj_t * actor) { - mobj_t *mo; + mobj_t *mo; - mo = P_SpawnMobj(actor->x+((P_Random()-128)<<12), - actor->y+((P_Random()-128)<<12), actor->floorz+FRACUNIT, - MT_SERPENT_GIB1); - if(mo) - { - mo->momx = (P_Random()-128)<<6; - mo->momy = (P_Random()-128)<<6; - mo->floorclip = 6*FRACUNIT; - } - mo = P_SpawnMobj(actor->x+((P_Random()-128)<<12), - actor->y+((P_Random()-128)<<12), actor->floorz+FRACUNIT, - MT_SERPENT_GIB2); - if(mo) - { - mo->momx = (P_Random()-128)<<6; - mo->momy = (P_Random()-128)<<6; - mo->floorclip = 6*FRACUNIT; - } - mo = P_SpawnMobj(actor->x+((P_Random()-128)<<12), - actor->y+((P_Random()-128)<<12), actor->floorz+FRACUNIT, - MT_SERPENT_GIB3); - if(mo) - { - mo->momx = (P_Random()-128)<<6; - mo->momy = (P_Random()-128)<<6; - mo->floorclip = 6*FRACUNIT; - } + mo = P_SpawnMobj(actor->x + ((P_Random() - 128) << 12), + actor->y + ((P_Random() - 128) << 12), + actor->floorz + FRACUNIT, MT_SERPENT_GIB1); + if (mo) + { + mo->momx = (P_Random() - 128) << 6; + mo->momy = (P_Random() - 128) << 6; + mo->floorclip = 6 * FRACUNIT; + } + mo = P_SpawnMobj(actor->x + ((P_Random() - 128) << 12), + actor->y + ((P_Random() - 128) << 12), + actor->floorz + FRACUNIT, MT_SERPENT_GIB2); + if (mo) + { + mo->momx = (P_Random() - 128) << 6; + mo->momy = (P_Random() - 128) << 6; + mo->floorclip = 6 * FRACUNIT; + } + mo = P_SpawnMobj(actor->x + ((P_Random() - 128) << 12), + actor->y + ((P_Random() - 128) << 12), + actor->floorz + FRACUNIT, MT_SERPENT_GIB3); + if (mo) + { + mo->momx = (P_Random() - 128) << 6; + mo->momy = (P_Random() - 128) << 6; + mo->floorclip = 6 * FRACUNIT; + } } //============================================================================ @@ -2382,9 +2420,9 @@ void A_SerpentSpawnGibs(mobj_t *actor) // //============================================================================ -void A_FloatGib(mobj_t *actor) +void A_FloatGib(mobj_t * actor) { - actor->floorclip -= FRACUNIT; + actor->floorclip -= FRACUNIT; } //============================================================================ @@ -2393,9 +2431,9 @@ void A_FloatGib(mobj_t *actor) // //============================================================================ -void A_SinkGib(mobj_t *actor) +void A_SinkGib(mobj_t * actor) { - actor->floorclip += FRACUNIT; + actor->floorclip += FRACUNIT; } //============================================================================ @@ -2404,9 +2442,9 @@ void A_SinkGib(mobj_t *actor) // //============================================================================ -void A_DelayGib(mobj_t *actor) +void A_DelayGib(mobj_t * actor) { - actor->tics -= P_Random()>>2; + actor->tics -= P_Random() >> 2; } //============================================================================ @@ -2415,20 +2453,20 @@ void A_DelayGib(mobj_t *actor) // //============================================================================ -void A_SerpentHeadCheck(mobj_t *actor) +void A_SerpentHeadCheck(mobj_t * actor) { - if(actor->z <= actor->floorz) - { - if(P_GetThingFloorType(actor) >= FLOOR_LIQUID) - { - P_HitFloor(actor); - P_SetMobjState(actor, S_NULL); - } - else - { - P_SetMobjState(actor, S_SERPENT_HEAD_X1); - } - } + if (actor->z <= actor->floorz) + { + if (P_GetThingFloorType(actor) >= FLOOR_LIQUID) + { + P_HitFloor(actor); + P_SetMobjState(actor, S_NULL); + } + else + { + P_SetMobjState(actor, S_SERPENT_HEAD_X1); + } + } } //============================================================================ @@ -2437,16 +2475,16 @@ void A_SerpentHeadCheck(mobj_t *actor) // //============================================================================ -void A_CentaurAttack(mobj_t *actor) +void A_CentaurAttack(mobj_t * actor) { - if(!actor->target) - { - return; - } - if(P_CheckMeleeRange(actor)) - { - P_DamageMobj(actor->target, actor, actor, P_Random()%7+3); - } + if (!actor->target) + { + return; + } + if (P_CheckMeleeRange(actor)) + { + P_DamageMobj(actor->target, actor, actor, P_Random() % 7 + 3); + } } //============================================================================ @@ -2455,51 +2493,51 @@ void A_CentaurAttack(mobj_t *actor) // //============================================================================ -void A_CentaurAttack2(mobj_t *actor) +void A_CentaurAttack2(mobj_t * actor) { - if(!actor->target) - { - return; - } - P_SpawnMissile(actor, actor->target, MT_CENTAUR_FX); - S_StartSound(actor, SFX_CENTAURLEADER_ATTACK); + if (!actor->target) + { + return; + } + P_SpawnMissile(actor, actor->target, MT_CENTAUR_FX); + S_StartSound(actor, SFX_CENTAURLEADER_ATTACK); } //============================================================================ // // A_CentaurDropStuff // -// Spawn shield/sword sprites when the centaur pulps //============================================================================ - -void A_CentaurDropStuff(mobj_t *actor) -{ - mobj_t *mo; - angle_t angle; - - mo = P_SpawnMobj(actor->x, actor->y, actor->z+45*FRACUNIT, - MT_CENTAUR_SHIELD); - if(mo) - { - angle = actor->angle+ANG90; - mo->momz = FRACUNIT*8+(P_Random()<<10); - mo->momx = FixedMul(((P_Random()-128)<<11)+FRACUNIT, - finecosine[angle>>ANGLETOFINESHIFT]); - mo->momy = FixedMul(((P_Random()-128)<<11)+FRACUNIT, - finesine[angle>>ANGLETOFINESHIFT]); - mo->target = actor; - } - mo = P_SpawnMobj(actor->x, actor->y, actor->z+45*FRACUNIT, - MT_CENTAUR_SWORD); - if(mo) - { - angle = actor->angle-ANG90; - mo->momz = FRACUNIT*8+(P_Random()<<10); - mo->momx = FixedMul(((P_Random()-128)<<11)+FRACUNIT, - finecosine[angle>>ANGLETOFINESHIFT]); - mo->momy = FixedMul(((P_Random()-128)<<11)+FRACUNIT, - finesine[angle>>ANGLETOFINESHIFT]); - mo->target = actor; - } +// Spawn shield/sword sprites when the centaur pulps //============================================================================ + +void A_CentaurDropStuff(mobj_t * actor) +{ + mobj_t *mo; + angle_t angle; + + mo = P_SpawnMobj(actor->x, actor->y, actor->z + 45 * FRACUNIT, + MT_CENTAUR_SHIELD); + if (mo) + { + angle = actor->angle + ANG90; + mo->momz = FRACUNIT * 8 + (P_Random() << 10); + mo->momx = FixedMul(((P_Random() - 128) << 11) + FRACUNIT, + finecosine[angle >> ANGLETOFINESHIFT]); + mo->momy = FixedMul(((P_Random() - 128) << 11) + FRACUNIT, + finesine[angle >> ANGLETOFINESHIFT]); + mo->target = actor; + } + mo = P_SpawnMobj(actor->x, actor->y, actor->z + 45 * FRACUNIT, + MT_CENTAUR_SWORD); + if (mo) + { + angle = actor->angle - ANG90; + mo->momz = FRACUNIT * 8 + (P_Random() << 10); + mo->momx = FixedMul(((P_Random() - 128) << 11) + FRACUNIT, + finecosine[angle >> ANGLETOFINESHIFT]); + mo->momy = FixedMul(((P_Random() - 128) << 11) + FRACUNIT, + finesine[angle >> ANGLETOFINESHIFT]); + mo->target = actor; + } } //============================================================================ @@ -2508,14 +2546,14 @@ void A_CentaurDropStuff(mobj_t *actor) // //============================================================================ -void A_CentaurDefend(mobj_t *actor) +void A_CentaurDefend(mobj_t * actor) { - A_FaceTarget(actor); - if(P_CheckMeleeRange(actor) && P_Random() < 32) - { - A_UnSetInvulnerable(actor); - P_SetMobjState(actor, actor->info->meleestate); - } + A_FaceTarget(actor); + if (P_CheckMeleeRange(actor) && P_Random() < 32) + { + A_UnSetInvulnerable(actor); + P_SetMobjState(actor, actor->info->meleestate); + } } //============================================================================ @@ -2524,45 +2562,45 @@ void A_CentaurDefend(mobj_t *actor) // //============================================================================ -void A_BishopAttack(mobj_t *actor) +void A_BishopAttack(mobj_t * actor) { - if(!actor->target) - { - return; - } - S_StartSound(actor, actor->info->attacksound); - if(P_CheckMeleeRange(actor)) - { - P_DamageMobj(actor->target, actor, actor, HITDICE(4)); - return; - } - actor->special1 = (P_Random()&3)+5; + if (!actor->target) + { + return; + } + S_StartSound(actor, actor->info->attacksound); + if (P_CheckMeleeRange(actor)) + { + P_DamageMobj(actor->target, actor, actor, HITDICE(4)); + return; + } + actor->special1 = (P_Random() & 3) + 5; } //============================================================================ // // A_BishopAttack2 // -// Spawns one of a string of bishop missiles +// Spawns one of a string of bishop missiles //============================================================================ -void A_BishopAttack2(mobj_t *actor) +void A_BishopAttack2(mobj_t * actor) { - mobj_t *mo; + mobj_t *mo; - if(!actor->target || !actor->special1) - { - actor->special1 = 0; - P_SetMobjState(actor, S_BISHOP_WALK1); - return; - } - mo = P_SpawnMissile(actor, actor->target, MT_BISH_FX); - if(mo) - { - mo->special1 = (int)actor->target; - mo->special2 = 16; // High word == x/y, Low word == z - } - actor->special1--; + if (!actor->target || !actor->special1) + { + actor->special1 = 0; + P_SetMobjState(actor, S_BISHOP_WALK1); + return; + } + mo = P_SpawnMissile(actor, actor->target, MT_BISH_FX); + if (mo) + { + mo->special1 = (int) actor->target; + mo->special2 = 16; // High word == x/y, Low word == z + } + actor->special1--; } //============================================================================ @@ -2571,29 +2609,27 @@ void A_BishopAttack2(mobj_t *actor) // //============================================================================ -void A_BishopMissileWeave(mobj_t *actor) +void A_BishopMissileWeave(mobj_t * actor) { - fixed_t newX, newY; - int weaveXY, weaveZ; - int angle; + fixed_t newX, newY; + int weaveXY, weaveZ; + int angle; - weaveXY = actor->special2>>16; - weaveZ = actor->special2&0xFFFF; - angle = (actor->angle+ANG90)>>ANGLETOFINESHIFT; - newX = actor->x-FixedMul(finecosine[angle], - FloatBobOffsets[weaveXY]<<1); - newY = actor->y-FixedMul(finesine[angle], - FloatBobOffsets[weaveXY]<<1); - weaveXY = (weaveXY+2)&63; - newX += FixedMul(finecosine[angle], - FloatBobOffsets[weaveXY]<<1); - newY += FixedMul(finesine[angle], - FloatBobOffsets[weaveXY]<<1); - P_TryMove(actor, newX, newY); - actor->z -= FloatBobOffsets[weaveZ]; - weaveZ = (weaveZ+2)&63; - actor->z += FloatBobOffsets[weaveZ]; - actor->special2 = weaveZ+(weaveXY<<16); + weaveXY = actor->special2 >> 16; + weaveZ = actor->special2 & 0xFFFF; + angle = (actor->angle + ANG90) >> ANGLETOFINESHIFT; + newX = actor->x - FixedMul(finecosine[angle], + FloatBobOffsets[weaveXY] << 1); + newY = actor->y - FixedMul(finesine[angle], + FloatBobOffsets[weaveXY] << 1); + weaveXY = (weaveXY + 2) & 63; + newX += FixedMul(finecosine[angle], FloatBobOffsets[weaveXY] << 1); + newY += FixedMul(finesine[angle], FloatBobOffsets[weaveXY] << 1); + P_TryMove(actor, newX, newY); + actor->z -= FloatBobOffsets[weaveZ]; + weaveZ = (weaveZ + 2) & 63; + actor->z += FloatBobOffsets[weaveZ]; + actor->special2 = weaveZ + (weaveXY << 16); } //============================================================================ @@ -2602,9 +2638,9 @@ void A_BishopMissileWeave(mobj_t *actor) // //============================================================================ -void A_BishopMissileSeek(mobj_t *actor) +void A_BishopMissileSeek(mobj_t * actor) { - P_SeekerMissile(actor, ANGLE_1*2, ANGLE_1*3); + P_SeekerMissile(actor, ANGLE_1 * 2, ANGLE_1 * 3); } //============================================================================ @@ -2613,16 +2649,16 @@ void A_BishopMissileSeek(mobj_t *actor) // //============================================================================ -void A_BishopDecide(mobj_t *actor) +void A_BishopDecide(mobj_t * actor) { - if(P_Random() < 220) - { - return; - } - else - { - P_SetMobjState(actor, S_BISHOP_BLUR1); - } + if (P_Random() < 220) + { + return; + } + else + { + P_SetMobjState(actor, S_BISHOP_BLUR1); + } } //============================================================================ @@ -2631,22 +2667,22 @@ void A_BishopDecide(mobj_t *actor) // //============================================================================ -void A_BishopDoBlur(mobj_t *actor) +void A_BishopDoBlur(mobj_t * actor) { - actor->special1 = (P_Random()&3)+3; // Random number of blurs - if(P_Random() < 120) - { - P_ThrustMobj(actor, actor->angle+ANG90, 11*FRACUNIT); - } - else if(P_Random() > 125) - { - P_ThrustMobj(actor, actor->angle-ANG90, 11*FRACUNIT); - } - else - { // Thrust forward - P_ThrustMobj(actor, actor->angle, 11*FRACUNIT); - } - S_StartSound(actor, SFX_BISHOP_BLUR); + actor->special1 = (P_Random() & 3) + 3; // Random number of blurs + if (P_Random() < 120) + { + P_ThrustMobj(actor, actor->angle + ANG90, 11 * FRACUNIT); + } + else if (P_Random() > 125) + { + P_ThrustMobj(actor, actor->angle - ANG90, 11 * FRACUNIT); + } + else + { // Thrust forward + P_ThrustMobj(actor, actor->angle, 11 * FRACUNIT); + } + S_StartSound(actor, SFX_BISHOP_BLUR); } //============================================================================ @@ -2655,28 +2691,28 @@ void A_BishopDoBlur(mobj_t *actor) // //============================================================================ -void A_BishopSpawnBlur(mobj_t *actor) +void A_BishopSpawnBlur(mobj_t * actor) { - mobj_t *mo; + mobj_t *mo; - if(!--actor->special1) - { - actor->momx = 0; - actor->momy = 0; - if(P_Random() > 96) - { - P_SetMobjState(actor, S_BISHOP_WALK1); - } - else - { - P_SetMobjState(actor, S_BISHOP_ATK1); - } - } - mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_BISHOPBLUR); - if(mo) - { - mo->angle = actor->angle; - } + if (!--actor->special1) + { + actor->momx = 0; + actor->momy = 0; + if (P_Random() > 96) + { + P_SetMobjState(actor, S_BISHOP_WALK1); + } + else + { + P_SetMobjState(actor, S_BISHOP_ATK1); + } + } + mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_BISHOPBLUR); + if (mo) + { + mo->angle = actor->angle; + } } //============================================================================ @@ -2685,11 +2721,11 @@ void A_BishopSpawnBlur(mobj_t *actor) // //============================================================================ -void A_BishopChase(mobj_t *actor) +void A_BishopChase(mobj_t * actor) { - actor->z -= FloatBobOffsets[actor->special2]>>1; - actor->special2 = (actor->special2+4)&63; - actor->z += FloatBobOffsets[actor->special2]>>1; + actor->z -= FloatBobOffsets[actor->special2] >> 1; + actor->special2 = (actor->special2 + 4) & 63; + actor->z += FloatBobOffsets[actor->special2] >> 1; } //============================================================================ @@ -2698,16 +2734,16 @@ void A_BishopChase(mobj_t *actor) // //============================================================================ -void A_BishopPuff(mobj_t *actor) +void A_BishopPuff(mobj_t * actor) { - mobj_t *mo; + mobj_t *mo; - mo = P_SpawnMobj(actor->x, actor->y, actor->z+40*FRACUNIT, - MT_BISHOP_PUFF); - if(mo) - { - mo->momz = FRACUNIT/2; - } + mo = P_SpawnMobj(actor->x, actor->y, actor->z + 40 * FRACUNIT, + MT_BISHOP_PUFF); + if (mo) + { + mo->momz = FRACUNIT / 2; + } } //============================================================================ @@ -2716,22 +2752,23 @@ void A_BishopPuff(mobj_t *actor) // //============================================================================ -void A_BishopPainBlur(mobj_t *actor) +void A_BishopPainBlur(mobj_t * actor) { - mobj_t *mo; + mobj_t *mo; - if(P_Random() < 64) - { - P_SetMobjState(actor, S_BISHOP_BLUR1); - return; - } - mo = P_SpawnMobj(actor->x+((P_Random()-P_Random())<<12), actor->y - +((P_Random()-P_Random())<<12), actor->z+((P_Random()-P_Random())<<11), - MT_BISHOPPAINBLUR); - if(mo) - { - mo->angle = actor->angle; - } + if (P_Random() < 64) + { + P_SetMobjState(actor, S_BISHOP_BLUR1); + return; + } + mo = P_SpawnMobj(actor->x + ((P_Random() - P_Random()) << 12), actor->y + + ((P_Random() - P_Random()) << 12), + actor->z + ((P_Random() - P_Random()) << 11), + MT_BISHOPPAINBLUR); + if (mo) + { + mo->angle = actor->angle; + } } //============================================================================ @@ -2740,124 +2777,128 @@ void A_BishopPainBlur(mobj_t *actor) // //============================================================================ -static void DragonSeek(mobj_t *actor, angle_t thresh, angle_t turnMax) -{ - int dir; - int dist; - angle_t delta; - angle_t angle; - mobj_t *target; - int search; - int i; - int bestArg; - angle_t bestAngle; - angle_t angleToSpot, angleToTarget; - mobj_t *mo; - - target = (mobj_t *)actor->special1; - if(target == NULL) - { - return; - } - dir = P_FaceMobj(actor, target, &delta); - if(delta > thresh) - { - delta >>= 1; - if(delta > turnMax) - { - delta = turnMax; - } - } - if(dir) - { // Turn clockwise - actor->angle += delta; - } - else - { // Turn counter clockwise - actor->angle -= delta; - } - angle = actor->angle>>ANGLETOFINESHIFT; - actor->momx = FixedMul(actor->info->speed, finecosine[angle]); - actor->momy = FixedMul(actor->info->speed, finesine[angle]); - if(actor->z+actor->height < target->z - || target->z+target->height < actor->z) - { - dist = P_AproxDistance(target->x-actor->x, target->y-actor->y); - dist = dist/actor->info->speed; - if(dist < 1) - { - dist = 1; - } - actor->momz = (target->z-actor->z)/dist; - } - else - { - dist = P_AproxDistance(target->x-actor->x, target->y-actor->y); - dist = dist/actor->info->speed; - } - if(target->flags&MF_SHOOTABLE && P_Random() < 64) - { // attack the destination mobj if it's attackable - mobj_t *oldTarget; - - if(abs(actor->angle-R_PointToAngle2(actor->x, actor->y, - target->x, target->y)) < ANGLE_45/2) - { - oldTarget = actor->target; - actor->target = target; - if(P_CheckMeleeRange(actor)) - { - P_DamageMobj(actor->target, actor, actor, HITDICE(10)); - S_StartSound(actor, SFX_DRAGON_ATTACK); - } - else if(P_Random() < 128 && P_CheckMissileRange(actor)) - { - P_SpawnMissile(actor, target, MT_DRAGON_FX); - S_StartSound(actor, SFX_DRAGON_ATTACK); - } - actor->target = oldTarget; - } - } - if(dist < 4) - { // Hit the target thing - if(actor->target && P_Random() < 200) - { - bestArg = -1; - bestAngle = ANGLE_MAX; - angleToTarget = R_PointToAngle2(actor->x, actor->y, - actor->target->x, actor->target->y); - for(i = 0; i < 5; i++) - { - if(!target->args[i]) - { - continue; - } - search = -1; - mo = P_FindMobjFromTID(target->args[i], &search); - angleToSpot = R_PointToAngle2(actor->x, actor->y, - mo->x, mo->y); - if(abs(angleToSpot-angleToTarget) < bestAngle) - { - bestAngle = abs(angleToSpot-angleToTarget); - bestArg = i; - } - } - if(bestArg != -1) - { - search = -1; - actor->special1 = (int)P_FindMobjFromTID(target->args[bestArg], - &search); - } - } - else - { - do - { - i = (P_Random()>>2)%5; - } while(!target->args[i]); - search = -1; - actor->special1 = (int)P_FindMobjFromTID(target->args[i], &search); - } - } +static void DragonSeek(mobj_t * actor, angle_t thresh, angle_t turnMax) +{ + int dir; + int dist; + angle_t delta; + angle_t angle; + mobj_t *target; + int search; + int i; + int bestArg; + angle_t bestAngle; + angle_t angleToSpot, angleToTarget; + mobj_t *mo; + + target = (mobj_t *) actor->special1; + if (target == NULL) + { + return; + } + dir = P_FaceMobj(actor, target, &delta); + if (delta > thresh) + { + delta >>= 1; + if (delta > turnMax) + { + delta = turnMax; + } + } + if (dir) + { // Turn clockwise + actor->angle += delta; + } + else + { // Turn counter clockwise + actor->angle -= delta; + } + angle = actor->angle >> ANGLETOFINESHIFT; + actor->momx = FixedMul(actor->info->speed, finecosine[angle]); + actor->momy = FixedMul(actor->info->speed, finesine[angle]); + if (actor->z + actor->height < target->z + || target->z + target->height < actor->z) + { + dist = P_AproxDistance(target->x - actor->x, target->y - actor->y); + dist = dist / actor->info->speed; + if (dist < 1) + { + dist = 1; + } + actor->momz = (target->z - actor->z) / dist; + } + else + { + dist = P_AproxDistance(target->x - actor->x, target->y - actor->y); + dist = dist / actor->info->speed; + } + if (target->flags & MF_SHOOTABLE && P_Random() < 64) + { // attack the destination mobj if it's attackable + mobj_t *oldTarget; + + if (abs(actor->angle - R_PointToAngle2(actor->x, actor->y, + target->x, + target->y)) < ANGLE_45 / 2) + { + oldTarget = actor->target; + actor->target = target; + if (P_CheckMeleeRange(actor)) + { + P_DamageMobj(actor->target, actor, actor, HITDICE(10)); + S_StartSound(actor, SFX_DRAGON_ATTACK); + } + else if (P_Random() < 128 && P_CheckMissileRange(actor)) + { + P_SpawnMissile(actor, target, MT_DRAGON_FX); + S_StartSound(actor, SFX_DRAGON_ATTACK); + } + actor->target = oldTarget; + } + } + if (dist < 4) + { // Hit the target thing + if (actor->target && P_Random() < 200) + { + bestArg = -1; + bestAngle = ANGLE_MAX; + angleToTarget = R_PointToAngle2(actor->x, actor->y, + actor->target->x, + actor->target->y); + for (i = 0; i < 5; i++) + { + if (!target->args[i]) + { + continue; + } + search = -1; + mo = P_FindMobjFromTID(target->args[i], &search); + angleToSpot = R_PointToAngle2(actor->x, actor->y, + mo->x, mo->y); + if (abs(angleToSpot - angleToTarget) < bestAngle) + { + bestAngle = abs(angleToSpot - angleToTarget); + bestArg = i; + } + } + if (bestArg != -1) + { + search = -1; + actor->special1 = + (int) P_FindMobjFromTID(target->args[bestArg], &search); + } + } + else + { + do + { + i = (P_Random() >> 2) % 5; + } + while (!target->args[i]); + search = -1; + actor->special1 = + (int) P_FindMobjFromTID(target->args[i], &search); + } + } } //============================================================================ @@ -2866,21 +2907,22 @@ static void DragonSeek(mobj_t *actor, angle_t thresh, angle_t turnMax) // //============================================================================ -void A_DragonInitFlight(mobj_t *actor) +void A_DragonInitFlight(mobj_t * actor) { - int search; + int search; - search = -1; - do - { // find the first tid identical to the dragon's tid - actor->special1 = (int)P_FindMobjFromTID(actor->tid, &search); - if(search == -1) - { - P_SetMobjState(actor, actor->info->spawnstate); - return; - } - } while(actor->special1 == (int)actor); - P_RemoveMobjFromTIDList(actor); + search = -1; + do + { // find the first tid identical to the dragon's tid + actor->special1 = (int) P_FindMobjFromTID(actor->tid, &search); + if (search == -1) + { + P_SetMobjState(actor, actor->info->spawnstate); + return; + } + } + while (actor->special1 == (int) actor); + P_RemoveMobjFromTIDList(actor); } //============================================================================ @@ -2889,35 +2931,36 @@ void A_DragonInitFlight(mobj_t *actor) // //============================================================================ -void A_DragonFlight(mobj_t *actor) +void A_DragonFlight(mobj_t * actor) { - angle_t angle; + angle_t angle; - DragonSeek(actor, 4*ANGLE_1, 8*ANGLE_1); - if(actor->target) - { - if(!(actor->target->flags&MF_SHOOTABLE)) - { // target died - actor->target = NULL; - return; - } - angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, - actor->target->y); - if(abs(actor->angle-angle) < ANGLE_45/2 && P_CheckMeleeRange(actor)) - { - P_DamageMobj(actor->target, actor, actor, HITDICE(8)); - S_StartSound(actor, SFX_DRAGON_ATTACK); - } - else if(abs(actor->angle-angle) <= ANGLE_1*20) - { - P_SetMobjState(actor, actor->info->missilestate); - S_StartSound(actor, SFX_DRAGON_ATTACK); - } - } - else - { - P_LookForPlayers(actor, true); - } + DragonSeek(actor, 4 * ANGLE_1, 8 * ANGLE_1); + if (actor->target) + { + if (!(actor->target->flags & MF_SHOOTABLE)) + { // target died + actor->target = NULL; + return; + } + angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, + actor->target->y); + if (abs(actor->angle - angle) < ANGLE_45 / 2 + && P_CheckMeleeRange(actor)) + { + P_DamageMobj(actor->target, actor, actor, HITDICE(8)); + S_StartSound(actor, SFX_DRAGON_ATTACK); + } + else if (abs(actor->angle - angle) <= ANGLE_1 * 20) + { + P_SetMobjState(actor, actor->info->missilestate); + S_StartSound(actor, SFX_DRAGON_ATTACK); + } + } + else + { + P_LookForPlayers(actor, true); + } } //============================================================================ @@ -2926,17 +2969,17 @@ void A_DragonFlight(mobj_t *actor) // //============================================================================ -void A_DragonFlap(mobj_t *actor) +void A_DragonFlap(mobj_t * actor) { - A_DragonFlight(actor); - if(P_Random() < 240) - { - S_StartSound(actor, SFX_DRAGON_WINGFLAP); - } - else - { - S_StartSound(actor, actor->info->activesound); - } + A_DragonFlight(actor); + if (P_Random() < 240) + { + S_StartSound(actor, SFX_DRAGON_WINGFLAP); + } + else + { + S_StartSound(actor, actor->info->activesound); + } } //============================================================================ @@ -2945,11 +2988,11 @@ void A_DragonFlap(mobj_t *actor) // //============================================================================ -void A_DragonAttack(mobj_t *actor) +void A_DragonAttack(mobj_t * actor) { - mobj_t *mo; + mobj_t *mo; - mo = P_SpawnMissile(actor, actor->target, MT_DRAGON_FX); + mo = P_SpawnMissile(actor, actor->target, MT_DRAGON_FX); } //============================================================================ @@ -2958,24 +3001,25 @@ void A_DragonAttack(mobj_t *actor) // //============================================================================ -void A_DragonFX2(mobj_t *actor) +void A_DragonFX2(mobj_t * actor) { - mobj_t *mo; - int i; - int delay; + mobj_t *mo; + int i; + int delay; - delay = 16+(P_Random()>>3); - for(i = 1+(P_Random()&3); i; i--) - { - mo = P_SpawnMobj(actor->x+((P_Random()-128)<<14), - actor->y+((P_Random()-128)<<14), actor->z+((P_Random()-128)<<12), - MT_DRAGON_FX2); - if(mo) - { - mo->tics = delay+(P_Random()&3)*i*2; - mo->target = actor->target; - } - } + delay = 16 + (P_Random() >> 3); + for (i = 1 + (P_Random() & 3); i; i--) + { + mo = P_SpawnMobj(actor->x + ((P_Random() - 128) << 14), + actor->y + ((P_Random() - 128) << 14), + actor->z + ((P_Random() - 128) << 12), + MT_DRAGON_FX2); + if (mo) + { + mo->tics = delay + (P_Random() & 3) * i * 2; + mo->target = actor->target; + } + } } //============================================================================ @@ -2984,13 +3028,13 @@ void A_DragonFX2(mobj_t *actor) // //============================================================================ -void A_DragonPain(mobj_t *actor) +void A_DragonPain(mobj_t * actor) { - A_Pain(actor); - if(!actor->special1) - { // no destination spot yet - P_SetMobjState(actor, S_DRAGON_INIT); - } + A_Pain(actor); + if (!actor->special1) + { // no destination spot yet + P_SetMobjState(actor, S_DRAGON_INIT); + } } //============================================================================ @@ -2999,12 +3043,12 @@ void A_DragonPain(mobj_t *actor) // //============================================================================ -void A_DragonCheckCrash(mobj_t *actor) +void A_DragonCheckCrash(mobj_t * actor) { - if(actor->z <= actor->floorz) - { - P_SetMobjState(actor, S_DRAGON_CRASH1); - } + if (actor->z <= actor->floorz) + { + P_SetMobjState(actor, S_DRAGON_CRASH1); + } } //============================================================================ @@ -3014,108 +3058,108 @@ void A_DragonCheckCrash(mobj_t *actor) // // A_DemonAttack1 (melee) // -void A_DemonAttack1(mobj_t *actor) +void A_DemonAttack1(mobj_t * actor) { - if(P_CheckMeleeRange(actor)) - { - P_DamageMobj(actor->target, actor, actor, HITDICE(2)); - } + if (P_CheckMeleeRange(actor)) + { + P_DamageMobj(actor->target, actor, actor, HITDICE(2)); + } } // // A_DemonAttack2 (missile) // -void A_DemonAttack2(mobj_t *actor) +void A_DemonAttack2(mobj_t * actor) { - mobj_t *mo; - int fireBall; + mobj_t *mo; + int fireBall; - if(actor->type == MT_DEMON) - { - fireBall = MT_DEMONFX1; - } - else - { - fireBall = MT_DEMON2FX1; - } - mo = P_SpawnMissile(actor, actor->target, fireBall); - if (mo) - { - mo->z += 30*FRACUNIT; - S_StartSound(actor, SFX_DEMON_MISSILE_FIRE); - } + if (actor->type == MT_DEMON) + { + fireBall = MT_DEMONFX1; + } + else + { + fireBall = MT_DEMON2FX1; + } + mo = P_SpawnMissile(actor, actor->target, fireBall); + if (mo) + { + mo->z += 30 * FRACUNIT; + S_StartSound(actor, SFX_DEMON_MISSILE_FIRE); + } } // // A_DemonDeath // -void A_DemonDeath(mobj_t *actor) -{ - mobj_t *mo; - angle_t angle; - - mo = P_SpawnMobj(actor->x, actor->y, actor->z+45*FRACUNIT, - MT_DEMONCHUNK1); - if(mo) - { - angle = actor->angle+ANG90; - mo->momz = 8*FRACUNIT; - mo->momx = FixedMul((P_Random()<<10)+FRACUNIT, - finecosine[angle>>ANGLETOFINESHIFT]); - mo->momy = FixedMul((P_Random()<<10)+FRACUNIT, - finesine[angle>>ANGLETOFINESHIFT]); - mo->target = actor; - } - mo = P_SpawnMobj(actor->x, actor->y, actor->z+45*FRACUNIT, - MT_DEMONCHUNK2); - if(mo) - { - angle = actor->angle-ANG90; - mo->momz = 8*FRACUNIT; - mo->momx = FixedMul((P_Random()<<10)+FRACUNIT, - finecosine[angle>>ANGLETOFINESHIFT]); - mo->momy = FixedMul((P_Random()<<10)+FRACUNIT, - finesine[angle>>ANGLETOFINESHIFT]); - mo->target = actor; - } - mo = P_SpawnMobj(actor->x, actor->y, actor->z+45*FRACUNIT, - MT_DEMONCHUNK3); - if(mo) - { - angle = actor->angle-ANG90; - mo->momz = 8*FRACUNIT; - mo->momx = FixedMul((P_Random()<<10)+FRACUNIT, - finecosine[angle>>ANGLETOFINESHIFT]); - mo->momy = FixedMul((P_Random()<<10)+FRACUNIT, - finesine[angle>>ANGLETOFINESHIFT]); - mo->target = actor; - } - mo = P_SpawnMobj(actor->x, actor->y, actor->z+45*FRACUNIT, - MT_DEMONCHUNK4); - if(mo) - { - angle = actor->angle-ANG90; - mo->momz = 8*FRACUNIT; - mo->momx = FixedMul((P_Random()<<10)+FRACUNIT, - finecosine[angle>>ANGLETOFINESHIFT]); - mo->momy = FixedMul((P_Random()<<10)+FRACUNIT, - finesine[angle>>ANGLETOFINESHIFT]); - mo->target = actor; - } - mo = P_SpawnMobj(actor->x, actor->y, actor->z+45*FRACUNIT, - MT_DEMONCHUNK5); - if(mo) - { - angle = actor->angle-ANG90; - mo->momz = 8*FRACUNIT; - mo->momx = FixedMul((P_Random()<<10)+FRACUNIT, - finecosine[angle>>ANGLETOFINESHIFT]); - mo->momy = FixedMul((P_Random()<<10)+FRACUNIT, - finesine[angle>>ANGLETOFINESHIFT]); - mo->target = actor; - } +void A_DemonDeath(mobj_t * actor) +{ + mobj_t *mo; + angle_t angle; + + mo = P_SpawnMobj(actor->x, actor->y, actor->z + 45 * FRACUNIT, + MT_DEMONCHUNK1); + if (mo) + { + angle = actor->angle + ANG90; + mo->momz = 8 * FRACUNIT; + mo->momx = FixedMul((P_Random() << 10) + FRACUNIT, + finecosine[angle >> ANGLETOFINESHIFT]); + mo->momy = FixedMul((P_Random() << 10) + FRACUNIT, + finesine[angle >> ANGLETOFINESHIFT]); + mo->target = actor; + } + mo = P_SpawnMobj(actor->x, actor->y, actor->z + 45 * FRACUNIT, + MT_DEMONCHUNK2); + if (mo) + { + angle = actor->angle - ANG90; + mo->momz = 8 * FRACUNIT; + mo->momx = FixedMul((P_Random() << 10) + FRACUNIT, + finecosine[angle >> ANGLETOFINESHIFT]); + mo->momy = FixedMul((P_Random() << 10) + FRACUNIT, + finesine[angle >> ANGLETOFINESHIFT]); + mo->target = actor; + } + mo = P_SpawnMobj(actor->x, actor->y, actor->z + 45 * FRACUNIT, + MT_DEMONCHUNK3); + if (mo) + { + angle = actor->angle - ANG90; + mo->momz = 8 * FRACUNIT; + mo->momx = FixedMul((P_Random() << 10) + FRACUNIT, + finecosine[angle >> ANGLETOFINESHIFT]); + mo->momy = FixedMul((P_Random() << 10) + FRACUNIT, + finesine[angle >> ANGLETOFINESHIFT]); + mo->target = actor; + } + mo = P_SpawnMobj(actor->x, actor->y, actor->z + 45 * FRACUNIT, + MT_DEMONCHUNK4); + if (mo) + { + angle = actor->angle - ANG90; + mo->momz = 8 * FRACUNIT; + mo->momx = FixedMul((P_Random() << 10) + FRACUNIT, + finecosine[angle >> ANGLETOFINESHIFT]); + mo->momy = FixedMul((P_Random() << 10) + FRACUNIT, + finesine[angle >> ANGLETOFINESHIFT]); + mo->target = actor; + } + mo = P_SpawnMobj(actor->x, actor->y, actor->z + 45 * FRACUNIT, + MT_DEMONCHUNK5); + if (mo) + { + angle = actor->angle - ANG90; + mo->momz = 8 * FRACUNIT; + mo->momx = FixedMul((P_Random() << 10) + FRACUNIT, + finecosine[angle >> ANGLETOFINESHIFT]); + mo->momy = FixedMul((P_Random() << 10) + FRACUNIT, + finesine[angle >> ANGLETOFINESHIFT]); + mo->target = actor; + } } //=========================================================================== @@ -3124,71 +3168,71 @@ void A_DemonDeath(mobj_t *actor) // //=========================================================================== -void A_Demon2Death(mobj_t *actor) -{ - mobj_t *mo; - angle_t angle; - - mo = P_SpawnMobj(actor->x, actor->y, actor->z+45*FRACUNIT, - MT_DEMON2CHUNK1); - if(mo) - { - angle = actor->angle+ANG90; - mo->momz = 8*FRACUNIT; - mo->momx = FixedMul((P_Random()<<10)+FRACUNIT, - finecosine[angle>>ANGLETOFINESHIFT]); - mo->momy = FixedMul((P_Random()<<10)+FRACUNIT, - finesine[angle>>ANGLETOFINESHIFT]); - mo->target = actor; - } - mo = P_SpawnMobj(actor->x, actor->y, actor->z+45*FRACUNIT, - MT_DEMON2CHUNK2); - if(mo) - { - angle = actor->angle-ANG90; - mo->momz = 8*FRACUNIT; - mo->momx = FixedMul((P_Random()<<10)+FRACUNIT, - finecosine[angle>>ANGLETOFINESHIFT]); - mo->momy = FixedMul((P_Random()<<10)+FRACUNIT, - finesine[angle>>ANGLETOFINESHIFT]); - mo->target = actor; - } - mo = P_SpawnMobj(actor->x, actor->y, actor->z+45*FRACUNIT, - MT_DEMON2CHUNK3); - if(mo) - { - angle = actor->angle-ANG90; - mo->momz = 8*FRACUNIT; - mo->momx = FixedMul((P_Random()<<10)+FRACUNIT, - finecosine[angle>>ANGLETOFINESHIFT]); - mo->momy = FixedMul((P_Random()<<10)+FRACUNIT, - finesine[angle>>ANGLETOFINESHIFT]); - mo->target = actor; - } - mo = P_SpawnMobj(actor->x, actor->y, actor->z+45*FRACUNIT, - MT_DEMON2CHUNK4); - if(mo) - { - angle = actor->angle-ANG90; - mo->momz = 8*FRACUNIT; - mo->momx = FixedMul((P_Random()<<10)+FRACUNIT, - finecosine[angle>>ANGLETOFINESHIFT]); - mo->momy = FixedMul((P_Random()<<10)+FRACUNIT, - finesine[angle>>ANGLETOFINESHIFT]); - mo->target = actor; - } - mo = P_SpawnMobj(actor->x, actor->y, actor->z+45*FRACUNIT, - MT_DEMON2CHUNK5); - if(mo) - { - angle = actor->angle-ANG90; - mo->momz = 8*FRACUNIT; - mo->momx = FixedMul((P_Random()<<10)+FRACUNIT, - finecosine[angle>>ANGLETOFINESHIFT]); - mo->momy = FixedMul((P_Random()<<10)+FRACUNIT, - finesine[angle>>ANGLETOFINESHIFT]); - mo->target = actor; - } +void A_Demon2Death(mobj_t * actor) +{ + mobj_t *mo; + angle_t angle; + + mo = P_SpawnMobj(actor->x, actor->y, actor->z + 45 * FRACUNIT, + MT_DEMON2CHUNK1); + if (mo) + { + angle = actor->angle + ANG90; + mo->momz = 8 * FRACUNIT; + mo->momx = FixedMul((P_Random() << 10) + FRACUNIT, + finecosine[angle >> ANGLETOFINESHIFT]); + mo->momy = FixedMul((P_Random() << 10) + FRACUNIT, + finesine[angle >> ANGLETOFINESHIFT]); + mo->target = actor; + } + mo = P_SpawnMobj(actor->x, actor->y, actor->z + 45 * FRACUNIT, + MT_DEMON2CHUNK2); + if (mo) + { + angle = actor->angle - ANG90; + mo->momz = 8 * FRACUNIT; + mo->momx = FixedMul((P_Random() << 10) + FRACUNIT, + finecosine[angle >> ANGLETOFINESHIFT]); + mo->momy = FixedMul((P_Random() << 10) + FRACUNIT, + finesine[angle >> ANGLETOFINESHIFT]); + mo->target = actor; + } + mo = P_SpawnMobj(actor->x, actor->y, actor->z + 45 * FRACUNIT, + MT_DEMON2CHUNK3); + if (mo) + { + angle = actor->angle - ANG90; + mo->momz = 8 * FRACUNIT; + mo->momx = FixedMul((P_Random() << 10) + FRACUNIT, + finecosine[angle >> ANGLETOFINESHIFT]); + mo->momy = FixedMul((P_Random() << 10) + FRACUNIT, + finesine[angle >> ANGLETOFINESHIFT]); + mo->target = actor; + } + mo = P_SpawnMobj(actor->x, actor->y, actor->z + 45 * FRACUNIT, + MT_DEMON2CHUNK4); + if (mo) + { + angle = actor->angle - ANG90; + mo->momz = 8 * FRACUNIT; + mo->momx = FixedMul((P_Random() << 10) + FRACUNIT, + finecosine[angle >> ANGLETOFINESHIFT]); + mo->momy = FixedMul((P_Random() << 10) + FRACUNIT, + finesine[angle >> ANGLETOFINESHIFT]); + mo->target = actor; + } + mo = P_SpawnMobj(actor->x, actor->y, actor->z + 45 * FRACUNIT, + MT_DEMON2CHUNK5); + if (mo) + { + angle = actor->angle - ANG90; + mo->momz = 8 * FRACUNIT; + mo->momx = FixedMul((P_Random() << 10) + FRACUNIT, + finecosine[angle >> ANGLETOFINESHIFT]); + mo->momy = FixedMul((P_Random() << 10) + FRACUNIT, + finesine[angle >> ANGLETOFINESHIFT]); + mo->target = actor; + } } @@ -3198,23 +3242,23 @@ void A_Demon2Death(mobj_t *actor) // Sink a mobj incrementally into the floor // -boolean A_SinkMobj(mobj_t *actor) +boolean A_SinkMobj(mobj_t * actor) { - if (actor->floorclip < actor->info->height) - { - switch(actor->type) - { - case MT_THRUSTFLOOR_DOWN: - case MT_THRUSTFLOOR_UP: - actor->floorclip += 6*FRACUNIT; - break; - default: - actor->floorclip += FRACUNIT; - break; - } - return false; - } - return true; + if (actor->floorclip < actor->info->height) + { + switch (actor->type) + { + case MT_THRUSTFLOOR_DOWN: + case MT_THRUSTFLOOR_UP: + actor->floorclip += 6 * FRACUNIT; + break; + default: + actor->floorclip += FRACUNIT; + break; + } + return false; + } + return true; } // @@ -3222,99 +3266,99 @@ boolean A_SinkMobj(mobj_t *actor) // Raise a mobj incrementally from the floor to // -boolean A_RaiseMobj(mobj_t *actor) -{ - int done = true; - - // Raise a mobj from the ground - if (actor->floorclip > 0) - { - switch(actor->type) - { - case MT_WRAITHB: - actor->floorclip -= 2*FRACUNIT; - break; - case MT_THRUSTFLOOR_DOWN: - case MT_THRUSTFLOOR_UP: - actor->floorclip -= actor->special2*FRACUNIT; - break; - default: - actor->floorclip -= 2*FRACUNIT; - break; - } - if (actor->floorclip <= 0) - { - actor->floorclip = 0; - done=true; - } - else - { - done = false; - } - } - return done; // Reached target height +boolean A_RaiseMobj(mobj_t * actor) +{ + int done = true; + + // Raise a mobj from the ground + if (actor->floorclip > 0) + { + switch (actor->type) + { + case MT_WRAITHB: + actor->floorclip -= 2 * FRACUNIT; + break; + case MT_THRUSTFLOOR_DOWN: + case MT_THRUSTFLOOR_UP: + actor->floorclip -= actor->special2 * FRACUNIT; + break; + default: + actor->floorclip -= 2 * FRACUNIT; + break; + } + if (actor->floorclip <= 0) + { + actor->floorclip = 0; + done = true; + } + else + { + done = false; + } + } + return done; // Reached target height } //============================================================================ // Wraith Variables // -// special1 Internal index into floatbob -// special2 +// special1 Internal index into floatbob +// special2 //============================================================================ // // A_WraithInit // -void A_WraithInit(mobj_t *actor) +void A_WraithInit(mobj_t * actor) { - actor->z += 48<special1 = 0; // index into floatbob + actor->z += 48 << FRACBITS; + actor->special1 = 0; // index into floatbob } -void A_WraithRaiseInit(mobj_t *actor) +void A_WraithRaiseInit(mobj_t * actor) { - actor->flags2 &= ~MF2_DONTDRAW; - actor->flags2 &= ~MF2_NONSHOOTABLE; - actor->flags |= MF_SHOOTABLE|MF_SOLID; - actor->floorclip = actor->info->height; + actor->flags2 &= ~MF2_DONTDRAW; + actor->flags2 &= ~MF2_NONSHOOTABLE; + actor->flags |= MF_SHOOTABLE | MF_SOLID; + actor->floorclip = actor->info->height; } -void A_WraithRaise(mobj_t *actor) +void A_WraithRaise(mobj_t * actor) { - if (A_RaiseMobj(actor)) - { - // Reached it's target height - P_SetMobjState(actor,S_WRAITH_CHASE1); - } + if (A_RaiseMobj(actor)) + { + // Reached it's target height + P_SetMobjState(actor, S_WRAITH_CHASE1); + } - P_SpawnDirt(actor, actor->radius); + P_SpawnDirt(actor, actor->radius); } -void A_WraithMelee(mobj_t *actor) +void A_WraithMelee(mobj_t * actor) { - int amount; + int amount; - // Steal health from target and give to player - if(P_CheckMeleeRange(actor) && (P_Random()<220)) - { - amount = HITDICE(2); - P_DamageMobj(actor->target, actor, actor, amount); - actor->health += amount; - } + // Steal health from target and give to player + if (P_CheckMeleeRange(actor) && (P_Random() < 220)) + { + amount = HITDICE(2); + P_DamageMobj(actor->target, actor, actor, amount); + actor->health += amount; + } } -void A_WraithMissile(mobj_t *actor) +void A_WraithMissile(mobj_t * actor) { - mobj_t *mo; + mobj_t *mo; - mo = P_SpawnMissile(actor, actor->target, MT_WRAITHFX1); - if (mo) - { - S_StartSound(actor, SFX_WRAITH_MISSILE_FIRE); - } + mo = P_SpawnMissile(actor, actor->target, MT_WRAITHFX1); + if (mo) + { + S_StartSound(actor, SFX_WRAITH_MISSILE_FIRE); + } } @@ -3322,129 +3366,129 @@ void A_WraithMissile(mobj_t *actor) // A_WraithFX2 - spawns sparkle tail of missile // -void A_WraithFX2(mobj_t *actor) -{ - mobj_t *mo; - angle_t angle; - int i; - - for (i=0; i<2; i++) - { - mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_WRAITHFX2); - if(mo) - { - if (P_Random()<128) - { - angle = actor->angle+(P_Random()<<22); - } - else - { - angle = actor->angle-(P_Random()<<22); - } - mo->momz = 0; - mo->momx = FixedMul((P_Random()<<7)+FRACUNIT, - finecosine[angle>>ANGLETOFINESHIFT]); - mo->momy = FixedMul((P_Random()<<7)+FRACUNIT, - finesine[angle>>ANGLETOFINESHIFT]); - mo->target = actor; - mo->floorclip = 10*FRACUNIT; - } - } +void A_WraithFX2(mobj_t * actor) +{ + mobj_t *mo; + angle_t angle; + int i; + + for (i = 0; i < 2; i++) + { + mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_WRAITHFX2); + if (mo) + { + if (P_Random() < 128) + { + angle = actor->angle + (P_Random() << 22); + } + else + { + angle = actor->angle - (P_Random() << 22); + } + mo->momz = 0; + mo->momx = FixedMul((P_Random() << 7) + FRACUNIT, + finecosine[angle >> ANGLETOFINESHIFT]); + mo->momy = FixedMul((P_Random() << 7) + FRACUNIT, + finesine[angle >> ANGLETOFINESHIFT]); + mo->target = actor; + mo->floorclip = 10 * FRACUNIT; + } + } } // Spawn an FX3 around the actor during attacks -void A_WraithFX3(mobj_t *actor) +void A_WraithFX3(mobj_t * actor) { - mobj_t *mo; - int numdropped=P_Random()%15; - int i; + mobj_t *mo; + int numdropped = P_Random() % 15; + int i; - for (i=0; ix, actor->y, actor->z, MT_WRAITHFX3); - if(mo) - { - mo->x += (P_Random()-128)<<11; - mo->y += (P_Random()-128)<<11; - mo->z += (P_Random()<<10); - mo->target = actor; - } - } + for (i = 0; i < numdropped; i++) + { + mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_WRAITHFX3); + if (mo) + { + mo->x += (P_Random() - 128) << 11; + mo->y += (P_Random() - 128) << 11; + mo->z += (P_Random() << 10); + mo->target = actor; + } + } } // Spawn an FX4 during movement -void A_WraithFX4(mobj_t *actor) -{ - mobj_t *mo; - int chance = P_Random(); - int spawn4,spawn5; - - if (chance < 10) - { - spawn4 = true; - spawn5 = false; - } - else if (chance < 20) - { - spawn4 = false; - spawn5 = true; - } - else if (chance < 25) - { - spawn4 = true; - spawn5 = true; - } - else - { - spawn4 = false; - spawn5 = false; - } - - if (spawn4) - { - mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_WRAITHFX4); - if(mo) - { - mo->x += (P_Random()-128)<<12; - mo->y += (P_Random()-128)<<12; - mo->z += (P_Random()<<10); - mo->target = actor; - } - } - if (spawn5) - { - mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_WRAITHFX5); - if(mo) - { - mo->x += (P_Random()-128)<<11; - mo->y += (P_Random()-128)<<11; - mo->z += (P_Random()<<10); - mo->target = actor; - } - } -} - - -void A_WraithLook(mobj_t *actor) -{ -// A_WraithFX4(actor); // too expensive - A_Look(actor); -} - - -void A_WraithChase(mobj_t *actor) -{ - int weaveindex = actor->special1; - actor->z += FloatBobOffsets[weaveindex]; - actor->special1 = (weaveindex+2)&63; -// if (actor->floorclip > 0) -// { -// P_SetMobjState(actor, S_WRAITH_RAISE2); -// return; -// } - A_Chase(actor); - A_WraithFX4(actor); +void A_WraithFX4(mobj_t * actor) +{ + mobj_t *mo; + int chance = P_Random(); + int spawn4, spawn5; + + if (chance < 10) + { + spawn4 = true; + spawn5 = false; + } + else if (chance < 20) + { + spawn4 = false; + spawn5 = true; + } + else if (chance < 25) + { + spawn4 = true; + spawn5 = true; + } + else + { + spawn4 = false; + spawn5 = false; + } + + if (spawn4) + { + mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_WRAITHFX4); + if (mo) + { + mo->x += (P_Random() - 128) << 12; + mo->y += (P_Random() - 128) << 12; + mo->z += (P_Random() << 10); + mo->target = actor; + } + } + if (spawn5) + { + mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_WRAITHFX5); + if (mo) + { + mo->x += (P_Random() - 128) << 11; + mo->y += (P_Random() - 128) << 11; + mo->z += (P_Random() << 10); + mo->target = actor; + } + } +} + + +void A_WraithLook(mobj_t * actor) +{ +// A_WraithFX4(actor); // too expensive + A_Look(actor); +} + + +void A_WraithChase(mobj_t * actor) +{ + int weaveindex = actor->special1; + actor->z += FloatBobOffsets[weaveindex]; + actor->special1 = (weaveindex + 2) & 63; +// if (actor->floorclip > 0) +// { +// P_SetMobjState(actor, S_WRAITH_RAISE2); +// return; +// } + A_Chase(actor); + A_WraithFX4(actor); } @@ -3453,213 +3497,217 @@ void A_WraithChase(mobj_t *actor) // Ettin AI //============================================================================ -void A_EttinAttack(mobj_t *actor) +void A_EttinAttack(mobj_t * actor) { - if(P_CheckMeleeRange(actor)) - { - P_DamageMobj(actor->target, actor, actor, HITDICE(2)); - } + if (P_CheckMeleeRange(actor)) + { + P_DamageMobj(actor->target, actor, actor, HITDICE(2)); + } } -void A_DropMace(mobj_t *actor) +void A_DropMace(mobj_t * actor) { - mobj_t *mo; + mobj_t *mo; - mo = P_SpawnMobj(actor->x, actor->y, - actor->z+(actor->height>>1), MT_ETTIN_MACE); - if (mo) - { - mo->momx = (P_Random()-128)<<11; - mo->momy = (P_Random()-128)<<11; - mo->momz = FRACUNIT*10+(P_Random()<<10); - mo->target = actor; - } + mo = P_SpawnMobj(actor->x, actor->y, + actor->z + (actor->height >> 1), MT_ETTIN_MACE); + if (mo) + { + mo->momx = (P_Random() - 128) << 11; + mo->momy = (P_Random() - 128) << 11; + mo->momz = FRACUNIT * 10 + (P_Random() << 10); + mo->target = actor; + } } //============================================================================ // Fire Demon AI // -// special1 index into floatbob -// special2 whether strafing or not +// special1 index into floatbob +// special2 whether strafing or not //============================================================================ -void A_FiredSpawnRock(mobj_t *actor) +void A_FiredSpawnRock(mobj_t * actor) { - mobj_t *mo; - int x,y,z; - int rtype; + mobj_t *mo; + int x, y, z; + int rtype; - switch(P_Random()%5) - { - case 0: - rtype = MT_FIREDEMON_FX1; - break; - case 1: - rtype = MT_FIREDEMON_FX2; - break; - case 2: - rtype = MT_FIREDEMON_FX3; - break; - case 3: - rtype = MT_FIREDEMON_FX4; - break; - case 4: - rtype = MT_FIREDEMON_FX5; - break; - } + switch (P_Random() % 5) + { + case 0: + rtype = MT_FIREDEMON_FX1; + break; + case 1: + rtype = MT_FIREDEMON_FX2; + break; + case 2: + rtype = MT_FIREDEMON_FX3; + break; + case 3: + rtype = MT_FIREDEMON_FX4; + break; + case 4: + rtype = MT_FIREDEMON_FX5; + break; + } - x = actor->x + ((P_Random()-128) << 12); - y = actor->y + ((P_Random()-128) << 12); - z = actor->z + ((P_Random()) << 11); - mo = P_SpawnMobj(x,y,z,rtype); - if (mo) - { - mo->target = actor; - mo->momx = (P_Random()-128)<<10; - mo->momy = (P_Random()-128)<<10; - mo->momz = (P_Random()<<10); - mo->special1 = 2; // Number bounces - } + x = actor->x + ((P_Random() - 128) << 12); + y = actor->y + ((P_Random() - 128) << 12); + z = actor->z + ((P_Random()) << 11); + mo = P_SpawnMobj(x, y, z, rtype); + if (mo) + { + mo->target = actor; + mo->momx = (P_Random() - 128) << 10; + mo->momy = (P_Random() - 128) << 10; + mo->momz = (P_Random() << 10); + mo->special1 = 2; // Number bounces + } - // Initialize fire demon - actor->special2 = 0; - actor->flags &= ~MF_JUSTATTACKED; + // Initialize fire demon + actor->special2 = 0; + actor->flags &= ~MF_JUSTATTACKED; } -void A_FiredRocks(mobj_t *actor) +void A_FiredRocks(mobj_t * actor) { - A_FiredSpawnRock(actor); - A_FiredSpawnRock(actor); - A_FiredSpawnRock(actor); - A_FiredSpawnRock(actor); - A_FiredSpawnRock(actor); + A_FiredSpawnRock(actor); + A_FiredSpawnRock(actor); + A_FiredSpawnRock(actor); + A_FiredSpawnRock(actor); + A_FiredSpawnRock(actor); } -void A_FiredAttack(mobj_t *actor) +void A_FiredAttack(mobj_t * actor) { - mobj_t *mo; - mo = P_SpawnMissile(actor, actor->target, MT_FIREDEMON_FX6); - if (mo) S_StartSound(actor, SFX_FIRED_ATTACK); + mobj_t *mo; + mo = P_SpawnMissile(actor, actor->target, MT_FIREDEMON_FX6); + if (mo) + S_StartSound(actor, SFX_FIRED_ATTACK); } -void A_SmBounce(mobj_t *actor) +void A_SmBounce(mobj_t * actor) { - // give some more momentum (x,y,&z) - actor->z = actor->floorz + FRACUNIT; - actor->momz = (2*FRACUNIT) + (P_Random()<<10); - actor->momx = P_Random()%3<momy = P_Random()%3<z = actor->floorz + FRACUNIT; + actor->momz = (2 * FRACUNIT) + (P_Random() << 10); + actor->momx = P_Random() % 3 << FRACBITS; + actor->momy = P_Random() % 3 << FRACBITS; } #define FIREDEMON_ATTACK_RANGE 64*8*FRACUNIT -void A_FiredChase(mobj_t *actor) -{ - int weaveindex = actor->special1; - mobj_t *target = actor->target; - angle_t ang; - fixed_t dist; - - if(actor->reactiontime) actor->reactiontime--; - if(actor->threshold) actor->threshold--; - - // Float up and down - actor->z += FloatBobOffsets[weaveindex]; - actor->special1 = (weaveindex+2)&63; - - // Insure it stays above certain height - if (actor->z < actor->floorz + (64*FRACUNIT)) - { - actor->z += 2*FRACUNIT; - } - - if(!actor->target || !(actor->target->flags&MF_SHOOTABLE)) - { // Invalid target - P_LookForPlayers(actor,true); - return; - } - - // Strafe - if (actor->special2 > 0) - { - actor->special2--; - } - else - { - actor->special2 = 0; - actor->momx = actor->momy = 0; - dist = P_AproxDistance(actor->x - target->x, actor->y - target->y); - if (dist < FIREDEMON_ATTACK_RANGE) - { - if (P_Random()<30) - { - ang = R_PointToAngle2(actor->x, actor->y, target->x, target->y); - if (P_Random()<128) - ang += ANGLE_90; - else - ang -= ANGLE_90; - ang>>=ANGLETOFINESHIFT; - actor->momx = FixedMul(8*FRACUNIT, finecosine[ang]); - actor->momy = FixedMul(8*FRACUNIT, finesine[ang]); - actor->special2 = 3; // strafe time - } - } - } - - FaceMovementDirection(actor); - - // Normal movement - if (!actor->special2) - { - if (--actor->movecount<0 || !P_Move (actor)) - { - P_NewChaseDir (actor); - } - } - - // Do missile attack - if (!(actor->flags&MF_JUSTATTACKED)) - { - if (P_CheckMissileRange(actor) && (P_Random()<20)) - { - P_SetMobjState (actor, actor->info->missilestate); - actor->flags |= MF_JUSTATTACKED; - return; - } - } - else - { - actor->flags &= ~MF_JUSTATTACKED; - } - - // make active sound - if(actor->info->activesound && P_Random() < 3) - { - S_StartSound(actor, actor->info->activesound); - } -} - -void A_FiredSplotch(mobj_t *actor) -{ - mobj_t *mo; - - mo = P_SpawnMobj(actor->x,actor->y,actor->z, MT_FIREDEMON_SPLOTCH1); - if (mo) - { - mo->momx = (P_Random()-128)<<11; - mo->momy = (P_Random()-128)<<11; - mo->momz = FRACUNIT*3 + (P_Random()<<10); - } - mo = P_SpawnMobj(actor->x,actor->y,actor->z, MT_FIREDEMON_SPLOTCH2); - if (mo) - { - mo->momx = (P_Random()-128)<<11; - mo->momy = (P_Random()-128)<<11; - mo->momz = FRACUNIT*3 + (P_Random()<<10); - } +void A_FiredChase(mobj_t * actor) +{ + int weaveindex = actor->special1; + mobj_t *target = actor->target; + angle_t ang; + fixed_t dist; + + if (actor->reactiontime) + actor->reactiontime--; + if (actor->threshold) + actor->threshold--; + + // Float up and down + actor->z += FloatBobOffsets[weaveindex]; + actor->special1 = (weaveindex + 2) & 63; + + // Insure it stays above certain height + if (actor->z < actor->floorz + (64 * FRACUNIT)) + { + actor->z += 2 * FRACUNIT; + } + + if (!actor->target || !(actor->target->flags & MF_SHOOTABLE)) + { // Invalid target + P_LookForPlayers(actor, true); + return; + } + + // Strafe + if (actor->special2 > 0) + { + actor->special2--; + } + else + { + actor->special2 = 0; + actor->momx = actor->momy = 0; + dist = P_AproxDistance(actor->x - target->x, actor->y - target->y); + if (dist < FIREDEMON_ATTACK_RANGE) + { + if (P_Random() < 30) + { + ang = + R_PointToAngle2(actor->x, actor->y, target->x, target->y); + if (P_Random() < 128) + ang += ANGLE_90; + else + ang -= ANGLE_90; + ang >>= ANGLETOFINESHIFT; + actor->momx = FixedMul(8 * FRACUNIT, finecosine[ang]); + actor->momy = FixedMul(8 * FRACUNIT, finesine[ang]); + actor->special2 = 3; // strafe time + } + } + } + + FaceMovementDirection(actor); + + // Normal movement + if (!actor->special2) + { + if (--actor->movecount < 0 || !P_Move(actor)) + { + P_NewChaseDir(actor); + } + } + + // Do missile attack + if (!(actor->flags & MF_JUSTATTACKED)) + { + if (P_CheckMissileRange(actor) && (P_Random() < 20)) + { + P_SetMobjState(actor, actor->info->missilestate); + actor->flags |= MF_JUSTATTACKED; + return; + } + } + else + { + actor->flags &= ~MF_JUSTATTACKED; + } + + // make active sound + if (actor->info->activesound && P_Random() < 3) + { + S_StartSound(actor, actor->info->activesound); + } +} + +void A_FiredSplotch(mobj_t * actor) +{ + mobj_t *mo; + + mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_FIREDEMON_SPLOTCH1); + if (mo) + { + mo->momx = (P_Random() - 128) << 11; + mo->momy = (P_Random() - 128) << 11; + mo->momz = FRACUNIT * 3 + (P_Random() << 10); + } + mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_FIREDEMON_SPLOTCH2); + if (mo) + { + mo->momx = (P_Random() - 128) << 11; + mo->momy = (P_Random() - 128) << 11; + mo->momz = FRACUNIT * 3 + (P_Random() << 10); + } } @@ -3669,21 +3717,22 @@ void A_FiredSplotch(mobj_t *actor) // //============================================================================ -void A_IceGuyLook(mobj_t *actor) +void A_IceGuyLook(mobj_t * actor) { - fixed_t dist; - fixed_t an; + fixed_t dist; + fixed_t an; - A_Look(actor); - if(P_Random() < 64) - { - dist = ((P_Random()-128)*actor->radius)>>7; - an = (actor->angle+ANG90)>>ANGLETOFINESHIFT; + A_Look(actor); + if (P_Random() < 64) + { + dist = ((P_Random() - 128) * actor->radius) >> 7; + an = (actor->angle + ANG90) >> ANGLETOFINESHIFT; - P_SpawnMobj(actor->x+FixedMul(dist, finecosine[an]), - actor->y+FixedMul(dist, finesine[an]), actor->z+60*FRACUNIT, - MT_ICEGUY_WISP1+(P_Random()&1)); - } + P_SpawnMobj(actor->x + FixedMul(dist, finecosine[an]), + actor->y + FixedMul(dist, finesine[an]), + actor->z + 60 * FRACUNIT, + MT_ICEGUY_WISP1 + (P_Random() & 1)); + } } //============================================================================ @@ -3692,29 +3741,30 @@ void A_IceGuyLook(mobj_t *actor) // //============================================================================ -void A_IceGuyChase(mobj_t *actor) +void A_IceGuyChase(mobj_t * actor) { - fixed_t dist; - fixed_t an; - mobj_t *mo; + fixed_t dist; + fixed_t an; + mobj_t *mo; - A_Chase(actor); - if(P_Random() < 128) - { - dist = ((P_Random()-128)*actor->radius)>>7; - an = (actor->angle+ANG90)>>ANGLETOFINESHIFT; - - mo = P_SpawnMobj(actor->x+FixedMul(dist, finecosine[an]), - actor->y+FixedMul(dist, finesine[an]), actor->z+60*FRACUNIT, - MT_ICEGUY_WISP1+(P_Random()&1)); - if(mo) - { - mo->momx = actor->momx; - mo->momy = actor->momy; - mo->momz = actor->momz; - mo->target = actor; - } - } + A_Chase(actor); + if (P_Random() < 128) + { + dist = ((P_Random() - 128) * actor->radius) >> 7; + an = (actor->angle + ANG90) >> ANGLETOFINESHIFT; + + mo = P_SpawnMobj(actor->x + FixedMul(dist, finecosine[an]), + actor->y + FixedMul(dist, finesine[an]), + actor->z + 60 * FRACUNIT, + MT_ICEGUY_WISP1 + (P_Random() & 1)); + if (mo) + { + mo->momx = actor->momx; + mo->momy = actor->momy; + mo->momz = actor->momz; + mo->target = actor; + } + } } //============================================================================ @@ -3723,25 +3773,27 @@ void A_IceGuyChase(mobj_t *actor) // //============================================================================ -void A_IceGuyAttack(mobj_t *actor) +void A_IceGuyAttack(mobj_t * actor) { - fixed_t an; + fixed_t an; - if(!actor->target) - { - return; - } - an = (actor->angle+ANG90)>>ANGLETOFINESHIFT; - P_SpawnMissileXYZ(actor->x+FixedMul(actor->radius>>1, - finecosine[an]), actor->y+FixedMul(actor->radius>>1, - finesine[an]), actor->z+40*FRACUNIT, actor, actor->target, - MT_ICEGUY_FX); - an = (actor->angle-ANG90)>>ANGLETOFINESHIFT; - P_SpawnMissileXYZ(actor->x+FixedMul(actor->radius>>1, - finecosine[an]), actor->y+FixedMul(actor->radius>>1, - finesine[an]), actor->z+40*FRACUNIT, actor, actor->target, - MT_ICEGUY_FX); - S_StartSound(actor, actor->info->attacksound); + if (!actor->target) + { + return; + } + an = (actor->angle + ANG90) >> ANGLETOFINESHIFT; + P_SpawnMissileXYZ(actor->x + FixedMul(actor->radius >> 1, + finecosine[an]), + actor->y + FixedMul(actor->radius >> 1, finesine[an]), + actor->z + 40 * FRACUNIT, actor, actor->target, + MT_ICEGUY_FX); + an = (actor->angle - ANG90) >> ANGLETOFINESHIFT; + P_SpawnMissileXYZ(actor->x + FixedMul(actor->radius >> 1, + finecosine[an]), + actor->y + FixedMul(actor->radius >> 1, finesine[an]), + actor->z + 40 * FRACUNIT, actor, actor->target, + MT_ICEGUY_FX); + S_StartSound(actor, actor->info->attacksound); } //============================================================================ @@ -3750,10 +3802,11 @@ void A_IceGuyAttack(mobj_t *actor) // //============================================================================ -void A_IceGuyMissilePuff(mobj_t *actor) +void A_IceGuyMissilePuff(mobj_t * actor) { - mobj_t *mo; - mo = P_SpawnMobj(actor->x, actor->y, actor->z+2*FRACUNIT, MT_ICEFX_PUFF); + mobj_t *mo; + mo = P_SpawnMobj(actor->x, actor->y, actor->z + 2 * FRACUNIT, + MT_ICEFX_PUFF); } //============================================================================ @@ -3762,15 +3815,15 @@ void A_IceGuyMissilePuff(mobj_t *actor) // //============================================================================ -void A_IceGuyDie(mobj_t *actor) +void A_IceGuyDie(mobj_t * actor) { - void A_FreezeDeathChunks(mobj_t *actor); + void A_FreezeDeathChunks(mobj_t * actor); - actor->momx = 0; - actor->momy = 0; - actor->momz = 0; - actor->height <<= 2; - A_FreezeDeathChunks(actor); + actor->momx = 0; + actor->momy = 0; + actor->momz = 0; + actor->height <<= 2; + A_FreezeDeathChunks(actor); } //============================================================================ @@ -3779,19 +3832,20 @@ void A_IceGuyDie(mobj_t *actor) // //============================================================================ -void A_IceGuyMissileExplode(mobj_t *actor) +void A_IceGuyMissileExplode(mobj_t * actor) { - mobj_t *mo; - int i; + mobj_t *mo; + int i; - for(i = 0; i < 8; i++) - { - mo = P_SpawnMissileAngle(actor, MT_ICEGUY_FX2, i*ANG45, -0.3*FRACUNIT); - if(mo) - { - mo->target = actor->target; - } - } + for (i = 0; i < 8; i++) + { + mo = P_SpawnMissileAngle(actor, MT_ICEGUY_FX2, i * ANG45, + -0.3 * FRACUNIT); + if (mo) + { + mo->target = actor->target; + } + } } @@ -3804,20 +3858,20 @@ void A_IceGuyMissileExplode(mobj_t *actor) //============================================================================ // -// Sorcerer stuff +// Sorcerer stuff // // Sorcerer Variables -// special1 Angle of ball 1 (all others relative to that) -// special2 which ball to stop at in stop mode (MT_???) -// args[0] Denfense time -// args[1] Number of full rotations since stopping mode -// args[2] Target orbit speed for acceleration/deceleration -// args[3] Movement mode (see SORC_ macros) -// args[4] Current ball orbit speed -// Sorcerer Ball Variables -// special1 Previous angle of ball (for woosh) -// special2 Countdown of rapid fire (FX4) -// args[0] If set, don't play the bounce sound when bouncing +// special1 Angle of ball 1 (all others relative to that) +// special2 which ball to stop at in stop mode (MT_???) +// args[0] Denfense time +// args[1] Number of full rotations since stopping mode +// args[2] Target orbit speed for acceleration/deceleration +// args[3] Movement mode (see SORC_ macros) +// args[4] Current ball orbit speed +// Sorcerer Ball Variables +// special1 Previous angle of ball (for woosh) +// special2 Countdown of rapid fire (FX4) +// args[0] If set, don't play the bounce sound when bouncing //============================================================================ #define SORCBALL_INITIAL_SPEED 7 @@ -3826,7 +3880,7 @@ void A_IceGuyMissileExplode(mobj_t *actor) #define SORC_DEFENSE_TIME 255 #define SORC_DEFENSE_HEIGHT 45 #define BOUNCE_TIME_UNIT (35/2) -#define SORCFX4_RAPIDFIRE_TIME (6*3) // 3 seconds +#define SORCFX4_RAPIDFIRE_TIME (6*3) // 3 seconds #define SORCFX4_SPREAD_ANGLE 20 #define SORC_DECELERATE 0 @@ -3841,46 +3895,48 @@ void A_IceGuyMissileExplode(mobj_t *actor) #define BALL2_ANGLEOFFSET (ANGLE_MAX/3) #define BALL3_ANGLEOFFSET ((ANGLE_MAX/3)*2) -void A_SorcBallOrbit(mobj_t *actor); -void A_SorcSpinBalls(mobj_t *actor); -void A_SpeedBalls(mobj_t *actor); -void A_SlowBalls(mobj_t *actor); -void A_StopBalls(mobj_t *actor); -void A_AccelBalls(mobj_t *actor); -void A_DecelBalls(mobj_t *actor); -void A_SorcBossAttack(mobj_t *actor); -void A_SpawnFizzle(mobj_t *actor); -void A_CastSorcererSpell(mobj_t *actor); -void A_SorcUpdateBallAngle(mobj_t *actor); -void A_BounceCheck(mobj_t *actor); -void A_SorcFX1Seek(mobj_t *actor); -void A_SorcOffense1(mobj_t *actor); -void A_SorcOffense2(mobj_t *actor); +void A_SorcBallOrbit(mobj_t * actor); +void A_SorcSpinBalls(mobj_t * actor); +void A_SpeedBalls(mobj_t * actor); +void A_SlowBalls(mobj_t * actor); +void A_StopBalls(mobj_t * actor); +void A_AccelBalls(mobj_t * actor); +void A_DecelBalls(mobj_t * actor); +void A_SorcBossAttack(mobj_t * actor); +void A_SpawnFizzle(mobj_t * actor); +void A_CastSorcererSpell(mobj_t * actor); +void A_SorcUpdateBallAngle(mobj_t * actor); +void A_BounceCheck(mobj_t * actor); +void A_SorcFX1Seek(mobj_t * actor); +void A_SorcOffense1(mobj_t * actor); +void A_SorcOffense2(mobj_t * actor); // Spawn spinning balls above head - actor is sorcerer -void A_SorcSpinBalls(mobj_t *actor) +void A_SorcSpinBalls(mobj_t * actor) { - mobj_t *mo; - fixed_t z; - - A_SlowBalls(actor); - actor->args[0] = 0; // Currently no defense - actor->args[3] = SORC_NORMAL; - actor->args[4] = SORCBALL_INITIAL_SPEED; // Initial orbit speed - actor->special1 = ANGLE_1; - z = actor->z - actor->floorclip + actor->info->height; - - mo = P_SpawnMobj(actor->x, actor->y, z, MT_SORCBALL1); - if (mo) - { - mo->target = actor; - mo->special2 = SORCFX4_RAPIDFIRE_TIME; - } - mo = P_SpawnMobj(actor->x, actor->y, z, MT_SORCBALL2); - if (mo) mo->target = actor; - mo = P_SpawnMobj(actor->x, actor->y, z, MT_SORCBALL3); - if (mo) mo->target = actor; + mobj_t *mo; + fixed_t z; + + A_SlowBalls(actor); + actor->args[0] = 0; // Currently no defense + actor->args[3] = SORC_NORMAL; + actor->args[4] = SORCBALL_INITIAL_SPEED; // Initial orbit speed + actor->special1 = ANGLE_1; + z = actor->z - actor->floorclip + actor->info->height; + + mo = P_SpawnMobj(actor->x, actor->y, z, MT_SORCBALL1); + if (mo) + { + mo->target = actor; + mo->special2 = SORCFX4_RAPIDFIRE_TIME; + } + mo = P_SpawnMobj(actor->x, actor->y, z, MT_SORCBALL2); + if (mo) + mo->target = actor; + mo = P_SpawnMobj(actor->x, actor->y, z, MT_SORCBALL3); + if (mo) + mo->target = actor; } @@ -3888,184 +3944,185 @@ void A_SorcSpinBalls(mobj_t *actor) // A_SorcBallOrbit() ========================================== // -void A_SorcBallOrbit(mobj_t *actor) -{ - int x,y; - angle_t angle, baseangle; - int mode = actor->target->args[3]; - mobj_t *parent = (mobj_t *)actor->target; - int dist = parent->radius - (actor->radius<<1); - angle_t prevangle = actor->special1; - - if (actor->target->health <= 0) - P_SetMobjState(actor, actor->info->painstate); - - baseangle = (angle_t)parent->special1; - switch(actor->type) - { - case MT_SORCBALL1: - angle = baseangle + BALL1_ANGLEOFFSET; - break; - case MT_SORCBALL2: - angle = baseangle + BALL2_ANGLEOFFSET; - break; - case MT_SORCBALL3: - angle = baseangle + BALL3_ANGLEOFFSET; - break; - default: - I_Error("corrupted sorcerer"); - break; - } - actor->angle = angle; - angle >>= ANGLETOFINESHIFT; - - switch(mode) - { - case SORC_NORMAL: // Balls rotating normally - A_SorcUpdateBallAngle(actor); - break; - case SORC_DECELERATE: // Balls decelerating - A_DecelBalls(actor); - A_SorcUpdateBallAngle(actor); - break; - case SORC_ACCELERATE: // Balls accelerating - A_AccelBalls(actor); - A_SorcUpdateBallAngle(actor); - break; - case SORC_STOPPING: // Balls stopping - if ((parent->special2 == actor->type) && - (parent->args[1] > SORCBALL_SPEED_ROTATIONS) && - (abs(angle - (parent->angle>>ANGLETOFINESHIFT)) < (30<<5))) - { - // Can stop now - actor->target->args[3] = SORC_FIRESPELL; - actor->target->args[4] = 0; - // Set angle so ball angle == sorcerer angle - switch(actor->type) - { - case MT_SORCBALL1: - parent->special1 = (int)(parent->angle - - BALL1_ANGLEOFFSET); - break; - case MT_SORCBALL2: - parent->special1 = (int)(parent->angle - - BALL2_ANGLEOFFSET); - break; - case MT_SORCBALL3: - parent->special1 = (int)(parent->angle - - BALL3_ANGLEOFFSET); - break; - default: - break; - } - } - else - { - A_SorcUpdateBallAngle(actor); - } - break; - case SORC_FIRESPELL: // Casting spell - if (parent->special2 == actor->type) - { - // Put sorcerer into special throw spell anim - if (parent->health > 0) - P_SetMobjStateNF(parent, S_SORC_ATTACK1); - - if (actor->type==MT_SORCBALL1 && P_Random()<200) - { - S_StartSound(NULL, SFX_SORCERER_SPELLCAST); - actor->special2 = SORCFX4_RAPIDFIRE_TIME; - actor->args[4] = 128; - parent->args[3] = SORC_FIRING_SPELL; - } - else - { - A_CastSorcererSpell(actor); - parent->args[3] = SORC_STOPPED; - } - } - break; - case SORC_FIRING_SPELL: - if (parent->special2 == actor->type) - { - if (actor->special2-- <= 0) - { - // Done rapid firing - parent->args[3] = SORC_STOPPED; - // Back to orbit balls - if (parent->health > 0) - P_SetMobjStateNF(parent, S_SORC_ATTACK4); - } - else - { - // Do rapid fire spell - A_SorcOffense2(actor); - } - } - break; - case SORC_STOPPED: // Balls stopped - default: - break; - } - - if ((angle < prevangle) && (parent->args[4]==SORCBALL_TERMINAL_SPEED)) - { - parent->args[1]++; // Bump rotation counter - // Completed full rotation - make woosh sound - S_StartSound(actor, SFX_SORCERER_BALLWOOSH); - } - actor->special1 = angle; // Set previous angle - x = parent->x + FixedMul(dist, finecosine[angle]); - y = parent->y + FixedMul(dist, finesine[angle]); - actor->x = x; - actor->y = y; - actor->z = parent->z - parent->floorclip + parent->info->height; +void A_SorcBallOrbit(mobj_t * actor) +{ + int x, y; + angle_t angle, baseangle; + int mode = actor->target->args[3]; + mobj_t *parent = (mobj_t *) actor->target; + int dist = parent->radius - (actor->radius << 1); + angle_t prevangle = actor->special1; + + if (actor->target->health <= 0) + P_SetMobjState(actor, actor->info->painstate); + + baseangle = (angle_t) parent->special1; + switch (actor->type) + { + case MT_SORCBALL1: + angle = baseangle + BALL1_ANGLEOFFSET; + break; + case MT_SORCBALL2: + angle = baseangle + BALL2_ANGLEOFFSET; + break; + case MT_SORCBALL3: + angle = baseangle + BALL3_ANGLEOFFSET; + break; + default: + I_Error("corrupted sorcerer"); + break; + } + actor->angle = angle; + angle >>= ANGLETOFINESHIFT; + + switch (mode) + { + case SORC_NORMAL: // Balls rotating normally + A_SorcUpdateBallAngle(actor); + break; + case SORC_DECELERATE: // Balls decelerating + A_DecelBalls(actor); + A_SorcUpdateBallAngle(actor); + break; + case SORC_ACCELERATE: // Balls accelerating + A_AccelBalls(actor); + A_SorcUpdateBallAngle(actor); + break; + case SORC_STOPPING: // Balls stopping + if ((parent->special2 == actor->type) && + (parent->args[1] > SORCBALL_SPEED_ROTATIONS) && + (abs(angle - (parent->angle >> ANGLETOFINESHIFT)) < + (30 << 5))) + { + // Can stop now + actor->target->args[3] = SORC_FIRESPELL; + actor->target->args[4] = 0; + // Set angle so ball angle == sorcerer angle + switch (actor->type) + { + case MT_SORCBALL1: + parent->special1 = (int) (parent->angle - + BALL1_ANGLEOFFSET); + break; + case MT_SORCBALL2: + parent->special1 = (int) (parent->angle - + BALL2_ANGLEOFFSET); + break; + case MT_SORCBALL3: + parent->special1 = (int) (parent->angle - + BALL3_ANGLEOFFSET); + break; + default: + break; + } + } + else + { + A_SorcUpdateBallAngle(actor); + } + break; + case SORC_FIRESPELL: // Casting spell + if (parent->special2 == actor->type) + { + // Put sorcerer into special throw spell anim + if (parent->health > 0) + P_SetMobjStateNF(parent, S_SORC_ATTACK1); + + if (actor->type == MT_SORCBALL1 && P_Random() < 200) + { + S_StartSound(NULL, SFX_SORCERER_SPELLCAST); + actor->special2 = SORCFX4_RAPIDFIRE_TIME; + actor->args[4] = 128; + parent->args[3] = SORC_FIRING_SPELL; + } + else + { + A_CastSorcererSpell(actor); + parent->args[3] = SORC_STOPPED; + } + } + break; + case SORC_FIRING_SPELL: + if (parent->special2 == actor->type) + { + if (actor->special2-- <= 0) + { + // Done rapid firing + parent->args[3] = SORC_STOPPED; + // Back to orbit balls + if (parent->health > 0) + P_SetMobjStateNF(parent, S_SORC_ATTACK4); + } + else + { + // Do rapid fire spell + A_SorcOffense2(actor); + } + } + break; + case SORC_STOPPED: // Balls stopped + default: + break; + } + + if ((angle < prevangle) && (parent->args[4] == SORCBALL_TERMINAL_SPEED)) + { + parent->args[1]++; // Bump rotation counter + // Completed full rotation - make woosh sound + S_StartSound(actor, SFX_SORCERER_BALLWOOSH); + } + actor->special1 = angle; // Set previous angle + x = parent->x + FixedMul(dist, finecosine[angle]); + y = parent->y + FixedMul(dist, finesine[angle]); + actor->x = x; + actor->y = y; + actor->z = parent->z - parent->floorclip + parent->info->height; } // // Set balls to speed mode - actor is sorcerer // -void A_SpeedBalls(mobj_t *actor) +void A_SpeedBalls(mobj_t * actor) { - actor->args[3] = SORC_ACCELERATE; // speed mode - actor->args[2] = SORCBALL_TERMINAL_SPEED; // target speed + actor->args[3] = SORC_ACCELERATE; // speed mode + actor->args[2] = SORCBALL_TERMINAL_SPEED; // target speed } // // Set balls to slow mode - actor is sorcerer // -void A_SlowBalls(mobj_t *actor) +void A_SlowBalls(mobj_t * actor) { - actor->args[3] = SORC_DECELERATE; // slow mode - actor->args[2] = SORCBALL_INITIAL_SPEED; // target speed + actor->args[3] = SORC_DECELERATE; // slow mode + actor->args[2] = SORCBALL_INITIAL_SPEED; // target speed } // // Instant stop when rotation gets to ball in special2 -// actor is sorcerer +// actor is sorcerer // -void A_StopBalls(mobj_t *actor) +void A_StopBalls(mobj_t * actor) { - int chance = P_Random(); - actor->args[3] = SORC_STOPPING; // stopping mode - actor->args[1] = 0; // Reset rotation counter + int chance = P_Random(); + actor->args[3] = SORC_STOPPING; // stopping mode + actor->args[1] = 0; // Reset rotation counter - if ((actor->args[0] <= 0) && (chance < 200)) - { - actor->special2 = MT_SORCBALL2; // Blue - } - else if((actor->health < (actor->info->spawnhealth >> 1)) && - (chance < 200)) - { - actor->special2 = MT_SORCBALL3; // Green - } - else - { - actor->special2 = MT_SORCBALL1; // Yellow - } + if ((actor->args[0] <= 0) && (chance < 200)) + { + actor->special2 = MT_SORCBALL2; // Blue + } + else if ((actor->health < (actor->info->spawnhealth >> 1)) && + (chance < 200)) + { + actor->special2 = MT_SORCBALL3; // Green + } + else + { + actor->special2 = MT_SORCBALL1; // Yellow + } } @@ -4074,100 +4131,108 @@ void A_StopBalls(mobj_t *actor) // // Increase ball orbit speed - actor is ball // -void A_AccelBalls(mobj_t *actor) +void A_AccelBalls(mobj_t * actor) { - mobj_t *sorc = actor->target; + mobj_t *sorc = actor->target; - if (sorc->args[4] < sorc->args[2]) - { - sorc->args[4]++; - } - else - { - sorc->args[3] = SORC_NORMAL; - if (sorc->args[4] >= SORCBALL_TERMINAL_SPEED) - { - // Reached terminal velocity - stop balls - A_StopBalls(sorc); - } - } + if (sorc->args[4] < sorc->args[2]) + { + sorc->args[4]++; + } + else + { + sorc->args[3] = SORC_NORMAL; + if (sorc->args[4] >= SORCBALL_TERMINAL_SPEED) + { + // Reached terminal velocity - stop balls + A_StopBalls(sorc); + } + } } // Decrease ball orbit speed - actor is ball -void A_DecelBalls(mobj_t *actor) +void A_DecelBalls(mobj_t * actor) { - mobj_t *sorc = actor->target; + mobj_t *sorc = actor->target; - if (sorc->args[4] > sorc->args[2]) - { - sorc->args[4]--; - } - else - { - sorc->args[3] = SORC_NORMAL; - } + if (sorc->args[4] > sorc->args[2]) + { + sorc->args[4]--; + } + else + { + sorc->args[3] = SORC_NORMAL; + } } // Update angle if first ball - actor is ball -void A_SorcUpdateBallAngle(mobj_t *actor) +void A_SorcUpdateBallAngle(mobj_t * actor) { - if (actor->type == MT_SORCBALL1) - { - actor->target->special1 += ANGLE_1*actor->target->args[4]; - } + if (actor->type == MT_SORCBALL1) + { + actor->target->special1 += ANGLE_1 * actor->target->args[4]; + } } // actor is ball -void A_CastSorcererSpell(mobj_t *actor) -{ - mobj_t *mo; - int spell = actor->type; - angle_t ang1,ang2; - fixed_t z; - mobj_t *parent = actor->target; - - S_StartSound(NULL, SFX_SORCERER_SPELLCAST); - - // Put sorcerer into throw spell animation - if (parent->health > 0) P_SetMobjStateNF(parent, S_SORC_ATTACK4); - - switch(spell) - { - case MT_SORCBALL1: // Offensive - A_SorcOffense1(actor); - break; - case MT_SORCBALL2: // Defensive - z = parent->z - parent->floorclip + - SORC_DEFENSE_HEIGHT*FRACUNIT; - mo = P_SpawnMobj(actor->x, actor->y, z, MT_SORCFX2); - parent->flags2 |= MF2_REFLECTIVE|MF2_INVULNERABLE; - parent->args[0] = SORC_DEFENSE_TIME; - if (mo) mo->target = parent; - break; - case MT_SORCBALL3: // Reinforcements - ang1 = actor->angle - ANGLE_45; - ang2 = actor->angle + ANGLE_45; - if(actor->health < (actor->info->spawnhealth/3)) - { // Spawn 2 at a time - mo = P_SpawnMissileAngle(parent, MT_SORCFX3, ang1, 4*FRACUNIT); - if (mo) mo->target = parent; - mo = P_SpawnMissileAngle(parent, MT_SORCFX3, ang2, 4*FRACUNIT); - if (mo) mo->target = parent; - } - else - { - if (P_Random() < 128) - ang1 = ang2; - mo = P_SpawnMissileAngle(parent, MT_SORCFX3, ang1, 4*FRACUNIT); - if (mo) mo->target = parent; - } - break; - default: - break; - } +void A_CastSorcererSpell(mobj_t * actor) +{ + mobj_t *mo; + int spell = actor->type; + angle_t ang1, ang2; + fixed_t z; + mobj_t *parent = actor->target; + + S_StartSound(NULL, SFX_SORCERER_SPELLCAST); + + // Put sorcerer into throw spell animation + if (parent->health > 0) + P_SetMobjStateNF(parent, S_SORC_ATTACK4); + + switch (spell) + { + case MT_SORCBALL1: // Offensive + A_SorcOffense1(actor); + break; + case MT_SORCBALL2: // Defensive + z = parent->z - parent->floorclip + + SORC_DEFENSE_HEIGHT * FRACUNIT; + mo = P_SpawnMobj(actor->x, actor->y, z, MT_SORCFX2); + parent->flags2 |= MF2_REFLECTIVE | MF2_INVULNERABLE; + parent->args[0] = SORC_DEFENSE_TIME; + if (mo) + mo->target = parent; + break; + case MT_SORCBALL3: // Reinforcements + ang1 = actor->angle - ANGLE_45; + ang2 = actor->angle + ANGLE_45; + if (actor->health < (actor->info->spawnhealth / 3)) + { // Spawn 2 at a time + mo = P_SpawnMissileAngle(parent, MT_SORCFX3, ang1, + 4 * FRACUNIT); + if (mo) + mo->target = parent; + mo = P_SpawnMissileAngle(parent, MT_SORCFX3, ang2, + 4 * FRACUNIT); + if (mo) + mo->target = parent; + } + else + { + if (P_Random() < 128) + ang1 = ang2; + mo = P_SpawnMissileAngle(parent, MT_SORCFX3, ang1, + 4 * FRACUNIT); + if (mo) + mo->target = parent; + } + break; + default: + break; + } } /* @@ -4184,93 +4249,94 @@ void A_SpawnReinforcements(mobj_t *actor) */ // actor is ball -void A_SorcOffense1(mobj_t *actor) -{ - mobj_t *mo; - angle_t ang1,ang2; - mobj_t *parent=(mobj_t *)actor->target; - - ang1 = actor->angle + ANGLE_1*70; - ang2 = actor->angle - ANGLE_1*70; - mo = P_SpawnMissileAngle(parent, MT_SORCFX1, ang1, 0); - if (mo) - { - mo->target = parent; - mo->special1 = (int)parent->target; - mo->args[4] = BOUNCE_TIME_UNIT; - mo->args[3] = 15; // Bounce time in seconds - } - mo = P_SpawnMissileAngle(parent, MT_SORCFX1, ang2, 0); - if (mo) - { - mo->target = parent; - mo->special1 = (int)parent->target; - mo->args[4] = BOUNCE_TIME_UNIT; - mo->args[3] = 15; // Bounce time in seconds - } +void A_SorcOffense1(mobj_t * actor) +{ + mobj_t *mo; + angle_t ang1, ang2; + mobj_t *parent = (mobj_t *) actor->target; + + ang1 = actor->angle + ANGLE_1 * 70; + ang2 = actor->angle - ANGLE_1 * 70; + mo = P_SpawnMissileAngle(parent, MT_SORCFX1, ang1, 0); + if (mo) + { + mo->target = parent; + mo->special1 = (int) parent->target; + mo->args[4] = BOUNCE_TIME_UNIT; + mo->args[3] = 15; // Bounce time in seconds + } + mo = P_SpawnMissileAngle(parent, MT_SORCFX1, ang2, 0); + if (mo) + { + mo->target = parent; + mo->special1 = (int) parent->target; + mo->args[4] = BOUNCE_TIME_UNIT; + mo->args[3] = 15; // Bounce time in seconds + } } // Actor is ball -void A_SorcOffense2(mobj_t *actor) -{ - angle_t ang1; - mobj_t *mo; - int delta, index; - mobj_t *parent = actor->target; - mobj_t *dest = parent->target; - int dist; - - index = actor->args[4] << 5; - actor->args[4] += 15; - delta = (finesine[index])*SORCFX4_SPREAD_ANGLE; - delta = (delta>>FRACBITS)*ANGLE_1; - ang1 = actor->angle + delta; - mo = P_SpawnMissileAngle(parent, MT_SORCFX4, ang1, 0); - if (mo) - { - mo->special2 = 35*5/2; // 5 seconds - dist = P_AproxDistance(dest->x - mo->x, dest->y - mo->y); - dist = dist/mo->info->speed; - if(dist < 1) dist = 1; - mo->momz = (dest->z-mo->z)/dist; - } +void A_SorcOffense2(mobj_t * actor) +{ + angle_t ang1; + mobj_t *mo; + int delta, index; + mobj_t *parent = actor->target; + mobj_t *dest = parent->target; + int dist; + + index = actor->args[4] << 5; + actor->args[4] += 15; + delta = (finesine[index]) * SORCFX4_SPREAD_ANGLE; + delta = (delta >> FRACBITS) * ANGLE_1; + ang1 = actor->angle + delta; + mo = P_SpawnMissileAngle(parent, MT_SORCFX4, ang1, 0); + if (mo) + { + mo->special2 = 35 * 5 / 2; // 5 seconds + dist = P_AproxDistance(dest->x - mo->x, dest->y - mo->y); + dist = dist / mo->info->speed; + if (dist < 1) + dist = 1; + mo->momz = (dest->z - mo->z) / dist; + } } // Resume ball spinning -void A_SorcBossAttack(mobj_t *actor) +void A_SorcBossAttack(mobj_t * actor) { - actor->args[3] = SORC_ACCELERATE; - actor->args[2] = SORCBALL_INITIAL_SPEED; + actor->args[3] = SORC_ACCELERATE; + actor->args[2] = SORCBALL_INITIAL_SPEED; } // spell cast magic fizzle -void A_SpawnFizzle(mobj_t *actor) -{ - fixed_t x,y,z; - fixed_t dist = 5*FRACUNIT; - angle_t angle = actor->angle >> ANGLETOFINESHIFT; - fixed_t speed = actor->info->speed; - angle_t rangle; - mobj_t *mo; - int ix; - - x = actor->x + FixedMul(dist,finecosine[angle]); - y = actor->y + FixedMul(dist,finesine[angle]); - z = actor->z - actor->floorclip + (actor->height>>1); - for (ix=0; ix<5; ix++) - { - mo = P_SpawnMobj(x,y,z,MT_SORCSPARK1); - if (mo) - { - rangle = angle + ((P_Random()%5) << 1); - mo->momx = FixedMul(P_Random()%speed,finecosine[rangle]); - mo->momy = FixedMul(P_Random()%speed,finesine[rangle]); - mo->momz = FRACUNIT*2; - } - } +void A_SpawnFizzle(mobj_t * actor) +{ + fixed_t x, y, z; + fixed_t dist = 5 * FRACUNIT; + angle_t angle = actor->angle >> ANGLETOFINESHIFT; + fixed_t speed = actor->info->speed; + angle_t rangle; + mobj_t *mo; + int ix; + + x = actor->x + FixedMul(dist, finecosine[angle]); + y = actor->y + FixedMul(dist, finesine[angle]); + z = actor->z - actor->floorclip + (actor->height >> 1); + for (ix = 0; ix < 5; ix++) + { + mo = P_SpawnMobj(x, y, z, MT_SORCSPARK1); + if (mo) + { + rangle = angle + ((P_Random() % 5) << 1); + mo->momx = FixedMul(P_Random() % speed, finecosine[rangle]); + mo->momy = FixedMul(P_Random() % speed, finesine[rangle]); + mo->momz = FRACUNIT * 2; + } + } } @@ -4278,10 +4344,10 @@ void A_SpawnFizzle(mobj_t *actor) // Yellow spell - offense //============================================================================ -void A_SorcFX1Seek(mobj_t *actor) +void A_SorcFX1Seek(mobj_t * actor) { - A_BounceCheck(actor); - P_SeekerMissile(actor,ANGLE_1*2,ANGLE_1*6); + A_BounceCheck(actor); + P_SeekerMissile(actor, ANGLE_1 * 2, ANGLE_1 * 6); } @@ -4290,88 +4356,88 @@ void A_SorcFX1Seek(mobj_t *actor) //============================================================================ // // FX2 Variables -// special1 current angle -// special2 -// args[0] 0 = CW, 1 = CCW -// args[1] +// special1 current angle +// special2 +// args[0] 0 = CW, 1 = CCW +// args[1] //============================================================================ // Split ball in two -void A_SorcFX2Split(mobj_t *actor) -{ - mobj_t *mo; - - mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_SORCFX2); - if (mo) - { - mo->target = actor->target; - mo->args[0] = 0; // CW - mo->special1 = actor->angle; // Set angle - P_SetMobjStateNF(mo, S_SORCFX2_ORBIT1); - } - mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_SORCFX2); - if (mo) - { - mo->target = actor->target; - mo->args[0] = 1; // CCW - mo->special1 = actor->angle; // Set angle - P_SetMobjStateNF(mo, S_SORCFX2_ORBIT1); - } - P_SetMobjStateNF(actor, S_NULL); +void A_SorcFX2Split(mobj_t * actor) +{ + mobj_t *mo; + + mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_SORCFX2); + if (mo) + { + mo->target = actor->target; + mo->args[0] = 0; // CW + mo->special1 = actor->angle; // Set angle + P_SetMobjStateNF(mo, S_SORCFX2_ORBIT1); + } + mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_SORCFX2); + if (mo) + { + mo->target = actor->target; + mo->args[0] = 1; // CCW + mo->special1 = actor->angle; // Set angle + P_SetMobjStateNF(mo, S_SORCFX2_ORBIT1); + } + P_SetMobjStateNF(actor, S_NULL); } // Orbit FX2 about sorcerer -void A_SorcFX2Orbit(mobj_t *actor) -{ - angle_t angle; - fixed_t x,y,z; - mobj_t *parent = actor->target; - fixed_t dist = parent->info->radius; - - if ((parent->health <= 0) || // Sorcerer is dead - (!parent->args[0])) // Time expired - { - P_SetMobjStateNF(actor, actor->info->deathstate); - parent->args[0] = 0; - parent->flags2 &= ~MF2_REFLECTIVE; - parent->flags2 &= ~MF2_INVULNERABLE; - } - - if (actor->args[0] && (parent->args[0]-- <= 0)) // Time expired - { - P_SetMobjStateNF(actor, actor->info->deathstate); - parent->args[0] = 0; - parent->flags2 &= ~MF2_REFLECTIVE; - } - - // Move to new position based on angle - if (actor->args[0]) // Counter clock-wise - { - actor->special1 += ANGLE_1*10; - angle = ((angle_t)actor->special1) >> ANGLETOFINESHIFT; - x = parent->x + FixedMul(dist, finecosine[angle]); - y = parent->y + FixedMul(dist, finesine[angle]); - z = parent->z - parent->floorclip + SORC_DEFENSE_HEIGHT*FRACUNIT; - z += FixedMul(15*FRACUNIT,finecosine[angle]); - // Spawn trailer - P_SpawnMobj(x,y,z, MT_SORCFX2_T1); - } - else // Clock wise - { - actor->special1 -= ANGLE_1*10; - angle = ((angle_t)actor->special1) >> ANGLETOFINESHIFT; - x = parent->x + FixedMul(dist, finecosine[angle]); - y = parent->y + FixedMul(dist, finesine[angle]); - z = parent->z - parent->floorclip + SORC_DEFENSE_HEIGHT*FRACUNIT; - z += FixedMul(20*FRACUNIT,finesine[angle]); - // Spawn trailer - P_SpawnMobj(x,y,z, MT_SORCFX2_T1); - } - - actor->x = x; - actor->y = y; - actor->z = z; +void A_SorcFX2Orbit(mobj_t * actor) +{ + angle_t angle; + fixed_t x, y, z; + mobj_t *parent = actor->target; + fixed_t dist = parent->info->radius; + + if ((parent->health <= 0) || // Sorcerer is dead + (!parent->args[0])) // Time expired + { + P_SetMobjStateNF(actor, actor->info->deathstate); + parent->args[0] = 0; + parent->flags2 &= ~MF2_REFLECTIVE; + parent->flags2 &= ~MF2_INVULNERABLE; + } + + if (actor->args[0] && (parent->args[0]-- <= 0)) // Time expired + { + P_SetMobjStateNF(actor, actor->info->deathstate); + parent->args[0] = 0; + parent->flags2 &= ~MF2_REFLECTIVE; + } + + // Move to new position based on angle + if (actor->args[0]) // Counter clock-wise + { + actor->special1 += ANGLE_1 * 10; + angle = ((angle_t) actor->special1) >> ANGLETOFINESHIFT; + x = parent->x + FixedMul(dist, finecosine[angle]); + y = parent->y + FixedMul(dist, finesine[angle]); + z = parent->z - parent->floorclip + SORC_DEFENSE_HEIGHT * FRACUNIT; + z += FixedMul(15 * FRACUNIT, finecosine[angle]); + // Spawn trailer + P_SpawnMobj(x, y, z, MT_SORCFX2_T1); + } + else // Clock wise + { + actor->special1 -= ANGLE_1 * 10; + angle = ((angle_t) actor->special1) >> ANGLETOFINESHIFT; + x = parent->x + FixedMul(dist, finecosine[angle]); + y = parent->y + FixedMul(dist, finesine[angle]); + z = parent->z - parent->floorclip + SORC_DEFENSE_HEIGHT * FRACUNIT; + z += FixedMul(20 * FRACUNIT, finesine[angle]); + // Spawn trailer + P_SpawnMobj(x, y, z, MT_SORCFX2_T1); + } + + actor->x = x; + actor->y = y; + actor->z = z; } @@ -4380,18 +4446,18 @@ void A_SorcFX2Orbit(mobj_t *actor) // Green spell - spawn bishops //============================================================================ -void A_SpawnBishop(mobj_t *actor) +void A_SpawnBishop(mobj_t * actor) { - mobj_t *mo; - mo=P_SpawnMobj(actor->x, actor->y, actor->z, MT_BISHOP); - if(mo) - { - if(!P_TestMobjLocation(mo)) - { - P_SetMobjState(mo, S_NULL); - } - } - P_SetMobjState(actor, S_NULL); + mobj_t *mo; + mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_BISHOP); + if (mo) + { + if (!P_TestMobjLocation(mo)) + { + P_SetMobjState(mo, S_NULL); + } + } + P_SetMobjState(actor, S_NULL); } /* @@ -4401,15 +4467,15 @@ void A_SmokePuffEntry(mobj_t *actor) } */ -void A_SmokePuffExit(mobj_t *actor) +void A_SmokePuffExit(mobj_t * actor) { - P_SpawnMobj(actor->x, actor->y, actor->z, MT_MNTRSMOKEEXIT); + P_SpawnMobj(actor->x, actor->y, actor->z, MT_MNTRSMOKEEXIT); } -void A_SorcererBishopEntry(mobj_t *actor) +void A_SorcererBishopEntry(mobj_t * actor) { - P_SpawnMobj(actor->x, actor->y, actor->z, MT_SORCFX3_EXPLOSION); - S_StartSound(actor, actor->info->seesound); + P_SpawnMobj(actor->x, actor->y, actor->z, MT_SORCFX3_EXPLOSION); + S_StartSound(actor, actor->info->seesound); } @@ -4417,59 +4483,59 @@ void A_SorcererBishopEntry(mobj_t *actor) // FX4 - rapid fire balls //============================================================================ -void A_SorcFX4Check(mobj_t *actor) +void A_SorcFX4Check(mobj_t * actor) { - if (actor->special2-- <= 0) - { - P_SetMobjStateNF(actor, actor->info->deathstate); - } + if (actor->special2-- <= 0) + { + P_SetMobjStateNF(actor, actor->info->deathstate); + } } //============================================================================ // Ball death - spawn stuff //============================================================================ -void A_SorcBallPop(mobj_t *actor) +void A_SorcBallPop(mobj_t * actor) { - S_StartSound(NULL, SFX_SORCERER_BALLPOP); - actor->flags &= ~MF_NOGRAVITY; - actor->flags2 |= MF2_LOGRAV; - actor->momx = ((P_Random()%10)-5) << FRACBITS; - actor->momy = ((P_Random()%10)-5) << FRACBITS; - actor->momz = (2+(P_Random()%3)) << FRACBITS; - actor->special2 = 4*FRACUNIT; // Initial bounce factor - actor->args[4] = BOUNCE_TIME_UNIT; // Bounce time unit - actor->args[3] = 5; // Bounce time in seconds + S_StartSound(NULL, SFX_SORCERER_BALLPOP); + actor->flags &= ~MF_NOGRAVITY; + actor->flags2 |= MF2_LOGRAV; + actor->momx = ((P_Random() % 10) - 5) << FRACBITS; + actor->momy = ((P_Random() % 10) - 5) << FRACBITS; + actor->momz = (2 + (P_Random() % 3)) << FRACBITS; + actor->special2 = 4 * FRACUNIT; // Initial bounce factor + actor->args[4] = BOUNCE_TIME_UNIT; // Bounce time unit + actor->args[3] = 5; // Bounce time in seconds } -void A_BounceCheck(mobj_t *actor) +void A_BounceCheck(mobj_t * actor) { - if (actor->args[4]-- <= 0) - { - if (actor->args[3]-- <= 0) - { - P_SetMobjState(actor, actor->info->deathstate); - switch(actor->type) - { - case MT_SORCBALL1: - case MT_SORCBALL2: - case MT_SORCBALL3: - S_StartSound(NULL, SFX_SORCERER_BIGBALLEXPLODE); - break; - case MT_SORCFX1: - S_StartSound(NULL, SFX_SORCERER_HEADSCREAM); - break; - default: - break; - } - } - else - { - actor->args[4] = BOUNCE_TIME_UNIT; - } - } + if (actor->args[4]-- <= 0) + { + if (actor->args[3]-- <= 0) + { + P_SetMobjState(actor, actor->info->deathstate); + switch (actor->type) + { + case MT_SORCBALL1: + case MT_SORCBALL2: + case MT_SORCBALL3: + S_StartSound(NULL, SFX_SORCERER_BIGBALLEXPLODE); + break; + case MT_SORCFX1: + S_StartSound(NULL, SFX_SORCERER_HEADSCREAM); + break; + default: + break; + } + } + else + { + actor->args[4] = BOUNCE_TIME_UNIT; + } + } } @@ -4480,175 +4546,177 @@ void A_BounceCheck(mobj_t *actor) //============================================================================ #define CLASS_BOSS_STRAFE_RANGE 64*10*FRACUNIT -void A_FastChase(mobj_t *actor) +void A_FastChase(mobj_t * actor) { - int delta; - fixed_t dist; - angle_t ang; - mobj_t *target; + int delta; + fixed_t dist; + angle_t ang; + mobj_t *target; - if(actor->reactiontime) - { - actor->reactiontime--; - } + if (actor->reactiontime) + { + actor->reactiontime--; + } - // Modify target threshold - if(actor->threshold) - { - actor->threshold--; - } + // Modify target threshold + if (actor->threshold) + { + actor->threshold--; + } - if(gameskill == sk_nightmare) - { // Monsters move faster in nightmare mode - actor->tics -= actor->tics/2; - if(actor->tics < 3) - { - actor->tics = 3; - } - } + if (gameskill == sk_nightmare) + { // Monsters move faster in nightmare mode + actor->tics -= actor->tics / 2; + if (actor->tics < 3) + { + actor->tics = 3; + } + } // // turn towards movement direction if not there yet // - if(actor->movedir < 8) - { - actor->angle &= (7<<29); - delta = actor->angle-(actor->movedir << 29); - if(delta > 0) - { - actor->angle -= ANG90/2; - } - else if(delta < 0) - { - actor->angle += ANG90/2; - } - } - - if(!actor->target || !(actor->target->flags&MF_SHOOTABLE)) - { // look for a new target - if(P_LookForPlayers(actor, true)) - { // got a new target - return; - } - P_SetMobjState(actor, actor->info->spawnstate); - return; - } + if (actor->movedir < 8) + { + actor->angle &= (7 << 29); + delta = actor->angle - (actor->movedir << 29); + if (delta > 0) + { + actor->angle -= ANG90 / 2; + } + else if (delta < 0) + { + actor->angle += ANG90 / 2; + } + } + + if (!actor->target || !(actor->target->flags & MF_SHOOTABLE)) + { // look for a new target + if (P_LookForPlayers(actor, true)) + { // got a new target + return; + } + P_SetMobjState(actor, actor->info->spawnstate); + return; + } // // don't attack twice in a row // - if(actor->flags & MF_JUSTATTACKED) - { - actor->flags &= ~MF_JUSTATTACKED; - if (gameskill != sk_nightmare) - P_NewChaseDir (actor); - return; - } - - // Strafe - if (actor->special2 > 0) - { - actor->special2--; - } - else - { - target = actor->target; - actor->special2 = 0; - actor->momx = actor->momy = 0; - dist=P_AproxDistance(actor->x - target->x, - actor->y - target->y); - if (dist < CLASS_BOSS_STRAFE_RANGE) - { - if (P_Random()<100) - { - ang = R_PointToAngle2(actor->x, actor->y, - target->x, target->y); - if (P_Random()<128) - ang += ANGLE_90; - else - ang -= ANGLE_90; - ang>>=ANGLETOFINESHIFT; - actor->momx = FixedMul(13*FRACUNIT, finecosine[ang]); - actor->momy = FixedMul(13*FRACUNIT, finesine[ang]); - actor->special2 = 3; // strafe time - } - } - } + if (actor->flags & MF_JUSTATTACKED) + { + actor->flags &= ~MF_JUSTATTACKED; + if (gameskill != sk_nightmare) + P_NewChaseDir(actor); + return; + } + + // Strafe + if (actor->special2 > 0) + { + actor->special2--; + } + else + { + target = actor->target; + actor->special2 = 0; + actor->momx = actor->momy = 0; + dist = P_AproxDistance(actor->x - target->x, actor->y - target->y); + if (dist < CLASS_BOSS_STRAFE_RANGE) + { + if (P_Random() < 100) + { + ang = R_PointToAngle2(actor->x, actor->y, + target->x, target->y); + if (P_Random() < 128) + ang += ANGLE_90; + else + ang -= ANGLE_90; + ang >>= ANGLETOFINESHIFT; + actor->momx = FixedMul(13 * FRACUNIT, finecosine[ang]); + actor->momy = FixedMul(13 * FRACUNIT, finesine[ang]); + actor->special2 = 3; // strafe time + } + } + } // // check for missile attack // - if (actor->info->missilestate) - { - if (gameskill < sk_nightmare && actor->movecount) - goto nomissile; - if (!P_CheckMissileRange (actor)) - goto nomissile; - P_SetMobjState (actor, actor->info->missilestate); - actor->flags |= MF_JUSTATTACKED; - return; - } -nomissile: + if (actor->info->missilestate) + { + if (gameskill < sk_nightmare && actor->movecount) + goto nomissile; + if (!P_CheckMissileRange(actor)) + goto nomissile; + P_SetMobjState(actor, actor->info->missilestate); + actor->flags |= MF_JUSTATTACKED; + return; + } + nomissile: // // possibly choose another target // - if (netgame && !actor->threshold && !P_CheckSight (actor, actor->target) ) - { - if (P_LookForPlayers(actor,true)) - return; // got a new target - } + if (netgame && !actor->threshold && !P_CheckSight(actor, actor->target)) + { + if (P_LookForPlayers(actor, true)) + return; // got a new target + } // // chase towards player // - if (!actor->special2) - { - if (--actor->movecount<0 || !P_Move (actor)) - { - P_NewChaseDir (actor); - } - } + if (!actor->special2) + { + if (--actor->movecount < 0 || !P_Move(actor)) + { + P_NewChaseDir(actor); + } + } } -void A_FighterAttack(mobj_t *actor) +void A_FighterAttack(mobj_t * actor) { - extern void A_FSwordAttack2(mobj_t *actor); + extern void A_FSwordAttack2(mobj_t * actor); - if(!actor->target) return; - A_FSwordAttack2(actor); + if (!actor->target) + return; + A_FSwordAttack2(actor); } -void A_ClericAttack(mobj_t *actor) +void A_ClericAttack(mobj_t * actor) { - extern void A_CHolyAttack3(mobj_t *actor); + extern void A_CHolyAttack3(mobj_t * actor); - if(!actor->target) return; - A_CHolyAttack3(actor); + if (!actor->target) + return; + A_CHolyAttack3(actor); } -void A_MageAttack(mobj_t *actor) +void A_MageAttack(mobj_t * actor) { - extern void A_MStaffAttack2(mobj_t *actor); + extern void A_MStaffAttack2(mobj_t * actor); - if(!actor->target) return; - A_MStaffAttack2(actor); + if (!actor->target) + return; + A_MStaffAttack2(actor); } -void A_ClassBossHealth(mobj_t *actor) +void A_ClassBossHealth(mobj_t * actor) { - if (netgame && !deathmatch) // co-op only - { - if (!actor->special1) - { - actor->health *= 5; - actor->special1 = true; // has been initialized - } - } + if (netgame && !deathmatch) // co-op only + { + if (!actor->special1) + { + actor->health *= 5; + actor->special1 = true; // has been initialized + } + } } @@ -4658,14 +4726,14 @@ void A_ClassBossHealth(mobj_t *actor) // //=========================================================================== -void A_CheckFloor(mobj_t *actor) +void A_CheckFloor(mobj_t * actor) { - if(actor->z <= actor->floorz) - { - actor->z = actor->floorz; - actor->flags2 &= ~MF2_LOGRAV; - P_SetMobjState(actor, actor->info->deathstate); - } + if (actor->z <= actor->floorz) + { + actor->z = actor->floorz; + actor->flags2 &= ~MF2_LOGRAV; + P_SetMobjState(actor, actor->info->deathstate); + } } //============================================================================ @@ -4674,28 +4742,28 @@ void A_CheckFloor(mobj_t *actor) // //============================================================================ -void A_FreezeDeath(mobj_t *actor) +void A_FreezeDeath(mobj_t * actor) { - actor->tics = 75+P_Random()+P_Random(); - actor->flags |= MF_SOLID|MF_SHOOTABLE|MF_NOBLOOD; - actor->flags2 |= MF2_PUSHABLE|MF2_TELESTOMP|MF2_PASSMOBJ|MF2_SLIDE; - actor->height <<= 2; - S_StartSound(actor, SFX_FREEZE_DEATH); + actor->tics = 75 + P_Random() + P_Random(); + actor->flags |= MF_SOLID | MF_SHOOTABLE | MF_NOBLOOD; + actor->flags2 |= MF2_PUSHABLE | MF2_TELESTOMP | MF2_PASSMOBJ | MF2_SLIDE; + actor->height <<= 2; + S_StartSound(actor, SFX_FREEZE_DEATH); - if(actor->player) - { - actor->player->damagecount = 0; - actor->player->poisoncount = 0; - actor->player->bonuscount = 0; - if(actor->player == &players[consoleplayer]) - { - SB_PaletteFlash(false); - } - } - else if(actor->flags&MF_COUNTKILL && actor->special) - { // Initiate monster death actions - P_ExecuteLineSpecial(actor->special, actor->args, NULL, 0, actor); - } + if (actor->player) + { + actor->player->damagecount = 0; + actor->player->poisoncount = 0; + actor->player->bonuscount = 0; + if (actor->player == &players[consoleplayer]) + { + SB_PaletteFlash(false); + } + } + else if (actor->flags & MF_COUNTKILL && actor->special) + { // Initiate monster death actions + P_ExecuteLineSpecial(actor->special, actor->args, NULL, 0, actor); + } } //============================================================================ @@ -4704,20 +4772,20 @@ void A_FreezeDeath(mobj_t *actor) // //============================================================================ -void A_IceSetTics(mobj_t *actor) +void A_IceSetTics(mobj_t * actor) { - int floor; + int floor; - actor->tics = 70+(P_Random()&63); - floor = P_GetThingFloorType(actor); - if(floor == FLOOR_LAVA) - { - actor->tics >>= 2; - } - else if(floor == FLOOR_ICE) - { - actor->tics <<= 1; - } + actor->tics = 70 + (P_Random() & 63); + floor = P_GetThingFloorType(actor); + if (floor == FLOOR_LAVA) + { + actor->tics >>= 2; + } + else if (floor == FLOOR_ICE) + { + actor->tics <<= 1; + } } //============================================================================ @@ -4726,12 +4794,12 @@ void A_IceSetTics(mobj_t *actor) // //============================================================================ -void A_IceCheckHeadDone(mobj_t *actor) +void A_IceCheckHeadDone(mobj_t * actor) { - if(actor->special2 == 666) - { - P_SetMobjState(actor, S_ICECHUNK_HEAD2); - } + if (actor->special2 == 666) + { + P_SetMobjState(actor, S_ICECHUNK_HEAD2); + } } //============================================================================ @@ -4740,314 +4808,334 @@ void A_IceCheckHeadDone(mobj_t *actor) // //============================================================================ -void A_FreezeDeathChunks(mobj_t *actor) -{ - int i; - mobj_t *mo; - - if(actor->momx || actor->momy || actor->momz) - { - actor->tics = 105; - return; - } - S_StartSound(actor, SFX_FREEZE_SHATTER); - - for(i = 12+(P_Random()&15); i >= 0; i--) - { - mo = P_SpawnMobj(actor->x+(((P_Random()-128)*actor->radius)>>7), - actor->y+(((P_Random()-128)*actor->radius)>>7), - actor->z+(P_Random()*actor->height/255), MT_ICECHUNK); - P_SetMobjState(mo, mo->info->spawnstate+(P_Random()%3)); - if(mo) - { - mo->momz = FixedDiv(mo->z-actor->z, actor->height)<<2; - mo->momx = (P_Random()-P_Random())<<(FRACBITS-7); - mo->momy = (P_Random()-P_Random())<<(FRACBITS-7); - A_IceSetTics(mo); // set a random tic wait - } - } - for(i = 12+(P_Random()&15); i >= 0; i--) - { - mo = P_SpawnMobj(actor->x+(((P_Random()-128)*actor->radius)>>7), - actor->y+(((P_Random()-128)*actor->radius)>>7), - actor->z+(P_Random()*actor->height/255), MT_ICECHUNK); - P_SetMobjState(mo, mo->info->spawnstate+(P_Random()%3)); - if(mo) - { - mo->momz = FixedDiv(mo->z-actor->z, actor->height)<<2; - mo->momx = (P_Random()-P_Random())<<(FRACBITS-7); - mo->momy = (P_Random()-P_Random())<<(FRACBITS-7); - A_IceSetTics(mo); // set a random tic wait - } - } - if(actor->player) - { // attach the player's view to a chunk of ice - mo = P_SpawnMobj(actor->x, actor->y, actor->z+VIEWHEIGHT, MT_ICECHUNK); - P_SetMobjState(mo, S_ICECHUNK_HEAD); - mo->momz = FixedDiv(mo->z-actor->z, actor->height)<<2; - mo->momx = (P_Random()-P_Random())<<(FRACBITS-7); - mo->momy = (P_Random()-P_Random())<<(FRACBITS-7); - mo->flags2 |= MF2_ICEDAMAGE; // used to force blue palette - mo->flags2 &= ~MF2_FLOORCLIP; - mo->player = actor->player; - actor->player = NULL; - mo->health = actor->health; - mo->angle = actor->angle; - mo->player->mo = mo; - mo->player->lookdir = 0; - } - P_RemoveMobjFromTIDList(actor); - P_SetMobjState(actor, S_FREETARGMOBJ); - actor->flags2 |= MF2_DONTDRAW; +void A_FreezeDeathChunks(mobj_t * actor) +{ + int i; + mobj_t *mo; + + if (actor->momx || actor->momy || actor->momz) + { + actor->tics = 105; + return; + } + S_StartSound(actor, SFX_FREEZE_SHATTER); + + for (i = 12 + (P_Random() & 15); i >= 0; i--) + { + mo = P_SpawnMobj(actor->x + + (((P_Random() - 128) * actor->radius) >> 7), + actor->y + + (((P_Random() - 128) * actor->radius) >> 7), + actor->z + (P_Random() * actor->height / 255), + MT_ICECHUNK); + P_SetMobjState(mo, mo->info->spawnstate + (P_Random() % 3)); + if (mo) + { + mo->momz = FixedDiv(mo->z - actor->z, actor->height) << 2; + mo->momx = (P_Random() - P_Random()) << (FRACBITS - 7); + mo->momy = (P_Random() - P_Random()) << (FRACBITS - 7); + A_IceSetTics(mo); // set a random tic wait + } + } + for (i = 12 + (P_Random() & 15); i >= 0; i--) + { + mo = P_SpawnMobj(actor->x + + (((P_Random() - 128) * actor->radius) >> 7), + actor->y + + (((P_Random() - 128) * actor->radius) >> 7), + actor->z + (P_Random() * actor->height / 255), + MT_ICECHUNK); + P_SetMobjState(mo, mo->info->spawnstate + (P_Random() % 3)); + if (mo) + { + mo->momz = FixedDiv(mo->z - actor->z, actor->height) << 2; + mo->momx = (P_Random() - P_Random()) << (FRACBITS - 7); + mo->momy = (P_Random() - P_Random()) << (FRACBITS - 7); + A_IceSetTics(mo); // set a random tic wait + } + } + if (actor->player) + { // attach the player's view to a chunk of ice + mo = P_SpawnMobj(actor->x, actor->y, actor->z + VIEWHEIGHT, + MT_ICECHUNK); + P_SetMobjState(mo, S_ICECHUNK_HEAD); + mo->momz = FixedDiv(mo->z - actor->z, actor->height) << 2; + mo->momx = (P_Random() - P_Random()) << (FRACBITS - 7); + mo->momy = (P_Random() - P_Random()) << (FRACBITS - 7); + mo->flags2 |= MF2_ICEDAMAGE; // used to force blue palette + mo->flags2 &= ~MF2_FLOORCLIP; + mo->player = actor->player; + actor->player = NULL; + mo->health = actor->health; + mo->angle = actor->angle; + mo->player->mo = mo; + mo->player->lookdir = 0; + } + P_RemoveMobjFromTIDList(actor); + P_SetMobjState(actor, S_FREETARGMOBJ); + actor->flags2 |= MF2_DONTDRAW; } //=========================================================================== // Korax Variables -// special1 last teleport destination -// special2 set if "below half" script not yet run +// special1 last teleport destination +// special2 set if "below half" script not yet run // // Korax Scripts (reserved) -// 249 Tell scripts that we are below half health -// 250-254 Control scripts -// 255 Death script +// 249 Tell scripts that we are below half health +// 250-254 Control scripts +// 255 Death script // // Korax TIDs (reserved) -// 245 Reserved for Korax himself -// 248 Initial teleport destination -// 249 Teleport destination -// 250-254 For use in respective control scripts -// 255 For use in death script (spawn spots) +// 245 Reserved for Korax himself +// 248 Initial teleport destination +// 249 Teleport destination +// 250-254 For use in respective control scripts +// 255 For use in death script (spawn spots) //=========================================================================== -#define KORAX_SPIRIT_LIFETIME (5*(35/5)) // 5 seconds +#define KORAX_SPIRIT_LIFETIME (5*(35/5)) // 5 seconds #define KORAX_COMMAND_HEIGHT (120*FRACUNIT) #define KORAX_COMMAND_OFFSET (27*FRACUNIT) -void KoraxFire1(mobj_t *actor, int type); -void KoraxFire2(mobj_t *actor, int type); -void KoraxFire3(mobj_t *actor, int type); -void KoraxFire4(mobj_t *actor, int type); -void KoraxFire5(mobj_t *actor, int type); -void KoraxFire6(mobj_t *actor, int type); -void KSpiritInit(mobj_t *spirit, mobj_t *korax); +void KoraxFire1(mobj_t * actor, int type); +void KoraxFire2(mobj_t * actor, int type); +void KoraxFire3(mobj_t * actor, int type); +void KoraxFire4(mobj_t * actor, int type); +void KoraxFire5(mobj_t * actor, int type); +void KoraxFire6(mobj_t * actor, int type); +void KSpiritInit(mobj_t * spirit, mobj_t * korax); #define KORAX_TID (245) #define KORAX_FIRST_TELEPORT_TID (248) #define KORAX_TELEPORT_TID (249) -void A_KoraxChase(mobj_t *actor) -{ - mobj_t *spot; - int lastfound; - byte args[3]={0,0,0}; - - if ((!actor->special2) && - (actor->health <= (actor->info->spawnhealth/2))) - { - lastfound = 0; - spot = P_FindMobjFromTID(KORAX_FIRST_TELEPORT_TID, &lastfound); - if (spot) - { - P_Teleport(actor, spot->x, spot->y, spot->angle, true); - } - - P_StartACS(249, 0, args, actor, NULL, 0); - actor->special2 = 1; // Don't run again - - return; - } - - if (!actor->target) return; - if (P_Random()<30) - { - P_SetMobjState(actor, actor->info->missilestate); - } - else if (P_Random()<30) - { - S_StartSound(NULL, SFX_KORAX_ACTIVE); - } - - // Teleport away - if (actor->health < (actor->info->spawnhealth>>1)) - { - if (P_Random()<10) - { - lastfound = actor->special1; - spot = P_FindMobjFromTID(KORAX_TELEPORT_TID, &lastfound); - actor->special1 = lastfound; - if (spot) - { - P_Teleport(actor, spot->x, spot->y, spot->angle, true); - } - } - } -} - -void A_KoraxStep(mobj_t *actor) -{ - A_Chase(actor); -} - -void A_KoraxStep2(mobj_t *actor) -{ - S_StartSound(NULL, SFX_KORAX_STEP); - A_Chase(actor); -} - -void A_KoraxBonePop(mobj_t *actor) -{ - fixed_t x,y,z; - mobj_t *mo; - byte args[5]; - - args[0]=args[1]=args[2]=args[3]=args[4]=0; - x=actor->x, y=actor->y, z=actor->z; - - // Spawn 6 spirits equalangularly - mo = P_SpawnMissileAngle(actor,MT_KORAX_SPIRIT1, ANGLE_60*0, 5*FRACUNIT); - if (mo) KSpiritInit(mo,actor); - mo = P_SpawnMissileAngle(actor,MT_KORAX_SPIRIT2, ANGLE_60*1, 5*FRACUNIT); - if (mo) KSpiritInit(mo,actor); - mo = P_SpawnMissileAngle(actor,MT_KORAX_SPIRIT3, ANGLE_60*2, 5*FRACUNIT); - if (mo) KSpiritInit(mo,actor); - mo = P_SpawnMissileAngle(actor,MT_KORAX_SPIRIT4, ANGLE_60*3, 5*FRACUNIT); - if (mo) KSpiritInit(mo,actor); - mo = P_SpawnMissileAngle(actor,MT_KORAX_SPIRIT5, ANGLE_60*4, 5*FRACUNIT); - if (mo) KSpiritInit(mo,actor); - mo = P_SpawnMissileAngle(actor,MT_KORAX_SPIRIT6, ANGLE_60*5, 5*FRACUNIT); - if (mo) KSpiritInit(mo,actor); - - P_StartACS(255, 0, args, actor, NULL, 0); // Death script -} - -void KSpiritInit(mobj_t *spirit, mobj_t *korax) -{ - int i; - mobj_t *tail, *next; - - spirit->health = KORAX_SPIRIT_LIFETIME; - - spirit->special1 = (int)korax; // Swarm around korax - spirit->special2 = 32+(P_Random()&7); // Float bob index - spirit->args[0] = 10; // initial turn value - spirit->args[1] = 0; // initial look angle - - // Spawn a tail for spirit - tail = P_SpawnMobj(spirit->x, spirit->y, spirit->z, MT_HOLY_TAIL); - tail->special2 = (int)spirit; // parent - for(i = 1; i < 3; i++) - { - next = P_SpawnMobj(spirit->x, spirit->y, spirit->z, MT_HOLY_TAIL); - P_SetMobjState(next, next->info->spawnstate+1); - tail->special1 = (int)next; - tail = next; - } - tail->special1 = 0; // last tail bit -} - -void A_KoraxDecide(mobj_t *actor) -{ - if (P_Random()<220) - { - P_SetMobjState(actor, S_KORAX_MISSILE1); - } - else - { - P_SetMobjState(actor, S_KORAX_COMMAND1); - } -} - -void A_KoraxMissile(mobj_t *actor) -{ - int type = P_Random()%6; - int sound; - - S_StartSound(actor, SFX_KORAX_ATTACK); - - switch(type) - { - case 0: - type = MT_WRAITHFX1; - sound = SFX_WRAITH_MISSILE_FIRE; - break; - case 1: - type = MT_DEMONFX1; - sound = SFX_DEMON_MISSILE_FIRE; - break; - case 2: - type = MT_DEMON2FX1; - sound = SFX_DEMON_MISSILE_FIRE; - break; - case 3: - type = MT_FIREDEMON_FX6; - sound = SFX_FIRED_ATTACK; - break; - case 4: - type = MT_CENTAUR_FX; - sound = SFX_CENTAURLEADER_ATTACK; - break; - case 5: - type = MT_SERPENTFX; - sound = SFX_CENTAURLEADER_ATTACK; - break; - } - - // Fire all 6 missiles at once - S_StartSound(NULL, sound); - KoraxFire1(actor, type); - KoraxFire2(actor, type); - KoraxFire3(actor, type); - KoraxFire4(actor, type); - KoraxFire5(actor, type); - KoraxFire6(actor, type); +void A_KoraxChase(mobj_t * actor) +{ + mobj_t *spot; + int lastfound; + byte args[3] = { 0, 0, 0 }; + + if ((!actor->special2) && + (actor->health <= (actor->info->spawnhealth / 2))) + { + lastfound = 0; + spot = P_FindMobjFromTID(KORAX_FIRST_TELEPORT_TID, &lastfound); + if (spot) + { + P_Teleport(actor, spot->x, spot->y, spot->angle, true); + } + + P_StartACS(249, 0, args, actor, NULL, 0); + actor->special2 = 1; // Don't run again + + return; + } + + if (!actor->target) + return; + if (P_Random() < 30) + { + P_SetMobjState(actor, actor->info->missilestate); + } + else if (P_Random() < 30) + { + S_StartSound(NULL, SFX_KORAX_ACTIVE); + } + + // Teleport away + if (actor->health < (actor->info->spawnhealth >> 1)) + { + if (P_Random() < 10) + { + lastfound = actor->special1; + spot = P_FindMobjFromTID(KORAX_TELEPORT_TID, &lastfound); + actor->special1 = lastfound; + if (spot) + { + P_Teleport(actor, spot->x, spot->y, spot->angle, true); + } + } + } +} + +void A_KoraxStep(mobj_t * actor) +{ + A_Chase(actor); +} + +void A_KoraxStep2(mobj_t * actor) +{ + S_StartSound(NULL, SFX_KORAX_STEP); + A_Chase(actor); +} + +void A_KoraxBonePop(mobj_t * actor) +{ + fixed_t x, y, z; + mobj_t *mo; + byte args[5]; + + args[0] = args[1] = args[2] = args[3] = args[4] = 0; + x = actor->x, y = actor->y, z = actor->z; + + // Spawn 6 spirits equalangularly + mo = P_SpawnMissileAngle(actor, MT_KORAX_SPIRIT1, ANGLE_60 * 0, + 5 * FRACUNIT); + if (mo) + KSpiritInit(mo, actor); + mo = P_SpawnMissileAngle(actor, MT_KORAX_SPIRIT2, ANGLE_60 * 1, + 5 * FRACUNIT); + if (mo) + KSpiritInit(mo, actor); + mo = P_SpawnMissileAngle(actor, MT_KORAX_SPIRIT3, ANGLE_60 * 2, + 5 * FRACUNIT); + if (mo) + KSpiritInit(mo, actor); + mo = P_SpawnMissileAngle(actor, MT_KORAX_SPIRIT4, ANGLE_60 * 3, + 5 * FRACUNIT); + if (mo) + KSpiritInit(mo, actor); + mo = P_SpawnMissileAngle(actor, MT_KORAX_SPIRIT5, ANGLE_60 * 4, + 5 * FRACUNIT); + if (mo) + KSpiritInit(mo, actor); + mo = P_SpawnMissileAngle(actor, MT_KORAX_SPIRIT6, ANGLE_60 * 5, + 5 * FRACUNIT); + if (mo) + KSpiritInit(mo, actor); + + P_StartACS(255, 0, args, actor, NULL, 0); // Death script +} + +void KSpiritInit(mobj_t * spirit, mobj_t * korax) +{ + int i; + mobj_t *tail, *next; + + spirit->health = KORAX_SPIRIT_LIFETIME; + + spirit->special1 = (int) korax; // Swarm around korax + spirit->special2 = 32 + (P_Random() & 7); // Float bob index + spirit->args[0] = 10; // initial turn value + spirit->args[1] = 0; // initial look angle + + // Spawn a tail for spirit + tail = P_SpawnMobj(spirit->x, spirit->y, spirit->z, MT_HOLY_TAIL); + tail->special2 = (int) spirit; // parent + for (i = 1; i < 3; i++) + { + next = P_SpawnMobj(spirit->x, spirit->y, spirit->z, MT_HOLY_TAIL); + P_SetMobjState(next, next->info->spawnstate + 1); + tail->special1 = (int) next; + tail = next; + } + tail->special1 = 0; // last tail bit +} + +void A_KoraxDecide(mobj_t * actor) +{ + if (P_Random() < 220) + { + P_SetMobjState(actor, S_KORAX_MISSILE1); + } + else + { + P_SetMobjState(actor, S_KORAX_COMMAND1); + } +} + +void A_KoraxMissile(mobj_t * actor) +{ + int type = P_Random() % 6; + int sound; + + S_StartSound(actor, SFX_KORAX_ATTACK); + + switch (type) + { + case 0: + type = MT_WRAITHFX1; + sound = SFX_WRAITH_MISSILE_FIRE; + break; + case 1: + type = MT_DEMONFX1; + sound = SFX_DEMON_MISSILE_FIRE; + break; + case 2: + type = MT_DEMON2FX1; + sound = SFX_DEMON_MISSILE_FIRE; + break; + case 3: + type = MT_FIREDEMON_FX6; + sound = SFX_FIRED_ATTACK; + break; + case 4: + type = MT_CENTAUR_FX; + sound = SFX_CENTAURLEADER_ATTACK; + break; + case 5: + type = MT_SERPENTFX; + sound = SFX_CENTAURLEADER_ATTACK; + break; + } + + // Fire all 6 missiles at once + S_StartSound(NULL, sound); + KoraxFire1(actor, type); + KoraxFire2(actor, type); + KoraxFire3(actor, type); + KoraxFire4(actor, type); + KoraxFire5(actor, type); + KoraxFire6(actor, type); } // Call action code scripts (250-254) -void A_KoraxCommand(mobj_t *actor) -{ - byte args[5]; - fixed_t x,y,z; - angle_t ang; - int numcommands; - - S_StartSound(actor, SFX_KORAX_COMMAND); - - // Shoot stream of lightning to ceiling - ang = (actor->angle - ANGLE_90) >> ANGLETOFINESHIFT; - x=actor->x + FixedMul(KORAX_COMMAND_OFFSET,finecosine[ang]); - y=actor->y + FixedMul(KORAX_COMMAND_OFFSET,finesine[ang]); - z=actor->z + KORAX_COMMAND_HEIGHT; - P_SpawnMobj(x,y,z, MT_KORAX_BOLT); - - args[0]=args[1]=args[2]=args[3]=args[4]=0; - - if (actor->health <= (actor->info->spawnhealth >> 1)) - { - numcommands = 5; - } - else - { - numcommands = 4; - } - - switch(P_Random() % numcommands) - { - case 0: - P_StartACS(250, 0, args, actor, NULL, 0); - break; - case 1: - P_StartACS(251, 0, args, actor, NULL, 0); - break; - case 2: - P_StartACS(252, 0, args, actor, NULL, 0); - break; - case 3: - P_StartACS(253, 0, args, actor, NULL, 0); - break; - case 4: - P_StartACS(254, 0, args, actor, NULL, 0); - break; - } +void A_KoraxCommand(mobj_t * actor) +{ + byte args[5]; + fixed_t x, y, z; + angle_t ang; + int numcommands; + + S_StartSound(actor, SFX_KORAX_COMMAND); + + // Shoot stream of lightning to ceiling + ang = (actor->angle - ANGLE_90) >> ANGLETOFINESHIFT; + x = actor->x + FixedMul(KORAX_COMMAND_OFFSET, finecosine[ang]); + y = actor->y + FixedMul(KORAX_COMMAND_OFFSET, finesine[ang]); + z = actor->z + KORAX_COMMAND_HEIGHT; + P_SpawnMobj(x, y, z, MT_KORAX_BOLT); + + args[0] = args[1] = args[2] = args[3] = args[4] = 0; + + if (actor->health <= (actor->info->spawnhealth >> 1)) + { + numcommands = 5; + } + else + { + numcommands = 4; + } + + switch (P_Random() % numcommands) + { + case 0: + P_StartACS(250, 0, args, actor, NULL, 0); + break; + case 1: + P_StartACS(251, 0, args, actor, NULL, 0); + break; + case 2: + P_StartACS(252, 0, args, actor, NULL, 0); + break; + case 3: + P_StartACS(253, 0, args, actor, NULL, 0); + break; + case 4: + P_StartACS(254, 0, args, actor, NULL, 0); + break; + } } @@ -5064,245 +5152,242 @@ void A_KoraxCommand(mobj_t *actor) // Arm projectiles -// arm positions numbered: -// 1 top left -// 2 middle left -// 3 lower left -// 4 top right -// 5 middle right -// 6 lower right +// arm positions numbered: +// 1 top left +// 2 middle left +// 3 lower left +// 4 top right +// 5 middle right +// 6 lower right // Arm 1 projectile -void KoraxFire1(mobj_t *actor, int type) +void KoraxFire1(mobj_t * actor, int type) { - mobj_t *mo; - angle_t ang; - fixed_t x,y,z; + mobj_t *mo; + angle_t ang; + fixed_t x, y, z; - ang = (actor->angle - KORAX_DELTAANGLE) >> ANGLETOFINESHIFT; - x = actor->x + FixedMul(KORAX_ARM_EXTENSION_SHORT, finecosine[ang]); - y = actor->y + FixedMul(KORAX_ARM_EXTENSION_SHORT, finesine[ang]); - z = actor->z - actor->floorclip + KORAX_ARM1_HEIGHT; - mo = P_SpawnKoraxMissile(x,y,z,actor, actor->target, type); + ang = (actor->angle - KORAX_DELTAANGLE) >> ANGLETOFINESHIFT; + x = actor->x + FixedMul(KORAX_ARM_EXTENSION_SHORT, finecosine[ang]); + y = actor->y + FixedMul(KORAX_ARM_EXTENSION_SHORT, finesine[ang]); + z = actor->z - actor->floorclip + KORAX_ARM1_HEIGHT; + mo = P_SpawnKoraxMissile(x, y, z, actor, actor->target, type); } // Arm 2 projectile -void KoraxFire2(mobj_t *actor, int type) +void KoraxFire2(mobj_t * actor, int type) { - mobj_t *mo; - angle_t ang; - fixed_t x,y,z; + mobj_t *mo; + angle_t ang; + fixed_t x, y, z; - ang = (actor->angle - KORAX_DELTAANGLE) >> ANGLETOFINESHIFT; - x = actor->x + FixedMul(KORAX_ARM_EXTENSION_LONG, finecosine[ang]); - y = actor->y + FixedMul(KORAX_ARM_EXTENSION_LONG, finesine[ang]); - z = actor->z - actor->floorclip + KORAX_ARM2_HEIGHT; - mo = P_SpawnKoraxMissile(x,y,z,actor, actor->target, type); + ang = (actor->angle - KORAX_DELTAANGLE) >> ANGLETOFINESHIFT; + x = actor->x + FixedMul(KORAX_ARM_EXTENSION_LONG, finecosine[ang]); + y = actor->y + FixedMul(KORAX_ARM_EXTENSION_LONG, finesine[ang]); + z = actor->z - actor->floorclip + KORAX_ARM2_HEIGHT; + mo = P_SpawnKoraxMissile(x, y, z, actor, actor->target, type); } // Arm 3 projectile -void KoraxFire3(mobj_t *actor, int type) +void KoraxFire3(mobj_t * actor, int type) { - mobj_t *mo; - angle_t ang; - fixed_t x,y,z; + mobj_t *mo; + angle_t ang; + fixed_t x, y, z; - ang = (actor->angle - KORAX_DELTAANGLE) >> ANGLETOFINESHIFT; - x = actor->x + FixedMul(KORAX_ARM_EXTENSION_LONG, finecosine[ang]); - y = actor->y + FixedMul(KORAX_ARM_EXTENSION_LONG, finesine[ang]); - z = actor->z - actor->floorclip + KORAX_ARM3_HEIGHT; - mo = P_SpawnKoraxMissile(x,y,z,actor, actor->target, type); + ang = (actor->angle - KORAX_DELTAANGLE) >> ANGLETOFINESHIFT; + x = actor->x + FixedMul(KORAX_ARM_EXTENSION_LONG, finecosine[ang]); + y = actor->y + FixedMul(KORAX_ARM_EXTENSION_LONG, finesine[ang]); + z = actor->z - actor->floorclip + KORAX_ARM3_HEIGHT; + mo = P_SpawnKoraxMissile(x, y, z, actor, actor->target, type); } // Arm 4 projectile -void KoraxFire4(mobj_t *actor, int type) +void KoraxFire4(mobj_t * actor, int type) { - mobj_t *mo; - angle_t ang; - fixed_t x,y,z; + mobj_t *mo; + angle_t ang; + fixed_t x, y, z; - ang = (actor->angle + KORAX_DELTAANGLE) >> ANGLETOFINESHIFT; - x = actor->x + FixedMul(KORAX_ARM_EXTENSION_SHORT, finecosine[ang]); - y = actor->y + FixedMul(KORAX_ARM_EXTENSION_SHORT, finesine[ang]); - z = actor->z - actor->floorclip + KORAX_ARM4_HEIGHT; - mo = P_SpawnKoraxMissile(x,y,z,actor, actor->target, type); + ang = (actor->angle + KORAX_DELTAANGLE) >> ANGLETOFINESHIFT; + x = actor->x + FixedMul(KORAX_ARM_EXTENSION_SHORT, finecosine[ang]); + y = actor->y + FixedMul(KORAX_ARM_EXTENSION_SHORT, finesine[ang]); + z = actor->z - actor->floorclip + KORAX_ARM4_HEIGHT; + mo = P_SpawnKoraxMissile(x, y, z, actor, actor->target, type); } // Arm 5 projectile -void KoraxFire5(mobj_t *actor, int type) +void KoraxFire5(mobj_t * actor, int type) { - mobj_t *mo; - angle_t ang; - fixed_t x,y,z; + mobj_t *mo; + angle_t ang; + fixed_t x, y, z; - ang = (actor->angle + KORAX_DELTAANGLE) >> ANGLETOFINESHIFT; - x = actor->x + FixedMul(KORAX_ARM_EXTENSION_LONG, finecosine[ang]); - y = actor->y + FixedMul(KORAX_ARM_EXTENSION_LONG, finesine[ang]); - z = actor->z - actor->floorclip + KORAX_ARM5_HEIGHT; - mo = P_SpawnKoraxMissile(x,y,z,actor, actor->target, type); + ang = (actor->angle + KORAX_DELTAANGLE) >> ANGLETOFINESHIFT; + x = actor->x + FixedMul(KORAX_ARM_EXTENSION_LONG, finecosine[ang]); + y = actor->y + FixedMul(KORAX_ARM_EXTENSION_LONG, finesine[ang]); + z = actor->z - actor->floorclip + KORAX_ARM5_HEIGHT; + mo = P_SpawnKoraxMissile(x, y, z, actor, actor->target, type); } // Arm 6 projectile -void KoraxFire6(mobj_t *actor, int type) -{ - mobj_t *mo; - angle_t ang; - fixed_t x,y,z; - - ang = (actor->angle + KORAX_DELTAANGLE) >> ANGLETOFINESHIFT; - x = actor->x + FixedMul(KORAX_ARM_EXTENSION_LONG, finecosine[ang]); - y = actor->y + FixedMul(KORAX_ARM_EXTENSION_LONG, finesine[ang]); - z = actor->z - actor->floorclip + KORAX_ARM6_HEIGHT; - mo = P_SpawnKoraxMissile(x,y,z,actor, actor->target, type); -} - - -void A_KSpiritWeave(mobj_t *actor) -{ - fixed_t newX, newY; - int weaveXY, weaveZ; - int angle; - - weaveXY = actor->special2>>16; - weaveZ = actor->special2&0xFFFF; - angle = (actor->angle+ANG90)>>ANGLETOFINESHIFT; - newX = actor->x-FixedMul(finecosine[angle], - FloatBobOffsets[weaveXY]<<2); - newY = actor->y-FixedMul(finesine[angle], - FloatBobOffsets[weaveXY]<<2); - weaveXY = (weaveXY+(P_Random()%5))&63; - newX += FixedMul(finecosine[angle], - FloatBobOffsets[weaveXY]<<2); - newY += FixedMul(finesine[angle], - FloatBobOffsets[weaveXY]<<2); - P_TryMove(actor, newX, newY); - actor->z -= FloatBobOffsets[weaveZ]<<1; - weaveZ = (weaveZ+(P_Random()%5))&63; - actor->z += FloatBobOffsets[weaveZ]<<1; - actor->special2 = weaveZ+(weaveXY<<16); -} - -void A_KSpiritSeeker(mobj_t *actor, angle_t thresh, angle_t turnMax) -{ - int dir; - int dist; - angle_t delta; - angle_t angle; - mobj_t *target; - fixed_t newZ; - fixed_t deltaZ; - - target = (mobj_t *)actor->special1; - if(target == NULL) - { - return; - } - dir = P_FaceMobj(actor, target, &delta); - if(delta > thresh) - { - delta >>= 1; - if(delta > turnMax) - { - delta = turnMax; - } - } - if(dir) - { // Turn clockwise - actor->angle += delta; - } - else - { // Turn counter clockwise - actor->angle -= delta; - } - angle = actor->angle>>ANGLETOFINESHIFT; - actor->momx = FixedMul(actor->info->speed, finecosine[angle]); - actor->momy = FixedMul(actor->info->speed, finesine[angle]); - - if(!(leveltime&15) - || actor->z > target->z+(target->info->height) - || actor->z+actor->height < target->z) - { - newZ = target->z+((P_Random()*target->info->height)>>8); - deltaZ = newZ-actor->z; - if(abs(deltaZ) > 15*FRACUNIT) - { - if(deltaZ > 0) - { - deltaZ = 15*FRACUNIT; - } - else - { - deltaZ = -15*FRACUNIT; - } - } - dist = P_AproxDistance(target->x-actor->x, target->y-actor->y); - dist = dist/actor->info->speed; - if(dist < 1) - { - dist = 1; - } - actor->momz = deltaZ/dist; - } - return; -} - - -void A_KSpiritRoam(mobj_t *actor) -{ - if (actor->health-- <= 0) - { - S_StartSound(actor, SFX_SPIRIT_DIE); - P_SetMobjState(actor, S_KSPIRIT_DEATH1); - } - else - { - if (actor->special1) - { - A_KSpiritSeeker(actor, actor->args[0]*ANGLE_1, - actor->args[0]*ANGLE_1*2); - } - A_KSpiritWeave(actor); - if (P_Random()<50) - { - S_StartSound(NULL, SFX_SPIRIT_ACTIVE); - } - } -} - -void A_KBolt(mobj_t *actor) -{ - // Countdown lifetime - if (actor->special1-- <= 0) - { - P_SetMobjState(actor, S_NULL); - } +void KoraxFire6(mobj_t * actor, int type) +{ + mobj_t *mo; + angle_t ang; + fixed_t x, y, z; + + ang = (actor->angle + KORAX_DELTAANGLE) >> ANGLETOFINESHIFT; + x = actor->x + FixedMul(KORAX_ARM_EXTENSION_LONG, finecosine[ang]); + y = actor->y + FixedMul(KORAX_ARM_EXTENSION_LONG, finesine[ang]); + z = actor->z - actor->floorclip + KORAX_ARM6_HEIGHT; + mo = P_SpawnKoraxMissile(x, y, z, actor, actor->target, type); +} + + +void A_KSpiritWeave(mobj_t * actor) +{ + fixed_t newX, newY; + int weaveXY, weaveZ; + int angle; + + weaveXY = actor->special2 >> 16; + weaveZ = actor->special2 & 0xFFFF; + angle = (actor->angle + ANG90) >> ANGLETOFINESHIFT; + newX = actor->x - FixedMul(finecosine[angle], + FloatBobOffsets[weaveXY] << 2); + newY = actor->y - FixedMul(finesine[angle], + FloatBobOffsets[weaveXY] << 2); + weaveXY = (weaveXY + (P_Random() % 5)) & 63; + newX += FixedMul(finecosine[angle], FloatBobOffsets[weaveXY] << 2); + newY += FixedMul(finesine[angle], FloatBobOffsets[weaveXY] << 2); + P_TryMove(actor, newX, newY); + actor->z -= FloatBobOffsets[weaveZ] << 1; + weaveZ = (weaveZ + (P_Random() % 5)) & 63; + actor->z += FloatBobOffsets[weaveZ] << 1; + actor->special2 = weaveZ + (weaveXY << 16); +} + +void A_KSpiritSeeker(mobj_t * actor, angle_t thresh, angle_t turnMax) +{ + int dir; + int dist; + angle_t delta; + angle_t angle; + mobj_t *target; + fixed_t newZ; + fixed_t deltaZ; + + target = (mobj_t *) actor->special1; + if (target == NULL) + { + return; + } + dir = P_FaceMobj(actor, target, &delta); + if (delta > thresh) + { + delta >>= 1; + if (delta > turnMax) + { + delta = turnMax; + } + } + if (dir) + { // Turn clockwise + actor->angle += delta; + } + else + { // Turn counter clockwise + actor->angle -= delta; + } + angle = actor->angle >> ANGLETOFINESHIFT; + actor->momx = FixedMul(actor->info->speed, finecosine[angle]); + actor->momy = FixedMul(actor->info->speed, finesine[angle]); + + if (!(leveltime & 15) + || actor->z > target->z + (target->info->height) + || actor->z + actor->height < target->z) + { + newZ = target->z + ((P_Random() * target->info->height) >> 8); + deltaZ = newZ - actor->z; + if (abs(deltaZ) > 15 * FRACUNIT) + { + if (deltaZ > 0) + { + deltaZ = 15 * FRACUNIT; + } + else + { + deltaZ = -15 * FRACUNIT; + } + } + dist = P_AproxDistance(target->x - actor->x, target->y - actor->y); + dist = dist / actor->info->speed; + if (dist < 1) + { + dist = 1; + } + actor->momz = deltaZ / dist; + } + return; +} + + +void A_KSpiritRoam(mobj_t * actor) +{ + if (actor->health-- <= 0) + { + S_StartSound(actor, SFX_SPIRIT_DIE); + P_SetMobjState(actor, S_KSPIRIT_DEATH1); + } + else + { + if (actor->special1) + { + A_KSpiritSeeker(actor, actor->args[0] * ANGLE_1, + actor->args[0] * ANGLE_1 * 2); + } + A_KSpiritWeave(actor); + if (P_Random() < 50) + { + S_StartSound(NULL, SFX_SPIRIT_ACTIVE); + } + } +} + +void A_KBolt(mobj_t * actor) +{ + // Countdown lifetime + if (actor->special1-- <= 0) + { + P_SetMobjState(actor, S_NULL); + } } #define KORAX_BOLT_HEIGHT 48*FRACUNIT #define KORAX_BOLT_LIFETIME 3 -void A_KBoltRaise(mobj_t *actor) +void A_KBoltRaise(mobj_t * actor) { - mobj_t *mo; - fixed_t z; + mobj_t *mo; + fixed_t z; - // Spawn a child upward - z = actor->z + KORAX_BOLT_HEIGHT; + // Spawn a child upward + z = actor->z + KORAX_BOLT_HEIGHT; - if ((z + KORAX_BOLT_HEIGHT) < actor->ceilingz) - { - mo = P_SpawnMobj(actor->x, actor->y, z, MT_KORAX_BOLT); - if (mo) - { - mo->special1 = KORAX_BOLT_LIFETIME; - } - } - else - { - // Maybe cap it off here - } + if ((z + KORAX_BOLT_HEIGHT) < actor->ceilingz) + { + mo = P_SpawnMobj(actor->x, actor->y, z, MT_KORAX_BOLT); + if (mo) + { + mo->special1 = KORAX_BOLT_LIFETIME; + } + } + else + { + // Maybe cap it off here + } } - -- cgit v1.2.3