Starshatter_Open
Open source Starshatter engine
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
CombatAction.cpp
Go to the documentation of this file.
1 /* Project Starshatter 4.5
2  Destroyer Studios LLC
3  Copyright © 1997-2004. All Rights Reserved.
4 
5  SUBSYSTEM: Stars.exe
6  FILE: CombatAction.cpp
7  AUTHOR: John DiCamillo
8 
9 
10  OVERVIEW
11  ========
12  A significant (newsworthy) event in the dynamic campaign.
13 */
14 
15 #include "MemDebug.h"
16 #include "CombatAction.h"
17 #include "CombatGroup.h"
18 #include "Campaign.h"
19 #include "Combatant.h"
20 #include "Player.h"
21 #include "Random.h"
22 
23 // +----------------------------------------------------------------------+
24 
25 CombatAction::CombatAction(int n, int typ, int sub, int iff)
26 : id(n), type(typ), subtype(sub), opp_type(-1), team(iff),
27 status(PENDING), count(0), rval(-1), source(0), time(0),
28 start_before((int) 1e9), start_after(0),
29 min_rank(0), max_rank(100),
30 delay(0), probability(100), asset_type(0), target_type(0)
31 { }
32 
34 {
35  requirements.destroy();
36  asset_kills.destroy();
37  target_kills.destroy();
38 }
39 
40 // +----------------------------------------------------------------------+
41 
42 bool
44 {
45  CombatAction* pThis = (CombatAction*) this;
46 
47  if (rval < 0) {
48  pThis->rval = (int) Random(0, 100);
49 
50  if (rval > probability)
51  pThis->status = SKIPPED;
52  }
53 
54  if (status != PENDING)
55  return false;
56 
57  if (min_rank > 0 || max_rank < 100) {
58  Player* player = Player::GetCurrentPlayer();
59 
60  if (player->Rank() < min_rank || player->Rank() > max_rank)
61  return false;
62  }
63 
64  Campaign* campaign = Campaign::GetCampaign();
65  if (campaign) {
66  if (campaign->GetTime() < start_after) {
67  return false;
68  }
69 
70  if (campaign->GetTime() > start_before) {
71  pThis->status = FAILED; // too late!
72  return false;
73  }
74 
75  // check requirements against actions in current campaign:
76  ListIter<CombatActionReq> iter = pThis->requirements;
77  while (++iter) {
78  CombatActionReq* r = iter.value();
79  bool ok = false;
80 
81  if (r->action > 0) {
82  ListIter<CombatAction> action = campaign->GetActions();
83  while (++action) {
84  CombatAction* a = action.value();
85 
86  if (a->Identity() == r->action) {
87  if (r->not) {
88  if (a->Status() == r->stat)
89  return false;
90  }
91  else {
92  if (a->Status() != r->stat)
93  return false;
94  }
95  }
96  }
97  }
98 
99  // group-based requirement
100  else if (r->group_type > 0) {
101  if (r->c1) {
102  CombatGroup* group = r->c1->FindGroup(r->group_type, r->group_id);
103 
104  if (group) {
105  int test = 0;
106  int comp = 0;
107 
108  if (r->intel) {
109  test = group->IntelLevel();
110  comp = r->intel;
111  }
112 
113  else {
114  test = group->CalcValue();
115  comp = r->score;
116  }
117 
118  switch (r->comp) {
119  case CombatActionReq::LT: ok = (test < comp); break;
120  case CombatActionReq::LE: ok = (test <= comp); break;
121  case CombatActionReq::GT: ok = (test > comp); break;
122  case CombatActionReq::GE: ok = (test >= comp); break;
123  case CombatActionReq::EQ: ok = (test == comp); break;
124  }
125  }
126 
127  if (!ok)
128  return false;
129  }
130  }
131 
132  // score-based requirement
133  else {
134  int test = 0;
135 
136  if (r->comp <= CombatActionReq::EQ) { // absolute
137  if (r->c1) {
138  int test = r->c1->Score();
139 
140  switch (r->comp) {
141  case CombatActionReq::LT: ok = (test < r->score); break;
142  case CombatActionReq::LE: ok = (test <= r->score); break;
143  case CombatActionReq::GT: ok = (test > r->score); break;
144  case CombatActionReq::GE: ok = (test >= r->score); break;
145  case CombatActionReq::EQ: ok = (test == r->score); break;
146  }
147  }
148  }
149 
150  else { // relative
151  if (r->c1 && r->c2) {
152  int test = r->c1->Score() - r->c2->Score();
153 
154  switch (r->comp) {
155  case CombatActionReq::RLT: ok = (test < r->score); break;
156  case CombatActionReq::RLE: ok = (test <= r->score); break;
157  case CombatActionReq::RGT: ok = (test > r->score); break;
158  case CombatActionReq::RGE: ok = (test >= r->score); break;
159  case CombatActionReq::REQ: ok = (test == r->score); break;
160  }
161  }
162  }
163 
164  if (!ok)
165  return false;
166  }
167 
168  if (delay > 0) {
169  pThis->start_after = (int) campaign->GetTime() + delay;
170  pThis->delay = 0;
171  return IsAvailable();
172  }
173  }
174  }
175 
176  return true;
177 }
178 
179 // +----------------------------------------------------------------------+
180 
181 void
183 {
184  Campaign* campaign = Campaign::GetCampaign();
185  if (campaign)
186  time = (int) campaign->GetTime();
187 
188  if (count >= 1)
189  count--;
190 
191  if (count < 1)
192  status = COMPLETE;
193 }
194 
195 void
197 {
198  Campaign* campaign = Campaign::GetCampaign();
199  if (campaign)
200  time = (int) campaign->GetTime();
201 
202  count = 0;
203  status = FAILED;
204 }
205 
206 // +----------------------------------------------------------------------+
207 
208 void
209 CombatAction::AddRequirement(int action, int stat, bool not)
210 {
211  requirements.append(new(__FILE__,__LINE__) CombatActionReq(action, stat, not));
212 }
213 
214 void
215 CombatAction::AddRequirement(Combatant* c1, Combatant* c2, int comp, int score)
216 {
217  requirements.append(new(__FILE__,__LINE__) CombatActionReq(c1, c2, comp, score));
218 }
219 
220 void
221 CombatAction::AddRequirement(Combatant* c1, int group_type, int group_id, int comp, int score, int intel)
222 {
223  requirements.append(new(__FILE__,__LINE__) CombatActionReq(c1, group_type, group_id, comp, score, intel));
224 }
225 
226 // +----------------------------------------------------------------------+
227 
228 int
230 {
231  int type = 0;
232 
233  if (!_stricmp(n, "NO_ACTION"))
234  type = NO_ACTION;
235 
236  else if (!_stricmp(n, "MARKER"))
237  type = NO_ACTION;
238 
239  else if (!_stricmp(n, "STRATEGIC_DIRECTIVE"))
240  type = STRATEGIC_DIRECTIVE;
241 
242  else if (!_stricmp(n, "STRATEGIC"))
243  type = STRATEGIC_DIRECTIVE;
244 
245  else if (!_stricmp(n, "ZONE_ASSIGNMENT"))
246  type = ZONE_ASSIGNMENT;
247 
248  else if (!_stricmp(n, "ZONE"))
249  type = ZONE_ASSIGNMENT;
250 
251  else if (!_stricmp(n, "SYSTEM_ASSIGNMENT"))
252  type = SYSTEM_ASSIGNMENT;
253 
254  else if (!_stricmp(n, "SYSTEM"))
255  type = SYSTEM_ASSIGNMENT;
256 
257  else if (!_stricmp(n, "MISSION_TEMPLATE"))
258  type = MISSION_TEMPLATE;
259 
260  else if (!_stricmp(n, "MISSION"))
261  type = MISSION_TEMPLATE;
262 
263  else if (!_stricmp(n, "COMBAT_EVENT"))
264  type = COMBAT_EVENT;
265 
266  else if (!_stricmp(n, "EVENT"))
267  type = COMBAT_EVENT;
268 
269  else if (!_stricmp(n, "INTEL_EVENT"))
270  type = INTEL_EVENT;
271 
272  else if (!_stricmp(n, "INTEL"))
273  type = INTEL_EVENT;
274 
275  else if (!_stricmp(n, "CAMPAIGN_SITUATION"))
276  type = CAMPAIGN_SITUATION;
277 
278  else if (!_stricmp(n, "SITREP"))
279  type = CAMPAIGN_SITUATION;
280 
281  else if (!_stricmp(n, "CAMPAIGN_ORDERS"))
282  type = CAMPAIGN_ORDERS;
283 
284  else if (!_stricmp(n, "ORDERS"))
285  type = CAMPAIGN_ORDERS;
286 
287  return type;
288 }
289 
290 int
292 {
293  int stat = 0;
294 
295  if (!_stricmp(n, "PENDING"))
296  stat = PENDING;
297 
298  else if (!_stricmp(n, "ACTIVE"))
299  stat = ACTIVE;
300 
301  else if (!_stricmp(n, "SKIPPED"))
302  stat = SKIPPED;
303 
304  else if (!_stricmp(n, "FAILED"))
305  stat = FAILED;
306 
307  else if (!_stricmp(n, "COMPLETE"))
308  stat = COMPLETE;
309 
310  return stat;
311 }
312 
313 
314 // +----------------------------------------------------------------------+
315 
316 int
318 {
319  int comp = 0;
320 
321  if (!_stricmp(n, "LT"))
322  comp = LT;
323 
324  else if (!_stricmp(n, "LE"))
325  comp = LE;
326 
327  else if (!_stricmp(n, "GT"))
328  comp = GT;
329 
330  else if (!_stricmp(n, "GE"))
331  comp = GE;
332 
333  else if (!_stricmp(n, "EQ"))
334  comp = EQ;
335 
336  else if (!_stricmp(n, "RLT"))
337  comp = RLT;
338 
339  else if (!_stricmp(n, "RLE"))
340  comp = RLE;
341 
342  else if (!_stricmp(n, "RGT"))
343  comp = RGT;
344 
345  else if (!_stricmp(n, "RGE"))
346  comp = RGE;
347 
348  else if (!_stricmp(n, "REQ"))
349  comp = REQ;
350 
351  return comp;
352 }