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

- Fixed some warnings from cppcheck

- Minor improvements to JSON validation
- Cleanup in SDL_Extensions.cpp
- Implemented new propery for creature format: idle animation duration
- Disabled idle animation of some of conflux creatures (was clearly
broken)
This commit is contained in:
Ivan Savenko 2013-11-06 13:42:58 +00:00
parent 86b7feeab3
commit 71d6b0fea9
24 changed files with 159 additions and 183 deletions

View File

@ -176,7 +176,7 @@ CDefEssential * Graphics::loadHeroAnim( const std::string &name, const std::vect
for(int e=0; e<8; ++e) for(int e=0; e<8; ++e)
{ {
Cimage nci; Cimage nci;
nci.bitmap = CSDL_Ext::rotate01(anim->ourImages[o+e].bitmap); nci.bitmap = CSDL_Ext::verticalFlip(anim->ourImages[o+e].bitmap);
nci.groupNumber = rotations[p].second; nci.groupNumber = rotations[p].second;
nci.imName = std::string(); nci.imName = std::string();
anim->ourImages.push_back(nci); anim->ourImages.push_back(nci);
@ -218,7 +218,7 @@ void Graphics::loadHeroFlagsDetail(std::pair<std::vector<CDefEssential *> Graphi
for(int e=0; e<8; ++e) for(int e=0; e<8; ++e)
{ {
Cimage nci; Cimage nci;
nci.bitmap = CSDL_Ext::rotate01(curImgs[o+e].bitmap); nci.bitmap = CSDL_Ext::verticalFlip(curImgs[o+e].bitmap);
nci.groupNumber = rotation.second; nci.groupNumber = rotation.second;
nci.imName = std::string(); nci.imName = std::string();
curImgs.push_back(nci); curImgs.push_back(nci);
@ -236,7 +236,7 @@ void Graphics::loadHeroFlagsDetail(std::pair<std::vector<CDefEssential *> Graphi
for(int e=0; e<8; ++e) for(int e=0; e<8; ++e)
{ {
Cimage nci; Cimage nci;
nci.bitmap = CSDL_Ext::rotate01(curImgs[o+e].bitmap); nci.bitmap = CSDL_Ext::verticalFlip(curImgs[o+e].bitmap);
nci.groupNumber = 12 + curImgs[o].groupNumber; nci.groupNumber = 12 + curImgs[o].groupNumber;
nci.imName = std::string(); nci.imName = std::string();
curImgs.push_back(nci); curImgs.push_back(nci);

View File

@ -1336,10 +1336,10 @@ void CBattleInterface::spellCast( const BattleSpellCast * sc )
//displaying message in console //displaying message in console
bool customSpell = false; bool customSpell = false;
bool plural = false; //add singular / plural form of creature text if this is true
int textID = 0;
if(sc->affectedCres.size() == 1) if(sc->affectedCres.size() == 1)
{ {
bool plural = false; //add singular / plural form of creature text if this is true
int textID = 0;
std::string text = CGI->generaltexth->allTexts[195]; std::string text = CGI->generaltexth->allTexts[195];
if(sc->castedByHero) if(sc->castedByHero)
{ {
@ -1970,8 +1970,6 @@ void CBattleInterface::startAction(const BattleAction* action)
redraw(); // redraw after deactivation, including proper handling of hovered hexes redraw(); // redraw after deactivation, including proper handling of hovered hexes
char txt[400];
if (action->actionType == Battle::HERO_SPELL) //when hero casts spell if (action->actionType == Battle::HERO_SPELL) //when hero casts spell
{ {
if(action->side) if(action->side)
@ -2006,8 +2004,8 @@ void CBattleInterface::startAction(const BattleAction* action)
if(txtid) if(txtid)
{ {
sprintf(txt, CGI->generaltexth->allTexts[txtid].c_str(), (stack->count != 1) ? stack->getCreature()->namePl.c_str() : stack->getCreature()->nameSing.c_str(), 0); std::string name = (stack->count != 1) ? stack->getCreature()->namePl.c_str() : stack->getCreature()->nameSing.c_str();
console->addText(txt); console->addText((boost::format(CGI->generaltexth->allTexts[txtid].c_str()) % name).str());
} }
//displaying special abilities //displaying special abilities
@ -3186,7 +3184,7 @@ void CBattleInterface::showProjectiles(SDL_Surface * to)
if(it->reverse) if(it->reverse)
{ {
SDL_Surface * rev = CSDL_Ext::rotate01(image); SDL_Surface * rev = CSDL_Ext::verticalFlip(image);
CSDL_Ext::blit8bppAlphaTo24bpp(rev, nullptr, to, &dst); CSDL_Ext::blit8bppAlphaTo24bpp(rev, nullptr, to, &dst);
SDL_FreeSurface(rev); SDL_FreeSurface(rev);
} }

View File

@ -222,7 +222,7 @@ CBattleHero::CBattleHero(const std::string & defName, bool flipG, PlayerColor pl
{ {
if(flip) if(flip)
{ {
SDL_Surface * hlp = CSDL_Ext::rotate01(elem.bitmap); SDL_Surface * hlp = CSDL_Ext::verticalFlip(elem.bitmap);
SDL_FreeSurface(elem.bitmap); SDL_FreeSurface(elem.bitmap);
elem.bitmap = hlp; elem.bitmap = hlp;
} }

View File

@ -68,8 +68,9 @@ float AnimationControls::getCreatureAnimationSpeed(const CCreature * creature, c
return speed * 2 * creature->animation.walkAnimationTime / anim->framesInGroup(type); return speed * 2 * creature->animation.walkAnimationTime / anim->framesInGroup(type);
case CCreatureAnim::MOUSEON: case CCreatureAnim::MOUSEON:
case CCreatureAnim::HOLDING:
return baseSpeed; return baseSpeed;
case CCreatureAnim::HOLDING:
return baseSpeed * creature->animation.idleAnimationTime / anim->framesInGroup(type);
case CCreatureAnim::SHOOT_UP: case CCreatureAnim::SHOOT_UP:
case CCreatureAnim::SHOOT_FRONT: case CCreatureAnim::SHOOT_FRONT:
@ -452,5 +453,7 @@ void CCreatureAnimation::pause()
void CCreatureAnimation::play() void CCreatureAnimation::play()
{ {
speed = 0;
if (speedController(this, type) != 0)
speed = 1 / speedController(this, type); speed = 1 / speedController(this, type);
} }

View File

@ -62,96 +62,56 @@ void blitAt(SDL_Surface * src, const SDL_Rect & pos, SDL_Surface * dst)
blitAt(src,pos.x,pos.y,dst); blitAt(src,pos.x,pos.y,dst);
} }
void updateRect (SDL_Rect * rect, SDL_Surface * scr)
{
SDL_UpdateRect(scr,rect->x,rect->y,rect->w,rect->h);
}
// Vertical flip // Vertical flip
SDL_Surface * CSDL_Ext::rotate01(SDL_Surface * toRot) SDL_Surface * CSDL_Ext::verticalFlip(SDL_Surface * toRot)
{ {
SDL_Surface * ret = SDL_ConvertSurface(toRot, toRot->format, toRot->flags); SDL_Surface * ret = SDL_ConvertSurface(toRot, toRot->format, toRot->flags);
const int bpl = ret->pitch;
const int bpp = ret->format->BytesPerPixel; const int bpp = ret->format->BytesPerPixel;
for(int i=0; i<ret->h; i++) { char * src = reinterpret_cast<char *>(toRot->pixels);
char *src = (char *)toRot->pixels + i*bpl; char * dst = reinterpret_cast<char *>(ret->pixels);
char *dst = (char *)ret->pixels + i*bpl;
for(int j=0; j<ret->w; j++) {
for (int k=0; k<bpp; k++) {
dst[j*bpp + k] = src[(ret->w-j-1)*bpp + k];
}
}
}
for(int i=0; i<ret->h; i++)
{
char * srcPxl = src;
char * dstPxl = dst + ret->w * bpp;
if (bpp == 1)
{
// much faster for 8-bit surfaces (majority of our data)
std::reverse_copy(src, src + ret->pitch, dst);
}
else
{
for(int j=0; j<ret->w; j++)
{
dstPxl -= bpp;
std::copy(srcPxl, srcPxl + bpp, dstPxl);
srcPxl += bpp;
}
}
src += toRot->pitch;
dst += ret->pitch;
}
return ret; return ret;
} }
// Horizontal flip // Horizontal flip
SDL_Surface * CSDL_Ext::hFlip(SDL_Surface * toRot) SDL_Surface * CSDL_Ext::horizontalFlip(SDL_Surface * toRot)
{ {
SDL_Surface * ret = SDL_ConvertSurface(toRot, toRot->format, toRot->flags); SDL_Surface * ret = SDL_ConvertSurface(toRot, toRot->format, toRot->flags);
int bpl = ret->pitch; char * src = reinterpret_cast<char *>(toRot->pixels);
char * dst = reinterpret_cast<char *>(ret->pixels) + ret->h * ret->pitch;
for(int i=0; i<ret->h; i++) { for(int i=0; i<ret->h; i++)
memcpy((char *)ret->pixels + i*bpl, (char *)toRot->pixels + (ret->h-i-1)*bpl, bpl); {
dst -= ret->pitch;
std::copy(src, src + toRot->pitch, dst);
src += toRot->pitch;
} }
return ret; return ret;
}; };
///**************/
///Rotates toRot surface by 90 degrees left
///**************/
SDL_Surface * CSDL_Ext::rotate02(SDL_Surface * toRot)
{
SDL_Surface * ret = SDL_ConvertSurface(toRot, toRot->format, toRot->flags);
//SDL_SetColorKey(ret, SDL_SRCCOLORKEY, toRot->format->colorkey);
for(int i=0; i<ret->w; ++i)
{
for(int j=0; j<ret->h; ++j)
{
{
Uint8 *p = (Uint8 *)toRot->pixels + i * toRot->pitch + j * toRot->format->BytesPerPixel;
SDL_PutPixelWithoutRefresh(ret, i, j, p[2], p[1], p[0]);
}
}
}
return ret;
}
///*************/
///Rotates toRot surface by 180 degrees
///*************/
SDL_Surface * CSDL_Ext::rotate03(SDL_Surface * toRot)
{
SDL_Surface * ret = SDL_ConvertSurface(toRot, toRot->format, toRot->flags);
if(ret->format->BytesPerPixel!=1)
{
for(int i=0; i<ret->w; ++i)
{
for(int j=0; j<ret->h; ++j)
{
{
Uint8 *p = (Uint8 *)toRot->pixels + (ret->h - j - 1) * toRot->pitch + (ret->w - i - 1) * toRot->format->BytesPerPixel+2;
SDL_PutPixelWithoutRefresh(ret, i, j, p[2], p[1], p[0], 0);
}
}
}
}
else
{
for(int i=0; i<ret->w; ++i)
{
for(int j=0; j<ret->h; ++j)
{
Uint8 *p = (Uint8 *)toRot->pixels + (ret->h - j - 1) * toRot->pitch + (ret->w - i - 1) * toRot->format->BytesPerPixel;
(*((Uint8*)ret->pixels + j*ret->pitch + i*ret->format->BytesPerPixel)) = *p;
}
}
}
return ret;
}
Uint32 CSDL_Ext::SDL_GetPixel(SDL_Surface *surface, const int & x, const int & y, bool colorByte) Uint32 CSDL_Ext::SDL_GetPixel(SDL_Surface *surface, const int & x, const int & y, bool colorByte)
{ {
int bpp = surface->format->BytesPerPixel; int bpp = surface->format->BytesPerPixel;
@ -162,9 +122,7 @@ Uint32 CSDL_Ext::SDL_GetPixel(SDL_Surface *surface, const int & x, const int & y
{ {
case 1: case 1:
if(colorByte) if(colorByte)
{
return colorToUint32(surface->format->palette->colors+(*p)); return colorToUint32(surface->format->palette->colors+(*p));
}
else else
return *p; return *p;

View File

@ -34,7 +34,6 @@ struct Rect;
extern SDL_Surface * screen, *screen2, *screenBuf; extern SDL_Surface * screen, *screen2, *screenBuf;
void blitAt(SDL_Surface * src, int x, int y, SDL_Surface * dst=screen); void blitAt(SDL_Surface * src, int x, int y, SDL_Surface * dst=screen);
void blitAt(SDL_Surface * src, const SDL_Rect & pos, SDL_Surface * dst=screen); void blitAt(SDL_Surface * src, const SDL_Rect & pos, SDL_Surface * dst=screen);
void updateRect (SDL_Rect * rect, SDL_Surface * scr = screen);
bool isItIn(const SDL_Rect * rect, int x, int y); bool isItIn(const SDL_Rect * rect, int x, int y);
/** /**
@ -137,16 +136,12 @@ namespace CSDL_Ext
void SDL_PutPixelWithoutRefresh(SDL_Surface *ekran, const int & x, const int & y, const Uint8 & R, const Uint8 & G, const Uint8 & B, Uint8 A = 255); void SDL_PutPixelWithoutRefresh(SDL_Surface *ekran, const int & x, const int & y, const Uint8 & R, const Uint8 & G, const Uint8 & B, Uint8 A = 255);
void SDL_PutPixelWithoutRefreshIfInSurf(SDL_Surface *ekran, const int & x, const int & y, const Uint8 & R, const Uint8 & G, const Uint8 & B, Uint8 A = 255); void SDL_PutPixelWithoutRefreshIfInSurf(SDL_Surface *ekran, const int & x, const int & y, const Uint8 & R, const Uint8 & G, const Uint8 & B, Uint8 A = 255);
SDL_Surface * rotate01(SDL_Surface * toRot); //vertical flip SDL_Surface * verticalFlip(SDL_Surface * toRot); //vertical flip
SDL_Surface * hFlip(SDL_Surface * toRot); //horizontal flip SDL_Surface * horizontalFlip(SDL_Surface * toRot); //horizontal flip
SDL_Surface * rotate02(SDL_Surface * toRot); //rotate 90 degrees left
SDL_Surface * rotate03(SDL_Surface * toRot); //rotate 180 degrees
SDL_Cursor * SurfaceToCursor(SDL_Surface *image, int hx, int hy); //creates cursor from bitmap
Uint32 SDL_GetPixel(SDL_Surface *surface, const int & x, const int & y, bool colorByte = false); Uint32 SDL_GetPixel(SDL_Surface *surface, const int & x, const int & y, bool colorByte = false);
void alphaTransform(SDL_Surface * src); //adds transparency and shadows (partial handling only; see examples of using for details) void alphaTransform(SDL_Surface * src); //adds transparency and shadows (partial handling only; see examples of using for details)
bool isTransparent(SDL_Surface * srf, int x, int y); //checks if surface is transparent at given position bool isTransparent(SDL_Surface * srf, int x, int y); //checks if surface is transparent at given position
Uint8 *getPxPtr(const SDL_Surface * const &srf, const int x, const int y); Uint8 *getPxPtr(const SDL_Surface * const &srf, const int x, const int y);
TColorPutter getPutterFor(SDL_Surface * const &dest, int incrementing); //incrementing: -1, 0, 1 TColorPutter getPutterFor(SDL_Surface * const &dest, int incrementing); //incrementing: -1, 0, 1
TColorPutterAlpha getPutterAlphaFor(SDL_Surface * const &dest, int incrementing); //incrementing: -1, 0, 1 TColorPutterAlpha getPutterAlphaFor(SDL_Surface * const &dest, int incrementing); //incrementing: -1, 0, 1

View File

@ -104,7 +104,7 @@ void CMapHandler::prepareFOWDefs()
for(auto & elem : missRot) for(auto & elem : missRot)
{ {
nw = graphics->FoWpartialHide->ourImages[elem]; nw = graphics->FoWpartialHide->ourImages[elem];
nw.bitmap = CSDL_Ext::rotate01(nw.bitmap); nw.bitmap = CSDL_Ext::verticalFlip(nw.bitmap);
graphics->FoWpartialHide->ourImages.push_back(nw); graphics->FoWpartialHide->ourImages.push_back(nw);
} }
//necessaary rotations added //necessaary rotations added

View File

@ -36,6 +36,10 @@
"upgrades": ["stormElemental"], "upgrades": ["stormElemental"],
"graphics" : "graphics" :
{ {
"animationTime" :
{
"idle" : 0
},
"animation": "CAELEM.DEF" "animation": "CAELEM.DEF"
}, },
"sound" : "sound" :
@ -82,6 +86,10 @@
"upgrades": ["magmaElemental"], "upgrades": ["magmaElemental"],
"graphics" : "graphics" :
{ {
"animationTime" :
{
"idle" : 0
},
"animation": "CEELEM.DEF" "animation": "CEELEM.DEF"
}, },
"sound" : "sound" :
@ -129,6 +137,10 @@
"upgrades": ["energyElemental"], "upgrades": ["energyElemental"],
"graphics" : "graphics" :
{ {
"animationTime" :
{
"idle" : 0
},
"animation": "CFELEM.DEF" "animation": "CFELEM.DEF"
}, },
"sound" : "sound" :
@ -195,6 +207,10 @@
"upgrades": ["iceElemental"], "upgrades": ["iceElemental"],
"graphics" : "graphics" :
{ {
"animationTime" :
{
"idle" : 0
},
"animation": "CWELEM.DEF" "animation": "CWELEM.DEF"
}, },
"sound" : "sound" :
@ -334,6 +350,10 @@
"graphics" : "graphics" :
{ {
"animation": "CICEE.DEF", "animation": "CICEE.DEF",
"animationTime" :
{
"idle" : 0
},
"missile" : "missile" :
{ {
"projectile": "PICEE.DEF" "projectile": "PICEE.DEF"
@ -379,6 +399,10 @@
}, },
"graphics" : "graphics" :
{ {
"animationTime" :
{
"idle" : 0
},
"animation": "CSTONE.DEF" "animation": "CSTONE.DEF"
}, },
"sound" : "sound" :
@ -420,6 +444,10 @@
}, },
"graphics" : "graphics" :
{ {
"animationTime" :
{
"idle" : 0
},
"animation": "CSTORM.DEF", "animation": "CSTORM.DEF",
"missile" : "missile" :
{ {
@ -471,6 +499,10 @@
}, },
"graphics" : "graphics" :
{ {
"animationTime" :
{
"idle" : 0
},
"animation": "CNRG.DEF" "animation": "CNRG.DEF"
}, },
"sound" : "sound" :

View File

@ -172,13 +172,17 @@
"animationTime": { "animationTime": {
"type":"object", "type":"object",
"additionalProperties" : false, "additionalProperties" : false,
"required" : [ "attack", "flight", "walk" ], "required" : [ "attack", "flight", "walk", "idle" ],
"description": "Length of several animations", "description": "Length of several animations",
"properties":{ "properties":{
"attack": { "attack": {
"type":"number", "type":"number",
"description": "attack" "description": "attack"
}, },
"idle": {
"type":"number",
"description": "idle"
},
"flight": { "flight": {
"type":"number", "type":"number",
"description": "flight" "description": "flight"

View File

@ -15,13 +15,14 @@
using namespace Battle; using namespace Battle;
BattleAction::BattleAction() BattleAction::BattleAction():
side(-1),
stackNumber(-1),
actionType(INVALID),
destinationTile(-1),
additionalInfo(-1),
selectedStack(-1)
{ {
side = -1;
stackNumber = -1;
actionType = INVALID;
destinationTile = -1;
additionalInfo = -1;
} }
BattleAction BattleAction::makeHeal(const CStack *healer, const CStack *healed) BattleAction BattleAction::makeHeal(const CStack *healer, const CStack *healed)

View File

@ -19,19 +19,19 @@ BattleHex& BattleHex::moveInDir(EDir dir, bool hasToBeValid)
switch(dir) switch(dir)
{ {
case TOP_LEFT: case TOP_LEFT:
setXY(y%2 ? x-1 : x, y-1, hasToBeValid); setXY((y%2) ? x-1 : x, y-1, hasToBeValid);
break; break;
case TOP_RIGHT: case TOP_RIGHT:
setXY(y%2 ? x : x+1, y-1, hasToBeValid); setXY((y%2) ? x : x+1, y-1, hasToBeValid);
break; break;
case RIGHT: case RIGHT:
setXY(x+1, y, hasToBeValid); setXY(x+1, y, hasToBeValid);
break; break;
case BOTTOM_RIGHT: case BOTTOM_RIGHT:
setXY(y%2 ? x : x+1, y+1, hasToBeValid); setXY((y%2) ? x : x+1, y+1, hasToBeValid);
break; break;
case BOTTOM_LEFT: case BOTTOM_LEFT:
setXY(y%2 ? x-1 : x, y+1, hasToBeValid); setXY((y%2) ? x-1 : x, y+1, hasToBeValid);
break; break;
case LEFT: case LEFT:
setXY(x-1, y, hasToBeValid); setXY(x-1, y, hasToBeValid);

View File

@ -300,12 +300,12 @@ struct RangeGenerator
{ {
}; };
RangeGenerator(int _min, int _max, std::function<int()> _myRand) RangeGenerator(int _min, int _max, std::function<int()> _myRand):
min(_min),
remainingCount(_max - _min + 1),
remaining(remainingCount, true),
myRand(_myRand)
{ {
myRand = _myRand;
min = _min;
remainingCount = _max - _min + 1;
remaining.resize(remainingCount, true);
} }
int generateNumber() int generateNumber()

View File

@ -543,6 +543,7 @@ void CBattleInfoCallback::battleGetStackQueue(std::vector<const CStack *> &out,
const CStack *fastest = st[i], *other = nullptr; const CStack *fastest = st[i], *other = nullptr;
int bestSpeed = fastest->Speed(turn); int bestSpeed = fastest->Speed(turn);
//FIXME: comparison between bool and integer. Logic does not makes sense either
if(fastest->attackerOwned != lastMoved) if(fastest->attackerOwned != lastMoved)
{ {
ret = fastest; ret = fastest;
@ -648,6 +649,7 @@ void CBattleInfoCallback::battleGetStackQueue(std::vector<const CStack *> &out,
{ {
if(active) if(active)
{ {
//FIXME: both branches contain same code!!!
if(out.size() && out.front() == active) if(out.size() && out.front() == active)
lastMoved = active->attackerOwned; lastMoved = active->attackerOwned;
else else

View File

@ -531,6 +531,7 @@ void CCreatureHandler::loadUnitAnimInfo(JsonNode & graphics, CLegacyConfigParser
animationTime["walk"].Float() = parser.readNumber(); animationTime["walk"].Float() = parser.readNumber();
animationTime["attack"].Float() = parser.readNumber(); animationTime["attack"].Float() = parser.readNumber();
animationTime["flight"].Float() = parser.readNumber(); animationTime["flight"].Float() = parser.readNumber();
animationTime["idle"].Float() = 10.0;
JsonNode & missile = graphics["missile"]; JsonNode & missile = graphics["missile"];
JsonNode & offsets = missile["offset"]; JsonNode & offsets = missile["offset"];
@ -609,6 +610,7 @@ void CCreatureHandler::loadJsonAnimation(CCreature * cre, const JsonNode & graph
const JsonNode & animationTime = graphics["animationTime"]; const JsonNode & animationTime = graphics["animationTime"];
cre->animation.walkAnimationTime = animationTime["walk"].Float(); cre->animation.walkAnimationTime = animationTime["walk"].Float();
cre->animation.idleAnimationTime = animationTime["idle"].Float();
cre->animation.attackAnimationTime = animationTime["attack"].Float(); cre->animation.attackAnimationTime = animationTime["attack"].Float();
cre->animation.flightAnimationDistance = animationTime["flight"].Float(); //? cre->animation.flightAnimationDistance = animationTime["flight"].Float(); //?

View File

@ -55,7 +55,8 @@ public:
struct CreatureAnimation struct CreatureAnimation
{ {
double timeBetweenFidgets, walkAnimationTime, attackAnimationTime, flightAnimationDistance; double timeBetweenFidgets, idleAnimationTime,
walkAnimationTime, attackAnimationTime, flightAnimationDistance;
int upperRightMissleOffsetX, rightMissleOffsetX, lowerRightMissleOffsetX, int upperRightMissleOffsetX, rightMissleOffsetX, lowerRightMissleOffsetX,
upperRightMissleOffsetY, rightMissleOffsetY, lowerRightMissleOffsetY; upperRightMissleOffsetY, rightMissleOffsetY, lowerRightMissleOffsetY;
@ -67,7 +68,8 @@ public:
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & timeBetweenFidgets & walkAnimationTime & attackAnimationTime & flightAnimationDistance; h & timeBetweenFidgets & idleAnimationTime;
h & walkAnimationTime & attackAnimationTime & flightAnimationDistance;
h & upperRightMissleOffsetX & rightMissleOffsetX & lowerRightMissleOffsetX; h & upperRightMissleOffsetX & rightMissleOffsetX & lowerRightMissleOffsetX;
h & upperRightMissleOffsetY & rightMissleOffsetY & lowerRightMissleOffsetY; h & upperRightMissleOffsetY & rightMissleOffsetY & lowerRightMissleOffsetY;
h & missleFrameAngles & troopCountLocationOffset & attackClimaxFrame; h & missleFrameAngles & troopCountLocationOffset & attackClimaxFrame;

View File

@ -2940,10 +2940,10 @@ DuelParameters::SideSettings::SideSettings()
heroId = -1; heroId = -1;
} }
DuelParameters::DuelParameters() DuelParameters::DuelParameters():
terType(ETerrainType::DIRT),
bfieldType(BFieldType::ROCKLANDS)
{ {
terType = ETerrainType::DIRT;
bfieldType = BFieldType::ROCKLANDS;
} }
DuelParameters DuelParameters::fromJSON(const std::string &fname) DuelParameters DuelParameters::fromJSON(const std::string &fname)

View File

@ -450,6 +450,7 @@ struct DLL_LINKAGE QuestInfo //universal interface for human and AI
QuestInfo (const CQuest * Quest, const CGObjectInstance * Obj, int3 Tile) : QuestInfo (const CQuest * Quest, const CGObjectInstance * Obj, int3 Tile) :
quest (Quest), obj (Obj), tile (Tile){}; quest (Quest), obj (Obj), tile (Tile){};
//FIXME: assignment operator should return QuestInfo &
bool operator= (const QuestInfo &qi) bool operator= (const QuestInfo &qi)
{ {
quest = qi.quest; quest = qi.quest;

View File

@ -265,7 +265,7 @@ void CContentHandler::ContentTypeHandler::loadMod(std::string modName)
continue; continue;
} }
} }
// normal new object // normal new object or one with index bigger that data size
JsonUtils::validate(data, "vcmi:" + objectName, name); JsonUtils::validate(data, "vcmi:" + objectName, name);
handler->loadObject(modName, name, data); handler->loadObject(modName, name, data);
} }
@ -533,22 +533,6 @@ CModInfo & CModHandler::getModData(TModID modId)
assert(vstd::contains(activeMods, modId)); // not really necessary but won't hurt assert(vstd::contains(activeMods, modId)); // not really necessary but won't hurt
return mod; return mod;
} }
template<typename Handler>
void CModHandler::handleData(Handler handler, const JsonNode & source, std::string listName, std::string schemaName)
{
JsonNode config = JsonUtils::assembleFromFiles(source[listName].convertTo<std::vector<std::string> >());
for(auto & entry : config.Struct())
{
if (!entry.second.isNull()) // may happens if mod removed object by setting json entry to null
{
JsonUtils::validate(entry.second, schemaName, entry.first);
handler->load(entry.first, entry.second);
}
}
}
void CModHandler::beforeLoad() void CModHandler::beforeLoad()
{ {
loadConfigFromFile("defaultMods.json"); loadConfigFromFile("defaultMods.json");

View File

@ -156,10 +156,6 @@ class DLL_LINKAGE CModHandler
// returns load order in which all dependencies are resolved, e.g. loaded after required mods // returns load order in which all dependencies are resolved, e.g. loaded after required mods
// function assumes that input list is valid (checkDependencies returned true) // function assumes that input list is valid (checkDependencies returned true)
std::vector <TModID> resolveDependencies(std::vector<TModID> input) const; std::vector <TModID> resolveDependencies(std::vector<TModID> input) const;
// helper for loadActiveMods. Loads content from list of files
template<typename Handler>
void handleData(Handler handler, const JsonNode & source, std::string listName, std::string schemaName);
public: public:
CIdentifierStorage identifiers; CIdentifierStorage identifiers;

View File

@ -294,15 +294,14 @@ PlayerColor CGObjectInstance::getOwner() const
return tempOwner; //won't have owner return tempOwner; //won't have owner
} }
CGObjectInstance::CGObjectInstance() CGObjectInstance::CGObjectInstance():
pos(-1,-1,-1),
ID(Obj::NO_OBJ),
subID(-1),
defInfo(nullptr),
tempOwner(PlayerColor::UNFLAGGABLE),
blockVisit(false)
{ {
pos = int3(-1,-1,-1);
//state = new CLuaObjectScript();
ID = Obj::NO_OBJ;
subID = -1;
defInfo = nullptr;
tempOwner = PlayerColor::UNFLAGGABLE;
blockVisit = false;
} }
CGObjectInstance::~CGObjectInstance() CGObjectInstance::~CGObjectInstance()
{ {
@ -1036,17 +1035,17 @@ void CGHeroInstance::initObj()
const CCreature &specCreature = *VLC->creh->creatures[spec.additionalinfo]; //creature in which we have specialty const CCreature &specCreature = *VLC->creh->creatures[spec.additionalinfo]; //creature in which we have specialty
int creLevel = specCreature.level; //int creLevel = specCreature.level;
if(!creLevel) //if(!creLevel)
{ //{
if(spec.additionalinfo == 146) // if(spec.additionalinfo == 146)
creLevel = 5; //treat ballista as 5-level // creLevel = 5; //treat ballista as 5-level
else // else
{ // {
logGlobal->warnStream() << "Warning: unknown level of " << specCreature.namePl; // logGlobal->warnStream() << "Warning: unknown level of " << specCreature.namePl;
continue; // continue;
} // }
} //}
//bonus->additionalInfo = spec.additionalinfo; //creature id, should not be used again - this works only with limiter //bonus->additionalInfo = spec.additionalinfo; //creature id, should not be used again - this works only with limiter
bonus->limiter.reset(new CCreatureTypeLimiter (specCreature, true)); //with upgrades bonus->limiter.reset(new CCreatureTypeLimiter (specCreature, true)); //with upgrades

View File

@ -113,7 +113,7 @@ JsonWriter::JsonWriter(std::ostream &output, const JsonNode &node):
std::ostream & operator<<(std::ostream &out, const JsonNode &node) std::ostream & operator<<(std::ostream &out, const JsonNode &node)
{ {
JsonWriter(out, node); JsonWriter writer(out, node);
return out << "\n"; return out << "\n";
} }
@ -580,7 +580,7 @@ namespace
{ {
JsonNode::JsonType type = stringToType.find(schema.String())->second; JsonNode::JsonType type = stringToType.find(schema.String())->second;
if(type != data.getType() && data.getType() != JsonNode::DATA_NULL) if(type != data.getType() && data.getType() != JsonNode::DATA_NULL)
return validator.makeErrorMessage("Type mismatch!"); return validator.makeErrorMessage("Type mismatch! Expected " + schema.String());
return ""; return "";
} }
@ -591,7 +591,6 @@ namespace
//Local reference. Turn it into more easy to handle remote ref //Local reference. Turn it into more easy to handle remote ref
if (boost::algorithm::starts_with(URI, "#")) if (boost::algorithm::starts_with(URI, "#"))
URI = validator.usedSchemas.back() + URI; URI = validator.usedSchemas.back() + URI;
return check(JsonUtils::getSchema(URI), data, validator); return check(JsonUtils::getSchema(URI), data, validator);
} }
@ -607,7 +606,7 @@ namespace
errors += validator.makeErrorMessage(result); errors += validator.makeErrorMessage(result);
} }
else else
errors += validator.makeErrorMessage("Unknown format: " + schema.String()); errors += validator.makeErrorMessage("Unsupported format type: " + schema.String());
return errors; return errors;
} }
} }
@ -617,14 +616,14 @@ namespace
std::string maxLengthCheck(Validation::ValidationData & validator, const JsonNode & baseSchema, const JsonNode & schema, const JsonNode & data) std::string maxLengthCheck(Validation::ValidationData & validator, const JsonNode & baseSchema, const JsonNode & schema, const JsonNode & data)
{ {
if (data.String().size() > schema.Float()) if (data.String().size() > schema.Float())
return validator.makeErrorMessage("String too long"); return validator.makeErrorMessage((boost::format("String is longer than %d symbols") % schema.Float()).str());
return ""; return "";
} }
std::string minLengthCheck(Validation::ValidationData & validator, const JsonNode & baseSchema, const JsonNode & schema, const JsonNode & data) std::string minLengthCheck(Validation::ValidationData & validator, const JsonNode & baseSchema, const JsonNode & schema, const JsonNode & data)
{ {
if (data.String().size() < schema.Float()) if (data.String().size() < schema.Float())
return validator.makeErrorMessage("String too short"); return validator.makeErrorMessage((boost::format("String is shorter than %d symbols") % schema.Float()).str());
return ""; return "";
} }
} }
@ -637,12 +636,12 @@ namespace
if (baseSchema["exclusiveMaximum"].Bool()) if (baseSchema["exclusiveMaximum"].Bool())
{ {
if (data.Float() >= schema.Float()) if (data.Float() >= schema.Float())
return validator.makeErrorMessage("Value is too large"); return validator.makeErrorMessage((boost::format("Value is bigger than %d") % schema.Float()).str());
} }
else else
{ {
if (data.Float() > schema.Float()) if (data.Float() > schema.Float())
return validator.makeErrorMessage("Value is too large"); return validator.makeErrorMessage((boost::format("Value is bigger than %d") % schema.Float()).str());
} }
return ""; return "";
} }
@ -652,12 +651,12 @@ namespace
if (baseSchema["exclusiveMinimum"].Bool()) if (baseSchema["exclusiveMinimum"].Bool())
{ {
if (data.Float() <= schema.Float()) if (data.Float() <= schema.Float())
return validator.makeErrorMessage("Value is too small"); return validator.makeErrorMessage((boost::format("Value is smaller than %d") % schema.Float()).str());
} }
else else
{ {
if (data.Float() < schema.Float()) if (data.Float() < schema.Float())
return validator.makeErrorMessage("Value is too small"); return validator.makeErrorMessage((boost::format("Value is smaller than %d") % schema.Float()).str());
} }
return ""; return "";
} }
@ -666,7 +665,7 @@ namespace
{ {
double result = data.Float() / schema.Float(); double result = data.Float() / schema.Float();
if (floor(result) != result) if (floor(result) != result)
return validator.makeErrorMessage("Value is not divisible"); return validator.makeErrorMessage((boost::format("Value is not divisible by %d") % schema.Float()).str());
return ""; return "";
} }
} }
@ -726,14 +725,14 @@ namespace
std::string minItemsCheck(Validation::ValidationData & validator, const JsonNode & baseSchema, const JsonNode & schema, const JsonNode & data) std::string minItemsCheck(Validation::ValidationData & validator, const JsonNode & baseSchema, const JsonNode & schema, const JsonNode & data)
{ {
if (data.Vector().size() < schema.Float()) if (data.Vector().size() < schema.Float())
return validator.makeErrorMessage("Too few items in the list"); return validator.makeErrorMessage((boost::format("Length is smaller than %d") % schema.Float()).str());
return ""; return "";
} }
std::string maxItemsCheck(Validation::ValidationData & validator, const JsonNode & baseSchema, const JsonNode & schema, const JsonNode & data) std::string maxItemsCheck(Validation::ValidationData & validator, const JsonNode & baseSchema, const JsonNode & schema, const JsonNode & data)
{ {
if (data.Vector().size() > schema.Float()) if (data.Vector().size() > schema.Float())
return validator.makeErrorMessage("Too many items in the list!"); return validator.makeErrorMessage((boost::format("Length is bigger than %d") % schema.Float()).str());
return ""; return "";
} }
@ -760,14 +759,14 @@ namespace
std::string maxPropertiesCheck(Validation::ValidationData & validator, const JsonNode & baseSchema, const JsonNode & schema, const JsonNode & data) std::string maxPropertiesCheck(Validation::ValidationData & validator, const JsonNode & baseSchema, const JsonNode & schema, const JsonNode & data)
{ {
if (data.Struct().size() > schema.Float()) if (data.Struct().size() > schema.Float())
return validator.makeErrorMessage("Too many items in the list!"); return validator.makeErrorMessage((boost::format("Number of entries is bigger than %d") % schema.Float()).str());
return ""; return "";
} }
std::string minPropertiesCheck(Validation::ValidationData & validator, const JsonNode & baseSchema, const JsonNode & schema, const JsonNode & data) std::string minPropertiesCheck(Validation::ValidationData & validator, const JsonNode & baseSchema, const JsonNode & schema, const JsonNode & data)
{ {
if (data.Struct().size() < schema.Float()) if (data.Struct().size() < schema.Float())
return validator.makeErrorMessage("Too few items in the list"); return validator.makeErrorMessage((boost::format("Number of entries is less than %d") % schema.Float()).str());
return ""; return "";
} }
@ -855,11 +854,11 @@ namespace
{ {
// try generic additionalItems schema // try generic additionalItems schema
if (schema.getType() == JsonNode::DATA_STRUCT) if (schema.getType() == JsonNode::DATA_STRUCT)
return propertyEntryCheck(validator, entry.second, schema, entry.first); errors += propertyEntryCheck(validator, entry.second, schema, entry.first);
// or, additionalItems field can be bool which indicates if such items are allowed // or, additionalItems field can be bool which indicates if such items are allowed
if (!schema.isNull() && schema.Bool() == false) // present and set to false - error else if (!schema.isNull() && schema.Bool() == false) // present and set to false - error
return validator.makeErrorMessage("Unknown entry found: " + entry.first); errors += validator.makeErrorMessage("Unknown entry found: " + entry.first);
} }
} }
return errors; return errors;
@ -914,7 +913,7 @@ namespace
TEST_FILE("Sprites/", node.String(), EResType::IMAGE); TEST_FILE("Sprites/", node.String(), EResType::IMAGE);
if (node.String().find(':') != std::string::npos) if (node.String().find(':') != std::string::npos)
return testAnimation(node.String().substr(0, node.String().find(':'))); return testAnimation(node.String().substr(0, node.String().find(':')));
return "Image file not found"; return "Image file \"" + node.String() + "\" was not found";
} }
#undef TEST_FILE #undef TEST_FILE

View File

@ -50,9 +50,9 @@ JsonNode::JsonNode(ResourceID && fileURI):
} }
JsonNode::JsonNode(const JsonNode &copy): JsonNode::JsonNode(const JsonNode &copy):
type(DATA_NULL) type(DATA_NULL),
meta(copy.meta)
{ {
meta = copy.meta;
setType(copy.getType()); setType(copy.getType());
switch(type) switch(type)
{ {

View File

@ -18,7 +18,7 @@ public:
inline int3():x(0),y(0),z(0){}; //c-tor, x/y/z initialized to 0 inline int3():x(0),y(0),z(0){}; //c-tor, x/y/z initialized to 0
inline int3(const si32 X, const si32 Y, const si32 Z):x(X),y(Y),z(Z){}; //c-tor inline int3(const si32 X, const si32 Y, const si32 Z):x(X),y(Y),z(Z){}; //c-tor
inline int3(const int3 & val) : x(val.x), y(val.y), z(val.z){} //copy c-tor inline int3(const int3 & val) : x(val.x), y(val.y), z(val.z){} //copy c-tor
inline int3 operator=(const int3 & val) {x = val.x; y = val.y; z = val.z; return *this;} //assignemt operator inline int3 & operator=(const int3 & val) {x = val.x; y = val.y; z = val.z; return *this;} //assignemt operator
~int3() {} // d-tor - does nothing ~int3() {} // d-tor - does nothing
inline int3 operator+(const int3 & i) const //returns int3 with coordinates increased by corresponding coordinate of given int3 inline int3 operator+(const int3 & i) const //returns int3 with coordinates increased by corresponding coordinate of given int3
{return int3(x+i.x,y+i.y,z+i.z);} {return int3(x+i.x,y+i.y,z+i.z);}

View File

@ -2176,28 +2176,28 @@ void CGameHandler::applyAndSend(CPackForClient * info)
void CGameHandler::sendAndApply(CGarrisonOperationPack * info) void CGameHandler::sendAndApply(CGarrisonOperationPack * info)
{ {
sendAndApply((CPackForClient*)info); sendAndApply(static_cast<CPackForClient*>(info));
if(gs->map->victoryCondition.condition == EVictoryConditionType::GATHERTROOP) if(gs->map->victoryCondition.condition == EVictoryConditionType::GATHERTROOP)
winLoseHandle(); winLoseHandle();
} }
void CGameHandler::sendAndApply( SetResource * info ) void CGameHandler::sendAndApply( SetResource * info )
{ {
sendAndApply((CPackForClient*)info); sendAndApply(static_cast<CPackForClient*>(info));
if(gs->map->victoryCondition.condition == EVictoryConditionType::GATHERRESOURCE) if(gs->map->victoryCondition.condition == EVictoryConditionType::GATHERRESOURCE)
checkLossVictory(info->player); checkLossVictory(info->player);
} }
void CGameHandler::sendAndApply( SetResources * info ) void CGameHandler::sendAndApply( SetResources * info )
{ {
sendAndApply((CPackForClient*)info); sendAndApply(static_cast<CPackForClient*>(info));
if(gs->map->victoryCondition.condition == EVictoryConditionType::GATHERRESOURCE) if(gs->map->victoryCondition.condition == EVictoryConditionType::GATHERRESOURCE)
checkLossVictory(info->player); checkLossVictory(info->player);
} }
void CGameHandler::sendAndApply( NewStructures * info ) void CGameHandler::sendAndApply( NewStructures * info )
{ {
sendAndApply((CPackForClient*)info); sendAndApply(static_cast<CPackForClient*>(info));
if(gs->map->victoryCondition.condition == EVictoryConditionType::BUILDCITY) if(gs->map->victoryCondition.condition == EVictoryConditionType::BUILDCITY)
checkLossVictory(getTown(info->tid)->tempOwner); checkLossVictory(getTown(info->tid)->tempOwner);
} }