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-05-09 20:19:05 -05: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 ());
2023-08-03 09:04:20 -04:00
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 ) {
2024-05-20 00:03:04 -05:00
int mobBootySet = mob . getMobBase (). bootySet ;
if ( mobBootySet != 0 ) {
RunBootySetIfPresent ( mobBootySet , mob );
}
2023-08-03 09:04:20 -04:00
2024-05-20 00:03:04 -05:00
mobBootySet = mob . bootySet ;
if ( mobBootySet != 0 ) {
RunBootySetIfPresent ( mobBootySet , mob );
}
2023-08-03 09:04:20 -04:00
2024-05-20 00:03:04 -05:00
// Check mob's inventory for godly or disc runes to send a server announcement
for ( Item item : mob . getInventory ()) {
ItemBase itemBase = item . getItemBase ();
if ( itemBase != null && itemBase . getName (). toLowerCase (). contains ( "of the gods" )) {
ChatSystemMsg chatMsg = new ChatSystemMsg (
null ,
mob . getName () + " in " + mob . getParentZone (). getName () + " has found the " + itemBase . 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
}
2024-05-20 00:03:04 -05: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 ) {
float dropRate = NORMAL_DROP_RATE ;
2024-05-20 00:03:04 -05:00
boolean isSafeZone = mob . parentZone . getSafeZone () == 0 ;
if ( isSafeZone ) {
2024-04-02 19:53:16 -05:00
GenerateLootDrop ( mob , 1300 );
2024-05-20 00:03:04 -05:00
if ( ThreadLocalRandom . current (). nextInt ( 1 , 10000 ) == 5000 ) {
2024-04-02 19:53:16 -05:00
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
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-05-20 00:03:04 -05:00
if ( ThreadLocalRandom . current (). nextInt ( 1 , 101 ) < ( bse . dropChance * dropRate )) {
GenerateLootDrop ( mob , bse . genTable );
}
if ( isSafeZone && ! hasExtraRolled && ThreadLocalRandom . current (). nextInt ( 1 , 5000 ) < 15 * dropRate ) {
MobLoot extraLoot = ( ThreadLocalRandom . current (). nextInt ( 1 , 101 ) <= 50 )
? rollForContract ( bse . genTable , mob )
: rollForRune ( bse . genTable , mob );
if ( extraLoot != null ) {
mob . getCharItemManager (). addItemToInventory ( extraLoot );
2023-08-04 12:21:22 -04:00
}
2024-05-20 00:03:04 -05:00
hasExtraRolled = true ;
2024-05-27 22:22:08 -05:00
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 );
}
2024-05-20 00:03:04 -05:00
}
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-05-20 00:03:04 -05:00
MobLoot specialDrop = getSpecialDropForMob ( mob );
if ( specialDrop != null ) {
enhanceMob ( mob , 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-05-20 00:03:04 -05:00
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 ;
int mobUUID = mob . getObjectUUID ();
switch ( mobUUID ) {
case 22595 :
specialDrop = createSpecialDrop ( mob , 252134 , "Melandrach The Blood-Mage" );
break ;
case 22432 :
specialDrop = createSpecialDrop ( mob , 252135 , "Kyrtaar The Blood-Mage" );
break ;
case 22537 :
specialDrop = createSpecialDrop ( mob , 252136 , "Vamir The Blood-Mage" );
break ;
case 16387 :
specialDrop = createSpecialDrop ( mob , 252129 , "Alatar The Blood-Mage" );
break ;
case 32724 :
specialDrop = createSpecialDrop ( mob , 252130 , "Elphaba The Blood-Mage" );
break ;
case 23379 :
specialDrop = createSpecialDrop ( mob , 252131 , "Bavmorda The Blood-Mage" );
break ;
case 10826 :
specialDrop = createSpecialDrop ( mob , 252132 , "Draco The Blood-Mage" );
break ;
case 15929 :
specialDrop = createSpecialDrop ( mob , 252133 , "Atlantes The Blood-Mage" );
break ;
}
return specialDrop ;
}
private static MobLoot createSpecialDrop ( Mob mob , int itemBaseId , String name ) {
mob . setFirstName ( name );
return new MobLoot ( mob , ItemBase . getItemBase ( itemBaseId ), true );
}
private static void enhanceMob ( Mob mob , MobLoot specialDrop ) {
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 );
mob . getCharItemManager (). addItemToInventory ( specialDrop );
mob . setResists ( new Resists ( "Dropper" ));
}
2024-02-11 17:12:43 -06:00
public static MobLoot getGenTableItem ( int genTableID , AbstractCharacter mob ) {
2024-05-20 00:03:04 -05:00
if ( mob == null || ! _genTables . containsKey ( genTableID )) {
2023-08-03 09:04:20 -04:00
return null ;
2024-05-20 00:03:04 -05:00
}
2023-08-03 09:04:20 -04:00
2024-05-20 00:03:04 -05:00
int genRoll = ThreadLocalRandom . current (). nextInt ( 1 , 95 );
2023-08-16 08:29:29 -04:00
GenTableEntry selectedRow = GenTableEntry . rollTable ( genTableID , genRoll , 1 . 0f );
2023-08-04 13:25:13 -04:00
2024-05-20 00:03:04 -05:00
if ( selectedRow == null || ! _itemTables . containsKey ( selectedRow . itemTableID )) {
2023-08-03 09:04:20 -04:00
return null ;
2023-08-08 20:37:31 -05:00
}
2024-05-20 00:03:04 -05:00
int itemTableRoll = ( mob . getObjectType (). ordinal () == 52 ) ?
ThreadLocalRandom . current (). nextInt ( 1 , 321 ) :
TableRoll ( mob . level );
ItemTableEntry tableRow = ItemTableEntry . rollTable ( selectedRow . itemTableID , itemTableRoll );
if ( tableRow == null || tableRow . cacheID == 0 ) {
2023-08-03 09:04:20 -04:00
return null ;
2024-05-20 00:03:04 -05:00
}
2023-08-03 09:04:20 -04:00
2024-05-20 00:03:04 -05:00
ItemBase itemBase = ItemBase . getItemBase ( tableRow . cacheID );
if ( itemBase == null ) {
2023-08-03 09:04:20 -04:00
return null ;
2024-05-20 00:03:04 -05:00
}
2023-08-03 09:04:20 -04:00
2024-05-20 00:03:04 -05:00
if ( itemBase . getType () == Enum . ItemType . RESOURCE ) {
if ( ThreadLocalRandom . current (). nextInt ( 1 , 101 ) > 10 ) {
2024-02-17 21:01:28 -06:00
return null ;
2024-05-20 00:03:04 -05:00
}
int amount = ThreadLocalRandom . current (). nextInt (( int ) ( tableRow . minSpawn * 0 . 5f ),
( int ) (( tableRow . maxSpawn + 1 ) * 0 . 5f ));
return new MobLoot ( mob , itemBase , amount , false );
2023-08-03 09:04:20 -04:00
}
2024-05-20 00:03:04 -05:00
MobLoot outItem = new MobLoot ( mob , itemBase , false );
try {
if ( selectedRow . pModTable != 0 ) {
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 );
}
2024-05-20 00:03:04 -05:00
if ( selectedRow . sModTable != 0 ) {
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 );
2023-07-15 09:23:48 -04:00
}
2024-05-20 00:03:04 -05:00
} catch ( Exception e ) {
Logger . error ( "Failed to generate mod for item: " + outItem . getName (), e );
2023-08-03 09:04:20 -04:00
}
2024-05-20 00:03:04 -05:00
2023-08-03 09:04:20 -04:00
return outItem ;
2023-04-06 20:07:24 -05: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-16 08:29:29 -04:00
GenTableEntry selectedRow = GenTableEntry . rollTable ( genTableID , genRoll , 1 . 0f );
2024-05-20 00:03:04 -05:00
if ( selectedRow == null ) {
2023-08-05 19:28:53 -04:00
return inItem ;
2023-08-08 20:37:31 -05:00
}
2023-08-03 09:04:20 -04:00
2024-05-20 00:03:04 -05:00
ModTypeTableEntry prefixTable = ModTypeTableEntry . rollTable ( selectedRow . pModTable , ThreadLocalRandom . current (). nextInt ( 1 , 101 ));
if ( prefixTable == null ) {
2023-08-07 10:16:30 -04:00
return inItem ;
2024-05-20 00:03:04 -05:00
}
2023-08-04 13:25:13 -04:00
2024-05-20 00:03:04 -05:00
int prefixTableRoll = ( mob . getObjectType (). ordinal () == 52 ) ?
ThreadLocalRandom . current (). nextInt ( 1 , 321 ) :
TableRoll ( mob . level );
ModTableEntry prefixMod = ModTableEntry . rollTable ( prefixTable . modTableID , prefixTableRoll );
if ( prefixMod == null ) {
return inItem ;
}
if ( ! prefixMod . action . isEmpty ()) {
2023-08-07 10:16:30 -04:00
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-16 08:29:29 -04:00
GenTableEntry selectedRow = GenTableEntry . rollTable ( genTableID , genRoll , 1 . 0f );
2024-05-20 00:03:04 -05:00
if ( selectedRow == null ) {
2023-08-05 19:28:53 -04:00
return inItem ;
2023-08-08 20:37:31 -05:00
}
2023-08-05 19:28:53 -04:00
2024-05-20 00:03:04 -05:00
ModTypeTableEntry suffixTable = ModTypeTableEntry . rollTable ( selectedRow . sModTable , ThreadLocalRandom . current (). nextInt ( 1 , 101 ));
if ( suffixTable == null ) {
2023-08-07 10:16:30 -04:00
return inItem ;
2024-05-20 00:03:04 -05:00
}
2023-08-05 19:28:53 -04:00
2024-05-20 00:03:04 -05:00
int suffixTableRoll = ( mob . getObjectType (). ordinal () == 52 ) ?
ThreadLocalRandom . current (). nextInt ( 1 , 321 ) :
TableRoll ( mob . level );
ModTableEntry suffixMod = ModTableEntry . rollTable ( suffixTable . modTableID , suffixTableRoll );
if ( suffixMod == null ) {
return inItem ;
}
if ( ! suffixMod . action . isEmpty ()) {
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 ) {
2024-05-20 00:03:04 -05:00
mobLevel = Math . min ( mobLevel , 65 );
2023-08-03 09:04:20 -04:00
2024-05-20 00:03:04 -05:00
int max = Math . min (( int ) ( 4 . 882 * mobLevel + 127 . 0 ), 319 );
int min = Math . max (( int ) ( 4 . 469 * mobLevel - 3 . 469 ), 70 );
2023-08-03 09:04:20 -04:00
2024-05-20 00:03:04 -05:00
return ThreadLocalRandom . current (). nextInt ( min , max + 1 );
2023-07-17 22:25:54 -05:00
}
2023-08-03 09:04:20 -04:00
2024-02-11 17:12:43 -06:00
public static void GenerateGoldDrop ( Mob mob , BootySetEntry bse ) {
2024-05-20 00:03:04 -05:00
int chanceRoll = ThreadLocalRandom . current (). nextInt ( 1 , 101 ); // Simplified the chance roll to be out of 100 directly
2023-08-03 09:04:20 -04:00
2024-05-20 00:03:04 -05:00
// Early exit if failed to hit minimum chance roll
if ( chanceRoll > bse . dropChance ) {
2023-07-30 11:43:26 -05:00
return ;
2024-05-20 00:03:04 -05:00
}
2023-08-03 09:04:20 -04:00
2024-05-20 00:03:04 -05:00
// Determine and add gold to mob inventory
int high = ( int ) ( bse . highGold * NORMAL_GOLD_RATE );
int low = ( int ) ( bse . lowGold * NORMAL_GOLD_RATE );
2024-02-11 17:37:01 -06:00
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
2024-02-11 17:12:43 -06:00
public static void GenerateLootDrop ( Mob mob , int tableID ) {
2024-05-20 00:03:04 -05:00
if ( mob . parentZone . getSafeZone () == 1 ) {
return ; // Exit early if in a safe zone
}
2023-08-03 09:04:20 -04:00
try {
2024-02-11 17:12:43 -06:00
MobLoot toAdd = getGenTableItem ( tableID , mob );
2024-05-20 00:03:04 -05:00
if ( toAdd != null && ! isContractOrRune ( toAdd )) {
2024-02-14 22:02:04 -06:00
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 ) {
2024-05-20 00:03:04 -05:00
// Handle exceptions if necessary
2023-07-30 13:55:08 -05:00
}
2023-07-30 11:43:26 -05:00
}
2023-08-03 09:04:20 -04:00
2024-05-20 00:03:04 -05:00
private static boolean isContractOrRune ( MobLoot loot ) {
Enum . ItemType type = loot . getItemBase (). getType ();
return type == Enum . ItemType . CONTRACT || type == Enum . ItemType . RUNE ;
}
2023-08-03 09:04:20 -04:00
2024-05-20 00:03:04 -05:00
public static void GenerateEquipmentDrop ( Mob mob ) {
if ( mob . parentZone . getSafeZone () == 1 ) {
2024-04-02 19:53:16 -05:00
return ;
}
2023-08-21 19:21:50 -05:00
int dropCount = 0 ;
2024-05-20 00:03:04 -05:00
if ( mob . getEquip () != null ) {
2023-07-30 11:43:26 -05:00
for ( MobEquipment me : mob . getEquip (). values ()) {
2024-05-20 00:03:04 -05:00
if ( me . getDropChance () == 0 ) {
2023-07-30 11:43:26 -05:00
continue ;
2024-02-11 22:36:48 -06:00
}
2023-08-04 13:09:09 -04:00
2024-05-20 00:03:04 -05:00
float equipmentRoll = ThreadLocalRandom . current (). nextInt ( 1 , 101 ); // Simplified the roll to be out of 100 directly
float dropChance = me . getDropChance () * 100 ;
if ( equipmentRoll > dropChance ) {
continue ;
}
ItemBase genericIB = me . getItemBase ();
if ( genericIB . isVorg ()) {
genericIB = getRandomVorgPiece ( genericIB ); // Replaced separate method calls with a single one
mob . spawnTime = ThreadLocalRandom . current (). nextInt ( 300 , 2700 );
}
MobLoot ml = new MobLoot ( mob , genericIB , false );
if ( ml != null && dropCount < 1 ) {
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 );
2024-05-20 00:03:04 -05:00
dropCount ++ ;
2023-08-03 21:07:07 -05:00
}
2024-05-20 00:03:04 -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
}
2024-05-20 00:03:04 -05:00
}
}
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
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 ) {
2024-05-20 00:03:04 -05:00
// Check if the item is a discipline rune
if ( ItemBase . getItemBase ( bse . itemBase ). isDiscRune ()) {
if ( ! Mob . disciplineDroppers . contains ( mob )) {
2024-04-22 21:49:15 -05:00
Mob . disciplineDroppers . add ( mob );
2024-05-20 00:03:04 -05:00
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?" );
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
2024-05-20 00:03:04 -05:00
// Skip drop if mob is in a safe zone
if ( mob . parentZone . getSafeZone () == 1 ) {
2024-04-02 19:53:16 -05:00
return ;
}
2024-05-20 00:03:04 -05:00
// Roll for drop chance
int chanceRoll = ThreadLocalRandom . current (). nextInt ( 1 , 100 ); // Changed upper bound to 100
2023-08-03 09:04:20 -04:00
2024-05-20 00:03:04 -05:00
// Check if the chance roll exceeds drop chance
if ( chanceRoll > bse . dropChance ) {
return ; // Early exit if the drop chance fails
}
2023-08-03 09:04:20 -04:00
2024-05-20 00:03:04 -05:00
// Create and add the loot item to the mob's inventory
2023-08-03 19:18:05 -05:00
MobLoot lootItem = new MobLoot ( mob , ItemBase . getItemBase ( bse . itemBase ), true );
2024-05-20 00:03:04 -05:00
if ( lootItem != null ) {
2023-08-03 19:18:05 -05:00
mob . getCharItemManager (). addItemToInventory ( lootItem );
2024-05-20 00:03:04 -05:00
}
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-08 20:37:31 -05:00
2023-08-09 17:52:39 -04:00
if ( tableID == 0 )
2023-08-09 14:48:22 -05:00
return ;
//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 );
}
//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-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
2024-05-20 00:03:04 -05:00
public static MobLoot rollForContract ( int table , Mob mob ) {
2024-05-27 22:22:08 -05:00
mob . parentZone . lastContractDrop = System . currentTimeMillis ();
2024-05-20 00:03:04 -05:00
int roll = ( table == 1900 || table == 1500 ) ? 73 : 99 ;
2024-03-13 21:23:47 -05:00
GenTableEntry selectedRow = GenTableEntry . rollTable ( table , roll , 1 . 0f );
2024-05-20 00:03:04 -05:00
if ( selectedRow == null ) {
2024-02-17 19:14:08 -06:00
return null ;
2024-03-13 21:23:47 -05:00
}
2024-02-17 19:14:08 -06:00
int itemTableId = selectedRow . itemTableID ;
2024-05-20 00:03:04 -05:00
if ( ! _itemTables . containsKey ( itemTableId )) {
2024-02-17 19:14:08 -06:00
return null ;
2024-05-20 00:03:04 -05:00
}
ItemTableEntry tableRow = ItemTableEntry . rollTable ( itemTableId , ThreadLocalRandom . current (). nextInt ( 1 , 321 ));
if ( tableRow == null || tableRow . cacheID == 0 ) {
2024-02-17 19:14:08 -06:00
return null ;
2024-05-20 00:03:04 -05:00
}
2024-02-17 19:14:08 -06:00
2024-05-20 00:03:04 -05:00
return new MobLoot ( mob , ItemBase . getItemBase ( tableRow . cacheID ), false );
2024-02-17 19:14:08 -06:00
}
2024-05-20 00:03:04 -05:00
public static MobLoot rollForRune ( int table , Mob mob ) {
2024-05-27 22:22:08 -05:00
mob . parentZone . lastRuneDrop = System . currentTimeMillis ();
2024-05-20 00:03:04 -05:00
int roll = ( table == 1900 || table == 1500 ) ? 77 : 97 ;
GenTableEntry selectedRow = GenTableEntry . rollTable ( table , roll , 1 . 0f );
if ( selectedRow == null ) {
2024-02-17 19:14:08 -06:00
return null ;
2024-05-20 00:03:04 -05:00
}
2024-02-17 19:14:08 -06:00
2024-05-20 00:03:04 -05:00
int itemTableId = selectedRow . itemTableID ;
if ( ! _itemTables . containsKey ( itemTableId )) {
2024-02-17 19:14:08 -06:00
return null ;
2024-05-20 00:03:04 -05:00
}
2024-02-17 19:14:08 -06:00
2024-05-20 00:03:04 -05:00
ItemTableEntry tableRow = ItemTableEntry . rollTable ( itemTableId , ThreadLocalRandom . current (). nextInt ( 1 , 321 ));
if ( tableRow == null || tableRow . cacheID == 0 ) {
return null ;
}
return new MobLoot ( mob , ItemBase . getItemBase ( tableRow . cacheID ), false );
}
public static MobLoot rollForGlass ( Mob mob ) {
ItemTableEntry tableRow = ItemTableEntry . rollTable ( 126 , ThreadLocalRandom . current (). nextInt ( 1 , 321 ));
if ( tableRow != null && tableRow . cacheID != 0 ) {
return new MobLoot ( mob , ItemBase . getItemBase ( tableRow . cacheID ), false );
}
2024-02-17 19:14:08 -06:00
return null ;
}
2024-04-21 21:16:25 -05:00
2024-05-20 00:03:04 -05:00
public static ItemBase getRandomVorgItem ( int maxRandom , int ... itemBaseIDs ) {
int random = ThreadLocalRandom . current (). nextInt ( maxRandom );
int index = random / ( maxRandom / itemBaseIDs . length );
if ( index >= itemBaseIDs . length ) {
index = itemBaseIDs . length - 1 ;
}
return ItemBase . getItemBase ( itemBaseIDs [ index ] );
}
public static ItemBase getRandomVorgCloth () {
return getRandomVorgItem ( 100 , 27600 , 188700 , 188720 , 189550 , 189560 );
2024-04-21 21:16:25 -05:00
}
2024-05-20 00:03:04 -05:00
public static ItemBase getRandomVorgLA () {
return getRandomVorgItem ( 160 , 27550 , 27560 , 189100 , 189110 , 189120 , 189130 , 189140 , 189150 );
2024-04-21 21:16:25 -05:00
}
2024-05-20 00:03:04 -05:00
public static ItemBase getRandomVorgMA () {
return getRandomVorgItem ( 160 , 27570 , 188900 , 188910 , 188920 , 188930 , 188940 , 188950 , 189500 );
2024-04-21 21:16:25 -05:00
}
2024-05-20 00:03:04 -05:00
public static ItemBase getRandomVorgHA () {
return getRandomVorgItem ( 180 , 27580 , 27590 , 188500 , 188510 , 188520 , 188530 , 188540 , 188550 , 189510 );
2024-04-21 21:16:25 -05:00
}
2023-08-07 10:16:30 -04:00
}