mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Sound patch from Ubuntux #6 - adds sound to units during combats
(vcmi_sound_battle.diff)
This commit is contained in:
		| @@ -57,7 +57,7 @@ CBattleInterface::CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, C | |||||||
| 	: attackingHeroInstance(hero1), defendingHeroInstance(hero2), animCount(0), activeStack(-1),  | 	: attackingHeroInstance(hero1), defendingHeroInstance(hero2), animCount(0), activeStack(-1),  | ||||||
| 	  mouseHoveredStack(-1), previouslyHoveredHex(-1), spellDestSelectMode(false), spellToCast(NULL), | 	  mouseHoveredStack(-1), previouslyHoveredHex(-1), spellDestSelectMode(false), spellToCast(NULL), | ||||||
| 	  attackingInfo(NULL), givenCommand(NULL), myTurn(false), resWindow(NULL),  | 	  attackingInfo(NULL), givenCommand(NULL), myTurn(false), resWindow(NULL),  | ||||||
| 	  showStackQueue(false), moveStarted(false) | 	  showStackQueue(false), moveStarted(false), moveSh(-1) | ||||||
| { | { | ||||||
| 	pos = myRect; | 	pos = myRect; | ||||||
| 	strongInterest = true; | 	strongInterest = true; | ||||||
| @@ -1099,6 +1099,7 @@ void CBattleInterface::stackMoved(int number, int destHex, bool endMoving, int d | |||||||
| 	} | 	} | ||||||
| 	if(moveStarted) | 	if(moveStarted) | ||||||
| 	{ | 	{ | ||||||
|  | 		moveSh = CGI->mush->playSound(movedStack->creature->sounds.move, -1); | ||||||
| 		CGI->curh->hide(); | 		CGI->curh->hide(); | ||||||
| 		creAnims[number]->setType(0); | 		creAnims[number]->setType(0); | ||||||
| 		moveStarted = false; | 		moveStarted = false; | ||||||
| @@ -1205,6 +1206,7 @@ void CBattleInterface::stackMoved(int number, int destHex, bool endMoving, int d | |||||||
| 		} | 		} | ||||||
| 		creAnims[number]->setType(2); //resetting to default | 		creAnims[number]->setType(2); //resetting to default | ||||||
| 		CGI->curh->show(); | 		CGI->curh->show(); | ||||||
|  | 		CGI->mush->stopSound(moveSh); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	CStack curs = *LOCPLINT->cb->battleGetStackByID(number); | 	CStack curs = *LOCPLINT->cb->battleGetStackByID(number); | ||||||
| @@ -1274,12 +1276,17 @@ void CBattleInterface::stacksAreAttacked(std::vector<CBattleInterface::SStackAtt | |||||||
| 	int maxLen = 0; | 	int maxLen = 0; | ||||||
| 	for(size_t g=0; g<attackedInfos.size(); ++g) | 	for(size_t g=0; g<attackedInfos.size(); ++g) | ||||||
| 	{ | 	{ | ||||||
|  | 		CStack attacked = *LOCPLINT->cb->battleGetStackByID(attackedInfos[g].ID); | ||||||
|  | 			 | ||||||
| 		if(attackedInfos[g].killed) | 		if(attackedInfos[g].killed) | ||||||
| 		{ | 		{ | ||||||
|  | 			CGI->mush->playSound(attacked.creature->sounds.killed); | ||||||
| 			creAnims[attackedInfos[g].ID]->setType(5); //death | 			creAnims[attackedInfos[g].ID]->setType(5); //death | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
|  | 			// TODO: this block doesn't seems correct if the unit is defending. | ||||||
|  | 			CGI->mush->playSound(attacked.creature->sounds.wince); | ||||||
| 			creAnims[attackedInfos[g].ID]->setType(3); //getting hit | 			creAnims[attackedInfos[g].ID]->setType(3); //getting hit | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @@ -1460,6 +1467,7 @@ void CBattleInterface::stackAttacking(int ID, int dest) | |||||||
| 	attackingInfo->reversing = false; | 	attackingInfo->reversing = false; | ||||||
| 	attackingInfo->posShiftDueToDist = reversedShift; | 	attackingInfo->posShiftDueToDist = reversedShift; | ||||||
| 	attackingInfo->shooting = false; | 	attackingInfo->shooting = false; | ||||||
|  | 	attackingInfo->sh = -1; | ||||||
|  |  | ||||||
| 	switch(BattleInfo::mutualPosition(aStack.position + reversedShift, dest)) //attack direction | 	switch(BattleInfo::mutualPosition(aStack.position + reversedShift, dest)) //attack direction | ||||||
| 	{ | 	{ | ||||||
| @@ -1756,6 +1764,7 @@ void CBattleInterface::stackIsShooting(int ID, int dest) | |||||||
| 	attackingInfo->reversing = false; | 	attackingInfo->reversing = false; | ||||||
| 	attackingInfo->posShiftDueToDist = 0; | 	attackingInfo->posShiftDueToDist = 0; | ||||||
| 	attackingInfo->shooting = true; | 	attackingInfo->shooting = true; | ||||||
|  | 	attackingInfo->sh = -1; | ||||||
| 	if(projectileAngle > straightAngle) //upper shot | 	if(projectileAngle > straightAngle) //upper shot | ||||||
| 		attackingInfo->shootingGroup = 14; | 		attackingInfo->shootingGroup = 14; | ||||||
| 	else if(projectileAngle < -straightAngle) //lower shot | 	else if(projectileAngle < -straightAngle) //lower shot | ||||||
| @@ -2024,10 +2033,20 @@ void CBattleInterface::attackingShowHelper() | |||||||
| 			CStack aStack = *LOCPLINT->cb->battleGetStackByID(attackingInfo->ID); //attacking stack | 			CStack aStack = *LOCPLINT->cb->battleGetStackByID(attackingInfo->ID); //attacking stack | ||||||
| 			if(attackingInfo->shooting) | 			if(attackingInfo->shooting) | ||||||
| 			{ | 			{ | ||||||
|  | 				// TODO: I see that we enter this function twice with | ||||||
|  | 				// attackingInfo->frame==0, so all the inits are done | ||||||
|  | 				// twice. The following is just a workaround until | ||||||
|  | 				// that is fixed. Once done, we can get rid of | ||||||
|  | 				// attackingInfo->sh | ||||||
|  | 				if (attackingInfo->sh == -1) | ||||||
|  | 					attackingInfo->sh = CGI->mush->playSound(aStack.creature->sounds.shoot); | ||||||
| 				creAnims[attackingInfo->ID]->setType(attackingInfo->shootingGroup); | 				creAnims[attackingInfo->ID]->setType(attackingInfo->shootingGroup); | ||||||
| 			} | 			} | ||||||
| 			else | 			else | ||||||
| 			{ | 			{ | ||||||
|  | 				// TODO: see comment above | ||||||
|  | 				if (attackingInfo->sh == -1) | ||||||
|  | 					attackingInfo->sh = CGI->mush->playSound(aStack.creature->sounds.attack); | ||||||
| 				if(aStack.creature->isDoubleWide()) | 				if(aStack.creature->isDoubleWide()) | ||||||
| 				{ | 				{ | ||||||
| 					switch(BattleInfo::mutualPosition(aStack.position+attackingInfo->posShiftDueToDist, attackingInfo->dest)) //attack direction | 					switch(BattleInfo::mutualPosition(aStack.position+attackingInfo->posShiftDueToDist, attackingInfo->dest)) //attack direction | ||||||
|   | |||||||
| @@ -191,6 +191,7 @@ private: | |||||||
| 		int posShiftDueToDist; | 		int posShiftDueToDist; | ||||||
| 		bool shooting; | 		bool shooting; | ||||||
| 		int shootingGroup; //if shooting is true, print this animation group | 		int shootingGroup; //if shooting is true, print this animation group | ||||||
|  | 		int sh;			   // temporary sound handler | ||||||
| 	} * attackingInfo; | 	} * attackingInfo; | ||||||
| 	void attackingShowHelper(); | 	void attackingShowHelper(); | ||||||
| 	void redrawBackgroundWithHexes(int activeStack); | 	void redrawBackgroundWithHexes(int activeStack); | ||||||
| @@ -240,6 +241,7 @@ public: | |||||||
| 	bool showStackQueue; //if true, queue of stacks will be shown | 	bool showStackQueue; //if true, queue of stacks will be shown | ||||||
|  |  | ||||||
| 	bool moveStarted; //if true, the creature that is already moving is going to make its first step | 	bool moveStarted; //if true, the creature that is already moving is going to make its first step | ||||||
|  | 	int moveSh;		  // sound handler used when moving a unit | ||||||
|  |  | ||||||
| 	//button handle funcs: | 	//button handle funcs: | ||||||
| 	void bOptionsf(); | 	void bOptionsf(); | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								CMT.cpp
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								CMT.cpp
									
									
									
									
									
								
							| @@ -130,6 +130,7 @@ int main(int argc, char** argv) | |||||||
| 		tlog0<<"Loading .lod files: "<<tmh.getDif()<<std::endl; | 		tlog0<<"Loading .lod files: "<<tmh.getDif()<<std::endl; | ||||||
| 		initDLL(cgi->bitmaph,::console,logfile); | 		initDLL(cgi->bitmaph,::console,logfile); | ||||||
| 		CGI->setFromLib(); | 		CGI->setFromLib(); | ||||||
|  | 		cgi->mush->initCreaturesSounds(CGI->creh->creatures); | ||||||
| 		tlog0<<"Initializing VCMI_Lib: "<<tmh.getDif()<<std::endl; | 		tlog0<<"Initializing VCMI_Lib: "<<tmh.getDif()<<std::endl; | ||||||
| 		pomtime.getDif(); | 		pomtime.getDif(); | ||||||
| 		cgi->curh = new CCursorHandler; | 		cgi->curh = new CCursorHandler; | ||||||
|   | |||||||
							
								
								
									
										211
									
								
								config/cr_sounds.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										211
									
								
								config/cr_sounds.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,211 @@ | |||||||
|  | # Format is: <creature number> <attack> <defend> <killed> <move> <shoot> <wince> <ext1> <ext2> | ||||||
|  | # All fields are mandatory, except ext1 and ext2. | ||||||
|  | # If a sound doesn't exist or is not applicable, use invalid. | ||||||
|  |  | ||||||
|  | AdvancedLizardman ALIZATTK.wav ALIZDFND.wav ALIZKILL.wav ALIZMOVE.wav ALIZSHOT.wav ALIZWNCE.wav | ||||||
|  | AirElemental AELMATTK.wav AELMDFND.wav AELMKILL.wav AELMMOVE.wav invalid AELMWNCE.wav | ||||||
|  | AmmoCart invalid invalid CARTKILL.wav invalid invalid CARTWNCE.wav | ||||||
|  | AncientBehemoth BMTHATTK.wav BMTHDFND.wav BMTHKILL.wav BMTHMOVE.wav invalid BMTHWNCE.wav | ||||||
|  | Angel ANGLATTK.wav ANGLDFND.wav ANGLKILL.wav ANGLMOVE.wav invalid ANGLWNCE.wav | ||||||
|  | ApprenticeGremlin AGRMATTK.wav AGRMDFND.wav AGRMKILL.wav AGRMMOVE.wav AGRMSHOT.wav AGRMWNCE.wav | ||||||
|  | ArchDevil ADVLATTK.wav ADVLDFND.wav ADVLKILL.wav ADVLMOVE.wav invalid ADVLWNCE.wav ADVLEXT1.wav ADVLEXT2.wav | ||||||
|  | ArchMage AMAGATTK.wav AMAGDFND.wav AMAGKILL.wav AMAGMOVE.wav AMAGSHOT.wav AMAGWNCE.wav | ||||||
|  | Archangel AAGLATTK.wav AAGLDFND.wav AAGLKILL.wav AAGLMOVE.wav invalid AAGLWNCE.wav | ||||||
|  | AzureDragon AZURATTK.wav AZURDFND.wav AZURKILL.wav AZURMOVE.wav invalid AZURWNCE.wav | ||||||
|  | Ballista invalid  invalid BALLKILL.wav invalid BALLSHOT.wav BALLWNCE.wav | ||||||
|  | Basilisk BASLATTK.wav BASLDFND.wav BASLKILL.wav BASLMOVE.wav invalid BASLWNCE.wav | ||||||
|  | BattleDwarf BDRFATTK.wav BDRFDFND.wav BDRFKILL.wav BDRFMOVE.wav invalid BDRFWNCE.wav | ||||||
|  | Beholder BHDRATTK.wav BHDRDFND.wav BHDRKILL.wav BHDRMOVE.wav BHDRSHOT.wav BHDRWNCE.wav BHDRDETH.wav | ||||||
|  | BlackDragon BKDRATTK.wav BKDRDFND.wav BKDRKILL.wav BKDRMOVE.wav invalid BKDRWNCE.wav | ||||||
|  | BlackKnight BKNTATTK.wav BKNTDFND.wav BKNTKILL.wav BKNTMOVE.wav invalid BKNTWNCE.wav | ||||||
|  | BlackLord BLRDATTK.wav BLRDDFND.wav BLRDKILL.wav BLRDMOVE.wav invalid BLRDWNCE.wav | ||||||
|  | Boar BOARATTK.wav BOARDFND.wav BOARKILL.wav BOARMOVE.wav invalid BOARWNCE.wav | ||||||
|  | BoneDragon BODRATTK.wav BODRDFND.wav BODRKILL.wav BODRMOVE.wav invalid BODRWNCE.wav | ||||||
|  | BriarTreefolk BTREATTK.wav BTREDFND.wav BTREKILL.wav BTREMOVE.wav invalid BTREWNCE.wav | ||||||
|  | BronzeGorgon BGORATTK.wav BGORDFND.wav BGORKILL.wav BGORMOVE.wav invalid BGORWNCE.wav | ||||||
|  | Caliph CALFATTK.wav CALFDFND.wav CALFKILL.wav CALFMOVE.wav CALFSHOT.wav CALFWNCE.wav | ||||||
|  | Catapult invalid invalid CATAKILL.wav invalid CATASHOT.wav CATAWNCE.wav | ||||||
|  | Cavalier CAVAATTK.wav CAVADFND.wav CAVAKILL.wav CAVAMOVE.wav invalid CAVAWNCE.wav | ||||||
|  | Centaur CNTRATTK.wav CNTRDFND.wav CNTRKILL.wav CNTRMOVE.wav CNTRSHOT.wav CNTRWNCE.wav | ||||||
|  | Cerberus CERBATTK.wav CERBDFND.wav CERBKILL.wav CERBMOVE.wav invalid CERBWNCE.wav | ||||||
|  | Champion CHMPATTK.wav CHMPDFND.wav CHMPKILL.wav CHMPMOVE.wav invalid CHMPWNCE.wav | ||||||
|  | ChaosHydra CHYDATTK.wav CHYDDFND.wav CHYDKILL.wav CHYDMOVE.wav invalid CHYDWNCE.wav | ||||||
|  | CopperGorgon CGORATTK.wav CGORDFND.wav CGORKILL.wav CGORMOVE.wav invalid CGORWNCE.wav | ||||||
|  | Crusader CRUSATTK.wav CRUSDFND.wav CRUSKILL.wav CRUSMOVE.wav invalid CRUSWNCE.wav | ||||||
|  | CrystalDragon CRYSATTK.wav CRYSDFND.wav CRYSKILL.wav CRYSMOVE.wav invalid CRYSWNCE.wav | ||||||
|  | Cyclops CCYCATTK.wav CCYCDFND.wav CCYCKILL.wav CCYCMOVE.wav CCYCSHOT.wav CCYCWNCE.wav | ||||||
|  | CyclopsLord CYCLATTK.wav CYCLDFND.wav CYCLKILL.wav CYCLMOVE.wav CYCLSHOT.wav CYCLWNCE.wav | ||||||
|  | Devil DEVLATTK.wav DEVLDFND.wav DEVLKILL.wav DEVLMOVE.wav invalid DEVLWNCE.wav DEVLEXT1.wav DEVLEXT2.wav | ||||||
|  | DiamondGolem DGLMATTK.wav DGLMDFND.wav DGLMKILL.wav DGLMMOVE.wav invalid DGLMWNCE.wav | ||||||
|  | DragonFly DFLYATTK.wav DFLYDFND.wav DFLYKILL.wav DFLYMOVE.wav invalid DFLYWNCE.wav | ||||||
|  | Dual-HornedDemon DHDMATTK.wav DHDMDFND.wav DHDMKILL.wav DHDMMOVE.wav invalid DHDMWNCE.wav | ||||||
|  | Dwarf DWRFATTK.wav DWRFDFND.wav DWRFKILL.wav DWRFMOVE.wav invalid DWRFWNCE.wav | ||||||
|  | EarthElemental EELMATTK.wav EELMDFND.wav EELMKILL.wav EELMMOVE.wav invalid EELMWNCE.wav | ||||||
|  | Efreet EFRTATTK.wav EFRTDFND.wav EFRTKILL.wav EFRTMOVE.wav invalid EFRTWNCE.wav | ||||||
|  | EfreetSultan ESULATTK.wav ESULDFND.wav ESULKILL.wav ESULMOVE.wav ESULSHOT.wav ESULWNCE.wav | ||||||
|  | ElectricityElemental ENERATTK.wav ENERDFND.wav ENERKILL.wav ENERMOVE.wav invalid ENERWNCE.wav | ||||||
|  | EliteCentaur ECNTATTK.wav ECNTDFND.wav ECNTKILL.wav ECNTMOVE.wav invalid ECNTWNCE.wav | ||||||
|  | Enchanter ENCHATTK.wav ENCHDFND.wav ENCHKILL.wav ENCHMOVE.wav ENCHSHOT.wav ENCHWNCE.wav | ||||||
|  | EvilEye EVLIATTK.wav EVLIDFND.wav EVLIKILL.wav EVLIMOVE.wav EVLISHOT.wav EVLIWNCE.wav EVLIDETH.wav | ||||||
|  | FairieDragon FAERATTK.wav FAERDFND.wav FAERKILL.wav FAERMOVE.wav FAERSHOT.wav FAERWNCE.wav | ||||||
|  | Familiar FMLRATTK.wav FMLRDFND.wav FMLRKILL.wav FMLRMOVE.wav invalid FMLRWNCE.wav | ||||||
|  | FireDragonFly FDFLATTK.wav FDFLDFND.wav FDFLKILL.wav FDFLMOVE.wav FDFLSHOT.wav FDFLWNCE.wav | ||||||
|  | FireElemental FELMATTK.wav FELMDFND.wav FELMKILL.wav FELMMOVE.wav invalid FELMWNCE.wav | ||||||
|  | Firebird FIRBATTK.wav FIRBDFND.wav FIRBKILL.wav FIRBMOVE.wav invalid FIRBWNCE.wav | ||||||
|  | FirstAidTent invalid invalid FAIDKILL.wav invalid invalid FAIDWNCE.wav | ||||||
|  | Genie GENIATTK.wav GENIDFND.wav GENIKILL.wav GENIMOVE.wav invalid GENIWNCE.wav | ||||||
|  | GhostDragon GHDRATTK.wav GHDRDFND.wav GHDRKILL.wav GHDRMOVE.wav invalid GHDRWNCE.wav | ||||||
|  | Gnoll GNOLATTK.wav GNOLDFND.wav GNOLKILL.wav GNOLMOVE.wav invalid GNOLWNCE.wav | ||||||
|  | GnollMarauder GNLMATTK.wav GNLMDFND.wav GNLMKILL.wav GNLMMOVE.wav invalid GNLMWNCE.wav | ||||||
|  | Goblin GBLNATTK.wav GBLNDFND.wav GBLNKILL.wav GBLNMOVE.wav invalid GBLNWNCE.wav | ||||||
|  | GoblinWolfRider GWRDATTK.wav GWRDDFND.wav GWRDKILL.wav GWRDMOVE.wav invalid GWRDWNCE.wav | ||||||
|  | Gog GOGGATTK.wav GOGGDFND.wav GOGGKILL.wav GOGGMOVE.wav GOGGSHOT.wav GOGGWNCE.wav GOGFLAME.wav | ||||||
|  | GoldDragon GODRATTK.wav GODRDFND.wav GODRKILL.wav GODRMOVE.wav invalid GODRWNCE.wav | ||||||
|  | GoldGolem GGLMATTK.wav GGLMDFND.wav GGLMKILL.wav GGLMMOVE.wav invalid GGLMWNCE.wav | ||||||
|  | GrandElf GELFATTK.wav GELFDFND.wav GELFKILL.wav GELFMOVE.wav GELFSHOT.wav GELFWNCE.wav | ||||||
|  | GreaterBasilisk GBASATTK.wav GBASDFND.wav GBASKILL.wav GBASMOVE.wav invalid GBASWNCE.wav | ||||||
|  | GreaterTitan GTITATTK.wav GTITDFND.wav GTITKILL.wav GTITMOVE.wav GTITSHOT.wav GTITWNCE.wav | ||||||
|  | GreenDragon GRDRATTK.wav GRDRDFND.wav GRDRKILL.wav GRDRMOVE.wav invalid GRDRWNCE.wav | ||||||
|  | Griffin GRIFATTK.wav GRIFDFND.wav GRIFKILL.wav GRIFMOVE.wav invalid GRIFWNCE.wav | ||||||
|  | Halberdier HALBATTK.wav HALBDFND.wav HALBKILL.wav HALBMOVE.wav invalid HALBWNCE.wav | ||||||
|  | Halfling HALFATTK.wav HALFDFND.wav HALFKILL.wav HALFMOVE.wav HALFSHOT.wav HALFWNCE.wav | ||||||
|  | Harpy HARPATTK.wav HARPDFND.wav HARPKILL.wav HARPMOVE.wav silence HARPWNCE.wav | ||||||
|  | HarpyHag HHAGATTK.wav HHAGDFND.wav HHAGKILL.wav HHAGMOVE.wav HHAGSHOT.wav HHAGWNCE.wav | ||||||
|  | HeavyCrossbowman HCRSATTK.wav HCRSDFND.wav HCRSKILL.wav HCRSMOVE.wav HCRSSHOT.wav HCRSWNCE.wav | ||||||
|  | HellHound HHNDATTK.wav HHNDDFND.wav HHNDKILL.wav HHNDMOVE.wav invalid HHNDWNCE.wav | ||||||
|  | Hobgoblin HGOBATTK.wav HGOBDFND.wav HGOBKILL.wav HGOBMOVE.wav invalid HGOBWNCE.wav | ||||||
|  | HobgoblinWolfRider HGWRATTK.wav HGWRDFND.wav HGWRKILL.wav HGWRMOVE.wav invalid HGWRWNCE.wav | ||||||
|  | Hydra HYDRATTK.wav HYDRDFND.wav HYDRKILL.wav HYDRMOVE.wav invalid HYDRWNCE.wav | ||||||
|  | IceElemental ICELATTK.wav ICELDFND.wav ICELKILL.wav ICELMOVE.wav ICELSHOT.wav ICELWNCE.wav | ||||||
|  | Imp IMPPATTK.wav IMPPDFND.wav IMPPKILL.wav IMPPMOVE.wav invalid IMPPWNCE.wav | ||||||
|  | InfernalTroglodyte ITRGATTK.wav ITRGDFND.wav ITRGKILL.wav ITRGMOVE.wav invalid ITRGWNCE.wav | ||||||
|  | IronGolem IGLMATTK.wav IGLMDFND.wav IGLMKILL.wav IGLMMOVE.wav invalid IGLMWNCE.wav | ||||||
|  | LesserTitan LTITATTK.wav LTITDFND.wav LTITKILL.wav LTITMOVE.wav invalid LTITWNCE.wav | ||||||
|  | Lich LICHATTK.wav LICHDFND.wav LICHKILL.wav LICHMOVE.wav LICHSHOT.wav LICHWNCE.wav LICHATK2.wav | ||||||
|  | LightCrossbowman LCRSATTK.wav LCRSDFND.wav LCRSKILL.wav LCRSMOVE.wav LCRSSHOT.wav LCRSWNCE.wav | ||||||
|  | Mage MAGEATTK.wav MAGEDFND.wav MAGEKILL.wav MAGEMOVE.wav MAGESHOT.wav MAGEWNCE.wav | ||||||
|  | MagicElemental MGELATTK.wav MGELDFND.wav MGELKILL.wav MGELMOVE.wav invalid MGELWNCE.wav | ||||||
|  | Magog MGOGATTK.wav MGOGDFND.wav MGOGKILL.wav MGOGMOVE.wav MGOGSHOT.wav MGOGWNCE.wav GOGFLAME.wav | ||||||
|  | Manticore MANTATTK.wav MANTDFND.wav MANTKILL.wav MANTMOVE.wav MANTSHOT.wav MANTWNCE.wav | ||||||
|  | MasterGremlin MGRMATTK.wav MGRMDFND.wav MGRMKILL.wav MGRMMOVE.wav MGRMSHOT.wav MGRMWNCE.wav | ||||||
|  | Medusa MEDUATTK.wav MEDUDFND.wav MEDUKILL.wav MEDUMOVE.wav MEDUSHOT.wav MEDUWNCE.wav | ||||||
|  | MedusaQueen MEDQATTK.wav MEDQDFND.wav MEDQKILL.wav MEDQMOVE.wav MEDQSHOT.wav MEDQWNCE.wav | ||||||
|  | Minotaur MINOATTK.wav MINODFND.wav MINOKILL.wav MINOMOVE.wav invalid MINOWNCE.wav | ||||||
|  | MinotaurKing MINKATTK.wav MINKDFND.wav MINKKILL.wav MINKMOVE.wav MINKSHOT.wav MINKWNCE.wav | ||||||
|  | Monk MONKATTK.wav MONKDFND.wav MONKKILL.wav MONKMOVE.wav MONKSHOT.wav MONKWNCE.wav | ||||||
|  | Mummy MUMYATTK.wav MUMYDFND.wav MUMYKILL.wav MUMYMOVE.wav invalid MUMYWNCE.wav | ||||||
|  | NagaGuardian NGRDATTK.wav NGRDDFND.wav NGRDKILL.wav NGRDMOVE.wav invalid NGRDWNCE.wav | ||||||
|  | NagaSentinel NSENATTK.wav NSENDFND.wav NSENKILL.wav NSENMOVE.wav invalid NSENWNCE.wav | ||||||
|  | Nosferatu NOSFATTK.wav NOSFDFND.wav NOSFEXT1.wav NOSFEXT2.wav NOSFKILL.wav NOSFMOVE.wav NOSFSHOT.wav NOSFWNCE.wav | ||||||
|  | ObsidianGargoyle OGRGATTK.wav OGRGDFND.wav OGRGKILL.wav OGRGMOVE.wav invalid OGRGWNCE.wav | ||||||
|  | Ogre OGREATTK.wav OGREDFND.wav OGREKILL.wav OGREMOVE.wav invalid OGREWNCE.wav | ||||||
|  | OgreMage OGRMATTK.wav OGRMDFND.wav OGRMKILL.wav OGRMMOVE.wav OGRMSHOT.wav OGRMWNCE.wav | ||||||
|  | Orc OORCATTK.wav OORCDFND.wav OORCKILL.wav OORCMOVE.wav OORCSHOT.wav OORCWNCE.wav | ||||||
|  | OrcChieftain ORCCATTK.wav ORCCDFND.wav ORCCKILL.wav ORCCMOVE.wav ORCCSHOT.wav ORCCWNCE.wav | ||||||
|  | Peasant PSNTATTK.wav PSNTDFND.wav PSNTKILL.wav PSNTMOVE.wav invalid PSNTWNCE.wav | ||||||
|  | Pegasus PEGAATTK.wav PEGADFND.wav PEGAKILL.wav PEGAMOVE.wav invalid PEGAWNCE.wav | ||||||
|  | Pheonix PHOEATTK.wav PHOEDFND.wav PHOEKILL.wav PHOEMOVE.wav invalid PHOEWNCE.wav | ||||||
|  | Pikeman PIKEATTK.wav PIKEDFND.wav PIKEKILL.wav PIKEMOVE.wav invalid PIKEWNCE.wav | ||||||
|  | PitFiend PFNDATTK.wav PFNDDFND.wav PFNDKILL.wav PFNDMOVE.wav invalid PFNDWNCE.wav | ||||||
|  | PitFoe PFOEATTK.wav PFOEDFND.wav PFOEKILL.wav PFOEMOVE.wav invalid PFOEWNCE.wav | ||||||
|  | Pixie PIXIATTK.wav PIXIDFND.wav PIXIKILL.wav PIXIMOVE.wav invalid PIXIWNCE.wav | ||||||
|  | PowerLich PLCHATTK.wav PLCHDFND.wav PLCHKILL.wav PLCHMOVE.wav PLCHSHOT.wav PLCHWNCE.wav | ||||||
|  | PrimitiveLizardman PLIZATTK.wav PLIZDFND.wav PLIZKILL.wav PLIZMOVE.wav PLIZSHOT.wav PLIZWNCE.wav | ||||||
|  | PsiElemental PSYCATTK.wav PSYCDFND.wav PSYCKILL.wav PSYCMOVE.wav invalid PSYCWNCE.wav | ||||||
|  | RedDragon RDDRATTK.wav RDDRDFND.wav RDDRKILL.wav RDDRMOVE.wav invalid RDDRWNCE.wav | ||||||
|  | Roc ROCCATTK.wav ROCCDFND.wav ROCCKILL.wav ROCCMOVE.wav invalid ROCCWNCE.wav | ||||||
|  | Rogue ROGUATTK.wav ROGUDFND.wav ROGUKILL.wav ROGUMOVE.wav invalid ROGUWNCE.wav | ||||||
|  | RoyalGriffin RGRFATTK.wav RGRFDFND.wav RGRFKILL.wav RGRFMOVE.wav invalid RGRFWNCE.wav | ||||||
|  | RustDragon RUSTATTK.wav RUSTDFND.wav RUSTKILL.wav RUSTMOVE.wav invalid RUSTWNCE.wav | ||||||
|  | Scorpicore SCRPATTK.wav SCRPDFND.wav SCRPKILL.wav SCRPMOVE.wav SCRPSHOT.wav SCRPWNCE.wav | ||||||
|  | SilverPegasus APEGATTK.wav APEGDFND.wav APEGKILL.wav APEGMOVE.wav invalid APEGWNCE.wav | ||||||
|  | Single-HornedDemon SHDMATTK.wav SHDMDFND.wav SHDMKILL.wav SHDMMOVE.wav invalid SHDMWNCE.wav | ||||||
|  | Skeleton SKELATTK.wav SKELDFND.wav SKELKILL.wav SKELMOVE.wav invalid SKELWNCE.wav | ||||||
|  | SkeletonWarrior SKLWATTK.wav SKLWDFND.wav SKLWKILL.wav SKLWMOVE.wav invalid SKLWWNCE.wav | ||||||
|  | Sprite SPRTATTK.wav SPRTDFND.wav SPRTKILL.wav SPRTMOVE.wav invalid SPRTWNCE.wav | ||||||
|  | StoneGargoyle SGRGATTK.wav SGRGDFND.wav SGRGKILL.wav SGRGMOVE.wav invalid SGRGWNCE.wav | ||||||
|  | StoneGolem SGLMATTK.wav SGLMDFND.wav SGLMKILL.wav SGLMMOVE.wav invalid SGLMWNCE.wav | ||||||
|  | StormElemental STORATTK.wav STORDFND.wav STORKILL.wav STORMOVE.wav STORSHOT.wav STORWNCE.wav | ||||||
|  | Swordsman SWRDATTK.wav SWRDDFND.wav SWRDKILL.wav SWRDMOVE.wav invalid SWRDWNCE.wav | ||||||
|  | Thunderbird TBRDATTK.wav TBRDDFND.wav TBRDKILL.wav TBRDMOVE.wav invalid TBRDWNCE.wav | ||||||
|  | Treefolk TREEATTK.wav TREEDFND.wav TREEKILL.wav TREEMOVE.wav invalid TREEWNCE.wav | ||||||
|  | Troglodyte TROGATTK.wav TROGDFND.wav TROGKILL.wav TROGMOVE.wav invalid TROGWNCE.wav | ||||||
|  | Unicorn UNICATTK.wav UNICDFND.wav UNICKILL.wav UNICMOVE.wav invalid UNICWNCE.wav | ||||||
|  | Vampire VAMPATTK.wav VAMPDFND.wav VAMPKILL.wav VAMPMOVE.wav invalid VAMPWNCE.wav VAMPEXT1.wav VAMPEXT2.wav | ||||||
|  | WarUnicorn WUNCATTK.wav WUNCDFND.wav WUNCKILL.wav WUNCMOVE.wav WUNCSHOT.wav WUNCWNCE.wav | ||||||
|  | WaterElemental WELMATTK.wav WELMDFND.wav WELMKILL.wav WELMMOVE.wav invalid WELMWNCE.wav | ||||||
|  | Wight WGHTATTK.wav WGHTDFND.wav WGHTKILL.wav WGHTMOVE.wav invalid WGHTWNCE.wav | ||||||
|  | WoodElf WELFATTK.wav WELFDFND.wav WELFKILL.wav WELFMOVE.wav WELFSHOT.wav WELFWNCE.wav | ||||||
|  | Wraith WRTHATTK.wav WRTHDFND.wav WRTHKILL.wav WRTHMOVE.wav invalid WRTHWNCE.wav | ||||||
|  | Wyvern WYVNATTK.wav WYVNDFND.wav WYVNKILL.wav WYVNMOVE.wav invalid WYVNWNCE.wav | ||||||
|  | WyvernMonarch WYVMATTK.wav WYVMDFND.wav WYVMKILL.wav WYVMMOVE.wav invalid WYVMWNCE.wav | ||||||
|  | YoungBehemoth YBMHATTK.wav YBMHDFND.wav YBMHKILL.wav YBMHMOVE.wav invalid YBMHWNCE.wav | ||||||
|  | Zealot ZELTATTK.wav ZELTDFND.wav ZELTKILL.wav ZELTMOVE.wav ZELTSHOT.wav ZELTWNCE.wav | ||||||
|  | Zombie ZOMBATTK.wav ZOMBDFND.wav ZOMBKILL.wav ZOMBMOVE.wav invalid ZOMBWNCE.wav | ||||||
|  | ZombieLord ZMBLATTK.wav ZMBLDFND.wav ZMBLKILL.wav ZMBLMOVE.wav invalid ZMBLWNCE.wav | ||||||
|  |  | ||||||
|  | # todo - troll ? | ||||||
|  | # TRLLATTK.wav TRLLDFND.wav TRLLKILL.wav TRLLMOVE.wav invalid TRLLWNCE.wav | ||||||
|  |  | ||||||
|  | # todo - nomad ? | ||||||
|  | # NMADATTK.wav NMADDFND.wav NMADKILL.wav NMADMOVE.wav invalid NMADWNCE.wav | ||||||
|  |  | ||||||
|  | # todo - magma ? | ||||||
|  | # MAGMATTK.wav MAGMDFND.wav MAGMKILL.wav MAGMMOVE.wav invalid MAGMWNCE.wav | ||||||
|  |  | ||||||
|  |  | ||||||
|  | # Missing entries | ||||||
|  | # 125 StoneElemental | ||||||
|  | # 128 FireElemental | ||||||
|  | # 129 FireElemental | ||||||
|  | # 137 Sharpshooter | ||||||
|  | # 142 warrior | ||||||
|  | # 144 OgreShaman | ||||||
|  | # 149 ArrowTower | ||||||
|  | # 150 SupremeArchangel | ||||||
|  | # 151 DiamondDragon | ||||||
|  | # 152 LordofThunder | ||||||
|  | # 153 HellBaron | ||||||
|  | # 154 BloodDragon | ||||||
|  | # 155 DarknessDragon | ||||||
|  | # 156 GhostBehemoth | ||||||
|  | # 157 HellHydra | ||||||
|  | # 158 SacredPhoenix | ||||||
|  | # 159 Ghost | ||||||
|  | # 160 God1War | ||||||
|  | # 161 God2Peace | ||||||
|  | # 162 God3Mana | ||||||
|  | # 163 God4Lore | ||||||
|  | # 164 MinotaurKing | ||||||
|  | # 165 MineralElemental | ||||||
|  | # 166 ElectricityElemental | ||||||
|  | # 167 AncientBasilisk | ||||||
|  | # 168 Gorynych | ||||||
|  | # 169 WarZealot | ||||||
|  | # 170 Myriad | ||||||
|  | # 171 MedusaMatriarch | ||||||
|  | # 172 Nightmare | ||||||
|  | # 173 SantaGremlin | ||||||
|  | # 174 Paladin1 | ||||||
|  | # 175 Hierophant1 | ||||||
|  | # 176 TempleGuardian1 | ||||||
|  | # 177 Succubus1 | ||||||
|  | # 178 SoulEater1 | ||||||
|  | # 179 Brute1 | ||||||
|  | # 180 OgreLeader1 | ||||||
|  | # 181 Shaman1 | ||||||
|  | # 182 AstralSpirit1 | ||||||
|  | # 183 Paladin2 | ||||||
|  | # 184 Hierophant2 | ||||||
|  | # 185 TempleGuardian2 | ||||||
|  | # 186 Succubus2 | ||||||
|  | # 187 SoulEater2 | ||||||
|  | # 188 Brute2 | ||||||
|  | # 189 OgreLeader2 | ||||||
|  | # 190 Shaman2 | ||||||
|  | # 191 AstralSpirit2 | ||||||
|  | # 192 SylvanCentaur | ||||||
|  | # 193 Sorceress | ||||||
|  | # 194 Werewolf | ||||||
|  | # 195 HellSteed | ||||||
|  | # 196 Dracolich | ||||||
| @@ -99,6 +99,15 @@ void CCreatureHandler::loadCreatures() | |||||||
| 		CCreature ncre; | 		CCreature ncre; | ||||||
| 		ncre.cost.resize(RESOURCE_QUANTITY); | 		ncre.cost.resize(RESOURCE_QUANTITY); | ||||||
| 		ncre.level=0; | 		ncre.level=0; | ||||||
|  | 		ncre.sounds.attack = soundBase::invalid; | ||||||
|  | 		ncre.sounds.defend = soundBase::invalid; | ||||||
|  | 		ncre.sounds.killed = soundBase::invalid; | ||||||
|  | 		ncre.sounds.move = soundBase::invalid; | ||||||
|  | 		ncre.sounds.shoot = soundBase::invalid; | ||||||
|  | 		ncre.sounds.wince = soundBase::invalid; | ||||||
|  | 		ncre.sounds.ext1 = soundBase::invalid; | ||||||
|  | 		ncre.sounds.ext2 = soundBase::invalid; | ||||||
|  |  | ||||||
| 		int befi=i; | 		int befi=i; | ||||||
| 		for(i; i<andame; ++i) | 		for(i; i<andame; ++i) | ||||||
| 		{ | 		{ | ||||||
|   | |||||||
| @@ -6,6 +6,8 @@ | |||||||
| #include <map> | #include <map> | ||||||
| #include <set> | #include <set> | ||||||
|  |  | ||||||
|  | #include "CSoundBase.h" | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * CCreatureHandler.h, part of VCMI engine |  * CCreatureHandler.h, part of VCMI engine | ||||||
|  * |  * | ||||||
| @@ -42,6 +44,18 @@ public: | |||||||
| 	int troopCountLocationOffset, attackClimaxFrame; | 	int troopCountLocationOffset, attackClimaxFrame; | ||||||
| 	///end of anim info | 	///end of anim info | ||||||
|  |  | ||||||
|  | 	// Sound infos | ||||||
|  | 	struct { | ||||||
|  | 		soundBase::soundNames attack; | ||||||
|  | 		soundBase::soundNames defend; | ||||||
|  | 		soundBase::soundNames killed; // was killed died | ||||||
|  | 		soundBase::soundNames move; | ||||||
|  | 		soundBase::soundNames shoot; // range attack | ||||||
|  | 		soundBase::soundNames wince; // attacked but did not die | ||||||
|  | 		soundBase::soundNames ext1;	 // creature specific extension | ||||||
|  | 		soundBase::soundNames ext2;	 // creature specific extension | ||||||
|  | 	} sounds; | ||||||
|  |  | ||||||
| 	bool isDoubleWide() const; //returns true if unit is double wide on battlefield | 	bool isDoubleWide() const; //returns true if unit is double wide on battlefield | ||||||
| 	bool isFlying() const; //returns true if it is a flying unit | 	bool isFlying() const; //returns true if it is a flying unit | ||||||
| 	bool isShooting() const; //returns true if unit can shoot | 	bool isShooting() const; //returns true if unit can shoot | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| #include "../stdafx.h" | #include "../stdafx.h" | ||||||
|  |  | ||||||
|  | #include <sstream> | ||||||
| #include <boost/assign/std/vector.hpp>  | #include <boost/assign/std/vector.hpp>  | ||||||
| #include <boost/assign/list_of.hpp> | #include <boost/assign/list_of.hpp> | ||||||
|  |  | ||||||
| @@ -7,6 +8,8 @@ | |||||||
|  |  | ||||||
| #include "CSndHandler.h" | #include "CSndHandler.h" | ||||||
| #include "CMusicHandler.h" | #include "CMusicHandler.h" | ||||||
|  | #include "CCreatureHandler.h" | ||||||
|  | #include "../CGameInfo.h" | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * CMusicHandler.cpp, part of VCMI engine |  * CMusicHandler.cpp, part of VCMI engine | ||||||
| @@ -46,6 +49,11 @@ void CMusicHandler::initMusics() | |||||||
| 		soundBase::horseSubterranean, soundBase::horseLava, | 		soundBase::horseSubterranean, soundBase::horseLava, | ||||||
| 		soundBase::horseWater, soundBase::horseRock; | 		soundBase::horseWater, soundBase::horseRock; | ||||||
|  |  | ||||||
|  | 	// Create reverse map. It's used during game init to map names to internal IDs | ||||||
|  | 	std::map<soundBase::soundNames, cachedSounds>::iterator it; | ||||||
|  | 	for ( it=sounds.begin() ; it != sounds.end(); it++ ) | ||||||
|  | 		reverse_sounds[(*it).second.filename] = (*it).first; | ||||||
|  |  | ||||||
| 	//AITheme0 = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "AITheme0.mp3"); | 	//AITheme0 = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "AITheme0.mp3"); | ||||||
| 	//AITheme1 = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "AITHEME1.mp3"); | 	//AITheme1 = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "AITHEME1.mp3"); | ||||||
| 	//AITheme2 = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "AITHEME2.mp3"); | 	//AITheme2 = Mix_LoadMUS(DATA_DIR "MP3" PATHSEPARATOR "AITHEME2.mp3"); | ||||||
| @@ -113,7 +121,71 @@ Mix_Chunk *CMusicHandler::GetSoundChunk(std::string srcName) | |||||||
|  |  | ||||||
| 	return chunk; | 	return chunk; | ||||||
| } | } | ||||||
|    |  | ||||||
|  | soundBase::soundNames CMusicHandler::getSoundID(std::string &fileName) | ||||||
|  | { | ||||||
|  | 	std::map<std::string, soundBase::soundNames>::iterator it; | ||||||
|  |  | ||||||
|  | 	it = reverse_sounds.find(fileName); | ||||||
|  | 	if (it == reverse_sounds.end()) | ||||||
|  | 		return soundBase::invalid; | ||||||
|  | 	else | ||||||
|  | 		return it->second; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void CMusicHandler::initCreaturesSounds(std::vector<CCreature> &creatures) | ||||||
|  | { | ||||||
|  | 	tlog5 << "\t\tReading config/cr_sounds.txt" << std::endl; | ||||||
|  | 	std::ifstream ifs("config/cr_sounds.txt"); | ||||||
|  | 	std::string line; | ||||||
|  |  | ||||||
|  | 	while(getline(ifs, line)) | ||||||
|  | 	{ | ||||||
|  | 		std::string cname="", attack="", defend="", killed="", move="",  | ||||||
|  | 			shoot="", wince="", ext1="", ext2=""; | ||||||
|  | 		std::stringstream str(line); | ||||||
|  |  | ||||||
|  | 		str >> cname >> attack >> defend >> killed >> move >> shoot >> wince >> ext1 >> ext2; | ||||||
|  |  | ||||||
|  | 		if (cname[0] == '#') | ||||||
|  | 			// That's a comment. Discard. | ||||||
|  | 			continue; | ||||||
|  |  | ||||||
|  | 		if (str.good() || (str.eof() && wince != "")) | ||||||
|  | 		{ | ||||||
|  | 			int id = CGI->creh->nameToID[cname]; | ||||||
|  | 			CCreature &c = CGI->creh->creatures[id]; | ||||||
|  |  | ||||||
|  | 			if (c.sounds.killed != soundBase::invalid) | ||||||
|  | 				tlog1 << "Creature << " << cname << " already has sounds" << std::endl; | ||||||
|  | 			 | ||||||
|  | 			c.sounds.attack = getSoundID(attack); | ||||||
|  | 			c.sounds.defend = getSoundID(defend); | ||||||
|  | 			c.sounds.killed = getSoundID(killed); | ||||||
|  | 			c.sounds.move = getSoundID(move); | ||||||
|  | 			c.sounds.shoot = getSoundID(shoot); | ||||||
|  | 			c.sounds.wince = getSoundID(wince); | ||||||
|  | 			c.sounds.ext1 = getSoundID(ext1); | ||||||
|  | 			c.sounds.ext2 = getSoundID(ext2); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	ifs.close(); | ||||||
|  | 	ifs.clear(); | ||||||
|  |  | ||||||
|  | 	// Find creatures without sounds | ||||||
|  | 	for(unsigned int i=0;i<CGI->creh->creatures.size();i++) | ||||||
|  | 	{ | ||||||
|  | 		// Note: this will exclude war machines, but it's better | ||||||
|  | 		// than nothing. | ||||||
|  | 		if (vstd::contains(CGI->creh->notUsedMonsters, i)) | ||||||
|  | 			continue; | ||||||
|  |  | ||||||
|  | 		CCreature &c = CGI->creh->creatures[i]; | ||||||
|  | 		if (c.sounds.killed == soundBase::invalid) | ||||||
|  | 			tlog1 << "creature " << c.idNumber << " doesn't have sounds" << std::endl; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| // Plays a sound, and return its channel so we can fade it out later | // Plays a sound, and return its channel so we can fade it out later | ||||||
| int CMusicHandler::playSound(soundBase::soundNames soundID, int repeats) | int CMusicHandler::playSound(soundBase::soundNames soundID, int repeats) | ||||||
| { | { | ||||||
|   | |||||||
| @@ -20,6 +20,7 @@ class CMusicHandler | |||||||
| { | { | ||||||
| private: | private: | ||||||
| 	CSndHandler *sndh; | 	CSndHandler *sndh; | ||||||
|  | 	soundBase::soundNames getSoundID(std::string &fileName); | ||||||
|  |  | ||||||
| 	class cachedSounds { | 	class cachedSounds { | ||||||
| 	public: | 	public: | ||||||
| @@ -33,12 +34,15 @@ private: | |||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	std::map<soundBase::soundNames, cachedSounds> sounds; | 	std::map<soundBase::soundNames, cachedSounds> sounds; | ||||||
|  | 	std::map<std::string, soundBase::soundNames> reverse_sounds; | ||||||
|  |  | ||||||
| 	Mix_Chunk *GetSoundChunk(std::string srcName); | 	Mix_Chunk *GetSoundChunk(std::string srcName); | ||||||
|  |  | ||||||
| public: | public: | ||||||
| 	CMusicHandler(): sndh(NULL) {}; | 	CMusicHandler(): sndh(NULL) {}; | ||||||
|  |  | ||||||
| 	void initMusics(); | 	void initMusics(); | ||||||
|  | 	void initCreaturesSounds(std::vector<CCreature> &creatures); | ||||||
|  |  | ||||||
| 	// Sounds | 	// Sounds | ||||||
| 	int playSound(soundBase::soundNames soundID, int repeats=0); | 	int playSound(soundBase::soundNames soundID, int repeats=0); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user