forked from CaravelGames/drod
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCueEvents.cpp
More file actions
332 lines (294 loc) · 10.5 KB
/
Copy pathCueEvents.cpp
File metadata and controls
332 lines (294 loc) · 10.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
// $Id: CueEvents.cpp 9209 2008-09-08 00:22:15Z mrimer $
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Deadly Rooms of Death.
*
* The Initial Developer of the Original Code is
* Caravel Software.
* Portions created by the Initial Developer are Copyright (C) 2001, 2002, 2005
* Caravel Software. All Rights Reserved.
*
* Contributor(s):
* Mike Rimer (mrimer)
*
* ***** END LICENSE BLOCK ***** */
#include "CueEvents.h"
#include "MonsterMessage.h"
#include <BackEndLib/AttachableObject.h>
using namespace std;
//
//Definitions
//
//Has player left room or will he shortly be leaving/restarting? Another way
//of looking at: are any more commands going to be processed in the current room.
const CUEEVENT_ID CIDA_PlayerLeftRoom[11] = {
CID_ExitRoomPending, CID_ExitRoom, CID_ExitLevelPending, CID_ExitToWorldMapPending, CID_WinGame,
CID_MonsterKilledPlayer, CID_ExplosionKilledPlayer, CID_BriarKilledPlayer,
CID_CriticalNPCDied, CID_PlayerFellIntoPit, CID_PlayerDrownedInWater}; //CID_NPCBeethroDied
//Did something kill the player? This array should be checked for death instead
//of these separate events so that future causes of death will be checked without
//project-wide changes to code.
const CUEEVENT_ID CIDA_PlayerDied[6] = {
CID_MonsterKilledPlayer, CID_ExplosionKilledPlayer, CID_BriarKilledPlayer,
CID_CriticalNPCDied, CID_PlayerFellIntoPit, CID_PlayerDrownedInWater}; //CID_NPCBeethroDied
//Did something happen that will prevent a scorepoint from being valid?
//Leaving a room in anyway other than winning the game, or making an illegal move that
//has to be rewound.
const CUEEVENT_ID CIDA_ScoreCheckpointBlocked[12] = {
CID_ExitRoomPending, CID_ExitRoom, CID_ExitLevelPending, CID_ExitToWorldMapPending,
CID_MonsterKilledPlayer, CID_ExplosionKilledPlayer, CID_BriarKilledPlayer,
CID_CriticalNPCDied, CID_PlayerFellIntoPit, CID_PlayerDrownedInWater,
CID_InvalidAttackMove, CID_StalledCombat};
//Did a monster die?
const CUEEVENT_ID CIDA_MonsterDied[2] = {
CID_SnakeDiedFromTruncation, CID_MonsterDiedFromStab}; //, CID_MonsterBurned};
//Was a monster stabbed?
const CUEEVENT_ID CIDA_MonsterStabbed[3] = {
CID_MonsterDiedFromStab, CID_MonsterPieceStabbed, CID_TarstuffDestroyed
};
//
//Public methods.
//
//***************************************************************************************
void CCueEvents::Clear()
//Frees resources and resets members.
{
//Delete private data and nodes to track it.
for (UINT wCID=CUEEVENT_COUNT; wCID--; )
{
vector<CID_PRIVDATA_NODE>::iterator pSeek = this->CIDPrivateData[wCID].begin();
while (pSeek != this->CIDPrivateData[wCID].end())
{
ASSERT(pSeek->pvPrivateData);
if (pSeek->bIsAttached)
delete pSeek->pvPrivateData;
++pSeek;
}
//this->CIDPrivateData[wCID].clear(); //cleared in Zero below
}
//Zero all the members.
Zero();
}
//***************************************************************************************
void CCueEvents::ClearEvent(const CUEEVENT_ID eCID, const bool bDeleteAttached) //[default=true]
//Resets members for specified cue event.
{
if (bDeleteAttached)
{
//Delete attached data objects.
vector<CID_PRIVDATA_NODE>::iterator pSeek = this->CIDPrivateData[eCID].begin();
while (pSeek != this->CIDPrivateData[eCID].end())
{
ASSERT(pSeek->pvPrivateData);
if (pSeek->bIsAttached)
delete pSeek->pvPrivateData;
++pSeek;
}
}
this->CIDPrivateData[eCID].clear();
//Reset any iteration through this event's members.
if (this->wNextCID == (UINT)eCID)
{
this->wNextPrivateDataIndex = 0;
this->wNextCID = (UINT)-1;
}
//Reset flags for this event.
if (this->barrIsCIDSet[eCID])
{
this->barrIsCIDSet[eCID] = false;
--this->wEventCount;
}
}
//***************************************************************************************
UINT CCueEvents::GetOccurrenceCount(
//Get number of times a specified cue event has occurred.
//
//Params:
const CUEEVENT_ID eCID) //(in) Cue event for which to count occurrences.
//
//Returns:
//The count. Will be 0 if cue event has not occurred.
const
{
return this->CIDPrivateData[eCID].size();
}
//***************************************************************************************
void CCueEvents::Add(
//Sets a cue event to true and associates a private data pointer with that cue event.
//
//Params:
const CUEEVENT_ID eCID, //(in) Cue event ID that will be set to true.
const CAttachableObject *pvPrivateData, //(in) Private data to associate with cue event. If NULL
// (default) then no private data will be associated.
// Never pass an array allocated with "new []"--encapsulate
// in a class or struct before passing.
const bool bIsAttached) //(in) If set to true then the private data will be deleted
// by CCueEvents when it destructs. If false (default)
// then data should get deleted elsewhere, but not by
// caller. See comments about private data validity
// guarantee in CueEvents.h.
{
ASSERT(IS_VALID_CID(eCID));
ASSERT(!(pvPrivateData == NULL && bIsAttached));
//Set CID flag.
if (!this->barrIsCIDSet[eCID])
{
this->barrIsCIDSet[eCID] = true;
++this->wEventCount;
}
//Add private data.
if (pvPrivateData)
this->CIDPrivateData[eCID].push_back(
CID_PRIVDATA_NODE(bIsAttached, pvPrivateData));
}
//***************************************************************************************
const CAttachableObject* CCueEvents::GetFirstPrivateData(
//Returns: first private data pointer associated with a cue event, and sets object state so
//that a call to GetNextPrivateData() will return the second private data, if available.
//
//Params:
const CUEEVENT_ID eCID) //(in) Which event for which to retrieve private data.
//
//Returns:
//First private data pointer or NULL if there is no private data associated with cue event.
{
vector<CID_PRIVDATA_NODE>::const_iterator pFirst = this->CIDPrivateData[eCID].begin();
if (pFirst != this->CIDPrivateData[eCID].end())
{
ASSERT(this->barrIsCIDSet[eCID]); //If I found private data then the event should be set.
ASSERT(pFirst->pvPrivateData);
this->wNextCID = eCID;
this->wNextPrivateDataIndex = 1;
return pFirst->pvPrivateData;
}
this->wNextPrivateDataIndex = 0;
this->wNextCID = (UINT)-1;
return NULL;
}
//***************************************************************************************
const CAttachableObject* CCueEvents::GetNextPrivateData()
//Gets next private data pointer after call made to GetFirstPrivateData(). May be called
//multiple times to retrieve a succession of private data pointers.
//
//Returns:
//Private data pointer or NULL if there are no more.
{
//Check whether there are any more private data left.
if (this->wNextCID == (UINT)-1) return NULL;
if (this->wNextPrivateDataIndex >= this->CIDPrivateData[this->wNextCID].size())
return NULL;
CID_PRIVDATA_NODE *pCurrent = &(this->CIDPrivateData[this->wNextCID]
[this->wNextPrivateDataIndex++]);
ASSERT(pCurrent->pvPrivateData);
return pCurrent->pvPrivateData;
}
//***************************************************************************************
bool CCueEvents::HasAnyOccurred(
//Checks to see if at least one cue event from a list has been set.
//
//Params:
const UINT wCIDArrayCount, //# of elements in array.
const CUEEVENT_ID *peCIDArray) //IDs to check for.
//
//Returns:
//True if any of the IDs were found, false if not.
const
{
//Each iteration checks for presence of one CID from
for (UINT wCIDI = 0; wCIDI < wCIDArrayCount; ++wCIDI)
{
ASSERT(IS_VALID_CID(peCIDArray[wCIDI]));
if (this->barrIsCIDSet[peCIDArray[wCIDI]])
//Found one from the list--any remaining IDs are ignored.
return true;
}
//Didn't find any.
return false;
}
//***************************************************************************************
bool CCueEvents::HasOccurredWith(
//Has an event occurred with a matching private data pointer?
//
//Params:
const CUEEVENT_ID eCID, //(in) Check for this CID.
const CAttachableObject *pvPrivateData) //(in) Check for this private data.
//
//Returns:
//True if a match was found, false if not.
const
{
ASSERT(IS_VALID_CID(eCID));
ASSERT(pvPrivateData);
vector<CID_PRIVDATA_NODE>::const_iterator pSeek = this->CIDPrivateData[eCID].begin();
const vector<CID_PRIVDATA_NODE>::const_iterator pSeekEnd = this->CIDPrivateData[eCID].end();
//Each iteration checks on private data for a matching pointer.
while (pSeek != pSeekEnd)
{
ASSERT(this->barrIsCIDSet[eCID]);
if (pSeek->pvPrivateData == pvPrivateData)
return true; //Found it.
++pSeek;
}
//Didn't find it.
return false;
}
//***************************************************************************************
bool CCueEvents::Remove(
//Remove event that occurred with a matching private data pointer
//
//Params:
const CUEEVENT_ID eCID, //(in) Check for this CID.
const CAttachableObject *pvPrivateData) //(in) Check for this private data.
//
//Returns:
//True if a match was found, false if not.
{
ASSERT(IS_VALID_CID(eCID));
ASSERT(pvPrivateData);
vector<CID_PRIVDATA_NODE>::iterator pSeek = this->CIDPrivateData[eCID].begin();
const vector<CID_PRIVDATA_NODE>::const_iterator pSeekEnd = this->CIDPrivateData[eCID].end();
//Each iteration checks on private data for a matching pointer.
while (pSeek != pSeekEnd)
{
ASSERT(this->barrIsCIDSet[eCID]);
if (pSeek->pvPrivateData == pvPrivateData)
{
if (pSeek->bIsAttached)
delete pSeek->pvPrivateData;
this->CIDPrivateData[eCID].erase(pSeek);
return true; //Found it.
}
++pSeek;
}
//Didn't find it.
return false;
}
//
//Private methods.
//
//***************************************************************************************
void CCueEvents::Zero()
//Zero all the members.
{
ASSERT(sizeof(this->barrIsCIDSet) ==
sizeof(this->barrIsCIDSet[0]) * CUEEVENT_COUNT);
ASSERT(sizeof(this->CIDPrivateData) ==
sizeof(this->CIDPrivateData[0]) * CUEEVENT_COUNT);
this->wNextPrivateDataIndex = 0;
this->wNextCID = (UINT)-1;
memset(this->barrIsCIDSet, 0, sizeof(this->barrIsCIDSet));
for (UINT wCID=CUEEVENT_COUNT; wCID--; )
this->CIDPrivateData[wCID].clear();
this->wEventCount = 0;
}