Esempio n. 1
0
void CDwellingInstanceConstructor::configureObject(CGObjectInstance * object, CRandomGenerator &rng) const
{
    CGDwelling * dwelling = dynamic_cast<CGDwelling*>(object);

    dwelling->creatures.clear();
    dwelling->creatures.reserve(availableCreatures.size());

    for (auto & entry : availableCreatures)
    {
        dwelling->creatures.resize(dwelling->creatures.size() + 1);
        for (const CCreature * cre : entry)
            dwelling->creatures.back().second.push_back(cre->idNumber);
    }

    if (guards.getType() == JsonNode::DATA_BOOL)
    {
        if (guards.Bool())
        {
            const CCreature * crea = availableCreatures.at(0).at(0);
            dwelling->putStack(SlotID(0), new CStackInstance(crea->idNumber, crea->growth * 3 ));
        }
    }
    else for (auto & stack : JsonRandom::loadCreatures(guards, rng))
        {
            dwelling->putStack(SlotID(dwelling->stacksCount()), new CStackInstance(stack.type->idNumber, stack.count));
        }
}
Esempio n. 2
0
SlotID CCreatureSet::getFreeSlot(ui32 slotsAmount/*=ARMY_SIZE*/) const
{
	for(ui32 i=0; i<slotsAmount; i++)
	{
		if(!vstd::contains(stacks, SlotID(i)))
		{
			return SlotID(i); //return first free slot
		}
	}
	return SlotID(); //no slot available
}
Esempio n. 3
0
bool TradeOnMarketplace::applyGh( CGameHandler *gh )
{
	//market must be owned or visited
	const IMarket *m = IMarket::castFrom(market);

	if(!m)
		COMPLAIN_AND_RETURN("market is not-a-market! :/");

	PlayerColor player = market->tempOwner;

	if(player >= PlayerColor::PLAYER_LIMIT)
		player = gh->getTile(market->visitablePos())->visitableObjects.back()->tempOwner;

	if(player >= PlayerColor::PLAYER_LIMIT)
		COMPLAIN_AND_RETURN("No player can use this market!");

	if(hero && (player != hero->tempOwner || hero->visitablePos() != market->visitablePos()))
		COMPLAIN_AND_RETURN("This hero can't use this marketplace!");

	ERROR_IF_NOT(player);

	switch(mode)
	{
	case EMarketMode::RESOURCE_RESOURCE:
		return gh->tradeResources(m, val, player, r1, r2);
	case EMarketMode::RESOURCE_PLAYER:
		return gh->sendResources(val, player, static_cast<Res::ERes>(r1), PlayerColor(r2));
	case EMarketMode::CREATURE_RESOURCE:
		if(!hero)
			COMPLAIN_AND_RETURN("Only hero can sell creatures!");
		return gh->sellCreatures(val, m, hero, SlotID(r1), static_cast<Res::ERes>(r2));
	case EMarketMode::RESOURCE_ARTIFACT:
		if(!hero)
			COMPLAIN_AND_RETURN("Only hero can buy artifacts!");
		return gh->buyArtifact(m, hero, static_cast<Res::ERes>(r1), ArtifactID(r2));
	case EMarketMode::ARTIFACT_RESOURCE:
		if(!hero)
			COMPLAIN_AND_RETURN("Only hero can sell artifacts!");
		return gh->sellArtifact(m, hero, ArtifactInstanceID(r1), static_cast<Res::ERes>(r2));
	case EMarketMode::CREATURE_UNDEAD:
		return gh->transformInUndead(m, hero, SlotID(r1));
	case EMarketMode::RESOURCE_SKILL:
		return gh->buySecSkill(m, hero, SecondarySkill(r2));
	case EMarketMode::CREATURE_EXP:
		return gh->sacrificeCreatures(m, hero, SlotID(r1), val);
	case EMarketMode::ARTIFACT_EXP:
		return gh->sacrificeArtifact(m, hero, ArtifactPosition(r1));
	default:
		COMPLAIN_AND_RETURN("Unknown exchange mode!");
	}
}
Esempio n. 4
0
SlotID CCreatureSet::findStack(const CStackInstance *stack) const
{
	auto h = dynamic_cast<const CGHeroInstance *>(this);
	if (h && h->commander == stack)
		return SlotID::COMMANDER_SLOT_PLACEHOLDER;

	if(!stack)
		return SlotID();

	for(TSlots::const_iterator i = stacks.begin(); i != stacks.end(); ++i)
		if(i->second == stack)
			return i->first;

	return SlotID();
}
Esempio n. 5
0
void CGSeerHut::completeQuest (const CGHeroInstance * h) const //reward
{
	switch (rewardType)
	{
		case EXPERIENCE:
		{
			TExpType expVal = h->calculateXp(rVal);
			cb->changePrimSkill(h, PrimarySkill::EXPERIENCE, expVal, false);
			break;
		}
		case MANA_POINTS:
		{
			cb->setManaPoints(h->id, h->mana+rVal);
			break;
		}
		case MORALE_BONUS: case LUCK_BONUS:
		{
			Bonus hb(Bonus::ONE_WEEK, (rewardType == 3 ? Bonus::MORALE : Bonus::LUCK),
				Bonus::OBJECT, rVal, h->id.getNum(), "", -1);
			GiveBonus gb;
			gb.id = h->id.getNum();
			gb.bonus = hb;
			cb->giveHeroBonus(&gb);
		}
			break;
		case RESOURCES:
			cb->giveResource(h->getOwner(), static_cast<Res::ERes>(rID), rVal);
			break;
		case PRIMARY_SKILL:
			cb->changePrimSkill(h, static_cast<PrimarySkill::PrimarySkill>(rID), rVal, false);
			break;
		case SECONDARY_SKILL:
			cb->changeSecSkill(h, SecondarySkill(rID), rVal, false);
			break;
		case ARTIFACT:
			cb->giveHeroNewArtifact(h, VLC->arth->artifacts[rID],ArtifactPosition::FIRST_AVAILABLE);
			break;
		case SPELL:
		{
			std::set<SpellID> spell;
			spell.insert (SpellID(rID));
			cb->changeSpells(h, true, spell);
		}
			break;
		case CREATURE:
			{
				CCreatureSet creatures;
				creatures.setCreature(SlotID(0), CreatureID(rID), rVal);
				cb->giveCreatures(this, h, creatures, false);
			}
			break;
		default:
			break;
	}
}
Esempio n. 6
0
void CGHeroInstance::initArmy(IArmyDescriptor *dst /*= nullptr*/)
{
	if(!dst)
		dst = this;

	int howManyStacks = 0; //how many stacks will hero receives <1 - 3>
	int pom = cb->gameState()->getRandomGenerator().nextInt(99);
	int warMachinesGiven = 0;

	if(pom < 9)
		howManyStacks = 1;
	else if(pom < 79)
		howManyStacks = 2;
	else
		howManyStacks = 3;

	vstd::amin(howManyStacks, type->initialArmy.size());

	for(int stackNo=0; stackNo < howManyStacks; stackNo++)
	{
		auto & stack = type->initialArmy[stackNo];

		int count = cb->gameState()->getRandomGenerator().nextInt(stack.minAmount, stack.maxAmount);

		if(stack.creature >= CreatureID::CATAPULT &&
		   stack.creature <= CreatureID::ARROW_TOWERS) //war machine
		{
			warMachinesGiven++;
			if(dst != this)
				continue;

			int slot = -1;
			ArtifactID aid = ArtifactID::NONE;
			switch (stack.creature)
			{
			case CreatureID::CATAPULT:
				slot = ArtifactPosition::MACH4;
				aid = ArtifactID::CATAPULT;
				break;
			default:
				aid = CArtHandler::creatureToMachineID(stack.creature);
				slot = 9 + aid;
				break;
			}
			auto convSlot = ArtifactPosition(slot);
			if(!getArt(convSlot))
				putArtifact(convSlot, CArtifactInstance::createNewArtifactInstance(aid));
			else
                logGlobal->warnStream() << "Hero " << name << " already has artifact at " << slot << ", omitting giving " << aid;
		}
		else
			dst->setCreature(SlotID(stackNo-warMachinesGiven), stack.creature, count);
	}
}
Esempio n. 7
0
void CGSeerHut::setObjToKill()
{
	if (quest->missionType == CQuest::MISSION_KILL_CREATURE)
	{
		quest->stackToKill = getCreatureToKill(false)->getStack(SlotID(0)); //FIXME: stacks tend to disappear (desync?) on server :?
		assert(quest->stackToKill.type);
		quest->stackToKill.count = 0; //no count in info window
		quest->stackDirection = checkDirection();
	}
	else if (quest->missionType == CQuest::MISSION_KILL_HERO)
	{
		quest->heroName = getHeroToKill(false)->name;
		quest->heroPortrait = getHeroToKill(false)->portrait;
	}
}
Esempio n. 8
0
/**
 * Calculates what creatures and how many to be raised from a battle.
 * @param battleResult The results of the battle.
 * @return Returns a pair with the first value indicating the ID of the creature
 * type and second value the amount. Both values are returned as -1 if necromancy
 * could not be applied.
 */
CStackBasicDescriptor CGHeroInstance::calculateNecromancy (const BattleResult &battleResult) const
{
	const ui8 necromancyLevel = getSecSkillLevel(SecondarySkill::NECROMANCY);

	// Hero knows necromancy or has Necromancer Cloak
	if (necromancyLevel > 0 || hasBonusOfType(Bonus::IMPROVED_NECROMANCY))
	{
		double necromancySkill = valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, SecondarySkill::NECROMANCY)/100.0;
		vstd::amin(necromancySkill, 1.0); //it's impossible to raise more creatures than all...
		const std::map<ui32,si32> &casualties = battleResult.casualties[!battleResult.winner];
		ui32 raisedUnits = 0;

		// Figure out what to raise and how many.
		const CreatureID creatureTypes[] = {CreatureID::SKELETON, CreatureID::WALKING_DEAD, CreatureID::WIGHTS, CreatureID::LICHES};
		const bool improvedNecromancy = hasBonusOfType(Bonus::IMPROVED_NECROMANCY);
		const CCreature *raisedUnitType = VLC->creh->creatures[creatureTypes[improvedNecromancy ? necromancyLevel : 0]];
		const ui32 raisedUnitHP = raisedUnitType->valOfBonuses(Bonus::STACK_HEALTH);

		//calculate creatures raised from each defeated stack
		for (auto & casualtie : casualties)
		{
			// Get lost enemy hit points convertible to units.
			CCreature * c = VLC->creh->creatures[casualtie.first];

			const ui32 raisedHP = c->valOfBonuses(Bonus::STACK_HEALTH) * casualtie.second * necromancySkill;
			raisedUnits += std::min<ui32>(raisedHP / raisedUnitHP, casualtie.second * necromancySkill); //limit to % of HP and % of original stack count
		}

		// Make room for new units.
		SlotID slot = getSlotFor(raisedUnitType->idNumber);
		if (slot == SlotID())
		{
			// If there's no room for unit, try it's upgraded version 2/3rds the size.
			raisedUnitType = VLC->creh->creatures[*raisedUnitType->upgrades.begin()];
			raisedUnits = (raisedUnits*2)/3;

			slot = getSlotFor(raisedUnitType->idNumber);
		}
		if (raisedUnits <= 0)
			raisedUnits = 1;

		return CStackBasicDescriptor(raisedUnitType->idNumber, raisedUnits);
	}

	return CStackBasicDescriptor();
}
Esempio n. 9
0
 * License: GNU General Public License v2.0 or later
 * Full text of license available in license.txt file, in main folder
 *
 */

#define INSTANTIATE_BASE_FOR_ID_HERE

#include "StdInc.h"

#include "VCMI_Lib.h"
#include "mapObjects/CObjectClassesHandler.h"
#include "CArtHandler.h"
#include "CCreatureHandler.h"
#include "spells/CSpellHandler.h"

const SlotID SlotID::COMMANDER_SLOT_PLACEHOLDER = SlotID(-2);
const PlayerColor PlayerColor::CANNOT_DETERMINE = PlayerColor(253);
const PlayerColor PlayerColor::UNFLAGGABLE = PlayerColor(254);
const PlayerColor PlayerColor::NEUTRAL = PlayerColor(255);
const PlayerColor PlayerColor::PLAYER_LIMIT = PlayerColor(PLAYER_LIMIT_I);
const TeamID TeamID::NO_TEAM = TeamID(255);

#define ID_LIKE_OPERATORS_INTERNAL(A, B, AN, BN)	\
bool operator==(const A & a, const B & b)			\
{													\
	return AN == BN ;								\
}													\
bool operator!=(const A & a, const B & b)			\
{													\
	return AN != BN ;								\
}													\
Esempio n. 10
0
void CGHeroInstance::setPropertyDer( ui8 what, ui32 val )
{
	if(what == ObjProperty::PRIMARY_STACK_COUNT)
		setStackCount(SlotID(0), val);
}
Esempio n. 11
0
#include "StdInc.h"

#ifndef VCMI_NO_EXTRA_VERSION
#include "../Version.h"
#endif

#include "VCMI_Lib.h"
#include "mapObjects/CObjectClassesHandler.h"
#include "CArtHandler.h"
#include "CCreatureHandler.h"
#include "spells/CSpellHandler.h"
#include "StringConstants.h"
#include "CGeneralTextHandler.h"

const SlotID SlotID::COMMANDER_SLOT_PLACEHOLDER = SlotID(-2);
const SlotID SlotID::SUMMONED_SLOT_PLACEHOLDER = SlotID(-3);
const SlotID SlotID::WAR_MACHINES_SLOT = SlotID(-4);
const SlotID SlotID::ARROW_TOWERS_SLOT = SlotID(-5);

const PlayerColor PlayerColor::CANNOT_DETERMINE = PlayerColor(253);
const PlayerColor PlayerColor::UNFLAGGABLE = PlayerColor(254);
const PlayerColor PlayerColor::NEUTRAL = PlayerColor(255);
const PlayerColor PlayerColor::PLAYER_LIMIT = PlayerColor(PLAYER_LIMIT_I);
const TeamID TeamID::NO_TEAM = TeamID(255);

namespace GameConstants
{
#ifdef VCMI_NO_EXTRA_VERSION
	const std::string VCMI_VERSION = std::string("VCMI 0.99");
#else