1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Cheat codes: add option to apply cheats on different players

All suitable codes can now be used with "ai", "all" color or with object ID:
vcminahar all - will apply cheat to all heroes of all players
vcminahar ai - will apply cheat  to all heroes of AI players
vcminahar blue - will apply it to all heroes of blue player
vcminahar 553 - will apply cheat to hero with instance id of 553 if it's exist
Cheats without options work as before.
This commit is contained in:
Arseniy Shestakov 2016-10-02 16:21:46 +03:00
parent cd5c0b3297
commit 7b7958c548
2 changed files with 176 additions and 144 deletions

View File

@ -4250,163 +4250,64 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
return ok;
}
void CGameHandler::playerMessage( PlayerColor player, const std::string &message, ObjectInstanceID currObj )
void CGameHandler::playerMessage(PlayerColor player, const std::string &message, ObjectInstanceID currObj)
{
bool cheated=true;
bool cheated = true;
PlayerMessage temp_message(player, message, ObjectInstanceID(-1)); // don't inform other client on selected object
sendAndApply(&temp_message);
if(message == "vcmiistari") //give all spells and 999 mana
std::vector<std::string> cheat;
boost::split(cheat, message, boost::is_any_of(" "));
int obj = 0;
if(cheat.size() == 2)
{
SetMana sm;
GiveBonus giveBonus(GiveBonus::HERO);
const CGHeroInstance * h = getHero(currObj);
if(!h && complain("Cannot realize cheat, no hero selected!")) return;
sm.hid = h->id;
giveBonus.id = h->id.getNum();
//give all spells with bonus (to allow banned spells)
giveBonus.bonus = Bonus(Bonus::PERMANENT, Bonus::SPELLS_OF_LEVEL, Bonus::OTHER, 0, 0);
//start with level 0 to skip abilities
for(int level = 1; level <= GameConstants::SPELL_LEVELS; level++)
{
giveBonus.bonus.subtype = level;
sendAndApply(&giveBonus);
}
//give mana
sm.val = 999;
sm.absolute = true;
if(!h->hasSpellbook()) //hero doesn't have spellbook
giveHeroNewArtifact(h, VLC->arth->artifacts[ArtifactID::SPELLBOOK], ArtifactPosition::SPELLBOOK); //give spellbook
sendAndApply(&sm);
obj = std::atoi(cheat[1].c_str());
if(obj)
currObj = ObjectInstanceID(obj);
}
else if (message == "vcmiarmenelos") //build all buildings in selected town
const CGHeroInstance * hero = getHero(currObj);
const CGTownInstance * town = getTown(currObj);
if(!town && hero)
town = hero->visitedTown;
if(cheat.size() == 1 || obj)
handleCheatCode(cheat[0], player, hero, town, cheated);
else
{
const CGHeroInstance * hero = getHero(currObj);
const CGTownInstance * town;
if (hero)
town = hero->visitedTown;
else
town = getTown(currObj);
if (town)
for(const auto & i : gs->players)
{
for (auto & build : town->town->buildings)
if(i.first == PlayerColor::NEUTRAL)
continue;
if(cheat[1] == "ai")
{
if (!town->hasBuilt(build.first)
&& !build.second->Name().empty()
&& build.first != BuildingID::SHIP)
if(i.second.human)
continue;
}
else if(cheat[1] != "all" && cheat[1] != i.first.getStr())
continue;
if(cheat[0] == "vcmiformenos" || cheat[0] == "vcmieagles" || cheat[0] == "vcmiungoliant")
{
handleCheatCode(cheat[0], i.first, nullptr, nullptr, cheated);
}
else if(cheat[0] == "vcmiarmenelos")
{
for(const auto & t : i.second.towns)
{
buildStructure(town->id, build.first, true);
handleCheatCode(cheat[0], i.first, nullptr, t, cheated);
}
}
else
{
for(const auto & h : i.second.heroes)
{
handleCheatCode(cheat[0], i.first, h, nullptr, cheated);
}
}
}
}
else if(message == "vcmiainur") //gives 5 archangels into each slot
{
const CGHeroInstance * hero = getHero(currObj);
const CCreature *archangel = VLC->creh->creatures.at(13);
if(!hero) return;
for(int i = 0; i < GameConstants::ARMY_SIZE; i++)
if(!hero->hasStackAtSlot(SlotID(i)))
insertNewStack(StackLocation(hero, SlotID(i)), archangel, 5);
}
else if(message == "vcmiangband") //gives 10 black knight into each slot
{
const CGHeroInstance * hero = getHero(currObj);
const CCreature *blackKnight = VLC->creh->creatures.at(66);
if(!hero) return;
for(int i = 0; i < GameConstants::ARMY_SIZE; i++)
if(!hero->hasStackAtSlot(SlotID(i)))
insertNewStack(StackLocation(hero, SlotID(i)), blackKnight, 10);
}
else if(message == "vcmiglaurung") //gives 5000 crystal dragons into each slot
{
const CGHeroInstance * hero = getHero(currObj);
const CCreature *crystalDragon = VLC->creh->creatures.at(133);
if(!hero) return;
for(int i = 0; i < GameConstants::ARMY_SIZE; i++)
if(!hero->hasStackAtSlot(SlotID(i)))
insertNewStack(StackLocation(hero, SlotID(i)), crystalDragon, 5000);
}
else if(message == "vcminoldor") //all war machines
{
const CGHeroInstance * hero = getHero(currObj);
if(!hero) return;
if(!hero->getArt(ArtifactPosition::MACH1))
giveHeroNewArtifact(hero, VLC->arth->artifacts[ArtifactID::BALLISTA], ArtifactPosition::MACH1);
if(!hero->getArt(ArtifactPosition::MACH2))
giveHeroNewArtifact(hero, VLC->arth->artifacts[ArtifactID::AMMO_CART], ArtifactPosition::MACH2);
if(!hero->getArt(ArtifactPosition::MACH3))
giveHeroNewArtifact(hero, VLC->arth->artifacts[ArtifactID::FIRST_AID_TENT], ArtifactPosition::MACH3);
}
else if (message == "vcmiforgeofnoldorking") //hero gets all artifacts except war machines, spell scrolls and spell book
{
const CGHeroInstance *hero = gs->getHero(currObj);
if(!hero) return;
for (int g = 7; g < VLC->arth->artifacts.size(); ++g) //including artifacts from mods
giveHeroNewArtifact(hero, VLC->arth->artifacts[g], ArtifactPosition::PRE_FIRST);
}
else if(message == "vcmiglorfindel") //selected hero gains a new level
{
CGHeroInstance *hero = gs->getHero(currObj);
changePrimSkill(hero, PrimarySkill::EXPERIENCE, VLC->heroh->reqExp(hero->level+1) - VLC->heroh->reqExp(hero->level));
}
else if(message == "vcminahar") //1000000 movement points
{
CGHeroInstance *hero = gs->getHero(currObj);
if(!hero) return;
SetMovePoints smp;
smp.hid = hero->id;
smp.val = 1000000;
sendAndApply(&smp);
}
else if(message == "vcmiformenos") //give resources
{
SetResources sr;
sr.player = player;
sr.res = getPlayer(player)->resources;
for(int i=0;i<Res::GOLD;i++)
sr.res[i] += 100;
sr.res[Res::GOLD] += 100000; //100k
sendAndApply(&sr);
}
else if(message == "vcmieagles" || message == "vcmiungoliant") //reveal or conceal FoW
{
FoWChange fc;
fc.mode = (message == "vcmieagles" ? 1 : 0);
fc.player = player;
auto hlp_tab = new int3[gs->map->width * gs->map->height * (gs->map->twoLevel ? 2 : 1)];
int lastUnc = 0;
for(int i=0;i<gs->map->width;i++)
for(int j=0;j<gs->map->height;j++)
for(int k = 0; k < (gs->map->twoLevel ? 2 : 1); k++)
if(!gs->getPlayerTeam(fc.player)->fogOfWarMap.at(i).at(j).at(k) || message == "vcmiungoliant")
hlp_tab[lastUnc++] = int3(i,j,k);
fc.tiles.insert(hlp_tab, hlp_tab + lastUnc);
delete [] hlp_tab;
sendAndApply(&fc);
}
else if(message == "vcmisilmaril") //player wins
{
gs->getPlayer(player)->enteredWinningCheatCode = 1;
}
else if(message == "vcmimelkor") //player looses
{
gs->getPlayer(player)->enteredLosingCheatCode = 1;
}
else
cheated = false;
if(cheated)
{
SystemMessage temp_message(VLC->generaltexth->allTexts.at(260));
@ -6004,6 +5905,136 @@ void CGameHandler::spawnWanderingMonsters(CreatureID creatureID)
}
}
void CGameHandler::handleCheatCode(std::string & cheat, PlayerColor player, const CGHeroInstance * hero, const CGTownInstance * town, bool & cheated)
{
if(cheat == "vcmiistari")
{
if(!hero) return;
///Give hero spellbook
if(!hero->hasSpellbook())
giveHeroNewArtifact(hero, VLC->arth->artifacts[ArtifactID::SPELLBOOK], ArtifactPosition::SPELLBOOK);
///Give all spells with bonus (to allow banned spells)
GiveBonus giveBonus(GiveBonus::HERO);
giveBonus.id = hero->id.getNum();
giveBonus.bonus = Bonus(Bonus::PERMANENT, Bonus::SPELLS_OF_LEVEL, Bonus::OTHER, 0, 0);
//start with level 0 to skip abilities
for(int level = 1; level <= GameConstants::SPELL_LEVELS; level++)
{
giveBonus.bonus.subtype = level;
sendAndApply(&giveBonus);
}
///Give mana
SetMana sm;
sm.hid = hero->id;
sm.val = 999;
sm.absolute = true;
sendAndApply(&sm);
}
else if(cheat == "vcmiarmenelos")
{
if(!town) return;
///Build all buildings in selected town
for(auto & build : town->town->buildings)
{
if(!town->hasBuilt(build.first)
&& !build.second->Name().empty()
&& build.first != BuildingID::SHIP)
{
buildStructure(town->id, build.first, true);
}
}
}
else if(cheat == "vcmiainur" || cheat == "vcmiangband" || cheat == "vcmiglaurung")
{
if(!hero) return;
///Gives N creatures into each slot
std::map<std::string, std::pair<int, int>> creatures;
creatures.insert(std::make_pair("vcmiainur", std::make_pair(13, 5))); //5 archangels
creatures.insert(std::make_pair("vcmiangband", std::make_pair(66, 10))); //10 black knights
creatures.insert(std::make_pair("vcmiglaurung", std::make_pair(133, 5000))); //5000 crystal dragons
const CCreature * creature = VLC->creh->creatures.at(creatures[cheat].first);
for(int i = 0; i < GameConstants::ARMY_SIZE; i++)
if(!hero->hasStackAtSlot(SlotID(i)))
insertNewStack(StackLocation(hero, SlotID(i)), creature, creatures[cheat].second);
}
else if(cheat == "vcminoldor")
{
if(!hero) return;
///Give all war machines to hero
if(!hero->getArt(ArtifactPosition::MACH1))
giveHeroNewArtifact(hero, VLC->arth->artifacts[ArtifactID::BALLISTA], ArtifactPosition::MACH1);
if(!hero->getArt(ArtifactPosition::MACH2))
giveHeroNewArtifact(hero, VLC->arth->artifacts[ArtifactID::AMMO_CART], ArtifactPosition::MACH2);
if(!hero->getArt(ArtifactPosition::MACH3))
giveHeroNewArtifact(hero, VLC->arth->artifacts[ArtifactID::FIRST_AID_TENT], ArtifactPosition::MACH3);
}
else if(cheat == "vcmiforgeofnoldorking")
{
if(!hero) return;
///Give hero all artifacts except war machines, spell scrolls and spell book
for(int g = 7; g < VLC->arth->artifacts.size(); ++g) //including artifacts from mods
giveHeroNewArtifact(hero, VLC->arth->artifacts[g], ArtifactPosition::PRE_FIRST);
}
else if(cheat == "vcmiglorfindel")
{
if(!hero) return;
///selected hero gains a new level
changePrimSkill(hero, PrimarySkill::EXPERIENCE, VLC->heroh->reqExp(hero->level + 1) - VLC->heroh->reqExp(hero->level));
}
else if(cheat == "vcminahar")
{
if(!hero) return;
///Give 1000000 movement points to hero
SetMovePoints smp;
smp.hid = hero->id;
smp.val = 1000000;
sendAndApply(&smp);
}
else if(cheat == "vcmiformenos")
{
///Give resources to player
TResources resources;
resources[Res::GOLD] = 100000;
for(Res::ERes i = Res::WOOD; i < Res::GOLD; vstd::advance(i, 1))
resources[i] = 100;
giveResources(player, resources);
}
else if(cheat == "vcmisilmaril")
{
///Player wins
gs->getPlayer(player)->enteredWinningCheatCode = 1;
}
else if(cheat == "vcmimelkor")
{
///Player looses
gs->getPlayer(player)->enteredLosingCheatCode = 1;
}
else if(cheat == "vcmieagles" || cheat == "vcmiungoliant")
{
///Reveal or conceal FoW
FoWChange fc;
fc.mode = (cheat == "vcmieagles" ? 1 : 0);
fc.player = player;
const auto & fowMap = gs->getPlayerTeam(player)->fogOfWarMap;
auto hlp_tab = new int3[gs->map->width * gs->map->height * (gs->map->twoLevel ? 2 : 1)];
int lastUnc = 0;
for(int i = 0; i < gs->map->width; i++)
for(int j = 0; j < gs->map->height; j++)
for(int k = 0; k < (gs->map->twoLevel ? 2 : 1); k++)
if(!fowMap.at(i).at(j).at(k) || !fc.mode)
hlp_tab[lastUnc++] = int3(i, j, k);
fc.tiles.insert(hlp_tab, hlp_tab + lastUnc);
delete [] hlp_tab;
sendAndApply(&fc);
}
else
cheated = false;
}
void CGameHandler::removeObstacle(const CObstacleInstance &obstacle)
{
ObstaclesRemoved obsRem;

View File

@ -194,7 +194,7 @@ public:
void handleConnection(std::set<PlayerColor> players, CConnection &c);
PlayerColor getPlayerAt(CConnection *c) const;
void playerMessage( PlayerColor player, const std::string &message, ObjectInstanceID currObj);
void playerMessage(PlayerColor player, const std::string &message, ObjectInstanceID currObj);
void updateGateState();
bool makeBattleAction(BattleAction &ba);
bool makeAutomaticAction(const CStack *stack, BattleAction &ba); //used when action is taken by stack without volition of player (eg. unguided catapult attack)
@ -284,6 +284,7 @@ public:
void attackCasting(const BattleAttack & bat, Bonus::BonusType attackMode, const CStack * attacker);
bool sacrificeArtifact(const IMarket * m, const CGHeroInstance * hero, ArtifactPosition slot);
void spawnWanderingMonsters(CreatureID creatureID);
void handleCheatCode(std::string & cheat, PlayerColor player, const CGHeroInstance * hero, const CGTownInstance * town, bool & cheated);
friend class CVCMIServer;
CRandomGenerator & getRandomGenerator();