Example #1
0
/* read element to body */
bool AGG::File::Read(const std::string & key, std::vector<u8> & body)
{
    const FAT & f = fat[key];

    if(IS_DEBUG(DBG_ENGINE, DBG_TRACE)) f.Dump(key);
    
    if(f.size)
    {
	DEBUG(DBG_ENGINE , DBG_TRACE, "AGG::File::Read: " << key);

	body.resize(f.size);

	stream->seekg(f.offset, std::ios_base::beg);

	stream->read(reinterpret_cast<char*>(&body[0]), f.size);

	return true;
    }

    return false;
}
Example #2
0
bool Algorithm::PathFind(std::list<Route::Step> *result, const s32 from, const s32 to, const u16 limit, const Heroes *hero)
{
    const u8 pathfinding = (hero ? hero->GetLevelSkill(Skill::Secondary::PATHFINDING) : Skill::Level::NONE);

    s32 cur = from;
    s32 alt = 0;
    s32 tmp = 0;
    std::map<s32, cell_t> list;
    std::map<s32, cell_t>::iterator it1 = list.begin();
    std::map<s32, cell_t>::iterator it2 = list.end();
    Direction::vector_t direct = Direction::CENTER;

    list[cur].cost_g = 0;
    list[cur].cost_t = 0;
    list[cur].parent = -1;
    list[cur].open   = false;

    while(cur != to)
    {
	LocalEvent::Get().HandleEvents(false);

	for(direct = Direction::TOP_LEFT; direct != Direction::CENTER; ++direct)
	{
    	    if(Maps::isValidDirection(cur, direct))
	    {
		tmp = Maps::GetDirectionIndex(cur, direct);

		if(list[tmp].open)
		{
		    // new
		    if(-1 == list[tmp].parent)
		    {
	    		const u16 costg = Maps::Ground::GetPenalty(tmp, direct, pathfinding);
			if(MAXU16 == costg) continue;

			if((list[cur].passbl & direct) ||
			   PassableFromToTile(hero, cur, tmp, direct, to))
			{
			    list[cur].passbl |= direct;

			    cell_t & cell = list[tmp];
	    		    cell.cost_g = costg;
			    cell.parent = cur;
			    cell.open = true;
	    		    cell.cost_t = cell.cost_g + list[cur].cost_t;
			    cell.cost_d = 50 * Maps::GetApproximateDistance(tmp, to);
			}
		    }
		    // check alt
		    else
		    {
			alt = Maps::Ground::GetPenalty(cur, direct, pathfinding);
			if(list[tmp].cost_t > list[cur].cost_t + alt &&
			   ((list[cur].passbl & direct) ||
			     PassableFromToTile(hero, cur, tmp, direct, to)))
			{
			    list[cur].passbl |= direct;

			    list[tmp].parent = cur;
			    list[tmp].cost_g = alt;
			    list[tmp].cost_t = list[cur].cost_t + alt;
			}
		    }
    		}
	    }
	}

	list[cur].open = false;

	it1 = list.begin();
	alt = -1;
	tmp = MAXU16;

	DEBUG(DBG_OTHER, DBG_TRACE, "route, from: " << cur);
	
	// find minimal cost
	for(; it1 != it2; ++it1) if((*it1).second.open)
	{
	    const cell_t & cell2 = (*it1).second;
#ifdef WITH_DEBUG
	    if(IS_DEBUG(DBG_OTHER, DBG_TRACE) && cell2.cost_g != MAXU16)
	    {
		direct = Direction::Get(cur, (*it1).first);
		if(Direction::UNKNOWN != direct)
		{
		    VERBOSE("\t\tdirect: " << Direction::String(direct) <<
			    ", index: " << (*it1).first <<
			    ", cost g: " << cell2.cost_g <<
			    ", cost t: " << cell2.cost_t <<
			    ", cost d: " << cell2.cost_d);
		}
	    }
#endif

	    if(cell2.cost_t + cell2.cost_d < tmp)
	    {
    		tmp = cell2.cost_t + cell2.cost_d;
    		alt = (*it1).first;
	    }
	}

	// not found, and exception
	if(MAXU16 == tmp || -1 == alt || (limit && GetCurrentLength(list, cur) > limit)) break;
#ifdef WITH_DEBUG
	else
	DEBUG(DBG_OTHER, DBG_TRACE, "select: " << alt);
#endif
	cur = alt;
    }

    // save path
    if(cur == to)
    {
	while(cur != from)
	{
	    if(-1 == list[cur].parent) break;
	    alt = cur;
    	    cur = list[alt].parent;
	    if(result) result->push_front(Route::Step(cur, Direction::Get(cur, alt), list[alt].cost_g));
	}
        return true;
    }

    DEBUG(DBG_OTHER, DBG_TRACE, "not found" << ", from:" << from << ", to: " << to);
    list.clear();

    return false;
}
Battle::Result Battle::Loader(Army & army1, Army & army2, s32 mapsindex)
{
    const Settings & conf = Settings::Get();

    // pre battle army1
    if(army1.GetCommander())
    {
	if(CONTROL_AI & army1.GetControl())
    	    AI::HeroesPreBattle(*army1.GetCommander());
        else
	    army1.GetCommander()->ActionPreBattle();
    }

    // pre battle army2
    if(army2.GetCommander())
    {
	if(CONTROL_AI & army2.GetControl())
    	    AI::HeroesPreBattle(*army2.GetCommander());
        else
	    army2.GetCommander()->ActionPreBattle();
    }

    if(conf.ExtPocketLowMemory())
        AGG::ICNRegistryEnable(true);

    AGG::ResetMixer();
    bool local = (CONTROL_HUMAN & army1.GetControl()) || (CONTROL_HUMAN & army2.GetControl()) || IS_DEBUG(DBG_BATTLE, DBG_TRACE);

    Arena arena(army1, army2, mapsindex, local);

    DEBUG(DBG_BATTLE, DBG_INFO, "army1 " << army1.String());
    DEBUG(DBG_BATTLE, DBG_INFO, "army2 " << army2.String());

    while(arena.BattleValid())
	arena.Turns();

    const Result & result = arena.GetResult();
    AGG::ResetMixer();

    HeroBase* hero_wins = (result.army1 & RESULT_WINS ? army1.GetCommander() : (result.army2 & RESULT_WINS ? army2.GetCommander() : NULL));
    HeroBase* hero_loss = (result.army1 & RESULT_LOSS ? army1.GetCommander() : (result.army2 & RESULT_LOSS ? army2.GetCommander() : NULL));
    const u8 loss_result =  result.army1 & RESULT_LOSS ? result.army1 : result.army2;

    if(local)
    {
	// fade arena
	arena.FadeArena();

	// dialog summary
	arena.DialogBattleSummary(result);
    }

    // save count troop
    arena.GetForce1().SyncArmyCount();
    arena.GetForce2().SyncArmyCount();

    // after battle army1
    if(army1.GetCommander())
    {
	if(CONTROL_AI & army1.GetControl())
    	    AI::HeroesAfterBattle(*army1.GetCommander());
        else
	    army1.GetCommander()->ActionAfterBattle();
    }

    // after battle army2
    if(army2.GetCommander())
    {
	if(CONTROL_AI & army2.GetControl())
    	    AI::HeroesAfterBattle(*army2.GetCommander());
        else
	    army2.GetCommander()->ActionAfterBattle();
    }

    // pickup artifact
    if(hero_wins && hero_loss &&
	!((RESULT_RETREAT | RESULT_SURRENDER) & loss_result) &&
	Skill::Primary::HEROES == hero_wins->GetType() &&
	Skill::Primary::HEROES == hero_loss->GetType())
	PickupArtifactsAction(*hero_wins, *hero_loss, (CONTROL_HUMAN & hero_wins->GetControl()));

    // eagle eye capability
    if(hero_wins && hero_loss &&
	hero_wins->GetLevelSkill(Skill::Secondary::EAGLEEYE) &&
	Skill::Primary::HEROES == hero_loss->GetType())
	    EagleEyeSkillAction(*hero_wins, arena.GetUsageSpells(), (CONTROL_HUMAN & hero_wins->GetControl()));

    // necromancy capability
    if(hero_wins &&
	hero_wins->GetLevelSkill(Skill::Secondary::NECROMANCY))
	    NecromancySkillAction(*hero_wins, result.killed, (CONTROL_HUMAN & hero_wins->GetControl()));

    DEBUG(DBG_BATTLE, DBG_INFO, "army1 " << army1.String());
    DEBUG(DBG_BATTLE, DBG_INFO, "army2 " << army1.String());

    // update army
    if(army1.GetCommander() && Skill::Primary::HEROES == army1.GetCommander()->GetType())
    {
	// hard reset army
	if(!army1.isValid() || (result.army1 & RESULT_RETREAT)) army1.Reset(false);
    }

    // update army
    if(army2.GetCommander() && Skill::Primary::HEROES == army2.GetCommander()->GetType())
    {
	// hard reset army
        if(!army2.isValid() || (result.army2 & RESULT_RETREAT)) army2.Reset(false);
    }

    if(conf.ExtPocketLowMemory())
    {
        AGG::ICNRegistryEnable(false);
        AGG::ICNRegistryFreeObjects();
    }

    DEBUG(DBG_BATTLE, DBG_INFO, "army1: " << (result.army1 & RESULT_WINS ? "wins" : "loss") << ", army2: " << (result.army2 & RESULT_WINS ? "wins" : "loss"));

    return result;
}
Example #4
0
Battle::Result Battle::Loader(Army & army1, Army & army2, s32 mapsindex)
{
    // pre battle army1
    if(army1.GetCommander())
    {
	if(army1.GetCommander()->isCaptain())
	    army1.GetCommander()->ActionPreBattle();
	else
	if(army1.isControlAI())
    	    AI::HeroesPreBattle(*army1.GetCommander());
        else
	    army1.GetCommander()->ActionPreBattle();
    }

    // pre battle army2
    if(army2.GetCommander())
    {
	if(army2.GetCommander()->isCaptain())
	    army2.GetCommander()->ActionPreBattle();
	else
	if(army2.isControlAI())
    	    AI::HeroesPreBattle(*army2.GetCommander());
        else
	    army2.GetCommander()->ActionPreBattle();
    }

    AGG::ResetMixer();
    bool local = army1.isControlHuman() || army2.isControlHuman();

#ifdef DEBUG
    if(IS_DEBUG(DBG_BATTLE, DBG_TRACE)) local = true;
#endif

    Arena arena(army1, army2, mapsindex, local);

    DEBUG(DBG_BATTLE, DBG_INFO, "army1 " << army1.String());
    DEBUG(DBG_BATTLE, DBG_INFO, "army2 " << army2.String());

    while(arena.BattleValid())
	arena.Turns();

    const Result & result = arena.GetResult();
    AGG::ResetMixer();

    HeroBase* hero_wins = (result.army1 & RESULT_WINS ? army1.GetCommander() : (result.army2 & RESULT_WINS ? army2.GetCommander() : NULL));
    HeroBase* hero_loss = (result.army1 & RESULT_LOSS ? army1.GetCommander() : (result.army2 & RESULT_LOSS ? army2.GetCommander() : NULL));
    const u32 loss_result =  result.army1 & RESULT_LOSS ? result.army1 : result.army2;

    if(local)
    {
	// fade arena
	arena.FadeArena();

	// dialog summary
	arena.DialogBattleSummary(result);
    }

    // save count troop
    arena.GetForce1().SyncArmyCount();
    arena.GetForce2().SyncArmyCount();

    // after battle army1
    if(army1.GetCommander())
    {
	if(army1.isControlAI())
    	    AI::HeroesAfterBattle(*army1.GetCommander());
        else
	    army1.GetCommander()->ActionAfterBattle();
    }

    // after battle army2
    if(army2.GetCommander())
    {
	if(army2.isControlAI())
    	    AI::HeroesAfterBattle(*army2.GetCommander());
        else
	    army2.GetCommander()->ActionAfterBattle();
    }

    // pickup artifact
    if(hero_wins && hero_loss &&
	!((RESULT_RETREAT | RESULT_SURRENDER) & loss_result) &&
	hero_wins->isHeroes() &&
	hero_loss->isHeroes())
	PickupArtifactsAction(*hero_wins, *hero_loss, hero_wins->isControlHuman());

    // eagle eye capability
    if(hero_wins && hero_loss &&
	hero_wins->GetLevelSkill(Skill::Secondary::EAGLEEYE) &&
	hero_loss->isHeroes())
	    EagleEyeSkillAction(*hero_wins, arena.GetUsageSpells(), hero_wins->isControlHuman());

    // necromancy capability
    if(hero_wins &&
	hero_wins->GetLevelSkill(Skill::Secondary::NECROMANCY))
	    NecromancySkillAction(*hero_wins, result.killed, hero_wins->isControlHuman());

    DEBUG(DBG_BATTLE, DBG_INFO, "army1 " << army1.String());
    DEBUG(DBG_BATTLE, DBG_INFO, "army2 " << army1.String());

    // update army
    if(army1.GetCommander() && army1.GetCommander()->isHeroes())
    {
	// hard reset army
	if(!army1.isValid() || (result.army1 & RESULT_RETREAT)) army1.Reset(false);
    }

    // update army
    if(army2.GetCommander() && army2.GetCommander()->isHeroes())
    {
	// hard reset army
        if(!army2.isValid() || (result.army2 & RESULT_RETREAT)) army2.Reset(false);
    }

    DEBUG(DBG_BATTLE, DBG_INFO, "army1: " << (result.army1 & RESULT_WINS ? "wins" : "loss") << ", army2: " << (result.army2 & RESULT_WINS ? "wins" : "loss"));

    return result;
}
bool Route::Path::Find(s32 to, int limit)
{
    const int pathfinding = hero->GetLevelSkill(Skill::Secondary::PATHFINDING);
    const s32 from = hero->GetIndex();

    s32 cur = from;
    s32 alt = 0;
    s32 tmp = 0;
    std::map<s32, cell_t> list;
    std::map<s32, cell_t>::iterator it1 = list.begin();
    std::map<s32, cell_t>::iterator it2 = list.end();

    list[cur].cost_g = 0;
    list[cur].cost_t = 0;
    list[cur].parent = -1;
    list[cur].open   = 0;

    const Directions directions = Direction::All();
    clear();

    while(cur != to)
    {
	LocalEvent::Get().HandleEvents(false);
    	for(Directions::const_iterator
	    it = directions.begin(); it != directions.end(); ++it)
	{
    	    if(Maps::isValidDirection(cur, *it))
	    {
		tmp = Maps::GetDirectionIndex(cur, *it);

		if(list[tmp].open)
		{
		    const u32 costg = GetPenaltyFromTo(cur, tmp, *it, pathfinding);

		    // new
		    if(-1 == list[tmp].parent)
		    {
			if((list[cur].passbl & *it) ||
			   PassableFromToTile(*hero, cur, tmp, *it, to))
			{
			    list[cur].passbl |= *it;

			    list[tmp].direct = *it;
	    		    list[tmp].cost_g = costg;
			    list[tmp].parent = cur;
			    list[tmp].open   = 1;
			    list[tmp].cost_d = 50 * Maps::GetApproximateDistance(tmp, to);
	    		    list[tmp].cost_t = list[cur].cost_t + costg;
			}
		    }
		    // check alt
		    else
		    {
			if(list[tmp].cost_t > list[cur].cost_t + costg &&
			   ((list[cur].passbl & *it) || PassableFromToTile(*hero, cur, tmp, *it, to)))
			{
			    list[cur].passbl |= *it;

			    list[tmp].direct = *it;
			    list[tmp].parent = cur;
			    list[tmp].cost_g = costg;
			    list[tmp].cost_t = list[cur].cost_t + costg;
			}
		    }
    		}
	    }
	}

	list[cur].open = 0;

	it1 = list.begin();
	alt = -1;
	tmp = MAXU16;

	DEBUG(DBG_OTHER, DBG_TRACE, "route, from: " << cur);

	// find minimal cost
	for(; it1 != it2; ++it1) if((*it1).second.open)
	{
	    const cell_t & cell2 = (*it1).second;
#ifdef WITH_DEBUG
	    if(IS_DEBUG(DBG_OTHER, DBG_TRACE) && cell2.cost_g != MAXU16)
	    {
		int direct = Direction::Get(cur, (*it1).first);

		if(Direction::UNKNOWN != direct)
		{
		    VERBOSE("\t\tdirect: " << Direction::String(direct) <<
			    ", index: " << (*it1).first <<
			    ", cost g: " << cell2.cost_g <<
			    ", cost t: " << cell2.cost_t <<
			    ", cost d: " << cell2.cost_d);
		}
	    }
#endif

	    if(cell2.cost_t + cell2.cost_d < tmp)
	    {
    		tmp = cell2.cost_t + cell2.cost_d;
    		alt = (*it1).first;
	    }
	}

	// not found, and exception
	if(MAXU16 == tmp || -1 == alt) break;
#ifdef WITH_DEBUG
	else
	DEBUG(DBG_OTHER, DBG_TRACE, "select: " << alt);
#endif
	cur = alt;

	if(0 < limit && GetCurrentLength(list, cur) > limit) break;
    }

    // save path
    if(cur == to)
    {
	while(cur != from)
	{
	    push_front(Route::Step(list[cur].parent, list[cur].direct, list[cur].cost_g));
    	    cur = list[cur].parent;
	}
    }
    else
    {
	DEBUG(DBG_OTHER, DBG_TRACE, "not found" << ", from:" << from << ", to: " << to);
    }

    return !empty();
}