123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502 |
- /********************************************************************** <BR>
- This file is part of Crack dot Com's free source code release of
- Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
- information about compiling & licensing issues visit this URL</a>
- <PRE> If that doesn't help, contact Jonathan Clark at
- golgotha_source@usa.net (Subject should have "GOLG" in it)
- ***********************************************************************/
- #include "lisp/lisp.hh"
- #include "objs/miscobjs.hh"
- #include "g1_object.hh"
- #include "lisp/li_class.hh"
- #include "objs/model_id.hh"
- #include "saver.hh"
- #include "objs/model_draw.hh"
- #include "objs/def_object.hh"
- #include "li_objref.hh"
- #include "lisp/li_vect.hh"
- #include "lisp/li_dialog.hh"
- #include "map_man.hh"
- #include "map.hh"
- static li_symbol *s_model_name=0, *s_mini_object=0,
- *s_offset=0, *s_position=0, *s_rotation=0,
- *s_object_flags=0, *s_type_flags=0;
- static li_symbol *s_ofun[G1_F_TOTAL];
- //////////////////// li_def_object setup code ///////////////////////////////////////
- // these flag value are assigned ot their symbol names for easy ussage in script files
- static w32 g1_oflag_values[]={g1_object_class::THINKING,
- g1_object_class::SELECTABLE,
- g1_object_class::TARGETABLE,
- g1_object_class::GROUND,
- g1_object_class::UNDERWATER,
- g1_object_class::AERIAL,
- g1_object_class::HIT_GROUND,
- g1_object_class::HIT_UNDERWATER,
- g1_object_class::HIT_AERIAL,
- g1_object_class::BLOCKING,
- g1_object_class::DANGEROUS,
- g1_object_class::CAN_DRIVE_ON
- };
- static char *g1_oflag_names[]={"thinking",
- "selectable",
- "targetable",
- "ground",
- "underwater",
- "aerial",
- "hit_ground",
- "hit_underwater",
- "hit_aerial",
- "blocking",
- "dangerous",
- "can_drive_on",
- 0};
- static char *g1_ofun_names[G1_F_TOTAL]={"think",
- "damage",
- "notify_damage",
- "enter_range",
- "draw",
- "message",
- "deploy_to",
- "change_player_num",
- "occupy_location",
- "unoccupy_location"};
- li_object *li_def_object(li_object *o, li_environment *env);
- li_object *li_def_buildings(li_object *o, li_environment *env)
- {
- for (; o; o=li_cdr(o,env))
- g1_create_deco_object(li_string::get(li_eval(li_car(o,env), env),env)->value());
- return 0;
- }
- class g1_create_object_init : public i4_init_class
- {
- public:
- void init()
- {
- int i=0;
- for (char **a=g1_oflag_names; *a; a++)
- li_set_value(*a, new li_int(g1_oflag_values[i++]));
- for (i=0; i<G1_F_TOTAL; i++)
- s_ofun[i]=li_get_symbol(g1_ofun_names[i]);
-
- li_set_value("editor_selectable", new li_int(g1_object_definition_class::EDITOR_SELECTABLE));
- li_set_value("movable", new li_int(g1_object_definition_class::MOVABLE));
- li_add_function("def_object", li_def_object);
- li_add_function("def_buildings", li_def_buildings);
- }
- } g1_create_object_init_instance;
- struct g1_object_def_struct
- {
- char *name;
- char *model_name;
- i4_array<g1_mini_object_def> *minis;
- li_type_number var_class;
- w32 flags;
-
- g1_object_def_struct()
- {
- name=0;
- minis=0;
- var_class=0;
- flags=0;
- }
- } ;
- ///////////////////////////// Dynamic object code ///////////////////////////////
- void g1_mini_object_def::assign_to(g1_mini_object *m)
- {
- m->offset=offset;
- m->x=m->lx=position.x;
- m->y=m->ly=position.y;
- m->h=m->lh=position.z;
- m->rotation=m->lrotation=rotation;
- m->defmodeltype=defmodeltype;
- m->frame=0;
- m->animation=0;
- }
- g1_dynamic_object_type_class::g1_dynamic_object_type_class(li_symbol *sym)
- : g1_object_definition_class(sym->name()->value()),
- minis(0,1)
- {
- obj_flags=g1_object_class::CAN_DRIVE_ON;
- var_class=0;
- flags |= TO_DYNAMIC_OBJECT;
- memset(&funs, 0, sizeof(funs));
- }
- li_object *g1_dynamic_object_class::message(li_symbol *name, li_object *params, li_environment *env)
- {
- g1_dynamic_object_type_class *t=get_type();
- if (t->funs[G1_F_MESSAGE])
- {
- li_class_context context(vars);
- li_g1_ref _me(global_id);
-
- li_list *p=(li_list *)params;
- li_push(p, name);
- li_push(p, &_me);
- return t->funs[G1_F_MESSAGE](p , env);
- }
- return 0;
- }
- g1_draw_context_class *g1_draw_context;
- // called when the object is on a map cell that is drawn
- void g1_dynamic_object_class::draw(g1_draw_context_class *context)
- {
- g1_dynamic_object_type_class *t=get_type();
- if (t->funs[G1_F_DRAW])
- {
- g1_draw_context=context;
- li_class_context context(vars);
- li_g1_ref _me(global_id);
- t->funs[G1_F_DRAW](li_make_list(&_me,0),0);
- }
- else
- {
- g1_model_draw_parameters mp;
- mp.model=get_type()->model;
- g1_model_draw(this, mp, context);
- }
- }
- // void g1_dynamic_object_class::note_enter_range(g1_object_class *who, g1_fire_range_type range)
- // {
- // g1_dynamic_object_type_class *t=get_type();
- // if (t->funs[G1_F_ENTER_RANGE])
- // {
- // li_class_context context(vars);
- // t->funs[G1_F_ENTER_RANGE](li_make_list(new li_g1_ref(global_id),
- // new li_g1_ref(who->global_id),
- // new li_int(range), 0), 0);
- // }
- // }
- void g1_dynamic_object_class::damage(g1_object_class *obj, int hp, i4_3d_vector damage_dir)
- {
- g1_dynamic_object_type_class *t=get_type();
- if (t->funs[G1_F_DAMAGE])
- {
- li_class_context context(vars);
- t->funs[G1_F_DAMAGE](li_make_list(new li_g1_ref(global_id),
- new li_g1_ref(obj->global_id),
- new li_int(hp),
- new li_vect(damage_dir), 0),0);
- }
- else
- request_think();
- }
- void g1_dynamic_object_class::notify_damage(g1_object_class *obj, int hp, w32 notes)
- {
- g1_dynamic_object_type_class *t=get_type();
- if (t->funs[G1_F_NOTIFY_DAMAGE])
- {
- li_class_context context(vars);
- t->funs[G1_F_NOTIFY_DAMAGE](li_make_list(new li_g1_ref(global_id),
- new li_g1_ref(obj->global_id),
- new li_int(hp),
- new li_int(notes), 0),0);
- }
- else
- g1_object_class::notify_damage(obj, hp);
- }
- void g1_dynamic_object_class::think()
- {
- g1_dynamic_object_type_class *t=get_type();
- if (t->funs[G1_F_THINK])
- {
- li_class_context context(vars);
- t->funs[G1_F_THINK](li_make_list(new li_g1_ref(global_id), 0), 0);
- }
- }
- static li_float_class_member dest_x("dest_x"), dest_y("dest_y");
- i4_bool g1_dynamic_object_class::deploy_to(float x, float y)
- {
- g1_dynamic_object_type_class *t=get_type();
- li_class_context context(vars);
- if (t->funs[G1_F_DEPLOY_TO])
- t->funs[G1_F_DEPLOY_TO](li_make_list(new li_g1_ref(global_id),
- new li_float(x),
- new li_float(y),0), 0);
- else
- {
- if (vars && vars->member_offset(dest_x)!=-1)
- {
- dest_x()=x;
- dest_y()=y;
- }
- }
- return 0;
- }
- void g1_dynamic_object_class::change_player_num(int new_player)
- {
- g1_dynamic_object_type_class *t=get_type();
- if (t->funs[G1_F_CHANGE_TEAMS])
- {
- li_class_context context(vars);
- t->funs[G1_F_CHANGE_TEAMS](li_make_list(new li_g1_ref(global_id),
- new li_int(new_player), 0), 0);
- }
- else
- g1_object_class::change_player_num(new_player);
- }
- i4_bool g1_dynamic_object_class::occupy_location()
- {
- g1_dynamic_object_type_class *t=get_type();
- if (t->funs[G1_F_OCCUPY_LOCATION])
- {
- li_class_context context(vars);
- if (t->funs[G1_F_OCCUPY_LOCATION](li_make_list(new li_g1_ref(global_id),0), 0))
- return i4_T;
- else return i4_F;
- }
- else
- return g1_object_class::occupy_location();
- }
- void g1_dynamic_object_class::unoccupy_location()
- {
- g1_dynamic_object_type_class *t=get_type();
- if (t->funs[G1_F_UNOCCUPY_LOCATION])
- {
- li_class_context context(vars);
- t->funs[G1_F_UNOCCUPY_LOCATION](li_make_list(new li_g1_ref(global_id), 0), 0);
- }
- else
- g1_object_class::unoccupy_location();
- }
- g1_dynamic_object_class::g1_dynamic_object_class(g1_object_type type, g1_loader_class *fp)
- : g1_object_class(type, fp)
- {
- g1_dynamic_object_type_class *dtype=get_type();
-
- if (dtype->minis.size())
- {
- allocate_mini_objects(dtype->minis.size(), "");
- for (int i=0; i<dtype->minis.size(); i++)
- dtype->minis[i].assign_to(mini_objects+i);
- }
- if (fp && fp->read_16()==VERSION)
- {
- int old_minis=fp->read_8(), i;
- int old_mini_disk_size=fp->read_32();
-
- if (old_minis==dtype->minis.size())
- {
- g1_mini_object *m=mini_objects;
- for (i=0; i<dtype->minis.size(); i++)
- {
- fp->read_format("fffffffff",
- &m->offset.x, &m->offset.y, &m->offset.z,
- &m->x, &m->y, &m->h,
- &m->rotation.x, &m->rotation.y, &m->rotation.z);
- }
- }
- else
- fp->seek(fp->tell() + old_mini_disk_size);
- }
- flags = get_type()->obj_flags;
- grab_old();
- }
- void g1_dynamic_object_class::save(g1_saver_class *fp)
- {
- g1_object_class::save(fp);
- fp->write_16(VERSION);
- fp->write_8(num_mini_objects);
- int han=fp->mark_size();
- g1_mini_object *m=mini_objects;
- for (int i=0; i<num_mini_objects; i++)
- {
- fp->write_format("fffffffff",
- &m->offset.x, &m->offset.y, &m->offset.z,
- &m->x, &m->y, &m->h,
- &m->rotation.x, &m->rotation.y, &m->rotation.z);
- }
- fp->end_mark_size(han);
- }
- ////////////////// dynamic object type functions ///////////////////////////////
- g1_object_class *g1_dynamic_object_type_class::create_object(g1_object_type type,
- g1_loader_class *fp)
- {
- g1_object_class *o=new g1_dynamic_object_class(type, fp);
- o->init();
- return o;
- }
- static void read_vect(i4_3d_vector &v, li_object *o, li_environment *env)
- {
- v.x=li_get_float(li_eval(li_car(o,env), env),env); o=li_cdr(o,env);
- v.y=li_get_float(li_eval(li_car(o,env), env),env); o=li_cdr(o,env);
- v.z=li_get_float(li_eval(li_car(o,env), env),env);
- }
- static li_function_type get_function(li_object *o, li_environment *env)
- {
- li_object *fun=li_get_fun(li_symbol::get(o,env),env);
- if (!fun)
- li_error(env, "no registered function %O", o);
- return li_function::get(fun,env)->value();
- }
- li_object *li_def_object(li_object *o, li_environment *env)
- {
- li_symbol *sym=li_symbol::get(li_car(o,env),env);
-
- g1_dynamic_object_type_class *type=new g1_dynamic_object_type_class(sym);
- for (li_object *l=li_cdr(o,env); l; l=li_cdr(l,env))
- {
- li_object *prop=li_car(l,env);
- li_symbol *sym=li_symbol::get(li_car(prop,env),env);
- prop=li_cdr(prop,env);
- if (sym==li_get_symbol("model_name", s_model_name))
- {
- int id=g1_model_list_man.find_handle(li_string::get(li_car(prop,env),env)->value());
- type->model=g1_model_list_man.get_model(id);
- }
- else if (sym==li_get_symbol("mini_object", s_mini_object))
- {
- g1_mini_object_def mo;
- mo.init();
-
- char *name=0;
- for (;prop; prop=li_cdr(prop,env)) // prop = ((offset 0 0 0.1) (center 0 0 0) "gunport_barrel")
- {
- li_object *sub=li_car(prop,env);
- sym=li_symbol::get(li_car(sub,env),env); sub=li_cdr(sub,env);
- if (sym==li_get_symbol("offset", s_offset))
- read_vect(mo.offset, sub, env);
- else if (sym==li_get_symbol("position", s_position))
- read_vect(mo.position, sub, env);
- else if (sym==li_get_symbol("rotation", s_rotation))
- read_vect(mo.rotation, sub, env);
- else if (sym==li_get_symbol("model_name", s_model_name))
- {
- char *n=li_string::get(li_eval(li_car(sub,env), env),env)->value();
- mo.defmodeltype=g1_model_list_man.find_handle(n);
- }
- else li_error(env,"%O should be (offset/position/rotation x y z)",sym);
- }
- type->minis.add(mo);
- }
- else if (sym==li_get_symbol("object_flags", s_object_flags))
- {
- for (;prop; prop=li_cdr(prop,env))
- type->obj_flags |= li_int::get(li_eval(li_car(prop,env),env),env)->value();
- }
- else if (sym==li_get_symbol("type_flags", s_type_flags))
- {
- for (;prop; prop=li_cdr(prop,env))
- type->flags |= li_int::get(li_eval(li_car(prop,env),env),env)->value();
- }
- else
- {
- int found=0;
- for (int i=0; i<G1_F_TOTAL; i++)
- if (sym==s_ofun[i])
- {
- type->funs[i]=get_function(li_car(prop,env),env);
- found=1;
- }
- if (!found)
- li_error(env,"unknown object property %O", sym);
- }
- }
- // if functions were not filled in see if we can find defaults
- for (int i=0; i<G1_F_TOTAL; i++)
- if (type->funs[i]==0)
- {
- char buf[200];
- sprintf(buf, "%s_%s", type->name(), g1_ofun_names[i]);
-
- li_symbol *sym=li_find_symbol(buf);
- if (sym)
- {
- li_function *fun=li_function::get(sym->fun(), env);
- if (fun)
- type->funs[i]=li_function::get(fun, env)->value();
- }
- }
- type->flags|=g1_object_definition_class::DELETE_WITH_LEVEL;
-
- return 0;
- }
|