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