/* 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 "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_GROUP_00); 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; } Mover::~Mover() { } /** * 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); } /** * tick function */ void Mover::tick(float dt) { if (this->state == Closed) { if (this->checkPlayerInActionRadius()) { this->state = Opening; } } else if (this->state == Opening) { if (this->checkOpen(dt)) { this->state = Open; this->setAbsCoor(this->originCoordinates + this->targetCoordinates); } } else if (this->state == Open) { if (!this->checkPlayerInActionRadius()) { this->state = Closing; } } else if (this->state == Closing) { if (this->checkClosed(dt)) { this->state = Closed; this->setAbsCoor(this->originCoordinates); } 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; Vector vDistance; float powerDistance; for (ObjectList::const_iterator it = Playable::objectList().begin(); it != Playable::objectList().end(); ++it) // for all players { entity = (*it); vDistance = this->originCoordinates - entity->getAbsCoor(); powerDistance = vDistance.x * vDistance.x + vDistance.z * vDistance.z; if( powerDistance < (this->actionRadius * this->actionRadius)) return true; } for (ObjectList::const_iterator it = GenericNPC::objectList().begin(); it != GenericNPC::objectList().end(); ++it) { entity = (*it); vDistance = this->originCoordinates - entity->getAbsCoor(); powerDistance = vDistance.x * vDistance.x + vDistance.z * vDistance.z; if( powerDistance < (this->actionRadius * this->actionRadius)) return true; } return false; }