Downloads containing SmokeSaveLoad1.0.asc

Downloads
Name Author Game Mode Rating
Smoke Save Load Library SmokeNC Other N/A Download file

File preview

  1. /*
  2. Made by Smoke[NC] December 2022
  3.  
  4. Description:
  5. This library allows the player to save/load the game at the savepoints/checkpoints (The blue box that a bunny doll gets out from when you touch it)
  6.  
  7. When at a savepoint, the player can type 'jjsave' to save his progress
  8. To load your progress, go to the FIRST checkpoint that the player encounters and type 'jjload', basically you want to put a checkpoint close to the start pos
  9. Loading is allowed only at the first checkpoint at the first encounter, while saving is allowed at any checkpoint
  10. The script does not save any of the game objects states of enemies, pickups, etc... but only the player's and the most important global states (triggers, waterlevel, etc)
  11. The user can pass a hook function to save custom variables of his own.
  12. Currently only 1 save slot per level, saving overwrites the previous save file, whose format is: <LevelName>_SaveGame.asdat
  13.  
  14. Usage:
  15.         Simply call SmokeSaveLoad::Init function under onLevelLoad.
  16.         Example:
  17.    
  18.                 #include "SmokeSaveLoad1.0.asc"
  19.                 void onLevelLoad()
  20.                 {
  21.                         SmokeSaveLoad::Init();
  22.                 }
  23.        
  24.         you can also pass hook functions for saving and loading extra script variables
  25.         Example:
  26.                 int banana = 0;
  27.                 int apple = 0;
  28.                 void MyCustomExtraVarsSave(jjSTREAM @stream) {stream.push(banana); stream.push(apple);}
  29.                 void MyCustomExtraVarsLoad(jjSTREAM @stream) {stream.pop(banana); stream.pop(apple);}
  30.  
  31.                 void onLevelLoad()
  32.                 {
  33.                         SmokeSaveLoad::Init(@MyCustomExtraVarsSave, @MyCustomExtraVarsLoad);
  34.                 }
  35. */
  36. namespace SmokeSaveLoad
  37.    {
  38.  
  39.         funcdef void HookSave(jjSTREAM @stream);
  40.         funcdef void HookLoad(jjSTREAM @stream);
  41.        
  42.         /* SmokeSaveLoad::Init
  43.                 This is the only function that the user needs to call! Read description above.
  44.         */
  45.         void Init(HookSave @userVarsSave = null, HookLoad @userVarsLoad = null)
  46.         {
  47.                 @ hookSave = @ userVarsSave;
  48.                 @ hookLoad = @ userVarsLoad;
  49.                  
  50.                 jjObjectPresets[OBJECT::SAVEPOST].behavior = CheckPoint();
  51.         }
  52.        
  53.         /* Shared Vars */
  54.         const float version = 1.0f;
  55.         HookSave @hookSave = null;
  56.         HookSave @hookLoad = null;
  57.         bool playerWantSave = false;
  58.         bool playerWantLoad = false;
  59.         bool playerInCheckPoint = false;
  60.        
  61.        
  62.         class BasicPlayerState
  63.         {
  64.                 uint8 health;
  65.                 array<int> ammo(9);
  66.                 array<bool> powerup(9);
  67.                 int score;
  68.                 int lives;
  69.                 int coins;
  70.                 int food;
  71.  
  72.                 array<int> gems(4);
  73.                 int fastfire;
  74.                 int8 light;
  75.                 uint8 lighting;
  76.                
  77.                 uint charCurr;
  78.                 uint lightType;
  79.  
  80.                 float xPos;
  81.                 float xOrg;
  82.                 float yPos;
  83.                 float yOrg;
  84.                
  85.                 void GetBasicState()
  86.                 {
  87.                         jjPLAYER @ player = jjLocalPlayers[0];
  88.                         health = player.health;
  89.                         for(int iAmmo = 0; iAmmo < 9; iAmmo++)
  90.                         {
  91.                                 ammo[iAmmo] = player.ammo[iAmmo];
  92.                                 powerup[iAmmo] = player.powerup[iAmmo];
  93.                         }
  94.                        
  95.                         for(int iGem = 0; iGem < 4; iGem++)
  96.                         {
  97.                                 gems[iGem] = player.gems[GEM::Color(iGem)];
  98.                         }
  99.                        
  100.                         fastfire = player.fastfire;
  101.                         light = player.light;
  102.                         lighting = player.lighting;
  103.                         lightType = uint(player.lightType);
  104.                        
  105.                         score = player.score;
  106.                         lives = player.lives;
  107.                         charCurr = uint(player.charCurr);
  108.                         coins = player.coins;
  109.                         food =  player.food;
  110.                        
  111.                         xPos =  player.xPos;
  112.                         yPos =  player.yPos;
  113.                         xOrg =  player.xOrg;
  114.                         yOrg =  player.yOrg;
  115.                 }
  116.                
  117.                 void SetBasicState()
  118.                 {
  119.                         jjPLAYER @ player = jjLocalPlayers[0];
  120.                         player.health = health;
  121.                         for(int iAmmo = 0; iAmmo < 9; iAmmo++)
  122.                         {
  123.                                 player.ammo[iAmmo] = ammo[iAmmo];
  124.                                 player.powerup[iAmmo] = powerup[iAmmo];
  125.                         }
  126.                        
  127.                         for(int iGem = 0; iGem < 4; iGem++)
  128.                         {
  129.                                 player.gems[GEM::Color(iGem)] = gems[iGem];
  130.                         }
  131.                        
  132.                         player.fastfire = fastfire;
  133.                         player.light = light;
  134.                         player.lighting = lighting;
  135.                         player.lightType = LIGHT::Type(lightType);
  136.                        
  137.                        
  138.                         player.score = score;
  139.                         player.lives = lives;
  140.                         player.setScore(score);
  141.                         player.morphTo(CHAR::Char(charCurr));
  142.                         player.coins = coins;
  143.                         player.food = food;
  144.                         player.xPos = xPos;
  145.                         player.yPos = yPos;
  146.                         player.xOrg = xOrg;
  147.                         player.yOrg = yOrg;
  148.                 }
  149.         };
  150.        
  151.         class BasicGlobalState
  152.         {
  153.                 array<bool> _jjTriggers(32);
  154.                 float _jjWaterLevel;
  155.                 string _jjMusicFileName;
  156.                 int _jjDifficulty;
  157.                
  158.                 void GetBasicState()
  159.                 {
  160.                         for(int iTrig = 0; iTrig < 32; iTrig++)
  161.                         {
  162.                                 _jjTriggers[iTrig] = jjTriggers[iTrig];
  163.                         }
  164.                        
  165.                         _jjWaterLevel = jjWaterLevel;
  166.                         _jjMusicFileName = jjMusicFileName;
  167.                         _jjDifficulty = jjDifficulty;
  168.                 }
  169.                
  170.                 void SetBasicState()
  171.                 {
  172.                         if(_jjDifficulty != jjDifficulty)
  173.                         {
  174.                                 jjAlert("ERROR! Difficulties must match! Reload the game in the same difficulty");
  175.                         }
  176.                        
  177.                         for(int iTrig = 0; iTrig < 32; iTrig++)
  178.                         {
  179.                                 jjTriggers[iTrig] = _jjTriggers[iTrig];
  180.                         }
  181.  
  182.                         jjSetWaterLevel(_jjWaterLevel, false);
  183.                         jjMusicLoad(_jjMusicFileName);
  184.                 }
  185.         }
  186.        
  187.  
  188.        
  189.         void SaveGameState()
  190.         {
  191.                 jjSTREAM saveState;
  192.                 BasicPlayerState playerState;
  193.                 BasicGlobalState globalState;
  194.                 playerState.GetBasicState();
  195.                 globalState.GetBasicState();
  196.                
  197.                 saveState.push(version);
  198.  
  199.                 saveState.push(playerState.health);
  200.                
  201.                 for(int i = 0; i < 9; i++)
  202.                 {
  203.                         saveState.push(playerState.ammo[i]);
  204.                         saveState.push(playerState.powerup[i]);
  205.                 }
  206.                 for(int i = 0;i < 4; i++)
  207.                 {
  208.                         saveState.push(playerState.gems[i]);
  209.                 }
  210.  
  211.                 saveState.push(playerState.fastfire);
  212.                 saveState.push(playerState.light);
  213.                 saveState.push(playerState.lighting);
  214.                 saveState.push(playerState.lightType);
  215.  
  216.                        
  217.                 saveState.push(playerState.score);
  218.                 saveState.push(playerState.lives);
  219.                 saveState.push(playerState.charCurr);
  220.                 saveState.push(playerState.coins);
  221.                 saveState.push(playerState.food);
  222.                 saveState.push(playerState.xPos);
  223.                 saveState.push(playerState.yPos);
  224.                
  225.                 saveState.push(playerState.xOrg);
  226.                 saveState.push(playerState.yOrg);
  227.                
  228.                 for(int i = 0; i < 32; i++)
  229.                 {
  230.                         saveState.push(globalState._jjTriggers[i]);
  231.                 }
  232.                 saveState.push(globalState._jjWaterLevel);
  233.                 saveState.push(globalState._jjMusicFileName);
  234.                 saveState.push(globalState._jjDifficulty);
  235.                
  236.                 if(hookSave !is null)
  237.                 {
  238.                         hookSave(@saveState);
  239.                 }
  240.                
  241.                 string saveFileName = jjLevelName + "_SaveGame" + ".asdat";
  242.                 saveState.save(saveFileName);
  243.         }
  244.        
  245.        
  246.         bool LoadGameState()
  247.         {
  248.                 string saveFileName = jjLevelName + "_SaveGame" + ".asdat";
  249.                 jjSTREAM loadState(saveFileName);
  250.                 if(loadState.isEmpty())
  251.                 {
  252.                         jjAlert("You can't load if you have no save!", true, STRING::MEDIUM);
  253.                         return false;
  254.                 }
  255.                
  256.                
  257.                 BasicPlayerState playerState;
  258.                 BasicGlobalState globalState;
  259.                
  260.                 float loadedVersion;
  261.  
  262.                 loadState.pop(loadedVersion);
  263.                
  264.                 if(version != loadedVersion)
  265.                 {
  266.                         jjAlert("Version mismatch, loaded " + loadedVersion + " but script version is " + version, true, STRING::MEDIUM);
  267.                         return false;
  268.                 }
  269.  
  270.                 loadState.pop(playerState.health);
  271.                
  272.                 for(int i = 0; i < 9; i++)
  273.                 {
  274.                         loadState.pop(playerState.ammo[i]);
  275.                         loadState.pop(playerState.powerup[i]);
  276.                 }
  277.                 for(int i = 0;i < 4; i++)
  278.                 {
  279.                         loadState.pop(playerState.gems[i]);
  280.                 }
  281.                
  282.                 loadState.pop(playerState.fastfire);
  283.                 loadState.pop(playerState.light);
  284.                 loadState.pop(playerState.lighting);
  285.                 loadState.pop(playerState.lightType);
  286.  
  287.                 loadState.pop(playerState.score);
  288.                 loadState.pop(playerState.lives);
  289.                 loadState.pop(playerState.charCurr);
  290.                 loadState.pop(playerState.coins);
  291.                 loadState.pop(playerState.food);
  292.                 loadState.pop(playerState.xPos);
  293.                 loadState.pop(playerState.yPos);
  294.                
  295.                 loadState.pop(playerState.xOrg);
  296.                 loadState.pop(playerState.yOrg);
  297.                
  298.                                
  299.                 for(int i = 0; i < 32; i++)
  300.                 {
  301.                         loadState.pop(globalState._jjTriggers[i]);
  302.                 }
  303.                 loadState.pop(globalState._jjWaterLevel);
  304.                 loadState.pop(globalState._jjMusicFileName);
  305.                 loadState.pop(globalState._jjDifficulty);
  306.                
  307.                 if(globalState._jjDifficulty != jjDifficulty)
  308.                 {
  309.                         jjAlert("Game vs SaveFile difficulty mismatch: " +
  310.                         DiffToStr(jjDifficulty) + " vs " + DiffToStr(globalState._jjDifficulty), true, STRING::MEDIUM);
  311.                         jjAlert("To load your load file, you must play the game in " + DiffToStr(globalState._jjDifficulty) + " mode" , true, STRING::MEDIUM);
  312.                         return false;
  313.                 }
  314.  
  315.                 globalState.SetBasicState();
  316.                 playerState.SetBasicState();
  317.                
  318.                 if(hookLoad !is null)
  319.                 {
  320.                         hookLoad(@loadState);
  321.                 }
  322.                 return true;
  323.         }
  324.        
  325.        
  326.         class CheckPoint: jjBEHAVIORINTERFACE
  327.         {
  328.                 bool showText = true;
  329.                 int checkPointsEncountered = 0;
  330.  
  331.             void onBehave(jjOBJ @ obj)
  332.                 {
  333.                         bool enableLoad = false;
  334.                         if(obj.state == STATE::START)
  335.                         {
  336.                                 checkPointsEncountered++;
  337.                         }
  338.                        
  339.                         obj.behave(BEHAVIOR::CHECKPOINT, true);
  340.                        
  341.                         int playerId = obj.findNearestPlayer((32 * 2) * (32 * 2));
  342.                         int playerId2 = obj.findNearestPlayer((32*6) * (32 * 6));
  343.                        
  344.                         if(playerId2 >= 0)
  345.                         {
  346.                                 if (playerId >= 0)
  347.                                 {
  348.                                         if(checkPointsEncountered == 1) // first checkpoint encountered
  349.                                         {
  350.                                                 enableLoad = true;
  351.                                         }
  352.  
  353.                                         playerInCheckPoint = true;
  354.                                        
  355.                                         jjPLAYER @ player = jjPlayers[playerId];
  356.                                         if(showText == true)
  357.                                         {
  358.                                                 if(enableLoad)
  359.                                                 {
  360.                                                         player.showText("@@@@@@To save game type \"jjsave\" @To load game type \"jjload\" ",  STRING::MEDIUM);
  361.                                                 }
  362.                                                 else
  363.                                                 {
  364.                                                         player.showText("@@@@@@To save game type \"jjsave\" ",  STRING::MEDIUM);
  365.                                                 }
  366.                                                 showText = false;
  367.                                         }
  368.                                        
  369.                                         if(playerWantSave == true)
  370.                                         {
  371.                                                 playerWantSave = false;
  372.                                                 SaveGameState();
  373.                                                 jjAlert("Game Saved Succesfully!", true, STRING::MEDIUM);
  374.                                         }
  375.                                        
  376.                                         if((playerWantLoad == true) && enableLoad)
  377.                                         {
  378.                                                 playerWantLoad = false;
  379.                                                 if(LoadGameState() == true)
  380.                                                 {
  381.                                                         jjAlert("Game Loaded Succesfully!", true, STRING::MEDIUM);
  382.                                                 }
  383.                                         }
  384.                                 }
  385.                                 else
  386.                                 {
  387.                                         showText = true;
  388.                                         playerInCheckPoint = false;
  389.                                 }
  390.                         }
  391.                 }
  392.         }
  393.        
  394.         void HandlePlayerInput(string &in input)
  395.         {
  396.                 if((input == "jjsave" || input == "jjSave"))
  397.                 {
  398.                         if(playerInCheckPoint == true)
  399.                         {
  400.                                 playerWantSave = true;
  401.                         }
  402.                         else
  403.                         {
  404.                                 jjAlert("You must stand on a checkpoint to save!", true, STRING::MEDIUM);
  405.                         }
  406.                 }
  407.                 if((input == "jjload" || input == "jjLoad"))
  408.                 {
  409.                         if(playerInCheckPoint == true)
  410.                         {
  411.                                 playerWantLoad = true;
  412.                         }
  413.                         else
  414.                         {
  415.                                 jjAlert("You must stand on the FIRST checkpoint to load!", true, STRING::MEDIUM);
  416.                         }
  417.                 }
  418.         }
  419.        
  420.         string DiffToStr(int diff)
  421.         {
  422.         switch (diff)
  423.                 {
  424.                         case 0: return "Easy";
  425.                         case 1: return "Normal";
  426.                         case 2: return "Hard";
  427.                         case 3: return "Turbo";
  428.                 }
  429.                 return "NULL";
  430.         }
  431. }
  432.  
  433. bool onCheat(string &in cheat)
  434. {
  435.         SmokeSaveLoad::HandlePlayerInput(cheat);
  436.         return false;
  437. }
  438.