using System; using System.Reflection; using DOL.Database; using log4net; using DOL.GS; using DOL.GS.PacketHandler; namespace DOL.GS { public class RoG : LootGeneratorBase { //Minimum level mob to drop an item. private static int MIN_LEVEL = 0; //%chance for an item to drop. private static int DROP_CHANCE = 100; //Toggle scaling of drop % by the relative level of mob to attacker. If the mob is lower level, chance reduced. If mob is higher, chance increased. //Modifier is the rate at which the chance changes by level difference. Mod = 5 means that the drop% changes by 5% per level difference. private static bool CHANCE_SCALE = false; private static int CHANCE_MODIFIER = 1; //Toggle Quality scaling of drops, killing higher level monsters increases the MIN_QUAL of the items by QUALITY_MODIFIER per level difference. private static bool QUALITY_SCALE = false; private static int QUALITY_MODIFIER = 1; //Minimum Quality of items private static int MIN_QUAL = 85; //Maximum Quality of items private static int MAX_QUAL = 100; //Adjust the ratio of Armor dropped to other (jewelry+cloaks) items. //The % of armor drops is related by: % = (ARMOR_RATIO - 6)/ARMOR_RATIO; So a ratio of 10 would give 50% armor, and 100 gives 95%. private static bool ARMOR_RATIO = 30; //80% //Maximum number of item drops from a single mob private static int MAX_DROPS = 5; /* armor[0][][] = cloth; armor[1][][] = leather; armor[2][][] = studded; armor[3][][] = chain; armor[4][][] = scale; armor[5][][] = plate; armor[][0][] = head; armor[][1][] = hands; armor[][2][] = arms; armor[][3][] = torso; armor[][4][] = legs; armor[][5][] = boots; armor[][][x] = Model IDs; cloak[x] = Model IDs; misc[0] = necklace; misc[1] = jewel; misc[2] = belt; misc[3] = ring; misc[4] = bracer; */ //MODEL IDS private static ushort[][][] armor = new ushort[6][][]; private static ushort[] cloak; private static ushort[] jewel = { 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 620, 621 }; private static ushort[] necklace = { 101, 623, 624, 1887 }; private static ushort[] belt = { 597, 1601, 1884 }; private static ushort[] ring = { 103, 1888, 1891, 2520, 2521, 2522, 2523, 2524, 2525, 2526 }; private static ushort[] bracer = { 598, 1885, 619, 622 }; /* obj_armor contains Object_Type values for armor. obj_armor[0][] = albion; obj_armor[1][] = hibernia; obj_armor[2][] = midgard; armor_type = { head, hands, arms, torso, legs, boots }; */ private static byte[][] obj_armor = {{ 32, 33, 34, 35, 36 }, { 32, 33, 34, 35 }, { 32, 33, 37, 38 }}; private static byte[] item_types = { 0x15, 0x16, 0x1C, 0x19, 0x1B, 0x17 }; private static byte[][] stat_value = {{1, 1}, {4, 3}, {7, 5}, {10, 7}, {13, 9}, {16, 11}, {19, 13}, {22, 15}, {25, 17}, {28, 19}}; private static byte[][] resist_value = {{1, 1}, {2, 2}, {3, 4}, {5, 8}, {7, 12}, {9, 16}, {11, 20}, {13, 24}, {15, 28}, {17, 32}}; private static byte[][] hits_value = {{4, 1}, {12, 3}, {20, 5}, {28, 7}, {36, 9}, {44, 11}, {52, 13}, {60, 15}, {68, 17}, {76, 19}}; private static byte[][] power_value = {{1, 1}, {2, 2}, {3, 4}, {5, 8}, {7, 12}, {9, 16}, {11, 20}, {13, 24}, {15, 28}, {17, 32}}; private static byte[][] skill_value = {{1, 1}, {2, 5}, {3, 10}, {4, 15}, {5, 20}, {6, 25}, {7, 30}, {8, 35}}; private static byte[][] focus_value = {{5, 1}, {10, 1}, {15, 1}, {20, 1}, {25, 1}, {30, 1}, {35, 1}, {40, 1}, {45, 1}, {50, 1}}; [ScriptLoadedEvent] public static void OnScriptCompiled(DOLEvent e, object sender, EventArgs args) { DataObject[] temp; int[] ot = { 32, 33, 34, 35, 38, 36 }; int x; for (int a = 0; a<6; a++) { armor[a] = new ushort[6][]; for (int b = 0; b<6; b++) { x = 0; temp = GameServer.Database.SelectObjects(typeof(ItemTemplate), "Object_Type = " + ot[a] + " AND Item_Type = " + slots[b]); armor[a][b] = new ushort[temp.Length]; foreach(DataObject item in temp) { armor[a][b][x++] = (ushort)(item as ItemTemplate).Model; } } } x = 0; temp = GameServer.Database.SelectObjects(typeof(ItemTemplate), "Item_Type = " + slots[6]); cloak = new ushort[temp.Length]; foreach(DataObject item in temp) { cloak[x++] = (ushort)(item as ItemTemplate).Model; } } // Defines a logger for this class. private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); // Map holding the corresponding lootTemplateName for each Moblevel group // groups are rounded down to 1-5, 5-10, 10-15, 15-20, 20-25, etc... // 1:n Mapping between Moblevel and LootTemplate protected static ItemTemplate[][] m_itemTemplates=null; // Constrcut a new templategenerate and load it's values from database. public RoG() { } public override LootList GenerateLoot(GameMob mob, GameObject killer) { LootList loot = new LootList(); if(mob.Level >= MIN_LEVEL) { int NewChance = DROP_CHANCE; if(CHANCE_SCALE) { NewChance += (mob.Level - killer.Level)*MODIFIER; if(NewChance > 100) NewChance = 100; if(NewChance < 0) NewChance = 0; } if (Util.Chance(NewChance)) { for(int i = 0; i < MAX_DROPS; i++) if(Util.Chance(NewChance)) loot.AddFixed(GetItem(mob, killer)); } } return loot; } public virtual ItemTemplate GetItem(GameMob mob, GameObject killer) { ItemTemplate temp = new ItemTemplate(); /*These properties apply to all items unless otherwise specified*/ temp.Condition = 50000; temp.Durability = 50000; temp.MaxCondition = 50000; temp.MaxDurability = 50000; int qual; if(QUALITY_SCALE) { qual = Util.Random(MIN_QUALITY + (killer.Level - mob.Level), MAX_QUALITY); if(qual < MIN_QUALITY) qual = MIN_QUALITY; } else qual = Util.Random(MIN_QUALITY, MAX_QUALITY); temp.Quality = qual; temp.MaxQuality = qual; temp.level = killer.Level; temp.Bonus = Util.Random(killer.Level * 0.7); temp.IsPickable = true; temp.IsDropable = true; temp.Weight = Util.Random(5, 30); temp.SPD_ABS = 0; temp.DPS_AF = 0; switch(Util.Random(ARMOR_RATIO)); { case 0: //Cloak { temp.Object_Type = 41; temp.Item_Type = 0x1A; temp.Model = cloak[Util.Random(cloak.Length - 1)]; break; } case 1: //Necklace { temp.Object_Type = 41; temp.Item_Type = 0x1D; temp.Model = necklace[Util.Random(necklace.Length - 1)]; break; } case 2: //Jewel { temp.Object_Type = 41; temp.Item_Type = 0x18; temp.Model = jewel[Util.Random(jewel.Length - 1)]; break; } case 3: //Ring { temp.Object_Type = 41; temp.Item_Type = 0x23; temp.Model = ring[Util.Random(ring.Length - 1)]; break; } case 4: //Bracer { temp.Object_Type = 41; temp.Item_Type = 0x21; temp.Model = bracer[Util.Random(bracer.Length - 1)]; break; } case 5: //Belt { temp.Object_Type = 41; temp.Item_Type = 0x20; temp.Model = belt[Util.Random(belt.Length - 1); break; } default: { byte armorMaterial = Util.Random(obj_armor[RandRealm].Length - 1) temp.Object_Type = obj_armor[RandRealm][armorMaterial] byte armorSlot = Util.Random(item_types.Length - 1); temp.Item_Type = armor_type[armorSlot]; temp.Model = armor[armorMaterial][armorSlot][Util.Random(armor[armorMaterial][armorSlot].Length - 1)]; switch(armorMaterial) { case 0: temp.SPD_ABS = 0; break; case 1: temp.SPD_ABS = 10; break; case 2: temp.SPD_ABS = 19; break; case 3: temp.SPD_ABS = 27; break; case 4: temp.SPD_ABS = 27; break; case 5: temp.SPD_ABS = 34; break; } temp.DPS_AF = killer.Level + 1; if(armorMaterial != 0) temp.DPS_AF *= 2; break; } } //TODO: BETTER MODPOINT SYSTEM byte modpoints = temp.Level * (temp.Quality / 100); for(int modloop = 0; modloop < 6 && modpoints > 0; modloop++) { byte mod = Util.Random(19) + 1; byte value = 0; byte cost = 0; byte rndSC = 0; if(mod < 9) { do { rndSC = Util.Random(stat_value.Length - 1); value = stat_value[rndSC][0]; cost = modloop > 0 ? stat_value[rndSC][1]/2 : stat_value[rndSC][1]; }while(modpoints - cost < 0); } else if(mod > 10) { do { rndSC = Util.Random(resist_value.Length - 1); value = resist_value[rndSC][0]; cost = modloop > 0 ? resist_value[rndSC][1]/2 : resist_value[rndSC][1]; }while(modpoints - cost < 0); } else if(mod == 9) { do { rndSC = Util.Random(hits_value.Length - 1); value = hits_value[rndSC][0]; cost = modloop > 0 ? hits_value[rndSC][1]/2 : hits_value[rndSC][1]; }while(modpoints - cost < 0); } else if(mod == 10) { do { rndSC = Util.Random(power_value.Length - 1); value = power_value[rndSC][0]; cost = modloop > 0 ? power_value[rndSC][1]/2 : power_value[rndSC][1]; }while(modpoints - cost < 0); } switch(modloop) { case 0: temp.Bonus1Type = mod; temp.Bonus1 = value; break; case 1: temp.Bonus2Type = mod; temp.Bonus1 = value; break; case 2: temp.Bonus3Type = mod; temp.Bonus1 = value; break; case 3: temp.Bonus4Type = mod; temp.Bonus1 = value; break; case 4: temp.Bonus5Type = mod; temp.Bonus1 = value; break; case 5: temp.ExtraBonusType = mod; temp.ExtraBonus = value; break; } } temp.Name = "TempName"; temp.Gold = killer.Level / 10; temp.Silver = Util.Random(killer.Level * 2); temp.Copper = Util.Random(100); return temp; } } }