Starshatter_Open
Open source Starshatter engine
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
CombatZone.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: CombatZone.cpp
7  AUTHOR: John DiCamillo
8 
9 
10  OVERVIEW
11  ========
12  CombatZone is used by the dynamic campaign strategy
13  and logistics algorithms to assign forces to locations
14  within the campaign. A CombatZone is a collection of
15  closely related sectors, and the assets contained
16  within them.
17 */
18 
19 #include "MemDebug.h"
20 #include "CombatZone.h"
21 #include "CombatGroup.h"
22 #include "CombatUnit.h"
23 #include "Campaign.h"
24 #include "ShipDesign.h"
25 #include "Ship.h"
26 
27 #include "Game.h"
28 #include "DataLoader.h"
29 #include "ParseUtil.h"
30 
31 // +----------------------------------------------------------------------+
32 
34 {
35 }
36 
38 {
39  regions.destroy();
40  forces.destroy();
41 }
42 
43 // +--------------------------------------------------------------------+
44 
45 void
47 {
48  forces.destroy();
49 }
50 
51 // +--------------------------------------------------------------------+
52 
53 void
55 {
56  if (group) {
57  int iff = group->GetIFF();
58  ZoneForce* f = FindForce(iff);
59  f->AddGroup(group);
60  group->SetCurrentZone(this);
61  }
62 }
63 
64 void
66 {
67  if (group) {
68  int iff = group->GetIFF();
69  ZoneForce* f = FindForce(iff);
70  f->RemoveGroup(group);
71  group->SetCurrentZone(0);
72  }
73 }
74 
75 bool
77 {
78  if (group) {
79  int iff = group->GetIFF();
80  ZoneForce* f = FindForce(iff);
81  return f->HasGroup(group);
82  }
83 
84  return false;
85 }
86 
87 // +--------------------------------------------------------------------+
88 
89 void
90 CombatZone::AddRegion(const char* rgn)
91 {
92  if (rgn && *rgn) {
93  regions.append(new (__FILE__,__LINE__) Text(rgn));
94 
95  if (name.length() < 1)
96  name = rgn;
97  }
98 }
99 
100 // +--------------------------------------------------------------------+
101 
102 bool
103 CombatZone::HasRegion(const char* rgn)
104 {
105  if (rgn && *rgn && regions.size()) {
106  Text test(rgn);
107  return regions.contains(&test);
108  }
109 
110  return false;
111 }
112 
113 // +--------------------------------------------------------------------+
114 
115 ZoneForce*
117 {
118  ListIter<ZoneForce> f = forces;
119  while (++f) {
120  if (f->GetIFF() == iff)
121  return f.value();
122  }
123 
124  return MakeForce(iff);
125 }
126 
127 // +--------------------------------------------------------------------+
128 
129 ZoneForce*
131 {
132  ZoneForce* f = new(__FILE__,__LINE__) ZoneForce(iff);
133  forces.append(f);
134  return f;
135 }
136 
137 // +--------------------------------------------------------------------+
138 
139 static List<CombatZone> zonelist;
140 
142 CombatZone::Load(const char* filename)
143 {
144  zonelist.clear();
145 
146  DataLoader* loader = DataLoader::GetLoader();
147  BYTE* block = 0;
148 
149  loader->LoadBuffer(filename, block, true);
150  Parser parser(new(__FILE__,__LINE__) BlockReader((const char*) block));
151 
152  Term* term = parser.ParseTerm();
153 
154  if (!term) {
155  return zonelist;
156  }
157  else {
158  TermText* file_type = term->isText();
159  if (!file_type || file_type->value() != "ZONES") {
160  return zonelist;
161  }
162  }
163 
164  do {
165  delete term; term = 0;
166  term = parser.ParseTerm();
167 
168  if (term) {
169  TermDef* def = term->isDef();
170  if (def) {
171  if (def->name()->value() == "zone") {
172  if (!def->term() || !def->term()->isStruct()) {
173  ::Print("WARNING: zone struct missing in '%s%s'\n", loader->GetDataPath(), filename);
174  }
175  else {
176  TermStruct* val = def->term()->isStruct();
177 
178  CombatZone* zone = new(__FILE__,__LINE__) CombatZone();
179  char rgn[64];
180  ZeroMemory(rgn, sizeof(rgn));
181 
182  for (int i = 0; i < val->elements()->size(); i++) {
183  TermDef* pdef = val->elements()->at(i)->isDef();
184  if (pdef) {
185  if (pdef->name()->value() == "region") {
186  GetDefText(rgn, pdef, filename);
187  zone->AddRegion(rgn);
188  }
189  else if (pdef->name()->value() == "system") {
190  GetDefText(rgn, pdef, filename);
191  zone->system = rgn;
192  }
193  }
194  }
195 
196  zonelist.append(zone);
197  }
198  }
199  }
200  }
201  }
202  while (term);
203 
204  loader->ReleaseBuffer(block);
205 
206  return zonelist;
207 }
208 
209 // +--------------------------------------------------------------------+
210 
212 {
213  iff = i;
214 
215  for (int n = 0; n < 8; n++)
216  need[n] = 0;
217 }
218 
219 void
221 {
222  if (group)
223  groups.append(group);
224 }
225 
226 void
228 {
229  if (group)
230  groups.remove(group);
231 }
232 
233 bool
235 {
236  if (group)
237  return groups.contains(group);
238 
239  return false;
240 }
241 
242 int
243 ZoneForce::GetNeed(int group_type) const
244 {
245  switch (group_type) {
246  case CombatGroup::CARRIER_GROUP: return need[0];
247  case CombatGroup::BATTLE_GROUP: return need[1];
248  case CombatGroup::DESTROYER_SQUADRON: return need[2];
249  case CombatGroup::ATTACK_SQUADRON: return need[3];
250  case CombatGroup::FIGHTER_SQUADRON: return need[4];
251  case CombatGroup::INTERCEPT_SQUADRON: return need[5];
252  }
253 
254  return 0;
255 }
256 
257 void
258 ZoneForce::SetNeed(int group_type, int needed)
259 {
260  switch (group_type) {
261  case CombatGroup::CARRIER_GROUP: need[0] = needed; break;
262  case CombatGroup::BATTLE_GROUP: need[1] = needed; break;
263  case CombatGroup::DESTROYER_SQUADRON: need[2] = needed; break;
264  case CombatGroup::ATTACK_SQUADRON: need[3] = needed; break;
265  case CombatGroup::FIGHTER_SQUADRON: need[4] = needed; break;
266  case CombatGroup::INTERCEPT_SQUADRON: need[5] = needed; break;
267  }
268 }
269 
270 void
271 ZoneForce::AddNeed(int group_type, int needed)
272 {
273  switch (group_type) {
274  case CombatGroup::CARRIER_GROUP: need[0] += needed; break;
275  case CombatGroup::BATTLE_GROUP: need[1] += needed; break;
276  case CombatGroup::DESTROYER_SQUADRON: need[2] += needed; break;
277  case CombatGroup::ATTACK_SQUADRON: need[3] += needed; break;
278  case CombatGroup::FIGHTER_SQUADRON: need[4] += needed; break;
279  case CombatGroup::INTERCEPT_SQUADRON: need[5] += needed; break;
280  }
281 }
282