diff --git a/questtypes/bossfight/BossfightQuesttypeAgent.inc b/questtypes/bossfight/BossfightQuesttypeAgent.inc new file mode 100644 index 00000000..6d99ec44 --- /dev/null +++ b/questtypes/bossfight/BossfightQuesttypeAgent.inc @@ -0,0 +1,24 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\questtypes; + + + /** + * QuesttypeAgent for a boss-fight. + * + * @author Oliver Hanraths + */ + class BossfightQuesttypeAgent extends \hhu\z\QuesttypeAgent + { + } + +?> diff --git a/questtypes/bossfight/BossfightQuesttypeController.inc b/questtypes/bossfight/BossfightQuesttypeController.inc new file mode 100644 index 00000000..366aabc8 --- /dev/null +++ b/questtypes/bossfight/BossfightQuesttypeController.inc @@ -0,0 +1,244 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\questtypes; + + + /** + * Controller of the BossfightQuesttypeAgent for a boss-fight. + * + * @author Oliver Hanraths + */ + class BossfightQuesttypeController extends \hhu\z\QuesttypeController + { + /** + * Required models + * + * @var array + */ + public $models = array('media'); + + + + + /** + * Save the answers of a Character for a Quest. + * + * @param array $seminary Current Seminary data + * @param array $questgroup Current Questgroup data + * @param array $quest Current Quest data + * @param array $character Current Character data + * @param array $answers Character answers for the Quest + */ + public function saveAnswersOfCharacter($seminary, $questgroup, $quest, $character, $answers) + { + // Prepare session + $this->prepareSession($quest['id']); + + // Remove previous answers + $this->Bossfight->clearCharacterSubmissions($quest['id'], $character['id']); + + // Save answers + foreach($_SESSION['quests'][$quest['id']]['stages'] as &$stage) { + $this->Bossfight->setCharacterSubmission($stage['id'], $character['id']); + } + } + + + /** + * Check if answers of a Character for a Quest match the correct ones. + * + * @param array $seminary Current Seminary data + * @param array $questgroup Current Questgroup data + * @param array $quest Current Quest data + * @param array $character Current Character data + * @return boolean True/false for a right/wrong answer or null for moderator evaluation + */ + public function matchAnswersOfCharacter($seminary, $questgroup, $quest, $character, $answers) + { + // Get Boss-Fight + $fight = $this->Bossfight->getBossFight($quest['id']); + + // Prepare session + $this->prepareSession($quest['id']); + + // Calculate lives + $lives = array( + 'character' => $fight['lives_character'], + 'boss' => $fight['lives_boss'] + ); + foreach($_SESSION['quests'][$quest['id']]['stages'] as &$stage) + { + $lives['character'] += $stage['livedrain_character']; + $lives['boss'] += $stage['livedrain_boss']; + } + + + return ($lives['boss'] == 0 && $lives['character'] > 0); + } + + + /** + * Action: quest. + * + * Display a stage with a text and the answers for the following + * stages. + * + * @param array $seminary Current Seminary data + * @param array $questgroup Current Questgroup data + * @param array $quest Current Quest data + * @param array $character Current Character data + * @param Exception $exception Character submission exception + */ + public function quest($seminary, $questgroup, $quest, $character, $exception) + { + // Get Boss-Fight + $fight = $this->Bossfight->getBossFight($quest['id']); + if(!is_null($fight['boss_seminarymedia_id'])) { + $fight['bossmedia'] = $this->Media->getSeminaryMediaById($fight['boss_seminarymedia_id']); + } + + // Prepare session + $this->prepareSession($quest['id']); + + // Get Stage + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('submit_stages'))) + { + $stages = $this->request->getPostParam('submit_stages'); + $stageId = array_keys($stages)[0]; + $stage = $this->Bossfight->getStageById($stageId); + } + else + { + $_SESSION['quests'][$quest['id']]['stages'] = array(); + $stage = $this->Bossfight->getFirstStage($quest['id']); + } + + // Store Stage in session + if(count($_SESSION['quests'][$quest['id']]['stages']) == 0 || $_SESSION['quests'][$quest['id']]['stages'][count($_SESSION['quests'][$quest['id']]['stages'])-1]['id'] != $stage['id']) { + $_SESSION['quests'][$quest['id']]['stages'][] = $stage; + } + + // Calculate lives + $lives = array( + 'character' => $fight['lives_character'], + 'boss' => $fight['lives_boss'] + ); + foreach($_SESSION['quests'][$quest['id']]['stages'] as &$stage) + { + $lives['character'] += $stage['livedrain_character']; + $lives['boss'] += $stage['livedrain_boss']; + } + + // Get Child-Stages + $childStages = $this->Bossfight->getChildStages($stage['id']); + + // Get answer of Character + if($this->request->getGetParam('show-answer') == 'true') { + foreach($childStages as &$childStage) { + $childStage['answer'] = $this->Bossfight->getCharacterSubmission($childStage['id'], $character['id']); + } + } + + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('character', $character); + $this->set('fight', $fight); + $this->set('stage', $stage); + $this->set('lives', $lives); + $this->set('childStages', $childStages); + } + + + /** + * Action: submission. + * + * Display all stages with the answers the character has + * choosen. + * + * @param array $seminary Current Seminary data + * @param array $questgroup Current Questgroup data + * @param array $quest Current Quest data + * @param array $character Current Character data + */ + public function submission($seminary, $questgroup, $quest, $character) + { + // Get Boss-Fight + $fight = $this->Bossfight->getBossFight($quest['id']); + if(!is_null($fight['boss_seminarymedia_id'])) { + $fight['bossmedia'] = $this->Media->getSeminaryMediaById($fight['boss_seminarymedia_id']); + } + + // Get stages + $stages = array(); + $stage = $this->Bossfight->getFirstStage($quest['id']); + while(!is_null($stage)) + { + $stages[] = $stage; + + $childStages = $this->Bossfight->getChildStages($stage['id']); + $stage = null; + foreach($childStages as &$childStage) + { + if($this->Bossfight->getCharacterSubmission($childStage['id'], $character['id'])) + { + $stage = $childStage; + break; + } + } + } + + // Calculate lives + $stages[0]['lives'] = array( + 'character' => $fight['lives_character'], + 'boss' => $fight['lives_boss'] + ); + for($i=1; $i $stages[$i-1]['lives']['character'] + $stages[$i]['livedrain_character'], + 'boss' => $stages[$i-1]['lives']['boss'] + $stages[$i]['livedrain_boss'], + ); + } + + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('character', $character); + $this->set('fight', $fight); + $this->set('stages', $stages); + } + + + + + /** + * Prepare the session to store stage information in + * + * @param int $questId ID of Quest + */ + private function prepareSession($questId) + { + if(!array_key_exists('quests', $_SESSION)) { + $_SESSION['quests'] = array(); + } + if(!array_key_exists($questId, $_SESSION['quests'])) { + $_SESSION['quests'][$questId] = array(); + } + if(!array_key_exists('stages', $_SESSION['quests'][$questId])) { + $_SESSION['quests'][$questId]['stages'] = array(); + } + } + + } + +?> diff --git a/questtypes/bossfight/BossfightQuesttypeModel.inc b/questtypes/bossfight/BossfightQuesttypeModel.inc new file mode 100644 index 00000000..a05927f0 --- /dev/null +++ b/questtypes/bossfight/BossfightQuesttypeModel.inc @@ -0,0 +1,183 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\questtypes; + + + /** + * Model of the BossfightQuesttypeAgent for a boss-fight. + * + * @author Oliver Hanraths + */ + class BossfightQuesttypeModel extends \hhu\z\QuesttypeModel + { + + + + + /** + * Get a Boss-Fight. + * + * @throws IdNotFoundException + * @param int $questId ID of Quest + * @return array Boss-Fight data + */ + public function getBossFight($questId) + { + $data = $this->db->query( + 'SELECT bossname, boss_seminarymedia_id, lives_character, lives_boss '. + 'FROM questtypes_bossfight '. + 'WHERE quest_id = ?', + 'i', + $questId + ); + if(empty($data)) { + throw new \nre\exceptions\IdNotFoundException($questId); + } + + + return $data[0]; + } + + + /** + * Get the first Stage to begin the Boss-Fight with. + * + * @param int $questId ID of Quest + * @return array Data of first Stage + */ + public function getFirstStage($questId) + { + $data = $this->db->query( + 'SELECT id, text, question, livedrain_character, livedrain_boss '. + 'FROM questtypes_bossfight_stages '. + 'WHERE questtypes_bossfight_quest_id = ? AND parent_stage_id IS NULL', + 'i', + $questId + ); + if(!empty($data)) { + return $data[0]; + } + + + return null; + } + + + /** + * Get a Stage by its ID. + * + * @param int $stageId ID of Stage + * @return array Stage data or null + */ + public function getStageById($stageId) + { + $data = $this->db->query( + 'SELECT id, text, question, livedrain_character, livedrain_boss '. + 'FROM questtypes_bossfight_stages '. + 'WHERE id = ?', + 'i', + $stageId + ); + if(!empty($data)) { + return $data[0]; + } + + + return null; + } + + + /** + * Get the follow-up Stages for a Stage. + * + * @param int $parentStageId ID of Stage to get follow-up Stages for + * @return array List of follow-up Stages + */ + public function getChildStages($parentStageId) + { + return $this->db->query( + 'SELECT id, text, question, livedrain_character, livedrain_boss '. + 'FROM questtypes_bossfight_stages '. + 'WHERE parent_stage_id = ?', + 'i', + $parentStageId + ); + } + + + /** + * Reset all Character submissions of a Boss-Fight. + * + * @param int $questId ID of Quest + * @param int $characterId ID of Character + */ + public function clearCharacterSubmissions($questId, $characterId) + { + $this->db->query( + 'DELETE FROM questtypes_bossfight_stages_characters '. + 'WHERE questtypes_bossfight_stage_id IN ('. + 'SELECT id '. + 'FROM questtypes_bossfight_stages '. + 'WHERE questtypes_bossfight_quest_id = ?'. + ') AND character_id = ?', + 'ii', + $questId, + $characterId + ); + } + + + /** + * Save Character’s submitted answer for one Boss-Fight-Stage. + * + * @param int $regexId ID of list + * @param int $characterId ID of Character + */ + public function setCharacterSubmission($stageId, $characterId) + { + $this->db->query( + 'INSERT INTO questtypes_bossfight_stages_characters '. + '(questtypes_bossfight_stage_id, character_id) '. + 'VALUES '. + '(?, ?) '. + 'ON DUPLICATE KEY UPDATE '. + 'questtypes_bossfight_stage_id = ?', + 'iii', + $stageId, $characterId, $stageId + ); + } + + + /** + * Get answer of one Boss-Fight-Stage submitted by Character. + * + * @param int $regexId ID of list + * @param int $characterId ID of Character + * @return boolean Stage taken + */ + public function getCharacterSubmission($stageId, $characterId) + { + $data = $this->db->query( + 'SELECT questtypes_bossfight_stage_id '. + 'FROM questtypes_bossfight_stages_characters '. + 'WHERE questtypes_bossfight_stage_id = ? AND character_id = ? ', + 'ii', + $stageId, $characterId + ); + + + return (!empty($data)); + } + + } + +?> diff --git a/questtypes/bossfight/html/quest.tpl b/questtypes/bossfight/html/quest.tpl new file mode 100644 index 00000000..bcf2bcd0 --- /dev/null +++ b/questtypes/bossfight/html/quest.tpl @@ -0,0 +1,58 @@ + + + + + + + + + + + +
+ + + + + +
+ : + 0) : ?> + + ♥ + + + + + + : + 0) : ?> + + ♥ + + + + +
+ +

+ +
+ +
    + +
  • + + → + + +
  • + + +
  • + + +
  • + +
+
diff --git a/questtypes/bossfight/html/submission.tpl b/questtypes/bossfight/html/submission.tpl new file mode 100644 index 00000000..a8b7eefb --- /dev/null +++ b/questtypes/bossfight/html/submission.tpl @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + +
+ + + + + +
+ +
+ : + 0) : ?> + + ♥ + + + + + + : + 0) : ?> + + ♥ + + + + +