Skip to content

Commit

Permalink
NWN: Hook up object picking again
Browse files Browse the repository at this point in the history
  • Loading branch information
DrMcCoy committed Jan 28, 2014
1 parent 7afed0a commit 721716b
Show file tree
Hide file tree
Showing 8 changed files with 171 additions and 48 deletions.
36 changes: 26 additions & 10 deletions src/engines/nwn/area.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ namespace Engines {
namespace NWN {

Area::Area(Module &module, const Common::UString &resRef) : _module(&module), _loaded(false),
_resRef(resRef), _visible(false), _tileset(0) {
_resRef(resRef), _visible(false), _highlightAll(false), _tileset(0) {

// Load ARE and GIT

Expand Down Expand Up @@ -361,11 +361,17 @@ void Area::loadTile(const Aurora::GFFStruct &t, Tile &tile) {
void Area::loadModels() {
loadTileModels();

for (ObjectList::iterator o = _objects.begin(); o != _objects.end(); ++o)
for (ObjectList::iterator o = _objects.begin(); o != _objects.end(); ++o) {
(*o)->loadModel();

if (!(*o)->isStatic())
for (std::vector<Common::UString>::const_iterator i = (*o)->getModelIDs().begin(); i != (*o)->getModelIDs().end(); ++i)
_dynamicObjects.insert(std::make_pair(*i, *o));
}
}

void Area::unloadModels() {
_dynamicObjects.clear();
for (ObjectList::iterator o = _objects.begin(); o != _objects.end(); ++o)
(*o)->unloadModel();

Expand Down Expand Up @@ -478,18 +484,28 @@ void Area::loadDoors(const Aurora::GFFList &list) {
}
}

void Area::addEvent(const Events::Event &event) {
_eventQueue.push_back(event);
}
Engines::NWN::Object *Area::getObjectAt(int x, int y, float &distance) const {
Graphics::Aurora::Renderable *r = SceneMan.getRenderableAt(x, y, Graphics::Aurora::kSelectableRenderable, distance);
if (!r)
return 0;

void Area::processEventQueue() {
for (std::list<Events::Event>::const_iterator e = _eventQueue.begin(); e != _eventQueue.end(); ++e) {
}
ObjectMap::const_iterator o = _dynamicObjects.find(r->getID());
if (o == _dynamicObjects.end())
return 0;

_eventQueue.clear();
return o->second;
}

void Area::notifyCameraMoved() {
bool Area::getHighlightAll() const {
return _highlightAll;
}

void Area::setHighlightAll(bool highlight) {
for (ObjectList::iterator o = _objects.begin(); o != _objects.end(); ++o)
if (!(*o)->isStatic())
(*o)->setHighlight(highlight);

_highlightAll = highlight;
}

// "Elfland: The Woods" -> "The Woods"
Expand Down
25 changes: 11 additions & 14 deletions src/engines/nwn/area.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,13 @@

#include "common/types.h"
#include "common/ustring.h"
#include "common/mutex.h"

#include "aurora/types.h"

#include "aurora/nwscript/object.h"

#include "sound/types.h"

#include "events/types.h"
#include "events/notifyable.h"

#include "engines/nwn/tileset.h"
#include "engines/nwn/model.h"

Expand All @@ -57,7 +53,7 @@ namespace NWN {
class Module;
class Object;

class Area : public Aurora::NWScript::Object, public Events::Notifyable {
class Area : public Aurora::NWScript::Object {
public:
Area(Module &module, const Common::UString &resRef);
~Area();
Expand Down Expand Up @@ -94,13 +90,13 @@ class Area : public Aurora::NWScript::Object, public Events::Notifyable {
/** Play the specified sound (or the area's default) as ambient sound. */
void playAmbientSound(Common::UString sound = "");

// Events

/** Add a single event for consideration into the area event queue. */
void addEvent(const Events::Event &event);
/** Process the current event queue. */
void processEventQueue();
/** Find the dynamic object that's displayed at these screen coordinates. */
Engines::NWN::Object *getObjectAt(int x, int y, float &distance) const;

/** Are we currently highlighting all dynamic objects? */
bool getHighlightAll() const;
/** Highlight/Dehighlight all dynamic objects. */
void setHighlightAll(bool highlight);

/** Return the localized name of an area. */
static Common::UString getName(const Common::UString &resRef);
Expand Down Expand Up @@ -138,6 +134,7 @@ class Area : public Aurora::NWScript::Object, public Events::Notifyable {
};

typedef std::list<Engines::NWN::Object *> ObjectList;
typedef std::map<Common::UString, Engines::NWN::Object *> ObjectMap;


Module *_module;
Expand Down Expand Up @@ -168,6 +165,8 @@ class Area : public Aurora::NWScript::Object, public Events::Notifyable {

bool _visible; ///< Is the area currently visible?

bool _highlightAll; ///< Are we currently highlighting all dynamic objects?

Sound::ChannelHandle _ambientSound; ///< Sound handle of the currently playing sound.
Sound::ChannelHandle _ambientMusic; ///< Sound handle of the currently playing music.

Expand All @@ -181,9 +180,7 @@ class Area : public Aurora::NWScript::Object, public Events::Notifyable {

ObjectList _objects; ///< List of all objects in the area.

std::list<Events::Event> _eventQueue; ///< The event queue.

Common::Mutex _mutex; ///< Mutex securing access to the area.
ObjectMap _dynamicObjects; ///< Map of all non-static objects indexed by their IDs.


// Loading helpers
Expand Down
105 changes: 82 additions & 23 deletions src/engines/nwn/module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@
#include "graphics/graphics.h"
#include "graphics/cameraman.h"
#include "graphics/textureman.h"
#include "graphics/cursorman.h"

#include "graphics/aurora/sceneman.h"
#include "graphics/aurora/model_nwn.h"

#include "engines/aurora/util.h"
Expand All @@ -51,12 +53,15 @@
#include "engines/nwn/types.h"
#include "engines/nwn/module.h"
#include "engines/nwn/area.h"
#include "engines/nwn/object.h"

namespace Engines {

namespace NWN {

Module::Module() : _hasModule(false), _currentTexturePack(-1), _exit(false), _currentArea(0) {
Module::Module() : _hasModule(false), _currentTexturePack(-1), _exit(false),
_currentArea(0), _currentObject(0) {

}

Module::~Module() {
Expand Down Expand Up @@ -189,7 +194,8 @@ void Module::enterArea() {
if (_currentArea) {
_currentArea->setVisible(false);

_currentArea = 0;
_currentArea = 0;
_currentObject = 0;
}

if (_newArea.empty()) {
Expand Down Expand Up @@ -245,14 +251,15 @@ void Module::handleEvents() {
Events::Event event;
while (EventMan.pollEvent(event)) {
// Camera
if (SDL_IsTextInputActive() == SDL_FALSE)
if (SDL_IsTextInputActive() == SDL_FALSE) {
if (handleCamera(event))
continue;

_currentArea->addEvent(event);
if (handlePicker(event))
continue;
if (handleKeys(event))
continue;
}
}

_currentArea->processEventQueue();
}

bool Module::handleCamera(const Events::Event &e) {
Expand Down Expand Up @@ -287,33 +294,84 @@ bool Module::handleCamera(const Events::Event &e) {
CameraMan.moveRelative(0.0, -speed, 0.0);
else if (e.key.keysym.sym == SDLK_PAGEUP)
CameraMan.pitch(Common::deg2rad(5));
//CameraMan.rotate(Common::deg2rad( 5), 1.0, 0.0, 0.0);
else if (e.key.keysym.sym == SDLK_PAGEDOWN)
CameraMan.pitch(Common::deg2rad(-5));
//CameraMan.rotate(Common::deg2rad(-5), 1.0, 0.0, 0.0);
else if (e.key.keysym.sym == SDLK_END) {
float x, y, z;
CameraMan.getDirection(x, y, z);
CameraMan.setDirection(x, 0.0, z);
} else if (e.key.keysym.sym == SDLK_RETURN) {
GfxMan.toggleVSync();
} else if (e.key.keysym.scancode == SDL_SCANCODE_1) {
GfxMan.setFSAA(GfxMan.getCurrentFSAA() / 2);
} else if (e.key.keysym.scancode == SDL_SCANCODE_2) {
GfxMan.setFSAA((GfxMan.getCurrentFSAA() == 0) ? 2 : (GfxMan.getCurrentFSAA() * 2));
} else if (e.key.keysym.scancode == SDL_SCANCODE_F) {
double averageFrameTime, averageFPS;
if (GfxMan.getRenderStatistics(averageFrameTime, averageFPS))
warning("FPS: %lf, AverageFrameTime: %lf", averageFPS, averageFrameTime);
else
warning("NO STATS");

} else
return false;

checkCurrentObject();
return true;
}

bool Module::handlePicker(const Events::Event &e) {
if (e.type != Events::kEventMouseMove)
return false;

checkCurrentObject();
return true;
}

bool Module::handleKeys(const Events::Event &e) {
if ((e.type != Events::kEventKeyDown) && (e.type != Events::kEventKeyUp))
return false;

if (e.type == Events::kEventKeyDown) {
if (e.key.keysym.sym == SDLK_RETURN)
GfxMan.toggleVSync();
else if (e.key.keysym.scancode == SDL_SCANCODE_1)
GfxMan.setFSAA(GfxMan.getCurrentFSAA() / 2);
else if (e.key.keysym.scancode == SDL_SCANCODE_2)
GfxMan.setFSAA((GfxMan.getCurrentFSAA() == 0) ? 2 : (GfxMan.getCurrentFSAA() * 2));
else if (e.key.keysym.sym == SDLK_TAB)
_currentArea->setHighlightAll(true);
else if (e.key.keysym.scancode == SDL_SCANCODE_F) {
double averageFrameTime, averageFPS;
if (GfxMan.getRenderStatistics(averageFrameTime, averageFPS))
warning("FPS: %lf, AverageFrameTime: %lf", averageFPS, averageFrameTime);
} else
return false;
}

if (e.type == Events::kEventKeyUp) {
if (e.key.keysym.sym == SDLK_TAB) {
_currentArea->setHighlightAll(false);
checkCurrentObject();
} else
return false;
}

return true;
}

void Module::checkCurrentObject() {
int x, y;
CursorMan.getPosition(x, y);

float distance;
Engines::NWN::Object *object = _currentArea->getObjectAt(x, y, distance);

// Highlight the new object
if (object)
object->setHighlight(true);

// If the highlighting changed...
if (_currentObject != object) {
// If we're not highlighting everything anyway, dehighlight the old object.
if (_currentObject && !_currentArea->getHighlightAll())
_currentObject->setHighlight(false);

_currentObject = object;

// Act on a new object
if (_currentObject)
warning("Entered object \"%s\" (\"%s\")", _currentObject->getTag().c_str(), _currentObject->getName().c_str());
}
}

void Module::unload() {
unloadAreas();
unloadTexturePack();
Expand Down Expand Up @@ -417,7 +475,8 @@ void Module::unloadAreas() {
_areas.clear();
_newArea.clear();

_currentArea = 0;
_currentArea = 0;
_currentObject = 0;
}

const Common::UString &Module::getName() const {
Expand Down
7 changes: 7 additions & 0 deletions src/engines/nwn/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ namespace Engines {
namespace NWN {

class Area;
class Object;

class Module : public Aurora::NWScript::Object, public Aurora::NWScript::ObjectContainer {
public:
Expand Down Expand Up @@ -96,6 +97,8 @@ class Module : public Aurora::NWScript::Object, public Aurora::NWScript::ObjectC
Common::UString _newArea; ///< The new area to enter.
Area *_currentArea; ///< The current area.

Engines::NWN::Object *_currentObject; ///< The currently selected object.

Common::UString _newModule; ///< The module we should change to.


Expand All @@ -121,6 +124,10 @@ class Module : public Aurora::NWScript::Object, public Aurora::NWScript::ObjectC

void handleEvents();
bool handleCamera(const Events::Event &e);
bool handlePicker(const Events::Event &e);
bool handleKeys(const Events::Event &e);

void checkCurrentObject();
};

} // End of namespace NWN
Expand Down
14 changes: 13 additions & 1 deletion src/engines/nwn/object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ namespace Engines {
namespace NWN {

Object::Object(ObjectType type) : _type(type),
_soundSet(Aurora::kFieldIDInvalid), _ssf(0), _static(false), _usable(true), _area(0) {
_soundSet(Aurora::kFieldIDInvalid), _ssf(0), _static(false), _usable(true), _highlight(false), _area(0) {

_position [0] = 0.0;
_position [1] = 0.0;
Expand Down Expand Up @@ -112,6 +112,10 @@ const Aurora::SSFFile *Object::getSSF() {
return _ssf;
}

const std::vector<Common::UString> &Object::getModelIDs() const {
return _modelIDs;
}

bool Object::isStatic() const {
return _static;
}
Expand All @@ -124,6 +128,14 @@ bool Object::isClickable() const {
return !_static && _usable;
}

bool Object::getHighlight() const {
return _highlight;
}

void Object::setHighlight(bool highlight) {
_highlight = highlight;
}

Area *Object::getArea() const {
return _area;
}
Expand Down

0 comments on commit 721716b

Please sign in to comment.