BattleEvent* BattleEvent::translateFromXML(QDomElement element) { QString ID = element.attributeNode("ID").value(); QDomElement typeElement = element.firstChildElement("type"); QString typeString = typeElement.attributeNode("value").value(); if (typeString != "BATTLE") throw ProjectException("The translation of a battle event should have type BATTLE instead of " + typeString + "."); Event::Trigger trigger = Event::NONE; QString triggerString = element.firstChildElement("trigger").attributeNode("value").value(); if (triggerString == "TOUCH") trigger = Event::TOUCH; else if (triggerString == "INTERACT") trigger = Event::INTERACT; else if (triggerString == "NONE") trigger = Event::NONE; BattleEvent *event = create(ID, trigger); Event::translateFromXML(element, event); QDomElement activationElement = element.firstChildElement("activation"); event->setActivation(activationElement.attributeNode("value").value().toInt()); return event; }
/** * This is called when a battle event is deleted. */ void EventSystem::battleEventDeleted(QString ID) { for (int i = 0; i < _battleEvents.size(); i++) { BattleEvent *it = _battleEvents.at(i); if (it->getName() == ID) _battleEvents.remove(i); } }
/** * Get battle event with specified name. */ BattleEvent* EventSystem::getBattleEvent(QString ID) const { if (ID == QString()) throw ProjectException("Cannot search for a battle event with an empty ID."); for (int i = 0; i < _battleEvents.size(); i++) { BattleEvent *it = _battleEvents.at(i); if (!!it && (it->getName() == ID)) return it; } return 0; }
/** * Remove battle event with name <i>name</i> from the system. */ void EventSystem::removeBattleEvent(QString name) { if (name == QString()) throw ProjectException("Cannot search for a battle event with an empty name."); for (int i = 0; i < _battleEvents.size(); i++) { BattleEvent *it = _battleEvents.at(i); if (!!it && (it->getName() == name)) { _battleEvents.remove(i); delete it; return; } } }
void BattleView::DrawExplosions(void) { PointerList<BattleEvent>::Walker *walker = new PointerList<BattleEvent>::Walker(m_activeEvents); while (walker->IsValid()) { BattleEvent *event = walker->GetObj(); if (event) { event->DrawExplosions(m_battleSurface); } walker->Next(); } delete walker; }
bool GUIBattle::onBattleStart(BattleEvent& be) { if (be.getEventType() == BATTLE_START) { auto& camSys = be.getCameraSystem(); const auto& pokemon = be.getBattler(); const auto& opponent = be.getOpponent(); auto& em = be.getEntityManager(); const auto& pokemonBc = em.getComponent<BattleComponent>(pokemon); const auto& opponentBc = em.getComponent<BattleComponent>(opponent); //TODO max hp venant des stats du fichier ini addHPBar(camSys, pokemonBc.hp, pokemonBc.hp, em, pokemon); addHPBar(camSys, opponentBc.hp, opponentBc.hp, em, opponent); } else { removeHPBar(be.getBattler()); removeHPBar(be.getOpponent()); } return true; }
void Battle::NextTurn() { std::queue<BattleEvent> events; std::sort(combatants.begin(), combatants.end(), [](Creature* a, Creature* b) { return a->GetAgility() > b->GetAgility(); }); for (auto com : combatants) { if (com->GetID() == "Player") { Dialogue targetSelection = Dialogue("Who?", {}); for (auto target : combatants) if (target->GetID() != "Player") targetSelection.AddChoice(target->GetName()); int choice = battleOptions.Activate(); switch (choice) { default: case 1: { int position = targetSelection.Activate(); for (int i = 0; i < position; i++) if (combatants[i]->GetID() == "Player") position++; Creature* target = combatants[position - 1]; events.push(BattleEvent(com, target, BattleEventType::ATTACK)); break; } case 2: { events.push(BattleEvent(com, nullptr, BattleEventType::DEFEND)); break; } } } else { Creature* player = *std::find_if(combatants.begin(), combatants.end(), [](Creature* a) { return a->GetID() == "Player"; }); events.push(BattleEvent(com, player, BattleEventType::ATTACK)); } } while (!events.empty()) { BattleEvent event = events.front(); switch (event.GetType()) { case BattleEventType::ATTACK: { auto a = combatants.begin(); auto b = combatants.end(); if (std::find(a, b, event.GetSource()) == b || std::find(a, b, event.GetTarget()) == b) break; std::cout << event.GetSource()->GetName() << " attacks " << event.GetTarget()->GetName() << " for " << event.Run() << " damage!" << std::endl; if (event.GetTarget()->GetHP() <= 0) Kill(event.GetTarget()); break; } case BattleEventType::DEFEND: std::cout << event.GetSource()->GetName() << " defends!\n"; break; default: break; } events.pop(); } }
void Battle::next_turn() { // Queue of battle events. Fastest combatants will be // at the start of the queue, and so will go first, // whereas slower ones will be at the back std::queue<BattleEvent> events; // Sort the combatants in agility order std::sort(combatants.begin(), combatants.end(), [](Creature* a, Creature* b) { return a->agility < b->agility; }); // Iterate over the combatants and decide what they should do, // before adding the action to the event queue. for(auto com : this->combatants) { if(com->id == "player") { // Create the target selection dialogue Dialogue targetSelection = Dialogue("Who?", {}); // Created every turn because some combatants may die for(auto target : this->combatants) { if(target->id != "player") { targetSelection.addChoice(target->name); } } // Ask the player for their action (attack or defend) int choice = this->battleOptions.activate(); switch(choice) { default: case 1: { // Player is attacking, so ask for the target. // Dialogue returns the number of the choice, but we // want the pointer that name corresponds to and so we // must look it up in the combatant vector Creature* target = this->combatants[targetSelection.activate()-1]; // Add the attack command to the event queue events.push(BattleEvent(com, target, BattleEventType::ATTACK)); break; } case 2: { // Player is defending, so do nothing events.push(BattleEvent(com, nullptr, BattleEventType::DEFEND)); break; } } } else { // Simple enemy AI where enemy constantly attacks player Creature* player = *std::find_if(this->combatants.begin(), this->combatants.end(), [](Creature* a) { return a->id == "player"; }); events.push(BattleEvent(com, player, BattleEventType::ATTACK)); } } // Take each event from the queue in turn and process them, // displaying the results while(!events.empty()) { // Take event from the front of the queue BattleEvent event = events.front(); switch(event.type) { case BattleEventType::ATTACK: { // The event can't be run if either the source or the // target were slain previously in this turn, so we // must check that they're valid first auto a = this->combatants.begin(); auto b = this->combatants.end(); if(std::find(a, b, event.source) == b || std::find(a, b, event.target) == b) { break; } std::cout << event.source->name << " attacks " << event.target->name << " for " << event.run() << " damage!\n"; // Delete slain enemies if(event.target->hp <= 0) { this->kill(event.target); } break; } case BattleEventType::DEFEND: std::cout << event.source->name << " defends!\n"; break; default: break; } events.pop(); } }
void BattleView::Process(void) { Assert(m_eventQueue); if(!m_eventQueue) return; PointerList<BattleEvent>::PointerListNode *eventNode = m_eventQueue->GetHeadNode(); while (eventNode) { BattleEvent * event = eventNode->GetObj(); Assert(event); BattleViewActor * actor = event->GetActor(); bool addEvent = true; bool isAfterAttack = IsAfterAttack(*event); PointerList<BattleEvent>::PointerListNode * activeNode = m_activeEvents->GetHeadNode(); while (activeNode) { if (isAfterAttack && (activeNode->GetObj()->GetType() == BATTLE_EVENT_TYPE_ATTACK) ) { addEvent = false; break; } if((event->GetType() == BATTLE_EVENT_TYPE_PLACEMENT) && (activeNode->GetObj()->GetType() != BATTLE_EVENT_TYPE_PLACEMENT)) { addEvent = false; break; } if(activeNode->GetObj()->GetActor() == actor) { addEvent = false; break; } activeNode = activeNode->GetNext(); } if(addEvent) { PointerList<BattleEvent>::PointerListNode *addNode = eventNode; eventNode = eventNode->GetNext(); m_eventQueue->Remove(addNode); m_activeEvents->AddTail(event); } else { eventNode = eventNode->GetNext(); } } if(m_activeEvents->GetCount() > 0) { m_walker->SetList(m_activeEvents); while (m_walker->IsValid()) { BattleEvent * event = m_walker->GetObj(); Assert(event); event->Process(); if (event->IsFinished()) { m_walker->Remove(); delete event; if (!IsProcessing() && (!g_theCurrentBattle || !g_theCurrentBattle->IsDone())) { g_gevManager->GotUserInput(); } } else { m_walker->Next(); } } } }