/** @file /world/world_engine.h Vykona trida realizujici dotazy a zmeny na objektu World a jeho komponentach. @see /world/world_client.h @see /world/world.h @author Petr Wolf */ #ifndef WORLD_WORLD_ENGINE_H #define WORLD_WORLD_ENGINE_H #include #include "common/mm.h" #include "common/mutex.h" #include "common/TCL/tcl_script.h" #include "world/world_messages.h" #include "world/world.h" #include "world/history.h" #include "ai/PathFind/pathenv.h" namespace World { /** Realizace "read-only" pravidel nad objektem sveta. Trida, ktera implementuje jednotlive casti pravidel. Nezasahuje primo do reprezentace sveta, pouze "odpovida" na jednotlive dotazy vyhodnocujici dosah pohybu atd. */ class TWorldEngine : public TMutex { protected: TWorld & _world; public: TTCL_Interpreter interpreter; /** Konstruktor @param world ukazatel na svet, nad kterym ma engine pocitat */ TWorldEngine(TWorld * world); /** Destruktor */ ~TWorldEngine(); /** Inicializace */ void init(TWorld * world); /// Zamceni mutexu int lock(); /// Odemceni mutexu int unlock(); /** Vypocet dosahu pohuby jednotky. @param unit_id ID jednotky @return seznam hexu (jejich ID), kam jednotka muze vstoupit */ TIntContainer * getRange(int unit_id); /** Vypocet moznych cilu utoku jednotky @param unit_id ID utocici jednotky @return seznam hexu (jejich ID), na ktere muze jednotka zautocit s prihlednutim k tomu, co na nich je */ TIntContainer getAttackRange(int unit_id); /** Vypocet oblasti, ze ktereho muze \c attacker zautocit na policko \c target @param unit_id id jednotky utocnika @param hex_id id hexu, ktery ma byt napaden @return seznam hexu (jejich ID), ze kterych muze jednotka napadnout dany hex */ TIntContainer getInverseAttackRange(UNIT_ID unit_id, HEX_ID hex_id); /** Spocitani ceny za pohyb z hexu na sousedni hex. Funkce nevychazi z aktualni pozice jednotky, ale pocita obecne cenu za pohyb z hexu X na hex Y. Pokud by jednotka provedenim tohoto pohybu vstoupila do budovy ci do sfery vlivu cizi jednotky nebo ciziho mesta, bude jako cena pohybu vracen pocet zbyvajicich bodu pohybu. Funkce je pouzita pri PATHFIND vypoctech. @param unit_id ID jednotky @param points_of_movement dosud utracene body pohybu jednotky @param from ID startovniho hexu @param to ID ciloveho hexu @param transparency pruhlednost, se kterou se cesta pocita. Umoznuje AI planovat delsi cesty a ignorovat pritom vlastni jednotky, reky atd. @return cena za pohyb (v bodech pohybu) */ int getDistance(int unit_id, int points_of_movement, int from, int to, ai_ns::pathfind_ns::TGetCostTransparency transparency = ai_ns::pathfind_ns::GCT_UnitsNotTransparent); /** Spocitani dohledu jednotky. Funkce projde okoli jednotky a spocita seznam hexu, na ktere jednotka ze sve momentalni pozice vidi. @param unit_id ID jednotky @param hex_id Pozice jednotky, ze ktere se viditelnost pocita. Implicitne jeji aktualni pozice. @return seznam hexu, na ktere jednotka momentalne vidi */ TIntContainer * getUnitVisibility(int unit_id, int hex_id = -1); /** Spocitani dohledu budovy. Funkce projde okoli budovy a spocita seznam hexu, na ktere budova ze sve pozice vidi. @param building_id ID budovy @return seznam hexu, na ktere budova vidi */ TIntContainer * getBuildingVisibility(int building_id); /** Spocitani dohledu mesta. Funkce projde plochu a okoli mesta a spocita seznam hexu, na ktere budova ze sve pozice vidi. @param town_id ID mesta @return seznam hexu, na ktere mesto vidi */ TIntContainer * getTownVisibility(int town_id); /** Seznam moznych umisteni budovy. Funkce vyhleda hexy, na kterych muze dana jednotka postavit dany typ budovy. */ std::vector getBuildingRange(int unit_id, int building_type); /** Seznam moznych cilu pro opravu. Funkce vyhleda hexy, na kterych je mozno opravovat budovy. */ TIntContainer getRepairRange(UNIT_ID unit_id); int getUnitActions(UNIT_ID unit_id, int actions[], std::vector & buildings); int getBuildingActions(BUILDING_ID building_id, int actions[], std::vector & recruitment, std::vector & bonuses); }; /** Kompletni reprezentace pravidel nad objektem sveta. Trida reprezentuje celkovy soubor pravidel, vyhodnocuje vsechny akce. Akce menici stav sveta rovnou zaznamenava do dat, soucasne plni zasobnik historie. Jeden objekt teto tridy je inicializovan na serveru. */ class TWorldServerEngine : public TWorldEngine { private: THistory & _history; void removeUnitVisibility(int unit_id, TIntContainer & hidden); void removeBuildingVisibility(int building_id, TIntContainer & hidden); void removeTownVisibility(int town_id, TIntContainer & hidden); public: TWorldServerEngine(TWorld * world, THistory * history); ~TWorldServerEngine(); /** Akce - sebezniceni jednotky */ int unitSuicide(int unit_id); /** Akce - sebezniceni budovy */ int buildingSuicide(int building_id); /** Akce - vyroba jednotky */ int buildingRecruitUnit(int building_id, int unit_type); /** Akce - zahajeni stavby */ int startBuilding(int unit_id, int building_type, int location, int orientation); /** Akce - oprava budovy */ int repairBuilding(int unit_id, int building_id); /** Akce - preruseni stavby */ int stopBuilding(int unit_id); /** Akce - prodej bonusu jednotce v budove */ int sellBonus(int building_id, int bonus_id); /** Akce - pohyb jednotky. @param unit_id ID jednotky @param to ID ciloveho hexu @param transparency transparence, se kterou se pocita cesta, po ktere jednotka pujde */ int unitMove(int unit_id, int to, ai_ns::pathfind_ns::TPathFindTransparency transparency = ai_ns::pathfind_ns::PFT_UnitsNotTransparent); /** Akce - utok jednotky @param attacker ID utocici jednotky @param target ID napadeneho hexu */ int unitAttack(int attacker, int target); /** Akce - leceni jednotky @param unit_id ID lecene jednotky */ int unitHeal(int unit_id); /** Akce - doplneni jednotky (neelitni) @param unit_id ID doplnovane jednotky */ int unitRecruit(int unit_id); /** Akce - doplneni jednotky (elitni) @param unit_id ID doplnovane jednotky */ int unitRecruitElite(int unit_id); void buildingOccuppied(int building_id, int new_player_id); /** Sekvence akci, ktere je nutne provest pri obsazeni mesta. Metoda zmeni majitele mesta, upravi viditelnost, zaznamena udalost do statistik a upozorni modul diplomacie. @param town_id id mesta, ktere bylo obsazeno @param new_player_id ID hrace, ktery mesto obsadil */ void townOccuppied(int town_id, int new_player_id); /** Sekvence akci, ktere je nutne provest pri obsazeni kralovstvi. Metoda zmeni majitele kralovstvi a zaznamena udalost do statistik. @param kingdom_id id kralovstvi, ktere bylo obsazeno @param new_player_id ID hrace, ktery kralovstvi obsadil */ void kingdomOccuppied(int kingdom_id, int new_player_id); /** Akce - ukonceni tahu */ int nextTurn(); /** Test, zda hrac neprohral */ int playerDefeatedTest(PLAYER_ID player_id); /** Test, zda nedoslo k ukonceni hry @retval true hra skoncila @retval false hra pokracuje */ bool endGameTest(); /** Souhrnny test na porazewni hrace a ukonceni hry @see playerDefeatedTest() @see endGameTest() @param player1_id ID hrace, u ktereho se neco menilo (0, nema-li to smysl) @param player2_id ID dalsiho hrace, ktereho se zmena tykala (0, nema-li to smysl) @retval true hra skoncila @retval false hra pokracuje */ bool finalTest(PLAYER_ID player1_id = 0, PLAYER_ID player2_id = 0); /** Ukonceni hry @param reason duvod k ukonceni @param winner vitez hry, existuje-li */ int endGame(ENDGAME_REASON reason, PLAYER_ID winner = 0); /** Spocitani aktualni viditelnosti pro jednotlive hrace */ void calculateVisibility(); }; }; #endif /*****************************************************************************/