Initial commit
This commit is contained in:
72
engines/crab/ai/SpriteConstant.cpp
Normal file
72
engines/crab/ai/SpriteConstant.cpp
Normal file
@@ -0,0 +1,72 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on the CRAB engine
|
||||
*
|
||||
* Copyright (c) Arvind Raja Yadav
|
||||
*
|
||||
* Licensed under MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "crab/ai/SpriteConstant.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
using namespace pyrodactyl::ai;
|
||||
|
||||
FlyerConstant::FlyerConstant() : _start(10, 40), _vel(8.0f, 0.0f) {
|
||||
_delayMin = 5000;
|
||||
_delayMax = 20000;
|
||||
}
|
||||
|
||||
void FlyerConstant::load(rapidxml::xml_node<char> *node) {
|
||||
if (nodeValid("start", node))
|
||||
_start.load(node->first_node("start"));
|
||||
|
||||
if (nodeValid("vel", node))
|
||||
_vel.load(node->first_node("vel"));
|
||||
|
||||
if (nodeValid("delay", node)) {
|
||||
auto n = node->first_node("delay");
|
||||
loadNum(_delayMin, "min", n);
|
||||
loadNum(_delayMax, "max", n);
|
||||
}
|
||||
}
|
||||
|
||||
SpriteConstant::SpriteConstant() : _walkVelMod(0.9f, 0.63f) {
|
||||
_planeW = 20;
|
||||
_tweening = 0.2f;
|
||||
}
|
||||
|
||||
void SpriteConstant::load(rapidxml::xml_node<char> *node) {
|
||||
loadNum(_planeW, "plane_width", node);
|
||||
loadNum(_tweening, "tweening", node);
|
||||
|
||||
if (nodeValid("_walkVelMod", node))
|
||||
_walkVelMod.load(node->first_node("_walkVelMod"));
|
||||
|
||||
if (nodeValid("fly", node))
|
||||
_fly.load(node->first_node("fly"));
|
||||
}
|
||||
|
||||
} // End of namespace Crab
|
||||
79
engines/crab/ai/SpriteConstant.h
Normal file
79
engines/crab/ai/SpriteConstant.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on the CRAB engine
|
||||
*
|
||||
* Copyright (c) Arvind Raja Yadav
|
||||
*
|
||||
* Licensed under MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CRAB_SPRITECONSTANT_H
|
||||
#define CRAB_SPRITECONSTANT_H
|
||||
|
||||
#include "crab/vectors.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
namespace pyrodactyl {
|
||||
namespace ai {
|
||||
// These parameters control aspects of sprites flying across the screen
|
||||
struct FlyerConstant {
|
||||
// How far does a flier sprite start from the camera (an offset, not the whole value)
|
||||
Vector2i _start;
|
||||
|
||||
// The value of the delay for fliers
|
||||
uint32 _delayMin, _delayMax;
|
||||
|
||||
// The velocity of fliers
|
||||
Vector2f _vel;
|
||||
|
||||
FlyerConstant();
|
||||
|
||||
void load(rapidxml::xml_node<char> *node);
|
||||
};
|
||||
|
||||
// These values are used in various sprite related tasks
|
||||
struct SpriteConstant {
|
||||
// Plane width decides the maximum difference in sprite Y values that is considered on the same plane
|
||||
int _planeW;
|
||||
|
||||
// Tweening constant controls the acceleration curve of every sprite
|
||||
float _tweening;
|
||||
|
||||
// The modifiers of x and y movement speeds
|
||||
Vector2f _walkVelMod;
|
||||
|
||||
// Data for flying sprites
|
||||
FlyerConstant _fly;
|
||||
|
||||
SpriteConstant();
|
||||
|
||||
void load(rapidxml::xml_node<char> *node);
|
||||
};
|
||||
} // End of namespace ai
|
||||
} // End of namespace pyrodactyl
|
||||
|
||||
} // End of namespace Crab
|
||||
|
||||
#endif // CRAB_SPRITECONSTANT_H
|
||||
66
engines/crab/ai/moveeffect.cpp
Normal file
66
engines/crab/ai/moveeffect.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on the CRAB engine
|
||||
*
|
||||
* Copyright (c) Arvind Raja Yadav
|
||||
*
|
||||
* Licensed under MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "crab/ai/moveeffect.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
using namespace pyrodactyl::anim;
|
||||
|
||||
FightMoveEffect::FightMoveEffect() {
|
||||
_activate = -1;
|
||||
_hit = -1;
|
||||
_dmg = 0;
|
||||
_stun = 0;
|
||||
_hurt = -1;
|
||||
_death = -1;
|
||||
}
|
||||
|
||||
void FightMoveEffect::load(rapidxml::xml_node<char> *node) {
|
||||
loadNum(_stun, "stun", node);
|
||||
loadNum(_dmg, "damage", node);
|
||||
loadNum(_hurt, "hurt", node);
|
||||
loadNum(_death, "death", node);
|
||||
|
||||
if (nodeValid("image", node, false))
|
||||
_img.load(node->first_node("image"));
|
||||
|
||||
if (nodeValid("sound", node)) {
|
||||
rapidxml::xml_node<char> *soundnode = node->first_node("sound");
|
||||
|
||||
if (!loadNum(_activate, "activate", soundnode, false))
|
||||
_activate = -1;
|
||||
|
||||
if (!loadNum(_activate, "hit", soundnode, false))
|
||||
_activate = -1;
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Crab
|
||||
72
engines/crab/ai/moveeffect.h
Normal file
72
engines/crab/ai/moveeffect.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on the CRAB engine
|
||||
*
|
||||
* Copyright (c) Arvind Raja Yadav
|
||||
*
|
||||
* Licensed under MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CRAB_MOVEEFFECT_H
|
||||
#define CRAB_MOVEEFFECT_H
|
||||
|
||||
#include "crab/animation/imageeffect.h"
|
||||
#include "crab/music/musicparam.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
namespace pyrodactyl {
|
||||
namespace anim {
|
||||
struct FightMoveEffect {
|
||||
// The image displayed on being hit
|
||||
ImageEffect _img;
|
||||
|
||||
// The sound played by this move when it's activated
|
||||
pyrodactyl::music::ChunkKey _activate;
|
||||
|
||||
// The sound played by this move when it hits opponent
|
||||
pyrodactyl::music::ChunkKey _hit;
|
||||
|
||||
// The move the sprite hit by our current move performs - if living (hurt animation)
|
||||
int _hurt;
|
||||
|
||||
// The move the sprite hit by our current move performs - if it dies as a result (dying animation)
|
||||
int _death;
|
||||
|
||||
// The stun time for the enemy if this move hits a sprite
|
||||
uint _stun;
|
||||
|
||||
// The base damage of the move if it hits a sprite
|
||||
int _dmg;
|
||||
|
||||
FightMoveEffect();
|
||||
|
||||
void load(rapidxml::xml_node<char> *node);
|
||||
};
|
||||
} // End of namespace anim
|
||||
} // End of namespace pyrodactyl
|
||||
|
||||
} // End of namespace Crab
|
||||
|
||||
#endif // CRAB_MOVEEFFECT_H
|
||||
66
engines/crab/ai/movement.cpp
Normal file
66
engines/crab/ai/movement.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on the CRAB engine
|
||||
*
|
||||
* Copyright (c) Arvind Raja Yadav
|
||||
*
|
||||
* Licensed under MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "crab/ai/movement.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
using namespace pyrodactyl::ai;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Walk in preset paths
|
||||
//------------------------------------------------------------------------
|
||||
void MovementSet::load(rapidxml::xml_node<char> *node) {
|
||||
_enabled = true;
|
||||
loadBool(_repeat, "repeat", node);
|
||||
for (auto n = node->first_node("walk"); n != nullptr; n = n->next_sibling("walk"))
|
||||
_path.push_back(n);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: To make the AI patrol/wait along certain points
|
||||
//------------------------------------------------------------------------
|
||||
bool MovementSet::internalEvents(const Rect rect) {
|
||||
if (_enabled) {
|
||||
// If we are at the current waypoint, get to the next waypoint
|
||||
if (_path[_cur]._target.collide(rect)) {
|
||||
_cur = (_cur + 1) % _path.size();
|
||||
_timer.start();
|
||||
}
|
||||
|
||||
// Wait according to the delay value in the node
|
||||
if (_timer.ticks() >= _path[_cur]._delay)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // End of namespace Crab
|
||||
92
engines/crab/ai/movement.h
Normal file
92
engines/crab/ai/movement.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on the CRAB engine
|
||||
*
|
||||
* Copyright (c) Arvind Raja Yadav
|
||||
*
|
||||
* Licensed under MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CRAB_MOVEMENT_H
|
||||
#define CRAB_MOVEMENT_H
|
||||
|
||||
#include "crab/Rectangle.h"
|
||||
#include "crab/timer.h"
|
||||
#include "crab/vectors.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
namespace pyrodactyl {
|
||||
namespace ai {
|
||||
struct MovementSet {
|
||||
struct Movement {
|
||||
// The position this sprite has to move to
|
||||
Rect _target;
|
||||
|
||||
// The time the sprite waits before it starts moving to pos
|
||||
uint32 _delay;
|
||||
|
||||
Movement(rapidxml::xml_node<char> *node) {
|
||||
_target.load(node);
|
||||
_delay = 0;
|
||||
loadNum(_delay, "delay", node);
|
||||
}
|
||||
};
|
||||
|
||||
// The path followed by the sprite
|
||||
Common::Array<Movement> _path;
|
||||
|
||||
// If true, sprite repeats the path pattern after reaching the last co-ordinate
|
||||
bool _repeat;
|
||||
|
||||
// The current path node we are traveling to
|
||||
uint _cur;
|
||||
|
||||
// The time the sprite has spent waiting is calculated here
|
||||
Timer _timer;
|
||||
|
||||
// Is this set enabled?
|
||||
bool _enabled;
|
||||
|
||||
MovementSet() {
|
||||
_cur = 0;
|
||||
_repeat = false;
|
||||
_enabled = false;
|
||||
}
|
||||
|
||||
MovementSet(rapidxml::xml_node<char> *node) : MovementSet() {
|
||||
load(node);
|
||||
}
|
||||
|
||||
void load(rapidxml::xml_node<char> *node);
|
||||
|
||||
bool internalEvents(const Rect rect);
|
||||
Rect target() { return _path[_cur]._target; }
|
||||
};
|
||||
} // End of namespace ai
|
||||
} // End of namespace pyrodactyl
|
||||
|
||||
} // End of namespace Crab
|
||||
|
||||
#endif // CRAB_MOVEMENT_H
|
||||
315
engines/crab/ai/spriteai.cpp
Normal file
315
engines/crab/ai/spriteai.cpp
Normal file
@@ -0,0 +1,315 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on the CRAB engine
|
||||
*
|
||||
* Copyright (c) Arvind Raja Yadav
|
||||
*
|
||||
* Licensed under MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "crab/crab.h"
|
||||
#include "crab/ScreenSettings.h"
|
||||
#include "crab/animation/sprite.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
using namespace pyrodactyl::anim;
|
||||
using namespace pyrodactyl::ai;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Calculate distance between two sprites
|
||||
//------------------------------------------------------------------------
|
||||
double Sprite::distSq(const Sprite &s) {
|
||||
double result = (_pos.x - s._pos.x) * (_pos.x - s._pos.x) + (_pos.y - s._pos.y) * (_pos.y - s._pos.y);
|
||||
return result;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Used for player movement
|
||||
//------------------------------------------------------------------------
|
||||
void Sprite::moveToDest(pyrodactyl::event::Info &info, const SpriteConstant &sc) {
|
||||
if (_aiData._dest._active) {
|
||||
int num = 0;
|
||||
info.statGet(_id, pyrodactyl::stat::STAT_SPEED, num);
|
||||
++num;
|
||||
float playerSpeed = static_cast<float>(num);
|
||||
|
||||
if (moveToLoc(_aiData._dest, playerSpeed, sc)) {
|
||||
_aiData._dest._active = false;
|
||||
xVel(0.0f);
|
||||
yVel(0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Sprite::moveToDestPathfinding(pyrodactyl::event::Info &info, const SpriteConstant &sc) {
|
||||
if (_aiData._dest._active) {
|
||||
int num = 0;
|
||||
info.statGet(_id, pyrodactyl::stat::STAT_SPEED, num);
|
||||
++num;
|
||||
float playerSpeed = static_cast<float>(num);
|
||||
|
||||
Rect b = boundRect();
|
||||
|
||||
// Use to provide a bit of leeway with reaching the goal.
|
||||
_pathing.setNodeBufferDistance((b.w * b.w) / 2.0f);
|
||||
|
||||
// IF we either have a solution, have reached our destination, and it was our final destination OR
|
||||
// IF there is no solution OR
|
||||
// IF we haven't yet found a solution
|
||||
// THEN stop.
|
||||
if ((moveToLocPathfinding(_aiData._dest, playerSpeed, sc) && _pathing._solutionFound &&
|
||||
_pathing.getImmediateDest() == Vector2i(_pathing._destination.x, _pathing._destination.y)) ||
|
||||
_pathing._noSolution || !_pathing._solutionFound) {
|
||||
_aiData._dest._active = false;
|
||||
xVel(0.0f);
|
||||
yVel(0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Move towards a location without any path finding
|
||||
//------------------------------------------------------------------------
|
||||
bool Sprite::moveToLoc(Vector2i &dest, const float &velocity, const SpriteConstant &sc) {
|
||||
// Use the bound rectangle dimensions
|
||||
Rect b = boundRect();
|
||||
|
||||
// X axis
|
||||
if (b.x + b.w < dest.x)
|
||||
xVel(velocity * sc._walkVelMod.x);
|
||||
else if (b.x > dest.x)
|
||||
xVel(-velocity * sc._walkVelMod.x);
|
||||
else
|
||||
xVel(0.0f);
|
||||
|
||||
// Y axis
|
||||
if (b.y + b.h < dest.y)
|
||||
yVel(velocity * sc._walkVelMod.y);
|
||||
else if (b.y > dest.y)
|
||||
yVel(-velocity * sc._walkVelMod.y);
|
||||
else
|
||||
yVel(0.0f);
|
||||
|
||||
return b.contains(dest);
|
||||
}
|
||||
|
||||
// Move toward the location using pathfinding.
|
||||
bool Sprite::moveToLocPathfinding(Vector2i &dest, const float &velocity, const SpriteConstant &sc) {
|
||||
// Rect b = BoundRect();
|
||||
|
||||
Vector2i immediateDest = _pathing.getImmediateDest();
|
||||
|
||||
Vector2f vecTo = Vector2f((float)immediateDest.x, (float)immediateDest.y) - _pathing.getPosition();
|
||||
|
||||
// If the destination is not the pathing goal, we must reach it exactly before moving on.
|
||||
if (immediateDest != Vector2i(_pathing._destination.x, _pathing._destination.y)) {
|
||||
Timer fps;
|
||||
float deltaTime = 1.0f / (float)g_engine->_screenSettings->_fps;
|
||||
|
||||
// Project how far we will travel next frame.
|
||||
Vector2f velVec = Vector2f(sc._walkVelMod.x * velocity * deltaTime, sc._walkVelMod.y * velocity * deltaTime);
|
||||
|
||||
if (vecTo.magnitude() > velVec.magnitude()) {
|
||||
vecTo.normalize();
|
||||
|
||||
xVel(vecTo.x * sc._walkVelMod.x * velocity);
|
||||
yVel(vecTo.y * sc._walkVelMod.y * velocity);
|
||||
} else {
|
||||
xVel(0.0f);
|
||||
yVel(0.0f);
|
||||
}
|
||||
} else {
|
||||
Vector2i loc = _pathing.getImmediateDest();
|
||||
moveToLoc(loc, velocity, sc);
|
||||
}
|
||||
|
||||
// return(MoveToLoc(pathing.GetImmediateDest(), vel, sc) || (xVel() == 0.0f && yVel() == 0.0f));
|
||||
|
||||
return (xVel() == 0.0f && yVel() == 0.0f);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: AI routine for running to the nearest exit, then disappearing
|
||||
//------------------------------------------------------------------------
|
||||
void Sprite::flee(pyrodactyl::event::Info &info, Common::Array<pyrodactyl::level::Exit> &areaExit, const SpriteConstant &sc) {
|
||||
switch (_aiData._flee._state) {
|
||||
case FLEESTATE_GETNEARESTEXIT: {
|
||||
if (areaExit.empty()) {
|
||||
// No valid exits in the level
|
||||
_aiData._flee._state = FLEESTATE_CANTFLEE;
|
||||
break;
|
||||
} else {
|
||||
_aiData._flee._state = FLEESTATE_GETNEARESTEXIT;
|
||||
|
||||
// Standard way to find nearest exit
|
||||
int min_dist = INT_MAX;
|
||||
|
||||
// Find the nearest exit
|
||||
for (auto &i : areaExit) {
|
||||
// Compare distance to the rough center of each exit
|
||||
int dist = distance2D(_pos.x, _pos.y, i._dim._rect.x + i._dim._rect.w / 2, i._dim._rect.y + i._dim._rect.h / 2);
|
||||
if (dist < min_dist) {
|
||||
min_dist = dist;
|
||||
|
||||
// Set the destination of sprite to this exit
|
||||
_aiData.dest(i._dim._rect.x + i._dim._rect.w / 2, i._dim._rect.y + i._dim._rect.h / 2);
|
||||
|
||||
_pathing.setDestination(Vector2f((float)_aiData._dest.x, (float)_aiData._dest.y));
|
||||
}
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case FLEESTATE_RUNTOEXIT: {
|
||||
Rect b = boundRect();
|
||||
if (b.contains(_aiData._dest)) {
|
||||
// We have reached the exit, time to make the sprite disappear
|
||||
_aiData._flee._state = FLEESTATE_DISAPPEAR;
|
||||
break;
|
||||
} else {
|
||||
int num = 0;
|
||||
info.statGet(_id, pyrodactyl::stat::STAT_SPEED, num);
|
||||
++num;
|
||||
float velocity = static_cast<float>(num);
|
||||
|
||||
// MoveToLoc(_aiData.dest, vel, sc);
|
||||
moveToLocPathfinding(_aiData._dest, velocity, sc);
|
||||
}
|
||||
} break;
|
||||
case FLEESTATE_DISAPPEAR:
|
||||
_visible.result(false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: AI routine for fighting the player
|
||||
//------------------------------------------------------------------------
|
||||
void Sprite::attack(pyrodactyl::event::Info &info, Sprite &targetSp, const SpriteConstant &sc) {
|
||||
switch (_aiData._fight._state) {
|
||||
case FIGHTSTATE_GETNEXTMOVE: {
|
||||
_aiData._fight._state = FIGHTSTATE_GETINRANGE;
|
||||
_aiData._fight._delay.start();
|
||||
|
||||
uint size = _aiData._fight._attack.size();
|
||||
if (size > 1)
|
||||
_animSet._fight.next(_aiData._fight._attack[g_engine->getRandomNumber(_aiData._fight._attack.size())]);
|
||||
else if (size <= 0)
|
||||
_aiData._fight._state = FIGHTSTATE_CANTFIGHT;
|
||||
else
|
||||
_animSet._fight.next(_aiData._fight._attack[0]);
|
||||
}
|
||||
break;
|
||||
case FIGHTSTATE_GETINRANGE: {
|
||||
// Set destination path to the player location
|
||||
Rect b = targetSp.boundRect();
|
||||
Vector2i dest(b.x + b.w / 2, b.y + b.h / 2);
|
||||
setDestPathfinding(dest);
|
||||
|
||||
Rect p = boundRect();
|
||||
_pathing.setPosition(Vector2f((float)(p.x + p.w / 2), (float)p.y + p.h / 2));
|
||||
_pathing.update(0);
|
||||
|
||||
FightMove f;
|
||||
if (_animSet._fight.nextMove(f) && fightCollide(targetSp.boxV(), targetSp.boundRect(), f._ai._range, sc)) {
|
||||
if (_aiData._fight._delay.ticks() > f._ai._delay)
|
||||
_aiData._fight._state = FIGHTSTATE_EXECUTEMOVE;
|
||||
} else if (_input.idle())
|
||||
moveToDestPathfinding(info, sc);
|
||||
}
|
||||
break;
|
||||
case FIGHTSTATE_EXECUTEMOVE:
|
||||
updateMove(_animSet._fight.next());
|
||||
_aiData._fight._state = FIGHTSTATE_GETNEXTMOVE;
|
||||
_aiData._fight._delay.stop();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Sprite::flyAround(const Rect &camera, const SpriteConstant &sc) {
|
||||
// Is this sprite flying right now?
|
||||
if (_aiData._walk._enabled) {
|
||||
// We're flying towards the left edge
|
||||
if (xVel() < 0) {
|
||||
// Are we completely out of the left edge of the camera?
|
||||
if (x() < camera.x - w()) {
|
||||
_aiData._walk._enabled = false;
|
||||
|
||||
// Start the timer, set a semi-random time
|
||||
_aiData._walk._timer.target(sc._fly._delayMin + (g_engine->getRandomNumber(sc._fly._delayMax)));
|
||||
_aiData._walk._timer.start();
|
||||
}
|
||||
} else if (xVel() > 0) { // Flying towards the right edge
|
||||
// Are we completely out of the left edge of the camera?
|
||||
if (x() > camera.x + camera.w + w()) {
|
||||
_aiData._walk._enabled = false;
|
||||
|
||||
// Start the timer, set a semi-random time
|
||||
_aiData._walk._timer.target(sc._fly._delayMin + (g_engine->getRandomNumber(sc._fly._delayMax)));
|
||||
_aiData._walk._timer.start();
|
||||
}
|
||||
}
|
||||
|
||||
move(sc);
|
||||
} else {
|
||||
// Safety condition in case timer isn't running
|
||||
if (!_aiData._walk._timer.started())
|
||||
_aiData._walk._timer.start();
|
||||
|
||||
// Is it time to start flying?
|
||||
if (_aiData._walk._timer.targetReached()) {
|
||||
// Stop the timer
|
||||
_aiData._walk._timer.stop();
|
||||
|
||||
// Decide if the sprite flies from the left or right of the camera
|
||||
if (g_engine->getRandomNumber(1)) {
|
||||
// Fly in from the right
|
||||
x(camera.x + camera.w + sc._fly._start.x);
|
||||
xVel(-1.0f * sc._fly._vel.x);
|
||||
|
||||
// Sprite needs to face left
|
||||
_dir = DIRECTION_LEFT;
|
||||
} else {
|
||||
// Fly in from the left
|
||||
x(camera.x - w() - sc._fly._start.x);
|
||||
xVel(sc._fly._vel.x);
|
||||
|
||||
// Sprite needs to face right
|
||||
_dir = DIRECTION_RIGHT;
|
||||
}
|
||||
|
||||
y(camera.y + sc._fly._start.y + (g_engine->getRandomNumber(camera.h - (2 * sc._fly._start.y))));
|
||||
yVel(sc._fly._vel.y);
|
||||
|
||||
// Set state to flying
|
||||
_aiData._walk._enabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Crab
|
||||
118
engines/crab/ai/spriteai.h
Normal file
118
engines/crab/ai/spriteai.h
Normal file
@@ -0,0 +1,118 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is based on the CRAB engine
|
||||
*
|
||||
* Copyright (c) Arvind Raja Yadav
|
||||
*
|
||||
* Licensed under MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CRAB_SPRITEAI_H
|
||||
#define CRAB_SPRITEAI_H
|
||||
|
||||
#include "crab/ai/movement.h"
|
||||
#include "crab/PathfindingAgent.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
// class PathfindingAgent;
|
||||
namespace pyrodactyl {
|
||||
namespace ai {
|
||||
|
||||
// States of a fighting sprite
|
||||
enum AIFightState {
|
||||
FIGHTSTATE_GETNEXTMOVE,
|
||||
FIGHTSTATE_GETINRANGE,
|
||||
FIGHTSTATE_EXECUTEMOVE,
|
||||
FIGHTSTATE_CANTFIGHT
|
||||
};
|
||||
|
||||
// States of a fleeing sprite
|
||||
enum AIFleeState {
|
||||
FLEESTATE_GETNEARESTEXIT,
|
||||
FLEESTATE_RUNTOEXIT,
|
||||
FLEESTATE_DISAPPEAR,
|
||||
FLEESTATE_CANTFLEE
|
||||
};
|
||||
|
||||
struct SpriteAIData {
|
||||
// Data required for fighting
|
||||
struct FightData {
|
||||
// The state of the sprite
|
||||
AIFightState _state;
|
||||
|
||||
// Used to count down the time NPCs wait before their next move
|
||||
// Usually varies per move which is why we don't load target for it
|
||||
Timer _delay;
|
||||
|
||||
// The list of moves that can be performed while attacking
|
||||
Common::Array<uint> _attack;
|
||||
|
||||
FightData() {
|
||||
_state = FIGHTSTATE_GETNEXTMOVE;
|
||||
}
|
||||
} _fight;
|
||||
|
||||
// The pattern a peaceful sprite walks in
|
||||
MovementSet _walk;
|
||||
|
||||
// Data required to flee
|
||||
struct FleeData {
|
||||
AIFleeState _state;
|
||||
|
||||
FleeData() {
|
||||
_state = FLEESTATE_GETNEARESTEXIT;
|
||||
}
|
||||
} _flee;
|
||||
|
||||
// The next location the sprite has to reach
|
||||
// PLAYER: Used for adventure game style point-n-click movement
|
||||
// AI: Used for path-finding (usually to the player's location)
|
||||
struct Destination : public Vector2i {
|
||||
// Are we trying to reach the destination?
|
||||
bool _active;
|
||||
|
||||
Destination() {
|
||||
_active = false;
|
||||
}
|
||||
} _dest;
|
||||
|
||||
SpriteAIData() {}
|
||||
|
||||
void dest(const int &x, const int &y, const bool &active = true) {
|
||||
_dest.x = x;
|
||||
_dest.y = y;
|
||||
_dest._active = active;
|
||||
}
|
||||
|
||||
void dest(const Vector2i &v, const bool &active = true) {
|
||||
dest(v.x, v.y, active);
|
||||
}
|
||||
};
|
||||
} // End of namespace ai
|
||||
} // End of namespace pyrodactyl
|
||||
|
||||
} // End of namespace Crab
|
||||
|
||||
#endif // CRAB_SPRITEAI_H
|
||||
Reference in New Issue
Block a user