diff --git a/src/API/AchievementAPI.php b/src/API/AchievementAPI.php new file mode 100644 index 000000000..8052f5b13 --- /dev/null +++ b/src/API/AchievementAPI.php @@ -0,0 +1,141 @@ + array( + "name" => "Taking Inventory", + "requires" => array(), + ),*/ + "mineWood" => array( + "name" => "Getting Wood", + "requires" => array( + //"openInventory", + ), + ), + "buildWorkBench" => array( + "name" => "Benchmarking", + "requires" => array( + "mineWood", + ), + ), + "buildPickaxe" => array( + "name" => "Time to Mine!", + "requires" => array( + "buildWorkBench", + ), + ), + "buildFurnace" => array( + "name" => "Hot Topic", + "requires" => array( + "buildPickaxe", + ), + ), + "acquireIron" => array( + "name" => "Acquire hardware", + "requires" => array( + "buildFurnace", + ), + ), + "buildHoe" => array( + "name" => "Time to Farm!", + "requires" => array( + "buildWorkBench", + ), + ), + "makeBread" => array( + "name" => "Bake Bread", + "requires" => array( + "buildHoe", + ), + ), + "bakeCake" => array( + "name" => "The Lie", + "requires" => array( + "buildHoe", + ), + ), + "buildBetterPickaxe" => array( + "name" => "Getting an Upgrade", + "requires" => array( + "buildWorkBench", + ), + ), + + ); + + function __construct(){ + } + + public static function broadcastAchievement(Player $player, $achievementId){ + if(ServerAPI::request()->api->getProperty("announce-player-achievements") == true){ + ServerAPI::request()->api->chat->broadcast($player->username." has just earned the achievement ".self::$achievements[$achievementId]["name"]); + }else{ + $player->sendChat("You have just earned the achievement ".self::$achievements[$achievementId]["name"]); + } + } + + public static function addAchievement($achievementId, $achievementName, array $requires = array()){ + if(!isset(self::$achievements[$achievementId])){ + self::$achievements[$achievementId] = array( + "name" => $achievementName, + "requires" => $requires, + ); + return true; + } + return false; + } + + public static function hasAchievement(Player $player, $achievementId){ + if(!isset(self::$achievements[$achievementId]) or !isset($player->achievements)){ + $player->achievements = array(); + return false; + } + + if(!isset($player->achievements[$achievementId]) or $player->achievements[$achievementId] == false){ + return false; + } + return true; + } + + public static function grantAchievement(Player $player, $achievementId){ + if(isset(self::$achievements[$achievementId]) and !self::hasAchievement($player, $achievementId)){ + foreach(self::$achievements[$achievementId]["requires"] as $requerimentId){ + if(!self::hasAchievement($player, $requerimentId)){ + return false; + } + } + $player->achievements[$achievementId] = true; + self::broadcastAchievement($player, $achievementId); + return true; + } + return false; + } + + public static function removeAchievement(Player $player, $achievementId){ + if(self::hasAchievement($player, $achievementId)){ + $player->achievements[$achievementId] = false; + } + } + + public function init(){ + } +} diff --git a/src/API/PlayerAPI.php b/src/API/PlayerAPI.php index e3d80dacd..a18f08160 100644 --- a/src/API/PlayerAPI.php +++ b/src/API/PlayerAPI.php @@ -449,6 +449,7 @@ class PlayerAPI{ "health" => 20, "lastIP" => "", "lastID" => 0, + "achievements" => array(), ); if(!file_exists(DATA_PATH."players/".$iname.".yml")){ diff --git a/src/API/ServerAPI.php b/src/API/ServerAPI.php index 5c4de5012..809d7952c 100644 --- a/src/API/ServerAPI.php +++ b/src/API/ServerAPI.php @@ -61,6 +61,7 @@ class ServerAPI{ "memory-limit" => "128M", "last-update" => false, "white-list" => false, + "announce-player-achievements" => true, "spawn-protection" => 16, "view-distance" => 10, "max-players" => 20, diff --git a/src/Player.php b/src/Player.php index 82b6f54b7..1bc43a455 100644 --- a/src/Player.php +++ b/src/Player.php @@ -58,6 +58,7 @@ class Player{ public $windowCnt = 2; public $windows = array(); public $blocked = true; + public $achievements = array(); public $chunksLoaded = array(); private $chunksOrder = array(); private $lastMeasure = 0; @@ -78,9 +79,9 @@ class Player{ private $received = array(); public $realmsData = array(); - public function __get($name){ + public function &__get($name){ if(isset($this->{$name})){ - return ($this->{$name}); + return $this->{$name}; } return null; } @@ -216,6 +217,7 @@ class Player{ public function save(){ if($this->entity instanceof Entity){ + $this->data->set("achievements", $this->achievements); $this->data->set("position", array( "level" => $this->entity->level->getName(), "x" => $this->entity->x, @@ -534,6 +536,11 @@ class Player{ if(($this->gamemode & 0x01) === 0x00){ $this->addItem($data["entity"]->type, $data["entity"]->meta, $data["entity"]->stack, false); } + switch($data["entity"]->type){ + case WOOD: + AchievementAPI::grantAchievement($this, "mineWood"); + break; + } }elseif($data["entity"]->level === $this->level){ $this->dataPacket(MC_TAKE_ITEM_ENTITY, $data); } @@ -740,6 +747,19 @@ class Player{ }else{ $this->setSlot($slot, BlockAPI::getItem($item->getID(), $item->getMetadata(), $s->count + $item->count), false); } + + switch($item->getID()){ + case WORKBENCH: + AchievementAPI::grantAchievement($this, "buildWorkBench"); + break; + case WOODEN_PICKAXE: + AchievementAPI::grantAchievement($this, "buildPickaxe"); + break; + case FURNACE: + AchievementAPI::grantAchievement($this, "buildFurnace"); + break; + + } } } return $res; @@ -1200,6 +1220,7 @@ class Player{ } $this->data->set("inventory", $inv); } + $this->achievements = $this->data->get("achievements"); $this->data->set("caseusername", $this->username); $this->inventory = array(); foreach($this->data->get("inventory") as $slot => $item){ @@ -1217,9 +1238,8 @@ class Player{ $this->data->set("lastIP", $this->ip); $this->data->set("lastID", $this->clientID); - if($this->data instanceof Config){ - $this->server->api->player->saveOffline($this->data); - } + $this->server->api->player->saveOffline($this->data); + $this->dataPacket(MC_LOGIN_STATUS, array( "status" => 0, )); @@ -1940,6 +1960,15 @@ class Player{ )); break; } + + if($tile->class === TILE_FURNACE and $data["slot"] == 2){ + switch($slot->getID()){ + case IRON_INGOT: + AchievementAPI::grantAchievement($this, "acquireIron"); + break; + } + } + if($item->getID() !== AIR and $slot->getID() == $item->getID()){ if($slot->count < $item->count){ if($this->removeItem($item->getID(), $item->getMetadata(), $item->count - $slot->count, false) === false){ diff --git a/src/utils/Config.php b/src/utils/Config.php index 9291e2789..ef8ba9090 100644 --- a/src/utils/Config.php +++ b/src/utils/Config.php @@ -150,7 +150,7 @@ class Config{ } } - public function __get($k){ + public function &__get($k){ return $this->get($k); } @@ -166,11 +166,11 @@ class Config{ return $this->remove($k); } - public function get($k){ + public function &get($k){ if($this->correct === false or !isset($this->config[$k])){ return false; } - return ($this->config[$k]); + return $this->config[$k]; } public function set($k, $v = true){