refactor: Refactor game objects
- Split Object class into Object and SpatialObject - Inherit Module and Area from Object - Move object creation into (Multiplayer)ObjectFactory class
This commit is contained in:
parent
c34eba71d0
commit
8890a1bd82
37 changed files with 562 additions and 357 deletions
|
@ -69,12 +69,14 @@ set(HEADERS
|
|||
src/game/multiplayer/creature.h
|
||||
src/game/multiplayer/door.h
|
||||
src/game/multiplayer/game.h
|
||||
src/game/multiplayer/module.h
|
||||
src/game/multiplayer/objectfactory.h
|
||||
src/game/multiplayer/util.h
|
||||
src/game/object/creature.h
|
||||
src/game/object/door.h
|
||||
src/game/object/factory.h
|
||||
src/game/object/object.h
|
||||
src/game/object/placeable.h
|
||||
src/game/object/spatial.h
|
||||
src/game/object/trigger.h
|
||||
src/game/object/waypoint.h
|
||||
src/game/room.h
|
||||
|
@ -179,13 +181,15 @@ set(SOURCES
|
|||
src/game/multiplayer/creature.cpp
|
||||
src/game/multiplayer/door.cpp
|
||||
src/game/multiplayer/game.cpp
|
||||
src/game/multiplayer/module.cpp
|
||||
src/game/multiplayer/objectfactory.cpp
|
||||
src/game/multiplayer/util.cpp
|
||||
src/game/navmesh.cpp
|
||||
src/game/object/creature.cpp
|
||||
src/game/object/door.cpp
|
||||
src/game/object/factory.cpp
|
||||
src/game/object/object.cpp
|
||||
src/game/object/placeable.cpp
|
||||
src/game/object/spatial.cpp
|
||||
src/game/object/trigger.cpp
|
||||
src/game/object/waypoint.cpp
|
||||
src/game/room.cpp
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
#include "area.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/format.hpp>
|
||||
|
||||
|
@ -33,10 +35,7 @@
|
|||
#include "../resources/visfile.h"
|
||||
#include "../script/execution.h"
|
||||
|
||||
#include "object/door.h"
|
||||
#include "object/placeable.h"
|
||||
#include "object/trigger.h"
|
||||
#include "object/waypoint.h"
|
||||
#include "object/factory.h"
|
||||
#include "script/routines.h"
|
||||
#include "script/util.h"
|
||||
|
||||
|
@ -63,7 +62,13 @@ static const char kPartyLeaderTag[] = "party-leader";
|
|||
static const char kPartyMember1Tag[] = "party-member-1";
|
||||
static const char kPartyMember2Tag[] = "party-member-2";
|
||||
|
||||
Area::Area(GameVersion version, const string &name) : _version(version), _name(name), _navMesh(new NavMesh()) {
|
||||
Area::Area(uint32_t id, GameVersion version, ObjectFactory *factory) :
|
||||
Object(id), _version(version), _objectFactory(factory), _navMesh(new NavMesh()) {
|
||||
|
||||
assert(_objectFactory);
|
||||
|
||||
_type = ObjectType::Area;
|
||||
|
||||
_objects.insert(make_pair(ObjectType::Creature, ObjectList()));
|
||||
_objects.insert(make_pair(ObjectType::Door, ObjectList()));
|
||||
_objects.insert(make_pair(ObjectType::Placeable, ObjectList()));
|
||||
|
@ -74,7 +79,9 @@ Area::Area(GameVersion version, const string &name) : _version(version), _name(n
|
|||
_renderLists.insert(make_pair(RenderListName::Transparent, RenderList()));
|
||||
}
|
||||
|
||||
void Area::load(const GffStruct &are, const GffStruct &git) {
|
||||
void Area::load(const string &name, const GffStruct &are, const GffStruct &git) {
|
||||
_name = name;
|
||||
|
||||
loadProperties(git.getStruct("AreaProperties"));
|
||||
loadVisibility();
|
||||
loadLayout();
|
||||
|
@ -82,20 +89,20 @@ void Area::load(const GffStruct &are, const GffStruct &git) {
|
|||
loadScripts(are);
|
||||
|
||||
for (auto &gffs : git.getList("Creature List")) {
|
||||
shared_ptr<Creature> creature(makeCreature());
|
||||
shared_ptr<Creature> creature(_objectFactory->newCreature());
|
||||
creature->load(gffs);
|
||||
landObject(*creature);
|
||||
creature->setSynchronize(true);
|
||||
_objects[ObjectType::Creature].push_back(move(creature));
|
||||
}
|
||||
for (auto &gffs : git.getList("Door List")) {
|
||||
shared_ptr<Door> door(makeDoor());
|
||||
shared_ptr<Door> door(_objectFactory->newDoor());
|
||||
door->load(gffs);
|
||||
door->setSynchronize(true);
|
||||
_objects[ObjectType::Door].push_back(move(door));
|
||||
}
|
||||
for (auto &gffs : git.getList("Placeable List")) {
|
||||
shared_ptr<Placeable> placeable(makePlaceable());
|
||||
shared_ptr<Placeable> placeable(_objectFactory->newPlaceable());
|
||||
placeable->load(gffs);
|
||||
if (placeable->walkmesh()) {
|
||||
_navMesh->add(placeable->walkmesh(), placeable->transform());
|
||||
|
@ -103,12 +110,12 @@ void Area::load(const GffStruct &are, const GffStruct &git) {
|
|||
_objects[ObjectType::Placeable].push_back(move(placeable));
|
||||
}
|
||||
for (auto &gffs : git.getList("WaypointList")) {
|
||||
shared_ptr<Waypoint> waypoint(makeWaypoint());
|
||||
shared_ptr<Waypoint> waypoint(_objectFactory->newWaypoint());
|
||||
waypoint->load(gffs);
|
||||
_objects[ObjectType::Waypoint].push_back(move(waypoint));
|
||||
}
|
||||
for (auto &gffs : git.getList("TriggerList")) {
|
||||
shared_ptr<Trigger> trigger(makeTrigger());
|
||||
shared_ptr<Trigger> trigger(_objectFactory->newTrigger());
|
||||
trigger->load(gffs);
|
||||
_objects[ObjectType::Trigger].push_back(move(trigger));
|
||||
}
|
||||
|
@ -120,26 +127,6 @@ void Area::load(const GffStruct &are, const GffStruct &git) {
|
|||
});
|
||||
}
|
||||
|
||||
shared_ptr<Creature> Area::makeCreature(uint32_t id) {
|
||||
return make_unique<Creature>(id > 0 ? id : _idCounter++);
|
||||
}
|
||||
|
||||
shared_ptr<Door> Area::makeDoor() {
|
||||
return make_unique<Door>(_idCounter++);
|
||||
}
|
||||
|
||||
shared_ptr<Placeable> Area::makePlaceable() {
|
||||
return make_unique<Placeable>(_idCounter++);
|
||||
}
|
||||
|
||||
shared_ptr<Waypoint> Area::makeWaypoint() {
|
||||
return make_unique<Waypoint>(_idCounter++);
|
||||
}
|
||||
|
||||
shared_ptr<Trigger> Area::makeTrigger() {
|
||||
return make_unique<Trigger>(_idCounter++);
|
||||
}
|
||||
|
||||
void Area::loadProperties(const GffStruct &gffs) {
|
||||
ResourceManager &resources = ResourceManager::instance();
|
||||
shared_ptr<TwoDaTable> musicTable(resources.find2DA("ambientmusic"));
|
||||
|
@ -198,7 +185,7 @@ void Area::loadScripts(const GffStruct &are) {
|
|||
_scripts[ScriptType::OnUserDefined] = are.getString("OnUserDefined");
|
||||
}
|
||||
|
||||
void Area::landObject(Object &object) {
|
||||
void Area::landObject(SpatialObject &object) {
|
||||
glm::vec3 position(object.position());
|
||||
if (findElevationAt(position, position.z)) {
|
||||
object.setPosition(position);
|
||||
|
@ -239,7 +226,7 @@ void Area::loadParty(const PartyConfiguration &party, const glm::vec3 &position,
|
|||
}
|
||||
|
||||
shared_ptr<Creature> Area::makeCharacter(const CreatureConfiguration &character, const string &tag, const glm::vec3 &position, float heading) {
|
||||
shared_ptr<Creature> creature(makeCreature());
|
||||
shared_ptr<Creature> creature(_objectFactory->newCreature());
|
||||
creature->setTag(tag);
|
||||
creature->load(character);
|
||||
creature->setPosition(position);
|
||||
|
@ -341,7 +328,7 @@ bool Area::moveCreatureTowards(Creature &creature, const glm::vec3 &point, float
|
|||
newPosition.x += creature.runSpeed() * dir.x * dt;
|
||||
newPosition.y += creature.runSpeed() * dir.y * dt;
|
||||
|
||||
Object *obstacle = nullptr;
|
||||
SpatialObject *obstacle = nullptr;
|
||||
glm::vec3 intersection(0.0f);
|
||||
|
||||
if (findObstacleByAABB(position, newPosition + 1.0f * dir, kObstacleCreature, &creature, &obstacle)) {
|
||||
|
@ -404,7 +391,7 @@ void Area::signalEvent(int eventId) {
|
|||
return;
|
||||
}
|
||||
if (!_scripts[ScriptType::OnUserDefined].empty()) {
|
||||
runScript(_scripts[ScriptType::OnUserDefined], kObjectArea, kObjectInvalid, it->second.eventNumber);
|
||||
runScript(_scripts[ScriptType::OnUserDefined], _id, kObjectInvalid, it->second.eventNumber);
|
||||
}
|
||||
_events.erase(it);
|
||||
}
|
||||
|
@ -412,7 +399,7 @@ void Area::signalEvent(int eventId) {
|
|||
void Area::runOnEnterScript() {
|
||||
if (_scriptsEnabled) {
|
||||
if (!_scripts[ScriptType::OnEnter].empty()) {
|
||||
runScript(_scripts[ScriptType::OnEnter], kObjectArea, _player->id(), -1);
|
||||
runScript(_scripts[ScriptType::OnEnter], _id, _player->id(), -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -431,7 +418,7 @@ void Area::addToDebugContext(const RenderListItem &item, const UpdateContext &up
|
|||
debugCtx.objects.push_back(move(object));
|
||||
}
|
||||
|
||||
void Area::addToDebugContext(const Object &object, const UpdateContext &updateCtx, DebugContext &debugCtx) const {
|
||||
void Area::addToDebugContext(const SpatialObject &object, const UpdateContext &updateCtx, DebugContext &debugCtx) const {
|
||||
glm::vec4 viewport(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
glm::vec3 position(object.position());
|
||||
|
||||
|
@ -476,8 +463,8 @@ void Area::loadState(const GameState &state) {
|
|||
}
|
||||
}
|
||||
|
||||
shared_ptr<Object> Area::find(uint32_t id) const {
|
||||
shared_ptr<Object> object;
|
||||
shared_ptr<SpatialObject> Area::find(uint32_t id) const {
|
||||
shared_ptr<SpatialObject> object;
|
||||
for (auto &list : _objects) {
|
||||
object = find(id, list.first);
|
||||
if (object) return object;
|
||||
|
@ -486,8 +473,8 @@ shared_ptr<Object> Area::find(uint32_t id) const {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
shared_ptr<Object> Area::find(const string &tag, int nth) const {
|
||||
shared_ptr<Object> object;
|
||||
shared_ptr<SpatialObject> Area::find(const string &tag, int nth) const {
|
||||
shared_ptr<SpatialObject> object;
|
||||
for (auto &list : _objects) {
|
||||
object = find(tag, list.first, nth);
|
||||
if (object) return object;
|
||||
|
@ -496,18 +483,18 @@ shared_ptr<Object> Area::find(const string &tag, int nth) const {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
shared_ptr<Object> Area::find(uint32_t id, ObjectType type) const {
|
||||
shared_ptr<SpatialObject> Area::find(uint32_t id, ObjectType type) const {
|
||||
const ObjectList &list = _objects.find(type)->second;
|
||||
|
||||
auto it = find_if(
|
||||
list.begin(),
|
||||
list.end(),
|
||||
[&id](const shared_ptr<Object> &object) { return object->id() == id; });
|
||||
[&id](const shared_ptr<SpatialObject> &object) { return object->id() == id; });
|
||||
|
||||
return it != list.end() ? *it : nullptr;
|
||||
}
|
||||
|
||||
shared_ptr<Object> Area::find(const string &tag, ObjectType type, int nth) const {
|
||||
shared_ptr<SpatialObject> Area::find(const string &tag, ObjectType type, int nth) const {
|
||||
const ObjectList &list = _objects.find(type)->second;
|
||||
int idx = 0;
|
||||
|
||||
|
@ -518,8 +505,8 @@ shared_ptr<Object> Area::find(const string &tag, ObjectType type, int nth) const
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bool Area::findObstacleByWalkmesh(const glm::vec3 &from, const glm::vec3 &to, int mask, glm::vec3 &intersection, Object **obstacle) const {
|
||||
vector<pair<Object *, float>> candidates;
|
||||
bool Area::findObstacleByWalkmesh(const glm::vec3 &from, const glm::vec3 &to, int mask, glm::vec3 &intersection, SpatialObject **obstacle) const {
|
||||
vector<pair<SpatialObject *, float>> candidates;
|
||||
|
||||
for (auto &list : _objects) {
|
||||
if (list.first != ObjectType::Door && list.first != ObjectType::Placeable) continue;
|
||||
|
@ -540,10 +527,10 @@ bool Area::findObstacleByWalkmesh(const glm::vec3 &from, const glm::vec3 &to, in
|
|||
sort(
|
||||
candidates.begin(),
|
||||
candidates.end(),
|
||||
[](const pair<Object *, float> &left, const pair<Object *, float> &right) { return left.second < right.second; });
|
||||
[](const pair<SpatialObject *, float> &left, const pair<SpatialObject *, float> &right) { return left.second < right.second; });
|
||||
|
||||
for (auto &pair : candidates) {
|
||||
Object &object = *pair.first;
|
||||
SpatialObject &object = *pair.first;
|
||||
|
||||
glm::mat4 invObjectTransform(glm::inverse(object.transform()));
|
||||
glm::vec3 relFrom(invObjectTransform * glm::vec4(from, 1.0f));
|
||||
|
@ -573,8 +560,8 @@ bool Area::findObstacleByWalkmesh(const glm::vec3 &from, const glm::vec3 &to, in
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Area::findObstacleByAABB(const glm::vec3 &from, const glm::vec3 &to, int mask, const Object *except, Object **obstacle) const {
|
||||
vector<pair<Object *, float>> candidates;
|
||||
bool Area::findObstacleByAABB(const glm::vec3 &from, const glm::vec3 &to, int mask, const SpatialObject *except, SpatialObject **obstacle) const {
|
||||
vector<pair<SpatialObject *, float>> candidates;
|
||||
|
||||
for (auto &list : _objects) {
|
||||
if (list.first != ObjectType::Creature &&
|
||||
|
@ -600,10 +587,10 @@ bool Area::findObstacleByAABB(const glm::vec3 &from, const glm::vec3 &to, int ma
|
|||
sort(
|
||||
candidates.begin(),
|
||||
candidates.end(),
|
||||
[](const pair<Object *, float> &left, const pair<Object *, float> &right) { return left.second < right.second; });
|
||||
[](const pair<SpatialObject *, float> &left, const pair<SpatialObject *, float> &right) { return left.second < right.second; });
|
||||
|
||||
for (auto &pair : candidates) {
|
||||
Object *object = pair.first;
|
||||
SpatialObject *object = pair.first;
|
||||
AABB aabb(object->model()->model()->aabb() * object->transform());
|
||||
float distance = 0.0f;
|
||||
|
||||
|
@ -620,7 +607,7 @@ bool Area::findElevationAt(const glm::vec3 &position, float &z) const {
|
|||
glm::vec3 from(position + glm::vec3(0.0f, 0.0f, kElevationTestOffset));
|
||||
glm::vec3 to(from + glm::vec3(0.0f, 0.0f, -kElevationTestDistance));
|
||||
glm::vec3 intersection(0.0f);
|
||||
Object *obstacle = nullptr;
|
||||
SpatialObject *obstacle = nullptr;
|
||||
|
||||
if (findObstacleByWalkmesh(from, to, kObstacleDoor | kObstaclePlaceable, intersection, &obstacle)) {
|
||||
return false;
|
||||
|
@ -648,19 +635,19 @@ const string &Area::music() const {
|
|||
return _music;
|
||||
}
|
||||
|
||||
shared_ptr<Object> Area::player() const {
|
||||
shared_ptr<SpatialObject> Area::player() const {
|
||||
return _player;
|
||||
}
|
||||
|
||||
shared_ptr<Object> Area::partyLeader() const {
|
||||
shared_ptr<SpatialObject> Area::partyLeader() const {
|
||||
return _partyLeader;
|
||||
}
|
||||
|
||||
shared_ptr<Object> Area::partyMember1() const {
|
||||
shared_ptr<SpatialObject> Area::partyMember1() const {
|
||||
return _partyMember1;
|
||||
}
|
||||
|
||||
shared_ptr<Object> Area::partyMember2() const {
|
||||
shared_ptr<SpatialObject> Area::partyMember2() const {
|
||||
return _partyMember2;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,19 +42,15 @@ namespace reone {
|
|||
|
||||
namespace game {
|
||||
|
||||
typedef std::vector<std::shared_ptr<Object>> ObjectList;
|
||||
typedef std::vector<std::shared_ptr<SpatialObject>> ObjectList;
|
||||
|
||||
/*
|
||||
* Game object container. Building block of a module.
|
||||
*
|
||||
* @see reone::game::Module
|
||||
* @see reone::game::Object
|
||||
*/
|
||||
class Area {
|
||||
class ObjectFactory;
|
||||
|
||||
class Area : public Object {
|
||||
public:
|
||||
Area(resources::GameVersion version, const std::string &name);
|
||||
Area(uint32_t id, resources::GameVersion version, ObjectFactory *objectFactory);
|
||||
|
||||
void load(const resources::GffStruct &are, const resources::GffStruct &git);
|
||||
void load(const std::string &name, const resources::GffStruct &are, const resources::GffStruct &git);
|
||||
void loadParty(const PartyConfiguration &party, const glm::vec3 &position, float heading);
|
||||
void runOnEnterScript();
|
||||
|
||||
|
@ -76,25 +72,25 @@ public:
|
|||
void loadState(const GameState &state);
|
||||
|
||||
// Object search
|
||||
std::shared_ptr<Object> find(uint32_t id) const;
|
||||
std::shared_ptr<Object> find(const std::string &tag, int nth = 0) const;
|
||||
std::shared_ptr<Object> find(uint32_t id, ObjectType type) const;
|
||||
std::shared_ptr<Object> find(const std::string &tag, ObjectType type, int nth = 0) const;
|
||||
bool findObstacleByWalkmesh(const glm::vec3 &from, const glm::vec3 &to, int mask, glm::vec3 &intersection, Object **obstacle) const;
|
||||
bool findObstacleByAABB(const glm::vec3 &from, const glm::vec3 &to, int mask, const Object *except, Object **obstacle) const;
|
||||
|
||||
// Setters
|
||||
void setDebugMode(DebugMode mode);
|
||||
std::shared_ptr<SpatialObject> find(uint32_t id) const;
|
||||
std::shared_ptr<SpatialObject> find(const std::string &tag, int nth = 0) const;
|
||||
std::shared_ptr<SpatialObject> find(uint32_t id, ObjectType type) const;
|
||||
std::shared_ptr<SpatialObject> find(const std::string &tag, ObjectType type, int nth = 0) const;
|
||||
bool findObstacleByWalkmesh(const glm::vec3 &from, const glm::vec3 &to, int mask, glm::vec3 &intersection, SpatialObject **obstacle) const;
|
||||
bool findObstacleByAABB(const glm::vec3 &from, const glm::vec3 &to, int mask, const SpatialObject *except, SpatialObject **obstacle) const;
|
||||
|
||||
// General getters
|
||||
const render::CameraStyle &cameraStyle() const;
|
||||
const std::string &music() const;
|
||||
|
||||
// Party getters
|
||||
std::shared_ptr<Object> player() const;
|
||||
std::shared_ptr<Object> partyLeader() const;
|
||||
std::shared_ptr<Object> partyMember1() const;
|
||||
std::shared_ptr<Object> partyMember2() const;
|
||||
std::shared_ptr<SpatialObject> player() const;
|
||||
std::shared_ptr<SpatialObject> partyLeader() const;
|
||||
std::shared_ptr<SpatialObject> partyMember1() const;
|
||||
std::shared_ptr<SpatialObject> partyMember2() const;
|
||||
|
||||
// Setters
|
||||
void setDebugMode(DebugMode mode);
|
||||
|
||||
// Callbacks
|
||||
void setOnModuleTransition(const std::function<void(const std::string &, const std::string &)> &fn);
|
||||
|
@ -102,24 +98,19 @@ public:
|
|||
void setOnStartDialog(const std::function<void(const Object &, const std::string &)> &fn);
|
||||
|
||||
protected:
|
||||
uint32_t _idCounter { 1000 };
|
||||
ObjectFactory *_objectFactory { nullptr };
|
||||
std::map<ObjectType, ObjectList> _objects;
|
||||
bool _scriptsEnabled { true };
|
||||
std::function<void()> _onPlayerChanged;
|
||||
|
||||
// Party
|
||||
std::shared_ptr<Object> _player;
|
||||
std::shared_ptr<Object> _partyLeader;
|
||||
std::shared_ptr<Object> _partyMember1;
|
||||
std::shared_ptr<Object> _partyMember2;
|
||||
std::shared_ptr<SpatialObject> _player;
|
||||
std::shared_ptr<SpatialObject> _partyLeader;
|
||||
std::shared_ptr<SpatialObject> _partyMember1;
|
||||
std::shared_ptr<SpatialObject> _partyMember2;
|
||||
|
||||
void landObject(Object &object);
|
||||
void landObject(SpatialObject &object);
|
||||
|
||||
virtual std::shared_ptr<Creature> makeCreature(uint32_t id = 0);
|
||||
virtual std::shared_ptr<Door> makeDoor();
|
||||
virtual std::shared_ptr<Placeable> makePlaceable();
|
||||
virtual std::shared_ptr<Waypoint> makeWaypoint();
|
||||
virtual std::shared_ptr<Trigger> makeTrigger();
|
||||
virtual void updateCreature(Creature &creature, float dt);
|
||||
|
||||
private:
|
||||
|
@ -171,7 +162,7 @@ private:
|
|||
void updateCreaturePath(Creature &creature, const glm::vec3 &dest);
|
||||
void fillRenderLists(const glm::vec3 &cameraPosition);
|
||||
void addToDebugContext(const render::RenderListItem &item, const UpdateContext &updateCtx, DebugContext &debugCtx) const;
|
||||
void addToDebugContext(const Object &object, const UpdateContext &updateCtx, DebugContext &debugCtx) const;
|
||||
void addToDebugContext(const SpatialObject &object, const UpdateContext &updateCtx, DebugContext &debugCtx) const;
|
||||
bool findElevationAt(const glm::vec3 &position, float &z) const;
|
||||
|
||||
// Loading
|
||||
|
|
|
@ -40,7 +40,10 @@ void Area::updateCreature(Creature &creature, float dt) {
|
|||
switch (action.type) {
|
||||
case Creature::ActionType::MoveToPoint:
|
||||
case Creature::ActionType::Follow: {
|
||||
glm::vec3 dest = (action.type == Creature::ActionType::Follow || action.object) ? action.object->position() : action.point;
|
||||
SpatialObject *spatial = dynamic_cast<SpatialObject *>(action.object.get());
|
||||
assert(spatial);
|
||||
|
||||
glm::vec3 dest = (action.type == Creature::ActionType::Follow || action.object) ? spatial->position() : action.point;
|
||||
bool reached = navigateCreature(creature, dest, action.distance, dt);
|
||||
if (reached && action.type == Creature::ActionType::MoveToPoint) {
|
||||
creature.popCurrentAction();
|
||||
|
|
|
@ -86,7 +86,7 @@ void Area::render() const {
|
|||
|
||||
for (auto &object : list.second) {
|
||||
shared_ptr<ModelInstance> model(object->model());
|
||||
if (!model) return;
|
||||
if (!model) continue;
|
||||
|
||||
aabb.render(model->model()->aabb(), object->transform());
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "../core/streamutil.h"
|
||||
#include "../resources/resources.h"
|
||||
|
||||
#include "object/factory.h"
|
||||
#include "script/routines.h"
|
||||
#include "util.h"
|
||||
|
||||
|
@ -56,6 +57,12 @@ Game::Game(GameVersion version, const fs::path &path, const Options &opts) :
|
|||
_path(path),
|
||||
_opts(opts),
|
||||
_renderWindow(opts.graphics, this) {
|
||||
|
||||
initObjectFactory();
|
||||
}
|
||||
|
||||
void Game::initObjectFactory() {
|
||||
_objectFactory = make_unique<ObjectFactory>(_version, _opts);
|
||||
}
|
||||
|
||||
int Game::run() {
|
||||
|
@ -188,10 +195,10 @@ void Game::loadModule(const string &name, const PartyConfiguration &party, strin
|
|||
|
||||
shared_ptr<GffStruct> ifo(ResMan.findGFF("module", ResourceType::ModuleInfo));
|
||||
|
||||
_module = makeModule(name);
|
||||
_module = _objectFactory->newModule();
|
||||
configureModule();
|
||||
|
||||
_module->load(*ifo);
|
||||
_module->load(name, *ifo);
|
||||
_module->loadParty(party, entry);
|
||||
_module->area().loadState(_state);
|
||||
_module->initGL();
|
||||
|
@ -254,10 +261,10 @@ void Game::onDialogReplyPicked(uint32_t index) {
|
|||
}
|
||||
|
||||
void Game::onDialogSpeakerChanged(uint32_t from, uint32_t to) {
|
||||
shared_ptr<Object> player(_module->area().player());
|
||||
shared_ptr<Object> partyLeader(_module->area().partyLeader());
|
||||
shared_ptr<Object> prevSpeaker = from != 0 ? _module->area().find(from, ObjectType::Creature) : nullptr;
|
||||
shared_ptr<Object> speaker = to != 0 ? _module->area().find(to, ObjectType::Creature) : nullptr;
|
||||
shared_ptr<SpatialObject> player(_module->area().player());
|
||||
shared_ptr<SpatialObject> partyLeader(_module->area().partyLeader());
|
||||
shared_ptr<SpatialObject> prevSpeaker = from != 0 ? _module->area().find(from, ObjectType::Creature) : nullptr;
|
||||
shared_ptr<SpatialObject> speaker = to != 0 ? _module->area().find(to, ObjectType::Creature) : nullptr;
|
||||
if (speaker == partyLeader) return;
|
||||
|
||||
debug(boost::format("Game: dialog speaker: \"%s\"") % (speaker ? speaker->tag() : ""));
|
||||
|
@ -282,10 +289,6 @@ void Game::onDialogFinished() {
|
|||
_screen = Screen::InGame;
|
||||
}
|
||||
|
||||
const shared_ptr<Module> Game::makeModule(const string &name) {
|
||||
return make_shared<Module>(name, _version, _opts.graphics);
|
||||
}
|
||||
|
||||
void Game::configureModule() {
|
||||
_module->setOnCameraChanged([this](CameraType type) {
|
||||
_renderWindow.setRelativeMouseMode(type == CameraType::FirstPerson);
|
||||
|
@ -490,6 +493,14 @@ void Game::delayCommand(uint32_t timestamp, const ExecutionContext &ctx) {
|
|||
_module->area().delayCommand(timestamp, ctx);
|
||||
}
|
||||
|
||||
Module *Game::getModule() {
|
||||
return _module.get();
|
||||
}
|
||||
|
||||
Area *Game::getArea() {
|
||||
return &_module->area();
|
||||
}
|
||||
|
||||
shared_ptr<Object> Game::getObjectById(uint32_t id) {
|
||||
return _module->area().find(id);
|
||||
}
|
||||
|
@ -510,8 +521,14 @@ int Game::eventUserDefined(int eventNumber) {
|
|||
return _module->area().eventUserDefined(eventNumber);
|
||||
}
|
||||
|
||||
void Game::signalEvent(int eventId) {
|
||||
_module->area().signalEvent(eventId);
|
||||
void Game::signalEvent(uint32_t objectId, int eventId) {
|
||||
assert(objectId >= 2);
|
||||
Area &area = _module->area();
|
||||
if (objectId != area.id()) {
|
||||
warn("Game: event object is not an area");
|
||||
return;
|
||||
}
|
||||
area.signalEvent(eventId);
|
||||
}
|
||||
|
||||
bool Game::getGlobalBoolean(const string &name) const {
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "gui/mainmenu.h"
|
||||
#include "gui/portraitsel.h"
|
||||
|
||||
#include "area.h"
|
||||
#include "module.h"
|
||||
|
||||
namespace reone {
|
||||
|
@ -64,9 +65,11 @@ public:
|
|||
|
||||
// Events
|
||||
int eventUserDefined(int eventNumber) override;
|
||||
void signalEvent(int eventId) override;
|
||||
void signalEvent(uint32_t objectId, int eventId) override;
|
||||
|
||||
// Objects
|
||||
Module *getModule() override;
|
||||
Area *getArea() override;
|
||||
std::shared_ptr<Object> getObjectById(uint32_t id) override;
|
||||
std::shared_ptr<Object> getObjectByTag(const std::string &tag, int nth) override;
|
||||
std::shared_ptr<Object> getWaypointByTag(const std::string &tag) override;
|
||||
|
@ -101,14 +104,15 @@ protected:
|
|||
|
||||
resources::GameVersion _version { resources::GameVersion::KotOR };
|
||||
Options _opts;
|
||||
std::unique_ptr<ObjectFactory> _objectFactory;
|
||||
std::shared_ptr<Module> _module;
|
||||
std::string _nextModule;
|
||||
Screen _screen { Screen::None };
|
||||
std::shared_ptr<DialogGui> _dialogGui;
|
||||
bool _pickDialogReplyEnabled { true };
|
||||
|
||||
virtual void initObjectFactory();
|
||||
virtual void configure();
|
||||
virtual const std::shared_ptr<Module> makeModule(const std::string &name);
|
||||
virtual void configureModule();
|
||||
virtual void update();
|
||||
virtual void loadNextModule();
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "../resources/resources.h"
|
||||
|
||||
#include "object/door.h"
|
||||
#include "object/factory.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace std::placeholders;
|
||||
|
@ -40,18 +41,17 @@ namespace game {
|
|||
|
||||
static const float kDefaultFieldOfView = 75.0f;
|
||||
|
||||
Module::Module(
|
||||
const string &name,
|
||||
GameVersion version,
|
||||
const GraphicsOptions &opts
|
||||
) :
|
||||
_name(name),
|
||||
_version(version),
|
||||
_opts(opts),
|
||||
_cameraAspect(opts.width / static_cast<float>(opts.height)) {
|
||||
Module::Module(uint32_t id, GameVersion version, ObjectFactory *objectFactory, const GraphicsOptions &opts) :
|
||||
Object(id), _version(version), _objectFactory(objectFactory), _opts(opts) {
|
||||
|
||||
assert(_objectFactory);
|
||||
_type = ObjectType::Module;
|
||||
_cameraAspect = opts.width / static_cast<float>(opts.height);
|
||||
}
|
||||
|
||||
void Module::load(const GffStruct &ifo) {
|
||||
void Module::load(const string &name, const GffStruct &ifo) {
|
||||
_name = name;
|
||||
|
||||
loadInfo(ifo);
|
||||
loadArea(ifo);
|
||||
loadCameras();
|
||||
|
@ -78,7 +78,7 @@ void Module::loadArea(const GffStruct &ifo) {
|
|||
shared_ptr<GffStruct> are(resources.findGFF(_info.entryArea, ResourceType::Area));
|
||||
shared_ptr<GffStruct> git(resources.findGFF(_info.entryArea, ResourceType::GameInstance));
|
||||
|
||||
shared_ptr<Area> area(makeArea());
|
||||
shared_ptr<Area> area(_objectFactory->newArea());
|
||||
area->setOnModuleTransition([this](const string &module, const string &entry) {
|
||||
if (_onModuleTransition) {
|
||||
_onModuleTransition(module, entry);
|
||||
|
@ -99,14 +99,10 @@ void Module::loadArea(const GffStruct &ifo) {
|
|||
|
||||
_startDialog(object, finalResRef);
|
||||
});
|
||||
area->load(*are, *git);
|
||||
area->load(_info.entryArea, *are, *git);
|
||||
_area = move(area);
|
||||
}
|
||||
|
||||
const shared_ptr<Area> Module::makeArea() const {
|
||||
return make_shared<Area>(_version, _info.entryArea);
|
||||
}
|
||||
|
||||
void Module::loadCameras() {
|
||||
glm::vec3 position(_info.entryPosition);
|
||||
position.z += 1.7f;
|
||||
|
@ -130,7 +126,7 @@ void Module::loadCameras() {
|
|||
}
|
||||
|
||||
bool Module::findObstacle(const glm::vec3 &from, const glm::vec3 &to, glm::vec3 &intersection) const {
|
||||
Object *obstacle = nullptr;
|
||||
SpatialObject *obstacle = nullptr;
|
||||
if (_area->findObstacleByWalkmesh(from, to, kObstacleRoom | kObstacleDoor, intersection, &obstacle)) {
|
||||
return true;
|
||||
}
|
||||
|
@ -159,7 +155,7 @@ void Module::getEntryPoint(const string &waypoint, glm::vec3 &position, float &h
|
|||
heading = _info.entryHeading;
|
||||
|
||||
if (!waypoint.empty()) {
|
||||
shared_ptr<Object> object(_area->find(waypoint, ObjectType::Waypoint));
|
||||
shared_ptr<SpatialObject> object(_area->find(waypoint, ObjectType::Waypoint));
|
||||
if (object) {
|
||||
position = object->position();
|
||||
heading = object->heading();
|
||||
|
@ -168,14 +164,14 @@ void Module::getEntryPoint(const string &waypoint, glm::vec3 &position, float &h
|
|||
}
|
||||
|
||||
void Module::update3rdPersonCameraTarget() {
|
||||
shared_ptr<Object> player(_area->player());
|
||||
shared_ptr<SpatialObject> player(_area->player());
|
||||
if (!player) return;
|
||||
|
||||
_thirdPersonCamera->setTargetPosition(player->position() + player->model()->getNodeAbsolutePosition("camerahook"));
|
||||
}
|
||||
|
||||
void Module::update3rdPersonCameraHeading() {
|
||||
shared_ptr<Object> player(_area->player());
|
||||
shared_ptr<SpatialObject> player(_area->player());
|
||||
if (!player) return;
|
||||
|
||||
_thirdPersonCamera->setHeading(player->heading());
|
||||
|
@ -218,9 +214,9 @@ bool Module::handleMouseButtonUp(const SDL_MouseButtonEvent &event) {
|
|||
glm::vec3 fromWorld(glm::unProject(glm::vec3(event.x, _opts.height - event.y, 0.0f), camera->view(), camera->projection(), viewport));
|
||||
glm::vec3 toWorld(glm::unProject(glm::vec3(event.x, _opts.height - event.y, 1.0f), camera->view(), camera->projection(), viewport));
|
||||
|
||||
shared_ptr<Object> player(_area->player());
|
||||
Object *except = player ? player.get() : nullptr;
|
||||
Object *obstacle = nullptr;
|
||||
shared_ptr<SpatialObject> player(_area->player());
|
||||
SpatialObject *except = player ? player.get() : nullptr;
|
||||
SpatialObject *obstacle = nullptr;
|
||||
|
||||
if (_area->findObstacleByAABB(fromWorld, toWorld, kObstacleCreature | kObstacleDoor | kObstaclePlaceable, except, &obstacle)) {
|
||||
assert(obstacle);
|
||||
|
|
|
@ -39,33 +39,23 @@ struct ModuleInfo {
|
|||
float entryHeading { 0.0f };
|
||||
};
|
||||
|
||||
/**
|
||||
* Isolated portion of the game.
|
||||
*
|
||||
* @see reone::game::Area
|
||||
*/
|
||||
class Module : public render::IEventHandler {
|
||||
class Module : public Object {
|
||||
public:
|
||||
Module(
|
||||
const std::string &name,
|
||||
resources::GameVersion version,
|
||||
const render::GraphicsOptions &opts);
|
||||
Module(uint32_t id, resources::GameVersion version, ObjectFactory *objectFactory, const render::GraphicsOptions &opts);
|
||||
|
||||
// Loading
|
||||
void load(const resources::GffStruct &ifo);
|
||||
void load(const std::string &name, const resources::GffStruct &ifo);
|
||||
void loadParty(const PartyConfiguration &party, const std::string &entry = "");
|
||||
|
||||
// Rendering
|
||||
void initGL();
|
||||
void render() const;
|
||||
|
||||
bool handle(const SDL_Event &event) override;
|
||||
bool handle(const SDL_Event &event);
|
||||
void update(float dt, GuiContext &guiCtx);
|
||||
void update3rdPersonCameraHeading();
|
||||
void saveTo(GameState &state) const;
|
||||
|
||||
virtual const std::shared_ptr<Area> makeArea() const;
|
||||
|
||||
// Getters
|
||||
const std::string &name() const;
|
||||
bool loaded() const;
|
||||
|
@ -85,6 +75,7 @@ protected:
|
|||
ModuleInfo _info;
|
||||
|
||||
private:
|
||||
ObjectFactory *_objectFactory { nullptr };
|
||||
std::string _name;
|
||||
bool _loaded { false };
|
||||
render::GraphicsOptions _opts;
|
||||
|
|
|
@ -17,11 +17,11 @@
|
|||
|
||||
#include "area.h"
|
||||
|
||||
#include "creature.h"
|
||||
#include "door.h"
|
||||
#include "../object/factory.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
using namespace reone::resources;
|
||||
using namespace reone::net;
|
||||
|
||||
namespace reone {
|
||||
|
@ -29,24 +29,17 @@ namespace reone {
|
|||
namespace game {
|
||||
|
||||
MultiplayerArea::MultiplayerArea(
|
||||
uint32_t id,
|
||||
GameVersion version,
|
||||
MultiplayerMode mode,
|
||||
resources::GameVersion version,
|
||||
const string &name,
|
||||
IMultiplayerCallbacks *mpCallbacks
|
||||
ObjectFactory *objectFactory,
|
||||
IMultiplayerCallbacks *callbacks
|
||||
) :
|
||||
Area(version, name), _callbacks(mpCallbacks) {
|
||||
Area(id, version, objectFactory), _callbacks(callbacks) {
|
||||
|
||||
_scriptsEnabled = mode == MultiplayerMode::Server;
|
||||
}
|
||||
|
||||
shared_ptr<Creature> MultiplayerArea::makeCreature(uint32_t id) {
|
||||
return make_unique<MultiplayerCreature>(id > 0 ? id : _idCounter++, _callbacks);
|
||||
}
|
||||
|
||||
shared_ptr<Door> MultiplayerArea::makeDoor() {
|
||||
return make_unique<MultiplayerDoor>(_idCounter++, _callbacks);
|
||||
}
|
||||
|
||||
void MultiplayerArea::updateCreature(Creature &creature, float dt) {
|
||||
if (static_cast<MultiplayerCreature &>(creature).isControlled()) return;
|
||||
|
||||
|
@ -81,7 +74,7 @@ void MultiplayerArea::execute(const Command &cmd) {
|
|||
}
|
||||
}
|
||||
void MultiplayerArea::executeLoadCreature(const Command &cmd) {
|
||||
shared_ptr<Creature> creature(makeCreature(cmd.objectId()));
|
||||
shared_ptr<Creature> creature(new MultiplayerCreature(cmd.objectId(), _callbacks));
|
||||
creature->setTag(cmd.tag());
|
||||
|
||||
for (auto &item : cmd.equipment()) {
|
||||
|
@ -136,7 +129,7 @@ void MultiplayerArea::executeSetPlayerRole(const Command &cmd) {
|
|||
}
|
||||
|
||||
void MultiplayerArea::executeSetObjectTransform(const Command &cmd) {
|
||||
shared_ptr<Object> object(find(cmd.objectId(), ObjectType::Creature));
|
||||
shared_ptr<SpatialObject> object(find(cmd.objectId(), ObjectType::Creature));
|
||||
if (object) {
|
||||
object->setSynchronize(false);
|
||||
object->setPosition(cmd.position());
|
||||
|
@ -146,7 +139,7 @@ void MultiplayerArea::executeSetObjectTransform(const Command &cmd) {
|
|||
}
|
||||
|
||||
void MultiplayerArea::executeSetObjectAnimation(const Command &cmd) {
|
||||
shared_ptr<Object> object(find(cmd.objectId(), ObjectType::Creature));
|
||||
shared_ptr<SpatialObject> object(find(cmd.objectId(), ObjectType::Creature));
|
||||
if (object) {
|
||||
object->setSynchronize(false);
|
||||
object->animate(cmd.animation(), cmd.animationFlags());
|
||||
|
@ -155,7 +148,7 @@ void MultiplayerArea::executeSetObjectAnimation(const Command &cmd) {
|
|||
}
|
||||
|
||||
void MultiplayerArea::executeSetCreatureMovementType(const Command &cmd) {
|
||||
shared_ptr<Object> creature(find(cmd.objectId(), ObjectType::Creature));
|
||||
shared_ptr<SpatialObject> creature(find(cmd.objectId(), ObjectType::Creature));
|
||||
if (creature) {
|
||||
creature->setSynchronize(false);
|
||||
static_cast<Creature &>(*creature).setMovementType(cmd.movementType());
|
||||
|
@ -164,7 +157,7 @@ void MultiplayerArea::executeSetCreatureMovementType(const Command &cmd) {
|
|||
}
|
||||
|
||||
void MultiplayerArea::executeSetCreatureTalking(const Command &cmd) {
|
||||
shared_ptr<Object> creature(find(cmd.objectId(), ObjectType::Creature));
|
||||
shared_ptr<SpatialObject> creature(find(cmd.objectId(), ObjectType::Creature));
|
||||
if (creature) {
|
||||
creature->setSynchronize(false);
|
||||
static_cast<Creature &>(*creature).setTalking(cmd.talking());
|
||||
|
|
|
@ -28,9 +28,10 @@ namespace game {
|
|||
class MultiplayerArea : public Area {
|
||||
public:
|
||||
MultiplayerArea(
|
||||
MultiplayerMode mode,
|
||||
uint32_t id,
|
||||
resources::GameVersion version,
|
||||
const std::string &name,
|
||||
MultiplayerMode mode,
|
||||
ObjectFactory *objectFactory,
|
||||
IMultiplayerCallbacks *callbacks);
|
||||
|
||||
void execute(const Command &cmd);
|
||||
|
@ -40,8 +41,6 @@ public:
|
|||
private:
|
||||
IMultiplayerCallbacks *_callbacks { nullptr };
|
||||
|
||||
std::shared_ptr<Creature> makeCreature(uint32_t id) override;
|
||||
std::shared_ptr<Door> makeDoor() override;
|
||||
void updateCreature(Creature &creature, float dt) override;
|
||||
|
||||
void executeLoadCreature(const Command &cmd);
|
||||
|
|
|
@ -41,14 +41,14 @@ const string &MultiplayerCreature::clientTag() const {
|
|||
}
|
||||
|
||||
void MultiplayerCreature::animate(const string &anim, int flags, float speed) {
|
||||
Object::animate(anim, flags);
|
||||
SpatialObject::animate(anim, flags);
|
||||
if (_synchronize) {
|
||||
_callbacks->onObjectAnimationChanged(*this, anim, flags, speed);
|
||||
}
|
||||
}
|
||||
|
||||
void MultiplayerCreature::updateTransform() {
|
||||
Object::updateTransform();
|
||||
SpatialObject::updateTransform();
|
||||
if (_synchronize) {
|
||||
_callbacks->onObjectTransformChanged(*this, _position, _heading);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "../../core/log.h"
|
||||
|
||||
#include "area.h"
|
||||
#include "module.h"
|
||||
#include "objectfactory.h"
|
||||
#include "util.h"
|
||||
|
||||
using namespace std;
|
||||
|
@ -46,6 +46,10 @@ MultiplayerGame::MultiplayerGame(
|
|||
_pickDialogReplyEnabled = _mode == MultiplayerMode::Server;
|
||||
}
|
||||
|
||||
void MultiplayerGame::initObjectFactory() {
|
||||
_objectFactory = unique_ptr<ObjectFactory>(new MultiplayerObjectFactory(_version, _mode, this, _opts));
|
||||
}
|
||||
|
||||
void MultiplayerGame::configure() {
|
||||
switch (_mode) {
|
||||
case MultiplayerMode::Server:
|
||||
|
@ -380,10 +384,6 @@ void MultiplayerGame::sendFinishDialog() {
|
|||
sendCommand(cmd);
|
||||
}
|
||||
|
||||
const shared_ptr<Module> MultiplayerGame::makeModule(const string &name) {
|
||||
return shared_ptr<Module>(new MultiplayerModule(name, _mode, _version, _opts.graphics, this));
|
||||
}
|
||||
|
||||
} // namespace game
|
||||
|
||||
} // namespace reone
|
||||
|
|
|
@ -52,10 +52,10 @@ private:
|
|||
std::recursive_mutex _commandsInMutex;
|
||||
|
||||
// Game overrides
|
||||
void initObjectFactory() override;
|
||||
void configure() override;
|
||||
void update() override;
|
||||
void loadNextModule() override;
|
||||
const std::shared_ptr<Module> makeModule(const std::string &name) override;
|
||||
void startDialog(uint32_t ownerId, const std::string &resRef) override;
|
||||
void onDialogReplyPicked(uint32_t index) override;
|
||||
void onDialogFinished() override;
|
||||
|
|
|
@ -15,31 +15,39 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "module.h"
|
||||
#include "objectfactory.h"
|
||||
|
||||
#include "area.h"
|
||||
#include "creature.h"
|
||||
#include "door.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
using namespace reone::render;
|
||||
using namespace reone::resources;
|
||||
|
||||
namespace reone {
|
||||
|
||||
namespace game {
|
||||
|
||||
MultiplayerModule::MultiplayerModule(
|
||||
const string &name,
|
||||
MultiplayerMode mode,
|
||||
MultiplayerObjectFactory::MultiplayerObjectFactory(
|
||||
GameVersion version,
|
||||
const GraphicsOptions &opts,
|
||||
IMultiplayerCallbacks *callbacks
|
||||
MultiplayerMode mode,
|
||||
IMultiplayerCallbacks *callbacks,
|
||||
const Options &opts
|
||||
) :
|
||||
Module(name, version, opts), _callbacks(callbacks) {
|
||||
ObjectFactory(version, opts), _mode(mode), _callbacks(callbacks) {
|
||||
}
|
||||
|
||||
const shared_ptr<Area> MultiplayerModule::makeArea() const {
|
||||
return shared_ptr<Area>(new MultiplayerArea(_mode, _version, _info.entryArea, _callbacks));
|
||||
unique_ptr<Area> MultiplayerObjectFactory::newArea() {
|
||||
return make_unique<MultiplayerArea>(_counter++, _version, _mode, this, _callbacks);
|
||||
}
|
||||
|
||||
unique_ptr<Creature> MultiplayerObjectFactory::newCreature() {
|
||||
return make_unique<MultiplayerCreature>(_counter++, _callbacks);
|
||||
}
|
||||
|
||||
unique_ptr<Door> MultiplayerObjectFactory::newDoor() {
|
||||
return make_unique<MultiplayerDoor>(_counter++, _callbacks);
|
||||
}
|
||||
|
||||
} // namespace game
|
|
@ -17,28 +17,25 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "../module.h"
|
||||
#include "../object/factory.h"
|
||||
|
||||
#include "callbacks.h"
|
||||
|
||||
namespace reone {
|
||||
|
||||
namespace game {
|
||||
|
||||
class IMultiplayerCallbacks;
|
||||
|
||||
class MultiplayerModule : public Module {
|
||||
class MultiplayerObjectFactory : public ObjectFactory {
|
||||
public:
|
||||
MultiplayerModule(
|
||||
const std::string &name,
|
||||
MultiplayerMode mode,
|
||||
resources::GameVersion version,
|
||||
const render::GraphicsOptions &opts,
|
||||
IMultiplayerCallbacks *callbacks);
|
||||
MultiplayerObjectFactory(resources::GameVersion version, MultiplayerMode mode, IMultiplayerCallbacks *callbacks, const Options &opts);
|
||||
|
||||
std::unique_ptr<Area> newArea();
|
||||
std::unique_ptr<Creature> newCreature();
|
||||
std::unique_ptr<Door> newDoor();
|
||||
|
||||
private:
|
||||
MultiplayerMode _mode { MultiplayerMode::None };
|
||||
IMultiplayerCallbacks *_callbacks { nullptr };
|
||||
|
||||
const std::shared_ptr<Area> makeArea() const override;
|
||||
};
|
||||
|
||||
} // namespace game
|
|
@ -60,7 +60,7 @@ Creature::Action::Action(ActionType type, const shared_ptr<Object> &object, floa
|
|||
Creature::Action::Action(ActionType type, const ExecutionContext &ctx) : type(type), context(ctx) {
|
||||
}
|
||||
|
||||
Creature::Creature(uint32_t id) : Object(id) {
|
||||
Creature::Creature(uint32_t id) : SpatialObject(id) {
|
||||
_type = ObjectType::Creature;
|
||||
_drawDistance = 2048.0f;
|
||||
_fadeDistance = 0.25f * _drawDistance;
|
||||
|
@ -229,7 +229,7 @@ void Creature::loadPortrait(int appearance) {
|
|||
}
|
||||
|
||||
void Creature::initGL() {
|
||||
Object::initGL();
|
||||
SpatialObject::initGL();
|
||||
|
||||
if (_portrait) _portrait->initGL();
|
||||
}
|
||||
|
|
|
@ -25,13 +25,13 @@
|
|||
|
||||
#include "../item.h"
|
||||
|
||||
#include "object.h"
|
||||
#include "spatial.h"
|
||||
|
||||
namespace reone {
|
||||
|
||||
namespace game {
|
||||
|
||||
class Creature : public Object {
|
||||
class Creature : public SpatialObject {
|
||||
public:
|
||||
enum class ActionType {
|
||||
MoveToPoint = 0,
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace reone {
|
|||
|
||||
namespace game {
|
||||
|
||||
Door::Door(uint32_t id) : Object(id) {
|
||||
Door::Door(uint32_t id) : SpatialObject(id) {
|
||||
_type = ObjectType::Door;
|
||||
_drawDistance = FLT_MAX;
|
||||
_fadeDistance = 0.25f * _drawDistance;
|
||||
|
|
|
@ -17,13 +17,15 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "object.h"
|
||||
#include "spatial.h"
|
||||
|
||||
#include "../../resources/gfffile.h"
|
||||
|
||||
namespace reone {
|
||||
|
||||
namespace game {
|
||||
|
||||
class Door : public Object {
|
||||
class Door : public SpatialObject {
|
||||
public:
|
||||
Door(uint32_t id);
|
||||
|
||||
|
|
62
src/game/object/factory.cpp
Normal file
62
src/game/object/factory.cpp
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright © 2020 Vsevolod Kremianskii
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "factory.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
using namespace reone::resources;
|
||||
|
||||
namespace reone {
|
||||
|
||||
namespace game {
|
||||
|
||||
ObjectFactory::ObjectFactory(GameVersion version, const Options &opts) :
|
||||
_version(version), _options(opts) {
|
||||
}
|
||||
|
||||
unique_ptr<Module> ObjectFactory::newModule() {
|
||||
return make_unique<Module>(_counter++, _version, this, _options.graphics);
|
||||
}
|
||||
|
||||
unique_ptr<Area> ObjectFactory::newArea() {
|
||||
return make_unique<Area>(_counter++, _version, this);
|
||||
}
|
||||
|
||||
unique_ptr<Creature> ObjectFactory::newCreature() {
|
||||
return make_unique<Creature>(_counter++);
|
||||
}
|
||||
|
||||
unique_ptr<Placeable> ObjectFactory::newPlaceable() {
|
||||
return make_unique<Placeable>(_counter++);
|
||||
}
|
||||
|
||||
unique_ptr<Door> ObjectFactory::newDoor() {
|
||||
return make_unique<Door>(_counter++);
|
||||
}
|
||||
|
||||
unique_ptr<Waypoint> ObjectFactory::newWaypoint() {
|
||||
return make_unique<Waypoint>(_counter++);
|
||||
}
|
||||
|
||||
unique_ptr<Trigger> ObjectFactory::newTrigger() {
|
||||
return make_unique<Trigger>(_counter++);
|
||||
}
|
||||
|
||||
} // namespace game
|
||||
|
||||
} // namespace reone
|
63
src/game/object/factory.h
Normal file
63
src/game/object/factory.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright © 2020 Vsevolod Kremianskii
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
#include "../../resources/types.h"
|
||||
|
||||
#include "../area.h"
|
||||
#include "../module.h"
|
||||
#include "../types.h"
|
||||
|
||||
#include "creature.h"
|
||||
#include "door.h"
|
||||
#include "placeable.h"
|
||||
#include "trigger.h"
|
||||
#include "waypoint.h"
|
||||
|
||||
namespace reone {
|
||||
|
||||
namespace game {
|
||||
|
||||
class ObjectFactory {
|
||||
public:
|
||||
ObjectFactory(resources::GameVersion version, const Options &opts);
|
||||
|
||||
virtual std::unique_ptr<Module> newModule();
|
||||
virtual std::unique_ptr<Area> newArea();
|
||||
virtual std::unique_ptr<Creature> newCreature();
|
||||
virtual std::unique_ptr<Placeable> newPlaceable();
|
||||
virtual std::unique_ptr<Door> newDoor();
|
||||
virtual std::unique_ptr<Waypoint> newWaypoint();
|
||||
virtual std::unique_ptr<Trigger> newTrigger();
|
||||
|
||||
protected:
|
||||
resources::GameVersion _version { resources::GameVersion::KotOR };
|
||||
Options _options;
|
||||
uint32_t _counter { 2 }; // ids 0 and 1 are reserved
|
||||
|
||||
private:
|
||||
ObjectFactory(const ObjectFactory &) = delete;
|
||||
ObjectFactory &operator=(const ObjectFactory &) = delete;
|
||||
};
|
||||
|
||||
} // namespace game
|
||||
|
||||
} // namespace reone
|
|
@ -17,9 +17,6 @@
|
|||
|
||||
#include "object.h"
|
||||
|
||||
#include "glm/gtx/euler_angles.hpp"
|
||||
#include "glm/gtx/norm.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
using namespace reone::render;
|
||||
|
@ -32,43 +29,7 @@ namespace game {
|
|||
Object::Object(uint32_t id) : _id(id) {
|
||||
}
|
||||
|
||||
void Object::animate(const string &parent, const string &anim, int flags, float speed) {
|
||||
if (_model) {
|
||||
_model->animate(parent, anim, flags, speed);
|
||||
}
|
||||
}
|
||||
|
||||
void Object::animate(const string &anim, int flags, float speed) {
|
||||
if (_model) {
|
||||
_model->animate(anim, flags, speed);
|
||||
}
|
||||
}
|
||||
|
||||
void Object::update(const UpdateContext &ctx) {
|
||||
if (_model) {
|
||||
glm::vec4 viewport(-1.0f, -1.0f, 1.0f, 1.0f);
|
||||
glm::vec3 screenCoords = glm::project(_position, ctx.view, ctx.projection, viewport);
|
||||
float distanceToCamera = glm::distance2(_position, ctx.cameraPosition);
|
||||
bool visible = distanceToCamera < _drawDistance && screenCoords.z < 1.0f;
|
||||
float alpha = 1.0f;
|
||||
|
||||
if (_drawDistance != _fadeDistance && distanceToCamera > _fadeDistance) {
|
||||
alpha = 1.0f - (distanceToCamera - _fadeDistance) / (_drawDistance - _fadeDistance);
|
||||
}
|
||||
if (visible) {
|
||||
_model->show();
|
||||
} else {
|
||||
_model->hide();
|
||||
}
|
||||
_model->setAlpha(alpha);
|
||||
_model->update(ctx.deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
void Object::initGL() {
|
||||
if (_model) {
|
||||
_model->initGL();
|
||||
}
|
||||
}
|
||||
|
||||
void Object::saveTo(AreaState &state) const {
|
||||
|
@ -77,38 +38,10 @@ void Object::saveTo(AreaState &state) const {
|
|||
void Object::loadState(const AreaState &state) {
|
||||
}
|
||||
|
||||
void Object::face(const Object &other) {
|
||||
glm::vec2 dir(glm::normalize(other._position - _position));
|
||||
_heading = -glm::atan(dir.x, dir.y);
|
||||
updateTransform();
|
||||
}
|
||||
|
||||
float Object::distanceTo(const glm::vec3 &point) const {
|
||||
return glm::distance2(_position, point);
|
||||
}
|
||||
|
||||
bool Object::contains(const glm::vec3 &point) const {
|
||||
if (!_model) return false;
|
||||
|
||||
const AABB &aabb = _model->model()->aabb();
|
||||
|
||||
return (aabb * _transform).contains(point);
|
||||
}
|
||||
|
||||
void Object::setPosition(const glm::vec3 &position) {
|
||||
_position = position;
|
||||
updateTransform();
|
||||
}
|
||||
|
||||
void Object::setSynchronize(bool synchronize) {
|
||||
_synchronize = synchronize;
|
||||
}
|
||||
|
||||
void Object::setHeading(float heading) {
|
||||
_heading = heading;
|
||||
updateTransform();
|
||||
}
|
||||
|
||||
uint32_t Object::id() const {
|
||||
return _id;
|
||||
}
|
||||
|
@ -121,31 +54,6 @@ const string &Object::tag() const {
|
|||
return _tag;
|
||||
}
|
||||
|
||||
const glm::vec3 &Object::position() const {
|
||||
return _position;
|
||||
}
|
||||
|
||||
float Object::heading() const {
|
||||
return _heading;
|
||||
}
|
||||
|
||||
const glm::mat4 &Object::transform() const {
|
||||
return _transform;
|
||||
}
|
||||
|
||||
shared_ptr<ModelInstance> Object::model() const {
|
||||
return _model;
|
||||
}
|
||||
|
||||
shared_ptr<Walkmesh> Object::walkmesh() const {
|
||||
return _walkmesh;
|
||||
}
|
||||
|
||||
void Object::updateTransform() {
|
||||
_transform = glm::translate(glm::mat4(1.0f), _position);
|
||||
_transform *= glm::eulerAngleZ(_heading);
|
||||
}
|
||||
|
||||
} // namespace game
|
||||
|
||||
} // namespace reone
|
||||
|
|
|
@ -17,63 +17,35 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "../../render/modelinstance.h"
|
||||
#include "../../render/walkmesh.h"
|
||||
#include "../../resources/gfffile.h"
|
||||
|
||||
#include "../types.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
namespace reone {
|
||||
|
||||
namespace game {
|
||||
|
||||
class Object {
|
||||
public:
|
||||
virtual void animate(const std::string &parent, const std::string &anim, int flags = 0, float speed = 1.0f);
|
||||
virtual void animate(const std::string &anim, int flags = 0, float speed = 1.0f);
|
||||
virtual void update(const UpdateContext &ctx);
|
||||
virtual void initGL();
|
||||
|
||||
virtual void saveTo(AreaState &state) const;
|
||||
virtual void loadState(const AreaState &state);
|
||||
void face(const Object &other);
|
||||
|
||||
float distanceTo(const glm::vec3 &point) const;
|
||||
bool contains(const glm::vec3 &point) const;
|
||||
|
||||
// Setters
|
||||
void setPosition(const glm::vec3 &position);
|
||||
void setHeading(float heading);
|
||||
void setSynchronize(bool synchronize);
|
||||
|
||||
// Getters
|
||||
uint32_t id() const;
|
||||
ObjectType type() const;
|
||||
const std::string &tag() const;
|
||||
const glm::vec3 &position() const;
|
||||
float heading() const;
|
||||
const glm::mat4 &transform() const;
|
||||
std::shared_ptr<render::ModelInstance> model() const;
|
||||
std::shared_ptr<render::Walkmesh> walkmesh() const;
|
||||
|
||||
void setSynchronize(bool synchronize);
|
||||
|
||||
protected:
|
||||
uint32_t _id { 0 };
|
||||
ObjectType _type { ObjectType::None };
|
||||
float _drawDistance { 1024.0f };
|
||||
float _fadeDistance { 256.0f };
|
||||
std::string _tag;
|
||||
glm::vec3 _position { 0.0f };
|
||||
float _heading { 0.0f };
|
||||
glm::mat4 _transform { 1.0f };
|
||||
std::shared_ptr<render::ModelInstance> _model;
|
||||
std::shared_ptr<render::Walkmesh> _walkmesh;
|
||||
bool _synchronize { false };
|
||||
|
||||
Object(uint32_t id);
|
||||
Object(Object &&) = default;
|
||||
|
||||
Object &operator=(Object &&) = default;
|
||||
|
||||
virtual void updateTransform();
|
||||
|
||||
private:
|
||||
Object(const Object &) = delete;
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace reone {
|
|||
|
||||
namespace game {
|
||||
|
||||
Placeable::Placeable(uint32_t id) : Object(id) {
|
||||
Placeable::Placeable(uint32_t id) : SpatialObject(id) {
|
||||
_type = ObjectType::Placeable;
|
||||
_drawDistance = 4096.0f;
|
||||
_fadeDistance = 0.25f * _drawDistance;
|
||||
|
|
|
@ -19,15 +19,15 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
#include "object.h"
|
||||
|
||||
#include "../item.h"
|
||||
|
||||
#include "spatial.h"
|
||||
|
||||
namespace reone {
|
||||
|
||||
namespace game {
|
||||
|
||||
class Placeable : public Object {
|
||||
class Placeable : public SpatialObject {
|
||||
public:
|
||||
Placeable(uint32_t id);
|
||||
|
||||
|
|
127
src/game/object/spatial.cpp
Normal file
127
src/game/object/spatial.cpp
Normal file
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* Copyright © 2020 Vsevolod Kremianskii
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "spatial.h"
|
||||
|
||||
#include "glm/gtx/euler_angles.hpp"
|
||||
#include "glm/gtx/norm.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
using namespace reone::render;
|
||||
|
||||
namespace reone {
|
||||
|
||||
namespace game {
|
||||
|
||||
SpatialObject::SpatialObject(uint32_t id) : Object(id) {
|
||||
}
|
||||
|
||||
float SpatialObject::distanceTo(const glm::vec3 &point) const {
|
||||
return glm::distance2(_position, point);
|
||||
}
|
||||
|
||||
bool SpatialObject::contains(const glm::vec3 &point) const {
|
||||
if (!_model) return false;
|
||||
|
||||
const AABB &aabb = _model->model()->aabb();
|
||||
|
||||
return (aabb * _transform).contains(point);
|
||||
}
|
||||
|
||||
void SpatialObject::face(const SpatialObject &other) {
|
||||
glm::vec2 dir(glm::normalize(other._position - _position));
|
||||
_heading = -glm::atan(dir.x, dir.y);
|
||||
updateTransform();
|
||||
}
|
||||
|
||||
void SpatialObject::update(const UpdateContext &ctx) {
|
||||
if (!_model) return;
|
||||
|
||||
glm::vec4 viewport(-1.0f, -1.0f, 1.0f, 1.0f);
|
||||
glm::vec3 screenCoords = glm::project(_position, ctx.view, ctx.projection, viewport);
|
||||
float distanceToCamera = glm::distance2(_position, ctx.cameraPosition);
|
||||
bool visible = distanceToCamera < _drawDistance && screenCoords.z < 1.0f;
|
||||
float alpha = 1.0f;
|
||||
|
||||
if (_drawDistance != _fadeDistance && distanceToCamera > _fadeDistance) {
|
||||
alpha = 1.0f - (distanceToCamera - _fadeDistance) / (_drawDistance - _fadeDistance);
|
||||
}
|
||||
if (visible) {
|
||||
_model->show();
|
||||
} else {
|
||||
_model->hide();
|
||||
}
|
||||
_model->setAlpha(alpha);
|
||||
_model->update(ctx.deltaTime);
|
||||
}
|
||||
|
||||
void SpatialObject::initGL() {
|
||||
if (!_model) return;
|
||||
|
||||
_model->initGL();
|
||||
}
|
||||
|
||||
void SpatialObject::animate(const string &anim, int flags, float speed) {
|
||||
if (!_model) return;
|
||||
|
||||
_model->animate(anim, flags, speed);
|
||||
}
|
||||
|
||||
void SpatialObject::animate(const string &parent, const string &anim, int flags, float speed) {
|
||||
if (!_model) return;
|
||||
|
||||
_model->animate(parent, anim, flags, speed);
|
||||
}
|
||||
|
||||
const glm::vec3 &SpatialObject::position() const {
|
||||
return _position;
|
||||
}
|
||||
|
||||
float SpatialObject::heading() const {
|
||||
return _heading;
|
||||
}
|
||||
|
||||
const glm::mat4 &SpatialObject::transform() const {
|
||||
return _transform;
|
||||
}
|
||||
void SpatialObject::setPosition(const glm::vec3 &position) {
|
||||
_position = position;
|
||||
updateTransform();
|
||||
}
|
||||
|
||||
void SpatialObject::updateTransform() {
|
||||
_transform = glm::translate(glm::mat4(1.0f), _position);
|
||||
_transform *= glm::eulerAngleZ(_heading);
|
||||
}
|
||||
|
||||
void SpatialObject::setHeading(float heading) {
|
||||
_heading = heading;
|
||||
updateTransform();
|
||||
}
|
||||
|
||||
shared_ptr<ModelInstance> SpatialObject::model() const {
|
||||
return _model;
|
||||
}
|
||||
|
||||
shared_ptr<Walkmesh> SpatialObject::walkmesh() const {
|
||||
return _walkmesh;
|
||||
}
|
||||
|
||||
} // namespace game
|
||||
|
||||
} // namespace reone
|
74
src/game/object/spatial.h
Normal file
74
src/game/object/spatial.h
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright © 2020 Vsevolod Kremianskii
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "object.h"
|
||||
|
||||
#include "glm/mat4x4.hpp"
|
||||
#include "glm/vec3.hpp"
|
||||
|
||||
#include "../../render/modelinstance.h"
|
||||
#include "../../render/walkmesh.h"
|
||||
|
||||
namespace reone {
|
||||
|
||||
namespace game {
|
||||
|
||||
static const float kDefaultDrawDistance = 1024.0f;
|
||||
static const float kDefaultFadeDistance = 256.0f;
|
||||
|
||||
class SpatialObject : public Object {
|
||||
public:
|
||||
void update(const UpdateContext &ctx) override;
|
||||
|
||||
float distanceTo(const glm::vec3 &point) const;
|
||||
bool contains(const glm::vec3 &point) const;
|
||||
|
||||
void face(const SpatialObject &other);
|
||||
|
||||
virtual void initGL();
|
||||
virtual void animate(const std::string &anim, int flags = 0, float speed = 1.0f);
|
||||
virtual void animate(const std::string &parent, const std::string &anim, int flags = 0, float speed = 1.0f);
|
||||
|
||||
const glm::vec3 &position() const;
|
||||
float heading() const;
|
||||
const glm::mat4 &transform() const;
|
||||
|
||||
void setPosition(const glm::vec3 &position);
|
||||
void setHeading(float heading);
|
||||
|
||||
std::shared_ptr<render::ModelInstance> model() const;
|
||||
std::shared_ptr<render::Walkmesh> walkmesh() const;
|
||||
|
||||
protected:
|
||||
glm::vec3 _position { 0.0f };
|
||||
float _heading { 0.0f };
|
||||
glm::mat4 _transform { 1.0f };
|
||||
std::shared_ptr<render::ModelInstance> _model;
|
||||
std::shared_ptr<render::Walkmesh> _walkmesh;
|
||||
float _drawDistance { kDefaultDrawDistance };
|
||||
float _fadeDistance { kDefaultFadeDistance };
|
||||
|
||||
SpatialObject(uint32_t id);
|
||||
|
||||
virtual void updateTransform();
|
||||
};
|
||||
|
||||
} // namespace game
|
||||
|
||||
} // namespace reone
|
|
@ -29,7 +29,7 @@ namespace reone {
|
|||
|
||||
namespace game {
|
||||
|
||||
Trigger::Trigger(uint32_t id) : Object(id) {
|
||||
Trigger::Trigger(uint32_t id) : SpatialObject(id) {
|
||||
_type = ObjectType::Trigger;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,13 +17,15 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "object.h"
|
||||
#include "spatial.h"
|
||||
|
||||
#include "../../resources/gfffile.h"
|
||||
|
||||
namespace reone {
|
||||
|
||||
namespace game {
|
||||
|
||||
class Trigger : public Object {
|
||||
class Trigger : public SpatialObject {
|
||||
public:
|
||||
Trigger(uint32_t id);
|
||||
|
||||
|
|
|
@ -19,13 +19,15 @@
|
|||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#include "glm/glm.hpp"
|
||||
|
||||
using namespace reone::resources;
|
||||
|
||||
namespace reone {
|
||||
|
||||
namespace game {
|
||||
|
||||
Waypoint::Waypoint(uint32_t id) : Object(id) {
|
||||
Waypoint::Waypoint(uint32_t id) : SpatialObject(id) {
|
||||
_type = ObjectType::Waypoint;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,13 +17,15 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "object.h"
|
||||
#include "spatial.h"
|
||||
|
||||
#include "../../resources/gfffile.h"
|
||||
|
||||
namespace reone {
|
||||
|
||||
namespace game {
|
||||
|
||||
class Waypoint : public Object {
|
||||
class Waypoint : public SpatialObject {
|
||||
public:
|
||||
Waypoint(uint32_t id);
|
||||
|
||||
|
|
|
@ -28,19 +28,23 @@ namespace reone {
|
|||
|
||||
namespace game {
|
||||
|
||||
class Area;
|
||||
class Module;
|
||||
|
||||
class IRoutineCallbacks {
|
||||
public:
|
||||
virtual ~IRoutineCallbacks() {
|
||||
}
|
||||
virtual ~IRoutineCallbacks() = default;
|
||||
|
||||
// Commands
|
||||
virtual void delayCommand(uint32_t timestamp, const script::ExecutionContext &ctx) = 0;
|
||||
|
||||
// Events
|
||||
virtual int eventUserDefined(int eventNumber) = 0;
|
||||
virtual void signalEvent(int eventId) = 0;
|
||||
virtual void signalEvent(uint32_t objectId, int eventId) = 0;
|
||||
|
||||
// Objects
|
||||
virtual Module *getModule() = 0;
|
||||
virtual Area *getArea() = 0;
|
||||
virtual std::shared_ptr<Object> getObjectById(uint32_t id) = 0;
|
||||
virtual std::shared_ptr<Object> getObjectByTag(const std::string &tag, int nth = 0) = 0;
|
||||
virtual std::shared_ptr<Object> getWaypointByTag(const std::string &tag) = 0;
|
||||
|
|
|
@ -84,8 +84,6 @@ shared_ptr<Object> RoutineManager::getObjectById(uint32_t id, const ExecutionCon
|
|||
finalId = ctx.callerId;
|
||||
break;
|
||||
case kObjectInvalid:
|
||||
case kObjectModule:
|
||||
case kObjectArea:
|
||||
warn("Routine: invalid object id: " + to_string(id));
|
||||
return nullptr;
|
||||
default:
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "../../core/log.h"
|
||||
#include "../../core/random.h"
|
||||
|
||||
#include "../area.h"
|
||||
#include "../object/creature.h"
|
||||
#include "../object/door.h"
|
||||
|
||||
|
@ -133,7 +134,7 @@ Variable RoutineManager::getArea(const vector<Variable> &args, ExecutionContext
|
|||
assert(!args.empty() && args[0].type == VariableType::Object);
|
||||
|
||||
Variable result(VariableType::Object);
|
||||
result.objectId = kObjectArea;
|
||||
result.objectId = _callbacks->getArea()->id();
|
||||
|
||||
return move(result);
|
||||
}
|
||||
|
@ -254,13 +255,11 @@ Variable RoutineManager::signalEvent(const vector<Variable> &args, ExecutionCont
|
|||
args[0].type == VariableType::Object &&
|
||||
args[1].type == VariableType::Event);
|
||||
|
||||
if (args[0].objectId == kObjectArea ||
|
||||
(args[0].objectId == kObjectSelf && ctx.callerId == kObjectArea)) {
|
||||
|
||||
_callbacks->signalEvent(args[1].engineTypeId);
|
||||
|
||||
shared_ptr<Object> subject(getObjectById(args[0].objectId, ctx));
|
||||
if (subject) {
|
||||
_callbacks->signalEvent(subject->id(), args[1].engineTypeId);
|
||||
} else {
|
||||
warn("Routine: invalid callee: " + to_string(args[0].objectId));
|
||||
warn("Routine: object not found by id: " + to_string(args[0].objectId));
|
||||
}
|
||||
|
||||
return Variable();
|
||||
|
|
|
@ -56,6 +56,8 @@ enum class ClassType {
|
|||
|
||||
enum class ObjectType {
|
||||
None,
|
||||
Module,
|
||||
Area,
|
||||
Creature,
|
||||
Door,
|
||||
Placeable,
|
||||
|
|
|
@ -28,8 +28,6 @@ namespace script {
|
|||
|
||||
const uint32_t kObjectSelf = 0;
|
||||
const uint32_t kObjectInvalid = 1;
|
||||
const uint32_t kObjectModule = 2;
|
||||
const uint32_t kObjectArea = 3;
|
||||
|
||||
struct Variable;
|
||||
class ScriptProgram;
|
||||
|
|
Loading…
Reference in a new issue