public void ShowTo(User invoker, VisibleObject target = null, bool runCheck = true) { // Either we must have an associate already known to us, one must be passed, or we must have a script defined if (Associate == null && target == null && Script == null) { Logger.ErrorFormat("DialogSequence {0} has no known associate or script...?", Name); // Need better error handling here return; } if (PreDisplayCallback != null && runCheck) { var invocation = new ScriptInvocation(); invocation.Function = PreDisplayCallback; invocation.Invoker = invoker; invocation.Associate = target == null ? Associate : target; if (Script != null) invocation.Script = Script; if (invocation.Execute()) Dialogs.First().ShowTo(invoker, target); } else { Dialogs.First().ShowTo(invoker, target); } }
public override void OnClick(User invoker) { if (!Ready) OnSpawn(); if (Script != null) { Script.ExecuteScriptableFunction("OnClick", new HybrasylUser(invoker)); } }
/// <summary> /// Check to see if a specified user can equip an item. Returns a boolean indicating whether /// the item can be equipped and if not, sets the message reference to contain an appropriate /// message to be sent to the user. /// </summary> /// <param name="userobj">User object to check for meeting this item's requirements.</param> /// <param name="message">A reference that will be used in the case of failure to set an appropriate error message.</param> /// <returns></returns> public bool CheckRequirements(User userobj, out String message) { // We check a variety of conditions and return the first failure. message = string.Empty; // Check class if (userobj.Class != Class && Class != Enums.Class.Peasant) { message = userobj.Class == Enums.Class.Peasant ? "Perhaps one day you'll know how to use such things." : "Your path has forbidden itself from using such vulgar implements."; } // Check level / AB if (userobj.Level < Level || (Ability != 0 && userobj.Ability < Ability)) { message = "You can't even lift it above your head, let alone wield it!"; } // Check gender if (Sex != 0 && (Sex != userobj.Sex)) { message = "You conclude this garment would look much better on someone else."; } // Check if user is equipping a shield while holding a two-handed weapon if (EquipmentSlot == ClientItemSlots.Shield && userobj.Equipment.Weapon != null && userobj.Equipment.Weapon.WeaponType == Enums.WeaponType.TwoHanded) { message = "You can't equip a shield with a two-handed weapon."; } // Check if user is equipping a two-handed weapon while holding a shield if (EquipmentSlot == ClientItemSlots.Weapon && WeaponType == Enums.WeaponType.TwoHanded && userobj.Equipment.Shield != null) { message = "You can't equip a two-handed weapon with a shield."; } // Check mastership if (Master && !userobj.IsMaster) { message = "Perhaps one day you'll know how to use such things."; } if (UniqueEquipped && userobj.Equipment.Find(Name) != null) { message = "You can't equip more than one of these."; } return message == string.Empty; }
public UserGroup(User founder) { Members = new List<User>(); ClassCount = new Dictionary<Class, uint>(); foreach (var cl in Enum.GetValues(typeof(Class)).Cast<Class>()) { ClassCount[cl] = 0; } Logger.InfoFormat("Creating new group with {0} as founder.", founder.Name); // Distribute full experience to everyone with a bonus if a member of each // class is present. ExperienceDistributionFunc = Distribution_AllClassBonus; Add(founder); CreatedOn = DateTime.Now; }
// Group-related functions and accessors public bool Add(User user) { // You can only join a group if you're not already a member in another group. // Check this condition and notify the invitee and existing group members if // there's an issue. if (user.Grouped) { user.SendMessage("You're already in a group.", MessageTypes.SYSTEM); foreach (var member in Members) { member.SendMessage(String.Format("{0} is in another group.", user.Name), MessageTypes.SYSTEM); } // If this fails when the group only contains one other person, the group should be abandoned. if (Count == 1) { Remove(Members[0]); } return false; } // Send a message to notify everyone else that someone's joined. foreach (var member in Members) { member.SendMessage(user.Name + " has joined your group.", MessageTypes.SYSTEM); } Members.Add(user); user.Group = this; ClassCount[user.Class]++; MaxMembers = (uint)Math.Max(MaxMembers, Members.Count); // Send a distinct message to the new user. user.SendMessage("You've joined a group.", MessageTypes.SYSTEM); return true; }
public HybrasylUser(User user) { User = user; World = new HybrasylWorld(user.World); Map = new HybrasylMap(user.Map); }
public void RunCallback(User target, VisibleObject associate) { ActiveDialog.RunCallback(target, associate); }
public override void ShowTo(User invoker, VisibleObject invokee) { Logger.DebugFormat("active for input dialog: {0}, {1}, {2}", TopCaption, InputLength, BottomCaption); var dialogPacket = base.GenerateBasePacket(invoker, invokee); dialogPacket.WriteString8(TopCaption); dialogPacket.WriteByte((byte)InputLength); dialogPacket.WriteString8(BottomCaption); invoker.Enqueue(dialogPacket); RunCallback(invoker, invokee); }
public override void ShowTo(User invoker, VisibleObject invokee) { var dialogPacket = base.GenerateBasePacket(invoker, invokee); invoker.Enqueue(dialogPacket); RunCallback(invoker, invokee); }
public virtual void ShowTo(User invoker, VisibleObject invokee) { }
public void RunCallback(User target, VisibleObject associateOverride = null) { if (CallbackFunction != null) { VisibleObject associate = associateOverride == null ? Sequence.Associate as VisibleObject : associateOverride; var invocation = new ScriptInvocation(); invocation.Invoker = target; invocation.Associate = associate; invocation.Function = CallbackFunction; associate.Script.ExecuteFunction(invocation); } }
public override void OnClick(User invoker) { // Return a profile packet (0x34) to the user who clicked. // This packet format is: // uint32 id, 18 equipment slots (uint16 sprite, byte color), byte namelength, string name, // byte nation, byte titlelength, string title, byte grouping, byte guildranklength, string guildrank, // byte classnamelength, string classname, byte guildnamelength, byte guildname, byte numLegendMarks (lame!), // numLegendMarks[byte icon, byte color, byte marklength, string mark] // This packet can also contain a portrait and profile text but we haven't even remotely implemented it yet. var profilePacket = new ServerPacket(0x34); profilePacket.WriteUInt32(Id); // Equipment block is 3 bytes per slot and contains 54 bytes (18 slots), which I believe is sprite+color // EXCEPT WHEN IT'S MUNGED IN SOME OBSCURE WAY BECAUSE REASONS foreach (var tuple in Equipment.GetEquipmentDisplayList()) { profilePacket.WriteUInt16(tuple.Item1); profilePacket.WriteByte(tuple.Item2); } profilePacket.WriteByte((byte)GroupStatus); profilePacket.WriteString8(Name); profilePacket.WriteByte((byte)Citizenship.flag); // This should pull from town / nation profilePacket.WriteString8(Title); profilePacket.WriteByte((byte)(Grouping ? 1 : 0)); profilePacket.WriteString8(GuildRank); profilePacket.WriteString8(Hybrasyl.Constants.REVERSE_CLASSES[(int)Class]); profilePacket.WriteString8(Guild); profilePacket.WriteByte((byte)LegendMarks.Count); foreach (var mark in LegendMarks) { profilePacket.WriteByte((byte)mark.icon); profilePacket.WriteByte((byte)mark.color); profilePacket.WriteString8(mark.prefix); profilePacket.WriteString8(mark.text); } profilePacket.WriteUInt16((ushort)(PortraitData.Length + ProfileText.Length + 4)); profilePacket.WriteUInt16((ushort)PortraitData.Length); profilePacket.Write(PortraitData); profilePacket.WriteString16(ProfileText); invoker.Enqueue(profilePacket); }
/// <summary> /// Send an exchange initiation request to the client (open exchange window) /// </summary> /// <param name="requestor">The user requesting the trade</param> public void SendExchangeInitiation(User requestor) { if (Status.HasFlag(PlayerStatus.InExchange) && requestor.Status.HasFlag(PlayerStatus.InExchange)) { var x42 = new ServerPacket(0x42); x42.WriteByte(0); // show exchange window x42.WriteUInt32(requestor.Id); x42.WriteString8(requestor.Name); Enqueue(x42); } }
public bool Use(User target) { Logger.DebugFormat("warp: {0} from {1} ({2},{3}) to {4} ({5}, {6}", target.Name, SourceMap.Name, X, Y, DestinationMapName, DestinationX, DestinationY); switch (WarpType) { case WarpType.Map: Map map; if (SourceMap.World.MapCatalog.TryGetValue(DestinationMapName, out map)) { Thread.Sleep(250); target.Teleport(map.Id, DestinationX, DestinationY); } Logger.ErrorFormat("User {0} tried to warp to nonexistent map {1} from {2}: {3},{4}", target.Name, DestinationMapName, SourceMap.Name, X, Y); break; case WarpType.WorldMap: WorldMap wmap; if (SourceMap.World.WorldMaps.TryGetValue(DestinationMapName, out wmap)) { SourceMap.Remove(target); target.SendWorldMap(wmap); SourceMap.World.Maps[Hybrasyl.Constants.LAG_MAP].Insert(target, 5, 5, false); } Logger.ErrorFormat("User {0} tried to warp to nonexistent worldmap {1} from {2}: {3},{4}", target.Name, DestinationMapName, SourceMap.Name, X, Y); break; } return false; }
public void Invoke(User trigger) { /* try { World.ScriptMethod(ScriptName, this, trigger); } catch { trigger.SendMessage("It doesn't work.", 3); } * */ trigger.SendMessage("Not implemented.", 3); }
private void MerchantMenuHandler_SellItemConfirmation(User user, Merchant merchant, ClientPacket packet) { packet.ReadByte(); byte slot = packet.ReadByte(); byte quantity = packet.ReadByte(); var item = user.Inventory[slot]; if (item == null) return; if (!merchant.Inventory.ContainsKey(item.Name)) { user.ShowMerchantGoBack(merchant, "I do not want that item.", MerchantMenuItem.SellItemMenu); return; } if (item.Count < quantity) { user.ShowMerchantGoBack(merchant, "You don't have that many to sell.", MerchantMenuItem.SellItemMenu); return; } uint profit = (uint) (Math.Round(item.Value*0.50)*quantity); if (item.Stackable && quantity < item.Count) user.DecreaseItem(slot, quantity); else user.RemoveItem(slot); user.AddGold(profit); merchant.DisplayPursuits(user); }
public void AddUser(User userobj) { Users[userobj.Name] = userobj; }
private void PacketHandler_0x10_ClientJoin(Object obj, ClientPacket packet) { var connectionId = (long) obj; var seed = packet.ReadByte(); var keyLength = packet.ReadByte(); var key = packet.Read(keyLength); var name = packet.ReadString8(); var id = packet.ReadUInt32(); var redirect = ExpectedConnections[id]; if (redirect.Matches(name, key, seed)) { ((IDictionary) ExpectedConnections).Remove(id); if (PlayerExists(name)) { var user = new User(this, connectionId, name); user.SetEncryptionParameters(key, seed, name); user.LoadDataFromEntityFramework(true); user.UpdateLoginTime(); user.UpdateAttributes(StatUpdateFlags.Full); Logger.DebugFormat("Elapsed time since login: {0}", user.SinceLastLogin); if (user.Citizenship.spawn_points.Count != 0 && user.SinceLastLogin > Hybrasyl.Constants.NATION_SPAWN_TIMEOUT) { Insert(user); var spawnpoint = user.Citizenship.spawn_points.First(); user.Teleport((ushort) spawnpoint.map_id, (byte) spawnpoint.map_x, (byte) spawnpoint.map_y); } else if (user.MapId != null && Maps.ContainsKey(user.MapId)) { Insert(user); user.Teleport(user.MapId, (byte) user.MapX, (byte) user.MapY); } else { // Handle any weird cases where a map someone exited on was deleted, etc // This "default" of Mileth should be set somewhere else Insert(user); user.Teleport((ushort) 500, (byte) 50, (byte) 50); } Logger.DebugFormat("Adding {0} to hash", user.Name); AddUser(user); ActiveUsers[connectionId] = user; ActiveUsersByName[user.Name] = connectionId; Logger.InfoFormat("cid {0}: {1} entering world", connectionId, user.Name); } } }
public ServerPacket GenerateBasePacket(User invoker, VisibleObject invokee) { byte color = 0; ushort sprite = 0; byte objType = 0; var dialogPacket = new ServerPacket(0x30); dialogPacket.WriteByte((byte)(DialogType)); if (invokee is Creature) { var creature = (Creature) invokee; sprite = (ushort) (0x4000 + creature.Sprite); objType = 1; } else if (invokee is Item) { var item = (Item) invokee; objType = 2; sprite = (ushort)(0x8000 + item.Sprite); color = item.Color; } else if (invokee is Reactor) { objType = 4; } if (DisplaySprite != 0) sprite = DisplaySprite; dialogPacket.WriteByte(objType); dialogPacket.WriteUInt32(invokee.Id); dialogPacket.WriteByte(0); // Unknown value Logger.DebugFormat("Sprite is {0}", sprite); dialogPacket.WriteUInt16(sprite); dialogPacket.WriteByte(color); dialogPacket.WriteByte(0); // Unknown value dialogPacket.WriteUInt16(sprite); dialogPacket.WriteByte(color); Logger.DebugFormat("Dialog group id {0}, index {1}", Sequence.Id, Index); dialogPacket.WriteUInt16((ushort)Sequence.Id); dialogPacket.WriteUInt16((ushort)Index); dialogPacket.WriteBoolean(HasPrevDialog()); dialogPacket.WriteBoolean(HasNextDialog()); dialogPacket.WriteByte(0); dialogPacket.WriteString8(invokee.Name); if (DisplayText != null) { dialogPacket.WriteString16(DisplayText); } return dialogPacket; }
private void MerchantMenuHandler_MainMenu(User user, Merchant merchant, ClientPacket packet) { merchant.DisplayPursuits(user); }
public override void ShowTo(User invoker, VisibleObject invokee) { return; }
private void MerchantMenuHandler_SellItemMenu(User user, Merchant merchant, ClientPacket packet) { user.ShowSellMenu(merchant); }
public override void ShowTo(User invoker, VisibleObject invokee) { var dialogPacket = base.GenerateBasePacket(invoker, invokee); if (Options.Count > 0) { dialogPacket.WriteByte((byte)Options.Count); foreach (var option in Options) { dialogPacket.WriteString8(option.OptionText); } invoker.Enqueue(dialogPacket); RunCallback(invoker, invokee); } }
private void MerchantMenuHandler_BuyItem(User user, Merchant merchant, ClientPacket packet) { string name = packet.ReadString8(); if (!merchant.Inventory.ContainsKey(name)) { user.ShowMerchantGoBack(merchant, "I do not sell that item.", MerchantMenuItem.BuyItemMenu); return; } var template = merchant.Inventory[name]; if (template.Stackable) { user.ShowBuyMenuQuantity(merchant, name); return; } if (user.Gold < template.value) { user.ShowMerchantGoBack(merchant, "You do not have enough gold.", MerchantMenuItem.BuyItemMenu); return; } if (user.CurrentWeight + template.weight > user.MaximumWeight) { user.ShowMerchantGoBack(merchant, "That item is too heavy for you to carry.", MerchantMenuItem.BuyItemMenu); return; } if (user.Inventory.IsFull) { user.ShowMerchantGoBack(merchant, "You cannot carry any more items.", MerchantMenuItem.BuyItemMenu); return; } user.RemoveGold((uint) template.value); var item = CreateItem(template.id); Insert(item); user.AddItem(item); user.UpdateAttributes(StatUpdateFlags.Experience); user.ShowBuyMenu(merchant); }
public DialogState(User user) { Associate = null; ActiveDialog = null; ActiveDialogSequence = null; User = user; }
private void MerchantMenuHandler_BuyItemWithQuantity(User user, Merchant merchant, ClientPacket packet) { string name = packet.ReadString8(); string qStr = packet.ReadString8(); if (!merchant.Inventory.ContainsKey(name)) { user.ShowMerchantGoBack(merchant, "I do not sell that item.", MerchantMenuItem.BuyItemMenu); return; } var template = merchant.Inventory[name]; if (!template.Stackable) return; int quantity; if (!int.TryParse(qStr, out quantity) || quantity < 1) { user.ShowBuyMenuQuantity(merchant, name); return; } uint cost = (uint) (template.value*quantity); if (user.Gold < cost) { user.ShowMerchantGoBack(merchant, "You do not have enough gold.", MerchantMenuItem.BuyItemMenu); return; } if (quantity > template.max_stack) { user.ShowMerchantGoBack(merchant, string.Format("You cannot hold that many {0}.", name), MerchantMenuItem.BuyItemMenu); return; } if (user.Inventory.Contains(name)) { byte slot = user.Inventory.SlotOf(name); if (user.Inventory[slot].Count + quantity > template.max_stack) { user.ShowMerchantGoBack(merchant, string.Format("You cannot hold that many {0}.", name), MerchantMenuItem.BuyItemMenu); return; } user.IncreaseItem(slot, quantity); } else { if (user.Inventory.IsFull) { user.ShowMerchantGoBack(merchant, "You cannot carry any more items.", MerchantMenuItem.BuyItemMenu); return; } var item = CreateItem(template.id, quantity); Insert(item); user.AddItem(item); } user.RemoveGold(cost); user.UpdateAttributes(StatUpdateFlags.Experience); user.ShowBuyMenu(merchant); }
private void MerchantMenuHandler_SellItem(User user, Merchant merchant, ClientPacket packet) { byte slot = packet.ReadByte(); var item = user.Inventory[slot]; if (item == null) return; if (!merchant.Inventory.ContainsKey(item.Name)) { user.ShowMerchantGoBack(merchant, "I do not want that item.", MerchantMenuItem.SellItemMenu); return; } if (item.Stackable && item.Count > 1) { user.ShowSellQuantity(merchant, slot); return; } user.ShowSellConfirm(merchant, slot, 1); }
private void MerchantMenuHandler_SellItemWithQuantity(User user, Merchant merchant, ClientPacket packet) { packet.ReadByte(); byte slot = packet.ReadByte(); string qStr = packet.ReadString8(); int quantity; if (!int.TryParse(qStr, out quantity) || quantity < 1) { user.ShowSellQuantity(merchant, slot); return; } var item = user.Inventory[slot]; if (item == null || !item.Stackable) return; if (!merchant.Inventory.ContainsKey(item.Name)) { user.ShowMerchantGoBack(merchant, "I do not want that item.", MerchantMenuItem.SellItemMenu); return; } if (item.Count < quantity) { user.ShowMerchantGoBack(merchant, "You don't have that many to sell.", MerchantMenuItem.SellItemMenu); return; } user.ShowSellConfirm(merchant, slot, quantity); }
private void PacketHandler_0x04_CreateB(Client client, ClientPacket packet) { if (string.IsNullOrEmpty(client.NewCharacterName) || string.IsNullOrEmpty(client.NewCharacterPassword)) return; var hairStyle = packet.ReadByte(); var sex = packet.ReadByte(); var hairColor = packet.ReadByte(); if (hairStyle < 1) hairStyle = 1; if (hairStyle > 17) hairStyle = 17; if (hairColor > 13) hairColor = 13; if (sex < 1) sex = 1; if (sex > 2) sex = 2; if (!Game.World.PlayerExists(client.NewCharacterName)) { var newPlayer = new User(); newPlayer.Name = client.NewCharacterName; newPlayer.Sex = (Sex) sex; newPlayer.Location.Direction = Direction.South; newPlayer.Location.MapId = 136; newPlayer.Location.X = 10; newPlayer.Location.Y = 10; newPlayer.HairColor = hairColor; newPlayer.HairStyle = hairStyle; newPlayer.Class = Class.Peasant; newPlayer.Level = 1; newPlayer.Experience = 1; newPlayer.Level = 1; newPlayer.Experience = 0; newPlayer.AbilityExp = 0; newPlayer.Gold = 0; newPlayer.Ability = 0; newPlayer.Hp = 50; newPlayer.Mp = 50; newPlayer.BaseHp = 50; newPlayer.BaseMp = 50; newPlayer.BaseStr = 3; newPlayer.BaseInt = 3; newPlayer.BaseWis = 3; newPlayer.BaseCon = 3; newPlayer.BaseDex = 3; newPlayer.Login.CreatedTime = DateTime.Now; newPlayer.Password.Hash = client.NewCharacterPassword; newPlayer.Password.LastChanged = DateTime.Now; newPlayer.Password.LastChangedFrom = ((IPEndPoint) client.Socket.RemoteEndPoint).Address.ToString(); IDatabase cache = World.DatastoreConnection.GetDatabase(); var myPerson = JsonConvert.SerializeObject(newPlayer); cache.Set(String.Format("{0}:{1}", User.DatastorePrefix, newPlayer.Name), myPerson); // Logger.ErrorFormat("Error saving new player!"); // Logger.ErrorFormat(e.ToString()); // client.LoginMessage("Unknown error. Contact [email protected]", 3); // } client.LoginMessage("\0", 0); } }
/** * Give the full quantity of a resource to each of the group members, +10% bonus * if there's at least one representative from each class. */ private Dictionary<uint, int> Distribution_AllClassBonus(User source, int full) { // Check to see if at least one representative from each class is in the group. if (ContainsAllClasses()) { full = (int)(full * 1.10); } return Distribution_Full(source, full); }