//This is where the painted buff is applied to NPCs that the item hits with melee public override void OnHitNPC(Player p, NPC target, int damage, float knockBack, bool crit) { WoMDNPC npc = target.GetGlobalNPC <WoMDNPC>(); if (npc != null && p != null && item.owner == Main.myPlayer) { WoMDPlayer player = p.GetModPlayer <WoMDPlayer>(); PaintMethods method = overridePaintMethod(player); if (method != PaintMethods.None) { if (method == PaintMethods.RemovePaint) { npc.painted = false; int index = target.FindBuffIndex(BuffType <Painted>()); if (index >= 0) { target.DelBuff(index); } } else { applyPaintedToNPC(target, new PaintData(npcCyclingTimeScale, player.paintData.PaintColor, player.paintData.CustomPaint, player.paintData.CustomPaint is ISprayPaint, Main.GlobalTime, player: player.player)); } } } }
protected PaintData getPaintData() { if (_overridePaintData != null) { return(_overridePaintData); } PaintData data = new PaintData(paintCyclingTimeScale, -1, null, false, 0); if (npcOwner != -1) { NPC npc = getNPC(npcOwner); if (npc == null) { return(data); } WoMDNPC gNpc = npc.GetGlobalNPC <WoMDNPC>(); return(gNpc.paintData); } WoMDPlayer player = getModPlayer(projectile.owner); if (player == null) { return(data); } return(player.paintData); }
public override void OnHitNPC(NPC target, int damage, float knockback, bool crit) { WoMDNPC npc = target.GetGlobalNPC <WoMDNPC>(); WoMDPlayer player = getModPlayer(projectile.owner); if (npc != null && player != null) { PaintMethods method = player.paintData.paintMethod; if (method != PaintMethods.None) { if (method == PaintMethods.RemovePaint) { npc.painted = false; int index = target.FindBuffIndex(BuffType <Painted>()); if (index >= 0) { target.DelBuff(index); } } else { applyPaintedToNPC(target, new PaintData(npcCyclingTimeScale, player.paintData.PaintColor, player.paintData.CustomPaint, player.paintData.CustomPaint is ISprayPaint, Main.GlobalTime, player: player.player)); } } } if (projectile.penetrate == 1) { onKillOnNPC(target); } }
/// <summary> /// Gets a shader for the provided WoMDNPC. Possible results are the Painted, SprayPainted, and PaintedNegative shaders. /// </summary> /// <param name="globalNpc"></param> /// <param name="drawData">This is necessary for the SprayPainted shader to work</param> /// <returns></returns> public static MiscShaderData getShader(WoMDNPC globalNpc, PaintData data, out bool needsDrawData) { needsDrawData = false; if (globalNpc == null) { return(null); } if (!globalNpc.painted) { return(null); } if (data.PaintColor == -1 && data.CustomPaint == null) { return(null); } if (data.PaintColor == PaintID.Negative || data.CustomPaint is NegativeSprayPaint) { return(getNegativeShader()); } Color color = getColor(data); if (data.CustomPaint != null && data.sprayPaint) { needsDrawData = true; return(getSprayPaintedShader(color)); } return(getPaintedShader(color)); }
/// <summary> /// Updates the colorFrame property /// </summary> public void updateColorFrame(PaintMethods method) { if (npcOwner == -1) { WoMDPlayer player = getModPlayer(projectile.owner); if (player != null) { if (player.paintData.PaintColor == -1 && player.paintData.CustomPaint == null) { colorFrame = 0; } else if (player.paintData.CustomPaint == null) { colorFrame = (byte)player.paintData.PaintColor; } else { colorFrame = player.paintData.CustomPaint.getPaintID(player.paintData); } } } else { NPC npc = getNPC(npcOwner); if (npc == null) { return; } WoMDNPC gNpc = npc.GetGlobalNPC <WoMDNPC>(); if (gNpc == null) { return; } PaintData data = gNpc.paintData; if (data == null) { colorFrame = 0; } else { if (data.PaintColor == -1 && data.CustomPaint == null) { colorFrame = 0; } else if (data.CustomPaint == null) { colorFrame = (byte)data.PaintColor; } else { colorFrame = data.CustomPaint.getPaintID(data); } } } updateFrame(method); }
/// <summary> /// Applies a shader for the provided WoMDNPC. Possible results are the Painted, SprayPainted, and PaintedNegative shaders. /// </summary> /// <param name="globalNpc"></param> /// <param name="drawData">This is necessary for the SprayPainted shader to work</param> /// <returns></returns> public static MiscShaderData applyShader(WoMDNPC globalNpc, PaintData data, DrawData?drawData = null) { MiscShaderData shader = getShader(globalNpc, data, out bool needsDrawData); if (shader != null) { shader.Apply(needsDrawData ? drawData : null); } return(shader); }
public override void HandlePacket(BinaryReader reader, int whoAmI) { switch (reader.ReadByte()) { case WoMDMessageTypes.SetNPCColors: if (multiplayer() || server()) { WoMDNPC.readColorPacket(reader, out WoMDNPC gNpc, out NPC npc); if (server()) { WoMDNPC.sendColorPacket(gNpc, npc); } } break; case WoMDMessageTypes.SetProjectileColor: if (multiplayer()) { WoMDProjectile.readProjectileColorPacket(reader, out _, out _); } break; case WoMDMessageTypes.SetProjNPCOwner: if (multiplayer()) { PaintingProjectile.readProjNPCOwnerPacket(reader); } break; case WoMDMessageTypes.SetMultiProjNPCOwner: if (multiplayer()) { PaintingProjectile.readMultiProjNPCOwnerPacket(reader); } break; case WoMDMessageTypes.SetPPOverrideData: if (multiplayer() || server()) { PaintingProjectile.readPPOverrideDataPacket(reader, out PaintingProjectile proj); if (server() && proj != null) { PaintingProjectile.sendPPOverrideDataPacket(proj); } } break; } }
/// <summary> /// Copies the painted settings from the provided npc to the provided projectile /// </summary> /// <param name="projectile">The projectile to inherit the painted settings</param> /// <param name="npc">The npc to copy the painted settings from</param> private static void applyPaintedFromNpc(Projectile projectile, NPC npc) { WoMDNPC gNpc = npc.GetGlobalNPC <WoMDNPC>(); if (gNpc == null || !gNpc.painted) { return; } WoMDProjectile proj = projectile.GetGlobalProjectile <WoMDProjectile>(); if (proj == null) { return; } proj._paintData = gNpc.paintData.clone(); proj.npcOwner = npc.whoAmI; if (server()) { sendProjectileColorPacket(proj, projectile); } }
public override void Update(NPC npc, ref int buffIndex) { WoMDNPC gNpc = npc.GetGlobalNPC <WoMDNPC>(); gNpc.painted = true; /* not sure I actually like this * if(GetInstance<WoMDConfig>().paintStatusEffects) { * PaintData data = gNpc.paintData; * byte paintColor = data.TruePaintColor; * if(paintColor == 0) * return; * switch(paintColor) { * case PaintID.Red: * case PaintID.DeepRed: * //fire * npc.AddBuff(BuffID.OnFire, 2); * //buffIndex++; * break; * case PaintID.Yellow: * if(npc.defense <= 0) * break; * if(npc.defense <= 5) * npc.defense = 0; * else * npc.defense -= 5; * break; * case PaintID.DeepYellow: * if(npc.defense <= 0) * break; * if(npc.defense <= 10) * npc.defense = 0; * else * npc.defense -= 10; * break; * case PaintID.Green: * case PaintID.DeepGreen: * //poison * break; * case PaintID.Purple: * case PaintID.DeepPurple: * //venom * break; * case PaintID.Cyan: * case PaintID.DeepCyan: * //frozen * npc.AddBuff(BuffID.Frostburn, 2); * buffIndex++; * break; * case PaintID.Black: * //darkness * break; * case PaintID.Shadow: * //blackout * break; * case PaintID.Negative: * //confused * npc.AddBuff(BuffID.Confused, 2); * buffIndex++; * break; * } * } */ }
/// <summary> /// Applies the painted buff to the provided npc, based on the paintColor and customPaint provided /// </summary> /// <param name="npc">The npc to apply the buff to</param> /// <param name="paintColor">The PaintID to use for painting the npc. Should be -1 when using a CustomPaint</param> /// <param name="customPaint">The CustomPaint to use for painting the npc. Should be null when using a vanilla paint</param> /// <param name="handledNpcs">Should not be provided</param> /// <param name="preventRecursion">Should not be provided</param> public static void applyPaintedToNPC(NPC npc, PaintData data, List <NPC> handledNpcs = null, bool preventRecursion = false) { switch (npc.type) { //cultist fight case NPCID.CultistDragonBody1: case NPCID.CultistDragonBody2: case NPCID.CultistDragonBody3: case NPCID.CultistDragonBody4: case NPCID.CultistDragonHead: case NPCID.CultistDragonTail: case NPCID.CultistBossClone: case NPCID.CultistBoss: case NPCID.AncientCultistSquidhead: //destroyer case NPCID.TheDestroyer: case NPCID.TheDestroyerBody: case NPCID.TheDestroyerTail: //pillars case NPCID.LunarTowerNebula: case NPCID.NebulaBeast: case NPCID.LunarTowerSolar: case NPCID.LunarTowerStardust: case NPCID.StardustWormTail: case NPCID.StardustWormBody: case NPCID.StardustWormHead: case NPCID.LunarTowerVortex: //martian saucer case NPCID.MartianSaucer: case NPCID.MartianSaucerCannon: case NPCID.MartianSaucerCore: case NPCID.MartianSaucerTurret: //misc bosses case NPCID.Pumpking: case NPCID.PumpkingBlade: //misc random mobs case NPCID.DungeonSpirit: case NPCID.Tumbleweed: case NPCID.DesertDjinn: case NPCID.Ghost: case NPCID.Poltergeist: return; } if (preventRecursion) { return; } npc.AddBuff(ModContent.BuffType <Painted>(), paintedBuffDuration); WoMDNPC globalNpc = npc.GetGlobalNPC <WoMDNPC>(); if (data.CustomPaint != null) { data.CustomPaint.modifyPaintDataForNpc(ref data); } if (globalNpc.painted) { PaintData existingData = globalNpc.paintData; if (existingData.PaintColor == data.PaintColor && (existingData.CustomPaint == null) == (data.CustomPaint == null) && //either both or neither are null existingData.CustomPaint.GetType().Equals(data.CustomPaint.GetType()) && existingData.sprayPaint == data.sprayPaint) { return; //nothing needs to be updated } } globalNpc.setPaintData(npc, data); if (singlePlayer()) { //TODO: do this whole section better if (handledNpcs == null) { handledNpcs = new List <NPC>(); } handledNpcs.Add(npc); switch (npc.type) { case NPCID.MoonLordHead: case NPCID.MoonLordHand: case NPCID.MoonLordCore: case NPCID.MoonLordLeechBlob: for (int i = 0; i < Main.npc.Length; i++) { if (Main.npc[i].TypeName == "") { break; } switch (Main.npc[i].type) { case NPCID.MoonLordHead: case NPCID.MoonLordHand: case NPCID.MoonLordCore: applyPaintedToNPC(Main.npc[i], data, null, true); break; } } break; case NPCID.EaterofWorldsBody: case NPCID.DevourerBody: case NPCID.WyvernBody: case NPCID.WyvernBody2: case NPCID.WyvernBody3: case NPCID.WyvernLegs: case NPCID.GiantWormBody: case NPCID.DiggerBody: case NPCID.SeekerBody: //world feeder case NPCID.TombCrawlerBody: case NPCID.DuneSplicerBody: case NPCID.SolarCrawltipedeBody: case NPCID.BoneSerpentBody: if (npc.ai[0] == Math.Round(npc.ai[0])) { NPC prevSection = getNPC((int)npc.ai[0]); if (prevSection != null && !handledNpcs.Contains(prevSection)) { if (prevSection.ai[1] == Math.Round(prevSection.ai[1])) { NPC thisSection = getNPC((int)prevSection.ai[1]); if (thisSection != null && thisSection.Equals(npc)) { applyPaintedToNPC(prevSection, data, handledNpcs); } } } } goto case NPCID.EaterofWorldsTail; case NPCID.EaterofWorldsHead: case NPCID.DevourerHead: case NPCID.WyvernHead: case NPCID.GiantWormHead: case NPCID.DiggerHead: case NPCID.SeekerHead: //world feeder case NPCID.TombCrawlerHead: case NPCID.DuneSplicerHead: case NPCID.SolarCrawltipedeHead: case NPCID.BoneSerpentHead: if (npc.ai[0] == Math.Round(npc.ai[0])) { NPC prevSection = getNPC((int)npc.ai[0]); if (prevSection != null && !handledNpcs.Contains(prevSection)) { if (prevSection.ai[1] == Math.Round(prevSection.ai[1])) { NPC thisSection = getNPC((int)prevSection.ai[1]); if (thisSection != null && thisSection.Equals(npc)) { applyPaintedToNPC(prevSection, data, handledNpcs); } } } } break; case NPCID.EaterofWorldsTail: case NPCID.DevourerTail: case NPCID.WyvernTail: case NPCID.GiantWormTail: case NPCID.DiggerTail: case NPCID.SeekerTail: //world feeder case NPCID.TombCrawlerTail: case NPCID.DuneSplicerTail: case NPCID.SolarCrawltipedeTail: case NPCID.BoneSerpentTail: if (npc.ai[1] == Math.Round(npc.ai[1])) { NPC nextSection = getNPC((int)npc.ai[1]); if (nextSection != null && !handledNpcs.Contains(nextSection)) { if (nextSection.ai[0] == Math.Round(nextSection.ai[0])) { NPC thisSection = getNPC((int)nextSection.ai[0]); if (thisSection != null && thisSection.Equals(npc)) { applyPaintedToNPC(nextSection, data, handledNpcs); } } } } break; } } }
//Handles assigning new projectiles npc owners public override bool PreAI(Projectile projectile) { if (server() || singlePlayer()) { if (!projectile.friendly && !setupPreAi) { if (GetInstance <WoMDConfig>().chaosModeEnabled) { setupPreAi = true; switch (projectile.type) { case ProjectileID.WoodenArrowHostile: if (true) { if (server()) { break; //running into issues making this work in multiplayer } NPC archer = Main.npc .Where(npc => npc.type == NPCID.CultistArcherBlue || npc.type == NPCID.GoblinArcher) .OrderBy(npc => Math.Abs(npc.Center.X - projectile.Center.X) + Math.Abs(npc.Center.Y - projectile.Center.Y)) .FirstOrDefault(); if (archer != null) { WoMDNPC gNpc = archer.GetGlobalNPC <WoMDNPC>(); if (gNpc == null || !gNpc.painted) { break; } int projId = Projectile.NewProjectile(projectile.Center, projectile.velocity, ProjectileType <PaintArrow>(), projectile.damage, projectile.knockBack); Projectile newArrow = getProjectile(projId); if (newArrow == null) { break; } PaintArrow arrow = (PaintArrow)newArrow.modProjectile; cloneProperties(projectile, arrow.projectile); arrow.npcOwner = archer.whoAmI; arrow.projectile.GetGlobalProjectile <WoMDProjectile>().setupPreAi = true; projectile.timeLeft = 0; if (server()) { PaintingProjectile.sendProjNPCOwnerPacket(arrow); } } } break; case ProjectileID.RainNimbus: if (true) { NPC nimbus = Main.npc .Where(npc => npc.type == NPCID.AngryNimbus) .OrderBy(npc => Math.Abs(npc.Center.X - projectile.Center.X) + Math.Abs(npc.Center.Y - projectile.Center.Y)) .FirstOrDefault(); if (nimbus != null) { applyPaintedFromNpc(projectile, nimbus); } } break; case ProjectileID.SandnadoHostileMark: case ProjectileID.SandnadoHostile: if (true) { NPC elemental = Main.npc .Where(npc => npc.type == NPCID.SandElemental) .OrderBy(npc => Math.Abs(npc.Center.X - projectile.Center.X) + Math.Abs(npc.Center.Y - projectile.Center.Y)) .FirstOrDefault(); if (elemental != null) { applyPaintedFromNpc(projectile, elemental); } } break; case ProjectileID.BulletDeadeye: if (true) { NPC enemy = Main.npc .Where(npc => new int[] { NPCID.TacticalSkeleton, NPCID.SantaNK1, NPCID.ElfCopter, NPCID.PirateDeadeye, NPCID.PirateCaptain }.Contains(npc.type)) .OrderBy(npc => Math.Abs(npc.Center.X - projectile.Center.X) + Math.Abs(npc.Center.Y - projectile.Center.Y)) .FirstOrDefault(); Vector2 enemyPos = enemy.Center; float range = 20; switch (enemy.type) { case NPCID.SantaNK1: enemyPos = enemy.Center + (projectile.velocity * 2.75f); range = 130; break; case NPCID.ElfCopter: range = 30; break; } float dist = Math.Abs(enemyPos.X - projectile.Center.X) + Math.Abs(enemyPos.Y - projectile.Center.Y); if (dist < range) { applyPaintedFromNpc(projectile, enemy); } } break; case ProjectileID.HappyBomb: if (true) { NPC enemy = Main.npc .Where(npc => npc.type == NPCID.Clown) .OrderBy(npc => Math.Abs(npc.Center.X - projectile.Center.X) + Math.Abs(npc.Center.Y - projectile.Center.Y)) .FirstOrDefault(); if (enemy != null) { float dist = Math.Abs(enemy.Center.X - projectile.Center.X) + Math.Abs(enemy.Center.Y - projectile.Center.Y); if (dist < 64) { applyPaintedFromNpc(projectile, enemy); } } } break; case ProjectileID.InfernoHostileBolt: if (true) { NPC enemy = Main.npc .Where(npc => npc.type == NPCID.DiabolistRed || npc.type == NPCID.DiabolistWhite) .OrderBy(npc => Math.Abs(npc.Center.X - projectile.Center.X) + Math.Abs(npc.Center.Y - projectile.Center.Y)) .FirstOrDefault(); if (enemy != null) { float dist = Math.Abs(enemy.Center.X - projectile.Center.X) + Math.Abs(enemy.Center.Y - projectile.Center.Y); if (dist <= 20) { applyPaintedFromNpc(projectile, enemy); } } } break; case ProjectileID.PaladinsHammerHostile: if (true) { NPC enemy = Main.npc .Where(npc => npc.type == NPCID.Paladin) .OrderBy(npc => Math.Abs(npc.Center.X - projectile.Center.X) + Math.Abs(npc.Center.Y - projectile.Center.Y)) .FirstOrDefault(); if (enemy != null) { WoMDNPC gNpc = enemy.GetGlobalNPC <WoMDNPC>(); if (gNpc != null && gNpc.painted) { float dist = Math.Abs(enemy.Center.X - projectile.Center.X) + Math.Abs(enemy.Center.Y - projectile.Center.Y); if (dist <= 25) { applyPaintedFromNpc(projectile, enemy); projectile.Opacity = 0; projectile.alpha = 0; } } } } break; } } } } return(base.PreAI(projectile)); }