File: CExchangeController.cpp

package info (click to toggle)
vcmi 1.6.5%2Bdfsg-2
  • links: PTS, VCS
  • area: contrib
  • in suites: forky, sid, trixie
  • size: 32,060 kB
  • sloc: cpp: 238,971; python: 265; sh: 224; xml: 157; ansic: 78; objc: 61; makefile: 49
file content (124 lines) | stat: -rw-r--r-- 3,330 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/*
 * CExchangeController.cpp, part of VCMI engine
 *
 * Authors: listed in file AUTHORS in main folder
 *
 * License: GNU General Public License v2.0 or later
 * Full text of license available in license.txt file, in main folder
 *
 */
#include "StdInc.h"
#include "CExchangeController.h"

#include "../CPlayerInterface.h"

#include "../widgets/CGarrisonInt.h"

#include "../../CCallback.h"

#include "../lib/mapObjects/CGHeroInstance.h"

CExchangeController::CExchangeController(ObjectInstanceID hero1, ObjectInstanceID hero2)
	: left(LOCPLINT->cb->getHero(hero1))
	, right(LOCPLINT->cb->getHero(hero2))
{
}

void CExchangeController::swapArmy()
{
	auto getStacks = [](const CArmedInstance * source) -> std::vector<std::pair<SlotID, CStackInstance*>>
	{
		auto slots = source->Slots();
		return std::vector<std::pair<SlotID, CStackInstance*>>(slots.begin(), slots.end());
	};

	auto leftSlots = getStacks(left);
	auto rightSlots = getStacks(right);

	auto i = leftSlots.begin();
	auto j = rightSlots.begin();

	for(; i != leftSlots.end() && j != rightSlots.end(); i++, j++)
	{
		LOCPLINT->cb->swapCreatures(left, right, i->first, j->first);
	}

	if(i != leftSlots.end())
	{
		auto freeSlots = right->getFreeSlots();
		auto slot = freeSlots.begin();

		for(; i != leftSlots.end() && slot != freeSlots.end(); i++, slot++)
		{
			LOCPLINT->cb->swapCreatures(left, right, i->first, *slot);
		}
	}
	else if(j != rightSlots.end())
	{
		auto freeSlots = left->getFreeSlots();
		auto slot = freeSlots.begin();

		for(; j != rightSlots.end() && slot != freeSlots.end(); j++, slot++)
		{
			LOCPLINT->cb->swapCreatures(left, right, *slot, j->first);
		}
	}
}

void CExchangeController::moveArmy(bool leftToRight, std::optional<SlotID> heldSlot)
{
	const auto source = leftToRight ? left : right;
	const auto target = leftToRight ? right : left;

	if(!heldSlot.has_value())
	{
		auto weakestSlot = vstd::minElementByFun(source->Slots(),
			[](const std::pair<SlotID, CStackInstance*> & s) -> int
			{
				return s.second->getCreatureID().toCreature()->getAIValue();
			});
		heldSlot = weakestSlot->first;
	}
	
	if (source->getCreature(heldSlot.value()) == nullptr)
		return;

	LOCPLINT->cb->bulkMoveArmy(source->id, target->id, heldSlot.value());
}

void CExchangeController::moveStack(bool leftToRight, SlotID sourceSlot)
{
	const auto source = leftToRight ? left : right;
	const auto target = leftToRight ? right : left;
	auto creature = source->getCreature(sourceSlot);

	if(creature == nullptr)
		return;

	SlotID targetSlot = target->getSlotFor(creature);
	if(targetSlot.validSlot())
	{
		if(source->stacksCount() == 1 && source->needsLastStack())
		{
			LOCPLINT->cb->splitStack(source, target, sourceSlot, targetSlot,
				target->getStackCount(targetSlot) + source->getStackCount(sourceSlot) - 1);
		}
		else
		{
			LOCPLINT->cb->mergeOrSwapStacks(source, target, sourceSlot, targetSlot);
		}
	}
}

void CExchangeController::swapArtifacts(bool equipped, bool baclpack)
{
	LOCPLINT->cb->bulkMoveArtifacts(left->id, right->id, true, equipped, baclpack);
}

void CExchangeController::moveArtifacts(bool leftToRight, bool equipped, bool baclpack)
{
	const auto source = leftToRight ? left : right;
	const auto target = leftToRight ? right : left;

	LOCPLINT->cb->bulkMoveArtifacts(source->id, target->id, false, equipped, baclpack);
}