void RecvUpdateVelocityAndPosition(IIPSocket conn, BitStream r) { var mapEntityIndex = r.ReadMapEntityIndex(); DynamicEntity dynamicEntity = null; // Grab the DynamicEntity // The map can be null if the spatial updates come very early (which isn't uncommon) if (Map != null) dynamicEntity = _objGrabber.GetDynamicEntity<DynamicEntity>(mapEntityIndex); // Deserialize if (dynamicEntity != null) { // Read the value into the DynamicEntity dynamicEntity.DeserializePositionAndVelocity(r); } else { // DynamicEntity was null, so just flush the values from the reader DynamicEntity.FlushPositionAndVelocity(r); } }
void RecvStartShopping(IIPSocket conn, BitStream r) { var entityIndex = r.ReadMapEntityIndex(); User user; Map map; if (!TryGetMap(conn, out user, out map)) return; if (user.IsPeerTrading) return; var shopkeeper = map.GetDynamicEntity<Character>(entityIndex); if (shopkeeper == null) return; user.ShoppingState.TryStartShopping(shopkeeper); }
void RecvUseWorld(IIPSocket conn, BitStream r) { var useEntityIndex = r.ReadMapEntityIndex(); // Get the map and user User user; Map map; if (!TryGetMap(conn, out user, out map)) return; if (user.IsPeerTrading) return; if (!user.IsAlive) { const string errmsg = "User `{0}` tried to use world entity while dead."; if (log.IsInfoEnabled) log.InfoFormat(errmsg, user); return; } // Grab the DynamicEntity to use var useEntity = map.GetDynamicEntity(useEntityIndex); if (useEntity == null) { const string errmsg = "UseEntity received but usedEntityIndex `{0}` is not a valid DynamicEntity."; Debug.Fail(string.Format(errmsg, useEntityIndex)); if (log.IsErrorEnabled) log.ErrorFormat(errmsg, useEntityIndex); return; } // Ensure the used DynamicEntity is even usable var asUsable = useEntity as IUsableEntity; if (asUsable == null) { const string errmsg = "UseEntity received but useByIndex `{0}` refers to DynamicEntity `{1}` which does " + "not implement IUsableEntity."; Debug.Fail(string.Format(errmsg, useEntityIndex, useEntity)); if (log.IsErrorEnabled) log.WarnFormat(errmsg, useEntityIndex, useEntity); return; } // Use it if (asUsable.Use(user)) { // Notify everyone in the map it was used if (asUsable.NotifyClientsOfUsage) { using (var pw = ServerPacket.UseEntity(useEntity.MapEntityIndex, user.MapEntityIndex)) { map.Send(pw, ServerMessageType.Map); } } } }
void RecvAttack(IIPSocket conn, BitStream r) { User user; MapEntityIndex? targetIndex = null; var hasTarget = r.ReadBool(); if (hasTarget) targetIndex = r.ReadMapEntityIndex(); if ((user = TryGetUser(conn)) != null) { if (user.IsPeerTrading) return; user.Attack(GetTargetCharacter(user, targetIndex)); } }
void RecvRequestMapEntityIndex(IIPSocket conn, BitStream r) { var index = r.ReadMapEntityIndex(); // Get the user and their map User user; if ((user = TryGetUser(conn)) == null) return; Map map; if (!TryGetMap(user, out map)) return; // Get the DynamicEntity var de = map.GetDynamicEntity(index); if (de == null) { // The DynamicEntity for the index was null, so tell the client to delete whatever is at that index using (var pw = ServerPacket.RemoveDynamicEntity(index)) { conn.Send(pw, ServerMessageType.Map); } } else { // A DynamicEntity does exist at that index, so tell the client to create it using (var pw = ServerPacket.CreateDynamicEntity(de)) { conn.Send(pw, ServerMessageType.Map); } } }
void RecvSkillStopCasting_ToMap(IIPSocket conn, BitStream r) { var casterEntityIndex = r.ReadMapEntityIndex(); // Get the entity var casterEntity = _objGrabber.GetDynamicEntity<Character>(casterEntityIndex); if (casterEntity == null) return; // Set the entity as not casting casterEntity.IsCastingSkill = false; }
void RecvStartChatDialog(IIPSocket conn, BitStream r) { #pragma warning disable 168 var npcIndex = r.ReadMapEntityIndex(); #pragma warning restore 168 var dialogIndex = r.ReadNPCChatDialogID(); var dialog = ClientNPCChatManager.Instance[dialogIndex]; GameplayScreen.ChatDialogForm.StartDialog(dialog); }
void RecvSynchronizeDynamicEntity(IIPSocket conn, BitStream r) { var mapEntityIndex = r.ReadMapEntityIndex(); DynamicEntity e = Map.GetDynamicEntity(mapEntityIndex); e.Deserialize(r); }
void RecvEmote(IIPSocket conn, BitStream r) { var mapEntityIndex = r.ReadMapEntityIndex(); var emoticon = r.ReadEnum<Emoticon>(); var entity = Map.GetDynamicEntity(mapEntityIndex); if (entity == null) return; EmoticonDisplayManager.Instance.Add(entity, emoticon, GetTime()); }
void RecvChatSay(IIPSocket conn, BitStream r) { var name = r.ReadString(GameData.MaxServerSayNameLength); var mapEntityIndex = r.ReadMapEntityIndex(); var text = r.ReadString(GameData.MaxServerSayLength); var chatText = CreateChatText(name, text); GameplayScreen.AppendToChatOutput(chatText); var entity = Map.GetDynamicEntity(mapEntityIndex); if (entity == null) return; GameplayScreen.AddChatBubble(entity, text); }
void RecvCreateDynamicEntity(IIPSocket conn, BitStream r) { var mapEntityIndex = r.ReadMapEntityIndex(); var dynamicEntity = _dynamicEntityFactory.Read(r); Map.AddDynamicEntity(dynamicEntity, mapEntityIndex); var character = dynamicEntity as Character; if (character != null) { // HACK: Having to call this .Initialize() and pass these parameters seems hacky character.Initialize(Map, GameplayScreen.SkeletonManager); } if (log.IsInfoEnabled) log.InfoFormat("Created DynamicEntity with index `{0}` of type `{1}`", dynamicEntity.MapEntityIndex, dynamicEntity.GetType()); }
void RecvCharDamage(IIPSocket conn, BitStream r) { var mapCharIndex = r.ReadMapEntityIndex(); var damage = r.ReadInt(); var chr = _objGrabber.GetDynamicEntity<Character>(mapCharIndex); if (chr == null) return; GameplayScreen.DamageTextPool.Create(damage, chr, GetTime()); }
void RecvCharAttack(IIPSocket conn, BitStream r) { // Read the values var attackerID = r.ReadMapEntityIndex(); MapEntityIndex? attackedID; if (r.ReadBool()) attackedID = r.ReadMapEntityIndex(); else attackedID = null; ActionDisplayID? actionDisplayIDNullable; if (r.ReadBool()) actionDisplayIDNullable = r.ReadActionDisplayID(); else actionDisplayIDNullable = null; // Get the object references using the IDs provided var attacker = _objGrabber.GetDynamicEntity<Character>(attackerID); if (attacker == null) return; DynamicEntity attacked = attackedID.HasValue ? Map.GetDynamicEntity(attackedID.Value) : null; // Use the default ActionDisplayID if we were provided with a null value ActionDisplayID actionDisplayID = !actionDisplayIDNullable.HasValue ? GameData.DefaultActionDisplayID : actionDisplayIDNullable.Value; // Get the ActionDisplay to use and, if valid, execute it var actionDisplay = ActionDisplayScripts.ActionDisplays[actionDisplayID]; if (actionDisplay != null) actionDisplay.Execute(Map, attacker, attacked); }
void RecvUseEntity(IIPSocket conn, BitStream r) { var usedEntityIndex = r.ReadMapEntityIndex(); var usedByIndex = r.ReadMapEntityIndex(); // Grab the used DynamicEntity var usedEntity = _objGrabber.GetDynamicEntity<IUsableEntity>(usedEntityIndex); if (usedEntity == null) return; // Grab the one who used this DynamicEntity (we can still use it, we'll just pass null) var usedBy = Map.GetDynamicEntity(usedByIndex); if (usedBy == null) return; // Use it usedEntity.Use(usedBy); }
void RecvCreateActionDisplayAtEntity(IIPSocket conn, BitStream r) { ActionDisplayID actionDisplayId = r.ReadActionDisplayID(); MapEntityIndex sourceEntityIndex = r.ReadMapEntityIndex(); bool hasTarget = r.ReadBool(); MapEntityIndex? targetEntityIndex = hasTarget ? r.ReadMapEntityIndex() : (MapEntityIndex?)null; // Get the entities var sourceEntity = _objGrabber.GetDynamicEntity<Character>(sourceEntityIndex); if (sourceEntity == null) return; var targetEntity = targetEntityIndex.HasValue ? _objGrabber.GetDynamicEntity<Character>(targetEntityIndex.Value) : null; // Get the action display var ad = ActionDisplayScripts.ActionDisplays[actionDisplayId]; if (ad == null) return; // Create ad.Execute(Map, sourceEntity, targetEntity); }
void RecvNotifyLevel(IIPSocket conn, BitStream r) { var mapCharIndex = r.ReadMapEntityIndex(); var chr = _objGrabber.GetDynamicEntity<Character>(mapCharIndex); if (chr == null) return; var message = GameMessageCollection.CurrentLanguage.GetMessage(GameMessage.CombatSelfLevelUp, UserInfo.Level.ToString()); if (chr == World.UserChar) GameplayScreen.InfoBox.Add(message); }
void RecvSkillStartCasting_ToMap(IIPSocket conn, BitStream r) { var casterEntityIndex = r.ReadMapEntityIndex(); var skillType = r.ReadEnum<SkillType>(); // Get the SkillInfo for the skill being used var skillInfo = _objGrabber.GetSkillInfo(skillType); if (skillInfo == null) return; // Get the entity var casterEntity = _objGrabber.GetDynamicEntity<Character>(casterEntityIndex); if (casterEntity == null) return; // If an ActionDisplay is available for this skill, display it if (skillInfo.StartCastingActionDisplay.HasValue) { var ad = ActionDisplayScripts.ActionDisplays[skillInfo.StartCastingActionDisplay.Value]; if (ad != null) { casterEntity.IsCastingSkill = true; ad.Execute(Map, casterEntity, null); } } }
void RecvPlaySoundAtEntity(IIPSocket conn, BitStream r) { var soundID = r.ReadSoundID(); var index = r.ReadMapEntityIndex(); var entity = Map.GetDynamicEntity(index); if (entity == null) return; if (!SoundManager.Play(soundID, entity)) LogFailPlaySound(soundID); }
void RecvSkillUse(IIPSocket conn, BitStream r) { var casterEntityIndex = r.ReadMapEntityIndex(); var hasTarget = r.ReadBool(); MapEntityIndex? targetEntityIndex = null; if (hasTarget) targetEntityIndex = r.ReadMapEntityIndex(); var skillType = r.ReadEnum<SkillType>(); var casterEntity = _objGrabber.GetDynamicEntity<CharacterEntity>(casterEntityIndex); CharacterEntity targetEntity = null; if (targetEntityIndex.HasValue) targetEntity = _objGrabber.GetDynamicEntity<CharacterEntity>(targetEntityIndex.Value); if (casterEntity == null) return; // Get the SkillInfo for the skill being used var skillInfo = _objGrabber.GetSkillInfo(skillType); if (skillInfo == null) return; // If an ActionDisplay is available for this skill, display it if (skillInfo.CastActionDisplay.HasValue) { var ad = ActionDisplayScripts.ActionDisplays[skillInfo.CastActionDisplay.Value]; if (ad != null) ad.Execute(Map, casterEntity, targetEntity); } }
void RecvRemoveDynamicEntity(IIPSocket conn, BitStream r) { var mapEntityIndex = r.ReadMapEntityIndex(); var dynamicEntity = Map.GetDynamicEntity(mapEntityIndex); if (dynamicEntity == null) return; Map.RemoveEntity(dynamicEntity); if (log.IsInfoEnabled) log.InfoFormat("Removed DynamicEntity with index `{0}`", mapEntityIndex); dynamicEntity.Dispose(); }
void RecvStartQuestChatDialog(IIPSocket conn, BitStream r) { var npcIndex = r.ReadMapEntityIndex(); // Available quests var numAvailableQuests = r.ReadByte(); var availableQuests = new QuestID[numAvailableQuests]; for (var i = 0; i < availableQuests.Length; i++) { availableQuests[i] = r.ReadQuestID(); } // Quests that can be turned in var numTurnInQuests = r.ReadByte(); var turnInQuests = new QuestID[numTurnInQuests]; for (var i = 0; i < turnInQuests.Length; i++) { turnInQuests[i] = r.ReadQuestID(); } // For the quests that are available, make sure we set their status to not being able to be turned in (just in case) foreach (var id in availableQuests) { UserInfo.HasFinishQuestRequirements.SetRequirementsStatus(id, false); } // For the quests that were marked as being able to turn in, set their status to being able to be finished foreach (var id in turnInQuests) { UserInfo.HasFinishQuestRequirements.SetRequirementsStatus(id, true); } // Grab the descriptions for both the available quests and quests we can turn in var qds = availableQuests.Concat(turnInQuests).Distinct().Select(x => _questDescriptions.GetOrDefault(x)).ToArray(); // Display the form GameplayScreen.AvailableQuestsForm.Display(qds, npcIndex); }
void RecvSetCharacterMPPercent(IIPSocket conn, BitStream r) { var mapEntityIndex = r.ReadMapEntityIndex(); var percent = r.ReadByte(); var character = _objGrabber.GetDynamicEntity<Character>(mapEntityIndex); if (character == null) return; character.MPPercent = percent; }
void RecvPickupItem(IIPSocket conn, BitStream r) { var mapEntityIndex = r.ReadMapEntityIndex(); User user; Map map; if (!TryGetMap(conn, out user, out map)) return; // Get the item var item = map.GetDynamicEntity<ItemEntityBase>(mapEntityIndex); if (item == null) return; // Ensure the distance is valid if (!GameData.IsValidPickupDistance(user, item)) { const string errmsg = "User `{0}` failed to pick up item `{1}` - distance was too great."; if (log.IsInfoEnabled) log.InfoFormat(errmsg, user, item); return; } // Pick it up item.Pickup(user); }
void RecvSetCharacterPaperDoll(IIPSocket conn, BitStream r) { var mapEntityIndex = r.ReadMapEntityIndex(); var count = r.ReadByte(); var layers = new string[count]; for (var i = 0; i < layers.Length; i++) { layers[i] = r.ReadString(); } var character = _objGrabber.GetDynamicEntity<Character>(mapEntityIndex); if (character == null) return; character.CharacterSprite.SetPaperDollLayers(layers); }
void RecvStartNPCChatDialog(IIPSocket conn, BitStream r) { var npcIndex = r.ReadMapEntityIndex(); var forceSkipQuestDialog = r.ReadBool(); User user; Map map; if (!TryGetMap(conn, out user, out map)) return; if (user.IsPeerTrading) return; var npc = map.GetDynamicEntity<NPC>(npcIndex); if (npc == null) return; // Check the distance and state if (user.Map != npc.Map || user.Map == null || !npc.IsAlive || npc.IsDisposed || user.GetDistance(npc) > GameData.MaxNPCChatDistance) return; // If the NPC provides any quests that this user can do or turn in, show that instead if (!forceSkipQuestDialog && !npc.Quests.IsEmpty()) { IQuest<User>[] availableQuests; IQuest<User>[] turnInQuests; QuestHelper.GetAvailableQuests(user, npc, out availableQuests, out turnInQuests); if (availableQuests.Length > 0 || turnInQuests.Length > 0) { using (var pw = ServerPacket.StartQuestChatDialog(npcIndex, availableQuests.Select(x => x.QuestID), turnInQuests.Select(x => x.QuestID))) { user.Send(pw, ServerMessageType.GUI); } return; } } // Force-skipped the quest dialog, or there was no available quests, so start the chat dialog user.ChatState.StartChat(npc); }
void RecvSetProvidedQuests(IIPSocket conn, BitStream r) { var mapEntityIndex = r.ReadMapEntityIndex(); var count = r.ReadByte(); var questIDs = new QuestID[count]; for (var i = 0; i < count; i++) { questIDs[i] = r.ReadQuestID(); } var character = _objGrabber.GetDynamicEntity<Character>(mapEntityIndex); if (character != null) character.ProvidedQuests = questIDs; }
void RecvUseSkill(IIPSocket conn, BitStream r) { SkillType skillType; MapEntityIndex? targetIndex = null; // Get the SkillType to use try { skillType = r.ReadEnum<SkillType>(); } catch (InvalidCastException) { const string errmsg = "Failed to read SkillType from stream."; if (log.IsWarnEnabled) log.Warn(errmsg); Debug.Fail(errmsg); r.ReadBool(); return; } // Check for a target var hasTarget = r.ReadBool(); if (hasTarget) targetIndex = r.ReadMapEntityIndex(); // Get the user User user; if ((user = TryGetUser(conn)) != null) { // Check that they know the skill if (!user.KnownSkills.Knows(skillType)) user.Send(GameMessage.SkillNotKnown, ServerMessageType.GUIChat); else { // Use the skill user.UseSkill(skillType, GetTargetCharacter(user, targetIndex)); } } }
void RecvSetUserChar(IIPSocket conn, BitStream r) { var mapCharIndex = r.ReadMapEntityIndex(); World.UserCharIndex = mapCharIndex; }
void RecvAcceptOrTurnInQuest(IIPSocket conn, BitStream r) { var providerIndex = r.ReadMapEntityIndex(); var questID = r.ReadQuestID(); // Get the user User user; if ((user = TryGetUser(conn)) == null || user.Map == null) return; if (user.IsPeerTrading) return; // Get the provider var npc = user.Map.GetDynamicEntity<Character>(providerIndex); var provider = npc as IQuestProvider<User>; if (provider == null) return; // Check the distance and state if (user.Map != npc.Map || user.Map == null || !npc.IsAlive || npc.IsDisposed || user.GetDistance(npc) > GameData.MaxNPCChatDistance) return; // Get the quest var quest = _questManager.GetQuest(questID); if (quest == null) return; // Ensure this provider even provides this quest if (!provider.Quests.Contains(quest)) return; // If the user already has the quest, try to turn it in if (user.ActiveQuests.Contains(quest)) { // Quest already started, try to turn in var success = user.TryFinishQuest(quest); using (var pw = ServerPacket.AcceptOrTurnInQuestReply(questID, success, false)) { user.Send(pw, ServerMessageType.GUI); } } else { // Quest not started yet, try to add it var success = user.TryAddQuest(quest); using (var pw = ServerPacket.AcceptOrTurnInQuestReply(questID, success, true)) { user.Send(pw, ServerMessageType.GUI); } } }
void RecvStartShopping(IIPSocket conn, BitStream r) { var shopOwnerIndex = r.ReadMapEntityIndex(); var canBuy = r.ReadBool(); var name = r.ReadString(); var itemCount = r.ReadByte(); var items = new IItemTemplateTable[itemCount]; for (var i = 0; i < itemCount; i++) { var value = new ItemTemplateTable(); value.ReadState(r); items[i] = value; } var shopOwner = Map.GetDynamicEntity(shopOwnerIndex); var shopInfo = new ShopInfo<IItemTemplateTable>(shopOwner, name, canBuy, items); GameplayScreen.ShopForm.DisplayShop(shopInfo); }