Browse Source

THIRD AFTER ROLLBACK: contract and rune and glass drop rates adjusted properly

lakebane-master
FatBoy-DOTC 7 months ago
parent
commit
885b612bd6
  1. 613
      src/engine/gameManager/LootManager.java
  2. 208
      src/engine/objects/Mob.java

613
src/engine/gameManager/LootManager.java

@ -73,38 +73,38 @@ public enum LootManager {
} }
public static void GenerateMobLoot(Mob mob) { public static void GenerateMobLoot(Mob mob) {
int mobBootySet = mob.getMobBase().bootySet;
if (mobBootySet != 0) {
RunBootySetIfPresent(mobBootySet, mob);
}
mobBootySet = mob.bootySet; //iterate the booty sets
if (mobBootySet != 0) {
RunBootySetIfPresent(mobBootySet, mob); if (mob.getMobBase().bootySet != 0 && _bootySetMap.containsKey(mob.getMobBase().bootySet) == true)
} RunBootySet(_bootySetMap.get(mob.getMobBase().bootySet), mob);
if (mob.bootySet != 0 && _bootySetMap.containsKey(mob.bootySet) == true)
RunBootySet(_bootySetMap.get(mob.bootySet), mob);
//lastly, check mobs inventory for godly or disc runes to send a server announcement
for (Item it : mob.getInventory()) {
// Check mob's inventory for godly or disc runes to send a server announcement ItemBase ib = it.getItemBase();
for (Item item : mob.getInventory()) { if(ib == null)
ItemBase itemBase = item.getItemBase(); break;
if (itemBase != null && itemBase.getName().toLowerCase().contains("of the gods")) { if (ib.getName().toLowerCase().contains("of the gods")) {
ChatSystemMsg chatMsg = new ChatSystemMsg( ChatSystemMsg chatMsg = new ChatSystemMsg(null, mob.getName() + " in " + mob.getParentZone().getName() + " has found the " + ib.getName() + ". Are you tough enough to take it?");
null, chatMsg.setMessageType(10);
mob.getName() + " in " + mob.getParentZone().getName() + " has found the " + itemBase.getName() + ". Are you tough enough to take it?" chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID());
); DispatchMessage.dispatchMsgToAll(chatMsg);
chatMsg.setMessageType(10); }
chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID());
DispatchMessage.dispatchMsgToAll(chatMsg);
} }
}
} }
private static void RunBootySet(ArrayList<BootySetEntry> entries, Mob mob) { private static void RunBootySet(ArrayList<BootySetEntry> entries, Mob mob) {
float dropRate = NORMAL_DROP_RATE;
boolean isSafeZone = mob.parentZone.getSafeZone() == 0;
if (isSafeZone) { float dropRate = NORMAL_DROP_RATE;
//roll the geenric world drop table
if(mob.parentZone.getSafeZone() == 0) {
GenerateLootDrop(mob, 1300); GenerateLootDrop(mob, 1300);
if (ThreadLocalRandom.current().nextInt(1, 10000) == 5000) { if(ThreadLocalRandom.current().nextInt(1, 10000) == 5000) {
MobLoot extraLoot = rollForGlass(mob); MobLoot extraLoot = rollForGlass(mob);
if (extraLoot != null) { if (extraLoot != null) {
mob.getCharItemManager().addItemToInventory(extraLoot); mob.getCharItemManager().addItemToInventory(extraLoot);
@ -112,6 +112,7 @@ public enum LootManager {
} }
} }
// Iterate all entries in this bootySet and process accordingly
boolean hasExtraRolled = false; boolean hasExtraRolled = false;
for (BootySetEntry bse : entries) { for (BootySetEntry bse : entries) {
switch (bse.bootyType) { switch (bse.bootyType) {
@ -119,26 +120,17 @@ public enum LootManager {
GenerateGoldDrop(mob, bse); GenerateGoldDrop(mob, bse);
break; break;
case "LOOT": case "LOOT":
if (ThreadLocalRandom.current().nextInt(1, 101) < (bse.dropChance * dropRate)) { if (ThreadLocalRandom.current().nextInt(1, 100 + 1) < (bse.dropChance * dropRate))
GenerateLootDrop(mob, bse.genTable); GenerateLootDrop(mob, bse.genTable); //generate normal loot drop
if(mob.contractCounter >= 250){
MobLoot extraLoot = rollForContract(bse.genTable, mob);
if (extraLoot != null)
mob.getCharItemManager().addItemToInventory(extraLoot);
} }
if (isSafeZone && !hasExtraRolled && ThreadLocalRandom.current().nextInt(1, 5000) < 15 * dropRate) { if(mob.runeCounter >= 250){
MobLoot extraLoot = (ThreadLocalRandom.current().nextInt(1, 101) <= 50) MobLoot extraLoot = rollForRune(bse.genTable, mob);
? rollForContract(bse.genTable, mob) if (extraLoot != null)
: rollForRune(bse.genTable, mob);
if (extraLoot != null) {
mob.getCharItemManager().addItemToInventory(extraLoot); mob.getCharItemManager().addItemToInventory(extraLoot);
}
hasExtraRolled = true;
if(mob.parentZone.lastContractDrop + 3600000 > System.currentTimeMillis()){
//no contract in last hour, force roll for one
rollForContract(bse.genTable, mob);
}
if(mob.parentZone.lastRuneDrop + 3600000 > System.currentTimeMillis()){
//no rune in last hour, force roll for one
rollForRune(bse.genTable, mob);
}
} }
break; break;
case "ITEM": case "ITEM":
@ -146,143 +138,147 @@ public enum LootManager {
break; break;
} }
} }
MobLoot specialDrop = getSpecialDropForMob(mob);
if (specialDrop != null) {
enhanceMob(mob, specialDrop);
}
}
private static void RunBootySetIfPresent(int bootySet, Mob mob) {
if (_bootySetMap.containsKey(bootySet)) {
RunBootySet(_bootySetMap.get(bootySet), mob);
}
}
private static MobLoot getSpecialDropForMob(Mob mob) {
MobLoot specialDrop = null; MobLoot specialDrop = null;
int mobUUID = mob.getObjectUUID(); switch(mob.getObjectUUID()) {
switch (mobUUID) { case 22595://elf 1
case 22595: specialDrop = new MobLoot(mob,ItemBase.getItemBase(252134),true);
specialDrop = createSpecialDrop(mob, 252134, "Melandrach The Blood-Mage"); mob.setFirstName("Melandrach The Blood-Mage");
break; break;
case 22432: case 22432: //elf 2
specialDrop = createSpecialDrop(mob, 252135, "Kyrtaar The Blood-Mage"); specialDrop = new MobLoot(mob,ItemBase.getItemBase(252135),true);
mob.setFirstName("Kyrtaar The Blood-Mage");
break; break;
case 22537: case 22537: //elf 3
specialDrop = createSpecialDrop(mob, 252136, "Vamir The Blood-Mage"); specialDrop = new MobLoot(mob,ItemBase.getItemBase(252136),true);
mob.setFirstName("Vamir The Blood-Mage");
break; break;
case 16387: case 16387: //human 4 DONE
specialDrop = createSpecialDrop(mob, 252129, "Alatar The Blood-Mage"); specialDrop = new MobLoot(mob,ItemBase.getItemBase(252129),true);
mob.setFirstName("Alatar The Blood-Mage");
break; break;
case 32724: case 32724:// human 5 GOOD
specialDrop = createSpecialDrop(mob, 252130, "Elphaba The Blood-Mage"); specialDrop = new MobLoot(mob,ItemBase.getItemBase(252130),true);
mob.setFirstName("Elphaba The Blood-Mage");
break; break;
case 23379: case 23379: //human 1 GOOD
specialDrop = createSpecialDrop(mob, 252131, "Bavmorda The Blood-Mage"); specialDrop = new MobLoot(mob,ItemBase.getItemBase(252131),true);
mob.setFirstName("Bavmorda The Blood-Mage");
break; break;
case 10826: case 10826: //human 2 REDO
specialDrop = createSpecialDrop(mob, 252132, "Draco The Blood-Mage"); specialDrop = new MobLoot(mob,ItemBase.getItemBase(252132),true);
mob.setFirstName("Draco The Blood-Mage");
break; break;
case 15929: case 15929: //human 3 GOOD
specialDrop = createSpecialDrop(mob, 252133, "Atlantes The Blood-Mage"); specialDrop = new MobLoot(mob,ItemBase.getItemBase(252133),true);
mob.setFirstName("Atlantes The Blood-Mage");
break; break;
} }
return specialDrop; if(specialDrop != null) {
} mob.setLevel((short) 65);
mob.setSpawnTime(10800);
private static MobLoot createSpecialDrop(Mob mob, int itemBaseId, String name) { mob.healthMax = (7500);
mob.setFirstName(name); mob.setHealth(7500);
return new MobLoot(mob, ItemBase.getItemBase(itemBaseId), true); ChatSystemMsg chatMsg = new ChatSystemMsg(null, mob.getName() + " in " + mob.getParentZone().getName() + " has found the " + specialDrop.getName() + ". Are you tough enough to take it?");
} chatMsg.setMessageType(10);
chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID());
private static void enhanceMob(Mob mob, MobLoot specialDrop) { DispatchMessage.dispatchMsgToAll(chatMsg);
mob.setLevel((short) 65); mob.getCharItemManager().addItemToInventory(specialDrop);
mob.setSpawnTime(10800); mob.setResists(new Resists("Dropper"));
mob.healthMax = 7500; }
mob.setHealth(7500);
ChatSystemMsg chatMsg = new ChatSystemMsg(null, mob.getName() + " in " + mob.getParentZone().getName() + " has found the " + specialDrop.getName() + ". Are you tough enough to take it?");
chatMsg.setMessageType(10);
chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID());
DispatchMessage.dispatchMsgToAll(chatMsg);
mob.getCharItemManager().addItemToInventory(specialDrop);
mob.setResists(new Resists("Dropper"));
} }
public static MobLoot getGenTableItem(int genTableID, AbstractCharacter mob) { public static MobLoot getGenTableItem(int genTableID, AbstractCharacter mob) {
if (mob == null || !_genTables.containsKey(genTableID)) {
if (mob == null || _genTables.containsKey(genTableID) == false)
return null; return null;
}
int genRoll = ThreadLocalRandom.current().nextInt(1, 95); MobLoot outItem;
int genRoll = ThreadLocalRandom.current().nextInt(1,94 + 1);
GenTableEntry selectedRow = GenTableEntry.rollTable(genTableID, genRoll, 1.0f); GenTableEntry selectedRow = GenTableEntry.rollTable(genTableID, genRoll, 1.0f);
if (selectedRow == null || !_itemTables.containsKey(selectedRow.itemTableID)) { if (selectedRow == null)
return null; return null;
}
int itemTableRoll = (mob.getObjectType().ordinal() == 52) ? int itemTableId = selectedRow.itemTableID;
ThreadLocalRandom.current().nextInt(1, 321) :
TableRoll(mob.level);
ItemTableEntry tableRow = ItemTableEntry.rollTable(selectedRow.itemTableID, itemTableRoll);
if (tableRow == null || tableRow.cacheID == 0) { if (_itemTables.containsKey(itemTableId) == false)
return null; return null;
//gets the 1-320 roll for this mob
int itemTableRoll = 0;
int objectType = mob.getObjectType().ordinal();
if(mob.getObjectType().ordinal() == 52) { //52 = player character
itemTableRoll = ThreadLocalRandom.current().nextInt(1,320 + 1);
} else{
itemTableRoll = TableRoll(mob.level);
} }
ItemTableEntry tableRow = ItemTableEntry.rollTable(itemTableId, itemTableRoll);
if (tableRow == null)
return null;
ItemBase itemBase = ItemBase.getItemBase(tableRow.cacheID); int itemUUID = tableRow.cacheID;
if (itemBase == null) {
if (itemUUID == 0)
return null; return null;
}
if (itemBase.getType() == Enum.ItemType.RESOURCE) { if (ItemBase.getItemBase(itemUUID).getType().ordinal() == Enum.ItemType.RESOURCE.ordinal()) {
if (ThreadLocalRandom.current().nextInt(1, 101) > 10) { int chance = ThreadLocalRandom.current().nextInt(1,101);
if(chance > 10)
return null; return null;
} int amount = ThreadLocalRandom.current().nextInt((int)(tableRow.minSpawn * 0.5f), (int)((tableRow.maxSpawn + 1) * 0.5f));
int amount = ThreadLocalRandom.current().nextInt((int) (tableRow.minSpawn * 0.5f), return new MobLoot(mob, ItemBase.getItemBase(itemUUID), amount, false);
(int) ((tableRow.maxSpawn + 1) * 0.5f));
return new MobLoot(mob, itemBase, amount, false);
} }
MobLoot outItem = new MobLoot(mob, itemBase, false); outItem = new MobLoot(mob, ItemBase.getItemBase(itemUUID), false);
try { Enum.ItemType outType = outItem.getItemBase().getType();
if (selectedRow.pModTable != 0) {
if(selectedRow.pModTable != 0){
try {
outItem = GeneratePrefix(mob, outItem, genTableID, genRoll); outItem = GeneratePrefix(mob, outItem, genTableID, genRoll);
outItem.setIsID(false); outItem.setIsID(false);
} catch (Exception e) {
Logger.error("Failed to GeneratePrefix for item: " + outItem.getName());
} }
if (selectedRow.sModTable != 0) { }
if(selectedRow.sModTable != 0){
try {
outItem = GenerateSuffix(mob, outItem, genTableID, genRoll); outItem = GenerateSuffix(mob, outItem, genTableID, genRoll);
outItem.setIsID(false); outItem.setIsID(false);
} catch (Exception e) {
Logger.error("Failed to GenerateSuffix for item: " + outItem.getName());
} }
} catch (Exception e) {
Logger.error("Failed to generate mod for item: " + outItem.getName(), e);
} }
return outItem; return outItem;
} }
private static MobLoot GeneratePrefix(AbstractCharacter mob, MobLoot inItem, int genTableID, int genRoll) { private static MobLoot GeneratePrefix(AbstractCharacter mob, MobLoot inItem, int genTableID, int genRoll) {
GenTableEntry selectedRow = GenTableEntry.rollTable(genTableID, genRoll, 1.0f); GenTableEntry selectedRow = GenTableEntry.rollTable(genTableID, genRoll, 1.0f);
if (selectedRow == null) {
return inItem;
}
ModTypeTableEntry prefixTable = ModTypeTableEntry.rollTable(selectedRow.pModTable, ThreadLocalRandom.current().nextInt(1, 101)); if (selectedRow == null)
if (prefixTable == null) {
return inItem; return inItem;
}
int prefixTableRoll = (mob.getObjectType().ordinal() == 52) ? int prefixroll = ThreadLocalRandom.current().nextInt(1, 100 + 1);
ThreadLocalRandom.current().nextInt(1, 321) :
TableRoll(mob.level);
ModTableEntry prefixMod = ModTableEntry.rollTable(prefixTable.modTableID, prefixTableRoll); ModTypeTableEntry prefixTable = ModTypeTableEntry.rollTable(selectedRow.pModTable, prefixroll);
if (prefixMod == null) {
if (prefixTable == null)
return inItem; return inItem;
int prefixTableRoll = 0;
if(mob.getObjectType().ordinal() == 52) {
prefixTableRoll = ThreadLocalRandom.current().nextInt(1,320 + 1);
} else{
prefixTableRoll = TableRoll(mob.level);
} }
ModTableEntry prefixMod = ModTableEntry.rollTable(prefixTable.modTableID, prefixTableRoll);
if (prefixMod == null)
return inItem;
if (!prefixMod.action.isEmpty()) { if (prefixMod.action.length() > 0) {
inItem.setPrefix(prefixMod.action); inItem.setPrefix(prefixMod.action);
inItem.addPermanentEnchantment(prefixMod.action, 0, prefixMod.level, true); inItem.addPermanentEnchantment(prefixMod.action, 0, prefixMod.level, true);
} }
@ -291,26 +287,30 @@ public enum LootManager {
} }
private static MobLoot GenerateSuffix(AbstractCharacter mob, MobLoot inItem, int genTableID, int genRoll) { private static MobLoot GenerateSuffix(AbstractCharacter mob, MobLoot inItem, int genTableID, int genRoll) {
GenTableEntry selectedRow = GenTableEntry.rollTable(genTableID, genRoll, 1.0f); GenTableEntry selectedRow = GenTableEntry.rollTable(genTableID, genRoll, 1.0f);
if (selectedRow == null) {
return inItem;
}
ModTypeTableEntry suffixTable = ModTypeTableEntry.rollTable(selectedRow.sModTable, ThreadLocalRandom.current().nextInt(1, 101)); if (selectedRow == null)
if (suffixTable == null) {
return inItem; return inItem;
}
int suffixTableRoll = (mob.getObjectType().ordinal() == 52) ? int suffixRoll = ThreadLocalRandom.current().nextInt(1, 100 + 1);
ThreadLocalRandom.current().nextInt(1, 321) :
TableRoll(mob.level);
ModTableEntry suffixMod = ModTableEntry.rollTable(suffixTable.modTableID, suffixTableRoll); ModTypeTableEntry suffixTable = ModTypeTableEntry.rollTable(selectedRow.sModTable, suffixRoll);
if (suffixMod == null) {
if (suffixTable == null)
return inItem; return inItem;
int suffixTableRoll = 0;
if(mob.getObjectType().ordinal() == 52) {
suffixTableRoll = ThreadLocalRandom.current().nextInt(1,320 + 1);
} else{
suffixTableRoll = TableRoll(mob.level);
} }
ModTableEntry suffixMod = ModTableEntry.rollTable(suffixTable.modTableID, suffixTableRoll);
if (suffixMod == null)
return inItem;
if (!suffixMod.action.isEmpty()) { if (suffixMod.action.length() > 0) {
inItem.setSuffix(suffixMod.action); inItem.setSuffix(suffixMod.action);
inItem.addPermanentEnchantment(suffixMod.action, 0, suffixMod.level, false); inItem.addPermanentEnchantment(suffixMod.action, 0, suffixMod.level, false);
} }
@ -319,141 +319,150 @@ public enum LootManager {
} }
public static int TableRoll(int mobLevel) { public static int TableRoll(int mobLevel) {
mobLevel = Math.min(mobLevel, 65);
int max = Math.min((int) (4.882 * mobLevel + 127.0), 319); if (mobLevel > 65)
int min = Math.max((int) (4.469 * mobLevel - 3.469), 70); mobLevel = 65;
int max = (int) (4.882 * mobLevel + 127.0);
if (max > 319)
max = 319;
int min = (int) (4.469 * mobLevel - 3.469);
if (min < 70)
min = 70;
return ThreadLocalRandom.current().nextInt(min, max + 1); int roll = ThreadLocalRandom.current().nextInt(min, max + 1);
return roll;
} }
public static void GenerateGoldDrop(Mob mob, BootySetEntry bse) { public static void GenerateGoldDrop(Mob mob, BootySetEntry bse) {
int chanceRoll = ThreadLocalRandom.current().nextInt(1, 101); // Simplified the chance roll to be out of 100 directly
// Early exit if failed to hit minimum chance roll int chanceRoll = ThreadLocalRandom.current().nextInt(1, 100 + 1);
if (chanceRoll > bse.dropChance) {
//early exit, failed to hit minimum chance roll
if (chanceRoll > bse.dropChance)
return; return;
}
// Determine and add gold to mob inventory //determine and add gold to mob inventory
int high = (int) (bse.highGold * NORMAL_GOLD_RATE);
int low = (int) (bse.lowGold * NORMAL_GOLD_RATE); int high = (int)(bse.highGold * NORMAL_GOLD_RATE);
int low = (int)(bse.lowGold * NORMAL_GOLD_RATE);
int gold = ThreadLocalRandom.current().nextInt(low, high); int gold = ThreadLocalRandom.current().nextInt(low, high);
if (gold > 0) { if (gold > 0) {
MobLoot goldAmount = new MobLoot(mob, gold); MobLoot goldAmount = new MobLoot(mob, gold);
mob.getCharItemManager().addItemToInventory(goldAmount); mob.getCharItemManager().addItemToInventory(goldAmount);
} }
} }
public static void GenerateLootDrop(Mob mob, int tableID) { public static void GenerateLootDrop(Mob mob, int tableID) {
if (mob.parentZone.getSafeZone() == 1) {
return; // Exit early if in a safe zone
}
try { try {
if(mob.parentZone.getSafeZone() == 1) {
return;
}
MobLoot toAdd = getGenTableItem(tableID, mob); MobLoot toAdd = getGenTableItem(tableID, mob);
if (toAdd != null && !isContractOrRune(toAdd)) { if(toAdd.getItemBase().getType().equals(Enum.ItemType.CONTRACT) || toAdd.getItemBase().getType().equals(Enum.ItemType.RUNE))
return;//block all contracts and runes that drop outside the confines of the new system
if (toAdd != null) {
toAdd.setIsID(true); toAdd.setIsID(true);
mob.getCharItemManager().addItemToInventory(toAdd); mob.getCharItemManager().addItemToInventory(toAdd);
} }
} catch (Exception e) { } catch (Exception e) {
// Handle exceptions if necessary //TODO chase down loot generation error, affects roughly 2% of drops
} }
} }
private static boolean isContractOrRune(MobLoot loot) {
Enum.ItemType type = loot.getItemBase().getType();
return type == Enum.ItemType.CONTRACT || type == Enum.ItemType.RUNE;
}
public static void GenerateEquipmentDrop(Mob mob) { public static void GenerateEquipmentDrop(Mob mob) {
if (mob.parentZone.getSafeZone() == 1) {
if(mob.parentZone.getSafeZone() == 1) {
return; return;
} }
//do equipment here
int dropCount = 0; int dropCount = 0;
if (mob.getEquip() != null) { if (mob.getEquip() != null)
for (MobEquipment me : mob.getEquip().values()) { for (MobEquipment me : mob.getEquip().values()) {
if (me.getDropChance() == 0) {
if (me.getDropChance() == 0)
continue; continue;
}
float equipmentRoll = ThreadLocalRandom.current().nextInt(1, 101); // Simplified the roll to be out of 100 directly float equipmentRoll = ThreadLocalRandom.current().nextInt(1, 100 + 1);
float dropChance = me.getDropChance() * 100; float dropChance = me.getDropChance() * 100;
if (equipmentRoll > dropChance)
if (equipmentRoll > dropChance) {
continue; continue;
}
ItemBase genericIB = me.getItemBase(); ItemBase genericIB = me.getItemBase();
if (genericIB.isVorg()) { if(genericIB.isVorg()){
genericIB = getRandomVorgPiece(genericIB); // Replaced separate method calls with a single one if(genericIB.isClothArmor()){
mob.spawnTime = ThreadLocalRandom.current().nextInt(300, 2700); //get random cloth piece
genericIB = getRandomVorgCloth();//ItemBase.getItemBase(vorg_cloth_uuids.get(ThreadLocalRandom.current().nextInt(0,vorg_cloth_uuids.size() - 1)));
} else if(genericIB.isHeavyArmor()){
//get random heavy armor piece
genericIB = getRandomVorgHA();//ItemBase.getItemBase(vorg_ha_uuids.get(ThreadLocalRandom.current().nextInt(0,vorg_ha_uuids.size() - 1)));
} else if(genericIB.isMediumArmor()){
//get random medium armor piece
genericIB = getRandomVorgMA();//ItemBase.getItemBase(vorg_ma_uuids.get(ThreadLocalRandom.current().nextInt(0,vorg_ma_uuids.size() - 1)));
} else if(genericIB.isLightArmor()){
//get random light armor piece
genericIB = getRandomVorgLA();//ItemBase.getItemBase(vorg_la_uuids.get(ThreadLocalRandom.current().nextInt(0,vorg_la_uuids.size() - 1)));
}
mob.spawnTime = ThreadLocalRandom.current().nextInt(300,2700);
} }
MobLoot ml = new MobLoot(mob, genericIB, false);
MobLoot ml = new MobLoot(mob, genericIB, false); if (ml != null && dropCount < 1 && genericIB.isVorg() == false) {
if (ml != null && dropCount < 1) {
ml.setIsID(true); ml.setIsID(true);
ml.setDurabilityCurrent((short) (ml.getDurabilityCurrent() - ThreadLocalRandom.current().nextInt(5) + 1)); ml.setDurabilityCurrent((short) (ml.getDurabilityCurrent() - ThreadLocalRandom.current().nextInt(5) + 1));
mob.getCharItemManager().addItemToInventory(ml); mob.getCharItemManager().addItemToInventory(ml);
dropCount++; dropCount = 1;
//break; // Exit on first successful roll.
} }
if(ml != null && genericIB.isVorg() && mob.getMobBaseID() != 14062){
if (ml != null && genericIB.isVorg() && mob.getMobBaseID() != 14062) {
ml.setIsID(true); ml.setIsID(true);
ml.setDurabilityCurrent(ml.getDurabilityMax()); ml.setDurabilityCurrent(ml.getDurabilityMax());
mob.getCharItemManager().addItemToInventory(ml); mob.getCharItemManager().addItemToInventory(ml);
} }
} }
}
}
private static ItemBase getRandomVorgPiece(ItemBase genericIB) {
if (genericIB.isClothArmor()) {
return getRandomVorgCloth();
} else if (genericIB.isHeavyArmor()) {
return getRandomVorgHA();
} else if (genericIB.isMediumArmor()) {
return getRandomVorgMA();
} else if (genericIB.isLightArmor()) {
return getRandomVorgLA();
}
return genericIB; // Return the original item base if it's not a vorg piece
} }
public static void GenerateInventoryDrop(Mob mob, BootySetEntry bse) { public static void GenerateInventoryDrop(Mob mob, BootySetEntry bse) {
// Check if the item is a discipline rune
if (ItemBase.getItemBase(bse.itemBase).isDiscRune()) { if(ItemBase.getItemBase(bse.itemBase).isDiscRune()) {
if (!Mob.disciplineDroppers.contains(mob)) { if(!Mob.disciplineDroppers.contains(mob))
Mob.disciplineDroppers.add(mob); Mob.disciplineDroppers.add(mob);
mob.setResists(new Resists("Dropper"));
ChatSystemMsg chatMsg = new ChatSystemMsg(null, mob.getName() + " in " + mob.getParentZone().getName() + " has found the " + ItemBase.getItemBase(bse.itemBase).getName() + ". Are you tough enough to take it?"); mob.setResists(new Resists("Dropper"));
chatMsg.setMessageType(10); ChatSystemMsg chatMsg = new ChatSystemMsg(null, mob.getName() + " in " + mob.getParentZone().getName() + " has found the " + ItemBase.getItemBase(bse.itemBase).getName() + ". Are you tough enough to take it?");
chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID()); chatMsg.setMessageType(10);
DispatchMessage.dispatchMsgToAll(chatMsg); chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID());
} DispatchMessage.dispatchMsgToAll(chatMsg);
} }
// Skip drop if mob is in a safe zone //if((bse.itemBase == 3040 || bse.itemBase == 3021) && mob.level < 80){
if (mob.parentZone.getSafeZone() == 1) { // chance = 100;
//}
if(mob.parentZone.getSafeZone() == 1) {
return; return;
} }
// Roll for drop chance int chanceRoll = ThreadLocalRandom.current().nextInt(1, 99);
int chanceRoll = ThreadLocalRandom.current().nextInt(1, 100); // Changed upper bound to 100
// Check if the chance roll exceeds drop chance //early exit, failed to hit minimum chance roll
if (chanceRoll > bse.dropChance) {
return; // Early exit if the drop chance fails if (chanceRoll > bse.dropChance)
} return;
// Create and add the loot item to the mob's inventory
MobLoot lootItem = new MobLoot(mob, ItemBase.getItemBase(bse.itemBase), true); MobLoot lootItem = new MobLoot(mob, ItemBase.getItemBase(bse.itemBase), true);
if (lootItem != null) {
if (lootItem != null)
mob.getCharItemManager().addItemToInventory(lootItem); mob.getCharItemManager().addItemToInventory(lootItem);
}
} }
public static void peddleFate(PlayerCharacter playerCharacter, Item gift) { public static void peddleFate(PlayerCharacter playerCharacter, Item gift) {
@ -540,77 +549,155 @@ public enum LootManager {
itemMan.updateInventory(); itemMan.updateInventory();
} }
public static MobLoot rollForContract(int table, Mob mob) { public static MobLoot rollForContract(int table, Mob mob){
mob.parentZone.lastContractDrop = System.currentTimeMillis();
int roll = (table == 1900 || table == 1500) ? 73 : 99; int roll = 99;
if (table == 1900 || table == 1500)
roll = 73;
GenTableEntry selectedRow = GenTableEntry.rollTable(table, roll, 1.0f); GenTableEntry selectedRow = GenTableEntry.rollTable(table, roll, 1.0f);
if (selectedRow == null) { if (selectedRow == null)
return null; return null;
}
int itemTableId = selectedRow.itemTableID; int itemTableId = selectedRow.itemTableID;
if (!_itemTables.containsKey(itemTableId)) {
if (_itemTables.containsKey(itemTableId) == false)
return null; return null;
} ItemTableEntry tableRow = ItemTableEntry.rollTable(itemTableId, ThreadLocalRandom.current().nextInt(75,321));
if (tableRow == null)
return null;
int itemUUID = tableRow.cacheID;
ItemTableEntry tableRow = ItemTableEntry.rollTable(itemTableId, ThreadLocalRandom.current().nextInt(1, 321)); if (itemUUID == 0)
if (tableRow == null || tableRow.cacheID == 0) {
return null; return null;
}
return new MobLoot(mob, ItemBase.getItemBase(tableRow.cacheID), false); MobLoot outItem = new MobLoot(mob, ItemBase.getItemBase(itemUUID), false);
if(outItem != null) {
mob.contractCounter = 0;
return outItem;
}
return null;
} }
public static MobLoot rollForRune(int table, Mob mob){
public static MobLoot rollForRune(int table, Mob mob) { int roll = 97;
mob.parentZone.lastRuneDrop = System.currentTimeMillis(); if(table == 1900 || table == 1500){
int roll = (table == 1900 || table == 1500) ? 77 : 97; roll = 77;
}
GenTableEntry selectedRow = GenTableEntry.rollTable(table, roll, 1.0f); GenTableEntry selectedRow = GenTableEntry.rollTable(table, roll, 1.0f);
if (selectedRow == null) { if (selectedRow == null)
return null; return null;
}
int itemTableId = selectedRow.itemTableID; int itemTableId = selectedRow.itemTableID;
if (!_itemTables.containsKey(itemTableId)) {
return null;
}
ItemTableEntry tableRow = ItemTableEntry.rollTable(itemTableId, ThreadLocalRandom.current().nextInt(1, 321)); if (_itemTables.containsKey(itemTableId) == false)
if (tableRow == null || tableRow.cacheID == 0) { return null;
ItemTableEntry tableRow = ItemTableEntry.rollTable(itemTableId, ThreadLocalRandom.current().nextInt(75,321));
if (tableRow == null)
return null; return null;
}
return new MobLoot(mob, ItemBase.getItemBase(tableRow.cacheID), false); int itemUUID = tableRow.cacheID;
}
if (itemUUID == 0)
return null;
public static MobLoot rollForGlass(Mob mob) { MobLoot outItem = new MobLoot(mob, ItemBase.getItemBase(itemUUID), false);
ItemTableEntry tableRow = ItemTableEntry.rollTable(126, ThreadLocalRandom.current().nextInt(1, 321)); if(outItem != null) {
if (tableRow != null && tableRow.cacheID != 0) { mob.runeCounter = 0;
return new MobLoot(mob, ItemBase.getItemBase(tableRow.cacheID), false); return outItem;
} }
return null; return null;
} }
public static MobLoot rollForGlass( Mob mob){
ItemTableEntry tableRow = ItemTableEntry.rollTable(126, ThreadLocalRandom.current().nextInt(220,321));
if (tableRow == null)
return null;
public static ItemBase getRandomVorgItem(int maxRandom, int... itemBaseIDs) { int itemUUID = tableRow.cacheID;
int random = ThreadLocalRandom.current().nextInt(maxRandom);
int index = random / (maxRandom / itemBaseIDs.length); if (itemUUID == 0)
if (index >= itemBaseIDs.length) { return null;
index = itemBaseIDs.length - 1;
}
return ItemBase.getItemBase(itemBaseIDs[index]);
}
public static ItemBase getRandomVorgCloth() {
return getRandomVorgItem(100, 27600, 188700, 188720, 189550, 189560);
}
public static ItemBase getRandomVorgLA() { MobLoot outItem = new MobLoot(mob, ItemBase.getItemBase(itemUUID), false);
return getRandomVorgItem(160, 27550, 27560, 189100, 189110, 189120, 189130, 189140, 189150); if(outItem != null)
return outItem;
return null;
} }
public static ItemBase getRandomVorgMA() { public static ItemBase getRandomVorgCloth(){
return getRandomVorgItem(160, 27570, 188900, 188910, 188920, 188930, 188940, 188950, 189500); int random = ThreadLocalRandom.current().nextInt(100);
if(random < 20)
return ItemBase.getItemBase(27600);
if(random > 20 && random < 40)
return ItemBase.getItemBase(188700);
if(random > 40 && random < 60)
return ItemBase.getItemBase(188720);
if(random > 60 && random < 80)
return ItemBase.getItemBase(189550);
if(random > 80)
return ItemBase.getItemBase(189560);
return null;
} }
public static ItemBase getRandomVorgHA() { public static ItemBase getRandomVorgLA(){
return getRandomVorgItem(180, 27580, 27590, 188500, 188510, 188520, 188530, 188540, 188550, 189510); int random = ThreadLocalRandom.current().nextInt(160);
if(random < 20)
return ItemBase.getItemBase(27550);
if(random > 20 && random < 40)
return ItemBase.getItemBase(27560);
if(random > 40 && random < 60)
return ItemBase.getItemBase(189100);
if(random > 60 && random < 80)
return ItemBase.getItemBase(189110);
if(random > 80 && random < 100)
return ItemBase.getItemBase(189120);
if(random > 100 && random < 120)
return ItemBase.getItemBase(189130);
if(random > 120 && random < 140)
return ItemBase.getItemBase(189140);
if(random > 140)
return ItemBase.getItemBase(189150);
return null;
}
public static ItemBase getRandomVorgMA(){
int random = ThreadLocalRandom.current().nextInt(160);
if(random < 20)
return ItemBase.getItemBase(27570);
if(random > 20 && random < 40)
return ItemBase.getItemBase(188900);
if(random > 40 && random < 60)
return ItemBase.getItemBase(188910);
if(random > 60 && random < 80)
return ItemBase.getItemBase(188920);
if(random > 80 && random < 100)
return ItemBase.getItemBase(188930);
if(random > 100 && random < 120)
return ItemBase.getItemBase(188940);
if(random > 120 && random < 140)
return ItemBase.getItemBase(188950);
if(random > 140)
return ItemBase.getItemBase(189500);
return null;
}
public static ItemBase getRandomVorgHA(){
int random = ThreadLocalRandom.current().nextInt(180);
if(random < 20)
return ItemBase.getItemBase(27580);
if(random > 20 && random < 40)
return ItemBase.getItemBase(27590);
if(random > 40 && random < 60)
return ItemBase.getItemBase(188500);
if(random > 60 && random < 80)
return ItemBase.getItemBase(188510);
if(random > 80 && random < 100)
return ItemBase.getItemBase(188520);
if(random > 100 && random < 120)
return ItemBase.getItemBase(188530);
if(random > 120 && random < 140)
return ItemBase.getItemBase(188540);
if(random > 140 && random < 160)
return ItemBase.getItemBase(188550);
if(random > 160)
return ItemBase.getItemBase(189510);
return null;
} }
} }

208
src/engine/objects/Mob.java

@ -12,7 +12,6 @@ package engine.objects;
import ch.claude_martin.enumbitset.EnumBitSet; import ch.claude_martin.enumbitset.EnumBitSet;
import engine.Enum; import engine.Enum;
import engine.Enum.*; import engine.Enum.*;
import engine.InterestManagement.RealmMap;
import engine.InterestManagement.WorldGrid; import engine.InterestManagement.WorldGrid;
import engine.exception.SerializationException; import engine.exception.SerializationException;
import engine.gameManager.*; import engine.gameManager.*;
@ -26,7 +25,6 @@ import engine.net.Dispatch;
import engine.net.DispatchMessage; import engine.net.DispatchMessage;
import engine.net.client.msg.PetMsg; import engine.net.client.msg.PetMsg;
import engine.net.client.msg.PlaceAssetMsg; import engine.net.client.msg.PlaceAssetMsg;
import engine.net.client.msg.chat.ChatSystemMsg;
import engine.powers.MobPowerEntry; import engine.powers.MobPowerEntry;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
import org.joda.time.DateTime; import org.joda.time.DateTime;
@ -38,6 +36,7 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;
import static engine.gameManager.NPCManager._runeSetMap; import static engine.gameManager.NPCManager._runeSetMap;
@ -87,6 +86,9 @@ public class Mob extends AbstractIntelligenceAgent {
public boolean dropper = false; public boolean dropper = false;
public int contractCounter = 0;
public int runeCounter = 0;
// New Mobile constructor. Fill in the blanks and then call // New Mobile constructor. Fill in the blanks and then call
// PERSIST. // PERSIST.
public Mob() { public Mob() {
@ -96,6 +98,7 @@ public class Mob extends AbstractIntelligenceAgent {
this.bindLoc = Vector3fImmutable.ZERO; this.bindLoc = Vector3fImmutable.ZERO;
this.gridObjectType = GridObjectType.DYNAMIC; this.gridObjectType = GridObjectType.DYNAMIC;
this.agentType = AIAgentType.MOBILE; this.agentType = AIAgentType.MOBILE;
setResistsForMob(this);
} }
@ -164,6 +167,13 @@ public class Mob extends AbstractIntelligenceAgent {
this.currentID = this.dbID; this.currentID = this.dbID;
this.agentType = AIAgentType.MOBILE; this.agentType = AIAgentType.MOBILE;
//this.setResists(Resists.getResists(rs.getInt("mob_spawnType")));
setResistsForMob(this);
this.contractCounter = ThreadLocalRandom.current().nextInt(250);
this.runeCounter = ThreadLocalRandom.current().nextInt(250);
} catch (Exception e) { } catch (Exception e) {
Logger.error(e + " " + this.dbID); Logger.error(e + " " + this.dbID);
} }
@ -172,77 +182,78 @@ public class Mob extends AbstractIntelligenceAgent {
public static void setResistsForMob(Mob mob){ public static void setResistsForMob(Mob mob){
Resists resists = new Resists("Generic"); Resists resists = new Resists("Generic");
Zone parentMacro = null;
for(Zone zone : ZoneManager.getAllZonesIn(mob.loc)){
if(zone.isMacroZone() == false)
continue;
parentMacro = zone;
}
if(parentMacro != null) {
switch (parentMacro.getName()) {
//ice generics
case "Ymur's Crown":
case "Kralgaar Holm":
case "Ecklund Wilds":
case "Aurrochs Skrae":
resists.addResists(Resists.getResists(28));
break;
//Desert Generics
case "Leth'khalivar Desert":
case "Kharsoom":
case "Vale of Nar Addad":
case "The Blood Sands":
resists.addResists(Resists.getResists(2));
break;
//Swamp Generics
case "Thollok Marsh":
case "The Black Bog":
case "Sevaath Mere":
resists.addResists(Resists.getResists(8));
break;
//Oblivion Generics
case "Plain of Ashes":
case "Bone Marches":
case "The Doomplain":
case "Greensward Pyre":
resists.addResists(Resists.getResists(4));
break;
//Maelstrom Generics
case "Pandemonium":
case "Western Battleground":
resists.addResists(Resists.getResists(32));
break;
}
}
if(MobBase.mobbase_race_types.size() == 0){ if(MobBase.mobbase_race_types.size() == 0){
DbManager.MobBaseQueries.LOAD_ALL_MOBBASE_RACES(); DbManager.MobBaseQueries.LOAD_ALL_MOBBASE_RACES();
} }
String raceType = MobBase.mobbase_race_types.get(mob.getMobBaseID()); int mobbaseID = mob.getMobBaseID();
if(raceType != null) { if(mobbaseID != 0) {
switch (raceType) { switch (MobBase.mobbase_race_types.get(mobbaseID)) {
case "Aelfborn": case "Aelfborn":
case "NPC": case "NPC":
case "Rat":
case "Reptile":
case "Grave": case "Grave":
case "Human": case "Human":
case "Goblin":
case "CSR": case "CSR":
case "Construct": case "Construct":
case "Celestial": case "Celestial":
case "Animal": case "Animal":
case "All": case "All":
case "SiegeEngineer": case "SiegeEngineer":
int realmID = RealmMap.getRealmIDAtLocation(mob.bindLoc); resists.addResists(new Resists("Generic"));
Realm realm = Realm.getRealm(realmID);
if (realm != null) {
switch (realm.getRealmName()) {
//ice generics
case "Hethlund":
case "Hregenlund":
case "Ecklund":
case "Kralgaard":
resists.addResists(Resists.getResists(28));
break;
//Desert Generics
case "Letharuun":
case "Adduram":
case "Neshraa":
resists.addResists(Resists.getResists(2));
break;
//Swamp Generics
case "Aeglund":
case "Thollmar":
resists.addResists(Resists.getResists(8));
break;
//Oblivion Generics
case "Oblivion":
case "Vandernoch":
resists.addResists(Resists.getResists(4));
break;
//Maelstrom Generics
case "Maelstrom":
resists.addResists(Resists.getResists(32));
break;
case "Valkos":
case "Ulward":
resists.addResists(Resists.getResists(5));
}
}
break;
case "Reptile":
case "Dragon":
resists.addResists(Resists.getResists(10));
break;
case "Goblin":
resists.addResists(Resists.getResists(9));
break; break;
case "Aracoix": case "Aracoix":
resists.addResists(Resists.getResists(22)); resists.addResists(Resists.getResists(22));
break; break;
case "Rat":
case "Troll":
resists.addResists(Resists.getResists(33));
break;
case "Centaur": case "Centaur":
resists.addResists(Resists.getResists(24)); resists.addResists(Resists.getResists(24));
break; break;
case "Dragon":
resists.addResists(Resists.getResists(10));
break;
case "Dwarf": case "Dwarf":
resists.addResists(Resists.getResists(25)); resists.addResists(Resists.getResists(25));
break; break;
@ -284,6 +295,9 @@ public class Mob extends AbstractIntelligenceAgent {
case "Siege": case "Siege":
resists.addResists(Resists.getResists(38)); resists.addResists(Resists.getResists(38));
break; break;
case "Troll":
resists.addResists(Resists.getResists(33));
break;
case "Undead": case "Undead":
resists.addResists(Resists.getResists(27)); resists.addResists(Resists.getResists(27));
break; break;
@ -1010,7 +1024,7 @@ public class Mob extends AbstractIntelligenceAgent {
//Next upda //Next upda
} }
this.setLoc(newLoc); setLoc(newLoc);
this.region = AbstractWorldObject.GetRegionByWorldObject(this); this.region = AbstractWorldObject.GetRegionByWorldObject(this);
//Next update will be end Loc, lets stop him here. //Next update will be end Loc, lets stop him here.
@ -1185,17 +1199,6 @@ public class Mob extends AbstractIntelligenceAgent {
return; return;
LootManager.GenerateMobLoot(this); LootManager.GenerateMobLoot(this);
if(this.dropper){
for(Item item : this.charItemManager.getInventory()) {
ItemBase ib = item.getItemBase();
if(ib.isDiscRune()) {
ChatSystemMsg chatMsg = new ChatSystemMsg(null, this.getName() + " in " + this.getParentZone().getName() + " has found the " + ib.getName() + ". Are you tough enough to take it?");
chatMsg.setMessageType(10);
chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID());
DispatchMessage.dispatchMsgToAll(chatMsg);
}
}
}
} }
@Override @Override
@ -1711,10 +1714,7 @@ public class Mob extends AbstractIntelligenceAgent {
this.behaviourType = MobBehaviourType.GuardCaptain; this.behaviourType = MobBehaviourType.GuardCaptain;
this.spawnTime = 60 * 15; this.spawnTime = 60 * 15;
this.isPlayerGuard = true; this.isPlayerGuard = true;
if(this.building != null && ZoneManager.getCityAtLocation(this.building.getLoc()) != null) this.guardedCity = ZoneManager.getCityAtLocation(this.building.getLoc());
this.guardedCity = ZoneManager.getCityAtLocation(this.building.getLoc());
else
this.guardedCity = null;
} }
// Load AI for wall archers // Load AI for wall archers
@ -1771,8 +1771,8 @@ public class Mob extends AbstractIntelligenceAgent {
//TODO set these correctly later //TODO set these correctly later
this.rangeHandOne = this.mobBase.getAttackRange(); this.rangeHandOne = this.mobBase.getAttackRange();
this.rangeHandTwo = -1; this.rangeHandTwo = -1;
this.minDamageHandOne = (int) this.mobBase.getMinDmg(); this.minDamageHandOne = (int)this.mobBase.getMinDmg();
this.maxDamageHandOne = (int) this.mobBase.getMaxDmg(); this.maxDamageHandOne = (int)this.mobBase.getMaxDmg();
this.minDamageHandTwo = 0; this.minDamageHandTwo = 0;
this.maxDamageHandTwo = 0; this.maxDamageHandTwo = 0;
this.atrHandOne = this.mobBase.getAtr(); this.atrHandOne = this.mobBase.getAtr();
@ -1852,10 +1852,10 @@ public class Mob extends AbstractIntelligenceAgent {
try { try {
NPCManager.applyRuneSetEffects(this); NPCManager.applyRuneSetEffects(this);
recalculateStats(); recalculateStats();
if (this.mobBase.getLevel() > 80) { if(this.mobBase.getLevel() > 80){
if (this.getMobBaseID() == 14319) {//ithriana if(this.getMobBaseID() == 14319){//ithriana
this.healthMax = 5400000; this.healthMax = 5400000;
} else { } else{
this.healthMax = 1500000; this.healthMax = 1500000;
} }
} }
@ -1879,51 +1879,41 @@ public class Mob extends AbstractIntelligenceAgent {
Logger.error(e.getMessage()); Logger.error(e.getMessage());
} }
if (this.behaviourType.equals(MobBehaviourType.HamletGuard) && this.getMobBaseID() == 14104) {//guards if(this.behaviourType.equals(MobBehaviourType.HamletGuard) && this.getMobBaseID() == 14104) {//guards
this.behaviourType = MobBehaviourType.Aggro; this.behaviourType = MobBehaviourType.Aggro;
} }
for (MobEquipment equipped : this.equip.values()) { for(MobEquipment equipped: this.equip.values()){
if (equipped.getItemBase().isVorg() && this.getMobBaseID() != 14062 && this.getMobBaseID() != 14163) { if(equipped.getItemBase().isVorg() && this.getMobBaseID() != 14062 && this.getMobBaseID() != 14163){
this.dropper = true; this.dropper = true;
} }
} }
for (Item item : this.charItemManager.getInventory()) { for(Item item : this.charItemManager.getInventory()){
if (item.getItemBase().isDiscRune() && this.level < 75) { if(item.getItemBase().isDiscRune() && this.level < 75){
this.dropper = true; this.dropper = true;
} }
} }
switch (this.getObjectUUID()) {
case 40551://ithrianna if(this.dropper){
this.mobResists = Resists.getResists(14); this.level = 65;
break; this.atrHandOne *= 2;
case 11297: // mordoth this.atrHandTwo *= 2;
this.mobResists = Resists.getResists(16); this.defenseRating *= 2;
break; this.maxDamageHandOne *= 2;
case 19842://vranaxxas this.maxDamageHandTwo *= 2;
this.mobResists = Resists.getResists(37); this.minDamageHandOne *= 2;
break; this.minDamageHandTwo *= 2;
case 6407://draug tovald
this.mobResists = Resists.getResists(15);
break;
case 30959://shuggroth mael
this.mobResists = Resists.getResists(17);
break;
default:
if (this.dropper) {
this.level = 65;
this.atrHandOne *= 2;
this.atrHandTwo *= 2;
this.defenseRating *= 2;
this.maxDamageHandOne *= 2;
this.maxDamageHandTwo *= 2;
this.minDamageHandOne *= 2;
this.minDamageHandTwo *= 2;
this.mobResists = new Resists("Dropper");
}// else {
//setResistsForMob(this);
//}
} }
//for(Item loot : this.charItemManager.getInventory()){
// if(loot.getItemBase().isDiscRune() && this.level < 80){
// if(this.firstSpawn) {
// this.killCharacter("first spawn");
// this.firstSpawn = false;
// if(this.despawned == false)
// this.despawn();
// }
// }
//}
} }
@Override @Override

Loading…
Cancel
Save