Initial commit
This commit is contained in:
57
engines/crab/level/LevelExit.cpp
Normal file
57
engines/crab/level/LevelExit.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
/* 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/level/LevelExit.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
using namespace pyrodactyl::level;
|
||||
|
||||
void Exit::load(rapidxml::xml_node<char> *node) {
|
||||
_dim.load(node);
|
||||
loadStr(_name, "name", node);
|
||||
|
||||
if (nodeValid("properties", node)) {
|
||||
rapidxml::xml_node<char> *propertynode = node->first_node("properties");
|
||||
for (auto n = propertynode->first_node("property"); n != nullptr; n = n->next_sibling("property")) {
|
||||
Common::String nodeName;
|
||||
loadStr(nodeName, "name", n);
|
||||
if (nodeName == "entry_x") {
|
||||
if (!loadNum(_entry.x, "value", n))
|
||||
_entry.x = -1;
|
||||
} else if (nodeName == "entry_y") {
|
||||
if (!loadNum(_entry.y, "value", n))
|
||||
_entry.y = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Crab
|
||||
57
engines/crab/level/LevelExit.h
Normal file
57
engines/crab/level/LevelExit.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/* 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_LEVELEXIT_H
|
||||
#define CRAB_LEVELEXIT_H
|
||||
|
||||
#include "crab/Shape.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
namespace pyrodactyl {
|
||||
namespace level {
|
||||
struct Exit {
|
||||
Common::String _name;
|
||||
Shape _dim;
|
||||
Vector2i _entry;
|
||||
|
||||
Exit() : _entry(-1, -1) {}
|
||||
Exit(rapidxml::xml_node<char> *node) {
|
||||
load(node);
|
||||
}
|
||||
|
||||
void load(rapidxml::xml_node<char> *node);
|
||||
};
|
||||
} // End of namespace level
|
||||
} // End of namespace pyrodactyl
|
||||
|
||||
} // End of namespace Crab
|
||||
|
||||
#endif // CRAB_LEVELEXIT_H
|
||||
56
engines/crab/level/MusicArea.cpp
Normal file
56
engines/crab/level/MusicArea.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
/* 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/level/MusicArea.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
using namespace pyrodactyl::level;
|
||||
|
||||
void MusicArea::load(rapidxml::xml_node<char> *node, const bool &echo) {
|
||||
Shape::load(node, echo);
|
||||
|
||||
if (nodeValid("properties", node, echo)) {
|
||||
auto pnode = node->first_node("properties");
|
||||
for (auto n = pnode->first_node("property"); n != nullptr; n = n->next_sibling("property")) {
|
||||
Common::String name;
|
||||
if (loadStr(name, "name", n, echo)) {
|
||||
if (name == "music")
|
||||
loadBool(_track, "value", n, echo);
|
||||
else if (name == "id")
|
||||
loadNum(_id, "value", n, echo);
|
||||
else if (name == "loops")
|
||||
loadNum(_loops, "value", n, echo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Crab
|
||||
71
engines/crab/level/MusicArea.h
Normal file
71
engines/crab/level/MusicArea.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/* 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_MUSICAREA_H
|
||||
#define CRAB_MUSICAREA_H
|
||||
|
||||
#include "crab/Shape.h"
|
||||
#include "crab/music/musicparam.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
namespace pyrodactyl {
|
||||
namespace level {
|
||||
struct MusicInfo {
|
||||
// Are we playing a sound effect or a music track
|
||||
bool _track;
|
||||
|
||||
// The id of the music track or sound effect being played
|
||||
int _id;
|
||||
|
||||
// The amount of loops
|
||||
int _loops;
|
||||
|
||||
MusicInfo() {
|
||||
_track = false;
|
||||
_id = -1;
|
||||
_loops = -1;
|
||||
}
|
||||
~MusicInfo() {}
|
||||
};
|
||||
|
||||
class MusicArea : public Shape, public MusicInfo {
|
||||
public:
|
||||
MusicArea() {}
|
||||
~MusicArea() {}
|
||||
|
||||
void load(rapidxml::xml_node<char> *node, const bool &echo = true);
|
||||
};
|
||||
} // End of namespace level
|
||||
} // End of namespace pyrodactyl
|
||||
|
||||
} // End of namespace Crab
|
||||
|
||||
#endif // CRAB_MUSICAREA_H
|
||||
54
engines/crab/level/Stairs.cpp
Normal file
54
engines/crab/level/Stairs.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
/* 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/level/Stairs.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
using namespace pyrodactyl::level;
|
||||
|
||||
void Stairs::load(rapidxml::xml_node<char> *node, const bool &echo) {
|
||||
Shape::load(node, echo);
|
||||
|
||||
if (nodeValid("properties", node, echo)) {
|
||||
auto pnode = node->first_node("properties");
|
||||
for (auto n = pnode->first_node("property"); n != nullptr; n = n->next_sibling("property")) {
|
||||
Common::String name;
|
||||
if (loadStr(name, "name", n, echo)) {
|
||||
if (name == "x")
|
||||
loadNum(_modifier.x, "value", n, echo);
|
||||
else if (name == "y")
|
||||
loadNum(_modifier.y, "value", n, echo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Crab
|
||||
55
engines/crab/level/Stairs.h
Normal file
55
engines/crab/level/Stairs.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/* 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_STAIRS_H
|
||||
#define CRAB_STAIRS_H
|
||||
|
||||
#include "crab/Shape.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
namespace pyrodactyl {
|
||||
namespace level {
|
||||
class Stairs : public Shape {
|
||||
public:
|
||||
// The modifier by which the velocity of the character walking over the stairs is changed
|
||||
Vector2f _modifier;
|
||||
|
||||
Stairs() : _modifier(1.0f, 1.0f) {}
|
||||
~Stairs() {}
|
||||
|
||||
void load(rapidxml::xml_node<char> *node, const bool &echo = true);
|
||||
};
|
||||
} // End of namespace level
|
||||
} // End of namespace pyrodactyl
|
||||
|
||||
} // End of namespace Crab
|
||||
|
||||
#endif // CRAB_STAIRS_H
|
||||
147
engines/crab/level/level.cpp
Normal file
147
engines/crab/level/level.cpp
Normal file
@@ -0,0 +1,147 @@
|
||||
/* 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/ScreenSettings.h"
|
||||
#include "crab/input/cursor.h"
|
||||
#include "crab/level/level.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
using namespace TMX;
|
||||
using namespace pyrodactyl::stat;
|
||||
using namespace pyrodactyl::anim;
|
||||
using namespace pyrodactyl::level;
|
||||
using namespace pyrodactyl::image;
|
||||
using namespace pyrodactyl::people;
|
||||
using namespace pyrodactyl::input;
|
||||
using namespace pyrodactyl::event;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: We re-use the same level object each time
|
||||
// this function cleans up everything to make it good as new (get it)
|
||||
//------------------------------------------------------------------------
|
||||
void Level::reset() {
|
||||
if (_playerIndex > 0 && _objects.size() > _playerIndex)
|
||||
_objects[_playerIndex]._pathing.shutdown();
|
||||
|
||||
_playerIndex = 0;
|
||||
_terrain.reset();
|
||||
|
||||
_objects.clear();
|
||||
_objSeq.clear();
|
||||
_background.clear();
|
||||
_fly.clear();
|
||||
|
||||
Camera(0, 0, g_engine->_screenSettings->_cur.w, g_engine->_screenSettings->_cur.h);
|
||||
|
||||
_showmap.set(true);
|
||||
_insideExit = false;
|
||||
_firstHit = true;
|
||||
_music._id = -1;
|
||||
_previewPath.clear();
|
||||
|
||||
_img.deleteImage();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Get sprite in the object array
|
||||
//------------------------------------------------------------------------
|
||||
pyrodactyl::anim::Sprite *Level::getSprite(const Common::String &id) {
|
||||
for (auto &i : _objects)
|
||||
if (i.id() == id)
|
||||
return &i;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Figure visibility and let the AI see what moves are allowed
|
||||
//------------------------------------------------------------------------
|
||||
void Level::calcProperties(pyrodactyl::event::Info &info) {
|
||||
for (auto &i : _objects)
|
||||
i.calcProperties(info);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Handle the level movement
|
||||
//------------------------------------------------------------------------
|
||||
void Level::handleEvents(Info &info, const Common::Event &event) {
|
||||
if (!g_engine->_mouse->_insideHud) {
|
||||
if (event.type == Common::EVENT_LBUTTONDOWN || event.type == Common::EVENT_RBUTTONDOWN) {
|
||||
// Only go to path if our mouse is a normal walking cursor
|
||||
if (!g_engine->_mouse->_hover) {
|
||||
// The destination coordinate is set by adding camera position to click position
|
||||
Vector2i dest = g_engine->_mouse->_button;
|
||||
dest.x += _camera.x;
|
||||
dest.y += _camera.y;
|
||||
|
||||
Rect b = _objects[_playerIndex].boundRect();
|
||||
b.w /= 2;
|
||||
b.h /= 2;
|
||||
b.x = dest.x - b.w / 2;
|
||||
b.y = dest.y - b.h / 2;
|
||||
|
||||
_objects[_playerIndex].setDestPathfinding(dest, !_terrain.insideNoWalk(dest));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_objects[_playerIndex].handleEvents(info, _camera, _scDefault, event);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Swap the player sprites
|
||||
//------------------------------------------------------------------------
|
||||
void Level::playerId(const Common::String &ID, const int &x, const int &y) {
|
||||
int index = 0;
|
||||
for (auto i = _objects.begin(); i != _objects.end(); ++i, ++index) {
|
||||
if (i->id() == ID) {
|
||||
_playerIndex = index;
|
||||
|
||||
if (x != -1)
|
||||
i->x(x);
|
||||
if (y != -1)
|
||||
i->y(y);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Rearrange stuff after resolution change
|
||||
//------------------------------------------------------------------------
|
||||
void Level::setUI() {
|
||||
_camera.w = g_engine->_screenSettings->_cur.w;
|
||||
_camera.h = g_engine->_screenSettings->_cur.h;
|
||||
setCamera();
|
||||
}
|
||||
|
||||
} // End of namespace Crab
|
||||
220
engines/crab/level/level.h
Normal file
220
engines/crab/level/level.h
Normal file
@@ -0,0 +1,220 @@
|
||||
/* 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_LEVEL_H
|
||||
#define CRAB_LEVEL_H
|
||||
|
||||
#include "common/multimap.h"
|
||||
#include "crab/PathfindingGrid.h"
|
||||
#include "crab/animation/sprite.h"
|
||||
#include "crab/level/level_objects.h"
|
||||
#include "crab/level/talknotify.h"
|
||||
#include "crab/TMX/TMXMap.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
namespace pyrodactyl {
|
||||
namespace level {
|
||||
class Level {
|
||||
// The .tmx file to import terrain from
|
||||
TMX::TMXMap _terrain;
|
||||
|
||||
// The pathfinding grid for the level
|
||||
PathfindingGrid _pathfindingGrid;
|
||||
|
||||
// The area we display to the player
|
||||
Rect _camera;
|
||||
|
||||
// The player sprite location in the object list
|
||||
uint _playerIndex;
|
||||
|
||||
// The order in which to draw the sprites
|
||||
Common::MultiMap<int, pyrodactyl::anim::Sprite *> _objSeq;
|
||||
|
||||
// The file index which contains the fighting moves of all characters
|
||||
Common::Array<Common::Path> _animSet;
|
||||
|
||||
// The movement sets for sprites in levels
|
||||
Common::Array<pyrodactyl::ai::MovementSet> _moveSet;
|
||||
|
||||
// These sprites are only for animated objects and cannot be interacted with
|
||||
Common::Array<pyrodactyl::anim::Sprite> _background;
|
||||
|
||||
// These sprites fly across the screen randomly
|
||||
Common::Array<pyrodactyl::anim::Sprite> _fly;
|
||||
|
||||
// The id of the music track being played
|
||||
MusicInfo _music;
|
||||
|
||||
// Is the world map accessible from this level?
|
||||
MapVis _showmap;
|
||||
|
||||
// We disable exits when player is fighting enemies - this is used to check if we are in an exit area WHILE fighting enemies
|
||||
// If we are fighting inside exit area, the level switch is delayed until we walk out of exit and back in
|
||||
// to prevent instant level switch as soon as you beat all enemies
|
||||
bool _insideExit;
|
||||
|
||||
bool _firstHit;
|
||||
|
||||
// Default sprite parameters
|
||||
pyrodactyl::ai::SpriteConstant _scDefault;
|
||||
|
||||
// Protected level functions
|
||||
bool collidingWithObject(pyrodactyl::event::Info &info, Common::String &id);
|
||||
bool collidingWithLevel(pyrodactyl::event::Info &info, pyrodactyl::anim::Sprite &s);
|
||||
bool playerInCombat(pyrodactyl::event::Info &info);
|
||||
void battleAlert(pyrodactyl::event::Info &info);
|
||||
|
||||
void sortObjectsToDraw();
|
||||
void moveObject(pyrodactyl::event::Info &info, pyrodactyl::anim::Sprite &s);
|
||||
|
||||
void think(pyrodactyl::event::Info &info, Common::Array<pyrodactyl::event::EventResult> &result,
|
||||
Common::Array<pyrodactyl::event::EventSeqInfo> &endSeq, Common::String &id);
|
||||
|
||||
void drawObjects(pyrodactyl::event::Info &info);
|
||||
void setCamera();
|
||||
|
||||
bool layerVisible(pyrodactyl::anim::Sprite *obj);
|
||||
|
||||
public:
|
||||
// The objects in the level, and the player character
|
||||
Common::Array<pyrodactyl::anim::Sprite> _objects;
|
||||
|
||||
// The notification text drawn if the player is able to talk to a sprite
|
||||
TalkNotify _talkNotify;
|
||||
|
||||
// Used for drawing the destination marker for point and click movement
|
||||
PlayerDestMarker _destMarker;
|
||||
|
||||
// The location of this level on the world map
|
||||
Vector2i _mapLoc;
|
||||
|
||||
// The clip revealed by this level on the world map
|
||||
struct MapClip {
|
||||
// Which world map is this clip added to?
|
||||
int _id;
|
||||
|
||||
// The clip itself
|
||||
Rect _rect;
|
||||
|
||||
MapClip() {
|
||||
_id = 0;
|
||||
}
|
||||
} _mapClip;
|
||||
|
||||
// Used to draw ambient dialog
|
||||
pyrodactyl::ui::ParagraphData _pop;
|
||||
|
||||
// The path of the preview image
|
||||
Common::Path _previewPath;
|
||||
|
||||
// A full rendered image of the level
|
||||
pyrodactyl::image::Image _img;
|
||||
|
||||
Level() : _playerIndex(0) {
|
||||
reset();
|
||||
}
|
||||
|
||||
~Level() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void reset();
|
||||
|
||||
void Camera(int x, int y, int w, int h) {
|
||||
_camera.x = x;
|
||||
_camera.y = y;
|
||||
_camera.w = w;
|
||||
_camera.h = h;
|
||||
}
|
||||
|
||||
Rect camera() {
|
||||
return _camera;
|
||||
}
|
||||
|
||||
void playerStop() {
|
||||
_objects[_playerIndex].stop();
|
||||
}
|
||||
|
||||
const Common::String &playerId() {
|
||||
return _objects[_playerIndex].id();
|
||||
}
|
||||
|
||||
void playerId(const Common::String &ID, const int &x, const int &y);
|
||||
|
||||
void showMap(bool val) {
|
||||
_showmap._normal = val;
|
||||
}
|
||||
|
||||
bool showMap() {
|
||||
return _showmap._current;
|
||||
}
|
||||
|
||||
bool operator()(int i, int j);
|
||||
|
||||
// This calculates the unlocked moves for each sprite in the level, and the visibility of objects
|
||||
void calcProperties(pyrodactyl::event::Info &info);
|
||||
|
||||
// Loading function
|
||||
void load(const Common::Path &filename, pyrodactyl::event::Info &info, pyrodactyl::event::TriggerSet &gameOver,
|
||||
const int &playerX = -1, const int &playerY = -1);
|
||||
|
||||
// One time load called first-time
|
||||
void loadMoves(const Common::Path &filename);
|
||||
void loadConst(const Common::Path &filename);
|
||||
|
||||
// Used to see if a sprite collides with a rectangle
|
||||
void calcTrigCollide(pyrodactyl::event::Info &info);
|
||||
|
||||
// See if a player clicked on the sprite in contact
|
||||
bool containsClick(const Common::String &id, const Common::Event &event);
|
||||
|
||||
// Get index of a sprite in the object array
|
||||
pyrodactyl::anim::Sprite *getSprite(const Common::String &id);
|
||||
|
||||
void handleEvents(pyrodactyl::event::Info &info, const Common::Event &event);
|
||||
LevelResult internalEvents(pyrodactyl::event::Info &info, Common::Array<pyrodactyl::event::EventResult> &result,
|
||||
Common::Array<pyrodactyl::event::EventSeqInfo> &endSeq, bool eventInProgress);
|
||||
|
||||
void preDraw();
|
||||
void preDrawObjects(Graphics::ManagedSurface *surf);
|
||||
void draw(pyrodactyl::event::Info &info);
|
||||
|
||||
void saveState(rapidxml::xml_document<> &doc, rapidxml::xml_node<char> *root);
|
||||
void loadState(rapidxml::xml_node<char> *node);
|
||||
|
||||
void setUI();
|
||||
};
|
||||
} // End of namespace level
|
||||
} // End of namespace pyrodactyl
|
||||
|
||||
} // End of namespace Crab
|
||||
|
||||
#endif // CRAB_LEVEL_H
|
||||
219
engines/crab/level/level_ai.cpp
Normal file
219
engines/crab/level/level_ai.cpp
Normal file
@@ -0,0 +1,219 @@
|
||||
/* 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/level/level.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
using namespace TMX;
|
||||
using namespace pyrodactyl::stat;
|
||||
using namespace pyrodactyl::anim;
|
||||
using namespace pyrodactyl::level;
|
||||
using namespace pyrodactyl::image;
|
||||
using namespace pyrodactyl::people;
|
||||
using namespace pyrodactyl::input;
|
||||
using namespace pyrodactyl::event;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Let the level tick along and notify if we go into an exit
|
||||
//------------------------------------------------------------------------
|
||||
LevelResult Level::internalEvents(Info &info, Common::Array<EventResult> &result, Common::Array<EventSeqInfo> &endSeq, bool eventInProgress) {
|
||||
LevelResult lResult;
|
||||
|
||||
// input.internalEvents();
|
||||
calcTrigCollide(info);
|
||||
|
||||
if (_terrain.collideWithExit(_objects[_playerIndex].boundRect(), lResult)) {
|
||||
if (playerInCombat(info)) {
|
||||
_insideExit = true;
|
||||
} else if (_insideExit == false) {
|
||||
lResult._type = LR_LEVEL;
|
||||
return lResult;
|
||||
}
|
||||
} else {
|
||||
_insideExit = false;
|
||||
|
||||
if (playerInCombat(info))
|
||||
_showmap._current = false;
|
||||
else
|
||||
_showmap._current = _showmap._normal;
|
||||
}
|
||||
|
||||
if (eventInProgress)
|
||||
playerStop();
|
||||
else
|
||||
think(info, result, endSeq, lResult._val);
|
||||
|
||||
if (lResult._val != "")
|
||||
info.lastPerson(lResult._val);
|
||||
else if (collidingWithObject(info, lResult._val))
|
||||
info.lastPerson(lResult._val);
|
||||
else
|
||||
info.lastPerson("");
|
||||
|
||||
return lResult;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Let the AI think and animate the level
|
||||
//------------------------------------------------------------------------
|
||||
void Level::think(pyrodactyl::event::Info &info, Common::Array<pyrodactyl::event::EventResult> &result,
|
||||
Common::Array<pyrodactyl::event::EventSeqInfo> &endSeq, Common::String &id) {
|
||||
uint index = 0;
|
||||
for (auto i = _objects.begin(); i != _objects.end(); ++i, ++index) {
|
||||
// Only bother if the sprite is visible
|
||||
if (i->visible()) {
|
||||
// TODO: Find a place where this should be initialized... (SZ)
|
||||
if (i->_pathing._grid == nullptr)
|
||||
i->_pathing.initialize(&_pathfindingGrid);
|
||||
|
||||
// If a sprite is dead, nothing else matters
|
||||
if (info.state(i->id()) == PST_DYING) {
|
||||
if (i->lastFrame()) {
|
||||
info.statSet(i->id(), STAT_HEALTH, 0);
|
||||
info.state(i->id(), PST_KO);
|
||||
i->effectImg(false);
|
||||
i->inputStop();
|
||||
}
|
||||
} else if (info.state(i->id()) != PST_KO) {
|
||||
Rect boundRect = i->boundRect();
|
||||
|
||||
i->_pathing.setPosition(Vector2f((float)(boundRect.x + boundRect.w / 2), (float)boundRect.y + boundRect.h / 2));
|
||||
i->_pathing.update(0);
|
||||
|
||||
// For the AI sprites
|
||||
if (index != _playerIndex) {
|
||||
switch (info.state(i->id())) {
|
||||
case PST_FIGHT: {
|
||||
// Only attack if the player is alive
|
||||
if (info.state(_objects[_playerIndex].id()) < PST_KO)
|
||||
i->attack(info, _objects[_playerIndex], _scDefault);
|
||||
} break;
|
||||
case PST_FLEE:
|
||||
i->flee(info, _terrain._areaExit, _scDefault);
|
||||
break;
|
||||
case PST_NORMAL:
|
||||
if (i->takingDamage(_objects[_playerIndex], _scDefault)) {
|
||||
if (_firstHit) {
|
||||
battleAlert(info);
|
||||
_firstHit = false;
|
||||
}
|
||||
}
|
||||
/*else
|
||||
TraversePath(*i);*/
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Only do this if the player is alive
|
||||
if (info.state(_objects[_playerIndex].id()) < PST_KO)
|
||||
_objects[_playerIndex].exchangeDamage(info, *i, _scDefault);
|
||||
} else {
|
||||
// For the player sprite
|
||||
boundRect = i->boundRect();
|
||||
|
||||
i->_pathing.setPosition(Vector2f((float)(boundRect.x + boundRect.w / 2), (float)boundRect.y + boundRect.h / 2));
|
||||
i->_pathing.update(0);
|
||||
|
||||
i->moveToDestPathfinding(info, _scDefault);
|
||||
}
|
||||
|
||||
i->internalEvents(info, playerId(), result, endSeq);
|
||||
moveObject(info, *i);
|
||||
}
|
||||
|
||||
i->animate(info);
|
||||
}
|
||||
}
|
||||
|
||||
// Background sprites don't move
|
||||
for (auto &i : _background)
|
||||
i.animate(PST_NORMAL);
|
||||
|
||||
// Flier sprites fly across the screen from left to right or vice versa
|
||||
// The movement is semi-random
|
||||
for (auto &i : _fly) {
|
||||
i.flyAround(_camera, _scDefault);
|
||||
i.animate(PST_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Once a player provokes any sprite, call this function
|
||||
//------------------------------------------------------------------------
|
||||
void Level::battleAlert(pyrodactyl::event::Info &info) {
|
||||
uint index = 0;
|
||||
for (auto i = _objects.begin(); i != _objects.end(); ++i, ++index) {
|
||||
if (index != _playerIndex && i->visible() && info.state(i->id()) != PST_KO) {
|
||||
switch (info.type(i->id())) {
|
||||
case PE_NEUTRAL:
|
||||
case PE_HOSTILE:
|
||||
info.state(i->id(), PST_FIGHT);
|
||||
break;
|
||||
case PE_COWARD:
|
||||
info.state(i->id(), PST_FLEE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Move a sprite according to its velocity
|
||||
//------------------------------------------------------------------------
|
||||
void Level::moveObject(pyrodactyl::event::Info &info, pyrodactyl::anim::Sprite &s) {
|
||||
// Update x,y coordinates according to velocity
|
||||
s.move(_scDefault);
|
||||
|
||||
// First check collision with objects and forbidden areas inside a level
|
||||
if (collidingWithLevel(info, s))
|
||||
s.resolveCollide();
|
||||
|
||||
// Finally see if we are inside the overall level bounds
|
||||
if (!_terrain.insideWalk(s.boundRect()))
|
||||
s.resolveInside(_terrain.areaWalk());
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: If any other object is trying to kill you, you are in combat
|
||||
//------------------------------------------------------------------------
|
||||
bool Level::playerInCombat(pyrodactyl::event::Info &info) {
|
||||
uint index = 0;
|
||||
for (auto i = _objects.begin(); i != _objects.end(); ++i, ++index)
|
||||
if (index != _playerIndex && info.state(i->id()) == PST_FIGHT && i->visible())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // End of namespace Crab
|
||||
149
engines/crab/level/level_collide.cpp
Normal file
149
engines/crab/level/level_collide.cpp
Normal file
@@ -0,0 +1,149 @@
|
||||
/* 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/input/cursor.h"
|
||||
#include "crab/level/level.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
using namespace TMX;
|
||||
using namespace pyrodactyl::stat;
|
||||
using namespace pyrodactyl::anim;
|
||||
using namespace pyrodactyl::level;
|
||||
using namespace pyrodactyl::image;
|
||||
using namespace pyrodactyl::people;
|
||||
using namespace pyrodactyl::input;
|
||||
using namespace pyrodactyl::event;
|
||||
using namespace pyrodactyl::music;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: See if player clicked on a sprite they are colliding with
|
||||
//------------------------------------------------------------------------
|
||||
bool Level::containsClick(const Common::String &id, const Common::Event &event) {
|
||||
// If mouse is moved and is hovering on the specified sprite (id), set hover = true
|
||||
if (event.type == Common::EVENT_MOUSEMOVE) {
|
||||
for (auto &i : _objects) {
|
||||
Rect r = i.posRect();
|
||||
|
||||
if (r.contains(g_engine->_mouse->_motion.x + _camera.x, g_engine->_mouse->_motion.y + _camera.y)) {
|
||||
// This is to show the sprite's name on top of their head
|
||||
i._hover = true;
|
||||
|
||||
// This is to update the mouse cursor only if we're in talking range of a sprite
|
||||
if (i.id() == id)
|
||||
g_engine->_mouse->_hover = true;
|
||||
} else
|
||||
i._hover = false;
|
||||
}
|
||||
|
||||
return false;
|
||||
} else if (g_engine->_mouse->pressed()) {
|
||||
for (auto &i : _objects) {
|
||||
if (i.id() == id) {
|
||||
Rect r = i.posRect();
|
||||
if (r.contains(g_engine->_mouse->_button.x + _camera.x, g_engine->_mouse->_button.y + _camera.y)) {
|
||||
g_engine->_mouse->_hover = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Find if a layer is visible (used only for objects with layers associated with them)
|
||||
//------------------------------------------------------------------------
|
||||
bool Level::layerVisible(pyrodactyl::anim::Sprite *obj) {
|
||||
if (obj->_layer < 0)
|
||||
return true;
|
||||
|
||||
if ((uint)obj->_layer < _terrain._layer.size())
|
||||
return _terrain._layer[obj->_layer]._collide;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Check if a sprite is colliding with the trigger areas
|
||||
// Common::String &id is set to the id of colliding object
|
||||
//------------------------------------------------------------------------
|
||||
void Level::calcTrigCollide(pyrodactyl::event::Info &info) {
|
||||
for (auto &i : _objects)
|
||||
if (info.personValid(i.id()))
|
||||
_terrain.collideWithTrigger(i.boundRect(), info.personGet(i.id())._trig);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Check if a sprite is colliding with interactive objects
|
||||
// Common::String &id is set to the id of colliding object
|
||||
//------------------------------------------------------------------------
|
||||
bool Level::collidingWithObject(pyrodactyl::event::Info &info, Common::String &id) {
|
||||
// Clip and Bounding rectangle of player
|
||||
Rect pPos = _objects[_playerIndex].posRect(), pBound = _objects[_playerIndex].boundRect();
|
||||
|
||||
uint index = 0;
|
||||
for (auto i = _objects.begin(); i != _objects.end(); ++i, ++index) {
|
||||
if (i->visible() && _playerIndex != index && info.state(i->id()) == PST_NORMAL) {
|
||||
// Clip and bounding rectangles for the NPC sprite
|
||||
Rect iPos = i->posRect(), iBound = i->boundRect();
|
||||
|
||||
if (pPos.collide(iPos) || iPos.contains(pPos) || pBound.collide(iBound) || iBound.contains(pBound)) {
|
||||
id = i->id();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Check if a sprite is colliding with non-interactive stuff in the level
|
||||
// id is set to the id of colliding object
|
||||
//------------------------------------------------------------------------
|
||||
bool Level::collidingWithLevel(pyrodactyl::event::Info &info, pyrodactyl::anim::Sprite &s) {
|
||||
_terrain.collideWithNoWalk(s.boundRect(), s._collideData);
|
||||
|
||||
_terrain.collideWithStairs(s.boundRect(), s._velMod);
|
||||
|
||||
if (_terrain.collideWithMusic(s.boundRect(), _music)) {
|
||||
if (_music._track)
|
||||
g_engine->_musicManager->playMusic(_music._id);
|
||||
else
|
||||
g_engine->_musicManager->playEffect(_music._id, _music._loops);
|
||||
}
|
||||
|
||||
// If we are colliding with something, return true
|
||||
return !s._collideData.empty();
|
||||
}
|
||||
|
||||
} // End of namespace Crab
|
||||
271
engines/crab/level/level_draw.cpp
Normal file
271
engines/crab/level/level_draw.cpp
Normal file
@@ -0,0 +1,271 @@
|
||||
/* 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 "graphics/managed_surface.h"
|
||||
#include "crab/ScreenSettings.h"
|
||||
#include "crab/level/level.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
using namespace TMX;
|
||||
using namespace pyrodactyl::stat;
|
||||
using namespace pyrodactyl::anim;
|
||||
using namespace pyrodactyl::level;
|
||||
using namespace pyrodactyl::image;
|
||||
using namespace pyrodactyl::people;
|
||||
using namespace pyrodactyl::input;
|
||||
|
||||
// Purpose: Pre render the terrain layer
|
||||
void Level::preDraw() {
|
||||
Graphics::ManagedSurface *surf = new Graphics::ManagedSurface(_terrain.w(), _terrain.h(), g_engine->_format);
|
||||
uint layerCount = 0u;
|
||||
for (auto l = _terrain._layer.begin(); l != _terrain._layer.end(); ++l, ++layerCount) {
|
||||
g_engine->_imageManager->_tileset.preDraw(*l, _terrain._tileSize, surf);
|
||||
|
||||
// Draw the normal sprites if this is the layer for it
|
||||
if (layerCount == _terrain._spriteLayer)
|
||||
preDrawObjects(surf);
|
||||
}
|
||||
|
||||
// This is to ensure we don't miss out on drawing sprites
|
||||
if (layerCount <= _terrain._spriteLayer)
|
||||
preDrawObjects(surf);
|
||||
|
||||
_img.load(surf);
|
||||
delete surf;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Draw the level
|
||||
//------------------------------------------------------------------------
|
||||
void Level::draw(pyrodactyl::event::Info &info) {
|
||||
setCamera();
|
||||
sortObjectsToDraw();
|
||||
|
||||
// Background sprites are assumed to be sorted by their layer count
|
||||
auto b = _background.begin();
|
||||
|
||||
uint layerCount = 0u;
|
||||
|
||||
// Draw the terrain layer
|
||||
g_engine->_imageManager->_tileset.draw(_terrain._layer[0], _camera, _terrain._tileSize, _objects[_playerIndex].posRect(), _img);
|
||||
|
||||
Vector2i pos = _objects[_playerIndex]._aiData._dest;
|
||||
Rect newpos(pos.x - (_destMarker._size.x / 2), pos.y - (_destMarker._size.y / 2), _destMarker._size.x, _destMarker._size.y);
|
||||
|
||||
for (auto l = _terrain._layer.begin(); l != _terrain._layer.end(); ++l, ++layerCount) {
|
||||
|
||||
// Draw the background sprites
|
||||
for (; b != _background.end(); ++b) {
|
||||
if ((uint)b->_layer > layerCount) // We don't have any sprites to draw at this layer
|
||||
break;
|
||||
else if ((uint)b->_layer == layerCount && b->visible())
|
||||
b->draw(info, _camera);
|
||||
}
|
||||
|
||||
// Draw the normal sprites if this is the layer for it
|
||||
if (layerCount == _terrain._spriteLayer)
|
||||
drawObjects(info);
|
||||
|
||||
// Draw the terrain layer
|
||||
g_engine->_imageManager->_tileset.forceDraw(*l, _camera, _terrain._tileSize, _objects[_playerIndex].posRect());
|
||||
}
|
||||
|
||||
// Draw the background sprites
|
||||
for (; b != _background.end(); ++b) {
|
||||
if ((uint)b->_layer > layerCount) // We don't have any sprites to draw at this layer
|
||||
break;
|
||||
else if ((uint)b->_layer >= layerCount && b->visible())
|
||||
b->draw(info, _camera);
|
||||
}
|
||||
|
||||
// This is to ensure we don't miss out on drawing sprites
|
||||
if (layerCount <= _terrain._spriteLayer)
|
||||
drawObjects(info);
|
||||
|
||||
// Fliers are drawn above every sprite but below popup text
|
||||
for (auto &i : _fly) {
|
||||
// Only draw if it is supposed to be flying
|
||||
if (i._aiData._walk._enabled)
|
||||
i.draw(info, _camera);
|
||||
}
|
||||
|
||||
// Draw popup text over all level layers
|
||||
for (auto &i : _objects) {
|
||||
// Only draw popups for visible sprites
|
||||
if (i.visible()) {
|
||||
if (i.popupShow())
|
||||
i.drawPopup(_pop, _camera);
|
||||
else {
|
||||
// Only draw their name if they are
|
||||
//(a) hovered over by the mouse, OR
|
||||
//(b) are in talk range and don't have popup text over their head
|
||||
if (i._hover || (info.lastPerson() == i.id() && !i.popupShow()))
|
||||
_talkNotify.draw(info, i, _camera);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (g_engine->_debugDraw & DRAW_TMX)
|
||||
_terrain.drawDebug(_camera);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Draw sprites and prop layers in sequences according to depth
|
||||
//------------------------------------------------------------------------
|
||||
void Level::drawObjects(pyrodactyl::event::Info &info) {
|
||||
// Draw player destination marker
|
||||
if (_objects[_playerIndex]._aiData._dest._active)
|
||||
_destMarker.draw(_objects[_playerIndex]._aiData._dest, _camera);
|
||||
|
||||
Vector2i pos = _objects[_playerIndex]._aiData._dest;
|
||||
Rect newpos(pos.x - (_destMarker._size.x / 2), pos.y - (_destMarker._size.y / 2), _destMarker._size.x, _destMarker._size.y);
|
||||
|
||||
if (_terrain._prop.empty()) {
|
||||
for (auto &entry : _objSeq) {
|
||||
if (entry.second->visible() && layerVisible(entry.second))
|
||||
entry.second->draw(info, _camera);
|
||||
}
|
||||
} else {
|
||||
auto a = _terrain._prop.begin();
|
||||
auto b = _objSeq.begin();
|
||||
|
||||
while (a != _terrain._prop.end() && b != _objSeq.end()) {
|
||||
auto obj = b->second;
|
||||
if (a->_pos.y + a->_pos.h < obj->y() + obj->h()) {
|
||||
for (auto &i : a->_boundRect) {
|
||||
// draw prop bounds if requested
|
||||
if (g_engine->_debugDraw & DRAW_PROP_BOUNDS)
|
||||
i.draw(-_camera.x, -_camera.y, 128, 128, 0, 255);
|
||||
|
||||
if (i.collide(_objects[_playerIndex].posRect())) {
|
||||
g_engine->_imageManager->_tileset.forceDraw(*a, _camera, _terrain._tileSize, _objects[_playerIndex].posRect());
|
||||
}
|
||||
|
||||
if (i.contains(_objects[_playerIndex]._aiData._dest)) {
|
||||
g_engine->_imageManager->_tileset.forceDraw(*a, _camera, _terrain._tileSize, newpos);
|
||||
}
|
||||
}
|
||||
++a;
|
||||
} else {
|
||||
if (obj->visible() && layerVisible(obj))
|
||||
obj->draw(info, _camera);
|
||||
++b;
|
||||
}
|
||||
}
|
||||
|
||||
if (a == _terrain._prop.end()) {
|
||||
for (; b != _objSeq.end(); ++b) {
|
||||
auto obj = b->second;
|
||||
if (obj->visible() && layerVisible(obj))
|
||||
obj->draw(info, _camera);
|
||||
}
|
||||
} else if (b == _objSeq.end()) {
|
||||
for (; a != _terrain._prop.end(); ++a) {
|
||||
for (auto &i : a->_boundRect) {
|
||||
// draw prop bounds if requested
|
||||
if (g_engine->_debugDraw & DRAW_PROP_BOUNDS)
|
||||
i.draw(-_camera.x, -_camera.y, 128, 128, 0, 255);
|
||||
|
||||
if (i.collide(_objects[_playerIndex].posRect())) {
|
||||
g_engine->_imageManager->_tileset.forceDraw(*a, _camera, _terrain._tileSize, _objects[_playerIndex].posRect());
|
||||
}
|
||||
|
||||
if (i.contains(_objects[_playerIndex]._aiData._dest)) {
|
||||
g_engine->_imageManager->_tileset.forceDraw(*a, _camera, _terrain._tileSize, newpos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Level::preDrawObjects(Graphics::ManagedSurface *surf) {
|
||||
if (_terrain._prop.empty()) {
|
||||
return;
|
||||
} else {
|
||||
auto a = _terrain._prop.begin();
|
||||
auto b = _objSeq.begin();
|
||||
|
||||
while (a != _terrain._prop.end() && b != _objSeq.end()) {
|
||||
auto obj = b->second;
|
||||
if (a->_pos.y + a->_pos.h < obj->y() + obj->h()) {
|
||||
g_engine->_imageManager->_tileset.preDraw(*a, _terrain._tileSize, surf);
|
||||
++a;
|
||||
} else {
|
||||
++b;
|
||||
}
|
||||
}
|
||||
|
||||
if (a == _terrain._prop.end()) {
|
||||
} else if (b == _objSeq.end()) {
|
||||
for (; a != _terrain._prop.end(); ++a)
|
||||
g_engine->_imageManager->_tileset.preDraw(*a, _terrain._tileSize, surf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Sort objects to draw them according to their Y coordinates
|
||||
//------------------------------------------------------------------------
|
||||
bool Level::operator()(int i, int j) {
|
||||
return _objects[i].y() + _objects[i].h() < _objects[j].y() + _objects[j].h();
|
||||
}
|
||||
|
||||
void Level::sortObjectsToDraw() {
|
||||
// add each object to the map to sort it
|
||||
_objSeq.clear();
|
||||
for (auto &object : _objects)
|
||||
_objSeq.insert(Common::Pair<int, Sprite *>(object.y() + object.h(), &object));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Center the camera on the player for scrolling levels
|
||||
//------------------------------------------------------------------------
|
||||
void Level::setCamera() {
|
||||
// Use the focus points of sprites
|
||||
Vector2i focus = _objects[_playerIndex].camFocus();
|
||||
|
||||
// Center the camera over the player
|
||||
_camera.x = focus.x - (g_engine->_screenSettings->_cur.w / 2);
|
||||
_camera.y = focus.y - (g_engine->_screenSettings->_cur.h / 2);
|
||||
|
||||
// Keep the camera in bounds
|
||||
if (_camera.x > _terrain.w() - _camera.w)
|
||||
_camera.x = _terrain.w() - _camera.w;
|
||||
if (_camera.y > _terrain.h() - _camera.h)
|
||||
_camera.y = _terrain.h() - _camera.h;
|
||||
if (_camera.x < 0)
|
||||
_camera.x = 0;
|
||||
if (_camera.y < 0)
|
||||
_camera.y = 0;
|
||||
}
|
||||
|
||||
} // End of namespace Crab
|
||||
238
engines/crab/level/level_load.cpp
Normal file
238
engines/crab/level/level_load.cpp
Normal file
@@ -0,0 +1,238 @@
|
||||
/* 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/XMLDoc.h"
|
||||
#include "crab/ScreenSettings.h"
|
||||
#include "crab/level/level.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
using namespace TMX;
|
||||
using namespace pyrodactyl::stat;
|
||||
using namespace pyrodactyl::anim;
|
||||
using namespace pyrodactyl::level;
|
||||
using namespace pyrodactyl::image;
|
||||
using namespace pyrodactyl::people;
|
||||
using namespace pyrodactyl::input;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Used to sort background sprites
|
||||
//------------------------------------------------------------------------
|
||||
static bool compSpriteLayer(const Sprite &a, const Sprite &b) {
|
||||
return (a._layer < b._layer);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Load the level
|
||||
//------------------------------------------------------------------------
|
||||
void Level::load(const Common::Path &filename, pyrodactyl::event::Info &info,
|
||||
pyrodactyl::event::TriggerSet &gameOver, const int &playerX, const int &playerY) {
|
||||
reset();
|
||||
XMLDoc conf(filename);
|
||||
if (conf.ready()) {
|
||||
rapidxml::xml_node<char> *node = conf.doc()->first_node("level");
|
||||
if (nodeValid(node)) {
|
||||
Common::String vis;
|
||||
loadStr(vis, "map", node, false);
|
||||
if (vis == "false")
|
||||
_showmap.set(false);
|
||||
else
|
||||
_showmap.set(true);
|
||||
|
||||
if (nodeValid("preview", node))
|
||||
loadPath(_previewPath, "path", node->first_node("preview"));
|
||||
|
||||
if (nodeValid("music", node)) {
|
||||
loadNum(_music._id, "id", node->first_node("music"));
|
||||
g_engine->_musicManager->playMusic(_music._id);
|
||||
}
|
||||
|
||||
if (nodeValid("map", node)) {
|
||||
rapidxml::xml_node<char> *mapnode = node->first_node("map");
|
||||
Common::Path path;
|
||||
Common::String tmxfile;
|
||||
loadPath(path, "path", mapnode);
|
||||
loadStr(tmxfile, "file", mapnode);
|
||||
|
||||
_terrain.load(path, tmxfile);
|
||||
|
||||
// Remember to load the terrain data before constructing the pathfinding grid
|
||||
_pathfindingGrid.setupNodes(_terrain);
|
||||
|
||||
_terrain._grid = &_pathfindingGrid;
|
||||
|
||||
if (nodeValid("loc", mapnode))
|
||||
_mapLoc.load(mapnode->first_node("loc"));
|
||||
|
||||
if (nodeValid("clip", mapnode)) {
|
||||
rapidxml::xml_node<char> *clipnode = mapnode->first_node("clip");
|
||||
loadNum(_mapClip._id, "id", clipnode);
|
||||
_mapClip._rect.load(clipnode);
|
||||
}
|
||||
}
|
||||
|
||||
if (nodeValid("sprites", node)) {
|
||||
rapidxml::xml_node<char> *spritenode = node->first_node("sprites");
|
||||
int count = 0;
|
||||
for (auto n = spritenode->first_node(); n != nullptr; n = n->next_sibling(), ++count) {
|
||||
Sprite s;
|
||||
s.load(n, _animSet);
|
||||
|
||||
Common::String str = n->name();
|
||||
if (str == "player") {
|
||||
_playerIndex = _objects.size();
|
||||
if (playerX != -1 && playerY != -1) {
|
||||
s.x(playerX);
|
||||
s.y(playerY);
|
||||
}
|
||||
}
|
||||
|
||||
_objects.push_back(s);
|
||||
}
|
||||
}
|
||||
|
||||
if (nodeValid("background", node)) {
|
||||
rapidxml::xml_node<char> *spritenode = node->first_node("background");
|
||||
for (auto n = spritenode->first_node(); n != nullptr; n = n->next_sibling()) {
|
||||
Sprite s;
|
||||
s.load(n, _animSet);
|
||||
_background.push_back(s);
|
||||
}
|
||||
|
||||
Common::sort(_background.begin(), _background.end(), compSpriteLayer);
|
||||
}
|
||||
|
||||
if (nodeValid("fly", node)) {
|
||||
rapidxml::xml_node<char> *spritenode = node->first_node("fly");
|
||||
for (auto n = spritenode->first_node(); n != nullptr; n = n->next_sibling()) {
|
||||
Sprite s;
|
||||
s.load(n, _animSet);
|
||||
|
||||
// Set the timer target for the first time
|
||||
//s.ai_data.walk.timer.Target(sc_default.fly.delay_min + (gRandom.Num() % sc_default.fly.delay_max));
|
||||
s._aiData._walk._timer.target(_scDefault._fly._delayMax);
|
||||
|
||||
_fly.push_back(s);
|
||||
}
|
||||
}
|
||||
|
||||
if (nodeValid("movement", node)) {
|
||||
rapidxml::xml_node<char> *movnode = node->first_node("movement");
|
||||
for (auto n = movnode->first_node("set"); n != nullptr; n = n->next_sibling("set"))
|
||||
_moveSet.push_back(n);
|
||||
}
|
||||
|
||||
if (nodeValid("popup", node, false))
|
||||
_pop.load(node->first_node("popup"));
|
||||
|
||||
gameOver.clear();
|
||||
if (nodeValid("game_over", node, false))
|
||||
gameOver.load(node->first_node("game_over"));
|
||||
else if (_playerIndex < _objects.size()) {
|
||||
// The default lose condition is the death of the player
|
||||
using namespace pyrodactyl::event;
|
||||
Trigger t;
|
||||
t._type = TRIG_STAT;
|
||||
t._target = STATNAME_HEALTH;
|
||||
t._subject = _objects[_playerIndex].id();
|
||||
t._operation = "<";
|
||||
t._val = "1";
|
||||
gameOver.add(t);
|
||||
}
|
||||
|
||||
calcProperties(info);
|
||||
}
|
||||
}
|
||||
|
||||
setCamera();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Build an index of all animation files, called once at start
|
||||
//------------------------------------------------------------------------
|
||||
void Level::loadMoves(const Common::Path &filename) {
|
||||
XMLDoc movList(filename);
|
||||
if (movList.ready()) {
|
||||
rapidxml::xml_node<char> *node = movList.doc()->first_node("movelist");
|
||||
for (auto n = node->first_node("set"); n != nullptr; n = n->next_sibling("set")) {
|
||||
uint pos = _animSet.size();
|
||||
|
||||
loadNum(pos, "id", n);
|
||||
if (pos >= _animSet.size())
|
||||
_animSet.resize(pos + 1);
|
||||
|
||||
// See if there is an alternate moveset for low quality setting
|
||||
// If no, just load the regular one
|
||||
if (!g_engine->_screenSettings->_quality) {
|
||||
if (!loadPath(_animSet[pos], "path_low", n))
|
||||
loadPath(_animSet[pos], "path", n);
|
||||
} else
|
||||
loadPath(_animSet[pos], "path", n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Load the default sprite constant parameters
|
||||
//------------------------------------------------------------------------
|
||||
void Level::loadConst(const Common::Path &filename) {
|
||||
XMLDoc doc(filename);
|
||||
if (doc.ready()) {
|
||||
rapidxml::xml_node<char> *node = doc.doc()->first_node("constant");
|
||||
if (nodeValid(node))
|
||||
_scDefault.load(node);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Save all sprite positions to save file
|
||||
//------------------------------------------------------------------------
|
||||
void Level::saveState(rapidxml::xml_document<> &doc, rapidxml::xml_node<char> *root) {
|
||||
root->append_attribute(doc.allocate_attribute("player_index", g_engine->_stringPool->get(_playerIndex)));
|
||||
|
||||
for (auto &i : _objects) {
|
||||
rapidxml::xml_node<char> *child = doc.allocate_node(rapidxml::node_element, "sprite");
|
||||
i.saveState(doc, child);
|
||||
root->append_node(child);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Purpose: Load all sprite positions from save file
|
||||
//------------------------------------------------------------------------
|
||||
void Level::loadState(rapidxml::xml_node<char> *node) {
|
||||
loadNum(_playerIndex, "player_index", node);
|
||||
|
||||
auto i = _objects.begin();
|
||||
for (auto *n = node->first_node("sprite"); n != nullptr && i != _objects.end(); n = n->next_sibling("sprite"), ++i)
|
||||
i->loadState(n);
|
||||
}
|
||||
|
||||
} // End of namespace Crab
|
||||
50
engines/crab/level/level_objects.cpp
Normal file
50
engines/crab/level/level_objects.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
/* 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/image/ImageManager.h"
|
||||
#include "crab/level/level_objects.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
using namespace pyrodactyl::image;
|
||||
using namespace pyrodactyl::level;
|
||||
|
||||
void PlayerDestMarker::load(rapidxml::xml_node<char> *node) {
|
||||
loadImgKey(_img, "dest", node);
|
||||
_size.x = g_engine->_imageManager->getTexture(_img).w();
|
||||
_size.y = g_engine->_imageManager->getTexture(_img).h();
|
||||
}
|
||||
|
||||
void PlayerDestMarker::draw(const Vector2i &pos, const Rect &camera) {
|
||||
g_engine->_imageManager->draw(pos.x - (_size.x / 2) - camera.x, pos.y - (_size.y / 2) - camera.y, _img);
|
||||
}
|
||||
|
||||
} // End of namespace Crab
|
||||
72
engines/crab/level/level_objects.h
Normal file
72
engines/crab/level/level_objects.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_LEVEL_OBJECTS_H
|
||||
#define CRAB_LEVEL_OBJECTS_H
|
||||
|
||||
#include "crab/image/ImageManager.h"
|
||||
#include "crab/Rectangle.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
namespace pyrodactyl {
|
||||
namespace level {
|
||||
// Is the world map accessible from this level?
|
||||
struct MapVis {
|
||||
bool _normal, _current;
|
||||
|
||||
MapVis() {
|
||||
set(true);
|
||||
}
|
||||
|
||||
void set(bool val) {
|
||||
_normal = val;
|
||||
_current = val;
|
||||
}
|
||||
};
|
||||
|
||||
// Used for drawing the destination marker for point and click movement
|
||||
struct PlayerDestMarker {
|
||||
ImageKey _img;
|
||||
Vector2i _size;
|
||||
|
||||
PlayerDestMarker() {
|
||||
_img = 0;
|
||||
}
|
||||
|
||||
void load(rapidxml::xml_node<char> *node);
|
||||
void draw(const Vector2i &pos, const Rect &camera);
|
||||
};
|
||||
} // End of namespace level
|
||||
} // End of namespace pyrodactyl
|
||||
|
||||
} // End of namespace Crab
|
||||
|
||||
#endif // CRAB_LEVEL_OBJECTS_H
|
||||
60
engines/crab/level/talknotify.cpp
Normal file
60
engines/crab/level/talknotify.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
/* 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/level/talknotify.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
using namespace pyrodactyl::text;
|
||||
using namespace pyrodactyl::level;
|
||||
using namespace pyrodactyl::image;
|
||||
|
||||
void TalkNotify::load(rapidxml::xml_node<char> *node) {
|
||||
_offset.load(node);
|
||||
loadNum(_font, "font", node);
|
||||
loadAlign(_align, node);
|
||||
loadNum(_col, "col", node);
|
||||
}
|
||||
|
||||
void TalkNotify::draw(pyrodactyl::event::Info &info, pyrodactyl::anim::Sprite &s, const Rect &camera) {
|
||||
Rect rect = s.posRect();
|
||||
|
||||
// Find position to draw name (over the sprite's top edge)
|
||||
Vector2i pos;
|
||||
pos.x = rect.x + rect.w / 2 + _offset.x;
|
||||
pos.y = rect.y + _offset.y;
|
||||
|
||||
// Find the sprite name
|
||||
Common::String text = info.getName(s.id());
|
||||
|
||||
g_engine->_textManager->draw(pos.x - camera.x, pos.y - camera.y, text, _col, _font, _align, true);
|
||||
}
|
||||
|
||||
} // End of namespace Crab
|
||||
62
engines/crab/level/talknotify.h
Normal file
62
engines/crab/level/talknotify.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/* 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_TALKNOTIFY_H
|
||||
#define CRAB_TALKNOTIFY_H
|
||||
|
||||
#include "crab/animation/sprite.h"
|
||||
|
||||
namespace Crab {
|
||||
|
||||
namespace pyrodactyl {
|
||||
namespace level {
|
||||
class TalkNotify {
|
||||
// The offset to the sprite at which the name is drawn - along with alignment, font and color used to draw the name
|
||||
Vector2i _offset;
|
||||
FontKey _font;
|
||||
int _col;
|
||||
Align _align;
|
||||
|
||||
public:
|
||||
TalkNotify() {
|
||||
_font = 0;
|
||||
_col = 0;
|
||||
_align = ALIGN_CENTER;
|
||||
}
|
||||
|
||||
void load(rapidxml::xml_node<char> *node);
|
||||
void draw(pyrodactyl::event::Info &info, pyrodactyl::anim::Sprite &s, const Rect &camera);
|
||||
};
|
||||
} // End of namespace level
|
||||
} // End of namespace pyrodactyl
|
||||
|
||||
} // End of namespace Crab
|
||||
|
||||
#endif // CRAB_TALKNOTIFY_H
|
||||
Reference in New Issue
Block a user