MobBase walk/walkCombat/run/runCombat now come from rune_speed WALK/COMBATWALK/RUN/COMBATRUN instead of static_npc_mobbase_race. Parity (JSON-Refactor-Plan/scripts/p33.py, compared as Java floats): 2375/2375 loaded mobbases identical, every one has a race row on dev. No value changes. The 253 unused race rows (no mobbase) and the fly/swim columns had no reader. LOAD_ALL_MOBBASE_SPEEDS and static_npc_mobbase_race are now unread; they go in Task 3.6. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
277 lines
8.2 KiB
Java
277 lines
8.2 KiB
Java
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
|
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
|
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
|
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
|
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
|
// Magicbane Emulator Project © 2013 - 2026
|
|
// https://www.magicbane.com
|
|
|
|
|
|
package engine.objects;
|
|
|
|
import engine.gameManager.DbManager;
|
|
import engine.gameManager.ItemManager;
|
|
import engine.gameManager.LootManager;
|
|
import engine.loot.BootySetEntry;
|
|
import engine.mbEnums;
|
|
import engine.parsers.objects.RuneTemplate;
|
|
import engine.server.MBServerStatics;
|
|
import org.pmw.tinylog.Logger;
|
|
|
|
import java.sql.ResultSet;
|
|
import java.sql.SQLException;
|
|
import java.util.ArrayList;
|
|
import java.util.EnumSet;
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
|
|
public class MobBase extends AbstractGameObject {
|
|
|
|
private final int loadID;
|
|
private final String firstName;
|
|
private final byte level;
|
|
private final float scale;
|
|
public final ArrayList<MobBaseEffects> effectsList;
|
|
public int bootySet;
|
|
public mbEnums.MobBehaviourType fsm;
|
|
public EnumSet<mbEnums.MonsterType> notEnemy;
|
|
public EnumSet<mbEnums.MonsterType> enemy;
|
|
private float healthMax;
|
|
private int attackRating;
|
|
private int defenseRating;
|
|
private float damageMin;
|
|
private float damageMax;
|
|
private float hitBoxRadius;
|
|
private EnumSet<mbEnums.MobFlagType> flags;
|
|
private int mask;
|
|
private int goldMod;
|
|
private int seeInvis;
|
|
private int spawnTime = 0;
|
|
private float attackRange;
|
|
private boolean isNecroPet = false;
|
|
private MobBaseStats mobBaseStats;
|
|
private float walk = 0;
|
|
private float run = 0;
|
|
private float walkCombat = 0;
|
|
private float runCombat = 0;
|
|
|
|
/**
|
|
* ResultSet Constructor
|
|
*/
|
|
public MobBase(ResultSet rs) throws SQLException {
|
|
super(rs, rs.getInt("ID"));
|
|
|
|
RuneTemplate rune = null;
|
|
String fsmName;
|
|
|
|
this.loadID = rs.getInt("loadID");
|
|
rune = RuneTemplate._runes.get(this.loadID);
|
|
|
|
if (rune != null) {
|
|
this.firstName = rune.obj_name;
|
|
this.level = (byte) rune.rune_level;
|
|
this.healthMax = rune.rune_health;
|
|
this.damageMin = rune.rune_min_damage;
|
|
this.damageMax = rune.rune_max_damage;
|
|
this.attackRating = rune.rune_attack;
|
|
this.defenseRating = rune.rune_defense;
|
|
fsmName = rune.obj_sparse_data.getOrDefault("ROOTFSMID", mbEnums.MobBehaviourType.None.name());
|
|
this.fsm = mbEnums.MobBehaviourType.valueOf(fsmName);
|
|
this.notEnemy = EnumSet.copyOf(rune.rune_not_enemy_monster_types);
|
|
this.enemy = EnumSet.copyOf(rune.rune_enemy_monster_types);
|
|
this.walk = rune.rune_speed.getOrDefault(mbEnums.MovementType.WALK, 0f);
|
|
this.walkCombat = rune.rune_speed.getOrDefault(mbEnums.MovementType.COMBATWALK, 0f);
|
|
this.run = rune.rune_speed.getOrDefault(mbEnums.MovementType.RUN, 0f);
|
|
this.runCombat = rune.rune_speed.getOrDefault(mbEnums.MovementType.COMBATRUN, 0f);
|
|
} else {
|
|
Logger.error("Mobbase " + this.getObjectUUID() + " has no race rune " + this.loadID);
|
|
this.firstName = "";
|
|
this.level = 0;
|
|
this.fsm = mbEnums.MobBehaviourType.None;
|
|
this.notEnemy = EnumSet.noneOf(mbEnums.MonsterType.class);
|
|
this.enemy = EnumSet.noneOf(mbEnums.MonsterType.class);
|
|
}
|
|
|
|
this.goldMod = rs.getInt("goldMod");
|
|
this.spawnTime = rs.getInt("spawnTime");
|
|
this.attackRange = rs.getFloat("attackRange");
|
|
this.bootySet = rs.getInt("bootySet");
|
|
|
|
this.flags = mbEnums.fromLong(rs.getLong("flags"), mbEnums.MobFlagType.class);
|
|
|
|
this.seeInvis = rs.getInt("seeInvis");
|
|
this.scale = rs.getFloat("scale");
|
|
this.hitBoxRadius = 5f;
|
|
this.mask = 0;
|
|
|
|
if (this.getObjectUUID() == 12021 || this.getObjectUUID() == 12022)
|
|
this.isNecroPet = true;
|
|
|
|
if (this.flags.contains(mbEnums.MobFlagType.HUMANOID))
|
|
this.mask += MBServerStatics.MASK_HUMANOID;
|
|
|
|
if (this.flags.contains(mbEnums.MobFlagType.UNDEAD))
|
|
this.mask += MBServerStatics.MASK_UNDEAD;
|
|
|
|
if (this.flags.contains(mbEnums.MobFlagType.BEAST))
|
|
this.mask += MBServerStatics.MASK_BEAST;
|
|
|
|
if (this.flags.contains(mbEnums.MobFlagType.DRAGON))
|
|
this.mask += MBServerStatics.MASK_DRAGON;
|
|
|
|
if (this.flags.contains(mbEnums.MobFlagType.RAT))
|
|
this.mask += MBServerStatics.MASK_RAT;
|
|
|
|
this.mobBaseStats = (rune != null) ? new MobBaseStats(rune) : MobBaseStats.GetGenericStats();
|
|
//load effects for mobbase
|
|
this.effectsList = DbManager.MobBaseQueries.GET_RUNEBASE_EFFECTS(this.loadID);
|
|
|
|
}
|
|
|
|
public static ConcurrentHashMap<mbEnums.EquipSlotType, Item> loadEquipmentSet(int equipmentSetID) {
|
|
|
|
ArrayList<BootySetEntry> equipList;
|
|
ConcurrentHashMap<mbEnums.EquipSlotType, Item> equip = new ConcurrentHashMap<>();
|
|
|
|
if (equipmentSetID == 0)
|
|
return equip;
|
|
|
|
equipList = LootManager._bootySetMap.get(equipmentSetID);
|
|
|
|
if (equipList == null)
|
|
return equip;
|
|
|
|
for (BootySetEntry equipmentSetEntry : equipList) {
|
|
|
|
Item item = new Item(equipmentSetEntry.templateID);
|
|
|
|
if (item.template.getItemEqSlotsOr().isEmpty())
|
|
continue;
|
|
|
|
item.objectUUID = ItemManager.lastNegativeID.decrementAndGet();
|
|
item.drop_chance = equipmentSetEntry.dropChance;
|
|
item.equipSlot = item.template.getItemEqSlotsOr().iterator().next();
|
|
equip.put(item.equipSlot, item);
|
|
|
|
}
|
|
|
|
return equip;
|
|
}
|
|
|
|
public static MobBase getMobBase(int id) {
|
|
return DbManager.MobBaseQueries.GET_MOBBASE(id);
|
|
}
|
|
|
|
public void updateSpeeds(float walk, float walkCombat, float run, float runCombat) {
|
|
this.walk = walk;
|
|
this.walkCombat = walkCombat;
|
|
this.run = run;
|
|
this.runCombat = runCombat;
|
|
|
|
}
|
|
|
|
/*
|
|
* Getters
|
|
*/
|
|
public String getFirstName() {
|
|
return this.firstName;
|
|
}
|
|
|
|
public int getLoadID() {
|
|
return this.loadID;
|
|
}
|
|
|
|
public int getLevel() {
|
|
return this.level;
|
|
}
|
|
|
|
public float getHealthMax() {
|
|
return this.healthMax;
|
|
}
|
|
|
|
public float getDamageMin() {
|
|
return this.damageMin;
|
|
}
|
|
|
|
public float getDamageMax() {
|
|
return this.damageMax;
|
|
}
|
|
|
|
public int getAttackRating() {
|
|
return this.attackRating;
|
|
}
|
|
|
|
public int getDefenseRating() {
|
|
return this.defenseRating;
|
|
}
|
|
|
|
public EnumSet<mbEnums.MobFlagType> getFlags() {
|
|
return this.flags;
|
|
}
|
|
|
|
public float getScale() {
|
|
return this.scale;
|
|
}
|
|
|
|
public int getTypeMasks() {
|
|
return this.mask;
|
|
}
|
|
|
|
public int getSeeInvis() {
|
|
return this.seeInvis;
|
|
}
|
|
|
|
public int getSpawnTime() {
|
|
return this.spawnTime;
|
|
}
|
|
|
|
@Override
|
|
public void updateDatabase() {
|
|
// TODO Create update logic.
|
|
}
|
|
|
|
public float getHitBoxRadius() {
|
|
if (this.hitBoxRadius < 0f) {
|
|
return 0f;
|
|
} else {
|
|
return this.hitBoxRadius;
|
|
}
|
|
}
|
|
|
|
public MobBaseStats getMobBaseStats() {
|
|
return mobBaseStats;
|
|
}
|
|
|
|
public float getAttackRange() {
|
|
return attackRange;
|
|
}
|
|
|
|
public boolean isNecroPet() {
|
|
return isNecroPet;
|
|
}
|
|
|
|
public float getWalk() {
|
|
return walk;
|
|
}
|
|
|
|
public void setWalk(float walk) {
|
|
this.walk = walk;
|
|
}
|
|
|
|
public float getRun() {
|
|
return run;
|
|
}
|
|
|
|
public void setRun(float run) {
|
|
this.run = run;
|
|
}
|
|
|
|
public float getWalkCombat() {
|
|
return walkCombat;
|
|
}
|
|
|
|
public float getRunCombat() {
|
|
return runCombat;
|
|
}
|
|
|
|
}
|