diff --git a/src/g_inventory/a_pickups.cpp b/src/g_inventory/a_pickups.cpp index 51072023b..bdd1b6dc6 100644 --- a/src/g_inventory/a_pickups.cpp +++ b/src/g_inventory/a_pickups.cpp @@ -261,7 +261,7 @@ bool AInventory::SpecialDropAction (AActor *dropper) DEFINE_ACTION_FUNCTION(AInventory, SpecialDropAction) { PARAM_SELF_PROLOGUE(AInventory); - PARAM_OBJECT(dropper, AActor); + PARAM_OBJECT_NOT_NULL(dropper, AActor); ACTION_RETURN_BOOL(self->SpecialDropAction(dropper)); } @@ -429,7 +429,7 @@ bool AInventory::HandlePickup (AInventory *item) DEFINE_ACTION_FUNCTION(AInventory, HandlePickup) { PARAM_SELF_PROLOGUE(AInventory); - PARAM_OBJECT(item, AInventory); + PARAM_OBJECT_NOT_NULL(item, AInventory); ACTION_RETURN_BOOL(self->HandlePickup(item)); } @@ -1416,7 +1416,7 @@ bool AInventory::TryPickup (AActor *&toucher) DEFINE_ACTION_FUNCTION(AInventory, TryPickup) { PARAM_SELF_PROLOGUE(AInventory); - PARAM_POINTER(toucher, AActor*); + PARAM_POINTER_NOT_NULL(toucher, AActor*); ACTION_RETURN_BOOL(self->TryPickup(*toucher)); } @@ -1434,7 +1434,7 @@ bool AInventory::TryPickupRestricted (AActor *&toucher) DEFINE_ACTION_FUNCTION(AInventory, TryPickupRestricted) { PARAM_SELF_PROLOGUE(AInventory); - PARAM_POINTER(toucher, AActor*); + PARAM_POINTER_NOT_NULL(toucher, AActor*); ACTION_RETURN_BOOL(self->TryPickupRestricted(*toucher)); } @@ -1613,7 +1613,7 @@ void AInventory::AttachToOwner (AActor *other) DEFINE_ACTION_FUNCTION(AInventory, AttachToOwner) { PARAM_SELF_PROLOGUE(AInventory); - PARAM_OBJECT(other, AActor); + PARAM_OBJECT_NOT_NULL(other, AActor); self->AttachToOwner(other); return 0; } diff --git a/src/g_shared/a_morph.cpp b/src/g_shared/a_morph.cpp index 03f76c0c0..136c096a3 100644 --- a/src/g_shared/a_morph.cpp +++ b/src/g_shared/a_morph.cpp @@ -363,7 +363,7 @@ bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag, DEFINE_ACTION_FUNCTION(_PlayerInfo, UndoPlayerMorph) { PARAM_SELF_STRUCT_PROLOGUE(player_t); - PARAM_POINTER(player, player_t); + PARAM_POINTER_NOT_NULL(player, player_t); PARAM_INT_DEF(unmorphflag); PARAM_BOOL_DEF(force); ACTION_RETURN_BOOL(P_UndoPlayerMorph(self, player, unmorphflag, force)); diff --git a/src/g_shared/a_specialspot.cpp b/src/g_shared/a_specialspot.cpp index 026185d07..b5debf2df 100644 --- a/src/g_shared/a_specialspot.cpp +++ b/src/g_shared/a_specialspot.cpp @@ -265,6 +265,7 @@ DEFINE_ACTION_FUNCTION(DSpotState, GetSpotState) FSpotList *DSpotState::FindSpotList(PClassActor *type) { + if (type == nullptr) return nullptr; for(unsigned i = 0; i < SpotLists.Size(); i++) { if (SpotLists[i].Type == type) return &SpotLists[i]; @@ -404,7 +405,7 @@ void ASpecialSpot::Destroy() DEFINE_ACTION_FUNCTION(AActor, A_SpawnSingleItem) { PARAM_SELF_PROLOGUE(AActor); - PARAM_CLASS (cls, AActor); + PARAM_CLASS_NOT_NULL(cls, AActor); PARAM_INT_DEF (fail_sp) PARAM_INT_DEF (fail_co) PARAM_INT_DEF (fail_dm) diff --git a/src/p_actionfunctions.cpp b/src/p_actionfunctions.cpp index 477ed37f2..115bc1f54 100644 --- a/src/p_actionfunctions.cpp +++ b/src/p_actionfunctions.cpp @@ -247,7 +247,7 @@ DEFINE_ACTION_FUNCTION(AActor, CheckClass) PARAM_BOOL_DEF (match_superclass); self = COPY_AAPTR(self, pick_pointer); - if (self == NULL) + if (self == nullptr || checktype == nullptr) { ret->SetInt(false); } diff --git a/src/p_ceiling.cpp b/src/p_ceiling.cpp index 932b4c649..4da81db46 100644 --- a/src/p_ceiling.cpp +++ b/src/p_ceiling.cpp @@ -461,7 +461,7 @@ bool P_CreateCeiling(sector_t *sec, DCeiling::ECeiling type, line_t *line, int t DEFINE_ACTION_FUNCTION(DCeiling, CreateCeiling) { PARAM_PROLOGUE; - PARAM_POINTER(sec, sector_t); + PARAM_POINTER_NOT_NULL(sec, sector_t); PARAM_INT(type); PARAM_POINTER(ln, line_t); PARAM_FLOAT(speed); diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 751f92a30..beaa1548f 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -1307,6 +1307,11 @@ bool P_IsVisible(AActor *lookee, AActor *other, INTBOOL allaround, FLookExParams double mindist; DAngle fov; + if (other == nullptr) + { + return false; + } + if (params != NULL) { maxdist = params->maxDist; @@ -3095,7 +3100,7 @@ void A_FaceTarget(AActor *self) DEFINE_ACTION_FUNCTION(AActor, A_Face) { PARAM_SELF_PROLOGUE(AActor); - PARAM_OBJECT(faceto, AActor) + PARAM_OBJECT_NOT_NULL(faceto, AActor) PARAM_ANGLE_DEF(max_turn) PARAM_ANGLE_DEF(max_pitch) PARAM_ANGLE_DEF(ang_offset) @@ -3323,15 +3328,6 @@ AInventory *P_DropItem (AActor *source, PClassActor *type, int dropamount, int c return NULL; } -DEFINE_ACTION_FUNCTION(AActor, DoDropItem) -{ - PARAM_SELF_PROLOGUE(AActor); - PARAM_CLASS(cls, AActor); - PARAM_INT(amt); - PARAM_INT(chance); - ACTION_RETURN_OBJECT(P_DropItem(self, cls, amt, chance)); -} - //============================================================================ // // P_TossItem diff --git a/src/p_floor.cpp b/src/p_floor.cpp index 8fd5ad038..4b1f243d5 100644 --- a/src/p_floor.cpp +++ b/src/p_floor.cpp @@ -495,7 +495,7 @@ bool P_CreateFloor(sector_t *sec, DFloor::EFloor floortype, line_t *line, DEFINE_ACTION_FUNCTION(DFloor, CreateFloor) { PARAM_PROLOGUE; - PARAM_POINTER(sec, sector_t); + PARAM_POINTER_NOT_NULL(sec, sector_t); PARAM_INT(floortype); PARAM_POINTER(ln, line_t); PARAM_FLOAT(speed); diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index e6729096c..9aa178e64 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -1639,7 +1639,7 @@ void P_PoisonMobj (AActor *target, AActor *inflictor, AActor *source, int damage DEFINE_ACTION_FUNCTION(AActor, PoisonMobj) { PARAM_SELF_PROLOGUE(AActor); - PARAM_OBJECT(inflictor, AActor); + PARAM_OBJECT_NOT_NULL(inflictor, AActor); PARAM_OBJECT(source, AActor); PARAM_INT(damage); PARAM_INT(duration); diff --git a/src/p_map.cpp b/src/p_map.cpp index 11036d171..f25c33612 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -4513,6 +4513,7 @@ DEFINE_ACTION_FUNCTION(AActor, LineAttack) PARAM_POINTER_DEF(victim, FTranslatedLineTarget); int acdmg; + if (puffType == nullptr) puffType = PClass::FindActor("BulletPuff"); // P_LineAttack does not work without a puff to take info from. auto puff = P_LineAttack(self, angle, distance, pitch, damage, damageType, puffType, flags, victim, &acdmg); if (numret > 0) ret[0].SetPointer(puff, ATAG_OBJECT); if (numret > 1) ret[1].SetInt(acdmg), numret = 2; @@ -4716,7 +4717,7 @@ DEFINE_ACTION_FUNCTION(_FTranslatedLineTarget, TraceBleed) { PARAM_SELF_STRUCT_PROLOGUE(FTranslatedLineTarget); PARAM_INT(damage); - PARAM_OBJECT(missile, AActor); + PARAM_OBJECT_NOT_NULL(missile, AActor); P_TraceBleed(damage, self, missile); return 0; diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index aa29a1c5e..31b412598 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -1193,7 +1193,7 @@ IMPLEMENT_CLASS(DBlockThingsIterator, false, false); DEFINE_ACTION_FUNCTION(DBlockThingsIterator, Create) { PARAM_PROLOGUE; - PARAM_OBJECT(origin, AActor); + PARAM_OBJECT_NOT_NULL(origin, AActor); PARAM_FLOAT_DEF(radius); PARAM_BOOL_DEF(ignore); ACTION_RETURN_OBJECT(new DBlockThingsIterator(origin, radius, ignore)); diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 26e362d8f..88653fca9 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -751,7 +751,7 @@ void AActor::AddInventory (AInventory *item) DEFINE_ACTION_FUNCTION(AActor, AddInventory) { PARAM_SELF_PROLOGUE(AActor); - PARAM_OBJECT(item, AInventory); + PARAM_OBJECT_NOT_NULL(item, AInventory); self->AddInventory(item); return 0; } @@ -819,7 +819,7 @@ bool AActor::GiveInventory(PClassInventory *type, int amount, bool givecheat) DEFINE_ACTION_FUNCTION(AActor, Inventory) { PARAM_SELF_PROLOGUE(AActor); - PARAM_OBJECT(item, AInventory); + PARAM_OBJECT_NOT_NULL(item, AInventory); ACTION_RETURN_BOOL(self->UseInventory(item)); } @@ -854,7 +854,7 @@ void AActor::RemoveInventory(AInventory *item) DEFINE_ACTION_FUNCTION(AActor, RemoveInventory) { PARAM_SELF_PROLOGUE(AActor); - PARAM_OBJECT(item, AInventory); + PARAM_OBJECT_NOT_NULL(item, AInventory); self->RemoveInventory(item); return 0; } @@ -1009,7 +1009,7 @@ bool AActor::UseInventory (AInventory *item) DEFINE_ACTION_FUNCTION(AActor, UseInventory) { PARAM_SELF_PROLOGUE(AActor); - PARAM_OBJECT(item, AInventory); + PARAM_OBJECT_NOT_NULL(item, AInventory); ACTION_RETURN_BOOL(self->UseInventory(item)); } @@ -1042,7 +1042,7 @@ AInventory *AActor::DropInventory (AInventory *item) DEFINE_ACTION_FUNCTION(AActor, DropInventory) { PARAM_SELF_PROLOGUE(AActor); - PARAM_OBJECT(item, AInventory); + PARAM_OBJECT_NOT_NULL(item, AInventory); ACTION_RETURN_OBJECT(self->DropInventory(item)); } @@ -1263,7 +1263,7 @@ void AActor::CopyFriendliness (AActor *other, bool changeTarget, bool resetHealt DEFINE_ACTION_FUNCTION(AActor, CopyFriendliness) { PARAM_SELF_PROLOGUE(AActor); - PARAM_OBJECT(other, AActor); + PARAM_OBJECT_NOT_NULL(other, AActor); PARAM_BOOL_DEF(changetarget); PARAM_BOOL_DEF(resethealth); self->CopyFriendliness(other, changetarget, resethealth); @@ -1486,7 +1486,7 @@ void AActor::Touch (AActor *toucher) DEFINE_ACTION_FUNCTION(AActor, Touch) { PARAM_SELF_PROLOGUE(AActor); - PARAM_OBJECT(toucher, AActor); + PARAM_OBJECT_NOT_NULL(toucher, AActor); self->Touch(toucher); return 0; } @@ -2000,7 +2000,7 @@ bool AActor::CanSeek(AActor *target) const DEFINE_ACTION_FUNCTION(AActor, CanSeek) { PARAM_SELF_PROLOGUE(AActor); - PARAM_OBJECT(target, AActor); + PARAM_OBJECT_NOT_NULL(target, AActor); ACTION_RETURN_BOOL(self->CanSeek(target)); } @@ -4669,7 +4669,7 @@ AActor *AActor::StaticSpawn (PClassActor *type, const DVector3 &pos, replace_t a DEFINE_ACTION_FUNCTION(AActor, Spawn) { PARAM_PROLOGUE; - PARAM_CLASS(type, AActor); + PARAM_CLASS_NOT_NULL(type, AActor); PARAM_FLOAT_DEF(x); PARAM_FLOAT_DEF(y); PARAM_FLOAT_DEF(z); @@ -5656,6 +5656,8 @@ AActor *P_SpawnPuff (AActor *source, PClassActor *pufftype, const DVector3 &pos1 AActor *puff; DVector3 pos = pos1; + if (pufftype == nullptr) return nullptr; + if (!(flags & PF_NORANDOMZ)) pos.Z += pr_spawnpuff.Random2() / 64.; puff = Spawn(pufftype, pos, ALLOW_REPLACE); if (puff == NULL) return NULL; @@ -6163,7 +6165,7 @@ foundone: DEFINE_ACTION_FUNCTION(AActor, HitWater) { PARAM_SELF_PROLOGUE(AActor); - PARAM_POINTER(sec, sector_t); + PARAM_POINTER_NOT_NULL(sec, sector_t); PARAM_FLOAT(x); PARAM_FLOAT(y); PARAM_FLOAT(z); @@ -6383,7 +6385,7 @@ void P_PlaySpawnSound(AActor *missile, AActor *spawner) DEFINE_ACTION_FUNCTION(AActor, PlaySpawnSound) { PARAM_SELF_PROLOGUE(AActor); - PARAM_OBJECT(missile, AActor); + PARAM_OBJECT_NOT_NULL(missile, AActor); P_PlaySpawnSound(missile, self); return 0; } @@ -6415,47 +6417,11 @@ DEFINE_ACTION_FUNCTION(AActor, GetDefaultSpeed) // //--------------------------------------------------------------------------- -AActor *P_SpawnMissile (AActor *source, AActor *dest, PClassActor *type, AActor *owner) -{ - if (source == NULL) - { - return NULL; - } - return P_SpawnMissileXYZ (source->PosPlusZ(32 + source->GetBobOffset()), source, dest, type, true, owner); -} - -DEFINE_ACTION_FUNCTION(AActor, SpawnMissile) -{ - PARAM_SELF_PROLOGUE(AActor); - PARAM_OBJECT(dest, AActor); - PARAM_CLASS(type, AActor); - PARAM_OBJECT_DEF(owner, AActor); - ACTION_RETURN_OBJECT(P_SpawnMissile(self, dest, type, owner)); -} - -AActor *P_SpawnMissileZ (AActor *source, double z, AActor *dest, PClassActor *type) -{ - if (source == NULL) - { - return NULL; - } - return P_SpawnMissileXYZ (source->PosAtZ(z), source, dest, type); -} - -DEFINE_ACTION_FUNCTION(AActor, SpawnMissileZ) -{ - PARAM_SELF_PROLOGUE(AActor); - PARAM_FLOAT(z); - PARAM_OBJECT(dest, AActor); - PARAM_CLASS(type, AActor); - ACTION_RETURN_OBJECT(P_SpawnMissileZ(self, z, dest, type)); -} - AActor *P_SpawnMissileXYZ (DVector3 pos, AActor *source, AActor *dest, PClassActor *type, bool checkspawn, AActor *owner) { - if (source == NULL) + if (source == nullptr || type == nullptr) { - return NULL; + return nullptr; } if (dest == NULL) @@ -6530,19 +6496,56 @@ DEFINE_ACTION_FUNCTION(AActor, SpawnMissileXYZ) PARAM_FLOAT(x); PARAM_FLOAT(y); PARAM_FLOAT(z); - PARAM_OBJECT(dest, AActor); + PARAM_OBJECT_NOT_NULL(dest, AActor); PARAM_CLASS(type, AActor); PARAM_BOOL_DEF(check); PARAM_OBJECT_DEF(owner, AActor); ACTION_RETURN_OBJECT(P_SpawnMissileXYZ(DVector3(x,y,z), self, dest, type, check, owner)); } +AActor *P_SpawnMissile(AActor *source, AActor *dest, PClassActor *type, AActor *owner) +{ + if (source == nullptr) + { + return nullptr; + } + return P_SpawnMissileXYZ(source->PosPlusZ(32 + source->GetBobOffset()), source, dest, type, true, owner); +} + +DEFINE_ACTION_FUNCTION(AActor, SpawnMissile) +{ + PARAM_SELF_PROLOGUE(AActor); + PARAM_OBJECT_NOT_NULL(dest, AActor); + PARAM_CLASS(type, AActor); + PARAM_OBJECT_DEF(owner, AActor); + ACTION_RETURN_OBJECT(P_SpawnMissile(self, dest, type, owner)); +} + +AActor *P_SpawnMissileZ(AActor *source, double z, AActor *dest, PClassActor *type) +{ + if (source == nullptr) + { + return nullptr; + } + return P_SpawnMissileXYZ(source->PosAtZ(z), source, dest, type); +} + +DEFINE_ACTION_FUNCTION(AActor, SpawnMissileZ) +{ + PARAM_SELF_PROLOGUE(AActor); + PARAM_FLOAT(z); + PARAM_OBJECT_NOT_NULL(dest, AActor); + PARAM_CLASS(type, AActor); + ACTION_RETURN_OBJECT(P_SpawnMissileZ(self, z, dest, type)); +} + + AActor *P_OldSpawnMissile(AActor *source, AActor *owner, AActor *dest, PClassActor *type) { - if (source == NULL) + if (source == nullptr || type == nullptr) { - return NULL; + return nullptr; } AActor *th = Spawn (type, source->PosPlusZ(32.), ALLOW_REPLACE); @@ -6568,7 +6571,7 @@ AActor *P_OldSpawnMissile(AActor *source, AActor *owner, AActor *dest, PClassAct DEFINE_ACTION_FUNCTION(AActor, OldSpawnMissile) { PARAM_SELF_PROLOGUE(AActor); - PARAM_OBJECT(dest, AActor); + PARAM_OBJECT_NOT_NULL(dest, AActor); PARAM_CLASS(type, AActor); PARAM_OBJECT_DEF(owner, AActor); ACTION_RETURN_OBJECT(P_OldSpawnMissile(self, owner, dest, type)); @@ -6586,7 +6589,7 @@ DEFINE_ACTION_FUNCTION(AActor, OldSpawnMissile) AActor *P_SpawnMissileAngle (AActor *source, PClassActor *type, DAngle angle, double vz) { - if (source == NULL) + if (source == nullptr || type == nullptr) { return NULL; } @@ -6595,14 +6598,18 @@ AActor *P_SpawnMissileAngle (AActor *source, PClassActor *type, DAngle angle, do AActor *P_SpawnMissileAngleZ (AActor *source, double z, PClassActor *type, DAngle angle, double vz) { + if (type == nullptr) + { + return nullptr; + } return P_SpawnMissileAngleZSpeed (source, z, type, angle, vz, GetDefaultSpeed (type)); } AActor *P_SpawnMissileZAimed (AActor *source, double z, AActor *dest, PClassActor *type) { - if (source == NULL) + if (source == nullptr || type == nullptr) { - return NULL; + return nullptr; } DAngle an; double dist; @@ -6626,7 +6633,7 @@ DEFINE_ACTION_FUNCTION(AActor, SpawnMissileZAimed) { PARAM_SELF_PROLOGUE(AActor); PARAM_FLOAT(z); - PARAM_OBJECT(dest, AActor); + PARAM_OBJECT_NOT_NULL(dest, AActor); PARAM_CLASS(type, AActor); ACTION_RETURN_OBJECT(P_SpawnMissileZAimed(self, z, dest, type)); } @@ -6643,9 +6650,9 @@ DEFINE_ACTION_FUNCTION(AActor, SpawnMissileZAimed) AActor *P_SpawnMissileAngleZSpeed (AActor *source, double z, PClassActor *type, DAngle angle, double vz, double speed, AActor *owner, bool checkspawn) { - if (source == NULL) + if (source == nullptr || type == nullptr) { - return NULL; + return nullptr; } AActor *mo; @@ -6689,9 +6696,9 @@ AActor *P_SpawnSubMissile(AActor *source, PClassActor *type, AActor *target) { AActor *other = Spawn(type, source->Pos(), ALLOW_REPLACE); - if (other == NULL) + if (source == nullptr || type == nullptr) { - return NULL; + return nullptr; } other->target = target; @@ -6723,7 +6730,7 @@ DEFINE_ACTION_FUNCTION(AActor, SpawnSubMissile) { PARAM_SELF_PROLOGUE(AActor); PARAM_CLASS(cls, AActor); - PARAM_OBJECT(target, AActor); + PARAM_OBJECT_NOT_NULL(target, AActor); ACTION_RETURN_OBJECT(P_SpawnSubMissile(self, cls, target)); } /* @@ -6753,6 +6760,11 @@ AActor *P_SpawnPlayerMissile (AActor *source, double x, double y, double z, PClassActor *type, DAngle angle, FTranslatedLineTarget *pLineTarget, AActor **pMissileActor, bool nofreeaim, bool noautoaim, int aimflags) { + if (source == nullptr || type == nullptr) + { + return nullptr; + } + static const double angdiff[3] = { -5.625, 5.625, 0 }; DAngle an = angle; DAngle pitch; @@ -6760,10 +6772,6 @@ AActor *P_SpawnPlayerMissile (AActor *source, double x, double y, double z, AActor *defaultobject = GetDefaultByType(type); DAngle vrange = nofreeaim ? 35. : 0.; - if (source == NULL) - { - return NULL; - } if (!pLineTarget) pLineTarget = &scratch; if (source->player && source->player->ReadyWeapon && ((source->player->ReadyWeapon->WeaponFlags & WIF_NOAUTOAIM) || noautoaim)) { @@ -6910,7 +6918,7 @@ bool AActor::IsTeammate (AActor *other) DEFINE_ACTION_FUNCTION(AActor, isTeammate) { PARAM_SELF_PROLOGUE(AActor); - PARAM_OBJECT(other, AActor); + PARAM_OBJECT_NOT_NULL(other, AActor); ACTION_RETURN_BOOL(self->IsTeammate(other)); } @@ -6982,7 +6990,7 @@ bool AActor::IsFriend (AActor *other) DEFINE_ACTION_FUNCTION(AActor, isFriend) { PARAM_SELF_PROLOGUE(AActor); - PARAM_OBJECT(other, AActor); + PARAM_OBJECT_NOT_NULL(other, AActor); ACTION_RETURN_BOOL(self->IsFriend(other)); } @@ -7019,7 +7027,7 @@ bool AActor::IsHostile (AActor *other) DEFINE_ACTION_FUNCTION(AActor, isHostile) { PARAM_SELF_PROLOGUE(AActor); - PARAM_OBJECT(other, AActor); + PARAM_OBJECT_NOT_NULL(other, AActor); ACTION_RETURN_BOOL(self->IsHostile(other)); } @@ -7058,7 +7066,7 @@ int AActor::DoSpecialDamage (AActor *target, int damage, FName damagetype) DEFINE_ACTION_FUNCTION(AActor, DoSpecialDamage) { PARAM_SELF_PROLOGUE(AActor); - PARAM_OBJECT(target, AActor); + PARAM_OBJECT_NOT_NULL(target, AActor); PARAM_INT(damage); PARAM_NAME(damagetype); ACTION_RETURN_INT(self->DoSpecialDamage(target, damage, damagetype)); @@ -7580,14 +7588,14 @@ DEFINE_ACTION_FUNCTION(AActor, absangle) // should this be global? DEFINE_ACTION_FUNCTION(AActor, Distance2D) { PARAM_SELF_PROLOGUE(AActor); - PARAM_OBJECT(other, AActor); + PARAM_OBJECT_NOT_NULL(other, AActor); ACTION_RETURN_FLOAT(self->Distance2D(other)); } DEFINE_ACTION_FUNCTION(AActor, Distance3D) { PARAM_SELF_PROLOGUE(AActor); - PARAM_OBJECT(other, AActor); + PARAM_OBJECT_NOT_NULL(other, AActor); ACTION_RETURN_FLOAT(self->Distance3D(other)); } @@ -7620,7 +7628,7 @@ DEFINE_ACTION_FUNCTION(AActor, GetDefaultByType) { PARAM_PROLOGUE; PARAM_CLASS(cls, AActor); - ACTION_RETURN_OBJECT(GetDefaultByType(cls)); + ACTION_RETURN_OBJECT(cls == nullptr? nullptr : GetDefaultByType(cls)); } DEFINE_ACTION_FUNCTION(AActor, GetBobOffset) @@ -7692,7 +7700,7 @@ DEFINE_ACTION_FUNCTION(AActor, Thrust) DEFINE_ACTION_FUNCTION(AActor, AngleTo) { PARAM_SELF_PROLOGUE(AActor); - PARAM_OBJECT(targ, AActor); + PARAM_OBJECT_NOT_NULL(targ, AActor); PARAM_BOOL_DEF(absolute); ACTION_RETURN_FLOAT(self->AngleTo(targ, absolute).Degrees); } @@ -7717,7 +7725,7 @@ DEFINE_ACTION_FUNCTION(AActor, RotateVector) DEFINE_ACTION_FUNCTION(AActor, DistanceBySpeed) { PARAM_SELF_PROLOGUE(AActor); - PARAM_OBJECT(targ, AActor); + PARAM_OBJECT_NOT_NULL(targ, AActor); PARAM_FLOAT(speed); ACTION_RETURN_FLOAT(self->DistanceBySpeed(targ, speed)); } @@ -7745,14 +7753,14 @@ DEFINE_ACTION_FUNCTION(AActor, Vec2Angle) DEFINE_ACTION_FUNCTION(AActor, Vec3To) { PARAM_SELF_PROLOGUE(AActor); - PARAM_OBJECT(t, AActor) + PARAM_OBJECT_NOT_NULL(t, AActor) ACTION_RETURN_VEC3(self->Vec3To(t)); } DEFINE_ACTION_FUNCTION(AActor, Vec2To) { PARAM_SELF_PROLOGUE(AActor); - PARAM_OBJECT(t, AActor) + PARAM_OBJECT_NOT_NULL(t, AActor) ACTION_RETURN_VEC2(self->Vec2To(t)); } diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index 610ade35a..733741cb2 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -1605,38 +1605,40 @@ void player_t::DestroyPSprites() void P_SetSafeFlash(AWeapon *weapon, player_t *player, FState *flashstate, int index) { - - PClassActor *cls = weapon->GetClass(); - while (cls != RUNTIME_CLASS(AWeapon)) + if (flashstate != nullptr) { - if (flashstate >= cls->OwnedStates && flashstate < cls->OwnedStates + cls->NumOwnedStates) + PClassActor *cls = weapon->GetClass(); + while (cls != RUNTIME_CLASS(AWeapon)) { - // The flash state belongs to this class. - // Now let's check if the actually wanted state does also - if (flashstate + index < cls->OwnedStates + cls->NumOwnedStates) + if (flashstate >= cls->OwnedStates && flashstate < cls->OwnedStates + cls->NumOwnedStates) { - // we're ok so set the state - P_SetPsprite(player, PSP_FLASH, flashstate + index, true); - return; - } - else - { - // oh, no! The state is beyond the end of the state table so use the original flash state. - P_SetPsprite(player, PSP_FLASH, flashstate, true); - return; + // The flash state belongs to this class. + // Now let's check if the actually wanted state does also + if (flashstate + index < cls->OwnedStates + cls->NumOwnedStates) + { + // we're ok so set the state + P_SetPsprite(player, PSP_FLASH, flashstate + index, true); + return; + } + else + { + // oh, no! The state is beyond the end of the state table so use the original flash state. + P_SetPsprite(player, PSP_FLASH, flashstate, true); + return; + } } + // try again with parent class + cls = static_cast(cls->ParentClass); + } + // if we get here the state doesn't seem to belong to any class in the inheritance chain + // This can happen with Dehacked if the flash states are remapped. + // The only way to check this would be to go through all Dehacked modifiable actors, convert + // their states into a single flat array and find the correct one. + // Rather than that, just check to make sure it belongs to something. + if (FState::StaticFindStateOwner(flashstate + index) == NULL) + { // Invalid state. With no index offset, it should at least be valid. + index = 0; } - // try again with parent class - cls = static_cast(cls->ParentClass); - } - // if we get here the state doesn't seem to belong to any class in the inheritance chain - // This can happen with Dehacked if the flash states are remapped. - // The only way to check this would be to go through all Dehacked modifiable actors, convert - // their states into a single flat array and find the correct one. - // Rather than that, just check to make sure it belongs to something. - if (FState::StaticFindStateOwner(flashstate + index) == NULL) - { // Invalid state. With no index offset, it should at least be valid. - index = 0; } P_SetPsprite(player, PSP_FLASH, flashstate + index, true); } @@ -1644,7 +1646,7 @@ void P_SetSafeFlash(AWeapon *weapon, player_t *player, FState *flashstate, int i DEFINE_ACTION_FUNCTION(_PlayerInfo, SetSafeFlash) { PARAM_SELF_STRUCT_PROLOGUE(player_t); - PARAM_OBJECT(weapon, AWeapon); + PARAM_OBJECT_NOT_NULL(weapon, AWeapon); PARAM_POINTER(state, FState); PARAM_INT(index); P_SetSafeFlash(weapon, self, state, index); diff --git a/src/p_sight.cpp b/src/p_sight.cpp index 319d5b3ec..21aa1bbe3 100644 --- a/src/p_sight.cpp +++ b/src/p_sight.cpp @@ -908,7 +908,7 @@ done: DEFINE_ACTION_FUNCTION(AActor, CheckSight) { PARAM_SELF_PROLOGUE(AActor); - PARAM_OBJECT(target, AActor); + PARAM_OBJECT_NOT_NULL(target, AActor); PARAM_INT_DEF(flags); ACTION_RETURN_BOOL(P_CheckSight(self, target, flags)); } diff --git a/src/p_states.cpp b/src/p_states.cpp index 7daaa5e41..87a1bae2f 100644 --- a/src/p_states.cpp +++ b/src/p_states.cpp @@ -1083,11 +1083,12 @@ DEFINE_ACTION_FUNCTION(FState, DistanceTo) { PARAM_SELF_STRUCT_PROLOGUE(FState); PARAM_POINTER(other, FState); - - // Safely calculate the distance between two states. - auto o1 = FState::StaticFindStateOwner(self); - int retv; - if (other < o1->OwnedStates || other >= o1->OwnedStates + o1->NumOwnedStates) retv = INT_MIN; - else retv = int(other - self); + int retv = INT_MIN; + if (other != nullptr) + { + // Safely calculate the distance between two states. + auto o1 = FState::StaticFindStateOwner(self); + if (other >= o1->OwnedStates && other < o1->OwnedStates + o1->NumOwnedStates) retv = int(other - self); + } ACTION_RETURN_INT(retv); } diff --git a/src/scripting/codegeneration/codegen.cpp b/src/scripting/codegeneration/codegen.cpp index 20c98acbe..3a2dc6034 100644 --- a/src/scripting/codegeneration/codegen.cpp +++ b/src/scripting/codegeneration/codegen.cpp @@ -9697,7 +9697,7 @@ int BuiltinClassCast(VMValue *param, TArray &defaultparam, int numparam PARAM_PROLOGUE; PARAM_CLASS(from, DObject); PARAM_CLASS(to, DObject); - ACTION_RETURN_OBJECT(from->IsDescendantOf(to) ? from : nullptr); + ACTION_RETURN_OBJECT(from && to && from->IsDescendantOf(to) ? from : nullptr); } ExpEmit FxClassPtrCast::Emit(VMFunctionBuilder *build) diff --git a/src/scripting/vm/vm.h b/src/scripting/vm/vm.h index 0ccde006f..d105d396c 100644 --- a/src/scripting/vm/vm.h +++ b/src/scripting/vm/vm.h @@ -951,6 +951,9 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction // Use these to collect the parameters in a native function. // variable name at position

+void NullParam(const char *varname); + +#define PARAM_NULLCHECK(ptr, var) (ptr == nullptr? NullParam(#var), ptr : ptr) // For required parameters. #define PARAM_INT_AT(p,x) assert((p) < numparam); assert(param[p].Type == REGT_INT); int x = param[p].i; @@ -966,6 +969,9 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction #define PARAM_POINTER_AT(p,x,type) assert((p) < numparam); assert(param[p].Type == REGT_POINTER); type *x = (type *)param[p].a; #define PARAM_OBJECT_AT(p,x,type) assert((p) < numparam); assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_OBJECT || param[p].a == NULL)); type *x = (type *)param[p].a; assert(x == NULL || x->IsKindOf(RUNTIME_CLASS(type))); #define PARAM_CLASS_AT(p,x,base) assert((p) < numparam); assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_OBJECT || param[p].a == NULL)); base::MetaClass *x = (base::MetaClass *)param[p].a; assert(x == NULL || x->IsDescendantOf(RUNTIME_CLASS(base))); +#define PARAM_POINTER_NOT_NULL_AT(p,x,type) assert((p) < numparam); assert(param[p].Type == REGT_POINTER); type *x = (type *)PARAM_NULLCHECK(param[p].a, #x); +#define PARAM_OBJECT_NOT_NULL_AT(p,x,type) assert((p) < numparam); assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_OBJECT || param[p].a == NULL)); type *x = (type *)PARAM_NULLCHECK(param[p].a, #x); assert(x == NULL || x->IsKindOf(RUNTIME_CLASS(type))); +#define PARAM_CLASS_NOT_NULL_AT(p,x,base) assert((p) < numparam); assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_OBJECT || param[p].a == NULL)); base::MetaClass *x = (base::MetaClass *)PARAM_NULLCHECK(param[p].a, #x); assert(x == NULL || x->IsDescendantOf(RUNTIME_CLASS(base))); #define PARAM_EXISTS(p) ((p) < numparam) #define ASSERTINT(p) assert((p).Type == REGT_INT) @@ -988,6 +994,7 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction #define PARAM_POINTER_DEF_AT(p,x,t) t *x; if (PARAM_EXISTS(p)) { ASSERTPOINTER(param[p]); x = (t*)param[p].a; } else { ASSERTPOINTER(defaultparam[p]); x = (t*)defaultparam[p].a; } #define PARAM_OBJECT_DEF_AT(p,x,t) t *x; if (PARAM_EXISTS(p)) { ASSERTOBJECT(param[p]); x = (t*)param[p].a; } else { ASSERTOBJECT(defaultparam[p]); x = (t*)defaultparam[p].a; } #define PARAM_CLASS_DEF_AT(p,x,t) t::MetaClass *x; if (PARAM_EXISTS(p)) { ASSERTOBJECT(param[p]); x = (t::MetaClass*)param[p].a; } else { ASSERTOBJECT(defaultparam[p]); x = (t::MetaClass*)defaultparam[p].a; } +#define PARAM_CLASS_DEF_NOT_NULL_AT(p,x,t) t::MetaClass *x; if (PARAM_EXISTS(p)) { ASSERTOBJECT(param[p]); x = (t::MetaClass*)PARAM_NULLCHECK(param[p].a, #x); } else { ASSERTOBJECT(defaultparam[p]); x = (t::MetaClass*)PARAM_NULLCHECK(defaultparam[p].a, #x); } // The above, but with an automatically increasing position index. #define PARAM_PROLOGUE int paramnum = -1; @@ -1005,6 +1012,9 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction #define PARAM_POINTER(x,type) ++paramnum; PARAM_POINTER_AT(paramnum,x,type) #define PARAM_OBJECT(x,type) ++paramnum; PARAM_OBJECT_AT(paramnum,x,type) #define PARAM_CLASS(x,base) ++paramnum; PARAM_CLASS_AT(paramnum,x,base) +#define PARAM_POINTER_NOT_NULL(x,type) ++paramnum; PARAM_POINTER_NOT_NULL_AT(paramnum,x,type) +#define PARAM_OBJECT_NOT_NULL(x,type) ++paramnum; PARAM_OBJECT_NOT_NULL_AT(paramnum,x,type) +#define PARAM_CLASS_NOT_NULL(x,base) ++paramnum; PARAM_CLASS_NOT_NULL_AT(paramnum,x,base) #define PARAM_INT_DEF(x) ++paramnum; PARAM_INT_DEF_AT(paramnum,x) #define PARAM_BOOL_DEF(x) ++paramnum; PARAM_BOOL_DEF_AT(paramnum,x) @@ -1019,6 +1029,7 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction #define PARAM_POINTER_DEF(x,type) ++paramnum; PARAM_POINTER_DEF_AT(paramnum,x,type) #define PARAM_OBJECT_DEF(x,type) ++paramnum; PARAM_OBJECT_DEF_AT(paramnum,x,type) #define PARAM_CLASS_DEF(x,base) ++paramnum; PARAM_CLASS_DEF_AT(paramnum,x,base) +#define PARAM_CLASS_DEF_NOT_NULL(x,base) ++paramnum; PARAM_CLASS_DEF_NOT_NULL_AT(paramnum,x,base) typedef int(*actionf_p)(VMValue *param, TArray &defaultparam, int numparam, VMReturn *ret, int numret);/*(VM_ARGS)*/ diff --git a/src/scripting/vm/vmexec.cpp b/src/scripting/vm/vmexec.cpp index f51038f36..183cc728c 100644 --- a/src/scripting/vm/vmexec.cpp +++ b/src/scripting/vm/vmexec.cpp @@ -228,3 +228,7 @@ void VMFillParams(VMValue *params, VMFrame *callee, int numparam) } } } + +void NullParam(const char *varname) +{ +} \ No newline at end of file