1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-12 02:28:11 +02:00

* fixed #9 and #12 from 0.7b bug thread

* more logging around #19 from that thread
* glowing effect of yellow border around creatures
* blue glowing border around hovered creature
* making animation on battlefield more smooth
* standing stacks have more static animation
This commit is contained in:
mateuszb 2009-02-21 15:43:28 +00:00
parent a635ac7143
commit f835ea9033
9 changed files with 130 additions and 33 deletions

View File

@ -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
{

View File

@ -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; v<stackDeadByHex[b].size(); ++v)
{
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]], 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; b<BFIELD_SIZE; ++b) //showing alive stacks
@ -466,8 +466,31 @@ void CBattleInterface::show(SDL_Surface * to)
for(size_t v=0; v<stackAliveByHex[b].size(); ++v)
{
int animType = creAnims[stackAliveByHex[b][v]]->getType();
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; g<BFIELD_SIZE; ++g)
{
@ -647,6 +671,11 @@ void CBattleInterface::mouseMoved(const SDL_MouseMotionEvent &sEvent)
sprintf(buf, CGI->generaltexth->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; i<steps; ++i)
{
@ -1358,7 +1391,7 @@ void CBattleInterface::stackAttacking(int ID, int dest)
attackingInfo->maxframe = creAnims[ID]->framesInGroup(12);
break;
default:
tlog1<<"Critical Error! Wrong dest in stackAttacking!"<<std::endl;
tlog1<<"Critical Error! Wrong dest in stackAttacking! dest: "<<dest<<" attacking stack pos: "<<aStack.position<<" reversed shift: "<<reversedShift<<std::endl;
}
}

View File

@ -137,11 +137,13 @@ private:
std::map< int, bool > creDir; // <creatureID, if false reverse creature's animation>
unsigned char animCount;
int activeStack; //number of active stack; -1 - no one
int mouseHoveredStack; //stack hovered by mouse; if -1 -> none
std::vector<int> 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<int, int> 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();

View File

@ -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);

View File

@ -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<int3> tilesToReveal(int3 pos, int radious, int player) const; //if player==-1 => adds all tiles in radious
std::set<int3> 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();

View File

@ -2093,11 +2093,13 @@ void CPlayerInterface::actionStarted(const BattleAction* action)
{
boost::unique_lock<boost::recursive_mutex> 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)
{

View File

@ -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 && xB<dest->w && yB<dest->h)
{
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 && xB<dest->w && yB<dest->h)
{
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
{

View File

@ -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
};

View File

@ -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()