Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using LitJson;
- using Microsoft.Xna.Framework;
- using System;
- using System.Collections.Generic;
- using System.Text;
- using Terraria;
- namespace TAPI
- {
- public class LootRule
- {
- private static readonly int
- VICINITY_W = Main.maxScreenW,
- VICINITY_H = Main.maxScreenH;
- public static List<Func<NPC, bool>> filters = new List<Func<NPC,bool>>(), bfilters = new List<Func<NPC,bool>>();
- public static List<LootRule> globalRules = new List<LootRule>(), bglobalRules = new List<LootRule>();
- public static IDictionary<int, List<LootRule>> rulesType = new WrapperDictionary<int, List<LootRule>>(), brulesType = new WrapperDictionary<int, List<LootRule>>();
- public static IDictionary<string, List<LootRule>> rulesName = new WrapperDictionary<string, List<LootRule>>(), brulesName = new WrapperDictionary<string, List<LootRule>>();
- public static IDictionary<string, Func<NPC, bool>> jsonRules = new WrapperDictionary<string, Func<NPC, bool>>();
- public static bool modifiedLists = false;
- public static List<LootRule> modifiedRules = new List<LootRule>();
- public static bool settingUp = false;
- public static Func<NPC, float> luckHandler = null, bluckHandler = null;
- public static Func<NPC, bool>
- ruleBloodMoon, ruleHardmode, ruleHalloween, ruleChristmas,
- rulePumpkinMoon, ruleFrostMoon,
- ruleHostile, ruleHasValue,
- ruleUnderground,
- rulePlayerCorruption, rulePlayerCrimson, rulePlayerEvil, rulePlayerHallow, rulePlayerJungle, rulePlayerSnow, rulePlayerDungeon;
- public static readonly Func<NPC, float>
- LuckHandlerClosestPlayer = npc => npc == null ? 1f : (Main.netMode == 0 ? Main.localPlayer : Main.player[Player.FindClosest(npc.position, npc.width, npc.height)]).lootLuck,
- LuckHandlerMaxVicinity = (npc) =>
- {
- if (npc == null)
- return 1f;
- List<Player> vicinity = InVicinity(new Rectangle((int)(npc.Center.X - VICINITY_W / 2), (int)(npc.Center.Y - VICINITY_H / 2), VICINITY_W, VICINITY_H));
- float maxLuck = 1f;
- foreach (Player p in vicinity)
- if (p.lootLuck > maxLuck)
- maxLuck = p.lootLuck;
- return maxLuck;
- },
- LuckHandlerModVicinity = (npc) =>
- {
- if (npc == null)
- return 1f;
- List<Player> vicinity = InVicinity(new Rectangle((int)(npc.Center.X - VICINITY_W / 2), (int)(npc.Center.Y - VICINITY_H / 2), VICINITY_W, VICINITY_H));
- float maxLuck = 1f;
- foreach (Player p in vicinity)
- maxLuck *= p.lootLuck;
- return maxLuck;
- };
- private static List<Player> InVicinity(Rectangle rect)
- {
- List<Player> list = new List<Player>();
- Vector2 rcenter = rect.Center();
- foreach (Player p in Main.player)
- {
- if (!p.active) continue;
- if (p.ghost) continue;
- Vector2 pcenter = p.Center;
- if (pcenter.X >= rcenter.X)
- {
- if ((p.position.X + p.width) - (rect.X + rect.Width) <= VICINITY_W)
- {
- if (pcenter.Y >= rcenter.Y)
- {
- if ((p.position.Y + p.height) - (rect.Y + rect.Height) <= VICINITY_H)
- list.Add(p);
- }
- else
- {
- if (rect.Y - p.position.Y <= VICINITY_H)
- list.Add(p);
- }
- }
- }
- else
- {
- if (rect.X - p.position.X <= VICINITY_W)
- {
- if (pcenter.Y >= rcenter.Y)
- {
- if ((p.position.Y + p.height) - (rect.Y + rect.Height) <= VICINITY_H)
- list.Add(p);
- }
- else
- {
- if (rect.Y - p.position.Y <= VICINITY_H)
- list.Add(p);
- }
- }
- }
- }
- return list;
- }
- public static Func<NPC, bool> RuleClosestPlayer(Func<NPC, Player, bool> rule)
- {
- return npc => rule(npc, Main.player[Player.FindClosest(npc.position, npc.width, npc.height)]);
- }
- public static Func<NPC, bool> RuleOneIn(int max)
- {
- return npc => Main.rand.OneIn(max);
- }
- public static Func<NPC, bool> RuleValueLimit(int max)
- {
- return RuleValueLimit(1, max);
- }
- public static Func<NPC, bool> RuleValueLimit(int min, int max)
- {
- return npc => npc.value >= min && npc.value <= max;
- }
- public static void FullBackup()
- {
- bluckHandler = luckHandler;
- bfilters.Clear();
- bfilters.AddRange(filters);
- bglobalRules.Clear();
- foreach (LootRule rule in globalRules)
- {
- rule.Backup();
- bglobalRules.Add(rule.copy);
- }
- brulesType.Clear();
- foreach (KeyValuePair<int, List<LootRule>> kvp in rulesType)
- {
- List<LootRule> list = new List<LootRule>();
- foreach (LootRule rule in kvp.Value)
- {
- rule.Backup();
- list.Add(rule.copy);
- }
- brulesType[kvp.Key] = list;
- }
- brulesName.Clear();
- foreach (KeyValuePair<string, List<LootRule>> kvp in rulesName)
- {
- List<LootRule> list = new List<LootRule>();
- foreach (LootRule rule in kvp.Value)
- {
- rule.Backup();
- list.Add(rule.copy);
- }
- brulesName[kvp.Key] = list;
- }
- }
- public static void Restore()
- {
- luckHandler = bluckHandler;
- if (modifiedLists)
- {
- modifiedLists = false;
- filters.Clear();
- filters.AddRange(bfilters);
- globalRules.Clear();
- foreach (LootRule rule in bglobalRules)
- globalRules.Add(rule.copy);
- rulesType.Clear();
- foreach (KeyValuePair<int, List<LootRule>> kvp in brulesType)
- {
- List<LootRule> list = new List<LootRule>();
- foreach (LootRule rule in kvp.Value)
- list.Add(rule.copy);
- rulesType[kvp.Key] = list;
- }
- rulesName.Clear();
- foreach (KeyValuePair<string, List<LootRule>> kvp in brulesName)
- {
- List<LootRule> list = new List<LootRule>();
- foreach (LootRule rule in kvp.Value)
- list.Add(rule.copy);
- rulesName[kvp.Key] = list;
- }
- }
- foreach (LootRule rule in modifiedRules)
- rule.copy.CopyInto(rule);
- modifiedRules.Clear();
- }
- public static void RunHooks()
- {
- try
- {
- foreach (Tuple<string, JsonData> tuple in Mods.lootRules)
- {
- NPC npc = tuple.Item1 == null ? null : NPCDef.byName[tuple.Item1];
- foreach (JsonData j in tuple.Item2)
- {
- LootRule rule = new LootRule();
- rule.ReadFrom(j, npc);
- if (npc == null)
- globalRules.Add(rule);
- else
- AddForName(npc.name, rule);
- }
- }
- }
- catch (Exception e)
- {
- ErrorHandling.Handle(e);
- }
- foreach (KeyValuePair<string, NPC> kvp in NPCDef.byName)
- {
- NPC n = kvp.Value;
- if (n.def.modNPCTemplate != null)
- n.def.modNPCTemplate.SetupLootRules(n);
- }
- foreach (Mod mod in Mods.mods)
- {
- if (!mod.Loaded) continue;
- foreach (ModNPC modnpc in mod.modBase.modNPCTemplates)
- modnpc.SetupLootRules(null);
- }
- }
- public static void Setup()
- {
- Clear();
- Fill();
- }
- public static void Clear()
- {
- filters.Clear(); bfilters.Clear();
- globalRules.Clear(); bglobalRules.Clear();
- rulesType.Clear(); brulesType.Clear();
- rulesName.Clear(); brulesName.Clear();
- modifiedLists = false;
- modifiedRules.Clear();
- jsonRules.Clear();
- }
- public static void Fill()
- {
- settingUp = true;
- #region base stuff
- jsonRules["BloodMoon"] = ruleBloodMoon = npc => Main.bloodMoon;
- jsonRules["Hardmode"] = ruleHardmode = npc => Main.hardMode;
- jsonRules["Halloween"] = ruleHalloween = npc => Main.halloween;
- jsonRules["Christmas"] = ruleChristmas = npc => Main.xMas;
- jsonRules["PumpkinMoon"] = rulePumpkinMoon = npc => Main.pumpkinMoon;
- jsonRules["FrostMoon"] = ruleFrostMoon = npc => Main.snowMoon;
- jsonRules["Hostile"] = ruleHostile = npc => npc.lifeMax > 1 && npc.damage > 0 && !npc.friendly;
- jsonRules["HasValue"] = ruleHasValue = npc => npc.value > 0;
- jsonRules["Underground"] = ruleUnderground = npc => npc.position.Y > Main.rockLayer * 16.0;
- jsonRules["BiomeCorruption"] = rulePlayerCorruption = RuleClosestPlayer((npc, player) => player.zoneEvil);
- jsonRules["BiomeCrimson"] = rulePlayerCrimson = RuleClosestPlayer((npc, player) => player.zoneBlood);
- jsonRules["BiomeEvil"] = rulePlayerEvil = RuleClosestPlayer((npc, player) => player.zoneEvil || player.zoneBlood);
- jsonRules["BiomeHallow"] = rulePlayerHallow = RuleClosestPlayer((npc, player) => player.zoneHoly);
- jsonRules["BiomeJungle"] = rulePlayerJungle = RuleClosestPlayer((npc, player) => player.zoneJungle);
- jsonRules["BiomeSnow"] = rulePlayerSnow = RuleClosestPlayer((npc, player) => player.zoneSnow);
- jsonRules["BiomeDungeon"] = rulePlayerDungeon = RuleClosestPlayer((npc, player) => player.zoneDungeon);
- Dictionary<string, Func<NPC, bool>> rev = new Dictionary<string,Func<NPC,bool>>();
- foreach (KeyValuePair<string, Func<NPC, bool>> kvp in jsonRules)
- rev["!" + kvp.Key] = npc => !kvp.Value(npc);
- foreach (KeyValuePair<string, Func<NPC, bool>> kvp in rev)
- jsonRules[kvp.Key] = kvp.Value;
- luckHandler = LuckHandlerClosestPlayer;
- #endregion
- #region global rules
- filters.Add(
- npc => npc.name == "Vanilla:Meteor Head" && Main.hardMode
- );
- Add(
- new LootRule("Soul of Light/Night").Rules(
- npc => npc.name != "Vanilla:Slimer",
- ruleHardmode, ruleHostile, ruleHasValue, ruleUnderground
- ).LootRules(
- new LootRule().Chance(1.0 / 5.0).Rules(
- rulePlayerEvil
- ).Item("Soul of Night"),
- new LootRule().Chance(1.0 / 5.0).Rules(
- rulePlayerHallow
- ).Item("Soul of Light")
- ),
- new LootRule("Vanilla NPC banners").Chance(1.0 / 200.0).Rules(
- npc => Terraria.Item.NPCtoBanner(npc.type) > 0
- ).Item(
- npc => new Item().SetDefaults(1614 + Terraria.Item.NPCtoBanner(npc.type))
- ),
- new LootRule("Mechanical boss spawners").Rules(
- ruleHardmode
- ).LootRules(
- new LootRule().Chance(1.0 / 2500.0).Rules(
- npc => !NPC.downedMechBoss1
- ).Item("Mechanical Worm"),
- new LootRule().Chance(1.0 / 2500.0).Rules(
- npc => !NPC.downedMechBoss2
- ).Item("Mechanical Eye"),
- new LootRule().Chance(1.0 / 2500.0).Rules(
- npc => !NPC.downedMechBoss3
- ).Item("Mechanical Skull")
- ),
- new LootRule("Halloween Weak Mob").Chance(1.0 / 2000.0).Rules(
- ruleHalloween,
- RuleValueLimit(499),
- npc => npc.damage < 40 && npc.defense < 20
- ).Weighted().LootRules(
- new LootRule().Item("Bloody Machete"),
- new LootRule().Item("Bladed Glove")
- ),
- new LootRule("Key Molds").Rules(
- ruleHardmode,
- ruleHasValue
- ).LootRules(
- new LootRule().Chance(1.0 / 2500.0).Rules(
- rulePlayerJungle
- ).Item("Jungle Key Mold"),
- new LootRule().Chance(1.0 / 2500.0).Rules(
- rulePlayerCorruption
- ).Item("Corruption Key Mold"),
- new LootRule().Chance(1.0 / 2500.0).Rules(
- rulePlayerCrimson
- ).Item("Crimson Key Mold"),
- new LootRule().Chance(1.0 / 2500.0).Rules(
- rulePlayerHallow
- ).Item("Hallowed Key Mold"),
- new LootRule().Chance(1.0 / 2500.0).Rules(
- rulePlayerSnow
- ).Item("Frozen Key Mold")
- ),
- new LootRule("Living Fire").Chance(1.0 / 50.0).Rules(
- ruleHasValue, ruleHardmode,
- npc => npc.lifeMax >= 5,
- npc => !npc.friendly,
- npc => npc.position.Y / 16f > Main.maxTilesY - 200 //TODO: use hellLayer
- ).Item("Living Fire Block").Stack(20, 50),
- new LootRule("Goodie Bags").Chance(1.0 / 80.0).Rules(
- npc => npc.name != "Vanilla:Slimer" && npc.name != "Vanilla:Meteor Head",
- ruleHalloween, ruleHostile, ruleHasValue
- ).Item("Goodie Bag"),
- new LootRule().Chance(1.0 / 13.0).Rules(
- npc => npc.name != "Vanilla:Slimer",
- ruleChristmas, ruleHostile, ruleHasValue
- ).Item("Present"),
- new LootRule("Dungeon Spirits").Chance(1.0 / 15.0).Rules(
- rulePlayerDungeon, ruleHardmode,
- npc => npc.lifeMax > 100,
- npc => npc.name != "Vanilla:Dungeon Spirit",
- npc => npc.target >= 0,
- npc => NPC.downedPlantBoss,
- npc => TileDef.wallDungeon[Main.tile[(int)npc.center().X / 16, (int)npc.center().Y / 16].wall]
- ).Code(npc => {
- NPC.NewNPC((int)npc.center().X, (int)npc.center().Y, "Dungeon Spirit", 0);
- }),
- new LootRule().Chance(1.0 / 1000.0).Rules(
- ruleBloodMoon, ruleHardmode
- ).Item("KO Cannon"),
- new LootRule().Chance(1.0 / 100.0).Rules(
- ruleHardmode, ruleHasValue,
- npc => (double)(npc.position.Y / 16f) < Main.worldSurface + 10.0 && (npc.center().X / 16f < 380f || npc.center().X / 16f > (float)(Main.maxTilesX - 380))
- ).Item("Pirate Map"),
- new LootRule("Hearts and Stars").Rules(
- npc => npc.name != "Vanilla:Slimer" && npc.name != "Vanilla:Mother Slime" && npc.name != "Vanilla:Corrupt Slime",
- npc => npc.lifeMax > 1 && npc.damage > 0
- ).LootRules(
- new LootRule().Chance(1.0 / 6.0).Conditional().LootRules(
- new LootRule().Chance(1.0 / 2.0).Rules(
- RuleClosestPlayer((npc, player) => player.statMana < player.statManaMax2)
- ).Item("Star"),
- new LootRule().Chance(1.0 / 2.0).Rules(
- RuleClosestPlayer((npc, player) => player.statLife < player.statLifeMax2)
- ).Item("Heart")
- ),
- new LootRule().Chance(1.0 / 2.0).Rules(
- RuleClosestPlayer((npc, player) => player.statMana < player.statManaMax2)
- ).Item("Star")
- ),
- new LootRule("Coins").Code(npc => {
- float val = npc.value;
- if (npc.midas)
- val *= 1.1f + Main.rand.NextFloat() * 0.4f;
- val *= 0.8f + Main.rand.NextFloat() * 0.4f;
- if (Main.rand.OneIn(5))
- val *= 1.05f + Main.rand.NextFloat() * 0.05f;
- if (Main.rand.OneIn(10))
- val *= 1.1f + Main.rand.NextFloat() * 0.1f;
- if (Main.rand.OneIn(15))
- val *= 1.15f + Main.rand.NextFloat() * 0.15f;
- if (Main.rand.OneIn(20))
- val *= 1.2f + Main.rand.NextFloat() * 0.2f;
- int coins = (int)val;
- int coinC, coinS, coinG, coinP;
- coinC = coins;
- coinS = coinC / 100;
- coinC %= 100;
- coinG = coinS / 100;
- coinS %= 100;
- coinP = coinG / 100;
- coinG %= 100;
- while (coinP > 0)
- {
- int drop = coinP;
- if (drop > 50 && Main.rand.OneIn(5))
- {
- drop /= 1 + Main.rand.Next(3);
- }
- if (Main.rand.OneIn(5))
- {
- drop /= 1 + Main.rand.Next(3);
- }
- if (drop < 0)
- drop++;
- npc.NewItemAt("Vanilla:Platinum Coin", drop);
- coinP -= drop;
- }
- while (coinG > 0)
- {
- int drop = coinG;
- if (drop > 50 && Main.rand.OneIn(5))
- {
- drop /= 1 + Main.rand.Next(3);
- }
- if (Main.rand.OneIn(5))
- {
- drop /= 1 + Main.rand.Next(3);
- }
- if (drop < 0)
- drop++;
- npc.NewItemAt("Vanilla:Gold Coin", drop);
- coinG -= drop;
- }
- while (coinS > 0)
- {
- int drop = coinS;
- if (drop > 50 && Main.rand.OneIn(5))
- {
- drop /= 1 + Main.rand.Next(3);
- }
- if (Main.rand.OneIn(5))
- {
- drop /= 1 + Main.rand.Next(3);
- }
- if (drop < 0)
- drop++;
- npc.NewItemAt("Vanilla:Silver Coin", drop);
- coinS -= drop;
- }
- while (coinC > 0)
- {
- int drop = coinC;
- if (drop > 50 && Main.rand.OneIn(5))
- {
- drop /= 1 + Main.rand.Next(3);
- }
- if (Main.rand.OneIn(5))
- {
- drop /= 1 + Main.rand.Next(3);
- }
- if (drop < 0)
- drop++;
- npc.NewItemAt("Vanilla:Copper Coin", drop);
- coinC -= drop;
- }
- })
- );
- #endregion
- #region enemy-specific rules
- #region Surface
- #region pre-hardmode
- AddFor(new int[] { 1, 16, 138, 141, 147, 184, 187, 204, 302, 333, 334, 335, 336 }, //Slimes
- new LootRule().Item("Gel").Stack(1, 2),
- new LootRule().Chance(1.0 / 10000.0).Item("Slime Staff")
- );
- AddFor(new int[] { 3, 132, 161, 186, 187, 188, 189, 200, 223, 319, 320, 321, 331, 332 }, //Zombies
- new LootRule().Chance(1.0 / 50.0).Item("Shackle"),
- new LootRule().Chance(1.0 / 250.0).Item("Zombie Arm")
- );
- AddFor(223, //Zombie 2 (Rain Coat Set)
- new LootRule("Rain Coat Set").Chance(1.0 / 10.0).Weighted().LootRules(
- new LootRule().Chance(1.0 / 50.0).Item("Rain Hat"),
- new LootRule().Chance(1.0 / 50.0).Item("Rain Coat")
- )
- );
- AddFor(new int[] { 2, 190, 191, 192, 193, 194, 317, 318 }, //Demon Eyes
- new LootRule().Chance(1.0 / 3.0).Item("Lens"),
- new LootRule().Chance(1.0 / 100.0).Item("Black Lens")
- );
- AddFor("Pincushion Zombie",
- new LootRule().Item("Wooden Arrow").Stack(1, 9)
- );
- AddFor("The Groom",
- new LootRule().Item("Top Hat")
- );
- AddFor("Umbrella Slime",
- new LootRule().Conditional().LootRules(
- new LootRule().Chance(1.0 / 45.0).Item("Umbrella Hat"),
- new LootRule().Item("Gel").Stack(2, 5)
- )
- );
- AddFor(new Tuple<int, int>(333, 336), //Slimes with a giant bow
- new LootRule().Chance(1.0 / 20.0).Item("Giant Bow")
- );
- AddFor(new object[] { new Tuple<int, int>(10, 12), new Tuple<int, int>(95, 97) }, //Giant Worm, Digger
- new LootRule().Chance(1.0 / 100.0).Item("Whoopie Cushion")
- );
- AddFor("Meteor Head",
- new LootRule().Chance(1.0 / 50.0).Item("Meteorite")
- );
- AddFor("Shark",
- new LootRule().Conditional().LootRules(
- new LootRule().Chance(1.0 / 50.0).Item("Diving Helmet"),
- new LootRule().Item("Shark Fin")
- )
- );
- AddFor("Corrupt Bunny",
- new LootRule().Chance(1.0 / 75.0).Item("Bunny Hood")
- );
- #endregion
- #region hardmode
- AddFor("Rainbow Slime",
- new LootRule().Item("Gel").Stack(1, 5),
- new LootRule().Times(3).Chance(1.0 / 2.0).Item("Gel").Stack(1, 5),
- new LootRule().Item("Rainbow Brick").Stack(30, 60)
- );
- AddFor("Angry Nimbus",
- new LootRule().Chance(1.0 / 15.0).Item("Nimbus Rod")
- );
- AddFor("Clown",
- new LootRule().Chance(1.0 / 30.0).Item("Bananarang").Stack(1, 4),
- new LootRule().Code(
- npc => DownedBoss(ref NPC.downedClown)
- )
- );
- AddFor("Werewolf",
- new LootRule().Chance(1.0 / 60.0).Item("Moon Charm")
- );
- #endregion
- #endregion
- #region Desert
- #region pre-hardmode
- AddFor("Antlion",
- new LootRule().Chance(1.0 / 7.0).Item("Antlion Mandible")
- );
- #endregion
- #region hardmode
- AddFor("Dark Mummy",
- new LootRule().Chance(1.0 / 10.0).Item("Dark Shard")
- );
- AddFor("Light Mummy",
- new LootRule().Chance(1.0 / 10.0).Item("Light Shard")
- );
- AddFor(new string[] { "Mummy", "Dark Mummy", "Light Mummy" },
- new LootRule().Chance(1.0 / 75.0).Item("Mummy Mask"),
- new LootRule().Chance(1.0 / 75.0).Item("Mummy Shirt"),
- new LootRule().Chance(1.0 / 75.0).Item("Mummy Pants")
- );
- #endregion
- #endregion
- #region Snow
- #region pre-hardmode
- AddFor("Snow Flinx",
- new LootRule().Chance(1.0 / 150.0).Item("Snowball Launcher")
- );
- AddFor("Zombie Eskimo",
- new LootRule("Eskimo Set").Chance(1.0 / 50.0).Item(
- npc => new Item().SetDefaults(803 + Main.rand.Next(3))
- )
- );
- AddFor("Undead Viking",
- new LootRule().Chance(1.0 / 50.0).Item("Viking Helmet")
- );
- #endregion
- #region hardmode
- AddFor("Ice Golem",
- new LootRule().Chance(1.0 / 3.0).Item("Ice Feather"),
- new LootRule().Item("Frost Core")
- );
- AddFor("Armored Viking",
- new LootRule().Chance(1.0 / 200.0).Item("Ice Sickle")
- );
- AddFor("Ice Tortoise",
- new LootRule().Chance(1.0 / 100.0).Item("Frozen Turtle Shell")
- );
- AddFor(new string[] { "Ice Elemental", "Icy Merman" },
- new LootRule().Chance(1.0 / 50.0).Item("Frost Staff")
- );
- #endregion
- #endregion
- #region Underground
- #region pre-hardmode
- AddFor("Cave Bat",
- new LootRule().Chance(1.0 / 250.0).Item("Chain Knife"),
- new LootRule().Chance(1.0 / 200.0).Item("Depth Meter")
- );
- AddFor("Undead Miner",
- new LootRule().Chance(1.0 / 75.0).Item("Bone Pickaxe"),
- new LootRule().Conditional().LootRules(
- new LootRule("Mining Set").Chance(1.0 / 20.0).Weighted().LootRules(
- new LootRule().Item("Mining Shirt"),
- new LootRule().Item("Mining Pants")
- ),
- new LootRule().Item("Bomb").Stack(1, 3)
- )
- );
- AddFor(new int[] { 21, 201, 202, 203, 322, 323, 324 }, //Skeletons
- new LootRule().Conditional().LootRules(
- new LootRule().Chance(1.0 / 100.0).Item("Ancient Iron Helmet"),
- new LootRule().Chance(1.0 / 200.0).Item("Ancient Gold Helmet"),
- new LootRule().Chance(1.0 / 200.0).Item("Bone Sword"),
- new LootRule().Chance(1.0 / 500.0).Item("Skull")
- )
- );
- AddFor(new string[] { "Blue Jellyfish", "Pink Jellyfish", "Green Jellyfish" },
- new LootRule().Chance(1.0 / 100.0).Item("Jellyfish Necklace"),
- new LootRule().Item("Glowstick").Stack(1, 4)
- );
- AddFor(new object[] { "Skeleton", "Undead Miner", "Undead Viking", 201, 202, 203, 322, 323, 324 /*Skeleton variations*/ },
- new LootRule().Chance(1.0 / 25.0).Item("Hook")
- );
- AddFor("Tim",
- new LootRule().Item("Wizard Hat")
- );
- #endregion
- #region hardmode
- AddFor("Armored Skeleton",
- new LootRule().Chance(1.0 / 150.0).Item("Beam Sword")
- );
- AddFor("Skeleton Archer",
- new LootRule().Chance(1.0 / 100.0).Item("Magic Quiver"),
- new LootRule().Chance(1.0 / 200.0).Item("Marrow")
- );
- AddFor(new string[] { "Black Recluse", "Black Recluse 2" },
- new LootRule().Chance(1.0 / 40.0).Item("Poison Staff"),
- new LootRule("Spider Fangs").Chance(3.0 / 4.0).Conditional().LootRules(
- new LootRule().Chance(1.0 / 3.0).Item("Spider Fang").Stack(1, 3),
- new LootRule().Chance(1.0 / 2.0).Item("Spider Fang").Stack(1, 2),
- new LootRule().Item("Spider Fang")
- )
- );
- AddFor("Mimic",
- new LootRule().Rules(
- ruleHasValue
- ).Conditional().LootRules(
- new LootRule("Present Mimic").Rules(
- npc => npc.ai[3] == 4f
- ).Conditional().LootRules(
- new LootRule().Chance(1.0 / 20.0).Item("Toy Sled"),
- new LootRule().Weighted().LootRules(
- new LootRule().Item("Frostbrand"),
- new LootRule().Item("Ice Bow"),
- new LootRule().Item("Flower of Frost")
- )
- ),
- new LootRule().Weighted().LootRules(
- new LootRule().Item("Dual Hook"),
- new LootRule().Item("Magic Dagger"),
- new LootRule().Item("Philosopher's Stone"),
- new LootRule().Item("Titan Glove"),
- new LootRule().Item("Star Cloak"),
- new LootRule().Item("Compass"),
- new LootRule().Item("Cross Necklace")
- )
- )
- );
- AddFor("Rune Wizard",
- new LootRule().Item("Rune Hat"),
- new LootRule().Item("Rune Robe")
- );
- #endregion
- #endregion
- #region Corruption
- #region pre-hardmode
- AddFor("Eater of Souls",
- new LootRule("Ancient Shadow Set").Chance(1.0 / 175.0).Weighted().LootRules(
- new LootRule().Item("Ancient Shadow Helmet"),
- new LootRule().Item("Ancient Shadow Scalemail"),
- new LootRule().Item("Ancient Shadow Greaves")
- )
- );
- AddFor(new string[] { "Eater of Souls", "Corruptor" },
- new LootRule().Chance(1.0 / 3.0).Item("Rotten Chunk")
- );
- AddFor(new Tuple<int, int>(7, 9), //Devourer
- new LootRule().Chance(1.0 / 3.0).Item("Rotten Chunk").Stack(1, 2),
- new LootRule().Item("Worm Tooth").Stack(3, 8)
- );
- #endregion
- #region hardmode
- AddFor("Corrupt Slime",
- new LootRule().Item("Gel").Stack(2, 4)
- );
- AddFor(new string[] { "Seeker Head", "Clinger" },
- new LootRule().Item("Cursed Flame").Stack(2, 5)
- );
- #endregion
- #endregion
- #region Crimson
- #region pre-hardmode
- AddFor(new string[] { "Face Monster", "Crimera", "Floaty Gross", "Blood Crawler", "Blood Crawler 2" },
- new LootRule().Chance(1.0 / 3.0).Item("Vertebrae")
- );
- #endregion
- #region hardmode
- AddFor("Ichor Sticker",
- new LootRule().Item("Ichor").Stack(1, 3)
- );
- AddFor(new string[] { "Herpling", "Crimson Axe", "Floaty Gross", "Crimslime" },
- new LootRule().Chance(1.0 / 200.0).Item("Meat Grinder")
- );
- #endregion
- #endregion
- #region Hallow
- AddFor("Chaos Elemental",
- new LootRule().Chance(1.0 / 500.0).Item("Rod of Discord")
- );
- AddFor("Pixie",
- new LootRule().Item("Pixie Dust").Stack(1, 3)
- );
- AddFor("Unicorn",
- new LootRule().Item("Unicorn Horn"),
- new LootRule().Chance(1.0 / 100.0).Item("Unicorn on a Stick")
- );
- AddFor("Gastropod",
- new LootRule().Item("Gel").Stack(5, 10)
- );
- #endregion
- #region Jungle
- #region pre-hardmode
- AddFor(new object[] { "Hornet", "Man Eater", new Tuple<int, int>(231, 235) /*Hornets*/ },
- new LootRule("Ancient Cobalt Set").Chance(1.0 / 100.0).Weighted().LootRules(
- new LootRule().Item("Ancient Cobalt Helmet"),
- new LootRule().Item("Ancient Cobalt Breastplate"),
- new LootRule().Item("Ancient Cobalt Leggings")
- )
- );
- AddFor(new object[] { "Hornet", new Tuple<int, int>(231, 235) /*Hornets*/ },
- new LootRule().Chance(1.0 / 2.0).Item("Stinger")
- );
- AddFor("Man Eater",
- new LootRule().Chance(1.0 / 3.0).Item("Vine")
- );
- AddFor("Spiked Jungle Slime",
- new LootRule().Chance(1.0 / 3.0).Item("Stinger")
- );
- AddFor("Piranha",
- new LootRule().Conditional().LootRules(
- new LootRule().Chance(1.0 / 500.0).Item("Robot Hat"),
- new LootRule().Chance(1.0 / 40.0).Item("Hook")
- )
- );
- AddFor("Doctor Bones",
- new LootRule().Item("Archaeologist's Hat")
- );
- #endregion
- #region hardmode
- AddFor("Moss Hornet",
- new LootRule().Chance(1.0 / 150.0).Item("Tattered Bee Wing")
- );
- AddFor("Moth",
- new LootRule().Chance(1.0 / 2.0).Item("Butterfly Dust")
- );
- AddFor("Giant Tortoise",
- new LootRule().Chance(1.0 / 17.0).Item("Turtle Shell")
- );
- AddFor("Angler Fish",
- new LootRule().Conditional().LootRules(
- new LootRule().Chance(1.0 / 500.0).Item("Robot Hat")
- )
- );
- AddFor("Angry Trapper",
- new LootRule().Chance(1.0 / 200.0).Item("Uzi")
- );
- #endregion
- #endregion
- #region Dungeon
- #region pre-hardmode
- AddFor(new int[] { 31, 32, 294, 295, 296 }, //Angry Bones
- new LootRule().Chance(1.0 / 450.0).Item("Ancient Necro Helmet"),
- new LootRule().Chance(1.0 / 300.0).Item("Clothier Voodoo Doll")
- );
- AddFor("Dungeon Slime",
- new LootRule().Item("Golden Key")
- );
- AddFor(new string[] { "Angry Bones", "Dark Caster", "Cursed Skull" },
- new LootRule().Conditional().LootRules(
- new LootRule().Chance(1.0 / 250.0).Item("Bone Wand"),
- new LootRule().Chance(1.0 / 65.0).Item("Golden Key"),
- new LootRule().Item("Bone").Stack(1, 3)
- )
- );
- #endregion
- #region hardmode
- AddFor(new Tuple<int, int>(269, 280), //Rusty/Blue/Hell Armored Bones 1-4
- new LootRule().Chance(1.0 / 450.0).Item("Bone Feather"),
- new LootRule().Conditional().LootRules(
- new LootRule().Chance(1.0 / 600.0).Item("Wisp in a Bottle"),
- new LootRule().Chance(1.0 / 400.0).Item("Magnet Sphere"),
- new LootRule().Chance(1.0 / 300.0).Item("Keybrand")
- )
- );
- AddFor(new Tuple<int, int>(281, 282), //Ragged Caster 1-2
- new LootRule().Chance(1.0 / 40.0).Item("Spectre Staff")
- );
- AddFor(new Tuple<int, int>(283, 284), //Necromancer 1-2
- new LootRule().Chance(1.0 / 40.0).Item("Shadowbeam Staff")
- );
- AddFor(new Tuple<int, int>(285, 286), //Diabolist 1-2
- new LootRule().Chance(1.0 / 40.0).Item("Inferno Fork")
- );
- AddFor("Bone Lee",
- new LootRule().Chance(1.0 / 7.0).Weighted().LootRules(
- new LootRule().Item("Black Belt"),
- new LootRule().Item("Tabi")
- )
- );
- AddFor("Dungeon Spirit",
- new LootRule().Item("Ectoplasm").Stack(1, 2)
- );
- AddFor("Paladin",
- new LootRule().Weighted().LootRules(
- new LootRule().Weight(1.0 / 35.0).Item("Paladin's Hammer"),
- new LootRule().Weight(1.0 / 15.0).Item("Paladin's Shield")
- ).EmptyElseLootRule()
- );
- AddFor("Skeleton Sniper",
- new LootRule().Weighted().LootRules(
- new LootRule().Weight(1.0 / 15.0).Item("Rifle Scope"),
- new LootRule().Weight(1.0 / 15.0).Item("Sniper Rifle")
- ).EmptyElseLootRule()
- );
- AddFor("Tactical Skeleton",
- new LootRule().Weighted().LootRules(
- new LootRule().Weight(1.0 / 15.0).Item("SWAT Helmet"),
- new LootRule().Weight(1.0 / 15.0).Item("Tactical Shotgun")
- ).EmptyElseLootRule()
- );
- AddFor("Skeleton Commando",
- new LootRule().Chance(1.0 / 20.0).Item("Rocket Launcher")
- );
- #endregion
- #endregion
- #region Hell
- #region pre-hardmode
- AddFor("Fire Imp",
- new LootRule().Chance(1.0 / 75.0).Item("Obsidian Rose"),
- new LootRule().Chance(1.0 / 300.0).Item("Plumber's Hat")
- );
- AddFor("Hellbat",
- new LootRule().Chance(1.0 / 150.0).Item("Magma Stone")
- );
- AddFor("Demon",
- new LootRule().Chance(1.0 / 50.0).Item("Demon Scythe")
- );
- AddFor("Voodoo Demon",
- new LootRule().Item("Guide Voodoo Doll")
- );
- #endregion
- #region hardmode
- AddFor("Lava Bat",
- new LootRule().Chance(1.0 / 50.0).Item("Magma Stone")
- );
- AddFor("Red Devil",
- new LootRule().Chance(1.0 / 75.0).Item("Fire Feather"),
- new LootRule().Chance(1.0 / 30.0).Item("Unholy Trident")
- );
- #endregion
- #endregion
- #region Sky
- #region pre-hardmode
- AddFor("Harpy",
- new LootRule().Chance(1.0 / 200.0).Item("Giant Harpy Feather"),
- new LootRule().Chance(1.0 / 2.0).Item("Feather")
- );
- #endregion
- #region hardmode
- AddFor("Wyvern Head",
- new LootRule().Item("Soul of Flight").Stack(5, 10)
- );
- #endregion
- #endregion
- #region Jungle Temple
- AddFor(new string[] { "Lihzahrd", "Lihzahrd 2", "Flying Snake" },
- new LootRule().Chance(1.0 / 3000.0).Item("Lizard Egg"),
- new LootRule().Chance(1.0 / 50.0).Item("Lihzahrd Power Cell")
- );
- #endregion
- #region bosses
- AddFor("Eye of Cthulhu",
- new LootRule().Item("Lesser Healing Potion").Stack(5, 15),
- new LootRule().Times(npc => 5 + Main.rand.Next(5)).Item("Heart"),
- new LootRule().Chance(1.0 / 7.0).Item("Eye of Cthulhu Mask"),
- new LootRule().Chance(1.0 / 10.0).Item("Eye of Cthulhu Trophy"),
- new LootRule().Chance(1.0 / 150.0).Item("Binoculars"),
- new LootRule().Rules(
- npc => WorldGen.crimson
- ).LootRules(
- new LootRule().Times(3).Item("Crimtane Ore").Stack(10, 30),
- new LootRule().Item("Crimson Seeds").Stack(1, 3)
- ),
- new LootRule().Rules(
- npc => WorldGen.corruption
- ).LootRules(
- new LootRule().Item("Unholy Arrow").Stack(20, 50),
- new LootRule().Times(3).Item("Demonite Ore").Stack(10, 30),
- new LootRule().Item("Corrupt Seeds").Stack(1, 3)
- ),
- new LootRule().Code(
- npc => DownedBoss(ref NPC.downedBoss1)
- ),
- new LootRule("Message").Code(npc => {
- DownedBossMessage(npc.displayName + " " + Lang.misc[17]);
- })
- );
- AddFor(new Tuple<int, int>(13, 15), //Eater of Worlds
- new LootRule().Chance(1.0 / 2.0).Item("Shadow Scale").Stack(1, 2),
- new LootRule().Chance(1.0 / 2.0).Item("Demonite Ore").Stack(2, 5),
- new LootRule().Rules(
- npc => npc.boss
- ).LootRules(
- new LootRule().Item("Lesser Healing Potion").Stack(5, 15),
- new LootRule().Times(npc => 5 + Main.rand.Next(5)).Item("Heart"),
- new LootRule().Chance(1.0 / 30.0).Item("Eater's Bone"),
- new LootRule().Chance(1.0 / 7.0).Item("Eater of Worlds Mask"),
- new LootRule().Chance(1.0 / 10.0).Item("Eater of Worlds Trophy"),
- new LootRule().Code(
- npc => DownedBoss(ref NPC.downedBoss2)
- ),
- new LootRule("Message").Code(npc => {
- DownedBossMessage(npc.displayName + " " + Lang.misc[17]);
- })
- ),
- new LootRule().Chance(1.0 / 4.0).Rules(
- RuleClosestPlayer((npc, player) => player.statLife < player.statLifeMax2)
- ).Item("Heart")
- );
- AddFor("Brain of Cthulhu",
- new LootRule().Item("Lesser Healing Potion").Stack(5, 15),
- new LootRule().Times(npc => 5 + Main.rand.Next(5)).Item("Heart"),
- new LootRule().Chance(1.0 / 7.0).Item("Brain of Cthulhu Mask"),
- new LootRule().Chance(1.0 / 10.0).Item("Brain of Cthulhu Trophy"),
- new LootRule().Times(2).Item("Crimtane Ore").Stack(10, 30),
- new LootRule().Code(
- npc => DownedBoss(ref NPC.downedBoss2)
- ),
- new LootRule("Message").Code(npc => {
- DownedBossMessage(npc.displayName + " " + Lang.misc[17]);
- })
- );
- AddFor("Creeper",
- new LootRule().Rules(
- npc => NPC.AnyNPCs(266) //Brain of Cthulhu
- ).LootRules(
- new LootRule().Chance(1.0 / 3.0).Item("Tissue Sample").Stack(2, 5),
- new LootRule().Chance(1.0 / 3.0).Item("Crimtane Ore").Stack(4, 10),
- new LootRule().Chance(1.0 / 2.0).Rules(
- RuleClosestPlayer((npc, player) => player.statLife < player.statLifeMax2)
- ).Item("Heart")
- )
- );
- AddFor("King Slime",
- new LootRule().Times(npc => 5 + Main.rand.Next(5)).Item("Heart"),
- new LootRule().Chance(1.0 / 7.0).Item("King Slime Mask"),
- new LootRule().Chance(1.0 / 10.0).Item("King Slime Trophy"),
- new LootRule().Chance(1.0 / 30.0).Item("Slimy Saddle"),
- new LootRule("Ninja Set").Weighted().LootRules(
- new LootRule().Item("Ninja Hood"),
- new LootRule().Item("Ninja Shirt"),
- new LootRule().Item("Ninja Pants")
- ),
- new LootRule().Weighted().LootRules(
- new LootRule().Item("Slime Gun"),
- new LootRule().Item("Slime Hook")
- ),
- new LootRule("Message").Code(npc => {
- DownedBossMessage(npc.displayName + " " + Lang.misc[17]);
- })
- );
- AddFor("Skeletron Head",
- new LootRule().Item("Lesser Healing Potion").Stack(5, 15),
- new LootRule().Times(npc => 5 + Main.rand.Next(5)).Item("Heart"),
- new LootRule().Conditional().LootRules(
- new LootRule().Chance(1.0 / 7.0).Item("Skeletron Mask"),
- new LootRule().Chance(1.0 / 7.0).Item("Skeletron Hand"),
- new LootRule().Chance(1.0 / 7.0).Item("Book of Skulls")
- ),
- new LootRule().Chance(1.0 / 10.0).Item("Skeletron Trophy"),
- new LootRule().Code(
- npc => DownedBoss(ref NPC.downedBoss3)
- ),
- new LootRule("Message").Code(npc => {
- DownedBossMessage(npc.displayName + " " + Lang.misc[17]);
- })
- );
- AddFor("Dungeon Guardian",
- new LootRule().Item("Bone Key")
- );
- AddFor("Queen Bee",
- new LootRule().Item("Bottled Honey").Stack(5, 15),
- new LootRule().Times(npc => 5 + Main.rand.Next(5)).Item("Heart"),
- new LootRule().Chance(1.0 / 7.0).Item("Queen Bee Mask"),
- new LootRule().Chance(1.0 / 10.0).Item("Queen Bee Trophy"),
- new LootRule().Weighted().LootRules(
- new LootRule().Item("Bee Gun"),
- new LootRule().Item("Bee Keeper"),
- new LootRule().Item("Honey Comb")
- ),
- new LootRule().Chance(1.0 / 20.0).Item("Nectar"),
- new LootRule().Chance(1.0 / 100.0).Item("Honeyed Goggles"),
- new LootRule().Conditional().LootRules(
- new LootRule().Chance(1.0 / 3.0).Item("Hive Wand"),
- new LootRule("Bee Set").Chance(1.0 / 2.0).Weighted().LootRules(
- new LootRule().Item("Bee Hat"),
- new LootRule().Item("Bee Shirt"),
- new LootRule().Item("Bee Pants")
- )
- ),
- new LootRule().Chance(1.0 / 4.0).Item("Beenade").Stack(10, 30),
- new LootRule().Item("Bee Wax").Stack(16, 26),
- new LootRule().Code(
- npc => DownedBoss(ref NPC.downedQueenBee)
- ),
- new LootRule("Message").Code(npc => {
- DownedBossMessage(npc.displayName + " " + Lang.misc[17]);
- })
- );
- AddFor("Wall of Flesh",
- new LootRule().Item("Healing Potion").Stack(5, 15),
- new LootRule().Times(npc => 5 + Main.rand.Next(5)).Item("Heart"),
- new LootRule().Chance(1.0 / 7.0).Item("Wall of Flesh Mask"),
- new LootRule().Chance(1.0 / 10.0).Item("Wall of Flesh Trophy"),
- new LootRule().Item("Pwnhammer"),
- new LootRule().Weighted().LootRules(
- new LootRule("Emblem").Weighted().LootRules(
- new LootRule().Item("Sorcerer Emblem"),
- new LootRule().Item("Warrior Emblem"),
- new LootRule().Item("Ranger Emblem")
- ),
- new LootRule().Weighted().LootRules(
- new LootRule().Item("Laser Rifle"),
- new LootRule().Item("Breaker Blade"),
- new LootRule().Item("Clockwork Assault Rifle")
- )
- ),
- new LootRule("Loot Cage").Code(npc => {
- if (Main.netMode != 1)
- {
- int num22 = (int)(npc.position.X + (npc.width / 2)) / 16;
- int num23 = (int)(npc.position.Y + (npc.height / 2)) / 16;
- int num24 = npc.width / 2 / 16 + 1;
- for (int k = num22 - num24; k <= num22 + num24; k++)
- {
- for (int l = num23 - num24; l <= num23 + num24; l++)
- {
- if ((k == num22 - num24 || k == num22 + num24 || l == num23 - num24 || l == num23 + num24) && !Main.tile[k, l].active())
- {
- Main.tile[k, l].type = 140;
- Main.tile[k, l].active(true);
- }
- Main.tile[k, l].lava(false);
- Main.tile[k, l].liquid = 0;
- if (Main.netMode == 2)
- {
- NetMessage.SendTileSquare(-1, k, l, 1);
- }
- else
- {
- WorldGen.SquareTileFrame(k, l, true);
- }
- }
- }
- }
- }),
- new LootRule("Message").Code(npc => {
- DownedBossMessage(npc.displayName + " " + Lang.misc[17]);
- }),
- new LootRule("Hardmode").Rules(
- npc => Main.netMode != 1,
- npc => !Main.hardMode
- ).Code(npc => {
- bool hardMode = Main.hardMode;
- WorldGen.StartHardmode();
- if (NPC.downedMechBoss1 && NPC.downedMechBoss2 && NPC.downedMechBoss3 && !hardMode)
- {
- DownedBossMessage(Lang.misc[32], 50, 255, 130);
- }
- })
- );
- AddFor(new Tuple<int, int>(116, 119), //The Hungry (without 1)
- new LootRule().Item("Heart")
- );
- AddFor("The Destroyer",
- new LootRule().Item("Greater Healing Potion").Stack(5, 15),
- new LootRule().Times(npc => 5 + Main.rand.Next(5)).Item("Heart"),
- new LootRule().Chance(1.0 / 7.0).Item("Destroyer Mask"),
- new LootRule().Chance(1.0 / 10.0).Item("Destroyer Trophy"),
- new LootRule().Item("Soul of Might").Stack(25, 40),
- new LootRule().Item("Hallowed Bar").Stack(15, 30),
- new LootRule().Code(npc => {
- NPC.downedMechBossAny = true;
- DownedBoss(ref NPC.downedMechBoss1);
- }),
- new LootRule("Message").Code(npc => {
- DownedBossMessage(npc.displayName + " " + Lang.misc[17]);
- }),
- new LootRule("Restless Jungle").Rules(
- npc => NPC.downedMechBoss2 && NPC.downedMechBoss3
- ).Code(npc => {
- DownedBossMessage(Lang.misc[32], 50, 255, 130);
- })
- );
- AddFor("Probe",
- new LootRule().Chance(1.0 / 2.0).Item("Heart")
- );
- AddFor("Skeletron Prime",
- new LootRule().Item("Greater Healing Potion").Stack(5, 15),
- new LootRule().Times(npc => 5 + Main.rand.Next(5)).Item("Heart"),
- new LootRule().Chance(1.0 / 7.0).Item("Skeletron Prime Mask"),
- new LootRule().Chance(1.0 / 10.0).Item("Skeletron Prime Trophy"),
- new LootRule().Item("Soul of Fright").Stack(25, 40),
- new LootRule().Item("Hallowed Bar").Stack(15, 30),
- new LootRule().Code(npc => {
- NPC.downedMechBossAny = true;
- DownedBoss(ref NPC.downedMechBoss3);
- }),
- new LootRule("Message").Code(npc => {
- DownedBossMessage(npc.displayName + " " + Lang.misc[17]);
- }),
- new LootRule("Restless Jungle").Rules(
- npc => NPC.downedMechBoss1 && NPC.downedMechBoss2
- ).Code(npc => {
- DownedBossMessage(Lang.misc[32], 50, 255, 130);
- })
- );
- AddFor(new string[] { "Retinazer", "Spazmatism" },
- new LootRule().Conditional().LootRules(
- new LootRule("Last one").Rules(
- npc => !NPC.AnyNPCs(npc.name == "Vanilla:Retinazer" ? "Vanilla:Spazmatism" : "Vanilla:Retinazer")
- ).LootRules(
- new LootRule().Item("Greater Healing Potion").Stack(5, 15),
- new LootRule().Times(npc => 5 + Main.rand.Next(5)).Item("Heart"),
- new LootRule().Chance(1.0 / 7.0).Item("Twin Mask"),
- new LootRule().Item("Soul of Sight").Stack(25, 40),
- new LootRule().Item("Hallowed Bar").Stack(15, 30),
- new LootRule().Code(npc => {
- NPC.downedMechBossAny = true;
- DownedBoss(ref NPC.downedMechBoss2);
- }),
- new LootRule("Message").Code(npc => {
- DownedBossMessage("The Twins " + Lang.misc[17]);
- }),
- new LootRule("Restless Jungle").Rules(
- npc => NPC.downedMechBoss1 && NPC.downedMechBoss3
- ).Code(npc => {
- DownedBossMessage(Lang.misc[32], 50, 255, 130);
- })
- ),
- new LootRule("Fix").Code(npc => {
- npc.value = 0;
- npc.boss = false;
- })
- )
- );
- AddFor("Retinazer",
- new LootRule().Chance(1.0 / 10.0).Item("Retinazer Trophy")
- );
- AddFor("Spazmatism",
- new LootRule().Chance(1.0 / 10.0).Item("Spazmatism Trophy")
- );
- AddFor("Plantera",
- new LootRule().Item("Greater Healing Potion").Stack(5, 15),
- new LootRule().Times(npc => 5 + Main.rand.Next(5)).Item("Heart"),
- new LootRule().Chance(1.0 / 7.0).Item("Plantera Mask"),
- new LootRule().Chance(1.0 / 10.0).Item("Plantera Trophy"),
- new LootRule().Item("Temple Key"),
- new LootRule().Chance(1.0 / 20.0).Item("Seedling"),
- new LootRule().Chance(1.0 / 200.0).Item("The Axe"),
- new LootRule().Chance(1.0 / 4.0).Item("Pygmy Staff"),
- new LootRule().Conditional().LootRules(
- new LootRule().Rules(
- npc => NPC.downedPlantBoss
- ).Weighted().LootRules(
- new LootRule("Grenade Launcher").LootRules(
- new LootRule().Item("Grenade Launcher"),
- new LootRule().Item("Rocket I").Stack(20, 50)
- ),
- new LootRule().Item("Venus Magnum"),
- new LootRule().Item("Nettle Burst"),
- new LootRule().Item("Leaf Blower"),
- new LootRule().Item("Flower Pow"),
- new LootRule().Item("Wasp Gun")
- ),
- new LootRule("Grenade Launcher").LootRules(
- new LootRule().Item("Grenade Launcher"),
- new LootRule().Item("Rocket I").Stack(20, 50)
- )
- ),
- new LootRule().Code(npc => {
- if (!NPC.downedPlantBoss)
- {
- if (Main.netMode == 0)
- {
- Main.NewText(Lang.misc[33], 50, 255, 130, false);
- }
- else if (Main.netMode == 2)
- {
- NetMessage.SendData(25, -1, -1, Lang.misc[33], 255, 50f, 255f, 130f, 0);
- }
- }
- DownedBoss(ref NPC.downedPlantBoss);
- }),
- new LootRule("Message").Code(npc => {
- DownedBossMessage(npc.displayName + " " + Lang.misc[17]);
- })
- );
- AddFor("Golem",
- new LootRule().Item("Greater Healing Potion").Stack(5, 15),
- new LootRule().Times(npc => 5 + Main.rand.Next(5)).Item("Heart"),
- new LootRule().Chance(1.0 / 7.0).Item("Golem Mask"),
- new LootRule().Chance(1.0 / 10.0).Item("Golem Trophy"),
- new LootRule().Weighted().LootRules(
- new LootRule("Stynger").LootRules(
- new LootRule().Item("Stynger"),
- new LootRule().Item("Stynger Bolt").Stack(60, 100)
- ),
- new LootRule().Item("Possessed Hatchet"),
- new LootRule().Item("Sun Stone"),
- new LootRule().Item("Eye of the Golem"),
- new LootRule().Item("Picksaw"),
- new LootRule().Item("Heat Ray"),
- new LootRule().Item("Staff of Earth"),
- new LootRule().Item("Golem Fist")
- ),
- new LootRule().Item("Beetle Husk").Stack(4, 8),
- new LootRule().Code(
- npc => DownedBoss(ref NPC.downedGolemBoss)
- ),
- new LootRule("Message").Code(npc => {
- DownedBossMessage(npc.displayName + " " + Lang.misc[17]);
- })
- );
- AddFor("Duke Fishron",
- new LootRule().Item("Greater Healing Potion").Stack(5, 15),
- new LootRule().Times(npc => 5 + Main.rand.Next(5)).Item("Heart"),
- new LootRule().Chance(1.0 / 7.0).Item("Duke Fishron Mask"),
- new LootRule().Chance(1.0 / 10.0).Item("Duke Fishron Trophy"),
- new LootRule().Chance(1.0 / 15.0).Item("Fishron Wings"),
- new LootRule().Weighted().LootRules(
- new LootRule().Item("Flairon"),
- new LootRule().Item("Tsunami"),
- new LootRule().Item("Razorblade Typhoon"),
- new LootRule().Item("Tempest Staff"),
- new LootRule().Item("Bubble Gun")
- ),
- new LootRule().Code(
- npc => DownedBoss(ref NPC.downedFishron)
- ),
- new LootRule("Message").Code(npc => {
- DownedBossMessage(npc.displayName + " " + Lang.misc[17]);
- })
- );
- #endregion
- #region Goblin Army related
- AddFor("Goblin Scout",
- new LootRule().Item("Tattered Cloth").Stack(1, 2)
- );
- AddFor(new object[] { new Tuple<int, int>(26, 29), 111 }, //all Goblins in the Goblin Army invasion
- new LootRule().Conditional().LootRules(
- new LootRule().Chance(1.0 / 200.0).Item("Harpoon"),
- new LootRule().Chance(1.0 / 2.0).Item("Spiky Ball").Stack(1, 5)
- )
- );
- #endregion
- #region Frost Legion
- AddFor(new string[] { "Snowman Gangsta", "Mister Stabby", "Snow Balla" },
- new LootRule().Item("Snow Block").Stack(5, 10)
- );
- #endregion
- #region Solar Eclipse
- AddFor("Reaper",
- new LootRule().Chance(1.0 / 250.0).Item("Death Sickle")
- );
- AddFor("Eyezor",
- new LootRule().Chance(1.0 / 50.0).Item("Eye Spring")
- );
- AddFor(new string[] { "Frankenstein", "Swamp Thing" },
- new LootRule().Chance(1.0 / 250.0).Item("Broken Hero Sword")
- );
- AddFor(new int[] { 158, 159 }, //Vampire 1-2
- new LootRule().Chance(1.0 / 40.0).Item("Broken Bat Wing"),
- new LootRule().Chance(1.0 / 100.0).Item("Moon Stone")
- );
- #endregion
- #region Pirate Invasion
- AddFor(new Tuple<int, int>(212, 215), //Pirate Deckhand/Corsair/Deadeye/Crossbower
- new LootRule().Chance(1.0 / 8000.0).Item("Coin Gun"),
- new LootRule().Chance(1.0 / 4000.0).Item("Lucky Coin"),
- new LootRule().Chance(1.0 / 2000.0).Item("Discount Card"),
- new LootRule().Chance(1.0 / 2000.0).Item("Pirate Staff"),
- new LootRule().Chance(1.0 / 200.0).Item("Cutlass"),
- new LootRule().Chance(1.0 / 500.0).Item("Sailor Hat"),
- new LootRule().Chance(1.0 / 500.0).Item("Eye Patch"),
- new LootRule().Chance(1.0 / 500.0).Item("Sailor Shirt"),
- new LootRule().Chance(1.0 / 500.0).Item("Sailor Pants"),
- new LootRule().Chance(1.0 / 300.0).Item("Golden Chair"),
- new LootRule().Chance(1.0 / 300.0).Item("Golden Toilet"),
- new LootRule().Chance(1.0 / 300.0).Item("Golden Door"),
- new LootRule().Chance(1.0 / 300.0).Item("Golden Table"),
- new LootRule().Chance(1.0 / 300.0).Item("Golden Bed"),
- new LootRule().Chance(1.0 / 300.0).Item("Golden Piano"),
- new LootRule().Chance(1.0 / 300.0).Item("Golden Dresser"),
- new LootRule().Chance(1.0 / 300.0).Item("Golden Sofa"),
- new LootRule().Chance(1.0 / 300.0).Item("Golden Bathtub"),
- new LootRule().Chance(1.0 / 300.0).Item("Golden Clock"),
- new LootRule().Chance(1.0 / 300.0).Item("Golden Lamp"),
- new LootRule().Chance(1.0 / 300.0).Item("Golden Bookcase"),
- new LootRule().Chance(1.0 / 300.0).Item("Golden Chandelier"),
- new LootRule().Chance(1.0 / 300.0).Item("Golden Candelabra"),
- new LootRule().Chance(1.0 / 300.0).Item("Golden Candle")
- );
- AddFor("Pirate Captain",
- new LootRule().Chance(1.0 / 2000.0).Item("Coin Gun"),
- new LootRule().Chance(1.0 / 1000.0).Item("Lucky Coin"),
- new LootRule().Chance(1.0 / 500.0).Item("Discount Card"),
- new LootRule().Chance(1.0 / 500.0).Item("Pirate Staff"),
- new LootRule().Chance(1.0 / 50.0).Item("Cutlass")
- );
- #endregion
- #region Pumpkin Moon
- AddFor(new Tuple<int, int>(305, 314), //Scarecrow 1-10
- new LootRule("Pumpkin Moon").Chance(
- npc => 1.0 / Math.Max((int)((17 - NPC.waveCount) / 1.25), 1)
- ).Rules(
- rulePumpkinMoon
- ).LootRules(
- new LootRule("Scarecrow Set").Chance(1.0 / 10.0).Item(
- npc => new Item().SetDefaults(1788 + Main.rand.Next(3))
- )
- ),
- new LootRule().Chance(1.0 / 4.0).Item("Heart")
- );
- AddFor("Splinterling",
- new LootRule().Item("Spooky Wood").Stack(1, 4),
- new LootRule().Chance(1.0 / 6.0).Item("Heart")
- );
- AddFor("Hellhound",
- new LootRule().Chance(1.0 / 4.0).Item("Heart")
- );
- AddFor("Poltergeist",
- new LootRule().Chance(1.0 / 4.0).Item("Heart")
- );
- AddFor("Headless Horseman",
- new LootRule("Pumpkin Moon").Chance(
- npc => 1.0 / Math.Max((int)((17 - NPC.waveCount) / 1.25), 1)
- ).Rules(
- rulePumpkinMoon
- ).LootRules(
- new LootRule().Chance(1.0 / 20.0).Item("Jack 'O Lantern Mask")
- ),
- new LootRule().Item("Heart")
- );
- AddFor("Mourning Wood",
- new LootRule("Pumpkin Moon").Rules(
- rulePumpkinMoon
- ).LootRules(
- new LootRule().Rules(
- npc => NPC.waveCount == 15
- ).Item("Mourning Wood Trophy"),
- new LootRule("Wave Chance").Chance(
- npc => 1.0 / Math.Max((int)((17 - NPC.waveCount) / 1.25), 1)
- ).LootRules(
- new LootRule().Weighted().LootRules(
- new LootRule().Item("Spooky Hook"),
- new LootRule().Item("Spooky Twig"),
- new LootRule("Stake Launcher").LootRules(
- new LootRule().Item("Stake Launcher"),
- new LootRule().Item("Stake").Stack(30, 60)
- ),
- new LootRule().Item("Cursed Sapling"),
- new LootRule().Item("Necromantic Scroll")
- )
- )
- ),
- new LootRule().Item("Spooky Wood").Stack(30, 50),
- new LootRule().Times(
- npc => 5 + Main.rand.Next(6)
- ).Item("Heart")
- );
- AddFor("Pumpking",
- new LootRule("Pumpkin Moon").Rules(
- rulePumpkinMoon
- ).LootRules(
- new LootRule().Rules(
- npc => NPC.waveCount == 15
- ).Item("Pumpking Trophy"),
- new LootRule("Wave Chance").Chance(
- npc => 1.0 / Math.Max((int)((17 - NPC.waveCount) / 1.25), 1)
- ).LootRules(
- new LootRule().Weighted().LootRules(
- new LootRule("Candy Corn Rifle").LootRules(
- new LootRule().Item("Candy Corn Rifle"),
- new LootRule().Item("Candy Corn").Stack(50, 100)
- ),
- new LootRule("Jack 'O Lantern Launcher").LootRules(
- new LootRule().Item("Jack 'O Lantern Launcher"),
- new LootRule().Item("Explosive Jack 'O Lantern").Stack(25, 50)
- ),
- new LootRule().Item("Black Fairy Dust"),
- new LootRule().Item("The Horseman's Blade"),
- new LootRule().Item("Bat Scepter"),
- new LootRule().Item("Raven Staff"),
- new LootRule().Item("Spider Egg")
- )
- )
- ),
- new LootRule().Times(
- npc => 5 + Main.rand.Next(6)
- ).Item("Heart")
- );
- #endregion
- #region Frost Moon
- AddFor("Present Mimic",
- new LootRule().Times(
- npc => 5 + Main.rand.Next(6)
- ).Item("Heart"),
- new LootRule().Rules(
- ruleChristmas
- ).Item("Present")
- );
- AddFor(new Tuple<int, int>(338, 340), //Zombie Elf 1-3
- new LootRule().Chance(1.0 / 5.0).Item("Heart"),
- new LootRule("Elf Set").Chance(1.0 / 200.0).Weighted().LootRules(
- new LootRule().Item("Elf Hat"),
- new LootRule().Item("Elf Shirt"),
- new LootRule().Item("Elf Pants")
- )
- );
- AddFor("Gingerbread Man",
- new LootRule().Chance(1.0 / 3.0).Item("Heart")
- );
- AddFor("Everscream",
- new LootRule("Frost Moon").Rules(
- ruleFrostMoon
- ).LootRules(
- new LootRule("Wave Chance").Chance(
- npc => 1.0 / Math.Max((int)((30 - NPC.waveCount) / 2.5), 1)
- ).LootRules(
- new LootRule().Conditional().LootRules(
- new LootRule().Chance(1.0 / 15.0).Item("Festive Wings"),
- new LootRule().Weighted().LootRules(
- new LootRule().Item("Christmas Hook"),
- new LootRule().Item("Christmas Tree Sword"),
- new LootRule().Item("Razorpine")
- )
- ),
- new LootRule().Chance(
- npc => 1.0 / (4 + (NPC.waveCount - 15) / 2)
- ).Rules(
- npc => NPC.waveCount >= 15
- ).Item("Everscream Trophy")
- )
- ),
- new LootRule().Times(
- npc => 5 + Main.rand.Next(6)
- ).Item("Heart")
- );
- AddFor("Ice Queen",
- new LootRule("Frost Moon").Rules(
- ruleFrostMoon
- ).LootRules(
- new LootRule("Wave Chance").Chance(
- npc => 1.0 / Math.Max((int)((30 - NPC.waveCount) / 2.5), 1)
- ).LootRules(
- new LootRule().Conditional().LootRules(
- new LootRule().Chance(1.0 / 30.0).Rules(
- npc => NPC.waveCount >= 15
- ).Item("Reindeer Bells"),
- new LootRule().Chance(1.0 / 15.0).Item("Baby Grinch's Mischief Whistle"),
- new LootRule().Weighted().LootRules(
- new LootRule().Item("Blizzard Staff"),
- new LootRule().Item("Snowman Cannon"),
- new LootRule().Item("North Pole")
- )
- ),
- new LootRule().Chance(
- npc => 1.0 / (4 + (NPC.waveCount - 15) / 2)
- ).Rules(
- npc => NPC.waveCount >= 15
- ).Item("Ice Queen Trophy")
- )
- ),
- new LootRule().Times(
- npc => 5 + Main.rand.Next(6)
- ).Item("Heart")
- );
- AddFor("Santa-NK1",
- new LootRule("Frost Moon").Rules(
- ruleFrostMoon
- ).LootRules(
- new LootRule("Wave Chance").Chance(
- npc => 1.0 / Math.Max((int)((30 - NPC.waveCount) / 2.5), 1)
- ).LootRules(
- new LootRule().Weighted().LootRules(
- new LootRule().Item("Elf Melter"),
- new LootRule().Item("Chain Gun")
- ),
- new LootRule().Chance(
- npc => 1.0 / (4 + (NPC.waveCount - 15) / 2)
- ).Rules(
- npc => NPC.waveCount >= 15
- ).Item("Santa-NK1 Trophy")
- )
- ),
- new LootRule().Times(
- npc => 5 + Main.rand.Next(6)
- ).Item("Heart")
- );
- #endregion
- #region generic
- AddFor(new string[] { "Pixie", "Mummy", "Wraith" },
- new LootRule().Chance(1.0 / 100.0).Item("Fast Clock")
- );
- AddFor(new string[] { "Corrupt Slime", "Dark Mummy" },
- new LootRule().Chance(1.0 / 100.0).Item("Blindfold")
- );
- AddFor(new string[] { "Pixie", "Dark Mummy", "Green Jellyfish" },
- new LootRule().Chance(1.0 / 100.0).Item("Megaphone")
- );
- AddFor(new string[] { "Cursed Hammer", "Enchanted Sword", "Cursed Skull", "Crimson Axe" },
- new LootRule().Chance(1.0 / 100.0).Item("Nazar")
- );
- AddFor(new string[] { "Enchanted Sword", "Floaty Gross" },
- new LootRule().Chance(1.0 / 100.0).Item("Vitamins")
- );
- AddFor(new object[] { "Angler Fish", "Werewolf", new Tuple <int, int>(269,272) },
- new LootRule().Chance(1.0 / 100.0).Item("Adhesive Bandage")
- );
- AddFor(new string[] { "Clown", "Light Mummy", "Giant Bat" },
- new LootRule().Chance(1.0 / 100.0).Item("Trifold Map")
- );
- AddFor(new object[] { "Hornet", "Toxic Sludge", "Moss Hornet", new Tuple<int, int>(231, 235) /*Hornets*/ },
- new LootRule().Chance(1.0 / 100.0).Item("Bezoar")
- );
- AddFor(new object[] { new Tuple<int, int>(273, 276) /*Blue Armored Bones 1-4*/, "Armored Skeleton", "Heavy Skeleton", "Paladin" },
- new LootRule().Chance(1.0 / 100.0).Item("Armor Polish")
- );
- AddFor("Cochineal Beetle",
- new LootRule().Item("Red Husk")
- );
- AddFor("Cyan Beetle",
- new LootRule().Item("Cyan Husk")
- );
- AddFor("Lac Beetle",
- new LootRule().Item("Violet Husk")
- );
- AddFor("Sea Snail",
- new LootRule().Item("Purple Mucos")
- );
- AddFor("Squid",
- new LootRule().Item("Black Ink")
- );
- #endregion
- #endregion
- #region town NPCs
- AddFor("Guide",
- new LootRule().Rules(
- npc => npc.displayName == "Andrew"
- ).Item("Green Cap")
- );
- AddFor("Clothier",
- new LootRule().Item("Red Hat")
- );
- AddFor("Travelling Merchant",
- new LootRule().Item("Peddler's Hat")
- );
- #endregion
- settingUp = false;
- }
- public static void DownedBoss(ref bool b)
- {
- if (!b)
- {
- b = true;
- if (Main.netMode == 2)
- {
- NetMessage.SendData(7, -1, -1, "", 0, 0f, 0f, 0f, 0);
- }
- }
- }
- public static void DownedBossMessage(string message)
- {
- DownedBossMessage(message, 175, 75, 255);
- }
- public static void DownedBossMessage(string message, int r, int g, int b)
- {
- if (Main.netMode == 0)
- {
- Main.NewText(message, (byte)r, (byte)g, (byte)b, false);
- }
- else if (Main.netMode == 2)
- {
- NetMessage.SendData(25, -1, -1, message, 255, r, g, b, 0);
- }
- }
- public static void Add(params LootRule[] rules)
- {
- globalRules.AddRange(rules);
- }
- public static void AddFor(object[] npcs, params LootRule[] rules)
- {
- foreach (object npc in npcs)
- {
- if (npc is string)
- AddFor((string)npc, rules);
- else if (npc is int)
- AddFor((int)npc, rules);
- else if (npc is string[])
- AddFor((string[])npc, rules);
- else if (npc is int[])
- AddFor((int[])npc, rules);
- else if (npc is Tuple<int, int>)
- AddFor((Tuple<int, int>)npc, rules);
- }
- }
- public static void AddFor(string npcName, params LootRule[] rules)
- {
- if (npcName.IndexOf(':') == -1)
- {
- npcName = "Vanilla:" + npcName;
- }
- AddFor(NPCDef.byName[npcName].type, rules);
- }
- public static void AddFor(int[] types, params LootRule[] rules)
- {
- foreach (int type in types)
- {
- AddFor(type, rules);
- }
- }
- public static void AddFor(string[] npcNames, params LootRule[] rules)
- {
- foreach (string npcName in npcNames)
- {
- AddFor(npcName, rules);
- }
- }
- public static void AddForName(string npcName, params LootRule[] rules)
- {
- if (npcName.IndexOf(':') == -1)
- {
- npcName = "Vanilla:" + npcName;
- }
- if (!rulesName.ContainsKey(npcName))
- {
- rulesName[npcName] = new List<LootRule>();
- }
- rulesName[npcName].AddRange(rules);
- }
- public static void AddForName(string[] npcNames, params LootRule[] rules)
- {
- foreach (string npcName in npcNames)
- {
- AddForName(npcName, rules);
- }
- }
- public static void AddFor(int type, params LootRule[] rules)
- {
- if (!rulesType.ContainsKey(type))
- {
- rulesType[type] = new List<LootRule>();
- }
- rulesType[type].AddRange(rules);
- }
- public static void AddFor(Tuple<int, int> range, params LootRule[] rules)
- {
- for (int i = range.Item1; i <= range.Item2; i++)
- {
- AddFor(i, rules);
- }
- }
- public static Tuple<List<Item>, List<Action<NPC>>> GetResults(NPC npc)
- {
- foreach (Func<NPC, bool> filter in filters)
- {
- if (filter(npc))
- {
- return new Tuple<List<Item>, List<Action<NPC>>>(new List<Item>(), new List<Action<NPC>>());
- }
- }
- List<LootRule> rules = new List<LootRule>();
- if (rulesName.ContainsKey(npc.name))
- rules.AddRange(rulesName[npc.name]);
- if (rulesType.ContainsKey(npc.type))
- rules.AddRange(rulesType[npc.type]);
- rules.AddRange(globalRules);
- return GetResultsFor(npc, rules);
- }
- public static Tuple<List<Item>, List<Action<NPC>>> GetResultsFor(NPC npc, List<LootRule> rules)
- {
- List<Item> list = new List<Item>();
- List<Action<NPC>> list2 = new List<Action<NPC>>();
- foreach (LootRule rule in rules)
- {
- Tuple<List<Item>, List<Action<NPC>>> tuple = rule.GetResult(npc);
- list.AddRange(tuple.Item1);
- list2.AddRange(tuple.Item2);
- }
- return new Tuple<List<Item>, List<Action<NPC>>>(list, list2);
- }
- public LootRule parent = null, copy = null;
- public string name = null;
- public List<Func<NPC, bool>> rules = new List<Func<NPC, bool>>();
- public Dynamic<double> weight = 1.0, chance = 1.0;
- public DynamicItem item = new Item();
- public Dynamic<int> minStack = 1, maxStack = 1, times = 1;
- public Action<NPC> code = null;
- public List<LootRule> subrules = new List<LootRule>();
- public bool conditional = false, weighted = false;
- public LootRule elseSubrule = null;
- public bool enabled = true, modified = false;
- public LootRule(string name = null)
- {
- this.name = name;
- }
- public LootRule Rules(params Func<NPC, bool>[] rules)
- {
- this.rules.AddRange(rules);
- return MarkModified();
- }
- public LootRule Weight(double weight = 1)
- {
- this.weight.value = weight;
- return MarkModified();
- }
- public LootRule Weight(Func<NPC, double> f)
- {
- weight.func = f;
- return MarkModified();
- }
- public LootRule Chance(double chance = 1)
- {
- this.chance.value = chance;
- return MarkModified();
- }
- public LootRule Chance(Func<NPC, double> f)
- {
- chance.func = f;
- return MarkModified();
- }
- public LootRule Times(int times = 1)
- {
- this.times.value = times;
- return MarkModified();
- }
- public LootRule Times(Func<NPC, int> f)
- {
- times.func = f;
- return MarkModified();
- }
- public LootRule Item(int type)
- {
- item.value.netDefaults(type);
- if (name == null)
- {
- name = item.value.displayName;
- }
- return MarkModified();
- }
- public LootRule Item(string name)
- {
- if (name.IndexOf(':') == -1)
- {
- name = "Vanilla:" + name;
- }
- item.value.SetDefaults(name);
- if (this.name == null)
- {
- this.name = item.value.displayName;
- }
- return MarkModified();
- }
- public LootRule Stack(int stack = 1)
- {
- return Stack(stack, stack);
- }
- public LootRule Stack(int min, int max)
- {
- minStack.value = min;
- maxStack.value = max;
- return MarkModified();
- }
- public LootRule Stack(Func<NPC, int> stack)
- {
- return Stack(stack, stack);
- }
- public LootRule Stack(Func<NPC, int> min, Func<NPC, int> max)
- {
- minStack.func = min;
- maxStack.func = max;
- return MarkModified();
- }
- public LootRule Item(Func<NPC, Item> f)
- {
- item.func = f;
- return MarkModified();
- }
- public LootRule Code(Action<NPC> code)
- {
- this.code = code;
- if (name == null)
- {
- name = "Code";
- }
- return MarkModified();
- }
- public LootRule Conditional(bool state = true)
- {
- conditional = state;
- weighted = false;
- if (name == null)
- {
- name = "Conditional";
- }
- return MarkModified();
- }
- public LootRule Weighted(bool state = true)
- {
- weighted = state;
- conditional = false;
- if (name == null)
- {
- name = "Weighted";
- }
- return MarkModified();
- }
- public LootRule LootRules(params LootRule[] subrules)
- {
- foreach (LootRule rule in subrules)
- {
- rule.parent = this;
- this.subrules.Add(rule);
- }
- return MarkModified();
- }
- public LootRule EmptyElseLootRule(double totalWeight)
- {
- return EmptyElseLootRule(null, totalWeight);
- }
- public LootRule EmptyElseLootRule(string name = null, double totalWeight = 1)
- {
- return ElseLootRule(new LootRule(), totalWeight);
- }
- public LootRule ElseLootRule(LootRule rule, double totalWeight = 1)
- {
- rule.parent = this;
- elseSubrule = rule.Weight(totalWeight);
- return MarkModified();
- }
- public LootRule Enable()
- {
- enabled = true;
- return MarkModified();
- }
- public LootRule Disable()
- {
- enabled = false;
- return MarkModified();
- }
- public LootRule MarkModified()
- {
- if (settingUp)
- return this;
- if (!modified)
- modifiedRules.Add(this);
- modified = true;
- return this;
- }
- public void Backup()
- {
- CopyInto(copy);
- }
- public void CopyInto(LootRule copy)
- {
- if (copy == null)
- copy = new LootRule();
- if (parent != null)
- copy.parent = parent.copy;
- copy.name = name;
- copy.rules.Clear();
- copy.rules.AddRange(rules);
- weight.CopyInto(copy.weight);
- chance.CopyInto(copy.chance);
- item.CopyInto(copy.item);
- minStack.CopyInto(copy.minStack);
- maxStack.CopyInto(copy.maxStack);
- times.CopyInto(copy.times);
- copy.code = code;
- copy.subrules.Clear();
- foreach (LootRule rule in subrules)
- {
- LootRule copyrule = new LootRule();
- rule.CopyInto(copyrule);
- copy.subrules.Add(copyrule);
- }
- copy.conditional = conditional;
- copy.weighted = weighted;
- copy.elseSubrule = elseSubrule == null ? null : new LootRule();
- if (elseSubrule != null)
- elseSubrule.CopyInto(copy.elseSubrule);
- copy.enabled = enabled;
- copy.copy = this;
- }
- public void ReadFrom(JsonData j, NPC npc)
- {
- if (j.Has("name")) name = (string)j["name"];
- if (j.Has("times")) Times((int)j["times"]);
- if (j.Has("weight")) Weight((double)j["weight"]);
- if (j.Has("chance")) Chance((double)j["chance"]);
- if (j.Has("conditional")) Conditional((bool)j["conditional"]);
- if (j.Has("weighted")) Weighted((bool)j["weighted"]);
- if (j.Has("stack"))
- {
- if (j["stack"].IsInt)
- Stack((int)j["stack"]);
- if (j["stack"].IsArray)
- {
- JsonData jStack = j["stack"];
- Stack((int)jStack[0], (int)jStack[1]);
- }
- else
- throw new ArgumentException("Wrong type of the 'stack' property in LootRule for " + (npc == null ? "global NPC" : ("NPC '" + npc.name + "'")));
- }
- if (j.Has("item"))
- {
- if (j["item"].IsString)
- Item((string)j["item"]);
- else if (j["item"].IsInt)
- Item((int)j["item"]);
- else
- throw new ArgumentException("Wrong type of the 'item' property in LootRule for " + (npc == null ? "global NPC" : ("NPC '" + npc.name + "'")));
- }
- if (j.Has("rules"))
- {
- foreach (JsonData jRule in j["rules"])
- Rules(jsonRules[(string)jRule]);
- }
- if (j.Has("lootRules"))
- {
- foreach (JsonData jLootRule in j["lootRules"])
- {
- LootRule lootRule = new LootRule();
- lootRule.ReadFrom(jLootRule, npc);
- lootRule.parent = this;
- LootRules(lootRule);
- }
- }
- if (j.Has("else"))
- {
- double totalWeight = 1;
- JsonData jElse = j["else"];
- if (jElse.Has("totalWeight")) totalWeight = (double)jElse["totalWeight"];
- LootRule lootRule = new LootRule();
- lootRule.ReadFrom(jElse, npc);
- lootRule.parent = this;
- ElseLootRule(lootRule, totalWeight);
- }
- }
- public int DoesPass(NPC npc)
- {
- if (!enabled)
- return 0;
- int passed = 0;
- int times = this.times.Get(npc);
- for (int i = 0; i < times; i++)
- {
- foreach (Func<NPC, bool> frule in rules)
- {
- if (!frule(npc))
- {
- goto L1;
- }
- }
- double chance = this.chance.Get(npc) * luckHandler(npc);
- if (chance > 0 && (chance >= 1 || Main.rand.NextDouble() < chance))
- {
- passed++;
- }
- L1: {}
- }
- return passed;
- }
- public Tuple<List<Item>, List<Action<NPC>>> GetResult(NPC npc, int passed = -1)
- {
- List<Item> list = new List<Item>();
- List<Action<NPC>> list2 = new List<Action<NPC>>();
- if (passed < 0)
- {
- passed = DoesPass(npc);
- }
- for (int i = 0; i < passed; i++)
- {
- if (subrules.Count == 0)
- {
- Item myItem = GetItem(npc);
- if (myItem != null && !myItem.IsBlank())
- {
- list.Add(myItem);
- }
- if (code != null)
- {
- list2.Add(code);
- }
- }
- else
- {
- if (conditional)
- {
- foreach (LootRule rule in subrules)
- {
- if (rule.DoesPass(npc) != 0)
- {
- Tuple<List<Item>, List<Action<NPC>>> tuple = rule.GetResult(npc, 1);
- list.AddRange(tuple.Item1);
- list2.AddRange(tuple.Item2);
- break;
- }
- }
- }
- else if (weighted)
- {
- double totalWeight = 0;
- WeightedRandom<LootRule> wr = new WeightedRandom<LootRule>(Main.rand);
- foreach (LootRule rule in subrules)
- {
- int passed2 = rule.DoesPass(npc);
- for (int j = 0; j < passed2; j++)
- {
- double weight = rule.weight.Get(npc);
- if (weight > 0)
- {
- wr.Add(rule, weight);
- totalWeight += weight;
- }
- }
- }
- if (elseSubrule != null)
- {
- float luckMult = luckHandler(npc);
- if (luckMult > 0)
- {
- double weight = elseSubrule.weight.Get(npc) / luckMult;
- if (weight > 0)
- {
- wr.Add(elseSubrule, weight - totalWeight);
- totalWeight = weight;
- }
- }
- }
- if (totalWeight != 0)
- {
- LootRule rule = wr.Get();
- Tuple<List<Item>, List<Action<NPC>>> tuple = rule.GetResult(npc, 1);
- list.AddRange(tuple.Item1);
- list2.AddRange(tuple.Item2);
- }
- }
- else
- {
- foreach (LootRule rule in subrules)
- {
- Tuple<List<Item>, List<Action<NPC>>> tuple = rule.GetResult(npc);
- list.AddRange(tuple.Item1);
- list2.AddRange(tuple.Item2);
- }
- }
- }
- }
- return new Tuple<List<Item>, List<Action<NPC>>>(list, list2);
- }
- public Item GetItem(NPC npc)
- {
- Item item = this.item.Get(npc);
- if (item == null || item.IsBlank())
- return null;
- if (this.item.func == null)
- {
- int minStack = this.minStack.Get(npc);
- int maxStack = this.maxStack.Get(npc);
- item.stack = minStack == maxStack ? minStack : (minStack + Main.rand.Next(maxStack - minStack + 1));
- if (Prefix.CanHavePrefix(item))
- item.Prefix(-1);
- }
- return item;
- }
- }
- public class Dynamic<T>
- {
- public T value;
- public Func<NPC, T> func;
- public Dynamic()
- {
- value = default(T);
- func = null;
- }
- public Dynamic(T value)
- {
- this.value = value;
- func = null;
- }
- public Dynamic(Func<NPC, T> func)
- {
- value = default(T);
- this.func = func;
- }
- public T Get(NPC npc)
- {
- if (func != null)
- {
- return func(npc);
- }
- return value;
- }
- public virtual void CopyInto(Dynamic<T> other)
- {
- other.value = value;
- other.func = func;
- }
- public static implicit operator Dynamic<T>(T value)
- {
- return new Dynamic<T>(value);
- }
- public static implicit operator Dynamic<T>(Func<NPC, T> func)
- {
- return new Dynamic<T>(func);
- }
- }
- public class DynamicItem : Dynamic<Item>
- {
- public DynamicItem() : base() { }
- public DynamicItem(Item value) : base(value) { }
- public DynamicItem(Func<NPC, Item> func) : base(func) { }
- public override void CopyInto(Dynamic<Item> other)
- {
- BinBuffer bb = new BinBuffer();
- bb.Write(value);
- bb.Pos = 0;
- other.value = bb.ReadItem();
- other.func = func;
- }
- public static implicit operator DynamicItem(Item value)
- {
- return new DynamicItem(value);
- }
- public static implicit operator DynamicItem(Func<NPC, Item> func)
- {
- return new DynamicItem(func);
- }
- }
- }
Add Comment
Please, Sign In to add comment