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;
}
Exemple #7
0
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();
            }
		}
	}
}