1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029 |
- #include "Precompiled.h"
- #include "globaldata.h"
- #include <stdlib.h>
- #include "m_random.h"
- #include "i_system.h"
- #include "doomdef.h"
- #include "p_local.h"
- #include "s_sound.h"
- #include "g_game.h"
- #include "doomstat.h"
- #include "r_state.h"
- #include "sounds.h"
- extern bool globalNetworking;
- const dirtype_t opposite[] =
- {
- DI_WEST, DI_SOUTHWEST, DI_SOUTH, DI_SOUTHEAST,
- DI_EAST, DI_NORTHEAST, DI_NORTH, DI_NORTHWEST, DI_NODIR
- };
- const dirtype_t diags[] =
- {
- DI_NORTHWEST, DI_NORTHEAST, DI_SOUTHWEST, DI_SOUTHEAST
- };
- extern "C" void A_Fall (mobj_t *actor, void *);
- void
- P_RecursiveSound
- ( sector_t* sec,
- int soundblocks )
- {
- int i;
- line_t* check;
- sector_t* other;
-
-
- if (sec->validcount == ::g->validcount
- && sec->soundtraversed <= soundblocks+1)
- {
- return;
- }
-
- sec->validcount = ::g->validcount;
- sec->soundtraversed = soundblocks+1;
- sec->soundtarget = ::g->soundtarget;
-
- for (i=0 ;i<sec->linecount ; i++)
- {
- check = sec->lines[i];
- if (! (check->flags & ML_TWOSIDED) )
- continue;
-
- P_LineOpening (check);
- if (::g->openrange <= 0)
- continue;
-
- if ( ::g->sides[ check->sidenum[0] ].sector == sec)
- other = ::g->sides[ check->sidenum[1] ] .sector;
- else
- other = ::g->sides[ check->sidenum[0] ].sector;
-
- if (check->flags & ML_SOUNDBLOCK)
- {
- if (!soundblocks)
- P_RecursiveSound (other, 1);
- }
- else
- P_RecursiveSound (other, soundblocks);
- }
- }
- void
- P_NoiseAlert
- ( mobj_t* target,
- mobj_t* emmiter )
- {
- ::g->soundtarget = target;
- ::g->validcount++;
- P_RecursiveSound (emmiter->subsector->sector, 0);
- }
- qboolean P_CheckMeleeRange (mobj_t* actor)
- {
- mobj_t* pl;
- fixed_t dist;
-
- if (!actor->target)
- return false;
-
- pl = actor->target;
- dist = P_AproxDistance (pl->x-actor->x, pl->y-actor->y);
- if (dist >= MELEERANGE-20*FRACUNIT+pl->info->radius)
- return false;
-
- if (! P_CheckSight (actor, actor->target) )
- return false;
-
- return true;
- }
- qboolean P_CheckMissileRange (mobj_t* actor)
- {
- fixed_t dist;
-
- if (! P_CheckSight (actor, actor->target) )
- return false;
-
- if ( actor->flags & MF_JUSTHIT )
- {
-
-
- actor->flags &= ~MF_JUSTHIT;
- return true;
- }
-
- if (actor->reactiontime)
- return false;
-
-
- dist = P_AproxDistance ( actor->x-actor->target->x,
- actor->y-actor->target->y) - 64*FRACUNIT;
-
- if (!actor->info->meleestate)
- dist -= 128*FRACUNIT;
- dist >>= 16;
- if (actor->type == MT_VILE)
- {
- if (dist > 14*64)
- return false;
- }
-
- if (actor->type == MT_UNDEAD)
- {
- if (dist < 196)
- return false;
- dist >>= 1;
- }
-
- if (actor->type == MT_CYBORG
- || actor->type == MT_SPIDER
- || actor->type == MT_SKULL)
- {
- dist >>= 1;
- }
-
- if (dist > 200)
- dist = 200;
-
- if (actor->type == MT_CYBORG && dist > 160)
- dist = 160;
-
- if (P_Random () < dist)
- return false;
-
- return true;
- }
- const fixed_t xspeed[8] = {FRACUNIT,47000,0,-47000,-FRACUNIT,-47000,0,47000};
- const fixed_t yspeed[8] = {0,47000,FRACUNIT,47000,0,-47000,-FRACUNIT,-47000};
- qboolean P_Move (mobj_t* actor)
- {
- fixed_t tryx;
- fixed_t tryy;
-
- line_t* ld;
-
-
-
- qboolean try_ok;
- qboolean good;
-
- if (actor->movedir == DI_NODIR)
- return false;
-
- if ((unsigned)actor->movedir >= 8)
- I_Error ("Weird actor->movedir!");
-
- tryx = actor->x + actor->info->speed*xspeed[actor->movedir];
- tryy = actor->y + actor->info->speed*yspeed[actor->movedir];
- try_ok = P_TryMove (actor, tryx, tryy);
- if (!try_ok)
- {
-
- if (actor->flags & MF_FLOAT && ::g->floatok)
- {
-
- if (actor->z < ::g->tmfloorz)
- actor->z += FLOATSPEED;
- else
- actor->z -= FLOATSPEED;
- actor->flags |= MF_INFLOAT;
- return true;
- }
-
- if (!::g->numspechit)
- return false;
-
- actor->movedir = DI_NODIR;
- good = false;
- while (::g->numspechit--)
- {
- ld = ::g->spechit[::g->numspechit];
-
-
-
- if (P_UseSpecialLine (actor, ld,0))
- good = true;
- }
- return good;
- }
- else
- {
- actor->flags &= ~MF_INFLOAT;
- }
-
-
- if (! (actor->flags & MF_FLOAT) )
- actor->z = actor->floorz;
- return true;
- }
- qboolean P_TryWalk (mobj_t* actor)
- {
- if (!P_Move (actor))
- {
- return false;
- }
- actor->movecount = P_Random()&15;
- return true;
- }
- void P_NewChaseDir (mobj_t* actor)
- {
- fixed_t deltax;
- fixed_t deltay;
-
- dirtype_t d[3];
-
- int tdir;
- dirtype_t olddir;
-
- dirtype_t turnaround;
- if (!actor->target)
- I_Error ("P_NewChaseDir: called with no target");
-
- olddir = (dirtype_t)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;
-
- 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 (P_Random() > 200
- || abs(deltay)>abs(deltax))
- {
- tdir=d[1];
- d[1]=d[2];
- d[2]=(dirtype_t)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;
- }
- }
- if (d[2]!=DI_NODIR)
- {
- actor->movedir =d[2];
- if (P_TryWalk(actor))
- return;
- }
-
-
- if (olddir!=DI_NODIR)
- {
- actor->movedir =olddir;
- if (P_TryWalk(actor))
- return;
- }
-
- if (P_Random()&1)
- {
- 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-1);
- 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;
- }
- qboolean
- P_LookForPlayers
- ( mobj_t* actor,
- qboolean allaround )
- {
- int c;
- int stop;
- player_t* player;
- sector_t* sector;
- angle_t an;
- fixed_t dist;
-
- sector = actor->subsector->sector;
-
- c = 0;
- stop = (actor->lastlook-1)&3;
-
- for ( ; ; actor->lastlook = (actor->lastlook+1)&3 )
- {
- if (!::g->playeringame[actor->lastlook])
- continue;
-
- if (c++ == 2
- || actor->lastlook == stop)
- {
-
- return false;
- }
-
- player = &::g->players[actor->lastlook];
- if (player->health <= 0)
- continue;
- if (!P_CheckSight (actor, player->mo))
- continue;
-
- 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 (dist > MELEERANGE)
- continue;
- }
- }
-
- actor->target = player->mo;
- return true;
- }
- return false;
- }
- extern "C" {
- void A_KeenDie (mobj_t* mo, void * )
- {
- thinker_t* th;
- mobj_t* mo2;
- line_t junk;
- A_Fall (mo, 0);
-
-
-
- for (th = ::g->thinkercap.next ; th != &::g->thinkercap ; th=th->next)
- {
- if (th->function.acp1 != (actionf_p1)P_MobjThinker)
- continue;
- mo2 = (mobj_t *)th;
- if (mo2 != mo
- && mo2->type == mo->type
- && mo2->health > 0)
- {
-
- return;
- }
- }
- junk.tag = 666;
- EV_DoDoor(&junk,opened);
- }
- void A_Look (mobj_t* actor, void * )
- {
- mobj_t* targ;
-
- actor->threshold = 0;
- 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;
-
-
- seeyou:
- if (actor->info->seesound)
- {
- int sound;
-
- switch (actor->info->seesound)
- {
- case sfx_posit1:
- case sfx_posit2:
- case sfx_posit3:
- sound = sfx_posit1+P_Random()%3;
- break;
- case sfx_bgsit1:
- case sfx_bgsit2:
- sound = sfx_bgsit1+P_Random()%2;
- break;
- default:
- sound = actor->info->seesound;
- break;
- }
- if (actor->type==MT_SPIDER
- || actor->type == MT_CYBORG)
- {
-
- S_StartSound (NULL, sound);
- }
- else
- S_StartSound (actor, sound);
- }
- P_SetMobjState (actor, (statenum_t)actor->info->seestate);
- }
- void A_Chase (mobj_t* actor, void * )
- {
- int delta;
- if (actor->reactiontime)
- actor->reactiontime--;
-
-
- if (actor->threshold)
- {
- if (!actor->target
- || actor->target->health <= 0)
- {
- actor->threshold = 0;
- }
- else
- actor->threshold--;
- }
-
-
- 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))
- {
-
- if (P_LookForPlayers(actor,true))
- return;
-
- P_SetMobjState (actor, (statenum_t)actor->info->spawnstate);
- return;
- }
-
-
- if (actor->flags & MF_JUSTATTACKED)
- {
- actor->flags &= ~MF_JUSTATTACKED;
- if (::g->gameskill != sk_nightmare && !::g->fastparm)
- P_NewChaseDir (actor);
- return;
- }
-
-
- if (actor->info->meleestate && P_CheckMeleeRange (actor))
- {
- if (actor->info->attacksound)
- S_StartSound (actor, actor->info->attacksound);
- P_SetMobjState (actor, (statenum_t)actor->info->meleestate);
- return;
- }
-
-
- if (actor->info->missilestate)
- {
- if (::g->gameskill < sk_nightmare
- && !::g->fastparm && actor->movecount)
- {
- goto nomissile;
- }
-
- if (!P_CheckMissileRange (actor))
- goto nomissile;
-
- P_SetMobjState (actor, (statenum_t)actor->info->missilestate);
- actor->flags |= MF_JUSTATTACKED;
- return;
- }
-
- nomissile:
-
- if (::g->netgame
- && !actor->threshold
- && !P_CheckSight (actor, actor->target) )
- {
- if (P_LookForPlayers(actor,true))
- return;
- }
-
-
- if (--actor->movecount<0
- || !P_Move (actor))
- {
- P_NewChaseDir (actor);
- }
-
-
- if (actor->info->activesound && P_Random () < 3)
- {
- S_StartSound (actor, actor->info->activesound);
- }
- }
- void A_FaceTarget (mobj_t* actor, void * )
- {
- 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)
- actor->angle += (P_Random()-P_Random())<<21;
- }
- void A_PosAttack (mobj_t* actor, void * )
- {
- int angle;
- int damage;
- int slope;
-
- if (!actor->target)
- return;
-
- A_FaceTarget (actor, 0);
- angle = actor->angle;
- slope = P_AimLineAttack (actor, angle, MISSILERANGE);
- S_StartSound (actor, sfx_pistol);
- angle += (P_Random()-P_Random())<<20;
- damage = ((P_Random()%5)+1)*3;
- P_LineAttack (actor, angle, MISSILERANGE, slope, damage);
- }
- void A_SPosAttack (mobj_t* actor, void * )
- {
- int i;
- int angle;
- int bangle;
- int damage;
- int slope;
-
- if (!actor->target)
- return;
- S_StartSound (actor, sfx_shotgn);
- A_FaceTarget (actor, 0);
- bangle = actor->angle;
- slope = P_AimLineAttack (actor, bangle, MISSILERANGE);
- for (i=0 ; i<3 ; i++)
- {
- angle = bangle + ((P_Random()-P_Random())<<20);
- damage = ((P_Random()%5)+1)*3;
- P_LineAttack (actor, angle, MISSILERANGE, slope, damage);
- }
- }
- void A_CPosAttack (mobj_t* actor, void * )
- {
- int angle;
- int bangle;
- int damage;
- int slope;
-
- if (!actor->target)
- return;
- S_StartSound (actor, sfx_shotgn);
- A_FaceTarget (actor, 0);
- bangle = actor->angle;
- slope = P_AimLineAttack (actor, bangle, MISSILERANGE);
- angle = bangle + ((P_Random()-P_Random())<<20);
- damage = ((P_Random()%5)+1)*3;
- P_LineAttack (actor, angle, MISSILERANGE, slope, damage);
- }
- void A_CPosRefire (mobj_t* actor, void * )
- {
-
- A_FaceTarget (actor, 0);
- if (P_Random () < 40)
- return;
- if (!actor->target
- || actor->target->health <= 0
- || !P_CheckSight (actor, actor->target) )
- {
- P_SetMobjState (actor, (statenum_t)actor->info->seestate);
- }
- }
- void A_SpidRefire (mobj_t* actor, void * )
- {
-
- A_FaceTarget (actor, 0);
- if (P_Random () < 10)
- return;
- if (!actor->target
- || actor->target->health <= 0
- || !P_CheckSight (actor, actor->target) )
- {
- P_SetMobjState (actor, (statenum_t)actor->info->seestate);
- }
- }
- void A_BspiAttack (mobj_t *actor, void * )
- {
- if (!actor->target)
- return;
-
- A_FaceTarget (actor, 0);
-
- P_SpawnMissile (actor, actor->target, MT_ARACHPLAZ);
- }
- void A_TroopAttack (mobj_t* actor, void * )
- {
- int damage;
-
- if (!actor->target)
- return;
-
- A_FaceTarget (actor, 0);
- if (P_CheckMeleeRange (actor))
- {
- S_StartSound (actor, sfx_claw);
- damage = (P_Random()%8+1)*3;
- P_DamageMobj (actor->target, actor, actor, damage);
- return;
- }
-
-
- P_SpawnMissile (actor, actor->target, MT_TROOPSHOT);
- }
- void A_SargAttack (mobj_t* actor, void * )
- {
- int damage;
- if (!actor->target)
- return;
-
- A_FaceTarget (actor, 0);
- if (P_CheckMeleeRange (actor))
- {
- damage = ((P_Random()%10)+1)*4;
- P_DamageMobj (actor->target, actor, actor, damage);
- }
- }
- void A_HeadAttack (mobj_t* actor, void * )
- {
- int damage;
-
- if (!actor->target)
- return;
-
- A_FaceTarget (actor, 0);
- if (P_CheckMeleeRange (actor))
- {
- damage = (P_Random()%6+1)*10;
- P_DamageMobj (actor->target, actor, actor, damage);
- return;
- }
-
-
- P_SpawnMissile (actor, actor->target, MT_HEADSHOT);
- }
- void A_CyberAttack (mobj_t* actor, void * )
- {
- if (!actor->target)
- return;
-
- A_FaceTarget (actor, 0);
- P_SpawnMissile (actor, actor->target, MT_ROCKET);
- }
- void A_BruisAttack (mobj_t* actor, void * )
- {
- int damage;
-
- if (!actor->target)
- return;
-
- if (P_CheckMeleeRange (actor))
- {
- S_StartSound (actor, sfx_claw);
- damage = (P_Random()%8+1)*10;
- P_DamageMobj (actor->target, actor, actor, damage);
- return;
- }
-
-
- P_SpawnMissile (actor, actor->target, MT_BRUISERSHOT);
- }
- void A_SkelMissile (mobj_t* actor, void * )
- {
- mobj_t* mo;
-
- if (!actor->target)
- return;
-
- A_FaceTarget (actor, 0);
- actor->z += 16*FRACUNIT;
- mo = P_SpawnMissile (actor, actor->target, MT_TRACER);
- actor->z -= 16*FRACUNIT;
- mo->x += mo->momx;
- mo->y += mo->momy;
- mo->tracer = actor->target;
- }
- void A_Tracer (mobj_t* actor, void * )
- {
- angle_t exact;
- fixed_t dist;
- fixed_t slope;
- mobj_t* dest;
- mobj_t* th;
-
-
-
-
- if ( ::g->leveltime & 3 ) {
- return;
- }
-
- P_SpawnPuff (actor->x, actor->y, actor->z);
-
- th = P_SpawnMobj (actor->x-actor->momx,
- actor->y-actor->momy,
- actor->z, MT_SMOKE);
-
- th->momz = FRACUNIT;
- th->tics -= P_Random()&3;
- if (th->tics < 1)
- th->tics = 1;
-
-
- dest = actor->tracer;
-
- if (!dest || dest->health <= 0)
- return;
-
-
- exact = R_PointToAngle2 (actor->x,
- actor->y,
- dest->x,
- dest->y);
- if (exact != actor->angle)
- {
- if (exact - actor->angle > 0x80000000)
- {
- actor->angle -= ::g->TRACEANGLE;
- if (exact - actor->angle < 0x80000000)
- actor->angle = exact;
- }
- else
- {
- actor->angle += ::g->TRACEANGLE;
- if (exact - actor->angle > 0x80000000)
- actor->angle = exact;
- }
- }
-
- exact = actor->angle>>ANGLETOFINESHIFT;
- actor->momx = FixedMul (actor->info->speed, finecosine[exact]);
- actor->momy = FixedMul (actor->info->speed, finesine[exact]);
-
-
- dist = P_AproxDistance (dest->x - actor->x,
- dest->y - actor->y);
-
- dist = dist / actor->info->speed;
- if (dist < 1)
- dist = 1;
- slope = (dest->z+40*FRACUNIT - actor->z) / dist;
- if (slope < actor->momz)
- actor->momz -= FRACUNIT/8;
- else
- actor->momz += FRACUNIT/8;
- }
- void A_SkelWhoosh (mobj_t* actor, void * )
- {
- if (!actor->target)
- return;
- A_FaceTarget (actor, 0);
- S_StartSound (actor,sfx_skeswg);
- }
- void A_SkelFist (mobj_t* actor, void * )
- {
- int damage;
- if (!actor->target)
- return;
-
- A_FaceTarget (actor, 0);
-
- if (P_CheckMeleeRange (actor))
- {
- damage = ((P_Random()%10)+1)*6;
- S_StartSound (actor, sfx_skepch);
- P_DamageMobj (actor->target, actor, actor, damage);
- }
- }
- qboolean PIT_VileCheck (mobj_t* thing )
- {
- int maxdist;
- qboolean check;
-
- if (!(thing->flags & MF_CORPSE) )
- return true;
-
- if (thing->tics != -1)
- return true;
-
- if (thing->info->raisestate == S_NULL)
- return true;
-
- maxdist = thing->info->radius + mobjinfo[MT_VILE].radius;
-
- if ( abs(thing->x - ::g->viletryx) > maxdist
- || abs(thing->y - ::g->viletryy) > maxdist )
- return true;
-
- ::g->corpsehit = thing;
- ::g->corpsehit->momx = ::g->corpsehit->momy = 0;
- ::g->corpsehit->height <<= 2;
- check = P_CheckPosition (::g->corpsehit, ::g->corpsehit->x, ::g->corpsehit->y);
- ::g->corpsehit->height >>= 2;
- if (!check)
- return true;
-
- return false;
- }
- void A_VileChase (mobj_t* actor, void * )
- {
- int xl;
- int xh;
- int yl;
- int yh;
-
- int bx;
- int by;
- const mobjinfo_t* info;
- mobj_t* temp;
-
- if (actor->movedir != DI_NODIR)
- {
-
- ::g->viletryx =
- actor->x + actor->info->speed*xspeed[actor->movedir];
- ::g->viletryy =
- actor->y + actor->info->speed*yspeed[actor->movedir];
- xl = (::g->viletryx - ::g->bmaporgx - MAXRADIUS*2)>>MAPBLOCKSHIFT;
- xh = (::g->viletryx - ::g->bmaporgx + MAXRADIUS*2)>>MAPBLOCKSHIFT;
- yl = (::g->viletryy - ::g->bmaporgy - MAXRADIUS*2)>>MAPBLOCKSHIFT;
- yh = (::g->viletryy - ::g->bmaporgy + MAXRADIUS*2)>>MAPBLOCKSHIFT;
-
- ::g->vileobj = actor;
- for (bx=xl ; bx<=xh ; bx++)
- {
- for (by=yl ; by<=yh ; by++)
- {
-
-
-
- if (!P_BlockThingsIterator(bx,by,PIT_VileCheck))
- {
-
- temp = actor->target;
- actor->target = ::g->corpsehit;
- A_FaceTarget (actor, 0);
- actor->target = temp;
-
- P_SetMobjState (actor, S_VILE_HEAL1);
- S_StartSound (::g->corpsehit, sfx_slop);
- info = ::g->corpsehit->info;
-
- P_SetMobjState (::g->corpsehit,(statenum_t)info->raisestate);
- ::g->corpsehit->height <<= 2;
- ::g->corpsehit->flags = info->flags;
- ::g->corpsehit->health = info->spawnhealth;
- ::g->corpsehit->target = NULL;
- return;
- }
- }
- }
- }
-
- A_Chase (actor, 0);
- }
- void A_VileStart (mobj_t* actor, void * )
- {
- S_StartSound (actor, sfx_vilatk);
- }
- void A_Fire (mobj_t* actor, void * );
- void A_StartFire (mobj_t* actor, void * )
- {
- S_StartSound(actor,sfx_flamst);
- A_Fire(actor, 0 );
- }
- void A_FireCrackle (mobj_t* actor, void * )
- {
- S_StartSound(actor,sfx_flame);
- A_Fire(actor, 0);
- }
- void A_Fire (mobj_t* actor, void * )
- {
- mobj_t* dest;
- unsigned an;
-
- dest = actor->tracer;
- if (!dest)
- return;
-
-
- if (!P_CheckSight (actor->target, dest) )
- return;
- an = dest->angle >> ANGLETOFINESHIFT;
- P_UnsetThingPosition (actor);
- actor->x = dest->x + FixedMul (24*FRACUNIT, finecosine[an]);
- actor->y = dest->y + FixedMul (24*FRACUNIT, finesine[an]);
- actor->z = dest->z;
- P_SetThingPosition (actor);
- }
- void A_VileTarget (mobj_t* actor, void * )
- {
- mobj_t* fog;
-
- if (!actor->target)
- return;
- A_FaceTarget (actor, 0);
- fog = P_SpawnMobj (actor->target->x,
- actor->target->x,
- actor->target->z, MT_FIRE);
-
- actor->tracer = fog;
- fog->target = actor;
- fog->tracer = actor->target;
- A_Fire (fog, 0);
- }
- void A_VileAttack (mobj_t* actor, void * )
- {
- mobj_t* fire;
- int an;
-
- if (!actor->target)
- return;
-
- A_FaceTarget (actor, 0);
- if (!P_CheckSight (actor, actor->target) )
- return;
- S_StartSound (actor, sfx_barexp);
- P_DamageMobj (actor->target, actor, actor, 20);
- actor->target->momz = 1000*FRACUNIT/actor->target->info->mass;
-
- an = actor->angle >> ANGLETOFINESHIFT;
- fire = actor->tracer;
- if (!fire)
- return;
-
-
- fire->x = actor->target->x - FixedMul (24*FRACUNIT, finecosine[an]);
- fire->y = actor->target->y - FixedMul (24*FRACUNIT, finesine[an]);
- P_RadiusAttack (fire, actor, 70 );
- }
- void A_FatRaise (mobj_t *actor, void * )
- {
- A_FaceTarget (actor, 0);
- S_StartSound (actor, sfx_manatk);
- }
- void A_FatAttack1 (mobj_t* actor, void * )
- {
- mobj_t* mo;
- int an;
-
- A_FaceTarget (actor, 0);
-
- actor->angle += FATSPREAD;
- P_SpawnMissile (actor, actor->target, MT_FATSHOT);
- mo = P_SpawnMissile (actor, actor->target, MT_FATSHOT);
- mo->angle += FATSPREAD;
- an = mo->angle >> ANGLETOFINESHIFT;
- mo->momx = FixedMul (mo->info->speed, finecosine[an]);
- mo->momy = FixedMul (mo->info->speed, finesine[an]);
- }
- void A_FatAttack2 (mobj_t* actor, void * )
- {
- mobj_t* mo;
- int an;
- A_FaceTarget (actor, 0);
-
- actor->angle -= FATSPREAD;
- P_SpawnMissile (actor, actor->target, MT_FATSHOT);
- mo = P_SpawnMissile (actor, actor->target, MT_FATSHOT);
- mo->angle -= FATSPREAD*2;
- an = mo->angle >> ANGLETOFINESHIFT;
- mo->momx = FixedMul (mo->info->speed, finecosine[an]);
- mo->momy = FixedMul (mo->info->speed, finesine[an]);
- }
- void A_FatAttack3 (mobj_t* actor, void * )
- {
- mobj_t* mo;
- int an;
- A_FaceTarget (actor, 0);
-
- mo = P_SpawnMissile (actor, actor->target, MT_FATSHOT);
- mo->angle -= FATSPREAD/2;
- an = mo->angle >> ANGLETOFINESHIFT;
- mo->momx = FixedMul (mo->info->speed, finecosine[an]);
- mo->momy = FixedMul (mo->info->speed, finesine[an]);
- mo = P_SpawnMissile (actor, actor->target, MT_FATSHOT);
- mo->angle += FATSPREAD/2;
- an = mo->angle >> ANGLETOFINESHIFT;
- mo->momx = FixedMul (mo->info->speed, finecosine[an]);
- mo->momy = FixedMul (mo->info->speed, finesine[an]);
- }
- void A_SkullAttack (mobj_t* actor, void * )
- {
- mobj_t* dest;
- angle_t an;
- int dist;
- if (!actor->target)
- return;
-
- dest = actor->target;
- actor->flags |= MF_SKULLFLY;
- S_StartSound (actor, actor->info->attacksound);
- A_FaceTarget (actor, 0);
- an = actor->angle >> ANGLETOFINESHIFT;
- actor->momx = FixedMul (SKULLSPEED, finecosine[an]);
- actor->momy = FixedMul (SKULLSPEED, finesine[an]);
- dist = P_AproxDistance (dest->x - actor->x, dest->y - actor->y);
- dist = dist / SKULLSPEED;
-
- if (dist < 1)
- dist = 1;
- actor->momz = (dest->z+(dest->height>>1) - actor->z) / dist;
- }
- void
- A_PainShootSkull
- ( mobj_t* actor,
- angle_t angle )
- {
- fixed_t x;
- fixed_t y;
- fixed_t z;
-
- mobj_t* newmobj;
- angle_t an;
- int prestep;
- int count;
- thinker_t* currentthinker;
-
- count = 0;
- currentthinker = ::g->thinkercap.next;
- while (currentthinker != &::g->thinkercap)
- {
- if ( (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker)
- && ((mobj_t *)currentthinker)->type == MT_SKULL)
- count++;
- currentthinker = currentthinker->next;
- }
-
-
- if (count > 20)
- return;
-
- an = angle >> ANGLETOFINESHIFT;
-
- prestep =
- 4*FRACUNIT
- + 3*(actor->info->radius + mobjinfo[MT_SKULL].radius)/2;
-
- x = actor->x + FixedMul (prestep, finecosine[an]);
- y = actor->y + FixedMul (prestep, finesine[an]);
- z = actor->z + 8*FRACUNIT;
-
- newmobj = P_SpawnMobj (x , y, z, MT_SKULL);
-
- if (!P_TryMove (newmobj, newmobj->x, newmobj->y))
- {
-
- P_DamageMobj (newmobj,actor,actor,10000);
- return;
- }
-
- newmobj->target = actor->target;
- A_SkullAttack (newmobj, 0);
- }
- void A_PainAttack (mobj_t* actor, void * )
- {
- if (!actor->target)
- return;
- A_FaceTarget (actor, 0);
- A_PainShootSkull (actor, actor->angle);
- }
- void A_PainDie (mobj_t* actor, void * )
- {
- A_Fall (actor, 0);
- A_PainShootSkull (actor, actor->angle+ANG90);
- A_PainShootSkull (actor, actor->angle+ANG180);
- A_PainShootSkull (actor, actor->angle+ANG270);
- }
- void A_Scream (mobj_t* actor, void * )
- {
- int sound;
-
- switch (actor->info->deathsound)
- {
- case 0:
- return;
-
- case sfx_podth1:
- case sfx_podth2:
- case sfx_podth3:
- sound = sfx_podth1 + P_Random ()%3;
- break;
-
- case sfx_bgdth1:
- case sfx_bgdth2:
- sound = sfx_bgdth1 + P_Random ()%2;
- break;
-
- default:
- sound = actor->info->deathsound;
- break;
- }
-
- if (actor->type==MT_SPIDER
- || actor->type == MT_CYBORG)
- {
-
- S_StartSound (NULL, sound);
- }
- else
- S_StartSound (actor, sound);
- }
- void A_XScream (mobj_t* actor, void * )
- {
- S_StartSound (actor, sfx_slop);
- }
- void A_Pain (mobj_t* actor, void * )
- {
- if (actor->info->painsound )
- S_StartSound (actor, actor->info->painsound);
- }
- void A_Fall (mobj_t *actor, void * )
- {
-
- actor->flags &= ~MF_SOLID;
-
-
- }
- void A_Explode (mobj_t* thingy, void * )
- {
- P_RadiusAttack ( thingy, thingy->target, 128 );
- }
- void A_BossDeath (mobj_t* mo, void * )
- {
- thinker_t* th;
- mobj_t* mo2;
- line_t junk;
- int i;
-
- if ( ::g->gamemode == commercial)
- {
- if (::g->gamemap != 7)
- return;
-
- if ((mo->type != MT_FATSO)
- && (mo->type != MT_BABY))
- return;
- }
- else
- {
- switch(::g->gameepisode)
- {
- case 1:
- if (::g->gamemap != 8)
- return;
- if (mo->type != MT_BRUISER)
- return;
- break;
-
- case 2:
- if (::g->gamemap != 8)
- return;
- if (mo->type != MT_CYBORG)
- return;
- break;
-
- case 3:
- if (::g->gamemap != 8)
- return;
-
- if (mo->type != MT_SPIDER)
- return;
-
- break;
-
- case 4:
- switch(::g->gamemap)
- {
- case 6:
- if (mo->type != MT_CYBORG)
- return;
- break;
-
- case 8:
- if (mo->type != MT_SPIDER)
- return;
- break;
-
- default:
- return;
- break;
- }
- break;
-
- default:
- if (::g->gamemap != 8)
- return;
- break;
- }
-
- }
-
-
- for (i=0 ; i<MAXPLAYERS ; i++)
- if (::g->playeringame[i] && ::g->players[i].health > 0)
- break;
-
- if (i==MAXPLAYERS)
- return;
-
-
-
- for (th = ::g->thinkercap.next ; th != &::g->thinkercap ; th=th->next)
- {
- if (th->function.acp1 != (actionf_p1)P_MobjThinker)
- continue;
-
- mo2 = (mobj_t *)th;
- if (mo2 != mo
- && mo2->type == mo->type
- && mo2->health > 0)
- {
-
- return;
- }
- }
-
-
- if ( ::g->gamemode == commercial)
- {
- if (::g->gamemap == 7)
- {
- if (mo->type == MT_FATSO)
- {
- junk.tag = 666;
- EV_DoFloor(&junk,lowerFloorToLowest);
- return;
- }
-
- if (mo->type == MT_BABY)
- {
- junk.tag = 667;
- EV_DoFloor(&junk,raiseToTexture);
- return;
- }
- }
- }
- else
- {
- switch(::g->gameepisode)
- {
- case 1:
- junk.tag = 666;
- EV_DoFloor (&junk, lowerFloorToLowest);
- return;
- break;
-
- case 4:
- switch(::g->gamemap)
- {
- case 6:
- junk.tag = 666;
- EV_DoDoor (&junk, blazeOpen);
- return;
- break;
-
- case 8:
- junk.tag = 666;
- EV_DoFloor (&junk, lowerFloorToLowest);
- return;
- break;
- }
- }
- }
-
- G_ExitLevel ();
- }
- void A_Hoof (mobj_t* mo, void * )
- {
- S_StartSound (mo, sfx_hoof);
- A_Chase (mo, 0);
- }
- void A_Metal (mobj_t* mo, void * )
- {
- S_StartSound (mo, sfx_metal);
- A_Chase (mo, 0);
- }
- void A_BabyMetal (mobj_t* mo, void * )
- {
- S_StartSound (mo, sfx_bspwlk);
- A_Chase (mo, 0);
- }
- void
- A_OpenShotgun2
- ( player_t* player,
- pspdef_t* psp )
- {
- if (globalNetworking || (player == &::g->players[::g->consoleplayer]))
- S_StartSound (player->mo, sfx_dbopn);
- }
- void
- A_LoadShotgun2
- ( player_t* player,
- pspdef_t* psp )
- {
- if (globalNetworking || (player == &::g->players[::g->consoleplayer]))
- S_StartSound (player->mo, sfx_dbload);
- }
- void
- A_ReFire
- ( player_t* player,
- pspdef_t* psp );
- void
- A_CloseShotgun2
- ( player_t* player,
- pspdef_t* psp )
- {
- if (globalNetworking || (player == &::g->players[::g->consoleplayer]))
- S_StartSound (player->mo, sfx_dbcls);
- A_ReFire(player,psp);
- }
- void A_BrainAwake (mobj_t* mo, void * )
- {
- thinker_t* thinker;
- mobj_t* m;
-
-
- ::g->easy = 0;
- ::g->numbraintargets = 0;
- ::g->braintargeton = 0;
-
- thinker = ::g->thinkercap.next;
- for (thinker = ::g->thinkercap.next ;
- thinker != &::g->thinkercap ;
- thinker = thinker->next)
- {
- if (thinker->function.acp1 != (actionf_p1)P_MobjThinker)
- continue;
- m = (mobj_t *)thinker;
- if (m->type == MT_BOSSTARGET )
- {
- ::g->braintargets[::g->numbraintargets] = m;
- ::g->numbraintargets++;
- }
- }
-
- S_StartSound (NULL,sfx_bossit);
- }
- void A_BrainPain (mobj_t* mo, void * )
- {
- S_StartSound (NULL,sfx_bospn);
- }
- void A_BrainScream (mobj_t* mo, void * )
- {
- int x;
- int y;
- int z;
- mobj_t* th;
-
- for (x=mo->x - 196*FRACUNIT ; x< mo->x + 320*FRACUNIT ; x+= FRACUNIT*8)
- {
- y = mo->y - 320*FRACUNIT;
- z = 128 + P_Random()*2*FRACUNIT;
- th = P_SpawnMobj (x,y,z, MT_ROCKET);
- th->momz = P_Random()*512;
- P_SetMobjState (th, S_BRAINEXPLODE1);
- th->tics -= P_Random()&7;
- if (th->tics < 1)
- th->tics = 1;
- }
-
- S_StartSound (NULL,sfx_bosdth);
- }
- void A_BrainExplode (mobj_t* mo, void * )
- {
- int x;
- int y;
- int z;
- mobj_t* th;
-
- x = mo->x + (P_Random () - P_Random ())*2048;
- y = mo->y;
- z = 128 + P_Random()*2*FRACUNIT;
- th = P_SpawnMobj (x,y,z, MT_ROCKET);
- th->momz = P_Random()*512;
- P_SetMobjState (th, S_BRAINEXPLODE1);
- th->tics -= P_Random()&7;
- if (th->tics < 1)
- th->tics = 1;
- }
- void A_BrainDie (mobj_t* mo, void * )
- {
- G_ExitLevel ();
- }
- void A_BrainSpit (mobj_t* mo, void * )
- {
- mobj_t* targ;
- mobj_t* newmobj;
- ::g->easy ^= 1;
- if (::g->gameskill <= sk_easy && (!::g->easy))
- return;
- if ( 1 ) {
-
- int numCorpse = 0;
- int numEnemies = 0;
- for ( thinker_t* th = ::g->thinkercap.next; th != &::g->thinkercap; th = th->next ) {
- if ( th->function.acp1 == (actionf_p1)P_MobjThinker ) {
- mobj_t* obj = (mobj_t*)th;
- if ( obj->flags & MF_CORPSE ) {
- numCorpse++;
- }
- else if ( obj->type > MT_PLAYER && obj->type < MT_KEEN ) {
- numEnemies++;
- }
- }
- }
- if ( numCorpse > 48 ) {
- for ( int i = 0; i < 12; i++ ) {
- for ( thinker_t* th = ::g->thinkercap.next; th != &::g->thinkercap; th = th->next ) {
- if ( th->function.acp1 == (actionf_p1)P_MobjThinker ) {
- mobj_t* obj = (mobj_t*)th;
- if ( obj->flags & MF_CORPSE ) {
- P_RemoveMobj( obj );
- break;
- }
- }
- }
- }
- }
- if ( numEnemies > 32 ) {
- return;
- }
- }
-
- targ = ::g->braintargets[::g->braintargeton];
- ::g->braintargeton = (::g->braintargeton+1) % ::g->numbraintargets;
-
- newmobj = P_SpawnMissile (mo, targ, MT_SPAWNSHOT);
- newmobj->target = targ;
- newmobj->reactiontime =
- ((targ->y - mo->y)/newmobj->momy) / newmobj->state->tics;
- S_StartSound(NULL, sfx_bospit);
- }
- void A_SpawnFly (mobj_t* mo, void * );
- void A_SpawnSound (mobj_t* mo, void * )
- {
- S_StartSound (mo,sfx_boscub);
- A_SpawnFly(mo, 0);
- }
- void A_SpawnFly (mobj_t* mo, void * )
- {
- mobj_t* newmobj;
- mobj_t* fog;
- mobj_t* targ;
- int r;
- mobjtype_t type;
-
- if (--mo->reactiontime)
- return;
-
- targ = mo->target;
-
- fog = P_SpawnMobj (targ->x, targ->y, targ->z, MT_SPAWNFIRE);
- S_StartSound (fog, sfx_telept);
-
- r = P_Random ();
-
-
- if ( r<50 )
- type = MT_TROOP;
- else if (r<90)
- type = MT_SERGEANT;
- else if (r<120)
- type = MT_SHADOWS;
- else if (r<130)
- type = MT_PAIN;
- else if (r<160)
- type = MT_HEAD;
- else if (r<162)
- type = MT_VILE;
- else if (r<172)
- type = MT_UNDEAD;
- else if (r<192)
- type = MT_BABY;
- else if (r<222)
- type = MT_FATSO;
- else if (r<246)
- type = MT_KNIGHT;
- else
- type = MT_BRUISER;
- newmobj = P_SpawnMobj (targ->x, targ->y, targ->z, type);
- if (P_LookForPlayers (newmobj, true) )
- P_SetMobjState (newmobj, (statenum_t)newmobj->info->seestate);
-
-
- P_TeleportMove (newmobj, newmobj->x, newmobj->y);
-
- P_RemoveMobj (mo);
- }
- void A_PlayerScream (mobj_t* mo, void * )
- {
-
- int sound = sfx_pldeth;
-
- if ( (::g->gamemode == commercial)
- && (mo->health < -50))
- {
-
-
- sound = sfx_pdiehi;
- }
-
- if ( ::g->demoplayback || globalNetworking || (mo == ::g->players[::g->consoleplayer].mo))
- S_StartSound (mo, sound);
- }
- };
|