mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-07 02:12:14 +00:00
173 lines
5.0 KiB
C++
173 lines
5.0 KiB
C++
/* 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 {
|
|
|
|
void aiOmniBotInit(AIEntity *e) {
|
|
if (e->value1 == 1)
|
|
e->aiAction = aiOmniBotMove;
|
|
else if (g_hdb->_ai->findPath(e))
|
|
e->aiAction = aiOmniBotAction;
|
|
}
|
|
|
|
void aiOmniBotInit2(AIEntity *e) {
|
|
e->standdownGfx[0] = e->movedownGfx[0];
|
|
e->standupGfx[0] = e->movedownGfx[0];
|
|
e->standleftGfx[0] = e->moveleftGfx[0];
|
|
e->standrightGfx[0] = e->moverightGfx[0];
|
|
e->standdownFrames = e->standupFrames = e->standleftFrames = e->standrightFrames = 1;
|
|
e->draw = g_hdb->_ai->getStandFrameDir(e);
|
|
}
|
|
|
|
void aiOmniBotMove(AIEntity *e) {
|
|
if (e->goalX)
|
|
g_hdb->_ai->animateEntity(e);
|
|
else
|
|
g_hdb->_ai->animEntFrames(e);
|
|
}
|
|
|
|
void aiOmniBotAction(AIEntity *e) {
|
|
AIEntity *p = g_hdb->_ai->getPlayer();
|
|
if (e->goalX) {
|
|
if (!e->sequence) {
|
|
g_hdb->_ai->animateEntity(e);
|
|
// Is the Player collding?
|
|
if (e->onScreen && (p->level = e->level) && g_hdb->_ai->checkPlayerCollision(e->x, e->y, 4) && !g_hdb->_ai->playerDead()) {
|
|
g_hdb->_ai->killPlayer(DEATH_FRIED);
|
|
return;
|
|
}
|
|
|
|
// Shoot player ?
|
|
if (onEvenTile(e->x, e->y) && g_hdb->getActionMode()) {
|
|
int xv = 0, yv = 0, result;
|
|
int shoot = 0;
|
|
AIEntity *omni;
|
|
// FIXME: Is reloading Player required here?
|
|
p = g_hdb->_ai->getPlayer();
|
|
|
|
// On same level/screen?
|
|
if ((e->level != p->level) || g_hdb->_ai->playerDead() || !e->onScreen)
|
|
return;
|
|
|
|
// Is Player in Line of Sight?
|
|
switch (e->dir) {
|
|
case DIR_UP:
|
|
if (p->x == e->x && p->y < e->y) {
|
|
shoot = 1;
|
|
yv = -1;
|
|
}
|
|
break;
|
|
case DIR_DOWN:
|
|
if (p->x == e->x && p->y > e->y) {
|
|
shoot = 1;
|
|
yv = 1;
|
|
}
|
|
break;
|
|
case DIR_LEFT:
|
|
if (p->x < e->x && p->y == e->y) {
|
|
shoot = 1;
|
|
xv = -1;
|
|
}
|
|
break;
|
|
case DIR_RIGHT:
|
|
if (p->x > e->x && p->y == e->y) {
|
|
shoot = 1;
|
|
xv = 1;
|
|
}
|
|
break;
|
|
case DIR_NONE:
|
|
warning("aiOmniBotAction: DIR_NONE found");
|
|
break;
|
|
}
|
|
|
|
// If shoot = 1, take the shot
|
|
// (1) Check we're not shooting into a solid tile
|
|
// (2) Check we're not shooting into an Entity unless it's the player
|
|
AIEntity *hit = g_hdb->_ai->legalMoveOverWater(e->tileX+xv, e->tileY + yv, e->level, &result);
|
|
if (shoot && !hit && result) {
|
|
omni = g_hdb->_ai->spawn(AI_OMNIBOT_MISSILE, e->dir, e->tileX + xv, e->tileY + yv, NULL, NULL, NULL, DIR_NONE, e->level, 0, 0, 1);
|
|
omni->xVel = xv * kPlayerMoveSpeed * 2;
|
|
omni->yVel = yv * kPlayerMoveSpeed * 2;
|
|
if (g_hdb->_map->onScreen(e->tileX, e->tileY))
|
|
warning("STUB: aiOmniBotAction: Play SND_OMNIBOT_FIRE");
|
|
if (!g_hdb->getActionMode()) {
|
|
omni->xVel >>= 1;
|
|
omni->yVel >>= 1;
|
|
}
|
|
e->sequence = 16;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
g_hdb->_ai->findPath(e);
|
|
if (e->onScreen)
|
|
warning("STUB: aiOmniBotAction: Play SND_OMNIBOT_AMBIENT");
|
|
}
|
|
|
|
if (e->sequence)
|
|
e->sequence--;
|
|
}
|
|
|
|
void aiOmniBotMissileInit(AIEntity *e) {
|
|
e->state = STATE_MOVEDOWN;
|
|
e->aiAction = aiOmniBotMissileAction;
|
|
}
|
|
|
|
void aiOmniBotMissileInit2(AIEntity *e) {
|
|
for (int i = 0; i < e->movedownFrames;i++)
|
|
e->moveleftGfx[i] = e->moverightGfx[i] = e->moveupGfx[i] = e->movedownGfx[i];
|
|
|
|
e->moveleftFrames = e->moverightFrames = e->moveupFrames = e->movedownFrames;
|
|
e->draw = e->movedownGfx[0];
|
|
}
|
|
|
|
void aiOmniBotMissileAction(AIEntity *e) {
|
|
AIEntity *p = g_hdb->_ai->getPlayer();
|
|
|
|
g_hdb->_ai->animEntFrames(e);
|
|
e->x += e->xVel;
|
|
e->y += e->yVel;
|
|
e->tileX = e->x / kTileWidth;
|
|
e->tileY = e->y / kTileHeight;
|
|
|
|
// Did we hit a solid wall?
|
|
int result;
|
|
AIEntity *hit = g_hdb->_ai->legalMoveOverWaterIgnore(e->tileX, e->tileY, e->level, &result, e);
|
|
|
|
if (hit || !result) {
|
|
g_hdb->_ai->addAnimateTarget(e->x, e->y, 0, 3, ANIM_FAST, false, false, "steam_puff_sit");
|
|
g_hdb->_ai->removeEntity(e);
|
|
}
|
|
|
|
// On Even tiles, check for hitting player
|
|
if (onEvenTile(e->x, e->y))
|
|
if (e->onScreen && (p->level == e->level) && g_hdb->_ai->checkPlayerCollision(e->x, e->y, 4) && !g_hdb->_ai->playerDead()) {
|
|
g_hdb->_ai->killPlayer(DEATH_NORMAL);
|
|
g_hdb->_ai->addAnimateTarget(e->x, e->y, 0, 3, ANIM_FAST, false, false, "steam_puff_sit");
|
|
g_hdb->_ai->removeEntity(e);
|
|
}
|
|
}
|
|
|
|
} // End of Namespace
|