/// <summary> /// Sends every modified weapon to the player. /// Steps: /// Change every weapon to default values. /// Stores the index of every modified weapon, and stores the index as the max index. /// Fill the player's inventory with a placeholder item up to the max index. /// Removes every item that was modified serverside with the list of indexes. /// Starts to drop the modified items. /// </summary> public static void SendCustomItems(PvPPlayer player) { RefreshInventory(player); List <int> itemIndex = new List <int>(); InventoryIndexer indexer = new InventoryIndexer(); for (byte loop = 0; loop < indexer.MaxInventoryCycle; loop++) { int index = indexer.NextIndex(); Item item = player.TPlayer.inventory[index]; var custwep = GetCustomWeapon(player, item.type, item.prefix, (short)item.stack); if (IsModifiedItem(custwep.ItemNetId)) { indexer.StoreMaxIndex(index); itemIndex.Add(index); player.InvTracker.AddItem(custwep); } } if (itemIndex.Count != 0) { SSCUtils.FillInventoryToIndex(player, Constants.EmptyItem, Constants.JunkItem, indexer.MaxIndex); foreach (int num in itemIndex) { SSCUtils.SetItem(player, (byte)num, Constants.EmptyItem); } player.InvTracker.StartDroppingItems(); } else { player.InvTracker.CheckFinishedModifications(0); } }
public static MapIcon CreateMapIcon(PvPPlayer player, FrameworkElement uiElement) { if (player == null) { throw new ArgumentNullException(nameof(player)); } if (uiElement == null) { throw new ArgumentNullException(nameof(uiElement)); } var playerIcon = new MapIcon { BackgroundColor = GetTeamColor(player.Team), PlayerIdentityColor = player.IdentityColor, EventContent = uiElement, }; var playerNameBinding = new Binding("Name") { Source = player, }; playerIcon.SetBinding(Timeline.Parts.MapIcon.PlayerNameProperty, playerNameBinding); return(playerIcon); }
public static void OnPvPToggled(PvPPlayer player) { if (PvPToggled != null) { PvPToggled(typeof(DataHandler), new TogglePvPArgs(player)); } }
public static void OnPlayerSlotUpdated(PvPPlayer player, int slotid) { if (PlayerSlotUpdated != null) { PlayerSlotUpdated(typeof(DataHandler), new PlayerSlotArgs(player, slotid)); } }
public static void OnPlayerDead(PvPPlayer dead) { if (PlayerDied != null) { PlayerDied(typeof(DataHandler), new PlayerDeathArgs(dead)); } }
/// <summary> /// Finds the closest pvper from a position. /// </summary> /// <param name="position">The position to find players from</param> /// <param name="selfIndex">The user to ignore</param> /// <param name="radius">The radius in which to find players (in pixels)</param> public static PvPPlayer FindClosestPlayer(Vector2 position, int selfIndex, float radius = -1) { float closestPersonDistance = -1; PvPPlayer target = null; for (int pvperIndex = 0; pvperIndex < Main.maxPlayers; pvperIndex++) { var pvper = PvPModifier.PvPers[pvperIndex]; if (pvper == null || !pvper.TPlayer.hostile || pvper.TPlayer.dead) { continue; } var distance = Vector2.Distance(position, pvper.TPlayer.Center); if (pvper.Index != selfIndex && (distance < closestPersonDistance || closestPersonDistance == -1) && (distance < radius || radius == -1)) { closestPersonDistance = distance; target = pvper; } } return(target); }
/// <summary> /// Generates a death message for a person based off the weapon and type of death. /// </summary> /// <param Name="attacker">The person inflicting the hit.</param> /// <param Name="deadplayer">The target receiving the death message.</param> /// <param Name="weapon">The weapon used to hit the target.</param> /// <param Name="type">1 for normal hits, 2 for reflection hits such as thorns and turtle.</param> /// <returns>A string of the death message.</returns> public static string GetPvPDeathMessage(PvPPlayer attacker, PvPPlayer deadplayer, PvPItem weapon, int type = 1) { Random random = new Random(); string deathmessage = ""; if (type == 1) { deathmessage = PvPController.Config.NormalDeathMessages[random.Next(PvPController.Config.NormalDeathMessages.Count)]; } else if (type == 2) { deathmessage = PvPController.Config.ReflectedDeathMessages[random.Next(PvPController.Config.ReflectedDeathMessages.Count)]; } string tag = PvPController.Config.DeathItemTag; if (PvPController.Config.DeathItemTag == "weapon" && type == 1) { tag = weapon.netID != 0 ? "[i/p{0}:{1}] ".SFormat(weapon.prefix, weapon.netID) : ""; } else if (PvPController.Config.DeathItemTag == "weapon" && type == 2) { tag = "[i:1150] "; } return(tag + deadplayer.Name + deathmessage + attacker.Name + "'s " + weapon.Name + "."); }
public static void ActivateSpectreBolt(PvPPlayer attacker, PvPPlayer target, PvPItem weapon, int dmg) { if (!weapon.magic) { return; } int Damage = dmg / 2; if (dmg / 2 <= 1) { return; } int?attackingIndex = null; if (Collision.CanHit(attacker.TPlayer.position, attacker.TPlayer.width, attacker.TPlayer.height, target.TPlayer.position, target.TPlayer.width, target.TPlayer.height)) { attackingIndex = target.Index; } if (attackingIndex == null) { return; } int num3 = (int)attackingIndex; double num4 = 4.0; float num5 = (float)Main.rand.Next(-100, 101); float num6 = (float)Main.rand.Next(-100, 101); double num7 = Math.Sqrt((double)num5 * (double)num5 + (double)num6 * (double)num6); float num8 = (float)(num4 / num7); float SpeedX = num5 * num8; float SpeedY = num6 * num8; ProjectileUtils.SpawnProjectile(attacker, attacker.X, attacker.Y, SpeedX, SpeedY, 356, Damage, 0.0f, attacker.Index, (float)num3, 0.0f); }
public bool ExtractData(GetDataEventArgs args, MemoryStream data, PvPPlayer attacker, out ProjectileNewArgs arg) { arg = null; if (PresetData.ProjectileDummy.Contains(Type)) { return(false); } arg = new ProjectileNewArgs { Args = args, Attacker = attacker, Identity = data.ReadInt16(), Position = new Vector2(data.ReadSingle(), data.ReadSingle()), Velocity = new Vector2(data.ReadSingle(), data.ReadSingle()), Knockback = data.ReadSingle(), Damage = data.ReadInt16(), Owner = data.ReadByte(), Type = data.ReadInt16(), AiFlags = (BitsByte)data.ReadByte(), Ai0 = AiFlags[0] ? Ai0 = data.ReadSingle() : 0, Ai1 = AiFlags[1] ? data.ReadSingle() : 0, Ai = new float[Projectile.maxAI], Proj = new PvPProjectile(Type, Identity), Weapon = ProjectileUtils.GetProjectileWeapon(attacker, Type) }; return(true); }
/// <summary> /// Gets the weapon of a projectile. /// For certain projectiles, it will pull from a list of /// projectile-to-weapon Dictionaries and returns /// the weapon based off the dictionary mapping. /// </summary> /// <param name="owner">Index of the owner of projectile.</param> /// <param name="type">Type of projectile.</param> /// <returns>Returns the item the projectile came from.</returns> public static PvPItem GetProjectileWeapon(PvPPlayer owner, int type) { PvPItem weapon; if (PresetData.PresetProjDamage.ContainsKey(type)) { weapon = new PvPItem(); } else if (PresetData.ProjHooks.ContainsKey(type)) { weapon = owner.FindPlayerItem(PresetData.ProjHooks[type]); } else if (PresetData.FromWhatItem.ContainsKey(type)) { weapon = owner.FindPlayerItem(PresetData.FromWhatItem[type]); } else if (PresetData.MinionItem.ContainsKey(type)) { weapon = owner.FindPlayerItem(PresetData.MinionItem[type]); } else { weapon = owner.HeldItem; } return(weapon); }
//Stores newly created projectiles into a list along with its originated item public void OnNewProjectile(object sender, GetDataHandlers.NewProjectileEventArgs args) { if (!PvPController.config.enablePlugin) { return; } PvPPlayer player = new PvPPlayer(args.Owner); if (player == null || !player.TPlayer.hostile) { return; } PvPItem weapon; if (MiscData.accessoryOrArmorProjectiles.ContainsKey(args.Type)) { weapon = new PvPItem(); weapon.damage = MiscData.accessoryOrArmorProjectiles[args.Type]; weapon.name = Lang.GetProjectileName(args.Type).ToString(); } else if (MiscData.fromWhatWeapon.ContainsKey(args.Type)) { weapon = new PvPItem(MiscData.fromWhatWeapon[args.Type]); } else { weapon = player.GetPlayerItem(); } projectiles[args.Identity] = new PvPProjectile(args.Type); projectiles[args.Identity].SetOwner(args.Owner); projectiles[args.Identity].SetOriginatedItem(weapon); }
public static void ActivateYoyo(PvPPlayer attacker, PvPPlayer target, int dmg, float kb) { if (!attacker.TPlayer.yoyoGlove && attacker.TPlayer.counterWeight <= 0) { return; } int index1 = -1; int num1 = 0; int num2 = 0; for (int index2 = 0; index2 < 1000; ++index2) { if (Main.projectile[index2].active && Main.projectile[index2].owner == attacker.TPlayer.whoAmI) { if (Main.projectile[index2].counterweight) { ++num2; } else if (Main.projectile[index2].aiStyle == 99) { ++num1; index1 = index2; } } } if (attacker.TPlayer.yoyoGlove && num1 < 2) { if (index1 < 0) { return; } int index; Vector2 vector2_1 = Vector2.Subtract(target.LastNetPosition, attacker.TPlayer.Center); vector2_1.Normalize(); Vector2 vector2_2 = Vector2.Multiply(vector2_1, 16f); index = Projectile.NewProjectile(attacker.TPlayer.Center.X, attacker.TPlayer.Center.Y, vector2_2.X, vector2_2.Y, Main.projectile[index1].type, Main.projectile[index1].damage, Main.projectile[index1].knockBack, attacker.TPlayer.whoAmI, 1f, 0.0f); NetMessage.SendData(27, -1, -1, null, index, 0.0f, 0.0f, 0.0f, 0, 0, 0); } else { if (num2 >= num1) { return; } int index; Vector2 vector2_1 = Vector2.Subtract(target.LastNetPosition, attacker.TPlayer.Center); vector2_1.Normalize(); Vector2 vector2_2 = Vector2.Multiply(vector2_1, 16f); float KnockBack = (float)((kb + 6.0) / 2.0); if (num2 > 0) { index = Projectile.NewProjectile(attacker.TPlayer.Center.X, attacker.TPlayer.Center.Y, vector2_2.X, vector2_2.Y, attacker.TPlayer.counterWeight, (int)(dmg * 0.8), KnockBack, attacker.TPlayer.whoAmI, 1f, 0.0f); } else { index = Projectile.NewProjectile(attacker.TPlayer.Center.X, attacker.TPlayer.Center.Y, vector2_2.X, vector2_2.Y, attacker.TPlayer.counterWeight, (int)(dmg * 0.8), KnockBack, attacker.TPlayer.whoAmI, 0.0f, 0.0f); } NetMessage.SendData(27, -1, -1, null, index, 0.0f, 0.0f, 0.0f, 0, 0, 0); } }
public ProjectileNewArgs(GetDataEventArgs args, MemoryStream data, PvPPlayer attacker) { Args = args; Attacker = attacker; Identity = data.ReadInt16(); Position = new Vector2(data.ReadSingle(), data.ReadSingle()); Velocity = new Vector2(data.ReadSingle(), data.ReadSingle()); Knockback = data.ReadSingle(); Damage = data.ReadInt16(); Owner = data.ReadByte(); Type = data.ReadInt16(); AiFlags = (BitsByte)data.ReadByte(); Ai0 = 0; Ai1 = 0; if (AiFlags[0]) { Ai0 = data.ReadSingle(); } if (AiFlags[1]) { Ai1 = data.ReadSingle(); } Ai = new float[Projectile.maxAI]; Weapon = ProjectileUtils.GetProjectileWeapon(attacker, Type); }
/// <summary> /// Gets the weapon of a projectile. /// For certain projectiles, it will pull from a list of /// projectile-to-weapon-mapping Dictionaries and returns /// the weapon based off the dictionary mapping. /// </summary> /// <param Name="owner">Owner of projectile.</param> /// <param Name="type">Type of projectile.</param> /// <returns>Returns the item the projectile came from.</returns> public static PvPItem GetProjectileWeapon(PvPPlayer owner, int type) { PvPItem weapon; if (PresetData.PresetProjDamage.ContainsKey(type)) { weapon = new PvPItem { Damage = PresetData.PresetProjDamage[type], SpecialName = Lang.GetProjectileName(type).ToString() }; } else if (PresetData.ProjHooks.ContainsKey(type)) { weapon = new PvPItem(type); } else if (PresetData.FromWhatItem.ContainsKey(type)) { weapon = owner.FindPlayerItem(PresetData.FromWhatItem[type]); } else if (PresetData.MinionItem.ContainsKey(type)) { weapon = owner.FindPlayerItem(PresetData.MinionItem[type]); } else { weapon = owner.GetPlayerItem; } return(weapon); }
public static void HandleData(GetDataEventArgs args, MemoryStream data, PvPPlayer player) { switch (args.MsgID) { case PacketTypes.PlayerHurtV2: PlayerHurt?.Invoke(typeof(DataHandler), new PlayerHurtArgs(args, data, player)); return; case PacketTypes.TogglePvp: PvPToggled?.Invoke(typeof(DataHandler), new TogglePvPArgs(player)); return; case PacketTypes.PlayerSlot: PlayerSlotUpdated?.Invoke(typeof(DataHandler), new PlayerSlotArgs(data, player)); return; case PacketTypes.PlayerDeathV2: PlayerDied?.Invoke(typeof(DataHandler), new PlayerDeathArgs(player)); return; case PacketTypes.ProjectileNew: ProjectileNew?.Invoke(typeof(DataHandler), new ProjectileNewArgs(args, data, player)); return; case PacketTypes.ProjectileDestroy: ProjectileDestroyed?.Invoke(typeof(DataHandler), new ProjectileDestroyArgs(data)); return; case PacketTypes.PlayerUpdate: PlayerUpdated?.Invoke(typeof(DataHandler), new PlayerUpdateArgs(data, player)); return; } }
public static void OnPlayerUpdated(MemoryStream data, PvPPlayer player) { if (PlayerUpdated != null) { PlayerUpdated(typeof(DataHandler), new PlayerUpdateArgs(data, player)); } }
public bool ExtractData(PvPPlayer dead, out PlayerDeathArgs arg) { arg = new PlayerDeathArgs { Dead = dead }; return(true); }
public static void OnPlayerHurtted(GetDataEventArgs args, PvPPlayer attacker, PvPPlayer target, PvPItem weapon, PvPProjectile projectile, PlayerDeathReason playerHitReason, int inflictedDamage, int damageReceived, int knockback) { if (PlayerHurtted != null) { PlayerHurtted(typeof(DataHandler), new PlayerHurtArgs(args, attacker, target, weapon, projectile, playerHitReason, inflictedDamage, damageReceived, knockback)); } }
/// <summary> /// Changes every item in a player's inventory to be the default values. /// </summary> public static void RefreshInventory(PvPPlayer player) { player.InvTracker.OnPvPInventoryChecked = false; for (byte index = 0; index < 58; index++) { SSCUtils.SetItem(player, index, player.TPlayer.inventory[index]); } }
public static void SpawnProjectile(PvPPlayer player, float x, float y, float speedX, float speedY, int type, int damage, float knockBack, int owner = 255, float ai0 = 0.0f, float ai1 = 0.0f) { int projIndex = Projectile.NewProjectile(x, y, speedX, speedY, type, damage, knockBack, owner, ai0, ai1); NetMessage.SendData(27, -1, -1, null, projIndex); player.ProjTracker.InsertProjectile(projIndex, type, player.Index, player.HeldItem); player.ProjTracker.Projectiles[type].PerformProjectileAction(); }
public bool ExtractData(PvPPlayer player, out TogglePvPArgs arg) { arg = new TogglePvPArgs { Player = player, Hostile = !player.TPlayer.hostile }; return(true); }
public PlayerUpdateArgs(MemoryStream data, PvPPlayer player) { this.player = player; data.ReadByte(); playerAction = data.ReadByte(); pulley = data.ReadByte(); this.selectedSlot = data.ReadByte(); }
public PlayerUpdateArgs(MemoryStream data, PvPPlayer player) { Player = player; data.ReadByte(); PlayerAction = data.ReadByte(); Pulley = data.ReadByte(); SelectedSlot = data.ReadByte(); }
/// <summary> /// Changes every item in a player's inventory that matches the item ID to the default values. /// </summary> /// <param name="itemID">Numerical ID of item to be reset.</param> public static void RefreshItem(PvPPlayer player, int itemID) { for (byte index = 0; index <= 58; index++) { if (player.TPlayer.inventory[index].netID == itemID) { SSCUtils.SetItem(player, index, player.TPlayer.inventory[index]); } } }
public static int GetVortexDamage(PvPPlayer attacker, PvPItem weapon, int damage) { double vanillaVortexMultiplier = 1.36; if (weapon.ranged && attacker.TPlayer.vortexStealthActive) { return((int)(((double)damage / vanillaVortexMultiplier * PvPController.config.vortexMultiplier) - damage)); } return(0); }
public static void HandleData(GetDataEventArgs args, MemoryStream data, PvPPlayer player) { switch (args.MsgID) { case PacketTypes.PlayerHurtV2: if (new PlayerHurtArgs().ExtractData(args, data, player, out var playerhurt)) { PlayerHurt?.Invoke(typeof(DataHandler), playerhurt); } return; case PacketTypes.TogglePvp: if (new TogglePvPArgs().ExtractData(player, out var togglepvp)) { PvPToggled?.Invoke(typeof(DataHandler), togglepvp); } return; case PacketTypes.PlayerSlot: if (new PlayerSlotArgs().ExtractData(data, player, out var playerslot)) { SlotUpdate?.Invoke(typeof(DataHandler), playerslot); } return; case PacketTypes.PlayerDeathV2: if (new PlayerDeathArgs().ExtractData(player, out var playerdeath)) { PlayerDeath?.Invoke(typeof(DataHandler), playerdeath); } return; case PacketTypes.ProjectileNew: if (new ProjectileNewArgs().ExtractData(args, data, player, out var projectilenew)) { ProjectileNew?.Invoke(typeof(DataHandler), projectilenew); } return; case PacketTypes.ProjectileDestroy: if (new ProjectileDestroyArgs().ExtractData(data, out var projectiledestroy)) { ProjectileDestroyed?.Invoke(typeof(DataHandler), projectiledestroy); } return; case PacketTypes.PlayerUpdate: if (new PlayerUpdateArgs().ExtractData(data, player, out var playerupdate)) { PlayerUpdate?.Invoke(typeof(DataHandler), playerupdate); } return; } }
/// <summary> /// Gets a <see cref="CustomWeapon"/> from the <see cref="Cache"/> /// </summary> /// <returns></returns> public static CustomWeapon GetCustomWeapon(PvPPlayer player, int type, byte prefix = 0, short stack = 1) { Item wep = new Item(); wep.SetDefaults(type); CustomWeapon custwep = new CustomWeapon { ItemNetId = (short)wep.netID, Prefix = prefix, Stack = stack, DropAreaWidth = short.MaxValue, DropAreaHeight = short.MaxValue }; DbItem dbitem = Cache.Items[type]; if (dbitem.Damage != -1) { custwep.Damage = (ushort)dbitem.Damage; } if (wep.knockBack != dbitem.Knockback) { custwep.Knockback = dbitem.Knockback; } if (dbitem.UseAnimation != -1) { custwep.UseAnimation = (ushort)dbitem.UseAnimation; } if (dbitem.UseTime != -1) { custwep.UseTime = (ushort)dbitem.UseTime; } if (dbitem.Shoot != -1) { custwep.ShootProjectileId = (short)dbitem.Shoot; } if (dbitem.ShootSpeed != -1) { custwep.ShootSpeed = dbitem.ShootSpeed; } if (dbitem.AmmoIdentifier != -1) { custwep.AmmoIdentifier = (short)dbitem.AmmoIdentifier; } if (dbitem.UseAmmoIdentifier != -1) { custwep.UseAmmoIdentifier = (short)dbitem.AmmoIdentifier; } if (wep.notAmmo != dbitem.IsNotAmmo) { custwep.NotAmmo = dbitem.NotAmmo == 1; } return(custwep); }
/// <summary> /// Processes data so it can be used in <see cref="Network.PvPEvents"/>. /// </summary> /// <param name="args">The data needed to be processed.</param> private void GetData(GetDataEventArgs args) { MemoryStream data = new MemoryStream(args.Msg.readBuffer, args.Index, args.Length); PvPPlayer attacker = PvPers[args.Msg.whoAmI]; if (attacker == null || !attacker.TPlayer.active || !attacker.ConnectionAlive) { return; } DataHandler.HandleData(args, data, attacker); }
/// <summary> /// Spawns Counterweights/Additional yoyos when a person has hit with one. /// This normally does not work in vanilla servers, so this must be emulated on a /// server for accessories such as Yoyo Bag to work. /// </summary> public static void ActivateYoyoBag(PvPPlayer attacker, PvPPlayer target, int dmg, float kb) { if (!attacker.TPlayer.yoyoGlove && attacker.TPlayer.counterWeight <= 0) { return; } int index1 = -1; int num1 = 0; int num2 = 0; for (int index2 = 0; index2 < 1000; ++index2) { if (Main.projectile[index2].active && Main.projectile[index2].owner == attacker.TPlayer.whoAmI) { if (Main.projectile[index2].counterweight) { ++num2; } else if (Main.projectile[index2].aiStyle == 99) { ++num1; index1 = index2; } } } if (attacker.TPlayer.yoyoGlove && num1 < 2) { if (index1 < 0) { return; } Vector2 vector21 = Vector2.Subtract(target.LastNetPosition, attacker.TPlayer.Center); vector21.Normalize(); Vector2 vector22 = Vector2.Multiply(vector21, 16f); ProjectileUtils.SpawnProjectile(attacker, attacker.TPlayer.Center.X, attacker.TPlayer.Center.Y, vector22.X, vector22.Y, Main.projectile[index1].type, Main.projectile[index1].damage, Main.projectile[index1].knockBack, attacker.TPlayer.whoAmI, 1f); } else { if (num2 >= num1) { return; } int index; Vector2 vector21 = Vector2.Subtract(target.LastNetPosition, attacker.TPlayer.Center); vector21.Normalize(); Vector2 vector22 = Vector2.Multiply(vector21, 16f); float knockBack = (float)((kb + 6.0) / 2.0); ProjectileUtils.SpawnProjectile(attacker, attacker.TPlayer.Center.X, attacker.TPlayer.Center.Y, vector22.X, vector22.Y, attacker.TPlayer.counterWeight, (int)(dmg * 0.8), knockBack, attacker.TPlayer.whoAmI, (num2 > 0).ToInt()); } }
public bool ExtractData(MemoryStream data, PvPPlayer player, out PlayerUpdateArgs arg) { data.ReadByte(); arg = new PlayerUpdateArgs { Player = player, PlayerAction = data.ReadByte(), Pulley = data.ReadByte(), SelectedSlot = data.ReadByte() }; return(true); }