Przeglądaj źródła

swapping spells

Laserlicht 1 rok temu
rodzic
commit
5b2aa4dc71

+ 2 - 2
CCallback.cpp

@@ -249,9 +249,9 @@ int CBattleCallback::sendRequest(const CPackForServer * request)
 	return requestID;
 }
 
-void CCallback::spellResearch( const CGTownInstance *town )
+void CCallback::spellResearch( const CGTownInstance *town, SpellID spellAtSlot )
 {
-	SpellResearch pack(town->id);
+	SpellResearch pack(town->id, spellAtSlot);
 	sendRequest(&pack);
 }
 

+ 2 - 2
CCallback.h

@@ -78,7 +78,7 @@ public:
 	virtual bool visitTownBuilding(const CGTownInstance *town, BuildingID buildingID)=0;
 	virtual void recruitCreatures(const CGDwelling *obj, const CArmedInstance * dst, CreatureID ID, ui32 amount, si32 level=-1)=0;
 	virtual bool upgradeCreature(const CArmedInstance *obj, SlotID stackPos, CreatureID newID=CreatureID::NONE)=0; //if newID==-1 then best possible upgrade will be made
-	virtual void spellResearch(const CGTownInstance *town)=0;
+	virtual void spellResearch(const CGTownInstance *town, SpellID spellAtSlot)=0;
 	virtual void swapGarrisonHero(const CGTownInstance *town)=0;
 
 	virtual void trade(const ObjectInstanceID marketId, EMarketMode mode, TradeItemSell id1, TradeItemBuy id2, ui32 val1, const CGHeroInstance * hero)=0; //mode==0: sell val1 units of id1 resource for id2 resiurce
@@ -188,7 +188,7 @@ public:
 	bool dismissCreature(const CArmedInstance *obj, SlotID stackPos) override;
 	bool upgradeCreature(const CArmedInstance *obj, SlotID stackPos, CreatureID newID=CreatureID::NONE) override;
 	void endTurn() override;
-	void spellResearch(const CGTownInstance *town) override;
+	void spellResearch(const CGTownInstance *town, SpellID spellAtSlot) override;
 	void swapGarrisonHero(const CGTownInstance *town) override;
 	void buyArtifact(const CGHeroInstance *hero, ArtifactID aid) override;
 	void trade(const ObjectInstanceID marketId, EMarketMode mode, TradeItemSell id1, TradeItemBuy id2, ui32 val1, const CGHeroInstance * hero = nullptr) override;

+ 1 - 1
client/windows/CCastleInterface.cpp

@@ -2032,7 +2032,7 @@ void CMageGuildScreen::Scroll::clickPressed(const Point & cursorPosition)
 {
 	const CGTownInstance * town = LOCPLINT->cb->getTown(townId);
 	if(LOCPLINT->cb->getSettings().getBoolean(EGameSettings::TOWNS_SPELL_RESEARCH))
-		LOCPLINT->cb->spellResearch(town);
+		LOCPLINT->cb->spellResearch(town, spell->id);
 	else
 		LOCPLINT->showInfoDialog(spell->getDescriptionTranslated(0), std::make_shared<CComponent>(ComponentType::SPELL, spell->id));
 }

+ 4 - 2
lib/networkPacks/PacksForServer.h

@@ -309,11 +309,12 @@ struct DLL_LINKAGE RazeStructure : public BuildStructure
 struct DLL_LINKAGE SpellResearch : public CPackForServer
 {
 	SpellResearch() = default;
-	SpellResearch(const ObjectInstanceID & TID)
-		: tid(TID)
+	SpellResearch(const ObjectInstanceID & TID, SpellID spellAtSlot)
+		: tid(TID), spellAtSlot(spellAtSlot)
 	{
 	}
 	ObjectInstanceID tid;
+	SpellID spellAtSlot;
 
 	void visitTyped(ICPackVisitor & visitor) override;
 
@@ -321,6 +322,7 @@ struct DLL_LINKAGE SpellResearch : public CPackForServer
 	{
 		h & static_cast<CPackForServer &>(*this);
 		h & tid;
+		h & spellAtSlot;
 	}
 };
 

+ 17 - 5
server/CGameHandler.cpp

@@ -2242,16 +2242,28 @@ bool CGameHandler::razeStructure (ObjectInstanceID tid, BuildingID bid)
 	return true;
 }
 
-bool CGameHandler::spellResearch(ObjectInstanceID tid)
+bool CGameHandler::spellResearch(ObjectInstanceID tid, SpellID spellAtSlot)
 {
 	if(!getSettings().getBoolean(EGameSettings::TOWNS_SPELL_RESEARCH) && complain("Spell research not allowed!"))
 		return false;
 
 	CGTownInstance *t = gs->getTown(tid);
-	auto spells = t->spells.at(0);
-	auto spell = SpellID(SpellID::FLY);
-	spells.at(0) = spell;
-	setTownSpells(t, 0, spells);
+
+	int level = -1;
+	for(int i = 0; i < t->spells.size(); i++)
+		if(vstd::find_pos(t->spells[i], spellAtSlot) != -1)
+			level = i;
+	
+	if(level == -1 && complain("Spell for replacement not found!"))
+		return false;
+
+	auto spells = t->spells.at(level);
+
+	std::swap(spells.at(t->spellsAtLevel(level, false)), spells.at(vstd::find_pos(spells, spellAtSlot)));
+	auto it = spells.begin() + t->spellsAtLevel(level, false);
+	std::rotate(it, it + 1, spells.end()); // move to end
+
+	setTownSpells(t, level, spells);
 
 	if(t->visitingHero)
 		giveSpells(t, t->visitingHero);

+ 1 - 1
server/CGameHandler.h

@@ -219,7 +219,7 @@ public:
 	bool buildStructure(ObjectInstanceID tid, BuildingID bid, bool force=false);//force - for events: no cost, no checkings
 	bool visitTownBuilding(ObjectInstanceID tid, BuildingID bid);
 	bool razeStructure(ObjectInstanceID tid, BuildingID bid);
-	bool spellResearch(ObjectInstanceID tid);
+	bool spellResearch(ObjectInstanceID tid, SpellID spellAtSlot);
 	bool disbandCreature( ObjectInstanceID id, SlotID pos );
 	bool arrangeStacks( ObjectInstanceID id1, ObjectInstanceID id2, ui8 what, SlotID p1, SlotID p2, si32 val, PlayerColor player);
 	bool bulkMoveArmy(ObjectInstanceID srcArmy, ObjectInstanceID destArmy, SlotID srcSlot);

+ 1 - 1
server/NetPacksServer.cpp

@@ -140,7 +140,7 @@ void ApplyGhNetPackVisitor::visitBuildStructure(BuildStructure & pack)
 
 void ApplyGhNetPackVisitor::visitSpellResearch(SpellResearch & pack)
 {
-	result = gh.spellResearch(pack.tid);
+	result = gh.spellResearch(pack.tid, pack.spellAtSlot);
 }
 
 void ApplyGhNetPackVisitor::visitVisitTownBuilding(VisitTownBuilding & pack)