34
34
///////////////////////////////////////////////////////////////////////////////
35
35
// Makros / Defines
36
36
#if defined _WIN32 && defined _DEBUG && defined _MSC_VER
37
#define new new(_NORMAL_BLOCK, THIS_FILE, __LINE__)
39
static char THIS_FILE[] = __FILE__;
37
#define new new(_NORMAL_BLOCK, THIS_FILE, __LINE__)
39
static char THIS_FILE[] = __FILE__;
42
Ware::Ware(const GoodType type, noBaseBuilding * goal, noRoadNode * location) :
43
next_dir(255), state(STATE_WAITINWAREHOUSE), location(location),
44
type(type == GD_SHIELDROMANS ? SHIELD_TYPES[GameClient::inst().GetPlayer(location->GetPlayer())->nation] : type ),// Bin ich ein Schild? Dann evtl. Typ nach Nation anpassen
42
Ware::Ware(const GoodType type, noBaseBuilding* goal, noRoadNode* location) :
43
next_dir(255), state(STATE_WAITINWAREHOUSE), location(location),
44
type(type == GD_SHIELDROMANS ? SHIELD_TYPES[GameClient::inst().GetPlayer(location->GetPlayer())->nation] : type ),// Bin ich ein Schild? Dann evtl. Typ nach Nation anpassen
47
// Ware in den Index mit eintragen
48
gwg->GetPlayer(location->GetPlayer())->RegisterWare(this);
51
//assert(obj_id != 1197877);
47
// Ware in den Index mit eintragen
48
gwg->GetPlayer(location->GetPlayer())->RegisterWare(this);
51
//assert(obj_id != 1197877);
56
/*assert(!gwg->GetPlayer((location->GetPlayer()].IsWareRegistred(this));*/
58
// assert(!gwg->GetPlayer((location->GetPlayer())->IsWareDependent(this));
56
/*assert(!gwg->GetPlayer((location->GetPlayer()].IsWareRegistred(this));*/
58
// assert(!gwg->GetPlayer((location->GetPlayer())->IsWareDependent(this));
61
61
void Ware::Destroy(void)
65
void Ware::Serialize_Ware(SerializedGameData * sgd) const
65
void Ware::Serialize_Ware(SerializedGameData* sgd) const
67
Serialize_GameObject(sgd);
67
Serialize_GameObject(sgd);
69
sgd->PushUnsignedChar(next_dir);
70
sgd->PushUnsignedChar(static_cast<unsigned char>(state));
71
sgd->PushObject(location,false);
72
sgd->PushUnsignedChar(static_cast<unsigned char>(type));
73
sgd->PushObject(goal,false);
74
sgd->PushUnsignedShort(next_harbor.x);
75
sgd->PushUnsignedShort(next_harbor.y);
69
sgd->PushUnsignedChar(next_dir);
70
sgd->PushUnsignedChar(static_cast<unsigned char>(state));
71
sgd->PushObject(location, false);
72
sgd->PushUnsignedChar(static_cast<unsigned char>(type));
73
sgd->PushObject(goal, false);
74
sgd->PushUnsignedShort(next_harbor.x);
75
sgd->PushUnsignedShort(next_harbor.y);
78
Ware::Ware(SerializedGameData * sgd, const unsigned obj_id) : GameObject(sgd,obj_id),
79
next_dir(sgd->PopUnsignedChar()),
80
state(State(sgd->PopUnsignedChar())),
81
location(sgd->PopObject<noRoadNode>(GOT_UNKNOWN)),
82
type(GoodType(sgd->PopUnsignedChar())),
83
goal(sgd->PopObject<noBaseBuilding>(GOT_UNKNOWN))
78
Ware::Ware(SerializedGameData* sgd, const unsigned obj_id) : GameObject(sgd, obj_id),
79
next_dir(sgd->PopUnsignedChar()),
80
state(State(sgd->PopUnsignedChar())),
81
location(sgd->PopObject<noRoadNode>(GOT_UNKNOWN)),
82
type(GoodType(sgd->PopUnsignedChar())),
83
goal(sgd->PopObject<noBaseBuilding>(GOT_UNKNOWN))
86
next_harbor.x = sgd->PopUnsignedShort();
87
next_harbor.y = sgd->PopUnsignedShort();
88
//assert(obj_id != 1197877);
86
next_harbor.x = sgd->PopUnsignedShort();
87
next_harbor.y = sgd->PopUnsignedShort();
88
//assert(obj_id != 1197877);
92
92
void Ware::RecalcRoute()
94
// Nächste Richtung nehmen
95
next_dir = gwg->FindPathForWareOnRoads(location,goal,NULL,&next_harbor);
97
// Evtl gibts keinen Weg mehr? Dann wieder zurück ins Lagerhaus (wenns vorher überhaupt zu nem Ziel ging)
98
if(next_dir == 0xFF && goal)
100
// meinem Ziel Becheid sagen
101
goal->WareLost(this);
103
nobBaseWarehouse * wh = gwg->GetPlayer(location->GetPlayer())->FindWarehouse(
104
location,FW::Condition_StoreWare,0,true,&type,true);
107
// Lagerhaus ist unser neues Ziel
110
next_dir = gwg->FindPathForWareOnRoads(location,goal,NULL,&next_harbor);
118
// Es gibt auch kein Weg zu einem Lagerhaus, tja dann ist es wohl vorbei erstmal
126
// If we waited in the harbor for the ship before and don't want to travel now
127
// -> inform the harbor so that it can remove us from its list
128
if(state == STATE_WAITFORSHIP && next_dir != SHIP_DIR)
131
assert(location->GetGOT() == GOT_NOB_HARBORBUILDING);
133
static_cast<nobHarborBuilding*>(location)->WareDontWantToTravelByShip(this);
135
state = STATE_WAITINWAREHOUSE;
138
//// Es wurde ein gültiger Weg gefunden! Dann muss aber noch dem nächsten Träger Bescheid gesagt werden
139
//location->routes[next_dir]->AddWareJob(location);
94
// Nächste Richtung nehmen
95
next_dir = gwg->FindPathForWareOnRoads(location, goal, NULL, &next_harbor);
97
// Evtl gibts keinen Weg mehr? Dann wieder zurück ins Lagerhaus (wenns vorher überhaupt zu nem Ziel ging)
98
if(next_dir == 0xFF && goal)
100
// meinem Ziel Becheid sagen
101
goal->WareLost(this);
103
nobBaseWarehouse* wh = gwg->GetPlayer(location->GetPlayer())->FindWarehouse(
104
location, FW::Condition_StoreWare, 0, true, &type, true);
107
// Lagerhaus ist unser neues Ziel
110
next_dir = gwg->FindPathForWareOnRoads(location, goal, NULL, &next_harbor);
118
// Es gibt auch kein Weg zu einem Lagerhaus, tja dann ist es wohl vorbei erstmal
126
// If we waited in the harbor for the ship before and don't want to travel now
127
// -> inform the harbor so that it can remove us from its list
128
if(state == STATE_WAITFORSHIP && next_dir != SHIP_DIR)
131
assert(location->GetGOT() == GOT_NOB_HARBORBUILDING);
133
static_cast<nobHarborBuilding*>(location)->WareDontWantToTravelByShip(this);
135
state = STATE_WAITINWAREHOUSE;
138
//// Es wurde ein gültiger Weg gefunden! Dann muss aber noch dem nächsten Träger Bescheid gesagt werden
139
//location->routes[next_dir]->AddWareJob(location);
142
142
void Ware::GoalDestroyed()
145
if(state == STATE_WAITINWAREHOUSE)
147
// Ware ist noch im Lagerhaus auf der Warteliste
149
// Ist sie evtl. gerade mit dem Schiff unterwegs?
150
else if(state == STATE_ONSHIP)
152
// Ziel zunächst auf NULL setzen, was dann vom Zielhafen erkannt wird,
153
// woraufhin dieser die Ware gleich in sein Inventar mit übernimmt
156
// Oder wartet sie im Hafen noch auf ein Schiff
157
else if(state == STATE_WAITFORSHIP)
159
// Dann dem Hafen Bescheid sagen
160
dynamic_cast<nobHarborBuilding*>(location)->CancelWareForShip(this);
161
GAMECLIENT.GetPlayer(location->GetPlayer())->RemoveWare(this);
162
em->AddToKillList(this);
166
// Ware ist unterwegs, Lagerhaus finden und Ware dort einliefern
168
assert(location->GetPlayer() < MAX_PLAYERS);
170
// Wird sie gerade aus einem Lagerhaus rausgetragen?
171
if(location->GetGOT() == GOT_NOB_STOREHOUSE ||
172
/*location->GetGOT() == GOT_NOB_HARBOUR || */
173
location->GetGOT() == GOT_NOB_HQ)
177
goal = static_cast<noBaseBuilding*>(location);
178
// Lagerhaus ggf. Bescheid sagen
179
goal->TakeWare(this);
187
// Wenn sie an einer Flagge liegt, muss der Weg neu berechnet werden und dem Träger Bescheid gesagt werden
188
else if(state == STATE_WAITATFLAG)
190
goal = gwg->GetPlayer(location->GetPlayer())->FindWarehouse(location,FW::Condition_StoreWare,0,true,&type,true);
192
unsigned char last_next_dir = next_dir;
193
next_dir = gwg->FindPathForWareOnRoads(location,goal,NULL,&next_harbor);
194
RemoveWareJobForCurrentDir(last_next_dir);
197
// Kein Lagerhaus gefunden bzw kein Weg dorthin?
198
if(!goal || next_dir == 0xFF)
200
//// Mich aus der globalen Warenliste rausnehmen und in die WareLost Liste einfügen
201
//gwg->GetPlayer((location->GetPlayer()].RemoveWare(this);
202
//gwg->GetPlayer((location->GetPlayer()].RegisterLostWare(this);
206
// Es wurde ein gültiger Weg gefunden! Dann muss aber noch dem nächsten Träger Bescheid gesagt werden
207
location->routes[next_dir]->AddWareJob(location);
209
// Lagerhaus Bescheid sagen
210
goal->TakeWare(this);
212
else if(state == STATE_CARRIED)
214
// Ziel = aktuelle Position, d.h. der Träger, der die Ware trägt, geht gerade in das Zielgebäude rein
215
// d.h. es ist sowieso zu spät
218
goal = gwg->GetPlayer(location->GetPlayer())->FindWarehouse(location,FW::Condition_StoreWare,0,true,&type,true);
221
// Lagerhaus ggf. Bescheid sagen
222
goal->TakeWare(this);
145
if(state == STATE_WAITINWAREHOUSE)
147
// Ware ist noch im Lagerhaus auf der Warteliste
149
// Ist sie evtl. gerade mit dem Schiff unterwegs?
150
else if(state == STATE_ONSHIP)
152
// Ziel zunächst auf NULL setzen, was dann vom Zielhafen erkannt wird,
153
// woraufhin dieser die Ware gleich in sein Inventar mit übernimmt
156
// Oder wartet sie im Hafen noch auf ein Schiff
157
else if(state == STATE_WAITFORSHIP)
159
// Dann dem Hafen Bescheid sagen
160
dynamic_cast<nobHarborBuilding*>(location)->CancelWareForShip(this);
161
GAMECLIENT.GetPlayer(location->GetPlayer())->RemoveWare(this);
162
em->AddToKillList(this);
166
// Ware ist unterwegs, Lagerhaus finden und Ware dort einliefern
168
assert(location->GetPlayer() < MAX_PLAYERS);
170
// Wird sie gerade aus einem Lagerhaus rausgetragen?
171
if(location->GetGOT() == GOT_NOB_STOREHOUSE ||
172
/*location->GetGOT() == GOT_NOB_HARBOUR || */
173
location->GetGOT() == GOT_NOB_HQ)
177
goal = static_cast<noBaseBuilding*>(location);
178
// Lagerhaus ggf. Bescheid sagen
179
goal->TakeWare(this);
187
// Wenn sie an einer Flagge liegt, muss der Weg neu berechnet werden und dem Träger Bescheid gesagt werden
188
else if(state == STATE_WAITATFLAG)
190
goal = gwg->GetPlayer(location->GetPlayer())->FindWarehouse(location, FW::Condition_StoreWare, 0, true, &type, true);
192
unsigned char last_next_dir = next_dir;
193
next_dir = gwg->FindPathForWareOnRoads(location, goal, NULL, &next_harbor);
194
RemoveWareJobForCurrentDir(last_next_dir);
197
// Kein Lagerhaus gefunden bzw kein Weg dorthin?
198
if(!goal || next_dir == 0xFF)
200
//// Mich aus der globalen Warenliste rausnehmen und in die WareLost Liste einfügen
201
//gwg->GetPlayer((location->GetPlayer()].RemoveWare(this);
202
//gwg->GetPlayer((location->GetPlayer()].RegisterLostWare(this);
206
// Es wurde ein gültiger Weg gefunden! Dann muss aber noch dem nächsten Träger Bescheid gesagt werden
207
location->routes[next_dir]->AddWareJob(location);
209
// Lagerhaus Bescheid sagen
210
goal->TakeWare(this);
212
else if(state == STATE_CARRIED)
214
// Ziel = aktuelle Position, d.h. der Träger, der die Ware trägt, geht gerade in das Zielgebäude rein
215
// d.h. es ist sowieso zu spät
218
goal = gwg->GetPlayer(location->GetPlayer())->FindWarehouse(location, FW::Condition_StoreWare, 0, true, &type, true);
221
// Lagerhaus ggf. Bescheid sagen
222
goal->TakeWare(this);
228
228
/// Gibt dem Ziel der Ware bekannt, dass diese nicht mehr kommen kann
229
229
void Ware::NotifyGoalAboutLostWare()
231
// Meinem Ziel Bescheid sagen, dass ich weg vom Fenster bin (falls ich ein Ziel habe!)
233
goal->WareLost(this);
231
// Meinem Ziel Bescheid sagen, dass ich weg vom Fenster bin (falls ich ein Ziel habe!)
233
goal->WareLost(this);
236
236
/// Wenn die Ware vernichtet werden muss
237
237
void Ware::WareLost(const unsigned char player)
239
// Inventur verringern
240
gwg->GetPlayer(player)->DecreaseInventoryWare(type,1);
241
// Ziel der Ware Bescheid sagen
242
NotifyGoalAboutLostWare();
243
// Zentrale Registrierung der Ware löschen
244
gwg->GetPlayer(player)->RemoveWare(this);
239
// Inventur verringern
240
gwg->GetPlayer(player)->DecreaseInventoryWare(type, 1);
241
// Ziel der Ware Bescheid sagen
242
NotifyGoalAboutLostWare();
243
// Zentrale Registrierung der Ware löschen
244
gwg->GetPlayer(player)->RemoveWare(this);
248
248
void Ware::RemoveWareJobForCurrentDir(const unsigned char last_next_dir)
250
// last_next_dir war die letzte Richtung, in die die Ware eigentlich wollte,
251
// aber nun nicht mehr will, deshalb muss dem Träger Bescheid gesagt werden
253
// War's überhaupt ne richtige Richtung?
254
if(last_next_dir < 6)
256
// Existiert da noch ne Straße?
257
if(location->routes[last_next_dir])
259
// Den Trägern Bescheid sagen
260
location->routes[last_next_dir]->WareJobRemoved(0);
261
// Wenn nicht, könntes ja sein, dass die Straße in ein Lagerhaus führt, dann muss dort Bescheid gesagt werden
262
if(location->routes[last_next_dir]->GetF2()->GetType() == NOP_BUILDING)
264
if(static_cast<noBuilding*>(location->routes[1]->GetF2())->GetBuildingType() == BLD_HEADQUARTERS ||
265
static_cast<noBuilding*>(location->routes[1]->GetF2())->GetBuildingType() == BLD_STOREHOUSE ||
266
static_cast<noBuilding*>(location->routes[1]->GetF2())->GetBuildingType() == BLD_HARBORBUILDING)
267
static_cast<nobBaseWarehouse*>(location->routes[1]->GetF2())->DontFetchNextWare();
272
//// Und stand ein Träger drauf?
273
//if(location->routes[last_next_dir]->carrier)
274
// location->routes[last_next_dir]->carrier->RemoveWareJob();
275
//// Wenn nicht, könntes ja sein, dass die Straße in ein Lagerhaus führt, dann muss dort Bescheid gesagt werden
276
//else if(location->routes[1])
278
// if(location->routes[1]->f2->GetType() == NOP_BUILDING)
280
// if(static_cast<noBuilding*>(location->routes[1]->f2)->GetBuildingType() == BLD_HEADQUARTERS ||
281
// static_cast<noBuilding*>(location->routes[1]->f2)->GetBuildingType() == BLD_STOREHOUSE ||
282
// static_cast<noBuilding*>(location->routes[1]->f2)->GetBuildingType() == BLD_HARBORBUILDING)
283
// static_cast<nobBaseWarehouse*>(location->routes[1]->f2)->DontFetchNextWare();
285
// LOG.lprintf("Ware::RemoveWareJobForCurrentDi: WARNING: Ware in front of building!\n");
288
// LOG.lprintf("Ware::RemoveWareJobForCurrentDir: WARNING: Ware in front of building site (gf: %lu)!\n",GAMECLIENT.GetGFNumber());
250
// last_next_dir war die letzte Richtung, in die die Ware eigentlich wollte,
251
// aber nun nicht mehr will, deshalb muss dem Träger Bescheid gesagt werden
253
// War's überhaupt ne richtige Richtung?
254
if(last_next_dir < 6)
256
// Existiert da noch ne Straße?
257
if(location->routes[last_next_dir])
259
// Den Trägern Bescheid sagen
260
location->routes[last_next_dir]->WareJobRemoved(0);
261
// Wenn nicht, könntes ja sein, dass die Straße in ein Lagerhaus führt, dann muss dort Bescheid gesagt werden
262
if(location->routes[last_next_dir]->GetF2()->GetType() == NOP_BUILDING)
264
if(static_cast<noBuilding*>(location->routes[1]->GetF2())->GetBuildingType() == BLD_HEADQUARTERS ||
265
static_cast<noBuilding*>(location->routes[1]->GetF2())->GetBuildingType() == BLD_STOREHOUSE ||
266
static_cast<noBuilding*>(location->routes[1]->GetF2())->GetBuildingType() == BLD_HARBORBUILDING)
267
static_cast<nobBaseWarehouse*>(location->routes[1]->GetF2())->DontFetchNextWare();
272
//// Und stand ein Träger drauf?
273
//if(location->routes[last_next_dir]->carrier)
274
// location->routes[last_next_dir]->carrier->RemoveWareJob();
275
//// Wenn nicht, könntes ja sein, dass die Straße in ein Lagerhaus führt, dann muss dort Bescheid gesagt werden
276
//else if(location->routes[1])
278
// if(location->routes[1]->f2->GetType() == NOP_BUILDING)
280
// if(static_cast<noBuilding*>(location->routes[1]->f2)->GetBuildingType() == BLD_HEADQUARTERS ||
281
// static_cast<noBuilding*>(location->routes[1]->f2)->GetBuildingType() == BLD_STOREHOUSE ||
282
// static_cast<noBuilding*>(location->routes[1]->f2)->GetBuildingType() == BLD_HARBORBUILDING)
283
// static_cast<nobBaseWarehouse*>(location->routes[1]->f2)->DontFetchNextWare();
285
// LOG.lprintf("Ware::RemoveWareJobForCurrentDi: WARNING: Ware in front of building!\n");
288
// LOG.lprintf("Ware::RemoveWareJobForCurrentDir: WARNING: Ware in front of building site (gf: %lu)!\n",GAMECLIENT.GetGFNumber());
293
293
void Ware::FindRouteToWarehouse()
295
goal = gwg->GetPlayer(location->GetPlayer())->FindWarehouse(location,FW::Condition_StoreWare,0,true,&type,true);
297
if(goal && state == STATE_WAITATFLAG)
299
//// Bin nun keine LostWare mehr, sondern steige in die Liste der richtigen Waren auf, da ich nun in ein Lagerhaus komme
300
//gwg->GetPlayer(location->GetPlayer()].RemoveLostWare(this);
301
//gwg->GetPlayer(location->GetPlayer()].RegisterWare(this);
304
next_dir = gwg->FindPathForWareOnRoads(location,goal);
306
// Es wurde ein gültiger Weg gefunden! Dann muss aber noch dem nächsten Träger Bescheid gesagt werden
307
location->routes[next_dir]->AddWareJob(location);
309
// Lagerhaus auch Bescheid sagen
310
static_cast<nobBaseWarehouse*>(goal)->TakeWare(this);
295
goal = gwg->GetPlayer(location->GetPlayer())->FindWarehouse(location, FW::Condition_StoreWare, 0, true, &type, true);
297
if(goal && state == STATE_WAITATFLAG)
299
//// Bin nun keine LostWare mehr, sondern steige in die Liste der richtigen Waren auf, da ich nun in ein Lagerhaus komme
300
//gwg->GetPlayer(location->GetPlayer()].RemoveLostWare(this);
301
//gwg->GetPlayer(location->GetPlayer()].RegisterWare(this);
304
next_dir = gwg->FindPathForWareOnRoads(location, goal);
306
// Es wurde ein gültiger Weg gefunden! Dann muss aber noch dem nächsten Träger Bescheid gesagt werden
307
location->routes[next_dir]->AddWareJob(location);
309
// Lagerhaus auch Bescheid sagen
310
static_cast<nobBaseWarehouse*>(goal)->TakeWare(this);
314
314
bool Ware::FindRouteFromWarehouse()
318
return (gwg->FindPathForWareOnRoads(location,goal) != 0xFF);
318
return (gwg->FindPathForWareOnRoads(location, goal) != 0xFF);
321
321
/// Informiert Ware, dass eine Schiffsreise beginnt
322
322
void Ware::StartShipJourney()
324
state = STATE_ONSHIP;
324
state = STATE_ONSHIP;
328
328
/// Informiert Ware, dass Schiffsreise beendet ist und die Ware nun in einem Hafengebäude liegt
329
bool Ware::ShipJorneyEnded(nobHarborBuilding * hb)
329
bool Ware::ShipJorneyEnded(nobHarborBuilding* hb)
331
state = STATE_WAITINWAREHOUSE;
339
next_dir = gwg->FindPathForWareOnRoads(location,goal,NULL,&next_harbor);
331
state = STATE_WAITINWAREHOUSE;
339
next_dir = gwg->FindPathForWareOnRoads(location, goal, NULL, &next_harbor);
341
341
// TODO: SHIP_DIR? order ship etc.
342
if ((next_dir == 0xFF) || (next_dir == SHIP_DIR))
344
goal->WareLost(this);
342
if ((next_dir == 0xFF) || (next_dir == SHIP_DIR))
344
goal->WareLost(this);
352
352
/// Beginnt damit auf ein Schiff im Hafen zu warten
353
void Ware::WaitForShip(nobHarborBuilding * hb)
353
void Ware::WaitForShip(nobHarborBuilding* hb)
355
state = STATE_WAITFORSHIP;
355
state = STATE_WAITFORSHIP;