Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Iskhodnyy_kod_Doom

.pdf
Скачиваний:
7
Добавлен:
13.02.2015
Размер:
1.01 Mб
Скачать

// modify target threshold if (actor->threshold)

{

if (!actor->target

|| actor->target->health <= 0)

{

actor->threshold = 0;

}

else

actor->threshold--;

}

// 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))

 

return;

// got a new target

P_SetMobjState (actor, actor->info->spawnstate); return;

}

// do not attack twice in a row

if (actor->flags & MF_JUSTATTACKED)

{

actor->flags &= ~MF_JUSTATTACKED;

if (gameskill != sk_nightmare && !fastparm) 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;

}

// check for missile attack

if (actor->info->missilestate)

{

if (gameskill < sk_nightmare

&& !fastparm && actor->movecount)

{

goto nomissile;

}

if (!P_CheckMissileRange (actor))

391

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

}

//chase towards player if (--actor->movecount<0

||!P_Move (actor))

{

P_NewChaseDir (actor);

}

//make active sound

if (actor->info->activesound && P_Random () < 3)

{

S_StartSound (actor, actor->info->activesound);

}

}

//

// A_FaceTarget

//

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) actor->angle += (P_Random()-P_Random())<<21;

}

//

// A_PosAttack

//

void A_PosAttack (mobj_t* actor)

{

int

angle;

int

damage;

int

slope;

if (!actor->target)

 

return;

 

392

A_FaceTarget (actor); 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)

{

 

int

i;

int

angle;

int

bangle;

int

damage;

int

slope;

if (!actor->target)

 

return;

 

S_StartSound (actor, sfx_shotgn);

A_FaceTarget (actor);

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)

{

 

int

angle;

int

bangle;

int

damage;

int

slope;

if (!actor->target) return;

S_StartSound (actor, sfx_shotgn);

A_FaceTarget (actor);

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)

{

// keep firing unless target got out of sight A_FaceTarget (actor);

if (P_Random () < 40) return;

if (!actor->target

|| actor->target->health <= 0

393

|| !P_CheckSight (actor, actor->target) )

{

P_SetMobjState (actor, actor->info->seestate);

}

}

void A_SpidRefire (mobj_t* actor)

{

// keep firing unless target got out of sight A_FaceTarget (actor);

if (P_Random () < 10) return;

if (!actor->target

||actor->target->health <= 0

||!P_CheckSight (actor, actor->target) )

{

P_SetMobjState (actor, actor->info->seestate);

}

}

void A_BspiAttack (mobj_t *actor)

{

if (!actor->target) return;

A_FaceTarget (actor);

// launch a missile

P_SpawnMissile (actor, actor->target, MT_ARACHPLAZ);

}

//

// A_TroopAttack

//

void A_TroopAttack (mobj_t* actor)

{

int

damage;

if (!actor->target) return;

A_FaceTarget (actor);

if (P_CheckMeleeRange (actor))

{

S_StartSound (actor, sfx_claw); damage = (P_Random()%8+1)*3;

P_DamageMobj (actor->target, actor, actor, damage); return;

}

// launch a missile

P_SpawnMissile (actor, actor->target, MT_TROOPSHOT);

}

void A_SargAttack (mobj_t* actor)

{

int

damage;

if (!actor->target)

394

return;

A_FaceTarget (actor);

if (P_CheckMeleeRange (actor))

{

 

damage = ((P_Random()%10)+1)*4;

 

P_DamageMobj (actor->target, actor, actor, damage);

}

 

}

 

void A_HeadAttack (mobj_t* actor)

{

 

int

damage;

if (!actor->target) return;

A_FaceTarget (actor);

if (P_CheckMeleeRange (actor))

{

damage = (P_Random()%6+1)*10;

P_DamageMobj (actor->target, actor, actor, damage); return;

}

// launch a missile

P_SpawnMissile (actor, actor->target, MT_HEADSHOT);

}

void A_CyberAttack (mobj_t* actor)

{

if (!actor->target) return;

A_FaceTarget (actor);

P_SpawnMissile (actor, actor->target, MT_ROCKET);

}

void A_BruisAttack (mobj_t* actor)

{

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;

}

// launch a missile

P_SpawnMissile (actor, actor->target, MT_BRUISERSHOT);

}

//

// A_SkelMissile

//

void A_SkelMissile (mobj_t* actor)

{

mobj_t* mo;

395

if (!actor->target)

return;

 

A_FaceTarget (actor);

 

actor->z += 16*FRACUNIT;

// so missile spawns higher

mo = P_SpawnMissile (actor, actor->target, MT_TRACER);

actor->z -= 16*FRACUNIT;

// back to normal

mo->x += mo->momx;

 

mo->y += mo->momy;

 

mo->tracer = actor->target;

 

}

 

 

int

TRACEANGLE = 0xc000000;

 

void A_Tracer (mobj_t* actor)

 

{

 

 

angle_t

exact;

 

fixed_t

dist;

 

fixed_t

slope;

 

mobj_t*

dest;

 

mobj_t*

th;

 

if (gametic & 3) return;

// spawn a puff of smoke behind the rocket 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;

// adjust direction dest = actor->tracer;

if (!dest || dest->health <= 0) return;

// change angle

exact = R_PointToAngle2 (actor->x, actor->y, dest->x, dest->y);

if (exact != actor->angle)

{

if (exact - actor->angle > 0x80000000)

{

actor->angle -= TRACEANGLE;

if (exact - actor->angle < 0x80000000) actor->angle = exact;

}

else

{

actor->angle += TRACEANGLE;

if (exact - actor->angle > 0x80000000) actor->angle = exact;

}

396

}

exact = actor->angle>>ANGLETOFINESHIFT;

actor->momx = FixedMul (actor->info->speed, finecosine[exact]); actor->momy = FixedMul (actor->info->speed, finesine[exact]);

// change slope

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)

{

 

if (!actor->target) return;

A_FaceTarget (actor);

S_StartSound (actor,sfx_skeswg);

}

void A_SkelFist (mobj_t*

actor)

{

 

 

int

damage;

 

if (!actor->target) return;

A_FaceTarget (actor);

if (P_CheckMeleeRange (actor))

{

damage = ((P_Random()%10)+1)*6; S_StartSound (actor, sfx_skepch);

P_DamageMobj (actor->target, actor, actor, damage);

}

}

//

//PIT_VileCheck

//Detect a corpse that could be raised.

mobj_t*

corpsehit;

 

mobj_t*

vileobj;

 

fixed_t

viletryx;

 

fixed_t

viletryy;

 

boolean PIT_VileCheck (mobj_t*

thing)

{

 

 

int

maxdist;

 

boolean

check;

 

if (!(thing->flags & MF_CORPSE) )

397

return true;

// not

a monster

if (thing->tics != -1)

 

 

return true;

// not

lying still yet

if (thing->info->raisestate ==

S_NULL)

return true;

// monster doesn’t have a raise state

maxdist = thing->info->radius + mobjinfo[MT_VILE].radius;

if ( abs(thing->x

- viletryx) > maxdist

|| abs(thing->y - viletryy) > maxdist )

return true;

// not actually touching

corpsehit = thing;

 

corpsehit->momx =

corpsehit->momy = 0;

corpsehit->height

<<= 2;

check = P_CheckPosition (corpsehit, corpsehit->x, corpsehit->y); corpsehit->height >>= 2;

if (!check)

 

return true;

// doesn’t fit here

return false;

// got one, so stop checking

}

//

//A_VileChase

//Check for ressurecting a body

void A_VileChase (mobj_t* actor)

{

int

xl;

int

xh;

int

yl;

int

yh;

int

bx;

int

by;

mobjinfo_t*

info;

mobj_t*

temp;

if (actor->movedir != DI_NODIR)

{

// check for corpses to raise viletryx =

actor->x + actor->info->speed*xspeed[actor->movedir]; viletryy =

actor->y + actor->info->speed*yspeed[actor->movedir];

xl = (viletryx - bmaporgx - MAXRADIUS*2)>>MAPBLOCKSHIFT; xh = (viletryx - bmaporgx + MAXRADIUS*2)>>MAPBLOCKSHIFT; yl = (viletryy - bmaporgy - MAXRADIUS*2)>>MAPBLOCKSHIFT; yh = (viletryy - bmaporgy + MAXRADIUS*2)>>MAPBLOCKSHIFT;

vileobj = actor;

for (bx=xl ; bx<=xh ; bx++)

{

for (by=yl ; by<=yh ; by++)

{

//Call PIT_VileCheck to check

//whether object is a corpse

398

// that canbe raised.

if (!P_BlockThingsIterator(bx,by,PIT_VileCheck))

{

// got one!

temp = actor->target; actor->target = corpsehit; A_FaceTarget (actor); actor->target = temp;

P_SetMobjState (actor, S_VILE_HEAL1); S_StartSound (corpsehit, sfx_slop); info = corpsehit->info;

P_SetMobjState (corpsehit,info->raisestate); corpsehit->height <<= 2;

corpsehit->flags = info->flags; corpsehit->health = info->spawnhealth; corpsehit->target = NULL;

return;

}

}

}

}

// Return to normal attack. A_Chase (actor);

}

//

// A_VileStart

//

void A_VileStart (mobj_t* actor)

{

S_StartSound (actor, sfx_vilatk);

}

//

//A_Fire

//Keep fire in front of player unless out of sight

void A_Fire (mobj_t* actor);

void A_StartFire (mobj_t* actor)

{

S_StartSound(actor,sfx_flamst);

A_Fire(actor);

}

void A_FireCrackle (mobj_t* actor)

{

S_StartSound(actor,sfx_flame);

A_Fire(actor);

}

void A_Fire (mobj_t* actor)

{

mobj_t* dest; unsigned an;

dest = actor->tracer; if (!dest)

return;

399

// don’t move it if the vile lost sight 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);

}

//

//A_VileTarget

//Spawn the hellfire

void A_VileTarget (mobj_t*

actor)

{

 

 

mobj_t*

fog;

 

if (!actor->target) return;

A_FaceTarget (actor);

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);

}

//

// A_VileAttack

//

void A_VileAttack (mobj_t* actor)

{

mobj_t*

fire;

int

an;

if (!actor->target) return;

A_FaceTarget (actor);

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;

400

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]