public override void EnterState() { if (!isLoaded) { Entity temp; buildEntities = new List <Entity>(); temp = Parent.Controller.EntFactory.CreateIcon(GameVariables.IconTypes.BED, LodgingBuildSelect); buildEntities.Add(temp); Parent.AddEntity(temp); temp = Parent.Controller.EntFactory.CreateIcon(GameVariables.IconTypes.MUG, FareBuildSelect); buildEntities.Add(temp); Parent.AddEntity(temp); grid = new BuildGrid(GameVariables.GRID_SIZE, Parent.Controller.ScreenWidth, Parent.Controller.ScreenHeight); isLoaded = true; } else { foreach (Entity ent in buildEntities) { ent.IsVisible = true; } } currentEntity = null; base.EnterState(); }
/// <summary> /// Function gets called when a collision with this object occurs. /// </summary> /// <param name="ent"> Entity this object collides with.</param> /// <param name="penetration"> Amount of penetration.</param> /// <param name="side"> The side the objects collide on.</param> /// <param name="axis"> The axis that is being checked.</param> /// <param name="fromBounds"> Where the colliding entity came from.</param> public override void OnCollision(Entity ent, int penetration, CollisionTester.CollisionSide side, CollisionTester.Axis axis, Rectangle fromBounds) { // Check if the entity colliding is player and came from the bottom. if (ent is Player && side == CollisionTester.CollisionSide.BOTTOM && axis == CollisionTester.Axis.Y) { // Check if there is a powerup inside. if (_item != null) { // Get the powerup. PowerUp item = _item; // Set the position of the powerup. item.Position = Position; // Call the spawn of the powerup. item.OnSpawn(); // Add the powerup to the level. Parent.AddEntity(item); // Play wood animation. Animations.Play((int)GiftBlockAnimation.WOOD); // Remove item. _item = null; } } }
public void DropItem(byte slot) { UpdateInventorySlot(slot); if (!ValidSlot(slot)) { #if DEBUG Program.Print(PrintType.Error, "Invalid slot"); #endif return; } int item = Inventory[slot]; int data = ItemDatas[slot]; if (item == -1) { #if DEBUG Program.Print(PrintType.Error, "Nothing to drop"); #endif return; } Inventory[slot] = -1; ItemDatas[slot] = -1; UpdateInventorySlot(slot); Container container = new Container(Container.PurpleBag, Id, 120000); container.Inventory[0] = item; container.ItemDatas[0] = data; container.UpdateInventorySlot(0); RecalculateEquipBonuses(); Parent.AddEntity(container, Position + MathUtils.Position(.2f, .2f)); }
/// <summary> /// Function gets called on enemy death. /// </summary> /// <param name="ent"> Entity that killed this enemy.</param> public override void OnDeath(Entity ent) { // Set not solid and disable collisions. Solid = false; Collidable = false; // Start death timer. EnableDeathTimer(); // Add shell on position of death. if (!(ent is EggEnemy)) { Parent.AddEntity(new EggEnemy(new Vector2(Position.X, Position.Y + 11), 16, 16, _content, Parent)); } // Play death animation. Animations.Play((int)ChickenEnemyAnimation.DEATH); // Disable the start of a new animtaion. Animations.Lock(); // Call jump. Jump(); // Set width and height to death sprite size. Height = 16; Width = 15; }
/// <summary> /// Function gets called when a collision with this object occurs. /// </summary> /// <param name="ent"> Entity this object collides with.</param> /// <param name="penetration"> Amount of penetration.</param> /// <param name="side"> The side the objects collide on.</param> /// <param name="axis"> The axis that is being checked.</param> /// <param name="fromBounds"> Where the colliding entity came from.</param> public override void OnCollision(Entity ent, int penetration, CollisionTester.CollisionSide side, CollisionTester.Axis axis, Rectangle fromBounds) { // Check if collision is a player and came from the bottom. if (ent is Player && side == CollisionTester.CollisionSide.BOTTOM && axis == CollisionTester.Axis.Y) { // Check if there are any coins left. if (_coins > 0) { // Remove a coin. _coins--; int halfHeight = (Height / 2); // Create a new coin. Coin coin = new Coin(new Vector2(Position.X + 2, Position.Y - halfHeight), _content, Parent); // Coin should perform on free action. coin.OnFree(); // Add coin to the level. Parent.AddEntity(coin); // Set the state to BUMP_START. State = TileState.BUMP_START; } } }
void FareBuildSelect() { if (currentEntity != null) { Parent.RemoveEntity(currentEntity); currentEntity = null; } currentEntity = Parent.Controller.EntFactory.CreateRoom(GameVariables.RoomTypes.GREATHALL); currentEntity.SetPosition(new Vector2(64, 64)); // This should really only be called after the room is set Parent.Controller.CurrentInn.IncreaseCustomerChance(40); Parent.AddEntity(currentEntity); }
public void TryUseItem(int time, SlotData slot, Position target) { if (!ValidTime(time)) { #if DEBUG Program.Print(PrintType.Error, "Invalid time useitem"); #endif Client.Disconnect(); return; } if (slot.SlotId == HealthPotionSlotId) { if (HealthPotions > 0 && !HasConditionEffect(ConditionEffectIndex.Sick)) { Heal(100, false); HealthPotions--; } return; } else if (slot.SlotId == MagicPotionSlotId) { if (MagicPotions > 0 && !HasConditionEffect(ConditionEffectIndex.Quiet)) { Heal(100, true); MagicPotions--; } return; } Entity en = Parent.GetEntity(slot.ObjectId); if (slot.SlotId != 1) { (en as IContainer)?.UpdateInventorySlot(slot.SlotId); } if (en == null || !(en is IContainer)) { #if DEBUG Program.Print(PrintType.Error, "Undefined entity"); #endif return; } if (en is Player && !en.Equals(this)) { #if DEBUG Program.Print(PrintType.Error, "Trying to use items from another players inventory"); #endif return; } if (en is Container c) { if ((en as Container).OwnerId != -1 && (en as Container).OwnerId != Id) { #if DEBUG Program.Print(PrintType.Error, "Trying to use items from another players container/bag"); #endif return; } if (en.Position.Distance(this) > ContainerMinimumDistance) { #if DEBUG Program.Print(PrintType.Error, "Too far away from container"); #endif return; } } IContainer con = en as IContainer; ItemDesc desc = null; if (con.Inventory[slot.SlotId] != -1) { desc = Resources.Type2Item[(ushort)con.Inventory[slot.SlotId]]; } if (desc == null) { #if DEBUG Program.Print(PrintType.Error, "Invalid use item"); #endif return; } bool isAbility = slot.SlotId == 1; if (isAbility) { if (slot.ObjectId != Id) { #if DEBUG Program.Print(PrintType.Error, "Trying to use ability from a container?"); #endif return; } if (UseTime + (UseDuration * (1f / UseCooldownThreshold)) > time) { #if DEBUG Program.Print(PrintType.Error, "Used ability too soon"); #endif return; } if (MP - desc.MpCost < 0) { #if DEBUG Program.Print(PrintType.Error, "Not enough MP"); #endif return; } } bool inRange = Position.Distance(target) <= MaxAbilityDist && Parent.GetTileF(target.X, target.Y) != null; Action callback = null; foreach (ActivateEffectDesc eff in desc.ActivateEffects) { switch (eff.Index) { case ActivateEffectIndex.Shuriken: //Could be optimized too, it's not great.. { byte[] nova = GameServer.ShowEffect(ShowEffectIndex.Nova, Id, 0xffeba134, new Position(2.5f, 0)); foreach (Entity j in Parent.EntityChunks.HitTest(Position, 2.5f)) { if (j is Enemy k && !k.HasConditionEffect(ConditionEffectIndex.Invincible) && !k.HasConditionEffect(ConditionEffectIndex.Stasis)) { k.ApplyConditionEffect(ConditionEffectIndex.Dazed, 1000); } } List <byte[]> stars = new List <byte[]>(); HashSet <Entity> seeked = new HashSet <Entity>(); int startId = NextAEProjectileId; NextAEProjectileId += eff.Amount; float angle = Position.Angle(target); float cone = MathF.PI / 8; for (int i = 0; i < eff.Amount; i++) { Entity t = this.GetNearestEnemy(8, angle, cone, target, seeked) ?? this.GetNearestEnemy(6, seeked); if (t != null) { seeked.Add(t); } int d = GetNextDamage(desc.Projectile.MinDamage, desc.Projectile.MaxDamage, ItemDatas[slot.SlotId]); float a = t == null?MathUtils.NextAngle() : Position.Angle(t.Position); List <Projectile> p = new List <Projectile>() { new Projectile(this, desc.Projectile, startId + i, time, a, Position, d) }; stars.Add(GameServer.ServerPlayerShoot(startId + i, Id, desc.Type, Position, a, 0, p)); AwaitProjectiles(p); } foreach (Entity j in Parent.PlayerChunks.HitTest(Position, SightRadius)) { if (j is Player k) { if (k.Client.Account.Effects || k.Equals(this)) { k.Client.Send(nova); } if (k.Client.Account.AllyShots || k.Equals(this)) { foreach (byte[] s in stars) { k.Client.Send(s); } } } } } break; case ActivateEffectIndex.VampireBlast: //Maybe optimize this...? if (inRange) { byte[] line = GameServer.ShowEffect(ShowEffectIndex.Line, Id, 0xFFFF0000, target); byte[] burst = GameServer.ShowEffect(ShowEffectIndex.Burst, Id, 0xFFFF0000, target, new Position(target.X + eff.Radius, target.Y)); int lifeSucked = 0; List <Entity> enemies = new List <Entity>(); List <Entity> players = new List <Entity>(); List <byte[]> flows = new List <byte[]>(); foreach (Entity j in Parent.EntityChunks.HitTest(target, eff.Radius)) { if (j is Enemy k && !k.HasConditionEffect(ConditionEffectIndex.Invincible) && !k.HasConditionEffect(ConditionEffectIndex.Stasis)) { k.Damage(this, eff.TotalDamage, eff.Effects, true, true); lifeSucked += eff.TotalDamage; enemies.Add(k); } } foreach (Entity j in Parent.PlayerChunks.HitTest(Position, eff.Radius)) { if (j is Player k) { players.Add(k); k.Heal(lifeSucked, false); } } if (enemies.Count > 0) { for (int i = 0; i < 5; i++) { Entity a = enemies[MathUtils.Next(enemies.Count)]; Entity b = players[MathUtils.Next(players.Count)]; flows.Add(GameServer.ShowEffect(ShowEffectIndex.Flow, b.Id, 0xffffffff, a.Position)); } } foreach (Entity j in Parent.PlayerChunks.HitTest(Position, SightRadius)) { if (j is Player k) { if (k.Client.Account.Effects) { k.Client.Send(line); foreach (byte[] p in flows) { k.Client.Send(p); } } if (k.Client.Account.Effects || k.Equals(this)) { k.Client.Send(burst); } } } } break; case ActivateEffectIndex.StasisBlast: if (inRange) { byte[] blast = GameServer.ShowEffect(ShowEffectIndex.Collapse, Id, 0xffffffff, target, new Position(target.X + 3, target.Y)); List <byte[]> notifications = new List <byte[]>(); foreach (Entity j in Parent.EntityChunks.HitTest(target, 3)) { if (j is Enemy k) { if (k.HasConditionEffect(ConditionEffectIndex.StasisImmune)) { notifications.Add(GameServer.Notification(k.Id, "Immune", 0xff00ff00)); continue; } if (k.HasConditionEffect(ConditionEffectIndex.Stasis)) { continue; } notifications.Add(GameServer.Notification(k.Id, "Stasis", 0xffff0000)); k.ApplyConditionEffect(ConditionEffectIndex.Stasis, eff.DurationMS); k.ApplyConditionEffect(ConditionEffectIndex.StasisImmune, eff.DurationMS + 3000); } } foreach (Entity j in Parent.PlayerChunks.HitTest(Position, SightRadius)) { if (j is Player k) { if (k.Client.Account.Effects || k.Equals(this)) { k.Client.Send(blast); } if (k.Client.Account.Notifications || k.Equals(this)) { foreach (byte[] n in notifications) { k.Client.Send(n); } } } } } break; case ActivateEffectIndex.Trap: if (inRange) { byte[] @throw = GameServer.ShowEffect(ShowEffectIndex.Throw, Id, 0xff9000ff, target); foreach (Entity j in Parent.PlayerChunks.HitTest(Position, SightRadius)) { if (j is Player k && (k.Client.Account.Effects || k.Equals(this))) { k.Client.Send(@throw); } } Manager.AddTimedAction(1500, () => { if (Parent != null) { Parent.AddEntity(new Trap(this, eff.Radius, eff.TotalDamage, eff.Effects), target); } }); } break; case ActivateEffectIndex.Lightning: { float angle = Position.Angle(target); float cone = MathF.PI / 4; Entity start = this.GetNearestEnemy(MaxAbilityDist, angle, cone, target); if (start == null) { float[] angles = new float[3] { angle, angle - cone, angle + cone }; byte[][] lines = new byte[3][]; for (int i = 0; i < 3; i++) { float x = (int)(MaxAbilityDist * MathF.Cos(angles[i])) + Position.X; float y = (int)(MaxAbilityDist * MathF.Sin(angles[i])) + Position.Y; lines[i] = GameServer.ShowEffect(ShowEffectIndex.Line, Id, 0xffff0088, new Position(x, y), new Position(350, 0)); } foreach (Entity j in Parent.PlayerChunks.HitTest(Position, SightRadius)) { if (j is Player k && k.Client.Account.Effects) { k.Client.Send(lines[0]); k.Client.Send(lines[1]); k.Client.Send(lines[2]); } } } else { Entity prev = this; Entity current = start; HashSet <Entity> targets = new HashSet <Entity>(); List <byte[]> pkts = new List <byte[]>(); targets.Add(current); (current as Enemy).Damage(this, eff.TotalDamage, eff.Effects, false, true); for (int i = 1; i < eff.MaxTargets + 1; i++) { pkts.Add(GameServer.ShowEffect(ShowEffectIndex.Lightning, prev.Id, 0xffff0088, new Position(current.Position.X, current.Position.Y), new Position(350, 0))); if (i == eff.MaxTargets) { break; } Entity next = current.GetNearestEnemy(10, targets); if (next == null) { break; } targets.Add(next); (next as Enemy).Damage(this, eff.TotalDamage, eff.Effects, false, true); prev = current; current = next; } foreach (Entity j in Parent.PlayerChunks.HitTest(Position, SightRadius)) { if (j is Player k && k.Client.Account.Effects) { foreach (byte[] p in pkts) { Console.WriteLine(p.Length); k.Client.Send(p); } } } } } break; case ActivateEffectIndex.PoisonGrenade: if (inRange) { Placeholder placeholder = new Placeholder(); Parent.AddEntity(placeholder, target); byte[] @throw = GameServer.ShowEffect(ShowEffectIndex.Throw, Id, 0xffddff00, target); byte[] nova = GameServer.ShowEffect(ShowEffectIndex.Nova, placeholder.Id, 0xffddff00, new Position(eff.Radius, 0)); foreach (Entity j in Parent.PlayerChunks.HitTest(Position, SightRadius)) { if (j is Player k && (k.Client.Account.Effects || k.Equals(this))) { k.Client.Send(@throw); } } Manager.AddTimedAction(1500, () => { if (placeholder.Parent != null) { if (Parent != null) { foreach (Entity j in Parent.PlayerChunks.HitTest(Position, SightRadius)) { if (j is Player k && (k.Client.Account.Effects || k.Equals(this))) { k.Client.Send(nova); } } foreach (Entity j in Parent.EntityChunks.HitTest(placeholder.Position, eff.Radius)) { if (j is Enemy e) { e.ApplyPoison(this, new ConditionEffectDesc[0], (int)(eff.TotalDamage / (eff.DurationMS / 1000f)), eff.TotalDamage); } } } placeholder.Parent.RemoveEntity(placeholder); } });
public void Death(string killer) { #if DEBUG if (Parent.Name.Equals("Dreamland")) { return; } #endif if (Dead) { return; } Client.Active = false; Dead = true; SaveToCharacter(); Database.Death(killer, Client.Account, Client.Character); byte[] death = GameServer.Death(Client.Account.Id, Client.Character.Id, killer); Client.Send(death); byte[] text = GameServer.Text("", 0, -1, 0, "", $"{Name} died at level {Level} killed by {killer}!"); byte[] sound = GameServer.PlaySound("quack"); foreach (Player p in Parent.Players.Values) { p.Client.Send(text); if (p.Client.Account.Sounds) { p.Client.Send(sound); } } ushort type; int time; switch (GetMaxedStats()) { case 8: type = 0x0735; time = 600000; break; case 7: type = 0x0734; time = 600000; break; case 6: type = 0x072b; time = 600000; break; case 5: type = 0x072a; time = 600000; break; case 4: type = 0x0729; time = 600000; break; case 3: type = 0x0728; time = 600000; break; case 2: type = 0x0727; time = 600000; break; case 1: type = 0x0726; time = 600000; break; default: type = 0x0725; time = 300000; if (Level < 20) { type = 0x0724; time = 60000; } if (Level <= 1) { type = 0x0723; time = 30000; } break; } Entity grave = new Entity(type, time); grave.TrySetSV(StatType.Name, Name); Parent.AddEntity(grave, Position); Parent.RemoveEntity(this); Manager.AddTimedAction(1500, () => { Client.Disconnect(); }); }
public void Death(Player killer) { #if DEBUG if (killer == null) { throw new Exception("Undefined killer"); } #endif int baseExp = (int)Math.Ceiling(MaxHP / 10f); if (baseExp != 0) { List <Entity> l; foreach (Entity en in l = Parent.PlayerChunks.HitTest(Position, Player.SightRadius)) { if (!(en is Player player)) { continue; } int exp = baseExp; if (exp > Player.GetNextLevelEXP(player.Level) / 10) { exp = Player.GetNextLevelEXP(player.Level) / 10; } if (player.GainEXP(exp)) { foreach (Entity p in l) { if (!p.Equals(player)) { (p as Player).FameStats.LevelUpAssists++; } } } } } int position = 0; foreach (KeyValuePair <int, int> i in DamageStorage.OrderByDescending(k => k.Value)) { Entity en = Parent.GetEntity(i.Key); if (en == null) { continue; } Player player = en as Player; if (Desc.Quest) { player.HealthPotions = Math.Min(Player.MaxPotions, player.HealthPotions + 1); player.MagicPotions = Math.Min(Player.MaxPotions, player.MagicPotions + 1); } else { if (MathUtils.Chance(.05f)) { player.HealthPotions = Math.Min(Player.MaxPotions, player.HealthPotions + 1); } if (MathUtils.Chance(.05f)) { player.MagicPotions = Math.Min(Player.MaxPotions, player.MagicPotions + 1); } } if (!player.Equals(killer)) { player.FameStats.MonsterAssists++; if (Desc.Cube) { player.FameStats.CubeAssists++; } if (Desc.Oryx) { player.FameStats.OryxAssists++; } if (Desc.God) { player.FameStats.GodAssists++; } } if (Behavior != null && Behavior.Loots.Count > 0) { List <int> items = new List <int>(); foreach (Loot l in Behavior.Loots) { float t = Math.Min(1f, i.Value / MaxHP); int j = l.TryObtainItem(this, player, position, t); if (j != -1) { items.Add(j); } if (items.Count == Container.MaxSlots) { break; } } if (items.Count > 0) { int bagType = 1; for (int k = 0; k < items.Count; k++) { ItemDesc d = Resources.Type2Item[(ushort)items[k]]; if (d.BagType > bagType) { bagType = d.BagType; } } if (bagType == 2) { player.FameStats.CyanBags++; } else if (bagType == 3) { player.FameStats.BlueBags++; } else if (bagType == 4) { player.FameStats.WhiteBags++; } Container c = new Container(Container.FromBagType(bagType), player.Id, 40000 * bagType); for (int k = 0; k < items.Count; k++) { Tuple <bool, ItemData> roll = Resources.Type2Item[(ushort)items[k]].Roll(); c.Inventory[k] = items[k]; c.ItemDatas[k] = roll.Item1 ? (int)roll.Item2 : -1; c.UpdateInventorySlot(k); } Parent.AddEntity(c, Position + MathUtils.Position(0.2f, 0.2f)); } } position++; } killer.FameStats.MonsterKills++; if (Desc.Cube) { killer.FameStats.CubeKills++; } if (Desc.Oryx) { killer.FameStats.OryxKills++; } if (Desc.God) { killer.FameStats.GodKills++; } if (Behavior != null) { foreach (Behavior b in Behavior.Behaviors) { b.Death(this); } foreach (State s in CurrentStates) { foreach (Behavior b in s.Behaviors) { b.Death(this); } } } Dead = true; Parent.RemoveEntity(this); }
public void Chat(string text) { if (text.Length <= 0 || text.Length > 128) { #if DEBUG Program.Print(PrintType.Error, "Text too short or too long"); #endif Client.Disconnect(); return; } string validText = Regex.Replace(text, @"[^a-zA-Z0-9`!@#$%^&* ()_+|\-=\\{}\[\]:"";'<>?,./]", ""); if (validText.Length <= 0) { SendError("Invalid text."); return; } if (LastChatTime + ChatCooldownMS > Manager.TotalTimeUnsynced) { SendError("Message sent too soon after previous one."); return; } LastChatTime = Manager.TotalTimeUnsynced; if (validText[0] == '/') { string[] s = validText.Split(' '); string[] j = new string[s.Length - 1]; for (int i = 1; i < s.Length; i++) { j[i - 1] = s[i]; } string command = s[0]; string input = string.Join(' ', j); switch (command.ToLower()) { case "/legendary": if (Client.Account.Ranked) { int slot = int.Parse(j[0]); if (Inventory[slot] != -1) { Tuple <bool, ItemData> roll = Resources.Type2Item[(ushort)Inventory[slot]].Roll(); while ((roll.Item2 & ItemData.T7) == 0) { roll = Resources.Type2Item[(ushort)Inventory[slot]].Roll(); } ItemDatas[slot] = !roll.Item1 ? -1 : (int)roll.Item2; UpdateInventorySlot(slot); RecalculateEquipBonuses(); } } break; case "/roll": if (Client.Account.Ranked) { for (int k = 0; k < 20; k++) { if (Inventory[k] != -1) { Tuple <bool, ItemData> roll = Resources.Type2Item[(ushort)Inventory[k]].Roll(); ItemDatas[k] = !roll.Item1 ? -1 : (int)roll.Item2; UpdateInventorySlot(k); RecalculateEquipBonuses(); } } } break; case "/disconnect": case "/dcAll": case "/dc": if (Client.Account.Ranked) { foreach (Client c in Manager.Clients.Values.ToArray()) { try { c.Disconnect(); } catch { } } } break; case "/terminate": case "/stop": if (Client.Account.Ranked) { Program.StartTerminating(); return; } break; case "/gimme": case "/give": if (!Client.Account.Ranked) { SendError("Not ranked"); return; } if (Resources.IdLower2Item.TryGetValue(input.ToLower(), out ItemDesc item)) { if (GiveItem(item.Type)) { SendInfo("Success"); } else { SendError("No inventory slots"); } } else { SendError($"Item <{input}> not found in GameData"); } break; case "/create": case "/spawn": if (!Client.Account.Ranked) { SendError("Not ranked"); return; } if (string.IsNullOrWhiteSpace(input)) { SendHelp("/spawn <count> <entity>"); return; } int spawnCount; if (!int.TryParse(j[0], out spawnCount)) { spawnCount = -1; } if (Resources.IdLower2Object.TryGetValue((spawnCount == -1 ? input : string.Join(' ', j.Skip(1))).ToLower(), out ObjectDesc desc)) { if (spawnCount == -1) { spawnCount = 1; } if (desc.Player || desc.Static) { SendError("Can't spawn this entity"); return; } SendInfo($"Spawning <{spawnCount}> <{desc.DisplayId}> in 2 seconds"); Position pos = Position; Manager.AddTimedAction(2000, () => { for (int i = 0; i < spawnCount; i++) { Entity entity = Resolve(desc.Type); Parent?.AddEntity(entity, pos); } }); } else { SendError($"Entity <{input}> not found in Game Data"); } break; case "/max": if (!Client.Account.Ranked) { SendError("Not ranked"); return; } for (int i = 0; i < Stats.Length; i++) { Stats[i] = (Desc as PlayerDesc).Stats[i].MaxValue; } UpdateStats(); SendInfo("Maxed"); break; case "/god": if (!Client.Account.Ranked) { SendError("Not ranked"); return; } ApplyConditionEffect(ConditionEffectIndex.Invincible, HasConditionEffect(ConditionEffectIndex.Invincible) ? 0 : -1); SendInfo($"Godmode set to {HasConditionEffect(ConditionEffectIndex.Invincible)}"); break; case "/allyshots": Client.Account.AllyShots = !Client.Account.AllyShots; SendInfo($"Ally shots set to {Client.Account.AllyShots}"); break; case "/allydamage": Client.Account.AllyDamage = !Client.Account.AllyDamage; SendInfo($"Ally damage set to {Client.Account.AllyDamage}"); break; case "/effects": Client.Account.Effects = !Client.Account.Effects; SendInfo($"Effects set to {Client.Account.Effects}"); break; case "/sounds": Client.Account.Sounds = !Client.Account.Sounds; SendInfo($"Sounds set to {Client.Account.Sounds}"); break; case "/notifications": Client.Account.Notifications = !Client.Account.Notifications; SendInfo($"Notifications set to {Client.Account.Notifications}"); break; case "/online": case "/who": SendInfo($"" + $"<{Manager.Clients.Values.Count(k => k.Player != null)} Player(s)> " + $"<{string.Join(", ", Manager.Clients.Values.Where(k => k.Player != null).Select(k => k.Player.Name))}>"); break; case "/server": case "/pos": case "/loc": SendInfo(this.ToString()); break; case "/where": case "/find": Player findTarget = Manager.GetPlayer(input); if (findTarget == null) { SendError("Couldn't find player"); } else { SendInfo(findTarget.ToString()); } break; case "/fame": case "/famestats": case "/stats": SaveToCharacter(); FameStats fameStats = Database.CalculateStats(Client.Account, Client.Character, ""); SendInfo($"Active: {FameStats.MinutesActive} minutes"); SendInfo($"Shots: {FameStats.Shots}"); SendInfo($"Accuracy: {(int)(((float)FameStats.ShotsThatDamage / FameStats.Shots) * 100f)}% ({FameStats.ShotsThatDamage}/{FameStats.Shots})"); SendInfo($"Abilities Used: {FameStats.AbilitiesUsed}"); SendInfo($"Tiles Seen: {FameStats.TilesUncovered}"); SendInfo($"Monster Kills: {FameStats.MonsterKills} ({FameStats.MonsterAssists} Assists, {(int)(((float)FameStats.MonsterKills / (FameStats.MonsterKills + FameStats.MonsterAssists)) * 100f)}% Final Blows)"); SendInfo($"God Kills: {FameStats.GodKills} ({(int)(((float)FameStats.GodKills / FameStats.MonsterKills) * 100f)}%) ({FameStats.GodKills}/{FameStats.MonsterKills})"); SendInfo($"Oryx Kills: {FameStats.OryxKills} ({(int)(((float)FameStats.OryxKills / FameStats.MonsterKills) * 100f)}%) ({FameStats.OryxKills}/{FameStats.MonsterKills})"); SendInfo($"Cube Kills: {FameStats.CubeKills} ({(int)(((float)FameStats.CubeKills / FameStats.MonsterKills) * 100f)}%) ({FameStats.CubeKills}/{FameStats.MonsterKills})"); SendInfo($"Cyan Bags: {FameStats.CyanBags}"); SendInfo($"Blue Bags: {FameStats.BlueBags}"); SendInfo($"White Bags: {FameStats.WhiteBags}"); SendInfo($"Damage Taken: {FameStats.DamageTaken}"); SendInfo($"Damage Dealt: {FameStats.DamageDealt}"); SendInfo($"Teleports: {FameStats.Teleports}"); SendInfo($"Potions Drank: {FameStats.PotionsDrank}"); SendInfo($"Quests Completed: {FameStats.QuestsCompleted}"); SendInfo($"Pirate Caves Completed: {FameStats.PirateCavesCompleted}"); SendInfo($"Spider Dens Completed: {FameStats.SpiderDensCompleted}"); SendInfo($"Snake Pits Completed: {FameStats.SnakePitsCompleted}"); SendInfo($"Sprite Worlds Completed: {FameStats.SpriteWorldsCompleted}"); SendInfo($"Undead Lairs Completed: {FameStats.UndeadLairsCompleted}"); SendInfo($"Abyss Of Demons Completed: {FameStats.AbyssOfDemonsCompleted}"); SendInfo($"Tombs Completed: {FameStats.TombsCompleted}"); SendInfo($"Escapes: {FameStats.Escapes}"); SendInfo($"Near Death Escapes: {FameStats.NearDeathEscapes}"); SendInfo($"Party Member Level Ups: {FameStats.LevelUpAssists}"); foreach (FameBonus bonus in fameStats.Bonuses) { SendHelp($"{bonus.Name}: +{bonus.Fame}"); } SendInfo($"Base Fame: {fameStats.BaseFame}"); SendInfo($"Total Fame: {fameStats.TotalFame}"); break; default: SendError("Unknown command"); break; } return; } if (Client.Account.Muted) { SendError("You are muted"); return; } byte[] packet = GameServer.Text(Name, Id, NumStars, 5, "", validText); foreach (Player player in Parent.Players.Values) { if (!player.Client.Account.IgnoredIds.Contains(AccountId)) { player.Client.Send(packet); } } }