diff --git a/Minecraft.Client/Common/App_Defines.h b/Minecraft.Client/Common/App_Defines.h index 55658beff..722774ae8 100644 --- a/Minecraft.Client/Common/App_Defines.h +++ b/Minecraft.Client/Common/App_Defines.h @@ -45,11 +45,10 @@ #define GAME_HOST_OPTION_BITMASK_DOTILEDROPS 0x08000000 #define GAME_HOST_OPTION_BITMASK_NATURALREGEN 0x10000000 #define GAME_HOST_OPTION_BITMASK_DODAYLIGHTCYCLE 0x20000000 -#define GAME_HOST_OPTION_BITMASK_WORLDMOBCAP 0xC0000000 // 2 bits, 4 values (small(0), medium(1), large(2), unlimited(3)) +#define GAME_HOST_OPTION_BITMASK_NOMOBCAP 0x40000000 #define GAME_HOST_OPTION_BITMASK_ALL 0xFFFFFFFF #define GAME_HOST_OPTION_BITMASK_WORLDSIZE_BITSHIFT 20 -#define GAME_HOST_OPTION_BITMASK_WORLDMOBCAP_BITSHIFT 30 // Set to this value as there is no other remaining space enum EGameHostOptionWorldSize { diff --git a/Minecraft.Client/Common/App_enums.h b/Minecraft.Client/Common/App_enums.h index 3c11cc386..809d4bdfc 100644 --- a/Minecraft.Client/Common/App_enums.h +++ b/Minecraft.Client/Common/App_enums.h @@ -636,7 +636,6 @@ enum eGameHostOption eGameHostOption_BedrockFog, eGameHostOption_NoHUD, eGameHostOption_WorldSize, - eGameHostOption_WorldMobCap, eGameHostOption_All, eGameHostOption_DisableSaving, @@ -649,6 +648,7 @@ enum eGameHostOption eGameHostOption_DoTileDrops, eGameHostOption_NaturalRegeneration, eGameHostOption_DoDaylightCycle, + eGameHostOption_NoMobCap, }; // 4J-PB - If any new DLC items are added to the TMSFiles, this array needs updated diff --git a/Minecraft.Client/Common/Consoles_App.cpp b/Minecraft.Client/Common/Consoles_App.cpp index c54dd26e1..d2757c526 100644 --- a/Minecraft.Client/Common/Consoles_App.cpp +++ b/Minecraft.Client/Common/Consoles_App.cpp @@ -8063,10 +8063,16 @@ void CMinecraftApp::SetGameHostOption(unsigned int &uiHostSettings, eGameHostOpt uiHostSettings&=~GAME_HOST_OPTION_BITMASK_WORLDSIZE; uiHostSettings|=(GAME_HOST_OPTION_BITMASK_WORLDSIZE & (uiVal<> GAME_HOST_OPTION_BITMASK_WORLDSIZE_BITSHIFT; - case eGameHostOption_WorldMobCap: - return (uiHostSettings&GAME_HOST_OPTION_BITMASK_WORLDMOBCAP) >> GAME_HOST_OPTION_BITMASK_WORLDMOBCAP_BITSHIFT; + case eGameHostOption_NoMobCap: + return (uiHostSettings&GAME_HOST_OPTION_BITMASK_NOMOBCAP); case eGameHostOption_MobGriefing: return !(uiHostSettings&GAME_HOST_OPTION_BITMASK_MOBGRIEFING); case eGameHostOption_KeepInventory: diff --git a/Minecraft.Client/Common/Media/LaunchMoreOptionsMenu1080.swf b/Minecraft.Client/Common/Media/LaunchMoreOptionsMenu1080.swf index 07d812079..ef9767828 100644 Binary files a/Minecraft.Client/Common/Media/LaunchMoreOptionsMenu1080.swf and b/Minecraft.Client/Common/Media/LaunchMoreOptionsMenu1080.swf differ diff --git a/Minecraft.Client/Common/Media/LaunchMoreOptionsMenu480.swf b/Minecraft.Client/Common/Media/LaunchMoreOptionsMenu480.swf index 666f11274..79a83c626 100644 Binary files a/Minecraft.Client/Common/Media/LaunchMoreOptionsMenu480.swf and b/Minecraft.Client/Common/Media/LaunchMoreOptionsMenu480.swf differ diff --git a/Minecraft.Client/Common/Media/LaunchMoreOptionsMenu720.swf b/Minecraft.Client/Common/Media/LaunchMoreOptionsMenu720.swf index e77beb4ec..62a255fbe 100644 Binary files a/Minecraft.Client/Common/Media/LaunchMoreOptionsMenu720.swf and b/Minecraft.Client/Common/Media/LaunchMoreOptionsMenu720.swf differ diff --git a/Minecraft.Client/Common/Media/LaunchMoreOptionsMenuVita.swf b/Minecraft.Client/Common/Media/LaunchMoreOptionsMenuVita.swf index 5c1d44d9b..ef93b2dd6 100644 Binary files a/Minecraft.Client/Common/Media/LaunchMoreOptionsMenuVita.swf and b/Minecraft.Client/Common/Media/LaunchMoreOptionsMenuVita.swf differ diff --git a/Minecraft.Client/Common/UI/UIScene_CreateWorldMenu.cpp b/Minecraft.Client/Common/UI/UIScene_CreateWorldMenu.cpp index 1cadc46c1..e2c869f84 100644 --- a/Minecraft.Client/Common/UI/UIScene_CreateWorldMenu.cpp +++ b/Minecraft.Client/Common/UI/UIScene_CreateWorldMenu.cpp @@ -1206,6 +1206,7 @@ void UIScene_CreateWorldMenu::CreateGame(UIScene_CreateWorldMenu* pClass, DWORD app.SetGameHostOption(eGameHostOption_DoTileDrops, pClass->m_MoreOptionsParams.bDoTileDrops); app.SetGameHostOption(eGameHostOption_NaturalRegeneration, pClass->m_MoreOptionsParams.bNaturalRegeneration); app.SetGameHostOption(eGameHostOption_DoDaylightCycle, pClass->m_MoreOptionsParams.bDoDaylightCycle); + app.SetGameHostOption(eGameHostOption_NoMobCap, pClass->m_MoreOptionsParams.bNoMobCap); app.SetGameHostOption(eGameHostOption_WasntSaveOwner, false); #ifdef _LARGE_WORLDS @@ -1213,10 +1214,6 @@ void UIScene_CreateWorldMenu::CreateGame(UIScene_CreateWorldMenu* pClass, DWORD pClass->m_MoreOptionsParams.currentWorldSize = static_cast(pClass->m_MoreOptionsParams.worldSize + 1); pClass->m_MoreOptionsParams.newWorldSize = static_cast(pClass->m_MoreOptionsParams.worldSize + 1); #endif - app.SetGameHostOption(eGameHostOption_WorldMobCap, pClass->m_MoreOptionsParams.worldMobCap ); - - // Use helper to update the caps based on what was set earlier - MobCategory::updateMobCaps(pClass->m_MoreOptionsParams.worldMobCap); g_NetworkManager.HostGame(dwLocalUsersMask,isClientSide,isPrivate,MINECRAFT_NET_MAX_PLAYERS,0); diff --git a/Minecraft.Client/Common/UI/UIScene_LaunchMoreOptionsMenu.cpp b/Minecraft.Client/Common/UI/UIScene_LaunchMoreOptionsMenu.cpp index 438c0a959..9d9a7e640 100644 --- a/Minecraft.Client/Common/UI/UIScene_LaunchMoreOptionsMenu.cpp +++ b/Minecraft.Client/Common/UI/UIScene_LaunchMoreOptionsMenu.cpp @@ -15,14 +15,6 @@ int m_iWorldSizeTitleA[4] = }; #endif -string m_iWorldMobCapTitleA[4] = -{ - "Small", - "Medium", - "Large", - "Unlimited" -}; - UIScene_LaunchMoreOptionsMenu::UIScene_LaunchMoreOptionsMenu(int iPad, void *initData, UILayer *parentLayer) : UIScene(iPad, parentLayer) { // Setup all the Iggy references we need for this scene @@ -109,6 +101,7 @@ UIScene_LaunchMoreOptionsMenu::UIScene_LaunchMoreOptionsMenu(int iPad, void *ini m_checkboxes[eLaunchCheckbox_TileDrops].init(app.GetString(IDS_TILE_DROPS), eLaunchCheckbox_TileDrops, m_params->bDoTileDrops); m_checkboxes[eLaunchCheckbox_NaturalRegeneration].init(app.GetString(IDS_NATURAL_REGEN), eLaunchCheckbox_NaturalRegeneration, m_params->bNaturalRegeneration); m_checkboxes[eLaunchCheckbox_DayLightCycle].init(app.GetString(IDS_DAYLIGHT_CYCLE), eLaunchCheckbox_DayLightCycle, m_params->bDoDaylightCycle); + m_checkboxes[eLaunchCheckbox_NoMobCap].init(UIString::UIString("No Mob Cap"), eLaunchCheckbox_NoMobCap, m_params->bNoMobCap); m_labelGameOptions.init( app.GetString(IDS_GAME_OPTIONS) ); m_labelSeed.init(app.GetString(IDS_CREATE_NEW_WORLD_SEED)); @@ -140,10 +133,6 @@ UIScene_LaunchMoreOptionsMenu::UIScene_LaunchMoreOptionsMenu(int iPad, void *ini m_tabIndex = m_params->bGenerateOptions ? TAB_WORLD_OPTIONS : TAB_GAME_OPTIONS; - - // Introduce a mob cap slider for large worlds. If there were a better solution for this it would be nice... - m_sliderWorldMobCap.init(UIString::UIString("Mob Cap Size: " + m_iWorldMobCapTitleA[m_params->worldMobCap]),eControl_WorldMobCap,0,3,m_params->worldMobCap); - // set the default text #ifdef _LARGE_WORLDS wstring wsText=L""; @@ -499,10 +488,10 @@ void UIScene_LaunchMoreOptionsMenu::handleFocusChange(F64 controlId, F64 childId case eLaunchCheckbox_DayLightCycle: stringId = IDS_GAMEOPTION_DAYLIGHT_CYCLE; break; - case eControl_EditSeed: + case eLaunchCheckbox_NoMobCap: stringId = IDS_GAMEOPTION_SEED; break; - case eControl_WorldMobCap: + case eControl_EditSeed: stringId = IDS_GAMEOPTION_SEED; break; #ifdef _LARGE_WORLDS @@ -660,11 +649,6 @@ void UIScene_LaunchMoreOptionsMenu::handleSliderMove(F64 sliderId, F64 currentVa int value = static_cast(currentValue); switch(static_cast(sliderId)) { - case eControl_WorldMobCap: - m_sliderWorldMobCap.handleSliderMove(value); - m_params->worldMobCap = value; - m_sliderWorldMobCap.setLabel(UIString::UIString("Mob Cap Size: " + m_iWorldMobCapTitleA[m_params->worldMobCap])); - break; case eControl_WorldSize: #ifdef _LARGE_WORLDS m_sliderWorldSize.handleSliderMove(value); diff --git a/Minecraft.Client/Common/UI/UIScene_LaunchMoreOptionsMenu.h b/Minecraft.Client/Common/UI/UIScene_LaunchMoreOptionsMenu.h index 962ea1765..d789473a3 100644 --- a/Minecraft.Client/Common/UI/UIScene_LaunchMoreOptionsMenu.h +++ b/Minecraft.Client/Common/UI/UIScene_LaunchMoreOptionsMenu.h @@ -32,13 +32,13 @@ private: eLaunchCheckbox_TileDrops, eLaunchCheckbox_NaturalRegeneration, eLaunchCheckbox_DayLightCycle, + eLaunchCheckbox_NoMobCap, eLaunchCheckboxes_Count, eControl_EditSeed, eControl_WorldSize, eControl_WorldResize, - eControl_WorldMobCap, eControl_Count }; @@ -62,7 +62,6 @@ private: UIControl_TextInput m_editSeed; UIControl_Slider m_sliderWorldSize; UIControl_Slider m_sliderWorldResize; - UIControl_Slider m_sliderWorldMobCap; // Added ~ Mob cap slider for user control IggyName m_funcSetMenuType, m_funcChangeTab, m_funcSetDescription; UI_BEGIN_MAP_ELEMENTS_AND_NAMES(UIScene) UI_MAP_ELEMENT( m_labelGameOptions, "LabelGame") @@ -87,6 +86,7 @@ private: UI_MAP_ELEMENT( m_checkboxes[eLaunchCheckbox_MobLoot], "CheckboxMobLoot") UI_MAP_ELEMENT( m_checkboxes[eLaunchCheckbox_TileDrops], "CheckboxTileDrops") UI_MAP_ELEMENT( m_checkboxes[eLaunchCheckbox_NaturalRegeneration], "CheckboxNaturalRegeneration") + UI_MAP_ELEMENT( m_checkboxes[eLaunchCheckbox_NoMobCap], "CheckboxNoMobCap") UI_END_MAP_CHILD_ELEMENTS() UI_MAP_ELEMENT(m_worldOptions, "WorldOptions") @@ -101,7 +101,6 @@ private: UI_MAP_ELEMENT( m_labelRandomSeed, "RandomSeed") UI_MAP_ELEMENT( m_labelWorldSize, "WorldSize") UI_MAP_ELEMENT( m_sliderWorldSize, "WorldSizeSlider") - UI_MAP_ELEMENT( m_sliderWorldMobCap, "WorldMobCapSlider") UI_MAP_ELEMENT( m_checkboxes[eLaunchCheckbox_Structures], "CheckboxStructures") UI_MAP_ELEMENT( m_checkboxes[eLaunchCheckbox_BonusChest], "CheckboxBonusChest") diff --git a/Minecraft.Client/Common/UI/UIScene_LoadMenu.cpp b/Minecraft.Client/Common/UI/UIScene_LoadMenu.cpp index 7bf129056..7c4ec3086 100644 --- a/Minecraft.Client/Common/UI/UIScene_LoadMenu.cpp +++ b/Minecraft.Client/Common/UI/UIScene_LoadMenu.cpp @@ -480,8 +480,6 @@ void UIScene_LoadMenu::tick() m_MoreOptionsParams.bDisableSaving = app.GetGameHostOption(uiHostOptions,eGameHostOption_DisableSaving)>0?TRUE:FALSE; m_MoreOptionsParams.currentWorldSize = static_cast(app.GetGameHostOption(uiHostOptions, eGameHostOption_WorldSize)); m_MoreOptionsParams.newWorldSize = m_MoreOptionsParams.currentWorldSize; - // Load world mob cap option - m_MoreOptionsParams.worldMobCap = app.GetGameHostOption(uiHostOptions,eGameHostOption_WorldMobCap); m_MoreOptionsParams.bMobGriefing = app.GetGameHostOption(uiHostOptions, eGameHostOption_MobGriefing); m_MoreOptionsParams.bKeepInventory = app.GetGameHostOption(uiHostOptions, eGameHostOption_KeepInventory); @@ -490,6 +488,7 @@ void UIScene_LoadMenu::tick() m_MoreOptionsParams.bDoTileDrops = app.GetGameHostOption(uiHostOptions, eGameHostOption_DoTileDrops); m_MoreOptionsParams.bNaturalRegeneration = app.GetGameHostOption(uiHostOptions, eGameHostOption_NaturalRegeneration); m_MoreOptionsParams.bDoDaylightCycle = app.GetGameHostOption(uiHostOptions, eGameHostOption_DoDaylightCycle); + m_MoreOptionsParams.bNoMobCap = app.GetGameHostOption(uiHostOptions,eGameHostOption_NoMobCap); bool cheatsOn = m_MoreOptionsParams.bHostPrivileges; if (!cheatsOn) @@ -1615,14 +1614,12 @@ void UIScene_LoadMenu::StartGameFromSave(UIScene_LoadMenu* pClass, DWORD dwLocal app.SetGameHostOption(eGameHostOption_DoTileDrops, pClass->m_MoreOptionsParams.bDoTileDrops); app.SetGameHostOption(eGameHostOption_NaturalRegeneration, pClass->m_MoreOptionsParams.bNaturalRegeneration); app.SetGameHostOption(eGameHostOption_DoDaylightCycle, pClass->m_MoreOptionsParams.bDoDaylightCycle); + app.SetGameHostOption(eGameHostOption_NoMobCap, pClass->m_MoreOptionsParams.bNoMobCap); #ifdef _LARGE_WORLDS app.SetGameHostOption(eGameHostOption_WorldSize, pClass->m_MoreOptionsParams.worldSize+1 ); // 0 is GAME_HOST_OPTION_WORLDSIZE_UNKNOWN #endif - app.SetGameHostOption(eGameHostOption_WorldMobCap, pClass->m_MoreOptionsParams.worldMobCap ); - // Use helper to update the caps based on what was set earlier - MobCategory::updateMobCaps(pClass->m_MoreOptionsParams.worldMobCap); // app.SetGameNewWorldSize(64, true ); // app.SetGameNewWorldSize(0, false ); diff --git a/Minecraft.Client/Common/UI/UIStructs.h b/Minecraft.Client/Common/UI/UIStructs.h index 6e16799ca..2f4336487 100644 --- a/Minecraft.Client/Common/UI/UIStructs.h +++ b/Minecraft.Client/Common/UI/UIStructs.h @@ -350,6 +350,7 @@ typedef struct _LaunchMoreOptionsMenuInitData bool bDoTileDrops; bool bNaturalRegeneration; bool bDoDaylightCycle; + bool bNoMobCap; bool bOnlineSettingChangedBySystem; @@ -359,7 +360,6 @@ typedef struct _LaunchMoreOptionsMenuInitData wstring seed; int worldSize; - int worldMobCap; bool bDisableSaving; EGameHostOptionWorldSize currentWorldSize; @@ -376,7 +376,6 @@ typedef struct _LaunchMoreOptionsMenuInitData bTNT = true; iPad = -1; worldSize = 3; - worldMobCap = 0; seed = L""; bDisableSaving = false; newWorldSize = e_worldSize_Unknown; @@ -389,6 +388,7 @@ typedef struct _LaunchMoreOptionsMenuInitData bDoTileDrops = true; bNaturalRegeneration = true; bDoDaylightCycle = true; + bNoMobCap=false; } } LaunchMoreOptionsMenuInitData; diff --git a/Minecraft.Client/MinecraftServer.cpp b/Minecraft.Client/MinecraftServer.cpp index e2a3456ff..f439d470c 100644 --- a/Minecraft.Client/MinecraftServer.cpp +++ b/Minecraft.Client/MinecraftServer.cpp @@ -618,7 +618,7 @@ bool MinecraftServer::initServer(int64_t seed, NetworkGameInitData *initData, DW app.SetGameHostOption(eGameHostOption_Difficulty, GetDedicatedServerInt(settings, L"difficulty", app.GetGameHostOption(eGameHostOption_Difficulty))); app.SetGameHostOption(eGameHostOption_GameType, GetDedicatedServerInt(settings, L"gamemode", app.GetGameHostOption(eGameHostOption_GameType))); - app.SetGameHostOption(eGameHostOption_WorldMobCap, GetDedicatedServerInt(settings, L"world-mob-cap", app.GetGameHostOption(eGameHostOption_WorldMobCap))); + app.SetGameHostOption(eGameHostOption_NoMobCap, GetDedicatedServerBool(settings, L"no-mob-cap", app.GetGameHostOption(eGameHostOption_NoMobCap))); app.SetGameHostOption(eGameHostOption_Structures, GetDedicatedServerBool(settings, L"generate-structures", app.GetGameHostOption(eGameHostOption_Structures) > 0) ? 1 : 0); app.SetGameHostOption(eGameHostOption_BonusChest, GetDedicatedServerBool(settings, L"bonus-chest", app.GetGameHostOption(eGameHostOption_BonusChest) > 0) ? 1 : 0); app.SetGameHostOption(eGameHostOption_PvP, GetDedicatedServerBool(settings, L"pvp", app.GetGameHostOption(eGameHostOption_PvP) > 0) ? 1 : 0); @@ -626,9 +626,6 @@ bool MinecraftServer::initServer(int64_t seed, NetworkGameInitData *initData, DW app.SetGameHostOption(eGameHostOption_FireSpreads, GetDedicatedServerBool(settings, L"fire-spreads", app.GetGameHostOption(eGameHostOption_FireSpreads) > 0) ? 1 : 0); app.SetGameHostOption(eGameHostOption_TNT, GetDedicatedServerBool(settings, L"tnt", app.GetGameHostOption(eGameHostOption_TNT) > 0) ? 1 : 0); - // Use helper to update the caps based on what was set earlier - MobCategory::updateMobCaps(app.GetGameHostOption(eGameHostOption_WorldMobCap)); - app.DebugPrintf("\n*** SERVER SETTINGS ***\n"); app.DebugPrintf("ServerSettings: host-friends-only is %s\n",(app.GetGameHostOption(eGameHostOption_FriendsOfFriends)>0)?"on":"off"); app.DebugPrintf("ServerSettings: game-type is %s\n",(app.GetGameHostOption(eGameHostOption_GameType)==0)?"Survival Mode":"Creative Mode"); diff --git a/Minecraft.World/Biome.cpp b/Minecraft.World/Biome.cpp index 66265765e..6f42ec509 100644 --- a/Minecraft.World/Biome.cpp +++ b/Minecraft.World/Biome.cpp @@ -222,7 +222,24 @@ int Biome::getSkyColor(float temp) vector *Biome::getMobs(MobCategory *category) { if (category == MobCategory::monster) return &enemies; - if (category == MobCategory::creature) return &friendlies; + if (category == MobCategory::creature) + { + if (app.GetGameHostOption(eGameHostOption_NoMobCap)) + { + // Only input into this if necessary, this should be after all others are set up for this biome as well + if (allFriendlies.empty()) { + // If empty, reserve the combined size of all mob spawner data + allFriendlies.reserve(friendlies.size() + friendlies_chicken.size() + friendlies_wolf.size() + friendlies_mushroomcow.size()); + // Combine each vector into allFriendlies + allFriendlies.insert(allFriendlies.end(), friendlies.begin(), friendlies.end()); + allFriendlies.insert(allFriendlies.end(), friendlies_chicken.begin(), friendlies_chicken.end()); + allFriendlies.insert(allFriendlies.end(), friendlies_wolf.begin(), friendlies_wolf.end()); + allFriendlies.insert(allFriendlies.end(), friendlies_mushroomcow.begin(), friendlies_mushroomcow.end()); + } + return &allFriendlies; // Use combined vector when using Java logic + } + return &friendlies; + } if (category == MobCategory::waterCreature) return &waterFriendlies; if (category == MobCategory::creature_chicken) return &friendlies_chicken; if (category == MobCategory::creature_wolf) return &friendlies_wolf; diff --git a/Minecraft.World/Biome.h b/Minecraft.World/Biome.h index f7de31662..50446fedc 100644 --- a/Minecraft.World/Biome.h +++ b/Minecraft.World/Biome.h @@ -82,6 +82,7 @@ public: protected: vector enemies; + vector allFriendlies; // Added to not have to recombine with other groups every time spawner data is used vector friendlies; vector waterFriendlies; vector friendlies_chicken; diff --git a/Minecraft.World/Level.cpp b/Minecraft.World/Level.cpp index 1ba28c62d..6a65e3f25 100644 --- a/Minecraft.World/Level.cpp +++ b/Minecraft.World/Level.cpp @@ -4695,7 +4695,7 @@ void Level::decrementUnsavedChunkCount() bool Level::canCreateMore(eINSTANCEOF type, ESPAWN_TYPE spawnType) { - if (app.GetGameHostOption(eGameHostOption_WorldMobCap) == 3) + if (app.GetGameHostOption(eGameHostOption_NoMobCap)) { return true; } diff --git a/Minecraft.World/MobCategory.cpp b/Minecraft.World/MobCategory.cpp index 19437bb83..e08503ab4 100644 --- a/Minecraft.World/MobCategory.cpp +++ b/Minecraft.World/MobCategory.cpp @@ -47,8 +47,9 @@ void MobCategory::staticCtor() { // 4J - adjusted the max levels here for the xbox version, which now represent the max levels in the whole world monster = new MobCategory(70, Material::air, false, false, eTYPE_MONSTER, false); - creature = new MobCategory(10, Material::air, true, true, eTYPE_ANIMALS_SPAWN_LIMIT_CHECK, false); - ambient = new MobCategory(15, Material::air, true, false, eTYPE_AMBIENT, false), + // Raised these to be identical to base LCE + creature = new MobCategory(50, Material::air, true, true, eTYPE_ANIMALS_SPAWN_LIMIT_CHECK, eTYPE_ANIMAL, false); + ambient = new MobCategory(20, Material::air, true, false, eTYPE_AMBIENT, false), waterCreature = new MobCategory(5, Material::water, true, false, eTYPE_WATERANIMAL, false); values[0] = monster; @@ -62,18 +63,53 @@ void MobCategory::staticCtor() values[4] = creature_wolf; values[5] = creature_chicken; values[6] = creature_mushroomcow; - - updateMobCaps(0); // Set the mob caps to the default limits + + maxNaturalMonsters = 50; + maxNaturalAnimals = 50; + maxNaturalAmbient = 20; + maxNaturalSquid = 5; + maxNaturalChickens = 8; + maxNaturalWolves = 8; + maxNaturalMushroomCows = 2; + maxSnowGolems = 16; + maxIronGolems = 16; + maxBosses = 1; + maxVillagersWithBreeding = 35; + monster->m_maxPerLevel = maxNaturalMonsters; + creature->m_maxPerLevel = maxNaturalAnimals; + ambient->m_maxPerLevel = maxNaturalAmbient; + waterCreature->m_maxPerLevel = maxNaturalSquid; + creature_wolf->m_maxPerLevel = maxNaturalWolves; + creature_chicken->m_maxPerLevel = maxNaturalChickens; + creature_mushroomcow->m_maxPerLevel = maxNaturalMushroomCows; + maxAnimalsWithBreeding = maxNaturalAnimals + 20; + maxChickensWithBreeding = maxNaturalChickens + 8; + maxMushroomCowsWithBreeding = maxNaturalMushroomCows + 20; + maxWolvesWithBreeding = maxNaturalWolves + 8; + maxAnimalsWithSpawnEgg = maxAnimalsWithBreeding + 20; + maxChickensWithSpawnEgg = maxChickensWithBreeding + 10; + maxWolvesWithSpawnEgg = maxWolvesWithBreeding + 10; + maxMonstersWithSpawnEgg = maxNaturalMonsters + 20; + maxVillagersWithSpawnEgg = maxVillagersWithBreeding + 15; + maxMushroomCowsWithSpawnEgg = maxMushroomCowsWithBreeding + 8; + maxSquidsWithSpawnEgg = maxNaturalSquid + 8; + maxAmbientWithSpawnEgg = maxNaturalAmbient + 8; } MobCategory::MobCategory(int maxVar, Material *spawnPositionMaterial, bool isFriendly, bool isPersistent, eINSTANCEOF eBase, bool isSingleType) - : m_max(maxVar), spawnPositionMaterial(spawnPositionMaterial), m_isFriendly(isFriendly), m_isPersistent(isPersistent), m_eBase(eBase), m_isSingleType(isSingleType) + : m_max(maxVar), spawnPositionMaterial(spawnPositionMaterial), m_isFriendly(isFriendly), m_isPersistent(isPersistent), m_eBase(eBase), m_eJavaBase(eBase), m_isSingleType(isSingleType) +{ +} + +MobCategory::MobCategory(int maxVar, Material *spawnPositionMaterial, bool isFriendly, bool isPersistent, eINSTANCEOF eBase, eINSTANCEOF eJavaBase, bool isSingleType) + : m_max(maxVar), spawnPositionMaterial(spawnPositionMaterial), m_isFriendly(isFriendly), m_isPersistent(isPersistent), m_eBase(eBase), m_eJavaBase(eJavaBase), m_isSingleType(isSingleType) { } // 4J - added const eINSTANCEOF MobCategory::getEnumBaseClass() { + if (app.GetGameHostOption(eGameHostOption_NoMobCap)) return m_eJavaBase; return m_eBase; } @@ -105,72 +141,4 @@ bool MobCategory::isSingleType() bool MobCategory::isPersistent() { return m_isPersistent; -} - -void MobCategory::updateMobCaps(int mode) -{ - switch (mode) - { - case 0: // Original limits - maxNaturalMonsters = 50; - maxNaturalAnimals = 50; - maxNaturalAmbient = 20; - maxNaturalSquid = 5; - maxNaturalChickens = 8; - maxNaturalWolves = 8; - maxNaturalMushroomCows = 2; - maxSnowGolems = 16; - maxIronGolems = 16; - maxBosses = 1; - maxVillagersWithBreeding = 35; - break; - case 1: - // Match previous definition of limits - maxNaturalMonsters = 70; - maxNaturalAnimals = 70; - maxNaturalAmbient = 20; - maxNaturalSquid = 10; - maxNaturalChickens = 16; - maxNaturalWolves = 16; - maxNaturalMushroomCows = 8; - maxSnowGolems = 16; - maxIronGolems = 16; - maxBosses = 1; - maxVillagersWithBreeding = 50; - break; - case 2: // Large, higher than both original and new limits - maxNaturalMonsters = 100; - maxNaturalAnimals = 100; - maxNaturalAmbient = 40; - maxNaturalSquid = 15; - maxNaturalChickens = 24; - maxNaturalWolves = 24; - maxNaturalMushroomCows = 16; - maxSnowGolems = 32; - maxIronGolems = 32; - maxBosses = 3; - maxVillagersWithBreeding = 100; - break; - case 3: - return; // Keep current limits, as all related checks are bypassed in this case - } - monster->m_maxPerLevel = maxNaturalMonsters; - creature->m_maxPerLevel = maxNaturalAnimals; - ambient->m_maxPerLevel = maxNaturalAmbient; - waterCreature->m_maxPerLevel = maxNaturalSquid; - creature_wolf->m_maxPerLevel = maxNaturalWolves; - creature_chicken->m_maxPerLevel = maxNaturalChickens; - creature_mushroomcow->m_maxPerLevel = maxNaturalMushroomCows; - maxAnimalsWithBreeding = maxNaturalAnimals + 20; - maxChickensWithBreeding = maxNaturalChickens + 8; - maxMushroomCowsWithBreeding = maxNaturalMushroomCows + 20; - maxWolvesWithBreeding = maxNaturalWolves + 8; - maxAnimalsWithSpawnEgg = maxAnimalsWithBreeding + 20; - maxChickensWithSpawnEgg = maxChickensWithBreeding + 10; - maxWolvesWithSpawnEgg = maxWolvesWithBreeding + 10; - maxMonstersWithSpawnEgg = maxNaturalMonsters + 20; - maxVillagersWithSpawnEgg = maxVillagersWithBreeding + 15; - maxMushroomCowsWithSpawnEgg = maxMushroomCowsWithBreeding + 8; - maxSquidsWithSpawnEgg = maxNaturalSquid + 8; - maxAmbientWithSpawnEgg = maxNaturalAmbient + 8; } \ No newline at end of file diff --git a/Minecraft.World/MobCategory.h b/Minecraft.World/MobCategory.h index 569bff16b..69b74853a 100644 --- a/Minecraft.World/MobCategory.h +++ b/Minecraft.World/MobCategory.h @@ -71,8 +71,14 @@ private: const bool m_isPersistent; const bool m_isSingleType; // 4J Added const eINSTANCEOF m_eBase; // 4J added + // Added for animals so that wolves, mushroomcows, and chickens can be included in the category count. + // Only used when mob cap is unlimited, done to ensure the wolves and chickens can spawn properly. + // When using the shorter constructor, this will be set to m_eBase. + const eINSTANCEOF m_eJavaBase; MobCategory(int maxVar, Material *spawnPositionMaterial, bool isFriendly, bool isPersistent, eINSTANCEOF eBase, bool isSingleType); + // Additional constructor, allows specifying the enum to use if mob cap is unlimited + MobCategory(int maxVar, Material * spawnPositionMaterial, bool isFriendly, bool isPersistent, eINSTANCEOF eBase, eINSTANCEOF eJavaBase, bool isSingleType); public: const type_info getBaseClass(); @@ -85,7 +91,5 @@ public: bool isPersistent(); public: - // Add a function to update the mob caps - static void updateMobCaps(int mode); static void staticCtor(); }; diff --git a/Minecraft.World/MobSpawner.cpp b/Minecraft.World/MobSpawner.cpp index 1053f8094..efbf2b87f 100644 --- a/Minecraft.World/MobSpawner.cpp +++ b/Minecraft.World/MobSpawner.cpp @@ -212,11 +212,13 @@ const int MobSpawner::tick(ServerLevel *level, bool spawnEnemies, bool spawnFrie // Use variable to not repeat checks int maxInstances = mobCategory->getMaxInstancesPerLevel(); // Check for if the mob cap is "off" (works as Java does, scaled by chunk count) - bool usesChunkLimit = app.GetGameHostOption(eGameHostOption_WorldMobCap) == 3; + bool usesChunkLimit = app.GetGameHostOption(eGameHostOption_NoMobCap); if (usesChunkLimit) { // Use Java logic for the max count instead, accounting for chunks polled and the magic number. maxInstances = mobCategory->getMaxInstancesPerChunk() * chunksToPoll.size() / MAGIC_NUMBER; + // Cancel spawning under extra categories, with this option they should be included in creature + if (i > 3) continue; } // 4J - this is now quite different to the java version. We just have global max counts for the level whereas the original has a max per chunk that