source: golgotha/src/golg/editor/mode/e_object.cc @ 80

Last change on this file since 80 was 80, checked in by Sam Hocevar, 14 years ago
  • Adding the Golgotha source code. Not sure what's going to be interesting in there, but since it's all public domain, there's certainly stuff to pick up.
File size: 25.3 KB
Line 
1/********************************************************************** <BR>
2  This file is part of Crack dot Com's free source code release of
3  Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
4  information about compiling & licensing issues visit this URL</a>
5  <PRE> If that doesn't help, contact Jonathan Clark at
6  golgotha_source@usa.net (Subject should have "GOLG" in it)
7***********************************************************************/
8
9#include "editor/mode/e_object.hh"
10#include "editor/e_state.hh"
11#include "error/error.hh"
12#include "g1_object.hh"
13#include "editor/contedit.hh"
14#include "device/keys.hh"
15#include "image/color.hh"
16#include "image/image.hh"
17#include "g1_limits.hh"
18#include "editor/dialogs/d_light.hh"
19#include "math/pi.hh"
20#include "m_flow.hh"
21#include "g1_render.hh"
22#include "r1_clip.hh"
23#include "objs/light_o.hh"
24#include "editor/editor.hh"
25#include "gui/butbox.hh"
26#include "player.hh"
27#include "objs/def_object.hh"
28#include "lisp/li_class.hh"
29#include "editor/e_res.hh"
30#include "editor/dialogs/object_picker.hh"
31#include "lisp/li_dialog.hh"
32#include "li_objref.hh"
33#include "lisp/li_init.hh"
34#include "remove_man.hh"
35#include "objs/path_object.hh"
36#include "objs/bases.hh"
37#include "tick_count.hh"
38
39static g1_typed_reference_class<g1_object_class> preselected_object;
40static li_symbol *g1_last_link_var=0;
41static g1_typed_reference_class<g1_object_class> editing_object;
42static li_symbol_ref path_object_type("path_object");
43
44g1_object_params g1_e_object;
45
46
47li_object *g1_object_changed(li_object *o, li_environment *env)
48{
49  if (editing_object.get())
50  {
51    if (o)
52    {
53      editing_object->vars=li_class::get(li_car(o,env),env);
54
55               
56      g1_object_class *list[G1_MAX_OBJECTS];
57      int t=g1_get_map()->make_object_list(list, G1_MAX_OBJECTS);
58      li_class *old=li_class::get(li_second(o,env),env);
59      for (int i=0; i<t; i++)
60        list[i]->object_changed_by_editor(editing_object.get(), old);
61
62    }
63
64    g1_e_object.close_edit_window();
65  }
66
67  return 0;
68}
69
70li_automatic_add_function(g1_object_changed, "object_changed");
71
72
73
74g1_mode_handler::state g1_object_mode::current_state()
75{
76  w8 remap[]={ ROTATE,
77               ZOOM,
78               OTHER,
79               DRAG_SELECT,
80               DRAG_SELECT,
81               DRAG_SELECT };
82
83  I4_ASSERT(g1_e_object.minor_mode<=sizeof(remap), "state too big");
84  return (g1_mode_handler::state)remap[g1_e_object.get_minor_mode()];
85}
86
87
88void g1_object_mode::hide_focus()
89{
90  if (add.get())
91  {
92    add->unoccupy_location();
93    add->request_remove();
94    g1_remove_man.process_requests();
95    add=0;
96  }
97}
98
99
100     
101
102void g1_object_mode::show_focus()
103{
104  if (!add.get() && g1_e_object.get_minor_mode()==g1_object_params::ADD)
105  {
106    w32 type=g1_e_object.get_object_type();
107    if (g1_object_type_array[type])
108    {
109      add=g1_create_object(type);
110
111
112      if (add.get())
113      {
114
115        add->player_num=g1_edit_state.current_team;
116
117        i4_float gx,gy, dx,dy;
118        if (!c->view_to_game(lx(),ly(), gx,gy, dx,dy))
119        { gx=2; gy=2; }
120   
121        if (gx<0 || gy<0 ||  gx>=c->get_map()->width() || gy>=c->get_map()->height())
122        { gx=2; gy=2; }
123
124        i4_3d_point_class pos(gx,gy,c->get_map()->terrain_height(gx,gy));
125        g1_edit_state.snap_point(pos);
126
127        add->x=pos.x;
128        add->y=pos.y;
129        add->h=pos.z;
130        add->grab_old();
131
132        if (add->id==g1_get_object_type("lightbulb"))
133        {
134          add->h+=2;
135          g1_light_object_class *l=g1_light_object_class::cast(add.get());
136          l->setup(add->x, add->y, add->h, 1,1,1,1);
137        }
138
139        add->player_num=g1_edit_state.current_team;
140
141        add->grab_old();
142
143        if (!add->occupy_location())
144        {
145          g1_remove_man.process_requests();       
146          add=0;
147        }
148        else
149        {
150
151          g1_object_class *list[G1_MAX_OBJECTS];
152          int t=g1_get_map()->make_object_list(list, G1_MAX_OBJECTS);
153
154          // if we are creating a path-object, and a path object was previously selected, form a
155          // link between the two
156          g1_path_object_class *po=g1_path_object_class::cast(add.get()), *p2;
157          if (po)
158          {
159
160            for (int i=0; i<t; i++)
161            {
162              if (list[i]->get_flag(g1_object_class::SELECTED))
163              {
164                p2=g1_path_object_class::cast(list[i]);
165                if (p2)
166                {
167                  p2->add_link(G1_ALLY, po);
168                  po->add_link(G1_ENEMY, p2);
169                }
170                else
171                {
172                  po->add_controlled_object(list[i]);
173                  for (g1_factory_class *f=g1_factory_list.first(); f; f=f->next)
174                  {
175                    if (f==list[i])
176                      f->set_start(po);
177                  }
178                }
179              }
180            }
181          } else
182          {
183            // see if a path object was previously selected, if so add ourself to it's
184            // controlled-object list
185
186            for (int i=0; i<t; i++)
187            {
188              if (list[i]->get_flag(g1_object_class::SELECTED))
189              {
190                po=g1_path_object_class::cast(list[i]);
191                if (po)
192                {
193                  po->add_controlled_object(add.get());
194                  for (g1_factory_class *f=g1_factory_list.first(); f; f=f->next)
195                  {
196                    if (f==add.get())
197                      f->set_start(po);
198                  }
199                }
200              }
201            }
202          }
203
204          add->grab_old();         
205        }
206
207        c->refresh();
208      }
209    }
210  }
211}
212
213void g1_object_mode::mouse_down()
214{
215  if (add.get())
216  {
217    hide_focus();
218    g1_editor_instance.add_undo(G1_MAP_OBJECTS);
219    show_focus();
220
221    g1_object_class *list[G1_MAX_OBJECTS];
222    int t=g1_get_map()->make_object_list(list, G1_MAX_OBJECTS);           
223    for (int i=0; i<t; i++)
224      list[i]->set_flag(g1_object_class::SELECTED, 0);   
225    add->set_flag(g1_object_class::SELECTED, 1);
226
227
228
229
230    add->request_think();
231    g1_player_man.get(add->player_num)->add_object(add->global_id);
232    add=0;
233    show_focus();
234  }
235
236  g1_mode_handler::mouse_down();
237}
238
239
240
241void g1_object_mode::mouse_move(sw32 mx, sw32 my)
242{
243  if (!add.get())
244    show_focus();
245
246  if (add.get())
247  {
248    i4_float gx,gy, dx,dy;
249    if (c->view_to_game(mx,my, gx,gy, dx,dy) &&
250        (!(gx<0 || gy<0 ||  gx>=c->get_map()->width() || gy>=c->get_map()->height())))
251    {     
252
253      i4_3d_point_class pos(gx,gy, c->get_map()->terrain_height(gx,gy));
254      g1_edit_state.snap_point(pos);
255
256      if (pos.x!=add->x || pos.y!=add->y || pos.z!=add->h)
257      {
258        add->unoccupy_location();
259        add->player_num=g1_edit_state.current_team;
260   
261        add->x=pos.x;
262        add->y=pos.y;
263        add->h=pos.z;
264        add->grab_old();
265     
266        if (!add->occupy_location())
267        {
268          g1_remove_man.process_requests();       
269          add=0;
270        }
271     
272        c->refresh();
273      }
274    }
275  }
276
277  g1_mode_handler::mouse_move(mx,my);
278}
279
280static li_symbol_ref s_add_link("add_link"), s_remove_link("remove_link");
281
282li_object *g1_add_link(li_object *o, li_environment *env)
283{
284  if (preselected_object.get())
285  {
286    li_call("redraw");
287    li_call("add_undo", li_make_list(new li_int(G1_MAP_OBJECTS)));
288
289    g1_object_class *olist[G1_MAX_OBJECTS];
290    int t = g1_get_map()->make_object_list(olist, G1_MAX_OBJECTS);   
291    li_g1_ref *who=new li_g1_ref(preselected_object.get()->global_id);   
292    for (int i=0; i<t; i++)
293      if (olist[i]->selected())
294        olist[i]->message(s_add_link.get(), who, 0);
295  }
296 
297  return 0;
298}
299li_automatic_add_function(g1_add_link, "add_link");
300
301
302li_object *g1_remove_link(li_object *o, li_environment *env)
303{
304  if (preselected_object.get())
305  {
306    li_call("redraw");
307    li_call("add_undo", li_make_list(new li_int(G1_MAP_OBJECTS)));
308     
309    g1_object_class *olist[G1_MAX_OBJECTS];
310    int t = g1_get_map()->make_object_list(olist, G1_MAX_OBJECTS);   
311    li_g1_ref *who=new li_g1_ref(preselected_object.get()->global_id);   
312    for (int i=0; i<t; i++)
313      if (olist[i]->selected())
314        olist[i]->message(s_remove_link.get(), who, 0);
315  }
316 
317  return 0;
318}
319li_automatic_add_function(g1_remove_link, "remove_link");
320
321
322li_object *g1_fix_forward_link(li_object *o, li_environment *env)
323{
324  if (preselected_object.get())
325  {
326    li_call("redraw");
327    li_call("add_undo", li_make_list(new li_int(G1_MAP_OBJECTS)));
328
329    g1_object_class *olist[G1_MAX_OBJECTS];
330    int t = g1_get_map()->make_object_list(olist, G1_MAX_OBJECTS);   
331    for (int i=0; i<t; i++)
332      if (olist[i]->selected())
333      {
334        g1_map_piece_class *mp = g1_map_piece_class::cast(olist[i]);
335        if (mp)
336          mp->fix_forward_link(preselected_object.get());
337      }
338  }
339 
340  return 0;
341}
342li_automatic_add_function(g1_fix_forward_link, "fix_forward_link");
343
344
345li_object *g1_fix_previous_link(li_object *o, li_environment *env)
346{
347  if (preselected_object.get())
348  {
349    li_call("redraw");
350    li_call("add_undo", li_make_list(new li_int(G1_MAP_OBJECTS)));
351
352    g1_object_class *olist[G1_MAX_OBJECTS];
353    int t = g1_get_map()->make_object_list(olist, G1_MAX_OBJECTS);   
354    for (int i=0; i<t; i++)
355      if (olist[i]->selected())
356      {
357        g1_map_piece_class *mp = g1_map_piece_class::cast(olist[i]);
358        if (mp)
359          mp->fix_previous_link(preselected_object.get());
360      }
361  }
362 
363  return 0;
364}
365li_automatic_add_function(g1_fix_previous_link, "fix_previous_link");
366
367
368li_object *g1_fix_path_link(li_object *o, li_environment *env)
369{
370  g1_path_object_class *p2 = g1_path_object_class::cast(preselected_object.get());
371  g1_map_piece_class *mp = 0;
372  g1_path_object_class *p1 = 0;
373
374  if (p2)
375  {
376    g1_object_class *olist[G1_MAX_OBJECTS];
377    int t = g1_get_map()->make_object_list(olist, G1_MAX_OBJECTS);
378
379    for (int i=0; i<t; i++)
380      if (olist[i]->selected())
381      {
382        g1_map_piece_class *_mp = g1_map_piece_class::cast(olist[i]);
383        g1_path_object_class *_p1 = g1_path_object_class::cast(olist[i]);
384        if (_mp)
385          mp = _mp;
386        if (_p1)
387          p1 = _p1;
388      }
389
390    if (p1 && mp)
391    {
392      int index = p1->get_path_index(p2);
393
394      if (index>=0)
395        p1->link[index].object = mp;
396    }
397  }
398 
399  return 0;
400}
401li_automatic_add_function(g1_fix_path_link, "fix_path_link");
402
403
404li_object *g1_fix_tick_count(li_object *o, li_environment *env)
405{
406  if (o)
407  {
408    w32 new_tick = li_get_int(li_eval(li_car(o,env), env),env);
409    g1_tick_counter = new_tick;
410  }
411 
412  return 0;
413}
414li_automatic_add_function(g1_fix_tick_count, "fix_tick_count");
415
416
417void g1_object_mode::key_press(i4_key_press_event_class *kev)
418{
419  int i,t;
420  g1_object_class *olist[G1_MAX_OBJECTS];
421 
422  switch (kev->key)
423  {
424    case 'A' :
425    {
426      hide_focus();
427      t = c->get_map()->make_object_list(olist, G1_MAX_OBJECTS);
428      for (i=0; i<t; i++) 
429        olist[i]->flags |= g1_object_class::SELECTED;     
430      show_focus();
431      c->refresh();
432      break;
433    }
434
435    case '[' :
436    {
437      if (g1_e_object.get_object_type()>0)
438      {
439        int find=-1;
440        for (int j=g1_e_object.get_object_type()-1;
441             find==-1 && j>0;
442             j--)
443        {
444          if (g1_object_type_array[j] && g1_object_type_array[j]->editor_selectable())
445            find=j;
446        }
447
448        if (find)
449        {
450          hide_focus();       
451          g1_e_object.set_object_type(find);
452          show_focus();
453        }
454
455      } break;
456    } break;
457
458    case ']' :
459    {     
460      if (g1_e_object.get_object_type()<=g1_last_object_type)
461      {
462        int find=-1;
463        for (int j=g1_e_object.get_object_type()+1;
464             find==-1 && j<=g1_last_object_type;
465             j++)
466        {
467          if (g1_object_type_array[j] && g1_object_type_array[j]->editor_selectable())
468            find=j;
469        }
470         
471       
472        if (find)
473        {
474          hide_focus();
475          g1_e_object.set_object_type(find);
476          show_focus();
477        }
478
479      } break;
480    } break;
481
482
483 
484  }
485  g1_mode_handler::key_press(kev);
486}
487
488void g1_object_mode::delete_selected()
489{
490  g1_object_class *olist[G1_MAX_OBJECTS];
491  sw32 t=c->get_map()->make_object_list(olist, G1_MAX_OBJECTS);
492  for (int i=0; i<t; i++)
493    if (olist[i]->selected())
494    {
495      olist[i]->unoccupy_location();
496      olist[i]->request_remove();
497      g1_remove_man.process_requests();
498    }
499
500  c->refresh();
501}
502
503float g1_object_mode::get_snap_theta()
504{
505  return real_object_theta-fmod(real_object_theta, i4_pi()/2.0);
506}
507
508void g1_object_mode::move_selected(i4_float xc, i4_float yc, i4_float zc,
509                                   sw32 mouse_x, sw32 mouse_y)
510{
511  if (!no_more_move_undos)
512  {
513    g1_editor_instance.add_undo(G1_MAP_OBJECTS);
514    no_more_move_undos=i4_T;
515  }
516
517
518
519  g1_object_class *olist[G1_MAX_OBJECTS];
520  sw32 t=c->get_map()->make_object_list(olist, G1_MAX_OBJECTS);
521
522
523  for (int i=0; i<t; i++)
524    if (olist[i]->flags&g1_object_class::SELECTED)
525    {
526      olist[i]->unoccupy_location();
527
528      switch (g1_e_object.get_minor_mode())
529      {
530        case g1_object_params::MOVE :
531        {
532          g1_object_class *o=olist[i];
533          o->x+=xc;
534          o->y+=yc;
535          o->h+=zc;
536
537
538        } break;
539
540        case g1_object_params::OBJECT_ROTATE :
541        {
542          real_object_theta += mouse_y/300.0 * 2*3.14;
543
544          if (g1_edit_state.snap==g1_edit_state_class::SNAP_CENTER ||
545              g1_edit_state.snap==g1_edit_state_class::SNAP_ORIGIN)
546            olist[i]->theta = get_snap_theta();
547          else
548            olist[i]->theta = real_object_theta;
549
550        }
551        break;
552
553      }
554
555      olist[i]->grab_old();
556      olist[i]->occupy_location();
557    }
558 
559  c->changed();
560  c->refresh();
561}
562
563i4_bool g1_object_mode::select_object(sw32 mx, sw32 my,
564                                      i4_float &ox, i4_float &oy, i4_float &oz,
565                                      select_modifier mod)
566{
567  no_more_move_undos=i4_F;
568
569  if (mod!=FOR_CURSOR_HINT)
570    g1_editor_instance.add_undo(G1_MAP_OBJECTS);
571
572  g1_object_class *olist[G1_MAX_OBJECTS];
573  sw32 t=c->get_map()->make_object_list(olist, G1_MAX_OBJECTS);
574  int i;
575  i4_bool ret=i4_F;
576  i4_bool change=i4_F;
577
578  preselected_object=0;
579  if (!c->g1_context.transform)
580    return i4_F;
581 
582  int set_team=-1;
583
584  for (i=0; i<t && !ret; i++)
585  {
586    r1_vert rv;
587    if (g1_render.project_point(i4_3d_point_class(olist[i]->x, olist[i]->y, olist[i]->h),
588                         rv, c->g1_context.transform))
589      if (abs((sw32)rv.px-mx)<3 && abs((sw32)rv.py-my)<3)
590      {
591        ox=olist[i]->x;
592        oy=olist[i]->y;
593        oz=olist[i]->h;
594        real_object_theta=olist[i]->theta;
595
596        if ((olist[i]->flags & g1_object_class::SELECTED)==0 &&
597            mod==CLEAR_OLD_IF_NO_SELECTION)
598        {
599          for (int j=0; j<t; j++)
600            olist[j]->flags &= ~g1_object_class::SELECTED;
601          change=i4_T;
602        }
603
604
605        if (mod==CLEAR_OLD_IF_NO_SELECTION || mod==ADD_TO_OLD)
606        {
607          olist[i]->flags |= g1_object_class::SELECTED;
608          change=i4_T;
609
610          set_team=olist[i]->player_num;
611         
612        }
613        else if (mod==SUB_FROM_OLD)
614        {
615          olist[i]->flags &= ~g1_object_class::SELECTED;       
616          change=i4_T;
617        }
618        else if (mod==FOR_CURSOR_HINT)
619          preselected_object=olist[i];
620
621        ret=i4_T;       
622      }
623  }
624
625  if (set_team!=-1)
626    g1_edit_state.set_current_team(set_team);
627
628
629  if (change)
630  {
631    c->changed();
632    c->refresh();
633  }
634
635
636  return ret;
637}
638
639void g1_object_mode::select_objects_in_area(sw32 x1, sw32 y1, sw32 x2, sw32 y2,
640                                            select_modifier mod)
641{
642  no_more_move_undos=i4_F;
643
644  g1_editor_instance.add_undo(G1_MAP_OBJECTS);
645
646  g1_object_class *olist[G1_MAX_OBJECTS];
647  sw32 t=c->get_map()->make_object_list(olist, G1_MAX_OBJECTS);
648 
649  for (int i=0; i<t; i++)
650  {
651    r1_vert rv;
652    if (g1_render.project_point(i4_3d_point_class(olist[i]->x,
653                                           olist[i]->y,
654                                           olist[i]->h), rv, c->g1_context.transform))
655    {
656      if (rv.px>=x1 && rv.px<=x2 && rv.py>=y1 && rv.py<=y2)
657      {
658        if (mod==SUB_FROM_OLD)
659          olist[i]->flags&=~g1_object_class::SELECTED;
660        else
661          olist[i]->flags|=g1_object_class::SELECTED;       
662      }
663      else if (mod==CLEAR_OLD_IF_NO_SELECTION)
664        olist[i]->flags&=~g1_object_class::SELECTED;
665    }
666  }
667
668  c->changed();
669  c->refresh();
670}
671
672li_symbol_ref dbug_objs("dbug_objects");
673
674void g1_object_mode::post_draw(i4_draw_context_class &context)
675{
676  g1_object_class *olist[G1_MAX_OBJECTS];
677  sw32 t=c->get_map()->make_object_list(olist, G1_MAX_OBJECTS);
678  int w=1;
679  for (int i=0; i<t; i++)
680  {
681    r1_vert rv;
682    i4_3d_point_class v(olist[i]->x, olist[i]->y, olist[i]->h);
683    if (g1_render.project_point(v, rv, c->g1_context.transform))
684    {
685      w32 color=norm_color;
686
687      li_object *dbug=li_get_value(dbug_objs.get());
688      for (;dbug; dbug=li_cdr(dbug,0))
689        if (li_get_int(li_car(dbug,0),0)==olist[i]->global_id)
690          color=0xff0000;
691
692
693      if (olist[i]->flags & g1_object_class::SELECTED)
694      {
695        color=sel_color;
696        i4_3d_point_class floor(v.x, v.y, c->get_map()->terrain_height(v.x,v.y));
697        g1_render.render_3d_line(v,floor,sel_color,norm_color,c->g1_context.transform);
698      }
699 
700      r1_clip_clear_area((sw32)rv.px-w, (sw32)rv.py-w, (sw32)rv.px+w, (sw32)rv.py+w,
701                         color, 0.01, *c->g1_context.context, g1_render.r_api);
702
703
704    }
705  }
706
707  g1_mode_handler::post_draw(context);
708}
709
710g1_object_mode::g1_object_mode(g1_controller_edit_class *c) : g1_mode_handler(c) 
711{
712  add=0;
713  sel_color=0xffff00;
714  norm_color=0x7f7f7f;
715  no_more_move_undos=i4_F;
716}
717
718void g1_object_mode::edit_selected()
719{
720  g1_object_class *olist[G1_MAX_OBJECTS], *first=0;
721  sw32 t=c->get_map()->make_object_list(olist, G1_MAX_OBJECTS), tsel=0;
722 
723  g1_e_object.close_edit_window();
724
725 
726  for (int i=0; i<t; i++)
727  {
728    if (olist[i]->selected())
729    {
730      editing_object=olist[i];
731      tsel++;
732    }       
733  }
734
735  if (tsel==1)   
736  {
737    i4_window_class *w=g1_object_type_array[editing_object->id]->create_edit_dialog();
738    if (w)
739      g1_e_object.set_edit_window(w);
740  }
741  else
742    editing_object=0;
743}
744
745void g1_object_mode::idle()
746{
747  g1_object_class *olist[G1_MAX_OBJECTS];
748  sw32 t=c->get_map()->make_object_list(olist, G1_MAX_OBJECTS);
749  int closest=-1, closest_d=10000;
750
751  for (int i=0; i<t; i++)
752  {
753    r1_vert rv;
754    if (g1_render.project_point(i4_3d_point_class(olist[i]->x, olist[i]->y, olist[i]->h),
755                         rv, c->g1_context.transform))
756      if (abs((sw32)rv.px-lx())<8 && abs((sw32)rv.py-ly())<8)
757      {
758        int d=abs((sw32)rv.px-lx()) + abs((sw32)rv.py-ly());
759        if (d<closest_d)
760        {
761          closest=i;
762          closest_d=d;
763        }
764      }
765  }
766
767  if (closest!=-1)
768  {
769    i4_str *help=olist[closest]->get_context_string();
770
771    i4_str *h2=i4_const_str("gid=%d %S").sprintf(200,olist[closest]->global_id, help);
772    g1_edit_state.context_help.show(*h2, x()+lx(), y()+ly());
773
774    if (help)
775      delete help;
776    delete h2;
777
778  }
779}
780
781
782
783void g1_object_params::create_buttons(i4_parent_window_class *containter)
784{
785  i4_button_box_class *box=new i4_button_box_class(&g1_edit_state);
786  char *rn[]={"oROTATE", "oZOOM", "oADD", "oSELECT", "oMOVE", "oOBJECT_ROTATE", 0 };
787  w32 i=ROTATE;
788  for (char **a=rn; *a; a++, i++)
789    g1_edit_state.add_but(box, *a, 0, (i4_bool) i==minor_mode,
790                          new g1_set_minor_mode_event("OBJECT",i));
791
792  box->arrange_right_down();
793  containter->add_child(0,0, box);
794}
795
796
797void g1_object_params::cleanup()
798{
799  if (edit_win.get())
800  {
801    get_style()->close_mp_window(edit_win.get());
802    edit_win=0;
803  }
804
805  if (g1_object_picker_mp.get())
806  {
807    get_style()->close_mp_window(g1_object_picker_mp.get());
808    g1_object_picker_mp=0;
809  }
810
811}
812
813
814void g1_object_params::close_edit_window()
815{
816  if (edit_win.get())
817  {
818    get_style()->close_mp_window(edit_win.get());
819    edit_win=0;
820  }
821}
822
823void g1_object_params::set_edit_window(i4_window_class *p)
824{
825  close_edit_window();
826  edit_win=get_style()->create_mp_window(0,0,
827                                   p->width(), p->height(),
828                                   g1_ges("edit_object"), 0);
829  edit_win->add_child(0,0,p);
830}
831
832
833g1_object_params::g1_object_params()
834{
835  minor_mode=MOVE;
836
837  current_object_type=0;
838  edit_win=0;
839
840}
841
842g1_mode_handler *g1_object_params::create_mode_handler(g1_controller_edit_class *c)
843
844  return new g1_object_mode(c);
845}
846
847
848
849li_object *g1_join_objects(li_object *o, li_environment *env)
850{
851  li_call("add_undo", li_make_list(new li_int(G1_MAP_OBJECTS)));
852
853  g1_object_class *olist[G1_MAX_OBJECTS];
854  int t = g1_get_map()->make_object_list(olist, G1_MAX_OBJECTS),i,j;
855
856  for (i=0; i<t; i++)
857  {
858    if (olist[i]->get_flag(g1_object_class::SELECTED))
859    {
860      g1_path_object_class *p=g1_path_object_class::cast(olist[i]);
861      if (p)
862      {
863        for (j=0; j<t; j++)
864        {
865          if (j!=i && olist[j]->get_flag(g1_object_class::SELECTED))
866          {
867            g1_path_object_class *p2=g1_path_object_class::cast(olist[j]);
868
869            if (!p2)
870            {
871              p->add_controlled_object(olist[j]);
872             
873              for (g1_factory_class *f=g1_factory_list.first(); f; f=f->next)
874              {
875                if (f==olist[j])
876                  f->set_start(p);
877              }
878            }
879            else
880            {
881              // join to path objects if we can determine the direction
882              if ((p->total_links(G1_ENEMY)>0 || p->total_links(G1_ALLY)>0) &&
883                  p->total_links(G1_ALLY)==0 &&
884                  p2->total_links(G1_ENEMY)==0 &&
885                  p->get_path_index(p2)<0)
886              {
887                p->add_link(G1_ALLY, p2);
888                p2->add_link(G1_ENEMY, p);
889              }
890            }
891          }
892        }         
893      }
894
895    }
896  }
897
898  return 0;
899}
900
901
902li_object *g1_insert_path_object(li_object *o, li_environment *env)
903{
904  li_call("add_undo", li_make_list(new li_int(G1_MAP_OBJECTS)));
905
906  g1_object_class *olist[G1_MAX_OBJECTS];
907  int t = g1_get_map()->make_object_list(olist, G1_MAX_OBJECTS),i,j;
908  g1_path_object_class *p1=0, *p2=0;
909
910  for (i=0; i<t; i++)
911  {
912    if (olist[i]->get_flag(g1_object_class::SELECTED))
913    {
914      if (!p1)
915        p1=g1_path_object_class::cast(olist[i]);
916      else if (!p2)
917        p2=g1_path_object_class::cast(olist[i]);
918      else
919        return 0;
920    }
921  }
922
923  if (p1 && p2)
924  {
925    // determine if we should swap the two
926    int t=p1->total_links(G1_ENEMY), swap=0;
927    for (i=0; i<t; i++)
928      if (p1->get_link(G1_ENEMY,i)==p2)
929        swap=1;
930
931    if (swap)
932    {
933      g1_path_object_class *t=p1;
934      p1=p2;
935      p2=p1;
936    }
937
938    g1_path_object_class *newp;
939    newp=(g1_path_object_class *)g1_create_object(g1_get_object_type(path_object_type.get()));
940    if (newp)
941
942
943    if (!p1->remove_link(G1_ALLY, p2) ||
944        !p2->remove_link(G1_ENEMY, p1))
945      return 0;
946     
947
948    p1->add_link(G1_ALLY, newp);
949    p2->add_link(G1_ENEMY, newp);
950    newp->add_link(G1_ENEMY, p1);
951    newp->add_link(G1_ALLY, p2);
952
953    newp->x=(p1->x + p2->x)/2.0;
954    newp->y=(p1->y + p2->y)/2.0;
955    newp->h=(p1->h + p2->h)/2.0;
956    newp->grab_old();
957
958    g1_player_man.get(newp->player_num)->add_object(newp->global_id);
959    newp->occupy_location();
960   
961  }
962
963  return 0;
964}
965
966//li_automatic_add_function(g1_unjoin_objects, "join_path_ends");
967li_automatic_add_function(g1_join_objects, "join_path_ends");
968li_automatic_add_function(g1_insert_path_object, "insert_path_object");
969
970
971static float move_v=0;
972static void move_objs()
973{
974  g1_object_class *olist[G1_MAX_OBJECTS];
975  int t = g1_get_map()->make_object_list(olist, G1_MAX_OBJECTS);
976  for (int i=0; i<t; i++)
977  {
978    if (olist[i]->get_flag(g1_object_class::SELECTED))
979    {
980      olist[i]->unoccupy_location();
981      olist[i]->h+=move_v;
982      olist[i]->grab_old();
983      olist[i]->occupy_location();
984    }
985  }
986  li_call("redraw");
987}
988
989
990
991li_object *g1_move_object_up_start(li_object *o, li_environment *env)
992{
993  move_v+=0.05;
994  move_objs();
995  return 0;
996}
997
998li_object *g1_move_object_up_end(li_object *o, li_environment *env)
999{
1000  move_v=0;
1001  return 0;
1002}
1003
1004
1005li_object *g1_move_object_down_start(li_object *o, li_environment *env)
1006{
1007  move_v-=0.05;
1008  move_objs();
1009  return 0;
1010}
1011
1012li_object *g1_move_object_down_end(li_object *o, li_environment *env)
1013{
1014  move_v=0;
1015  return 0;
1016}
1017
1018
1019li_automatic_add_function(g1_move_object_up_start, "move_selected_up");
1020li_automatic_add_function(g1_move_object_up_end, "-move_selected_up");
1021li_automatic_add_function(g1_move_object_down_start, "move_selected_down");
1022li_automatic_add_function(g1_move_object_down_end, "-move_selected_down");
1023
Note: See TracBrowser for help on using the repository browser.