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/abstractpather.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(AbstractPather* 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 unsigned int m_action_start_time;
82 unsigned int m_action_offset_time;
84 unsigned int m_prev_call_time;
86 int m_pather_session_id;
88 AbstractPather* m_pather;
95 SayInfo(
const std::string& txt,
unsigned int duration):
101 unsigned int m_duration;
102 unsigned int 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 if (source.m_facinglocation) {
119 m_facinglocation = *source.m_facinglocation;
123 Instance::InstanceActivity::~InstanceActivity() {
126 delete m_timeprovider;
130 source.m_changeinfo = ICHANGE_NO_CHANGES;
131 if (m_location != source.m_location) {
132 source.m_changeinfo |= ICHANGE_LOC;
133 m_location = source.m_location;
135 if (m_rotation != source.m_rotation) {
136 source.m_changeinfo |= ICHANGE_ROTATION;
137 m_rotation = source.m_rotation;
139 if (source.m_facinglocation && (m_facinglocation != *source.m_facinglocation)) {
140 source.m_changeinfo |= ICHANGE_FACING_LOC;
141 m_facinglocation = *source.m_facinglocation;
143 if (m_actioninfo && (m_speed != m_actioninfo->m_speed)) {
144 source.m_changeinfo |= ICHANGE_SPEED;
145 m_speed = m_actioninfo->m_speed;
147 if (m_actioninfo && (m_action != m_actioninfo->m_action)) {
148 source.m_changeinfo |= ICHANGE_ACTION;
149 m_action = m_actioninfo->m_action;
151 if (m_timeprovider && (m_timemultiplier != m_timeprovider->getMultiplier())) {
152 source.m_changeinfo |= ICHANGE_TIME_MULTIPLIER;
153 m_timemultiplier = m_timeprovider->getMultiplier();
155 if (m_sayinfo && (m_saytxt != m_sayinfo->m_txt)) {
156 source.m_changeinfo |= ICHANGE_SAYTEXT;
157 m_saytxt = m_sayinfo->m_txt;
160 if (source.m_changeinfo != ICHANGE_NO_CHANGES) {
161 std::vector<InstanceChangeListener*>::iterator i = m_changelisteners.begin();
162 while (i != m_changelisteners.end()) {
165 (*i)->onInstanceChanged(&source, source.m_changeinfo);
170 m_changelisteners.erase(
171 std::remove(m_changelisteners.begin(),m_changelisteners.end(),
172 (InstanceChangeListener*)NULL),
173 m_changelisteners.end());
181 m_changeinfo(ICHANGE_NO_CHANGES),
183 m_location(location),
184 m_facinglocation(NULL),
186 m_blocking(object->isBlocking()),
187 m_override_blocking(false) {
191 std::vector<InstanceDeleteListener *>::iterator itor;
192 for(itor = m_deletelisteners.begin();
193 itor != m_deletelisteners.end();
195 (*itor)->onInstanceDeleted(
this);
198 if(m_activity && m_activity->m_actioninfo) {
201 m_activity->m_actionlisteners.clear();
206 delete m_facinglocation;
210 void Instance::initializeChanges() {
212 m_activity =
new InstanceActivity(*
this);
213 if(m_location.getLayer()) {
214 m_location.getLayer()->setInstanceActivityStatus(
this,
true);
220 return bool(m_activity);
224 if(m_location != loc) {
235 if(m_rotation != rotation) {
236 m_rotation = rotation;
250 if (m_override_blocking) {
251 m_blocking = blocking;
261 m_activity->m_actionlisteners.push_back(listener);
268 std::vector<InstanceActionListener*>::iterator i = m_activity->m_actionlisteners.begin();
269 while (i != m_activity->m_actionlisteners.end()) {
270 if ((*i) == listener) {
276 FL_WARN(_log,
"Cannot remove unknown listener");
281 m_activity->m_changelisteners.push_back(listener);
288 std::vector<InstanceChangeListener*>::iterator i = m_activity->m_changelisteners.begin();
289 while (i != m_activity->m_changelisteners.end()) {
290 if ((*i) == listener) {
296 FL_WARN(_log,
"Cannot remove unknown listener");
298 void Instance::initializeAction(
const std::string& action_name) {
301 const Action *old_action = m_activity->m_actioninfo ? m_activity->m_actioninfo->m_action : NULL;
302 if (m_activity->m_actioninfo) {
303 delete m_activity->m_actioninfo;
304 m_activity->m_actioninfo = NULL;
306 m_activity->m_actioninfo =
new ActionInfo(m_object->
getPather(), m_location);
307 m_activity->m_actioninfo->m_action = m_object->
getAction(action_name);
308 if (!m_activity->m_actioninfo->m_action) {
309 delete m_activity->m_actioninfo;
310 m_activity->m_actioninfo = NULL;
311 throw NotFound(std::string(
"action ") + action_name +
" not found");
313 m_activity->m_actioninfo->m_prev_call_time =
getRuntime();
314 if (m_activity->m_actioninfo->m_action != old_action) {
315 m_activity->m_actioninfo->m_action_start_time = m_activity->m_actioninfo->m_prev_call_time;
319 void Instance::move(
const std::string& action_name,
const Location& target,
const double speed) {
321 initializeAction(action_name);
322 m_activity->m_actioninfo->m_target =
new Location(target);
323 m_activity->m_actioninfo->m_speed = speed;
325 FL_DBG(_log,
LMsg(
"starting action ") << action_name <<
" from" << m_location <<
" to " << target <<
" with speed " << speed);
330 initializeAction(action_name);
331 m_activity->m_actioninfo->m_target =
new Location(leader->
getLocationRef());
332 m_activity->m_actioninfo->m_speed = speed;
333 m_activity->m_actioninfo->m_leader = leader;
336 FL_DBG(_log,
LMsg(
"starting action ") << action_name <<
" from" << m_location <<
" to " << *m_activity->m_actioninfo->m_target <<
" with speed " << speed);
339 void Instance::act(
const std::string& action_name,
const Location& direction,
bool repeating) {
341 initializeAction(action_name);
342 m_activity->m_actioninfo->m_repeating = repeating;
348 delete m_activity->m_sayinfo;
349 m_activity->m_sayinfo = NULL;
352 m_activity->m_sayinfo =
new SayInfo(text, duration);
353 m_activity->m_sayinfo->m_start_time =
getRuntime();
358 if (m_activity && m_activity->m_sayinfo) {
359 return &m_activity->m_sayinfo->m_txt;
365 if (!m_facinglocation) {
366 m_facinglocation =
new Location(loc);
368 *m_facinglocation = loc;
372 bool Instance::process_movement() {
373 FL_DBG(_log,
"Moving...");
374 ActionInfo* info = m_activity->m_actioninfo;
376 unsigned int timedelta = m_activity->m_timeprovider->getGameTime() - info->m_prev_call_time;
377 FL_DBG(_log,
LMsg(
"timedelta ") << timedelta <<
" prevcalltime " << info->m_prev_call_time);
379 double distance_to_travel = (
static_cast<double>(timedelta) / 1000.0) * info->m_speed;
380 FL_DBG(_log,
LMsg(
"dist ") << distance_to_travel);
382 Location nextLocation = m_location;
383 info->m_pather_session_id = info->m_pather->getNextLocation(
384 this, *info->m_target,
385 distance_to_travel, nextLocation, *m_facinglocation,
386 info->m_pather_session_id);
387 m_location.getLayer()->getInstanceTree()->removeInstance(
this);
388 m_location = nextLocation;
391 m_location.getLayer()->getInstanceTree()->addInstance(
this);
393 if (info->m_pather_session_id == -1) {
401 return ICHANGE_NO_CHANGES;
403 m_activity->update(*
this);
404 if (!m_activity->m_timeprovider) {
407 ActionInfo* info = m_activity->m_actioninfo;
409 FL_DBG(_log,
"updating instance");
411 if (info->m_target) {
412 FL_DBG(_log,
"action contains target for movement");
414 if (info->m_leader && (info->m_leader->getLocationRef() != *info->m_target)) {
415 *info->m_target = info->m_leader->getLocation();
417 bool movement_finished = process_movement();
418 if (movement_finished) {
419 FL_DBG(_log,
"movement finished");
423 FL_DBG(_log,
"action does not contain target for movement");
424 if (m_activity->m_timeprovider->getGameTime() - info->m_action_start_time + info->m_action_offset_time >= info->m_action->getDuration()) {
425 if (info->m_repeating) {
426 info->m_action_start_time = m_activity->m_timeprovider->getGameTime();
428 info->m_action_offset_time = 0;
436 if( m_activity->m_actioninfo ) {
437 m_activity->m_actioninfo->m_prev_call_time = m_activity->m_timeprovider->getGameTime();
440 if (m_activity->m_sayinfo) {
441 if (m_activity->m_sayinfo->m_duration > 0) {
442 if (m_activity->m_timeprovider->getGameTime() >= m_activity->m_sayinfo->m_start_time + m_activity->m_sayinfo->m_duration) {
450 void Instance::finalizeAction() {
451 FL_DBG(_log,
"finalizing action");
453 assert(m_activity->m_actioninfo);
455 if( m_activity->m_actioninfo->m_leader ) {
456 m_activity->m_actioninfo->m_leader->removeDeleteListener(
this);
459 Action* action = m_activity->m_actioninfo->m_action;
460 delete m_activity->m_actioninfo;
461 m_activity->m_actioninfo = NULL;
463 std::vector<InstanceActionListener*>::iterator i = m_activity->m_actionlisteners.begin();
464 while (i != m_activity->m_actionlisteners.end()) {
466 (*i)->onInstanceActionFinished(
this, action);
469 m_activity->m_actionlisteners.erase(
470 std::remove(m_activity->m_actionlisteners.begin(),
471 m_activity->m_actionlisteners.end(),
472 (InstanceActionListener*)NULL),
473 m_activity->m_actionlisteners.end());
477 if (m_activity && m_activity->m_actioninfo) {
478 return m_activity->m_actioninfo->m_action;
484 if (m_activity && m_activity->m_actioninfo && m_activity->m_actioninfo->m_target) {
485 return *m_activity->m_actioninfo->m_target;
491 if (m_activity && m_activity->m_actioninfo) {
492 return m_activity->m_actioninfo->m_speed;
502 if (!m_facinglocation) {
503 m_facinglocation =
new Location(m_location);
504 m_facinglocation->setExactLayerCoordinates(m_facinglocation->getExactLayerCoordinates() +
ExactModelCoordinate(1.0, 0.0));
507 return *m_facinglocation;
511 if (m_activity && m_activity->m_actioninfo) {
512 if(!m_activity->m_timeprovider)
514 return m_activity->m_timeprovider->getGameTime() - m_activity->m_actioninfo->m_action_start_time + m_activity->m_actioninfo->m_action_offset_time;
520 m_activity->m_actioninfo->m_action_offset_time = time_offset;
523 void Instance::bindTimeProvider() {
524 float multiplier = 1.0;
525 if (m_activity->m_timeprovider) {
526 multiplier = m_activity->m_timeprovider->getMultiplier();
528 delete m_activity->m_timeprovider;
529 m_activity->m_timeprovider = NULL;
531 if (m_location.getLayer()) {
532 Map* map = m_location.getLayer()->getMap();
534 m_activity->m_timeprovider =
new TimeProvider(map->getTimeProvider());
537 if (!m_activity->m_timeprovider) {
538 m_activity->m_timeprovider =
new TimeProvider(NULL);
540 m_activity->m_timeprovider->setMultiplier(multiplier);
550 if (!m_activity->m_timeprovider) {
553 m_activity->m_timeprovider->setMultiplier(multip);
557 if (m_activity && m_activity->m_timeprovider) {
558 return m_activity->m_timeprovider->getMultiplier();
564 if (m_activity && m_activity->m_timeprovider) {
565 return m_activity->m_timeprovider->getTotalMultiplier();
567 if (m_location.getLayer()) {
568 Map* map = m_location.getLayer()->getMap();
578 if(!m_activity->m_timeprovider)
580 return m_activity->m_timeprovider->getGameTime();
582 if (m_location.getLayer()) {
583 Map* map = m_location.getLayer()->getMap();
588 return TimeManager::instance()->getTime();
591 m_deletelisteners.push_back(listener);
594 std::vector<InstanceDeleteListener*>::iterator itor;
595 itor = std::find(m_deletelisteners.begin(),
596 m_deletelisteners.end(),
598 if(itor != m_deletelisteners.end()) {
599 m_deletelisteners.erase(itor);
601 FL_WARN(_log,
"Cannot remove unknown listener");
606 m_activity->m_actioninfo &&
607 m_activity->m_actioninfo->m_leader == instance) {
608 m_activity->m_actioninfo->m_leader = NULL;