1 /* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23 #include "titanic/support/time_event_info.h"
24 #include "titanic/core/game_object.h"
25 #include "titanic/core/project_item.h"
26 #include "titanic/messages/messages.h"
27
28 namespace Titanic {
29
postLoad(uint ticks,CProjectItem * project)30 void CTimeEventInfoList::postLoad(uint ticks, CProjectItem *project) {
31 for (iterator i = begin(); i != end(); ++i)
32 (*i)->postLoad(ticks, project);
33 }
34
preSave(uint ticks)35 void CTimeEventInfoList::preSave(uint ticks) {
36 for (iterator i = begin(); i != end(); ++i)
37 (*i)->preSave(ticks);
38 }
39
postSave()40 void CTimeEventInfoList::postSave() {
41 for (iterator i = begin(); i != end(); ++i)
42 (*i)->postSave();
43 }
44
update(uint ticks)45 void CTimeEventInfoList::update(uint ticks) {
46 // Remove any items that are done
47 for (iterator i = begin(); i != end(); ) {
48 CTimeEventInfo *item = *i;
49 if (item->_done) {
50 i = erase(i);
51 delete item;
52 } else {
53 ++i;
54 }
55 }
56
57 // Handle updating the items
58 for (iterator i = begin(); i != end(); ) {
59 CTimeEventInfo *item = *i;
60 if (!item->update(ticks)) {
61 ++i;
62 } else {
63 i = erase(i);
64 delete item;
65 }
66 }
67 }
68
stop(uint id)69 void CTimeEventInfoList::stop(uint id) {
70 for (iterator i = begin(); i != end(); ++i) {
71 CTimeEventInfo *item = *i;
72 if (item->_id == id) {
73 item->_done = true;
74 return;
75 }
76 }
77 }
78
setPersisent(uint id,bool flag)79 void CTimeEventInfoList::setPersisent(uint id, bool flag) {
80 for (iterator i = begin(); i != end(); ++i) {
81 CTimeEventInfo *item = *i;
82 if (item->_id == id) {
83 item->setPersisent(flag);
84 return;
85 }
86 }
87 }
88
89 /*------------------------------------------------------------------------*/
90
91 uint CTimeEventInfo::_nextId;
92
CTimeEventInfo()93 CTimeEventInfo::CTimeEventInfo() : ListItem(), _lockCounter(0),
94 _repeated(false), _firstDuration(0), _repeatDuration(0),
95 _target(nullptr), _actionVal(0), _timerCtr(0), _done(false),
96 _lastTimerTicks(0), _relativeTicks(0), _persisent(true) {
97 _id = _nextId++;
98 }
99
CTimeEventInfo(uint ticks,bool repeated,uint firstDuration,uint repeatDuration,CTreeItem * target,int endVal,const CString & action)100 CTimeEventInfo::CTimeEventInfo(uint ticks, bool repeated, uint firstDuration,
101 uint repeatDuration, CTreeItem *target, int endVal, const CString &action) :
102 ListItem(), _lockCounter(0), _repeated(repeated), _firstDuration(firstDuration),
103 _repeatDuration(repeatDuration), _target(target), _actionVal(endVal), _action(action),
104 _done(false), _timerCtr(0), _lastTimerTicks(ticks), _relativeTicks(0), _persisent(true) {
105 _id = _nextId++;
106 }
107
save(SimpleFile * file,int indent)108 void CTimeEventInfo::save(SimpleFile *file, int indent) {
109 file->writeNumberLine(0, indent);
110
111 CString targetName;
112 if (_target)
113 targetName = _target->getName();
114 file->writeQuotedLine(targetName, indent);
115 file->writeNumberLine(_id, indent);
116 file->writeNumberLine(_repeated, indent);
117 file->writeNumberLine(_firstDuration, indent);
118 file->writeNumberLine(_repeatDuration, indent);
119 file->writeNumberLine(_actionVal, indent);
120 file->writeQuotedLine(_action, indent);
121 file->writeNumberLine(_timerCtr, indent);
122 file->writeNumberLine(_relativeTicks, indent);
123 file->writeNumberLine(_done, indent);
124 file->writeNumberLine(_persisent, indent);
125 }
126
load(SimpleFile * file)127 void CTimeEventInfo::load(SimpleFile *file) {
128 lock();
129 int val = file->readNumber();
130
131 if (!val) {
132 _targetName = file->readString();
133 _id = file->readNumber();
134 _repeated = file->readNumber();
135 _firstDuration = file->readNumber();
136 _repeatDuration = file->readNumber();
137 _actionVal = file->readNumber();
138 _action = file->readString();
139 _timerCtr = file->readNumber();
140 _relativeTicks = file->readNumber();
141 _done = file->readNumber() != 0;
142 _persisent = file->readNumber() != 0;
143 _target = nullptr;
144 }
145 }
146
postLoad(uint ticks,CProjectItem * project)147 void CTimeEventInfo::postLoad(uint ticks, CProjectItem *project) {
148 if (!_persisent || _targetName.empty())
149 _done = true;
150
151 // Get the timer's target
152 if (project)
153 _target = project->findByName(_targetName);
154 if (!_target)
155 _done = true;
156
157 _lastTimerTicks = ticks + _relativeTicks;
158 if (_id >= _nextId)
159 _nextId = _id + 1;
160
161 unlock();
162 }
163
preSave(uint ticks)164 void CTimeEventInfo::preSave(uint ticks) {
165 _relativeTicks = _lastTimerTicks - ticks;
166 lock();
167 }
168
postSave()169 void CTimeEventInfo::postSave() {
170 unlock();
171 }
172
update(uint ticks)173 bool CTimeEventInfo::update(uint ticks) {
174 if (_lockCounter)
175 return false;
176
177 if (_timerCtr) {
178 if (ticks > (_lastTimerTicks + _repeatDuration)) {
179 ++_timerCtr;
180 _lastTimerTicks = ticks;
181
182 if (_target) {
183 CTimerMsg timerMsg(ticks, _timerCtr, _actionVal, _action);
184 timerMsg.execute(_target);
185 }
186 }
187 } else {
188 if (ticks > (_lastTimerTicks + _firstDuration)) {
189 _timerCtr = 1;
190 _lastTimerTicks = ticks;
191
192 if (_target) {
193 CTimerMsg timerMsg(ticks, _timerCtr, _actionVal, _action);
194 timerMsg.execute(_target);
195 }
196
197 if (!_repeated)
198 // Event is done, and can be removed
199 return true;
200 }
201 }
202
203 return false;
204 }
205
206 } // End of namespace Titanic
207