Explorar el Código

vcmi: make some CStack properties private

There is a getters for this properties already available
Konstantin P hace 2 años
padre
commit
b472c89276

+ 3 - 3
AI/BattleAI/BattleAI.cpp

@@ -102,7 +102,7 @@ BattleAction CBattleAI::activeStack( const CStack * stack )
 
 
 	try
 	try
 	{
 	{
-		if(stack->type->getId() == CreatureID::CATAPULT)
+		if(stack->creatureId() == CreatureID::CATAPULT)
 			return useCatapult(stack);
 			return useCatapult(stack);
 		if(stack->hasBonusOfType(Bonus::SIEGE_WEAPON) && stack->hasBonusOfType(Bonus::HEALER))
 		if(stack->hasBonusOfType(Bonus::SIEGE_WEAPON) && stack->hasBonusOfType(Bonus::HEALER))
 		{
 		{
@@ -420,7 +420,7 @@ BattleAction CBattleAI::useCatapult(const CStack * stack)
 	attack.aimToHex(targetHex);
 	attack.aimToHex(targetHex);
 	attack.actionType = EActionType::CATAPULT;
 	attack.actionType = EActionType::CATAPULT;
 	attack.side = side;
 	attack.side = side;
-	attack.stackNumber = stack->ID;
+	attack.stackNumber = stack->unitId();
 
 
 	movesSkippedByDefense = 0;
 	movesSkippedByDefense = 0;
 
 
@@ -815,7 +815,7 @@ std::optional<BattleAction> CBattleAI::considerFleeingOrSurrendering()
 	{
 	{
 		if(stack->alive())
 		if(stack->alive())
 		{
 		{
-			if(stack->side == bs.ourSide)
+			if(stack->unitSide() == bs.ourSide)
 				bs.ourStacks.push_back(stack);
 				bs.ourStacks.push_back(stack);
 			else
 			else
 			{
 			{

+ 1 - 1
AI/BattleAI/BattleAI.h

@@ -31,7 +31,7 @@ struct CurrentOffensivePotential
 	{
 	{
 		for(auto stack : cbc->battleGetStacks())
 		for(auto stack : cbc->battleGetStacks())
 		{
 		{
-			if(stack->side == side)
+			if(stack->unitSide() == side)
 				ourAttacks[stack] = PotentialTargets(stack);
 				ourAttacks[stack] = PotentialTargets(stack);
 			else
 			else
 				enemyAttacks[stack] = PotentialTargets(stack);
 				enemyAttacks[stack] = PotentialTargets(stack);

+ 1 - 1
AI/BattleAI/ThreatMap.cpp

@@ -30,7 +30,7 @@ ThreatMap::ThreatMap(const CStack *Endangered) : endangered(Endangered)
 	for(const CStack *enemy : getCbc()->battleGetStacks())
 	for(const CStack *enemy : getCbc()->battleGetStacks())
 	{
 	{
 		//Consider only stacks of different owner
 		//Consider only stacks of different owner
-		if(enemy->side == endangered->side)
+		if(enemy->unitSide() == endangered->unitSide())
 			continue;
 			continue;
 
 
 		//Look-up which tiles can be melee-attacked
 		//Look-up which tiles can be melee-attacked

+ 2 - 2
AI/StupidAI/StupidAI.cpp

@@ -95,7 +95,7 @@ BattleAction CStupidAI::activeStack( const CStack * stack )
 	ReachabilityInfo dists = cb->getReachability(stack);
 	ReachabilityInfo dists = cb->getReachability(stack);
 	std::vector<EnemyInfo> enemiesShootable, enemiesReachable, enemiesUnreachable;
 	std::vector<EnemyInfo> enemiesShootable, enemiesReachable, enemiesUnreachable;
 
 
-	if(stack->type->getId() == CreatureID::CATAPULT)
+	if(stack->creatureId() == CreatureID::CATAPULT)
 	{
 	{
 		BattleAction attack;
 		BattleAction attack;
 		static const std::vector<int> wallHexes = {50, 183, 182, 130, 78, 29, 12, 95};
 		static const std::vector<int> wallHexes = {50, 183, 182, 130, 78, 29, 12, 95};
@@ -103,7 +103,7 @@ BattleAction CStupidAI::activeStack( const CStack * stack )
 		attack.aimToHex(seletectedHex);
 		attack.aimToHex(seletectedHex);
 		attack.actionType = EActionType::CATAPULT;
 		attack.actionType = EActionType::CATAPULT;
 		attack.side = side;
 		attack.side = side;
-		attack.stackNumber = stack->ID;
+		attack.stackNumber = stack->unitId();
 
 
 		return attack;
 		return attack;
 	}
 	}

+ 1 - 1
client/CPlayerInterface.cpp

@@ -774,7 +774,7 @@ BattleAction CPlayerInterface::activeStack(const CStack * stack) //called when i
 {
 {
 	THREAD_CREATED_BY_CLIENT;
 	THREAD_CREATED_BY_CLIENT;
 	logGlobal->trace("Awaiting command for %s", stack->nodeName());
 	logGlobal->trace("Awaiting command for %s", stack->nodeName());
-	auto stackId = stack->ID;
+	auto stackId = stack->unitId();
 	auto stackName = stack->nodeName();
 	auto stackName = stack->nodeName();
 	if (autofightingAI)
 	if (autofightingAI)
 	{
 	{

+ 2 - 2
client/NetPacksClient.cpp

@@ -708,13 +708,13 @@ void ApplyClientNetPackVisitor::visitBattleSetActiveStack(BattleSetActiveStack &
 	PlayerColor playerToCall; //pack.player that will move activated stack
 	PlayerColor playerToCall; //pack.player that will move activated stack
 	if (activated->hasBonusOfType(Bonus::HYPNOTIZED))
 	if (activated->hasBonusOfType(Bonus::HYPNOTIZED))
 	{
 	{
-		playerToCall = (gs.curB->sides[0].color == activated->owner
+		playerToCall = (gs.curB->sides[0].color == activated->unitOwner()
 			? gs.curB->sides[1].color
 			? gs.curB->sides[1].color
 			: gs.curB->sides[0].color);
 			: gs.curB->sides[0].color);
 	}
 	}
 	else
 	else
 	{
 	{
-		playerToCall = activated->owner;
+		playerToCall = activated->unitOwner();
 	}
 	}
 
 
 	cl.startPlayerBattleAction(playerToCall);
 	cl.startPlayerBattleAction(playerToCall);

+ 1 - 1
client/battle/BattleActionsController.cpp

@@ -524,7 +524,7 @@ std::string BattleActionsController::actionGetStatusMessageBlocked(PossiblePlaye
 bool BattleActionsController::actionIsLegal(PossiblePlayerBattleAction action, BattleHex targetHex)
 bool BattleActionsController::actionIsLegal(PossiblePlayerBattleAction action, BattleHex targetHex)
 {
 {
 	const CStack * targetStack = getStackForHex(targetHex);
 	const CStack * targetStack = getStackForHex(targetHex);
-	bool targetStackOwned = targetStack && targetStack->owner == owner.curInt->playerID;
+	bool targetStackOwned = targetStack && targetStack->unitOwner() == owner.curInt->playerID;
 
 
 	switch (action.get())
 	switch (action.get())
 	{
 	{

+ 4 - 4
client/battle/BattleAnimationClasses.cpp

@@ -71,17 +71,17 @@ std::vector<BattleAnimation *> & BattleAnimation::pendingAnimations()
 
 
 std::shared_ptr<CreatureAnimation> BattleAnimation::stackAnimation(const CStack * stack) const
 std::shared_ptr<CreatureAnimation> BattleAnimation::stackAnimation(const CStack * stack) const
 {
 {
-	return owner.stacksController->stackAnimation[stack->ID];
+	return owner.stacksController->stackAnimation[stack->unitId()];
 }
 }
 
 
 bool BattleAnimation::stackFacingRight(const CStack * stack)
 bool BattleAnimation::stackFacingRight(const CStack * stack)
 {
 {
-	return owner.stacksController->stackFacingRight[stack->ID];
+	return owner.stacksController->stackFacingRight[stack->unitId()];
 }
 }
 
 
 void BattleAnimation::setStackFacingRight(const CStack * stack, bool facingRight)
 void BattleAnimation::setStackFacingRight(const CStack * stack, bool facingRight)
 {
 {
-	owner.stacksController->stackFacingRight[stack->ID] = facingRight;
+	owner.stacksController->stackFacingRight[stack->unitId()] = facingRight;
 }
 }
 
 
 BattleStackAnimation::BattleStackAnimation(BattleInterface & owner, const CStack * stack)
 BattleStackAnimation::BattleStackAnimation(BattleInterface & owner, const CStack * stack)
@@ -279,7 +279,7 @@ ECreatureAnimType MeleeAttackAnimation::selectGroup(bool multiAttack)
 		getForwardGroup  (multiAttack)
 		getForwardGroup  (multiAttack)
 	};
 	};
 
 
-	int revShiftattacker = (attackingStack->side == BattleSide::ATTACKER ? -1 : 1);
+	int revShiftattacker = (attackingStack->unitSide() == BattleSide::ATTACKER ? -1 : 1);
 
 
 	int mutPos = BattleHex::mutualPosition(attackingStackPosBeforeReturn, dest);
 	int mutPos = BattleHex::mutualPosition(attackingStackPosBeforeReturn, dest);
 	if(mutPos == -1 && attackingStack->doubleWide())
 	if(mutPos == -1 && attackingStack->doubleWide())

+ 5 - 5
client/battle/BattleFieldController.cpp

@@ -134,7 +134,7 @@ void BattleFieldController::renderBattlefield(Canvas & canvas)
 
 
 void BattleFieldController::showBackground(Canvas & canvas)
 void BattleFieldController::showBackground(Canvas & canvas)
 {
 {
-	if (owner.stacksController->getActiveStack() != nullptr ) //&& creAnims[stacksController->getActiveStack()->ID]->isIdle() //show everything with range
+	if (owner.stacksController->getActiveStack() != nullptr ) //&& creAnims[stacksController->getActiveStack()->unitId()]->isIdle() //show everything with range
 		showBackgroundImageWithHexes(canvas);
 		showBackgroundImageWithHexes(canvas);
 	else
 	else
 		showBackgroundImage(canvas);
 		showBackgroundImage(canvas);
@@ -540,7 +540,7 @@ BattleHex BattleFieldController::fromWhichHexAttack(BattleHex attackTarget)
 		case BattleHex::LEFT:
 		case BattleHex::LEFT:
 		case BattleHex::BOTTOM_LEFT:
 		case BattleHex::BOTTOM_LEFT:
 		{
 		{
-			if ( attacker->side == BattleSide::ATTACKER )
+			if ( attacker->unitSide() == BattleSide::ATTACKER )
 				return attackTarget.cloneInDirection(direction);
 				return attackTarget.cloneInDirection(direction);
 			else
 			else
 				return attackTarget.cloneInDirection(direction).cloneInDirection(BattleHex::LEFT);
 				return attackTarget.cloneInDirection(direction).cloneInDirection(BattleHex::LEFT);
@@ -550,7 +550,7 @@ BattleHex BattleFieldController::fromWhichHexAttack(BattleHex attackTarget)
 		case BattleHex::RIGHT:
 		case BattleHex::RIGHT:
 		case BattleHex::BOTTOM_RIGHT:
 		case BattleHex::BOTTOM_RIGHT:
 		{
 		{
-			if ( attacker->side == BattleSide::ATTACKER )
+			if ( attacker->unitSide() == BattleSide::ATTACKER )
 				return attackTarget.cloneInDirection(direction).cloneInDirection(BattleHex::RIGHT);
 				return attackTarget.cloneInDirection(direction).cloneInDirection(BattleHex::RIGHT);
 			else
 			else
 				return attackTarget.cloneInDirection(direction);
 				return attackTarget.cloneInDirection(direction);
@@ -558,7 +558,7 @@ BattleHex BattleFieldController::fromWhichHexAttack(BattleHex attackTarget)
 
 
 		case BattleHex::TOP:
 		case BattleHex::TOP:
 		{
 		{
-			if ( attacker->side == BattleSide::ATTACKER )
+			if ( attacker->unitSide() == BattleSide::ATTACKER )
 				return attackTarget.cloneInDirection(BattleHex::TOP_RIGHT);
 				return attackTarget.cloneInDirection(BattleHex::TOP_RIGHT);
 			else
 			else
 				return attackTarget.cloneInDirection(BattleHex::TOP_LEFT);
 				return attackTarget.cloneInDirection(BattleHex::TOP_LEFT);
@@ -566,7 +566,7 @@ BattleHex BattleFieldController::fromWhichHexAttack(BattleHex attackTarget)
 
 
 		case BattleHex::BOTTOM:
 		case BattleHex::BOTTOM:
 		{
 		{
-			if ( attacker->side == BattleSide::ATTACKER )
+			if ( attacker->unitSide() == BattleSide::ATTACKER )
 				return attackTarget.cloneInDirection(BattleHex::BOTTOM_RIGHT);
 				return attackTarget.cloneInDirection(BattleHex::BOTTOM_RIGHT);
 			else
 			else
 				return attackTarget.cloneInDirection(BattleHex::BOTTOM_LEFT);
 				return attackTarget.cloneInDirection(BattleHex::BOTTOM_LEFT);

+ 2 - 2
client/battle/BattleInterface.cpp

@@ -208,7 +208,7 @@ void BattleInterface::stacksAreAttacked(std::vector<StackAttackedInfo> attackedI
 
 
 	for(const StackAttackedInfo & attackedInfo : attackedInfos)
 	for(const StackAttackedInfo & attackedInfo : attackedInfos)
 	{
 	{
-		ui8 side = attackedInfo.defender->side;
+		ui8 side = attackedInfo.defender->unitSide();
 		killedBySide.at(side) += attackedInfo.amountKilled;
 		killedBySide.at(side) += attackedInfo.amountKilled;
 	}
 	}
 
 
@@ -288,7 +288,7 @@ const CGHeroInstance * BattleInterface::getActiveHero()
 		return nullptr;
 		return nullptr;
 	}
 	}
 
 
-	if(attacker->side == BattleSide::ATTACKER)
+	if(attacker->unitSide() == BattleSide::ATTACKER)
 	{
 	{
 		return attackingHeroInstance;
 		return attackingHeroInstance;
 	}
 	}

+ 4 - 4
client/battle/BattleInterfaceClasses.cpp

@@ -455,18 +455,18 @@ BattleResultWindow::BattleResultWindow(const BattleResult & br, CPlayerInterface
 			auto stacks = owner.cb->battleGetAllStacks();
 			auto stacks = owner.cb->battleGetAllStacks();
 			vstd::erase_if(stacks, [i](const CStack * stack) //erase stack of other side and not coming from garrison
 			vstd::erase_if(stacks, [i](const CStack * stack) //erase stack of other side and not coming from garrison
 			{
 			{
-				return stack->side != i || !stack->base;
+				return stack->unitSide() != i || !stack->base;
 			});
 			});
 
 
 			auto best = vstd::maxElementByFun(stacks, [](const CStack * stack)
 			auto best = vstd::maxElementByFun(stacks, [](const CStack * stack)
 			{
 			{
-				return stack->type->getAIValue();
+				return stack->unitType()->getAIValue();
 			});
 			});
 
 
 			if(best != stacks.end()) //should be always but to be safe...
 			if(best != stacks.end()) //should be always but to be safe...
 			{
 			{
-				icons.push_back(std::make_shared<CAnimImage>("TWCRPORT", (*best)->type->getIconIndex(), 0, xs[i], 38));
-				sideNames[i] = (*best)->type->getNamePluralTranslated();
+				icons.push_back(std::make_shared<CAnimImage>("TWCRPORT", (*best)->unitType()->getIconIndex(), 0, xs[i], 38));
+				sideNames[i] = (*best)->unitType()->getNamePluralTranslated();
 			}
 			}
 		}
 		}
 	}
 	}

+ 5 - 5
client/battle/BattleProjectileController.cpp

@@ -205,7 +205,7 @@ std::shared_ptr<CAnimation> BattleProjectileController::getProjectileImage(const
 
 
 void BattleProjectileController::emitStackProjectile(const CStack * stack)
 void BattleProjectileController::emitStackProjectile(const CStack * stack)
 {
 {
-	int stackID = stack ? stack->ID : -1;
+	int stackID = stack ? stack->unitId() : -1;
 
 
 	for (auto projectile : projectiles)
 	for (auto projectile : projectiles)
 	{
 	{
@@ -232,7 +232,7 @@ void BattleProjectileController::showProjectiles(Canvas & canvas)
 
 
 bool BattleProjectileController::hasActiveProjectile(const CStack * stack, bool emittedOnly) const
 bool BattleProjectileController::hasActiveProjectile(const CStack * stack, bool emittedOnly) const
 {
 {
-	int stackID = stack ? stack->ID : -1;
+	int stackID = stack ? stack->unitId() : -1;
 
 
 	for(auto const & instance : projectiles)
 	for(auto const & instance : projectiles)
 	{
 	{
@@ -294,7 +294,7 @@ void BattleProjectileController::createCatapultProjectile(const CStack * shooter
 	catapultProjectile->speed     = computeProjectileFlightTime(from, dest, AnimationControls::getCatapultSpeed());
 	catapultProjectile->speed     = computeProjectileFlightTime(from, dest, AnimationControls::getCatapultSpeed());
 	catapultProjectile->from      = from;
 	catapultProjectile->from      = from;
 	catapultProjectile->dest      = dest;
 	catapultProjectile->dest      = dest;
-	catapultProjectile->shooterID = shooter->ID;
+	catapultProjectile->shooterID = shooter->unitId();
 	catapultProjectile->playing   = false;
 	catapultProjectile->playing   = false;
 	catapultProjectile->frameProgress = 0.f;
 	catapultProjectile->frameProgress = 0.f;
 
 
@@ -333,7 +333,7 @@ void BattleProjectileController::createProjectile(const CStack * shooter, Point
 
 
 	projectile->from      = from;
 	projectile->from      = from;
 	projectile->dest      = dest;
 	projectile->dest      = dest;
-	projectile->shooterID = shooter->ID;
+	projectile->shooterID = shooter->unitId();
 	projectile->progress  = 0;
 	projectile->progress  = 0;
 	projectile->playing   = false;
 	projectile->playing   = false;
 
 
@@ -357,7 +357,7 @@ void BattleProjectileController::createSpellProjectile(const CStack * shooter, P
 		projectile->reverse       = from.x > dest.x;
 		projectile->reverse       = from.x > dest.x;
 		projectile->from          = from;
 		projectile->from          = from;
 		projectile->dest          = dest;
 		projectile->dest          = dest;
-		projectile->shooterID     = shooter ? shooter->ID : -1;
+		projectile->shooterID     = shooter ? shooter->unitId() : -1;
 		projectile->progress      = 0;
 		projectile->progress      = 0;
 		projectile->speed         = computeProjectileFlightTime(from, dest, AnimationControls::getProjectileSpeed());
 		projectile->speed         = computeProjectileFlightTime(from, dest, AnimationControls::getProjectileSpeed());
 		projectile->playing       = false;
 		projectile->playing       = false;

+ 43 - 43
client/battle/BattleStacksController.cpp

@@ -104,10 +104,10 @@ BattleStacksController::BattleStacksController(BattleInterface & owner):
 
 
 BattleHex BattleStacksController::getStackCurrentPosition(const CStack * stack) const
 BattleHex BattleStacksController::getStackCurrentPosition(const CStack * stack) const
 {
 {
-	if ( !stackAnimation.at(stack->ID)->isMoving())
+	if ( !stackAnimation.at(stack->unitId())->isMoving())
 		return stack->getPosition();
 		return stack->getPosition();
 
 
-	if (stack->hasBonusOfType(Bonus::FLYING) && stackAnimation.at(stack->ID)->getType() == ECreatureAnimType::MOVING )
+	if (stack->hasBonusOfType(Bonus::FLYING) && stackAnimation.at(stack->unitId())->getType() == ECreatureAnimType::MOVING )
 		return BattleHex::HEX_AFTER_ALL;
 		return BattleHex::HEX_AFTER_ALL;
 
 
 	for (auto & anim : currentAnimations)
 	for (auto & anim : currentAnimations)
@@ -131,14 +131,14 @@ void BattleStacksController::collectRenderableObjects(BattleRenderer & renderer)
 
 
 	for (auto stack : stacks)
 	for (auto stack : stacks)
 	{
 	{
-		if (stackAnimation.find(stack->ID) == stackAnimation.end()) //e.g. for summoned but not yet handled stacks
+		if (stackAnimation.find(stack->unitId()) == stackAnimation.end()) //e.g. for summoned but not yet handled stacks
 			continue;
 			continue;
 
 
 		//FIXME: hack to ignore ghost stacks
 		//FIXME: hack to ignore ghost stacks
-		if ((stackAnimation[stack->ID]->getType() == ECreatureAnimType::DEAD || stackAnimation[stack->ID]->getType() == ECreatureAnimType::HOLDING) && stack->isGhost())
+		if ((stackAnimation[stack->unitId()]->getType() == ECreatureAnimType::DEAD || stackAnimation[stack->unitId()]->getType() == ECreatureAnimType::HOLDING) && stack->isGhost())
 			continue;
 			continue;
 
 
-		auto layer = stackAnimation[stack->ID]->isDead() ? EBattleFieldLayer::CORPSES : EBattleFieldLayer::STACKS;
+		auto layer = stackAnimation[stack->unitId()]->isDead() ? EBattleFieldLayer::CORPSES : EBattleFieldLayer::STACKS;
 		auto location = getStackCurrentPosition(stack);
 		auto location = getStackCurrentPosition(stack);
 
 
 		renderer.insert(layer, location, [this, stack]( BattleRenderer::RendererRef renderer ){
 		renderer.insert(layer, location, [this, stack]( BattleRenderer::RendererRef renderer ){
@@ -159,13 +159,13 @@ void BattleStacksController::stackReset(const CStack * stack)
 	owner.checkForAnimations();
 	owner.checkForAnimations();
 
 
 	//reset orientation?
 	//reset orientation?
-	//stackFacingRight[stack->ID] = stack->side == BattleSide::ATTACKER;
+	//stackFacingRight[stack->unitId()] = stack->unitSide() == BattleSide::ATTACKER;
 
 
-	auto iter = stackAnimation.find(stack->ID);
+	auto iter = stackAnimation.find(stack->unitId());
 
 
 	if(iter == stackAnimation.end())
 	if(iter == stackAnimation.end())
 	{
 	{
-		logGlobal->error("Unit %d have no animation", stack->ID);
+		logGlobal->error("Unit %d have no animation", stack->unitId());
 		return;
 		return;
 	}
 	}
 
 
@@ -185,7 +185,7 @@ void BattleStacksController::stackAdded(const CStack * stack, bool instant)
 	// Tower shooters have only their upper half visible
 	// Tower shooters have only their upper half visible
 	static const int turretCreatureAnimationHeight = 232;
 	static const int turretCreatureAnimationHeight = 232;
 
 
-	stackFacingRight[stack->ID] = stack->side == BattleSide::ATTACKER; // must be set before getting stack position
+	stackFacingRight[stack->unitId()] = stack->unitSide() == BattleSide::ATTACKER; // must be set before getting stack position
 
 
 	Point coords = getStackPositionAtHex(stack->getPosition(), stack);
 	Point coords = getStackPositionAtHex(stack->getPosition(), stack);
 
 
@@ -195,26 +195,26 @@ void BattleStacksController::stackAdded(const CStack * stack, bool instant)
 
 
 		const CCreature *turretCreature = owner.siegeController->getTurretCreature();
 		const CCreature *turretCreature = owner.siegeController->getTurretCreature();
 
 
-		stackAnimation[stack->ID] = AnimationControls::getAnimation(turretCreature);
-		stackAnimation[stack->ID]->pos.h = turretCreatureAnimationHeight;
-		stackAnimation[stack->ID]->pos.w = stackAnimation[stack->ID]->getWidth();
+		stackAnimation[stack->unitId()] = AnimationControls::getAnimation(turretCreature);
+		stackAnimation[stack->unitId()]->pos.h = turretCreatureAnimationHeight;
+		stackAnimation[stack->unitId()]->pos.w = stackAnimation[stack->unitId()]->getWidth();
 
 
 		// FIXME: workaround for visible animation of Medusa tails (animation disabled in H3)
 		// FIXME: workaround for visible animation of Medusa tails (animation disabled in H3)
 		if (turretCreature->getId() == CreatureID::MEDUSA )
 		if (turretCreature->getId() == CreatureID::MEDUSA )
-			stackAnimation[stack->ID]->pos.w = 250;
+			stackAnimation[stack->unitId()]->pos.w = 250;
 
 
 		coords = owner.siegeController->getTurretCreaturePosition(stack->initialPosition);
 		coords = owner.siegeController->getTurretCreaturePosition(stack->initialPosition);
 	}
 	}
 	else
 	else
 	{
 	{
-		stackAnimation[stack->ID] = AnimationControls::getAnimation(stack->unitType());
-		stackAnimation[stack->ID]->onAnimationReset += std::bind(&onAnimationFinished, stack, stackAnimation[stack->ID]);
-		stackAnimation[stack->ID]->pos.h = stackAnimation[stack->ID]->getHeight();
-		stackAnimation[stack->ID]->pos.w = stackAnimation[stack->ID]->getWidth();
+		stackAnimation[stack->unitId()] = AnimationControls::getAnimation(stack->unitType());
+		stackAnimation[stack->unitId()]->onAnimationReset += std::bind(&onAnimationFinished, stack, stackAnimation[stack->unitId()]);
+		stackAnimation[stack->unitId()]->pos.h = stackAnimation[stack->unitId()]->getHeight();
+		stackAnimation[stack->unitId()]->pos.w = stackAnimation[stack->unitId()]->getWidth();
 	}
 	}
-	stackAnimation[stack->ID]->pos.x = coords.x;
-	stackAnimation[stack->ID]->pos.y = coords.y;
-	stackAnimation[stack->ID]->setType(ECreatureAnimType::HOLDING);
+	stackAnimation[stack->unitId()]->pos.x = coords.x;
+	stackAnimation[stack->unitId()]->pos.y = coords.y;
+	stackAnimation[stack->unitId()]->setType(ECreatureAnimType::HOLDING);
 
 
 	if (!instant)
 	if (!instant)
 	{
 	{
@@ -234,12 +234,12 @@ void BattleStacksController::stackAdded(const CStack * stack, bool instant)
 void BattleStacksController::setActiveStack(const CStack *stack)
 void BattleStacksController::setActiveStack(const CStack *stack)
 {
 {
 	if (activeStack) // update UI
 	if (activeStack) // update UI
-		stackAnimation[activeStack->ID]->setBorderColor(AnimationControls::getNoBorder());
+		stackAnimation[activeStack->unitId()]->setBorderColor(AnimationControls::getNoBorder());
 
 
 	activeStack = stack;
 	activeStack = stack;
 
 
 	if (activeStack) // update UI
 	if (activeStack) // update UI
-		stackAnimation[activeStack->ID]->setBorderColor(AnimationControls::getGoldBorder());
+		stackAnimation[activeStack->unitId()]->setBorderColor(AnimationControls::getGoldBorder());
 
 
 	owner.windowObject->blockUI(activeStack == nullptr);
 	owner.windowObject->blockUI(activeStack == nullptr);
 }
 }
@@ -258,7 +258,7 @@ bool BattleStacksController::stackNeedsAmountBox(const CStack * stack) const
 		return false;
 		return false;
 
 
 	// if stack has any ongoing animation - hide the box
 	// if stack has any ongoing animation - hide the box
-	if (stackAmountBoxHidden.count(stack->ID))
+	if (stackAmountBoxHidden.count(stack->unitId()))
 		return false;
 		return false;
 
 
 	return true;
 	return true;
@@ -291,7 +291,7 @@ void BattleStacksController::showStackAmountBox(Canvas & canvas, const CStack *
 
 
 	bool doubleWide = stack->doubleWide();
 	bool doubleWide = stack->doubleWide();
 	bool turnedRight = facingRight(stack);
 	bool turnedRight = facingRight(stack);
-	bool attacker = stack->side == BattleSide::ATTACKER;
+	bool attacker = stack->unitSide() == BattleSide::ATTACKER;
 
 
 	BattleHex stackPos = stack->getPosition();
 	BattleHex stackPos = stack->getPosition();
 
 
@@ -334,8 +334,8 @@ void BattleStacksController::showStack(Canvas & canvas, const CStack * stack)
 			fullFilter = ColorFilter::genCombined(fullFilter, filter.effect);
 			fullFilter = ColorFilter::genCombined(fullFilter, filter.effect);
 	}
 	}
 
 
-	stackAnimation[stack->ID]->nextFrame(canvas, fullFilter, facingRight(stack)); // do actual blit
-	stackAnimation[stack->ID]->incrementFrame(float(GH.mainFPSmng->getElapsedMilliseconds()) / 1000);
+	stackAnimation[stack->unitId()]->nextFrame(canvas, fullFilter, facingRight(stack)); // do actual blit
+	stackAnimation[stack->unitId()]->incrementFrame(float(GH.mainFPSmng->getElapsedMilliseconds()) / 1000);
 }
 }
 
 
 void BattleStacksController::update()
 void BattleStacksController::update()
@@ -390,17 +390,17 @@ void BattleStacksController::addNewAnim(BattleAnimation *anim)
 
 
 	auto stackAnimation = dynamic_cast<BattleStackAnimation*>(anim);
 	auto stackAnimation = dynamic_cast<BattleStackAnimation*>(anim);
 	if(stackAnimation)
 	if(stackAnimation)
-		stackAmountBoxHidden.insert(stackAnimation->stack->ID);
+		stackAmountBoxHidden.insert(stackAnimation->stack->unitId());
 }
 }
 
 
 void BattleStacksController::stackRemoved(uint32_t stackID)
 void BattleStacksController::stackRemoved(uint32_t stackID)
 {
 {
-	if (getActiveStack() && getActiveStack()->ID == stackID)
+	if (getActiveStack() && getActiveStack()->unitId() == stackID)
 	{
 	{
 		BattleAction *action = new BattleAction();
 		BattleAction *action = new BattleAction();
 		action->side = owner.defendingHeroInstance ? (owner.curInt->playerID == owner.defendingHeroInstance->tempOwner) : false;
 		action->side = owner.defendingHeroInstance ? (owner.curInt->playerID == owner.defendingHeroInstance->tempOwner) : false;
 		action->actionType = EActionType::CANCEL;
 		action->actionType = EActionType::CANCEL;
-		action->stackNumber = getActiveStack()->ID;
+		action->stackNumber = getActiveStack()->unitId();
 		owner.givenCommand.setn(action);
 		owner.givenCommand.setn(action);
 		setActiveStack(nullptr);
 		setActiveStack(nullptr);
 	}
 	}
@@ -431,7 +431,7 @@ void BattleStacksController::stacksAreAttacked(std::vector<StackAttackedInfo> at
 
 
 		// FIXME: this check is better, however not usable since stacksAreAttacked is called after net pack is applyed - petrification is already removed
 		// FIXME: this check is better, however not usable since stacksAreAttacked is called after net pack is applyed - petrification is already removed
 		// if (needsReverse && !attackedInfo.defender->isFrozen())
 		// if (needsReverse && !attackedInfo.defender->isFrozen())
-		if (needsReverse && stackAnimation[attackedInfo.defender->ID]->getType() != ECreatureAnimType::FROZEN)
+		if (needsReverse && stackAnimation[attackedInfo.defender->unitId()]->getType() != ECreatureAnimType::FROZEN)
 		{
 		{
 			owner.addToAnimationStage(EAnimationEvents::MOVEMENT, [=]()
 			owner.addToAnimationStage(EAnimationEvents::MOVEMENT, [=]()
 			{
 			{
@@ -485,7 +485,7 @@ void BattleStacksController::stacksAreAttacked(std::vector<StackAttackedInfo> at
 		{
 		{
 			owner.addToAnimationStage(EAnimationEvents::AFTER_HIT, [=](){
 			owner.addToAnimationStage(EAnimationEvents::AFTER_HIT, [=](){
 				addNewAnim(new ColorTransformAnimation(owner, attackedInfo.defender, "summonFadeOut", nullptr));
 				addNewAnim(new ColorTransformAnimation(owner, attackedInfo.defender, "summonFadeOut", nullptr));
-				stackRemoved(attackedInfo.defender->ID);
+				stackRemoved(attackedInfo.defender->unitId());
 			});
 			});
 		}
 		}
 	}
 	}
@@ -503,7 +503,7 @@ void BattleStacksController::stackTeleported(const CStack *stack, std::vector<Ba
 	});
 	});
 
 
 	owner.addToAnimationStage(EAnimationEvents::AFTER_HIT, [=](){
 	owner.addToAnimationStage(EAnimationEvents::AFTER_HIT, [=](){
-		stackAnimation[stack->ID]->pos.moveTo(getStackPositionAtHex(destHex.back(), stack));
+		stackAnimation[stack->unitId()]->pos.moveTo(getStackPositionAtHex(destHex.back(), stack));
 		addNewAnim( new ColorTransformAnimation(owner, stack, "teleportFadeIn", nullptr) );
 		addNewAnim( new ColorTransformAnimation(owner, stack, "teleportFadeIn", nullptr) );
 	});
 	});
 
 
@@ -551,7 +551,7 @@ bool BattleStacksController::shouldAttackFacingRight(const CStack * attacker, co
 				attacker,
 				attacker,
 				defender);
 				defender);
 
 
-	if (attacker->side == BattleSide::ATTACKER)
+	if (attacker->unitSide() == BattleSide::ATTACKER)
 		return !mustReverse;
 		return !mustReverse;
 	else
 	else
 		return mustReverse;
 		return mustReverse;
@@ -669,9 +669,9 @@ void BattleStacksController::endAction(const BattleAction* action)
 
 
 	for (const CStack *s : stacks)
 	for (const CStack *s : stacks)
 	{
 	{
-		bool shouldFaceRight  = s && s->side == BattleSide::ATTACKER;
+		bool shouldFaceRight  = s && s->unitSide() == BattleSide::ATTACKER;
 
 
-		if (s && facingRight(s) != shouldFaceRight && s->alive() && stackAnimation[s->ID]->isIdle())
+		if (s && facingRight(s) != shouldFaceRight && s->alive() && stackAnimation[s->unitId()]->isIdle())
 		{
 		{
 			addNewAnim(new ReverseAnimation(owner, s, s->getPosition()));
 			addNewAnim(new ReverseAnimation(owner, s, s->getPosition()));
 		}
 		}
@@ -715,7 +715,7 @@ void BattleStacksController::activateStack()
 	if ( !stackToActivate)
 	if ( !stackToActivate)
 		return;
 		return;
 
 
-	owner.trySetActivePlayer(stackToActivate->owner);
+	owner.trySetActivePlayer(stackToActivate->unitOwner());
 
 
 	setActiveStack(stackToActivate);
 	setActiveStack(stackToActivate);
 	stackToActivate = nullptr;
 	stackToActivate = nullptr;
@@ -732,7 +732,7 @@ const CStack* BattleStacksController::getActiveStack() const
 
 
 bool BattleStacksController::facingRight(const CStack * stack) const
 bool BattleStacksController::facingRight(const CStack * stack) const
 {
 {
-	return stackFacingRight.at(stack->ID);
+	return stackFacingRight.at(stack->unitId());
 }
 }
 
 
 Point BattleStacksController::getStackPositionAtHex(BattleHex hexNum, const CStack * stack) const
 Point BattleStacksController::getStackPositionAtHex(BattleHex hexNum, const CStack * stack) const
@@ -757,7 +757,7 @@ Point BattleStacksController::getStackPositionAtHex(BattleHex hexNum, const CSta
 		//shifting position for double - hex creatures
 		//shifting position for double - hex creatures
 		if(stack->doubleWide())
 		if(stack->doubleWide())
 		{
 		{
-			if(stack->side == BattleSide::ATTACKER)
+			if(stack->unitSide() == BattleSide::ATTACKER)
 			{
 			{
 				if(facingRight(stack))
 				if(facingRight(stack))
 					ret.x -= 44;
 					ret.x -= 44;
@@ -812,9 +812,9 @@ void BattleStacksController::updateHoveredStacks()
 			continue;
 			continue;
 
 
 		if (stack == activeStack)
 		if (stack == activeStack)
-			stackAnimation[stack->ID]->setBorderColor(AnimationControls::getGoldBorder());
+			stackAnimation[stack->unitId()]->setBorderColor(AnimationControls::getGoldBorder());
 		else
 		else
-			stackAnimation[stack->ID]->setBorderColor(AnimationControls::getNoBorder());
+			stackAnimation[stack->unitId()]->setBorderColor(AnimationControls::getNoBorder());
 	}
 	}
 
 
 	for(const auto * stack : newStacks)
 	for(const auto * stack : newStacks)
@@ -822,9 +822,9 @@ void BattleStacksController::updateHoveredStacks()
 		if (vstd::contains(mouseHoveredStacks, stack))
 		if (vstd::contains(mouseHoveredStacks, stack))
 			continue;
 			continue;
 
 
-		stackAnimation[stack->ID]->setBorderColor(AnimationControls::getBlueBorder());
-		if (stackAnimation[stack->ID]->framesInGroup(ECreatureAnimType::MOUSEON) > 0 && stack->alive() && !stack->isFrozen())
-			stackAnimation[stack->ID]->playOnce(ECreatureAnimType::MOUSEON);
+		stackAnimation[stack->unitId()]->setBorderColor(AnimationControls::getBlueBorder());
+		if (stackAnimation[stack->unitId()]->framesInGroup(ECreatureAnimType::MOUSEON) > 0 && stack->alive() && !stack->isFrozen())
+			stackAnimation[stack->unitId()]->playOnce(ECreatureAnimType::MOUSEON);
 	}
 	}
 
 
 	mouseHoveredStacks = newStacks;
 	mouseHoveredStacks = newStacks;

+ 1 - 1
client/windows/CCreatureWindow.cpp

@@ -651,7 +651,7 @@ CStackWindow::CStackWindow(const CStack * stack, bool popup)
 {
 {
 	info->stack = stack;
 	info->stack = stack;
 	info->stackNode = stack->base;
 	info->stackNode = stack->base;
-	info->creature = stack->type;
+	info->creature = stack->unitType();
 	info->creatureCount = stack->getCount();
 	info->creatureCount = stack->getCount();
 	info->popupWindow = popup;
 	info->popupWindow = popup;
 	init();
 	init();

+ 1 - 1
lib/CGameInterface.cpp

@@ -156,7 +156,7 @@ BattleAction CGlobalAI::activeStack(const CStack * stack)
 {
 {
 	BattleAction ba;
 	BattleAction ba;
 	ba.actionType = EActionType::DEFEND;
 	ba.actionType = EActionType::DEFEND;
-	ba.stackNumber = stack->ID;
+	ba.stackNumber = stack->unitId();
 	return ba;
 	return ba;
 }
 }
 
 

+ 1 - 1
lib/CStack.cpp

@@ -28,7 +28,7 @@ CStack::CStack(const CStackInstance * Base, const PlayerColor & O, int I, ui8 Si
 	base(Base),
 	base(Base),
 	ID(I),
 	ID(I),
 	type(Base->type),
 	type(Base->type),
-	baseAmount(base->count),
+	baseAmount(Base->count),
 	owner(O),
 	owner(O),
 	slot(S),
 	slot(S),
 	side(Side)
 	side(Side)

+ 7 - 4
lib/CStack.h

@@ -25,17 +25,20 @@ class BattleInfo;
 //Represents STACK_BATTLE nodes
 //Represents STACK_BATTLE nodes
 class DLL_LINKAGE CStack : public CBonusSystemNode, public battle::CUnitState, public battle::IUnitEnvironment
 class DLL_LINKAGE CStack : public CBonusSystemNode, public battle::CUnitState, public battle::IUnitEnvironment
 {
 {
-public:
-	const CStackInstance * base = nullptr; //garrison slot from which stack originates (nullptr for war machines, summoned cres, etc)
-
+private:
 	ui32 ID = -1; //unique ID of stack
 	ui32 ID = -1; //unique ID of stack
 	const CCreature * type = nullptr;
 	const CCreature * type = nullptr;
 	TerrainId nativeTerrain; //tmp variable to save native terrain value on battle init
 	TerrainId nativeTerrain; //tmp variable to save native terrain value on battle init
 	ui32 baseAmount = -1;
 	ui32 baseAmount = -1;
 
 
 	PlayerColor owner; //owner - player color (255 for neutrals)
 	PlayerColor owner; //owner - player color (255 for neutrals)
-	SlotID slot;  //slot - position in garrison (may be 255 for neutrals/called creatures)
 	ui8 side = 1;
 	ui8 side = 1;
+
+	SlotID slot;  //slot - position in garrison (may be 255 for neutrals/called creatures)
+
+public:
+	const CStackInstance * base = nullptr; //garrison slot from which stack originates (nullptr for war machines, summoned cres, etc)
+	
 	BattleHex initialPosition; //position on battlefield; -2 - keep, -3 - lower tower, -4 - upper tower
 	BattleHex initialPosition; //position on battlefield; -2 - keep, -3 - lower tower, -4 - upper tower
 
 
 	CStack(const CStackInstance * base, const PlayerColor & O, int I, ui8 Side, const SlotID & S);
 	CStack(const CStackInstance * base, const PlayerColor & O, int I, ui8 Side, const SlotID & S);

+ 2 - 2
lib/HeroBonus.cpp

@@ -2047,7 +2047,7 @@ const CCreature * retrieveCreature(const CBonusSystemNode *node)
 	case CBonusSystemNode::CREATURE:
 	case CBonusSystemNode::CREATURE:
 		return (dynamic_cast<const CCreature *>(node));
 		return (dynamic_cast<const CCreature *>(node));
 	case CBonusSystemNode::STACK_BATTLE:
 	case CBonusSystemNode::STACK_BATTLE:
-		return (dynamic_cast<const CStack *>(node))->type;
+		return (dynamic_cast<const CStack *>(node))->unitType();
 	default:
 	default:
 		const CStackInstance * csi = retrieveStackInstance(node);
 		const CStackInstance * csi = retrieveStackInstance(node);
 		if(csi)
 		if(csi)
@@ -2749,7 +2749,7 @@ std::shared_ptr<Bonus> TimesStackLevelUpdater::createUpdatedBonus(const std::sha
 		//otherwise we'd end up multiplying twice
 		//otherwise we'd end up multiplying twice
 		if(stack.base == nullptr)
 		if(stack.base == nullptr)
 		{
 		{
-			int level = stack.type->getLevel();
+			int level = stack.unitType()->getLevel();
 			std::shared_ptr<Bonus> newBonus = std::make_shared<Bonus>(*b);
 			std::shared_ptr<Bonus> newBonus = std::make_shared<Bonus>(*b);
 			newBonus->val *= level;
 			newBonus->val *= level;
 			return newBonus;
 			return newBonus;

+ 1 - 1
lib/NetPacksLib.cpp

@@ -2467,7 +2467,7 @@ void BattleSetStackProperty::applyGs(CGameState * gs) const
 		}
 		}
 		case ENCHANTER_COUNTER:
 		case ENCHANTER_COUNTER:
 		{
 		{
-			auto & counter = gs->curB->sides[gs->curB->whatSide(stack->owner)].enchanterCounter;
+			auto & counter = gs->curB->sides[gs->curB->whatSide(stack->unitOwner())].enchanterCounter;
 			if(absolute)
 			if(absolute)
 				counter = val;
 				counter = val;
 			else
 			else

+ 2 - 3
lib/battle/BattleInfo.cpp

@@ -47,12 +47,11 @@ std::pair< std::vector<BattleHex>, int > BattleInfo::getPath(BattleHex start, Ba
 
 
 void BattleInfo::calculateCasualties(std::map<ui32,si32> * casualties) const
 void BattleInfo::calculateCasualties(std::map<ui32,si32> * casualties) const
 {
 {
-	for(const auto & elem : stacks) //setting casualties
+	for(const auto & st : stacks) //setting casualties
 	{
 	{
-		const CStack * const st = elem;
 		si32 killed = st->getKilled();
 		si32 killed = st->getKilled();
 		if(killed > 0)
 		if(killed > 0)
-			casualties[st->side][st->unitType()->getId()] += killed;
+			casualties[st->unitSide()][st->creatureId()] += killed;
 	}
 	}
 }
 }
 
 

+ 3 - 3
lib/battle/CBattleInfoCallback.cpp

@@ -1367,7 +1367,7 @@ std::set<const CStack*> CBattleInfoCallback::getAttackedCreatures(const CStack*
 	for (BattleHex tile : at.hostileCreaturePositions) //all around & three-headed attack
 	for (BattleHex tile : at.hostileCreaturePositions) //all around & three-headed attack
 	{
 	{
 		const CStack * st = battleGetStackByPos(tile, true);
 		const CStack * st = battleGetStackByPos(tile, true);
-		if(st && st->owner != attacker->owner) //only hostile stacks - does it work well with Berserk?
+		if(st && st->unitOwner() != attacker->unitOwner()) //only hostile stacks - does it work well with Berserk?
 		{
 		{
 			attackedCres.insert(st);
 			attackedCres.insert(st);
 		}
 		}
@@ -1623,7 +1623,7 @@ SpellID CBattleInfoCallback::getRandomBeneficialSpell(CRandomGenerator & rand, c
 	{
 	{
 		auto stacks = battleGetStacksIf([=](const CStack * stack)
 		auto stacks = battleGetStacksIf([=](const CStack * stack)
 		{
 		{
-			return pred(stack) && stack->owner != subject->owner && stack->isValidTarget(false);
+			return pred(stack) && stack->unitOwner() != subject->unitOwner() && stack->isValidTarget(false);
 		});
 		});
 
 
 		if(stacks.empty())
 		if(stacks.empty())
@@ -1673,7 +1673,7 @@ SpellID CBattleInfoCallback::getRandomBeneficialSpell(CRandomGenerator & rand, c
 		case SpellID::PROTECTION_FROM_FIRE:
 		case SpellID::PROTECTION_FROM_FIRE:
 		case SpellID::PROTECTION_FROM_WATER:
 		case SpellID::PROTECTION_FROM_WATER:
 		{
 		{
-			const ui8 enemySide = 1 - subject->side;
+			const ui8 enemySide = 1 - subject->unitSide();
 			//todo: only if enemy has spellbook
 			//todo: only if enemy has spellbook
 			if (!battleHasHero(enemySide)) //only if there is enemy hero
 			if (!battleHasHero(enemySide)) //only if there is enemy hero
 				continue;
 				continue;

+ 2 - 2
lib/battle/CBattleInfoEssentials.cpp

@@ -87,7 +87,7 @@ bool CBattleInfoEssentials::battleHasNativeStack(ui8 side) const
 
 
 	for(const auto * s : battleGetAllStacks())
 	for(const auto * s : battleGetAllStacks())
 	{
 	{
-		if(s->side == side && s->isNativeTerrain(getBattle()->getTerrainType()))
+		if(s->unitSide() == side && s->isNativeTerrain(getBattle()->getTerrainType()))
 			return true;
 			return true;
 	}
 	}
 
 
@@ -173,7 +173,7 @@ const CStack* CBattleInfoEssentials::battleGetStackByID(int ID, bool onlyAlive)
 
 
 	auto stacks = battleGetStacksIf([=](const CStack * s)
 	auto stacks = battleGetStacksIf([=](const CStack * s)
 	{
 	{
-		return s->ID == ID && (!onlyAlive || s->alive());
+		return s->unitId() == ID && (!onlyAlive || s->alive());
 	});
 	});
 
 
 	if(stacks.empty())
 	if(stacks.empty())

+ 2 - 2
lib/battle/CPlayerBattleCallback.cpp

@@ -30,8 +30,8 @@ TStacks CPlayerBattleCallback::battleGetStacks(EStackOwnership whose, bool onlyA
 
 
 	return battleGetStacksIf([=](const CStack * s){
 	return battleGetStacksIf([=](const CStack * s){
 		const bool ownerMatches = (whose == MINE_AND_ENEMY)
 		const bool ownerMatches = (whose == MINE_AND_ENEMY)
-								|| (whose == ONLY_MINE && s->owner == player)
-								|| (whose == ONLY_ENEMY && s->owner != player);
+								|| (whose == ONLY_MINE && s->unitOwner() == player)
+								|| (whose == ONLY_ENEMY && s->unitOwner() != player);
 
 
 		return ownerMatches && s->isValidTarget(!onlyAlive);
 		return ownerMatches && s->isValidTarget(!onlyAlive);
 	});
 	});

+ 2 - 2
lib/spells/BattleSpellMechanics.cpp

@@ -279,9 +279,9 @@ void BattleSpellMechanics::cast(ServerCallback * server, const Target & target)
 		if(nullptr != otherHero) //handle mana channel
 		if(nullptr != otherHero) //handle mana channel
 		{
 		{
 			int manaChannel = 0;
 			int manaChannel = 0;
-			for(const CStack * stack : battle()->battleGetAllStacks(true)) //TODO: shouldn't bonus system handle it somehow?
+			for(const auto * stack : battle()->battleGetAllStacks(true)) //TODO: shouldn't bonus system handle it somehow?
 			{
 			{
-				if(stack->owner == otherHero->tempOwner)
+				if(stack->unitOwner() == otherHero->tempOwner)
 				{
 				{
 					vstd::amax(manaChannel, stack->valOfBonuses(Bonus::MANA_CHANNELING));
 					vstd::amax(manaChannel, stack->valOfBonuses(Bonus::MANA_CHANNELING));
 				}
 				}

+ 54 - 54
server/CGameHandler.cpp

@@ -951,7 +951,7 @@ void CGameHandler::makeAttack(const CStack * attacker, const CStack * defender,
 		bat.flags |= BattleAttack::DEATH_BLOW;
 		bat.flags |= BattleAttack::DEATH_BLOW;
 	}
 	}
 
 
-	const auto * owner = gs->curB->getHero(attacker->owner);
+	const auto * owner = gs->curB->getHero(attacker->unitOwner());
 	if(owner)
 	if(owner)
 	{
 	{
 		int chance = owner->valOfBonuses(Bonus::BONUS_DAMAGE_CHANCE, attacker->creatureIndex());
 		int chance = owner->valOfBonuses(Bonus::BONUS_DAMAGE_CHANCE, attacker->creatureIndex());
@@ -1005,7 +1005,7 @@ void CGameHandler::makeAttack(const CStack * attacker, const CStack * defender,
 		//now add effect info for all attacked stacks
 		//now add effect info for all attacked stacks
 		for (BattleStackAttacked & bsa : bat.bsa)
 		for (BattleStackAttacked & bsa : bat.bsa)
 		{
 		{
-			if (bsa.attackerID == attacker->ID) //this is our attack and not f.e. fire shield
+			if (bsa.attackerID == attacker->unitId()) //this is our attack and not f.e. fire shield
 			{
 			{
 				//this is need for displaying affect animation
 				//this is need for displaying affect animation
 				bsa.flags |= BattleStackAttacked::SPELL_EFFECT;
 				bsa.flags |= BattleStackAttacked::SPELL_EFFECT;
@@ -1072,7 +1072,7 @@ void CGameHandler::makeAttack(const CStack * attacker, const CStack * defender,
 			const CStack * actor = item.first;
 			const CStack * actor = item.first;
 			int64_t rawDamage = item.second;
 			int64_t rawDamage = item.second;
 
 
-			const CGHeroInstance * actorOwner = gs->curB->getHero(actor->owner);
+			const CGHeroInstance * actorOwner = gs->curB->getHero(actor->unitOwner());
 
 
 			if(actorOwner)
 			if(actorOwner)
 			{
 			{
@@ -1092,8 +1092,8 @@ void CGameHandler::makeAttack(const CStack * attacker, const CStack * defender,
 			BattleStackAttacked bsa;
 			BattleStackAttacked bsa;
 
 
 			bsa.flags |= BattleStackAttacked::FIRE_SHIELD;
 			bsa.flags |= BattleStackAttacked::FIRE_SHIELD;
-			bsa.stackAttacked = attacker->ID; //invert
-			bsa.attackerID = defender->ID;
+			bsa.stackAttacked = attacker->unitId(); //invert
+			bsa.attackerID = defender->unitId();
 			bsa.damageAmount = totalDamage;
 			bsa.damageAmount = totalDamage;
 			attacker->prepareAttacked(bsa, getRandomGenerator());
 			attacker->prepareAttacked(bsa, getRandomGenerator());
 
 
@@ -1323,7 +1323,7 @@ int CGameHandler::moveStack(int stack, BattleHex dest)
 
 
 	bool canUseGate = false;
 	bool canUseGate = false;
 	auto dbState = gs->curB->si.gateState;
 	auto dbState = gs->curB->si.gateState;
-	if(battleGetSiegeLevel() > 0 && curStack->side == BattleSide::DEFENDER &&
+	if(battleGetSiegeLevel() > 0 && curStack->unitSide() == BattleSide::DEFENDER &&
 		dbState != EGateState::DESTROYED &&
 		dbState != EGateState::DESTROYED &&
 		dbState != EGateState::BLOCKED)
 		dbState != EGateState::BLOCKED)
 	{
 	{
@@ -1385,7 +1385,7 @@ int CGameHandler::moveStack(int stack, BattleHex dest)
 
 
 			//inform clients about move
 			//inform clients about move
 			BattleStackMoved sm;
 			BattleStackMoved sm;
-			sm.stack = curStack->ID;
+			sm.stack = curStack->unitId();
 			std::vector<BattleHex> tiles;
 			std::vector<BattleHex> tiles;
 			tiles.push_back(path.first[0]);
 			tiles.push_back(path.first[0]);
 			sm.tilesToMove = tiles;
 			sm.tilesToMove = tiles;
@@ -1514,7 +1514,7 @@ int CGameHandler::moveStack(int stack, BattleHex dest)
 			{
 			{
 				//commit movement
 				//commit movement
 				BattleStackMoved sm;
 				BattleStackMoved sm;
-				sm.stack = curStack->ID;
+				sm.stack = curStack->unitId();
 				sm.distance = path.second;
 				sm.distance = path.second;
 				sm.teleporting = false;
 				sm.teleporting = false;
 				sm.tilesToMove = tiles;
 				sm.tilesToMove = tiles;
@@ -1560,8 +1560,8 @@ int CGameHandler::moveStack(int stack, BattleHex dest)
 	//handle last hex separately for deviation
 	//handle last hex separately for deviation
 	if (VLC->settings()->getBoolean(EGameSettings::COMBAT_ONE_HEX_TRIGGERS_OBSTACLES))
 	if (VLC->settings()->getBoolean(EGameSettings::COMBAT_ONE_HEX_TRIGGERS_OBSTACLES))
 	{
 	{
-		if (dest == battle::Unit::occupiedHex(start, curStack->doubleWide(), curStack->side)
-			|| start == battle::Unit::occupiedHex(dest, curStack->doubleWide(), curStack->side))
+		if (dest == battle::Unit::occupiedHex(start, curStack->doubleWide(), curStack->unitSide())
+			|| start == battle::Unit::occupiedHex(dest, curStack->doubleWide(), curStack->unitSide()))
 			passed.clear(); //Just empty passed, obstacles will handled automatically
 			passed.clear(); //Just empty passed, obstacles will handled automatically
 	}
 	}
 	//handling obstacle on the final field (separate, because it affects both flying and walking stacks)
 	//handling obstacle on the final field (separate, because it affects both flying and walking stacks)
@@ -4568,7 +4568,7 @@ bool CGameHandler::makeBattleAction(BattleAction &ba)
 
 
 		if (battleTacticDist())
 		if (battleTacticDist())
 		{
 		{
-			if (stack && stack->side != battleGetTacticsSide())
+			if (stack && stack->unitSide() != battleGetTacticsSide())
 			{
 			{
 				complain("This is not a stack of side that has tactics!");
 				complain("This is not a stack of side that has tactics!");
 				return false;
 				return false;
@@ -4731,7 +4731,7 @@ bool CGameHandler::makeBattleAction(BattleAction &ba)
 				break;
 				break;
 			}
 			}
 
 
-			if(destinationStack && stack->ID == destinationStack->ID) //we should just move, it will be handled by following check
+			if(destinationStack && stack->unitId() == destinationStack->unitId()) //we should just move, it will be handled by following check
 			{
 			{
 				destinationStack = nullptr;
 				destinationStack = nullptr;
 			}
 			}
@@ -4796,7 +4796,7 @@ bool CGameHandler::makeBattleAction(BattleAction &ba)
 				&& stack->alive())
 				&& stack->alive())
 			{
 			{
 				moveStack(ba.stackNumber, startingPos);
 				moveStack(ba.stackNumber, startingPos);
-				//NOTE: curStack->ID == ba.stackNumber (rev 1431)
+				//NOTE: curStack->unitId() == ba.stackNumber (rev 1431)
 			}
 			}
 			break;
 			break;
 		}
 		}
@@ -5181,7 +5181,7 @@ void CGameHandler::stackEnchantedTrigger(const CStack * st)
 void CGameHandler::stackTurnTrigger(const CStack *st)
 void CGameHandler::stackTurnTrigger(const CStack *st)
 {
 {
 	BattleTriggerEffect bte;
 	BattleTriggerEffect bte;
-	bte.stackID = st->ID;
+	bte.stackID = st->unitId();
 	bte.effect = -1;
 	bte.effect = -1;
 	bte.val = 0;
 	bte.val = 0;
 	bte.additionalInfo = 0;
 	bte.additionalInfo = 0;
@@ -5214,7 +5214,7 @@ void CGameHandler::stackTurnTrigger(const CStack *st)
 			{
 			{
 				BattleSetStackProperty ssp;
 				BattleSetStackProperty ssp;
 				ssp.which = BattleSetStackProperty::UNBIND;
 				ssp.which = BattleSetStackProperty::UNBIND;
-				ssp.stackID = st->ID;
+				ssp.stackID = st->unitId();
 				sendAndApply(&ssp);
 				sendAndApply(&ssp);
 			}
 			}
 		}
 		}
@@ -5270,7 +5270,7 @@ void CGameHandler::stackTurnTrigger(const CStack *st)
 			}
 			}
 		}
 		}
 		BonusList bl = *(st->getBonuses(Selector::type()(Bonus::ENCHANTER)));
 		BonusList bl = *(st->getBonuses(Selector::type()(Bonus::ENCHANTER)));
-		int side = gs->curB->whatSide(st->owner);
+		int side = gs->curB->whatSide(st->unitOwner());
 		if(st->canCast() && gs->curB->battleGetEnchanterCounter(side) == 0)
 		if(st->canCast() && gs->curB->battleGetEnchanterCounter(side) == 0)
 		{
 		{
 			bool cast = false;
 			bool cast = false;
@@ -6043,7 +6043,7 @@ void CGameHandler::handleAfterAttackCasting(bool ranged, const CStack * attacker
 
 
 		BattleStackAttacked bsa;
 		BattleStackAttacked bsa;
 		bsa.attackerID = -1;
 		bsa.attackerID = -1;
-		bsa.stackAttacked = defender->ID;
+		bsa.stackAttacked = defender->unitId();
 		bsa.damageAmount = amountToDie * defender->MaxHealth();
 		bsa.damageAmount = amountToDie * defender->MaxHealth();
 		bsa.flags = BattleStackAttacked::SPELL_EFFECT;
 		bsa.flags = BattleStackAttacked::SPELL_EFFECT;
 		bsa.spellID = SpellID::SLAYER;
 		bsa.spellID = SpellID::SLAYER;
@@ -6159,8 +6159,8 @@ void CGameHandler::makeStackDoNothing(const CStack * next)
 {
 {
 	BattleAction doNothing;
 	BattleAction doNothing;
 	doNothing.actionType = EActionType::NO_ACTION;
 	doNothing.actionType = EActionType::NO_ACTION;
-	doNothing.side = next->side;
-	doNothing.stackNumber = next->ID;
+	doNothing.side = next->unitSide();
+	doNothing.stackNumber = next->unitId();
 
 
 	makeAutomaticAction(next, doNothing);
 	makeAutomaticAction(next, doNothing);
 }
 }
@@ -6387,17 +6387,17 @@ void CGameHandler::runBattle()
 			if (!guardianIsBig)
 			if (!guardianIsBig)
 				targetHexes = stack->getSurroundingHexes();
 				targetHexes = stack->getSurroundingHexes();
 			else
 			else
-				summonGuardiansHelper(targetHexes, stack->getPosition(), stack->side, targetIsBig);
+				summonGuardiansHelper(targetHexes, stack->getPosition(), stack->unitSide(), targetIsBig);
 
 
 			for(auto hex : targetHexes)
 			for(auto hex : targetHexes)
 			{
 			{
-				if(accessibility.accessible(hex, guardianIsBig, stack->side)) //without this multiple creatures can occupy one hex
+				if(accessibility.accessible(hex, guardianIsBig, stack->unitSide())) //without this multiple creatures can occupy one hex
 				{
 				{
 					battle::UnitInfo info;
 					battle::UnitInfo info;
 					info.id = gs->curB->battleNextUnitId();
 					info.id = gs->curB->battleNextUnitId();
 					info.count =  std::max(1, (int)(stack->getCount() * 0.01 * summonInfo->val));
 					info.count =  std::max(1, (int)(stack->getCount() * 0.01 * summonInfo->val));
 					info.type = creatureData;
 					info.type = creatureData;
-					info.side = stack->side;
+					info.side = stack->unitSide();
 					info.position = hex;
 					info.position = hex;
 					info.summoned = true;
 					info.summoned = true;
 
 
@@ -6485,7 +6485,7 @@ void CGameHandler::runBattle()
 					if(stack && stack->alive() && !stack->waiting)
 					if(stack && stack->alive() && !stack->waiting)
 					{
 					{
 						BattleTriggerEffect bte;
 						BattleTriggerEffect bte;
-						bte.stackID = stack->ID;
+						bte.stackID = stack->unitId();
 						bte.effect = Bonus::HP_REGENERATION;
 						bte.effect = Bonus::HP_REGENERATION;
 
 
 						const int32_t lostHealth = stack->MaxHealth() - stack->getFirstHPleft();
 						const int32_t lostHealth = stack->MaxHealth() - stack->getFirstHPleft();
@@ -6529,8 +6529,8 @@ void CGameHandler::runBattle()
 					//unit loses its turn - empty freeze action
 					//unit loses its turn - empty freeze action
 					BattleAction ba;
 					BattleAction ba;
 					ba.actionType = EActionType::BAD_MORALE;
 					ba.actionType = EActionType::BAD_MORALE;
-					ba.side = next->side;
-					ba.stackNumber = next->ID;
+					ba.side = next->unitSide();
+					ba.stackNumber = next->unitId();
 
 
 					makeAutomaticAction(next, ba);
 					makeAutomaticAction(next, ba);
 					continue;
 					continue;
@@ -6545,8 +6545,8 @@ void CGameHandler::runBattle()
 				{
 				{
 					BattleAction attack;
 					BattleAction attack;
 					attack.actionType = EActionType::WALK_AND_ATTACK;
 					attack.actionType = EActionType::WALK_AND_ATTACK;
-					attack.side = next->side;
-					attack.stackNumber = next->ID;
+					attack.side = next->unitSide();
+					attack.stackNumber = next->unitId();
 					attack.aimToHex(attackInfo.second);
 					attack.aimToHex(attackInfo.second);
 					attack.aimToUnit(attackInfo.first);
 					attack.aimToUnit(attackInfo.first);
 
 
@@ -6569,8 +6569,8 @@ void CGameHandler::runBattle()
 			{
 			{
 				BattleAction attack;
 				BattleAction attack;
 				attack.actionType = EActionType::SHOOT;
 				attack.actionType = EActionType::SHOOT;
-				attack.side = next->side;
-				attack.stackNumber = next->ID;
+				attack.side = next->unitSide();
+				attack.stackNumber = next->unitId();
 
 
 				//TODO: select target by priority
 				//TODO: select target by priority
 
 
@@ -6579,7 +6579,7 @@ void CGameHandler::runBattle()
 				for(auto & elem : gs->curB->stacks)
 				for(auto & elem : gs->curB->stacks)
 				{
 				{
 					if(elem->unitType()->getId() != CreatureID::CATAPULT
 					if(elem->unitType()->getId() != CreatureID::CATAPULT
-						&& elem->owner != next->owner
+						&& elem->unitOwner() != next->unitOwner()
 						&& elem->isValidTarget()
 						&& elem->isValidTarget()
 						&& gs->curB->battleCanShoot(next, elem->getPosition()))
 						&& gs->curB->battleCanShoot(next, elem->getPosition()))
 					{
 					{
@@ -6614,8 +6614,8 @@ void CGameHandler::runBattle()
 				{
 				{
 					BattleAction attack;
 					BattleAction attack;
 					attack.actionType = EActionType::CATAPULT;
 					attack.actionType = EActionType::CATAPULT;
-					attack.side = next->side;
-					attack.stackNumber = next->ID;
+					attack.side = next->unitSide();
+					attack.stackNumber = next->unitId();
 
 
 					makeAutomaticAction(next, attack);
 					makeAutomaticAction(next, attack);
 					continue;
 					continue;
@@ -6626,7 +6626,7 @@ void CGameHandler::runBattle()
 			{
 			{
 				TStacks possibleStacks = battleGetStacksIf([=](const CStack * s)
 				TStacks possibleStacks = battleGetStacksIf([=](const CStack * s)
 				{
 				{
-					return s->owner == next->owner && s->canBeHealed();
+					return s->unitOwner() == next->unitOwner() && s->canBeHealed();
 				});
 				});
 
 
 				if (!possibleStacks.size())
 				if (!possibleStacks.size())
@@ -6643,8 +6643,8 @@ void CGameHandler::runBattle()
 					BattleAction heal;
 					BattleAction heal;
 					heal.actionType = EActionType::STACK_HEAL;
 					heal.actionType = EActionType::STACK_HEAL;
 					heal.aimToUnit(toBeHealed);
 					heal.aimToUnit(toBeHealed);
-					heal.side = next->side;
-					heal.stackNumber = next->ID;
+					heal.side = next->unitSide();
+					heal.stackNumber = next->unitId();
 
 
 					makeAutomaticAction(next, heal);
 					makeAutomaticAction(next, heal);
 					continue;
 					continue;
@@ -6666,7 +6666,7 @@ void CGameHandler::runBattle()
 					else
 					else
 					{
 					{
 						logGlobal->trace("Activating %s", next->nodeName());
 						logGlobal->trace("Activating %s", next->nodeName());
-						auto nextId = next->ID;
+						auto nextId = next->unitId();
 						BattleSetActiveStack sas;
 						BattleSetActiveStack sas;
 						sas.stack = nextId;
 						sas.stack = nextId;
 						sendAndApply(&sas);
 						sendAndApply(&sas);
@@ -6719,7 +6719,7 @@ void CGameHandler::runBattle()
 						if(diceSize.size() > 0 && getRandomGenerator().nextInt(1, diceSize[diceIndex]) == 1)
 						if(diceSize.size() > 0 && getRandomGenerator().nextInt(1, diceSize[diceIndex]) == 1)
 						{
 						{
 							BattleTriggerEffect bte;
 							BattleTriggerEffect bte;
-							bte.stackID = next->ID;
+							bte.stackID = next->unitId();
 							bte.effect = Bonus::MORALE;
 							bte.effect = Bonus::MORALE;
 							bte.val = 1;
 							bte.val = 1;
 							bte.additionalInfo = 0;
 							bte.additionalInfo = 0;
@@ -6748,7 +6748,7 @@ void CGameHandler::runBattle()
 bool CGameHandler::makeAutomaticAction(const CStack *stack, BattleAction &ba)
 bool CGameHandler::makeAutomaticAction(const CStack *stack, BattleAction &ba)
 {
 {
 	BattleSetActiveStack bsa;
 	BattleSetActiveStack bsa;
-	bsa.stack = stack->ID;
+	bsa.stack = stack->unitId();
 	bsa.askPlayerInterface = false;
 	bsa.askPlayerInterface = false;
 	sendAndApply(&bsa);
 	sendAndApply(&bsa);
 
 
@@ -7210,20 +7210,20 @@ CasualtiesAfterBattle::CasualtiesAfterBattle(const CArmedInstance * _army, const
 	{
 	{
 		if(st->summoned) //don't take into account temporary summoned stacks
 		if(st->summoned) //don't take into account temporary summoned stacks
 			continue;
 			continue;
-		if(st->owner != color) //remove only our stacks
+		if(st->unitOwner() != color) //remove only our stacks
 			continue;
 			continue;
 
 
 		logGlobal->debug("Calculating casualties for %s", st->nodeName());
 		logGlobal->debug("Calculating casualties for %s", st->nodeName());
 
 
 		st->health.takeResurrected();
 		st->health.takeResurrected();
 
 
-		if(st->slot == SlotID::ARROW_TOWERS_SLOT)
+		if(st->unitSlot() == SlotID::ARROW_TOWERS_SLOT)
 		{
 		{
 			logGlobal->debug("Ignored arrow towers stack.");
 			logGlobal->debug("Ignored arrow towers stack.");
 		}
 		}
-		else if(st->slot == SlotID::WAR_MACHINES_SLOT)
+		else if(st->unitSlot() == SlotID::WAR_MACHINES_SLOT)
 		{
 		{
-			auto warMachine = st->type->warMachine;
+			auto warMachine = st->unitType()->warMachine;
 
 
 			if(warMachine == ArtifactID::NONE)
 			if(warMachine == ArtifactID::NONE)
 			{
 			{
@@ -7240,16 +7240,16 @@ CasualtiesAfterBattle::CasualtiesAfterBattle(const CArmedInstance * _army, const
 					logGlobal->error("War machine in army without hero");
 					logGlobal->error("War machine in army without hero");
 			}
 			}
 		}
 		}
-		else if(st->slot == SlotID::SUMMONED_SLOT_PLACEHOLDER)
+		else if(st->unitSlot() == SlotID::SUMMONED_SLOT_PLACEHOLDER)
 		{
 		{
 			if(st->alive() && st->getCount() > 0)
 			if(st->alive() && st->getCount() > 0)
 			{
 			{
 				logGlobal->debug("Permanently summoned %d units.", st->getCount());
 				logGlobal->debug("Permanently summoned %d units.", st->getCount());
-				const CreatureID summonedType = st->type->getId();
+				const CreatureID summonedType = st->creatureId();
 				summoned[summonedType] += st->getCount();
 				summoned[summonedType] += st->getCount();
 			}
 			}
 		}
 		}
-		else if(st->slot == SlotID::COMMANDER_SLOT_PLACEHOLDER)
+		else if(st->unitSlot() == SlotID::COMMANDER_SLOT_PLACEHOLDER)
 		{
 		{
 			if (nullptr == st->base)
 			if (nullptr == st->base)
 			{
 			{
@@ -7271,25 +7271,25 @@ CasualtiesAfterBattle::CasualtiesAfterBattle(const CArmedInstance * _army, const
 					logGlobal->error("Stack with invalid instance in commander slot. Stack: %s", st->nodeName());
 					logGlobal->error("Stack with invalid instance in commander slot. Stack: %s", st->nodeName());
 			}
 			}
 		}
 		}
-		else if(st->base && !army->slotEmpty(st->slot))
+		else if(st->base && !army->slotEmpty(st->unitSlot()))
 		{
 		{
-			logGlobal->debug("Count: %d; base count: %d", st->getCount(), army->getStackCount(st->slot));
+			logGlobal->debug("Count: %d; base count: %d", st->getCount(), army->getStackCount(st->unitSlot()));
 			if(st->getCount() == 0 || !st->alive())
 			if(st->getCount() == 0 || !st->alive())
 			{
 			{
 				logGlobal->debug("Stack has been destroyed.");
 				logGlobal->debug("Stack has been destroyed.");
-				StackLocation sl(army, st->slot);
+				StackLocation sl(army, st->unitSlot());
 				newStackCounts.push_back(TStackAndItsNewCount(sl, 0));
 				newStackCounts.push_back(TStackAndItsNewCount(sl, 0));
 			}
 			}
-			else if(st->getCount() < army->getStackCount(st->slot))
+			else if(st->getCount() < army->getStackCount(st->unitSlot()))
 			{
 			{
-				logGlobal->debug("Stack lost %d units.", army->getStackCount(st->slot) - st->getCount());
-				StackLocation sl(army, st->slot);
+				logGlobal->debug("Stack lost %d units.", army->getStackCount(st->unitSlot()) - st->getCount());
+				StackLocation sl(army, st->unitSlot());
 				newStackCounts.push_back(TStackAndItsNewCount(sl, st->getCount()));
 				newStackCounts.push_back(TStackAndItsNewCount(sl, st->getCount()));
 			}
 			}
-			else if(st->getCount() > army->getStackCount(st->slot))
+			else if(st->getCount() > army->getStackCount(st->unitSlot()))
 			{
 			{
-				logGlobal->debug("Stack gained %d units.", st->getCount() - army->getStackCount(st->slot));
-				StackLocation sl(army, st->slot);
+				logGlobal->debug("Stack gained %d units.", st->getCount() - army->getStackCount(st->unitSlot()));
+				StackLocation sl(army, st->unitSlot());
 				newStackCounts.push_back(TStackAndItsNewCount(sl, st->getCount()));
 				newStackCounts.push_back(TStackAndItsNewCount(sl, st->getCount()));
 			}
 			}
 		}
 		}