public override bool?CanBeHitByProjectile(NPC npc, Projectile projectile) { if (ImmuneTime > 0) { Main.NewText($"{npc.FullName} is immune for {ImmuneTime} seconds!"); return(false); } ProceduralSpellProj ps = projectile.modProjectile as ProceduralSpellProj; if (ps?.Source == null) { return(null); } if (!npc.GetGlobalNPC <kNPC>().InvincibilityTime.ContainsKey(ps.Source)) { return(null); } if (npc.GetGlobalNPC <kNPC>().InvincibilityTime[ps.Source] > 0) { return(false); } return(null); }
public override Action <ProceduralSpellProj> GetAIAction() { return(delegate(ProceduralSpellProj spell) { ProceduralSpellProj.AI_RotateToVelocity(spell); if (Main.rand.NextFloat(0f, 2f) <= spell.alpha) { int dust = Dust.NewDust(spell.projectile.position, spell.projectile.width, spell.projectile.height, DustID.Electric, spell.projectile.velocity.X * 0.2f, spell.projectile.velocity.Y * 0.2f, 63, Color.White, 0.2f + spell.alpha); Main.dust[dust].noGravity = true; } }); }
public override bool? CanBeHitByProjectile(NPC npc, Projectile projectile) { if (immuneTime > 0) return false; if (projectile.modProjectile is ProceduralSpellProj) { ProceduralSpellProj ps = (ProceduralSpellProj)projectile.modProjectile; if (ps.source != null) if (invincibilityTime.ContainsKey(ps.source)) if (invincibilityTime[ps.source] > 0) return false; } return null; }
public override Action <ProceduralSpell, Player, Vector2, Vector2, Entity> GetCastAction() { return(delegate(ProceduralSpell spell, Player player, Vector2 origin, Vector2 target, Entity caster) { switch (caster) { case Player p: { PlayerCharacter character = p.GetModPlayer <PlayerCharacter>(); foreach (ProceduralSpellProj proj in character.CirclingProtection.Where(proj => proj.projectile.modProjectile is ProceduralSpellProj)) { proj.projectile.Kill(); } character.CirclingProtection.Clear(); break; } case Projectile pj: { ProceduralMinion minion = (ProceduralMinion)pj.modProjectile; foreach (ProceduralSpellProj proj in minion.CirclingProtection.Where(proj => proj.projectile.modProjectile is ProceduralSpellProj)) { proj.projectile.Kill(); } minion.CirclingProtection.Clear(); break; } } float spread = GetSpread(spell.ProjCount); Vector2 velocity = new Vector2(0f, -1.5f); for (int i = 0; i < spell.ProjCount; i += 1) { ProceduralSpellProj proj = spell.CreateProjectile(player, Vector2.Zero, spread * i, origin, caster); proj.projectile.timeLeft = RotTimeLeft; proj.DisplacementVelocity = velocity.RotatedBy(i * spread * Constants.Tau); proj.DisplacementAngle = i * spread * (float)Constants.Tau; switch (caster) { case Player _: player.GetModPlayer <PlayerCharacter>().CirclingProtection.Add(proj); break; case Projectile pj: ((ProceduralMinion)pj.modProjectile).CirclingProtection.Add(proj); break; } } }); }
public override Action <ProceduralSpellProj> GetAiAction() { return(delegate(ProceduralSpellProj spell) { ProceduralSpellProj.aiRotateToVelocity(spell); if (!(Main.rand.NextFloat(0f, 1.5f) <= spell.Alpha)) { return; } int dust = Dust.NewDust(spell.projectile.position, spell.projectile.width, spell.projectile.height, DustID.Shadowflame, spell.projectile.velocity.X * 0.2f, spell.projectile.velocity.Y * 0.2f, 63, Color.White, 0.4f + spell.Alpha * 1.2f); Main.dust[dust].noGravity = true; }); }
public override void OnHitByProjectile(NPC npc, Projectile projectile, int damage, float knockback, bool crit) { for (var i = 0; i < modifiers.Count; i++) { modifiers[i].OnHitByProjectile(npc, projectile, damage, knockback, crit); } if (projectile.modProjectile is ProceduralSpellProj) { ProceduralSpellProj ps = (ProceduralSpellProj)projectile.modProjectile; if (invincibilityTime.ContainsKey(ps.source)) invincibilityTime[ps.source] = 30; else invincibilityTime.Add(ps.source, 30); } }
public override Action <ProceduralSpell, Player, Vector2, Vector2, Entity> GetCastAction() { return(delegate(ProceduralSpell spell, Player player, Vector2 origin, Vector2 target, Entity caster) { if (caster is Player) { PlayerCharacter character = ((Player)caster).GetModPlayer <PlayerCharacter>(); foreach (ProceduralSpellProj proj in character.circlingProtection) { if (proj.projectile.modProjectile is ProceduralSpellProj) { proj.projectile.Kill(); } } character.circlingProtection.Clear(); } else if (caster is Projectile) { ProceduralMinion minion = (ProceduralMinion)((Projectile)caster).modProjectile; foreach (ProceduralSpellProj proj in minion.circlingProtection) { if (proj.projectile.modProjectile is ProceduralSpellProj) { proj.projectile.Kill(); } } minion.circlingProtection.Clear(); } float spread = GetSpread(spell.projCount); Vector2 velocity = new Vector2(0f, -1.5f); for (int i = 0; i < spell.projCount; i += 1) { ProceduralSpellProj proj = spell.CreateProjectile(player, Vector2.Zero, spread * i, origin, caster); proj.projectile.timeLeft = RotTimeLeft; proj.displacementVelocity = velocity.RotatedBy(i * spread * API.Tau); proj.displacementAngle = i * spread * (float)API.Tau; if (caster is Player) { player.GetModPlayer <PlayerCharacter>().circlingProtection.Add(proj); } else if (caster is Projectile) { ((ProceduralMinion)((Projectile)caster).modProjectile).circlingProtection.Add(proj); } } }); }
public override Action <ProceduralSpell, Player, Vector2, Vector2, Entity> GetCastAction() { return(delegate(ProceduralSpell spell, Player player, Vector2 origin, Vector2 target, Entity caster) { new SpellEffect(spell, target, projCount * 10, delegate(ProceduralSpell ability, int timeLeft) { if (timeLeft % 10 == 0) { ProceduralSpellProj proj = spell.CreateProjectile(player, new Vector2(0, -9f), Main.rand.NextFloat(-0.07f, 0.07f), caster.Center + new Vector2(0, -16f), caster); if (proj.alpha < 1f) { proj.alpha = 0.5f; } proj.projectile.tileCollide = true; } }); }); }
public override Action <ProceduralSpell, Player, Vector2, Vector2, Entity> GetCastAction() { return(delegate(ProceduralSpell spell, Player player, Vector2 origin, Vector2 target, Entity caster) { new SpellEffect(spell, target, projCount * 8, delegate(ProceduralSpell ability, int timeLeft) { if (timeLeft % 8 == 0) { ProceduralSpellProj proj = spell.CreateProjectile(player, new Vector2(0f, 8f), 0f, new Vector2(target.X - area / 2f + Main.rand.NextFloat(area), target.Y - 240f), caster); if (proj.alpha < 1f) { proj.alpha = 0.5f; } proj.projectile.timeLeft = 60; } }); }); }
public override Action <ProceduralSpell, Player, Vector2, Vector2, Entity> GetCastAction() { return(delegate(ProceduralSpell spell, Player player, Vector2 origin, Vector2 target, Entity caster) { int rotDistance = spell.minion ? 32 : 48; float spread = GetSpread(spell.projCount); for (int i = 0; i < spell.projCount; i += 1) { float angle = (float)i * spread * (float)API.Tau; ProceduralSpellProj proj = spell.CreateProjectile(player, Vector2.Zero, spread * i, origin + new Vector2(0f, -rotDistance).RotatedBy(angle), caster); proj.basePosition = origin; Vector2 unitVelocity = (target - origin); unitVelocity.Normalize(); proj.baseVelocity = unitVelocity * 8f; proj.displacementAngle = angle; proj.projectile.penetrate = 3; } }); }
public override Action <ProceduralSpellProj> GetAIAction() { return(delegate(ProceduralSpellProj spell) { try { ProceduralSpellProj.AI_RotateToVelocity(spell); if (Main.rand.NextFloat(0f, 1.5f) <= spell.alpha) { int dust = Dust.NewDust(spell.projectile.position, spell.projectile.width, spell.projectile.height, DustID.Fire, spell.projectile.velocity.X * 0.2f, spell.projectile.velocity.Y * 0.2f, 63, Color.White, 1f + spell.alpha * 2f); Main.dust[dust].noGravity = true; } } catch (SystemException e) { ErrorLogger.Log(e.ToString()); } }); }
public override Action <ProceduralSpellProj> GetAiAction() { return(delegate(ProceduralSpellProj spell) { try { ProceduralSpellProj.aiRotateToVelocity(spell); if (!(Main.rand.NextFloat(0f, 1.5f) <= spell.Alpha)) { return; } int dust = Dust.NewDust(spell.projectile.position, spell.projectile.width, spell.projectile.height, DustID.Fire, spell.projectile.velocity.X * 0.2f, spell.projectile.velocity.Y * 0.2f, 63, Color.White, 1f + spell.Alpha * 2f); Main.dust[dust].noGravity = true; } catch (SystemException e) { ModLoader.GetMod(Constants.ModName).Logger.InfoFormat(e.ToString()); } }); }
public override void AI(Projectile projectile) { if (elementalDamage == null && Main.netMode != 1) { elementalDamage = new Dictionary <ELEMENT, int>() { { ELEMENT.FIRE, 0 }, { ELEMENT.COLD, 0 }, { ELEMENT.LIGHTNING, 0 }, { ELEMENT.SHADOW, 0 } }; if (Main.npc.GetUpperBound(0) >= projectile.owner) { if (projectile.hostile && !projectile.friendly && Main.npc[projectile.owner] != null) { NPC npc = Main.npc[projectile.owner]; if (npc.boss) { return; } kNPC kn = npc.GetGlobalNPC <kNPC>(); int elecount = 0; foreach (ELEMENT element in Enum.GetValues(typeof(ELEMENT))) { if (kn.elementalDamage[element] > 0) { elecount += 1; } } int portionsize = (int)Math.Round((double)projectile.damage * kNPC.ELE_DMG_MODIFIER / 2.0 / elecount); foreach (ELEMENT element in Enum.GetValues(typeof(ELEMENT))) { if (kn.elementalDamage[element] > 0) { elementalDamage[element] = Math.Max(1, portionsize); } } return; } } if (projectile.type == mod.ProjectileType <ProceduralSpellProj>()) { PlayerCharacter character = Main.player[projectile.owner].GetModPlayer <PlayerCharacter>(); ProceduralSpellProj spell = (ProceduralSpellProj)projectile.modProjectile; if (spell.source == null) { SelectItem(projectile); } else { Cross cross = ((Cross)spell.source.glyphs[(int)GLYPHTYPE.CROSS].modItem); if (cross is Cross_Orange) { SelectItem(projectile, character.lastSelectedWeapon); } else { foreach (ELEMENT element in Enum.GetValues(typeof(ELEMENT))) { elementalDamage[element] = (int)Math.Round(cross.eleDmg[element] * projectile.damage); } } } } else if (projectile.friendly && !projectile.hostile && Main.player[projectile.owner] != null) { Player player = Main.player[projectile.owner]; if (player.active) { if (player.inventory[player.selectedItem] != null) { if (player.inventory[player.selectedItem].active && projectile.type != mod.ProjectileType <Explosion>() && projectile.type != mod.ProjectileType <SmokePellets>()) { SelectItem(projectile); } } } } } //if (Main.netMode != 0) //{ // ModPacket packet = mod.GetPacket(); // packet.Write((byte)Message.InitProjEleDmg); // packet.Write(projectile.whoAmI); // foreach (ELEMENT element in Enum.GetValues(typeof(ELEMENT))) // packet.Write(elementalDamage[element]); // packet.Send(); //} }
//angle from 0f to 1f public ProceduralSpellProj CreateProjectile(Player player, Vector2 velocity, float angle = 0f, Vector2?position = null, Entity caster = null) { if (caster == null) { caster = player; } Projectile projectile = Main.projectile[Projectile.NewProjectile(position == null ? caster.Center : (Vector2)position, velocity.RotatedBy(API.Tau * angle), mod.ProjectileType <ProceduralSpellProj>(), ProjectileDamage(player.GetModPlayer <PlayerCharacter>()), 3f, player.whoAmI)]; ProceduralSpellProj ps = (ProceduralSpellProj)projectile.modProjectile; ps.origin = projectile.position; foreach (Item item in glyphs) { Glyph glyph = (Glyph)item.modItem; if (glyph.GetAIAction() != null) { ps.ai.Add(glyph.GetAIAction()); } if (glyph.GetInitAction() != null) { ps.init.Add(glyph.GetInitAction()); } if (glyph.GetImpactAction() != null) { ps.impact.Add(glyph.GetImpactAction()); } if (glyph.GetKillAction() != null) { ps.kill.Add(glyph.GetKillAction()); } } foreach (GlyphModifier modifier in modifiers) { if (modifier.impact != null) { ps.impact.Add(modifier.impact); } if (modifier.draw != null) { ps.draw.Add(modifier.draw); } if (modifier.init != null) { ps.init.Add(modifier.init); } } ps.caster = caster; ps.projectile.minion = minion; /*if (minion) * { * ps.projectile.melee = false; * ps.projectile.ranged = false; * ps.projectile.magic = false; * }*/ ps.source = this; ps.Initialize(); if (Main.netMode != 1) { return(ps); } ModPacket packet = mod.GetPacket(); packet.Write((byte)Message.CreateProjectile); packet.Write(player.whoAmI); packet.Write(ps.projectile.whoAmI); packet.Write(glyphs[(byte)GLYPHTYPE.STAR].type); packet.Write(glyphs[(byte)GLYPHTYPE.CROSS].type); packet.Write(glyphs[(byte)GLYPHTYPE.MOON].type); packet.Write(ps.projectile.damage); packet.Write(minion); packet.Write(caster.whoAmI); List <GlyphModifier> mods = modifiers; packet.Write(mods.Count); for (int j = 0; j < mods.Count; j += 1) { packet.Write(mods[j].id); } packet.Send(); return(ps); }
public static void Read(BinaryReader reader) { try { int playerWhoAmI = reader.ReadInt32(); int projectileWhoAmI = reader.ReadInt32(); int starType = reader.ReadInt32(); int crossType = reader.ReadInt32(); int moonType = reader.ReadInt32(); float damage = reader.ReadSingle(); bool minion = reader.ReadBoolean(); int casterWhoAmI = reader.ReadInt32(); int modCount = reader.ReadInt32(); if (Main.netMode == NetmodeID.MultiplayerClient) { if (playerWhoAmI == Main.myPlayer) { return; } } int modifierCount = modCount; List <GlyphModifier> modifiers = new List <GlyphModifier>(); for (int i = 0; i < modifierCount; i += 1) { modifiers.Add(GlyphModifier.Modifiers[reader.ReadInt32()]); } Projectile projectile = Main.projectile[projectileWhoAmI]; if (projectile == null) { return; } projectile.owner = playerWhoAmI; if (!(projectile.modProjectile is ProceduralSpellProj)) { return; } ProceduralSpellProj ps = (ProceduralSpellProj)projectile.modProjectile; ps.Source = new ProceduralSpell(kRPG.Mod) { Glyphs = new Item[3] }; for (int i = 0; i < ps.Source.Glyphs.Length; i += 1) { ps.Source.Glyphs[i] = new Item(); ps.Source.Glyphs[i].SetDefaults(0, true); } ps.Source.Glyphs[(byte)GlyphType.Star].SetDefaults(starType, true); ps.Source.Glyphs[(byte)GlyphType.Cross].SetDefaults(crossType, true); ps.Source.Glyphs[(byte)GlyphType.Moon].SetDefaults(moonType, true); projectile.damage = (int)damage; projectile.minion = minion; try { if (projectile.minion) { ps.Caster = Main.projectile[casterWhoAmI]; } else if (projectile.hostile) { ps.Caster = Main.npc[casterWhoAmI]; } else { ps.Caster = Main.player[casterWhoAmI]; } } catch (SystemException e) { kRPG.LogMessage("Source-assignment failed, aborting..." + e); return; } ps.Source.ModifierOverride = modifiers; foreach (Item item in ps.Source.Glyphs) { if (item == null) { continue; } Glyph glyph = (Glyph)item.modItem; if (glyph.GetAiAction() != null) { ps.Ai.Add(glyph.GetAiAction()); } if (glyph.GetInitAction() != null) { ps.Inits.Add(glyph.GetInitAction()); } if (glyph.GetImpactAction() != null) { ps.Impacts.Add(glyph.GetImpactAction()); } if (glyph.GetKillAction() != null) { ps.Kills.Add(glyph.GetKillAction()); } } foreach (GlyphModifier modifier in modifiers) { if (modifier.Impact != null) { ps.Impacts.Add(modifier.Impact); } if (modifier.Draw != null) { ps.SpellDraw.Add(modifier.Draw); } if (modifier.Init != null) { ps.Inits.Add(modifier.Init); } } ps.Initialize(); CreateProjectilePacket.Write(projectile.owner, projectile.whoAmI, ps.Source.Glyphs[(byte)GlyphType.Star].type, ps.Source.Glyphs[(byte)GlyphType.Cross].type, ps.Source.Glyphs[(byte)GlyphType.Moon].type, projectile.damage, projectile.minion, ps.Caster.whoAmI, modifiers ); } catch (SystemException e) { kRPG.LogMessage("Error handling packet: CreateProjectilePacket on " + (Main.netMode == NetmodeID.Server ? "serverside" : "clientSide") + ", full error trace: " + e); } }
public override void HandlePacket(BinaryReader reader, int whoAmI) { Message msg = (Message)reader.ReadByte(); Dictionary <DataTag, object> tags = new Dictionary <DataTag, object>(); foreach (DataTag tag in dataTags[msg]) { tags.Add(tag, tag.read(reader)); } switch (msg) { //case Message.InitProjEleDmg: // if (!Main.projectile.IndexInRange((int)tags[DataTag.projId])) break; // Projectile p = Main.projectile[(int)tags[DataTag.projId]]; // try // { // kProjectile proj = p.GetGlobalProjectile<kProjectile>(); // proj.elementalDamage = new Dictionary<ELEMENT, int>() // { // { ELEMENT.FIRE, (int)tags[DataTag.fire] }, // { ELEMENT.COLD, (int)tags[DataTag.cold] }, // { ELEMENT.LIGHTNING, (int)tags[DataTag.lightning] }, // { ELEMENT.SHADOW, (int)tags[DataTag.shadow] } // }; // } // catch (SystemException e) // { // Main.NewText(e.ToString()); // } // break; case Message.SyncStats: if (Main.netMode == 2) { PlayerCharacter character = Main.player[(int)tags[DataTag.playerId]].GetModPlayer <PlayerCharacter>(); character.level = (int)tags[DataTag.amount]; character.baseStats[STAT.RESILIENCE] = (int)tags[DataTag.resilience]; character.baseStats[STAT.QUICKNESS] = (int)tags[DataTag.quickness]; character.baseStats[STAT.POTENCY] = (int)tags[DataTag.potency]; character.baseStats[STAT.WITS] = (int)tags[DataTag.wits]; } break; case Message.SyncLevel: if (Main.netMode == 2) { Main.player[(int)tags[DataTag.playerId]].GetModPlayer <PlayerCharacter>().level = (int)tags[DataTag.amount]; } break; case Message.CreateProjectile: if (Main.netMode == 2) { Projectile projectile = Main.projectile[(int)tags[DataTag.projId]]; projectile.owner = (int)tags[DataTag.playerId]; ProceduralSpellProj ps = (ProceduralSpellProj)projectile.modProjectile; ps.source.glyphs[(byte)GLYPHTYPE.STAR].SetDefaults((int)tags[DataTag.glyph_star], true); ps.source.glyphs[(byte)GLYPHTYPE.CROSS].SetDefaults((int)tags[DataTag.glyph_cross], true); ps.source.glyphs[(byte)GLYPHTYPE.MOON].SetDefaults((int)tags[DataTag.glyph_moon], true); projectile.damage = (int)tags[DataTag.damage]; int modifierCount = (int)tags[DataTag.modifierCount]; List <GlyphModifier> modifiers = new List <GlyphModifier>(); for (int i = 0; i < modifierCount; i += 1) { modifiers.Add(GlyphModifier.modifiers[reader.ReadInt32()]); } ps.source.modifierOverride = modifiers; foreach (Item item in ps.source.glyphs) { Glyph glyph = (Glyph)item.modItem; if (glyph.GetAIAction() != null) { ps.ai.Add(glyph.GetAIAction()); } if (glyph.GetInitAction() != null) { ps.init.Add(glyph.GetInitAction()); } if (glyph.GetImpactAction() != null) { ps.impact.Add(glyph.GetImpactAction()); } if (glyph.GetKillAction() != null) { ps.kill.Add(glyph.GetKillAction()); } } foreach (GlyphModifier modifier in modifiers) { if (modifier.impact != null) { ps.impact.Add(modifier.impact); } if (modifier.draw != null) { ps.draw.Add(modifier.draw); } if (modifier.init != null) { ps.init.Add(modifier.init); } } ps.Initialize(); } break; case Message.AddXP: if (Main.netMode == 1) { //Player player = Main.player[Main.myPlayer]; //if (Vector2.Distance(player.Center, Main.npc[(int)tags[DataTag.npcId]].Center) > 1024) // break; PlayerCharacter character = Main.LocalPlayer.GetModPlayer <PlayerCharacter>(); character.AddXP((int)tags[DataTag.amount]); } break; case Message.SyncSpear: ProceduralSpear spear = (ProceduralSpear)Main.projectile[(int)tags[DataTag.projId]].modProjectile; spear.blade = SwordBlade.blades[(int)tags[DataTag.partPrimary]]; spear.hilt = SwordHilt.hilts[(int)tags[DataTag.partSecondary]]; spear.accent = SwordAccent.accents[(int)tags[DataTag.partTertiary]]; if (Main.netMode == 1) { spear.Initialize(); } break; case Message.SwordInit: if (Main.netMode == 1) { ProceduralSword sword = (ProceduralSword)Main.item[(int)tags[DataTag.itemId]].modItem; sword.blade = SwordBlade.blades[(int)tags[DataTag.partPrimary]]; sword.hilt = SwordHilt.hilts[(int)tags[DataTag.partSecondary]]; sword.accent = SwordAccent.accents[(int)tags[DataTag.partTertiary]]; sword.dps = (float)tags[DataTag.itemDps]; Main.NewText(sword.dps.ToString()); sword.enemyDef = (int)tags[DataTag.itemDef]; sword.Initialize(); } break; case Message.StaffInit: if (Main.netMode == 1) { ProceduralStaff staff = (ProceduralStaff)Main.item[(int)tags[DataTag.itemId]].modItem; staff.staff = Staff.staves[(int)tags[DataTag.partPrimary]]; staff.gem = StaffGem.gems[(int)tags[DataTag.partSecondary]]; staff.ornament = StaffOrnament.ornament[(int)tags[DataTag.partTertiary]]; staff.dps = (float)tags[DataTag.itemDps]; staff.enemyDef = (int)tags[DataTag.itemDef]; staff.Initialize(); } break; case Message.BowInit: if (Main.netMode == 1) { RangedWeapon bow = (RangedWeapon)Main.item[(int)tags[DataTag.itemId]].modItem; bow.dps = (float)tags[DataTag.itemDps]; bow.enemyDef = (int)tags[DataTag.itemDef]; bow.Initialize(); } break; case Message.SyncHit: if (Main.netMode == 1) { PlayerCharacter character = Main.player[(int)tags[DataTag.playerId]].GetModPlayer <PlayerCharacter>(); character.accuracyCounter = (float)tags[DataTag.amount_single]; } break; case Message.SyncCritHit: if (Main.netMode == 1) { PlayerCharacter character = Main.player[(int)tags[DataTag.playerId]].GetModPlayer <PlayerCharacter>(); character.critAccuracyCounter = (float)tags[DataTag.amount_single]; } break; } }
public override void HandlePacket(BinaryReader reader, int whoAmI) { Message msg = (Message)reader.ReadByte(); Dictionary <DataTag, object> tags = new Dictionary <DataTag, object>(); foreach (DataTag tag in dataTags[msg]) { tags.Add(tag, tag.read(reader)); } switch (msg) { //case Message.InitProjEleDmg: // if (!Main.projectile.IndexInRange((int)tags[DataTag.projId])) break; // Projectile p = Main.projectile[(int)tags[DataTag.projId]]; // try // { // kProjectile proj = p.GetGlobalProjectile<kProjectile>(); // proj.elementalDamage = new Dictionary<ELEMENT, int>() // { // { ELEMENT.FIRE, (int)tags[DataTag.fire] }, // { ELEMENT.COLD, (int)tags[DataTag.cold] }, // { ELEMENT.LIGHTNING, (int)tags[DataTag.lightning] }, // { ELEMENT.SHADOW, (int)tags[DataTag.shadow] } // }; // } // catch (SystemException e) // { // Main.NewText(e.ToString()); // } // break; case Message.NPCEleDmg: if (Main.netMode == 1) { NPC npc = Main.npc[(int)tags[DataTag.npcId]]; kNPC kn = npc.GetGlobalNPC <kNPC>(); Dictionary <ELEMENT, bool> haselement = new Dictionary <ELEMENT, bool>() { { ELEMENT.FIRE, (bool)tags[DataTag.flag] }, { ELEMENT.COLD, (bool)tags[DataTag.flag2] }, { ELEMENT.LIGHTNING, (bool)tags[DataTag.flag3] }, { ELEMENT.SHADOW, (bool)tags[DataTag.flag4] } }; int count = 0; foreach (ELEMENT element in Enum.GetValues(typeof(ELEMENT))) { if (haselement[element]) { count += 1; } } int portionsize = (int)Math.Round((double)npc.damage * kNPC.ELE_DMG_MODIFIER / 2.0 / count); foreach (ELEMENT element in Enum.GetValues(typeof(ELEMENT))) { if (haselement[element]) { kn.elementalDamage[element] = Math.Max(1, portionsize); } } kn.dealseledmg = count > 0; } break; case Message.PrefixNPC: if (Main.netMode == 1) { NPC npc = Main.npc[(int)tags[DataTag.npcId]]; kNPC kn = npc.GetGlobalNPC <kNPC>(); for (int i = 0; i < (int)tags[DataTag.amount]; i += 1) { NPCModifier modifier = kn.modifierFuncs[reader.ReadInt32()].Invoke(kn, npc); modifier.Read(reader); modifier.Apply(); kn.modifiers.Add(modifier); } kn.MakeNotable(npc); } break; case Message.SyncStats: if (Main.netMode == 2) { PlayerCharacter character = Main.player[(int)tags[DataTag.playerId]].GetModPlayer <PlayerCharacter>(); character.level = (int)tags[DataTag.amount]; character.baseStats[STAT.RESILIENCE] = (int)tags[DataTag.resilience]; character.baseStats[STAT.QUICKNESS] = (int)tags[DataTag.quickness]; character.baseStats[STAT.POTENCY] = (int)tags[DataTag.potency]; character.baseStats[STAT.WITS] = (int)tags[DataTag.wits]; } break; case Message.SyncLevel: if (Main.netMode == 2) { Main.player[(int)tags[DataTag.playerId]].GetModPlayer <PlayerCharacter>().level = (int)tags[DataTag.amount]; } break; case Message.CreateProjectile: try { if (Main.netMode == 1) { if ((int)tags[DataTag.playerId] == Main.myPlayer) { break; } } int modifierCount = (int)tags[DataTag.modifierCount]; List <GlyphModifier> modifiers = new List <GlyphModifier>(); for (int i = 0; i < modifierCount; i += 1) { modifiers.Add(GlyphModifier.modifiers[reader.ReadInt32()]); } Projectile projectile = Main.projectile[(int)tags[DataTag.projId]]; if (projectile == null) { break; } projectile.owner = (int)tags[DataTag.playerId]; if (!(projectile.modProjectile is ProceduralSpellProj)) { break; } ProceduralSpellProj ps = (ProceduralSpellProj)projectile.modProjectile; ps.source = new ProceduralSpell(mod); ps.source.glyphs = new Item[3]; for (int i = 0; i < ps.source.glyphs.Length; i += 1) { ps.source.glyphs[i] = new Item(); ps.source.glyphs[i].SetDefaults(0, true); } ps.source.glyphs[(byte)GLYPHTYPE.STAR].SetDefaults((int)tags[DataTag.glyph_star], true); ps.source.glyphs[(byte)GLYPHTYPE.CROSS].SetDefaults((int)tags[DataTag.glyph_cross], true); ps.source.glyphs[(byte)GLYPHTYPE.MOON].SetDefaults((int)tags[DataTag.glyph_moon], true); projectile.damage = (int)tags[DataTag.damage]; projectile.minion = (bool)tags[DataTag.flag]; try { if (projectile.minion) { ps.caster = Main.projectile[(int)tags[DataTag.entityId]]; } else if (projectile.hostile) { ps.caster = Main.npc[(int)tags[DataTag.entityId]]; } else { ps.caster = Main.player[(int)tags[DataTag.entityId]]; } } catch (SystemException e) { ErrorLogger.Log("Source-assignment failed, aborting..."); break; } ps.source.modifierOverride = modifiers; foreach (Item item in ps.source.glyphs) { if (item != null) { Glyph glyph = (Glyph)item.modItem; if (glyph.GetAIAction() != null) { ps.ai.Add(glyph.GetAIAction()); } if (glyph.GetInitAction() != null) { ps.init.Add(glyph.GetInitAction()); } if (glyph.GetImpactAction() != null) { ps.impact.Add(glyph.GetImpactAction()); } if (glyph.GetKillAction() != null) { ps.kill.Add(glyph.GetKillAction()); } } } foreach (GlyphModifier modifier in modifiers) { if (modifier.impact != null) { ps.impact.Add(modifier.impact); } if (modifier.draw != null) { ps.draw.Add(modifier.draw); } if (modifier.init != null) { ps.init.Add(modifier.init); } } ps.Initialize(); if (Main.netMode == 2) { ModPacket packet = mod.GetPacket(); packet.Write((byte)Message.CreateProjectile); packet.Write(projectile.owner); packet.Write(projectile.whoAmI); packet.Write(ps.source.glyphs[(byte)GLYPHTYPE.STAR].type); packet.Write(ps.source.glyphs[(byte)GLYPHTYPE.CROSS].type); packet.Write(ps.source.glyphs[(byte)GLYPHTYPE.MOON].type); packet.Write(projectile.damage); packet.Write(projectile.minion); packet.Write(ps.caster.whoAmI); List <GlyphModifier> mods = modifiers; packet.Write(mods.Count); for (int j = 0; j < mods.Count; j += 1) { packet.Write(mods[j].id); } packet.Send(); } } catch (SystemException e) { ErrorLogger.Log("Error handling packet: " + msg.ToString() + " on " + (Main.netMode == 2 ? "serverside" : "clientside") + ", full error trace: " + e.ToString()); } break; case Message.AddXP: if (Main.netMode == 1) { //Player player = Main.player[Main.myPlayer]; //if (Vector2.Distance(player.Center, Main.npc[(int)tags[DataTag.npcId]].Center) > 1024) // break; PlayerCharacter character = Main.LocalPlayer.GetModPlayer <PlayerCharacter>(); character.AddXP((int)tags[DataTag.amount]); } break; case Message.SyncSpear: ProceduralSpear spear = (ProceduralSpear)Main.projectile[(int)tags[DataTag.projId]].modProjectile; spear.blade = SwordBlade.blades[(int)tags[DataTag.partPrimary]]; spear.hilt = SwordHilt.hilts[(int)tags[DataTag.partSecondary]]; spear.accent = SwordAccent.accents[(int)tags[DataTag.partTertiary]]; if (Main.netMode == 1) { spear.Initialize(); } break; case Message.SwordInit: if (Main.netMode == 1) { ProceduralSword sword = (ProceduralSword)Main.item[(int)tags[DataTag.itemId]].modItem; sword.blade = SwordBlade.blades[(int)tags[DataTag.partPrimary]]; sword.hilt = SwordHilt.hilts[(int)tags[DataTag.partSecondary]]; sword.accent = SwordAccent.accents[(int)tags[DataTag.partTertiary]]; sword.dps = (float)tags[DataTag.itemDps]; Main.NewText(sword.dps.ToString()); sword.enemyDef = (int)tags[DataTag.itemDef]; sword.Initialize(); } break; case Message.StaffInit: if (Main.netMode == 1) { ProceduralStaff staff = (ProceduralStaff)Main.item[(int)tags[DataTag.itemId]].modItem; staff.staff = Staff.staves[(int)tags[DataTag.partPrimary]]; staff.gem = StaffGem.gems[(int)tags[DataTag.partSecondary]]; staff.ornament = StaffOrnament.ornament[(int)tags[DataTag.partTertiary]]; staff.dps = (float)tags[DataTag.itemDps]; staff.enemyDef = (int)tags[DataTag.itemDef]; staff.Initialize(); } break; case Message.BowInit: if (Main.netMode == 1) { RangedWeapon bow = (RangedWeapon)Main.item[(int)tags[DataTag.itemId]].modItem; bow.dps = (float)tags[DataTag.itemDps]; bow.enemyDef = (int)tags[DataTag.itemDef]; bow.Initialize(); } break; case Message.SyncHit: if (Main.netMode == 1) { PlayerCharacter character = Main.player[(int)tags[DataTag.playerId]].GetModPlayer <PlayerCharacter>(); character.accuracyCounter = (float)tags[DataTag.amount_single]; } break; case Message.SyncCritHit: if (Main.netMode == 1) { PlayerCharacter character = Main.player[(int)tags[DataTag.playerId]].GetModPlayer <PlayerCharacter>(); character.critAccuracyCounter = (float)tags[DataTag.amount_single]; } break; } }
public override void Update(NPC npc) { try { int rotDistance = 64; int rotTimeLeft = 36000; if (rotMissile != null) { if (rotMissile.projectile.active && npc.active) { goto Secondary; } else { rotMissile.projectile.Kill(); } } Projectile proj1 = Main.projectile[ Projectile.NewProjectile(npc.Center, new Vector2(0f, -1.5f), kNPC.mod.ProjectileType <ProceduralSpellProj>(), npc.damage, 3f)]; proj1.hostile = true; proj1.friendly = false; ProceduralSpellProj ps1 = (ProceduralSpellProj)proj1.modProjectile; ps1.origin = proj1.position; Cross cross1 = Main.rand.Next(2) == 0 ? (Cross) new Cross_Red() : new Cross_Violet(); ps1.ai.Add(delegate(ProceduralSpellProj spell) { cross1.GetAIAction()(spell); float displacementAngle = (float)API.Tau / 4f; Vector2 displacementVelocity = Vector2.Zero; if (rotTimeLeft - spell.projectile.timeLeft >= rotDistance * 2 / 3) { Vector2 unitRelativePos = spell.RelativePos(spell.caster.Center); unitRelativePos.Normalize(); spell.projectile.Center = spell.caster.Center + unitRelativePos * rotDistance; displacementVelocity = new Vector2(-2f, 0f).RotatedBy((spell.RelativePos(spell.caster.Center)).ToRotation() + (float)API.Tau / 4f); float angle = displacementAngle - 0.06f * (float)(rotTimeLeft - spell.projectile.timeLeft - rotDistance * 2 / 3); spell.projectile.Center = spell.caster.Center + new Vector2(0f, -rotDistance).RotatedBy(angle); } else { spell.projectile.Center = spell.caster.Center + new Vector2(0f, -1.5f).RotatedBy(displacementAngle) * (rotTimeLeft - spell.projectile.timeLeft); } spell.projectile.velocity = displacementVelocity + spell.caster.velocity; spell.basePosition = spell.caster.position; }); ps1.init.Add(cross1.GetInitAction()); ps1.caster = npc; ps1.Initialize(); ps1.projectile.penetrate = -1; ps1.projectile.timeLeft = rotTimeLeft; rotMissile = ps1; Secondary: if (rotSecondary != null) { if (rotSecondary.projectile.active && npc.active) { return; } else { rotSecondary.projectile.Kill(); } } Projectile proj2 = Main.projectile[ Projectile.NewProjectile(npc.Center, new Vector2(0f, 1.5f), kNPC.mod.ProjectileType <ProceduralSpellProj>(), npc.damage, 3f)]; proj2.hostile = true; proj2.friendly = false; ProceduralSpellProj ps2 = (ProceduralSpellProj)proj2.modProjectile; ps2.origin = proj2.position; Cross cross2 = Main.rand.Next(2) == 0 ? (Cross) new Cross_Blue() : new Cross_Purple(); ps2.ai.Add(delegate(ProceduralSpellProj spell) { cross2.GetAIAction()(spell); float displacementAngle = (float)API.Tau / 4f + (float)Math.PI; Vector2 displacementVelocity = Vector2.Zero; if (rotTimeLeft - spell.projectile.timeLeft >= rotDistance * 2 / 3) { Vector2 unitRelativePos = spell.RelativePos(spell.caster.Center); unitRelativePos.Normalize(); spell.projectile.Center = spell.caster.Center + unitRelativePos * rotDistance; displacementVelocity = new Vector2(-2f, 0f).RotatedBy((spell.RelativePos(spell.caster.Center)).ToRotation() + (float)API.Tau / 4f); float angle = displacementAngle - 0.06f * (float)(rotTimeLeft - spell.projectile.timeLeft - rotDistance * 2 / 3); spell.projectile.Center = spell.caster.Center + new Vector2(0f, -rotDistance).RotatedBy(angle); } else { spell.projectile.Center = spell.caster.Center + new Vector2(0f, 1.5f).RotatedBy(displacementAngle) * (rotTimeLeft - spell.projectile.timeLeft); } spell.projectile.velocity = displacementVelocity + spell.caster.velocity; spell.basePosition = spell.caster.position; }); ps2.init.Add(cross2.GetInitAction()); ps2.caster = npc; ps2.Initialize(); ps2.projectile.penetrate = -1; ps2.projectile.timeLeft = rotTimeLeft; rotSecondary = ps2; } catch (SystemException e) { Main.NewText(e.ToString()); ErrorLogger.Log(e.ToString()); } }
public override void AI(Projectile projectile) { if (ElementalDamage != null || Main.netMode == NetmodeID.MultiplayerClient) { return; } ElementalDamage = new Dictionary <Element, int> { { Element.Fire, 0 }, { Element.Cold, 0 }, { Element.Lightning, 0 }, { Element.Shadow, 0 } }; if (Main.npc.GetUpperBound(0) >= projectile.owner) { if (projectile.hostile && !projectile.friendly) { bool bossFight = false; foreach (NPC n in Main.npc) { if (n.active) { if (n.boss) { bossFight = true; } } } if (bossFight) { return; } Player player = Main.netMode == NetmodeID.Server ? Main.player[0] : Main.player[Main.myPlayer]; Dictionary <Element, bool> hasElement = new Dictionary <Element, bool> { { Element.Fire, player.ZoneUnderworldHeight || player.ZoneTowerSolar || player.ZoneMeteor || player.ZoneDesert || Main.rand.Next(10) == 0 && Main.netMode == NetmodeID.MultiplayerClient }, { Element.Cold, player.ZoneSnow || player.ZoneSkyHeight || player.ZoneTowerVortex || player.ZoneDungeon || player.ZoneRain || Main.rand.Next(10) == 0 && Main.netMode == NetmodeID.MultiplayerClient }, { Element.Lightning, player.ZoneSkyHeight || player.ZoneTowerVortex || player.ZoneTowerStardust || player.ZoneMeteor || player.ZoneHoly || Main.rand.Next(10) == 0 && Main.netMode == NetmodeID.MultiplayerClient }, { Element.Shadow, player.ZoneCorrupt || player.ZoneCrimson || player.ZoneUnderworldHeight || player.ZoneTowerNebula || !Main.dayTime && Main.rand.Next(10) == 0 && Main.netMode == NetmodeID.MultiplayerClient && player.ZoneOverworldHeight } }; int count = Enum.GetValues(typeof(Element)).Cast <Element>().Count(element => hasElement[element]); int portionSize = (int)Math.Round(projectile.damage * kNPC.EleDmgModifier / 3.0 / count); foreach (Element element in Enum.GetValues(typeof(Element))) { if (hasElement[element]) { ElementalDamage[element] = Math.Max(1, portionSize); } } return; } } if (projectile.type == ModContent.ProjectileType <ProceduralSpellProj>()) { PlayerCharacter character = Main.player[projectile.owner].GetModPlayer <PlayerCharacter>(); ProceduralSpellProj spell = (ProceduralSpellProj)projectile.modProjectile; if (spell.Source == null) { SelectItem(projectile); } else { Cross cross = (Cross)spell.Source.Glyphs[(int)GlyphType.Cross].modItem; if (cross is Cross_Orange) { SelectItem(projectile, character.LastSelectedWeapon); } else { foreach (Element element in Enum.GetValues(typeof(Element))) { ElementalDamage[element] = (int)Math.Round(cross.EleDmg[element] * projectile.damage); } } } } else if (projectile.friendly && !projectile.hostile && Main.player[projectile.owner] != null) { Player player = Main.player[projectile.owner]; if (!player.active) { return; } if (player.inventory[player.selectedItem] == null) { return; } if (player.inventory[player.selectedItem].active && projectile.type != ModContent.ProjectileType <Explosion>() && projectile.type != ModContent.ProjectileType <SmokePellets>()) { SelectItem(projectile); } } //if (Main.netMode != 0) //{ // ModPacket packet = mod.GetPacket(); // packet.Pack((byte)Message.InitProjEleDmg); // packet.Pack(projectile.whoAmI); // foreach (ELEMENT element in Enum.GetValues(typeof(ELEMENT))) // packet.Pack(elementalDamage[element]); // packet.Send(); //} }
public static void Initialize() { Modifiers = new List <GlyphModifier>(); Attack = new GlyphModifier(0, "Attack", glyph => glyph.Minion, () => Main.rand.Next(2) == 0, 0.6f).SetMinionAi(delegate(ProceduralMinion minion) { if (minion.projectile.timeLeft % 50 != 0) { return; } Projectile proj = minion.projectile; NPC target = minion.GetTarget(); Vector2 unitVelocity = target.Center - proj.Center; if (!minion.Attack) { return; } if (Vector2.Distance(minion.projectile.Center, target.Center) < 400f) { unitVelocity.Normalize(); } Vector2 velocity = unitVelocity * 5f; ProceduralSpellProj spell = minion.Source.CreateProjectile(Main.player[minion.projectile.owner], velocity, 0, proj.Center, proj); spell.projectile.minion = true; Moon moon = (Moon)minion.Source.Glyphs[(int)GlyphType.Moon].modItem; spell.Ai.Remove(moon.GetAiAction()); }); SmallProt = new GlyphModifier(1, "Orbiting fire", glyph => glyph.Minion, () => Main.rand.Next(4) == 0, 0.95f).SetMinionAi( delegate(ProceduralMinion minion) { if (minion.SmallProt != null || minion.projectile.timeLeft % 180 != 0) { // ReSharper disable once PossibleNullReferenceException if (minion.SmallProt.projectile.active) { return; } else { minion.SmallProt.projectile.Kill(); } } Projectile m = minion.projectile; Player player = Main.player[m.owner]; Projectile projectile = Main.projectile[ Projectile.NewProjectile(m.Center, new Vector2(0f, -1.5f), ModContent.ProjectileType <ProceduralSpellProj>(), minion.Source.ProjectileDamage(player.GetModPlayer <PlayerCharacter>()), 3f, m.owner)]; projectile.minion = true; ProceduralSpellProj ps = (ProceduralSpellProj)projectile.modProjectile; ps.Origin = projectile.position; Cross cross = new Cross_Red(); ps.Ai.Add(delegate(ProceduralSpellProj spell) { cross.GetAiAction()(spell); int rotDistance = 40; int rotTimeLeft = 3600; float displacementAngle = (float)Constants.Tau / 4f; Vector2 displacementVelocity = Vector2.Zero; if (rotTimeLeft - spell.projectile.timeLeft >= rotDistance * 2 / 3) { Vector2 unitRelativePos = spell.RelativePos(spell.Caster.Center); unitRelativePos.Normalize(); spell.projectile.Center = spell.Caster.Center + unitRelativePos * rotDistance; displacementVelocity = new Vector2(-2f, 0f).RotatedBy(spell.RelativePos(spell.Caster.Center).ToRotation() + (float)Constants.Tau / 4f); float angle = displacementAngle - 0.06f * (rotTimeLeft - spell.projectile.timeLeft - rotDistance * 2 / 3); spell.projectile.Center = spell.Caster.Center + new Vector2(0f, -rotDistance).RotatedBy(angle); } else { spell.projectile.Center = spell.Caster.Center + new Vector2(0f, -1.5f).RotatedBy(displacementAngle) * (rotTimeLeft - spell.projectile.timeLeft); } spell.projectile.velocity = displacementVelocity + spell.Caster.velocity; spell.BasePosition = spell.Caster.position; }); ps.Inits.Add(delegate(ProceduralSpellProj spell) { cross.GetInitAction()(spell); spell.projectile.scale = 0.9f; ProceduralSpellProj.aiRotateToVelocity(spell); if (!(Main.rand.NextFloat(0f, 1.5f) <= spell.Alpha)) { return; } int dust = Dust.NewDust(spell.projectile.position, spell.projectile.width, spell.projectile.height, DustID.Fire, spell.projectile.velocity.X * 0.2f, spell.projectile.velocity.Y * 0.2f, 63, Color.White, 1f + spell.Alpha * 2f); Main.dust[dust].noGravity = true; }); ps.Impacts.Add(cross.GetImpactAction()); ps.Kills.Add(cross.GetKillAction()); ps.Caster = m; ps.Initialize(); minion.SmallProt = ps; }); GroupImpactEffects = new GlyphModifier(2, "", glyph => glyph is Cross, () => Main.rand.Next(2) == 0).DefineGroup(delegate { switch (Main.rand.Next(2)) { default: return(SmokePellets); case 1: return(Explosions); } }); SmokePellets = new GlyphModifier(3, "Smoke Pellets", glyph => false, () => false, 0.9f).SetImpact( delegate(ProceduralSpellProj spell, NPC npc, int damage) { SoundManager.PlaySound(Sounds.LegacySoundStyle_Item14, spell.projectile.Center, .5f); //Main.PlaySound(new LegacySoundStyle(2, 14).WithVolume(0.5f), spell.projectile.Center); Projectile proj = Main.projectile[ Projectile.NewProjectile(npc.Center - new Vector2(24, 48), Vector2.Zero, ModContent.ProjectileType <SmokePellets>(), 2, 0f, spell.projectile.owner)]; proj.minion = true; }); Explosions = new GlyphModifier(4, "Explosive", glyph => false, () => false, 0.85f).SetImpact( delegate(ProceduralSpellProj spell, NPC npc, int damage) { SoundManager.PlaySound(Sounds.LegacySoundStyle_Item14, spell.projectile.Center, .5f); //Main.PlaySound(new LegacySoundStyle(2, 14).WithVolume(0.5f), spell.projectile.Center); Projectile proj = Main.projectile[ Projectile.NewProjectile(npc.Center - new Vector2(16, 32), Vector2.Zero, ModContent.ProjectileType <Explosion>(), spell.projectile.damage, 0f, spell.projectile.owner)]; proj.minion = true; }); Vanish = new GlyphModifier(5, "Discord", glyph => glyph is Star, () => Main.rand.Next(3) == 0, 1.2f); CrossChains = new GlyphModifier(6, "", glyph => glyph is Cross, () => Main.rand.Next(3) == 0).DefineGroup(delegate { switch (Main.rand.Next(2)) { default: return(LifeLeech); case 1: return(ManaLeech); } }); LifeLeech = new GlyphModifier(7, "Leeches life", glyph => false, () => false, 0.9f, 1.2f).SetImpact( delegate(ProceduralSpellProj spell, NPC npc, int damage) { if (Main.rand.Next(3) != 0) { return; } PlayerCharacter character = Main.player[spell.projectile.owner].GetModPlayer <PlayerCharacter>(); float distance = Vector2.Distance(npc.Center, character.player.Center); int count = (int)(distance / 20); Trail trail = new Trail(npc.Center, 60, delegate(SpriteBatch spriteBatch, Player player, Vector2 end, Vector2[] displacement, float scale) { for (int i = 0; i < count; i += 1) { Vector2 position = (npc.position - player.Center) * i / count + player.Center; spriteBatch.Draw(GFX.GFX.Heart, position - Main.screenPosition + displacement[i], null, Color.White, 0f, Vector2.Zero, scale, SpriteEffects.None, 0f); } }) { Displacement = new Vector2[count] }; for (int i = 0; i < count; i += 1) { trail.Displacement[i] = new Vector2(Main.rand.NextFloat(-1f, 1f), Main.rand.NextFloat(-1f, 1f)); } character.Trails.Add(trail); int heal = damage / 5; if (heal < 1) { return; } character.player.HealEffect(heal); character.player.statLife += heal; }); ManaLeech = new GlyphModifier(8, "Steals mana", glyph => false, () => false, 0.8f).SetImpact( delegate(ProceduralSpellProj spell, NPC npc, int damage) { if (Main.rand.Next(2) != 0) { return; } PlayerCharacter character = Main.player[spell.projectile.owner].GetModPlayer <PlayerCharacter>(); float distance = Vector2.Distance(npc.Center, character.player.Center); int count = (int)(distance / 20); Trail trail = new Trail(npc.Center, 60, delegate(SpriteBatch spriteBatch, Player player, Vector2 end, Vector2[] displacement, float scale) { for (int i = 0; i < count; i += 1) { Vector2 position = (npc.position - player.Center) * i / count + player.Center; spriteBatch.Draw(GFX.GFX.Star, position - Main.screenPosition + displacement[i], null, Color.White, 0f, Vector2.Zero, scale, SpriteEffects.None, 0f); } }) { Displacement = new Vector2[count] }; for (int i = 0; i < count; i += 1) { trail.Displacement[i] = new Vector2(Main.rand.NextFloat(-1f, 1f), Main.rand.NextFloat(-1f, 1f)); } character.Trails.Add(trail); int mana = damage / 6; if (mana < 1) { return; } character.player.ManaEffect(mana); character.Mana += mana; character.player.statMana += mana; }); ThornChains = new GlyphModifier(9, "Thorny Chains", glyph => glyph is Moon && !(glyph is Moon_Violet), () => Main.rand.Next(4) == 0, 0.9f).SetDraw( delegate(ProceduralSpellProj spell, SpriteBatch spriteBatch, Color color) { Projectile proj = spell.projectile; Player player = Main.player[proj.owner]; Entity caster = spell.Caster; List <NPC> npcs = new List <NPC>(); for (int i = 0; i < Main.npc.Length; i += 1) { if (new Rectangle((int)Math.Min(caster.Center.X, proj.Center.X), (int)Math.Min(caster.Center.Y, proj.Center.Y), (int)Math.Abs(proj.Center.X - caster.Center.X), (int)Math.Abs(proj.Center.Y - caster.Center.Y)) .Intersects(new Rectangle((int)Main.npc[i].position.X, (int)Main.npc[i].position.Y, Main.npc[i].width, Main.npc[i].height))) { npcs.Add(Main.npc[i]); } } Vector2 relativePos = proj.Center - caster.Center; if (relativePos.Length() > 480f) { return; } int count = (int)(relativePos.Length() / 24); for (int i = 0; i < count; i += 1) { Vector2 chainpos = caster.Center + relativePos * (i + 0.5f) / count; Rectangle bounds = new Rectangle((int)Math.Round(chainpos.X) - 12, (int)Math.Round(chainpos.Y) - 12, 24, 24); foreach (NPC npc in npcs) { if (npc.active) { if (bounds.Intersects(new Rectangle((int)npc.position.X, (int)npc.position.Y, npc.width, npc.height)) && !npc.friendly && !npc.townNPC) { kNPC kn = npc.GetGlobalNPC <kNPC>(); bool canHit = !(kn.ImmuneTime > 0); if (kn.InvincibilityTime.ContainsKey(spell.Source)) { if (kn.InvincibilityTime[spell.Source] > 0) { canHit = false; } } if (!canHit) { continue; } player.ApplyDamageToNPC(npc, proj.damage, 0f, 0, false); npc.AddBuff(BuffID.Poisoned, proj.damage + 60); kn.InvincibilityTime[spell.Source] = 30; } } } spriteBatch.Draw(GFX.GFX.ThornChain, chainpos - Main.screenPosition, null, spell.Lighted ? Color.White : color, relativePos.ToRotation() - (float)Constants.Tau / 4f, new Vector2(10f, 16f), 1f, SpriteEffects.None, 0.1f); } }); Pierce = new GlyphModifier(10, "Pierces two additional enemies", glyph => glyph is Moon, () => Main.rand.Next(3) == 0, 0.8f, 1.1f).SetInit( delegate(ProceduralSpellProj spell) { if (spell.projectile.penetrate > 0) { spell.projectile.penetrate += 2; } }); Bounce = new GlyphModifier(11, "Bouncing", glyph => glyph is Moon_Blue || glyph is Moon_Purple, () => Main.rand.Next(7) < 2, 0.8f).SetInit( delegate(ProceduralSpellProj spell) { spell.projectile.tileCollide = true; spell.Bounce = true; }); }
public override void AI(Projectile projectile) { if (elementalDamage == null && Main.netMode != 1) { elementalDamage = new Dictionary <ELEMENT, int>() { { ELEMENT.FIRE, 0 }, { ELEMENT.COLD, 0 }, { ELEMENT.LIGHTNING, 0 }, { ELEMENT.SHADOW, 0 } }; if (Main.npc.GetUpperBound(0) >= projectile.owner) { if (projectile.hostile && !projectile.friendly) { bool bossfight = false; foreach (NPC n in Main.npc) { if (n.active) { if (n.boss) { bossfight = true; } } } if (bossfight) { return; } Player player = Main.netMode == 2 ? Main.player[0] : Main.player[Main.myPlayer]; Dictionary <ELEMENT, bool> haselement = new Dictionary <ELEMENT, bool>() { { ELEMENT.FIRE, player.ZoneUnderworldHeight || player.ZoneTowerSolar || player.ZoneMeteor || player.ZoneDesert || Main.rand.Next(10) == 0 && Main.netMode == 0 }, { ELEMENT.COLD, player.ZoneSnow || player.ZoneSkyHeight || player.ZoneTowerVortex || player.ZoneDungeon || player.ZoneRain || Main.rand.Next(10) == 0 && Main.netMode == 0 }, { ELEMENT.LIGHTNING, player.ZoneSkyHeight || player.ZoneTowerVortex || player.ZoneTowerStardust || player.ZoneMeteor || player.ZoneHoly || Main.rand.Next(10) == 0 && Main.netMode == 0 }, { ELEMENT.SHADOW, player.ZoneCorrupt || player.ZoneCrimson || player.ZoneUnderworldHeight || player.ZoneTowerNebula || !Main.dayTime && (Main.rand.Next(10) == 0 && Main.netMode == 0 && player.ZoneOverworldHeight) } }; int count = 0; foreach (ELEMENT element in Enum.GetValues(typeof(ELEMENT))) { if (haselement[element]) { count += 1; } } int portionsize = (int)Math.Round((double)projectile.damage * kNPC.ELE_DMG_MODIFIER / 3.0 / count); foreach (ELEMENT element in Enum.GetValues(typeof(ELEMENT))) { if (haselement[element]) { elementalDamage[element] = Math.Max(1, portionsize); } } return; } } if (projectile.type == mod.ProjectileType <ProceduralSpellProj>()) { PlayerCharacter character = Main.player[projectile.owner].GetModPlayer <PlayerCharacter>(); ProceduralSpellProj spell = (ProceduralSpellProj)projectile.modProjectile; if (spell.source == null) { SelectItem(projectile); } else { Cross cross = ((Cross)spell.source.glyphs[(int)GLYPHTYPE.CROSS].modItem); if (cross is Cross_Orange) { SelectItem(projectile, character.lastSelectedWeapon); } else { foreach (ELEMENT element in Enum.GetValues(typeof(ELEMENT))) { elementalDamage[element] = (int)Math.Round(cross.eleDmg[element] * projectile.damage); } } } } else if (projectile.friendly && !projectile.hostile && Main.player[projectile.owner] != null) { Player player = Main.player[projectile.owner]; if (player.active) { if (player.inventory[player.selectedItem] != null) { if (player.inventory[player.selectedItem].active && projectile.type != mod.ProjectileType <Explosion>() && projectile.type != mod.ProjectileType <SmokePellets>()) { SelectItem(projectile); } } } } } //if (Main.netMode != 0) //{ // ModPacket packet = mod.GetPacket(); // packet.Write((byte)Message.InitProjEleDmg); // packet.Write(projectile.whoAmI); // foreach (ELEMENT element in Enum.GetValues(typeof(ELEMENT))) // packet.Write(elementalDamage[element]); // packet.Send(); //} }
//angle from 0f to 1f public ProceduralSpellProj CreateProjectile(Player player, Vector2 velocity, float angle = 0f, Vector2?position = null, Entity caster = null) { if (caster == null) { caster = player; } Projectile projectile = Main.projectile[ Projectile.NewProjectile(position ?? caster.Center, velocity.RotatedBy(Constants.Tau * angle), ModContent.ProjectileType <ProceduralSpellProj>(), ProjectileDamage(player.GetModPlayer <PlayerCharacter>()), 3f, player.whoAmI)]; ProceduralSpellProj ps = (ProceduralSpellProj)projectile.modProjectile; ps.Origin = projectile.position; foreach (Item item in Glyphs) { Glyph glyph = (Glyph)item.modItem; if (glyph.GetAiAction() != null) { ps.Ai.Add(glyph.GetAiAction()); } if (glyph.GetInitAction() != null) { ps.Inits.Add(glyph.GetInitAction()); } if (glyph.GetImpactAction() != null) { ps.Impacts.Add(glyph.GetImpactAction()); } if (glyph.GetKillAction() != null) { ps.Kills.Add(glyph.GetKillAction()); } } foreach (GlyphModifier modifier in Modifiers) { if (modifier.Impact != null) { ps.Impacts.Add(modifier.Impact); } if (modifier.Draw != null) { ps.SpellDraw.Add(modifier.Draw); } if (modifier.Init != null) { ps.Inits.Add(modifier.Init); } } ps.Caster = caster; ps.projectile.minion = Minion; /*if (minion) * { * ps.projectile.melee = false; * ps.projectile.ranged = false; * ps.projectile.magic = false; * }*/ ps.Source = this; ps.Initialize(); CreateProjectilePacket.Write(player.whoAmI, ps.projectile.whoAmI, Glyphs[(byte)GlyphType.Star].type, Glyphs[(byte)GlyphType.Cross].type, Glyphs[(byte)GlyphType.Moon].type, ps.projectile.damage, Minion, caster.whoAmI, Modifiers); return(ps); }
//public new static NpcModifier Random(kNPC kNpc, NPC npc) //{ // return new SageModifier(kNpc, npc); //} public override void Update(NPC kNpc) { try { const int rotDistance = 64; const int rotTimeLeft = 36000; if (RotMissile != null) { if (RotMissile.projectile.active && kNpc.active) { goto Secondary; } else { RotMissile.projectile.Kill(); } } Projectile proj1 = Main.projectile[Projectile.NewProjectile(kNpc.Center, new Vector2(0f, -1.5f), ModContent.ProjectileType <ProceduralSpellProj>(), kNpc.damage, 3f)]; proj1.hostile = true; proj1.friendly = false; ProceduralSpellProj ps1 = (ProceduralSpellProj)proj1.modProjectile; ps1.Origin = proj1.position; Cross cross1 = Cross1Id == 0 ? (Cross) new Cross_Red() : new Cross_Violet(); ps1.Ai.Add(delegate(ProceduralSpellProj spell) { cross1.GetAiAction()(spell); float displacementAngle = (float)Constants.Tau / 4f; Vector2 displacementVelocity = Vector2.Zero; if (rotTimeLeft - spell.projectile.timeLeft >= rotDistance * 2 / 3) { Vector2 unitRelativePos = spell.RelativePos(spell.Caster.Center); unitRelativePos.Normalize(); spell.projectile.Center = spell.Caster.Center + unitRelativePos * rotDistance; displacementVelocity = new Vector2(-2f, 0f).RotatedBy(spell.RelativePos(spell.Caster.Center).ToRotation() + (float)Constants.Tau / 4f); float angle = displacementAngle - 0.06f * (rotTimeLeft - spell.projectile.timeLeft - rotDistance * 2 / 3); spell.projectile.Center = spell.Caster.Center + new Vector2(0f, -rotDistance).RotatedBy(angle); } else { spell.projectile.Center = spell.Caster.Center + new Vector2(0f, -1.5f).RotatedBy(displacementAngle) * (rotTimeLeft - spell.projectile.timeLeft); } spell.projectile.velocity = displacementVelocity + spell.Caster.velocity; spell.BasePosition = spell.Caster.position; }); ps1.Inits.Add(cross1.GetInitAction()); ps1.Caster = kNpc; ps1.Initialize(); ps1.projectile.penetrate = -1; ps1.projectile.timeLeft = rotTimeLeft; RotMissile = ps1; Secondary: if (RotSecondary != null) { if (RotSecondary.projectile.active && kNpc.active) { return; } else { RotSecondary.projectile.Kill(); } } Projectile proj2 = Main.projectile[Projectile.NewProjectile(kNpc.Center, new Vector2(0f, 1.5f), ModContent.ProjectileType <ProceduralSpellProj>(), kNpc.damage, 3f)]; proj2.hostile = true; proj2.friendly = false; ProceduralSpellProj ps2 = (ProceduralSpellProj)proj2.modProjectile; //Null Check to prevent crash. if (ps2 == null) { return; } ps2.Origin = proj2.position; Cross cross2 = Cross2Id == 0 ? (Cross) new Cross_Blue() : new Cross_Purple(); ps2.Ai.Add(delegate(ProceduralSpellProj spell) { cross2.GetAiAction()(spell); float displacementAngle = (float)Constants.Tau / 4f + (float)Math.PI; Vector2 displacementVelocity = Vector2.Zero; if (rotTimeLeft - spell.projectile.timeLeft >= rotDistance * 2 / 3) { Vector2 unitRelativePos = spell.RelativePos(spell.Caster.Center); unitRelativePos.Normalize(); spell.projectile.Center = spell.Caster.Center + unitRelativePos * rotDistance; displacementVelocity = new Vector2(-2f, 0f).RotatedBy(spell.RelativePos(spell.Caster.Center).ToRotation() + (float)Constants.Tau / 4f); float angle = displacementAngle - 0.06f * (rotTimeLeft - spell.projectile.timeLeft - rotDistance * 2 / 3); spell.projectile.Center = spell.Caster.Center + new Vector2(0f, -rotDistance).RotatedBy(angle); } else { spell.projectile.Center = spell.Caster.Center + new Vector2(0f, 1.5f).RotatedBy(displacementAngle) * (rotTimeLeft - spell.projectile.timeLeft); } spell.projectile.velocity = displacementVelocity + spell.Caster.velocity; spell.BasePosition = spell.Caster.position; }); ps2.Inits.Add(cross2.GetInitAction()); ps2.Caster = kNpc; ps2.Initialize(); ps2.projectile.penetrate = -1; ps2.projectile.timeLeft = rotTimeLeft; RotSecondary = ps2; } catch (SystemException e) { Main.NewText(e.ToString()); ModLoader.GetMod(Constants.ModName).Logger.InfoFormat(e.ToString()); } }