2022-04-30 09:41:17 -04:00
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
2023-08-03 08:27:08 -04:00
package engine.gameManager ;
2022-04-30 09:41:17 -04:00
2023-04-06 20:07:24 -05:00
import engine.Enum ;
2023-08-03 09:43:30 -04:00
import engine.loot.* ;
2023-04-06 20:07:24 -05:00
import engine.net.DispatchMessage ;
2023-08-09 17:52:39 -04:00
import engine.net.client.msg.ErrorPopupMsg ;
2023-04-06 20:07:24 -05:00
import engine.net.client.msg.chat.ChatSystemMsg ;
import engine.objects.* ;
2023-08-02 19:57:32 -05:00
import org.pmw.tinylog.Logger ;
2023-04-06 20:07:24 -05:00
import java.util.ArrayList ;
2024-02-11 22:36:48 -06:00
import java.util.Arrays ;
2022-04-30 09:41:17 -04:00
import java.util.HashMap ;
import java.util.concurrent.ThreadLocalRandom ;
/**
* Class contains static methods for data from Magicbane's loot tables
*/
2023-08-03 09:04:20 -04:00
public enum LootManager {
LOOTMANAGER ;
2022-04-30 09:41:17 -04:00
2023-08-06 17:44:30 -04:00
// Newer tables
2023-08-06 18:09:34 -04:00
public static HashMap < Integer , ArrayList < GenTableEntry > > _genTables = new HashMap < > ( ) ;
2023-08-07 08:39:08 -04:00
public static HashMap < Integer , ArrayList < ItemTableEntry > > _itemTables = new HashMap < > ( ) ;
2023-08-07 08:49:43 -04:00
public static HashMap < Integer , ArrayList < ModTableEntry > > _modTables = new HashMap < > ( ) ;
2023-08-07 08:58:44 -04:00
public static HashMap < Integer , ArrayList < ModTypeTableEntry > > _modTypeTables = new HashMap < > ( ) ;
2023-08-06 17:44:30 -04:00
2024-02-11 22:36:48 -06:00
public static ArrayList < Integer > vorg_ha_uuids = new ArrayList < > ( Arrays . asList ( new Integer [ ] { 27580 , 27590 , 188500 , 188510 , 188520 , 188530 , 188540 , 188550 , 189510 } ) ) ;
public static ArrayList < Integer > vorg_ma_uuids = new ArrayList < > ( Arrays . asList ( new Integer [ ] { 27570 , 188900 , 188910 , 188920 , 188930 , 188940 , 188950 , 189500 } ) ) ;
public static ArrayList < Integer > vorg_la_uuids = new ArrayList < > ( Arrays . asList ( new Integer [ ] { 27550 , 27560 , 189100 , 189110 , 189120 , 189130 , 189140 , 189150 } ) ) ;
public static ArrayList < Integer > vorg_cloth_uuids = new ArrayList < > ( Arrays . asList ( new Integer [ ] { 27600 , 188700 , 188720 , 189550 , 189560 } ) ) ;
2023-08-03 09:04:20 -04:00
// Drop Rates
public static float NORMAL_DROP_RATE ;
public static float NORMAL_EXP_RATE ;
public static float NORMAL_GOLD_RATE ;
public static float HOTZONE_DROP_RATE ;
public static float HOTZONE_EXP_RATE ;
public static float HOTZONE_GOLD_RATE ;
2023-08-08 18:30:21 -04:00
public static HashMap < Integer , ArrayList < BootySetEntry > > _bootySetMap = new HashMap < > ( ) ;
2023-08-03 09:04:20 -04:00
// Bootstrap routine to initialize the Loot Manager
public static void init ( ) {
2022-04-30 09:41:17 -04:00
2023-08-03 15:20:31 -04:00
// Load loot tables from database.
2023-08-07 08:22:37 -04:00
_genTables = DbManager . LootQueries . LOAD_GEN_ITEM_TABLES ( ) ;
2023-08-07 08:39:08 -04:00
_itemTables = DbManager . LootQueries . LOAD_ITEM_TABLES ( ) ;
2023-08-07 08:49:43 -04:00
_modTables = DbManager . LootQueries . LOAD_MOD_TABLES ( ) ;
2023-08-07 08:58:44 -04:00
_modTypeTables = DbManager . LootQueries . LOAD_MOD_TYPE_TABLES ( ) ;
2023-08-03 15:20:31 -04:00
// Cache drop rate values from Config manager.
2024-02-07 15:52:42 -06:00
//NORMAL_DROP_RATE = Float.parseFloat(ConfigManager.MB_NORMAL_DROP_RATE.getValue());
//NORMAL_EXP_RATE = Float.parseFloat(ConfigManager.MB_NORMAL_EXP_RATE.getValue());
//NORMAL_GOLD_RATE = Float.parseFloat(ConfigManager.MB_NORMAL_GOLD_RATE.getValue());
//HOTZONE_DROP_RATE = Float.parseFloat(ConfigManager.MB_HOTZONE_DROP_RATE.getValue());
//HOTZONE_EXP_RATE = Float.parseFloat(ConfigManager.MB_HOTZONE_EXP_RATE.getValue());
//HOTZONE_GOLD_RATE = Float.parseFloat(ConfigManager.MB_HOTZONE_GOLD_RATE.getValue());
//hardcoded drop rates
NORMAL_DROP_RATE = 5 . 0f ;
NORMAL_EXP_RATE = 5 . 0f ;
NORMAL_GOLD_RATE = 5 . 0f ;
HOTZONE_DROP_RATE = 10 . 0f ;
HOTZONE_EXP_RATE = 10 . 0f ;
HOTZONE_GOLD_RATE = 10 . 0f ;
2022-04-30 09:41:17 -04:00
}
2023-07-15 09:23:48 -04:00
2023-08-21 19:36:46 -05:00
public static void GenerateMobLoot ( Mob mob ) {
2023-08-03 09:04:20 -04:00
2023-04-06 20:07:24 -05:00
//iterate the booty sets
2023-08-03 09:04:20 -04:00
2023-08-08 18:30:21 -04:00
if ( mob . getMobBase ( ) . bootySet ! = 0 & & _bootySetMap . containsKey ( mob . getMobBase ( ) . bootySet ) = = true )
2024-02-11 17:12:43 -06:00
RunBootySet ( _bootySetMap . get ( mob . getMobBase ( ) . bootySet ) , mob ) ;
2023-08-03 09:04:20 -04:00
2023-08-08 18:30:21 -04:00
if ( mob . bootySet ! = 0 & & _bootySetMap . containsKey ( mob . bootySet ) = = true )
2024-02-11 17:12:43 -06:00
RunBootySet ( _bootySetMap . get ( mob . bootySet ) , mob ) ;
2023-08-03 09:04:20 -04:00
2023-04-07 12:22:33 -05:00
//lastly, check mobs inventory for godly or disc runes to send a server announcement
2023-04-30 12:27:02 -05:00
for ( Item it : mob . getInventory ( ) ) {
2023-08-03 09:04:20 -04:00
2023-04-30 12:27:02 -05:00
ItemBase ib = it . getItemBase ( ) ;
2023-08-21 19:36:46 -05:00
if ( ib = = null )
break ;
2024-04-22 19:23:08 -05:00
if ( ib . getName ( ) . toLowerCase ( ) . contains ( " of the gods " ) ) {
2023-04-30 12:27:02 -05:00
ChatSystemMsg chatMsg = new ChatSystemMsg ( null , mob . getName ( ) + " in " + mob . 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 ) ;
}
2023-04-06 20:07:24 -05:00
}
2023-08-04 13:25:13 -04:00
2023-04-07 12:22:33 -05:00
}
2023-08-03 09:04:20 -04:00
2024-02-11 17:12:43 -06:00
private static void RunBootySet ( ArrayList < BootySetEntry > entries , Mob mob ) {
2023-08-03 09:04:20 -04:00
2024-02-11 17:12:43 -06:00
float dropRate = NORMAL_DROP_RATE ;
2024-03-13 21:23:47 -05:00
//roll the geenric world drop table
2024-04-02 19:53:16 -05:00
if ( mob . parentZone . getSafeZone ( ) = = 0 ) {
GenerateLootDrop ( mob , 1300 ) ;
if ( ThreadLocalRandom . current ( ) . nextInt ( 1 , 10000 ) = = 5000 ) {
MobLoot extraLoot = rollForGlass ( mob ) ;
if ( extraLoot ! = null ) {
mob . getCharItemManager ( ) . addItemToInventory ( extraLoot ) ;
}
2024-03-13 21:23:47 -05:00
}
}
2024-04-02 19:53:16 -05:00
2023-08-04 14:01:12 -04:00
// Iterate all entries in this bootySet and process accordingly
2024-03-13 21:23:47 -05:00
boolean hasExtraRolled = false ;
2023-08-04 12:21:22 -04:00
for ( BootySetEntry bse : entries ) {
switch ( bse . bootyType ) {
case " GOLD " :
2024-02-11 17:12:43 -06:00
GenerateGoldDrop ( mob , bse ) ;
2023-08-04 12:21:22 -04:00
break ;
case " LOOT " :
2024-04-02 19:53:16 -05:00
if ( ThreadLocalRandom . current ( ) . nextInt ( 1 , 100 + 1 ) < ( bse . dropChance * dropRate ) )
GenerateLootDrop ( mob , bse . genTable ) ; //generate normal loot drop
2024-04-12 23:00:46 -05:00
if ( mob . parentZone . getSafeZone ( ) = = 0 & & hasExtraRolled = = false & & ThreadLocalRandom . current ( ) . nextInt ( 1 , 5000 ) < 5 * dropRate ) {
2024-04-02 19:53:16 -05:00
int roll = ThreadLocalRandom . current ( ) . nextInt ( 1 , 101 ) ;
MobLoot extraLoot = null ;
2024-04-12 23:00:46 -05:00
if ( roll < = 50 ) {
2024-04-02 19:53:16 -05:00
extraLoot = rollForContract ( bse . genTable , mob ) ;
}
2024-04-12 23:00:46 -05:00
if ( roll > = 51 ) {
2024-04-02 19:53:16 -05:00
extraLoot = rollForRune ( bse . genTable , mob ) ;
}
if ( extraLoot ! = null ) {
mob . getCharItemManager ( ) . addItemToInventory ( extraLoot ) ;
}
2024-03-13 21:23:47 -05:00
hasExtraRolled = true ;
2023-08-04 12:21:22 -04:00
}
break ;
case " ITEM " :
2023-08-04 13:16:44 -04:00
GenerateInventoryDrop ( mob , bse ) ;
2023-08-04 12:21:22 -04:00
break ;
2023-07-30 19:52:11 -05:00
}
2023-07-31 21:28:41 -05:00
}
2024-04-13 20:57:10 -05:00
MobLoot specialDrop = null ;
switch ( mob . getObjectUUID ( ) ) {
case 5996 : //elf 1
specialDrop = new MobLoot ( mob , ItemBase . getItemBase ( 252134 ) , true ) ;
mob . setFirstName ( " Melandrach The Blood-Mage " ) ;
break ;
case 8139 : //elf 2
specialDrop = new MobLoot ( mob , ItemBase . getItemBase ( 252135 ) , true ) ;
mob . setFirstName ( " Kyrtaar The Blood-Mage " ) ;
break ;
case 2332 : //elf 3
specialDrop = new MobLoot ( mob , ItemBase . getItemBase ( 252136 ) , true ) ;
mob . setFirstName ( " Vamir The Blood-Mage " ) ;
break ;
case 34071 : //human 4
specialDrop = new MobLoot ( mob , ItemBase . getItemBase ( 252129 ) , true ) ;
mob . setFirstName ( " Alatar The Blood-Mage " ) ;
break ;
case 32724 : // human 5
specialDrop = new MobLoot ( mob , ItemBase . getItemBase ( 252130 ) , true ) ;
mob . setFirstName ( " Elphaba The Blood-Mage " ) ;
break ;
case 23379 : //human 1
specialDrop = new MobLoot ( mob , ItemBase . getItemBase ( 252131 ) , true ) ;
mob . setFirstName ( " Bavmorda The Blood-Mage " ) ;
break ;
case 16910 : //human 2
specialDrop = new MobLoot ( mob , ItemBase . getItemBase ( 252132 ) , true ) ;
mob . setFirstName ( " Draco The Blood-Mage " ) ;
break ;
case 15929 : //human 3
specialDrop = new MobLoot ( mob , ItemBase . getItemBase ( 252133 ) , true ) ;
mob . setFirstName ( " Atlantes The Blood-Mage " ) ;
break ;
}
if ( specialDrop ! = null ) {
mob . setLevel ( ( short ) 65 ) ;
mob . setSpawnTime ( 10800 ) ;
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 ) ;
2024-04-13 21:09:28 -05:00
mob . getCharItemManager ( ) . addItemToInventory ( specialDrop ) ;
2024-04-13 20:57:10 -05:00
}
2023-07-31 19:20:41 -05:00
}
2023-08-03 09:04:20 -04:00
2024-02-11 17:12:43 -06:00
public static MobLoot getGenTableItem ( int genTableID , AbstractCharacter mob ) {
2023-08-03 09:04:20 -04:00
2023-08-07 10:16:30 -04:00
if ( mob = = null | | _genTables . containsKey ( genTableID ) = = false )
2023-08-03 09:04:20 -04:00
return null ;
MobLoot outItem ;
2024-02-19 17:25:19 -06:00
int genRoll = ThreadLocalRandom . current ( ) . nextInt ( 1 , 94 + 1 ) ;
2023-08-03 09:04:20 -04:00
2023-08-16 08:29:29 -04:00
GenTableEntry selectedRow = GenTableEntry . rollTable ( genTableID , genRoll , 1 . 0f ) ;
2023-08-04 13:25:13 -04:00
2023-08-03 09:04:20 -04:00
if ( selectedRow = = null )
return null ;
int itemTableId = selectedRow . itemTableID ;
2023-08-07 10:16:30 -04:00
if ( _itemTables . containsKey ( itemTableId ) = = false )
2023-08-03 19:18:05 -05:00
return null ;
2023-08-03 09:04:20 -04:00
//gets the 1-320 roll for this mob
2023-08-08 20:37:31 -05:00
int itemTableRoll = 0 ;
int objectType = mob . getObjectType ( ) . ordinal ( ) ;
if ( mob . getObjectType ( ) . ordinal ( ) = = 52 ) { //52 = player character
itemTableRoll = ThreadLocalRandom . current ( ) . nextInt ( 1 , 320 + 1 ) ;
} else {
2024-02-11 17:12:43 -06:00
itemTableRoll = TableRoll ( mob . level ) ;
2023-08-08 20:37:31 -05:00
}
2023-08-07 10:16:30 -04:00
ItemTableEntry tableRow = ItemTableEntry . rollTable ( itemTableId , itemTableRoll ) ;
2023-08-03 09:04:20 -04:00
if ( tableRow = = null )
return null ;
int itemUUID = tableRow . cacheID ;
if ( itemUUID = = 0 )
return null ;
if ( ItemBase . getItemBase ( itemUUID ) . getType ( ) . ordinal ( ) = = Enum . ItemType . RESOURCE . ordinal ( ) ) {
2024-02-17 21:01:28 -06:00
int chance = ThreadLocalRandom . current ( ) . nextInt ( 1 , 101 ) ;
2024-03-13 21:51:55 -05:00
if ( chance > 10 )
2024-02-17 21:01:28 -06:00
return null ;
2024-03-13 21:51:55 -05:00
int amount = ThreadLocalRandom . current ( ) . nextInt ( ( int ) ( tableRow . minSpawn * 0 . 5f ) , ( int ) ( ( tableRow . maxSpawn + 1 ) * 0 . 5f ) ) ;
2023-08-03 09:04:20 -04:00
return new MobLoot ( mob , ItemBase . getItemBase ( itemUUID ) , amount , false ) ;
}
outItem = new MobLoot ( mob , ItemBase . getItemBase ( itemUUID ) , false ) ;
Enum . ItemType outType = outItem . getItemBase ( ) . getType ( ) ;
2023-08-05 19:28:53 -04:00
2023-08-04 13:25:13 -04:00
2023-08-08 19:32:39 -05:00
if ( selectedRow . pModTable ! = 0 ) {
try {
2024-02-11 17:12:43 -06:00
outItem = GeneratePrefix ( mob , outItem , genTableID , genRoll ) ;
2023-08-08 19:32:39 -05:00
outItem . setIsID ( false ) ;
} catch ( Exception e ) {
Logger . error ( " Failed to GeneratePrefix for item: " + outItem . getName ( ) ) ;
}
}
if ( selectedRow . sModTable ! = 0 ) {
try {
2024-02-11 17:12:43 -06:00
outItem = GenerateSuffix ( mob , outItem , genTableID , genRoll ) ;
2023-08-08 19:32:39 -05:00
outItem . setIsID ( false ) ;
} catch ( Exception e ) {
Logger . error ( " Failed to GenerateSuffix for item: " + outItem . getName ( ) ) ;
2023-07-15 09:23:48 -04:00
}
2023-08-03 09:04:20 -04:00
}
return outItem ;
2022-04-30 09:41:17 -04:00
}
2023-08-03 09:04:20 -04:00
2024-02-11 17:12:43 -06:00
private static MobLoot GeneratePrefix ( AbstractCharacter mob , MobLoot inItem , int genTableID , int genRoll ) {
2023-08-03 09:04:20 -04:00
2023-08-16 08:29:29 -04:00
GenTableEntry selectedRow = GenTableEntry . rollTable ( genTableID , genRoll , 1 . 0f ) ;
2023-08-04 13:25:13 -04:00
2023-08-05 19:28:53 -04:00
if ( selectedRow = = null )
return inItem ;
2023-08-03 19:18:05 -05:00
2023-08-05 09:39:16 -04:00
int prefixroll = ThreadLocalRandom . current ( ) . nextInt ( 1 , 100 + 1 ) ;
2023-08-03 09:04:20 -04:00
2023-08-07 10:16:30 -04:00
ModTypeTableEntry prefixTable = ModTypeTableEntry . rollTable ( selectedRow . pModTable , prefixroll ) ;
2023-08-04 13:25:13 -04:00
2023-08-07 10:16:30 -04:00
if ( prefixTable = = null )
return inItem ;
2023-08-08 20:37:31 -05:00
int prefixTableRoll = 0 ;
if ( mob . getObjectType ( ) . ordinal ( ) = = 52 ) {
prefixTableRoll = ThreadLocalRandom . current ( ) . nextInt ( 1 , 320 + 1 ) ;
} else {
2024-02-11 17:12:43 -06:00
prefixTableRoll = TableRoll ( mob . level ) ;
2023-08-08 20:37:31 -05:00
}
ModTableEntry prefixMod = ModTableEntry . rollTable ( prefixTable . modTableID , prefixTableRoll ) ;
2023-08-04 13:25:13 -04:00
2023-08-07 10:16:30 -04:00
if ( prefixMod = = null )
return inItem ;
2023-08-03 09:04:20 -04:00
2023-08-07 10:16:30 -04:00
if ( prefixMod . action . length ( ) > 0 ) {
inItem . setPrefix ( prefixMod . action ) ;
inItem . addPermanentEnchantment ( prefixMod . action , 0 , prefixMod . level , true ) ;
2023-08-05 19:28:53 -04:00
}
2023-08-07 10:16:30 -04:00
2023-08-02 19:45:18 -05:00
return inItem ;
}
2023-08-03 09:04:20 -04:00
2024-02-11 17:12:43 -06:00
private static MobLoot GenerateSuffix ( AbstractCharacter mob , MobLoot inItem , int genTableID , int genRoll ) {
2023-08-03 09:04:20 -04:00
2023-08-16 08:29:29 -04:00
GenTableEntry selectedRow = GenTableEntry . rollTable ( genTableID , genRoll , 1 . 0f ) ;
2023-08-04 13:25:13 -04:00
2023-08-05 19:28:53 -04:00
if ( selectedRow = = null )
return inItem ;
2023-08-03 19:18:05 -05:00
2023-08-07 10:16:30 -04:00
int suffixRoll = ThreadLocalRandom . current ( ) . nextInt ( 1 , 100 + 1 ) ;
2023-08-03 19:18:05 -05:00
2023-08-07 10:16:30 -04:00
ModTypeTableEntry suffixTable = ModTypeTableEntry . rollTable ( selectedRow . sModTable , suffixRoll ) ;
2023-08-04 13:25:13 -04:00
2023-08-05 19:28:53 -04:00
if ( suffixTable = = null )
return inItem ;
2023-08-08 20:37:31 -05:00
int suffixTableRoll = 0 ;
if ( mob . getObjectType ( ) . ordinal ( ) = = 52 ) {
suffixTableRoll = ThreadLocalRandom . current ( ) . nextInt ( 1 , 320 + 1 ) ;
} else {
2024-02-11 17:12:43 -06:00
suffixTableRoll = TableRoll ( mob . level ) ;
2023-08-08 20:37:31 -05:00
}
ModTableEntry suffixMod = ModTableEntry . rollTable ( suffixTable . modTableID , suffixTableRoll ) ;
2023-08-04 13:25:13 -04:00
2023-08-07 10:16:30 -04:00
if ( suffixMod = = null )
return inItem ;
2023-08-03 09:04:20 -04:00
2023-08-07 10:16:30 -04:00
if ( suffixMod . action . length ( ) > 0 ) {
2023-08-09 07:39:10 -04:00
inItem . setSuffix ( suffixMod . action ) ;
2023-08-17 17:53:31 -04:00
inItem . addPermanentEnchantment ( suffixMod . action , 0 , suffixMod . level , false ) ;
2023-08-05 19:28:53 -04:00
}
2023-08-07 10:16:30 -04:00
2023-08-02 19:45:18 -05:00
return inItem ;
}
2023-08-03 09:04:20 -04:00
2024-02-11 17:12:43 -06:00
public static int TableRoll ( int mobLevel ) {
2023-08-03 09:04:20 -04:00
if ( mobLevel > 65 )
2023-07-30 13:55:08 -05:00
mobLevel = 65 ;
2023-08-03 09:04:20 -04:00
int max = ( int ) ( 4 . 882 * mobLevel + 127 . 0 ) ;
if ( max > 319 )
max = 319 ;
2023-08-04 13:25:13 -04:00
int min = ( int ) ( 4 . 469 * mobLevel - 3 . 469 ) ;
if ( min < 70 )
2023-08-03 21:07:07 -05:00
min = 70 ;
2023-08-04 13:25:13 -04:00
2023-08-08 15:43:24 -05:00
int roll = ThreadLocalRandom . current ( ) . nextInt ( min , max + 1 ) ;
2023-08-03 09:04:20 -04:00
2023-07-17 22:25:54 -05:00
return roll ;
}
2023-08-03 09:04:20 -04:00
2024-02-11 17:12:43 -06:00
public static void GenerateGoldDrop ( Mob mob , BootySetEntry bse ) {
2023-08-03 09:04:20 -04:00
2023-08-05 09:39:16 -04:00
int chanceRoll = ThreadLocalRandom . current ( ) . nextInt ( 1 , 100 + 1 ) ;
2023-08-03 09:04:20 -04:00
2023-08-03 19:18:05 -05:00
//early exit, failed to hit minimum chance roll
2023-08-03 09:04:20 -04:00
if ( chanceRoll > bse . dropChance )
2023-07-30 11:43:26 -05:00
return ;
2023-08-03 09:04:20 -04:00
2023-07-30 11:43:26 -05:00
//determine and add gold to mob inventory
2023-08-03 09:04:20 -04:00
2024-02-11 17:37:01 -06:00
int high = ( int ) ( bse . highGold * NORMAL_GOLD_RATE ) ;
int low = ( int ) ( bse . lowGold * NORMAL_GOLD_RATE ) ;
int gold = ThreadLocalRandom . current ( ) . nextInt ( low , high ) ;
2023-08-03 09:04:20 -04:00
2023-07-30 11:43:26 -05:00
if ( gold > 0 ) {
2023-08-02 19:45:18 -05:00
MobLoot goldAmount = new MobLoot ( mob , gold ) ;
2023-07-30 11:43:26 -05:00
mob . getCharItemManager ( ) . addItemToInventory ( goldAmount ) ;
}
2023-08-03 09:04:20 -04:00
2023-07-30 11:43:26 -05:00
}
2023-08-03 09:04:20 -04:00
2024-02-11 17:12:43 -06:00
public static void GenerateLootDrop ( Mob mob , int tableID ) {
2023-08-03 09:04:20 -04:00
try {
2024-04-02 19:53:16 -05:00
if ( mob . parentZone . getSafeZone ( ) = = 1 ) {
return ;
}
2024-02-11 17:12:43 -06:00
MobLoot toAdd = getGenTableItem ( tableID , mob ) ;
2024-03-13 20:03:32 -05:00
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
2023-08-05 19:28:53 -04:00
2024-02-14 22:02:04 -06:00
if ( toAdd ! = null ) {
toAdd . setIsID ( true ) ;
2023-08-03 09:04:20 -04:00
mob . getCharItemManager ( ) . addItemToInventory ( toAdd ) ;
2024-02-14 22:02:04 -06:00
}
2023-08-03 09:04:20 -04:00
} catch ( Exception e ) {
2023-07-30 13:55:08 -05:00
//TODO chase down loot generation error, affects roughly 2% of drops
}
2023-07-30 11:43:26 -05:00
}
2023-08-03 09:04:20 -04:00
2023-08-04 13:04:57 -04:00
public static void GenerateEquipmentDrop ( Mob mob ) {
2023-08-03 09:04:20 -04:00
2024-04-02 19:53:16 -05:00
if ( mob . parentZone . getSafeZone ( ) = = 1 ) {
return ;
}
2023-07-30 11:43:26 -05:00
//do equipment here
2023-08-21 19:21:50 -05:00
int dropCount = 0 ;
2023-08-04 14:01:12 -04:00
if ( mob . getEquip ( ) ! = null )
2023-07-30 11:43:26 -05:00
for ( MobEquipment me : mob . getEquip ( ) . values ( ) ) {
2023-08-03 09:04:20 -04:00
2023-07-30 11:43:26 -05:00
if ( me . getDropChance ( ) = = 0 )
continue ;
2023-08-03 09:04:20 -04:00
2023-08-05 09:39:16 -04:00
float equipmentRoll = ThreadLocalRandom . current ( ) . nextInt ( 1 , 100 + 1 ) ;
2023-07-30 11:43:26 -05:00
float dropChance = me . getDropChance ( ) * 100 ;
2023-08-04 13:04:57 -04:00
if ( equipmentRoll > dropChance )
2023-08-03 19:18:05 -05:00
continue ;
2024-02-11 22:36:48 -06:00
ItemBase genericIB = me . getItemBase ( ) ;
if ( genericIB . isVorg ( ) ) {
if ( genericIB . isClothArmor ( ) ) {
//get random cloth piece
2024-04-21 21:16:25 -05:00
genericIB = getRandomVorgCloth ( ) ; //ItemBase.getItemBase(vorg_cloth_uuids.get(ThreadLocalRandom.current().nextInt(0,vorg_cloth_uuids.size() - 1)));
2024-02-11 22:36:48 -06:00
} else if ( genericIB . isHeavyArmor ( ) ) {
//get random heavy armor piece
2024-04-21 21:16:25 -05:00
genericIB = getRandomVorgHA ( ) ; //ItemBase.getItemBase(vorg_ha_uuids.get(ThreadLocalRandom.current().nextInt(0,vorg_ha_uuids.size() - 1)));
2024-02-11 22:36:48 -06:00
} else if ( genericIB . isMediumArmor ( ) ) {
//get random medium armor piece
2024-04-21 21:16:25 -05:00
genericIB = getRandomVorgMA ( ) ; //ItemBase.getItemBase(vorg_ma_uuids.get(ThreadLocalRandom.current().nextInt(0,vorg_ma_uuids.size() - 1)));
2024-02-11 22:36:48 -06:00
} else if ( genericIB . isLightArmor ( ) ) {
//get random light armor piece
2024-04-21 21:16:25 -05:00
genericIB = getRandomVorgLA ( ) ; //ItemBase.getItemBase(vorg_la_uuids.get(ThreadLocalRandom.current().nextInt(0,vorg_la_uuids.size() - 1)));
2024-02-11 22:36:48 -06:00
}
mob . spawnTime = ThreadLocalRandom . current ( ) . nextInt ( 300 , 2700 ) ;
}
MobLoot ml = new MobLoot ( mob , genericIB , false ) ;
2023-08-04 13:09:09 -04:00
2024-03-06 19:47:31 -06:00
if ( ml ! = null & & dropCount < 1 & & genericIB . isVorg ( ) = = false ) {
2023-08-03 21:07:07 -05:00
ml . setIsID ( true ) ;
2023-08-05 19:28:53 -04:00
ml . setDurabilityCurrent ( ( short ) ( ml . getDurabilityCurrent ( ) - ThreadLocalRandom . current ( ) . nextInt ( 5 ) + 1 ) ) ;
2023-07-30 11:43:26 -05:00
mob . getCharItemManager ( ) . addItemToInventory ( ml ) ;
2023-08-21 19:21:50 -05:00
dropCount = 1 ;
//break; // Exit on first successful roll.
2023-08-03 21:07:07 -05:00
}
2024-03-14 19:13:58 -05:00
if ( ml ! = null & & genericIB . isVorg ( ) & & mob . getMobBaseID ( ) ! = 14062 ) {
2024-03-06 19:47:31 -06:00
ml . setIsID ( true ) ;
ml . setDurabilityCurrent ( ml . getDurabilityMax ( ) ) ;
mob . getCharItemManager ( ) . addItemToInventory ( ml ) ;
}
2023-07-30 11:43:26 -05:00
}
}
2023-08-03 09:04:20 -04:00
2023-08-04 13:16:44 -04:00
public static void GenerateInventoryDrop ( Mob mob , BootySetEntry bse ) {
2023-08-03 09:04:20 -04:00
2024-04-19 16:40:24 -05:00
if ( bse . itemBase = = 3049 ) //disable clanwarden
return ;
2024-04-23 05:44:32 -05:00
int chance ;
2024-04-22 19:23:08 -05:00
2024-04-23 05:44:32 -05:00
if ( ! ItemBase . getItemBase ( bse . itemBase ) . isDiscRune ( ) ) {
2024-04-22 21:49:15 -05:00
chance = ( int ) bse . dropChance ;
} else {
2024-04-22 19:23:08 -05:00
chance = 25 ;
2024-04-23 05:44:32 -05:00
if ( ! Mob . disciplineDroppers . contains ( mob ) )
2024-04-22 21:49:15 -05:00
Mob . disciplineDroppers . add ( mob ) ;
2024-04-23 05:44:32 -05:00
mob . level = 60 ;
mob . healthMax = 7500 ;
mob . setHealth ( 7500 ) ;
ChatSystemMsg chatMsg = new ChatSystemMsg ( null , mob . getName ( ) + " in " + mob . getParentZone ( ) . getName ( ) + " may have found the " + ItemBase . getItemBase ( bse . itemBase ) . getName ( ) + " . Are you tough enough to take it? " ) ;
chatMsg . setMessageType ( 10 ) ;
chatMsg . setChannel ( Enum . ChatChannelType . SYSTEM . getChannelID ( ) ) ;
DispatchMessage . dispatchMsgToAll ( chatMsg ) ;
2024-04-22 21:49:15 -05:00
}
2024-04-22 19:23:08 -05:00
//if((bse.itemBase == 3040 || bse.itemBase == 3021) && mob.level < 80){
// chance = 100;
//}
2024-04-13 20:22:27 -05:00
2024-04-02 19:53:16 -05:00
if ( mob . parentZone . getSafeZone ( ) = = 1 ) {
return ;
}
2024-04-22 19:23:08 -05:00
int chanceRoll = ThreadLocalRandom . current ( ) . nextInt ( 1 , 99 ) ;
2023-08-03 09:04:20 -04:00
//early exit, failed to hit minimum chance roll
2024-04-22 19:23:08 -05:00
if ( chanceRoll > chance )
2023-07-30 15:57:01 -05:00
return ;
2023-08-03 09:04:20 -04:00
2023-08-03 19:18:05 -05:00
MobLoot lootItem = new MobLoot ( mob , ItemBase . getItemBase ( bse . itemBase ) , true ) ;
2023-08-03 09:04:20 -04:00
2023-08-03 19:18:05 -05:00
if ( lootItem ! = null )
mob . getCharItemManager ( ) . addItemToInventory ( lootItem ) ;
2023-07-30 11:43:26 -05:00
}
2023-08-09 17:52:39 -04:00
public static void peddleFate ( PlayerCharacter playerCharacter , Item gift ) {
2023-08-09 15:50:56 -05:00
//get table ID for the itembase ID
2023-08-09 17:52:39 -04:00
2023-08-09 15:50:56 -05:00
int tableID = 0 ;
2023-08-09 17:52:39 -04:00
if ( _bootySetMap . get ( gift . getItemBaseID ( ) ) ! = null )
2023-08-09 15:50:56 -05:00
tableID = _bootySetMap . get ( gift . getItemBaseID ( ) ) . get ( ThreadLocalRandom . current ( ) . nextInt ( _bootySetMap . get ( gift . getItemBaseID ( ) ) . size ( ) ) ) . genTable ;
2023-08-09 14:48:22 -05:00
2023-08-09 17:52:39 -04:00
if ( tableID = = 0 )
2023-08-08 19:37:42 -05:00
return ;
2023-08-09 14:48:22 -05:00
//get the character item manager
2023-08-09 17:52:39 -04:00
CharacterItemManager itemMan = playerCharacter . getCharItemManager ( ) ;
if ( itemMan = = null )
2023-08-09 14:48:22 -05:00
return ;
//check if player owns the gift he is trying to open
2023-08-09 17:52:39 -04:00
if ( itemMan . doesCharOwnThisItem ( gift . getObjectUUID ( ) ) = = false )
2023-08-09 14:48:22 -05:00
return ;
//roll 1-100 for the gen table selection
2023-08-09 17:52:39 -04:00
2023-08-16 08:29:29 -04:00
int genRoll = ThreadLocalRandom . current ( ) . nextInt ( 1 , 100 + 1 ) ;
GenTableEntry selectedRow = GenTableEntry . rollTable ( tableID , genRoll , LootManager . NORMAL_DROP_RATE ) ;
2023-08-09 17:52:39 -04:00
2023-08-09 14:48:22 -05:00
if ( selectedRow = = null )
2023-08-09 15:50:56 -05:00
return ;
2023-08-09 14:48:22 -05:00
//roll 220-320 for the item table selection
2023-08-09 17:52:39 -04:00
int itemRoll = ThreadLocalRandom . current ( ) . nextInt ( 220 , 320 + 1 ) ;
ItemTableEntry selectedItem = ItemTableEntry . rollTable ( selectedRow . itemTableID , itemRoll ) ;
if ( selectedItem = = null )
2023-08-09 14:48:22 -05:00
return ;
//create the item from the table, quantity is always 1
2023-08-09 17:52:39 -04:00
MobLoot winnings = new MobLoot ( playerCharacter , ItemBase . getItemBase ( selectedItem . cacheID ) , 1 , false ) ;
if ( winnings = = null )
2023-08-09 14:48:22 -05:00
return ;
2023-08-09 15:50:56 -05:00
//early exit if the inventory of the player will not old the item
2023-08-09 17:52:39 -04:00
if ( itemMan . hasRoomInventory ( winnings . getItemBase ( ) . getWeight ( ) ) = = false ) {
2023-08-09 17:58:11 -04:00
ErrorPopupMsg . sendErrorPopup ( playerCharacter , 21 ) ;
2023-08-09 15:50:56 -05:00
return ;
}
2023-08-09 14:48:22 -05:00
//determine if the winning item needs a prefix
2023-08-09 17:52:39 -04:00
2023-08-09 14:48:22 -05:00
if ( selectedRow . pModTable ! = 0 ) {
int prefixRoll = ThreadLocalRandom . current ( ) . nextInt ( 220 , 320 + 1 ) ;
ModTableEntry prefix = ModTableEntry . rollTable ( selectedRow . pModTable , prefixRoll ) ;
2023-08-09 15:50:56 -05:00
if ( prefix ! = null )
2023-08-09 14:48:22 -05:00
winnings . addPermanentEnchantment ( prefix . action , 0 , prefix . level , true ) ;
2023-08-08 19:37:42 -05:00
}
2023-08-09 14:48:22 -05:00
//determine if the winning item needs a suffix
2023-08-09 17:52:39 -04:00
2023-08-09 14:48:22 -05:00
if ( selectedRow . sModTable ! = 0 ) {
int suffixRoll = ThreadLocalRandom . current ( ) . nextInt ( 220 , 320 + 1 ) ;
ModTableEntry suffix = ModTableEntry . rollTable ( selectedRow . sModTable , suffixRoll ) ;
2023-08-09 17:52:39 -04:00
if ( suffix ! = null )
2023-08-09 14:48:22 -05:00
winnings . addPermanentEnchantment ( suffix . action , 0 , suffix . level , true ) ;
2023-08-08 19:32:39 -05:00
}
2023-08-09 15:50:56 -05:00
winnings . setIsID ( true ) ;
2023-08-09 17:52:39 -04:00
2023-08-09 14:48:22 -05:00
//remove gift from inventory
2023-08-09 17:52:39 -04:00
2023-08-09 15:50:56 -05:00
itemMan . consume ( gift ) ;
2023-08-09 14:48:22 -05:00
//add winnings to player inventory
2023-08-09 17:52:39 -04:00
2023-08-12 07:46:24 -04:00
Item playerWinnings = winnings . promoteToItem ( playerCharacter ) ;
2023-08-09 14:53:05 -05:00
itemMan . addItemToInventory ( playerWinnings ) ;
2023-08-09 15:50:56 -05:00
itemMan . updateInventory ( ) ;
2023-08-08 19:32:39 -05:00
}
2024-02-17 19:14:08 -06:00
public static MobLoot rollForContract ( int table , Mob mob ) {
2024-04-02 19:53:16 -05:00
2024-03-13 21:23:47 -05:00
int roll = 99 ;
if ( table = = 1900 | | table = = 1500 )
roll = 73 ;
GenTableEntry selectedRow = GenTableEntry . rollTable ( table , roll , 1 . 0f ) ;
2024-02-17 19:14:08 -06:00
if ( selectedRow = = null )
return null ;
int itemTableId = selectedRow . itemTableID ;
if ( _itemTables . containsKey ( itemTableId ) = = false )
return null ;
ItemTableEntry tableRow = ItemTableEntry . rollTable ( itemTableId , ThreadLocalRandom . current ( ) . nextInt ( 1 , 321 ) ) ;
if ( tableRow = = null )
return null ;
int itemUUID = tableRow . cacheID ;
if ( itemUUID = = 0 )
return null ;
MobLoot outItem = new MobLoot ( mob , ItemBase . getItemBase ( itemUUID ) , false ) ;
if ( outItem ! = null )
return outItem ;
return null ;
}
public static MobLoot rollForRune ( int table , Mob mob ) {
2024-03-13 21:23:47 -05:00
int roll = 97 ;
if ( table = = 1900 | | table = = 1500 ) {
roll = 77 ;
}
GenTableEntry selectedRow = GenTableEntry . rollTable ( table , roll , 1 . 0f ) ;
2024-02-17 19:14:08 -06:00
if ( selectedRow = = null )
return null ;
int itemTableId = selectedRow . itemTableID ;
if ( _itemTables . containsKey ( itemTableId ) = = false )
return null ;
ItemTableEntry tableRow = ItemTableEntry . rollTable ( itemTableId , ThreadLocalRandom . current ( ) . nextInt ( 1 , 321 ) ) ;
if ( tableRow = = null )
return null ;
int itemUUID = tableRow . cacheID ;
if ( itemUUID = = 0 )
return null ;
MobLoot outItem = new MobLoot ( mob , ItemBase . getItemBase ( itemUUID ) , false ) ;
if ( outItem ! = null )
return outItem ;
return null ;
}
public static MobLoot rollForGlass ( Mob mob ) {
ItemTableEntry tableRow = ItemTableEntry . rollTable ( 126 , ThreadLocalRandom . current ( ) . nextInt ( 1 , 321 ) ) ;
if ( tableRow = = null )
return null ;
int itemUUID = tableRow . cacheID ;
if ( itemUUID = = 0 )
return null ;
MobLoot outItem = new MobLoot ( mob , ItemBase . getItemBase ( itemUUID ) , false ) ;
if ( outItem ! = null )
return outItem ;
return null ;
}
2024-04-21 21:16:25 -05:00
public static ItemBase getRandomVorgCloth ( ) {
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 getRandomVorgLA ( ) {
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 ;
}
2023-08-07 10:16:30 -04:00
}