Laserlicht преди 5 месеца
родител
ревизия
d102f660a0

+ 6 - 1
client/CPlayerInterface.cpp

@@ -46,6 +46,7 @@
 #include "render/CAnimation.h"
 #include "render/IImage.h"
 #include "render/IRenderHandler.h"
+#include "render/IScreenHandler.h"
 
 #include "widgets/Buttons.h"
 #include "widgets/CComponent.h"
@@ -1825,6 +1826,11 @@ void CPlayerInterface::showWorldViewEx(const std::vector<ObjectPosInfo>& objectP
 	adventureInt->openWorldView(objectPositions, showTerrain );
 }
 
+void CPlayerInterface::setColorScheme(ColorScheme scheme)
+{
+	ENGINE->screenHandler().setColorScheme(scheme);
+}
+
 std::optional<BattleAction> CPlayerInterface::makeSurrenderRetreatDecision(const BattleID & battleID, const BattleStateInfoForRetreat & battleState)
 {
 	return std::nullopt;
@@ -1842,4 +1848,3 @@ void CPlayerInterface::unregisterBattleInterface(std::shared_ptr<CBattleGameInte
 	GAME->server().client->unregisterBattleInterface(autofightingAI, playerID);
 	autofightingAI.reset();
 }
-

+ 1 - 0
client/CPlayerInterface.h

@@ -145,6 +145,7 @@ protected: // Call-ins from server, should not be called directly, but only via
 	void playerStartsTurn(PlayerColor player) override; //called before yourTurn on active interface
 	void playerEndsTurn(PlayerColor player) override;
 	void showWorldViewEx(const std::vector<ObjectPosInfo> & objectPositions, bool showTerrain) override;
+	void setColorScheme(ColorScheme scheme) override;
 
 	//for battles
 	void actionFinished(const BattleID & battleID, const BattleAction& action) override;//occurs AFTER action taken by active stack or by the hero

+ 1 - 0
client/ClientNetPackVisitors.h

@@ -103,6 +103,7 @@ public:
 	void visitNewObject(NewObject & pack) override;
 	void visitSetAvailableArtifacts(SetAvailableArtifacts & pack) override;
 	void visitEntitiesChanged(EntitiesChanged & pack) override;
+	void visitPlayerCheated(PlayerCheated & pack) override;
 };
 
 class ApplyFirstClientNetPackVisitor : public VCMI_LIB_WRAP_NAMESPACE(ICPackVisitor)

+ 6 - 1
client/NetPacksClient.cpp

@@ -1074,8 +1074,13 @@ void ApplyClientNetPackVisitor::visitSetAvailableArtifacts(SetAvailableArtifacts
 	}
 }
 
-
 void ApplyClientNetPackVisitor::visitEntitiesChanged(EntitiesChanged & pack)
 {
 	callAllInterfaces(cl, &CGameInterface::invalidatePaths);
 }
+
+void ApplyClientNetPackVisitor::visitPlayerCheated(PlayerCheated & pack)
+{
+	if(pack.colorScheme != ColorScheme::KEEP && vstd::contains(cl.playerint, pack.player))
+		cl.playerint[pack.player]->setColorScheme(pack.colorScheme);
+}

+ 4 - 0
client/render/IScreenHandler.h

@@ -10,6 +10,8 @@
 
 #pragma once
 
+#include "../../lib/constants/Enumerations.h"
+
 VCMI_LIB_NAMESPACE_BEGIN
 class Point;
 class Rect;
@@ -58,4 +60,6 @@ public:
 
 	/// Window has focus
 	virtual bool hasFocus() = 0;
+
+	virtual void setColorScheme(ColorScheme scheme) = 0;
 };

+ 63 - 13
client/renderSDL/SDL_Extensions.cpp

@@ -547,24 +547,27 @@ void CSDL_Ext::convertToGrayscaleBpp(SDL_Surface * surf, const Rect & rect )
 {
 	uint8_t * pixels = static_cast<uint8_t*>(surf->pixels);
 
-	for(int yp = rect.top(); yp < rect.bottom(); ++yp)
+	tbb::parallel_for(tbb::blocked_range<size_t>(rect.top(), rect.bottom()), [&](const tbb::blocked_range<size_t>& r)
 	{
-		uint8_t * pixel_from = pixels + yp * surf->pitch + rect.left() * surf->format->BytesPerPixel;
-		uint8_t * pixel_dest = pixels + yp * surf->pitch + rect.right() * surf->format->BytesPerPixel;
-
-		for (uint8_t * pixel = pixel_from; pixel < pixel_dest; pixel += surf->format->BytesPerPixel)
+		for(int yp = r.begin(); yp != r.end(); ++yp)
 		{
-			int r = Channels::px<bpp>::r.get(pixel);
-			int g = Channels::px<bpp>::g.get(pixel);
-			int b = Channels::px<bpp>::b.get(pixel);
+			uint8_t * pixel_from = pixels + yp * surf->pitch + rect.left() * surf->format->BytesPerPixel;
+			uint8_t * pixel_dest = pixels + yp * surf->pitch + rect.right() * surf->format->BytesPerPixel;
+
+			for (uint8_t * pixel = pixel_from; pixel < pixel_dest; pixel += surf->format->BytesPerPixel)
+			{
+				int r = Channels::px<bpp>::r.get(pixel);
+				int g = Channels::px<bpp>::g.get(pixel);
+				int b = Channels::px<bpp>::b.get(pixel);
 
-			int gray = static_cast<int>(0.299 * r + 0.587 * g + 0.114 *b);
+				int gray = static_cast<int>(0.299 * r + 0.587 * g + 0.114 *b);
 
-			Channels::px<bpp>::r.set(pixel, gray);
-			Channels::px<bpp>::g.set(pixel, gray);
-			Channels::px<bpp>::b.set(pixel, gray);
+				Channels::px<bpp>::r.set(pixel, gray);
+				Channels::px<bpp>::g.set(pixel, gray);
+				Channels::px<bpp>::b.set(pixel, gray);
+			}
 		}
-	}
+	});
 }
 
 void CSDL_Ext::convertToGrayscale( SDL_Surface * surf, const Rect & rect )
@@ -576,6 +579,53 @@ void CSDL_Ext::convertToGrayscale( SDL_Surface * surf, const Rect & rect )
 	}
 }
 
+template<int bpp>
+void CSDL_Ext::convertToH2SchemeBpp(SDL_Surface * surf, const Rect & rect )
+{
+	uint8_t * pixels = static_cast<uint8_t*>(surf->pixels);
+
+	tbb::parallel_for(tbb::blocked_range<size_t>(rect.top(), rect.bottom()), [&](const tbb::blocked_range<size_t>& r)
+	{
+		for(int yp = r.begin(); yp != r.end(); ++yp)
+		{
+			uint8_t * pixel_from = pixels + yp * surf->pitch + rect.left() * surf->format->BytesPerPixel;
+			uint8_t * pixel_dest = pixels + yp * surf->pitch + rect.right() * surf->format->BytesPerPixel;
+
+			for (uint8_t * pixel = pixel_from; pixel < pixel_dest; pixel += surf->format->BytesPerPixel)
+			{
+				int r = Channels::px<bpp>::r.get(pixel);
+				int g = Channels::px<bpp>::g.get(pixel);
+				int b = Channels::px<bpp>::b.get(pixel);
+
+				double gray = 0.3 * r + 0.59 * g + 0.11 * b;
+				double factor = 2.0;
+
+				//fast approximation instead of colorspace conversion
+				r = static_cast<int>(gray + (r - gray) * factor);
+				g = static_cast<int>(gray + (g - gray) * factor);
+				b = static_cast<int>(gray + (b - gray) * factor);
+
+				r = std::clamp(r, 0, 255);
+				g = std::clamp(g, 0, 255);
+				b = std::clamp(b, 0, 255);
+
+				Channels::px<bpp>::r.set(pixel, r);
+				Channels::px<bpp>::g.set(pixel, g);
+				Channels::px<bpp>::b.set(pixel, b);
+			}
+		}
+	});
+}
+
+void CSDL_Ext::convertToH2Scheme( SDL_Surface * surf, const Rect & rect )
+{
+	switch(surf->format->BytesPerPixel)
+	{
+		case 3: convertToH2SchemeBpp<3>(surf, rect); break;
+		case 4: convertToH2SchemeBpp<4>(surf, rect); break;
+	}
+}
+
 void CSDL_Ext::blitSurface(SDL_Surface * src, const Rect & srcRectInput, SDL_Surface * dst, const Point & dstPoint)
 {
 	SDL_Rect srcRect = CSDL_Ext::toSDL(srcRectInput);

+ 4 - 0
client/renderSDL/SDL_Extensions.h

@@ -71,6 +71,10 @@ SDL_Color toSDL(const ColorRGBA & color);
 	void convertToGrayscaleBpp(SDL_Surface * surf, const Rect & rect);
 	void convertToGrayscale(SDL_Surface * surf, const Rect & rect);
 
+	template<int bpp>
+	void convertToH2SchemeBpp(SDL_Surface * surf, const Rect & rect);
+	void convertToH2Scheme(SDL_Surface * surf, const Rect & rect);
+
 	void setColorKey(SDL_Surface * surface, SDL_Color color);
 
 	///set key-color to 0,255,255

+ 20 - 1
client/renderSDL/ScreenHandler.cpp

@@ -11,6 +11,8 @@
 #include "StdInc.h"
 #include "ScreenHandler.h"
 
+#include "SDL_Extensions.h"
+
 #include "../CMT.h"
 #include "../eventsSDL/NotificationHandler.h"
 #include "../GameEngine.h"
@@ -623,7 +625,19 @@ Canvas ScreenHandler::getScreenCanvas() const
 
 void ScreenHandler::updateScreenTexture()
 {
-	SDL_UpdateTexture(screenTexture, nullptr, screen->pixels, screen->pitch);
+	if(colorScheme == ColorScheme::NONE)
+	{
+		SDL_UpdateTexture(screenTexture, nullptr, screen->pixels, screen->pitch);
+		return;
+	}
+
+	SDL_Surface * screenScheme = SDL_ConvertSurface(screen, screen->format, screen->flags);
+	if(colorScheme == ColorScheme::GRAYSCALE)
+		CSDL_Ext::convertToGrayscale(screenScheme, Rect(0, 0, screen->w, screen->h));
+	else if(colorScheme == ColorScheme::H2_SCHEME)
+		CSDL_Ext::convertToH2Scheme(screenScheme, Rect(0, 0, screen->w, screen->h));
+	SDL_UpdateTexture(screenTexture, nullptr, screenScheme->pixels, screenScheme->pitch);
+	SDL_FreeSurface(screenScheme);
 }
 
 void ScreenHandler::presentScreenTexture()
@@ -674,3 +688,8 @@ bool ScreenHandler::hasFocus()
 	ui32 flags = SDL_GetWindowFlags(mainWindow);
 	return flags & SDL_WINDOW_INPUT_FOCUS;
 }
+
+void ScreenHandler::setColorScheme(ColorScheme scheme)
+{
+	colorScheme = scheme;
+}

+ 3 - 0
client/renderSDL/ScreenHandler.h

@@ -49,6 +49,7 @@ class ScreenHandler final : public IScreenHandler
 	SDL_Surface * screen = nullptr;
 
 	EUpscalingFilter upscalingFilter = EUpscalingFilter::AUTO;
+	ColorScheme colorScheme = ColorScheme::NONE;
 
 	/// Dimensions of target surfaces/textures, this value is what game logic views as screen size
 	Point getPreferredLogicalResolution() const;
@@ -124,4 +125,6 @@ public:
 	std::vector<Point> getSupportedResolutions(int displayIndex) const;
 	std::tuple<int, int> getSupportedScalingRange() const final;
 	Rect convertLogicalPointsToWindow(const Rect & input) const final;
+
+	void setColorScheme(ColorScheme filter) final;
 };

+ 2 - 0
docs/players/Cheat_Codes.md

@@ -73,6 +73,8 @@ Alternative usage: `vcmiexp <amount>` - gives selected hero specified amount of
 ### Misc
 
 `nwctheone` or `vcmigod` - reveals the whole map, gives 5 archangels in each empty slot, unlimited movement points and permanent flight
+`nwcphisherprice` or `vcmicolor` - change game color palette to Heroes II like until game restart
+`vcmigray` - change game color palette to grayscale until game restart
 
 ## Using cheat codes on other players
 

+ 3 - 0
lib/callback/CGameInterface.h

@@ -11,6 +11,7 @@
 
 #include "CBattleGameInterface.h"
 #include "IGameEventsReceiver.h"
+#include "../constants/Enumerations.h"
 
 VCMI_LIB_NAMESPACE_BEGIN
 
@@ -51,6 +52,8 @@ public:
 
 	/// Invalidates and destroys all paths for all heroes
 	virtual void invalidatePaths(){};
+
+	virtual void setColorScheme(ColorScheme scheme){};
 };
 
 VCMI_LIB_NAMESPACE_END

+ 8 - 0
lib/constants/Enumerations.h

@@ -259,4 +259,12 @@ enum class EWeekType : int8_t
 	PLAGUE
 };
 
+enum class ColorScheme : int8_t
+{
+	NONE,
+	KEEP,
+	GRAYSCALE,
+	H2_SCHEME
+};
+
 VCMI_LIB_NAMESPACE_END

+ 1 - 1
lib/gameState/GameStatePackVisitor.cpp

@@ -1415,7 +1415,7 @@ void GameStatePackVisitor::visitPlayerCheated(PlayerCheated & pack)
 
 	gs.getPlayerState(pack.player)->enteredLosingCheatCode = pack.losingCheatCode;
 	gs.getPlayerState(pack.player)->enteredWinningCheatCode = pack.winningCheatCode;
-	gs.getPlayerState(pack.player)->cheated = true;
+	gs.getPlayerState(pack.player)->cheated = !pack.localOnlyCheat;
 }
 
 void GameStatePackVisitor::visitPlayerStartsTurn(PlayerStartsTurn & pack)

+ 7 - 0
lib/networkPacks/PacksForClient.h

@@ -112,16 +112,23 @@ struct DLL_LINKAGE PlayerBlocked : public CPackForClient
 struct DLL_LINKAGE PlayerCheated : public CPackForClient
 {
 	PlayerColor player;
+	bool localOnlyCheat = false;
+
 	bool losingCheatCode = false;
 	bool winningCheatCode = false;
+	ColorScheme colorScheme = ColorScheme::KEEP;
 
 	void visitTyped(ICPackVisitor & visitor) override;
 
 	template <typename Handler> void serialize(Handler & h)
 	{
 		h & player;
+		if (h.version >= Handler::Version::COLOR_FILTER)
+			h & localOnlyCheat;
 		h & losingCheatCode;
 		h & winningCheatCode;
+		if (h.version >= Handler::Version::COLOR_FILTER)
+			h & colorScheme;
 	}
 };
 

+ 2 - 1
lib/serializer/ESerializationVersion.h

@@ -41,8 +41,9 @@ enum class ESerializationVersion : int32_t
 	STORE_UID_COUNTER_IN_CMAP,  // fix crash caused by conflicting instanceName after loading game
 	REWARDABLE_EXTENSIONS, // new functionality for rewardable objects
 	FLAGGABLE_BONUS_SYSTEM_NODE, // flaggable objects now contain bonus system node
+	COLOR_FILTER, // color filter cheat
 
-	CURRENT = FLAGGABLE_BONUS_SYSTEM_NODE,
+	CURRENT = COLOR_FILTER,
 };
 
 static_assert(ESerializationVersion::MINIMAL <= ESerializationVersion::CURRENT, "Invalid serialization version definition!");

+ 100 - 80
server/processors/PlayerMessageProcessor.cpp

@@ -494,6 +494,15 @@ void PlayerMessageProcessor::cheatGiveScrolls(PlayerColor player, const CGHeroIn
 		}
 }
 
+void PlayerMessageProcessor::cheatColorSchemeChange(PlayerColor player, ColorScheme scheme)
+{
+	PlayerCheated pc;
+	pc.player = player;
+	pc.colorScheme = scheme;
+	pc.localOnlyCheat = true;
+	gameHandler->sendAndApply(pc);
+}
+
 void PlayerMessageProcessor::cheatLevelup(PlayerColor player, const CGHeroInstance * hero, std::vector<std::string> words)
 {
 	if (!hero)
@@ -698,6 +707,10 @@ bool PlayerMessageProcessor::handleCheatCode(const std::string & cheat, PlayerCo
 	words.erase(words.begin());
 
 	//  VCMI                       VCMI simple        SoD/HotA                   AB                    RoE
+	std::vector<std::string> localCheat = {
+		                           "vcmicolor",       "nwcphisherprice",
+		                           "vcmigray"
+	};
 	std::vector<std::string> townTargetedCheats = {
 		"vcmiarmenelos",           "vcmibuild",       "nwczion",                 "nwccoruscant",       "nwconlyamodel"
 	};
@@ -726,6 +739,12 @@ bool PlayerMessageProcessor::handleCheatCode(const std::string & cheat, PlayerCo
 		                           "vcmiscrolls"
 	};
 
+	if(vstd::contains(localCheat, cheatName))
+	{
+		executeCheatCode(cheatName, player, currObj, words);
+		return true;
+	}
+
 	if (!vstd::contains(townTargetedCheats, cheatName) && !vstd::contains(playerTargetedCheats, cheatName) && !vstd::contains(heroTargetedCheats, cheatName))
 		return false;
 
@@ -810,88 +829,89 @@ void PlayerMessageProcessor::executeCheatCode(const std::string & cheatName, Pla
 		cheatMovement(player, hero, { });
 		cheatFly(player, hero);
 	};
-
-	// Unimplemented H3 cheats:
-	// nwcphisherprice - Changes and brightens the game colors.
+	const auto & doColorSchemeChange = [&](ColorScheme filter) { cheatColorSchemeChange(player, filter); };
 
 	std::map<std::string, std::function<void()>> callbacks = {
-		{"vcmiainur",              [&] () {doCheatGiveArmyFixed({ "archangel", "5" });} },
-		{"nwctrinity",             [&] () {doCheatGiveArmyFixed({ "archangel", "5" });} },
-		{"nwcpadme",               [&] () {doCheatGiveArmyFixed({ "archangel", "5" });} },
-		{"nwcavertingoureyes",     [&] () {doCheatGiveArmyFixed({ "archangel", "5" });} },
-		{"vcmiangband",            [&] () {doCheatGiveArmyFixed({ "blackKnight", "10" });} },
-		{"vcmiglaurung",           [&] () {doCheatGiveArmyFixed({ "crystalDragon", "5000" });} },
-		{"vcmiarchangel",          [&] () {doCheatGiveArmyFixed({ "archangel", "5" });} },
-		{"nwcagents",              [&] () {doCheatGiveArmyFixed({ "blackKnight", "10" });} },
-		{"nwcdarthmaul",           [&] () {doCheatGiveArmyFixed({ "blackKnight", "10" });} },
-		{"nwcfleshwound",          [&] () {doCheatGiveArmyFixed({ "blackKnight", "10" });} },
-		{"vcmiblackknight",        [&] () {doCheatGiveArmyFixed({ "blackKnight", "10" });} },
-		{"vcmicrystal",            [&] () {doCheatGiveArmyFixed({ "crystalDragon", "5000" });} },
-		{"vcmiazure",              [&] () {doCheatGiveArmyFixed({ "azureDragon", "5000" });} },
-		{"vcmifaerie",             [&] () {doCheatGiveArmyFixed({ "fairieDragon", "5000" });} },
-		{"vcmiarmy",                doCheatGiveArmyCustom },
-		{"vcminissi",               doCheatGiveArmyCustom },
-		{"vcmiistari",              doCheatGiveSpells     },
-		{"vcmispells",              doCheatGiveSpells     },
-		{"nwcthereisnospoon",       doCheatGiveSpells     },
-		{"nwcmidichlorians",        doCheatGiveSpells     },
-		{"nwctim",                  doCheatGiveSpells     },
-		{"vcmiarmenelos",           doCheatBuildTown      },
-		{"vcmibuild",               doCheatBuildTown      },
-		{"nwczion",                 doCheatBuildTown      },
-		{"nwccoruscant",            doCheatBuildTown      },
-		{"nwconlyamodel",           doCheatBuildTown      },
-		{"vcminoldor",              doCheatGiveMachines   },
-		{"vcmimachines",            doCheatGiveMachines   },
-		{"nwclotsofguns",           doCheatGiveMachines   },
-		{"nwcr2d2",                 doCheatGiveMachines   },
-		{"nwcantioch",              doCheatGiveMachines   },
-		{"vcmiforgeofnoldorking",   doCheatGiveArtifacts  },
-		{"vcmiartifacts",           doCheatGiveArtifacts  },
-		{"vcmiglorfindel",          doCheatLevelup        },
-		{"vcmilevel",               doCheatLevelup        },
-		{"nwcneo",                  doCheatLevelup        },
-		{"vcmiolorin",              doCheatExperience     },
-		{"vcmiexp",                 doCheatExperience     },
-		{"vcminahar",               doCheatMovement       },
-		{"vcmimove",                doCheatMovement       },
-		{"nwcnebuchadnezzar",       doCheatMovement       },
-		{"nwcpodracer",             doCheatMovement       },
-		{"nwccoconuts",             doCheatMovement       },
-		{"vcmiformenos",            doCheatResources      },
-		{"vcmiresources",           doCheatResources      },
-		{"nwctheconstruct",         doCheatResources      },
-		{"nwcwatto",                doCheatResources      },
-		{"nwcshrubbery",            doCheatResources      },
-		{"nwcbluepill",             doCheatDefeat         },
-		{"nwcsirrobin",             doCheatDefeat         },
-		{"vcmimelkor",              doCheatDefeat         },
-		{"vcmilose",                doCheatDefeat         },
-		{"nwcredpill",              doCheatVictory        },
-		{"nwctrojanrabbit",         doCheatVictory        },
-		{"vcmisilmaril",            doCheatVictory        },
-		{"vcmiwin",                 doCheatVictory        },
-		{"nwcwhatisthematrix",      doCheatMapReveal      },
-		{"nwcrevealourselves",      doCheatMapReveal      },
-		{"nwcgeneraldirection",     doCheatMapReveal      },
-		{"vcmieagles",              doCheatMapReveal      },
-		{"vcmimap",                 doCheatMapReveal      },
-		{"vcmiungoliant",           doCheatMapHide        },
-		{"vcmihidemap",             doCheatMapHide        },
-		{"nwcignoranceisbliss",     doCheatMapHide        },
-		{"vcmiobelisk",             doCheatRevealPuzzle   },
-		{"nwcoracle",               doCheatRevealPuzzle   },
-		{"nwcprophecy",             doCheatRevealPuzzle   },
-		{"nwcalreadygotone",        doCheatRevealPuzzle   },
-		{"vcmiluck",                doCheatMaxLuck        },
-		{"nwcfollowthewhiterabbit", doCheatMaxLuck        },
-		{"nwccastleanthrax",        doCheatMaxLuck        },
-		{"vcmimorale",              doCheatMaxMorale      },
-		{"nwcmorpheus",             doCheatMaxMorale      },
-		{"nwcmuchrejoicing",        doCheatMaxMorale      },
-		{"vcmigod",                 doCheatTheOne         },
-		{"nwctheone",               doCheatTheOne         },
-		{"vcmiscrolls",             doCheatGiveScrolls    },
+		{"vcmiainur",               [&] () {doCheatGiveArmyFixed({ "archangel", "5" });}        },
+		{"nwctrinity",              [&] () {doCheatGiveArmyFixed({ "archangel", "5" });}        },
+		{"nwcpadme",                [&] () {doCheatGiveArmyFixed({ "archangel", "5" });}        },
+		{"nwcavertingoureyes",      [&] () {doCheatGiveArmyFixed({ "archangel", "5" });}        },
+		{"vcmiangband",             [&] () {doCheatGiveArmyFixed({ "blackKnight", "10" });}     },
+		{"vcmiglaurung",            [&] () {doCheatGiveArmyFixed({ "crystalDragon", "5000" });} },
+		{"vcmiarchangel",           [&] () {doCheatGiveArmyFixed({ "archangel", "5" });}        },
+		{"nwcagents",               [&] () {doCheatGiveArmyFixed({ "blackKnight", "10" });}     },
+		{"nwcdarthmaul",            [&] () {doCheatGiveArmyFixed({ "blackKnight", "10" });}     },
+		{"nwcfleshwound",           [&] () {doCheatGiveArmyFixed({ "blackKnight", "10" });}     },
+		{"vcmiblackknight",         [&] () {doCheatGiveArmyFixed({ "blackKnight", "10" });}     },
+		{"vcmicrystal",             [&] () {doCheatGiveArmyFixed({ "crystalDragon", "5000" });} },
+		{"vcmiazure",               [&] () {doCheatGiveArmyFixed({ "azureDragon", "5000" });}   },
+		{"vcmifaerie",              [&] () {doCheatGiveArmyFixed({ "fairieDragon", "5000" });}  },
+		{"vcmiarmy",                doCheatGiveArmyCustom                                       },
+		{"vcminissi",               doCheatGiveArmyCustom                                       },
+		{"vcmiistari",              doCheatGiveSpells                                           },
+		{"vcmispells",              doCheatGiveSpells                                           },
+		{"nwcthereisnospoon",       doCheatGiveSpells                                           },
+		{"nwcmidichlorians",        doCheatGiveSpells                                           },
+		{"nwctim",                  doCheatGiveSpells                                           },
+		{"vcmiarmenelos",           doCheatBuildTown                                            },
+		{"vcmibuild",               doCheatBuildTown                                            },
+		{"nwczion",                 doCheatBuildTown                                            },
+		{"nwccoruscant",            doCheatBuildTown                                            },
+		{"nwconlyamodel",           doCheatBuildTown                                            },
+		{"vcminoldor",              doCheatGiveMachines                                         },
+		{"vcmimachines",            doCheatGiveMachines                                         },
+		{"nwclotsofguns",           doCheatGiveMachines                                         },
+		{"nwcr2d2",                 doCheatGiveMachines                                         },
+		{"nwcantioch",              doCheatGiveMachines                                         },
+		{"vcmiforgeofnoldorking",   doCheatGiveArtifacts                                        },
+		{"vcmiartifacts",           doCheatGiveArtifacts                                        },
+		{"vcmiglorfindel",          doCheatLevelup                                              },
+		{"vcmilevel",               doCheatLevelup                                              },
+		{"nwcneo",                  doCheatLevelup                                              },
+		{"vcmiolorin",              doCheatExperience                                           },
+		{"vcmiexp",                 doCheatExperience                                           },
+		{"vcminahar",               doCheatMovement                                             },
+		{"vcmimove",                doCheatMovement                                             },
+		{"nwcnebuchadnezzar",       doCheatMovement                                             },
+		{"nwcpodracer",             doCheatMovement                                             },
+		{"nwccoconuts",             doCheatMovement                                             },
+		{"vcmiformenos",            doCheatResources                                            },
+		{"vcmiresources",           doCheatResources                                            },
+		{"nwctheconstruct",         doCheatResources                                            },
+		{"nwcwatto",                doCheatResources                                            },
+		{"nwcshrubbery",            doCheatResources                                            },
+		{"nwcbluepill",             doCheatDefeat                                               },
+		{"nwcsirrobin",             doCheatDefeat                                               },
+		{"vcmimelkor",              doCheatDefeat                                               },
+		{"vcmilose",                doCheatDefeat                                               },
+		{"nwcredpill",              doCheatVictory                                              },
+		{"nwctrojanrabbit",         doCheatVictory                                              },
+		{"vcmisilmaril",            doCheatVictory                                              },
+		{"vcmiwin",                 doCheatVictory                                              },
+		{"nwcwhatisthematrix",      doCheatMapReveal                                            },
+		{"nwcrevealourselves",      doCheatMapReveal                                            },
+		{"nwcgeneraldirection",     doCheatMapReveal                                            },
+		{"vcmieagles",              doCheatMapReveal                                            },
+		{"vcmimap",                 doCheatMapReveal                                            },
+		{"vcmiungoliant",           doCheatMapHide                                              },
+		{"vcmihidemap",             doCheatMapHide                                              },
+		{"nwcignoranceisbliss",     doCheatMapHide                                              },
+		{"vcmiobelisk",             doCheatRevealPuzzle                                         },
+		{"nwcoracle",               doCheatRevealPuzzle                                         },
+		{"nwcprophecy",             doCheatRevealPuzzle                                         },
+		{"nwcalreadygotone",        doCheatRevealPuzzle                                         },
+		{"vcmiluck",                doCheatMaxLuck                                              },
+		{"nwcfollowthewhiterabbit", doCheatMaxLuck                                              },
+		{"nwccastleanthrax",        doCheatMaxLuck                                              },
+		{"vcmimorale",              doCheatMaxMorale                                            },
+		{"nwcmorpheus",             doCheatMaxMorale                                            },
+		{"nwcmuchrejoicing",        doCheatMaxMorale                                            },
+		{"vcmigod",                 doCheatTheOne                                               },
+		{"nwctheone",               doCheatTheOne                                               },
+		{"vcmiscrolls",             doCheatGiveScrolls                                          },
+		{"vcmicolor",               [&] () {doColorSchemeChange(ColorScheme::H2_SCHEME);}       },
+		{"nwcphisherprice",         [&] () {doColorSchemeChange(ColorScheme::H2_SCHEME);}       },
+		{"vcmigray",                [&] () {doColorSchemeChange(ColorScheme::GRAYSCALE);}       },
 	};
 
 	assert(callbacks.count(cheatName));

+ 1 - 0
server/processors/PlayerMessageProcessor.h

@@ -47,6 +47,7 @@ class PlayerMessageProcessor
 	void cheatGiveMachines(PlayerColor player, const CGHeroInstance * hero);
 	void cheatGiveArtifacts(PlayerColor player, const CGHeroInstance * hero, std::vector<std::string> words);
 	void cheatGiveScrolls(PlayerColor player, const CGHeroInstance * hero);
+	void cheatColorSchemeChange(PlayerColor player, ColorScheme scheme);
 	void cheatLevelup(PlayerColor player, const CGHeroInstance * hero, std::vector<std::string> words);
 	void cheatExperience(PlayerColor player, const CGHeroInstance * hero, std::vector<std::string> words);
 	void cheatMovement(PlayerColor player, const CGHeroInstance * hero, std::vector<std::string> words);