mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	* added slow spell
* a few mistakes in AC_desc.txt fixed * appropriate spells cannot be casted at any tile * small memory optimizations in CDefHandler * minor fixes
This commit is contained in:
		| @@ -7,6 +7,7 @@ | ||||
| #include "hch/CObjectHandler.h" | ||||
| #include "hch/CHeroHandler.h" | ||||
| #include "hch/CDefHandler.h" | ||||
| #include "hch/CSpellHandler.h" | ||||
| #include "CCursorHandler.h" | ||||
| #include "CCallback.h" | ||||
| #include "CGameState.h" | ||||
| @@ -410,7 +411,7 @@ void CBattleInterface::show(SDL_Surface * to) | ||||
| 	std::vector< std::list<SBattleEffect>::iterator > toErase; | ||||
| 	for(std::list<SBattleEffect>::iterator it = battleEffects.begin(); it!=battleEffects.end(); ++it) | ||||
| 	{ | ||||
| 		blitAt(it->anim->ourImages[it->frame].bitmap, it->x, it->y, to); | ||||
| 		blitAt(it->anim->ourImages[(it->frame)%it->anim->ourImages.size()].bitmap, it->x, it->y, to); | ||||
| 		++(it->frame); | ||||
|  | ||||
| 		if(it->frame == it->maxFrame) | ||||
| @@ -565,6 +566,51 @@ void CBattleInterface::mouseMoved(const SDL_MouseMotionEvent &sEvent) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	else if(spellDestSelectMode) | ||||
| 	{ | ||||
| 		int myNumber = -1; //number of hovered tile | ||||
| 		for(int g=0; g<BFIELD_SIZE; ++g) | ||||
| 		{ | ||||
| 			if(bfield[g].hovered && bfield[g].strictHovered) | ||||
| 			{ | ||||
| 				myNumber = g; | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 		if(myNumber == -1) | ||||
| 		{ | ||||
| 			CGI->curh->changeGraphic(1, 0); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			switch(spellSelMode) | ||||
| 			{ | ||||
| 			case 0: | ||||
| 				CGI->curh->changeGraphic(3, 0); | ||||
| 				break; | ||||
| 			case 1: | ||||
| 				if(LOCPLINT->cb->battleGetStackByPos(myNumber) && LOCPLINT->playerID == LOCPLINT->cb->battleGetStackByPos(myNumber)->owner ) | ||||
| 					CGI->curh->changeGraphic(3, 0); | ||||
| 				else | ||||
| 					CGI->curh->changeGraphic(1, 0); | ||||
| 				break; | ||||
| 			case 2: | ||||
| 				if(LOCPLINT->cb->battleGetStackByPos(myNumber) && LOCPLINT->playerID != LOCPLINT->cb->battleGetStackByPos(myNumber)->owner ) | ||||
| 					CGI->curh->changeGraphic(3, 0); | ||||
| 				else | ||||
| 					CGI->curh->changeGraphic(1, 0); | ||||
| 				break; | ||||
| 			case 3: | ||||
| 				if(LOCPLINT->cb->battleGetStackByPos(myNumber)) | ||||
| 					CGI->curh->changeGraphic(3, 0); | ||||
| 				else | ||||
| 					CGI->curh->changeGraphic(1, 0); | ||||
| 				break; | ||||
| 			case 4: //TODO: implement this case | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| bool CBattleInterface::reverseCreature(int number, int hex, bool wideTrick) | ||||
| @@ -1077,12 +1123,35 @@ void CBattleInterface::hexLclicked(int whichOne) | ||||
| 			return; //we are not permit to do anything | ||||
| 		if(spellDestSelectMode) | ||||
| 		{ | ||||
| 			spellToCast->destinationTile = whichOne; | ||||
| 			LOCPLINT->cb->battleMakeAction(spellToCast); | ||||
| 			delete spellToCast; | ||||
| 			spellToCast = NULL; | ||||
| 			spellDestSelectMode = false; | ||||
| 			CGI->curh->changeGraphic(1, 6); | ||||
| 			//checking destination | ||||
| 			bool allowCasting = true; | ||||
| 			switch(spellSelMode) | ||||
| 			{ | ||||
| 			case 1: | ||||
| 				if(!LOCPLINT->cb->battleGetStackByPos(whichOne) || LOCPLINT->playerID != LOCPLINT->cb->battleGetStackByPos(whichOne)->owner ) | ||||
| 					allowCasting = false; | ||||
| 				break; | ||||
| 			case 2: | ||||
| 				if(!LOCPLINT->cb->battleGetStackByPos(whichOne) || LOCPLINT->playerID == LOCPLINT->cb->battleGetStackByPos(whichOne)->owner ) | ||||
| 					allowCasting = false; | ||||
| 				break; | ||||
| 			case 3: | ||||
| 				if(!LOCPLINT->cb->battleGetStackByPos(whichOne)) | ||||
| 					allowCasting = false; | ||||
| 				break; | ||||
| 			case 4: //TODO: implement this case | ||||
| 				break; | ||||
| 			} | ||||
| 			//destination checked | ||||
| 			if(allowCasting) | ||||
| 			{ | ||||
| 				spellToCast->destinationTile = whichOne; | ||||
| 				LOCPLINT->cb->battleMakeAction(spellToCast); | ||||
| 				delete spellToCast; | ||||
| 				spellToCast = NULL; | ||||
| 				spellDestSelectMode = false; | ||||
| 				CGI->curh->changeGraphic(1, 6); | ||||
| 			} | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| @@ -1282,11 +1351,16 @@ void CBattleInterface::spellCasted(SpellCasted * sc) | ||||
| 			displayEffect(1, sc->tile); | ||||
| 			break; | ||||
| 		} | ||||
| 	case 53://haste | ||||
| 	case 53: //haste | ||||
| 		{ | ||||
| 			displayEffect(31, sc->tile); | ||||
| 			break; | ||||
| 		} | ||||
| 	case 54: //slow | ||||
| 		{ | ||||
| 			displayEffect(19, sc->tile); | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -1300,6 +1374,22 @@ void CBattleInterface::castThisSpell(int spellID) | ||||
| 	ba->side = defendingHeroInstance ? (LOCPLINT->playerID == defendingHeroInstance->tempOwner) : false; | ||||
| 	spellToCast = ba; | ||||
| 	spellDestSelectMode = true; | ||||
|  | ||||
| 	//choosing possible tragets | ||||
| 	const CGHeroInstance * castingHero = (attackingHeroInstance->tempOwner == LOCPLINT->playerID) ? attackingHeroInstance : attackingHeroInstance; | ||||
| 	spellSelMode = 0; | ||||
| 	if(CGI->spellh->spells[spellID].attributes.find("CREATURE_TARGET") != std::string::npos) | ||||
| 	{ | ||||
| 		spellSelMode = 3; | ||||
| 	} | ||||
| 	if(CGI->spellh->spells[spellID].attributes.find("CREATURE_TARGET_2") != std::string::npos) | ||||
| 	{ | ||||
| 		if(castingHero && castingHero->getSpellSecLevel(spellID) < 3) | ||||
| 			spellSelMode = 3; | ||||
| 		else //TODO: no destination chould apply in this case | ||||
| 		{ | ||||
| 		} | ||||
| 	} | ||||
| 	CGI->curh->changeGraphic(3, 0);  | ||||
| } | ||||
|  | ||||
| @@ -1311,8 +1401,8 @@ void CBattleInterface::displayEffect(ui32 effect, int destTile) | ||||
| 		be.anim = CDefHandler::giveDef(graphics->battleACToDef[effect][0]); | ||||
| 		be.frame = 0; | ||||
| 		be.maxFrame = be.anim->ourImages.size(); | ||||
| 		be.x = 22 * ( ((destTile/BFIELD_WIDTH) + 1)%2 ) + 44 * (destTile % BFIELD_WIDTH) + 50; | ||||
| 		be.y = 100 + 42 * (destTile/BFIELD_WIDTH); | ||||
| 		be.x = 22 * ( ((destTile/BFIELD_WIDTH) + 1)%2 ) + 44 * (destTile % BFIELD_WIDTH) + 45; | ||||
| 		be.y = 105 + 42 * (destTile/BFIELD_WIDTH); | ||||
|  | ||||
| 		if(effect != 1) | ||||
| 		{ | ||||
|   | ||||
| @@ -135,6 +135,7 @@ private: | ||||
| 	float getAnimSpeedMultiplier() const; //returns multiplier for number of frames in a group | ||||
|  | ||||
| 	bool spellDestSelectMode; //if true, player is choosing destination for his spell | ||||
| 	int spellSelMode; //0 - any location, 1 - any firendly creature, 2 - any hostile creature, 3 - any creature, 4 - obstacle | ||||
| 	BattleAction * spellToCast; //spell for which player is choosing destination | ||||
|  | ||||
| 	class CAttHelper | ||||
|   | ||||
| @@ -212,7 +212,7 @@ signed char BattleInfo::mutualPosition(int hex1, int hex2) | ||||
| } | ||||
| std::vector<int> BattleInfo::neighbouringTiles(int hex) | ||||
| { | ||||
| #define CHECK_AND_PUSH(tile) {int hlp = (tile); if(hlp>=0 && hlp<BFIELD_SIZE && (hlp%17!=16) && hlp%17) ret.push_back(hlp);} | ||||
| #define CHECK_AND_PUSH(tile) {int hlp = (tile); if(hlp>=0 && hlp<BFIELD_SIZE && (hlp%BFIELD_WIDTH!=16) && hlp%BFIELD_WIDTH) ret.push_back(hlp);} | ||||
| 	std::vector<int> ret; | ||||
| 	CHECK_AND_PUSH(hex - ( (hex/17)%2 ? 18 : 17 )); | ||||
| 	CHECK_AND_PUSH(hex - ( (hex/17)%2 ? 17 : 16 )); | ||||
|   | ||||
| @@ -18,7 +18,7 @@ | ||||
| 16 1 C08SPE0.DEF | ||||
| 17 1 C08SPF0.DEF | ||||
| 18 1 C09SPA0.DEF | ||||
| 19 3 C17SPE0.DEF C17SPE1.DEF C17SPE2.DEF | ||||
| 19 1 C09SPE0.DEF | ||||
| 20 1 C09SPW0.DEF | ||||
| 21 1 C10SPA0.DEF | ||||
| 22 1 C11SPE0.DEF | ||||
| @@ -54,10 +54,10 @@ | ||||
| 52 1 C12SPE0.DEF | ||||
| 53 2 C13SPF.DEF C13SPF0.DEF | ||||
| 54 2 C16SPE.DEF C16SPE0.DEF | ||||
| 55 1 C09SPE0.DEF | ||||
| 55 1 C17SPE0.DEF | ||||
| 56 1 C0ACID.DEF | ||||
| 57 2 C09SPF1.DEF C09SPF2.DEF | ||||
| 58 0 | ||||
| 58 1 C17SPE2.DEF | ||||
| 59 1 C09SPF0.DEF | ||||
| 60 0 | ||||
| 61 0 | ||||
|   | ||||
| @@ -16,7 +16,6 @@ CDefHandler::CDefHandler() | ||||
| { | ||||
| 	//FDef = NULL; | ||||
| 	RWEntries = NULL; | ||||
| 	RLEntries = NULL; | ||||
| 	notFreeImgs = false; | ||||
| } | ||||
| CDefHandler::~CDefHandler() | ||||
| @@ -25,8 +24,6 @@ CDefHandler::~CDefHandler() | ||||
| 		//delete [] FDef; | ||||
| 	if (RWEntries) | ||||
| 		delete [] RWEntries; | ||||
| 	if (RLEntries) | ||||
| 		delete [] RLEntries; | ||||
| 	if (notFreeImgs) | ||||
| 		return; | ||||
| 	for (int i=0; i<ourImages.size(); i++) | ||||
| @@ -47,6 +44,7 @@ void CDefHandler::openDef(std::string name) | ||||
| { | ||||
| 	int i,j, totalInBlock; | ||||
| 	char Buffer[13]; | ||||
| 	BMPPalette palette[256]; | ||||
| 	defName=name; | ||||
|  | ||||
| 	int andame; | ||||
| @@ -108,7 +106,7 @@ void CDefHandler::openDef(std::string name) | ||||
| 	for(int i=0; i<SEntries.size(); ++i) | ||||
| 	{ | ||||
| 		Cimage nimg; | ||||
| 		nimg.bitmap = getSprite(i, FDef); | ||||
| 		nimg.bitmap = getSprite(i, FDef, palette); | ||||
| 		nimg.imName = SEntries[i].name; | ||||
| 		nimg.groupNumber = SEntries[i].group; | ||||
| 		ourImages.push_back(nimg); | ||||
| @@ -121,6 +119,7 @@ void CDefHandler::openFromMemory(unsigned char *table, std::string name) | ||||
| { | ||||
| 	int i,j, totalInBlock; | ||||
| 	char Buffer[13]; | ||||
| 	BMPPalette palette[256]; | ||||
| 	defName=name; | ||||
| 	i = 0; | ||||
| 	DEFType = readNormalNr(i,4,table); i+=4; | ||||
| @@ -170,11 +169,10 @@ void CDefHandler::openFromMemory(unsigned char *table, std::string name) | ||||
| 		SEntries[j].name = SEntries[j].name.substr(0, SEntries[j].name.find('.')+4); | ||||
| 	} | ||||
| 	RWEntries = new unsigned int[fullHeight]; | ||||
| 	RLEntries = new int[fullHeight]; | ||||
| 	for(int i=0; i<SEntries.size(); ++i) | ||||
| 	{ | ||||
| 		Cimage nimg; | ||||
| 		nimg.bitmap = getSprite(i, table); | ||||
| 		nimg.bitmap = getSprite(i, table, palette); | ||||
| 		nimg.imName = SEntries[i].name; | ||||
| 		nimg.groupNumber = SEntries[i].group; | ||||
| 		ourImages.push_back(nimg); | ||||
| @@ -241,7 +239,7 @@ void CDefHandler::print (std::ostream & stream, int nr, int bytcon) | ||||
| 	free(temp); | ||||
| } | ||||
|  | ||||
| SDL_Surface * CDefHandler::getSprite (int SIndex, unsigned char * FDef) | ||||
| SDL_Surface * CDefHandler::getSprite (int SIndex, unsigned char * FDef, BMPPalette * palette) | ||||
| { | ||||
| 	SDL_Surface * ret=NULL; | ||||
|  | ||||
| @@ -341,11 +339,11 @@ SDL_Surface * CDefHandler::getSprite (int SIndex, unsigned char * FDef) | ||||
| 		} | ||||
| 		for (int i=0;i<SpriteHeight;i++) | ||||
| 		{ | ||||
| 			RLEntries[i]=readNormalNr(BaseOffset,4,FDef);BaseOffset+=4; | ||||
| 			RWEntries[i]=readNormalNr(BaseOffset,4,FDef);BaseOffset+=4; | ||||
| 		} | ||||
| 		for (int i=0;i<SpriteHeight;i++) | ||||
| 		{ | ||||
| 			BaseOffset=BaseOffsetor+RLEntries[i]; | ||||
| 			BaseOffset=BaseOffsetor+RWEntries[i]; | ||||
| 			if (LeftMargin>0) | ||||
| 			{ | ||||
| 				for (int j=0;j<LeftMargin;j++) | ||||
|   | ||||
| @@ -18,9 +18,7 @@ private: | ||||
| 	int totalEntries, DEFType, totalBlocks, fullWidth, fullHeight; | ||||
| 	bool allowRepaint; | ||||
| 	int length; | ||||
| 	BMPPalette palette[256]; | ||||
| 	unsigned int * RWEntries; | ||||
| 	int * RLEntries; | ||||
| 	struct SEntry | ||||
| 	{ | ||||
| 		std::string name; | ||||
| @@ -28,8 +26,6 @@ private: | ||||
| 		int group; | ||||
| 	} ; | ||||
| 	std::vector<SEntry> SEntries ; | ||||
| 	char id[2]; | ||||
|  | ||||
|  | ||||
| public: | ||||
| 	static CLodHandler * Spriteh; | ||||
| @@ -43,7 +39,7 @@ public: | ||||
| 	static void print (std::ostream & stream, int nr, int bytcon); | ||||
| 	int readNormalNr (int pos, int bytCon, unsigned char * str=NULL, bool cyclic=false); | ||||
| 	static unsigned char *writeNormalNr (int nr, int bytCon); | ||||
| 	SDL_Surface * getSprite (int SIndex, unsigned char * FDef); //zapisuje klatke o zadanym numerze do "testtt.bmp" | ||||
| 	SDL_Surface * getSprite (int SIndex, unsigned char * FDef, BMPPalette * palette); //zapisuje klatke o zadanym numerze do "testtt.bmp" | ||||
| 	void openDef(std::string name); | ||||
| 	void expand(unsigned char N,unsigned char & BL, unsigned char & BR); | ||||
| 	void openFromMemory(unsigned char * table, std::string name); | ||||
|   | ||||
| @@ -5,6 +5,7 @@ | ||||
| #include "CLodHandler.h" | ||||
| #include "CDefObjInfoHandler.h" | ||||
| #include "CHeroHandler.h" | ||||
| #include "CSpellHandler.h" | ||||
| #include <boost/algorithm/string/replace.hpp> | ||||
| #include <boost/random/linear_congruential.hpp> | ||||
| #include "CTownHandler.h" | ||||
| @@ -407,6 +408,33 @@ const CArtifact * CGHeroInstance::getArt(int pos) const | ||||
| 	else | ||||
| 		return NULL; | ||||
| } | ||||
|  | ||||
| int CGHeroInstance::getSpellSecLevel(int spell) const | ||||
| { | ||||
| 	int bestslvl = 0; | ||||
| 	if(VLC->spellh->spells[spell].air) | ||||
| 		if(getSecSkillLevel(15) >= bestslvl) | ||||
| 		{ | ||||
| 			bestslvl = getSecSkillLevel(15); | ||||
| 		} | ||||
| 	if(VLC->spellh->spells[spell].fire) | ||||
| 		if(getSecSkillLevel(14) >= bestslvl) | ||||
| 		{ | ||||
| 			bestslvl = getSecSkillLevel(14); | ||||
| 		} | ||||
| 	if(VLC->spellh->spells[spell].water) | ||||
| 		if(getSecSkillLevel(16) >= bestslvl) | ||||
| 		{ | ||||
| 			bestslvl = getSecSkillLevel(16); | ||||
| 		} | ||||
| 	if(VLC->spellh->spells[spell].earth) | ||||
| 		if(getSecSkillLevel(17) >= bestslvl) | ||||
| 		{ | ||||
| 			bestslvl = getSecSkillLevel(17); | ||||
| 		} | ||||
| 	return bestslvl; | ||||
| } | ||||
|  | ||||
| int CGTownInstance::getSightDistance() const //returns sight distance | ||||
| { | ||||
| 	return 10; | ||||
|   | ||||
| @@ -132,6 +132,7 @@ public: | ||||
| 	ui32 getArtAtPos(ui16 pos) const; //-1 - no artifact | ||||
| 	void setArtAtPos(ui16 pos, int art); | ||||
| 	const CArtifact * getArt(int pos) const; | ||||
| 	int getSpellSecLevel(int spell) const; //returns level of secondary ability (fire, water, earth, air magic) known to this hero and applicable to given spell; -1 if error | ||||
| 	void initHero();  | ||||
| 	void initHero(int SUBID);  | ||||
| 	CGHeroInstance(); | ||||
|   | ||||
| @@ -1279,6 +1279,16 @@ upgend: | ||||
| 									sendAndApply(&sse); | ||||
| 									break; | ||||
| 								} | ||||
| 							case 54: //slow | ||||
| 								{ | ||||
| 									SetStackEffect sse; | ||||
| 									sse.stack = gs->curB->getStackT(ba.destinationTile)->ID; | ||||
| 									sse.effect.id = 54; | ||||
| 									sse.effect.level = getSchoolLevel(h,s); | ||||
| 									sse.effect.turnsRemain = h->getPrimSkillLevel(2); | ||||
| 									sendAndApply(&sse); | ||||
| 									break; | ||||
| 								} | ||||
| 							} | ||||
|  | ||||
| 							//TODO: spells to support possibly soon (list by Zamolxis): | ||||
|   | ||||
		Reference in New Issue
	
	Block a user