From ac042335906bd83b75c9cc521eb413f0ce020db2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 23 Dec 2007 14:23:52 +0000 Subject: [PATCH] - Added Karate Chris's 'Take' console command submission. SVN r624 (trunk) --- docs/rh-log.txt | 1 + src/c_cmds.cpp | 13 +++ src/d_net.cpp | 6 ++ src/d_protocol.h | 1 + src/m_cheat.cpp | 236 +++++++++++++++++++++++++++++++++++++++++++++++ src/m_cheat.h | 1 + 6 files changed, 258 insertions(+) diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 8446acf57..4137c7e71 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,4 +1,5 @@ December 23, 2007 (Changes by Graf Zahl) +- Added Karate Chris's 'Take' console command submission. - Changed DTA_Translation parameter for DrawTexture to an integer to avoid passing renderer specific data to the function. Also added DTA_Font so that the renderer can fetch font translations from the proper font. diff --git a/src/c_cmds.cpp b/src/c_cmds.cpp index 609e65040..f3b44a1ee 100644 --- a/src/c_cmds.cpp +++ b/src/c_cmds.cpp @@ -362,6 +362,19 @@ CCMD (give) Net_WriteWord (0); } +CCMD (take) +{ + if (CheckCheatmode () || argv.argc() < 2) + return; + + Net_WriteByte (DEM_TAKECHEAT); + Net_WriteString (argv[1]); + if (argv.argc() > 2) + Net_WriteWord (clamp (atoi (argv[2]), 1, 32767)); + else + Net_WriteWord (0); +} + CCMD (gameversion) { Printf ("%s : " __DATE__ "\n", DOTVERSIONSTR); diff --git a/src/d_net.cpp b/src/d_net.cpp index c0ab17b32..15c937fb6 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -1998,6 +1998,11 @@ void Net_DoCommand (int type, BYTE **stream, int player) cht_Give (&players[player], s, ReadWord (stream)); break; + case DEM_TAKECHEAT: + s = ReadString (stream); + cht_Take (&players[player], s, ReadWord (stream)); + break; + case DEM_WARPCHEAT: { int x, y; @@ -2325,6 +2330,7 @@ void Net_SkipCommand (int type, BYTE **stream) break; case DEM_GIVECHEAT: + case DEM_TAKECHEAT: skip = strlen ((char *)(*stream)) + 3; break; diff --git a/src/d_protocol.h b/src/d_protocol.h index f6a7a735e..dde9a6c61 100644 --- a/src/d_protocol.h +++ b/src/d_protocol.h @@ -146,6 +146,7 @@ enum EDemoCommand DEM_SUMMONFOE, // 44 String: Thing to fabricate DEM_WIPEON, // 45 Player started a screen wipe DEM_WIPEOFF, // 46 Player finished a screen wipe + DEM_TAKECHEAT, // 47 String: item to take, Word: quantity }; // The following are implemented by cht_DoCheat in m_cheat.cpp diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index f35c0ed0f..5ccc45a21 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -41,6 +41,7 @@ #include "a_keys.h" #include "templates.h" #include "p_lnspec.h" +#include "c_console.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 @@ -713,6 +714,241 @@ void cht_Give (player_t *player, const char *name, int amount) return; } +void cht_Take (player_t *player, const char *name, int amount) +{ + bool takeall; + const PClass *type; + + if (player->mo == NULL || player->health <= 0) + { + return; + } + + 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) + { + // Select the correct type of backpack based on the game + if (gameinfo.gametype == GAME_Heretic) + { + type = PClass::FindClass ("BagOfHolding"); + } + else if (gameinfo.gametype == GAME_Strife) + { + type = PClass::FindClass ("AmmoSatchel"); + } + else if (gameinfo.gametype == GAME_Doom) + { + type = PClass::FindClass ("Backpack"); + } + else + { // Hexen doesn't have a backpack, foo! + type = NULL; + } + if (type != NULL) + { + AActor *backpack = player->mo->FindInventory (type); + + if (backpack) + backpack->Destroy (); + } + + if (!takeall) + return; + } + + if (takeall || stricmp (name, "ammo") == 0) + { + for (unsigned int i = 0; i < PClass::m_Types.Size(); ++i) + { + const PClass *type = PClass::m_Types[i]; + + if (type->ParentClass == RUNTIME_CLASS (AAmmo)) + { + AInventory *ammo = player->mo->FindInventory (type); + + if (ammo) + ammo->Amount = 0; + } + } + + if (!takeall) + return; + } + + if (takeall || stricmp (name, "armor") == 0) + { + for (unsigned int i = 0; i < PClass::m_Types.Size(); ++i) + { + type = PClass::m_Types[i]; + + if (type->IsDescendantOf (RUNTIME_CLASS (AArmor))) + { + AActor *armor = player->mo->FindInventory (type); + + if (armor) + armor->Destroy (); + } + } + + if (!takeall) + return; + } + + if (takeall || stricmp (name, "keys") == 0) + { + for (unsigned int i = 0; i < PClass::m_Types.Size(); ++i) + { + type = PClass::m_Types[i]; + + if (type->IsDescendantOf (RUNTIME_CLASS (AKey))) + { + AActor *key = player->mo->FindInventory (type); + + if (key) + key->Destroy (); + } + } + + if (!takeall) + return; + } + + if (takeall || stricmp (name, "weapons") == 0) + { + for (unsigned int i = 0; i < PClass::m_Types.Size(); ++i) + { + type = PClass::m_Types[i]; + + if (type != RUNTIME_CLASS(AWeapon) && + type->IsDescendantOf (RUNTIME_CLASS (AWeapon))) + { + AActor *weapon = player->mo->FindInventory (type); + + if (weapon) + weapon->Destroy (); + + player->ReadyWeapon = NULL; + player->PendingWeapon = WP_NOCHANGE; + player->psprites[ps_weapon].state = NULL; + player->psprites[ps_flash].state = NULL; + } + } + + if (!takeall) + return; + } + + if (takeall || stricmp (name, "artifacts") == 0) + { + for (unsigned int i = 0; i < PClass::m_Types.Size(); ++i) + { + type = PClass::m_Types[i]; + + if (type->IsDescendantOf (RUNTIME_CLASS (AInventory))) + { + if (!type->IsDescendantOf (RUNTIME_CLASS (APuzzleItem)) && + !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 (type); + + if (artifact) + artifact->Destroy (); + } + } + } + + if (!takeall) + return; + } + + if (takeall || stricmp (name, "puzzlepieces") == 0) + { + for (unsigned int i = 0; i < PClass::m_Types.Size(); ++i) + { + type = PClass::m_Types[i]; + + if (type->IsDescendantOf (RUNTIME_CLASS (APuzzleItem))) + { + AActor *puzzlepiece = player->mo->FindInventory (type); + + if (puzzlepiece) + puzzlepiece->Destroy (); + } + } + + if (!takeall) + return; + } + + if (takeall) + return; + + type = PClass::FindClass (name); + if (type == NULL || !type->IsDescendantOf (RUNTIME_CLASS (AInventory))) + { + if (player == &players[consoleplayer]) + Printf ("Unknown item \"%s\"\n", name); + } + else + { + AInventory *inventory = player->mo->FindInventory (type); + + if (inventory != NULL) + { + inventory->Amount -= amount ? amount : 1; + + if (inventory->Amount <= 0) + { + if (inventory->ItemFlags & IF_KEEPDEPLETED) + { + inventory->Amount = 0; + } + else + { + inventory->Destroy (); + } + } + } + } + return; +} + void cht_Suicide (player_t *plyr) { if (plyr->mo != NULL) diff --git a/src/m_cheat.h b/src/m_cheat.h index 0ca1f3e3e..fe304630c 100644 --- a/src/m_cheat.h +++ b/src/m_cheat.h @@ -32,6 +32,7 @@ class player_s; struct PClass; void cht_DoCheat (player_s *player, int cheat); void cht_Give (player_s *player, const char *item, int amount=1); +void cht_Take (player_s *player, const char *item, int amount=1); void cht_Suicide (player_s *player); const char *cht_Morph (player_s *player, const PClass *morphclass, bool quickundo);