Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "engines/stark/movement/followpath.h"
00024
00025 #include "engines/stark/services/global.h"
00026 #include "engines/stark/services/services.h"
00027 #include "engines/stark/services/stateprovider.h"
00028
00029 #include "engines/stark/resources/anim.h"
00030 #include "engines/stark/resources/floor.h"
00031 #include "engines/stark/resources/item.h"
00032 #include "engines/stark/resources/path.h"
00033
00034 namespace Stark {
00035
00036 FollowPath::FollowPath(Resources::ItemVisual *item) :
00037 Movement(item),
00038 _path(nullptr),
00039 _speed(0.0),
00040 _position(0.0),
00041 _previouslyEnabled(true),
00042 _anim(nullptr) {
00043 }
00044
00045 FollowPath::~FollowPath() {
00046 }
00047
00048 void FollowPath::start() {
00049 Movement::start();
00050
00051 _previouslyEnabled = _item->isEnabled();
00052 _item->setEnabled(true);
00053
00054 updateItemPosition(0, 0);
00055 changeItemAnim();
00056 }
00057
00058 void FollowPath::stop(bool force) {
00059 Movement::stop(force);
00060
00061 changeItemAnim();
00062 _item->setEnabled(_previouslyEnabled);
00063 }
00064
00065 void FollowPath::onGameLoop() {
00066
00067 _position += _speed * StarkGlobal->getMillisecondsPerGameloop();
00068
00069
00070 uint currentEdge = 0;
00071 float positionInEdge = _position;
00072 for (uint i = 0; i < _path->getEdgeCount(); i++) {
00073 float edgeLength = _path->getWeightedEdgeLength(i);
00074 if (positionInEdge < edgeLength) {
00075 break;
00076 }
00077
00078 positionInEdge -= edgeLength;
00079 currentEdge++;
00080 }
00081
00082
00083 if (currentEdge >= _path->getEdgeCount()) {
00084 stop();
00085 return;
00086 }
00087
00088 updateItemPosition(currentEdge, positionInEdge);
00089 }
00090
00091 void FollowPath::updateItemPosition(uint currentEdge, float positionInEdge) const {
00092 Math::Vector3d newPosition = _path->getWeightedPositionInEdge(currentEdge, positionInEdge);
00093
00094
00095 if (is3D()) {
00096 Resources::FloorPositionedItem *item3D = Resources::Object::cast<Resources::FloorPositionedItem>(_item);
00097 Resources::Floor *floor = StarkGlobal->getCurrent()->getFloor();
00098
00099 int32 floorFaceIndex = floor->findFaceContainingPoint(newPosition);
00100 if (floorFaceIndex >= 0) {
00101 item3D->setFloorFaceIndex(floorFaceIndex);
00102 } else {
00103 item3D->overrideSortKey(_path->getSortKey());
00104 }
00105
00106 item3D->setPosition3D(newPosition);
00107
00108 Math::Vector3d direction = _path->getEdgeDirection(currentEdge);
00109 item3D->setDirection(computeAngleBetweenVectorsXYPlane(direction, Math::Vector3d(1.0, 0.0, 0.0)));
00110 } else {
00111 Common::Point position2D = Common::Point(newPosition.x(), newPosition.y());
00112 _item->setPosition2D(position2D);
00113 }
00114 }
00115
00116 void FollowPath::changeItemAnim() {
00117 if (_ended) {
00118 if (_anim) {
00119 _item->resetActionAnim();
00120 } else {
00121 _item->setAnimActivity(Resources::Anim::kActorActivityIdle);
00122 }
00123 } else {
00124 if (_anim) {
00125 _item->playActionAnim(_anim);
00126 } else {
00127 _item->setAnimActivity(Resources::Anim::kActorActivityWalk);
00128 }
00129 }
00130 }
00131
00132 void FollowPath::setPath(Resources::Path *path) {
00133 _path = path;
00134 }
00135
00136 void FollowPath::setSpeed(float speed) {
00137 _speed = speed;
00138 }
00139
00140 bool FollowPath::is3D() const {
00141 return _path->getSubType() == Resources::Path::kPath3D;
00142 }
00143
00144 void FollowPath::setAnim(Resources::Anim *anim) {
00145 _anim = anim;
00146 }
00147
00148 uint32 FollowPath::getType() const {
00149 return kTypeFollowPath;
00150 }
00151
00152 void FollowPath::saveLoad(ResourceSerializer *serializer) {
00153 serializer->syncAsResourceReference(&_path);
00154 serializer->syncAsResourceReference(&_anim);
00155 serializer->syncAsFloat(_position);
00156 serializer->syncAsFloat(_speed);
00157 serializer->syncAsUint32LE(_previouslyEnabled);
00158 }
00159
00160 }