From 87f13e3da186a9ce6ce0b9a69048a072d7490266 Mon Sep 17 00:00:00 2001 From: Sirinut Euaungkanakul Date: Mon, 7 Oct 2024 11:24:31 +0700 Subject: [PATCH 1/4] Mob Rate --- .../java/client/command/CommandsExecutor.java | 4 +++ .../command/commands/gm4/MobRateCommand.java | 26 +++++++++++++++++++ .../commands/gm4/MobpointRateCommand.java | 26 +++++++++++++++++++ src/main/java/config/WorldConfig.java | 2 ++ src/main/java/net/server/Server.java | 12 ++++----- src/main/java/net/server/world/World.java | 23 +++++++++++++++- src/main/java/server/life/SpawnPoint.java | 6 ++++- src/main/java/server/maps/MapleMap.java | 6 ++--- 8 files changed, 94 insertions(+), 11 deletions(-) create mode 100644 src/main/java/client/command/commands/gm4/MobRateCommand.java create mode 100644 src/main/java/client/command/commands/gm4/MobpointRateCommand.java diff --git a/src/main/java/client/command/CommandsExecutor.java b/src/main/java/client/command/CommandsExecutor.java index 16de5278254..67ab52f2d2a 100644 --- a/src/main/java/client/command/CommandsExecutor.java +++ b/src/main/java/client/command/CommandsExecutor.java @@ -160,6 +160,8 @@ import client.command.commands.gm4.HorntailCommand; import client.command.commands.gm4.ItemVacCommand; import client.command.commands.gm4.MesoRateCommand; +import client.command.commands.gm4.MobRateCommand; +import client.command.commands.gm4.MobpointRateCommand; import client.command.commands.gm4.PapCommand; import client.command.commands.gm4.PianusCommand; import client.command.commands.gm4.PinkbeanCommand; @@ -507,6 +509,8 @@ private void registerLv4Commands() { addCommand("questrate", 4, QuestRateCommand.class); addCommand("travelrate", 4, TravelRateCommand.class); addCommand("fishrate", 4, FishingRateCommand.class); + addCommand("mobrate", 4, MobRateCommand.class); + addCommand("mobpoint", 4, MobpointRateCommand.class); addCommand("itemvac", 4, ItemVacCommand.class); addCommand("forcevac", 4, ForceVacCommand.class); addCommand("zakum", 4, ZakumCommand.class); diff --git a/src/main/java/client/command/commands/gm4/MobRateCommand.java b/src/main/java/client/command/commands/gm4/MobRateCommand.java new file mode 100644 index 00000000000..588fd0b8d38 --- /dev/null +++ b/src/main/java/client/command/commands/gm4/MobRateCommand.java @@ -0,0 +1,26 @@ +package client.command.commands.gm4; + +import client.Character; +import client.Client; +import client.command.Command; +import tools.PacketCreator; + +public class MobRateCommand extends Command { + { + setDescription("Set mob spawn rate."); + } + + @Override + public void execute(Client c, String[] params) { + Character player = c.getPlayer(); + if (params.length < 1) { + player.yellowMessage("Syntax: !mobrate "); + player.yellowMessage("Current Mob Rate: " + c.getWorldServer().getMobrate()); + return; + } + + float mobrate = Math.max(Float.parseFloat(params[0]), 1f); + c.getWorldServer().setMobrate(mobrate); + c.getWorldServer().broadcastPacket(PacketCreator.serverNotice(6, "[Rate] Mob Spawn Rate has been changed to " + mobrate + "x.")); + } +} diff --git a/src/main/java/client/command/commands/gm4/MobpointRateCommand.java b/src/main/java/client/command/commands/gm4/MobpointRateCommand.java new file mode 100644 index 00000000000..cb1c1ee498b --- /dev/null +++ b/src/main/java/client/command/commands/gm4/MobpointRateCommand.java @@ -0,0 +1,26 @@ +package client.command.commands.gm4; + +import client.Character; +import client.Client; +import client.command.Command; +import tools.PacketCreator; + +public class MobpointRateCommand extends Command { + { + setDescription("Set max mob per spawnpoint rate. (Should always be equal or higher than mob rate)"); + } + + @Override + public void execute(Client c, String[] params) { + Character player = c.getPlayer(); + if (params.length < 1) { + player.yellowMessage("Syntax: !mobpoint "); + player.yellowMessage("Current Mob Point Rate: " + c.getWorldServer().getMobperspawnpoint()); + return; + } + + int maxmobperspawnpoint = Math.max(Integer.parseInt(params[0]), 1); + c.getWorldServer().setMobperspawnpoint(maxmobperspawnpoint); + c.getWorldServer().broadcastPacket(PacketCreator.serverNotice(6, "[Rate] Max Mob Per Spawnpoint Rate has been changed to " + maxmobperspawnpoint + "x.")); + } +} diff --git a/src/main/java/config/WorldConfig.java b/src/main/java/config/WorldConfig.java index 075282bf509..bb85082a479 100644 --- a/src/main/java/config/WorldConfig.java +++ b/src/main/java/config/WorldConfig.java @@ -7,6 +7,8 @@ public class WorldConfig { public String why_am_i_recommended = ""; public int channels = 1; public int exp_rate = 1; + public float mob_rate = 1; + public int max_mob_per_spawnpoint = 1; public int meso_rate = 1; public int drop_rate = 1; public int boss_drop_rate = 1; diff --git a/src/main/java/net/server/Server.java b/src/main/java/net/server/Server.java index 1b0159d2cc2..676f5a819ee 100644 --- a/src/main/java/net/server/Server.java +++ b/src/main/java/net/server/Server.java @@ -427,6 +427,8 @@ private int initWorld() { log.info("Starting world {}", i); int exprate = YamlConfig.config.worlds.get(i).exp_rate; + float mobrate = YamlConfig.config.worlds.get(i).mob_rate; + int mobperspawnpoint = YamlConfig.config.worlds.get(i).max_mob_per_spawnpoint; int mesorate = YamlConfig.config.worlds.get(i).meso_rate; int droprate = YamlConfig.config.worlds.get(i).drop_rate; int bossdroprate = YamlConfig.config.worlds.get(i).boss_drop_rate; @@ -438,10 +440,8 @@ private int initWorld() { String event_message = YamlConfig.config.worlds.get(i).event_message; String why_am_i_recommended = YamlConfig.config.worlds.get(i).why_am_i_recommended; - World world = new World(i, - flag, - event_message, - exprate, droprate, bossdroprate, mesorate, questrate, travelrate, fishingrate); + World world = new World(i, flag, event_message, exprate, droprate, bossdroprate, mesorate, questrate, + travelrate, fishingrate, mobrate, mobperspawnpoint); Map channelInfo = new HashMap<>(); long bootTime = getCurrentTime(); @@ -1477,7 +1477,7 @@ public void transferWorldCharacterEntry(Character chr, Integer toWorld) { // use lgnWLock.unlock(); } } - + /* public void deleteAccountEntry(Integer accountid) { is this even a thing? lgnWLock.lock(); @@ -1487,7 +1487,7 @@ public void deleteAccountEntry(Integer accountid) { is this even a thing? } finally { lgnWLock.unlock(); } - + for (World wserv : this.getWorlds()) { wserv.clearAccountCharacterView(accountid); wserv.unregisterAccountStorage(accountid); diff --git a/src/main/java/net/server/world/World.java b/src/main/java/net/server/world/World.java index 0abb0e570e6..fdb1109e6e5 100644 --- a/src/main/java/net/server/world/World.java +++ b/src/main/java/net/server/world/World.java @@ -126,6 +126,8 @@ public class World { private int questrate; private int travelrate; private int fishingrate; + private float mobrate; + private int mobperspawnpoint; private final String eventmsg; private final List channels = new ArrayList<>(); private final Map pnpcStep = new HashMap<>(); @@ -200,7 +202,8 @@ public class World { private ScheduledFuture timeoutSchedule; private ScheduledFuture hpDecSchedule; - public World(int world, int flag, String eventmsg, int exprate, int droprate, int bossdroprate, int mesorate, int questrate, int travelrate, int fishingrate) { + public World(int world, int flag, String eventmsg, int exprate, int droprate, int bossdroprate, int mesorate, + int questrate, int travelrate, int fishingrate, float mobrate, int mobperspawnpoint) { this.id = world; this.flag = flag; this.eventmsg = eventmsg; @@ -211,6 +214,8 @@ public World(int world, int flag, String eventmsg, int exprate, int droprate, in this.questrate = questrate; this.travelrate = travelrate; this.fishingrate = fishingrate; + this.mobrate = mobrate; + this.mobperspawnpoint = mobperspawnpoint; runningPartyId.set(1000000001); // partyid must not clash with charid to solve update item looting issues, found thanks to Vcoc runningMessengerId.set(1); @@ -458,6 +463,22 @@ public void setFishingRate(int quest) { this.fishingrate = quest; } + public float getMobrate() { + return mobrate; + } + + public void setMobrate(float mobrate) { + this.mobrate = mobrate; + } + + public int getMobperspawnpoint() { + return mobperspawnpoint; + } + + public void setMobperspawnpoint(int mobperspawnpoint) { + this.mobperspawnpoint = mobperspawnpoint; + } + public void loadAccountCharactersView(Integer accountId, List chars) { SortedMap charsMap = new TreeMap<>(); for (Character chr : chars) { diff --git a/src/main/java/server/life/SpawnPoint.java b/src/main/java/server/life/SpawnPoint.java index 798bd95beaa..be9370ae400 100644 --- a/src/main/java/server/life/SpawnPoint.java +++ b/src/main/java/server/life/SpawnPoint.java @@ -67,7 +67,11 @@ public boolean getDenySpawn() { } public boolean shouldSpawn() { - if (denySpawn || mobTime < 0 || spawnedMonsters.get() > 0) { + return shouldSpawn(1); + } + + public boolean shouldSpawn(int maxSpawnedMonsters) { + if (denySpawn || mobTime < 0 || spawnedMonsters.get() >= maxSpawnedMonsters) { return false; } return nextPossibleSpawn <= Server.getInstance().getCurrentTime(); diff --git a/src/main/java/server/maps/MapleMap.java b/src/main/java/server/maps/MapleMap.java index 9ab159af1ba..2d1d711c21e 100644 --- a/src/main/java/server/maps/MapleMap.java +++ b/src/main/java/server/maps/MapleMap.java @@ -3531,10 +3531,10 @@ private int getNumShouldSpawn(int numPlayers) { */ if (YamlConfig.config.server.USE_ENABLE_FULL_RESPAWN) { - return (monsterSpawn.size() - spawnedMonstersOnMap.get()); + return (int) Math.ceil((monsterSpawn.size() - spawnedMonstersOnMap.get()) * getWorldServer().getMobrate()); } - int maxNumShouldSpawn = (int) Math.ceil(getCurrentSpawnRate(numPlayers) * monsterSpawn.size()); + int maxNumShouldSpawn = (int) Math.ceil(getCurrentSpawnRate(numPlayers) * monsterSpawn.size() * getWorldServer().getMobrate()); return maxNumShouldSpawn - spawnedMonstersOnMap.get(); } @@ -3561,7 +3561,7 @@ public void respawn() { Collections.shuffle(randomSpawn); short spawned = 0; for (SpawnPoint spawnPoint : randomSpawn) { - if (spawnPoint.shouldSpawn()) { + if (spawnPoint.shouldSpawn(getWorldServer().getMobperspawnpoint())) { spawnMonster(spawnPoint.getMonster()); spawned++; From d00f08af5be504302883466abc949f0c57b84997 Mon Sep 17 00:00:00 2001 From: Sirinut Euaungkanakul Date: Mon, 7 Oct 2024 14:04:22 +0700 Subject: [PATCH 2/4] fix full respawn calculation --- src/main/java/server/maps/MapleMap.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/server/maps/MapleMap.java b/src/main/java/server/maps/MapleMap.java index 2d1d711c21e..dc8c73709a4 100644 --- a/src/main/java/server/maps/MapleMap.java +++ b/src/main/java/server/maps/MapleMap.java @@ -3530,12 +3530,12 @@ private int getNumShouldSpawn(int numPlayers) { System.out.println("----------------------------------"); */ + float maxMob = monsterSpawn.size() * getWorldServer().getMobrate(); + if (YamlConfig.config.server.USE_ENABLE_FULL_RESPAWN) { - return (int) Math.ceil((monsterSpawn.size() - spawnedMonstersOnMap.get()) * getWorldServer().getMobrate()); + return (int) Math.ceil(maxMob) - spawnedMonstersOnMap.get(); } - - int maxNumShouldSpawn = (int) Math.ceil(getCurrentSpawnRate(numPlayers) * monsterSpawn.size() * getWorldServer().getMobrate()); - return maxNumShouldSpawn - spawnedMonstersOnMap.get(); + return (int) Math.ceil(getCurrentSpawnRate(numPlayers) * maxMob) - spawnedMonstersOnMap.get(); } public void respawn() { From af1ac3fe3321c59a66e24963c3cfbc4293f3b43e Mon Sep 17 00:00:00 2001 From: Sirinut Euaungkanakul Date: Mon, 7 Oct 2024 14:34:35 +0700 Subject: [PATCH 3/4] config --- config.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config.yaml b/config.yaml index 588ef50ca3e..d28158e8a1a 100644 --- a/config.yaml +++ b/config.yaml @@ -9,6 +9,8 @@ worlds: why_am_i_recommended: Welcome to Scania! channels: 3 exp_rate: 10 + mob_rate: 1.0 #Mob count multiplier + max_mob_per_spawnpoint: 1 #Must be equal or higher than mob_rate meso_rate: 10 drop_rate: 10 boss_drop_rate: 10 #NOTE: Boss drop rate OVERRIDES common drop rate, for bosses-only. From 0db01030a26e1575d11dc7bfc1f670755d8b3ca9 Mon Sep 17 00:00:00 2001 From: Sirinut Euaungkanakul Date: Sat, 12 Oct 2024 10:51:35 +0700 Subject: [PATCH 4/4] Spawn max 1 boss (cherry picked from commit 958d9e68d189bd6c9c313b592a72944dd1e937bf) --- src/main/java/server/life/SpawnPoint.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/server/life/SpawnPoint.java b/src/main/java/server/life/SpawnPoint.java index be9370ae400..fa8d7dad2f5 100644 --- a/src/main/java/server/life/SpawnPoint.java +++ b/src/main/java/server/life/SpawnPoint.java @@ -71,7 +71,9 @@ public boolean shouldSpawn() { } public boolean shouldSpawn(int maxSpawnedMonsters) { - if (denySpawn || mobTime < 0 || spawnedMonsters.get() >= maxSpawnedMonsters) { + Monster mob = LifeFactory.getMonster(monster); + int max = mob != null && mob.isBoss() ? 1 : maxSpawnedMonsters; + if (denySpawn || mobTime < 0 || spawnedMonsters.get() >= max) { return false; } return nextPossibleSpawn <= Server.getInstance().getCurrentTime();