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 "utils.h"
00035 #include "shapefile.h"
00036 #include "shapedraw.h"
00037
00038 #ifdef WIN32
00039 #include "windrag.h"
00040 #endif
00041
00042 using std::cout;
00043 using std::endl;
00044
00045
00046
00047
00048 C_EXPORT void on_open_npc_activate
00049 (
00050 GtkMenuItem *menuitem,
00051 gpointer user_data
00052 )
00053 {
00054 ExultStudio *studio = ExultStudio::get_instance();
00055 studio->open_npc_window();
00056 }
00057
00058
00059
00060
00061 C_EXPORT void on_npc_apply_btn_clicked
00062 (
00063 GtkButton *btn,
00064 gpointer user_data
00065 )
00066 {
00067 ExultStudio::get_instance()->save_npc_window();
00068 }
00069
00070
00071
00072
00073 C_EXPORT void on_npc_cancel_btn_clicked
00074 (
00075 GtkButton *btn,
00076 gpointer user_data
00077 )
00078 {
00079 ExultStudio::get_instance()->close_npc_window();
00080 }
00081
00082
00083
00084
00085 C_EXPORT gboolean on_npc_window_delete_event
00086 (
00087 GtkWidget *widget,
00088 GdkEvent *event,
00089 gpointer user_data
00090 )
00091 {
00092 ExultStudio::get_instance()->close_npc_window();
00093 return TRUE;
00094 }
00095
00096
00097
00098
00099 C_EXPORT gboolean on_npc_draw_expose_event
00100 (
00101 GtkWidget *widget,
00102 GdkEventExpose *event,
00103 gpointer data
00104 )
00105 {
00106 ExultStudio::get_instance()->show_npc_shape(
00107 event->area.x, event->area.y, event->area.width,
00108 event->area.height);
00109 return (TRUE);
00110 }
00111
00112
00113
00114
00115 C_EXPORT gboolean on_npc_shape_focus_out_event
00116 (
00117 GtkWidget *widget,
00118 GdkEventFocus *event,
00119 gpointer user_data
00120 )
00121 {
00122 ExultStudio::get_instance()->show_npc_shape();
00123 return FALSE;
00124 }
00125
00126
00127
00128
00129
00130 static void Npc_shape_dropped
00131 (
00132 int file,
00133 int shape,
00134 int frame,
00135 void *udata
00136 )
00137 {
00138 if (file == U7_SHAPE_SHAPES && shape >= 0 && shape < 1024)
00139 ((ExultStudio *) udata)->set_npc_shape(shape, frame);
00140 }
00141
00142
00143
00144
00145
00146 C_EXPORT gboolean on_npc_face_draw_expose_event
00147 (
00148 GtkWidget *widget,
00149 GdkEventExpose *event,
00150 gpointer data
00151 )
00152 {
00153 ExultStudio::get_instance()->show_npc_face(
00154 event->area.x, event->area.y, event->area.width,
00155 event->area.height);
00156 return (TRUE);
00157 }
00158
00159
00160
00161
00162
00163 static void Npc_face_dropped
00164 (
00165 int file,
00166 int shape,
00167 int frame,
00168 void *udata
00169 )
00170 {
00171 if (file == U7_SHAPE_FACES && shape >= 0 && shape < 1024)
00172 ((ExultStudio *) udata)->set_npc_face(shape, frame);
00173 }
00174
00175
00176 static char *sched_names[32] = {
00177 "Combat", "Horiz. Pace", "Vert. Pace", "Talk", "Dance",
00178 "Eat", "Farm", "Tend Shop", "Miner", "Hound", "Stand",
00179 "Loiter", "Wander", "Blacksmith", "Sleep", "Wait", "Sit",
00180 "Graze", "Bake", "Sew", "Shy", "Lab Work", "Thief", "Waiter",
00181 "Special", "Kid Games", "Eat at Inn", "Duel", "Preach",
00182 "Patrol", "Desk Work", "Follow"};
00183
00184
00185
00186
00187
00188 static void Set_schedule_line
00189 (
00190 GladeXML *app_xml,
00191 int time,
00192 int type,
00193 int tx, int ty, int tz = 0
00194 )
00195 {
00196 char *lname = g_strdup_printf("npc_sched%d", time);
00197 GtkLabel *label = GTK_LABEL(glade_xml_get_widget(app_xml, lname));
00198 g_free(lname);
00199
00200 gtk_object_set_user_data(GTK_OBJECT(label), (gpointer) type);
00201 gtk_label_set_text(label,
00202 type >= 0 && type < 32 ? sched_names[type] : "-----");
00203
00204 char *locname = g_strdup_printf("sched_loc%d", time);
00205 GtkBox *box = GTK_BOX(glade_xml_get_widget(app_xml, locname));
00206 g_free(locname);
00207 GList *list = g_list_first(box->children);
00208 GtkWidget *spin = ((GtkBoxChild *) list->data)->widget;
00209 gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin), tx);
00210 list = g_list_next(list);
00211 spin = ((GtkBoxChild *) list->data)->widget;
00212 gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin), ty);
00213 list = g_list_next(list);
00214 spin = ((GtkBoxChild *) list->data)->widget;
00215
00216 gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin), 0);
00217 gtk_widget_set_sensitive(spin, FALSE);
00218 }
00219
00220
00221
00222
00223
00224
00225
00226 static bool Get_schedule_line
00227 (
00228 GladeXML *app_xml,
00229 int time,
00230 Serial_schedule& sched
00231 )
00232 {
00233 char *lname = g_strdup_printf("npc_sched%d", time);
00234 GtkLabel *label = GTK_LABEL(glade_xml_get_widget(app_xml, lname));
00235 g_free(lname);
00236
00237 sched.type = (int) gtk_object_get_user_data(GTK_OBJECT(label));
00238 if (sched.type < 0 || sched.type > 31)
00239 return false;
00240
00241 char *locname = g_strdup_printf("sched_loc%d", time);
00242 GtkBox *box = GTK_BOX(glade_xml_get_widget(app_xml, locname));
00243 g_free(locname);
00244 GList *list = g_list_first(box->children);
00245 GtkWidget *spin = ((GtkBoxChild *) list->data)->widget;
00246 sched.tx = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spin));
00247 list = g_list_next(list);
00248 spin = ((GtkBoxChild *) list->data)->widget;
00249 sched.ty = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spin));
00250
00251
00252
00253 sched.time = time;
00254 return true;
00255 }
00256
00257
00258
00259
00260
00261 #ifdef WIN32
00262
00263 static void Drop_dragged_shape(int shape, int frame, int x, int y, void *data)
00264 {
00265 cout << "Dropped a shape: " << shape << "," << frame << " " << data << endl;
00266
00267 Npc_shape_dropped(U7_SHAPE_SHAPES, shape, frame, data);
00268 }
00269
00270 static void Drop_dragged_face(int shape, int frame, int x, int y, void *data)
00271 {
00272 cout << "Dropped a face: " << shape << "," << frame << " " << data << endl;
00273
00274 Npc_face_dropped(U7_SHAPE_FACES, shape, frame, data);
00275 }
00276
00277 #endif
00278
00279 void ExultStudio::open_npc_window
00280 (
00281 unsigned char *data,
00282 int datalen
00283 )
00284 {
00285 bool first_time = false;
00286 if (!npcwin)
00287 {
00288 first_time = true;
00289 npcwin = glade_xml_get_widget( app_xml, "npc_window" );
00290
00291 if (vgafile && palbuf)
00292 {
00293 npc_draw = new Shape_draw(vgafile->get_ifile(), palbuf,
00294 glade_xml_get_widget(app_xml, "npc_draw"));
00295 npc_draw->enable_drop(Npc_shape_dropped, this);
00296 }
00297 if (facefile && palbuf)
00298 {
00299 npc_face_draw = new Shape_draw(facefile->get_ifile(),
00300 palbuf,
00301 glade_xml_get_widget(app_xml, "npc_face_draw"));
00302 npc_face_draw->enable_drop(Npc_face_dropped, this);
00303 }
00304 npc_ctx = gtk_statusbar_get_context_id(
00305 GTK_STATUSBAR(glade_xml_get_widget(
00306 app_xml, "npc_status")), "Npc Editor");
00307 for (int i = 0; i < 24/3; i++)
00308 Set_schedule_line(app_xml, i, -1, 0, 0, 0);
00309
00310 }
00311
00312 gtk_object_set_user_data(GTK_OBJECT(npcwin), 0);
00313
00314 set_sensitive("npc_apply_btn", true);
00315 set_sensitive("npc_cancel_btn", true);
00316 remove_statusbar("npc_status", npc_ctx, npc_status_id);
00317 if (data)
00318 {
00319 if (!init_npc_window(data, datalen))
00320 return;
00321 }
00322 else
00323 init_new_npc();
00324 gtk_widget_show(npcwin);
00325 #ifdef WIN32
00326 if (first_time || !npcdnd)
00327 Windnd::CreateStudioDropDest(npcdnd, npchwnd, Drop_dragged_shape, NULL, Drop_dragged_face, (void*) this);
00328
00329 #endif
00330 }
00331
00332
00333
00334
00335
00336 void ExultStudio::close_npc_window
00337 (
00338 )
00339 {
00340 if (npcwin) {
00341 gtk_widget_hide(npcwin);
00342 #ifdef WIN32
00343 Windnd::DestroyStudioDropDest(npcdnd, npchwnd);
00344 #endif
00345 }
00346 }
00347
00348
00349
00350
00351
00352
00353
00354
00355 static bool Get_prop_spin
00356 (
00357 GList *list,
00358 GtkSpinButton *& spin,
00359 int& pnum
00360 )
00361 {
00362 GtkTableChild *ent = (GtkTableChild *) list->data;
00363 GtkBin *frame = GTK_BIN(ent->widget);
00364 spin = GTK_SPIN_BUTTON(frame->child);
00365 assert (spin != 0);
00366 const char *name = glade_get_widget_name(GTK_WIDGET(spin));
00367
00368 if (strncmp(name, "npc_prop_", 9) != 0)
00369 return false;
00370 pnum = atoi(name + 9);
00371 return (pnum >= 0 && pnum < 12);
00372 }
00373
00374
00375
00376
00377
00378
00379
00380
00381 static bool Get_flag_cbox
00382 (
00383 GList *list,
00384 unsigned long *oflags,
00385 unsigned long *siflags,
00386 unsigned long *type_flags,
00387 GtkCheckButton *& cbox,
00388 unsigned long *& bits,
00389 int& fnum
00390 )
00391 {
00392 GtkTableChild *ent = (GtkTableChild *) list->data;
00393 cbox = GTK_CHECK_BUTTON(ent->widget);
00394 assert (cbox != 0);
00395 const char *name = glade_get_widget_name(GTK_WIDGET(cbox));
00396
00397
00398 if (strncmp(name, "npc_flag_", 9) != 0)
00399 return false;
00400
00401 if (strncmp(name + 9, "si", 2) == 0)
00402 bits = siflags;
00403 else if (strncmp(name + 9, "of", 2) == 0)
00404 bits = oflags;
00405 else if (strncmp(name + 9, "tf", 2) == 0)
00406 bits = type_flags;
00407 else
00408 return false;
00409 fnum = atoi(name + 9 + 3);
00410 return (fnum >= 0 && fnum < 32);
00411 }
00412
00413
00414
00415
00416
00417 void ExultStudio::init_new_npc
00418 (
00419 )
00420 {
00421 int npc_num = -1;
00422 if (Send_data(server_socket, Exult_server::npc_info) == -1)
00423 cout << "Error sending data to server." << endl;
00424
00425 unsigned char data[Exult_server::maxlength];
00426 Exult_server::Msg_type id;
00427 Exult_server::wait_for_response(server_socket, 100);
00428 int len = Exult_server::Receive_data(server_socket,
00429 id, data, sizeof(data));
00430 unsigned char *ptr = &data[0];
00431 int npcs = Read2(ptr);
00432 int first_unused = Read2(ptr);
00433 npc_num = first_unused;
00434 set_entry("npc_num_entry", npc_num, true, false);
00435
00436 set_entry("npc_usecode_entry", 0x400 + npc_num, true,
00437 npc_num >=256 ? true : false);
00438
00439 set_npc_face(npc_num, 0);
00440 set_entry("npc_name_entry", "");
00441 set_entry("npc_ident_entry", 0);
00442 set_entry("npc_shape", -1);
00443 set_entry("npc_frame", 0);
00444 set_optmenu("npc_attack_mode", 0);
00445 set_optmenu("npc_alignment", 0);
00446
00447 GtkTable *ftable = GTK_TABLE(
00448 glade_xml_get_widget(app_xml, "npc_flags_table"));
00449
00450 for (GList *list = g_list_first(ftable->children); list;
00451 list = g_list_next(list))
00452 {
00453 GtkTableChild *ent = (GtkTableChild *) list->data;
00454 GtkCheckButton *cbox = GTK_CHECK_BUTTON(ent->widget);
00455 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cbox), false);
00456 }
00457
00458 GtkTable *ptable = GTK_TABLE(
00459 glade_xml_get_widget(app_xml, "npc_props_table"));
00460 for (GList *list = g_list_first(ptable->children); list;
00461 list = g_list_next(list))
00462 {
00463 GtkSpinButton *spin;
00464 int pnum;
00465 if (Get_prop_spin(list, spin, pnum))
00466 gtk_spin_button_set_value(spin, 12);
00467 }
00468
00469 for (int i = 0; i < 24/3; i++)
00470 Set_schedule_line(app_xml, i, -1, 0, 0, 0);
00471 }
00472
00473
00474
00475
00476
00477
00478
00479 int ExultStudio::init_npc_window
00480 (
00481 unsigned char *data,
00482 int datalen
00483 )
00484 {
00485 unsigned long addr;
00486 int tx, ty, tz;
00487 int shape, frame, face;
00488 std::string name;
00489 short npc_num, ident;
00490 int usecode;
00491 int properties[12];
00492 short attack_mode, alignment;
00493 unsigned long oflags;
00494 unsigned long siflags;
00495 unsigned long type_flags;
00496 short num_schedules;
00497 Serial_schedule schedules[8];
00498 if (!Npc_actor_in(data, datalen, addr, tx, ty, tz, shape, frame, face,
00499 name, npc_num, ident, usecode, properties,
00500 attack_mode, alignment,
00501 oflags, siflags, type_flags, num_schedules, schedules))
00502 {
00503 cout << "Error decoding npc" << endl;
00504 return 0;
00505 }
00506
00507 gtk_object_set_user_data(GTK_OBJECT(npcwin), (gpointer) addr);
00508
00509 set_entry("npc_name_entry", name.c_str());
00510
00511 set_entry("npc_num_entry", npc_num, true, false);
00512 set_entry("npc_ident_entry", ident);
00513
00514 set_entry("npc_shape", shape);
00515 set_entry("npc_frame", frame);
00516 set_npc_face(face, 0);
00517
00518 set_entry("npc_usecode_entry", usecode, true,
00519 npc_num >= 256 ? true : false);
00520
00521 set_optmenu("npc_attack_mode", attack_mode);
00522 set_optmenu("npc_alignment", alignment);
00523
00524 GtkTable *ftable = GTK_TABLE(
00525 glade_xml_get_widget(app_xml, "npc_flags_table"));
00526
00527 for (GList *list = g_list_first(ftable->children); list;
00528 list = g_list_next(list))
00529 {
00530 GtkCheckButton *cbox;
00531 unsigned long *bits;
00532 int fnum;
00533 if (Get_flag_cbox(list, &oflags, &siflags, &type_flags, cbox,
00534 bits, fnum))
00535 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cbox),
00536 (*bits&(1<<fnum)) != 0);
00537 }
00538
00539 GtkTable *ptable = GTK_TABLE(
00540 glade_xml_get_widget(app_xml, "npc_props_table"));
00541 for (GList *list = g_list_first(ptable->children); list;
00542 list = g_list_next(list))
00543 {
00544 GtkSpinButton *spin;
00545 int pnum;
00546 if (Get_prop_spin(list, spin, pnum))
00547 gtk_spin_button_set_value(spin, properties[pnum]);
00548 }
00549
00550 for (int i = 0; i < 24/3; i++)
00551 Set_schedule_line(app_xml, i, -1, 0, 0, 0);
00552 for (int i = 0; i < num_schedules; i++)
00553 {
00554 Serial_schedule& sched = schedules[i];
00555 int time = sched.time;
00556 if (time < 0 || time > 7)
00557 continue;
00558 Set_schedule_line(app_xml,time,sched.type, sched.tx, sched.ty);
00559 }
00560 return 1;
00561 }
00562
00563
00564
00565
00566
00567 static void Npc_response
00568 (
00569 Exult_server::Msg_type id,
00570 unsigned char *data,
00571 int datalen,
00572 void *
00573 )
00574 {
00575 ExultStudio *studio = ExultStudio::get_instance();
00576 if (id == Exult_server::user_responded)
00577 studio->close_npc_window();
00578
00579 }
00580
00581
00582
00583
00584
00585
00586
00587 int ExultStudio::save_npc_window
00588 (
00589 )
00590 {
00591 cout << "In save_npc_window()" << endl;
00592 unsigned char data[Exult_server::maxlength];
00593
00594 unsigned long addr = (unsigned long) gtk_object_get_user_data(
00595 GTK_OBJECT(npcwin));
00596 int tx = -1, ty = -1, tz = -1;
00597 std::string name(get_text_entry("npc_name_entry"));
00598 short npc_num = get_num_entry("npc_num_entry");
00599 short ident = get_num_entry("npc_ident_entry");
00600 int shape = get_num_entry("npc_shape");
00601 int frame = get_num_entry("npc_frame");
00602 GtkWidget *fw = glade_xml_get_widget(app_xml, "npc_face_frame");
00603 int face = (int) gtk_object_get_user_data(GTK_OBJECT(fw));
00604 int usecode = get_num_entry("npc_usecode_entry");
00605 short attack_mode = get_optmenu("npc_attack_mode");
00606 short alignment = get_optmenu("npc_alignment");
00607
00608 unsigned long oflags = 0;
00609 unsigned long siflags = 0;
00610 unsigned long type_flags = 0;
00611
00612 if (shape < 0 || shape >= vgafile->get_ifile()->get_num_shapes())
00613 {
00614 EStudio::Alert("You must set a valid shape #.");
00615 return 0;
00616 }
00617
00618 GtkTable *ftable = GTK_TABLE(
00619 glade_xml_get_widget(app_xml, "npc_flags_table"));
00620
00621 for (GList *list = g_list_first(ftable->children); list;
00622 list = g_list_next(list))
00623 {
00624 GtkCheckButton *cbox;
00625 unsigned long *bits;
00626 int fnum;
00627 if (Get_flag_cbox(list, &oflags, &siflags, &type_flags, cbox,
00628 bits, fnum))
00629 if (gtk_toggle_button_get_active(
00630 GTK_TOGGLE_BUTTON(cbox)))
00631 *bits |= (1<<fnum);
00632 }
00633 int properties[12];
00634 GtkTable *ptable = GTK_TABLE(
00635 glade_xml_get_widget(app_xml, "npc_props_table"));
00636 for (GList *list = g_list_first(ptable->children); list;
00637 list = g_list_next(list))
00638 {
00639 GtkSpinButton *spin;
00640 int pnum;
00641 if (Get_prop_spin(list, spin, pnum))
00642 properties[pnum] =
00643 gtk_spin_button_get_value_as_int(spin);
00644 }
00645 short num_schedules = 0;
00646 Serial_schedule schedules[8];
00647 for (int i = 0; i < 8; i++)
00648 if (Get_schedule_line(app_xml, i, schedules[num_schedules]))
00649 num_schedules++;
00650 if (Npc_actor_out(server_socket, addr, tx, ty, tz, shape, frame, face,
00651 name, npc_num, ident, usecode,
00652 properties, attack_mode, alignment,
00653 oflags, siflags, type_flags,
00654 num_schedules, schedules) == -1)
00655 {
00656 cout << "Error sending npc data to server" <<endl;
00657 return 0;
00658 }
00659 cout << "Sent npc data to server" << endl;
00660 if (!addr)
00661 {
00662 npc_status_id = set_statusbar("npc_status", npc_ctx,
00663 "Click on map at place to insert npc");
00664
00665 set_sensitive("npc_apply_btn", false);
00666 set_sensitive("npc_cancel_btn", false);
00667 waiting_for_server = Npc_response;
00668 return 1;
00669 }
00670 close_npc_window();
00671 return 1;
00672 }
00673
00674
00675
00676
00677
00678 void ExultStudio::show_npc_shape
00679 (
00680 int x, int y, int w, int h
00681 )
00682 {
00683 if (!npc_draw)
00684 return;
00685 npc_draw->configure();
00686
00687 int shnum = get_num_entry("npc_shape");
00688 int frnum = get_num_entry("npc_frame");
00689 if (!shnum)
00690 shnum = -1;
00691 npc_draw->draw_shape_centered(shnum, frnum);
00692 if (w != -1)
00693 npc_draw->show(x, y, w, h);
00694 else
00695 npc_draw->show();
00696 }
00697
00698
00699
00700
00701
00702 void ExultStudio::set_npc_shape
00703 (
00704 int shape,
00705 int frame
00706 )
00707 {
00708 set_entry("npc_shape", shape);
00709 set_entry("npc_frame", frame);
00710 show_npc_shape();
00711 }
00712
00713
00714
00715
00716
00717 void ExultStudio::show_npc_face
00718 (
00719 int x, int y, int w, int h
00720 )
00721 {
00722 if (!npc_face_draw)
00723 return;
00724 npc_face_draw->configure();
00725 GtkWidget *frame = glade_xml_get_widget(app_xml, "npc_face_frame");
00726 int shnum = (int) gtk_object_get_user_data(GTK_OBJECT(frame));
00727 npc_face_draw->draw_shape_centered(shnum, 0);
00728 if (w != -1)
00729 npc_face_draw->show(x, y, w, h);
00730 else
00731 npc_face_draw->show();
00732 }
00733
00734
00735
00736
00737
00738 void ExultStudio::set_npc_face
00739 (
00740 int shape,
00741 int frame
00742 )
00743 {
00744
00745
00746 if (shape < 0)
00747 shape = 1;
00748 GtkWidget *widget = glade_xml_get_widget(app_xml, "npc_face_frame");
00749 gtk_object_set_user_data(GTK_OBJECT(widget), (gpointer) shape);
00750 char *label = g_strdup_printf("Face #%d", shape);
00751 gtk_frame_set_label(GTK_FRAME(widget), label);
00752 g_free(label);
00753 show_npc_face();
00754 }
00755
00756
00757
00758
00759
00760 void ExultStudio::schedule_btn_clicked
00761 (
00762 GtkWidget *btn,
00763 gpointer data
00764 )
00765 {
00766 ExultStudio *studio = ExultStudio::get_instance();
00767
00768 const char *name = glade_get_widget_name(btn);
00769 const char *numptr = name + 5;
00770 int num = atoi(numptr);
00771 GtkWidget *schedwin = (GtkWidget *) data;
00772 GtkLabel *label = (GtkLabel *) gtk_object_get_user_data(
00773 GTK_OBJECT(schedwin));
00774
00775 gtk_object_set_user_data(GTK_OBJECT(label), (gpointer) num);
00776 gtk_label_set_text(label, num >= 0 && num < 32
00777 ? sched_names[num] : "-----");
00778 cout << "Chose schedule " << num << endl;
00779 gtk_widget_hide(glade_xml_get_widget(studio->get_xml(),
00780 "schedule_dialog"));
00781 }
00782
00783
00784
00785
00786
00787 static void Set_sched_btn
00788 (
00789 GtkWidget *btn,
00790 gpointer data
00791 )
00792 {
00793 gtk_signal_connect(GTK_OBJECT(btn), "clicked",
00794 GTK_SIGNAL_FUNC(ExultStudio::schedule_btn_clicked), data);
00795 }
00796
00797
00798
00799
00800 C_EXPORT void on_npc_set_sched
00801 (
00802 GtkWidget *btn,
00803 gpointer user_data
00804 )
00805 {
00806 static int first = 1;
00807 const char *name = glade_get_widget_name(btn);
00808 const char *numptr = name + strlen(name) - 1;
00809 GladeXML *xml = ExultStudio::get_instance()->get_xml();
00810 char lname[20];
00811 strcpy(lname, "npc_sched");
00812 strcat(lname, numptr);
00813 GtkLabel *label = GTK_LABEL(glade_xml_get_widget(xml, lname));
00814 GtkContainer *btns = GTK_CONTAINER(
00815 glade_xml_get_widget(xml, "sched_btns"));
00816 GtkWidget *schedwin = glade_xml_get_widget(xml, "schedule_dialog");
00817 if (!label || !btns || !schedwin)
00818 return;
00819 if (first)
00820 {
00821 first = 0;
00822 gtk_container_foreach(btns, Set_sched_btn, schedwin);
00823 }
00824
00825 gtk_object_set_user_data(GTK_OBJECT(schedwin), label);
00826 gtk_widget_show(schedwin);
00827 }
00828
00829
00830
00831
00832 static void Game_loc_response
00833 (
00834 Exult_server::Msg_type id,
00835 unsigned char *data,
00836 int datalen,
00837 void *client
00838 )
00839 {
00840 if (id != Exult_server::game_pos)
00841 return;
00842
00843 GtkBox *box = (GtkBox *) client;
00844 int tx = Read2(data);
00845 int ty = Read2(data);
00846 int tz = Read2(data);
00847 if (tz != 0)
00848 {
00849 EStudio::Alert("Non-zero height (%d) not yet supported", tz);
00850 return;
00851 }
00852 GList *list = g_list_first(box->children);
00853 GtkWidget *spin = ((GtkBoxChild *) list->data)->widget;
00854 gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin), tx);
00855 list = g_list_next(list);
00856 spin = ((GtkBoxChild *) list->data)->widget;
00857 gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin), ty);
00858 list = g_list_next(list);
00859 spin = ((GtkBoxChild *) list->data)->widget;
00860 gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin), tz);
00861 }
00862
00863
00864
00865
00866
00867 C_EXPORT void on_sched_loc_clicked
00868 (
00869 GtkWidget *btn,
00870 gpointer user_data
00871 )
00872 {
00873 ExultStudio *studio = ExultStudio::get_instance();
00874
00875 GtkBox *box = GTK_BOX(gtk_widget_get_parent(btn));
00876 if (Send_data(studio->get_server_socket(),
00877 Exult_server::game_pos) == -1)
00878 cout << "Error sending message to server" << endl;
00879 else
00880 studio->set_msg_callback(Game_loc_response, box);
00881 }