Skip to content

Commit d1ba47e

Browse files
jerethkKarjala22
authored andcommitted
Object Scripting - manipulate logic data (luciusDXL#568)
* Get logic hitpoints * Set hitpoints and projectile * Get and set Velocity
1 parent 664464e commit d1ba47e

File tree

3 files changed

+326
-2
lines changed

3 files changed

+326
-2
lines changed

TheForceEngine/TFE_DarkForces/Scripting/gs_player.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#include "gs_player.h"
22
#include "assert.h"
3-
#include <TFE_DarkForces/player.h>
43
#include <TFE_DarkForces/mission.h>
54
#include <TFE_DarkForces/pickup.h>
65
#include <TFE_DarkForces/weapon.h>

TheForceEngine/TFE_DarkForces/Scripting/gs_player.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22
#include <TFE_System/system.h>
33
#include <TFE_System/types.h>
4+
#include <TFE_DarkForces/player.h>
45
#include <TFE_ForceScript/scriptInterface.h>
56
#include <string>
67

@@ -11,4 +12,7 @@ namespace TFE_DarkForces
1112
public:
1213
bool scriptRegister(ScriptAPI api) override;
1314
};
15+
16+
vec3_float getPlayerVelocity();
17+
void setPlayerVelocity(vec3_float vel);
1418
}

TheForceEngine/TFE_DarkForces/Scripting/scriptObject.cpp

Lines changed: 322 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "gs_level.h"
2+
#include "gs_player.h"
23
#include "scriptObject.h"
34
#include "scriptSector.h"
45
#include <angelscript.h>
@@ -14,9 +15,17 @@
1415
#include <TFE_ForceScript/scriptAPI.h>
1516
#include <TFE_Jedi/Level/levelData.h>
1617
#include <TFE_Jedi/Collision/collision.h>
18+
#include <TFE_Jedi/Memory/allocator.h>
1719

1820
namespace TFE_DarkForces
1921
{
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+
2029
bool isScriptObjectValid(ScriptObject* sObject)
2130
{
2231
return sObject->m_id >= 0 && sObject->m_id < s_objectRefList.size();
@@ -278,6 +287,7 @@ namespace TFE_DarkForces
278287
if (s_nightVisionActive) { disableNightVision(); }
279288
}
280289

290+
281291
void sendMessageToObject(MessageType messageType, ScriptObject* sObject)
282292
{
283293
if (!doesObjectExist(sObject)) { return; }
@@ -286,6 +296,288 @@ namespace TFE_DarkForces
286296
message_sendToObj(obj, messageType, actor_messageFunc);
287297
}
288298

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+
289581
void ScriptObject::registerType()
290582
{
291583
s32 res = 0;
@@ -295,6 +587,28 @@ namespace TFE_DarkForces
295587
// Variables
296588
ScriptMemberVariable("int id", m_id);
297589

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+
298612
// Checks
299613
ScriptObjFunc("bool isValid()", isScriptObjectValid);
300614
ScriptObjFunc("bool exists()", doesObjectExist);
@@ -323,6 +637,13 @@ namespace TFE_DarkForces
323637
ScriptObjFunc("void delete()", deleteObject);
324638
ScriptObjFunc("void addLogic(string)", addLogicToObject);
325639
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);
327648
}
328649
}

0 commit comments

Comments
 (0)