2019-06-19 17:27:11 +05:30
|
|
|
/* ScummVM - Graphic Adventure Engine
|
|
|
|
*
|
|
|
|
* ScummVM is the legal property of its developers, whose names
|
|
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
|
|
* file distributed with this source distribution.
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "hdb/hdb.h"
|
|
|
|
|
|
|
|
namespace HDB {
|
|
|
|
|
2019-06-20 02:29:49 +05:30
|
|
|
AIEntity *AI::spawn(AIType type, AIDir dir, int x, int y, char *funcInit, char *funcAction, char *funcUse, AIDir dir2, int level, int value1, int value2, int callInit) {
|
|
|
|
AIEntity *e = new AIEntity;
|
|
|
|
|
|
|
|
e->type = type;
|
|
|
|
e->dir = dir;
|
|
|
|
|
|
|
|
// Set Co-ordinates & Speed
|
|
|
|
e->x = x * kTileWidth;
|
|
|
|
e->tileX = x;
|
|
|
|
e->y = y * kTileHeight;
|
|
|
|
e->tileY = y;
|
|
|
|
e->moveSpeed = kPlayerMoveSpeed; // Default Speed
|
|
|
|
if (!g_hdb->getActionMode()) {
|
|
|
|
e->moveSpeed /= 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Other variables
|
|
|
|
e->dir2 = dir2;
|
|
|
|
if (!level)
|
|
|
|
level = 1;
|
|
|
|
e->level = level;
|
|
|
|
e->value1 = value1;
|
|
|
|
e->value2 = value2;
|
|
|
|
e->animCycle = 2; // Game frames to wait before animating graphic frames
|
|
|
|
e->animDelay = e->animCycle;
|
|
|
|
e->animFrame = 0;
|
|
|
|
|
|
|
|
if (funcInit) {
|
|
|
|
strcpy(e->luaFuncInit, funcInit);
|
|
|
|
}
|
|
|
|
if (funcAction) {
|
|
|
|
strcpy(e->luaFuncAction, funcAction);
|
|
|
|
}
|
|
|
|
if (funcUse) {
|
|
|
|
strcpy(e->luaFuncUse, funcUse);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (e->luaFuncInit[0] == '*')
|
|
|
|
e->luaFuncInit[0] = 0;
|
|
|
|
if (e->luaFuncAction[0] == '*')
|
|
|
|
e->luaFuncAction[0] = 0;
|
|
|
|
if (e->luaFuncUse[0] == '*')
|
|
|
|
e->luaFuncUse[0] = 0;
|
|
|
|
|
2019-06-20 05:24:08 +05:30
|
|
|
e->standdownFrames = e->standupFrames = e->standleftFrames = e->standrightFrames = 0;
|
|
|
|
e->movedownFrames = e->moveupFrames = e->moveleftFrames = e->moverightFrames = 0;
|
|
|
|
e->blinkFrames = 0;
|
2019-06-20 02:29:49 +05:30
|
|
|
|
2019-06-20 05:24:08 +05:30
|
|
|
if (!cacheEntGfx(e, (bool)callInit)) {
|
|
|
|
return NULL;
|
|
|
|
} else {
|
|
|
|
_ents->push_back(e);
|
|
|
|
}
|
2019-06-20 02:29:49 +05:30
|
|
|
|
|
|
|
return e;
|
|
|
|
}
|
|
|
|
|
2019-06-20 05:23:20 +05:30
|
|
|
bool AI::cacheEntGfx(AIEntity *e, bool init) {
|
|
|
|
int i = 0;
|
|
|
|
while (true) {
|
|
|
|
if (aiEntList[i].type == END_AI_TYPES) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Load Gfx for corresponding Entity
|
|
|
|
if (aiEntList[i].type == e->type) {
|
|
|
|
int j = 0;
|
|
|
|
AIStateDef *list = aiEntList[i].stateDef;
|
|
|
|
|
|
|
|
while (list[j].state != STATE_ENDSTATES) {
|
|
|
|
|
|
|
|
Common::Array<const char *> *gfxFiles = g_hdb->_fileMan->findFiles(list[j].name, TYPE_TILE32);
|
|
|
|
uint32 size;
|
|
|
|
|
|
|
|
for (Common::Array<const char *>::iterator it = gfxFiles->begin(); it != gfxFiles->end(); it++) {
|
|
|
|
size = g_hdb->_fileMan->getLength((*it), TYPE_TILE32);
|
|
|
|
|
|
|
|
Tile *gfx = g_hdb->_drawMan->getGfx((*it), size);
|
|
|
|
switch (list[j].state) {
|
|
|
|
case STATE_STANDDOWN:
|
|
|
|
e->standdownGfx[e->standdownFrames] = gfx;
|
|
|
|
e->standdownFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_STANDUP:
|
|
|
|
e->standupGfx[e->standupFrames] = gfx;
|
|
|
|
e->standupFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_STANDLEFT:
|
|
|
|
e->standleftGfx[e->standleftFrames] = gfx;
|
|
|
|
e->standleftFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_STANDRIGHT:
|
|
|
|
e->standrightGfx[e->standrightFrames] = gfx;
|
|
|
|
e->standrightFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_BLINK:
|
|
|
|
e->blinkGfx[e->blinkFrames] = gfx;
|
|
|
|
e->blinkFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_MOVEDOWN:
|
|
|
|
e->movedownGfx[e->movedownFrames] = gfx;
|
|
|
|
e->movedownFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_MOVEUP:
|
|
|
|
e->moveupGfx[e->moveupFrames] = gfx;
|
|
|
|
e->moveupFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_MOVELEFT:
|
|
|
|
e->moveleftGfx[e->moveleftFrames] = gfx;
|
|
|
|
e->moveleftFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_MOVERIGHT:
|
|
|
|
e->moverightGfx[e->moverightFrames] = gfx;
|
|
|
|
e->moverightFrames++;
|
|
|
|
break;
|
|
|
|
|
|
|
|
// Special Player Frames
|
|
|
|
case STATE_PUSHDOWN:
|
|
|
|
pushdownGfx[pushdownFrames] = gfx;
|
|
|
|
pushdownFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_PUSHUP:
|
|
|
|
pushupGfx[pushupFrames] = gfx;
|
|
|
|
pushupFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_PUSHLEFT:
|
|
|
|
pushleftGfx[pushleftFrames] = gfx;
|
|
|
|
pushleftFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_PUSHRIGHT:
|
|
|
|
pushrightGfx[pushrightFrames] = gfx;
|
|
|
|
pushrightFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_GRABUP:
|
|
|
|
getGfx[DIR_UP] = gfx; break;
|
|
|
|
case STATE_GRABDOWN:
|
|
|
|
getGfx[DIR_DOWN] = gfx; break;
|
|
|
|
case STATE_GRABLEFT:
|
|
|
|
getGfx[DIR_LEFT] = gfx; break;
|
|
|
|
case STATE_GRABRIGHT:
|
|
|
|
getGfx[DIR_RIGHT] = gfx; break;
|
|
|
|
|
|
|
|
case STATE_ATK_CLUB_UP:
|
|
|
|
clubUpGfx[clubUpFrames] = gfx;
|
|
|
|
clubUpFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_ATK_CLUB_DOWN:
|
|
|
|
clubDownGfx[clubDownFrames] = gfx;
|
|
|
|
clubDownFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_ATK_CLUB_LEFT:
|
|
|
|
clubLeftGfx[clubLeftFrames] = gfx;
|
|
|
|
clubLeftFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_ATK_CLUB_RIGHT:
|
|
|
|
clubRightGfx[clubRightFrames] = gfx;
|
|
|
|
clubRightFrames++;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case STATE_ATK_STUN_UP:
|
|
|
|
stunUpGfx[stunUpFrames] = gfx;
|
|
|
|
stunUpFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_ATK_STUN_DOWN:
|
|
|
|
stunDownGfx[stunDownFrames] = gfx;
|
|
|
|
stunDownFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_ATK_STUN_LEFT:
|
|
|
|
stunLeftGfx[stunLeftFrames] = gfx;
|
|
|
|
stunLeftFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_ATK_STUN_RIGHT:
|
|
|
|
stunRightGfx[stunRightFrames] = gfx;
|
|
|
|
stunRightFrames++;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case STATE_ATK_SLUG_UP:
|
|
|
|
slugUpGfx[slugUpFrames] = gfx;
|
|
|
|
slugUpFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_ATK_SLUG_DOWN:
|
|
|
|
slugDownGfx[slugDownFrames] = gfx;
|
|
|
|
slugDownFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_ATK_SLUG_LEFT:
|
|
|
|
slugLeftGfx[slugLeftFrames] = gfx;
|
|
|
|
slugLeftFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_ATK_SLUG_RIGHT:
|
|
|
|
slugRightGfx[slugRightFrames] = gfx;
|
|
|
|
slugRightFrames++;
|
|
|
|
break;
|
|
|
|
|
|
|
|
// Maintenance Bot
|
|
|
|
case STATE_USEUP:
|
|
|
|
e->standupGfx[4] = gfx;
|
|
|
|
break;
|
|
|
|
case STATE_USEDOWN:
|
|
|
|
e->standdownGfx[4] = gfx;
|
|
|
|
break;
|
|
|
|
case STATE_USELEFT:
|
|
|
|
e->standleftGfx[4] = gfx;
|
|
|
|
break;
|
|
|
|
case STATE_USERIGHT:
|
|
|
|
e->standrightGfx[4] = gfx;
|
|
|
|
break;
|
|
|
|
|
|
|
|
// Death & Dying for Player
|
|
|
|
case STATE_DYING:
|
|
|
|
dyingGfx[dyingFrames] = gfx;
|
|
|
|
dyingFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_GOODJOB:
|
|
|
|
goodjobGfx = gfx;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case STATE_HORRIBLE1:
|
|
|
|
horrible1Gfx[horrible1Frames] = gfx;
|
|
|
|
horrible1Frames++;
|
|
|
|
break;
|
|
|
|
case STATE_HORRIBLE2:
|
|
|
|
horrible2Gfx[horrible2Frames] = gfx;
|
|
|
|
horrible2Frames++;
|
|
|
|
break;
|
|
|
|
case STATE_HORRIBLE3:
|
|
|
|
horrible3Gfx[horrible3Frames] = gfx;
|
|
|
|
horrible3Frames++;
|
|
|
|
break;
|
|
|
|
case STATE_HORRIBLE4:
|
|
|
|
horrible4Gfx[horrible4Frames] = gfx;
|
|
|
|
horrible4Frames++;
|
|
|
|
break;
|
|
|
|
case STATE_PLUMMET:
|
|
|
|
plummetGfx[plummetFrames] = gfx;
|
|
|
|
plummetFrames++;
|
|
|
|
break;
|
|
|
|
|
|
|
|
// floating frames - overwrite "standup" info
|
|
|
|
case STATE_FLOATING:
|
|
|
|
e->blinkGfx[e->blinkFrames] = gfx;
|
|
|
|
e->blinkFrames++;
|
|
|
|
break;
|
|
|
|
|
|
|
|
// melted frames - go in the special area (lightbarrels)
|
|
|
|
// shocking frames - go in the special1 area (shockbots)
|
|
|
|
// exploding frames, same
|
|
|
|
case STATE_MELTED:
|
|
|
|
case STATE_SHOCKING:
|
|
|
|
case STATE_EXPLODING:
|
|
|
|
e->special1Gfx[e->special1Frames] = gfx;
|
|
|
|
e->special1Frames++;
|
|
|
|
break;
|
|
|
|
|
|
|
|
// ICEPUFF spawning states
|
|
|
|
case STATE_ICEP_PEEK:
|
|
|
|
e->blinkGfx[e->blinkFrames] = gfx;
|
|
|
|
e->blinkFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_ICEP_APPEAR:
|
|
|
|
e->standupGfx[e->standupFrames] = gfx;
|
|
|
|
e->standupFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_ICEP_THROWDOWN:
|
|
|
|
e->standdownGfx[e->standdownFrames] = gfx;
|
|
|
|
e->standdownFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_ICEP_THROWRIGHT:
|
|
|
|
e->standrightGfx[e->standrightFrames] = gfx;
|
|
|
|
e->standrightFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_ICEP_THROWLEFT:
|
|
|
|
e->standleftGfx[e->standleftFrames] = gfx;
|
|
|
|
e->standleftFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_ICEP_DISAPPEAR:
|
|
|
|
e->special1Gfx[e->special1Frames] = gfx;
|
|
|
|
e->special1Frames++;
|
|
|
|
break;
|
|
|
|
|
|
|
|
// FATFROG spawning states
|
|
|
|
case STATE_LICKDOWN:
|
|
|
|
e->movedownGfx[e->movedownFrames] = gfx;
|
|
|
|
e->movedownFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_LICKLEFT:
|
|
|
|
e->moveleftGfx[e->moveleftFrames] = gfx;
|
|
|
|
e->moveleftFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_LICKRIGHT:
|
|
|
|
e->moverightGfx[e->moverightFrames] = gfx;
|
|
|
|
e->moverightFrames++;
|
|
|
|
break;
|
|
|
|
|
|
|
|
// MEERKAT spawning states
|
|
|
|
case STATE_MEER_MOVE:
|
|
|
|
e->standdownGfx[e->standdownFrames] = gfx;
|
|
|
|
e->standdownFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_MEER_APPEAR:
|
|
|
|
e->standleftGfx[e->standleftFrames] = gfx;
|
|
|
|
e->standleftFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_MEER_BITE:
|
|
|
|
e->standrightGfx[e->standrightFrames] = gfx;
|
|
|
|
e->standrightFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_MEER_DISAPPEAR:
|
|
|
|
e->standupGfx[e->standupFrames] = gfx;
|
|
|
|
e->standupFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_MEER_LOOK:
|
|
|
|
e->movedownGfx[e->movedownFrames] = gfx;
|
|
|
|
e->movedownFrames++;
|
|
|
|
break;
|
|
|
|
|
|
|
|
// DIVERTER spawning states
|
|
|
|
case STATE_DIVERTER_BL:
|
|
|
|
e->standdownGfx[e->standdownFrames] = gfx;
|
|
|
|
e->standdownFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_DIVERTER_BR:
|
|
|
|
e->standupGfx[e->standupFrames] = gfx;
|
|
|
|
e->standupFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_DIVERTER_TL:
|
|
|
|
e->standleftGfx[e->standleftFrames] = gfx;
|
|
|
|
e->standleftFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_DIVERTER_TR:
|
|
|
|
e->standrightGfx[e->standrightFrames] = gfx;
|
|
|
|
e->standrightFrames++;
|
|
|
|
break;
|
|
|
|
// DOLLY states
|
|
|
|
// angry[4] = standright[4]
|
|
|
|
// kissright[4]/kissleft[4] = standleft[8]
|
|
|
|
// panic[4]/laugh[4] = standdown[8]
|
|
|
|
// dollyuseright[5] = special1[5]
|
|
|
|
case STATE_ANGRY:
|
|
|
|
e->standrightGfx[e->standrightFrames] = gfx;
|
|
|
|
e->standrightFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_KISSRIGHT:
|
|
|
|
e->standleftGfx[e->standleftFrames] = gfx;
|
|
|
|
e->standleftFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_KISSLEFT:
|
|
|
|
e->standleftGfx[4 + e->int1] = gfx;
|
|
|
|
e->int1++;
|
|
|
|
break;
|
|
|
|
case STATE_PANIC:
|
|
|
|
e->standdownGfx[e->standdownFrames] = gfx;
|
|
|
|
e->standdownFrames++;
|
|
|
|
break;
|
|
|
|
case STATE_LAUGH:
|
|
|
|
e->standdownGfx[4 + e->value1] = gfx;
|
|
|
|
e->value1++;
|
|
|
|
break;
|
|
|
|
case STATE_DOLLYUSERIGHT:
|
|
|
|
e->special1Gfx[e->special1Frames] = gfx;
|
|
|
|
e->special1Frames++;
|
|
|
|
break;
|
|
|
|
|
|
|
|
// SARGE yelling
|
|
|
|
case STATE_YELL:
|
|
|
|
e->special1Gfx[e->special1Frames] = gfx;
|
|
|
|
e->special1Frames++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
j++;
|
|
|
|
}
|
|
|
|
|
|
|
|
e->aiInit = aiEntList[i].initFunc;
|
|
|
|
e->aiInit2 = aiEntList[i].initFunc2;
|
|
|
|
if (init) {
|
|
|
|
e->aiInit(e);
|
|
|
|
if (e->aiInit2) {
|
|
|
|
e->aiInit2(e);
|
|
|
|
}
|
|
|
|
if (e->luaFuncInit[0]) {
|
|
|
|
g_hdb->_lua->callFunction(e->luaFuncInit, 2);
|
|
|
|
|
|
|
|
const char *str1 = g_hdb->_lua->getStringOffStack();
|
|
|
|
const char *str2 = g_hdb->_lua->getStringOffStack();
|
|
|
|
if (str1) {
|
|
|
|
strcpy(e->entityName, str1);
|
|
|
|
}
|
|
|
|
if (str2) {
|
|
|
|
strcpy(e->printedName, str2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (e->aiInit2) {
|
|
|
|
e->aiInit2(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
break; // Entity Initiated
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2019-06-20 17:47:01 +05:30
|
|
|
// Stops the movement of an entity
|
|
|
|
void AI::stopEntity(AIEntity *e) {
|
|
|
|
if (e == _player) {
|
|
|
|
clearWaypoints();
|
|
|
|
// Reset Player speed
|
|
|
|
e->moveSpeed = kPlayerMoveSpeed;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Reset animation
|
|
|
|
e->animFrame = 0;
|
|
|
|
|
|
|
|
// Align with tile boundaries
|
|
|
|
e->x = e->tileX * kTileWidth;
|
|
|
|
e->y = e->tileY * kTileHeight;
|
|
|
|
e->goalX = e->tileX;
|
|
|
|
e->goalY = e->tileY;
|
|
|
|
e->drawXOff = e->drawYOff = 0;
|
|
|
|
|
|
|
|
// Don't change the state of Diverters or Floating entities
|
|
|
|
switch (e->state) {
|
|
|
|
case STATE_FLOATLEFT:
|
|
|
|
case STATE_FLOATRIGHT:
|
|
|
|
case STATE_FLOATUP:
|
|
|
|
case STATE_FLOATDOWN:
|
|
|
|
e->state = STATE_FLOATING;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (e->type != AI_DIVERTER) {
|
|
|
|
switch (e->dir) {
|
|
|
|
case DIR_UP:
|
|
|
|
if (e->standupFrames)
|
|
|
|
e->state = STATE_STANDUP;
|
|
|
|
else
|
|
|
|
e->state = STATE_NONE;
|
|
|
|
break;
|
|
|
|
case DIR_DOWN:
|
|
|
|
if (e->standdownFrames)
|
|
|
|
e->state = STATE_STANDDOWN;
|
|
|
|
else
|
|
|
|
e->state = STATE_NONE;
|
|
|
|
break;
|
|
|
|
case DIR_LEFT:
|
|
|
|
if (e->standleftFrames)
|
|
|
|
e->state = STATE_STANDLEFT;
|
|
|
|
else
|
|
|
|
e->state = STATE_NONE;
|
|
|
|
break;
|
|
|
|
case DIR_RIGHT:
|
|
|
|
if (e->standrightFrames)
|
|
|
|
e->state = STATE_STANDRIGHT;
|
|
|
|
else
|
|
|
|
e->state = STATE_NONE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-19 17:27:11 +05:30
|
|
|
AIEntity *AI::locateEntity(const char *luaName) {
|
2019-06-19 17:35:27 +05:30
|
|
|
for (Common::Array<AIEntity *>::iterator it = _ents->begin(); it != _ents->end(); it++) {
|
|
|
|
if (Common::matchString((*it)->entityName, luaName)) {
|
|
|
|
return *it;
|
|
|
|
}
|
|
|
|
}
|
2019-06-19 17:27:11 +05:30
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2019-06-19 23:57:17 +05:30
|
|
|
void AI::removeEntity(AIEntity *e) {
|
|
|
|
_ents->erase(&e);
|
|
|
|
}
|
|
|
|
|
2019-06-20 18:14:07 +05:30
|
|
|
void AI::setEntityGoal(AIEntity *e, int x, int y) {
|
|
|
|
int xv, yv;
|
|
|
|
|
|
|
|
e->xVel = e->yVel = 0;
|
|
|
|
|
|
|
|
xv = x - e->tileX;
|
|
|
|
if (xv < 0) {
|
|
|
|
e->xVel = -e->moveSpeed;
|
|
|
|
e->state = STATE_MOVELEFT;
|
|
|
|
e->dir = DIR_LEFT;
|
|
|
|
} else if (xv > 0) {
|
|
|
|
e->xVel = e->moveSpeed;
|
|
|
|
e->state = STATE_MOVERIGHT;
|
|
|
|
e->dir = DIR_RIGHT;
|
|
|
|
}
|
|
|
|
|
|
|
|
yv = y - e->tileY;
|
|
|
|
if (yv < 0) {
|
|
|
|
e->yVel = -e->moveSpeed;
|
|
|
|
e->state = STATE_MOVELEFT;
|
|
|
|
e->dir = DIR_LEFT;
|
|
|
|
} else if (yv > 0) {
|
|
|
|
e->yVel = e->moveSpeed;
|
|
|
|
e->state = STATE_MOVERIGHT;
|
|
|
|
e->dir = DIR_RIGHT;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (e->type == AI_GUY && _playerRunning) {
|
|
|
|
e->xVel = e->xVel << 1;
|
|
|
|
e->yVel = e->yVel << 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
e->goalX = x;
|
|
|
|
e->goalY = y;
|
|
|
|
e->animFrame = 0;
|
|
|
|
e->drawXOff = e->drawYOff = 0;
|
|
|
|
}
|
|
|
|
|
2019-06-20 01:46:40 +05:30
|
|
|
// Initializes each entity after map is loaded
|
|
|
|
void AI::initAllEnts() {
|
|
|
|
for (Common::Array<AIEntity *>::iterator it = _ents->begin(); it != _ents->end(); it++) {
|
|
|
|
(*it)->aiInit((*it));
|
|
|
|
if ((*it)->luaFuncInit[0]) {
|
|
|
|
if (g_hdb->_lua->callFunction((*it)->luaFuncInit, 2)) {
|
|
|
|
strcpy((*it)->entityName, g_hdb->_lua->getStringOffStack());
|
|
|
|
strcpy((*it)->printedName, g_hdb->_lua->getStringOffStack());
|
|
|
|
} else {
|
|
|
|
warning("'%s' doesn't exists", (*it)->luaFuncInit);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-06-20 02:03:39 +05:30
|
|
|
|
2019-06-20 19:03:40 +05:30
|
|
|
for (int i = 0; i < _numInventory; i++) {
|
|
|
|
AIEntity *temp = &_inventory[i].ent;
|
|
|
|
|
|
|
|
// Clear out all ptrs in entity before writing
|
|
|
|
for (int j = 0; i < kMaxAnimFrames; i++) {
|
|
|
|
temp->blinkGfx[j] = NULL;
|
|
|
|
temp->movedownGfx[j] = NULL;
|
|
|
|
temp->moveupGfx[j] = NULL;
|
|
|
|
temp->moveleftGfx[j] = NULL;
|
|
|
|
temp->moverightGfx[j] = NULL;
|
|
|
|
temp->standdownGfx[j] = NULL;
|
|
|
|
temp->standupGfx[j] = NULL;
|
|
|
|
temp->standleftGfx[j] = NULL;
|
|
|
|
temp->standrightGfx[j] = NULL;
|
|
|
|
temp->special1Gfx[j] = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
temp->blinkFrames = 0;
|
|
|
|
temp->movedownFrames = 0;
|
|
|
|
temp->moveupFrames = 0;
|
|
|
|
temp->moveleftFrames = 0;
|
|
|
|
temp->moverightFrames = 0;
|
|
|
|
temp->standdownFrames = 0;
|
|
|
|
temp->standupFrames = 0;
|
|
|
|
temp->standleftFrames = 0;
|
|
|
|
temp->standrightFrames = 0;
|
|
|
|
|
|
|
|
temp->draw = NULL;
|
|
|
|
temp->aiDraw = NULL;
|
|
|
|
temp->aiAction = temp->aiInit = temp->aiUse = NULL;
|
|
|
|
|
|
|
|
cacheEntGfx(temp, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
warning("STUB: initAllEnts: Cache graphics for Deliveries");
|
2019-06-20 02:03:39 +05:30
|
|
|
warning("STUB: initAllEnts: LaserScan required");
|
2019-06-20 01:46:40 +05:30
|
|
|
}
|
|
|
|
|
2019-06-19 22:21:26 +05:30
|
|
|
// Check to see if we can get this entity
|
|
|
|
bool AI::getTableEnt(AIType type) {
|
|
|
|
switch (type) {
|
|
|
|
case ITEM_CELL:
|
|
|
|
case ITEM_ENV_WHITE:
|
|
|
|
case ITEM_ENV_RED:
|
|
|
|
case ITEM_ENV_BLUE:
|
|
|
|
case ITEM_ENV_GREEN:
|
|
|
|
case ITEM_TRANSCEIVER:
|
|
|
|
case ITEM_CLUB:
|
|
|
|
case ITEM_ROBOSTUNNER:
|
|
|
|
case ITEM_SLUGSLINGER:
|
|
|
|
case ITEM_MONKEYSTONE:
|
|
|
|
case ITEM_GOO_CUP:
|
|
|
|
case ITEM_TEACUP:
|
|
|
|
case ITEM_BURGER:
|
|
|
|
case ITEM_PDA:
|
|
|
|
case ITEM_BOOK:
|
|
|
|
case ITEM_CLIPBOARD:
|
|
|
|
case ITEM_NOTE:
|
|
|
|
case ITEM_KEYCARD_WHITE:
|
|
|
|
case ITEM_KEYCARD_BLUE:
|
|
|
|
case ITEM_KEYCARD_RED:
|
|
|
|
case ITEM_KEYCARD_GREEN:
|
|
|
|
case ITEM_KEYCARD_PURPLE:
|
|
|
|
case ITEM_KEYCARD_BLACK:
|
|
|
|
case ITEM_SEED:
|
|
|
|
case ITEM_SODA:
|
|
|
|
case ITEM_SLICER:
|
|
|
|
case ITEM_DOLLYTOOL1:
|
|
|
|
case ITEM_DOLLYTOOL2:
|
|
|
|
case ITEM_DOLLYTOOL3:
|
|
|
|
case ITEM_DOLLYTOOL4:
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check to see if it's okay to move through this entity
|
|
|
|
bool AI::walkThroughEnt(AIType type) {
|
|
|
|
switch (type) {
|
|
|
|
case AI_VORTEXIAN:
|
|
|
|
case AI_MEERKAT:
|
|
|
|
case AI_GOODFAIRY:
|
|
|
|
case AI_BADFAIRY:
|
|
|
|
case AI_GATEPUDDLE:
|
|
|
|
case AI_BUZZFLY:
|
|
|
|
case AI_OMNIBOT:
|
|
|
|
case AI_PUSHBOT:
|
|
|
|
case AI_TURNBOT:
|
|
|
|
case AI_RIGHTBOT:
|
|
|
|
|
|
|
|
case ITEM_GEM_WHITE:
|
|
|
|
case ITEM_GEM_BLUE:
|
|
|
|
case ITEM_GEM_RED:
|
|
|
|
case ITEM_GEM_GREEN:
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return getTableEnt(type);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Play special sound for every item you get
|
|
|
|
void AI::getItemSound(AIType type) {
|
|
|
|
warning("STUB: AI: getItemSound required");
|
|
|
|
}
|
2019-06-19 22:46:33 +05:30
|
|
|
|
|
|
|
void AI::lookAtEntity(AIEntity *e) {
|
|
|
|
lookAtXY(e->tileX, e->tileY);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Change player direction to XY
|
|
|
|
void AI::lookAtXY(int x, int y) {
|
|
|
|
int distX, distY;
|
|
|
|
|
|
|
|
distX = abs(_player->tileX - x);
|
|
|
|
distY = abs(_player->tileY - y);
|
|
|
|
|
|
|
|
if (distX > distY) {
|
|
|
|
// X takes precedence
|
|
|
|
if (x < _player->tileX) {
|
|
|
|
_player->dir = DIR_LEFT;
|
|
|
|
} else if (x > _player->tileX) {
|
|
|
|
_player->dir = DIR_RIGHT;
|
|
|
|
} else if (y < _player->tileY) {
|
|
|
|
_player->dir = DIR_UP;
|
|
|
|
} else {
|
|
|
|
_player->dir = DIR_DOWN;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Y takes precedence
|
|
|
|
if (y < _player->tileY) {
|
|
|
|
_player->dir = DIR_UP;
|
|
|
|
} else if (y > _player->tileY) {
|
|
|
|
_player->dir = DIR_DOWN;
|
|
|
|
} else if (x < _player->tileX) {
|
|
|
|
_player->dir = DIR_LEFT;
|
|
|
|
} else {
|
|
|
|
_player->dir = DIR_RIGHT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (_player->dir) {
|
|
|
|
case DIR_UP:
|
|
|
|
_player->state = STATE_STANDUP;
|
|
|
|
warning("STUB: Set _player->draw to Player standup_gfx");
|
|
|
|
break;
|
|
|
|
case DIR_DOWN:
|
|
|
|
_player->state = STATE_STANDDOWN;
|
|
|
|
warning("STUB: Set _player->draw to Player standdown_gfx");
|
|
|
|
break;
|
|
|
|
case DIR_LEFT:
|
|
|
|
_player->state = STATE_STANDLEFT;
|
|
|
|
warning("STUB: Set _player->draw to Player standleft_gfx");
|
|
|
|
break;
|
|
|
|
case DIR_RIGHT:
|
|
|
|
_player->state = STATE_STANDRIGHT;
|
|
|
|
warning("STUB: Set _player->draw to Player standright_gfx");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2019-06-19 15:55:51 +02:00
|
|
|
} // End of Namespace
|