/** * Check of a character can move from one area to the other * * @param int $area_id_from the ID of the current area * @param int $area_id_to the ID of the area where the character wanna go * @param int @character_id the current character ID * @return boolean whenever the character can move or not */ function canMove($area_id_from = null, $area_id_to = null, $character_id = null) { $this->contain(); $areaFrom = $this->find('first', array('conditions' => array('Area.id' => $area_id_from))); $areaTo = $this->find('first', array('conditions' => array('Area.id' => $area_id_to))); if ($areaFrom['Area']['travel_to_quest_id'] != 0) { App::import('Model', 'CharactersQuest'); $CharactersQuest = new CharactersQuest(); $someQuest = $CharactersQuest->find('first', array('conditions' => array('CharactersQuest.quest_id' => $areaFrom['Area']['travel_to_quest_id'], 'CharactersQuest.character_id' => $character_id, 'CharactersQuest.completed' => 'finished'))); if (empty($someQuest)) { return false; } } return true; }
function game_abandon($id = null) { App::import('Model', 'CharactersQuest'); $CharactersQuest = new CharactersQuest(); $CharactersQuest->deleteAll(array('quest_id' => $id, 'character_id' => $this->Session->read('Game.Character.id'), 'completed' => array('yes', 'no'))); $this->redirect('/game/quests'); }
/** * Get the avaible options of npc/character conversation * @return array */ function getOptions($npc_id = null, $character_id = null) { if (!isset($npc_id) || empty($npc_id) || !isset($character_id) || empty($character_id)) { return array(); } $this->bindModel(array('hasMany' => array('Log'))); $this->Log->bindModel(array('belongsTo' => array('Conversation'))); $last_log = $this->Log->find('first', array('conditions' => array('Log.npc_id' => $npc_id, 'Log.character_id' => $character_id), 'order' => 'Log.created DESC')); if (!empty($last_log)) { // Get the conversation $conditions = array(); if ($last_log['Conversation']['conversation_goto'] != 0) { $conditions['Conversation.parent_id'] = $last_log['Conversation']['conversation_goto']; } else { $conditions['Conversation.parent_id'] = $last_log['Conversation']['id']; } $this->unbindModel(array('hasMany' => array('Log'))); $available_conversations = $this->find('all', array('conditions' => $conditions)); // In het geval dat er we naar een conversation moeten gaan, pakken we daar ook de laat gesproken antwoord van if ($last_log['Conversation']['conversation_goto'] != 0) { $this->unbindModel(array('hasMany' => array('Log'))); $last_log = $this->find('first', array('conditions' => array('Conversation.id' => $last_log['Conversation']['conversation_goto']))); } } else { $this->unbindModel(array('hasMany' => array('Log'))); $last_log = $this->find('first', array('conditions' => array('Conversation.npc_id' => $npc_id, 'Conversation.parent_id' => '0'))); $this->unbindModel(array('hasMany' => array('Log'))); $available_conversations = $this->find('all', array('conditions' => array('Conversation.parent_id' => $last_log['Conversation']['id']))); } // Voor sommige quests moeten bepaalde quest behaald zijn (of mee bezig zijn). Kijken of dat bij deze quests het geval is... App::import('Model', 'ConversationsQuest'); $ConversationsQuest = new ConversationsQuest(); App::import('Model', 'CharactersQuest'); $CharactersQuest = new CharactersQuest(); /* $ConversationsQuest->bindModel(array('hasOne' => array( 'CharactersQuest' => array( #'foreignKey' => false, #'foreignKey' => 'ConversationsQuest.quest_id = CharactersQuest.quest_id', 'conditions' => array( 'CharactersQuest.character_id' => $character_id ) ) ) )); */ $conversations_ids = array(); foreach ($available_conversations as $index => $conversation) { if ($conversation['Conversation']['quest_id'] != '0') { // Er moet een quest zijn voor deze conversation $someQuest = $CharactersQuest->find('first', array('conditions' => array('CharactersQuest.quest_id' => $conversation['Conversation']['quest_id'], 'CharactersQuest.character_id' => $character_id, 'CharactersQuest.completed' => 'finished'))); if (empty($someQuest)) { unset($available_conversations[$index]); } } // Let op! Dit zijn acties... if (!empty($conversation['Quest'])) { // Kijken of er een quest completed moet zijn... foreach ($conversation['Quest'] as $ActionsQuest) { // @TODO. Check it in Quest->canView() if ($ActionsQuest['ActionsConversation']['type'] == 'completequest') { // Dan moet deze quest ook wel klaar zijn om in te leveren zijn... $someQuest = $CharactersQuest->find('first', array('conditions' => array('CharactersQuest.quest_id' => $ActionsQuest['ActionsConversation']['target_id'], 'CharactersQuest.character_id' => $character_id, 'CharactersQuest.completed' => 'yes'))); if (empty($someQuest) && isset($available_conversations[$index])) { unset($available_conversations[$index]); } } elseif ($ActionsQuest['ActionsConversation']['type'] == 'getquest') { // Ervoor zorgen dat je niet 2x dezelfde quest kan krijgen... // Dan moet deze quest ook wel klaar zijn om in te leveren zijn... // @TODO kijken of je hier niet een quest hebt wat 'repeatable' is... $someQuest = $CharactersQuest->find('first', array('conditions' => array('CharactersQuest.quest_id' => $ActionsQuest['ActionsConversation']['target_id'], 'CharactersQuest.character_id' => $character_id))); if (!empty($someQuest) && isset($available_conversations[$index])) { unset($available_conversations[$index]); } } } } if (isset($available_conversations[$index])) { $conversations_ids[$conversation['Conversation']['id']] = $conversation['Conversation']['id']; } } $ConversationsQuests = $ConversationsQuest->find('all', array('conditions' => array('ConversationsQuest.conversation_id' => $conversations_ids))); foreach ($ConversationsQuests as $ConversationsQuest) { // Controleren of de character deze conversation wel mag zien... // Compleet en moet deze compleet zijn? // De bijhorende quest opvragen... $CharactersQuestData = $CharactersQuest->find('first', array('conditions' => array('CharactersQuest.quest_id' => $ConversationsQuest['ConversationsQuest']['quest_id'], 'CharactersQuest.character_id' => $character_id))); if ($ConversationsQuest['ConversationsQuest']['completed'] == 'yes') { // De conversation mag alleen zichtbaar zijn als de gebruiker deze ook compleet heeft. if ($CharactersQuestData['CharactersQuest']['completed'] != 'yes') { unset($conversations_ids[$ConversationsQuest['ConversationsQuest']['conversation_id']]); } } elseif ($ConversationsQuest['ConversationsQuest']['completed'] == 'no') { // De conversation mag alleen zichtbaar zijn als de gebruiker deze niet compleet heeft. if ($CharactersQuestData['CharactersQuest']['completed'] != 'no') { unset($conversations_ids[$ConversationsQuest['ConversationsQuest']['conversation_id']]); } } elseif ($ConversationsQuest['ConversationsQuest']['completed'] == 'finished') { // De conversation mag alleen zichtbaar zijn als de gebruiker deze niet compleet heeft. if ($CharactersQuestData['CharactersQuest']['completed'] != 'finished') { unset($conversations_ids[$ConversationsQuest['ConversationsQuest']['conversation_id']]); } } elseif ($ConversationsQuest['ConversationsQuest']['completed'] == 'all') { // De conversation mag alleen zichtbaar zijn als de gebruiker deze niet compleet heeft. if ($CharactersQuestData['CharactersQuest']['completed'] != '') { // Bij geen resultaat is de gebruiker niet aan deze quest bezig unset($conversations_ids[$ConversationsQuest['ConversationsQuest']['conversation_id']]); } } } if (!empty($conversations_ids)) { $available = $this->find('all', array('conditions' => array('Conversation.id' => $conversations_ids))); } else { $available = array(); } return array('available' => $available, 'last_log' => $last_log); }
/** * Check if a character can loot a item * * There are a several conditions before an item can be looted. * If the field `Item.unique` is greater then 0 the item may not be looted if * the character has already the number of `unique` in it's bags. In case of * the field `AreasObstaclesItem.max_drop` is greater than 0 the item may not * be looted again. If `AreasObstaclesItem.player_only` this last conditions is * per Character and not per game. So it is possible to loot an very rarely item * witch can be looted X times in a game. * There is also a field called `AreasObstaclesItem.spawn_time`. This is the time * in seconds between the item can looted. If `AreasObstaclesItem.player_only` is * set to 1 this only counts for the player. * If the character doesn't have enough space in it's back the item cannot be * loaded aswell. * An item can only be looted if the character is at the same location of the item. * Some items can only be looted if the character is on a quest (and not completed). * * @param int $character_id the current character ID * @param int $areas_obstacles_item_id the ID of the Area_Obstacle_Item @see `areas_obstacles_items` * @param int $area_id the current area of the character * @return boolean whenever the character can loot or not */ function canLoot($areas_obstacles_item_id = null, $character_id = null, $area_id = null) { if (!isset($character_id) || !isset($areas_obstacles_item_id)) { return false; } $conditions = array(); $conditions['Drop.character_id'] = $character_id; App::import('Model', 'AreasObstaclesItem'); $AreasObstaclesItem = new AreasObstaclesItem(); $AreasObstaclesItem->contain(array('AreasObstacle')); $drop = $AreasObstaclesItem->find('first', array('conditions' => array('AreasObstaclesItem.id' => $areas_obstacles_item_id))); if ($drop['AreasObstacle']['area_id'] != $area_id) { return false; } if ($drop['AreasObstaclesItem']['quest_id'] != 0) { App::import('Model', 'CharactersQuest'); $CharactersQuest = new CharactersQuest(); $hasQuest = $CharactersQuest->find('first', array('conditions' => array('CharactersQuest.character_id' => $character_id, 'CharactersQuest.quest_id' => $drop['AreasObstaclesItem']['quest_id'], 'CharactersQuest.completed' => 'no'))); if (empty($hasQuest)) { return false; } } if (isset($drop['AreasObstaclesItem']['item_id'])) { $conditions['Drop.item_id'] = $drop['AreasObstaclesItem']['item_id']; } $allDrops = $this->find('count', array('conditions' => array('Drop.character_id' => $character_id, 'Drop.item_id' => $drop['AreasObstaclesItem']['item_id'], 'Drop.areas_obstacle_item_id' => $drop['AreasObstaclesItem']['id']))); App::import('Model', 'Inventory'); $Inventory = new Inventory(); $Inventory->contain(); $hasAmount = $Inventory->find('count', array('conditions' => array('Inventory.character_id' => $character_id, 'Inventory.item_id' => $drop['AreasObstaclesItem']['item_id']))); if (isset($drop['AreasObstaclesItem']['max_drop']) && $drop['AreasObstaclesItem']['max_drop'] > 0) { if ($allDrops >= $drop['AreasObstaclesItem']['max_drop'] && $hasAmount >= $drop['AreasObstaclesItem']['max_drop']) { return false; } } if (isset($drop['AreasObstaclesItem']['spawn_time']) && $drop['AreasObstaclesItem']['spawn_time'] > 0) { $conditions['Drop.created >'] = date('Y-m-d H:i:s', strtotime("-" . $drop['AreasObstaclesItem']['spawn_time'] . " seconds")); } $conditions['Drop.areas_obstacle_item_id'] = $drop['AreasObstaclesItem']['id']; $someDrops = $this->find('first', array('conditions' => $conditions)); if (!$this->hasFreeSpace($character_id, $drop['AreasObstaclesItem']['item_id'])) { return false; } if (empty($someDrops)) { return true; } else { if ($hasAmount < $drop['AreasObstaclesItem']['max_drop']) { return true; } else { return false; } } }
/** * Updates a Quest for a Character. If the Quest is completed and turned in * the Character may receive some Quest rewards. * * @param int $quest The ID of the quest * @param int $character_id The ID of the Character * @param boolean $turnIn Whenever this quest is turning in */ function update($quest_id = null, $character_id = null, $turnIn = false) { App::import('Model', 'CharactersQuest'); $CharactersQuest = new CharactersQuest(); $conditions = array(); $conditions['CharactersQuest.completed !='] = 'finished'; if (isset($quest_id)) { $conditions['CharactersQuest.quest_id'] = $quest_id; } if (isset($character_id)) { $conditions['CharactersQuest.character_id'] = $character_id; } $quests = $CharactersQuest->find('all', array('conditions' => array($conditions))); if (!empty($quests)) { // Inventory, Kill maybe needed App::import('Model', 'Inventory'); $Inventory = new Inventory(); App::import('Model', 'Kill'); $Kill = new Kill(); $charactersQuestsData = array(); $i = 0; foreach ($quests as $quest) { $charactersQuestsData[$i]['id'] = $quest['CharactersQuest']['id']; // Get the needed things (items, object, whatever) here $itemsNeeded = $this->ItemsQuest->find('list', array('conditions' => array('ItemsQuest.quest_id' => $quest['CharactersQuest']['quest_id'], 'ItemsQuest.type' => 'needed'), 'fields' => array('ItemsQuest.item_id', 'ItemsQuest.amount'))); $mobsNeeded = $this->MobsQuest->find('list', array('conditions' => array('MobsQuest.quest_id' => $quest['CharactersQuest']['quest_id']), 'fields' => array('MobsQuest.mob_id', 'MobsQuest.amount'))); $itemsRewards = $this->ItemsQuest->find('list', array('conditions' => array('ItemsQuest.quest_id' => $quest['CharactersQuest']['quest_id'], 'ItemsQuest.type' => 'reward'), 'fields' => array('ItemsQuest.item_id', 'ItemsQuest.amount'))); $statsRewards = $this->QuestsStat->find('list', array('conditions' => array('QuestsStat.quest_id' => $quest['CharactersQuest']['quest_id']), 'fields' => array('QuestsStat.stat_id', 'QuestsStat.amount'))); $completed = ''; if (empty($itemsNeeded) && empty($mobsNeeded)) { // Geen items nodig.. Omdat er op het moment niks anders is om te controleren updaten we deze quest... if ($turnIn == true && isset($character_id) && isset($quest_id)) { $charactersQuestsData[$i]['completed'] = 'finished'; } else { $charactersQuestsData[$i]['completed'] = 'yes'; } } else { $completed = 'yes'; // Default it's completed. $itemList = array(); $mobList = array(); foreach ($itemsNeeded as $item_id => $amount) { $itemList[] = $item_id; } foreach ($mobsNeeded as $mob_id => $amount) { $mobList[] = $mob_id; } // Er zijn items nodig voor deze quest.. Kijken of deze al gehaald zijn... // ItemsNeeded: item_id => aantal_needed $characterInventories = $Inventory->find('all', array('conditions' => array('Inventory.character_id' => $quest['CharactersQuest']['character_id'], 'Inventory.item_id' => $itemList), 'fields' => array('Inventory.item_id', 'COUNT(Inventory.item_id) as amount'), 'group' => array('Inventory.item_id'))); // Er zijn mobs nodig voor deze quest. Kijken of ze gekilled zijn NADAT de quest is geaccepteerd... $characterKills = $Kill->find('all', array('conditions' => array('Kill.character_id' => $quest['CharactersQuest']['character_id'], 'Kill.mob_id' => $mobList, 'Kill.type' => 'mob', 'Kill.created >=' => $quest['CharactersQuest']['created']), 'fields' => array('Kill.mob_id', 'COUNT(Kill.target_id) as amount'), 'group' => array('Kill.target_id'))); // We hebben een lijst met items wat nodig is.. // En dit wordt een lijst met wat we hebben... $itemsHave = array(); foreach ($characterInventories as $characterInventory) { $itemsHave[$characterInventory['Inventory']['item_id']] = $characterInventory[0]['amount']; } // Opslaan yes/no of de quest compleet is... foreach ($itemsNeeded as $item_id => $amount) { if (!isset($itemsHave[$item_id]) || isset($itemsHave[$item_id]) && $itemsHave[$item_id] < $itemsNeeded[$item_id]) { $completed = 'no'; } } // We hebben nu een lijst met mobs die nodig zijn, en een lijst met kills $mobsHave = array(); foreach ($characterKills as $characterKill) { $mobsHave[$characterKill['Kill']['mob_id']] = $characterKill[0]['amount']; } // Opslaan yes/no of de quest compleet is... foreach ($mobsNeeded as $mob_id => $amount) { if (!isset($mobsHave[$mob_id]) || isset($mobsHave[$mob_id]) && $mobsHave[$mob_id] < $mobsNeeded[$mob_id]) { $completed = 'no'; } } // Maybe the character is turning in the quest... if ($completed == 'yes' && $turnIn == true && isset($character_id) && isset($quest_id)) { $completed = 'finished'; } // Als de quest 'finished' is, dan moeten eventuele items uit de inventory verwijderd worden... // Dat kan hier. if ($completed == 'finished' && !empty($itemsNeeded)) { foreach ($itemsNeeded as $item_id => $amount) { for ($j = 1; $j <= $amount; $j++) { $Inventory->deleteAll(array('Inventory.character_id' => $quest['CharactersQuest']['character_id'], 'Inventory.item_id' => $item_id)); } } } $charactersQuestsData[$i]['completed'] = $completed; } // En voor het mooi, natuurlijk ook even de rewards geven... if ($completed == 'finished' && !empty($itemsRewards)) { App::import('Model', 'Drop'); $Drop = new Drop(); foreach ($itemsRewards as $item_id => $amount) { for ($j = 1; $j <= $amount; $j++) { $data = array(); // Bagid en index opvragen $bagIndex = $Drop->hasFreeSpace($quest['CharactersQuest']['character_id'], $item_id, true); $data['character_id'] = $quest['CharactersQuest']['character_id']; $data['item_id'] = $item_id; $data['index'] = $bagIndex['index']; $data['bag_id'] = $bagIndex['bag_id']; $Inventory->create(); $Inventory->save($data); } } } if ($completed == 'finished' && !empty($statsRewards)) { App::import('Model', 'CharactersStat'); $CharactersStat = new CharactersStat(); foreach ($statsRewards as $stat_id => $amount) { $statData = array(); $statData['character_id'] = $quest['CharactersQuest']['character_id']; // Kijken of deze stat al in de database bestaat $someStat = $CharactersStat->find('first', array('conditions' => array('CharactersStat.stat_id' => $stat_id, 'CharactersStat.character_id' => $quest['CharactersQuest']['character_id']))); if (!empty($someStat)) { $statData['id'] = $someStat['CharactersStat']['id']; $statData['amount'] = $someStat['CharactersStat']['amount'] + $amount; } else { $statData['amount'] = $amount; $statData['stat_id'] = $stat_id; } $CharactersStat->create(); $CharactersStat->save($statData); } } $i++; } $CharactersQuest->saveAll($charactersQuestsData); } }