// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ // ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ // 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 effectsList; public int bootySet; public mbEnums.MobBehaviourType fsm; public EnumSet notEnemy; public EnumSet enemy; private float healthMax; private int attackRating; private int defenseRating; private float damageMin; private float damageMax; private float hitBoxRadius; private EnumSet 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 loadEquipmentSet(int equipmentSetID) { ArrayList equipList; ConcurrentHashMap 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 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; } }