From 51393aa182513f48e87790c2a2c4f6d302a33ffa Mon Sep 17 00:00:00 2001 From: Mads Boddum Date: Sun, 12 May 2019 16:47:15 +0200 Subject: [PATCH 1/7] #143: Server log available in-game as a chat room for admins --- .../chat/SystemChatRoomMessageIntent.java | 29 ++++++++++++ .../support/global/chat/ChatRoomHandler.java | 19 +++++++- .../support/global/chat/ChatRoomService.java | 24 ++++++++-- .../utilities/ChatRoomLogWrapper.java | 46 +++++++++++++++++++ 4 files changed, 114 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/projectswg/holocore/intents/support/global/chat/SystemChatRoomMessageIntent.java create mode 100644 src/main/java/com/projectswg/holocore/utilities/ChatRoomLogWrapper.java diff --git a/src/main/java/com/projectswg/holocore/intents/support/global/chat/SystemChatRoomMessageIntent.java b/src/main/java/com/projectswg/holocore/intents/support/global/chat/SystemChatRoomMessageIntent.java new file mode 100644 index 00000000..030a03bd --- /dev/null +++ b/src/main/java/com/projectswg/holocore/intents/support/global/chat/SystemChatRoomMessageIntent.java @@ -0,0 +1,29 @@ +package com.projectswg.holocore.intents.support.global.chat; + +import me.joshlarson.jlcommon.control.Intent; +import org.jetbrains.annotations.NotNull; + +public class SystemChatRoomMessageIntent extends Intent { + + private final String roomPath; + private final String message; + + public SystemChatRoomMessageIntent(@NotNull String roomPath, @NotNull String message) { + this.roomPath = roomPath; + this.message = message; + } + + @NotNull + public String getRoomPath() { + return roomPath; + } + + @NotNull + public String getMessage() { + return message; + } + + public static void broadcast(@NotNull String roomPath, @NotNull String message) { + new SystemChatRoomMessageIntent(roomPath, message).broadcast(); + } +} diff --git a/src/main/java/com/projectswg/holocore/resources/support/global/chat/ChatRoomHandler.java b/src/main/java/com/projectswg/holocore/resources/support/global/chat/ChatRoomHandler.java index b70b4dff..dddaf3a2 100644 --- a/src/main/java/com/projectswg/holocore/resources/support/global/chat/ChatRoomHandler.java +++ b/src/main/java/com/projectswg/holocore/resources/support/global/chat/ChatRoomHandler.java @@ -40,6 +40,7 @@ import com.projectswg.holocore.resources.support.data.server_info.CachedObjectDa import com.projectswg.holocore.resources.support.data.server_info.ObjectDatabase; import com.projectswg.holocore.resources.support.global.player.AccessLevel; import com.projectswg.holocore.resources.support.global.player.Player; +import com.projectswg.holocore.services.support.global.chat.ChatRoomService; import com.projectswg.holocore.services.support.global.zone.CharacterLookupService.PlayerLookup; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -85,6 +86,10 @@ public class ChatRoomHandler { for (String channel : player.getPlayerObject().getJoinedChannels()) { enterChatChannel(player, channel, false); } + + if (player.getAccessLevel() != AccessLevel.PLAYER) { + enterChatChannel(player, ChatRoomService.LOG_ROOM_PATH, true); + } } /** @@ -232,7 +237,14 @@ public class ChatRoomHandler { sendMessage(room, avatar, message, oobPackage); } } - + + public void sendMessageToRoomFromSystem(String path, String message, OutOfBandPackage oobPackage) { + ChatAvatar systemAvatar = ChatAvatar.getSystemAvatar(); + ChatRoom room = rooms.getRoomByPath(path); + + sendMessage(room, systemAvatar, message, oobPackage); + } + public boolean notifyDestroyRoom(ChatAvatar destroyer, String roomPath, int sequence) { ChatRoom room; @@ -272,6 +284,7 @@ public class ChatRoomHandler { rooms.handleRows((r) -> createRoom(systemAvatar, true, false, basePath + rooms.getCell(r, 0), (String) rooms.getCell(r, 1), false)); createPlanetChannels(systemAvatar, basePath); + createAdminChannels(systemAvatar, basePath); /* * Battlefield Room path examples: SWG.Bria.corellia.battlefield SWG.Bria.corellia.battlefield.corellia_mountain_fortress.allFactions SWG.Bria.corellia.battlefield.corellia_pvp.allFactions / Imperial / Rebel SWG.Bria.corellia.battlefield.corellia_rebel_riverside_fort.allFactions @@ -287,6 +300,10 @@ public class ChatRoomHandler { createRoom(systemAvatar, true, false, path + "Chat", "public chat for this planet, can create rooms here", false); }); } + + private void createAdminChannels(ChatAvatar systemAvatar, String basePath) { + createRoom(systemAvatar, false, false, ChatRoomService.LOG_ROOM_PATH, "server log", false); + } public ChatRoom getRoomById(int roomId) { return rooms.getRoomById(roomId); diff --git a/src/main/java/com/projectswg/holocore/services/support/global/chat/ChatRoomService.java b/src/main/java/com/projectswg/holocore/services/support/global/chat/ChatRoomService.java index 8486543f..77658bde 100644 --- a/src/main/java/com/projectswg/holocore/services/support/global/chat/ChatRoomService.java +++ b/src/main/java/com/projectswg/holocore/services/support/global/chat/ChatRoomService.java @@ -34,20 +34,26 @@ import com.projectswg.common.data.encodables.oob.OutOfBandPackage; import com.projectswg.common.network.packets.SWGPacket; import com.projectswg.common.network.packets.swg.zone.chat.*; import com.projectswg.common.network.packets.swg.zone.insertion.ChatRoomList; +import com.projectswg.holocore.ProjectSWG; import com.projectswg.holocore.intents.support.global.chat.ChatRoomMessageIntent; import com.projectswg.holocore.intents.support.global.chat.ChatRoomUpdateIntent; +import com.projectswg.holocore.intents.support.global.chat.SystemChatRoomMessageIntent; import com.projectswg.holocore.intents.support.global.network.InboundPacketIntent; import com.projectswg.holocore.intents.support.global.zone.PlayerEventIntent; import com.projectswg.holocore.resources.support.global.chat.ChatRoomHandler; import com.projectswg.holocore.resources.support.global.player.AccessLevel; import com.projectswg.holocore.resources.support.global.player.Player; import com.projectswg.holocore.services.support.global.zone.CharacterLookupService.PlayerLookup; +import com.projectswg.holocore.utilities.ChatRoomLogWrapper; import me.joshlarson.jlcommon.control.IntentHandler; import me.joshlarson.jlcommon.control.Service; +import me.joshlarson.jlcommon.log.Log; import org.jetbrains.annotations.NotNull; public class ChatRoomService extends Service { - + + public static final String LOG_ROOM_PATH = "SWG." + ProjectSWG.getGalaxy().getName() + ".admin.ServerLog"; + private final ChatRoomHandler chatRoomHandler; public ChatRoomService() { @@ -58,7 +64,14 @@ public class ChatRoomService extends Service { public boolean initialize() { return super.initialize() && chatRoomHandler.initialize(); } - + + @Override + public boolean start() { + Log.addWrapper(new ChatRoomLogWrapper(ChatRoomService.LOG_ROOM_PATH)); + + return super.start(); + } + @Override public boolean terminate() { return chatRoomHandler.terminate() && super.terminate(); @@ -119,7 +132,7 @@ public class ChatRoomService extends Service { @IntentHandler private void handlePlayerEventIntent(PlayerEventIntent pei) { switch (pei.getEvent()) { - case PE_FIRST_ZONE: + case PE_ZONE_IN_SERVER: chatRoomHandler.enterChatChannels(pei.getPlayer()); break; default: @@ -152,6 +165,11 @@ public class ChatRoomService extends Service { private void handleChatRoomMessageIntent(ChatRoomMessageIntent crmi) { chatRoomHandler.sendMessageToRoom(crmi.getPlayer(), crmi.getRoomPath(), 0, crmi.getMessage(), new OutOfBandPackage()); } + + @IntentHandler + private void handleSystemChatRoomMessageIntent(SystemChatRoomMessageIntent intent) { + chatRoomHandler.sendMessageToRoomFromSystem(intent.getRoomPath(), intent.getMessage(), new OutOfBandPackage()); + } /* Chat Rooms */ diff --git a/src/main/java/com/projectswg/holocore/utilities/ChatRoomLogWrapper.java b/src/main/java/com/projectswg/holocore/utilities/ChatRoomLogWrapper.java new file mode 100644 index 00000000..240b7a27 --- /dev/null +++ b/src/main/java/com/projectswg/holocore/utilities/ChatRoomLogWrapper.java @@ -0,0 +1,46 @@ +/*********************************************************************************** + * Copyright (c) 2018 /// Project SWG /// www.projectswg.com * + * * + * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on * + * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * + * Our goal is to create an emulator which will provide a server for players to * + * continue playing a game similar to the one they used to play. We are basing * + * it on the final publish of the game prior to end-game events. * + * * + * This file is part of Holocore. * + * * + * --------------------------------------------------------------------------------* + * * + * Holocore is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Affero General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * Holocore is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Affero General Public License for more details. * + * * + * You should have received a copy of the GNU Affero General Public License * + * along with Holocore. If not, see . * + ***********************************************************************************/ +package com.projectswg.holocore.utilities; + +import com.projectswg.holocore.intents.support.global.chat.SystemChatRoomMessageIntent; +import me.joshlarson.jlcommon.log.Log; +import me.joshlarson.jlcommon.log.LogWrapper; +import org.jetbrains.annotations.NotNull; + +public class ChatRoomLogWrapper implements LogWrapper { + + private final String roomPath; + + public ChatRoomLogWrapper(String roomPath) { + this.roomPath = roomPath; + } + + @Override + public void onLog(Log.@NotNull LogLevel level, @NotNull String str) { + SystemChatRoomMessageIntent.broadcast(roomPath, str); + } +} From d7b44fb79e7cc3d83e7594fd6c076b5be8d96f8a Mon Sep 17 00:00:00 2001 From: Mads Boddum Date: Sun, 11 Aug 2019 07:03:18 +0000 Subject: [PATCH 2/7] Added license header to SystemChatRoomMessageIntent --- .../chat/SystemChatRoomMessageIntent.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/main/java/com/projectswg/holocore/intents/support/global/chat/SystemChatRoomMessageIntent.java b/src/main/java/com/projectswg/holocore/intents/support/global/chat/SystemChatRoomMessageIntent.java index 030a03bd..87b66ae5 100644 --- a/src/main/java/com/projectswg/holocore/intents/support/global/chat/SystemChatRoomMessageIntent.java +++ b/src/main/java/com/projectswg/holocore/intents/support/global/chat/SystemChatRoomMessageIntent.java @@ -1,3 +1,29 @@ +/*********************************************************************************** + * Copyright (c) 2018 /// Project SWG /// www.projectswg.com * + * * + * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on * + * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * + * Our goal is to create an emulator which will provide a server for players to * + * continue playing a game similar to the one they used to play. We are basing * + * it on the final publish of the game prior to end-game events. * + * * + * This file is part of Holocore. * + * * + * --------------------------------------------------------------------------------* + * * + * Holocore is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Affero General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * Holocore is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Affero General Public License for more details. * + * * + * You should have received a copy of the GNU Affero General Public License * + * along with Holocore. If not, see . * + ***********************************************************************************/ package com.projectswg.holocore.intents.support.global.chat; import me.joshlarson.jlcommon.control.Intent; From 858fb7a592817467b0ffd671411f19e78602ea8d Mon Sep 17 00:00:00 2001 From: Ziggy Date: Sat, 7 Sep 2019 09:27:14 +0200 Subject: [PATCH 3/7] 143: Chat channels are now only entered when zoning in for the first time --- .../holocore/services/support/global/chat/ChatRoomService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/projectswg/holocore/services/support/global/chat/ChatRoomService.java b/src/main/java/com/projectswg/holocore/services/support/global/chat/ChatRoomService.java index 77658bde..7c216af4 100644 --- a/src/main/java/com/projectswg/holocore/services/support/global/chat/ChatRoomService.java +++ b/src/main/java/com/projectswg/holocore/services/support/global/chat/ChatRoomService.java @@ -132,7 +132,7 @@ public class ChatRoomService extends Service { @IntentHandler private void handlePlayerEventIntent(PlayerEventIntent pei) { switch (pei.getEvent()) { - case PE_ZONE_IN_SERVER: + case PE_FIRST_ZONE: chatRoomHandler.enterChatChannels(pei.getPlayer()); break; default: From 7c8bd3f6bc0062f45a3eb51c81ffa9a0eea5d3a2 Mon Sep 17 00:00:00 2001 From: Ziggy Date: Tue, 8 Oct 2019 11:39:45 +0200 Subject: [PATCH 4/7] Characters start with 5% block, dodge, evasion, parry, critical and strikethrough chance #178 --- .../player/experience/skills/SkillModService.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/SkillModService.java b/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/SkillModService.java index d426540b..c46543c5 100644 --- a/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/SkillModService.java +++ b/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/SkillModService.java @@ -121,6 +121,7 @@ public class SkillModService extends Service { updateLevelHAMValues(creature, newLevel, profession); updateLevelSkillModValues(creature, newLevel, profession, race); + grantBaseCombatChances(creature); } @IntentHandler @@ -215,6 +216,15 @@ public class SkillModService extends Service { } } + private void grantBaseCombatChances(CreatureObject creatureObject) { + creatureObject.adjustSkillmod("display_only_block", 500, 0); + creatureObject.adjustSkillmod("display_only_dodge", 500, 0); + creatureObject.adjustSkillmod("display_only_evasion", 500, 0); + creatureObject.adjustSkillmod("display_only_parry", 500, 0); + creatureObject.adjustSkillmod("display_only_critical", 500, 0); + creatureObject.adjustSkillmod("display_only_strikethrough", 500, 0); + } + private int getLevelSkillModValue(int level, String professionModName, String raceModName){ int skillModValue = 0; From 30cf2e253e88317d45b348ef1f3943035f8add37 Mon Sep 17 00:00:00 2001 From: Ziggy Date: Tue, 8 Oct 2019 11:42:19 +0200 Subject: [PATCH 5/7] Single target attacks may now be dodged #178 --- .../combat/command/CombatCommandAttack.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/projectswg/holocore/services/gameplay/combat/command/CombatCommandAttack.java b/src/main/java/com/projectswg/holocore/services/gameplay/combat/command/CombatCommandAttack.java index 813a98f9..528b9f3b 100644 --- a/src/main/java/com/projectswg/holocore/services/gameplay/combat/command/CombatCommandAttack.java +++ b/src/main/java/com/projectswg/holocore/services/gameplay/combat/command/CombatCommandAttack.java @@ -28,6 +28,7 @@ package com.projectswg.holocore.services.gameplay.combat.command; import com.projectswg.common.data.combat.*; +import com.projectswg.common.network.packets.swg.zone.object_controller.Animation; import com.projectswg.common.network.packets.swg.zone.object_controller.combat.CombatAction; import com.projectswg.common.network.packets.swg.zone.object_controller.combat.CombatAction.Defender; import com.projectswg.holocore.intents.gameplay.combat.EnterCombatIntent; @@ -40,6 +41,7 @@ import com.projectswg.holocore.resources.support.objects.swg.weapon.WeaponObject import java.util.Collection; import java.util.HashSet; import java.util.Set; +import java.util.concurrent.ThreadLocalRandom; import java.util.stream.Collectors; import static com.projectswg.holocore.services.gameplay.combat.command.CombatCommandCommon.*; @@ -84,6 +86,12 @@ enum CombatCommandAttack implements CombatCommandHitType { private static void doCombatSingle(CreatureObject source, SWGObject target, AttackInfo info, WeaponObject weapon, CombatCommand command) { // TODO single target only defence rolls against target + if (target instanceof CreatureObject && isAttackDodged(source, (CreatureObject) target)) { + info.setDodge(true); + info.setSuccess(false); // This means that the attack did no damage to the target at all + target.sendObservers(new Animation(target.getObjectId(), "dodge")); + } + // TODO single target only offence rolls for source // TODO below logic should be in CommandService when target checks are implemented in there @@ -133,7 +141,8 @@ enum CombatCommandAttack implements CombatCommandHitType { if (!info.isSuccess()) { // Single target negate, like dodge or parry! target.sendObservers(createCombatSpam(source, target, weapon, info, command)); - return; + action.addDefender(new Defender(target.getObjectId(), target.getPosture(), false, (byte) 4, HitLocation.HIT_LOCATION_BODY, (short) 0)); + continue; // This target negated the attack completely - move on to the next target } addBuff(source, target, command.getBuffNameTarget()); // Add target buff @@ -232,4 +241,11 @@ enum CombatCommandAttack implements CombatCommandHitType { } + private static boolean isAttackDodged(CreatureObject source, CreatureObject target) { + double dodgeChance = (target.getSkillModValue("display_only_dodge") - source.getSkillModValue("display_only_opp_dodge_reduction")) / 100; + double roll = ThreadLocalRandom.current().nextDouble(100); // Generate number between 0 and 100 + + return roll <= dodgeChance; // If dodge chance is 25%, then the roll should be between 0 and 25 (both inclusive) + } + } From 3a2298bb53ed42d410d190df29bd3ea1291051d6 Mon Sep 17 00:00:00 2001 From: Ziggy Date: Tue, 8 Oct 2019 11:46:45 +0200 Subject: [PATCH 6/7] clientEffectId back to 0 #178 --- .../services/gameplay/combat/command/CombatCommandAttack.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/projectswg/holocore/services/gameplay/combat/command/CombatCommandAttack.java b/src/main/java/com/projectswg/holocore/services/gameplay/combat/command/CombatCommandAttack.java index 528b9f3b..be7bf78c 100644 --- a/src/main/java/com/projectswg/holocore/services/gameplay/combat/command/CombatCommandAttack.java +++ b/src/main/java/com/projectswg/holocore/services/gameplay/combat/command/CombatCommandAttack.java @@ -141,7 +141,7 @@ enum CombatCommandAttack implements CombatCommandHitType { if (!info.isSuccess()) { // Single target negate, like dodge or parry! target.sendObservers(createCombatSpam(source, target, weapon, info, command)); - action.addDefender(new Defender(target.getObjectId(), target.getPosture(), false, (byte) 4, HitLocation.HIT_LOCATION_BODY, (short) 0)); + action.addDefender(new Defender(target.getObjectId(), target.getPosture(), false, (byte) 0, HitLocation.HIT_LOCATION_BODY, (short) 0)); continue; // This target negated the attack completely - move on to the next target } From 3e59185bf7ee1d12a03888d76babe2d97c1bd90c Mon Sep 17 00:00:00 2001 From: Ziggy Date: Tue, 8 Oct 2019 15:25:13 +0200 Subject: [PATCH 7/7] Stat mods now also add relevant skill mods #29 --- .../experience/skills/ProtectionService.java | 15 ------ .../experience/skills/SkillManager.java | 1 + .../{ => skillmod}/SkillModService.java | 53 ++++++++++++++++--- .../adjust/AgilityAdjustFunction.java | 23 ++++++++ .../adjust/InnateArmorAdjustFunction.java | 23 ++++++++ .../skillmod/adjust/LuckAdjustFunction.java | 27 ++++++++++ .../adjust/PrecisionAdjustFunction.java | 24 +++++++++ .../adjust/SingleModAdjustFunction.java | 25 +++++++++ .../skillmod/adjust/SkillModAdjust.java | 25 +++++++++ .../adjust/StrengthAdjustFunction.java | 18 +++++++ 10 files changed, 211 insertions(+), 23 deletions(-) rename src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/{ => skillmod}/SkillModService.java (85%) create mode 100644 src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/skillmod/adjust/AgilityAdjustFunction.java create mode 100644 src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/skillmod/adjust/InnateArmorAdjustFunction.java create mode 100644 src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/skillmod/adjust/LuckAdjustFunction.java create mode 100644 src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/skillmod/adjust/PrecisionAdjustFunction.java create mode 100644 src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/skillmod/adjust/SingleModAdjustFunction.java create mode 100644 src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/skillmod/adjust/SkillModAdjust.java create mode 100644 src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/skillmod/adjust/StrengthAdjustFunction.java diff --git a/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/ProtectionService.java b/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/ProtectionService.java index 17efd38e..d373672a 100644 --- a/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/ProtectionService.java +++ b/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/ProtectionService.java @@ -98,21 +98,6 @@ public class ProtectionService extends Service { } } - @IntentHandler - private void handleSkillModIntent(SkillModIntent intent) { - // Modify protection values if an innate armor skillmod is being granted - String skillModName = intent.getSkillModName(); - - if ("expertise_innate_protection_all".equals(skillModName)) { - new SkillModIntent("kinetic", intent.getAdjustBase(), intent.getAdjustModifier(), intent.getAffectedCreatures()).broadcast(); - new SkillModIntent("energy", intent.getAdjustBase(), intent.getAdjustModifier(), intent.getAffectedCreatures()).broadcast(); - new SkillModIntent("heat", intent.getAdjustBase(), intent.getAdjustModifier(), intent.getAffectedCreatures()).broadcast(); - new SkillModIntent("cold", intent.getAdjustBase(), intent.getAdjustModifier(), intent.getAffectedCreatures()).broadcast(); - new SkillModIntent("acid", intent.getAdjustBase(), intent.getAdjustModifier(), intent.getAffectedCreatures()).broadcast(); - new SkillModIntent("electricity", intent.getAdjustBase(), intent.getAdjustModifier(), intent.getAffectedCreatures()).broadcast(); - } - } - private void handleTransfer(SWGObject item, CreatureObject container, boolean equip) { switch (item.getGameObjectType()) { case GOT_CLOTHING_CLOAK: diff --git a/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/SkillManager.java b/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/SkillManager.java index 94776095..c5a59419 100644 --- a/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/SkillManager.java +++ b/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/SkillManager.java @@ -26,6 +26,7 @@ ***********************************************************************************/ package com.projectswg.holocore.services.gameplay.player.experience.skills; +import com.projectswg.holocore.services.gameplay.player.experience.skills.skillmod.SkillModService; import me.joshlarson.jlcommon.control.Manager; import me.joshlarson.jlcommon.control.ManagerStructure; diff --git a/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/SkillModService.java b/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/skillmod/SkillModService.java similarity index 85% rename from src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/SkillModService.java rename to src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/skillmod/SkillModService.java index d426540b..4b5680a0 100644 --- a/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/SkillModService.java +++ b/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/skillmod/SkillModService.java @@ -24,7 +24,7 @@ * You should have received a copy of the GNU Affero General Public License * * along with Holocore. If not, see . * ***********************************************************************************/ -package com.projectswg.holocore.services.gameplay.player.experience.skills; +package com.projectswg.holocore.services.gameplay.player.experience.skills.skillmod; import com.projectswg.common.data.encodables.tangible.Race; import com.projectswg.common.data.info.RelationalServerData; @@ -38,6 +38,7 @@ import com.projectswg.holocore.resources.support.global.player.Player; import com.projectswg.holocore.resources.support.objects.swg.creature.CreatureObject; import com.projectswg.holocore.resources.support.objects.swg.player.PlayerObject; import com.projectswg.holocore.resources.support.objects.swg.player.Profession; +import com.projectswg.holocore.services.gameplay.player.experience.skills.skillmod.adjust.*; import com.projectswg.holocore.utilities.IntentFactory; import me.joshlarson.jlcommon.control.IntentHandler; import me.joshlarson.jlcommon.control.Service; @@ -46,8 +47,8 @@ import me.joshlarson.jlcommon.log.Log; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.Locale; -import java.util.Map; +import java.util.*; +import java.util.function.Function; public class SkillModService extends Service { @@ -62,6 +63,9 @@ public class SkillModService extends Service { private final RelationalServerData racialStatsDatabase; private final PreparedStatement getPlayerLevelStatement; private final PreparedStatement getRacialStatsStatement; + + private final Map>> skillModAdjusters; + public SkillModService() { playerLevelDatabase = RelationalServerFactory.getServerData("player/player_levels.db", "player_levels"); @@ -74,7 +78,18 @@ public class SkillModService extends Service { if (racialStatsDatabase == null) throw new ProjectSWG.CoreException("Unable to load racial_stats.sdb file for SkillTemplateService"); - getRacialStatsStatement = racialStatsDatabase.prepareStatement(GET_RACIAL_STATS_SQL); + getRacialStatsStatement = racialStatsDatabase.prepareStatement(GET_RACIAL_STATS_SQL); + + skillModAdjusters = Map.of( + "agility_modified", new AgilityAdjustFunction(), + "luck_modified", new LuckAdjustFunction(), + "precision_modified", new PrecisionAdjustFunction(), + "strength_modified", new StrengthAdjustFunction(), + "expertise_dodge", new SingleModAdjustFunction("display_only_dodge", 100), + "expertise_innate_protection_all", new InnateArmorAdjustFunction(), + "expertise_innate_protection_kinetic", new SingleModAdjustFunction("kinetic"), + "expertise_innate_protection_energy", new SingleModAdjustFunction("energy") + ); } @Override @@ -140,8 +155,30 @@ public class SkillModService extends Service { for (CreatureObject creature : smi.getAffectedCreatures()) { String skillModName = smi.getSkillModName(); - creature.adjustSkillmod(skillModName, smi.getAdjustBase(), smi.getAdjustModifier()); - updateSkillModHamValues(creature, skillModName, smi.getAdjustBase() + smi.getAdjustModifier()); + int adjustBase = smi.getAdjustBase(); + int adjustModifier = smi.getAdjustModifier(); + + adjustSkillmod(creature, skillModName, adjustBase, adjustModifier); + updateSkillModHamValues(creature, skillModName, adjustBase + adjustModifier); + } + } + + private void adjustSkillmod(CreatureObject creature, String skillModName, int adjustBase, int adjustModifier) { + creature.adjustSkillmod(skillModName, adjustBase, adjustModifier); + + if (skillModAdjusters.containsKey(skillModName)) { + Function> modIntentConsumer = skillModAdjusters.get(skillModName); + SkillModAdjust inputAdjust = new SkillModAdjust(skillModName, adjustBase, adjustModifier); + + Collection outputAdjusts = modIntentConsumer.apply(inputAdjust); + + for (SkillModAdjust outputAdjust : outputAdjusts) { + int outputBase = outputAdjust.getBase(); + int outputModifier = outputAdjust.getModifier(); + String outputName = outputAdjust.getName(); + + adjustSkillmod(creature, outputName, outputBase, outputModifier); + } } } @@ -203,8 +240,8 @@ public class SkillModService extends Service { oldSkillModValue = creature.getSkillModValue(type.toString().toLowerCase(Locale.US)); if (skillModValue > oldSkillModValue){ - creature.adjustSkillmod(type.toString().toLowerCase(Locale.US), 0, -creature.getSkillModValue(type.toString().toLowerCase(Locale.US))); - creature.adjustSkillmod(type.toString().toLowerCase(Locale.US), 0, skillModValue); + adjustSkillmod(creature, type.toString().toLowerCase(Locale.US), 0, -creature.getSkillModValue(type.toString().toLowerCase(Locale.US))); + adjustSkillmod(creature, type.toString().toLowerCase(Locale.US), 0, skillModValue); if (type == SkillModTypes.CONSTITUTION_MODIFIED || type == SkillModTypes.STAMINA_MODIFIED) updateSkillModHamValues(creature, type.toString().toLowerCase(Locale.US),skillModValue - oldSkillModValue); diff --git a/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/skillmod/adjust/AgilityAdjustFunction.java b/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/skillmod/adjust/AgilityAdjustFunction.java new file mode 100644 index 00000000..2bd508a2 --- /dev/null +++ b/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/skillmod/adjust/AgilityAdjustFunction.java @@ -0,0 +1,23 @@ +package com.projectswg.holocore.services.gameplay.player.experience.skills.skillmod.adjust; + +import java.util.Arrays; +import java.util.Collection; +import java.util.function.Function; + +public class AgilityAdjustFunction implements Function> { + @Override + public Collection apply(SkillModAdjust skillModAdjust) { + int adjustBase = skillModAdjust.getBase(); + int adjustModifier = skillModAdjust.getModifier(); + + int adjustBaseTwoToOne = (int) Math.ceil(adjustBase / 2f); + int adjustModifierTwoToOne = (int) Math.ceil(adjustModifier / 2f); + + return Arrays.asList( + new SkillModAdjust("display_only_dodge", adjustBase, adjustModifier), + new SkillModAdjust("display_only_parry", adjustBaseTwoToOne, adjustModifierTwoToOne), + new SkillModAdjust("display_only_evasion", adjustBase, adjustModifier) + + ); + } +} diff --git a/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/skillmod/adjust/InnateArmorAdjustFunction.java b/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/skillmod/adjust/InnateArmorAdjustFunction.java new file mode 100644 index 00000000..037e18ff --- /dev/null +++ b/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/skillmod/adjust/InnateArmorAdjustFunction.java @@ -0,0 +1,23 @@ +package com.projectswg.holocore.services.gameplay.player.experience.skills.skillmod.adjust; + +import java.util.Arrays; +import java.util.Collection; +import java.util.function.Function; + +public class InnateArmorAdjustFunction implements Function> { + + @Override + public Collection apply(SkillModAdjust skillModAdjust) { + int adjustBase = skillModAdjust.getBase(); + int adjustModifier = skillModAdjust.getModifier(); + + return Arrays.asList( + new SkillModAdjust("kinetic", adjustBase, adjustModifier), + new SkillModAdjust("energy", adjustBase, adjustModifier), + new SkillModAdjust("heat", adjustBase, adjustModifier), + new SkillModAdjust("cold", adjustBase, adjustModifier), + new SkillModAdjust("acid", adjustBase, adjustModifier), + new SkillModAdjust("electricity", adjustBase, adjustModifier) + ); + } +} diff --git a/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/skillmod/adjust/LuckAdjustFunction.java b/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/skillmod/adjust/LuckAdjustFunction.java new file mode 100644 index 00000000..f25a5037 --- /dev/null +++ b/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/skillmod/adjust/LuckAdjustFunction.java @@ -0,0 +1,27 @@ +package com.projectswg.holocore.services.gameplay.player.experience.skills.skillmod.adjust; + +import java.util.Arrays; +import java.util.Collection; +import java.util.function.Function; + +public class LuckAdjustFunction implements Function> { + @Override + public Collection apply(SkillModAdjust skillModAdjust) { + int adjustBase = skillModAdjust.getBase(); + int adjustModifier = skillModAdjust.getModifier(); + + int adjustBaseThreeToOne = (int) Math.ceil(adjustBase / 3f); + int adjustModifierThreeToOne = (int) Math.ceil(adjustModifier / 3f); + + int adjustBaseTwoToOne = (int) Math.ceil(adjustBase / 2f); + int adjustModifierTwoToOne = (int) Math.ceil(adjustModifier / 2f); + + return Arrays.asList( + new SkillModAdjust("display_only_dodge", adjustBaseThreeToOne, adjustModifierThreeToOne), + new SkillModAdjust("display_only_evasion", adjustBaseThreeToOne, adjustModifierThreeToOne), + new SkillModAdjust("display_only_critical", adjustBaseThreeToOne, adjustModifierThreeToOne), + new SkillModAdjust("display_only_strikethrough", adjustBaseTwoToOne, adjustModifierTwoToOne) + + ); + } +} diff --git a/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/skillmod/adjust/PrecisionAdjustFunction.java b/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/skillmod/adjust/PrecisionAdjustFunction.java new file mode 100644 index 00000000..4bb6c49c --- /dev/null +++ b/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/skillmod/adjust/PrecisionAdjustFunction.java @@ -0,0 +1,24 @@ +package com.projectswg.holocore.services.gameplay.player.experience.skills.skillmod.adjust; + +import java.util.Arrays; +import java.util.Collection; +import java.util.function.Function; + +public class PrecisionAdjustFunction implements Function> { + @Override + public Collection apply(SkillModAdjust skillModAdjust) { + int adjustBase = skillModAdjust.getBase(); + int adjustModifier = skillModAdjust.getModifier(); + + int adjustBaseTwoToOne = (int) Math.ceil(adjustBase / 2f); + int adjustModifierTwoToOne = (int) Math.ceil(adjustModifier / 2f); + + return Arrays.asList( + new SkillModAdjust("display_only_parry", adjustBaseTwoToOne, adjustModifierTwoToOne), + new SkillModAdjust("display_only_block", adjustBaseTwoToOne, adjustModifierTwoToOne), + new SkillModAdjust("display_only_critical", adjustBase, adjustModifier), + new SkillModAdjust("display_only_strikethrough", adjustBaseTwoToOne, adjustModifierTwoToOne) + + ); + } +} diff --git a/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/skillmod/adjust/SingleModAdjustFunction.java b/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/skillmod/adjust/SingleModAdjustFunction.java new file mode 100644 index 00000000..71a339e8 --- /dev/null +++ b/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/skillmod/adjust/SingleModAdjustFunction.java @@ -0,0 +1,25 @@ +package com.projectswg.holocore.services.gameplay.player.experience.skills.skillmod.adjust; + +import java.util.Collection; +import java.util.Collections; +import java.util.function.Function; + +public class SingleModAdjustFunction implements Function> { + + private final String skillModName; + private final int multiplier; + + public SingleModAdjustFunction(String skillModName, int multiplier) { + this.skillModName = skillModName; + this.multiplier = multiplier; + } + + public SingleModAdjustFunction(String skillModName) { + this(skillModName, 1); + } + + @Override + public Collection apply(SkillModAdjust skillModAdjust) { + return Collections.singleton(new SkillModAdjust(skillModName, skillModAdjust.getBase() * multiplier, skillModAdjust.getModifier() * multiplier)); + } +} diff --git a/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/skillmod/adjust/SkillModAdjust.java b/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/skillmod/adjust/SkillModAdjust.java new file mode 100644 index 00000000..993a0c14 --- /dev/null +++ b/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/skillmod/adjust/SkillModAdjust.java @@ -0,0 +1,25 @@ +package com.projectswg.holocore.services.gameplay.player.experience.skills.skillmod.adjust; + +public class SkillModAdjust { + private final String name; + private final int base; + private final int modifier; + + public SkillModAdjust(String name, int base, int modifier) { + this.name = name; + this.base = base; + this.modifier = modifier; + } + + public String getName() { + return name; + } + + public int getBase() { + return base; + } + + public int getModifier() { + return modifier; + } +} diff --git a/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/skillmod/adjust/StrengthAdjustFunction.java b/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/skillmod/adjust/StrengthAdjustFunction.java new file mode 100644 index 00000000..66d9ac55 --- /dev/null +++ b/src/main/java/com/projectswg/holocore/services/gameplay/player/experience/skills/skillmod/adjust/StrengthAdjustFunction.java @@ -0,0 +1,18 @@ +package com.projectswg.holocore.services.gameplay.player.experience.skills.skillmod.adjust; + +import java.util.Collection; +import java.util.Collections; +import java.util.function.Function; + +public class StrengthAdjustFunction implements Function> { + @Override + public Collection apply(SkillModAdjust skillModAdjust) { + int adjustBase = skillModAdjust.getBase(); + int adjustModifier = skillModAdjust.getModifier(); + + int adjustBaseTwoToOne = (int) Math.ceil(adjustBase / 2f); + int adjustModifierTwoToOne = (int) Math.ceil(adjustModifier / 2f); + + return Collections.singleton(new SkillModAdjust("display_only_block", adjustBaseTwoToOne, adjustModifierTwoToOne)); + } +}