/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2004 orx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. ### File Specific: main-programmer: Fabian 'x3n' Landau co-programmer: */ #include "sound/resource_sound_buffer.h" #include "util/loading/load_param.h" #include "util/loading/factory.h" #include "debug.h" #include "mover.h" ObjectListDefinition(Mover); CREATE_FACTORY(Mover); /** * initializes the Mover from a XmlElement */ Mover::Mover(const TiXmlElement* root) { this->registerObject(this, Mover::_objectList); this->toList(OM_COMMON); this->targetCoordinates = Vector(0, 0, 0); this->originCoordinates = Vector(0, 87, -256); this->actionRadius = 40.0; this->actionTime = 1.0; if (root != NULL) this->loadParams(root); this->updateNode(0.001); this->originCoordinates = this->getAbsCoor(); this->state = Closed; this->soundSource_starting.setSourceNode(this); this->soundSource_moving.setSourceNode(this); this->soundSource_ending.setSourceNode(this); // this->soundSource_starting.setRolloffFactor(0.0); // this->soundSource_moving.setRolloffFactor(0.0); // this->soundSource_ending.setRolloffFactor(0.0); } Mover::~Mover() { if (this->soundSource_starting.isPlaying()) this->soundSource_starting.stop(); if (this->soundSource_moving.isPlaying()) this->soundSource_moving.stop(); if (this->soundSource_ending.isPlaying()) this->soundSource_ending.stop(); } /** * loads the Settings of the Mover from an XML-element. * @param root the XML-element to load the Movers's properties from */ void Mover::loadParams(const TiXmlElement* root) { WorldEntity::loadParams(root); LoadParam(root, "rel-target-coor", this, Mover, setTargetCoordinates) .describe("sets the relative target coordinates of the door"); LoadParam(root, "action-radius", this, Mover, setActionRadius) .describe("sets the action radius of the door") .defaultValues(40.0); LoadParam(root, "action-time", this, Mover, setActionTime) .describe("sets the action time of the door") .defaultValues(1.0); LoadParam(root, "opening-sound", this, Mover, setOpeningSoundFile) .describe("Sets the file of the opening sound source"); LoadParam(root, "opened-sound", this, Mover, setOpenedSoundFile) .describe("Sets the file of the opened sound source"); LoadParam(root, "moving-sound", this, Mover, setMovingSoundFile) .describe("Sets the file of the moving sound source"); LoadParam(root, "closing-sound", this, Mover, setClosingSoundFile) .describe("Sets the file of the closing sound source"); LoadParam(root, "closed-sound", this, Mover, setClosedSoundFile) .describe("Sets the file of the closed sound source"); } void Mover::setOpeningSoundFile(const std::string& fileName) { this->soundBuffer_opening = OrxSound::ResourceSoundBuffer(fileName); } void Mover::setOpenedSoundFile(const std::string& fileName) { this->soundBuffer_opened = OrxSound::ResourceSoundBuffer(fileName); } void Mover::setMovingSoundFile(const std::string& fileName) { this->soundBuffer_moving = OrxSound::ResourceSoundBuffer(fileName); } void Mover::setClosingSoundFile(const std::string& fileName) { this->soundBuffer_closing = OrxSound::ResourceSoundBuffer(fileName); } void Mover::setClosedSoundFile(const std::string& fileName) { this->soundBuffer_closed = OrxSound::ResourceSoundBuffer(fileName); } /** * tick function */ void Mover::tick(float dt) { if (this->state == Closed) { if (this->checkPlayerInActionRadius()) { this->state = Opening; if (this->soundBuffer_opening.loaded()) this->soundSource_starting.play(this->soundBuffer_opening); if (this->soundBuffer_moving.loaded()) this->soundSource_moving.play(this->soundBuffer_moving, 1.0, true); } } else if (this->state == Opening) { if (this->checkOpen(dt)) { this->state = Open; this->setAbsCoor(this->originCoordinates + this->targetCoordinates); if (this->soundBuffer_opened.loaded()) this->soundSource_ending.play(this->soundBuffer_opened); if (this->soundBuffer_moving.loaded()) this->soundSource_moving.stop(); } } else if (this->state == Open) { if (!this->checkPlayerInActionRadius()) { this->state = Closing; if (this->soundBuffer_closing.loaded()) this->soundSource_starting.play(this->soundBuffer_closing); if (this->soundBuffer_moving.loaded()) this->soundSource_moving.play(this->soundBuffer_moving, 1.0, true); } } else if (this->state == Closing) { if (this->checkClosed(dt)) { this->state = Closed; this->setAbsCoor(this->originCoordinates); if (this->soundBuffer_closed.loaded()) this->soundSource_ending.play(this->soundBuffer_closed); if (this->soundBuffer_moving.loaded()) this->soundSource_moving.stop(); } if (this->checkPlayerInActionRadius()) { this->state = Opening; } } if (this->state == Opening) { this->shiftCoor(this->targetCoordinates / this->actionTime * dt); } else if (this->state == Closing) { this->shiftCoor(this->targetCoordinates * (-1) / this->actionTime * dt); } } /** * checks if the door is open */ bool Mover::checkOpen(float dt) { if (fabs((this->originCoordinates - (this->getAbsCoor() - this->targetCoordinates)).len()) < fabs(2 * (this->targetCoordinates / this->actionTime * dt).len())) return true; return false; } /** * checks if the door is closed */ bool Mover::checkClosed(float dt) { if (fabs((this->getAbsCoor() - this->originCoordinates).len()) < fabs(2 * (this->targetCoordinates / this->actionTime * dt).len())) return true; return false; } #include "playable.h" #include "generic_npc.h" /** * checks if the player is within the action radius */ bool Mover::checkPlayerInActionRadius() { WorldEntity* entity; float distance; for (ObjectList::const_iterator it = Playable::objectList().begin(); it != Playable::objectList().end(); ++it) // for all players { entity = (*it); distance = (this->originCoordinates - entity->getAbsCoor()).len(); if (distance < this->actionRadius) { this->soundSource_starting.setSourceNode(entity); // bad hack! this->soundSource_moving.setSourceNode(entity); // TODO: make the sound louder without this->soundSource_ending.setSourceNode(entity); // attaching him to the player return true; } } for (ObjectList::const_iterator it = GenericNPC::objectList().begin(); it != GenericNPC::objectList().end(); ++it) { entity = (*it); distance = (this->originCoordinates - entity->getAbsCoor()).len(); if (distance < this->actionRadius) return true; } return false; }