1 /* GemRB - Infinity Engine Emulator
2  * Copyright (C) 2003 The GemRB Project
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8 
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13 
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  *
19  */
20 
21 #include "Dialog.h"
22 
23 #include "GameScript/GameScript.h"
24 #include "RNG.h"
25 
26 namespace GemRB {
27 
Dialog(void)28 Dialog::Dialog(void)
29 {
30 	TopLevelCount = 0;
31 	Flags = 0;
32 	Order = NULL;
33 	initialStates = NULL;
34 }
35 
~Dialog(void)36 Dialog::~Dialog(void)
37 {
38 	if (initialStates) {
39 		for (unsigned int i = 0; i < TopLevelCount; i++) {
40 			if (initialStates[i]) {
41 				FreeDialogState( initialStates[i] );
42 			}
43 		}
44 		free(initialStates);
45 	}
46 	if (Order) free(Order);
47 }
48 
GetState(unsigned int index)49 DialogState* Dialog::GetState(unsigned int index)
50 {
51 	if (index >= TopLevelCount) {
52 		return NULL;
53 	}
54 	return initialStates[index];
55 }
56 
FreeDialogState(DialogState * ds)57 void Dialog::FreeDialogState(DialogState* ds)
58 {
59 	for (unsigned int i = 0; i < ds->transitionsCount; i++) {
60 		DialogTransition *trans = ds->transitions[i];
61 		for (size_t j = 0; j < trans->actions.size(); ++j)
62 			trans->actions[j]->Release();
63 		if (trans->condition)
64 			delete trans->condition;
65 		delete( trans );
66 	}
67 	free( ds->transitions );
68 	if (ds->condition) {
69 		delete ds->condition;
70 	}
71 	delete( ds );
72 }
73 
FindFirstState(Scriptable * target)74 int Dialog::FindFirstState(Scriptable* target)
75 {
76 	for (unsigned int i = 0; i < TopLevelCount; i++) {
77 		const Condition *cond = GetState(Order[i])->condition;
78 		if (cond && cond->Evaluate(target)) {
79 			return Order[i];
80 		}
81 	}
82 	return -1;
83 }
84 
FindRandomState(Scriptable * target)85 int Dialog::FindRandomState(Scriptable* target)
86 {
87 	unsigned int max = TopLevelCount;
88 	if (!max) return -1;
89 	unsigned int pick = RAND(0, max-1);
90 	for (unsigned int i = pick; i < max; i++) {
91 		const Condition *cond = GetState(i)->condition;
92 		if (cond && cond->Evaluate(target)) {
93 			return i;
94 		}
95 	}
96 	for (unsigned int i = 0; i < pick; i++) {
97 		const Condition *cond = GetState(i)->condition;
98 		if (cond && cond->Evaluate(target)) {
99 			return i;
100 		}
101 	}
102 	return -1;
103 }
104 
105 }
106