Example #1
0
void CGBorderGate::onHeroVisit( const CGHeroInstance * h ) const //TODO: passability
{
	if (!wasMyColorVisited (h->getOwner()) )
	{
		showInfoDialog(h,18,0);

		AddQuest aq;
		aq.quest = QuestInfo (quest, this, visitablePos());
		aq.player = h->tempOwner;
		cb->sendAndApply (&aq);
	}
}
Example #2
0
void CGObjectInstance::setType(si32 ID, si32 subID)
{
	const TerrainTile &tile = cb->gameState()->map->getTile(visitablePos());

	this->ID = Obj(ID);
	this->subID = subID;

	//recalculate blockvis tiles - new appearance might have different blockmap than before
	cb->gameState()->map->removeBlockVisTiles(this, true);
	auto handler = VLC->objtypeh->getHandlerFor(ID, subID);
	if(!handler)
	{
		logGlobal->error("Unknown object type %d:%d at %s", ID, subID, visitablePos().toString());
		return;
	}
	if(!handler->getTemplates(tile.terType).empty())
		appearance = handler->getTemplates(tile.terType)[0];
	else
		appearance = handler->getTemplates()[0]; // get at least some appearance since alternative is crash
	cb->gameState()->map->addBlockVisTiles(this);
}
Example #3
0
void CGSeerHut::onHeroVisit( const CGHeroInstance * h ) const
{
	InfoWindow iw;
	iw.player = h->getOwner();
	if (quest->progress < CQuest::COMPLETE)
	{
		bool firstVisit = !quest->progress;
		bool failRequirements = !checkQuest(h);
		bool isCustom=false;

		if (firstVisit)
		{
			isCustom = quest->isCustomFirst;
			cb->setObjProperty (id, 10, CQuest::IN_PROGRESS);

			AddQuest aq;
			aq.quest = QuestInfo (quest, this, visitablePos());
			aq.player = h->tempOwner;
			cb->sendAndApply (&aq); //TODO: merge with setObjProperty?
		}
		else if (failRequirements)
		{
			isCustom = quest->isCustomNext;
		}

		if (firstVisit || failRequirements)
		{
			getVisitText (iw.text, iw.components, isCustom, firstVisit, h);

			cb->showInfoDialog(&iw);
		}
		if (!failRequirements) // propose completion, also on first visit
		{
			BlockingDialog bd (true, false);
			bd.player = h->getOwner();
			bd.soundID = soundBase::QUEST;

			getCompletionText (bd.text, bd.components, isCustom, h);

			cb->showBlockingDialog (&bd);
			return;
		}
	}
	else
	{
		iw.text << VLC->generaltexth->seerEmpty[quest->textOption];
		if (ID == Obj::SEER_HUT)
			iw.text.addReplacement(seerName);
		cb->showInfoDialog(&iw);
	}
}
Example #4
0
void CGBorderGuard::onHeroVisit( const CGHeroInstance * h ) const
{
	if (wasMyColorVisited (h->getOwner()) )
	{
		BlockingDialog bd (true, false);
		bd.player = h->getOwner();
		bd.soundID = soundBase::QUEST;
		bd.text.addTxt (MetaString::ADVOB_TXT, 17);
		cb->showBlockingDialog (&bd);
	}
	else
	{
		showInfoDialog(h,18,soundBase::CAVEHEAD);

		AddQuest aq;
		aq.quest = QuestInfo (quest, this, visitablePos());
		aq.player = h->tempOwner;
		cb->sendAndApply (&aq);
		//TODO: add this quest only once OR check for multiple instances later
	}
}
Example #5
0
void CGHeroInstance::initObj()
{
	blockVisit = true;
	auto  hs = new HeroSpecial();
	hs->setNodeType(CBonusSystemNode::SPECIALTY);
	attachTo(hs); //do we ever need to detach it?

	if(!type)
		initHero(); //TODO: set up everything for prison before specialties are configured

	skillsInfo.rand.setSeed(cb->gameState()->getRandomGenerator().nextInt());
	skillsInfo.resetMagicSchoolCounter();
	skillsInfo.resetWisdomCounter();

	if (ID != Obj::PRISON)
	{
		auto customApp = VLC->objtypeh->getHandlerFor(ID, type->heroClass->id)->getOverride(cb->gameState()->getTile(visitablePos())->terType, this);
		if (customApp)
			appearance = customApp.get();
	}

	for(const auto &spec : type->spec) //TODO: unfity with bonus system
	{
		auto bonus = new Bonus();
		bonus->val = spec.val;
		bonus->sid = id.getNum(); //from the hero, specialty has no unique id
		bonus->duration = Bonus::PERMANENT;
		bonus->source = Bonus::HERO_SPECIAL;
		switch (spec.type)
		{
			case 1:// creature specialty
				{
					hs->growsWithLevel = true;

					const CCreature &specCreature = *VLC->creh->creatures[spec.additionalinfo]; //creature in which we have specialty

					//int creLevel = specCreature.level;
					//if(!creLevel)
					//{
					//	if(spec.additionalinfo == 146)
					//		creLevel = 5; //treat ballista as 5-level
					//	else
					//	{
					//        logGlobal->warnStream() << "Warning: unknown level of " << specCreature.namePl;
					//		continue;
					//	}
					//}

					//bonus->additionalInfo = spec.additionalinfo; //creature id, should not be used again - this works only with limiter
					bonus->limiter.reset(new CCreatureTypeLimiter (specCreature, true)); //with upgrades
					bonus->type = Bonus::PRIMARY_SKILL;
					bonus->valType = Bonus::ADDITIVE_VALUE;

					bonus->subtype = PrimarySkill::ATTACK;
					hs->addNewBonus(bonus);

					bonus = new Bonus(*bonus);
					bonus->subtype = PrimarySkill::DEFENSE;
					hs->addNewBonus(bonus);
					//values will be calculated later

					bonus = new Bonus(*bonus);
					bonus->type = Bonus::STACKS_SPEED;
					bonus->val = 1; //+1 speed
					hs->addNewBonus(bonus);
				}
				break;
			case 2://secondary skill
				hs->growsWithLevel = true;
				bonus->type = Bonus::SPECIAL_SECONDARY_SKILL; //needs to be recalculated with level, based on this value
				bonus->valType = Bonus::BASE_NUMBER; // to receive nonzero value
				bonus->subtype = spec.subtype; //skill id
				bonus->val = spec.val; //value per level, in percent
				hs->addNewBonus(bonus);
				bonus = new Bonus(*bonus);

				switch (spec.additionalinfo)
				{
					case 0: //normal
						bonus->valType = Bonus::PERCENT_TO_BASE;
						break;
					case 1: //when it's navigation or there's no 'base' at all
						bonus->valType = Bonus::PERCENT_TO_ALL;
						break;
				}
				bonus->type = Bonus::SECONDARY_SKILL_PREMY; //value will be calculated later
				hs->addNewBonus(bonus);
				break;
			case 3://spell damage bonus, level dependent but calculated elsewhere
				bonus->type = Bonus::SPECIAL_SPELL_LEV;
				bonus->subtype = spec.subtype;
				hs->addNewBonus(bonus);
				break;
			case 4://creature stat boost
				switch (spec.subtype)
				{
					case 1://attack
						bonus->type = Bonus::PRIMARY_SKILL;
						bonus->subtype = PrimarySkill::ATTACK;
						break;
					case 2://defense
						bonus->type = Bonus::PRIMARY_SKILL;
						bonus->subtype = PrimarySkill::DEFENSE;
						break;
					case 3:
						bonus->type = Bonus::CREATURE_DAMAGE;
						bonus->subtype = 0; //both min and max
						break;
					case 4://hp
						bonus->type = Bonus::STACK_HEALTH;
						break;
					case 5:
						bonus->type = Bonus::STACKS_SPEED;
						break;
					default:
						continue;
				}
				bonus->additionalInfo = spec.additionalinfo; //creature id
				bonus->valType = Bonus::ADDITIVE_VALUE;
				bonus->limiter.reset(new CCreatureTypeLimiter (*VLC->creh->creatures[spec.additionalinfo], true));
				hs->addNewBonus(bonus);
				break;
			case 5://spell damage bonus in percent
				bonus->type = Bonus::SPECIFIC_SPELL_DAMAGE;
				bonus->valType = Bonus::BASE_NUMBER; // current spell system is screwed
				bonus->subtype = spec.subtype; //spell id
				hs->addNewBonus(bonus);
				break;
			case 6://damage bonus for bless (Adela)
				bonus->type = Bonus::SPECIAL_BLESS_DAMAGE;
				bonus->subtype = spec.subtype; //spell id if you ever wanted to use it otherwise
				bonus->additionalInfo = spec.additionalinfo; //damage factor
				hs->addNewBonus(bonus);
				break;
			case 7://maxed mastery for spell
				bonus->type = Bonus::MAXED_SPELL;
				bonus->subtype = spec.subtype; //spell i
				hs->addNewBonus(bonus);
				break;
			case 8://peculiar spells - enchantments
				bonus->type = Bonus::SPECIAL_PECULIAR_ENCHANT;
				bonus->subtype = spec.subtype; //spell id
				bonus->additionalInfo = spec.additionalinfo;//0, 1 for Coronius
				hs->addNewBonus(bonus);
				break;
			case 9://upgrade creatures
			{
				const auto &creatures = VLC->creh->creatures;
				bonus->type = Bonus::SPECIAL_UPGRADE;
				bonus->subtype = spec.subtype; //base id
				bonus->additionalInfo = spec.additionalinfo; //target id
				hs->addNewBonus(bonus);
				bonus = new Bonus(*bonus);

				for(auto cre_id : creatures[spec.subtype]->upgrades)
				{
					bonus->subtype = cre_id; //propagate for regular upgrades of base creature
					hs->addNewBonus(bonus);
					bonus = new Bonus(*bonus);
				}
				vstd::clear_pointer(bonus);
				break;
			}
			case 10://resource generation
				bonus->type = Bonus::GENERATE_RESOURCE;
				bonus->subtype = spec.subtype;
				hs->addNewBonus(bonus);
				break;
			case 11://starting skill with mastery (Adrienne)
				setSecSkillLevel(SecondarySkill(spec.val), spec.additionalinfo, true);
				break;
			case 12://army speed
				bonus->type = Bonus::STACKS_SPEED;
				hs->addNewBonus(bonus);
				break;
			case 13://Dragon bonuses (Mutare)
				bonus->type = Bonus::PRIMARY_SKILL;
				bonus->valType = Bonus::ADDITIVE_VALUE;
				switch (spec.subtype)
				{
					case 1:
						bonus->subtype = PrimarySkill::ATTACK;
						break;
					case 2:
						bonus->subtype = PrimarySkill::DEFENSE;
						break;
				}
				bonus->limiter.reset(new HasAnotherBonusLimiter(Bonus::DRAGON_NATURE));
				hs->addNewBonus(bonus);
				break;
			default:
                logGlobal->warnStream() << "Unexpected hero specialty " << type;
		}
	}
	specialty.push_back(hs); //will it work?

	for (auto hs2 : type->specialty) //copy active (probably growing) bonuses from hero prootype to hero object
	{
		auto  hs = new HeroSpecial();
		attachTo(hs); //do we ever need to detach it?

		hs->setNodeType(CBonusSystemNode::SPECIALTY);
		for (auto bonus : hs2.bonuses)
		{
			hs->addNewBonus (bonus);
		}
		hs->growsWithLevel = hs2.growsWithLevel;

		specialty.push_back(hs); //will it work?
	}

	//initialize bonuses
	recreateSecondarySkillsBonuses();
	Updatespecialty();

	mana = manaLimit(); //after all bonuses are taken into account, make sure this line is the last one
	type->name = name;
}
Example #6
0
int3 CGObjectInstance::getSightCenter() const
{
	return visitablePos();
}