1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

* added an initial version of adventure AI: VCAI, more details here: http://forum.vcmi.eu/viewtopic.php?p=6508#6508

* VCAI set as default adventure AI
* several adjustments in GUI (hourglass during AI turn), minor changes
This commit is contained in:
Michał W. Urbańczyk 2012-02-14 18:04:45 +00:00
parent f7ac873303
commit 7a66c1bf2b
14 changed files with 3109 additions and 44 deletions

1
AI/VCAI/StdInc.cpp Normal file
View File

@ -0,0 +1 @@
#include "StdInc.h"

41
AI/VCAI/StdInc.h Normal file
View File

@ -0,0 +1,41 @@
#pragma once
#include "../../Global.h"
#include <cassert>
#include <boost/lexical_cast.hpp>
#include <boost/format.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/type_traits.hpp>
#include "../../lib/AI_Base.h"
#include "../../CCallback.h"
#include "../../lib/CObjectHandler.h"
#include <boost/foreach.hpp>
#include "../../lib/CThreadHelper.h"
#include <boost/thread/tss.hpp>
#include "../../lib/VCMI_Lib.h"
#include "../../lib/CBuildingHandler.h"
#include "../../lib/CCreatureHandler.h"
#include "../../lib/CTownHandler.h"
#include "../../lib/CSpellHandler.h"
#include "../../lib/CObjectHandler.h"
#include "../../lib/Connection.h"
#include "../../lib/CGameState.h"
#include "../../lib/map.h"
#include "../../lib/NetPacks.h"
#include "../../lib/CondSh.h"
#include "../../lib/CStopWatch.h"
#include <fstream>
#include <queue>
using boost::format;
using boost::str;
#define INDENT AILogger::Tab ___dummy_ind
#define PNLOG(txt) {int i = logger.lvl; while(i--) printf("\t"); tlog4 << txt; printf("\n");}
#define BNLOG(txt, formattingEls) {int i = logger.lvl; while(i--) printf("\t"); tlog4 << (boost::format(txt) % formattingEls); printf("\n");}
//#define LOG_ENTRY PNLOG("Entered " __FUNCTION__)
#define LOG_ENTRY

2482
AI/VCAI/VCAI.cpp Normal file

File diff suppressed because it is too large Load Diff

284
AI/VCAI/VCAI.h Normal file
View File

@ -0,0 +1,284 @@
#pragma once
typedef const int3& crint3;
typedef const std::string& crstring;
enum BattleState
{
NO_BATTLE,
UPCOMING_BATTLE,
ONGOING_BATTLE,
ENDING_BATTLE
};
class AIStatus
{
boost::mutex mx;
boost::condition_variable cv;
BattleState battle;
int remainingQueries;
bool havingTurn;
public:
AIStatus();
~AIStatus();
void setBattle(BattleState BS);
BattleState getBattle();
void addQueries(int val);
void addQuery();
void removeQuery();
int getQueriesCount();
void startedTurn();
void madeTurn();
void waitTillFree();
bool haveTurn();
};
enum EGoals
{
INVALID = -1,
WIN, DO_NOT_LOSE, CONQUER, BUILD, EXPLORE,
RECRUIT_HERO,
BUILD_STRUCTURE, //if hero set, then in visited town
COLLECT_RES,
OBJECT_GOALS_BEGIN,
GET_OBJ, //visit or defeat or collect the object
GET_ART_TYPE,
//BUILD_STRUCTURE,
ISSUE_COMMAND,
//hero
//VISIT_OBJ, //hero + tile
VISIT_TILE, //tile, in conjunction with hero elementar; assumes tile is reachable
CLEAR_WAY_TO,
DIG_AT_TILE //elementar with hero on tile
};
struct CGoal;
typedef CGoal TSubgoal;
#define SETTER(type, field) CGoal &set ## field(const type &rhs) { field = rhs; return *this; }
#if 0
#define SETTER
#endif // _DEBUG
enum {LOW_PR = -1};
struct CGoal
{
EGoals goalType;
bool isElementar; SETTER(bool, isElementar)
int priority; SETTER(bool, priority)
virtual TSubgoal whatToDoToAchieve();
bool isBlockedBorderGate(int3 tileToHit);
CGoal(EGoals goal = INVALID) : goalType(goal)
{
priority = 0;
isElementar = false;
objid = -1;
aid = -1;
tile = int3(-1, -1, -1);
hero = NULL;
town = NULL;
}
bool invalid() const;
static TSubgoal goVisitOrLookFor(const CGObjectInstance *obj); //if obj is NULL, then we'll explore
static TSubgoal lookForArtSmart(int aid); //checks non-standard ways of obtaining art (merchants, quests, etc.)
int value; SETTER(int, value)
int resID; SETTER(int, resID)
int objid; SETTER(int, objid)
int aid; SETTER(int, aid)
int3 tile; SETTER(int3, tile)
const CGHeroInstance *hero; SETTER(const CGHeroInstance *, hero)
const CGTownInstance *town; SETTER(const CGTownInstance *, town)
int bid; SETTER(int, bid)
};
enum {NOT_VISIBLE = 0, NOT_CHECKED = 1, NOT_AVAILABLE};
struct SectorMap
{
//a sector is set of tiles that would be mutually reachable if all visitable objs would be passable (incl monsters)
struct Sector
{
int id;
std::vector<int3> tiles;
std::vector<int3> embarkmentPoints; //tiles of other sectors onto which we can (dis)embark
bool water; //all tiles of sector are land or water
Sector()
{
id = -1;
}
};
bool valid; //some kind of lazy eval
std::map<int3, int3> parent;
std::vector<std::vector<std::vector<unsigned char>>> sector;
//std::vector<std::vector<std::vector<unsigned char>>> pathfinderSector;
std::map<int, Sector> infoOnSectors;
SectorMap();
void update();
void clear();
void exploreNewSector(crint3 pos, int num);
void write(crstring fname);
unsigned char &retreiveTile(crint3 pos);
void makeParentBFS(crint3 source);
int3 firstTileToGet(const CGHeroInstance *h, crint3 dst); //if h wants to reach tile dst, which tile he should visit to clear the way?
};
struct CIssueCommand : CGoal
{
boost::function<bool()> command;
CIssueCommand(boost::function<bool()> _command) : command(_command), CGoal(ISSUE_COMMAND) {}
};
class VCAI : public CAdventureAI
{
public:
std::map<const CGObjectInstance *, const CGObjectInstance *> knownSubterraneanGates;
std::vector<const CGObjectInstance *> visitedThisWeek; //only OPWs
std::map<const CGHeroInstance *, std::vector<const CGTownInstance *> > townVisitsThisWeek;
std::set<const CGHeroInstance *> blockedHeroes; //they won't get any new action
std::vector<const CGObjectInstance *> visitableObjs;
std::vector<const CGObjectInstance *> alreadyVisited;
TResources saving;
AIStatus status;
std::string battlename;
CCallback *myCb;
VCAI(void);
~VCAI(void);
CGoal currentGoal;
boost::thread *makingTurn;
void tryRealize(CGoal g);
int3 explorationBestNeighbour(int3 hpos, int radius, const CGHeroInstance * h);
int3 explorationNewPoint(int radius, const CGHeroInstance * h, std::vector<std::vector<int3> > &tiles);
void recruitHero();
virtual void init(CCallback * CB);
virtual void yourTurn();
virtual void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback) OVERRIDE; //pskill is gained primary skill, interface has to choose one of given skills and call callback with selection id
virtual void showBlockingDialog(const std::string &text, const std::vector<Component> &components, ui32 askID, const int soundID, bool selection, bool cancel) OVERRIDE; //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID.
virtual void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, boost::function<void()> &onEnd) OVERRIDE; //all stacks operations between these objects become allowed, interface has to call onEnd when done
virtual void serialize(COSer<CSaveFile> &h, const int version) OVERRIDE; //saving
virtual void serialize(CISer<CLoadFile> &h, const int version) OVERRIDE; //loading
virtual void availableCreaturesChanged(const CGDwelling *town) OVERRIDE;
virtual void heroMoved(const TryMoveHero & details) OVERRIDE;
virtual void stackChagedCount(const StackLocation &location, const TQuantity &change, bool isAbsolute) OVERRIDE;
virtual void heroInGarrisonChange(const CGTownInstance *town) OVERRIDE;
virtual void centerView(int3 pos, int focusTime) OVERRIDE;
virtual void tileHidden(const boost::unordered_set<int3, ShashInt3> &pos) OVERRIDE;
virtual void artifactMoved(const ArtifactLocation &src, const ArtifactLocation &dst) OVERRIDE;
virtual void artifactAssembled(const ArtifactLocation &al) OVERRIDE;
virtual void showTavernWindow(const CGObjectInstance *townOrTavern) OVERRIDE;
virtual void playerBlocked(int reason) OVERRIDE;
virtual void showPuzzleMap() OVERRIDE;
virtual void showShipyardDialog(const IShipyard *obj) OVERRIDE;
virtual void gameOver(ui8 player, bool victory) OVERRIDE;
virtual void artifactPut(const ArtifactLocation &al) OVERRIDE;
virtual void artifactRemoved(const ArtifactLocation &al) OVERRIDE;
virtual void stacksErased(const StackLocation &location) OVERRIDE;
virtual void artifactDisassembled(const ArtifactLocation &al) OVERRIDE;
virtual void heroVisit(const CGHeroInstance *visitor, const CGObjectInstance *visitedObj, bool start) OVERRIDE;
virtual void availableArtifactsChanged(const CGBlackMarket *bm = NULL) OVERRIDE;
virtual void heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town) OVERRIDE;
virtual void tileRevealed(const boost::unordered_set<int3, ShashInt3> &pos) OVERRIDE;
virtual void heroExchangeStarted(si32 hero1, si32 hero2) OVERRIDE;
virtual void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, si64 val) OVERRIDE;
virtual void showRecruitmentDialog(const CGDwelling *dwelling, const CArmedInstance *dst, int level) OVERRIDE;
virtual void heroMovePointsChanged(const CGHeroInstance * hero) OVERRIDE;
virtual void stackChangedType(const StackLocation &location, const CCreature &newType) OVERRIDE;
virtual void stacksRebalanced(const StackLocation &src, const StackLocation &dst, TQuantity count) OVERRIDE;
virtual void newObject(const CGObjectInstance * obj) OVERRIDE;
virtual void showHillFortWindow(const CGObjectInstance *object, const CGHeroInstance *visitor) OVERRIDE;
virtual void playerBonusChanged(const Bonus &bonus, bool gain) OVERRIDE;
virtual void newStackInserted(const StackLocation &location, const CStackInstance &stack) OVERRIDE;
virtual void heroCreated(const CGHeroInstance*) OVERRIDE;
virtual void advmapSpellCast(const CGHeroInstance * caster, int spellID) OVERRIDE;
virtual void showInfoDialog(const std::string &text, const std::vector<Component*> &components, int soundID) OVERRIDE;
virtual void requestRealized(PackageApplied *pa) OVERRIDE;
virtual void receivedResource(int type, int val) OVERRIDE;
virtual void stacksSwapped(const StackLocation &loc1, const StackLocation &loc2) OVERRIDE;
virtual void objectRemoved(const CGObjectInstance *obj) OVERRIDE;
virtual void showUniversityWindow(const IMarket *market, const CGHeroInstance *visitor) OVERRIDE;
virtual void heroManaPointsChanged(const CGHeroInstance * hero) OVERRIDE;
virtual void heroSecondarySkillChanged(const CGHeroInstance * hero, int which, int val) OVERRIDE;
virtual void battleResultsApplied() OVERRIDE;
virtual void objectPropertyChanged(const SetObjectProperty * sop) OVERRIDE;
virtual void buildChanged(const CGTownInstance *town, int buildingID, int what) OVERRIDE;
virtual void heroBonusChanged(const CGHeroInstance *hero, const Bonus &bonus, bool gain) OVERRIDE;
virtual void showMarketWindow(const IMarket *market, const CGHeroInstance *visitor) OVERRIDE;
virtual void battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side) OVERRIDE;
virtual void battleEnd(const BattleResult *br) OVERRIDE;
void makeTurn();
void makeTurnInternal();
void performTypicalActions();
void buildArmyIn(const CGTownInstance * t);
void striveToGoal(const CGoal &ultimateGoal);
void endTurn();
void wander(const CGHeroInstance * h);
void recruitHero(const CGTownInstance * t);
std::vector<const CGObjectInstance *> getPossibleDestinations(const CGHeroInstance *h);
void buildStructure(const CGTownInstance * t);
void recruitCreatures(const CGTownInstance * t);
void moveCreaturesToHero(const CGTownInstance * t);
bool goVisitObj(const CGObjectInstance * obj, const CGHeroInstance * h);
bool moveHeroToTile(int3 dst, const CGHeroInstance * h);
void waitTillFree();
void addVisitableObj(const CGObjectInstance *obj);
//void removeVisitableObj(const CGObjectInstance *obj);
void validateVisitableObjs();
void retreiveVisitableObjs(std::vector<const CGObjectInstance *> &out, bool includeOwned = false) const;
std::vector<const CGObjectInstance *> getFlaggedObjects() const;
const CGObjectInstance *lookForArt(int aid) const;
bool isAccessible(const int3 &pos);
const CGHeroInstance *getHeroWithGrail() const;
const CGObjectInstance *getUnvisitedObj(const boost::function<bool(const CGObjectInstance *)> &predicate);
bool isAccessibleForHero(const int3 & pos, const CGHeroInstance * h) const;
const CGTownInstance *findTownWithTavern() const;
std::vector<const CGHeroInstance *> getUnblockedHeroes() const;
const CGHeroInstance *primaryHero() const;
TResources estimateIncome() const;
bool containsSavedRes(const TResources &cost) const;
};
template<int id>
bool objWithID(const CGObjectInstance *obj)
{
return obj->ID == id;
}

181
AI/VCAI/VCAI.vcxproj Normal file
View File

@ -0,0 +1,181 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="RD|Win32">
<Configuration>RD</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="RD|x64">
<Configuration>RD</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{276C3DB0-7A6B-4417-8E5C-322B08633AAC}</ProjectGuid>
<RootNamespace>StupidAI</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RD|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RD|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\VCMI_global.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\VCMI_global.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='RD|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\VCMI_global.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='RD|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\VCMI_global.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SolutionDir)\AI\</OutDir>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(SolutionDir)\AI\</OutDir>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RD|Win32'">
<OutDir>$(SolutionDir)$(Configuration)\bin\AI\</OutDir>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RD|x64'">
<OutDir>$(SolutionDir)$(Configuration)\bin\AI\</OutDir>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile>
<AdditionalOptions>/Zm150 %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OutDir)..;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<OutputFile>$(OutDir)VCAI.dll</OutputFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile>
<AdditionalOptions>/Zm150 %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OutDir)..;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<OutputFile>$(OutDir)VCAI.dll</OutputFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='RD|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile>
<AdditionalOptions>/Zm150 %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OutDir)..;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<OutputFile>$(OutDir)VCAI.dll</OutputFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='RD|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>StdInc.h</PrecompiledHeaderFile>
<AdditionalOptions>/Zm150 %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>VCMI_lib.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OutDir)..;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<OutputFile>$(OutDir)StupidAI.dll</OutputFile>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="main.cpp" />
<ClCompile Include="StdInc.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='RD|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='RD|x64'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="VCAI.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="StdInc.h" />
<ClInclude Include="VCAI.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

23
AI/VCAI/main.cpp Normal file
View File

@ -0,0 +1,23 @@
#include "StdInc.h"
#include "VCAI.h"
#ifdef __GNUC__
#define strcpy_s(a, b, c) strncpy(a, c, b)
#endif
const char *g_cszAiName = "VCAI";
extern "C" DLL_EXPORT int GetGlobalAiVersion()
{
return AI_INTERFACE_VER;
}
extern "C" DLL_EXPORT void GetAiName(char* name)
{
strcpy_s(name, strlen(g_cszAiName) + 1, g_cszAiName);
}
extern "C" DLL_EXPORT CGlobalAI* GetNewAI()
{
return new VCAI();
}

View File

@ -799,7 +799,8 @@ void CResDataBar::showAll(SDL_Surface * to)
CInfoBar::CInfoBar() CInfoBar::CInfoBar()
{ {
toNextTick = mode = pom = -1; toNextTick = pom = -1;
mode = NOTHING;
pos.x=ADVOPT.infoboxX; pos.x=ADVOPT.infoboxX;
pos.y=ADVOPT.infoboxY; pos.y=ADVOPT.infoboxY;
pos.w=194; pos.w=194;
@ -809,6 +810,8 @@ CInfoBar::CInfoBar()
week2 = CDefHandler::giveDef("NEWWEEK2.DEF"); week2 = CDefHandler::giveDef("NEWWEEK2.DEF");
week3 = CDefHandler::giveDef("NEWWEEK3.DEF"); week3 = CDefHandler::giveDef("NEWWEEK3.DEF");
week4 = CDefHandler::giveDef("NEWWEEK4.DEF"); week4 = CDefHandler::giveDef("NEWWEEK4.DEF");
hourglass = CDefHandler::giveDef("HOURGLAS.DEF");
hourglassSand = CDefHandler::giveDef("HOURSAND.DEF");
selInfoWin = NULL; selInfoWin = NULL;
} }
CInfoBar::~CInfoBar() CInfoBar::~CInfoBar()
@ -825,51 +828,57 @@ CInfoBar::~CInfoBar()
void CInfoBar::showAll(SDL_Surface * to) void CInfoBar::showAll(SDL_Surface * to)
{ {
if ((mode>=0) && mode<5) if (mode >= NEW_DAY && mode <= NEW_WEEK4)
{ {
blitAnim(mode); blitAnim(mode);
return;
} }
else if (mode==5) else if(mode == ENEMY_TURN)
{ {
mode = -1; CPicture bg("ADSTATOT.bmp");
bg.convertToScreenBPP();
blitAt(graphics->flags->ourImages[enemyTurnInfo.color].bitmap, 20, 51, bg);
int hourglassFrame = enemyTurnInfo.progress * hourglass->ourImages.size();
static int sandFrame = 0;
vstd::amin(hourglassFrame, hourglass->ourImages.size()-1);
blitAt(hourglassSand->ourImages[sandFrame++ % hourglassSand->ourImages.size()].bitmap, 99, 51, bg);
blitAt(hourglass->ourImages[hourglassFrame].bitmap, 99, 51, bg);
blitAtLoc(bg, 8, 11, to);
} }
else if(selInfoWin)
if(selInfoWin)
{ {
blitAt(selInfoWin, pos.x, pos.y, to); blitAt(selInfoWin, pos.x, pos.y, to);
} }
} }
CDefHandler * CInfoBar::getAnim(int mode) CDefHandler * CInfoBar::getAnim(EMode mode)
{ {
switch(mode) switch(mode)
{ {
case 0: case NEW_DAY:
return day; return day;
case 1: case NEW_WEEK1:
return week1; return week1;
case 2: case NEW_WEEK2:
return week2; return week2;
case 3: case NEW_WEEK3:
return week3; return week3;
case 4: case NEW_WEEK4:
return week4; return week4;
default: default:
return NULL; return NULL;
} }
} }
void CInfoBar::blitAnim(int mode)//0 - day, 1 - week void CInfoBar::blitAnim(EMode mode)//0 - day, 1 - week
{ {
CDefHandler * anim = NULL; CDefHandler * anim = NULL;
std::ostringstream txt; std::ostringstream txt;
anim = getAnim(mode); anim = getAnim(mode);
if(mode) //new week animation if(mode > NEW_DAY) //new week animation
{ {
txt << CGI->generaltexth->allTexts[63] << " " << LOCPLINT->cb->getDate(2); txt << CGI->generaltexth->allTexts[63] << " " << LOCPLINT->cb->getDate(2);
} }
else //new day else if(mode == NEW_DAY) //new day
{ {
txt << CGI->generaltexth->allTexts[64] << " " << LOCPLINT->cb->getDate(1); txt << CGI->generaltexth->allTexts[64] << " " << LOCPLINT->cb->getDate(1);
} }
@ -883,26 +892,26 @@ void CInfoBar::newDay(int Day)
{ {
if(LOCPLINT->cb->getDate(1) != 1) if(LOCPLINT->cb->getDate(1) != 1)
{ {
mode = 0; //showing day mode = NEW_DAY; //showing day
} }
else else
{ {
switch(LOCPLINT->cb->getDate(2)) switch(LOCPLINT->cb->getDate(2))
{ {
case 1: case 1:
mode = 1; mode = NEW_WEEK1;
break; break;
case 2: case 2:
mode = 2; mode = NEW_WEEK2;
break; break;
case 3: case 3:
mode = 3; mode = NEW_WEEK3;
break; break;
case 4: case 4:
mode = 4; mode = NEW_WEEK4;
break; break;
default: default:
mode = -1; mode = NOTHING;
break; break;
} }
} }
@ -929,33 +938,30 @@ void CInfoBar::showComp(CComponent * comp, int time)
SDL_FreeSurface(b); SDL_FreeSurface(b);
if(!(active & TIME)) if(!(active & TIME))
activateTimer(); activateTimer();
mode = 6; mode = SHOW_COMPONENT;
toNextTick = time; toNextTick = time;
} }
void CInfoBar::tick() void CInfoBar::tick()
{ {
if(mode >= 0 && mode < 5) if(mode >= NEW_DAY && mode <= NEW_WEEK4) //animation
{ {
pom++; pom++;
if (pom >= getAnim(mode)->ourImages.size()) if (pom >= getAnim(mode)->ourImages.size())
{ {
deactivateTimer(); deactivateTimer();
toNextTick = -1; toNextTick = -1;
mode = 5; mode = NOTHING;
showAll(screen2);
return;
} }
toNextTick = 150; toNextTick = 150;
blitAnim(mode);
} }
else if(mode == 6) else if(mode == SHOW_COMPONENT)
{ {
deactivateTimer(); deactivateTimer();
toNextTick = -1; toNextTick = -1;
mode = 5; mode = NOTHING;
showAll(screen2);
} }
redraw();
} }
void CInfoBar::show(SDL_Surface * to) void CInfoBar::show(SDL_Surface * to)
@ -973,6 +979,9 @@ void CInfoBar::deactivate()
//CIntObject::deactivate(); //CIntObject::deactivate();
if(active & TIME) if(active & TIME)
deactivateTimer(); deactivateTimer();
toNextTick = -1;
mode = NOTHING;
} }
void CInfoBar::updateSelection(const CGObjectInstance *obj) void CInfoBar::updateSelection(const CGObjectInstance *obj)
@ -986,6 +995,17 @@ void CInfoBar::updateSelection(const CGObjectInstance *obj)
selInfoWin = LOCPLINT->infoWin(obj); selInfoWin = LOCPLINT->infoWin(obj);
} }
void CInfoBar::enemyTurn(ui8 color, double progress)
{
mode = ENEMY_TURN;
enemyTurnInfo.color = color;
enemyTurnInfo.progress = progress;
redraw();
if(!(active & TIME))
activateTimer();
toNextTick = 250;
}
CAdvMapInt::CAdvMapInt() CAdvMapInt::CAdvMapInt()
:statusbar(ADVOPT.statusbarX,ADVOPT.statusbarY,ADVOPT.statusbarG), :statusbar(ADVOPT.statusbarX,ADVOPT.statusbarY,ADVOPT.statusbarG),
kingOverview(CGI->generaltexth->zelp[293].first,CGI->generaltexth->zelp[293].second, kingOverview(CGI->generaltexth->zelp[293].first,CGI->generaltexth->zelp[293].second,
@ -1273,7 +1293,6 @@ void CAdvMapInt::deactivate()
townList.deactivate(); townList.deactivate();
terrain.deactivate(); terrain.deactivate();
infoBar.deactivate(); infoBar.deactivate();
infoBar.mode=-1;
if(LOCPLINT->cingconsole->active) //TODO if(LOCPLINT->cingconsole->active) //TODO
LOCPLINT->cingconsole->deactivate(); LOCPLINT->cingconsole->deactivate();

View File

@ -134,22 +134,36 @@ public:
/// Info box which shows next week/day information, hold the current date /// Info box which shows next week/day information, hold the current date
class CInfoBar : public CIntObject class CInfoBar : public CIntObject
{ {
CDefHandler *day, *week1, *week2, *week3, *week4; enum EMode {NOTHING = -1, NEW_DAY, NEW_WEEK1, NEW_WEEK2, NEW_WEEK3, NEW_WEEK4, ____, SHOW_COMPONENT, ENEMY_TURN};
CDefHandler *day, *week1, *week2, *week3, *week4, *hourglass, *hourglassSand;
CComponent * current; CComponent * current;
int pom; int pom;
SDL_Surface *selInfoWin; //info box for selection SDL_Surface *selInfoWin; //info box for selection
CDefHandler * getAnim(int mode); CDefHandler * getAnim(EMode mode);
struct EnemyTurn
{
ui8 color;
double progress; //0-1
EnemyTurn()
{
color = 255;
progress = 0.;
}
} enemyTurnInfo;
public: public:
int mode; EMode mode;
const CGHeroInstance * curSel; const CGHeroInstance * curSel;
CInfoBar(); CInfoBar();
~CInfoBar(); ~CInfoBar();
void newDay(int Day); //start showing new day/week animation void newDay(int Day); //start showing new day/week animation
void showComp(CComponent * comp, int time=5000); void showComp(CComponent * comp, int time=5000);
void enemyTurn(ui8 color, double progress);
void tick(); void tick();
void showAll(SDL_Surface * to); // if specific==0 function draws info about selected hero/town void showAll(SDL_Surface * to); // if specific==0 function draws info about selected hero/town
void blitAnim(int mode);//0 - day, 1 - week void blitAnim(EMode mode);//0 - day, 1 - week
void show(SDL_Surface * to); void show(SDL_Surface * to);
void activate(); void activate();

View File

@ -266,7 +266,7 @@ void CDefFile::loadFrame(size_t frame, size_t group, ImageLoader &loader) const
break; break;
} }
default: default:
tlog0<<"Error: unsupported format of def file:"<<sprite.format<<"\n"; tlog0<<"Error: unsupported format of def file: "<<sprite.format<<"\n";
break; break;
} }
}; };

View File

@ -62,6 +62,7 @@ void processCommand(const std::string &message, CClient *&client);
extern std::queue<SDL_Event*> events; extern std::queue<SDL_Event*> events;
extern boost::mutex eventsM; extern boost::mutex eventsM;
boost::recursive_mutex * CPlayerInterface::pim = new boost::recursive_mutex;
CPlayerInterface * LOCPLINT; CPlayerInterface * LOCPLINT;
@ -232,7 +233,14 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details)
if(!ho) if(!ho)
{ {
//AI hero left the visible area (we can't obtain info) //AI hero left the visible area (we can't obtain info)
//TODO - probably needs some handling //TODO very evil workaround -> retreive pointer to hero so we could animate it
// TODO -> we should not need full CGHeroInstance structure to display animation or it should not be handled by playerint (but by the client itself)
const TerrainTile2 &tile = CGI->mh->ttiles[hp.x-1][hp.y][hp.z];
for(int i = 0; i < tile.objects.size(); i++)
if(tile.objects[i].first->id == details.id)
ho = dynamic_cast<const CGHeroInstance *>(tile.objects[i].first);
if(!ho) //still nothing...
return; return;
} }
@ -2334,7 +2342,17 @@ void CPlayerInterface::artifactDisassembled(const ArtifactLocation &al)
} }
} }
boost::recursive_mutex * CPlayerInterface::pim = new boost::recursive_mutex; void CPlayerInterface::playerStartsTurn(ui8 player)
{
if(player != playerID && this == LOCPLINT)
{
adventureInt->minimap.redraw();
adventureInt->infoBar.enemyTurn(player, 0.5);
//TODO AI turn music
//TODO block GUI
}
}
CPlayerInterface::SpellbookLastSetting::SpellbookLastSetting() CPlayerInterface::SpellbookLastSetting::SpellbookLastSetting()
{ {

View File

@ -169,6 +169,7 @@ public:
void objectPropertyChanged(const SetObjectProperty * sop) OVERRIDE; void objectPropertyChanged(const SetObjectProperty * sop) OVERRIDE;
void objectRemoved(const CGObjectInstance *obj) OVERRIDE; void objectRemoved(const CGObjectInstance *obj) OVERRIDE;
void gameOver(ui8 player, bool victory) OVERRIDE; void gameOver(ui8 player, bool victory) OVERRIDE;
void playerStartsTurn(ui8 player) OVERRIDE;
void serialize(COSer<CSaveFile> &h, const int version) OVERRIDE; //saving void serialize(COSer<CSaveFile> &h, const int version) OVERRIDE; //saving
void serialize(CISer<CLoadFile> &h, const int version) OVERRIDE; //loading void serialize(CISer<CLoadFile> &h, const int version) OVERRIDE; //loading

View File

@ -130,7 +130,7 @@
}, },
"playerAI" : { "playerAI" : {
"type" : "string", "type" : "string",
"default" : "GeniusAI" "default" : "VCAI"
}, },
"neutralAI" : { "neutralAI" : {
"type" : "string", "type" : "string",

View File

@ -6896,7 +6896,7 @@ std::vector<int> IMarket::availableItemsIds(EMarketMode::EMarketMode mode) const
return ret; return ret;
} }
const IMarket * IMarket::castFrom(const CGObjectInstance *obj) const IMarket * IMarket::castFrom(const CGObjectInstance *obj, bool verbose /*= true*/)
{ {
switch(obj->ID) switch(obj->ID)
{ {
@ -6911,6 +6911,7 @@ const IMarket * IMarket::castFrom(const CGObjectInstance *obj)
case 104: //University case 104: //University
return static_cast<const CGUniversity*>(obj); return static_cast<const CGUniversity*>(obj);
default: default:
if(verbose)
tlog1 << "Cannot cast to IMarket object with ID " << obj->ID << std::endl; tlog1 << "Cannot cast to IMarket object with ID " << obj->ID << std::endl;
return NULL; return NULL;
} }

View File

@ -135,7 +135,7 @@ public:
bool getOffer(int id1, int id2, int &val1, int &val2, EMarketMode::EMarketMode mode) const; //val1 - how many units of id1 player has to give to receive val2 units bool getOffer(int id1, int id2, int &val1, int &val2, EMarketMode::EMarketMode mode) const; //val1 - how many units of id1 player has to give to receive val2 units
std::vector<EMarketMode::EMarketMode> availableModes() const; std::vector<EMarketMode::EMarketMode> availableModes() const;
static const IMarket *castFrom(const CGObjectInstance *obj); static const IMarket *castFrom(const CGObjectInstance *obj, bool verbose = true);
}; };
class DLL_LINKAGE CGObjectInstance : public IObjectInterface class DLL_LINKAGE CGObjectInstance : public IObjectInterface