2
* Copyright (C) 2002-4 by the Widelands Development Team
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.
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.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
21
#include "filesystem.h"
22
#include "editor_game_base.h"
27
#include "widelands_map_data_packet_ids.h"
28
#include "widelands_map_bob_data_packet.h"
31
// VERSION 1: inital release
32
// VERSION 2: workers are also handled here, registering through Map_Object_Loader/Saver
33
#define CURRENT_PACKET_VERSION 2
38
Widelands_Map_Bob_Data_Packet::~Widelands_Map_Bob_Data_Packet(void) {
44
void Widelands_Map_Bob_Data_Packet::Read(FileRead* fr, Editor_Game_Base* egbase, bool skip, Widelands_Map_Map_Object_Loader* mol) throw(wexception) {
45
Map* map=egbase->get_map();
47
// First packet version
48
int packet_version=fr->Unsigned16();
50
if(packet_version==1) {
51
read_packet_version_1(fr,egbase,skip,mol);
53
} else if (packet_version==CURRENT_PACKET_VERSION) {
54
// Now get all the the bobs
55
for(ushort y=0; y<map->get_height(); y++) {
56
for(ushort x=0; x<map->get_width(); x++) {
57
uint nr_bobs=fr->Unsigned32();
61
assert(!egbase->get_map()->get_field(Coords(x,y))->get_first_bob());
63
for(i=0;i<nr_bobs;i++) {
64
std::string owner=fr->CString();
65
std::string name=fr->CString();
66
uchar subtype=fr->Unsigned8();
68
uint reg=fr->Unsigned32();
69
assert(!mol->is_object_known(reg));
72
if(subtype != Bob::CRITTER && subtype != Bob::WORKER)
73
throw wexception("Unknown bob type %i in Widelands_Map_Bob_Data_Packet!\n", subtype);
76
if(subtype!=Bob::CRITTER)
77
throw wexception("world bob is not a critter!\n");
78
int idx=egbase->get_map()->get_world()->get_bob(name.c_str());
80
throw wexception("Map defines Bob %s, but world doesn't deliver!\n", name.c_str());
81
bob=egbase->create_bob(Coords(x,y),idx);
83
if(skip) continue; // We do no load player bobs when no scenario
84
egbase->manually_load_tribe(owner.c_str()); // Make sure that the correct tribe is known and loaded
85
Tribe_Descr* tribe=egbase->get_tribe(owner.c_str());
87
throw wexception("Map asks for Tribe %s, but world doesn't deliver!\n", owner.c_str());
88
if(subtype==Bob::WORKER) {
89
int idx=tribe->get_worker_index(name.c_str());
91
throw wexception("Map defines Bob %s, but tribe %s doesn't deliver!\n", name.c_str(), owner.c_str());
92
Worker_Descr* descr=tribe->get_worker_descr(idx);
93
bob=descr->create_object();
94
bob->set_position(egbase, Coords(x,y));
96
} else if(subtype==Bob::CRITTER) {
97
int idx=tribe->get_bob(name.c_str());
99
throw wexception("Map defines Bob %s, but tribe %s doesn't deliver!\n", name.c_str(), owner.c_str());
100
bob=egbase->create_bob(Coords(x,y),idx,tribe);
106
// Register the bob for further loading
108
mol->register_object(egbase, reg, bob);
116
assert(0); // never here
123
void Widelands_Map_Bob_Data_Packet::Write(FileWrite* fw, Editor_Game_Base* egbase, Widelands_Map_Map_Object_Saver* mos) throw(wexception) {
126
// first of all the magic bytes
127
fw->Unsigned16(PACKET_BOB);
129
// now packet version
130
fw->Unsigned16(CURRENT_PACKET_VERSION);
132
// Now, all bob id and registerd it
133
// A Field can have more
134
// than one bob, we have to take this into account
135
// uchar numbers of bob for field
140
Map* map=egbase->get_map();
141
for(ushort y=0; y<map->get_height(); y++) {
142
for(ushort x=0; x<map->get_width(); x++) {
143
std::vector<Bob*> bobarr;
145
egbase->get_map()->find_bobs(Coords(x,y), 0, &bobarr);
146
fw->Unsigned32(bobarr.size());
148
for(uint i=0; i<bobarr.size(); i++) {
150
for(uint j=i; j<bobarr.size(); j++) {
152
if(ibob->get_file_serial() < jbob->get_file_serial()) {
160
for(uint i=0;i<bobarr.size(); i++) {
161
// write serial number
162
assert(!mos->is_object_known(bobarr[i])); // a bob can't be owned by two fields
163
uint reg=mos->register_object(bobarr[i]);
165
std::string owner_tribe = bobarr[i]->get_descr()->get_owner_tribe() ? bobarr[i]->get_descr()->get_owner_tribe()->get_name() : "world";
166
fw->CString(owner_tribe.c_str());
168
fw->CString(bobarr[i]->get_name().c_str());
169
// Write it's subtype
170
fw->Unsigned8(bobarr[i]->get_bob_type());
171
// And it's file register index
182
* Below here are the read functions for old map formats
184
void Widelands_Map_Bob_Data_Packet::read_packet_version_1(FileRead* fr, Editor_Game_Base* egbase, bool skip, Widelands_Map_Map_Object_Loader* mol) {
185
Map* map=egbase->get_map();
186
World* world=map->get_world();
187
int nr_bobs=fr->Unsigned16();
188
if(nr_bobs>world->get_nr_bobs()) throw wexception("Number of bobs in map (%i) is bigger than in world (%i)",
189
nr_bobs, world->get_nr_bobs());
191
// construct ids and map
192
std::map<uchar,Bob_Descr*> smap;
194
for(int i=0; i<nr_bobs; i++) {
195
int id=fr->Unsigned16();
196
buffer=fr->CString();
197
if(!world->get_bob_descr(world->get_bob(buffer))) throw wexception("Bob '%s' exists in map, not in world!", buffer);
198
smap[id]=world->get_bob_descr(world->get_bob(buffer));
201
// Now get all the the bobs
202
for(ushort y=0; y<map->get_height(); y++) {
203
for(ushort x=0; x<map->get_width(); x++) {
204
int nr_bobs=fr->Unsigned8();
207
for(i=0;i<nr_bobs;i++) {
208
int id=fr->Unsigned16();
209
egbase->create_bob(Coords(x, y), id);