Skip to content

Commit

Permalink
Ensure certain instance methods properly check if the entity is active
Browse files Browse the repository at this point in the history
  • Loading branch information
Lactozilla committed Aug 2, 2024
1 parent 57d1537 commit df75b9b
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 39 deletions.
10 changes: 5 additions & 5 deletions guides/Documentation.htm
Original file line number Diff line number Diff line change
Expand Up @@ -10120,7 +10120,7 @@ <h2 style="margin-bottom: 8px;">instance.CollideWithObject</h2>
<div style="margin-top: 8px; font-size: 14px;">Does collision with another entity.</div>
<div style="font-weight: bold; margin-top: 8px;">Parameters:</div>
<ul style="margin-top: 0px; font-size: 14px;">
<li>other (Instance): The other entity.</li>
<li>other (Instance): The other entity to check collision for.</li>
</ul>
<div style="font-weight: bold; margin-top: 8px;">Returns:</div>
<div style="font-size: 14px;">Returns <code>true</code> if the entity collided, <code>false</code> if otherwise.</div>
Expand All @@ -10131,7 +10131,7 @@ <h2 style="margin-bottom: 8px;">instance.SolidCollideWithObject</h2>
<div style="margin-top: 8px; font-size: 14px;">Does solid collision with another entity.</div>
<div style="font-weight: bold; margin-top: 8px;">Parameters:</div>
<ul style="margin-top: 0px; font-size: 14px;">
<li>other (Instance): The other entity.</li>
<li>other (Instance): The other entity to check collision for.</li>
</ul>
<div style="font-weight: bold; margin-top: 8px;">Returns:</div>
<div style="font-size: 14px;">Returns <code>true</code> if the entity collided, <code>false</code> if otherwise.</div>
Expand All @@ -10142,7 +10142,7 @@ <h2 style="margin-bottom: 8px;">instance.TopSolidCollideWithObject</h2>
<div style="margin-top: 8px; font-size: 14px;">Does solid collision with another entity's top.</div>
<div style="font-weight: bold; margin-top: 8px;">Parameters:</div>
<ul style="margin-top: 0px; font-size: 14px;">
<li>other (Instance): The other entity.</li>
<li>other (Instance): The other entity to check collision for.</li>
</ul>
<div style="font-weight: bold; margin-top: 8px;">Returns:</div>
<div style="font-size: 14px;">Returns <code>true</code> if the entity collided, <code>false</code> if otherwise.</div>
Expand Down Expand Up @@ -10230,7 +10230,7 @@ <h2 style="margin-bottom: 8px;">instance.PlaySound</h2>
<li>volume (Decimal): Controls the volume of the audio. 0.0 is muted, 1.0 is normal volume. (1.0 is the default.)</li>
</ul>
<div style="font-weight: bold; margin-top: 8px;">Returns:</div>
<div style="font-size: 14px;">Returns the channel index where the sound began to play.</div>
<div style="font-size: 14px;">Returns the channel index where the sound began to play, or <code>-1</code> if no channel was available.</div>
</p>
<p id="Reference_methods_instance_LoopSound">
<h2 style="margin-bottom: 8px;">instance.LoopSound</h2>
Expand All @@ -10245,7 +10245,7 @@ <h2 style="margin-bottom: 8px;">instance.LoopSound</h2>
<li>volume (Decimal): Controls the volume of the audio. 0.0 is muted, 1.0 is normal volume. (1.0 is the default.)</li>
</ul>
<div style="font-weight: bold; margin-top: 8px;">Returns:</div>
<div style="font-size: 14px;">Returns the channel index where the sound began to play.</div>
<div style="font-size: 14px;">Returns the channel index where the sound began to play, or <code>-1</code> if no channel was available.</div>
</p>
<p id="Reference_methods_instance_StopSound">
<h2 style="margin-bottom: 8px;">instance.StopSound</h2>
Expand Down
77 changes: 43 additions & 34 deletions source/Engine/Bytecode/ScriptEntity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1041,14 +1041,22 @@ ScriptEntity* GetScriptEntity(VMValue* args, int index, Uint32 threadID) {
return nullptr;
return (ScriptEntity*)entity->EntityPtr;
}
bool TestEntityCollision(ScriptEntity* other, ScriptEntity* self) {
if (!other->Active || other->Removed)
bool IsValidEntity(Entity* self) {
if (!self || !self->Active || self->Removed)
return false;

return true;
}
bool TestEntityCollision(Entity* other, Entity* self) {
if (!IsValidEntity(other))
return false;

return self->CollideWithObject(other);
}
PUBLIC STATIC bool ScriptEntity::VM_Getter(Obj* object, Uint32 hash, VMValue* result, Uint32 threadID) {
Entity* self = GetScriptEntity(object);
if (self == nullptr)
return false;

if (hash == Hash_HitboxLeft) {
if (result)
Expand All @@ -1075,6 +1083,8 @@ PUBLIC STATIC bool ScriptEntity::VM_Getter(Obj* object, Uint32 hash, VMValue* re
}
PUBLIC STATIC bool ScriptEntity::VM_Setter(Obj* object, Uint32 hash, VMValue value, Uint32 threadID) {
Entity* self = GetScriptEntity(object);
if (self == nullptr)
return false;

if (hash == Hash_HitboxLeft) {
if (ScriptManager::DoDecimalConversion(value, threadID))
Expand Down Expand Up @@ -1112,7 +1122,7 @@ PUBLIC STATIC VMValue ScriptEntity::VM_SetAnimation(int argCount, VMValue* args,
int animation = GET_ARG(1, GetInteger);
int frame = GET_ARG(2, GetInteger);

if (!self)
if (!IsValidEntity(self))
return NULL_VAL;

ISprite* sprite = Scene::GetSpriteResource(self->Sprite);
Expand Down Expand Up @@ -1146,7 +1156,7 @@ PUBLIC STATIC VMValue ScriptEntity::VM_ResetAnimation(int argCount, VMValue* arg
int animation = GET_ARG(1, GetInteger);
int frame = GET_ARG(2, GetInteger);

if (!self)
if (!IsValidEntity(self))
return NULL_VAL;

int spriteIns = self->Sprite;
Expand Down Expand Up @@ -1218,7 +1228,7 @@ PUBLIC STATIC VMValue ScriptEntity::VM_AddToRegistry(int argCount, VMValue* args
Entity* self = GET_ENTITY(0);
char* registry = GET_ARG(1, GetString);

if (!self)
if (!IsValidEntity(self))
return NULL_VAL;

ObjectRegistry* objectRegistry;
Expand Down Expand Up @@ -1246,9 +1256,8 @@ PUBLIC STATIC VMValue ScriptEntity::VM_IsInRegistry(int argCount, VMValue* args,
Entity* self = GET_ENTITY(0);
char* registry = GET_ARG(1, GetString);

if (!self || !Scene::ObjectRegistries->Exists(registry)) {
if (!IsValidEntity(self) || !Scene::ObjectRegistries->Exists(registry))
return NULL_VAL;
}

ObjectRegistry* objectRegistry = Scene::ObjectRegistries->Get(registry);

Expand All @@ -1265,14 +1274,10 @@ PUBLIC STATIC VMValue ScriptEntity::VM_RemoveFromRegistry(int argCount, VMValue*
Entity* self = GET_ENTITY(0);
char* registry = GET_ARG(1, GetString);

if (!self)
if (!IsValidEntity(self) || !Scene::ObjectRegistries->Exists(registry))
return NULL_VAL;

ObjectRegistry* objectRegistry;
if (!Scene::ObjectRegistries->Exists(registry)) {
return NULL_VAL;
}
objectRegistry = Scene::ObjectRegistries->Get(registry);
ObjectRegistry* objectRegistry = Scene::ObjectRegistries->Get(registry);

objectRegistry->Remove(self);

Expand All @@ -1286,7 +1291,7 @@ PUBLIC STATIC VMValue ScriptEntity::VM_RemoveFromRegistry(int argCount, VMValue*
PUBLIC STATIC VMValue ScriptEntity::VM_ApplyMotion(int argCount, VMValue* args, Uint32 threadID) {
StandardLibrary::CheckArgCount(argCount, 1);
Entity* self = GET_ENTITY(0);
if (self)
if (IsValidEntity(self))
self->ApplyMotion();
return NULL_VAL;
}
Expand Down Expand Up @@ -1329,13 +1334,11 @@ PUBLIC STATIC VMValue ScriptEntity::VM_CollidedWithObject(int argCount, VMValue*
StandardLibrary::CheckArgCount(argCount, 2);

ScriptEntity* self = GET_ENTITY(0);
if (!self)
if (IsValidEntity(self))
return NULL_VAL;

if (IS_INSTANCE(args[1])) {
ScriptEntity* other = GET_ENTITY(1);
if (!other)
return NULL_VAL;
if (TestEntityCollision(other, self))
return OBJECT_VAL(other->Instance);
return NULL_VAL;
Expand Down Expand Up @@ -1382,7 +1385,7 @@ PUBLIC STATIC VMValue ScriptEntity::VM_GetHitboxFromSprite(int argCount, VMValue
int frame = GET_ARG(3, GetInteger);
int hitbox = GET_ARG(4, GetInteger);

if (!self || !sprite)
if (!IsValidEntity(self) || !sprite)
return NULL_VAL;

if (!(animation > -1 && (size_t)animation < sprite->Animations.size())) {
Expand Down Expand Up @@ -1424,7 +1427,7 @@ PUBLIC STATIC VMValue ScriptEntity::VM_ReturnHitboxFromSprite(int argCount, VMVa
int frame = GET_ARG(3, GetInteger);
int hitbox = GET_ARG(4, GetInteger);

if (!self || !sprite)
if (!IsValidEntity(self) || !sprite)
return NULL_VAL;

if (!(animation > -1 && (size_t)animation < sprite->Animations.size())) {
Expand Down Expand Up @@ -1455,22 +1458,22 @@ PUBLIC STATIC VMValue ScriptEntity::VM_ReturnHitboxFromSprite(int argCount, VMVa
/***
* \method CollideWithObject
* \desc Does collision with another entity.
* \param other (Instance): The other entity.
* \param other (Instance): The other entity to check collision for.
* \return Returns <code>true</code> if the entity collided, <code>false</code> if otherwise.
* \ns Instance
*/
PUBLIC STATIC VMValue ScriptEntity::VM_CollideWithObject(int argCount, VMValue* args, Uint32 threadID) {
StandardLibrary::CheckArgCount(argCount, 2);
ScriptEntity* self = GET_ENTITY(0);
ScriptEntity* other = GET_ENTITY(1);
if (!self || !other)
if (!IsValidEntity(self) || !IsValidEntity(other))
return NULL_VAL;
return INTEGER_VAL(self->CollideWithObject(other));
}
/***
* \method SolidCollideWithObject
* \desc Does solid collision with another entity.
* \param other (Instance): The other entity.
* \param other (Instance): The other entity to check collision for.
* \return Returns <code>true</code> if the entity collided, <code>false</code> if otherwise.
* \ns Instance
*/
Expand All @@ -1479,14 +1482,14 @@ PUBLIC STATIC VMValue ScriptEntity::VM_SolidCollideWithObject(int argCount, VMVa
ScriptEntity* self = GET_ENTITY(0);
ScriptEntity* other = GET_ENTITY(1);
int flag = GET_ARG(2, GetInteger);
if (!self || !other)
if (!IsValidEntity(self) || !IsValidEntity(other))
return NULL_VAL;
return INTEGER_VAL(self->SolidCollideWithObject(other, flag));
}
/***
* \method TopSolidCollideWithObject
* \desc Does solid collision with another entity's top.
* \param other (Instance): The other entity.
* \param other (Instance): The other entity to check collision for.
* \return Returns <code>true</code> if the entity collided, <code>false</code> if otherwise.
* \ns Instance
*/
Expand All @@ -1495,15 +1498,15 @@ PUBLIC STATIC VMValue ScriptEntity::VM_TopSolidCollideWithObject(int argCount, V
ScriptEntity* self = GET_ENTITY(0);
ScriptEntity* other = GET_ENTITY(1);
int flag = GET_ARG(2, GetInteger);
if (!self || !other)
if (!IsValidEntity(self) || !IsValidEntity(other))
return NULL_VAL;
return INTEGER_VAL(self->TopSolidCollideWithObject(other, flag));
}

PUBLIC STATIC VMValue ScriptEntity::VM_ApplyPhysics(int argCount, VMValue* args, Uint32 threadID) {
StandardLibrary::CheckArgCount(argCount, 1);
ScriptEntity* self = GET_ENTITY(0);
if (self)
if (IsValidEntity(self))
self->ApplyPhysics();
return NULL_VAL;
}
Expand Down Expand Up @@ -1551,7 +1554,7 @@ PUBLIC STATIC VMValue ScriptEntity::VM_SetViewVisibility(int argCount, VMValue*
ScriptEntity* self = GET_ENTITY(0);
int viewIndex = GET_ARG(1, GetInteger);
bool visible = GET_ARG(2, GetInteger);
if (self) {
if (IsValidEntity(self)) {
int flag = 1 << viewIndex;
if (visible)
self->ViewRenderFlag |= flag;
Expand All @@ -1572,7 +1575,7 @@ PUBLIC STATIC VMValue ScriptEntity::VM_SetViewOverride(int argCount, VMValue* ar
ScriptEntity* self = GET_ENTITY(0);
int viewIndex = GET_ARG(1, GetInteger);
bool override = GET_ARG(2, GetInteger);
if (self) {
if (IsValidEntity(self)) {
int flag = 1 << viewIndex;
if (override)
self->ViewOverrideFlag |= flag;
Expand All @@ -1591,6 +1594,8 @@ PUBLIC STATIC VMValue ScriptEntity::VM_SetViewOverride(int argCount, VMValue* ar
PUBLIC STATIC VMValue ScriptEntity::VM_AddToDrawGroup(int argCount, VMValue* args, Uint32 threadID) {
StandardLibrary::CheckArgCount(argCount, 2);
ScriptEntity* self = GET_ENTITY(0);
if (!IsValidEntity(self))
return NULL_VAL;
int drawGroup = GET_ARG(1, GetInteger);
if (drawGroup >= 0 && drawGroup < Scene::PriorityPerLayer) {
if (!Scene::PriorityLists[drawGroup].Contains(self))
Expand All @@ -1610,6 +1615,8 @@ PUBLIC STATIC VMValue ScriptEntity::VM_AddToDrawGroup(int argCount, VMValue* arg
PUBLIC STATIC VMValue ScriptEntity::VM_IsInDrawGroup(int argCount, VMValue* args, Uint32 threadID) {
StandardLibrary::CheckArgCount(argCount, 2);
ScriptEntity* self = GET_ENTITY(0);
if (!IsValidEntity(self))
return INTEGER_VAL(false);
int drawGroup = GET_ARG(1, GetInteger);
if (drawGroup >= 0 && drawGroup < Scene::PriorityPerLayer)
return INTEGER_VAL(!!(Scene::PriorityLists[drawGroup].Contains(self)));
Expand All @@ -1626,6 +1633,8 @@ PUBLIC STATIC VMValue ScriptEntity::VM_IsInDrawGroup(int argCount, VMValue* args
PUBLIC STATIC VMValue ScriptEntity::VM_RemoveFromDrawGroup(int argCount, VMValue* args, Uint32 threadID) {
StandardLibrary::CheckArgCount(argCount, 2);
ScriptEntity* self = GET_ENTITY(0);
if (!IsValidEntity(self))
return NULL_VAL;
int drawGroup = GET_ARG(1, GetInteger);
if (drawGroup >= 0 && drawGroup < Scene::PriorityPerLayer)
Scene::PriorityLists[drawGroup].Remove(self);
Expand All @@ -1641,7 +1650,7 @@ PUBLIC STATIC VMValue ScriptEntity::VM_RemoveFromDrawGroup(int argCount, VMValue
* \paramOpt panning (Decimal): Control the panning of the audio. -1.0 makes it sound in left ear only, 1.0 makes it sound in right ear, and closer to 0.0 centers it. (0.0 is the default.)
* \paramOpt speed (Decimal): Control the speed of the audio. > 1.0 makes it faster, < 1.0 is slower, 1.0 is normal speed. (1.0 is the default.)
* \paramOpt volume (Decimal): Controls the volume of the audio. 0.0 is muted, 1.0 is normal volume. (1.0 is the default.)
* \return Returns the channel index where the sound began to play.
* \return Returns the channel index where the sound began to play, or <code>-1</code> if no channel was available.
* \ns Instance
*/
PUBLIC STATIC VMValue ScriptEntity::VM_PlaySound(int argCount, VMValue* args, Uint32 threadID) {
Expand All @@ -1652,7 +1661,7 @@ PUBLIC STATIC VMValue ScriptEntity::VM_PlaySound(int argCount, VMValue* args, Ui
float speed = GET_ARG_OPT(3, GetDecimal, 1.0f);
float volume = GET_ARG_OPT(4, GetDecimal, 1.0f);
int channel = -1;
if (self) {
if (IsValidEntity(self)) {
AudioManager::StopOriginSound((void*)self, audio);
channel = AudioManager::PlaySound(audio, false, 0, panning, speed, volume, (void*)self);
}
Expand All @@ -1666,7 +1675,7 @@ PUBLIC STATIC VMValue ScriptEntity::VM_PlaySound(int argCount, VMValue* args, Ui
* \paramOpt panning (Decimal): Control the panning of the audio. -1.0 makes it sound in left ear only, 1.0 makes it sound in right ear, and closer to 0.0 centers it. (0.0 is the default.)
* \paramOpt speed (Decimal): Control the speed of the audio. > 1.0 makes it faster, < 1.0 is slower, 1.0 is normal speed. (1.0 is the default.)
* \paramOpt volume (Decimal): Controls the volume of the audio. 0.0 is muted, 1.0 is normal volume. (1.0 is the default.)
* \return Returns the channel index where the sound began to play.
* \return Returns the channel index where the sound began to play, or <code>-1</code> if no channel was available.
* \ns Instance
*/
PUBLIC STATIC VMValue ScriptEntity::VM_LoopSound(int argCount, VMValue* args, Uint32 threadID) {
Expand All @@ -1678,7 +1687,7 @@ PUBLIC STATIC VMValue ScriptEntity::VM_LoopSound(int argCount, VMValue* args, Ui
float speed = GET_ARG_OPT(4, GetDecimal, 1.0f);
float volume = GET_ARG_OPT(5, GetDecimal, 1.0f);
int channel = -1;
if (self) {
if (IsValidEntity(self)) {
AudioManager::StopOriginSound((void*)self, audio);
channel = AudioManager::PlaySound(audio, true, loopPoint, panning, speed, volume, (void*)self);
}
Expand All @@ -1694,7 +1703,7 @@ PUBLIC STATIC VMValue ScriptEntity::VM_StopSound(int argCount, VMValue* args, Ui
StandardLibrary::CheckArgCount(argCount, 2);
ScriptEntity* self = GET_ENTITY(0);
ISound* audio = GET_ARG(1, GetSound);
if (self)
if (IsValidEntity(self))
AudioManager::StopOriginSound((void*)self, audio);
return NULL_VAL;
}
Expand All @@ -1706,7 +1715,7 @@ PUBLIC STATIC VMValue ScriptEntity::VM_StopSound(int argCount, VMValue* args, Ui
PUBLIC STATIC VMValue ScriptEntity::VM_StopAllSounds(int argCount, VMValue* args, Uint32 threadID) {
StandardLibrary::CheckArgCount(argCount, 1);
ScriptEntity* self = GET_ENTITY(0);
if (self)
if (IsValidEntity(self))
AudioManager::StopAllOriginSounds((void*)self);
return NULL_VAL;
}
3 changes: 3 additions & 0 deletions source/Engine/Scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,9 @@ PRIVATE STATIC void Scene::RemoveObject(Entity* obj) {
for (int l = 0; l < Scene::PriorityPerLayer; l++)
PriorityLists[l].Remove(obj);

// Stop all sounds
AudioManager::StopAllOriginSounds((void*)obj);

// Remove it from the scene
Scene::RemoveFromScene(obj);

Expand Down

0 comments on commit df75b9b

Please sign in to comment.