Skip to content

Commit ba1c35b

Browse files
committed
Some randomness improvements
1 parent 2d8238c commit ba1c35b

File tree

5 files changed

+69
-6
lines changed

5 files changed

+69
-6
lines changed

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ java {
2121
toolchain.languageVersion.set(JavaLanguageVersion.of(21))
2222
}
2323

24-
val papyrusVersion = "1.21.7-R0.1-SNAPSHOT"
24+
val papyrusVersion = "1.21.8-R0.1-SNAPSHOT"
2525
paperweight.reobfArtifactConfiguration = io.papermc.paperweight.userdev.ReobfArtifactConfiguration.MOJANG_PRODUCTION
2626

2727
dependencies {

src/main/java/de/erethon/aether/combat/SpellCastEntry.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import de.erethon.aether.Aether;
44
import de.erethon.spellbook.api.SpellData;
5+
import de.erethon.spellbook.api.SpellLibrary;
6+
import org.bukkit.Bukkit;
57
import org.bukkit.configuration.ConfigurationSection;
68

79
public class SpellCastEntry {
@@ -10,7 +12,7 @@ public class SpellCastEntry {
1012
private SpellData spell;
1113
private double chance;
1214

13-
//private SpellLibrary library = Bukkit.getServer().getSpellbookAPI().getLibrary();
15+
private final SpellLibrary library = Bukkit.getServer().getSpellbookAPI().getLibrary();
1416

1517

1618
public boolean canCast() {
@@ -23,7 +25,7 @@ public SpellData getSpell() {
2325

2426
public void load(String loadingID, ConfigurationSection section) {
2527
name = section.getName();
26-
spell = null; //library.getSpellByID(section.getName());
28+
spell = library.getSpellByID(section.getName());
2729
if (spell == null) {
2830
Aether.addException(loadingID, "Spell not found: " + section.getName(), "Check if the Spellbook spell exists and is loaded", null);
2931
Aether.log("Spell not found: " + section.getName());

src/main/java/de/erethon/aether/creature/AetherBaseMob.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,11 @@ public AetherBaseMob(NPCData data, World world) {
115115
public AetherBaseMob(NPCData data, World world, Integer overrideLevel) {
116116
super((EntityType<? extends Monster>) data.getDisplayType(), ((CraftWorld) world).getHandle());
117117
this.data = data;
118+
this.displayType = data.getDisplayType();
118119

119120
if (data.hasLevels()) {
120121
mobLevel = Objects.requireNonNullElseGet(overrideLevel, data::selectRandomLevel);
121-
levelInfo = data.getLevelInfoForLevel(mobLevel);
122+
levelInfo = data.getCompositeLevelInfoForLevel(mobLevel);
122123
Aether.log("Spawned " + data.getID() + " at level " + mobLevel);
123124
}
124125

@@ -573,13 +574,14 @@ public void readAdditionalSaveData(ValueInput input) {
573574
remove(RemovalReason.DISCARDED);
574575
return;
575576
}
577+
this.displayType = data.getDisplayType();
576578
Optional<Integer> papyrusVersion = input.getInt("papyrus-entity-version");
577579
version = papyrusVersion.orElse(0);
578580

579581
Optional<Integer> savedLevel = input.getInt("aether-mob-level");
580582
if (savedLevel.isPresent()) {
581583
mobLevel = savedLevel.get();
582-
levelInfo = data.getLevelInfoForLevel(mobLevel);
584+
levelInfo = data.getCompositeLevelInfoForLevel(mobLevel);
583585
Aether.log("Loaded " + data.getID() + " at level " + mobLevel);
584586
}
585587

src/main/java/de/erethon/aether/creature/CreatureManager.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,9 @@ public void loadSub(File file) {
7474
}
7575
if (f.isDirectory()) {
7676
loadSub(f);
77+
continue;
7778
}
78-
loadNPCFile(file);
79+
loadNPCFile(f);
7980
}
8081
}
8182

src/main/java/de/erethon/aether/creature/NPCData.java

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,64 @@ public MobLevelInfo getLevelInfoForLevel(int level) {
795795
return bestLevel != -1 ? levelInfo.get(bestLevel) : null;
796796
}
797797

798+
/**
799+
* Gets composite level info for a mob level, finding the best available configuration
800+
* for each attribute individually. If a specific attribute isn't configured at the
801+
* exact level, it falls back to the highest configured level below it.
802+
*/
803+
public MobLevelInfo getCompositeLevelInfoForLevel(int level) {
804+
if (levelInfo.isEmpty()) {
805+
return null;
806+
}
807+
808+
// Always build composite attribute bonuses by finding best level for each attribute
809+
// This ensures attributes "fall through" from lower levels when not defined at higher levels
810+
Map<org.bukkit.attribute.Attribute, MobAttributeRange> compositeAttributes = new HashMap<>();
811+
812+
// Collect all unique attributes across all levels
813+
Set<org.bukkit.attribute.Attribute> allAttributes = new HashSet<>();
814+
for (MobLevelInfo info : levelInfo.values()) {
815+
allAttributes.addAll(info.baseAttributeBonus().keySet());
816+
}
817+
818+
// For each attribute, find the best available level
819+
for (org.bukkit.attribute.Attribute attribute : allAttributes) {
820+
int bestLevelForAttribute = -1;
821+
822+
for (int configuredLevel : levelInfo.keySet()) {
823+
MobLevelInfo info = levelInfo.get(configuredLevel);
824+
// Only consider levels at or below the target level that have this specific attribute
825+
if (configuredLevel <= level &&
826+
info.baseAttributeBonus().containsKey(attribute) &&
827+
configuredLevel > bestLevelForAttribute) {
828+
bestLevelForAttribute = configuredLevel;
829+
}
830+
}
831+
832+
if (bestLevelForAttribute != -1) {
833+
MobLevelInfo bestInfo = levelInfo.get(bestLevelForAttribute);
834+
compositeAttributes.put(attribute, bestInfo.baseAttributeBonus().get(attribute));
835+
Aether.log("Using level " + bestLevelForAttribute + " configuration for attribute " +
836+
attribute.getKey() + " on mob level " + level);
837+
}
838+
}
839+
840+
// For loot, use the highest configured level at or below the target level
841+
MobLevelLoot compositeLoot = null;
842+
int bestLootLevel = -1;
843+
for (int configuredLevel : levelInfo.keySet()) {
844+
if (configuredLevel <= level && configuredLevel > bestLootLevel) {
845+
MobLevelInfo info = levelInfo.get(configuredLevel);
846+
if (info.loot() != null) {
847+
bestLootLevel = configuredLevel;
848+
compositeLoot = info.loot();
849+
}
850+
}
851+
}
852+
853+
return new MobLevelInfo(level, compositeAttributes, compositeLoot);
854+
}
855+
798856
@Override
799857
public String toString() {
800858
return "NPCData{" +

0 commit comments

Comments
 (0)