]> icculus.org git repositories - btb/d2x.git/blob - main/entity.c
needed for tolower()
[btb/d2x.git] / main / entity.c
1
2 #ifdef HAVE_CONFIG_H
3 #include <conf.h>
4 #endif
5
6 #include "inferno.h"
7 #include "hash.h"
8 #include "u_mem.h"
9
10
11 #define ENTITY_MAX_ENTITIES (MAX_ROBOT_TYPES + MAX_POWERUP_TYPES)
12
13 hashtable entity_hash;
14 entity *entity_list[ENTITY_MAX_ENTITIES];
15 int Num_entities;
16
17
18 void entity_add(ubyte object_type, int object_id, char object_name[16])
19 {
20         entity *ent;
21         char entity_name[32];
22         char *p;
23
24         strcpy(entity_name, Object_type_names[object_type]);
25         p = strchr(entity_name, ' ');
26         if (!p)
27                 p = strchr(entity_name, '\0');
28         *p++ = '_';
29
30         strcpy(p, object_name);
31         strlwr(entity_name);
32
33         MALLOC(ent, entity, 1);
34         ent->name = d_strdup(entity_name);
35         ent->object_type = object_type;
36         ent->object_number = object_id;
37
38         hashtable_insert(&entity_hash, ent->name, Num_entities);
39         con_printf(CON_DEBUG, "entity_add: added %s\n", ent->name);
40
41         entity_list[Num_entities++] = ent;
42 }
43
44
45 static void entity_add_object_type(ubyte object_type, char typenames[][16], int num)
46 {
47         int i;
48
49         for (i = 0; i < num; i++)
50         {
51                 if (!typenames[i] || !typenames[i][0])
52                         continue;
53
54                 entity_add(object_type, i, typenames[i]);
55         }
56 }
57
58
59 entity *entity_find(const char *entity_name)
60 {
61         int i;
62
63         i = hashtable_search( &entity_hash, entity_name );
64
65         if ( i < 0 )
66                 return NULL;
67
68         return entity_list[i];
69 }
70
71
72 void entity_cmd_report_entities(int argc, char **argv)
73 {
74         int i;
75
76         if (argc > 1)
77                 return;
78
79         for (i = 0; i < Num_entities; i++)
80                 con_printf(CON_NORMAL, "    %s\n", entity_list[i]->name);
81 }
82
83
84 #define SPIT_SPEED 20
85
86
87 void entity_cmd_create(int argc, char **argv)
88 {
89         entity     *ent;
90         int        objnum;
91         object     *obj;
92         vms_vector new_velocity, new_pos;
93         fix        objsize = F0_0;
94         ubyte      ctype = 0, mtype = 0, rtype = 0;
95
96         if (argc < 2)
97                 return;
98
99         ent = entity_find(argv[1]);
100
101         if (!ent)
102                 return;
103
104         vm_vec_scale_add(&new_velocity, &ConsoleObject->mtype.phys_info.velocity, &ConsoleObject->orient.fvec, i2f(SPIT_SPEED));
105
106 #ifdef NETWORK
107         if (Game_mode & GM_MULTI)
108         {
109                 if (Net_create_loc >= MAX_NET_CREATE_OBJECTS)
110                 {
111                         con_printf(CON_NORMAL, "ent_create: Not enough slots\n");
112                         return;
113                 }
114         }
115 #endif
116
117         switch (ent->object_type) {
118                 case OBJ_POWERUP:
119                         objsize = Powerup_info[ent->object_number].size;
120                         ctype = CT_POWERUP;
121                         mtype = MT_PHYSICS;
122                         rtype = RT_POWERUP;
123                         break;
124                 case OBJ_ROBOT:
125                         objsize = Polygon_models[Robot_info[ent->object_number].model_num].rad;
126                         ctype = CT_AI;
127                         mtype = MT_PHYSICS;
128                         rtype = RT_POLYOBJ;
129                         break;
130                 default:
131                         Int3();
132                         break;
133         }
134
135         // there's a piece of code which lets the player pick up a powerup if
136         // the distance between him and the powerup is less than 2 time their
137         // combined radii.  So we need to create powerups pretty far out from
138         // the player.
139         vm_vec_scale_add(&new_pos, &ConsoleObject->pos, &ConsoleObject->orient.fvec, ConsoleObject->size + objsize);
140
141         objnum = obj_create( ent->object_type, ent->object_number, ConsoleObject->segnum, &new_pos, &vmd_identity_matrix, objsize, ctype, mtype, rtype);
142
143         if (objnum < 0 ) {
144                 con_printf(CON_NORMAL, "ent_create: cannot create. Aborting.\n");
145                 Int3();
146                 return;
147         }
148
149         obj = &Objects[objnum];
150
151         switch (ent->object_type) {
152                 case OBJ_POWERUP:
153                         obj->mtype.phys_info.velocity = new_velocity;
154                         obj->mtype.phys_info.drag = 512;
155                         obj->mtype.phys_info.mass = F1_0;
156
157                         obj->mtype.phys_info.flags = PF_BOUNCE;
158
159                         obj->rtype.vclip_info.vclip_num = Powerup_info[obj->id].vclip_num;
160                         obj->rtype.vclip_info.frametime = Vclip[obj->rtype.vclip_info.vclip_num].frame_time;
161                         obj->rtype.vclip_info.framenum = 0;
162
163                         obj->ctype.powerup_info.flags |= PF_SPAT_BY_PLAYER;
164                         break;
165                 case OBJ_ROBOT:
166                         obj->mtype.phys_info.velocity = new_velocity;
167                         obj->rtype.pobj_info.model_num = Robot_info[obj->id].model_num;
168                         obj->rtype.pobj_info.subobj_flags = 0;
169
170                         obj->mtype.phys_info.mass = Robot_info[obj->id].mass;
171                         obj->mtype.phys_info.drag = Robot_info[obj->id].drag;
172
173                         obj->mtype.phys_info.flags |= (PF_LEVELLING);
174
175                         obj->shields = Robot_info[obj->id].strength;
176                         break;
177                 default:
178                         Int3();
179                         break;
180         }
181 }
182
183
184 static void entity_free(void)
185 {
186         while (Num_entities--) {
187                 d_free(entity_list[Num_entities]->name);
188                 d_free(entity_list[Num_entities]);
189         }
190
191         hashtable_free(&entity_hash);
192 }
193
194
195 void entity_init(void)
196 {
197         hashtable_init(&entity_hash, ENTITY_MAX_ENTITIES);
198
199         entity_add_object_type(OBJ_ROBOT, Robot_names, N_robot_types);
200         entity_add_object_type(OBJ_POWERUP, Powerup_names, N_powerup_types);
201
202         cmd_addcommand("report_entities", entity_cmd_report_entities, "");
203         cmd_addcommand("ent_create", entity_cmd_create, "");
204
205         atexit(entity_free);
206 }