00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifdef HAVE_CONFIG_H
00023 # include <config.h>
00024 #endif
00025
00026 #ifndef ALPHA_LINUX_CXX
00027 # include <cstring>
00028 #endif
00029 #include "gamewin.h"
00030 #include "game.h"
00031 #include "monsters.h"
00032 #include "ucmachine.h"
00033 #include "utils.h"
00034 #include "fnames.h"
00035 #include "schedule.h"
00036 #include "databuf.h"
00037
00038
00039 #ifndef UNDER_CE
00040 using std::cerr;
00041 using std::cout;
00042 using std::endl;
00043 using std::ifstream;
00044 using std::ios;
00045 using std::memset;
00046 using std::ofstream;
00047 #endif
00048
00049
00050
00051
00052
00053 void Game_window::read_npcs
00054 (
00055 )
00056 {
00057 npcs.resize(1);
00058 camera_actor = npcs[0] = main_actor = new Main_actor("", 0);
00059 ifstream nfile_stream;
00060 StreamDataSource nfile(&nfile_stream);
00061 int num_npcs;
00062 bool fix_unused = false;
00063 try
00064 {
00065 U7open(nfile_stream, NPC_DAT);
00066 num_npcs1 = nfile.read2();
00067 num_npcs = num_npcs1 + nfile.read2();
00068 main_actor->read(&nfile, 0, false, fix_unused);
00069 }
00070 catch(exult_exception &e)
00071 {
00072 if (!Game::is_editing())
00073 throw e;
00074 num_npcs1 = num_npcs = 1;
00075 if (Game::get_avname())
00076 main_actor->set_npc_name(Game::get_avname());
00077 main_actor->set_shape(721);
00078 main_actor->set_invalid();
00079 main_actor->move(c_num_tiles/2, c_num_tiles/2, 0);
00080 }
00081 npcs.resize(num_npcs);
00082 bodies.resize(num_npcs);
00083 int i;
00084
00085
00086 center_view(main_actor->get_tile());
00087 for (i = 1; i < num_npcs; i++)
00088 {
00089 npcs[i] = new Npc_actor("", 0);
00090 npcs[i]->read(&nfile, i, i < num_npcs1, fix_unused);
00091 if (npcs[i]->is_unused())
00092 {
00093 npcs[i]->remove_this(1);
00094 npcs[i]->set_schedule_type(Schedule::wait);
00095 }
00096 else
00097 npcs[i]->restore_schedule();
00098 CYCLE_RED_PLASMA();
00099 }
00100 nfile_stream.close();
00101 main_actor->set_actor_shape();
00102 try
00103 {
00104 U7open(nfile_stream, MONSNPCS);
00105
00106 int cnt = nfile.read2();
00107 char tmp = nfile.read1();
00108 int okay = nfile_stream.good();
00109 nfile.skip(-1);
00110 while (okay && cnt--)
00111 {
00112
00113 nfile.skip(2);
00114 unsigned short shnum = nfile.read2()&0x3ff;
00115 okay = nfile_stream.good();
00116 nfile.skip(-4);
00117 ShapeID sid(shnum, 0);
00118 if (!okay || sid.get_num_frames() < 16)
00119 break;
00120 Monster_actor *act = Monster_actor::create(shnum);
00121 act->read(&nfile, -1, false, fix_unused);
00122 act->restore_schedule();
00123 CYCLE_RED_PLASMA();
00124 }
00125 }
00126 catch(exult_exception &e) {
00127 #ifdef DEBUG
00128 cerr << "Error reading saved monsters. Clearing list." << endl;
00129 #endif
00130 Monster_actor::give_up();
00131 }
00132 if (moving_barge)
00133 {
00134 Barge_object *b = moving_barge;
00135 moving_barge = 0;
00136 set_moving_barge(b);
00137 }
00138 read_schedules();
00139 center_view(main_actor->get_tile());
00140 }
00141
00142
00143
00144
00145
00146
00147
00148 void Game_window::write_npcs
00149 (
00150 )
00151 {
00152 int num_npcs = npcs.size();
00153 ofstream nfile_stream;
00154 U7open(nfile_stream, NPC_DAT);
00155 StreamDataSource nfile(&nfile_stream);
00156
00157 nfile.write2(num_npcs1);
00158 nfile.write2(num_npcs - num_npcs1);
00159 int i;
00160 for (i = 0; i < num_npcs; i++)
00161 npcs[i]->write(&nfile);
00162 nfile_stream.flush();
00163 bool result = nfile_stream.good();
00164 if (!result)
00165 throw file_write_exception(NPC_DAT);
00166 nfile_stream.close();
00167 write_schedules();
00168
00169 U7open(nfile_stream, MONSNPCS);
00170 int cnt = 0;
00171 nfile.write2(0);
00172 for (Monster_actor *mact = Monster_actor::get_first_in_world();
00173 mact; mact = mact->get_next_in_world())
00174 if (!mact->is_dead())
00175 {
00176 mact->write(&nfile);
00177 cnt++;
00178 }
00179 nfile.seek(0);
00180 nfile.write2(cnt);
00181 nfile_stream.flush();
00182 result = nfile_stream.good();
00183 nfile_stream.close();
00184 if (!result)
00185 throw file_write_exception(NPC_DAT);
00186 }
00187
00188
00189
00190
00191
00192 void Game_window::read_schedules
00193 (
00194 )
00195 {
00196 ifstream sfile_stream;
00197 int num_npcs = 0;
00198 try
00199 {
00200 U7open(sfile_stream, GSCHEDULE);
00201 }
00202 catch(exult_exception e)
00203 {
00204 #ifdef DEBUG
00205 cerr << "Couldn't open " << GSCHEDULE << ". Falling back to "
00206 << SCHEDULE_DAT << "." << endl;
00207 #endif
00208 try
00209 {
00210 U7open(sfile_stream, SCHEDULE_DAT);
00211 }
00212 catch(exult_exception e1)
00213 {
00214 if (!Game::is_editing())
00215 throw e1;
00216 else
00217 return;
00218 }
00219 }
00220 StreamDataSource sfile(&sfile_stream);
00221
00222 num_npcs = sfile.read4();
00223
00224 short *offsets = new short[num_npcs];
00225 int i;
00226 for (i = 0; i < num_npcs; i++)
00227 offsets[i] = sfile.read2();
00228 for (i = 0; i < num_npcs - 1; i++)
00229 {
00230
00231 Actor *npc = npcs[i + 1];
00232 int cnt = offsets[i + 1] - offsets[i];
00233
00234 Schedule_change *schedules = cnt?new Schedule_change[cnt]:0;
00235
00236 for (int j = 0; j < cnt; j++)
00237 {
00238 unsigned char ent[4];
00239 sfile.read(reinterpret_cast<char*>(ent), 4);
00240 schedules[j].set(ent);
00241 }
00242
00243 if (npc)
00244 npc->set_schedules(schedules, cnt);
00245 else
00246 delete schedules;
00247 CYCLE_RED_PLASMA();
00248 }
00249 delete [] offsets;
00250 cout.flush();
00251 }
00252
00253
00254
00255
00256
00257
00258 void Game_window::write_schedules ()
00259 {
00260
00261 ofstream sfile_stream;
00262 Schedule_change *schedules;
00263 int cnt;
00264 short offset = 0;
00265 int i;
00266 int num;
00267
00268
00269 num = npcs.size();
00270
00271 U7open(sfile_stream, GSCHEDULE);
00272 StreamDataSource sfile(&sfile_stream);
00273
00274 sfile.write4(num);
00275 sfile.write2(0);
00276
00277 for (i = 1; i < num; i++)
00278 {
00279 npcs[i]->get_schedules(schedules, cnt);
00280 offset += cnt;
00281 sfile.write2(offset);
00282 }
00283
00284 for (i = 1; i < num; i++)
00285 {
00286 npcs[i]->get_schedules(schedules, cnt);
00287 for (int j = 0; j < cnt; j++)
00288 {
00289 unsigned char ent[4];
00290 schedules[j].get(ent);
00291 sfile.write(reinterpret_cast<char*>(ent), 4);
00292 }
00293 }
00294 }
00295
00296 void Game_window::revert_schedules(Actor *npc)
00297 {
00298
00299 if (npc->get_npc_num() <= 0) return;
00300
00301 int i;
00302 ifstream sfile_stream;
00303
00304 U7open(sfile_stream, SCHEDULE_DAT);
00305 StreamDataSource sfile(&sfile_stream);
00306
00307
00308 int num_npcs = sfile.read4();
00309 short *offsets = new short[num_npcs];
00310 for (i = 0; i < num_npcs; i++) offsets[i] = sfile.read2();
00311
00312
00313 sfile.skip(offsets[npc->get_npc_num()-1]*4);
00314
00315
00316 int cnt = offsets[npc->get_npc_num()] - offsets[npc->get_npc_num()-1];
00317
00318
00319 Schedule_change *schedules = cnt?new Schedule_change[cnt]:0;
00320
00321 for (i = 0; i < cnt; i++)
00322 {
00323 unsigned char ent[4];
00324 sfile.read(reinterpret_cast<char*>(ent), 4);
00325 schedules[i].set(ent);
00326 }
00327
00328 npc->set_schedules(schedules, cnt);
00329
00330
00331 delete [] offsets;
00332 }
00333