mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	* next part of shooting in battles (there will be more of them)
* now compiles under MSVC * small refactoring / cleaning / fixing / etc.
This commit is contained in:
		| @@ -11,6 +11,8 @@ | ||||
| #include "hch/CGeneralTextHandler.h" | ||||
| #include <queue> | ||||
| #include <sstream> | ||||
| #define _USE_MATH_DEFINES | ||||
| #include <cmath> | ||||
|  | ||||
| extern SDL_Surface * screen; | ||||
| extern TTF_Font * GEOR13; | ||||
| @@ -123,6 +125,22 @@ CBattleInterface::CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, C | ||||
| 		if(g->second.creature->isShooting() && CGI->creh->idToProjectile[g->second.creature->idNumber] != std::string()) | ||||
| 		{ | ||||
| 			idToProjectile[g->second.creature->idNumber] = CGI->spriteh->giveDef(CGI->creh->idToProjectile[g->second.creature->idNumber]); | ||||
|  | ||||
| 			if(idToProjectile[g->second.creature->idNumber]->ourImages.size() > 2) //add symmetric images | ||||
| 			{ | ||||
| 				for(int k = idToProjectile[g->second.creature->idNumber]->ourImages.size()-2; k > 1; --k) | ||||
| 				{ | ||||
| 					Cimage ci; | ||||
| 					ci.bitmap = CSDL_Ext::rotate01(idToProjectile[g->second.creature->idNumber]->ourImages[k].bitmap); | ||||
| 					ci.groupNumber = 0; | ||||
| 					ci.imName = std::string(); | ||||
| 					idToProjectile[g->second.creature->idNumber]->ourImages.push_back(ci); | ||||
| 				} | ||||
| 			} | ||||
| 			for(int s=0; s<idToProjectile[g->second.creature->idNumber]->ourImages.size(); ++s) //alpha transforming | ||||
| 			{ | ||||
| 				CSDL_Ext::alphaTransform(idToProjectile[g->second.creature->idNumber]->ourImages[s].bitmap); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @@ -413,7 +431,7 @@ void CBattleInterface::stackRemoved(CStack stack) | ||||
| 	creAnims.erase(stack.ID); | ||||
| } | ||||
|  | ||||
| void CBattleInterface::stackKilled(int ID, int dmg, int killed, int IDby) | ||||
| void CBattleInterface::stackKilled(int ID, int dmg, int killed, int IDby, bool byShooting) | ||||
| { | ||||
| 	creAnims[ID]->setType(5); //death | ||||
| 	for(int i=0; i<creAnims[ID]->framesInGroup(5)-1; ++i) | ||||
| @@ -608,7 +626,7 @@ void CBattleInterface::stackMoved(int number, int destHex, bool startMoving, boo | ||||
| 	creAnims[number]->pos.y = coords.second; | ||||
| } | ||||
|  | ||||
| void CBattleInterface::stackIsAttacked(int ID, int dmg, int killed, int IDby) | ||||
| void CBattleInterface::stackIsAttacked(int ID, int dmg, int killed, int IDby, bool byShooting) | ||||
| { | ||||
| 	creAnims[ID]->setType(3); //getting hit | ||||
| 	for(int i=0; i<creAnims[ID]->framesInGroup(3); ++i) | ||||
| @@ -673,54 +691,28 @@ void CBattleInterface::stackAttacking(int ID, int dest) | ||||
| 	attackingInfo->frame = 0; | ||||
| 	attackingInfo->ID = ID; | ||||
| 	attackingInfo->reversing = false; | ||||
| 	attackingInfo->shooting = false; | ||||
|  | ||||
| 	if(aStack.creature->isDoubleWide()) | ||||
| 	switch(CBattleHex::mutualPosition(aStack.position, dest)) //attack direction | ||||
| 	{ | ||||
| 		switch(CBattleHex::mutualPosition(aStack.position, dest)) //attack direction | ||||
| 		{ | ||||
| 			case 0: | ||||
| 				attackingInfo->maxframe = creAnims[ID]->framesInGroup(10); | ||||
| 				break; | ||||
| 			case 1: | ||||
| 				attackingInfo->maxframe = creAnims[ID]->framesInGroup(10); | ||||
| 				break; | ||||
| 			case 2: | ||||
| 				attackingInfo->maxframe = creAnims[ID]->framesInGroup(11); | ||||
| 				break; | ||||
| 			case 3: | ||||
| 				attackingInfo->maxframe = creAnims[ID]->framesInGroup(12); | ||||
| 				break; | ||||
| 			case 4: | ||||
| 				attackingInfo->maxframe = creAnims[ID]->framesInGroup(12); | ||||
| 				break; | ||||
| 			case 5: | ||||
| 				attackingInfo->maxframe = creAnims[ID]->framesInGroup(11); | ||||
| 				break; | ||||
| 		} | ||||
| 	} | ||||
| 	else //else for if(aStack.creature->isDoubleWide()) | ||||
| 	{ | ||||
| 		switch(CBattleHex::mutualPosition(aStack.position, dest)) //attack direction | ||||
| 		{ | ||||
| 			case 0: | ||||
| 				attackingInfo->maxframe = creAnims[ID]->framesInGroup(10); | ||||
| 				break; | ||||
| 			case 1: | ||||
| 				attackingInfo->maxframe = creAnims[ID]->framesInGroup(10); | ||||
| 				break; | ||||
| 			case 2: | ||||
| 				attackingInfo->maxframe = creAnims[ID]->framesInGroup(11); | ||||
| 				break; | ||||
| 			case 3: | ||||
| 				attackingInfo->maxframe = creAnims[ID]->framesInGroup(12); | ||||
| 				break; | ||||
| 			case 4: | ||||
| 				attackingInfo->maxframe = creAnims[ID]->framesInGroup(12); | ||||
| 				break; | ||||
| 			case 5: | ||||
| 				attackingInfo->maxframe = creAnims[ID]->framesInGroup(11); | ||||
| 				break; | ||||
| 		} | ||||
| 		case 0: | ||||
| 			attackingInfo->maxframe = creAnims[ID]->framesInGroup(10); | ||||
| 			break; | ||||
| 		case 1: | ||||
| 			attackingInfo->maxframe = creAnims[ID]->framesInGroup(10); | ||||
| 			break; | ||||
| 		case 2: | ||||
| 			attackingInfo->maxframe = creAnims[ID]->framesInGroup(11); | ||||
| 			break; | ||||
| 		case 3: | ||||
| 			attackingInfo->maxframe = creAnims[ID]->framesInGroup(12); | ||||
| 			break; | ||||
| 		case 4: | ||||
| 			attackingInfo->maxframe = creAnims[ID]->framesInGroup(12); | ||||
| 			break; | ||||
| 		case 5: | ||||
| 			attackingInfo->maxframe = creAnims[ID]->framesInGroup(11); | ||||
| 			break; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -763,6 +755,74 @@ void CBattleInterface::hexLclicked(int whichOne) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CBattleInterface::stackIsShooting(int ID, int dest) | ||||
| { | ||||
| 	//projectile | ||||
| 	float projectileAngle; //in radians; if positive, projectiles goes up | ||||
| 	float straightAngle = 0.2f; //maximal angle in radians between straight horizontal line and shooting line for which shot is considered to be straight (absoulte value) | ||||
| 	int fromHex = LOCPLINT->cb->battleGetPos(ID); | ||||
| 	projectileAngle = atan2(float(abs(dest - fromHex)/17), float(abs(dest - fromHex)%17)); | ||||
| 	if(fromHex < dest) | ||||
| 		projectileAngle = -projectileAngle; | ||||
|  | ||||
| 	SProjectileInfo spi; | ||||
| 	spi.creID = LOCPLINT->cb->battleGetStackByID(ID).creature->idNumber; | ||||
|  | ||||
| 	spi.step = 0; | ||||
| 	spi.frameNum = 0; | ||||
| 	spi.spin = CGI->creh->idToProjectileSpin[spi.creID]; | ||||
|  | ||||
| 	std::pair<int, int> xycoord = CBattleHex::getXYUnitAnim(LOCPLINT->cb->battleGetPos(ID), true, &LOCPLINT->cb->battleGetCreature(ID)); | ||||
| 	std::pair<int, int> destcoord = CBattleHex::getXYUnitAnim(dest, false, &LOCPLINT->cb->battleGetCreature(ID));  | ||||
| 	destcoord.first += 250; destcoord.second += 210; //TODO: find a better place to shoot | ||||
|  | ||||
| 	if(projectileAngle > straightAngle) //upper shot | ||||
| 	{ | ||||
| 		spi.x = xycoord.first + 200 + LOCPLINT->cb->battleGetCreature(ID).upperRightMissleOffsetX; | ||||
| 		spi.y = xycoord.second + 150 - LOCPLINT->cb->battleGetCreature(ID).upperRightMissleOffsetY; | ||||
| 	} | ||||
| 	else if(projectileAngle < -straightAngle) //lower shot | ||||
| 	{ | ||||
| 		spi.x = xycoord.first + 200 + LOCPLINT->cb->battleGetCreature(ID).lowerRightMissleOffsetX; | ||||
| 		spi.y = xycoord.second + 150 - LOCPLINT->cb->battleGetCreature(ID).lowerRightMissleOffsetY; | ||||
| 	} | ||||
| 	else //straight shot | ||||
| 	{ | ||||
| 		spi.x = xycoord.first + 200 + LOCPLINT->cb->battleGetCreature(ID).rightMissleOffsetX; | ||||
| 		spi.y = xycoord.second + 150 - LOCPLINT->cb->battleGetCreature(ID).rightMissleOffsetY; | ||||
| 	} | ||||
| 	spi.lastStep = sqrt((float)((destcoord.first - spi.x)*(destcoord.first - spi.x) + (destcoord.second - spi.y) * (destcoord.second - spi.y))) / 40; | ||||
| 	spi.dx = (destcoord.first - spi.x) / spi.lastStep; | ||||
| 	spi.dy = (destcoord.second - spi.y) / spi.lastStep; | ||||
| 	//set starting frame | ||||
| 	if(spi.spin) | ||||
| 	{ | ||||
| 		spi.frameNum = 0; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		spi.frameNum = ((M_PI/2.0f - projectileAngle) / (2.0f *M_PI) + 1/((float)(2*(idToProjectile[spi.creID]->ourImages.size()-1)))) * (idToProjectile[spi.creID]->ourImages.size()-1); | ||||
| 	} | ||||
| 	//set delay | ||||
| 	spi.animStartDelay = CGI->creh->creatures[spi.creID].attackClimaxFrame; | ||||
| 	projectiles.push_back(spi); | ||||
|  | ||||
| 	//attack aniamtion | ||||
| 	attackingInfo = new CAttHelper; | ||||
| 	attackingInfo->dest = dest; | ||||
| 	attackingInfo->frame = 0; | ||||
| 	attackingInfo->ID = ID; | ||||
| 	attackingInfo->reversing = false; | ||||
| 	attackingInfo->shooting = true; | ||||
| 	if(projectileAngle > straightAngle) //upper shot | ||||
| 		attackingInfo->shootingGroup = 14; | ||||
| 	else if(projectileAngle < -straightAngle) //lower shot | ||||
| 		attackingInfo->shootingGroup = 15; | ||||
| 	else //straight shot | ||||
| 		attackingInfo->shootingGroup = 16; | ||||
| 	attackingInfo->maxframe = creAnims[ID]->framesInGroup(attackingInfo->shootingGroup); | ||||
| } | ||||
|  | ||||
| void CBattleInterface::showRange(SDL_Surface * to, int ID) | ||||
| { | ||||
| 	std::vector<int> shadedHexes = LOCPLINT->cb->battleGetAvailableHexes(ID); | ||||
| @@ -780,52 +840,59 @@ void CBattleInterface::attackingShowHelper() | ||||
| 		if(attackingInfo->frame == 0) | ||||
| 		{ | ||||
| 			CStack aStack = LOCPLINT->cb->battleGetStackByID(attackingInfo->ID); //attacking stack | ||||
| 			if(aStack.creature->isDoubleWide()) | ||||
| 			if(attackingInfo->shooting) | ||||
| 			{ | ||||
| 				switch(CBattleHex::mutualPosition(aStack.position, attackingInfo->dest)) //attack direction | ||||
| 				{ | ||||
| 					case 0: | ||||
| 						creAnims[attackingInfo->ID]->setType(10); | ||||
| 						break; | ||||
| 					case 1: | ||||
| 						creAnims[attackingInfo->ID]->setType(10); | ||||
| 						break; | ||||
| 					case 2: | ||||
| 						creAnims[attackingInfo->ID]->setType(11); | ||||
| 						break; | ||||
| 					case 3: | ||||
| 						creAnims[attackingInfo->ID]->setType(12); | ||||
| 						break; | ||||
| 					case 4: | ||||
| 						creAnims[attackingInfo->ID]->setType(12); | ||||
| 						break; | ||||
| 					case 5: | ||||
| 						creAnims[attackingInfo->ID]->setType(11); | ||||
| 						break; | ||||
| 				} | ||||
| 				creAnims[attackingInfo->ID]->setType(attackingInfo->shootingGroup); | ||||
| 			} | ||||
| 			else //else for if(aStack.creature->isDoubleWide()) | ||||
| 			else | ||||
| 			{ | ||||
| 				switch(CBattleHex::mutualPosition(aStack.position, attackingInfo->dest)) //attack direction | ||||
| 				if(aStack.creature->isDoubleWide()) | ||||
| 				{ | ||||
| 					case 0: | ||||
| 						creAnims[attackingInfo->ID]->setType(10); | ||||
| 						break; | ||||
| 					case 1: | ||||
| 						creAnims[attackingInfo->ID]->setType(10); | ||||
| 						break; | ||||
| 					case 2: | ||||
| 						creAnims[attackingInfo->ID]->setType(11); | ||||
| 						break; | ||||
| 					case 3: | ||||
| 						creAnims[attackingInfo->ID]->setType(12); | ||||
| 						break; | ||||
| 					case 4: | ||||
| 						creAnims[attackingInfo->ID]->setType(12); | ||||
| 						break; | ||||
| 					case 5: | ||||
| 						creAnims[attackingInfo->ID]->setType(11); | ||||
| 						break; | ||||
| 					switch(CBattleHex::mutualPosition(aStack.position, attackingInfo->dest)) //attack direction | ||||
| 					{ | ||||
| 						case 0: | ||||
| 							creAnims[attackingInfo->ID]->setType(10); | ||||
| 							break; | ||||
| 						case 1: | ||||
| 							creAnims[attackingInfo->ID]->setType(10); | ||||
| 							break; | ||||
| 						case 2: | ||||
| 							creAnims[attackingInfo->ID]->setType(11); | ||||
| 							break; | ||||
| 						case 3: | ||||
| 							creAnims[attackingInfo->ID]->setType(12); | ||||
| 							break; | ||||
| 						case 4: | ||||
| 							creAnims[attackingInfo->ID]->setType(12); | ||||
| 							break; | ||||
| 						case 5: | ||||
| 							creAnims[attackingInfo->ID]->setType(11); | ||||
| 							break; | ||||
| 					} | ||||
| 				} | ||||
| 				else //else for if(aStack.creature->isDoubleWide()) | ||||
| 				{ | ||||
| 					switch(CBattleHex::mutualPosition(aStack.position, attackingInfo->dest)) //attack direction | ||||
| 					{ | ||||
| 						case 0: | ||||
| 							creAnims[attackingInfo->ID]->setType(10); | ||||
| 							break; | ||||
| 						case 1: | ||||
| 							creAnims[attackingInfo->ID]->setType(10); | ||||
| 							break; | ||||
| 						case 2: | ||||
| 							creAnims[attackingInfo->ID]->setType(11); | ||||
| 							break; | ||||
| 						case 3: | ||||
| 							creAnims[attackingInfo->ID]->setType(12); | ||||
| 							break; | ||||
| 						case 4: | ||||
| 							creAnims[attackingInfo->ID]->setType(12); | ||||
| 							break; | ||||
| 						case 5: | ||||
| 							creAnims[attackingInfo->ID]->setType(11); | ||||
| 							break; | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| @@ -912,6 +979,43 @@ void CBattleInterface::printConsoleAttacked(int ID, int dmg, int killed, int IDb | ||||
|  | ||||
| void CBattleInterface::projectileShowHelper(SDL_Surface * to) | ||||
| { | ||||
| 	if(to == NULL) | ||||
| 		to = screen; | ||||
| 	std::list< std::list<SProjectileInfo>::iterator > toBeDeleted; | ||||
| 	for(std::list<SProjectileInfo>::iterator it=projectiles.begin(); it!=projectiles.end(); ++it) | ||||
| 	{ | ||||
| 		if(it->animStartDelay>0) | ||||
| 		{ | ||||
| 			--(it->animStartDelay); | ||||
| 			continue; | ||||
| 		} | ||||
| 		SDL_Rect dst; | ||||
| 		dst.h = idToProjectile[it->creID]->ourImages[it->frameNum].bitmap->h; | ||||
| 		dst.w = idToProjectile[it->creID]->ourImages[it->frameNum].bitmap->w; | ||||
| 		dst.x = it->x; | ||||
| 		dst.y = it->y; | ||||
| 		CSDL_Ext::blit8bppAlphaTo24bpp(idToProjectile[it->creID]->ourImages[it->frameNum].bitmap, NULL, to, &dst); | ||||
| 		//actualizing projectile | ||||
| 		++it->step; | ||||
| 		if(it->step == it->lastStep) | ||||
| 		{ | ||||
| 			toBeDeleted.insert(toBeDeleted.end(), it); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			it->x += it->dx; | ||||
| 			it->y += it->dy; | ||||
| 			if(it->spin) | ||||
| 			{ | ||||
| 				++(it->frameNum); | ||||
| 				it->frameNum %= idToProjectile[it->creID]->ourImages.size(); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	for(std::list< std::list<SProjectileInfo>::iterator >::iterator it = toBeDeleted.begin(); it!= toBeDeleted.end(); ++it) | ||||
| 	{ | ||||
| 		projectiles.erase(*it); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CBattleHero::show(SDL_Surface *to) | ||||
|   | ||||
| @@ -93,6 +93,8 @@ private: | ||||
| 		int dest; //atacked hex | ||||
| 		int frame, maxframe; //frame of animation, number of frames of animation | ||||
| 		bool reversing; | ||||
| 		bool shooting; | ||||
| 		int shootingGroup; //if shooting is true, print this animation group | ||||
| 	} * attackingInfo; | ||||
| 	void attackingShowHelper(); | ||||
| 	void printConsoleAttacked(int ID, int dmg, int killed, int IDby); | ||||
| @@ -105,9 +107,10 @@ private: | ||||
| 		int creID; //ID of creature that shot this projectile | ||||
| 		int frameNum; //frame to display form projectile animation | ||||
| 		bool spin; //if true, frameNum will be increased | ||||
| 		int animStartDelay; //how many times projectile must be attempted to be shown till it's really show (decremented after hit) | ||||
| 	}; | ||||
| 	std::list<SProjectileInfo> projectiles; | ||||
| 	void projectileShowHelper(SDL_Surface * to); //prints projectiles present on the battlefield | ||||
| 	void projectileShowHelper(SDL_Surface * to=NULL); //prints projectiles present on the battlefield | ||||
|  | ||||
| public: | ||||
| 	CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, CGHeroInstance *hero1, CGHeroInstance *hero2); //c-tor | ||||
| @@ -140,13 +143,14 @@ public: | ||||
| 	//call-ins | ||||
| 	void newStack(CStack stack); //new stack appeared on battlefield | ||||
| 	void stackRemoved(CStack stack); //stack disappeared from batlefiled | ||||
| 	void stackKilled(int ID, int dmg, int killed, int IDby); //stack has been killed (but corpses remain) | ||||
| 	void stackKilled(int ID, int dmg, int killed, int IDby, bool byShooting); //stack has been killed (but corpses remain) | ||||
| 	void stackActivated(int number); //active stack has been changed | ||||
| 	void stackMoved(int number, int destHex, bool startMoving, bool endMoving); //stack with id number moved to destHex | ||||
| 	void stackIsAttacked(int ID, int dmg, int killed, int IDby); //called when stack id attacked by stack with id IDby | ||||
| 	void stackIsAttacked(int ID, int dmg, int killed, int IDby, bool byShooting); //called when stack id attacked by stack with id IDby | ||||
| 	void stackAttacking(int ID, int dest); //called when stack with id ID is attacking something on hex dest | ||||
| 	void newRound(int number); //caled when round is ended; number is the number of round | ||||
| 	void hexLclicked(int whichOne); //hex only call-in | ||||
| 	void stackIsShooting(int ID, int dest); //called when stack with id ID is shooting to hex dest | ||||
|  | ||||
| 	friend class CBattleHex; | ||||
| }; | ||||
|   | ||||
| @@ -14,9 +14,15 @@ | ||||
| #include "CPlayerInterface.h" | ||||
| #include "hch/CBuildingHandler.h" | ||||
|  | ||||
| #ifndef _MSC_VER | ||||
| extern "C" { | ||||
| #endif | ||||
|  | ||||
| LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); | ||||
|  | ||||
| #ifndef _MSC_VER | ||||
| } | ||||
| #endif | ||||
|  | ||||
| int CCallback::lowestSpeed(CGHeroInstance * chi) | ||||
| { | ||||
| @@ -770,18 +776,7 @@ int CCallback::battleGetObstaclesAtTile(int tile) //returns bitfield | ||||
| } | ||||
| int CCallback::battleGetStack(int pos) | ||||
| { | ||||
| 	for(int g=0; g<CGI->state->curB->stacks.size(); ++g) | ||||
| 	{ | ||||
| 		if(CGI->state->curB->stacks[g]->position == pos || | ||||
| 				( CGI->state->curB->stacks[g]->creature->isDoubleWide() && | ||||
| 					( (CGI->state->curB->stacks[g]->attackerOwned && CGI->state->curB->stacks[g]->position-1 == pos) || | ||||
| 						(!CGI->state->curB->stacks[g]->attackerOwned && CGI->state->curB->stacks[g]->position+1 == pos) | ||||
| 					) | ||||
| 				) | ||||
| 			) | ||||
| 			return CGI->state->curB->stacks[g]->ID; | ||||
| 	} | ||||
| 	return -1; | ||||
| 	return CGI->state->battleGetStack(pos); | ||||
| } | ||||
|  | ||||
| CStack CCallback::battleGetStackByID(int ID) | ||||
|   | ||||
							
								
								
									
										162
									
								
								CGameState.cpp
									
									
									
									
									
								
							
							
						
						
									
										162
									
								
								CGameState.cpp
									
									
									
									
									
								
							| @@ -239,6 +239,7 @@ void CGameState::battle(CCreatureSet * army1, CCreatureSet * army2, int3 tile, C | ||||
| 						} | ||||
| 					case 7: //shoot | ||||
| 						{ | ||||
| 							battleShootCreatureStack(ba.stackNumber, ba.destinationTile); | ||||
| 							break; | ||||
| 						} | ||||
| 					} | ||||
| @@ -430,43 +431,7 @@ bool CGameState::battleMoveCreatureStack(int ID, int dest) | ||||
| 		{ | ||||
| 			LOCPLINT->battleStackAttacking(ID, path[v]); | ||||
| 			//counting dealt damage | ||||
| 			int numberOfCres = curStack->amount; //number of attacking creatures | ||||
| 			int attackDefenseBonus = curStack->creature->attack - curB->stacks[numberOfStackAtEnd]->creature->defence; | ||||
| 			int damageBase = 0; | ||||
| 			if(curStack->creature->damageMax == curStack->creature->damageMin) //constant damage | ||||
| 			{ | ||||
| 				damageBase = curStack->creature->damageMin; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				damageBase = rand()%(curStack->creature->damageMax - curStack->creature->damageMin) + curStack->creature->damageMin + 1; | ||||
| 			} | ||||
|  | ||||
| 			float dmgBonusMultiplier = 1.0; | ||||
| 			if(attackDefenseBonus < 0) //decreasing dmg | ||||
| 			{ | ||||
| 				if(0.02f * (-attackDefenseBonus) > 0.3f) | ||||
| 				{ | ||||
| 					dmgBonusMultiplier += -0.3f; | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					dmgBonusMultiplier += 0.02f * attackDefenseBonus; | ||||
| 				} | ||||
| 			} | ||||
| 			else //increasing dmg | ||||
| 			{ | ||||
| 				if(0.05f * attackDefenseBonus > 4.0f) | ||||
| 				{ | ||||
| 					dmgBonusMultiplier += 4.0f; | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					dmgBonusMultiplier += 0.05f * attackDefenseBonus; | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			int finalDmg = (float)damageBase * (float)curStack->amount * dmgBonusMultiplier; | ||||
| 			int finalDmg = calculateDmg(curStack, curB->stacks[numberOfStackAtEnd]); | ||||
|  | ||||
| 			//applying damages | ||||
| 			int cresKilled = finalDmg / curB->stacks[numberOfStackAtEnd]->creature->hitPoints; | ||||
| @@ -487,12 +452,12 @@ bool CGameState::battleMoveCreatureStack(int ID, int dest) | ||||
| 			if(curB->stacks[numberOfStackAtEnd]->amount<=0) //stack killed | ||||
| 			{ | ||||
| 				curB->stacks[numberOfStackAtEnd]->amount = 0; | ||||
| 				LOCPLINT->battleStackKilled(curB->stacks[numberOfStackAtEnd]->ID, finalDmg, std::min(cresKilled, cresInstackBefore) , ID); | ||||
| 				LOCPLINT->battleStackKilled(curB->stacks[numberOfStackAtEnd]->ID, finalDmg, std::min(cresKilled, cresInstackBefore) , ID, false); | ||||
| 				curB->stacks[numberOfStackAtEnd]->alive = false; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				LOCPLINT->battleStackIsAttacked(curB->stacks[numberOfStackAtEnd]->ID, finalDmg, std::min(cresKilled, cresInstackBefore), ID); | ||||
| 				LOCPLINT->battleStackIsAttacked(curB->stacks[numberOfStackAtEnd]->ID, finalDmg, std::min(cresKilled, cresInstackBefore), ID, false); | ||||
| 			} | ||||
|  | ||||
| 			//damage applied | ||||
| @@ -520,6 +485,125 @@ bool CGameState::battleAttackCreatureStack(int ID, int dest) | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| bool CGameState::battleShootCreatureStack(int ID, int dest) | ||||
| { | ||||
| 	CStack * curStack = NULL; | ||||
| 	for(int y=0; y<curB->stacks.size(); ++y) | ||||
| 	{ | ||||
| 		if(curB->stacks[y]->ID == ID) | ||||
| 		{ | ||||
| 			curStack = curB->stacks[y]; | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	if(!curStack) | ||||
| 		return false; | ||||
| 	int IDOfStackAtEnd = battleGetStack(dest); | ||||
| 	int numberOfStackAtEnd = -1; | ||||
| 	for(int v=0; v<curB->stacks.size(); ++v) | ||||
| 	{ | ||||
| 		if(curB->stacks[v]->ID == IDOfStackAtEnd) | ||||
| 		{ | ||||
| 			numberOfStackAtEnd = v; | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if(IDOfStackAtEnd == -1 || curB->stacks[numberOfStackAtEnd]->owner == curStack->owner) | ||||
| 		return false; | ||||
|  | ||||
| 	LOCPLINT->battleStackIsShooting(ID, dest); | ||||
|  | ||||
| 	//counting dealt damage | ||||
| 	int finalDmg = calculateDmg(curStack, curB->stacks[numberOfStackAtEnd]); | ||||
|  | ||||
| 	//applying damages | ||||
| 	int cresKilled = finalDmg / curB->stacks[ID]->creature->hitPoints; | ||||
| 	int damageFirst = finalDmg % curB->stacks[ID]->creature->hitPoints; | ||||
|  | ||||
| 	if( curB->stacks[numberOfStackAtEnd]->firstHPleft <= damageFirst ) | ||||
| 	{ | ||||
| 		curB->stacks[numberOfStackAtEnd]->amount -= 1; | ||||
| 		curB->stacks[numberOfStackAtEnd]->firstHPleft += curB->stacks[numberOfStackAtEnd]->creature->hitPoints - damageFirst; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		curB->stacks[numberOfStackAtEnd]->firstHPleft -= damageFirst; | ||||
| 	} | ||||
|  | ||||
| 	int cresInstackBefore = curB->stacks[numberOfStackAtEnd]->amount;  | ||||
| 	curB->stacks[numberOfStackAtEnd]->amount -= cresKilled; | ||||
| 	if(curB->stacks[numberOfStackAtEnd]->amount<=0) //stack killed | ||||
| 	{ | ||||
| 		curB->stacks[numberOfStackAtEnd]->amount = 0; | ||||
| 		LOCPLINT->battleStackKilled(curB->stacks[numberOfStackAtEnd]->ID, finalDmg, std::min(cresKilled, cresInstackBefore), ID, true); | ||||
| 		curB->stacks[numberOfStackAtEnd]->alive = false; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		LOCPLINT->battleStackIsAttacked(curB->stacks[numberOfStackAtEnd]->ID, finalDmg, std::min(cresKilled, cresInstackBefore), ID, true); | ||||
| 	} | ||||
|  | ||||
| 	//damage applied | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| int CGameState::battleGetStack(int pos) | ||||
| { | ||||
| 	for(int g=0; g<curB->stacks.size(); ++g) | ||||
| 	{ | ||||
| 		if(curB->stacks[g]->position == pos || | ||||
| 				( curB->stacks[g]->creature->isDoubleWide() && | ||||
| 					( (curB->stacks[g]->attackerOwned && curB->stacks[g]->position-1 == pos) || | ||||
| 						(!curB->stacks[g]->attackerOwned && curB->stacks[g]->position+1 == pos) | ||||
| 					) | ||||
| 				) | ||||
| 			) | ||||
| 			return curB->stacks[g]->ID; | ||||
| 	} | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| int CGameState::calculateDmg(const CStack* attacker, const CStack* defender) | ||||
| { | ||||
| 	int attackDefenseBonus = attacker->creature->attack - defender->creature->defence; | ||||
| 	int damageBase = 0; | ||||
| 	if(attacker->creature->damageMax == attacker->creature->damageMin) //constant damage | ||||
| 	{ | ||||
| 		damageBase = attacker->creature->damageMin; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		damageBase = rand()%(attacker->creature->damageMax - attacker->creature->damageMin) + attacker->creature->damageMin + 1; | ||||
| 	} | ||||
|  | ||||
| 	float dmgBonusMultiplier = 1.0; | ||||
| 	if(attackDefenseBonus < 0) //decreasing dmg | ||||
| 	{ | ||||
| 		if(0.02f * (-attackDefenseBonus) > 0.3f) | ||||
| 		{ | ||||
| 			dmgBonusMultiplier += -0.3f; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			dmgBonusMultiplier += 0.02f * attackDefenseBonus; | ||||
| 		} | ||||
| 	} | ||||
| 	else //increasing dmg | ||||
| 	{ | ||||
| 		if(0.05f * attackDefenseBonus > 4.0f) | ||||
| 		{ | ||||
| 			dmgBonusMultiplier += 4.0f; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			dmgBonusMultiplier += 0.05f * attackDefenseBonus; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return (float)damageBase * (float)attacker->amount * dmgBonusMultiplier; | ||||
| } | ||||
|  | ||||
| std::vector<int> CGameState::battleGetRange(int ID) | ||||
| { | ||||
| 	int initialPlace=-1; //position of unit | ||||
|   | ||||
| @@ -100,6 +100,9 @@ private: | ||||
| 	void battle(CCreatureSet * army1, CCreatureSet * army2, int3 tile, CArmedInstance *hero1, CArmedInstance *hero2); | ||||
| 	bool battleMoveCreatureStack(int ID, int dest); | ||||
| 	bool battleAttackCreatureStack(int ID, int dest); | ||||
| 	bool battleShootCreatureStack(int ID, int dest); | ||||
| 	int battleGetStack(int pos); //returns ID of stack at given tile | ||||
| 	static int calculateDmg(const CStack* attacker, const CStack* defender); //TODO: add additional conditions and require necessary data | ||||
| 	std::vector<int> battleGetRange(int ID); //called by std::vector<int> CCallback::battleGetAvailableHexes(int ID); | ||||
| public: | ||||
| 	friend class CCallback; | ||||
|   | ||||
							
								
								
									
										8
									
								
								CLua.cpp
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								CLua.cpp
									
									
									
									
									
								
							| @@ -2,14 +2,22 @@ | ||||
| #include "CLua.h" | ||||
| #include "CLuaHandler.h" | ||||
| #include "hch/CHeroHandler.h" | ||||
|  | ||||
| #ifndef _MSC_VER | ||||
| extern "C" { | ||||
| #endif | ||||
|  | ||||
| #include "lua.h" | ||||
| #include "lualib.h" | ||||
| #include "lauxlib.h" | ||||
| #include "lobject.h" | ||||
| #include "lgc.h" | ||||
| #include "lapi.h" | ||||
|  | ||||
| #ifndef _MSC_VER | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #include "CGameInfo.h" | ||||
| #include "CGameState.h" | ||||
| #include <sstream> | ||||
|   | ||||
							
								
								
									
										9
									
								
								CLua.h
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								CLua.h
									
									
									
									
									
								
							| @@ -1,8 +1,17 @@ | ||||
| #pragma once | ||||
| #include "global.h" | ||||
|  | ||||
|  | ||||
| #ifndef _MSC_VER | ||||
| extern "C" { | ||||
| #endif | ||||
|  | ||||
| #include "lstate.h" | ||||
|  | ||||
| #ifndef _MSC_VER | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #include <set> | ||||
| #include <map> | ||||
| class CLua; | ||||
|   | ||||
| @@ -1,10 +1,17 @@ | ||||
| #include "stdafx.h" | ||||
|  | ||||
| #ifndef _MSC_VER | ||||
| extern "C" { | ||||
| #endif | ||||
|  | ||||
| #include "lua.h" | ||||
| #include "lualib.h" | ||||
| #include "lauxlib.h"  | ||||
|  | ||||
| #ifndef _MSC_VER | ||||
| } | ||||
| #endif | ||||
|  | ||||
| //#include <luabind/luabind.hpp> | ||||
| //#include <luabind/function.hpp> | ||||
| //#include <luabind/class.hpp> | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
| #define CMESSAGE_H | ||||
|  | ||||
| #include "global.h" | ||||
| #include "SDL_ttf.h" | ||||
| #include <SDL_ttf.h> | ||||
| #include "SDL.h" | ||||
| #include "CPreGame.h" | ||||
|  | ||||
|   | ||||
| @@ -2080,14 +2080,19 @@ void CPlayerInterface::battleStackAttacking(int ID, int dest) | ||||
| 	dynamic_cast<CBattleInterface*>(curint)->stackAttacking(ID, dest); | ||||
| } | ||||
|  | ||||
| void CPlayerInterface::battleStackIsAttacked(int ID, int dmg, int killed, int IDby) | ||||
| void CPlayerInterface::battleStackIsAttacked(int ID, int dmg, int killed, int IDby, bool byShooting) | ||||
| { | ||||
| 	dynamic_cast<CBattleInterface*>(curint)->stackIsAttacked(ID, dmg, killed, IDby); | ||||
| 	dynamic_cast<CBattleInterface*>(curint)->stackIsAttacked(ID, dmg, killed, IDby, byShooting); | ||||
| } | ||||
|  | ||||
| void CPlayerInterface::battleStackKilled(int ID, int dmg, int killed, int IDby) | ||||
| void CPlayerInterface::battleStackKilled(int ID, int dmg, int killed, int IDby, bool byShooting) | ||||
| { | ||||
| 	dynamic_cast<CBattleInterface*>(curint)->stackKilled(ID, dmg, killed, IDby); | ||||
| 	dynamic_cast<CBattleInterface*>(curint)->stackKilled(ID, dmg, killed, IDby, byShooting); | ||||
| } | ||||
|  | ||||
| void CPlayerInterface::battleStackIsShooting(int ID, int dest) | ||||
| { | ||||
| 	dynamic_cast<CBattleInterface*>(curint)->stackIsShooting(ID, dest); | ||||
| } | ||||
|  | ||||
| void CPlayerInterface::showComp(SComponent comp) | ||||
|   | ||||
| @@ -341,8 +341,9 @@ public: | ||||
| 	void battleEnd(CCreatureSet * army1, CCreatureSet * army2, CArmedInstance *hero1, CArmedInstance *hero2, std::vector<int> capturedArtifacts, int expForWinner, bool winner); | ||||
| 	void battleStackMoved(int ID, int dest, bool startMoving, bool endMoving); | ||||
| 	void battleStackAttacking(int ID, int dest); | ||||
| 	void battleStackIsAttacked(int ID, int dmg, int killed, int IDby); | ||||
| 	void battleStackKilled(int ID, int dmg, int killed, int IDby); | ||||
| 	void battleStackIsAttacked(int ID, int dmg, int killed, int IDby, bool byShooting); | ||||
| 	void battleStackKilled(int ID, int dmg, int killed, int IDby, bool byShooting); | ||||
| 	void battleStackIsShooting(int ID, int dest); //called when stack with id ID is shooting to hex dest | ||||
|  | ||||
|  | ||||
| 	//-------------// | ||||
|   | ||||
		Reference in New Issue
	
	Block a user