public static unsafe byte[] SpawnCarpet(YiObj character, int id) { const ushort packetType = 1109; var packet = BufferPool.GetBuffer(); fixed(byte *p = packet) { *(ushort *)p = (ushort)(28 + character.Name.Length); *(ushort *)(p + 2) = packetType; *(int *)(p + 4) = id; *(ushort *)(p + 16) = (ushort)(character.Location.X + (ushort)Constants.DeltaX[(sbyte)character.Direction]); *(ushort *)(p + 18) = (ushort)(character.Location.Y + (ushort)Constants.DeltaY[(sbyte)character.Direction]); *(ushort *)(p + 20) = 400; //TODO Figure out what value this is, set proper direction *(ushort *)(p + 22) = 14; *(p + 24) = 11; *(p + 26) = 1; *(p + 27) = (byte)character.Name.Length; for (var I = 0; I < character.Name.Length; I++) { *(p + 28 + I) = Convert.ToByte(character.Name[I]); } } return(packet); }
private static IEnumerable <(YiObj, int)> GetTargets(YiObj player, Vector2 loc, MagicTypeEnum magicType) { var targetList = new List <(YiObj, int)>(); switch (MagicTypeHelper.ConvertTargetingType(magicType)) { case TargetingType.Single: Single(player, targetList); break; case TargetingType.Sector: Sector(player, loc, targetList); break; case TargetingType.Circle: Circle(player, targetList); break; case TargetingType.Self: targetList.Add((player, 0)); break; } return(targetList); }
private static void ConfigureAutoAttack(YiObj attacker, int damage) { if (!(attacker is Player player)) { return; } if (!attacker.CurrentTarget.Alive) { return; } if (attacker.CurrentTarget.CurrentHp - damage <= 0) { return; } if (!Constants.LoopableSkills.Contains(attacker.CurrentSkill.Id)) { return; } if (player.AttackJob != null) { player.AttackJob.Cancelled = true; } var delay = TimeSpan.FromMilliseconds(attacker.CurrentSkill.Info.IntoneDuration * 1.5); player.AttackJob = YiScheduler.Instance.DoReturn(delay, () => ExecuteAttack(player, attacker.Location)); }
public static int PhysicalAttack(YiObj attacker, MsgInteractType attackType = MsgInteractType.Physical) { if (!CanAttackPhysical(attacker, attacker.CurrentTarget)) { return(-1); } if (attacker.HasFlag(StatusEffect.Invisibility)) { attacker.RemoveStatusEffect(StatusEffect.Invisibility); } if (attacker is Player player) { if (player.AttackJob != null) { player.AttackJob.Cancelled = true; } if (player.CurrentTarget != null && player.CurrentTarget.Alive) { player.AttackJob = YiScheduler.Instance.DoReturn(TimeSpan.FromMilliseconds(attacker.AttackSpeed), () => MsgInteract.Handle(player, MsgInteract.Create(attacker, attacker.CurrentTarget, attackType, 0))); } } return(AttackCalcs.GetDamage(attacker, attacker.CurrentTarget, attackType)); }
public static void SendSpawn(YiObj obj) { try { if (obj is Monster monster) { if (!Entities.ContainsKey(obj.UniqueId)) { Create(obj); } foreach (var uid in Entities[obj.UniqueId]) { if (!GameWorld.Maps[obj.MapId].Entities.TryGetValue(uid, out var found)) { continue; } if (found is Player player) { player.Send(MsgSpawn.Create(monster)); player.Send(MsgAction.SpawnEffect(monster)); } } } } catch (Exception e) { Output.WriteLine(e); } }
private static void ACTION_USER_HAIR(YiObj target, YiObj invoker, cq_action cqaction, SquigglyContext db) { var nextIds = cqaction.param.Trim().Split(' '); invoker.Hair = uint.Parse(nextIds[1]); Process(target, invoker, db.cq_action.Find(cqaction.id_next), db); }
public static void Drop(YiObj attacker, Monster mob) { var rand = SafeRandom.Next(1, 1000); Item created = default(Item); switch (mob.Id) { case 3131: case 3135: created = ItemFactory.Create(ItemNames.ExpPotion); break; //exp potion from titan and gano default: { if (!GenerateDrop(attacker, mob, rand, ref created)) //YOU FORGOT TO ADD THE ! SO NOTHING WAS DROPPING { return; } break; } } if (created.Valid()) { FloorItemSystem.Drop(attacker, mob, created); } if (YiCore.Success(5)) //5% chance to drop more than one item. { Drop(attacker, mob); } }
private static void ACTION_USER_MEDIAPLAY(YiObj target, YiObj invoker, cq_action cqaction, SquigglyContext db) { var nextIds = cqaction.param.Trim().Split(' '); //Send Sound Packet here Process(target, invoker, db.cq_action.Find(cqaction.id_next), db); }
private static void ACTION_USER_EFFECT(YiObj target, YiObj invoker, cq_action cqaction, SquigglyContext db) { var nextIds = cqaction.param.Trim().Split(' '); (invoker as Player)?.Send(LegacyPackets.Effect(invoker, nextIds[1])); Process(target, invoker, db.cq_action.Find(cqaction.id_next), db); }
private static void ACTION_ITEM_MULTIDEL(YiObj target, YiObj invoker, cq_action cqaction, SquigglyContext db) { var items = cqaction.param.Trim().Split(' '); var startId = int.Parse(items[0]); var endId = int.Parse(items[1]); var amount = int.Parse(items[2]); var range = Enumerable.Range(startId, (endId - startId) + 1); var amountFound = (from id in range from inventoryItem in invoker.Inventory.Items where inventoryItem.Value.ItemId == id select id).Count(); var removed = 0; foreach (var inventoryItem in invoker.Inventory.Items) { if (removed == amount) { break; } if (range.Contains(inventoryItem.Value.ItemId)) { invoker.Inventory.RemoveItem(inventoryItem.Value); removed++; } } Process(target, invoker, amountFound >= amount ? db.cq_action.Find(cqaction.id_next) : db.cq_action.Find(cqaction.id_nextfail), db); }
public static float AdjustEvP(float damage, Monster attacker, YiObj target) { byte level = 120; if (attacker.Level < 120) { level = attacker.Level; } if (attacker.IsRed(target)) { damage *= 1.5f; } else if (attacker.IsBlack(target)) { var deltaLvl = target.Level - level; if (deltaLvl >= -10 && deltaLvl <= -5) { damage *= 2.0f; } else if (deltaLvl >= -20 && deltaLvl < -10) { damage *= 3.5f; } else if (deltaLvl < -20) { damage *= 5.0f; } } return(Math.Max(0, (int)damage)); }
public static byte[] Create(YiObj human) { MsgSyndicateSpawn *msgP = stackalloc MsgSyndicateSpawn[1]; msgP->Size = (ushort)sizeof(MsgSyndicateSpawn); msgP->Id = 1106; if (human.Guild != null) { msgP->UniqueId = human.Guild.UniqueId; msgP->Donation = human.GuildDonation; msgP->Funds = human.Guild.Funds; msgP->Rank = human.GuildRank; msgP->MemberCount = human.Guild.Members.Count; if (GameWorld.Find(human.Guild.Leader, out Player leader)) { for (byte i = 0; i < leader.Name.Length; i++) { msgP->LeaderName[i] = (byte)leader.Name[i]; } } } var buffer = BufferPool.GetBuffer(); fixed(byte *p = buffer) * (MsgSyndicateSpawn *)p = *msgP; return(buffer); }
public static bool TakeOut(YiObj owner, int npcId, int itemId) { if (StoragePool[owner.UniqueId].TryGetValue(owner.CurrentStorageId, out var storage)) { if (storage.NpcId != npcId) { Message.SendTo(owner, "hacker.", MsgTextType.Action); return(false); } if (storage.CanTakeItems(owner)) { if (!storage.Contents.TryRemove(itemId, out var item)) { return(false); } if (owner.Inventory.AddItem(item)) { return(true); } storage.Contents.AddOrUpdate(item.UniqueId, item); Message.SendTo(owner, "Item was returned. Inventory full?", MsgTextType.Action); } else { Message.SendTo(owner, "You're not allowed to take out items from this storage.", MsgTextType.Action); } } else { NewStorage(owner, npcId); } return(false); }
public void Leave(YiObj obj) { Entities.TryRemove(obj.UniqueId); switch (obj) { case Npc npc: //RemoveNpc(obj); break; case DynamicNpc npc: //RemoveNpc(obj); break; case Monster monster: RemoveMob(obj); break; case FloorItem item: RemoveItem(obj); break; } ScreenSystem.Send(obj, MsgAction.Create(obj, 0, MsgActionType.EntityRemove)); ScreenSystem.ClearFor(obj); }
private static void Invite(YiObj player, ref MsgTeam packet) { if (!TeamSystem.Teams.ContainsKey(player.UniqueId)) { return; } if (TeamSystem.Teams[player.UniqueId].Members.ContainsKey(packet.TargetUniqueId)) { return; } if (TeamSystem.Teams[player.UniqueId].Members.Count > 4) { return; } if (!GameWorld.Maps[player.MapId].Entities.TryGetValue(packet.TargetUniqueId, out var found)) { return; } if (found == null) { return; } var target = found; (target as Player)?.Send(Invite(player)); if (target is Bot) { TeamSystem.Join(player, target); } }
private static void AddItem(YiObj player, ref MsgTrade packet) { if (packet.UniqueId == 0) { return; } if (player.Trade == null) { return; } if (!player.Inventory.Items.TryGetValue(packet.UniqueId, out var found)) { return; } if (player.Trade.Owner.UniqueId == player.UniqueId) { if (player.Trade.OwnerItems.Count >= 20) { return; } if (player.Trade.Partner.Inventory.Count + player.Trade.OwnerItems.Count > 40 && !(player.Trade.Partner is Npc)) { return; } if (player.Trade.OwnerItems.ContainsKey(found.UniqueId)) { return; } player.Trade.OwnerItems.Add(found.UniqueId, found); (player.Trade.Partner as Player)?.Send(new MsgItemInformation(found, MsgItemInfoAction.Trade)); if (player.Trade.Partner is Npc) { player.Trade.PartnerMoney += found.PriceBaseline; packet.Mode = TradeMode.DisplayMoney; packet.UniqueId = player.Trade.PartnerMoney; (player as Player)?.ForceSend(packet, packet.Size); (player as Player)?.Send(Create(packet.UniqueId, TradeMode.DisplayMoney)); } } else { if (player.Trade.PartnerItems.Count >= 20) { return; } if (player.Trade.Owner.Inventory.Count + player.Trade.PartnerItems.Count > 40) { return; } if (player.Trade.PartnerItems.ContainsKey(found.UniqueId)) { return; } player.Trade.PartnerItems.Add(found.UniqueId, found); (player.Trade.Owner as Player)?.Send(new MsgItemInformation(found, MsgItemInfoAction.Trade)); } }
public static bool Execute(YiObj player, Item item) { try { if (player.CurrentHp == player.MaximumHp) { Message.SendTo(player, "Your hitpoints are full.", MsgTextType.Action); return(false); } if (player.CurrentHp + 2000 > player.MaximumHp) { player.CurrentHp = player.MaximumHp; } else { player.CurrentHp += 2000; } player.Inventory.RemoveItem(item); } catch { return(false); } return(true); }
private static void AddMoney(YiObj player, ref MsgTrade packet) { if (packet.UniqueId == 0) { return; } if (player.Trade == null) { return; } if (player.Money < packet.UniqueId) { return; } if (player.Trade.Owner.UniqueId == player.UniqueId) { if (player.Trade.Partner.Money + packet.UniqueId > int.MaxValue) { return; } player.Trade.OwnerMoney += packet.UniqueId; (player.Trade.Partner as Player)?.Send(Create(packet.UniqueId, TradeMode.DisplayMoney)); } else { if (player.Trade.Owner.Money + packet.UniqueId > int.MaxValue) { return; } player.Trade.PartnerMoney += packet.UniqueId; (player.Trade.Owner as Player)?.Send(Create(packet.UniqueId, TradeMode.DisplayMoney)); } }
public static bool Execute(YiObj player, Item item) { try { var human = player; if (human.CurrentMp == human.MaximumMp) { Message.SendTo(player, "Your manapoints are full.", MsgTextType.Action); return(false); } if (human.CurrentMp + 500 > human.MaximumMp) { human.CurrentMp = human.MaximumMp; } else { human.CurrentMp += 500; } player.Inventory.RemoveItem(item); } catch { return(false); } return(true); }
public void LoadInEntity(YiObj obj) { Entities.AddOrUpdate(obj.UniqueId, obj); switch (obj) { case Npc npc: AddNpc(obj); break; case DynamicNpc npc: AddNpc(obj); break; case Monster monster: AddMob(obj); break; case FloorItem item: AddItem(obj); break; } ScreenSystem.Create(obj); }
public void Add(YiObj human) { if (Members.Contains(human.UniqueId)) { return; } Members.Add(human.UniqueId); human.Guild = this; human.GuildRank = GuildRanks.Member; if (human is Player player) { player.Send(MsgSyndicateSpawn.Create(player)); Message.SendTo(player, $"{player.Name} has joined our guild!", MsgTextType.Guild); foreach (var guild in Allies) { player.Send(MsgSyndicate.Create(guild.UniqueId, GuildRequest.SetAlly)); } foreach (var guild in Enemies) { player.Send(MsgSyndicate.Create(guild.UniqueId, GuildRequest.SetEnemy)); } } ScreenSystem.Send(human, MsgSpawn.Create(human as Player), true); }
public string ToString(YiObj req) { var moneyAccess = ""; var itemAccess = ""; if (Members.ContainsKey(req.UniqueId)) { if (Members[req.UniqueId].HasFlag(StorageAccess.MoneyAdd)) { moneyAccess += "R"; } if (Members[req.UniqueId].HasFlag(StorageAccess.MoneyTake)) { moneyAccess += "W"; } if (Members[req.UniqueId].HasFlag(StorageAccess.ItemAdd)) { itemAccess += "R"; } if (Members[req.UniqueId].HasFlag(StorageAccess.ItemTake)) { itemAccess += "W"; } } return($"{StorageId.ToString("00000")} {StorageName.Size32(' ')} {GetOwner().Name.Replace("\0", "").Size16(' ')} Money: {moneyAccess} Items: {itemAccess}"); }
public Trade(YiObj player, YiObj target) { Owner = player; Partner = target; OwnerItems = new Dictionary <int, Item>(); PartnerItems = new Dictionary <int, Item>(); }
public static bool InAttackRange(Monster monster, YiObj currentTarget) { if (currentTarget == null) { return(false); } return(GetDistance(monster, currentTarget) <= monster.AttackRange); }
private void RemoveItem(YiObj obj) { if (obj.Location.X <= 0 || obj.Location.X >= Width - 1 || obj.Location.Y <= 0 || obj.Location.Y >= Height - 1) { return; } MapAccess.MapData[Id].ItemLayer[(obj.Location.X + 1) * Width + obj.Location.Y + 1] = true; }
public void RemoveMob(YiObj obj) { if (obj.Location.X <= 0 || obj.Location.X >= Width - 1 || obj.Location.Y <= 0 || obj.Location.Y >= Height - 1) { return; } MapAccess.MapData[Id].MobLayer[(obj.Location.X + 1) * Width + obj.Location.Y + 1] = true; }
private void AddNpc(YiObj obj) { if (obj.Location.X <= 0 || obj.Location.X >= Width - 1 || obj.Location.Y <= 0 || obj.Location.Y >= Height - 1) { return; } MapAccess.MapData[Id].GroundLayer[(obj.Location.X + 1) * Width + obj.Location.Y + 1] = false; }
public Buff(YiObj owner, SkillId id, TimeSpan duration) { SkillId = id; Duration = duration; StartTime = DateTime.UtcNow; EndTime = DateTime.UtcNow.Add(Duration); RemoveJob = YiScheduler.Instance.DoReturn(Duration, () => BuffSystem.RemoveBuff(owner, this)); }
public static void SendTo(YiObj player, string message, MsgTextType action) { if (string.IsNullOrEmpty(message)) { return; } player.GetMessage(Constants.System, player.Name, message, action); }
public static void ExecuteAction(Monster target, YiObj attacker) { using (var db = new SquigglyContext()) { var cqaction = db.cq_action.Find((long)target.CQAction); Process(target, attacker, cqaction, db); } }