mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-28 08:48:48 +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:
parent
73cd282bbe
commit
f6807a2af9
@ -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
|
||||
|
@ -123,10 +123,21 @@ void CGarrisonSlot::hover (bool on)
|
||||
else
|
||||
{
|
||||
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
|
||||
{
|
||||
temp = CGI->townh->tcommands[11];
|
||||
@ -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();
|
||||
|
24
ChangeLog
24
ChangeLog
@ -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
|
||||
|
@ -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);
|
||||
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;
|
||||
}
|
||||
@ -346,6 +348,7 @@ void CClient::process(int what)
|
||||
//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));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3003:
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
2
map.cpp
2
map.cpp
@ -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; }
|
||||
|
@ -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((s1->ID==34 && !S1->slots.size()) //it's not allowed to take last stack from hero army!
|
||||
|| (s2->ID==34 && !S2->slots.size()))
|
||||
{
|
||||
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->needsLastStack() && !S1.slots.size()) //it's not allowed to take last stack from hero army!
|
||||
|| (s2->needsLastStack() && !S2.slots.size())
|
||||
)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user