From 2e5ae5155d95d5dd797a618f135bc6dd82acafb3 Mon Sep 17 00:00:00 2001 From: Ziggy Date: Sun, 30 Apr 2023 13:26:01 +0200 Subject: [PATCH] [Misc] CombatExperienceService uses the NpcStat DataLoader instead of parsing the sdb itself with the deprecated RelationalServerFactory --- .../combat/CombatExperienceService.java | 107 ++++++------------ 1 file changed, 36 insertions(+), 71 deletions(-) diff --git a/src/main/java/com/projectswg/holocore/services/gameplay/combat/CombatExperienceService.java b/src/main/java/com/projectswg/holocore/services/gameplay/combat/CombatExperienceService.java index 041118a1a..7f9df4167 100644 --- a/src/main/java/com/projectswg/holocore/services/gameplay/combat/CombatExperienceService.java +++ b/src/main/java/com/projectswg/holocore/services/gameplay/combat/CombatExperienceService.java @@ -26,71 +26,39 @@ ***********************************************************************************/ package com.projectswg.holocore.services.gameplay.combat; -import com.projectswg.common.data.info.RelationalDatabase; -import com.projectswg.common.data.info.RelationalServerFactory; import com.projectswg.common.data.objects.GameObjectType; import com.projectswg.holocore.intents.gameplay.combat.CreatureKilledIntent; import com.projectswg.holocore.intents.gameplay.player.experience.ExperienceIntent; +import com.projectswg.holocore.resources.support.data.server_info.loader.DataLoader; +import com.projectswg.holocore.resources.support.data.server_info.loader.npc.NpcStatLoader; import com.projectswg.holocore.resources.support.objects.swg.creature.CreatureDifficulty; import com.projectswg.holocore.resources.support.objects.swg.creature.CreatureObject; import com.projectswg.holocore.resources.support.objects.swg.group.GroupObject; -import com.projectswg.holocore.resources.support.data.server_info.StandardLog; import com.projectswg.holocore.resources.support.objects.swg.weapon.WeaponType; import com.projectswg.holocore.services.support.objects.ObjectStorageService; import me.joshlarson.jlcommon.control.IntentHandler; import me.joshlarson.jlcommon.control.Service; import me.joshlarson.jlcommon.log.Log; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.HashMap; -import java.util.Map; - public class CombatExperienceService extends Service { - - private final Map xpData; - public CombatExperienceService() { - xpData = new HashMap<>(); - } - - @Override - public boolean initialize() { - loadXpData(); - return true; - } - - private void loadXpData() { - long startTime = StandardLog.onStartLoad("combat XP rates"); - try (RelationalDatabase npcStats = RelationalServerFactory.getServerData("npc/npc_stats.db", "npc_stats")) { - try (ResultSet set = npcStats.executeQuery("SELECT * FROM npc_stats")) { - while (set.next()) { - xpData.put(set.getShort("Level"), new XpData(set.getInt("XP"), set.getInt("Elite_XP"), set.getInt("Boss_XP"))); - } - } catch (SQLException e) { - Log.e(e); - } - } - StandardLog.onEndLoad(xpData.size(), "combat XP rates", startTime); - } - @IntentHandler private void handleCreatureKilledIntent(CreatureKilledIntent i) { CreatureObject corpse = i.getCorpse(); - - if(corpseIsNpc(corpse)) { + + if (corpseIsNpc(corpse)) { CreatureObject killer = i.getKiller(); GroupObject group = getGroupThatKillerIsIn(killer); - + short killerLevel = getKillerLevel(killer, group); int experienceGained = calculateXpGain(killer, corpse, killerLevel); - + if (experienceGained <= 0) { return; } - + boolean killerIsGrouped = group != null; - + if (killerIsGrouped) { grantXpToGroup(corpse, group, experienceGained); } else { @@ -98,7 +66,7 @@ public class CombatExperienceService extends Service { } } } - + private GroupObject getGroupThatKillerIsIn(CreatureObject killer) { long groupId = killer.getGroupId(); if (groupId > 0) { @@ -107,18 +75,19 @@ public class CombatExperienceService extends Service { return null; } } - + private void grantXpToGroup(CreatureObject corpse, GroupObject group, int experienceGained) { - group.getGroupMemberObjects().stream() + group.getGroupMemberObjects() + .stream() .filter(groupMember -> isMemberNearby(corpse, groupMember)) .filter(groupMember -> didMemberParticipateInCombat(corpse, groupMember)) .forEach(eligibleMember -> grantXpToKiller(eligibleMember, corpse, experienceGained)); } - + private boolean didMemberParticipateInCombat(CreatureObject corpse, CreatureObject groupMember) { return corpse.getHateMap().containsKey(groupMember); } - + private short getKillerLevel(CreatureObject killer, GroupObject group) { if (group != null) { return group.getLevel(); @@ -126,53 +95,53 @@ public class CombatExperienceService extends Service { return killer.getLevel(); } } - + private boolean corpseIsNpc(CreatureObject corpse) { return !corpse.isPlayer(); } - + private void grantXpToKiller(CreatureObject killer, CreatureObject corpse, int experienceGained) { boolean xpMultiply = experienceGained > 1; grantWeaponTypeXp(killer, corpse, experienceGained, xpMultiply); - + if (scoutKilledCreature(killer, corpse)) { grantTrappingXp(killer, experienceGained); } - + grantCombatXp(killer, corpse, experienceGained, xpMultiply); } - + private void grantTrappingXp(CreatureObject receiver, int experienceGained) { new ExperienceIntent(receiver, "trapping", (int) Math.ceil(experienceGained / 10f)).broadcast(); } - + private boolean scoutKilledCreature(CreatureObject killer, CreatureObject corpse) { return isKillerScout(killer) && isCorpseCreature(corpse); } - + private boolean isCorpseCreature(CreatureObject corpse) { return corpse.getGameObjectType() == GameObjectType.GOT_CREATURE; } - + private boolean isKillerScout(CreatureObject killer) { return killer.hasSkill("outdoors_scout_novice"); } - + private void grantCombatXp(CreatureObject receiver, CreatureObject corpse, int experienceGained, boolean xpMultiply) { new ExperienceIntent(receiver, corpse, "combat_general", (int) Math.ceil(experienceGained / 10f), xpMultiply).broadcast(); } - + private void grantWeaponTypeXp(CreatureObject receiver, CreatureObject corpse, int experienceGained, boolean xpMultiply) { WeaponType weaponType = receiver.getEquippedWeapon().getType(); String xpType = xpTypeForWeaponType(weaponType); - + if (xpType == null) { Log.w("%s did not receive %d xp because the used weapon %s had unrecognized type", receiver, experienceGained, weaponType); } - + new ExperienceIntent(receiver, corpse, xpType, experienceGained, xpMultiply).broadcast(); } - + private String xpTypeForWeaponType(WeaponType weaponType) { return switch (weaponType) { case UNARMED -> "combat_meleespecialize_unarmed"; @@ -187,16 +156,16 @@ public class CombatExperienceService extends Service { default -> null; }; } - + private int calculateXpGain(CreatureObject killer, CreatureObject corpse, short killerLevel) { short corpseLevel = corpse.getLevel(); - + if (killerLevel - corpseLevel >= 5) { return 1; } else { - XpData xpForLevel = this.xpData.get(corpseLevel); + NpcStatLoader.NpcStatInfo npcStats = DataLoader.Companion.npcStats().getNpcStats(corpseLevel); - if (xpForLevel == null) { + if (npcStats == null) { Log.e("%s received no XP: No XP data was found for level %d!", killer, corpseLevel); return 0; } @@ -204,15 +173,15 @@ public class CombatExperienceService extends Service { CreatureDifficulty creatureDifficulty = corpse.getDifficulty(); return switch (creatureDifficulty) { - case BOSS -> xpForLevel.bossXp(); - case ELITE -> xpForLevel.eliteXp(); - case NORMAL -> xpForLevel.xp(); + case BOSS -> npcStats.getBossDetailStat().getXp(); + case ELITE -> npcStats.getEliteDetailStat().getXp(); + case NORMAL -> npcStats.getNormalDetailStat().getXp(); }; } } - + /** - * @param corpse of the NPC that was killed + * @param corpse of the NPC that was killed * @param groupMember of the group that killed the NPC * @return true if {@code groupMember} is close enough to the corpse to gain XP */ @@ -220,8 +189,4 @@ public class CombatExperienceService extends Service { return corpse.distanceTo(groupMember) <= 128; } - private record XpData(int xp, int eliteXp, int bossXp) { - - } - }