32 #include "util/log/logger.h"
33 #include "util/base/exception.h"
34 #include "util/math/fife_math.h"
35 #include "util/time/timemanager.h"
36 #include "model/metamodel/grids/cellgrid.h"
37 #include "model/metamodel/ipather.h"
38 #include "model/metamodel/action.h"
39 #include "model/metamodel/timeprovider.h"
40 #include "model/structures/layer.h"
41 #include "model/structures/map.h"
42 #include "model/structures/instancetree.h"
47 static Logger _log(LM_INSTANCE);
51 ActionInfo(IPather* pather,
const Location& curloc):
56 m_action_start_time(0),
57 m_action_offset_time(0),
59 m_pather_session_id(-1),
64 if (m_pather_session_id != -1) {
65 m_pather->cancelSession(m_pather_session_id);
80 uint32_t m_action_start_time;
82 uint32_t m_action_offset_time;
84 uint32_t m_prev_call_time;
86 int32_t m_pather_session_id;
95 SayInfo(
const std::string& txt, uint32_t duration):
102 uint32_t m_start_time;
105 Instance::InstanceActivity::InstanceActivity(Instance& source):
106 m_location(source.m_location),
107 m_rotation(source.m_rotation),
111 m_timemultiplier(1.0),
117 m_timeprovider(NULL),
118 m_blocking(source.m_blocking) {
119 if (source.m_facinglocation) {
120 m_facinglocation = *source.m_facinglocation;
124 Instance::InstanceActivity::~InstanceActivity() {
127 delete m_timeprovider;
131 source.m_changeinfo = ICHANGE_NO_CHANGES;
132 if (m_location != source.m_location) {
133 source.m_changeinfo |= ICHANGE_LOC;
134 if (m_location.getLayerCoordinates() != source.m_location.getLayerCoordinates()) {
135 source.m_changeinfo |= ICHANGE_CELL;
137 m_location = source.m_location;
139 if (m_rotation != source.m_rotation) {
140 source.m_changeinfo |= ICHANGE_ROTATION;
141 m_rotation = source.m_rotation;
143 if (source.m_facinglocation && (m_facinglocation != *source.m_facinglocation)) {
144 source.m_changeinfo |= ICHANGE_FACING_LOC;
145 m_facinglocation = *source.m_facinglocation;
147 if (m_actioninfo && (m_speed != m_actioninfo->m_speed)) {
148 source.m_changeinfo |= ICHANGE_SPEED;
149 m_speed = m_actioninfo->m_speed;
151 if (m_actioninfo && (m_action != m_actioninfo->m_action)) {
152 source.m_changeinfo |= ICHANGE_ACTION;
153 m_action = m_actioninfo->m_action;
155 if (m_timeprovider && (m_timemultiplier != m_timeprovider->getMultiplier())) {
156 source.m_changeinfo |= ICHANGE_TIME_MULTIPLIER;
157 m_timemultiplier = m_timeprovider->getMultiplier();
159 if (m_sayinfo && (m_saytxt != m_sayinfo->m_txt)) {
160 source.m_changeinfo |= ICHANGE_SAYTEXT;
161 m_saytxt = m_sayinfo->m_txt;
163 if (m_blocking != source.m_blocking) {
164 source.m_changeinfo |= ICHANGE_BLOCK;
165 m_blocking = source.m_blocking;
168 if (source.m_changeinfo != ICHANGE_NO_CHANGES) {
169 std::vector<InstanceChangeListener*>::iterator i = m_changelisteners.begin();
170 while (i != m_changelisteners.end()) {
173 (*i)->onInstanceChanged(&source, source.m_changeinfo);
178 m_changelisteners.erase(
179 std::remove(m_changelisteners.begin(),m_changelisteners.end(),
180 (InstanceChangeListener*)NULL),
181 m_changelisteners.end());
189 m_changeinfo(ICHANGE_NO_CHANGES),
191 m_location(location),
192 m_facinglocation(NULL),
194 m_blocking(object->isBlocking()),
195 m_override_blocking(false) {
199 std::vector<InstanceDeleteListener *>::iterator itor;
200 for(itor = m_deletelisteners.begin(); itor != m_deletelisteners.end(); ++itor) {
202 (*itor)->onInstanceDeleted(
this);
206 if(m_activity && m_activity->m_actioninfo) {
209 m_activity->m_actionlisteners.clear();
214 delete m_facinglocation;
218 void Instance::initializeChanges() {
220 m_activity =
new InstanceActivity(*
this);
221 if(m_location.getLayer()) {
222 m_location.getLayer()->setInstanceActivityStatus(
this,
true);
228 return (m_activity != 0);
233 if(m_location != loc) {
235 if (m_location.getLayerCoordinates() != loc.getLayerCoordinates()) {
236 m_location.getLayer()->getInstanceTree()->removeInstance(
this);
238 m_location.getLayer()->getInstanceTree()->addInstance(
this);
245 if (m_location.getLayerCoordinates() != loc.getLayerCoordinates()) {
246 m_location.getLayer()->getInstanceTree()->removeInstance(
this);
248 m_location.getLayer()->getInstanceTree()->addInstance(
this);
257 if(m_rotation != rotation) {
259 m_rotation = rotation;
263 m_rotation = rotation;
273 if (m_override_blocking) {
274 m_blocking = blocking;
284 m_activity->m_actionlisteners.push_back(listener);
291 std::vector<InstanceActionListener*>::iterator i = m_activity->m_actionlisteners.begin();
292 while (i != m_activity->m_actionlisteners.end()) {
293 if ((*i) == listener) {
299 FL_WARN(_log,
"Cannot remove unknown listener");
304 m_activity->m_changelisteners.push_back(listener);
312 std::vector<InstanceActionListener*>::iterator i = m_activity->m_actionlisteners.begin();
313 while (i != m_activity->m_actionlisteners.end()) {
315 (*i)->onInstanceActionFrame(
this, action, frame);
325 std::vector<InstanceChangeListener*>::iterator i = m_activity->m_changelisteners.begin();
326 while (i != m_activity->m_changelisteners.end()) {
327 if ((*i) == listener) {
333 FL_WARN(_log,
"Cannot remove unknown listener");
335 void Instance::initializeAction(
const std::string& action_name) {
338 const Action *old_action = m_activity->m_actioninfo ? m_activity->m_actioninfo->m_action : NULL;
339 if (m_activity->m_actioninfo) {
340 delete m_activity->m_actioninfo;
341 m_activity->m_actioninfo = NULL;
343 m_activity->m_actioninfo =
new ActionInfo(m_object->
getPather(), m_location);
344 m_activity->m_actioninfo->m_action = m_object->
getAction(action_name);
345 if (!m_activity->m_actioninfo->m_action) {
346 delete m_activity->m_actioninfo;
347 m_activity->m_actioninfo = NULL;
348 throw NotFound(std::string(
"action ") + action_name +
" not found");
350 m_activity->m_actioninfo->m_prev_call_time =
getRuntime();
351 if (m_activity->m_actioninfo->m_action != old_action) {
352 m_activity->m_actioninfo->m_action_start_time = m_activity->m_actioninfo->m_prev_call_time;
356 void Instance::move(
const std::string& action_name,
const Location& target,
const double speed) {
358 initializeAction(action_name);
359 m_activity->m_actioninfo->m_target =
new Location(target);
360 m_activity->m_actioninfo->m_speed = speed;
362 FL_DBG(_log,
LMsg(
"starting action ") << action_name <<
" from" << m_location <<
" to " << target <<
" with speed " << speed);
367 initializeAction(action_name);
368 m_activity->m_actioninfo->m_target =
new Location(leader->
getLocationRef());
369 m_activity->m_actioninfo->m_speed = speed;
370 m_activity->m_actioninfo->m_leader = leader;
373 FL_DBG(_log,
LMsg(
"starting action ") << action_name <<
" from" << m_location <<
" to " << *m_activity->m_actioninfo->m_target <<
" with speed " << speed);
376 void Instance::act(
const std::string& action_name,
const Location& direction,
bool repeating) {
378 initializeAction(action_name);
379 m_activity->m_actioninfo->m_repeating = repeating;
385 delete m_activity->m_sayinfo;
386 m_activity->m_sayinfo = NULL;
389 m_activity->m_sayinfo =
new SayInfo(text, duration);
390 m_activity->m_sayinfo->m_start_time =
getRuntime();
395 if (m_activity && m_activity->m_sayinfo) {
396 return &m_activity->m_sayinfo->m_txt;
402 if (!m_facinglocation) {
403 m_facinglocation =
new Location(loc);
405 *m_facinglocation = loc;
409 bool Instance::process_movement() {
411 ActionInfo* info = m_activity->m_actioninfo;
413 uint32_t timedelta = m_activity->m_timeprovider->getGameTime() - info->m_prev_call_time;
416 double distance_to_travel = (
static_cast<double>(timedelta) / 1000.0) * info->m_speed;
419 Location nextLocation = m_location;
420 info->m_pather_session_id = info->m_pather->getNextLocation(
421 this, *info->m_target,
422 distance_to_travel, nextLocation, *m_facinglocation,
423 info->m_pather_session_id);
424 m_location.getLayer()->getInstanceTree()->removeInstance(
this);
425 m_location = nextLocation;
428 m_location.getLayer()->getInstanceTree()->addInstance(
this);
430 if (info->m_pather_session_id == -1) {
438 return ICHANGE_NO_CHANGES;
441 m_deletelisteners.erase(std::remove(m_deletelisteners.begin(),m_deletelisteners.end(),
442 (InstanceDeleteListener*)NULL), m_deletelisteners.end());
443 m_activity->update(*
this);
444 if (!m_activity->m_timeprovider) {
447 ActionInfo* info = m_activity->m_actioninfo;
451 if (info->m_target) {
454 if (info->m_leader && (info->m_leader->getLocationRef() != *info->m_target)) {
455 *info->m_target = info->m_leader->getLocation();
457 bool movement_finished = process_movement();
458 if (movement_finished) {
464 if (m_activity->m_timeprovider->getGameTime() - info->m_action_start_time + info->m_action_offset_time >= info->m_action->getDuration()) {
465 if (info->m_repeating) {
466 info->m_action_start_time = m_activity->m_timeprovider->getGameTime();
468 info->m_action_offset_time = 0;
476 if( m_activity->m_actioninfo ) {
477 m_activity->m_actioninfo->m_prev_call_time = m_activity->m_timeprovider->getGameTime();
480 if (m_activity->m_sayinfo) {
481 if (m_activity->m_sayinfo->m_duration > 0) {
482 if (m_activity->m_timeprovider->getGameTime() >= m_activity->m_sayinfo->m_start_time + m_activity->m_sayinfo->m_duration) {
486 }
else if (!m_activity->m_actioninfo && m_changeinfo == ICHANGE_NO_CHANGES && m_activity->m_actionlisteners.empty()) {
490 return ICHANGE_NO_CHANGES;
495 void Instance::finalizeAction() {
496 FL_DBG(_log,
"finalizing action");
498 assert(m_activity->m_actioninfo);
500 if( m_activity->m_actioninfo->m_leader ) {
501 m_activity->m_actioninfo->m_leader->removeDeleteListener(
this);
504 Action* action = m_activity->m_actioninfo->m_action;
505 delete m_activity->m_actioninfo;
506 m_activity->m_actioninfo = NULL;
508 std::vector<InstanceActionListener*>::iterator i = m_activity->m_actionlisteners.begin();
509 while (i != m_activity->m_actionlisteners.end()) {
511 (*i)->onInstanceActionFinished(
this, action);
514 m_activity->m_actionlisteners.erase(
515 std::remove(m_activity->m_actionlisteners.begin(),
516 m_activity->m_actionlisteners.end(),
517 (InstanceActionListener*)NULL),
518 m_activity->m_actionlisteners.end());
522 if (m_activity && m_activity->m_actioninfo) {
523 return m_activity->m_actioninfo->m_action;
529 if (m_activity && m_activity->m_actioninfo && m_activity->m_actioninfo->m_target) {
530 return *m_activity->m_actioninfo->m_target;
536 if (m_activity && m_activity->m_actioninfo) {
537 return m_activity->m_actioninfo->m_speed;
547 if (!m_facinglocation) {
548 m_facinglocation =
new Location(m_location);
549 m_facinglocation->setExactLayerCoordinates(m_facinglocation->getExactLayerCoordinates() +
ExactModelCoordinate(1.0, 0.0));
552 return *m_facinglocation;
556 if (m_activity && m_activity->m_actioninfo) {
557 if(!m_activity->m_timeprovider)
559 return m_activity->m_timeprovider->getGameTime() - m_activity->m_actioninfo->m_action_start_time + m_activity->m_actioninfo->m_action_offset_time;
565 m_activity->m_actioninfo->m_action_offset_time = time_offset;
568 void Instance::bindTimeProvider() {
569 float multiplier = 1.0;
570 if (m_activity->m_timeprovider) {
571 multiplier = m_activity->m_timeprovider->getMultiplier();
573 delete m_activity->m_timeprovider;
574 m_activity->m_timeprovider = NULL;
576 if (m_location.getLayer()) {
577 Map* map = m_location.getLayer()->getMap();
579 m_activity->m_timeprovider =
new TimeProvider(map->getTimeProvider());
582 if (!m_activity->m_timeprovider) {
583 m_activity->m_timeprovider =
new TimeProvider(NULL);
585 m_activity->m_timeprovider->setMultiplier(multiplier);
595 if (!m_activity->m_timeprovider) {
598 m_activity->m_timeprovider->setMultiplier(multip);
602 if (m_activity && m_activity->m_timeprovider) {
603 return m_activity->m_timeprovider->getMultiplier();
609 if (m_activity && m_activity->m_timeprovider) {
610 return m_activity->m_timeprovider->getTotalMultiplier();
612 if (m_location.getLayer()) {
613 Map* map = m_location.getLayer()->getMap();
623 if(!m_activity->m_timeprovider)
625 return m_activity->m_timeprovider->getGameTime();
627 if (m_location.getLayer()) {
628 Map* map = m_location.getLayer()->getMap();
633 return TimeManager::instance()->getTime();
637 m_deletelisteners.push_back(listener);
641 if (!m_deletelisteners.empty()) {
642 std::vector<InstanceDeleteListener*>::iterator itor;
643 itor = std::find(m_deletelisteners.begin(), m_deletelisteners.end(), listener);
644 if(itor != m_deletelisteners.end()) {
645 if ((*itor) == listener) {
650 FL_WARN(_log,
"Cannot remove unknown listener");
656 if(m_activity && m_activity->m_actioninfo &&
657 m_activity->m_actioninfo->m_leader == instance) {
658 m_activity->m_actioninfo->m_leader = NULL;