mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2025-01-18 14:41:40 +00:00
- 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
|
@ -1326,6 +1326,12 @@ void C_HideConsole ()
|
|||
}
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_Console, HideConsole)
|
||||
{
|
||||
C_HideConsole();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool C_HandleKey (event_t *ev, FCommandBuffer &buffer)
|
||||
{
|
||||
int data1 = ev->data1;
|
||||
|
|
|
@ -219,6 +219,7 @@ DEFINE_FIELD_X(DehInfo, DehInfo, ExplosionStyle)
|
|||
DEFINE_FIELD_X(DehInfo, DehInfo, ExplosionAlpha)
|
||||
DEFINE_FIELD_X(DehInfo, DehInfo, NoAutofreeze)
|
||||
DEFINE_FIELD_X(DehInfo, DehInfo, BFGCells)
|
||||
DEFINE_FIELD_X(DehInfo, DehInfo, BlueAC)
|
||||
|
||||
// Doom identified pickup items by their sprites. ZDoom prefers to use their
|
||||
// class type to identify them instead. To support the traditional Doom
|
||||
|
|
|
@ -1288,6 +1288,19 @@ bool FWeaponSlots::LocateWeapon (PClassWeapon *type, int *const slot, int *const
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
DEFINE_ACTION_FUNCTION(FWeaponSlots, LocateWeapon)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FWeaponSlots);
|
||||
PARAM_CLASS(weap, AWeapon);
|
||||
int slot = 0, index = 0;
|
||||
bool retv = self->LocateWeapon(weap, &slot, &index);
|
||||
if (numret >= 1) ret[0].SetInt(retv);
|
||||
if (numret >= 2) ret[1].SetInt(slot);
|
||||
if (numret >= 3) ret[2].SetInt(index);
|
||||
return MIN(numret, 3);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// FindMostRecentWeapon
|
||||
|
|
|
@ -45,6 +45,10 @@
|
|||
|
||||
gameinfo_t gameinfo;
|
||||
|
||||
DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, backpacktype)
|
||||
DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, Armor2Percent)
|
||||
|
||||
|
||||
const char *GameNames[17] =
|
||||
{
|
||||
NULL, "Doom", "Heretic", NULL, "Hexen", NULL, NULL, NULL, "Strife", NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Chex"
|
||||
|
|
2
src/gi.h
2
src/gi.h
|
@ -148,7 +148,7 @@ struct gameinfo_t
|
|||
FString translator;
|
||||
DWORD defaultbloodcolor;
|
||||
DWORD defaultbloodparticlecolor;
|
||||
FString backpacktype;
|
||||
FName backpacktype;
|
||||
FString statusbar;
|
||||
FString intermissionMusic;
|
||||
int intermissionOrder;
|
||||
|
|
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)
|
||||
{
|
||||
|
|
|
@ -1224,22 +1224,6 @@ DEFINE_ACTION_FUNCTION(AActor, CheckInventory)
|
|||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// State jump function
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_ACTION_FUNCTION(AActor, CheckArmorType)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_NAME (type);
|
||||
PARAM_INT_DEF(amount);
|
||||
|
||||
ABasicArmor *armor = (ABasicArmor *)self->FindInventory(NAME_BasicArmor);
|
||||
|
||||
ACTION_RETURN_BOOL(armor && armor->ArmorType == type && armor->Amount >= amount);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Parameterized version of A_Explode
|
||||
|
|
|
@ -822,11 +822,13 @@ bool AActor::GiveInventory(PClassInventory *type, int amount, bool givecheat)
|
|||
return result;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, Inventory)
|
||||
DEFINE_ACTION_FUNCTION(AActor, GiveInventory)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_OBJECT_NOT_NULL(item, AInventory);
|
||||
ACTION_RETURN_BOOL(self->UseInventory(item));
|
||||
PARAM_CLASS(type, AInventory);
|
||||
PARAM_INT(amount);
|
||||
PARAM_BOOL_DEF(givecheat);
|
||||
ACTION_RETURN_BOOL(self->GiveInventory(type, amount, givecheat));
|
||||
}
|
||||
|
||||
|
||||
|
@ -918,6 +920,16 @@ bool AActor::TakeInventory(PClassActor *itemclass, int amount, bool fromdecorate
|
|||
return result;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, TakeInventory)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_OBJECT_NOT_NULL(item, AInventory);
|
||||
PARAM_INT(amount);
|
||||
PARAM_BOOL_DEF(fromdecorate);
|
||||
PARAM_BOOL_DEF(notakeinfinite);
|
||||
self->RemoveInventory(item);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
|
|
|
@ -638,6 +638,14 @@ void player_t::SendPitchLimits() const
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_PlayerInfo, GetUserName)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(player_t);
|
||||
ACTION_RETURN_STRING(self->userinfo.GetName());
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APlayerPawn
|
||||
|
|
|
@ -4362,9 +4362,8 @@ ExpEmit FxDotCross::Emit(VMFunctionBuilder *build)
|
|||
FxTypeCheck::FxTypeCheck(FxExpression *l, FxExpression *r)
|
||||
: FxExpression(EFX_TypeCheck, l->ScriptPosition)
|
||||
{
|
||||
left = new FxTypeCast(l, NewPointer(RUNTIME_CLASS(DObject)), false);
|
||||
right = new FxClassTypeCast(NewClassPointer(RUNTIME_CLASS(DObject)), r);
|
||||
EmitTail = false;
|
||||
left = l;
|
||||
right = r;
|
||||
ValueType = TypeBool;
|
||||
}
|
||||
|
||||
|
@ -4389,9 +4388,27 @@ FxTypeCheck::~FxTypeCheck()
|
|||
FxExpression *FxTypeCheck::Resolve(FCompileContext& ctx)
|
||||
{
|
||||
CHECKRESOLVED();
|
||||
// This must resolve the cast separately so that it can set the proper type for class descriptors.
|
||||
RESOLVE(left, ctx);
|
||||
RESOLVE(right, ctx);
|
||||
ABORT(right && left);
|
||||
|
||||
if (left->ValueType->IsKindOf(RUNTIME_CLASS(PClassPointer)))
|
||||
{
|
||||
left = new FxClassTypeCast(NewClassPointer(RUNTIME_CLASS(DObject)), left);
|
||||
ClassCheck = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
left = new FxTypeCast(left, NewPointer(RUNTIME_CLASS(DObject)), false);
|
||||
ClassCheck = false;
|
||||
}
|
||||
right = new FxClassTypeCast(NewClassPointer(RUNTIME_CLASS(DObject)), right);
|
||||
|
||||
RESOLVE(left, ctx);
|
||||
RESOLVE(right, ctx);
|
||||
ABORT(right && left);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -4408,7 +4425,8 @@ ExpEmit FxTypeCheck::EmitCommon(VMFunctionBuilder *build)
|
|||
castee.Free(build);
|
||||
casttype.Free(build);
|
||||
ExpEmit ares(build, REGT_POINTER);
|
||||
build->Emit(casttype.Konst ? OP_DYNCAST_K : OP_DYNCAST_R, ares.RegNum, castee.RegNum, casttype.RegNum);
|
||||
if (!ClassCheck) build->Emit(casttype.Konst ? OP_DYNCAST_K : OP_DYNCAST_R, ares.RegNum, castee.RegNum, casttype.RegNum);
|
||||
else build->Emit(casttype.Konst ? OP_DYNCASTC_K : OP_DYNCASTC_R, ares.RegNum, castee.RegNum, casttype.RegNum);
|
||||
return ares;
|
||||
}
|
||||
|
||||
|
|
|
@ -1086,7 +1086,7 @@ class FxTypeCheck : public FxExpression
|
|||
public:
|
||||
FxExpression *left;
|
||||
FxExpression *right;
|
||||
bool EmitTail;
|
||||
bool ClassCheck;
|
||||
|
||||
FxTypeCheck(FxExpression*, FxExpression*);
|
||||
~FxTypeCheck();
|
||||
|
|
|
@ -788,6 +788,11 @@ void InitThingdef()
|
|||
PField *dehf = new PField("deh", dstruct, VARF_Native | VARF_Static, (intptr_t)&deh);
|
||||
GlobalSymbols.AddSymbol(dehf);
|
||||
|
||||
// set up a variable for the global gameinfo data
|
||||
PStruct *gistruct = NewNativeStruct("GameInfoStruct", nullptr);
|
||||
PField *gi = new PField("gameinfo", gistruct, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&gameinfo);
|
||||
GlobalSymbols.AddSymbol(gi);
|
||||
|
||||
// set up a variable for the global players array.
|
||||
PStruct *pstruct = NewNativeStruct("PlayerInfo", nullptr);
|
||||
pstruct->Size = sizeof(player_t);
|
||||
|
@ -796,6 +801,9 @@ void InitThingdef()
|
|||
PField *playerf = new PField("players", parray, VARF_Native | VARF_Static, (intptr_t)&players);
|
||||
GlobalSymbols.AddSymbol(playerf);
|
||||
|
||||
pstruct->AddNativeField("weapons", NewNativeStruct("WeaponSlots", nullptr), myoffsetof(player_t, weapons), VARF_Native);
|
||||
|
||||
|
||||
parray = NewArray(TypeBool, MAXPLAYERS);
|
||||
playerf = new PField("playeringame", parray, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&playeringame);
|
||||
GlobalSymbols.AddSymbol(playerf);
|
||||
|
|
|
@ -401,7 +401,7 @@ begin:
|
|||
OP(MOVEA):
|
||||
{
|
||||
ASSERTA(a); ASSERTA(B);
|
||||
int b = B;
|
||||
b = B;
|
||||
reg.a[a] = reg.a[b];
|
||||
reg.atag[a] = reg.atag[b];
|
||||
NEXTOP;
|
||||
|
@ -409,7 +409,7 @@ begin:
|
|||
OP(MOVEV2):
|
||||
{
|
||||
ASSERTF(a); ASSERTF(B);
|
||||
int b = B;
|
||||
b = B;
|
||||
reg.f[a] = reg.f[b];
|
||||
reg.f[a + 1] = reg.f[b + 1];
|
||||
NEXTOP;
|
||||
|
@ -417,7 +417,7 @@ begin:
|
|||
OP(MOVEV3):
|
||||
{
|
||||
ASSERTF(a); ASSERTF(B);
|
||||
int b = B;
|
||||
b = B;
|
||||
reg.f[a] = reg.f[b];
|
||||
reg.f[a + 1] = reg.f[b + 1];
|
||||
reg.f[a + 2] = reg.f[b + 2];
|
||||
|
@ -435,6 +435,18 @@ begin:
|
|||
reg.a[a] = (reg.a[b] && ((DObject*)(reg.a[b]))->IsKindOf((PClass*)(konsta[C].o))) ? reg.a[b] : nullptr;
|
||||
reg.atag[a] = ATAG_OBJECT;
|
||||
NEXTOP;
|
||||
OP(DYNCASTC_R) :
|
||||
ASSERTA(a); ASSERTA(B); ASSERTA(C);
|
||||
b = B;
|
||||
reg.a[a] = (reg.a[b] && ((PClass*)(reg.a[b]))->IsDescendantOf((PClass*)(reg.a[C]))) ? reg.a[b] : nullptr;
|
||||
reg.atag[a] = ATAG_OBJECT;
|
||||
NEXTOP;
|
||||
OP(DYNCASTC_K) :
|
||||
ASSERTA(a); ASSERTA(B); ASSERTKA(C);
|
||||
b = B;
|
||||
reg.a[a] = (reg.a[b] && ((PClass*)(reg.a[b]))->IsDescendantOf((PClass*)(konsta[C].o))) ? reg.a[b] : nullptr;
|
||||
reg.atag[a] = ATAG_OBJECT;
|
||||
NEXTOP;
|
||||
OP(CAST):
|
||||
if (C == CAST_I2F)
|
||||
{
|
||||
|
@ -1746,9 +1758,21 @@ static void DoCast(const VMRegisters ®, const VMFrame *f, int a, int b, int c
|
|||
break;
|
||||
|
||||
case CAST_P2S:
|
||||
{
|
||||
ASSERTS(a); ASSERTA(b);
|
||||
reg.s[a].Format("%s<%p>", reg.atag[b] == ATAG_OBJECT ? (reg.a[b] == nullptr? "Object" : ((DObject*)reg.a[b])->GetClass()->TypeName.GetChars() ) : "Pointer", reg.a[b]);
|
||||
break;
|
||||
if (reg.a[b] == nullptr) reg.s[a] = "null";
|
||||
else if (reg.atag[b] == ATAG_OBJECT)
|
||||
{
|
||||
auto op = static_cast<DObject*>(reg.a[b]);
|
||||
if (op->IsKindOf(RUNTIME_CLASS(PClass))) reg.s[a].Format("Class<%s>", static_cast<PClass*>(op)->TypeName.GetChars());
|
||||
else reg.s[a].Format("Object<%p>", ((DObject*)reg.a[b])->GetClass()->TypeName.GetChars());
|
||||
}
|
||||
else
|
||||
{
|
||||
reg.s[a].Format("%s<%p>", "Pointer", reg.a[b]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case CAST_S2I:
|
||||
ASSERTD(a); ASSERTS(b);
|
||||
|
|
|
@ -86,6 +86,8 @@ xx(CAST, cast, CAST, NOP, 0, 0), // xA = xB, conversion specified by C
|
|||
xx(CASTB, castb, CAST, NOP, 0, 0), // xA = !!xB, type specified by C
|
||||
xx(DYNCAST_R, dyncast, RPRPRP, NOP, 0, 0), // aA = dyn_cast<aC>(aB);
|
||||
xx(DYNCAST_K, dyncast, RPRPKP, NOP, 0, 0), // aA = dyn_cast<aKC>(aB);
|
||||
xx(DYNCASTC_R, dyncastc, RPRPRP, NOP, 0, 0), // aA = dyn_cast<aC>(aB); for class types
|
||||
xx(DYNCASTC_K, dyncastc, RPRPKP, NOP, 0, 0), // aA = dyn_cast<aKC>(aB);
|
||||
|
||||
// Control flow.
|
||||
xx(TEST, test, RII16, NOP, 0, 0), // if (dA != BC) then pc++
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "zscript/inventory/powerups.txt"
|
||||
|
||||
#include "zscript/shared/player.txt"
|
||||
#include "zscript/shared/player_cheat.txt"
|
||||
#include "zscript/shared/morph.txt"
|
||||
#include "zscript/shared/botstuff.txt"
|
||||
#include "zscript/shared/sharedmisc.txt"
|
||||
|
|
|
@ -487,6 +487,8 @@ class Actor : Thinker native
|
|||
native void AddInventory(Inventory inv);
|
||||
native void RemoveInventory(Inventory inv);
|
||||
native void ClearInventory();
|
||||
native bool GiveInventory(class<Inventory> type, int amount, bool givecheat = false);
|
||||
native bool TakeInventory(class<Inventory> itemclass, int amount, bool fromdecorate = false, bool notakeinfinite = false);
|
||||
native Inventory FindInventory(class<Inventory> itemtype, bool subclass = false);
|
||||
native Inventory GiveInventoryType(class<Inventory> itemtype);
|
||||
native Inventory DropInventory (Inventory item);
|
||||
|
|
|
@ -106,11 +106,15 @@ extend class Actor
|
|||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
// rather pointless these days to do it this way.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
native bool CheckArmorType(name Type, int amount = 1);
|
||||
bool CheckArmorType(name Type, int amount = 1)
|
||||
{
|
||||
let myarmor = BasicArmor(FindInventory("BasicArmor"));
|
||||
return myarmor != null && myarmor.ArmorType == type && myarmor.Amount >= amount;
|
||||
}
|
||||
|
||||
action state A_JumpIfArmorType(name Type, statelabel label, int amount = 1)
|
||||
{
|
||||
|
|
|
@ -32,11 +32,23 @@ struct TexMan
|
|||
native static TextureID CheckForTexture(String name, int usetype, int flags = TryAny);
|
||||
}
|
||||
|
||||
struct Screen
|
||||
struct Screen native
|
||||
{
|
||||
native static void DrawHUDTexture(TextureID tex, double x, double y);
|
||||
}
|
||||
|
||||
struct Console native
|
||||
{
|
||||
native static void HideConsole();
|
||||
}
|
||||
|
||||
struct GameInfoStruct native
|
||||
{
|
||||
// will be extended as needed.
|
||||
native Name backpacktype;
|
||||
native double Armor2Percent;
|
||||
}
|
||||
|
||||
class Object native
|
||||
{
|
||||
native bool bDestroyed;
|
||||
|
@ -200,6 +212,7 @@ struct DehInfo native
|
|||
native double ExplosionAlpha;
|
||||
native int NoAutofreeze;
|
||||
native int BFGCells;
|
||||
native int BlueAC;
|
||||
}
|
||||
|
||||
struct State native
|
||||
|
|
|
@ -125,3 +125,7 @@ class WeaponPiece : Inventory native
|
|||
}
|
||||
}
|
||||
|
||||
struct WeaponSlots native
|
||||
{
|
||||
native bool, int, int LocateWeapon(class<Weapon> weap);
|
||||
}
|
|
@ -258,11 +258,12 @@ struct PlayerInfo native // this is what internally is known as player_t
|
|||
native Actor ConversationPC;
|
||||
native double ConversationNPCAngle;
|
||||
native bool ConversationFaceTalker;
|
||||
//native WeaponSlots weapons; <- defined internally
|
||||
|
||||
/* these are not doable yet
|
||||
ticcmd_t cmd;
|
||||
usercmd_t original_cmd;
|
||||
userinfo_t userinfo; // [RH] who is this?
|
||||
FWeaponSlots weapons;
|
||||
userinfo_t userinfo;
|
||||
*/
|
||||
|
||||
|
||||
|
@ -276,5 +277,6 @@ FWeaponSlots weapons;
|
|||
native PSprite FindPSprite(int id);
|
||||
native void SetLogNumber (int text);
|
||||
native void SetLogText (String text);
|
||||
native String GetUserName();
|
||||
|
||||
}
|
||||
|
|
402
wadsrc/static/zscript/shared/player_cheat.txt
Normal file
402
wadsrc/static/zscript/shared/player_cheat.txt
Normal file
|
@ -0,0 +1,402 @@
|
|||
/*
|
||||
** player_cheat.txt
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 1999-2016 Randy Heit
|
||||
** Copyright 2006-2017 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
extend class PlayerPawn
|
||||
{
|
||||
enum EAll
|
||||
{
|
||||
ALL_NO,
|
||||
ALL_YES,
|
||||
ALL_YESYES
|
||||
}
|
||||
|
||||
native void CheatSuicide();
|
||||
|
||||
virtual void CheatGive (String name, int amount)
|
||||
{
|
||||
int i;
|
||||
Class<Inventory> type;
|
||||
let player = self.player;
|
||||
|
||||
if (PlayerNumber() != consoleplayer)
|
||||
A_Log(format ("%s is a cheater: give %s\n", player.GetUserName(), name));
|
||||
|
||||
if (player.mo == NULL || player.health <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int giveall = ALL_NO;
|
||||
if (name ~== "all")
|
||||
{
|
||||
giveall = ALL_YES;
|
||||
}
|
||||
else if (name ~== "everything")
|
||||
{
|
||||
giveall = ALL_YESYES;
|
||||
}
|
||||
|
||||
if (name ~== "health")
|
||||
{
|
||||
if (amount > 0)
|
||||
{
|
||||
health += amount;
|
||||
player.health = health;
|
||||
}
|
||||
else
|
||||
{
|
||||
player.health = health = GetMaxHealth();
|
||||
}
|
||||
}
|
||||
|
||||
if (giveall || name ~== "backpack")
|
||||
{
|
||||
// Select the correct type of backpack based on the game
|
||||
type = (class<Inventory>)(gameinfo.backpacktype);
|
||||
if (type != NULL)
|
||||
{
|
||||
GiveInventory(type, 1, true);
|
||||
}
|
||||
|
||||
if (!giveall)
|
||||
return;
|
||||
}
|
||||
|
||||
if (giveall || name ~== "ammo")
|
||||
{
|
||||
// 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 (i = 0; i < AllActorClasses.Size(); ++i)
|
||||
{
|
||||
type = (class<Inventory>)(AllActorClasses[i]);
|
||||
|
||||
if (type != null && type.GetParentClass() == "Ammo")
|
||||
{
|
||||
let ammoitem = FindInventory(type);
|
||||
if (ammoitem == NULL)
|
||||
{
|
||||
ammoitem = Inventory(Spawn (type));
|
||||
ammoitem.AttachToOwner (self);
|
||||
ammoitem.Amount = ammoitem.MaxAmount;
|
||||
}
|
||||
else if (ammoitem.Amount < ammoitem.MaxAmount)
|
||||
{
|
||||
ammoitem.Amount = ammoitem.MaxAmount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!giveall)
|
||||
return;
|
||||
}
|
||||
|
||||
if (giveall || name ~== "armor")
|
||||
{
|
||||
if (GameType() != GAME_Hexen)
|
||||
{
|
||||
let armoritem = BasicArmorPickup(Spawn("BasicArmorPickup"));
|
||||
armoritem.SaveAmount = 100*deh.BlueAC;
|
||||
armoritem.SavePercent = gameinfo.Armor2Percent > 0? gameinfo.Armor2Percent : 0.5;
|
||||
if (!armoritem.CallTryPickup (self))
|
||||
{
|
||||
armoritem.Destroy ();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
let armoritem = Inventory(Spawn("HexenArmor"));
|
||||
armoritem.health = i;
|
||||
armoritem.Amount = 0;
|
||||
if (!armoritem.CallTryPickup (self))
|
||||
{
|
||||
armoritem.Destroy ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!giveall)
|
||||
return;
|
||||
}
|
||||
|
||||
if (giveall || name ~== "keys")
|
||||
{
|
||||
for (int i = 0; i < AllActorClasses.Size(); ++i)
|
||||
{
|
||||
if (AllActorClasses[i] is "Key")
|
||||
{
|
||||
readonly<Key> keyitem = GetDefaultByType ((class<Key>)(AllActorClasses[i]));
|
||||
if (keyitem.KeyNumber != 0)
|
||||
{
|
||||
let item = Inventory(Spawn(AllActorClasses[i]));
|
||||
if (!item.CallTryPickup (self))
|
||||
{
|
||||
item.Destroy ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!giveall)
|
||||
return;
|
||||
}
|
||||
|
||||
if (giveall || name ~== "weapons")
|
||||
{
|
||||
let savedpending = player.PendingWeapon;
|
||||
for (i = 0; i < AllActorClasses.Size(); ++i)
|
||||
{
|
||||
let type = (class<Weapon>)(AllActorClasses[i]);
|
||||
if (type != null && type != "Weapon")
|
||||
{
|
||||
// Don't give replaced weapons unless the replacement was done by Dehacked.
|
||||
let rep = GetReplacement(type);
|
||||
if (rep == type || rep is "DehackedPickup")
|
||||
{
|
||||
// Give the weapon only if it is set in a weapon slot.
|
||||
if (player.weapons.LocateWeapon(type))
|
||||
{
|
||||
readonly<Weapon> def = GetDefaultByType (type);
|
||||
if (giveall == ALL_YESYES || !def.bCheatNotWeapon)
|
||||
{
|
||||
GiveInventory(type, 1, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
player.PendingWeapon = savedpending;
|
||||
|
||||
if (!giveall)
|
||||
return;
|
||||
}
|
||||
|
||||
if (giveall || name ~== "artifacts")
|
||||
{
|
||||
for (i = 0; i < AllActorClasses.Size(); ++i)
|
||||
{
|
||||
type = (class<Inventory>)(AllActorClasses[i]);
|
||||
if (type!= null)
|
||||
{
|
||||
let def = GetDefaultByType (type);
|
||||
if (def.Icon.isValid() && def.MaxAmount > 1 &&
|
||||
!(type is "PuzzleItem") && !(type is "Powerup") && !(type is "Ammo") && !(type is "Armor"))
|
||||
{
|
||||
// Do not give replaced items unless using "give everything"
|
||||
if (giveall == ALL_YESYES || GetReplacement(type) == type)
|
||||
{
|
||||
GiveInventory(type, amount <= 0 ? def.MaxAmount : amount, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!giveall)
|
||||
return;
|
||||
}
|
||||
|
||||
if (giveall || name ~== "puzzlepieces")
|
||||
{
|
||||
for (i = 0; i < AllActorClasses.Size(); ++i)
|
||||
{
|
||||
let type = (class<PuzzleItem>)(AllActorClasses[i]);
|
||||
if (type != null)
|
||||
{
|
||||
let def = GetDefaultByType (type);
|
||||
if (def.Icon.isValid())
|
||||
{
|
||||
// Do not give replaced items unless using "give everything"
|
||||
if (giveall == ALL_YESYES || GetReplacement(type) == type)
|
||||
{
|
||||
GiveInventory(type, amount <= 0 ? def.MaxAmount : amount, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!giveall)
|
||||
return;
|
||||
}
|
||||
|
||||
if (giveall)
|
||||
return;
|
||||
|
||||
type = name;
|
||||
if (type == NULL)
|
||||
{
|
||||
if (PlayerNumber() == consoleplayer)
|
||||
A_Log(format("Unknown item \"%s\"\n", name));
|
||||
}
|
||||
else
|
||||
{
|
||||
GiveInventory(type, amount, true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void CheatTakeType(class<Inventory> deletetype)
|
||||
{
|
||||
for (int i = 0; i < AllActorClasses.Size(); ++i)
|
||||
{
|
||||
let type = (class<Inventory>)(AllActorClasses[i]);
|
||||
|
||||
if (type != null && type is deletetype)
|
||||
{
|
||||
let pack = FindInventory(type);
|
||||
if (pack) pack.Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void CheatTake (String name, int amount)
|
||||
{
|
||||
bool takeall;
|
||||
Class<Inventory> type;
|
||||
let player = self.player;
|
||||
|
||||
|
||||
if (player.mo == NULL || player.health <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
takeall = name ~== "all";
|
||||
|
||||
if (!takeall && name ~== "health")
|
||||
{
|
||||
if (player.mo.health - amount <= 0
|
||||
|| player.health - amount <= 0
|
||||
|| amount == 0)
|
||||
{
|
||||
|
||||
CheatSuicide ();
|
||||
|
||||
if (PlayerNumber() == consoleplayer)
|
||||
Console.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 || name ~== "backpack")
|
||||
{
|
||||
CheatTakeType("BackpackItem");
|
||||
if (!takeall)
|
||||
return;
|
||||
}
|
||||
|
||||
if (takeall || name ~== "ammo")
|
||||
{
|
||||
CheatTakeType("Ammo");
|
||||
if (!takeall)
|
||||
return;
|
||||
}
|
||||
|
||||
if (takeall || name ~== "armor")
|
||||
{
|
||||
CheatTakeType("Armor");
|
||||
if (!takeall)
|
||||
return;
|
||||
}
|
||||
|
||||
if (takeall || name ~== "keys")
|
||||
{
|
||||
CheatTakeType("Key");
|
||||
if (!takeall)
|
||||
return;
|
||||
}
|
||||
|
||||
if (takeall || name ~== "weapons")
|
||||
{
|
||||
CheatTakeType("Weapon");
|
||||
CheatTakeType("WeaponHolder");
|
||||
player.ReadyWeapon = null;
|
||||
player.PendingWeapon = WP_NOCHANGE;
|
||||
|
||||
if (!takeall)
|
||||
return;
|
||||
}
|
||||
|
||||
if (takeall || name ~== "artifacts")
|
||||
{
|
||||
for (int i = 0; i < AllActorClasses.Size(); ++i)
|
||||
{
|
||||
type = (class<Inventory>)(AllActorClasses[i]);
|
||||
if (type!= null && !(type is "PuzzleItem") && !(type is "Powerup") && !(type is "Ammo") && !(type is "Armor"))
|
||||
{
|
||||
let pack = FindInventory(type);
|
||||
if (pack) pack.Destroy();
|
||||
}
|
||||
}
|
||||
if (!takeall)
|
||||
return;
|
||||
}
|
||||
|
||||
if (takeall || name ~== "puzzlepieces")
|
||||
{
|
||||
CheatTakeType("PuzzleItem");
|
||||
if (!takeall)
|
||||
return;
|
||||
}
|
||||
|
||||
if (takeall)
|
||||
return;
|
||||
|
||||
type = name;
|
||||
if (type == NULL)
|
||||
{
|
||||
if (PlayerNumber() == consoleplayer)
|
||||
A_Log(format("Unknown item \"%s\"\n", name));
|
||||
}
|
||||
else
|
||||
{
|
||||
TakeInventory(type, max(amount, 1));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue