Mission system (includes Tutorial)

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • Mission system (includes Tutorial)

      Well, i've always heard many people disagress about using eval'd due to potential exploits can bring to your code, but if you know how to use it, I believe there are no problems.

      I have serious problems on keeping my code beautiful, I hate ton of foreaches and endless lines just to express a few things, so I decided to make a mission system, that includes tutorial or another interesting grinding quests (such Destroy X from achievements) that may interest you.

      Is that safe? Yes.
      • I presume only you have access to your database?
      • There are not any forms
      • You can first import to the database to check the missions if you think this is untrusted, then change the files.
      I keep this code in Overview so players can track, as you can see here


      So how does it work?

      Add these lines in ShowOverviewPage.class.php before the $this->assign

      PHP Source Code: ShowOverviewPage.class.php

      1. // /**/ Missions category
      2. $Quests = array();
      3. // /*
      4. if(!isset($USER['mission']) || is_null($USER['mission']) || empty($USER['mission'])){
      5. $UserMission = array();
      6. }else{
      7. $UserMission = unserialize($USER['mission']);
      8. }
      9. $Quest = Database::get()->select("SELECT DISTINCT class, grind FROM uni1_missions ORDER BY priority ASC;", array());
      10. foreach($Quest as $Row){
      11. if(!array_key_exists($Row['class'], $UserMission)){
      12. $UserMission[$Row['class']] = 1;
      13. }
      14. // Only unlock additional missions after finish tutorial
      15. $MissionTracker = $Row['grind'] == 1 ? $Row['class'].'_'.$UserMission[$Row['class']] : $Row['class'];
      16. // Current Mission
      17. $Mission = Database::get()->selectSingle("SELECT * FROM uni1_missions where id = :mission;", array(':mission' => $MissionTracker));
      18. // Has mission ended?
      19. if(!isset($Mission) || empty($Mission)) continue;
      20. eval($Mission['code']);
      21. $Quests[] = array(
      22. 'tracker' => $MissionTracker,
      23. 'grind' => $Mission['grind'],
      24. 'id' => $Mission['id'],
      25. 'class' => $Mission['class'],
      26. 'requirements' => isset($Requirements) ? $Requirements : NULL,
      27. );
      28. }
      29. // */
      30. // /**/ Missions category
      31. /* add this to $this->assign */
      32. 'Quests' => $Quests,
      Display All



      Then you'll need to add the following piece of TPL. Adapt for your game since this is strict copy-paste from mine.

      HTML Source Code: page.overview.default.tpl

      1. <table class="table table-dark">
      2. {foreach $Quests as $Row}
      3. <tr>
      4. <td style="text-align:left;">
      5. <b>{$LNG["mission_{$Row.class}"]}</b>{if $Row.grind == 1}: {$LNG["mission_{$Row.id}"]}{/if}
      6. <p>{$LNG["mission_{$Row.id}_desc"]}
      7. {foreach $Row.requirements as $K => $C}<br>{if $C.locked != 0}<i class="fa fa-check" style="color:lime"></i>{else}<i class="fa fa-times" style="color:red"></i>{/if} {$C.text}{/foreach}
      8. {if isset($LNG["mission_{$Row.tracker}_0"])}<br> <i class="fa fa-question-circle-o" style="color:orange"></i> <a href="#" class="tooltip" data-tooltip-content='{$LNG["mission_{$Row.tracker}_0"]}'>Tips & Help</a>{/if}
      9. </td>
      10. </tr>
      11. {/foreach}
      12. </table>
      Display All
      We are not finished. Now we need to run the following query:

      SQL-Query

      1. ALTER TABLE uni1_users ADD `mission` text NULL;
      2. CREATE TABLE `uni1_missions` (
      3. `id` varchar(64) NOT NULL,
      4. `class` varchar(64) NOT NULL,
      5. `reward901` int(11) DEFAULT '0',
      6. `reward902` int(11) DEFAULT '0',
      7. `reward903` int(11) DEFAULT '0',
      8. `reward921` int(11) DEFAULT '0',
      9. `code` text,
      10. `grind` int(11) NOT NULL DEFAULT '1',
      11. PRIMARY KEY (`id`)
      12. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
      Display All

      The missions are on the SQL file I'll upload here. I can't upload as .sql extension, so it goes as .txt.

      The column "reward" is to multiply the current user production * hours as resource reward. The resource921 is in case you want to give him dark matter.
      The column "class" is in case you want to create quests with progress.
      The column "grind" is in case you want to create a mission like "Destroy X resources" and when user achieves, has do destroy another X. You can see the demo file in "Warmonger.txt" as mission to destroy X ships.

      To end, this is the template, if you want to create new missions, that goes to the "code" box.


      You can add as much requirements as you want, aswell missions, it's a huge and good alternative to my very old and classic Achievements system. This template is experimental, requirements goes to the 'req' associative from $A, $B, $C ... $Z array. Want to add a requirement? Simply copypaste $C and replace to $D, etc.

      Source Code

      1. $A = array('req' => Database::get()->selectSingle("SELECT COUNT(*) FROM %%PLANETS%% WHERE planet_type = '1' AND id_owner = ".$USER['id'].";")['COUNT(*)'], 'value' => 10);
      2. $B = array('req' => $USER['computer_tech'], 'value' => 10);
      3. $C = array('req' => $PLANET['metal_mine'], 'value' => 10);
      4. $Requirements = array(
      5. $A['req'] >= $A['value'] ? 1 : 0,
      6. $B['req'] >= $B['value'] ? 1 : 0,
      7. $C['req'] >= $C['value'] ? 1 : 0,
      8. );
      9. if(count($Requirements) == array_sum($Requirements)){
      10. $PLANET[$resource[901]] += $MetalProduction * $Mission['reward901'];
      11. $PLANET[$resource[902]] += $CrystalProduction * $Mission['reward902'];
      12. $PLANET[$resource[903]] += $DeuteriumProduction * $Mission['reward903'];
      13. $USER[$resource[921]] += $Mission['reward921'];
      14. $UserMission[$Row['class']] += 1;
      15. Database::get()->update("UPDATE %%USERS%% SET mission = :missions WHERE id = :id;", array(':missions' => serialize($UserMission), ':id' => $USER['id']));
      16. }
      17. $Requirements = array(
      18. 1 => array('locked' => $A['req'] >= $A['value'] ? 1 : 0, 'text' => sprintf($LNG['mission_'.$MissionTracker.'_1'], $A['value'])),
      19. 2 => array('locked' => $B['req'] >= $B['value'] ? 1 : 0, 'text' => sprintf($LNG['mission_'.$MissionTracker.'_2'], $B['value'])),
      20. 3 => array('locked' => $C['req'] >= $C['value'] ? 1 : 0, 'text' => sprintf($LNG['mission_'.$MissionTracker.'_3'], $C['value'])),
      21. );
      Display All
      Files
      • CUSTOM.txt

        (7.45 kB, downloaded 518 times, last: )
      • uni1_missions.txt

        (16.2 kB, downloaded 564 times, last: )
      • Warmonger.txt

        (954 Byte, downloaded 514 times, last: )

      The post was edited 2 times, last by Qwa ().

    • проверил.... это один из лучших вариантов - где отходят от традиций старых и делаю что то новое !!! молодец !! я скоро докину правки думаю понравятся
    • Qwa wrote:

      I think not. It was made from 1.8+
      hey i tried to changed it over wondering if you can give it a quick look ove
      just cant do the sql keep getting errors
      Files
      • uni1_missions.txt

        (16.28 kB, downloaded 419 times, last: )
      • Warmonger.txt

        (959 Byte, downloaded 378 times, last: )
    • i went through the install and i get this error.....maybe i missed something ...thanks

      SQLSTATE[42S22]: Column not found: 1054 Unknown column 'priority' in 'order clause'

      Query-Code:SELECT DISTINCT class, grind FROM uni1_missions ORDER BY priority ASC;
      /includes/classes/Database.class.php

      1.8
    • possibly i forgot to add in sql file the priority column, its numeric, to set which quest should be load first.
    • i tried to install in 1.8 but i get sql error when uplading the warmonger sql

      21 errors were found during analysis.
      1. Unexpected character. (near "$" at position 0)
      2. Unexpected character. (near "$" at position 20)
      3. Unexpected character. (near "[" at position 25)
      4. Unexpected character. (near "]" at position 36)
      5. Unexpected character. (near "$" at position 50)
      6. Unexpected character. (near "[" at position 62)
      7. Unexpected character. (near "$" at position 63)
      8. Unexpected character. (near "[" at position 67)
      9. Unexpected character. (near "]" at position 75)
      10. Unexpected character. (near "]" at position 76)
      11. Unexpected character. (near "?" at position 89)
      12. Unexpected character. (near "$" at position 91)
      13. Unexpected character. (near "[" at position 103)
      14. Unexpected character. (near "$" at position 104)
      15. Unexpected character. (near "[" at position 108)
      16. Unexpected character. (near "]" at position 116)
      17. Unexpected character. (near "]" at position 117)
      18. Variable name was expected. (near " " at position 120)
      19. Unexpected beginning of statement. (near "$" at position 0)
      20. Unexpected beginning of statement. (near "A" at position 1)
      21. Unrecognized statement type. (near "array" at position 5)
      SQL query:
      $A = array('req' => $USER['desunits'], 'value' => $UserMission[$Row['class']] > 10000000 ? $UserMission[$Row['class']] : 10000000)
    • column type for requriements is "text"?

      You can also try open the file, copy the content, paste in sql window
    • so did that i got the sql but i get this now the bottom quote where would that go
      Message: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'priority' in 'order clause'

      Query-Code:SELECT DISTINCT class, grind FROM uni1_missions ORDER BY priority ASC;
      File: /includes/classes/Database.class.php

      Qwa wrote:

      Well, i've always heard many people disagress about using eval'd due to potential exploits can bring to your code, but if you know how to use it, I believe there are no problems.

      I have serious problems on keeping my code beautiful, I hate ton of foreaches and endless lines just to express a few things, so I decided to make a mission system, that includes tutorial or another interesting grinding quests (such Destroy X from achievements) that may interest you.

      Is that safe? Yes.
      • I presume only you have access to your database?
      • There are not any forms
      • You can first import to the database to check the missions if you think this is untrusted, then change the files.
      I keep this code in Overview so players can track, as you can see here


      So how does it work?

      Add these lines in ShowOverviewPage.class.php before the $this->assign

      PHP Source Code: ShowOverviewPage.class.php

      1. // /**/ Missions category
      2. $Quests = array();
      3. // /*
      4. if(!isset($USER['mission']) || is_null($USER['mission']) || empty($USER['mission'])){
      5. $UserMission = array();
      6. }else{
      7. $UserMission = unserialize($USER['mission']);
      8. }
      9. $Quest = Database::get()->select("SELECT DISTINCT class, grind FROM uni1_missions ORDER BY priority ASC;", array());
      10. foreach($Quest as $Row){
      11. if(!array_key_exists($Row['class'], $UserMission)){
      12. $UserMission[$Row['class']] = 1;
      13. }
      14. // Only unlock additional missions after finish tutorial
      15. $MissionTracker = $Row['grind'] == 1 ? $Row['class'].'_'.$UserMission[$Row['class']] : $Row['class'];
      16. // Current Mission
      17. $Mission = Database::get()->selectSingle("SELECT * FROM uni1_missions where id = :mission;", array(':mission' => $MissionTracker));
      18. // Has mission ended?
      19. if(!isset($Mission) || empty($Mission)) continue;
      20. eval($Mission['code']);
      21. $Quests[] = array(
      22. 'tracker' => $MissionTracker,
      23. 'grind' => $Mission['grind'],
      24. 'id' => $Mission['id'],
      25. 'class' => $Mission['class'],
      26. 'requirements' => isset($Requirements) ? $Requirements : NULL,
      27. );
      28. }
      29. // */
      30. // /**/ Missions category
      31. /* add this to $this->assign */
      32. 'Quests' => $Quests,
      Display All


      Then you'll need to add the following piece of TPL. Adapt for your game since this is strict copy-paste from mine.

      HTML Source Code: page.overview.default.tpl

      1. <table class="table table-dark">
      2. {foreach $Quests as $Row}
      3. <tr>
      4. <td style="text-align:left;">
      5. <b>{$LNG["mission_{$Row.class}"]}</b>{if $Row.grind == 1}: {$LNG["mission_{$Row.id}"]}{/if}
      6. <p>{$LNG["mission_{$Row.id}_desc"]}
      7. {foreach $Row.requirements as $K => $C}<br>{if $C.locked != 0}<i class="fa fa-check" style="color:lime"></i>{else}<i class="fa fa-times" style="color:red"></i>{/if} {$C.text}{/foreach}
      8. {if isset($LNG["mission_{$Row.tracker}_0"])}<br> <i class="fa fa-question-circle-o" style="color:orange"></i> <a href="#" class="tooltip" data-tooltip-content='{$LNG["mission_{$Row.tracker}_0"]}'>Tips & Help</a>{/if}
      9. </td>
      10. </tr>
      11. {/foreach}
      12. </table>
      Display All
      We are not finished. Now we need to run the following query:

      SQL-Query

      1. ALTER TABLE uni1_users ADD `mission` text NULL;
      2. CREATE TABLE `uni1_missions` (
      3. `id` varchar(64) NOT NULL,
      4. `class` varchar(64) NOT NULL,
      5. `reward901` int(11) DEFAULT '0',
      6. `reward902` int(11) DEFAULT '0',
      7. `reward903` int(11) DEFAULT '0',
      8. `reward921` int(11) DEFAULT '0',
      9. `code` text,
      10. `grind` int(11) NOT NULL DEFAULT '1',
      11. PRIMARY KEY (`id`)
      12. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
      Display All
      The missions are on the SQL file I'll upload here. I can't upload as .sql extension, so it goes as .txt.

      The column "reward" is to multiply the current user production * hours as resource reward. The resource921 is in case you want to give him dark matter.
      The column "class" is in case you want to create quests with progress.
      The column "grind" is in case you want to create a mission like "Destroy X resources" and when user achieves, has do destroy another X. You can see the demo file in "Warmonger.txt" as mission to destroy X ships.

      To end, this is the template, if you want to create new missions, that goes to the "code" box.


      You can add as much requirements as you want, aswell missions, it's a huge and good alternative to my very old and classic Achievements system. This template is experimental, requirements goes to the 'req' associative from $A, $B, $C ... $Z array. Want to add a requirement? Simply copypaste $C and replace to $D, etc.

      Source Code

      1. $A = array('req' => Database::get()->selectSingle("SELECT COUNT(*) FROM %%PLANETS%% WHERE planet_type = '1' AND id_owner = ".$USER['id'].";")['COUNT(*)'], 'value' => 10);
      2. $B = array('req' => $USER['computer_tech'], 'value' => 10);
      3. $C = array('req' => $PLANET['metal_mine'], 'value' => 10);
      4. $Requirements = array(
      5. $A['req'] >= $A['value'] ? 1 : 0,
      6. $B['req'] >= $B['value'] ? 1 : 0,
      7. $C['req'] >= $C['value'] ? 1 : 0,
      8. );
      9. if(count($Requirements) == array_sum($Requirements)){
      10. $PLANET[$resource[901]] += $MetalProduction * $Mission['reward901'];
      11. $PLANET[$resource[902]] += $CrystalProduction * $Mission['reward902'];
      12. $PLANET[$resource[903]] += $DeuteriumProduction * $Mission['reward903'];
      13. $USER[$resource[921]] += $Mission['reward921'];
      14. $UserMission[$Row['class']] += 1;
      15. Database::get()->update("UPDATE %%USERS%% SET mission = :missions WHERE id = :id;", array(':missions' => serialize($UserMission), ':id' => $USER['id']));
      16. }
      17. $Requirements = array(
      18. 1 => array('locked' => $A['req'] >= $A['value'] ? 1 : 0, 'text' => sprintf($LNG['mission_'.$MissionTracker.'_1'], $A['value'])),
      19. 2 => array('locked' => $B['req'] >= $B['value'] ? 1 : 0, 'text' => sprintf($LNG['mission_'.$MissionTracker.'_2'], $B['value'])),
      20. 3 => array('locked' => $C['req'] >= $C['value'] ? 1 : 0, 'text' => sprintf($LNG['mission_'.$MissionTracker.'_3'], $C['value'])),
      21. );
      Display All
    • alter table uni1_mission (i guess, no longer used) add priority int(11) not null default '99'

      if i well remember, make sure tutorial has priority 1