00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifdef HAVE_CONFIG_H
00026 # include <config.h>
00027 #endif
00028
00029 #include "studio.h"
00030 #include "u7drag.h"
00031 #include "servemsg.h"
00032 #include "objserial.h"
00033 #include "exult_constants.h"
00034 #include "shapefile.h"
00035 #include "shapedraw.h"
00036
00037 using std::cout;
00038 using std::cerr;
00039 using std::endl;
00040
00041
00042
00043
00044 C_EXPORT void on_open_egg_activate
00045 (
00046 GtkMenuItem *menuitem,
00047 gpointer user_data
00048 )
00049 {
00050 ExultStudio *studio = ExultStudio::get_instance();
00051 studio->open_egg_window();
00052 }
00053
00054
00055
00056
00057 C_EXPORT void on_egg_apply_btn_clicked
00058 (
00059 GtkButton *btn,
00060 gpointer user_data
00061 )
00062 {
00063 ExultStudio::get_instance()->save_egg_window();
00064 }
00065
00066
00067
00068
00069 C_EXPORT void on_egg_cancel_btn_clicked
00070 (
00071 GtkButton *btn,
00072 gpointer user_data
00073 )
00074 {
00075 ExultStudio::get_instance()->close_egg_window();
00076 }
00077
00078
00079
00080
00081 C_EXPORT gboolean on_egg_window_delete_event
00082 (
00083 GtkWidget *widget,
00084 GdkEvent *event,
00085 gpointer user_data
00086 )
00087 {
00088 ExultStudio::get_instance()->close_egg_window();
00089 return TRUE;
00090 }
00091
00092
00093
00094
00095 C_EXPORT gboolean on_egg_monster_draw_expose_event
00096 (
00097 GtkWidget *widget,
00098 GdkEventExpose *event,
00099 gpointer data
00100 )
00101 {
00102 ExultStudio::get_instance()->show_egg_monster(
00103 event->area.x, event->area.y, event->area.width,
00104 event->area.height);
00105 return (TRUE);
00106 }
00107
00108
00109
00110
00111 C_EXPORT gboolean on_monst_shape_focus_out_event
00112 (
00113 GtkWidget *widget,
00114 GdkEventFocus *event,
00115 gpointer user_data
00116 )
00117 {
00118 ExultStudio::get_instance()->show_egg_monster();
00119 return FALSE;
00120 }
00121
00122
00123
00124 C_EXPORT void on_teleport_coord_toggled
00125 (
00126 GtkToggleButton *btn,
00127 gpointer user_data
00128 )
00129 {
00130 ExultStudio *studio = ExultStudio::get_instance();
00131 bool on = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(btn));
00132 studio->set_sensitive("teleport_x", on);
00133 studio->set_sensitive("teleport_y", on);
00134 studio->set_sensitive("teleport_eggnum", !on);
00135 }
00136
00137
00138
00139
00140
00141 static void Egg_monster_dropped
00142 (
00143 int file,
00144 int shape,
00145 int frame,
00146 void *udata
00147 )
00148 {
00149 if (file == U7_SHAPE_SHAPES && shape >= 0 && shape < 1024)
00150 ((ExultStudio *) udata)->set_egg_monster(shape, frame);
00151 }
00152
00153 #ifdef WIN32
00154
00155 static void Drop_dragged_shape(int shape, int frame, int x, int y, void *data)
00156 {
00157 cout << "Dropped a shape: " << shape << "," << frame << " " << data << endl;
00158
00159 Egg_monster_dropped(U7_SHAPE_SHAPES, shape, frame, data);
00160 }
00161
00162 #endif
00163
00164
00165
00166
00167
00168 void ExultStudio::open_egg_window
00169 (
00170 unsigned char *data,
00171 int datalen
00172 )
00173 {
00174 bool first_time = false;
00175 if (!eggwin)
00176 {
00177 first_time = true;
00178 eggwin = glade_xml_get_widget( app_xml, "egg_window" );
00179 if (vgafile && palbuf)
00180 {
00181 egg_monster_draw = new Shape_draw(vgafile->get_ifile(),
00182 palbuf,
00183 glade_xml_get_widget(app_xml, "egg_monster_draw"));
00184 egg_monster_draw->enable_drop(Egg_monster_dropped,
00185 this);
00186 }
00187 egg_ctx = gtk_statusbar_get_context_id(
00188 GTK_STATUSBAR(glade_xml_get_widget(
00189 app_xml, "egg_status")), "Egg Editor");
00190 }
00191
00192 gtk_object_set_user_data(GTK_OBJECT(eggwin), 0);
00193
00194 gtk_widget_set_sensitive(glade_xml_get_widget(app_xml,
00195 "egg_apply_btn"), true);
00196 if (data)
00197 {
00198 if (!init_egg_window(data, datalen))
00199 return;
00200 }
00201 else if (first_time)
00202 {
00203 set_toggle("teleport_coord", true);
00204 set_sensitive("teleport_x", true);
00205 set_sensitive("teleport_y", true);
00206 set_sensitive("teleport_eggnum", false);
00207 }
00208 gtk_widget_show(eggwin);
00209
00210 #ifdef WIN32
00211 if (first_time || !eggdnd)
00212 Windnd::CreateStudioDropDest(eggdnd, egghwnd, Drop_dragged_shape, NULL, NULL, (void*) this);
00213 #endif
00214 }
00215
00216
00217
00218
00219
00220 void ExultStudio::close_egg_window
00221 (
00222 )
00223 {
00224 if (eggwin) {
00225 gtk_widget_hide(eggwin);
00226 #ifdef WIN32
00227 Windnd::DestroyStudioDropDest(eggdnd, egghwnd);
00228 #endif
00229 }
00230 }
00231
00232
00233
00234
00235
00236
00237
00238 int ExultStudio::init_egg_window
00239 (
00240 unsigned char *data,
00241 int datalen
00242 )
00243 {
00244 unsigned long addr;
00245 int tx, ty, tz;
00246 int shape, frame;
00247 int type;
00248 int criteria;
00249 int probability;
00250 int distance;
00251 bool nocturnal, once, hatched, auto_reset;
00252 int data1, data2;
00253 if (!Egg_object_in(data, datalen, addr, tx, ty, tz, shape, frame,
00254 type, criteria, probability, distance,
00255 nocturnal, once, hatched, auto_reset,
00256 data1, data2))
00257 {
00258 cout << "Error decoding egg" << endl;
00259 return 0;
00260 }
00261
00262 gtk_object_set_user_data(GTK_OBJECT(eggwin), (gpointer) addr);
00263 GtkWidget *notebook = glade_xml_get_widget(app_xml, "notebook1");
00264 if (notebook)
00265 gtk_notebook_set_page(GTK_NOTEBOOK(notebook), type - 1);
00266 set_spin("probability", probability);
00267 set_spin("distance", distance);
00268 set_optmenu("criteria", criteria);
00269 set_toggle("nocturnal", nocturnal);
00270 set_toggle("once", once);
00271 set_toggle("hatched", hatched);
00272 set_toggle("autoreset", auto_reset);
00273 switch (type)
00274 {
00275 case 1:
00276 {
00277 int shnum = data2&1023, frnum = data2>>10;
00278 set_entry("monst_shape", shnum);
00279 set_entry("monst_frame", frnum);
00280 set_optmenu("monst_schedule", data1>>8);
00281 set_optmenu("monst_align", data1&3);
00282 set_spin("monst_count", (data1&0xff)>>2);
00283 break;
00284 }
00285 case 2:
00286 set_spin("juke_song", data1&0xff);
00287 set_toggle("juke_cont", (data1>>8)&0x01);
00288 break;
00289 case 3:
00290 set_spin("sfx_number", data1&0xff);
00291 set_toggle("sfx_cont", (data1>>8)&0x01);
00292 break;
00293 case 4:
00294 set_spin("speech_number", data1&0xff);
00295 break;
00296 case 5:
00297 set_entry("usecode_number", data2, true);
00298 set_spin("usecode_quality", data1&0xff);
00299 break;
00300 case 6:
00301 set_entry("missile_shape", data1);
00302 set_optmenu("missile_dir", data2&0xff);
00303 set_spin("missile_delay", data2>>8);
00304 break;
00305 case 7:
00306 {
00307 int qual = data1&0xff;
00308 if (qual == 255)
00309 {
00310 set_toggle("teleport_coord", true);
00311 int schunk = data1 >> 8;
00312 set_entry("teleport_x",
00313 (schunk%12)*c_tiles_per_schunk +(data2&0xff),
00314 true);
00315 set_entry("teleport_y",
00316 (schunk/12)*c_tiles_per_schunk +(data2>>8),
00317 true);
00318 set_spin("teleport_eggnum", 0, false);
00319 }
00320 else
00321 {
00322 set_toggle("teleport_coord", false);
00323 set_entry("teleport_x", 0, false, false);
00324 set_entry("teleport_y", 0, false, false);
00325 set_spin("teleport_eggnum", qual);
00326 }
00327 break;
00328 }
00329 case 8:
00330 set_optmenu("weather_type", data1&0xff);
00331 set_spin("weather_length", data1>>8);
00332 break;
00333 case 9:
00334 set_spin("pathegg_num", data1&0xff);
00335 break;
00336 case 10:
00337 set_spin("btnegg_distance", data1&0xff);
00338 break;
00339 default:
00340 break;
00341 }
00342 return 1;
00343 }
00344
00345
00346
00347
00348
00349 static void Egg_response
00350 (
00351 Exult_server::Msg_type id,
00352 unsigned char *data,
00353 int datalen,
00354 void *
00355 )
00356 {
00357 if (id == Exult_server::user_responded)
00358 ExultStudio::get_instance()->close_egg_window();
00359
00360 }
00361
00362
00363
00364
00365
00366
00367
00368 int ExultStudio::save_egg_window
00369 (
00370 )
00371 {
00372 cout << "In save_egg_window()" << endl;
00373 unsigned char data[Exult_server::maxlength];
00374
00375 unsigned long addr = (unsigned long) gtk_object_get_user_data(
00376 GTK_OBJECT(eggwin));
00377 int tx = -1, ty = -1, tz = -1;
00378 int shape = -1, frame = -1;
00379 int type = -1;
00380 GtkWidget *notebook = glade_xml_get_widget(app_xml, "notebook1");
00381 if (notebook)
00382 type = 1 + gtk_notebook_get_current_page(
00383 GTK_NOTEBOOK(notebook));
00384 else
00385 {
00386 cout << "Can't find notebook widget" << endl;
00387 return 0;
00388 }
00389 int criteria = get_optmenu("criteria");
00390 int probability = get_spin("probability");
00391 int distance = get_spin("distance");
00392 bool nocturnal = get_toggle("nocturnal"),
00393 once = get_toggle("once"),
00394 hatched = get_toggle("hatched"),
00395 auto_reset = get_toggle("autoreset");
00396 int data1 = -1, data2 = -1;
00397 switch (type)
00398 {
00399 case 1:
00400 data2 = (get_num_entry("monst_shape")&1023) +
00401 (get_num_entry("monst_frame")<<10);
00402 data1 = (get_optmenu("monst_schedule")<<8) +
00403 (get_optmenu("monst_align")&3) +
00404 (get_spin("monst_count")<<2);
00405 break;
00406 case 2:
00407 data1 = (get_spin("juke_song")&0xff) +
00408 (get_toggle("juke_cont")<<8);
00409 break;
00410 case 3:
00411 data1 = (get_spin("sfx_number")&0xff) +
00412 (get_toggle("sfx_cont")<<8);
00413 break;
00414 case 4:
00415 data1 = get_spin("speech_number")&0xff;
00416 break;
00417 case 5:
00418 data2 = get_num_entry("usecode_number");
00419 data1 = get_spin("usecode_quality")&0xff;
00420 break;
00421 case 6:
00422 data1 = get_num_entry("missile_shape");
00423 data2 = (get_optmenu("missile_dir")&0xff) +
00424 (get_spin("missile_delay")<<8);
00425 break;
00426 case 7:
00427 if (get_toggle("teleport_coord"))
00428 {
00429 int tx = get_num_entry("teleport_x"),
00430 ty = get_num_entry("teleport_y");
00431 data2 = (tx&0xff) + ((ty&0xff)<<8);
00432 int sx = tx/c_tiles_per_schunk,
00433 sy = ty/c_tiles_per_schunk;
00434 data1 = 255 + ((sy*12 + sx)<<8);
00435 }
00436 else
00437 data1 = get_spin("teleport_eggnum")&0xff;
00438 break;
00439 case 8:
00440 data1 = (get_optmenu("weather_type")&0xff) +
00441 (get_spin("weather_length")<<8);
00442 break;
00443 case 9:
00444 data1 = get_spin("pathegg_num")&0xff;
00445 break;
00446 case 10:
00447 data1 = get_spin("btnegg_distance")&0xff;
00448 break;
00449 default:
00450 cout << "Unknown egg type" << endl;
00451 return 0;
00452 }
00453 if (Egg_object_out(server_socket, addr, tx, ty, tz,
00454 shape, frame, type, criteria, probability, distance,
00455 nocturnal, once, hatched, auto_reset, data1, data2) == -1)
00456 {
00457 cout << "Error sending egg data to server" <<endl;
00458 return 0;
00459 }
00460 cout << "Sent egg data to server" << endl;
00461 if (!addr)
00462 {
00463 set_statusbar("egg_status", egg_ctx,
00464 "Click on map at place to insert egg");
00465
00466 gtk_widget_set_sensitive(glade_xml_get_widget(app_xml,
00467 "egg_apply_btn"), false);
00468 waiting_for_server = Egg_response;
00469 return 1;
00470 }
00471 close_egg_window();
00472 return 1;
00473 }
00474
00475
00476
00477
00478
00479 void ExultStudio::show_egg_monster
00480 (
00481 int x, int y, int w, int h
00482 )
00483 {
00484 if (!egg_monster_draw)
00485 return;
00486 egg_monster_draw->configure();
00487
00488 int shnum = get_num_entry("monst_shape");
00489 int frnum = get_num_entry("monst_frame");
00490 egg_monster_draw->draw_shape_centered(shnum, frnum);
00491 if (w != -1)
00492 egg_monster_draw->show(x, y, w, h);
00493 else
00494 egg_monster_draw->show();
00495 }
00496
00497
00498
00499
00500
00501 void ExultStudio::set_egg_monster
00502 (
00503 int shape,
00504 int frame
00505 )
00506 {
00507 set_entry("monst_shape", shape);
00508 set_entry("monst_frame", frame);
00509 show_egg_monster();
00510 }
00511