3
* Copyright (C) 2002-4 by the Widelands Development Team
5
* This program is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU General Public License
7
* as published by the Free Software Foundation; either version 2
8
* of the License, or (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
#include "critter_bob.h"
23
#include "critter_bob_program.h"
24
#include "filesystem.h"
29
#include "transport.h"
31
#include "widelands_map_data_packet_ids.h"
32
#include "widelands_map_bobdata_data_packet.h"
34
#include "worker_program.h"
37
#define CURRENT_PACKET_VERSION 1
39
// Bob subtype versions
40
#define CRITTER_BOB_PACKET_VERSION 1
41
#define WORKER_BOB_PACKET_VERSION 1
43
// Worker subtype versions
44
#define SOLDIER_WORKER_BOB_PACKET_VERSION 2
45
#define CARRIER_WORKER_BOB_PACKET_VERSION 1
50
Widelands_Map_Bobdata_Data_Packet::~Widelands_Map_Bobdata_Data_Packet(void) {
56
void Widelands_Map_Bobdata_Data_Packet::Read(FileRead* fr, Editor_Game_Base* egbase, bool skip, Widelands_Map_Map_Object_Loader* ol) throw(wexception) {
58
// First packet version
59
int packet_version=fr->Unsigned16();
61
if(packet_version==CURRENT_PACKET_VERSION) {
62
// Now the rest data len
63
uint len = fr->Unsigned32();
65
// Skip the rest, flags are not our problem here
72
uint reg=fr->Unsigned32();
73
if(reg==0xffffffff) break; // No more bobs
75
assert(ol->is_object_known(reg));
76
Bob* bob=static_cast<Bob*>(ol->get_object_by_file_index(reg));
78
uchar read_owner=fr->Unsigned8();
81
plr_owner=egbase->get_safe_player(read_owner);
82
assert(plr_owner); // He must be there
86
pos.x=fr->Unsigned16();
87
pos.y=fr->Unsigned16();
89
// Basic initialisation
90
bob->set_owner(plr_owner);
91
bob->set_position(egbase, pos);
93
// Look if we had an transfer
94
bool have_transfer=fr->Unsigned8();
98
trans=bob->m_stack[0].transfer;
102
/* if(!have_transfer)
103
bob->reset_tasks(static_cast<Game*>(egbase));
105
bob->m_actid=fr->Unsigned32();
108
if(fr->Unsigned8()) {
109
bob->m_anim=bob->get_descr()->get_animation(fr->CString());
112
bob->m_animstart=fr->Signed32();
115
bob->m_walking=(Map_Object::WalkingDir)fr->Signed32();
116
bob->m_walkstart=fr->Signed32();
117
bob->m_walkend=fr->Signed32();
119
uint oldstacksize=bob->m_stack.size();
120
bob->m_stack.resize(fr->Unsigned16());
121
for(uint i=0; i<bob->m_stack.size(); i++) {
122
Bob::State* s=&bob->m_stack[i];
126
std::string taskname=fr->CString();
127
if(taskname=="idle") task=&Bob::taskIdle;
128
else if(taskname=="movepath") task=&Bob::taskMovepath;
129
else if(taskname=="forcemove") task=&Bob::taskForcemove;
130
else if(taskname=="roam") task=&Critter_Bob::taskRoam;
131
else if(taskname=="program") {
132
if(bob->get_bob_type()==Bob::WORKER)
133
task=&Worker::taskProgram;
135
task=&Critter_Bob::taskProgram;
136
} else if(taskname=="transfer") task=&Worker::taskTransfer;
137
else if(taskname=="buildingwork") task=&Worker::taskBuildingwork;
138
else if(taskname=="return") task=&Worker::taskReturn;
139
else if(taskname=="gowarehouse") task=&Worker::taskGowarehouse;
140
else if(taskname=="dropoff") task=&Worker::taskDropoff;
141
else if(taskname=="fetchfromflag") task=&Worker::taskFetchfromflag;
142
else if(taskname=="waitforcapacity") task=&Worker::taskWaitforcapacity;
143
else if(taskname=="leavebuilding") task=&Worker::taskLeavebuilding;
144
else if(taskname=="fugitive") task=&Worker::taskFugitive;
145
else if(taskname=="geologist") task=&Worker::taskGeologist;
146
else if(taskname=="road") task=&Carrier::taskRoad;
147
else if(taskname=="transport") task=&Carrier::taskTransport;
148
else if(taskname=="launchattack") task=&Soldier::taskLaunchAttack;
149
else if(taskname=="defendbuilding") task=&Soldier::taskDefendBuilding;
150
else if(taskname=="waitforassault") task=&Soldier::taskWaitForAssault;
151
else if(taskname=="") continue; // Skip task
153
throw wexception("Unknown task %s in file!\n", taskname.c_str());
157
s->ivar1=fr->Signed32();
158
s->ivar2=fr->Signed32();
159
s->ivar3=fr->Signed32();
163
int obj=fr->Unsigned32();
165
assert(ol->is_object_known(obj));
166
s->objvar1=ol->get_object_by_file_index(obj);
169
s->svar1=fr->CString();
170
s->coords.x=fr->Signed32();
171
s->coords.y=fr->Signed32();
173
bool diranims=fr->Unsigned8();
175
s->diranims=new DirAnimations();
176
s->diranims->overwrite_animation(1, bob->get_descr()->get_animation(fr->CString()));
177
s->diranims->overwrite_animation(2, bob->get_descr()->get_animation(fr->CString()));
178
s->diranims->overwrite_animation(3, bob->get_descr()->get_animation(fr->CString()));
179
s->diranims->overwrite_animation(4, bob->get_descr()->get_animation(fr->CString()));
180
s->diranims->overwrite_animation(5, bob->get_descr()->get_animation(fr->CString()));
181
s->diranims->overwrite_animation(6, bob->get_descr()->get_animation(fr->CString()));
185
uint pathsteps=fr->Unsigned16();
186
if(s->path && i<oldstacksize)
190
start.x=fr->Unsigned16();
191
start.y=fr->Unsigned16();
192
Path* path=new Path(egbase->get_map(), start);
193
for(uint i=0; i<pathsteps; i++)
194
path->append(fr->Unsigned8());
199
if(s->transfer && i<oldstacksize && !trans)
202
if(s->task==&Worker::taskGowarehouse || s->task==&Worker::taskTransfer)
207
bool route=fr->Unsigned8();
208
if(s->route && i<oldstacksize)
220
route->m_totalcost=fr->Signed32();
221
int nsteps=fr->Unsigned16();
222
for(int i=0; i<nsteps; i++) {
223
int reg=fr->Unsigned32();
224
assert(ol->is_object_known(reg));
225
Flag* flag=static_cast<Flag*>(ol->get_object_by_file_index(reg));
226
route->m_route.push_back(flag);
229
route->verify(static_cast<Game*>(egbase));
234
bool program=fr->Unsigned8();
236
std::string progname=fr->CString();
237
if(bob->get_bob_type()==Bob::WORKER)
238
s->program=static_cast<Worker*>(bob)->get_descr()->get_program(progname);
240
s->program=static_cast<Critter_Bob*>(bob)->get_descr()->get_program(progname);
246
bob->m_stack_dirty=fr->Unsigned8();
247
bob->m_sched_init_task=fr->Unsigned8();
248
bob->m_signal=fr->CString();
250
switch(bob->get_bob_type()) {
251
case Bob::CRITTER: read_critter_bob(fr,egbase,ol,static_cast<Critter_Bob*>(bob)); break;
252
case Bob::WORKER: read_worker_bob(fr,egbase,ol,static_cast<Worker*>(bob)); break;
253
default: throw wexception("Unknown sub bob type %i in Widelands_Map_Bobdata_Data_Packet::Read\n", bob->get_bob_type());
256
ol->mark_object_as_loaded(bob);
261
throw wexception("Unknown version %i in Widelands_Map_Bobdata_Data_Packet!\n", packet_version);
264
void Widelands_Map_Bobdata_Data_Packet::read_critter_bob(FileRead* fr, Editor_Game_Base*, Widelands_Map_Map_Object_Loader*, Critter_Bob*) {
265
int version=fr->Unsigned16();
267
if(version==CRITTER_BOB_PACKET_VERSION) {
268
// No data for critter bob currently
270
throw wexception("Unknown version %i in Critter Bob Subpacket!\n", version);
273
void Widelands_Map_Bobdata_Data_Packet::read_worker_bob(FileRead* fr, Editor_Game_Base* egbase, Widelands_Map_Map_Object_Loader* ol, Worker* worker) {
274
int version=fr->Unsigned16();
276
if(version==WORKER_BOB_PACKET_VERSION) {
277
switch(worker->get_worker_type()) {
278
case Worker_Descr::NORMAL: break;
279
case Worker_Descr::SOLDIER:
281
int soldierversion=fr->Unsigned16();
282
if(soldierversion==SOLDIER_WORKER_BOB_PACKET_VERSION) {
283
Soldier* soldier=static_cast<Soldier*>(worker);
285
soldier->m_hp_current=fr->Unsigned32();
286
soldier->m_hp_max=fr->Unsigned32();
287
soldier->m_min_attack=fr->Unsigned32();
288
soldier->m_max_attack=fr->Unsigned32();
289
soldier->m_defense=fr->Unsigned32();
290
soldier->m_evade=fr->Unsigned32();
291
soldier->m_hp_level=fr->Unsigned32();
292
soldier->m_attack_level=fr->Unsigned32();
293
soldier->m_defense_level=fr->Unsigned32();
294
soldier->m_evade_level=fr->Unsigned32();
295
soldier->m_marked=fr->Unsigned8();
297
throw wexception("Unknown version %i in Soldier Bob (SubSubPacket)!", soldierversion);
301
case Worker_Descr::CARRIER:
303
int carrierversion=fr->Unsigned16();
304
if(carrierversion==CARRIER_WORKER_BOB_PACKET_VERSION) {
305
Carrier* c=static_cast<Carrier*>(worker);
306
c->m_acked_ware=fr->Signed32();
310
default: throw wexception("Unknown Worker %i in Widelands_Map_Bobdata_Data_Packet::read_worker_bob()\n", worker->get_worker_type());
314
uint reg=fr->Unsigned32();
316
assert(ol->is_object_known(reg));
317
worker->set_location(static_cast<PlayerImmovable*>(ol->get_object_by_file_index(reg)));
318
assert(worker->m_location.get(egbase));
320
worker->m_location=0;
324
reg=fr->Unsigned32();
326
assert(ol->is_object_known(reg));
327
worker->m_carried_item=ol->get_object_by_file_index(reg);
329
worker->m_carried_item=0;
333
worker->m_needed_exp=fr->Signed32();
334
worker->m_current_exp=fr->Signed32();
337
if(worker->m_location.get(egbase))
338
eco=static_cast<PlayerImmovable*>(worker->m_location.get(egbase))->get_economy();
340
worker->set_economy(eco);
341
if(worker->m_carried_item.get(egbase))
342
static_cast<WareInstance*>(worker->m_carried_item.get(egbase))->set_economy(eco);
346
throw wexception("Unknown version %i in Worker Bob Subpacket!\n", version);
353
void Widelands_Map_Bobdata_Data_Packet::Write(FileWrite* fw, Editor_Game_Base* egbase, Widelands_Map_Map_Object_Saver* os) throw(wexception) {
354
// first of all the magic bytes
355
fw->Unsigned16(PACKET_BOBDATA);
357
// now packet version
358
fw->Unsigned16(CURRENT_PACKET_VERSION);
360
// Here we will insert skip data (packet lenght)
361
// later, write a dummy for know
362
int filepos = fw->GetFilePos();
363
fw->Unsigned32(0x00000000);
364
fw->ResetByteCounter();
366
Map* map=egbase->get_map();
367
for(ushort y=0; y<map->get_height(); y++) {
368
for(ushort x=0; x<map->get_width(); x++) {
370
std::vector<Bob*> bobarr;
372
egbase->get_map()->find_bobs(Coords(x,y), 0, &bobarr);
374
for(uint i=0; i<bobarr.size(); i++) {
376
for(uint j=i; j<bobarr.size(); j++) {
378
if(ibob->get_file_serial() < jbob->get_file_serial()) {
386
for(uint i=0; i<bobarr.size(); i++) {
388
assert(os->is_object_known(bob));
389
uint reg=os->get_object_file_index(bob);
395
fw->Unsigned8(bob->m_owner->get_player_number());
400
fw->Unsigned16(bob->m_position.x);
401
fw->Unsigned16(bob->m_position.y);
402
// FIELD can't be saved
404
// m_linknext, linkpprev are handled automatically
406
// Are we currently transfering?
407
if(bob->m_stack.size() && bob->m_stack[0].transfer)
412
fw->Unsigned32(bob->m_actid);
417
fw->CString(bob->get_descr()->get_animation_name(bob->m_anim).c_str());
420
fw->Signed32(bob->m_animstart);
423
fw->Signed32(bob->m_walking);
426
fw->Signed32(bob->m_walkstart);
429
fw->Signed32(bob->m_walkend);
432
fw->Unsigned16(bob->m_stack.size());
433
for(uint i=0; i<bob->m_stack.size(); i++) {
434
Bob::State* s=&bob->m_stack[i];
436
// Write name, enough to reconstruct the
438
fw->CString(s->task->name);
440
fw->Signed32(s->ivar1);
441
fw->Signed32(s->ivar2);
442
fw->Signed32(s->ivar3);
444
Map_Object* obj=s->objvar1.get(egbase);
446
assert(os->is_object_known(obj));
447
fw->Unsigned32(os->get_object_file_index(obj));
451
fw->CString(s->svar1.c_str());
454
fw->Signed32(s->coords.x);
455
fw->Signed32(s->coords.y);
459
fw->CString(bob->get_descr()->get_animation_name(s->diranims->get_animation(1)).c_str());
460
fw->CString(bob->get_descr()->get_animation_name(s->diranims->get_animation(2)).c_str());
461
fw->CString(bob->get_descr()->get_animation_name(s->diranims->get_animation(3)).c_str());
462
fw->CString(bob->get_descr()->get_animation_name(s->diranims->get_animation(4)).c_str());
463
fw->CString(bob->get_descr()->get_animation_name(s->diranims->get_animation(5)).c_str());
464
fw->CString(bob->get_descr()->get_animation_name(s->diranims->get_animation(6)).c_str());
470
fw->Unsigned16(s->path->get_nsteps());
471
Coords pstart=s->path->get_start();
472
fw->Unsigned16(pstart.x);
473
fw->Unsigned16(pstart.y);
474
for(int i=0; i<s->path->get_nsteps(); i++)
475
fw->Unsigned8(s->path->get_step(i));
482
fw->Signed32(s->route->get_totalcost());
483
fw->Unsigned16(s->route->get_nrsteps());
484
for(int i=0; i<s->route->get_nrsteps(); i++) {
485
Flag* f=s->route->get_flag(egbase, i);
486
assert(os->is_object_known(f));
487
fw->Unsigned32(os->get_object_file_index(f));
495
fw->CString(s->program->get_name().c_str());
502
fw->Unsigned8(bob->m_stack_dirty);
503
fw->Unsigned8(bob->m_sched_init_task);
504
fw->CString(bob->m_signal.c_str());
506
switch(bob->get_bob_type()) {
507
case Bob::CRITTER: write_critter_bob(fw,egbase,os,static_cast<Critter_Bob*>(bob)); break;
508
case Bob::WORKER: write_worker_bob(fw,egbase,os,static_cast<Worker*>(bob)); break;
509
default: throw wexception("Unknown sub bob type %i in Widelands_Map_Bobdata_Data_Packet::Write\n", bob->get_bob_type());
513
os->mark_object_as_saved(bob);
518
fw->Unsigned32(0xffffffff); // No more bobs
520
// Now, write the packet length
521
fw->Unsigned32(fw->GetByteCounter(), filepos);
526
void Widelands_Map_Bobdata_Data_Packet::write_critter_bob(FileWrite* fw, Editor_Game_Base* egbase, Widelands_Map_Map_Object_Saver* os, Critter_Bob* critter) {
527
fw->Unsigned16(CRITTER_BOB_PACKET_VERSION);
530
void Widelands_Map_Bobdata_Data_Packet::write_worker_bob(FileWrite* fw, Editor_Game_Base* egbase, Widelands_Map_Map_Object_Saver* os, Worker* worker) {
531
fw->Unsigned16(WORKER_BOB_PACKET_VERSION);
533
switch(worker->get_worker_type()) {
534
case Worker_Descr::NORMAL: break;
535
case Worker_Descr::SOLDIER:
537
fw->Unsigned16(SOLDIER_WORKER_BOB_PACKET_VERSION);
538
Soldier* soldier=static_cast<Soldier*>(worker);
540
fw->Unsigned32(soldier->m_hp_current);
541
fw->Unsigned32(soldier->m_hp_max);
542
fw->Unsigned32(soldier->m_min_attack);
543
fw->Unsigned32(soldier->m_max_attack);
544
fw->Unsigned32(soldier->m_defense);
545
fw->Unsigned32(soldier->m_evade);
546
fw->Unsigned32(soldier->m_hp_level);
547
fw->Unsigned32(soldier->m_attack_level);
548
fw->Unsigned32(soldier->m_defense_level);
549
fw->Unsigned32(soldier->m_evade_level);
550
fw->Unsigned8 (soldier->m_marked);
554
case Worker_Descr::CARRIER:
556
fw->Unsigned16(CARRIER_WORKER_BOB_PACKET_VERSION);
557
Carrier* c=static_cast<Carrier*>(worker);
559
fw->Signed32(c->m_acked_ware);
562
default: throw wexception("Unknown Worker %i in Widelands_Map_Bobdata_Data_Packet::write_worker_bob()\n", worker->get_worker_type());
566
Map_Object* loca=worker->m_location.get(egbase);
568
assert(os->is_object_known(loca));
569
fw->Unsigned32(os->get_object_file_index(loca));
573
// Economy is not our beer
576
Map_Object* carried_item=worker->m_carried_item.get(egbase);
578
assert(os->is_object_known(carried_item));
579
fw->Unsigned32(os->get_object_file_index(carried_item));
584
* Write if a idle supply is to be created
591
fw->Signed32(worker->m_needed_exp);
592
fw->Signed32(worker->m_current_exp);