1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-24 08:32:34 +02:00

* loading AI dll for neutrals

* hopefully fixed reported by Zamolxis garrison bugs
* fixed calculating hero level
* fixed gicing starting exp for heroes
This commit is contained in:
Michał W. Urbańczyk 2008-11-15 00:55:19 +00:00
parent 73cd282bbe
commit f6807a2af9
9 changed files with 99 additions and 64 deletions

View File

@ -24,6 +24,7 @@ using namespace CSDL_Ext;
CGlobalAI * CAIHandler::getNewAI(CCallback * cb, std::string dllname)
{
char temp[50];
dllname = "AI/"+dllname;
CGlobalAI * ret=NULL;
CGlobalAI*(*getAI)();
@ -34,26 +35,18 @@ CGlobalAI * CAIHandler::getNewAI(CCallback * cb, std::string dllname)
if (!dll)
{
tlog1 << "Cannot open AI library ("<<dllname<<"). Throwing..."<<std::endl;
#ifdef _MSC_VER
throw new std::exception("Cannot open AI library");
#endif
throw new std::exception();
throw new std::string("Cannot open AI library");
}
//int len = dllname.size()+1;
getName = (void(*)(char*))GetProcAddress(dll,"GetAiName");
getAI = (CGlobalAI*(*)())GetProcAddress(dll,"GetNewAI");
getName(temp);
#else
; //TODO: handle AI library on Linux
#endif
char * temp = new char[50];
#if _WIN32
getName(temp);
#endif
tlog0 << "Loaded .dll with AI named " << temp << std::endl;
delete temp;
#if _WIN32
ret = getAI();
ret->init(cb);
#else
//ret = new CEmptyAI();
#endif

View File

@ -124,8 +124,19 @@ void CGarrisonSlot::hover (bool on)
{
if(owner->highlighted)
{
const CArmedInstance *highl = owner->highlighted->getObj();
if( highl->needsLastStack() //we are moving stack from hero's
&& highl->army.slots.size() == 1 //it's only stack
&& owner->highlighted->upg != upg //we're moving it to the other garrison
)
{
temp = CGI->townh->tcommands[5]; //cannot move last stack!
}
else
{
temp = CGI->townh->tcommands[6];
boost::algorithm::replace_first(temp,"%s",owner->highlighted->creature->nameSing);
}
}
else
{
@ -1935,7 +1946,7 @@ void CPlayerInterface::garrisonChanged(const CGObjectInstance * obj)
hw->garInt->recreateSlots();
hw->garInt->show();
}
if(castleInt) //opened town window - redraw town garrsion slots (change is within hero garr)
if(castleInt) //opened town window - redraw town garrison slots (change is within hero garr)
{
castleInt->garr->highlighted = NULL;
castleInt->garr->recreateSlots();

View File

@ -1,3 +1,27 @@
0.64 -> 0.next (???) [as for r639]
GENERAL:
* move some settings to the config/settings.txt file
* partial support for new screen resolutions
* /Data and /Sprites subfolders can be used for adding files not present in .lod archives
* fixed crashbug occuring when hero levelled above 15 level
BATTLES
* magic arrow *really* works
* war machines support partially added
* queue of stacks narrowed
* spell effect animation displaying improvements
* several reported bugs fixed
* new spells supported:
a) Haste
b) lightning bolt
c) ice bolt
d) slow
e) implosion
GENERAL:
* started making external settings file (will be used for support for non 800x600 screen resolutions)
And a lot of minor fixes
0.63 -> 0.64 (Nov 01 2008)
GENERAL:
* sprites from /Sprites folder are handled correctly

View File

@ -110,9 +110,11 @@ CClient::CClient(CConnection *con, StartInfo *si)
c << *si;
c >> pom8;
if(pom8) throw "Server cannot open the map!";
c << ui8(si->playerInfos.size());
c << ui8(si->playerInfos.size()+1); //number of players + neutral
for(int i=0;i<si->playerInfos.size();i++)
c << ui8(si->playerInfos[i].color);
c << ui8(si->playerInfos[i].color); //players
c << ui8(255); // neutrals
ui32 seed, sum;
std::string mapname;
@ -142,21 +144,20 @@ CClient::CClient(CConnection *con, StartInfo *si)
CGI->mh->init();
tlog0 <<"Initializing mapHandler (together): "<<tmh.getDif()<<std::endl;
for (int i=0; i<CGI->state->scenarioOps->playerInfos.size();i++) //initializing interfaces
for (int i=0; i<CGI->state->scenarioOps->playerInfos.size();i++) //initializing interfaces for players
{
ui8 color = gs->scenarioOps->playerInfos[i].color;
CCallback *cb = new CCallback(gs,color,this);
if(!gs->scenarioOps->playerInfos[i].human)
{
playerint[color] = static_cast<CGameInterface*>(CAIHandler::getNewAI(cb,conf.cc.defaultAI));
}
else
{
gs->currentPlayer = color;
playerint[color] = new CPlayerInterface(color,i);
playerint[color]->init(cb);
}
gs->currentPlayer = color;
playerint[color]->init(cb);
}
playerint[255] = CAIHandler::getNewAI(cb,conf.cc.defaultAI);
playerint[255]->init(new CCallback(gs,255,this));
}
CClient::~CClient(void)
{
@ -166,11 +167,12 @@ void CClient::process(int what)
static BattleAction curbaction;
switch (what)
{
case 100: //one of our interaces has turn
case 100: //one of our interfaces has turn
{
ui8 player;
*serv >> player;//who?
tlog5 << "It's turn of "<<(unsigned)player<<" player."<<std::endl;
gs->currentPlayer = player;
boost::thread(boost::bind(&CGameInterface::yourTurn,playerint[player]));
break;
}
@ -343,9 +345,10 @@ void CClient::process(int what)
//std::for_each(th->fowRevealed.begin(),th->fowRevealed.end(),boost::bind(&CGameInterface::tileRevealed,playerint[player],_1));
}
//notify interfacesabout move
//notify interfaces about move
for(std::map<ui8, CGameInterface*>::iterator i=playerint.begin();i!=playerint.end();i++)
{
if(i->first >= PLAYER_LIMIT) continue;
if(gs->players[i->first].fogOfWarMap[th->start.x-1][th->start.y][th->start.z] || gs->players[i->first].fogOfWarMap[th->end.x-1][th->end.y][th->end.z])
{
i->second->heroMoved(hmd);
@ -546,17 +549,7 @@ void CClient::process(int what)
tlog5 << "Active stack: " << sas.stack <<std::endl;
gs->apply(&sas);
int owner = gs->curB->getStack(sas.stack)->owner;
if(owner >= PLAYER_LIMIT) //ugly workaround to skip neutral creatures - should be replaced with AI
{
BattleAction ba;
ba.stackNumber = sas.stack;
ba.actionType = 3;
*serv << ui16(3002) << ba;
}
else
{
boost::thread(boost::bind(&CClient::waitForMoveAndSend,this,owner));
}
boost::thread(boost::bind(&CClient::waitForMoveAndSend,this,owner));
break;
}
case 3003:

View File

@ -338,7 +338,7 @@ unsigned int CHeroHandler::level(unsigned int experience)
for(int i=expPerLevel.size()-1; i>=0; --i)
{
if(experience>=expPerLevel[i])
return i+add;
return 1+i+add;
}
return -1;
}

View File

@ -561,7 +561,7 @@ CGHeroInstance::CGHeroInstance()
mana = movement = portrait = level = -1;
isStanding = true;
moveDir = 4;
exp = 0;
exp = 0xffffffff;
visitedTown = NULL;
type = NULL;
secSkills.push_back(std::make_pair(-1, -1));
@ -618,7 +618,7 @@ void CGHeroInstance::initHero()
name = type->name;
if (!biography.length())
biography = type->biography;
if (exp == -1)
if (exp == 0xffffffff)
{
exp=40+ (ran()) % 50;
level = 1;
@ -662,6 +662,10 @@ CGHeroInstance::~CGHeroInstance()
{
}
bool CGHeroInstance::needsLastStack() const
{
return true;
}
CGTownInstance::~CGTownInstance()
{}
@ -674,6 +678,13 @@ int CGTownInstance::spellsAtLevel(int level, bool checkGuild) const
ret++;
return ret;
}
bool CGTownInstance::needsLastStack() const
{
if(garrisonHero)
return true;
else return false;
}
CGObjectInstance::CGObjectInstance(const CGObjectInstance & right)
{
pos = right.pos;

View File

@ -75,6 +75,7 @@ class DLL_EXPORT CArmedInstance: public CGObjectInstance
{
public:
CCreatureSet army; //army
virtual bool needsLastStack() const=0; //true if last stack cannot be taken
};
class DLL_EXPORT CGHeroInstance : public CArmedInstance
@ -112,6 +113,7 @@ public:
std::map<ui16,ui32> artifWorn; //map<position,artifact_id>; positions: 0 - head; 1 - shoulders; 2 - neck; 3 - right hand; 4 - left hand; 5 - torso; 6 - right ring; 7 - left ring; 8 - feet; 9 - misc1; 10 - misc2; 11 - misc3; 12 - misc4; 13 - mach1; 14 - mach2; 15 - mach3; 16 - mach4; 17 - spellbook; 18 - misc5
std::set<ui32> spells; //known spells (spell IDs)
bool needsLastStack()const;
virtual bool isHero() const;
unsigned int getTileCost(const EterrainType & ttype, const Eroad & rdtype, const Eriver & rvtype) const;
unsigned int getLowestCreatureSpeed();
@ -165,6 +167,7 @@ public:
std::set<CCastleEvent> events;
bool needsLastStack() const;
int getSightDistance() const; //returns sight distance
int fortLevel() const; //0 - none, 1 - fort, 2 - citadel, 3 - castle
int hallLevel() const; // -1 - none, 0 - village, 1 - town, 2 - city, 3 - capitol

View File

@ -1054,7 +1054,7 @@ void Mapa::loadHero( CGObjectInstance * &nobj, unsigned char * bufor, int &i )
if(readChar(bufor,i))//true if hore's experience is greater than 0
{ nhi->exp = readNormalNr(bufor,i); i+=4; }
else
nhi->exp = -1;
nhi->exp = 0xffffffff;
}
else
{ nhi->exp = readNormalNr(bufor,i); i+=4; }

View File

@ -518,50 +518,50 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
c >> what >> id1 >> p1 >> id2 >> p2;
CArmedInstance *s1 = static_cast<CArmedInstance*>(gs->map->objects[id1]),
*s2 = static_cast<CArmedInstance*>(gs->map->objects[id2]);
CCreatureSet *S1 = &s1->army, *S2 = &s2->army;
CCreatureSet temp1 = s1->army, temp2 = s2->army,
&S1 = temp1, &S2 = (s1!=s2)?(temp2):(temp1);
if(what==1) //swap
{
int pom = S2->slots[p2].first;
S2->slots[p2].first = S1->slots[p1].first;
S1->slots[p1].first = pom;
int pom2 = S2->slots[p2].second;
S2->slots[p2].second = S1->slots[p1].second;
S1->slots[p1].second = pom2;
std::swap(S1.slots[p1],S2.slots[p2]);
if(!S1->slots[p1].second)
S1->slots.erase(p1);
if(!S2->slots[p2].second)
S2->slots.erase(p2);
if(!S1.slots[p1].second)
S1.slots.erase(p1);
if(!S2.slots[p2].second)
S2.slots.erase(p2);
}
else if(what==2)//merge
{
if(S1->slots[p1].first != S2->slots[p2].first) break; //not same creature
S2->slots[p2].second += S1->slots[p1].second;
S1->slots[p1].first = NULL;
S1->slots[p1].second = 0;
S1->slots.erase(p1);
if(S1.slots[p1].first != S2.slots[p2].first) break; //not same creature
S2.slots[p2].second += S1.slots[p1].second;
S1.slots.erase(p1);
}
else if(what==3) //split
{
si32 val;
c >> val;
if(S2->slots.find(p2) != S2->slots.end()) break; //slot not free
S2->slots[p2].first = S1->slots[p1].first;
S2->slots[p2].second = val;
S1->slots[p1].second -= val;
if(!S1->slots[p1].second) //if we've moved all creatures
S1->slots.erase(p1);
if( vstd::contains(S2.slots,p2) //dest. slot not free
|| !vstd::contains(S1.slots,p1) //no creatures to split
|| S1.slots[p1].second < val //not enough creatures
|| val<1 //val must be positive
)
break;
S2.slots[p2].first = S1.slots[p1].first;
S2.slots[p2].second = val;
S1.slots[p1].second -= val;
if(!S1.slots[p1].second) //if we've moved all creatures
S1.slots.erase(p1);
}
if((s1->ID==34 && !S1->slots.size()) //it's not allowed to take last stack from hero army!
|| (s2->ID==34 && !S2->slots.size()))
if((s1->needsLastStack() && !S1.slots.size()) //it's not allowed to take last stack from hero army!
|| (s2->needsLastStack() && !S2.slots.size())
)
{
break;
break; //leave without applying changes to garrison
}
SetGarrisons sg;
sg.garrs[id1] = *S1;
sg.garrs[id1] = S1;
if(s1 != s2)
sg.garrs[id2] = *S2;
sg.garrs[id2] = S2;
sendAndApply(&sg);
break;
}