private static void HandleInteract(GameSession session, PacketReader packet) { string id = packet.ReadMapleString(); InteractObject interactObject = session.FieldManager.State.InteractObjects[id]; if (interactObject == null) { return; } InteractObjectMetadata metadata = InteractObjectMetadataStorage.GetInteractObjectMetadata(interactObject.InteractId); switch (interactObject.Type) { case InteractObjectType.Binoculars: session.Send(InteractObjectPacket.Use(interactObject)); QuestHelper.UpdateExplorationQuest(session, interactObject.InteractId.ToString(), "interact_object_rep"); break; case InteractObjectType.Ui: session.Send(InteractObjectPacket.Use(interactObject)); break; case InteractObjectType.RankBoard: session.Send(WebOpenPacket.Open(metadata.Web.Url)); break; case InteractObjectType.AdBalloon: session.Send(PlayerHostPacket.AdBalloonWindow((AdBalloon)interactObject)); break; case InteractObjectType.Gathering: GatheringHelper.HandleGathering(session, metadata.Gathering.RecipeId, out int numDrop); session.Send(InteractObjectPacket.Use(interactObject, (short)(numDrop > 0 ? 0 : 1), numDrop)); break; } session.Send(InteractObjectPacket.Interact(interactObject)); }
private static void HandleUse(GameSession session, PacketReader packet) { string uuid = packet.ReadMapleString(); IFieldObject <InteractObject> interactObject = session.FieldManager.State.InteractObjects[uuid]; if (interactObject == null) { return; } MapInteractObject mapObject = MapEntityStorage.GetInteractObject(session.Player.MapId).FirstOrDefault(x => x.Uuid == uuid); int numDrop = 0; switch (interactObject.Value.Type) { case InteractObjectType.Binoculars: QuestHelper.UpdateExplorationQuest(session, mapObject.InteractId.ToString(), "interact_object_rep"); break; case InteractObjectType.Gathering: RecipeMetadata recipe = RecipeMetadataStorage.GetRecipe(mapObject.RecipeId); session.Player.Levels.GainMasteryExp((MasteryType)recipe.MasteryType, 0); long currentMastery = session.Player.Levels.MasteryExp.FirstOrDefault(x => x.Type == (MasteryType)recipe.MasteryType).CurrentExp; if (currentMastery < recipe.RequireMastery) { return; } session.Player.IncrementGatheringCount(mapObject.RecipeId, 0); int numCount = session.Player.GatheringCount[mapObject.RecipeId].Current; List <RecipeItem> items = RecipeMetadataStorage.GetResult(recipe); int masteryDiffFactor = numCount switch { int n when n < recipe.HighPropLimitCount => MasteryFactorMetadataStorage.GetFactor(0), int n when n < recipe.NormalPropLimitCount => MasteryFactorMetadataStorage.GetFactor(1), int n when n < (int)(recipe.NormalPropLimitCount * 1.3) => MasteryFactorMetadataStorage.GetFactor(2), _ => MasteryFactorMetadataStorage.GetFactor(3), }; foreach (RecipeItem item in items) { int prob = RarityChance[item.Rarity] * masteryDiffFactor / 10000; if (RandomProvider.Get().Next(100) >= prob) { continue; } for (int i = 0; i < item.Amount; i++) { session.FieldManager.AddItem(session, new Item(item.Id)); } numDrop += item.Amount; } if (numDrop > 0) { session.Player.IncrementGatheringCount(mapObject.RecipeId, numDrop); session.Player.Levels.GainMasteryExp((MasteryType)recipe.MasteryType, recipe.RewardMastery); } break; case InteractObjectType.AdBalloon: session.Send(PlayerHostPacket.AdBalloonWindow(interactObject)); return; default: break; } session.Send(InteractObjectPacket.UseObject(mapObject, (short)(numDrop > 0 ? 0 : 1), numDrop)); session.Send(InteractObjectPacket.Extra(mapObject)); }
private static void HandleInteract(GameSession session, PacketReader packet) { Player player = session.Player; string id = packet.ReadString(); session.FieldManager.State.InteractObjects.TryGetValue(id, out IFieldObject <InteractObject> fieldInteractObject); if (fieldInteractObject is null) { return; } InteractObject interactObject = fieldInteractObject.Value; InteractObjectMetadata metadata = InteractObjectMetadataStorage.GetInteractObjectMetadata(interactObject.InteractId); QuestManager.OnInteractObject(player, interactObject.InteractId); switch (interactObject.Type) { case InteractObjectType.Binoculars: session.Send(InteractObjectPacket.Use(interactObject)); break; case InteractObjectType.Ui: session.Send(InteractObjectPacket.Use(interactObject)); break; case InteractObjectType.RankBoard: session.Send(WebOpenPacket.Open(metadata.Web.Url)); break; case InteractObjectType.AdBalloon: session.Send(PlayerHostPacket.AdBalloonWindow((AdBalloon)interactObject)); break; case InteractObjectType.Gathering: GatheringHelper.HandleGathering(session, metadata.Gathering.RecipeId, out int numDrop); session.Send(InteractObjectPacket.Use(interactObject, (short)(numDrop > 0 ? 0 : 1), numDrop)); break; case InteractObjectType.Common: // Unsure if all interact objects need to be set as disabled. interactObject.State = InteractObjectState.Disable; session.Send(InteractObjectPacket.Update(interactObject)); session.Send(InteractObjectPacket.Interact(interactObject)); foreach ((int questId, QuestState state) in metadata.Quests) { if (!player.QuestData.TryGetValue(questId, out QuestStatus questStatus) || questStatus.State != state) { continue; } interactObject.State = InteractObjectState.Activated; session.Send(InteractObjectPacket.Update(interactObject)); } DropItems(); TrophyManager.OnObjectInteract(player, interactObject.InteractId); if (interactObject is MapChest) { // Unsure if setting as activated is specific of map chests interactObject.State = InteractObjectState.Activated; // Delayed removal of the chest Task.Run(async() => { await Task.Delay(TimeSpan.FromSeconds(10)); session.FieldManager.State.RemoveInteractObject(interactObject.Id); session.FieldManager.BroadcastPacket(InteractObjectPacket.Update(interactObject)); session.FieldManager.BroadcastPacket(InteractObjectPacket.Remove(interactObject)); }); } return; } session.Send(InteractObjectPacket.Interact(interactObject)); void DropItems() { foreach (int boxId in metadata.Drop.IndividualDropBoxId) { ItemDropMetadata itemDropMetadataStorage = ItemDropMetadataStorage.GetItemDropMetadata(boxId); if (itemDropMetadataStorage is null) { continue; } foreach (DropGroup dropGroup in itemDropMetadataStorage.DropGroups) { foreach (DropGroupContent dropGroupContent in dropGroup.Contents) { foreach (int itemId in dropGroupContent.ItemIds) { int amount = Random.Shared.Next((int)dropGroupContent.MinAmount, (int)dropGroupContent.MaxAmount); Item item = new(itemId, amount, dropGroupContent.Rarity); session.FieldManager.AddItem(session.Player.FieldPlayer, item); } } } } foreach (int boxId in metadata.Drop.GlobalDropBoxId) { ItemDropMetadata itemDropMetadataStorage = ItemDropMetadataStorage.GetItemDropMetadata(boxId); if (itemDropMetadataStorage is null) { continue; } foreach (DropGroup dropGroup in itemDropMetadataStorage.DropGroups) { foreach (DropGroupContent dropGroupContent in dropGroup.Contents) { foreach (int itemId in dropGroupContent.ItemIds) { int amount = Random.Shared.Next((int)dropGroupContent.MinAmount, (int)dropGroupContent.MaxAmount); Item item = new(itemId, amount, dropGroupContent.Rarity); session.FieldManager.AddItem(session.Player.FieldPlayer, item); } } } } } }