From 7d7abbb68d5e1d314afcbe224d95358788977253 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20W=2E=20Urba=C5=84czyk?= Date: Sat, 31 May 2008 20:37:54 +0000 Subject: [PATCH] * no more divison by 0 in slider * little more code for upgrades * version set to 0.6 * "plural" reference names for Conflux creatures (starting armies of Conflux heroes should now be working) * minor changes --- AdventureMapButton.cpp | 11 ++++-- CBattleInterface.cpp | 12 +++--- CCallback.cpp | 60 ++++++++++++++++++++++++---- CCallback.h | 4 +- CMT.cpp | 2 +- CPlayerInterface.cpp | 34 ++++++++++++---- CPlayerInterface.h | 8 ++-- config/cr_upgrade_list.txt | 80 ++++++++++++++++++++++++++++++++++++++ config/crerefnam.txt | 5 +++ hch/CCreatureHandler.cpp | 10 +++++ hch/CCreatureHandler.h | 1 + hch/CHeroHandler.cpp | 3 ++ hch/CObjectHandler.cpp | 1 + hch/CObjectHandler.h | 9 ++--- 14 files changed, 205 insertions(+), 35 deletions(-) create mode 100644 config/cr_upgrade_list.txt diff --git a/AdventureMapButton.cpp b/AdventureMapButton.cpp index dc1505dcb..576a41484 100644 --- a/AdventureMapButton.cpp +++ b/AdventureMapButton.cpp @@ -183,9 +183,14 @@ void CSlider::moveTo(int to) else if(to>amount) to=amount; value = to; - float part = (float)to/amount; - part*=(pos.w-48); - slider.pos.x = part + pos.x + 16; + if(amount) + { + float part = (float)to/amount; + part*=(pos.w-48); + slider.pos.x = part + pos.x + 16; + } + else + slider.pos.x = pos.x+16; moved(to); } diff --git a/CBattleInterface.cpp b/CBattleInterface.cpp index 7000fed33..0a688f123 100644 --- a/CBattleInterface.cpp +++ b/CBattleInterface.cpp @@ -559,7 +559,7 @@ void CBattleInterface::stackAttacking(int ID, int dest) switch(CBattleHex::mutualPosition(aStack.position, dest)) //attack direction { case 0: - /*reverseCreature(ID, aStack.position, true); + //reverseCreature(ID, aStack.position, true); creAnims[ID]->setType(10); for(int i=0; iframesInGroup(10); ++i) { @@ -567,7 +567,7 @@ void CBattleInterface::stackAttacking(int ID, int dest) CSDL_Ext::update(); SDL_framerateDelay(LOCPLINT->mainFPSmng); } - reverseCreature(ID, aStack.position, true);*/ + //reverseCreature(ID, aStack.position, true); break; case 1: creAnims[ID]->setType(10); @@ -597,7 +597,7 @@ void CBattleInterface::stackAttacking(int ID, int dest) } break; case 4: - /*reverseCreature(ID, aStack.position, true); + //reverseCreature(ID, aStack.position, true); creAnims[ID]->setType(12); for(int i=0; iframesInGroup(12); ++i) { @@ -605,10 +605,10 @@ void CBattleInterface::stackAttacking(int ID, int dest) CSDL_Ext::update(); SDL_framerateDelay(LOCPLINT->mainFPSmng); } - reverseCreature(ID, aStack.position, true);*/ + //reverseCreature(ID, aStack.position, true); break; case 5: - /*reverseCreature(ID, aStack.position, true); + reverseCreature(ID, aStack.position, true); creAnims[ID]->setType(11); for(int i=0; iframesInGroup(11); ++i) { @@ -616,7 +616,7 @@ void CBattleInterface::stackAttacking(int ID, int dest) CSDL_Ext::update(); SDL_framerateDelay(LOCPLINT->mainFPSmng); } - reverseCreature(ID, aStack.position, true);*/ + reverseCreature(ID, aStack.position, true); break; } creAnims[ID]->setType(2); diff --git a/CCallback.cpp b/CCallback.cpp index 6235a41e2..bcfb042c3 100644 --- a/CCallback.cpp +++ b/CCallback.cpp @@ -281,7 +281,7 @@ void CCallback::recruitCreatures(const CGObjectInstance *obj, int ID, int amount for(int i=0;i<7;i++) { - if(!t->army.slots[i].first) + if((!t->army.slots[i].first) || (t->army.slots[i].first->idNumber == ID)) //slot is free or there is saem creature { slot = i; break; @@ -295,9 +295,15 @@ void CCallback::recruitCreatures(const CGObjectInstance *obj, int ID, int amount gs->players[player].resources[i] -= (CGI->creh->creatures[ID].cost[i] * amount); t->strInfo.creatures[ser] -= amount; - - t->army.slots[slot].first = &CGI->creh->creatures[ID]; - t->army.slots[slot].second = amount; + if(t->army.slots[slot].first) //add new creatures to the existing stack + { + t->army.slots[slot].second += amount; + } + else //create new stack in the garrison + { + t->army.slots[slot].first = &CGI->creh->creatures[ID]; + t->army.slots[slot].second = amount; + } CGI->playerint[gs->players[player].serial]->garrisonChanged(obj); } @@ -306,15 +312,53 @@ void CCallback::recruitCreatures(const CGObjectInstance *obj, int ID, int amount bool CCallback::dismissCreature(const CArmedInstance *obj, int stackPos) { - return false; + if(obj->tempOwner != player) + return false; + CArmedInstance *ob = const_cast(obj); + ob->army.slots.erase(stackPos); + CGI->playerint[gs->players[player].serial]->garrisonChanged(obj); + return true; } -bool CCallback::upgradeCreature(const CArmedInstance *obj, int stackPos) +bool CCallback::upgradeCreature(const CArmedInstance *obj, int stackPos, int newID) { return false; } UpgradeInfo CCallback::getUpgradeInfo(const CArmedInstance *obj, int stackPos) { - return UpgradeInfo(); + UpgradeInfo ret; + CCreature *base = ((CArmedInstance*)obj)->army.slots[stackPos].first; + if((obj->ID == 98) || ((obj->ID == 34) && static_cast(obj)->visitedTown)) + { + CGTownInstance * t; + if(obj->ID == 98) + t = static_cast(const_cast(obj)); + else + t = static_cast(obj)->visitedTown; + for(std::set::iterator i=t->builtBuildings.begin(); i!=t->builtBuildings.end(); i++) + { + if( (*i) >= 37 && (*i) < 44 ) //upgraded creature dwelling + { + int nid = t->town->upgradedCreatures[(*i)-37]; //upgrade offered by that building + if(base->upgrades.find(nid) != base->upgrades.end()) //possible upgrade + { + ret.newID.push_back(nid); + ret.cost.push_back(std::set >()); + for(int j=0;jcreh->creatures[nid].cost[j] - base->cost[j]; + if(dif) + ret.cost[ret.cost.size()-1].insert(std::make_pair(j,dif)); + } + } + } + }//end for + } + //TODO: check if hero ability makes some upgrades possible + + if(ret.newID.size()) + ret.oldID = base->idNumber; + + return ret; } int CCallback::howManyTowns() @@ -907,6 +951,7 @@ void CScriptCallback::heroVisitCastle(CGObjectInstance * ob, int heroID) if(n = dynamic_cast(ob)) { n->visitingHero = CGI->state->getHero(heroID,0); + CGI->state->getHero(heroID,0)->visitedTown = n; for(int b=0; bplayerint.size(); ++b) { if(CGI->playerint[b]->playerID == getHeroOwner(heroID)) @@ -925,6 +970,7 @@ void CScriptCallback::stopHeroVisitCastle(CGObjectInstance * ob, int heroID) CGTownInstance * n; if(n = dynamic_cast(ob)) { + CGI->state->getHero(heroID,0)->visitedTown = NULL; if(n->visitingHero && n->visitingHero->type->ID == heroID) n->visitingHero = NULL; return; diff --git a/CCallback.h b/CCallback.h index 35155fd8a..4d745ea62 100644 --- a/CCallback.h +++ b/CCallback.h @@ -35,7 +35,7 @@ public: virtual bool swapArifacts(const CGHeroInstance * hero1, bool worn1, int pos1, const CGHeroInstance * hero2, bool worn2, int pos2)=0; //swaps artifacts between two given heroes virtual void recruitCreatures(const CGObjectInstance *obj, int ID, int amount)=0; virtual bool dismissCreature(const CArmedInstance *obj, int stackPos)=0; - virtual bool upgradeCreature(const CArmedInstance *obj, int stackPos)=0; + virtual bool upgradeCreature(const CArmedInstance *obj, int stackPos, int newID=-1)=0; //if newID==-1 then best possible upgrade will be made //get info virtual bool verifyPath(CPath * path, bool blockSea)=0; @@ -103,7 +103,7 @@ public: bool buildBuilding(const CGTownInstance *town, int buildingID); void recruitCreatures(const CGObjectInstance *obj, int ID, int amount); bool dismissCreature(const CArmedInstance *obj, int stackPos); - bool upgradeCreature(const CArmedInstance *obj, int stackPos); + bool upgradeCreature(const CArmedInstance *obj, int stackPos, int newID=-1); //get info diff --git a/CMT.cpp b/CMT.cpp index 2fd57b45a..2802982b9 100644 --- a/CMT.cpp +++ b/CMT.cpp @@ -62,7 +62,7 @@ CGameInfo* CGI; #endif #define CHUNK 16384 -const char * NAME = "VCMI 0.59"; +const char * NAME = "VCMI 0.6"; SDL_Color playerColorPalette[256]; //palette to make interface colors good diff --git a/CPlayerInterface.cpp b/CPlayerInterface.cpp index 18bb06b92..7c170f40c 100644 --- a/CPlayerInterface.cpp +++ b/CPlayerInterface.cpp @@ -104,7 +104,7 @@ void CGarrisonSlot::hover (bool on) } } -const CGObjectInstance * CGarrisonSlot::getObj() +const CArmedInstance * CGarrisonSlot::getObj() { return (!upg)?(owner->oup):(owner->odown); } @@ -142,7 +142,12 @@ void CGarrisonSlot::clickLeft(tribool down) { if(owner->highlighted == this) //view info { - //TODO: view creature info + UpgradeInfo pom = LOCPLINT->cb->getUpgradeInfo(getObj(),ID); + (new CCreInfoWindow + (creature->idNumber,1,NULL, + (pom.oldID>=0)?(boost::bind(&CCallback::upgradeCreature,LOCPLINT->cb,getObj(),ID,-1)):(boost::function()), //if upgrade is possible we'll bind proper function in callback + boost::bind(&CCallback::dismissCreature,LOCPLINT->cb,getObj(),ID))) + ->activate(); owner->highlighted = NULL; show(); refr = true; @@ -399,7 +404,7 @@ void CGarrisonInt::splitStacks(int am2) am2); } -CGarrisonInt::CGarrisonInt(int x, int y, int inx, int iny, SDL_Surface *pomsur, int OX, int OY, const CGObjectInstance *s1, const CGObjectInstance *s2) +CGarrisonInt::CGarrisonInt(int x, int y, int inx, int iny, SDL_Surface *pomsur, int OX, int OY, const CArmedInstance *s1, const CArmedInstance *s2) :interx(inx),intery(iny),sur(pomsur),highlighted(NULL),sup(NULL),sdown(NULL),oup(s1),odown(s2), offx(OX),offy(OY) { @@ -2926,10 +2931,17 @@ void CCreInfoWindow::show(SDL_Surface * to) blitAt(bitmap,pos.x,pos.y,screen); blitAt(CGI->creh->backgrounds[c->faction],pos.x+21,pos.y+48,screen); anim->nextFrameMiddle(screen,pos.x+90,pos.y+95,true,false,false); + if(upgrade) + upgrade->show(); + if(dismiss) + dismiss->show(); + if(ok) + ok->show(); } -CCreInfoWindow::CCreInfoWindow(int Cid, int Type, StackState *State, boost::function Upg, boost::function Dsm) -:ok(0),dismiss(0),upgrade(0),type(Type) +CCreInfoWindow::CCreInfoWindow + (int Cid, int Type, StackState *State, boost::function Upg, boost::function Dsm) +:ok(0),dismiss(0),upgrade(0),type(Type),dsm(Dsm) { c = &CGI->creh->creatures[Cid]; bitmap = CGI->bitmaph->loadBitmap("CRSTKPU.bmp"); @@ -3008,9 +3020,10 @@ CCreInfoWindow::CCreInfoWindow(int Cid, int Type, StackState *State, boost::func if(type) { if(Upg) - upgrade = new AdventureMapButton("",CGI->preth->zelp[446].second,Upg,76,237,"IVIEWCR.DEF"); + upgrade = new AdventureMapButton("",CGI->preth->zelp[446].second,Upg,pos.x+76,pos.y+237,"IVIEWCR.DEF"); if(Dsm) - dismiss = new AdventureMapButton("",CGI->preth->zelp[445].second,Upg,21,237,"IVIEWCR2.DEF"); + dismiss = new AdventureMapButton("",CGI->preth->zelp[445].second,boost::bind(&CCreInfoWindow::dismissF,this),pos.x+21,pos.y+237,"IVIEWCR2.DEF"); + ok = new AdventureMapButton("",CGI->preth->zelp[445].second,boost::bind(&CCreInfoWindow::close,this),pos.x+216,pos.y+237,"IOKAY.DEF"); } else { @@ -3032,6 +3045,8 @@ void CCreInfoWindow::activate() dismiss->activate(); if(upgrade) upgrade->activate(); + if(type) + LOCPLINT->curint->deactivate(); } void CCreInfoWindow::close() { @@ -3049,6 +3064,11 @@ void CCreInfoWindow::clickRight(boost::logic::tribool down) return; close(); } +void CCreInfoWindow::dismissF() +{ + dsm(); + close(); +} void CCreInfoWindow::keyPressed (SDL_KeyboardEvent & key) { } diff --git a/CPlayerInterface.h b/CPlayerInterface.h index a82f0ed6b..f28ce6684 100644 --- a/CPlayerInterface.h +++ b/CPlayerInterface.h @@ -245,7 +245,7 @@ public: bool active; virtual void hover (bool on); - const CGObjectInstance * getObj(); + const CArmedInstance * getObj(); void clickRight (boost::logic::tribool down); void clickLeft(boost::logic::tribool down); void activate(); @@ -269,7 +269,7 @@ public: const CCreatureSet *set2; std::vector *sup, *sdown; - const CGObjectInstance *oup, *odown; + const CArmedInstance *oup, *odown; void activate(); void deactivate(); @@ -283,7 +283,7 @@ public: void splitClick(); void splitStacks(int am2); - CGarrisonInt(int x, int y, int inx, int iny, SDL_Surface *pomsur, int OX, int OY, const CGObjectInstance *s1, const CGObjectInstance *s2=NULL); + CGarrisonInt(int x, int y, int inx, int iny, SDL_Surface *pomsur, int OX, int OY, const CArmedInstance *s1, const CArmedInstance *s2=NULL); ~CGarrisonInt(); }; @@ -514,6 +514,7 @@ public: int type;//0 - rclick popup; 1 - normal window SDL_Surface *bitmap; + boost::function dsm; CCreatureAnimation *anim; CCreature *c; @@ -523,6 +524,7 @@ public: void activate(); void close(); void clickRight(boost::logic::tribool down); + void dismissF(); void keyPressed (SDL_KeyboardEvent & key); void deactivate(); void show(SDL_Surface * to = NULL); diff --git a/config/cr_upgrade_list.txt b/config/cr_upgrade_list.txt new file mode 100644 index 000000000..eb186e305 --- /dev/null +++ b/config/cr_upgrade_list.txt @@ -0,0 +1,80 @@ +0 1 +2 3 +4 5 +6 7 +8 9 +10 11 +12 13 +14 15 +16 17 +18 19 +20 21 +22 23 +24 25 +26 27 +28 29 +30 31 +32 33 +34 35 +36 37 +38 39 +40 41 +42 43 +44 45 +46 47 +48 49 +50 51 +52 53 +54 55 +56 57 +58 59 +60 61 +62 63 +64 65 +66 67 +68 69 +70 71 +72 73 +74 75 +76 77 +78 79 +80 81 +82 83 +84 85 +86 87 +88 89 +90 91 +92 93 +94 95 +96 97 +98 99 +100 101 +102 103 +104 105 +106 107 +108 109 +110 111 +118 119 +120 121 +112 127 +113 125 +114 129 +115 123 +130 131 +2 137 +3 137 +18 137 +19 137 +34 136 +35 136 +8 136 +9 136 +13 150 +27 151 +41 152 +55 153 +69 154 +83 155 +97 156 +111 157 +131 15 \ No newline at end of file diff --git a/config/crerefnam.txt b/config/crerefnam.txt index c098f49bd..9c59edcc5 100644 --- a/config/crerefnam.txt +++ b/config/crerefnam.txt @@ -113,12 +113,17 @@ 110 Hydra 111 ChaosHydra 112 AirElemental +112 AirElementals 113 EarthElemental +113 EarthElementals 114 FireElemental +114 FireElementals 115 WaterElemental +115 WaterElementals 116 GoldGolem 117 DiamondGolem 118 Pixie +118 Pixies 119 Sprite 120 PsiElemental 121 MagicElemental diff --git a/hch/CCreatureHandler.cpp b/hch/CCreatureHandler.cpp index e57895b37..30ee3afab 100644 --- a/hch/CCreatureHandler.cpp +++ b/hch/CCreatureHandler.cpp @@ -369,6 +369,16 @@ void CCreatureHandler::loadCreatures() ifs.close(); ifs.clear(); + ifs.open("config/cr_upgrade_list.txt"); + while(!ifs.eof()) + { + int id, up; + ifs >> id >> up; + creatures[id].upgrades.insert(up); + } + ifs.close(); + ifs.clear(); + //loading 32x32px imgs CDefHandler *smi = CGI->spriteh->giveDef("CPRSMALL.DEF"); smi->notFreeImgs = true; diff --git a/hch/CCreatureHandler.h b/hch/CCreatureHandler.h index 3d67cef3d..ea1c0e137 100644 --- a/hch/CCreatureHandler.h +++ b/hch/CCreatureHandler.h @@ -15,6 +15,7 @@ class CCreature public: std::string namePl, nameSing, nameRef; //name in singular and plural form; and reference name std::vector cost; //cost[res_id] - amount of that resource + std::set upgrades; // IDs of creatures to which this creature can be upgraded int fightValue, AIValue, growth, hordeGrowth, hitPoints, speed, attack, defence, shots, spells; int damageMin, damageMax; int ammMin, ammMax; diff --git a/hch/CHeroHandler.cpp b/hch/CHeroHandler.cpp index 6be8f39e8..585148f1a 100644 --- a/hch/CHeroHandler.cpp +++ b/hch/CHeroHandler.cpp @@ -116,6 +116,9 @@ void CHeroHandler::loadHeroes() CGeneralTextHandler::loadToIt(pom,buf,it,4); nher->highStack[x] = atoi(pom.c_str()); CGeneralTextHandler::loadToIt(nher->refTypeStack[x],buf,it,(x==2) ? (3) : (4)); + int hlp = nher->refTypeStack[x].find_first_of(' ',0); + if(hlp>=0) + nher->refTypeStack[x].replace(hlp,1,""); } nher->ID = heroes.size(); diff --git a/hch/CObjectHandler.cpp b/hch/CObjectHandler.cpp index 8b5958b67..5106bd02f 100644 --- a/hch/CObjectHandler.cpp +++ b/hch/CObjectHandler.cpp @@ -349,6 +349,7 @@ CGHeroInstance::CGHeroInstance() isStanding = true; moveDir = 4; mana = 0; + visitedTown = NULL; } CGHeroInstance::~CGHeroInstance() diff --git a/hch/CObjectHandler.h b/hch/CObjectHandler.h index 31e0d7ab9..8fc2b9f48 100644 --- a/hch/CObjectHandler.h +++ b/hch/CObjectHandler.h @@ -304,7 +304,7 @@ class CGObjectInstance { public: int3 pos; //h3m pos - int ID, subID; //normal ID (this one from OH3 maps ;]) + int ID, subID; //normal ID (this one from OH3 maps ;]) - eg. town=98; hero=34 int id;//number of object in CObjectHandler's vector CGDefInfo * defInfo; CCPPObjectScript * state; @@ -350,14 +350,11 @@ public: std::vector primSkills; //0-attack, 1-defence, 2-spell power, 3-knowledge std::vector > secSkills; //first - ID of skill, second - level of skill (0 - basic, 1 - adv., 2 - expert) int movement; //remaining movement points + bool inTownGarrison; // if hero is in town garrison + CGTownInstance * visitedTown; //set if hero is visiting town or in the town garrison std::vector artifacts; //hero's artifacts from bag - //CArtifact * artHead, * artLRing, * artRRing, * artLHand, - // * artRhand, * artFeet, * artSpellBook, * artMach1, - // * artMach2, * artMach3, * artMach4, * artMisc1, * artMisc2, - // * artMisc3, * artMisc4, * artMisc5, * artTorso, * artNeck, - // * artShoulders; //working artifacts std::vector artifWorn; // 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 virtual bool isHero() const;