diff options
author | piernov <piernov@piernov.org> | 2016-05-09 22:06:30 +0200 |
---|---|---|
committer | piernov <piernov@piernov.org> | 2016-05-09 22:06:30 +0200 |
commit | f10c51f07a755d75a583f85316efbcd3bd1e4b6d (patch) | |
tree | 87419a11e12f5b7433459fcb5cb9da5211dcbd9e /inc | |
parent | 54635d17eef27eb2546d69599e4107b242509ced (diff) | |
parent | 2f32bc3153b7f2c2561e4603f912573921e6449f (diff) | |
download | candybox-f10c51f07a755d75a583f85316efbcd3bd1e4b6d.tar.gz candybox-f10c51f07a755d75a583f85316efbcd3bd1e4b6d.tar.bz2 candybox-f10c51f07a755d75a583f85316efbcd3bd1e4b6d.tar.xz candybox-f10c51f07a755d75a583f85316efbcd3bd1e4b6d.zip |
Merge branch 'alexichi' of ssh://piernov.org/srv/git/candybox into alexichi
Diffstat (limited to 'inc')
-rw-r--r-- | inc/Inventory.inc | 50 | ||||
-rw-r--r-- | inc/Item.inc | 35 | ||||
-rw-r--r-- | inc/Monster.inc | 23 | ||||
-rw-r--r-- | inc/craftmine.inc | 6 | ||||
-rw-r--r-- | inc/dungeon.inc | 66 | ||||
-rw-r--r-- | inc/messages.inc | 25 | ||||
-rw-r--r-- | inc/mine.inc | 2 | ||||
-rw-r--r-- | inc/perso.inc | 63 | ||||
-rw-r--r-- | inc/savegame.inc | 117 | ||||
-rw-r--r-- | inc/shop.inc | 56 |
10 files changed, 416 insertions, 27 deletions
diff --git a/inc/Inventory.inc b/inc/Inventory.inc index efe54f2..3e0137d 100644 --- a/inc/Inventory.inc +++ b/inc/Inventory.inc @@ -1,5 +1,7 @@ <?php +require_once("perso.inc"); + class Inventory { public $items = array(); @@ -20,22 +22,64 @@ class Inventory { } private function _addItem($item) { - $this->items[] = $item; + foreach($this->items as $k => $object){ + if($object[0] == $item){ + $this->items[$k][1]++; + return $this->items[$k]; + } + } + $tab = array($item,1); + $this->items[] = $tab; + return $tab; } public static function addItem($item) { $inv = self::get(); - $inv->_addItem($item); + $tab = $inv->_addItem($item); + return $tab; } private function _removeItem($item) { - unset($this->items[array_search($item, $this->items)]); + foreach($this->items as $k => $object) { + if($object[0] == $item) { + unset($this->items[$k]); + return; + } + } } public static function removeItem($item) { $inv = self::get(); $inv->_removeItem($item); } + + private function _useItem($item) { + foreach($this->items as $k => $object){ + if($object[0] == $item) { + $nb = $this->items[$k][1]; + if(limitUse($this->items[$k][0])){ + if($nb > 0) { + $this->items[$k][0]->consume(); + $this->items[$k][1]--; + } + if($nb-1 <= 0) $this->_removeItem($item); + return array($object[0], $nb-1); + } + } + } + return false; + } + + public static function useItem($item) { + $inv = self::get(); + $it = $inv->_useItem($item); + return $it; + } + + public function addToXML($root) { + foreach($this->items as $item) + $item[0]->addToXML($root, $item[1]); + } } ?> diff --git a/inc/Item.inc b/inc/Item.inc index bf77818..a8ee302 100644 --- a/inc/Item.inc +++ b/inc/Item.inc @@ -1,16 +1,49 @@ <?php +require_once("perso.inc"); + class Item { public $name = ""; public $cost = 0; public $icon = ""; public $desc = ""; + public $feat = array(); - function __construct($name, $cost, $icon, $desc) { + function __construct($name, $cost, $icon, $desc, $feat) { $this->name = $name; $this->cost = $cost; $this->icon = $icon; $this->desc = $desc; + $this->feat = $feat; + } + + function consume() { + foreach($this->feat as $k => $v) { + switch($k) { + case "hp": increasePerso("hp", +$v); break; + case "power": increasePerso("bonusPower", +$v); break; + } + } + } + + function addToXML($root, $count) { + $item = $root->addChild("item"); + $item->addChild("name", $this->name); + $item->addChild("cost", $this->cost); + $item->addChild("icon", $this->icon); + $item->addChild("desc", $this->desc); + $xmlfeat = $item->addChild("feat"); + foreach($this->feat as $k => $v) + $xmlfeat->addChild($k, $v); + $item->addChild("count", $count); + } + + public static function fromXML($xml) { + $feats = array(); + foreach($xml->feat[0] as $k => $v) + $feats[(string)$k] = (string)$v; + + return new static((string)$xml->name, +(string)$xml->cost /* convert to number */, (string)$xml->icon, (string)$xml->desc, $feats); } } diff --git a/inc/Monster.inc b/inc/Monster.inc new file mode 100644 index 0000000..ae48691 --- /dev/null +++ b/inc/Monster.inc @@ -0,0 +1,23 @@ +<?php + +class Monster { + public $name = ""; + public $icon = ""; + public $desc = ""; + public $hp = 1; + public $xp = 0; + public $level = 1; + public $power = 1; + + function __construct($name, $level, $hp, $xp, $power, $icon) { + $this->name = $name; + $this->level = $level; + $this->hp = $hp; + $this->xp = $xp; + $this->power = $power; + $this->icon = $icon; + + } +} + +?> diff --git a/inc/craftmine.inc b/inc/craftmine.inc index 33a28d7..f5dbbb1 100644 --- a/inc/craftmine.inc +++ b/inc/craftmine.inc @@ -2,12 +2,16 @@ require_once("mine.inc"); require_once("shop.inc"); +require_once("dungeon.inc"); +require_once("perso.inc"); function sendCraftMine() { $data = array("gold" => sendMine(), "shop" => sendShop(), "inventory" => Inventory::sendContent(), - "miners" => sendMiners() + "miners" => sendMiners(), + "dungeon" => sendDungeon(), + "perso" => sendPerso(), ); echo json_encode($data); } diff --git a/inc/dungeon.inc b/inc/dungeon.inc new file mode 100644 index 0000000..521303e --- /dev/null +++ b/inc/dungeon.inc @@ -0,0 +1,66 @@ +<?php +require_once("messages.inc"); +require_once("account.inc"); +require_once("Monster.inc"); + + +function generateMonster(){ + $monsters = simplexml_load_file('data/monsters.xml'); + $dungeon = array("cost"=>(string)$monsters["cost"],"monsters"=>array()); + foreach($monsters as $f){ + $floor = (string)$f["name"]; + $dungeon["monsters"][$floor] = array(); + foreach($f as $monster){ + $dungeon["monsters"][$floor][] = new Monster((string)$monster->name, + intval($monster->level), + intval($monster->hp), + intval($monster->xp), + intval($monster->power), + (string)$monster->icon); + } + } + return $dungeon; +} + +function initDungeon() { + $_SESSION["dungeon"]["access"] = true; +} + +function sendDungeon() { + if(!empty($_SESSION["dungeon"])) + return $_SESSION["dungeon"]; + else return false; +} + +function buildDungeon() { + $dungeon=generateMonster(); + if(!empty($_SESSION["dungeon"])) { + sendError("dungeon_already_available"); + } + elseif(debitAccount($dungeon["cost"])) { + initDungeon(); + $_SESSION["mine"]["gold"] -= $dungeon["cost"]; + echo json_encode($dungeon); + } +} + +function launchDungeon(){ + $f= $_POST["floor"]; + $dungeon=generateMonster(); + $opponent = $dungeon["monsters"]["floor".$f]; + echo json_encode($opponent); +} + +function sendDungeonProgress(){ + $f= $_POST["floor"]; + $nb=$_POST["mob"]; + $_SESSION["dungeon"]["flat"] = $f; + $_SESSION["dungeon"]["mob"] = $nb; +} + + +function exitDungeon(){ + $_SESSION["dungeon"] = false; +} + +?> diff --git a/inc/messages.inc b/inc/messages.inc index d6ea87e..3a7d9b1 100644 --- a/inc/messages.inc +++ b/inc/messages.inc @@ -5,13 +5,32 @@ $messages = array( "gold_insufficient" => "You don't have enough gold.", "shop_missing_item" => "This item does not exist.", "guild_not_yet_created" => "You need to create a guild first.", - "guild_already_built" => "You have aready built a guild." + "guild_already_built" => "You have aready built a guild.", + "dungeon_already_available" => "You can already access the dungeon", + + "gamesave_ok" => "Game saved.", + "gamesave_error" => "An error occured when trying to save the game.", + "gamesave_not_found" => "Couldn't find the specified save file.", + "gamesave_delete_fail" => "Couldn't delete the specified save file.", + "gamesave_delete_success" => "Game save successfully removed from server", + + "upload_fail" => "Could not upload save file.", + "upload_success" => "Save file uploaded successfully: %s", ); -function sendError($msg) { +function sendMessage($type, $msg, $fmt = null) { global $messages; $text = $messages[$msg]; - echo json_encode(array("error" => $text)); + if($fmt) $text = vsprintf($text, $fmt); + echo json_encode(array($type => $text)); +} + +function sendError($msg, $fmt = null) { + sendMessage("error", $msg, $fmt); +} + +function sendInfo($msg, $fmt = null) { + sendMessage("info", $msg, $fmt); } ?> diff --git a/inc/mine.inc b/inc/mine.inc index 94a2c66..752fc69 100644 --- a/inc/mine.inc +++ b/inc/mine.inc @@ -1,7 +1,7 @@ <?php function initCraftMine() { - $_SESSION["mine"] = array("mine" => 0, "gold" => 0, "miners" => 0); + $_SESSION["mine"] = array("gold" => 0, "miners" => 0); } function withdrawMine() { diff --git a/inc/perso.inc b/inc/perso.inc new file mode 100644 index 0000000..0a32b64 --- /dev/null +++ b/inc/perso.inc @@ -0,0 +1,63 @@ +<?php + +function sendPerso() { + if(empty($_SESSION["perso"])) + initPerso(); + return $_SESSION["perso"]; +} + +function increasePerso($prop, $num) { + if(empty($_SESSION["perso"])) + initPerso(); + $_SESSION["perso"][$prop] += $num; + if($_SESSION["perso"]["hp"] > $_SESSION["perso"]["maxHP"]){//if you want to heal even if you have less than 3 hp to heal, heal until the max is attained + $diff = $_SESSION["perso"]["hp"] - $_SESSION["perso"]["maxHP"]; + $_SESSION["perso"]["hp"] -= $diff; + } +} + +/** + *traite le fait que wooden sword n'est pas cumulable + *metal sword non plus + *life bottle cumulable 3 fois + *si on clique sur wooden sword alors que on avait une metal sword, le bonusPower passe de +3 à +1 + */ +function limitUse($item){ + $n = $item->name; + if($n =="Life Bottle")return true; + if(empty($_SESSION[$n])){ + $_SESSION[$n]=1; + return true; + } + else{ + $_SESSION[$n]++; + if($_SESSION[$n] >= $item->feat["limit"])return false; + else return true; + } +} + +function updatePerso(){ + $hp = $_POST["hp"]; + $maxHP = $_POST["maxHP"]; + $xp = $_POST["xp"]; + $lv = $_POST["lv"]; + $power = $_POST["power"]; + $bonusPower = $_POST["bonusPower"]; + $_SESSION["perso"]["hp"] = +$hp; + $_SESSION["perso"]["maxHP"] = +$maxHP; + $_SESSION["perso"]["xp"] = +$xp; + $_SESSION["perso"]["lv"] = +$lv; + $_SESSION["perso"]["power"] = +$power; + $_SESSION["perso"]["bonusPower"] = +$bonusPower; +} + +function initPerso(){ + $_SESSION["perso"]["hp"] = 5; + $_SESSION["perso"]["maxHP"] = 5; + $_SESSION["perso"]["xp"] = 0; + $_SESSION["perso"]["lv"] = 3; + $_SESSION["perso"]["power"] = 3; + $_SESSION["perso"]["bonusPower"] = 0; +} + +?> diff --git a/inc/savegame.inc b/inc/savegame.inc new file mode 100644 index 0000000..6d92af2 --- /dev/null +++ b/inc/savegame.inc @@ -0,0 +1,117 @@ +<?php + +require_once("inc/messages.inc"); +require_once("inc/Inventory.inc"); +require_once("inc/Item.inc"); + +define("SAVEDIR", "data/save"); + +function genXML($table, $xml) { + foreach($table as $k => $v) { + if(is_object($v)) { // Object: either Item or Inventory + if(is_callable(array($v, "addToXML"))) // Check if the object has a addToXML method + $v->addToXML($xml->addChild($k)); + } elseif(is_array($v)) // Nested array + genXML($v, $xml->addChild($k)); + else // Single value (numeric or string) + $xml->addChild($k, $v); + } +} + +function genSave() { + $save = new SimpleXMLElement("<save/>"); + genXML($_SESSION, $save); + return $save; +} + +function genFilename() { + return "craftmine-".date("d-m-Y_H-i-s").".save.xml"; +} + +function saveGame() { + $save = genSave(); + if($save->asXML(SAVEDIR."/".genFilename())) sendInfo("gamesave_ok"); + else sendError("gamesave_error"); +} + +function downSave() { + $save = ""; + $filename = ""; + + if(empty($_GET["filename"])) { + $filename = genFilename(); + $save = genSave()->asXML(); // Send current game save file if no file specified + } else { + $filename = $_GET["filename"]; + $save = file_get_contents(SAVEDIR . "/" . $filename); + if(empty($save)) return; // Probably file not found + } + + header("Content-Type: application/xml"); // Force browser to intepret the file as XML + header("Content-Disposition: attachment; filename=".$filename); // Force download with specific filename + header("Cache-Control: no-cache"); // Avoid storing save file in proxy/browser cache + echo $save; +} + +function listSaves() { + chdir(SAVEDIR); // Go to SAVEDIR folder, avoiding leading folder name in file list + echo json_encode(glob("*.save.xml")); +} + +function parseSave($xml, &$table) { // Passing $table by reference + foreach($xml as $k => $v) { + if($v->count() == 0) { // No child, treat as string + $v = (string)$v; + if(is_numeric($v)) $v = +$v; // If it is in fact a number, treat it that way using PHP unary '+' coercion + $table[$k] = $v; + } elseif($k == "inventory") { // Special case for inventory: objects need to be created + foreach($v as $item) { + for($i=0; $i<+$item->count; $i++) // Add the right count of items to Inventory + Inventory::addItem(Item::fromXML($item)); + } + } else { // If nested array + $table[$k] = array(); + parseSave($v, $table[$k]); + } // Other types unsupported (unused) + } +} + +function deleteSave() { + if(empty($_POST["filename"])) return; + $path = SAVEDIR . "/" . basename($_POST["filename"]); // remove any leading directory + if(file_exists($path) && unlink($path)) + sendInfo("gamesave_delete_success"); + else sendError("gamesave_delete_fail"); +} + +function loadSave() { + if(empty($_POST["filename"])) return; + $xml = simplexml_load_file(SAVEDIR . "/" . $_POST["filename"]); + if(empty($xml)) { + sendError("gamesave_not_found"); + return; + } + $_SESSION = array(); // drop current game + parseSave($xml, $_SESSION); +} + +function uploadSave() { + $fname = basename($_FILES['savefile']['name']); + $src = $_FILES['savefile']['tmp_name']; + + libxml_use_internal_errors(true); // Ignore errors when loading the received file + $xml = simplexml_load_file($src); + libxml_use_internal_errors(false); + if(!$xml) { + sendError("upload_fail"); + return; + } + $table = array(); + parseSave($xml, $table); // Parse received file + + $save = new SimpleXMLElement("<save/>"); + genXML($table, $save); // Regenerate it + if($save->asXML(SAVEDIR."/".$fname)) sendInfo("upload_success", array($fname)); + else sendError("upload_error"); +} +?> diff --git a/inc/shop.inc b/inc/shop.inc index 11cf97b..69161e1 100644 --- a/inc/shop.inc +++ b/inc/shop.inc @@ -4,20 +4,36 @@ require_once("messages.inc"); require_once("account.inc"); require_once("Item.inc"); require_once("Inventory.inc"); +require_once("perso.inc"); -$shop = array( - "cost" => 3, - "items" => array( - new Item("cat", 6, "🐈", "Nyan!"), - new Item("torch", 3, "🔦", "Electric torch"), - ), -); +function loadShop(){ + $items = simplexml_load_file('data/items.xml'); + $shop = array("cost"=>(string)$items["cost"],"items"=>array()); + foreach($items as $cat){ + $category = (string)$cat["name"]; + $shop["items"][$category] = array(); + foreach($cat as $item){ + $feats = array(); + foreach($item->features[0] as $k => $v) + $feats[(string)$k] = (string)$v; + $shop["items"][$category][] = new Item( + (string)$item->name, + intval($item->cost), + (string)$item->icon, + (string)$item->description, + $feats); + } + } + return $shop; +} function getItem($name) { - global $shop; - foreach($shop["items"] as $item) { - if($name == $item->name) { - return $item; + $shop=loadShop(); + foreach($shop["items"] as $cat) { + foreach($cat as $item){ + if($name == $item->name) { + return $item; + } } } sendError("shop_missing_item"); @@ -29,31 +45,35 @@ function initShop() { } function sendShop() { - global $shop; if(!empty($_SESSION["shop"])) - return $shop; + return loadShop(); else return false; } function buildShop() { - global $shop; + $shop=loadShop(); if(!empty($_SESSION["shop"])) { sendError("shop_already_built"); } elseif(debitAccount($shop["cost"])) { initShop(); - $_SESSION["mine"]["gold"] -= $shop["cost"]; - echo json_encode(sendShop()); + echo json_encode($shop); } } function buyItem() { $item = getItem($_POST["item"]); if($item && debitAccount($item->cost)) { - Inventory::addItem($item); - echo json_encode($item); + $tab = Inventory::addItem($item); + echo json_encode($tab); //renvoyer un tableau avec comme première entrée $item et comme deuxième entrée le nombre } } +function useItem(){ + $item = getItem($_POST["item"]); + $it = Inventory::useItem($item); + echo json_encode(array("perso" => sendPerso(), "item" => $it)); +} + ?> |