Dev Rambling: Exploration System
So I've managed to make this (which is mostly just a proof of concept):
And you're welcome to the source code for it! It's fairly well commented, so you might even be able to dive right into it.
view/exploreview.php -
PHP Code:
<?php class ExploreView extends View{ public function index(){ $mysidia = Registry::get("mysidia"); $document = $this->document;
/* If an area is NOT selected: */ if(!$mysidia->input->post()){ $document->setTitle("Explore"); $document->add(new Comment("You have decided to go exploring!"));
/* This is a list of your area links that will appear on your /expore page, name them accordingly! Use * in place of apostrophes! You can also use these button links inside of areas, (see usage further on). You DON'T have to list all areas on the main page.
*/
$this->exploreButton("High_Woods", TRUE); $this->exploreButton("Seaside_Harbor", TRUE); $this->exploreButton("Maple_Grove", TRUE); /* [ OPTIONS ] Area Logo: Set the second parameter to TRUE to use a logo image. Save images in a new folder in your root called /img/, with _ in place of spaces, BUT use apostrophes, NOT asterisks, add _logo to the end, and save as a .png! Text-Only Area Name Link: Set the second parameter to FALSE to use a text-only link. Custom Link Text: Set a third parameter to define custom button text. Custom Image Link: Set the second parameter to TRUE, leave the third parameter "", and set a fourth parameter with an image stored in the /img/ folder. Include the file extension! [EXAMPLES] Area Logo: $this->exploreButton("High_Woods", TRUE);
Apostrophe Names: $this->exploreButton("Sally*s_Pond", TRUE);
Text-Only Link: $this->exploreButton("High_Woods"); ~ or ~ $this->exploreButton("High_Woods", FALSE);
Custom Text Link: $this->exploreButton("Seaside_Harbor", FALSE, "Head toward the water?");
Custom Image Link: $this->exploreButton("Rabbit_Hole", TRUE, "", "white_rabbit.gif"); ~ sub folders? no problem ~ $this->exploreButton("Rabbit_Hole", TRUE, "", "wonderland/white_rabbit.gif");
*/
} # END no area selected
/* If an area is selected: */ if($mysidia->input->post("area")){ $area = $mysidia->input->post("area"); // This has apostrophes as *s instead, just like the exploreButtons above! $str = str_replace("_", " ", $area); $areaname = str_replace("*", "'", $str); // This one has apostrophes instead of asterisks.
$document->setTitle("{$areaname}"); switch ($area){ # First one is the default response that will happen unless something specific is specified: case $areaname: $document->add(new Comment("There's nothing here...?", FALSE)); break;
/* Area: High_Woods */ case "High_Woods": $document->add(new Comment("The woods are densely packed with lush flora. Through the trees, you can just barely make out the ocean.", FALSE)); $this->exploreButton("Seaside_Harbor", FALSE, "Head toward the water?"); break; /* END High_Woods */
/* Area: Seaside_Harbor */ case "Seaside_Harbor": $document->add(new Comment("The water is lined with fishing boats. A sign post nearby points you onward to", FALSE)); $this->exploreButton("Maple_Grove"); $document->add(new Comment(". <br/> Or back the", FALSE)); $this->exploreButton("High_Woods", FALSE, "way you came"); $document->add(new Comment("...", FALSE)); break; /* END Seaside_Harbor */
/* Area: Maple_Grove */ case "Maple_Grove": $document->add(new Comment("Sometimes you wonder if you should", FALSE)); $this->exploreButton("Seaside_Harbor", FALSE, "return the way you came"); $document->add(new Comment(", or take a break", FALSE)); $this->exploreButton("Sally*s_Pond", FALSE, "by the pond up ahead"); $document->add(new Comment("."));
# So you want to give users an item? $document->add(new Comment("Hey, want some icecream?", FALSE));
# Quantity, Item Name, Area Name $this->pickupItem(2, "Beta Icecream", "Maple_Grove");
break; /* END Maple_Grove */
/* Area: Sally's Pond */ # NOTE that this name has an apostrophe replaced with a * case "Sally*s_Pond": $document->add(new Comment("What a beautiful pond!", FALSE)); break; /* END Sally's Pond */
} # END switch($area)
return; } # END areas output
if($mysidia->input->post("item_found")){ $mysidia = Registry::get("mysidia"); $document = $this->document; $give_qty = $mysidia->input->post("give_qty"); $item = $mysidia->input->post("item_found"); $continue = $mysidia->input->post("continue"); $this->giveItem($give_qty, $item); $document->setTitle("Items Acquired!"); $document->add(new Comment(" There have been {$give_qty} {$item}(s) added to your inventory. <br/> ", FALSE)); $this->exploreButton($continue, FALSE, "Back");
} # END item_found output
} #END index
public function exploreButton($areaname, $image_link = "", $customtext = "", $customimg = ""){ $document = $this->document; if ($image_link){ /* Image Links */ if (!$customimg){ /* Area Logo Image */ $imgname = str_replace("*", "'", $areaname); $document->add(new Comment(" <form id='exploreform' action='explore' name='exploreform' method='post' role='form'> <input id='area' name='area' type='hidden' value='{$areaname}'> <button id='{$areaname}' class='btn-text btn-sm' value='explore' name='{$areaname}' type='submit'> <img src=\"./img/{$imgname}_logo.png\"/> </button> </form> ", FALSE)); } else { /* Custom Link Image */ $imgname = str_replace("*", "'", $customimg); $document->add(new Comment(" <form id='exploreform' action='explore' name='exploreform' method='post' role='form'> <input id='area' name='area' type='hidden' value='{$areaname}'> <button id='{$areaname}' class='btn-text btn-sm' value='explore' name='{$areaname}' type='submit'> <img src=\"./img/{$imgname}\"/> </button> </form> ", FALSE)); } } else { /* Text-Only Links */ if (!$customtext){ /* Area Name Button */ $str = str_replace("_", " ", $areaname); $btn_name = str_replace("*", "'", $str); $document->add(new Comment(" <form id='exploreform' action='explore' name='exploreform' method='post' role='form'> <input id='area' name='area' type='hidden' value='{$areaname}'> <button id='{$areaname}' class='btn-violet btn-sm' value='explore' name='{$areaname}' type='submit'> {$btn_name} </button> </form> ", FALSE)); } else { /* Custom Link Text */ $customtext = str_replace("*", "'", $customtext); $document->add(new Comment(" <form id='exploreform' action='explore' name='exploreform' method='post' role='form'> <input id='area' name='area' type='hidden' value='{$areaname}'> <button id='{$areaname}' class='btn-violet btn-sm' style='display: inline;' value='explore' name='{$areaname}' type='submit'> {$customtext} </button> </form> ", FALSE)); } } return; } # END exploreButton
public function pickupItem($give_qty, $item, $continue){ $document = $this->document; $document->add(new Comment(" <form id='pickup_item' action='explore' name='pickup_item' method='post' role='form'> <input id='give_qty' name='give_qty' type='hidden' value='{$give_qty}'> <input id='item_found' name='item_found' type='hidden' value='{$item}'> <input id='continue' name='continue' type='hidden' value='{$continue}'> <button id='acquire' class='btn-violet btn-sm' style='display: inline;' value='item' name='acquire' type='submit'> Pick up {$give_qty} {$item}(s)? </button> </form> ", FALSE)); return; } # END pickupItem
public function giveItem($give_qty, $item){ $mysidia = Registry::get("mysidia"); $owned_qty = $mysidia->db->select("inventory", array("quantity"), "itemname ='{$item}' and owner ='{$mysidia->user->username}'")->fetchColumn(); if($owned_qty > 0){ // the item already exists, update the row for user's inventory $new_qty = $owned_qty + $give_qty; $mysidia->db->update("inventory", array("quantity" => $new_qty), "itemname ='{$item}' and owner='{$mysidia->user->username}'"); } else { // the item does not exist yet # find what $item's item category is so we can add it to the user's inventory $category = $mysidia->db->select("items", array("category"), "itemname ='{$item}'")->fetchColumn(); # insert a new row into user's inventory $mysidia->db->insert("inventory", array("iid" => NULL, "category" => $category, "itemname" => $item, "owner" => $mysidia->user->username, "quantity" => 1, "status" => 'Available')); } return; } # END giveItem
} #END ExploreView class ?>
You'll also need to make a relatively empty explore.php -
PHP Code:
<?php
class ExploreController extends AppController{ public function __construct(){ parent::__construct("member"); }
public function index(){ $mysidia = Registry::get("mysidia"); }
} # END ExploreController ?>
I think this paves the way for quite a lot, but there are a couple of important things:
Your browser url never leaves /explore. Areas do not exist as individual pages and are not linkable. This is a limitation of me not knowing how, and if I could, I'd build my system around that. I was hoping I could do something like "yoursite.com/explore/high_woods" to visit the High Woods, but... 'tis not what I got.
But I'm going to consider this an upside, in my case, because I do not want players sharing access to areas with other players. My players will be unlocking access to areas. Once unlocked, a shortcut to it will appear on the main explore page. Not all locations will appear there, but they'll be easy enough to traverse to.
My plan isn't to leave the text exploring system in place. Rather, I will display a map in most areas accessible from the main explore page. The links from there will go to pages with NPCs, take you to shops, other things, etc.
[ Question Time! ]
If you like the sounds of this, stay tuned! Let me know how you would like to see the system adapted, things you would like to do with it, your needs.
I've already implemented a way of giving users any amount of any item. I could also do this with money. But do you really want users to get something every time they visit an area? I think not!! I need examples of limiting factors. Both feasible and creative ones.
So things I'd like to implement: - - Items/money available while visiting during a certain time of day.
- - Items/money offered by a random percent chance. (And at a certain time of day, only?)
- - An item/money/event only able to be triggered/obtained once, at all, ever. (Flag in the database.)
- - Only able to obtain an item if don't already own that item. (Or a quantity of that item?)
- - Or maybe you require an item (a lantern?) to see in an area, and will only find items/continue if you can see.
- - Areas have items that respawn consistently (timestamp in the database, each item has to have its own slot in a table). 10 minutes, 20 minutes, daily, anything like that.
- - A random quantity of the item. (Limited, like, 2 to 5, or whatever you want to set, you know?) Same with money, a random amount between a min and max.
- - A random item from an array of possible items.
- - Find more than one item, like you find a shiny pebble and a mushroom and an exotic flower. =|?
- - Maybe there's only a chance of finding more than one item. 100% of the time you will find a pebble, 50% of the time you will also find a mushroom in addition to the pebble, and like 2% of the time you may also find an exotic flower.
Can anyone think of more, while I continue to work on this? Does anyone have more specific needs??
I also have a quest system somewhat ready to go hand-in-hand with this. Just want feedback before I go attempting to explain it.
__________________
Please do not contact me directly outside of Mysidia.
I also cannot troubleshoot code more than two years old - I legit don't remember it.
Last edited by Kyttias; 01-15-2015 at 07:23 PM.
|