Skip to content

Commit a91ff26

Browse files
avoitishinXottab-DUTY
authored andcommitted
+ actor_before_death script call back (set in bind_stalker). This will allow scripts to process actor condition and prevent actor's death or kill him if desired. IMPORTANT: if you wish to kill actor you need to call db.actor:kill(level:object_by_id(whoID), true) in actor_before_death callback, to ensure all objects are properly destroyed.
+ set_health_ex script method for game_object. This will directly set entity's health instead of going through health property which operates on delta
1 parent 664fda4 commit a91ff26

9 files changed

+53
-18
lines changed

res/gamedata/scripts/bind_stalker.script

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ function actor_binder:net_destroy()
9595
self.object:set_callback(callback.item_to_belt, nil)
9696
self.object:set_callback(callback.item_to_ruck, nil)
9797
self.object:set_callback(callback.item_to_slot, nil)
98+
self.object:set_callback(callback.actor_before_death, nil)
9899
----| end:aVo |----------------------------------------------------------------
99100

100101
log("--------->"..tostring(_G.amb_vol))
@@ -141,6 +142,7 @@ function actor_binder:reinit()
141142
self.object:set_callback(callback.item_to_ruck, self.item_to_ruck, self)
142143
self.object:set_callback(callback.item_to_belt, self.item_to_belt, self)
143144
self.object:set_callback(callback.item_to_slot, self.item_to_slot, self)
145+
self.object:set_callback(callback.actor_before_death, self.on_actor_before_death, self)
144146
----| end:aVo |----------------------------------------------------------------
145147
end
146148
---------------------------------------------------------------------------------------------------------------------
@@ -197,6 +199,13 @@ end
197199
function actor_binder:item_to_slot(obj)
198200
log(string.format("item_to_slot [%s]", obj:name()))
199201
end
202+
-- actor before death callback
203+
-- IMPORTANT: if you wish to kill actor you need to call db.actor:kill(level:object_by_id(whoID), true) in actor_before_death callback, to ensure all objects are properly destroyed.
204+
function actor_binder:on_actor_before_death(whoID)
205+
-- log("[AVO] on_actor_before_death callback")
206+
-- db.actor:set_health_ex(1)
207+
db.actor:kill(level:object_by_id(whoID), true)
208+
end
200209
----| end:aVo |---------------------------------------------------------------
201210
----------------------------------------------------------------------------------------------------------------------
202211
function actor_binder:take_item_from_box(box, item)

src/xrGame/Entity.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,12 +252,22 @@ void CEntity::net_Destroy()
252252
set_ready_to_save();
253253
}
254254

255-
void CEntity::KillEntity(u16 whoID)
255+
void CEntity::KillEntity(u16 whoID, bool bypass_actor_check)
256256
{
257+
//AVO: allow scripts to process actor condition and prevent actor's death or kill him if desired.
258+
//IMPORTANT: if you wish to kill actor you need to call db.actor:kill(level:object_by_id(whoID), true) in actor_before_death callback, to ensure all objects are properly destroyed
259+
// this will bypass below if block and go to normal KillEntity routine.
260+
if (IsGameTypeSingle() && this->ID() == Actor()->ID() && bypass_actor_check != true)
261+
{
262+
Actor()->callback(GameObject::eActorBeforeDeath)(whoID);
263+
return;
264+
}
265+
//-AVO
266+
257267
if (this->ID() == Actor()->ID())
258268
{
259269
Actor()->detach_Vehicle();
260-
Actor()->use_MountedWeapon(NULL);
270+
Actor()->use_MountedWeapon(nullptr);
261271
}
262272
if (whoID != ID())
263273
{

src/xrGame/Entity.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,8 @@ class CEntity : public CPhysicsShellHolder, public CDamageManager
9494
virtual void HitImpulse(float P, Fvector& vWorldDir, Fvector& vLocalDir) = 0;
9595

9696
virtual void Die(IGameObject* who);
97-
// void KillEntity (IGameObject* who);
98-
void KillEntity(u16 whoID);
97+
//void KillEntity (IGameObject* who);
98+
void KillEntity(u16 whoID, bool bypass_actor_check = false);
9999

100100
// Events
101101
virtual void OnEvent(NET_Packet& P, u16 type);

src/xrGame/game_object_space.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,18 +54,20 @@ enum ECallbackType
5454
eInvBoxItemTake,
5555
eWeaponNoAmmoAvailable,
5656

57-
/* avo: custom callbacks */
58-
// input
57+
//AVO: custom callbacks
58+
// Input
5959
eKeyPress,
6060
eKeyRelease,
6161
eKeyHold,
6262
eMouseMove,
6363
eMouseWheel,
64-
// inventory
64+
// Inventory
6565
eItemToBelt,
6666
eItemToSlot,
6767
eItemToRuck,
68-
/* avo: end */
68+
// Actor
69+
eActorBeforeDeath,
70+
//-AVO
6971

7072
eDummy = u32(-1),
7173
};

src/xrGame/script_game_object.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ class CScriptGameObject
189189
_DECLARE_FUNCTION10(Squad, int);
190190
_DECLARE_FUNCTION10(Group, int);
191191

192-
void Kill(CScriptGameObject* who);
192+
void Kill(CScriptGameObject* who, bool bypass_actor_check = false /*AVO: added for actor before death callback*/);
193193

194194
// CEntityAlive
195195
_DECLARE_FUNCTION10(GetFOV, float);
@@ -821,7 +821,8 @@ class CScriptGameObject
821821
bool isWeaponGL() const;
822822
bool isInventoryBox() const;
823823
bool IsActorOutdoors() const;
824-
//end AVO
824+
void SetHealthEx(float hp);
825+
//-AVO
825826

826827
doors::door* m_door;
827828
};

src/xrGame/script_game_object4.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,16 @@ void CScriptGameObject::stop_particles(LPCSTR pname, LPCSTR bone)
368368
LuaMessageType::Error, "Cant stop particles, bone [%s] is not visible now", bone);
369369
}
370370

371+
//AVO: directly set entity health instead of going throuhg normal health property which operates on delta
372+
void CScriptGameObject::SetHealthEx(float hp)
373+
{
374+
CEntity* obj = smart_cast<CEntity*>(&object());
375+
if (!obj) return;
376+
clamp(hp, -0.01f, 1.0f);
377+
obj->SetfHealth(hp);
378+
}
379+
//-AVO
380+
371381
// AVO: functions for testing object class
372382
// Credits: KD
373383
//#include "Car.h"

src/xrGame/script_game_object_script.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,18 +83,20 @@ SCRIPT_EXPORT(CScriptGameObject, (), {
8383
value("take_item_from_box", int(GameObject::eInvBoxItemTake)),
8484
value("weapon_no_ammo", int(GameObject::eWeaponNoAmmoAvailable)),
8585

86-
/* avo: custom callbacks */
87-
// input
86+
//AVO: custom callbacks
87+
// Input
8888
value("key_press", int(GameObject::eKeyPress)),
8989
value("key_release", int(GameObject::eKeyRelease)),
9090
value("key_hold", int(GameObject::eKeyHold)),
9191
value("mouse_move", int(GameObject::eMouseMove)),
9292
value("mouse_wheel", int(GameObject::eMouseWheel)),
93-
// inventory
93+
// Inventory
9494
value("item_to_belt", int(GameObject::eItemToBelt)),
9595
value("item_to_slot", int(GameObject::eItemToSlot)),
9696
value("item_to_ruck", int(GameObject::eItemToRuck)),
97-
/* avo: end */
97+
// Actor
98+
value("actor_before_death", int(GameObject::eActorBeforeDeath)),
99+
//-AVO
98100

99101
value("map_location_added", int(GameObject::eMapLocationAdded))],
100102

src/xrGame/script_game_object_script3.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -385,8 +385,9 @@ class_<CScriptGameObject>& script_register_game_object2(class_<CScriptGameObject
385385
.def("is_torch", &CScriptGameObject::isTorch)
386386
.def("is_weapon_gl", &CScriptGameObject::isWeaponGL)
387387
.def("is_inventory_box", &CScriptGameObject::isInventoryBox)
388-
//end AVO
388+
.def("set_health_ex", &CScriptGameObject::SetHealthEx)
389+
//-AVO
389390

390391
;
391-
return (instance);
392+
return instance;
392393
}

src/xrGame/script_game_object_use.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ int CScriptGameObject::clsid() const { return (object().clsid()); }
5959
LPCSTR CScriptGameObject::Name() const { return (*object().cName()); }
6060
shared_str CScriptGameObject::cName() const { return (object().cName()); }
6161
LPCSTR CScriptGameObject::Section() const { return (*object().cNameSect()); }
62-
void CScriptGameObject::Kill(CScriptGameObject* who)
62+
void CScriptGameObject::Kill(CScriptGameObject* who, bool bypass_actor_check /*AVO: added for actor before death callback*/)
6363
{
6464
CEntity* l_tpEntity = smart_cast<CEntity*>(&object());
6565
if (!l_tpEntity)
@@ -69,7 +69,7 @@ void CScriptGameObject::Kill(CScriptGameObject* who)
6969
return;
7070
}
7171
if (!l_tpEntity->AlreadyDie())
72-
l_tpEntity->KillEntity(who ? who->object().ID() : object().ID());
72+
l_tpEntity->KillEntity(who ? who->object().ID() : object().ID(), bypass_actor_check);
7373
else
7474
ai().script_engine().script_log(LuaMessageType::Error, "attempt to kill dead object %s", *object().cName());
7575
}

0 commit comments

Comments
 (0)