1
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5
6 extern "C" {
7 #include <lua.h>
8 #include <lualib.h>
9 #include <lauxlib.h>
10 }
11
12 #include "script.h"
13
14 #include "../core/system.h"
15 #include "../core/gl_text.h"
16 #include "../core/console.h"
17 #include "../core/vmath.h"
18 #include "../physics/physics.h"
19 #include "../mesh.h"
20 #include "../skeletal_model.h"
21 #include "../trigger.h"
22 #include "../room.h"
23 #include "../gui/gui_inventory.h"
24 #include "../inventory.h"
25 #include "../entity.h"
26 #include "../world.h"
27 #include "../engine.h"
28
29
Script_ExecEntity(lua_State * lua,int id_callback,int id_object,int id_activator)30 int Script_ExecEntity(lua_State *lua, int id_callback, int id_object, int id_activator)
31 {
32 int top = lua_gettop(lua);
33 int ret = -1;
34
35 lua_getglobal(lua, "entity_funcs");
36 if(!lua_istable(lua, -1))
37 {
38 lua_settop(lua, top);
39 return -1;
40 }
41
42 lua_rawgeti(lua, -1, id_object);
43 if(!lua_istable(lua, -1))
44 {
45 lua_settop(lua, top);
46 return -1;
47 }
48
49 switch(id_callback)
50 {
51 case ENTITY_CALLBACK_ACTIVATE:
52 lua_pushstring(lua, "onActivate");
53 break;
54
55 case ENTITY_CALLBACK_DEACTIVATE:
56 lua_pushstring(lua, "onDeactivate");
57 break;
58
59 case ENTITY_CALLBACK_COLLISION:
60 lua_pushstring(lua, "onCollide");
61 break;
62
63 case ENTITY_CALLBACK_STAND:
64 lua_pushstring(lua, "onStand");
65 break;
66
67 case ENTITY_CALLBACK_HIT:
68 lua_pushstring(lua, "onHit");
69 break;
70
71 case ENTITY_CALLBACK_ATTACK:
72 lua_pushstring(lua, "onAttack");
73 break;
74
75 case ENTITY_CALLBACK_SHOOT:
76 lua_pushstring(lua, "onShoot");
77 break;
78
79 default:
80 lua_settop(lua, top);
81 return -1;
82 }
83
84 lua_rawget(lua, -2);
85 if(!lua_isfunction(lua, -1))
86 {
87 lua_settop(lua, top);
88 return -1;
89 }
90
91 lua_pushinteger(lua, id_object);
92 if(id_activator >= 0)
93 {
94 lua_pushinteger(lua, id_activator);
95 }
96 else
97 {
98 lua_pushnil(lua);
99 }
100
101 if(lua_pcall(lua, 2, 1, 0) == LUA_OK)
102 {
103 ret = lua_tointeger(lua, -1);
104 }
105
106 lua_settop(lua, top);
107
108 return ret;
109 }
110
111
Script_EntityUpdateCollisionInfo(lua_State * lua,int id,struct collision_node_s * cn)112 int Script_EntityUpdateCollisionInfo(lua_State *lua, int id, struct collision_node_s *cn)
113 {
114 int top = lua_gettop(lua);
115
116 lua_getglobal(lua, "entity_funcs");
117 if(!lua_istable(lua, -1))
118 {
119 lua_settop(lua, top);
120 return 0;
121 }
122
123 lua_rawgeti(lua, -1, id);
124 if(!lua_istable(lua, -1))
125 {
126 lua_settop(lua, top);
127 return 0;
128 }
129
130 lua_pushstring(lua, "col_part_from");
131 lua_pushinteger(lua, cn->part_from);
132 lua_settable(lua, -3);
133
134 lua_pushstring(lua, "col_part_self");
135 lua_pushinteger(lua, cn->part_self);
136 lua_settable(lua, -3);
137
138 lua_pushstring(lua, "col_px");
139 lua_pushnumber(lua, cn->penetration[0] * cn->penetration[3]);
140 lua_settable(lua, -3);
141
142 lua_pushstring(lua, "col_py");
143 lua_pushnumber(lua, cn->penetration[1] * cn->penetration[3]);
144 lua_settable(lua, -3);
145
146 lua_pushstring(lua, "col_pz");
147 lua_pushnumber(lua, cn->penetration[2] * cn->penetration[3]);
148 lua_settable(lua, -3);
149
150 lua_settop(lua, top);
151
152 return 1;
153 }
154
155
Script_GetEntitySaveData(lua_State * lua,int id_entity,char * buf,size_t buf_size)156 size_t Script_GetEntitySaveData(lua_State *lua, int id_entity, char *buf, size_t buf_size)
157 {
158 int top = lua_gettop(lua);
159 size_t ret = 0;
160
161 lua_getglobal(lua, "getEntitySaveData");
162 if(lua_isfunction(lua, -1))
163 {
164 lua_pushinteger(lua, id_entity);
165 if((lua_pcall(lua, 1, 1, 0) == LUA_OK) && lua_isstring(lua, -1))
166 {
167 strncpy(buf, lua_tolstring(lua, -1, &ret), buf_size);
168 }
169 }
170 lua_settop(lua, top);
171
172 return ret;
173 }
174
175
Script_LoopEntity(lua_State * lua,struct entity_s * ent)176 void Script_LoopEntity(lua_State *lua, struct entity_s *ent)
177 {
178 if(lua && ent && (ent->state_flags & ENTITY_STATE_ACTIVE))
179 {
180 int top = lua_gettop(lua);
181 int tick_state = TICK_ACTIVE;
182
183 if(ent->timer > 0.0f)
184 {
185 ent->timer -= engine_frame_time;
186 if(ent->timer <= 0.0f)
187 {
188 ent->timer = 0.0f;
189 tick_state = TICK_STOPPED;
190 }
191 }
192 else
193 {
194 tick_state = TICK_IDLE;
195 }
196
197 lua_getglobal(lua, "entity_funcs");
198 if(!lua_istable(lua, -1))
199 {
200 lua_settop(lua, top);
201 return;
202 }
203
204 lua_rawgeti(lua, -1, ent->id);
205 if(!lua_istable(lua, -1))
206 {
207 lua_settop(lua, top);
208 return;
209 }
210
211 lua_pushstring(lua, "onLoop");
212 lua_rawget(lua, -2);
213 if(!lua_isfunction(lua, -1))
214 {
215 lua_settop(lua, top);
216 return;
217 }
218
219 lua_pushinteger(lua, ent->id);
220 lua_pushinteger(lua, tick_state);
221 lua_CallAndLog(lua, 2, 0, 0);
222
223 lua_settop(lua, top);
224 }
225 }
226
227 /*
228 * Base Entity trigger functions
229 */
lua_ActivateEntity(lua_State * lua)230 int lua_ActivateEntity(lua_State *lua)
231 {
232 if(lua_gettop(lua) >= 6)
233 {
234 entity_p object = World_GetEntityByID(lua_tointeger(lua, 1));
235 if(object)
236 {
237 entity_p activator = World_GetEntityByID(lua_tointeger(lua, 2));
238 uint16_t trigger_mask = lua_tointeger(lua, 3);
239 uint16_t trigger_op = lua_tointeger(lua, 4);
240 uint16_t trigger_lock = lua_tointeger(lua, 5);
241 uint16_t trigger_timer = lua_tointeger(lua, 6);
242 uint16_t ret = Entity_Activate(object, activator, trigger_mask, trigger_op, trigger_lock, trigger_timer);
243 lua_pushinteger(lua, ret);
244 return 1;
245 }
246 }
247 else
248 {
249 Con_Warning("activateEntity: expecting arguments (object_id, activator_id, trigger_mask, trigger_op, trigger_lock, trigger_timer)");
250 }
251
252 return 0;
253 }
254
255
lua_DeactivateEntity(lua_State * lua)256 int lua_DeactivateEntity(lua_State *lua)
257 {
258 if(lua_gettop(lua) >= 2)
259 {
260 entity_p object = World_GetEntityByID(lua_tointeger(lua, 1));
261 if(object)
262 {
263 entity_p activator = World_GetEntityByID(lua_tointeger(lua, 2));
264 uint16_t ret = Entity_Deactivate(object, activator);
265 lua_pushinteger(lua, ret);
266 return 1;
267 }
268 }
269 else
270 {
271 Con_Warning("deactivateEntity: expecting arguments (object_id, activator_id)");
272 }
273
274 return 0;
275 }
276
277
lua_NoFixEntityCollision(lua_State * lua)278 int lua_NoFixEntityCollision(lua_State *lua)
279 {
280 if(lua_gettop(lua) >= 2)
281 {
282 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
283 if(ent)
284 {
285 ent->no_fix_all = lua_toboolean(lua, 2);
286 }
287 }
288 else
289 {
290 Con_Warning("noFixEntityCollision: Expecting arguments (entity_id, value)");
291 }
292
293 return 0;
294 }
295
296
lua_NoEntityMove(lua_State * lua)297 int lua_NoEntityMove(lua_State *lua)
298 {
299 if(lua_gettop(lua) >= 2)
300 {
301 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
302 if(ent)
303 {
304 ent->no_move = lua_toboolean(lua, 2);
305 }
306 }
307 else
308 {
309 Con_Warning("noEntityMove: Expecting arguments (entity_id, value)");
310 }
311
312 return 0;
313 }
314
315
lua_EnableEntity(lua_State * lua)316 int lua_EnableEntity(lua_State * lua)
317 {
318 if(lua_gettop(lua) >= 1)
319 {
320 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
321 if(ent)
322 {
323 Entity_Enable(ent);
324 }
325 }
326 else
327 {
328 Con_Warning("enableEntity: Expecting arguments (entity_id)");
329 }
330
331 return 0;
332 }
333
334
lua_DisableEntity(lua_State * lua)335 int lua_DisableEntity(lua_State * lua)
336 {
337 if(lua_gettop(lua) >= 1)
338 {
339 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
340 if(ent)
341 {
342 Entity_Disable(ent);
343 }
344 }
345 else
346 {
347 Con_Warning("disableEntity: Expecting arguments (entity_id)");
348 }
349
350 return 0;
351 }
352
353
lua_GetEntitySectorFlags(lua_State * lua)354 int lua_GetEntitySectorFlags(lua_State *lua)
355 {
356 if(lua_gettop(lua) >= 1)
357 {
358 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
359 if(ent && (ent->self->sector))
360 {
361 lua_pushinteger(lua, ent->self->sector->flags);
362 return 1;
363 }
364 }
365
366 return 0;
367 }
368
369
lua_GetEntitySectorIndex(lua_State * lua)370 int lua_GetEntitySectorIndex(lua_State *lua)
371 {
372 if(lua_gettop(lua) >= 1)
373 {
374 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
375 if(ent && (ent->self->sector))
376 {
377 lua_pushinteger(lua, ent->self->sector->trig_index);
378 return 1;
379 }
380 }
381
382 return 0;
383 }
384
385
lua_GetEntitySectorMaterial(lua_State * lua)386 int lua_GetEntitySectorMaterial(lua_State *lua)
387 {
388 if(lua_gettop(lua) >= 1)
389 {
390 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
391 if(ent && ent->self->sector)
392 {
393 lua_pushinteger(lua, ent->self->sector->material);
394 return 1;
395 }
396 }
397
398 return 0;
399 }
400
401
lua_GetEntityBoxID(lua_State * lua)402 int lua_GetEntityBoxID(lua_State *lua)
403 {
404 int top = lua_gettop(lua);
405 if(top >= 3)
406 {
407 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
408 if(ent && ent->self->room)
409 {
410 float pos[3] = {ent->transform.M4x4[12 + 0], ent->transform.M4x4[12 + 1], ent->transform.M4x4[12 + 2]};
411 float dx = TR_METERING_SECTORSIZE * lua_tointeger(lua, 2);
412 float dy = TR_METERING_SECTORSIZE * lua_tointeger(lua, 3);
413 pos[0] += dx * ent->transform.M4x4[0 + 0] + dy * ent->transform.M4x4[4 + 0];
414 pos[1] += dx * ent->transform.M4x4[0 + 1] + dy * ent->transform.M4x4[4 + 1];
415 room_sector_p rs = Room_GetSectorRaw(ent->self->room, pos);
416 rs = Sector_GetPortalSectorTargetRaw(rs);
417 if(rs && rs->box)
418 {
419 lua_pushinteger(lua, rs->box->id);
420 lua_pushboolean(lua, rs->box->is_blockable);
421 return 2;
422 }
423 }
424 }
425
426 return 0;
427 }
428
429
lua_GetEntityActivationOffset(lua_State * lua)430 int lua_GetEntityActivationOffset(lua_State * lua)
431 {
432 if(lua_gettop(lua) >= 1)
433 {
434 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
435 if(ent && ent->activation_point)
436 {
437 lua_pushnumber(lua, ent->activation_point->offset[0]);
438 lua_pushnumber(lua, ent->activation_point->offset[1]);
439 lua_pushnumber(lua, ent->activation_point->offset[2]);
440 lua_pushnumber(lua, ent->activation_point->offset[3]);
441 return 4;
442 }
443 }
444
445 return 0;
446 }
447
448
lua_SetEntityActivationOffset(lua_State * lua)449 int lua_SetEntityActivationOffset(lua_State * lua)
450 {
451 int top = lua_gettop(lua);
452
453 if(top >= 1)
454 {
455 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
456 if(ent)
457 {
458 if(!ent->activation_point)
459 {
460 Entity_InitActivationPoint(ent);
461 }
462
463 if(top >= 4)
464 {
465 ent->activation_point->offset[0] = lua_tonumber(lua, 2);
466 ent->activation_point->offset[1] = lua_tonumber(lua, 3);
467 ent->activation_point->offset[2] = lua_tonumber(lua, 4);
468 }
469 if(top >= 5)
470 {
471 ent->activation_point->offset[3] = lua_tonumber(lua, 5);
472 }
473 }
474 else
475 {
476 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
477 }
478 }
479 else
480 {
481 Con_Warning("setEntityActivationOffset: Expecting arguments (entity_id)");
482 }
483
484 return 0;
485 }
486
487
lua_GetEntityActivationDirection(lua_State * lua)488 int lua_GetEntityActivationDirection(lua_State * lua)
489 {
490 if(lua_gettop(lua) >= 1)
491 {
492 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
493 if(ent)
494 {
495 lua_pushnumber(lua, ent->activation_point->direction[0]);
496 lua_pushnumber(lua, ent->activation_point->direction[1]);
497 lua_pushnumber(lua, ent->activation_point->direction[2]);
498 lua_pushnumber(lua, ent->activation_point->direction[3]);
499 return 4;
500 }
501 }
502
503 return 0;
504 }
505
506
lua_SetEntityActivationDirection(lua_State * lua)507 int lua_SetEntityActivationDirection(lua_State * lua)
508 {
509 int top = lua_gettop(lua);
510
511 if(top >= 4)
512 {
513 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
514 if(ent)
515 {
516 if(!ent->activation_point)
517 {
518 Entity_InitActivationPoint(ent);
519 }
520
521 ent->activation_point->direction[0] = lua_tonumber(lua, 2);
522 ent->activation_point->direction[1] = lua_tonumber(lua, 3);
523 ent->activation_point->direction[2] = lua_tonumber(lua, 4);
524 if(top >= 5)
525 {
526 ent->activation_point->direction[3] = lua_tonumber(lua, 5);
527 }
528 }
529 else
530 {
531 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
532 }
533 }
534 else
535 {
536 Con_Warning("setEntityActivationDirection: Expecting arguments (entity_id, x, y, z, (w))");
537 }
538
539 return 0;
540 }
541
542
543 /*
544 * Moveables script control section
545 */
lua_GetEntityVector(lua_State * lua)546 int lua_GetEntityVector(lua_State * lua)
547 {
548 if(lua_gettop(lua) >= 2)
549 {
550 entity_p e1 = World_GetEntityByID(lua_tointeger(lua, 1));
551 entity_p e2 = World_GetEntityByID(lua_tointeger(lua, 2));
552 if(e1 && e2)
553 {
554 lua_pushnumber(lua, e2->transform.M4x4[12 + 0] - e1->transform.M4x4[12 + 0]);
555 lua_pushnumber(lua, e2->transform.M4x4[12 + 1] - e1->transform.M4x4[12 + 1]);
556 lua_pushnumber(lua, e2->transform.M4x4[12 + 2] - e1->transform.M4x4[12 + 2]);
557 return 3;
558 }
559 }
560 else
561 {
562 Con_Warning("getEntityVector: expecting arguments (entity_id1, entity_id2)");
563 }
564
565 return 0;
566 }
567
568
lua_GetEntityDistance(lua_State * lua)569 int lua_GetEntityDistance(lua_State * lua)
570 {
571 if(lua_gettop(lua) >= 2)
572 {
573 entity_p e1 = World_GetEntityByID(lua_tointeger(lua, 1));
574 entity_p e2 = World_GetEntityByID(lua_tointeger(lua, 2));
575 if(e1 && e2)
576 {
577 lua_pushnumber(lua, vec3_dist(e1->transform.M4x4 + 12, e2->transform.M4x4 + 12));
578 return 1;
579 }
580 }
581 else
582 {
583 Con_Warning("getEntityDistance: expecting arguments (entity_id1, entity_id2)");
584 }
585
586 return 0;
587 }
588
589
lua_GetEntityDirDot(lua_State * lua)590 int lua_GetEntityDirDot(lua_State * lua)
591 {
592 if(lua_gettop(lua) >= 2)
593 {
594 entity_p e1 = World_GetEntityByID(lua_tointeger(lua, 1));
595 entity_p e2 = World_GetEntityByID(lua_tointeger(lua, 2));
596 if(e1 && e2)
597 {
598 lua_pushnumber(lua, vec3_dot(e1->transform.M4x4 + 4, e2->transform.M4x4 + 4));
599 return 1;
600 }
601 }
602 else
603 {
604 Con_Warning("getEntityDirDot: expecting arguments (id1, id2)");
605 }
606
607 return 0;
608 }
609
610
lua_GetEntityRoom(lua_State * lua)611 int lua_GetEntityRoom(lua_State * lua)
612 {
613 if(lua_gettop(lua) >= 1)
614 {
615 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
616 if(ent)
617 {
618 if(ent->self->room)
619 {
620 lua_pushinteger(lua, ent->self->room->id);
621 }
622 else
623 {
624 lua_pushnil(lua);
625 }
626 return 1;
627 }
628 else
629 {
630 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
631 }
632 }
633 else
634 {
635 Con_Warning("getEntityRoom: expecting arguments (entity_id)");
636 }
637
638 return 0;
639 }
640
641
lua_GetEntityPosition(lua_State * lua)642 int lua_GetEntityPosition(lua_State * lua)
643 {
644 if(lua_gettop(lua) >= 1)
645 {
646 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
647 if(ent)
648 {
649 lua_pushnumber(lua, ent->transform.M4x4[12 + 0]);
650 lua_pushnumber(lua, ent->transform.M4x4[12 + 1]);
651 lua_pushnumber(lua, ent->transform.M4x4[12 + 2]);
652 lua_pushnumber(lua, ent->transform.angles[0]);
653 lua_pushnumber(lua, ent->transform.angles[1]);
654 lua_pushnumber(lua, ent->transform.angles[2]);
655 return 6;
656 }
657 else
658 {
659 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
660 }
661 }
662 else
663 {
664 Con_Warning("getEntityPosition: expecting arguments (entity_id)");
665 }
666
667 return 0;
668 }
669
670
lua_GetEntityAngles(lua_State * lua)671 int lua_GetEntityAngles(lua_State * lua)
672 {
673 if(lua_gettop(lua) >= 1)
674 {
675 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
676 if(ent)
677 {
678 lua_pushnumber(lua, ent->transform.angles[0]);
679 lua_pushnumber(lua, ent->transform.angles[1]);
680 lua_pushnumber(lua, ent->transform.angles[2]);
681 return 3;
682 }
683 else
684 {
685 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
686 }
687 }
688 else
689 {
690 Con_Warning("getEntityAngles: expecting arguments (entity_id)");
691 }
692
693 return 0;
694 }
695
696
lua_GetEntityScaling(lua_State * lua)697 int lua_GetEntityScaling(lua_State * lua)
698 {
699 if(lua_gettop(lua) >= 1)
700 {
701 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
702 if(ent)
703 {
704 lua_pushnumber(lua, ent->transform.scaling[0]);
705 lua_pushnumber(lua, ent->transform.scaling[1]);
706 lua_pushnumber(lua, ent->transform.scaling[2]);
707 return 3;
708 }
709 else
710 {
711 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
712 }
713 }
714 else
715 {
716 Con_Warning("getEntityScaling: expecting arguments (entity_id)");
717 }
718
719 return 0;
720 }
721
722
lua_SetEntityScaling(lua_State * lua)723 int lua_SetEntityScaling(lua_State * lua)
724 {
725 if(lua_gettop(lua) >= 4)
726 {
727 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
728 if(ent)
729 {
730 ent->transform.scaling[0] = lua_tonumber(lua, 2);
731 ent->transform.scaling[1] = lua_tonumber(lua, 3);
732 ent->transform.scaling[2] = lua_tonumber(lua, 4);
733
734 Physics_SetCollisionScale(ent->physics, ent->transform.scaling);
735 Entity_UpdateRigidBody(ent, 1);
736 }
737 else
738 {
739 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
740 }
741 }
742 else
743 {
744 Con_Warning("setEntityScaling: expecting arguments (entity_id, x_scaling, y_scaling, z_scaling)");
745 }
746
747 return 0;
748 }
749
750
lua_SetEntityPosition(lua_State * lua)751 int lua_SetEntityPosition(lua_State * lua)
752 {
753 switch(lua_gettop(lua))
754 {
755 case 4:
756 {
757 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
758 if(ent)
759 {
760 ent->transform.M4x4[12 + 0] = lua_tonumber(lua, 2);
761 ent->transform.M4x4[12 + 1] = lua_tonumber(lua, 3);
762 ent->transform.M4x4[12 + 2] = lua_tonumber(lua, 4);
763 Entity_UpdateRigidBody(ent, 1);
764 }
765 else
766 {
767 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
768 }
769 }
770 return 0;
771
772 case 7:
773 {
774 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
775 if(ent)
776 {
777 ent->transform.M4x4[12 + 0] = lua_tonumber(lua, 2);
778 ent->transform.M4x4[12 + 1] = lua_tonumber(lua, 3);
779 ent->transform.M4x4[12 + 2] = lua_tonumber(lua, 4);
780 ent->transform.angles[0] = lua_tonumber(lua, 5);
781 ent->transform.angles[1] = lua_tonumber(lua, 6);
782 ent->transform.angles[2] = lua_tonumber(lua, 7);
783 Entity_UpdateTransform(ent);
784 Entity_UpdateRigidBody(ent, 1);
785 }
786 else
787 {
788 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
789 }
790 }
791 return 0;
792
793 default:
794 Con_Warning("setEntityPosition: expecting arguments (entity_id, x, y, z, (fi_x, fi_y, fi_z))");
795 return 0;
796 }
797
798 return 0;
799 }
800
801
lua_SetEntityAngles(lua_State * lua)802 int lua_SetEntityAngles(lua_State * lua)
803 {
804 if(lua_gettop(lua) >= 4)
805 {
806 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
807 if(ent)
808 {
809 ent->transform.angles[0] = lua_tonumber(lua, 2);
810 ent->transform.angles[1] = lua_tonumber(lua, 3);
811 ent->transform.angles[2] = lua_tonumber(lua, 4);
812 Entity_UpdateTransform(ent);
813 }
814 else
815 {
816 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
817 }
818 }
819 else
820 {
821 Con_Warning("setEntityAngles: expecting arguments (entity_id, fi_x, (fi_y, fi_z))");
822 }
823
824 return 0;
825 }
826
827
lua_MoveEntityGlobal(lua_State * lua)828 int lua_MoveEntityGlobal(lua_State * lua)
829 {
830 switch(lua_gettop(lua))
831 {
832 case 4:
833 {
834 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
835 if(ent)
836 {
837 ent->transform.M4x4[12 + 0] += lua_tonumber(lua, 2);
838 ent->transform.M4x4[12 + 1] += lua_tonumber(lua, 3);
839 ent->transform.M4x4[12 + 2] += lua_tonumber(lua, 4);
840 Entity_UpdateRigidBody(ent, 1);
841 }
842 else
843 {
844 Con_Printf("can not find entity with id = %d", lua_tointeger(lua, 1));
845 }
846 }
847 return 0;
848
849 default:
850 Con_Warning("moveEntityGlobal: expecting arguments (entity_id, x, y, z)");
851 return 0;
852 }
853
854 return 0;
855 }
856
857
lua_MoveEntityLocal(lua_State * lua)858 int lua_MoveEntityLocal(lua_State * lua)
859 {
860 if(lua_gettop(lua) >= 4)
861 {
862 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
863 if(ent)
864 {
865 float dx = lua_tonumber(lua, 2);
866 float dy = lua_tonumber(lua, 3);
867 float dz = lua_tonumber(lua, 4);
868
869 ent->transform.M4x4[12 + 0] += dx * ent->transform.M4x4[0 + 0] + dy * ent->transform.M4x4[4 + 0] + dz * ent->transform.M4x4[8 + 0];
870 ent->transform.M4x4[12 + 1] += dx * ent->transform.M4x4[0 + 1] + dy * ent->transform.M4x4[4 + 1] + dz * ent->transform.M4x4[8 + 1];
871 ent->transform.M4x4[12 + 2] += dx * ent->transform.M4x4[0 + 2] + dy * ent->transform.M4x4[4 + 2] + dz * ent->transform.M4x4[8 + 2];
872
873 Entity_UpdateRigidBody(ent, 1);
874 }
875 else
876 {
877 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
878 }
879 }
880 else
881 {
882 Con_Warning("moveEntityLocal: expecting arguments (entity_id, dx, dy, dz)");
883 }
884
885 return 0;
886 }
887
888
lua_MoveEntityToSink(lua_State * lua)889 int lua_MoveEntityToSink(lua_State * lua)
890 {
891 if(lua_gettop(lua) >= 2)
892 {
893 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
894 if(ent)
895 {
896 Entity_MoveToSink(ent, World_GetStaticCameraSink(lua_tointeger(lua, 2)));
897 }
898 }
899 else
900 {
901 Con_Warning("moveEntityToSink: expecting arguments (entity_id, sink_id)");
902 }
903
904 return 0;
905 }
906
907
lua_MoveEntityToEntity(lua_State * lua)908 int lua_MoveEntityToEntity(lua_State * lua)
909 {
910 int top = lua_gettop(lua);
911
912 if(top >= 3)
913 {
914 entity_p ent1 = World_GetEntityByID(lua_tointeger(lua, 1));
915 entity_p ent2 = World_GetEntityByID(lua_tointeger(lua, 2));
916 if(ent1 && ent2)
917 {
918 float speed_mult = lua_tonumber(lua, 3);
919 float *ent1_pos = ent1->transform.M4x4 + 12;
920 float *ent2_pos = ent2->transform.M4x4 + 12;
921 float t, speed[3];
922
923 vec3_sub(speed, ent2_pos, ent1_pos);
924 t = vec3_abs(speed);
925 t = (t == 0.0f) ? 1.0f : t; // Prevents division by zero.
926 t = speed_mult / t;
927
928 ent1->transform.M4x4[12 + 0] += speed[0] * t;
929 ent1->transform.M4x4[12 + 1] += speed[1] * t;
930 if((top == 3) || !lua_toboolean(lua, 4))
931 {
932 ent1->transform.M4x4[12 + 2] += speed[2] * t;
933 }
934
935 Entity_UpdateRigidBody(ent1, 1);
936 }
937 }
938 else
939 {
940 Con_Warning("moveEntityToEntity: expecting arguments (moved_entity_id, target_entity_id, speed, (ignore_z))");
941 }
942
943 return 0;
944 }
945
946
lua_RotateEntity(lua_State * lua)947 int lua_RotateEntity(lua_State *lua)
948 {
949 int top = lua_gettop(lua);
950
951 if(top >= 2)
952 {
953 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
954 if(ent)
955 {
956 ent->transform.angles[0] += lua_tonumber(lua, 2);
957 if(top >= 4)
958 {
959 ent->transform.angles[1] += lua_tonumber(lua, 3);
960 ent->transform.angles[2] += lua_tonumber(lua, 4);
961 }
962 Entity_UpdateTransform(ent);
963 Entity_UpdateRigidBody(ent, 1);
964 }
965 else
966 {
967 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
968 }
969 }
970 else
971 {
972 Con_Warning("rotateEntity: expecting arguments (ent_id, rot_x, (rot_y, rot_z))");
973 }
974
975 return 0;
976 }
977
978
lua_GetEntitySpeed(lua_State * lua)979 int lua_GetEntitySpeed(lua_State * lua)
980 {
981 if(lua_gettop(lua) >= 1)
982 {
983 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
984 if(ent)
985 {
986 lua_pushnumber(lua, ent->speed[0]);
987 lua_pushnumber(lua, ent->speed[1]);
988 lua_pushnumber(lua, ent->speed[2]);
989 return 3;
990 }
991 else
992 {
993 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
994 }
995 }
996 else
997 {
998 Con_Warning("getEntitySpeed: expecting arguments (entity_id)");
999 }
1000
1001 return 0;
1002 }
1003
1004
lua_GetEntitySpeedLinear(lua_State * lua)1005 int lua_GetEntitySpeedLinear(lua_State * lua)
1006 {
1007 if(lua_gettop(lua) >= 1)
1008 {
1009 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1010 if(ent)
1011 {
1012 lua_pushnumber(lua, vec3_abs(ent->speed));
1013 return 1;
1014 }
1015 else
1016 {
1017 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
1018 }
1019 }
1020 else
1021 {
1022 Con_Warning("getEntitySpeedLinear: expecting arguments (entity_id)");
1023 }
1024
1025 return 0;
1026 }
1027
1028
lua_SetEntitySpeed(lua_State * lua)1029 int lua_SetEntitySpeed(lua_State * lua)
1030 {
1031 if(lua_gettop(lua) >= 4)
1032 {
1033 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1034 if(ent)
1035 {
1036 ent->speed[0] = lua_tonumber(lua, 2);
1037 ent->speed[1] = lua_tonumber(lua, 3);
1038 ent->speed[2] = lua_tonumber(lua, 4);
1039 }
1040 else
1041 {
1042 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
1043 }
1044 }
1045 else
1046 {
1047 Con_Warning("setEntitySpeed: expecting arguments (id, speed_x, speed_y, speed_z)");
1048 }
1049
1050 return 0;
1051 }
1052
1053
lua_SetEntityLinearSpeed(lua_State * lua)1054 int lua_SetEntityLinearSpeed(lua_State * lua)
1055 {
1056 if(lua_gettop(lua) >= 2)
1057 {
1058 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1059 if(ent)
1060 {
1061 ent->linear_speed = lua_tonumber(lua, 2);
1062 }
1063 else
1064 {
1065 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
1066 }
1067 }
1068 else
1069 {
1070 Con_Warning("setEntityLinearSpeed: expecting arguments (id, speed");
1071 }
1072
1073 return 0;
1074 }
1075
1076
lua_SetEntityBodyPartFlag(lua_State * lua)1077 int lua_SetEntityBodyPartFlag(lua_State * lua)
1078 {
1079 if(lua_gettop(lua) >= 3)
1080 {
1081 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1082 if(ent)
1083 {
1084 int bone_id = lua_tointeger(lua, 2);
1085 if((bone_id >= 0) && (bone_id < ent->bf->bone_tag_count))
1086 {
1087 ent->bf->bone_tags[bone_id].body_part = lua_tointeger(lua, 3);
1088 }
1089 }
1090 else
1091 {
1092 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
1093 }
1094 }
1095 else
1096 {
1097 Con_Warning("setEntityBodyPartFlag: expecting arguments (entity_id, bone_id, body_part_flag)");
1098 }
1099
1100 return 0;
1101 }
1102
1103
lua_AddItem(lua_State * lua)1104 int lua_AddItem(lua_State * lua)
1105 {
1106 int top = lua_gettop(lua);
1107 if(top >= 2)
1108 {
1109 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1110 if(ent)
1111 {
1112 entity_p player = World_GetPlayer();
1113 int item_id = lua_tointeger(lua, 2);
1114 int count = (top >= 3) ? (lua_tointeger(lua, 3)) : (1);
1115 lua_pushinteger(lua, Inventory_AddItem(&ent->inventory, item_id, count));
1116 if(!player || ent->id == player->id)
1117 {
1118 Gui_NotifierStart(item_id);
1119 }
1120 return 1;
1121 }
1122 else
1123 {
1124 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
1125 }
1126 }
1127 else
1128 {
1129 Con_Warning("addItem: expecting arguments (entity_id, item_id, (items_count = pickup_count))");
1130 }
1131
1132 return 0;
1133 }
1134
1135
lua_RemoveItem(lua_State * lua)1136 int lua_RemoveItem(lua_State * lua)
1137 {
1138 if(lua_gettop(lua) >= 3)
1139 {
1140 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1141 if(ent)
1142 {
1143 int item_id = lua_tointeger(lua, 2);
1144 int count = lua_tointeger(lua, 3);
1145 lua_pushinteger(lua, Inventory_RemoveItem(&ent->inventory, item_id, count));
1146 return 1;
1147 }
1148 else
1149 {
1150 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
1151 }
1152 }
1153 else
1154 {
1155 Con_Warning("removeItem: expecting arguments (entity_id, item_id, items_count)");
1156 }
1157
1158 return 0;
1159 }
1160
1161
lua_RemoveAllItems(lua_State * lua)1162 int lua_RemoveAllItems(lua_State * lua)
1163 {
1164 if(lua_gettop(lua) >= 1)
1165 {
1166 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1167 if(ent)
1168 {
1169 Inventory_RemoveAllItems(&ent->inventory);
1170 }
1171 else
1172 {
1173 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
1174 }
1175 }
1176 else
1177 {
1178 Con_Warning("removeAllItems: expecting arguments (entity_id)");
1179 }
1180
1181 return 0;
1182 }
1183
1184
lua_GetItemsCount(lua_State * lua)1185 int lua_GetItemsCount(lua_State * lua)
1186 {
1187 if(lua_gettop(lua) >= 2)
1188 {
1189 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1190 if(ent)
1191 {
1192 int item_id = lua_tointeger(lua, 2);
1193 lua_pushinteger(lua, Inventory_GetItemsCount(ent->inventory, item_id));
1194 return 1;
1195 }
1196 else
1197 {
1198 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
1199 }
1200 }
1201 else
1202 {
1203 Con_Warning("getItemsCount: expecting arguments (entity_id, item_id)");
1204 }
1205
1206 return 0;
1207 }
1208
1209
lua_GetItems(lua_State * lua)1210 int lua_GetItems(lua_State * lua)
1211 {
1212 if(lua_gettop(lua) >= 1)
1213 {
1214 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1215 if(ent)
1216 {
1217 lua_newtable(lua);
1218 int top = lua_gettop(lua);
1219 for(inventory_node_p i = ent->inventory; i; i = i->next)
1220 {
1221 lua_pushinteger(lua, i->count);
1222 lua_rawseti(lua, -2, i->id);
1223 lua_settop(lua, top);
1224 }
1225
1226 return 1;
1227 }
1228 else
1229 {
1230 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
1231 }
1232 }
1233 else
1234 {
1235 Con_Warning("getItems: expecting arguments (entity_id)");
1236 }
1237
1238 return 0;
1239 }
1240
1241
lua_CanTriggerEntity(lua_State * lua)1242 int lua_CanTriggerEntity(lua_State * lua)
1243 {
1244 if(lua_gettop(lua) >= 2)
1245 {
1246 lua_pushboolean(lua, Entity_CanTrigger(World_GetEntityByID(lua_tointeger(lua, 1)),
1247 World_GetEntityByID(lua_tointeger(lua, 2))));
1248 }
1249 else
1250 {
1251 lua_pushboolean(lua, false);
1252 }
1253
1254 return 1;
1255 }
1256
1257
lua_EntityRotateToTriggerZ(lua_State * lua)1258 int lua_EntityRotateToTriggerZ(lua_State * lua)
1259 {
1260 if(lua_gettop(lua) >= 2)
1261 {
1262 Entity_RotateToTriggerZ(World_GetEntityByID(lua_tointeger(lua, 1)),
1263 World_GetEntityByID(lua_tointeger(lua, 2)));
1264 }
1265
1266 return 0;
1267 }
1268
1269
lua_EntityRotateToTrigger(lua_State * lua)1270 int lua_EntityRotateToTrigger(lua_State * lua)
1271 {
1272 if(lua_gettop(lua) >= 3)
1273 {
1274 Entity_RotateToTrigger(World_GetEntityByID(lua_tointeger(lua, 1)),
1275 World_GetEntityByID(lua_tointeger(lua, 2)),
1276 lua_tointeger(lua, 3));
1277 }
1278
1279 return 0;
1280 }
1281
1282
lua_EntityMoveToTriggerActivationPoint(lua_State * lua)1283 int lua_EntityMoveToTriggerActivationPoint(lua_State * lua)
1284 {
1285 if(lua_gettop(lua) >= 2)
1286 {
1287 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1288 entity_p trigger = World_GetEntityByID(lua_tointeger(lua, 2));
1289 if(ent && trigger && trigger->activation_point)
1290 {
1291 float *pos = ent->transform.M4x4 + 12;
1292 Mat4_vec3_mul_macro(pos, trigger->transform.M4x4, trigger->activation_point->offset);
1293 }
1294 }
1295
1296 return 0;
1297 }
1298
1299
lua_GetEntityVisibility(lua_State * lua)1300 int lua_GetEntityVisibility(lua_State * lua)
1301 {
1302 if(lua_gettop(lua) >= 1)
1303 {
1304 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1305 if(ent)
1306 {
1307 lua_pushinteger(lua, (ent->state_flags & ENTITY_STATE_VISIBLE) != 0);
1308 return 1;
1309 }
1310 else
1311 {
1312 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
1313 }
1314 }
1315 else
1316 {
1317 Con_Warning("getEntityVisibility: expecting arguments (entity_id)");
1318 }
1319
1320 return 0;
1321 }
1322
1323
lua_SetEntityVisibility(lua_State * lua)1324 int lua_SetEntityVisibility(lua_State * lua)
1325 {
1326 if(lua_gettop(lua) >= 2)
1327 {
1328 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1329 if(ent)
1330 {
1331 if(lua_toboolean(lua, 2))
1332 {
1333 ent->state_flags |= ENTITY_STATE_VISIBLE;
1334 }
1335 else
1336 {
1337 ent->state_flags &= ~ENTITY_STATE_VISIBLE;
1338 }
1339 }
1340 else
1341 {
1342 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
1343 }
1344 }
1345 else
1346 {
1347 Con_Warning("setEntityVisibility: expecting arguments (entity_id, value)");
1348 }
1349
1350 return 0;
1351 }
1352
1353
lua_GetEntityEnability(lua_State * lua)1354 int lua_GetEntityEnability(lua_State * lua)
1355 {
1356 if(lua_gettop(lua) >= 1)
1357 {
1358 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1359 if(ent)
1360 {
1361 lua_pushboolean(lua, (ent->state_flags & ENTITY_STATE_ENABLED) != 0);
1362 return 1;
1363 }
1364 else
1365 {
1366 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
1367 }
1368 }
1369 else
1370 {
1371 Con_Warning("getEntityEnability: expecting arguments (entity_id)");
1372 }
1373
1374 return 0;
1375 }
1376
1377
lua_GetEntityActivity(lua_State * lua)1378 int lua_GetEntityActivity(lua_State * lua)
1379 {
1380 if(lua_gettop(lua) >= 1)
1381 {
1382 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1383 if(ent)
1384 {
1385 lua_pushboolean(lua, (ent->state_flags & ENTITY_STATE_ACTIVE) != 0);
1386 return 1;
1387 }
1388 else
1389 {
1390 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
1391 }
1392 }
1393 else
1394 {
1395 Con_Warning("getEntityActivity: expecting arguments (entity_id)");
1396 }
1397
1398 return 0;
1399 }
1400
1401
lua_SetEntityActivity(lua_State * lua)1402 int lua_SetEntityActivity(lua_State * lua)
1403 {
1404 if(lua_gettop(lua) >= 2)
1405 {
1406 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1407 if(ent)
1408 {
1409 if(lua_toboolean(lua, 2))
1410 {
1411 ent->state_flags |= ENTITY_STATE_ACTIVE;
1412 }
1413 else
1414 {
1415 ent->state_flags &= ~ENTITY_STATE_ACTIVE;
1416 }
1417 }
1418 else
1419 {
1420 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
1421 }
1422 }
1423 else
1424 {
1425 Con_Warning("setEntityActivity: expecting arguments (entity_id, value)");
1426 }
1427
1428 return 0;
1429 }
1430
1431
lua_GetEntityTriggerLayout(lua_State * lua)1432 int lua_GetEntityTriggerLayout(lua_State *lua)
1433 {
1434 if(lua_gettop(lua) >= 1)
1435 {
1436 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1437 if(ent)
1438 {
1439 lua_pushinteger(lua, (ent->trigger_layout & ENTITY_TLAYOUT_MASK)); // mask
1440 lua_pushinteger(lua, (ent->trigger_layout & ENTITY_TLAYOUT_EVENT) >> 5); // event
1441 lua_pushinteger(lua, (ent->trigger_layout & ENTITY_TLAYOUT_LOCK) >> 6); // lock
1442 return 3;
1443 }
1444 }
1445
1446 return 0;
1447 }
1448
1449
lua_SetEntityTriggerLayout(lua_State * lua)1450 int lua_SetEntityTriggerLayout(lua_State *lua)
1451 {
1452 int top = lua_gettop(lua);
1453
1454 if(top >= 2)
1455 {
1456 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1457 if(ent)
1458 {
1459 if(top == 2)
1460 {
1461 ent->trigger_layout = (uint8_t)lua_tointeger(lua, 2);
1462 }
1463 else if(top == 4)
1464 {
1465 uint8_t trigger_layout = ent->trigger_layout;
1466 trigger_layout &= ~(uint8_t)(ENTITY_TLAYOUT_MASK);
1467 trigger_layout ^= (uint8_t)lua_tointeger(lua, 2); // mask - 00011111
1468 trigger_layout &= ~(uint8_t)(ENTITY_TLAYOUT_EVENT);
1469 trigger_layout ^= ((uint8_t)lua_tointeger(lua, 3)) << 5; // event - 00100000
1470 trigger_layout &= ~(uint8_t)(ENTITY_TLAYOUT_LOCK);
1471 trigger_layout ^= ((uint8_t)lua_tointeger(lua, 4)) << 6; // lock - 01000000
1472 ent->trigger_layout = trigger_layout;
1473 }
1474 }
1475 else
1476 {
1477 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
1478 }
1479 }
1480 else
1481 {
1482 Con_Warning("setEntityTriggerLayout: expecting arguments (entity_id, layout) or (entity_id, mask, event, once)");
1483 }
1484
1485 return 0;
1486 }
1487
1488
lua_SetEntityLock(lua_State * lua)1489 int lua_SetEntityLock(lua_State * lua)
1490 {
1491 if(lua_gettop(lua) >= 2)
1492 {
1493 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1494 if(ent)
1495 {
1496 uint8_t trigger_layout = ent->trigger_layout;
1497 trigger_layout &= ~(uint8_t)(ENTITY_TLAYOUT_LOCK);
1498 trigger_layout ^= ((uint8_t)lua_tointeger(lua, 2)) << 6; // lock - 01000000
1499 ent->trigger_layout = trigger_layout;
1500 }
1501 }
1502
1503 return 0;
1504 }
1505
1506
lua_GetEntityLock(lua_State * lua)1507 int lua_GetEntityLock(lua_State * lua)
1508 {
1509 if(lua_gettop(lua) >= 1)
1510 {
1511 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1512 if(ent)
1513 {
1514 lua_pushinteger(lua, ((ent->trigger_layout & ENTITY_TLAYOUT_LOCK) >> 6)); // lock
1515 return 1;
1516 }
1517 }
1518
1519 return 0;
1520 }
1521
1522
lua_SetEntityEvent(lua_State * lua)1523 int lua_SetEntityEvent(lua_State * lua)
1524 {
1525 if(lua_gettop(lua) >= 2)
1526 {
1527 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1528 if(ent)
1529 {
1530 uint8_t trigger_layout = ent->trigger_layout;
1531 trigger_layout &= ~(uint8_t)(ENTITY_TLAYOUT_EVENT);
1532 trigger_layout ^= ((uint8_t)lua_tointeger(lua, 2)) << 5; // event - 00100000
1533 ent->trigger_layout = trigger_layout;
1534 }
1535 }
1536
1537 return 0;
1538 }
1539
1540
lua_GetEntityEvent(lua_State * lua)1541 int lua_GetEntityEvent(lua_State *lua)
1542 {
1543 if(lua_gettop(lua) >= 1)
1544 {
1545 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1546 if(ent)
1547 {
1548 lua_pushinteger(lua, ((ent->trigger_layout & ENTITY_TLAYOUT_EVENT) >> 5)); // event
1549 return 1;
1550 }
1551 }
1552
1553 return 0;
1554 }
1555
1556
lua_GetEntityMask(lua_State * lua)1557 int lua_GetEntityMask(lua_State * lua)
1558 {
1559 if(lua_gettop(lua) >= 1)
1560 {
1561 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1562 if(ent)
1563 {
1564 lua_pushinteger(lua, (ent->trigger_layout & ENTITY_TLAYOUT_MASK)); // mask
1565 return 1;
1566 }
1567 }
1568
1569 return 0;
1570 }
1571
1572
lua_SetEntityMask(lua_State * lua)1573 int lua_SetEntityMask(lua_State * lua)
1574 {
1575 if(lua_gettop(lua) >= 2)
1576 {
1577 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1578 if(ent)
1579 {
1580 uint8_t trigger_layout = ent->trigger_layout;
1581 trigger_layout &= ~(uint8_t)(ENTITY_TLAYOUT_MASK);
1582 trigger_layout ^= (uint8_t)lua_tointeger(lua, 2); // mask - 00011111
1583 ent->trigger_layout = trigger_layout;
1584 }
1585 }
1586
1587 return 0;
1588 }
1589
1590
lua_GetEntitySectorStatus(lua_State * lua)1591 int lua_GetEntitySectorStatus(lua_State *lua)
1592 {
1593 if(lua_gettop(lua) >= 1)
1594 {
1595 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1596 if(ent)
1597 {
1598 lua_pushinteger(lua, ((ent->trigger_layout & ENTITY_TLAYOUT_SSTATUS) >> 7));
1599 return 1;
1600 }
1601 }
1602
1603 return 0;
1604 }
1605
1606
lua_SetEntitySectorStatus(lua_State * lua)1607 int lua_SetEntitySectorStatus(lua_State *lua)
1608 {
1609 if(lua_gettop(lua) >= 2)
1610 {
1611 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1612 if(ent)
1613 {
1614 uint8_t trigger_layout = ent->trigger_layout;
1615 trigger_layout &= ~(uint8_t)(ENTITY_TLAYOUT_SSTATUS);
1616 trigger_layout ^= ((uint8_t)lua_tointeger(lua, 2)) << 7; // sector_status - 10000000
1617 ent->trigger_layout = trigger_layout;
1618 }
1619 }
1620
1621 return 0;
1622 }
1623
1624
lua_GetEntityOCB(lua_State * lua)1625 int lua_GetEntityOCB(lua_State * lua)
1626 {
1627 if(lua_gettop(lua) >= 1)
1628 {
1629 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1630 if(ent)
1631 {
1632 lua_pushinteger(lua, ent->OCB);
1633 return 1;
1634 }
1635 }
1636
1637 return 0; // No entity found - return.
1638 }
1639
1640
lua_SetEntityOCB(lua_State * lua)1641 int lua_SetEntityOCB(lua_State * lua)
1642 {
1643 if(lua_gettop(lua) >= 2)
1644 {
1645 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1646 if(ent)
1647 {
1648 ent->OCB = lua_tointeger(lua, 2);
1649 }
1650 }
1651
1652 return 0;
1653 }
1654
1655
lua_GetEntityFlags(lua_State * lua)1656 int lua_GetEntityFlags(lua_State * lua)
1657 {
1658 if(lua_gettop(lua) >= 1)
1659 {
1660 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1661 if(ent)
1662 {
1663 lua_pushinteger(lua, ent->state_flags);
1664 lua_pushinteger(lua, ent->type_flags);
1665 lua_pushinteger(lua, ent->callback_flags);
1666 return 3;
1667 }
1668 else
1669 {
1670 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
1671 }
1672 }
1673 else
1674 {
1675 Con_Warning("getEntityFlags: expecting arguments (entity_id)");
1676 }
1677
1678 return 0;
1679 }
1680
1681
lua_SetEntityFlags(lua_State * lua)1682 int lua_SetEntityFlags(lua_State * lua)
1683 {
1684 if(lua_gettop(lua) >= 4)
1685 {
1686 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1687 if(ent)
1688 {
1689 if(!lua_isnil(lua, 2))
1690 {
1691 ent->state_flags = lua_tointeger(lua, 2);
1692 if(ent->state_flags & ENTITY_STATE_COLLIDABLE)
1693 {
1694 Entity_EnableCollision(ent);
1695 }
1696 else
1697 {
1698 Entity_DisableCollision(ent);
1699 }
1700 }
1701 if(!lua_isnil(lua, 3))
1702 {
1703 ent->type_flags = lua_tointeger(lua, 3);
1704 }
1705 if(!lua_isnil(lua, 4))
1706 {
1707 ent->callback_flags = lua_tointeger(lua, 4);
1708 }
1709 }
1710 else
1711 {
1712 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
1713 }
1714 }
1715 else
1716 {
1717 Con_Warning("setEntityFlags: expecting arguments (entity_id, state_flags, type_flags, callback_flags)");
1718 }
1719
1720 return 0;
1721 }
1722
1723
lua_GetEntityTypeFlag(lua_State * lua)1724 int lua_GetEntityTypeFlag(lua_State *lua)
1725 {
1726 int top = lua_gettop(lua);
1727
1728 if(top >= 1)
1729 {
1730 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1731 if(ent)
1732 {
1733 if(top == 1)
1734 {
1735 lua_pushinteger(lua, ent->type_flags);
1736 }
1737 else
1738 {
1739 lua_pushinteger(lua, (ent->type_flags & (uint16_t)(lua_tointeger(lua, 2))));
1740 }
1741 return 1;
1742 }
1743 else
1744 {
1745 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
1746 }
1747 }
1748 else
1749 {
1750 Con_Warning("getEntityTypeFlag: expecting arguments (entity_id, (type_flag))");
1751 }
1752
1753 return 0;
1754 }
1755
1756
lua_SetEntityTypeFlag(lua_State * lua)1757 int lua_SetEntityTypeFlag(lua_State *lua)
1758 {
1759 int top = lua_gettop(lua);
1760
1761 if(top >= 2)
1762 {
1763 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1764 if(ent)
1765 {
1766 if(top == 2)
1767 {
1768 ent->type_flags ^= (uint16_t)lua_tointeger(lua, 2);
1769 }
1770 else
1771 {
1772 if(lua_tointeger(lua, 3) == 1)
1773 {
1774 ent->type_flags |= (uint16_t)lua_tointeger(lua, 2);
1775 }
1776 else
1777 {
1778 ent->type_flags &= ~(uint16_t)lua_tointeger(lua, 2);
1779 }
1780 }
1781 }
1782 else
1783 {
1784 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
1785 }
1786 }
1787 else
1788 {
1789 Con_Warning("setEntityTypeFlag: expecting arguments (entity_id, type_flag, (value))");
1790 }
1791
1792 return 0;
1793 }
1794
1795
lua_GetEntityStateFlag(lua_State * lua)1796 int lua_GetEntityStateFlag(lua_State *lua)
1797 {
1798 int top = lua_gettop(lua);
1799
1800 if(top >= 1)
1801 {
1802 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1803 if(ent)
1804 {
1805 if(top == 1)
1806 {
1807 lua_pushinteger(lua, ent->state_flags);
1808 }
1809 else
1810 {
1811 lua_pushinteger(lua, (ent->state_flags & (uint16_t)(lua_tointeger(lua, 2))));
1812 }
1813 return 1;
1814 }
1815 else
1816 {
1817 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
1818 }
1819 }
1820 else
1821 {
1822 Con_Warning("getEntityStateFlag: expecting arguments (entity_id, (state_flag))");
1823 }
1824
1825 return 0;
1826 }
1827
1828
lua_SetEntityStateFlag(lua_State * lua)1829 int lua_SetEntityStateFlag(lua_State *lua)
1830 {
1831 int top = lua_gettop(lua);
1832
1833 if(top >= 2)
1834 {
1835 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1836 if(ent)
1837 {
1838 if(top == 2)
1839 {
1840 ent->state_flags ^= (uint16_t)lua_tointeger(lua, 2);
1841 }
1842 else
1843 {
1844 if(lua_tointeger(lua, 3) == 1)
1845 {
1846 ent->state_flags |= (uint16_t)lua_tointeger(lua, 2);
1847 }
1848 else
1849 {
1850 ent->state_flags &= ~(uint16_t)lua_tointeger(lua, 2);
1851 }
1852 }
1853 }
1854 else
1855 {
1856 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
1857 }
1858 }
1859 else
1860 {
1861 Con_Warning("setEntityStateFlag: expecting arguments (entity_id, state_flag, (value))");
1862 }
1863
1864 return 0;
1865 }
1866
1867
lua_GetEntityCallbackFlag(lua_State * lua)1868 int lua_GetEntityCallbackFlag(lua_State *lua)
1869 {
1870 int top = lua_gettop(lua);
1871
1872 if(top >= 1)
1873 {
1874 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1875 if(ent)
1876 {
1877 if(top == 1)
1878 {
1879 lua_pushinteger(lua, ent->callback_flags);
1880 }
1881 else
1882 {
1883 lua_pushinteger(lua, (ent->callback_flags & (uint32_t)(lua_tointeger(lua, 2))));
1884 }
1885 return 1;
1886 }
1887 else
1888 {
1889 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
1890 }
1891 }
1892 else
1893 {
1894 Con_Warning("getEntityCallbackFlag: expecting arguments (entity_id, (callback_flag))");
1895 }
1896
1897 return 0;
1898 }
1899
1900
lua_SetEntityCallbackFlag(lua_State * lua)1901 int lua_SetEntityCallbackFlag(lua_State *lua)
1902 {
1903 int top = lua_gettop(lua);
1904
1905 if(top >= 2)
1906 {
1907 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1908 if(ent)
1909 {
1910 if(top == 2)
1911 {
1912 ent->callback_flags ^= (uint32_t)lua_tointeger(lua, 2);
1913 }
1914 else
1915 {
1916 if(lua_tointeger(lua, 3) == 1)
1917 {
1918 ent->callback_flags |= (uint16_t)lua_tointeger(lua, 2);
1919 }
1920 else
1921 {
1922 ent->callback_flags &= ~(uint32_t)lua_tointeger(lua, 2);
1923 }
1924 }
1925 }
1926 else
1927 {
1928 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
1929 }
1930 }
1931 else
1932 {
1933 Con_Warning("setEntityCallbackFlag: expecting arguments (entity_id, callback_flag, (value))");
1934 }
1935
1936 return 0;
1937 }
1938
1939
lua_GetEntityTimer(lua_State * lua)1940 int lua_GetEntityTimer(lua_State * lua)
1941 {
1942 if(lua_gettop(lua) >= 1)
1943 {
1944 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1945 if(ent)
1946 {
1947 lua_pushnumber(lua, ent->timer);
1948 return 1;
1949 }
1950 }
1951
1952 return 0;
1953 }
1954
1955
lua_SetEntityTimer(lua_State * lua)1956 int lua_SetEntityTimer(lua_State * lua)
1957 {
1958 if(lua_gettop(lua) >= 2)
1959 {
1960 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1961 if(ent)
1962 {
1963 ent->timer = lua_tonumber(lua, 2);
1964 }
1965 }
1966
1967 return 0;
1968 }
1969
1970
lua_GetEntityMoveType(lua_State * lua)1971 int lua_GetEntityMoveType(lua_State * lua)
1972 {
1973 if(lua_gettop(lua) >= 1)
1974 {
1975 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
1976 if(ent)
1977 {
1978 lua_pushinteger(lua, ent->move_type);
1979 return 1;
1980 }
1981 else
1982 {
1983 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
1984 }
1985 }
1986 else
1987 {
1988 Con_Warning("getEntityMoveType: expecting arguments (entity_id)");
1989 }
1990
1991 return 0;
1992 }
1993
1994
lua_SetEntityMoveType(lua_State * lua)1995 int lua_SetEntityMoveType(lua_State * lua)
1996 {
1997 if(lua_gettop(lua) >= 2)
1998 {
1999 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
2000 if(ent)
2001 {
2002 ent->move_type = lua_tointeger(lua, 2);
2003 }
2004 }
2005 else
2006 {
2007 Con_Warning("setEntityMoveType: expecting arguments (entity_id, move_type)");
2008 }
2009
2010 return 0;
2011 }
2012
2013
lua_SetEntityRoomMove(lua_State * lua)2014 int lua_SetEntityRoomMove(lua_State * lua)
2015 {
2016 if(lua_gettop(lua) >= 4)
2017 {
2018 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
2019 if(ent)
2020 {
2021 room_p room = NULL;
2022 if(!lua_isnil(lua, 2) && (room = World_GetRoomByID(lua_tointeger(lua, 2))))
2023 {
2024 if(ent->self->room != room)
2025 {
2026 if(ent->self->room != NULL)
2027 {
2028 Room_RemoveObject(ent->self->room, ent->self);
2029 }
2030 Room_AddObject(room, ent->self);
2031 }
2032 }
2033 Entity_UpdateRoomPos(ent);
2034
2035 if(!lua_isnil(lua, 3))
2036 {
2037 ent->move_type = lua_tointeger(lua, 3);
2038 }
2039 if(!lua_isnil(lua, 4))
2040 {
2041 ent->dir_flag = lua_tointeger(lua, 4);
2042 }
2043 }
2044 else
2045 {
2046 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
2047 }
2048 }
2049 else
2050 {
2051 Con_Warning("setEntityRoomMove: expecting arguments (entity_id, room_id, move_type, dir_flag)");
2052 }
2053
2054 return 0;
2055 }
2056
2057 /*
2058 * physics routine
2059 */
lua_SetEntityCollision(lua_State * lua)2060 int lua_SetEntityCollision(lua_State * lua)
2061 {
2062 int top = lua_gettop(lua);
2063
2064 if(top >= 1)
2065 {
2066 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
2067 if(ent)
2068 {
2069 if((top >= 2) && (lua_toboolean(lua, 2)))
2070 {
2071 Entity_EnableCollision(ent);
2072 }
2073 else
2074 {
2075 Entity_DisableCollision(ent);
2076 }
2077 }
2078 }
2079 else
2080 {
2081 Con_Warning("setEntityCollision: Expecting arguments (entity_id, val)");
2082 }
2083
2084 return 0;
2085 }
2086
2087
lua_SetEntityBoneCollision(lua_State * lua)2088 int lua_SetEntityBoneCollision(lua_State * lua)
2089 {
2090 int top = lua_gettop(lua);
2091
2092 if(top >= 3)
2093 {
2094 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
2095 if(ent)
2096 {
2097 Physics_SetBoneCollision(ent->physics, lua_tointeger(lua, 2), lua_tointeger(lua, 3));
2098 }
2099 }
2100 else
2101 {
2102 Con_Warning("setEntityBoneCollision: Expecting arguments (entity_id, bone_id, val)");
2103 }
2104
2105 return 0;
2106 }
2107
2108
lua_SetEntityGhostCollisionShape(lua_State * lua)2109 int lua_SetEntityGhostCollisionShape(lua_State * lua)
2110 {
2111 if(lua_gettop(lua) >= 9)
2112 {
2113 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
2114 if(ent)
2115 {
2116 uint16_t ghost_index = lua_tointeger(lua, 2);
2117 base_mesh_p mesh = ent->bf->bone_tags[ghost_index].mesh_base;
2118 ghost_shape_t shape;
2119 shape.shape_id = lua_tointeger(lua, 3);
2120 shape.bb_min[0] = (!lua_isnil(lua, 4) || !mesh) ? (lua_tonumber(lua, 4)) : (mesh->bb_min[0]);
2121 shape.bb_min[1] = (!lua_isnil(lua, 5) || !mesh) ? (lua_tonumber(lua, 5)) : (mesh->bb_min[1]);
2122 shape.bb_min[2] = (!lua_isnil(lua, 6) || !mesh) ? (lua_tonumber(lua, 6)) : (mesh->bb_min[2]);
2123 shape.bb_max[0] = (!lua_isnil(lua, 7) || !mesh) ? (lua_tonumber(lua, 7)) : (mesh->bb_max[0]);
2124 shape.bb_max[1] = (!lua_isnil(lua, 8) || !mesh) ? (lua_tonumber(lua, 8)) : (mesh->bb_max[1]);
2125 shape.bb_max[2] = (!lua_isnil(lua, 9) || !mesh) ? (lua_tonumber(lua, 9)) : (mesh->bb_max[2]);
2126 vec3_add(shape.offset, shape.bb_min, shape.bb_max);
2127 shape.offset[0] *= 0.5f;
2128 shape.offset[1] *= 0.5f;
2129 shape.offset[2] *= 0.5f;
2130 Physics_SetGhostCollisionShape(ent->physics, ent->bf, ghost_index, &shape);
2131 }
2132 else
2133 {
2134 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
2135 }
2136 }
2137 else
2138 {
2139 Con_Warning("setEntityGhostCollisionShape: expecting arguments (entity_id, shape_index, min_x, min_y, min_z, max_x, max_y, max_z)");
2140 }
2141
2142 return 0;
2143 }
2144
2145
lua_SetEntityCollisionFlags(lua_State * lua)2146 int lua_SetEntityCollisionFlags(lua_State * lua)
2147 {
2148 if(lua_gettop(lua) >= 4)
2149 {
2150 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
2151 if(ent)
2152 {
2153 if(!lua_isnil(lua, 2))
2154 {
2155 ent->self->collision_group = lua_tointeger(lua, 2);
2156 }
2157 if(!lua_isnil(lua, 3))
2158 {
2159 ent->self->collision_shape = lua_tointeger(lua, 3);
2160 }
2161 if(!lua_isnil(lua, 4))
2162 {
2163 ent->self->collision_mask = lua_tointeger(lua, 4);
2164 }
2165
2166 if(Physics_GetBodiesCount(ent->physics) != ent->bf->bone_tag_count)
2167 {
2168 ent->self->collision_shape = COLLISION_SHAPE_SINGLE_BOX;
2169 }
2170 }
2171 else
2172 {
2173 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
2174 }
2175 }
2176 else
2177 {
2178 Con_Warning("setEntityCollisionFlags: expecting arguments (entity_id, collision_group, collision_shape, collision_mask)");
2179 }
2180
2181 return 0;
2182 }
2183
2184
lua_SetEntityCollisionGroupAndMask(lua_State * lua)2185 int lua_SetEntityCollisionGroupAndMask(lua_State * lua)
2186 {
2187 if(lua_gettop(lua) >= 3)
2188 {
2189 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
2190 if(ent)
2191 {
2192 if(!lua_isnil(lua, 2))
2193 {
2194 ent->self->collision_group = lua_tointeger(lua, 2);
2195 }
2196 if(!lua_isnil(lua, 3))
2197 {
2198 ent->self->collision_mask = lua_tointeger(lua, 3);
2199 }
2200 Physics_SetCollisionGroupAndMask(ent->physics, ent->self->collision_group, ent->self->collision_mask);
2201 }
2202 else
2203 {
2204 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
2205 }
2206 }
2207 else
2208 {
2209 Con_Warning("setEntityCollisionGroupAndMask: expecting arguments (entity_id, collision_group, collision_mask)");
2210 }
2211
2212 return 0;
2213 }
2214
2215
lua_ResetRigidBodies(lua_State * lua)2216 int lua_ResetRigidBodies(lua_State * lua)
2217 {
2218 if(lua_gettop(lua) >= 1)
2219 {
2220 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
2221 if(ent)
2222 {
2223 Physics_GenRigidBody(ent->physics, ent->bf);
2224 }
2225 else
2226 {
2227 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
2228 }
2229 }
2230 else
2231 {
2232 Con_Warning("resetRigidBodies: expecting arguments (entity_id)");
2233 }
2234
2235 return 0;
2236 }
2237
2238
lua_CreateGhosts(lua_State * lua)2239 int lua_CreateGhosts(lua_State * lua)
2240 {
2241 if(lua_gettop(lua) >= 1)
2242 {
2243 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
2244 if(ent && !Physics_IsGhostsInited(ent->physics))
2245 {
2246 Physics_CreateGhosts(ent->physics, ent->bf, NULL);
2247 Entity_GhostUpdate(ent);
2248 }
2249 else
2250 {
2251 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
2252 }
2253 }
2254 else
2255 {
2256 Con_Warning("createGhosts: expecting arguments (entity_id)");
2257 }
2258
2259 return 0;
2260 }
2261
2262
lua_GetEntityGlobalMove(lua_State * lua)2263 int lua_GetEntityGlobalMove(lua_State * lua)
2264 {
2265 if(lua_gettop(lua) >= 4)
2266 {
2267 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
2268 if(ent)
2269 {
2270 float move[3], gmove[3];
2271 move[0] = lua_tonumber(lua, 2);
2272 move[1] = lua_tonumber(lua, 3);
2273 move[2] = lua_tonumber(lua, 4);
2274
2275 Mat4_vec3_rot_macro(gmove, ent->transform.M4x4, move);
2276
2277 lua_pushnumber(lua, gmove[0]);
2278 lua_pushnumber(lua, gmove[1]);
2279 lua_pushnumber(lua, gmove[2]);
2280 return 3;
2281 }
2282 else
2283 {
2284 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
2285 }
2286 }
2287 else
2288 {
2289 Con_Warning("getEntityGlobalMove: expecting arguments (entity_id, dx, dy, dz)");
2290 }
2291
2292 return 0;
2293 }
2294
2295
lua_GetEntityCollisionFix(lua_State * lua)2296 int lua_GetEntityCollisionFix(lua_State * lua)
2297 {
2298 if(lua_gettop(lua) >= 2)
2299 {
2300 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
2301 if(ent)
2302 {
2303 int16_t filter = lua_tointeger(lua, 2);
2304 float reaction[3] = {0.0f, 0.0f, 0.0f};
2305 Entity_GetPenetrationFixVector(ent, NULL, reaction, NULL, filter);
2306
2307 bool result = (reaction[0] != 0.0f) || (reaction[1] != 0.0f) || (reaction[2] != 0.0f);
2308 lua_pushboolean(lua, result);
2309 lua_pushnumber(lua, reaction[0]);
2310 lua_pushnumber(lua, reaction[1]);
2311 lua_pushnumber(lua, reaction[2]);
2312 return 4;
2313 }
2314 else
2315 {
2316 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
2317 }
2318 }
2319 else
2320 {
2321 Con_Warning("getEntityCollisionFix: expecting arguments (entity_id, filter)");
2322 }
2323
2324 return 0;
2325 }
2326
2327
lua_GetEntityMoveCollisionFix(lua_State * lua)2328 int lua_GetEntityMoveCollisionFix(lua_State * lua)
2329 {
2330 if(lua_gettop(lua) >= 5)
2331 {
2332 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
2333 if(ent)
2334 {
2335 int16_t filter = lua_tointeger(lua, 2);
2336 float reaction[3] = {0.0f, 0.0f, 0.0f};
2337 float move[3];
2338 move[0] = lua_tonumber(lua, 3);
2339 move[1] = lua_tonumber(lua, 4);
2340 move[2] = lua_tonumber(lua, 5);
2341
2342 Entity_CheckNextPenetration(ent, NULL, move, reaction, filter);
2343
2344 bool result = (reaction[0] != 0.0f) || (reaction[1] != 0.0f) || (reaction[2] != 0.0f);
2345 lua_pushboolean(lua, result);
2346 lua_pushnumber(lua, reaction[0]);
2347 lua_pushnumber(lua, reaction[1]);
2348 lua_pushnumber(lua, reaction[2]);
2349 return 4;
2350 }
2351 else
2352 {
2353 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
2354 }
2355 }
2356 else
2357 {
2358 Con_Warning("getEntityMoveCollisionFix: expecting arguments (entity_id, filter, dx, dy, dz)");
2359 }
2360
2361 return 0;
2362 }
2363
2364
lua_GetEntityRayTest(lua_State * lua)2365 int lua_GetEntityRayTest(lua_State * lua)
2366 {
2367 int top = lua_gettop(lua);
2368 if(top >= 5)
2369 {
2370 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
2371 if(ent)
2372 {
2373 int16_t filter = lua_tointeger(lua, 2);
2374 float from[3], to[3], move[3];
2375 collision_result_t cs;
2376
2377 vec3_copy(move, ent->bf->centre);
2378 if(top >= 8)
2379 {
2380 move[0] += lua_tonumber(lua, 6);
2381 move[1] += lua_tonumber(lua, 7);
2382 move[2] += lua_tonumber(lua, 8);
2383 }
2384 Mat4_vec3_mul_macro(from, ent->transform.M4x4, move);
2385
2386 move[0] = lua_tonumber(lua, 3);
2387 move[1] = lua_tonumber(lua, 4);
2388 move[2] = lua_tonumber(lua, 5);
2389 Mat4_vec3_rot_macro(to, ent->transform.M4x4, move);
2390
2391 to[0] += from[0];
2392 to[1] += from[1];
2393 to[2] += from[2];
2394
2395 bool result = Physics_RayTestFiltered(&cs, from, to, ent->self, filter);
2396 lua_pushboolean(lua, result);
2397 lua_pushnumber(lua, cs.fraction);
2398 lua_pushnumber(lua, cs.point[0]);
2399 lua_pushnumber(lua, cs.point[1]);
2400 lua_pushnumber(lua, cs.point[2]);
2401 return 5;
2402 }
2403 else
2404 {
2405 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
2406 }
2407 }
2408 else
2409 {
2410 Con_Warning("getEntityRayTest: expecting arguments (entity_id, filter, mx, my, mz, (dx, dy, dz))");
2411 }
2412
2413 return 0;
2414 }
2415
2416
lua_GetEntitySphereTest(lua_State * lua)2417 int lua_GetEntitySphereTest(lua_State * lua)
2418 {
2419 int top = lua_gettop(lua);
2420 if(top >= 6)
2421 {
2422 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
2423 if(ent)
2424 {
2425 int16_t filter = lua_tointeger(lua, 2);
2426 float r = lua_tointeger(lua, 3);
2427 float from[3], to[3], move[3];
2428 collision_result_t cs;
2429
2430 vec3_copy(move, ent->bf->centre);
2431 if(top >= 9)
2432 {
2433 move[0] += lua_tonumber(lua, 7);
2434 move[1] += lua_tonumber(lua, 8);
2435 move[2] += lua_tonumber(lua, 9);
2436 }
2437 Mat4_vec3_mul_macro(from, ent->transform.M4x4, move);
2438
2439 move[0] = lua_tonumber(lua, 4);
2440 move[1] = lua_tonumber(lua, 5);
2441 move[2] = lua_tonumber(lua, 6);
2442 Mat4_vec3_rot_macro(to, ent->transform.M4x4, move);
2443
2444 to[0] += from[0];
2445 to[1] += from[1];
2446 to[2] += from[2];
2447
2448 bool result = Physics_SphereTest(&cs, from, to, r, ent->self, filter);
2449 lua_pushboolean(lua, result);
2450 lua_pushnumber(lua, cs.fraction);
2451 lua_pushnumber(lua, cs.point[0]);
2452 lua_pushnumber(lua, cs.point[1]);
2453 lua_pushnumber(lua, cs.point[2]);
2454 return 5;
2455 }
2456 else
2457 {
2458 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
2459 }
2460 }
2461 else
2462 {
2463 Con_Warning("getEntitySphereTest: expecting arguments (entity_id, filter, r, mx, my, mz, (dx, dy, dz))");
2464 }
2465
2466 return 0;
2467 }
2468
2469
lua_DropEntity(lua_State * lua)2470 int lua_DropEntity(lua_State * lua)
2471 {
2472 int top = lua_gettop(lua);
2473
2474 if(top >= 2)
2475 {
2476 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
2477 if(ent)
2478 {
2479 bool only_room = (top > 2) ? (lua_toboolean(lua, 3)) : (false);
2480 int16_t filter = ((only_room) ? (COLLISION_GROUP_STATIC_ROOM) : ent->self->collision_mask);
2481 float move[3], g[3], t, time = lua_tonumber(lua, 2);
2482 float from[3], to[3];
2483 collision_result_t cb;
2484
2485 Physics_GetGravity(g);
2486 vec3_mul_scalar(move, ent->speed, time);
2487 t = 0.5f * time * time;
2488 vec3_add_mul(move, move, g, t);
2489 ent->speed[0] += g[0] * time;
2490 ent->speed[1] += g[1] * time;
2491 ent->speed[2] += g[2] * time;
2492
2493 Mat4_vec3_mul_macro(from, ent->transform.M4x4, ent->bf->centre);
2494 vec3_add(to, from, move);
2495 from[2] += 32.0f;
2496 to[2] -= (ent->bf->bb_max[2] - ent->bf->bb_min[2]);
2497
2498 if(Physics_RayTestFiltered(&cb, from, to, ent->self, filter))
2499 {
2500 lua_pushboolean(lua, ent->transform.M4x4[12 + 2] < cb.point[2] + 1.0f);
2501 ent->transform.M4x4[12 + 2] = cb.point[2];
2502 vec3_set_zero(ent->speed);
2503 }
2504 else
2505 {
2506 vec3_add_to(ent->transform.M4x4 + 12, move);
2507 lua_pushboolean(lua, false);
2508 }
2509 Entity_UpdateRigidBody(ent, 1);
2510 return 1;
2511 }
2512 else
2513 {
2514 Con_Warning("no entity with id = %d", lua_tointeger(lua, 1));
2515 }
2516 }
2517 else
2518 {
2519 Con_Warning("dropEntity: expecting arguments (entity_id, time, (only_room))");
2520 }
2521
2522 return 0;
2523 }
2524
2525
lua_PushEntityBody(lua_State * lua)2526 int lua_PushEntityBody(lua_State *lua)
2527 {
2528 if(lua_gettop(lua) >= 5)
2529 {
2530 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
2531 int body_number = lua_tointeger(lua, 2);
2532 if(ent && (body_number < ent->bf->bone_tag_count) && (ent->type_flags & ENTITY_TYPE_DYNAMIC))
2533 {
2534 float h_force = lua_tonumber(lua, 3);
2535 float t = ent->transform.angles[0] * M_PI / 180.0;
2536 float speed[3];
2537
2538 speed[0] = -sinf(t) * h_force;
2539 speed[1] = cosf(t) * h_force;
2540 speed[2] = lua_tonumber(lua, 4);
2541
2542 Physics_PushBody(ent->physics, speed, body_number);
2543 }
2544 else
2545 {
2546 Con_Printf("Can't apply force to entity %d - no entity, body, or entity is not kinematic!", lua_tointeger(lua, 1));
2547 }
2548 }
2549 else
2550 {
2551 Con_Printf("pushEntityBody: expecting arguments (entity_id, body_number, h_force, v_force, reset_flag)");
2552 }
2553
2554 return 0;
2555 }
2556
2557
lua_SetEntityBodyMass(lua_State * lua)2558 int lua_SetEntityBodyMass(lua_State *lua)
2559 {
2560 int top = lua_gettop(lua);
2561
2562 if(lua_gettop(lua) >= 3)
2563 {
2564 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
2565 int body_number = lua_tointeger(lua, 2);
2566 body_number = (body_number < 1) ? (1) : (body_number);
2567
2568 if(ent && (ent->bf->bone_tag_count >= body_number))
2569 {
2570 uint16_t argn = 3;
2571 bool dynamic = false;
2572 float mass = 0.0;
2573
2574 for(int i = 0; i < body_number; i++)
2575 {
2576 if(top >= argn) mass = lua_tonumber(lua, argn++);
2577 if(mass > 0.0) dynamic = true;
2578 Physics_SetBodyMass(ent->physics, mass, i);
2579 }
2580 Entity_UpdateRigidBody(ent, 1);
2581
2582 if(dynamic)
2583 {
2584 ent->type_flags |= ENTITY_TYPE_DYNAMIC;
2585 }
2586 else
2587 {
2588 ent->type_flags &= ~ENTITY_TYPE_DYNAMIC;
2589 }
2590 }
2591 else
2592 {
2593 Con_Printf("Can't find entity %d or body number is more than %d", lua_tointeger(lua, 1), body_number);
2594 }
2595 }
2596 else
2597 {
2598 Con_Printf("setEntityBodyMass: expecting arguments (entity_id, body_number, (mass / each body mass))");
2599 }
2600
2601 return 0;
2602 }
2603
2604
lua_LockEntityBodyLinearFactor(lua_State * lua)2605 int lua_LockEntityBodyLinearFactor(lua_State *lua)
2606 {
2607 int top = lua_gettop(lua);
2608
2609 if(top >= 2)
2610 {
2611 entity_p ent = World_GetEntityByID(lua_tointeger(lua, 1));
2612 int body_number = lua_tointeger(lua, 2);
2613 if(ent && (body_number < ent->bf->bone_tag_count) && (ent->type_flags & ENTITY_TYPE_DYNAMIC))
2614 {
2615 float factor[3], t = ent->transform.angles[0] * M_PI / 180.0;
2616 factor[0] = fabs(sinf(t));
2617 factor[1] = fabs(cosf(t));
2618 factor[2] = 1.0;
2619
2620 if(top >= 3)
2621 {
2622 factor[2] = fabs(lua_tonumber(lua, 3));
2623 factor[2] = (factor[2] > 1.0) ? (1.0) : (factor[2]);
2624 }
2625 Physics_SetLinearFactor(ent->physics, factor, body_number);
2626 }
2627 else
2628 {
2629 Con_Printf("Can't apply force to entity %d - no entity, body, or entity is not dynamic!", lua_tointeger(lua, 1));
2630 }
2631 }
2632 else
2633 {
2634 Con_Printf("lockEntityBodyLinearFactor: expecting arguments (entity_id, body_number, (vertical_factor))");
2635 }
2636
2637 return 0;
2638 }
2639
2640
Script_LuaRegisterEntityFuncs(lua_State * lua)2641 void Script_LuaRegisterEntityFuncs(lua_State *lua)
2642 {
2643 lua_register(lua, "addItem", lua_AddItem);
2644 lua_register(lua, "removeItem", lua_RemoveItem);
2645 lua_register(lua, "removeAllItems", lua_RemoveAllItems);
2646 lua_register(lua, "getItemsCount", lua_GetItemsCount);
2647 lua_register(lua, "getItems", lua_GetItems);
2648
2649 lua_register(lua, "canTriggerEntity", lua_CanTriggerEntity);
2650 lua_register(lua, "entityRotateToTriggerZ", lua_EntityRotateToTriggerZ);
2651 lua_register(lua, "entityRotateToTrigger", lua_EntityRotateToTrigger);
2652 lua_register(lua, "entityMoveToTriggerActivationPoint", lua_EntityMoveToTriggerActivationPoint);
2653 lua_register(lua, "enableEntity", lua_EnableEntity);
2654 lua_register(lua, "disableEntity", lua_DisableEntity);
2655
2656 lua_register(lua, "activateEntity", lua_ActivateEntity);
2657 lua_register(lua, "deactivateEntity", lua_DeactivateEntity);
2658 lua_register(lua, "noFixEntityCollision", lua_NoFixEntityCollision);
2659 lua_register(lua, "noEntityMove", lua_NoEntityMove);
2660
2661 lua_register(lua, "moveEntityGlobal", lua_MoveEntityGlobal);
2662 lua_register(lua, "moveEntityLocal", lua_MoveEntityLocal);
2663 lua_register(lua, "moveEntityToSink", lua_MoveEntityToSink);
2664 lua_register(lua, "moveEntityToEntity", lua_MoveEntityToEntity);
2665 lua_register(lua, "rotateEntity", lua_RotateEntity);
2666
2667 lua_register(lua, "getEntityVector", lua_GetEntityVector);
2668 lua_register(lua, "getEntityDirDot", lua_GetEntityDirDot);
2669 lua_register(lua, "getEntityDistance", lua_GetEntityDistance);
2670 lua_register(lua, "getEntityRoom", lua_GetEntityRoom);
2671 lua_register(lua, "getEntityPos", lua_GetEntityPosition);
2672 lua_register(lua, "setEntityPos", lua_SetEntityPosition);
2673 lua_register(lua, "getEntityAngles", lua_GetEntityAngles);
2674 lua_register(lua, "setEntityAngles", lua_SetEntityAngles);
2675 lua_register(lua, "getEntityScaling", lua_GetEntityScaling);
2676 lua_register(lua, "setEntityScaling", lua_SetEntityScaling);
2677 lua_register(lua, "getEntitySpeed", lua_GetEntitySpeed);
2678 lua_register(lua, "setEntitySpeed", lua_SetEntitySpeed);
2679 lua_register(lua, "setEntityLinearSpeed", lua_SetEntityLinearSpeed);
2680 lua_register(lua, "getEntitySpeedLinear", lua_GetEntitySpeedLinear);
2681 lua_register(lua, "setEntityBodyPartFlag", lua_SetEntityBodyPartFlag);
2682 lua_register(lua, "getEntityVisibility", lua_GetEntityVisibility);
2683 lua_register(lua, "setEntityVisibility", lua_SetEntityVisibility);
2684 lua_register(lua, "getEntityActivity", lua_GetEntityActivity);
2685 lua_register(lua, "setEntityActivity", lua_SetEntityActivity);
2686 lua_register(lua, "getEntityEnability", lua_GetEntityEnability);
2687 lua_register(lua, "getEntityOCB", lua_GetEntityOCB);
2688 lua_register(lua, "setEntityOCB", lua_SetEntityOCB);
2689 lua_register(lua, "getEntityTimer", lua_GetEntityTimer);
2690 lua_register(lua, "setEntityTimer", lua_SetEntityTimer);
2691 lua_register(lua, "getEntityFlags", lua_GetEntityFlags);
2692 lua_register(lua, "setEntityFlags", lua_SetEntityFlags);
2693 lua_register(lua, "getEntityTypeFlag", lua_GetEntityTypeFlag);
2694 lua_register(lua, "setEntityTypeFlag", lua_SetEntityTypeFlag);
2695 lua_register(lua, "getEntityStateFlag", lua_GetEntityStateFlag);
2696 lua_register(lua, "setEntityStateFlag", lua_SetEntityStateFlag);
2697 lua_register(lua, "getEntityCallbackFlag", lua_GetEntityCallbackFlag);
2698 lua_register(lua, "setEntityCallbackFlag", lua_SetEntityCallbackFlag);
2699 lua_register(lua, "setEntityRoomMove", lua_SetEntityRoomMove);
2700 lua_register(lua, "getEntityMoveType", lua_GetEntityMoveType);
2701 lua_register(lua, "setEntityMoveType", lua_SetEntityMoveType);
2702
2703 lua_register(lua, "getEntityTriggerLayout", lua_GetEntityTriggerLayout);
2704 lua_register(lua, "setEntityTriggerLayout", lua_SetEntityTriggerLayout);
2705 lua_register(lua, "getEntityMask", lua_GetEntityMask);
2706 lua_register(lua, "setEntityMask", lua_SetEntityMask);
2707 lua_register(lua, "getEntityEvent", lua_GetEntityEvent);
2708 lua_register(lua, "setEntityEvent", lua_SetEntityEvent);
2709 lua_register(lua, "getEntityLock", lua_GetEntityLock);
2710 lua_register(lua, "setEntityLock", lua_SetEntityLock);
2711 lua_register(lua, "getEntitySectorStatus", lua_GetEntitySectorStatus);
2712 lua_register(lua, "setEntitySectorStatus", lua_SetEntitySectorStatus);
2713
2714 lua_register(lua, "getEntityActivationOffset", lua_GetEntityActivationOffset);
2715 lua_register(lua, "setEntityActivationOffset", lua_SetEntityActivationOffset);
2716 lua_register(lua, "getEntityActivationDirection", lua_GetEntityActivationDirection);
2717 lua_register(lua, "setEntityActivationDirection", lua_SetEntityActivationDirection);
2718 lua_register(lua, "getEntitySectorIndex", lua_GetEntitySectorIndex);
2719 lua_register(lua, "getEntitySectorFlags", lua_GetEntitySectorFlags);
2720 lua_register(lua, "getEntitySectorMaterial", lua_GetEntitySectorMaterial);
2721 lua_register(lua, "getEntityBoxID", lua_GetEntityBoxID);
2722
2723 lua_register(lua, "setEntityCollision", lua_SetEntityCollision);
2724 lua_register(lua, "setEntityBoneCollision", lua_SetEntityBoneCollision);
2725 lua_register(lua, "setEntityGhostCollisionShape", lua_SetEntityGhostCollisionShape);
2726 lua_register(lua, "setEntityCollisionFlags", lua_SetEntityCollisionFlags);
2727 lua_register(lua, "setEntityCollisionGroupAndMask", lua_SetEntityCollisionGroupAndMask);
2728 lua_register(lua, "resetRigidBodies", lua_ResetRigidBodies);
2729 lua_register(lua, "createGhosts", lua_CreateGhosts);
2730 lua_register(lua, "getEntityGlobalMove", lua_GetEntityGlobalMove);
2731 lua_register(lua, "getEntityCollisionFix", lua_GetEntityCollisionFix);
2732 lua_register(lua, "getEntityMoveCollisionFix", lua_GetEntityMoveCollisionFix);
2733 lua_register(lua, "getEntityRayTest", lua_GetEntityRayTest);
2734 lua_register(lua, "getEntitySphereTest", lua_GetEntitySphereTest);
2735 lua_register(lua, "dropEntity", lua_DropEntity);
2736 lua_register(lua, "setEntityBodyMass", lua_SetEntityBodyMass);
2737 lua_register(lua, "pushEntityBody", lua_PushEntityBody);
2738 lua_register(lua, "lockEntityBodyLinearFactor", lua_LockEntityBodyLinearFactor);
2739 }
2740