mirror of
https://github.com/ZDoom/Raze.git
synced 2025-02-08 15:52:00 +00:00
* Since all code is included in `all.cpp`, several identically named static functions have been renamed to avoid conflicts.
332 lines
7.2 KiB
C++
332 lines
7.2 KiB
C++
#include "ns.h"
|
|
#include "wh.h"
|
|
|
|
BEGIN_WH_NS
|
|
|
|
static void checkexplfred(PLAYER& plr, short i);
|
|
|
|
|
|
static void chasefred(PLAYER& plr, short i) {
|
|
SPRITE& spr = sprite[i];
|
|
spr.lotag -= TICSPERFRAME;
|
|
if (spr.lotag < 0)
|
|
spr.lotag = 250;
|
|
|
|
short osectnum = spr.sectnum;
|
|
if (cansee(plr.x, plr.y, plr.z, plr.sector, spr.x, spr.y, spr.z - (tileHeight(spr.picnum) << 7),
|
|
spr.sectnum) && plr.invisibletime < 0) {
|
|
if (checkdist(plr, i)) {
|
|
if (plr.shadowtime > 0) {
|
|
spr.ang = (short)(((krand() & 512 - 256) + spr.ang + 1024) & 2047);
|
|
newstatus(i, FLEE);
|
|
}
|
|
else
|
|
newstatus(i, ATTACK);
|
|
}
|
|
else if (krand() % 63 > 60) {
|
|
spr.ang = (short)(((krand() & 128 - 256) + spr.ang + 1024) & 2047);
|
|
newstatus(i, FLEE);
|
|
}
|
|
else {
|
|
int movestat = aimove(i);
|
|
|
|
if ((movestat & kHitTypeMask) == kHitSprite) {
|
|
if ((movestat & kHitIndexMask) != plr.spritenum) {
|
|
short daang = (short)((spr.ang - 256) & 2047);
|
|
spr.ang = daang;
|
|
if (plr.shadowtime > 0) {
|
|
spr.ang = (short)(((krand() & 512 - 256) + spr.ang + 1024) & 2047);
|
|
newstatus(i, FLEE);
|
|
}
|
|
else
|
|
newstatus(i, SKIRMISH);
|
|
}
|
|
else {
|
|
spr.ang = (short)(((krand() & 512 - 256) + spr.ang + 1024) & 2047);
|
|
newstatus(i, SKIRMISH);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
spr.ang = (short)(((krand() & 512 - 256) + spr.ang + 1024) & 2047);
|
|
newstatus(i, FLEE);
|
|
}
|
|
|
|
getzrange(spr.x, spr.y, spr.z - 1, spr.sectnum, (spr.clipdist) << 2, CLIPMASK0);
|
|
if ((spr.sectnum != osectnum) && (sector[spr.sectnum].lotag == 10))
|
|
warpsprite(i);
|
|
|
|
if (checksector6(i))
|
|
return;
|
|
|
|
processfluid(i, zr_florhit, false);
|
|
|
|
if (sector[osectnum].lotag == KILLSECTOR) {
|
|
spr.hitag--;
|
|
if (spr.hitag < 0)
|
|
newstatus(i, DIE);
|
|
}
|
|
|
|
setsprite(i, spr.x, spr.y, spr.z);
|
|
|
|
if ((zr_florhit & kHitTypeMask) == kHitSector && (sector[spr.sectnum].floorpicnum == LAVA
|
|
|| sector[spr.sectnum].floorpicnum == LAVA1 || sector[spr.sectnum].floorpicnum == ANILAVA)) {
|
|
spr.hitag--;
|
|
if (spr.hitag < 0)
|
|
newstatus(i, DIE);
|
|
}
|
|
|
|
checkexplfred(plr, i);
|
|
}
|
|
|
|
static void skirmishfred(PLAYER& plr, short i) {
|
|
SPRITE& spr = sprite[i];
|
|
|
|
spr.lotag -= TICSPERFRAME;
|
|
|
|
if (spr.lotag < 0)
|
|
newstatus(i, FACE);
|
|
short osectnum = spr.sectnum;
|
|
if (aimove(i) != 0) {
|
|
spr.ang = getangle(plr.x - spr.x, plr.y - spr.y);
|
|
newstatus(i, FACE);
|
|
}
|
|
if ((spr.sectnum != osectnum) && (sector[spr.sectnum].lotag == 10))
|
|
warpsprite(i);
|
|
|
|
processfluid(i, zr_florhit, false);
|
|
|
|
setsprite(i, spr.x, spr.y, spr.z);
|
|
|
|
if (checksector6(i))
|
|
return;
|
|
|
|
checkexplfred(plr, i);
|
|
}
|
|
|
|
static void diefred(PLAYER& plr, short i) {
|
|
SPRITE& spr = sprite[i];
|
|
spr.lotag -= TICSPERFRAME;
|
|
|
|
if (spr.lotag <= 0) {
|
|
spr.picnum++;
|
|
spr.lotag = 20;
|
|
|
|
if (spr.picnum == FREDDEAD) {
|
|
if (difficulty == 4)
|
|
newstatus(i, RESURECT);
|
|
else {
|
|
kills++;
|
|
newstatus(i, DEAD);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void searchfred(PLAYER& plr, short i) {
|
|
aisearch(plr, i, false);
|
|
if (!checksector6(i))
|
|
checkexplfred(plr, i);
|
|
}
|
|
|
|
static void frozenfred(PLAYER& plr, short i) {
|
|
SPRITE& spr = sprite[i];
|
|
|
|
spr.lotag -= TICSPERFRAME;
|
|
if (spr.lotag < 0) {
|
|
spr.pal = 0;
|
|
spr.picnum = FRED;
|
|
newstatus(i, FACE);
|
|
}
|
|
}
|
|
|
|
static void facefred(PLAYER& plr, short i) {
|
|
SPRITE& spr = sprite[i];
|
|
|
|
|
|
boolean cansee = ::cansee(plr.x, plr.y, plr.z, plr.sector, spr.x, spr.y, spr.z - (tileHeight(spr.picnum) << 7),
|
|
spr.sectnum);
|
|
|
|
if (cansee && plr.invisibletime < 0) {
|
|
spr.ang = (short)(getangle(plr.x - spr.x, plr.y - spr.y) & 2047);
|
|
|
|
if (plr.shadowtime > 0) {
|
|
spr.ang = (short)(((krand() & 512 - 256) + spr.ang + 1024) & 2047);
|
|
newstatus(i, FLEE);
|
|
}
|
|
else {
|
|
spr.owner = plr.spritenum;
|
|
newstatus(i, CHASE);
|
|
}
|
|
}
|
|
else { // get off the wall
|
|
if (spr.owner == plr.spritenum) {
|
|
spr.ang = (short)(((krand() & 512 - 256) + spr.ang) & 2047);
|
|
newstatus(i, FINDME);
|
|
}
|
|
else if (cansee) newstatus(i, FLEE);
|
|
}
|
|
|
|
if (checkdist(plr, i))
|
|
newstatus(i, ATTACK);
|
|
|
|
checkexplfred(plr, i);
|
|
}
|
|
|
|
static void attackfred(PLAYER& plr, short i) {
|
|
SPRITE& spr = sprite[i];
|
|
|
|
getzrange(spr.x, spr.y, spr.z - 1, spr.sectnum, (spr.clipdist) << 2, CLIPMASK0);
|
|
spr.z = zr_florz;
|
|
|
|
switch (checkfluid(i, zr_florhit)) {
|
|
case TYPELAVA:
|
|
sprite[i].hitag--;
|
|
if (sprite[i].hitag < 0)
|
|
newstatus(i, DIE);
|
|
case TYPEWATER:
|
|
spr.z += tileHeight(spr.picnum) << 5;
|
|
break;
|
|
}
|
|
|
|
setsprite(i, spr.x, spr.y, spr.z);
|
|
|
|
if (spr.lotag >= 64) {
|
|
if (checksight(plr, i))
|
|
if (checkdist(plr, i)) {
|
|
spr.ang = (short)checksight_ang;
|
|
attack(plr, i);
|
|
}
|
|
}
|
|
else if (spr.lotag < 0) {
|
|
if (plr.shadowtime > 0) {
|
|
spr.ang = (short)(((krand() & 512 - 256) + spr.ang + 1024) & 2047); // NEW
|
|
newstatus(i, FLEE);
|
|
}
|
|
else
|
|
newstatus(i, CHASE);
|
|
}
|
|
spr.lotag -= TICSPERFRAME;
|
|
|
|
checksector6(i);
|
|
}
|
|
|
|
static void fleefred(PLAYER& plr, short i) {
|
|
SPRITE& spr = sprite[i];
|
|
spr.lotag -= TICSPERFRAME;
|
|
short osectnum = spr.sectnum;
|
|
|
|
int movestat = aimove(i);
|
|
|
|
if (movestat != 0) {
|
|
if ((movestat & kHitTypeMask) == kHitWall) {
|
|
int nWall = movestat & kHitIndexMask;
|
|
int nx = -(wall[wall[nWall].point2].y - wall[nWall].y) >> 4;
|
|
int ny = (wall[wall[nWall].point2].x - wall[nWall].x) >> 4;
|
|
spr.ang = getangle(nx, ny);
|
|
}
|
|
else {
|
|
spr.ang = getangle(plr.x - spr.x, plr.y - spr.y);
|
|
newstatus(i, FACE);
|
|
}
|
|
}
|
|
if (spr.lotag < 0)
|
|
newstatus(i, FACE);
|
|
|
|
if ((spr.sectnum != osectnum) && (sector[spr.sectnum].lotag == 10))
|
|
warpsprite(i);
|
|
|
|
if (checksector6(i))
|
|
return;
|
|
|
|
processfluid(i, zr_florhit, false);
|
|
|
|
setsprite(i, spr.x, spr.y, spr.z);
|
|
|
|
checkexplfred(plr, i);
|
|
}
|
|
|
|
static void painfred(PLAYER& plr, short i) {
|
|
SPRITE& spr = sprite[i];
|
|
spr.lotag -= TICSPERFRAME;
|
|
if (spr.lotag < 0) {
|
|
spr.picnum = FRED;
|
|
spr.ang = plr.angle.ang.asbuild();
|
|
newstatus(i, FLEE);
|
|
}
|
|
|
|
aimove(i);
|
|
processfluid(i, zr_florhit, false);
|
|
setsprite(i, spr.x, spr.y, spr.z);
|
|
|
|
checkexplfred(plr, i);
|
|
}
|
|
|
|
static void resurectfred(PLAYER& plr, short i) {
|
|
SPRITE& spr = sprite[i];
|
|
|
|
spr.lotag -= TICSPERFRAME;
|
|
if (spr.lotag < 0) {
|
|
newstatus(i, FACE);
|
|
spr.picnum = FRED;
|
|
spr.hitag = (short)adjusthp(40);
|
|
spr.lotag = 100;
|
|
spr.cstat |= 1;
|
|
}
|
|
}
|
|
|
|
static void checkexplfred(PLAYER& plr, short i) {
|
|
SPRITE& spr = sprite[i];
|
|
short j = headspritesect[spr.sectnum];
|
|
while (j != -1) {
|
|
short nextj = nextspritesect[j];
|
|
int dx = abs(spr.x - sprite[j].x); // x distance to sprite
|
|
int dy = abs(spr.y - sprite[j].y); // y distance to sprite
|
|
int dz = abs((spr.z >> 8) - (sprite[j].z >> 8)); // z distance to sprite
|
|
int dh = tileHeight(sprite[j].picnum) >> 1; // height of sprite
|
|
if (dx + dy < PICKDISTANCE && dz - dh <= getPickHeight()) {
|
|
if (sprite[j].picnum == EXPLO2
|
|
|| sprite[j].picnum == SMOKEFX
|
|
|| sprite[j].picnum == MONSTERBALL) {
|
|
spr.hitag -= TICSPERFRAME << 2;
|
|
if (spr.hitag < 0) {
|
|
newstatus(i, DIE);
|
|
}
|
|
}
|
|
}
|
|
j = nextj;
|
|
}
|
|
}
|
|
|
|
void createFredAI() {
|
|
auto &e = enemy[FREDTYPE];
|
|
e.info.Init(48, 48, 1024 + 256, 120, 0, 64, false, 40, 0);
|
|
e.chase = chasefred;
|
|
e.skirmish = skirmishfred;
|
|
e.die = diefred;
|
|
e.search = searchfred;
|
|
e.frozen = frozenfred;
|
|
e.face = facefred;
|
|
e.attack = attackfred;
|
|
e.flee = fleefred;
|
|
e.pain = painfred;
|
|
e.resurect = resurectfred;
|
|
}
|
|
|
|
|
|
void premapFred(short i) {
|
|
SPRITE& spr = sprite[i];
|
|
if (spr.picnum == FRED && spr.pal == 1) {
|
|
deletesprite(i);
|
|
return;
|
|
}
|
|
spr.detail = FREDTYPE;
|
|
changespritestat(i, FACE);
|
|
enemy[FREDTYPE].info.set(spr);
|
|
|
|
if (krand() % 100 > 50)
|
|
spr.extra = 1;
|
|
}
|
|
|
|
END_WH_NS
|