~ubuntu-branches/ubuntu/precise/widelands/precise-backports

« back to all changes in this revision

Viewing changes to src/widelands_map_bob_data_packet.cc

  • Committer: Bazaar Package Importer
  • Author(s): Martin Quinson
  • Date: 2005-02-14 10:41:12 UTC
  • Revision ID: james.westby@ubuntu.com-20050214104112-6v08iux9fptxpva9
Tags: upstream-build9
Import upstream version build9

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2002-4 by the Widelands Development Team
 
3
 *
 
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.
 
8
 *
 
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.
 
13
 *
 
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.
 
17
 *
 
18
 */
 
19
 
 
20
#include <map>
 
21
#include "filesystem.h"
 
22
#include "editor_game_base.h"
 
23
#include "map.h"
 
24
#include "player.h"
 
25
#include "tribe.h"
 
26
#include "world.h"
 
27
#include "widelands_map_data_packet_ids.h"
 
28
#include "widelands_map_bob_data_packet.h"
 
29
#include "error.h"
 
30
 
 
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
 
34
 
 
35
/*
 
36
 * Destructor
 
37
 */
 
38
Widelands_Map_Bob_Data_Packet::~Widelands_Map_Bob_Data_Packet(void) {
 
39
}
 
40
 
 
41
/*
 
42
 * Read Function
 
43
 */
 
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();
 
46
 
 
47
   // First packet version
 
48
   int packet_version=fr->Unsigned16();
 
49
 
 
50
   if(packet_version==1) {
 
51
      read_packet_version_1(fr,egbase,skip,mol);
 
52
      return;
 
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();
 
58
      
 
59
            uint i=0;
 
60
 
 
61
            assert(!egbase->get_map()->get_field(Coords(x,y))->get_first_bob());
 
62
            
 
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();
 
67
               
 
68
               uint reg=fr->Unsigned32();
 
69
               assert(!mol->is_object_known(reg));
 
70
 
 
71
               Bob* bob=0;
 
72
               if(subtype != Bob::CRITTER && subtype != Bob::WORKER) 
 
73
                  throw wexception("Unknown bob type %i in Widelands_Map_Bob_Data_Packet!\n", subtype);
 
74
 
 
75
               if(owner=="world") {
 
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());
 
79
                  if(idx==-1) 
 
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);
 
82
               } else {
 
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());
 
86
                  if(!tribe) 
 
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());
 
90
                     if(idx==-1) 
 
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));
 
95
                     bob->init(egbase);
 
96
                  } else if(subtype==Bob::CRITTER) {
 
97
                     int idx=tribe->get_bob(name.c_str());
 
98
                     if(idx==-1) 
 
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); 
 
101
                  }
 
102
               }
 
103
            
 
104
               assert(bob);
 
105
 
 
106
               // Register the bob for further loading
 
107
               if(!skip)
 
108
                  mol->register_object(egbase, reg, bob);
 
109
            }
 
110
         }
 
111
      }
 
112
      // DONE
 
113
      return;
 
114
   }
 
115
   
 
116
      assert(0); // never here
 
117
}
 
118
 
 
119
 
 
120
/*
 
121
 * Write Function
 
122
 */
 
123
void Widelands_Map_Bob_Data_Packet::Write(FileWrite* fw, Editor_Game_Base* egbase, Widelands_Map_Map_Object_Saver* mos) throw(wexception) {
 
124
   assert(mos);
 
125
 
 
126
   // first of all the magic bytes
 
127
   fw->Unsigned16(PACKET_BOB);
 
128
 
 
129
   // now packet version
 
130
   fw->Unsigned16(CURRENT_PACKET_VERSION);
 
131
 
 
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
 
136
   //      bob1
 
137
   //      bob2
 
138
   //      ...
 
139
   //      bobn
 
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;
 
144
         
 
145
            egbase->get_map()->find_bobs(Coords(x,y), 0, &bobarr);
 
146
            fw->Unsigned32(bobarr.size());
 
147
 
 
148
            for(uint i=0; i<bobarr.size(); i++) {
 
149
               Bob* ibob=bobarr[i];
 
150
               for(uint j=i; j<bobarr.size(); j++) {
 
151
                  Bob* jbob=bobarr[j];
 
152
                  if(ibob->get_file_serial() < jbob->get_file_serial()) {
 
153
                     bobarr[i] = jbob;
 
154
                     bobarr[j] = ibob;
 
155
                     ibob=jbob;
 
156
                  }
 
157
               }
 
158
            }
 
159
 
 
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]);
 
164
               // Write its owner
 
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());
 
167
               // Write it's name
 
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
 
172
               fw->Unsigned32(reg);
 
173
            }
 
174
      }
 
175
   }
 
176
 
 
177
   // DONE
 
178
}
 
179
 
 
180
 
 
181
/* 
 
182
 * Below here are the read functions for old map formats
 
183
 */
 
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());
 
190
 
 
191
   // construct ids and map
 
192
   std::map<uchar,Bob_Descr*> smap;
 
193
   char* buffer;
 
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));
 
199
   }
 
200
 
 
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();
 
205
 
 
206
         int i=0;
 
207
         for(i=0;i<nr_bobs;i++) {
 
208
            int id=fr->Unsigned16();
 
209
            egbase->create_bob(Coords(x, y), id);
 
210
         }
 
211
      }
 
212
   }
 
213
}
 
214