mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +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:
		| @@ -176,7 +176,7 @@ CDefEssential * Graphics::loadHeroAnim( const std::string &name, const std::vect | ||||
| 				for(int e=0; e<8; ++e) | ||||
| 				{ | ||||
| 					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.imName = std::string(); | ||||
| 					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) | ||||
| 					{ | ||||
| 						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.imName = std::string(); | ||||
| 						curImgs.push_back(nci); | ||||
| @@ -236,7 +236,7 @@ void Graphics::loadHeroFlagsDetail(std::pair<std::vector<CDefEssential *> Graphi | ||||
| 					for(int e=0; e<8; ++e) | ||||
| 					{ | ||||
| 						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.imName = std::string(); | ||||
| 						curImgs.push_back(nci); | ||||
|   | ||||
| @@ -1336,10 +1336,10 @@ void CBattleInterface::spellCast( const BattleSpellCast * sc ) | ||||
|  | ||||
| 	//displaying message in console | ||||
| 	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) | ||||
| 	{ | ||||
| 		bool plural = false; //add singular / plural form of creature text if this is true | ||||
| 		int textID = 0; | ||||
| 		std::string text = CGI->generaltexth->allTexts[195]; | ||||
| 		if(sc->castedByHero) | ||||
| 		{ | ||||
| @@ -1970,8 +1970,6 @@ void CBattleInterface::startAction(const BattleAction* action) | ||||
|  | ||||
| 	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->side) | ||||
| @@ -2006,8 +2004,8 @@ void CBattleInterface::startAction(const BattleAction* action) | ||||
|  | ||||
| 	if(txtid) | ||||
| 	{ | ||||
| 		sprintf(txt, CGI->generaltexth->allTexts[txtid].c_str(),  (stack->count != 1) ? stack->getCreature()->namePl.c_str() : stack->getCreature()->nameSing.c_str(), 0); | ||||
| 		console->addText(txt); | ||||
| 		std::string name = (stack->count != 1) ? stack->getCreature()->namePl.c_str() : stack->getCreature()->nameSing.c_str(); | ||||
| 		console->addText((boost::format(CGI->generaltexth->allTexts[txtid].c_str()) % name).str()); | ||||
| 	} | ||||
|  | ||||
| 	//displaying special abilities | ||||
| @@ -3186,7 +3184,7 @@ void CBattleInterface::showProjectiles(SDL_Surface * to) | ||||
|  | ||||
| 		if(it->reverse) | ||||
| 		{ | ||||
| 			SDL_Surface * rev = CSDL_Ext::rotate01(image); | ||||
| 			SDL_Surface * rev = CSDL_Ext::verticalFlip(image); | ||||
| 			CSDL_Ext::blit8bppAlphaTo24bpp(rev, nullptr, to, &dst); | ||||
| 			SDL_FreeSurface(rev); | ||||
| 		} | ||||
|   | ||||
| @@ -222,7 +222,7 @@ CBattleHero::CBattleHero(const std::string & defName, bool flipG, PlayerColor pl | ||||
| 	{ | ||||
| 		if(flip) | ||||
| 		{ | ||||
| 			SDL_Surface * hlp = CSDL_Ext::rotate01(elem.bitmap); | ||||
| 			SDL_Surface * hlp = CSDL_Ext::verticalFlip(elem.bitmap); | ||||
| 			SDL_FreeSurface(elem.bitmap); | ||||
| 			elem.bitmap = hlp; | ||||
| 		} | ||||
|   | ||||
| @@ -68,8 +68,9 @@ float AnimationControls::getCreatureAnimationSpeed(const CCreature * creature, c | ||||
| 		return speed * 2 * creature->animation.walkAnimationTime / anim->framesInGroup(type); | ||||
|  | ||||
| 	case CCreatureAnim::MOUSEON: | ||||
| 	case CCreatureAnim::HOLDING: | ||||
| 		return baseSpeed; | ||||
| 	case CCreatureAnim::HOLDING: | ||||
| 		return baseSpeed * creature->animation.idleAnimationTime / anim->framesInGroup(type); | ||||
|  | ||||
| 	case CCreatureAnim::SHOOT_UP: | ||||
| 	case CCreatureAnim::SHOOT_FRONT: | ||||
| @@ -452,5 +453,7 @@ void CCreatureAnimation::pause() | ||||
|  | ||||
| void CCreatureAnimation::play() | ||||
| { | ||||
| 	speed = 1 / speedController(this, type); | ||||
|     speed = 0; | ||||
|     if (speedController(this, type) != 0) | ||||
|         speed = 1 / speedController(this, type); | ||||
| } | ||||
|   | ||||
| @@ -62,96 +62,56 @@ void blitAt(SDL_Surface * src, const SDL_Rect & pos, SDL_Surface * 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 | ||||
| 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); | ||||
| 	const int bpl = ret->pitch; | ||||
| 	const int bpp = ret->format->BytesPerPixel; | ||||
|  | ||||
| 	for(int i=0; i<ret->h; i++) { | ||||
| 		char *src = (char *)toRot->pixels + i*bpl; | ||||
| 		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]; | ||||
| 	char * src = reinterpret_cast<char *>(toRot->pixels); | ||||
| 	char * dst = reinterpret_cast<char *>(ret->pixels); | ||||
|  | ||||
| 	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; | ||||
| } | ||||
|  | ||||
| // 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); | ||||
| 	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++) { | ||||
| 		memcpy((char *)ret->pixels + i*bpl, (char *)toRot->pixels + (ret->h-i-1)*bpl, bpl); | ||||
| 	for(int i=0; i<ret->h; i++) | ||||
| 	{ | ||||
| 		dst -= ret->pitch; | ||||
| 		std::copy(src, src + toRot->pitch, dst); | ||||
| 		src += toRot->pitch; | ||||
| 	} | ||||
|  | ||||
| 	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) | ||||
| { | ||||
| 	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: | ||||
| 		if(colorByte) | ||||
| 		{ | ||||
| 			return colorToUint32(surface->format->palette->colors+(*p)); | ||||
| 		} | ||||
| 		else | ||||
| 			return *p; | ||||
|  | ||||
|   | ||||
| @@ -34,7 +34,6 @@ struct Rect; | ||||
| extern SDL_Surface * screen, *screen2, *screenBuf; | ||||
| 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 updateRect (SDL_Rect * rect, SDL_Surface * scr = screen); | ||||
| 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_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 * hFlip(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 | ||||
| 	SDL_Surface * verticalFlip(SDL_Surface * toRot); //vertical flip | ||||
| 	SDL_Surface * horizontalFlip(SDL_Surface * toRot); //horizontal flip | ||||
| 	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) | ||||
| 	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); | ||||
| 	TColorPutter getPutterFor(SDL_Surface  * const &dest, int incrementing); //incrementing: -1, 0, 1 | ||||
| 	TColorPutterAlpha getPutterAlphaFor(SDL_Surface  * const &dest, int incrementing); //incrementing: -1, 0, 1 | ||||
|   | ||||
| @@ -104,7 +104,7 @@ void CMapHandler::prepareFOWDefs() | ||||
| 	for(auto & elem : missRot) | ||||
| 	{ | ||||
| 		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); | ||||
| 	} | ||||
| 	//necessaary rotations added | ||||
|   | ||||
| @@ -36,6 +36,10 @@ | ||||
| 		"upgrades": ["stormElemental"], | ||||
| 		"graphics" : | ||||
| 		{ | ||||
| 			"animationTime" : | ||||
| 			{ | ||||
| 				"idle" : 0 | ||||
| 			}, | ||||
| 			"animation": "CAELEM.DEF" | ||||
| 		}, | ||||
| 		"sound" : | ||||
| @@ -82,6 +86,10 @@ | ||||
| 		"upgrades": ["magmaElemental"], | ||||
| 		"graphics" : | ||||
| 		{ | ||||
| 			"animationTime" : | ||||
| 			{ | ||||
| 				"idle" : 0 | ||||
| 			}, | ||||
| 			"animation": "CEELEM.DEF" | ||||
| 		}, | ||||
| 		"sound" : | ||||
| @@ -129,6 +137,10 @@ | ||||
| 		"upgrades": ["energyElemental"], | ||||
| 		"graphics" : | ||||
| 		{ | ||||
| 			"animationTime" : | ||||
| 			{ | ||||
| 				"idle" : 0 | ||||
| 			}, | ||||
| 			"animation": "CFELEM.DEF" | ||||
| 		}, | ||||
| 		"sound" : | ||||
| @@ -195,6 +207,10 @@ | ||||
| 		"upgrades": ["iceElemental"], | ||||
| 		"graphics" : | ||||
| 		{ | ||||
| 			"animationTime" : | ||||
| 			{ | ||||
| 				"idle" : 0 | ||||
| 			}, | ||||
| 			"animation": "CWELEM.DEF" | ||||
| 		}, | ||||
| 		"sound" : | ||||
| @@ -334,6 +350,10 @@ | ||||
| 		"graphics" : | ||||
| 		{ | ||||
| 			"animation": "CICEE.DEF", | ||||
| 			"animationTime" : | ||||
| 			{ | ||||
| 				"idle" : 0 | ||||
| 			}, | ||||
| 			"missile" : | ||||
| 			{ | ||||
| 				"projectile": "PICEE.DEF" | ||||
| @@ -379,6 +399,10 @@ | ||||
| 		}, | ||||
| 		"graphics" : | ||||
| 		{ | ||||
| 			"animationTime" : | ||||
| 			{ | ||||
| 				"idle" : 0 | ||||
| 			}, | ||||
| 			"animation": "CSTONE.DEF" | ||||
| 		}, | ||||
| 		"sound" : | ||||
| @@ -420,6 +444,10 @@ | ||||
| 		}, | ||||
| 		"graphics" : | ||||
| 		{ | ||||
| 			"animationTime" : | ||||
| 			{ | ||||
| 				"idle" : 0 | ||||
| 			}, | ||||
| 			"animation": "CSTORM.DEF", | ||||
| 			"missile" : | ||||
| 			{ | ||||
| @@ -471,6 +499,10 @@ | ||||
| 		}, | ||||
| 		"graphics" : | ||||
| 		{ | ||||
| 			"animationTime" : | ||||
| 			{ | ||||
| 				"idle" : 0 | ||||
| 			}, | ||||
| 			"animation": "CNRG.DEF" | ||||
| 		}, | ||||
| 		"sound" : | ||||
|   | ||||
| @@ -172,13 +172,17 @@ | ||||
| 				"animationTime": { | ||||
| 					"type":"object", | ||||
| 					"additionalProperties" : false, | ||||
| 					"required" : [ "attack", "flight", "walk" ], | ||||
| 					"required" : [ "attack", "flight", "walk", "idle" ], | ||||
| 					"description": "Length of several animations", | ||||
| 					"properties":{ | ||||
| 						"attack": { | ||||
| 							"type":"number", | ||||
| 							"description": "attack" | ||||
| 						}, | ||||
| 						"idle": { | ||||
| 							"type":"number", | ||||
| 							"description": "idle" | ||||
| 						}, | ||||
| 						"flight": { | ||||
| 							"type":"number", | ||||
| 							"description": "flight" | ||||
|   | ||||
| @@ -15,13 +15,14 @@ | ||||
|  | ||||
| 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) | ||||
|   | ||||
| @@ -19,19 +19,19 @@ BattleHex& BattleHex::moveInDir(EDir dir, bool hasToBeValid) | ||||
| 	switch(dir) | ||||
| 	{ | ||||
| 	case TOP_LEFT: | ||||
| 		setXY(y%2 ? x-1 : x, y-1, hasToBeValid); | ||||
| 		setXY((y%2) ? x-1 : x, y-1, hasToBeValid); | ||||
| 		break; | ||||
| 	case TOP_RIGHT: | ||||
| 		setXY(y%2 ? x : x+1, y-1, hasToBeValid); | ||||
| 		setXY((y%2) ? x : x+1, y-1, hasToBeValid); | ||||
| 		break; | ||||
| 	case RIGHT: | ||||
| 		setXY(x+1, y, hasToBeValid); | ||||
| 		break; | ||||
| 	case BOTTOM_RIGHT: | ||||
| 		setXY(y%2 ? x : x+1, y+1, hasToBeValid); | ||||
| 		setXY((y%2) ? x : x+1, y+1, hasToBeValid); | ||||
| 		break; | ||||
| 	case BOTTOM_LEFT: | ||||
| 		setXY(y%2 ? x-1 : x, y+1, hasToBeValid); | ||||
| 		setXY((y%2) ? x-1 : x, y+1, hasToBeValid); | ||||
| 		break; | ||||
| 	case LEFT: | ||||
| 		setXY(x-1, y, hasToBeValid); | ||||
| @@ -157,4 +157,4 @@ BattleHex BattleHex::getClosestTile(bool attackerOwned, BattleHex initialPos, st | ||||
| 	boost::sort (sortedTiles, compareHorizontal); | ||||
|  | ||||
| 	return sortedTiles.front(); | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -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() | ||||
|   | ||||
| @@ -543,6 +543,7 @@ void CBattleInfoCallback::battleGetStackQueue(std::vector<const CStack *> &out, | ||||
| 		const CStack *fastest = st[i], *other = nullptr; | ||||
| 		int bestSpeed = fastest->Speed(turn); | ||||
|  | ||||
| 		//FIXME: comparison between bool and integer. Logic does not makes sense either | ||||
| 		if(fastest->attackerOwned != lastMoved) | ||||
| 		{ | ||||
| 			ret = fastest; | ||||
| @@ -648,6 +649,7 @@ void CBattleInfoCallback::battleGetStackQueue(std::vector<const CStack *> &out, | ||||
| 	{ | ||||
| 		if(active) | ||||
| 		{ | ||||
| 			//FIXME: both branches contain same code!!! | ||||
| 			if(out.size() && out.front() == active) | ||||
| 				lastMoved = active->attackerOwned; | ||||
| 			else | ||||
|   | ||||
| @@ -531,6 +531,7 @@ void CCreatureHandler::loadUnitAnimInfo(JsonNode & graphics, CLegacyConfigParser | ||||
| 	animationTime["walk"].Float() = parser.readNumber(); | ||||
| 	animationTime["attack"].Float() = parser.readNumber(); | ||||
| 	animationTime["flight"].Float() = parser.readNumber(); | ||||
| 	animationTime["idle"].Float() = 10.0; | ||||
|  | ||||
| 	JsonNode & missile = graphics["missile"]; | ||||
| 	JsonNode & offsets = missile["offset"]; | ||||
| @@ -609,6 +610,7 @@ void CCreatureHandler::loadJsonAnimation(CCreature * cre, const JsonNode & graph | ||||
|  | ||||
| 	const JsonNode & animationTime = graphics["animationTime"]; | ||||
| 	cre->animation.walkAnimationTime = animationTime["walk"].Float(); | ||||
| 	cre->animation.idleAnimationTime = animationTime["idle"].Float(); | ||||
| 	cre->animation.attackAnimationTime = animationTime["attack"].Float(); | ||||
| 	cre->animation.flightAnimationDistance = animationTime["flight"].Float(); //? | ||||
|  | ||||
|   | ||||
| @@ -55,7 +55,8 @@ public: | ||||
|  | ||||
| 	struct CreatureAnimation | ||||
| 	{ | ||||
| 		double timeBetweenFidgets, walkAnimationTime, attackAnimationTime, flightAnimationDistance; | ||||
| 		double timeBetweenFidgets, idleAnimationTime, | ||||
| 			   walkAnimationTime, attackAnimationTime, flightAnimationDistance; | ||||
| 		int upperRightMissleOffsetX, rightMissleOffsetX, lowerRightMissleOffsetX, | ||||
| 		    upperRightMissleOffsetY, rightMissleOffsetY, lowerRightMissleOffsetY; | ||||
|  | ||||
| @@ -67,7 +68,8 @@ public: | ||||
|  | ||||
| 		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 & upperRightMissleOffsetY & rightMissleOffsetY & lowerRightMissleOffsetY; | ||||
| 			h & missleFrameAngles & troopCountLocationOffset & attackClimaxFrame; | ||||
|   | ||||
| @@ -2940,10 +2940,10 @@ DuelParameters::SideSettings::SideSettings() | ||||
| 	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) | ||||
|   | ||||
| @@ -450,6 +450,7 @@ struct DLL_LINKAGE QuestInfo //universal interface for human and AI | ||||
| 	QuestInfo (const CQuest * Quest, const CGObjectInstance * Obj, int3 Tile) : | ||||
| 		quest (Quest), obj (Obj), tile (Tile){}; | ||||
|  | ||||
| 	//FIXME: assignment operator should return QuestInfo & | ||||
| 	bool operator= (const QuestInfo &qi) | ||||
| 	{ | ||||
| 		quest = qi.quest; | ||||
|   | ||||
| @@ -265,7 +265,7 @@ void CContentHandler::ContentTypeHandler::loadMod(std::string modName) | ||||
| 				continue; | ||||
| 			} | ||||
| 		} | ||||
| 		// normal new object | ||||
| 		// normal new object or one with index bigger that data size | ||||
| 		JsonUtils::validate(data, "vcmi:" + objectName, name); | ||||
| 		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 | ||||
| 	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() | ||||
| { | ||||
| 	loadConfigFromFile("defaultMods.json"); | ||||
|   | ||||
| @@ -156,10 +156,6 @@ class DLL_LINKAGE CModHandler | ||||
| 	// 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) | ||||
| 	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: | ||||
|  | ||||
| 	CIdentifierStorage identifiers; | ||||
|   | ||||
| @@ -294,15 +294,14 @@ PlayerColor CGObjectInstance::getOwner() const | ||||
| 		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() | ||||
| { | ||||
| @@ -1036,17 +1035,17 @@ void CGHeroInstance::initObj() | ||||
|  | ||||
| 					const CCreature &specCreature = *VLC->creh->creatures[spec.additionalinfo]; //creature in which we have specialty | ||||
|  | ||||
| 					int creLevel = specCreature.level; | ||||
| 					if(!creLevel) | ||||
| 					{ | ||||
| 						if(spec.additionalinfo == 146) | ||||
| 							creLevel = 5; //treat ballista as 5-level | ||||
| 						else | ||||
| 						{ | ||||
|                             logGlobal->warnStream() << "Warning: unknown level of " << specCreature.namePl; | ||||
| 							continue; | ||||
| 						} | ||||
| 					} | ||||
| 					//int creLevel = specCreature.level; | ||||
| 					//if(!creLevel) | ||||
| 					//{ | ||||
| 					//	if(spec.additionalinfo == 146) | ||||
| 					//		creLevel = 5; //treat ballista as 5-level | ||||
| 					//	else | ||||
| 					//	{ | ||||
| 					//        logGlobal->warnStream() << "Warning: unknown level of " << specCreature.namePl; | ||||
| 					//		continue; | ||||
| 					//	} | ||||
| 					//} | ||||
|  | ||||
| 					//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 | ||||
|   | ||||
| @@ -113,7 +113,7 @@ JsonWriter::JsonWriter(std::ostream &output, const JsonNode &node): | ||||
|  | ||||
| std::ostream & operator<<(std::ostream &out, const JsonNode &node) | ||||
| { | ||||
| 	JsonWriter(out, node); | ||||
| 	JsonWriter writer(out, node); | ||||
| 	return out << "\n"; | ||||
| } | ||||
|  | ||||
| @@ -580,7 +580,7 @@ namespace | ||||
| 		{ | ||||
| 			JsonNode::JsonType type = stringToType.find(schema.String())->second; | ||||
| 			if(type != data.getType() && data.getType() != JsonNode::DATA_NULL) | ||||
| 				return validator.makeErrorMessage("Type mismatch!"); | ||||
| 				return validator.makeErrorMessage("Type mismatch! Expected " + schema.String()); | ||||
| 			return ""; | ||||
| 		} | ||||
|  | ||||
| @@ -591,7 +591,6 @@ namespace | ||||
| 			//Local reference. Turn it into more easy to handle remote ref | ||||
| 			if (boost::algorithm::starts_with(URI, "#")) | ||||
| 				URI = validator.usedSchemas.back() + URI; | ||||
|  | ||||
| 			return check(JsonUtils::getSchema(URI), data, validator); | ||||
| 		} | ||||
|  | ||||
| @@ -607,7 +606,7 @@ namespace | ||||
| 					errors += validator.makeErrorMessage(result); | ||||
| 			} | ||||
| 			else | ||||
| 				errors += validator.makeErrorMessage("Unknown format: " + schema.String()); | ||||
| 				errors += validator.makeErrorMessage("Unsupported format type: " + schema.String()); | ||||
| 			return errors; | ||||
| 		} | ||||
| 	} | ||||
| @@ -617,14 +616,14 @@ namespace | ||||
| 		std::string maxLengthCheck(Validation::ValidationData & validator, const JsonNode & baseSchema, const JsonNode & schema, const JsonNode & data) | ||||
| 		{ | ||||
| 			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 ""; | ||||
| 		} | ||||
|  | ||||
| 		std::string minLengthCheck(Validation::ValidationData & validator, const JsonNode & baseSchema, const JsonNode & schema, const JsonNode & data) | ||||
| 		{ | ||||
| 			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 ""; | ||||
| 		} | ||||
| 	} | ||||
| @@ -637,12 +636,12 @@ namespace | ||||
| 			if (baseSchema["exclusiveMaximum"].Bool()) | ||||
| 			{ | ||||
| 				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 | ||||
| 			{ | ||||
| 				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 ""; | ||||
| 		} | ||||
| @@ -652,12 +651,12 @@ namespace | ||||
| 			if (baseSchema["exclusiveMinimum"].Bool()) | ||||
| 			{ | ||||
| 				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 | ||||
| 			{ | ||||
| 				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 ""; | ||||
| 		} | ||||
| @@ -666,7 +665,7 @@ namespace | ||||
| 		{ | ||||
| 			double result = data.Float() / schema.Float(); | ||||
| 			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 ""; | ||||
| 		} | ||||
| 	} | ||||
| @@ -726,14 +725,14 @@ namespace | ||||
| 		std::string minItemsCheck(Validation::ValidationData & validator, const JsonNode & baseSchema, const JsonNode & schema, const JsonNode & data) | ||||
| 		{ | ||||
| 			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 ""; | ||||
| 		} | ||||
|  | ||||
| 		std::string maxItemsCheck(Validation::ValidationData & validator, const JsonNode & baseSchema, const JsonNode & schema, const JsonNode & data) | ||||
| 		{ | ||||
| 			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 ""; | ||||
| 		} | ||||
|  | ||||
| @@ -760,14 +759,14 @@ namespace | ||||
| 		std::string maxPropertiesCheck(Validation::ValidationData & validator, const JsonNode & baseSchema, const JsonNode & schema, const JsonNode & data) | ||||
| 		{ | ||||
| 			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 ""; | ||||
| 		} | ||||
|  | ||||
| 		std::string minPropertiesCheck(Validation::ValidationData & validator, const JsonNode & baseSchema, const JsonNode & schema, const JsonNode & data) | ||||
| 		{ | ||||
| 			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 ""; | ||||
| 		} | ||||
|  | ||||
| @@ -855,11 +854,11 @@ namespace | ||||
| 				{ | ||||
| 					// try generic additionalItems schema | ||||
| 					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 | ||||
| 					if (!schema.isNull() && schema.Bool() == false) // present and set to false - error | ||||
| 						return validator.makeErrorMessage("Unknown entry found: " + entry.first); | ||||
|                     else if (!schema.isNull() && schema.Bool() == false) // present and set to false - error | ||||
|                         errors += validator.makeErrorMessage("Unknown entry found: " + entry.first); | ||||
| 				} | ||||
| 			} | ||||
| 			return errors; | ||||
| @@ -914,7 +913,7 @@ namespace | ||||
| 			TEST_FILE("Sprites/", node.String(), EResType::IMAGE); | ||||
| 			if (node.String().find(':') != std::string::npos) | ||||
| 				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 | ||||
| @@ -1082,4 +1081,4 @@ namespace Validation | ||||
| 		return knownFormats; | ||||
| 	} | ||||
|  | ||||
| } // Validation namespace | ||||
| } // Validation namespace | ||||
|   | ||||
| @@ -50,9 +50,9 @@ JsonNode::JsonNode(ResourceID && fileURI): | ||||
| } | ||||
|  | ||||
| JsonNode::JsonNode(const JsonNode ©): | ||||
| 	type(DATA_NULL) | ||||
| 	type(DATA_NULL), | ||||
| 	meta(copy.meta) | ||||
| { | ||||
| 	meta = copy.meta; | ||||
| 	setType(copy.getType()); | ||||
| 	switch(type) | ||||
| 	{ | ||||
|   | ||||
| @@ -18,7 +18,7 @@ public: | ||||
| 	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 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 | ||||
| 	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);} | ||||
|   | ||||
| @@ -2176,28 +2176,28 @@ void CGameHandler::applyAndSend(CPackForClient * info) | ||||
|  | ||||
| void CGameHandler::sendAndApply(CGarrisonOperationPack * info) | ||||
| { | ||||
| 	sendAndApply((CPackForClient*)info); | ||||
| 	sendAndApply(static_cast<CPackForClient*>(info)); | ||||
| 	if(gs->map->victoryCondition.condition == EVictoryConditionType::GATHERTROOP) | ||||
| 		winLoseHandle(); | ||||
| } | ||||
|  | ||||
| void CGameHandler::sendAndApply( SetResource * info ) | ||||
| { | ||||
| 	sendAndApply((CPackForClient*)info); | ||||
| 	sendAndApply(static_cast<CPackForClient*>(info)); | ||||
| 	if(gs->map->victoryCondition.condition == EVictoryConditionType::GATHERRESOURCE) | ||||
| 		checkLossVictory(info->player); | ||||
| } | ||||
|  | ||||
| void CGameHandler::sendAndApply( SetResources * info ) | ||||
| { | ||||
| 	sendAndApply((CPackForClient*)info); | ||||
| 	sendAndApply(static_cast<CPackForClient*>(info)); | ||||
| 	if(gs->map->victoryCondition.condition == EVictoryConditionType::GATHERRESOURCE) | ||||
| 		checkLossVictory(info->player); | ||||
| } | ||||
|  | ||||
| void CGameHandler::sendAndApply( NewStructures * info ) | ||||
| { | ||||
| 	sendAndApply((CPackForClient*)info); | ||||
| 	sendAndApply(static_cast<CPackForClient*>(info)); | ||||
| 	if(gs->map->victoryCondition.condition == EVictoryConditionType::BUILDCITY) | ||||
| 		checkLossVictory(getTown(info->tid)->tempOwner); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user