From effe449040876386a47ada53c403578ab27a10c6 Mon Sep 17 00:00:00 2001
From: XProger <xproger@list.ru>
Date: Tue, 23 Oct 2018 03:05:39 +0300
Subject: [PATCH] only pistols at start, cheats (all weapons, skip level),
 global variables refactoring

---
 src/cache.h     |  2 ++
 src/game.h      | 31 +++++++++++++++++++++++++++----
 src/gameflow.h  |  4 ++++
 src/inventory.h | 37 ++++++++++++++++++++-----------------
 src/level.h     | 17 +++++++++--------
 src/savegame.h  |  1 -
 6 files changed, 62 insertions(+), 30 deletions(-)

diff --git a/src/cache.h b/src/cache.h
index d052fc2..1dc59d2 100644
--- a/src/cache.h
+++ b/src/cache.h
@@ -1157,6 +1157,8 @@ struct ZoneCache {
     }
 };
 
+ShaderCache *shaderCache;
+
 #undef UNDERWATER_COLOR
 
 #endif
diff --git a/src/game.h b/src/game.h
index 0d5248d..cab607a 100644
--- a/src/game.h
+++ b/src/game.h
@@ -9,13 +9,32 @@
 #include "ui.h"
 #include "savegame.h"
 
-ShaderCache *shaderCache;
-Inventory   *inventory;
-
 namespace Game {
     Level     *level;
     Stream    *nextLevel;
 
+    #define MAX_CHEAT_SEQUENCE 8
+    ControlKey cheatSeq[MAX_CHEAT_SEQUENCE];
+
+    void cheatControl(ControlKey key) {
+        if (key == cMAX || !level || level->level.isTitle() || level->level.isCutsceneLevel()) return;
+        const ControlKey CHEAT_ALL_WEAPONS[] = { cLook, cWeapon, cDash, cDuck, cDuck, cDash, cRoll, cLook };
+        const ControlKey CHEAT_SKIP_LEVEL[]  = { cDuck, cDash, cLook, cRoll, cWeapon, cLook, cDash, cDuck };
+
+        for (int i = 0; i < MAX_CHEAT_SEQUENCE - 1; i++)
+            cheatSeq[i] = cheatSeq[i + 1];
+        cheatSeq[MAX_CHEAT_SEQUENCE - 1] = key;
+
+    // add all weapons
+        if (!memcmp(&cheatSeq[MAX_CHEAT_SEQUENCE - COUNT(CHEAT_ALL_WEAPONS)], CHEAT_ALL_WEAPONS, sizeof(CHEAT_ALL_WEAPONS))) {
+            inventory->addWeapons();
+            level->playSound(TR::SND_SCREAM);
+        }
+    // skip level
+        if (!memcmp(&cheatSeq[MAX_CHEAT_SEQUENCE - COUNT(CHEAT_SKIP_LEVEL)], CHEAT_SKIP_LEVEL, sizeof(CHEAT_SKIP_LEVEL)))
+            level->loadNextLevel();
+    }
+
     void startLevel(Stream *lvl) {
         TR::LevelID id = TR::LVL_MAX;
         if (level)
@@ -112,6 +131,8 @@ namespace Game {
         shaderCache = NULL;
         level       = NULL;
 
+        memset(cheatSeq, 0, sizeof(cheatSeq));
+
         Core::init();
         Sound::callback = stopChannel;
 
@@ -152,7 +173,9 @@ namespace Game {
 
     void updateTick() {
         Input::update();
-        
+
+        cheatControl(Input::lastState[0]); 
+
         if (!level->level.isTitle()) {
             if (Input::lastState[0] == cStart) level->addPlayer(0);
             if (Input::lastState[1] == cStart) level->addPlayer(1);
diff --git a/src/gameflow.h b/src/gameflow.h
index 1cc3304..13b5033 100644
--- a/src/gameflow.h
+++ b/src/gameflow.h
@@ -724,6 +724,10 @@ namespace TR {
         return id == LVL_TR1_TITLE || id == LVL_TR2_TITLE || id == LVL_TR3_TITLE;
     }
 
+    bool isEmptyLevel(LevelID id) {
+        return id == TR::LVL_TR1_10A || id == TR::LVL_TR2_RIG || id == TR::LVL_TR3_COMPOUND;
+    }
+
     Version getGameVersion() {
         useEasyStart = true;
         if (Stream::existsContent("DATA/GYM.PHD") || Stream::existsContent("GYM.PHD"))
diff --git a/src/inventory.h b/src/inventory.h
index 9e5462e..fc03fd5 100644
--- a/src/inventory.h
+++ b/src/inventory.h
@@ -18,8 +18,6 @@
 #define TITLE_LOADING        64.0f
 #define LINE_HEIGHT          20.0f
 
-extern Array<SaveSlot> saveSlots;
-
 static const struct OptionItem *waitForKey = NULL;
 
 struct OptionItem {
@@ -607,28 +605,18 @@ struct Inventory {
         if (!game) return;
 
         TR::Level *level = game->getLevel();
-        TR::LevelID id   = level->id;
 
         add(TR::Entity::INV_PASSPORT);
         add(TR::Entity::INV_DETAIL);
         add(TR::Entity::INV_SOUND);
         add(TR::Entity::INV_CONTROLS);
 
-        if (!level->isTitle() && id != TR::LVL_TR1_GYM && id != TR::LVL_TR2_ASSAULT) {
-/*
-            if (level->extra.inv.map != -1)
-                add(TR::Entity::INV_MAP);
-            if (level->extra.inv.gamma != -1)
-                add(TR::Entity::INV_GAMMA);
-*/
-            add(TR::Entity::INV_PISTOLS, UNLIMITED_AMMO);
-            add(TR::Entity::INV_SHOTGUN, 10);
-            add(TR::Entity::INV_MAGNUMS, 10);
-            add(TR::Entity::INV_UZIS, 50);
-//              add(TR::Entity::INV_MEDIKIT_SMALL, 999);
-//              add(TR::Entity::INV_MEDIKIT_BIG, 999);
-//              add(TR::Entity::INV_SCION, 1);
+        if (!level->isTitle() && !level->isCutsceneLevel() && !level->isHome()) {
+            if (!TR::isEmptyLevel(level->id)) {
+                add(TR::Entity::INV_PISTOLS, UNLIMITED_AMMO);
+            }
         #ifdef _DEBUG
+            addWeapons();
             add(TR::Entity::INV_KEY_1, 3);
             add(TR::Entity::INV_KEY_2, 3);
             add(TR::Entity::INV_KEY_3, 3);
@@ -651,6 +639,19 @@ struct Inventory {
         }
     }
 
+    void addWeapons() {
+        TR::Level *level = game->getLevel();
+        if (level->isTitle() || level->isCutsceneLevel() || level->isHome())
+            return;
+
+        if (level->version & TR::VER_TR1) {
+            add(TR::Entity::INV_PISTOLS, UNLIMITED_AMMO);
+            add(TR::Entity::INV_SHOTGUN, UNLIMITED_AMMO);
+            add(TR::Entity::INV_MAGNUMS, UNLIMITED_AMMO);
+            add(TR::Entity::INV_UZIS,    UNLIMITED_AMMO);
+        }
+    }
+
     void startVideo() {
         new Stream(playVideo ? TR::getGameVideo(game->getLevel()->id) : NULL, loadVideo, this);
     }
@@ -1832,6 +1833,8 @@ struct Inventory {
     }
 };
 
+Inventory *inventory;
+
 #undef SETTINGS
 #undef LINE_HEIGHT
 
diff --git a/src/level.h b/src/level.h
index 768c2c2..06f3205 100644
--- a/src/level.h
+++ b/src/level.h
@@ -22,14 +22,8 @@
 
 #define ANIM_TEX_TIMESTEP (10.0f / 30.0f)
 
-extern ShaderCache *shaderCache;
 extern void loadLevelAsync(Stream *stream, void *userData);
 
-extern Inventory *inventory;
-extern Array<SaveSlot> saveSlots;
-extern SaveResult saveResult;
-extern int loadSlot;
-
 struct Level : IGame {
 
     TR::Level   level;
@@ -144,8 +138,15 @@ struct Level : IGame {
             for (int i = 0; i < inventory->itemsCount; i++) {
                 Inventory::Item *invItem = inventory->items[i];
             
-                if (!TR::Entity::isPickup(TR::Entity::convFromInv(invItem->type))) continue;
-                if (!checkpoint && !TR::Entity::isCrossLevelItem(TR::Entity::convFromInv(invItem->type))) continue;
+                if (!TR::Entity::isPickup(TR::Entity::convFromInv(invItem->type)))
+                    continue;
+
+                if (!checkpoint) {
+                    if (!TR::Entity::isCrossLevelItem(TR::Entity::convFromInv(invItem->type)))
+                        continue;
+                    if (TR::isEmptyLevel(id))
+                        continue;
+                }
 
                 SaveItem *item = (SaveItem*)ptr;
                 ptr += sizeof(*item);
diff --git a/src/savegame.h b/src/savegame.h
index b26d998..f3ce52a 100644
--- a/src/savegame.h
+++ b/src/savegame.h
@@ -196,5 +196,4 @@ int getSaveSlot(TR::LevelID levelID, bool checkpoint) {
     return -1;
 }
 
-
 #endif