Пример #1
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);
	}
}
Пример #2
0
void CQuest::getVisitText (MetaString &iwText, std::vector<Component> &components, bool isCustom, bool firstVisit, const CGHeroInstance * h) const
{
	std::string text;
	bool failRequirements = (h ? !checkQuest(h) : true);

	if (firstVisit)
	{
		isCustom = isCustomFirst;
		iwText << (text = firstVisitText);
	}
	else if (failRequirements)
	{
		isCustom = isCustomNext;
		iwText << (text = nextVisitText);
	}
	switch (missionType)
	{
		case MISSION_LEVEL:
			components.push_back(Component (Component::EXPERIENCE, 0, m13489val, 0));
			if (!isCustom)
				iwText.addReplacement(m13489val);
			break;
		case MISSION_PRIMARY_STAT:
		{
			MetaString loot;
			for (int i = 0; i < 4; ++i)
			{
				if (m2stats[i])
				{
					components.push_back(Component (Component::PRIM_SKILL, i, m2stats[i], 0));
					loot << "%d %s";
					loot.addReplacement(m2stats[i]);
					loot.addReplacement(VLC->generaltexth->primarySkillNames[i]);
				}
			}
			if (!isCustom)
				iwText.addReplacement(loot.buildList());
		}
			break;
		case MISSION_KILL_HERO:
			components.push_back(Component(Component::HERO_PORTRAIT, heroPortrait, 0, 0));
			if (!isCustom)
				addReplacements(iwText, text);
			break;
		case MISSION_HERO:
			//FIXME: portrait may not match hero, if custom portrait was set in map editor
			components.push_back(Component (Component::HERO_PORTRAIT, VLC->heroh->heroes[m13489val]->imageIndex, 0, 0));
			if (!isCustom)
				iwText.addReplacement(VLC->heroh->heroes[m13489val]->name);
			break;
		case MISSION_KILL_CREATURE:
			{
				components.push_back(Component(stackToKill));
				if (!isCustom)
				{
					addReplacements(iwText, text);
				}
			}
			break;
		case MISSION_ART:
		{
			MetaString loot;
			for (auto & elem : m5arts)
			{
				components.push_back(Component (Component::ARTIFACT, elem, 0, 0));
				loot << "%s";
				loot.addReplacement(MetaString::ART_NAMES, elem);
			}
			if (!isCustom)
				iwText.addReplacement(loot.buildList());
		}
			break;
		case MISSION_ARMY:
		{
			MetaString loot;
			for (auto & elem : m6creatures)
			{
				components.push_back(Component(elem));
				loot << "%s";
				loot.addReplacement(elem);
			}
			if (!isCustom)
				iwText.addReplacement(loot.buildList());
		}
			break;
		case MISSION_RESOURCES:
		{
			MetaString loot;
			for (int i = 0; i < 7; ++i)
			{
				if (m7resources[i])
				{
					components.push_back(Component (Component::RESOURCE, i, m7resources[i], 0));
					loot << "%d %s";
					loot.addReplacement(m7resources[i]);
					loot.addReplacement(MetaString::RES_NAMES, i);
				}
			}
			if (!isCustom)
				iwText.addReplacement(loot.buildList());
		}
			break;
		case MISSION_PLAYER:
			components.push_back(Component (Component::FLAG, m13489val, 0, 0));
			if (!isCustom)
				iwText.addReplacement(VLC->generaltexth->colors[m13489val]);
			break;
	}
}
Пример #3
0
PlayerAI_Actions PlayerAI::takeAction() {
  int px, py;
  PlayerAI_Actions action;

  /* player coodinates */
  px = cd->xpos;
  py = cd->ypos;

  /* set map for pathfinding algorithm */
  pathfind_alg.setMatrix(cd->mapx, cd->mapy, cd->terrain);
  pathfind_alg.setSecondMatrix(CLIENT_MATRIX_SIZE, CLIENT_MATRIX_SIZE,
                               cd->dynamic_objects, cd->xpos - MAX_CLIENT_VIEW,
                               cd->ypos - MAX_CLIENT_VIEW);

  /* if node update was received wait some more */
  /* if no update is received for a long time take another action */
  if (purpose != BASIC)
    if (sbx != px || sby != py) {
      sb_wait_count++;
      if (sb_wait_count == AI_RETRY_COUNT) {
        if (debug_AI)
          printf("[AI]Wait limit reached "
                 "(now:%d,%d -> sb: %d,%d) \n",
                 px, py, sbx, sby);
        purpose = BASIC;
        path->clear();
      } else
        return NO_ACTION;
    }
  if (debug_AI)
    printf("[AI][%d,%d]Purpose: %s\n", px, py, AI_state_names[purpose]);
  cd->purpose = purpose;

  /* select a new action */
  switch (purpose) {
    case BASIC:
      checkFood(10) || checkQuest() || checkStrongPlayer() || checkWeakPlayer()
          || tryToExplore();
      break;
    case SEEKING_QUEST:
      if (!questExists())
        purpose = BASIC;
      checkFood(20);
      break;
    case CHASING_PLAYER:
      checkFood(40) || checkQuest() || checkWeakPlayer();
      break;
    case EXPLORING:
      checkFood(90) || checkQuest() || checkStrongPlayer() || checkWeakPlayer();
      break;
    default:
      break;
  }

  /* move player */
  action = moveAlongThePath();
  if (action != NO_ACTION)
    return action;

  if (path->size() <= 1 && purpose == CHASING_PLAYER) {
    if (debug_AI)
      printf("[AI]Attack\n");
    purpose = BASIC;

    if (path->size() == 1) {
      int opponent_x = path->getX();
      int opponent_y = path->getY();

      if (opponent_x == px + 1)
        return ATTACK_RIGHT;
      if (opponent_x == px - 1)
        return ATTACK_LEFT;
      if (opponent_y == py + 1)
        return ATTACK_DOWN;
      if (opponent_y == py - 1)
        return ATTACK_UP;
    }

    return ATTACK_UP;
  }

  /* check if last purpose is over */
  if (path->empty() && purpose != BASIC) {
    if (purpose == SEEKING_FOOD
        && cd->map[MAX_CLIENT_VIEW][MAX_CLIENT_VIEW].type == CELL_OBJECT
        && cd->map[MAX_CLIENT_VIEW][MAX_CLIENT_VIEW].quantity > 0) {
      if (debug_AI)
        printf("[AI]Eat\n");
      purpose = BASIC;
      return USE;
    }
    purpose = BASIC;
  }

  return NO_ACTION;
}