1
1
#include " gs_level.h"
2
+ #include " gs_player.h"
2
3
#include " scriptObject.h"
3
4
#include " scriptSector.h"
4
5
#include < angelscript.h>
14
15
#include < TFE_ForceScript/scriptAPI.h>
15
16
#include < TFE_Jedi/Level/levelData.h>
16
17
#include < TFE_Jedi/Collision/collision.h>
18
+ #include < TFE_Jedi/Memory/allocator.h>
17
19
18
20
namespace TFE_DarkForces
19
21
{
22
+ // The "special" actors can all be cast to this struct (eg. bosses, dark troopers, mousebot, turret)
23
+ struct SpecialActor
24
+ {
25
+ Logic logic;
26
+ PhysicsActor actor;
27
+ };
28
+
20
29
bool isScriptObjectValid (ScriptObject* sObject )
21
30
{
22
31
return sObject ->m_id >= 0 && sObject ->m_id < s_objectRefList.size ();
@@ -278,6 +287,7 @@ namespace TFE_DarkForces
278
287
if (s_nightVisionActive) { disableNightVision (); }
279
288
}
280
289
290
+
281
291
void sendMessageToObject (MessageType messageType, ScriptObject* sObject )
282
292
{
283
293
if (!doesObjectExist (sObject )) { return ; }
@@ -286,6 +296,288 @@ namespace TFE_DarkForces
286
296
message_sendToObj (obj, messageType, actor_messageFunc);
287
297
}
288
298
299
+ // ////////////////////////////////////////////////////
300
+ // Logic related functionality
301
+ // ////////////////////////////////////////////////////
302
+
303
+ // Helper function - gets the first Dispatch actor linked to an object
304
+ ActorDispatch* getDispatch (SecObject* obj)
305
+ {
306
+ Logic** logicPtr = (Logic**)allocator_getHead ((Allocator*)obj->logic );
307
+ while (logicPtr)
308
+ {
309
+ Logic* logic = *logicPtr;
310
+ if (logic->type == LOGIC_DISPATCH)
311
+ {
312
+ return (ActorDispatch*)logic;
313
+ }
314
+ logicPtr = (Logic**)allocator_getNext ((Allocator*)obj->logic );
315
+ }
316
+
317
+ return nullptr ;
318
+ }
319
+
320
+ // Helper function - gets the damage module from a dispatch logic
321
+ DamageModule* getDamageModule (ActorDispatch* dispatch)
322
+ {
323
+ for (s32 i = 0 ; i < ACTOR_MAX_MODULES; i++)
324
+ {
325
+ ActorModule* module = dispatch->modules [ACTOR_MAX_MODULES - 1 - i];
326
+ if (module && module ->type == ACTMOD_DAMAGE)
327
+ {
328
+ return (DamageModule*)module ;
329
+ }
330
+ }
331
+
332
+ return nullptr ;
333
+ }
334
+
335
+ // Helper function - gets the attack module from a dispatch logic
336
+ AttackModule* getAttackModule (ActorDispatch* dispatch)
337
+ {
338
+ for (s32 i = 0 ; i < ACTOR_MAX_MODULES; i++)
339
+ {
340
+ ActorModule* module = dispatch->modules [ACTOR_MAX_MODULES - 1 - i];
341
+ if (module && module ->type == ACTMOD_ATTACK)
342
+ {
343
+ return (AttackModule*)module ;
344
+ }
345
+ }
346
+
347
+ return nullptr ;
348
+ }
349
+
350
+ int getHitPoints (ScriptObject* sObject )
351
+ {
352
+ if (!doesObjectExist (sObject )) { return -1 ; }
353
+ SecObject* obj = TFE_Jedi::s_objectRefList[sObject ->m_id ].object ;
354
+
355
+ // First try to find a dispatch logic
356
+ ActorDispatch* dispatch = getDispatch (obj);
357
+ if (dispatch)
358
+ {
359
+ DamageModule* damageMod = getDamageModule (dispatch);
360
+ if (damageMod)
361
+ {
362
+ return floor16 (damageMod->hp );
363
+ }
364
+ }
365
+
366
+ // Then try other logics
367
+ Logic** logicPtr = (Logic**)allocator_getHead ((Allocator*)obj->logic );
368
+ while (logicPtr)
369
+ {
370
+ Logic* logic = *logicPtr;
371
+ PhysicsActor* actor = nullptr ;
372
+
373
+ switch (logic->type )
374
+ {
375
+ case LOGIC_BOBA_FETT:
376
+ case LOGIC_DRAGON:
377
+ case LOGIC_PHASE_ONE:
378
+ case LOGIC_PHASE_TWO:
379
+ case LOGIC_PHASE_THREE:
380
+ case LOGIC_TURRET:
381
+ case LOGIC_WELDER:
382
+ case LOGIC_MOUSEBOT:
383
+ SpecialActor* data = (SpecialActor*)logic;
384
+ actor = &data->actor ;
385
+ break ;
386
+ }
387
+
388
+ if (actor)
389
+ {
390
+ return floor16 (actor->hp );
391
+ }
392
+
393
+ logicPtr = (Logic**)allocator_getNext ((Allocator*)obj->logic );
394
+ }
395
+
396
+ return -1 ;
397
+ }
398
+
399
+ void setHitPoints (int hitpoints, ScriptObject* sObject )
400
+ {
401
+ if (!doesObjectExist (sObject )) { return ; }
402
+ SecObject* obj = TFE_Jedi::s_objectRefList[sObject ->m_id ].object ;
403
+
404
+ // First try to find a dispatch logic
405
+ ActorDispatch* dispatch = getDispatch (obj);
406
+ if (dispatch)
407
+ {
408
+ DamageModule* damageMod = getDamageModule (dispatch);
409
+ if (damageMod)
410
+ {
411
+ damageMod->hp = FIXED (hitpoints);
412
+ return ;
413
+ }
414
+ }
415
+
416
+ // Then try other logics
417
+ Logic** logicPtr = (Logic**)allocator_getHead ((Allocator*)obj->logic );
418
+ while (logicPtr)
419
+ {
420
+ Logic* logic = *logicPtr;
421
+ PhysicsActor* actor = nullptr ;
422
+
423
+ switch (logic->type )
424
+ {
425
+ case LOGIC_BOBA_FETT:
426
+ case LOGIC_DRAGON:
427
+ case LOGIC_PHASE_ONE:
428
+ case LOGIC_PHASE_TWO:
429
+ case LOGIC_PHASE_THREE:
430
+ case LOGIC_TURRET:
431
+ case LOGIC_WELDER:
432
+ case LOGIC_MOUSEBOT:
433
+ SpecialActor* data = (SpecialActor*)logic;
434
+ actor = &data->actor ;
435
+ break ;
436
+ }
437
+
438
+ if (actor)
439
+ {
440
+ actor->hp = FIXED (hitpoints);
441
+ return ;
442
+ }
443
+
444
+ logicPtr = (Logic**)allocator_getNext ((Allocator*)obj->logic );
445
+ }
446
+ }
447
+
448
+ void setProjectile (ProjectileType projectile, ScriptObject* sObject )
449
+ {
450
+ if (!doesObjectExist (sObject )) { return ; }
451
+ SecObject* obj = TFE_Jedi::s_objectRefList[sObject ->m_id ].object ;
452
+
453
+ ActorDispatch* dispatch = getDispatch (obj);
454
+ if (dispatch)
455
+ {
456
+ AttackModule* attackMod = getAttackModule (dispatch);
457
+ if (attackMod)
458
+ {
459
+ attackMod->projType = projectile;
460
+ }
461
+ }
462
+ }
463
+
464
+ vec3_float getVelocity (ScriptObject* sObject )
465
+ {
466
+ if (!doesObjectExist (sObject )) { return { 0 , 0 , 0 ,}; }
467
+ SecObject* obj = TFE_Jedi::s_objectRefList[sObject ->m_id ].object ;
468
+
469
+ // Is it the player?
470
+ if (obj->entityFlags & ETFLAG_PLAYER)
471
+ {
472
+ return getPlayerVelocity ();
473
+ }
474
+
475
+ // First try to find a dispatch logic
476
+ ActorDispatch* dispatch = getDispatch (obj);
477
+ if (dispatch)
478
+ {
479
+ return
480
+ {
481
+ fixed16ToFloat (dispatch->vel .x ),
482
+ -fixed16ToFloat (dispatch->vel .y ),
483
+ fixed16ToFloat (dispatch->vel .z )
484
+ };
485
+ }
486
+
487
+ // Then try other logics
488
+ Logic** logicPtr = (Logic**)allocator_getHead ((Allocator*)obj->logic );
489
+ while (logicPtr)
490
+ {
491
+ Logic* logic = *logicPtr;
492
+ PhysicsActor* actor = nullptr ;
493
+
494
+ switch (logic->type )
495
+ {
496
+ case LOGIC_BOBA_FETT:
497
+ case LOGIC_DRAGON:
498
+ case LOGIC_PHASE_ONE:
499
+ case LOGIC_PHASE_TWO:
500
+ case LOGIC_PHASE_THREE:
501
+ case LOGIC_TURRET:
502
+ case LOGIC_WELDER:
503
+ case LOGIC_MOUSEBOT:
504
+ SpecialActor* data = (SpecialActor*)logic;
505
+ actor = &data->actor ;
506
+ break ;
507
+ }
508
+
509
+ if (actor)
510
+ {
511
+ return
512
+ {
513
+ fixed16ToFloat (actor->vel .x ),
514
+ -fixed16ToFloat (actor->vel .y ),
515
+ fixed16ToFloat (actor->vel .z )
516
+ };
517
+ }
518
+
519
+ logicPtr = (Logic**)allocator_getNext ((Allocator*)obj->logic );
520
+ }
521
+
522
+ return { 0 , 0 , 0 };
523
+ }
524
+
525
+ void setVelocity (vec3_float vel, ScriptObject* sObject )
526
+ {
527
+ if (!doesObjectExist (sObject )) { return ; }
528
+ SecObject* obj = TFE_Jedi::s_objectRefList[sObject ->m_id ].object ;
529
+
530
+ // Is it the player?
531
+ if (obj->entityFlags & ETFLAG_PLAYER)
532
+ {
533
+ setPlayerVelocity (vel);
534
+ return ;
535
+ }
536
+
537
+ // First try to find a dispatch logic
538
+ ActorDispatch* dispatch = getDispatch (obj);
539
+ if (dispatch)
540
+ {
541
+ dispatch->vel .x = floatToFixed16 (vel.x );
542
+ dispatch->vel .y = -floatToFixed16 (vel.y );
543
+ dispatch->vel .z = floatToFixed16 (vel.z );
544
+ return ;
545
+ }
546
+
547
+ // Then try other logics
548
+ Logic** logicPtr = (Logic**)allocator_getHead ((Allocator*)obj->logic );
549
+ while (logicPtr)
550
+ {
551
+ Logic* logic = *logicPtr;
552
+ PhysicsActor* actor = nullptr ;
553
+
554
+ switch (logic->type )
555
+ {
556
+ case LOGIC_BOBA_FETT:
557
+ case LOGIC_DRAGON:
558
+ case LOGIC_PHASE_ONE:
559
+ case LOGIC_PHASE_TWO:
560
+ case LOGIC_PHASE_THREE:
561
+ case LOGIC_TURRET:
562
+ case LOGIC_WELDER:
563
+ case LOGIC_MOUSEBOT:
564
+ SpecialActor* data = (SpecialActor*)logic;
565
+ actor = &data->actor ;
566
+ break ;
567
+ }
568
+
569
+ if (actor)
570
+ {
571
+ actor->vel .x = floatToFixed16 (vel.x );
572
+ actor->vel .y = -floatToFixed16 (vel.y );
573
+ actor->vel .z = floatToFixed16 (vel.z );
574
+ return ;
575
+ }
576
+
577
+ logicPtr = (Logic**)allocator_getNext ((Allocator*)obj->logic );
578
+ }
579
+ }
580
+
289
581
void ScriptObject::registerType ()
290
582
{
291
583
s32 res = 0 ;
@@ -295,6 +587,28 @@ namespace TFE_DarkForces
295
587
// Variables
296
588
ScriptMemberVariable (" int id" , m_id);
297
589
590
+ // Enums
591
+ ScriptEnumRegister (" Projectiles" );
592
+ ScriptEnumStr (PROJ_PUNCH);
593
+ ScriptEnumStr (PROJ_PISTOL_BOLT);
594
+ ScriptEnumStr (PROJ_RIFLE_BOLT);
595
+ ScriptEnumStr (PROJ_THERMAL_DET);
596
+ ScriptEnumStr (PROJ_REPEATER);
597
+ ScriptEnumStr (PROJ_PLASMA);
598
+ ScriptEnumStr (PROJ_MORTAR);
599
+ ScriptEnumStr (PROJ_LAND_MINE);
600
+ ScriptEnumStr (PROJ_LAND_MINE_PROX);
601
+ ScriptEnumStr (PROJ_LAND_MINE_PLACED);
602
+ ScriptEnumStr (PROJ_CONCUSSION);
603
+ ScriptEnumStr (PROJ_CANNON);
604
+ ScriptEnumStr (PROJ_MISSILE);
605
+ ScriptEnumStr (PROJ_TURRET_BOLT);
606
+ ScriptEnumStr (PROJ_REMOTE_BOLT);
607
+ ScriptEnumStr (PROJ_EXP_BARREL);
608
+ ScriptEnumStr (PROJ_HOMING_MISSILE);
609
+ ScriptEnumStr (PROJ_PROBE_PROJ);
610
+ ScriptEnum (" PROJ_BOBAFETT_BALL" , PROJ_BOBAFET_BALL);
611
+
298
612
// Checks
299
613
ScriptObjFunc (" bool isValid()" , isScriptObjectValid);
300
614
ScriptObjFunc (" bool exists()" , doesObjectExist);
@@ -323,6 +637,13 @@ namespace TFE_DarkForces
323
637
ScriptObjFunc (" void delete()" , deleteObject);
324
638
ScriptObjFunc (" void addLogic(string)" , addLogicToObject);
325
639
ScriptObjFunc (" void setCamera()" , setCamera);
326
- ScriptObjFunc (" void sendMessage(int)" , sendMessageToObject)
640
+ ScriptObjFunc (" void sendMessage(int)" , sendMessageToObject);
641
+
642
+ // Logic getters & setters
643
+ ScriptPropertyGetFunc (" int get_hitPoints()" , getHitPoints);
644
+ ScriptPropertySetFunc (" void set_hitPoints(int)" , setHitPoints);
645
+ ScriptPropertySetFunc (" void set_projectile(int)" , setProjectile);
646
+ ScriptPropertyGetFunc (" float3 get_velocity()" , getVelocity);
647
+ ScriptPropertySetFunc (" void set_velocity(float3)" , setVelocity);
327
648
}
328
649
}
0 commit comments