mirror of
https://github.com/ZDoom/Raze.git
synced 2025-03-13 04:24:39 +00:00
- importing Witchaven code from GDX
This is a straight port of the GDX Java code to C++ with as few changes made as possible. Part 1: AI code.
This commit is contained in:
parent
c93b8f3e54
commit
96637a25d1
34 changed files with 10861 additions and 0 deletions
|
@ -1339,3 +1339,4 @@ add_subdirectory( games/duke )
|
|||
add_subdirectory( blood )
|
||||
add_subdirectory( sw )
|
||||
add_subdirectory( exhumed )
|
||||
add_subdirectory( games/whaven )
|
||||
|
|
|
@ -20,6 +20,9 @@
|
|||
#define BEGIN_PS_NS namespace Exhumed {
|
||||
#define END_PS_NS }
|
||||
|
||||
#define BEGIN_WH_NS namespace Witchaven {
|
||||
#define END_WH_NS }
|
||||
|
||||
#else
|
||||
|
||||
#define BEGIN_EDUKE_NS
|
||||
|
|
31
source/games/whaven/CMakeLists.txt
Normal file
31
source/games/whaven/CMakeLists.txt
Normal file
|
@ -0,0 +1,31 @@
|
|||
|
||||
set( PCH_SOURCES
|
||||
src/ai.cpp
|
||||
src/aidemon.cpp
|
||||
src/aidevil.cpp
|
||||
src/aidragon.cpp
|
||||
src/aifatwitch.cpp
|
||||
src/aifish.cpp
|
||||
src/aifred.cpp
|
||||
src/aigoblin.cpp
|
||||
src/aigonzo.cpp
|
||||
src/aigron.cpp
|
||||
src/aiguardian.cpp
|
||||
src/aiimp.cpp
|
||||
src/aijudy.cpp
|
||||
src/aikatie.cpp
|
||||
src/aikobold.cpp
|
||||
src/aikurt.cpp
|
||||
src/aiminotaur.cpp
|
||||
src/ainewguy.cpp
|
||||
src/airat.cpp
|
||||
src/aiskeleton.cpp
|
||||
src/aiskully.cpp
|
||||
src/aispider.cpp
|
||||
src/aiwillow.cpp
|
||||
src/names.cpp
|
||||
)
|
||||
|
||||
add_game_library2( whaven )
|
||||
|
||||
include_directories( src )
|
1213
source/games/whaven/src/ai.cpp
Normal file
1213
source/games/whaven/src/ai.cpp
Normal file
File diff suppressed because it is too large
Load diff
142
source/games/whaven/src/ai.h
Normal file
142
source/games/whaven/src/ai.h
Normal file
|
@ -0,0 +1,142 @@
|
|||
#pragma once
|
||||
#include "wh.h"
|
||||
|
||||
BEGIN_WH_NS
|
||||
|
||||
struct EnemyInfo
|
||||
{
|
||||
short sizx, sizy;
|
||||
int attackdist;
|
||||
int attackdamage;
|
||||
int attackheight;
|
||||
short health;
|
||||
bool fly;
|
||||
int clipdist;
|
||||
int score;
|
||||
|
||||
void Init(int sizx, int sizy, int dist, int height, int damage, int clipdist, bool fly, int health, int score)
|
||||
{
|
||||
this->sizx = (short) sizx;
|
||||
this->sizy = (short) sizy;
|
||||
this->attackdist = dist;
|
||||
this->attackheight = height;
|
||||
this->attackdamage = damage;
|
||||
this->clipdist = clipdist;
|
||||
this->fly = fly;
|
||||
this->health = (short) health;
|
||||
this->score = score;
|
||||
}
|
||||
|
||||
short (*getHealth)(EnemyInfo& e, SPRITE& spr) = [](EnemyInfo& e, SPRITE& spr)
|
||||
{
|
||||
return adjusthp(e.health);
|
||||
};
|
||||
|
||||
int (*getAttackDist)(EnemyInfo& e, SPRITE& spr) = [](EnemyInfo &e, SPRITE& spr)
|
||||
{
|
||||
return e.attackdist;
|
||||
};
|
||||
|
||||
void set(SPRITE &spr)
|
||||
{
|
||||
spr.clipdist = clipdist;
|
||||
spr.hitag = getHealth(*this, spr);
|
||||
if(sizx != -1)
|
||||
spr.xrepeat = sizx;
|
||||
if(sizy != -1)
|
||||
spr.yrepeat = sizy;
|
||||
spr.lotag = 100;
|
||||
|
||||
int tflag = 0;
|
||||
if((spr.cstat & 514) != 0)
|
||||
tflag = spr.cstat & 514;
|
||||
|
||||
spr.cstat = (short) (0x101 | tflag);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
using AIState = void (*)(PLAYER &plr, short i);
|
||||
|
||||
|
||||
struct Enemy
|
||||
{
|
||||
EnemyInfo info;
|
||||
|
||||
AIState patrol;
|
||||
AIState chase;
|
||||
AIState resurect;
|
||||
AIState nuked;
|
||||
AIState frozen;
|
||||
AIState pain;
|
||||
AIState face;
|
||||
AIState attack;
|
||||
AIState flee;
|
||||
AIState cast;
|
||||
AIState die;
|
||||
AIState skirmish;
|
||||
AIState stand;
|
||||
AIState search;
|
||||
};
|
||||
|
||||
|
||||
enum EEnemy
|
||||
{
|
||||
DEMONTYPE = 1, // ok
|
||||
DEVILTYPE = 2, // nuked ok, frozen no
|
||||
DRAGONTYPE = 3, // wh1
|
||||
FATWITCHTYPE = 4, // wh1
|
||||
FISHTYPE = 5,
|
||||
FREDTYPE = 6,
|
||||
GOBLINTYPE = 7, // wh1
|
||||
GONZOTYPE = 8, // freeze nuke ok
|
||||
GRONTYPE = 9, // ok
|
||||
GUARDIANTYPE = 10, // nuke ok
|
||||
IMPTYPE = 11, // freeze nuke ok
|
||||
JUDYTYPE = 12, // wh1
|
||||
KATIETYPE = 13, // ok
|
||||
KOBOLDTYPE = 14, // freeze nuke ok
|
||||
KURTTYPE = 15,
|
||||
MINOTAURTYPE = 16, // freeze nuke ok
|
||||
NEWGUYTYPE = 17, // freeze nuke ok
|
||||
RATTYPE = 18,
|
||||
SKELETONTYPE = 19, // freezee nuke ok
|
||||
SKULLYTYPE = 20, // wh1
|
||||
SPIDERTYPE = 21, // wh1
|
||||
WILLOWTYPE = 22, //nuke ok
|
||||
MAXTYPES = 23,
|
||||
};
|
||||
|
||||
enum EAIConst
|
||||
{
|
||||
TYPENONE = 0,
|
||||
TYPEWATER = 1,
|
||||
TYPELAVA = 2,
|
||||
};
|
||||
|
||||
extern Enemy enemy[MAXTYPES];
|
||||
|
||||
void aiProcess();
|
||||
int aimove(short i);
|
||||
int aifly(short i);
|
||||
void aisearch(PLAYER& plr, short i, boolean fly);
|
||||
boolean checksector6(short i);
|
||||
int checkfluid(int i, int zr_florhit);
|
||||
void processfluid(int i, int zr_florhit, boolean fly);
|
||||
void castspell(PLAYER& plr, int i);
|
||||
void skullycastspell(PLAYER& plr, int i);
|
||||
void attack(PLAYER& plr, int i);
|
||||
int checkmove(short i, int dax, int day);
|
||||
boolean checkdist(PLAYER& plr, int i);
|
||||
boolean checkdist(int i, int x, int y, int z);
|
||||
extern int checksight_ang;
|
||||
boolean checksight(PLAYER& plr, int i);
|
||||
void monsterweapon(int i);
|
||||
PLAYER& aiGetPlayerTarget(short i);
|
||||
boolean actoruse(short i);
|
||||
|
||||
inline int findplayer() {
|
||||
return 0; // no multiplayer support, apparently...
|
||||
}
|
||||
|
||||
END_WH_NS
|
231
source/games/whaven/src/aidemon.cpp
Normal file
231
source/games/whaven/src/aidemon.cpp
Normal file
|
@ -0,0 +1,231 @@
|
|||
#include "ns.h"
|
||||
#include "wh.h"
|
||||
|
||||
BEGIN_WH_NS
|
||||
|
||||
static void chase(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0)
|
||||
spr.lotag = 250;
|
||||
|
||||
if (plr.z < spr.z) {
|
||||
spr.z -= TICSPERFRAME << 8;
|
||||
}
|
||||
if (plr.z > spr.z) {
|
||||
spr.z += TICSPERFRAME << 8;
|
||||
}
|
||||
|
||||
short osectnum = spr.sectnum;
|
||||
if (krand() % 63 == 0) {
|
||||
if (cansee(plr.x, plr.y, plr.z, plr.sector, sprite[i].x, sprite[i].y,
|
||||
sprite[i].z - (tilesizy[sprite[i].picnum] << 7), sprite[i].sectnum) && plr.invisibletime < 0)
|
||||
newstatus(i, ATTACK);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
if (totalclock % 100 > 70)
|
||||
trailingsmoke(i, true);
|
||||
|
||||
int dax = ((sintable[(sprite[i].ang + 512) & 2047] * TICSPERFRAME) << 2);
|
||||
int day = ((sintable[sprite[i].ang & 2047] * TICSPERFRAME) << 2);
|
||||
checksight(plr, i);
|
||||
|
||||
|
||||
if (!checkdist(plr, i)) {
|
||||
checkmove(i, dax, day);
|
||||
}
|
||||
else {
|
||||
if (plr.invisibletime < 0) {
|
||||
if (krand() % 8 == 0) // NEW
|
||||
newstatus(i, ATTACK); // NEW
|
||||
else { // NEW
|
||||
sprite[i].ang = (short)(((krand() & 512 - 256) + sprite[i].ang + 1024) & 2047); // NEW
|
||||
newstatus(i, CHASE); // NEW
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
checksector6(i);
|
||||
|
||||
processfluid(i, zr_florhit, true);
|
||||
|
||||
if (sector[osectnum].lotag == KILLSECTOR && spr.z + (8 << 8) >= sector[osectnum].floorz) {
|
||||
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)) {
|
||||
if (spr.z + (8 << 8) >= sector[osectnum].floorz) {
|
||||
spr.hitag--;
|
||||
if (spr.hitag < 0)
|
||||
newstatus(i, DIE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void search(PLAYER& plr, short i) {
|
||||
aisearch(plr, i, true);
|
||||
checksector6(i);
|
||||
}
|
||||
|
||||
static void pain(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum = DEMON;
|
||||
spr.ang = (short)plr.ang;
|
||||
newstatus(i, FLEE);
|
||||
}
|
||||
|
||||
aifly(i);
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
}
|
||||
|
||||
static void face(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 - (tilesizy[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);
|
||||
}
|
||||
|
||||
|
||||
static void attack(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
if (plr.z < spr.z) {
|
||||
spr.z -= TICSPERFRAME << 8;
|
||||
}
|
||||
if (plr.z > spr.z) {
|
||||
spr.z += TICSPERFRAME << 8;
|
||||
}
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
if (cansee(plr.x, plr.y, plr.z, plr.sector, spr.x, spr.y, spr.z - (tilesizy[spr.picnum] << 7),
|
||||
spr.sectnum))
|
||||
newstatus(i, CAST);
|
||||
else
|
||||
newstatus(i, CHASE);
|
||||
}
|
||||
else
|
||||
spr.ang = getangle(plr.x - spr.x, plr.y - spr.y);
|
||||
}
|
||||
|
||||
static void flee(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
short osectnum = spr.sectnum;
|
||||
|
||||
int movestat = aifly(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, true);
|
||||
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
}
|
||||
|
||||
static void cast(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
|
||||
if (plr.z < spr.z) {
|
||||
spr.z -= TICSPERFRAME << 8;
|
||||
}
|
||||
if (plr.z > spr.z) {
|
||||
spr.z += TICSPERFRAME << 8;
|
||||
}
|
||||
|
||||
if (spr.lotag < 0) {
|
||||
castspell(plr, i);
|
||||
newstatus(i, CHASE);
|
||||
}
|
||||
}
|
||||
|
||||
static void nuked(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
chunksofmeat(plr, i, spr.x, spr.y, spr.z, spr.sectnum, spr.ang);
|
||||
trailingsmoke(i, false);
|
||||
newstatus((short)i, DIE);
|
||||
}
|
||||
|
||||
|
||||
void createDemonAI() {
|
||||
auto& e = enemy[DEMONTYPE];
|
||||
enemy[DEMONTYPE].info.Init(38, 41, 4096 + 2048, 120, 0, 64, true, 300, 0);
|
||||
|
||||
e.chase = chase;
|
||||
e.resurect;
|
||||
e.nuked = nuked;
|
||||
e.frozen;
|
||||
e.pain = pain;
|
||||
e.face = face;
|
||||
e.attack = attack;
|
||||
e.flee = flee;
|
||||
e.cast = cast;
|
||||
e.die;
|
||||
e.skirmish;
|
||||
e.stand;
|
||||
e.search = search;
|
||||
}
|
||||
|
||||
|
||||
void premapDemon(short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.detail = DEMONTYPE;
|
||||
changespritestat(i, FACE);
|
||||
enemy[DEMONTYPE].info.set(spr);
|
||||
}
|
280
source/games/whaven/src/aidevil.cpp
Normal file
280
source/games/whaven/src/aidevil.cpp
Normal file
|
@ -0,0 +1,280 @@
|
|||
#include "ns.h"
|
||||
#include "wh.h"
|
||||
|
||||
BEGIN_WH_NS
|
||||
|
||||
|
||||
static void chase(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0)
|
||||
spr.lotag = 250;
|
||||
|
||||
short osectnum = spr.sectnum;
|
||||
|
||||
if (krand() % 63 == 0) {
|
||||
if (cansee(plr.x, plr.y, plr.z, plr.sector, sprite[i].x, sprite[i].y,
|
||||
sprite[i].z - (tilesizy[sprite[i].picnum] << 7), sprite[i].sectnum) && plr.invisibletime < 0)
|
||||
newstatus(i, ATTACK);
|
||||
}
|
||||
else {
|
||||
checksight(plr, i);
|
||||
if (!checkdist(plr, i)) {
|
||||
if ((aimove(i) & kHitTypeMask) == kHitFloor)
|
||||
{
|
||||
spr.ang = (short)((spr.ang + 1024) & 2047);
|
||||
newstatus(i, FLEE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (plr.invisibletime < 0) {
|
||||
if (krand() % 8 == 0) // NEW
|
||||
newstatus(i, ATTACK); // NEW
|
||||
else { // NEW
|
||||
sprite[i].ang = (short)(((krand() & 512 - 256) + sprite[i].ang + 1024) & 2047); // NEW
|
||||
newstatus(i, FLEE); // NEW
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getzrange(spr.x, spr.y, spr.z - 1, spr.sectnum, (spr.clipdist) << 2, CLIPMASK0);
|
||||
spr.z = zr_florz;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void die(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
|
||||
if (spr.lotag <= 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 20;
|
||||
|
||||
if (spr.picnum == DEVILDEAD) {
|
||||
if (difficulty == 4)
|
||||
newstatus(i, RESURECT);
|
||||
else {
|
||||
kills++;
|
||||
newstatus(i, DEAD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void pain(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum = DEVIL;
|
||||
spr.ang = (short)plr.ang;
|
||||
newstatus(i, FLEE);
|
||||
}
|
||||
|
||||
aimove(i);
|
||||
processfluid(i, zr_florhit, false);
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
}
|
||||
|
||||
static void face(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 - (tilesizy[spr.picnum] << 7),
|
||||
spr.sectnum);
|
||||
|
||||
if (cansee && plr.invisibletime < 0) {
|
||||
spr.ang = getangle(plr.x - spr.x, plr.y - spr.y);
|
||||
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);
|
||||
}
|
||||
|
||||
static void flee(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
short osectnum = spr.sectnum;
|
||||
|
||||
int movestat = aimove(i);
|
||||
if ((movestat & kHitTypeMask) != kHitFloor && 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);
|
||||
}
|
||||
|
||||
static void attack(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:
|
||||
case TYPEWATER:
|
||||
spr.z += tilesizy[spr.picnum] << 5;
|
||||
break;
|
||||
}
|
||||
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
|
||||
sprite[i].extra -= TICSPERFRAME;
|
||||
sprite[i].lotag -= TICSPERFRAME;
|
||||
if (sprite[i].lotag < 0) {
|
||||
if (cansee(plr.x, plr.y, plr.z, plr.sector, sprite[i].x, sprite[i].y,
|
||||
sprite[i].z - (tilesizy[sprite[i].picnum] << 7), sprite[i].sectnum))
|
||||
newstatus(i, CAST);
|
||||
else
|
||||
newstatus(i, CHASE);
|
||||
}
|
||||
else
|
||||
sprite[i].ang = getangle(plr.x - sprite[i].x, plr.y - sprite[i].y);
|
||||
}
|
||||
|
||||
static void resurect(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
newstatus(i, FACE);
|
||||
spr.picnum = DEVIL;
|
||||
spr.hitag = (short)adjusthp(60);
|
||||
spr.lotag = 100;
|
||||
spr.cstat |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void search(PLAYER& plr, short i) {
|
||||
aisearch(plr, i, false);
|
||||
checksector6(i);
|
||||
}
|
||||
|
||||
static void frozen(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.pal = 0;
|
||||
spr.picnum = DEVIL;
|
||||
newstatus(i, FACE);
|
||||
}
|
||||
}
|
||||
|
||||
static void nuked(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
if (game.WH2) {
|
||||
chunksofmeat(plr, i, spr.x, spr.y, spr.z, spr.sectnum, spr.ang);
|
||||
trailingsmoke(i, false);
|
||||
newstatus((short)i, DIE);
|
||||
return;
|
||||
}
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 24;
|
||||
if (spr.picnum == DEVILCHAR + 4) {
|
||||
trailingsmoke(i, false);
|
||||
deletesprite(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void cast(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 12;
|
||||
}
|
||||
|
||||
if (spr.picnum == DEVILATTACK + 2) {
|
||||
spr.picnum = DEVIL;
|
||||
playsound_loc(S_FIREBALL, sprite[i].x, sprite[i].y);
|
||||
castspell(plr, i);
|
||||
newstatus(i, CHASE);
|
||||
}
|
||||
checksector6(i);
|
||||
}
|
||||
|
||||
|
||||
void createDevilAI() {
|
||||
auto &e = enemy[DEVILTYPE];
|
||||
e.info.Init(game.WH2 ? 50 : 36, game.WH2 ? 50 : 36, 2048, 120, 0, 64, false, 50, 0);
|
||||
e.chase = chase;
|
||||
e.die = die;
|
||||
e.pain = pain;
|
||||
e.face = face;
|
||||
e.flee = flee;
|
||||
e.attack = attack;
|
||||
e.resurect = resurect;
|
||||
e.search = search;
|
||||
e.frozen = frozen;
|
||||
e.nuked = nuked;
|
||||
e.cast = cast;
|
||||
}
|
||||
|
||||
void premapDevil(short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.detail = DEVILTYPE;
|
||||
changespritestat(i, FACE);
|
||||
enemy[DEVILTYPE].info.set(spr);
|
||||
if (spr.pal == 2)
|
||||
spr.hitag = adjusthp(60);
|
||||
}
|
||||
|
||||
END_WH_NS
|
420
source/games/whaven/src/aidragon.cpp
Normal file
420
source/games/whaven/src/aidragon.cpp
Normal file
|
@ -0,0 +1,420 @@
|
|||
#include "ns.h"
|
||||
#include "wh.h"
|
||||
|
||||
BEGIN_WH_NS
|
||||
|
||||
static int checksight_x, checksight_y = 0;
|
||||
|
||||
static void checkspeed(int i, int speed);
|
||||
static void dragonAttack2(PLAYER& plr, short i);
|
||||
static void firebreath(PLAYER& plr, int i, int a, int b, int c);
|
||||
|
||||
static void chase(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0)
|
||||
spr.lotag = 250;
|
||||
|
||||
short osectnum = spr.sectnum;
|
||||
// int speed = 10;
|
||||
if ((krand() % 16) == 0) {
|
||||
if (cansee(plr.x, plr.y, plr.z, plr.sector, spr.x, spr.y, spr.z - (tilesizy[spr.picnum] << 7),
|
||||
spr.sectnum) && plr.invisibletime < 0)
|
||||
if (plr.z < spr.z)
|
||||
newstatus(i, ATTACK2);
|
||||
else
|
||||
newstatus(i, ATTACK);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
int dax = (sintable[(sprite[i].ang + 512) & 2047] * TICSPERFRAME) << 3;
|
||||
int day = (sintable[sprite[i].ang & 2047] * TICSPERFRAME) << 3;
|
||||
// checkspeed(i, speed);
|
||||
checksight(plr, i);
|
||||
if (!checkdist(plr, i)) {
|
||||
// checkmove(i, checksight_x, checksight_y);
|
||||
checkmove(i, dax, day);
|
||||
}
|
||||
else {
|
||||
if (plr.invisibletime < 0) {
|
||||
if (krand() % 8 == 0) { // NEW
|
||||
if (plr.z < spr.z)
|
||||
newstatus(i, ATTACK2);
|
||||
else
|
||||
newstatus(i, ATTACK);
|
||||
}
|
||||
else { // NEW
|
||||
newstatus(i, FACE); // NEW
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getzrange(spr.x, spr.y, spr.z - 1, spr.sectnum, (spr.clipdist) << 2, CLIPMASK0);
|
||||
spr.z = zr_florz;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void flee(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
short osectnum = spr.sectnum;
|
||||
|
||||
int movestat = aimove(i);
|
||||
if ((movestat & kHitTypeMask) != kHitFloor && 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);
|
||||
}
|
||||
|
||||
static void die(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
|
||||
if (spr.lotag <= 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 20;
|
||||
if (spr.picnum == DRAGONDEAD) {
|
||||
if (difficulty == 4)
|
||||
newstatus(i, RESURECT);
|
||||
else {
|
||||
kills++;
|
||||
newstatus(i, DEAD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void cast(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 12;
|
||||
}
|
||||
|
||||
switch (spr.picnum) {
|
||||
case DRAGONATTACK + 17:
|
||||
case DRAGONATTACK + 4:
|
||||
if ((krand() % 2) != 0)
|
||||
playsound_loc(S_FLAME1, spr.x, spr.y);
|
||||
else
|
||||
playsound_loc(S_FIREBALL, spr.x, spr.y);
|
||||
|
||||
firebreath(plr, i, 1, 2, LOW);
|
||||
break;
|
||||
case DRAGONATTACK + 18:
|
||||
case DRAGONATTACK + 5:
|
||||
if ((krand() % 2) != 0)
|
||||
playsound_loc(S_FLAME1, spr.x, spr.y);
|
||||
else
|
||||
playsound_loc(S_FIREBALL, spr.x, spr.y);
|
||||
|
||||
firebreath(plr, i, 2, 1, LOW);
|
||||
break;
|
||||
case DRAGONATTACK + 19:
|
||||
case DRAGONATTACK + 6:
|
||||
if ((krand() % 2) != 0)
|
||||
playsound_loc(S_FLAME1, spr.x, spr.y);
|
||||
else
|
||||
playsound_loc(S_FIREBALL, spr.x, spr.y);
|
||||
|
||||
firebreath(plr, i, 4, 0, LOW);
|
||||
break;
|
||||
case DRAGONATTACK + 20:
|
||||
case DRAGONATTACK + 7:
|
||||
firebreath(plr, i, 2, -1, LOW);
|
||||
break;
|
||||
case DRAGONATTACK + 21:
|
||||
case DRAGONATTACK + 8:
|
||||
firebreath(plr, i, 1, -2, LOW);
|
||||
break;
|
||||
|
||||
case DRAGONATTACK2 + 2:
|
||||
if ((krand() % 2) != 0)
|
||||
playsound_loc(S_FLAME1, spr.x, spr.y);
|
||||
else
|
||||
playsound_loc(S_FIREBALL, spr.x, spr.y);
|
||||
|
||||
firebreath(plr, i, 1, -1, HIGH);
|
||||
break;
|
||||
case DRAGONATTACK2 + 3:
|
||||
firebreath(plr, i, 2, 0, HIGH);
|
||||
break;
|
||||
|
||||
case DRAGONATTACK2 + 5:
|
||||
spr.picnum = DRAGON;
|
||||
newstatus(i, CHASE);
|
||||
break;
|
||||
case DRAGONATTACK + 22:
|
||||
spr.picnum = DRAGONATTACK;
|
||||
newstatus(i, CHASE);
|
||||
break;
|
||||
}
|
||||
|
||||
checksector6(i);
|
||||
}
|
||||
|
||||
static void attack(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
if (cansee(plr.x, plr.y, plr.z, plr.sector, spr.x, spr.y, spr.z - (tilesizy[spr.picnum] << 7),
|
||||
spr.sectnum))
|
||||
newstatus(i, CAST);
|
||||
else
|
||||
newstatus(i, CHASE);
|
||||
}
|
||||
else
|
||||
spr.ang = getangle(plr.x - spr.x, plr.y - spr.y);
|
||||
}
|
||||
|
||||
static void resurect(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
newstatus(i, FACE);
|
||||
spr.picnum = DRAGON;
|
||||
spr.hitag = (short)adjusthp(900);
|
||||
spr.lotag = 100;
|
||||
spr.cstat |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void search(PLAYER& plr, short i) {
|
||||
aisearch(plr, i, true);
|
||||
checksector6(i);
|
||||
}
|
||||
|
||||
static void frozen(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.pal = 0;
|
||||
spr.picnum = DRAGON;
|
||||
newstatus(i, FACE);
|
||||
}
|
||||
}
|
||||
|
||||
static void nuked(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 24;
|
||||
if (spr.picnum == DRAGONCHAR + 4) {
|
||||
trailingsmoke(i, false);
|
||||
deletesprite(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void pain(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
aimove(i);
|
||||
processfluid(i, zr_florhit, false);
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
}
|
||||
|
||||
static void face(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 - (tilesizy[spr.picnum] << 7),
|
||||
spr.sectnum);
|
||||
|
||||
if (cansee && plr.invisibletime < 0) {
|
||||
spr.ang = getangle(plr.x - spr.x, plr.y - spr.y);
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
void dragonProcess(PLAYER& plr)
|
||||
{
|
||||
for (short i = headspritestat[ATTACK2], nextsprite; i >= 0; i = nextsprite) {
|
||||
nextsprite = nextspritestat[i];
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
switch (spr.detail) {
|
||||
case DRAGON:
|
||||
dragonAttack2(plr, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void dragonAttack2(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
if (cansee(plr.x, plr.y, plr.z, plr.sector, spr.x, spr.y, spr.z - (tilesizy[spr.picnum] << 7),
|
||||
spr.sectnum) && plr.invisibletime < 0)
|
||||
newstatus(i, CAST);
|
||||
else
|
||||
newstatus(i, CHASE);
|
||||
return;
|
||||
}
|
||||
else
|
||||
spr.ang = getangle(plr.x - spr.x, plr.y - spr.y);
|
||||
|
||||
checksector6(i);
|
||||
}
|
||||
|
||||
void dragonProcess(PLAYER& plr)
|
||||
{
|
||||
for (short i = headspritestat[ATTACK2], nextsprite; i >= 0; i = nextsprite) {
|
||||
nextsprite = nextspritestat[i];
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
switch (spr.detail) {
|
||||
case DRAGON:
|
||||
dragonAttack2(plr, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void dragonAttack2(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
if (cansee(plr.x, plr.y, plr.z, plr.sector, spr.x, spr.y, spr.z - (tilesizy[spr.picnum] << 7),
|
||||
spr.sectnum) && plr.invisibletime < 0)
|
||||
newstatus(i, CAST);
|
||||
else
|
||||
newstatus(i, CHASE);
|
||||
return;
|
||||
}
|
||||
else
|
||||
spr.ang = getangle(plr.x - spr.x, plr.y - spr.y);
|
||||
|
||||
checksector6(i);
|
||||
}
|
||||
|
||||
static void firebreath(PLAYER& plr, int i, int a, int b, int c) {
|
||||
for (int k = 0; k <= a; k++) {
|
||||
int j = insertsprite(sprite[i].sectnum, MISSILE);
|
||||
if (j == -1)
|
||||
return;
|
||||
|
||||
sprite[j].x = sprite[i].x;
|
||||
sprite[j].y = sprite[i].y;
|
||||
if (c == LOW)
|
||||
sprite[j].z = sector[sprite[i].sectnum].floorz - (32 << 8);
|
||||
else
|
||||
sprite[j].z = sector[sprite[i].sectnum].floorz - (tilesizy[sprite[i].picnum] << 7);
|
||||
sprite[j].cstat = 0;
|
||||
sprite[j].picnum = MONSTERBALL;
|
||||
sprite[j].shade = -15;
|
||||
sprite[j].xrepeat = 128;
|
||||
sprite[j].yrepeat = 128;
|
||||
sprite[j].ang = (short)((((getangle(plr.x - sprite[j].x, plr.y - sprite[j].y)
|
||||
+ (krand() & 15) - 8) + 2048) + ((b * 22) + (k * 10))) & 2047);
|
||||
sprite[j].xvel = (short)(sintable[(sprite[j].ang + 2560) & 2047] >> 6);
|
||||
sprite[j].yvel = (short)(sintable[(sprite[j].ang + 2048) & 2047] >> 6);
|
||||
int discrim = ksqrt(
|
||||
(plr.x - sprite[j].x) * (plr.x - sprite[j].x) + (plr.y - sprite[j].y) * (plr.y - sprite[j].y));
|
||||
if (discrim == 0)
|
||||
discrim = 1;
|
||||
if (c == HIGH)
|
||||
sprite[j].zvel = (short)(((plr.z + (32 << 8) - sprite[j].z) << 7) / discrim);
|
||||
else
|
||||
sprite[j].zvel = (short)((((plr.z + (8 << 8)) - sprite[j].z) << 7) / discrim);// NEW
|
||||
|
||||
sprite[j].owner = (short)i;
|
||||
sprite[j].clipdist = 16;
|
||||
sprite[j].lotag = 512;
|
||||
sprite[j].hitag = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void checkspeed(int i, int speed) {
|
||||
checksight_x = (sintable[(sprite[i].ang + 512) & 2047] >> speed);
|
||||
checksight_y = (sintable[sprite[i].ang & 2047] >> speed);
|
||||
}
|
||||
|
||||
|
||||
void createDragonAI() {
|
||||
auto& e = enemy[DRAGONTYPE];
|
||||
e.info.Init(54, 54, 512, 120, 0, 128, false, 900, 0);
|
||||
e.chase = chase;
|
||||
e.flee = flee;
|
||||
e.die = die;
|
||||
e.cast = cast;
|
||||
e.attack = attack;
|
||||
e.resurect = resurect;
|
||||
e.search = search;
|
||||
e.frozen = frozen;
|
||||
e.nuked = nuked;
|
||||
e.pain = pain;
|
||||
e.face = face;
|
||||
}
|
||||
|
||||
void premapDragon(short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.detail = DRAGONTYPE;
|
||||
changespritestat(i, FACE);
|
||||
enemy[DRAGONTYPE].info.set(spr);
|
||||
}
|
288
source/games/whaven/src/aifatwitch.cpp
Normal file
288
source/games/whaven/src/aifatwitch.cpp
Normal file
|
@ -0,0 +1,288 @@
|
|||
#include "ns.h"
|
||||
#include "wh.h"
|
||||
|
||||
BEGIN_WH_NS
|
||||
|
||||
|
||||
static void chase(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0)
|
||||
spr.lotag = 250;
|
||||
|
||||
short osectnum = spr.sectnum;
|
||||
|
||||
if (krand() % 63 == 0) {
|
||||
if (cansee(plr.x, plr.y, plr.z, plr.sector, sprite[i].x, sprite[i].y,
|
||||
sprite[i].z - (tilesizy[sprite[i].picnum] << 7), sprite[i].sectnum))// && invisibletime < 0)
|
||||
newstatus(i, ATTACK);
|
||||
}
|
||||
else {
|
||||
checksight(plr, i);
|
||||
if (!checkdist(i, plr.x, plr.y, plr.z)) {
|
||||
int movestat = aimove(i);
|
||||
if ((movestat & kHitTypeMask) == kHitFloor)
|
||||
{
|
||||
spr.ang = (short)((spr.ang + 1024) & 2047);
|
||||
newstatus(i, FLEE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (krand() % 8 == 0) // NEW
|
||||
newstatus(i, ATTACK); // NEW
|
||||
else { // NEW
|
||||
sprite[i].ang = (short)(((krand() & 512 - 256) + sprite[i].ang + 1024) & 2047); // NEW
|
||||
newstatus(i, FLEE); // NEW
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getzrange(spr.x, spr.y, spr.z - 1, spr.sectnum, (spr.clipdist) << 2, CLIPMASK0);
|
||||
spr.z = zr_florz;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void resurect(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
newstatus(i, FACE);
|
||||
spr.picnum = FATWITCH;
|
||||
spr.hitag = (short)adjusthp(90);
|
||||
spr.lotag = 100;
|
||||
spr.cstat |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void search(PLAYER& plr, short i) {
|
||||
aisearch(plr, i, false);
|
||||
checksector6(i);
|
||||
}
|
||||
|
||||
static void nuked(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 24;
|
||||
if (spr.picnum == FATWITCHCHAR + 4) {
|
||||
trailingsmoke(i, false);
|
||||
deletesprite(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void pain(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum = FATWITCH;
|
||||
spr.ang = (short)plr.ang;
|
||||
newstatus(i, FLEE);
|
||||
}
|
||||
|
||||
aimove(i);
|
||||
processfluid(i, zr_florhit, false);
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
}
|
||||
|
||||
static void face(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 - (tilesizy[spr.picnum] << 7), spr.sectnum);
|
||||
|
||||
if (cansee && plr.invisibletime < 0) {
|
||||
spr.ang = getangle(plr.x - spr.x, plr.y - spr.y);
|
||||
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(i, plr.x, plr.y, plr.z))
|
||||
newstatus(i, ATTACK);
|
||||
}
|
||||
|
||||
static void attack(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:
|
||||
case TYPEWATER:
|
||||
spr.z += tilesizy[spr.picnum] << 5;
|
||||
break;
|
||||
}
|
||||
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
|
||||
sprite[i].lotag -= TICSPERFRAME;
|
||||
if (sprite[i].lotag < 0) {
|
||||
if (cansee(plr.x, plr.y, plr.z, plr.sector, sprite[i].x, sprite[i].y,
|
||||
sprite[i].z - (tilesizy[sprite[i].picnum] << 7), sprite[i].sectnum))
|
||||
newstatus(i, CAST);
|
||||
else
|
||||
newstatus(i, CHASE);
|
||||
}
|
||||
else
|
||||
sprite[i].ang = getangle(plr.x - sprite[i].x, plr.y - sprite[i].y);
|
||||
}
|
||||
|
||||
static void flee(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
short osectnum = spr.sectnum;
|
||||
|
||||
int movestat = aimove(i);
|
||||
if ((movestat & kHitTypeMask) != kHitFloor && 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);
|
||||
}
|
||||
|
||||
static void cast(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 12;
|
||||
}
|
||||
|
||||
if (spr.picnum == FATWITCHATTACK + 3) {
|
||||
sprite[i].picnum = FATWITCH;
|
||||
throwspank(plr, i);
|
||||
newstatus(i, CHASE);
|
||||
}
|
||||
checksector6(i);
|
||||
}
|
||||
|
||||
static void die(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
|
||||
if (spr.lotag <= 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 20;
|
||||
|
||||
if (spr.picnum == FATWITCHDEAD) {
|
||||
if (difficulty == 4)
|
||||
newstatus(i, RESURECT);
|
||||
else {
|
||||
kills++;
|
||||
newstatus(i, DEAD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void throwspank(PLAYER& plr, int i) {
|
||||
int j = insertsprite(sprite[i].sectnum, MISSILE);
|
||||
if (j == -1)
|
||||
return;
|
||||
playsound_loc(S_WITCHTHROW, sprite[i].x, sprite[i].y);
|
||||
|
||||
sprite[j].x = sprite[i].x;
|
||||
sprite[j].y = sprite[i].y;
|
||||
sprite[j].z = sector[sprite[i].sectnum].floorz - ((tilesizy[sprite[i].picnum] >> 1) << 8);
|
||||
sprite[j].cstat = 0; // Hitscan does not hit other bullets
|
||||
sprite[j].picnum = FATSPANK;
|
||||
sprite[j].shade = -15;
|
||||
sprite[j].xrepeat = 64;
|
||||
sprite[j].yrepeat = 64;
|
||||
sprite[j].ang = (short)(((getangle(plr.x - sprite[j].x, plr.y - sprite[j].y) + (krand() & 15)
|
||||
- 8) + 2048) & 2047);
|
||||
sprite[j].xvel = (short)(sintable[(sprite[j].ang + 2560) & 2047] >> 6);
|
||||
sprite[j].yvel = (short)(sintable[(sprite[j].ang + 2048) & 2047] >> 6);
|
||||
long discrim = ksqrt((plr.x - sprite[j].x) * (plr.x - sprite[j].x) + (plr.y - sprite[j].y) * (plr.y - sprite[j].y));
|
||||
if (discrim == 0)
|
||||
discrim = 1;
|
||||
sprite[j].zvel = (short)(((plr.z + (48 << 8) - sprite[j].z) << 7) / discrim);
|
||||
sprite[j].owner = (short)i;
|
||||
sprite[j].clipdist = 16;
|
||||
sprite[j].lotag = 512;
|
||||
sprite[j].hitag = 0;
|
||||
sprite[j].pal = 0;
|
||||
}
|
||||
|
||||
void createFatwitchAI() {
|
||||
auto& e = enemy[FATWITCHTYPE];
|
||||
e.info.Init(32, 32, 2048, 120, 0, 64, false, 280, 0);
|
||||
e.chase = chase;
|
||||
e.resurect = resurect;
|
||||
e.search = search;
|
||||
e.nuked = nuked;
|
||||
e.pain = pain;
|
||||
e.face = face;
|
||||
e.attack = attack;
|
||||
e.flee = flee;
|
||||
e.cast = cast;
|
||||
e.die = die;
|
||||
}
|
||||
|
||||
void premapFatwitch(short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.detail = FATWITCHTYPE;
|
||||
changespritestat(i, FACE);
|
||||
enemy[FATWITCHTYPE].info.set(spr);
|
||||
if (spr.pal == 7)
|
||||
spr.hitag = (short)adjusthp(290);
|
||||
if (krand() % 100 > 50)
|
||||
spr.extra = 1;
|
||||
|
||||
}
|
||||
|
||||
END_WH_NS
|
196
source/games/whaven/src/aifish.cpp
Normal file
196
source/games/whaven/src/aifish.cpp
Normal file
|
@ -0,0 +1,196 @@
|
|||
#include "ns.h"
|
||||
#include "wh.h"
|
||||
|
||||
BEGIN_WH_NS
|
||||
|
||||
|
||||
static void chase(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 - (tilesizy[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);
|
||||
}
|
||||
}
|
||||
|
||||
static void die(PLAYER& plr, short i) {
|
||||
deletesprite(i);
|
||||
}
|
||||
|
||||
static void attack(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.z = sector[sprite[i].sectnum].floorz;
|
||||
|
||||
switch (checkfluid(i, zr_florhit)) {
|
||||
case TYPELAVA:
|
||||
sprite[i].hitag--;
|
||||
if (sprite[i].hitag < 0)
|
||||
newstatus(i, DIE);
|
||||
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 skirmish(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;
|
||||
}
|
||||
|
||||
static void search(PLAYER& plr, short i) {
|
||||
aisearch(plr, i, false);
|
||||
checksector6(i);
|
||||
}
|
||||
|
||||
static void face(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 - (tilesizy[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);
|
||||
}
|
||||
|
||||
void createFishAI() {
|
||||
auto &e = enemy[FISHTYPE];
|
||||
e.info.Init(1, 1, 512, 120, 0, 32, false, 10, 0);
|
||||
e.chase = chase;
|
||||
e.die = die;
|
||||
e.attack = attack;
|
||||
e.skirmish = skirmish;
|
||||
e.search = search;
|
||||
e.face = face;
|
||||
}
|
||||
|
||||
void premapFish(short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.detail = FISHTYPE;
|
||||
changespritestat(i, FACE);
|
||||
enemy[FISHTYPE].info.set(spr);
|
||||
}
|
||||
|
||||
END_WH_NS
|
332
source/games/whaven/src/aifred.cpp
Normal file
332
source/games/whaven/src/aifred.cpp
Normal file
|
@ -0,0 +1,332 @@
|
|||
#include "ns.h"
|
||||
#include "wh.h"
|
||||
|
||||
BEGIN_WH_NS
|
||||
|
||||
static void checkexpl(PLAYER& plr, short i);
|
||||
|
||||
|
||||
static void chase(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 - (tilesizy[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);
|
||||
}
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void skirmish(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;
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void die(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 search(PLAYER& plr, short i) {
|
||||
aisearch(plr, i, false);
|
||||
if (!checksector6(i))
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void frozen(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 face(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 - (tilesizy[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);
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void attack(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 += tilesizy[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 flee(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);
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void pain(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum = FRED;
|
||||
spr.ang = (short)plr.ang;
|
||||
newstatus(i, FLEE);
|
||||
}
|
||||
|
||||
aimove(i);
|
||||
processfluid(i, zr_florhit, false);
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void resurect(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 checkexpl(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
short j = headspritesect[spr.sectnum];
|
||||
while (j != -1) {
|
||||
short nextj = nextspritesect[j];
|
||||
long dx = klabs(spr.x - sprite[j].x); // x distance to sprite
|
||||
long dy = klabs(spr.y - sprite[j].y); // y distance to sprite
|
||||
long dz = klabs((spr.z >> 8) - (sprite[j].z >> 8)); // z distance to sprite
|
||||
long dh = tilesizy[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 = chase;
|
||||
e.skirmish = skirmish;
|
||||
e.die = die;
|
||||
e.search = search;
|
||||
e.frozen = frozen;
|
||||
e.face = face;
|
||||
e.attack = attack;
|
||||
e.flee = flee;
|
||||
e.pain = pain;
|
||||
e.resurect = resurect;
|
||||
}
|
||||
|
||||
|
||||
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
|
581
source/games/whaven/src/aigoblin.cpp
Normal file
581
source/games/whaven/src/aigoblin.cpp
Normal file
|
@ -0,0 +1,581 @@
|
|||
#include "ns.h"
|
||||
#include "wh.h"
|
||||
|
||||
BEGIN_WH_NS
|
||||
|
||||
static void checkexpl(PLAYER& plr, short i);
|
||||
|
||||
|
||||
static void chase(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 - (tilesizy[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) == kHitFloor)
|
||||
{
|
||||
spr.ang = (short)((spr.ang + 1024) & 2047);
|
||||
newstatus(i, FLEE);
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void die(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
|
||||
if (spr.lotag <= 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 20;
|
||||
|
||||
if (spr.picnum == GOBLINDEAD) {
|
||||
if (difficulty == 4)
|
||||
newstatus(i, RESURECT);
|
||||
else {
|
||||
kills++;
|
||||
newstatus(i, DEAD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void pain(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum = GOBLIN;
|
||||
spr.ang = (short)plr.ang;
|
||||
newstatus(i, FLEE);
|
||||
}
|
||||
|
||||
aimove(i);
|
||||
processfluid(i, zr_florhit, false);
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void face(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 - (tilesizy[spr.picnum] << 7),
|
||||
spr.sectnum);
|
||||
|
||||
if (cansee && plr.invisibletime < 0) {
|
||||
spr.ang = getangle(plr.x - spr.x, plr.y - spr.y);
|
||||
spr.picnum = GOBLIN;
|
||||
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);
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void flee(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
short osectnum = spr.sectnum;
|
||||
|
||||
int movestat = aimove(i);
|
||||
if ((movestat & kHitTypeMask) != kHitFloor && 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);
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void stand(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.ang = getangle(plr.x - spr.x, plr.y - spr.y);
|
||||
if (sintable[(spr.ang + 2560) & 2047] * (plr.x - spr.x)
|
||||
+ sintable[(spr.ang + 2048) & 2047] * (plr.y - spr.y) >= 0)
|
||||
if (cansee(plr.x, plr.y, plr.z, plr.sector, spr.x, spr.y, spr.z - (tilesizy[spr.picnum] << 7),
|
||||
spr.sectnum) && plr.invisibletime < 0) {
|
||||
switch (spr.picnum) {
|
||||
case GOBLINCHILL:
|
||||
spr.picnum = GOBLINSURPRISE;
|
||||
playsound_loc(S_GOBPAIN1 + (krand() % 2), spr.x, spr.y);
|
||||
newstatus(i, CHILL);
|
||||
break;
|
||||
default:
|
||||
spr.picnum = GOBLIN;
|
||||
if (plr.shadowtime > 0) {
|
||||
spr.ang = (short)(((krand() & 512 - 256) + spr.ang + 1024) & 2047); // NEW
|
||||
newstatus(i, FLEE);
|
||||
}
|
||||
else
|
||||
newstatus(i, CHASE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
checksector6(i);
|
||||
}
|
||||
|
||||
static void attack(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 += tilesizy[spr.picnum] << 5;
|
||||
break;
|
||||
}
|
||||
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
|
||||
if (spr.lotag == 31) {
|
||||
if (checksight(plr, i))
|
||||
if (checkdist(plr, i)) {
|
||||
spr.ang = (short)checksight_ang;
|
||||
attack(plr, i);
|
||||
}
|
||||
}
|
||||
else if (spr.lotag < 0) {
|
||||
spr.picnum = GOBLIN;
|
||||
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 resurect(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
newstatus(i, FACE);
|
||||
spr.picnum = GOBLIN;
|
||||
spr.hitag = (short)adjusthp(35);
|
||||
spr.lotag = 100;
|
||||
spr.cstat |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void search(PLAYER& plr, short i) {
|
||||
aisearch(plr, i, false);
|
||||
if (!checksector6(i))
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void frozen(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.pal = 0;
|
||||
spr.picnum = GOBLIN;
|
||||
newstatus(i, FACE);
|
||||
}
|
||||
}
|
||||
|
||||
static void nuked(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 24;
|
||||
if (spr.picnum == GOBLINCHAR + 4) {
|
||||
trailingsmoke(i, false);
|
||||
deletesprite(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void skirmish(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
|
||||
if (spr.lotag < 0)
|
||||
newstatus(i, FACE);
|
||||
short osectnum = spr.sectnum;
|
||||
int movestat = aimove(i);
|
||||
if ((movestat & kHitTypeMask) != kHitFloor && movestat != 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;
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
void goblinChill(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 18;
|
||||
if (spr.picnum == GOBLINSURPRISE + 5) {
|
||||
spr.picnum = GOBLIN;
|
||||
newstatus(i, FACE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void goblinWar(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
short k;
|
||||
|
||||
if (spr.lotag > 256) {
|
||||
spr.lotag = 100;
|
||||
spr.extra = 0;
|
||||
}
|
||||
|
||||
switch (spr.extra) {
|
||||
case 0: // find new target
|
||||
long olddist = 1024 << 4;
|
||||
boolean found = false;
|
||||
for (k = 0; k < MAXSPRITES; k++) {
|
||||
if (sprite[k].picnum == GOBLIN && spr.pal != sprite[k].pal && spr.hitag == sprite[k].hitag) {
|
||||
long dist = klabs(spr.x - sprite[k].x) + klabs(spr.y - sprite[k].y);
|
||||
if (dist < olddist) {
|
||||
found = true;
|
||||
olddist = dist;
|
||||
spr.owner = k;
|
||||
spr.ang = getangle(sprite[k].x - spr.x, sprite[k].y - spr.y);
|
||||
spr.extra = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
if (spr.pal == 5)
|
||||
spr.hitag = (short)adjusthp(35);
|
||||
else if (spr.pal == 4)
|
||||
spr.hitag = (short)adjusthp(25);
|
||||
else
|
||||
spr.hitag = (short)adjusthp(15);
|
||||
if (plr.shadowtime > 0) {
|
||||
spr.ang = (short)(((krand() & 512 - 256) + spr.ang + 1024) & 2047); // NEW
|
||||
newstatus(i, FLEE);
|
||||
}
|
||||
else
|
||||
newstatus(i, FACE);
|
||||
}
|
||||
break;
|
||||
case 1: // chase
|
||||
k = spr.owner;
|
||||
|
||||
int movehit = aimove(i);
|
||||
if (movehit == 0)
|
||||
spr.ang = getangle(sprite[k].x - spr.x, sprite[k].y - spr.y);
|
||||
else if ((movehit & kHitTypeMask) == kHitWall) {
|
||||
spr.extra = 3;
|
||||
spr.ang = (short)((spr.ang + (krand() & 256 - 128)) & 2047);
|
||||
spr.lotag = 60;
|
||||
}
|
||||
else if ((movehit & kHitTypeMask) == kHitSprite) {
|
||||
int sprnum = movehit & kHitIndexMask;
|
||||
if (sprnum != k) {
|
||||
spr.extra = 3;
|
||||
spr.ang = (short)((spr.ang + (krand() & 256 - 128)) & 2047);
|
||||
spr.lotag = 60;
|
||||
}
|
||||
else spr.ang = getangle(sprite[k].x - spr.x, sprite[k].y - spr.y);
|
||||
}
|
||||
|
||||
processfluid(i, zr_florhit, false);
|
||||
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
if (checkdist(i, sprite[k].x, sprite[k].y, sprite[k].z)) {
|
||||
spr.extra = 2;
|
||||
}
|
||||
else
|
||||
spr.picnum = GOBLIN;
|
||||
|
||||
if (checksector6(i))
|
||||
return;
|
||||
|
||||
break;
|
||||
case 2: // attack
|
||||
k = spr.owner;
|
||||
if (checkdist(i, sprite[k].x, sprite[k].y, sprite[k].z)) {
|
||||
if ((krand() & 1) != 0) {
|
||||
// goblins are fighting
|
||||
// JSA_DEMO
|
||||
if (krand() % 10 > 6)
|
||||
playsound_loc(S_GENSWING, spr.x, spr.y);
|
||||
if (krand() % 10 > 6)
|
||||
playsound_loc(S_SWORD1 + (krand() % 6), spr.x, spr.y);
|
||||
|
||||
if (checkdist(plr, i))
|
||||
addhealth(plr, -(krand() & 5));
|
||||
|
||||
if (krand() % 100 > 90) { // if k is dead
|
||||
spr.extra = 0; // needs to
|
||||
spr.picnum = GOBLIN;
|
||||
sprite[k].extra = 4;
|
||||
sprite[k].picnum = GOBLINDIE;
|
||||
sprite[k].lotag = 20;
|
||||
sprite[k].hitag = 0;
|
||||
newstatus(k, DIE);
|
||||
}
|
||||
else { // i attack k flee
|
||||
spr.extra = 0;
|
||||
sprite[k].extra = 3;
|
||||
sprite[k].ang = (short)((spr.ang + (krand() & 256 - 128)) & 2047);
|
||||
sprite[k].lotag = 60;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
spr.extra = 1;
|
||||
}
|
||||
|
||||
processfluid(i, zr_florhit, false);
|
||||
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
|
||||
if (checksector6(i))
|
||||
return;
|
||||
|
||||
break;
|
||||
case 3: // flee
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
|
||||
if (aimove(i) != 0)
|
||||
spr.ang = (short)(krand() & 2047);
|
||||
processfluid(i, zr_florhit, false);
|
||||
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
|
||||
if (spr.lotag < 0) {
|
||||
spr.lotag = 0;
|
||||
spr.extra = 0;
|
||||
}
|
||||
|
||||
if (checksector6(i))
|
||||
return;
|
||||
|
||||
break;
|
||||
case 4: // pain
|
||||
spr.picnum = GOBLINDIE;
|
||||
break;
|
||||
case 5: // cast
|
||||
break;
|
||||
}
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
void goblinWarProcess(PLAYER& plr)
|
||||
{
|
||||
for (short i = headspritestat[WAR], nextsprite; i >= 0; i = nextsprite) {
|
||||
nextsprite = nextspritestat[i];
|
||||
SPRITE& spr = sprite[i];
|
||||
switch (spr.detail) {
|
||||
case GOBLINTYPE:
|
||||
goblinWar(plr, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void checkexpl(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
short j = headspritesect[spr.sectnum];
|
||||
while (j != -1) {
|
||||
short nextj = nextspritesect[j];
|
||||
long dx = klabs(spr.x - sprite[j].x); // x distance to sprite
|
||||
long dy = klabs(spr.y - sprite[j].y); // y distance to sprite
|
||||
long dz = klabs((spr.z >> 8) - (sprite[j].z >> 8)); // z distance to sprite
|
||||
long dh = tilesizy[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 createGoblinAI() {
|
||||
auto& e = enemy[GOBLINTYPE];
|
||||
e.info.Init(36, 36, 1024, 120, 0, 64, false, 15, 0);
|
||||
e.chase = chase;
|
||||
e.die = die;
|
||||
e.pain = pain;
|
||||
e.face = face;
|
||||
e.flee = flee;
|
||||
e.stand = stand;
|
||||
e.attack = attack;
|
||||
e.resurect = resurect;
|
||||
e.search = search;
|
||||
e.frozen = frozen;
|
||||
e.nuked = nuked;
|
||||
e.skirmish = skirmish;
|
||||
e.info.getHealth = [](EnemyInfo& e, SPRITE& spr)
|
||||
{
|
||||
if (spr.pal == 5)
|
||||
return adjusthp(35);
|
||||
else if (spr.pal == 4)
|
||||
return adjusthp(25);
|
||||
|
||||
return adjusthp(e.health);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
void premapGoblin(short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.detail = GOBLINTYPE;
|
||||
|
||||
if (spr.hitag < 90 || spr.hitag > 99)
|
||||
enemy[GOBLINTYPE].info.set(spr);
|
||||
else {
|
||||
short ohitag = spr.hitag;
|
||||
enemy[GOBLINTYPE].info.set(spr);
|
||||
if (spr.pal != 0)
|
||||
spr.xrepeat = 30;
|
||||
spr.extra = 0;
|
||||
spr.owner = 0;
|
||||
spr.hitag = ohitag;
|
||||
return;
|
||||
}
|
||||
|
||||
if (spr.picnum == GOBLINCHILL) {
|
||||
changespritestat(i, STAND);
|
||||
spr.lotag = 30;
|
||||
if (krand() % 100 > 50)
|
||||
spr.extra = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
changespritestat(i, FACE);
|
||||
if (krand() % 100 > 50)
|
||||
spr.extra = 1;
|
||||
}
|
||||
|
||||
END_WH_NS
|
783
source/games/whaven/src/aigonzo.cpp
Normal file
783
source/games/whaven/src/aigonzo.cpp
Normal file
|
@ -0,0 +1,783 @@
|
|||
#include "ns.h"
|
||||
#include "wh.h"
|
||||
|
||||
BEGIN_WH_NS
|
||||
|
||||
static void gonzopike(short s, PLAYER& plr);
|
||||
static void checkexpl(PLAYER& plr, short i);
|
||||
static boolean patrolprocess(PLAYER& plr, short i);
|
||||
|
||||
static void chase(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0)
|
||||
spr.lotag = 250;
|
||||
|
||||
short osectnum = spr.sectnum;
|
||||
|
||||
switch (spr.picnum) {
|
||||
case GONZOGHM:
|
||||
case GONZOGSH:
|
||||
if (cansee(plr.x, plr.y, plr.z, plr.sector, spr.x, spr.y, spr.z - (tilesizy[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);
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if ((krand() & 0) == 1) {
|
||||
spr.ang = (short)(((krand() & 128 - 256) + spr.ang + 1024) & 2047);
|
||||
newstatus(i, FLEE);
|
||||
}
|
||||
if (krand() % 63 > 60) {
|
||||
spr.ang = (short)(((krand() & 128 - 256) + spr.ang + 1024) & 2047);
|
||||
newstatus(i, FLEE);
|
||||
break;
|
||||
}
|
||||
|
||||
int dax = spr.x; // Back up old x&y if stepping off cliff
|
||||
int day = spr.y;
|
||||
int daz = spr.z;
|
||||
|
||||
osectnum = spr.sectnum;
|
||||
int movestat = aimove(i);
|
||||
if ((movestat & kHitTypeMask) == kHitFloor)
|
||||
{
|
||||
spr.ang = (short)((spr.ang + 1024) & 2047);
|
||||
newstatus(i, FLEE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (zr_florz > spr.z + (48 << 8)) {
|
||||
spr.x = dax;
|
||||
spr.y = day;
|
||||
spr.z = daz;
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
movestat = 1;
|
||||
|
||||
if (rand() % 100 > 80 && sector[plr.sector].lotag == 25) {
|
||||
newstatus(i, AMBUSH);
|
||||
sprite[i].z -= (getPlayerHeight() << 6);
|
||||
sprite[i].lotag = 60;
|
||||
sprite[i].extra = 1;
|
||||
sprite[i].picnum = GONZOHMJUMP;
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ((movestat & 0xc000) == 32768 && sector[plr.sector].lotag == 25) {
|
||||
newstatus(i, AMBUSH);
|
||||
sprite[i].z -= (getPlayerHeight() << 6);
|
||||
sprite[i].lotag = 90;
|
||||
sprite[i].extra = 3;
|
||||
sprite[i].picnum = GONZOHMJUMP;
|
||||
return;
|
||||
}
|
||||
|
||||
if (movestat != 0) {
|
||||
if ((movestat & 4095) != plr.spritenum) {
|
||||
int daang;
|
||||
if ((krand() & 0) == 1)
|
||||
daang = (spr.ang + 256) & 2047;
|
||||
else
|
||||
daang = (spr.ang - 256) & 2047;
|
||||
spr.ang = (short)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);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
else {
|
||||
if (!patrolprocess(plr, i))
|
||||
newstatus(i, FLEE);
|
||||
}
|
||||
break;
|
||||
case GONZOCSW:
|
||||
case GONZOGSW:
|
||||
if (cansee(plr.x, plr.y, plr.z, plr.sector, spr.x, spr.y, spr.z - (tilesizy[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) == kHitFloor)
|
||||
{
|
||||
spr.ang = (short)((spr.ang + 1024) & 2047);
|
||||
newstatus(i, FLEE);
|
||||
return;
|
||||
}
|
||||
|
||||
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 {
|
||||
if (!patrolprocess(plr, i))
|
||||
newstatus(i, FLEE);
|
||||
}
|
||||
|
||||
getzrange(spr.x, spr.y, spr.z - 1, spr.sectnum, (spr.clipdist) << 2, CLIPMASK0);
|
||||
spr.z = zr_florz;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void resurect(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
newstatus(i, FACE);
|
||||
switch (spr.picnum) {
|
||||
case GONZOCSWDEAD:
|
||||
spr.picnum = GONZOCSW;
|
||||
spr.hitag = (short)adjusthp(50);
|
||||
break;
|
||||
case GONZOGSWDEAD:
|
||||
spr.picnum = GONZOGSW;
|
||||
spr.hitag = (short)adjusthp(100);
|
||||
break;
|
||||
case GONZOGHMDEAD:
|
||||
spr.picnum = GONZOGHM;
|
||||
spr.hitag = (short)adjusthp(40);
|
||||
break;
|
||||
case GONZOGSHDEAD:
|
||||
spr.picnum = GONZOGSH;
|
||||
spr.hitag = (short)adjusthp(50);
|
||||
break;
|
||||
}
|
||||
spr.lotag = 100;
|
||||
spr.cstat |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void skirmish(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
|
||||
if (spr.lotag < 0)
|
||||
newstatus(i, FACE);
|
||||
short osectnum = spr.sectnum;
|
||||
|
||||
int movestat = aimove(i);
|
||||
if ((movestat & kHitTypeMask) != kHitFloor && movestat != 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;
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void search(PLAYER& plr, short i) {
|
||||
aisearch(plr, i, false);
|
||||
if (!checksector6(i))
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void nuked(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
chunksofmeat(plr, i, spr.x, spr.y, spr.z, spr.sectnum, spr.ang);
|
||||
trailingsmoke(i, false);
|
||||
newstatus(i, DIE);
|
||||
}
|
||||
|
||||
static void frozen(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.pal = 0;
|
||||
switch (sprite[i].picnum) {
|
||||
case GONZOCSWPAIN:
|
||||
spr.picnum = GONZOCSW;
|
||||
break;
|
||||
case GONZOGSWPAIN:
|
||||
spr.picnum = GONZOGSW;
|
||||
break;
|
||||
case GONZOGHMPAIN:
|
||||
spr.picnum = GONZOGHM;
|
||||
break;
|
||||
case GONZOGSHPAIN:
|
||||
spr.picnum = GONZOGSH;
|
||||
break;
|
||||
}
|
||||
newstatus(i, FACE);
|
||||
}
|
||||
}
|
||||
|
||||
static void pain(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
switch (sprite[i].picnum) {
|
||||
case GONZOCSWPAIN:
|
||||
spr.picnum = GONZOCSW;
|
||||
break;
|
||||
case GONZOGSWPAIN:
|
||||
spr.picnum = GONZOGSW;
|
||||
break;
|
||||
case GONZOGHMPAIN:
|
||||
spr.picnum = GONZOGHM;
|
||||
break;
|
||||
case GONZOGSHPAIN:
|
||||
spr.picnum = GONZOGSH;
|
||||
break;
|
||||
}
|
||||
spr.ang = (short)plr.ang;
|
||||
newstatus(i, FLEE);
|
||||
}
|
||||
|
||||
aimove(i);
|
||||
processfluid(i, zr_florhit, false);
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void face(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 - (tilesizy[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 (plr.invisibletime < 0 && checkdist(plr, i))
|
||||
newstatus(i, ATTACK);
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void attack(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:
|
||||
case TYPEWATER:
|
||||
spr.z += tilesizy[spr.picnum] << 5;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (spr.picnum) {
|
||||
// WANGO
|
||||
case KURTREADY:
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 24;
|
||||
}
|
||||
break;
|
||||
case KURTREADY + 1:
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum = KURTAT;
|
||||
spr.lotag = 64;
|
||||
}
|
||||
break;
|
||||
case KURTAT:
|
||||
case KURTPUNCH:
|
||||
if (spr.lotag == 46) {
|
||||
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;
|
||||
break;
|
||||
case GONZOCSWAT:
|
||||
sprite[i].lotag -= TICSPERFRAME;
|
||||
if (sprite[i].lotag < 0) {
|
||||
if (cansee(plr.x, plr.y, plr.z, plr.sector, sprite[i].x, sprite[i].y,
|
||||
sprite[i].z - (tilesizy[sprite[i].picnum] << 7), sprite[i].sectnum))
|
||||
newstatus(i, CAST);
|
||||
else
|
||||
newstatus(i, CHASE);
|
||||
}
|
||||
else
|
||||
sprite[i].ang = getangle(plr.x - sprite[i].x, plr.y - sprite[i].y);
|
||||
break;
|
||||
case GONZOGSWAT:
|
||||
case GONZOGHMAT:
|
||||
case GONZOGSHAT:
|
||||
if (spr.lotag == 31) {
|
||||
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;
|
||||
break;
|
||||
}
|
||||
|
||||
checksector6(i);
|
||||
}
|
||||
|
||||
static void flee(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
short osectnum = spr.sectnum;
|
||||
|
||||
int movestat = aimove(i);
|
||||
|
||||
if ((movestat & kHitTypeMask) != kHitFloor && 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 {
|
||||
if (plr.invisibletime < 0) {
|
||||
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);
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void cast(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 12;
|
||||
}
|
||||
|
||||
if (spr.picnum == GONZOCSWAT) {
|
||||
spr.extra--;
|
||||
playsound_loc(S_GENTHROW, spr.x, spr.y);
|
||||
gonzopike(i, plr);
|
||||
newstatus(i, CHASE);
|
||||
}
|
||||
}
|
||||
|
||||
static void die(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
|
||||
if (spr.lotag <= 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 20;
|
||||
|
||||
switch (sprite[i].picnum) {
|
||||
case GONZOBSHDEAD:
|
||||
case GONZOCSWDEAD:
|
||||
case GONZOGSWDEAD:
|
||||
case GONZOGHMDEAD:
|
||||
case GONZOGSHDEAD:
|
||||
if (difficulty == 4)
|
||||
newstatus(i, RESURECT);
|
||||
else {
|
||||
kills++;
|
||||
newstatus(i, DEAD);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gonzoProcess(PLAYER& plr)
|
||||
{
|
||||
short nextsprite;
|
||||
for (short i = headspritestat[LAND]; i >= 0; i = nextsprite) {
|
||||
nextsprite = nextspritestat[i];
|
||||
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.lotag = 12;
|
||||
spr.picnum++;
|
||||
}
|
||||
|
||||
switch (spr.picnum) {
|
||||
case GONZOHMJUMPEND:
|
||||
spr.picnum = GONZOGSH;
|
||||
spr.detail = GONZOTYPE;
|
||||
enemy[GONZOTYPE].info.set(spr);
|
||||
sprite[i].hitag = adjusthp(100);
|
||||
newstatus(i, FACE);
|
||||
break;
|
||||
case GONZOSHJUMPEND:
|
||||
spr.picnum = GONZOGSH;
|
||||
spr.detail = GONZOTYPE;
|
||||
enemy[GONZOTYPE].info.set(spr);
|
||||
sprite[i].hitag = adjusthp(100);
|
||||
newstatus(i, FACE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
short movestat;
|
||||
for (short i = headspritestat[AMBUSH]; i >= 0; i = nextsprite) {
|
||||
nextsprite = nextspritestat[i];
|
||||
|
||||
SPRITE& spr = sprite[i];
|
||||
switch (spr.extra) {
|
||||
case 1: // forward
|
||||
spr.zvel += TICSPERFRAME << 3;
|
||||
|
||||
movestat = (short)movesprite(i, ((sintable[(spr.ang + 512) & 2047]) * TICSPERFRAME) << 3,
|
||||
((sintable[spr.ang]) * TICSPERFRAME) << 3, spr.zvel, 4 << 8, 4 << 8, 0);
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
|
||||
if (zr_florz <= spr.z && spr.lotag < 0) {
|
||||
spr.z = zr_florz;
|
||||
changespritestat(i, LAND);
|
||||
}
|
||||
|
||||
if ((movestat & 0xc000) == 49152) { // Bullet hit a sprite
|
||||
int k = (movestat & 4095);
|
||||
for (int j = 0; j < 15; j++) {
|
||||
shards(k, 1);
|
||||
}
|
||||
damageactor(plr, movestat, i);
|
||||
}
|
||||
|
||||
break;
|
||||
case 2: // fall
|
||||
spr.zvel += TICSPERFRAME << 4;
|
||||
|
||||
movestat = (short)movesprite(i, ((sintable[(spr.ang + 512) & 2047]) * TICSPERFRAME) << 1,
|
||||
((sintable[spr.ang]) * TICSPERFRAME) << 1, spr.zvel, 4 << 8, 4 << 8, 0);
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
|
||||
if (zr_florz <= spr.z && spr.lotag < 0) {
|
||||
spr.z = zr_florz;
|
||||
changespritestat(i, LAND);
|
||||
}
|
||||
|
||||
break;
|
||||
case 3: // jumpup
|
||||
|
||||
spr.zvel -= TICSPERFRAME << 4;
|
||||
|
||||
movestat = (short)movesprite(i, ((sintable[(spr.ang + 512) & 2047]) * TICSPERFRAME) << 3,
|
||||
((sintable[spr.ang]) * TICSPERFRAME) << 3, spr.zvel, 4 << 8, 4 << 8, 0);
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
|
||||
if (spr.lotag < 0) {
|
||||
spr.extra = 2;
|
||||
spr.lotag = 20;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static short searchpatrol(SPRITE& spr) {
|
||||
long mindist = 0x7fffffff;
|
||||
short target = -1;
|
||||
short j = headspritestat[APATROLPOINT];
|
||||
while (j != -1) {
|
||||
short nextj = nextspritestat[j];
|
||||
SPRITE tspr = sprite[j];
|
||||
long dist = klabs(tspr.x - spr.x) + klabs(tspr.y - spr.y);
|
||||
if (dist < mindist) {
|
||||
mindist = dist;
|
||||
target = j;
|
||||
}
|
||||
j = nextj;
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
static boolean patrolprocess(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
short target = searchpatrol(spr);
|
||||
if (target != -1) {
|
||||
SPRITE tspr = sprite[target];
|
||||
if (cansee(tspr.x, tspr.y, tspr.z, tspr.sectnum, spr.x, spr.y, spr.z - (tilesizy[spr.picnum] << 7),
|
||||
spr.sectnum)) {
|
||||
spr.ang = getangle(tspr.x - spr.x, tspr.y - spr.y);
|
||||
newstatus(i, PATROL);
|
||||
}
|
||||
}
|
||||
|
||||
return target != -1;
|
||||
}
|
||||
|
||||
static void gonzopike(short s, PLAYER& plr) {
|
||||
int j = insertsprite(sprite[s].sectnum, JAVLIN);
|
||||
if (j == -1)
|
||||
return;
|
||||
|
||||
SPRITE& spr = sprite[j];
|
||||
|
||||
spr.x = sprite[s].x;
|
||||
spr.y = sprite[s].y;
|
||||
spr.z = sprite[s].z - (40 << 8);
|
||||
|
||||
spr.cstat = 21;
|
||||
spr.picnum = THROWPIKE;
|
||||
spr.ang = (short)(((sprite[s].ang + 2048 + 96) - 512) & 2047);
|
||||
spr.xrepeat = 24;
|
||||
spr.yrepeat = 24;
|
||||
spr.clipdist = 32;
|
||||
|
||||
spr.extra = sprite[s].ang;
|
||||
spr.shade = -15;
|
||||
spr.xvel = (short)((krand() & 256) - 128);
|
||||
spr.yvel = (short)((krand() & 256) - 128);
|
||||
|
||||
spr.zvel = (short)(((plr.z + (8 << 8) - sprite[s].z) << 7) / engine
|
||||
.ksqrt((plr.x - sprite[s].x) * (plr.x - sprite[s].x) + (plr.y - sprite[s].y) * (plr.y - sprite[s].y)));
|
||||
|
||||
spr.zvel += ((krand() % 256) - 128);
|
||||
|
||||
spr.owner = s;
|
||||
spr.lotag = 1024;
|
||||
spr.hitag = 0;
|
||||
spr.pal = 0;
|
||||
|
||||
}
|
||||
|
||||
static void checkexpl(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
short j = headspritesect[spr.sectnum];
|
||||
while (j != -1) {
|
||||
short nextj = nextspritesect[j];
|
||||
long dx = klabs(spr.x - sprite[j].x); // x distance to sprite
|
||||
long dy = klabs(spr.y - sprite[j].y); // y distance to sprite
|
||||
long dz = klabs((spr.z >> 8) - (sprite[j].z >> 8)); // z distance to sprite
|
||||
long dh = tilesizy[sprite[j].picnum] >> 1; // height of sprite
|
||||
if (dx + dy < PICKDISTANCE && dz - dh <= getPickHeight()) {
|
||||
if (sprite[j].picnum == EXPLO2
|
||||
|| sprite[j].picnum == MONSTERBALL) {
|
||||
spr.hitag -= TICSPERFRAME << 2;
|
||||
if (spr.hitag < 0) {
|
||||
newstatus(i, DIE);
|
||||
}
|
||||
}
|
||||
}
|
||||
j = nextj;
|
||||
}
|
||||
}
|
||||
|
||||
void createGonzoAI() {
|
||||
auto &e = enemy[GONZOTYPE];
|
||||
e.info.Init(35, 35, 1024 + 256, 120, 0, 48, false, 50, 0);
|
||||
e.info.getAttackDist = [](EnemyInfo& e, SPRITE& spr)
|
||||
{
|
||||
int out = e.attackdist;
|
||||
switch (spr.picnum) {
|
||||
case KURTAT:
|
||||
case GONZOCSW:
|
||||
case GONZOCSWAT:
|
||||
if (spr.extra > 10)
|
||||
out = 2048 << 1;
|
||||
break;
|
||||
}
|
||||
|
||||
return out;
|
||||
};
|
||||
|
||||
e.info.getHealth = [](EnemyInfo& e, SPRITE& spr)
|
||||
{
|
||||
switch (spr.picnum) {
|
||||
case KURTAT:
|
||||
return 10;
|
||||
case KURTPUNCH:
|
||||
return adjusthp(15);
|
||||
case GONZOGSW:
|
||||
return adjusthp(100);
|
||||
case GONZOGHM:
|
||||
return adjusthp(40);
|
||||
}
|
||||
|
||||
return adjusthp(e.health);
|
||||
};
|
||||
e.chase = chase;
|
||||
e.resurect = resurect;
|
||||
e.skirmish = skirmish;
|
||||
e.search = search;
|
||||
e.nuked = nuked;
|
||||
e.frozen = frozen;
|
||||
e.pain = pain;
|
||||
e.face = face;
|
||||
e.attack = attack;
|
||||
e.flee = flee;
|
||||
e.cast = cast;
|
||||
e.die = die;
|
||||
}
|
||||
|
||||
|
||||
void premapGonzo(short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.detail = GONZOTYPE;
|
||||
enemy[GONZOTYPE].info.set(spr);
|
||||
changespritestat(i, FACE);
|
||||
|
||||
switch (spr.picnum) {
|
||||
case KURTAT:
|
||||
spr.picnum = GONZOCSW;
|
||||
break;
|
||||
case KURTPUNCH:
|
||||
spr.extra = 0;
|
||||
spr.picnum = GONZOCSW;
|
||||
break;
|
||||
case GONZOCSW:
|
||||
spr.extra = 20;
|
||||
break;
|
||||
case GONZOGSW:
|
||||
case GONZOGHM:
|
||||
case GONZOGSH:
|
||||
spr.clipdist = 32;
|
||||
spr.extra = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void deaddude(short sn) {
|
||||
int j = insertsprite(sprite[sn].sectnum, DEAD);
|
||||
sprite[j].x = sprite[sn].x;
|
||||
sprite[j].y = sprite[sn].y;
|
||||
sprite[j].z = sprite[sn].z;
|
||||
sprite[j].cstat = 0;
|
||||
sprite[j].picnum = GONZOBSHDEAD;
|
||||
sprite[j].shade = sector[sprite[sn].sectnum].floorshade;
|
||||
sprite[j].pal = 0;
|
||||
sprite[j].xrepeat = sprite[sn].xrepeat;
|
||||
sprite[j].yrepeat = sprite[sn].yrepeat;
|
||||
sprite[j].owner = 0;
|
||||
sprite[j].lotag = 0;
|
||||
sprite[j].hitag = 0;
|
||||
}
|
||||
|
||||
END_WH_NS
|
529
source/games/whaven/src/aigron.cpp
Normal file
529
source/games/whaven/src/aigron.cpp
Normal file
|
@ -0,0 +1,529 @@
|
|||
#include "ns.h"
|
||||
#include "wh.h"
|
||||
|
||||
BEGIN_WH_NS
|
||||
|
||||
static void checkexpl(PLAYER& plr, short i);
|
||||
static void throwhalberd(int s);
|
||||
|
||||
|
||||
static void chase(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0)
|
||||
spr.lotag = 250;
|
||||
|
||||
short osectnum = spr.sectnum;
|
||||
|
||||
if (spr.picnum == GRONSW) {
|
||||
if (cansee(plr.x, plr.y, plr.z, plr.sector, spr.x, spr.y, spr.z - (tilesizy[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) == kHitFloor)
|
||||
{
|
||||
spr.ang = (short)((spr.ang + 1024) & 2047);
|
||||
newstatus(i, FLEE);
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (krand() % 63 == 0) {
|
||||
if (cansee(plr.x, plr.y, plr.z, plr.sector, sprite[i].x, sprite[i].y,
|
||||
sprite[i].z - (tilesizy[sprite[i].picnum] << 7), sprite[i].sectnum))// && invisibletime < 0)
|
||||
newstatus(i, ATTACK);
|
||||
}
|
||||
else {
|
||||
checksight(plr, i);
|
||||
if (!checkdist(plr, i)) {
|
||||
if ((aimove(i) & kHitTypeMask) == kHitFloor)
|
||||
{
|
||||
spr.ang = (short)((spr.ang + 1024) & 2047);
|
||||
newstatus(i, FLEE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (krand() % 8 == 0) // NEW
|
||||
newstatus(i, ATTACK); // NEW
|
||||
else { // NEW
|
||||
sprite[i].ang = (short)(((krand() & 512 - 256) + sprite[i].ang + 1024) & 2047); // NEW
|
||||
newstatus(i, FLEE); // NEW
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getzrange(spr.x, spr.y, spr.z - 1, spr.sectnum, (spr.clipdist) << 2, CLIPMASK0);
|
||||
spr.z = zr_florz;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void resurect(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
newstatus(i, FACE);
|
||||
switch (krand() % 3) {
|
||||
case 0:
|
||||
sprite[i].picnum = GRONHAL;
|
||||
sprite[i].hitag = (short)adjusthp(120);
|
||||
sprite[i].extra = 3;
|
||||
break;
|
||||
case 1:
|
||||
sprite[i].picnum = GRONSW;
|
||||
sprite[i].hitag = (short)adjusthp(120);
|
||||
sprite[i].extra = 0;
|
||||
break;
|
||||
case 2:
|
||||
sprite[i].picnum = GRONMU;
|
||||
sprite[i].hitag = (short)adjusthp(120);
|
||||
sprite[i].extra = 2;
|
||||
break;
|
||||
}
|
||||
spr.lotag = 100;
|
||||
spr.cstat |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void skirmish(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
|
||||
if (spr.lotag < 0)
|
||||
newstatus(i, FACE);
|
||||
short osectnum = spr.sectnum;
|
||||
int movestat = aimove(i);
|
||||
if ((movestat & kHitTypeMask) != kHitFloor && movestat != 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;
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void search(PLAYER& plr, short i) {
|
||||
aisearch(plr, i, false);
|
||||
if (!checksector6(i))
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void nuked(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
if (game.WH2) {
|
||||
chunksofmeat(plr, i, spr.x, spr.y, spr.z, spr.sectnum, spr.ang);
|
||||
trailingsmoke(i, false);
|
||||
newstatus((short)i, DIE);
|
||||
return;
|
||||
}
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 24;
|
||||
if (spr.picnum == GRONCHAR + 4) {
|
||||
trailingsmoke(i, false);
|
||||
deletesprite(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void frozen(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.pal = 0;
|
||||
if (sprite[i].picnum == GRONHALDIE)
|
||||
sprite[i].picnum = GRONHAL;
|
||||
else if (sprite[i].picnum == GRONSWDIE)
|
||||
sprite[i].picnum = GRONSW;
|
||||
else if (sprite[i].picnum == GRONMUDIE)
|
||||
sprite[i].picnum = GRONMU;
|
||||
newstatus(i, FACE);
|
||||
}
|
||||
}
|
||||
|
||||
static void pain(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
if (sprite[i].picnum == GRONHALPAIN)
|
||||
sprite[i].picnum = GRONHAL;
|
||||
else if (sprite[i].picnum == GRONSWPAIN)
|
||||
sprite[i].picnum = GRONSW;
|
||||
else if (sprite[i].picnum == GRONMUPAIN)
|
||||
sprite[i].picnum = GRONMU;
|
||||
|
||||
spr.ang = (short)plr.ang;
|
||||
newstatus(i, FLEE);
|
||||
}
|
||||
|
||||
aimove(i);
|
||||
processfluid(i, zr_florhit, false);
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void face(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 - (tilesizy[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);
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void attack(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
if (spr.picnum == GRONSWATTACK) {
|
||||
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 += tilesizy[spr.picnum] << 5;
|
||||
break;
|
||||
}
|
||||
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
|
||||
if (spr.lotag == 31) {
|
||||
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;
|
||||
}
|
||||
else {
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
if (cansee(plr.x, plr.y, plr.z, plr.sector, sprite[i].x, sprite[i].y,
|
||||
spr.z - (tilesizy[sprite[i].picnum] << 7), sprite[i].sectnum))
|
||||
newstatus(i, CAST);
|
||||
else
|
||||
newstatus(i, CHASE);
|
||||
}
|
||||
else
|
||||
spr.ang = getangle(plr.x - sprite[i].x, plr.y - sprite[i].y);
|
||||
}
|
||||
|
||||
checksector6(i);
|
||||
}
|
||||
|
||||
static void flee(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
short osectnum = spr.sectnum;
|
||||
|
||||
int movestat = aimove(i);
|
||||
if ((movestat & kHitTypeMask) != kHitFloor && 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);
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void cast(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
if (spr.picnum == GRONHALATTACK) {
|
||||
spr.extra--;
|
||||
playsound_loc(S_THROWPIKE, sprite[i].x, sprite[i].y);
|
||||
throwhalberd(i);
|
||||
newstatus(i, CHASE);
|
||||
}
|
||||
else if (spr.picnum == GRONMUATTACK) {
|
||||
spr.extra--;
|
||||
playsound_loc(S_SPELL2, sprite[i].x, sprite[i].y);
|
||||
castspell(plr, i);
|
||||
newstatus(i, CHASE);
|
||||
}
|
||||
}
|
||||
|
||||
checksector6(i);
|
||||
}
|
||||
|
||||
static void die(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
|
||||
if (spr.picnum == GRONSWDIE || spr.picnum == GRONHALDIE || spr.picnum == GRONMUDIE)
|
||||
{
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum = GRONDIE;
|
||||
spr.lotag = 20;
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
if (spr.lotag <= 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 20;
|
||||
|
||||
if (spr.picnum == GRONDEAD) {
|
||||
if (difficulty == 4)
|
||||
newstatus(i, RESURECT);
|
||||
else {
|
||||
kills++;
|
||||
newstatus(i, DEAD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void checkexpl(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
short j = headspritesect[spr.sectnum];
|
||||
while (j != -1) {
|
||||
short nextj = nextspritesect[j];
|
||||
long dx = klabs(spr.x - sprite[j].x); // x distance to sprite
|
||||
long dy = klabs(spr.y - sprite[j].y); // y distance to sprite
|
||||
long dz = klabs((spr.z >> 8) - (sprite[j].z >> 8)); // z distance to sprite
|
||||
long dh = tilesizy[sprite[j].picnum] >> 1; // height of sprite
|
||||
if (dx + dy < PICKDISTANCE && dz - dh <= getPickHeight()) {
|
||||
if (sprite[j].picnum == EXPLO2
|
||||
|| sprite[j].picnum == MONSTERBALL) {
|
||||
spr.hitag -= TICSPERFRAME << 2;
|
||||
if (spr.hitag < 0) {
|
||||
newstatus(i, DIE);
|
||||
}
|
||||
}
|
||||
}
|
||||
j = nextj;
|
||||
}
|
||||
}
|
||||
|
||||
static void throwhalberd(int s) {
|
||||
int j = insertsprite(sprite[s].sectnum, JAVLIN);
|
||||
|
||||
if (j == -1)
|
||||
return;
|
||||
SPRITE& spr = sprite[j];
|
||||
spr.x = sprite[s].x;
|
||||
spr.y = sprite[s].y;
|
||||
spr.z = sprite[s].z - (40 << 8);
|
||||
|
||||
spr.cstat = 17;
|
||||
|
||||
spr.picnum = THROWHALBERD;
|
||||
spr.detail = THROWHALBERDTYPE;
|
||||
spr.ang = (short)(((sprite[s].ang + 2048) - 512) & 2047);
|
||||
spr.xrepeat = 8;
|
||||
spr.yrepeat = 16;
|
||||
spr.clipdist = 32;
|
||||
|
||||
spr.extra = sprite[s].ang;
|
||||
spr.shade = -15;
|
||||
spr.xvel = (short)((krand() & 256) - 128);
|
||||
spr.yvel = (short)((krand() & 256) - 128);
|
||||
spr.zvel = (short)((krand() & 256) - 128);
|
||||
spr.owner = (short)s;
|
||||
spr.lotag = 0;
|
||||
spr.hitag = 0;
|
||||
spr.pal = 0;
|
||||
|
||||
spr.cstat = 0;
|
||||
int daz = (((spr.zvel) * TICSPERFRAME) >> 3);
|
||||
movesprite((short)j, ((sintable[(spr.extra + 512) & 2047]) * TICSPERFRAME) << 7,
|
||||
((sintable[spr.extra & 2047]) * TICSPERFRAME) << 7, daz, 4 << 8, 4 << 8, 1);
|
||||
spr.cstat = 21;
|
||||
}
|
||||
|
||||
void createGronAI() {
|
||||
auto& e = enemy[GRONTYPE];
|
||||
e.info.Init(game.WH2 ? 35 : 30, game.WH2 ? 35 : 30, -1, 120, 0, 64, false, 300, 0);
|
||||
e.info.getAttackDist = [](EnemyInfo& e, SPRITE& spr)
|
||||
{
|
||||
int out = e.attackdist;
|
||||
int pic = spr.picnum;
|
||||
|
||||
if (pic == GRONHAL || pic == GRONHALATTACK)
|
||||
out = 1024 + 512;
|
||||
else if (pic == GRONMU || pic == GRONMUATTACK)
|
||||
out = 2048;
|
||||
else if (pic == GRONSW || pic == GRONSWATTACK)
|
||||
out = 1024 + 256;
|
||||
|
||||
return out;
|
||||
};
|
||||
|
||||
e.info.getHealth = [](EnemyInfo& e, SPRITE& spr)
|
||||
{
|
||||
if (game.WH2) {
|
||||
if (spr.picnum == GRONHAL)
|
||||
return adjusthp(65);
|
||||
if (spr.picnum == GRONMU)
|
||||
return adjusthp(70);
|
||||
}
|
||||
return adjusthp(e.health);
|
||||
};
|
||||
e.chase = chase;
|
||||
e.resurect = resurect;
|
||||
e.skirmish = skirmish;
|
||||
e.search = search;
|
||||
e.nuked = nuked;
|
||||
e.frozen = frozen;
|
||||
e.pain = pain;
|
||||
e.face = face;
|
||||
e.attack = attack;
|
||||
e.flee = flee;
|
||||
e.cast = cast;
|
||||
e.die = die;
|
||||
}
|
||||
|
||||
|
||||
void premapGron(short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
if (spr.picnum == GRONSW && spr.pal == 10)
|
||||
deletesprite(i);
|
||||
|
||||
spr.detail = GRONTYPE;
|
||||
enemy[GRONTYPE].info.set(spr);
|
||||
changespritestat(i, FACE);
|
||||
|
||||
if (spr.picnum == GRONHAL)
|
||||
spr.extra = 4;
|
||||
else if (spr.picnum == GRONSW)
|
||||
spr.extra = 0;
|
||||
else if (spr.picnum == GRONMU)
|
||||
spr.extra = 2;
|
||||
}
|
||||
|
||||
END_WH_NS
|
249
source/games/whaven/src/aiguardian.cpp
Normal file
249
source/games/whaven/src/aiguardian.cpp
Normal file
|
@ -0,0 +1,249 @@
|
|||
#include "ns.h"
|
||||
#include "wh.h"
|
||||
|
||||
BEGIN_WH_NS
|
||||
|
||||
static void chase(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0)
|
||||
spr.lotag = 250;
|
||||
|
||||
short osectnum = spr.sectnum;
|
||||
if (plr.z < spr.z)
|
||||
spr.z -= TICSPERFRAME << 8;
|
||||
if (plr.z > spr.z)
|
||||
spr.z += TICSPERFRAME << 8;
|
||||
|
||||
if (krand() % 63 == 0) {
|
||||
if (cansee(plr.x, plr.y, plr.z, plr.sector, sprite[i].x, sprite[i].y,
|
||||
sprite[i].z - (tilesizy[sprite[i].picnum] << 7), sprite[i].sectnum) && plr.invisibletime < 0)
|
||||
newstatus(i, ATTACK);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
int dax = (sintable[(sprite[i].ang + 512) & 2047] * TICSPERFRAME) << 3;
|
||||
int day = (sintable[sprite[i].ang & 2047] * TICSPERFRAME) << 3;
|
||||
checksight(plr, i);
|
||||
|
||||
if (totalclock % 100 > 70)
|
||||
trailingsmoke(i, true);
|
||||
|
||||
if (!checkdist(plr, i)) {
|
||||
checkmove(i, dax, day);
|
||||
}
|
||||
else {
|
||||
if (krand() % 8 == 0) // NEW
|
||||
newstatus(i, ATTACK); // NEW
|
||||
else { // NEW
|
||||
sprite[i].ang = (short)(((krand() & 512 - 256) + sprite[i].ang + 1024) & 2047); // NEW
|
||||
newstatus(i, CHASE); // NEW
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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, true);
|
||||
|
||||
if (sector[osectnum].lotag == KILLSECTOR) {
|
||||
spr.hitag--;
|
||||
if (spr.hitag < 0)
|
||||
newstatus(i, DIE);
|
||||
}
|
||||
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
|
||||
if (!isValidSector(spr.sectnum))
|
||||
return;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
static void nuked(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
if (game.WH2) {
|
||||
chunksofmeat(plr, i, spr.x, spr.y, spr.z, spr.sectnum, spr.ang);
|
||||
trailingsmoke(i, false);
|
||||
newstatus((short)i, DIE);
|
||||
return;
|
||||
}
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 24;
|
||||
if (spr.picnum == GUARDIANCHAR + 4) {
|
||||
trailingsmoke(i, false);
|
||||
deletesprite(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void attack(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
if (plr.z < spr.z) {
|
||||
spr.z -= TICSPERFRAME << 8;
|
||||
}
|
||||
if (plr.z > spr.z) {
|
||||
spr.z += TICSPERFRAME << 8;
|
||||
}
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
if (cansee(plr.x, plr.y, plr.z, plr.sector, spr.x, spr.y, spr.z - (tilesizy[spr.picnum] << 7),
|
||||
spr.sectnum))
|
||||
newstatus(i, CAST);
|
||||
else
|
||||
newstatus(i, CHASE);
|
||||
}
|
||||
else
|
||||
spr.ang = getangle(plr.x - spr.x, plr.y - spr.y);
|
||||
}
|
||||
|
||||
static void face(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 - (tilesizy[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);
|
||||
}
|
||||
|
||||
static void search(PLAYER& plr, short i) {
|
||||
aisearch(plr, i, true);
|
||||
checksector6(i);
|
||||
}
|
||||
|
||||
static void flee(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
short osectnum = spr.sectnum;
|
||||
|
||||
if (totalclock % 100 > 70)
|
||||
trailingsmoke(i, true);
|
||||
|
||||
int movestat = aifly(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, true);
|
||||
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
}
|
||||
|
||||
static void pain(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum = GUARDIAN;
|
||||
spr.ang = (short)plr.ang;
|
||||
newstatus(i, FLEE);
|
||||
}
|
||||
|
||||
// aifly(i);
|
||||
// setsprite(i, spr.x, spr.y, spr.z);
|
||||
}
|
||||
|
||||
static void cast(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
|
||||
if (plr.z < spr.z) {
|
||||
spr.z -= TICSPERFRAME << 8;
|
||||
}
|
||||
if (plr.z > spr.z) {
|
||||
spr.z += TICSPERFRAME << 8;
|
||||
}
|
||||
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 12;
|
||||
}
|
||||
|
||||
if (spr.picnum == GUARDIANATTACK + 6) {
|
||||
spr.picnum = GUARDIAN;
|
||||
playsound_loc(S_FIREBALL, sprite[i].x, sprite[i].y);
|
||||
castspell(plr, i);
|
||||
newstatus(i, CHASE);
|
||||
}
|
||||
checksector6(i);
|
||||
}
|
||||
|
||||
|
||||
void createGuardianAI() {
|
||||
auto& e = enemy[GUARDIANTYPE];
|
||||
e.info.Init(game.WH2 ? 35 : 32, game.WH2 ? 35 : 32, 4096, 120, 0, 64, true, game.WH2 ? 100 : 200, 0);
|
||||
e.chase = chase;
|
||||
e.nuked = nuked;
|
||||
e.attack = attack;
|
||||
e.face = face;
|
||||
e.search = search;
|
||||
e.flee = flee;
|
||||
e.pain = pain;
|
||||
e.cast = cast;
|
||||
}
|
||||
|
||||
void premapGuardian(short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.detail = GUARDIANTYPE;
|
||||
enemy[GUARDIANTYPE].info.set(spr);
|
||||
changespritestat(i, FACE);
|
||||
}
|
||||
|
||||
END_WH_NS
|
340
source/games/whaven/src/aiimp.cpp
Normal file
340
source/games/whaven/src/aiimp.cpp
Normal file
|
@ -0,0 +1,340 @@
|
|||
#include "ns.h"
|
||||
#include "wh.h"
|
||||
|
||||
BEGIN_WH_NS
|
||||
|
||||
static void checkexpl(PLAYER& plr, short i);
|
||||
|
||||
static void chase(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 - (tilesizy[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) == kHitFloor)
|
||||
{
|
||||
spr.ang = (short)((spr.ang + 1024) & 2047);
|
||||
newstatus(i, FLEE);
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
spr.z = zr_florz;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void frozen(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.pal = 0;
|
||||
spr.picnum = IMP;
|
||||
newstatus(i, FACE);
|
||||
}
|
||||
}
|
||||
|
||||
static void pain(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum = IMP;
|
||||
spr.ang = (short)plr.ang;
|
||||
newstatus(i, FLEE);
|
||||
}
|
||||
|
||||
aimove(i);
|
||||
processfluid(i, zr_florhit, false);
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
}
|
||||
|
||||
static void die(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
|
||||
if (spr.lotag <= 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 20;
|
||||
|
||||
if (spr.picnum == IMPDEAD) {
|
||||
if (difficulty == 4)
|
||||
newstatus(i, RESURECT);
|
||||
else {
|
||||
kills++;
|
||||
newstatus(i, DEAD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void nuked(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
chunksofmeat(plr, i, spr.x, spr.y, spr.z, spr.sectnum, spr.ang);
|
||||
trailingsmoke(i, false);
|
||||
newstatus((short)i, DIE);
|
||||
}
|
||||
|
||||
static void resurect(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
newstatus(i, FACE);
|
||||
spr.picnum = IMP;
|
||||
spr.hitag = (short)adjusthp(20);
|
||||
spr.lotag = 100;
|
||||
spr.cstat |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void face(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 - (tilesizy[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);
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void flee(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
short osectnum = spr.sectnum;
|
||||
|
||||
int movestat = aimove(i);
|
||||
|
||||
if ((movestat & kHitTypeMask) != kHitFloor && 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);
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void attack(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 += tilesizy[spr.picnum] << 5;
|
||||
break;
|
||||
}
|
||||
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
if (spr.lotag == 32) { //original 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 search(PLAYER& plr, short i) {
|
||||
aisearch(plr, i, false);
|
||||
if (!checksector6(i))
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void skirmish(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
|
||||
if (spr.lotag < 0)
|
||||
newstatus(i, FACE);
|
||||
short osectnum = spr.sectnum;
|
||||
int movestat = aimove(i);
|
||||
if ((movestat & kHitTypeMask) != kHitFloor && movestat != 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;
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void checkexpl(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
short j = headspritesect[spr.sectnum];
|
||||
while (j != -1) {
|
||||
short nextj = nextspritesect[j];
|
||||
long dx = klabs(spr.x - sprite[j].x); // x distance to sprite
|
||||
long dy = klabs(spr.y - sprite[j].y); // y distance to sprite
|
||||
long dz = klabs((spr.z >> 8) - (sprite[j].z >> 8)); // z distance to sprite
|
||||
long dh = tilesizy[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 createImpAI() {
|
||||
auto &e = enemy[IMPTYPE];
|
||||
e.info.Init(25, 25, 1024, 120, 0, 64, false, 20, 0);
|
||||
e.chase = chase;
|
||||
e.frozen = frozen;
|
||||
e.pain = pain;
|
||||
e.die = die;
|
||||
e.nuked = nuked;
|
||||
e.resurect = resurect;
|
||||
e.face = face;
|
||||
e.flee = flee;
|
||||
e.attack = attack;
|
||||
e.search = search;
|
||||
e.skirmish = skirmish;
|
||||
}
|
||||
|
||||
|
||||
void premapImp(short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.detail = IMPTYPE;
|
||||
enemy[IMPTYPE].info.set(spr);
|
||||
changespritestat(i, FACE);
|
||||
spr.shade = -4;
|
||||
}
|
||||
}
|
||||
END_WH_NS
|
423
source/games/whaven/src/aijudy.cpp
Normal file
423
source/games/whaven/src/aijudy.cpp
Normal file
|
@ -0,0 +1,423 @@
|
|||
#include "ns.h"
|
||||
#include "wh.h"
|
||||
|
||||
BEGIN_WH_NS
|
||||
|
||||
static void spawnabaddy(int i, int monster);
|
||||
|
||||
static void chase(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0)
|
||||
spr.lotag = 250;
|
||||
|
||||
short osectnum = spr.sectnum;
|
||||
|
||||
if (mapon < 24) {
|
||||
sprite[i].extra -= TICSPERFRAME;
|
||||
if (sprite[i].extra < 0) {
|
||||
for (int j = 0; j < 8; j++)
|
||||
trailingsmoke(i, true);
|
||||
deletesprite((short)i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (krand() % 63 == 0) {
|
||||
if (cansee(plr.x, plr.y, plr.z, plr.sector, sprite[i].x, sprite[i].y,
|
||||
sprite[i].z - (tilesizy[sprite[i].picnum] << 7), sprite[i].sectnum))// && invisibletime < 0)
|
||||
newstatus(i, ATTACK);
|
||||
}
|
||||
else {
|
||||
checksight(plr, i);
|
||||
if (!checkdist(i, plr.x, plr.y, plr.z)) {
|
||||
int movestat = aimove(i);
|
||||
if ((movestat & kHitTypeMask) == kHitFloor)
|
||||
{
|
||||
spr.ang = (short)((spr.ang + 1024) & 2047);
|
||||
newstatus(i, FLEE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (krand() % 8 == 0) // NEW
|
||||
newstatus(i, ATTACK); // NEW
|
||||
else { // NEW
|
||||
sprite[i].ang = (short)(((krand() & 512 - 256) + sprite[i].ang + 1024) & 2047); // NEW
|
||||
newstatus(i, FLEE); // NEW
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getzrange(spr.x, spr.y, spr.z - 1, spr.sectnum, (spr.clipdist) << 2, CLIPMASK0);
|
||||
spr.z = zr_florz;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void resurect(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
newstatus(i, FACE);
|
||||
spr.picnum = JUDY;
|
||||
spr.hitag = (short)adjusthp(200);
|
||||
spr.lotag = 100;
|
||||
spr.cstat |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void search(PLAYER& plr, short i) {
|
||||
aisearch(plr, i, false);
|
||||
checksector6(i);
|
||||
}
|
||||
|
||||
static void nuked(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 24;
|
||||
if (spr.picnum == JUDYCHAR + 4) {
|
||||
trailingsmoke(i, false);
|
||||
deletesprite(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void pain(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum = JUDY;
|
||||
spr.ang = (short)plr.ang;
|
||||
newstatus(i, FLEE);
|
||||
}
|
||||
|
||||
aimove(i);
|
||||
processfluid(i, zr_florhit, false);
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
}
|
||||
|
||||
static void face(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.ang = getangle(plr.x - spr.x, plr.y - spr.y);
|
||||
|
||||
boolean cansee = cansee(plr.x, plr.y, plr.z, plr.sector, spr.x, spr.y, spr.z - (tilesizy[spr.picnum] << 7),
|
||||
spr.sectnum);
|
||||
|
||||
if (cansee && plr.invisibletime < 0) {
|
||||
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(i, plr.x, plr.y, plr.z))
|
||||
newstatus(i, ATTACK);
|
||||
}
|
||||
|
||||
static void attack(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:
|
||||
case TYPEWATER:
|
||||
spr.z += tilesizy[spr.picnum] << 5;
|
||||
break;
|
||||
}
|
||||
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
|
||||
sprite[i].extra -= TICSPERFRAME;
|
||||
sprite[i].lotag -= TICSPERFRAME;
|
||||
if (sprite[i].lotag < 0) {
|
||||
if (cansee(plr.x, plr.y, plr.z, plr.sector, sprite[i].x, sprite[i].y,
|
||||
sprite[i].z - (tilesizy[sprite[i].picnum] << 7), sprite[i].sectnum))
|
||||
newstatus(i, CAST);
|
||||
else
|
||||
newstatus(i, CHASE);
|
||||
}
|
||||
else
|
||||
sprite[i].ang = getangle(plr.x - sprite[i].x, plr.y - sprite[i].y);
|
||||
}
|
||||
|
||||
static void flee(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
short osectnum = spr.sectnum;
|
||||
|
||||
int movestat = aimove(i);
|
||||
if ((movestat & kHitTypeMask) != kHitFloor && 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);
|
||||
}
|
||||
|
||||
static void cast(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 12;
|
||||
}
|
||||
|
||||
if (spr.picnum == JUDYATTACK1 + 3) {
|
||||
sprite[i].picnum = JUDYATTACK1;
|
||||
playsound_loc(S_JUDY1 + krand() % 4, sprite[i].x, sprite[i].y);
|
||||
if (krand() % 100 > 70) {
|
||||
castspell(plr, i);
|
||||
}
|
||||
else {
|
||||
if (krand() % 100 > 40) {
|
||||
// raise the dead
|
||||
short j = headspritestat[DEAD];
|
||||
while (j >= 0) {
|
||||
short nextj = nextspritestat[j];
|
||||
sprite[j].lotag = (short)((krand() % 120) + 120);
|
||||
kills--;
|
||||
newstatus(j, RESURECT);
|
||||
j = nextj;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (krand() % 100 > 50) {
|
||||
// curse
|
||||
for (int j = 1; j < 9; j++) {
|
||||
plr.ammo[j] = 3;
|
||||
}
|
||||
}
|
||||
else {
|
||||
int j = krand() % 5;
|
||||
switch (j) {
|
||||
case 0:// SPAWN WILLOW
|
||||
spawnabaddy(i, WILLOW);
|
||||
break;
|
||||
case 1:// SPAWN 10 SPIDERS
|
||||
for (j = 0; j < 4; j++) {
|
||||
spawnabaddy(i, SPIDER);
|
||||
}
|
||||
break;
|
||||
case 2:// SPAWN 2 GRONSW
|
||||
for (j = 0; j < 2; j++) {
|
||||
spawnabaddy(i, GRONSW);
|
||||
}
|
||||
break;
|
||||
case 3:// SPAWN SKELETONS
|
||||
for (j = 0; j < 4; j++) {
|
||||
spawnabaddy(i, SKELETON);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
castspell(plr, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
newstatus(i, CHASE);
|
||||
}
|
||||
else if (spr.picnum == JUDYATTACK2 + 8) {
|
||||
sprite[i].picnum = JUDYATTACK2;
|
||||
playsound_loc(S_JUDY1 + krand() % 4, sprite[i].x, sprite[i].y);
|
||||
if (krand() % 100 > 50)
|
||||
skullycastspell(plr, i);
|
||||
else {
|
||||
if (krand() % 100 > 70) {
|
||||
if (krand() % 100 > 50) {
|
||||
plr.health = 0;
|
||||
addhealth(plr, 1);
|
||||
}
|
||||
else {
|
||||
addarmor(plr, -(plr.armor));
|
||||
plr.armortype = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
int j = krand() % 5;
|
||||
switch (j) {
|
||||
case 0:// SPAWN WILLOW
|
||||
spawnabaddy(i, WILLOW);
|
||||
break;
|
||||
case 1:// SPAWN 6 SPIDERS
|
||||
for (j = 0; j < 4; j++) {
|
||||
spawnabaddy(i, SPIDER);
|
||||
}
|
||||
break;
|
||||
case 2:// SPAWN 2 GRONSW
|
||||
for (j = 0; j < 2; j++) {
|
||||
spawnabaddy(i, GRONSW);
|
||||
}
|
||||
break;
|
||||
case 3:// SPAWN SKELETONS
|
||||
for (j = 0; j < 4; j++) {
|
||||
spawnabaddy(i, SKELETON);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
castspell(plr, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
newstatus(i, CHASE);
|
||||
}
|
||||
checksector6(i);
|
||||
}
|
||||
|
||||
static void die(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
|
||||
if (spr.lotag <= 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 20;
|
||||
|
||||
if (spr.picnum == JUDYDEAD) {
|
||||
if (difficulty == 4)
|
||||
newstatus(i, RESURECT);
|
||||
else {
|
||||
kills++;
|
||||
newstatus(i, DEAD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void judyOperate(PLAYER& plr)
|
||||
{
|
||||
short nextsprite;
|
||||
for (short i = headspritestat[WITCHSIT]; i >= 0; i = nextsprite) {
|
||||
nextsprite = nextspritestat[i];
|
||||
|
||||
sprite[i].ang = (short)(getangle(plr.x - sprite[i].x, plr.y - sprite[i].y) & 2047);
|
||||
if (cansee(plr.x, plr.y, plr.z, plr.sector, sprite[i].x, sprite[i].y,
|
||||
sprite[i].z - (tilesizy[sprite[i].picnum] << 7), sprite[i].sectnum)) {
|
||||
sprite[i].lotag -= TICSPERFRAME;
|
||||
if (sprite[i].lotag < 0) {
|
||||
sprite[i].picnum++;
|
||||
sprite[i].lotag = 12;
|
||||
if (sprite[i].picnum == JUDYSIT + 4) {
|
||||
sprite[i].picnum = JUDY;
|
||||
newstatus(i, FACE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void spawnabaddy(int i, int monster) {
|
||||
short j = insertsprite(sprite[i].sectnum, FACE);
|
||||
|
||||
sprite[j].x = sprite[i].x + (krand() & 2048) - 1024;
|
||||
sprite[j].y = sprite[i].y + (krand() & 2048) - 1024;
|
||||
sprite[j].z = sprite[i].z;
|
||||
|
||||
sprite[j].pal = 0;
|
||||
sprite[j].shade = 0;
|
||||
sprite[j].cstat = 0;
|
||||
|
||||
if(monster == WILLOW)
|
||||
premapWillow(j);
|
||||
else if(monster == SPIDER)
|
||||
premapSpider(j);
|
||||
else if(monster == GRONSW)
|
||||
premapGron(j);
|
||||
else if(monster == SKELETON)
|
||||
premapSkeleton(j);
|
||||
else if(monster == GONZOGSH)
|
||||
premapGonzo(j);
|
||||
|
||||
sprite[j].picnum = (short) monster;
|
||||
killcnt++;
|
||||
|
||||
setsprite(j, sprite[j].x, sprite[j].y, sprite[j].z);
|
||||
//game.pInt.setsprinterpolate(j, sprite[j]);
|
||||
}
|
||||
|
||||
|
||||
void createJudyAI() {
|
||||
auto &e = enemy[JUDYTYPE];
|
||||
e.info.Init(32, 32, 2048, 120, 0, 64, false, 500, 0);
|
||||
e.chase = chase;
|
||||
e.resurect = resurect;
|
||||
e.search = search;
|
||||
e.nuked = nuked;
|
||||
e.pain = pain;
|
||||
e.face = face;
|
||||
e.attack = attack;
|
||||
e.flee = flee;
|
||||
e.cast = cast;
|
||||
e.die = die;
|
||||
}
|
||||
|
||||
void premapJudy(short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.detail = JUDYTYPE;
|
||||
|
||||
enemy[JUDYTYPE].info.set(spr);
|
||||
|
||||
if (mapon > 24)
|
||||
spr.hitag = adjusthp(700);
|
||||
|
||||
if (spr.picnum == JUDYSIT) {
|
||||
changespritestat(i, WITCHSIT);
|
||||
spr.extra = 1200;
|
||||
} else
|
||||
changespritestat(i, FACE);
|
||||
}
|
||||
}
|
||||
END_WH_NS
|
284
source/games/whaven/src/aikatie.cpp
Normal file
284
source/games/whaven/src/aikatie.cpp
Normal file
|
@ -0,0 +1,284 @@
|
|||
#include "ns.h"
|
||||
#include "wh.h"
|
||||
|
||||
BEGIN_WH_NS
|
||||
|
||||
|
||||
static void chase(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0)
|
||||
spr.lotag = 250;
|
||||
|
||||
short osectnum = spr.sectnum;
|
||||
|
||||
if (krand() % 63 == 0) {
|
||||
if (cansee(plr.x, plr.y, plr.z, plr.sector, sprite[i].x, sprite[i].y,
|
||||
sprite[i].z - (tilesizy[sprite[i].picnum] << 7), sprite[i].sectnum))// && invisibletime < 0)
|
||||
newstatus(i, ATTACK);
|
||||
}
|
||||
else {
|
||||
checksight(plr, i);
|
||||
if (!checkdist(i, plr.x, plr.y, plr.z)) {
|
||||
int movestat = aimove(i);
|
||||
if ((movestat & kHitTypeMask) == kHitFloor)
|
||||
{
|
||||
spr.ang = (short)((spr.ang + 1024) & 2047);
|
||||
newstatus(i, FLEE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (krand() % 8 == 0) // NEW
|
||||
newstatus(i, ATTACK); // NEW
|
||||
else { // NEW
|
||||
sprite[i].ang = (short)(((krand() & 512 - 256) + sprite[i].ang + 1024) & 2047); // NEW
|
||||
newstatus(i, FLEE); // NEW
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getzrange(spr.x, spr.y, spr.z - 1, spr.sectnum, (spr.clipdist) << 2, CLIPMASK0);
|
||||
spr.z = zr_florz;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void resurect(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
newstatus(i, FACE);
|
||||
spr.picnum = KATIE;
|
||||
spr.hitag = (short)adjusthp(200);
|
||||
spr.lotag = 100;
|
||||
spr.cstat |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void search(PLAYER& plr, short i) {
|
||||
aisearch(plr, i, false);
|
||||
checksector6(i);
|
||||
}
|
||||
|
||||
static void pain(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum = KATIE;
|
||||
spr.ang = (short)plr.ang;
|
||||
newstatus(i, FLEE);
|
||||
}
|
||||
|
||||
aimove(i);
|
||||
processfluid(i, zr_florhit, false);
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
}
|
||||
|
||||
static void face(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.ang = (short)(getangle(plr.x - spr.x, plr.y - spr.y) & 2047);
|
||||
|
||||
boolean cansee = cansee(plr.x, plr.y, plr.z, plr.sector, spr.x, spr.y, spr.z - (tilesizy[spr.picnum] << 7),
|
||||
spr.sectnum);
|
||||
|
||||
if (cansee && plr.invisibletime < 0) {
|
||||
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(i, plr.x, plr.y, plr.z))
|
||||
newstatus(i, ATTACK);
|
||||
}
|
||||
|
||||
static void attack(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:
|
||||
case TYPEWATER:
|
||||
spr.z += tilesizy[spr.picnum] << 5;
|
||||
break;
|
||||
}
|
||||
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
|
||||
sprite[i].lotag -= TICSPERFRAME;
|
||||
if (sprite[i].lotag < 0) {
|
||||
if (cansee(plr.x, plr.y, plr.z, plr.sector, sprite[i].x, sprite[i].y,
|
||||
sprite[i].z - (tilesizy[sprite[i].picnum] << 7), sprite[i].sectnum))
|
||||
newstatus(i, CAST);
|
||||
else
|
||||
newstatus(i, CHASE);
|
||||
}
|
||||
else
|
||||
sprite[i].ang = getangle(plr.x - sprite[i].x, plr.y - sprite[i].y);
|
||||
}
|
||||
|
||||
static void flee(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
short osectnum = spr.sectnum;
|
||||
|
||||
int movestat = aimove(i);
|
||||
if ((movestat & kHitTypeMask) != kHitFloor && 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 (movestat != 0) {
|
||||
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);
|
||||
}
|
||||
|
||||
static void cast(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 12;
|
||||
}
|
||||
|
||||
if (spr.picnum == KATIEAT + 2) {
|
||||
if (spr.extra >= 2) {
|
||||
if (rand() % 100 > 50) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
spawnabaddy(i, GONZOGSH);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int j = 0; j < 6; j++) {
|
||||
spawnabaddy(i, GRONSW);
|
||||
}
|
||||
}
|
||||
spr.picnum = KATIE;
|
||||
spr.extra--;
|
||||
playsound_loc(S_FIREBALL, spr.x, spr.y);
|
||||
newstatus(i, CHASE);
|
||||
}
|
||||
}
|
||||
|
||||
if (spr.picnum == KATIEAT + 6) {
|
||||
if (spr.extra == 1) {
|
||||
for (short j = 0; j < MAXSPRITES; j++) {
|
||||
if (sprite[j].pal == 8) {
|
||||
sprite[j].picnum--;
|
||||
sprite[j].pal = 0;
|
||||
sprite[j].shade = 0;
|
||||
changespritestat(j, FACE);
|
||||
}
|
||||
}
|
||||
spr.picnum = KATIE;
|
||||
playsound_loc(S_FIREBALL, spr.x, spr.y);
|
||||
newstatus(i, CHASE);
|
||||
spr.extra--;
|
||||
}
|
||||
}
|
||||
|
||||
if (spr.picnum == KATIEAT + 16) {
|
||||
spr.picnum = KATIE;
|
||||
playsound_loc(S_FIREBALL, spr.x, spr.y);
|
||||
castspell(plr, i);
|
||||
newstatus(i, CHASE);
|
||||
spr.extra++;
|
||||
}
|
||||
checksector6(i);
|
||||
}
|
||||
|
||||
static void die(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
|
||||
if (spr.lotag <= 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 20;
|
||||
|
||||
if (spr.picnum == KATIEDEAD) {
|
||||
if (difficulty == 4)
|
||||
newstatus(i, RESURECT);
|
||||
else {
|
||||
kills++;
|
||||
newstatus(i, DEAD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void createKatieAI() {
|
||||
auto& e = enemy[KATIETYPE];
|
||||
e.info.Init(35, 35, 2048, 120, 0, 64, false, 200, 0);
|
||||
e.chase = chase;
|
||||
e.resurect = resurect;
|
||||
e.search = search;
|
||||
e.pain = pain;
|
||||
e.face = face;
|
||||
e.attack = attack;
|
||||
e.flee = flee;
|
||||
e.cast = cast;
|
||||
e.die = die;
|
||||
}
|
||||
|
||||
void premapKatie(short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.detail = KATIETYPE;
|
||||
changespritestat(i, FACE);
|
||||
enemy[KATIETYPE].info.set(spr);
|
||||
spr.extra = 5;
|
||||
}
|
||||
|
||||
END_WH_NS
|
363
source/games/whaven/src/aikobold.cpp
Normal file
363
source/games/whaven/src/aikobold.cpp
Normal file
|
@ -0,0 +1,363 @@
|
|||
#include "ns.h"
|
||||
#include "wh.h"
|
||||
|
||||
BEGIN_WH_NS
|
||||
|
||||
static void checkexpl(PLAYER& plr, short i);
|
||||
|
||||
static void chase(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0)
|
||||
spr.lotag = 250;
|
||||
|
||||
if ((krand() % 100) > 98)
|
||||
playsound_loc(S_KSNARL1 + (krand() % 4), sprite[i].x, sprite[i].y);
|
||||
|
||||
short osectnum = spr.sectnum;
|
||||
if (cansee(plr.x, plr.y, plr.z, plr.sector, spr.x, spr.y, spr.z - (tilesizy[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) == kHitFloor)
|
||||
{
|
||||
spr.ang = (short)((spr.ang + 1024) & 2047);
|
||||
newstatus(i, FLEE);
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
spr.z = zr_florz;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void die(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
|
||||
if (spr.lotag <= 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 20;
|
||||
|
||||
if (spr.picnum == KOBOLDDEAD) {
|
||||
if (difficulty == 4)
|
||||
newstatus(i, RESURECT);
|
||||
else {
|
||||
kills++;
|
||||
newstatus(i, DEAD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void pain(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum = KOBOLD;
|
||||
spr.ang = (short)plr.ang;
|
||||
newstatus(i, FLEE);
|
||||
}
|
||||
|
||||
aimove(i);
|
||||
processfluid(i, zr_florhit, false);
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void face(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 - (tilesizy[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);
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void flee(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
short osectnum = spr.sectnum;
|
||||
|
||||
int movestat = aimove(i);
|
||||
if ((movestat & kHitTypeMask) != kHitFloor && 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);
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void attack(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:
|
||||
case TYPEWATER:
|
||||
spr.z += tilesizy[spr.picnum] << 5;
|
||||
break;
|
||||
}
|
||||
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
|
||||
if (spr.lotag == 34) {
|
||||
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 resurect(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
newstatus(i, FACE);
|
||||
spr.picnum = KOBOLD;
|
||||
spr.hitag = (short)adjusthp(30);
|
||||
spr.lotag = 100;
|
||||
spr.cstat |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void search(PLAYER& plr, short i) {
|
||||
if ((krand() % 100) > 98)
|
||||
playsound_loc(S_KSNARL1 + (krand() % 4), sprite[i].x, sprite[i].y);
|
||||
aisearch(plr, i, false);
|
||||
if (!checksector6(i))
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void frozen(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.pal = 0;
|
||||
spr.picnum = KOBOLD;
|
||||
newstatus(i, FACE);
|
||||
}
|
||||
}
|
||||
|
||||
static void nuked(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
if (game.WH2) {
|
||||
chunksofmeat(plr, i, spr.x, spr.y, spr.z, spr.sectnum, spr.ang);
|
||||
trailingsmoke(i, false);
|
||||
newstatus((short)i, DIE);
|
||||
return;
|
||||
}
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 24;
|
||||
if (spr.picnum == KOBOLDCHAR + 4) {
|
||||
trailingsmoke(i, false);
|
||||
deletesprite(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void skirmish(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
|
||||
if (spr.lotag < 0)
|
||||
newstatus(i, FACE);
|
||||
short osectnum = spr.sectnum;
|
||||
int movestat = aimove(i);
|
||||
if ((movestat & kHitTypeMask) != kHitFloor && movestat != 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;
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
|
||||
static void checkexpl(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
short j = headspritesect[spr.sectnum];
|
||||
while (j != -1) {
|
||||
short nextj = nextspritesect[j];
|
||||
long dx = klabs(spr.x - sprite[j].x); // x distance to sprite
|
||||
long dy = klabs(spr.y - sprite[j].y); // y distance to sprite
|
||||
long dz = klabs((spr.z >> 8) - (sprite[j].z >> 8)); // z distance to sprite
|
||||
long dh = tilesizy[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 createKoboldAI() {
|
||||
auto& e = enemy[KOBOLDTYPE];
|
||||
e.info.Init(game.WH2 ? 60 : 54, game.WH2 ? 60 : 54, 1024, 120, 0, 64, false, 20, 0);
|
||||
e.chase = chase;
|
||||
e.die = die;
|
||||
e.pain = pain;
|
||||
e.face = face;
|
||||
e.flee = flee;
|
||||
e.attack = attack;
|
||||
e.resurect = resurect;
|
||||
e.search = search;
|
||||
e.frozen = frozen;
|
||||
e.nuked = nuked;
|
||||
e.skirmish = skirmish;
|
||||
}
|
||||
|
||||
void premapKobold(short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.detail = KOBOLDTYPE;
|
||||
enemy[KOBOLDTYPE].info.set(spr);
|
||||
changespritestat(i, FACE);
|
||||
|
||||
if (spr.pal == 8)
|
||||
spr.hitag = adjusthp(40);
|
||||
else if (spr.pal == 7)
|
||||
spr.hitag = adjusthp(60);
|
||||
}
|
||||
|
||||
END_WH_NS
|
103
source/games/whaven/src/aikurt.cpp
Normal file
103
source/games/whaven/src/aikurt.cpp
Normal file
|
@ -0,0 +1,103 @@
|
|||
#include "ns.h"
|
||||
#include "wh.h"
|
||||
|
||||
BEGIN_WH_NS
|
||||
|
||||
|
||||
static void stand(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
if (sintable[(spr.ang + 512) & 2047] * (plr.x - spr.x)
|
||||
+ sintable[spr.ang & 2047] * (plr.y - spr.y) >= 0)
|
||||
if (cansee(spr.x, spr.y, spr.z - (tilesizy[spr.picnum] << 7), spr.sectnum, plr.x, plr.y,
|
||||
plr.z, plr.sector) && plr.invisibletime < 0) {
|
||||
if (plr.shadowtime > 0) {
|
||||
spr.ang = (short)(((krand() & 512 - 256) + spr.ang + 1024) & 2047);
|
||||
newstatus(i, FLEE);
|
||||
}
|
||||
else
|
||||
newstatus(i, CHASE);
|
||||
}
|
||||
}
|
||||
|
||||
static void nuked(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
chunksofmeat(plr, i, spr.x, spr.y, spr.z, spr.sectnum, spr.ang);
|
||||
trailingsmoke(i, false);
|
||||
newstatus(i, DIE);
|
||||
}
|
||||
|
||||
static void kurtExplo(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
spr.picnum++;
|
||||
if (spr.lotag < 0)
|
||||
spr.lotag = 12;
|
||||
|
||||
short j = headspritesect[spr.sectnum];
|
||||
while (j != -1) {
|
||||
short nextj = nextspritesect[j];
|
||||
long dx = klabs(spr.x - sprite[j].x); // x distance to sprite
|
||||
long dy = klabs(spr.y - sprite[j].y); // y distance to sprite
|
||||
long dz = klabs((spr.z >> 8) - (sprite[j].z >> 8)); // z distance to sprite
|
||||
long dh = tilesizy[sprite[j].picnum] >> 1; // height of sprite
|
||||
if (dx + dy < PICKDISTANCE && dz - dh <= getPickHeight()) {
|
||||
if (sprite[j].detail == KURTTYPE) {
|
||||
sprite[j].hitag -= TICSPERFRAME << 4;
|
||||
if (sprite[j].hitag < 0) {
|
||||
newstatus(j, DIE);
|
||||
}
|
||||
}
|
||||
}
|
||||
j = nextj;
|
||||
}
|
||||
}
|
||||
|
||||
void createKurtAI() {
|
||||
auto& e = enemy[KURTTYPE];
|
||||
e.info.Init(35, 35, 1024 + 256, 120, 0, 48, false, 50, 0);
|
||||
e.info.getAttackDist = [](EnemyInfo& e, SPRITE& spr) {
|
||||
int out = e.attackdist;
|
||||
switch (spr.picnum) {
|
||||
case KURTAT:
|
||||
case GONZOCSW:
|
||||
case GONZOCSWAT:
|
||||
if (spr.extra > 10)
|
||||
out = 2048 << 1;
|
||||
break;
|
||||
}
|
||||
|
||||
return out;
|
||||
};
|
||||
e.stand = stand;
|
||||
e.nuked = nuked;
|
||||
e.chase = enemy[GONZOTYPE].chase;
|
||||
e.resurect = enemy[GONZOTYPE].resurect;
|
||||
e.skirmish = enemy[GONZOTYPE].skirmish;
|
||||
e.search = enemy[GONZOTYPE].search;
|
||||
e.frozen = enemy[GONZOTYPE].frozen;
|
||||
e.pain = enemy[GONZOTYPE].pain;
|
||||
e.face = enemy[GONZOTYPE].face;
|
||||
e.attack = enemy[GONZOTYPE].attack;
|
||||
e.cast = enemy[GONZOTYPE].cast;
|
||||
e.flee = enemy[GONZOTYPE].flee;
|
||||
e.die = enemy[GONZOTYPE].die;
|
||||
}
|
||||
|
||||
void premapKurt(short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.detail = KURTTYPE;
|
||||
enemy[KURTTYPE].info.set(spr);
|
||||
changespritestat(i, STAND);
|
||||
|
||||
switch (spr.picnum) {
|
||||
case KURTSTAND:
|
||||
spr.extra = 20;
|
||||
break;
|
||||
case KURTKNEE:
|
||||
spr.extra = 10;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
END_WH_NS
|
362
source/games/whaven/src/aiminotaur.cpp
Normal file
362
source/games/whaven/src/aiminotaur.cpp
Normal file
|
@ -0,0 +1,362 @@
|
|||
#include "ns.h"
|
||||
#include "wh.h"
|
||||
|
||||
BEGIN_WH_NS
|
||||
|
||||
static void checkexpl(PLAYER& plr, short i);
|
||||
|
||||
static void chase(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 - (tilesizy[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) == kHitFloor)
|
||||
{
|
||||
spr.ang = (short)((spr.ang + 1024) & 2047);
|
||||
newstatus(i, FLEE);
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
spr.z = zr_florz;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void resurect(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
newstatus(i, FACE);
|
||||
spr.picnum = MINOTAUR;
|
||||
spr.hitag = (short)adjusthp(100);
|
||||
spr.lotag = 100;
|
||||
spr.cstat |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void skirmish(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
|
||||
if (spr.lotag < 0)
|
||||
newstatus(i, FACE);
|
||||
short osectnum = spr.sectnum;
|
||||
int movestat = aimove(i);
|
||||
if ((movestat & kHitTypeMask) != kHitFloor && movestat != 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;
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void nuked(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
if (game.WH2) {
|
||||
chunksofmeat(plr, i, spr.x, spr.y, spr.z, spr.sectnum, spr.ang);
|
||||
trailingsmoke(i, false);
|
||||
newstatus((short)i, DIE);
|
||||
return;
|
||||
}
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 24;
|
||||
if (spr.picnum == MINOTAURCHAR + 4) {
|
||||
trailingsmoke(i, false);
|
||||
deletesprite(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void pain(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum = MINOTAUR;
|
||||
spr.ang = (short)plr.ang;
|
||||
newstatus(i, FLEE);
|
||||
}
|
||||
|
||||
aimove(i);
|
||||
processfluid(i, zr_florhit, false);
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void face(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 - (tilesizy[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);
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void attack(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 += tilesizy[spr.picnum] << 5;
|
||||
break;
|
||||
}
|
||||
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
|
||||
if (spr.lotag == 31) {
|
||||
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 die(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
|
||||
if (spr.lotag <= 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 20;
|
||||
|
||||
if (spr.picnum == MINOTAURDEAD) {
|
||||
if (difficulty == 4)
|
||||
newstatus(i, RESURECT);
|
||||
else {
|
||||
kills++;
|
||||
newstatus(i, DEAD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void flee(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
short osectnum = spr.sectnum;
|
||||
|
||||
int movestat = aimove(i);
|
||||
if ((movestat & kHitTypeMask) != kHitFloor && 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);
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void frozen(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.pal = 0;
|
||||
spr.picnum = MINOTAUR;
|
||||
newstatus(i, FACE);
|
||||
}
|
||||
}
|
||||
|
||||
static void search(PLAYER& plr, short i) {
|
||||
aisearch(plr, i, false);
|
||||
if (!checksector6(i))
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
|
||||
static void checkexpl(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
short j = headspritesect[spr.sectnum];
|
||||
while (j != -1) {
|
||||
short nextj = nextspritesect[j];
|
||||
long dx = klabs(spr.x - sprite[j].x); // x distance to sprite
|
||||
long dy = klabs(spr.y - sprite[j].y); // y distance to sprite
|
||||
long dz = klabs((spr.z >> 8) - (sprite[j].z >> 8)); // z distance to sprite
|
||||
long dh = tilesizy[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 createMinotaurAI() {
|
||||
|
||||
//picanm[MINOTAUR + 16] = 0;
|
||||
|
||||
auto& e = enemy[MINOTAURTYPE];
|
||||
e.info.Init(64, 64, 1024 + 512, 120, 0, 64, false, game.WH2 ? 80 : 100, 0);
|
||||
e.chase = chase;
|
||||
e.resurect = resurect;
|
||||
e.skirmish = skirmish;
|
||||
e.nuked = nuked;
|
||||
e.pain = pain;
|
||||
e.face = face;
|
||||
e.attack = attack;
|
||||
e.die = die;
|
||||
e.flee = flee;
|
||||
e.frozen = frozen;
|
||||
e.search = search;
|
||||
}
|
||||
|
||||
|
||||
void premapMinotaur(short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.detail = MINOTAURTYPE;
|
||||
enemy[MINOTAURTYPE].info.set(spr);
|
||||
changespritestat(i, FACE);
|
||||
|
||||
if (krand() % 100 > 50)
|
||||
spr.extra = 1;
|
||||
}
|
||||
|
||||
END_WH_NS
|
479
source/games/whaven/src/ainewguy.cpp
Normal file
479
source/games/whaven/src/ainewguy.cpp
Normal file
|
@ -0,0 +1,479 @@
|
|||
#include "ns.h"
|
||||
#include "wh.h"
|
||||
|
||||
BEGIN_WH_NS
|
||||
|
||||
static void newguyarrow(short s, PLAYER& plr);
|
||||
|
||||
static void stand(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
if (sintable[(spr.ang + 512) & 2047] * (plr.x - spr.x)
|
||||
+ sintable[spr.ang & 2047] * (plr.y - spr.y) >= 0)
|
||||
if (cansee(spr.x, spr.y, spr.z - (tilesizy[spr.picnum] << 7), spr.sectnum, plr.x, plr.y,
|
||||
plr.z, plr.sector) && plr.invisibletime < 0) {
|
||||
if (plr.shadowtime > 0) {
|
||||
spr.ang = (short)(((krand() & 512 - 256) + spr.ang + 1024) & 2047);
|
||||
newstatus(i, FLEE);
|
||||
}
|
||||
else
|
||||
newstatus(i, CHASE);
|
||||
}
|
||||
}
|
||||
|
||||
static void chase(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 - (tilesizy[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) == kHitFloor)
|
||||
{
|
||||
spr.ang = (short)((spr.ang + 1024) & 2047);
|
||||
newstatus(i, FLEE);
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
spr.z = zr_florz;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
static void resurect(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
newstatus(i, FACE);
|
||||
int j = krand() % 3;
|
||||
switch (j) {
|
||||
case 0:
|
||||
spr.extra = 30;
|
||||
spr.hitag = (short)adjusthp(85);
|
||||
break;
|
||||
case 1:
|
||||
spr.extra = 20;
|
||||
spr.hitag = (short)adjusthp(85);
|
||||
break;
|
||||
case 2:
|
||||
spr.extra = 10;
|
||||
spr.hitag = (short)adjusthp(45);
|
||||
break;
|
||||
case 3:
|
||||
spr.extra = 0;
|
||||
spr.hitag = (short)adjusthp(15);
|
||||
break;
|
||||
}
|
||||
spr.xrepeat = 35;
|
||||
spr.yrepeat = 35;
|
||||
spr.picnum = NEWGUY;
|
||||
}
|
||||
}
|
||||
|
||||
static void skirmish(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
|
||||
if (spr.lotag < 0)
|
||||
newstatus(i, FACE);
|
||||
short osectnum = spr.sectnum;
|
||||
int movestat = aimove(i);
|
||||
if ((movestat & kHitTypeMask) != kHitFloor && movestat != 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);
|
||||
|
||||
checksector6(i);
|
||||
}
|
||||
|
||||
static void search(PLAYER& plr, short i) {
|
||||
aisearch(plr, i, false);
|
||||
checksector6(i);
|
||||
}
|
||||
|
||||
static void nuked(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
chunksofmeat(plr, i, spr.x, spr.y, spr.z, spr.sectnum, spr.ang);
|
||||
trailingsmoke(i, false);
|
||||
newstatus((short)i, DIE);
|
||||
}
|
||||
|
||||
static void pain(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum = NEWGUY;
|
||||
spr.ang = (short)plr.ang;
|
||||
newstatus(i, FLEE);
|
||||
}
|
||||
|
||||
aimove(i);
|
||||
processfluid(i, zr_florhit, false);
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
}
|
||||
|
||||
static void face(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 - (tilesizy[spr.picnum] << 7),
|
||||
spr.sectnum);
|
||||
|
||||
if (cansee && plr.invisibletime < 0) {
|
||||
spr.ang = getangle(plr.x - spr.x, plr.y - spr.y);
|
||||
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);
|
||||
}
|
||||
|
||||
static void flee(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
short osectnum = spr.sectnum;
|
||||
|
||||
int movestat = aimove(i);
|
||||
if ((movestat & kHitTypeMask) != kHitFloor && 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 {
|
||||
if (plr.invisibletime < 0)
|
||||
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);
|
||||
}
|
||||
|
||||
static void attack(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:
|
||||
case TYPEWATER:
|
||||
spr.z += tilesizy[spr.picnum] << 5;
|
||||
break;
|
||||
}
|
||||
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
|
||||
switch (spr.picnum) {
|
||||
case NEWGUYCAST:
|
||||
case NEWGUYBOW:
|
||||
sprite[i].lotag -= TICSPERFRAME;
|
||||
if (sprite[i].lotag < 0) {
|
||||
if (cansee(plr.x, plr.y, plr.z, plr.sector, sprite[i].x, sprite[i].y,
|
||||
sprite[i].z - (tilesizy[sprite[i].picnum] << 7), sprite[i].sectnum))
|
||||
newstatus(i, CAST);
|
||||
else
|
||||
newstatus(i, CHASE);
|
||||
}
|
||||
else
|
||||
sprite[i].ang = getangle(plr.x - sprite[i].x, plr.y - sprite[i].y);
|
||||
break;
|
||||
case NEWGUYMACE:
|
||||
case NEWGUYPUNCH:
|
||||
if (spr.lotag == 31) {
|
||||
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);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void die(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
|
||||
if (spr.lotag <= 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 20;
|
||||
|
||||
if (spr.picnum == NEWGUYDEAD) {
|
||||
if (difficulty == 4)
|
||||
newstatus(i, RESURECT);
|
||||
else {
|
||||
kills++;
|
||||
newstatus(i, DEAD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void cast(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 12;
|
||||
}
|
||||
|
||||
if (spr.picnum == NEWGUYCAST + 2) {
|
||||
spr.extra--;
|
||||
spr.picnum = NEWGUY;
|
||||
playsound_loc(S_WISP, sprite[i].x, sprite[i].y);
|
||||
skullycastspell(plr, i);
|
||||
newstatus(i, CHASE);
|
||||
}
|
||||
if (spr.picnum == NEWGUYBOW + 2) {
|
||||
spr.extra--;
|
||||
spr.picnum = NEWGUY;
|
||||
playsound_loc(S_PLRWEAPON3, sprite[i].x, sprite[i].y);
|
||||
newguyarrow(i, plr);
|
||||
newstatus(i, CHASE);
|
||||
}
|
||||
checksector6(i);
|
||||
}
|
||||
|
||||
static void newguyarrow(short s, PLAYER& plr) {
|
||||
int j = insertsprite(sprite[s].sectnum, JAVLIN);
|
||||
if (j == -1)
|
||||
return;
|
||||
|
||||
SPRITE& spr = sprite[j];
|
||||
|
||||
spr.x = sprite[s].x;
|
||||
spr.y = sprite[s].y;
|
||||
spr.z = sprite[s].z - (40 << 8);
|
||||
|
||||
spr.cstat = 21;
|
||||
|
||||
spr.picnum = WALLARROW;
|
||||
spr.ang = (short)(((sprite[s].ang + 2048 + 96) - 512) & 2047);
|
||||
spr.xrepeat = 24;
|
||||
spr.yrepeat = 24;
|
||||
spr.clipdist = 32;
|
||||
|
||||
spr.extra = sprite[s].ang;
|
||||
spr.shade = -15;
|
||||
spr.xvel = (short)((krand() & 256) - 128);
|
||||
spr.yvel = (short)((krand() & 256) - 128);
|
||||
|
||||
spr.zvel = (short)(((plr.z + (8 << 8) - sprite[s].z) << 7) / engine
|
||||
.ksqrt((plr.x - sprite[s].x) * (plr.x - sprite[s].x) + (plr.y - sprite[s].y) * (plr.y - sprite[s].y)));
|
||||
|
||||
spr.zvel += ((krand() % 256) - 128);
|
||||
|
||||
spr.owner = s;
|
||||
spr.lotag = 1024;
|
||||
spr.hitag = 0;
|
||||
spr.pal = 0;
|
||||
}
|
||||
|
||||
void createNewGuyAI() {
|
||||
//picanm[NEWGUYDIE] = 0;
|
||||
//picanm[NEWGUYDIE + 3] = 0;
|
||||
auto& e = enemy[NEWGUYTYPE];
|
||||
e.info.Init(35, 35, 1024 + 256, 120, 0, 48, false, 90, 0);
|
||||
e.info.getAttackDist = [](EnemyInfo& e, SPRITE& spr)
|
||||
{
|
||||
int out = e.attackdist;
|
||||
switch (spr.picnum) {
|
||||
case NEWGUY:
|
||||
case NEWGUYMACE:
|
||||
case NEWGUYCAST:
|
||||
case NEWGUYBOW:
|
||||
if (spr.extra > 10)
|
||||
out = 2048 << 1;
|
||||
else out = 1024 + 256;
|
||||
break;
|
||||
case NEWGUYPUNCH:
|
||||
out = 1024 + 256;
|
||||
break;
|
||||
default:
|
||||
out = 512;
|
||||
break;
|
||||
}
|
||||
|
||||
return out;
|
||||
};
|
||||
|
||||
e.info.getHealth = [](EnemyInfo& e, SPRITE& spr)
|
||||
{
|
||||
switch (spr.picnum) {
|
||||
case NEWGUYSTAND:
|
||||
case NEWGUYKNEE:
|
||||
return adjusthp(50);
|
||||
case NEWGUYCAST:
|
||||
return adjusthp(85);
|
||||
case NEWGUYBOW:
|
||||
return adjusthp(85);
|
||||
case NEWGUYMACE:
|
||||
return adjusthp(45);
|
||||
case NEWGUYPUNCH:
|
||||
return adjusthp(15);
|
||||
}
|
||||
|
||||
return adjusthp(e.health);
|
||||
};
|
||||
e.stand = stand;
|
||||
e.chase = chase;
|
||||
e.resurect = resurect;
|
||||
e.skirmish = skirmish;
|
||||
e.search = search;
|
||||
e.nuked = nuked;
|
||||
e.pain = pain;
|
||||
e.face = face;
|
||||
e.flee = flee;
|
||||
e.attack = attack;
|
||||
e.die = die;
|
||||
e.cast = cast;
|
||||
}
|
||||
|
||||
|
||||
void premapNewGuy(short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.detail = NEWGUYTYPE;
|
||||
|
||||
enemy[NEWGUYTYPE].info.set(spr);
|
||||
|
||||
switch (spr.picnum) {
|
||||
case NEWGUYSTAND:
|
||||
case NEWGUYKNEE:
|
||||
changespritestat(i, STAND);
|
||||
if (spr.picnum == NEWGUYSTAND)
|
||||
spr.extra = 20;
|
||||
else
|
||||
spr.extra = 30;
|
||||
break;
|
||||
case NEWGUYCAST:
|
||||
case NEWGUYBOW:
|
||||
case NEWGUYMACE:
|
||||
case NEWGUYPUNCH:
|
||||
case NEWGUY:
|
||||
switch (spr.picnum) {
|
||||
case NEWGUYCAST:
|
||||
spr.extra = 30;
|
||||
break;
|
||||
case NEWGUYBOW:
|
||||
spr.extra = 20;
|
||||
break;
|
||||
case NEWGUYMACE:
|
||||
spr.extra = 10;
|
||||
break;
|
||||
case NEWGUYPUNCH:
|
||||
spr.extra = 0;
|
||||
break;
|
||||
}
|
||||
changespritestat(i, FACE);
|
||||
spr.picnum = NEWGUY;
|
||||
}
|
||||
}
|
||||
}
|
||||
END_WH_NS
|
111
source/games/whaven/src/airat.cpp
Normal file
111
source/games/whaven/src/airat.cpp
Normal file
|
@ -0,0 +1,111 @@
|
|||
#include "ns.h"
|
||||
#include "wh.h"
|
||||
|
||||
BEGIN_WH_NS
|
||||
|
||||
static void chase(PLAYER& plr, short i) {
|
||||
newstatus(i, FLEE);
|
||||
}
|
||||
|
||||
static void search(PLAYER& plr, short i) {
|
||||
sprite[i].ang = (short) (((krand() & 512 - 256) + sprite[i].ang + 1024) & 2047);
|
||||
newstatus(i, FLEE);
|
||||
}
|
||||
|
||||
static void face(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.ang = getangle(plr.x - spr.x, plr.y - spr.y);
|
||||
spr.ang = (short) (((krand() & 512 - 256) + spr.ang + 1024) & 2047); // NEW
|
||||
spr.owner = sprite[plr.spritenum].owner;
|
||||
newstatus(i, FLEE);
|
||||
}
|
||||
|
||||
static void die(PLAYER& plr, short i) {
|
||||
deletesprite(i);
|
||||
}
|
||||
|
||||
static void flee(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
short osectnum = spr.sectnum;
|
||||
|
||||
int movestat = aimove(i);
|
||||
if ((movestat & kHitTypeMask) == kHitFloor)
|
||||
{
|
||||
spr.ang = (short)((spr.ang + 1024) & 2047);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((movestat & kHitTypeMask) == kHitWall) {
|
||||
WALL wal = wall[movestat & kHitIndexMask];
|
||||
short wallang = (short)((getangle(wall[wal.point2].x - wal.x, wall[wal.point2].y - wal.y) + 512)
|
||||
& 2047);
|
||||
spr.ang = (short)(krand() & 512 - 256 + wallang);
|
||||
}
|
||||
|
||||
if ((movestat & kHitTypeMask) == kHitSprite) {
|
||||
SPRITE sp = sprite[movestat & kHitIndexMask];
|
||||
spr.owner = (short)(movestat & kHitIndexMask);
|
||||
spr.ang = getangle(sp.x - spr.x, sp.y - spr.y);
|
||||
spr.ang = (short)(((krand() & 512 - 256) + spr.ang + 1024) & 2047);
|
||||
}
|
||||
|
||||
if (klabs(plr.x - spr.x) <= 1024 && klabs(plr.y - spr.y) <= 1024) {
|
||||
spr.owner = sprite[plr.spritenum].owner;
|
||||
newstatus(i, FACE);
|
||||
}
|
||||
|
||||
if ((spr.sectnum != osectnum) && (sector[spr.sectnum].lotag == 10))
|
||||
warpsprite(i);
|
||||
|
||||
|
||||
if (checksector6(i))
|
||||
return;
|
||||
|
||||
processfluid(i, zr_florhit, false);
|
||||
|
||||
// switch (checkfluid(i, zr_florhit)) {
|
||||
// case TYPELAVA:
|
||||
// case TYPEWATER:
|
||||
// spr.z += tilesizy[spr.picnum] << 5;
|
||||
// break;
|
||||
// }
|
||||
|
||||
if ((zr_florhit & kHitTypeMask) == kHitSector && (sector[spr.sectnum].floorpicnum == LAVA
|
||||
|| sector[spr.sectnum].floorpicnum == LAVA2
|
||||
|| sector[spr.sectnum].floorpicnum == LAVA1 || sector[spr.sectnum].floorpicnum == ANILAVA)) {
|
||||
spr.hitag--;
|
||||
if (spr.hitag < 0)
|
||||
newstatus(i, DIE);
|
||||
}
|
||||
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
}
|
||||
|
||||
|
||||
void createRatAI() {
|
||||
auto& e = enemy[RATTYPE];
|
||||
e.info.Init(32, 32, 512, 120, 0, 32, false, 0, 0);
|
||||
e.info.getHealth = [](EnemyInfo&, SPRITE& spr)
|
||||
{
|
||||
return 10;
|
||||
};
|
||||
e.chase = chase;
|
||||
e.search = search;
|
||||
e.face = face;
|
||||
e.die = die;
|
||||
e.flee = flee;
|
||||
}
|
||||
|
||||
void premapRat(short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.detail = RATTYPE;
|
||||
enemy[RATTYPE].info.set(spr);
|
||||
changespritestat(i, FACE);
|
||||
|
||||
spr.shade = 12;
|
||||
spr.pal = 5;
|
||||
}
|
||||
|
||||
END_WH_NS
|
388
source/games/whaven/src/aiskeleton.cpp
Normal file
388
source/games/whaven/src/aiskeleton.cpp
Normal file
|
@ -0,0 +1,388 @@
|
|||
#include "ns.h"
|
||||
#include "wh.h"
|
||||
|
||||
BEGIN_WH_NS
|
||||
|
||||
static void checkexpl(PLAYER& plr, short i);
|
||||
|
||||
static void chase(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 - (tilesizy[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) == kHitFloor)
|
||||
{
|
||||
spr.ang = (short)((spr.ang + 1024) & 2047);
|
||||
newstatus(i, FLEE);
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
spr.z = zr_florz;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void die(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
|
||||
if (spr.lotag <= 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 20;
|
||||
|
||||
if (spr.picnum == SKELETONDEAD) {
|
||||
if (difficulty == 4)
|
||||
newstatus(i, RESURECT);
|
||||
else {
|
||||
kills++;
|
||||
newstatus(i, DEAD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void face(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 - (tilesizy[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);
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void flee(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.picnum = SKELETON;
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
short osectnum = spr.sectnum;
|
||||
|
||||
int movestat = aimove(i);
|
||||
if ((movestat & kHitTypeMask) != kHitFloor && 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);
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void stand(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.ang = getangle(plr.x - spr.x, plr.y - spr.y);
|
||||
if (sintable[(spr.ang + 2560) & 2047] * (plr.x - spr.x)
|
||||
+ sintable[(spr.ang + 2048) & 2047] * (plr.y - spr.y) >= 0)
|
||||
if (cansee(plr.x, plr.y, plr.z, plr.sector, spr.x, spr.y, spr.z - (tilesizy[spr.picnum] << 7),
|
||||
spr.sectnum) && plr.invisibletime < 0) {
|
||||
|
||||
if (spr.picnum == HANGMAN) {
|
||||
newstatus(i, CHILL);
|
||||
playsound_loc(S_SKELSEE, spr.x, spr.y);
|
||||
}
|
||||
else {
|
||||
if (plr.shadowtime > 0) {
|
||||
spr.ang = (short)(((krand() & 512 - 256) + spr.ang + 1024) & 2047); // NEW
|
||||
newstatus(i, FLEE);
|
||||
}
|
||||
else
|
||||
newstatus(i, CHASE);
|
||||
}
|
||||
}
|
||||
|
||||
checksector6(i);
|
||||
}
|
||||
|
||||
static void attack(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:
|
||||
case TYPEWATER:
|
||||
spr.z += tilesizy[spr.picnum] << 5;
|
||||
break;
|
||||
}
|
||||
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
|
||||
spr.ang = getangle(plr.x - spr.x, plr.y - spr.y);
|
||||
if (spr.lotag == 16) {
|
||||
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 resurect(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
newstatus(i, FACE);
|
||||
spr.picnum = SKELETON;
|
||||
spr.hitag = (short)adjusthp(10);
|
||||
spr.lotag = 100;
|
||||
spr.cstat |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void search(PLAYER& plr, short i) {
|
||||
aisearch(plr, i, false);
|
||||
if (!checksector6(i))
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void frozen(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.pal = 0;
|
||||
spr.picnum = SKELETON;
|
||||
newstatus(i, FACE);
|
||||
}
|
||||
}
|
||||
|
||||
static void nuked(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
if (game.WH2) {
|
||||
chunksofmeat(plr, i, spr.x, spr.y, spr.z, spr.sectnum, spr.ang);
|
||||
trailingsmoke(i, false);
|
||||
newstatus((short)i, DIE);
|
||||
return;
|
||||
}
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 24;
|
||||
if (spr.picnum == SKELETONCHAR + 4) {
|
||||
trailingsmoke(i, false);
|
||||
deletesprite(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void skirmish(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
|
||||
if (spr.lotag < 0)
|
||||
newstatus(i, FACE);
|
||||
short osectnum = spr.sectnum;
|
||||
int movestat = aimove(i);
|
||||
if ((movestat & kHitTypeMask) != kHitFloor && movestat != 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;
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
void skeletonChill(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 18;
|
||||
if (spr.picnum == HANGMAN + 10) {
|
||||
spr.picnum = SKELETON;
|
||||
newstatus(i, FACE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void checkexpl(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
short j = headspritesect[spr.sectnum];
|
||||
while (j != -1) {
|
||||
short nextj = nextspritesect[j];
|
||||
int dx = klabs(spr.x - sprite[j].x); // x distance to sprite
|
||||
int dy = klabs(spr.y - sprite[j].y); // y distance to sprite
|
||||
int dz = klabs((spr.z >> 8) - (sprite[j].z >> 8)); // z distance to sprite
|
||||
int dh = tilesizy[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 createSkeletonAI() {
|
||||
auto& e = enemy[SKELETONTYPE];
|
||||
e.info.Init(game.WH2 ? 35 : 24, game.WH2 ? 35 : 24, 1024, 120, 0, 64, false, game.WH2 ? 25 : 30, 0);
|
||||
e.chase = chase;
|
||||
e.die = die;
|
||||
e.face = face;
|
||||
e.flee = flee;
|
||||
e.stand = stand;
|
||||
e.attack = attack;
|
||||
e.resurect = resurect;
|
||||
e.search = search;
|
||||
e.frozen = frozen;
|
||||
e.nuked = nuked;
|
||||
e.skirmish = skirmish;
|
||||
}
|
||||
|
||||
|
||||
void premapSkeleton(short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.detail = SKELETONTYPE;
|
||||
enemy[SKELETONTYPE].info.set(spr);
|
||||
|
||||
if (spr.picnum == HANGMAN) {
|
||||
spr.xrepeat = 28;
|
||||
spr.yrepeat = 28;
|
||||
changespritestat(i, STAND);
|
||||
return;
|
||||
}
|
||||
|
||||
changespritestat(i, FACE);
|
||||
}
|
||||
|
||||
END_WH_NS
|
258
source/games/whaven/src/aiskully.cpp
Normal file
258
source/games/whaven/src/aiskully.cpp
Normal file
|
@ -0,0 +1,258 @@
|
|||
#include "ns.h"
|
||||
#include "wh.h"
|
||||
|
||||
BEGIN_WH_NS
|
||||
|
||||
static void chase(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0)
|
||||
spr.lotag = 250;
|
||||
|
||||
short osectnum = spr.sectnum;
|
||||
|
||||
if (krand() % 63 == 0) {
|
||||
if (cansee(plr.x, plr.y, plr.z, plr.sector, sprite[i].x, sprite[i].y,
|
||||
sprite[i].z - (tilesizy[sprite[i].picnum] << 7), sprite[i].sectnum))// && invisibletime < 0)
|
||||
newstatus(i, ATTACK);
|
||||
}
|
||||
else {
|
||||
checksight(plr, i);
|
||||
if (!checkdist(plr, i)) {
|
||||
if ((aimove(i) & kHitTypeMask) == kHitFloor)
|
||||
{
|
||||
spr.ang = (short)((spr.ang + 1024) & 2047);
|
||||
newstatus(i, FLEE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (krand() % 8 == 0) // NEW
|
||||
newstatus(i, ATTACK); // NEW
|
||||
else { // NEW
|
||||
sprite[i].ang = (short)(((krand() & 512 - 256) + sprite[i].ang + 1024) & 2047); // NEW
|
||||
newstatus(i, FLEE); // NEW
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getzrange(spr.x, spr.y, spr.z - 1, spr.sectnum, (spr.clipdist) << 2, CLIPMASK0);
|
||||
spr.z = zr_florz;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void resurect(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
newstatus(i, FACE);
|
||||
spr.picnum = SKULLY;
|
||||
spr.hitag = (short)adjusthp(100);
|
||||
spr.lotag = 100;
|
||||
spr.cstat |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void search(PLAYER& plr, short i) {
|
||||
aisearch(plr, i, false);
|
||||
checksector6(i);
|
||||
}
|
||||
|
||||
static void nuked(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 24;
|
||||
if (spr.picnum == SKULLYCHAR + 4) {
|
||||
trailingsmoke(i, false);
|
||||
deletesprite(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void pain(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum = SKULLY;
|
||||
spr.ang = (short)plr.ang;
|
||||
newstatus(i, FLEE);
|
||||
}
|
||||
|
||||
aimove(i);
|
||||
processfluid(i, zr_florhit, false);
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
}
|
||||
|
||||
static void face(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 - (tilesizy[spr.picnum] << 7),
|
||||
spr.sectnum);
|
||||
|
||||
if (cansee && plr.invisibletime < 0) {
|
||||
spr.ang = getangle(plr.x - spr.x, plr.y - spr.y);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void attack(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:
|
||||
case TYPEWATER:
|
||||
spr.z += tilesizy[spr.picnum] << 5;
|
||||
break;
|
||||
}
|
||||
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
|
||||
sprite[i].lotag -= TICSPERFRAME;
|
||||
if (sprite[i].lotag < 0) {
|
||||
if (cansee(plr.x, plr.y, plr.z, plr.sector, sprite[i].x, sprite[i].y,
|
||||
sprite[i].z - (tilesizy[sprite[i].picnum] << 7), sprite[i].sectnum))
|
||||
newstatus(i, CAST);
|
||||
else
|
||||
newstatus(i, CHASE);
|
||||
}
|
||||
else
|
||||
sprite[i].ang = getangle(plr.x - sprite[i].x, plr.y - sprite[i].y);
|
||||
}
|
||||
|
||||
static void flee(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
short osectnum = spr.sectnum;
|
||||
|
||||
int movestat = aimove(i);
|
||||
if ((movestat & kHitTypeMask) != kHitFloor && 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);
|
||||
}
|
||||
|
||||
static void cast(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 12;
|
||||
}
|
||||
|
||||
if (spr.picnum == SKULLYATTACK + 2) {
|
||||
sprite[i].picnum = SKULLY;
|
||||
playsound_loc(S_SKULLWITCH1 + krand() % 3, sprite[i].x, sprite[i].y);
|
||||
skullycastspell(plr, i);
|
||||
newstatus(i, CHASE);
|
||||
}
|
||||
checksector6(i);
|
||||
}
|
||||
|
||||
static void die(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
|
||||
if (spr.lotag <= 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 20;
|
||||
|
||||
if (spr.picnum == SKULLYDEAD) {
|
||||
if (difficulty == 4)
|
||||
newstatus(i, RESURECT);
|
||||
else {
|
||||
kills++;
|
||||
newstatus(i, DEAD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void createSkullyAI() {
|
||||
auto& e = enemy[SKULLYTYPE];
|
||||
e.info.Init(32, 32, 2048, 120, 0, 64, false, 300, 0);
|
||||
e.chase = chase;
|
||||
e.resurect = resurect;
|
||||
e.search = search;
|
||||
e.nuked = nuked;
|
||||
e.pain = pain;
|
||||
e.face = face;
|
||||
e.attack = attack;
|
||||
e.flee = flee;
|
||||
e.cast = cast;
|
||||
e.die = die;
|
||||
}
|
||||
|
||||
void premapSkully(short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.detail = SKULLYTYPE;
|
||||
enemy[SKULLYTYPE].info.set(spr);
|
||||
changespritestat(i, FACE);
|
||||
|
||||
if (krand() % 100 > 50)
|
||||
spr.extra = 1;
|
||||
}
|
||||
|
||||
END_WH_NS
|
322
source/games/whaven/src/aispider.cpp
Normal file
322
source/games/whaven/src/aispider.cpp
Normal file
|
@ -0,0 +1,322 @@
|
|||
#include "ns.h"
|
||||
#include "wh.h"
|
||||
|
||||
BEGIN_WH_NS
|
||||
|
||||
static void checkexpl(PLAYER& plr, short i);
|
||||
|
||||
static void chase(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 - (tilesizy[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) == kHitFloor)
|
||||
{
|
||||
spr.ang = (short)((spr.ang + 1024) & 2047);
|
||||
newstatus(i, FLEE);
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
spr.z = zr_florz;
|
||||
|
||||
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 == LAVA2 || sector[spr.sectnum].floorpicnum == LAVA1 || sector[spr.sectnum].floorpicnum == ANILAVA)) {
|
||||
spr.hitag--;
|
||||
if (spr.hitag < 0)
|
||||
newstatus(i, DIE);
|
||||
}
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void resurect(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
newstatus(i, FACE);
|
||||
spr.picnum = SPIDER;
|
||||
spr.hitag = (short)adjusthp(15);
|
||||
spr.lotag = 100;
|
||||
spr.cstat |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void skirmish(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
|
||||
if (spr.lotag < 0)
|
||||
newstatus(i, FACE);
|
||||
short osectnum = spr.sectnum;
|
||||
int movestat = aimove(i);
|
||||
if ((movestat & kHitTypeMask) != kHitFloor && movestat != 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;
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void search(PLAYER& plr, short i) {
|
||||
aisearch(plr, i, false);
|
||||
if (!checksector6(i))
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void frozen(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
spr.pal = 0;
|
||||
spr.picnum = SPIDER;
|
||||
newstatus(i, FACE);
|
||||
}
|
||||
}
|
||||
|
||||
static void face(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 - (tilesizy[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);
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void attack(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);
|
||||
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);
|
||||
if (krand() % 100 > ((plr.lvl * 7) + 20)) {
|
||||
playsound_loc(S_SPIDERBITE, sprite[i].x, sprite[i].y);
|
||||
plr.poisoned = 1;
|
||||
plr.poisontime = 7200;
|
||||
showmessage("Poisoned", 360);
|
||||
newstatus(i, DIE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
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 flee(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
short osectnum = spr.sectnum;
|
||||
|
||||
int movestat = aimove(i);
|
||||
if ((movestat & kHitTypeMask) != kHitFloor && 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);
|
||||
|
||||
checkexpl(plr, i);
|
||||
}
|
||||
|
||||
static void die(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
|
||||
if (spr.lotag <= 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 20;
|
||||
|
||||
if (spr.picnum == SPIDERDEAD) {
|
||||
if (difficulty == 4)
|
||||
newstatus(i, RESURECT);
|
||||
else {
|
||||
kills++;
|
||||
newstatus(i, DEAD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void checkexpl(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
short j = headspritesect[spr.sectnum];
|
||||
while (j != -1) {
|
||||
short nextj = nextspritesect[j];
|
||||
long dx = klabs(spr.x - sprite[j].x); // x distance to sprite
|
||||
long dy = klabs(spr.y - sprite[j].y); // y distance to sprite
|
||||
long dz = klabs((spr.z >> 8) - (sprite[j].z >> 8)); // z distance to sprite
|
||||
long dh = tilesizy[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 createSpiderAI() {
|
||||
auto& e = enemy[SPIDERTYPE];
|
||||
e.info.Init(24, 18, 512, 60, 0, 64, false, 5, 0);
|
||||
e.chase = chase;
|
||||
e.resurect = resurect;
|
||||
e.skirmish = skirmish;
|
||||
e.search = search;
|
||||
e.frozen = frozen;
|
||||
e.face = face;
|
||||
e.attack = attack;
|
||||
e.flee = flee;
|
||||
e.die = die;
|
||||
}
|
||||
|
||||
void premapSpider(short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.detail = SPIDERTYPE;
|
||||
enemy[SPIDERTYPE].info.set(spr);
|
||||
changespritestat(i, FACE);
|
||||
}
|
||||
|
||||
END_WH_NS
|
291
source/games/whaven/src/aiwillow.cpp
Normal file
291
source/games/whaven/src/aiwillow.cpp
Normal file
|
@ -0,0 +1,291 @@
|
|||
#include "ns.h"
|
||||
#include "wh.h"
|
||||
|
||||
BEGIN_WH_NS
|
||||
|
||||
static void willowDrain(PLAYER& plr, short i);
|
||||
|
||||
static void chase(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0)
|
||||
spr.lotag = 250;
|
||||
|
||||
short osectnum = spr.sectnum;
|
||||
if (krand() % 63 == 0) {
|
||||
if (cansee(plr.x, plr.y, plr.z, plr.sector, sprite[i].x, sprite[i].y,
|
||||
sprite[i].z - (tilesizy[sprite[i].picnum] << 7), sprite[i].sectnum) && plr.invisibletime < 0)
|
||||
newstatus(i, ATTACK);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
//sprite[i].z = sector[sprite[i].sectnum].floorz - (32 << 8);
|
||||
int dax = (sintable[(sprite[i].ang + 512) & 2047] * TICSPERFRAME) << 3;
|
||||
int day = (sintable[sprite[i].ang & 2047] * TICSPERFRAME) << 3;
|
||||
checksight(plr, i);
|
||||
|
||||
if (!checkdist(plr, i)) {
|
||||
checkmove(i, dax, day);
|
||||
}
|
||||
else {
|
||||
if (krand() % 8 == 0) // NEW
|
||||
newstatus(i, ATTACK); // NEW
|
||||
else { // NEW
|
||||
sprite[i].ang = (short)(((krand() & 512 - 256) + sprite[i].ang + 1024) & 2047); // NEW
|
||||
newstatus(i, CHASE); // NEW
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 (spr.z > zr_florz)
|
||||
spr.z = zr_florz;
|
||||
if (spr.z < zr_ceilz - (32 << 8))
|
||||
spr.z = zr_ceilz - (32 << 8);
|
||||
|
||||
if (checksector6(i))
|
||||
return;
|
||||
|
||||
processfluid(i, zr_florhit, true);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
static void attack(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (plr.z < spr.z)
|
||||
spr.z -= TICSPERFRAME << 8;
|
||||
|
||||
if (plr.z > spr.z)
|
||||
spr.z += TICSPERFRAME << 8;
|
||||
|
||||
if (spr.lotag < 0) {
|
||||
if (cansee(plr.x, plr.y, plr.z, plr.sector, spr.x, spr.y, spr.z - (tilesizy[spr.picnum] << 7),
|
||||
spr.sectnum))
|
||||
if (checkdist(plr, i)) {
|
||||
if (plr.shockme < 0)
|
||||
if ((krand() & 1) != 0) {
|
||||
plr.shockme = 120;
|
||||
if (!game.WH2) {
|
||||
plr.lvl--;
|
||||
switch (plr.lvl) {
|
||||
case 1:
|
||||
plr.score = 0;
|
||||
plr.maxhealth = 100;
|
||||
break;
|
||||
case 2:
|
||||
plr.score = 2350;
|
||||
plr.maxhealth = 120;
|
||||
break;
|
||||
case 3:
|
||||
plr.score = 4550;
|
||||
plr.maxhealth = 140;
|
||||
break;
|
||||
case 4:
|
||||
plr.score = 9300;
|
||||
plr.maxhealth = 160;
|
||||
break;
|
||||
case 5:
|
||||
plr.score = 18400;
|
||||
plr.maxhealth = 180;
|
||||
break;
|
||||
case 6:
|
||||
plr.score = 36700;
|
||||
plr.maxhealth = 200;
|
||||
break;
|
||||
case 7:
|
||||
plr.score = 75400;
|
||||
plr.maxhealth = 200;
|
||||
break;
|
||||
}
|
||||
if (plr.lvl < 1) {
|
||||
plr.lvl = 1;
|
||||
plr.health = -1;
|
||||
}
|
||||
showmessage("Level Drained", 360);
|
||||
}
|
||||
else
|
||||
showmessage("Shocked", 360);
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
newstatus(i, DRAIN);
|
||||
else
|
||||
newstatus(i, CHASE);
|
||||
}
|
||||
|
||||
int floorz = getflorzofslope(spr.sectnum, spr.x, spr.y) - (16 << 8);
|
||||
if (spr.z > floorz)
|
||||
spr.z = floorz;
|
||||
}
|
||||
|
||||
static void face(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
|
||||
if (cansee(plr.x, plr.y, plr.z, plr.sector, spr.x, spr.y, spr.z - (tilesizy[spr.picnum] << 7),
|
||||
spr.sectnum) && 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 newstatus(i, FLEE);
|
||||
}
|
||||
|
||||
if (checkdist(plr, i))
|
||||
newstatus(i, ATTACK);
|
||||
}
|
||||
|
||||
static void search(PLAYER& plr, short i) {
|
||||
aisearch(plr, i, true);
|
||||
checksector6(i);
|
||||
}
|
||||
|
||||
static void flee(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
short osectnum = spr.sectnum;
|
||||
|
||||
int movestat = aifly(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, true);
|
||||
|
||||
setsprite(i, spr.x, spr.y, spr.z);
|
||||
}
|
||||
|
||||
static void die(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
|
||||
if (spr.lotag <= 0) {
|
||||
spr.picnum++;
|
||||
spr.lotag = 20;
|
||||
if (sprite[i].picnum == WILLOWEXPLO || sprite[i].picnum == WILLOWEXPLO + 1
|
||||
|| sprite[i].picnum == WILLOWEXPLO + 2)
|
||||
sprite[i].xrepeat = sprite[i].yrepeat <<= 1;
|
||||
|
||||
if (spr.picnum == WILLOWEXPLO + 2) {
|
||||
if (difficulty == 4)
|
||||
newstatus(i, RESURECT);
|
||||
else {
|
||||
kills++;
|
||||
newstatus(i, DEAD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void nuked(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
if (game.WH2) {
|
||||
chunksofmeat(plr, i, spr.x, spr.y, spr.z, spr.sectnum, spr.ang);
|
||||
trailingsmoke(i, false);
|
||||
newstatus((short)i, DIE);
|
||||
}
|
||||
}
|
||||
|
||||
void willowProcess(PLAYER& plr)
|
||||
{
|
||||
for (short i = headspritestat[DRAIN], nextsprite; i >= 0; i = nextsprite) {
|
||||
nextsprite = nextspritestat[i];
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
switch (spr.detail) {
|
||||
case WILLOWTYPE:
|
||||
willowDrain(plr, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void willowDrain(PLAYER& plr, short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.lotag -= TICSPERFRAME;
|
||||
if (spr.lotag < 0) {
|
||||
playsound_loc(S_FIREBALL, spr.x, spr.y);
|
||||
int oldz = spr.z;
|
||||
spr.z += 6144;
|
||||
castspell(plr, i);
|
||||
spr.z = oldz;
|
||||
newstatus(i, CHASE);
|
||||
}
|
||||
}
|
||||
|
||||
void createWillowAI() {
|
||||
auto& e = enemy[WILLOWTYPE];
|
||||
e.info.Init(32, 32, 512, 120, 0, 64, true, game.WH2 ? 5 : 400, 0);
|
||||
e.chase = chase;
|
||||
e.attack = attack;
|
||||
e.face = face;
|
||||
e.search = search;
|
||||
e.flee = flee;
|
||||
e.die = die;
|
||||
e.nuked = nuked;
|
||||
}
|
||||
|
||||
|
||||
void premap(short i) {
|
||||
SPRITE& spr = sprite[i];
|
||||
|
||||
spr.detail = WILLOWTYPE;
|
||||
enemy[WILLOWTYPE].info.set(spr);
|
||||
spr.cstat |= 128;
|
||||
spr.z -= tilesizy[WILLOW] << 8;
|
||||
changespritestat(i, FACE);
|
||||
}
|
||||
|
||||
END_WH_NS
|
207
source/games/whaven/src/globals.h
Normal file
207
source/games/whaven/src/globals.h
Normal file
|
@ -0,0 +1,207 @@
|
|||
#pragma once
|
||||
#include "ns.h"
|
||||
|
||||
BEGIN_WH_NS
|
||||
|
||||
enum
|
||||
{
|
||||
MAXWEAPONS = 10,
|
||||
MAXPOTIONS = 5,
|
||||
|
||||
BACKBUTTON = 9216,
|
||||
BACKSCALE = 16384,
|
||||
MOUSECURSOR = 9217,
|
||||
RESERVED1 = 9218,
|
||||
RESERVED2 = 9219,
|
||||
|
||||
WHLOGO = 9220,
|
||||
MENUFONT = 9221, //+32
|
||||
|
||||
MINITEXTPOINT = 9254,
|
||||
MINITEXTSLASH = 9255,
|
||||
|
||||
WH2FONTBIGLETTERS = 9256,
|
||||
WH2FONTLILLETTERS = 9282,
|
||||
WH2FONTNUMBERS = 9308,
|
||||
WH2LOGO = 9335,
|
||||
WH2FONTBACKGROUND = 9336,
|
||||
|
||||
ARROWCOUNTLIMIT = 100,
|
||||
THROWPIKELIMIT = 100,
|
||||
|
||||
GRAVITYCONSTANT = (4 << 7) - 32,
|
||||
JUMPVEL = (4 << 10) - 256,
|
||||
|
||||
WH2GRAVITYCONSTANT = (8 << 5),
|
||||
WH2JUMPVEL = (6 << 10), //(8 << 10)
|
||||
GROUNDBIT = 1,
|
||||
PLATFORMBIT = 2,
|
||||
|
||||
TICSPERFRAME = 3,
|
||||
TIMERRATE = 120,
|
||||
|
||||
kExtraTile = MAXTILES - MAXUSERTILES,
|
||||
|
||||
// Hit definitions
|
||||
kHitTypeMask = 0xE000,
|
||||
kHitIndexMask = 0x1FFF,
|
||||
kHitFloor = 0x4000,
|
||||
kHitSector = 0x4000,
|
||||
kHitCeiling = 0x6000,
|
||||
kHitWall = 0x8000,
|
||||
kHitSprite = 0xC000,
|
||||
|
||||
PLAYERHEIGHT = 48,
|
||||
WH2PLAYERHEIGHT = 64,
|
||||
MAXNUMORBS = 8,
|
||||
MAXHEALTH = 100,
|
||||
MAXKEYS = 4,
|
||||
MAXTREASURES = 18,
|
||||
|
||||
LOW = 1,
|
||||
HIGH = 2,
|
||||
|
||||
TOP = 1,
|
||||
BOTTOM = 2,
|
||||
|
||||
INACTIVE = 0,
|
||||
PATROL = 1,
|
||||
CHASE = 2,
|
||||
AMBUSH = 3,
|
||||
BIRTH = 4,
|
||||
DODGE = 5,
|
||||
ATTACK = 6,
|
||||
DEATH = 7,
|
||||
STAND = 8,
|
||||
|
||||
MISSILE = 100,
|
||||
FX = 101,
|
||||
HEATSEEKER = 102,
|
||||
YELL = 103,
|
||||
CAST = 104,
|
||||
PUSH = 105,
|
||||
FALL = 106,
|
||||
DIE = 107,
|
||||
DEAD = 108,
|
||||
FACE = 109,
|
||||
SHOVE = 110,
|
||||
SHATTER = 111,
|
||||
FIRE = 112,
|
||||
LIFTUP = 113,
|
||||
LIFTDN = 114,
|
||||
PENDULUM = 115,
|
||||
RESURECT = 116,
|
||||
BOB = 117,
|
||||
SHOVER = 118,
|
||||
TORCHER = 119,
|
||||
MASPLASH = 120,
|
||||
CHUNKOMEAT = 121,
|
||||
FLEE = 122,
|
||||
DORMANT = 123,
|
||||
ACTIVE = 124,
|
||||
ATTACK2 = 125,
|
||||
WITCHSIT = 126,
|
||||
CHILL = 127,
|
||||
SKIRMISH = 128,
|
||||
FLOCK = 129,
|
||||
FLOCKSPAWN = 130,
|
||||
PAIN = 131,
|
||||
WAR = 132,
|
||||
TORCHLIGHT = 133,
|
||||
GLOWLIGHT = 134,
|
||||
BLOOD = 135,
|
||||
DRIP = 136,
|
||||
DEVILFIRE = 137,
|
||||
FROZEN = 138,
|
||||
PULLTHECHAIN = 139,
|
||||
FLOCKCHIRP = 140,
|
||||
CHUNKOWALL = 141,
|
||||
FINDME = 142,
|
||||
DRAIN = 143,
|
||||
RATRACE = 144,
|
||||
SMOKE = 145,
|
||||
EXPLO = 146,
|
||||
JAVLIN = 147,
|
||||
ANIMLEVERUP = 148,
|
||||
ANIMLEVERDN = 149,
|
||||
BROKENVASE = 150,
|
||||
NUKED = 151,
|
||||
WARPFX = 152,
|
||||
PATROLFLAG = 153,
|
||||
PLACECONE = 154,
|
||||
REMOVECONE = 155,
|
||||
FIRSTCONE = 156,
|
||||
GOTOCONE = 157,
|
||||
TORCHFRONT = 158,
|
||||
APATROLPOINT = 159,
|
||||
SHADE = 160,
|
||||
EVILSPIRIT = 161,
|
||||
STONETOFLESH = 162,
|
||||
SPARKS = 163,
|
||||
SPARKSUP = 164,
|
||||
SPARKSDN = 165,
|
||||
LAND = 166,
|
||||
SHARDOFGLASS = 167,
|
||||
FIRECHUNK = 168,
|
||||
DUDE = 170,
|
||||
|
||||
ACTIVATESECTOR = 1,
|
||||
ACTIVATESECTORONCE = 2,
|
||||
|
||||
DOORUPTAG = 6,
|
||||
DOORDOWNTAG = 7,
|
||||
DOORSPLITHOR = 8,
|
||||
DOORSPLITVER = 9,
|
||||
DOORSWINGTAG = 13,
|
||||
DOORBOX = 16,
|
||||
|
||||
PLATFORMELEVTAG = 1000,
|
||||
BOXELEVTAG = 1003,
|
||||
|
||||
SECTOREFFECT = 104,
|
||||
PULSELIGHT = 0,
|
||||
FLICKERLIGHT = 1,
|
||||
DELAYEFFECT = 2,
|
||||
XPANNING = 3,
|
||||
|
||||
DOORDELAY = 480, // 4 second delay for doors to close
|
||||
DOORSPEED = 128,
|
||||
ELEVSPEED = 256,
|
||||
|
||||
PICKDISTANCE = 512, // for picking up sprites
|
||||
PICKHEIGHT = 40,
|
||||
PICKHEIGHT2 = 64,
|
||||
|
||||
JETPACKPIC = 93 , // sprites available to pick up
|
||||
|
||||
MAXSWINGDOORS = 32,
|
||||
|
||||
JETPACKITEM = 0,
|
||||
SHOTGUNITEM = 1,
|
||||
|
||||
SHOTGUNPIC = 101,
|
||||
SHOTGUNVIEW = 102,
|
||||
|
||||
KILLSECTOR = 4444,
|
||||
|
||||
TDIAMONDRING = 0, //armortype3 200units
|
||||
TSHADOWAMULET = 1, //shadow
|
||||
TGLASSSKULL = 2, //add score
|
||||
TAHNK = 3, //health 250units
|
||||
TBLUESCEPTER = 4, //lava walk
|
||||
TYELLOWSCEPTER = 5, //water walk
|
||||
TADAMANTINERING = 6, //unfinity attack protection
|
||||
TONYXRING = 7, //projectiles protection
|
||||
TPENTAGRAM = 8, //exit
|
||||
TCRYSTALSTAFF = 9, //health 250units armortype2 200units
|
||||
TAMULETOFTHEMIST = 10, //invisible
|
||||
THORNEDSKULL = 11, //end game
|
||||
TTHEHORN = 12, //vampire
|
||||
TSAPHIRERING = 13, //set armortype to 3
|
||||
TBRASSKEY = 14,
|
||||
TBLACKKEY = 15,
|
||||
TGLASSKEY = 16,
|
||||
TIVORYKEY = 17,
|
||||
};
|
||||
|
||||
END_WH_NS
|
501
source/games/whaven/src/names.cpp
Normal file
501
source/games/whaven/src/names.cpp
Normal file
|
@ -0,0 +1,501 @@
|
|||
#include "ns.h"
|
||||
#include "gamecontrol.h"
|
||||
|
||||
short KNIFEREADY;
|
||||
short KNIFEATTACK;
|
||||
short RFIST;
|
||||
short SWORDATTACK;
|
||||
short MORNINGSTAR;
|
||||
short BOWREADY;
|
||||
short BOWREADYEND;
|
||||
short BOWWALK;
|
||||
short KNIFEATTACK2;
|
||||
short SWORDPULL;
|
||||
short SWORDATTACK2;
|
||||
short MORNINGATTACK2;
|
||||
short MUMEDUSA;
|
||||
short MUTWOHANDS;
|
||||
short BMUTWOHANDS;
|
||||
short GOBSWORDPULL;
|
||||
short GOBSWORDATTACK;
|
||||
short GOBSWORDATTACK2;
|
||||
short BIGAXEATTACK;
|
||||
short BIGAXEATTACK2;
|
||||
short BIGAXEDRAW;
|
||||
short HALBERDATTACK1;
|
||||
short HALBERDATTACK2;
|
||||
short HALBERDDRAW;
|
||||
short PIKEDRAW;
|
||||
short PIKEATTACK1;
|
||||
short EXCALATTACK1;
|
||||
short EXCALATTACK2;
|
||||
short EXCALDRAW;
|
||||
short BIGAXEDRAW9;
|
||||
short BIGAXEDRAW10;
|
||||
short GEARS2START;
|
||||
short HORNEDSKULL;
|
||||
short THEFONT;
|
||||
short CRYSTALSTAFF;
|
||||
short TORCH;
|
||||
short WEAPON1;
|
||||
short WEAPON1A;
|
||||
short AMULETOFTHEMIST;
|
||||
short WEAPON2;
|
||||
short BRASSKEY;
|
||||
short BLACKKEY;
|
||||
short GLASSKEY;
|
||||
short IVORYKEY;
|
||||
short NEWCHUNK;
|
||||
short BOWLOFFIRE;
|
||||
short SPAWNFIREBALL;
|
||||
short PENTAGRAM;
|
||||
short THEHORN;
|
||||
short BOW;
|
||||
short SWINGGATE3;
|
||||
short PLATEARMOR;
|
||||
short HELMET;
|
||||
short CHAINMAIL;
|
||||
short SCROLLSCARE;
|
||||
short SCROLLNUKE;
|
||||
short SCROLLFLY;
|
||||
short SCROLLFIREBALL;
|
||||
short SCROLLFREEZE;
|
||||
short SCROLLNIGHT;
|
||||
short SCROLLMAGIC;
|
||||
short SCROLLOPEN;
|
||||
short LEATHERARMOR;
|
||||
short QUIVER;
|
||||
short SWINGGATE4;
|
||||
short SWINGGATE5;
|
||||
short SMOKEFX;
|
||||
short STANDINTORCH;
|
||||
short PENTADOOR3;
|
||||
short PENTADOOR4;
|
||||
short PENTADOOR5;
|
||||
short PENTADOOR6;
|
||||
short PENTADOOR7;
|
||||
short SCARY;
|
||||
short FISH;
|
||||
short LEVERUP;
|
||||
short LEVERDOWN;
|
||||
short SPAWNJAVLIN;
|
||||
short RAT;
|
||||
short GUARDIAN;
|
||||
short GUARDIANATTACK;
|
||||
short DART;
|
||||
short WEAPON4;
|
||||
short WEAPON6;
|
||||
short WEAPON5;
|
||||
short WEAPON5B;
|
||||
short THROWHALBERD;
|
||||
short WEAPON7;
|
||||
short THROWPIKE;
|
||||
short EXPLO2;
|
||||
short SHATTERVASE;
|
||||
short SHATTERVASE2;
|
||||
short SHATTERVASE3;
|
||||
short HANGMAN;
|
||||
short SKELETON;
|
||||
short SKELETONATTACK;
|
||||
short SKELETONSKULL;
|
||||
short SKELETONUP;
|
||||
short SKELETONDIE;
|
||||
short SKELETONDEAD;
|
||||
short BONECHUNK1;
|
||||
short BONECHUNKEND;
|
||||
short PIKEATTACK2;
|
||||
short GOBWEAPON;
|
||||
short SFLASKBLUE;
|
||||
short SFLASKGREEN;
|
||||
short SFLASKOCHRE;
|
||||
short SFLASKRED;
|
||||
short SFLASKTAN;
|
||||
short SFLASKBLACK;
|
||||
short SHEALTHFONT;
|
||||
short SSCOREFONT;
|
||||
short SPOTIONFONT;
|
||||
short SPOTIONBACKPIC;
|
||||
short SPOTIONARROW;
|
||||
short SSPELLBOOKBLANK;
|
||||
short SSPELLBOOK2;
|
||||
short SSPELLBOOK3;
|
||||
short SSPELLBOOK4;
|
||||
short SSPELLBOOK5;
|
||||
short SSPELLBOOK6;
|
||||
short SSPELLBOOK7;
|
||||
short SSPELLBOOK8;
|
||||
short SARROWS;
|
||||
short SPLAYERLVL;
|
||||
short SSTATUSBAR;
|
||||
short SKEYBLANK;
|
||||
short SKEYBRASS;
|
||||
short SKEYBLACK;
|
||||
short SKEYGLASS;
|
||||
short SKEYIVORY;
|
||||
short SHEALTHBACK;
|
||||
short SSCOREBACKPIC;
|
||||
short SNDEFFECT;
|
||||
short SNDLOOP;
|
||||
short SNDLOOPOFF;
|
||||
short BROWNCHUNKSTART;
|
||||
short GREYCHUNKSTART;
|
||||
short REDCHUNKSTART;
|
||||
short GREENCHUNKSTART;
|
||||
short TANCHUNKSTART;
|
||||
short WILLOW;
|
||||
short SPIKES;
|
||||
short STHEFLAG;
|
||||
short GRONHALATTACK;
|
||||
short GRONHALATTACKEND;
|
||||
short GROLHALREADY;
|
||||
short GRONHALREADYEND;
|
||||
short GRONHAL;
|
||||
short GRONHALPAIN;
|
||||
short GRONHALDIE;
|
||||
short GRONSWATTACK;
|
||||
short GRONSW;
|
||||
short GRONSWPAIN;
|
||||
short GRONSWDIE;
|
||||
short GRONMUATTACK;
|
||||
short GRONDIE;
|
||||
short GRONDEAD;
|
||||
short GRONMU;
|
||||
short GRONMUPAIN;
|
||||
short GRONMUDIE;
|
||||
short GRONSHIELD;
|
||||
short SHIELD;
|
||||
|
||||
void InitNames()
|
||||
{
|
||||
if(!game.WH2) {
|
||||
KNIFEREADY = 1249;
|
||||
KNIFEATTACK = 1261;
|
||||
RFIST = 1268;
|
||||
SWORDATTACK = 1291;
|
||||
MORNINGSTAR = 1306;
|
||||
BOWREADY = 1313;
|
||||
BOWREADYEND = 1319;
|
||||
BOWWALK = 1323;
|
||||
KNIFEATTACK2 = 1329;
|
||||
SWORDPULL = 1333;
|
||||
SWORDATTACK2 = 1340;
|
||||
MORNINGATTACK2 = 1348;
|
||||
MUMEDUSA = 1353;
|
||||
MUTWOHANDS = 1363;
|
||||
BMUTWOHANDS = 1378;
|
||||
GOBSWORDPULL = 1390;
|
||||
GOBSWORDATTACK = 1397;
|
||||
GOBSWORDATTACK2 = 1404;
|
||||
BIGAXEATTACK = 1411;
|
||||
BIGAXEATTACK2 = 1421;
|
||||
BIGAXEDRAW = 1429;
|
||||
HALBERDATTACK1 = 1438;
|
||||
HALBERDATTACK2 = 1443;
|
||||
HALBERDDRAW = 1447;
|
||||
PIKEDRAW = 1451;
|
||||
PIKEATTACK1 = 1457;
|
||||
EXCALATTACK1 = 1463;
|
||||
EXCALATTACK2 = 1473;
|
||||
EXCALDRAW = 1481;
|
||||
BIGAXEDRAW9 = 1494;
|
||||
BIGAXEDRAW10 = 1495;
|
||||
GEARS2START = 1498;
|
||||
HORNEDSKULL = 1503;
|
||||
THEFONT = 1511;
|
||||
CRYSTALSTAFF = 1551;
|
||||
TORCH = 1554;
|
||||
WEAPON1 = 1567;
|
||||
WEAPON1A = 1571;
|
||||
AMULETOFTHEMIST = 1575;
|
||||
WEAPON2 = 1583;
|
||||
BRASSKEY = 1624;
|
||||
BLACKKEY = 1632;
|
||||
GLASSKEY = 1640;
|
||||
IVORYKEY = 1648;
|
||||
NEWCHUNK = 1664;
|
||||
BOWLOFFIRE = 1705;
|
||||
SPAWNFIREBALL = 1718;
|
||||
PENTAGRAM = 1760;
|
||||
THEHORN = 1768;
|
||||
BOW = 1776;
|
||||
SWINGGATE3 = 1789;
|
||||
PLATEARMOR = 1794;
|
||||
HELMET = 1802;
|
||||
CHAINMAIL = 1810;
|
||||
SCROLLSCARE = 1818;
|
||||
SCROLLNUKE = 1826;
|
||||
SCROLLFLY = 1834;
|
||||
SCROLLFIREBALL = 1842;
|
||||
SCROLLFREEZE = 1850;
|
||||
SCROLLNIGHT = 1858;
|
||||
SCROLLMAGIC = 1866;
|
||||
SCROLLOPEN = 1874;
|
||||
LEATHERARMOR = 1882;
|
||||
QUIVER = 1890;
|
||||
SWINGGATE4 = 1898;
|
||||
SWINGGATE5 = 1899;
|
||||
SMOKEFX = 1904;
|
||||
STANDINTORCH = 1908;
|
||||
PENTADOOR3 = 1927;
|
||||
PENTADOOR4 = 1928;
|
||||
PENTADOOR5 = 1929;
|
||||
PENTADOOR6 = 1930;
|
||||
PENTADOOR7 = 1931;
|
||||
SCARY = 1933;
|
||||
FISH = 1945;
|
||||
LEVERUP = 1947;
|
||||
LEVERDOWN = 1949;
|
||||
SPAWNJAVLIN = 1958;
|
||||
RAT = 1962;
|
||||
GUARDIAN = 1994;
|
||||
GUARDIANATTACK = 2002;
|
||||
DART = 2010;
|
||||
WEAPON4 = 2027;
|
||||
WEAPON6 = 2039;
|
||||
WEAPON5 = 2047;
|
||||
WEAPON5B = 2055;
|
||||
THROWHALBERD = 2066;
|
||||
WEAPON7 = 2067;
|
||||
THROWPIKE = 2071;
|
||||
EXPLO2 = 2096;
|
||||
SHATTERVASE = 2124;
|
||||
SHATTERVASE2 = 2131;
|
||||
SHATTERVASE3 = 2138;
|
||||
HANGMAN = 2145;
|
||||
SKELETON = 2156;
|
||||
SKELETONATTACK = 2181;
|
||||
SKELETONSKULL = 2186;
|
||||
SKELETONUP = 2191;
|
||||
SKELETONDIE = 2192;
|
||||
SKELETONDEAD = 2198;
|
||||
BONECHUNK1 = 2199;
|
||||
BONECHUNKEND = 2208;
|
||||
PIKEATTACK2 = 2209;
|
||||
GOBWEAPON = 2218;
|
||||
SFLASKBLUE = 2240;
|
||||
SFLASKGREEN = 2241;
|
||||
SFLASKOCHRE = 2242;
|
||||
SFLASKRED = 2243;
|
||||
SFLASKTAN = 2244;
|
||||
SFLASKBLACK = 2245;
|
||||
SHEALTHFONT = 2246;
|
||||
SSCOREFONT = 2256;
|
||||
SPOTIONFONT = 2266;
|
||||
SPOTIONBACKPIC = 2280;
|
||||
SPOTIONARROW = 2281;
|
||||
SSPELLBOOKBLANK = 2286;
|
||||
SSPELLBOOK2 = 2294;
|
||||
SSPELLBOOK3 = 2302;
|
||||
SSPELLBOOK4 = 2310;
|
||||
SSPELLBOOK5 = 2317;
|
||||
SSPELLBOOK6 = 2324;
|
||||
SSPELLBOOK7 = 2332;
|
||||
SSPELLBOOK8 = 2340;
|
||||
SARROWS = 2348;
|
||||
SPLAYERLVL = 2349;
|
||||
SSTATUSBAR = 2358;
|
||||
SKEYBLANK = 2359;
|
||||
SKEYBRASS = 2360;
|
||||
SKEYBLACK = 2361;
|
||||
SKEYGLASS = 2362;
|
||||
SKEYIVORY = 2363;
|
||||
SHEALTHBACK = 2365;
|
||||
SSCOREBACKPIC = 2368;
|
||||
SNDEFFECT = 2369;
|
||||
SNDLOOP = 2370;
|
||||
SNDLOOPOFF = 2371;
|
||||
BROWNCHUNKSTART = 2387;
|
||||
GREYCHUNKSTART = 2395;
|
||||
REDCHUNKSTART = 2403;
|
||||
GREENCHUNKSTART = 2411;
|
||||
TANCHUNKSTART = 2419;
|
||||
WILLOW = 2427;
|
||||
SPIKES = 2488;
|
||||
STHEFLAG = 2491;
|
||||
GRONHALATTACK = 2504;
|
||||
GRONHALATTACKEND = 2508;
|
||||
GROLHALREADY = 2509;
|
||||
GRONHALREADYEND = 2510;
|
||||
GRONHAL = 2539;
|
||||
GRONHALPAIN = 2559;
|
||||
GRONHALDIE = 2560;
|
||||
GRONSWATTACK = 2561;
|
||||
GRONSW = 2581;
|
||||
GRONSWPAIN = 2601;
|
||||
GRONSWDIE = 2602;
|
||||
GRONMUATTACK = 2603;
|
||||
GRONDIE = 2633;
|
||||
GRONDEAD = 2639;
|
||||
GRONMU = 2640;
|
||||
GRONMUPAIN = 2660;
|
||||
GRONMUDIE = 2661;
|
||||
GRONSHIELD = 2680;
|
||||
SHIELD = 2684;
|
||||
} else { //WH2
|
||||
KNIFEREADY = 1248;
|
||||
KNIFEATTACK = 1260;
|
||||
RFIST = 1267;
|
||||
SWORDATTACK = 1290;
|
||||
MORNINGSTAR = 1305;
|
||||
BOWREADY = 1312;
|
||||
BOWREADYEND = 1318;
|
||||
BOWWALK = 1322;
|
||||
KNIFEATTACK2 = 1328;
|
||||
SWORDPULL = 1332;
|
||||
SWORDATTACK2 = 1339;
|
||||
MORNINGATTACK2 = 1347;
|
||||
MUMEDUSA = 1352;
|
||||
MUTWOHANDS = 1362;
|
||||
BMUTWOHANDS = 1377;
|
||||
GOBSWORDPULL = 1389;
|
||||
GOBSWORDATTACK = 1396;
|
||||
GOBSWORDATTACK2 = 1403;
|
||||
BIGAXEATTACK = 1410;
|
||||
BIGAXEATTACK2 = 1420;
|
||||
BIGAXEDRAW = 1428;
|
||||
HALBERDATTACK1 = 1437;
|
||||
HALBERDATTACK2 = 1442;
|
||||
HALBERDDRAW = 1446;
|
||||
PIKEDRAW = 1450;
|
||||
PIKEATTACK1 = 1456;
|
||||
EXCALATTACK1 = 1462;
|
||||
EXCALATTACK2 = 1472;
|
||||
EXCALDRAW = 1480;
|
||||
BIGAXEDRAW9 = 1493;
|
||||
BIGAXEDRAW10 = 1494;
|
||||
GEARS2START = 1497;
|
||||
HORNEDSKULL = 1502;
|
||||
THEFONT = 1510;
|
||||
CRYSTALSTAFF = 1550;
|
||||
TORCH = 1553;
|
||||
WEAPON1 = 1566;
|
||||
WEAPON1A = 1570;
|
||||
AMULETOFTHEMIST = 1574;
|
||||
WEAPON2 = 1582;
|
||||
BRASSKEY = 1623;
|
||||
BLACKKEY = 1631;
|
||||
GLASSKEY = 1639;
|
||||
IVORYKEY = 1647;
|
||||
NEWCHUNK = 1663;
|
||||
BOWLOFFIRE = 1704;
|
||||
SPAWNFIREBALL = 1717;
|
||||
PENTAGRAM = 1759;
|
||||
THEHORN = 1767;
|
||||
BOW = 1775;
|
||||
SWINGGATE3 = 1788;
|
||||
PLATEARMOR = 1793;
|
||||
HELMET = 1801;
|
||||
CHAINMAIL = 1809;
|
||||
SCROLLSCARE = 1817;
|
||||
SCROLLNUKE = 1825;
|
||||
SCROLLFLY = 1833;
|
||||
SCROLLFIREBALL = 1841;
|
||||
SCROLLFREEZE = 1849;
|
||||
SCROLLNIGHT = 1857;
|
||||
SCROLLMAGIC = 1865;
|
||||
SCROLLOPEN = 1873;
|
||||
LEATHERARMOR = 1881;
|
||||
QUIVER = 1889;
|
||||
SWINGGATE4 = 1897;
|
||||
SWINGGATE5 = 1898;
|
||||
SMOKEFX = 1903;
|
||||
STANDINTORCH = 1907;
|
||||
PENTADOOR3 = 1926;
|
||||
PENTADOOR4 = 1927;
|
||||
PENTADOOR5 = 1928;
|
||||
PENTADOOR6 = 1929;
|
||||
PENTADOOR7 = 1930;
|
||||
SCARY = 1932;
|
||||
FISH = 1944;
|
||||
LEVERUP = 1946;
|
||||
LEVERDOWN = 1948;
|
||||
SPAWNJAVLIN = 1957;
|
||||
RAT = 1961;
|
||||
GUARDIAN = 1993;
|
||||
GUARDIANATTACK = 2001;
|
||||
DART = 2009;
|
||||
WEAPON4 = 2026;
|
||||
WEAPON6 = 2038;
|
||||
WEAPON5 = 2046;
|
||||
WEAPON5B = 2054;
|
||||
THROWHALBERD = 2065;
|
||||
WEAPON7 = 2066;
|
||||
THROWPIKE = 2070;
|
||||
EXPLO2 = 2095;
|
||||
SHATTERVASE = 2123;
|
||||
SHATTERVASE2 = 2130;
|
||||
SHATTERVASE3 = 2137;
|
||||
HANGMAN = 2144;
|
||||
SKELETON = 2155;
|
||||
SKELETONATTACK = 2180;
|
||||
SKELETONSKULL = 2185;
|
||||
SKELETONUP = 2190;
|
||||
SKELETONDIE = 2191;
|
||||
SKELETONDEAD = 2197;
|
||||
BONECHUNK1 = 2198;
|
||||
BONECHUNKEND = 2207;
|
||||
PIKEATTACK2 = 2208;
|
||||
GOBWEAPON = 2217;
|
||||
SFLASKBLUE = 2239;
|
||||
SFLASKGREEN = 2240;
|
||||
SFLASKOCHRE = 2241;
|
||||
SFLASKRED = 2242;
|
||||
SFLASKTAN = 2243;
|
||||
SFLASKBLACK = 2244;
|
||||
SHEALTHFONT = 2245;
|
||||
SSCOREFONT = 2255;
|
||||
SPOTIONFONT = 2265;
|
||||
SPOTIONBACKPIC = 2279;
|
||||
SPOTIONARROW = 2280;
|
||||
SSPELLBOOKBLANK = 2285;
|
||||
SSPELLBOOK2 = 2293;
|
||||
SSPELLBOOK3 = 2301;
|
||||
SSPELLBOOK4 = 2309;
|
||||
SSPELLBOOK5 = 2316;
|
||||
SSPELLBOOK6 = 2323;
|
||||
SSPELLBOOK7 = 2331;
|
||||
SSPELLBOOK8 = 2339;
|
||||
SARROWS = 2347;
|
||||
SPLAYERLVL = 2348;
|
||||
SSTATUSBAR = 2357;
|
||||
SKEYBLANK = 2358;
|
||||
SKEYBRASS = 2359;
|
||||
SKEYBLACK = 2360;
|
||||
SKEYGLASS = 2361;
|
||||
SKEYIVORY = 2362;
|
||||
SHEALTHBACK = 2364;
|
||||
SSCOREBACKPIC = 2367;
|
||||
SNDEFFECT = 2368;
|
||||
SNDLOOP = 2369;
|
||||
SNDLOOPOFF = 2370;
|
||||
BROWNCHUNKSTART = 2386;
|
||||
GREYCHUNKSTART = 2394;
|
||||
REDCHUNKSTART = 2402;
|
||||
GREENCHUNKSTART = 2410;
|
||||
TANCHUNKSTART = 2418;
|
||||
WILLOW = 2426;
|
||||
SPIKES = 2487;
|
||||
STHEFLAG = 2490;
|
||||
GRONHALATTACK = 2502;
|
||||
GRONHALATTACKEND = 2506;
|
||||
GROLHALREADY = 2507;
|
||||
GRONHALREADYEND = 2508;
|
||||
GRONHAL = 2537;
|
||||
GRONHALPAIN = 2557;
|
||||
GRONHALDIE = 2558;
|
||||
GRONSWATTACK = 2559;
|
||||
GRONSW = 2579;
|
||||
GRONSWPAIN = 2599;
|
||||
GRONSWDIE = 2600;
|
||||
GRONMUATTACK = 2601;
|
||||
GRONDIE = 2631;
|
||||
GRONDEAD = 2637;
|
||||
GRONMU = 2638;
|
||||
GRONMUPAIN = 2658;
|
||||
GRONMUDIE = 2659;
|
||||
GRONSHIELD = 2678;
|
||||
SHIELD = 2682;
|
||||
}
|
||||
}
|
||||
|
||||
END_WH_NS
|
388
source/games/whaven/src/names.h
Normal file
388
source/games/whaven/src/names.h
Normal file
|
@ -0,0 +1,388 @@
|
|||
BEGIN_WH_NS
|
||||
|
||||
enum Names {
|
||||
|
||||
TILES000_START = 0,
|
||||
SLIME = 5,
|
||||
DRYWATER = 22,
|
||||
DRYSLIME = 33,
|
||||
COOLLAVA = 58,
|
||||
ANILAVA = 61,
|
||||
LAVA1 = 62,
|
||||
WOODPLANK = 68,
|
||||
SKY = 75,
|
||||
LAVA = 79,
|
||||
LAVA2 = 80,
|
||||
HEALTHWATER = 86,
|
||||
WATER = 90,
|
||||
COOLLAVA2 = 103,
|
||||
SPLASHAROO = 160,
|
||||
LASTSPLASHAROO = 166,
|
||||
SKY2 = 167,
|
||||
SKY3 = 168,
|
||||
SKY4 = 169,
|
||||
SKY5 = 170,
|
||||
SKY6 = 171,
|
||||
SKY7 = 172,
|
||||
TILES001_START = 247,
|
||||
GIFTBOX = 260,
|
||||
OPENCHEST = 263,
|
||||
BARREL = 269,
|
||||
SPACEPLANK = 271,
|
||||
PENTADOOR1 = 280,
|
||||
PENTADOOR2 = 281,
|
||||
ROPEDOOR = 282,
|
||||
TELEPAD = 291,
|
||||
BULLET = 294,
|
||||
PINE = 308,
|
||||
SWINGDOOR = 324,
|
||||
SWINGDOOR2 = 325,
|
||||
SWINGDOOR3 = 326,
|
||||
BAT = 330,
|
||||
FBARREL = 340,
|
||||
FBARRELFALL = 341,
|
||||
FSHATTERBARREL = 342,
|
||||
BOULDER = 361,
|
||||
PULLCHAIN1 = 370,
|
||||
PULLCHAIN2 = 371,
|
||||
PULLCHAIN3 = 372,
|
||||
SAPHIRERING = 373,
|
||||
TALLSWING = 385,
|
||||
TALLSWING2 = 386,
|
||||
SPARKFX = 390,
|
||||
VASEA = 392,
|
||||
VASEB = 393,
|
||||
VASEC = 394,
|
||||
HEALTHPOTION = 401,
|
||||
FIREWALKPOTION = 402,
|
||||
STRENGTHPOTION = 403,
|
||||
INVISIBLEPOTION = 404,
|
||||
ARMORPOTION = 406,
|
||||
LAVASPLASH = 423,
|
||||
LASTLAVASPLASH = 437,
|
||||
SPIKEBLADE = 461,
|
||||
SPIKE = 462,
|
||||
SPIKEPOLE = 463,
|
||||
HORIZSPIKEPOLE = 464,
|
||||
HORIZSPIKE = 465,
|
||||
HORIZSPIKEBLADE = 466,
|
||||
GEARSSTART = 467,
|
||||
GEARSEND = 474,
|
||||
SWINGHOLE = 476,
|
||||
SWINGGATE = 477,
|
||||
SWINGGATE2 = 478,
|
||||
WOODGEARSSTART = 483,
|
||||
WOODGEARSEND = 486,
|
||||
SQUAREGRATE = 490,
|
||||
MAINMENU = 500,
|
||||
TITLEPIC = 501,
|
||||
SAVEPIC = 502,
|
||||
SAVENUMBERS = 503,
|
||||
LOADPIC = 504,
|
||||
AREYOUSURE = 505,
|
||||
BLOODGORERED = 506,
|
||||
DIFFICULTRED = 507,
|
||||
BLOODGOREGREEN = 508,
|
||||
DIFFICULTGREEN = 509,
|
||||
HORNYSKULL1 = 510,
|
||||
HORNYSKULL2 = 511,
|
||||
HORNYSKULL3 = 512,
|
||||
HORNYSKULL4 = 513,
|
||||
HORNYBACK = 514,
|
||||
LOADRED = 515,
|
||||
SAVERED = 516,
|
||||
LOADGREEN = 517,
|
||||
SAVEGREEN = 518,
|
||||
MENUSELECTIONS = 519,
|
||||
NEWGAMEGREEN = 520,
|
||||
LOADSAVEGREEN = 521,
|
||||
BLOODGOREGREEN2 = 522,
|
||||
HELPGREEN = 523,
|
||||
QUITGREEN = 524,
|
||||
NOGORESHADOW = 525,
|
||||
NOGORESOLID = 526,
|
||||
GORESHADOW = 527,
|
||||
GORESOLID = 528,
|
||||
VDARK = 529,
|
||||
MDARK = 530,
|
||||
FLICKER = 531,
|
||||
XDARK = 532,
|
||||
BACKGROUND = 536,
|
||||
WALLARROW = 537,
|
||||
MUHANDS = 538,
|
||||
STATUSBAR = 545,
|
||||
ORB1 = 546,
|
||||
ORB2 = 547,
|
||||
FLASKBLUE = 548,
|
||||
FLASKGREEN = 549,
|
||||
FLASKOCHRE = 550,
|
||||
FLASKRED = 551,
|
||||
FLASKTAN = 552,
|
||||
FLASKBLACK = 553,
|
||||
BGZERO = 554,
|
||||
BGONE = 555,
|
||||
BGTWO = 556,
|
||||
BGTHREE = 557,
|
||||
BGFOUR = 558,
|
||||
BGFIVE = 559,
|
||||
BGSIX = 560,
|
||||
BGSEVEN = 561,
|
||||
BGEIGHT = 562,
|
||||
BGNINE = 563,
|
||||
SCOREFONT = 564,
|
||||
MDONE = 565,
|
||||
MDTWO = 566,
|
||||
MDTHREE = 567,
|
||||
MDFOUR = 568,
|
||||
MDFIVE = 569,
|
||||
MDSIX = 570,
|
||||
MDSEVEN = 571,
|
||||
MDEIGHT = 572,
|
||||
MDNINE = 573,
|
||||
SMFONT = 574,
|
||||
SMONE = 575,
|
||||
SMTWO = 576,
|
||||
SMTHREE = 577,
|
||||
SMFOUR = 578,
|
||||
SMFIVE = 579,
|
||||
SMSIX = 580,
|
||||
SMSEVEN = 581,
|
||||
SMEIGHT = 582,
|
||||
SMNINE = 583,
|
||||
SCOREBACKPIC = 584,
|
||||
WEAPONBACKPIC = 585,
|
||||
HEALTHBACKPIC = 586,
|
||||
BOOKBACKPIC = 587,
|
||||
ORBBACKPIC = 588,
|
||||
POTIONBACKPIC = 589,
|
||||
POTIONARROW = 590,
|
||||
ORB3 = 595,
|
||||
ORB4 = 596,
|
||||
ORB5 = 597,
|
||||
ORB6 = 598,
|
||||
ORB7 = 599,
|
||||
ORB8 = 600,
|
||||
WAVES1_SND = 607,
|
||||
WAVES2_SND = 608,
|
||||
WIND1_SND = 609,
|
||||
WIND2_SND = 610,
|
||||
LAVA1_SND = 611,
|
||||
LAVA2_SND = 612,
|
||||
DIESPIKE = 613,
|
||||
SPELLBOOKBLANK = 618,
|
||||
SPELLBOOK2 = 627,
|
||||
SPELLBOOK3 = 636,
|
||||
CHUNK1 = 645,
|
||||
CHUNK2 = 646,
|
||||
CHUNK3 = 647,
|
||||
CHUNK4 = 648,
|
||||
PLASMA = 649,
|
||||
ANNIHILATE = 650,
|
||||
WILLOWEXPLO = 653,
|
||||
EXPLOSION = 656,
|
||||
FATSPANK = 658,
|
||||
MONSTERBALL = 660,
|
||||
ICECUBE = 663,
|
||||
DISTORTIONBLAST = 664,
|
||||
SPELLBOOKBACK = 665,
|
||||
WEAPON3 = 666,
|
||||
ORB = 674,
|
||||
SPAWN = 675,
|
||||
ARMOR = 676,
|
||||
POTION = 677,
|
||||
WEAPON = 678,
|
||||
COPYRIGHT = 679,
|
||||
DIAMONDRING = 694,
|
||||
SHADOWAMULET = 698,
|
||||
GLASSSKULL = 706,
|
||||
AHNK = 714,
|
||||
BLUESCEPTER = 718,
|
||||
YELLOWSCEPTER = 722,
|
||||
ADAMANTINERING = 726,
|
||||
ONYXRING = 730,
|
||||
TILES003_START = 736,
|
||||
KOBOLD = 737,
|
||||
KOBOLDATTACK = 762,
|
||||
KOBOLDDIE = 765,
|
||||
KOBOLDDEAD = 770,
|
||||
KOBOLDTORCH = 771,
|
||||
DEVILSTAND = 772,
|
||||
DEVIL = 777,
|
||||
DEVILATTACK = 797,
|
||||
DEVILPAIN = 809,
|
||||
DEVILDIE = 814,
|
||||
DEVILDEAD = 820,
|
||||
TILES004_START = 980,
|
||||
MINOTAUR = 981,
|
||||
MINOTAURATTACK = 1001,
|
||||
MINOTAURPAIN = 1012,
|
||||
MINOTAURDIE = 1017,
|
||||
MINOTAURDEAD = 1027,
|
||||
};
|
||||
|
||||
|
||||
extern short KNIFEREADY;
|
||||
extern short KNIFEATTACK;
|
||||
extern short RFIST;
|
||||
extern short SWORDATTACK;
|
||||
extern short MORNINGSTAR;
|
||||
extern short BOWREADY;
|
||||
extern short BOWREADYEND;
|
||||
extern short BOWWALK;
|
||||
extern short KNIFEATTACK2;
|
||||
extern short SWORDPULL;
|
||||
extern short SWORDATTACK2;
|
||||
extern short MORNINGATTACK2;
|
||||
extern short MUMEDUSA;
|
||||
extern short MUTWOHANDS;
|
||||
extern short BMUTWOHANDS;
|
||||
extern short GOBSWORDPULL;
|
||||
extern short GOBSWORDATTACK;
|
||||
extern short GOBSWORDATTACK2;
|
||||
extern short BIGAXEATTACK;
|
||||
extern short BIGAXEATTACK2;
|
||||
extern short BIGAXEDRAW;
|
||||
extern short HALBERDATTACK1;
|
||||
extern short HALBERDATTACK2;
|
||||
extern short HALBERDDRAW;
|
||||
extern short PIKEDRAW;
|
||||
extern short PIKEATTACK1;
|
||||
extern short EXCALATTACK1;
|
||||
extern short EXCALATTACK2;
|
||||
extern short EXCALDRAW;
|
||||
extern short BIGAXEDRAW9;
|
||||
extern short BIGAXEDRAW10;
|
||||
extern short GEARS2START;
|
||||
extern short HORNEDSKULL;
|
||||
extern short THEFONT;
|
||||
extern short CRYSTALSTAFF;
|
||||
extern short TORCH;
|
||||
extern short WEAPON1;
|
||||
extern short WEAPON1A;
|
||||
extern short AMULETOFTHEMIST;
|
||||
extern short WEAPON2;
|
||||
extern short BRASSKEY;
|
||||
extern short BLACKKEY;
|
||||
extern short GLASSKEY;
|
||||
extern short IVORYKEY;
|
||||
extern short NEWCHUNK;
|
||||
extern short BOWLOFFIRE;
|
||||
extern short SPAWNFIREBALL;
|
||||
extern short PENTAGRAM;
|
||||
extern short THEHORN;
|
||||
extern short BOW;
|
||||
extern short SWINGGATE3;
|
||||
extern short PLATEARMOR;
|
||||
extern short HELMET;
|
||||
extern short CHAINMAIL;
|
||||
extern short SCROLLSCARE;
|
||||
extern short SCROLLNUKE;
|
||||
extern short SCROLLFLY;
|
||||
extern short SCROLLFIREBALL;
|
||||
extern short SCROLLFREEZE;
|
||||
extern short SCROLLNIGHT;
|
||||
extern short SCROLLMAGIC;
|
||||
extern short SCROLLOPEN;
|
||||
extern short LEATHERARMOR;
|
||||
extern short QUIVER;
|
||||
extern short SWINGGATE4;
|
||||
extern short SWINGGATE5;
|
||||
extern short SMOKEFX;
|
||||
extern short STANDINTORCH;
|
||||
extern short PENTADOOR3;
|
||||
extern short PENTADOOR4;
|
||||
extern short PENTADOOR5;
|
||||
extern short PENTADOOR6;
|
||||
extern short PENTADOOR7;
|
||||
extern short SCARY;
|
||||
extern short FISH;
|
||||
extern short LEVERUP;
|
||||
extern short LEVERDOWN;
|
||||
extern short SPAWNJAVLIN;
|
||||
extern short RAT;
|
||||
extern short GUARDIAN;
|
||||
extern short GUARDIANATTACK;
|
||||
extern short DART;
|
||||
extern short WEAPON4;
|
||||
extern short WEAPON6;
|
||||
extern short WEAPON5;
|
||||
extern short WEAPON5B;
|
||||
extern short THROWHALBERD;
|
||||
extern short WEAPON7;
|
||||
extern short THROWPIKE;
|
||||
extern short EXPLO2;
|
||||
extern short SHATTERVASE;
|
||||
extern short SHATTERVASE2;
|
||||
extern short SHATTERVASE3;
|
||||
extern short HANGMAN;
|
||||
extern short SKELETON;
|
||||
extern short SKELETONATTACK;
|
||||
extern short SKELETONSKULL;
|
||||
extern short SKELETONUP;
|
||||
extern short SKELETONDIE;
|
||||
extern short SKELETONDEAD;
|
||||
extern short BONECHUNK1;
|
||||
extern short BONECHUNKEND;
|
||||
extern short PIKEATTACK2;
|
||||
extern short GOBWEAPON;
|
||||
extern short SFLASKBLUE;
|
||||
extern short SFLASKGREEN;
|
||||
extern short SFLASKOCHRE;
|
||||
extern short SFLASKRED;
|
||||
extern short SFLASKTAN;
|
||||
extern short SFLASKBLACK;
|
||||
extern short SHEALTHFONT;
|
||||
extern short SSCOREFONT;
|
||||
extern short SPOTIONFONT;
|
||||
extern short SPOTIONBACKPIC;
|
||||
extern short SPOTIONARROW;
|
||||
extern short SSPELLBOOKBLANK;
|
||||
extern short SSPELLBOOK2;
|
||||
extern short SSPELLBOOK3;
|
||||
extern short SSPELLBOOK4;
|
||||
extern short SSPELLBOOK5;
|
||||
extern short SSPELLBOOK6;
|
||||
extern short SSPELLBOOK7;
|
||||
extern short SSPELLBOOK8;
|
||||
extern short SARROWS;
|
||||
extern short SPLAYERLVL;
|
||||
extern short SSTATUSBAR;
|
||||
extern short SKEYBLANK;
|
||||
extern short SKEYBRASS;
|
||||
extern short SKEYBLACK;
|
||||
extern short SKEYGLASS;
|
||||
extern short SKEYIVORY;
|
||||
extern short SHEALTHBACK;
|
||||
extern short SSCOREBACKPIC;
|
||||
extern short SNDEFFECT;
|
||||
extern short SNDLOOP;
|
||||
extern short SNDLOOPOFF;
|
||||
extern short BROWNCHUNKSTART;
|
||||
extern short GREYCHUNKSTART;
|
||||
extern short REDCHUNKSTART;
|
||||
extern short GREENCHUNKSTART;
|
||||
extern short TANCHUNKSTART;
|
||||
extern short WILLOW;
|
||||
extern short SPIKES;
|
||||
extern short STHEFLAG;
|
||||
extern short GRONHALATTACK;
|
||||
extern short GRONHALATTACKEND;
|
||||
extern short GROLHALREADY;
|
||||
extern short GRONHALREADYEND;
|
||||
extern short GRONHAL;
|
||||
extern short GRONHALPAIN;
|
||||
extern short GRONHALDIE;
|
||||
extern short GRONSWATTACK;
|
||||
extern short GRONSW;
|
||||
extern short GRONSWPAIN;
|
||||
extern short GRONSWDIE;
|
||||
extern short GRONMUATTACK;
|
||||
extern short GRONDIE;
|
||||
extern short GRONDEAD;
|
||||
extern short GRONMU;
|
||||
extern short GRONMUPAIN;
|
||||
extern short GRONMUDIE;
|
||||
extern short GRONSHIELD;
|
||||
extern short SHIELD;
|
||||
|
||||
END_WH_NS
|
90
source/games/whaven/src/player.h
Normal file
90
source/games/whaven/src/player.h
Normal file
|
@ -0,0 +1,90 @@
|
|||
#pragma once
|
||||
|
||||
BEGIN_WH_NS
|
||||
|
||||
struct PLAYER {
|
||||
|
||||
//Input pInput;
|
||||
int x,y,z;
|
||||
float ang;
|
||||
float horiz, jumphoriz;
|
||||
int height;
|
||||
int hvel;
|
||||
short sector;
|
||||
short oldsector;
|
||||
short spritenum;
|
||||
boolean keytoggle;
|
||||
int flags;
|
||||
int weapon[MAXWEAPONS], preenchantedweapon[MAXWEAPONS];
|
||||
int ammo[MAXWEAPONS], preenchantedammo[MAXWEAPONS];
|
||||
int orbammo[MAXNUMORBS];
|
||||
int treasure[MAXTREASURES];
|
||||
int orbactive[MAXNUMORBS];
|
||||
int orb[MAXNUMORBS];
|
||||
int potion[MAXPOTIONS];
|
||||
int lvl;
|
||||
int score;
|
||||
int health;
|
||||
int maxhealth;
|
||||
int armor;
|
||||
int armortype;
|
||||
int onsomething;
|
||||
int fallz;
|
||||
|
||||
boolean dead;
|
||||
short turnAround;
|
||||
|
||||
int shadowtime;
|
||||
int helmettime;
|
||||
int scoretime;
|
||||
int vampiretime;
|
||||
|
||||
int selectedgun;
|
||||
int currweapon;
|
||||
int currweapontics;
|
||||
int currweaponanim;
|
||||
int currweaponframe;
|
||||
int currweaponfired;
|
||||
int currweaponattackstyle;
|
||||
int currweaponflip;
|
||||
int hasshot;
|
||||
|
||||
int currentpotion;
|
||||
int strongtime, manatime, invisibletime=-1;
|
||||
|
||||
int orbshot;
|
||||
int spellbooktics;
|
||||
int spellbook;
|
||||
int spellbookframe;
|
||||
int spellbookflip;
|
||||
int nightglowtime;
|
||||
|
||||
int showbook;
|
||||
int showbooktype;
|
||||
int showbookflip;
|
||||
int showbookanim;
|
||||
int currentorb;
|
||||
|
||||
int spelltime;
|
||||
|
||||
int shieldpoints;
|
||||
int shieldtype;
|
||||
|
||||
int poisoned;
|
||||
int poisontime;
|
||||
int shockme = -1;
|
||||
int invincibletime;
|
||||
|
||||
int spiked;
|
||||
int spiketics;
|
||||
int spikeframe;
|
||||
int currspikeframe;
|
||||
boolean godMode;
|
||||
boolean noclip;
|
||||
|
||||
// no copy assignments for this one!
|
||||
PLAYER(const PLAYER&) = delete;
|
||||
PLAYER& operator=(const PLAYER&) = delete;
|
||||
};
|
||||
|
||||
END_WH_NS
|
17
source/games/whaven/src/wh.h
Normal file
17
source/games/whaven/src/wh.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
#include "build.h"
|
||||
|
||||
BEGIN_WH_NS
|
||||
|
||||
using SPRITE = spritetype;
|
||||
using boolean = bool;
|
||||
|
||||
END_WH_NS
|
||||
|
||||
#include "globals.h"
|
||||
#include "names.h"
|
||||
#include "wh1names.h"
|
||||
#include "wh2names.h"
|
||||
#include "player.h"
|
||||
#include "ai.h"
|
266
source/games/whaven/src/wh1names.h
Normal file
266
source/games/whaven/src/wh1names.h
Normal file
|
@ -0,0 +1,266 @@
|
|||
#pragma once
|
||||
|
||||
BEGIN_WH_NS
|
||||
|
||||
enum WH1Names {
|
||||
|
||||
SKY8 = 179,
|
||||
SKY9 = 180,
|
||||
SKY10 = 181,
|
||||
FIREBALL = 314,
|
||||
LFIRE = 345,
|
||||
SFIRE = 353,
|
||||
WATERSPLASH = 438,
|
||||
LASTWATERSPLASH = 446,
|
||||
GLOW = 451,
|
||||
COMPASS = 499,
|
||||
MACEWITHSPIKES = 540,
|
||||
MACE = 541,
|
||||
KNIFE = 542,
|
||||
SWORD1 = 543,
|
||||
SWORD2 = 544,
|
||||
GYSER = 680,
|
||||
FATWITCH = 821,
|
||||
FATWITCHATTACK = 841,
|
||||
FATWITCHDIE = 846,
|
||||
FATWITCHDEAD = 852,
|
||||
SWAPCHILL = 853,
|
||||
SWAMPSTAND = 859,
|
||||
SWAMPTHING = 860,
|
||||
SWAMPATTACK = 862,
|
||||
FREDSTAND = 866,
|
||||
FRED = 871,
|
||||
FREDATTACK = 891,
|
||||
FREDPAIN = 906,
|
||||
FREDDIE = 911,
|
||||
FREDDEAD = 916,
|
||||
GOBLINSTAND = 917,
|
||||
GOBLIN = 922,
|
||||
GOBLINCHILL = 942,
|
||||
GOBLINSURPRISE = 946,
|
||||
GOBLINATTACK = 952,
|
||||
GOBLINPAIN = 963,
|
||||
GOBLINDIE = 968,
|
||||
GOBLINDEAD = 977,
|
||||
SKULLY = 1028,
|
||||
SKULLYATTACK = 1048,
|
||||
SKULLYDIE = 1059,
|
||||
SKULLYDEAD = 1069,
|
||||
SPIDER = 1070,
|
||||
SPIDERDIE = 1110,
|
||||
SPIDERDEAD = 1117,
|
||||
JUDYSIT = 1118,
|
||||
JUDYSTAND = 1119,
|
||||
JUDY = 1123,
|
||||
JUDYATTACK1 = 1143,
|
||||
JUDYATTACK2 = 1150,
|
||||
JUDYDIE = 1159,
|
||||
JUDYDEAD = 1163,
|
||||
DRAGONATTACK = 1164,
|
||||
DRAGONDIE = 1187,
|
||||
DRAGONDEAD = 1200,
|
||||
DRAGON = 1201,
|
||||
DRAGONATTACK2 = 1207,
|
||||
DOG = 1213,
|
||||
TILES005_START = 1221,
|
||||
SVGAMENU2 = 1990,
|
||||
SVGAMENU = 1991,
|
||||
GASCLOUD = 2021,
|
||||
POISONICON = 2373,
|
||||
SKULLYCHAR = 2433,
|
||||
DEVILCHAR = 2438,
|
||||
DRAGONCHAR = 2443,
|
||||
FATWITCHCHAR = 2448,
|
||||
GOBLINCHAR = 2453,
|
||||
JUDYCHAR = 2458,
|
||||
KOBOLDCHAR = 2463,
|
||||
MINOTAURCHAR = 2468,
|
||||
SKELETONCHAR = 2473,
|
||||
GRONCHAR = 2483,
|
||||
GUARDIANCHAR = 2498,
|
||||
BETAPAGE = 2691,
|
||||
STONEHENGE = 2698,
|
||||
SVGAVICTORYA1 = 2699,
|
||||
SVGAVICTORYA2 = 2700,
|
||||
VICTORYA = 2703,
|
||||
VICTORYB = 2704,
|
||||
SVGAVICTORYB1 = 2705,
|
||||
SVGAVICTORYB2 = 2706,
|
||||
SVB1 = 2707,
|
||||
SVB2 = 2708,
|
||||
SVBR1 = 2709,
|
||||
SVBR2 = 2710,
|
||||
VICTORYC = 2714,
|
||||
SVP1 = 2715,
|
||||
SVP2 = 2716,
|
||||
SVR1 = 2717,
|
||||
SVR2 = 2718,
|
||||
|
||||
|
||||
WH1KNIFEREADY = 1249,
|
||||
WH1KNIFEATTACK = 1261,
|
||||
WH1RFIST = 1268,
|
||||
WH1SWORDATTACK = 1291,
|
||||
WH1MORNINGSTAR = 1306,
|
||||
WH1BOWREADY = 1313,
|
||||
WH1BOWREADYEND = 1319,
|
||||
WH1BOWWALK = 1323,
|
||||
WH1KNIFEATTACK2 = 1329,
|
||||
WH1SWORDPULL = 1333,
|
||||
WH1SWORDATTACK2 = 1340,
|
||||
WH1MORNINGATTACK2 = 1348,
|
||||
WH1MUMEDUSA = 1353,
|
||||
WH1MUTWOHANDS = 1363,
|
||||
WH1BMUTWOHANDS = 1378,
|
||||
WH1GOBSWORDPULL = 1390,
|
||||
WH1GOBSWORDATTACK = 1397,
|
||||
WH1GOBSWORDATTACK2 = 1404,
|
||||
WH1BIGAXEATTACK = 1411,
|
||||
WH1BIGAXEATTACK2 = 1421,
|
||||
WH1BIGAXEDRAW = 1429,
|
||||
WH1HALBERDATTACK1 = 1438,
|
||||
WH1HALBERDATTACK2 = 1443,
|
||||
WH1HALBERDDRAW = 1447,
|
||||
WH1PIKEDRAW = 1451,
|
||||
WH1PIKEATTACK1 = 1457,
|
||||
WH1EXCALATTACK1 = 1463,
|
||||
WH1EXCALATTACK2 = 1473,
|
||||
WH1EXCALDRAW = 1481,
|
||||
WH1BIGAXEDRAW9 = 1494,
|
||||
WH1BIGAXEDRAW10 = 1495,
|
||||
WH1GEARS2START = 1498,
|
||||
WH1HORNEDSKULL = 1503,
|
||||
WH1THEFONT = 1511,
|
||||
WH1CRYSTALSTAFF = 1551,
|
||||
WH1TORCH = 1554,
|
||||
WH1WEAPON1 = 1567,
|
||||
WH1WEAPON1A = 1571,
|
||||
WH1AMULETOFTHEMIST = 1575,
|
||||
WH1WEAPON2 = 1583,
|
||||
WH1BRASSKEY = 1624,
|
||||
WH1BLACKKEY = 1632,
|
||||
WH1GLASSKEY = 1640,
|
||||
WH1IVORYKEY = 1648,
|
||||
WH1NEWCHUNK = 1664,
|
||||
WH1BOWLOFFIRE = 1705,
|
||||
WH1SPAWNFIREBALL = 1718,
|
||||
WH1PENTAGRAM = 1760,
|
||||
WH1THEHORN = 1768,
|
||||
WH1BOW = 1776,
|
||||
WH1SWINGGATE3 = 1789,
|
||||
WH1PLATEARMOR = 1794,
|
||||
WH1HELMET = 1802,
|
||||
WH1CHAINMAIL = 1810,
|
||||
WH1SCROLLSCARE = 1818,
|
||||
WH1SCROLLNUKE = 1826,
|
||||
WH1SCROLLFLY = 1834,
|
||||
WH1SCROLLFIREBALL = 1842,
|
||||
WH1SCROLLFREEZE = 1850,
|
||||
WH1SCROLLNIGHT = 1858,
|
||||
WH1SCROLLMAGIC = 1866,
|
||||
WH1SCROLLOPEN = 1874,
|
||||
WH1LEATHERARMOR = 1882,
|
||||
WH1QUIVER = 1890,
|
||||
WH1SWINGGATE4 = 1898,
|
||||
WH1SWINGGATE5 = 1899,
|
||||
WH1SMOKEFX = 1904,
|
||||
WH1STANDINTORCH = 1908,
|
||||
WH1PENTADOOR3 = 1927,
|
||||
WH1PENTADOOR4 = 1928,
|
||||
WH1PENTADOOR5 = 1929,
|
||||
WH1PENTADOOR6 = 1930,
|
||||
WH1PENTADOOR7 = 1931,
|
||||
WH1SCARY = 1933,
|
||||
WH1FISH = 1945,
|
||||
WH1LEVERUP = 1947,
|
||||
WH1LEVERDOWN = 1949,
|
||||
WH1SPAWNJAVLIN = 1958,
|
||||
WH1RAT = 1962,
|
||||
WH1GUARDIAN = 1994,
|
||||
WH1GUARDIANATTACK = 2002,
|
||||
WH1DART = 2010,
|
||||
WH1WEAPON4 = 2027,
|
||||
WH1WEAPON6 = 2039,
|
||||
WH1WEAPON5 = 2047,
|
||||
WH1WEAPON5B = 2055,
|
||||
WH1THROWHALBERD = 2066,
|
||||
WH1WEAPON7 = 2067,
|
||||
WH1THROWPIKE = 2071,
|
||||
WH1EXPLO2 = 2096,
|
||||
WH1SHATTERVASE = 2124,
|
||||
WH1SHATTERVASE2 = 2131,
|
||||
WH1SHATTERVASE3 = 2138,
|
||||
WH1HANGMAN = 2145,
|
||||
WH1SKELETON = 2156,
|
||||
WH1SKELETONATTACK = 2181,
|
||||
WH1SKELETONSKULL = 2186,
|
||||
WH1SKELETONUP = 2191,
|
||||
WH1SKELETONDIE = 2192,
|
||||
WH1SKELETONDEAD = 2198,
|
||||
WH1BONECHUNK1 = 2199,
|
||||
WH1BONECHUNKEND = 2208,
|
||||
WH1PIKEATTACK2 = 2209,
|
||||
WH1GOBWEAPON = 2218,
|
||||
WH1SFLASKBLUE = 2240,
|
||||
WH1SFLASKGREEN = 2241,
|
||||
WH1SFLASKOCHRE = 2242,
|
||||
WH1SFLASKRED = 2243,
|
||||
WH1SFLASKTAN = 2244,
|
||||
WH1SFLASKBLACK = 2245,
|
||||
WH1SHEALTHFONT = 2246,
|
||||
WH1SSCOREFONT = 2256,
|
||||
WH1SPOTIONFONT = 2266,
|
||||
WH1SPOTIONBACKPIC = 2280,
|
||||
WH1SPOTIONARROW = 2281,
|
||||
WH1SSPELLBOOKBLANK = 2286,
|
||||
WH1SSPELLBOOK2 = 2294,
|
||||
WH1SSPELLBOOK3 = 2302,
|
||||
WH1SSPELLBOOK4 = 2310,
|
||||
WH1SSPELLBOOK5 = 2317,
|
||||
WH1SSPELLBOOK6 = 2324,
|
||||
WH1SSPELLBOOK7 = 2332,
|
||||
WH1SSPELLBOOK8 = 2340,
|
||||
WH1SARROWS = 2348,
|
||||
WH1SPLAYERLVL = 2349,
|
||||
WH1SSTATUSBAR = 2358,
|
||||
WH1SKEYBLANK = 2359,
|
||||
WH1SKEYBRASS = 2360,
|
||||
WH1SKEYBLACK = 2361,
|
||||
WH1SKEYGLASS = 2362,
|
||||
WH1SKEYIVORY = 2363,
|
||||
WH1SHEALTHBACK = 2365,
|
||||
WH1SSCOREBACKPIC = 2368,
|
||||
WH1SNDEFFECT = 2369,
|
||||
WH1SNDLOOP = 2370,
|
||||
WH1SNDLOOPOFF = 2371,
|
||||
WH1BROWNCHUNKSTART = 2387,
|
||||
WH1GREYCHUNKSTART = 2395,
|
||||
WH1REDCHUNKSTART = 2403,
|
||||
WH1GREENCHUNKSTART = 2411,
|
||||
WH1TANCHUNKSTART = 2419,
|
||||
WH1WILLOW = 2427,
|
||||
WH1SPIKES = 2488,
|
||||
WH1STHEFLAG = 2491,
|
||||
WH1GRONHALATTACK = 2504,
|
||||
WH1GRONHALATTACKEND = 2508,
|
||||
WH1GROLHALREADY = 2509,
|
||||
WH1GRONHALREADYEND = 2510,
|
||||
WH1GRONHAL = 2539,
|
||||
WH1GRONHALPAIN = 2559,
|
||||
WH1GRONHALDIE = 2560,
|
||||
WH1GRONSWATTACK = 2561,
|
||||
WH1GRONSW = 2581,
|
||||
WH1GRONSWPAIN = 2601,
|
||||
WH1GRONSWDIE = 2602,
|
||||
WH1GRONMUATTACK = 2603,
|
||||
WH1GRONDIE = 2633,
|
||||
WH1GRONDEAD = 2639,
|
||||
WH1GRONMU = 2640,
|
||||
WH1GRONMUPAIN = 2660,
|
||||
WH1GRONMUDIE = 2661,
|
||||
WH1GRONSHIELD = 2680,
|
||||
WH1SHIELD = 2684,
|
||||
|
||||
};
|
||||
|
||||
END_WH_NS
|
389
source/games/whaven/src/wh2names.h
Normal file
389
source/games/whaven/src/wh2names.h
Normal file
|
@ -0,0 +1,389 @@
|
|||
#include "ns.h"
|
||||
|
||||
BEGIN_WH_NS
|
||||
|
||||
enum WH2Names {
|
||||
|
||||
STAINQ = 180,
|
||||
FLOORMIRROR = 182,
|
||||
STARMAP = 208,
|
||||
BLOODSPLAT1 = 212,
|
||||
BLOODSPLAT1END = 222,
|
||||
BLOODSPLAT2 = 223,
|
||||
BLOODSPLAT2END = 228,
|
||||
WEAPON8 = 229,
|
||||
SILVERBAG = 234,
|
||||
GOLDBAG = 235,
|
||||
GOLDBAG2 = 236,
|
||||
GOLDCOINS = 237,
|
||||
GOLDCOINS2 = 238,
|
||||
SILVERCOINS = 239,
|
||||
WALLPIKE = 356,
|
||||
WALLSWORD = 357,
|
||||
WALLBOW = 358,
|
||||
WALLAXE = 359,
|
||||
STAINTRIANGLE = 410,
|
||||
STAINFLOWER = 411,
|
||||
STAINTHIN = 412,
|
||||
PATROLPOINT = 447,
|
||||
CONE = 449,
|
||||
STAINCIRCLE = 451,
|
||||
STAINCIRCLEBREAK = 452,
|
||||
STAINCIRCLEEND = 457,
|
||||
STAINHEAD = 498,
|
||||
STAINSNAKE = 499,
|
||||
SKULLPULLCHAIN1 = 539,
|
||||
GONZOSHIELD = 540,
|
||||
SKULLPULLCHAIN3 = 541,
|
||||
SPARKBALL = 602,
|
||||
WEAPON3A = 670,
|
||||
SLIMESPLASH = 821,
|
||||
LASTSLIMESPLASH = 827,
|
||||
DAFONT = 864,
|
||||
ZFIRE = 905,
|
||||
IMP = 922,
|
||||
IMPATTACK = 952,
|
||||
IMPDIE = 958,
|
||||
IMPPAIN = 959,
|
||||
IMPDEAD = 967,
|
||||
THEMAINMENU = 1028,
|
||||
THEMAINMENUWITH = 1029,
|
||||
THENEWGAME = 1030,
|
||||
THELOADSAVE = 1031,
|
||||
THEOPTIONS = 1032,
|
||||
THEHELP = 1033,
|
||||
THEQUIT = 1034,
|
||||
ZCREDITS = 1035,
|
||||
ZWEAPON = 1036,
|
||||
ZSPELL = 1037,
|
||||
ZKEN = 1038,
|
||||
ZCREDITS2 = 1039,
|
||||
ZMOVE = 1040,
|
||||
ZMOVE2 = 1041,
|
||||
ZPOTION = 1042,
|
||||
ZCREDITS3 = 1043,
|
||||
ZARTIST = 1044,
|
||||
ZSAVE = 1045,
|
||||
ZLOAD = 1046,
|
||||
ZGOREPG = 1047,
|
||||
VMAINBLANK = 1048,
|
||||
VMAIN = 1049,
|
||||
VNEW = 1050,
|
||||
VCREDIT1 = 1055,
|
||||
DALOAD = 1065,
|
||||
DASAVE = 1066,
|
||||
ZLOADSAVE = 1067,
|
||||
ZSURE = 1068,
|
||||
THEORDER = 1069,
|
||||
STHEORDER = 1070,
|
||||
ZOPS = 1072,
|
||||
DASOUND = 1073,
|
||||
DAGAMEPLAY = 1074,
|
||||
DACONTROLS = 1075,
|
||||
DASLIDER = 1076,
|
||||
ZCDPLAYER = 1077,
|
||||
STAINGLASS1 = 1079,
|
||||
STAINGLASS2 = 1086,
|
||||
STAINGLASS3 = 1093,
|
||||
STAINGLASS4 = 1100,
|
||||
STAINGLASS5 = 1107,
|
||||
STAINGLASS6 = 1114,
|
||||
STAINGLASS7 = 1121,
|
||||
STAINGLASS8 = 1128,
|
||||
STAINGLASS9 = 1135,
|
||||
CDMUVOL = 1142,
|
||||
REDSHUFFLE = 1164,
|
||||
ZZGORE = 1182,
|
||||
ZZBLOOD = 1183,
|
||||
ZZDIFFICULTY = 1184,
|
||||
ZCONTROLS = 1185,
|
||||
ZZSLIDER = 1198,
|
||||
ZZON = 1199,
|
||||
ZZOFF = 1200,
|
||||
ZZONLITE = 1201,
|
||||
ZZOFFLITE = 1202,
|
||||
EXPLOSTART = 1203,
|
||||
EXPLOEND = 1215,
|
||||
ARROWFLAME = 1216,
|
||||
STAINSCENE = 1658,
|
||||
STAINSKULL = 1660,
|
||||
STAINGARGO = 1661,
|
||||
STAINMU = 1662,
|
||||
SHARD = 1687,
|
||||
DEMON = 1935,
|
||||
GONZOBSHIELD = 2432,
|
||||
GONZOCSHIELD = 2439,
|
||||
GONZOGSHIELD = 2446,
|
||||
STONEGONZOCHM = 2483,
|
||||
STONEGONZOGSH = 2484,
|
||||
STONEGRONDOVAL = 2485,
|
||||
STONEGONZOBSW = 2486,
|
||||
STONEGONZOBSH = 2497,
|
||||
STONEGONZOBSW2 = 2498,
|
||||
SBLUEKNIGHTS1 = 2705,
|
||||
SBLUEKNIGHTS2 = 2706,
|
||||
SBROWNKNIGHTS1 = 2707,
|
||||
SBROWNKNIGHTS2 = 2708,
|
||||
SPURPLEKNIGHTS1 = 2713,
|
||||
SPURPLEKNIGHTS2 = 2714,
|
||||
SREDKNIGHTS1 = 2715,
|
||||
SREDKNIGHTS2 = 2716,
|
||||
NEWGUYBOW = 2750,
|
||||
NEWGUYPUNCH = 2780,
|
||||
GONZOBSHPAIN = 3006,
|
||||
GONZOBSHDEAD = 3016,
|
||||
GONZOCSW = 3017,
|
||||
GONZOCSWAT = 3047,
|
||||
GONZOCSWPAIN = 3077,
|
||||
GONZOCSWDEAD = 3089,
|
||||
KURTSTAND = 3090,
|
||||
KURTKNEE = 3095,
|
||||
KURTJUMP = 3100,
|
||||
KURTAT = 3110,
|
||||
GONZOCHMAT = 3120,
|
||||
KURTPUNCH = 3140,
|
||||
KURTREADY = 3160,
|
||||
NEWGUY = 3170,
|
||||
NEWGUYMACE = 3200,
|
||||
NEWGUYDIE = 3230,
|
||||
NEWGUYDEAD = 3239,
|
||||
NEWGUYSTAND = 3243,
|
||||
NEWGUYKNEE = 3248,
|
||||
GONZOCSHPAIN = 3268,
|
||||
GONZOCSHDEAD = 3278,
|
||||
GONZOGSW = 3279,
|
||||
GONZOGSWAT = 3309,
|
||||
GONZOGSWPAIN = 3339,
|
||||
GONZOGSWDEAD = 3351,
|
||||
GONZOGHM = 3352,
|
||||
GONZOGHMAT = 3382,
|
||||
GONZOGHMPAIN = 3412,
|
||||
GONZOGHMDEAD = 3425,
|
||||
GONZOGSH = 3426,
|
||||
GONZOGSHAT = 3474,
|
||||
GONZOGSHPAIN = 3530,
|
||||
GONZOGSHDEAD = 3540,
|
||||
KATIE = 3541,
|
||||
KATIEASS = 3561,
|
||||
KATIEAT = 3566,
|
||||
KATIEPAIN = 3583,
|
||||
KATIEDEAD = 3591,
|
||||
NEWGUYMACEMU = 3592,
|
||||
NEWGUYCAST = 3602,
|
||||
NEWGUYPAIN = 3612,
|
||||
GONZOHMJUMP = 3630,
|
||||
GONZOHMJUMPEND = 3635,
|
||||
GONZOSHJUMP = 3636,
|
||||
GONZOSHJUMPEND = 3641,
|
||||
ZFLASHER1 = 3650,
|
||||
ZFLASHER2 = 3662,
|
||||
SFLASH1 = 3680,
|
||||
SFLASH2 = 3692,
|
||||
SFLASH4 = 3704,
|
||||
SFLASH3 = 3707,
|
||||
VLOAD = 3711,
|
||||
VSAVE = 3712,
|
||||
VSOUNDA = 3713,
|
||||
VSOUNDB = 3714,
|
||||
VGOREA = 3715,
|
||||
VGOREB = 3716,
|
||||
ZPIKEREADY = 3743,
|
||||
ZPIKE = 3748,
|
||||
ZPIKEATTACK = 3752,
|
||||
ZPIKEATTACK2 = 3758,
|
||||
ZBOWREADY = 3767,
|
||||
ZBOWREADYEND = 3774,
|
||||
ZBOWCOCK = 3775,
|
||||
ZBOWWALK = 3776,
|
||||
ZBOWATTACK = 3781,
|
||||
ZKNIFEREADY = 3786,
|
||||
ZKNIFEATTACK = 3798,
|
||||
ZKNIFEATTACK2 = 3804,
|
||||
ZAXEREADY = 3808,
|
||||
ZAXEATTACK = 3817,
|
||||
ZAXEATTACK2 = 3832,
|
||||
ZFREEZE = 3840,
|
||||
ZFIREBALL = 3855,
|
||||
ZLIGHT = 3865,
|
||||
ZSTARATTACK = 3875,
|
||||
ZSTARATTACK2 = 3884,
|
||||
ZTWOHANDREADY = 3888,
|
||||
ZTWOHANDATTACK = 3900,
|
||||
ZTWOHANDATTACK2 = 3915,
|
||||
ZSHORTREADY = 3922,
|
||||
ZSHORTATTACK = 3929,
|
||||
ZSHORTATTACKONE = 3933,
|
||||
ZSHORTATTACK2 = 3939,
|
||||
ZHALBERDREADY = 3946,
|
||||
ZHALBERDATTACK = 3948,
|
||||
ZHALBERDATTACK2 = 3957,
|
||||
ROUNDSHIELD = 3961,
|
||||
|
||||
|
||||
|
||||
WH2KNIFEREADY = 1248,
|
||||
WH2KNIFEATTACK = 1260,
|
||||
WH2RFIST = 1267,
|
||||
WH2SWORDATTACK = 1290,
|
||||
WH2MORNINGSTAR = 1305,
|
||||
WH2BOWREADY = 1312,
|
||||
WH2BOWREADYEND = 1318,
|
||||
WH2BOWWALK = 1322,
|
||||
WH2KNIFEATTACK2 = 1328,
|
||||
WH2SWORDPULL = 1332,
|
||||
WH2SWORDATTACK2 = 1339,
|
||||
WH2MORNINGATTACK2 = 1347,
|
||||
WH2MUMEDUSA = 1352,
|
||||
WH2MUTWOHANDS = 1362,
|
||||
WH2BMUTWOHANDS = 1377,
|
||||
WH2GOBSWORDPULL = 1389,
|
||||
WH2GOBSWORDATTACK = 1396,
|
||||
WH2GOBSWORDATTACK2 = 1403,
|
||||
WH2BIGAXEATTACK = 1410,
|
||||
WH2BIGAXEATTACK2 = 1420,
|
||||
WH2BIGAXEDRAW = 1428,
|
||||
WH2HALBERDATTACK1 = 1437,
|
||||
WH2HALBERDATTACK2 = 1442,
|
||||
WH2HALBERDDRAW = 1446,
|
||||
WH2PIKEDRAW = 1450,
|
||||
WH2PIKEATTACK1 = 1456,
|
||||
WH2EXCALATTACK1 = 1462,
|
||||
WH2EXCALATTACK2 = 1472,
|
||||
WH2EXCALDRAW = 1480,
|
||||
WH2BIGAXEDRAW9 = 1493,
|
||||
WH2BIGAXEDRAW10 = 1494,
|
||||
WH2GEARS2START = 1497,
|
||||
WH2HORNEDSKULL = 1502,
|
||||
WH2THEFONT = 1510,
|
||||
WH2CRYSTALSTAFF = 1550,
|
||||
WH2TORCH = 1553,
|
||||
WH2WEAPON1 = 1566,
|
||||
WH2WEAPON1A = 1570,
|
||||
WH2AMULETOFTHEMIST = 1574,
|
||||
WH2WEAPON2 = 1582,
|
||||
WH2BRASSKEY = 1623,
|
||||
WH2BLACKKEY = 1631,
|
||||
WH2GLASSKEY = 1639,
|
||||
WH2IVORYKEY = 1647,
|
||||
WH2NEWCHUNK = 1663,
|
||||
WH2BOWLOFFIRE = 1704,
|
||||
WH2SPAWNFIREBALL = 1717,
|
||||
WH2PENTAGRAM = 1759,
|
||||
WH2THEHORN = 1767,
|
||||
WH2BOW = 1775,
|
||||
WH2SWINGGATE3 = 1788,
|
||||
WH2PLATEARMOR = 1793,
|
||||
WH2HELMET = 1801,
|
||||
WH2CHAINMAIL = 1809,
|
||||
WH2SCROLLSCARE = 1817,
|
||||
WH2SCROLLNUKE = 1825,
|
||||
WH2SCROLLFLY = 1833,
|
||||
WH2SCROLLFIREBALL = 1841,
|
||||
WH2SCROLLFREEZE = 1849,
|
||||
WH2SCROLLNIGHT = 1857,
|
||||
WH2SCROLLMAGIC = 1865,
|
||||
WH2SCROLLOPEN = 1873,
|
||||
WH2LEATHERARMOR = 1881,
|
||||
WH2QUIVER = 1889,
|
||||
WH2SWINGGATE4 = 1897,
|
||||
WH2SWINGGATE5 = 1898,
|
||||
WH2SMOKEFX = 1903,
|
||||
WH2STANDINTORCH = 1907,
|
||||
WH2PENTADOOR3 = 1926,
|
||||
WH2PENTADOOR4 = 1927,
|
||||
WH2PENTADOOR5 = 1928,
|
||||
WH2PENTADOOR6 = 1929,
|
||||
WH2PENTADOOR7 = 1930,
|
||||
WH2SCARY = 1932,
|
||||
WH2FISH = 1944,
|
||||
WH2LEVERUP = 1946,
|
||||
WH2LEVERDOWN = 1948,
|
||||
WH2SPAWNJAVLIN = 1957,
|
||||
WH2RAT = 1961,
|
||||
WH2GUARDIAN = 1993,
|
||||
WH2GUARDIANATTACK = 2001,
|
||||
WH2DART = 2009,
|
||||
WH2WEAPON4 = 2026,
|
||||
WH2WEAPON6 = 2038,
|
||||
WH2WEAPON5 = 2046,
|
||||
WH2WEAPON5B = 2054,
|
||||
WH2THROWHALBERD = 2065,
|
||||
WH2WEAPON7 = 2066,
|
||||
WH2THROWPIKE = 2070,
|
||||
WH2EXPLO2 = 2095,
|
||||
WH2SHATTERVASE = 2123,
|
||||
WH2SHATTERVASE2 = 2130,
|
||||
WH2SHATTERVASE3 = 2137,
|
||||
WH2HANGMAN = 2144,
|
||||
WH2SKELETON = 2155,
|
||||
WH2SKELETONATTACK = 2180,
|
||||
WH2SKELETONSKULL = 2185,
|
||||
WH2SKELETONUP = 2190,
|
||||
WH2SKELETONDIE = 2191,
|
||||
WH2SKELETONDEAD = 2197,
|
||||
WH2BONECHUNK1 = 2198,
|
||||
WH2BONECHUNKEND = 2207,
|
||||
WH2PIKEATTACK2 = 2208,
|
||||
WH2GOBWEAPON = 2217,
|
||||
WH2SFLASKBLUE = 2239,
|
||||
WH2SFLASKGREEN = 2240,
|
||||
WH2SFLASKOCHRE = 2241,
|
||||
WH2SFLASKRED = 2242,
|
||||
WH2SFLASKTAN = 2243,
|
||||
WH2SFLASKBLACK = 2244,
|
||||
WH2SHEALTHFONT = 2245,
|
||||
WH2SSCOREFONT = 2255,
|
||||
WH2SPOTIONFONT = 2265,
|
||||
WH2SPOTIONBACKPIC = 2279,
|
||||
WH2SPOTIONARROW = 2280,
|
||||
WH2SSPELLBOOKBLANK = 2285,
|
||||
WH2SSPELLBOOK2 = 2293,
|
||||
WH2SSPELLBOOK3 = 2301,
|
||||
WH2SSPELLBOOK4 = 2309,
|
||||
WH2SSPELLBOOK5 = 2316,
|
||||
WH2SSPELLBOOK6 = 2323,
|
||||
WH2SSPELLBOOK7 = 2331,
|
||||
WH2SSPELLBOOK8 = 2339,
|
||||
WH2SARROWS = 2347,
|
||||
WH2SPLAYERLVL = 2348,
|
||||
WH2SSTATUSBAR = 2357,
|
||||
WH2SKEYBLANK = 2358,
|
||||
WH2SKEYBRASS = 2359,
|
||||
WH2SKEYBLACK = 2360,
|
||||
WH2SKEYGLASS = 2361,
|
||||
WH2SKEYIVORY = 2362,
|
||||
WH2SHEALTHBACK = 2364,
|
||||
WH2SSCOREBACKPIC = 2367,
|
||||
WH2SNDEFFECT = 2368,
|
||||
WH2SNDLOOP = 2369,
|
||||
WH2SNDLOOPOFF = 2370,
|
||||
WH2BROWNCHUNKSTART = 2386,
|
||||
WH2GREYCHUNKSTART = 2394,
|
||||
WH2REDCHUNKSTART = 2402,
|
||||
WH2GREENCHUNKSTART = 2410,
|
||||
WH2TANCHUNKSTART = 2418,
|
||||
WH2WILLOW = 2426,
|
||||
WH2SPIKES = 2487,
|
||||
WH2STHEFLAG = 2490,
|
||||
WH2GRONHALATTACK = 2502,
|
||||
WH2GRONHALATTACKEND = 2506,
|
||||
WH2GROLHALREADY = 2507,
|
||||
WH2GRONHALREADYEND = 2508,
|
||||
WH2GRONHAL = 2537,
|
||||
WH2GRONHALPAIN = 2557,
|
||||
WH2GRONHALDIE = 2558,
|
||||
WH2GRONSWATTACK = 2559,
|
||||
WH2GRONSW = 2579,
|
||||
WH2GRONSWPAIN = 2599,
|
||||
WH2GRONSWDIE = 2600,
|
||||
WH2GRONMUATTACK = 2601,
|
||||
WH2GRONDIE = 2631,
|
||||
WH2GRONDEAD = 2637,
|
||||
WH2GRONMU = 2638,
|
||||
WH2GRONMUPAIN = 2658,
|
||||
WH2GRONMUDIE = 2659,
|
||||
WH2GRONSHIELD = 2678,
|
||||
WH2SHIELD = 2682,
|
||||
};
|
||||
|
||||
END_WH_NS
|
Loading…
Reference in a new issue