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

* improved slider ( #58 )

* fixed problems with horde buildings (won't block original dwellings)
* giving primary skill when hero get level (but there is still no dialog)
* if an upgraded creature is available it'll be shown as the first in a recruitment window
* creature levels not messed in Fortress
* war machines are added to the hero's inventory, not to the garrison
* support for H3-style PCX graphics in Data/ (not tested)
* started doing support for ZSoft PCX graphics in Data/
* VCMI won't crash when is unable to initialize audio system
* fixed displaying wrong town defs
* minor fixes and improvements
This commit is contained in:
Michał W. Urbańczyk 2008-05-03 15:30:11 +00:00
parent 33e3bf4849
commit 2f2169b71f
14 changed files with 218 additions and 124 deletions

View File

@ -419,7 +419,7 @@ void CSlider<T>::sliderClicked()
template<typename T> template<typename T>
void CSlider<T>::mouseMoved (SDL_MouseMotionEvent & sEvent) void CSlider<T>::mouseMoved (SDL_MouseMotionEvent & sEvent)
{ {
float v = sEvent.x - pos.x - 16; float v = sEvent.x - pos.x - 24;
v/= (pos.w - 48); v/= (pos.w - 48);
v*=amount; v*=amount;
if(v!=value) if(v!=value)

View File

@ -659,10 +659,22 @@ bool CCallback::buildBuilding(const CGTownInstance *town, int buildingID)
{ {
CGTownInstance * t = const_cast<CGTownInstance *>(town); CGTownInstance * t = const_cast<CGTownInstance *>(town);
CBuilding *b = CGI->buildh->buildings[t->subID][buildingID]; CBuilding *b = CGI->buildh->buildings[t->subID][buildingID];
if(0/*not allowed*/)//TODO: check if we are allowed to build if(0/*not allowed*/)//TODO: check if we are allowed to build
return false; return false;
if(buildingID>36) //upg dwelling
{
if(t->getHordeLevel(0) == (buildingID-37))
t->builtBuildings.insert(19);
else if(t->getHordeLevel(1) == (buildingID-37))
t->builtBuildings.insert(25);
}
else if(buildingID >= 30) //bas. dwelling
{
t->strInfo.creatures[buildingID-30] = CGI->creh->creatures[t->town->basicCreatures[buildingID-30]].growth;
}
t->builtBuildings.insert(buildingID); t->builtBuildings.insert(buildingID);
for(int i=0;i<7;i++) for(int i=0;i<7;i++)
gs->players[player].resources[i]-=b->resources[i]; gs->players[player].resources[i]-=b->resources[i];
@ -768,7 +780,24 @@ void CScriptCallback::changePrimSkill(int ID, int which, int val)
else if (which==4) else if (which==4)
{ {
hero->exp+=val; hero->exp+=val;
std::cout << "Bohater o ID " << ID <<" (" <<CGI->heroh->heroes[ID]->name <<") dostaje "<<val<<" expa, ale nic z tym nie umiem zrobic :("<<std::endl; if(hero->exp >= CGI->heroh->reqExp(hero->level+1)) //new level
{
hero->level++;
std::cout << hero->name <<" got level "<<hero->level<<std::endl;
int r = rand()%100, pom=0, x=0;
int std::pair<int,int>::*g=hero->level>9?&std::pair<int,int>::second:&std::pair<int,int>::first;
for(;x<PRIMARY_SKILLS;x++)
{
pom += hero->type->heroClass->primChance[x].*g;
if(r<pom)
break;
}
std::cout << "Bohater dostaje umiejetnosc pierwszorzedna " << x << " (wynik losowania "<<r<<")"<<std::endl;
hero->primSkills[x]++;
//TODO: dac dwie umiejetnosci 2-rzedne to wyboru
}
//TODO - powiadomic interfejsy, sprawdzic czy nie ma awansu itp //TODO - powiadomic interfejsy, sprawdzic czy nie ma awansu itp
} }
} }

View File

@ -314,16 +314,26 @@ void CCastleInterface::splitF()
void CCastleInterface::buildingClicked(int building) void CCastleInterface::buildingClicked(int building)
{ {
std::cout<<"You've clicked on "<<building<<std::endl; std::cout<<"You've clicked on "<<building<<std::endl;
if(building==19 || building==18)
{
building = town->town->hordeLvl[0] + 30;
}
else if(building==24 || building==25)
{
building = town->town->hordeLvl[1] + 30;
}
if(building >= 30) if(building >= 30)
{ {
if(building>36) if(building>36)
building-=7; building-=7;
std::vector<std::pair<int,int > > crs; std::vector<std::pair<int,int > > crs;
int amount = (const_cast<CGTownInstance*>(town))->strInfo.creatures[building-30]; //trzeba odconstowac, bo inaczej operator [] by sypal :( int amount = (const_cast<CGTownInstance*>(town))->strInfo.creatures[building-30]; //trzeba odconstowac, bo inaczej operator [] by sypal :(
crs.push_back(std::make_pair(town->town->basicCreatures[building-30],amount));
if(town->builtBuildings.find(building+7) != town->builtBuildings.end()) //check if there is an upgraded building if(town->builtBuildings.find(building+7) != town->builtBuildings.end()) //check if there is an upgraded building
crs.push_back(std::make_pair(town->town->upgradedCreatures[building-30],amount)); crs.push_back(std::make_pair(town->town->upgradedCreatures[building-30],amount));
crs.push_back(std::make_pair(town->town->basicCreatures[building-30],amount));
CRecrutationWindow *rw = new CRecrutationWindow(crs,this); CRecrutationWindow *rw = new CRecrutationWindow(crs,this);
rw->activate(); rw->activate();
} }
@ -488,13 +498,13 @@ void CCastleInterface::deactivate()
void CCastleInterface::addBuilding(int bid) void CCastleInterface::addBuilding(int bid)
{ {
//TODO: lepiej by bylo tylko dodawac/usuwac co trzeba pamietajac o grupach //TODO: lepiej by bylo tylko dodawac co trzeba pamietajac o grupach
recreateBuildings(); recreateBuildings();
} }
void CCastleInterface::removeBuilding(int bid) void CCastleInterface::removeBuilding(int bid)
{ {
//TODO: lepiej by bylo tylko dodawac/usuwac co trzeba pamietajac o grupach //TODO: lepiej by bylo tylko usuwac co trzeba pamietajac o grupach
recreateBuildings(); recreateBuildings();
} }

45
CMT.cpp
View File

@ -152,26 +152,33 @@ void initGameState(CGameInfo * cgi)
vhi->portrait = vhi->type->ID; vhi->portrait = vhi->type->ID;
//initial army //initial army
if (!vhi->army.slots.size()) if (!vhi->army.slots.size()) //standard army
{ {
int pom; int pom, pom2=0;
vhi->army.slots[0].first = &(cgi->creh->creatures[(cgi->creh->nameToID[vhi->type->refType1stack])]); for(int x=0;x<3;x++)
if((pom = (vhi->type->high1stack-vhi->type->low1stack)) > 0) {
vhi->army.slots[0].second = (rand()%pom)+vhi->type->low1stack; pom = (cgi->creh->nameToID[vhi->type->refTypeStack[x]]);
else if(pom>=145 && pom<=149) //war machine
vhi->army.slots[0].second = +vhi->type->low1stack; {
pom2++;
vhi->army.slots[1].first = &(cgi->creh->creatures[(cgi->creh->nameToID[vhi->type->refType2stack])]); switch (pom)
if((pom=(vhi->type->high2stack-vhi->type->low2stack))>0) {
vhi->army.slots[1].second = (rand()%pom)+vhi->type->low2stack; case 145: //catapult
else vhi->artifWorn[16] = &CGI->arth->artifacts[3];
vhi->army.slots[1].second = vhi->type->low2stack; break;
default:
vhi->army.slots[2].first = &(cgi->creh->creatures[(cgi->creh->nameToID[vhi->type->refType3stack])]); pom-=145;
if((pom=(vhi->type->high3stack-vhi->type->low3stack))>0) vhi->artifWorn[13+pom] = &CGI->arth->artifacts[4+pom];
vhi->army.slots[2].second = (rand()%pom)+vhi->type->low3stack; break;
else }
vhi->army.slots[2].second = vhi->type->low3stack; continue;
}
vhi->army.slots[x-pom2].first = &(cgi->creh->creatures[pom]);
if((pom = (vhi->type->highStack[x]-vhi->type->lowStack[x])) > 0)
vhi->army.slots[x-pom2].second = (rand()%pom)+vhi->type->lowStack[x];
else
vhi->army.slots[x-pom2].second = +vhi->type->lowStack[x];
}
} }
cgi->state->players[vhi->getOwner()].heroes.push_back(vhi); cgi->state->players[vhi->getOwner()].heroes.push_back(vhi);

View File

@ -2572,6 +2572,7 @@ CSplitWindow::CSplitWindow(int cid, int max, CGarrisonInt *Owner)
slider = NULL; slider = NULL;
gar = Owner; gar = Owner;
bitmap = CGI->bitmaph->loadBitmap("GPUCRDIV.bmp"); bitmap = CGI->bitmaph->loadBitmap("GPUCRDIV.bmp");
SDL_SetColorKey(bitmap,SDL_SRCCOLORKEY,SDL_MapRGB(bitmap->format,0,255,255));
pos.x = screen->w/2 - bitmap->w/2; pos.x = screen->w/2 - bitmap->w/2;
pos.y = screen->h/2 - bitmap->h/2; pos.y = screen->h/2 - bitmap->h/2;
pos.w = bitmap->w; pos.w = bitmap->w;
@ -2650,4 +2651,4 @@ void CSplitWindow::show(SDL_Surface * to)
void CSplitWindow::keyPressed (SDL_KeyboardEvent & key) void CSplitWindow::keyPressed (SDL_KeyboardEvent & key)
{ {
//TODO: zeby sie dalo recznie wpisywac //TODO: zeby sie dalo recznie wpisywac
} }

View File

@ -49,9 +49,9 @@
6 6 97 6 6 97
7 0 99 7 0 99
7 1 101 7 1 101
7 2 103 7 2 105
7 3 105 7 3 107
7 4 107 7 4 103
7 5 109 7 5 109
7 6 111 7 6 111
8 0 119 8 0 119

View File

@ -146,7 +146,7 @@
144 OgreShaman 144 OgreShaman
145 Catapult 145 Catapult
146 Ballista 146 Ballista
147 First-AidTent 147 FirstAidTent
148 AmmoCart 148 AmmoCart
149 ArrowTower 149 ArrowTower
150 SupremeArchangel 150 SupremeArchangel

View File

@ -50,6 +50,7 @@ const int F_NUMBER = 9; //factions (town types) quantity
const int PLAYER_LIMIT = 8; //player limit per map const int PLAYER_LIMIT = 8; //player limit per map
const int HEROES_PER_TYPE=8; //amount of heroes of each type const int HEROES_PER_TYPE=8; //amount of heroes of each type
const int SKILL_QUANTITY=28; const int SKILL_QUANTITY=28;
const int SKILL_PER_HERO=8;
const int ARTIFACTS_QUANTITY=171; const int ARTIFACTS_QUANTITY=171;
const int HEROES_QUANTITY=156; const int HEROES_QUANTITY=156;
const int RESOURCE_QUANTITY=8; const int RESOURCE_QUANTITY=8;

View File

@ -109,23 +109,14 @@ void CHeroHandler::loadHeroes()
std::string pom ; std::string pom ;
CGeneralTextHandler::loadToIt(nher->name,buf,it,4); CGeneralTextHandler::loadToIt(nher->name,buf,it,4);
CGeneralTextHandler::loadToIt(pom,buf,it,4); for(int x=0;x<3;x++)
nher->low1stack = atoi(pom.c_str()); {
CGeneralTextHandler::loadToIt(pom,buf,it,4); CGeneralTextHandler::loadToIt(pom,buf,it,4);
nher->high1stack = atoi(pom.c_str()); nher->lowStack[x] = atoi(pom.c_str());
CGeneralTextHandler::loadToIt(nher->refType1stack,buf,it,4); CGeneralTextHandler::loadToIt(pom,buf,it,4);
nher->highStack[x] = atoi(pom.c_str());
CGeneralTextHandler::loadToIt(pom,buf,it,4); CGeneralTextHandler::loadToIt(nher->refTypeStack[x],buf,it,(x==2) ? (3) : (4));
nher->low2stack = atoi(pom.c_str()); }
CGeneralTextHandler::loadToIt(pom,buf,it,4);
nher->high2stack = atoi(pom.c_str());
CGeneralTextHandler::loadToIt(nher->refType2stack,buf,it,4);
CGeneralTextHandler::loadToIt(pom,buf,it,4);
nher->low3stack = atoi(pom.c_str());
CGeneralTextHandler::loadToIt(pom,buf,it,4);
nher->high3stack = atoi(pom.c_str());
CGeneralTextHandler::loadToIt(nher->refType3stack,buf,it,3);
nher->ID = heroes.size(); nher->ID = heroes.size();
heroes.push_back(nher); heroes.push_back(nher);
@ -253,77 +244,29 @@ void CHeroHandler::loadHeroClasses()
hc->initialKnowledge = atoi(buf.substr(befi, i-befi).c_str()); hc->initialKnowledge = atoi(buf.substr(befi, i-befi).c_str());
++i; ++i;
befi=i; hc->primChance.resize(PRIMARY_SKILLS);
for(i; i<andame; ++i) for(int x=0;x<PRIMARY_SKILLS;x++)
{ {
if(buf[i]=='\t') befi=i;
break; for(i; i<andame; ++i)
{
if(buf[i]=='\t')
break;
}
hc->primChance[x].first = atoi(buf.substr(befi, i-befi).c_str());
++i;
} }
hc->proAttack[0] = atoi(buf.substr(befi, i-befi).c_str()); for(int x=0;x<PRIMARY_SKILLS;x++)
++i;
befi=i;
for(i; i<andame; ++i)
{ {
if(buf[i]=='\t') befi=i;
break; for(i; i<andame; ++i)
{
if(buf[i]=='\t')
break;
}
hc->primChance[x].second = atoi(buf.substr(befi, i-befi).c_str());
++i;
} }
hc->proDefence[0] = atoi(buf.substr(befi, i-befi).c_str());
++i;
befi=i;
for(i; i<andame; ++i)
{
if(buf[i]=='\t')
break;
}
hc->proPower[0] = atoi(buf.substr(befi, i-befi).c_str());
++i;
befi=i;
for(i; i<andame; ++i)
{
if(buf[i]=='\t')
break;
}
hc->proKnowledge[0] = atoi(buf.substr(befi, i-befi).c_str());
++i;
befi=i;
for(i; i<andame; ++i)
{
if(buf[i]=='\t')
break;
}
hc->proAttack[1] = atoi(buf.substr(befi, i-befi).c_str());
++i;
befi=i;
for(i; i<andame; ++i)
{
if(buf[i]=='\t')
break;
}
hc->proDefence[1] = atoi(buf.substr(befi, i-befi).c_str());
++i;
befi=i;
for(i; i<andame; ++i)
{
if(buf[i]=='\t')
break;
}
hc->proPower[1] = atoi(buf.substr(befi, i-befi).c_str());
++i;
befi=i;
for(i; i<andame; ++i)
{
if(buf[i]=='\t')
break;
}
hc->proKnowledge[1] = atoi(buf.substr(befi, i-befi).c_str());
++i;
//CHero kkk = heroes[0]; //CHero kkk = heroes[0];

View File

@ -18,8 +18,8 @@ class CHero
public: public:
std::string name; std::string name;
int ID; int ID;
int low1stack, high1stack, low2stack, high2stack, low3stack, high3stack; //amount of units; described below int lowStack[3], highStack[3]; //amount of units; described below
std::string refType1stack, refType2stack, refType3stack; //reference names of units appearing in hero's army if he is recruited in tavern std::string refTypeStack[3]; //reference names of units appearing in hero's army if he is recruited in tavern
std::string bonusName, shortBonus, longBonus; //for special abilities std::string bonusName, shortBonus, longBonus; //for special abilities
std::string biography; //biography, of course std::string biography; //biography, of course
bool isAllowed; //true if we can play with this hero (depends on map) bool isAllowed; //true if we can play with this hero (depends on map)
@ -36,10 +36,7 @@ public:
std::string name; std::string name;
float aggression; float aggression;
int initialAttack, initialDefence, initialPower, initialKnowledge; int initialAttack, initialDefence, initialPower, initialKnowledge;
int proAttack[2]; //probability of gaining attack point on levels [0]: 2 - 9; [1]: 10+ (out of 100) std::vector<std::pair<int,int> > primChance;//primChance[PRIMARY_SKILL_ID] - first is for levels 2 - 9, second for 10+;;; probability (%) of getting point of primary skill when getting new level
int proDefence[2]; //probability of gaining defence point on levels [0]: 2 - 9; [1]: 10+ (out of 100)
int proPower[2]; //probability of gaining power point on levels [0]: 2 - 9; [1]: 10+ (out of 100)
int proKnowledge[2]; //probability of gaining knowledge point on levels [0]: 2 - 9; [1]: 10+ (out of 100)
std::vector<int> proSec; //probabilities of gaining secondary skills (out of 112), in id order std::vector<int> proSec; //probabilities of gaining secondary skills (out of 112), in id order
int selectionProbability[9]; //probability of selection in towns int selectionProbability[9]; //probability of selection in towns
std::vector<int> terrCosts; //default costs of going through terrains: dirt, sand, grass, snow, swamp, rough, subterrain, lava, water, rock; -1 means terrain is imapassable std::vector<int> terrCosts; //default costs of going through terrains: dirt, sand, grass, snow, swamp, rough, subterrain, lava, water, rock; -1 means terrain is imapassable

View File

@ -252,6 +252,53 @@ SDL_Surface * CPCXConv::getSurface()
} }
return ret; return ret;
} }
SDL_Surface * CPCXConv::getSurfaceZ()
{
//int i=1;
//int type = pcx[i];i+=2;//0 -- Version 2.5 2 -- Version 2.8, palette included 3 -- Version 2.8, use default palette 5 -- Version 3.0 or better
//int bpp = pcx[3];i++;
//int xmin, ymin, xmax, ymax, w, h;
//xmin = readNormalNr(i,2,pcx);i+=2;
//ymin = readNormalNr(i,2,pcx);i+=2;
//xmax = readNormalNr(i,2,pcx);i+=2;
//ymax = readNormalNr(i,2,pcx);i+=2;
//w = xmax - xmin + 1; h = ymax - ymin + 1;
//i+=4; //DPI is not interesting
//char palette[48];
//memcpy(palette,pcx+i,48); i+=48;
//int reserved = pcx[i++];
//int planes = pcx[i++];
//int bytesPerLine = readNormalNr(i,2,pcx);i+=2;
//i = 128; //to the end of header
//int totalBytes = planes * bytesPerLine;
//int padding = ((bytesPerLine * planes) * (8 / bpp)) - ((xmax - xmin) + 1);
//char * buffer = new char[totalBytes];
//int index = 0, count, value, total=0;
//do
//{
// count=0; value=0;
// unsigned char byte = pcx[i++];
// if((byte & 0xC0) == 0xC0) //two top bits set
// {
// count = byte & 0x3f;
// value = pcx[i++];
// }
// else
// {
// count = 1;
// value = byte;
// }
// for(total+=count; count && (index < totalBytes); index++)
// {
// buffer[index] = value;
// count--;
// }
//} while(index<totalBytes);
//delete buffer;
std::cout<<"Warning - not supported ZSoft-style .png file!!!"<<std::endl;
return NULL;
}
SDL_Surface * CLodHandler::loadBitmap(std::string fname) SDL_Surface * CLodHandler::loadBitmap(std::string fname)
{ {
if(!fname.size()) if(!fname.size())
@ -269,7 +316,44 @@ SDL_Surface * CLodHandler::loadBitmap(std::string fname)
{ {
fname.replace(fname.find_first_of('.'),fname.find_first_of('.')+4,".BMP"); fname.replace(fname.find_first_of('.'),fname.find_first_of('.')+4,".BMP");
fname = "Data/"+fname; fname = "Data/"+fname;
return SDL_LoadBMP(fname.c_str()); FILE * f = fopen(fname.c_str(),"r");
if(f)
{
fclose(f);
return SDL_LoadBMP(fname.c_str());
}
else //file .bmp not present, check .pcx
{
//TODO: zczytywanie nawala, dokonczyc wsparcie zsoftowych pcxow
char sign[3];
fname.replace(fname.find_first_of('.'),fname.find_first_of('.')+4,".PCX");
f = fopen(fname.c_str(),"r");
if(!f)
return NULL;
fread(sign,1,3,f);
if(sign[0]=='B' && sign[1]=='M') //BMP - ¿eby Kulex móg³ mieszaæ PCXy z BMPami
{
fclose(f);
return SDL_LoadBMP(fname.c_str());
}
else //PCX
{
CPCXConv cp;
pcx = new unsigned char[e->realSize];
memcpy(pcx,sign,3);
int res = fread((char*)pcx+3, 1, e->realSize-3, f);
fclose(f);
cp.openPCX((char*)pcx,e->realSize);
if((sign[0]==10) && (sign[1]<6) && (sign[2]==1)) //ZSoft PCX
{
return cp.getSurfaceZ();
}
else //H3 PCX
{
return cp.getSurface();
}
}
}
} }
fseek(FLOD, e->offset, 0); fseek(FLOD, e->offset, 0);
if (e->size==0) //file is not compressed if (e->size==0) //file is not compressed

View File

@ -53,7 +53,8 @@ public:
void openPCX(char * PCX, int len); void openPCX(char * PCX, int len);
void openPCX(); void openPCX();
void convert(); void convert();
SDL_Surface * getSurface(); SDL_Surface * getSurface(); //for standard H3 PCX
SDL_Surface * getSurfaceZ(); //for ZSoft PCX
CPCXConv(){pcx=bmp=NULL;pcxs=bmps=0;}; CPCXConv(){pcx=bmp=NULL;pcxs=bmps=0;};
~CPCXConv(){if (pcxs) delete[] pcx; if(bmps) delete[] bmp;} ~CPCXConv(){if (pcxs) delete[] pcx; if(bmps) delete[] bmp;}
}; };

View File

@ -5,8 +5,10 @@ void CMusicHandler::initMusics()
{ {
if(Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 4096)==-1) if(Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 4096)==-1)
{ {
printf("Mix_OpenAudio: %s\n", Mix_GetError()); printf("Mix_OpenAudio error: %s!!!\n", Mix_GetError());
exit(2); //exit(2);
sndh = NULL;
return;
} }
atexit(Mix_CloseAudio); atexit(Mix_CloseAudio);
@ -61,6 +63,7 @@ void CMusicHandler::initMusics()
void CMusicHandler::playClick() void CMusicHandler::playClick()
{ {
if(!sndh) return;
int channel; int channel;
channel = Mix_PlayChannel(-1, click, 0); channel = Mix_PlayChannel(-1, click, 0);
if(channel == -1) if(channel == -1)
@ -71,6 +74,7 @@ void CMusicHandler::playClick()
void CMusicHandler::playLodSnd(std::string sndname) void CMusicHandler::playLodSnd(std::string sndname)
{ {
if(!sndh) return;
int size; int size;
unsigned char *data; unsigned char *data;
SDL_RWops *ops; SDL_RWops *ops;

View File

@ -209,7 +209,24 @@ void CMapHandler::randomizeObject(CGObjectInstance *cur)
{ {
std::pair<int,int> ran = pickObject(cur); std::pair<int,int> ran = pickObject(cur);
if(ran.first<0 || ran.second<0) //this is not a random object, or we couldn't find anything if(ran.first<0 || ran.second<0) //this is not a random object, or we couldn't find anything
{
if(cur->ID==98) //town - set def
{
CGTownInstance *t = dynamic_cast<CGTownInstance*>(cur);
if(t->hasCapitol())
t->defInfo = capitols[t->subID];
else if(t->hasFort())
t->defInfo = CGI->dobjinfo->castles[t->subID];
else
t->defInfo = villages[t->subID];
if(!t->defInfo->handler)
{
t->defInfo->handler = CGI->spriteh->giveDef(t->defInfo->name);
alphaTransformDef(t->defInfo);
}
}
return; return;
}
else if(ran.first==34)//special code for hero else if(ran.first==34)//special code for hero
{ {
CGHeroInstance *h = dynamic_cast<CGHeroInstance *>(cur); CGHeroInstance *h = dynamic_cast<CGHeroInstance *>(cur);