diff --git a/CAdvmapInterface.cpp b/CAdvmapInterface.cpp index 432045a78..e9e9fec26 100644 --- a/CAdvmapInterface.cpp +++ b/CAdvmapInterface.cpp @@ -643,6 +643,14 @@ void CTerrainRect::showPath(const SDL_Rect * extRect) { pn = 4; } + else if(cv[i-1].coord.x == cv[i].coord.x+1 && cv[i-1].coord.y == cv[i].coord.y) //356 + { + pn = 3; + } + else if(cv[i-1].coord.x == cv[i].coord.x && cv[i-1].coord.y == cv[i].coord.y-1) //352 + { + pn = 17; + } } else if (cv[i+1].coord.x == cv[i].coord.x+1 && cv[i+1].coord.y == cv[i].coord.y) //65x { @@ -697,6 +705,14 @@ void CTerrainRect::showPath(const SDL_Rect * extRect) { pn = 18; } + else if(cv[i-1].coord.x == cv[i].coord.x+1 && cv[i-1].coord.y == cv[i].coord.y) //956 + { + pn = 19; + } + else if(cv[i-1].coord.x == cv[i].coord.x && cv[i-1].coord.y == cv[i].coord.y+1) //958 + { + pn = 5; + } } else if (cv[i+1].coord.x == cv[i].coord.x && cv[i+1].coord.y == cv[i].coord.y+1) //85x { diff --git a/CBattleInterface.cpp b/CBattleInterface.cpp index c685354d3..84abf5da0 100644 --- a/CBattleInterface.cpp +++ b/CBattleInterface.cpp @@ -44,7 +44,7 @@ struct CMP_stack2 CBattleInterface::CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, CGHeroInstance *hero1, CGHeroInstance *hero2, const SDL_Rect & myRect) : printCellBorders(true), attackingHeroInstance(hero1), defendingHeroInstance(hero2), animCount(0), activeStack(-1), givenCommand(NULL), attackingInfo(NULL), myTurn(false), resWindow(NULL), showStackQueue(false), animSpeed(2), printStackRange(true), - printMouseShadow(true), spellDestSelectMode(false), spellToCast(NULL), previouslyHoveredHex(-1) + printMouseShadow(true), spellDestSelectMode(false), spellToCast(NULL), previouslyHoveredHex(-1), moveStarted(false), mouseHoveredStack(-1) { pos = myRect; strongInterest = true; @@ -458,7 +458,7 @@ void CBattleInterface::show(SDL_Surface * to) { for(size_t v=0; vnextFrame(to, creAnims[stackDeadByHex[b][v]]->pos.x + pos.x, creAnims[stackDeadByHex[b][v]]->pos.y + pos.y, creDir[stackDeadByHex[b][v]], false, stackDeadByHex[b][v]==activeStack); //increment always when moving, never if stack died + creAnims[stackDeadByHex[b][v]]->nextFrame(to, creAnims[stackDeadByHex[b][v]]->pos.x + pos.x, creAnims[stackDeadByHex[b][v]]->pos.y + pos.y, creDir[stackDeadByHex[b][v]], animCount, false); //increment always when moving, never if stack died } } for(int b=0; bgetType(); - bool incrementFrame = (animCount%(4/animSpeed)==0) && animType!=0 && animType!=5 && animType!=20 && animType!=21 && animType!=3; - creAnims[stackAliveByHex[b][v]]->nextFrame(to, creAnims[stackAliveByHex[b][v]]->pos.x + pos.x, creAnims[stackAliveByHex[b][v]]->pos.y + pos.y, creDir[stackAliveByHex[b][v]], incrementFrame, stackAliveByHex[b][v]==activeStack); //increment always when moving, never if stack died + bool incrementFrame = (animCount%(4/animSpeed)==0) && animType!=0 && animType!=5 && animType!=20 && animType!=21 && animType!=3 && animType!=2; + if(animType == 2) + { + if(standingFrame.find(stackAliveByHex[b][v])!=standingFrame.end()) + { + incrementFrame = (animCount%(8/animSpeed)==0); + if(incrementFrame) + { + ++standingFrame[stackAliveByHex[b][v]]; + if(standingFrame[stackAliveByHex[b][v]] == creAnims[stackAliveByHex[b][v]]->framesInGroup(2)) + { + standingFrame.erase(standingFrame.find(stackAliveByHex[b][v])); + } + } + } + else + { + if((rand()%50) == 0) + { + standingFrame.insert(std::make_pair(stackAliveByHex[b][v], 0)); + } + } + } + + creAnims[stackAliveByHex[b][v]]->nextFrame(to, creAnims[stackAliveByHex[b][v]]->pos.x + pos.x, creAnims[stackAliveByHex[b][v]]->pos.y + pos.y, creDir[stackAliveByHex[b][v]], animCount, incrementFrame, stackAliveByHex[b][v]==activeStack, stackAliveByHex[b][v]==mouseHoveredStack); //increment always when moving, never if stack died //printing amount if(stacks[stackAliveByHex[b][v]].amount > 0) //don't print if stack is not alive { @@ -614,6 +637,7 @@ void CBattleInterface::mouseMoved(const SDL_MouseMotionEvent &sEvent) { if(activeStack>=0 && !spellDestSelectMode) { + mouseHoveredStack = -1; int myNumber = -1; //number of hovered tile for(int g=0; ggeneraltexth->allTexts[297].c_str(), shere->amount == 1 ? shere->creature->nameSing.c_str() : shere->creature->namePl.c_str()); console->alterTxt = buf; console->whoSetAlter = 0; + mouseHoveredStack = shere->ID; + if(creAnims[shere->ID]->getType() == 2 && creAnims[shere->ID]->framesInGroup(1) > 0) + { + creAnims[shere->ID]->playOnce(1); + } } else if(LOCPLINT->cb->battleCanShoot(activeStack,myNumber)) //we can shoot enemy { @@ -988,9 +1017,14 @@ void CBattleInterface::stackMoved(int number, int destHex, bool endMoving) if(startMoving) //animation of starting move; some units don't have this animation (ie. halberdier) { - CGI->curh->hide(); handleStartMoving(number); } + if(moveStarted) + { + CGI->curh->hide(); + creAnims[number]->setType(0); + moveStarted = false; + } int mutPos = BattleInfo::mutualPosition(curStackPos, destHex); @@ -1007,7 +1041,6 @@ void CBattleInterface::stackMoved(int number, int destHex, bool endMoving) break; } //moving instructions - creAnims[number]->setType(0); float posX = creAnims[number]->pos.x, posY = creAnims[number]->pos.y; // for precise calculations ;] for(int i=0; imaxframe = creAnims[ID]->framesInGroup(12); break; default: - tlog1<<"Critical Error! Wrong dest in stackAttacking!"< creDir; // unsigned char animCount; int activeStack; //number of active stack; -1 - no one + int mouseHoveredStack; //stack hovered by mouse; if -1 -> none std::vector shadedHexes; //hexes available for active stack int previouslyHoveredHex; //number of hex that was hovered by the cursor a while ago int currentlyHoveredHex; //number of hex that is supposed to be hovered (for a while it may be inappropriately set, but will be renewed soon) int animSpeed; //speed of animation; 1 - slowest, 2 - medium, 4 - fastest float getAnimSpeedMultiplier() const; //returns multiplier for number of frames in a group + std::map standingFrame; //number of frame in standing animation by stack ID, helps in showing 'random moves' bool spellDestSelectMode; //if true, player is choosing destination for his spell int spellSelMode; //0 - any location, 1 - any firendly creature, 2 - any hostile creature, 3 - any creature, 4 - obstacle, -1 - no location @@ -209,6 +211,8 @@ public: CBattleReslutWindow * resWindow; //window of end of battle bool showStackQueue; //if true, queue of stacks will be shown + bool moveStarted; //if true, the creature that is already moving is going to make its first step + //button handle funcs: void bOptionsf(); void bSurrenderf(); diff --git a/CCastleInterface.cpp b/CCastleInterface.cpp index b5d919455..83c193217 100644 --- a/CCastleInterface.cpp +++ b/CCastleInterface.cpp @@ -1597,7 +1597,7 @@ CBlacksmithDialog::CBlacksmithDialog(bool possible, int creMachineID, int aid, i blitAt(bg2,64,50,bmp); SDL_FreeSurface(bg2); CCreatureAnimation cra(CGI->creh->creatures[creMachineID].animDefName); - cra.nextFrameMiddle(bmp,170,120,true,false); + cra.nextFrameMiddle(bmp,170,120,true,0,false); char pom[75]; sprintf(pom,CGI->generaltexth->allTexts[274].c_str(),CGI->creh->creatures[creMachineID].nameSing.c_str()); //build a new ... printAtMiddle(pom,165,28,GEORXX,tytulowy,bmp); diff --git a/CGameState.h b/CGameState.h index 27f4667f6..79a6639f3 100644 --- a/CGameState.h +++ b/CGameState.h @@ -241,7 +241,7 @@ private: int battleGetBattlefieldType(int3 tile = int3());// 1. sand/shore 2. sand/mesas 3. dirt/birches 4. dirt/hills 5. dirt/pines 6. grass/hills 7. grass/pines 8. lava 9. magic plains 10. snow/mountains 11. snow/trees 12. subterranean 13. swamp/trees 14. fiery fields 15. rock lands 16. magic clouds 17. lucid pools 18. holy ground 19. clover field 20. evil fog 21. "favourable winds" text on magic plains background 22. cursed ground 23. rough 24. ship to ship 25. ship UpgradeInfo getUpgradeInfo(CArmedInstance *obj, int stackPos); float getMarketEfficiency(int player, int mode=0); - std::set tilesToReveal(int3 pos, int radious, int player) const; //if player==-1 => adds all tiles in radious + std::set tilesToReveal(int3 pos, int radious, int player) const; //if player==-1 => adds all tiles in radious int canBuildStructure(const CGTownInstance *t, int ID);// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements public: CGameState(); diff --git a/CPlayerInterface.cpp b/CPlayerInterface.cpp index 0e892f7bb..cf09006bf 100644 --- a/CPlayerInterface.cpp +++ b/CPlayerInterface.cpp @@ -2093,11 +2093,13 @@ void CPlayerInterface::actionStarted(const BattleAction* action) { boost::unique_lock un(*pim); curAction = action; - if((action->actionType==2 || (action->actionType==6 && action->destinationTile!=cb->battleGetPos(action->stackNumber))) - && battleInt->creAnims[action->stackNumber]->framesInGroup(20) - ) + if( (action->actionType==2 || (action->actionType==6 && action->destinationTile!=cb->battleGetPos(action->stackNumber))) ) { - battleInt->creAnims[action->stackNumber]->setType(20); + battleInt->moveStarted = true; + if(battleInt->creAnims[action->stackNumber]->framesInGroup(20)) + { + battleInt->creAnims[action->stackNumber]->setType(20); + } } @@ -3003,7 +3005,7 @@ int CCreaturePic::blitPic(SDL_Surface *to, int x, int y, bool nextFrame) } if(c->isDoubleWide()) x-=15; - return anim->nextFrameMiddle(to,x+78,y+(big ? 55 : 45),true,nextFrame,false,&dst); + return anim->nextFrameMiddle(to,x+78,y+(big ? 55 : 45),true,0,nextFrame,false,false,&dst); } SDL_Surface * CCreaturePic::getPic(bool nextFrame) { diff --git a/client/CCreatureAnimation.cpp b/client/CCreatureAnimation.cpp index 2b8662a8c..953a98e5f 100644 --- a/client/CCreatureAnimation.cpp +++ b/client/CCreatureAnimation.cpp @@ -22,7 +22,7 @@ void CCreatureAnimation::setType(int type) } } -CCreatureAnimation::CCreatureAnimation(std::string name) : RLEntries(NULL), internalFrame(0) +CCreatureAnimation::CCreatureAnimation(std::string name) : RLEntries(NULL), internalFrame(0), once(false) { FDef = CDefHandler::Spriteh->giveFile(name); //load main file @@ -102,9 +102,9 @@ int CCreatureAnimation::readNormalNr (int pos, int bytCon, unsigned char * str) } return ret; } -int CCreatureAnimation::nextFrameMiddle(SDL_Surface *dest, int x, int y, bool attacker, bool incrementFrame, bool yellowBorder, SDL_Rect * destRect) +int CCreatureAnimation::nextFrameMiddle(SDL_Surface *dest, int x, int y, bool attacker, unsigned char animCount, bool incrementFrame, bool yellowBorder, bool blueBorder, SDL_Rect * destRect) { - return nextFrame(dest,x-fullWidth/2,y-fullHeight/2,attacker,incrementFrame,yellowBorder,destRect); + return nextFrame(dest, x-fullWidth/2, y-fullHeight/2, attacker, animCount, incrementFrame, yellowBorder, blueBorder, destRect); } void CCreatureAnimation::incrementFrame() { @@ -113,7 +113,16 @@ void CCreatureAnimation::incrementFrame() { if(internalFrame == frameGroups[type].size()) //rewind { - curFrame = frameGroups[type][0]; + if(once) + { + type = 2; + once = false; + curFrame = frameGroups[2][0]; + } + else + { + curFrame = frameGroups[type][0]; + } } } else @@ -128,7 +137,13 @@ int CCreatureAnimation::getFrame() const return curFrame; } -int CCreatureAnimation::nextFrame(SDL_Surface *dest, int x, int y, bool attacker, bool IncrementFrame, bool yellowBorder, SDL_Rect * destRect) +void CCreatureAnimation::playOnce(int type) +{ + setType(type); + once = true; +} + +int CCreatureAnimation::nextFrame(SDL_Surface *dest, int x, int y, bool attacker, unsigned char animCount, bool IncrementFrame, bool yellowBorder, bool blueBorder, SDL_Rect * destRect) { if(dest->format->BytesPerPixel<3) return -1; //not enough depth @@ -182,6 +197,7 @@ int CCreatureAnimation::nextFrame(SDL_Surface *dest, int x, int y, bool attacker { SegmentType=FDef[BaseOffset++]; SegmentLength=FDef[BaseOffset++]; + unsigned char aCountMod = (animCount & 0x20) ? ((animCount & 0x1e)>>1)<<4 : 0x0f - ((animCount & 0x1e)>>1)<<4; if (SegmentType==0xFF) { for (int k=0;k<=SegmentLength;k++) @@ -191,7 +207,7 @@ int CCreatureAnimation::nextFrame(SDL_Surface *dest, int x, int y, bool attacker if(xB>=0 && yB>=0 && xBw && yBh) { if(!destRect || (destRect->x <= xB && destRect->x + destRect->w > xB && destRect->y <= yB && destRect->y + destRect->h > yB)) - putPixel(dest, xB + yB*dest->w, palette[FDef[BaseOffset+k]], FDef[BaseOffset+k], yellowBorder); + putPixel(dest, xB + yB*dest->w, palette[FDef[BaseOffset+k]], FDef[BaseOffset+k], yellowBorder, blueBorder, aCountMod); } ftcp++; //increment pos if ((TotalRowLength+k+1)>=SpriteWidth) @@ -209,7 +225,7 @@ int CCreatureAnimation::nextFrame(SDL_Surface *dest, int x, int y, bool attacker if(xB>=0 && yB>=0 && xBw && yBh) { if(!destRect || (destRect->x <= xB && destRect->x + destRect->w > xB && destRect->y <= yB && destRect->y + destRect->h > yB)) - putPixel(dest, xB + yB*dest->w, palette[SegmentType], SegmentType, yellowBorder); + putPixel(dest, xB + yB*dest->w, palette[SegmentType], SegmentType, yellowBorder, blueBorder, aCountMod); } ftcp++; //increment pos } @@ -249,7 +265,9 @@ inline void CCreatureAnimation::putPixel( const int & ftcp, const BMPPalette & color, const unsigned char & palc, - const bool & yellowBorder + const bool & yellowBorder, + const bool & blueBorder, + const unsigned char & animCount ) const { if(palc!=0) @@ -261,17 +279,35 @@ inline void CCreatureAnimation::putPixel( p[1] = color.G; p[2] = color.R; } - else if(yellowBorder && (palc == 6 || palc == 7)) //dark yellow border + else if((yellowBorder || blueBorder) && (palc == 6 || palc == 7)) //dark yellow border { - p[0] = 0; - p[1] = 0xff; - p[2] = 0xff; + if(blueBorder) + { + p[0] = 0x0f + animCount; + p[1] = 0x0f + animCount; + p[2] = 0; + } + else + { + p[0] = 0; + p[1] = 0x0f + animCount; + p[2] = 0x0f + animCount; + } } - else if(yellowBorder && (palc == 5)) //yellow border + else if((yellowBorder || blueBorder) && (palc == 5)) //yellow border { - p[0] = color.B; - p[1] = color.G; - p[2] = color.R; + if(blueBorder) + { + p[0] = color.R - 0xf0 + animCount; + p[1] = color.G - 0xf0 + animCount; + p[2] = color.B; + } + else + { + p[0] = color.B; + p[1] = color.G - 0xf0 + animCount; + p[2] = color.R - 0xf0 + animCount; + } } else if(palc < 5) //shadow { diff --git a/client/CCreatureAnimation.h b/client/CCreatureAnimation.h index 7201dd1e7..31eb707b0 100644 --- a/client/CCreatureAnimation.h +++ b/client/CCreatureAnimation.h @@ -26,7 +26,9 @@ private: const int & ftcp, const BMPPalette & color, const unsigned char & palc, - const bool & yellowBorder + const bool & yellowBorder, + const bool & blueBorder, + const unsigned char & animCount ) const; //////////// @@ -44,11 +46,14 @@ public: void setType(int type); //sets type of animation and cleares framecount int getType() const; //returns type of animation - int nextFrame(SDL_Surface * dest, int x, int y, bool attacker, bool incrementFrame = true, bool yellowBorder = false, SDL_Rect * destRect = NULL); //0 - success, any other - error //print next - int nextFrameMiddle(SDL_Surface * dest, int x, int y, bool attacker, bool IncrementFrame = true, bool yellowBorder = false, SDL_Rect * destRect = NULL); //0 - success, any other - error //print next + int nextFrame(SDL_Surface * dest, int x, int y, bool attacker, unsigned char animCount, bool incrementFrame = true, bool yellowBorder = false, bool blueBorder = false, SDL_Rect * destRect = NULL); //0 - success, any other - error //print next + int nextFrameMiddle(SDL_Surface * dest, int x, int y, bool attacker, unsigned char animCount, bool IncrementFrame = true, bool yellowBorder = false, bool blueBorder = false, SDL_Rect * destRect = NULL); //0 - success, any other - error //print next void incrementFrame(); int getFrame() const; + bool once; + void playOnce(int type); //plays once given stage of animation, then resets to 2 + int framesInGroup(int group) const; //retirns number of fromes in given group }; diff --git a/hch/CCreatureHandler.cpp b/hch/CCreatureHandler.cpp index 11bafb9d3..0fdfd1f79 100644 --- a/hch/CCreatureHandler.cpp +++ b/hch/CCreatureHandler.cpp @@ -456,6 +456,7 @@ void CCreatureHandler::loadCreatures() creatures[115].abilities.insert(DOUBLE_WIDE);//water elemental should be treated as double-wide creatures[123].abilities.insert(DOUBLE_WIDE);//ice elemental should be treated as double-wide creatures[140].abilities.insert(DOUBLE_WIDE);//boar should be treated as double-wide + creatures[142].abilities.insert(DOUBLE_WIDE);//nomads should be treated as double-wide } void CCreatureHandler::loadAnimationInfo()