- scriptified cht_Give and cht_Take and made them virtual function of PlayerPawn so that this can be better configured for mods that want other options in here.
- improved the class pointer to string cast to print the actual type it describes and not the class pointer's own type. - fixed: The 'is' operator created non-working code when checking the inheritance of a class pointer, it only worked for objects.
This commit is contained in:
parent
75d3f42d4f
commit
14f2c39e58
21 changed files with 559 additions and 461 deletions
442
src/m_cheat.cpp
442
src/m_cheat.cpp
|
|
@ -50,6 +50,7 @@
|
|||
#include "a_armor.h"
|
||||
#include "a_ammo.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "virtual.h"
|
||||
|
||||
// [RH] Actually handle the cheat. The cheat code in st_stuff.c now just
|
||||
// writes some bytes to the network data stream, and the network code
|
||||
|
|
@ -324,16 +325,10 @@ void cht_DoCheat (player_t *player, int cheat)
|
|||
}
|
||||
else
|
||||
{
|
||||
player->mo->Revive();
|
||||
player->playerstate = PST_LIVE;
|
||||
player->health = player->mo->health = player->mo->GetDefault()->health;
|
||||
player->viewheight = ((APlayerPawn *)player->mo->GetDefault())->ViewHeight;
|
||||
player->mo->flags = player->mo->GetDefault()->flags;
|
||||
player->mo->flags2 = player->mo->GetDefault()->flags2;
|
||||
player->mo->flags3 = player->mo->GetDefault()->flags3;
|
||||
player->mo->flags4 = player->mo->GetDefault()->flags4;
|
||||
player->mo->flags5 = player->mo->GetDefault()->flags5;
|
||||
player->mo->flags6 = player->mo->GetDefault()->flags6;
|
||||
player->mo->flags7 = player->mo->GetDefault()->flags7;
|
||||
player->mo->renderflags &= ~RF_INVISIBLE;
|
||||
player->mo->Height = player->mo->GetDefault()->Height;
|
||||
player->mo->radius = player->mo->GetDefault()->radius;
|
||||
|
|
@ -344,7 +339,6 @@ void cht_DoCheat (player_t *player, int cheat)
|
|||
{
|
||||
player->mo->Translation = TRANSLATION(TRANSLATION_Players, BYTE(player-players));
|
||||
}
|
||||
player->mo->DamageType = NAME_None;
|
||||
if (player->ReadyWeapon != nullptr)
|
||||
{
|
||||
P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->GetUpState());
|
||||
|
|
@ -588,434 +582,24 @@ const char *cht_Morph (player_t *player, PClassPlayerPawn *morphclass, bool quic
|
|||
|
||||
void cht_Give (player_t *player, const char *name, int amount)
|
||||
{
|
||||
enum { ALL_NO, ALL_YES, ALL_YESYES } giveall;
|
||||
int i;
|
||||
PClassActor *type;
|
||||
if (player->mo == nullptr) return;
|
||||
|
||||
if (player != &players[consoleplayer])
|
||||
Printf ("%s is a cheater: give %s\n", player->userinfo.GetName(), name);
|
||||
|
||||
if (player->mo == NULL || player->health <= 0)
|
||||
IFVIRTUALPTR(player->mo, APlayerPawn, CheatGive)
|
||||
{
|
||||
return;
|
||||
VMValue params[3] = { player->mo, FString(name), amount };
|
||||
GlobalVMStack.Call(func, params, 3, nullptr, 0);
|
||||
}
|
||||
|
||||
giveall = ALL_NO;
|
||||
if (stricmp (name, "all") == 0)
|
||||
{
|
||||
giveall = ALL_YES;
|
||||
}
|
||||
else if (stricmp (name, "everything") == 0)
|
||||
{
|
||||
giveall = ALL_YESYES;
|
||||
}
|
||||
|
||||
if (stricmp (name, "health") == 0)
|
||||
{
|
||||
if (amount > 0)
|
||||
{
|
||||
player->mo->health += amount;
|
||||
player->health = player->mo->health;
|
||||
}
|
||||
else
|
||||
{
|
||||
player->health = player->mo->health = player->mo->GetMaxHealth();
|
||||
}
|
||||
}
|
||||
|
||||
if (giveall || stricmp (name, "backpack") == 0)
|
||||
{
|
||||
// Select the correct type of backpack based on the game
|
||||
type = PClass::FindActor(gameinfo.backpacktype);
|
||||
if (type != NULL)
|
||||
{
|
||||
player->mo->GiveInventory(static_cast<PClassInventory *>(type), 1, true);
|
||||
}
|
||||
|
||||
if (!giveall)
|
||||
return;
|
||||
}
|
||||
|
||||
if (giveall || stricmp (name, "ammo") == 0)
|
||||
{
|
||||
// Find every unique type of ammo. Give it to the player if
|
||||
// he doesn't have it already, and set each to its maximum.
|
||||
for (unsigned int i = 0; i < PClassActor::AllActorClasses.Size(); ++i)
|
||||
{
|
||||
PClassActor *type = PClassActor::AllActorClasses[i];
|
||||
|
||||
if (type->ParentClass == RUNTIME_CLASS(AAmmo))
|
||||
{
|
||||
PClassInventory *atype = static_cast<PClassInventory *>(type);
|
||||
AInventory *ammo = player->mo->FindInventory(atype);
|
||||
if (ammo == NULL)
|
||||
{
|
||||
ammo = static_cast<AInventory *>(Spawn (atype));
|
||||
ammo->AttachToOwner (player->mo);
|
||||
ammo->Amount = ammo->MaxAmount;
|
||||
}
|
||||
else if (ammo->Amount < ammo->MaxAmount)
|
||||
{
|
||||
ammo->Amount = ammo->MaxAmount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!giveall)
|
||||
return;
|
||||
}
|
||||
|
||||
if (giveall || stricmp (name, "armor") == 0)
|
||||
{
|
||||
if (gameinfo.gametype != GAME_Hexen)
|
||||
{
|
||||
ABasicArmorPickup *armor = Spawn<ABasicArmorPickup> ();
|
||||
armor->SaveAmount = 100*deh.BlueAC;
|
||||
armor->SavePercent = gameinfo.Armor2Percent > 0? gameinfo.Armor2Percent : 0.5;
|
||||
if (!armor->CallTryPickup (player->mo))
|
||||
{
|
||||
armor->Destroy ();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
AHexenArmor *armor = Spawn<AHexenArmor> ();
|
||||
armor->health = i;
|
||||
armor->Amount = 0;
|
||||
if (!armor->CallTryPickup (player->mo))
|
||||
{
|
||||
armor->Destroy ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!giveall)
|
||||
return;
|
||||
}
|
||||
|
||||
if (giveall || stricmp (name, "keys") == 0)
|
||||
{
|
||||
for (unsigned int i = 0; i < PClassActor::AllActorClasses.Size(); ++i)
|
||||
{
|
||||
if (PClassActor::AllActorClasses[i]->IsDescendantOf (RUNTIME_CLASS(AKey)))
|
||||
{
|
||||
AKey *key = (AKey *)GetDefaultByType (PClassActor::AllActorClasses[i]);
|
||||
if (key->KeyNumber != 0)
|
||||
{
|
||||
key = static_cast<AKey *>(Spawn(static_cast<PClassActor *>(PClassActor::AllActorClasses[i])));
|
||||
if (!key->CallTryPickup (player->mo))
|
||||
{
|
||||
key->Destroy ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!giveall)
|
||||
return;
|
||||
}
|
||||
|
||||
if (giveall || stricmp (name, "weapons") == 0)
|
||||
{
|
||||
AWeapon *savedpending = player->PendingWeapon;
|
||||
for (unsigned int i = 0; i < PClassActor::AllActorClasses.Size(); ++i)
|
||||
{
|
||||
type = PClassActor::AllActorClasses[i];
|
||||
// Don't give replaced weapons unless the replacement was done by Dehacked.
|
||||
if (type != RUNTIME_CLASS(AWeapon) &&
|
||||
type->IsDescendantOf (RUNTIME_CLASS(AWeapon)) &&
|
||||
(static_cast<PClassActor *>(type)->GetReplacement() == type ||
|
||||
static_cast<PClassActor *>(type)->GetReplacement()->IsDescendantOf(RUNTIME_CLASS(ADehackedPickup))))
|
||||
{
|
||||
// Give the weapon only if it belongs to the current game or
|
||||
if (player->weapons.LocateWeapon(static_cast<PClassWeapon*>(type), NULL, NULL))
|
||||
{
|
||||
AWeapon *def = (AWeapon*)GetDefaultByType (type);
|
||||
if (giveall == ALL_YESYES || !(def->WeaponFlags & WIF_CHEATNOTWEAPON))
|
||||
{
|
||||
player->mo->GiveInventory(static_cast<PClassInventory *>(type), 1, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
player->PendingWeapon = savedpending;
|
||||
|
||||
if (!giveall)
|
||||
return;
|
||||
}
|
||||
|
||||
if (giveall || stricmp (name, "artifacts") == 0)
|
||||
{
|
||||
auto pitype = PClass::FindActor(NAME_PuzzleItem);
|
||||
|
||||
for (unsigned int i = 0; i < PClassActor::AllActorClasses.Size(); ++i)
|
||||
{
|
||||
type = PClassActor::AllActorClasses[i];
|
||||
if (type->IsDescendantOf (RUNTIME_CLASS(AInventory)))
|
||||
{
|
||||
AInventory *def = (AInventory*)GetDefaultByType (type);
|
||||
if (def->Icon.isValid() && def->MaxAmount > 1 &&
|
||||
!type->IsDescendantOf (pitype) &&
|
||||
!type->IsDescendantOf (RUNTIME_CLASS(APowerup)) &&
|
||||
!type->IsDescendantOf (RUNTIME_CLASS(AArmor)))
|
||||
{
|
||||
// Do not give replaced items unless using "give everything"
|
||||
if (giveall == ALL_YESYES || type->GetReplacement() == type)
|
||||
{
|
||||
player->mo->GiveInventory(static_cast<PClassInventory *>(type), amount <= 0 ? def->MaxAmount : amount, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!giveall)
|
||||
return;
|
||||
}
|
||||
|
||||
if (giveall || stricmp (name, "puzzlepieces") == 0)
|
||||
{
|
||||
auto pitype = PClass::FindActor(NAME_PuzzleItem);
|
||||
for (unsigned int i = 0; i < PClassActor::AllActorClasses.Size(); ++i)
|
||||
{
|
||||
type = PClassActor::AllActorClasses[i];
|
||||
if (type->IsDescendantOf (pitype))
|
||||
{
|
||||
AInventory *def = (AInventory*)GetDefaultByType (type);
|
||||
if (def->Icon.isValid())
|
||||
{
|
||||
// Do not give replaced items unless using "give everything"
|
||||
if (giveall == ALL_YESYES || type->GetReplacement() == type)
|
||||
{
|
||||
player->mo->GiveInventory(static_cast<PClassInventory *>(type), amount <= 0 ? def->MaxAmount : amount, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!giveall)
|
||||
return;
|
||||
}
|
||||
|
||||
if (giveall)
|
||||
return;
|
||||
|
||||
type = PClass::FindActor(name);
|
||||
if (type == NULL || !type->IsDescendantOf (RUNTIME_CLASS(AInventory)))
|
||||
{
|
||||
if (player == &players[consoleplayer])
|
||||
Printf ("Unknown item \"%s\"\n", name);
|
||||
}
|
||||
else
|
||||
{
|
||||
player->mo->GiveInventory(static_cast<PClassInventory *>(type), amount, true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void cht_Take (player_t *player, const char *name, int amount)
|
||||
{
|
||||
bool takeall;
|
||||
PClassActor *type;
|
||||
if (player->mo == nullptr) return;
|
||||
|
||||
if (player->mo == NULL || player->health <= 0)
|
||||
IFVIRTUALPTR(player->mo, APlayerPawn, CheatTake)
|
||||
{
|
||||
return;
|
||||
VMValue params[3] = { player->mo, FString(name), amount };
|
||||
GlobalVMStack.Call(func, params, 3, nullptr, 0);
|
||||
}
|
||||
|
||||
takeall = (stricmp (name, "all") == 0);
|
||||
|
||||
if (!takeall && stricmp (name, "health") == 0)
|
||||
{
|
||||
if (player->mo->health - amount <= 0
|
||||
|| player->health - amount <= 0
|
||||
|| amount == 0)
|
||||
{
|
||||
|
||||
cht_Suicide (player);
|
||||
|
||||
if (player == &players[consoleplayer])
|
||||
C_HideConsole ();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (amount > 0)
|
||||
{
|
||||
if (player->mo)
|
||||
{
|
||||
player->mo->health -= amount;
|
||||
player->health = player->mo->health;
|
||||
}
|
||||
else
|
||||
{
|
||||
player->health -= amount;
|
||||
}
|
||||
}
|
||||
|
||||
if (!takeall)
|
||||
return;
|
||||
}
|
||||
|
||||
if (takeall || stricmp (name, "backpack") == 0)
|
||||
{
|
||||
// Take away all types of backpacks the player might own.
|
||||
for (unsigned int i = 0; i < PClassActor::AllActorClasses.Size(); ++i)
|
||||
{
|
||||
PClass *type = PClassActor::AllActorClasses[i];
|
||||
|
||||
if (type->IsDescendantOf(PClass::FindClass(NAME_BackpackItem)))
|
||||
{
|
||||
AInventory *pack = player->mo->FindInventory(static_cast<PClassActor *>(type));
|
||||
|
||||
if (pack)
|
||||
pack->Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
if (!takeall)
|
||||
return;
|
||||
}
|
||||
|
||||
if (takeall || stricmp (name, "ammo") == 0)
|
||||
{
|
||||
for (unsigned int i = 0; i < PClassActor::AllActorClasses.Size(); ++i)
|
||||
{
|
||||
PClass *type = PClassActor::AllActorClasses[i];
|
||||
|
||||
if (type->ParentClass == RUNTIME_CLASS (AAmmo))
|
||||
{
|
||||
AInventory *ammo = player->mo->FindInventory(static_cast<PClassActor *>(type));
|
||||
|
||||
if (ammo)
|
||||
ammo->DepleteOrDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
if (!takeall)
|
||||
return;
|
||||
}
|
||||
|
||||
if (takeall || stricmp (name, "armor") == 0)
|
||||
{
|
||||
for (unsigned int i = 0; i < PClassActor::AllActorClasses.Size(); ++i)
|
||||
{
|
||||
type = PClassActor::AllActorClasses[i];
|
||||
|
||||
if (type->IsDescendantOf (RUNTIME_CLASS (AArmor)))
|
||||
{
|
||||
AInventory *armor = player->mo->FindInventory(static_cast<PClassActor *>(type));
|
||||
|
||||
if (armor)
|
||||
armor->DepleteOrDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
if (!takeall)
|
||||
return;
|
||||
}
|
||||
|
||||
if (takeall || stricmp (name, "keys") == 0)
|
||||
{
|
||||
for (unsigned int i = 0; i < PClassActor::AllActorClasses.Size(); ++i)
|
||||
{
|
||||
type = PClassActor::AllActorClasses[i];
|
||||
|
||||
if (type->IsDescendantOf (RUNTIME_CLASS (AKey)))
|
||||
{
|
||||
AActor *key = player->mo->FindInventory(static_cast<PClassActor *>(type));
|
||||
|
||||
if (key)
|
||||
key->Destroy ();
|
||||
}
|
||||
}
|
||||
|
||||
if (!takeall)
|
||||
return;
|
||||
}
|
||||
|
||||
if (takeall || stricmp (name, "weapons") == 0)
|
||||
{
|
||||
for (unsigned int i = 0; i < PClassActor::AllActorClasses.Size(); ++i)
|
||||
{
|
||||
type = PClassActor::AllActorClasses[i];
|
||||
|
||||
if (type != RUNTIME_CLASS(AWeapon) &&
|
||||
type->IsDescendantOf (RUNTIME_CLASS (AWeapon)))
|
||||
{
|
||||
AActor *weapon = player->mo->FindInventory(static_cast<PClassActor *>(type));
|
||||
|
||||
if (weapon)
|
||||
weapon->Destroy ();
|
||||
|
||||
player->ReadyWeapon = nullptr;
|
||||
player->PendingWeapon = WP_NOCHANGE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!takeall)
|
||||
return;
|
||||
}
|
||||
|
||||
if (takeall || stricmp (name, "artifacts") == 0)
|
||||
{
|
||||
auto pitype = PClass::FindActor(NAME_PuzzleItem);
|
||||
for (unsigned int i = 0; i < PClassActor::AllActorClasses.Size(); ++i)
|
||||
{
|
||||
type = PClassActor::AllActorClasses[i];
|
||||
|
||||
if (type->IsDescendantOf (RUNTIME_CLASS (AInventory)))
|
||||
{
|
||||
if (!type->IsDescendantOf (pitype) &&
|
||||
!type->IsDescendantOf (RUNTIME_CLASS (APowerup)) &&
|
||||
!type->IsDescendantOf (RUNTIME_CLASS (AArmor)) &&
|
||||
!type->IsDescendantOf (RUNTIME_CLASS (AWeapon)) &&
|
||||
!type->IsDescendantOf (RUNTIME_CLASS (AKey)))
|
||||
{
|
||||
AActor *artifact = player->mo->FindInventory(static_cast<PClassActor *>(type));
|
||||
|
||||
if (artifact)
|
||||
artifact->Destroy ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!takeall)
|
||||
return;
|
||||
}
|
||||
|
||||
if (takeall || stricmp (name, "puzzlepieces") == 0)
|
||||
{
|
||||
auto pitype = PClass::FindActor(NAME_PuzzleItem);
|
||||
for (unsigned int i = 0; i < PClassActor::AllActorClasses.Size(); ++i)
|
||||
{
|
||||
type = PClassActor::AllActorClasses[i];
|
||||
|
||||
if (type->IsDescendantOf (pitype))
|
||||
{
|
||||
AActor *puzzlepiece = player->mo->FindInventory(static_cast<PClassActor *>(type));
|
||||
|
||||
if (puzzlepiece)
|
||||
puzzlepiece->Destroy ();
|
||||
}
|
||||
}
|
||||
|
||||
if (!takeall)
|
||||
return;
|
||||
}
|
||||
|
||||
if (takeall)
|
||||
return;
|
||||
|
||||
type = PClass::FindActor (name);
|
||||
if (type == NULL || !type->IsDescendantOf (RUNTIME_CLASS (AInventory)))
|
||||
{
|
||||
if (player == &players[consoleplayer])
|
||||
Printf ("Unknown item \"%s\"\n", name);
|
||||
}
|
||||
else
|
||||
{
|
||||
player->mo->TakeInventory(type, amount ? amount : 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
class DSuicider : public DThinker
|
||||
|
|
@ -1070,6 +654,12 @@ void cht_Suicide (player_t *plyr)
|
|||
}
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(APlayerPawn, CheatSuicide)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(APlayerPawn);
|
||||
cht_Suicide(self->player);
|
||||
return 0;
|
||||
}
|
||||
|
||||
CCMD (mdk)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue