From 179cb505571b278ea3e14454c811c54cb4e06e2a Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Mon, 11 Nov 2019 03:40:16 -0800 Subject: [PATCH] Updates Packets & Randomizer (#43) * Fixes a bug with the main loop. Removes unnecessary optimizations for RDRand. * WIP - Rewriting packets. * Cleanup and updates README * Converts more packets * Fixes header * Converts Effects packets. * Forgot the send command * Adds the start of containers packets. * Adds message packets with caching * Extends the send methods * Starts to add Acquire methods * Converted the packets * Cleanup * Cleanup * Adds more packets * Adds more packets * Fixes clearing arrays from pool. Adds Mobile Incoming * Converts more packets. * Moves more packets * Moves more packets * Test compression * Merges * Migrating to an idiomatic syntax that also supports compression, and proxying. * Optimize the stack alloc. Changes attributes * Converted container packets * Visual Studio doesn't auto save files. I am still getting used to subpar IDEs. * Adds static packet caching. Will profile later. Converts more packets * Fixes packets and changes how compression is configured * WIP - Adds basics for Gumps. Not finished though. * Fix file * Fixes formatting * Changed SpanWriter to be more idiomatic. * Fixes Span vs RawSpan and missing stackallocs * Converts over some more gumps * WIP - Deletes 32bit support. * Drops RDRand32 support. * Fixes gump compilation * Converting gump components * Removes old huffman compression function * Revert signature for backwards compatibility * WIP - Converting more gump components * Creates ArraySet for the strings. Updates AppendTo to reference that. * Converts the maining gump components * Cleans up gump components * Cleans up directives * Cleans up ArraySet and moves it. Adds null-coalescing-assignment * Cleanup, Target Packets, and C# 8 changes. * Removed OPL Packet * World packets * Fixing packet uses * Cleans up code. Fixes packet uses in various places. * More cleanup for packets * Code cleanup * Converts more packet uses and cleans up more code * More code cleanup * Finishes fixing the packets in Item * Updates secure trade packets * Updates core and gets it to compile. * Moved packets to scripts. Fixed account handler use of packets * Code cleanup * Updates chat packets * Code cleanuo * Adds party packets, but need to implement them. * Party packets WIP * Finishes party packets * Rearrange movement namespaces and classes * Finishes plant packets * Code Formatting * Fixes moving effects * Code cleanup, eliminates equipinfo * Adds more packets. Fixes bugs with various packets. * Finishes mahjon packets * Fixes mahjong packet * Code cleanup * Finishes mahjong packets * Adds Map packets * Add multifacet maps and charts * Cleans up some packets with UTF8 * Optimizes packets * Cleans up more packets. Moves the MessageHelper * Removes assistant support. Removes extended protocol. Incorporates MapUO packets as normal packets. * Updates protocol extensions packet receiver * Fixes a few bugs. Fixes a few more packets. * Code cleanup and fixing more packets * Fixes packet effects * Cleaned up more code * Buff Icon cleanup * Removed unused constructors * Code Cleanup. Adds BoatHS Packets * Moves house files. Updates house foundation packets. * Deployment cleanup * Fixes: * Code cleanup * More code cleanup * More code cleanup * Cleaned up BaseHouse * Enforces styling * Converts foreach to linq where possible. * Dont need that * Goals/Readme updates * Removes 32bit support at the highest level. Turns on HRT by default. * Code cleanup. Fixes extended features packet. * Fixes various bugs * Code cleanup * Code cleanup * Code cleanup. Fixes gump X/Y assignment. * Code cleanup using |= operator * More code cleanup * Cleanup * Fixes spacing issues. Thanks Visual Studio. You suck. * Compiler error * Fixes NPE from RunUO 2.7 * Renames ScriptCompiler to AssemblyHandler. Fixes packets. Updates README * Fixes more packets. Stupid trailing nulls. * Fixes various bugs. * Fixes for gumps * Fixes more gump stuff. Going to split it out later since it is getting insane * Recoded the gump writing * WIP * *Added output path of scripts project to dev branch *Activated debugging in code --- GOALS.md | 4 +- ModernUO.sln | 20 +- Projects/Scripts/Accounting/Account.cs | 1 + .../Accounting/AccountAttackLimiter.cs | 3 +- Projects/Scripts/Accounting/AccountHandler.cs | 61 +- Projects/Scripts/Accounting/Accounts.cs | 2 +- Projects/Scripts/Accounting/Firewall.cs | 4 +- Projects/Scripts/Commands/Add.cs | 2 +- Projects/Scripts/Commands/Batch.cs | 3 +- .../Scripts/Commands/BoundingBoxPicker.cs | 4 +- Projects/Scripts/Commands/ConvertPlayers.cs | 2 +- Projects/Scripts/Commands/Decorate.cs | 4 +- Projects/Scripts/Commands/DecorateMag.cs | 2 +- Projects/Scripts/Commands/Docs.cs | 52 +- Projects/Scripts/Commands/GenTeleporter.cs | 76 +- .../Commands/Generic/Commands/Commands.cs | 63 +- .../Commands/Generic/Commands/DesignInsert.cs | 6 +- .../Compilers/ConditionalCompiler.cs | 41 +- .../Generic/Extensions/DistinctExtension.cs | 3 +- .../Generic/Extensions/SortExtension.cs | 4 +- .../Implementors/BaseCommandImplementor.cs | 11 +- .../ContainedCommandImplementor.cs | 5 +- .../Implementors/GlobalCommandImplementor.cs | 11 +- .../Generic/Implementors/ObjectConditional.cs | 3 +- .../Implementors/RegionCommandImplementor.cs | 14 +- .../Implementors/SerialCommandImplementor.cs | 8 +- Projects/Scripts/Commands/Handlers.cs | 73 +- Projects/Scripts/Commands/HelpInfo.cs | 2 +- Projects/Scripts/Commands/Logging.cs | 2 +- Projects/Scripts/Commands/Properties.cs | 8 +- Projects/Scripts/Commands/ShardTime.cs | 4 +- Projects/Scripts/Commands/SignParser.cs | 17 +- Projects/Scripts/Commands/Skills.cs | 4 +- Projects/Scripts/Commands/SkillsMenu.cs | 4 +- Projects/Scripts/Commands/Statics.cs | 10 +- Projects/Scripts/Commands/VisibilityList.cs | 88 +- Projects/Scripts/Commands/Wipe.cs | 6 +- .../Context Menus/AddToSpellbookEntry.cs | 6 +- .../Engines/BulkOrders/Books/BOBGump.cs | 1 - .../Engines/BulkOrders/Books/BulkOrderBook.cs | 1 - .../Scripts/Engines/BulkOrders/LargeBOD.cs | 1 + .../Engines/BulkOrders/LargeTailorBOD.cs | 3 +- .../Scripts/Engines/BulkOrders/Rewards.cs | 52 +- .../CannedEvil/ChampionSkullBrazier.cs | 26 +- .../Engines/CannedEvil/ChampionSpawn.cs | 20 +- Projects/Scripts/Engines/Chat/Channel.cs | 14 +- Projects/Scripts/Engines/Chat/Chat.cs | 31 +- .../Engines/Chat/ChatActionHandlers.cs | 6 +- Projects/Scripts/Engines/Chat/ChatUser.cs | 28 +- Projects/Scripts/Engines/Chat/Chatold.cs | 4 +- Projects/Scripts/Engines/Chat/Packets.cs | 34 +- Projects/Scripts/Engines/ConPVP/Arena.cs | 13 +- .../Scripts/Engines/ConPVP/DuelContext.cs | 28 +- .../Engines/ConPVP/Games/BombingRun.cs | 53 +- Projects/Scripts/Engines/ConPVP/Games/CTF.cs | 40 +- .../Scripts/Engines/ConPVP/Games/DoubleDom.cs | 10 +- .../Engines/ConPVP/Games/KingOfTheHill.cs | 19 +- .../Engines/ConPVP/Games/TourneyMatch.cs | 2 +- .../Engines/ConPVP/Gumps/RulesetGump.cs | 4 +- .../Scripts/Engines/ConPVP/Participant.cs | 2 +- Projects/Scripts/Engines/ConPVP/Tournament.cs | 55 +- .../Scripts/Engines/Craft/Core/CraftItem.cs | 9 +- .../Scripts/Engines/Craft/Core/Recipes.cs | 10 +- Projects/Scripts/Engines/Craft/Core/Repair.cs | 4 +- Projects/Scripts/Engines/Craft/DefAlchemy.cs | 2 +- .../Scripts/Engines/Craft/DefBlacksmithy.cs | 2 +- .../Scripts/Engines/Craft/DefBowFletching.cs | 2 +- .../Scripts/Engines/Craft/DefCarpentry.cs | 2 +- .../Scripts/Engines/Craft/DefCartography.cs | 2 +- Projects/Scripts/Engines/Craft/DefCooking.cs | 2 +- .../Scripts/Engines/Craft/DefGlassblowing.cs | 2 +- .../Scripts/Engines/Craft/DefInscription.cs | 2 +- Projects/Scripts/Engines/Craft/DefMasonry.cs | 2 +- .../Scripts/Engines/Craft/DefTailoring.cs | 2 +- .../Scripts/Engines/Craft/DefTinkering.cs | 2 +- .../Doom/LeverPuzzle/LeverPuzzleController.cs | 22 +- .../Doom/LeverPuzzle/LeverPuzzleItems.cs | 2 +- .../Doom/LeverPuzzle/LeverPuzzleRegions.cs | 6 +- Projects/Scripts/Engines/Ethics/Core/Ethic.cs | 4 +- .../Engines/Ethics/Evil/Powers/Blight.cs | 8 +- .../Engines/Ethics/Evil/Powers/UnholySense.cs | 4 +- .../Engines/Ethics/Hero/Powers/Bless.cs | 8 +- .../Engines/Ethics/Hero/Powers/HolySense.cs | 4 +- .../Scripts/Engines/Factions/Core/Faction.cs | 86 +- .../Engines/Factions/Core/PlayerState.cs | 4 +- .../Power Faction Items/PowerFactionItem.cs | 7 +- .../Power Faction Items/UrnOfAscension.cs | 6 +- .../Factions/Items/Traps/BaseFactionTrap.cs | 35 +- .../Items/Traps/FactionExplosionTrap.cs | 2 +- .../Factions/Items/Traps/FactionSawTrap.cs | 6 +- .../Factions/Mobiles/Guards/GuardAI.cs | 6 +- Projects/Scripts/Engines/Harvest/Fishing.cs | 4 +- .../Scripts/Engines/Harvest/Lumberjacking.cs | 2 +- Projects/Scripts/Engines/Harvest/Mining.cs | 2 +- Projects/Scripts/Engines/Help/HelpGump.cs | 93 +- Projects/Scripts/Engines/Help/PagePrompt.cs | 10 +- .../Scripts/Engines/Help/PagePromptGump.cs | 6 +- Projects/Scripts/Engines/Help/PageQueue.cs | 2 - .../Scripts/Engines/Help/PageQueueGump.cs | 86 +- .../Scripts/Engines/Help/SpeechLogGump.cs | 2 - Projects/Scripts/Engines/Help/StuckMenu.cs | 6 +- .../Scripts/Engines/Khaldun/PuzzleChest.cs | 46 +- .../Engines/MLQuests/Gumps/RaceChangeGump.cs | 85 +- Projects/Scripts/Engines/MLQuests/MLQuest.cs | 15 +- .../Engines/MLQuests/MLQuestContext.cs | 24 +- .../Scripts/Engines/MLQuests/MLQuestEntry.cs | 41 +- .../Engines/MLQuests/MLQuestPersistence.cs | 5 +- .../Scripts/Engines/MLQuests/MLQuestSystem.cs | 21 +- .../Engines/MLQuests/Mobiles/BoonCollector.cs | 16 +- .../Engines/MLQuests/Mobiles/SirHelper.cs | 46 +- .../MLQuests/Objectives/EscortObjective.cs | 14 +- .../MLQuests/Objectives/KillObjective.cs | 26 +- .../Scripts/Engines/MLQuests/QuestArea.cs | 10 +- .../Scripts/Engines/MyRunUO/LayerComparer.cs | 81 + Projects/Scripts/Engines/Party/Packets.cs | 196 +- Projects/Scripts/Engines/Party/Party.cs | 199 +- .../Engines/Pathing/FastAStarAlgorithm.cs | 42 +- .../Scripts/Engines/Pathing/FastMovement.cs | 4 +- Projects/Scripts/Engines/Pathing/Movement.cs | 6 +- .../Scripts/Engines/Pathing/MovementPath.cs | 4 +- .../Scripts/Engines/Pathing/PathAlgorithm.cs | 4 +- .../Scripts/Engines/Pathing/PathFollower.cs | 3 +- .../Engines/Pathing/SlowAStarAlgorithm.cs | 37 +- .../Engines/Plants/EmptyTheBowlGump.cs | 2 +- .../Scripts/Engines/Plants/MainPlantGump.cs | 20 +- .../Plants/Network/DisplayHelpTopic.cs | 15 - Projects/Scripts/Engines/Plants/PlantItem.cs | 3 +- .../Scripts/Engines/Plants/PlantResources.cs | 13 +- .../Scripts/Engines/Plants/PlantSystem.cs | 1 + Projects/Scripts/Engines/Plants/PlantType.cs | 24 +- .../Scripts/Engines/Plants/PollinateTarget.cs | 22 +- .../Engines/Plants/ReproductionGump.cs | 15 +- .../Engines/Plants/SetToDecorativeGump.cs | 2 +- .../Quests/Collector/Items/Obsidian.cs | 17 +- .../Engines/Quests/Collector/Objectives.cs | 2 +- .../Quests/Core/Items/EnchantedSextant.cs | 13 +- .../Engines/Quests/Core/QuestSerializer.cs | 14 - .../Engines/Quests/Core/QuestSystem.cs | 4 +- .../Quests/Dark Tides/Items/KronusScroll.cs | 9 +- .../Quests/Dark Tides/Items/MaabusCoffin.cs | 6 +- .../Engines/Quests/Dark Tides/Objectives.cs | 2 +- .../Quests/Uzeraan Turmoil/Conversations.cs | 50 +- .../Items/SchmendrickApprenticeCorpse.cs | 30 +- .../Uzeraan Turmoil/Mobiles/MilitiaFighter.cs | 9 +- .../Quests/Uzeraan Turmoil/Objectives.cs | 76 +- .../Uzeraan Turmoil/UzeraanTurmoilQuest.cs | 5 +- .../Quests/Witch Apprentice/Ingredient.cs | 10 +- .../Items/HagApprenticeCorpse.cs | 4 +- .../Quests/Witch Apprentice/Objectives.cs | 55 +- Projects/Scripts/Engines/Spawner/Spawner.cs | 130 +- .../Scripts/Engines/Spawner/SpawnerGump.cs | 12 +- .../Character Statue Maker/CharacterStatue.cs | 46 +- .../Gumps/CharacterStatueGump.cs | 11 +- .../Character Statue Maker/Packets.cs | 33 +- .../VeteranRewards/RewardOptionGump.cs | 13 +- Projects/Scripts/Engines/Virtues/Honor.cs | 4 +- .../Scripts/Engines/Virtues/VirtueGump.cs | 18 +- .../Scripts/Engines/Virtues/VirtueInfoGump.cs | 4 +- .../Engines/Virtues/VirtueStatusGump.cs | 2 +- Projects/Scripts/Gumps/AdminGump.cs | 79 +- Projects/Scripts/Gumps/BaseConfirmGump.cs | 6 +- Projects/Scripts/Gumps/CategorizedAddGump.cs | 7 +- Projects/Scripts/Gumps/ClientGump.cs | 4 +- Projects/Scripts/Gumps/CommentsGump.cs | 7 +- Projects/Scripts/Gumps/ConfirmHouseResize.cs | 4 +- Projects/Scripts/Gumps/Go/GoGump.cs | 4 +- .../Scripts/Gumps/Guilds/DeclareFealtyGump.cs | 4 +- .../Gumps/Guilds/GrantGuildTitleGump.cs | 2 +- .../Scripts/Gumps/Guilds/GuildAbbrvPrompt.cs | 1 - .../Gumps/Guilds/GuildAcceptWarGump.cs | 2 +- .../Gumps/Guilds/GuildAdminCandidatesGump.cs | 2 +- .../Gumps/Guilds/GuildCandidatesGump.cs | 2 +- .../Gumps/Guilds/GuildChangeTypeGump.cs | 2 +- .../Scripts/Gumps/Guilds/GuildCharterGump.cs | 2 +- .../Gumps/Guilds/GuildCharterPrompt.cs | 1 - .../Gumps/Guilds/GuildDeclarePeaceGump.cs | 2 +- .../Gumps/Guilds/GuildDeclareWarGump.cs | 2 +- .../Gumps/Guilds/GuildDeclareWarPrompt.cs | 1 - .../Scripts/Gumps/Guilds/GuildDismissGump.cs | 2 +- .../Scripts/Gumps/Guilds/GuildNamePrompt.cs | 1 - .../Gumps/Guilds/GuildRejectWarGump.cs | 2 +- .../Guilds/GuildRescindDeclarationGump.cs | 2 +- .../Scripts/Gumps/Guilds/GuildRosterGump.cs | 2 +- .../Scripts/Gumps/Guilds/GuildTitlePrompt.cs | 1 - .../Scripts/Gumps/Guilds/GuildWarAdminGump.cs | 2 +- Projects/Scripts/Gumps/Guilds/GuildWarGump.cs | 2 +- .../Gumps/Guilds/GuildWebsitePrompt.cs | 1 - .../Scripts/Gumps/Guilds/GuildmasterGump.cs | 2 +- .../Guilds/New Guild System/BaseGuildGump.cs | 29 +- .../Guilds/New Guild System/OtherGuildInfo.cs | 67 - Projects/Scripts/Gumps/HouseDemolishGump.cs | 18 +- Projects/Scripts/Gumps/HouseGump.cs | 8 +- Projects/Scripts/Gumps/HouseGumpAOS.cs | 160 +- Projects/Scripts/Gumps/HouseTransferGump.cs | 2 +- Projects/Scripts/Gumps/PetResurrectGump.cs | 4 +- Projects/Scripts/Gumps/PlayerVendorGumps.cs | 19 +- Projects/Scripts/Gumps/PolymorphGump.cs | 2 +- Projects/Scripts/Gumps/Props/PropsGump.cs | 8 +- Projects/Scripts/Gumps/Props/SetBodyGump.cs | 30 +- Projects/Scripts/Gumps/Props/SetGump.cs | 1 - Projects/Scripts/Gumps/Props/SetObjectGump.cs | 1 - Projects/Scripts/Gumps/RunebookGump.cs | 5 +- Projects/Scripts/Gumps/SetSecureLevelGump.cs | 6 +- Projects/Scripts/Gumps/SkillsGump.cs | 1 - Projects/Scripts/Gumps/VendorRentalGumps.cs | 1 - .../Halloween/2006/Engines/TrickOrTreat.cs | 5 +- Projects/Scripts/Items/Addons/BallotBox.cs | 1 - .../Addons/ElvenSpinningwheelEastAddon.cs | 23 +- .../Addons/ElvenSpinningwheelSouthAddon.cs | 24 +- .../Items/Addons/FlourMillEastAddon.cs | 7 +- .../Items/Addons/FlourMillSouthAddon.cs | 7 +- Projects/Scripts/Items/Addons/JackOLantern.cs | 22 +- .../Items/Addons/SpinningwheelEastAddon.cs | 24 +- .../Items/Addons/SpinningwheelSouthAddon.cs | 24 +- Projects/Scripts/Items/Aquarium/Aquarium.cs | 9 +- Projects/Scripts/Items/Armor/BaseArmor.cs | 64 +- .../Items/Armor/Glasses/ElvenGlasses.cs | 10 +- Projects/Scripts/Items/Body Parts/Head.cs | 5 +- Projects/Scripts/Items/Books/BaseBook.cs | 124 +- Projects/Scripts/Items/Books/BrownBook.cs | 6 +- Projects/Scripts/Items/Books/Packets.cs | 80 + Projects/Scripts/Items/Books/RedBook.cs | 6 +- Projects/Scripts/Items/Books/TanBook.cs | 6 +- .../Scripts/Items/Clothing/BaseClothing.cs | 32 +- Projects/Scripts/Items/Clothing/Hats.cs | 1 - .../Scripts/Items/Containers/Container.cs | 51 +- .../Items/Containers/FillableContainers.cs | 16 +- .../Items/Containers/LockableContainer.cs | 4 +- .../Scripts/Items/Containers/SalvageBag.cs | 15 +- .../Items/Containers/TrappableContainer.cs | 10 +- .../Items/Containers/TreasureMapChest.cs | 69 +- .../Scripts/Items/Deeds/HairRestylingDeed.cs | 8 +- .../Scripts/Items/Deeds/HolidayTreeDeed.cs | 10 +- .../Items/Equipment/EquipmentInfoAttribute.cs | 15 + Projects/Scripts/Items/Equipment/Packets.cs | 56 + Projects/Scripts/Items/Food/CookableFood.cs | 39 +- Projects/Scripts/Items/Food/Cooking.cs | 28 +- Projects/Scripts/Items/Games/BaseBoard.cs | 10 +- Projects/Scripts/Items/Games/Dices.cs | 8 +- .../Items/Games/Mahjong/MahjongGame.cs | 4 +- .../Games/Mahjong/MahjongPacketHandlers.cs | 11 +- .../Items/Games/Mahjong/MahjongPlayers.cs | 98 +- .../Scripts/Items/Games/Mahjong/Packets.cs | 232 +- Projects/Scripts/Items/Guilds/GuildDeed.cs | 1 - Projects/Scripts/Items/Guilds/Guildstone.cs | 21 +- .../Scripts/Items/Maps/IndecipherableMap.cs | 10 +- Projects/Scripts/Items/Maps/MapItem.cs | 105 +- Projects/Scripts/Items/Maps/Packets.cs | 81 + Projects/Scripts/Items/Maps/PresetMap.cs | 4 +- Projects/Scripts/Items/Maps/TreasureMap.cs | 92 +- Projects/Scripts/Items/Misc/BankCheck.cs | 1 - Projects/Scripts/Items/Misc/Blocker.cs | 172 +- Projects/Scripts/Items/Misc/BulletinBoards.cs | 227 +- .../Items/Misc/CommunicationCrystals.cs | 10 +- Projects/Scripts/Items/Misc/Corpses/Corpse.cs | 84 +- .../Scripts/Items/Misc/Corpses/Packets.cs | 236 +- .../Scripts/Items/Misc/EffectController.cs | 4 +- Projects/Scripts/Items/Misc/EffectItem.cs | 2 +- Projects/Scripts/Items/Misc/Firebomb.cs | 3 +- Projects/Scripts/Items/Misc/Gold.cs | 1 - .../Scripts/Items/Misc/InteriorDecorator.cs | 6 +- Projects/Scripts/Items/Misc/Key.cs | 19 +- Projects/Scripts/Items/Misc/KeyRing.cs | 16 +- Projects/Scripts/Items/Misc/LOSBlocker.cs | 173 +- .../Items/Misc/PlayerBulletinBoards.cs | 1 - Projects/Scripts/Items/Misc/PowerGenerator.cs | 15 +- Projects/Scripts/Items/Misc/PublicMoongate.cs | 8 +- Projects/Scripts/Items/Misc/Teleporter.cs | 31 +- Projects/Scripts/Items/Misc/TrashBarrel.cs | 2 +- Projects/Scripts/Items/Misc/UnholyBone.cs | 2 +- Projects/Scripts/Items/Quivers/BaseQuiver.cs | 2 +- .../Items/Resources/Tailor/BoltOfCloth.cs | 6 +- .../Scripts/Items/Resources/Tailor/Cloth.cs | 5 +- .../Items/Resources/Tailor/Leathers.cs | 14 +- .../Items/Resources/Tailor/UncutCloth.cs | 5 +- .../Items/Skill Items/Camping/Campfire.cs | 2 +- .../Items/Skill Items/Fishing/Misc/SOS.cs | 18 +- .../Fishing/Misc/SpecialFishingNet.cs | 3 +- .../Harvest Tools/BaseHarvestTool.cs | 4 +- .../Skill Items/Magical/Misc/Moongate.cs | 4 +- .../Skill Items/Magical/Misc/RecallRune.cs | 1 - .../Explosion Potions/BaseExplosionPotion.cs | 5 +- .../Skill Items/Magical/Potions/NightSight.cs | 6 +- .../Items/Skill Items/Magical/Runebook.cs | 14 +- .../Items/Skill Items/Magical/Spellbook.cs | 51 +- .../Scripts/Items/Skill Items/Misc/Bandage.cs | 2 +- .../Items/Skill Items/Misc/FireHorn.cs | 9 +- .../Musical Instruments/BaseInstrument.cs | 9 +- .../Skill Items/Ninjitsu/LeatherNinjaBelt.cs | 25 +- .../Skill Items/Tailor Items/Misc/Dyes.cs | 1 - .../Skill Items/Thief/DisguisePersistance.cs | 7 +- .../Items/Skill Items/Tinkering/Spyglass.cs | 12 +- .../Dawn's Music Box/DawnsMusicBox.cs | 14 +- .../SacrificialAltar.cs | 2 +- .../Special/House Raffle/HouseRaffleStone.cs | 27 +- .../Items/Special/Solen Items/BagOfSending.cs | 30 +- .../Special/Solen Items/BallOfSummoning.cs | 18 +- .../Special/Solen Items/BraceletOfBinding.cs | 1 - Projects/Scripts/Items/Special/SoulStone.cs | 25 +- .../Special/Special Scrolls/PowerScroll.cs | 30 +- .../Special Scrolls/ScrollofAlacrity.cs | 15 +- .../Special Scrolls/ScrollofTranscendence.cs | 15 +- .../Special/Special Scrolls/SpecialScroll.cs | 2 +- .../Special/Special Scrolls/StatScroll.cs | 34 +- .../Veteran Rewards/AnkhOfSacrifice.cs | 9 +- .../Items/Special/Veteran Rewards/Brazier.cs | 3 +- .../Items/Special/Veteran Rewards/Cannon.cs | 88 +- .../Veteran Rewards/WeaponEngravingTool.cs | 6 +- .../Scripts/Items/Talismans/TalismanSlayer.cs | 13 +- .../Items/Talismans/TalismanSummons.cs | 19 +- Projects/Scripts/Items/Traps/GasTrap.cs | 4 +- .../Scripts/Items/Traps/GiantSpikeTrap.cs | 2 +- Projects/Scripts/Items/Traps/SawTrap.cs | 4 +- Projects/Scripts/Items/Traps/SpikeTrap.cs | 14 +- Projects/Scripts/Items/Traps/StoneFaceTrap.cs | 26 +- Projects/Scripts/Items/Wands/BaseWand.cs | 13 +- .../Items/Weapons/Abilities/WeaponAbility.cs | 90 +- Projects/Scripts/Items/Weapons/BaseWeapon.cs | 140 +- .../Items/Weapons/Maces/FireworksWand.cs | 2 +- .../Items/Weapons/Ranged/BaseRanged.cs | 2 +- .../Items/Weapons/Staves/ShepherdsCrook.cs | 7 +- Projects/Scripts/Misc/AOS.cs | 5 +- Projects/Scripts/Misc/AccountPrompt.cs | 7 +- Projects/Scripts/Misc/Animations.cs | 4 +- Projects/Scripts/Misc/AttackMessage.cs | 4 +- Projects/Scripts/Misc/AutoSave.cs | 4 +- Projects/Scripts/Misc/Broadcasts.cs | 2 +- Projects/Scripts/Misc/BuffIcons.cs | 198 +- Projects/Scripts/Misc/CharacterCreation.cs | 127 +- Projects/Scripts/Misc/Cleanup.cs | 6 +- Projects/Scripts/Misc/CurrentExpansion.cs | 4 +- Projects/Scripts/Misc/DoorGenerator.cs | 2 +- Projects/Scripts/Misc/Email.cs | 16 +- Projects/Scripts/Misc/Fastwalk.cs | 4 +- Projects/Scripts/Misc/Geometry.cs | 19 +- .../Gifts/Winter2004/PileOfGlacialSnow.cs | 6 +- Projects/Scripts/Misc/Guild.cs | 134 +- Projects/Scripts/Misc/Keywords.cs | 4 +- Projects/Scripts/Misc/LanguageStatistics.cs | 13 +- Projects/Scripts/Misc/LightCycle.cs | 12 +- Projects/Scripts/Misc/LoginStats.cs | 4 +- Projects/Scripts/Misc/MapDefinitions.cs | 11 +- Projects/Scripts/Misc/MapUO.cs | 158 +- .../Solen Items => Misc}/MessageHelper.cs | 8 +- Projects/Scripts/Misc/NameList.cs | 1 + Projects/Scripts/Misc/NameVerification.cs | 27 +- Projects/Scripts/Misc/Notoriety.cs | 28 +- Projects/Scripts/Misc/Paperdoll.cs | 11 +- Projects/Scripts/Misc/ProfanityProtection.cs | 5 +- Projects/Scripts/Misc/Profile.cs | 16 +- Projects/Scripts/Misc/ProtocolExtensions.cs | 44 +- Projects/Scripts/Misc/RaceDefinitions.cs | 81 +- Projects/Scripts/Misc/ServerList.cs | 87 +- Projects/Scripts/Misc/ShardPoller.cs | 5 +- Projects/Scripts/Misc/SkillCheck.cs | 2 +- Projects/Scripts/Misc/Titles.cs | 3 +- .../Scripts/Misc/TreasureMapProtection.cs | 4 +- Projects/Scripts/Misc/VendorGenerator.cs | 20 +- Projects/Scripts/Misc/Weather.cs | 1 + Projects/Scripts/Misc/WeightOverloading.cs | 21 +- Projects/Scripts/Mobiles/AI/AnimalAI.cs | 2 +- Projects/Scripts/Mobiles/AI/BaseAI.cs | 79 +- Projects/Scripts/Mobiles/AI/HealerAI.cs | 20 +- Projects/Scripts/Mobiles/AI/MageAI.cs | 15 +- .../Mobiles/Animals/Mounts/Ethereals.cs | 9 +- .../Scripts/Mobiles/Animals/Mounts/Kirin.cs | 2 +- Projects/Scripts/Mobiles/BaseCreature.cs | 252 +- .../Scripts/Mobiles/Familiars/HordeMinion.cs | 6 +- .../Scripts/Mobiles/Guards/ArcherGuard.cs | 2 +- Projects/Scripts/Mobiles/Guards/BaseGuard.cs | 8 +- .../Scripts/Mobiles/Guards/WarriorGuard.cs | 2 +- .../Monsters/Humanoid/Magic/SavageShaman.cs | 8 +- .../Humanoid/Melee/KhaldunRevenant.cs | 11 +- .../Humanoid/Melee/KhaldunSummoner.cs | 2 +- .../Monsters/Humanoid/Melee/KhaldunZealot.cs | 2 +- .../Mobiles/Monsters/ML/Special/Ilhenir.cs | 4 +- .../Monsters/Misc/Melee/PlagueBeastLord.cs | 3 +- .../Monsters/Misc/Melee/PlagueSpawn.cs | 3 +- .../Mobiles/Monsters/SE/DeathWatchBeetle.cs | 2 +- .../Scripts/Mobiles/Monsters/SE/FanDancer.cs | 9 +- Projects/Scripts/Mobiles/PlayerMobile.cs | 365 +- .../Scripts/Mobiles/Special/ChaosGuard.cs | 1 - Projects/Scripts/Mobiles/Special/Harrower.cs | 14 +- Projects/Scripts/Mobiles/Special/Mephitis.cs | 9 +- .../Scripts/Mobiles/Special/OrderGuard.cs | 1 - Projects/Scripts/Mobiles/Special/Semidar.cs | 3 +- Projects/Scripts/Mobiles/Townfolk/Banker.cs | 11 - .../Scripts/Mobiles/Townfolk/BrideGroom.cs | 7 +- .../Mobiles/Townfolk/EscortableMage.cs | 2 +- Projects/Scripts/Mobiles/Townfolk/Merchant.cs | 2 +- .../Scripts/Mobiles/Townfolk/Messenger.cs | 2 +- Projects/Scripts/Mobiles/Townfolk/Noble.cs | 2 +- Projects/Scripts/Mobiles/Townfolk/Peasant.cs | 2 +- .../Mobiles/Townfolk/SeekerOfAdventure.cs | 9 +- .../Scripts/Mobiles/Townfolk/TownCrier.cs | 9 +- .../Scripts/Mobiles/Vendors/BaseVendor.cs | 126 +- .../Mobiles/Vendors/NPC/AnimalTrainer.cs | 44 +- .../NPC/Guildmasters/BaseGuildmaster.cs | 31 +- .../Mobiles/Vendors/PlayerBarkeeper.cs | 3 +- .../Scripts/Mobiles/Vendors/PlayerVendor.cs | 27 +- .../Scripts/Mobiles/Vendors/RentedVendor.cs | 4 +- .../Mobiles/Vendors/VendorInventory.cs | 5 +- Projects/Scripts/Multis/Boats/BaseBoat.cs | 168 +- .../Multis/Boats/ConfirmDryDockGump.cs | 2 +- Projects/Scripts/Multis/Boats/Packets.cs | 127 + .../Scripts/Multis/Boats/RenameBoatPrompt.cs | 2 - Projects/Scripts/Multis/Boats/Strandedness.cs | 4 +- Projects/Scripts/Multis/DynamicDecay.cs | 2 +- .../Scripts/Multis/{ => Houses}/BaseHouse.cs | 447 +- Projects/Scripts/Multis/{ => Houses}/Deeds.cs | 15 +- .../Multis/{ => Houses}/HouseFoundation.cs | 232 +- .../Multis/{ => Houses}/HousePlacement.cs | 28 +- .../Multis/{ => Houses}/HousePlacementTool.cs | 32 +- .../Scripts/Multis/{ => Houses}/HouseSign.cs | 0 .../Multis/{ => Houses}/HouseTeleporter.cs | 0 .../Scripts/Multis/{ => Houses}/Houses.cs | 2 +- .../Multis/{ => Houses}/MovingCrate.cs | 23 +- Projects/Scripts/Multis/Houses/Packets.cs | 366 ++ .../Multis/{ => Houses}/PreviewHouse.cs | 0 Projects/Scripts/Network/Packets.cs | 24 + Projects/Scripts/Regions/GuardedRegion.cs | 15 +- .../Scripts/Regions/Spawning/SpawnEntry.cs | 4 +- .../Regions/Spawning/SpawnPersistence.cs | 5 +- Projects/Scripts/Scripts.csproj | 1 + Projects/Scripts/Skills/Anatomy.cs | 2 +- Projects/Scripts/Skills/AnimalTaming.cs | 6 +- Projects/Scripts/Skills/Discordance.cs | 5 +- Projects/Scripts/Skills/EvalInt.cs | 3 +- Projects/Scripts/Skills/Hiding.cs | 6 +- Projects/Scripts/Skills/ItemIdentification.cs | 8 +- Projects/Scripts/Skills/SpiritSpeak.cs | 2 +- Projects/Scripts/Skills/Tracking.cs | 4 +- .../SpecialSystems/Engines/TestCenter.cs | 18 +- .../SpecialSystems/Items/Stones/GMStone.cs | 56 - Projects/Scripts/Spells/Base/SpecialMove.cs | 16 +- Projects/Scripts/Spells/Base/SpellHelper.cs | 62 +- .../Scripts/Spells/Bushido/SamuraiSpell.cs | 4 +- .../Scripts/Spells/Chivalry/DispelEvil.cs | 2 +- .../Scripts/Spells/Chivalry/NobleSacrifice.cs | 12 +- .../Scripts/Spells/Chivalry/SacredJourney.cs | 20 - .../Scripts/Spells/Eighth/AirElemental.cs | 2 +- .../Scripts/Spells/Eighth/EarthElemental.cs | 2 +- .../Scripts/Spells/Eighth/FireElemental.cs | 2 +- .../Scripts/Spells/Eighth/SummonDaemon.cs | 2 +- .../Scripts/Spells/Eighth/WaterElemental.cs | 2 +- Projects/Scripts/Spells/Fifth/PoisonField.cs | 11 +- .../Scripts/Spells/Fifth/SummonCreature.cs | 2 +- Projects/Scripts/Spells/First/Clumsy.cs | 2 +- Projects/Scripts/Spells/First/Feeblemind.cs | 2 +- Projects/Scripts/Spells/First/NightSight.cs | 2 +- .../Scripts/Spells/First/ReactiveArmor.cs | 2 +- Projects/Scripts/Spells/First/Weaken.cs | 2 +- Projects/Scripts/Spells/Fourth/ArchCure.cs | 18 +- Projects/Scripts/Spells/Fourth/Curse.cs | 2 +- Projects/Scripts/Spells/Fourth/FireField.cs | 13 +- Projects/Scripts/Spells/Fourth/Lightning.cs | 2 +- .../Spells/Mysticism/HailStormSpell.cs | 8 +- .../Spells/Mysticism/NetherCycloneSpell.cs | 8 +- .../Spells/Mysticism/StoneFormSpell.cs | 3 +- .../Spells/Necromancy/BloodOathSpell.cs | 4 +- .../Scripts/Spells/Necromancy/Exorcism.cs | 5 +- .../Scripts/Spells/Necromancy/PainSpike.cs | 2 +- .../Scripts/Spells/Necromancy/Strangle.cs | 4 +- .../Scripts/Spells/Ninjitsu/AnimalForm.cs | 8 +- Projects/Scripts/Spells/Second/Agility.cs | 2 +- Projects/Scripts/Spells/Second/Cunning.cs | 2 +- Projects/Scripts/Spells/Second/Protection.cs | 2 +- Projects/Scripts/Spells/Second/Strength.cs | 2 +- .../Scripts/Spells/Seventh/ChainLightning.cs | 11 +- .../Scripts/Spells/Seventh/EnergyField.cs | 13 +- Projects/Scripts/Spells/Seventh/GateTravel.cs | 21 +- .../Scripts/Spells/Seventh/MeteorSwarm.cs | 7 +- Projects/Scripts/Spells/Seventh/Polymorph.cs | 1 - Projects/Scripts/Spells/Sixth/Mark.cs | 4 +- .../Scripts/Spells/Sixth/ParalyzeField.cs | 11 +- .../Spells/Spellweaving/AttuneWeapon.cs | 2 +- .../Spells/Spellweaving/EssenceOfWind.cs | 3 +- .../Scripts/Spells/Spellweaving/GiftOfLife.cs | 2 +- .../Spells/Spellweaving/GiftOfRenewal.cs | 2 +- .../Scripts/Spells/Spellweaving/ReaperForm.cs | 6 +- .../Spells/Spellweaving/Thunderstorm.cs | 2 +- .../Spells/Targeting/RecallSpellTarget.cs | 11 +- Projects/Scripts/Spells/Third/Bless.cs | 2 +- Projects/Scripts/Spells/Third/WallOfStone.cs | 11 +- Projects/Server/Diagnostics/BaseProfile.cs | 4 +- Projects/Server/Effects.cs | 301 +- Projects/Server/ExpansionInfo.cs | 3 +- Projects/Server/Geometry.cs | 6 +- Projects/Server/Guild.cs | 34 +- Projects/Server/Gumps/Gump.cs | 260 +- Projects/Server/Gumps/GumpAlphaRegion.cs | 61 +- Projects/Server/Gumps/GumpBackground.cs | 69 +- Projects/Server/Gumps/GumpButton.cs | 105 +- Projects/Server/Gumps/GumpCheck.cs | 89 +- Projects/Server/Gumps/GumpEntry.cs | 37 +- Projects/Server/Gumps/GumpGroup.cs | 25 +- Projects/Server/Gumps/GumpHtml.cs | 96 +- Projects/Server/Gumps/GumpHtmlLocalized.cs | 220 +- Projects/Server/Gumps/GumpImage.cs | 76 +- Projects/Server/Gumps/GumpImageTileButton.cs | 176 +- Projects/Server/Gumps/GumpImageTiled.cs | 73 +- Projects/Server/Gumps/GumpItem.cs | 73 +- Projects/Server/Gumps/GumpItemProperty.cs | 26 +- Projects/Server/Gumps/GumpLabel.cs | 63 +- Projects/Server/Gumps/GumpLabelCropped.cs | 88 +- Projects/Server/Gumps/GumpPage.cs | 26 +- Projects/Server/Gumps/GumpRadio.cs | 92 +- Projects/Server/Gumps/GumpTextEntry.cs | 104 +- Projects/Server/Gumps/GumpTextEntryLimited.cs | 110 +- Projects/Server/Gumps/GumpTooltip.cs | 26 +- Projects/Server/HuePicker.cs | 10 +- Projects/Server/IAccount.cs | 2 +- Projects/Server/Insensitive.cs | 14 +- Projects/Server/Interfaces.cs | 7 +- Projects/Server/Item.cs | 364 +- Projects/Server/Items/Container.cs | 63 +- Projects/Server/Items/Containers.cs | 9 +- Projects/Server/Items/SecureTradeContainer.cs | 1 - Projects/Server/Items/VirtualCheck.cs | 9 +- Projects/Server/Items/VirtualHair.cs | 20 +- Projects/Server/Layer.cs | 20 + Projects/Server/LightType.cs | 20 + Projects/Server/Main.cs | 144 +- Projects/Server/Map.cs | 147 +- Projects/Server/Menus/IMenu.cs | 4 +- Projects/Server/Menus/ItemListMenu.cs | 17 +- Projects/Server/Menus/QuestionMenu.cs | 17 +- Projects/Server/Mobile.cs | 2031 +++----- Projects/Server/Movement.cs | 2 +- Projects/Server/Network/Listener.cs | 13 +- Projects/Server/Network/NetState.cs | 134 +- Projects/Server/Network/Packet.cs | 267 -- Projects/Server/Network/PacketHandlers.cs | 536 +-- Projects/Server/Network/PacketReader.cs | 306 +- Projects/Server/Network/PacketWriter.cs | 346 -- Projects/Server/Network/Packets.cs | 4170 ----------------- Projects/Server/Network/Packets/Accounts.cs | 325 ++ Projects/Server/Network/Packets/Arrow.cs | 69 + Projects/Server/Network/Packets/Attributes.cs | 168 + Projects/Server/Network/Packets/Containers.cs | 217 + Projects/Server/Network/Packets/Damage.cs | 61 + Projects/Server/Network/Packets/Effects.cs | 283 ++ Projects/Server/Network/Packets/Gumps.cs | 94 + Projects/Server/Network/Packets/Items.cs | 330 ++ Projects/Server/Network/Packets/Map.cs | 72 + Projects/Server/Network/Packets/Menus.cs | 235 + Projects/Server/Network/Packets/Messages.cs | 161 + Projects/Server/Network/Packets/Mobiles.cs | 959 ++++ Projects/Server/Network/Packets/Player.cs | 550 +++ Projects/Server/Network/Packets/Profile.cs | 29 + Projects/Server/Network/Packets/Targeting.cs | 81 + Projects/Server/Network/Packets/Trade.cs | 139 + Projects/Server/Network/Packets/Vendors.cs | 207 + .../Server/Network/Packets/VirtualHair.cs | 78 + Projects/Server/Network/SendQueue.cs | 44 - Projects/Server/Network/ServerInfo.cs | 24 + Projects/Server/Network/SocketExtensions.cs | 4 +- .../Server/Network/StaticPacketHandlers.cs | 135 - Projects/Server/Notoriety.cs | 24 +- Projects/Server/ObjectPropertyList.cs | 138 +- .../Server/Persistence/BinaryMemoryWriter.cs | 2 +- .../Server/Persistence/DualSaveStrategy.cs | 2 +- .../Server/Persistence/DynamicSaveStrategy.cs | 3 +- Projects/Server/Persistence/FileOperations.cs | 14 +- Projects/Server/Persistence/FileQueue.cs | 15 +- .../Persistence/ParallelSaveStrategy.cs | 3 +- Projects/Server/Persistence/Persistence.cs | 2 +- .../Server/Persistence/QueuedMemoryWriter.cs | 2 +- Projects/Server/Persistence/SaveStrategy.cs | 2 +- .../Persistence/SequentialFileWriter.cs | 2 +- .../Persistence/StandardSaveStrategy.cs | 7 +- Projects/Server/Prompt.cs | 8 +- Projects/Server/QuestArrow.cs | 10 +- Projects/Server/Region.cs | 41 +- Projects/Server/Sector.cs | 3 +- Projects/Server/SecureTrade.cs | 93 +- Projects/Server/Serial.cs | 4 +- Projects/Server/Serialization.cs | 16 +- Projects/Server/Server.csproj | 4 + Projects/Server/Skills.cs | 6 +- Projects/Server/Targeting/MultiTarget.cs | 11 +- Projects/Server/Targeting/Target.cs | 6 +- Projects/Server/TileData.cs | 7 +- Projects/Server/TileMatrix.cs | 24 +- Projects/Server/Timer.cs | 38 +- Projects/Server/Utility.cs | 89 +- Projects/Server/VirtueInfo.cs | 5 +- Projects/Server/World.cs | 45 +- 588 files changed, 10843 insertions(+), 16177 deletions(-) create mode 100644 Projects/Scripts/Engines/MyRunUO/LayerComparer.cs delete mode 100644 Projects/Scripts/Engines/Plants/Network/DisplayHelpTopic.cs create mode 100644 Projects/Scripts/Items/Books/Packets.cs create mode 100644 Projects/Scripts/Items/Equipment/EquipmentInfoAttribute.cs create mode 100644 Projects/Scripts/Items/Equipment/Packets.cs create mode 100644 Projects/Scripts/Items/Maps/Packets.cs rename Projects/Scripts/{Items/Special/Solen Items => Misc}/MessageHelper.cs (58%) create mode 100644 Projects/Scripts/Multis/Boats/Packets.cs rename Projects/Scripts/Multis/{ => Houses}/BaseHouse.cs (88%) rename Projects/Scripts/Multis/{ => Houses}/Deeds.cs (94%) rename Projects/Scripts/Multis/{ => Houses}/HouseFoundation.cs (90%) rename Projects/Scripts/Multis/{ => Houses}/HousePlacement.cs (90%) rename Projects/Scripts/Multis/{ => Houses}/HousePlacementTool.cs (96%) rename Projects/Scripts/Multis/{ => Houses}/HouseSign.cs (100%) rename Projects/Scripts/Multis/{ => Houses}/HouseTeleporter.cs (100%) rename Projects/Scripts/Multis/{ => Houses}/Houses.cs (96%) rename Projects/Scripts/Multis/{ => Houses}/MovingCrate.cs (88%) create mode 100644 Projects/Scripts/Multis/Houses/Packets.cs rename Projects/Scripts/Multis/{ => Houses}/PreviewHouse.cs (100%) create mode 100644 Projects/Scripts/Network/Packets.cs delete mode 100644 Projects/Scripts/SpecialSystems/Items/Stones/GMStone.cs delete mode 100644 Projects/Server/Network/Packet.cs delete mode 100644 Projects/Server/Network/PacketWriter.cs delete mode 100644 Projects/Server/Network/Packets.cs create mode 100644 Projects/Server/Network/Packets/Accounts.cs create mode 100644 Projects/Server/Network/Packets/Arrow.cs create mode 100644 Projects/Server/Network/Packets/Attributes.cs create mode 100644 Projects/Server/Network/Packets/Containers.cs create mode 100644 Projects/Server/Network/Packets/Damage.cs create mode 100644 Projects/Server/Network/Packets/Effects.cs create mode 100644 Projects/Server/Network/Packets/Gumps.cs create mode 100644 Projects/Server/Network/Packets/Items.cs create mode 100644 Projects/Server/Network/Packets/Map.cs create mode 100644 Projects/Server/Network/Packets/Menus.cs create mode 100644 Projects/Server/Network/Packets/Messages.cs create mode 100644 Projects/Server/Network/Packets/Mobiles.cs create mode 100644 Projects/Server/Network/Packets/Player.cs create mode 100644 Projects/Server/Network/Packets/Profile.cs create mode 100644 Projects/Server/Network/Packets/Targeting.cs create mode 100644 Projects/Server/Network/Packets/Trade.cs create mode 100644 Projects/Server/Network/Packets/Vendors.cs create mode 100644 Projects/Server/Network/Packets/VirtualHair.cs delete mode 100644 Projects/Server/Network/SendQueue.cs create mode 100644 Projects/Server/Network/ServerInfo.cs delete mode 100644 Projects/Server/Network/StaticPacketHandlers.cs diff --git a/GOALS.md b/GOALS.md index c70e89d09..1e4b2d13f 100644 --- a/GOALS.md +++ b/GOALS.md @@ -7,8 +7,8 @@ - [X] Support configuration via a `modernuo.json` file ### Networking -- [ ] Replace Packet classes with functions -- [ ] Improve asynchronous socket handling using Pipes +- [X] Replace Packet classes with functions +- [X] Improve asynchronous socket handling using Pipes - [ ] Improve socket handling (2-5x) and event loop using libuv ### Administration diff --git a/ModernUO.sln b/ModernUO.sln index deab80f56..cdd102acb 100644 --- a/ModernUO.sln +++ b/ModernUO.sln @@ -3,9 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.29102.190 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Server", "Projects\Server\Server.csproj", "{5E93BB35-3661-4822-9A8A-859726BAD87F}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Server", "Projects\Server\Server.csproj", "{9514A3D3-5C0F-4EE0-B168-67C3F50DC225}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Scripts", "Projects\Scripts\Scripts.csproj", "{83CF2484-BCCB-4B7C-9C5F-7AB43AEA5E8F}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Scripts", "Projects\Scripts\Scripts.csproj", "{BF29C43A-A539-448D-93DB-D7CBE13BACFE}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -13,14 +13,14 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {5E93BB35-3661-4822-9A8A-859726BAD87F}.Debug|Any CPU.ActiveCfg = Release|Any CPU - {5E93BB35-3661-4822-9A8A-859726BAD87F}.Debug|Any CPU.Build.0 = Release|Any CPU - {5E93BB35-3661-4822-9A8A-859726BAD87F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5E93BB35-3661-4822-9A8A-859726BAD87F}.Release|Any CPU.Build.0 = Release|Any CPU - {83CF2484-BCCB-4B7C-9C5F-7AB43AEA5E8F}.Debug|Any CPU.ActiveCfg = Release|Any CPU - {83CF2484-BCCB-4B7C-9C5F-7AB43AEA5E8F}.Debug|Any CPU.Build.0 = Release|Any CPU - {83CF2484-BCCB-4B7C-9C5F-7AB43AEA5E8F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {83CF2484-BCCB-4B7C-9C5F-7AB43AEA5E8F}.Release|Any CPU.Build.0 = Release|Any CPU + {9514A3D3-5C0F-4EE0-B168-67C3F50DC225}.Debug|Any CPU.ActiveCfg = Release|Any CPU + {9514A3D3-5C0F-4EE0-B168-67C3F50DC225}.Debug|Any CPU.Build.0 = Release|Any CPU + {9514A3D3-5C0F-4EE0-B168-67C3F50DC225}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9514A3D3-5C0F-4EE0-B168-67C3F50DC225}.Release|Any CPU.Build.0 = Release|Any CPU + {BF29C43A-A539-448D-93DB-D7CBE13BACFE}.Debug|Any CPU.ActiveCfg = Release|Any CPU + {BF29C43A-A539-448D-93DB-D7CBE13BACFE}.Debug|Any CPU.Build.0 = Release|Any CPU + {BF29C43A-A539-448D-93DB-D7CBE13BACFE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BF29C43A-A539-448D-93DB-D7CBE13BACFE}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Projects/Scripts/Accounting/Account.cs b/Projects/Scripts/Accounting/Account.cs index 8ff0ab711..ced955f02 100644 --- a/Projects/Scripts/Accounting/Account.cs +++ b/Projects/Scripts/Accounting/Account.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Net; using System.Security.Cryptography; using System.Text; diff --git a/Projects/Scripts/Accounting/AccountAttackLimiter.cs b/Projects/Scripts/Accounting/AccountAttackLimiter.cs index f302c22f3..a5b797bca 100644 --- a/Projects/Scripts/Accounting/AccountAttackLimiter.cs +++ b/Projects/Scripts/Accounting/AccountAttackLimiter.cs @@ -61,8 +61,7 @@ namespace Server.Accounting InvalidAccountAccessLog accessLog = FindAccessLog(ns); - if (accessLog == null) - m_List.Add(accessLog = new InvalidAccountAccessLog(ns.Address)); + m_List.Add(accessLog ??= new InvalidAccountAccessLog(ns.Address)); accessLog.Counts += 1; accessLog.RefreshAccessTime(); diff --git a/Projects/Scripts/Accounting/AccountHandler.cs b/Projects/Scripts/Accounting/AccountHandler.cs index 31c131b6a..459b173bd 100644 --- a/Projects/Scripts/Accounting/AccountHandler.cs +++ b/Projects/Scripts/Accounting/AccountHandler.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Net; using Server.Accounting; using Server.Engines.Help; @@ -176,8 +177,8 @@ namespace Server.Misc from.SendLocalizedMessage(501234, "", 0x35); /* The next available Counselor/Game Master will respond as soon as possible. - * Please check your Journal for messages every few minutes. - */ + * Please check your Journal for messages every few minutes. + */ PageQueue.Enqueue(new PageEntry(from, $"[Automated: Change Password]
Desired password: {pass}
Current IP address: {ipAddress}
Account IP address: {accessList[0]}", @@ -199,38 +200,27 @@ namespace Server.Misc if (!(state.Account is Account acct)) { state.Dispose(); + return; } - else if (index < 0 || index >= acct.Length) - { - state.Send(new DeleteResult(DeleteResultType.BadRequest)); - state.Send(new CharacterListUpdate(acct)); - } + + DeleteResultType deleteType; + + if (index < 0 || index >= acct.Length) + deleteType = DeleteResultType.BadRequest; else { Mobile m = acct[index]; if (m == null) - { - state.Send(new DeleteResult(DeleteResultType.CharNotExist)); - state.Send(new CharacterListUpdate(acct)); - } + deleteType = DeleteResultType.CharNotExist; else if (m.NetState != null) - { - state.Send(new DeleteResult(DeleteResultType.CharBeingPlayed)); - state.Send(new CharacterListUpdate(acct)); - } + deleteType = DeleteResultType.CharBeingPlayed; else if (RestrictDeletion && DateTime.UtcNow < m.CreationTime + DeleteDelay) - { - state.Send(new DeleteResult(DeleteResultType.CharTooYoung)); - state.Send(new CharacterListUpdate(acct)); - } + deleteType = DeleteResultType.CharTooYoung; else if (m.AccessLevel == AccessLevel.Player && Region.Find(m.LogoutLocation, m.LogoutMap).IsPartOf() ) //Don't need to check current location, if netstate is null, they're logged out - { - state.Send(new DeleteResult(DeleteResultType.BadRequest)); - state.Send(new CharacterListUpdate(acct)); - } + deleteType = DeleteResultType.BadRequest; else { Console.WriteLine("Client: {0}: Deleting character {1} (0x{2:X})", state, index, m.Serial.Value); @@ -238,27 +228,18 @@ namespace Server.Misc acct.Comments.Add(new AccountComment("System", $"Character #{index + 1} {m} deleted by {state}")); m.Delete(); - state.Send(new CharacterListUpdate(acct)); + Packets.SendCharacterListUpdate(state, acct); + return; } } + + Packets.SendDeleteResult(state, deleteType); + Packets.SendCharacterListUpdate(state, acct); } - public static bool CanCreate(IPAddress ip) - { - if (!IPTable.ContainsKey(ip)) - return true; + public static bool CanCreate(IPAddress ip) => !IPTable.ContainsKey(ip) || IPTable[ip] < MaxAccountsPerIP; - return IPTable[ip] < MaxAccountsPerIP; - } - - private static bool IsForbiddenChar(char c) - { - for (int i = 0; i < m_ForbiddenChars.Length; ++i) - if (c == m_ForbiddenChars[i]) - return true; - - return false; - } + private static bool IsForbiddenChar(char c) => m_ForbiddenChars.Any(t => c == t); private static Account CreateAccount(NetState state, string un, string pw) { @@ -377,9 +358,7 @@ namespace Server.Misc string pw = e.Password; if (!(Accounts.GetAccount(un) is Account acct)) - { e.Accepted = false; - } else if (!acct.HasAccess(e.State)) { Console.WriteLine("Login: {0}: Access denied for '{1}'", e.State, un); diff --git a/Projects/Scripts/Accounting/Accounts.cs b/Projects/Scripts/Accounting/Accounts.cs index 8bf7e5446..d5d01b165 100644 --- a/Projects/Scripts/Accounting/Accounts.cs +++ b/Projects/Scripts/Accounting/Accounts.cs @@ -90,4 +90,4 @@ namespace Server.Accounting xml.Close(); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Accounting/Firewall.cs b/Projects/Scripts/Accounting/Firewall.cs index 4946ff9c6..d7de42822 100644 --- a/Projects/Scripts/Accounting/Firewall.cs +++ b/Projects/Scripts/Accounting/Firewall.cs @@ -191,9 +191,7 @@ namespace Server return otherAddress.Equals(m_Address); } else if (obj is IPFirewallEntry entry) - { return m_Address.Equals(entry.m_Address); - } return false; } @@ -246,7 +244,7 @@ namespace Server public WildcardIPFirewallEntry(string entry) => m_Entry = entry; - public bool IsBlocked(IPAddress address) + bool IFirewallEntry.IsBlocked(IPAddress address) { if (!m_Valid) return false; //Why process if it's invalid? it'll return false anyway after processing it. diff --git a/Projects/Scripts/Commands/Add.cs b/Projects/Scripts/Commands/Add.cs index 60e144037..9948d1c39 100644 --- a/Projects/Scripts/Commands/Add.cs +++ b/Projects/Scripts/Commands/Add.cs @@ -7,7 +7,7 @@ using CPA = Server.CommandPropertyAttribute; namespace Server.Commands { - public class Add + public static class Add { private static Type m_EntityType = typeof(IEntity); diff --git a/Projects/Scripts/Commands/Batch.cs b/Projects/Scripts/Commands/Batch.cs index 89e703c5e..9abef7a59 100644 --- a/Projects/Scripts/Commands/Batch.cs +++ b/Projects/Scripts/Commands/Batch.cs @@ -120,8 +120,7 @@ namespace Server.Commands command.ExecuteList(eventArgs[i], usedList); - if (list.Count > 20) - CommandLogging.Enabled = true; + CommandLogging.Enabled |= list.Count > 20; command.Flush(e.Mobile, list.Count > 20); } diff --git a/Projects/Scripts/Commands/BoundingBoxPicker.cs b/Projects/Scripts/Commands/BoundingBoxPicker.cs index d95156919..29b0913bd 100644 --- a/Projects/Scripts/Commands/BoundingBoxPicker.cs +++ b/Projects/Scripts/Commands/BoundingBoxPicker.cs @@ -1,6 +1,6 @@ using Server.Targeting; -namespace Server +namespace Server.Commands { public delegate void BoundingBoxCallback(Map map, Point3D start, Point3D end); @@ -60,4 +60,4 @@ namespace Server } } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Commands/ConvertPlayers.cs b/Projects/Scripts/Commands/ConvertPlayers.cs index 5dacd925e..c37c971cb 100644 --- a/Projects/Scripts/Commands/ConvertPlayers.cs +++ b/Projects/Scripts/Commands/ConvertPlayers.cs @@ -7,7 +7,7 @@ using Server.Network; namespace Server.Commands { - public class ConvertPlayers + public static class ConvertPlayers { public static void Initialize() { diff --git a/Projects/Scripts/Commands/Decorate.cs b/Projects/Scripts/Commands/Decorate.cs index 5475fb6eb..4debc22a7 100644 --- a/Projects/Scripts/Commands/Decorate.cs +++ b/Projects/Scripts/Commands/Decorate.cs @@ -9,7 +9,7 @@ using Server.Mobiles; namespace Server.Commands { - public class Decorate + public static class Decorate { private static Mobile m_Mobile; private static int m_Count; @@ -878,9 +878,7 @@ namespace Server.Commands res = true; } else if ((item.ItemData.Flags & TileFlag.LightSource) != 0 && item.ItemData.Name == srcName) - { m_DeleteQueue.Enqueue(item); - } } } else if (srcItem is Teleporter || srcItem is FillableContainer || srcItem is BaseBook) diff --git a/Projects/Scripts/Commands/DecorateMag.cs b/Projects/Scripts/Commands/DecorateMag.cs index 38997aaad..4f0ba1386 100644 --- a/Projects/Scripts/Commands/DecorateMag.cs +++ b/Projects/Scripts/Commands/DecorateMag.cs @@ -10,7 +10,7 @@ using Server.Mobiles; namespace Server.Commands { - public class DecorateMag + public static class DecorateMag { private static Mobile m_Mobile; private static int m_Count; diff --git a/Projects/Scripts/Commands/Docs.cs b/Projects/Scripts/Commands/Docs.cs index c0e1fd763..152b1f31e 100644 --- a/Projects/Scripts/Commands/Docs.cs +++ b/Projects/Scripts/Commands/Docs.cs @@ -82,9 +82,7 @@ namespace Server.Commands if (baseInfo == null) m_Types[baseType] = baseInfo = new TypeInfo(baseType); - if (baseInfo.m_Derived == null) - baseInfo.m_Derived = new List(); - + baseInfo.m_Derived ??= new List(); baseInfo.m_Derived.Add(info); } @@ -97,9 +95,7 @@ namespace Server.Commands if (decInfo == null) m_Types[decType] = decInfo = new TypeInfo(decType); - if (decInfo.m_Nested == null) - decInfo.m_Nested = new List(); - + decInfo.m_Nested ??= new List(); decInfo.m_Nested.Add(info); } @@ -115,9 +111,7 @@ namespace Server.Commands if (ifaceInfo == null) m_Types[iface] = ifaceInfo = new TypeInfo(iface); - if (ifaceInfo.m_Derived == null) - ifaceInfo.m_Derived = new List(); - + ifaceInfo.m_Derived ??= new List(); ifaceInfo.m_Derived.Add(info); } } @@ -644,6 +638,7 @@ namespace Server.Commands m_Namespaces = new Dictionary>(); List assemblies = new List { Core.Assembly }; + assemblies.AddRange(AssemblyHandler.Assemblies); foreach (Assembly asm in AssemblyHandler.Assemblies) @@ -1163,37 +1158,21 @@ namespace Server.Commands Item item = items[i].Construct(); if (item is Sandals) - { rewards[5] = true; - } else if (item is SmallStretchedHideEastDeed || item is SmallStretchedHideSouthDeed) - { rewards[10] = rewards[11] = true; - } else if (item is MediumStretchedHideEastDeed || item is MediumStretchedHideSouthDeed) - { rewards[10] = rewards[11] = true; - } else if (item is LightFlowerTapestryEastDeed || item is LightFlowerTapestrySouthDeed) - { rewards[12] = rewards[13] = true; - } else if (item is DarkFlowerTapestryEastDeed || item is DarkFlowerTapestrySouthDeed) - { rewards[12] = rewards[13] = true; - } else if (item is BrownBearRugEastDeed || item is BrownBearRugSouthDeed) - { rewards[14] = rewards[15] = true; - } else if (item is PolarBearRugEastDeed || item is PolarBearRugSouthDeed) - { rewards[14] = rewards[15] = true; - } else if (item is ClothingBlessDeed) - { rewards[16] = true; - } else if (item is PowerScroll ps) { if (ps.Value == 105.0) @@ -1218,10 +1197,7 @@ namespace Server.Commands else rewards[4] = true; } - else if (item is RunicSewingKit rkit) - { - rewards[16 + CraftResources.GetIndex(rkit.Resource)] = true; - } + else if (item is RunicSewingKit rkit) rewards[16 + CraftResources.GetIndex(rkit.Resource)] = true; item.Delete(); } @@ -1439,37 +1415,21 @@ namespace Server.Commands Item item = items[i].Construct(); if (item is SturdyPickaxe || item is SturdyShovel) - { rewards[0] = true; - } else if (item is LeatherGlovesOfMining) - { rewards[1] = true; - } else if (item is StuddedGlovesOfMining) - { rewards[2] = true; - } else if (item is RingmailGlovesOfMining) - { rewards[3] = true; - } else if (item is GargoylesPickaxe) - { rewards[4] = true; - } else if (item is ProspectorsTool) - { rewards[5] = true; - } else if (item is PowderOfTemperament) - { rewards[6] = true; - } else if (item is ColoredAnvil) - { rewards[7] = true; - } else if (item is PowerScroll ps) { if (ps.Value == 105.0) @@ -1482,9 +1442,7 @@ namespace Server.Commands rewards[11] = true; } else if (item is RunicHammer rh) - { rewards[11 + CraftResources.GetIndex(rh.Resource)] = true; - } else if (item is AncientSmithyHammer ash) { if (ash.Bonus == 10) diff --git a/Projects/Scripts/Commands/GenTeleporter.cs b/Projects/Scripts/Commands/GenTeleporter.cs index 1c42392d7..a9e5e4497 100644 --- a/Projects/Scripts/Commands/GenTeleporter.cs +++ b/Projects/Scripts/Commands/GenTeleporter.cs @@ -3,7 +3,7 @@ using Server.Items; namespace Server.Commands { - public class GenTeleporter + public static class GenTeleporter { public static void Initialize() { @@ -282,7 +282,7 @@ namespace Server.Commands CreateTeleporter(2758, 2092, -20, 2756, 2097, 38, map, false); CreateTeleporter(2759, 2092, -20, 2756, 2097, 38, map, false); CreateTeleporter(2685, 2063, 39, 2685, 2063, -20, map, - false); // that should not be a teleporter: on OSI you simply fall under the ground + false); // that should not be a teleporter: on OSI you simply fall under the ground // Misc CreateTeleporter(5217, 18, 15, 5204, 74, 17, map, false); @@ -597,7 +597,7 @@ namespace Server.Commands CreateTeleporter(11, 1519, -27, 11, 873, -28, map, false); CreateTeleporter(12, 1519, -27, 12, 873, -27, map, false); - // Ratman Lair + // Ratman Lair CreateTeleporter(636, 813, -62, 164, 743, -28, map, false); CreateTeleporter(164, 746, -16, 636, 815, -52, map, false); @@ -775,47 +775,47 @@ namespace Server.Commands CreateTeleporter(548, 455, -40, 428, 113, -28, map, true); CreateTeleporter(429, 113, -28, 548, 455, -40, map, false); - CreateTeleporter(242, 27, -16, 372, 31, -31, map, false); // stairs - 0x754 - CreateTeleporter(242, 26, -16, 372, 30, -31, map, false); // stairs - 0x754 - CreateTeleporter(242, 25, -16, 372, 29, -31, map, false); // stairs - 0x754 - CreateTeleporter(371, 31, -36, 241, 27, -18, map, false); // stairs - 0x754 - CreateTeleporter(371, 30, -36, 241, 26, -18, map, false); // stairs - 0x754 + CreateTeleporter(242, 27, -16, 372, 31, -31, map, false); // stairs - 0x754 + CreateTeleporter(242, 26, -16, 372, 30, -31, map, false); // stairs - 0x754 + CreateTeleporter(242, 25, -16, 372, 29, -31, map, false); // stairs - 0x754 + CreateTeleporter(371, 31, -36, 241, 27, -18, map, false); // stairs - 0x754 + CreateTeleporter(371, 30, -36, 241, 26, -18, map, false); // stairs - 0x754 DestroyTeleporter(371, 29, -36, map); //To remove old erroneous teleporter CreateTeleporter(371, 29, -36, 241, 25, -18, map, false); // stairs - 0x754 - CreateTeleporter(272, 141, -16, 555, 427, -1, map, false); // stairs - 1st 0x753 - CreateTeleporter(273, 141, -16, 556, 427, -1, map, false); // stairs - 1st 0x753 - CreateTeleporter(274, 141, -16, 557, 427, -1, map, false); // stairs - 1st 0x753 - CreateTeleporter(555, 426, -6, 272, 140, -21, map, false); // stairs - 1st 0x753 - CreateTeleporter(556, 426, -6, 273, 140, -21, map, false); // stairs - 1st 0x753 - CreateTeleporter(557, 426, -6, 274, 140, -21, map, false); // stairs - 1st 0x753 + CreateTeleporter(272, 141, -16, 555, 427, -1, map, false); // stairs - 1st 0x753 + CreateTeleporter(273, 141, -16, 556, 427, -1, map, false); // stairs - 1st 0x753 + CreateTeleporter(274, 141, -16, 557, 427, -1, map, false); // stairs - 1st 0x753 + CreateTeleporter(555, 426, -6, 272, 140, -21, map, false); // stairs - 1st 0x753 + CreateTeleporter(556, 426, -6, 273, 140, -21, map, false); // stairs - 1st 0x753 + CreateTeleporter(557, 426, -6, 274, 140, -21, map, false); // stairs - 1st 0x753 - CreateTeleporter(265, 130, -31, 284, 72, -21, map, false); // stairs - 0x753 - CreateTeleporter(266, 130, -31, 285, 72, -21, map, false); // stairs - 0x753 - CreateTeleporter(267, 130, -31, 286, 72, -21, map, false); // stairs - 0x753 - CreateTeleporter(268, 130, -31, 287, 72, -21, map, false); // stairs - 0x753 - CreateTeleporter(284, 73, -16, 265, 131, -28, map, false); // stairs - 0x753 - CreateTeleporter(285, 73, -16, 266, 131, -28, map, false); // stairs - 0x753 - CreateTeleporter(286, 73, -16, 267, 131, -28, map, false); // stairs - 0x753 - CreateTeleporter(287, 73, -16, 268, 131, -28, map, false); // stairs - 0x753 + CreateTeleporter(265, 130, -31, 284, 72, -21, map, false); // stairs - 0x753 + CreateTeleporter(266, 130, -31, 285, 72, -21, map, false); // stairs - 0x753 + CreateTeleporter(267, 130, -31, 286, 72, -21, map, false); // stairs - 0x753 + CreateTeleporter(268, 130, -31, 287, 72, -21, map, false); // stairs - 0x753 + CreateTeleporter(284, 73, -16, 265, 131, -28, map, false); // stairs - 0x753 + CreateTeleporter(285, 73, -16, 266, 131, -28, map, false); // stairs - 0x753 + CreateTeleporter(286, 73, -16, 267, 131, -28, map, false); // stairs - 0x753 + CreateTeleporter(287, 73, -16, 268, 131, -28, map, false); // stairs - 0x753 - CreateTeleporter(284, 67, -30, 131, 128, -21, map, false); // stairs - 0x753 - CreateTeleporter(285, 67, -30, 132, 128, -21, map, false); // stairs - 0x753 - CreateTeleporter(286, 67, -30, 133, 128, -21, map, false); // stairs - 0x753 - CreateTeleporter(287, 67, -30, 134, 128, -21, map, false); // stairs - 0x753 - CreateTeleporter(131, 129, -16, 284, 68, -28, map, false); // stairs - 0x753 - CreateTeleporter(132, 129, -16, 285, 68, -28, map, false); // stairs - 0x753 - CreateTeleporter(133, 129, -16, 286, 68, -28, map, false); // stairs - 0x753 - CreateTeleporter(134, 129, -16, 287, 68, -28, map, false); // stairs - 0x753 + CreateTeleporter(284, 67, -30, 131, 128, -21, map, false); // stairs - 0x753 + CreateTeleporter(285, 67, -30, 132, 128, -21, map, false); // stairs - 0x753 + CreateTeleporter(286, 67, -30, 133, 128, -21, map, false); // stairs - 0x753 + CreateTeleporter(287, 67, -30, 134, 128, -21, map, false); // stairs - 0x753 + CreateTeleporter(131, 129, -16, 284, 68, -28, map, false); // stairs - 0x753 + CreateTeleporter(132, 129, -16, 285, 68, -28, map, false); // stairs - 0x753 + CreateTeleporter(133, 129, -16, 286, 68, -28, map, false); // stairs - 0x753 + CreateTeleporter(134, 129, -16, 287, 68, -28, map, false); // stairs - 0x753 - CreateTeleporter(358, 40, -36, 156, 88, -18, map, false); // stairs - 0x73A - CreateTeleporter(358, 41, -36, 156, 89, -18, map, false); // stairs - 0x73A - CreateTeleporter(358, 42, -36, 156, 90, -18, map, false); // stairs - 0x73A - CreateTeleporter(155, 88, -16, 357, 40, -31, map, false); // stairs - 0x73A - CreateTeleporter(155, 89, -16, 357, 41, -31, map, false); // stairs - 0x73A - CreateTeleporter(155, 90, -16, 357, 42, -31, map, false); // stairs - 0x73A + CreateTeleporter(358, 40, -36, 156, 88, -18, map, false); // stairs - 0x73A + CreateTeleporter(358, 41, -36, 156, 89, -18, map, false); // stairs - 0x73A + CreateTeleporter(358, 42, -36, 156, 90, -18, map, false); // stairs - 0x73A + CreateTeleporter(155, 88, -16, 357, 40, -31, map, false); // stairs - 0x73A + CreateTeleporter(155, 89, -16, 357, 41, -31, map, false); // stairs - 0x73A + CreateTeleporter(155, 90, -16, 357, 42, -31, map, false); // stairs - 0x73A CreateTeleporter(259, 90, -28, 236, 113, -28, map, true); @@ -923,7 +923,7 @@ namespace Server.Commands public void CreateTeleportersMap3(Map map) { - // CreateTeleporter( 408, 254, 2, 428, 319, 2, map, false ); // for doom quest; use blockers to avoid players teleporting into the ship! + // CreateTeleporter( 408, 254, 2, 428, 319, 2, map, false ); // for doom quest; use blockers to avoid players teleporting into the ship! // CreateTeleporter( 428, 321, 2, 422, 328, -1, map, false ); // for doom quest; use blockers to avoid players teleporting into the ship! // Doom Dungeon @@ -1040,4 +1040,4 @@ namespace Server.Commands } } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Commands/Generic/Commands/Commands.cs b/Projects/Scripts/Commands/Generic/Commands/Commands.cs index 95e7de3f7..c0718109c 100644 --- a/Projects/Scripts/Commands/Generic/Commands/Commands.cs +++ b/Projects/Scripts/Commands/Generic/Commands/Commands.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Server.Accounting; using Server.Engines.Help; using Server.Factions; @@ -12,7 +13,7 @@ using Server.Spells; namespace Server.Commands.Generic { - public class TargetCommands + public static class TargetCommands { public static List AllCommands{ get; } = new List(); @@ -185,10 +186,7 @@ namespace Server.Commands.Generic public override void ExecuteList(CommandEventArgs e, List list) { - if (list.Count == 1) - AddResponse("There is one matching object."); - else - AddResponse($"There are {list.Count} matching objects."); + AddResponse(list.Count == 1 ? "There is one matching object." : $"There are {list.Count} matching objects."); } } @@ -234,9 +232,7 @@ namespace Server.Commands.Generic NetState ns = mob.NetState; if (ns == null) - { LogFailure("That player is not online."); - } else { string url = e.GetString(0); @@ -244,10 +240,7 @@ namespace Server.Commands.Generic CommandLogging.WriteLine(from, "{0} {1} requesting to open web browser of {2} to {3}", from.AccessLevel, CommandLogging.Format(from), CommandLogging.Format(mob), url); - if (echo) - AddResponse("Awaiting user confirmation..."); - else - AddResponse("Open web browser request sent."); + AddResponse(echo ? "Awaiting user confirmation..." : "Open web browser request sent."); mob.SendGump(new WarningGump(1060637, 30720, $"A game master is requesting to open your web browser to the following URL:
{url}", 0xFFC000, @@ -255,14 +248,10 @@ namespace Server.Commands.Generic } } else - { LogFailure("That is not a player."); - } } else - { LogFailure("Format: OpenBrowser "); - } } public override void Execute(CommandEventArgs e, object obj) @@ -336,7 +325,7 @@ namespace Server.Commands.Generic CommandLogging.WriteLine(from, "{0} {1} playing sound {2} for {3}", from.AccessLevel, CommandLogging.Format(from), index, CommandLogging.Format(mob)); - mob.Send(new PlaySound(index, mob.Location)); + Packets.SendPlaySound(mob.NetState, index, mob.Location); } else { @@ -458,14 +447,10 @@ namespace Server.Commands.Generic e.Mobile.SendGump(new AddGump(e.Mobile, match, 0, Type.EmptyTypes, false)); } else - { e.Mobile.SendGump(new AddGump(e.Mobile, match, 0, AddGump.Match(match).ToArray(), true)); - } } else - { return true; - } } else { @@ -634,19 +619,9 @@ namespace Server.Commands.Generic public override void Execute(CommandEventArgs e, object obj) { - if (obj == null) - { - AddResponse("The object is null."); - } - else - { - Type type = obj.GetType(); - - if (type.DeclaringType == null) - AddResponse($"The type of that object is {type.Name}."); - else - AddResponse($"The type of that object is {type.FullName}."); - } + AddResponse(obj == null ? + "The object is null." : + $"The type of that object is {obj.GetType().FullName}."); } } @@ -860,13 +835,9 @@ namespace Server.Commands.Generic if (m_Value) { if (!mob.Alive) - { LogFailure("They are already dead."); - } else if (!mob.CanBeDamaged()) - { LogFailure("They cannot be harmed."); - } else { CommandLogging.WriteLine(from, "{0} {1} killing {2}", from.AccessLevel, CommandLogging.Format(from), @@ -960,10 +931,7 @@ namespace Server.Commands.Generic m.PlaySound(0x228); m.Hidden = m_Value; - if (m_Value) - AddResponse("They have been hidden."); - else - AddResponse("They have been revealed."); + AddResponse(m_Value ? "They have been hidden." : "They have been revealed."); } } @@ -1002,9 +970,7 @@ namespace Server.Commands.Generic } } else - { LogFailure("They are not online."); - } } } @@ -1098,12 +1064,11 @@ namespace Server.Commands.Generic return; } - foreach (BaseHouse house in BaseHouse.AllHouses) - if (house.HasSecureItem(item) || house.HasLockedDownItem(item)) - { - e.Mobile.SendGump(new PropertiesGump(e.Mobile, house)); - return; - } + foreach (BaseHouse house in BaseHouse.AllHouses.Where(house => house.HasSecureItem(item) || house.HasLockedDownItem(item))) + { + e.Mobile.SendGump(new PropertiesGump(e.Mobile, house)); + return; + } LogFailure("No house was found."); } diff --git a/Projects/Scripts/Commands/Generic/Commands/DesignInsert.cs b/Projects/Scripts/Commands/Generic/Commands/DesignInsert.cs index cae91d825..541f4959c 100644 --- a/Projects/Scripts/Commands/Generic/Commands/DesignInsert.cs +++ b/Projects/Scripts/Commands/Generic/Commands/DesignInsert.cs @@ -149,7 +149,7 @@ namespace Server.Commands.Generic AddResponse("Awaiting confirmation..."); } - private void OnConfirmCallback(Mobile from, bool okay, List list, bool staticsOnly) + private void OnConfirmCallback(Mobile from, bool okay, IReadOnlyList list, bool staticsOnly) { bool flushToLog = false; @@ -191,13 +191,11 @@ namespace Server.Commands.Generic house.Delta(ItemDelta.Update); } else - { AddResponse("Command aborted."); - } Flush(from, flushToLog); } #endregion } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Commands/Generic/Extensions/Compilers/ConditionalCompiler.cs b/Projects/Scripts/Commands/Generic/Extensions/Compilers/ConditionalCompiler.cs index 6db1c7a08..9b9ecf962 100644 --- a/Projects/Scripts/Commands/Generic/Extensions/Compilers/ConditionalCompiler.cs +++ b/Projects/Scripts/Commands/Generic/Extensions/Compilers/ConditionalCompiler.cs @@ -160,10 +160,6 @@ namespace Server.Commands.Generic FieldAttributes.Private | FieldAttributes.InitOnly ); -// parseMethod.Invoke(null, -// parseArgs.Length == 2 ? new object[] {toParse, (int) parseArgs[1]} : new object[] {toParse}); - - il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldstr, toParse); @@ -234,36 +230,17 @@ namespace Server.Commands.Generic public override void Compile(MethodEmitter emitter) { - bool inverse = false; + bool inverse = m_Operator == StringOperator.NotEqual; - string methodName; - - switch (m_Operator) + string methodName = m_Operator switch { - case StringOperator.Equal: - methodName = "Equals"; - break; - - case StringOperator.NotEqual: - methodName = "Equals"; - inverse = true; - break; - - case StringOperator.Contains: - methodName = "Contains"; - break; - - case StringOperator.StartsWith: - methodName = "StartsWith"; - break; - - case StringOperator.EndsWith: - methodName = "EndsWith"; - break; - - default: - throw new InvalidOperationException("Invalid string comparison operator."); - } + StringOperator.Equal => "Equals", + StringOperator.NotEqual => "Equals", + StringOperator.Contains => "Contains", + StringOperator.StartsWith => "StartsWith", + StringOperator.EndsWith => "EndsWith", + _ => throw new InvalidOperationException("Invalid string comparison operator.") + }; if (m_IgnoreCase || methodName == "Equals") { diff --git a/Projects/Scripts/Commands/Generic/Extensions/DistinctExtension.cs b/Projects/Scripts/Commands/Generic/Extensions/DistinctExtension.cs index 682f4681c..cc3fcf846 100644 --- a/Projects/Scripts/Commands/Generic/Extensions/DistinctExtension.cs +++ b/Projects/Scripts/Commands/Generic/Extensions/DistinctExtension.cs @@ -32,8 +32,7 @@ namespace Server.Commands.Generic prop.CheckAccess(from); } - if (assembly == null) - assembly = new AssemblyEmitter("__dynamic"); + assembly ??= new AssemblyEmitter("__dynamic"); m_Comparer = DistinctCompiler.Compile(assembly, baseType, m_Properties.ToArray()); } diff --git a/Projects/Scripts/Commands/Generic/Extensions/SortExtension.cs b/Projects/Scripts/Commands/Generic/Extensions/SortExtension.cs index 5f2684cdb..cd1f757e1 100644 --- a/Projects/Scripts/Commands/Generic/Extensions/SortExtension.cs +++ b/Projects/Scripts/Commands/Generic/Extensions/SortExtension.cs @@ -31,8 +31,7 @@ namespace Server.Commands.Generic order.Property.CheckAccess(from); } - if (assembly == null) - assembly = new AssemblyEmitter("__dynamic"); + assembly ??= new AssemblyEmitter("__dynamic"); m_Comparer = SortCompiler.Compile(assembly, baseType, m_Orders.ToArray()); } @@ -69,7 +68,6 @@ namespace Server.Commands.Generic case "up": case "asc": case "ascending": - isAscending = true; ++offset; break; diff --git a/Projects/Scripts/Commands/Generic/Implementors/BaseCommandImplementor.cs b/Projects/Scripts/Commands/Generic/Implementors/BaseCommandImplementor.cs index 23edf03ea..ab37d795c 100644 --- a/Projects/Scripts/Commands/Generic/Implementors/BaseCommandImplementor.cs +++ b/Projects/Scripts/Commands/Generic/Implementors/BaseCommandImplementor.cs @@ -111,20 +111,15 @@ namespace Server.Commands.Generic case ObjectTypes.All: case ObjectTypes.Both: { - if (condIsItem) - items = true; - - if (condIsMobile) - mobiles = true; + items |= condIsItem; + mobiles |= condIsMobile; break; } case ObjectTypes.Items: { if (condIsItem) - { items = true; - } else if (condIsMobile) { from.SendMessage("You may not use a mobile type condition for this command."); @@ -136,9 +131,7 @@ namespace Server.Commands.Generic case ObjectTypes.Mobiles: { if (condIsMobile) - { mobiles = true; - } else if (condIsItem) { from.SendMessage("You may not use an item type condition for this command."); diff --git a/Projects/Scripts/Commands/Generic/Implementors/ContainedCommandImplementor.cs b/Projects/Scripts/Commands/Generic/Implementors/ContainedCommandImplementor.cs index 2425840fe..f68ff1e2c 100644 --- a/Projects/Scripts/Commands/Generic/Implementors/ContainedCommandImplementor.cs +++ b/Projects/Scripts/Commands/Generic/Implementors/ContainedCommandImplementor.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Server.Items; using Server.Targeting; @@ -40,7 +41,7 @@ namespace Server.Commands.Generic from.SendMessage("That is not a container."); return; } - + try { Extensions ext = Extensions.Parse(from, ref args); @@ -70,4 +71,4 @@ namespace Server.Commands.Generic } } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Commands/Generic/Implementors/GlobalCommandImplementor.cs b/Projects/Scripts/Commands/Generic/Implementors/GlobalCommandImplementor.cs index e68726237..85d4d7b7f 100644 --- a/Projects/Scripts/Commands/Generic/Implementors/GlobalCommandImplementor.cs +++ b/Projects/Scripts/Commands/Generic/Implementors/GlobalCommandImplementor.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; namespace Server.Commands.Generic { @@ -28,14 +29,10 @@ namespace Server.Commands.Generic List list = new List(); if (items) - foreach (Item item in World.Items.Values) - if (ext.IsValid(item)) - list.Add(item); + list.AddRange(World.Items.Values.Where(item => ext.IsValid(item))); if (mobiles) - foreach (Mobile mob in World.Mobiles.Values) - if (ext.IsValid(mob)) - list.Add(mob); + list.AddRange(World.Mobiles.Values.Where(mob => ext.IsValid(mob))); ext.Filter(list); @@ -47,4 +44,4 @@ namespace Server.Commands.Generic } } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Commands/Generic/Implementors/ObjectConditional.cs b/Projects/Scripts/Commands/Generic/Implementors/ObjectConditional.cs index 72519c9c5..6124e0e34 100644 --- a/Projects/Scripts/Commands/Generic/Implementors/ObjectConditional.cs +++ b/Projects/Scripts/Commands/Generic/Implementors/ObjectConditional.cs @@ -30,8 +30,7 @@ namespace Server.Commands.Generic public void Compile(ref AssemblyEmitter emitter) { - if (emitter == null) - emitter = new AssemblyEmitter("__dynamic"); + emitter ??= new AssemblyEmitter("__dynamic"); m_Conditionals = new IConditional[m_Conditions.Length]; diff --git a/Projects/Scripts/Commands/Generic/Implementors/RegionCommandImplementor.cs b/Projects/Scripts/Commands/Generic/Implementors/RegionCommandImplementor.cs index 5739236f9..edf65f7d4 100644 --- a/Projects/Scripts/Commands/Generic/Implementors/RegionCommandImplementor.cs +++ b/Projects/Scripts/Commands/Generic/Implementors/RegionCommandImplementor.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; namespace Server.Commands.Generic { @@ -30,16 +31,7 @@ namespace Server.Commands.Generic List list = new List(); if (mobiles) - { - foreach (Mobile mob in reg.GetMobiles()) - { - if (!BaseCommand.IsAccessible(from, mob)) - continue; - - if (ext.IsValid(mob)) - list.Add(mob); - } - } + list.AddRange(reg.GetMobiles().Where(mob => BaseCommand.IsAccessible(from, mob)).Where(mob => ext.IsValid(mob))); else { command.LogFailure("This command does not support items."); @@ -56,4 +48,4 @@ namespace Server.Commands.Generic } } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Commands/Generic/Implementors/SerialCommandImplementor.cs b/Projects/Scripts/Commands/Generic/Implementors/SerialCommandImplementor.cs index 5996b1466..57873a2d1 100644 --- a/Projects/Scripts/Commands/Generic/Implementors/SerialCommandImplementor.cs +++ b/Projects/Scripts/Commands/Generic/Implementors/SerialCommandImplementor.cs @@ -17,7 +17,7 @@ namespace Server.Commands.Generic { Serial serial = e.GetUInt32(0); - object obj = null; + IEntity obj = null; if (serial.IsItem) obj = World.FindItem(serial); @@ -25,22 +25,16 @@ namespace Server.Commands.Generic obj = World.FindMobile(serial); if (obj == null) - { e.Mobile.SendMessage("That is not a valid serial."); - } else { Commands.TryGetValue(e.GetString(1), out BaseCommand command); if (command == null) - { e.Mobile.SendMessage( "That is either an invalid command name or one that does not support this modifier."); - } else if (e.Mobile.AccessLevel < command.AccessLevel) - { e.Mobile.SendMessage("You do not have access to that command."); - } else { switch (command.ObjectTypes) diff --git a/Projects/Scripts/Commands/Handlers.cs b/Projects/Scripts/Commands/Handlers.cs index 723dfb2eb..f1015888f 100644 --- a/Projects/Scripts/Commands/Handlers.cs +++ b/Projects/Scripts/Commands/Handlers.cs @@ -1,10 +1,11 @@ using System.Collections.Generic; +using System.Linq; using System.Text; using Server.Commands.Generic; using Server.Engines.Help; using Server.Gumps; using Server.Items; -using Server.Menus.ItemLists; +using Server.Menus; using Server.Menus.Questions; using Server.Misc; using Server.Mobiles; @@ -16,7 +17,7 @@ using Server.Targets; namespace Server.Commands { - public class CommandHandlers + public static class CommandHandlers { public static void Initialize() { @@ -88,19 +89,17 @@ namespace Server.Commands { if (e.Length == 1 && !e.GetBoolean(0)) { - from.Send(SpeedControl.Disable); + Packets.SendSpeedControlDisabled(from.NetState); from.SendMessage("Speed boost has been disabled."); } else { - from.Send(SpeedControl.MountSpeed); + Packets.SendSpeedControlMount(from.NetState); from.SendMessage("Speed boost has been enabled."); } } else - { from.SendMessage("Format: SpeedBoost [true|false]"); - } } [Usage("Where")] @@ -159,18 +158,16 @@ namespace Server.Commands { PageEntry pe = PageQueue.GetEntry(targ); - if (pe?.Handler == from) - from.SendMessage("You may only use this command if you are handling their help page."); - else - from.SendMessage("You may only use this command on someone who has paged you."); + from.SendMessage(pe?.Handler == from + ? "You may only use this command if you are handling their help page." + : "You may only use this command on someone who has paged you."); return; } - if (targ.AddToBackpack(held)) - from.SendMessage("The item they were holding has been placed into their backpack."); - else - from.SendMessage("The item they were holding has been placed at their feet."); + from.SendMessage(targ.AddToBackpack(held) + ? "The item they were holding has been placed into their backpack." + : "The item they were holding has been placed at their feet."); held.ClearBounce(); @@ -220,14 +217,8 @@ namespace Server.Commands } List list = new List(); - - foreach (Item item in World.Items.Values) - if (item.Map == map && item.Parent == null) - list.Add(item); - - foreach (Mobile m in World.Mobiles.Values) - if (m.Map == map && !m.Player) - list.Add(m); + list.AddRange(World.Items.Values.Where(item => item.Map == map && item.Parent == null)); + list.AddRange(World.Mobiles.Values.Where(m => m.Map == map && !m.Player)); if (list.Count > 0) { @@ -277,9 +268,7 @@ namespace Server.Commands } } else - { from.SendMessage("There were no pets found for that player."); - } } else if (obj is Mobile master && master.Player) { @@ -308,9 +297,7 @@ namespace Server.Commands } } else - { from.SendMessage("There were no pets found for that player."); - } } else { @@ -349,15 +336,9 @@ namespace Server.Commands CommandLogging.WriteLine(m, "{0} {1} playing sound {2} (toAll={3})", m.AccessLevel, CommandLogging.Format(m), index, toAll); - Packet p = new PlaySound(index, m.Location); - - p.Acquire(); - foreach (NetState state in m.GetClientsInRange(12)) if (toAll || state.Mobile.CanSee(m)) - state.Send(p); - - p.Release(); + Packets.SendPlaySound(state, index, m.Location); } [Usage("Echo ")] @@ -366,10 +347,7 @@ namespace Server.Commands { string toEcho = e.ArgString.Trim(); - if (toEcho.Length > 0) - e.Mobile.SendMessage(toEcho); - else - e.Mobile.SendMessage("Format: Echo \"\""); + e.Mobile.SendMessage(toEcho.Length > 0 ? toEcho : "Format: Echo \"\""); } [Usage("Bank")] @@ -528,16 +506,12 @@ namespace Server.Commands Dictionary list = from.Map.Regions; - foreach (KeyValuePair kvp in list) - { - Region r = kvp.Value; - + foreach (var (_, r) in list) if (Insensitive.Equals(r.Name, name)) { from.Location = new Point3D(r.GoLocation); return; } - } for (int i = 0; i < Map.AllMaps.Count; ++i) { @@ -618,11 +592,7 @@ namespace Server.Commands { Mobile m = e.Mobile; - List list = new List(); - - foreach (CommandEntry entry in CommandSystem.Entries.Values) - if (m.AccessLevel >= entry.AccessLevel) - list.Add(entry); + List list = CommandSystem.Entries.Values.Where(entry => m.AccessLevel >= entry.AccessLevel).ToList(); list.Sort(); @@ -671,13 +641,8 @@ namespace Server.Commands public static void BroadcastMessage(AccessLevel ac, int hue, string message) { - foreach (NetState state in NetState.Instances) - { - Mobile m = state.Mobile; - - if (m?.AccessLevel >= ac) - m.SendMessage(hue, message); - } + foreach (Mobile m in NetState.Instances.Select(state => state.Mobile).Where(m => m?.AccessLevel >= ac)) + m.SendMessage(hue, message); } [Usage("AutoPageNotify")] diff --git a/Projects/Scripts/Commands/HelpInfo.cs b/Projects/Scripts/Commands/HelpInfo.cs index a868edf7e..8f1dc7946 100644 --- a/Projects/Scripts/Commands/HelpInfo.cs +++ b/Projects/Scripts/Commands/HelpInfo.cs @@ -9,7 +9,7 @@ using CommandInfoSorter = Server.Commands.Docs.CommandEntrySorter; namespace Server.Commands { - public class HelpInfo + public static class HelpInfo { public static Dictionary HelpInfos{ get; } = new Dictionary(); diff --git a/Projects/Scripts/Commands/Logging.cs b/Projects/Scripts/Commands/Logging.cs index 8c4f09b86..0bc629775 100644 --- a/Projects/Scripts/Commands/Logging.cs +++ b/Projects/Scripts/Commands/Logging.cs @@ -5,7 +5,7 @@ using Server.Accounting; namespace Server.Commands { - public class CommandLogging + public static class CommandLogging { private static char[] m_NotSafe = { '\\', '/', ':', '*', '?', '"', '<', '>', '|' }; public static bool Enabled{ get; set; } = true; diff --git a/Projects/Scripts/Commands/Properties.cs b/Projects/Scripts/Commands/Properties.cs index 60ed30a2f..c95ece9eb 100644 --- a/Projects/Scripts/Commands/Properties.cs +++ b/Projects/Scripts/Commands/Properties.cs @@ -196,7 +196,7 @@ namespace Server.Commands } } - return chain[chain.Length - 1]; + return chain[^1]; } public static string GetValue(Mobile from, object o, string name) @@ -328,7 +328,7 @@ namespace Server.Commands concat[i * 2 + 1] = i < chain.Length - 1 ? "." : " = "; } - concat[concat.Length - 1] = toString; + concat[^1] = toString; return string.Concat(concat); } @@ -382,7 +382,7 @@ namespace Server.Commands if (IsEnum(type)) try { - toSet = Enum.Parse(type, value, true); + toSet = Enum.Parse(type, value ?? "", true); } catch { @@ -654,7 +654,7 @@ namespace Server if (!IsBound) throw new NotYetBoundException(this); - return m_Chain[m_Chain.Length - 1].PropertyType; + return m_Chain[^1].PropertyType; } } diff --git a/Projects/Scripts/Commands/ShardTime.cs b/Projects/Scripts/Commands/ShardTime.cs index af91bba37..33e7ea882 100644 --- a/Projects/Scripts/Commands/ShardTime.cs +++ b/Projects/Scripts/Commands/ShardTime.cs @@ -2,7 +2,7 @@ namespace Server.Commands { - public class ShardTime + public static class ShardTime { public static void Initialize() { @@ -16,4 +16,4 @@ namespace Server.Commands e.Mobile.SendMessage(DateTime.UtcNow.ToString()); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Commands/SignParser.cs b/Projects/Scripts/Commands/SignParser.cs index 66176541b..d8133da8e 100644 --- a/Projects/Scripts/Commands/SignParser.cs +++ b/Projects/Scripts/Commands/SignParser.cs @@ -4,7 +4,7 @@ using Server.Items; namespace Server.Commands { - public class SignParser + public static class SignParser { private static Queue m_ToDelete = new Queue(); @@ -76,9 +76,7 @@ namespace Server.Commands from.SendMessage("Sign generating complete."); } else - { from.SendMessage("{0} not found!", cfg); - } } public static void Add_Static(int itemID, Point3D location, Map map, string name) @@ -94,17 +92,8 @@ namespace Server.Commands while (m_ToDelete.Count > 0) m_ToDelete.Dequeue().Delete(); - Item sign; - - if (name.StartsWith("#")) - { - sign = new LocalizedSign(itemID, Utility.ToInt32(name.Substring(1))); - } - else - { - sign = new Sign(itemID); - sign.Name = name; - } + Item sign = name.StartsWith("#") ? new LocalizedSign(itemID, Utility.ToInt32(name.Substring(1))) : + new Sign(itemID) {Name = name}; if (map == Map.Malas) { diff --git a/Projects/Scripts/Commands/Skills.cs b/Projects/Scripts/Commands/Skills.cs index 7decdfc6f..11ba065da 100644 --- a/Projects/Scripts/Commands/Skills.cs +++ b/Projects/Scripts/Commands/Skills.cs @@ -3,7 +3,7 @@ using Server.Targeting; namespace Server.Commands { - public class SkillsCommand + public static class SkillsCommand { public static void Initialize() { @@ -123,4 +123,4 @@ namespace Server.Commands } } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Commands/SkillsMenu.cs b/Projects/Scripts/Commands/SkillsMenu.cs index 6b4e617ab..c97486d03 100644 --- a/Projects/Scripts/Commands/SkillsMenu.cs +++ b/Projects/Scripts/Commands/SkillsMenu.cs @@ -3,7 +3,7 @@ using Server.Targeting; namespace Server.Commands { - public class Skills + public static class Skills { public static void Initialize() { @@ -35,4 +35,4 @@ namespace Server.Commands } } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Commands/Statics.cs b/Projects/Scripts/Commands/Statics.cs index 476f96790..48f9acc38 100644 --- a/Projects/Scripts/Commands/Statics.cs +++ b/Projects/Scripts/Commands/Statics.cs @@ -1,12 +1,11 @@ using System.Collections.Generic; using System.IO; -using Server.Commands; using Server.Gumps; using Server.Items; -namespace Server +namespace Server.Commands { - public class Statics + public static class Statics { private const string BaseFreezeWarning = "{0} " + "Those items will be removed from the world and placed into the server data files. " + @@ -180,11 +179,8 @@ namespace Server int totalFrozen = 0; - foreach (KeyValuePair> de in mapTable) + foreach (var (map, table) in mapTable) { - Map map = de.Key; - Dictionary table = de.Value; - TileMatrix matrix = map.Tiles; using FileStream idxStream = OpenWrite(matrix.IndexStream); diff --git a/Projects/Scripts/Commands/VisibilityList.cs b/Projects/Scripts/Commands/VisibilityList.cs index 6e7afd9ec..0dfd9415f 100644 --- a/Projects/Scripts/Commands/VisibilityList.cs +++ b/Projects/Scripts/Commands/VisibilityList.cs @@ -49,9 +49,7 @@ namespace Server.Commands pm.SendMessage("#{0}: {1}", i + 1, list[i].Name); } else - { pm.SendMessage("Your visibility list is empty."); - } } } @@ -71,7 +69,7 @@ namespace Server.Commands Mobile m = list[i]; if (!m.CanSee(pm) && Utility.InUpdateRange(m, pm)) - m.Send(pm.RemovePacket); + Packets.SendRemoveEntity(m.NetState, pm.Serial); } } } @@ -84,58 +82,54 @@ namespace Server.Commands protected override void OnTarget(Mobile from, object targeted) { - if (from is PlayerMobile pm && targeted is Mobile targ) + if (!(from is PlayerMobile pm) || !(targeted is Mobile targ)) { - if (targ.AccessLevel <= pm.AccessLevel) - { - List list = pm.VisibilityList; + from.SendMessage("Add only mobiles to your visibility list."); + return; + } - if (list.Contains(targ)) - { - list.Remove(targ); - pm.SendMessage("{0} has been removed from your visibility list.", targ.Name); - } - else - { - list.Add(targ); - pm.SendMessage("{0} has been added to your visibility list.", targ.Name); - } + if (targ.AccessLevel > pm.AccessLevel) + { + pm.SendMessage("They can already see you!"); + return; + } - if (Utility.InUpdateRange(targ, from)) - { - NetState ns = targ.NetState; + List list = pm.VisibilityList; - if (ns != null) - { - if (targ.CanSee(pm)) - { - ns.Send(MobileIncoming.Create(ns, targ, pm)); - - if (ObjectPropertyList.Enabled) - { - ns.Send(pm.OPLPacket); - - foreach (Item item in pm.Items) - ns.Send(item.OPLPacket); - } - } - else - { - ns.Send(pm.RemovePacket); - } - } - } - } - else - { - pm.SendMessage("They can already see you!"); - } + if (list.Contains(targ)) + { + list.Remove(targ); + pm.SendMessage("{0} has been removed from your visibility list.", targ.Name); } else { - from.SendMessage("Add only mobiles to your visibility list."); + list.Add(targ); + pm.SendMessage("{0} has been added to your visibility list.", targ.Name); + } + + if (Utility.InUpdateRange(targ, from)) + { + NetState ns = targ.NetState; + + if (ns != null) + { + if (targ.CanSee(pm)) + { + Packets.SendMobileIncoming(ns, targ, pm); + + if (ObjectPropertyList.Enabled) + { + pm.PropertyList.Send(ns); + + foreach (Item item in pm.Items) + item.PropertyList.SendOPLInfo(ns); + } + } + else + Packets.SendRemoveEntity(ns, pm.Serial); + } } } } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Commands/Wipe.cs b/Projects/Scripts/Commands/Wipe.cs index eec17443b..a8e4921f8 100644 --- a/Projects/Scripts/Commands/Wipe.cs +++ b/Projects/Scripts/Commands/Wipe.cs @@ -5,7 +5,7 @@ using Server.Multis; namespace Server.Commands { - public class Wipe + public static class Wipe { [Flags] public enum WipeType @@ -74,7 +74,7 @@ namespace Server.Commands if (!items && !multis || !mobiles) return; - + eable = map.GetObjectsInBounds(rect); foreach (IEntity obj in eable) @@ -91,4 +91,4 @@ namespace Server.Commands toDelete[i].Delete(); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Context Menus/AddToSpellbookEntry.cs b/Projects/Scripts/Context Menus/AddToSpellbookEntry.cs index 18d1e0b35..48cc030bc 100644 --- a/Projects/Scripts/Context Menus/AddToSpellbookEntry.cs +++ b/Projects/Scripts/Context Menus/AddToSpellbookEntry.cs @@ -34,9 +34,7 @@ namespace Server.ContextMenus { } else if (book.HasSpell(m_Scroll.SpellID)) - { from.SendLocalizedMessage(500179); // That spell is already present in that spellbook. - } else { int val = m_Scroll.SpellID - book.BookOffset; @@ -47,11 +45,11 @@ namespace Server.ContextMenus m_Scroll.Consume(); - from.Send(new PlaySound(0x249, book.GetWorldLocation())); + Packets.SendPlaySound(from.NetState, 0x249, book.GetWorldLocation()); } } } } } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Engines/BulkOrders/Books/BOBGump.cs b/Projects/Scripts/Engines/BulkOrders/Books/BOBGump.cs index 4cbab8357..a7c6e37f3 100644 --- a/Projects/Scripts/Engines/BulkOrders/Books/BOBGump.cs +++ b/Projects/Scripts/Engines/BulkOrders/Books/BOBGump.cs @@ -4,7 +4,6 @@ using Server.Gumps; using Server.Items; using Server.Mobiles; using Server.Network; -using Server.Prompts; namespace Server.Engines.BulkOrders { diff --git a/Projects/Scripts/Engines/BulkOrders/Books/BulkOrderBook.cs b/Projects/Scripts/Engines/BulkOrders/Books/BulkOrderBook.cs index e73315712..8e6470dfb 100644 --- a/Projects/Scripts/Engines/BulkOrders/Books/BulkOrderBook.cs +++ b/Projects/Scripts/Engines/BulkOrders/Books/BulkOrderBook.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; using Server.Gumps; using Server.Multis; -using Server.Prompts; using Server.Mobiles; using Server.ContextMenus; using Server.Items; diff --git a/Projects/Scripts/Engines/BulkOrders/LargeBOD.cs b/Projects/Scripts/Engines/BulkOrders/LargeBOD.cs index cafddf4e8..e711755e8 100644 --- a/Projects/Scripts/Engines/BulkOrders/LargeBOD.cs +++ b/Projects/Scripts/Engines/BulkOrders/LargeBOD.cs @@ -1,3 +1,4 @@ +using System.Linq; using Server.Mobiles; namespace Server.Engines.BulkOrders diff --git a/Projects/Scripts/Engines/BulkOrders/LargeTailorBOD.cs b/Projects/Scripts/Engines/BulkOrders/LargeTailorBOD.cs index 8cb608427..8f109ac99 100644 --- a/Projects/Scripts/Engines/BulkOrders/LargeTailorBOD.cs +++ b/Projects/Scripts/Engines/BulkOrders/LargeTailorBOD.cs @@ -2,7 +2,7 @@ namespace Server.Engines.BulkOrders { public class LargeTailorBOD : LargeBOD { - public static double[] m_TailoringMaterialChances = + public static readonly double[] m_TailoringMaterialChances = { 0.857421875, // None 0.125000000, // Spined @@ -19,7 +19,6 @@ namespace Server.Engines.BulkOrders switch (Utility.Random(14)) { default: - case 0: entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.Farmer); break; case 1: diff --git a/Projects/Scripts/Engines/BulkOrders/Rewards.cs b/Projects/Scripts/Engines/BulkOrders/Rewards.cs index c427bb54f..7de897822 100644 --- a/Projects/Scripts/Engines/BulkOrders/Rewards.cs +++ b/Projects/Scripts/Engines/BulkOrders/Rewards.cs @@ -357,7 +357,14 @@ namespace Server.Engines.BulkOrders int[][][] goldTable = m_GoldTable; int typeIndex = ComputeType(type, itemCount); - int quanIndex = quantity == 20 ? 2 : quantity == 15 ? 1 : 0; + + int quanIndex = quantity switch + { + 20 => 2, + 15 => 1, + _ => 0 + }; + int mtrlIndex = material >= BulkMaterialType.DullCopper && material <= BulkMaterialType.Valorite ? 1 + (material - BulkMaterialType.DullCopper) : 0; @@ -599,11 +606,28 @@ namespace Server.Engines.BulkOrders { int[][][] goldTable = Core.AOS ? m_AosGoldTable : m_OldGoldTable; - int typeIndex = (itemCount == 6 ? 3 : itemCount == 5 ? 2 : itemCount == 4 ? 1 : 0) * 2 + (exceptional ? 1 : 0); - int quanIndex = quantity == 20 ? 2 : quantity == 15 ? 1 : 0; - int mtrlIndex = material == BulkMaterialType.Barbed ? 3 : - material == BulkMaterialType.Horned ? 2 : - material == BulkMaterialType.Spined ? 1 : 0; + int typeIndex = itemCount switch + { + 6 => 3, + 5 => 2, + 4 => 1, + _ => 0 + } * 2 + (exceptional ? 1 : 0); + + int quanIndex = quantity switch + { + 20 => 2, + 15 => 1, + _ => 0 + }; + + int mtrlIndex = material switch + { + BulkMaterialType.Barbed => 3, + BulkMaterialType.Horned => 2, + BulkMaterialType.Spined => 1, + _ => 0 + }; int gold = goldTable[typeIndex][quanIndex][mtrlIndex]; @@ -615,7 +639,7 @@ namespace Server.Engines.BulkOrders #region Constructors - private static int[][] m_ClothHues = + private static readonly int[][] m_ClothHues = { new[] { 0x483, 0x48C, 0x488, 0x48A }, new[] { 0x495, 0x48B, 0x486, 0x485 }, @@ -678,13 +702,15 @@ namespace Server.Engines.BulkOrders }; } - private static Item CreateRunicKit(int type) - { - if (type >= 1 && type <= 3) - return new RunicSewingKit(CraftResource.RegularLeather + type, 60 - type * 15); + private static Item CreateRunicKit(int type) => + type >= 1 && type <= 3 + ? new RunicSewingKit(CraftResource.RegularLeather + type, 60 - type * 15) + : throw new InvalidOperationException(); - throw new InvalidOperationException(); - } + private static Item CreatePowerScroll(int type) => + type == 5 || type == 10 || type == 15 || type == 20 + ? new PowerScroll(SkillName.Tailoring, 100 + type) + : throw new InvalidOperationException(); private static Item CreatePowerScroll(int type) { diff --git a/Projects/Scripts/Engines/CannedEvil/ChampionSkullBrazier.cs b/Projects/Scripts/Engines/CannedEvil/ChampionSkullBrazier.cs index 6991ac13e..3cb1b14f1 100644 --- a/Projects/Scripts/Engines/CannedEvil/ChampionSkullBrazier.cs +++ b/Projects/Scripts/Engines/CannedEvil/ChampionSkullBrazier.cs @@ -65,22 +65,16 @@ namespace Server.Engines.CannedEvil Skull = null; if (from.Map != Map || !from.InRange(GetWorldLocation(), 3)) - { from.SendLocalizedMessage(500446); // That is too far away. - } else if (!Harrower.CanSpawn) - { from.SendMessage("The harrower has already been spawned."); - } else if (m_Skull == null) { from.SendLocalizedMessage(1049485); // What would you like to sacrifice? from.Target = new SacrificeTarget(this); } else - { - SendLocalizedMessageTo(from, 1049487, ""); // I already have my champions awakening skull! - } + SendLocalizedMessageTo(from, 1049487); // I already have my champions awakening skull! } public void EndSacrifice(Mobile from, ChampionSkull skull) @@ -92,25 +86,15 @@ namespace Server.Engines.CannedEvil Skull = null; if (from.Map != Map || !from.InRange(GetWorldLocation(), 3)) - { from.SendLocalizedMessage(500446); // That is too far away. - } else if (!Harrower.CanSpawn) - { from.SendMessage("The harrower has already been spawned."); - } else if (skull == null) - { - SendLocalizedMessageTo(from, 1049488, ""); // That is not my champions awakening skull! - } + SendLocalizedMessageTo(from, 1049488); // That is not my champions awakening skull! else if (m_Skull != null) - { - SendLocalizedMessageTo(from, 1049487, ""); // I already have my champions awakening skull! - } + SendLocalizedMessageTo(from, 1049487); // I already have my champions awakening skull! else if (!skull.IsChildOf(from.Backpack)) - { from.SendLocalizedMessage(1049486); // You can only sacrifice items that are in your backpack! - } else { if (skull.Type == Type) @@ -121,9 +105,7 @@ namespace Server.Engines.CannedEvil Skull = skull; } else - { - SendLocalizedMessageTo(from, 1049488, ""); // That is not my champions awakening skull! - } + SendLocalizedMessageTo(from, 1049488); // That is not my champions awakening skull! } } diff --git a/Projects/Scripts/Engines/CannedEvil/ChampionSpawn.cs b/Projects/Scripts/Engines/CannedEvil/ChampionSpawn.cs index 2cdbe0c67..0ee5a3caf 100644 --- a/Projects/Scripts/Engines/CannedEvil/ChampionSpawn.cs +++ b/Projects/Scripts/Engines/CannedEvil/ChampionSpawn.cs @@ -950,24 +950,24 @@ namespace Server.Engines.CannedEvil Dictionary validEntries = new Dictionary(); - foreach (KeyValuePair kvp in m_DamageEntries) - if (IsEligible(kvp.Key, artifact)) + foreach (var (key, value) in m_DamageEntries) + if (IsEligible(key, artifact)) { - validEntries.Add(kvp.Key, kvp.Value); - totalDamage += kvp.Value; + validEntries.Add(key, value); + totalDamage += value; } int randomDamage = Utility.RandomMinMax(1, totalDamage); totalDamage = 0; - foreach (KeyValuePair kvp in validEntries) + foreach (var (key, value) in validEntries) { - totalDamage += kvp.Value; + totalDamage += value; if (totalDamage >= randomDamage) { - GiveArtifact(kvp.Key, artifact); + GiveArtifact(key, artifact); return; } } @@ -1001,10 +1001,10 @@ namespace Server.Engines.CannedEvil writer.Write(m_SPawnSzMod); writer.Write(m_DamageEntries.Count); - foreach (KeyValuePair kvp in m_DamageEntries) + foreach (var (key, value) in m_DamageEntries) { - writer.Write(kvp.Key); - writer.Write(kvp.Value); + writer.Write(key); + writer.Write(value); } writer.Write(ConfinedRoaming); diff --git a/Projects/Scripts/Engines/Chat/Channel.cs b/Projects/Scripts/Engines/Chat/Channel.cs index bc1a54ba8..127c560bb 100644 --- a/Projects/Scripts/Engines/Chat/Channel.cs +++ b/Projects/Scripts/Engines/Chat/Channel.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; namespace Server.Engines.Chat { @@ -401,18 +402,7 @@ namespace Server.Engines.Chat } } - public static Channel FindChannelByName(string name) - { - for (int i = 0; i < Channels.Count; ++i) - { - Channel channel = Channels[i]; - - if (channel.m_Name == name) - return channel; - } - - return null; - } + public static Channel FindChannelByName(string name) => Channels.FirstOrDefault(channel => channel.m_Name == name); public static void Initialize() { diff --git a/Projects/Scripts/Engines/Chat/Chat.cs b/Projects/Scripts/Engines/Chat/Chat.cs index 705463ec5..0c673dba2 100644 --- a/Projects/Scripts/Engines/Chat/Chat.cs +++ b/Projects/Scripts/Engines/Chat/Chat.cs @@ -1,12 +1,13 @@ using System; using System.IO; +using System.Linq; using Server.Accounting; using Server.Misc; using Server.Network; namespace Server.Engines.Chat { - public class ChatSystem + public static class ChatSystem { public static bool Enabled{ get; set; } = true; @@ -18,7 +19,7 @@ namespace Server.Engines.Chat public static void SendCommandTo(Mobile to, ChatCommand type, string param1 = null, string param2 = null) { - to?.Send(new ChatMessagePacket(null, (int)type + 20, param1, param2)); + ChatPackets.SendChatMessage(to?.NetState, null, (int)type + 20, param1, param2); } public static void OpenChatWindowRequest(NetState state, PacketReader pvSrc) @@ -61,21 +62,11 @@ namespace Server.Engines.Chat { // TODO: Optimize this search - foreach (Account checkAccount in Accounts.GetAccounts()) + if (Accounts.GetAccounts().Cast().Any(checkAccount => Insensitive.Equals(checkAccount.GetTag("ChatName")?.Trim(), chatName))) { - string existingName = checkAccount.GetTag("ChatName"); - - if (existingName != null) - { - existingName = existingName.Trim(); - - if (Insensitive.Equals(existingName, chatName)) - { - from.SendMessage("Nickname already in use."); - SendCommandTo(from, ChatCommand.AskNewNickname); - return; - } - } + from.SendMessage("Nickname already in use."); + SendCommandTo(from, ChatCommand.AskNewNickname); + return; } accountChatName = chatName; @@ -129,17 +120,15 @@ namespace Server.Engines.Chat if (handler.RequireConference && channel == null) user.SendMessage(31); /* You must be in a conference to do this. - * To join a conference, select one from the Conference menu. - */ + * To join a conference, select one from the Conference menu. + */ else if (handler.RequireModerator && !user.IsModerator) user.SendMessage(29); // You must have operator status to do this. else handler.Callback(user, channel, param); } else - { Console.WriteLine("Client: {0}: Unknown chat action 0x{1:X}: {2}", state, actionID, param); - } } catch (Exception e) { @@ -147,4 +136,4 @@ namespace Server.Engines.Chat } } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Engines/Chat/ChatActionHandlers.cs b/Projects/Scripts/Engines/Chat/ChatActionHandlers.cs index b6ad6c2df..5cf3b95c4 100644 --- a/Projects/Scripts/Engines/Chat/ChatActionHandlers.cs +++ b/Projects/Scripts/Engines/Chat/ChatActionHandlers.cs @@ -1,6 +1,6 @@ namespace Server.Engines.Chat { - public class ChatActionHandlers + public static class ChatActionHandlers { private static ChatActionHandler[] m_Handlers; @@ -112,8 +112,8 @@ namespace Server.Engines.Chat { from.IgnorePrivateMessage = true; from.SendMessage(38); /* You will no longer receive private messages. - * Those who send you a message will be notified that you are blocking incoming messages. - */ + * Those who send you a message will be notified that you are blocking incoming messages. + */ } public static void TogglePrivateMessages(ChatUser from, Channel channel, string param) diff --git a/Projects/Scripts/Engines/Chat/ChatUser.cs b/Projects/Scripts/Engines/Chat/ChatUser.cs index a24ee7508..d2d802da8 100644 --- a/Projects/Scripts/Engines/Chat/ChatUser.cs +++ b/Projects/Scripts/Engines/Chat/ChatUser.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using Server.Accounting; namespace Server.Engines.Chat @@ -64,16 +65,14 @@ namespace Server.Engines.Chat return false; } - public void SendMessage(int number, string param1 = null, string param2 = null) + public void SendMessage(int number, string param1 = "", string param2 = "") { - if (Mobile.NetState != null) - Mobile.Send(new ChatMessagePacket(Mobile, number, param1, param2)); + ChatPackets.SendChatMessage(Mobile.NetState, Mobile, number, param1, param2); } - public void SendMessage(int number, Mobile from, string param1, string param2) + public void SendMessage(int number, Mobile from, string param1 = "", string param2 = "") { - if (Mobile.NetState != null) - Mobile.Send(new ChatMessagePacket(from, number, param1, param2)); + ChatPackets.SendChatMessage(Mobile.NetState, from, number, param1, param2); } public bool IsIgnored(ChatUser check) => Ignored.Contains(check); @@ -81,9 +80,7 @@ namespace Server.Engines.Chat public void AddIgnored(ChatUser user) { if (IsIgnored(user)) - { SendMessage(22, user.Username); // You are already ignoring %1. - } else { Ignored.Add(user); @@ -106,9 +103,7 @@ namespace Server.Engines.Chat SendMessage(26); // You are no longer ignoring anyone. } else - { SendMessage(25, user.Username); // You are not ignoring %1. - } } public static ChatUser AddChatUser(Mobile from) @@ -172,18 +167,7 @@ namespace Server.Engines.Chat return c; } - public static ChatUser GetChatUser(string username) - { - for (int i = 0; i < m_Users.Count; ++i) - { - ChatUser user = m_Users[i]; - - if (user.Username == username) - return user; - } - - return null; - } + public static ChatUser GetChatUser(string username) => m_Users.FirstOrDefault(user => user.Username == username); public static void GlobalSendCommand(ChatCommand command, string param1, string param2 = null) { diff --git a/Projects/Scripts/Engines/Chat/Chatold.cs b/Projects/Scripts/Engines/Chat/Chatold.cs index 0f3626116..2ae2c4f35 100644 --- a/Projects/Scripts/Engines/Chat/Chatold.cs +++ b/Projects/Scripts/Engines/Chat/Chatold.cs @@ -1,6 +1,6 @@ namespace Server.Chat { - public class ChatSystem + public static class ChatSystem { public static void Initialize() { @@ -12,4 +12,4 @@ namespace Server.Chat e.Mobile.SendMessage("Chat is not currently supported."); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Engines/Chat/Packets.cs b/Projects/Scripts/Engines/Chat/Packets.cs index 3d8bfd563..ce41aa740 100644 --- a/Projects/Scripts/Engines/Chat/Packets.cs +++ b/Projects/Scripts/Engines/Chat/Packets.cs @@ -1,28 +1,36 @@ +using Server.Buffers; using Server.Network; namespace Server.Engines.Chat { - public sealed class ChatMessagePacket : Packet + public static class ChatPackets { - public ChatMessagePacket(Mobile who, int number, string param1, string param2) : base(0xB2) + public static void SendChatMessage(NetState ns, Mobile who, int number, string param1, string param2) { - if (param1 == null) - param1 = string.Empty; + if (ns == null) + return; - if (param2 == null) - param2 = string.Empty; + param1 ??= ""; + param2 ??= ""; - EnsureCapacity(13 + (param1.Length + param2.Length) * 2); + int length = 13 + (param1.Length + param2.Length) * 2; + //base(0xB2) - m_Stream.Write((ushort)(number - 20)); + SpanWriter writer = new SpanWriter(stackalloc byte[length]); + writer.Write((byte)0xB2); // Packet ID + writer.Write((ushort)length); // Dynamic Length + + writer.Write((ushort)(number - 20)); if (who != null) - m_Stream.WriteAsciiFixed(who.Language, 4); + writer.WriteAsciiFixed(who.Language, 4); else - m_Stream.Write(0); + writer.Position += 4; - m_Stream.WriteBigUniNull(param1); - m_Stream.WriteBigUniNull(param2); + writer.WriteBigUniNull(param1); + writer.WriteBigUniNull(param2); + + ns.Send(writer.Span); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Engines/ConPVP/Arena.cs b/Projects/Scripts/Engines/ConPVP/Arena.cs index 12703d633..c8a907a64 100644 --- a/Projects/Scripts/Engines/ConPVP/Arena.cs +++ b/Projects/Scripts/Engines/ConPVP/Arena.cs @@ -512,7 +512,7 @@ namespace Server.Engines.ConPVP if (offset < offsets.Length) p = offsets[offset++]; else - p = offsets[offsets.Length - 1]; + p = offsets[^1]; p.X = p.X * matrix[0, 0] + p.Y * matrix[0, 1]; p.Y = p.X * matrix[1, 0] + p.Y * matrix[1, 1]; @@ -574,12 +574,15 @@ namespace Server.Engines.ConPVP if (hasBounds) { List pets = new List(); + IPooledEnumerable eable = facet.GetMobilesInBounds(m_Bounds); - foreach (Mobile mob in facet.GetMobilesInBounds(m_Bounds)) + foreach (Mobile mob in eable) if (mob is BaseCreature pet && pet.Controlled && pet.ControlMaster != null && Players.Contains(pet.ControlMaster)) pets.Add(pet); + eable.Free(); + foreach (Mobile pet in pets) { pet.Combatant = null; @@ -749,7 +752,7 @@ namespace Server.Engines.ConPVP #region Offsets & Rotation - private static Point2D[] m_EdgeOffsets = + private static readonly Point2D[] m_EdgeOffsets = { /* * /\ @@ -772,7 +775,7 @@ namespace Server.Engines.ConPVP }; // nw corner - private static Point2D[] m_CornerOffsets = + private static readonly Point2D[] m_CornerOffsets = { /* * /\ @@ -793,7 +796,7 @@ namespace Server.Engines.ConPVP new Point2D(3, 0) }; - private static int[][,] m_Rotate = + private static readonly int[][,] m_Rotate = { new[,] { { +1, 0 }, { 0, +1 } }, // west new[,] { { -1, 0 }, { 0, -1 } }, // east diff --git a/Projects/Scripts/Engines/ConPVP/DuelContext.cs b/Projects/Scripts/Engines/ConPVP/DuelContext.cs index d4d2c388f..1d6a546b9 100644 --- a/Projects/Scripts/Engines/ConPVP/DuelContext.cs +++ b/Projects/Scripts/Engines/ConPVP/DuelContext.cs @@ -160,7 +160,7 @@ namespace Server.Engines.ConPVP if (spell is RecallSpell) from.SendMessage("You may not cast this spell."); - string title = null; + string title; string option; if (spell is ArcanistSpell) @@ -854,16 +854,9 @@ namespace Server.Engines.ConPVP Participant p = Participants[i]; if (p.Eliminated) - { - ++eliminated; - - if (eliminated == Participants.Count - 1) - hasWinner = true; - } + hasWinner |= ++eliminated == Participants.Count - 1; else - { winner = p; - } } return hasWinner ? winner ?? Participants[0] : null; @@ -1630,16 +1623,7 @@ namespace Server.Engines.ConPVP int rx = dx - dy; int ry = dx + dy; - bool eastToWest; - - if (rx >= 0 && ry >= 0) - eastToWest = false; - else if (rx >= 0) - eastToWest = true; - else if (ry >= 0) - eastToWest = true; - else - eastToWest = false; + bool eastToWest = (rx < 0 || ry < 0) && (rx >= 0 || ry >= 0); Effects.PlaySound(wall, Arena.Facet, 0x1F6); @@ -1817,9 +1801,7 @@ namespace Server.Engines.ConPVP } } else - { defs = basedef.Options; - } int changes = 0; @@ -1999,9 +1981,7 @@ namespace Server.Engines.ConPVP if (!Registered) return; - if (count != -1) - StartedReadyCountdown = true; - + StartedReadyCountdown |= count != -1; ReadyCount = count; if (count == 0) diff --git a/Projects/Scripts/Engines/ConPVP/Games/BombingRun.cs b/Projects/Scripts/Engines/ConPVP/Games/BombingRun.cs index 76318ee08..406d1121e 100644 --- a/Projects/Scripts/Engines/ConPVP/Games/BombingRun.cs +++ b/Projects/Scripts/Engines/ConPVP/Games/BombingRun.cs @@ -293,7 +293,7 @@ namespace Server.Engines.ConPVP if (list.Count > 0) { - Point3D p = list[list.Count - 1]; + Point3D p = list[^1]; if (p.X != ix || p.Y != iy || p.Z != iz) list.Add(new Point3D(ix, iy, iz)); @@ -308,7 +308,7 @@ namespace Server.Engines.ConPVP z += zslp; } - if (list.Count > 0 && list[list.Count - 1] != dest) + if (list.Count > 0 && list[^1] != dest) list.Add(dest); /*if ( dist3d > 4 && ( dest.X != org.X || dest.Y != org.Y ) ) @@ -429,10 +429,7 @@ namespace Server.Engines.ConPVP if (t.Z <= point.Z && t.Z + height >= point.Z && (id.Flags & (TileFlag.Impassable | TileFlag.Wall | TileFlag.NoShoot)) != 0) { - if (i > m_PathIdx) - point = m_Path[i - 1]; - else - point = GetWorldLocation(); + point = i > m_PathIdx ? m_Path[i - 1] : GetWorldLocation(); HitObject(point, t.Z, height); return; } @@ -448,13 +445,9 @@ namespace Server.Engines.ConPVP continue; if (i is BRGoal) - { height = 17; - } else if (i is Blocker) - { height = 20; - } else { ItemData id = i.ItemData; @@ -473,10 +466,7 @@ namespace Server.Engines.ConPVP (i is Blocker || loc.Z <= point.Z && loc.Z + height >= point.Z)) { found = true; - if (j > m_PathIdx) - point = m_Path[j - 1]; - else - point = GetWorldLocation(); + point = j > m_PathIdx ? m_Path[j - 1] : GetWorldLocation(); break; } } @@ -494,9 +484,7 @@ namespace Server.Engines.ConPVP HitObject(point, loc.Z, height); } else - { HitObject(point, loc.Z, height); - } return; } @@ -511,12 +499,11 @@ namespace Server.Engines.ConPVP if (m == null || m == Thrower) continue; - Point3D point; Point3D loc = m.Location; for (int j = m_PathIdx; j < pathCheckEnd && !found; j++) { - point = m_Path[j]; + Point3D point = m_Path[j]; if (loc.X == point.X && loc.Y == point.Y && loc.Z <= point.Z && loc.Z + 16 >= point.Z) @@ -550,9 +537,10 @@ namespace Server.Engines.ConPVP else if (m_Path.Count > 0) MoveToWorld(m_Path.Last); - int myZ = Map.GetAverageZ(X, Y); + int myZ = Map?.GetAverageZ(X, Y) ?? 0; + + StaticTile[] statics = Map?.Tiles?.GetStaticTiles(X, Y, true) ?? new StaticTile[0]; - StaticTile[] statics = Map.Tiles.GetStaticTiles(X, Y, true); for (int j = 0; j < statics.Length; j++) { StaticTile t = statics[j]; @@ -676,7 +664,7 @@ namespace Server.Engines.ConPVP if (m_Bomb.Parent == null && m_Bomb.m_Game?.Controller != null) { if (!m_Bomb.m_Flying && m_Bomb.Map != Map.Internal) - Effects.SendLocationEffect(m_Bomb.GetWorldLocation(), m_Bomb.Map, 0x377A, 16, 10, m_Bomb.Hue, 0); + Effects.SendLocationEffect(m_Bomb.GetWorldLocation(), m_Bomb.Map, 0x377A, 16, 10, m_Bomb.Hue); if (m_Bomb.Location != m_Bomb.m_Game.Controller.BombHome) { @@ -983,9 +971,7 @@ namespace Server.Engines.ConPVP total = entries.Count; } else - foreach (BRPlayerInfo player in section.Players.Values) - if (player.Score > 0) - total++; + total += section.Players.Values.Count(player => player.Score > 0); entries.Sort(); @@ -1722,12 +1708,13 @@ namespace Server.Engines.ConPVP for (int i = 0; i < m_Context.Participants.Count; ++i) { - if (!(m_Context.Participants[i] is Participant p) || p.Players == null) + DuelPlayer[] players = m_Context.Participants[i]?.Players; + if (players == null) continue; - for (int j = 0; j < p.Players.Length; ++j) + for (int j = 0; j < players.Length; ++j) { - DuelPlayer dp = p.Players[j]; + DuelPlayer dp = players[j]; if (dp?.Mobile != null) { @@ -1736,16 +1723,16 @@ namespace Server.Engines.ConPVP } } - if (i == winner.TeamID) + if (i == winner?.TeamID) continue; - if (p.Players != null) - for (int j = 0; j < p.Players.Length; ++j) - if (p.Players[j] != null) - p.Players[j].Eliminated = true; + for (int j = 0; j < players.Length; ++j) + if (players[j] != null) + players[j].Eliminated = true; } - m_Context.Finish(m_Context.Participants[winner.TeamID]); + if (winner != null) + m_Context.Finish(m_Context.Participants[winner.TeamID]); } public override void OnStop() diff --git a/Projects/Scripts/Engines/ConPVP/Games/CTF.cs b/Projects/Scripts/Engines/ConPVP/Games/CTF.cs index 608e1543c..9d631f312 100644 --- a/Projects/Scripts/Engines/ConPVP/Games/CTF.cs +++ b/Projects/Scripts/Engines/ConPVP/Games/CTF.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Text; using Server.Gumps; using Server.Items; @@ -70,17 +71,13 @@ namespace Server.Engines.ConPVP { CTFTeamInfo teamInfo = game.Controller.TeamInfo[i % 8]; - if (teamInfo?.Flag == null) - continue; - - entries.Add(teamInfo); + if (teamInfo?.Flag != null) + entries.Add(teamInfo); } else - foreach (CTFPlayerInfo player in section.Players.Values) - if (player.Score > 0) - entries.Add(player); + entries.AddRange(section.Players.Values.Where(player => player.Score > 0)); - entries.Sort(delegate(IRankedCTF a, IRankedCTF b) { return b.Score - a.Score; }); + entries.Sort((a, b) => b.Score - a.Score); int height = 0; @@ -111,7 +108,8 @@ namespace Server.Engines.ConPVP if (section == null) for (int i = 0; i < entries.Count; ++i) { - CTFTeamInfo teamInfo = entries[i] as CTFTeamInfo; + if (!(entries[i] is CTFTeamInfo teamInfo)) + continue; AddImage(30, 70 + i * 75, 10152); AddImage(30, 85 + i * 75, 10151); @@ -194,10 +192,7 @@ namespace Server.Engines.ConPVP private void AddColoredText(int x, int y, int width, int height, string text, int color) { - if (color == 0) - AddHtml(x, y, width, height, text); - else - AddHtml(x, y, width, height, Color(text, color)); + AddHtml(x, y, width, height, color == 0 ? text : Color(text, color)); } } @@ -246,10 +241,8 @@ namespace Server.Engines.ConPVP else if (ourTeam == useTeam) { if (Location == m_TeamInfo.Origin && Map == m_TeamInfo.Game.Facet) - { - from.Send(new UnicodeMessage(Serial, ItemID, MessageType.Regular, 0x3B2, 3, "ENU", Name, - "Touch me not for I am chaste.")); - } + Packets.SendUnicodeMessage(from.NetState, Serial, ItemID, MessageType.Regular, 0x3B2, 3, "ENU", Name, + "Touch me not for I am chaste."); else { CTFPlayerInfo playerInfo = useTeam[from]; @@ -306,9 +299,7 @@ namespace Server.Engines.ConPVP m_ReturnCount = Math.Min(m_ReturnCount, 10); } else - { SendHome(); - } } private void StopCountdown() @@ -417,9 +408,7 @@ namespace Server.Engines.ConPVP } } else - { from.LocalOverheadMessage(MessageType.Regular, 0x26, false, "Those are not my cookies."); - } } else if (obj is Mobile passTo) { @@ -943,15 +932,8 @@ namespace Server.Engines.ConPVP if (ourFlagCarrier != null && GetTeamInfo(ourFlagCarrier) == teamInfo) { - for (int j = 0; j < ourFlagCarrier.Aggressors.Count; ++j) - { - if (!(ourFlagCarrier.Aggressors[j] is AggressorInfo aggr) || - aggr.Defender != ourFlagCarrier || aggr.Attacker != mob) - continue; - + if (ourFlagCarrier.Aggressors.Any(t => t.Defender == ourFlagCarrier && t.Attacker == mob)) playerInfo.Score += 2; // helped defend guy capturing enemy flag - break; - } if (mob.Map == ourFlagCarrier.Map && ourFlagCarrier.InRange(mob, 12)) playerInfo.Score += 1; // helped defend guy capturing enemy flag diff --git a/Projects/Scripts/Engines/ConPVP/Games/DoubleDom.cs b/Projects/Scripts/Engines/ConPVP/Games/DoubleDom.cs index 48080203b..d516600cf 100644 --- a/Projects/Scripts/Engines/ConPVP/Games/DoubleDom.cs +++ b/Projects/Scripts/Engines/ConPVP/Games/DoubleDom.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Text; using Server.Gumps; using Server.Items; @@ -72,11 +73,9 @@ namespace Server.Engines.ConPVP entries.Add(teamInfo); } else - foreach (DDPlayerInfo player in section.Players.Values) - if (player.Score > 0) - entries.Add(player); + entries.AddRange(section.Players.Values.Where(player => player.Score > 0)); - entries.Sort(delegate(IRankedCTF a, IRankedCTF b) { return b.Score - a.Score; }); + entries.Sort((a, b) => b.Score - a.Score); int height = 0; @@ -107,7 +106,8 @@ namespace Server.Engines.ConPVP if (section == null) for (int i = 0; i < entries.Count; ++i) { - DDTeamInfo teamInfo = entries[i] as DDTeamInfo; + if (!(entries[i] is DDTeamInfo teamInfo)) + continue; AddImage(30, 70 + i * 75, 10152); AddImage(30, 85 + i * 75, 10151); diff --git a/Projects/Scripts/Engines/ConPVP/Games/KingOfTheHill.cs b/Projects/Scripts/Engines/ConPVP/Games/KingOfTheHill.cs index 5beded8eb..188ea8670 100644 --- a/Projects/Scripts/Engines/ConPVP/Games/KingOfTheHill.cs +++ b/Projects/Scripts/Engines/ConPVP/Games/KingOfTheHill.cs @@ -171,8 +171,7 @@ namespace Server.Engines.ConPVP King = m; - if (m_KingTimer == null) - m_KingTimer = new KingTimer(this); + m_KingTimer ??= new KingTimer(this); m_KingTimer.Stop(); m_KingTimer.StartHillTicker(); @@ -1113,12 +1112,13 @@ namespace Server.Engines.ConPVP for (int i = 0; i < m_Context.Participants.Count; ++i) { - if (!(m_Context.Participants[i] is Participant p) || p.Players == null) + DuelPlayer[] players = m_Context.Participants[i]?.Players; + if (players == null) continue; - for (int j = 0; j < p.Players.Length; ++j) + for (int j = 0; j < players.Length; ++j) { - DuelPlayer dp = p.Players[j]; + DuelPlayer dp = players[j]; if (dp?.Mobile != null) { @@ -1130,10 +1130,9 @@ namespace Server.Engines.ConPVP if (i == winner?.TeamID) continue; - if (p.Players != null) - for (int j = 0; j < p.Players.Length; ++j) - if (p.Players[j] != null) - p.Players[j].Eliminated = true; + for (int j = 0; j < players.Length; ++j) + if (players[j] != null) + players[j].Eliminated = true; } if (winner != null) @@ -1149,7 +1148,7 @@ namespace Server.Engines.ConPVP if (Controller.Hills[i] != null) Controller.Hills[i].Game = null; - foreach (KHBoard board in Controller.Boards) + foreach (var board in Controller.Boards) if (board != null) board.m_Game = null; diff --git a/Projects/Scripts/Engines/ConPVP/Games/TourneyMatch.cs b/Projects/Scripts/Engines/ConPVP/Games/TourneyMatch.cs index 1642a504f..e14e4840e 100644 --- a/Projects/Scripts/Engines/ConPVP/Games/TourneyMatch.cs +++ b/Projects/Scripts/Engines/ConPVP/Games/TourneyMatch.cs @@ -106,7 +106,7 @@ namespace Server.Engines.ConPVP foreach (Mobile view in mob.GetMobilesInRange(18)) if (!mob.CanSee(view)) - mob.Send(view.RemovePacket); + Packets.SendRemoveEntity(mob.NetState, view.Serial); mob.LocalOverheadMessage(MessageType.Emote, 0x3B2, false, "* Your mind focuses intently on the fight and all other distractions fade away *"); diff --git a/Projects/Scripts/Engines/ConPVP/Gumps/RulesetGump.cs b/Projects/Scripts/Engines/ConPVP/Gumps/RulesetGump.cs index f1359bae4..fe6842107 100644 --- a/Projects/Scripts/Engines/ConPVP/Gumps/RulesetGump.cs +++ b/Projects/Scripts/Engines/ConPVP/Gumps/RulesetGump.cs @@ -93,9 +93,7 @@ namespace Server.Engines.ConPVP for (int i = 0; i < info.Switches.Length; ++i) { int sid = info.Switches[i]; - - if (sid >= 0 && sid < m_Page.Options.Length) - opts[sid] = true; + opts[sid] |= sid >= 0 && sid < m_Page.Options.Length; } for (int i = 0; i < opts.Length; ++i) diff --git a/Projects/Scripts/Engines/ConPVP/Participant.cs b/Projects/Scripts/Engines/ConPVP/Participant.cs index 2f83d7fbe..9c5f8fbe1 100644 --- a/Projects/Scripts/Engines/ConPVP/Participant.cs +++ b/Projects/Scripts/Engines/ConPVP/Participant.cs @@ -173,7 +173,7 @@ namespace Server.Engines.ConPVP } Resize(Players.Length + 1); - Players[Players.Length - 1] = new DuelPlayer(player, this); + Players[^1] = new DuelPlayer(player, this); } public void Resize(int count) diff --git a/Projects/Scripts/Engines/ConPVP/Tournament.cs b/Projects/Scripts/Engines/ConPVP/Tournament.cs index bd2e9c569..355498447 100644 --- a/Projects/Scripts/Engines/ConPVP/Tournament.cs +++ b/Projects/Scripts/Engines/ConPVP/Tournament.cs @@ -433,7 +433,7 @@ namespace Server.Engines.ConPVP if (Pyramid.Levels.Count < 1) break; - PyramidLevel top = Pyramid.Levels[Pyramid.Levels.Count - 1]; + PyramidLevel top = Pyramid.Levels[^1]; if (top.FreeAdvance != null || top.Matches.Count != 1) break; @@ -451,7 +451,7 @@ namespace Server.Engines.ConPVP if (Pyramid.Levels.Count < 2) break; - PyramidLevel top = Pyramid.Levels[Pyramid.Levels.Count - 1]; + PyramidLevel top = Pyramid.Levels[^1]; if (top.FreeAdvance != null || top.Matches.Count != 1) break; @@ -471,7 +471,7 @@ namespace Server.Engines.ConPVP GiveAwards(part.Players, TrophyRank.Silver, cash / 2); } - PyramidLevel next = Pyramid.Levels[Pyramid.Levels.Count - 2]; + PyramidLevel next = Pyramid.Levels[^2]; if (next.Matches.Count > 2) break; @@ -495,7 +495,7 @@ namespace Server.Engines.ConPVP } } - private void GiveAwards(List players, TrophyRank rank, int cash) + private void GiveAwards(IReadOnlyList players, TrophyRank rank, int cash) { if (players.Count == 0) return; @@ -663,69 +663,39 @@ namespace Server.Engines.ConPVP try { if (EventController != null) - { Alert("The tournament has completed!", $"Team {EventController.GetTeamName(Pyramid.Levels[0].Matches[0].Participants.IndexOf(winner))} has won!"); - } else if (TourneyType == TourneyType.RandomTeam) - { Alert("The tournament has completed!", $"Team {Pyramid.Levels[0].Matches[0].Participants.IndexOf(winner) + 1} has won!"); - } else if (TourneyType == TourneyType.Faction) { if (m_ParticipantsPerMatch == 4) { - string name = "(null)"; - - switch (Pyramid.Levels[0].Matches[0].Participants.IndexOf( - winner)) + string name = Pyramid.Levels[0].Matches[0].Participants.IndexOf(winner) switch { - case 0: - { - name = "Minax"; - break; - } - case 1: - { - name = "Council of Mages"; - break; - } - case 2: - { - name = "True Britannians"; - break; - } - case 3: - { - name = "Shadowlords"; - break; - } - } + 0 => "Minax", + 1 => "Council of Mages", + 2 => "True Britannians", + 3 => "Shadowlords", + _ => "(null)" + }; Alert("The tournament has completed!", $"The {name} team has won!"); } else if (m_ParticipantsPerMatch == 2) - { Alert("The tournament has completed!", $"The {(Pyramid.Levels[0].Matches[0].Participants.IndexOf(winner) == 0 ? "Evil" : "Hero")} team has won!"); - } else - { Alert("The tournament has completed!", $"Team {Pyramid.Levels[0].Matches[0].Participants.IndexOf(winner) + 1} has won!"); - } } else if (TourneyType == TourneyType.RedVsBlue) - { Alert("The tournament has completed!", $"Team {(Pyramid.Levels[0].Matches[0].Participants.IndexOf(winner) == 0 ? "Red" : "Blue")} has won!"); - } else - { Alert("The tournament has completed!", $"{winner.NameList} {(winner.Players.Count > 1 ? "are" : "is")} the champion{(winner.Players.Count == 1 ? "" : "s")}."); - } } catch { @@ -739,7 +709,7 @@ namespace Server.Engines.ConPVP } else if (Pyramid.Levels.Count > 0) { - PyramidLevel activeLevel = Pyramid.Levels[Pyramid.Levels.Count - 1]; + PyramidLevel activeLevel = Pyramid.Levels[^1]; bool stillGoing = false; for (int i = 0; i < activeLevel.Matches.Count; ++i) @@ -846,7 +816,6 @@ namespace Server.Engines.ConPVP $"The {(Pyramid.Levels[0].Matches[0].Participants.IndexOf(winner) == 0 ? "Evil" : "Hero")} team has won!"); } else - { Alert("The tournament has completed!", $"Team {Pyramid.Levels[0].Matches[0].Participants.IndexOf(winner) + 1} has won!"); } diff --git a/Projects/Scripts/Engines/Craft/Core/CraftItem.cs b/Projects/Scripts/Engines/Craft/Core/CraftItem.cs index 23611a3ed..c53651f36 100644 --- a/Projects/Scripts/Engines/Craft/Core/CraftItem.cs +++ b/Projects/Scripts/Engines/Craft/Core/CraftItem.cs @@ -484,8 +484,7 @@ namespace Server.Engines.Craft if (m_TypesTable[j][0] == baseType) types[i] = m_TypesTable[j]; - if (types[i] == null) - types[i] = new[] { baseType }; + types[i] ??= new[] { baseType }; amounts[i] = craftRes.Amount; @@ -910,8 +909,7 @@ namespace Server.Engines.Craft hammer.Delete(); } - if (tool.UsesRemaining < 1 && tool.BreakOnDepletion) - toolBroken = true; + toolBroken |= tool.UsesRemaining < 1 && tool.BreakOnDepletion; if (toolBroken) tool.Delete(); @@ -1033,8 +1031,7 @@ namespace Server.Engines.Craft tool.UsesRemaining--; - if (tool.UsesRemaining < 1 && tool.BreakOnDepletion) - toolBroken = true; + toolBroken |= tool.UsesRemaining < 1 && tool.BreakOnDepletion; if (toolBroken) tool.Delete(); diff --git a/Projects/Scripts/Engines/Craft/Core/Recipes.cs b/Projects/Scripts/Engines/Craft/Core/Recipes.cs index a2b3578c3..74e5179d1 100644 --- a/Projects/Scripts/Engines/Craft/Core/Recipes.cs +++ b/Projects/Scripts/Engines/Craft/Core/Recipes.cs @@ -33,7 +33,7 @@ namespace Server.Engines.Craft public int ID{ get; } - public TextDefinition TextDefinition => m_TD ?? (m_TD = new TextDefinition(CraftItem.NameNumber, CraftItem.NameString)); + public TextDefinition TextDefinition => m_TD ??= new TextDefinition(CraftItem.NameNumber, CraftItem.NameString); public static void Initialize() { @@ -52,15 +52,13 @@ namespace Server.Engines.Craft { if (targeted is PlayerMobile mobile) { - foreach (KeyValuePair kvp in Recipes) - mobile.AcquireRecipe(kvp.Key); + foreach (var (key, _) in Recipes) + mobile.AcquireRecipe(key); m.SendMessage("You teach them all of the recipes."); } else - { m.SendMessage("That is not a player!"); - } }); } @@ -86,4 +84,4 @@ namespace Server.Engines.Craft }); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Engines/Craft/Core/Repair.cs b/Projects/Scripts/Engines/Craft/Core/Repair.cs index 2d74fc499..2fff2c4cb 100644 --- a/Projects/Scripts/Engines/Craft/Core/Repair.cs +++ b/Projects/Scripts/Engines/Craft/Core/Repair.cs @@ -491,7 +491,7 @@ namespace Server.Engines.Craft if (!usingDeed) { - CraftContext context = m_CraftSystem.GetContext(from); + m_CraftSystem.GetContext(from); from.SendGump(new CraftGump(from, m_CraftSystem, m_Tool, number)); } else @@ -504,4 +504,4 @@ namespace Server.Engines.Craft } } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Engines/Craft/DefAlchemy.cs b/Projects/Scripts/Engines/Craft/DefAlchemy.cs index 85746fc1f..bfdeef6c8 100644 --- a/Projects/Scripts/Engines/Craft/DefAlchemy.cs +++ b/Projects/Scripts/Engines/Craft/DefAlchemy.cs @@ -17,7 +17,7 @@ namespace Server.Engines.Craft public override int GumpTitleNumber => 1044001; - public static CraftSystem CraftSystem => m_CraftSystem ?? (m_CraftSystem = new DefAlchemy()); + public static CraftSystem CraftSystem => m_CraftSystem ??= new DefAlchemy(); public override double GetChanceAtMin(CraftItem item) => 0.0; diff --git a/Projects/Scripts/Engines/Craft/DefBlacksmithy.cs b/Projects/Scripts/Engines/Craft/DefBlacksmithy.cs index c68c961ab..a5f98f5b4 100644 --- a/Projects/Scripts/Engines/Craft/DefBlacksmithy.cs +++ b/Projects/Scripts/Engines/Craft/DefBlacksmithy.cs @@ -30,7 +30,7 @@ namespace Server.Engines.Craft public override int GumpTitleNumber => 1044002; - public static CraftSystem CraftSystem => m_CraftSystem ?? (m_CraftSystem = new DefBlacksmithy()); + public static CraftSystem CraftSystem => m_CraftSystem ??= new DefBlacksmithy(); public override CraftECA ECA => CraftECA.ChanceMinusSixtyToFourtyFive; diff --git a/Projects/Scripts/Engines/Craft/DefBowFletching.cs b/Projects/Scripts/Engines/Craft/DefBowFletching.cs index 1af14ebf7..c5a676fb8 100644 --- a/Projects/Scripts/Engines/Craft/DefBowFletching.cs +++ b/Projects/Scripts/Engines/Craft/DefBowFletching.cs @@ -15,7 +15,7 @@ namespace Server.Engines.Craft public override int GumpTitleNumber => 1044006; - public static CraftSystem CraftSystem => m_CraftSystem ?? (m_CraftSystem = new DefBowFletching()); + public static CraftSystem CraftSystem => m_CraftSystem ??= new DefBowFletching(); public override CraftECA ECA => CraftECA.FiftyPercentChanceMinusTenPercent; diff --git a/Projects/Scripts/Engines/Craft/DefCarpentry.cs b/Projects/Scripts/Engines/Craft/DefCarpentry.cs index 4e965a2f0..3d2427ce9 100644 --- a/Projects/Scripts/Engines/Craft/DefCarpentry.cs +++ b/Projects/Scripts/Engines/Craft/DefCarpentry.cs @@ -15,7 +15,7 @@ namespace Server.Engines.Craft public override int GumpTitleNumber => 1044004; - public static CraftSystem CraftSystem => m_CraftSystem ?? (m_CraftSystem = new DefCarpentry()); + public static CraftSystem CraftSystem => m_CraftSystem ??= new DefCarpentry(); public override double GetChanceAtMin(CraftItem item) => 0.5; diff --git a/Projects/Scripts/Engines/Craft/DefCartography.cs b/Projects/Scripts/Engines/Craft/DefCartography.cs index 370664838..3da613c7a 100644 --- a/Projects/Scripts/Engines/Craft/DefCartography.cs +++ b/Projects/Scripts/Engines/Craft/DefCartography.cs @@ -15,7 +15,7 @@ namespace Server.Engines.Craft public override int GumpTitleNumber => 1044008; - public static CraftSystem CraftSystem => m_CraftSystem ?? (m_CraftSystem = new DefCartography()); + public static CraftSystem CraftSystem => m_CraftSystem ??= new DefCartography(); public override double GetChanceAtMin(CraftItem item) => 0.0; diff --git a/Projects/Scripts/Engines/Craft/DefCooking.cs b/Projects/Scripts/Engines/Craft/DefCooking.cs index b37f7d4af..242cae9f8 100644 --- a/Projects/Scripts/Engines/Craft/DefCooking.cs +++ b/Projects/Scripts/Engines/Craft/DefCooking.cs @@ -15,7 +15,7 @@ namespace Server.Engines.Craft public override int GumpTitleNumber => 1044003; - public static CraftSystem CraftSystem => m_CraftSystem ?? (m_CraftSystem = new DefCooking()); + public static CraftSystem CraftSystem => m_CraftSystem ??= new DefCooking(); public override CraftECA ECA => CraftECA.ChanceMinusSixtyToFourtyFive; diff --git a/Projects/Scripts/Engines/Craft/DefGlassblowing.cs b/Projects/Scripts/Engines/Craft/DefGlassblowing.cs index 4daf3d40f..edfe0a8b4 100644 --- a/Projects/Scripts/Engines/Craft/DefGlassblowing.cs +++ b/Projects/Scripts/Engines/Craft/DefGlassblowing.cs @@ -16,7 +16,7 @@ namespace Server.Engines.Craft public override int GumpTitleNumber => 1044622; - public static CraftSystem CraftSystem => m_CraftSystem ?? (m_CraftSystem = new DefGlassblowing()); + public static CraftSystem CraftSystem => m_CraftSystem ??= new DefGlassblowing(); public override double GetChanceAtMin(CraftItem item) => item.ItemType == typeof(HollowPrism) ? 0.5 : 0.0; diff --git a/Projects/Scripts/Engines/Craft/DefInscription.cs b/Projects/Scripts/Engines/Craft/DefInscription.cs index d8a5892eb..42a884656 100644 --- a/Projects/Scripts/Engines/Craft/DefInscription.cs +++ b/Projects/Scripts/Engines/Craft/DefInscription.cs @@ -36,7 +36,7 @@ namespace Server.Engines.Craft public override int GumpTitleNumber => 1044009; - public static CraftSystem CraftSystem => m_CraftSystem ?? (m_CraftSystem = new DefInscription()); + public static CraftSystem CraftSystem => m_CraftSystem ??= new DefInscription(); public override double GetChanceAtMin(CraftItem item) => 0.0; diff --git a/Projects/Scripts/Engines/Craft/DefMasonry.cs b/Projects/Scripts/Engines/Craft/DefMasonry.cs index 66b193e29..a4aefbb5c 100644 --- a/Projects/Scripts/Engines/Craft/DefMasonry.cs +++ b/Projects/Scripts/Engines/Craft/DefMasonry.cs @@ -16,7 +16,7 @@ namespace Server.Engines.Craft public override int GumpTitleNumber => 1044500; - public static CraftSystem CraftSystem => m_CraftSystem ?? (m_CraftSystem = new DefMasonry()); + public static CraftSystem CraftSystem => m_CraftSystem ??= new DefMasonry(); public override double GetChanceAtMin(CraftItem item) => 0.0; diff --git a/Projects/Scripts/Engines/Craft/DefTailoring.cs b/Projects/Scripts/Engines/Craft/DefTailoring.cs index cc4185fb8..826b3fc21 100644 --- a/Projects/Scripts/Engines/Craft/DefTailoring.cs +++ b/Projects/Scripts/Engines/Craft/DefTailoring.cs @@ -23,7 +23,7 @@ namespace Server.Engines.Craft public override int GumpTitleNumber => 1044005; - public static CraftSystem CraftSystem => m_CraftSystem ?? (m_CraftSystem = new DefTailoring()); + public static CraftSystem CraftSystem => m_CraftSystem ??= new DefTailoring(); public override CraftECA ECA => CraftECA.ChanceMinusSixtyToFourtyFive; diff --git a/Projects/Scripts/Engines/Craft/DefTinkering.cs b/Projects/Scripts/Engines/Craft/DefTinkering.cs index e2cd7f346..f38af4961 100644 --- a/Projects/Scripts/Engines/Craft/DefTinkering.cs +++ b/Projects/Scripts/Engines/Craft/DefTinkering.cs @@ -31,7 +31,7 @@ namespace Server.Engines.Craft public override int GumpTitleNumber => 1044007; - public static CraftSystem CraftSystem => m_CraftSystem ?? (m_CraftSystem = new DefTinkering()); + public static CraftSystem CraftSystem => m_CraftSystem ??= new DefTinkering(); public override double GetChanceAtMin(CraftItem item) { diff --git a/Projects/Scripts/Engines/Doom/LeverPuzzle/LeverPuzzleController.cs b/Projects/Scripts/Engines/Doom/LeverPuzzle/LeverPuzzleController.cs index 4dbad8c90..de6aca895 100644 --- a/Projects/Scripts/Engines/Doom/LeverPuzzle/LeverPuzzleController.cs +++ b/Projects/Scripts/Engines/Doom/LeverPuzzle/LeverPuzzleController.cs @@ -5,11 +5,6 @@ using Server.Mobiles; using Server.Network; using Server.Spells; -/* - this is From me to you, Under no terms, Conditions... K? to apply you - just simply Unpatch/delete, Stick these in, Same location.. Restart - */ - namespace Server.Engines.Doom { public class LeverPuzzleController : Item @@ -326,7 +321,7 @@ namespace Server.Engines.Doom SendLocationEffect(lp_Center, 0x1153, 0, 60, 1); PlaySounds(lp_Center, cs1); - Effects.SendBoltEffect(player, true); + Effects.SendBoltEffect(player); player.MoveToWorld(lr_Enter, Map.Malas); m_Timer = new LampRoomTimer(this); @@ -417,25 +412,24 @@ namespace Server.Engines.Doom public static void SendLocationEffect(IPoint3D p, int itemID, int speed, int duration, int hue) { - Effects.SendPacket(p, Map.Malas, new LocationEffect(p, itemID, speed, duration, hue, 0)); + Effects.SendLocationEffect(p, Map.Malas, itemID, speed, duration, hue); } public static void PlayerSendASCII(Mobile player, int index) { - player.Send(new AsciiMessage(Serial.MinusOne, 0xFFFF, MessageType.Label, MsgParams[index][0], - MsgParams[index][1], null, Msgs[index])); + Packets.SendAsciiMessage(player.NetState, Serial.MinusOne, 0xFFFF, MessageType.Label, MsgParams[index][0], + MsgParams[index][1], null, Msgs[index]); } /* I cant find any better way to send "speech" using fonts other than default */ public static void POHMessage(Mobile from, int index) { - Packet p = new AsciiMessage(from.Serial, from.Body, MessageType.Regular, MsgParams[index][0], + IPooledEnumerable eable = from.Map.GetClientsInRange(from.Location); + foreach (NetState state in eable) + Packets.SendAsciiMessage(state, from.Serial, from.Body, MessageType.Regular, MsgParams[index][0], MsgParams[index][1], from.Name, Msgs[index]); - p.Acquire(); - foreach (NetState state in from.Map.GetClientsInRange(from.Location)) - state.Send(p); - Packet.Release(p); + eable.Free(); } public override void Serialize(GenericWriter writer) diff --git a/Projects/Scripts/Engines/Doom/LeverPuzzle/LeverPuzzleItems.cs b/Projects/Scripts/Engines/Doom/LeverPuzzle/LeverPuzzleItems.cs index 967aaa563..322b3ea97 100644 --- a/Projects/Scripts/Engines/Doom/LeverPuzzle/LeverPuzzleItems.cs +++ b/Projects/Scripts/Engines/Doom/LeverPuzzle/LeverPuzzleItems.cs @@ -39,7 +39,7 @@ namespace Server.Engines.Doom public void CallBackMessage() { - PublicOverheadMessage(MessageType.Regular, 0x3B2, 1060003, ""); // You try to pry the box open... + PublicOverheadMessage(MessageType.Regular, 0x3B2, 1060003); // You try to pry the box open... } public override void OnAfterDelete() diff --git a/Projects/Scripts/Engines/Doom/LeverPuzzle/LeverPuzzleRegions.cs b/Projects/Scripts/Engines/Doom/LeverPuzzle/LeverPuzzleRegions.cs index 193961bae..443285803 100644 --- a/Projects/Scripts/Engines/Doom/LeverPuzzle/LeverPuzzleRegions.cs +++ b/Projects/Scripts/Engines/Doom/LeverPuzzle/LeverPuzzleRegions.cs @@ -77,17 +77,15 @@ namespace Server.Engines.Doom public Mobile m_Occupant; public LeverPuzzleRegion(LeverPuzzleController controller, int[] loc) - : base(null, Map.Malas, Find(LeverPuzzleController.lr_Enter, Map.Malas), new Rectangle2D(loc[0], loc[1], 1, 1)) - { + : base(null, Map.Malas, Find(LeverPuzzleController.lr_Enter, Map.Malas), new Rectangle2D(loc[0], loc[1], 1, 1)) => Register(); - } [CommandProperty(AccessLevel.GameMaster)] public Mobile Occupant => m_Occupant?.Alive == true ? m_Occupant : null; public override void OnEnter(Mobile m) { - if (m != null && m_Occupant == null && m is PlayerMobile && m.Alive) + if (m_Occupant == null && m is PlayerMobile && m.Alive) m_Occupant = m; } diff --git a/Projects/Scripts/Engines/Ethics/Core/Ethic.cs b/Projects/Scripts/Engines/Ethics/Core/Ethic.cs index 555add67a..7cf6bbb93 100644 --- a/Projects/Scripts/Engines/Ethics/Core/Ethic.cs +++ b/Projects/Scripts/Engines/Ethics/Core/Ethic.cs @@ -93,8 +93,8 @@ namespace Server.Ethics if (IsImbued(child, true)) return true; - return false; - } + public static bool IsImbued(Item item, bool recurse) => + Find(item) != null || recurse && item.Items.Any(child => IsImbued(child, true)); public static void Initialize() { diff --git a/Projects/Scripts/Engines/Ethics/Evil/Powers/Blight.cs b/Projects/Scripts/Engines/Ethics/Evil/Powers/Blight.cs index 59a4216e4..3d1d981cd 100644 --- a/Projects/Scripts/Engines/Ethics/Evil/Powers/Blight.cs +++ b/Projects/Scripts/Engines/Ethics/Evil/Powers/Blight.cs @@ -33,7 +33,9 @@ namespace Server.Ethics.Evil SpellHelper.GetSurfaceTop(ref p); - foreach (Mobile mob in from.Mobile.GetMobilesInRange(6)) + IPooledEnumerable eable = from.Mobile.GetMobilesInRange(6); + + foreach (Mobile mob in eable) { if (mob == from.Mobile || !SpellHelper.ValidIndirectTarget(from.Mobile, mob)) continue; @@ -54,6 +56,8 @@ namespace Server.Ethics.Evil powerFunctioned = true; } + eable.Free(); + if (powerFunctioned) { SpellHelper.Turn(from.Mobile, p); @@ -71,4 +75,4 @@ namespace Server.Ethics.Evil } } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Engines/Ethics/Evil/Powers/UnholySense.cs b/Projects/Scripts/Engines/Ethics/Evil/Powers/UnholySense.cs index faf336aad..d62d6ea36 100644 --- a/Projects/Scripts/Engines/Ethics/Evil/Powers/UnholySense.cs +++ b/Projects/Scripts/Engines/Ethics/Evil/Powers/UnholySense.cs @@ -80,13 +80,11 @@ namespace Server.Ethics.Evil } } else - { sb.Append('.'); - } from.Mobile.LocalOverheadMessage(MessageType.Regular, 0x59, false, sb.ToString()); FinishInvoke(from); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Engines/Ethics/Hero/Powers/Bless.cs b/Projects/Scripts/Engines/Ethics/Hero/Powers/Bless.cs index f6ecfc8a6..b08df7afe 100644 --- a/Projects/Scripts/Engines/Ethics/Hero/Powers/Bless.cs +++ b/Projects/Scripts/Engines/Ethics/Hero/Powers/Bless.cs @@ -33,7 +33,9 @@ namespace Server.Ethics.Hero SpellHelper.GetSurfaceTop(ref p); - foreach (Mobile mob in from.Mobile.GetMobilesInRange(6)) + IPooledEnumerable eable = from.Mobile.GetMobilesInRange(6); + + foreach (Mobile mob in eable) { if (mob != from.Mobile && SpellHelper.ValidIndirectTarget(from.Mobile, mob)) continue; @@ -54,6 +56,8 @@ namespace Server.Ethics.Hero powerFunctioned = true; } + eable.Free(); + if (powerFunctioned) { SpellHelper.Turn(from.Mobile, p); @@ -71,4 +75,4 @@ namespace Server.Ethics.Hero } } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Engines/Ethics/Hero/Powers/HolySense.cs b/Projects/Scripts/Engines/Ethics/Hero/Powers/HolySense.cs index dff3df97c..9a625cc2b 100644 --- a/Projects/Scripts/Engines/Ethics/Hero/Powers/HolySense.cs +++ b/Projects/Scripts/Engines/Ethics/Hero/Powers/HolySense.cs @@ -80,13 +80,11 @@ namespace Server.Ethics.Hero } } else - { sb.Append('.'); - } from.Mobile.LocalOverheadMessage(MessageType.Regular, 0x59, false, sb.ToString()); FinishInvoke(from); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Engines/Factions/Core/Faction.cs b/Projects/Scripts/Engines/Factions/Core/Faction.cs index 4f9e0c0a4..39861a99a 100644 --- a/Projects/Scripts/Engines/Factions/Core/Faction.cs +++ b/Projects/Scripts/Engines/Factions/Core/Faction.cs @@ -8,7 +8,6 @@ using Server.Ethics; using Server.Guilds; using Server.Items; using Server.Mobiles; -using Server.Prompts; using Server.Targeting; namespace Server.Factions @@ -133,21 +132,12 @@ namespace Server.Factions public static void HandleAtrophy() { - foreach (Faction f in Factions) - if (!f.State.IsAtrophyReady) - return; + if (Factions.Any(f => !f.State.IsAtrophyReady)) + return; - List activePlayers = new List(); + List activePlayers = (from f in Factions from ps in f.Members where ps.KillPoints > 0 && ps.IsActive select ps).ToList(); - foreach (Faction f in Factions) - foreach (PlayerState ps in f.Members) - if (ps.KillPoints > 0 && ps.IsActive) - activePlayers.Add(ps); - - int distrib = 0; - - foreach (Faction f in Factions) - distrib += f.State.CheckAtrophy(); + int distrib = Factions.Sum(f => f.State.CheckAtrophy()); if (activePlayers.Count == 0) return; @@ -158,12 +148,7 @@ namespace Server.Factions public static void DistributePoints(int distrib) { - List activePlayers = new List(); - - foreach (Faction f in Factions) - foreach (PlayerState ps in f.Members) - if (ps.KillPoints > 0 && ps.IsActive) - activePlayers.Add(ps); + List activePlayers = (from f in Factions from ps in f.Members where ps.KillPoints > 0 && ps.IsActive select ps).ToList(); if (activePlayers.Count > 0) for (int i = 0; i < distrib; ++i) @@ -187,13 +172,9 @@ namespace Server.Factions return; if (recvState == null || recvState.Faction != giveState.Faction) - { from.SendLocalizedMessage(1042497); // Only faction mates can be honored this way. - } else if (giveState.KillPoints < 5) - { from.SendLocalizedMessage(1042499); // You must have at least five kill points to honor them. - } else { recvState.LastHonorTime = DateTime.UtcNow; @@ -205,9 +186,7 @@ namespace Server.Factions } } else - { from.SendLocalizedMessage(1042496); // You may only honor another player. - } } public virtual void AddMember(Mobile mob) @@ -649,11 +628,7 @@ namespace Server.Factions public static void FactionItemReset_OnCommand(CommandEventArgs e) { - List items = new List(); - - foreach (Item item in World.Items.Values) - if (item is IFactionItem && !(item is HoodedShroudOfShadows)) - items.Add(item); + List items = World.Items.Values.Where(item => item is IFactionItem && !(item is HoodedShroudOfShadows)).ToList(); int[] hues = new int[Factions.Count * 2]; @@ -673,16 +648,7 @@ namespace Server.Factions if (fci.FactionItemState != null || item.LootType != LootType.Blessed) continue; - bool isHued = false; - - for (int j = 0; j < hues.Length; ++j) - if (item.Hue == hues[j]) - { - isHued = true; - break; - } - - if (isHued) + if (hues.Any(t => item.Hue == t)) { fci.FactionItemState = null; ++count; @@ -841,7 +807,7 @@ namespace Server.Factions Silver += tithed; - silver = silver - tithed; + silver -= tithed; if (silver > 0) mob.AddToBackpack(new Silver(silver)); @@ -887,19 +853,12 @@ namespace Server.Factions Faction smallest = FindSmallestFaction(); - if (smallest == null) - return true; // sanity - - if ((Members.Count + influx) * 100 / StabilityFactor > smallest.Members.Count) - return false; - - return true; + return smallest == null || (Members.Count + influx) * 100 / StabilityFactor <= smallest.Members.Count; } public static void HandleDeath(Mobile victim, Mobile killer) { - if (killer == null) - killer = victim.FindMostRecentDamager(true); + killer ??= victim.FindMostRecentDamager(true); PlayerState killerState = PlayerState.Find(killer); Container killerPack = killer?.Backpack; @@ -941,7 +900,7 @@ namespace Server.Factions int silver = killerState.Faction.AwardSilver(killer, bc.FactionSilverWorth); if (silver > 0) - killer.SendLocalizedMessage(1042748, + killer?.SendLocalizedMessage(1042748, silver.ToString("N0")); // Thou hast earned ~1_AMOUNT~ silver for vanquishing the vile creature. } @@ -982,7 +941,7 @@ namespace Server.Factions { if (victimState.KillPoints <= -6) { - killer.SendLocalizedMessage(501693); // This victim is not worth enough to get kill points from. + killer?.SendLocalizedMessage(501693); // This victim is not worth enough to get kill points from. #region Ethics @@ -1024,13 +983,12 @@ namespace Server.Factions { victimState.IsActive = true; - if (1 > Utility.Random(3)) - killerState.IsActive = true; + killerState.IsActive |= 1 > Utility.Random(3); int silver = killerState.Faction.AwardSilver(killer, award * 40); if (silver > 0) - killer.SendLocalizedMessage(1042736, + killer?.SendLocalizedMessage(1042736, $"{silver:N0} silver\t{victim.Name}"); // You have earned ~1_SILVER_AMOUNT~ pieces for vanquishing ~2_PLAYER_NAME~! } @@ -1039,9 +997,9 @@ namespace Server.Factions int offset = award != 1 ? 0 : 2; // for pluralization - string args = $"{award}\t{victim.Name}\t{killer.Name}"; + string args = $"{award}\t{victim.Name}\t{killer?.Name ?? ""}"; - killer.SendLocalizedMessage(1042737 + offset, + killer?.SendLocalizedMessage(1042737 + offset, args); // Thou hast been honored with ~1_KILL_POINTS~ kill point(s) for vanquishing ~2_DEAD_PLAYER~! victim.SendLocalizedMessage(1042738 + offset, args); // Thou has lost ~1_KILL_POINTS~ kill point(s) to ~3_ATTACKER_NAME~ for being vanquished! @@ -1073,7 +1031,7 @@ namespace Server.Factions } else { - killer.SendLocalizedMessage( + killer?.SendLocalizedMessage( 1042231); // You have recently defeated this enemy and thus their death brings you no honor. } } @@ -1284,9 +1242,7 @@ namespace Server.Factions AddResponse("They have been kicked from their faction."); } else - { LogFailure("They are not in a faction."); - } break; } @@ -1300,9 +1256,7 @@ namespace Server.Factions AddResponse("The account has been banned from joining factions."); } else - { AddResponse("The account is already banned from joining factions."); - } for (int i = 0; i < acct.Length; ++i) { @@ -1322,9 +1276,7 @@ namespace Server.Factions } } else - { LogFailure("They have no assigned account."); - } break; } @@ -1333,9 +1285,7 @@ namespace Server.Factions if (mob.Account is Account acct) { if (acct.GetTag("FactionBanned") == null) - { AddResponse("The account is not already banned from joining factions."); - } else { acct.RemoveTag("FactionBanned"); @@ -1343,9 +1293,7 @@ namespace Server.Factions } } else - { LogFailure("They have no assigned account."); - } break; } diff --git a/Projects/Scripts/Engines/Factions/Core/PlayerState.cs b/Projects/Scripts/Engines/Factions/Core/PlayerState.cs index 121b8a7fe..2425ba99f 100644 --- a/Projects/Scripts/Engines/Factions/Core/PlayerState.cs +++ b/Projects/Scripts/Engines/Factions/Core/PlayerState.cs @@ -260,9 +260,7 @@ namespace Server.Factions public void OnGivenSilverTo(Mobile mob) { - if (SilverGiven == null) - SilverGiven = new List(); - + SilverGiven ??= new List(); SilverGiven.Add(new SilverGivenEntry(mob)); } diff --git a/Projects/Scripts/Engines/Factions/Items/Power Faction Items/PowerFactionItem.cs b/Projects/Scripts/Engines/Factions/Items/Power Faction Items/PowerFactionItem.cs index 77e3baa4b..1039a98ad 100644 --- a/Projects/Scripts/Engines/Factions/Items/Power Faction Items/PowerFactionItem.cs +++ b/Projects/Scripts/Engines/Factions/Items/Power Faction Items/PowerFactionItem.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Linq; using Server.Factions; using Server.Mobiles; using Server.Network; @@ -41,9 +42,7 @@ namespace Server if (chance > Utility.Random(100)) { - int weight = 0; - - foreach (WeightedItem item in _items) weight += item.Weight; + int weight = _items.Sum(item => item.Weight); weight = Utility.Random(weight); @@ -177,4 +176,4 @@ namespace Server public Item Construct() => Activator.CreateInstance(Type) as Item; } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Engines/Factions/Items/Power Faction Items/UrnOfAscension.cs b/Projects/Scripts/Engines/Factions/Items/Power Faction Items/UrnOfAscension.cs index 08b088de7..b03886141 100644 --- a/Projects/Scripts/Engines/Factions/Items/Power Faction Items/UrnOfAscension.cs +++ b/Projects/Scripts/Engines/Factions/Items/Power Faction Items/UrnOfAscension.cs @@ -25,7 +25,9 @@ namespace Server bool used = false; - foreach (Mobile mob in from.GetMobilesInRange(8)) + IPooledEnumerable eable = from.GetMobilesInRange(8); + + foreach (Mobile mob in eable) if (mob.Player && !mob.Alive && from.InLOS(mob)) { if (Faction.Find(mob) != ourFaction) continue; @@ -41,6 +43,8 @@ namespace Server } } + eable.Free(); + if (used) { from.LocalOverheadMessage(MessageType.Regular, 2219, false, "The urn shatters as you invoke its power."); diff --git a/Projects/Scripts/Engines/Factions/Items/Traps/BaseFactionTrap.cs b/Projects/Scripts/Engines/Factions/Items/Traps/BaseFactionTrap.cs index 898f40b5f..f54142a40 100644 --- a/Projects/Scripts/Engines/Factions/Items/Traps/BaseFactionTrap.cs +++ b/Projects/Scripts/Engines/Factions/Items/Traps/BaseFactionTrap.cs @@ -113,10 +113,15 @@ namespace Server.Factions return 502956; // You cannot place a trap on that. if (Core.ML) - foreach (Item item in m.GetItemsInRange(p, 0)) + { + IPooledEnumerable eable = m.GetItemsInRange(p, 0); + foreach (Item item in eable) if (item is BaseFactionTrap trap && trap.Faction == Faction) return 1075263; // There is already a trap belonging to your faction at this location.; + eable.Free(); + } + switch (AllowedPlacing) { case AllowedPlacing.FactionStronghold: @@ -129,22 +134,12 @@ namespace Server.Factions return 1010355; // This trap can only be placed in your stronghold } case AllowedPlacing.AnyFactionTown: - { - Town town = Town.FromRegion(Region.Find(p, m)); - - if (town != null) - return 0; - - return 1010356; // This trap can only be placed in a faction town - } + return Town.FromRegion(Region.Find(p, m)) != null ? 0 : 1010356; case AllowedPlacing.ControlledFactionTown: { Town town = Town.FromRegion(Region.Find(p, m)); - if (town != null && town.Owner == Faction) - return 0; - - return 1010357; // This trap can only be placed in a town your faction controls + return town != null && town.Owner == Faction ? 0 : 1010357; } } @@ -155,17 +150,16 @@ namespace Server.Factions { base.OnMovement(m, oldLocation); - if (!CheckDecay() && CheckRange(m.Location, oldLocation, 6)) - if (Faction.Find(m) != null && - (m.Skills.DetectHidden.Value - 80.0) / 20.0 > Utility.RandomDouble()) - PrivateOverheadLocalizedMessage(m, 1010154, MessageHue, "", ""); // [Faction Trap] + if (!CheckDecay() && CheckRange(m.Location, oldLocation, 6) && + Faction.Find(m) != null && (m.Skills.DetectHidden.Value - 80.0) / 20.0 > Utility.RandomDouble()) + PrivateOverheadLocalizedMessage(m, 1010154, MessageHue, "", ""); // [Faction Trap] } public void PrivateOverheadLocalizedMessage(Mobile to, int number, int hue, string name, string args) { NetState ns = to?.NetState; - ns?.Send(new MessageLocalized(Serial, ItemID, MessageType.Regular, hue, 3, number, name, args)); + Packets.SendMessageLocalized(ns, Serial, ItemID, MessageType.Regular, hue, 3, number, name, args); } public virtual bool CheckDecay() @@ -252,10 +246,7 @@ namespace Server.Factions if (faction == null && mob is BaseFactionGuard guard) faction = guard.Faction; - if (faction == null) - return false; - - return faction != Faction; + return faction != null && faction != Faction; } } } diff --git a/Projects/Scripts/Engines/Factions/Items/Traps/FactionExplosionTrap.cs b/Projects/Scripts/Engines/Factions/Items/Traps/FactionExplosionTrap.cs index 920e5fa72..8954ac22d 100644 --- a/Projects/Scripts/Engines/Factions/Items/Traps/FactionExplosionTrap.cs +++ b/Projects/Scripts/Engines/Factions/Items/Traps/FactionExplosionTrap.cs @@ -23,7 +23,7 @@ namespace Server.Factions public override void DoVisibleEffect() { - Effects.SendLocationEffect(GetWorldLocation(), Map, 0x36BD, 15, 10); + Effects.SendLocationEffect(GetWorldLocation(), Map, 0x36BD, 15); } public override void DoAttackEffect(Mobile m) diff --git a/Projects/Scripts/Engines/Factions/Items/Traps/FactionSawTrap.cs b/Projects/Scripts/Engines/Factions/Items/Traps/FactionSawTrap.cs index 6432656ff..acc3780e9 100644 --- a/Projects/Scripts/Engines/Factions/Items/Traps/FactionSawTrap.cs +++ b/Projects/Scripts/Engines/Factions/Items/Traps/FactionSawTrap.cs @@ -8,6 +8,10 @@ namespace Server.Factions { } + public FactionSawTrap(Serial serial) : base(serial) + { + } + public override int LabelNumber => 1041047; // faction saw trap public override int AttackMessage => 1010544; // The blade cuts deep into your skin! @@ -19,7 +23,7 @@ namespace Server.Factions public override void DoVisibleEffect() { - Effects.SendLocationEffect(Location, Map, 0x11AD, 25, 10); + Effects.SendLocationEffect(Location, Map, 0x11AD, 25); } public override void DoAttackEffect(Mobile m) diff --git a/Projects/Scripts/Engines/Factions/Mobiles/Guards/GuardAI.cs b/Projects/Scripts/Engines/Factions/Mobiles/Guards/GuardAI.cs index e31baae4a..2e4d01f6f 100644 --- a/Projects/Scripts/Engines/Factions/Mobiles/Guards/GuardAI.cs +++ b/Projects/Scripts/Engines/Factions/Mobiles/Guards/GuardAI.cs @@ -313,7 +313,9 @@ namespace Server.Factions actPrio = inactPrio = m_Mobile.GetDistanceToSqrt(comb); } - foreach (Mobile m in m_Mobile.GetMobilesInRange(12)) + IPooledEnumerable eable = m_Mobile.GetMobilesInRange(12); + + foreach (Mobile m in eable) if (m != m_Mobile && CanDispel(m)) { double prio = m_Mobile.GetDistanceToSqrt(m); @@ -331,6 +333,8 @@ namespace Server.Factions } } + eable.Free(); + return active ?? inactive; } diff --git a/Projects/Scripts/Engines/Harvest/Fishing.cs b/Projects/Scripts/Engines/Harvest/Fishing.cs index 79064a01d..33bdbd705 100644 --- a/Projects/Scripts/Engines/Harvest/Fishing.cs +++ b/Projects/Scripts/Engines/Harvest/Fishing.cs @@ -23,7 +23,7 @@ namespace Server.Engines.Harvest new MutateEntry(0.0, 125.0, -2375.0, false, typeof(PrizedFish), typeof(WondrousFish), typeof(TrulyRareFish), typeof(PeculiarFish)), new MutateEntry(0.0, 105.0, -420.0, false, typeof(Boots), typeof(Shoes), typeof(Sandals), typeof(ThighBoots)), - new MutateEntry(0.0, 200.0, -200.0, false, new Type[1] { null }) + new MutateEntry(0.0, 200.0, -200.0, false, new Type[] { null }) }; private static int[] m_WaterTiles = @@ -87,7 +87,7 @@ namespace Server.Engines.Harvest Definitions.Add(fish); } - public static Fishing System => m_System ?? (m_System = new Fishing()); + public static Fishing System => m_System ??= new Fishing(); public HarvestDefinition Definition{ get; } diff --git a/Projects/Scripts/Engines/Harvest/Lumberjacking.cs b/Projects/Scripts/Engines/Harvest/Lumberjacking.cs index c66eead6c..e5b5b8ffa 100644 --- a/Projects/Scripts/Engines/Harvest/Lumberjacking.cs +++ b/Projects/Scripts/Engines/Harvest/Lumberjacking.cs @@ -126,7 +126,7 @@ namespace Server.Engines.Harvest Definitions.Add(lumber); } - public static Lumberjacking System => m_System ?? (m_System = new Lumberjacking()); + public static Lumberjacking System => m_System ??= new Lumberjacking(); public HarvestDefinition Definition{ get; } diff --git a/Projects/Scripts/Engines/Harvest/Mining.cs b/Projects/Scripts/Engines/Harvest/Mining.cs index 043ebbc52..a4091cceb 100644 --- a/Projects/Scripts/Engines/Harvest/Mining.cs +++ b/Projects/Scripts/Engines/Harvest/Mining.cs @@ -153,7 +153,7 @@ namespace Server.Engines.Harvest #endregion } - public static Mining System => m_System ?? (m_System = new Mining()); + public static Mining System => m_System ??= new Mining(); public HarvestDefinition OreAndStone{ get; } diff --git a/Projects/Scripts/Engines/Help/HelpGump.cs b/Projects/Scripts/Engines/Help/HelpGump.cs index f99b5c308..305dc5c35 100644 --- a/Projects/Scripts/Engines/Help/HelpGump.cs +++ b/Projects/Scripts/Engines/Help/HelpGump.cs @@ -1,7 +1,9 @@ using System; +using System.Linq; using Server.Engines.ConPVP; using Server.Factions; using Server.Gumps; +using Server.Menus; using Server.Menus.Questions; using Server.Mobiles; using Server.Multis; @@ -27,9 +29,7 @@ namespace Server.Engines.Help public override void OnResponse(NetState state, int index) { if (index == 0) - { m_From.SendLocalizedMessage(1005306, "", 0x35); // Help request unchanged. - } else if (index == 1) { PageEntry entry = PageQueue.GetEntry(m_From); @@ -141,49 +141,49 @@ namespace Server.Engines.Help AddButton(80, 90, 5540, 5541, 7); AddHtmlLocalized(110, 90, 450, 145, 1062572, true, - true); /*
Another player is harassing me (or Exploiting).

- * VERBAL HARASSMENT
- * Use this option when another player is verbally harassing your character. - * Verbal harassment behaviors include but are not limited to, using bad language, threats etc.. - * Before you submit a complaint be sure you understand what constitutes harassment - * � what is verbal harassment? - - * and that you have followed these steps:
- * 1. You have asked the player to stop and they have continued.
- * 2. You have tried to remove yourself from the situation.
- * 3. You have done nothing to instigate or further encourage the harassment.
- * 4. You have added the player to your ignore list. - * - How do I ignore a player?
- * 5. You have read and understand Origin�s definition of harassment.
- * 6. Your account information is up to date. (Including a current email address)
- * *If these steps have not been taken, GMs may be unable to take action against the offending player.
- * **A chat log will be review by a GM to assess the validity of this complaint. - * Abuse of this system is a violation of the Rules of Conduct.
- * EXPLOITING
- * Use this option to report someone who may be exploiting or cheating. - * � What constitutes an exploit? - */ + true); /*
Another player is harassing me (or Exploiting).

+ * VERBAL HARASSMENT
+ * Use this option when another player is verbally harassing your character. + * Verbal harassment behaviors include but are not limited to, using bad language, threats etc.. + * Before you submit a complaint be sure you understand what constitutes harassment + * � what is verbal harassment? - + * and that you have followed these steps:
+ * 1. You have asked the player to stop and they have continued.
+ * 2. You have tried to remove yourself from the situation.
+ * 3. You have done nothing to instigate or further encourage the harassment.
+ * 4. You have added the player to your ignore list. + * - How do I ignore a player?
+ * 5. You have read and understand Origin�s definition of harassment.
+ * 6. Your account information is up to date. (Including a current email address)
+ * *If these steps have not been taken, GMs may be unable to take action against the offending player.
+ * **A chat log will be review by a GM to assess the validity of this complaint. + * Abuse of this system is a violation of the Rules of Conduct.
+ * EXPLOITING
+ * Use this option to report someone who may be exploiting or cheating. + * � What constitutes an exploit? + */ AddButton(80, 240, 5540, 5541, 8); AddHtmlLocalized(110, 240, 450, 145, 1062573, true, - true); /*
Another player is harassing me using game mechanics.

- *
- * PHYSICAL HARASSMENT
- * Use this option when another player is harassing your character using game mechanics. - * Physical harassment includes but is not limited to luring, Kill Stealing, and any act that causes a players death in Trammel. - * Before you submit a complaint be sure you understand what constitutes harassment - * � what is physical harassment? - * and that you have followed these steps:
- * 1. You have asked the player to stop and they have continued.
- * 2. You have tried to remove yourself from the situation.
- * 3. You have done nothing to instigate or further encourage the harassment.
- * 4. You have added the player to your ignore list. - * - how do I ignore a player?
- * 5. You have read and understand Origin�s definition of harassment.
- * 6. Your account information is up to date. (Including a current email address)
- * *If these steps have not been taken, GMs may be unable to take action against the offending player.
- * **This issue will be reviewed by a GM to assess the validity of this complaint. - * Abuse of this system is a violation of the Rules of Conduct. - */ + true); /*
Another player is harassing me using game mechanics.

+ *
+ * PHYSICAL HARASSMENT
+ * Use this option when another player is harassing your character using game mechanics. + * Physical harassment includes but is not limited to luring, Kill Stealing, and any act that causes a players death in Trammel. + * Before you submit a complaint be sure you understand what constitutes harassment + * � what is physical harassment? + * and that you have followed these steps:
+ * 1. You have asked the player to stop and they have continued.
+ * 2. You have tried to remove yourself from the situation.
+ * 3. You have done nothing to instigate or further encourage the harassment.
+ * 4. You have added the player to your ignore list. + * - how do I ignore a player?
+ * 5. You have read and understand Origin�s definition of harassment.
+ * 6. Your account information is up to date. (Including a current email address)
+ * *If these steps have not been taken, GMs may be unable to take action against the offending player.
+ * **This issue will be reviewed by a GM to assess the validity of this complaint. + * Abuse of this system is a violation of the Rules of Conduct. + */ AddButton(150, 390, 5540, 5541, 0, GumpButtonType.Page, 1); AddHtmlLocalized(180, 390, 335, 40, 1001015); // NO - I meant to ask for help with another matter. @@ -196,9 +196,8 @@ namespace Server.Engines.Help private static void EventSink_HelpRequest(HelpRequestEventArgs e) { - foreach (Gump g in e.Mobile.NetState.Gumps) - if (g is HelpGump) - return; + if (e.Mobile.NetState.Gumps.OfType().Any()) + return; if (!PageQueue.CheckAllowedToPage(e.Mobile)) return; @@ -224,9 +223,9 @@ namespace Server.Engines.Help return false; } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { - Mobile from = state.Mobile; + Mobile from = sender.Mobile; PageType type = (PageType)(-1); diff --git a/Projects/Scripts/Engines/Help/PagePrompt.cs b/Projects/Scripts/Engines/Help/PagePrompt.cs index 4ab9e3a79..612819b36 100644 --- a/Projects/Scripts/Engines/Help/PagePrompt.cs +++ b/Projects/Scripts/Engines/Help/PagePrompt.cs @@ -1,5 +1,3 @@ -using Server.Prompts; - namespace Server.Engines.Help { public class PagePrompt : Prompt @@ -16,11 +14,11 @@ namespace Server.Engines.Help public override void OnResponse(Mobile from, string text) { from.SendLocalizedMessage(501234, "", - 0x35); /* The next available Counselor/Game Master will respond as soon as possible. - * Please check your Journal for messages every few minutes. - */ + 0x35); /* The next available Counselor/Game Master will respond as soon as possible. + * Please check your Journal for messages every few minutes. + */ PageQueue.Enqueue(new PageEntry(from, text, m_Type)); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Engines/Help/PagePromptGump.cs b/Projects/Scripts/Engines/Help/PagePromptGump.cs index 982991a35..7987e690a 100644 --- a/Projects/Scripts/Engines/Help/PagePromptGump.cs +++ b/Projects/Scripts/Engines/Help/PagePromptGump.cs @@ -48,9 +48,9 @@ namespace Server.Engines.Help else { m_From.SendLocalizedMessage(501234, "", - 0x35); /* The next available Counselor/Game Master will respond as soon as possible. - * Please check your Journal for messages every few minutes. - */ + 0x35); /* The next available Counselor/Game Master will respond as soon as possible. + * Please check your Journal for messages every few minutes. + */ PageQueue.Enqueue(new PageEntry(m_From, text, m_Type)); } diff --git a/Projects/Scripts/Engines/Help/PageQueue.cs b/Projects/Scripts/Engines/Help/PageQueue.cs index f719ddea8..2062702a7 100644 --- a/Projects/Scripts/Engines/Help/PageQueue.cs +++ b/Projects/Scripts/Engines/Help/PageQueue.cs @@ -82,8 +82,6 @@ namespace Server.Engines.Help private class InternalTimer : Timer { - private static TimeSpan StatusDelay = TimeSpan.FromMinutes(2.0); - private PageEntry m_Entry; public InternalTimer(PageEntry entry) : base(TimeSpan.FromSeconds(1.0), StatusDelay) => m_Entry = entry; diff --git a/Projects/Scripts/Engines/Help/PageQueueGump.cs b/Projects/Scripts/Engines/Help/PageQueueGump.cs index a87f3d40e..124697ca9 100644 --- a/Projects/Scripts/Engines/Help/PageQueueGump.cs +++ b/Projects/Scripts/Engines/Help/PageQueueGump.cs @@ -32,7 +32,7 @@ namespace Server.Engines.Help AddHtmlLocalized(34, 28, 65, 24, 3001002, 0xFFFFFF); // Message } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { m_Mobile.SendGump(new PageResponseGump(m_Mobile, m_Name, m_Text)); @@ -100,20 +100,20 @@ namespace Server.Engines.Help } } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (info.ButtonID >= 1 && info.ButtonID <= m_List.Length) { if (PageQueue.List.IndexOf(m_List[info.ButtonID - 1]) >= 0) { - PageEntryGump g = new PageEntryGump(state.Mobile, m_List[info.ButtonID - 1]); + PageEntryGump g = new PageEntryGump(sender.Mobile, m_List[info.ButtonID - 1]); - g.SendTo(state); + g.SendTo(sender); } else { - state.Mobile.SendGump(new PageQueueGump()); - state.Mobile.SendMessage("That page has been removed."); + sender.Mobile.SendGump(new PageQueueGump()); + sender.Mobile.SendMessage("That page has been removed."); } } } @@ -553,12 +553,12 @@ namespace Server.Engines.Help g.SendTo(state); } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (info.ButtonID != 0 && PageQueue.List.IndexOf(m_Entry) < 0) { - state.Mobile.SendGump(new PageQueueGump()); - state.Mobile.SendMessage("That page has been removed."); + sender.Mobile.SendGump(new PageQueueGump()); + sender.Mobile.SendMessage("That page has been removed."); return; } @@ -566,18 +566,18 @@ namespace Server.Engines.Help { case 0: // close { - if (m_Entry.Handler != state.Mobile) + if (m_Entry.Handler != sender.Mobile) { PageQueueGump g = new PageQueueGump(); - g.SendTo(state); + g.SendTo(sender); } break; } case 1: // go to sender { - Mobile m = state.Mobile; + Mobile m = sender.Mobile; if (m_Entry.Sender.Deleted) { @@ -594,14 +594,14 @@ namespace Server.Engines.Help m.SendMessage("You have been teleported to that page's sender."); - Resend(state); + Resend(sender); } break; } case 2: // go to handler { - Mobile m = state.Mobile; + Mobile m = sender.Mobile; Mobile h = m_Entry.Handler; if (h != null) @@ -620,20 +620,20 @@ namespace Server.Engines.Help m.MoveToWorld(h.Location, h.Map); m.SendMessage("You have been teleported to that page's handler."); - Resend(state); + Resend(sender); } } else { m.SendMessage("Nobody is handling that page."); - Resend(state); + Resend(sender); } break; } case 3: // go to page location { - Mobile m = state.Mobile; + Mobile m = sender.Mobile; if (m_Entry.PageMap == null || m_Entry.PageMap == Map.Internal) { @@ -644,9 +644,9 @@ namespace Server.Engines.Help // m_Entry.AddResponse(state.Mobile, "[Go PageLoc]"); m.MoveToWorld(m_Entry.PageLocation, m_Entry.PageMap); - state.Mobile.SendMessage("You have been teleported to the original page location."); + sender.Mobile.SendMessage("You have been teleported to the original page location."); - Resend(state); + Resend(sender); } break; @@ -656,16 +656,14 @@ namespace Server.Engines.Help if (m_Entry.Handler == null) { // m_Entry.AddResponse(state.Mobile, "[Handling]"); - m_Entry.Handler = state.Mobile; + m_Entry.Handler = sender.Mobile; - state.Mobile.SendMessage("You are now handling the page."); + sender.Mobile.SendMessage("You are now handling the page."); } else - { - state.Mobile.SendMessage("Someone is already handling that page."); - } + sender.Mobile.SendMessage("Someone is already handling that page."); - Resend(state); + Resend(sender); break; } @@ -676,59 +674,57 @@ namespace Server.Engines.Help // m_Entry.AddResponse(state.Mobile, "[Deleting]"); PageQueue.Remove(m_Entry); - state.Mobile.SendMessage("You delete the page."); + sender.Mobile.SendMessage("You delete the page."); PageQueueGump g = new PageQueueGump(); - g.SendTo(state); + g.SendTo(sender); } else { - state.Mobile.SendMessage("Someone is handling that page, it can not be deleted."); + sender.Mobile.SendMessage("Someone is handling that page, it can not be deleted."); - Resend(state); + Resend(sender); } break; } case 6: // abandon page { - if (m_Entry.Handler == state.Mobile) + if (m_Entry.Handler == sender.Mobile) { // m_Entry.AddResponse(state.Mobile, "[Abandoning]"); - state.Mobile.SendMessage("You abandon the page."); + sender.Mobile.SendMessage("You abandon the page."); m_Entry.Handler = null; } else - { - state.Mobile.SendMessage("You are not handling that page."); - } + sender.Mobile.SendMessage("You are not handling that page."); - Resend(state); + Resend(sender); break; } case 7: // page handled { - if (m_Entry.Handler == state.Mobile) + if (m_Entry.Handler == sender.Mobile) { // m_Entry.AddResponse(state.Mobile, "[Handled]"); PageQueue.Remove(m_Entry); m_Entry.Handler = null; - state.Mobile.SendMessage("You mark the page as handled, and remove it from the queue."); + sender.Mobile.SendMessage("You mark the page as handled, and remove it from the queue."); PageQueueGump g = new PageQueueGump(); - g.SendTo(state); + g.SendTo(sender); } else { - state.Mobile.SendMessage("You are not handling that page."); + sender.Mobile.SendMessage("You are not handling that page."); - Resend(state); + Resend(sender); } break; @@ -743,20 +739,20 @@ namespace Server.Engines.Help //m_Entry.Sender.SendMessage( 0x482, "{0} tells you:", state.Mobile.Name ); //m_Entry.Sender.SendMessage( 0x482, text.Text ); - Resend(state); + Resend(sender); break; } case 9: // predef overview { - Resend(state); - state.Mobile.SendGump(new PredefGump(state.Mobile, null)); + Resend(sender); + sender.Mobile.SendGump(new PredefGump(sender.Mobile, null)); break; } case 10: // View Speech Log { - Resend(state); + Resend(sender); if (m_Entry.SpeechLog != null) state.Mobile.SendGump(new SpeechLogGump(m_Entry.Sender, m_Entry.SpeechLog)); @@ -772,7 +768,7 @@ namespace Server.Engines.Help m_Entry.Sender.SendGump(new MessageSentGump(m_Entry.Sender, state.Mobile.Name, preresp[index].Message)); - Resend(state); + Resend(sender); break; } diff --git a/Projects/Scripts/Engines/Help/SpeechLogGump.cs b/Projects/Scripts/Engines/Help/SpeechLogGump.cs index 7996e18f7..1afb7aea3 100644 --- a/Projects/Scripts/Engines/Help/SpeechLogGump.cs +++ b/Projects/Scripts/Engines/Help/SpeechLogGump.cs @@ -46,9 +46,7 @@ namespace Server.Engines.Help string sLog; if (page < 0 || page > lastPage) - { sLog = ""; - } else { int max = log.Count - (lastPage - page) * MaxEntriesPerPage; diff --git a/Projects/Scripts/Engines/Help/StuckMenu.cs b/Projects/Scripts/Engines/Help/StuckMenu.cs index 9c6519417..313b82c73 100644 --- a/Projects/Scripts/Engines/Help/StuckMenu.cs +++ b/Projects/Scripts/Engines/Help/StuckMenu.cs @@ -14,9 +14,9 @@ namespace Server.Menus.Questions Locations = locations; } - public int Name{ get; } + public int Name { get; } - public Point3D[] Locations{ get; } + public Point3D[] Locations { get; } } public class StuckMenu : Gump @@ -162,7 +162,7 @@ namespace Server.Menus.Questions m_Mobile.Frozen = false; } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { StopClose(); diff --git a/Projects/Scripts/Engines/Khaldun/PuzzleChest.cs b/Projects/Scripts/Engines/Khaldun/PuzzleChest.cs index 271a06410..6263a9b4d 100644 --- a/Projects/Scripts/Engines/Khaldun/PuzzleChest.cs +++ b/Projects/Scripts/Engines/Khaldun/PuzzleChest.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Server.Gumps; using Server.Network; @@ -47,22 +48,9 @@ namespace Server.Items int version = reader.ReadEncodedInt(); int length = reader.ReadEncodedInt(); - for (int i = 0;; i++) - if (i < length) - { - PuzzleChestCylinder cylinder = (PuzzleChestCylinder)reader.ReadInt(); - if (i < Cylinders.Length) - Cylinders[i] = cylinder; - } - else if (i < Cylinders.Length) - { - Cylinders[i] = RandomCylinder(); - } - else - { - break; - } + for (int i = 0; i < Cylinders.Length; i++) + Cylinders[i] = i < length ? (PuzzleChestCylinder)reader.ReadInt() : RandomCylinder(); } public PuzzleChestCylinder[] Cylinders{ get; } = new PuzzleChestCylinder[Length]; @@ -296,7 +284,7 @@ namespace Server.Items { case 0: { - Effects.SendLocationEffect(to, to.Map, 0x113A, 20, 10); + Effects.SendLocationEffect(to, to.Map, 0x113A, 20); to.PlaySound(0x231); to.LocalOverheadMessage(MessageType.Regular, 0x44, 1010523); // A toxic vapor envelops thee. @@ -326,7 +314,7 @@ namespace Server.Items } default: { - to.BoltEffect(0); + to.BoltEffect(); to.LocalOverheadMessage(MessageType.Regular, 0xDA, 1010526); // Lightning arcs through thy body. AOS.Damage(to, to, Utility.RandomMinMax(10, 40), 0, 0, 0, 0, 100); @@ -409,12 +397,8 @@ namespace Server.Items for (int i = 0; i < 2; i++) { - Item item; - - if (Core.AOS) - item = Loot.RandomArmorOrShieldOrWeaponOrJewelry(); - else - item = Loot.RandomArmorOrShieldOrWeapon(); + Item item = Core.AOS ? + Loot.RandomArmorOrShieldOrWeaponOrJewelry() : Loot.RandomArmorOrShieldOrWeapon(); if (item is BaseWeapon weapon) { @@ -475,13 +459,7 @@ namespace Server.Items public void CleanupGuesses() { - List toDelete = new List(); - - foreach (KeyValuePair kvp in m_Guesses) - if (DateTime.UtcNow - kvp.Value.When > CleanupTime) - toDelete.Add(kvp.Key); - - foreach (Mobile m in toDelete) + foreach (Mobile m in from kvp in m_Guesses where DateTime.UtcNow - kvp.Value.When > CleanupTime select kvp.Key) m_Guesses.Remove(m); } @@ -499,10 +477,10 @@ namespace Server.Items for (int i = 0; i < Hints.Length; i++) writer.Write((int)Hints[i]); writer.WriteEncodedInt(m_Guesses.Count); - foreach (KeyValuePair kvp in m_Guesses) + foreach (var (key, value) in m_Guesses) { - writer.Write(kvp.Key); - kvp.Value.Serialize(writer); + writer.Write(key); + value.Serialize(writer); } } @@ -680,9 +658,7 @@ namespace Server.Items } if (info.ButtonID == 1) - { m_Chest.SubmitSolution(m_From, m_Solution); - } else { if (info.Switches.Length == 0) diff --git a/Projects/Scripts/Engines/MLQuests/Gumps/RaceChangeGump.cs b/Projects/Scripts/Engines/MLQuests/Gumps/RaceChangeGump.cs index 4292a91dd..9ae4c9238 100644 --- a/Projects/Scripts/Engines/MLQuests/Gumps/RaceChangeGump.cs +++ b/Projects/Scripts/Engines/MLQuests/Gumps/RaceChangeGump.cs @@ -1,5 +1,7 @@ using System; using System.Collections.Generic; +using System.Linq; +using Server.Buffers; using Server.Gumps; using Server.Items; using Server.Mobiles; @@ -87,7 +89,7 @@ namespace Server.Engines.MLQuests.Gumps CloseCurrent(ns); m_Pending[ns] = new RaceChangeState(owner, ns, targetRace); - ns.Send(new RaceChanger(from.Female, targetRace)); + SendRaceChanger(ns, from.Female, targetRace); } private static void CloseCurrent(NetState ns) @@ -98,7 +100,7 @@ namespace Server.Engines.MLQuests.Gumps m_Pending.Remove(ns); } - ns.Send(CloseRaceChanger.Instance); + SendCloseRaceChanger(ns); } private static void Timeout(NetState ns) @@ -106,30 +108,21 @@ namespace Server.Engines.MLQuests.Gumps if (IsPending(ns)) { m_Pending.Remove(ns); - ns.Send(CloseRaceChanger.Instance); + SendCloseRaceChanger(ns); } } public static bool IsWearingEquipment(Mobile from) { - foreach (Item item in from.Items) - switch (item.Layer) + return from.Items.Select(item => item.Layer switch { - case Layer.Hair: - case Layer.FacialHair: - case Layer.Backpack: - case Layer.Mount: - case Layer.Bank: - { - continue; // ignore - } - default: - { - return true; - } - } - - return false; + Layer.Hair => false, + Layer.FacialHair => false, + Layer.Backpack => false, + Layer.Mount => false, + Layer.Bank => false, + _ => true + }).FirstOrDefault(); } private static bool CanChange(PlayerMobile from, Race targetRace) @@ -238,38 +231,34 @@ namespace Server.Engines.MLQuests.Gumps m_Timeout = Timer.DelayCall(m_TimeoutDelay, Timeout, ns); } } - } - public sealed class RaceChanger : Packet - { - public RaceChanger(bool female, Race targetRace) - : base(0xBF) + public static void SendRaceChanger(NetState ns, bool female, Race targetRace) { - EnsureCapacity(7); + if (ns == null) + return; - m_Stream.Write((short)0x2A); - m_Stream.Write((byte)(female ? 1 : 0)); - m_Stream.Write((byte)(targetRace.RaceID + 1)); + SpanWriter writer = new SpanWriter(stackalloc byte[7]); + writer.Write((byte)0xBF); // Packet ID + writer.Write((ushort)0x07); // Dynamic Length + + writer.Write((short)0x2A); + writer.Write(female); + writer.Write((byte)(targetRace.RaceID + 1)); + + ns.Send(writer.Span); + } + + private static void SendCloseRaceChanger(NetState ns) + { + ns?.Send(stackalloc byte[] + { + 0xBF, // Packet ID + 0x07, // Dynamic Length + 0x00, + 0xFF + }); } } - - public sealed class CloseRaceChanger : Packet - { - public static readonly Packet Instance = SetStatic(new CloseRaceChanger()); - - private CloseRaceChanger() - : base(0xBF) - { - EnsureCapacity(7); - - m_Stream.Write((short)0x2A); - m_Stream.Write((byte)0); - m_Stream.Write((byte)0xFF); - } - } - - #region For testing - public class RaceChangeDeed : Item, IRaceChanger { [Constructible] @@ -330,6 +319,4 @@ namespace Server.Engines.MLQuests.Gumps int version = reader.ReadInt(); } } - - #endregion } diff --git a/Projects/Scripts/Engines/MLQuests/MLQuest.cs b/Projects/Scripts/Engines/MLQuests/MLQuest.cs index 4231451b5..599f6f86a 100644 --- a/Projects/Scripts/Engines/MLQuests/MLQuest.cs +++ b/Projects/Scripts/Engines/MLQuests/MLQuest.cs @@ -86,14 +86,7 @@ namespace Server.Engines.MLQuests public virtual int Version => 0; - public bool HasObjective() where T : BaseObjective - { - foreach (BaseObjective obj in Objectives) - if (obj is T) - return true; - - return false; - } + public bool HasObjective() where T : BaseObjective => Objectives.OfType().Any(); public virtual void Generate() { @@ -151,11 +144,7 @@ namespace Server.Engines.MLQuests } } - foreach (BaseObjective obj in Objectives) - if (!obj.CanOffer(quester, pm, message)) - return false; - - return true; + return Objectives.All(obj => obj.CanOffer(quester, pm, message)); } public virtual void SendOffer(IQuestGiver quester, PlayerMobile pm) diff --git a/Projects/Scripts/Engines/MLQuests/MLQuestContext.cs b/Projects/Scripts/Engines/MLQuests/MLQuestContext.cs index 052f04544..17b886604 100644 --- a/Projects/Scripts/Engines/MLQuests/MLQuestContext.cs +++ b/Projects/Scripts/Engines/MLQuests/MLQuestContext.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Server.Mobiles; namespace Server.Engines.MLQuests @@ -113,14 +114,7 @@ namespace Server.Engines.MLQuests return quest != null && HasDoneQuest(quest); } - public bool HasDoneQuest(MLQuest quest) - { - foreach (MLDoneQuestInfo info in m_DoneQuests) - if (info.m_Quest == quest) - return true; - - return false; - } + public bool HasDoneQuest(MLQuest quest) => m_DoneQuests.Any(info => info.m_Quest == quest); public bool HasDoneQuest(MLQuest quest, out DateTime nextAvailable) { @@ -180,20 +174,10 @@ namespace Server.Engines.MLQuests { MLQuest quest = MLQuestSystem.FindQuest(questType); - if (quest == null) - return null; - - return FindInstance(quest); + return quest == null ? null : FindInstance(quest); } - public MLQuestInstance FindInstance(MLQuest quest) - { - foreach (MLQuestInstance instance in QuestInstances) - if (instance.Quest == quest) - return instance; - - return null; - } + public MLQuestInstance FindInstance(MLQuest quest) => QuestInstances.FirstOrDefault(instance => instance.Quest == quest); public bool IsDoingQuest(Type questType) { diff --git a/Projects/Scripts/Engines/MLQuests/MLQuestEntry.cs b/Projects/Scripts/Engines/MLQuests/MLQuestEntry.cs index 84e28db5a..095802ca8 100644 --- a/Projects/Scripts/Engines/MLQuests/MLQuestEntry.cs +++ b/Projects/Scripts/Engines/MLQuests/MLQuestEntry.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Server.Engines.MLQuests.Gumps; using Server.Engines.MLQuests.Objectives; using Server.Engines.MLQuests.Rewards; @@ -36,16 +37,7 @@ namespace Server.Engines.MLQuests Objectives = new BaseObjectiveInstance[quest.Objectives.Count]; - BaseObjectiveInstance obj; - bool timed = false; - - for (int i = 0; i < quest.Objectives.Count; ++i) - { - Objectives[i] = obj = quest.Objectives[i].CreateInstance(this); - - if (obj.IsTimed) - timed = true; - } + bool timed = quest.Objectives.Aggregate(false, (current, t) => current | t.CreateInstance(this).IsTimed); Register(); @@ -113,14 +105,8 @@ namespace Server.Engines.MLQuests Removed = true; } - public bool AllowsQuestItem(Item item, Type type) - { - foreach (BaseObjectiveInstance objective in Objectives) - if (!objective.Expired && objective.AllowsQuestItem(item, type)) - return true; - - return false; - } + public bool AllowsQuestItem(Item item, Type type) => + Objectives.Any(objective => !objective.Expired && objective.AllowsQuestItem(item, type)); public bool IsCompleted() { @@ -252,13 +238,11 @@ namespace Server.Engines.MLQuests if (Quest.ObjectiveType == ObjectiveType.All) { // TODO: 1115877 - You no longer have the required items to complete this quest. - foreach (BaseObjectiveInstance objective in Objectives) - if (!objective.IsCompleted()) - return; + if (Objectives.Any(objective => !objective.IsCompleted())) + return; - foreach (BaseObjectiveInstance objective in Objectives) - if (!objective.OnBeforeClaimReward()) - return; + if (Objectives.Any(objective => !objective.OnBeforeClaimReward())) + return; foreach (BaseObjectiveInstance objective in Objectives) objective.OnClaimReward(); @@ -314,14 +298,7 @@ namespace Server.Engines.MLQuests { // On OSI a more naive method of checking is used. // For containers, only the actual container item counts. - bool canFit = true; - - foreach (Item rewardItem in rewards) - if (!Player.AddToBackpack(rewardItem)) - { - canFit = false; - break; - } + bool canFit = rewards.All(rewardItem => Player.AddToBackpack(rewardItem)); if (!canFit) { diff --git a/Projects/Scripts/Engines/MLQuests/MLQuestPersistence.cs b/Projects/Scripts/Engines/MLQuests/MLQuestPersistence.cs index 87f3cfa5c..66c861788 100644 --- a/Projects/Scripts/Engines/MLQuests/MLQuestPersistence.cs +++ b/Projects/Scripts/Engines/MLQuests/MLQuestPersistence.cs @@ -14,8 +14,7 @@ namespace Server.Engines.MLQuests public static void EnsureExistence() { - if (m_Instance == null) - m_Instance = new MLQuestPersistence(); + m_Instance ??= new MLQuestPersistence(); } public override void Serialize(GenericWriter writer) @@ -55,4 +54,4 @@ namespace Server.Engines.MLQuests MLQuest.Deserialize(reader, version); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Engines/MLQuests/MLQuestSystem.cs b/Projects/Scripts/Engines/MLQuests/MLQuestSystem.cs index 32ec0c488..c65dd5640 100644 --- a/Projects/Scripts/Engines/MLQuests/MLQuestSystem.cs +++ b/Projects/Scripts/Engines/MLQuests/MLQuestSystem.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using Server.Commands; using Server.Commands.Generic; using Server.Engines.MLQuests.Gumps; @@ -213,7 +214,7 @@ namespace Server.Engines.MLQuests return; } - bool enable = e.Length == 1 ? e.GetBoolean(0) : true; + bool enable = e.Length != 1 || e.GetBoolean(0); foreach (MLQuest quest in Quests.Values) quest.SaveEnabled = enable; @@ -329,17 +330,8 @@ namespace Server.Engines.MLQuests } } - public static bool CanMarkQuestItem(PlayerMobile pm, Item item, Type type) - { - MLQuestContext context = GetContext(pm); - - if (context != null) - foreach (MLQuestInstance quest in context.QuestInstances) - if (!quest.ClaimReward && quest.AllowsQuestItem(item, type)) - return true; - - return false; - } + public static bool CanMarkQuestItem(PlayerMobile pm, Item item, Type type) => + GetContext(pm)?.QuestInstances.Any(quest => !quest.ClaimReward && quest.AllowsQuestItem(item, type)) == true; private static void OnMarkQuestItem(PlayerMobile pm, Item item, Type type) { @@ -563,8 +555,7 @@ namespace Server.Engines.MLQuests * Save first quest that reaches the CanOffer call. * If no quests are valid at all, return this quest for displaying the CanOffer error message. */ - if (fallback == null) - fallback = quest; + fallback ??= quest; if (quest.CanOffer(quester, pm, context, false)) m_EligiblePool.Add(quest); @@ -643,7 +634,7 @@ namespace Server.Engines.MLQuests if (questType == null) return null; // no longer a type - return FindQuest(questType); + return questType == null ? null : FindQuest(questType); } public static MLQuest FindQuest(Type questType) diff --git a/Projects/Scripts/Engines/MLQuests/Mobiles/BoonCollector.cs b/Projects/Scripts/Engines/MLQuests/Mobiles/BoonCollector.cs index 0ba0dff6d..303bed91c 100644 --- a/Projects/Scripts/Engines/MLQuests/Mobiles/BoonCollector.cs +++ b/Projects/Scripts/Engines/MLQuests/Mobiles/BoonCollector.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Server.Engines.MLQuests.Definitions; using Server.Engines.MLQuests.Gumps; using Server.Items; @@ -135,20 +136,7 @@ namespace Server.Engines.MLQuests.Mobiles { MLQuestContext context = MLQuestSystem.GetContext(pm); - if (context == null) - return 0; - - int result = 0; - - foreach (Type type in Needed) - { - MLQuest quest = MLQuestSystem.FindQuest(type); - - if (quest == null || context.HasDoneQuest(quest)) - ++result; - } - - return result; + return context == null ? 0 : Needed.Select(MLQuestSystem.FindQuest).Count(quest => quest == null || context.HasDoneQuest(quest)); } public virtual void OnComplete(PlayerMobile pm) diff --git a/Projects/Scripts/Engines/MLQuests/Mobiles/SirHelper.cs b/Projects/Scripts/Engines/MLQuests/Mobiles/SirHelper.cs index ac70f3b68..b92f56b41 100644 --- a/Projects/Scripts/Engines/MLQuests/Mobiles/SirHelper.cs +++ b/Projects/Scripts/Engines/MLQuests/Mobiles/SirHelper.cs @@ -42,9 +42,7 @@ namespace Server.Engines.MLQuests.Mobiles public override bool GetGender() => false; - public override void CheckMorph() - { - } + public override bool CheckMorph() => true; public override void InitOutfit() { @@ -53,22 +51,9 @@ namespace Server.Engines.MLQuests.Mobiles HairHue = FacialHairHue = 0x8A7; AddItem(new Sandals()); - - Item item; - - item = new Cloak(); - item.ItemID = 0x26AD; - item.Hue = 0x455; - AddItem(item); - - item = new Robe(); - item.ItemID = 0x26AE; - item.Hue = 0x4AB; - AddItem(item); - - item = new Backpack(); - item.Movable = false; - AddItem(item); + AddItem(new Cloak{ ItemID = 0x26AD, Hue = 0x455}); + AddItem(new Robe {ItemID = 0x26AE, Hue = 0x4AB}); + AddItem(new Backpack {Movable = false}); } public override void OnDoubleClick(Mobile from) @@ -92,32 +77,23 @@ namespace Server.Engines.MLQuests.Mobiles if (m_NextShout <= DateTime.UtcNow) { - Packet shoutPacket = null; - - foreach (NetState state in GetClientsInRange(12)) + IPooledEnumerable eable = GetClientsInRange(12); + foreach (NetState state in eable) { Mobile m = state.Mobile; if (m.CanSee(this) && m.InLOS(this) && m.CanBeginAction(this)) - { - if (shoutPacket == null) - shoutPacket = Packet.Acquire(new MessageLocalized(Serial, Body, MessageType.Regular, 946, 3, - 1078099, Name, "")); // Double Click On Me For Help! - - state.Send(shoutPacket); - } + Packets.SendMessageLocalized(state, Serial, Body, MessageType.Regular, 946, 3, + 1078099, Name); // Double Click On Me For Help! } - Packet.Release(shoutPacket); + eable.Free(); m_NextShout = DateTime.UtcNow + m_ShoutDelay; } } - private void EndLock(Mobile m) - { - m.EndAction(this); - } + private void EndLock(Mobile m) => m.EndAction(this); public override void Serialize(GenericWriter writer) { @@ -135,4 +111,4 @@ namespace Server.Engines.MLQuests.Mobiles Frozen = true; } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Engines/MLQuests/Objectives/EscortObjective.cs b/Projects/Scripts/Engines/MLQuests/Objectives/EscortObjective.cs index a81783ed4..d21af44a0 100644 --- a/Projects/Scripts/Engines/MLQuests/Objectives/EscortObjective.cs +++ b/Projects/Scripts/Engines/MLQuests/Objectives/EscortObjective.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using Server.Gumps; using Server.Misc; using Server.Mobiles; @@ -20,14 +21,13 @@ namespace Server.Engines.MLQuests.Objectives MLQuestContext context = MLQuestSystem.GetContext(pm); if (context != null) - foreach (MLQuestInstance instance in context.QuestInstances) - if (instance.Quest.IsEscort) - { - if (message) - MLQuestSystem.Tell(quester, pm, 500896); // I see you already have an escort. + if (context.QuestInstances.Any(instance => instance.Quest.IsEscort)) + { + if (message) + MLQuestSystem.Tell(quester, pm, 500896); // I see you already have an escort. - return false; - } + return false; + } DateTime nextEscort = pm.LastEscortTime + BaseEscortable.EscortDelay; diff --git a/Projects/Scripts/Engines/MLQuests/Objectives/KillObjective.cs b/Projects/Scripts/Engines/MLQuests/Objectives/KillObjective.cs index 89f47f269..0f35da79a 100644 --- a/Projects/Scripts/Engines/MLQuests/Objectives/KillObjective.cs +++ b/Projects/Scripts/Engines/MLQuests/Objectives/KillObjective.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using Server.Gumps; using Server.Mobiles; @@ -91,22 +92,21 @@ namespace Server.Engines.MLQuests.Objectives { int desired = Objective.DesiredAmount; - foreach (Type acceptedType in Objective.AcceptedTypes) - if (acceptedType.IsAssignableFrom(type)) - { - if (Objective.Area?.Contains(mob) == false) - return false; + if (Objective.AcceptedTypes.Any(acceptedType => acceptedType.IsAssignableFrom(type))) + { + if (Objective.Area?.Contains(mob) == false) + return false; - PlayerMobile pm = Instance.Player; + PlayerMobile pm = Instance.Player; - if (++Slain >= desired) - pm.SendLocalizedMessage(1075050); // You have killed all the required quest creatures of this type. - else - pm.SendLocalizedMessage(1075051, - (desired - Slain).ToString()); // You have killed a quest creature. ~1_val~ more left. + if (++Slain >= desired) + pm.SendLocalizedMessage(1075050); // You have killed all the required quest creatures of this type. + else + pm.SendLocalizedMessage(1075051, + (desired - Slain).ToString()); // You have killed a quest creature. ~1_val~ more left. - return true; - } + return true; + } return false; } diff --git a/Projects/Scripts/Engines/MLQuests/QuestArea.cs b/Projects/Scripts/Engines/MLQuests/QuestArea.cs index 92e2986a4..74f2c3ef9 100644 --- a/Projects/Scripts/Engines/MLQuests/QuestArea.cs +++ b/Projects/Scripts/Engines/MLQuests/QuestArea.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; namespace Server.Engines.MLQuests { @@ -34,14 +35,7 @@ namespace Server.Engines.MLQuests // Debug method public void Validate() { - bool found = false; - - foreach (Region r in Region.Regions) - if (r.Name == RegionName && (ForceMap == null || r.Map == ForceMap)) - { - found = true; - break; - } + bool found = Region.Regions.Any(r => r.Name == RegionName && (ForceMap == null || r.Map == ForceMap)); if (!found) Console.WriteLine("Warning: QuestArea region '{0}' does not exist (ForceMap = {1})", RegionName, diff --git a/Projects/Scripts/Engines/MyRunUO/LayerComparer.cs b/Projects/Scripts/Engines/MyRunUO/LayerComparer.cs new file mode 100644 index 000000000..cf00d5b67 --- /dev/null +++ b/Projects/Scripts/Engines/MyRunUO/LayerComparer.cs @@ -0,0 +1,81 @@ +using System.Collections.Generic; + +namespace Server.Engines.MyRunUO +{ + public class LayerComparer : IComparer + { + private static Layer PlateArms = (Layer)255; + private static Layer ChainTunic = (Layer)254; + private static Layer LeatherShorts = (Layer)253; + + private static Layer[] m_DesiredLayerOrder = + { + Layer.Cloak, + Layer.Bracelet, + Layer.Ring, + Layer.Shirt, + Layer.Pants, + Layer.InnerLegs, + Layer.Shoes, + LeatherShorts, + Layer.Arms, + Layer.InnerTorso, + LeatherShorts, + PlateArms, + Layer.MiddleTorso, + Layer.OuterLegs, + Layer.Neck, + Layer.Waist, + Layer.Gloves, + Layer.OuterTorso, + Layer.OneHanded, + Layer.TwoHanded, + Layer.FacialHair, + Layer.Hair, + Layer.Helm, + Layer.Talisman + }; + + public static readonly IComparer Instance = new LayerComparer(); + + static LayerComparer() + { + TranslationTable = new int[256]; + + for (int i = 0; i < m_DesiredLayerOrder.Length; ++i) + TranslationTable[(int)m_DesiredLayerOrder[i]] = m_DesiredLayerOrder.Length - i; + } + + public static int[] TranslationTable{ get; } + + public int Compare(Item a, Item b) + { + if (a == null) + return b == null ? 0 : 1; + + if (b == null) + return -1; + + Layer aLayer = Fix(a.ItemID, a.Layer); + Layer bLayer = Fix(b.ItemID, b.Layer); + + return TranslationTable[(int)bLayer] - TranslationTable[(int)aLayer]; + } + + public static bool IsValid(Item item) => TranslationTable[(int)item.Layer] > 0; + + public Layer Fix(int itemID, Layer oldLayer) + { + if (itemID == 0x1410 || itemID == 0x1417) // platemail arms + return PlateArms; + + if (itemID == 0x13BF || itemID == 0x13C4) // chainmail tunic + return ChainTunic; + + if (itemID == 0x1C08 || itemID == 0x1C09 || itemID == 0x1C00 || itemID == 0x1C01) // leather skirt/shorts + return LeatherShorts; + + return oldLayer; + } + } +} \ No newline at end of file diff --git a/Projects/Scripts/Engines/Party/Packets.cs b/Projects/Scripts/Engines/Party/Packets.cs index e417d0b3c..cabd86171 100644 --- a/Projects/Scripts/Engines/Party/Packets.cs +++ b/Projects/Scripts/Engines/Party/Packets.cs @@ -1,77 +1,175 @@ +using Server.Buffers; using Server.Network; namespace Server.Engines.PartySystem { - public sealed class PartyEmptyList : Packet + public static class PartyPackets { - public PartyEmptyList(Mobile m) : base(0xBF) + public static void SendPartyEmptyList(NetState ns, Mobile m) { - EnsureCapacity(7); + if (ns == null) + return; - m_Stream.Write((short)0x0006); - m_Stream.Write((byte)0x02); - m_Stream.Write((byte)0); - m_Stream.Write(m.Serial); + SpanWriter writer = new SpanWriter(stackalloc byte[11]); + writer.Write((byte)0xBF); // Packet ID + writer.Write((short)11); // Dynamic Length + + writer.Write((short)0x06); + writer.Write((byte)0x02); + writer.Position++; // Writer(0); // Number of members + writer.Write(m.Serial); + + ns.Send(writer.Span); } - } - public sealed class PartyMemberList : Packet - { - public PartyMemberList(Party p) : base(0xBF) + public static void SendPartyMemberList(NetState ns, Party p) { - EnsureCapacity(7 + p.Count * 4); + if (ns == null) + return; - m_Stream.Write((short)0x0006); - m_Stream.Write((byte)0x01); - m_Stream.Write((byte)p.Count); + ushort length = (ushort)(7 + p.Count * 4); + + SpanWriter writer = new SpanWriter(stackalloc byte[length]); + writer.Write((byte)0xBF); // Packet ID + writer.Write(length); // Dynamic Length + + writer.Write((short)0x06); + writer.Write((byte)0x01); + writer.Write((byte)p.Count); for (int i = 0; i < p.Count; ++i) - m_Stream.Write(p[i].Mobile.Serial); + writer.Write(p[i].Mobile.Serial); + + ns.Send(writer.Span); } - } - public sealed class PartyRemoveMember : Packet - { - public PartyRemoveMember(Mobile removed, Party p) : base(0xBF) + public static void SendPartyRemoveMember(NetState ns, Mobile removed, Party p) { - EnsureCapacity(11 + p.Count * 4); + if (ns == null) + return; - m_Stream.Write((short)0x0006); - m_Stream.Write((byte)0x02); - m_Stream.Write((byte)p.Count); + ushort length = (ushort)(11 + p.Count * 4); - m_Stream.Write(removed.Serial); + SpanWriter writer = new SpanWriter(stackalloc byte[length]); + writer.Write((byte)0xBF); // Packet ID + writer.Write(length); // Dynamic Length + + writer.Write((short)0x06); + writer.Write((byte)0x02); + writer.Write((byte)p.Count); + writer.Write(removed.Serial); for (int i = 0; i < p.Count; ++i) - m_Stream.Write(p[i].Mobile.Serial); - } - } + writer.Write(p[i].Mobile.Serial); - public sealed class PartyTextMessage : Packet - { - public PartyTextMessage(bool toAll, Mobile from, string text) : base(0xBF) + ns.Send(writer.Span); + } + + public static void SendPartyRemoveMemberToAll(Mobile removed, Party p) { - if (text == null) - text = ""; - - EnsureCapacity(12 + text.Length * 2); - - m_Stream.Write((short)0x0006); - m_Stream.Write((byte)(toAll ? 0x04 : 0x03)); - m_Stream.Write(from.Serial); - m_Stream.WriteBigUniNull(text); + for (int i = 0; i < p.Members.Count; i++) + SendPartyRemoveMember(p[i].Mobile.NetState, removed, p); } - } - public sealed class PartyInvitation : Packet - { - public PartyInvitation(Mobile leader) : base(0xBF) + public static void SendPartyTextMessage(NetState ns, bool toAll, Mobile from, string text) { - EnsureCapacity(10); + if (ns == null) + return; - m_Stream.Write((short)0x0006); - m_Stream.Write((byte)0x07); - m_Stream.Write(leader.Serial); + ushort length = (ushort)(12 + text.Length * 2); + + SpanWriter writer = new SpanWriter(stackalloc byte[length]); + writer.Write((byte)0xBF); // Packet ID + writer.Write(length); // Dynamic Length + + writer.Write((short)0x06); + writer.Write((byte)(toAll ? 0x04 : 0x03)); + writer.Write(from.Serial); + + writer.WriteBigUniNull(text); + + ns.Send(writer.Span); + } + + public static void SendPartyTextMessageToAll(Party p, bool toAll, Mobile from, string text) + { + for (int i = 0; i < p.Members.Count; ++i) + SendPartyTextMessage(p.Members[i].Mobile.NetState, toAll, from, text); + } + + public static void SendPartyInvitation(NetState ns, Mobile leader) + { + if (ns == null) + return; + + SpanWriter writer = new SpanWriter(stackalloc byte[10]); + writer.Write((byte)0xBF); // Packet ID + writer.Write((short)10); // Dynamic Length + + writer.Write((short)0x06); + writer.Write((byte)0x07); + writer.Write(leader.Serial); + + ns.Send(writer.Span); + } + + public static void SendPartyMessageLocalizedToAll(Party p, Serial serial, int graphic, MessageType type, int hue, int font, int number, string name = "", + string args = "") + { + for (int i = 0; i < p.Members.Count; ++i) + Packets.SendMessageLocalized(p.Members[i].Mobile.NetState, serial, graphic, type, hue, font, number, name, args); + + for (int i = 0; i < p.Listeners.Count; ++i) + { + Mobile mob = p.Listeners[i]; + + if (mob.Party != p) + Packets.SendMessageLocalized(mob.NetState, serial, graphic, type, hue, font, number, name, args); + } + } + + public static void SendPartyMessageLocalizedAffixToAll(Party p, Serial serial, int graphic, MessageType type, int hue, int font, int number, + string name = "", AffixType affixType = AffixType.System, string affix = "", string args = "") + { + for (int i = 0; i < p.Members.Count; ++i) + Packets.SendMessageLocalizedAffix(p.Members[i].Mobile.NetState, serial, graphic, type, hue, font, number, name, affixType, affix, args); + + for (int i = 0; i < p.Listeners.Count; ++i) + { + Mobile mob = p.Listeners[i]; + + if (mob.Party != p) + Packets.SendMessageLocalizedAffix(mob.NetState, serial, graphic, type, hue, font, number, name, affixType, affix, args); + } + } + + public static void SendPartyUnicodeMessageToAll(Party p, Serial serial, int graphic, MessageType type, int hue, int font, string lang, string name, + string text) + { + for (int i = 0; i < p.Members.Count; ++i) + Packets.SendUnicodeMessage(p.Members[i].Mobile.NetState, serial, graphic, type, hue, font, lang, name, text); + + for (int i = 0; i < p.Listeners.Count; ++i) + { + Mobile mob = p.Listeners[i]; + + if (mob.Party != p) + Packets.SendUnicodeMessage(p.Members[i].Mobile.NetState, serial, graphic, type, hue, font, lang, name, text); + } + } + + public static void SendPartyAsciiMessageToAll(Party p, Serial serial, int graphic, MessageType type, int hue, int font, string name, string text) + { + for (int i = 0; i < p.Members.Count; ++i) + Packets.SendAsciiMessage(p.Members[i].Mobile.NetState, serial, graphic, type, hue, font, name, text); + + for (int i = 0; i < p.Listeners.Count; ++i) + { + Mobile mob = p.Listeners[i]; + + if (mob.Party != p) + Packets.SendAsciiMessage(p.Members[i].Mobile.NetState, serial, graphic, type, hue, font, name, text); + } } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Engines/Party/Party.cs b/Projects/Scripts/Engines/Party/Party.cs index 015ccbea4..037376b12 100644 --- a/Projects/Scripts/Engines/Party/Party.cs +++ b/Projects/Scripts/Engines/Party/Party.cs @@ -9,7 +9,6 @@ namespace Server.Engines.PartySystem public class Party : IParty { public const int Capacity = 10; - private List m_Listeners; // staff listening public Party(Mobile leader) { @@ -17,7 +16,7 @@ namespace Server.Engines.PartySystem Members = new List(); Candidates = new List(); - m_Listeners = new List(); + Listeners = new List(); Members.Add(new PartyMemberInfo(leader)); } @@ -30,58 +29,32 @@ namespace Server.Engines.PartySystem public List Candidates{ get; } + public List Listeners { get; } // staff listening + public PartyMemberInfo this[int index] => Members[index]; - public PartyMemberInfo this[Mobile m] - { - get - { - for (int i = 0; i < Members.Count; ++i) - if (Members[i].Mobile == m) - return Members[i]; - - return null; - } - } + public PartyMemberInfo this[Mobile m] => Members.FirstOrDefault(t => t.Mobile == m); public void OnStamChanged(Mobile m) { - Packet p = null; - for (int i = 0; i < Members.Count; ++i) { Mobile c = Members[i].Mobile; if (c != m && m.Map == c.Map && Utility.InUpdateRange(c, m) && c.CanSee(m)) - { - if (p == null) - p = Packet.Acquire(new MobileStamN(m)); - - c.Send(p); - } + Packets.SendNormalizedMobileStam(c.NetState, c); } - - Packet.Release(p); } public void OnManaChanged(Mobile m) { - Packet p = null; - for (int i = 0; i < Members.Count; ++i) { Mobile c = Members[i].Mobile; if (c != m && m.Map == c.Map && Utility.InUpdateRange(c, m) && c.CanSee(m)) - { - if (p == null) - p = Packet.Acquire(new MobileManaN(m)); - - c.Send(p); - } + Packets.SendNormalizedMobileMana(c.NetState, c); } - - Packet.Release(p); } public void OnStatsQuery(Mobile beholder, Mobile beheld) @@ -90,9 +63,9 @@ namespace Server.Engines.PartySystem Utility.InUpdateRange(beholder, beheld)) { if (!beholder.CanSee(beheld)) - beholder.Send(new MobileStatusCompact(beheld.CanBeRenamedBy(beholder), beheld)); + Packets.SendMobileStatusCompact(beholder.NetState, beheld, beheld.CanBeRenamedBy(beholder)); - beholder.Send(new MobileAttributesN(beheld)); + Packets.SendNormalizedMobileAttributes(beholder.NetState, beheld); } } @@ -121,14 +94,14 @@ namespace Server.Engines.PartySystem { from.SendMessage("They are not in a party."); } - else if (p.m_Listeners.Contains(from)) + else if (p.Listeners.Contains(from)) { - p.m_Listeners.Remove(from); + p.Listeners.Remove(from); from.SendMessage("You are no longer listening to that party."); } else { - p.m_Listeners.Add(from); + p.Listeners.Add(from); from.SendMessage("You are now listening to that party."); } } @@ -184,35 +157,25 @@ namespace Server.Engines.PartySystem Members.Add(new PartyMemberInfo(m)); m.Party = this; - Packet memberList = Packet.Acquire(new PartyMemberList(this)); - Packet attrs = Packet.Acquire(new MobileAttributesN(m)); - for (int i = 0; i < Members.Count; ++i) { Mobile f = Members[i].Mobile; + NetState ns = f.NetState; - f.Send(memberList); + PartyPackets.SendPartyMemberList(ns, this); if (f != m) { - f.Send(new MobileStatusCompact(m.CanBeRenamedBy(f), m)); - f.Send(attrs); - m.Send(new MobileStatusCompact(f.CanBeRenamedBy(m), f)); - m.Send(new MobileAttributesN(f)); + Packets.SendMobileStatusCompact(ns, m, m.CanBeRenamedBy(f)); + Packets.SendNormalizedMobileAttributes(ns, m); + Packets.SendMobileStatusCompact(ns, f, f.CanBeRenamedBy(m)); + Packets.SendNormalizedMobileAttributes(ns, f); } } - - Packet.Release(memberList); - Packet.Release(attrs); } } - public void OnAccept(Mobile from) - { - OnAccept(from, false); - } - - public void OnAccept(Mobile from, bool force) + public void OnAccept(Mobile from, bool force = false) { Faction ourFaction = Faction.Find(Leader); Faction theirFaction = Faction.Find(from); @@ -221,8 +184,8 @@ namespace Server.Engines.PartySystem return; // : joined the party. - SendToAll(new MessageLocalizedAffix(Serial.MinusOne, -1, MessageType.Label, 0x3B2, 3, 1008094, "", - AffixType.Prepend | AffixType.System, from.Name, "")); + PartyPackets.SendPartyMessageLocalizedAffixToAll(this, Serial.MinusOne, -1, MessageType.Label, + 0x3B2, 3, 1008094, "",AffixType.Prepend | AffixType.System, from.Name); from.SendLocalizedMessage(1005445); // You have been added to the party. @@ -238,14 +201,15 @@ namespace Server.Engines.PartySystem from.SendLocalizedMessage(1008092); // You notify them that you do not wish to join the party. Candidates.Remove(from); - from.Send(new PartyEmptyList(from)); + PartyPackets.SendPartyEmptyList(from.NetState, from); if (Candidates.Count == 0 && Members.Count <= 1) { for (int i = 0; i < Members.Count; ++i) { - this[i].Mobile.Send(new PartyEmptyList(this[i].Mobile)); - this[i].Mobile.Party = null; + Mobile m = this[i].Mobile; + PartyPackets.SendPartyEmptyList(m.NetState, m); + m.Party = null; } Members.Clear(); @@ -255,9 +219,7 @@ namespace Server.Engines.PartySystem public void Remove(Mobile m) { if (m == Leader) - { Disband(); - } else { for (int i = 0; i < Members.Count; ++i) @@ -266,19 +228,21 @@ namespace Server.Engines.PartySystem Members.RemoveAt(i); m.Party = null; - m.Send(new PartyEmptyList(m)); + PartyPackets.SendPartyEmptyList(m.NetState, m); m.SendLocalizedMessage(1005451); // You have been removed from the party. - SendToAll(new PartyRemoveMember(m, this)); - SendToAll(1005452); // A player has been removed from your party. + PartyPackets.SendPartyRemoveMemberToAll(m, this); + // A player has been removed from your party. + PartyPackets.SendPartyMessageLocalizedToAll(this, Serial.MinusOne, -1, MessageType.Regular, 0x3B2, 3, 1005452, "System"); break; } if (Members.Count == 1) { - SendToAll(1005450); // The last person has left the party... + // The last person has left the party... + PartyPackets.SendPartyMessageLocalizedToAll(this, Serial.MinusOne, -1, MessageType.Regular, 0x3B2, 3, 1005450, "System"); Disband(); } } @@ -288,12 +252,14 @@ namespace Server.Engines.PartySystem public void Disband() { - SendToAll(1005449); // Your party has disbanded. + // Your party has disbanded. + PartyPackets.SendPartyMessageLocalizedToAll(this, Serial.MinusOne, -1, MessageType.Regular, 0x3B2, 3, 1005449, "System"); for (int i = 0; i < Members.Count; ++i) { - this[i].Mobile.Send(new PartyEmptyList(this[i].Mobile)); - this[i].Mobile.Party = null; + Mobile m = this[i].Mobile; + PartyPackets.SendPartyEmptyList(m.NetState, m); + m.Party = null; } Members.Clear(); @@ -320,82 +286,57 @@ namespace Server.Engines.PartySystem p.Candidates.Add(target); // : You are invited to join the party. Type /accept to join or /decline to decline the offer. - target.Send(new MessageLocalizedAffix(Serial.MinusOne, -1, MessageType.Label, 0x3B2, 3, 1008089, "", - AffixType.Prepend | AffixType.System, from.Name, "")); + Packets.SendMessageLocalizedAffix(target.NetState, Serial.MinusOne, -1, MessageType.Label, 0x3B2, 3, 1008089, "", + AffixType.Prepend | AffixType.System, from.Name); from.SendLocalizedMessage(1008090); // You have invited them to join the party. - target.Send(new PartyInvitation(from)); + PartyPackets.SendPartyInvitation(target.NetState, from); target.Party = from; DeclineTimer.Start(target, from); } - public void SendToAll(int number) - { - SendToAll(number, "", 0x3B2); - } - - public void SendToAll(int number, string args) - { - SendToAll(number, args, 0x3B2); - } - - public void SendToAll(int number, string args, int hue) - { - SendToAll(new MessageLocalized(Serial.MinusOne, -1, MessageType.Regular, hue, 3, number, "System", args)); - } - public void SendPublicMessage(Mobile from, string text) { - SendToAll(new PartyTextMessage(true, from, text)); + PartyPackets.SendPartyTextMessageToAll(this, true, from, text); - for (int i = 0; i < m_Listeners.Count; ++i) + for (int i = 0; i < Listeners.Count; ++i) { - Mobile mob = m_Listeners[i]; + Mobile mob = Listeners[i]; if (mob.Party != this) - m_Listeners[i].SendMessage("[{0}]: {1}", from.Name, text); + Listeners[i].SendMessage("[{0}]: {1}", from.Name, text); } - SendToStaffMessage(from, "[Party]: {0}", text); + SendToStaffMessage(from, $"[Party]: {text}"); } public void SendPrivateMessage(Mobile from, Mobile to, string text) { - to.Send(new PartyTextMessage(false, from, text)); + PartyPackets.SendPartyTextMessage(to.NetState, false, from, text); - for (int i = 0; i < m_Listeners.Count; ++i) + for (int i = 0; i < Listeners.Count; ++i) { - Mobile mob = m_Listeners[i]; + Mobile mob = Listeners[i]; if (mob.Party != this) - m_Listeners[i].SendMessage("[{0}]->[{1}]: {2}", from.Name, to.Name, text); + Listeners[i].SendMessage("[{0}]->[{1}]: {2}", from.Name, to.Name, text); } - SendToStaffMessage(from, "[Party]->[{0}]: {1}", to.Name, text); + SendToStaffMessage(from, $"[Party]->[{to.Name}]: {text}"); } private void SendToStaffMessage(Mobile from, string text) { - Packet p = null; - foreach (NetState ns in from.GetClientsInRange(8)) { Mobile mob = ns.Mobile; if (mob?.AccessLevel >= AccessLevel.GameMaster && mob.AccessLevel > from.AccessLevel && - mob.Party != this && !m_Listeners.Contains(mob)) - { - if (p == null) - p = Packet.Acquire(new UnicodeMessage(from.Serial, from.Body, MessageType.Regular, from.SpeechHue, 3, - from.Language, from.Name, text)); - - ns.Send(p); - } + mob.Party != this && !Listeners.Contains(mob)) + Packets.SendUnicodeMessage(ns, from.Serial, from.Body, MessageType.Regular, from.SpeechHue, 3, from.Language, from.Name, text); } - - Packet.Release(p); } private void SendToStaffMessage(Mobile from, string format, params object[] args) @@ -403,25 +344,6 @@ namespace Server.Engines.PartySystem SendToStaffMessage(from, string.Format(format, args)); } - public void SendToAll(Packet p) - { - p.Acquire(); - - for (int i = 0; i < Members.Count; ++i) - Members[i].Mobile.Send(p); - - if (p is MessageLocalized || p is MessageLocalizedAffix || p is UnicodeMessage || p is AsciiMessage) - for (int i = 0; i < m_Listeners.Count; ++i) - { - Mobile mob = m_Listeners[i]; - - if (mob.Party != this) - mob.Send(p); - } - - p.Release(); - } - private class RejoinTimer : Timer { private Mobile m_Mobile; @@ -436,11 +358,7 @@ namespace Server.Engines.PartySystem return; m_Mobile.SendLocalizedMessage(1005437); // You have rejoined the party. - m_Mobile.Send(new PartyMemberList(p)); - - Packet message = Packet.Acquire(new MessageLocalizedAffix(Serial.MinusOne, -1, MessageType.Label, 0x3B2, 3, - 1008087, "", AffixType.Prepend | AffixType.System, m_Mobile.Name, "")); - Packet attrs = Packet.Acquire(new MobileAttributesN(m_Mobile)); + PartyPackets.SendPartyMemberList(m_Mobile.NetState, p); foreach (PartyMemberInfo mi in p.Members) { @@ -448,16 +366,15 @@ namespace Server.Engines.PartySystem if (m != m_Mobile) { - m.Send(message); - m.Send(new MobileStatusCompact(m_Mobile.CanBeRenamedBy(m), m_Mobile)); - m.Send(attrs); - m_Mobile.Send(new MobileStatusCompact(m.CanBeRenamedBy(m_Mobile), m)); - m_Mobile.Send(new MobileAttributesN(m)); + NetState ns = m.NetState; + Packets.SendMessageLocalizedAffix(ns, Serial.MinusOne, -1, MessageType.Label, 0x3B2, 3, + 1008087, "", AffixType.Prepend | AffixType.System, m_Mobile.Name); + Packets.SendMobileStatusCompact(ns, m_Mobile, m_Mobile.CanBeRenamedBy(m)); + Packets.SendNormalizedMobileAttributes(ns, m_Mobile); + Packets.SendMobileStatusCompact(ns, m, m.CanBeRenamedBy(m_Mobile)); + Packets.SendNormalizedMobileAttributes(ns, m); } } - - Packet.Release(message); - Packet.Release(attrs); } } } diff --git a/Projects/Scripts/Engines/Pathing/FastAStarAlgorithm.cs b/Projects/Scripts/Engines/Pathing/FastAStarAlgorithm.cs index 312e995c0..640b624bf 100644 --- a/Projects/Scripts/Engines/Pathing/FastAStarAlgorithm.cs +++ b/Projects/Scripts/Engines/Pathing/FastAStarAlgorithm.cs @@ -1,19 +1,17 @@ using System.Collections; using Server.Mobiles; -using CalcMoves = Server.Movement.Movement; -using MoveImpl = Server.Movement.MovementImpl; -namespace Server.PathAlgorithms.FastAStar +namespace Server.PathAlgorithms { - public struct PathNode - { - public int cost, total; - public int parent, next, prev; - public int z; - } - public class FastAStarAlgorithm : PathAlgorithm { + public struct PathNode + { + public int cost, total; + public int parent, next, prev; + public int z; + } + private const int MaxDepth = 300; private const int AreaSize = 38; @@ -134,18 +132,18 @@ namespace Server.PathAlgorithms.FastAStar if (bc != null) { - MoveImpl.AlwaysIgnoreDoors = bc.CanOpenDoors; - MoveImpl.IgnoreMovableImpassables = bc.CanMoveOverObstacles; + MovementImpl.AlwaysIgnoreDoors = bc.CanOpenDoors; + MovementImpl.IgnoreMovableImpassables = bc.CanMoveOverObstacles; } - MoveImpl.Goal = goal; + MovementImpl.Goal = goal; int[] vals = m_Successors; int count = GetSuccessors(bestNode, m, map); - MoveImpl.AlwaysIgnoreDoors = false; - MoveImpl.IgnoreMovableImpassables = false; - MoveImpl.Goal = Point3D.Zero; + MovementImpl.AlwaysIgnoreDoors = false; + MovementImpl.IgnoreMovableImpassables = false; + MovementImpl.Goal = Point3D.Zero; if (count == 0) break; @@ -158,26 +156,26 @@ namespace Server.PathAlgorithms.FastAStar if (wasTouched) continue; - + int newCost = m_Nodes[bestNode].cost + 1; int newTotal = newCost + Heuristic(newNode % AreaSize, newNode / AreaSize % AreaSize, m_Nodes[newNode].z); if (m_Nodes[newNode].total <= newTotal) continue; - + m_Nodes[newNode].parent = bestNode; m_Nodes[newNode].cost = newCost; m_Nodes[newNode].total = newTotal; if (m_OnOpen[newNode]) continue; - + AddToChain(newNode); if (newNode != destNode) continue; - + int pathCount = 0; int parent = m_Nodes[newNode].parent; @@ -296,7 +294,7 @@ namespace Server.PathAlgorithms.FastAStar if (x < 0 || x >= AreaSize || y < 0 || y >= AreaSize) continue; - if (CalcMoves.CheckMovement(m, map, p3D, (Direction)i, out int z)) + if (Movement.CheckMovement(m, map, p3D, (Direction)i, out int z)) { int idx = GetIndex(x + m_xOffset, y + m_yOffset, z); @@ -311,4 +309,4 @@ namespace Server.PathAlgorithms.FastAStar return count; } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Engines/Pathing/FastMovement.cs b/Projects/Scripts/Engines/Pathing/FastMovement.cs index d71530a80..ae3fa8b67 100644 --- a/Projects/Scripts/Engines/Pathing/FastMovement.cs +++ b/Projects/Scripts/Engines/Pathing/FastMovement.cs @@ -8,7 +8,7 @@ using Server.Mobiles; #endregion -namespace Server.Movement +namespace Server { public class FastMovementImpl : IMovementImpl { @@ -179,7 +179,7 @@ namespace Server.Movement private static bool Check( Map map, Mobile m, - List items, + IReadOnlyCollection items, int x, int y, int startTop, diff --git a/Projects/Scripts/Engines/Pathing/Movement.cs b/Projects/Scripts/Engines/Pathing/Movement.cs index e04e7b1a8..6fbf02972 100644 --- a/Projects/Scripts/Engines/Pathing/Movement.cs +++ b/Projects/Scripts/Engines/Pathing/Movement.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using Server.Items; using Server.Mobiles; -namespace Server.Movement +namespace Server { public class MovementImpl : IMovementImpl { @@ -316,7 +316,7 @@ namespace Server.Movement return true; } - private bool Check(Map map, Mobile m, List items, List mobiles, int x, int y, int startTop, int startZ, + private bool Check(Map map, Mobile m, List items, IReadOnlyList mobiles, int x, int y, int startTop, int startZ, bool canSwim, bool cantWalk, out int newZ) { newZ = 0; @@ -500,7 +500,7 @@ namespace Server.Movement !t.Alive || !m.Alive || t.IsDeadBondedPet || m.IsDeadBondedPet || t.Hidden && t.AccessLevel > AccessLevel.Player; - private void GetStartZ(Mobile m, Map map, Point3D loc, List itemList, out int zLow, out int zTop) + private void GetStartZ(Mobile m, Map map, Point3D loc, IReadOnlyList itemList, out int zLow, out int zTop) { int xCheck = loc.X, yCheck = loc.Y; diff --git a/Projects/Scripts/Engines/Pathing/MovementPath.cs b/Projects/Scripts/Engines/Pathing/MovementPath.cs index 17a7f7409..ef993e52e 100644 --- a/Projects/Scripts/Engines/Pathing/MovementPath.cs +++ b/Projects/Scripts/Engines/Pathing/MovementPath.cs @@ -1,8 +1,6 @@ using System; using Server.Items; using Server.PathAlgorithms; -using Server.PathAlgorithms.FastAStar; -using Server.PathAlgorithms.SlowAStar; using Server.Spells; using Server.Targeting; @@ -84,7 +82,7 @@ namespace Server for (int i = 0; i < path.Directions.Length; ++i) { - Movement.Movement.Offset(path.Directions[i], ref x, ref y); + Movement.Offset(path.Directions[i], ref x, ref y); new RecallRune().MoveToWorld(new Point3D(x, y, z + zOffset), from.Map); } diff --git a/Projects/Scripts/Engines/Pathing/PathAlgorithm.cs b/Projects/Scripts/Engines/Pathing/PathAlgorithm.cs index 07500b988..9d04dd9ac 100644 --- a/Projects/Scripts/Engines/Pathing/PathAlgorithm.cs +++ b/Projects/Scripts/Engines/Pathing/PathAlgorithm.cs @@ -2,7 +2,7 @@ namespace Server.PathAlgorithms { public abstract class PathAlgorithm { - private static Direction[] m_CalcDirections = { + private static readonly Direction[] m_CalcDirections = { Direction.Up, Direction.North, Direction.Right, @@ -29,4 +29,4 @@ namespace Server.PathAlgorithms return m_CalcDirections[v]; } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Engines/Pathing/PathFollower.cs b/Projects/Scripts/Engines/Pathing/PathFollower.cs index 6780ba930..43004f0b0 100644 --- a/Projects/Scripts/Engines/Pathing/PathFollower.cs +++ b/Projects/Scripts/Engines/Pathing/PathFollower.cs @@ -1,5 +1,4 @@ using System; -using CalcMoves = Server.Movement.Movement; namespace Server { @@ -52,7 +51,7 @@ namespace Server { int x = p.X, y = p.Y; - CalcMoves.Offset(dirs[index], ref x, ref y); + Movement.Offset(dirs[index], ref x, ref y); p.X = x; p.Y = y; diff --git a/Projects/Scripts/Engines/Pathing/SlowAStarAlgorithm.cs b/Projects/Scripts/Engines/Pathing/SlowAStarAlgorithm.cs index e09d23520..3b36291ab 100644 --- a/Projects/Scripts/Engines/Pathing/SlowAStarAlgorithm.cs +++ b/Projects/Scripts/Engines/Pathing/SlowAStarAlgorithm.cs @@ -1,20 +1,18 @@ using System; using Server.Mobiles; -using CalcMoves = Server.Movement.Movement; -using MoveImpl = Server.Movement.MovementImpl; -namespace Server.PathAlgorithms.SlowAStar +namespace Server.PathAlgorithms { - public struct PathNode - { - public int x, y, z; - public int g, h; - public int px, py, pz; - public int dir; - } - public class SlowAStarAlgorithm : PathAlgorithm { + public struct PathNode + { + public int x, y, z; + public int g, h; + public int px, py, pz; + public int dir; + } + private const int MaxDepth = 300; private const int MaxNodes = MaxDepth * 16; public static PathAlgorithm Instance = new SlowAStarAlgorithm(); @@ -148,11 +146,11 @@ namespace Server.PathAlgorithms.SlowAStar if (bc != null) { - MoveImpl.AlwaysIgnoreDoors = bc.CanOpenDoors; - MoveImpl.IgnoreMovableImpassables = bc.CanMoveOverObstacles; + MovementImpl.AlwaysIgnoreDoors = bc.CanOpenDoors; + MovementImpl.IgnoreMovableImpassables = bc.CanMoveOverObstacles; } - MoveImpl.Goal = goal; + MovementImpl.Goal = goal; int x; int y; @@ -162,7 +160,6 @@ namespace Server.PathAlgorithms.SlowAStar switch (i) { default: - case 0: x = 0; y = -1; break; @@ -196,7 +193,7 @@ namespace Server.PathAlgorithms.SlowAStar break; } - if (CalcMoves.CheckMovement(m, map, new Point3D(curNode.x, curNode.y, curNode.z), (Direction)i, out z)) + if (Movement.CheckMovement(m, map, new Point3D(curNode.x, curNode.y, curNode.z), (Direction)i, out z)) { successors[sucCount].x = x + curNode.x; successors[sucCount].y = y + curNode.y; @@ -204,9 +201,9 @@ namespace Server.PathAlgorithms.SlowAStar } } - MoveImpl.AlwaysIgnoreDoors = false; - MoveImpl.IgnoreMovableImpassables = false; - MoveImpl.Goal = Point3D.Zero; + MovementImpl.AlwaysIgnoreDoors = false; + MovementImpl.IgnoreMovableImpassables = false; + MovementImpl.Goal = Point3D.Zero; if (sucCount == 0 || ++depth > MaxDepth) break; @@ -272,4 +269,4 @@ namespace Server.PathAlgorithms.SlowAStar return null; } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Engines/Plants/EmptyTheBowlGump.cs b/Projects/Scripts/Engines/Plants/EmptyTheBowlGump.cs index fdd97d00e..5b98406c2 100644 --- a/Projects/Scripts/Engines/Plants/EmptyTheBowlGump.cs +++ b/Projects/Scripts/Engines/Plants/EmptyTheBowlGump.cs @@ -75,7 +75,7 @@ namespace Server.Engines.Plants } case 2: // Help { - from.Send(new DisplayHelpTopic(71, true)); // EMPTYING THE BOWL + ContentPackets.SendDisplayHelpTopic(from.NetState, 17, true); // EMPTYING THE BOWL from.SendGump(new EmptyTheBowlGump(m_Plant)); diff --git a/Projects/Scripts/Engines/Plants/MainPlantGump.cs b/Projects/Scripts/Engines/Plants/MainPlantGump.cs index 835b8ed10..ae5da309a 100644 --- a/Projects/Scripts/Engines/Plants/MainPlantGump.cs +++ b/Projects/Scripts/Engines/Plants/MainPlantGump.cs @@ -264,9 +264,7 @@ namespace Server.Engines.Plants case 1: // Reproduction menu { if (m_Plant.PlantStatus > PlantStatus.BowlOfDirt) - { from.SendGump(new ReproductionGump(m_Plant)); - } else { from.SendLocalizedMessage(1061885); // You need to plant a seed in the bowl first. @@ -278,32 +276,28 @@ namespace Server.Engines.Plants } case 2: // Infestation { - from.Send(new DisplayHelpTopic(54, true)); // INFESTATION LEVEL - + ContentPackets.SendDisplayHelpTopic(from.NetState, 54, true); // INFESTATION LEVEL from.SendGump(new MainPlantGump(m_Plant)); break; } case 3: // Fungus { - from.Send(new DisplayHelpTopic(56, true)); // FUNGUS LEVEL - + ContentPackets.SendDisplayHelpTopic(from.NetState, 56, true); // FUNGUS LEVEL from.SendGump(new MainPlantGump(m_Plant)); break; } case 4: // Poison { - from.Send(new DisplayHelpTopic(58, true)); // POISON LEVEL - + ContentPackets.SendDisplayHelpTopic(from.NetState, 58, true); // POISON LEVEL from.SendGump(new MainPlantGump(m_Plant)); break; } case 5: // Disease { - from.Send(new DisplayHelpTopic(60, true)); // DISEASE LEVEL - + ContentPackets.SendDisplayHelpTopic(from.NetState, 60, true); // DISEASE LEVEL from.SendGump(new MainPlantGump(m_Plant)); break; @@ -320,9 +314,7 @@ namespace Server.Engines.Plants $"#{m_Plant.GetLocalizedPlantStatus()}"); // Target the container you wish to use to water the ~1_val~. } else - { m_Plant.Pour(from, bev); - } from.SendGump(new MainPlantGump(m_Plant)); @@ -354,7 +346,7 @@ namespace Server.Engines.Plants } case 11: // Help { - from.Send(new DisplayHelpTopic(48, true)); // PLANT GROWING + ContentPackets.SendDisplayHelpTopic(from.NetState, 48, true); // PLANT GROWING from.SendGump(new MainPlantGump(m_Plant)); @@ -374,9 +366,7 @@ namespace Server.Engines.Plants Item item = GetPotion(from, effects); if (item != null) - { m_Plant.Pour(from, item); - } else { if (m_Plant.ApplyPotion(effects[0], true, out int message)) diff --git a/Projects/Scripts/Engines/Plants/Network/DisplayHelpTopic.cs b/Projects/Scripts/Engines/Plants/Network/DisplayHelpTopic.cs deleted file mode 100644 index e026d8a03..000000000 --- a/Projects/Scripts/Engines/Plants/Network/DisplayHelpTopic.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Server.Network -{ - public class DisplayHelpTopic : Packet - { - public DisplayHelpTopic(int topicID, bool display) : base(0xBF) - { - EnsureCapacity(11); - - m_Stream.Write((short)0x17); - m_Stream.Write((byte)1); - m_Stream.Write(topicID); - m_Stream.Write(display); - } - } -} \ No newline at end of file diff --git a/Projects/Scripts/Engines/Plants/PlantItem.cs b/Projects/Scripts/Engines/Plants/PlantItem.cs index 6e825842b..db0a0124c 100644 --- a/Projects/Scripts/Engines/Plants/PlantItem.cs +++ b/Projects/Scripts/Engines/Plants/PlantItem.cs @@ -84,8 +84,7 @@ namespace Server.Engines.Plants } else { - if (PlantSystem == null) - PlantSystem = new PlantSystem(this, false); + PlantSystem ??= new PlantSystem(this, false); int hits = (int)(PlantSystem.MaxHits * ratio); diff --git a/Projects/Scripts/Engines/Plants/PlantResources.cs b/Projects/Scripts/Engines/Plants/PlantResources.cs index 32eae6913..6059c5140 100644 --- a/Projects/Scripts/Engines/Plants/PlantResources.cs +++ b/Projects/Scripts/Engines/Plants/PlantResources.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using Server.Items; namespace Server.Engines.Plants @@ -31,15 +32,9 @@ namespace Server.Engines.Plants public Type ResourceType{ get; } - public static PlantResourceInfo GetInfo(PlantType plantType, PlantHue plantHue) - { - foreach (PlantResourceInfo info in m_ResourceList) - if (info.PlantType == plantType && info.PlantHue == plantHue) - return info; - - return null; - } + public static PlantResourceInfo GetInfo(PlantType plantType, PlantHue plantHue) => + m_ResourceList.FirstOrDefault(info => info.PlantType == plantType && info.PlantHue == plantHue); public Item CreateResource() => (Item)Activator.CreateInstance(ResourceType); } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Engines/Plants/PlantSystem.cs b/Projects/Scripts/Engines/Plants/PlantSystem.cs index 25539101c..832a63fd1 100644 --- a/Projects/Scripts/Engines/Plants/PlantSystem.cs +++ b/Projects/Scripts/Engines/Plants/PlantSystem.cs @@ -383,6 +383,7 @@ namespace Server.Engines.Plants return 1060827; // soft if (Water <= 3) return 1060828; // squishy + return 1060829; // sopping wet } diff --git a/Projects/Scripts/Engines/Plants/PlantType.cs b/Projects/Scripts/Engines/Plants/PlantType.cs index aaeb5ea27..0010b253f 100644 --- a/Projects/Scripts/Engines/Plants/PlantType.cs +++ b/Projects/Scripts/Engines/Plants/PlantType.cs @@ -261,21 +261,13 @@ namespace Server.Engines.Plants double rand = Utility.RandomDouble(); - if (rand < 0.5 / exp4) - return PlantType.CommonGreenBonsai; - if (rand < 1.0 / exp4) - return PlantType.CommonPinkBonsai; - if (rand < (k1 * 0.5 + 1.0) / exp4) - return PlantType.UncommonGreenBonsai; - if (rand < exp1 / exp4) - return PlantType.UncommonPinkBonsai; - if (rand < (k2 * 0.5 + exp1) / exp4) - return PlantType.RareGreenBonsai; - if (rand < exp2 / exp4) - return PlantType.RarePinkBonsai; - if (rand < exp3 / exp4) - return PlantType.ExceptionalBonsai; - return PlantType.ExoticBonsai; + return rand < 0.5 / exp4 ? PlantType.CommonGreenBonsai : + rand < 1.0 / exp4 ? PlantType.CommonPinkBonsai : + rand < (k1 * 0.5 + 1.0) / exp4 ? PlantType.UncommonGreenBonsai : + rand < exp1 / exp4 ? PlantType.UncommonPinkBonsai : + rand < (k2 * 0.5 + exp1) / exp4 ? PlantType.RareGreenBonsai : + rand < exp2 / exp4 ? PlantType.RarePinkBonsai : + rand < exp3 / exp4 ? PlantType.ExceptionalBonsai : PlantType.ExoticBonsai; } public static bool IsCrossable(PlantType plantType) => GetInfo(plantType).Crossable; @@ -356,4 +348,4 @@ namespace Server.Engines.Plants return hueInfo.IsBright() ? 1113493 : 1113492; // ~1_amount~ [bright] ~2_color~ ~3_type~ seeds } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Engines/Plants/PollinateTarget.cs b/Projects/Scripts/Engines/Plants/PollinateTarget.cs index f7d0ded40..22b8e1cd9 100644 --- a/Projects/Scripts/Engines/Plants/PollinateTarget.cs +++ b/Projects/Scripts/Engines/Plants/PollinateTarget.cs @@ -14,50 +14,30 @@ namespace Server.Engines.Plants from.InRange(m_Plant.GetWorldLocation(), 3)) { if (!m_Plant.IsUsableBy(from)) - { m_Plant.LabelTo(from, 1061856); // You must have the item in your backpack or locked down in order to use it. - } else if (!m_Plant.IsCrossable) - { m_Plant.LabelTo(from, 1053050); // You cannot gather pollen from a mutated plant! - } else if (!m_Plant.PlantSystem.PollenProducing) - { m_Plant.LabelTo(from, 1053051); // You cannot gather pollen from a plant in this stage of development! - } else if (m_Plant.PlantSystem.Health < PlantHealth.Healthy) - { m_Plant.LabelTo(from, 1053052); // You cannot gather pollen from an unhealthy plant! - } else { if (!(targeted is PlantItem targ) || targ.PlantStatus >= PlantStatus.DecorativePlant || targ.PlantStatus <= PlantStatus.BowlOfDirt) - { m_Plant.LabelTo(from, 1053070); // You can only pollinate other specially grown plants! - } else if (!targ.IsUsableBy(from)) - { targ.LabelTo(from, 1061856); // You must have the item in your backpack or locked down in order to use it. - } else if (!targ.IsCrossable) - { targ.LabelTo(from, 1053073); // You cannot cross-pollinate with a mutated plant! - } else if (!targ.PlantSystem.PollenProducing) - { targ.LabelTo(from, 1053074); // This plant is not in the flowering stage. You cannot pollinate it! - } else if (targ.PlantSystem.Health < PlantHealth.Healthy) - { targ.LabelTo(from, 1053075); // You cannot pollinate an unhealthy plant! - } else if (targ.PlantSystem.Pollinated) - { targ.LabelTo(from, 1053072); // This plant has already been pollinated! - } else if (targ == m_Plant) { targ.PlantSystem.Pollinated = true; @@ -85,4 +65,4 @@ namespace Server.Engines.Plants m_Plant.IsUsableBy(from)) from.SendGump(new ReproductionGump(m_Plant)); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Engines/Plants/ReproductionGump.cs b/Projects/Scripts/Engines/Plants/ReproductionGump.cs index ead5ca625..5506bf512 100644 --- a/Projects/Scripts/Engines/Plants/ReproductionGump.cs +++ b/Projects/Scripts/Engines/Plants/ReproductionGump.cs @@ -138,24 +138,21 @@ namespace Server.Engines.Plants } case 3: // Pollination { - from.Send(new DisplayHelpTopic(67, true)); // POLLINATION STATE - + ContentPackets.SendDisplayHelpTopic(from.NetState, 67, true); // POLLINATION STATE from.SendGump(new ReproductionGump(m_Plant)); break; } case 4: // Resources { - from.Send(new DisplayHelpTopic(69, true)); // RESOURCE PRODUCTION - + ContentPackets.SendDisplayHelpTopic(from.NetState, 69, true); // RESOURCE PRODUCTION from.SendGump(new ReproductionGump(m_Plant)); break; } case 5: // Seeds { - from.Send(new DisplayHelpTopic(68, true)); // SEED PRODUCTION - + ContentPackets.SendDisplayHelpTopic(from.NetState, 68, true); // SEED PRODUCTION from.SendGump(new ReproductionGump(m_Plant)); break; @@ -200,9 +197,7 @@ namespace Server.Engines.Plants m_Plant.LabelTo(from, 1053055); // Mutated plants do not produce resources! } else if (system.AvailableResources == 0) - { m_Plant.LabelTo(from, 1053056); // This plant has no resources to gather! - } else { Item resource = resInfo.CreateResource(); @@ -229,13 +224,9 @@ namespace Server.Engines.Plants PlantSystem system = m_Plant.PlantSystem; if (!m_Plant.Reproduces) - { m_Plant.LabelTo(from, 1053060); // Mutated plants do not produce seeds! - } else if (system.AvailableSeeds == 0) - { m_Plant.LabelTo(from, 1053061); // This plant has no seeds to gather! - } else { Seed seed = new Seed(system.SeedType, system.SeedHue, true); diff --git a/Projects/Scripts/Engines/Plants/SetToDecorativeGump.cs b/Projects/Scripts/Engines/Plants/SetToDecorativeGump.cs index 5b3a60bce..4e63c8166 100644 --- a/Projects/Scripts/Engines/Plants/SetToDecorativeGump.cs +++ b/Projects/Scripts/Engines/Plants/SetToDecorativeGump.cs @@ -64,7 +64,7 @@ namespace Server.Engines.Plants } case 2: // Help { - from.Send(new DisplayHelpTopic(70, true)); // DECORATIVE MODE + ContentPackets.SendDisplayHelpTopic(from.NetState, 70, true); // DECORATIVE MODE from.SendGump(new SetToDecorativeGump(m_Plant)); diff --git a/Projects/Scripts/Engines/Quests/Collector/Items/Obsidian.cs b/Projects/Scripts/Engines/Quests/Collector/Items/Obsidian.cs index d48cd0da2..a0e87b719 100644 --- a/Projects/Scripts/Engines/Quests/Collector/Items/Obsidian.cs +++ b/Projects/Scripts/Engines/Quests/Collector/Items/Obsidian.cs @@ -167,11 +167,10 @@ namespace Server.Engines.Quests.Collector { if (m_Quantity < m_Completed) { - if (!IsChildOf(from.Backpack)) - from.Send(new MessageLocalized(Serial, ItemID, MessageType.Regular, 0x2C, 3, 500309, "", - "")); // Nothing Happens. - else + if (IsChildOf(from.Backpack)) from.Target = new InternalTarget(this); + else + Packets.SendMessageLocalized(from.NetState, Serial, ItemID, MessageType.Regular, 0x2C, 3, 500309); // Nothing Happens. } } @@ -245,15 +244,15 @@ namespace Server.Engines.Quests.Collector if (targObsidian.Quantity >= m_Completed) targObsidian.StatueName = RandomName(from); - from.Send(new AsciiMessage(targObsidian.Serial, targObsidian.ItemID, MessageType.Regular, 0x59, 3, - m_Obsidian.Name, "Something Happened.")); + Packets.SendAsciiMessage(from.NetState, targObsidian.Serial, targObsidian.ItemID, MessageType.Regular, 0x59, 3, + m_Obsidian.Name, "Something Happened."); return; } - from.Send(new MessageLocalized(m_Obsidian.Serial, m_Obsidian.ItemID, MessageType.Regular, 0x2C, 3, 500309, - m_Obsidian.Name, "")); // Nothing Happens. + Packets.SendMessageLocalized(from.NetState, m_Obsidian.Serial, m_Obsidian.ItemID, MessageType.Regular, 0x2C, 3, 500309, + m_Obsidian.Name); // Nothing Happens. } } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Engines/Quests/Collector/Objectives.cs b/Projects/Scripts/Engines/Quests/Collector/Objectives.cs index c59bd2a2b..9157eba14 100644 --- a/Projects/Scripts/Engines/Quests/Collector/Objectives.cs +++ b/Projects/Scripts/Engines/Quests/Collector/Objectives.cs @@ -359,4 +359,4 @@ namespace Server.Engines.Quests.Collector { public override object Message => 1055136; } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Engines/Quests/Core/Items/EnchantedSextant.cs b/Projects/Scripts/Engines/Quests/Core/Items/EnchantedSextant.cs index 2bb1b0fe0..9282a47f1 100644 --- a/Projects/Scripts/Engines/Quests/Core/Items/EnchantedSextant.cs +++ b/Projects/Scripts/Engines/Quests/Core/Items/EnchantedSextant.cs @@ -99,11 +99,10 @@ namespace Server.Items else if (from.Map == Map.Ilshenar) { #if false - banks = m_IlshenarBanks; - moongates = PMList.Ilshenar; + banks = m_IlshenarBanks; + moongates = PMList.Ilshenar; #else - from.Send(new MessageLocalized(Serial, ItemID, MessageType.Label, 0x482, 3, 1061684, "", - "")); // The magic of the sextant fails... + Packets.SendMessageLocalized(from.NetState, Serial, ItemID, MessageType.Label, 0x482, 3, 1061684); // The magic of the sextant fails... return; #endif } @@ -154,7 +153,7 @@ namespace Server.Items else moonMsg = 1048018; // You are next to a Moongate at the moment. - from.Send(new MessageLocalized(Serial, ItemID, MessageType.Label, 0x482, 3, moonMsg, "", "")); + Packets.SendMessageLocalized(from.NetState, Serial, ItemID, MessageType.Label, 0x482, 3, moonMsg); int bankMsg; if (bankDistance == double.MaxValue) @@ -166,7 +165,7 @@ namespace Server.Items else bankMsg = 1048019; // You are next to a Bank at the moment. - from.Send(new MessageLocalized(Serial, ItemID, MessageType.Label, 0x5AA, 3, bankMsg, "", "")); + Packets.SendMessageLocalized(from.NetState, Serial, ItemID, MessageType.Label, 0x5AA, 3, bankMsg); } public override void Serialize(GenericWriter writer) @@ -183,4 +182,4 @@ namespace Server.Items int version = reader.ReadInt(); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Engines/Quests/Core/QuestSerializer.cs b/Projects/Scripts/Engines/Quests/Core/QuestSerializer.cs index fcec07493..e8aabf4aa 100644 --- a/Projects/Scripts/Engines/Quests/Core/QuestSerializer.cs +++ b/Projects/Scripts/Engines/Quests/Core/QuestSerializer.cs @@ -44,9 +44,7 @@ namespace Server.Engines.Quests switch (encoding) { default: - { return null; - } case 0x01: // indexed { int index = reader.ReadEncodedInt(); @@ -75,9 +73,7 @@ namespace Server.Engines.Quests switch (encoding) { default: - { return null; - } case 0x01: { Type type = ReadType(QuestSystem.QuestTypes, reader); @@ -94,9 +90,7 @@ namespace Server.Engines.Quests public static void Serialize(QuestSystem qs, GenericWriter writer) { if (qs == null) - { writer.WriteEncodedInt(0x00); - } else { writer.WriteEncodedInt(0x01); @@ -114,9 +108,7 @@ namespace Server.Engines.Quests switch (encoding) { default: - { return null; - } case 0x01: { Type type = ReadType(referenceTable, reader); @@ -133,9 +125,7 @@ namespace Server.Engines.Quests public static void Serialize(Type[] referenceTable, QuestObjective obj, GenericWriter writer) { if (obj == null) - { writer.WriteEncodedInt(0x00); - } else { writer.WriteEncodedInt(0x01); @@ -153,9 +143,7 @@ namespace Server.Engines.Quests switch (encoding) { default: - { return null; - } case 0x01: { Type type = ReadType(referenceTable, reader); @@ -172,9 +160,7 @@ namespace Server.Engines.Quests public static void Serialize(Type[] referenceTable, QuestConversation conv, GenericWriter writer) { if (conv == null) - { writer.WriteEncodedInt(0x00); - } else { writer.WriteEncodedInt(0x01); diff --git a/Projects/Scripts/Engines/Quests/Core/QuestSystem.cs b/Projects/Scripts/Engines/Quests/Core/QuestSystem.cs index 01397d2a0..129093721 100644 --- a/Projects/Scripts/Engines/Quests/Core/QuestSystem.cs +++ b/Projects/Scripts/Engines/Quests/Core/QuestSystem.cs @@ -259,7 +259,7 @@ namespace Server.Engines.Quests From.SendGump(new QuestObjectivesGump(Objectives)); - QuestObjective last = Objectives[Objectives.Count - 1]; + QuestObjective last = Objectives[^1]; if (last.Info != null) From.SendGump(new QuestItemInfoGump(last.Info)); @@ -276,7 +276,7 @@ namespace Server.Engines.Quests From.SendGump(new QuestConversationsGump(Conversations)); - QuestConversation last = Conversations[Conversations.Count - 1]; + QuestConversation last = Conversations[^1]; if (last.Info != null) From.SendGump(new QuestItemInfoGump(last.Info)); diff --git a/Projects/Scripts/Engines/Quests/Dark Tides/Items/KronusScroll.cs b/Projects/Scripts/Engines/Quests/Dark Tides/Items/KronusScroll.cs index b0cdb7038..81912200d 100644 --- a/Projects/Scripts/Engines/Quests/Dark Tides/Items/KronusScroll.cs +++ b/Projects/Scripts/Engines/Quests/Dark Tides/Items/KronusScroll.cs @@ -1,13 +1,12 @@ using System; using Server.Items; using Server.Mobiles; -using Server.Network; namespace Server.Engines.Quests.Necro { public class KronusScroll : QuestItem { - private static readonly Rectangle2D m_WellOfTearsArea = new Rectangle2D(2080, 1346, 10, 10); + private static Rectangle2D m_WellOfTearsArea = new Rectangle2D(2080, 1346, 10, 10); private static readonly Map m_WellOfTearsMap = Map.Malas; [Constructible] @@ -134,9 +133,7 @@ namespace Server.Engines.Quests.Necro int hue = Utility.RandomList(0x481, 0x482, 0x489, 0x497, 0x66D); - Effects.SendPacket(from, map, - new HuedEffect(EffectType.Moving, Serial.Zero, Serial.Zero, 0x36D4, from, to, 0, 0, false, true, - hue, 0)); + Effects.SendMovingEffect(from, to, map, 0x36D4, 0, 0, false, true, hue); } } @@ -155,4 +152,4 @@ namespace Server.Engines.Quests.Necro } } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Engines/Quests/Dark Tides/Items/MaabusCoffin.cs b/Projects/Scripts/Engines/Quests/Dark Tides/Items/MaabusCoffin.cs index d1e311a1d..c6ce70243 100644 --- a/Projects/Scripts/Engines/Quests/Dark Tides/Items/MaabusCoffin.cs +++ b/Projects/Scripts/Engines/Quests/Dark Tides/Items/MaabusCoffin.cs @@ -65,8 +65,8 @@ namespace Server.Engines.Quests.Necro Maabus.Delete(); Maabus = null; - foreach (MaabusCoffinComponent c in Components) - c.TurnToFull(); + foreach (AddonComponent addonComponent in Components) + (addonComponent as MaabusCoffinComponent)?.TurnToFull(); } public override void Serialize(GenericWriter writer) @@ -151,4 +151,4 @@ namespace Server.Engines.Quests.Necro m_EmptyItemID = reader.ReadInt(); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Engines/Quests/Dark Tides/Objectives.cs b/Projects/Scripts/Engines/Quests/Dark Tides/Objectives.cs index 4eb61cc39..f39afebba 100644 --- a/Projects/Scripts/Engines/Quests/Dark Tides/Objectives.cs +++ b/Projects/Scripts/Engines/Quests/Dark Tides/Objectives.cs @@ -258,7 +258,7 @@ namespace Server.Engines.Quests.Necro public class FindWellOfTearsObjective : QuestObjective { - private static readonly Rectangle2D m_WellOfTearsArea = new Rectangle2D(2080, 1346, 10, 10); + private static Rectangle2D m_WellOfTearsArea = new Rectangle2D(2080, 1346, 10, 10); private bool m_Inside; diff --git a/Projects/Scripts/Engines/Quests/Uzeraan Turmoil/Conversations.cs b/Projects/Scripts/Engines/Quests/Uzeraan Turmoil/Conversations.cs index 1ed974af4..c62b965ab 100644 --- a/Projects/Scripts/Engines/Quests/Uzeraan Turmoil/Conversations.cs +++ b/Projects/Scripts/Engines/Quests/Uzeraan Turmoil/Conversations.cs @@ -36,29 +36,29 @@ namespace Server.Engines.Quests.Haven if (System.From.Profession == 2) // magician return 1049386; -/* Uzeraan nods at you with approval and begins to speak...

- * - * Now that you are ready, let me give you your first task.

- * - * As I mentioned earlier, we have been trying to fight back the wicked - * Horde Minions which have recently begun attacking our cities - * - but to no avail. Our need is great!

- * - * Your first task will be to assess the situation in the mountain pass, - * and help our troops defeat the Horde Minions there.

- * - * Take the road marked with glowing runes, that starts just outside of this mansion. - * Before you go into battle, it would be prudent to - * review combat techniques as well as - * information on healing yourself, - * using your Paladin ability 'Close Wounds'.

- * - * To aid you in your fight, you may also wish to - * purchase equipment from Frank the Blacksmith, - * who is standing just South of here.

- * - * Good luck young Paladin! - */ + /* Uzeraan nods at you with approval and begins to speak...

+ * + * Now that you are ready, let me give you your first task.

+ * + * As I mentioned earlier, we have been trying to fight back the wicked + * Horde Minions which have recently begun attacking our cities + * - but to no avail. Our need is great!

+ * + * Your first task will be to assess the situation in the mountain pass, + * and help our troops defeat the Horde Minions there.

+ * + * Take the road marked with glowing runes, that starts just outside of this mansion. + * Before you go into battle, it would be prudent to + * review combat techniques as well as + * information on healing yourself, + * using your Paladin ability 'Close Wounds'.

+ * + * To aid you in your fight, you may also wish to + * purchase equipment from Frank the Blacksmith, + * who is standing just South of here.

+ * + * Good luck young Paladin! + */ return 1060388; } } @@ -73,7 +73,7 @@ namespace Server.Engines.Quests.Haven public class UzeraanReportConversation : QuestConversation { - private static QuestItemInfo[] m_Info = + private static readonly QuestItemInfo[] m_Info = { new QuestItemInfo(1026153, 0x1822), // teleporter new QuestItemInfo(1048032, 0xE76) // a bag @@ -469,4 +469,4 @@ namespace Server.Engines.Quests.Haven public override bool Logged => false; } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Engines/Quests/Uzeraan Turmoil/Items/SchmendrickApprenticeCorpse.cs b/Projects/Scripts/Engines/Quests/Uzeraan Turmoil/Items/SchmendrickApprenticeCorpse.cs index 0f0904646..8847c6609 100644 --- a/Projects/Scripts/Engines/Quests/Uzeraan Turmoil/Items/SchmendrickApprenticeCorpse.cs +++ b/Projects/Scripts/Engines/Quests/Uzeraan Turmoil/Items/SchmendrickApprenticeCorpse.cs @@ -28,15 +28,14 @@ namespace Server.Engines.Quests.Haven { } - // TODO: What is this? Why are we creating and deleting a mobile? + // TODO: Should be a better way than making/deleting a mob. private static Mobile GetOwner() { - Mobile apprentice = new Mobile(); + Mobile apprentice = new Mobile + { + Hue = Race.Human.RandomSkinHue(), Female = false, Body = 0x190, Name = NameList.RandomName("male") + }; - apprentice.Hue = Race.Human.RandomSkinHue(); - apprentice.Female = false; - apprentice.Body = 0x190; - apprentice.Name = NameList.RandomName("male"); apprentice.Delete(); @@ -45,12 +44,14 @@ namespace Server.Engines.Quests.Haven private static List GetEquipment() { - List list = new List(); + List list = new List + { + new Robe(QuestSystem.RandomBrightHue()), + new WizardsHat(Utility.RandomNeutralHue()), + new Shoes(Utility.RandomNeutralHue()), + new Spellbook() + }; - list.Add(new Robe(QuestSystem.RandomBrightHue())); - list.Add(new WizardsHat(Utility.RandomNeutralHue())); - list.Add(new Shoes(Utility.RandomNeutralHue())); - list.Add(new Spellbook()); return list; } @@ -86,11 +87,10 @@ namespace Server.Engines.Quests.Haven int hue = Notoriety.GetHue(NotorietyHandlers.CorpseNotoriety(from, this)); if (ItemID == 0x2006) // Corpse form - from.Send(new MessageLocalized(Serial, ItemID, MessageType.Label, hue, 3, 1049144, "", - Name)); // the remains of ~1_NAME~ the apprentice + Packets.SendMessageLocalized(from.NetState, Serial, ItemID, MessageType.Label, hue, 3, 1049144, "", + Name); // the remains of ~1_NAME~ the apprentice else - from.Send(new MessageLocalized(Serial, ItemID, MessageType.Label, hue, 3, 1049145, "", - "")); // the remains of a wizard's apprentice + Packets.SendMessageLocalized(from.NetState, Serial, ItemID, MessageType.Label, hue, 3, 1049145); // the remains of a wizard's apprentice } public override void Open(Mobile from, bool checkSelfLoot) diff --git a/Projects/Scripts/Engines/Quests/Uzeraan Turmoil/Mobiles/MilitiaFighter.cs b/Projects/Scripts/Engines/Quests/Uzeraan Turmoil/Mobiles/MilitiaFighter.cs index 28a4e6619..155c0a5a2 100644 --- a/Projects/Scripts/Engines/Quests/Uzeraan Turmoil/Mobiles/MilitiaFighter.cs +++ b/Projects/Scripts/Engines/Quests/Uzeraan Turmoil/Mobiles/MilitiaFighter.cs @@ -118,11 +118,10 @@ namespace Server.Engines.Quests.Haven int hue = Notoriety.GetHue(NotorietyHandlers.CorpseNotoriety(from, this)); if (ItemID == 0x2006) // Corpse form - from.Send(new MessageLocalized(Serial, ItemID, MessageType.Label, hue, 3, 1049318, "", - Name)); // the remains of ~1_NAME~ the militia fighter + Packets.SendMessageLocalized(from.NetState, Serial, ItemID, MessageType.Label, hue, 3, 1049318, "", + Name); // the remains of ~1_NAME~ the militia fighter else - from.Send(new MessageLocalized(Serial, ItemID, MessageType.Label, hue, 3, 1049319, "", - "")); // the remains of a militia fighter + Packets.SendMessageLocalized(from.NetState, Serial, ItemID, MessageType.Label, hue, 3, 1049318); // the remains of a militia fighters } public override void Open(Mobile from, bool checkSelfLoot) @@ -146,4 +145,4 @@ namespace Server.Engines.Quests.Haven int version = reader.ReadInt(); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Engines/Quests/Uzeraan Turmoil/Objectives.cs b/Projects/Scripts/Engines/Quests/Uzeraan Turmoil/Objectives.cs index b023c610f..a4e34843f 100644 --- a/Projects/Scripts/Engines/Quests/Uzeraan Turmoil/Objectives.cs +++ b/Projects/Scripts/Engines/Quests/Uzeraan Turmoil/Objectives.cs @@ -72,9 +72,8 @@ namespace Server.Engines.Quests.Haven public KillHordeMinionsStep Step{ get; private set; } - public override object Message - { - get + public override object Message => + Step switch { return Step switch { @@ -108,19 +107,7 @@ namespace Server.Engines.Quests.Haven _ => 5 }; - return 5; - } - } - - public override bool Completed - { - get - { - if (Step == KillHordeMinionsStep.LearnKarma && HasBeenRead) - return true; - return base.Completed; - } - } + public override bool Completed => Step == KillHordeMinionsStep.LearnKarma && HasBeenRead || base.Completed; public override void RenderProgress(BaseQuestGump gump) { @@ -140,23 +127,15 @@ namespace Server.Engines.Quests.Haven CheckCompletionStatus(); } - public override bool IgnoreYoungProtection(Mobile from) - { - // This restriction continues until the quest is ended - if (from is HordeMinion && from.Map == Map.Trammel && from.X >= 3314 && from.X <= 3814 && from.Y >= 2345 && - from.Y <= 3095) // Haven island - return true; - - return false; - } + public override bool IgnoreYoungProtection(Mobile from) => + from is HordeMinion && from.Map == Map.Trammel && TreasureMap.IsInHavenIsland(from); public override void OnKill(BaseCreature creature, Container corpse) { - if (creature is HordeMinion && corpse.Map == Map.Trammel && corpse.X >= 3314 && corpse.X <= 3814 && - corpse.Y >= 2345 && corpse.Y <= 3095) // Haven island + if (creature is HordeMinion && corpse.Map == Map.Trammel && TreasureMap.IsInHavenIsland(corpse)) { if (CurProgress == 0) - System.From.Send(new DisplayHelpTopic(29, false)); // HEALING + ContentPackets.SendDisplayHelpTopic(System.From.NetState, 29, false); // HEALING CurProgress++; } @@ -340,49 +319,26 @@ namespace Server.Engines.Quests.Haven { public Container CorpseWithBone{ get; set; } - public override object Message - { - get - { - if (System.From.Profession == 5) return 1060755; - - /* Use Uzeraan's teleporter to get to the Haunted graveyard.

- * - * Slay the undead until you find a Daemon Bone. - */ - return 1049362; - } - } + public override object Message => System.From.Profession == 5 ? 1060755 : 1049362; public override void OnComplete() { System.AddObjective(new ReturnDaemonBoneObjective()); } - public override bool IgnoreYoungProtection(Mobile from) - { - // This restriction continues until the end of the quest - if ((from is Zombie || from is Skeleton) && from.Map == Map.Trammel && from.X >= 3391 && from.X <= 3424 && - from.Y >= 2639 && from.Y <= 2664) // Haven graveyard - return true; + private static bool IsInHavenGraveyard(IPoint2D p) => p.X >= 3391 && p.X <= 3424 && + p.Y >= 2639 && p.Y <= 2664; - return false; - } + public override bool IgnoreYoungProtection(Mobile from) => + (from is Zombie || from is Skeleton) && from.Map == Map.Trammel && IsInHavenGraveyard(from); - public override bool GetKillEvent(BaseCreature creature, Container corpse) - { - if (base.GetKillEvent(creature, corpse)) - return true; - - return UzeraanTurmoilQuest.HasLostDaemonBone(System.From); - } + public override bool GetKillEvent(BaseCreature creature, Container corpse) => + base.GetKillEvent(creature, corpse) || UzeraanTurmoilQuest.HasLostDaemonBone(System.From); public override void OnKill(BaseCreature creature, Container corpse) { - if ((creature is Zombie || creature is Skeleton) && corpse.Map == Map.Trammel && corpse.X >= 3391 && - corpse.X <= 3424 && corpse.Y >= 2639 && corpse.Y <= 2664) // Haven graveyard - if (Utility.RandomDouble() < 0.25) - CorpseWithBone = corpse; + if ((creature is Zombie || creature is Skeleton) && corpse.Map == Map.Trammel && IsInHavenGraveyard(corpse) && Utility.RandomDouble() < 0.25) + CorpseWithBone = corpse; } public override void ChildDeserialize(GenericReader reader) diff --git a/Projects/Scripts/Engines/Quests/Uzeraan Turmoil/UzeraanTurmoilQuest.cs b/Projects/Scripts/Engines/Quests/Uzeraan Turmoil/UzeraanTurmoilQuest.cs index e19696888..55f19b5ea 100644 --- a/Projects/Scripts/Engines/Quests/Uzeraan Turmoil/UzeraanTurmoilQuest.cs +++ b/Projects/Scripts/Engines/Quests/Uzeraan Turmoil/UzeraanTurmoilQuest.cs @@ -62,9 +62,8 @@ namespace Server.Engines.Quests.Haven public override TimeSpan RestartDelay => TimeSpan.MaxValue; public override bool IsTutorial => true; - public override int Picture - { - get + public override int Picture => + From.Profession switch { return From.Profession switch { diff --git a/Projects/Scripts/Engines/Quests/Witch Apprentice/Ingredient.cs b/Projects/Scripts/Engines/Quests/Witch Apprentice/Ingredient.cs index 5589c845d..807b5d3ee 100644 --- a/Projects/Scripts/Engines/Quests/Witch Apprentice/Ingredient.cs +++ b/Projects/Scripts/Engines/Quests/Witch Apprentice/Ingredient.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using Server.Mobiles; namespace Server.Engines.Quests.Hag @@ -89,12 +90,7 @@ namespace Server.Engines.Quests.Hag { Ingredient currIngredient = (Ingredient)i; - bool found = false; - for (int j = 0; !found && j < oldIngredients.Length; j++) - if (oldIngredients[j] == currIngredient) - found = true; - - if (!found) + if (oldIngredients.All(ingredient => ingredient != currIngredient)) ingredients[n++] = currIngredient; } @@ -103,4 +99,4 @@ namespace Server.Engines.Quests.Hag return ingredients[index]; } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Engines/Quests/Witch Apprentice/Items/HagApprenticeCorpse.cs b/Projects/Scripts/Engines/Quests/Witch Apprentice/Items/HagApprenticeCorpse.cs index 66e7fba84..39d9d29ad 100644 --- a/Projects/Scripts/Engines/Quests/Witch Apprentice/Items/HagApprenticeCorpse.cs +++ b/Projects/Scripts/Engines/Quests/Witch Apprentice/Items/HagApprenticeCorpse.cs @@ -46,7 +46,7 @@ namespace Server.Engines.Quests.Hag { int hue = Notoriety.GetHue(NotorietyHandlers.CorpseNotoriety(from, this)); - from.Send(new AsciiMessage(Serial, ItemID, MessageType.Label, hue, 3, "", "a charred corpse")); + Packets.SendAsciiMessage(from.NetState, Serial, ItemID, MessageType.Label, hue, 3, "", "a charred corpse"); } public override void Open(Mobile from, bool checkSelfLoot) @@ -96,4 +96,4 @@ namespace Server.Engines.Quests.Hag int version = reader.ReadInt(); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Engines/Quests/Witch Apprentice/Objectives.cs b/Projects/Scripts/Engines/Quests/Witch Apprentice/Objectives.cs index 777ab0fa8..e715ac8b1 100644 --- a/Projects/Scripts/Engines/Quests/Witch Apprentice/Objectives.cs +++ b/Projects/Scripts/Engines/Quests/Witch Apprentice/Objectives.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using Server.Items; using Server.Mobiles; @@ -50,7 +51,7 @@ namespace Server.Engines.Quests.Hag Corpse = new HagApprenticeCorpse(); Corpse.MoveToWorld(m_CorpseLocation, map); - Effects.SendLocationEffect(m_CorpseLocation, map, 0x3728, 10, 10); + Effects.SendLocationEffect(m_CorpseLocation, map, 0x3728, 10); Effects.PlaySound(m_CorpseLocation, map, 0x1FE); Mobile imp = new Zeefzorpul(); @@ -66,7 +67,7 @@ namespace Server.Engines.Quests.Hag { if (m?.Deleted == false) { - Effects.SendLocationEffect(m.Location, m.Map, 0x3728, 10, 10); + Effects.SendLocationEffect(m.Location, m.Map, 0x3728, 10); Effects.PlaySound(m.Location, m.Map, 0x1FE); m.Delete(); @@ -204,7 +205,7 @@ namespace Server.Engines.Quests.Hag Mobile from = System.From; Map map = from.Map; - Effects.SendLocationEffect(ImpLocation, map, 0x3728, 10, 10); + Effects.SendLocationEffect(ImpLocation, map, 0x3728, 10); Effects.PlaySound(ImpLocation, map, 0x1FE); Mobile imp = new Zeefzorpul(); @@ -219,7 +220,7 @@ namespace Server.Engines.Quests.Hag { if (imp is Mobile m && !m.Deleted) { - Effects.SendLocationEffect(m.Location, m.Map, 0x3728, 10, 10); + Effects.SendLocationEffect(m.Location, m.Map, 0x3728, 10); Effects.PlaySound(m.Location, m.Map, 0x1FE); m.Delete(); @@ -266,7 +267,7 @@ namespace Server.Engines.Quests.Hag for (int i = 0; i < oldIngredients.Length; i++) Ingredients[i] = oldIngredients[i]; - Ingredients[Ingredients.Length - 1] = IngredientInfo.RandomIngredient(oldIngredients); + Ingredients[^1] = IngredientInfo.RandomIngredient(oldIngredients); } else { @@ -279,13 +280,8 @@ namespace Server.Engines.Quests.Hag BlackheartMet = blackheartMet; } - public FindIngredientObjective() - { - } - - public override object Message - { - get + public override object Message => + !BlackheartMet ? Step switch { if (!BlackheartMet) return Step switch @@ -310,21 +306,13 @@ namespace Server.Engines.Quests.Hag */ return 1055055; } - } + : 1055055; - public override int MaxProgress - { - get - { - IngredientInfo info = IngredientInfo.Get(Ingredient); - - return info.Quantity; - } - } + public override int MaxProgress => IngredientInfo.Get(Ingredient).Quantity; public Ingredient[] Ingredients{ get; private set; } - public Ingredient Ingredient => Ingredients[Ingredients.Length - 1]; + public Ingredient Ingredient => Ingredients[^1]; public int Step => Ingredients.Length; public bool BlackheartMet{ get; private set; } @@ -345,26 +333,14 @@ namespace Server.Engines.Quests.Hag } } - public override bool IgnoreYoungProtection(Mobile from) - { - if (Completed) - return false; - - IngredientInfo info = IngredientInfo.Get(Ingredient); - Type fromType = from.GetType(); - - for (int i = 0; i < info.Creatures.Length; i++) - if (fromType == info.Creatures[i]) - return true; - - return false; - } + public override bool IgnoreYoungProtection(Mobile from) => + !Completed && IngredientInfo.Get(Ingredient).Creatures.Any(t => from.GetType() == t); public override void OnKill(BaseCreature creature, Container corpse) { IngredientInfo info = IngredientInfo.Get(Ingredient); - for (int i = 0; i < info.Creatures.Length; i++) + if (info.Creatures.Any(type => creature.GetType() == type)) { Type type = info.Creatures[i]; @@ -375,8 +351,7 @@ namespace Server.Engines.Quests.Hag CurProgress++; - break; - } + CurProgress++; } } diff --git a/Projects/Scripts/Engines/Spawner/Spawner.cs b/Projects/Scripts/Engines/Spawner/Spawner.cs index e6c0d77e1..2f2326944 100644 --- a/Projects/Scripts/Engines/Spawner/Spawner.cs +++ b/Projects/Scripts/Engines/Spawner/Spawner.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Reflection; using Server.Commands; using Server.Items; @@ -22,26 +23,24 @@ namespace Server.Mobiles private InternalTimer m_Timer; private int m_WalkingRange = -1; -// [Constructible] + [Constructible(AccessLevel.Developer)] + public Spawner() : base(0x1f13) + { + InitSpawn(1, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(10), 0, 4); + } + public Spawner(int amount, int minDelay, int maxDelay, int team, int homeRange, string spawnedNames) : base(0x1f13) { InitSpawn(amount, TimeSpan.FromMinutes(minDelay), TimeSpan.FromMinutes(maxDelay), team, homeRange); AddEntry(spawnedNames, 100, amount, false); } -// [Constructible] public Spawner(string spawnedName) : base(0x1f13) { InitSpawn(1, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(10), 0, 4); AddEntry(spawnedName, 100, 1, false); } - [Constructible(AccessLevel.Developer)] - public Spawner() : base(0x1f13) - { - InitSpawn(1, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(10), 0, 4); - } - public Spawner(int amount, TimeSpan minDelay, TimeSpan maxDelay, int team, int homeRange, params string[] spawnedNames) : base(0x1f13) { @@ -71,9 +70,8 @@ namespace Server.Mobiles { m_Count = value; - if (m_Timer != null) - if (!IsFull && !m_Timer.Running || IsFull && m_Timer.Running) - DoTimer(); + if (m_Timer != null && IsFull == m_Timer.Running) + DoTimer(); InvalidateProperties(); } @@ -266,20 +264,16 @@ namespace Server.Mobiles { base.OnSingleClick(from); - if (m_Running) - LabelTo(from, "[Running]"); - else - LabelTo(from, "[Off]"); + LabelTo(from, m_Running ? "[Running]" : "[Off]"); } public void Start() { - if (!m_Running) - if (Entries.Count > 0) - { - m_Running = true; - DoTimer(); - } + if (!m_Running && Entries.Count > 0) + { + m_Running = true; + DoTimer(); + } } public void Stop() @@ -293,8 +287,7 @@ namespace Server.Mobiles public void Defrag() { - if (Entries == null) - Entries = new List(); + Entries ??= new List(); for (int i = 0; i < Entries.Count; ++i) Entries[i].Defrag(this); @@ -302,8 +295,6 @@ namespace Server.Mobiles public void OnTick() { -// DoTimer( m_Spawned.Count >= m_Count ); - if (m_Group) { Defrag(); @@ -314,19 +305,8 @@ namespace Server.Mobiles Respawn(); } else - { Spawn(); - } -/* - if ( m_Running && m_Timer != null ) - { - if ( m_Spawned.Count >= m_Count && m_Timer.Running ) - DoTimer( true ); - else if ( m_Spawned.Count < m_Count && !m_Timer.Running ) - DoTimer( false ); - } -*/ DoTimer(); } @@ -347,11 +327,7 @@ namespace Server.Mobiles if (Entries.Count <= 0 || IsFull) return; - int probsum = 0; - - for (int i = 0; i < Entries.Count; i++) - if (!Entries[i].IsFull) - probsum += Entries[i].SpawnedProbability; + int probsum = Entries.Where(t => !t.IsFull).Sum(t => t.SpawnedProbability); if (probsum <= 0) return; @@ -394,9 +370,7 @@ namespace Server.Mobiles } } else - { props = new string[0, 0]; - } return props; } @@ -461,13 +435,8 @@ namespace Server.Mobiles try { object o = null; - string[] paramargs; - string[] propargs; - if (string.IsNullOrEmpty(entry.Properties)) - propargs = new string[0]; - else - propargs = CommandSystem.Split(entry.Properties.Trim()); + string[] propargs = string.IsNullOrEmpty(entry.Properties) ? new string[0] : CommandSystem.Split(entry.Properties.Trim()); string[,] props = FormatProperties(propargs); @@ -479,10 +448,7 @@ namespace Server.Mobiles return false; } - if (string.IsNullOrEmpty(entry.Parameters)) - paramargs = new string[0]; - else - paramargs = entry.Parameters.Trim().Split(' '); + string[] paramargs = string.IsNullOrEmpty(entry.Parameters) ? new string[0] : entry.Parameters.Trim().Split(' '); ConstructorInfo[] ctors = type.GetConstructors(); @@ -648,21 +614,9 @@ namespace Server.Mobiles LandTile landTile = map.Tiles.GetLandTile(x, y); - if (landTile.Z == z && (TileData.LandTable[landTile.ID & TileData.MaxLandValue].Flags & TileFlag.Wet) != 0) - return true; - - StaticTile[] staticTiles = map.Tiles.GetStaticTiles(x, y, true); - - for (int i = 0; i < staticTiles.Length; ++i) - { - StaticTile staticTile = staticTiles[i]; - - if (staticTile.Z == z && - (TileData.ItemTable[staticTile.ID & TileData.MaxItemValue].Flags & TileFlag.Wet) != 0) - return true; - } - - return false; + return landTile.Z == z && (TileData.LandTable[landTile.ID & TileData.MaxLandValue].Flags & TileFlag.Wet) != 0 || + map.Tiles.GetStaticTiles(x, y, true).Any(staticTile => + staticTile.Z == z && (TileData.ItemTable[staticTile.ID & TileData.MaxItemValue].Flags & TileFlag.Wet) != 0); } public virtual Map GetSpawnMap() => Map; @@ -977,11 +931,7 @@ namespace Server.Mobiles public InternalTimer(Spawner spawner, TimeSpan delay) : base(delay) { - if (spawner.IsFull) - Priority = TimerPriority.FiveSeconds; - else - Priority = TimerPriority.OneSecond; - + Priority = spawner.IsFull ? TimerPriority.FiveSeconds : TimerPriority.OneSecond; m_Spawner = spawner; } @@ -1150,41 +1100,11 @@ namespace Server.Mobiles bool remove = false; if (e is Item item) - { - if (item.Deleted || item.RootParent is Mobile || item.IsLockedDown || item.IsSecure || - item.Spawner == null) - remove = true; - } + remove |= item.Deleted || item.RootParent is Mobile || item.IsLockedDown || item.IsSecure || item.Spawner == null; else if (e is Mobile m) - { - if (m.Deleted) - { - remove = true; - } - else if (m is BaseCreature c) - { - if (c.Controlled || c.IsStabled) - remove = true; -/* - else if ( c.Combatant == null && ( c.GetDistanceToSqrt( Location ) > (c.RangeHome * 4) ) ) - { - //m_Spawned[i].Delete(); - m_Spawned.RemoveAt( i ); - --i; - c.Delete(); - remove = true; - } -*/ - } - else if (m.Spawner == null) - { - remove = true; - } - } + remove |= m.Deleted || m.Spawner == null || m is BaseCreature c && (c.Controlled || c.IsStabled); else - { remove = true; - } if (remove) { diff --git a/Projects/Scripts/Engines/Spawner/SpawnerGump.cs b/Projects/Scripts/Engines/Spawner/SpawnerGump.cs index 7be5f298d..18852a81f 100644 --- a/Projects/Scripts/Engines/Spawner/SpawnerGump.cs +++ b/Projects/Scripts/Engines/Spawner/SpawnerGump.cs @@ -203,7 +203,7 @@ namespace Server.Mobiles spawner.Start(); } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (m_Spawner.Deleted) return; @@ -246,7 +246,7 @@ namespace Server.Mobiles } case 2: //Okay { - CreateArray(info, state.Mobile, m_Spawner); + CreateArray(info, sender.Mobile, m_Spawner); return; } case 3: @@ -261,7 +261,7 @@ namespace Server.Mobiles } case 5: { - CreateArray(info, state.Mobile, m_Spawner); + CreateArray(info, sender.Mobile, m_Spawner); break; } } @@ -282,15 +282,15 @@ namespace Server.Mobiles m_Spawner.RemoveSpawn(entryindex); } - CreateArray(info, state.Mobile, m_Spawner); + CreateArray(info, sender.Mobile, m_Spawner); break; } } if (m_Entry != null && m_Spawner.Entries?.Contains(m_Entry) == true) - state.Mobile.SendGump(new SpawnerGump(m_Spawner, m_Entry, m_Page)); + sender.Mobile.SendGump(new SpawnerGump(m_Spawner, m_Entry, m_Page)); else - state.Mobile.SendGump(new SpawnerGump(m_Spawner, null, m_Page)); + sender.Mobile.SendGump(new SpawnerGump(m_Spawner, null, m_Page)); } } } diff --git a/Projects/Scripts/Engines/VeteranRewards/Character Statue Maker/CharacterStatue.cs b/Projects/Scripts/Engines/VeteranRewards/Character Statue Maker/CharacterStatue.cs index 98650495c..840eb354f 100644 --- a/Projects/Scripts/Engines/VeteranRewards/Character Statue Maker/CharacterStatue.cs +++ b/Projects/Scripts/Engines/VeteranRewards/Character Statue Maker/CharacterStatue.cs @@ -185,7 +185,7 @@ namespace Server.Mobiles public void OnRequestedAnimation(Mobile from) { - from.Send(new UpdateStatueAnimation(this, 1, m_Animation, m_Frames)); + StatuePackets.SendUpdateStatueAnimation(from.NetState, Serial, 1, m_Animation, m_Frames); } public override void OnAosSingleClick(Mobile from) @@ -364,22 +364,14 @@ namespace Server.Mobiles { ProcessDelta(); - Packet p = null; - IPooledEnumerable eable = Map.GetClientsInRange(Location); foreach (NetState state in eable) { state.Mobile.ProcessDelta(); - - if (p == null) - p = Packet.Acquire(new UpdateStatueAnimation(this, 1, m_Animation, m_Frames)); - - state.Send(p); + StatuePackets.SendUpdateStatueAnimation(state, Serial, 1, m_Animation, m_Frames); } - Packet.Release(p); - eable.Free(); } } @@ -424,9 +416,8 @@ namespace Server.Mobiles { } - public override int LabelNumber - { - get + public override int LabelNumber => + (Statue?.StatueType ?? m_Type) switch { StatueType t = m_Type; @@ -448,13 +439,7 @@ namespace Server.Mobiles [CommandProperty(AccessLevel.GameMaster)] public StatueType StatueType { - get - { - if (Statue != null) - return Statue.StatueType; - - return m_Type; - } + get => Statue?.StatueType ?? m_Type; set => m_Type = value; } @@ -611,18 +596,11 @@ namespace Server.Mobiles from.SendGump(new CharacterStatueGump(m_Maker, statue, from)); } else if (result == AddonFitResult.Blocked) - { from.SendLocalizedMessage(500269); // You cannot build that there. - } else if (result == AddonFitResult.NotInHouse) - { from.SendLocalizedMessage( 1076192); // Statues can only be placed in houses where you are the owner or co-owner. - } - else if (result == AddonFitResult.DoorTooClose) - { - from.SendLocalizedMessage(500271); // You cannot build near the door. - } + else if (result == AddonFitResult.DoorTooClose) from.SendLocalizedMessage(500271); // You cannot build near the door. } else { @@ -630,15 +608,9 @@ namespace Server.Mobiles } } - public static AddonFitResult CouldFit(Point3D p, Map map, Mobile from, ref BaseHouse house) - { - if (!map.CanFit(p.X, p.Y, p.Z, 20, true)) - return AddonFitResult.Blocked; - if (!BaseAddon.CheckHouse(from, p, map, 20, ref house)) - return AddonFitResult.NotInHouse; - - return CheckDoors(p, 20, house); - } + public static AddonFitResult CouldFit(Point3D p, Map map, Mobile from, ref BaseHouse house) => + !map.CanFit(p.X, p.Y, p.Z, 20, true) ? AddonFitResult.Blocked : + !BaseAddon.CheckHouse(from, p, map, 20, ref house) ? AddonFitResult.NotInHouse : CheckDoors(p, 20, house); public static AddonFitResult CheckDoors(Point3D p, int height, BaseHouse house) { diff --git a/Projects/Scripts/Engines/VeteranRewards/Character Statue Maker/Gumps/CharacterStatueGump.cs b/Projects/Scripts/Engines/VeteranRewards/Character Statue Maker/Gumps/CharacterStatueGump.cs index 48e429d14..60459b340 100644 --- a/Projects/Scripts/Engines/VeteranRewards/Character Statue Maker/Gumps/CharacterStatueGump.cs +++ b/Projects/Scripts/Engines/VeteranRewards/Character Statue Maker/Gumps/CharacterStatueGump.cs @@ -66,9 +66,8 @@ namespace Server.Gumps } } - private int GetMaterialNumber(StatueType type, StatueMaterial material) - { - switch (material) + private int GetMaterialNumber(StatueType type, StatueMaterial material) => + material switch { case StatueMaterial.Antique: @@ -126,7 +125,7 @@ namespace Server.Gumps m_Maker?.Delete(); - m_Statue.Sculpt(state.Mobile); + m_Statue.Sculpt(sender.Mobile); } else if (info.ButtonID == (int)Buttons.PosePrev) { @@ -174,11 +173,11 @@ namespace Server.Gumps } else // Close { - sendGump = !m_Statue.Demolish(state.Mobile); + sendGump = !m_Statue.Demolish(sender.Mobile); } if (sendGump) - state.Mobile.SendGump(new CharacterStatueGump(m_Maker, m_Statue, m_Owner)); + sender.Mobile.SendGump(new CharacterStatueGump(m_Maker, m_Statue, m_Owner)); } private enum Buttons diff --git a/Projects/Scripts/Engines/VeteranRewards/Character Statue Maker/Packets.cs b/Projects/Scripts/Engines/VeteranRewards/Character Statue Maker/Packets.cs index b13fd47b9..af457b1d9 100644 --- a/Projects/Scripts/Engines/VeteranRewards/Character Statue Maker/Packets.cs +++ b/Projects/Scripts/Engines/VeteranRewards/Character Statue Maker/Packets.cs @@ -1,20 +1,25 @@ +using Server.Buffers; + namespace Server.Network { - public class UpdateStatueAnimation : Packet + public static class StatuePackets { - public UpdateStatueAnimation(Mobile m, int status, int animation, int frame) : base(0xBF, 17) + public static void SendUpdateStatueAnimation(NetState ns, Serial m, int status, int animation, int frame) { - m_Stream.Write((short)0x11); - m_Stream.Write((short)0x19); - m_Stream.Write((byte)0x5); - m_Stream.Write(m.Serial); - m_Stream.Write((byte)0); - m_Stream.Write((byte)0xFF); - m_Stream.Write((byte)status); - m_Stream.Write((byte)0); - m_Stream.Write((byte)animation); - m_Stream.Write((byte)0); - m_Stream.Write((byte)frame); + if (ns == null) + return; + + SpanWriter writer = new SpanWriter(stackalloc byte[17]); + writer.Write((byte)0xBF); // Extended Packet ID + writer.Write((short)17); // Dynamic Length + + writer.Write((short)0x19); + writer.Write((byte)0x5); + writer.Write(m); + writer.Write((short)0xFF); + writer.Write((byte)status); + writer.Write((short)animation); + writer.Write((short)frame); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Engines/VeteranRewards/RewardOptionGump.cs b/Projects/Scripts/Engines/VeteranRewards/RewardOptionGump.cs index 4bdd1b2c9..7c10fd811 100644 --- a/Projects/Scripts/Engines/VeteranRewards/RewardOptionGump.cs +++ b/Projects/Scripts/Engines/VeteranRewards/RewardOptionGump.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using Server.Network; namespace Server.Gumps @@ -51,17 +52,7 @@ namespace Server.Gumps m_Option.OnOptionSelected(sender.Mobile, info.ButtonID); } - private bool Contains(int chosen) - { - if (m_Options == null) - return false; - - foreach (RewardOption option in m_Options) - if (option.ID == chosen) - return true; - - return false; - } + private bool Contains(int chosen) => m_Options?.Any(option => option.ID == chosen) == true; } public class RewardOption diff --git a/Projects/Scripts/Engines/Virtues/Honor.cs b/Projects/Scripts/Engines/Virtues/Honor.cs index 576d0d42d..b84c10510 100644 --- a/Projects/Scripts/Engines/Virtues/Honor.cs +++ b/Projects/Scripts/Engines/Virtues/Honor.cs @@ -342,9 +342,9 @@ namespace Server targetFame / 100.0 * (m_HonorDamage / m_TotalDamage); //Initial honor gain is 100th of the monsters honor if (m_HonorDamage == m_TotalDamage && m_FirstHit == FirstHit.Granted) - dGain = dGain * 1.5; //honor gain is increased alot more if the combat was fully honorable + dGain *= 1.5; //honor gain is increased alot more if the combat was fully honorable else - dGain = dGain * 0.9; + dGain *= 0.9; int gain = Math.Min((int)dGain, 200); diff --git a/Projects/Scripts/Engines/Virtues/VirtueGump.cs b/Projects/Scripts/Engines/Virtues/VirtueGump.cs index 9f9780989..3338479cb 100644 --- a/Projects/Scripts/Engines/Virtues/VirtueGump.cs +++ b/Projects/Scripts/Engines/Virtues/VirtueGump.cs @@ -36,14 +36,14 @@ namespace Server AddPage(1); - Add(new InternalEntry(61, 71, 108, GetHueFor(0))); // Humility - Add(new InternalEntry(123, 46, 112, GetHueFor(4))); // Valor - Add(new InternalEntry(187, 70, 107, GetHueFor(5))); // Honor - Add(new InternalEntry(35, 135, 110, GetHueFor(1))); // Sacrifice - Add(new InternalEntry(211, 133, 105, GetHueFor(2))); // Compassion - Add(new InternalEntry(61, 195, 111, GetHueFor(3))); // Spiritulaity - Add(new InternalEntry(186, 195, 109, GetHueFor(6))); // Justice - Add(new InternalEntry(121, 221, 106, GetHueFor(7))); // Honesty + Add(new GumpImage(61, 71, 108, GetHueFor(0), "VirtueGumpItem")); // Humility + Add(new GumpImage(123, 46, 112, GetHueFor(4), "VirtueGumpItem")); // Valor + Add(new GumpImage(187, 70, 107, GetHueFor(5), "VirtueGumpItem")); // Honor + Add(new GumpImage(35, 135, 110, GetHueFor(1), "VirtueGumpItem")); // Sacrifice + Add(new GumpImage(211, 133, 105, GetHueFor(2), "VirtueGumpItem")); // Compassion + Add(new GumpImage(61, 195, 111, GetHueFor(3), "VirtueGumpItem")); // Spiritulaity + Add(new GumpImage(186, 195, 109, GetHueFor(6), "VirtueGumpItem")); // Justice + Add(new GumpImage(121, 221, 106, GetHueFor(7), "VirtueGumpItem")); // Honesty if (m_Beholder == m_Beheld) { @@ -147,7 +147,7 @@ namespace Server return m_Table[index * 3 + vl]; } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (info.ButtonID == 1 && m_Beholder == m_Beheld) m_Beholder.SendGump(new VirtueStatusGump(m_Beholder)); diff --git a/Projects/Scripts/Engines/Virtues/VirtueInfoGump.cs b/Projects/Scripts/Engines/Virtues/VirtueInfoGump.cs index f642321a9..71aa4e4ab 100644 --- a/Projects/Scripts/Engines/Virtues/VirtueInfoGump.cs +++ b/Projects/Scripts/Engines/Virtues/VirtueInfoGump.cs @@ -79,7 +79,7 @@ namespace Server AddHtmlLocalized(83, 275, 400, 40, webPage == null ? 1052055 : 1052052); // This virtue is not yet defined. OR -click to learn more (opens webpage) } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { switch (info.ButtonID) { @@ -88,7 +88,7 @@ namespace Server m_Beholder.SendGump(new VirtueInfoGump(m_Beholder, m_Virtue, m_Desc, m_Page)); if (m_Page != null) - state.Send(new LaunchBrowser(m_Page)); //No message about web browser starting on OSI + Packets.SendLaunchBrowser(sender, m_Page); break; } case 2: diff --git a/Projects/Scripts/Engines/Virtues/VirtueStatusGump.cs b/Projects/Scripts/Engines/Virtues/VirtueStatusGump.cs index 911cc7774..f1de0b00e 100644 --- a/Projects/Scripts/Engines/Virtues/VirtueStatusGump.cs +++ b/Projects/Scripts/Engines/Virtues/VirtueStatusGump.cs @@ -47,7 +47,7 @@ namespace Server AddButton(280, 43, 4014, 4014, 9); } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { switch (info.ButtonID) { diff --git a/Projects/Scripts/Gumps/AdminGump.cs b/Projects/Scripts/Gumps/AdminGump.cs index fbc3db4b3..81deef6ad 100644 --- a/Projects/Scripts/Gumps/AdminGump.cs +++ b/Projects/Scripts/Gumps/AdminGump.cs @@ -16,7 +16,7 @@ namespace Server.Gumps { public enum AdminGumpPage { - Information_General, + Information_General = 0, Information_Perf, Administer, Clients, @@ -39,7 +39,8 @@ namespace Server.Gumps AccountDetails_Tags, AccountDetails_ChangePassword, AccountDetails_ChangeAccess, - FirewallInfo + FirewallInfo, + Invalid = -1 } public class AdminGump : Gump @@ -587,8 +588,7 @@ namespace Server.Gumps } case AdminGumpPage.Accounts: { - if (m_List == null) - m_List = new List(); + m_List ??= new List(); List rads = state as List; @@ -1182,11 +1182,10 @@ namespace Server.Gumps if (totalBytes > 1000000) return $"{(double)totalBytes / 1048576:F1} MB"; - if (totalBytes > 1000) - return $"{(double)totalBytes / 1024:F1} KB"; - - return $"{totalBytes} Bytes"; - } + public static string FormatByteAmount(long totalBytes) => + totalBytes > 1000000000 ? $"{(double)totalBytes / 1073741824:F1} GB" : + totalBytes > 1000000 ? $"{(double)totalBytes / 1048576:F1} MB" : + totalBytes > 1000 ? $"{(double)totalBytes / 1024:F1} KB" : $"{totalBytes} Bytes"; public static void Initialize() { @@ -1525,7 +1524,7 @@ namespace Server.Gumps { IPAddress[] ips = a.LoginIPs; - if (ips.Length != 0 && ip == ips[0] && AccountHandler.IPTable.ContainsKey(ips[0])) + if (ips.Length != 0 && ip.Equals(ips[0]) && AccountHandler.IPTable.ContainsKey(ips[0])) --AccountHandler.IPTable[ip]; List newList = new List(ips); @@ -1608,30 +1607,19 @@ namespace Server.Gumps { case 0: { - AdminGumpPage page; - - switch (index) + AdminGumpPage page = index switch { - case 0: - page = AdminGumpPage.Information_General; - break; - case 1: - page = AdminGumpPage.Administer; - break; - case 2: - page = AdminGumpPage.Clients; - break; - case 3: - page = AdminGumpPage.Accounts; - break; - case 4: - page = AdminGumpPage.Firewall; - break; - case 5: - page = AdminGumpPage.Information_Perf; - break; - default: return; - } + 0 => AdminGumpPage.Information_General, + 1 => AdminGumpPage.Administer, + 2 => AdminGumpPage.Clients, + 3 => AdminGumpPage.Accounts, + 4 => AdminGumpPage.Firewall, + 5 => AdminGumpPage.Information_Perf, + _ => AdminGumpPage.Invalid, + }; + + if (page == AdminGumpPage.Invalid) + return; from.SendGump(new AdminGump(from, page)); break; @@ -1951,12 +1939,7 @@ namespace Server.Gumps hasAccess = true; else for (int j = 0; !hasAccess && j < a.Length; ++j) - { - Mobile m = a[j]; - - if (m?.AccessLevel >= level) - hasAccess = true; - } + hasAccess |= a[j]?.AccessLevel >= level; if (!hasAccess) { @@ -2500,11 +2483,7 @@ namespace Server.Gumps } case 31: // View all inactive accounts { - List results = new List(); - - foreach (Account acct in Accounts.GetAccounts()) - if (acct.Inactive) - results.Add(acct); + List results = Accounts.GetAccounts().Cast().Where(acct => acct.Inactive).Cast().ToList(); if (results.Count == 1) from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Information, 0, null, @@ -2517,11 +2496,7 @@ namespace Server.Gumps } case 32: // View all banned accounts { - List results = new List(); - - foreach (Account acct in Accounts.GetAccounts()) - if (acct.Banned) - results.Add(acct); + List results = Accounts.GetAccounts().Cast().Where(acct => acct.Banned).Cast().ToList(); if (results.Count == 1) from.SendGump(new AdminGump(from, AdminGumpPage.AccountDetails_Information, 0, null, @@ -2552,8 +2527,7 @@ namespace Server.Gumps bool hasHouse = false; for (int i = 0; i < acct.Length && !hasHouse; ++i) - if (acct[i] != null && BaseHouse.HasHouse(acct[i])) - hasHouse = true; + hasHouse |= acct[i] != null && BaseHouse.HasHouse(acct[i]); if (!hasHouse) newRads.Add(acct); @@ -2972,8 +2946,7 @@ namespace Server.Gumps if (check.AccessLevel > accessLevel) accessLevel = check.AccessLevel; - if (check.NetState != null) - online = true; + online |= check.NetState != null; } } diff --git a/Projects/Scripts/Gumps/BaseConfirmGump.cs b/Projects/Scripts/Gumps/BaseConfirmGump.cs index eeb878c96..f0825c745 100644 --- a/Projects/Scripts/Gumps/BaseConfirmGump.cs +++ b/Projects/Scripts/Gumps/BaseConfirmGump.cs @@ -50,14 +50,14 @@ namespace Server.Gumps public virtual int LabelNumber // Are you sure you wish to select this? => 1074975; - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (info.ButtonID == (int)Buttons.Confirm) { if (info.IsSwitched((int)Buttons.Break)) - Confirm(state.Mobile); + Confirm(sender.Mobile); else - Refuse(state.Mobile); + Refuse(sender.Mobile); } } diff --git a/Projects/Scripts/Gumps/CategorizedAddGump.cs b/Projects/Scripts/Gumps/CategorizedAddGump.cs index f3e49ed66..cd796494c 100644 --- a/Projects/Scripts/Gumps/CategorizedAddGump.cs +++ b/Projects/Scripts/Gumps/CategorizedAddGump.cs @@ -110,7 +110,7 @@ namespace Server.Gumps public override string Caption => Title; - public static CAGCategory Root => m_Root ?? (m_Root = Load("Data/objects.xml")); + public static CAGCategory Root => m_Root ??= Load("Data/objects.xml"); public override void OnClick(Mobile from, int page) { @@ -184,7 +184,8 @@ namespace Server.Gumps public static readonly int NextButtonID1 = PropsConfig.NextButtonID1; public static readonly int NextButtonID2 = PropsConfig.NextButtonID2; - private static bool PrevLabel = false, NextLabel = false; + private static bool PrevLabel = false; + private static bool NextLabel = false; private static readonly int PrevLabelOffsetX = PrevWidth + 1; private static readonly int PrevLabelOffsetY = 0; @@ -333,7 +334,7 @@ namespace Server.Gumps } } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { Mobile from = m_Owner; diff --git a/Projects/Scripts/Gumps/ClientGump.cs b/Projects/Scripts/Gumps/ClientGump.cs index 357851480..df05ab3b9 100644 --- a/Projects/Scripts/Gumps/ClientGump.cs +++ b/Projects/Scripts/Gumps/ClientGump.cs @@ -128,13 +128,13 @@ namespace Server.Gumps to.SendGump(new ClientGump(to, m_State, te == null ? "" : te.Text)); } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (m_State == null) return; Mobile focus = m_State.Mobile; - Mobile from = state.Mobile; + Mobile from = sender.Mobile; if (focus == null) { diff --git a/Projects/Scripts/Gumps/CommentsGump.cs b/Projects/Scripts/Gumps/CommentsGump.cs index f884de9b6..3c7928d89 100644 --- a/Projects/Scripts/Gumps/CommentsGump.cs +++ b/Projects/Scripts/Gumps/CommentsGump.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; using Server.Accounting; using Server.Network; -using Server.Prompts; using Server.Targeting; namespace Server.Gumps @@ -78,12 +77,12 @@ namespace Server.Gumps from.SendGump(new CommentsGump((Account)m.Account)); } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (info.ButtonID == 0x7F) { - state.Mobile.SendMessage("Enter the text for the account comment (or press [Esc] to cancel):"); - state.Mobile.Prompt = new CommentPrompt(m_Acct); + sender.Mobile.SendMessage("Enter the text for the account comment (or press [Esc] to cancel):"); + sender.Mobile.Prompt = new CommentPrompt(m_Acct); } } diff --git a/Projects/Scripts/Gumps/ConfirmHouseResize.cs b/Projects/Scripts/Gumps/ConfirmHouseResize.cs index c572e08e6..a3fc0fd20 100644 --- a/Projects/Scripts/Gumps/ConfirmHouseResize.cs +++ b/Projects/Scripts/Gumps/ConfirmHouseResize.cs @@ -46,7 +46,7 @@ namespace Server.Gumps AddHtmlLocalized(240, 250, 170, 20, 1011012, 0x7FFF); // CANCEL } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (info.ButtonID == 1 && !m_House.Deleted) { @@ -100,7 +100,7 @@ namespace Server.Gumps } else { - Item toGive = null; + Item toGive; if (m_House.IsAosRules) { diff --git a/Projects/Scripts/Gumps/Go/GoGump.cs b/Projects/Scripts/Gumps/Go/GoGump.cs index ec26774c9..3ef2fff1f 100644 --- a/Projects/Scripts/Gumps/Go/GoGump.cs +++ b/Projects/Scripts/Gumps/Go/GoGump.cs @@ -187,9 +187,9 @@ namespace Server.Gumps from.SendGump(new GoGump(0, from, tree, branch)); } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { - Mobile from = state.Mobile; + Mobile from = sender.Mobile; switch (info.ButtonID) { diff --git a/Projects/Scripts/Gumps/Guilds/DeclareFealtyGump.cs b/Projects/Scripts/Gumps/Guilds/DeclareFealtyGump.cs index b6ade1cfa..f20bc3225 100644 --- a/Projects/Scripts/Gumps/Guilds/DeclareFealtyGump.cs +++ b/Projects/Scripts/Gumps/Guilds/DeclareFealtyGump.cs @@ -20,7 +20,7 @@ namespace Server.Gumps AddHtmlLocalized(335, 400, 100, 35, 1011012); // CANCEL } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (GuildGump.BadMember(m_Mobile, m_Guild)) return; @@ -38,7 +38,7 @@ namespace Server.Gumps Mobile m = m_List[index]; if (m?.Deleted == false) - state.Mobile.GuildFealty = m; + sender.Mobile.GuildFealty = m; } } } diff --git a/Projects/Scripts/Gumps/Guilds/GrantGuildTitleGump.cs b/Projects/Scripts/Gumps/Guilds/GrantGuildTitleGump.cs index 1af757d3b..c49d5123a 100644 --- a/Projects/Scripts/Gumps/Guilds/GrantGuildTitleGump.cs +++ b/Projects/Scripts/Gumps/Guilds/GrantGuildTitleGump.cs @@ -20,7 +20,7 @@ namespace Server.Gumps AddHtmlLocalized(335, 400, 100, 35, 1011012); // CANCEL } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (GuildGump.BadLeader(m_Mobile, m_Guild)) return; diff --git a/Projects/Scripts/Gumps/Guilds/GuildAbbrvPrompt.cs b/Projects/Scripts/Gumps/Guilds/GuildAbbrvPrompt.cs index f0f94a1c0..24c5cdda1 100644 --- a/Projects/Scripts/Gumps/Guilds/GuildAbbrvPrompt.cs +++ b/Projects/Scripts/Gumps/Guilds/GuildAbbrvPrompt.cs @@ -1,5 +1,4 @@ using Server.Guilds; -using Server.Prompts; namespace Server.Gumps { diff --git a/Projects/Scripts/Gumps/Guilds/GuildAcceptWarGump.cs b/Projects/Scripts/Gumps/Guilds/GuildAcceptWarGump.cs index 021acd651..61a26ce31 100644 --- a/Projects/Scripts/Gumps/Guilds/GuildAcceptWarGump.cs +++ b/Projects/Scripts/Gumps/Guilds/GuildAcceptWarGump.cs @@ -20,7 +20,7 @@ namespace Server.Gumps AddHtmlLocalized(335, 400, 100, 35, 1011012); // CANCEL } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (GuildGump.BadLeader(m_Mobile, m_Guild)) return; diff --git a/Projects/Scripts/Gumps/Guilds/GuildAdminCandidatesGump.cs b/Projects/Scripts/Gumps/Guilds/GuildAdminCandidatesGump.cs index 018f390ef..402f4b0fc 100644 --- a/Projects/Scripts/Gumps/Guilds/GuildAdminCandidatesGump.cs +++ b/Projects/Scripts/Gumps/Guilds/GuildAdminCandidatesGump.cs @@ -21,7 +21,7 @@ namespace Server.Gumps AddHtmlLocalized(335, 400, 100, 35, 1013077); // Refuse } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (GuildGump.BadLeader(m_Mobile, m_Guild)) return; diff --git a/Projects/Scripts/Gumps/Guilds/GuildCandidatesGump.cs b/Projects/Scripts/Gumps/Guilds/GuildCandidatesGump.cs index 60ce45109..f5a032390 100644 --- a/Projects/Scripts/Gumps/Guilds/GuildCandidatesGump.cs +++ b/Projects/Scripts/Gumps/Guilds/GuildCandidatesGump.cs @@ -17,7 +17,7 @@ namespace Server.Gumps AddHtmlLocalized(55, 400, 300, 35, 1011120); // Return to the main menu. } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (GuildGump.BadMember(m_Mobile, m_Guild)) return; diff --git a/Projects/Scripts/Gumps/Guilds/GuildChangeTypeGump.cs b/Projects/Scripts/Gumps/Guilds/GuildChangeTypeGump.cs index c5eb72a9a..54d5df27b 100644 --- a/Projects/Scripts/Gumps/Guilds/GuildChangeTypeGump.cs +++ b/Projects/Scripts/Gumps/Guilds/GuildChangeTypeGump.cs @@ -41,7 +41,7 @@ namespace Server.Gumps AddHtmlLocalized(335, 360, 150, 30, 1011012); // CANCEL } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (Guild.NewGuildSystem && !BaseGuildGump.IsLeader(m_Mobile, m_Guild) || !Guild.NewGuildSystem && GuildGump.BadLeader(m_Mobile, m_Guild)) diff --git a/Projects/Scripts/Gumps/Guilds/GuildCharterGump.cs b/Projects/Scripts/Gumps/Guilds/GuildCharterGump.cs index 16662a04f..a5fe1e55c 100644 --- a/Projects/Scripts/Gumps/Guilds/GuildCharterGump.cs +++ b/Projects/Scripts/Gumps/Guilds/GuildCharterGump.cs @@ -41,7 +41,7 @@ namespace Server.Gumps AddHtml(55, 220, 300, 20, website); } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (GuildGump.BadMember(m_Mobile, m_Guild)) return; diff --git a/Projects/Scripts/Gumps/Guilds/GuildCharterPrompt.cs b/Projects/Scripts/Gumps/Guilds/GuildCharterPrompt.cs index e3f265ba1..e158e8b60 100644 --- a/Projects/Scripts/Gumps/Guilds/GuildCharterPrompt.cs +++ b/Projects/Scripts/Gumps/Guilds/GuildCharterPrompt.cs @@ -1,5 +1,4 @@ using Server.Guilds; -using Server.Prompts; namespace Server.Gumps { diff --git a/Projects/Scripts/Gumps/Guilds/GuildDeclarePeaceGump.cs b/Projects/Scripts/Gumps/Guilds/GuildDeclarePeaceGump.cs index 00370e69d..fc18d39ac 100644 --- a/Projects/Scripts/Gumps/Guilds/GuildDeclarePeaceGump.cs +++ b/Projects/Scripts/Gumps/Guilds/GuildDeclarePeaceGump.cs @@ -20,7 +20,7 @@ namespace Server.Gumps AddHtmlLocalized(335, 400, 100, 35, 1011012); // CANCEL } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (GuildGump.BadLeader(m_Mobile, m_Guild)) return; diff --git a/Projects/Scripts/Gumps/Guilds/GuildDeclareWarGump.cs b/Projects/Scripts/Gumps/Guilds/GuildDeclareWarGump.cs index c60b6096c..3bb53678a 100644 --- a/Projects/Scripts/Gumps/Guilds/GuildDeclareWarGump.cs +++ b/Projects/Scripts/Gumps/Guilds/GuildDeclareWarGump.cs @@ -23,7 +23,7 @@ namespace Server.Gumps AddHtmlLocalized(335, 400, 100, 35, 1011012); // CANCEL } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (GuildGump.BadLeader(m_Mobile, m_Guild)) return; diff --git a/Projects/Scripts/Gumps/Guilds/GuildDeclareWarPrompt.cs b/Projects/Scripts/Gumps/Guilds/GuildDeclareWarPrompt.cs index 9b17dbaa0..8a18d46c6 100644 --- a/Projects/Scripts/Gumps/Guilds/GuildDeclareWarPrompt.cs +++ b/Projects/Scripts/Gumps/Guilds/GuildDeclareWarPrompt.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using Server.Guilds; -using Server.Prompts; namespace Server.Gumps { diff --git a/Projects/Scripts/Gumps/Guilds/GuildDismissGump.cs b/Projects/Scripts/Gumps/Guilds/GuildDismissGump.cs index f86a03209..5ff961a47 100644 --- a/Projects/Scripts/Gumps/Guilds/GuildDismissGump.cs +++ b/Projects/Scripts/Gumps/Guilds/GuildDismissGump.cs @@ -20,7 +20,7 @@ namespace Server.Gumps AddHtmlLocalized(335, 400, 100, 35, 1011012); // CANCEL } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (GuildGump.BadLeader(m_Mobile, m_Guild)) return; diff --git a/Projects/Scripts/Gumps/Guilds/GuildNamePrompt.cs b/Projects/Scripts/Gumps/Guilds/GuildNamePrompt.cs index 292a23b72..59a5ddddd 100644 --- a/Projects/Scripts/Gumps/Guilds/GuildNamePrompt.cs +++ b/Projects/Scripts/Gumps/Guilds/GuildNamePrompt.cs @@ -1,5 +1,4 @@ using Server.Guilds; -using Server.Prompts; namespace Server.Gumps { diff --git a/Projects/Scripts/Gumps/Guilds/GuildRejectWarGump.cs b/Projects/Scripts/Gumps/Guilds/GuildRejectWarGump.cs index 16761e975..5a15e9c85 100644 --- a/Projects/Scripts/Gumps/Guilds/GuildRejectWarGump.cs +++ b/Projects/Scripts/Gumps/Guilds/GuildRejectWarGump.cs @@ -20,7 +20,7 @@ namespace Server.Gumps AddHtmlLocalized(335, 400, 100, 35, 1011012); // CANCEL } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (GuildGump.BadLeader(m_Mobile, m_Guild)) return; diff --git a/Projects/Scripts/Gumps/Guilds/GuildRescindDeclarationGump.cs b/Projects/Scripts/Gumps/Guilds/GuildRescindDeclarationGump.cs index 2a648b5d4..866cb889e 100644 --- a/Projects/Scripts/Gumps/Guilds/GuildRescindDeclarationGump.cs +++ b/Projects/Scripts/Gumps/Guilds/GuildRescindDeclarationGump.cs @@ -20,7 +20,7 @@ namespace Server.Gumps AddHtmlLocalized(335, 400, 100, 35, 1011012); // CANCEL } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (GuildGump.BadLeader(m_Mobile, m_Guild)) return; diff --git a/Projects/Scripts/Gumps/Guilds/GuildRosterGump.cs b/Projects/Scripts/Gumps/Guilds/GuildRosterGump.cs index 5588678a3..36aa21b66 100644 --- a/Projects/Scripts/Gumps/Guilds/GuildRosterGump.cs +++ b/Projects/Scripts/Gumps/Guilds/GuildRosterGump.cs @@ -17,7 +17,7 @@ namespace Server.Gumps AddHtmlLocalized(55, 400, 300, 35, 1011120); // Return to the main menu. } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (GuildGump.BadMember(m_Mobile, m_Guild)) return; diff --git a/Projects/Scripts/Gumps/Guilds/GuildTitlePrompt.cs b/Projects/Scripts/Gumps/Guilds/GuildTitlePrompt.cs index 35e4655d0..a098d9eeb 100644 --- a/Projects/Scripts/Gumps/Guilds/GuildTitlePrompt.cs +++ b/Projects/Scripts/Gumps/Guilds/GuildTitlePrompt.cs @@ -1,5 +1,4 @@ using Server.Guilds; -using Server.Prompts; namespace Server.Gumps { diff --git a/Projects/Scripts/Gumps/Guilds/GuildWarAdminGump.cs b/Projects/Scripts/Gumps/Guilds/GuildWarAdminGump.cs index 64d284013..9b0dcba48 100644 --- a/Projects/Scripts/Gumps/Guilds/GuildWarAdminGump.cs +++ b/Projects/Scripts/Gumps/Guilds/GuildWarAdminGump.cs @@ -63,7 +63,7 @@ namespace Server.Gumps AddHtmlLocalized(55, 400, 400, 35, 1011104); // Return to the previous menu. } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (GuildGump.BadLeader(m_Mobile, m_Guild)) return; diff --git a/Projects/Scripts/Gumps/Guilds/GuildWarGump.cs b/Projects/Scripts/Gumps/Guilds/GuildWarGump.cs index d2304dc45..a56f1f1aa 100644 --- a/Projects/Scripts/Gumps/Guilds/GuildWarGump.cs +++ b/Projects/Scripts/Gumps/Guilds/GuildWarGump.cs @@ -86,7 +86,7 @@ namespace Server.Gumps } } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (GuildGump.BadMember(m_Mobile, m_Guild)) return; diff --git a/Projects/Scripts/Gumps/Guilds/GuildWebsitePrompt.cs b/Projects/Scripts/Gumps/Guilds/GuildWebsitePrompt.cs index 16aae7a12..487901fc9 100644 --- a/Projects/Scripts/Gumps/Guilds/GuildWebsitePrompt.cs +++ b/Projects/Scripts/Gumps/Guilds/GuildWebsitePrompt.cs @@ -1,5 +1,4 @@ using Server.Guilds; -using Server.Prompts; namespace Server.Gumps { diff --git a/Projects/Scripts/Gumps/Guilds/GuildmasterGump.cs b/Projects/Scripts/Gumps/Guilds/GuildmasterGump.cs index 29a7be63a..ff183da60 100644 --- a/Projects/Scripts/Gumps/Guilds/GuildmasterGump.cs +++ b/Projects/Scripts/Gumps/Guilds/GuildmasterGump.cs @@ -82,7 +82,7 @@ namespace Server.Gumps AddHtmlLocalized(335, 360, 100, 30, 1011441); // EXIT } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (GuildGump.BadLeader(m_Mobile, m_Guild)) return; diff --git a/Projects/Scripts/Gumps/Guilds/New Guild System/BaseGuildGump.cs b/Projects/Scripts/Gumps/Guilds/New Guild System/BaseGuildGump.cs index bab0308bf..408630817 100644 --- a/Projects/Scripts/Gumps/Guilds/New Guild System/BaseGuildGump.cs +++ b/Projects/Scripts/Gumps/Guilds/New Guild System/BaseGuildGump.cs @@ -1,3 +1,4 @@ +using System.Linq; using Server.Gumps; using Server.Misc; using Server.Mobiles; @@ -40,9 +41,7 @@ namespace Server.Guilds public override void OnResponse(NetState sender, RelayInfo info) { - PlayerMobile pm = sender.Mobile as PlayerMobile; - - if (!IsMember(pm, guild)) + if (!(sender.Mobile is PlayerMobile pm &&IsMember(pm, guild))) return; switch (info.ButtonID) @@ -85,30 +84,12 @@ namespace Server.Guilds s = s.ToLower(); - for (int i = 0; i < s.Length; ++i) - { - char c = s[i]; - - if ((c < 'a' || c > 'z') && (c < '0' || c > '9')) - { - bool except = false; - - for (int j = 0; !except && j < exceptions.Length; j++) - if (c == exceptions[j]) - except = true; - - if (!except) - return false; - } - } + if (s.Any(c => (c < 'a' || c > 'z') && (c < '0' || c > '9') && exceptions.All(exception => exception != c))) + return false; string[] disallowed = ProfanityProtection.Disallowed; - for (int i = 0; i < disallowed.Length; i++) - if (s.IndexOf(disallowed[i]) != -1) - return false; - - return true; + return disallowed.All(t => s.IndexOf(t) == -1); } public void AddHtmlText(int x, int y, int width, int height, TextDefinition text, bool back, bool scroll) diff --git a/Projects/Scripts/Gumps/Guilds/New Guild System/OtherGuildInfo.cs b/Projects/Scripts/Gumps/Guilds/New Guild System/OtherGuildInfo.cs index 6ae8e735d..1bea09ecc 100644 --- a/Projects/Scripts/Gumps/Guilds/New Guild System/OtherGuildInfo.cs +++ b/Projects/Scripts/Gumps/Guilds/New Guild System/OtherGuildInfo.cs @@ -108,9 +108,7 @@ namespace Server.Guilds if (PendingWar) { if (war.WarRequester) - { number = 1063027; //
You have challenged this guild to war!
- } else { number = 1062969; //
This guild has challenged you to war!
@@ -211,9 +209,7 @@ namespace Server.Guilds if (war?.WarRequester == false && activeWar == null) { if (!playerRank.GetFlag(RankFlags.ControlWarStatus)) - { pm.SendLocalizedMessage(1063440); // You don't have permission to negotiate wars. - } else if (alliance != null && alliance.Leader != guild) { pm.SendLocalizedMessage(1063239, @@ -276,9 +272,7 @@ namespace Server.Guilds if (war?.WarRequester == false && activeWar == null) { if (!playerRank.GetFlag(RankFlags.ControlWarStatus)) - { pm.SendLocalizedMessage(1063440); // You don't have permission to negotiate wars. - } else if (alliance != null && alliance.Leader != guild) { pm.SendLocalizedMessage(1063239, @@ -287,9 +281,7 @@ namespace Server.Guilds alliance.Leader.Name); // You need to negotiate via ~1_val~ instead. } else - { pm.SendGump(new WarDeclarationGump(pm, guild, otherGuild)); - } } break; @@ -299,9 +291,7 @@ namespace Server.Guilds if (war != null) { if (!playerRank.GetFlag(RankFlags.ControlWarStatus)) - { pm.SendLocalizedMessage(1063440); // You don't have permission to negotiate wars. - } else if (alliance != null && alliance.Leader != guild) { pm.SendLocalizedMessage(1063239, @@ -324,9 +314,7 @@ namespace Server.Guilds case 8: //Surrender { if (!playerRank.GetFlag(RankFlags.ControlWarStatus)) - { pm.SendLocalizedMessage(1063440); // You don't have permission to negotiate wars. - } else if (alliance != null && alliance.Leader != guild) { pm.SendLocalizedMessage(1063239, @@ -384,9 +372,7 @@ namespace Server.Guilds if (war == null && activeWar == null) { if (!playerRank.GetFlag(RankFlags.ControlWarStatus)) - { pm.SendLocalizedMessage(1063440); // You don't have permission to negotiate wars. - } else if (alliance != null && alliance.Leader != guild) { pm.SendLocalizedMessage(1063239, @@ -402,9 +388,7 @@ namespace Server.Guilds otherAlliance.Leader.Name); // You need to negotiate via ~1_val~ instead. } else - { pm.SendGump(new WarDeclarationGump(pm, guild, m_Other)); - } } break; @@ -419,14 +403,10 @@ namespace Server.Guilds if (alliance == null) { if (!playerRank.GetFlag(RankFlags.AllianceControl)) - { pm.SendLocalizedMessage(1070747); // You don't have permission to create an alliance. - } else if (Faction.Find(guild.Leader) != Faction.Find(m_Other.Leader)) - { pm.SendLocalizedMessage( 1070758); // You cannot propose an alliance to a guild with a different faction allegiance. - } else if (otherAlliance != null) { if (otherAlliance.IsPendingMember(m_Other)) @@ -436,13 +416,9 @@ namespace Server.Guilds pm.SendLocalizedMessage(1063426, m_Other.Name); // ~1_val~ already belongs to an alliance. } else if (m_Other.AcceptedWars.Count > 0 || m_Other.PendingWars.Count > 0) - { pm.SendLocalizedMessage(1063427, m_Other.Name); // ~1_val~ is currently involved in a guild war. - } else if (guild.AcceptedWars.Count > 0 || guild.PendingWars.Count > 0) - { pm.SendLocalizedMessage(1063427, guild.Name); // ~1_val~ is currently involved in a guild war. - } else { pm.SendLocalizedMessage(1063439); // Enter a name for the new alliance: @@ -457,14 +433,10 @@ namespace Server.Guilds else { if (!playerRank.GetFlag(RankFlags.AllianceControl)) - { pm.SendLocalizedMessage(1063436); // You don't have permission to negotiate an alliance. - } else if (alliance.Leader != guild) - { pm.SendLocalizedMessage(1063239, $"{guild.Name}\t{alliance.Name}"); // ~1_val~ is not the leader of the ~2_val~ alliance. - } else if (otherAlliance != null) { if (otherAlliance.IsPendingMember(m_Other)) @@ -474,23 +446,15 @@ namespace Server.Guilds pm.SendLocalizedMessage(1063426, m_Other.Name); // ~1_val~ already belongs to an alliance. } else if (alliance.IsPendingMember(guild)) - { pm.SendLocalizedMessage(1063416, guild.Name); // ~1_val~ is currently considering another alliance proposal. - } else if (m_Other.AcceptedWars.Count > 0 || m_Other.PendingWars.Count > 0) - { pm.SendLocalizedMessage(1063427, m_Other.Name); // ~1_val~ is currently involved in a guild war. - } else if (guild.AcceptedWars.Count > 0 || guild.PendingWars.Count > 0) - { pm.SendLocalizedMessage(1063427, guild.Name); // ~1_val~ is currently involved in a guild war. - } else if (Faction.Find(guild.Leader) != Faction.Find(m_Other.Leader)) - { pm.SendLocalizedMessage( 1070758); // You cannot propose an alliance to a guild with a different faction allegiance. - } else { pm.SendLocalizedMessage(1070750, @@ -517,9 +481,7 @@ namespace Server.Guilds case 11: //Leave Alliance { if (!playerRank.GetFlag(RankFlags.AllianceControl)) - { pm.SendLocalizedMessage(1063436); // You don't have permission to negotiate an alliance. - } else if (alliance?.IsMember(guild) == true) { guild.Alliance = null; //Calls alliance.Removeguild @@ -535,14 +497,10 @@ namespace Server.Guilds case 12: //Remove Guild from alliance { if (!playerRank.GetFlag(RankFlags.AllianceControl)) - { pm.SendLocalizedMessage(1063436); // You don't have permission to negotiate an alliance. - } else if (alliance != null && alliance.Leader != guild) - { pm.SendLocalizedMessage(1063239, $"{guild.Name}\t{alliance.Name}"); // ~1_val~ is not the leader of the ~2_val~ alliance. - } else if (alliance?.IsMember(guild) == true && alliance.IsMember(m_Other)) { m_Other.Alliance = null; @@ -557,14 +515,10 @@ namespace Server.Guilds case 13: //Promote to Alliance leader { if (!playerRank.GetFlag(RankFlags.AllianceControl)) - { pm.SendLocalizedMessage(1063436); // You don't have permission to negotiate an alliance. - } else if (alliance != null && alliance.Leader != guild) - { pm.SendLocalizedMessage(1063239, $"{guild.Name}\t{alliance.Name}"); // ~1_val~ is not the leader of the ~2_val~ alliance. - } else if (alliance?.IsMember(guild) == true && alliance.IsMember(m_Other)) { pm.SendLocalizedMessage(1063434, @@ -578,9 +532,7 @@ namespace Server.Guilds case 14: //Withdraw Request { if (!playerRank.GetFlag(RankFlags.AllianceControl)) - { pm.SendLocalizedMessage(1063436); // You don't have permission to negotiate an alliance. - } else if (alliance != null && alliance.Leader == guild && alliance.IsPendingMember(m_Other)) { m_Other.Alliance = null; @@ -592,9 +544,7 @@ namespace Server.Guilds case 15: //Deny Alliance Request { if (!playerRank.GetFlag(RankFlags.AllianceControl)) - { pm.SendLocalizedMessage(1063436); // You don't have permission to negotiate an alliance. - } else if (alliance != null && otherAlliance != null && alliance.Leader == m_Other && otherAlliance.IsPendingMember(guild)) { @@ -609,9 +559,7 @@ namespace Server.Guilds case 16: //Accept Alliance Request { if (!playerRank.GetFlag(RankFlags.AllianceControl)) - { pm.SendLocalizedMessage(1063436); // You don't have permission to negotiate an alliance. - } else if (otherAlliance != null && otherAlliance.Leader == m_Other && otherAlliance.IsPendingMember(guild)) { @@ -640,20 +588,15 @@ namespace Server.Guilds if (!IsMember(from, guild) || alliance != null) return; - RankDefinition playerRank = pm.GuildRank; if (!playerRank.GetFlag(RankFlags.AllianceControl)) - { pm.SendLocalizedMessage(1070747); // You don't have permission to create an alliance. - } else if (Faction.Find(guild.Leader) != Faction.Find(m_Other.Leader)) - { //Notes about this: OSI only cares/checks when proposing, you can change your faction all you want later. pm.SendLocalizedMessage( 1070758); // You cannot propose an alliance to a guild with a different faction allegiance. - } else if (otherAlliance != null) { if (otherAlliance.IsPendingMember(m_Other)) @@ -663,30 +606,20 @@ namespace Server.Guilds pm.SendLocalizedMessage(1063426, m_Other.Name); // ~1_val~ already belongs to an alliance. } else if (m_Other.AcceptedWars.Count > 0 || m_Other.PendingWars.Count > 0) - { pm.SendLocalizedMessage(1063427, m_Other.Name); // ~1_val~ is currently involved in a guild war. - } else if (guild.AcceptedWars.Count > 0 || guild.PendingWars.Count > 0) - { pm.SendLocalizedMessage(1063427, guild.Name); // ~1_val~ is currently involved in a guild war. - } else { string name = Utility.FixHtml(text.Trim()); if (!CheckProfanity(name)) - { pm.SendLocalizedMessage(1070886); // That alliance name is not allowed. - } else if (name.Length > Guild.NameLimit) - { pm.SendLocalizedMessage(1070887, Guild.NameLimit.ToString()); // An alliance name cannot exceed ~1_val~ characters in length. - } else if (AllianceInfo.Alliances.ContainsKey(name.ToLower())) - { pm.SendLocalizedMessage(1063428); // That alliance name is not available. - } else { pm.SendLocalizedMessage(1070750, diff --git a/Projects/Scripts/Gumps/HouseDemolishGump.cs b/Projects/Scripts/Gumps/HouseDemolishGump.cs index 1ec189cff..5a2e11f5a 100644 --- a/Projects/Scripts/Gumps/HouseDemolishGump.cs +++ b/Projects/Scripts/Gumps/HouseDemolishGump.cs @@ -1,4 +1,3 @@ -using Server.Accounting; using Server.Guilds; using Server.Items; using Server.Multis; @@ -32,13 +31,14 @@ namespace Server.Gumps AddImageTiled(10, 40, 400, 200, 2624); AddAlphaRegion(10, 40, 400, 200); - AddHtmlLocalized(10, 40, 400, 200, 1061795, 32512, false, true); /* You are about to demolish your house. - * You will be refunded the house's value directly to your bank box. - * All items in the house will remain behind and can be freely picked up by anyone. - * Once the house is demolished, anyone can attempt to place a new house on the vacant land. - * This action will not un-condemn any other houses on your account, nor will it end your 7-day waiting period (if it applies to you). - * Are you sure you wish to continue? - */ + AddHtmlLocalized(10, 40, 400, 200, 1061795, 32512, false, true); + /* You are about to demolish your house. + * You will be refunded the house's value directly to your bank box. + * All items in the house will remain behind and can be freely picked up by anyone. + * Once the house is demolished, anyone can attempt to place a new house on the vacant land. + * This action will not un-condemn any other houses on your account, nor will it end your 7-day waiting period (if it applies to you). + * Are you sure you wish to continue? + */ AddImageTiled(10, 250, 400, 20, 2624); AddAlphaRegion(10, 250, 400, 20); @@ -50,7 +50,7 @@ namespace Server.Gumps AddHtmlLocalized(240, 250, 170, 20, 1011012, 32767); // CANCEL } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (info.ButtonID == 1 && !m_House.Deleted) { diff --git a/Projects/Scripts/Gumps/HouseGump.cs b/Projects/Scripts/Gumps/HouseGump.cs index c3a65e70a..c940627bd 100644 --- a/Projects/Scripts/Gumps/HouseGump.cs +++ b/Projects/Scripts/Gumps/HouseGump.cs @@ -54,12 +54,12 @@ namespace Server.Gumps } } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (m_House.Deleted) return; - Mobile from = state.Mobile; + Mobile from = sender.Mobile; from.SendGump(new HouseGump(from, m_House)); } @@ -125,12 +125,12 @@ namespace Server.Gumps } } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (m_House.Deleted) return; - Mobile from = state.Mobile; + Mobile from = sender.Mobile; if (m_List != null && info.ButtonID == 1) // Remove now { diff --git a/Projects/Scripts/Gumps/HouseGumpAOS.cs b/Projects/Scripts/Gumps/HouseGumpAOS.cs index a29c9454e..22800fd7f 100644 --- a/Projects/Scripts/Gumps/HouseGumpAOS.cs +++ b/Projects/Scripts/Gumps/HouseGumpAOS.cs @@ -672,92 +672,92 @@ namespace Server.Gumps if (e == null) return; - int cost = e.Cost - house.Price; + int cost = e.Cost - house.Price; - if (cost > 0) + if (cost > 0) + { + if (Banker.Withdraw(from, cost)) { - if (Banker.Withdraw(from, cost)) - { - from.SendLocalizedMessage(1060398, - cost.ToString()); // ~1_AMOUNT~ gold has been withdrawn from your bank box. - } - else - { - from.SendLocalizedMessage( - 1061624); // You do not have enough funds in your bank to cover the difference between your old house and your new one. - return; - } + from.SendLocalizedMessage(1060398, + cost.ToString()); // ~1_AMOUNT~ gold has been withdrawn from your bank box. } - else if (cost < 0) + else { - if (Banker.Deposit(from, -cost)) - from.SendLocalizedMessage(1060397, - (-cost).ToString()); // ~1_AMOUNT~ gold has been deposited into your bank box. - else - return; - } - - BaseHouse newHouse = e.ConstructHouse(from); - - if (newHouse != null) - { - newHouse.Price = e.Cost; - - house.MoveAllToCrate(); - - newHouse.Friends = new List(house.Friends); - newHouse.CoOwners = new List(house.CoOwners); - newHouse.Bans = new List(house.Bans); - newHouse.Access = new List(house.Access); - newHouse.BuiltOn = house.BuiltOn; - newHouse.LastTraded = house.LastTraded; - newHouse.Public = house.Public; - - newHouse.VendorInventories.AddRange(house.VendorInventories); - house.VendorInventories.Clear(); - - foreach (VendorInventory inventory in newHouse.VendorInventories) inventory.House = newHouse; - - newHouse.InternalizedVendors.AddRange(house.InternalizedVendors); - house.InternalizedVendors.Clear(); - - foreach (Mobile mobile in newHouse.InternalizedVendors) - if (mobile is PlayerVendor vendor) - vendor.House = newHouse; - else if (mobile is PlayerBarkeeper barkeeper) - barkeeper.House = newHouse; - - if (house.MovingCrate != null) - { - newHouse.MovingCrate = house.MovingCrate; - newHouse.MovingCrate.House = newHouse; - house.MovingCrate = null; - } - - List items = house.GetItems(); - List mobiles = house.GetMobiles(); - - newHouse.MoveToWorld( - new Point3D(house.X + house.ConvertOffsetX, house.Y + house.ConvertOffsetY, - house.Z + house.ConvertOffsetZ), house.Map); - house.Delete(); - - foreach (Item item in items) item.Location = newHouse.BanLocation; - - foreach (Mobile mobile in mobiles) mobile.Location = newHouse.BanLocation; - - /* You have successfully replaced your original house with a new house. - * The value of the replaced house has been deposited into your bank box. - * All of the items in your original house have been relocated to a Moving Crate in the new house. - * Any deed-based house add-ons have been converted back into deeds. - * Vendors and barkeeps in the house, if any, have been stored in the Moving Crate as well. - * Use the Get Vendor context-sensitive menu option on your character to retrieve them. - * These containers can be used to re-create the vendor in a new location. - * Any barkeepers have been converted into deeds. - */ - from.SendGump(new NoticeGump(1060637, 30720, 1060012, 32512, 420, 280)); + from.SendLocalizedMessage( + 1061624); // You do not have enough funds in your bank to cover the difference between your old house and your new one. return; } + } + else if (cost < 0) + { + if (Banker.Deposit(from, -cost)) + from.SendLocalizedMessage(1060397, + (-cost).ToString()); // ~1_AMOUNT~ gold has been deposited into your bank box. + else + return; + } + + BaseHouse newHouse = e.ConstructHouse(from); + + if (newHouse != null) + { + newHouse.Price = e.Cost; + + house.MoveAllToCrate(); + + newHouse.Friends = new List(house.Friends); + newHouse.CoOwners = new List(house.CoOwners); + newHouse.Bans = new List(house.Bans); + newHouse.Access = new List(house.Access); + newHouse.BuiltOn = house.BuiltOn; + newHouse.LastTraded = house.LastTraded; + newHouse.Public = house.Public; + + newHouse.VendorInventories.AddRange(house.VendorInventories); + house.VendorInventories.Clear(); + + foreach (VendorInventory inventory in newHouse.VendorInventories) inventory.House = newHouse; + + newHouse.InternalizedVendors.AddRange(house.InternalizedVendors); + house.InternalizedVendors.Clear(); + + foreach (Mobile mobile in newHouse.InternalizedVendors) + if (mobile is PlayerVendor vendor) + vendor.House = newHouse; + else if (mobile is PlayerBarkeeper barkeeper) + barkeeper.House = newHouse; + + if (house.MovingCrate != null) + { + newHouse.MovingCrate = house.MovingCrate; + newHouse.MovingCrate.House = newHouse; + house.MovingCrate = null; + } + + List items = house.GetItems(); + List mobiles = house.GetMobiles(); + + newHouse.MoveToWorld( + new Point3D(house.X + house.ConvertOffsetX, house.Y + house.ConvertOffsetY, + house.Z + house.ConvertOffsetZ), house.Map); + house.Delete(); + + foreach (Item item in items) item.Location = newHouse.BanLocation; + + foreach (Mobile mobile in mobiles) mobile.Location = newHouse.BanLocation; + + /* You have successfully replaced your original house with a new house. + * The value of the replaced house has been deposited into your bank box. + * All of the items in your original house have been relocated to a Moving Crate in the new house. + * Any deed-based house add-ons have been converted back into deeds. + * Vendors and barkeeps in the house, if any, have been stored in the Moving Crate as well. + * Use the Get Vendor context-sensitive menu option on your character to retrieve them. + * These containers can be used to re-create the vendor in a new location. + * Any barkeepers have been converted into deeds. + */ + from.SendGump(new NoticeGump(1060637, 30720, 1060012, 32512, 420, 280)); + return; + } } from.SendGump(new HouseGumpAOS(HouseGumpPageAOS.Security, from, house)); diff --git a/Projects/Scripts/Gumps/HouseTransferGump.cs b/Projects/Scripts/Gumps/HouseTransferGump.cs index fc3926804..4dce5b90d 100644 --- a/Projects/Scripts/Gumps/HouseTransferGump.cs +++ b/Projects/Scripts/Gumps/HouseTransferGump.cs @@ -53,7 +53,7 @@ namespace Server.Gumps AddHtmlLocalized(240, 250, 170, 20, 1011012, 32767); // CANCEL } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (info.ButtonID == 1 && !m_House.Deleted) m_House.EndConfirmTransfer(m_From, m_To); diff --git a/Projects/Scripts/Gumps/PetResurrectGump.cs b/Projects/Scripts/Gumps/PetResurrectGump.cs index 494505e9e..87e53b6df 100644 --- a/Projects/Scripts/Gumps/PetResurrectGump.cs +++ b/Projects/Scripts/Gumps/PetResurrectGump.cs @@ -33,12 +33,12 @@ namespace Server.Gumps AddButton(110, 105, 0x819, 0x818, 0x2); // Cancel } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (m_Pet.Deleted || !m_Pet.IsBonded || !m_Pet.IsDeadPet) return; - Mobile from = state.Mobile; + Mobile from = sender.Mobile; if (info.ButtonID == 1) { diff --git a/Projects/Scripts/Gumps/PlayerVendorGumps.cs b/Projects/Scripts/Gumps/PlayerVendorGumps.cs index 93c2e375b..86ce1c962 100644 --- a/Projects/Scripts/Gumps/PlayerVendorGumps.cs +++ b/Projects/Scripts/Gumps/PlayerVendorGumps.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Reflection; -using Server.HuePickers; using Server.Items; using Server.Mobiles; using Server.Network; @@ -37,9 +36,9 @@ namespace Server.Gumps AddHtmlLocalized(152, 130, 100, 24, 1011036); // OKAY } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { - Mobile from = state.Mobile; + Mobile from = sender.Mobile; if (!m_Vendor.CanInteractWith(from, false)) return; @@ -135,9 +134,9 @@ namespace Server.Gumps AddLabel(300, 48, 0, ((int)(days / 12.0)).ToString()); } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { - Mobile from = state.Mobile; + Mobile from = sender.Mobile; if (!m_Vendor.CanInteractWith(from, true)) return; @@ -476,12 +475,12 @@ namespace Server.Gumps } } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (m_Vendor.Deleted) return; - Mobile from = state.Mobile; + Mobile from = sender.Mobile; if (m_Vendor is PlayerVendor vendor && !vendor.CanInteractWith(from, true)) return; @@ -581,11 +580,11 @@ namespace Server.Gumps if (category.Layer == Layer.Hair) { - new PVHairHuePicker(false, m_Vendor, from).SendTo(state); + new PVHairHuePicker(false, m_Vendor, from).SendTo(sender); } else if (category.Layer == Layer.FacialHair) { - new PVHairHuePicker(true, m_Vendor, from).SendTo(state); + new PVHairHuePicker(true, m_Vendor, from).SendTo(sender); } else { @@ -604,7 +603,7 @@ namespace Server.Gumps } if (item != null) - new PVHuePicker(item, m_Vendor, from).SendTo(state); + new PVHuePicker(item, m_Vendor, from).SendTo(sender); } } } diff --git a/Projects/Scripts/Gumps/PolymorphGump.cs b/Projects/Scripts/Gumps/PolymorphGump.cs index 4d6717b53..11a2e88d8 100644 --- a/Projects/Scripts/Gumps/PolymorphGump.cs +++ b/Projects/Scripts/Gumps/PolymorphGump.cs @@ -120,7 +120,7 @@ namespace Server.Gumps } } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (info.ButtonID == 1 && info.Switches.Length > 0) { diff --git a/Projects/Scripts/Gumps/Props/PropsGump.cs b/Projects/Scripts/Gumps/Props/PropsGump.cs index 57b9acb48..e0f2baaf5 100644 --- a/Projects/Scripts/Gumps/Props/PropsGump.cs +++ b/Projects/Scripts/Gumps/Props/PropsGump.cs @@ -153,9 +153,7 @@ namespace Server.Gumps if (parent != null) { - if (m_Stack == null) - m_Stack = new Stack(); - + m_Stack ??= new Stack(); m_Stack.Push(parent); } @@ -281,9 +279,9 @@ namespace Server.Gumps } } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { - Mobile from = state.Mobile; + Mobile from = sender.Mobile; if (!BaseCommand.IsAccessible(from, m_Object)) { diff --git a/Projects/Scripts/Gumps/Props/SetBodyGump.cs b/Projects/Scripts/Gumps/Props/SetBodyGump.cs index 43f1ee237..dedc3082a 100644 --- a/Projects/Scripts/Gumps/Props/SetBodyGump.cs +++ b/Projects/Scripts/Gumps/Props/SetBodyGump.cs @@ -127,7 +127,6 @@ namespace Server.Gumps switch (index) { default: - case 0: type = ModelBodyType.Monsters; list = m_Monster; break; @@ -204,24 +203,17 @@ namespace Server.Gumps if (((Body)bodyID).IsEmpty) continue; - List list; - - switch (oldEntry.BodyType) + List list = oldEntry.BodyType switch { - default: continue; - case ModelBodyType.Monsters: - list = m_Monster; - break; - case ModelBodyType.Animals: - list = m_Animal; - break; - case ModelBodyType.Sea: - list = m_Sea; - break; - case ModelBodyType.Human: - list = m_Human; - break; - } + ModelBodyType.Monsters => m_Monster, + ModelBodyType.Animals => m_Animal, + ModelBodyType.Sea => m_Sea, + ModelBodyType.Human => m_Human, + _ => null + }; + + if (list == null) + return; int itemID = ShrinkTable.Lookup(bodyID, -1); @@ -287,7 +279,7 @@ namespace Server.Gumps int v = Name.CompareTo(comp.Name); if (v == 0) - Body.CompareTo(comp.Body); + v = Body.CompareTo(comp.Body); return v; } diff --git a/Projects/Scripts/Gumps/Props/SetGump.cs b/Projects/Scripts/Gumps/Props/SetGump.cs index 918eab063..4d0b11904 100644 --- a/Projects/Scripts/Gumps/Props/SetGump.cs +++ b/Projects/Scripts/Gumps/Props/SetGump.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; using System.Reflection; using Server.Commands; -using Server.HuePickers; using Server.Network; namespace Server.Gumps diff --git a/Projects/Scripts/Gumps/Props/SetObjectGump.cs b/Projects/Scripts/Gumps/Props/SetObjectGump.cs index 30d79a680..ef3895bbd 100644 --- a/Projects/Scripts/Gumps/Props/SetObjectGump.cs +++ b/Projects/Scripts/Gumps/Props/SetObjectGump.cs @@ -4,7 +4,6 @@ using System.Reflection; using Server.Commands; using Server.Commands.Generic; using Server.Network; -using Server.Prompts; namespace Server.Gumps { diff --git a/Projects/Scripts/Gumps/RunebookGump.cs b/Projects/Scripts/Gumps/RunebookGump.cs index 845ed5628..9f259ff9c 100644 --- a/Projects/Scripts/Gumps/RunebookGump.cs +++ b/Projects/Scripts/Gumps/RunebookGump.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using Server.Items; using Server.Multis; using Server.Network; -using Server.Prompts; using Server.Spells.Chivalry; using Server.Spells.Fourth; using Server.Spells.Seventh; @@ -203,9 +202,9 @@ namespace Server.Gumps public static bool HasSpell(Mobile from, int spellID) => Spellbook.Find(from, spellID)?.HasSpell(spellID) == true; - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { - Mobile from = state.Mobile; + Mobile from = sender.Mobile; if (Book.Deleted || !from.InRange(Book.GetWorldLocation(), Core.ML ? 3 : 1) || !DesignContext.Check(from)) { diff --git a/Projects/Scripts/Gumps/SetSecureLevelGump.cs b/Projects/Scripts/Gumps/SetSecureLevelGump.cs index 149491e73..a52c8667e 100644 --- a/Projects/Scripts/Gumps/SetSecureLevelGump.cs +++ b/Projects/Scripts/Gumps/SetSecureLevelGump.cs @@ -60,7 +60,7 @@ namespace Server.Gumps public int GetFirstID(SecureLevel level) => m_Info.Level == level ? 4006 : 4005; - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { var level = info.ButtonID switch { @@ -74,12 +74,12 @@ namespace Server.Gumps if (m_Info.Level == level) { - state.Mobile.SendLocalizedMessage(1061281); // Access level unchanged. + sender.Mobile.SendLocalizedMessage(1061281); // Access level unchanged. } else { m_Info.Level = level; - state.Mobile.SendLocalizedMessage(1061280); // New access level set. + sender.Mobile.SendLocalizedMessage(1061280); // New access level set. } } } diff --git a/Projects/Scripts/Gumps/SkillsGump.cs b/Projects/Scripts/Gumps/SkillsGump.cs index 31a4c881d..2d3543009 100644 --- a/Projects/Scripts/Gumps/SkillsGump.cs +++ b/Projects/Scripts/Gumps/SkillsGump.cs @@ -306,7 +306,6 @@ namespace Server.Gumps switch (sk.Lock) { default: - case SkillLock.Up: buttonID1 = 0x983; buttonID2 = 0x983; xOffset = 6; diff --git a/Projects/Scripts/Gumps/VendorRentalGumps.cs b/Projects/Scripts/Gumps/VendorRentalGumps.cs index 01c140d51..4a80fa64e 100644 --- a/Projects/Scripts/Gumps/VendorRentalGumps.cs +++ b/Projects/Scripts/Gumps/VendorRentalGumps.cs @@ -1,6 +1,5 @@ using Server.Items; using Server.Network; -using Server.Prompts; using Server.Mobiles; using Server.Targeting; using Server.Multis; diff --git a/Projects/Scripts/Holiday Stuff/Halloween/2006/Engines/TrickOrTreat.cs b/Projects/Scripts/Holiday Stuff/Halloween/2006/Engines/TrickOrTreat.cs index e93873910..39281307d 100644 --- a/Projects/Scripts/Holiday Stuff/Halloween/2006/Engines/TrickOrTreat.cs +++ b/Projects/Scripts/Holiday Stuff/Halloween/2006/Engines/TrickOrTreat.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Server.Events.Halloween; using Server.Items; using Server.Mobiles; @@ -69,9 +70,7 @@ namespace Server.Engines.Events if (twin.Deleted) return; - foreach (Item item in m_From.Items) - if (item.Layer != Layer.Backpack && item.Layer != Layer.Mount && item.Layer != Layer.Bank) - m_Items.Add(item); + m_Items.AddRange(m_From.Items.Where(item => item.Layer != Layer.Backpack && item.Layer != Layer.Mount && item.Layer != Layer.Bank)); if (m_Items.Count > 0) { diff --git a/Projects/Scripts/Items/Addons/BallotBox.cs b/Projects/Scripts/Items/Addons/BallotBox.cs index 941e8037f..8888d0e93 100644 --- a/Projects/Scripts/Items/Addons/BallotBox.cs +++ b/Projects/Scripts/Items/Addons/BallotBox.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using Server.Gumps; using Server.Multis; using Server.Network; -using Server.Prompts; namespace Server.Items { diff --git a/Projects/Scripts/Items/Addons/ElvenSpinningwheelEastAddon.cs b/Projects/Scripts/Items/Addons/ElvenSpinningwheelEastAddon.cs index 69945e6d2..4cbc53e4e 100644 --- a/Projects/Scripts/Items/Addons/ElvenSpinningwheelEastAddon.cs +++ b/Projects/Scripts/Items/Addons/ElvenSpinningwheelEastAddon.cs @@ -26,14 +26,8 @@ namespace Server.Items m_Timer.Start(); foreach (AddonComponent c in Components) - switch (c.ItemID) - { - case 0x2DD9: - case 0x101C: - case 0x10A4: - ++c.ItemID; - break; - } + if (c.ItemID == 0x2DD9 || c.ItemID == 0x101C || c.ItemID == 0x10A4) + ++c.ItemID; } public override void Serialize(GenericWriter writer) @@ -69,15 +63,8 @@ namespace Server.Items m_Timer = null; foreach (AddonComponent c in Components) - switch (c.ItemID) - { - case 0x1016: - case 0x101A: - case 0x101D: - case 0x10A5: - --c.ItemID; - break; - } + if (c.ItemID == 0x1016 || c.ItemID == 0x101A || c.ItemID == 0x101D || c.ItemID == 0x10A5) + --c.ItemID; callback?.Invoke(this, from, hue); } @@ -134,4 +121,4 @@ namespace Server.Items int version = reader.ReadEncodedInt(); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Items/Addons/ElvenSpinningwheelSouthAddon.cs b/Projects/Scripts/Items/Addons/ElvenSpinningwheelSouthAddon.cs index 39bd60ec8..8d5d5f2cb 100644 --- a/Projects/Scripts/Items/Addons/ElvenSpinningwheelSouthAddon.cs +++ b/Projects/Scripts/Items/Addons/ElvenSpinningwheelSouthAddon.cs @@ -26,15 +26,8 @@ namespace Server.Items m_Timer.Start(); foreach (AddonComponent c in Components) - switch (c.ItemID) - { - case 0x1015: - case 0x1019: - case 0x101C: - case 0x10A4: - ++c.ItemID; - break; - } + if (c.ItemID == 0x1015 || c.ItemID == 0x1019 || c.ItemID == 0x101C || c.ItemID == 0x10A4) + ++c.ItemID; } public override void Serialize(GenericWriter writer) @@ -71,15 +64,8 @@ namespace Server.Items m_Timer = null; foreach (AddonComponent c in Components) - switch (c.ItemID) - { - case 0x1016: - case 0x101A: - case 0x101D: - case 0x10A5: - --c.ItemID; - break; - } + if (c.ItemID == 0x1016 || c.ItemID == 0x101A || c.ItemID == 0x101D || c.ItemID == 0x10A5) + --c.ItemID; callback?.Invoke(this, from, hue); } @@ -136,4 +122,4 @@ namespace Server.Items int version = reader.ReadEncodedInt(); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Items/Addons/FlourMillEastAddon.cs b/Projects/Scripts/Items/Addons/FlourMillEastAddon.cs index e5c597386..2f9071dfc 100644 --- a/Projects/Scripts/Items/Addons/FlourMillEastAddon.cs +++ b/Projects/Scripts/Items/Addons/FlourMillEastAddon.cs @@ -130,11 +130,10 @@ namespace Server.Items { List components = Components; - int[][] stageTable = m_StageTable; - for (int i = 0; i < components.Count; ++i) { - if (!(components[i] is AddonComponent component)) + AddonComponent component = components[i]; + if (component == null) continue; int[] itemTable = FindItemTable(component.ItemID); @@ -210,4 +209,4 @@ namespace Server.Items int version = reader.ReadInt(); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Items/Addons/FlourMillSouthAddon.cs b/Projects/Scripts/Items/Addons/FlourMillSouthAddon.cs index a158ec628..e3602112a 100644 --- a/Projects/Scripts/Items/Addons/FlourMillSouthAddon.cs +++ b/Projects/Scripts/Items/Addons/FlourMillSouthAddon.cs @@ -118,11 +118,10 @@ namespace Server.Items { List components = Components; - int[][] stageTable = m_StageTable; - for (int i = 0; i < components.Count; ++i) { - if (!(components[i] is AddonComponent component)) + AddonComponent component = components[i]; + if (component == null) continue; int[] itemTable = FindItemTable(component.ItemID); @@ -198,4 +197,4 @@ namespace Server.Items int version = reader.ReadInt(); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Items/Addons/JackOLantern.cs b/Projects/Scripts/Items/Addons/JackOLantern.cs index d72b6383e..80d34f308 100644 --- a/Projects/Scripts/Items/Addons/JackOLantern.cs +++ b/Projects/Scripts/Items/Addons/JackOLantern.cs @@ -39,15 +39,7 @@ namespace Server.Items public override bool ShareHue => false; - private AddonComponent GetComponent(int itemID, int hue) - { - AddonComponent ac = new AddonComponent(itemID); - - ac.Hue = hue; - ac.Name = "jack-o-lantern"; - - return ac; - } + private AddonComponent GetComponent(int itemID, int hue) => new AddonComponent(itemID) {Hue = hue, Name = "jack-o-lantern"}; public override void Serialize(GenericWriter writer) { @@ -66,17 +58,23 @@ namespace Server.Items Timer.DelayCall(TimeSpan.Zero, delegate { for (int i = 0; i < Components.Count; ++i) - if (Components[i] is AddonComponent ac && ac.Hue == 2118) + { + AddonComponent ac = Components[i]; + if (ac?.Hue == 2118) ac.Hue = 1161; + } }); if (version <= 1) Timer.DelayCall(TimeSpan.Zero, delegate { for (int i = 0; i < Components.Count; ++i) - if (Components[i] is AddonComponent ac) + { + AddonComponent ac = Components[i]; + if (ac != null) ac.Name = "jack-o-lantern"; + } }); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Items/Addons/SpinningwheelEastAddon.cs b/Projects/Scripts/Items/Addons/SpinningwheelEastAddon.cs index d85c4fd9b..e1dff197f 100644 --- a/Projects/Scripts/Items/Addons/SpinningwheelEastAddon.cs +++ b/Projects/Scripts/Items/Addons/SpinningwheelEastAddon.cs @@ -34,15 +34,8 @@ namespace Server.Items m_Timer.Start(); foreach (AddonComponent c in Components) - switch (c.ItemID) - { - case 0x1015: - case 0x1019: - case 0x101C: - case 0x10A4: - ++c.ItemID; - break; - } + if (c.ItemID == 0x1015 || c.ItemID == 0x1019 || c.ItemID == 0x101C || c.ItemID == 0x10A4) + ++c.ItemID; } public override void Serialize(GenericWriter writer) @@ -79,15 +72,8 @@ namespace Server.Items m_Timer = null; foreach (AddonComponent c in Components) - switch (c.ItemID) - { - case 0x1016: - case 0x101A: - case 0x101D: - case 0x10A5: - --c.ItemID; - break; - } + if (c.ItemID == 0x1016 || c.ItemID == 0x101A || c.ItemID == 0x101D || c.ItemID == 0x10A5) + --c.ItemID; callback?.Invoke(this, from, hue); } @@ -144,4 +130,4 @@ namespace Server.Items int version = reader.ReadInt(); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Items/Addons/SpinningwheelSouthAddon.cs b/Projects/Scripts/Items/Addons/SpinningwheelSouthAddon.cs index a79769d39..1123fea2f 100644 --- a/Projects/Scripts/Items/Addons/SpinningwheelSouthAddon.cs +++ b/Projects/Scripts/Items/Addons/SpinningwheelSouthAddon.cs @@ -26,15 +26,8 @@ namespace Server.Items m_Timer.Start(); foreach (AddonComponent c in Components) - switch (c.ItemID) - { - case 0x1015: - case 0x1019: - case 0x101C: - case 0x10A4: - ++c.ItemID; - break; - } + if (c.ItemID == 0x1015 || c.ItemID == 0x1019 || c.ItemID == 0x101C || c.ItemID == 0x10A4) + ++c.ItemID; } public override void Serialize(GenericWriter writer) @@ -71,15 +64,8 @@ namespace Server.Items m_Timer = null; foreach (AddonComponent c in Components) - switch (c.ItemID) - { - case 0x1016: - case 0x101A: - case 0x101D: - case 0x10A5: - --c.ItemID; - break; - } + if (c.ItemID == 0x1016 || c.ItemID == 0x101A || c.ItemID == 0x101D || c.ItemID == 0x10A5) + --c.ItemID; callback?.Invoke(this, from, hue); } @@ -136,4 +122,4 @@ namespace Server.Items int version = reader.ReadInt(); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Items/Aquarium/Aquarium.cs b/Projects/Scripts/Items/Aquarium/Aquarium.cs index c7247e0da..09e7fa1a7 100644 --- a/Projects/Scripts/Items/Aquarium/Aquarium.cs +++ b/Projects/Scripts/Items/Aquarium/Aquarium.cs @@ -597,8 +597,7 @@ namespace Server.Items UpdateWaterState(); // reward - if (LiveCreatures > 0) - m_RewardAvailable = true; + m_RewardAvailable |= LiveCreatures > 0; } else { @@ -606,12 +605,12 @@ namespace Server.Items if (OptimalState && LiveCreatures < MaxLiveCreatures) if (Utility.RandomDouble() < 0.005 * LiveCreatures) { - BaseFish fish = null; - int message = 0; + BaseFish fish; + int message; switch (Utility.Random(6)) { - case 0: + default: { message = 1074371; // Brine shrimp have hatched overnight in the tank. fish = new BrineShrimp(); diff --git a/Projects/Scripts/Items/Armor/BaseArmor.cs b/Projects/Scripts/Items/Armor/BaseArmor.cs index 59fd460df..81a69037c 100644 --- a/Projects/Scripts/Items/Armor/BaseArmor.cs +++ b/Projects/Scripts/Items/Armor/BaseArmor.cs @@ -436,9 +436,8 @@ namespace Server.Items BaseEnergyResistance + GetProtOffset() + GetResourceAttrs().ArmorEnergyResist + m_EnergyBonus; [CommandProperty(AccessLevel.GameMaster)] - public ArmorBodyType BodyPosition - { - get + public ArmorBodyType BodyPosition => + Layer switch { return Layer switch { @@ -1144,8 +1143,7 @@ namespace Server.Items if (GetSaveFlag(flags, SaveFlag.SkillBonuses)) SkillBonuses = new AosSkillBonuses(this, reader); - if (GetSaveFlag(flags, SaveFlag.PlayerConstructed)) - PlayerConstructed = true; + PlayerConstructed |= GetSaveFlag(flags, SaveFlag.PlayerConstructed); break; } @@ -1271,8 +1269,7 @@ namespace Server.Items } } - if (SkillBonuses == null) - SkillBonuses = new AosSkillBonuses(this); + SkillBonuses ??= new AosSkillBonuses(this); Mobile m = Parent as Mobile; @@ -1299,17 +1296,11 @@ namespace Server.Items m?.CheckStatTimers(); - if (version < 7) - PlayerConstructed = true; // we don't know, so, assume it's crafted + PlayerConstructed |= version < 7; // we don't know, so, assume it's crafted } - public override bool AllowSecureTrade(Mobile from, Mobile to, Mobile newOwner, bool accepted) - { - if (!Ethic.CheckTrade(from, to, newOwner, this)) - return false; - - return base.AllowSecureTrade(from, to, newOwner, accepted); - } + public override bool AllowSecureTrade(Mobile from, Mobile to, Mobile newOwner, bool accepted) => + Ethic.CheckTrade(@from, to, newOwner, this) && base.AllowSecureTrade(@from, to, newOwner, accepted); public override bool CanEquip(Mobile from) { @@ -1374,19 +1365,10 @@ namespace Server.Items return base.CanEquip(from); } - public override bool CheckPropertyConfliction(Mobile m) - { - if (base.CheckPropertyConfliction(m)) - return true; - - if (Layer == Layer.Pants) - return m.FindItemOnLayer(Layer.InnerLegs) != null; - - if (Layer == Layer.Shirt) - return m.FindItemOnLayer(Layer.InnerTorso) != null; - - return false; - } + public override bool CheckPropertyConfliction(Mobile m) => + base.CheckPropertyConfliction(m) || (Layer == Layer.Pants + ? m.FindItemOnLayer(Layer.InnerLegs) != null + : Layer == Layer.Shirt && m.FindItemOnLayer(Layer.InnerTorso) != null); public override bool OnEquip(Mobile from) { @@ -1477,25 +1459,9 @@ namespace Server.Items } } - public override bool AllowEquippedCast(Mobile from) - { - if (base.AllowEquippedCast(from)) - return true; + public override bool AllowEquippedCast(Mobile from) => base.AllowEquippedCast(@from) || Attributes.SpellChanneling != 0; - return Attributes.SpellChanneling != 0; - } - - public virtual int GetLuckBonus() - { - CraftResourceInfo resInfo = CraftResources.GetInfo(m_Resource); - - CraftAttributeInfo attrInfo = resInfo?.AttributeInfo; - - if (attrInfo == null) - return 0; - - return attrInfo.ArmorLuck; - } + public virtual int GetLuckBonus() => CraftResources.GetInfo(m_Resource)?.AttributeInfo?.ArmorLuck ?? 0; public override void GetProperties(ObjectPropertyList list) { @@ -1665,9 +1631,7 @@ namespace Server.Items if (attrs.Count == 0 && Crafter == null && Name != null) return; - EquipmentInfo eqInfo = new EquipmentInfo(number, m_Crafter, false, attrs.ToArray()); - - from.Send(new DisplayEquipmentInfo(this, eqInfo)); + EquipmentPackets.SendDisplayEquipmentInfo(from.NetState, this, number, m_Crafter, false, attrs); } [Flags] diff --git a/Projects/Scripts/Items/Armor/Glasses/ElvenGlasses.cs b/Projects/Scripts/Items/Armor/Glasses/ElvenGlasses.cs index 9f51f6393..d16ce0287 100644 --- a/Projects/Scripts/Items/Armor/Glasses/ElvenGlasses.cs +++ b/Projects/Scripts/Items/Armor/Glasses/ElvenGlasses.cs @@ -1,3 +1,5 @@ +using System; + namespace Server.Items { public class ElvenGlasses : BaseArmor @@ -120,16 +122,14 @@ namespace Server.Items SaveFlag flags = (SaveFlag)reader.ReadInt(); - if (GetSaveFlag(flags, SaveFlag.WeaponAttributes)) - WeaponAttributes = new AosWeaponAttributes(this, reader); - else - WeaponAttributes = new AosWeaponAttributes(this); + WeaponAttributes = GetSaveFlag(flags, SaveFlag.WeaponAttributes) ? new AosWeaponAttributes(this, reader) : new AosWeaponAttributes(this); } + [Flags] private enum SaveFlag { None = 0x00000000, WeaponAttributes = 0x00000001 } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Items/Body Parts/Head.cs b/Projects/Scripts/Items/Body Parts/Head.cs index 96086f183..a8d26d885 100644 --- a/Projects/Scripts/Items/Body Parts/Head.cs +++ b/Projects/Scripts/Items/Body Parts/Head.cs @@ -33,9 +33,8 @@ namespace Server.Items [CommandProperty(AccessLevel.GameMaster)] public HeadType HeadType{ get; set; } - public override string DefaultName - { - get + public override string DefaultName => + PlayerName == null ? base.DefaultName : HeadType switch { if (PlayerName == null) return base.DefaultName; diff --git a/Projects/Scripts/Items/Books/BaseBook.cs b/Projects/Scripts/Items/Books/BaseBook.cs index 754cabba2..67392e12d 100644 --- a/Projects/Scripts/Items/Books/BaseBook.cs +++ b/Projects/Scripts/Items/Books/BaseBook.cs @@ -57,19 +57,17 @@ namespace Server.Items if (content == null) { - Pages = new BookPageInfo[pageCount]; + Pages = new BookPageInfo[Math.Min(pageCount, 255)]; for (int i = 0; i < Pages.Length; ++i) Pages[i] = new BookPageInfo(); } else - { Pages = content.Copy(); - } } // Intended for defined books only - public BaseBook(int itemID, bool writable) : this(itemID, 0) + public BaseBook(int itemID, bool writable) : this(itemID, 0, writable) { } @@ -230,12 +228,7 @@ namespace Server.Items Pages[i] = new BookPageInfo(reader); } else - { - if (content != null) - Pages = content.Copy(); - else - Pages = new BookPageInfo[0]; - } + Pages = content?.Copy() ?? new BookPageInfo[0]; break; } @@ -254,14 +247,7 @@ namespace Server.Items Pages[i] = new BookPageInfo(reader); } else - { - BookContent content = DefaultContent; - - if (content != null) - Pages = content.Copy(); - else - Pages = new BookPageInfo[0]; - } + Pages = DefaultContent?.Copy() ?? new BookPageInfo[0]; break; } @@ -307,8 +293,8 @@ namespace Server.Items Author = from.Name; } - from.Send(new BookHeader(from, this)); - from.Send(new BookPageDetails(this)); + BookPackets.SendBookHeader(from.NetState, from, this); + BookPackets.SendBookPageDetails(from.NetState, this); } public static void Initialize() @@ -350,14 +336,14 @@ namespace Server.Items if (titleLength > 60) return; - string title = pvSrc.ReadUTF8StringSafe(titleLength); + string title = pvSrc.ReadStringSafe(titleLength); int authorLength = pvSrc.ReadUInt16(); if (authorLength > 30) return; - string author = pvSrc.ReadUTF8StringSafe(authorLength); + string author = pvSrc.ReadStringSafe(authorLength); book.Title = Utility.FixHtml(title); book.Author = Utility.FixHtml(author); @@ -380,31 +366,23 @@ namespace Server.Items { int index = pvSrc.ReadUInt16(); - if (index >= 1 && index <= book.PagesCount) - { - --index; - - int lineCount = pvSrc.ReadUInt16(); - - if (lineCount <= 8) - { - string[] lines = new string[lineCount]; - - for (int j = 0; j < lineCount; ++j) - if ((lines[j] = pvSrc.ReadUTF8StringSafe()).Length >= 80) - return; - - book.Pages[index].Lines = lines; - } - else - { - return; - } - } - else - { + if (index < 1 || index > book.PagesCount) return; - } + + --index; + + int lineCount = pvSrc.ReadUInt16(); + + if (lineCount > 8) + return; + + string[] lines = new string[lineCount]; + + for (int j = 0; j < lineCount; ++j) + if ((lines[j] = pvSrc.ReadUTF8StringSafe()).Length >= 80) + return; + + book.Pages[index].Lines = lines; } } @@ -418,58 +396,4 @@ namespace Server.Items Content = 0x08 } } - - public sealed class BookPageDetails : Packet - { - public BookPageDetails(BaseBook book) : base(0x66) - { - EnsureCapacity(256); - - m_Stream.Write(book.Serial); - m_Stream.Write((ushort)book.PagesCount); - - for (int i = 0; i < book.PagesCount; ++i) - { - BookPageInfo page = book.Pages[i]; - - m_Stream.Write((ushort)(i + 1)); - m_Stream.Write((ushort)page.Lines.Length); - - for (int j = 0; j < page.Lines.Length; ++j) - { - byte[] buffer = Utility.UTF8.GetBytes(page.Lines[j]); - - m_Stream.Write(buffer, 0, buffer.Length); - m_Stream.Write((byte)0); - } - } - } - } - - public sealed class BookHeader : Packet - { - public BookHeader(Mobile from, BaseBook book) : base(0xD4) - { - string title = book.Title ?? ""; - string author = book.Author ?? ""; - - byte[] titleBuffer = Utility.UTF8.GetBytes(title); - byte[] authorBuffer = Utility.UTF8.GetBytes(author); - - EnsureCapacity(15 + titleBuffer.Length + authorBuffer.Length); - - m_Stream.Write(book.Serial); - m_Stream.Write(true); - m_Stream.Write(book.Writable && from.InRange(book.GetWorldLocation(), 1)); - m_Stream.Write((ushort)book.PagesCount); - - m_Stream.Write((ushort)(titleBuffer.Length + 1)); - m_Stream.Write(titleBuffer, 0, titleBuffer.Length); - m_Stream.Write((byte)0); // terminate - - m_Stream.Write((ushort)(authorBuffer.Length + 1)); - m_Stream.Write(authorBuffer, 0, authorBuffer.Length); - m_Stream.Write((byte)0); // terminate - } - } } diff --git a/Projects/Scripts/Items/Books/BrownBook.cs b/Projects/Scripts/Items/Books/BrownBook.cs index f6900edf3..611c134ba 100644 --- a/Projects/Scripts/Items/Books/BrownBook.cs +++ b/Projects/Scripts/Items/Books/BrownBook.cs @@ -13,8 +13,8 @@ namespace Server.Items } [Constructible] - public BrownBook(string title, string author, int pageCount, bool writable) : base(0xFEF, title, author, pageCount, - writable) + public BrownBook(string title, string author, int pageCount, bool writable) : + base(0xFEF, title, author, pageCount, writable) { } @@ -41,4 +41,4 @@ namespace Server.Items writer.Write(0); // version } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Items/Books/Packets.cs b/Projects/Scripts/Items/Books/Packets.cs new file mode 100644 index 000000000..49a78fc2d --- /dev/null +++ b/Projects/Scripts/Items/Books/Packets.cs @@ -0,0 +1,80 @@ +using System; +using Server.Buffers; +using Server.Items; + +namespace Server.Network +{ + public static class BookPackets + { + public static void SendBookPageDetails(NetState ns, BaseBook book) + { + if (ns == null) + return; + + // 80 chars per line (240 bytes) + // 8 lines per page + // Max: 77049 bytes + int length = 9; + + for (int i = 0; i < book.PagesCount; i++) + length += 1926 * book.Pages[i].Lines.Length; + + SpanWriter writer = new SpanWriter(stackalloc byte[length]); + writer.Write((byte)0x66); // Packet ID + writer.Position += 2; // Dynamic Length + + writer.Write(book.Serial); + writer.Write((ushort)book.PagesCount); + + for (int i = 0; i < book.PagesCount; i++) + { + BookPageInfo page = book.Pages[i]; + length = Math.Min(page.Lines.Length, 8); + + writer.Write((ushort)(i + 1)); + writer.Write((ushort)length); + + for (int j = 0; j < length; j++) + { + string line = page.Lines[j]; + writer.WriteUTF8Null(line); + } + } + + writer.Position = 1; + writer.Write((ushort)writer.WrittenCount); + + ns.Send(writer.Span); + } + + public static void SendBookHeader(NetState ns, Mobile from, BaseBook book) + { + if (ns == null) + return; + + string title = book.Title ?? ""; + string author = book.Author ?? ""; + + int length = 17 + title.Length + author.Length; + SpanWriter writer = new SpanWriter(stackalloc byte[length]); + writer.Write((byte)0xD4); // Packet ID + writer.Position += 2; // Dynamic Length + + writer.Write(book.Serial); + writer.Write((byte)0x1); // true + writer.Write(book.Writable && from.InRange(book.GetWorldLocation(), 1)); + writer.Write((ushort)book.PagesCount); + + writer.Write((ushort)title.Length + 1); + writer.WriteAsciiNull(title); + + writer.Write((ushort)author.Length + 1); + writer.WriteAsciiNull(author); + + writer.Position = 1; + writer.Write((ushort)writer.WrittenCount); + + ns.Send(writer.Span); + } + } +} diff --git a/Projects/Scripts/Items/Books/RedBook.cs b/Projects/Scripts/Items/Books/RedBook.cs index 2ee8b7d15..d0ddb7bc7 100644 --- a/Projects/Scripts/Items/Books/RedBook.cs +++ b/Projects/Scripts/Items/Books/RedBook.cs @@ -13,8 +13,8 @@ namespace Server.Items } [Constructible] - public RedBook(string title, string author, int pageCount, bool writable) : base(0xFF1, title, author, pageCount, - writable) + public RedBook(string title, string author, int pageCount, bool writable) : + base(0xFF1, title, author, pageCount, writable) { } @@ -41,4 +41,4 @@ namespace Server.Items writer.Write(0); // version } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Items/Books/TanBook.cs b/Projects/Scripts/Items/Books/TanBook.cs index 5be5297b0..ef604c743 100644 --- a/Projects/Scripts/Items/Books/TanBook.cs +++ b/Projects/Scripts/Items/Books/TanBook.cs @@ -13,8 +13,8 @@ namespace Server.Items } [Constructible] - public TanBook(string title, string author, int pageCount, bool writable) : base(0xFF0, title, author, pageCount, - writable) + public TanBook(string title, string author, int pageCount, bool writable) : + base(0xFF0, title, author, pageCount, writable) { } @@ -41,4 +41,4 @@ namespace Server.Items writer.Write(0); // version } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Items/Clothing/BaseClothing.cs b/Projects/Scripts/Items/Clothing/BaseClothing.cs index 06ee87907..ac7ddf454 100644 --- a/Projects/Scripts/Items/Clothing/BaseClothing.cs +++ b/Projects/Scripts/Items/Clothing/BaseClothing.cs @@ -724,9 +724,7 @@ namespace Server.Items int number; if (Name == null) - { number = LabelNumber; - } else { LabelTo(from, Name); @@ -736,9 +734,7 @@ namespace Server.Items if (attrs.Count == 0 && Crafter == null && Name != null) return; - EquipmentInfo eqInfo = new EquipmentInfo(number, m_Crafter, false, attrs.ToArray()); - - from.Send(new DisplayEquipmentInfo(this, eqInfo)); + EquipmentPackets.SendDisplayEquipmentInfo(from.NetState, this, number, m_Crafter, false, attrs); } public virtual void AddEquipInfoAttributes(Mobile from, List attrs) @@ -904,25 +900,13 @@ namespace Server.Items else m_Resource = DefaultResource; - if (GetSaveFlag(flags, SaveFlag.Attributes)) - Attributes = new AosAttributes(this, reader); - else - Attributes = new AosAttributes(this); + Attributes = GetSaveFlag(flags, SaveFlag.Attributes) ? new AosAttributes(this, reader) : new AosAttributes(this); - if (GetSaveFlag(flags, SaveFlag.ClothingAttributes)) - ClothingAttributes = new AosArmorAttributes(this, reader); - else - ClothingAttributes = new AosArmorAttributes(this); + ClothingAttributes = GetSaveFlag(flags, SaveFlag.ClothingAttributes) ? new AosArmorAttributes(this, reader) : new AosArmorAttributes(this); - if (GetSaveFlag(flags, SaveFlag.SkillBonuses)) - SkillBonuses = new AosSkillBonuses(this, reader); - else - SkillBonuses = new AosSkillBonuses(this); + SkillBonuses = GetSaveFlag(flags, SaveFlag.SkillBonuses) ? new AosSkillBonuses(this, reader) : new AosSkillBonuses(this); - if (GetSaveFlag(flags, SaveFlag.Resistances)) - Resistances = new AosElementAttributes(this, reader); - else - Resistances = new AosElementAttributes(this); + Resistances = GetSaveFlag(flags, SaveFlag.Resistances) ? new AosElementAttributes(this, reader) : new AosElementAttributes(this); if (GetSaveFlag(flags, SaveFlag.MaxHitPoints)) m_MaxHitPoints = reader.ReadEncodedInt(); @@ -943,8 +927,7 @@ namespace Server.Items else m_StrReq = -1; - if (GetSaveFlag(flags, SaveFlag.PlayerConstructed)) - PlayerConstructed = true; + PlayerConstructed |= GetSaveFlag(flags, SaveFlag.PlayerConstructed); break; } @@ -982,8 +965,7 @@ namespace Server.Items } } - if (version < 2) - PlayerConstructed = true; // we don't know, so, assume it's crafted + PlayerConstructed |= version < 2; // we don't know, so, assume it's crafted if (version < 3) { diff --git a/Projects/Scripts/Items/Clothing/Hats.cs b/Projects/Scripts/Items/Clothing/Hats.cs index 122a4c086..45d17ad24 100644 --- a/Projects/Scripts/Items/Clothing/Hats.cs +++ b/Projects/Scripts/Items/Clothing/Hats.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using Server.Engines.Craft; using Server.Misc; -using Server.Network; namespace Server.Items { diff --git a/Projects/Scripts/Items/Containers/Container.cs b/Projects/Scripts/Items/Containers/Container.cs index 5dec60a0c..1d0186189 100644 --- a/Projects/Scripts/Items/Containers/Container.cs +++ b/Projects/Scripts/Items/Containers/Container.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using Server.ContextMenus; using Server.Mobiles; using Server.Multis; @@ -16,40 +17,17 @@ namespace Server.Items { } - public override int DefaultMaxWeight - { - get - { - if (IsSecure) - return 0; + public override int DefaultMaxWeight => IsSecure ? 0 : base.DefaultMaxWeight; - return base.DefaultMaxWeight; - } - } + public override bool IsAccessibleTo(Mobile m) => + BaseHouse.CheckAccessible(m, this) && base.IsAccessibleTo(m); - public override bool IsAccessibleTo(Mobile m) - { - if (!BaseHouse.CheckAccessible(m, this)) - return false; + public override bool CheckHold(Mobile m, Item item, bool message, bool checkItems, int plusItems, int plusWeight) => + (!IsSecure || BaseHouse.CheckHold(m, this, item, message, checkItems, plusItems, plusWeight)) && + base.CheckHold(m, item, message, checkItems, plusItems, plusWeight); - return base.IsAccessibleTo(m); - } - - public override bool CheckHold(Mobile m, Item item, bool message, bool checkItems, int plusItems, int plusWeight) - { - if (IsSecure && !BaseHouse.CheckHold(m, this, item, message, checkItems, plusItems, plusWeight)) - return false; - - return base.CheckHold(m, item, message, checkItems, plusItems, plusWeight); - } - - public override bool CheckItemUse(Mobile from, Item item) - { - if (IsDecoContainer && item is BaseBook) - return true; - - return base.CheckItemUse(from, item); - } + public override bool CheckItemUse(Mobile from, Item item) => + IsDecoContainer && item is BaseBook || base.CheckItemUse(from, item); public override void GetContextMenuEntries(Mobile from, List list) { @@ -79,13 +57,8 @@ namespace Server.Items List list = Items; - for (int i = 0; i < list.Count; ++i) - { - Item item = list[i]; - - if (!(item is Container) && item.StackWith(from, dropped, false)) - return true; - } + if (list.Any(item => !(item is Container) && item.StackWith(from, dropped, false))) + return true; DropItem(dropped); @@ -936,4 +909,4 @@ namespace Server.Items Weight = -1; } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Items/Containers/FillableContainers.cs b/Projects/Scripts/Items/Containers/FillableContainers.cs index 13b08e542..986be77cf 100644 --- a/Projects/Scripts/Items/Containers/FillableContainers.cs +++ b/Projects/Scripts/Items/Containers/FillableContainers.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Server.Mobiles; namespace Server.Items @@ -95,14 +96,7 @@ namespace Server.Items } } - public int GetItemsCount() - { - int count = 0; - - foreach (Item item in Items) count += item.Amount; - - return count; - } + public int GetItemsCount() => Items.Sum(item => item.Amount); public void CheckRespawn() { @@ -1507,7 +1501,9 @@ namespace Server.Items Mobile nearest = null; FillableContent content = null; - foreach (Mobile mob in map.GetMobilesInRange(loc, 20)) + IPooledEnumerable eable = map.GetMobilesInRange(loc, 20); + + foreach (Mobile mob in eable) { if (nearest != null && mob.GetDistanceToSqrt(loc) > nearest.GetDistanceToSqrt(loc) && !(nearest is Cobbler && mob is Provisioner)) @@ -1520,6 +1516,8 @@ namespace Server.Items } } + eable.Free(); + return content; } } diff --git a/Projects/Scripts/Items/Containers/LockableContainer.cs b/Projects/Scripts/Items/Containers/LockableContainer.cs index 783f90b0a..e6b89b306 100644 --- a/Projects/Scripts/Items/Containers/LockableContainer.cs +++ b/Projects/Scripts/Items/Containers/LockableContainer.cs @@ -264,7 +264,7 @@ namespace Server.Items inaccessible = true; } - from.Send(new MessageLocalized(Serial, ItemID, MessageType.Regular, 0x3B2, 3, number, "", "")); + Packets.SendMessageLocalized(from.NetState, Serial, ItemID, MessageType.Regular, 0x3B2, 3, number); } return inaccessible; @@ -323,4 +323,4 @@ namespace Server.Items LabelTo(from, 1041645); //recovered from a shipwreck } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Items/Containers/SalvageBag.cs b/Projects/Scripts/Items/Containers/SalvageBag.cs index cea584359..dad4c4ac7 100644 --- a/Projects/Scripts/Items/Containers/SalvageBag.cs +++ b/Projects/Scripts/Items/Containers/SalvageBag.cs @@ -126,16 +126,11 @@ namespace Server.Items #region Checks - private bool Resmeltables() //Where context menu checks for metal items and dragon barding deeds - { - foreach (Item i in Items) - return i?.Deleted == false && ( - i is BaseWeapon weapon && CraftResources.GetType(weapon.Resource) == CraftResourceType.Metal || - i is BaseArmor armor && CraftResources.GetType(armor.Resource) == CraftResourceType.Metal || - i is DragonBardingDeed); - - return false; - } + private bool Resmeltables() => //Where context menu checks for metal items and dragon barding deeds + Items.Select(i => i?.Deleted == false && + (i is BaseWeapon weapon && CraftResources.GetType(weapon.Resource) == CraftResourceType.Metal || + i is BaseArmor armor && CraftResources.GetType(armor.Resource) == CraftResourceType.Metal || + i is DragonBardingDeed)).FirstOrDefault(); private bool Scissorables() //Where context menu checks for Leather items and cloth items { diff --git a/Projects/Scripts/Items/Containers/TrappableContainer.cs b/Projects/Scripts/Items/Containers/TrappableContainer.cs index c5de08e12..804519d26 100644 --- a/Projects/Scripts/Items/Containers/TrappableContainer.cs +++ b/Projects/Scripts/Items/Containers/TrappableContainer.cs @@ -46,7 +46,7 @@ namespace Server.Items if (Deleted || !to.CanSee(this)) return; - to.Send(new MessageLocalized(Serial, ItemID, MessageType.Regular, hue, 3, number, "", "")); + Packets.SendMessageLocalized(to.NetState, Serial, ItemID, MessageType.Regular, hue, 3, number); } private void SendMessageTo(Mobile to, string text, int hue) @@ -54,7 +54,7 @@ namespace Server.Items if (Deleted || !to.CanSee(this)) return; - to.Send(new UnicodeMessage(Serial, ItemID, MessageType.Regular, hue, 3, "ENU", "", text)); + Packets.SendUnicodeMessage(to.NetState,Serial, ItemID, MessageType.Regular, hue, 3, "ENU", "", text); } public virtual bool ExecuteTrap(Mobile from) @@ -91,7 +91,7 @@ namespace Server.Items from.LocalOverheadMessage(MessageType.Regular, 0x2A, 503000); } - Effects.SendLocationEffect(loc, facet, 0x36BD, 15, 10); + Effects.SendLocationEffect(loc, facet, 0x36BD, 15); Effects.PlaySound(loc, facet, 0x307); break; @@ -129,7 +129,7 @@ namespace Server.Items AOS.Damage(from, damage, 100, 0, 0, 0, 0); - // A dart imbeds itself in your flesh! + // A dart embeds itself in your flesh! from.LocalOverheadMessage(MessageType.Regular, 0x62, 502998); } @@ -221,4 +221,4 @@ namespace Server.Items } } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Items/Containers/TreasureMapChest.cs b/Projects/Scripts/Items/Containers/TreasureMapChest.cs index a0ccfcde4..8a4432c52 100644 --- a/Projects/Scripts/Items/Containers/TreasureMapChest.cs +++ b/Projects/Scripts/Items/Containers/TreasureMapChest.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Server.ContextMenus; using Server.Engines.PartySystem; using Server.Gumps; @@ -39,7 +40,7 @@ namespace Server.Items public override int LabelNumber => 3000541; - public static Type[] Artifacts{ get; } = + public static Type[] Artifacts { get; } = { typeof(CandelabraOfSouls), typeof(GoldBricks), typeof(PhillipsWoodenSteed), typeof(ArcticDeathDealer), typeof(BlazeOfDeath), typeof(BurglarsBandana), @@ -51,18 +52,18 @@ namespace Server.Items }; [CommandProperty(AccessLevel.GameMaster)] - public int Level{ get; set; } + public int Level { get; set; } [CommandProperty(AccessLevel.GameMaster)] - public Mobile Owner{ get; set; } + public Mobile Owner { get; set; } [CommandProperty(AccessLevel.GameMaster)] - public DateTime DeleteTime{ get; private set; } + public DateTime DeleteTime { get; private set; } [CommandProperty(AccessLevel.GameMaster)] - public bool Temporary{ get; set; } + public bool Temporary { get; set; } - public List Guardians{ get; private set; } + public List Guardians { get; private set; } public override bool IsDecoContainer => false; @@ -196,18 +197,11 @@ namespace Server.Items }; } else - { numberItems = level * 6; - } for (int i = 0; i < numberItems; ++i) { - Item item; - - if (Core.AOS) - item = Loot.RandomArmorOrShieldOrWeaponOrJewelry(); - else - item = Loot.RandomArmorOrShieldOrWeapon(); + Item item = Core.AOS ? Loot.RandomArmorOrShieldOrWeaponOrJewelry() : Loot.RandomArmorOrShieldOrWeapon(); if (item is BaseWeapon weapon) { @@ -296,13 +290,12 @@ namespace Server.Items if (Level == 0 && from.AccessLevel < AccessLevel.GameMaster) { - foreach (Mobile m in Guardians) - if (m.Alive) - { - from.SendLocalizedMessage( - 1046448); // You must first kill the guardians before you may open this chest. - return true; - } + if (Guardians.Any(m => m.Alive)) + { + from.SendLocalizedMessage( + 1046448); // You must first kill the guardians before you may open this chest. + return true; + } LockPick(from); return false; @@ -395,29 +388,29 @@ namespace Server.Items switch (version) { case 2: - { - Guardians = reader.ReadStrongMobileList(); - Temporary = reader.ReadBool(); + { + Guardians = reader.ReadStrongMobileList(); + Temporary = reader.ReadBool(); - goto case 1; - } + goto case 1; + } case 1: - { - Owner = reader.ReadMobile(); + { + Owner = reader.ReadMobile(); - goto case 0; - } + goto case 0; + } case 0: - { - Level = reader.ReadInt(); - DeleteTime = reader.ReadDeltaTime(); - m_Lifted = reader.ReadStrongItemList(); + { + Level = reader.ReadInt(); + DeleteTime = reader.ReadDeltaTime(); + m_Lifted = reader.ReadStrongItemList(); - if (version < 2) - Guardians = new List(); + if (version < 2) + Guardians = new List(); - break; - } + break; + } } if (!Temporary) diff --git a/Projects/Scripts/Items/Deeds/HairRestylingDeed.cs b/Projects/Scripts/Items/Deeds/HairRestylingDeed.cs index 19eecb70c..a7026917f 100644 --- a/Projects/Scripts/Items/Deeds/HairRestylingDeed.cs +++ b/Projects/Scripts/Items/Deeds/HairRestylingDeed.cs @@ -56,9 +56,7 @@ namespace Server.Items new[] { 1074393, 1074390, 0x2fd0, 0x2fcd, 0xedde, 0xc6cb } // buns, long }; -/* - racial arrays are: cliloc_F, cliloc_M, ItemID_F, ItemID_M, gump_img_F, gump_img_M -*/ + // racial arrays are: cliloc_F, cliloc_M, ItemID_F, ItemID_M, gump_img_F, gump_img_M private int[][] HumanArray = /* why on earth cant these utilies be consistent with hex/dec */ { new[] { 0 }, @@ -73,10 +71,8 @@ namespace Server.Items new[] { 1011050, 1011050, 0x204A, 0x204A, 0xED29, 0xED29 }, // Topknot new[] { 1011396, 1011396, 0x2047, 0x2047, 0xed25, 0xc618 } // Curly }; -/* - gump data: bgX, bgY, htmlX, htmlY, imgX, imgY, butX, butY -*/ + // gump data: bgX, bgY, htmlX, htmlY, imgX, imgY, butX, butY private int[][] LayoutArray = { new[] { 0 }, /* padding: its more efficient than code to ++ the index/buttonid */ diff --git a/Projects/Scripts/Items/Deeds/HolidayTreeDeed.cs b/Projects/Scripts/Items/Deeds/HolidayTreeDeed.cs index c56b3b341..03ee8f05a 100644 --- a/Projects/Scripts/Items/Deeds/HolidayTreeDeed.cs +++ b/Projects/Scripts/Items/Deeds/HolidayTreeDeed.cs @@ -91,11 +91,11 @@ namespace Server.Items Point3D loc = new Point3D(p); if (p is StaticTarget target) - loc.Z -= TileData.ItemTable[target.ItemID] - .CalcHeight; /* NOTE: OSI does not properly normalize Z positioning here. - * A side affect is that you can only place on floors (due to the CanFit call). - * That functionality may be desired. And so, it's included in this script. - */ + loc.Z -= TileData.ItemTable[target.ItemID].CalcHeight; + /* NOTE: OSI does not properly normalize Z positioning here. + * A side affect is that you can only place on floors (due to the CanFit call). + * That functionality may be desired. And so, it's included in this script. + */ if (ValidatePlacement(from, loc)) EndPlace(from, type, loc); diff --git a/Projects/Scripts/Items/Equipment/EquipmentInfoAttribute.cs b/Projects/Scripts/Items/Equipment/EquipmentInfoAttribute.cs new file mode 100644 index 000000000..6f8ac034c --- /dev/null +++ b/Projects/Scripts/Items/Equipment/EquipmentInfoAttribute.cs @@ -0,0 +1,15 @@ +namespace Server.Items +{ + public class EquipInfoAttribute + { + public EquipInfoAttribute(int number, int charges = -1) + { + Number = number; + Charges = charges; + } + + public int Number { get; } + + public int Charges { get; } + } +} diff --git a/Projects/Scripts/Items/Equipment/Packets.cs b/Projects/Scripts/Items/Equipment/Packets.cs new file mode 100644 index 000000000..607227df7 --- /dev/null +++ b/Projects/Scripts/Items/Equipment/Packets.cs @@ -0,0 +1,56 @@ +using System.Collections.Generic; +using Server.Buffers; +using Server.Items; + +namespace Server.Network +{ + public static class EquipmentPackets + { + public static void SendDisplayEquipmentInfo(NetState ns, Item item, int number, Mobile crafter, bool unidentified, ICollection attrs) + { + int packetLength = 17 + + (crafter != null ? 6 + crafter.RawName?.Length ?? 0 : 0) + + (unidentified ? 4 : 0) + attrs.Count * 6; + + SpanWriter writer = new SpanWriter(stackalloc byte[packetLength]); + + writer.Write((byte)0xBF); // Extended Command Packet ID + writer.Write((ushort)packetLength); // Dynamic Length + + writer.Write((short)0x10); // Command + writer.Write(item.Serial); + writer.Write(number); + + if (crafter != null) + { + // TODO: We should not be referencing the crafter. + // They could have been deleted and the crafted by should still show up. + string name = crafter.RawName; + + writer.Write(-3); + + if (name == null) + writer.Write((ushort)0); + else + { + int length = name.Length; + writer.Write((ushort)length); + writer.WriteAsciiFixed(name, length); + } + } + + if (unidentified) + writer.Write(-4); + + foreach (EquipInfoAttribute attr in attrs) + { + writer.Write(attr.Number); + writer.Write((short)attr.Charges); + } + + writer.Write(-1); + + ns.Send(writer.Span); + } + } +} diff --git a/Projects/Scripts/Items/Food/CookableFood.cs b/Projects/Scripts/Items/Food/CookableFood.cs index cb03e9e15..66d3e86a6 100644 --- a/Projects/Scripts/Items/Food/CookableFood.cs +++ b/Projects/Scripts/Items/Food/CookableFood.cs @@ -43,13 +43,13 @@ namespace Server.Items } #if false - public override void OnDoubleClick( Mobile from ) - { - if ( !Movable ) - return; + public override void OnDoubleClick( Mobile from ) + { + if ( !Movable ) + return; - from.Target = new InternalTarget( this ); - } + from.Target = new InternalTarget( this ); + } #endif public static bool IsHeatSource(object targeted) @@ -63,22 +63,13 @@ namespace Server.Items else return false; - if (itemID >= 0xDE3 && itemID <= 0xDE9) - return true; // Campfire - if (itemID >= 0x461 && itemID <= 0x48E) - return true; // Sandstone oven/fireplace - if (itemID >= 0x92B && itemID <= 0x96C) - return true; // Stone oven/fireplace - if (itemID == 0xFAC) - return true; // Firepit - if (itemID >= 0x184A && itemID <= 0x184C) - return true; // Heating stand (left) - if (itemID >= 0x184E && itemID <= 0x1850) - return true; // Heating stand (right) - if (itemID >= 0x398C && itemID <= 0x399F) - return true; // Fire field - - return false; + return itemID == 0xFAC || + itemID >= 0xDE3 && itemID <= 0xDE9 || + itemID >= 0x461 && itemID <= 0x48E || + itemID >= 0x92B && itemID <= 0x96C || + itemID >= 0x184A && itemID <= 0x184C || + itemID >= 0x184E && itemID <= 0x1850 || + itemID >= 0x398C && itemID <= 0x399F; } private class InternalTarget : Target @@ -103,9 +94,7 @@ namespace Server.Items t.Start(); } else - { from.SendLocalizedMessage(500119); // You must wait to perform another action - } } } @@ -143,9 +132,7 @@ namespace Server.Items m_From.PlaySound(0x57); } else - { m_From.SendLocalizedMessage(500686); // You burn the food to a crisp! It's ruined. - } } } } diff --git a/Projects/Scripts/Items/Food/Cooking.cs b/Projects/Scripts/Items/Food/Cooking.cs index ca8a09e2a..aa68f6c75 100644 --- a/Projects/Scripts/Items/Food/Cooking.cs +++ b/Projects/Scripts/Items/Food/Cooking.cs @@ -47,13 +47,13 @@ namespace Server.Items } #if false - public override void OnDoubleClick( Mobile from ) - { - if ( !Movable ) - return; + public override void OnDoubleClick( Mobile from ) + { + if ( !Movable ) + return; - from.Target = new InternalTarget( this ); - } + from.Target = new InternalTarget( this ); + } #endif private class InternalTarget : Target @@ -135,13 +135,13 @@ namespace Server.Items } #if false - public override void OnDoubleClick( Mobile from ) - { - if ( !Movable ) - return; + public override void OnDoubleClick( Mobile from ) + { + if ( !Movable ) + return; - from.Target = new InternalTarget( this ); - } + from.Target = new InternalTarget( this ); + } #endif private class InternalTarget : Target @@ -454,9 +454,9 @@ namespace Server.Items ++ItemID; #if false - this.Delete(); + this.Delete(); - from.AddToBackpack( new SackFlourOpen() ); + from.AddToBackpack( new SackFlourOpen() ); #endif } } diff --git a/Projects/Scripts/Items/Games/BaseBoard.cs b/Projects/Scripts/Items/Games/BaseBoard.cs index fd292b550..d7ecddcd4 100644 --- a/Projects/Scripts/Items/Games/BaseBoard.cs +++ b/Projects/Scripts/Items/Games/BaseBoard.cs @@ -72,17 +72,13 @@ namespace Server.Items { if (dropped is BasePiece piece && piece.Board == this && base.OnDragDropInto(from, dropped, point)) { - Packet p = new PlaySound(0x127, GetWorldLocation()); - - p.Acquire(); + Point3D loc = GetWorldLocation(); if (RootParent == from) - from.Send(p); + Packets.SendPlaySound(from.NetState, 0x127, loc); else foreach (NetState state in GetClientsInRange(2)) - state.Send(p); - - p.Release(); + Packets.SendPlaySound(state, 0x127, loc); return true; } diff --git a/Projects/Scripts/Items/Games/Dices.cs b/Projects/Scripts/Items/Games/Dices.cs index d065caaed..29bc2d7bf 100644 --- a/Projects/Scripts/Items/Games/Dices.cs +++ b/Projects/Scripts/Items/Games/Dices.cs @@ -21,10 +21,8 @@ namespace Server.Items public override void OnDoubleClick(Mobile from) { - if (!from.InRange(GetWorldLocation(), 2)) - return; - - Roll(from); + if (from.InRange(GetWorldLocation(), 2)) + Roll(from); } public void Roll(Mobile from) @@ -45,4 +43,4 @@ namespace Server.Items int version = reader.ReadInt(); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Items/Games/Mahjong/MahjongGame.cs b/Projects/Scripts/Items/Games/Mahjong/MahjongGame.cs index cefbd322a..ac0d77495 100644 --- a/Projects/Scripts/Items/Games/Mahjong/MahjongGame.cs +++ b/Projects/Scripts/Items/Games/Mahjong/MahjongGame.cs @@ -76,7 +76,7 @@ namespace Server.Engines.Mahjong m_SpectatorVision = value; if (Players.IsInGamePlayer(Players.DealerPosition)) - Players.Dealer.Send(new MahjongGeneralInfo(this)); + MahjongPackets.SendMahjongGeneralInfo(Players.Dealer.NetState, this); Players.SendTilesPacket(false, true); @@ -292,4 +292,4 @@ namespace Server.Engines.Mahjong } } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Items/Games/Mahjong/MahjongPacketHandlers.cs b/Projects/Scripts/Items/Games/Mahjong/MahjongPacketHandlers.cs index 9683f3363..d3a69f0cd 100644 --- a/Projects/Scripts/Items/Games/Mahjong/MahjongPacketHandlers.cs +++ b/Projects/Scripts/Items/Games/Mahjong/MahjongPacketHandlers.cs @@ -6,7 +6,7 @@ namespace Server.Engines.Mahjong public sealed class MahjongPacketHandlers { - private static OnMahjongPacketReceive[] m_SubCommandDelegates = new OnMahjongPacketReceive[0x100]; + private static readonly OnMahjongPacketReceive[] m_SubCommandDelegates = new OnMahjongPacketReceive[0x100]; public static void RegisterSubCommand(int subCmd, OnMahjongPacketReceive onReceive) { @@ -80,12 +80,7 @@ namespace Server.Engines.Mahjong public static void ExitGame(MahjongGame game, NetState state, PacketReader pvSrc) { - if (game == null) - return; - - Mobile from = state.Mobile; - - game.Players.LeaveGame(from); + game?.Players.LeaveGame(state.Mobile); } public static void GivePoints(MahjongGame game, NetState state, PacketReader pvSrc) @@ -230,4 +225,4 @@ namespace Server.Engines.Mahjong game.DealerIndicator.Move(new Point2D(x, y), direction, wind); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Items/Games/Mahjong/MahjongPlayers.cs b/Projects/Scripts/Items/Games/Mahjong/MahjongPlayers.cs index dfb2f99bc..0bd9501c7 100644 --- a/Projects/Scripts/Items/Games/Mahjong/MahjongPlayers.cs +++ b/Projects/Scripts/Items/Games/Mahjong/MahjongPlayers.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; namespace Server.Engines.Mahjong { @@ -82,28 +83,13 @@ namespace Server.Engines.Mahjong return m_InGame[index]; } - public bool IsInGamePlayer(Mobile mobile) - { - int index = GetPlayerIndex(mobile); - - return IsInGamePlayer(index); - } + public bool IsInGamePlayer(Mobile mobile) => IsInGamePlayer(GetPlayerIndex(mobile)); public bool IsSpectator(Mobile mobile) => m_Spectators.Contains(mobile); - public int GetScore(int index) - { - if (index < 0 || index >= m_Scores.Length) - return 0; - return m_Scores[index]; - } + public bool IsSpectator(Mobile mobile) => m_Spectators.Contains(mobile); - public bool IsPublic(int index) - { - if (index < 0 || index >= m_PublicHand.Length) - return false; - return m_PublicHand[index]; - } + public bool IsPublic(int index) => index >= 0 && index < m_PublicHand.Length && m_PublicHand[index]; public void SetPublic(int index, bool value) { @@ -122,10 +108,7 @@ namespace Server.Engines.Mahjong { List list = new List(); - if (players) - for (int i = 0; i < m_Players.Length; i++) - if (IsInGamePlayer(i)) - list.Add(m_Players[i]); + if (players) list.AddRange(m_Players.Where((t, i) => IsInGamePlayer(i))); if (spectators) list.AddRange(m_Spectators); @@ -169,7 +152,7 @@ namespace Server.Engines.Mahjong { m_InGame[i] = false; - player.Send(new MahjongRelieve(Game)); + MahjongPackets.SendMahjongRelieve(player.NetState, Game); SendPlayerExitMessage(player); UpdateDealer(true); @@ -184,20 +167,16 @@ namespace Server.Engines.Mahjong Mobile mobile = m_Spectators[i]; if (mobile.NetState == null || mobile.Deleted) - { m_Spectators.RemoveAt(i); - } else if (!Game.IsAccessibleTo(mobile) || mobile.Map != Game.Map || !mobile.InRange(Game.GetWorldLocation(), 5)) { m_Spectators.RemoveAt(i); - mobile.Send(new MahjongRelieve(Game)); + MahjongPackets.SendMahjongRelieve(mobile.NetState, Game); } else - { i++; - } } if (removed && !UpdateSpectators()) @@ -276,12 +255,12 @@ namespace Server.Engines.Mahjong UpdateDealer(false); if (sendJoinGame) - player.Send(new MahjongJoinGame(Game)); + MahjongPackets.SendMahjongJoinGame(player.NetState, Game); SendPlayersPacket(true, true); - player.Send(new MahjongGeneralInfo(Game)); - player.Send(new MahjongTilesInfo(Game, player)); + MahjongPackets.SendMahjongGeneralInfo(player.NetState, Game); + MahjongPackets.SendMahjongTilesInfo(player.NetState, Game, player); if (DealerPosition == index) SendLocalizedMessage(1062773, player.Name); // ~1_name~ has entered the game as the dealer. @@ -289,14 +268,14 @@ namespace Server.Engines.Mahjong SendLocalizedMessage(1062772, player.Name); // ~1_name~ has entered the game as a player. } - private void AddSpectator(Mobile mobile) + private void AddSpectator(Mobile m) { - if (!IsSpectator(mobile)) m_Spectators.Add(mobile); + if (!IsSpectator(m)) m_Spectators.Add(m); - mobile.Send(new MahjongJoinGame(Game)); - mobile.Send(new MahjongPlayersInfo(Game, mobile)); - mobile.Send(new MahjongGeneralInfo(Game)); - mobile.Send(new MahjongTilesInfo(Game, mobile)); + MahjongPackets.SendMahjongJoinGame(m.NetState, Game); + MahjongPackets.SendMahjongPlayersInfo(m.NetState, Game, m); + MahjongPackets.SendMahjongGeneralInfo(m.NetState, Game); + MahjongPackets.SendMahjongTilesInfo(m.NetState, Game, m); } public void Join(Mobile mobile) @@ -304,9 +283,7 @@ namespace Server.Engines.Mahjong int index = GetPlayerIndex(mobile); if (index >= 0) - { AddPlayer(mobile, index, true); - } else { int nextSeat = GetNextSeat(); @@ -331,9 +308,7 @@ namespace Server.Engines.Mahjong SendPlayersPacket(true, true); } else - { m_Spectators.Remove(player); - } } public void ResetScores(int value) @@ -357,13 +332,11 @@ namespace Server.Engines.Mahjong m_Scores[toPosition] += amount; if (Game.ShowScores) - { SendPlayersPacket(true, true); - } else { - from.Send(new MahjongPlayersInfo(Game, from)); - to.Send(new MahjongPlayersInfo(Game, to)); + MahjongPackets.SendMahjongPlayersInfo(from.NetState, Game, from); + MahjongPackets.SendMahjongPlayersInfo(to.NetState, Game, to); } SendLocalizedMessage(1062774, @@ -377,7 +350,7 @@ namespace Server.Engines.Mahjong return; if (m_InGame[index]) - player.Send(new MahjongRelieve(Game)); + MahjongPackets.SendMahjongRelieve(player.NetState, Game); m_Players[index] = null; @@ -401,9 +374,9 @@ namespace Server.Engines.Mahjong DealerPosition = index; if (IsInGamePlayer(oldDealer)) - m_Players[oldDealer].Send(new MahjongPlayersInfo(Game, m_Players[oldDealer])); + MahjongPackets.SendMahjongPlayersInfo(m_Players[oldDealer].NetState, Game, m_Players[oldDealer]); - to.Send(new MahjongPlayersInfo(Game, to)); + MahjongPackets.SendMahjongPlayersInfo(to.NetState, Game, to); SendDealerChangedMessage(); } @@ -422,36 +395,25 @@ namespace Server.Engines.Mahjong public void SendPlayersPacket(bool players, bool spectators) { foreach (Mobile mobile in GetInGameMobiles(players, spectators)) - mobile.Send(new MahjongPlayersInfo(Game, mobile)); + MahjongPackets.SendMahjongPlayersInfo(mobile.NetState, Game, mobile); } public void SendGeneralPacket(bool players, bool spectators) { - List mobiles = GetInGameMobiles(players, spectators); - - if (mobiles.Count == 0) - return; - - MahjongGeneralInfo generalInfo = new MahjongGeneralInfo(Game); - - generalInfo.Acquire(); - - foreach (Mobile mobile in mobiles) - mobile.Send(generalInfo); - - generalInfo.Release(); + foreach (Mobile mobile in GetInGameMobiles(players, spectators)) + MahjongPackets.SendMahjongGeneralInfo(mobile.NetState, Game); } public void SendTilesPacket(bool players, bool spectators) { foreach (Mobile mobile in GetInGameMobiles(players, spectators)) - mobile.Send(new MahjongTilesInfo(Game, mobile)); + MahjongPackets.SendMahjongTilesInfo(mobile.NetState, Game, mobile); } public void SendTilePacket(MahjongTile tile, bool players, bool spectators) { foreach (Mobile mobile in GetInGameMobiles(players, spectators)) - mobile.Send(new MahjongTileInfo(tile, mobile)); + MahjongPackets.SendMahjongTileInfo(mobile.NetState, tile, mobile); } public void SendRelievePacket(bool players, bool spectators) @@ -461,14 +423,8 @@ namespace Server.Engines.Mahjong if (mobiles.Count == 0) return; - MahjongRelieve relieve = new MahjongRelieve(Game); - - relieve.Acquire(); - foreach (Mobile mobile in mobiles) - mobile.Send(relieve); - - relieve.Release(); + MahjongPackets.SendMahjongRelieve(mobile.NetState, Game); } public void SendLocalizedMessage(int number) diff --git a/Projects/Scripts/Items/Games/Mahjong/Packets.cs b/Projects/Scripts/Items/Games/Mahjong/Packets.cs index 39be5ea77..235083757 100644 --- a/Projects/Scripts/Items/Games/Mahjong/Packets.cs +++ b/Projects/Scripts/Items/Games/Mahjong/Packets.cs @@ -1,76 +1,78 @@ -using System.IO; +using Server.Buffers; using Server.Network; namespace Server.Engines.Mahjong { - public sealed class MahjongJoinGame : Packet + public static class MahjongPackets { - public MahjongJoinGame(MahjongGame game) : base(0xDA) + public static void SendMahjongJoinGame(NetState ns, MahjongGame game) { - EnsureCapacity(9); + if (ns == null) + return; - m_Stream.Write(game.Serial); - m_Stream.Write((byte)0); - m_Stream.Write((byte)0x19); + SpanWriter writer = new SpanWriter(stackalloc byte[9]); + writer.Write((byte)0xDA); // Packet ID + writer.Write((ushort)0x09); // Dynamic Length + + writer.Write(game.Serial); + writer.Write((short)0x19); + + ns.Send(writer.Span); } - } - public sealed class MahjongPlayersInfo : Packet - { - public MahjongPlayersInfo(MahjongGame game, Mobile to) : base(0xDA) + public static void SendMahjongPlayersInfo(NetState ns, MahjongGame game, Mobile to) { + if (ns == null) + return; + MahjongPlayers players = game.Players; + SpanWriter writer = new SpanWriter(stackalloc byte[11 + 45 * players.Seats]); + writer.Write((byte)0xDA); // Packet ID + writer.Position += 2; // Dynamic Length - EnsureCapacity(11 + 45 * players.Seats); + writer.Write(game.Serial); + writer.Write((short)0x02); + writer.Write((short)players.Seats); - m_Stream.Write(game.Serial); - m_Stream.Write((byte)0); - m_Stream.Write((byte)0x2); - - m_Stream.Write((byte)0); - m_Stream.Write((byte)players.Seats); - - int n = 0; + short n = 0; for (int i = 0; i < players.Seats; i++) { Mobile mobile = players.GetPlayer(i); if (mobile != null) { - m_Stream.Write(mobile.Serial); - m_Stream.Write(players.DealerPosition == i ? (byte)0x1 : (byte)0x2); - m_Stream.Write((byte)i); + writer.Write(mobile.Serial); + writer.Write(players.DealerPosition == i ? (byte)0x1 : (byte)0x2); + writer.Write((byte)i); if (game.ShowScores || mobile == to) - m_Stream.Write(players.GetScore(i)); + writer.Write(players.GetScore(i)); else - m_Stream.Write(0); + writer.Position++; // writer.Write(0); - m_Stream.Write((short)0); - m_Stream.Write((byte)0); + writer.Position += 3; - m_Stream.Write(players.IsPublic(i)); + writer.Write(players.IsPublic(i)); - m_Stream.WriteAsciiFixed(mobile.Name, 30); - m_Stream.Write(!players.IsInGamePlayer(i)); + writer.WriteAsciiFixed(mobile.Name, 30); + writer.Write(!players.IsInGamePlayer(i)); n++; } else if (game.ShowScores) { - m_Stream.Write(0); - m_Stream.Write((byte)0x2); - m_Stream.Write((byte)i); + writer.Position++; // writer.Write(0); + writer.Write((byte)0x2); + writer.Write((byte)i); - m_Stream.Write(players.GetScore(i)); + writer.Write(players.GetScore(i)); - m_Stream.Write((short)0); - m_Stream.Write((byte)0); + writer.Position += 3; - m_Stream.Write(players.IsPublic(i)); + writer.Write(players.IsPublic(i)); - m_Stream.WriteAsciiFixed("", 30); - m_Stream.Write(true); + writer.Position += 30; //writer.WriteAsciiFixed("", 30); + writer.Write((byte)0x1); // true n++; } @@ -78,58 +80,66 @@ namespace Server.Engines.Mahjong if (n != players.Seats) { - m_Stream.Seek(10, SeekOrigin.Begin); - m_Stream.Write((byte)n); + writer.Position = 9; + writer.Write(n); } + + writer.Position = 1; + writer.Write((short)writer.WrittenCount); + ns.Send(writer.Span); } - } - public sealed class MahjongGeneralInfo : Packet - { - public MahjongGeneralInfo(MahjongGame game) : base(0xDA) + public static void SendMahjongGeneralInfo(NetState ns, MahjongGame game) { - EnsureCapacity(13); + if (ns == null) + return; - m_Stream.Write(game.Serial); - m_Stream.Write((byte)0); - m_Stream.Write((byte)0x5); + SpanWriter writer = new SpanWriter(stackalloc byte[25]); + writer.Write((byte)0xDA); // Packet ID + writer.Write((ushort)25); // Dynamic Length - m_Stream.Write((short)0); - m_Stream.Write((byte)0); + writer.Write(game.Serial); + writer.Write((short)0x05); - m_Stream.Write((byte)((game.ShowScores ? 0x1 : 0x0) | (game.SpectatorVision ? 0x2 : 0x0))); + writer.Position += 3; - m_Stream.Write((byte)game.Dices.First); - m_Stream.Write((byte)game.Dices.Second); + writer.Write((byte)((game.ShowScores ? 0x1 : 0x0) | (game.SpectatorVision ? 0x2 : 0x0))); - m_Stream.Write((byte)game.DealerIndicator.Wind); - m_Stream.Write((short)game.DealerIndicator.Position.Y); - m_Stream.Write((short)game.DealerIndicator.Position.X); - m_Stream.Write((byte)game.DealerIndicator.Direction); + writer.Write((byte)game.Dices.First); + writer.Write((byte)game.Dices.Second); - m_Stream.Write((short)game.WallBreakIndicator.Position.Y); - m_Stream.Write((short)game.WallBreakIndicator.Position.X); + writer.Write((byte)game.DealerIndicator.Wind); + writer.Write((short)game.DealerIndicator.Position.Y); + writer.Write((short)game.DealerIndicator.Position.X); + writer.Write((byte)game.DealerIndicator.Direction); + + writer.Write((short)game.WallBreakIndicator.Position.Y); + writer.Write((short)game.WallBreakIndicator.Position.X); + + ns.Send(writer.Span); } - } - public sealed class MahjongTilesInfo : Packet - { - public MahjongTilesInfo(MahjongGame game, Mobile to) : base(0xDA) + public static void SendMahjongTilesInfo(NetState ns, MahjongGame game, Mobile to) { + if (ns == null) + return; + MahjongTile[] tiles = game.Tiles; MahjongPlayers players = game.Players; - EnsureCapacity(11 + 9 * tiles.Length); + int length = 11 + 9 * tiles.Length; + SpanWriter writer = new SpanWriter(stackalloc byte[length]); + writer.Write((byte)0xDA); // Packet ID + writer.Write((short)length); // Dynamic Length - m_Stream.Write(game.Serial); - m_Stream.Write((byte)0); - m_Stream.Write((byte)0x4); + writer.Write(game.Serial); + writer.Write((short)0x4); - m_Stream.Write((short)tiles.Length); + writer.Write((short)tiles.Length); foreach (MahjongTile tile in tiles) { - m_Stream.Write((byte)tile.Number); + writer.Write((byte)tile.Number); if (tile.Flipped) { @@ -137,39 +147,40 @@ namespace Server.Engines.Mahjong if (hand < 0 || players.IsPublic(hand) || players.GetPlayer(hand) == to || game.SpectatorVision && players.IsSpectator(to)) - m_Stream.Write((byte)tile.Value); + writer.Write((byte)tile.Value); else - m_Stream.Write((byte)0); + writer.Position++; } else - { - m_Stream.Write((byte)0); - } + writer.Position++; - m_Stream.Write((short)tile.Position.Y); - m_Stream.Write((short)tile.Position.X); - m_Stream.Write((byte)tile.StackLevel); - m_Stream.Write((byte)tile.Direction); + writer.Write((short)tile.Position.Y); + writer.Write((short)tile.Position.X); + writer.Write((byte)tile.StackLevel); + writer.Write((byte)tile.Direction); - m_Stream.Write(tile.Flipped ? (byte)0x10 : (byte)0x0); + writer.Write(tile.Flipped ? (byte)0x10 : (byte)0x0); } - } - } - public sealed class MahjongTileInfo : Packet - { - public MahjongTileInfo(MahjongTile tile, Mobile to) : base(0xDA) + ns.Send(writer.Span); + } + + public static void SendMahjongTileInfo(NetState ns, MahjongTile tile, Mobile to) { + if (ns == null) + return; + MahjongGame game = tile.Game; MahjongPlayers players = game.Players; - EnsureCapacity(18); + SpanWriter writer = new SpanWriter(stackalloc byte[18]); + writer.Write((byte)0xDA); // Packet ID + writer.Write((short)18); // Dynamic Length - m_Stream.Write(tile.Game.Serial); - m_Stream.Write((byte)0); - m_Stream.Write((byte)0x3); + writer.Write(game.Serial); + writer.Write((short)0x3); - m_Stream.Write((byte)tile.Number); + writer.Write((byte)tile.Number); if (tile.Flipped) { @@ -177,33 +188,36 @@ namespace Server.Engines.Mahjong if (hand < 0 || players.IsPublic(hand) || players.GetPlayer(hand) == to || game.SpectatorVision && players.IsSpectator(to)) - m_Stream.Write((byte)tile.Value); + writer.Write((byte)tile.Value); else - m_Stream.Write((byte)0); + writer.Position++; } else - { - m_Stream.Write((byte)0); - } + writer.Position++; - m_Stream.Write((short)tile.Position.Y); - m_Stream.Write((short)tile.Position.X); - m_Stream.Write((byte)tile.StackLevel); - m_Stream.Write((byte)tile.Direction); + writer.Write((short)tile.Position.Y); + writer.Write((short)tile.Position.X); + writer.Write((byte)tile.StackLevel); + writer.Write((byte)tile.Direction); - m_Stream.Write(tile.Flipped ? (byte)0x10 : (byte)0x0); + writer.Write(tile.Flipped ? (byte)0x10 : (byte)0x0); + + ns.Send(writer.Span); } - } - public sealed class MahjongRelieve : Packet - { - public MahjongRelieve(MahjongGame game) : base(0xDA) + public static void SendMahjongRelieve(NetState ns, MahjongGame game) { - EnsureCapacity(9); + if (ns == null) + return; - m_Stream.Write(game.Serial); - m_Stream.Write((byte)0); - m_Stream.Write((byte)0x1A); + SpanWriter writer = new SpanWriter(stackalloc byte[18]); + writer.Write((byte)0xDA); // Packet ID + writer.Write((short)18); // Dynamic Length + + writer.Write(game.Serial); + writer.Write((short)0x1A); + + ns.Send(writer.Span); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Items/Guilds/GuildDeed.cs b/Projects/Scripts/Items/Guilds/GuildDeed.cs index ea4197781..139077068 100644 --- a/Projects/Scripts/Items/Guilds/GuildDeed.cs +++ b/Projects/Scripts/Items/Guilds/GuildDeed.cs @@ -1,6 +1,5 @@ using Server.Guilds; using Server.Multis; -using Server.Prompts; namespace Server.Items { diff --git a/Projects/Scripts/Items/Guilds/Guildstone.cs b/Projects/Scripts/Items/Guilds/Guildstone.cs index c02b0cca4..3a34fdb7f 100644 --- a/Projects/Scripts/Items/Guilds/Guildstone.cs +++ b/Projects/Scripts/Items/Guilds/Guildstone.cs @@ -143,8 +143,7 @@ namespace Server.Items if (Guild.NewGuildSystem && ItemID == 0xED4) ItemID = 0xED6; - if (version <= 2) - m_BeforeChangeover = true; + m_BeforeChangeover |= version <= 2; if (Guild.NewGuildSystem && m_BeforeChangeover) Timer.DelayCall(TimeSpan.Zero, AddToHouse); @@ -251,10 +250,8 @@ namespace Server.Items from.SendGump(new GuildGump(from, Guild)); } else if (from.AccessLevel < AccessLevel.GameMaster && !Guild.IsMember(from)) - { - from.Send(new MessageLocalized(Serial, ItemID, MessageType.Regular, 0x3B2, 3, 501158, "", - "")); // You are not a member ... - } + Packets.SendMessageLocalized(from.NetState, Serial, ItemID, MessageType.Regular, 0x3B2, 3, + 501158); // You are not a member ... else { GuildGump.EnsureClosed(from); @@ -262,8 +259,6 @@ namespace Server.Items } } - #region IAddon Members - public Item Deed => new GuildstoneDeed(Guild, m_GuildName, m_GuildAbbrev); public bool CouldFit(IPoint3D p, Map map) => map.CanFit(p.X, p.Y, p.Z, ItemData.Height); @@ -376,9 +371,7 @@ namespace Server.Items list.Add(1060802, $"{Utility.FixHtml(name)} [{Utility.FixHtml(abbr)}]"); } else if (m_GuildName != null && m_GuildAbbrev != null) - { list.Add(1060802, $"{Utility.FixHtml(m_GuildName)} [{Utility.FixHtml(m_GuildAbbrev)}]"); - } } public override void OnDoubleClick(Mobile from) @@ -393,14 +386,10 @@ namespace Server.Items from.BeginTarget(-1, true, TargetFlags.None, Placement_OnTarget); } else - { from.SendLocalizedMessage(502092); // You must be in your house to do this. - } } else - { from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it. - } } public void Placement_OnTarget(Mobile from, object targeted) @@ -424,14 +413,10 @@ namespace Server.Items Delete(); } else - { from.SendLocalizedMessage(1042036); // That location is not in your house. - } } else - { from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it. - } } } } diff --git a/Projects/Scripts/Items/Maps/IndecipherableMap.cs b/Projects/Scripts/Items/Maps/IndecipherableMap.cs index 9cc9dfe9d..051e14fcb 100644 --- a/Projects/Scripts/Items/Maps/IndecipherableMap.cs +++ b/Projects/Scripts/Items/Maps/IndecipherableMap.cs @@ -3,13 +3,7 @@ namespace Server.Items public class IndecipherableMap : MapItem { [Constructible] - public IndecipherableMap() - { - if (Utility.RandomDouble() < 0.2) - Hue = 0x965; - else - Hue = 0x961; - } + public IndecipherableMap() => Hue = Utility.RandomDouble() < 0.2 ? 0x965 : 0x961; public IndecipherableMap(Serial serial) : base(serial) { @@ -36,4 +30,4 @@ namespace Server.Items int version = reader.ReadEncodedInt(); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Items/Maps/MapItem.cs b/Projects/Scripts/Items/Maps/MapItem.cs index d60d321cd..106f50e15 100644 --- a/Projects/Scripts/Items/Maps/MapItem.cs +++ b/Projects/Scripts/Items/Maps/MapItem.cs @@ -10,14 +10,16 @@ namespace Server.Items { private const int MaxUserPins = 50; private bool m_Editable; + private Map m_Facet; [Constructible] - public MapItem() : base(0x14EC) + public MapItem(Map facet = null) : base(0x14EC) { Weight = 1.0; Width = 200; Height = 200; + m_Facet = facet; } public MapItem(Serial serial) : base(serial) @@ -38,6 +40,13 @@ namespace Server.Items public List Pins{ get; } = new List(); + [CommandProperty(AccessLevel.GameMaster)] + public virtual Map Facet + { + get => m_Facet; + set => m_Facet = value; + } + #region ICraftable Members public int OnCraft(int quality, bool makersMark, Mobile from, CraftSystem craftSystem, Type typeRes, BaseTool tool, @@ -83,13 +92,24 @@ namespace Server.Items public virtual void DisplayTo(Mobile from) { - from.Send(new MapDetails(this)); - from.Send(new MapDisplay(this)); + NetState ns = from.NetState; + + if (ns.NewCharacterList) // 7.0.13.0+ supports maps on all facets + MapItemPackets.SendMapDetailsNew(ns, this); + else if (Facet != null && Facet != Map.Felucca && Facet != Map.Trammel) // Is it Felucca and Trammel, or just Felucca? + { + from.SendMessage("You must have client 7.0.13.0 or higher to display this map."); + return; + } + else + MapItemPackets.SendMapDetailsOld(ns, this); + + MapItemPackets.SendMapDisplay(from.NetState, this); for (int i = 0; i < Pins.Count; ++i) - from.Send(new MapAddPin(this, Pins[i])); + MapItemPackets.SendMapAddPin(from.NetState, this, Pins[i]); - from.Send(new MapSetEditable(this, ValidateEdit(from))); + MapItemPackets.SendMapSetEditable(from.NetState, this, ValidateEdit(from)); } public virtual void OnAddPin(Mobile from, int x, int y) @@ -144,7 +164,7 @@ namespace Server.Items if (Validate(from)) m_Editable = !m_Editable; - from.Send(new MapSetEditable(this, Validate(from) && m_Editable)); + MapItemPackets.SendMapSetEditable(from.NetState, this, m_Editable && ValidateEdit(from)); } public virtual void Validate(ref int x, ref int y) @@ -226,7 +246,9 @@ namespace Server.Items { base.Serialize(writer); - writer.Write(0); + writer.Write(1); + + writer.Write(m_Facet); writer.Write(Bounds); @@ -248,6 +270,9 @@ namespace Server.Items switch (version) { + case 1: + m_Facet = reader.ReadMap(); + goto case 0; case 0: { Bounds = reader.ReadRect2D(); @@ -306,71 +331,5 @@ namespace Server.Items break; } } - - private sealed class MapDetails : Packet - { - public MapDetails(MapItem map) : base(0x90, 19) - { - m_Stream.Write(map.Serial); - m_Stream.Write((short)0x139D); - m_Stream.Write((short)map.Bounds.Start.X); - m_Stream.Write((short)map.Bounds.Start.Y); - m_Stream.Write((short)map.Bounds.End.X); - m_Stream.Write((short)map.Bounds.End.Y); - m_Stream.Write((short)map.Width); - m_Stream.Write((short)map.Height); - } - } - - /* - private sealed class MapDetailsNew : Packet - { - public MapDetailsNew( MapItem map ) : base ( 0xF5, 21 ) - { - m_Stream.Write( (int) map.Serial ); - m_Stream.Write( (short) 0x139D ); - m_Stream.Write( (short) map.Bounds.Start.X ); - m_Stream.Write( (short) map.Bounds.Start.Y ); - m_Stream.Write( (short) map.Bounds.End.X ); - m_Stream.Write( (short) map.Bounds.End.Y ); - m_Stream.Write( (short) map.Width ); - m_Stream.Write( (short) map.Height ); - m_Stream.Write( (short) ( map.Facet == null ? 0 : map.Facet.MapID ) ); - } - } - */ - - private abstract class MapCommand : Packet - { - public MapCommand(MapItem map, int command, int number, int x, int y) : base(0x56, 11) - { - m_Stream.Write(map.Serial); - m_Stream.Write((byte)command); - m_Stream.Write((byte)number); - m_Stream.Write((short)x); - m_Stream.Write((short)y); - } - } - - private sealed class MapDisplay : MapCommand - { - public MapDisplay(MapItem map) : base(map, 5, 0, 0, 0) - { - } - } - - private sealed class MapAddPin : MapCommand - { - public MapAddPin(MapItem map, Point2D point) : base(map, 1, 0, point.X, point.Y) - { - } - } - - private sealed class MapSetEditable : MapCommand - { - public MapSetEditable(MapItem map, bool editable) : base(map, 7, editable ? 1 : 0, 0, 0) - { - } - } } } diff --git a/Projects/Scripts/Items/Maps/Packets.cs b/Projects/Scripts/Items/Maps/Packets.cs new file mode 100644 index 000000000..77d0805f4 --- /dev/null +++ b/Projects/Scripts/Items/Maps/Packets.cs @@ -0,0 +1,81 @@ +using Server.Buffers; +using Server.Items; + +namespace Server.Network +{ + public static class MapItemPackets + { + public static void SendMapDetailsOld(NetState ns, MapItem map) + { + if (ns == null) + return; + + SpanWriter writer = new SpanWriter(stackalloc byte[19]); + writer.Write((byte)0x90); // Packet ID + + writer.Write(map.Serial); + writer.Write((short)0x139D); + writer.Write((short)map.Bounds.Start.X); + writer.Write((short)map.Bounds.Start.Y); + writer.Write((short)map.Bounds.End.X); + writer.Write((short)map.Bounds.End.Y); + writer.Write((short)map.Width); + writer.Write((short)map.Height); + + ns.Send(writer.Span); + } + + public static void SendMapDetailsNew(NetState ns, MapItem map) + { + if (ns == null) + return; + + SpanWriter writer = new SpanWriter(stackalloc byte[21]); + writer.Write((byte)0xF5); // Packet ID + + writer.Write(map.Serial); + writer.Write((short)0x139D); + writer.Write((short)map.Bounds.Start.X); + writer.Write((short)map.Bounds.Start.Y); + writer.Write((short)map.Bounds.End.X); + writer.Write((short)map.Bounds.End.Y); + writer.Write((short)map.Width); + writer.Write((short)map.Height); + writer.Write( (short)(map.Facet?.MapID ?? 0) ); + + ns.Send(writer.Span); + } + + public static void SendMapDisplay(NetState ns, MapItem map) + { + SendMapCommand(ns, map, 5); + } + + public static void SendMapAddPin(NetState ns, MapItem map, Point2D p) + { + SendMapCommand(ns, map, 1, 0, p.X, p.Y); + } + + public static void SendMapSetEditable(NetState ns, MapItem map, bool editable) + { + SendMapCommand(ns, map, 7, editable ? 1 : 0); + } + + public static void SendMapCommand(NetState ns, MapItem map, int command, int number = 0, int x = 0, int y = 0) + { + if (ns == null) + return; + + SpanWriter writer = new SpanWriter(stackalloc byte[11]); + writer.Write((byte)0x56); // Packet ID + + writer.Write(map.Serial); + writer.Write((byte)command); + writer.Write((byte)number); + writer.Write((short)x); + writer.Write((short)y); + + ns.Send(writer.Span); + } + } +} diff --git a/Projects/Scripts/Items/Maps/PresetMap.cs b/Projects/Scripts/Items/Maps/PresetMap.cs index 9f79db312..5039220e3 100644 --- a/Projects/Scripts/Items/Maps/PresetMap.cs +++ b/Projects/Scripts/Items/Maps/PresetMap.cs @@ -78,7 +78,7 @@ namespace Server.Items public Rectangle2D Bounds{ get; } - public static PresetMapEntry[] Table{ get; } = + public static readonly PresetMapEntry[] Table = { new PresetMapEntry(1041189, 200, 200, 1092, 1396, 1736, 1924), // map of Britain new PresetMapEntry(1041203, 200, 200, 0256, 1792, 1736, 2560), // map of Britain to Skara Brae @@ -142,4 +142,4 @@ namespace Server.Items Yew, YewToBritain } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Items/Maps/TreasureMap.cs b/Projects/Scripts/Items/Maps/TreasureMap.cs index 066f240eb..de2815a90 100644 --- a/Projects/Scripts/Items/Maps/TreasureMap.cs +++ b/Projects/Scripts/Items/Maps/TreasureMap.cs @@ -17,7 +17,7 @@ namespace Server.Items private static Point2D[] m_Locations; private static Point2D[] m_HavenLocations; - private static Type[][] m_SpawnTypes = + private static readonly Type[][] m_SpawnTypes = { new[] { typeof(HeadlessOne), typeof(Skeleton) }, new[] { typeof(Mongbat), typeof(Ratman), typeof(HeadlessOne), typeof(Skeleton), typeof(Zombie) }, @@ -32,18 +32,13 @@ namespace Server.Items private Mobile m_CompletedBy; private Mobile m_Decoder; private int m_Level; - private Map m_Map; [Constructible] - public TreasureMap(int level, Map map) + public TreasureMap(int level, Map facet = null) : base(facet) { m_Level = level; - m_Map = map; - if (level == 0) - ChestLocation = GetRandomHavenLocation(); - else - ChestLocation = GetRandomLocation(); + ChestLocation = level == 0 ? GetRandomHavenLocation() : GetRandomLocation(); Width = 300; Height = 300; @@ -127,12 +122,12 @@ namespace Server.Items } [CommandProperty(AccessLevel.GameMaster)] - public Map ChestMap + public override Map Facet { - get => m_Map; + get => base.Facet; set { - m_Map = value; + base.Facet = value; InvalidateProperties(); } } @@ -145,15 +140,9 @@ namespace Server.Items get { if (m_Decoder != null) - { - if (m_Level == 6) - return 1063453; - return 1041516 + m_Level; - } + return m_Level == 6 ? 1063453 : 1041516 + m_Level; - if (m_Level == 6) - return 1063452; - return 1041510 + m_Level; + return m_Level == 6 ? 1063452 : 1041510 + m_Level; } } @@ -162,10 +151,8 @@ namespace Server.Items if (m_Locations == null) LoadLocations(); - if (m_Locations.Length > 0) - return m_Locations[Utility.Random(m_Locations.Length)]; - - return Point2D.Zero; + // ReSharper disable once PossibleNullReferenceException + return m_Locations.Length > 0 ? m_Locations[Utility.Random(m_Locations.Length)] : Point2D.Zero; } public static Point2D GetRandomHavenLocation() @@ -173,10 +160,8 @@ namespace Server.Items if (m_HavenLocations == null) LoadLocations(); - if (m_HavenLocations.Length > 0) - return m_HavenLocations[Utility.Random(m_HavenLocations.Length)]; - - return Point2D.Zero; + // ReSharper disable once PossibleNullReferenceException + return m_HavenLocations.Length > 0 ? m_HavenLocations[Utility.Random(m_HavenLocations.Length)] : Point2D.Zero; } private static void LoadLocations() @@ -325,7 +310,7 @@ namespace Server.Items { from.SendLocalizedMessage(503020); // You are already digging treasure. } - else if (from.Map != m_Map) + else if (from.Map != Facet) { from.SendLocalizedMessage(1010479); // You seem to be in the right place, but may be on the wrong facet! } @@ -473,7 +458,7 @@ namespace Server.Items { base.GetProperties(list); - list.Add(m_Map == Map.Felucca ? 1041502 : 1041503); // for somewhere in Felucca : for somewhere in Trammel + list.Add(Facet == Map.Felucca ? 1041502 : 1041503); // for somewhere in Felucca : for somewhere in Trammel if (m_Completed) list.Add(1041507, m_CompletedBy == null ? "someone" : m_CompletedBy.Name); // completed by ~1_val~ @@ -483,9 +468,8 @@ namespace Server.Items { if (m_Completed) { - from.Send(new MessageLocalizedAffix(Serial, ItemID, MessageType.Label, 0x3B2, 3, 1048030, "", - AffixType.Append, - $" completed by {(m_CompletedBy == null ? "someone" : m_CompletedBy.Name)}", "")); + Packets.SendMessageLocalizedAffix(from.NetState, Serial, ItemID, MessageType.Label, 0x3B2, 3, 1048030, "", + AffixType.Append, $" completed by {m_CompletedBy?.Name ?? "someone"}"); } else if (m_Decoder != null) { @@ -496,10 +480,10 @@ namespace Server.Items } else { - if (m_Level == 6) - LabelTo(from, 1041522, $"#{1063452}\t \t#{(m_Map == Map.Felucca ? 1041502 : 1041503)}"); - else - LabelTo(from, 1041522, $"#{1041510 + m_Level}\t \t#{(m_Map == Map.Felucca ? 1041502 : 1041503)}"); + LabelTo(from, 1041522, + m_Level == 6 + ? $"#{1063452}\t \t#{(Facet == Map.Felucca ? 1041502 : 1041503)}" + : $"#{1041510 + m_Level}\t \t#{(Facet == Map.Felucca ? 1041502 : 1041503)}"); } } @@ -507,14 +491,13 @@ namespace Server.Items { base.Serialize(writer); - writer.Write(1); + writer.Write(2); writer.Write(m_CompletedBy); writer.Write(m_Level); writer.Write(m_Completed); writer.Write(m_Decoder); - writer.Write(m_Map); writer.Write(ChestLocation); } @@ -537,7 +520,8 @@ namespace Server.Items m_Level = reader.ReadInt(); m_Completed = reader.ReadBool(); m_Decoder = reader.ReadMobile(); - m_Map = reader.ReadMap(); + if (version < 2) + Facet = reader.ReadMap(); ChestLocation = reader.ReadPoint2D(); if (version == 0 && m_Completed) @@ -562,12 +546,10 @@ namespace Server.Items if (m_Map.Deleted) return; - Map map = m_Map.m_Map; + Map facet = m_Map.Facet; if (m_Map.m_Completed) - { from.SendLocalizedMessage(503028); // The treasure for this map has already been found. - } /* else if ( from != m_Map.m_Decoder ) { @@ -575,22 +557,14 @@ namespace Server.Items } */ else if (m_Map.m_Decoder != from && !m_Map.HasRequiredSkill(from)) - { from.SendLocalizedMessage( 503031); // You did not decode this map and have no clue where to look for the treasure. - } else if (!from.CanBeginAction()) - { from.SendLocalizedMessage(503020); // You are already digging treasure. - } else if (!HasDiggingTool(from)) - { - from.SendMessage("You must have a digging tool to dig for treasure."); - } - else if (from.Map != map) - { + from.SendLocalizedMessage(1114416); // You must have a digging tool to dig for treasure. + else if (from.Map != facet) from.SendLocalizedMessage(1010479); // You seem to be in the right place, but may be on the wrong facet! - } else { IPoint3D p = targeted as IPoint3D; @@ -617,19 +591,17 @@ namespace Server.Items if (Utility.InRange(targ3D, chest3D0, maxRange)) { if (from.Location.X == x && from.Location.Y == y) - { from.SendLocalizedMessage( 503030); // The chest can't be dug up because you are standing on top of it. - } - else if (map != null) + else if (facet != null) { - int z = map.GetAverageZ(x, y); + int z = facet.GetAverageZ(x, y); - if (!map.CanFit(x, y, z, 16, true)) + if (!facet.CanFit(x, y, z, 16, true)) from.SendLocalizedMessage( 503021); // You have found the treasure chest but something is keeping it from being dug up. else if (from.BeginAction()) - new DigTimer(from, m_Map, new Point3D(x, y, z), map).Start(); + new DigTimer(from, m_Map, new Point3D(x, y, z), facet).Start(); else from.SendLocalizedMessage(503020); // You are already digging treasure. } @@ -644,9 +616,7 @@ namespace Server.Items else { if (Utility.InRange(targ3D, chest3D0, 8)) // We're close, but not quite - { - from.SendAsciiMessage(0x44, "The treasure chest is very close!"); - } + from.SendLocalizedMessage(1080030, "", 0x44); // The treasure chest is very close! else { Direction dir = Utility.GetDirection(targ3D, chest3D0); diff --git a/Projects/Scripts/Items/Misc/BankCheck.cs b/Projects/Scripts/Items/Misc/BankCheck.cs index a07a360dd..161c06380 100644 --- a/Projects/Scripts/Items/Misc/BankCheck.cs +++ b/Projects/Scripts/Items/Misc/BankCheck.cs @@ -1,6 +1,5 @@ using System; using System.Globalization; -using Server.Accounting; using Server.Engines.Quests; using Server.Engines.Quests.Haven; using Server.Engines.Quests.Necro; diff --git a/Projects/Scripts/Items/Misc/Blocker.cs b/Projects/Scripts/Items/Misc/Blocker.cs index b5baf8be0..87cfcce25 100644 --- a/Projects/Scripts/Items/Misc/Blocker.cs +++ b/Projects/Scripts/Items/Misc/Blocker.cs @@ -1,3 +1,4 @@ +using Server.Buffers; using Server.Network; namespace Server.Items @@ -13,14 +14,21 @@ namespace Server.Items public override int LabelNumber => 503057; // Impassable! - protected override Packet GetWorldPacketFor(NetState state) + protected override void SendWorldPacketFor(NetState state) { Mobile mob = state.Mobile; if (mob?.AccessLevel >= AccessLevel.GameMaster) - return new GMItemPacket(this); + { + if (state.HighSeas) + SendGMItemHS(state); + else if (state.StygianAbyss) + SendGMItemSA(state); + else + SendGMItem(state); + } - return base.GetWorldPacketFor(state); + base.SendWorldPacketFor(state); } public override void Serialize(GenericWriter writer) @@ -37,66 +45,138 @@ namespace Server.Items int version = reader.ReadInt(); } - public sealed class GMItemPacket : Packet + private void SendGMItem(NetState ns) { - public GMItemPacket(Item item) : base(0x1A) - { - EnsureCapacity(20); + if (ns == null) + return; - // 14 base length - // +2 - Amount - // +2 - Hue - // +1 - Flags + SpanWriter w = new SpanWriter(stackalloc byte[20]); + w.Write((byte)0x1A); // Packet ID + w.Position += 2; // Dynamic Length - uint serial = item.Serial.Value; - int itemID = 0x1183; - int amount = item.Amount; - Point3D loc = item.Location; - int x = loc.X; - int y = loc.Y; - int hue = item.Hue; - int flags = item.GetPacketFlags(); - int direction = (int)item.Direction; + uint serial = Serial.Value; + int itemId = 0x1183; + int amount = Amount; + Point3D loc = Location; + int x = loc.X; + int y = loc.Y; + int hue = Hue; + int flags = GetPacketFlags(); + int direction = (int)Direction; - if (amount != 0) - serial |= 0x80000000; - else - serial &= 0x7FFFFFFF; + if (amount != 0) + serial |= 0x80000000; + else + serial &= 0x7FFFFFFF; - m_Stream.Write(serial); - m_Stream.Write((short)(itemID & 0x7FFF)); + w.Write(serial); - if (amount != 0) - m_Stream.Write((short)amount); + w.Write((short)itemId); - x &= 0x7FFF; + if (amount != 0) + w.Write((short)amount); - if (direction != 0) - x |= 0x8000; + x &= 0x7FFF; - m_Stream.Write((short)x); + if (direction != 0) x |= 0x8000; - y &= 0x3FFF; + w.Write((short)x); - if (hue != 0) - y |= 0x8000; + y &= 0x3FFF; - if (flags != 0) - y |= 0x4000; + if (hue != 0) y |= 0x8000; - m_Stream.Write((short)y); + if (flags != 0) y |= 0x4000; - if (direction != 0) - m_Stream.Write((byte)direction); + w.Write((short)y); - m_Stream.Write((sbyte)loc.Z); + if (direction != 0) + w.Write((byte)direction); - if (hue != 0) - m_Stream.Write((ushort)hue); + w.Write((sbyte)loc.Z); - if (flags != 0) - m_Stream.Write((byte)flags); - } + if (hue != 0) + w.Write((ushort)hue); + + if (flags != 0) + w.Write((byte)flags); + + w.Position = 1; + w.Write((ushort)w.WrittenCount); + + ns.Send(w.Span); + } + + public void SendGMItemSA(NetState ns) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[24]); + w.Write((byte)0xF3); // Packet ID + + w.Write((short)0x01); + + int itemId = 0x1183; + + w.Position++; // w.Write((byte)0); + + w.Write(Serial); + + w.Write((short)itemId); + + w.Write((byte)Direction); + + short amount = (short)Amount; + w.Write(amount); + w.Write(amount); + + Point3D loc = Location; + w.Write((short)(loc.X & 0x7FFF)); + w.Write((short)(loc.Y & 0x3FFF)); + w.Write((sbyte)loc.Z); + + w.Write((byte)Light); + w.Write((short)Hue); + w.Write((byte)GetPacketFlags()); + + ns.Send(w.RawSpan); + } + + public void SendGMItemHS(NetState ns) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[26]); + w.Write((byte)0xF3); // Packet ID + + w.Write((short)0x01); + + int itemId = 0x1183; + + w.Position++; // w.Write((byte)0); + + w.Write(Serial); + + w.Write((short)itemId); + + w.Write((byte)Direction); + + short amount = (short)Amount; + w.Write(amount); + w.Write(amount); + + Point3D loc = Location; + w.Write((short)(loc.X & 0x7FFF)); + w.Write((short)(loc.Y & 0x3FFF)); + w.Write((sbyte)loc.Z); + + w.Write((byte)Light); + w.Write((short)Hue); + w.Write((byte)GetPacketFlags()); + + ns.Send(w.RawSpan); } } } diff --git a/Projects/Scripts/Items/Misc/BulletinBoards.cs b/Projects/Scripts/Items/Misc/BulletinBoards.cs index 69ec0b014..7e17e5874 100644 --- a/Projects/Scripts/Items/Misc/BulletinBoards.cs +++ b/Projects/Scripts/Items/Misc/BulletinBoards.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Server.Buffers; using Server.Network; using Server.Targeting; @@ -54,7 +55,7 @@ namespace Server.Items } [CommandProperty(AccessLevel.GameMaster)] - public string BoardName{ get; set; } + public string BoardName { get; set; } public static bool CheckTime(DateTime time, TimeSpan range) => time + range < DateTime.UtcNow; @@ -66,8 +67,10 @@ namespace Server.Items if (minutes != 0 && seconds != 0) return $"{minutes} minute{(minutes == 1 ? "" : "s")} and {seconds} second{(seconds == 1 ? "" : "s")}"; + if (minutes != 0) return $"{minutes} minute{(minutes == 1 ? "" : "s")}"; + return $"{seconds} second{(seconds == 1 ? "" : "s")}"; } @@ -146,11 +149,8 @@ namespace Server.Items NetState state = from.NetState; - state.Send(new BBDisplayBoard(this)); - if (state.ContainerGridLines) - state.Send(new ContainerContent6017(from, this)); - else - state.Send(new ContainerContent(from, this)); + BBPackets.SendBBDisplayBoard(state, this); + Packets.SendContainerContent(state, from, this); } else { @@ -232,18 +232,14 @@ namespace Server.Items public static void BBRequestContent(Mobile from, BaseBulletinBoard board, PacketReader pvSrc) { - if (!(World.FindItem(pvSrc.ReadUInt32()) is BulletinMessage msg) || msg.Parent != board) - return; - - from.Send(new BBMessageContent(board, msg)); + if (World.FindItem(pvSrc.ReadUInt32()) is BulletinMessage msg && msg.Parent == board) + BBPackets.SendBBMessageContent(from.NetState, board, msg); } public static void BBRequestHeader(Mobile from, BaseBulletinBoard board, PacketReader pvSrc) { - if (!(World.FindItem(pvSrc.ReadUInt32()) is BulletinMessage msg) || msg.Parent != board) - return; - - from.Send(new BBMessageHeader(board, msg)); + if (World.FindItem(pvSrc.ReadUInt32()) is BulletinMessage msg && msg.Parent == board) + BBPackets.SendBBMessageHeader(from.NetState, board, msg); } public static void BBPostMessage(Mobile from, BaseBulletinBoard board, PacketReader pvSrc) @@ -271,7 +267,7 @@ namespace Server.Items return; } - string subject = pvSrc.ReadUTF8StringSafe(pvSrc.ReadByte()); + string subject = pvSrc.ReadStringSafe(pvSrc.ReadByte()); if (subject.Length == 0) return; @@ -282,7 +278,7 @@ namespace Server.Items return; for (int i = 0; i < lines.Length; ++i) - lines[i] = pvSrc.ReadUTF8StringSafe(pvSrc.ReadByte()); + lines[i] = pvSrc.ReadStringSafe(pvSrc.ReadByte()); board.PostMessage(from, thread, subject, lines); } @@ -344,25 +340,25 @@ namespace Server.Items { } - public Mobile Poster{ get; private set; } + public Mobile Poster { get; private set; } - public BulletinMessage Thread{ get; private set; } + public BulletinMessage Thread { get; private set; } - public string Subject{ get; private set; } + public string Subject { get; private set; } - public DateTime Time{ get; private set; } + public DateTime Time { get; private set; } - public DateTime LastPostTime{ get; set; } + public DateTime LastPostTime { get; set; } - public string PostedName{ get; private set; } + public string PostedName { get; private set; } - public int PostedBody{ get; private set; } + public int PostedBody { get; private set; } - public int PostedHue{ get; private set; } + public int PostedHue { get; private set; } - public BulletinEquip[] PostedEquip{ get; private set; } + public BulletinEquip[] PostedEquip { get; private set; } - public string[] Lines{ get; private set; } + public string[] Lines { get; private set; } public string GetTimeAsString() => Time.ToString("MMM dd, yyyy"); @@ -452,70 +448,64 @@ namespace Server.Items } } - public class BBDisplayBoard : Packet + public static class BBPackets { - public BBDisplayBoard(BaseBulletinBoard board) : base(0x71) + public static void SendBBDisplayBoard(NetState ns, BaseBulletinBoard board) { - EnsureCapacity(38); + SpanWriter writer = new SpanWriter(stackalloc byte[38]); + writer.Write((byte)0x71); // Packet ID + writer.Write((ushort)38); // Dynamic Length - byte[] buffer = Utility.UTF8.GetBytes(board.BoardName ?? ""); + writer.Position++; // writer.Write((byte)0); // Command + writer.Write(board.Serial); + writer.WriteAsciiNull(board.BoardName ?? "", 29); - m_Stream.Write((byte)0x00); // PacketID - m_Stream.Write(board.Serial); // Bulletin board serial - - // Bulletin board name - if (buffer.Length >= 29) - { - m_Stream.Write(buffer, 0, 29); - m_Stream.Write((byte)0); - } - else - { - m_Stream.Write(buffer, 0, buffer.Length); - m_Stream.Fill(30 - buffer.Length); - } - } - } - - public class BBMessageHeader : Packet - { - public BBMessageHeader(BaseBulletinBoard board, BulletinMessage msg) : base(0x71) - { - string poster = SafeString(msg.PostedName); - string subject = SafeString(msg.Subject); - string time = SafeString(msg.GetTimeAsString()); - - EnsureCapacity(22 + poster.Length + subject.Length + time.Length); - - m_Stream.Write((byte)0x01); // PacketID - m_Stream.Write(board.Serial); // Bulletin board serial - m_Stream.Write(msg.Serial); // Message serial - - BulletinMessage thread = msg.Thread; - - if (thread == null) - m_Stream.Write(0); // Thread serial--root - else - m_Stream.Write(thread.Serial); // Thread serial--parent - - WriteString(poster); - WriteString(subject); - WriteString(time); + ns.Send(writer.Span); } - public void WriteString(string v) + public static void SendBBMessageHeader(NetState ns, BaseBulletinBoard board, BulletinMessage msg) { - byte[] buffer = Utility.UTF8.GetBytes(v); - int len = buffer.Length + 1; + string poster = msg.PostedName ?? ""; + string subject = msg.Subject ?? ""; + string time = msg.GetTimeAsString() ?? ""; - if (len > 255) - len = 255; + byte posterLength = Math.Min((byte)poster.Length, (byte)254); + byte subjectLength = Math.Min((byte)subject.Length, (byte)254); + byte timeLength = Math.Min((byte)time.Length, (byte)254); - m_Stream.Write((byte)len); - m_Stream.Write(buffer, 0, len - 1); - m_Stream.Write((byte)0); + int length = 22 + posterLength + subjectLength + timeLength; + SpanWriter writer = new SpanWriter(stackalloc byte[length]); + writer.Write((byte)0x71); // Packet ID + writer.Write((ushort)length); // Dynamic Length + + writer.Write((byte)0x01); // Command + writer.Write(board.Serial); // Bulletin board serial + writer.Write(msg.Serial); // Message serial + writer.Write(msg.Thread?.Serial ?? 0); + + writer.Write(posterLength); + writer.WriteAsciiNull(poster, posterLength + 1); + writer.Write(subjectLength); + writer.WriteAsciiNull(subject, subjectLength + 1); + writer.Write(timeLength); + writer.WriteAsciiNull(time, timeLength + 1); + + ns.Send(writer.Span); } + public static void SendBBMessageContent(NetState ns, BaseBulletinBoard board, BulletinMessage msg) + { + string poster = msg.PostedName ?? ""; + string subject = msg.Subject ?? ""; + string time = msg.GetTimeAsString() ?? ""; + + byte posterLength = Math.Min((byte)poster.Length, (byte)254); + byte subjectLength = Math.Min((byte)subject.Length, (byte)254); + byte timeLength = Math.Min((byte)time.Length, (byte)254); + + int equipLength = Math.Min(msg.PostedEquip.Length, 255); + int msgLength = Math.Min(msg.Lines.Length, 255); + public string SafeString(string v) => v ?? string.Empty; } @@ -529,72 +519,43 @@ namespace Server.Items EnsureCapacity(22 + poster.Length + subject.Length + time.Length); - m_Stream.Write((byte)0x02); // PacketID - m_Stream.Write(board.Serial); // Bulletin board serial - m_Stream.Write(msg.Serial); // Message serial + writer.Write((byte)0x02); // Command + writer.Write(board.Serial); // Bulletin board serial + writer.Write(msg.Serial); // Message serial - WriteString(poster); - WriteString(subject); - WriteString(time); + writer.Write(posterLength); + writer.WriteAsciiNull(poster, posterLength + 1); + writer.Write(subjectLength); + writer.WriteAsciiNull(subject, subjectLength + 1); + writer.Write(timeLength); + writer.WriteAsciiNull(time, timeLength + 1); - m_Stream.Write((short)msg.PostedBody); - m_Stream.Write((short)msg.PostedHue); + writer.Write((short)msg.PostedBody); + writer.Write((short)msg.PostedHue); - int len = msg.PostedEquip.Length; + writer.Write((byte)equipLength); - if (len > 255) - len = 255; - - m_Stream.Write((byte)len); - - for (int i = 0; i < len; ++i) + for (int i = 0; i < equipLength; ++i) { BulletinEquip eq = msg.PostedEquip[i]; - m_Stream.Write((short)eq.itemID); - m_Stream.Write((short)eq.hue); + writer.Write((short)eq.itemID); + writer.Write((short)eq.hue); } - len = msg.Lines.Length; + writer.Write((byte)msgLength); - if (len > 255) - len = 255; + for (int i = 0; i < msgLength; ++i) + { + string line = msg.Lines[i]; + byte len = Math.Min((byte)line.Length, (byte)254); + writer.WriteAsciiNull(line, len); + } - m_Stream.Write((byte)len); + writer.Position = 1; + writer.Write((ushort)writer.WrittenCount); - for (int i = 0; i < len; ++i) - WriteString(msg.Lines[i], true); - } - - public void WriteString(string v) - { - WriteString(v, false); - } - - public void WriteString(string v, bool padding) - { - byte[] buffer = Utility.UTF8.GetBytes(v); - int tail = padding ? 2 : 1; - int len = buffer.Length + tail; - - if (len > 255) - len = 255; - - m_Stream.Write((byte)len); - m_Stream.Write(buffer, 0, len - tail); - - if (padding) - m_Stream.Write((short)0); // padding compensates for a client bug - else - m_Stream.Write((byte)0); - } - - public string SafeString(string v) - { - if (v == null) - return string.Empty; - - return v; + ns.Send(writer.Span); } } } diff --git a/Projects/Scripts/Items/Misc/CommunicationCrystals.cs b/Projects/Scripts/Items/Misc/CommunicationCrystals.cs index d660b678f..1cd235d19 100644 --- a/Projects/Scripts/Items/Misc/CommunicationCrystals.cs +++ b/Projects/Scripts/Items/Misc/CommunicationCrystals.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Server.Network; using Server.Targeting; @@ -29,14 +30,7 @@ namespace Server.Items public int Amount{ get; } - public static CrystalRechargeInfo Get(Type type) - { - foreach (CrystalRechargeInfo info in Table) - if (info.Type == type) - return info; - - return null; - } + public static CrystalRechargeInfo Get(Type type) => Table.FirstOrDefault(info => info.Type == type); } public class BroadcastCrystal : Item diff --git a/Projects/Scripts/Items/Misc/Corpses/Corpse.cs b/Projects/Scripts/Items/Misc/Corpses/Corpse.cs index 5aaa1f3fc..dd37973f3 100644 --- a/Projects/Scripts/Items/Misc/Corpses/Corpse.cs +++ b/Projects/Scripts/Items/Misc/Corpses/Corpse.cs @@ -100,7 +100,7 @@ namespace Server.Items public Corpse(Mobile owner, HairInfo hair, FacialHairInfo facialhair, List equipItems) : base(0x2006) { - // To supress console warnings, stackable must be true + // To suppress console warnings, stackable must be true Stackable = true; Amount = owner.Body; // protocol defines that for itemid 0x2006, amount=body Stackable = false; @@ -193,16 +193,7 @@ namespace Server.Items } [CommandProperty(AccessLevel.GameMaster)] - public virtual bool InstancedCorpse - { - get - { - if (!Core.SE) - return false; - - return DateTime.UtcNow < TimeOfDeath + InstancedCorpseTime; - } - } + public virtual bool InstancedCorpse => Core.SE && DateTime.UtcNow < TimeOfDeath + InstancedCorpseTime; public override bool IsDecoContainer => false; @@ -302,9 +293,7 @@ namespace Server.Items Mobile dead = Owner; if (GetFlag(CorpseFlag.Carved) || dead == null) - { from.SendLocalizedMessage(500485); // You see nothing useful to carve from the corpse. - } else if (((Body)Amount).IsHuman && ItemID == 0x2006) { new Blood(0x122D).MoveToWorld(Location, Map); @@ -328,13 +317,9 @@ namespace Server.Items from.CriminalAction(true); } else if (dead is BaseCreature creature) - { creature.OnCarve(from, this, item); - } else - { from.SendLocalizedMessage(500485); // You see nothing useful to carve from the corpse. - } } public override bool IsChildVisibleTo(Mobile m, Item child) => @@ -347,8 +332,7 @@ namespace Server.Items if (Aggressors.Count == 0 || Items.Count == 0) return; - if (m_InstancedItems == null) - m_InstancedItems = new Dictionary(); + m_InstancedItems ??= new Dictionary(); List m_Stackables = new List(); List m_Unstackables = new List(); @@ -401,7 +385,7 @@ namespace Server.Items } if (remainder == 0) - m_InstancedItems.Add(item, new InstancedItemInfo(item, attackers[attackers.Count - 1])); + m_InstancedItems.Add(item, new InstancedItemInfo(item, attackers[^1])); else m_Unstackables.Add(item); } @@ -427,9 +411,7 @@ namespace Server.Items if (InstancedCorpse) { - if (m_InstancedItems == null) - m_InstancedItems = new Dictionary(); - + m_InstancedItems ??= new Dictionary(); m_InstancedItems.Add(carved, new InstancedItemInfo(carved, carver)); } } @@ -464,7 +446,6 @@ namespace Server.Items public override void OnAfterDelete() { m_DecayTimer?.Stop(); - m_DecayTimer = null; } @@ -543,29 +524,23 @@ namespace Server.Items writer.WriteDeltaTime(TimeOfDeath); - List> list = m_RestoreTable == null - ? null - : new List>(m_RestoreTable); - int count = list?.Count ?? 0; - - writer.Write(count); - - for (int i = 0; i < count; ++i) + if (m_RestoreTable == null) + writer.Write(0); + else { - KeyValuePair kvp = list[i]; - Item item = kvp.Key; - Point3D loc = kvp.Value; + writer.Write(m_RestoreTable.Count); - writer.Write(item); + foreach (var (item, loc) in m_RestoreTable) + { + writer.Write(item); - if (item.Location == loc) - { - writer.Write(false); - } - else - { - writer.Write(true); - writer.Write(loc); + if (item.Location == loc) + writer.Write(false); + else + { + writer.Write(true); + writer.Write(loc); + } } } @@ -757,12 +732,8 @@ namespace Server.Items if (!(((Body)Amount).IsHuman && ItemID == 0x2006)) return; - if (state.ContainerGridLines) - state.Send(new CorpseContent6017(state.Mobile, this)); - else - state.Send(new CorpseContent(state.Mobile, this)); - - state.Send(new CorpseEquip(state.Mobile, this)); + CorpsePackets.SendCorpseContent(state, state.Mobile, this); + CorpsePackets.SendCorpseEquip(state, state.Mobile, this); } public bool IsCriminalAction(Mobile from) @@ -836,8 +807,7 @@ namespace Server.Items if (item == null) return; - if (m_RestoreTable == null) - m_RestoreTable = new Dictionary(); + m_RestoreTable ??= new Dictionary(); m_RestoreTable[item] = loc; } @@ -1065,7 +1035,7 @@ namespace Server.Items ObjectPropertyList opl = PropertyList; if (opl.Header > 0) - from.Send(new MessageLocalized(Serial, ItemID, MessageType.Label, hue, 3, opl.Header, Name, opl.HeaderArgs)); + Packets.SendMessageLocalized(from.NetState, Serial, ItemID, MessageType.Label, hue, 3, opl.Header, Name, opl.HeaderArgs); } public override void OnSingleClick(Mobile from) @@ -1075,14 +1045,12 @@ namespace Server.Items if (ItemID == 0x2006) // Corpse form { if (m_CorpseName != null) - from.Send(new AsciiMessage(Serial, ItemID, MessageType.Label, hue, 3, "", m_CorpseName)); + Packets.SendAsciiMessage(from.NetState, Serial, ItemID, MessageType.Label, hue, 3, "", m_CorpseName); else - from.Send(new MessageLocalized(Serial, ItemID, MessageType.Label, hue, 3, 1046414, "", Name)); + Packets.SendMessageLocalized(from.NetState, Serial, ItemID, MessageType.Label, hue, 3, 1046414, "", Name); } else // Bone form - { - from.Send(new MessageLocalized(Serial, ItemID, MessageType.Label, hue, 3, 1046414, "", Name)); - } + Packets.SendMessageLocalized(from.NetState, Serial, ItemID, MessageType.Label, hue, 3, 1046414, "", Name); } private class InstancedItemInfo diff --git a/Projects/Scripts/Items/Misc/Corpses/Packets.cs b/Projects/Scripts/Items/Misc/Corpses/Packets.cs index cb4cb10d9..7040d5060 100644 --- a/Projects/Scripts/Items/Misc/Corpses/Packets.cs +++ b/Projects/Scripts/Items/Misc/Corpses/Packets.cs @@ -1,24 +1,29 @@ using System.Collections.Generic; -using System.IO; +using Server.Buffers; using Server.Items; namespace Server.Network { - public sealed class CorpseEquip : Packet + public static class CorpsePackets { - public CorpseEquip(Mobile beholder, Corpse beheld) : base(0x89) + public static void SendCorpseEquip(NetState ns, Mobile beholder, Corpse beheld) { + if (ns == null) + return; + List list = beheld.EquipItems; - int count = list.Count; - if (beheld.Hair != null && beheld.Hair.ItemID > 0) - count++; - if (beheld.FacialHair != null && beheld.FacialHair.ItemID > 0) - count++; + int length = 8 + list.Count * 5; + if (beheld.Hair?.ItemID > 0) + length += 5; + if (beheld.FacialHair?.ItemID > 0) + length += 5; - EnsureCapacity(8 + count * 5); + SpanWriter writer = new SpanWriter(stackalloc byte[length]); + writer.Write((byte)0x89); // Packet ID + writer.Write((ushort)length); // Dynamic Length - m_Stream.Write(beheld.Serial); + writer.Write(beheld.Serial); for (int i = 0; i < list.Count; ++i) { @@ -26,173 +31,180 @@ namespace Server.Network if (!item.Deleted && beholder.CanSee(item) && item.Parent == beheld) { - m_Stream.Write((byte)(item.Layer + 1)); - m_Stream.Write(item.Serial); + writer.Write((byte)(item.Layer + 1)); + writer.Write(item.Serial); } } - if (beheld.Hair != null && beheld.Hair.ItemID > 0) + if (beheld.Hair?.ItemID > 0) { - m_Stream.Write((byte)(Layer.Hair + 1)); - m_Stream.Write(HairInfo.FakeSerial(beheld.Owner) - 2); + writer.Write((byte)(Layer.Hair + 1)); + writer.Write(HairInfo.FakeSerial(beheld.Owner.Serial) - 2); } - if (beheld.FacialHair != null && beheld.FacialHair.ItemID > 0) + if (beheld.FacialHair?.ItemID > 0) { - m_Stream.Write((byte)(Layer.FacialHair + 1)); - m_Stream.Write(FacialHairInfo.FakeSerial(beheld.Owner) - 2); + writer.Write((byte)(Layer.FacialHair + 1)); + writer.Write(FacialHairInfo.FakeSerial(beheld.Owner.Serial) - 2); } - m_Stream.Write((byte)Layer.Invalid); + writer.Position++; // writer.Write((byte)Layer.Invalid); + + ns.Send(writer.Span); } - } - public sealed class CorpseContent : Packet - { - public CorpseContent(Mobile beholder, Corpse beheld) - : base(0x3C) + public static void SendCorpseContent(NetState ns, Mobile beholder, Corpse corpse) { - List items = beheld.EquipItems; - int count = items.Count; + if (ns == null) + return; - if (beheld.Hair != null && beheld.Hair.ItemID > 0) - count++; - if (beheld.FacialHair != null && beheld.FacialHair.ItemID > 0) - count++; + if (ns.ContainerGridLines) + SendCorpseContentNew(ns, beholder, corpse); + else + SendCorpseContentOld(ns, beholder, corpse); + } - EnsureCapacity(5 + count * 19); + public static void SendCorpseContentOld(NetState ns, Mobile beholder, Corpse corpse) + { + if (ns == null) + return; - long pos = m_Stream.Position; + List items = corpse.EquipItems; + int length = 5 + items.Count * 19; - int written = 0; + if (corpse.Hair?.ItemID > 0) + length += 19; + if (corpse.FacialHair?.ItemID > 0) + length += 19; - m_Stream.Write((ushort)0); + SpanWriter writer = new SpanWriter(stackalloc byte[length]); + writer.Write((byte)0x3C); // Packet ID + writer.Write((ushort)length); // Dynamic Length + writer.Position += 2; + + ushort written = 0; for (int i = 0; i < items.Count; ++i) { Item child = items[i]; - if (!child.Deleted && child.Parent == beheld && beholder.CanSee(child)) + if (!child.Deleted && child.Parent == corpse && beholder.CanSee(child)) { - m_Stream.Write(child.Serial); - m_Stream.Write((ushort)child.ItemID); - m_Stream.Write((byte)0); // signed, itemID offset - m_Stream.Write((ushort)child.Amount); - m_Stream.Write((short)child.X); - m_Stream.Write((short)child.Y); - m_Stream.Write(beheld.Serial); - m_Stream.Write((ushort)child.Hue); + writer.Write(child.Serial); + writer.Write((ushort)child.ItemID); + writer.Position++; // signed, itemID offset + writer.Write((ushort)child.Amount); + writer.Write((short)child.X); + writer.Write((short)child.Y); + writer.Write(corpse.Serial); + writer.Write((ushort)child.Hue); ++written; } } - if (beheld.Hair != null && beheld.Hair.ItemID > 0) + if (corpse.Hair?.ItemID > 0) { - m_Stream.Write(HairInfo.FakeSerial(beheld.Owner) - 2); - m_Stream.Write((ushort)beheld.Hair.ItemID); - m_Stream.Write((byte)0); // signed, itemID offset - m_Stream.Write((ushort)1); - m_Stream.Write((short)0); - m_Stream.Write((short)0); - m_Stream.Write(beheld.Serial); - m_Stream.Write((ushort)beheld.Hair.Hue); + writer.Write(HairInfo.FakeSerial(corpse.Owner.Serial) - 2); + writer.Write((ushort)corpse.Hair.ItemID); + writer.Position++; // signed, itemID offset + writer.Write((ushort)1); + writer.Position += 4; + writer.Write(corpse.Serial); + writer.Write((ushort)corpse.Hair.Hue); ++written; } - if (beheld.FacialHair != null && beheld.FacialHair.ItemID > 0) + if (corpse.FacialHair?.ItemID > 0) { - m_Stream.Write(FacialHairInfo.FakeSerial(beheld.Owner) - 2); - m_Stream.Write((ushort)beheld.FacialHair.ItemID); - m_Stream.Write((byte)0); // signed, itemID offset - m_Stream.Write((ushort)1); - m_Stream.Write((short)0); - m_Stream.Write((short)0); - m_Stream.Write(beheld.Serial); - m_Stream.Write((ushort)beheld.FacialHair.Hue); + writer.Write(FacialHairInfo.FakeSerial(corpse.Owner.Serial) - 2); + writer.Write((ushort)corpse.FacialHair.ItemID); + writer.Position++; // signed, itemID offset + writer.Write((ushort)1); + writer.Position += 4; + writer.Write(corpse.Serial); + writer.Write((ushort)corpse.FacialHair.Hue); ++written; } - m_Stream.Seek(pos, SeekOrigin.Begin); - m_Stream.Write((ushort)written); + writer.Position = 3; + writer.Write(written); + + ns.Send(writer.Span); } - } - public sealed class CorpseContent6017 : Packet - { - public CorpseContent6017(Mobile beholder, Corpse beheld) - : base(0x3C) + public static void SendCorpseContentNew(NetState ns, Mobile beholder, Corpse corpse) { - List items = beheld.EquipItems; - int count = items.Count; + if (ns == null) + return; - if (beheld.Hair != null && beheld.Hair.ItemID > 0) - count++; - if (beheld.FacialHair != null && beheld.FacialHair.ItemID > 0) - count++; + List items = corpse.EquipItems; + int length = 5 + items.Count * 20; - EnsureCapacity(5 + count * 20); + if (corpse.Hair?.ItemID > 0) + length += 20; + if (corpse.FacialHair?.ItemID > 0) + length += 20; - long pos = m_Stream.Position; + SpanWriter writer = new SpanWriter(stackalloc byte[length]); + writer.Write((byte)0x3C); // Packet ID + writer.Write((ushort)length); // Dynamic Length + writer.Position += 2; - int written = 0; - - m_Stream.Write((ushort)0); + ushort written = 0; for (int i = 0; i < items.Count; ++i) { Item child = items[i]; - if (!child.Deleted && child.Parent == beheld && beholder.CanSee(child)) + if (!child.Deleted && child.Parent == corpse && beholder.CanSee(child)) { - m_Stream.Write(child.Serial); - m_Stream.Write((ushort)child.ItemID); - m_Stream.Write((byte)0); // signed, itemID offset - m_Stream.Write((ushort)child.Amount); - m_Stream.Write((short)child.X); - m_Stream.Write((short)child.Y); - m_Stream.Write((byte)0); // Grid Location? - m_Stream.Write(beheld.Serial); - m_Stream.Write((ushort)child.Hue); + writer.Write(child.Serial); + writer.Write((ushort)child.ItemID); + writer.Position++; // signed, itemID offset + writer.Write((ushort)child.Amount); + writer.Write((short)child.X); + writer.Write((short)child.Y); + writer.Position++; // grid location + writer.Write(corpse.Serial); + writer.Write((ushort)child.Hue); ++written; } } - if (beheld.Hair != null && beheld.Hair.ItemID > 0) + if (corpse.Hair?.ItemID > 0) { - m_Stream.Write(HairInfo.FakeSerial(beheld.Owner) - 2); - m_Stream.Write((ushort)beheld.Hair.ItemID); - m_Stream.Write((byte)0); // signed, itemID offset - m_Stream.Write((ushort)1); - m_Stream.Write((short)0); - m_Stream.Write((short)0); - m_Stream.Write((byte)0); // Grid Location? - m_Stream.Write(beheld.Serial); - m_Stream.Write((ushort)beheld.Hair.Hue); + writer.Write(HairInfo.FakeSerial(corpse.Owner.Serial) - 2); + writer.Write((ushort)corpse.Hair.ItemID); + writer.Position++; // signed, itemID offset + writer.Write((ushort)1); + writer.Position += 5; + writer.Write(corpse.Serial); + writer.Write((ushort)corpse.Hair.Hue); ++written; } - if (beheld.FacialHair != null && beheld.FacialHair.ItemID > 0) + if (corpse.FacialHair?.ItemID > 0) { - m_Stream.Write(FacialHairInfo.FakeSerial(beheld.Owner) - 2); - m_Stream.Write((ushort)beheld.FacialHair.ItemID); - m_Stream.Write((byte)0); // signed, itemID offset - m_Stream.Write((ushort)1); - m_Stream.Write((short)0); - m_Stream.Write((short)0); - m_Stream.Write((byte)0); // Grid Location? - m_Stream.Write(beheld.Serial); - m_Stream.Write((ushort)beheld.FacialHair.Hue); + writer.Write(FacialHairInfo.FakeSerial(corpse.Owner.Serial) - 2); + writer.Write((ushort)corpse.FacialHair.ItemID); + writer.Position++; // signed, itemID offset + writer.Write((ushort)1); + writer.Position += 5; + writer.Write(corpse.Serial); + writer.Write((ushort)corpse.FacialHair.Hue); ++written; } - m_Stream.Seek(pos, SeekOrigin.Begin); - m_Stream.Write((ushort)written); + writer.Position = 3; + writer.Write(written); + + ns.Send(writer.Span); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Items/Misc/EffectController.cs b/Projects/Scripts/Items/Misc/EffectController.cs index 16f94d462..ecf776620 100644 --- a/Projects/Scripts/Items/Misc/EffectController.cs +++ b/Projects/Scripts/Items/Misc/EffectController.cs @@ -304,7 +304,7 @@ namespace Server.Items { case ECEffectType.Lightning: { - Effects.SendBoltEffect(from, false, EffectHue); + Effects.SendBoltEffect(from, false); break; } case ECEffectType.Location: @@ -334,4 +334,4 @@ namespace Server.Items } } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Items/Misc/EffectItem.cs b/Projects/Scripts/Items/Misc/EffectItem.cs index dcddd3b74..ebd8c9992 100644 --- a/Projects/Scripts/Items/Misc/EffectItem.cs +++ b/Projects/Scripts/Items/Misc/EffectItem.cs @@ -83,4 +83,4 @@ namespace Server.Items } } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Items/Misc/Firebomb.cs b/Projects/Scripts/Items/Misc/Firebomb.cs index 6ab46e1a2..0bc4553bf 100644 --- a/Projects/Scripts/Items/Misc/Firebomb.cs +++ b/Projects/Scripts/Items/Misc/Firebomb.cs @@ -66,8 +66,7 @@ namespace Server.Items from.SendLocalizedMessage(1060581); // You've already lit it! Better throw it now! } - if (m_Users == null) - m_Users = new List(); + m_Users ??= new List(); if (!m_Users.Contains(from)) m_Users.Add(from); diff --git a/Projects/Scripts/Items/Misc/Gold.cs b/Projects/Scripts/Items/Misc/Gold.cs index 4a8553f01..bacb07ef1 100644 --- a/Projects/Scripts/Items/Misc/Gold.cs +++ b/Projects/Scripts/Items/Misc/Gold.cs @@ -1,5 +1,4 @@ using System; -using Server.Accounting; namespace Server.Items { diff --git a/Projects/Scripts/Items/Misc/InteriorDecorator.cs b/Projects/Scripts/Items/Misc/InteriorDecorator.cs index 8e01befe1..c9012b72e 100644 --- a/Projects/Scripts/Items/Misc/InteriorDecorator.cs +++ b/Projects/Scripts/Items/Misc/InteriorDecorator.cs @@ -182,8 +182,7 @@ namespace Server.Items if (addon != null) { - if (count == 1 && Core.SE) - isDecorableComponent = true; + isDecorableComponent |= count == 1 && Core.SE; if (m_Decorator.Command == DecorateCommand.Turn) { @@ -191,8 +190,7 @@ namespace Server.Items (FlippableAddonAttribute[])addon.GetType() .GetCustomAttributes(typeof(FlippableAddonAttribute), false); - if (attributes.Length > 0) - isDecorableComponent = true; + isDecorableComponent = attributes.Length > 0; } } diff --git a/Projects/Scripts/Items/Misc/Key.cs b/Projects/Scripts/Items/Misc/Key.cs index 475b3492b..60a99de75 100644 --- a/Projects/Scripts/Items/Misc/Key.cs +++ b/Projects/Scripts/Items/Misc/Key.cs @@ -1,5 +1,4 @@ using Server.Network; -using Server.Prompts; using Server.Targeting; namespace Server.Items @@ -204,14 +203,9 @@ namespace Server.Items { base.GetProperties(list); - string desc; + string desc = m_KeyVal == 0 ? "(blank)" : m_Description?.Trim() ?? ""; - if (m_KeyVal == 0) - desc = "(blank)"; - else if ((desc = m_Description) == null || (desc = desc.Trim()).Length <= 0) - desc = null; - - if (desc != null) + if (desc != "") list.Add(desc); } @@ -219,15 +213,10 @@ namespace Server.Items { base.OnSingleClick(from); - string desc; - - if (m_KeyVal == 0) - desc = "(blank)"; - else if ((desc = m_Description) == null || (desc = desc.Trim()).Length <= 0) - desc = ""; + string desc = m_KeyVal == 0 ? "(blank)" : m_Description?.Trim() ?? ""; if (desc.Length > 0) - from.Send(new UnicodeMessage(Serial, ItemID, MessageType.Regular, 0x3B2, 3, "ENU", "", desc)); + Packets.SendUnicodeMessage(from.NetState, Serial, ItemID, MessageType.Regular, 0x3B2, 3, "ENU", "", desc); } public bool UseOn(Mobile from, ILockable o) diff --git a/Projects/Scripts/Items/Misc/KeyRing.cs b/Projects/Scripts/Items/Misc/KeyRing.cs index 4965f6827..40480d8a7 100644 --- a/Projects/Scripts/Items/Misc/KeyRing.cs +++ b/Projects/Scripts/Items/Misc/KeyRing.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using Server.Targeting; namespace Server.Items @@ -109,14 +110,7 @@ namespace Server.Items UpdateItemID(); } - public bool ContainsKey(uint keyValue) - { - foreach (Key key in Keys) - if (key.KeyValue == keyValue) - return true; - - return false; - } + public bool ContainsKey(uint keyValue) => Keys.Any(key => key.KeyValue == keyValue); private void UpdateItemID() { @@ -169,9 +163,7 @@ namespace Server.Items } else if (targeted is ILockable o) { - foreach (Key key in m_KeyRing.Keys) - if (key.UseOn(from, o)) - return; + if (m_KeyRing.Keys.Any(key => key.UseOn(from, o))) return; from.SendLocalizedMessage(1008140); // You do not have a key for that. } @@ -182,4 +174,4 @@ namespace Server.Items } } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Items/Misc/LOSBlocker.cs b/Projects/Scripts/Items/Misc/LOSBlocker.cs index 2d44cef77..ca21df5a3 100644 --- a/Projects/Scripts/Items/Misc/LOSBlocker.cs +++ b/Projects/Scripts/Items/Misc/LOSBlocker.cs @@ -1,3 +1,4 @@ +using Server.Buffers; using Server.Network; namespace Server.Items @@ -19,13 +20,21 @@ namespace Server.Items TileData.ItemTable[0x21A2].Height = 20; } - protected override Packet GetWorldPacketFor(NetState state) + protected override void SendWorldPacketFor(NetState state) { Mobile mob = state.Mobile; - if (mob?.AccessLevel >= AccessLevel.GameMaster) return new GMItemPacket(this); + if (mob?.AccessLevel >= AccessLevel.GameMaster) + { + if (state.HighSeas) + SendGMItemHS(state); + else if (state.StygianAbyss) + SendGMItemSA(state); + else + SendGMItem(state); + } - return base.GetWorldPacketFor(state); + base.SendWorldPacketFor(state); } public override void Serialize(GenericWriter writer) @@ -45,66 +54,138 @@ namespace Server.Items ItemID = 0x21A2; } - public sealed class GMItemPacket : Packet + private void SendGMItem(NetState ns) { - public GMItemPacket(Item item) : base(0x1A) - { - EnsureCapacity(20); + if (ns == null) + return; - // 14 base length - // +2 - Amount - // +2 - Hue - // +1 - Flags + SpanWriter w = new SpanWriter(stackalloc byte[20]); + w.Write((byte)0x1A); // Packet ID + w.Position += 2; // Dynamic Length - uint serial = item.Serial.Value; - int itemID = 0x36FF; - int amount = item.Amount; - Point3D loc = item.Location; - int x = loc.X; - int y = loc.Y; - int hue = item.Hue; - int flags = item.GetPacketFlags(); - int direction = (int)item.Direction; + uint serial = Serial.Value; + int itemId = 0x36FF; + int amount = Amount; + Point3D loc = Location; + int x = loc.X; + int y = loc.Y; + int hue = Hue; + int flags = GetPacketFlags(); + int direction = (int)Direction; - if (amount != 0) - serial |= 0x80000000; - else - serial &= 0x7FFFFFFF; + if (amount != 0) + serial |= 0x80000000; + else + serial &= 0x7FFFFFFF; - m_Stream.Write(serial); - m_Stream.Write((short)(itemID & 0x7FFF)); + w.Write(serial); - if (amount != 0) - m_Stream.Write((short)amount); + w.Write((short)itemId); - x &= 0x7FFF; + if (amount != 0) + w.Write((short)amount); - if (direction != 0) - x |= 0x8000; + x &= 0x7FFF; - m_Stream.Write((short)x); + if (direction != 0) x |= 0x8000; - y &= 0x3FFF; + w.Write((short)x); - if (hue != 0) - y |= 0x8000; + y &= 0x3FFF; - if (flags != 0) - y |= 0x4000; + if (hue != 0) y |= 0x8000; - m_Stream.Write((short)y); + if (flags != 0) y |= 0x4000; - if (direction != 0) - m_Stream.Write((byte)direction); + w.Write((short)y); - m_Stream.Write((sbyte)loc.Z); + if (direction != 0) + w.Write((byte)direction); - if (hue != 0) - m_Stream.Write((ushort)hue); + w.Write((sbyte)loc.Z); - if (flags != 0) - m_Stream.Write((byte)flags); - } + if (hue != 0) + w.Write((ushort)hue); + + if (flags != 0) + w.Write((byte)flags); + + w.Position = 1; + w.Write((ushort)w.WrittenCount); + + ns.Send(w.Span); + } + + public void SendGMItemSA(NetState ns) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[24]); + w.Write((byte)0xF3); // Packet ID + + w.Write((short)0x01); + + int itemId = 0x36FF; + + w.Position++; // w.Write((byte)0); + + w.Write(Serial); + + w.Write((short)itemId); + + w.Write((byte)Direction); + + short amount = (short)Amount; + w.Write(amount); + w.Write(amount); + + Point3D loc = Location; + w.Write((short)(loc.X & 0x7FFF)); + w.Write((short)(loc.Y & 0x3FFF)); + w.Write((sbyte)loc.Z); + + w.Write((byte)Light); + w.Write((short)Hue); + w.Write((byte)GetPacketFlags()); + + ns.Send(w.RawSpan); + } + + public void SendGMItemHS(NetState ns) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[26]); + w.Write((byte)0xF3); // Packet ID + + w.Write((short)0x01); + + int itemId = 0x36FF; + + w.Position++; // w.Write((byte)0); + + w.Write(Serial); + + w.Write((short)itemId); + + w.Write((byte)Direction); + + short amount = (short)Amount; + w.Write(amount); + w.Write(amount); + + Point3D loc = Location; + w.Write((short)(loc.X & 0x7FFF)); + w.Write((short)(loc.Y & 0x3FFF)); + w.Write((sbyte)loc.Z); + + w.Write((byte)Light); + w.Write((short)Hue); + w.Write((byte)GetPacketFlags()); + + ns.Send(w.RawSpan); } } } diff --git a/Projects/Scripts/Items/Misc/PlayerBulletinBoards.cs b/Projects/Scripts/Items/Misc/PlayerBulletinBoards.cs index 2789f301d..7d5259e7d 100644 --- a/Projects/Scripts/Items/Misc/PlayerBulletinBoards.cs +++ b/Projects/Scripts/Items/Misc/PlayerBulletinBoards.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using Server.Gumps; using Server.Multis; -using Server.Prompts; using Server.Mobiles; using Server.Network; using Server.ContextMenus; diff --git a/Projects/Scripts/Items/Misc/PowerGenerator.cs b/Projects/Scripts/Items/Misc/PowerGenerator.cs index db1d950c4..00da04a2c 100644 --- a/Projects/Scripts/Items/Misc/PowerGenerator.cs +++ b/Projects/Scripts/Items/Misc/PowerGenerator.cs @@ -31,11 +31,7 @@ namespace Server.Items private void AddGeneratorComponent(int itemID, int x, int y, int z) { - AddonComponent component = new AddonComponent(itemID); - component.Name = "a power generator"; - component.Hue = 0x451; - - AddComponent(component, x, y, z); + AddComponent(new AddonComponent(itemID){ Name = "a power generator", Hue = 0x451 }, x, y, z); } public override void Serialize(GenericWriter writer) @@ -148,9 +144,7 @@ namespace Server.Items visited[current.X, current.Y] = true; } else - { current = stack[--stackSize - 1]; - } } Path = new Node[stackSize]; @@ -197,9 +191,8 @@ namespace Server.Items public void DoDamage(Mobile to) { - to.Send(new UnicodeMessage(Serial, ItemID, MessageType.Regular, 0x3B2, 3, "", "", - "The generator shoots an arc of electricity at you!")); - to.BoltEffect(0); + Packets.SendMessageLocalized(to.NetState, Serial, ItemID, MessageType.Regular, 0x3B2, 3, 1152372); // The Nexus shoots an arc of energy at you! + to.BoltEffect(); to.LocalOverheadMessage(MessageType.Regular, 0xC9, true, "* Your body convulses from electric shock *"); to.NonlocalOverheadMessage(MessageType.Regular, 0xC9, true, $"* {to.Name} spasms from electric shock *"); @@ -358,7 +351,7 @@ namespace Server.Items hues[n.X, n.Y] = NodeHue.Blue; } - Node lastNode = path[path.Length - 1]; + Node lastNode = path[^1]; hues[lastNode.X, lastNode.Y] = NodeHue.Red; for (int i = 0; i < sideLength; i++) diff --git a/Projects/Scripts/Items/Misc/PublicMoongate.cs b/Projects/Scripts/Items/Misc/PublicMoongate.cs index c0af37445..d3dc1e9fc 100644 --- a/Projects/Scripts/Items/Misc/PublicMoongate.cs +++ b/Projects/Scripts/Items/Misc/PublicMoongate.cs @@ -119,11 +119,7 @@ namespace Server.Items private static void DeleteAll() { - List list = new List(); - - foreach (Item item in World.Items.Values) - if (item is PublicMoongate) - list.Add(item); + List list = World.Items.Values.OfType().Cast().ToList(); foreach (Item item in list) item.Delete(); @@ -349,7 +345,7 @@ namespace Server.Items } } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (info.ButtonID == 0) // Cancel return; diff --git a/Projects/Scripts/Items/Misc/Teleporter.cs b/Projects/Scripts/Items/Misc/Teleporter.cs index bf922bff7..74db4bc7b 100644 --- a/Projects/Scripts/Items/Misc/Teleporter.cs +++ b/Projects/Scripts/Items/Misc/Teleporter.cs @@ -157,10 +157,7 @@ namespace Server.Items { base.GetProperties(list); - if (m_Active) - list.Add(1060742); // active - else - list.Add(1060743); // inactive + list.Add(m_Active ? 1060742 : 1060743); if (m_MapDest != null) list.Add(1060658, "Map\t{0}", m_MapDest); @@ -234,12 +231,12 @@ namespace Server.Items bool sendEffect = !m.Hidden || m.AccessLevel == AccessLevel.Player; if (m_SourceEffect && sendEffect) - Effects.SendLocationEffect(m.Location, m.Map, 0x3728, 10, 10); + Effects.SendLocationEffect(m.Location, m.Map, 0x3728, 10); m.MoveToWorld(p, map); if (m_DestEffect && sendEffect) - Effects.SendLocationEffect(m.Location, m.Map, 0x3728, 10, 10); + Effects.SendLocationEffect(m.Location, m.Map, 0x3728, 10); if (m_SoundID > 0 && sendEffect) Effects.PlaySound(m.Location, m.Map, m_SoundID); @@ -395,11 +392,10 @@ namespace Server.Items if (m.BeginAction(this)) { if (m_MessageString != null) - m.Send(new UnicodeMessage(Serial, ItemID, MessageType.Regular, 0x3B2, 3, "ENU", null, - m_MessageString)); + Packets.SendUnicodeMessage(m.NetState, Serial, ItemID, MessageType.Regular, 0x3B2, 3, "ENU", "", + m_MessageString); else if (m_MessageNumber != 0) - m.Send(new MessageLocalized(Serial, ItemID, MessageType.Regular, 0x3B2, 3, m_MessageNumber, null, - "")); + Packets.SendMessageLocalized(m.NetState, Serial, ItemID, MessageType.Regular, 0x3B2, 3, m_MessageNumber); Timer.DelayCall(TimeSpan.FromSeconds(5.0), () => m.EndAction(this)); } @@ -525,12 +521,7 @@ namespace Server.Items if (!m.InRange(GetWorldLocation(), m_Range)) return; - bool isMatch = false; - - if (m_Keyword >= 0 && e.HasKeyword(m_Keyword)) - isMatch = true; - else if (m_Substring != null && e.Speech.ToLower().IndexOf(m_Substring.ToLower()) >= 0) - isMatch = true; + bool isMatch = m_Keyword >= 0 && e.HasKeyword(m_Keyword) || m_Substring != null && e.Speech.ToLower().IndexOf(m_Substring.ToLower()) >= 0; if (!isMatch || !CanTeleport(m)) return; @@ -820,10 +811,10 @@ namespace Server.Items writer.Write(TimeoutDelay); writer.Write(m_Teleporting.Count); - foreach (KeyValuePair kvp in m_Teleporting) + foreach (var (key, value) in m_Teleporting) { - writer.Write(kvp.Key); - writer.Write(kvp.Value.Next); + writer.Write(key); + writer.Write(value.Next); } } @@ -1063,9 +1054,7 @@ namespace Server.Items case Layer.Backpack: case Layer.Mount: case Layer.Bank: - { continue; // ignore - } default: { m.SendMessage("You must remove all of your equipment before proceeding."); diff --git a/Projects/Scripts/Items/Misc/TrashBarrel.cs b/Projects/Scripts/Items/Misc/TrashBarrel.cs index da67c25df..fc578e383 100644 --- a/Projects/Scripts/Items/Misc/TrashBarrel.cs +++ b/Projects/Scripts/Items/Misc/TrashBarrel.cs @@ -112,7 +112,7 @@ namespace Server.Items if (items.Count > 0) { - PublicOverheadMessage(MessageType.Regular, 0x3B2, message, ""); + PublicOverheadMessage(MessageType.Regular, 0x3B2, message); for (int i = items.Count - 1; i >= 0; --i) { diff --git a/Projects/Scripts/Items/Misc/UnholyBone.cs b/Projects/Scripts/Items/Misc/UnholyBone.cs index 236a41a1e..4f34ecc50 100644 --- a/Projects/Scripts/Items/Misc/UnholyBone.cs +++ b/Projects/Scripts/Items/Misc/UnholyBone.cs @@ -26,7 +26,7 @@ namespace Server.Items public void Carve(Mobile from, Item item) { Effects.PlaySound(GetWorldLocation(), Map, 0x48F); - Effects.SendLocationEffect(GetWorldLocation(), Map, 0x3728, 10, 10, 0, 0); + Effects.SendLocationEffect(GetWorldLocation(), Map, 0x3728, 10); if (0.3 > Utility.RandomDouble()) { diff --git a/Projects/Scripts/Items/Quivers/BaseQuiver.cs b/Projects/Scripts/Items/Quivers/BaseQuiver.cs index f38f31d44..def02a29d 100644 --- a/Projects/Scripts/Items/Quivers/BaseQuiver.cs +++ b/Projects/Scripts/Items/Quivers/BaseQuiver.cs @@ -302,7 +302,7 @@ namespace Server.Items if ((prop = Attributes.RegenMana) != 0) list.Add(1060440, prop.ToString()); // mana regeneration ~1_val~ - if ((prop = Attributes.NightSight) != 0) + if (Attributes.NightSight != 0) list.Add(1060441); // night sight if ((prop = Attributes.ReflectPhysical) != 0) diff --git a/Projects/Scripts/Items/Resources/Tailor/BoltOfCloth.cs b/Projects/Scripts/Items/Resources/Tailor/BoltOfCloth.cs index d57728a15..3e97a980e 100644 --- a/Projects/Scripts/Items/Resources/Tailor/BoltOfCloth.cs +++ b/Projects/Scripts/Items/Resources/Tailor/BoltOfCloth.cs @@ -54,10 +54,8 @@ namespace Server.Items public override void OnSingleClick(Mobile from) { - int number = Amount == 1 ? 1049122 : 1049121; - - from.Send( - new MessageLocalized(Serial, ItemID, MessageType.Label, 0x3B2, 3, number, "", (Amount * 50).ToString())); + Packets.SendMessageLocalized(from.NetState, Serial, ItemID, MessageType.Label, 0x3B2, 3, + Amount == 1 ? 1049122 : 1049121, "", (Amount * 50).ToString()); } } } diff --git a/Projects/Scripts/Items/Resources/Tailor/Cloth.cs b/Projects/Scripts/Items/Resources/Tailor/Cloth.cs index 9c98be700..4f5705daa 100644 --- a/Projects/Scripts/Items/Resources/Tailor/Cloth.cs +++ b/Projects/Scripts/Items/Resources/Tailor/Cloth.cs @@ -55,9 +55,8 @@ namespace Server.Items public override void OnSingleClick(Mobile from) { - int number = Amount == 1 ? 1049124 : 1049123; - - from.Send(new MessageLocalized(Serial, ItemID, MessageType.Regular, 0x3B2, 3, number, "", Amount.ToString())); + Packets.SendMessageLocalized(from.NetState, Serial, ItemID, MessageType.Label, 0x3B2, 3, + Amount == 1 ? 1049124 : 1049123, "", Amount.ToString()); } } } diff --git a/Projects/Scripts/Items/Resources/Tailor/Leathers.cs b/Projects/Scripts/Items/Resources/Tailor/Leathers.cs index a8568f553..8661bfcee 100644 --- a/Projects/Scripts/Items/Resources/Tailor/Leathers.cs +++ b/Projects/Scripts/Items/Resources/Tailor/Leathers.cs @@ -29,16 +29,10 @@ namespace Server.Items } } - public override int LabelNumber - { - get - { - if (m_Resource >= CraftResource.SpinedLeather && m_Resource <= CraftResource.BarbedLeather) - return 1049684 + (m_Resource - CraftResource.SpinedLeather); - - return 1047022; - } - } + public override int LabelNumber => + m_Resource >= CraftResource.SpinedLeather && m_Resource <= CraftResource.BarbedLeather + ? 1049684 + (m_Resource - CraftResource.SpinedLeather) + : 1047022; int ICommodity.DescriptionNumber => LabelNumber; bool ICommodity.IsDeedable => true; diff --git a/Projects/Scripts/Items/Resources/Tailor/UncutCloth.cs b/Projects/Scripts/Items/Resources/Tailor/UncutCloth.cs index 676283400..eda2b6400 100644 --- a/Projects/Scripts/Items/Resources/Tailor/UncutCloth.cs +++ b/Projects/Scripts/Items/Resources/Tailor/UncutCloth.cs @@ -55,9 +55,8 @@ namespace Server.Items public override void OnSingleClick(Mobile from) { - int number = Amount == 1 ? 1049124 : 1049123; - - from.Send(new MessageLocalized(Serial, ItemID, MessageType.Regular, 0x3B2, 3, number, "", Amount.ToString())); + Packets.SendMessageLocalized(from.NetState, Serial, ItemID, MessageType.Label, 0x3B2, 3, + Amount == 1 ? 1049124 : 1049123, "", Amount.ToString()); } } } diff --git a/Projects/Scripts/Items/Skill Items/Camping/Campfire.cs b/Projects/Scripts/Items/Skill Items/Camping/Campfire.cs index cbe187746..8f9a35130 100644 --- a/Projects/Scripts/Items/Skill Items/Camping/Campfire.cs +++ b/Projects/Scripts/Items/Skill Items/Camping/Campfire.cs @@ -44,7 +44,7 @@ namespace Server.Items [CommandProperty(AccessLevel.GameMaster)] public CampfireStatus Status { - get + get => ItemID switch { return ItemID switch { diff --git a/Projects/Scripts/Items/Skill Items/Fishing/Misc/SOS.cs b/Projects/Scripts/Items/Skill Items/Fishing/Misc/SOS.cs index 2b3639fc9..dc4f20bae 100644 --- a/Projects/Scripts/Items/Skill Items/Fishing/Misc/SOS.cs +++ b/Projects/Scripts/Items/Skill Items/Fishing/Misc/SOS.cs @@ -233,21 +233,19 @@ namespace Server.Items bool xEast = false, ySouth = false; string fmt; - if (Sextant.Format(loc, map, ref xLong, ref yLat, ref xMins, ref yMins, ref xEast, ref ySouth)) - fmt = $"{yLat}°{yMins}'{(ySouth ? "S" : "N")},{xLong}°{xMins}'{(xEast ? "E" : "W")}"; - else - fmt = "?????"; + fmt = Sextant.Format(loc, map, ref xLong, ref yLat, ref xMins, ref yMins, ref xEast, ref ySouth) ? + $"{yLat}°{yMins}'{(ySouth ? "S" : "N")},{xLong}°{xMins}'{(xEast ? "E" : "W")}" : "?????"; AddPage(0); AddBackground(0, 40, 350, 300, 2520); - AddHtmlLocalized(30, 80, 285, 160, 1018326, true, - true); /* This is a message hastily scribbled by a passenger aboard a sinking ship. - * While it is probably too late to save the passengers and crew, - * perhaps some treasure went down with the ship! - * The message gives the ship's last known sextant co-ordinates. - */ + AddHtmlLocalized(30, 80, 285, 160, 1018326, true, true); + /* This is a message hastily scribbled by a passenger aboard a sinking ship. + * While it is probably too late to save the passengers and crew, + * perhaps some treasure went down with the ship! + * The message gives the ship's last known sextant co-ordinates.= + */ AddHtml(35, 240, 230, 20, fmt); diff --git a/Projects/Scripts/Items/Skill Items/Fishing/Misc/SpecialFishingNet.cs b/Projects/Scripts/Items/Skill Items/Fishing/Misc/SpecialFishingNet.cs index db5d8c74d..e82ef9e7d 100644 --- a/Projects/Scripts/Items/Skill Items/Fishing/Misc/SpecialFishingNet.cs +++ b/Projects/Scripts/Items/Skill Items/Fishing/Misc/SpecialFishingNet.cs @@ -200,7 +200,6 @@ namespace Server.Items switch (Utility.Random(8)) { default: - case 0: x = -1; y = -1; break; @@ -405,4 +404,4 @@ namespace Server.Items int version = reader.ReadInt(); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Items/Skill Items/Harvest Tools/BaseHarvestTool.cs b/Projects/Scripts/Items/Skill Items/Harvest Tools/BaseHarvestTool.cs index 26bbbabf4..abf96ad14 100644 --- a/Projects/Scripts/Items/Skill Items/Harvest Tools/BaseHarvestTool.cs +++ b/Projects/Scripts/Items/Skill Items/Harvest Tools/BaseHarvestTool.cs @@ -159,9 +159,7 @@ namespace Server.Items if (!(from is PlayerMobile pm)) return; - ContextMenuEntry miningEntry = new ContextMenuEntry(pm.ToggleMiningStone ? 6179 : 6178); - miningEntry.Color = 0x421F; - list.Add(miningEntry); + list.Add(new ContextMenuEntry(pm.ToggleMiningStone ? 6179 : 6178) {Color = 0x421F}); list.Add(new ToggleMiningStoneEntry(pm, false, 6176)); list.Add(new ToggleMiningStoneEntry(pm, true, 6177)); diff --git a/Projects/Scripts/Items/Skill Items/Magical/Misc/Moongate.cs b/Projects/Scripts/Items/Skill Items/Magical/Misc/Moongate.cs index b0e17a24e..672019d2d 100644 --- a/Projects/Scripts/Items/Skill Items/Magical/Misc/Moongate.cs +++ b/Projects/Scripts/Items/Skill Items/Magical/Misc/Moongate.cs @@ -167,7 +167,7 @@ namespace Server.Items from.Map != Map.Felucca && TargetMap == Map.Felucca && ShowFeluccaWarning) { if (from.AccessLevel == AccessLevel.Player || !from.Hidden) - from.Send(new PlaySound(0x20E, from.Location)); + Packets.SendPlaySound(from.NetState, 0x20E, from.Location); from.CloseGump(); from.SendGump(new MoongateConfirmGump(from, this)); } @@ -381,7 +381,7 @@ namespace Server.Items } } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (info.ButtonID == 1) m_Gate.EndConfirmation(m_From); diff --git a/Projects/Scripts/Items/Skill Items/Magical/Misc/RecallRune.cs b/Projects/Scripts/Items/Skill Items/Magical/Misc/RecallRune.cs index af4e695b7..f78663b1a 100644 --- a/Projects/Scripts/Items/Skill Items/Magical/Misc/RecallRune.cs +++ b/Projects/Scripts/Items/Skill Items/Magical/Misc/RecallRune.cs @@ -1,5 +1,4 @@ using Server.Multis; -using Server.Prompts; using Server.Regions; namespace Server.Items diff --git a/Projects/Scripts/Items/Skill Items/Magical/Potions/Explosion Potions/BaseExplosionPotion.cs b/Projects/Scripts/Items/Skill Items/Magical/Potions/Explosion Potions/BaseExplosionPotion.cs index 84957e0fb..fcb582922 100644 --- a/Projects/Scripts/Items/Skill Items/Magical/Potions/Explosion Potions/BaseExplosionPotion.cs +++ b/Projects/Scripts/Items/Skill Items/Magical/Potions/Explosion Potions/BaseExplosionPotion.cs @@ -76,8 +76,7 @@ namespace Server.Items from.RevealingAction(); - if (Users == null) - Users = new List(); + Users ??= new List(); if (!Users.Contains(from)) Users.Add(from); @@ -169,7 +168,7 @@ namespace Server.Items Effects.PlaySound(loc, map, 0x307); - Effects.SendLocationEffect(loc, map, 0x36B0, 9, 10, 0, 0); + Effects.SendLocationEffect(loc, map, 0x36B0, 9); int alchemyBonus = 0; if (direct) diff --git a/Projects/Scripts/Items/Skill Items/Magical/Potions/NightSight.cs b/Projects/Scripts/Items/Skill Items/Magical/Potions/NightSight.cs index c4bc72042..d5256e9aa 100644 --- a/Projects/Scripts/Items/Skill Items/Magical/Potions/NightSight.cs +++ b/Projects/Scripts/Items/Skill Items/Magical/Potions/NightSight.cs @@ -29,7 +29,7 @@ namespace Server.Items public override void Drink(Mobile from) { - if (from.BeginAction()) + if (from.BeginAction()) { new LightCycle.NightSightTimer(from).Start(); from.LightLevel = LightCycle.DungeonLevel / 2; @@ -43,9 +43,7 @@ namespace Server.Items Consume(); } else - { from.SendMessage("You already have nightsight."); - } } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Items/Skill Items/Magical/Runebook.cs b/Projects/Scripts/Items/Skill Items/Magical/Runebook.cs index 2bc7d5692..fe054f07e 100644 --- a/Projects/Scripts/Items/Skill Items/Magical/Runebook.cs +++ b/Projects/Scripts/Items/Skill Items/Magical/Runebook.cs @@ -355,13 +355,9 @@ namespace Server.Items if (dropped is RecallRune rune) { if (IsLockedDown && from.AccessLevel < AccessLevel.GameMaster) - { from.SendLocalizedMessage(502413, null, 0x35); // That cannot be done while the book is locked down. - } else if (IsOpen(from)) - { from.SendLocalizedMessage(1005571); // You cannot place objects in the book while viewing the contents. - } else if (Entries.Count < 16) { if (rune.Marked && rune.TargetMap != null) @@ -370,12 +366,12 @@ namespace Server.Items rune.Delete(); - from.Send(new PlaySound(0x42, GetWorldLocation())); + Packets.SendPlaySound(from.NetState, 0x42, GetWorldLocation()); string desc = rune.Description; if (desc == null || (desc = desc.Trim()).Length == 0) - desc = "(indescript)"; + desc = "(nondescript)"; from.SendMessage(desc); @@ -385,15 +381,13 @@ namespace Server.Items from.SendLocalizedMessage(502409); // This rune does not have a marked location. } else - { from.SendLocalizedMessage(502401); // This runebook is full. - } } else if (dropped is RecallScroll) { if (CurCharges < MaxCharges) { - from.Send(new PlaySound(0x249, GetWorldLocation())); + Packets.SendPlaySound(from.NetState, 0x259, GetWorldLocation()); int amount = dropped.Amount; @@ -411,9 +405,7 @@ namespace Server.Items } } else - { from.SendLocalizedMessage(502410); // This book already has the maximum amount of charges. - } } return false; diff --git a/Projects/Scripts/Items/Skill Items/Magical/Spellbook.cs b/Projects/Scripts/Items/Skill Items/Magical/Spellbook.cs index ca99ee343..b97d2ebca 100644 --- a/Projects/Scripts/Items/Skill Items/Magical/Spellbook.cs +++ b/Projects/Scripts/Items/Skill Items/Magical/Spellbook.cs @@ -491,7 +491,7 @@ namespace Server.Items scroll.Delete(); - from.Send(new PlaySound(0x249, GetWorldLocation())); + Packets.SendPlaySound(from.NetState, 0x249, GetWorldLocation()); return true; } } @@ -569,49 +569,16 @@ namespace Server.Items return; if (Parent == null) - { - to.Send(WorldPacket); - } + SendWorldPacketFor(ns); else if (Parent is Item) - { // What will happen if the client doesn't know about our parent? - if (ns.ContainerGridLines) - to.Send(new ContainerContentUpdate6017(this)); - else - to.Send(new ContainerContentUpdate(this)); - } + Packets.SendContainerContentUpdate(ns, this); else if (Parent is Mobile) - { // What will happen if the client doesn't know about our parent? - to.Send(new EquipUpdate(this)); - } + Packets.SendEquipUpdate(ns, this); - if (ns.HighSeas) - to.Send(new DisplaySpellbookHS(this)); - else - to.Send(new DisplaySpellbook(this)); - - if (ObjectPropertyList.Enabled) - { - if (ns.NewSpellbook) - { - to.Send(new NewSpellbookContent(this, ItemID, BookOffset + 1, m_Content)); - } - else - { - if (ns.ContainerGridLines) - to.Send(new SpellbookContent6017(SpellCount, BookOffset + 1, m_Content, this)); - else - to.Send(new SpellbookContent(SpellCount, BookOffset + 1, m_Content, this)); - } - } - else - { - if (ns.ContainerGridLines) - to.Send(new SpellbookContent6017(SpellCount, BookOffset + 1, m_Content, this)); - else - to.Send(new SpellbookContent(SpellCount, BookOffset + 1, m_Content, this)); - } + Packets.SendDisplayContainer(ns, Serial); + Packets.SendSpellbookContent(ns, Serial, ItemID, BookOffset + 1, m_Content); } public override void GetProperties(ObjectPropertyList list) @@ -810,11 +777,9 @@ namespace Server.Items } } - if (Attributes == null) - Attributes = new AosAttributes(this); + Attributes ??= new AosAttributes(this); - if (SkillBonuses == null) - SkillBonuses = new AosSkillBonuses(this); + SkillBonuses ??= new AosSkillBonuses(this); if (Core.AOS && Parent is Mobile mobile) SkillBonuses.AddTo(mobile); diff --git a/Projects/Scripts/Items/Skill Items/Misc/Bandage.cs b/Projects/Scripts/Items/Skill Items/Misc/Bandage.cs index 752c68f87..f842d091d 100644 --- a/Projects/Scripts/Items/Skill Items/Misc/Bandage.cs +++ b/Projects/Scripts/Items/Skill Items/Misc/Bandage.cs @@ -387,7 +387,7 @@ namespace Server.Items double toHeal = min + Utility.RandomDouble() * (max - min); if (Patient.Body.IsMonster || Patient.Body.IsAnimal) - toHeal += Patient.HitsMax / 100; + toHeal += Patient.HitsMax / 100.0; if (Core.AOS) toHeal -= toHeal * Slips * 0.35; // TODO: Verify algorithm diff --git a/Projects/Scripts/Items/Skill Items/Misc/FireHorn.cs b/Projects/Scripts/Items/Skill Items/Misc/FireHorn.cs index 5e0d9c5d0..127cde348 100644 --- a/Projects/Scripts/Items/Skill Items/Misc/FireHorn.cs +++ b/Projects/Scripts/Items/Skill Items/Misc/FireHorn.cs @@ -79,9 +79,8 @@ namespace Server.Items from.Backpack.ConsumeUpTo(typeof(SulfurousAsh), sulfAsh); from.PlaySound(0x15F); - Effects.SendPacket(from, from.Map, - new HuedEffect(EffectType.Moving, from.Serial, Serial.Zero, 0x36D4, from.Location, loc, 5, 0, false, true, 0, - 0)); + + Effects.SendMovingEffect(from, loc, from.Map, 0x36D4, 5, 0, false, true); IPooledEnumerable eable = from.Map.GetMobilesInRange(new Point3D(loc), 2); @@ -92,11 +91,9 @@ namespace Server.Items || Core.AOS && !from.InLOS(m)) return false; - if (m.Player) - playerVsPlayer = true; + playerVsPlayer |= m.Player; return true; - }).ToList(); eable.Free(); diff --git a/Projects/Scripts/Items/Skill Items/Musical Instruments/BaseInstrument.cs b/Projects/Scripts/Items/Skill Items/Musical Instruments/BaseInstrument.cs index b1e840c8b..462ba6d62 100644 --- a/Projects/Scripts/Items/Skill Items/Musical Instruments/BaseInstrument.cs +++ b/Projects/Scripts/Items/Skill Items/Musical Instruments/BaseInstrument.cs @@ -406,13 +406,8 @@ namespace Server.Items number = 1041000; } - if (attrs.Count == 0 && Crafter == null && Name != null) - return; - - EquipmentInfo eqInfo = new EquipmentInfo(number, m_Crafter, false, - attrs.ToArray()); - - from.Send(new DisplayEquipmentInfo(this, eqInfo)); + if (attrs.Count > 0 || Crafter != null || Name == null) + EquipmentPackets.SendDisplayEquipmentInfo(from.NetState, this, number, m_Crafter, false, attrs); } public override void Serialize(GenericWriter writer) diff --git a/Projects/Scripts/Items/Skill Items/Ninjitsu/LeatherNinjaBelt.cs b/Projects/Scripts/Items/Skill Items/Ninjitsu/LeatherNinjaBelt.cs index 2c77e45ea..35773aa8c 100644 --- a/Projects/Scripts/Items/Skill Items/Ninjitsu/LeatherNinjaBelt.cs +++ b/Projects/Scripts/Items/Skill Items/Ninjitsu/LeatherNinjaBelt.cs @@ -6,7 +6,7 @@ using Server.Mobiles; namespace Server.Items { [Flippable(0x2790, 0x27DB)] - public class LeatherNinjaBelt : BaseWaist, IDyable, INinjaWeapon + public class LeatherNinjaBelt : BaseWaist, INinjaWeapon { private Poison m_Poison; private int m_PoisonCharges; @@ -27,18 +27,18 @@ namespace Server.Items public override CraftResource DefaultResource => CraftResource.RegularLeather; - public virtual int WrongAmmoMessage => 1063301; //You can only place shuriken in a ninja belt. - public virtual int NoFreeHandMessage => 1063299; //You must have a free hand to throw shuriken. - public virtual int EmptyWeaponMessage => 1063297; //You have no shuriken in your ninja belt! - public virtual int RecentlyUsedMessage => 1063298; //You cannot throw another shuriken yet. - public virtual int FullWeaponMessage => 1063302; //You cannot add any more shuriken. + public int WrongAmmoMessage => 1063301; //You can only place shuriken in a ninja belt. + public int NoFreeHandMessage => 1063299; //You must have a free hand to throw shuriken. + public int EmptyWeaponMessage => 1063297; //You have no shuriken in your ninja belt! + public int RecentlyUsedMessage => 1063298; //You cannot throw another shuriken yet. + public int FullWeaponMessage => 1063302; //You cannot add any more shuriken. - public virtual int WeaponMinRange => 2; - public virtual int WeaponMaxRange => 10; + public int WeaponMinRange => 2; + public int WeaponMaxRange => 10; - public virtual int WeaponDamage => Utility.RandomMinMax(3, 5); + public int WeaponDamage => Utility.RandomMinMax(3, 5); - public virtual Type AmmoType => typeof(Shuriken); + public Type AmmoType => typeof(Shuriken); [CommandProperty(AccessLevel.GameMaster)] public int UsesRemaining @@ -81,7 +81,8 @@ namespace Server.Items public void AttackAnimation(Mobile from, Mobile to) { - if (from.Body.IsHuman) from.Animate(from.Mounted ? 26 : 9, 7, 1, true, false, 0); + if (from.Body.IsHuman) + from.Animate(from.Mounted ? 26 : 9, 7, 1, true, false, 0); from.PlaySound(0x23A); from.MovingEffect(to, 0x27AC, 1, 0, false, false); @@ -156,4 +157,4 @@ namespace Server.Items } } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Items/Skill Items/Tailor Items/Misc/Dyes.cs b/Projects/Scripts/Items/Skill Items/Tailor Items/Misc/Dyes.cs index 8a86ab078..ff72147f8 100644 --- a/Projects/Scripts/Items/Skill Items/Tailor Items/Misc/Dyes.cs +++ b/Projects/Scripts/Items/Skill Items/Tailor Items/Misc/Dyes.cs @@ -1,4 +1,3 @@ -using Server.HuePickers; using Server.Targeting; namespace Server.Items diff --git a/Projects/Scripts/Items/Skill Items/Thief/DisguisePersistance.cs b/Projects/Scripts/Items/Skill Items/Thief/DisguisePersistance.cs index 50d3b0ccf..f41182141 100644 --- a/Projects/Scripts/Items/Skill Items/Thief/DisguisePersistance.cs +++ b/Projects/Scripts/Items/Skill Items/Thief/DisguisePersistance.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; namespace Server.Items { @@ -31,12 +30,10 @@ namespace Server.Items writer.Write(timerCount); - foreach (KeyValuePair entry in DisguiseTimers.Timers) + foreach (var (m, value) in DisguiseTimers.Timers) { - Mobile m = entry.Key; - writer.Write(m); - writer.Write(entry.Value.Next - DateTime.UtcNow); + writer.Write(value.Next - DateTime.UtcNow); writer.Write(m.NameMod); } } diff --git a/Projects/Scripts/Items/Skill Items/Tinkering/Spyglass.cs b/Projects/Scripts/Items/Skill Items/Tinkering/Spyglass.cs index 2dae504f3..711d7b173 100644 --- a/Projects/Scripts/Items/Skill Items/Tinkering/Spyglass.cs +++ b/Projects/Scripts/Items/Skill Items/Tinkering/Spyglass.cs @@ -20,10 +20,10 @@ namespace Server.Items from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1008155); // You peer into the heavens, seeking the moons... - from.Send(new MessageLocalizedAffix(from.Serial, from.Body, MessageType.Regular, 0x3B2, 3, - 1008146 + (int)Clock.GetMoonPhase(Map.Trammel, from.X, from.Y), "", AffixType.Prepend, "Trammel : ", "")); - from.Send(new MessageLocalizedAffix(from.Serial, from.Body, MessageType.Regular, 0x3B2, 3, - 1008146 + (int)Clock.GetMoonPhase(Map.Felucca, from.X, from.Y), "", AffixType.Prepend, "Felucca : ", "")); + Packets.SendMessageLocalizedAffix(from.NetState, from.Serial, from.Body, MessageType.Regular, 0x3B2, 3, + 1008146 + (int)Clock.GetMoonPhase(Map.Trammel, from.X, from.Y), "", AffixType.Prepend, "Trammel : "); + Packets.SendMessageLocalizedAffix(from.NetState, from.Serial, from.Body, MessageType.Regular, 0x3B2, 3, + 1008146 + (int)Clock.GetMoonPhase(Map.Felucca, from.X, from.Y), "", AffixType.Prepend, "Felucca : "); if (from is PlayerMobile player) { @@ -33,7 +33,7 @@ namespace Server.Items return; FindIngredientObjective obj = qs.FindObjective(); - + if (obj?.Completed == false && obj.Ingredient == Ingredient.StarChart) { Clock.GetTime(from.Map, from.X, from.Y, out int hours, out int _); @@ -68,4 +68,4 @@ namespace Server.Items int version = reader.ReadInt(); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Items/Special/8th Anniversary Items/Dawn's Music Box/DawnsMusicBox.cs b/Projects/Scripts/Items/Special/8th Anniversary Items/Dawn's Music Box/DawnsMusicBox.cs index e5d2fcfb0..3216bf7d0 100644 --- a/Projects/Scripts/Items/Special/8th Anniversary Items/Dawn's Music Box/DawnsMusicBox.cs +++ b/Projects/Scripts/Items/Special/8th Anniversary Items/Dawn's Music Box/DawnsMusicBox.cs @@ -7,16 +7,6 @@ using Server.Network; namespace Server.Items { - public sealed class StopMusic : Packet - { - public static readonly Packet Instance = SetStatic(new StopMusic()); - - public StopMusic() : base(0x6D, 3) - { - m_Stream.Write((short)0x1FFF); - } - } - [Flippable(0x2AF9, 0x2AFD)] public class DawnsMusicBox : Item, ISecurable { @@ -158,7 +148,7 @@ namespace Server.Items else m_ItemID = ItemID; - m.Send(new PlayMusic(music)); + Packets.SendPlayMusic(m.NetState, music); m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(0.5), TimeSpan.FromSeconds(0.5), 4, Animate); } @@ -167,7 +157,7 @@ namespace Server.Items if (m_Timer?.Running == true) m_Timer.Stop(); - m.Send(StopMusic.Instance); + Packets.SendStopMusic(m.NetState); if (m_Count > 0) ItemID = m_ItemID; diff --git a/Projects/Scripts/Items/Special/Evil Home Decor Collection/SacrificialAltar.cs b/Projects/Scripts/Items/Special/Evil Home Decor Collection/SacrificialAltar.cs index c8dfa3341..faa446550 100644 --- a/Projects/Scripts/Items/Special/Evil Home Decor Collection/SacrificialAltar.cs +++ b/Projects/Scripts/Items/Special/Evil Home Decor Collection/SacrificialAltar.cs @@ -108,7 +108,7 @@ namespace Server.Items Point3D location = Location; location.Z += 10; - Effects.SendLocationEffect(location, Map, 0x3709, 10, 10, 0x356, 0); + Effects.SendLocationEffect(location, Map, 0x3709, 10, 10, 0x356); Effects.PlaySound(location, Map, 0x32E); if (Items.Count > 0) diff --git a/Projects/Scripts/Items/Special/House Raffle/HouseRaffleStone.cs b/Projects/Scripts/Items/Special/House Raffle/HouseRaffleStone.cs index 9186c5dc1..a23ff661a 100644 --- a/Projects/Scripts/Items/Special/House Raffle/HouseRaffleStone.cs +++ b/Projects/Scripts/Items/Special/House Raffle/HouseRaffleStone.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Net; using System.Text; using Server.Accounting; @@ -290,22 +291,9 @@ namespace Server.Items } } - private bool HasEntered(Mobile from) - { - if (!(from.Account is Account acc)) - return false; - - foreach (RaffleEntry entry in Entries) - if (entry.From != null) - { - Account entryAcc = entry.From.Account as Account; - - if (entryAcc == acc) - return true; - } - - return false; - } + private bool HasEntered(Mobile from) => + from.Account is Account acc && + (from entry in Entries select entry.From?.Account as Account).Any(entryAcc => entryAcc == acc); private bool IsAtIPLimit(Mobile from) { @@ -315,12 +303,7 @@ namespace Server.Items IPAddress address = from.NetState.Address; int tickets = 0; - foreach (RaffleEntry entry in Entries) - if (Utility.IPMatchClassC(entry.Address, address)) - if (++tickets >= EntryLimitPerIP) - return true; - - return false; + return Entries.Where(entry => Utility.IPMatchClassC(entry.Address, address)).Any(entry => ++tickets >= EntryLimitPerIP); } public static string FormatLocation(Point3D loc, Map map, bool displayMap) diff --git a/Projects/Scripts/Items/Special/Solen Items/BagOfSending.cs b/Projects/Scripts/Items/Special/Solen Items/BagOfSending.cs index 33832fb3d..a186285ba 100644 --- a/Projects/Scripts/Items/Special/Solen Items/BagOfSending.cs +++ b/Projects/Scripts/Items/Special/Solen Items/BagOfSending.cs @@ -219,54 +219,34 @@ namespace Server.Items return; if (from.Region.IsPartOf()) - { from.SendMessage("You may not do that in jail."); - } else if (!m_Bag.IsChildOf(from.Backpack)) - { - MessageHelper.SendLocalizedMessageTo(m_Bag, from, 1062334, - 0x59); // The bag of sending must be in your backpack. 1054107 is gone from client, using generic response - } + MessageHelper.SendLocalizedMessageTo(m_Bag, from, 1054107, + 0x59); // This item must be in your backpack. else if (m_Bag.Charges == 0) - { MessageHelper.SendLocalizedMessageTo(m_Bag, from, 1042544, 0x59); // This item is out of charges. - } else if (targeted is Item item) { int reqCharges = (int)Math.Max(1, Math.Ceiling(item.TotalWeight / 10.0)); if (!item.IsChildOf(from.Backpack)) - { MessageHelper.SendLocalizedMessageTo(m_Bag, from, 1054152, 0x59); // You may only send items from your backpack to your bank box. - } else if (item is BagOfSending || item is Container) - { - from.Send(new AsciiMessage(m_Bag.Serial, m_Bag.ItemID, MessageType.Regular, 0x3B2, 3, "", - "You cannot send a container through the bag of sending.")); - } + Packets.SendAsciiMessage(from.NetState, m_Bag.Serial, m_Bag.ItemID, MessageType.Regular, 0x3B2, 3, "", + "You cannot send a container through the bag of sending." ); else if (item.LootType == LootType.Cursed) - { MessageHelper.SendLocalizedMessageTo(m_Bag, from, 1054108, 0x59); // The bag of sending rejects the cursed item. - } else if (!item.VerifyMove(from) || item is QuestItem || item.Nontransferable) - { MessageHelper.SendLocalizedMessageTo(m_Bag, from, 1054109, 0x59); // The bag of sending rejects that item. - } else if (SpellHelper.IsDoomGauntlet(from.Map, from.Location)) - { from.SendLocalizedMessage(1062089); // You cannot use that here. - } else if (!from.BankBox.TryDropItem(from, item, false)) - { MessageHelper.SendLocalizedMessageTo(m_Bag, from, 1054110, 0x59); // Your bank box is full. - } else if (Core.ML && reqCharges > m_Bag.Charges) - { from.SendLocalizedMessage(1079932); //You don't have enough charges to send that much weight - } else { m_Bag.Charges -= Core.ML ? reqCharges : 1; @@ -278,4 +258,4 @@ namespace Server.Items } } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Items/Special/Solen Items/BallOfSummoning.cs b/Projects/Scripts/Items/Special/Solen Items/BallOfSummoning.cs index 24a0bee0e..27e16780b 100644 --- a/Projects/Scripts/Items/Special/Solen Items/BallOfSummoning.cs +++ b/Projects/Scripts/Items/Special/Solen Items/BallOfSummoning.cs @@ -177,41 +177,27 @@ namespace Server.Items return; if (Charges == 0) - { SendLocalizedMessageTo(from, 1054122); // The Crystal Ball darkens. It must be charged before it can be used again. - } else if (pet is BaseMount mount && mount.Rider == from) - { MessageHelper.SendLocalizedMessageTo(this, from, 1054124, 0x36); // The Crystal Ball fills with a yellow mist. Why would you summon your pet while riding it? - } else if (pet.Map == Map.Internal && (!pet.IsStabled || from.Followers + pet.ControlSlots > from.FollowersMax)) - { MessageHelper.SendLocalizedMessageTo(this, from, 1054125, 0x5); // The Crystal Ball fills with a blue mist. Your pet is not responding to the summons. - } else if ((!pet.Controlled || pet.ControlMaster != from) && !from.Stabled.Contains(pet)) - { MessageHelper.SendLocalizedMessageTo(this, from, 1054126, 0x8FD); // The Crystal Ball fills with a grey mist. You are not the owner of the pet you are attempting to summon. - } else if (!pet.IsBonded) - { MessageHelper.SendLocalizedMessageTo(this, from, 1054127, 0x22); // The Crystal Ball fills with a red mist. You appear to have let your bond to your pet deteriorate. - } else if (from.Map == Map.Ilshenar || from.Region.IsPartOf() || from.Region.IsPartOf() || from.Region.IsPartOf()) - { - from.Send(new AsciiMessage(Serial, ItemID, MessageType.Regular, 0x22, 3, "", - "You cannot summon your pet to this location.")); - } + Packets.SendAsciiMessage(from.NetState, Serial, ItemID, MessageType.Regular, 0x22, 3, "", + "You cannot summon your pet to this location."); else if (Core.ML && from is PlayerMobile mobile && DateTime.UtcNow < mobile.LastPetBallTime.AddSeconds(15.0)) - { MessageHelper.SendLocalizedMessageTo(this, mobile, 1080072, 0x22); // You must wait a few seconds before you can summon your pet. - } else { if (Core.ML) diff --git a/Projects/Scripts/Items/Special/Solen Items/BraceletOfBinding.cs b/Projects/Scripts/Items/Special/Solen Items/BraceletOfBinding.cs index 4417b9b8e..9e4478191 100644 --- a/Projects/Scripts/Items/Special/Solen Items/BraceletOfBinding.cs +++ b/Projects/Scripts/Items/Special/Solen Items/BraceletOfBinding.cs @@ -5,7 +5,6 @@ using Server.Factions; using Server.Misc; using Server.Mobiles; using Server.Network; -using Server.Prompts; using Server.Regions; using Server.Spells; using Server.Targeting; diff --git a/Projects/Scripts/Items/Special/SoulStone.cs b/Projects/Scripts/Items/Special/SoulStone.cs index ea64d856e..aee2dd8ed 100644 --- a/Projects/Scripts/Items/Special/SoulStone.cs +++ b/Projects/Scripts/Items/Special/SoulStone.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using Server.Accounting; using Server.Engines.VeteranRewards; using Server.Factions; @@ -579,7 +580,6 @@ namespace Server.Items return; } - SkillName skill = m_Stone.Skill; double skillValue = m_Stone.SkillValue; Skill fromSkill = from.Skills[m_Stone.Skill]; @@ -589,27 +589,8 @@ namespace Server.Items */ int requiredAmount = (int)(skillValue * 10) - fromSkill.BaseFixedPoint - (from.SkillsCap - from.SkillsTotal); - bool cannotAbsorb = false; - - if (fromSkill.Lock != SkillLock.Up) - { - cannotAbsorb = true; - } - else if (requiredAmount > 0) - { - int available = 0; - - for (int i = 0; i < from.Skills.Length; ++i) - { - if (from.Skills[i].Lock != SkillLock.Down) - continue; - - available += from.Skills[i].BaseFixedPoint; - } - - if (requiredAmount > available) - cannotAbsorb = true; - } + bool cannotAbsorb = fromSkill.Lock != SkillLock.Up || requiredAmount > 0 && + requiredAmount > from.Skills.Where(t => t.Lock == SkillLock.Down).Sum(t => t.BaseFixedPoint); if (cannotAbsorb) { diff --git a/Projects/Scripts/Items/Special/Special Scrolls/PowerScroll.cs b/Projects/Scripts/Items/Special/Special Scrolls/PowerScroll.cs index 1e567af7b..c5de04d58 100644 --- a/Projects/Scripts/Items/Special/Special Scrolls/PowerScroll.cs +++ b/Projects/Scripts/Items/Special/Special Scrolls/PowerScroll.cs @@ -81,10 +81,12 @@ namespace Server.Items } public override int Message => - 1049469; /* Using a scroll increases the maximum amount of a specific skill or your maximum statistics. - * When used, the effect is not immediately seen without a gain of points with that skill or statistics. - * You can view your maximum skill values in your skills window. - * You can view your maximum statistic value in your statistics window. */ + 1049469; + /* Using a scroll increases the maximum amount of a specific skill or your maximum statistics. + * When used, the effect is not immediately seen without a gain of points with that skill or statistics. + * You can view your maximum skill values in your skills window. + * You can view your maximum statistic value in your statistics window. + */ public override int Title { @@ -93,10 +95,12 @@ namespace Server.Items double level = (Value - 105.0) / 5.0; if (level >= 0.0 && level <= 3.0 && Value % 5.0 == 0.0) - return 1049635 + (int)level; /* Wonderous Scroll (105 Skill): OR - * Exalted Scroll (110 Skill): OR - * Mythical Scroll (115 Skill): OR - * Legendary Scroll (120 Skill): */ + return 1049635 + (int)level; + /* Wonderous Scroll (105 Skill): OR + * Exalted Scroll (110 Skill): OR + * Mythical Scroll (115 Skill): OR + * Legendary Scroll (120 Skill): + */ return 0; } @@ -154,10 +158,12 @@ namespace Server.Items double level = (Value - 105.0) / 5.0; if (level >= 0.0 && level <= 3.0 && Value % 5.0 == 0.0) - list.Add(1049639 + (int)level, GetNameLocalized()); /* a wonderous scroll of ~1_type~ (105 Skill) OR - * an exalted scroll of ~1_type~ (110 Skill) OR - * a mythical scroll of ~1_type~ (115 Skill) OR - * a legendary scroll of ~1_type~ (120 Skill) */ + list.Add(1049639 + (int)level, GetNameLocalized()); + /* a wonderous scroll of ~1_type~ (105 Skill) OR + * an exalted scroll of ~1_type~ (110 Skill) OR + * a mythical scroll of ~1_type~ (115 Skill) OR + * a legendary scroll of ~1_type~ (120 Skill) + */ else list.Add("a power scroll of {0} ({1} Skill)", GetName(), Value); } diff --git a/Projects/Scripts/Items/Special/Special Scrolls/ScrollofAlacrity.cs b/Projects/Scripts/Items/Special/Special Scrolls/ScrollofAlacrity.cs index 1728e261d..aa4921f2f 100644 --- a/Projects/Scripts/Items/Special/Special Scrolls/ScrollofAlacrity.cs +++ b/Projects/Scripts/Items/Special/Special Scrolls/ScrollofAlacrity.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using Server.Engines.MLQuests; using Server.Engines.MLQuests.Objectives; using Server.Mobiles; @@ -21,9 +22,11 @@ namespace Server.Items public override int LabelNumber => 1078604; // Scroll of Alacrity public override int Message => - 1078602; /*Using a Scroll of Transcendence for a given skill will permanently increase your current - *level in that skill by the amount of points displayed on the scroll. - *As you may not gain skills beyond your maximum skill cap, any excess points will be lost.*/ + 1078602; + /* Using a Scroll of Transcendence for a given skill will permanently increase your current + * level in that skill by the amount of points displayed on the scroll. + * As you may not gain skills beyond your maximum skill cap, any excess points will be lost. + */ public override string DefaultTitle => "Scroll of Alacrity:"; @@ -74,8 +77,10 @@ namespace Server.Items if (tskill >= tcap || from.Skills[Skill].Lock != SkillLock.Up) { from.SendLocalizedMessage( - 1094935); /*You cannot increase this skill at this time. The skill may be locked or set to lower in your skill menu. - *If you are at your total skill cap, you must use a Powerscroll to increase your current skill cap.*/ + 1094935); + /* You cannot increase this skill at this time. The skill may be locked or set to lower in your skill menu. + * If you are at your total skill cap, you must use a Powerscroll to increase your current skill cap. + */ return; } diff --git a/Projects/Scripts/Items/Special/Special Scrolls/ScrollofTranscendence.cs b/Projects/Scripts/Items/Special/Special Scrolls/ScrollofTranscendence.cs index 3eeefe93c..d1d1c66a0 100644 --- a/Projects/Scripts/Items/Special/Special Scrolls/ScrollofTranscendence.cs +++ b/Projects/Scripts/Items/Special/Special Scrolls/ScrollofTranscendence.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using Server.Engines.MLQuests; using Server.Engines.MLQuests.Objectives; using Server.Mobiles; @@ -21,9 +22,11 @@ namespace Server.Items public override int LabelNumber => 1094934; // Scroll of Transcendence public override int Message => - 1094933; /*Using a Scroll of Transcendence for a given skill will permanently increase your current - *level in that skill by the amount of points displayed on the scroll. - *As you may not gain skills beyond your maximum skill cap, any excess points will be lost.*/ + 1094933; + /* Using a Scroll of Transcendence for a given skill will permanently increase your current + * level in that skill by the amount of points displayed on the scroll. + * As you may not gain skills beyond your maximum skill cap, any excess points will be lost. + */ public override string DefaultTitle => $"Scroll of Transcendence ({Value} Skill):"; @@ -112,8 +115,10 @@ namespace Server.Items if (!canGain) { from.SendLocalizedMessage( - 1094935); /*You cannot increase this skill at this time. The skill may be locked or set to lower in your skill menu. - *If you are at your total skill cap, you must use a Powerscroll to increase your current skill cap.*/ + 1094935); + /* You cannot increase this skill at this time. The skill may be locked or set to lower in your skill menu. + * If you are at your total skill cap, you must use a Powerscroll to increase your current skill cap. + */ return; } diff --git a/Projects/Scripts/Items/Special/Special Scrolls/SpecialScroll.cs b/Projects/Scripts/Items/Special/Special Scrolls/SpecialScroll.cs index 40fefa434..9090b11c5 100644 --- a/Projects/Scripts/Items/Special/Special Scrolls/SpecialScroll.cs +++ b/Projects/Scripts/Items/Special/Special Scrolls/SpecialScroll.cs @@ -158,7 +158,7 @@ namespace Server.Items AddHtmlLocalized(310, 20, 120, 20, AosSkillBonuses.GetLabel(m_Scroll.Skill), 0xFFFFFF); } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (info.ButtonID == 1) m_Scroll.Use(m_Mobile); diff --git a/Projects/Scripts/Items/Special/Special Scrolls/StatScroll.cs b/Projects/Scripts/Items/Special/Special Scrolls/StatScroll.cs index 4ebb96f5c..c3de85fcb 100644 --- a/Projects/Scripts/Items/Special/Special Scrolls/StatScroll.cs +++ b/Projects/Scripts/Items/Special/Special Scrolls/StatScroll.cs @@ -12,10 +12,12 @@ namespace Server.Items } public override int Message => - 1049469; /* Using a scroll increases the maximum amount of a specific skill or your maximum statistics. - * When used, the effect is not immediately seen without a gain of points with that skill or statistics. - * You can view your maximum skill values in your skills window. - * You can view your maximum statistic value in your statistics window. */ + 1049469; + /* Using a scroll increases the maximum amount of a specific skill or your maximum statistics. + * When used, the effect is not immediately seen without a gain of points with that skill or statistics. + * You can view your maximum skill values in your skills window. + * You can view your maximum statistic value in your statistics window. + */ public override int Title { @@ -24,11 +26,13 @@ namespace Server.Items int level = ((int)Value - 230) / 5; if (level >= 0 && level <= 4 && Value % 5 == 0) - return 1049458 + level; /* Wonderous Scroll (+5 Maximum Stats): OR - * Exalted Scroll (+10 Maximum Stats): OR - * Mythical Scroll (+15 Maximum Stats): OR - * Legendary Scroll (+20 Maximum Stats): OR - * Ultimate Scroll (+25 Maximum Stats): */ + return 1049458 + level; + /* Wonderous Scroll (+5 Maximum Stats): OR + * Exalted Scroll (+10 Maximum Stats): OR + * Mythical Scroll (+15 Maximum Stats): OR + * Legendary Scroll (+20 Maximum Stats): OR + * Ultimate Scroll (+25 Maximum Stats): + */ return 0; } @@ -42,11 +46,13 @@ namespace Server.Items int level = ((int)Value - 230) / 5; if (level >= 0 && level <= 4 && (int)Value % 5 == 0) - list.Add(1049463 + level, "#1049476"); /* a wonderous scroll of ~1_type~ (+5 Maximum Stats) OR - * an exalted scroll of ~1_type~ (+10 Maximum Stats) OR - * a mythical scroll of ~1_type~ (+15 Maximum Stats) OR - * a legendary scroll of ~1_type~ (+20 Maximum Stats) OR - * an ultimate scroll of ~1_type~ (+25 Maximum Stats) */ + list.Add(1049463 + level, "#1049476"); + /* a wonderous scroll of ~1_type~ (+5 Maximum Stats) OR + * an exalted scroll of ~1_type~ (+10 Maximum Stats) OR + * a mythical scroll of ~1_type~ (+15 Maximum Stats) OR + * a legendary scroll of ~1_type~ (+20 Maximum Stats) OR + * an ultimate scroll of ~1_type~ (+25 Maximum Stats) + */ else list.Add("a scroll of power ({0}{1} Maximum Stats)", Value - 225 >= 0 ? "+" : "", Value - 225); } diff --git a/Projects/Scripts/Items/Special/Veteran Rewards/AnkhOfSacrifice.cs b/Projects/Scripts/Items/Special/Veteran Rewards/AnkhOfSacrifice.cs index 4d81265d3..cbdb6164a 100644 --- a/Projects/Scripts/Items/Special/Veteran Rewards/AnkhOfSacrifice.cs +++ b/Projects/Scripts/Items/Special/Veteran Rewards/AnkhOfSacrifice.cs @@ -135,9 +135,9 @@ namespace Server.Items { } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { - Mobile from = state.Mobile; + Mobile from = sender.Mobile; if (info.ButtonID == 1 || info.ButtonID == 2) { @@ -147,9 +147,10 @@ namespace Server.Items return; } - if (from is PlayerMobile mobile) mobile.AnkhNextUse = DateTime.UtcNow + TimeSpan.FromHours(1); + if (from is PlayerMobile mobile) + mobile.AnkhNextUse = DateTime.UtcNow + TimeSpan.FromHours(1); - base.OnResponse(state, info); + base.OnResponse(sender, info); } } } diff --git a/Projects/Scripts/Items/Special/Veteran Rewards/Brazier.cs b/Projects/Scripts/Items/Special/Veteran Rewards/Brazier.cs index 7f43e8011..724723140 100644 --- a/Projects/Scripts/Items/Special/Veteran Rewards/Brazier.cs +++ b/Projects/Scripts/Items/Special/Veteran Rewards/Brazier.cs @@ -63,8 +63,7 @@ namespace Server.Items public void TurnOn() { - if (m_Fire == null) - m_Fire = new Item(); + m_Fire ??= new Item(); m_Fire.ItemID = 0x19AB; m_Fire.Movable = false; diff --git a/Projects/Scripts/Items/Special/Veteran Rewards/Cannon.cs b/Projects/Scripts/Items/Special/Veteran Rewards/Cannon.cs index 3c7c68035..a16a27f78 100644 --- a/Projects/Scripts/Items/Special/Veteran Rewards/Cannon.cs +++ b/Projects/Scripts/Items/Special/Veteran Rewards/Cannon.cs @@ -63,37 +63,37 @@ namespace Server.Items switch (direction) { case CannonDirection.North: - { - AddComponent(new CannonAddonComponent(0xE8D), 0, 0, 0); - AddComponent(new CannonAddonComponent(0xE8C), 0, 1, 0); - AddComponent(new CannonAddonComponent(0xE8B), 0, 2, 0); + { + AddComponent(new CannonAddonComponent(0xE8D), 0, 0, 0); + AddComponent(new CannonAddonComponent(0xE8C), 0, 1, 0); + AddComponent(new CannonAddonComponent(0xE8B), 0, 2, 0); - break; - } + break; + } case CannonDirection.East: - { - AddComponent(new CannonAddonComponent(0xE96), 0, 0, 0); - AddComponent(new CannonAddonComponent(0xE95), -1, 0, 0); - AddComponent(new CannonAddonComponent(0xE94), -2, 0, 0); + { + AddComponent(new CannonAddonComponent(0xE96), 0, 0, 0); + AddComponent(new CannonAddonComponent(0xE95), -1, 0, 0); + AddComponent(new CannonAddonComponent(0xE94), -2, 0, 0); - break; - } + break; + } case CannonDirection.South: - { - AddComponent(new CannonAddonComponent(0xE91), 0, 0, 0); - AddComponent(new CannonAddonComponent(0xE92), 0, -1, 0); - AddComponent(new CannonAddonComponent(0xE93), 0, -2, 0); + { + AddComponent(new CannonAddonComponent(0xE91), 0, 0, 0); + AddComponent(new CannonAddonComponent(0xE92), 0, -1, 0); + AddComponent(new CannonAddonComponent(0xE93), 0, -2, 0); - break; - } + break; + } default: - { - AddComponent(new CannonAddonComponent(0xE8E), 0, 0, 0); - AddComponent(new CannonAddonComponent(0xE8F), 1, 0, 0); - AddComponent(new CannonAddonComponent(0xE90), 2, 0, 0); + { + AddComponent(new CannonAddonComponent(0xE8E), 0, 0, 0); + AddComponent(new CannonAddonComponent(0xE8F), 1, 0, 0); + AddComponent(new CannonAddonComponent(0xE90), 2, 0, 0); - break; - } + break; + } } } @@ -114,7 +114,7 @@ namespace Server.Items } [CommandProperty(AccessLevel.GameMaster)] - public CannonDirection CannonDirection{ get; private set; } + public CannonDirection CannonDirection { get; private set; } [CommandProperty(AccessLevel.GameMaster)] public int Charges @@ -261,34 +261,19 @@ namespace Server.Items { if (!Utility.InRange(new Point3D(p), m_Cannon.Location, 2)) { - bool allow = false; int x = p.X - m_Cannon.X; int y = p.Y - m_Cannon.Y; - switch (m_Cannon.CannonDirection) + bool allow = m_Cannon.CannonDirection switch { - case CannonDirection.North: - if (y < 0 && Math.Abs(x) <= -y / 3) - allow = true; - break; - case CannonDirection.East: - if (x > 0 && Math.Abs(y) <= x / 3) - allow = true; - - break; - case CannonDirection.South: - if (y > 0 && Math.Abs(x) <= y / 3) - allow = true; - - break; - case CannonDirection.West: - if (x < 0 && Math.Abs(y) <= -x / 3) - allow = true; - - break; - } + CannonDirection.North => y < 0 && Math.Abs(x) <= -y / 3, + CannonDirection.East => x > 0 && Math.Abs(y) <= x / 3, + CannonDirection.South => y > 0 && Math.Abs(x) <= y / 3, + CannonDirection.West => x < 0 && Math.Abs(y) <= -x / 3, + _ => false, + }; if (allow && Utility.InRange(new Point3D(p), m_Cannon.Location, 14)) m_Cannon.DoFireEffect(p); @@ -301,9 +286,7 @@ namespace Server.Items } } else - { from.SendLocalizedMessage(1049630); // You cannot see that target! - } } protected override void OnTargetOutOfRange(Mobile from, object targeted) @@ -341,10 +324,10 @@ namespace Server.Items AddHtmlLocalized(195, 109, 120, 20, 1076197, 0x7FFF); // Recharge } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (m_Cannon?.Deleted == false && info.ButtonID == (int)Buttons.Recharge) - m_Cannon.Fill(state.Mobile, m_Keg); + m_Cannon.Fill(sender.Mobile, m_Keg); } private enum Buttons @@ -373,7 +356,8 @@ namespace Server.Items public override BaseAddon Addon => new CannonAddon(m_Direction) { - Charges = m_Charges, IsRewardItem = m_IsRewardItem + Charges = m_Charges, + IsRewardItem = m_IsRewardItem }; [CommandProperty(AccessLevel.GameMaster)] diff --git a/Projects/Scripts/Items/Special/Veteran Rewards/WeaponEngravingTool.cs b/Projects/Scripts/Items/Special/Veteran Rewards/WeaponEngravingTool.cs index 481b6c4c5..9090a7077 100644 --- a/Projects/Scripts/Items/Special/Veteran Rewards/WeaponEngravingTool.cs +++ b/Projects/Scripts/Items/Special/Veteran Rewards/WeaponEngravingTool.cs @@ -243,7 +243,7 @@ namespace Server.Items AddTextEntry(75, 245, 350, 40, 0x0, (int)Buttons.Text, ""); } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (m_Tool?.Deleted != false || m_Target?.Deleted != false) return; @@ -319,12 +319,12 @@ namespace Server.Items AddHtmlLocalized(40, 109, 100, 20, 1060051, 0x7FFF); // CANCEL } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (m_Engraver?.Deleted != false || info.ButtonID != (int)Buttons.Confirm) return; - m_Engraver.Recharge(state.Mobile, m_Guildmaster); + m_Engraver.Recharge(sender.Mobile, m_Guildmaster); } private enum Buttons diff --git a/Projects/Scripts/Items/Talismans/TalismanSlayer.cs b/Projects/Scripts/Items/Talismans/TalismanSlayer.cs index 15b84549a..71966f898 100644 --- a/Projects/Scripts/Items/Talismans/TalismanSlayer.cs +++ b/Projects/Scripts/Items/Talismans/TalismanSlayer.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Server.Mobiles; namespace Server.Items @@ -73,9 +74,7 @@ namespace Server.Items }, [TalismanSlayerName.Bovine] = new[] { - typeof(Cow), typeof(Bull), typeof(Gaman) /*, typeof( MinotaurCaptain ), - typeof( MinotaurScout ), typeof( Minotaur )*/ - // TODO TormentedMinotaur + typeof(Cow), typeof(Bull), typeof(Gaman), typeof(TormentedMinotaur) } }; } @@ -83,15 +82,11 @@ namespace Server.Items public static bool Slays(TalismanSlayerName name, Mobile m) { if (m == null || !m_Table.TryGetValue(name, out Type[] types) || types == null) - return false;; + return false; Type type = m.GetType(); - for (int i = 0; i < types.Length; i++) - if (types[i].IsAssignableFrom(type)) - return true; - - return false; + return types.Any(t => t.IsAssignableFrom(type)); } } } diff --git a/Projects/Scripts/Items/Talismans/TalismanSummons.cs b/Projects/Scripts/Items/Talismans/TalismanSummons.cs index e2e4e933f..6863a4c5a 100644 --- a/Projects/Scripts/Items/Talismans/TalismanSummons.cs +++ b/Projects/Scripts/Items/Talismans/TalismanSummons.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using Server.ContextMenus; using Server.Items; +using Server.Regions; namespace Server.Mobiles { @@ -396,9 +397,6 @@ namespace Server.Mobiles int version = reader.ReadEncodedInt(); } - /* - // An area attack that only damages staff, wtf? - private DateTime m_NextWave; public void AreaHeatDamage() @@ -408,29 +406,20 @@ namespace Server.Mobiles if ( mob != null ) { if ( mob.InRange( Location, 2 ) ) - { - if ( mob.AccessLevel != AccessLevel.Player ) + if ( mob.AccessLevel == AccessLevel.Player ) { AOS.Damage( mob, Utility.Random( 2, 3 ), 0, 100, 0, 0, 0 ); mob.SendLocalizedMessage( 1008112 ); // The intense heat is damaging you! } - } - GuardedRegion r = Region as GuardedRegion; - - if ( r != null && mob.Alive ) - { + if ( Region is GuardedRegion && mob.Alive ) foreach ( Mobile m in GetMobilesInRange( 2 ) ) - { if ( !mob.CanBeHarmful( m ) ) mob.CriminalAction( false ); - } - } } m_NextWave = DateTime.UtcNow + TimeSpan.FromSeconds( 3 ); } - */ } public class SummonedOrcBrute : BaseTalismanSummon @@ -631,4 +620,4 @@ namespace Server.Mobiles int version = reader.ReadEncodedInt(); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Items/Traps/GasTrap.cs b/Projects/Scripts/Items/Traps/GasTrap.cs index a6950be9c..9bd0efdef 100644 --- a/Projects/Scripts/Items/Traps/GasTrap.cs +++ b/Projects/Scripts/Items/Traps/GasTrap.cs @@ -35,7 +35,7 @@ namespace Server.Items [CommandProperty(AccessLevel.GameMaster)] public GasTrapType Type { - get + get => ItemID switch { return ItemID switch { @@ -69,7 +69,7 @@ namespace Server.Items if (Poison == null || !from.Player || !from.Alive || from.AccessLevel > AccessLevel.Player) return; - Effects.SendLocationEffect(Location, Map, GetBaseID(Type) - 2, 16, 3, GetEffectHue(), 0); + Effects.SendLocationEffect(Location, Map, GetBaseID(Type) - 2, 16, 3, GetEffectHue()); Effects.PlaySound(Location, Map, 0x231); from.ApplyPoison(from, Poison); diff --git a/Projects/Scripts/Items/Traps/GiantSpikeTrap.cs b/Projects/Scripts/Items/Traps/GiantSpikeTrap.cs index f5425d39e..121d9a38e 100644 --- a/Projects/Scripts/Items/Traps/GiantSpikeTrap.cs +++ b/Projects/Scripts/Items/Traps/GiantSpikeTrap.cs @@ -24,7 +24,7 @@ namespace Server.Items if (from.AccessLevel > AccessLevel.Player) return; - Effects.SendLocationEffect(Location, Map, 0x1D99, 48, 2, GetEffectHue(), 0); + Effects.SendLocationEffect(Location, Map, 0x1D99, 48, 2, GetEffectHue()); if (from.Alive && CheckRange(from.Location, 0)) SpellHelper.Damage(TimeSpan.FromTicks(1), from, from, Utility.Dice(10, 7, 0)); diff --git a/Projects/Scripts/Items/Traps/SawTrap.cs b/Projects/Scripts/Items/Traps/SawTrap.cs index 7b1de8d2c..8b28281d1 100644 --- a/Projects/Scripts/Items/Traps/SawTrap.cs +++ b/Projects/Scripts/Items/Traps/SawTrap.cs @@ -26,7 +26,7 @@ namespace Server.Items [CommandProperty(AccessLevel.GameMaster)] public SawTrapType Type { - get + get => ItemID switch { return ItemID switch { @@ -62,7 +62,7 @@ namespace Server.Items if (!from.Alive || from.AccessLevel > AccessLevel.Player) return; - Effects.SendLocationEffect(Location, Map, GetBaseID(Type) + 1, 6, 3, GetEffectHue(), 0); + Effects.SendLocationEffect(Location, Map, GetBaseID(Type) + 1, 6, 3, GetEffectHue()); Effects.PlaySound(Location, Map, 0x21C); SpellHelper.Damage(TimeSpan.FromTicks(1), from, from, Utility.RandomMinMax(5, 15)); diff --git a/Projects/Scripts/Items/Traps/SpikeTrap.cs b/Projects/Scripts/Items/Traps/SpikeTrap.cs index 0a4a636df..843b02e07 100644 --- a/Projects/Scripts/Items/Traps/SpikeTrap.cs +++ b/Projects/Scripts/Items/Traps/SpikeTrap.cs @@ -26,7 +26,7 @@ namespace Server.Items [CommandProperty(AccessLevel.GameMaster)] public SpikeTrapType Type { - get + get => ItemID switch { return ItemID switch { @@ -56,13 +56,7 @@ namespace Server.Items public bool Extended { get => ItemID == GetExtendedID(Type); - set - { - if (value) - ItemID = GetExtendedID(Type); - else - ItemID = GetBaseID(Type); - } + set => ItemID = value ? GetExtendedID(Type) : GetBaseID(Type); } public override bool PassivelyTriggered => false; @@ -101,7 +95,7 @@ namespace Server.Items if (!from.Alive || from.AccessLevel > AccessLevel.Player) return; - Effects.SendLocationEffect(Location, Map, GetBaseID(Type) + 1, 18, 3, GetEffectHue(), 0); + Effects.SendLocationEffect(Location, Map, GetBaseID(Type) + 1, 18, 3, GetEffectHue()); Effects.PlaySound(Location, Map, 0x22C); foreach (Mobile mob in GetMobilesInRange(0)) @@ -122,7 +116,7 @@ namespace Server.Items public virtual void OnSpikeRetracted() { Extended = false; - Effects.SendLocationEffect(Location, Map, GetExtendedID(Type) - 1, 6, 3, GetEffectHue(), 0); + Effects.SendLocationEffect(Location, Map, GetExtendedID(Type) - 1, 6, 3, GetEffectHue()); } public override void Serialize(GenericWriter writer) diff --git a/Projects/Scripts/Items/Traps/StoneFaceTrap.cs b/Projects/Scripts/Items/Traps/StoneFaceTrap.cs index 2aab141f8..f9a320d74 100644 --- a/Projects/Scripts/Items/Traps/StoneFaceTrap.cs +++ b/Projects/Scripts/Items/Traps/StoneFaceTrap.cs @@ -40,22 +40,24 @@ namespace Server.Items } set { - bool breathing = Breathing; - - ItemID = breathing ? GetFireID(value) : GetBaseID(value); - } + 0x10F5 => StoneFaceTrapType.NorthWestWall, + 0x10F6 => StoneFaceTrapType.NorthWestWall, + 0x10F7 => StoneFaceTrapType.NorthWestWall, + 0x10FC => StoneFaceTrapType.NorthWall, + 0x10FD => StoneFaceTrapType.NorthWall, + 0x10FE => StoneFaceTrapType.NorthWall, + 0x110F => StoneFaceTrapType.WestWall, + 0x1110 => StoneFaceTrapType.WestWall, + 0x1111 => StoneFaceTrapType.WestWall, + _ => StoneFaceTrapType.NorthWestWall + }; + set => ItemID = Breathing ? GetFireID(value) : GetBaseID(value); } public bool Breathing { get => ItemID == GetFireID(Type); - set - { - if (value) - ItemID = GetFireID(Type); - else - ItemID = GetBaseID(Type); - } + set => ItemID = value ? GetFireID(Type) : GetBaseID(Type); } public override bool PassivelyTriggered => true; @@ -157,4 +159,4 @@ namespace Server.Items int version = reader.ReadInt(); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Items/Wands/BaseWand.cs b/Projects/Scripts/Items/Wands/BaseWand.cs index 656850536..97819c442 100644 --- a/Projects/Scripts/Items/Wands/BaseWand.cs +++ b/Projects/Scripts/Items/Wands/BaseWand.cs @@ -236,22 +236,15 @@ namespace Server.Items int number; if (Name == null) - { number = 1017085; - } else { LabelTo(from, Name); number = 1041000; } - if (attrs.Count == 0 && Crafter == null && Name != null) - return; - - EquipmentInfo eqInfo = new EquipmentInfo(number, Crafter, false, - attrs.ToArray()); - - from.Send(new DisplayEquipmentInfo(this, eqInfo)); + if (attrs.Count > 0 || Crafter != null || Name == null) + EquipmentPackets.SendDisplayEquipmentInfo(from.NetState, this, number, Crafter, false, attrs); } public void Cast(Spell spell) @@ -279,4 +272,4 @@ namespace Server.Items public virtual bool OnWandTarget(Mobile from, object o) => true; } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Items/Weapons/Abilities/WeaponAbility.cs b/Projects/Scripts/Items/Weapons/Abilities/WeaponAbility.cs index dff3bf72e..50b2d774f 100644 --- a/Projects/Scripts/Items/Weapons/Abilities/WeaponAbility.cs +++ b/Projects/Scripts/Items/Weapons/Abilities/WeaponAbility.cs @@ -125,13 +125,13 @@ namespace Server.Items { int mana = BaseMana; - double skillTotal = GetSkill(from, SkillName.Swords) + GetSkill(from, SkillName.Macing) - + GetSkill(from, SkillName.Fencing) + + double skillTotal = GetSkill(from, SkillName.Swords) + GetSkill(from, SkillName.Macing) + + GetSkill(from, SkillName.Fencing) + GetSkill(from, SkillName.Archery) + - GetSkill(from, SkillName.Parry) - + GetSkill(from, SkillName.Lumberjacking) + - GetSkill(from, SkillName.Stealth) - + GetSkill(from, SkillName.Poisoning) + + GetSkill(from, SkillName.Parry) + + GetSkill(from, SkillName.Lumberjacking) + + GetSkill(from, SkillName.Stealth) + + GetSkill(from, SkillName.Poisoning) + GetSkill(from, SkillName.Bushido) + GetSkill(from, SkillName.Ninjitsu); @@ -256,55 +256,33 @@ namespace Server.Items #region Dueling - string option = null; - - if (this is ArmorIgnore) - option = "Armor Ignore"; - else if (this is BleedAttack) - option = "Bleed Attack"; - else if (this is ConcussionBlow) - option = "Concussion Blow"; - else if (this is CrushingBlow) - option = "Crushing Blow"; - else if (this is Disarm) - option = "Disarm"; - else if (this is Dismount) - option = "Dismount"; - else if (this is DoubleStrike) - option = "Double Strike"; - else if (this is InfectiousStrike) - option = "Infectious Strike"; - else if (this is MortalStrike) - option = "Mortal Strike"; - else if (this is MovingShot) - option = "Moving Shot"; - else if (this is ParalyzingBlow) - option = "Paralyzing Blow"; - else if (this is ShadowStrike) - option = "Shadow Strike"; - else if (this is WhirlwindAttack) - option = "Whirlwind Attack"; - else if (this is RidingSwipe) - option = "Riding Swipe"; - else if (this is FrenziedWhirlwind) - option = "Frenzied Whirlwind"; - else if (this is Block) - option = "Block"; - else if (this is DefenseMastery) - option = "Defense Mastery"; - else if (this is NerveStrike) - option = "Nerve Strike"; - else if (this is TalonStrike) - option = "Talon Strike"; - else if (this is Feint) - option = "Feint"; - else if (this is DualWield) - option = "Dual Wield"; - else if (this is DoubleShot) - option = "Double Shot"; - else if (this is ArmorPierce) - option = "Armor Pierce"; - + string option = this switch + { + ArmorIgnore _ => "Armor Ignore", + BleedAttack _ => "Bleed Attack", + ConcussionBlow _ => "Concussion Blow", + CrushingBlow _ => "Crushing Blow", + Disarm _ => "Disarm", + Dismount _ => "Dismount", + DoubleStrike _ => "Double Strike", + InfectiousStrike _ => "Infectious Strike", + MortalStrike _ => "Mortal Strike", + MovingShot _ => "Moving Shot", + ParalyzingBlow _ => "Paralyzing Blow", + ShadowStrike _ => "Shadow Strike", + WhirlwindAttack _ => "Whirlwind Attack", + RidingSwipe _ => "Riding Swipe", + FrenziedWhirlwind _ => "Frenzied Whirlwind", + Block _ => "Block", + DefenseMastery _ => "Defense Mastery", + NerveStrike _ => "Nerve Strike", + TalonStrike _ => "Talon Strike", + Feint _ => "Feint", + DualWield _ => "Dual Wield", + DoubleShot _ => "Double Shot", + ArmorPierce _ => "Armor Pierce", + _ => null + }; if (option != null && !DuelContext.AllowSpecialAbility(from, option, true)) return false; @@ -381,7 +359,7 @@ namespace Server.Items Table.Remove(m); if (Core.AOS && m.NetState != null) - m.Send(ClearWeaponAbility.Instance); + Packets.SendClearWeaponAbility(m.NetState); } public static void Initialize() diff --git a/Projects/Scripts/Items/Weapons/BaseWeapon.cs b/Projects/Scripts/Items/Weapons/BaseWeapon.cs index c3a156618..2d686d4dc 100644 --- a/Projects/Scripts/Items/Weapons/BaseWeapon.cs +++ b/Projects/Scripts/Items/Weapons/BaseWeapon.cs @@ -291,24 +291,16 @@ namespace Server.Items if (m_Quality == WeaponQuality.Exceptional) bonus += 20; - switch (m_DurabilityLevel) + + bonus += m_DurabilityLevel switch { - case WeaponDurabilityLevel.Durable: - bonus += 20; - break; - case WeaponDurabilityLevel.Substantial: - bonus += 50; - break; - case WeaponDurabilityLevel.Massive: - bonus += 70; - break; - case WeaponDurabilityLevel.Fortified: - bonus += 100; - break; - case WeaponDurabilityLevel.Indestructible: - bonus += 120; - break; - } + WeaponDurabilityLevel.Durable => 20, + WeaponDurabilityLevel.Substantial => 50, + WeaponDurabilityLevel.Massive => 70, + WeaponDurabilityLevel.Fortified => 100, + WeaponDurabilityLevel.Indestructible => 120, + _ => 0 + }; if (Core.AOS) { @@ -516,10 +508,9 @@ namespace Server.Items double swrd = m.Skills.Swords.Value; double fenc = m.Skills.Fencing.Value; double mcng = m.Skills.Macing.Value; - double val; sk = SkillName.Swords; - val = swrd; + double val = swrd; if (fenc > val) { @@ -530,12 +521,7 @@ namespace Server.Items if (mcng > val) sk = SkillName.Macing; } else if (WeaponAttributes.MageWeapon != 0) - { - if (m.Skills.Magery.Value > m.Skills[Skill].Value) - sk = SkillName.Magery; - else - sk = Skill; - } + sk = m.Skills.Magery.Value > m.Skills[Skill].Value ? SkillName.Magery : Skill; else { sk = Skill; @@ -792,9 +778,7 @@ namespace Server.Items if (canSwing && attacker.HarmfulCheck(defender)) { attacker.DisruptiveAction(); - - if (attacker.NetState != null) - attacker.Send(new Swing(0, attacker, defender)); + Packets.SendSwing(attacker.NetState, attacker.Serial, defender.Serial); if (attacker is BaseCreature bc) { @@ -1449,7 +1433,7 @@ namespace Server.Items damage = AOS.Scale(damage, 100 + damageBonus); - return damage / 100; + return damage / 100.0; } public virtual CheckSlayerResult CheckSlayers(Mobile attacker, Mobile defender) @@ -1641,65 +1625,32 @@ namespace Server.Items if (!Core.AOS) return 0; - int bonus = 0; - - switch (m_AccuracyLevel) + return m_AccuracyLevel switch { - case WeaponAccuracyLevel.Accurate: - bonus += 02; - break; - case WeaponAccuracyLevel.Surpassingly: - bonus += 04; - break; - case WeaponAccuracyLevel.Eminently: - bonus += 06; - break; - case WeaponAccuracyLevel.Exceedingly: - bonus += 08; - break; - case WeaponAccuracyLevel.Supremely: - bonus += 10; - break; - } - - return bonus; + WeaponAccuracyLevel.Accurate => 2, + WeaponAccuracyLevel.Surpassingly => 4, + WeaponAccuracyLevel.Eminently => 6, + WeaponAccuracyLevel.Exceedingly => 8, + WeaponAccuracyLevel.Supremely => 10, + _ => 0 + }; } - public virtual int GetDamageBonus() - { - int bonus = VirtualDamageBonus; - - switch (m_Quality) + public virtual int GetDamageBonus() => + VirtualDamageBonus + m_Quality switch { - case WeaponQuality.Low: - bonus -= 20; - break; - case WeaponQuality.Exceptional: - bonus += 20; - break; - } - - switch (m_DamageLevel) + WeaponQuality.Low => -20, + WeaponQuality.Exceptional => 20, + _ => 0, + } + m_DamageLevel switch { - case WeaponDamageLevel.Ruin: - bonus += 15; - break; - case WeaponDamageLevel.Might: - bonus += 20; - break; - case WeaponDamageLevel.Force: - bonus += 25; - break; - case WeaponDamageLevel.Power: - bonus += 30; - break; - case WeaponDamageLevel.Vanq: - bonus += 35; - break; - } - - return bonus; - } + WeaponDamageLevel.Ruin => 15, + WeaponDamageLevel.Might => 20, + WeaponDamageLevel.Force => 25, + WeaponDamageLevel.Power => 30, + WeaponDamageLevel.Vanq => 35, + _ => 0, + }; public virtual double ScaleDamageAOS(Mobile attacker, double damage, bool checkSkills) { @@ -2353,10 +2304,7 @@ namespace Server.Items } else if (m_Slayer != SlayerName.None || m_Slayer2 != SlayerName.None || m_DurabilityLevel != WeaponDurabilityLevel.Regular || m_DamageLevel != WeaponDamageLevel.Regular || - m_AccuracyLevel != WeaponAccuracyLevel.Regular) - { - attrs.Add(new EquipInfoAttribute(1038000)); // Unidentified - } + m_AccuracyLevel != WeaponAccuracyLevel.Regular) attrs.Add(new EquipInfoAttribute(1038000)); // Unidentified if (m_Poison != null && m_PoisonCharges > 0) attrs.Add(new EquipInfoAttribute(1017383, m_PoisonCharges)); @@ -2364,21 +2312,15 @@ namespace Server.Items int number; if (Name == null) - { number = LabelNumber; - } else { LabelTo(from, Name); number = 1041000; } - if (attrs.Count == 0 && Crafter == null && Name != null) - return; - - EquipmentInfo eqInfo = new EquipmentInfo(number, m_Crafter, false, attrs.ToArray()); - - from.Send(new DisplayEquipmentInfo(this, eqInfo)); + if (attrs.Count > 0 || Crafter != null || Name == null) + EquipmentPackets.SendDisplayEquipmentInfo(from.NetState, this, number, m_Crafter, false, attrs); } private class ResetEquipTimer : Timer @@ -2918,7 +2860,7 @@ namespace Server.Items double damage = GetAosDamage(attacker, 23, 1, 4); - defender.BoltEffect(0); + defender.BoltEffect(); SpellHelper.Damage(TimeSpan.Zero, defender, attacker, damage, 0, 0, 0, 0, 100); } @@ -3355,8 +3297,7 @@ namespace Server.Items parentMobile.AddSkillMod(m_MageMod); } - if (GetSaveFlag(flags, SaveFlag.PlayerConstructed)) - PlayerConstructed = true; + PlayerConstructed |= GetSaveFlag(flags, SaveFlag.PlayerConstructed); if (GetSaveFlag(flags, SaveFlag.SkillBonuses)) SkillBonuses = new AosSkillBonuses(this, reader); @@ -3508,8 +3449,7 @@ namespace Server.Items if (m_Hits <= 0 && m_MaxHits <= 0) m_Hits = m_MaxHits = Utility.RandomMinMax(InitMinHits, InitMaxHits); - if (version < 6) - PlayerConstructed = true; // we don't know, so, assume it's crafted + PlayerConstructed |= version < 6; // we don't know, so, assume it's crafted } #endregion diff --git a/Projects/Scripts/Items/Weapons/Maces/FireworksWand.cs b/Projects/Scripts/Items/Weapons/Maces/FireworksWand.cs index 37389667e..40f243fee 100644 --- a/Projects/Scripts/Items/Weapons/Maces/FireworksWand.cs +++ b/Projects/Scripts/Items/Weapons/Maces/FireworksWand.cs @@ -71,7 +71,7 @@ namespace Server.Items startLoc.Z + 32); Effects.SendMovingEffect(new Entity(Serial.Zero, startLoc, map), new Entity(Serial.Zero, endLoc, map), - 0x36E4, 5, 0, false, false); + 0x36E4, 5, 0); Timer.DelayCall(TimeSpan.FromSeconds(1.0), () => FinishLaunch(endLoc, map)); } diff --git a/Projects/Scripts/Items/Weapons/Ranged/BaseRanged.cs b/Projects/Scripts/Items/Weapons/Ranged/BaseRanged.cs index 7c87a4199..c9a1283d5 100644 --- a/Projects/Scripts/Items/Weapons/Ranged/BaseRanged.cs +++ b/Projects/Scripts/Items/Weapons/Ranged/BaseRanged.cs @@ -81,7 +81,7 @@ namespace Server.Items if (canSwing && attacker.HarmfulCheck(defender)) { attacker.DisruptiveAction(); - attacker.Send(new Swing(0, attacker, defender)); + Packets.SendSwing(attacker.NetState, attacker.Serial, defender.Serial); if (OnFired(attacker, defender)) { diff --git a/Projects/Scripts/Items/Weapons/Staves/ShepherdsCrook.cs b/Projects/Scripts/Items/Weapons/Staves/ShepherdsCrook.cs index dab5c1bb5..1a17ad5ff 100644 --- a/Projects/Scripts/Items/Weapons/Staves/ShepherdsCrook.cs +++ b/Projects/Scripts/Items/Weapons/Staves/ShepherdsCrook.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using Server.Engines.CannedEvil; using Server.Mobiles; using Server.Network; @@ -117,9 +118,7 @@ namespace Server.Items { Type t = bc.GetType(); - foreach (Type type in m_ChampTamables) - if (type == t) - return true; + return m_ChampTamables.Any(type => type == t); } } @@ -145,7 +144,7 @@ namespace Server.Items if (from.CheckTargetSkill(SkillName.Herding, m_Creature, min, max)) { - if (p != from) + if (!ReferenceEquals(p, from)) p = new Point2D(p.X, p.Y); m_Creature.TargetLocation = p; diff --git a/Projects/Scripts/Misc/AOS.cs b/Projects/Scripts/Misc/AOS.cs index cbf8d4487..2d9fac575 100644 --- a/Projects/Scripts/Misc/AOS.cs +++ b/Projects/Scripts/Misc/AOS.cs @@ -9,7 +9,7 @@ using Server.Spells.Seventh; namespace Server { - public class AOS + public static class AOS { public static void DisableStatInfluences() { @@ -1019,8 +1019,7 @@ namespace Server if (!GetValues(i, out SkillName skill, out double bonus)) continue; - if (m_Mods == null) - m_Mods = new List(); + m_Mods ??= new List(); SkillMod sk = new DefaultSkillMod(skill, true, bonus); sk.ObeyCap = true; diff --git a/Projects/Scripts/Misc/AccountPrompt.cs b/Projects/Scripts/Misc/AccountPrompt.cs index 1c5df4dab..274e5bd9e 100644 --- a/Projects/Scripts/Misc/AccountPrompt.cs +++ b/Projects/Scripts/Misc/AccountPrompt.cs @@ -3,7 +3,7 @@ using Server.Accounting; namespace Server.Misc { - public class AccountPrompt + public static class AccountPrompt { public static void Initialize() { @@ -22,8 +22,7 @@ namespace Server.Misc Console.Write("Password: "); string password = Console.ReadLine(); - Account a = new Account(username, password); - a.AccessLevel = AccessLevel.Owner; + Account a = new Account(username, password) {AccessLevel = AccessLevel.Owner}; Console.WriteLine("Account created."); } @@ -36,4 +35,4 @@ namespace Server.Misc } } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Misc/Animations.cs b/Projects/Scripts/Misc/Animations.cs index d4515e671..67de3a56b 100644 --- a/Projects/Scripts/Misc/Animations.cs +++ b/Projects/Scripts/Misc/Animations.cs @@ -1,6 +1,6 @@ namespace Server.Misc { - public class Animations + public static class Animations { public static void Initialize() { @@ -28,4 +28,4 @@ namespace Server.Misc from.Animate(action, 5, 1, true, false, 0); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Misc/AttackMessage.cs b/Projects/Scripts/Misc/AttackMessage.cs index 0687281f7..a58ccf38a 100644 --- a/Projects/Scripts/Misc/AttackMessage.cs +++ b/Projects/Scripts/Misc/AttackMessage.cs @@ -4,7 +4,7 @@ using Server.Network; namespace Server.Misc { - public class AttackMessage + public static class AttackMessage { private const string AggressorFormat = "You are attacking {0}!"; private const string AggressedFormat = "{0} is attacking you!"; @@ -59,4 +59,4 @@ namespace Server.Misc return false; } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Misc/AutoSave.cs b/Projects/Scripts/Misc/AutoSave.cs index 1d206f72b..6b538ce56 100644 --- a/Projects/Scripts/Misc/AutoSave.cs +++ b/Projects/Scripts/Misc/AutoSave.cs @@ -141,7 +141,7 @@ namespace Server.Misc string saves = Path.Combine(Core.BaseDirectory, "Saves"); if (Directory.Exists(saves)) - Directory.Move(saves, FormatDirectory(root, m_Backups[m_Backups.Length - 1], GetTimeStamp())); + Directory.Move(saves, FormatDirectory(root, m_Backups[^1], GetTimeStamp())); } private static DirectoryInfo Match(string[] paths, string match) @@ -181,4 +181,4 @@ namespace Server.Misc return $"{now.Day}-{now.Month}-{now.Year} {now.Hour}-{now.Minute:D2}-{now.Second:D2}"; } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Misc/Broadcasts.cs b/Projects/Scripts/Misc/Broadcasts.cs index 65d5f79a3..4e4e6b117 100644 --- a/Projects/Scripts/Misc/Broadcasts.cs +++ b/Projects/Scripts/Misc/Broadcasts.cs @@ -1,6 +1,6 @@ namespace Server.Misc { - public class Broadcasts + public static class Broadcasts { public static void Initialize() { diff --git a/Projects/Scripts/Misc/BuffIcons.cs b/Projects/Scripts/Misc/BuffIcons.cs index 6884f63c9..1a4bf64fa 100644 --- a/Projects/Scripts/Misc/BuffIcons.cs +++ b/Projects/Scripts/Misc/BuffIcons.cs @@ -1,4 +1,5 @@ using System; +using Server.Buffers; using Server.Mobiles; using Server.Network; @@ -18,13 +19,11 @@ namespace Server }; } - #region Properties - public BuffIcon ID{ get; } - public int TitleCliloc{ get; } + public int Title{ get; } - public int SecondaryCliloc{ get; } + public TextDefinition Description{ get; } public TimeSpan TimeLength{ get; } @@ -32,50 +31,30 @@ namespace Server public Timer Timer{ get; } - public bool RetainThroughDeath{ get; } + public bool RetainThroughDeath { get; } - public TextDefinition Args{ get; } - - #endregion - - #region Constructors - - public BuffInfo(BuffIcon iconID, int titleCliloc) - : this(iconID, titleCliloc, titleCliloc + 1) + public BuffInfo(BuffIcon iconId, int title, TimeSpan time = default, Mobile m = null) : + this(iconId, title, title + 1, time, m) { } - public BuffInfo(BuffIcon iconID, int titleCliloc, int secondaryCliloc) - { - ID = iconID; - TitleCliloc = titleCliloc; - SecondaryCliloc = secondaryCliloc; - } - - public BuffInfo(BuffIcon iconID, int titleCliloc, TimeSpan length, Mobile m) - : this(iconID, titleCliloc, titleCliloc + 1, length, m) + public BuffInfo(BuffIcon iconId, int title, string args, TimeSpan time = default, Mobile m = null) : + this(iconId, title, title + 1, args, time, m) { } - //Only the timed one needs to Mobile to know when to automagically remove it. - public BuffInfo(BuffIcon iconID, int titleCliloc, int secondaryCliloc, TimeSpan length, Mobile m) - : this(iconID, titleCliloc, secondaryCliloc) + public BuffInfo(BuffIcon iconId, int title, int desc, TimeSpan time = default, Mobile m = null) : + this(iconId, title, desc, null, time, m) { - TimeLength = length; - TimeStart = DateTime.UtcNow; - - Timer = Timer.DelayCall(length, delegate - { - if (!(m is PlayerMobile pm)) - return; - - pm.RemoveBuff(this); - }); } + public BuffInfo(BuffIcon iconId, int title, string args, bool retain, Mobile m = null) : + this(iconId, title, title + 1, args, DateTime.UtcNow, default, retain, m) + { + } - public BuffInfo(BuffIcon iconID, int titleCliloc, TextDefinition args) - : this(iconID, titleCliloc, titleCliloc + 1, args) + public BuffInfo(BuffIcon iconId, int title, int desc, string args, TimeSpan time, Mobile m = null) : + this(iconId, title, new TextDefinition(desc, args), DateTime.UtcNow, time, false, m) { } @@ -83,8 +62,8 @@ namespace Server : this(iconID, titleCliloc, secondaryCliloc) => Args = args; - public BuffInfo(BuffIcon iconID, int titleCliloc, bool retainThroughDeath) - : this(iconID, titleCliloc, titleCliloc + 1, retainThroughDeath) + public BuffInfo(BuffIcon iconId, int title, int desc, string args, TimeSpan time = default, bool retain = false, + Mobile m = null) : this(iconId, title, new TextDefinition(desc, args), DateTime.UtcNow, time, retain, m) { } @@ -92,9 +71,17 @@ namespace Server : this(iconID, titleCliloc, secondaryCliloc) => RetainThroughDeath = retainThroughDeath; - public BuffInfo(BuffIcon iconID, int titleCliloc, TextDefinition args, bool retainThroughDeath) - : this(iconID, titleCliloc, titleCliloc + 1, args, retainThroughDeath) + public BuffInfo(BuffIcon iconId, int title, TextDefinition desc, DateTime start = default, TimeSpan time = default, bool retain = false, + Mobile m = null) { + ID = iconId; + Title = title; + Description = desc; + TimeLength = time; + TimeStart = start; + RetainThroughDeath = retain; + if (m is PlayerMobile pm) + Timer = Timer.DelayCall(time, playermobile => playermobile.RemoveBuff(this), pm); } public BuffInfo(BuffIcon iconID, int titleCliloc, int secondaryCliloc, TextDefinition args, bool retainThroughDeath) @@ -131,20 +118,17 @@ namespace Server public static void AddBuff(Mobile m, BuffInfo b) { - if (m is PlayerMobile pm) - pm.AddBuff(b); + (m as PlayerMobile)?.AddBuff(b); } public static void RemoveBuff(Mobile m, BuffInfo b) { - if (m is PlayerMobile pm) - pm.RemoveBuff(b); + (m as PlayerMobile)?.RemoveBuff(b); } public static void RemoveBuff(Mobile m, BuffIcon b) { - if (m is PlayerMobile pm) - pm.RemoveBuff(b); + (m as PlayerMobile)?.RemoveBuff(b); } #endregion @@ -208,80 +192,68 @@ namespace Server Fly } - public sealed class AddBuffPacket : Packet + public static class BuffPackets { - public AddBuffPacket(Mobile m, BuffInfo info) - : this(m, info.ID, info.TitleCliloc, info.SecondaryCliloc, info.Args, - info.TimeStart != DateTime.MinValue ? info.TimeStart + info.TimeLength - DateTime.UtcNow : TimeSpan.Zero) + public static void SendAddBuff(Mobile m, BuffInfo info) { + SendAddBuff(m.NetState, m.Serial, info.ID, info.Title, info.Description, + info.TimeStart != DateTime.MinValue ? info.TimeStart + info.TimeLength - DateTime.UtcNow : TimeSpan.Zero); + } + public static void SendAddBuff(NetState ns, Serial m, BuffIcon iconID, int title, TextDefinition desc, TimeSpan time) + { + if (ns == null) + return; + + string args = desc?.String ?? ""; + + int length = 44 + args.Length * 2; + + SpanWriter writer = new SpanWriter(stackalloc byte[length]); + writer.Write((byte)0xDF); // Packet ID + writer.Write((ushort)length); // Dynamic Length + + writer.Write(m); + + writer.Write((short)iconID); //ID + writer.Write((short)0x1); //Type 0 for removal. 1 for add 2 for Data + + writer.Position += 4; + + writer.Write((short)iconID); //ID + writer.Write((short)0x01); //Type 0 for removal. 1 for add 2 for Data + + writer.Position += 4; + + writer.Write((short)Math.Max(time.TotalSeconds, 0)); //Time in seconds + + writer.Position += 3; + + writer.Write(title); + writer.Write(desc?.Number ?? 0); + + writer.Position += 5; + writer.Write((byte)0x1); // Start indicator? + writer.Position += 2; + + writer.WriteLittleUniNull(args); + + ns.Send(writer.Span); } - public AddBuffPacket(Mobile mob, BuffIcon iconID, int titleCliloc, int secondaryCliloc, TextDefinition args, - TimeSpan length) - : base(0xDF) + public static void SendRemoveBuffPacket(NetState ns, Serial m, int icon) { - bool hasArgs = args != null; + SpanWriter writer = new SpanWriter(stackalloc byte[13]); + writer.Write((byte)0xDF); // Packet ID + writer.Write((ushort)13); // Dynamic Length - EnsureCapacity(hasArgs ? 48 + args.ToString().Length * 2 : 44); - m_Stream.Write(mob.Serial); + writer.Write(m); + writer.Write((short)icon); //ID + writer.Write((short)0x0); //Type 0 for removal. 1 for add 2 for Data - m_Stream.Write((short)iconID); //ID - m_Stream.Write((short)0x1); //Type 0 for removal. 1 for add 2 for Data + writer.Position += 4; - m_Stream.Fill(4); - - m_Stream.Write((short)iconID); //ID - m_Stream.Write((short)0x01); //Type 0 for removal. 1 for add 2 for Data - - m_Stream.Fill(4); - - if (length < TimeSpan.Zero) - length = TimeSpan.Zero; - - m_Stream.Write((short)length.TotalSeconds); //Time in seconds - - m_Stream.Fill(3); - m_Stream.Write(titleCliloc); - m_Stream.Write(secondaryCliloc); - - if (!hasArgs) - { - //m_Stream.Fill( 2 ); - m_Stream.Fill(10); - } - else - { - m_Stream.Fill(4); - m_Stream.Write((short)0x1); //Unknown -> Possibly something saying 'hey, I have more data!'? - m_Stream.Fill(2); - - //m_Stream.WriteLittleUniNull( "\t#1018280" ); - m_Stream.WriteLittleUniNull($"\t{args}"); - - m_Stream.Write((short)0x1); //Even more Unknown -> Possibly something saying 'hey, I have more data!'? - m_Stream.Fill(2); - } + ns.Send(writer.Span); } } - - public sealed class RemoveBuffPacket : Packet - { - public RemoveBuffPacket(Mobile mob, BuffInfo info) - : this(mob, info.ID) - { - } - - public RemoveBuffPacket(Mobile mob, BuffIcon iconID) - : base(0xDF) - { - EnsureCapacity(13); - m_Stream.Write(mob.Serial); - - m_Stream.Write((short)iconID); //ID - m_Stream.Write((short)0x0); //Type 0 for removal. 1 for add 2 for Data - - m_Stream.Fill(4); - } - } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Misc/CharacterCreation.cs b/Projects/Scripts/Misc/CharacterCreation.cs index 64fcdd999..a234f5e6c 100644 --- a/Projects/Scripts/Misc/CharacterCreation.cs +++ b/Projects/Scripts/Misc/CharacterCreation.cs @@ -7,7 +7,7 @@ using Server.Network; namespace Server.Misc { - public class CharacterCreation + public static class CharacterCreation { private static readonly CityInfo m_NewHavenInfo = new CityInfo("New Haven", "The Bountiful Harvest Inn", 3503, 2574, 14, Map.Trammel); @@ -22,15 +22,8 @@ namespace Server.Misc private static void AddBackpack(Mobile m) { - Container pack = m.Backpack; - - if (pack == null) - { - pack = new Backpack(); - pack.Movable = false; - - m.AddItem(pack); - } + if (m.Backpack == null) + m.AddItem(new Backpack {Movable = false}); PackItem(new RedBook("a book", m.Name, 20, true)); PackItem(new Gold(1000)); // Starting gold can be customized here @@ -52,16 +45,8 @@ namespace Server.Misc item.Location = new Point3D(x, y, 0); } - private static Item MakePotionKeg(PotionEffect type, int hue) - { - PotionKeg keg = new PotionKeg(); - - keg.Held = 100; - keg.Type = type; - keg.Hue = hue; - - return MakeNewbie(keg); - } + private static Item MakePotionKeg(PotionEffect type, int hue) => + MakeNewbie(new PotionKeg {Held = 100, Type = type, Hue = hue}); private static void FillBankAOS(Mobile m) { @@ -75,11 +60,8 @@ namespace Server.Misc m.StatCap = 250; - Container cont; - - // Begin box of money - cont = new WoodenBox(); + Container cont = new WoodenBox(); cont.ItemID = 0xE7D; cont.Hue = 0x489; @@ -97,8 +79,7 @@ namespace Server.Misc // Begin bag of potion kegs - cont = new Backpack(); - cont.Name = "Various Potion Kegs"; + cont = new Backpack {Name = "Various Potion Kegs"}; PlaceItemIn(cont, 45, 149, MakePotionKeg(PotionEffect.CureGreater, 0x2D)); PlaceItemIn(cont, 69, 149, MakePotionKeg(PotionEffect.HealGreater, 0x499)); @@ -113,8 +94,7 @@ namespace Server.Misc // Begin bag of tools - cont = new Bag(); - cont.Name = "Tool Bag"; + cont = new Bag {Name = "Tool Bag"}; PlaceItemIn(cont, 30, 35, new TinkerTools(1000)); PlaceItemIn(cont, 60, 35, new HousePlacementTool()); @@ -145,8 +125,7 @@ namespace Server.Misc // Begin bag of archery ammo - cont = new Bag(); - cont.Name = "Bag Of Archery Ammo"; + cont = new Bag {Name = "Bag Of Archery Ammo"}; PlaceItemIn(cont, 48, 76, new Arrow(5000)); PlaceItemIn(cont, 72, 76, new Bolt(5000)); @@ -156,8 +135,7 @@ namespace Server.Misc // Begin bag of treasure maps - cont = new Bag(); - cont.Name = "Bag Of Treasure Maps"; + cont = new Bag {Name = "Bag Of Treasure Maps"}; PlaceItemIn(cont, 30, 35, new TreasureMap(1, Map.Trammel)); PlaceItemIn(cont, 45, 35, new TreasureMap(2, Map.Trammel)); @@ -181,9 +159,7 @@ namespace Server.Misc // Begin bag of raw materials - cont = new Bag(); - cont.Hue = 0x835; - cont.Name = "Raw Materials Bag"; + cont = new Bag {Hue = 0x835, Name = "Raw Materials Bag"}; PlaceItemIn(cont, 92, 60, new BarbedLeather(5000)); PlaceItemIn(cont, 92, 68, new HornedLeather(5000)); @@ -216,9 +192,7 @@ namespace Server.Misc // Begin bag of spell casting stuff - cont = new Backpack(); - cont.Hue = 0x480; - cont.Name = "Spell Casting Stuff"; + cont = new Backpack {Hue = 0x480, Name = "Spell Casting Stuff"}; PlaceItemIn(cont, 45, 105, new Spellbook(ulong.MaxValue)); PlaceItemIn(cont, 65, 105, new NecromancerSpellbook((ulong)0xFFFF)); @@ -234,8 +208,7 @@ namespace Server.Misc toHue.Hue = 0x2D; PlaceItemIn(cont, 45, 150, toHue); - toHue = new BagOfNecroReagents(150); - toHue.Hue = 0x488; + toHue = new BagOfNecroReagents(150) {Hue = 0x488}; PlaceItemIn(cont, 65, 150, toHue); PlaceItemIn(cont, 140, 150, new BagOfAllReagents(500)); @@ -250,9 +223,7 @@ namespace Server.Misc // Begin bag of ethereals - cont = new Backpack(); - cont.Hue = 0x490; - cont.Name = "Bag Of Ethy's!"; + cont = new Backpack {Hue = 0x490, Name = "Bag Of Ethy's!"}; PlaceItemIn(cont, 45, 66, new EtherealHorse()); PlaceItemIn(cont, 69, 82, new EtherealOstard()); @@ -268,9 +239,7 @@ namespace Server.Misc // Begin first bag of artifacts - cont = new Backpack(); - cont.Hue = 0x48F; - cont.Name = "Bag of Artifacts"; + cont = new Backpack {Hue = 0x48F, Name = "Bag of Artifacts"}; PlaceItemIn(cont, 45, 66, new TitansHammer()); PlaceItemIn(cont, 69, 82, new InquisitorsResolution()); @@ -282,9 +251,7 @@ namespace Server.Misc // Begin second bag of artifacts - cont = new Backpack(); - cont.Hue = 0x48F; - cont.Name = "Bag of Artifacts"; + cont = new Backpack {Hue = 0x48F, Name = "Bag of Artifacts"}; PlaceItemIn(cont, 45, 66, new GauntletsOfNobility()); PlaceItemIn(cont, 69, 82, new MidnightBracers()); @@ -324,10 +291,7 @@ namespace Server.Misc // End second bag of artifacts // Begin bag of minor artifacts - cont = new Backpack(); - cont.Hue = 0x48F; - cont.Name = "Bag of Minor Artifacts"; - + cont = new Backpack {Hue = 0x48F, Name = "Bag of Minor Artifacts"}; PlaceItemIn(cont, 45, 66, new LunaLance()); PlaceItemIn(cont, 69, 82, new VioletCourage()); @@ -368,9 +332,7 @@ namespace Server.Misc if (Core.SE) { - cont = new Bag(); - cont.Hue = 0x501; - cont.Name = "Tokuno Minor Artifacts"; + cont = new Bag {Hue = 0x501, Name = "Tokuno Minor Artifacts"}; PlaceItemIn(cont, 42, 70, new Exiler()); PlaceItemIn(cont, 38, 53, new HanzosBow()); @@ -398,8 +360,7 @@ namespace Server.Misc if (Core.SE) //This bag came only after SE. { - cont = new Bag(); - cont.Name = "Bag of Bows"; + cont = new Bag {Name = "Bag of Bows"}; PlaceItemIn(cont, 31, 84, new Bow()); PlaceItemIn(cont, 78, 74, new CompositeBow()); @@ -432,11 +393,7 @@ namespace Server.Misc bank.DropItem(new BankCheck(1000000)); // Full spellbook - Spellbook book = new Spellbook(); - - book.Content = ulong.MaxValue; - - bank.DropItem(book); + bank.DropItem(new Spellbook {Content = ulong.MaxValue}); Bag bag = new Bag(); @@ -641,10 +598,7 @@ namespace Server.Misc newChar.Female = args.Female; //newChar.Body = newChar.Female ? 0x191 : 0x190; - if (Core.Expansion >= args.Race.RequiredExpansion) - newChar.Race = args.Race; //Sets body - else - newChar.Race = Race.DefaultRace; + newChar.Race = Core.Expansion >= args.Race.RequiredExpansion ? args.Race : Race.DefaultRace; //newChar.Hue = Utility.ClipSkinHue( args.Hue & 0x3FFF ) | 0x8000; newChar.Hue = newChar.Race.ClipSkinHue(args.Hue & 0x3FFF) | 0x8000; @@ -692,12 +646,7 @@ namespace Server.Misc if (TestCenter.Enabled) FillBankbox(newChar); - if (young) - { - NewPlayerTicket ticket = new NewPlayerTicket(); - ticket.Owner = newChar; - newChar.BankBox.DropItem(ticket); - } + if (young) newChar.BankBox.DropItem(new NewPlayerTicket {Owner = newChar}); CityInfo city = GetStartLocation(args, young); @@ -710,19 +659,8 @@ namespace Server.Misc new WelcomeTimer(newChar).Start(); } - public static bool VerifyProfession(int profession) - { - if (profession < 0) - return false; - if (profession < 4) - return true; - if (Core.AOS && profession < 6) - return true; - if (Core.SE && profession < 8) - return true; - - return false; - } + public static bool VerifyProfession(int profession) => + profession >= 0 && (profession < 4 || Core.AOS && profession < 6 || Core.SE && profession < 8); private static CityInfo GetStartLocation(CharacterCreatedEventArgs args, bool isYoung) { @@ -754,9 +692,7 @@ namespace Server.Misc break; } case 5: //Paladin - { return m_NewHavenInfo; - } case 6: //Samurai { if ((flags & ClientFlags.Tokuno) != 0) @@ -795,10 +731,7 @@ namespace Server.Misc } } - if (useHaven) - return m_NewHavenInfo; - - return args.City; + return useHaven ? m_NewHavenInfo : args.City; } private static void FixStats(ref int str, ref int dex, ref int intel, int max) @@ -1164,7 +1097,7 @@ namespace Server.Misc if (m_Mobile?.EquipItem(item) == true) return; - Container pack = m_Mobile.Backpack; + Container pack = m_Mobile?.Backpack; if (!mustEquip && pack != null) pack.DropItem(item); @@ -1177,7 +1110,7 @@ namespace Server.Misc if (!Core.AOS) item.LootType = LootType.Newbied; - Container pack = m_Mobile.Backpack; + Container pack = m_Mobile?.Backpack; if (pack != null) pack.DropItem(item); @@ -1733,18 +1666,18 @@ namespace Server.Misc private class BadStartMessage : Timer { private int m_Message; - private Mobile m_Mobile; + private Mobile m_From; public BadStartMessage(Mobile m, int message) : base(TimeSpan.FromSeconds(3.5)) { - m_Mobile = m; + m_From = m; m_Message = message; Start(); } protected override void OnTick() { - m_Mobile.SendLocalizedMessage(m_Message); + m_From.SendLocalizedMessage(m_Message); } } } diff --git a/Projects/Scripts/Misc/Cleanup.cs b/Projects/Scripts/Misc/Cleanup.cs index 407f1d0a0..4b6f5f9f2 100644 --- a/Projects/Scripts/Misc/Cleanup.cs +++ b/Projects/Scripts/Misc/Cleanup.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; +using System.Linq; using Server.Items; -using Server.Mobiles; using Server.Multis; namespace Server.Misc @@ -43,9 +43,7 @@ namespace Server.Misc if (relEntity.Entity is Item item1) validItems.Add(item1); - foreach (VendorInventory inventory in house.VendorInventories) - foreach (Item subItem in inventory.Items) - validItems.Add(subItem); + validItems.AddRange(house.VendorInventories.SelectMany(inventory => inventory.Items)); } else if (item is BankBox box) { diff --git a/Projects/Scripts/Misc/CurrentExpansion.cs b/Projects/Scripts/Misc/CurrentExpansion.cs index 3ff96d7ed..bde778496 100644 --- a/Projects/Scripts/Misc/CurrentExpansion.cs +++ b/Projects/Scripts/Misc/CurrentExpansion.cs @@ -1,4 +1,4 @@ -using Server.Accounting; +using Server.Items; using Server.Network; namespace Server @@ -37,4 +37,4 @@ namespace Server } } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Misc/DoorGenerator.cs b/Projects/Scripts/Misc/DoorGenerator.cs index 865160c48..2a1b3fe76 100644 --- a/Projects/Scripts/Misc/DoorGenerator.cs +++ b/Projects/Scripts/Misc/DoorGenerator.cs @@ -390,7 +390,7 @@ namespace Server public static bool IsFrame(int id, int[] list) { - if (id > list[list.Length - 1]) + if (id > list[^1]) return false; for (int i = 0; i < list.Length; ++i) diff --git a/Projects/Scripts/Misc/Email.cs b/Projects/Scripts/Misc/Email.cs index 43d1d99c9..750515f03 100644 --- a/Projects/Scripts/Misc/Email.cs +++ b/Projects/Scripts/Misc/Email.cs @@ -6,17 +6,17 @@ using System.Threading; namespace Server.Misc { - public class Email + public static class Email { /* In order to support emailing, fill in EmailServer and FromAddress: * Example: * public static readonly string EmailServer = "mail.domain.com"; * public static readonly string FromAddress = "runuo@domain.com"; - * + * * If you want to add crash reporting emailing, fill in CrashAddresses: * Example: * public static readonly string CrashAddresses = "first@email.here,second@email.here,third@email.here"; - * + * * If you want to add speech log page emailing, fill in SpeechLogPageAddresses: * Example: * public static readonly string SpeechLogPageAddresses = "first@email.here,second@email.here,third@email.here"; @@ -62,7 +62,7 @@ namespace Server.Misc // .NET relies on the MTA to generate Message-ID header. Not all MTAs will add this header. DateTime now = DateTime.UtcNow; - string messageID = $"<{now.ToString("yyyyMMdd")}.{now.ToString("HHmmssff")}@{EmailServer}>"; + string messageID = $"<{now:yyyyMMdd}.{now:HHmmssff}@{EmailServer}>"; message.Headers.Add("Message-ID", messageID); message.Headers.Add("X-Mailer", "RunUO"); @@ -89,10 +89,8 @@ namespace Server.Misc { MailMessage message = (MailMessage)state; - if (Send(message)) - Console.WriteLine("Sent e-mail '{0}' to '{1}'.", message.Subject, message.To); - else - Console.WriteLine("Failure sending e-mail '{0}' to '{1}'.", message.Subject, message.To); + Console.WriteLine(Send(message) ? "Sent e-mail '{0}' to '{1}'." : "Failure sending e-mail '{0}' to '{1}'.", + message.Subject, message.To); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Misc/Fastwalk.cs b/Projects/Scripts/Misc/Fastwalk.cs index 232986b7a..a9861974c 100644 --- a/Projects/Scripts/Misc/Fastwalk.cs +++ b/Projects/Scripts/Misc/Fastwalk.cs @@ -4,7 +4,7 @@ namespace Server.Misc { // This fastwalk detection is no longer required // As of B36 PlayerMobile implements movement packet throttling which more reliably controls movement speeds - public class Fastwalk + public static class Fastwalk { private static int MaxSteps = 4; // Maximum number of queued steps until fastwalk is detected private static bool Enabled = false; // Is fastwalk detection enabled? @@ -30,4 +30,4 @@ namespace Server.Misc Console.WriteLine("Client: {0}: Fast movement detected (name={1})", e.NetState, e.NetState.Mobile.Name); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Misc/Geometry.cs b/Projects/Scripts/Misc/Geometry.cs index ff3fccdde..639d76896 100644 --- a/Projects/Scripts/Misc/Geometry.cs +++ b/Projects/Scripts/Misc/Geometry.cs @@ -19,26 +19,19 @@ namespace Server.Misc public static Point2D ArcPoint(Point3D loc, int radius, int angle) { - int sideA, sideB; - if (angle < 0) angle = 0; if (angle > 90) angle = 90; - sideA = (int)Math.Round(radius * Math.Sin(DegreesToRadians(angle))); - sideB = (int)Math.Round(radius * Math.Cos(DegreesToRadians(angle))); + int sideA = (int)Math.Round(radius * Math.Sin(DegreesToRadians(angle))); + int sideB = (int)Math.Round(radius * Math.Cos(DegreesToRadians(angle))); return new Point2D(loc.X - sideB, loc.Y - sideA); } - public static void Circle2D(Point3D loc, Map map, int radius, DoEffect_Callback effect) - { - Circle2D(loc, map, radius, effect, 0, 360); - } - - public static void Circle2D(Point3D loc, Map map, int radius, DoEffect_Callback effect, int angleStart, int angleEnd) + public static void Circle2D(Point3D loc, Map map, int radius, DoEffect_Callback effect, int angleStart = 0, int angleEnd = 360) { if (angleStart < 0 || angleStart > 360) angleStart = 0; @@ -147,13 +140,9 @@ namespace Server.Misc withinBounds = false; } else if (pointQuadrant == start.Quadrant && (x < startX || y > startY)) - { withinBounds = false; - } else if (pointQuadrant == end.Quadrant && (x > endX || y < endY)) - { withinBounds = false; - } return opposite ? !withinBounds : withinBounds; } @@ -218,4 +207,4 @@ namespace Server.Misc public int Quadrant{ get; } } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Misc/Gifts/Winter2004/PileOfGlacialSnow.cs b/Projects/Scripts/Misc/Gifts/Winter2004/PileOfGlacialSnow.cs index 1c6a17a03..e56ff99e9 100644 --- a/Projects/Scripts/Misc/Gifts/Winter2004/PileOfGlacialSnow.cs +++ b/Projects/Scripts/Misc/Gifts/Winter2004/PileOfGlacialSnow.cs @@ -129,9 +129,7 @@ namespace Server.Items Effects.SendMovingEffect(from, targ, 0x36E4, 7, 0, false, true, 0x47F); } else - { from.SendLocalizedMessage(1005574); // The snow is not ready to be packed yet. Keep trying. - } } else { @@ -140,11 +138,9 @@ namespace Server.Items } } else - { from.SendLocalizedMessage( 1005577); // You can only throw a snowball at something that can throw one back. - } } } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Misc/Guild.cs b/Projects/Scripts/Misc/Guild.cs index 9f6f2ec8c..8b70338c6 100644 --- a/Projects/Scripts/Misc/Guild.cs +++ b/Projects/Scripts/Misc/Guild.cs @@ -32,7 +32,7 @@ namespace Server.Guilds public class RankDefinition { - public static RankDefinition[] Ranks = + public static readonly RankDefinition[] Ranks = { new RankDefinition(1062963, 0, RankFlags.None), //Ronin new RankDefinition(1062962, 1, RankFlags.Member), //Member @@ -78,8 +78,8 @@ namespace Server.Guilds public class AllianceInfo { private Guild m_Leader; - private List m_Members; - private List m_PendingMembers; + private readonly List m_Members; + private readonly List m_PendingMembers; public AllianceInfo(Guild leader, string name, Guild partner) { @@ -154,21 +154,9 @@ namespace Server.Guilds } } - public bool IsPendingMember(Guild g) - { - if (g.Alliance != this) - return false; + public bool IsPendingMember(Guild g) => g.Alliance == this && m_PendingMembers.Contains(g); - return m_PendingMembers.Contains(g); - } - - public bool IsMember(Guild g) - { - if (g.Alliance != this) - return false; - - return m_Members.Contains(g); - } + public bool IsMember(Guild g) => g.Alliance == this && m_Members.Contains(g); public void Serialize(GenericWriter writer) { @@ -332,29 +320,18 @@ namespace Server.Guilds public void AllianceChat(Mobile from, int hue, string text) { - Packet p = null; for (int i = 0; i < m_Members.Count; i++) { Guild g = m_Members[i]; for (int j = 0; j < g.Members.Count; j++) { - Mobile m = g.Members[j]; + NetState ns = g.Members[j].NetState; - NetState state = m.NetState; - - if (state != null) - { - if (p == null) - p = Packet.Acquire(new UnicodeMessage(from.Serial, from.Body, MessageType.Alliance, hue, 3, - from.Language, from.Name, text)); - - state.Send(p); - } + if (ns != null) + Packets.SendUnicodeMessage(ns, from.Serial, from.Body, MessageType.Alliance, hue, 3, from.Language, from.Name, text); } } - - Packet.Release(p); } public void AllianceChat(Mobile from, string text) @@ -683,9 +660,7 @@ namespace Server.Guilds Mobile from = e.Mobile; if (arg.Length == 0) - { e.Mobile.Target = new GuildPropsTarget(); - } else { Guild g = uint.TryParse(arg, out uint id) @@ -720,7 +695,7 @@ namespace Server.Guilds if (o is Guildstone stone) { - if (stone?.Guild.Disbanded != false) + if (stone.Guild.Disbanded) { from.SendMessage("The guild associated with that Guildstone no longer exists"); return; @@ -729,9 +704,7 @@ namespace Server.Guilds g = stone.Guild; } else if (o is Mobile mobile) - { g = mobile.Guild as Guild; - } if (g == null) { @@ -773,13 +746,7 @@ namespace Server.Guilds public AllianceInfo Alliance { - get - { - if (m_AllianceInfo != null) - return m_AllianceInfo; - - return m_AllianceLeader?.m_AllianceInfo; - } + get => m_AllianceInfo ?? m_AllianceLeader?.m_AllianceInfo; set { AllianceInfo current = Alliance; @@ -822,10 +789,7 @@ namespace Server.Guilds { AllianceInfo alliance = g.Alliance; - if (alliance?.Leader != null && alliance.IsMember(g)) - return alliance.Leader; - - return g; + return alliance?.Leader != null && alliance.IsMember(g) ? alliance.Leader : g; } #endregion @@ -837,31 +801,9 @@ namespace Server.Guilds public List AcceptedWars{ get; private set; } - public WarDeclaration FindPendingWar(Guild g) - { - for (int i = 0; i < PendingWars.Count; i++) - { - WarDeclaration w = PendingWars[i]; + public WarDeclaration FindPendingWar(Guild g) => PendingWars.FirstOrDefault(w => w.Opponent == g); - if (w.Opponent == g) - return w; - } - - return null; - } - - public WarDeclaration FindActiveWar(Guild g) - { - for (int i = 0; i < AcceptedWars.Count; i++) - { - WarDeclaration w = AcceptedWars[i]; - - if (w.Opponent == g) - return w; - } - - return null; - } + public WarDeclaration FindActiveWar(Guild g) => AcceptedWars.FirstOrDefault(w => w.Opponent == g); public void CheckExpiredWars() { @@ -936,8 +878,7 @@ namespace Server.Guilds if (!NewGuildSystem) return; - if (killer == null) - killer = victim.FindMostRecentDamager(false); + killer ??= victim.FindMostRecentDamager(false); if (killer == null || victim.Guild == null || killer.Guild == null) return; @@ -1148,24 +1089,10 @@ namespace Server.Guilds } } - if (AllyDeclarations == null) - AllyDeclarations = new List(); - - if (AllyInvitations == null) - AllyInvitations = new List(); - - - if (AcceptedWars == null) - AcceptedWars = new List(); - - if (PendingWars == null) - PendingWars = new List(); - - - /* - if ( ( !NewGuildSystem && m_Guildstone == null )|| m_Members.Count == 0 ) - Disband(); - */ + AllyDeclarations ??= new List(); + AllyInvitations ??= new List(); + AcceptedWars ??= new List(); + PendingWars ??= new List(); Timer.DelayCall(TimeSpan.Zero, VerifyGuild_Callback); } @@ -1334,24 +1261,14 @@ namespace Server.Guilds public void GuildChat(Mobile from, int hue, string text) { - Packet p = null; for (int i = 0; i < Members.Count; i++) { - Mobile m = Members[i]; + NetState ns = Members[i].NetState; - NetState state = m.NetState; - - if (state != null) - { - if (p == null) - p = Packet.Acquire(new UnicodeMessage(from.Serial, from.Body, MessageType.Guild, hue, 3, - from.Language, from.Name, text)); - - state.Send(p); - } + if (ns != null) + Packets.SendUnicodeMessage(ns, from.Serial, from.Body, MessageType.Guild, hue, 3, + from.Language, from.Name, text); } - - Packet.Release(p); } public void GuildChat(Mobile from, string text) @@ -1402,17 +1319,12 @@ namespace Server.Guilds Mobile winner = null; int highVotes = 0; - foreach (KeyValuePair kvp in votes) - { - Mobile m = kvp.Key; - int val = kvp.Value; - + foreach ((Mobile m, int val) in votes) if (winner == null || val > highVotes) { winner = m; highVotes = val; } - } if (NewGuildSystem && highVotes * 100 / Math.Max(votingMembers, 1) < MajorityPercentage && !Disbanded && winner != m_Leader && m_Leader.Guild == this) diff --git a/Projects/Scripts/Misc/Keywords.cs b/Projects/Scripts/Misc/Keywords.cs index 6c4ac05e6..71e04ffc4 100644 --- a/Projects/Scripts/Misc/Keywords.cs +++ b/Projects/Scripts/Misc/Keywords.cs @@ -4,7 +4,7 @@ using Server.Mobiles; namespace Server.Misc { - public class Keywords + public static class Keywords { public static void Initialize() { @@ -51,4 +51,4 @@ namespace Server.Misc } } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Misc/LanguageStatistics.cs b/Projects/Scripts/Misc/LanguageStatistics.cs index f5cac3106..9a4ce9402 100644 --- a/Projects/Scripts/Misc/LanguageStatistics.cs +++ b/Projects/Scripts/Misc/LanguageStatistics.cs @@ -20,7 +20,7 @@ namespace Server.Misc * enable showing of unicode control chars **/ - public class LanguageStatistics + public static class LanguageStatistics { private static InternationalCode[] InternationalCodes = { @@ -317,13 +317,10 @@ namespace Server.Misc public int Compare(InternationalCodeCounter x, InternationalCodeCounter y) { - string a = null, b = null; - int ca = 0, cb = 0; - - a = x.Code; - ca = x.Count; - b = y.Code; - cb = y.Count; + string a = x?.Code; + int ca = x?.Count ?? 0; + string b = y?.Code; + int cb = y?.Count ?? 0; if (ca > cb) diff --git a/Projects/Scripts/Misc/LightCycle.cs b/Projects/Scripts/Misc/LightCycle.cs index 90155d0fa..14c7b0204 100644 --- a/Projects/Scripts/Misc/LightCycle.cs +++ b/Projects/Scripts/Misc/LightCycle.cs @@ -4,7 +4,7 @@ using Server.Network; namespace Server { - public class LightCycle + public static class LightCycle { public const int DayLevel = 0; public const int NightLevel = 12; @@ -69,12 +69,12 @@ namespace Server Clock.GetTime(from.Map, from.X, from.Y, out int hours, out int minutes); /* OSI times: - * + * * Midnight -> 3:59 AM : Night * 4:00 AM -> 11:59 PM : Day - * + * * RunUO times: - * + * * 10:00 PM -> 11:59 PM : Scale to night * Midnight -> 3:59 AM : Night * 4:00 AM -> 5:59 AM : Scale to day @@ -124,10 +124,10 @@ namespace Server protected override void OnTick() { - m_Owner.EndAction(); + m_Owner.EndAction(); m_Owner.LightLevel = 0; BuffInfo.RemoveBuff(m_Owner, BuffIcon.NightSight); } } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Misc/LoginStats.cs b/Projects/Scripts/Misc/LoginStats.cs index 69985c921..54a2fd3de 100644 --- a/Projects/Scripts/Misc/LoginStats.cs +++ b/Projects/Scripts/Misc/LoginStats.cs @@ -2,7 +2,7 @@ using Server.Network; namespace Server.Misc { - public class LoginStats + public static class LoginStats { public static void Initialize() { @@ -27,4 +27,4 @@ namespace Server.Misc mobileCount, mobileCount == 1 ? "" : "s"); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Misc/MapDefinitions.cs b/Projects/Scripts/Misc/MapDefinitions.cs index f0558527a..19d8a1006 100644 --- a/Projects/Scripts/Misc/MapDefinitions.cs +++ b/Projects/Scripts/Misc/MapDefinitions.cs @@ -1,17 +1,16 @@ namespace Server.Misc { - public class MapDefinitions + public static class MapDefinitions { public static void Configure() { /* Here we configure all maps. Some notes: - * + * * 1) The first 32 maps are reserved for core use. * 2) Map 0x7F is reserved for core use. * 3) Map 0xFF is reserved for core use. * 4) Changing or removing any predefined maps may cause server instability. */ - RegisterMap(0, 0, 0, 7168, 4096, 4, "Felucca", MapRules.FeluccaRules); RegisterMap(1, 1, 1, 7168, 4096, 0, "Trammel", MapRules.TrammelRules); RegisterMap(2, 2, 2, 2304, 1600, 1, "Ilshenar", MapRules.TrammelRules); @@ -23,7 +22,7 @@ namespace Server.Misc /* Example of registering a custom map: * RegisterMap( 32, 0, 0, 6144, 4096, 3, "Iceland", MapRules.FeluccaRules ); - * + * * Defined: * RegisterMap( , , , , , , , ); * - : An unreserved unique index for this map @@ -40,7 +39,7 @@ namespace Server.Misc MultiComponentList.PostHSFormat = true; // OSI Client Patch 7.0.9.0 } - public static void RegisterMap(int mapIndex, int mapID, int fileIndex, int width, int height, int season, + public static void RegisterMap(int mapIndex, int mapID, int fileIndex, int width, int height, byte season, string name, MapRules rules) { Map newMap = new Map(mapID, mapIndex, fileIndex, width, height, season, name, rules); @@ -49,4 +48,4 @@ namespace Server.Misc Map.AllMaps.Add(newMap); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Misc/MapUO.cs b/Projects/Scripts/Misc/MapUO.cs index 7263c6530..5ed36e88d 100644 --- a/Projects/Scripts/Misc/MapUO.cs +++ b/Projects/Scripts/Misc/MapUO.cs @@ -1,4 +1,5 @@ using System; +using Server.Buffers; using Server.Engines.PartySystem; using Server.Guilds; using Server.Network; @@ -18,35 +19,12 @@ namespace Server.Misc private static void OnPartyTrack(NetState state, PacketReader pvSrc) { - Mobile from = state.Mobile; - Party party = Party.Get(from); - - if (party != null) - { - Packets.PartyTrack packet = new Packets.PartyTrack(from, party); - - if (packet.UnderlyingStream.Length > 8) - state.Send(packet); - } + MapUOPackets.SendPartyTrack(state, Party.Get(state.Mobile)); } private static void OnGuildTrack(NetState state, PacketReader pvSrc) { - Mobile from = state.Mobile; - - if (from.Guild is Guild guild) - { - bool locations = pvSrc.ReadByte() != 0; - - Packets.GuildTrack packet = new Packets.GuildTrack(from, guild, locations); - - if (packet.UnderlyingStream.Length > (locations ? 9 : 5)) - state.Send(packet); - } - else - { - state.Send(new Packets.GuildTrack()); - } + MapUOPackets.SendGuildTrack(state, state.Mobile.Guild as Guild, pvSrc.ReadBoolean()); } private static class Settings @@ -56,75 +34,97 @@ namespace Server.Misc public const bool GuildHitsPercent = true; } - private static class Packets + private static class MapUOPackets { - public sealed class PartyTrack : ProtocolExtension + public static void SendPartyTrack(NetState ns, Party party) { - public PartyTrack(Mobile from, Party party) : base(0x01, (party.Members.Count - 1) * 9 + 4) + Mobile from = ns.Mobile; + int count = party?.Members.Count ?? 0; + if (count < 2) + return; + + SpanWriter writer = new SpanWriter(stackalloc byte[Math.Max(count - 1, 0) * 9 + 8]); + writer.Write((byte)0xF0); // Packet ID + writer.Position += 2; // Dynamic Length + + writer.Write((byte)0x01); // Command + + count = 0; + for (int i = 0; i < count; ++i) { - for (int i = 0; i < party.Members.Count; ++i) - { - PartyMemberInfo pmi = party.Members[i]; + Mobile mob = party.Members[i]?.Mobile; // if count is greater than 0, then party is not null - if (pmi == null || pmi.Mobile == from) - continue; + if (mob == from || mob?.NetState == null || Utility.InUpdateRange(from, mob) && from.CanSee(mob)) + continue; - Mobile mob = pmi.Mobile; - - if (Utility.InUpdateRange(from, mob) && from.CanSee(mob)) - continue; - - m_Stream.Write(mob.Serial); - m_Stream.Write((short)mob.X); - m_Stream.Write((short)mob.Y); - m_Stream.Write((byte)(mob.Map?.MapID ?? 0)); - } - - m_Stream.Write(0); + count++; + writer.Write(mob.Serial); + writer.Write((short)mob.X); + writer.Write((short)mob.Y); + writer.Write((byte)(mob.Map?.MapID ?? 0)); } + + if (count == 0) + return; + + writer.Position += 4; // Empty Serial + writer.Position = 1; + writer.Write((ushort)writer.WrittenCount); + + ns.Send(writer.Span); } - public sealed class GuildTrack : ProtocolExtension + public static void SendGuildTrack(NetState ns, Guild guild = null, bool locations = false) { - public GuildTrack() : base(0x02, 5) - { - m_Stream.Write((byte)0); - m_Stream.Write(0); - } + Mobile from = ns.Mobile; - public GuildTrack(Mobile from, Guild guild, bool locations) : base(0x02, - (guild.Members.Count - 1) * (locations ? 10 : 4) + 5) - { - m_Stream.Write((byte)(locations ? 1 : 0)); + int count = guild?.Members.Count ?? 0; - for (int i = 0; i < guild.Members.Count; ++i) + if (count < 2) + return; + + SpanWriter writer = new SpanWriter(stackalloc byte[Math.Max(count - 1, 0) * (locations ? 10 : 4) + 9]); + writer.Write((byte)0xF0); // Packet ID + writer.Position += 2; // Dynamic Length + + writer.Write((byte)0x02); // Command + + writer.Write(locations); + + count = 0; + for (int i = 0; i < count; ++i) + { + Mobile mob = guild.Members[i]; // If guild count is above 0, then guild is not null. + + if (mob == from || mob?.NetState == null || locations && Utility.InUpdateRange(from, mob) && from.CanSee(mob)) + continue; + + count++; + writer.Write(mob.Serial); + + if (locations) { - Mobile mob = guild.Members[i]; + writer.Write((short)mob.X); + writer.Write((short)mob.Y); + writer.Write((byte)(mob.Map?.MapID ?? 0)); - if (mob == null || mob == from || mob.NetState == null) - continue; - - if (locations && Utility.InUpdateRange(from, mob) && from.CanSee(mob)) - continue; - - m_Stream.Write(mob.Serial); - - if (locations) - { - m_Stream.Write((short)mob.X); - m_Stream.Write((short)mob.Y); - m_Stream.Write((byte)(mob.Map?.MapID ?? 0)); - - if (Settings.GuildHitsPercent && mob.Alive) - m_Stream.Write((byte)(mob.Hits / Math.Max(mob.HitsMax, 1.0) * 100)); - else - m_Stream.Write((byte)0); - } + if (Settings.GuildHitsPercent && mob.Alive) + writer.Write((byte)(mob.Hits / Math.Max(mob.HitsMax, 1.0) * 100)); + else + writer.Position++; // writer.Write((byte)0); } - - m_Stream.Write(0); } + + if (count == 0) + return; + + writer.Position += 4; // Empty Serial + + writer.Position = 1; + writer.Write((ushort)writer.WrittenCount); + + ns.Send(writer.Span); } } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Items/Special/Solen Items/MessageHelper.cs b/Projects/Scripts/Misc/MessageHelper.cs similarity index 58% rename from Projects/Scripts/Items/Special/Solen Items/MessageHelper.cs rename to Projects/Scripts/Misc/MessageHelper.cs index 09f79bf9d..6bf6b001d 100644 --- a/Projects/Scripts/Items/Special/Solen Items/MessageHelper.cs +++ b/Projects/Scripts/Misc/MessageHelper.cs @@ -2,7 +2,7 @@ using Server.Network; namespace Server { - public class MessageHelper + public static class MessageHelper { public static void SendLocalizedMessageTo(Item from, Mobile to, int number, int hue) { @@ -11,12 +11,12 @@ namespace Server public static void SendLocalizedMessageTo(Item from, Mobile to, int number, string args, int hue) { - to.Send(new MessageLocalized(from.Serial, from.ItemID, MessageType.Regular, hue, 3, number, "", args)); + Packets.SendMessageLocalized(to.NetState, from.Serial, from.ItemID, MessageType.Regular, hue, 3, number, "", args); } public static void SendMessageTo(Item from, Mobile to, string text, int hue) { - to.Send(new UnicodeMessage(from.Serial, from.ItemID, MessageType.Regular, hue, 3, "ENU", "", text)); + Packets.SendUnicodeMessage(to.NetState, from.Serial, from.ItemID, MessageType.Regular, hue, 3, "ENU", "", text); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Misc/NameList.cs b/Projects/Scripts/Misc/NameList.cs index 36ba6a249..95c8e89a0 100644 --- a/Projects/Scripts/Misc/NameList.cs +++ b/Projects/Scripts/Misc/NameList.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Xml; namespace Server diff --git a/Projects/Scripts/Misc/NameVerification.cs b/Projects/Scripts/Misc/NameVerification.cs index 44ef8f68e..250b56913 100644 --- a/Projects/Scripts/Misc/NameVerification.cs +++ b/Projects/Scripts/Misc/NameVerification.cs @@ -1,6 +1,6 @@ namespace Server.Misc { - public class NameVerification + public static class NameVerification { public static readonly char[] SpaceDashPeriodQuote = { @@ -148,20 +148,9 @@ namespace Server.Misc exceptCount = 0; } - else - { - bool except = false; - - for (int j = 0; !except && j < exceptions.Length; ++j) - if (c == exceptions[j]) - except = true; - - if (!except || i == 0 && noExceptionsAtStart) - return false; - - if (exceptCount++ == maxExceptions) - return false; - } + else if (exceptCount++ == maxExceptions || exceptions.All(exception => exception != c) || + i == 0 && noExceptionsAtStart) + return false; } for (int i = 0; i < disallowed.Length; ++i) @@ -188,11 +177,7 @@ namespace Server.Misc return false; } - for (int i = 0; i < startDisallowed.Length; ++i) - if (name.StartsWith(startDisallowed[i])) - return false; - - return true; + return startDisallowed.All(t => !name.StartsWith(t)); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Misc/Notoriety.cs b/Projects/Scripts/Misc/Notoriety.cs index ea42bc887..7b528858d 100644 --- a/Projects/Scripts/Misc/Notoriety.cs +++ b/Projects/Scripts/Misc/Notoriety.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Server.Engines.ConPVP; using Server.Engines.PartySystem; using Server.Factions; @@ -12,7 +13,7 @@ using Server.Spells.Seventh; namespace Server.Misc { - public class NotorietyHandlers + public static class NotorietyHandlers { public static void Initialize() { @@ -306,7 +307,7 @@ namespace Server.Misc } /* Must be thread-safe */ - public static int MobileNotoriety(Mobile source, Mobile target) + public static byte MobileNotoriety(Mobile source, Mobile target) { BaseCreature bcTarg = target as BaseCreature; @@ -429,27 +430,12 @@ namespace Server.Misc public static bool IsSummoned(BaseCreature c) => c?.Summoned == true; - public static bool CheckAggressor(List list, Mobile target) - { - for (int i = 0; i < list.Count; ++i) - if (list[i].Attacker == target) - return true; + public static bool IsSummoned(BaseCreature c) => c?.Summoned == true; - return false; - } + public static bool CheckAggressor(IEnumerable list, Mobile target) => list.Any(t => t.Attacker == target); - public static bool CheckAggressed(List list, Mobile target) - { - for (int i = 0; i < list.Count; ++i) - { - AggressorInfo info = list[i]; - - if (!info.CriminalAggression && info.Defender == target) - return true; - } - - return false; - } + public static bool CheckAggressed(IEnumerable list, Mobile target) => + list.Any(info => !info.CriminalAggression && info.Defender == target); private enum GuildStatus { diff --git a/Projects/Scripts/Misc/Paperdoll.cs b/Projects/Scripts/Misc/Paperdoll.cs index 4ba425c74..8ad46e846 100644 --- a/Projects/Scripts/Misc/Paperdoll.cs +++ b/Projects/Scripts/Misc/Paperdoll.cs @@ -3,7 +3,7 @@ using Server.Network; namespace Server.Misc { - public class Paperdoll + public static class Paperdoll { public static void Initialize() { @@ -13,21 +13,22 @@ namespace Server.Misc public static void EventSink_PaperdollRequest(PaperdollRequestEventArgs e) { Mobile beholder = e.Beholder; + NetState ns = beholder.NetState; Mobile beheld = e.Beheld; - beholder.Send(new DisplayPaperdoll(beheld, Titles.ComputeTitle(beholder, beheld), - beheld.AllowEquipFrom(beholder))); + Packets.SendDisplayPaperdoll(ns, beholder, Titles.ComputeTitle(beholder, beheld), + beheld.AllowEquipFrom(beholder)); if (ObjectPropertyList.Enabled) { List items = beheld.Items; for (int i = 0; i < items.Count; ++i) - beholder.Send(items[i].OPLPacket); + items[i].PropertyList.SendOPLInfo(ns); // NOTE: OSI sends MobileUpdate when opening your own paperdoll. // It has a very bad rubber-banding affect. What positive affects does it have? } } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Misc/ProfanityProtection.cs b/Projects/Scripts/Misc/ProfanityProtection.cs index 514589214..0f6ebb23e 100644 --- a/Projects/Scripts/Misc/ProfanityProtection.cs +++ b/Projects/Scripts/Misc/ProfanityProtection.cs @@ -99,10 +99,7 @@ namespace Server.Misc return false; } default: - case ProfanityAction.Other: // TODO: Provide custom implementation if this is chosen - { return true; - } } } @@ -118,4 +115,4 @@ namespace Server.Misc e.Blocked = !OnProfanityDetected(from, e.Speech); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Misc/Profile.cs b/Projects/Scripts/Misc/Profile.cs index 98731f549..c87afd5eb 100644 --- a/Projects/Scripts/Misc/Profile.cs +++ b/Projects/Scripts/Misc/Profile.cs @@ -4,7 +4,7 @@ using Server.Network; namespace Server.Misc { - public class Profile + public static class Profile { public static void Initialize() { @@ -48,12 +48,9 @@ namespace Server.Misc if (footer.Length == 0 && beholder == beheld) footer = GetAccountDuration(beheld); - string body = beheld.Profile; + string body = beheld.Profile ?? ""; - if (body == null || body.Length <= 0) - body = ""; - - beholder.Send(new DisplayProfile(beholder != beheld || !beheld.ProfileLocked, beheld, header, body, footer)); + Packets.SendDisplayProfile(beholder.NetState, beholder != beheld || !beheld.ProfileLocked ? beheld.Serial : Serial.Zero, header, body, footer); } private static string GetAccountDuration(Mobile m) @@ -72,10 +69,7 @@ namespace Server.Misc if (Format(ts.TotalMinutes, "This account is {0} minute{1} old.", out v)) return v; - if (Format(ts.TotalSeconds, "This account is {0} second{1} old.", out v)) - return v; - - return ""; + return Format(ts.TotalSeconds, "This account is {0} second{1} old.", out v) ? v : ""; } public static bool Format(double value, string format, out string op) @@ -90,4 +84,4 @@ namespace Server.Misc return false; } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Misc/ProtocolExtensions.cs b/Projects/Scripts/Misc/ProtocolExtensions.cs index 5aeee0a96..6b3e3290e 100644 --- a/Projects/Scripts/Misc/ProtocolExtensions.cs +++ b/Projects/Scripts/Misc/ProtocolExtensions.cs @@ -3,9 +3,9 @@ using Server.Network; namespace Server.Misc { - public class ProtocolExtensions + public static class ProtocolExtensions { - private static PacketHandler[] m_Handlers = new PacketHandler[0x100]; + private static readonly PacketHandler[] m_Handlers = new PacketHandler[0x100]; public static void Initialize() { @@ -17,48 +17,34 @@ namespace Server.Misc m_Handlers[packetID] = new PacketHandler(packetID, 0, ingame, onReceive); } - public static PacketHandler GetHandler(int packetID) - { - if (packetID >= 0 && packetID < m_Handlers.Length) - return m_Handlers[packetID]; - - return null; - } + public static PacketHandler GetHandler(int packetID) => packetID >= 0 && packetID < m_Handlers.Length ? m_Handlers[packetID] : null; public static void DecodeBundledPacket(NetState state, PacketReader pvSrc) { int packetID = pvSrc.ReadByte(); PacketHandler ph = GetHandler(packetID); + if (ph == null) + return; - if (ph != null) + if (ph.Ingame) { - if (ph.Ingame && state.Mobile == null) + if (state.Mobile == null) { Console.WriteLine( - "Client: {0}: Sent ingame packet (0xF0x{1:X2}) before having been attached to a mobile", state, - packetID); + "Client: {0}: Sent ingame packet (0xF0x{1:X2}) before having been attached to a mobile", state, packetID); state.Dispose(); + return; } - else if (ph.Ingame && state.Mobile.Deleted) + + if (state.Mobile.Deleted) { state.Dispose(); - } - else - { - ph.OnReceive(state, pvSrc); + return; } } + + ph.OnReceive(state, pvSrc); } } - - public abstract class ProtocolExtension : Packet - { - public ProtocolExtension(int packetID, int capacity) : base(0xF0) - { - EnsureCapacity(4 + capacity); - - m_Stream.Write((byte)packetID); - } - } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Misc/RaceDefinitions.cs b/Projects/Scripts/Misc/RaceDefinitions.cs index eb9720308..7f3c4aaa6 100644 --- a/Projects/Scripts/Misc/RaceDefinitions.cs +++ b/Projects/Scripts/Misc/RaceDefinitions.cs @@ -1,3 +1,5 @@ +using System.Linq; + namespace Server.Misc { public class RaceDefinitions @@ -30,22 +32,9 @@ namespace Server.Misc { } - public override bool ValidateHair(bool female, int itemID) - { - if (itemID == 0) - return true; - - if (female && itemID == 0x2048 || !female && itemID == 0x2046) - return false; //Buns & Receding Hair - - if (itemID >= 0x203B && itemID <= 0x203D) - return true; - - if (itemID >= 0x2044 && itemID <= 0x204A) - return true; - - return false; - } + public override bool ValidateHair(bool female, int itemID) => + itemID == 0 || (!female || itemID != 0x2048) && (female || itemID != 0x2046) && + (itemID >= 0x203B && itemID <= 0x203D || itemID >= 0x2044 && itemID <= 0x204A); public override int RandomHair(bool female) //Random hair doesn't include baldness { @@ -90,32 +79,18 @@ namespace Server.Misc return (rand < 4 ? 0x203E : 0x2047) + rand; } - public override int ClipSkinHue(int hue) - { - if (hue < 1002) - return 1002; - if (hue > 1058) - return 1058; - return hue; - } + public override int ClipSkinHue(int hue) => hue < 1002 ? 1002 : hue > 1058 ? 1058 : hue; public override int RandomSkinHue() => Utility.Random(1002, 57) | 0x8000; - public override int ClipHairHue(int hue) - { - if (hue < 1102) - return 1102; - if (hue > 1149) - return 1149; - return hue; - } + public override int ClipHairHue(int hue) => hue < 1102 ? 1102 : hue > 1149 ? 1149 : hue; public override int RandomHairHue() => Utility.Random(1102, 48); } private class Elf : Race { - private static int[] m_SkinHues = + private static readonly int[] m_SkinHues = { 0x0BF, 0x24D, 0x24E, 0x24F, 0x353, 0x361, 0x367, 0x374, 0x375, 0x376, 0x381, 0x382, 0x383, 0x384, 0x385, 0x389, @@ -123,7 +98,7 @@ namespace Server.Misc 0x51D, 0x53F, 0x579, 0x76B, 0x76C, 0x76D, 0x835, 0x903 }; - private static int[] m_HairHues = + private static readonly int[] m_HairHues = { 0x034, 0x035, 0x036, 0x037, 0x038, 0x039, 0x058, 0x08E, 0x08F, 0x090, 0x091, 0x092, 0x101, 0x159, 0x15A, 0x15B, @@ -139,10 +114,10 @@ namespace Server.Misc { } - public override bool ValidateHair(bool female, int itemID) - { - if (itemID == 0) - return true; + public override bool ValidateHair(bool female, int itemID) => + itemID == 0 || (!female || itemID != 0x2FCD && itemID != 0x2FBF) && + (female || itemID != 0x2FCC && itemID != 0x2FD0) && + (itemID >= 0x2FBF && itemID <= 0x2FC2 || itemID >= 0x2FCC && itemID <= 0x2FD1); if (female && (itemID == 0x2FCD || itemID == 0x2FBF) || !female && (itemID == 0x2FCC || itemID == 0x2FD0)) return false; @@ -186,14 +161,9 @@ namespace Server.Misc public override int RandomSkinHue() => m_SkinHues[Utility.Random(m_SkinHues.Length)] | 0x8000; - public override int ClipHairHue(int hue) - { - for (int i = 0; i < m_HairHues.Length; i++) - if (m_HairHues[i] == hue) - return hue; + public override int RandomSkinHue() => m_SkinHues[Utility.Random(m_SkinHues.Length)] | 0x8000; - return m_HairHues[0]; - } + public override int ClipHairHue(int hue) => m_HairHues.Any(t => t == hue) ? hue : m_HairHues[0]; public override int RandomHairHue() => m_HairHues[Utility.Random(m_HairHues.Length)]; } @@ -225,13 +195,11 @@ namespace Server.Misc { } - public override bool ValidateHair(bool female, int itemID) - { - if (female == false) return itemID >= 0x4258 && itemID <= 0x425F; - - return itemID == 0x4261 || itemID == 0x4262 || itemID >= 0x4273 && itemID <= 0x4275 || itemID == 0x42B0 || - itemID == 0x42B1 || itemID == 0x42AA || itemID == 0x42AB; - } + public override bool ValidateHair(bool female, int itemID) => + female == false + ? itemID >= 0x4258 && itemID <= 0x425F + : itemID == 0x4261 || itemID == 0x4262 || itemID >= 0x4273 && itemID <= 0x4275 || itemID == 0x42B0 || + itemID == 0x42B1 || itemID == 0x42AA || itemID == 0x42AB; public override int RandomHair(bool female) { @@ -262,14 +230,9 @@ namespace Server.Misc public override int RandomSkinHue() => m_BodyHues[Utility.Random(m_BodyHues.Length)] | 0x8000; - public override int ClipHairHue(int hue) - { - for (int i = 0; i < m_HornHues.Length; i++) - if (m_HornHues[i] == hue) - return hue; + public override int RandomSkinHue() => m_BodyHues[Utility.Random(m_BodyHues.Length)] | 0x8000; - return m_HornHues[0]; - } + public override int ClipHairHue(int hue) => m_HornHues.Any(t => t == hue) ? hue : m_HornHues[0]; public override int RandomHairHue() => m_HornHues[Utility.Random(m_HornHues.Length)]; } diff --git a/Projects/Scripts/Misc/ServerList.cs b/Projects/Scripts/Misc/ServerList.cs index 469fc8d84..885d3f8fb 100644 --- a/Projects/Scripts/Misc/ServerList.cs +++ b/Projects/Scripts/Misc/ServerList.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Linq; using System.Net; using System.Net.NetworkInformation; using System.Net.Sockets; @@ -9,18 +10,18 @@ namespace Server.Misc { public class ServerList { - /* + /* * The default setting for Address, a value of 'null', will use your local IP address. If all of your local IP addresses * are private network addresses and AutoDetect is 'true' then RunUO will attempt to discover your public IP address * for you automatically. * * If you do not plan on allowing clients outside of your LAN to connect, you can set AutoDetect to 'false' and leave * Address set to 'null'. - * + * * If your public IP address cannot be determined, you must change the value of Address to your public IP address * manually to allow clients outside of your LAN to connect to your server. Address can be either an IP address or * a hostname that will be resolved when RunUO starts. - * + * * If you want players outside your LAN to be able to connect to your server and you are behind a router, you must also * forward TCP port 2593 to your private IP address. The procedure for doing this varies by manufacturer but generally * involves configuration of the router through your web browser. @@ -32,7 +33,7 @@ namespace Server.Misc * properly and fully supports listening on multiple ports. If a client with a public IP address is connecting to a * locally private address, the server will direct the client to either the AutoDetected IP address or the manually entered * IP address or hostname, whichever is applicable. Loopback clients will be directed to loopback. - * + * * If you would like to listen on additional ports (i.e. 22, 23, 80, for clients behind highly restrictive egress * firewalls) or specific IP adddresses you can do so by modifying the file SocketOptions.cs found in this directory. */ @@ -111,7 +112,7 @@ namespace Server.Misc IPHostEntry iphe = Dns.GetHostEntry(addr); if (iphe.AddressList.Length > 0) - outValue = iphe.AddressList[iphe.AddressList.Length - 1]; + outValue = iphe.AddressList[^1]; } catch { @@ -119,65 +120,23 @@ namespace Server.Misc } } - private static bool HasPublicIPAddress() - { - NetworkInterface[] adapters = NetworkInterface.GetAllNetworkInterfaces(); + private static bool HasPublicIPAddress() => + NetworkInterface.GetAllNetworkInterfaces().Select(adapter => adapter.GetIPProperties()) + .Any(properties => properties.UnicastAddresses.Select(unicast => unicast.Address) + .Any(ip => !IPAddress.IsLoopback(ip) && ip.AddressFamily != AddressFamily.InterNetworkV6 && !IsPrivateNetwork(ip))); - foreach (NetworkInterface adapter in adapters) - { - IPInterfaceProperties properties = adapter.GetIPProperties(); - - foreach (IPAddressInformation unicast in properties.UnicastAddresses) - { - IPAddress ip = unicast.Address; - - if (!IPAddress.IsLoopback(ip) && ip.AddressFamily != AddressFamily.InterNetworkV6 && - !IsPrivateNetwork(ip)) - return true; - } - } - - return false; - - - /* - IPHostEntry iphe = Dns.GetHostEntry( Dns.GetHostName() ); - - IPAddress[] ips = iphe.AddressList; - - for ( int i = 0; i < ips.Length; ++i ) - { - if ( ips[i].AddressFamily != AddressFamily.InterNetworkV6 && !IsPrivateNetwork( ips[i] ) ) - return true; - } - - return false; - */ - } - - private static bool IsPrivateNetwork(IPAddress ip) - { - // 10.0.0.0/8 - // 172.16.0.0/12 - // 192.168.0.0/16 - // 169.254.0.0/16 - // 100.64.0.0/10 RFC 6598 - - if (ip.AddressFamily == AddressFamily.InterNetworkV6) - return false; - - if (Utility.IPMatch("192.168.*", ip)) - return true; - if (Utility.IPMatch("10.*", ip)) - return true; - if (Utility.IPMatch("172.16-31.*", ip)) - return true; - if (Utility.IPMatch("169.254.*", ip)) - return true; - if (Utility.IPMatch("100.64-127.*", ip)) - return true; - return false; - } + // 10.0.0.0/8 + // 172.16.0.0/12 + // 192.168.0.0/16 + // 169.254.0.0/16 + // 100.64.0.0/10 RFC 6598 + private static bool IsPrivateNetwork(IPAddress ip) => + ip.AddressFamily != AddressFamily.InterNetworkV6 && + (Utility.IPMatch("192.168.*", ip) || + Utility.IPMatch("10.*", ip) || + Utility.IPMatch("172.16-31.*", ip) || + Utility.IPMatch("169.254.*", ip) || + Utility.IPMatch("100.64-127.*", ip)); private static IPAddress FindPublicAddress() { @@ -193,7 +152,7 @@ namespace Server.Misc StreamReader sr = new StreamReader(s); - IPAddress ip = IPAddress.Parse(sr.ReadLine()); + IPAddress ip = IPAddress.Parse(sr.ReadLine() ?? ""); sr.Close(); s.Close(); diff --git a/Projects/Scripts/Misc/ShardPoller.cs b/Projects/Scripts/Misc/ShardPoller.cs index 2e94a58c2..484c60db9 100644 --- a/Projects/Scripts/Misc/ShardPoller.cs +++ b/Projects/Scripts/Misc/ShardPoller.cs @@ -4,7 +4,6 @@ using System.Net; using System.Text.RegularExpressions; using Server.Gumps; using Server.Network; -using Server.Prompts; namespace Server.Misc { @@ -465,9 +464,7 @@ namespace Server.Misc public void QueuePoll(ShardPoller poller) { - if (m_Polls == null) - m_Polls = new Queue(4); - + m_Polls ??= new Queue(4); m_Polls.Enqueue(poller); } diff --git a/Projects/Scripts/Misc/SkillCheck.cs b/Projects/Scripts/Misc/SkillCheck.cs index c0ead7ea3..b1ca705b0 100644 --- a/Projects/Scripts/Misc/SkillCheck.cs +++ b/Projects/Scripts/Misc/SkillCheck.cs @@ -224,7 +224,7 @@ namespace Server.Misc Skills skills = from.Skills; - if (from.Player && skills.Total / skills.Cap >= Utility.RandomDouble()) //( skills.Total >= skills.Cap ) + if (from.Player && skills.Total / (double)skills.Cap >= Utility.RandomDouble()) //( skills.Total >= skills.Cap ) for (int i = 0; i < skills.Length; ++i) { Skill toLower = skills[i]; diff --git a/Projects/Scripts/Misc/Titles.cs b/Projects/Scripts/Misc/Titles.cs index 2ff78569f..ee2d50860 100644 --- a/Projects/Scripts/Misc/Titles.cs +++ b/Projects/Scripts/Misc/Titles.cs @@ -373,8 +373,7 @@ namespace Server.Misc { int fp = Math.Min(skill.BaseFixedPoint, 1200); - return (fp - 300) / 100; - } + private static int GetTableIndex(Skill skill) => (Math.Min(skill.BaseFixedPoint, 1200) - 300) / 100; } public class FameEntry diff --git a/Projects/Scripts/Misc/TreasureMapProtection.cs b/Projects/Scripts/Misc/TreasureMapProtection.cs index 16f3951bc..bdc79fdbb 100644 --- a/Projects/Scripts/Misc/TreasureMapProtection.cs +++ b/Projects/Scripts/Misc/TreasureMapProtection.cs @@ -19,7 +19,7 @@ namespace Server public static void Initialize() { string filePath = Path.Combine(Core.BaseDirectory, "Data/treasure.cfg"); - int i = 0, x = 0, y = 0; + int i = 0; if (File.Exists(filePath)) { @@ -69,4 +69,4 @@ namespace Server m.SendMessage("You have left a protected treasure map area."); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Misc/VendorGenerator.cs b/Projects/Scripts/Misc/VendorGenerator.cs index 40451ac82..204f6a6da 100644 --- a/Projects/Scripts/Misc/VendorGenerator.cs +++ b/Projects/Scripts/Misc/VendorGenerator.cs @@ -347,8 +347,6 @@ namespace Server private static bool CanFit(Map map, int x, int y, int z) { - bool hasSurface = false; - LandTile lt = map.Tiles.GetLandTile(x, y); int lowZ = 0, avgZ = 0, topZ = 0; @@ -357,8 +355,8 @@ namespace Server if ((landFlags & TileFlag.Impassable) != 0 && topZ > z && z + 16 > lowZ) return false; - if ((landFlags & TileFlag.Impassable) == 0 && z == avgZ && !lt.Ignored) - hasSurface = true; + + bool hasSurface = (landFlags & TileFlag.Impassable) == 0 && z == avgZ && !lt.Ignored; StaticTile[] staticTiles = map.Tiles.GetStaticTiles(x, y); @@ -376,8 +374,8 @@ namespace Server if ((surface || impassable) && staticTiles[i].Z + id.CalcHeight > z && z + 16 > staticTiles[i].Z) return false; - if (surface && !impassable && z == staticTiles[i].Z + id.CalcHeight) - hasSurface = true; + + hasSurface |= surface && !impassable && z == staticTiles[i].Z + id.CalcHeight; } Sector sector = map.GetSector(x, y); @@ -395,8 +393,8 @@ namespace Server if ((surface || impassable) && item.Z + id.CalcHeight > z && z + 16 > item.Z) return false; - if (surface && !impassable && z == item.Z + id.CalcHeight) - hasSurface = true; + + hasSurface |= surface && !impassable && z == item.Z + id.CalcHeight; } } @@ -413,9 +411,9 @@ namespace Server floor.Add(p); for (int xo = -1; xo <= 1; ++xo) - for (int yo = -1; yo <= 1; ++yo) - if ((xo != 0 || yo != 0) && IsFloor(map, x + xo, y + yo, false)) - RecurseFindFloor(map, x + xo, y + yo, floor); + for (int yo = -1; yo <= 1; ++yo) + if ((xo != 0 || yo != 0) && IsFloor(map, x + xo, y + yo, false)) + RecurseFindFloor(map, x + xo, y + yo, floor); } [Flags] diff --git a/Projects/Scripts/Misc/Weather.cs b/Projects/Scripts/Misc/Weather.cs index 34d3aa2c4..c9ff68246 100644 --- a/Projects/Scripts/Misc/Weather.cs +++ b/Projects/Scripts/Misc/Weather.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Server.Items; using Server.Network; diff --git a/Projects/Scripts/Misc/WeightOverloading.cs b/Projects/Scripts/Misc/WeightOverloading.cs index 27704df0a..b09a9e653 100644 --- a/Projects/Scripts/Misc/WeightOverloading.cs +++ b/Projects/Scripts/Misc/WeightOverloading.cs @@ -23,21 +23,12 @@ namespace Server.Misc public static void FatigueOnDamage(Mobile m, int damage) { - double fatigue = 0.0; - - switch (DFA) + double fatigue = DFA switch { - case DFAlgorithm.Standard: - { - fatigue = damage * (100.0 / m.Hits) * ((double)m.Stam / 100) - 5.0; - break; - } - case DFAlgorithm.PainSpike: - { - fatigue = damage * (100.0 / m.Hits + (50.0 + m.Stam) / 100 - 1.0) - 5.0; - break; - } - } + DFAlgorithm.Standard => damage * (100.0 / m.Hits) * ((double)m.Stam / 100) - 5.0, + DFAlgorithm.PainSpike => damage * (100.0 / m.Hits + (50.0 + m.Stam) / 100 - 1.0) - 5.0, + _ => 0.0, + }; if (fatigue > 0) m.Stam -= (int)fatigue; @@ -117,4 +108,4 @@ namespace Server.Misc return Mobile.BodyWeight + m.TotalWeight > GetMaxWeight(m) + OverloadAllowance; } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Mobiles/AI/AnimalAI.cs b/Projects/Scripts/Mobiles/AI/AnimalAI.cs index 9cc4585ea..90ad332d5 100644 --- a/Projects/Scripts/Mobiles/AI/AnimalAI.cs +++ b/Projects/Scripts/Mobiles/AI/AnimalAI.cs @@ -1,5 +1,5 @@ // Ideas -// When you run on animals the panic +// When you run on animals they panic // When if ( distance < 8 && Utility.RandomDouble() * Math.Sqrt( (8 - distance) / 6 ) >= incoming.Skills.AnimalTaming.Value ) // More your close, the more it can panic /* diff --git a/Projects/Scripts/Mobiles/AI/BaseAI.cs b/Projects/Scripts/Mobiles/AI/BaseAI.cs index 801a02665..5ecb9dafc 100644 --- a/Projects/Scripts/Mobiles/AI/BaseAI.cs +++ b/Projects/Scripts/Mobiles/AI/BaseAI.cs @@ -12,7 +12,6 @@ using Server.Regions; using Server.Spells; using Server.Spells.Spellweaving; using Server.Targets; -using MoveImpl = Server.Movement.MovementImpl; namespace Server.Mobiles { @@ -111,18 +110,7 @@ namespace Server.Mobiles m_Timer = new AITimer(this); - bool activate; - - if (!m.PlayerRangeSensitive) - activate = true; - else if (World.Loading) - activate = false; - else if (m.Map == null || m.Map == Map.Internal || !m.Map.GetSector(m).Active) - activate = false; - else - activate = true; - - if (activate) + if (!(m.PlayerRangeSensitive || World.Loading || m.Map == null || m.Map == Map.Internal || !m.Map.GetSector(m).Active)) m_Timer.Start(); Action = ActionType.Wander; @@ -1689,20 +1677,17 @@ namespace Server.Mobiles bool isPassive = delay == m_Mobile.PassiveSpeed; bool isControlled = m_Mobile.Controlled || m_Mobile.Summoned; - if (delay == 0.2) - delay = 0.3; - else if (delay == 0.25) - delay = 0.45; - else if (delay == 0.3) - delay = 0.6; - else if (delay == 0.4) - delay = 0.9; - else if (delay == 0.5) - delay = 1.05; - else if (delay == 0.6) - delay = 1.2; - else if (delay == 0.8) - delay = 1.5; + delay = delay switch + { + 0.2 => 0.3, + 0.25 => 0.45, + 0.3 => 0.6, + 0.4 => 0.9, + 0.5 => 1.05, + 0.6 => 1.2, + 0.8 => 1.5, + _ => delay + }; if (isPassive) delay += 0.2; @@ -1782,13 +1767,13 @@ namespace Server.Mobiles m_Mobile.Pushing = false; - MoveImpl.IgnoreMovableImpassables = m_Mobile.CanMoveOverObstacles && !m_Mobile.CanDestroyObstacles; + MovementImpl.IgnoreMovableImpassables = m_Mobile.CanMoveOverObstacles && !m_Mobile.CanDestroyObstacles; if ((m_Mobile.Direction & Direction.Mask) != (d & Direction.Mask)) { bool v = m_Mobile.Move(d); - MoveImpl.IgnoreMovableImpassables = false; + MovementImpl.IgnoreMovableImpassables = false; return v ? MoveResult.Success : MoveResult.Blocked; } @@ -1810,7 +1795,7 @@ namespace Server.Mobiles if (map != null) { int x = m_Mobile.X, y = m_Mobile.Y; - Movement.Movement.Offset(d, ref x, ref y); + Movement.Offset(d, ref x, ref y); int destroyables = 0; @@ -1899,20 +1884,20 @@ namespace Server.Mobiles if (m_Mobile.Move(m_Mobile.Direction)) { - MoveImpl.IgnoreMovableImpassables = false; + MovementImpl.IgnoreMovableImpassables = false; return MoveResult.SuccessAutoTurn; } } - MoveImpl.IgnoreMovableImpassables = false; + MovementImpl.IgnoreMovableImpassables = false; return wasPushing ? MoveResult.BadState : MoveResult.Blocked; } - MoveImpl.IgnoreMovableImpassables = false; + MovementImpl.IgnoreMovableImpassables = false; return MoveResult.Success; } - MoveImpl.IgnoreMovableImpassables = false; + MovementImpl.IgnoreMovableImpassables = false; return MoveResult.Success; } @@ -2022,9 +2007,9 @@ namespace Server.Mobiles return true; } - if (m_Path?.Goal == m) + if (ReferenceEquals(m_Path?.Goal, m)) { - if (m_Path.Follow(run, 1)) + if (m_Path?.Follow(run, 1) == true) { m_Path = null; return true; @@ -2032,8 +2017,7 @@ namespace Server.Mobiles } else if (!DoMove(m_Mobile.GetDirectionTo(m), true)) { - m_Path = new PathFollower(m_Mobile, m); - m_Path.Mover = DoMoveImpl; + m_Path = new PathFollower(m_Mobile, m) {Mover = DoMoveImpl}; if (m_Path.Follow(run, 1)) { @@ -2075,30 +2059,23 @@ namespace Server.Mobiles if (iCurrDist < iWantDistMin || iCurrDist > iWantDistMax) { bool needCloser = iCurrDist > iWantDistMax; - bool needFurther = !needCloser; - if (needCloser && m_Path != null && m_Path.Goal == m) + if (needCloser && m_Path != null && ReferenceEquals(m_Path.Goal, m)) { if (m_Path.Follow(bRun, 1)) m_Path = null; } else { - Direction dirTo; - - if (iCurrDist > iWantDistMax) - dirTo = m_Mobile.GetDirectionTo(m); - else - dirTo = m.GetDirectionTo(m_Mobile); + Direction dirTo = iCurrDist > iWantDistMax ? m_Mobile.GetDirectionTo(m) : m.GetDirectionTo(m_Mobile); // Add the run flag if (bRun) - dirTo = dirTo | Direction.Running; + dirTo |= Direction.Running; if (!DoMove(dirTo, true) && needCloser) { - m_Path = new PathFollower(m_Mobile, m); - m_Path.Mover = DoMoveImpl; + m_Path = new PathFollower(m_Mobile, m) {Mover = DoMoveImpl}; if (m_Path.Follow(bRun, 1)) m_Path = null; @@ -2704,13 +2681,9 @@ namespace Server.Mobiles } if (m_Owner.m_Mobile.BardPacified) - { m_Owner.DoBardPacified(); - } else if (m_Owner.m_Mobile.BardProvoked) - { m_Owner.DoBardProvoked(); - } else { if (!m_Owner.m_Mobile.Controlled) diff --git a/Projects/Scripts/Mobiles/AI/HealerAI.cs b/Projects/Scripts/Mobiles/AI/HealerAI.cs index f5fe4f341..68c51964a 100644 --- a/Projects/Scripts/Mobiles/AI/HealerAI.cs +++ b/Projects/Scripts/Mobiles/AI/HealerAI.cs @@ -1,3 +1,4 @@ +using System.Linq; using Server.Spells; using Server.Spells.First; using Server.Spells.Fourth; @@ -116,19 +117,16 @@ namespace Server.Mobiles if (!m_Mobile.CanSee(m) || !(m is BaseCreature) || ((BaseCreature)m).Team != m_Mobile.Team) continue; - for (int i = 0; i < funcs.Length; ++i) - if (funcs[i](m)) + if (funcs.Any(t => t(m))) + { + double val = -m_Mobile.GetDistanceToSqrt(m); + + if (found == null || val > prio) { - double val = -m_Mobile.GetDistanceToSqrt(m); - - if (found == null || val > prio) - { - prio = val; - found = m; - } - - break; + prio = val; + found = m; } + } } return found; diff --git a/Projects/Scripts/Mobiles/AI/MageAI.cs b/Projects/Scripts/Mobiles/AI/MageAI.cs index e4f9e69a5..0cc8875f6 100644 --- a/Projects/Scripts/Mobiles/AI/MageAI.cs +++ b/Projects/Scripts/Mobiles/AI/MageAI.cs @@ -339,18 +339,17 @@ namespace Server.Mobiles if (m_Mobile.Skills.Magery.Value >= 80.0 && Utility.RandomBool()) return new ManaVampireSpell(m_Mobile); - return new ManaDrainSpell(m_Mobile); - } + public virtual Spell GetRandomManaDrainSpell() => + m_Mobile.Skills.Magery.Value >= 80.0 && Utility.RandomBool() + ? (Spell)new ManaVampireSpell(m_Mobile) + : new ManaDrainSpell(m_Mobile); public virtual Spell DoDispel(Mobile toDispel) { if (!SmartAI) - { - if (ScaleBySkill(DispelChance, SkillName.Magery) > Utility.RandomDouble()) - return new DispelSpell(m_Mobile); - - return ChooseSpell(toDispel); - } + return ScaleBySkill(DispelChance, SkillName.Magery) > Utility.RandomDouble() + ? new DispelSpell(m_Mobile) + : ChooseSpell(toDispel); Spell spell = CheckCastHealingSpell(); diff --git a/Projects/Scripts/Mobiles/Animals/Mounts/Ethereals.cs b/Projects/Scripts/Mobiles/Animals/Mounts/Ethereals.cs index b2e2a7995..6478c7d68 100644 --- a/Projects/Scripts/Mobiles/Animals/Mounts/Ethereals.cs +++ b/Projects/Scripts/Mobiles/Animals/Mounts/Ethereals.cs @@ -364,13 +364,8 @@ namespace Server.Mobiles Disturb(DisturbType.Hurt, false); } - public override bool CheckDisturb(DisturbType type, bool checkFirst, bool resistable) - { - if (type == DisturbType.EquipRequest || type == DisturbType.UseRequest /* || type == DisturbType.Hurt*/) - return false; - - return true; - } + public override bool CheckDisturb(DisturbType type, bool checkFirst, bool resistable) => + type != DisturbType.EquipRequest && type != DisturbType.UseRequest; public override void DoHurtFizzle() { diff --git a/Projects/Scripts/Mobiles/Animals/Mounts/Kirin.cs b/Projects/Scripts/Mobiles/Animals/Mounts/Kirin.cs index 650e1194a..1e5d70fd5 100644 --- a/Projects/Scripts/Mobiles/Animals/Mounts/Kirin.cs +++ b/Projects/Scripts/Mobiles/Animals/Mounts/Kirin.cs @@ -78,7 +78,7 @@ namespace Server.Mobiles if (Rider.Hits - damage < 30 && Rider.Map == attacker.Map && Rider.InRange(attacker, 18) ) //Range and map checked here instead of other base fuction because of abiliites that don't need to check this { - attacker.BoltEffect(0); + attacker.BoltEffect(); // 35~100 damage, unresistable, by the Ki-rin. attacker.Damage(Utility.RandomMinMax(35, 100), this, false); //Don't inform mount about this damage, Still unsure wether or not it's flagged as the mount doing damage or the player. If changed to player, without the extra bool it'd be an infinite loop diff --git a/Projects/Scripts/Mobiles/BaseCreature.cs b/Projects/Scripts/Mobiles/BaseCreature.cs index 26d7e716d..927e57603 100644 --- a/Projects/Scripts/Mobiles/BaseCreature.cs +++ b/Projects/Scripts/Mobiles/BaseCreature.cs @@ -327,6 +327,7 @@ namespace Server.Mobiles { if (m_Paragon == value) return; + if (value) Paragon.Convert(this); else @@ -915,7 +916,7 @@ namespace Server.Mobiles return (double)chance / 1000; } - public override void Damage(int amount, Mobile from) + public override void Damage(int amount, Mobile from = null, bool informMount = true) { int oldHits = Hits; @@ -930,10 +931,10 @@ namespace Server.Mobiles if (oath == this) { amount = (int)(amount * 1.1); - from.Damage(amount, from); + from?.Damage(amount, from); } - base.Damage(amount, from); + base.Damage(amount, from, informMount); if (SubdueBeforeTame && !Controlled && oldHits > HitsMax / 10 && Hits <= HitsMax / 10) PublicOverheadMessage(MessageType.Regular, 0x3B2, false, @@ -2110,9 +2111,7 @@ namespace Server.Mobiles } } else if (ReacquireOnMovement) - { ForceReacquire(); - } InhumanSpeech speechType = SpeechType; @@ -2133,10 +2132,7 @@ namespace Server.Mobiles if (MLQuestSystem.Enabled && CanShout && m is PlayerMobile mobile) CheckShout(mobile, oldLocation); - if (m_NoDupeGuards == m) - return; - - if (!Body.IsHuman || Kills >= 5 || AlwaysMurderer || AlwaysAttackable || m.Kills < 5 || + if (m_NoDupeGuards == m || !Body.IsHuman || Kills >= 5 || AlwaysMurderer || AlwaysAttackable || m.Kills < 5 || !m.InRange(Location, 12) || !m.Alive) return; @@ -3056,7 +3052,12 @@ namespace Server.Mobiles IsDeadPet = false; - Effects.SendPacket(Location, Map, new BondedStatus(0, Serial, 0)); + IPooledEnumerable eable = Map.GetClientsInRange(Location); + + foreach (NetState ns in eable) + Packets.SendBondStatus(ns, Serial, false); + + eable.Free(); SendIncomingPacket(); SendIncomingPacket(); @@ -3100,10 +3101,7 @@ namespace Server.Mobiles m_ReturnQueued = true; } - else if (PlayerRangeSensitive) - { - AIObject?.Deactivate(); - } + else if (PlayerRangeSensitive) AIObject?.Deactivate(); base.OnSectorDeactivate(); } @@ -3237,15 +3235,11 @@ namespace Server.Mobiles { if (m_MLQuests == null) { - if (StaticMLQuester) - m_MLQuests = MLQuestSystem.FindQuestList(GetType()); - else - m_MLQuests = ConstructQuestList(); + m_MLQuests = StaticMLQuester ? MLQuestSystem.FindQuestList(GetType()) : ConstructQuestList(); + // return EmptyList, but don't cache it (run construction again next time) if (m_MLQuests == null) - return - MLQuestSystem - .EmptyList; // return EmptyList, but don't cache it (run construction again next time) + return MLQuestSystem.EmptyList; } return m_MLQuests; @@ -3269,9 +3263,7 @@ namespace Server.Mobiles if (m_MLNextShout > DateTime.UtcNow || pm.Hidden || !pm.Alive) return; - int shoutRange = ShoutRange; - - if (!InRange(pm.Location, shoutRange) || InRange(oldLocation, shoutRange) || !CanSee(pm) || !InLOS(pm)) + if (!InRange(pm.Location, ShoutRange) || InRange(oldLocation, ShoutRange) || !CanSee(pm) || !InLOS(pm)) return; MLQuestContext context = MLQuestSystem.GetContext(pm); @@ -3314,16 +3306,7 @@ namespace Server.Mobiles public Spawner MySpawner => Spawner as Spawner; [CommandProperty(AccessLevel.GameMaster)] - public Mobile LastOwner - { - get - { - if (Owners == null || Owners.Count == 0) - return null; - - return Owners[Owners.Count - 1]; - } - } + public Mobile LastOwner => Owners?.Count > 0 ? Owners[^1] : null; [CommandProperty(AccessLevel.GameMaster)] public bool IsBonded @@ -3732,9 +3715,7 @@ namespace Server.Mobiles public virtual void AddPetFriend(Mobile m) { - if (Friends == null) - Friends = new List(); - + Friends ??= new List(); Friends.Add(m); } @@ -3865,28 +3846,13 @@ namespace Server.Mobiles typeof(Gold) }; - public virtual bool CheckFoodPreference(Item f) - { - if (CheckFoodPreference(f, FoodType.Eggs, m_Eggs)) - return true; - - if (CheckFoodPreference(f, FoodType.Fish, m_Fish)) - return true; - - if (CheckFoodPreference(f, FoodType.GrainsAndHay, m_GrainsAndHay)) - return true; - - if (CheckFoodPreference(f, FoodType.Meat, m_Meat)) - return true; - - if (CheckFoodPreference(f, FoodType.FruitsAndVegies, m_FruitsAndVegies)) - return true; - - if (CheckFoodPreference(f, FoodType.Gold, m_Gold)) - return true; - - return false; - } + public virtual bool CheckFoodPreference(Item f) => + CheckFoodPreference(f, FoodType.Eggs, m_Eggs) || + CheckFoodPreference(f, FoodType.Fish, m_Fish) || + CheckFoodPreference(f, FoodType.GrainsAndHay, m_GrainsAndHay) || + CheckFoodPreference(f, FoodType.Meat, m_Meat) || + CheckFoodPreference(f, FoodType.FruitsAndVegies, m_FruitsAndVegies) || + CheckFoodPreference(f, FoodType.Gold, m_Gold); public virtual bool CheckFoodPreference(Item fed, FoodType type, Type[] types) { @@ -3904,82 +3870,79 @@ namespace Server.Mobiles public virtual bool CheckFeed(Mobile from, Item dropped) { - if (!IsDeadPet && Controlled && (ControlMaster == from || IsPetFriend(from))) + if (IsDeadPet || !Controlled || ControlMaster != from && !IsPetFriend(from)) + return false; + + Item f = dropped; + + if (!CheckFoodPreference(f)) + return false; + + int amount = f.Amount; + + if (amount <= 0) + return false; + + int stamGain; + + if (f is Gold) + stamGain = amount - 50; + else + stamGain = amount * 15 - 50; + + if (stamGain > 0) + Stam += stamGain; + + if (Core.SE) { - Item f = dropped; + if (m_Loyalty < MaxLoyalty) + m_Loyalty = MaxLoyalty; + } + else + for (int i = 0; i < amount; ++i) + if (m_Loyalty < MaxLoyalty && 0.5 >= Utility.RandomDouble()) + m_Loyalty += 10; - if (CheckFoodPreference(f)) + /* if ( happier )*/ + // looks like in OSI pets say they are happier even if they are at maximum loyalty + SayTo(from, 502060); // Your pet looks happier. + + if (Body.IsAnimal) + Animate(3, 5, 1, true, false, 0); + else if (Body.IsMonster) + Animate(17, 5, 1, true, false, 0); + + if (IsBondable && !IsBonded) + { + Mobile master = m_ControlMaster; + + if (master != null && master == from) //So friends can't start the bonding process { - int amount = f.Amount; - - if (amount > 0) + if (MinTameSkill <= 29.1 || master.Skills.AnimalTaming.Base >= MinTameSkill || + OverrideBondingReqs() || + Core.ML && master.Skills.AnimalTaming.Value >= MinTameSkill) { - int stamGain; - - if (f is Gold) - stamGain = amount - 50; - else - stamGain = amount * 15 - 50; - - if (stamGain > 0) - Stam += stamGain; - - if (Core.SE) + if (BondingBegin == DateTime.MinValue) { - if (m_Loyalty < MaxLoyalty) m_Loyalty = MaxLoyalty; + BondingBegin = DateTime.UtcNow; } - else + else if (BondingBegin + BondingDelay <= DateTime.UtcNow) { - for (int i = 0; i < amount; ++i) - if (m_Loyalty < MaxLoyalty && 0.5 >= Utility.RandomDouble()) - m_Loyalty += 10; + IsBonded = true; + BondingBegin = DateTime.MinValue; + from.SendLocalizedMessage(1049666); // Your pet has bonded with you! } - - /* if ( happier )*/ - // looks like in OSI pets say they are happier even if they are at maximum loyalty - SayTo(from, 502060); // Your pet looks happier. - - if (Body.IsAnimal) - Animate(3, 5, 1, true, false, 0); - else if (Body.IsMonster) - Animate(17, 5, 1, true, false, 0); - - if (IsBondable && !IsBonded) - { - Mobile master = m_ControlMaster; - - if (master != null && master == from) //So friends can't start the bonding process - { - if (MinTameSkill <= 29.1 || master.Skills.AnimalTaming.Base >= MinTameSkill || - OverrideBondingReqs() || - Core.ML && master.Skills.AnimalTaming.Value >= MinTameSkill) - { - if (BondingBegin == DateTime.MinValue) - { - BondingBegin = DateTime.UtcNow; - } - else if (BondingBegin + BondingDelay <= DateTime.UtcNow) - { - IsBonded = true; - BondingBegin = DateTime.MinValue; - from.SendLocalizedMessage(1049666); // Your pet has bonded with you! - } - } - else if (Core.ML) - { - from.SendLocalizedMessage( - 1075268); // Your pet cannot form a bond with you until your animal taming ability has risen. - } - } - } - - dropped.Delete(); - return true; + } + else if (Core.ML) + { + from.SendLocalizedMessage( + 1075268); // Your pet cannot form a bond with you until your animal taming ability has risen. } } } - return false; + dropped.Delete(); + return true; } #endregion @@ -4032,23 +3995,10 @@ namespace Server.Mobiles public virtual bool CanTeach => false; - public virtual bool CheckTeach(SkillName skill, Mobile from) - { - if (!CanTeach) - return false; - - if (skill == SkillName.Stealth && from.Skills.Hiding.Base < Stealth.HidingRequirement) - return false; - - if (skill == SkillName.RemoveTrap && (from.Skills.Lockpicking.Base < 50.0 || - from.Skills.DetectHidden.Base < 50.0)) - return false; - - if (!Core.AOS && (skill == SkillName.Focus || skill == SkillName.Chivalry || skill == SkillName.Necromancy)) - return false; - - return true; - } + public virtual bool CheckTeach(SkillName skill, Mobile from) => + CanTeach && (skill != SkillName.Stealth || !(from.Skills.Hiding.Base < Stealth.HidingRequirement)) && + (skill != SkillName.RemoveTrap || !(from.Skills.Lockpicking.Base < 50.0) && !(from.Skills.DetectHidden.Base < 50.0)) && + (Core.AOS || skill != SkillName.Focus && skill != SkillName.Chivalry && skill != SkillName.Necromancy); public enum TeachResult { @@ -4158,16 +4108,8 @@ namespace Server.Mobiles return TeachResult.Success; } - public virtual bool CheckTeachingMatch(Mobile m) - { - if (m_Teaching == (SkillName)(-1)) - return false; - - if (m is PlayerMobile mobile) - return mobile.Learning == m_Teaching; - - return true; - } + public virtual bool CheckTeachingMatch(Mobile m) => + m_Teaching != (SkillName)(-1) && (!(m is PlayerMobile mobile) || mobile.Learning == m_Teaching); private SkillName m_Teaching = (SkillName)(-1); @@ -5112,9 +5054,7 @@ namespace Server.Mobiles if (c.Loyalty <= 0) lock (toRelease) - { toRelease.Add(c); - } } } @@ -5122,18 +5062,12 @@ namespace Server.Mobiles if (!c.Controlled && !c.IsStabled && (c.Region.IsPartOf() && c.CanBeDamaged() || c.RemoveIfUntamed && c.Spawner == null)) { - c.RemoveStep++; - - if (c.RemoveStep >= 20) + if (c.RemoveStep++ >= 20) lock (toRemove) - { toRemove.Add(c); - } } else - { c.RemoveStep = 0; - } }); // TODO: Parallelize this diff --git a/Projects/Scripts/Mobiles/Familiars/HordeMinion.cs b/Projects/Scripts/Mobiles/Familiars/HordeMinion.cs index 8012f81be..fb2205a74 100644 --- a/Projects/Scripts/Mobiles/Familiars/HordeMinion.cs +++ b/Projects/Scripts/Mobiles/Familiars/HordeMinion.cs @@ -73,11 +73,11 @@ namespace Server.Mobiles if (pack == null) return; - IEnumerable eable = GetItemsInRange(2).Where(item => item.Movable && item.Stackable); + IPooledEnumerable eable = GetItemsInRange(2); int pickedUp = 0; - foreach (Item item in eable) + foreach (Item item in eable.Where(item => item.Movable && item.Stackable)) { if (!pack.CheckHold(this, item, false, true)) return; @@ -94,6 +94,8 @@ namespace Server.Mobiles if (++pickedUp == 3) break; } + + eable.Free(); } private void ConfirmRelease_Callback(Mobile from, bool okay) diff --git a/Projects/Scripts/Mobiles/Guards/ArcherGuard.cs b/Projects/Scripts/Mobiles/Guards/ArcherGuard.cs index 6560b2652..ac3f11045 100644 --- a/Projects/Scripts/Mobiles/Guards/ArcherGuard.cs +++ b/Projects/Scripts/Mobiles/Guards/ArcherGuard.cs @@ -261,7 +261,7 @@ namespace Server.Mobiles { // TeleportTo(target); - target.BoltEffect(0); + target.BoltEffect(); if (target is BaseCreature creature) creature.NoKillAwards = true; diff --git a/Projects/Scripts/Mobiles/Guards/BaseGuard.cs b/Projects/Scripts/Mobiles/Guards/BaseGuard.cs index 187318cd8..5d8a5c59e 100644 --- a/Projects/Scripts/Mobiles/Guards/BaseGuard.cs +++ b/Projects/Scripts/Mobiles/Guards/BaseGuard.cs @@ -27,7 +27,9 @@ namespace Server.Mobiles if (target?.Deleted != false) return; - foreach (Mobile m in target.GetMobilesInRange(15)) + IPooledEnumerable eable = target.GetMobilesInRange(15); + + foreach (Mobile m in eable) if (m is BaseGuard g) { if (g.Focus == null) // idling @@ -42,6 +44,8 @@ namespace Server.Mobiles } } + eable.Free(); + while (amount-- > 0) caller.Region.MakeGuard(target); } @@ -72,4 +76,4 @@ namespace Server.Mobiles int version = reader.ReadInt(); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Mobiles/Guards/WarriorGuard.cs b/Projects/Scripts/Mobiles/Guards/WarriorGuard.cs index 1cad91a09..909a8dd27 100644 --- a/Projects/Scripts/Mobiles/Guards/WarriorGuard.cs +++ b/Projects/Scripts/Mobiles/Guards/WarriorGuard.cs @@ -292,7 +292,7 @@ namespace Server.Mobiles { // TeleportTo(target); - target.BoltEffect(0); + target.BoltEffect(); if (target is BaseCreature creature) creature.NoKillAwards = true; diff --git a/Projects/Scripts/Mobiles/Monsters/Humanoid/Magic/SavageShaman.cs b/Projects/Scripts/Mobiles/Monsters/Humanoid/Magic/SavageShaman.cs index 63bf68194..c2df17252 100644 --- a/Projects/Scripts/Mobiles/Monsters/Humanoid/Magic/SavageShaman.cs +++ b/Projects/Scripts/Mobiles/Monsters/Humanoid/Magic/SavageShaman.cs @@ -151,7 +151,7 @@ namespace Server.Mobiles return; IPooledEnumerable eable = GetMobilesInRange(8); - + switch (Utility.Random(3)) { case 0: /* greater heal */ @@ -208,7 +208,7 @@ namespace Server.Mobiles damage = Utility.Random(12, 9); } - m.BoltEffect(0); + m.BoltEffect(); SpellHelper.Damage(TimeSpan.FromSeconds(0.25), m, this, damage, 0, 0, 0, 0, 100); } @@ -260,7 +260,7 @@ namespace Server.Mobiles break; } } - + eable.Free(); } @@ -276,4 +276,4 @@ namespace Server.Mobiles int version = reader.ReadInt(); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Mobiles/Monsters/Humanoid/Melee/KhaldunRevenant.cs b/Projects/Scripts/Mobiles/Monsters/Humanoid/Melee/KhaldunRevenant.cs index 5bb6064aa..b56c8a0a5 100644 --- a/Projects/Scripts/Mobiles/Monsters/Humanoid/Melee/KhaldunRevenant.cs +++ b/Projects/Scripts/Mobiles/Monsters/Humanoid/Melee/KhaldunRevenant.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Server.Items; namespace Server.Mobiles @@ -79,13 +80,9 @@ namespace Server.Mobiles if (lastKiller is BaseCreature creature) lastKiller = creature.GetMaster(); - if (IsInsideKhaldun(m) && IsInsideKhaldun(lastKiller) && lastKiller.Player && !m_Set.Contains(lastKiller)) - foreach (AggressorInfo ai in m.Aggressors) - if (ai.Attacker == lastKiller && ai.CanReportMurder) - { - SummonRevenant(m, lastKiller); - break; - } + if (IsInsideKhaldun(m) && IsInsideKhaldun(lastKiller) && lastKiller.Player && + !m_Set.Contains(lastKiller) && m.Aggressors.Any(ai => ai.Attacker == lastKiller && ai.CanReportMurder)) + SummonRevenant(m, lastKiller); } public static void SummonRevenant(Mobile victim, Mobile killer) diff --git a/Projects/Scripts/Mobiles/Monsters/Humanoid/Melee/KhaldunSummoner.cs b/Projects/Scripts/Mobiles/Monsters/Humanoid/Melee/KhaldunSummoner.cs index 5eceebcba..7829cb1ae 100644 --- a/Projects/Scripts/Mobiles/Monsters/Humanoid/Melee/KhaldunSummoner.cs +++ b/Projects/Scripts/Mobiles/Monsters/Humanoid/Melee/KhaldunSummoner.cs @@ -104,7 +104,7 @@ namespace Server.Mobiles } Effects.PlaySound(this, Map, GetDeathSound()); - Effects.SendLocationEffect(Location, Map, 0x3709, 30, 10, 0x835, 0); + Effects.SendLocationEffect(Location, Map, 0x3709, 30, 10, 0x835); rm.MoveToWorld(Location, Map); Delete(); diff --git a/Projects/Scripts/Mobiles/Monsters/Humanoid/Melee/KhaldunZealot.cs b/Projects/Scripts/Mobiles/Monsters/Humanoid/Melee/KhaldunZealot.cs index b01f3900e..733d9df4f 100644 --- a/Projects/Scripts/Mobiles/Monsters/Humanoid/Melee/KhaldunZealot.cs +++ b/Projects/Scripts/Mobiles/Monsters/Humanoid/Melee/KhaldunZealot.cs @@ -113,7 +113,7 @@ namespace Server.Mobiles } Effects.PlaySound(this, Map, GetDeathSound()); - Effects.SendLocationEffect(Location, Map, 0x3709, 30, 10, 0x835, 0); + Effects.SendLocationEffect(Location, Map, 0x3709, 30, 10, 0x835); rm.MoveToWorld(Location, Map); Delete(); diff --git a/Projects/Scripts/Mobiles/Monsters/ML/Special/Ilhenir.cs b/Projects/Scripts/Mobiles/Monsters/ML/Special/Ilhenir.cs index 0d05094af..ede677bb7 100644 --- a/Projects/Scripts/Mobiles/Monsters/ML/Special/Ilhenir.cs +++ b/Projects/Scripts/Mobiles/Monsters/ML/Special/Ilhenir.cs @@ -217,7 +217,7 @@ namespace Server.Mobiles { if (to.Alive && to.Player && !UnderCacophonicAttack(to)) { - to.Send(SpeedControl.WalkSpeed); + Packets.SendSpeedControlWalk(to.NetState); to.SendLocalizedMessage(1072069); // A cacophonic sound lambastes you, suppressing your ability to move. to.PlaySound(0x584); @@ -229,7 +229,7 @@ namespace Server.Mobiles public virtual void CacophonicEnd(Mobile from) { m_Table.Remove(from); - from.Send(SpeedControl.Disable); + Packets.SendSpeedControlDisabled(from.NetState); } public static bool UnderCacophonicAttack(Mobile from) => m_Table.Contains(from); diff --git a/Projects/Scripts/Mobiles/Monsters/Misc/Melee/PlagueBeastLord.cs b/Projects/Scripts/Mobiles/Monsters/Misc/Melee/PlagueBeastLord.cs index 848713e48..d64a16c67 100644 --- a/Projects/Scripts/Mobiles/Monsters/Misc/Melee/PlagueBeastLord.cs +++ b/Projects/Scripts/Mobiles/Monsters/Misc/Melee/PlagueBeastLord.cs @@ -76,8 +76,7 @@ namespace Server.Mobiles { OpenedBy = from; - if (m_Timer == null) - m_Timer = new DecayTimer(this); + m_Timer ??= new DecayTimer(this); if (!m_Timer.Running) m_Timer.Start(); diff --git a/Projects/Scripts/Mobiles/Monsters/Misc/Melee/PlagueSpawn.cs b/Projects/Scripts/Mobiles/Monsters/Misc/Melee/PlagueSpawn.cs index 40eeebf38..e479247af 100644 --- a/Projects/Scripts/Mobiles/Monsters/Misc/Melee/PlagueSpawn.cs +++ b/Projects/Scripts/Mobiles/Monsters/Misc/Melee/PlagueSpawn.cs @@ -35,8 +35,7 @@ namespace Server.Mobiles Body = 0x15; BaseSoundID = 0xDB; break; - default: - case 5: // slime + default: // slime Body = 51; BaseSoundID = 456; break; diff --git a/Projects/Scripts/Mobiles/Monsters/SE/DeathWatchBeetle.cs b/Projects/Scripts/Mobiles/Monsters/SE/DeathWatchBeetle.cs index 72b4bb73e..a3b7a0179 100644 --- a/Projects/Scripts/Mobiles/Monsters/SE/DeathWatchBeetle.cs +++ b/Projects/Scripts/Mobiles/Monsters/SE/DeathWatchBeetle.cs @@ -98,7 +98,7 @@ namespace Server.Mobiles { if (Utility.RandomBool() && Mana > 14 && to != null) { - damage = damage + damage / 2; + damage += damage / 2; to.SendLocalizedMessage(1060091); // You take extra damage from the crushing attack! to.PlaySound(0x1E1); to.FixedParticles(0x377A, 1, 32, 0x26da, 0, 0, 0); diff --git a/Projects/Scripts/Mobiles/Monsters/SE/FanDancer.cs b/Projects/Scripts/Mobiles/Monsters/SE/FanDancer.cs index 998623e31..31ce55213 100644 --- a/Projects/Scripts/Mobiles/Monsters/SE/FanDancer.cs +++ b/Projects/Scripts/Mobiles/Monsters/SE/FanDancer.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using Server.Engines.Plants; using Server.Items; -using Server.Network; namespace Server.Mobiles { @@ -85,9 +84,7 @@ namespace Server.Mobiles * Effect: - To: "0x57D4F5B" - ItemId: "0x27A3" - ItemIdName: "Tessen" - FromLocation: "(992 299, 24)" - ToLocation: "(992 308, 22)" - Speed: "10" - Duration: "0" - FixedDirection: "False" - Explode: "False" - Hue: "0x0" - Render: "0x0" * Damage: 50-65 */ - Effects.SendPacket(attacker, attacker.Map, - new HuedEffect(EffectType.Moving, Serial.Zero, Serial.Zero, 0x27A3, Location, attacker.Location, 10, 0, - false, false, 0, 0)); + Effects.SendMovingEffect(Location, attacker.Location, attacker.Map, 0x27A3, 10); AOS.Damage(attacker, this, Utility.RandomMinMax(50, 65), 100, 0, 0, 0, 0); } } @@ -102,9 +99,7 @@ namespace Server.Mobiles * Effect: - To: "0x57D4F5B" - ItemId: "0x27A3" - ItemIdName: "Tessen" - FromLocation: "(992 299, 24)" - ToLocation: "(992 308, 22)" - Speed: "10" - Duration: "0" - FixedDirection: "False" - Explode: "False" - Hue: "0x0" - Render: "0x0" * Damage: 50-65 */ - Effects.SendPacket(attacker, attacker.Map, - new HuedEffect(EffectType.Moving, Serial.Zero, Serial.Zero, 0x27A3, Location, attacker.Location, 10, 0, - false, false, 0, 0)); + Effects.SendMovingEffect(Location, attacker.Location, attacker.Map, 0x27A3, 10); AOS.Damage(attacker, this, Utility.RandomMinMax(50, 65), 100, 0, 0, 0, 0); } } diff --git a/Projects/Scripts/Mobiles/PlayerMobile.cs b/Projects/Scripts/Mobiles/PlayerMobile.cs index b38ba71bb..0e02156ee 100644 --- a/Projects/Scripts/Mobiles/PlayerMobile.cs +++ b/Projects/Scripts/Mobiles/PlayerMobile.cs @@ -18,7 +18,6 @@ using Server.Guilds; using Server.Gumps; using Server.Items; using Server.Misc; -using Server.Movement; using Server.Multis; using Server.Network; using Server.Regions; @@ -204,16 +203,7 @@ namespace Server.Mobiles SkillName.TasteID }; - public override double RacialSkillBonus - { - get - { - if (Core.ML && Race == Race.Human) - return 20.0; - - return 0; - } - } + public override double RacialSkillBonus => Core.ML && Race == Race.Human ? 20.0 : 0; public List EquipSnapshot{ get; private set; } @@ -302,15 +292,7 @@ namespace Server.Mobiles public DateTime SessionStart{ get; private set; } [CommandProperty(AccessLevel.GameMaster)] - public TimeSpan GameTime - { - get - { - if (NetState != null) - return m_GameTime + (DateTime.UtcNow - SessionStart); - return m_GameTime; - } - } + public TimeSpan GameTime => NetState != null ? m_GameTime + (DateTime.UtcNow - SessionStart) : m_GameTime; public override bool NewGuildDisplay => Guilds.Guild.NewGuildSystem; @@ -365,13 +347,9 @@ namespace Server.Mobiles BlockMountType type = MountBlockReason; if (!Alive) - { SendLocalizedMessage(1113082); // You may not fly while dead. - } else if (IsBodyMod && !(BodyMod == 666 || BodyMod == 667)) - { SendLocalizedMessage(1112453); // You can't fly in your current form! - } else if (type != BlockMountType.None) { switch (type) @@ -548,10 +526,9 @@ namespace Server.Mobiles private static void CheckPets() { foreach (Mobile m in World.Mobiles.Values) - if (m is PlayerMobile pm) - if ((!pm.Mounted || pm.Mount is EtherealMount) && pm.AllFollowers.Count > pm.AutoStabled.Count || - pm.Mounted && pm.AllFollowers.Count > pm.AutoStabled.Count + 1) - pm.AutoStablePets(); /* autostable checks summons, et al: no need here */ + if (m is PlayerMobile pm && ((!pm.Mounted || pm.Mount is EtherealMount) && pm.AllFollowers.Count > pm.AutoStabled.Count || + pm.Mounted && pm.AllFollowers.Count > pm.AutoStabled.Count + 1)) + pm.AutoStablePets(); /* autostable checks summons, et al: no need here */ } private static bool CheckBlock(MountBlock block) => block?.m_Timer.Running == true; @@ -632,8 +609,8 @@ namespace Server.Mobiles m_LastGlobalLight = global; m_LastPersonalLight = personal; - ns.Send(GlobalLightLevel.Instantiate(global)); - ns.Send(new PersonalLightLevel(this, personal)); + Packets.SendGlobalLightLevel(ns, (sbyte)global); + Packets.SendPersonalLightLevel(ns, Serial, (sbyte)personal); } public override int GetMinResistance(ResistanceType type) @@ -677,23 +654,17 @@ namespace Server.Mobiles if (!(from.Account is Account acct) || !acct.HasAccess(from.NetState)) { - if (from.AccessLevel == AccessLevel.Player) - notice = "The server is currently under lockdown. No players are allowed to log in at this time."; - else - notice = - "The server is currently under lockdown. You do not have sufficient access level to connect."; + notice = from.AccessLevel == AccessLevel.Player ? + "The server is currently under lockdown. No players are allowed to log in at this time." : + "The server is currently under lockdown. You do not have sufficient access level to connect."; - Timer.DelayCall(TimeSpan.FromSeconds(1.0), () => from.NetState?.Dispose()); + Timer.DelayCall(TimeSpan.FromSeconds(1.0), ns => ns?.Dispose(), from.NetState); } else if (from.AccessLevel >= AccessLevel.Administrator) - { notice = "The server is currently under lockdown. As you are an administrator, you may change this from the [Admin gump."; - } else - { notice = "The server is currently under lockdown. You have sufficient access level to connect."; - } from.SendGump(new NoticeGump(1060637, 30720, notice, 0xFFC000, 300, 140)); return; @@ -1050,13 +1021,9 @@ namespace Server.Mobiles return base.CanBeHarmful(target, message, ignoreOurBlessedness); } - public override bool CanBeBeneficial(Mobile target, bool message, bool allowDead) - { - if (DesignContext != null || target is PlayerMobile mobile && mobile.DesignContext != null) - return false; - - return base.CanBeBeneficial(target, message, allowDead); - } + public override bool CanBeBeneficial(Mobile target, bool message, bool allowDead) => + DesignContext == null && (!(target is PlayerMobile mobile) || mobile.DesignContext == null) && + base.CanBeBeneficial(target, message, allowDead); public override bool CheckContextMenuDisplay(IEntity target) => DesignContext == null; @@ -1116,12 +1083,10 @@ namespace Server.Mobiles int speed = ComputeMovementSpeed(d); - bool res; - if (!Alive) MovementImpl.IgnoreMovableImpassables = true; - res = base.Move(d); + bool res = base.Move(d); MovementImpl.IgnoreMovableImpassables = false; @@ -1145,7 +1110,7 @@ namespace Server.Mobiles newZ = foundation.Z + HouseFoundation.GetLevelZ(context.Level, context.Foundation); int newX = X, newY = Y; - Movement.Movement.Offset(d, ref newX, ref newY); + Movement.Offset(d, ref newX, ref newY); int startX = foundation.X + foundation.Components.Min.X + 1; int startY = foundation.Y + foundation.Components.Min.Y + 1; @@ -1882,7 +1847,7 @@ namespace Server.Mobiles pointsToGain += (int)Math.Sqrt(GameTime.TotalSeconds * 4); pointsToGain *= 5; - pointsToGain += (int)Math.Pow(Skills.Total / 250, 2); + pointsToGain += (int)Math.Pow(Skills.Total / 250.0, 2); if (VirtueHelper.Award(m, VirtueName.Justice, pointsToGain, ref gainedPath)) { @@ -1894,7 +1859,7 @@ namespace Server.Mobiles m.FixedParticles(0x375A, 9, 20, 5027, EffectLayer.Waist); m.PlaySound(0x1F7); - m_NextJustAward = DateTime.UtcNow + TimeSpan.FromMinutes(pointsToGain / 3); + m_NextJustAward = DateTime.UtcNow + TimeSpan.FromMinutes(pointsToGain / 3.0); } } } @@ -1931,16 +1896,8 @@ namespace Server.Mobiles #endregion if (m_BuffTable != null) - { - List list = new List(); - - foreach (BuffInfo buff in m_BuffTable.Values) - if (!buff.RetainThroughDeath) - list.Add(buff); - - for (int i = 0; i < list.Count; i++) - RemoveBuff(list[i]); - } + foreach(var buff in m_BuffTable.Values.Where(buff => !buff.RetainThroughDeath)) + RemoveBuff(buff); } public override bool MutateSpeech(List hears, ref string text, ref object context) @@ -1951,14 +1908,8 @@ namespace Server.Mobiles if (Core.ML && Skills.SpiritSpeak.Value >= 100.0) return false; - if (Core.AOS) - for (int i = 0; i < hears.Count; ++i) - { - Mobile m = hears[i]; - - if (m != this && m.Skills.SpiritSpeak.Value >= 100.0) - return false; - } + if (Core.AOS && hears.Any(m => m != this && m.Skills.SpiritSpeak.Value >= 100.0)) + return false; return base.MutateSpeech(hears, ref text, ref context); } @@ -1968,65 +1919,48 @@ namespace Server.Mobiles if (Guilds.Guild.NewGuildSystem && (type == MessageType.Guild || type == MessageType.Alliance)) { if (!(Guild is Guild g)) - { SendLocalizedMessage(1063142); // You are not in a guild! - } else if (type == MessageType.Alliance) { if (g.Alliance?.IsMember(g) == true) { //g.Alliance.AllianceTextMessage( hue, "[Alliance][{0}]: {1}", this.Name, text ); g.Alliance.AllianceChat(this, text); - SendToStaffMessage(this, "[Alliance]: {0}", text); + SendToStaffMessage(this, $"[Alliance]: {text}"); AllianceMessageHue = hue; } else - { SendLocalizedMessage(1071020); // You are not in an alliance! - } } else //Type == MessageType.Guild { GuildMessageHue = hue; g.GuildChat(this, text); - SendToStaffMessage(this, "[Guild]: {0}", text); + SendToStaffMessage(this, $"[Guild]: {text}"); } } else - { base.DoSpeech(text, keywords, type, hue); - } } private static void SendToStaffMessage(Mobile from, string text) { - Packet p = null; - - foreach (NetState ns in from.GetClientsInRange(8)) + IPooledEnumerable eable = from.GetClientsInRange(8); + foreach (NetState ns in eable) { Mobile mob = ns.Mobile; if (mob?.AccessLevel >= AccessLevel.GameMaster && mob.AccessLevel > from.AccessLevel) - { - if (p == null) - p = Packet.Acquire(new UnicodeMessage(from.Serial, from.Body, MessageType.Regular, from.SpeechHue, 3, - from.Language, from.Name, text)); - - ns.Send(p); - } + Packets.SendUnicodeMessage(ns, from.Serial, from.Body, MessageType.Regular, from.SpeechHue, 3, + from.Language, from.Name, text); } - Packet.Release(p); + eable.Free(); } - private static void SendToStaffMessage(Mobile from, string format, params object[] args) - { - SendToStaffMessage(from, string.Format(format, args)); - } - - public override void Damage(int amount, Mobile from) + public override void Damage(int amount, Mobile from = null, bool informMount = true) { if (EvilOmenSpell.TryEndEffect(this)) amount = (int)(amount * 1.25); @@ -2049,16 +1983,15 @@ namespace Server.Mobiles from.Damage(amount, this); } - if (from != null && Talisman is BaseTalisman talisman) - if (talisman.Protection != null && talisman.Protection.Type != null) - { - Type type = talisman.Protection.Type; + if (from != null && Talisman is BaseTalisman talisman && talisman.Protection != null && talisman.Protection.Type != null) + { + Type type = talisman.Protection.Type; - if (type.IsInstanceOfType(from)) - amount = (int)(amount * (1 - (double)talisman.Protection.Amount / 100)); - } + if (type.IsInstanceOfType(from)) + amount = (int)(amount * (1 - (double)talisman.Protection.Amount / 100)); + } - base.Damage(amount, from); + base.Damage(amount, from, informMount); } public override bool IsHarmfulCriminal(Mobile target) @@ -2358,32 +2291,23 @@ namespace Server.Mobiles } } - if (RecentlyReported == null) - RecentlyReported = new List(); + RecentlyReported ??= new List(); // Professions weren't verified on 1.0 RC0 if (!CharacterCreation.VerifyProfession(Profession)) Profession = 0; - if (PermaFlags == null) - PermaFlags = new List(); + PermaFlags ??= new List(); + JusticeProtectors ??= new List(); + BOBFilter ??= new BOBFilter(); - if (JusticeProtectors == null) - JusticeProtectors = new List(); - - if (BOBFilter == null) - BOBFilter = new BOBFilter(); - - if (m_GuildRank == null) - m_GuildRank = - RankDefinition - .Member; //Default to member if going from older version to new version (only time it should be null) + //Default to member if going from older version to new version (only time it should be null) + m_GuildRank ??= RankDefinition.Member; if (LastOnline == DateTime.MinValue && Account != null) LastOnline = ((Account)Account).LastLogin; - if (ChampionTitles == null) - ChampionTitles = new ChampionTitleInfo(); + ChampionTitles ??= new ChampionTitleInfo(); if (AccessLevel > AccessLevel.Player) m_IgnoreMobiles = true; @@ -2797,9 +2721,10 @@ namespace Server.Mobiles for (int i = AutoStabled.Count - 1; i >= 0; --i) { - BaseCreature pet = AutoStabled[i] as BaseCreature; + if (!(AutoStabled[i] is BaseCreature pet)) + return; - if (pet?.Deleted == true) + if (pet.Deleted) { pet.IsStabled = false; pet.StabledBy = null; @@ -2831,10 +2756,8 @@ namespace Server.Mobiles Stabled.Remove(pet); } else - { SendLocalizedMessage(1049612, pet.Name); // ~1_NAME~ remained in the stables because you have too many followers. - } } AutoStabled.Clear(); @@ -2902,7 +2825,7 @@ namespace Server.Mobiles public bool NinjaWepCooldown{ get; set; } - public List AllFollowers => m_AllFollowers ?? (m_AllFollowers = new List()); + public List AllFollowers => m_AllFollowers ??= new List(); public RankDefinition GuildRank { @@ -3083,14 +3006,14 @@ namespace Server.Mobiles if (!Core.SE || !Alive) return; - foreach (KeyValuePair kvp in RecoverableAmmo) - if (kvp.Value > 0) + foreach (var (key, value) in RecoverableAmmo) + if (value > 0) { Item ammo = null; try { - ammo = Activator.CreateInstance(kvp.Key) as Item; + ammo = Activator.CreateInstance(key) as Item; } catch { @@ -3100,7 +3023,7 @@ namespace Server.Mobiles if (ammo == null) continue; string name = ammo.Name; - ammo.Amount = kvp.Value; + ammo.Amount = value; if (name == null) { @@ -3180,39 +3103,21 @@ namespace Server.Mobiles [CommandProperty(AccessLevel.GameMaster)] public override int Str { - get - { - if (Core.ML && AccessLevel == AccessLevel.Player) - return Math.Min(base.Str, 150); - - return base.Str; - } + get => Core.ML && AccessLevel == AccessLevel.Player ? Math.Min(base.Str, 150) : base.Str; set => base.Str = value; } [CommandProperty(AccessLevel.GameMaster)] public override int Int { - get - { - if (Core.ML && AccessLevel == AccessLevel.Player) - return Math.Min(base.Int, 150); - - return base.Int; - } + get => Core.ML && AccessLevel == AccessLevel.Player ? Math.Min(base.Int, 150) : base.Int; set => base.Int = value; } [CommandProperty(AccessLevel.GameMaster)] public override int Dex { - get - { - if (Core.ML && AccessLevel == AccessLevel.Player) - return Math.Min(base.Dex, 150); - - return base.Dex; - } + get => Core.ML && AccessLevel == AccessLevel.Player ? Math.Min(base.Dex, 150) : base.Dex; set => base.Dex = value; } @@ -3231,36 +3136,16 @@ namespace Server.Mobiles SendLocalizedMessage(1060868); // Target the item you wish to toggle insurance status on to cancel } - private bool CanInsure(Item item) - { - if (item is Container && !(item is BaseQuiver) || item is BagOfSending || item is KeyRing || item is PotionKeg || - item is Sigil) - return false; - - if (item.Stackable) - return false; - - if (item.LootType == LootType.Cursed) - return false; - - if (item.ItemID == 0x204E) // death shroud - return false; - - if (item.Layer == Layer.Mount) - return false; - - if (item.LootType == LootType.Blessed || item.LootType == LootType.Newbied || item.BlessedFor == this) - return false; - - return true; - } + private bool CanInsure(Item item) => + (!(item is Container) || item is BaseQuiver) && !(item is BagOfSending) && !(item is KeyRing) && + !(item is PotionKeg) && !(item is Sigil) && !item.Stackable && item.LootType != LootType.Cursed && + item.ItemID != 0x204E && item.Layer != Layer.Mount && item.LootType != LootType.Blessed && + item.LootType != LootType.Newbied && item.BlessedFor != this; private void ToggleItemInsurance_Callback(Mobile from, object obj) { - if (!CheckAlive()) - return; - - ToggleItemInsurance_Callback(from, obj as Item, true); + if (CheckAlive()) + ToggleItemInsurance_Callback(from, obj as Item, true); } private void ToggleItemInsurance_Callback(Mobile from, Item item, bool target) @@ -3390,9 +3275,7 @@ namespace Server.Mobiles m_Player.AutoRenewInsurance = false; } else - { m_Player.SendLocalizedMessage(1042021); // Cancelled. - } if (m_InsuranceGump != null) m_Player.SendGump(m_InsuranceGump.NewInstance()); @@ -3404,11 +3287,7 @@ namespace Server.Mobiles if (!CheckAlive()) return; - List items = new List(); - - foreach (Item item in Items) - if (DisplayInItemInsuranceGump(item)) - items.Add(item); + List items = Items.Where(DisplayInItemInsuranceGump).ToList(); Container pack = Backpack; @@ -3479,11 +3358,7 @@ namespace Server.Mobiles AddHtmlLocalized(400, 54, 70, 20, 1114311, 0x7FFF); // Insured int balance = Banker.GetBalance(from); - int cost = 0; - - for (int i = 0; i < items.Length; ++i) - if (insure[i]) - cost += GetInsuranceCost(items[i]); + int cost = items.Where((t, i) => insure[i]).Sum(GetInsuranceCost); AddHtmlLocalized(15, 420, 300, 20, 1114310, 0x7FFF); // GOLD AVAILABLE: AddLabel(215, 420, 0x481, balance.ToString()); @@ -3702,20 +3577,12 @@ namespace Server.Mobiles private DateTime[] m_StuckMenuUses; - public bool CanUseStuckMenu() - { - if (m_StuckMenuUses == null) return true; - - for (int i = 0; i < m_StuckMenuUses.Length; ++i) - if (DateTime.UtcNow - m_StuckMenuUses[i] > TimeSpan.FromDays(1.0)) - return true; - - return false; - } + public bool CanUseStuckMenu() => + m_StuckMenuUses?.Any(t => DateTime.UtcNow - t > TimeSpan.FromDays(1.0)) != false; public void UsedStuckMenu() { - if (m_StuckMenuUses == null) m_StuckMenuUses = new DateTime[2]; + m_StuckMenuUses ??= new DateTime[2]; for (int i = 0; i < m_StuckMenuUses.Length; ++i) if (DateTime.UtcNow - m_StuckMenuUses[i] > TimeSpan.FromDays(1.0)) @@ -3779,10 +3646,7 @@ namespace Server.Mobiles m_DuelPlayer = value; - if (m_DuelPlayer == null) - DuelContext = null; - else - DuelContext = m_DuelPlayer.Participant.Context; + DuelContext = m_DuelPlayer?.Participant.Context; bool isInTourney = DuelContext?.Finished == false && DuelContext.m_Tournament != null; @@ -3945,22 +3809,14 @@ namespace Server.Mobiles private void DeltaEnemies(Type oldType, Type newType) { + NetState ns = NetState; + foreach (Mobile m in GetMobilesInRange(18)) { Type t = m.GetType(); if (t == oldType || t == newType) - { - NetState ns = NetState; - - if (ns != null) - { - if (ns.StygianAbyss) - ns.Send(new MobileMoving(m, Notoriety.Compute(this, m))); - else - ns.Send(new MobileMovingOld(m, Notoriety.Compute(this, m))); - } - } + Packets.SendMobileMoving(NetState, m, Notoriety.Compute(this, m)); } } @@ -4120,13 +3976,8 @@ namespace Server.Mobiles return base.ApplyNameSuffix(suffix); } - public override TimeSpan GetLogoutDelay() - { - if (Young || BedrollLogout || TestCenter.Enabled) - return TimeSpan.Zero; - - return base.GetLogoutDelay(); - } + public override TimeSpan GetLogoutDelay() => + Young || BedrollLogout || TestCenter.Enabled ? TimeSpan.Zero : base.GetLogoutDelay(); private DateTime m_LastYoungMessage = DateTime.MinValue; @@ -4167,7 +4018,7 @@ namespace Server.Mobiles return false; } - private static Point3D[] m_TrammelDeathDestinations = + private static readonly Point3D[] m_TrammelDeathDestinations = { new Point3D(1481, 1612, 20), new Point3D(2708, 2153, 0), @@ -4186,7 +4037,7 @@ namespace Server.Mobiles new Point3D(3665, 2587, 0) }; - private static Point3D[] m_IlshenarDeathDestinations = + private static readonly Point3D[] m_IlshenarDeathDestinations = { new Point3D(1216, 468, -13), new Point3D(723, 1367, -60), @@ -4199,13 +4050,13 @@ namespace Server.Mobiles new Point3D(1722, 219, 96) }; - private static Point3D[] m_MalasDeathDestinations = + private static readonly Point3D[] m_MalasDeathDestinations = { new Point3D(2079, 1376, -70), new Point3D(944, 519, -71) }; - private static Point3D[] m_TokunoDeathDestinations = + private static readonly Point3D[] m_TokunoDeathDestinations = { new Point3D(1166, 801, 27), new Point3D(782, 1228, 25), @@ -4285,9 +4136,7 @@ namespace Server.Mobiles { if (SpeechLog.Enabled && NetState != null) { - if (SpeechLog == null) - SpeechLog = new SpeechLog(); - + SpeechLog ??= new SpeechLog(); SpeechLog.Add(e.Mobile, e.Speech); } } @@ -4435,8 +4284,7 @@ namespace Server.Mobiles if (m_Values == null || index < 0 || index >= m_Values.Length) return 0; - if (m_Values[index] == null) - m_Values[index] = new TitleInfo(); + m_Values[index] ??= new TitleInfo(); return m_Values[index].Value; } @@ -4446,16 +4294,14 @@ namespace Server.Mobiles if (m_Values == null || index < 0 || index >= m_Values.Length) return DateTime.MinValue; - if (m_Values[index] == null) - m_Values[index] = new TitleInfo(); + m_Values[index] ??= new TitleInfo(); return m_Values[index].LastDecay; } public void SetValue(int index, int value) { - if (m_Values == null) - m_Values = new TitleInfo[ChampionSpawnInfo.Table.Length]; + m_Values ??= new TitleInfo[ChampionSpawnInfo.Table.Length]; if (value < 0) value = 0; @@ -4463,36 +4309,31 @@ namespace Server.Mobiles if (index < 0 || index >= m_Values.Length) return; - if (m_Values[index] == null) - m_Values[index] = new TitleInfo(); + m_Values[index] ??= new TitleInfo(); m_Values[index].Value = value; } public void Award(int index, int value) { - if (m_Values == null) - m_Values = new TitleInfo[ChampionSpawnInfo.Table.Length]; + m_Values ??= new TitleInfo[ChampionSpawnInfo.Table.Length]; if (index < 0 || index >= m_Values.Length || value <= 0) return; - if (m_Values[index] == null) - m_Values[index] = new TitleInfo(); + m_Values[index] ??= new TitleInfo(); m_Values[index].Value += value; } public void Atrophy(int index, int value) { - if (m_Values == null) - m_Values = new TitleInfo[ChampionSpawnInfo.Table.Length]; + m_Values ??= new TitleInfo[ChampionSpawnInfo.Table.Length]; if (index < 0 || index >= m_Values.Length || value <= 0) return; - if (m_Values[index] == null) - m_Values[index] = new TitleInfo(); + m_Values[index] ??= new TitleInfo(); int before = m_Values[index].Value; @@ -4518,9 +4359,7 @@ namespace Server.Mobiles for (int i = 0; i < length; i++) { - if (titles.m_Values[i] == null) - titles.m_Values[i] = new TitleInfo(); - + titles.m_Values[i] ??= new TitleInfo(); TitleInfo.Serialize(writer, titles.m_Values[i]); } } @@ -4531,8 +4370,7 @@ namespace Server.Mobiles if (t == null) return; - if (t.m_Values == null) - t.m_Values = new TitleInfo[ChampionSpawnInfo.Table.Length]; + t.m_Values ??= new TitleInfo[ChampionSpawnInfo.Table.Length]; for (int i = 0; i < t.m_Values.Length; i++) if (t.GetLastDecay(i) + LossDelay < DateTime.UtcNow) @@ -4546,16 +4384,8 @@ namespace Server.Mobiles if (t == null) return; - if (t.m_Values == null) - t.m_Values = new TitleInfo[ChampionSpawnInfo.Table.Length]; - - int count = 1; - - for (int i = 0; i < t.m_Values.Length; i++) - if (t.m_Values[i].Value > 900) - count++; - - t.Harrower = Math.Max(count, t.Harrower); //Harrower titles never decay. + t.m_Values ??= new TitleInfo[ChampionSpawnInfo.Table.Length]; + t.Harrower = Math.Max(1 + t.m_Values.Count(t1 => t1.Value > 900), t.Harrower); //Harrower titles never decay. } private class TitleInfo @@ -4611,9 +4441,7 @@ namespace Server.Mobiles public virtual void AcquireRecipe(int recipeID) { - if (m_AcquiredRecipes == null) - m_AcquiredRecipes = new Dictionary(); - + m_AcquiredRecipes ??= new Dictionary(); m_AcquiredRecipes[recipeID] = true; } @@ -4631,12 +4459,11 @@ namespace Server.Mobiles public void ResendBuffs() { - if (!BuffInfo.Enabled || m_BuffTable == null) + if (!BuffInfo.Enabled || m_BuffTable == null || NetState?.BuffIcon != true) return; - if (NetState?.BuffIcon == true) - foreach (BuffInfo info in m_BuffTable.Values) - NetState.Send(new AddBuffPacket(this, info)); + foreach (BuffInfo info in m_BuffTable.Values) + BuffPackets.SendAddBuff(this, info); } private Dictionary m_BuffTable; @@ -4654,7 +4481,7 @@ namespace Server.Mobiles m_BuffTable.Add(b.ID, b); if (NetState?.BuffIcon == true) - NetState.Send(new AddBuffPacket(this, b)); + BuffPackets.SendAddBuff(this, b); } public void RemoveBuff(BuffInfo b) @@ -4678,7 +4505,7 @@ namespace Server.Mobiles m_BuffTable.Remove(b); if (NetState?.BuffIcon == true) - NetState.Send(new RemoveBuffPacket(this, b)); + BuffPackets.SendRemoveBuffPacket(NetState, Serial, (int)b); if (m_BuffTable.Count <= 0) m_BuffTable = null; diff --git a/Projects/Scripts/Mobiles/Special/ChaosGuard.cs b/Projects/Scripts/Mobiles/Special/ChaosGuard.cs index a7ad50117..0c96e9297 100644 --- a/Projects/Scripts/Mobiles/Special/ChaosGuard.cs +++ b/Projects/Scripts/Mobiles/Special/ChaosGuard.cs @@ -1,4 +1,3 @@ -using Server.Guilds; using Server.Items; namespace Server.Mobiles diff --git a/Projects/Scripts/Mobiles/Special/Harrower.cs b/Projects/Scripts/Mobiles/Special/Harrower.cs index 59a0bf1a7..863ed402c 100644 --- a/Projects/Scripts/Mobiles/Special/Harrower.cs +++ b/Projects/Scripts/Mobiles/Special/Harrower.cs @@ -398,24 +398,24 @@ namespace Server.Mobiles Dictionary validEntries = new Dictionary(); - foreach (KeyValuePair kvp in m_DamageEntries) - if (IsEligible(kvp.Key, artifact)) + foreach (var (key, value) in m_DamageEntries) + if (IsEligible(key, artifact)) { - validEntries.Add(kvp.Key, kvp.Value); - totalDamage += kvp.Value; + validEntries.Add(key, value); + totalDamage += value; } int randomDamage = Utility.RandomMinMax(1, totalDamage); totalDamage = 0; - foreach (KeyValuePair kvp in validEntries) + foreach (var (key, value) in validEntries) { - totalDamage += kvp.Value; + totalDamage += value; if (totalDamage >= randomDamage) { - GiveArtifact(kvp.Key, artifact); + GiveArtifact(key, artifact); return; } } diff --git a/Projects/Scripts/Mobiles/Special/Mephitis.cs b/Projects/Scripts/Mobiles/Special/Mephitis.cs index 2c80b0802..13fb0d633 100644 --- a/Projects/Scripts/Mobiles/Special/Mephitis.cs +++ b/Projects/Scripts/Mobiles/Special/Mephitis.cs @@ -68,12 +68,7 @@ namespace Server.Mobiles AddLoot(LootPack.UltraRich, 4); } - public override void OnGotMeleeAttack(Mobile attacker) - { - base.OnGotMeleeAttack(attacker); - - // TODO: Web ability - } + // TODO: Web Ability public override void Serialize(GenericWriter writer) { @@ -89,4 +84,4 @@ namespace Server.Mobiles int version = reader.ReadInt(); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Mobiles/Special/OrderGuard.cs b/Projects/Scripts/Mobiles/Special/OrderGuard.cs index e3db5a597..b46e23ce0 100644 --- a/Projects/Scripts/Mobiles/Special/OrderGuard.cs +++ b/Projects/Scripts/Mobiles/Special/OrderGuard.cs @@ -1,4 +1,3 @@ -using Server.Guilds; using Server.Items; namespace Server.Mobiles diff --git a/Projects/Scripts/Mobiles/Special/Semidar.cs b/Projects/Scripts/Mobiles/Special/Semidar.cs index 4f01a0747..c4f6dc568 100644 --- a/Projects/Scripts/Mobiles/Special/Semidar.cs +++ b/Projects/Scripts/Mobiles/Special/Semidar.cs @@ -71,8 +71,7 @@ namespace Server.Mobiles public override void CheckReflect(Mobile caster, ref bool reflect) { - if (caster.Body.IsMale) - reflect = true; // Always reflect if caster isn't female + reflect |= caster.Body.IsMale; // Always reflect if caster isn't female } public override void AlterDamageScalarFrom(Mobile caster, ref double scalar) diff --git a/Projects/Scripts/Mobiles/Townfolk/Banker.cs b/Projects/Scripts/Mobiles/Townfolk/Banker.cs index 1d7d3c6f8..84daa5cd0 100644 --- a/Projects/Scripts/Mobiles/Townfolk/Banker.cs +++ b/Projects/Scripts/Mobiles/Townfolk/Banker.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using Server.Accounting; using Server.ContextMenus; using Server.Items; using Server.Network; @@ -284,22 +283,16 @@ namespace Server.Mobiles break; if (!Core.ML && amount > 5000 || Core.ML && amount > 60000) - { Say(500381); // Thou canst not withdraw so much at one time! - } else if (pack?.Deleted != false || !(pack.TotalWeight < pack.MaxWeight) || !(pack.TotalItems < pack.MaxItems)) - { Say(1048147); // Your backpack can't hold anything else. - } else if (amount > 0) { BankBox box = e.Mobile.FindBankNoCreate(); if (box == null || !Withdraw(e.Mobile, amount)) - { Say(500384); // Ah, art thou trying to fool me? Thou hast not so much gold! - } else { pack.DropItem(new Gold(amount)); @@ -365,13 +358,9 @@ namespace Server.Mobiles break; if (amount < 5000) - { Say(1010006); // We cannot create checks for such a paltry amount of gold! - } else if (amount > 1000000) - { Say(1010007); // Our policies prevent us from creating checks worth that much! - } else { BankCheck check = new BankCheck(amount); diff --git a/Projects/Scripts/Mobiles/Townfolk/BrideGroom.cs b/Projects/Scripts/Mobiles/Townfolk/BrideGroom.cs index 027273089..40f372cd4 100644 --- a/Projects/Scripts/Mobiles/Townfolk/BrideGroom.cs +++ b/Projects/Scripts/Mobiles/Townfolk/BrideGroom.cs @@ -50,10 +50,7 @@ namespace Server.Mobiles else AddItem(new Boots(lowHue)); - if (Utility.RandomBool()) - HairItemID = 0x203B; - else - HairItemID = 0x203C; + HairItemID = Utility.RandomBool() ? 0x203B : 0x203C; HairHue = Race.RandomHairHue(); @@ -74,4 +71,4 @@ namespace Server.Mobiles int version = reader.ReadInt(); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Mobiles/Townfolk/EscortableMage.cs b/Projects/Scripts/Mobiles/Townfolk/EscortableMage.cs index b97d80c54..624dea558 100644 --- a/Projects/Scripts/Mobiles/Townfolk/EscortableMage.cs +++ b/Projects/Scripts/Mobiles/Townfolk/EscortableMage.cs @@ -68,4 +68,4 @@ namespace Server.Mobiles int version = reader.ReadInt(); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Mobiles/Townfolk/Merchant.cs b/Projects/Scripts/Mobiles/Townfolk/Merchant.cs index e80c8faa6..159f6557c 100644 --- a/Projects/Scripts/Mobiles/Townfolk/Merchant.cs +++ b/Projects/Scripts/Mobiles/Townfolk/Merchant.cs @@ -77,4 +77,4 @@ namespace Server.Mobiles int version = reader.ReadInt(); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Mobiles/Townfolk/Messenger.cs b/Projects/Scripts/Mobiles/Townfolk/Messenger.cs index 69a8e6908..5c909af23 100644 --- a/Projects/Scripts/Mobiles/Townfolk/Messenger.cs +++ b/Projects/Scripts/Mobiles/Townfolk/Messenger.cs @@ -66,4 +66,4 @@ namespace Server.Mobiles int version = reader.ReadInt(); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Mobiles/Townfolk/Noble.cs b/Projects/Scripts/Mobiles/Townfolk/Noble.cs index 994996a55..b603bc051 100644 --- a/Projects/Scripts/Mobiles/Townfolk/Noble.cs +++ b/Projects/Scripts/Mobiles/Townfolk/Noble.cs @@ -78,4 +78,4 @@ namespace Server.Mobiles int version = reader.ReadInt(); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Mobiles/Townfolk/Peasant.cs b/Projects/Scripts/Mobiles/Townfolk/Peasant.cs index 61619ac87..4658c9c01 100644 --- a/Projects/Scripts/Mobiles/Townfolk/Peasant.cs +++ b/Projects/Scripts/Mobiles/Townfolk/Peasant.cs @@ -71,4 +71,4 @@ namespace Server.Mobiles int version = reader.ReadInt(); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Mobiles/Townfolk/SeekerOfAdventure.cs b/Projects/Scripts/Mobiles/Townfolk/SeekerOfAdventure.cs index 2d34b17a7..a8da80d46 100644 --- a/Projects/Scripts/Mobiles/Townfolk/SeekerOfAdventure.cs +++ b/Projects/Scripts/Mobiles/Townfolk/SeekerOfAdventure.cs @@ -26,12 +26,7 @@ namespace Server.Mobiles public override bool ClickTitle => false; // Do not display 'the seeker of adventure' when single-clicking - public override string[] GetPossibleDestinations() - { - if (Core.ML) - return m_MLDestinations; - return m_Dungeons; - } + public override string[] GetPossibleDestinations() => Core.ML ? m_MLDestinations : m_Dungeons; private static int GetRandomHue() { @@ -89,4 +84,4 @@ namespace Server.Mobiles int version = reader.ReadInt(); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Mobiles/Townfolk/TownCrier.cs b/Projects/Scripts/Mobiles/Townfolk/TownCrier.cs index b151f5da7..41f9c7a1c 100644 --- a/Projects/Scripts/Mobiles/Townfolk/TownCrier.cs +++ b/Projects/Scripts/Mobiles/Townfolk/TownCrier.cs @@ -4,7 +4,6 @@ using System.Text; using Server.Gumps; using Server.Items; using Server.Network; -using Server.Prompts; namespace Server.Mobiles { @@ -20,7 +19,7 @@ namespace Server.Mobiles { private static GlobalTownCrierEntryList m_Instance; - public static GlobalTownCrierEntryList Instance => m_Instance ?? (m_Instance = new GlobalTownCrierEntryList()); + public static GlobalTownCrierEntryList Instance => m_Instance ??= new GlobalTownCrierEntryList(); public bool IsEmpty => Entries == null || Entries.Count == 0; @@ -50,8 +49,7 @@ namespace Server.Mobiles public TownCrierEntry AddEntry(string[] lines, TimeSpan duration) { - if (Entries == null) - Entries = new List(); + Entries ??= new List(); TownCrierEntry tce = new TownCrierEntry(lines, duration); @@ -384,8 +382,7 @@ namespace Server.Mobiles public TownCrierEntry AddEntry(string[] lines, TimeSpan duration) { - if (Entries == null) - Entries = new List(); + Entries ??= new List(); TownCrierEntry tce = new TownCrierEntry(lines, duration); diff --git a/Projects/Scripts/Mobiles/Vendors/BaseVendor.cs b/Projects/Scripts/Mobiles/Vendors/BaseVendor.cs index 639565a01..ec3c64456 100644 --- a/Projects/Scripts/Mobiles/Vendors/BaseVendor.cs +++ b/Projects/Scripts/Mobiles/Vendors/BaseVendor.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Server.ContextMenus; using Server.Engines.BulkOrders; using Server.Factions; @@ -24,10 +25,10 @@ namespace Server.Mobiles { private const int MaxSell = 500; - private static TimeSpan InventoryDecayTime = TimeSpan.FromHours(1.0); + private static readonly TimeSpan InventoryDecayTime = TimeSpan.FromHours(1.0); - private List m_ArmorBuyInfo = new List(); - private List m_ArmorSellInfo = new List(); + private readonly List m_ArmorBuyInfo = new List(); + private readonly List m_ArmorSellInfo = new List(); public BaseVendor(string title = null) : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2) @@ -125,7 +126,6 @@ namespace Server.Mobiles IShopSellInfo[] info = GetSellInfo(); int totalCost = 0; List validBuy = new List(list.Count); - bool bought; bool fromBank = false; bool fullPurchase = true; int controlSlots = buyer.FollowersMax - buyer.Followers; @@ -188,7 +188,7 @@ namespace Server.Mobiles if (validBuy.Count == 0) return false; - bought = buyer.AccessLevel >= AccessLevel.GameMaster; + bool bought = buyer.AccessLevel >= AccessLevel.GameMaster; Container cont = buyer.Backpack; if (!bought && cont != null) @@ -259,8 +259,9 @@ namespace Server.Mobiles if (cont?.TryDropItem(buyer, buyItem, false) != true) buyItem.MoveToWorld(buyer.Location, buyer.Map); - break; - } + if (cont?.TryDropItem(buyer, buyItem, false) != true) + buyItem.MoveToWorld(buyer.Location, buyer.Map); + } } } else if (ser.IsMobile) @@ -309,10 +310,7 @@ namespace Server.Mobiles public virtual bool OnSellItems(Mobile seller, List list) { - if (!IsActiveBuyer) - return false; - - if (!seller.CheckAlive()) + if (!(IsActiveBuyer && seller.CheckAlive())) return false; if (!CheckVendorAccess(seller)) @@ -334,12 +332,7 @@ namespace Server.Mobiles !resp.Item.Movable || resp.Item is Container container && container.Items.Count != 0) continue; - foreach (IShopSellInfo ssi in info) - if (ssi.IsSellable(resp.Item)) - { - Sold++; - break; - } + if (info.Any(ssi => ssi.IsSellable(resp.Item))) Sold++; } if (Sold > MaxSell) @@ -368,14 +361,11 @@ namespace Server.Mobiles { bool found = false; - foreach (IBuyItemInfo bii in buyInfo) - if (bii.Restock(resp.Item, amount)) - { - resp.Item.Consume(amount); - found = true; - - break; - } + if (buyInfo.Any(bii => bii.Restock(resp.Item, amount))) + { + resp.Item.Consume(amount); + found = true; + } if (!found) { @@ -522,11 +512,9 @@ namespace Server.Mobiles if (CheckGargoyle()) return; - if (CheckNecromancer()) - return; + public virtual int GetShoeHue() => 0.1 > Utility.RandomDouble() ? 0 : Utility.RandomNeutralHue(); - CheckTokuno(); - } + public virtual bool CheckMorph() => CheckGargoyle() || CheckNecromancer() || CheckTokuno(); public virtual bool CheckTokuno() { @@ -548,12 +536,7 @@ namespace Server.Mobiles public virtual bool CheckGargoyle() { - Map map = Map; - - if (map != Map.Ilshenar) - return false; - - if (!Region.IsPartOf("Gargoyle City")) + if (!(Map == Map.Ilshenar && Region.IsPartOf("Gargoyle City"))) return false; if (Body != 0x2F6 || (Hue & 0x8000) == 0) @@ -564,12 +547,7 @@ namespace Server.Mobiles public virtual bool CheckNecromancer() { - Map map = Map; - - if (map != Map.Malas) - return false; - - if (!Region.IsPartOf("Umbra")) + if (!(Map == Map.Malas && Region.IsPartOf("Umbra"))) return false; if (Hue != 0x83E8) @@ -639,12 +617,10 @@ namespace Server.Mobiles public virtual void CapitalizeTitle() { - string title = Title; - - if (title == null) + if (Title == null) return; - string[] split = title.Split(' '); + string[] split = Title.Split(' '); for (int i = 0; i < split.Length; ++i) { @@ -730,10 +706,7 @@ namespace Server.Mobiles public virtual void VendorBuy(Mobile from) { - if (!IsActiveSeller) - return; - - if (!from.CheckAlive()) + if (!(IsActiveSeller && from.CheckAlive())) return; if (!CheckVendorAccess(from)) @@ -824,25 +797,13 @@ namespace Server.Mobiles NetState ns = from.NetState; - if (ns == null) - return; - - if (ns.ContainerGridLines) - from.Send(new VendorBuyContent6017(list)); - else - from.Send(new VendorBuyContent(list)); - - from.Send(new VendorBuyList(this, list)); - - if (ns.HighSeas) - from.Send(new DisplayBuyListHS(this)); - else - from.Send(new DisplayBuyList(this)); - - from.Send(new MobileStatusExtended(from)); //make sure their gold amount is sent + Packets.SendVendorBuyContent(ns, list); + Packets.SendVendorBuyList(ns, this, list); + Packets.SendDisplayBuyList(ns, this.Serial); + Packets.SendMobileStatusExtended(ns, from); //make sure their gold amount is sent for (int i = 0; i < opls.Count; ++i) - from.Send(opls[i]); + opls[i].Send(ns); SayTo(from, 500186); // Greetings. Have a look around. } @@ -857,12 +818,14 @@ namespace Server.Mobiles AddItem(pack); } - from.Send(new EquipUpdate(pack)); + NetState ns = from.NetState; + + Packets.SendEquipUpdate(ns, pack); pack = FindItemOnLayer(Layer.ShopSell); if (pack != null) - from.Send(new EquipUpdate(pack)); + Packets.SendEquipUpdate(ns, pack); pack = FindItemOnLayer(Layer.ShopResale); @@ -872,15 +835,12 @@ namespace Server.Mobiles AddItem(pack); } - from.Send(new EquipUpdate(pack)); + Packets.SendEquipUpdate(ns, pack); } public virtual void VendorSell(Mobile from) { - if (!IsActiveBuyer) - return; - - if (!from.CheckAlive()) + if (!(IsActiveBuyer && from.CheckAlive())) return; if (!CheckVendorAccess(from)) @@ -911,13 +871,10 @@ namespace Server.Mobiles if (list.Count > 0) { SendPacksTo(from); - - from.Send(new VendorSellList(this, list)); + Packets.SendVendorSellList(from.NetState, Serial, list); } else - { Say(true, "You have nothing I would be interested in."); - } } public override bool OnDragDrop(Mobile from, Item dropped) @@ -992,7 +949,7 @@ namespace Server.Mobiles return null; } - private void ProcessSinglePurchase(BuyItemResponse buy, IBuyItemInfo bii, List validBuy, + private void ProcessSinglePurchase(BuyItemResponse buy, IBuyItemInfo bii, ICollection validBuy, ref int controlSlots, ref bool fullPurchase, ref int totalCost) { int amount = buy.Amount; @@ -1006,9 +963,7 @@ namespace Server.Mobiles int slots = bii.ControlSlots * amount; if (controlSlots >= slots) - { controlSlots -= slots; - } else { fullPurchase = false; @@ -1185,10 +1140,9 @@ namespace Server.Mobiles } } - if (IsParagon) - IsParagon = false; + IsParagon = false; - Timer.DelayCall(TimeSpan.Zero, CheckMorph); + Timer.DelayCall(TimeSpan.Zero, () => CheckMorph()); } public override void AddCustomContextEntries(Mobile from, List list) @@ -1288,8 +1242,7 @@ namespace Server.ContextMenus { private BaseVendor m_Vendor; - public VendorBuyEntry(Mobile from, BaseVendor vendor) - : base(6103, 8) + public VendorBuyEntry(Mobile from, BaseVendor vendor) : base(6103, 8) { m_Vendor = vendor; Enabled = vendor.CheckVendorAccess(from); @@ -1305,8 +1258,7 @@ namespace Server.ContextMenus { private BaseVendor m_Vendor; - public VendorSellEntry(Mobile from, BaseVendor vendor) - : base(6104, 8) + public VendorSellEntry(Mobile from, BaseVendor vendor) : base(6104, 8) { m_Vendor = vendor; Enabled = vendor.CheckVendorAccess(from); diff --git a/Projects/Scripts/Mobiles/Vendors/NPC/AnimalTrainer.cs b/Projects/Scripts/Mobiles/Vendors/NPC/AnimalTrainer.cs index 535d1cb4e..a909923b7 100644 --- a/Projects/Scripts/Mobiles/Vendors/NPC/AnimalTrainer.cs +++ b/Projects/Scripts/Mobiles/Vendors/NPC/AnimalTrainer.cs @@ -84,10 +84,7 @@ namespace Server.Mobiles return max; } - private void CloseClaimList(Mobile from) - { - from.CloseGump(); - } + private void CloseClaimList(Mobile from) => from.CloseGump(); public void BeginClaimList(Mobile from) { @@ -141,9 +138,7 @@ namespace Server.Mobiles (from as PlayerMobile)?.AutoStabled.Remove(pet); } else - { SayTo(from, 1049612, pet.Name); // ~1_NAME~ remained in the stables because you have too many followers. - } } public void BeginStable(Mobile from) @@ -176,43 +171,25 @@ namespace Server.Mobiles return; if (pet.Body.IsHuman) - { SayTo(from, 502672); // HA HA HA! Sorry, I am not an inn. - } else if (!pet.Controlled) - { SayTo(from, 1048053); // You can't stable that! - } else if (pet.ControlMaster != from) - { SayTo(from, 1042562); // You do not own that pet! - } else if (pet.IsDeadPet) - { SayTo(from, 1049668); // Living pets only, please. - } else if (pet.Summoned) - { SayTo(from, 502673); // I can not stable summoned creatures. - } -/* - else if ( pet.Allured ) - { - SayTo( from, 1048053 ); // You can't stable that! - } -*/ + /*else if ( pet.Allured ) + { + SayTo( from, 1048053 ); // You can't stable that! + }*/ else if ((pet is PackLlama || pet is PackHorse || pet is Beetle) && pet.Backpack?.Items.Count > 0) - { SayTo(from, 1042563); // You need to unload your pet. - } else if (pet.Combatant != null && pet.InRange(pet.Combatant, 12) && pet.Map == pet.Combatant.Map) - { SayTo(from, 1042564); // I'm sorry. Your pet seems to be busy. - } else if (from.Stabled.Count >= GetMaxStabled(from)) - { SayTo(from, 1042565); // You have too many pets in the stables! - } else { Container bank = from.FindBankNoCreate(); @@ -241,9 +218,7 @@ namespace Server.Mobiles : 502679); // [AOS: Your pet has been stabled.] Very well, thy pet is stabled. Thou mayst recover it by saying 'claim' to me. In one real world week, I shall sell it off if it is not claimed! } else - { SayTo(from, 502677); // But thou hast not the funds in thy bank account! - } } } @@ -263,8 +238,11 @@ namespace Server.Mobiles if (pet?.Deleted != false) { - pet.IsStabled = false; - pet.StabledBy = null; + if (pet != null) + { + pet.IsStabled = false; + pet.StabledBy = null; + } from.Stabled.RemoveAt(i); --i; continue; @@ -303,7 +281,7 @@ namespace Server.Mobiles public bool CanClaim(Mobile from, BaseCreature pet) => from.Followers + pet.ControlSlots <= from.FollowersMax; - private void DoClaim(Mobile from, BaseCreature pet) + private static void DoClaim(Mobile from, BaseCreature pet) { pet.SetControlMaster(from); diff --git a/Projects/Scripts/Mobiles/Vendors/NPC/Guildmasters/BaseGuildmaster.cs b/Projects/Scripts/Mobiles/Vendors/NPC/Guildmasters/BaseGuildmaster.cs index de015a30a..eab2fecb4 100644 --- a/Projects/Scripts/Mobiles/Vendors/NPC/Guildmasters/BaseGuildmaster.cs +++ b/Projects/Scripts/Mobiles/Vendors/NPC/Guildmasters/BaseGuildmaster.cs @@ -44,24 +44,13 @@ namespace Server.Mobiles public virtual void SayPriceTo(Mobile m) { - m.Send(new MessageLocalizedAffix(Serial, Body, MessageType.Regular, SpeechHue, 3, 1008052, Name, - AffixType.Append, JoinCost.ToString(), "")); + Packets.SendMessageLocalizedAffix(m.NetState, Serial, Body, MessageType.Regular, SpeechHue, 3, 1008052, Name, + AffixType.Append, JoinCost.ToString()); } - public virtual bool WasNamed(string speech) - { - string name = Name; + public virtual bool WasNamed(string speech) => Name != null && Insensitive.StartsWith(speech, Name); - return name != null && Insensitive.StartsWith(speech, name); - } - - public override bool HandlesOnSpeech(Mobile from) - { - if (from.InRange(Location, 2)) - return true; - - return base.HandlesOnSpeech(from); - } + public override bool HandlesOnSpeech(Mobile from) => from.InRange(Location, 2) || base.HandlesOnSpeech(from); public override void OnSpeech(SpeechEventArgs e) { @@ -85,14 +74,10 @@ namespace Server.Mobiles else if (e.HasKeyword(0x0005)) // *resign* | *quit* { if (pm.NpcGuild != NpcGuild) - { SayTo(pm, 501052); // Thou dost not belong to my guild! - } else if (pm.NpcGuildJoinTime + QuitAge > DateTime.UtcNow || pm.NpcGuildGameTime + QuitGameAge > pm.GameTime) - { SayTo(pm, 501053); // You just joined my guild! You must wait a week to resign. - } else { SayTo(pm, 501054); // I accept thy resignation. @@ -111,17 +96,11 @@ namespace Server.Mobiles if (from is PlayerMobile pm && dropped.Amount == JoinCost) { if (pm.NpcGuild == NpcGuild) - { SayTo(pm, 501047); // Thou art already a member of our guild. - } else if (pm.NpcGuild != NpcGuild.None) - { SayTo(pm, 501046); // Thou must resign from thy other guild first. - } else if (pm.GameTime < JoinGameAge || pm.CreationTime + JoinAge > DateTime.UtcNow) - { SayTo(pm, 501048); // You are too young to join my guild... - } else if (CheckCustomReqs(pm)) { SayWelcomeTo(pm); @@ -154,4 +133,4 @@ namespace Server.Mobiles int version = reader.ReadInt(); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Mobiles/Vendors/PlayerBarkeeper.cs b/Projects/Scripts/Mobiles/Vendors/PlayerBarkeeper.cs index a11537460..f808e3a21 100644 --- a/Projects/Scripts/Mobiles/Vendors/PlayerBarkeeper.cs +++ b/Projects/Scripts/Mobiles/Vendors/PlayerBarkeeper.cs @@ -5,7 +5,6 @@ using Server.Gumps; using Server.Items; using Server.Multis; using Server.Network; -using Server.Prompts; namespace Server.Mobiles { @@ -969,7 +968,7 @@ namespace Server.Mobiles AddItem(580, 44, 4033); } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (!m_Barkeeper.IsOwner(m_From)) return; diff --git a/Projects/Scripts/Mobiles/Vendors/PlayerVendor.cs b/Projects/Scripts/Mobiles/Vendors/PlayerVendor.cs index a3f4e850d..41d7dd9d8 100644 --- a/Projects/Scripts/Mobiles/Vendors/PlayerVendor.cs +++ b/Projects/Scripts/Mobiles/Vendors/PlayerVendor.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.Linq; using Server.ContextMenus; using Server.Engines.BulkOrders; using Server.Ethics; @@ -8,7 +9,6 @@ using Server.Gumps; using Server.Items; using Server.Misc; using Server.Multis; -using Server.Prompts; using Server.Targeting; namespace Server.Mobiles @@ -326,11 +326,7 @@ namespace Server.Mobiles { if (BaseHouse.NewVendorSystem) return ChargePerRealWorldDay / 12; - long total = 0; - foreach (VendorItem vi in m_SellItems.Values) - total += vi.Price; - - total -= 500; + long total = m_SellItems.Values.Aggregate(0, (current, vi) => current + vi.Price) - 500; if (total < 0) total = 0; @@ -345,9 +341,7 @@ namespace Server.Mobiles { if (BaseHouse.NewVendorSystem) { - long total = 0; - foreach (VendorItem vi in m_SellItems.Values) - total += vi.Price; + long total = m_SellItems.Values.Aggregate(0, (current, vi) => current + vi.Price); return (int)(60 + total / 500 * 3); } @@ -544,11 +538,7 @@ namespace Server.Mobiles protected List GetItems() { - List list = new List(); - - foreach (Item item in Items) - if (item.Movable && item != Backpack && item.Layer != Layer.Hair && item.Layer != Layer.FacialHair) - list.Add(item); + List list = Items.Where(item => item.Movable && item != Backpack && item.Layer != Layer.Hair && item.Layer != Layer.FacialHair).ToList(); if (Backpack != null) list.AddRange(Backpack.Items); @@ -584,18 +574,17 @@ namespace Server.Mobiles { if (House.IsOwner(Owner)) // Move to moving crate { - if (House.MovingCrate == null) - House.MovingCrate = new MovingCrate(House); + House.MovingCrate ??= new MovingCrate(House); if (HoldGold > 0) Banker.Deposit(House.MovingCrate, HoldGold); - foreach (Item item in list) House.MovingCrate.DropItem(item); + foreach (Item item in list) + House.MovingCrate.DropItem(item); } else // Move to vendor inventory { - VendorInventory inventory = new VendorInventory(House, Owner, Name, ShopName); - inventory.Gold = HoldGold; + VendorInventory inventory = new VendorInventory(House, Owner, Name, ShopName) {Gold = HoldGold}; foreach (Item item in list) inventory.AddItem(item); diff --git a/Projects/Scripts/Mobiles/Vendors/RentedVendor.cs b/Projects/Scripts/Mobiles/Vendors/RentedVendor.cs index 618076cfa..9d73296d1 100644 --- a/Projects/Scripts/Mobiles/Vendors/RentedVendor.cs +++ b/Projects/Scripts/Mobiles/Vendors/RentedVendor.cs @@ -4,7 +4,6 @@ using Server.ContextMenus; using Server.Gumps; using Server.Misc; using Server.Multis; -using Server.Prompts; namespace Server.Mobiles { @@ -129,8 +128,7 @@ namespace Server.Mobiles { if (RentalGold > 0 && House?.IsAosRules == true) { - if (House.MovingCrate == null) - House.MovingCrate = new MovingCrate(House); + House.MovingCrate ??= new MovingCrate(House); Banker.Deposit(House.MovingCrate, RentalGold); RentalGold = 0; diff --git a/Projects/Scripts/Mobiles/Vendors/VendorInventory.cs b/Projects/Scripts/Mobiles/Vendors/VendorInventory.cs index ad3104ae5..7b9323a6c 100644 --- a/Projects/Scripts/Mobiles/Vendors/VendorInventory.cs +++ b/Projects/Scripts/Mobiles/Vendors/VendorInventory.cs @@ -116,8 +116,7 @@ namespace Server.Mobiles { if (m_Inventory.Gold > 0) { - if (house.MovingCrate == null) - house.MovingCrate = new MovingCrate(house); + house.MovingCrate ??= new MovingCrate(house); Banker.Deposit(house.MovingCrate, m_Inventory.Gold); } @@ -134,4 +133,4 @@ namespace Server.Mobiles } } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Multis/Boats/BaseBoat.cs b/Projects/Scripts/Multis/Boats/BaseBoat.cs index b16405417..1d93e625e 100644 --- a/Projects/Scripts/Multis/Boats/BaseBoat.cs +++ b/Projects/Scripts/Multis/Boats/BaseBoat.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.IO; using System.Linq; using Server.Items; using Server.Network; @@ -259,7 +258,7 @@ namespace Server.Multis } int xOffset = 0, yOffset = 0; - Movement.Movement.Offset(m_Facing, ref xOffset, ref yOffset); + Movement.Offset(m_Facing, ref xOffset, ref yOffset); if (TillerMan != null) { @@ -1458,11 +1457,10 @@ namespace Server.Multis else { List toMove = GetMovingEntities(); - - SafeAdd(TillerMan, toMove); - SafeAdd(Hold, toMove); - SafeAdd(PPlank, toMove); - SafeAdd(SPlank, toMove); + if (TillerMan != null) toMove.Add(TillerMan); + if (Hold != null) toMove.Add(Hold); + if (PPlank != null) toMove.Add(PPlank); + if (SPlank != null) toMove.Add(SPlank); // Packet must be sent before actual locations are changed foreach (NetState ns in Map.GetClientsInRange(Location, GetMaxUpdateRange())) @@ -1470,7 +1468,7 @@ namespace Server.Multis Mobile m = ns.Mobile; if (ns.HighSeas && m.CanSee(this) && m.InRange(Location, GetUpdateRange(m))) - ns.Send(new MoveBoatHS(m, this, d, clientSpeed, toMove, xOffset, yOffset)); + BoatPackets.SendMoveBoatHS(ns, m, this, d, clientSpeed, toMove, xOffset, yOffset); } foreach (IEntity e in toMove) @@ -1502,12 +1500,6 @@ namespace Server.Multis return true; } - private static void SafeAdd(Item item, List toMove) - { - if (item != null) - toMove.Add(item); - } - public void Teleport(int xOffset, int yOffset, int zOffset) { List toMove = GetMovingEntities(); @@ -1534,9 +1526,9 @@ namespace Server.Multis return list; MultiComponentList mcl = Components; + IPooledEnumerable eable = map.GetObjectsInBounds(new Rectangle2D(X + mcl.Min.X, Y + mcl.Min.Y, mcl.Width, mcl.Height)); - foreach (IEntity o in map.GetObjectsInBounds(new Rectangle2D(X + mcl.Min.X, Y + mcl.Min.Y, mcl.Width, mcl.Height)) - ) + foreach (IEntity o in eable) { if (o == this || o is TillerMan || o is Hold || o is Plank) continue; @@ -1553,6 +1545,8 @@ namespace Server.Multis } } + eable.Free(); + return list; } @@ -1595,11 +1589,11 @@ namespace Server.Multis List toMove = GetMovingEntities(); - toMove.Add(PPlank); - toMove.Add(SPlank); + if (PPlank != null) toMove.Add(PPlank); + if (SPlank != null) toMove.Add(SPlank); int xOffset = 0, yOffset = 0; - Movement.Movement.Offset(facing, ref xOffset, ref yOffset); + Movement.Offset(facing, ref xOffset, ref yOffset); if (TillerMan != null) TillerMan.Location = new Point3D(X + xOffset * TillerManDistance + (facing == Direction.North ? 1 : 0), @@ -1616,9 +1610,7 @@ namespace Server.Multis IEntity e = toMove[i]; if (e is Item item) - { item.Location = Rotate(item.Location, count); - } else if (e is Mobile m) { m.Direction = m.Direction - old + facing & Direction.Mask; @@ -1734,8 +1726,6 @@ namespace Server.Multis } } - #region High Seas - public override bool AllowsRelativeDrop => true; /* @@ -1753,137 +1743,5 @@ namespace Server.Multis return base.GetWorldPacketFor( state ); } */ - - public sealed class MoveBoatHS : Packet - { - public MoveBoatHS(Mobile beholder, BaseBoat boat, Direction d, int speed, List ents, int xOffset, - int yOffset) - : base(0xF6) - { - EnsureCapacity(3 + 15 + ents.Count * 10); - - m_Stream.Write(boat.Serial); - m_Stream.Write((byte)speed); - m_Stream.Write((byte)d); - m_Stream.Write((byte)boat.Facing); - m_Stream.Write((short)(boat.X + xOffset)); - m_Stream.Write((short)(boat.Y + yOffset)); - m_Stream.Write((short)boat.Z); - m_Stream.Write((short)0); // count placeholder - - int count = 0; - - foreach (IEntity ent in ents) - { - if (!beholder.CanSee(ent)) - continue; - - m_Stream.Write(ent.Serial); - m_Stream.Write((short)(ent.X + xOffset)); - m_Stream.Write((short)(ent.Y + yOffset)); - m_Stream.Write((short)ent.Z); - ++count; - } - - m_Stream.Seek(16, SeekOrigin.Begin); - m_Stream.Write((short)count); - } - } - - public sealed class DisplayBoatHS : Packet - { - public DisplayBoatHS(Mobile beholder, BaseBoat boat) - : base(0xF7) - { - List ents = boat.GetMovingEntities(); - - SafeAdd(boat.TillerMan, ents); - SafeAdd(boat.Hold, ents); - SafeAdd(boat.PPlank, ents); - SafeAdd(boat.SPlank, ents); - - ents.Add(boat); - - EnsureCapacity(3 + 2 + ents.Count * 26); - - m_Stream.Write((short)0); // count placeholder - - int count = 0; - - foreach (IEntity ent in ents) - { - if (!beholder.CanSee(ent)) - continue; - - // Embedded WorldItemHS packets - m_Stream.Write((byte)0xF3); - m_Stream.Write((short)0x1); - - if (ent is BaseMulti bm) - { - m_Stream.Write((byte)0x02); - m_Stream.Write(bm.Serial); - // TODO: Mask no longer needed, merge with Item case? - m_Stream.Write((ushort)(bm.ItemID & 0x3FFF)); - m_Stream.Write((byte)0); - - m_Stream.Write((short)bm.Amount); - m_Stream.Write((short)bm.Amount); - - m_Stream.Write((short)(bm.X & 0x7FFF)); - m_Stream.Write((short)(bm.Y & 0x3FFF)); - m_Stream.Write((sbyte)bm.Z); - - m_Stream.Write((byte)bm.Light); - m_Stream.Write((short)bm.Hue); - m_Stream.Write((byte)bm.GetPacketFlags()); - } - else if (ent is Mobile m) - { - m_Stream.Write((byte)0x01); - m_Stream.Write(m.Serial); - m_Stream.Write((short)m.Body); - m_Stream.Write((byte)0); - - m_Stream.Write((short)1); - m_Stream.Write((short)1); - - m_Stream.Write((short)(m.X & 0x7FFF)); - m_Stream.Write((short)(m.Y & 0x3FFF)); - m_Stream.Write((sbyte)m.Z); - - m_Stream.Write((byte)m.Direction); - m_Stream.Write((short)m.Hue); - m_Stream.Write((byte)m.GetPacketFlags()); - } - else if (ent is Item item) - { - m_Stream.Write((byte)0x00); - m_Stream.Write(item.Serial); - m_Stream.Write((ushort)(item.ItemID & 0xFFFF)); - m_Stream.Write((byte)0); - - m_Stream.Write((short)item.Amount); - m_Stream.Write((short)item.Amount); - - m_Stream.Write((short)(item.X & 0x7FFF)); - m_Stream.Write((short)(item.Y & 0x3FFF)); - m_Stream.Write((sbyte)item.Z); - - m_Stream.Write((byte)item.Light); - m_Stream.Write((short)item.Hue); - m_Stream.Write((byte)item.GetPacketFlags()); - } - - m_Stream.Write((short)0x00); - ++count; - } - - m_Stream.Seek(3, SeekOrigin.Begin); - m_Stream.Write((short)count); - } - } - - #endregion } } diff --git a/Projects/Scripts/Multis/Boats/ConfirmDryDockGump.cs b/Projects/Scripts/Multis/Boats/ConfirmDryDockGump.cs index 920eecaa5..4184103ae 100644 --- a/Projects/Scripts/Multis/Boats/ConfirmDryDockGump.cs +++ b/Projects/Scripts/Multis/Boats/ConfirmDryDockGump.cs @@ -29,7 +29,7 @@ namespace Server.Multis AddButton(20, 125, 4005, 4007, 1); } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (info.ButtonID == 2) m_Boat.EndDryDock(m_From); diff --git a/Projects/Scripts/Multis/Boats/Packets.cs b/Projects/Scripts/Multis/Boats/Packets.cs new file mode 100644 index 000000000..e82d6fe22 --- /dev/null +++ b/Projects/Scripts/Multis/Boats/Packets.cs @@ -0,0 +1,127 @@ +using System.Collections.Generic; +using Server.Buffers; +using Server.Multis; + +namespace Server.Network +{ + public static class BoatPackets + { + public static void SendMoveBoatHS(NetState ns, Mobile beholder, BaseBoat boat, Direction d, int speed, + IReadOnlyCollection ents, int xOffset, + int yOffset) + { + if (ns == null) + return; + + int length = 18 + ents.Count * 10; + SpanWriter writer = new SpanWriter(stackalloc byte[length]); + writer.Write((byte)0xF6); // Packet ID + writer.Position += 2; // Dynamic Length + + writer.Write(boat.Serial); + writer.Write((byte)speed); + writer.Write((byte)d); + writer.Write((byte)boat.Facing); + writer.Write((short)(boat.X + xOffset)); + writer.Write((short)(boat.Y + yOffset)); + writer.Write((short)boat.Z); + writer.Position += 2; // count + + ushort count = 0; + foreach (IEntity ent in ents) + { + if (!beholder.CanSee(ent)) + continue; + + writer.Write(ent.Serial); + writer.Write((short)(ent.X + xOffset)); + writer.Write((short)(ent.Y + yOffset)); + writer.Write((short)ent.Z); + count++; + } + + writer.Position = 16; + writer.Write(count); + writer.Position = 1; + writer.Write((ushort)writer.WrittenCount); + + ns.Send(writer.Span); + } + + public static void SendDisplayBoatHS(NetState ns, Mobile beholder, BaseBoat boat) + { + if (ns == null) + return; + + List ents = boat.GetMovingEntities(); + if (boat.TillerMan != null) ents.Add(boat.TillerMan); + if (boat.Hold != null) ents.Add(boat.Hold); + if (boat.PPlank != null) ents.Add(boat.PPlank); + if (boat.SPlank != null) ents.Add(boat.SPlank); + ents.Add(boat); + + int length = 5 + ents.Count * 26; + SpanWriter writer = new SpanWriter(stackalloc byte[length]); + writer.Write((byte)0xF7); // Packet ID + writer.Position += 4; // Dynamic Length & Count + + ushort count = 0; + + foreach (IEntity ent in ents) + { + if (!beholder.CanSee(ent)) + continue; + + writer.Write((byte)0xF3); + writer.Write((short)0x1); + + if (ent is Mobile m) + { + writer.Write((byte)0x01); + writer.Write(m.Serial); + writer.Write((short)m.Body); + writer.Position++; + + writer.Write((short)1); + writer.Write((short)1); + + writer.Write((short)(m.X & 0x7FFF)); + writer.Write((short)(m.Y & 0x3FFF)); + writer.Write((sbyte)m.Z); + + writer.Write((byte)m.Direction); + writer.Write((short)m.Hue); + writer.Write((byte)m.GetPacketFlags()); + } + else if (ent is Item item) + { + writer.Position++; + writer.Write(item.Serial); + writer.Write((ushort)(item.ItemID & 0xFFFF)); + writer.Position++; + + writer.Write((short)item.Amount); + writer.Write((short)item.Amount); + + writer.Write((short)(item.X & 0x7FFF)); + writer.Write((short)(item.Y & 0x3FFF)); + writer.Write((sbyte)item.Z); + + writer.Write((byte)item.Light); + writer.Write((short)item.Hue); + writer.Write((byte)item.GetPacketFlags()); + } + + writer.Position += 2; + count++; + } + + writer.Position = 3; + writer.Write(count); + writer.Position = 1; + writer.Write((ushort)writer.WrittenCount); + + ns.Send(writer.Span); + } + } +} diff --git a/Projects/Scripts/Multis/Boats/RenameBoatPrompt.cs b/Projects/Scripts/Multis/Boats/RenameBoatPrompt.cs index 4448bbed8..6afc8694b 100644 --- a/Projects/Scripts/Multis/Boats/RenameBoatPrompt.cs +++ b/Projects/Scripts/Multis/Boats/RenameBoatPrompt.cs @@ -1,5 +1,3 @@ -using Server.Prompts; - namespace Server.Multis { public class RenameBoatPrompt : Prompt diff --git a/Projects/Scripts/Multis/Boats/Strandedness.cs b/Projects/Scripts/Multis/Boats/Strandedness.cs index 5f818ecee..3a4c4bfe2 100644 --- a/Projects/Scripts/Multis/Boats/Strandedness.cs +++ b/Projects/Scripts/Multis/Boats/Strandedness.cs @@ -95,7 +95,7 @@ namespace Server.Misc if (map == null) return false; - object surface = map.GetTopSurface(from.Location); + ITile surface = map.GetTopSurface(from.Location); if (surface is LandTile tile) { @@ -175,4 +175,4 @@ namespace Server.Misc from.Location = new Point3D(x, y, z); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Multis/DynamicDecay.cs b/Projects/Scripts/Multis/DynamicDecay.cs index 8976f294a..385862cb7 100644 --- a/Projects/Scripts/Multis/DynamicDecay.cs +++ b/Projects/Scripts/Multis/DynamicDecay.cs @@ -5,7 +5,7 @@ namespace Server.Multis { public class DynamicDecay { - private static Dictionary m_Stages; + private static readonly Dictionary m_Stages; static DynamicDecay() { diff --git a/Projects/Scripts/Multis/BaseHouse.cs b/Projects/Scripts/Multis/Houses/BaseHouse.cs similarity index 88% rename from Projects/Scripts/Multis/BaseHouse.cs rename to Projects/Scripts/Multis/Houses/BaseHouse.cs index 97c9e5829..69a819c44 100644 --- a/Projects/Scripts/Multis/BaseHouse.cs +++ b/Projects/Scripts/Multis/Houses/BaseHouse.cs @@ -24,7 +24,7 @@ namespace Server.Multis public const int MaximumBarkeepCount = 2; - private static Dictionary> m_Table = new Dictionary>(); + private static readonly Dictionary> m_Table = new Dictionary>(); private DecayLevel m_LastDecayLevel; @@ -148,10 +148,7 @@ namespace Server.Multis newest = check; } - if (this == newest) - return DecayType.AutoRefresh; - - return DecayType.ManualRefresh; + return this == newest ? DecayType.AutoRefresh : DecayType.ManualRefresh; } } @@ -218,43 +215,13 @@ namespace Server.Multis public virtual bool IsActive => true; - public bool HasPersonalVendors - { - get - { - foreach (PlayerVendor vendor in PlayerVendors) - if (!(vendor is RentedVendor)) - return true; + public bool HasPersonalVendors => PlayerVendors.Any(vendor => !(vendor is RentedVendor)); - return false; - } - } - - public bool HasRentedVendors - { - get - { - foreach (PlayerVendor vendor in PlayerVendors) - if (vendor is RentedVendor) - return true; - - return false; - } - } + public bool HasRentedVendors => PlayerVendors.OfType().Any(); #region Mondain's Legacy - public bool HasAddonContainers - { - get - { - foreach (Item item in Addons) - if (item is BaseAddonContainer) - return true; - - return false; - } - } + public bool HasAddonContainers => Addons.OfType().Any(); #endregion @@ -364,9 +331,7 @@ namespace Server.Multis { get { - int count = 0; - - count += GetLockdowns(); + int count = GetLockdowns(); if (Secures != null) for (int i = 0; i < Secures.Count; ++i) @@ -385,26 +350,7 @@ namespace Server.Multis } } - public int SecureCount - { - get - { - int count = 0; - - if (Secures != null) - for (int i = 0; i < Secures.Count; i++) - { - SecureInfo info = Secures[i]; - - if (info.Item.Deleted) - continue; - if (!(info.Item is StrongBox)) - count += 1; - } - - return count; - } - } + public int SecureCount => Secures?.Where(info => !info.Item.Deleted).Count(info => !(info.Item is StrongBox)) ?? 0; public List Addons{ get; set; } @@ -542,11 +488,9 @@ namespace Server.Multis { HousePlacementEntry hpe = GetAosEntry(); - if (hpe == null) - return 0; + public virtual int GetAosMaxSecures() => (int)(GetAosEntry()?.Storage ?? 0 * BonusStorageScalar); - return (int)(hpe.Lockdowns * BonusStorageScalar); - } + public virtual int GetAosMaxLockdowns() => (int)(GetAosEntry()?.Lockdowns ?? 0 * BonusStorageScalar); public virtual int GetAosCurSecures(out int fromSecures, out int fromVendors, out int fromLockdowns, out int fromMovingCrate) @@ -560,22 +504,14 @@ namespace Server.Multis if (list != null) { - for (int i = 0; i < list.Count; ++i) - { - SecureInfo si = list[i]; - - fromSecures += si.Item.TotalItems; - } - + fromSecures += list.Sum(si => si.Item.TotalItems); fromLockdowns += list.Count; } fromLockdowns += GetLockdowns(); if (!NewVendorSystem) - foreach (PlayerVendor vendor in PlayerVendors) - if (vendor.Backpack != null) - fromVendors += vendor.Backpack.TotalItems; + fromVendors += PlayerVendors.Where(vendor => vendor.Backpack != null).Sum(vendor => vendor.Backpack.TotalItems); if (MovingCrate != null) { @@ -589,18 +525,17 @@ namespace Server.Multis return fromSecures + fromVendors + fromLockdowns + fromMovingCrate; } - public bool InRange(IPoint2D from, int range) - { - if (Region == null) - return false; + public bool InRange(IPoint2D from, int range) => + Region?.Area.Any(rect => + from.X >= rect.Start.X - range && from.Y >= rect.Start.Y - range && from.X < rect.End.X + range && from.Y < rect.End.Y + range) + == true; - foreach (Rectangle3D rect in Region.Area) - if (from.X >= rect.Start.X - range && from.Y >= rect.Start.Y - range && from.X < rect.End.X + range && - from.Y < rect.End.Y + range) - return true; + public virtual int GetNewVendorSystemMaxVendors() => + (int)(GetAosEntry()?.Vendors ?? 0 * BonusStorageScalar); - return false; - } + public virtual bool CanPlaceNewVendor() => + !IsAosRules || (!NewVendorSystem ? CheckAosLockdowns(10) : + PlayerVendors.Count + VendorRentalContracts.Count < GetNewVendorSystemMaxVendors()); public virtual int GetNewVendorSystemMaxVendors() { @@ -651,25 +586,11 @@ namespace Server.Multis eable.Free(); } - public List AvailableVendorsFor(Mobile m) - { - List list = new List(); + public List AvailableVendorsFor(Mobile m) => + PlayerVendors.Where(vendor => vendor.CanInteractWith(m, false)).Cast().ToList(); - foreach (PlayerVendor vendor in PlayerVendors) - if (vendor.CanInteractWith(m, false)) - list.Add(vendor); - - return list; - } - - public bool AreThereAvailableVendorsFor(Mobile m) - { - foreach (PlayerVendor vendor in PlayerVendors) - if (vendor.CanInteractWith(m, false)) - return true; - - return false; - } + public bool AreThereAvailableVendorsFor(Mobile m) => + PlayerVendors.Any(vendor => vendor.CanInteractWith(m, false)); public void MoveAllToCrate() { @@ -696,7 +617,7 @@ namespace Server.Multis LockDowns.Clear(); - foreach (Item item in VendorRentalContracts) + foreach (VendorRentalContract item in VendorRentalContracts) if (!item.Deleted) { item.IsLockedDown = false; @@ -811,25 +732,10 @@ namespace Server.Multis if (m_Trash != null && m_Trash.Map != Map.Internal) list.Add(m_Trash); - foreach (Item item in LockDowns) - if (item.Parent == null && item.Map != Map.Internal) - list.Add(item); - - foreach (Item item in VendorRentalContracts) - if (item.Parent == null && item.Map != Map.Internal) - list.Add(item); - - foreach (SecureInfo info in Secures) - { - Item item = info.Item; - - if (item.Parent == null && item.Map != Map.Internal) - list.Add(item); - } - - foreach (Item item in Addons) - if (item.Parent == null && item.Map != Map.Internal) - list.Add(item); + list.AddRange(LockDowns.Where(item => item.Parent == null && item.Map != Map.Internal)); + list.AddRange(VendorRentalContracts.Cast().Where(item => item.Parent == null && item.Map != Map.Internal)); + list.AddRange(Secures.Select(info => info.Item).Where(item => item.Parent == null && item.Map != Map.Internal)); + list.AddRange(Addons.Where(item => item.Parent == null && item.Map != Map.Internal)); foreach (PlayerVendor mobile in PlayerVendors) { @@ -839,9 +745,7 @@ namespace Server.Multis list.Add(mobile); } - foreach (Mobile mobile in PlayerBarkeepers) - if (mobile.Map != Map.Internal) - list.Add(mobile); + list.AddRange(PlayerBarkeepers.Cast().Where(mobile => mobile.Map != Map.Internal)); return list; } @@ -908,9 +812,7 @@ namespace Server.Multis // The item can't fit if (item is TrashBarrel) - { item.Delete(); // Trash barrels don't go to the moving crate - } else { SetLockdown(item, false); @@ -995,9 +897,7 @@ namespace Server.Multis public void DropToMovingCrate(Item item) { - if (MovingCrate == null) - MovingCrate = new MovingCrate(this); - + MovingCrate ??= new MovingCrate(this); MovingCrate.DropItem(item); } @@ -1018,12 +918,11 @@ namespace Server.Multis return list; } - public List GetMobiles() - { - if (Map == null || Map == Map.Internal) - return new List(); + public List GetMobiles() => + Map == null || Map == Map.Internal ? new List() + : Region.GetMobiles().Where(IsInside).ToList(); - List list = new List(); + public virtual bool CheckAosLockdowns(int need) => GetAosCurLockdowns() + need <= GetAosMaxLockdowns(); foreach (Mobile mobile in Region.GetMobiles()) if (IsInside(mobile)) @@ -1046,14 +945,9 @@ namespace Server.Multis Timer.DelayCall(TimeSpan.FromMinutes(1.0), TimeSpan.FromMinutes(1.0), Decay_OnTick); } - public virtual int GetAosCurLockdowns() - { - int v = 0; + public virtual int GetAosCurLockdowns() => GetLockdowns() + Secures?.Count ?? 0 + (NewVendorSystem ? 0 : PlayerVendors.Count * 10); - v += GetLockdowns(); - - if (Secures != null) - v += Secures.Count; + public static bool CheckLockedDown(Item item) => FindHouseAt(item)?.HasLockedDownItem(item) == true; if (!NewVendorSystem) v += PlayerVendors.Count * 10; @@ -1114,31 +1008,15 @@ namespace Server.Multis BaseHouse house = FindHouseAt(item); - if (house == null) - return true; - - SecureAccessResult res = house.CheckSecureAccess(m, item); - - switch (res) + return house == null || house.CheckSecureAccess(m, item) switch { - case SecureAccessResult.Insecure: break; - case SecureAccessResult.Accessible: return true; - case SecureAccessResult.Inaccessible: return false; - } - - if (house.HasLockedDownItem(item)) - return house.IsCoOwner(m) && item is Container; - - return true; + SecureAccessResult.Accessible => true, + SecureAccessResult.Inaccessible => false, + _ => (!house.HasLockedDownItem(item) || house.IsCoOwner(m) && item is Container) + }; } - public static BaseHouse FindHouseAt(Mobile m) - { - if (m?.Deleted != false) - return null; - - return FindHouseAt(m.Location, m.Map, 16); - } + public static BaseHouse FindHouseAt(Mobile m) => m?.Deleted != false ? null : FindHouseAt(m.Location, m.Map, 16); public static BaseHouse FindHouseAt(Item item) => item?.Deleted != false ? null : @@ -1168,7 +1046,7 @@ namespace Server.Multis switch (res) { - case SecureAccessResult.Insecure: break; + // case SecureAccessResult.Insecure: break; case SecureAccessResult.Accessible: return true; case SecureAccessResult.Inaccessible: return false; } @@ -1185,28 +1063,21 @@ namespace Server.Multis return IsCoOwner(from); if (item.Stackable) return true; - if (item is BaseLight) - return IsFriend(from); - if (item is PotionKeg) - return IsFriend(from); - if (item is Dices) - return true; - if (item is RecallRune) - return true; - if (item is TreasureMap) - return true; - if (item is Clock) - return true; - if (item is BaseInstrument) - return true; - if (item is Dyes) - return true; - if (item is VendorRentalContract) - return true; - if (item is RewardBrazier) - return true; - return false; + return item switch + { + BaseLight _ => IsFriend(from), + PotionKeg _ => IsFriend(from), + Dices _ => true, + RecallRune _ => true, + TreasureMap _ => true, + Clock _ => true, + BaseInstrument _ => true, + Dyes _ => true, + VendorRentalContract _ => true, + RewardBrazier _ => true, + _ => false + }; } public virtual bool IsInside(Point3D p, int height) @@ -1491,9 +1362,11 @@ namespace Server.Multis m_Trash = new TrashBarrel { Movable = false }; m_Trash.MoveToWorld(from.Location, from.Map); - from.SendLocalizedMessage(502121); /* You have a new trash barrel. - * Three minutes after you put something in the barrel, the trash will be emptied. - * Be forewarned, this is permanent! */ + from.SendLocalizedMessage(502121); + /* You have a new trash barrel. + * Three minutes after you put something in the barrel, the trash will be emptied. + * Be forewarned, this is permanent! + */ } else { @@ -1562,31 +1435,19 @@ namespace Server.Multis Item parentItem = item.Parent as Item; if (checkIsInside && item.RootParent is Mobile) - { m.SendLocalizedMessage(1005525); //That is not in your house - } else if (checkIsInside && !IsInside(item.GetWorldLocation(), item.ItemData.Height)) - { m.SendLocalizedMessage(1005525); //That is not in your house - } else if (Ethic.IsImbued(item)) - { m.SendLocalizedMessage(1005377); //You cannot lock that down - } else if (HasSecureItem(rootItem)) - { m.SendLocalizedMessage(501737); // You need not lock down items in a secure container. - } else if (parentItem != null && !HasLockedDownItem(parentItem)) - { m.SendLocalizedMessage(501736); // You must lockdown the container first! - } else if (!(item is VendorRentalContract) && (IsAosRules ? !CheckAosLockdowns(amt) || !CheckAosStorage(amt) : LockDownCount + amt > MaxLockDowns)) - { m.SendLocalizedMessage(1005379); //That would exceed the maximum lock down limit for this house - } else { SetLockdown(item, true); @@ -1599,13 +1460,9 @@ namespace Server.Multis return true; } else if (item is HouseSign || item is Static) - { m.LocalOverheadMessage(MessageType.Regular, 0x3E9, 1005526); // This is already locked down. - } else - { m.SendLocalizedMessage(1005377); //You cannot lock that down - } return false; } @@ -1644,25 +1501,17 @@ namespace Server.Multis return; if (NewVendorSystem && HasPersonalVendors) - { from.SendLocalizedMessage( 1062467); // You cannot trade this house while you still have personal vendors inside. - } else if (DecayLevel == DecayLevel.DemolitionPending) - { from.SendLocalizedMessage( 1005321); // This house has been marked for demolition, and it cannot be transferred. - } else if (from == to) - { from.SendLocalizedMessage(1005330); // You cannot transfer a house to yourself, silly. - } else if (to.Player) { if (HasAccountHouse(to)) - { from.SendLocalizedMessage(501388); // You cannot transfer ownership to another house owner or co-owner! - } else if (CheckTransferPosition(from, to)) { from.SendLocalizedMessage(1005326); // Please wait while the other player verifies the transfer. @@ -1709,25 +1558,17 @@ namespace Server.Multis return; if (NewVendorSystem && HasPersonalVendors) - { from.SendLocalizedMessage( 1062467); // You cannot trade this house while you still have personal vendors inside. - } else if (DecayLevel == DecayLevel.DemolitionPending) - { from.SendLocalizedMessage( 1005321); // This house has been marked for demolition, and it cannot be transferred. - } else if (from == to) - { from.SendLocalizedMessage(1005330); // You cannot transfer a house to yourself, silly. - } else if (to.Player) { if (HasAccountHouse(to)) - { from.SendLocalizedMessage(501388); // You cannot transfer ownership to another house owner or co-owner! - } else if (CheckTransferPosition(from, to)) { NetState fromState = from.NetState, toState = to.NetState; @@ -1735,20 +1576,14 @@ namespace Server.Multis if (fromState != null && toState != null) { if (from.HasTrade) - { from.SendLocalizedMessage( 1062071); // You cannot trade a house while you have other trades pending. - } else if (to.HasTrade) - { to.SendLocalizedMessage( 1062071); // You cannot trade a house while you have other trades pending. - } else if (!to.Alive) - { // TODO: Check if the message is correct. from.SendLocalizedMessage(1062069); // You cannot transfer this house to that person. - } else { Container c = fromState.AddTrade(toState); @@ -1759,9 +1594,7 @@ namespace Server.Multis } } else - { from.SendLocalizedMessage(501384); // Only a player can own a house! - } } public void Release(Mobile m, Item item) @@ -1778,13 +1611,9 @@ namespace Server.Multis (item as RewardBrazier)?.TurnOff(); } else if (HasSecureItem(item)) - { ReleaseSecure(m, item); - } else - { m.LocalOverheadMessage(MessageType.Regular, 0x3E9, 1010416); // This is not locked down or secured. - } } public void AddSecure(Mobile m, Item item) @@ -1793,17 +1622,11 @@ namespace Server.Multis return; if (!IsInside(item)) - { m.SendLocalizedMessage(1005525); // That is not in your house - } else if (HasLockedDownItem(item)) - { m.SendLocalizedMessage(1010550); // This is already locked down and cannot be secured. - } else if (!(item is Container)) - { LockDown(m, item); - } else { SecureInfo info = null; @@ -1818,27 +1641,17 @@ namespace Server.Multis m.SendGump(new SetSecureLevelGump(m_Owner, info, this)); } else if (item.Parent != null) - { m.SendLocalizedMessage(1010423); // You cannot secure this, place it on the ground first. - } // Mondain's Legacy mod else if (!(item is BaseAddonContainer) && !item.Movable) - { m.SendLocalizedMessage(1010424); // You cannot secure this. - } else if (!IsAosRules && SecureCount >= MaxSecures) - { // The maximum number of secure items has been reached : m.SendLocalizedMessage(1008142, true, MaxSecures.ToString()); - } else if (IsAosRules ? !CheckAosLockdowns(1) : LockDownCount + 125 >= MaxLockDowns) - { m.SendLocalizedMessage(1005379); // That would exceed the maximum lock down limit for this house - } else if (IsAosRules && !CheckAosStorage(item.TotalItems)) - { m.SendLocalizedMessage(1061839); // This action would exceed the secure storage limit of the house. - } else { info = new SecureInfo((Container)item, SecureLevel.Owner); @@ -1908,15 +1721,7 @@ namespace Server.Multis item.IsLockedDown = false; item.IsSecure = false; - #region Mondain's Legacy - - if (item is BaseAddonContainer) - item.Movable = false; - else - - #endregion - - item.Movable = true; + item.Movable = !(item is BaseAddonContainer); item.SetLastMoved(); item.PublicOverheadMessage(MessageType.Label, 0x3B2, 501656); //[no longer secure] Secures.RemoveAt(i); @@ -1982,33 +1787,24 @@ namespace Server.Multis return; if (targ.AccessLevel > AccessLevel.Player && from.AccessLevel <= targ.AccessLevel) - { from.SendLocalizedMessage(501346); // Uh oh...a bigger boot may be required! - } else if (IsFriend(targ) && !Core.ML) - { from.SendLocalizedMessage(501348); // You cannot eject a friend of the house! - } else if (targ is PlayerVendor) - { from.SendLocalizedMessage(501351); // You cannot eject a vendor. - } else if (!IsInside(targ)) - { from.SendLocalizedMessage(501352); // You may not eject someone who is not in your house! - } else if (targ is BaseCreature creature && creature.NoHouseRestrictions) - { from.SendLocalizedMessage(501347); // You cannot eject that from the house! - } else { targ.MoveToWorld(BanLocation, Map); from.SendLocalizedMessage(1042840, targ.Name); // ~1_PLAYER NAME~ has been ejected from this house. - targ.SendLocalizedMessage(501341); /* You have been ejected from this house. - * If you persist in entering, you may be banned from the house. - */ + targ.SendLocalizedMessage(501341); + /* You have been ejected from this house. + * If you persist in entering, you may be banned from the house. + */ } } @@ -2050,38 +1846,22 @@ namespace Server.Multis return; if (targ.AccessLevel > AccessLevel.Player && from.AccessLevel <= targ.AccessLevel) - { from.SendLocalizedMessage(501354); // Uh oh...a bigger boot may be required. - } else if (IsFriend(targ)) - { from.SendLocalizedMessage(501348); // You cannot eject a friend of the house! - } else if (targ is PlayerVendor) - { from.SendLocalizedMessage(501351); // You cannot eject a vendor. - } else if (Bans.Count >= MaxBans) - { from.SendLocalizedMessage(501355); // The ban limit for this house has been reached! - } else if (IsBanned(targ)) - { from.SendLocalizedMessage(501356); // This person is already banned! - } else if (!IsInside(targ)) - { from.SendLocalizedMessage(501352); // You may not eject someone who is not in your house! - } else if (!Public && IsAosRules) - { from.SendLocalizedMessage( 1062521); // You cannot ban someone from a private house. Revoke their access instead. - } else if (targ is BaseCreature bc && bc.NoHouseRestrictions) - { from.SendLocalizedMessage(1062040); // You cannot ban that. - } else { Bans.Add(targ); @@ -2099,17 +1879,11 @@ namespace Server.Multis return; if (HasAccess(targ)) - { from.SendLocalizedMessage(1060729); // That person already has access to this house. - } else if (!targ.Player) - { from.SendLocalizedMessage(1060712); // That is not a player. - } else if (IsBanned(targ)) - { from.SendLocalizedMessage(501367); // This person is banned! Unban them first. - } else { Access.Add(targ); @@ -2124,33 +1898,19 @@ namespace Server.Multis return; if (IsOwner(targ)) - { from.SendLocalizedMessage(501360); // This person is already the house owner! - } else if (Friends.Contains(targ)) - { from.SendLocalizedMessage(501361); // This person is a friend of the house. Remove them first. - } else if (!targ.Player) - { from.SendLocalizedMessage(501362); // That can't be a co-owner of the house. - } else if (!Core.AOS && HasAccountHouse(targ)) - { from.SendLocalizedMessage(501364); // That person is already a house owner. - } else if (IsBanned(targ)) - { from.SendLocalizedMessage(501367); // This person is banned! Unban them first. - } else if (CoOwners.Count >= MaxCoOwners) - { from.SendLocalizedMessage(501368); // Your co-owner list is full! - } else if (CoOwners.Contains(targ)) - { from.SendLocalizedMessage(501369); // This person is already on your co-owner list! - } else { CoOwners.Add(targ); @@ -2196,29 +1956,17 @@ namespace Server.Multis return; if (IsOwner(targ)) - { from.SendLocalizedMessage(501370); // This person is already an owner of the house! - } else if (CoOwners.Contains(targ)) - { from.SendLocalizedMessage(501369); // This person is already on your co-owner list! - } else if (!targ.Player) - { from.SendLocalizedMessage(501371); // That can't be a friend of the house. - } else if (IsBanned(targ)) - { from.SendLocalizedMessage(501374); // This person is banned! Unban them first. - } else if (Friends.Count >= MaxFriends) - { from.SendLocalizedMessage(501375); // Your friends list is full! - } else if (Friends.Contains(targ)) - { from.SendLocalizedMessage(501376); // This person is already on your friends list! - } else { Friends.Add(targ); @@ -2801,21 +2549,7 @@ namespace Server.Multis AllHouses.Remove(this); } - public static bool HasHouse(Mobile m) - { - if (m == null || !m_Table.TryGetValue(m, out List list)) - return false; - - for (int i = 0; i < list.Count; ++i) - { - BaseHouse h = list[i]; - - if (!h.Deleted) - return true; - } - - return false; - } + public static bool HasHouse(Mobile m) => m != null && m_Table.TryGetValue(m, out List list) && list.Any(h => !h.Deleted); public static bool HasAccountHouse(Mobile m) { @@ -2829,35 +2563,15 @@ namespace Server.Multis return false; } - public bool IsOwner(Mobile m) - { - if (m == null) - return false; + public bool IsOwner(Mobile m) => + m != null && (m == m_Owner || m.AccessLevel >= AccessLevel.GameMaster || + IsAosRules && AccountHandler.CheckAccount(m, m_Owner)); - if (m == m_Owner || m.AccessLevel >= AccessLevel.GameMaster) - return true; + public bool IsCoOwner(Mobile m) => + m != null && (IsOwner(m) || CoOwners?.Contains(m) == true || + !IsAosRules && AccountHandler.CheckAccount(m, m_Owner)); - return IsAosRules && AccountHandler.CheckAccount(m, m_Owner); - } - - public bool IsCoOwner(Mobile m) - { - if (m == null || CoOwners == null) - return false; - - if (IsOwner(m) || CoOwners.Contains(m)) - return true; - - return !IsAosRules && AccountHandler.CheckAccount(m, m_Owner); - } - - public bool IsGuildMember(Mobile m) - { - if (m == null || Owner?.Guild == null) - return false; - - return m.Guild == Owner.Guild; - } + public bool IsGuildMember(Mobile m) => Owner?.Guild != null && m?.Guild == Owner.Guild; public void RemoveKeys(Mobile m) { @@ -3069,10 +2783,11 @@ namespace Server.Multis return; from.SendLocalizedMessage(501338); // You have transferred ownership of the house. - to.SendLocalizedMessage(501339); /* You are now the owner of this house. - * The house's co-owner, friend, ban, and access lists have been cleared. - * You should double-check the security settings on any doors and teleporters in the house. - */ + to.SendLocalizedMessage(501339); + /* You are now the owner of this house. + * The house's co-owner, friend, ban, and access lists have been cleared. + * You should double-check the security settings on any doors and teleporters in the house. + */ m_House.RemoveKeys(from); m_House.Owner = to; diff --git a/Projects/Scripts/Multis/Deeds.cs b/Projects/Scripts/Multis/Houses/Deeds.cs similarity index 94% rename from Projects/Scripts/Multis/Deeds.cs rename to Projects/Scripts/Multis/Houses/Deeds.cs index 81769384a..5436302c3 100644 --- a/Projects/Scripts/Multis/Deeds.cs +++ b/Projects/Scripts/Multis/Houses/Deeds.cs @@ -100,18 +100,15 @@ namespace Server.Multis.Deeds public override void OnDoubleClick(Mobile from) { if (!IsChildOf(from.Backpack)) - { from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it. - } else if (from.AccessLevel < AccessLevel.GameMaster && BaseHouse.HasAccountHouse(from)) - { from.SendLocalizedMessage(501271); // You already own a house, you may not place another! - } else { - from.SendLocalizedMessage(1010433); /* House placement cancellation could result in a - * 60 second delay in the return of your deed. - */ + from.SendLocalizedMessage(1010433); + /* House placement cancellation could result in a + * 60 second delay in the return of your deed. + */ from.Target = new HousePlacementTarget(this); } @@ -125,13 +122,9 @@ namespace Server.Multis.Deeds return; if (!IsChildOf(from.Backpack)) - { from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it. - } else if (from.AccessLevel < AccessLevel.GameMaster && BaseHouse.HasAccountHouse(from)) - { from.SendLocalizedMessage(501271); // You already own a house, you may not place another! - } else { Point3D center = new Point3D(p.X - Offset.X, p.Y - Offset.Y, p.Z - Offset.Z); diff --git a/Projects/Scripts/Multis/HouseFoundation.cs b/Projects/Scripts/Multis/Houses/HouseFoundation.cs similarity index 90% rename from Projects/Scripts/Multis/HouseFoundation.cs rename to Projects/Scripts/Multis/Houses/HouseFoundation.cs index b77b75d87..7e8ae0615 100644 --- a/Projects/Scripts/Multis/HouseFoundation.cs +++ b/Projects/Scripts/Multis/Houses/HouseFoundation.cs @@ -3,8 +3,8 @@ using System.Buffers; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Threading; -using System.Threading.Tasks; using Server.Gumps; using Server.Items; using Server.Mobiles; @@ -123,9 +123,7 @@ namespace Server.Multis { get { - if (m_Current == null) - SetInitialState(); - + if (m_Current == null) SetInitialState(); return m_Current.Components; } } @@ -187,7 +185,7 @@ namespace Server.Multis } } - public static ComponentVerification Verification => m_Verification ?? (m_Verification = new ComponentVerification()); + public static ComponentVerification Verification => m_Verification ??= new ComponentVerification(); public bool IsFixture(Item item) => Fixtures.Contains(item); @@ -300,8 +298,7 @@ namespace Server.Multis public void AddFixtures(Mobile from, MultiTileEntry[] list) { - if (Fixtures == null) - Fixtures = new List(); + Fixtures ??= new List(); uint keyValue = 0; @@ -394,13 +391,9 @@ namespace Server.Multis door = new GenericHouseDoor(facing, 0x29F5 + 8 * ((itemID - 0x2A05) / 8), sound, sound); } else if (itemID == 0x2D46) - { door = new GenericHouseDoor(DoorFacing.NorthCW, 0x2D46, 0xEA, 0xF1, false); - } else if (itemID == 0x2D48 || itemID == 0x2FE2) - { door = new GenericHouseDoor(DoorFacing.SouthCCW, itemID, 0xEA, 0xF1, false); - } else if (itemID >= 0x2D63 && itemID < 0x2D70) { int mod = (itemID - 0x2D63) / 2 % 2; @@ -411,9 +404,7 @@ namespace Server.Multis door = new GenericHouseDoor(facing, 0x2D63 + 4 * type + mod * 2, 0xEA, 0xF1, false); } else if (itemID == 0x2FE4 || itemID == 0x31AE) - { door = new GenericHouseDoor(DoorFacing.WestCCW, itemID, 0xEA, 0xF1, false); - } else if (itemID >= 0x319C && itemID < 0x31AE) { //special case for 0x31aa <-> 0x31a8 (a9) @@ -446,21 +437,13 @@ namespace Server.Multis }; } else if (itemID >= 0x409B && itemID < 0x40A3) - { door = new GenericHouseDoor(GetSADoorFacing(itemID - 0x409B), itemID, 0xEA, 0xF1, false); - } else if (itemID >= 0x410C && itemID < 0x4114) - { door = new GenericHouseDoor(GetSADoorFacing(itemID - 0x410C), itemID, 0xEA, 0xF1, false); - } else if (itemID >= 0x41C2 && itemID < 0x41CA) - { door = new GenericHouseDoor(GetSADoorFacing(itemID - 0x41C2), itemID, 0xEA, 0xF1, false); - } else if (itemID >= 0x41CF && itemID < 0x41D7) - { door = new GenericHouseDoor(GetSADoorFacing(itemID - 0x41CF), itemID, 0xEA, 0xF1, false); - } else if (itemID >= 0x436E && itemID < 0x437E) { /* These ones had to be different... @@ -472,25 +455,15 @@ namespace Server.Multis door = new GenericHouseDoor(facing, itemID, 0xEA, 0xF1, false); } else if (itemID >= 0x46DD && itemID < 0x46E5) - { door = new GenericHouseDoor(GetSADoorFacing(itemID - 0x46DD), itemID, 0xEB, 0xF2, false); - } else if (itemID >= 0x4D22 && itemID < 0x4D2A) - { door = new GenericHouseDoor(GetSADoorFacing(itemID - 0x4D22), itemID, 0xEA, 0xF1, false); - } else if (itemID >= 0x50C8 && itemID < 0x50D0) - { door = new GenericHouseDoor(GetSADoorFacing(itemID - 0x50C8), itemID, 0xEA, 0xF1, false); - } else if (itemID >= 0x50D0 && itemID < 0x50D8) - { door = new GenericHouseDoor(GetSADoorFacing(itemID - 0x50D0), itemID, 0xEA, 0xF1, false); - } else if (itemID >= 0x5142 && itemID < 0x514A) - { door = new GenericHouseDoor(GetSADoorFacing(itemID - 0x5142), itemID, 0xF0, 0xEF, false); - } if (door != null) { @@ -530,7 +503,6 @@ namespace Server.Multis switch (door.Facing) { default: - case DoorFacing.WestCW: linkFacing = DoorFacing.EastCCW; xOffset = 1; yOffset = 0; @@ -618,7 +590,6 @@ namespace Server.Multis switch (type) { default: - case FoundationType.DarkWood: corner = 0x0014; east = 0x0015; south = 0x0016; @@ -768,20 +739,8 @@ namespace Server.Multis x += mcl.Center.X; y += mcl.Center.Y; - if (x >= 0 && x < mcl.Width && y >= 0 && y < mcl.Height) - { - StaticTile[] tiles = mcl.Tiles[x][y]; - - for (int i = 0; i < tiles.Length; ++i) - { - StaticTile tile = tiles[i]; - - if (tile.Z == 7 && tile.Height == 20) - return true; - } - } - - return false; + return x >= 0 && x < mcl.Width && y >= 0 && y < mcl.Height && + mcl.Tiles[x][y].Any(tile => tile.Z == 7 && tile.Height == 20); } public void BeginCustomize(Mobile m) @@ -799,12 +758,11 @@ namespace Server.Multis foreach (Item item in GetItems()) item.Location = BanLocation; - foreach (Mobile mobile in GetMobiles()) - if (mobile != m) - mobile.Location = BanLocation; + foreach (Mobile mobile in GetMobiles().Where(mobile => mobile != m)) + mobile.Location = BanLocation; DesignContext.Add(m, this); - m.Send(new BeginHouseCustomization(this)); + HouseFoundationPackets.SendBeginHouseCustomization(m.NetState, Serial); NetState ns = m.NetState; if (ns != null) @@ -1073,19 +1031,15 @@ namespace Server.Multis { // Temporary Fix. We should be booting a client out of customization mode in the delete handler. if (from.AccessLevel >= AccessLevel.GameMaster && cost != 0) - { from.SendMessage("{0} gold would have been {1} your bank if you were not a GM.", cost.ToString(), cost > 0 ? "withdrawn from" : "deposited into"); - } else { if (cost > 0) { if (Banker.Withdraw(from, cost)) - { from.SendLocalizedMessage(1060398, cost.ToString()); // ~1_AMOUNT~ gold has been withdrawn from your bank box. - } else { from.SendLocalizedMessage( @@ -1142,7 +1096,7 @@ namespace Server.Multis DesignContext.Remove(from); // Notify the client that customization has ended - from.Send(new EndHouseCustomization(this)); + HouseFoundationPackets.SendEndHouseCustomization(from.NetState, Serial); // Notify the core that the foundation has changed and should be resent to all clients Delta(ItemDelta.Update); @@ -1283,8 +1237,7 @@ namespace Server.Multis switch (dir) { - default: - case 0: // North + default: // North { xStart = x; yStart = y + height; @@ -1393,16 +1346,12 @@ namespace Server.Multis // Remove the component if (AllowStairSectioning) { - if (DeleteStairs(mcl, itemID, x, y, z)) - fixState = true; // The client removes the entire set of stairs locally, resend state + fixState |= DeleteStairs(mcl, itemID, x, y, z); // The client removes the entire set of stairs locally, resend state mcl.Remove(itemID, x, y, z); } - else - { - if (!DeleteStairs(mcl, itemID, x, y, z)) - mcl.Remove(itemID, x, y, z); - } + else if (!DeleteStairs(mcl, itemID, x, y, z)) + mcl.Remove(itemID, x, y, z); // If needed, replace removed component with a dirt tile if (ax >= 1 && ax < mcl.Width && ay >= 1 && ay < mcl.Height - 1) @@ -1559,7 +1508,8 @@ namespace Server.Multis DesignContext.Remove(from); // Notify the client that customization has ended - from.Send(new EndHouseCustomization(context.Foundation)); + + HouseFoundationPackets.SendEndHouseCustomization(from.NetState, context.Foundation.Serial); // Refresh client with current visible design state context.Foundation.SendInfoTo(state); @@ -1707,7 +1657,8 @@ namespace Server.Multis public class DesignState { - private Packet m_PacketCache; + private int m_Revision; + private byte[] m_Packet; public DesignState(HouseFoundation foundation, MultiComponentList components) { @@ -1759,27 +1710,23 @@ namespace Server.Multis } } - public Packet PacketCache - { - get => m_PacketCache; - set - { - if (m_PacketCache == value) - return; - - m_PacketCache?.Release(); - - m_PacketCache = value; - } - } - public HouseFoundation Foundation{ get; } public MultiComponentList Components{ get; } public MultiTileEntry[] Fixtures{ get; private set; } - public int Revision{ get; set; } + public int Revision + { + get => m_Revision; + set => m_Revision = value; + } + + public byte[] Packet + { + get => m_Packet; + set => Interlocked.Exchange(ref m_Packet, value); + } public void Serialize(GenericWriter writer) { @@ -1805,31 +1752,18 @@ namespace Server.Multis public void OnRevised() { - lock (this) - { - Revision = ++Foundation.LastRevision; - - m_PacketCache?.Release(); - - m_PacketCache = null; - } + Interlocked.Exchange(ref m_Revision, ++Foundation.LastRevision); } public void SendGeneralInfoTo(NetState state) { - state?.Send(new DesignStateGeneral(Foundation, this)); + HouseFoundationPackets.SendDesignStateGeneral(state, Foundation.Serial, Revision); } public void SendDetailedInfoTo(NetState state) { if (state != null) - lock (this) - { - if (m_PacketCache == null) - DesignStateDetailed.SendDetails(state, Foundation, this); - else - state.Send(m_PacketCache); - } + HouseFoundationPackets.SendDesignDetails(state, Foundation, this); } public void FreezeFixtures() @@ -1875,68 +1809,36 @@ namespace Server.Multis } } - public static bool IsFixture(int itemID) - { - if (itemID >= 0x675 && itemID < 0x6F5) - return true; - if (itemID >= 0x314 && itemID < 0x364) - return true; - if (itemID >= 0x824 && itemID < 0x834) - return true; - if (itemID >= 0x839 && itemID < 0x849) - return true; - if (itemID >= 0x84C && itemID < 0x85C) - return true; - if (itemID >= 0x866 && itemID < 0x876) - return true; - if (itemID >= 0x0E8 && itemID < 0x0F8) - return true; - if (itemID >= 0x1FED && itemID < 0x1FFD) - return true; - if (itemID >= 0x181D && itemID < 0x1829) - return true; - if (itemID >= 0x241F && itemID < 0x2421) - return true; - if (itemID >= 0x2423 && itemID < 0x2425) - return true; - if (itemID >= 0x2A05 && itemID < 0x2A1D) - return true; - if (itemID >= 0x319C && itemID < 0x31B0) - return true; - // ML doors - if (itemID == 0x2D46 || itemID == 0x2D48 || itemID == 0x2FE2 || itemID == 0x2FE4) - return true; - if (itemID >= 0x2D63 && itemID < 0x2D70) - return true; - if (itemID >= 0x319C && itemID < 0x31AF) - return true; - if (itemID >= 0x367B && itemID < 0x369B) - return true; - // SA doors - if (itemID >= 0x409B && itemID < 0x40A3) - return true; - if (itemID >= 0x410C && itemID < 0x4114) - return true; - if (itemID >= 0x41C2 && itemID < 0x41CA) - return true; - if (itemID >= 0x41CF && itemID < 0x41D7) - return true; - if (itemID >= 0x436E && itemID < 0x437E) - return true; - if (itemID >= 0x46DD && itemID < 0x46E5) - return true; - if (itemID >= 0x4D22 && itemID < 0x4D2A) - return true; - if (itemID >= 0x50C8 && itemID < 0x50D8) - return true; - if (itemID >= 0x5142 && itemID < 0x514A) - return true; - // TOL doors - if (itemID >= 0x9AD7 && itemID < 0x9AE7) - return true; - - return itemID >= 0x9B3C && itemID < 0x9B4C; - } + public static bool IsFixture(int itemID) => + itemID >= 0x675 && itemID < 0x6F5 || + itemID >= 0x314 && itemID < 0x364 || + itemID >= 0x824 && itemID < 0x834 || + itemID >= 0x839 && itemID < 0x849 || + itemID >= 0x84C && itemID < 0x85C || + itemID >= 0x866 && itemID < 0x876 || + itemID >= 0x0E8 && itemID < 0x0F8 || + itemID >= 0x1FED && itemID < 0x1FFD || + itemID >= 0x181D && itemID < 0x1829 || + itemID >= 0x241F && itemID < 0x2421 || + itemID >= 0x2423 && itemID < 0x2425 || + itemID >= 0x2A05 && itemID < 0x2A1D || + itemID >= 0x319C && itemID < 0x31B0 || + itemID == 0x2D46 || itemID == 0x2D48 || + itemID == 0x2FE2 || itemID == 0x2FE4 || + itemID >= 0x2D63 && itemID < 0x2D70 || + itemID >= 0x319C && itemID < 0x31AF || + itemID >= 0x367B && itemID < 0x369B || + itemID >= 0x409B && itemID < 0x40A3 || + itemID >= 0x410C && itemID < 0x4114 || + itemID >= 0x41C2 && itemID < 0x41CA || + itemID >= 0x41CF && itemID < 0x41D7 || + itemID >= 0x436E && itemID < 0x437E || + itemID >= 0x46DD && itemID < 0x46E5 || + itemID >= 0x4D22 && itemID < 0x4D2A || + itemID >= 0x50C8 && itemID < 0x50D8 || + itemID >= 0x5142 && itemID < 0x514A || + itemID >= 0x9AD7 && itemID < 0x9AE7 || + itemID >= 0x9B3C && itemID < 0x9B4C; } public class ConfirmCommitGump : Gump @@ -2060,17 +1962,17 @@ namespace Server.Multis { Item item = fixtures[i]; - state.Send(item.RemovePacket); + Packets.SendRemoveEntity(state, item.Serial); } if (foundation.Signpost != null) - state.Send(foundation.Signpost.RemovePacket); + Packets.SendRemoveEntity(state, foundation.Signpost.Serial); if (foundation.SignHanger != null) - state.Send(foundation.SignHanger.RemovePacket); + Packets.SendRemoveEntity(state, foundation.SignHanger.Serial); if (foundation.Sign != null) - state.Send(foundation.Sign.RemovePacket); + Packets.SendRemoveEntity(state, foundation.Sign.Serial); } public static void Remove(Mobile from) @@ -2102,9 +2004,7 @@ namespace Server.Multis } context.Foundation.Signpost?.SendInfoTo(state); - context.Foundation.SignHanger?.SendInfoTo(state); - context.Foundation.Sign?.SendInfoTo(state); } } diff --git a/Projects/Scripts/Multis/HousePlacement.cs b/Projects/Scripts/Multis/Houses/HousePlacement.cs similarity index 90% rename from Projects/Scripts/Multis/HousePlacement.cs rename to Projects/Scripts/Multis/Houses/HousePlacement.cs index a41b615f4..5f19d065b 100644 --- a/Projects/Scripts/Multis/HousePlacement.cs +++ b/Projects/Scripts/Multis/Houses/HousePlacement.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using Server.Regions; using Server.Spells; @@ -157,8 +158,7 @@ namespace Server.Multis bool isFoundation = addTile.Z == 0 && (addTileFlags & TileFlag.Wall) != 0; bool hasSurface = false; - if (isFoundation) - hasFoundation = true; + hasFoundation |= isFoundation; int addTileZ = center.Z + addTile.Z; int addTileTop = addTileZ + addTile.Height; @@ -333,29 +333,7 @@ namespace Server.Multis } } - for (int i = 0; i < yard.Count; ++i) - foreach (BaseHouse b in _houses) - if (b.Contains(yard[i])) - return HousePlacementResult.BadStatic; // Broke rule #3 - /*Point2D yardPoint = yard[i]; - - IPooledEnumerable eable = map.GetMultiTilesAt( yardPoint.X, yardPoint.Y ); - - foreach ( StaticTile[] tile in eable ) - { - for ( int j = 0; j < tile.Length; ++j ) - { - if ( (TileData.ItemTable[tile[j].ID & TileData.MaxItemValue].Flags & (TileFlag.Impassable | TileFlag.Surface)) != 0 ) - { - eable.Free(); - return HousePlacementResult.BadStatic; // Broke rule #3 - } - } - } - - eable.Free();*/ - - return HousePlacementResult.Valid; + return yard.Any(t => _houses.Any(b => b.Contains(t))) ? HousePlacementResult.BadStatic : HousePlacementResult.Valid; } } } diff --git a/Projects/Scripts/Multis/HousePlacementTool.cs b/Projects/Scripts/Multis/Houses/HousePlacementTool.cs similarity index 96% rename from Projects/Scripts/Multis/HousePlacementTool.cs rename to Projects/Scripts/Multis/Houses/HousePlacementTool.cs index 6c79e252b..691411efc 100644 --- a/Projects/Scripts/Multis/HousePlacementTool.cs +++ b/Projects/Scripts/Multis/Houses/HousePlacementTool.cs @@ -611,9 +611,7 @@ namespace Server.Items case HousePlacementResult.Valid: { if (from.AccessLevel < AccessLevel.GameMaster && BaseHouse.HasAccountHouse(from)) - { from.SendLocalizedMessage(501271); // You already own a house, you may not place another! - } else { BaseHouse house = ConstructHouse(from); @@ -624,17 +622,13 @@ namespace Server.Items house.Price = Cost; if (from.AccessLevel >= AccessLevel.GameMaster) - { from.SendMessage("{0} gold would have been withdrawn from your bank if you were not a GM.", Cost.ToString()); - } else { if (Banker.Withdraw(from, Cost)) - { from.SendLocalizedMessage(1060398, Cost.ToString()); // ~1_AMOUNT~ gold has been withdrawn from your bank box. - } else { house.RemoveKeys(from); @@ -707,9 +701,7 @@ namespace Server.Items case HousePlacementResult.Valid: { if (from.AccessLevel < AccessLevel.GameMaster && BaseHouse.HasAccountHouse(from)) - { from.SendLocalizedMessage(501271); // You already own a house, you may not place another! - } else { from.SendLocalizedMessage(1011576); // This is a valid location. @@ -804,16 +796,13 @@ namespace Server.Items { m_Table.TryGetValue(house.GetType(), out object obj); - if (obj is HousePlacementEntry entry) - return entry; - - if (obj is List list) - return list.FirstOrDefault(e => e.MultiID == house.ItemID); - - if (obj is Dictionary table) - return table[house.ItemID]; - - return null; + return obj switch + { + HousePlacementEntry entry => entry, + List list => list.FirstOrDefault(e => e.MultiID == house.ItemID), + Dictionary table => table[house.ItemID], + _ => null + }; } private static void FillTable(HousePlacementEntry[] entries) @@ -823,9 +812,7 @@ namespace Server.Items HousePlacementEntry e = entries[i]; if (!m_Table.TryGetValue(e.Type, out object obj)) - { m_Table[e.Type] = e; - } else if (obj is HousePlacementEntry entry) { List list = new List { entry, e }; @@ -848,10 +835,7 @@ namespace Server.Items else list.Add(e); } - else if (obj is Dictionary table) - { - table[e.MultiID] = e; - } + else if (obj is Dictionary table) table[e.MultiID] = e; } } } diff --git a/Projects/Scripts/Multis/HouseSign.cs b/Projects/Scripts/Multis/Houses/HouseSign.cs similarity index 100% rename from Projects/Scripts/Multis/HouseSign.cs rename to Projects/Scripts/Multis/Houses/HouseSign.cs diff --git a/Projects/Scripts/Multis/HouseTeleporter.cs b/Projects/Scripts/Multis/Houses/HouseTeleporter.cs similarity index 100% rename from Projects/Scripts/Multis/HouseTeleporter.cs rename to Projects/Scripts/Multis/Houses/HouseTeleporter.cs diff --git a/Projects/Scripts/Multis/Houses.cs b/Projects/Scripts/Multis/Houses/Houses.cs similarity index 96% rename from Projects/Scripts/Multis/Houses.cs rename to Projects/Scripts/Multis/Houses/Houses.cs index 15b1f9fd0..084f93d67 100644 --- a/Projects/Scripts/Multis/Houses.cs +++ b/Projects/Scripts/Multis/Houses/Houses.cs @@ -581,4 +581,4 @@ namespace Server.Multis int version = reader.ReadInt(); } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Multis/MovingCrate.cs b/Projects/Scripts/Multis/Houses/MovingCrate.cs similarity index 88% rename from Projects/Scripts/Multis/MovingCrate.cs rename to Projects/Scripts/Multis/Houses/MovingCrate.cs index a29857e71..9087a8c96 100644 --- a/Projects/Scripts/Multis/MovingCrate.cs +++ b/Projects/Scripts/Multis/Houses/MovingCrate.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Server.Items; using Server.Network; @@ -49,19 +50,8 @@ namespace Server.Multis public override void DropItem(Item dropped) { // 1. Try to stack the item - foreach (Item item in Items) - if (item is PackingBox) - { - List subItems = item.Items; - - for (int i = 0; i < subItems.Count; i++) - { - Item subItem = subItems[i]; - - if (!(subItem is Container) && subItem.StackWith(null, dropped, false)) - return; - } - } + if (Items.Any(item => item is PackingBox && item.Items.Any(subItem => !(subItem is Container) && subItem.StackWith(null, dropped, false)))) + return; // 2. Try to drop the item into an existing container foreach (Item item in Items) @@ -173,12 +163,7 @@ namespace Server.Multis m_InternalizeTimer = null; } - List toRemove = new List(); - foreach (Item item in Items) - if (item is PackingBox && item.Items.Count == 0) - toRemove.Add(item); - - foreach (Item item in toRemove) + foreach (Item item in Items.Where(item => item is PackingBox && item.Items.Count == 0)) item.Delete(); if (TotalItems == 0) diff --git a/Projects/Scripts/Multis/Houses/Packets.cs b/Projects/Scripts/Multis/Houses/Packets.cs new file mode 100644 index 000000000..797ee49f1 --- /dev/null +++ b/Projects/Scripts/Multis/Houses/Packets.cs @@ -0,0 +1,366 @@ +using System; +using System.Buffers; +using System.Collections.Concurrent; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using Server.Buffers; +using Server.Multis; + +namespace Server.Network +{ + public static class HouseFoundationPackets + { + public static void SendBeginHouseCustomization(NetState ns, Serial house) + { + if (ns == null) + return; + + SpanWriter writer = new SpanWriter(stackalloc byte[17]); + writer.Write((byte)0xBF); // Packet ID + writer.Write((ushort)17); // Dynamic Length + + writer.Write((short)0x20); // House Customization + writer.Write(house); + writer.Write((byte)0x04); // Start customization + writer.Position += 2; + writer.Write(0xFFFFFFFF); + writer.Write((byte)0xFF); + + ns.Send(writer.Span); + } + + public static void SendEndHouseCustomization(NetState ns, Serial house) + { + if (ns == null) + return; + + SpanWriter writer = new SpanWriter(stackalloc byte[17]); + writer.Write((byte)0xBF); // Packet ID + writer.Write((ushort)17); // Dynamic Length + + writer.Write((short)0x20); // House Customization + writer.Write(house); + writer.Write((byte)0x05); // End customization + writer.Position += 2; + writer.Write(0xFFFFFFFF); + writer.Write((byte)0xFF); + + ns.Send(writer.Span); + } + + public static void SendDesignStateGeneral(NetState ns, Serial house, int revision) + { + if (ns == null) + return; + + SpanWriter writer = new SpanWriter(stackalloc byte[13]); + writer.Write((byte)0xBF); // Packet ID + writer.Write((ushort)13); // Dynamic Length + + writer.Write((short)0x1D); // Design + writer.Write(house); + writer.Write(revision); + + ns.Send(writer.Span); + } + + private const int MaxItemsPerStairBuffer = 750; + + private static ConcurrentQueue m_SendQueue; + private static AutoResetEvent m_Sync; + + static HouseFoundationPackets() + { + m_SendQueue = new ConcurrentQueue(); + m_Sync = new AutoResetEvent(false); + Task.Run(ProcessDesignStates); + } + + public static void ProcessDesignStates() + { + while (!Core.Closing) + { + m_Sync.WaitOne(); + + int count = m_SendQueue.Count; + + while (count > 0 && m_SendQueue.TryDequeue(out SendQueueEntry sqe)) + try + { + byte[] packet = sqe.m_DesignState.Packet; + + if (packet == null) + { + packet = CreateDesignDetailsPacket(sqe.m_Serial, sqe.m_Revision, sqe.m_xMin, sqe.m_yMin, sqe.m_xMax, + sqe.m_yMax, sqe.m_Tiles); + sqe.m_DesignState.Packet = packet; + return; + } + + sqe.m_NetState.Send(packet); + } + catch (Exception e) + { + Console.WriteLine(e); + + try + { + using StreamWriter op = new StreamWriter("dsd_exceptions.txt", true); + op.WriteLine(e); + } + catch + { + // ignored + } + } + finally + { + count = m_SendQueue.Count; + } + } + } + + public static byte[] CreateDesignDetailsPacket(Serial serial, int revision, int xMin, int yMin, int xMax, int yMax, + MultiTileEntry[] tiles) + { + ArrayBufferWriter bufferWriter = new ArrayBufferWriter(0x10000); + + SpanWriter headWriter = new SpanWriter(stackalloc byte[18]); + headWriter.Write((byte)0xD8); // Packet ID + headWriter.Position += 2; // Dynamic Length + + headWriter.Write((byte)0x03); // Compression Type + headWriter.Position++; + headWriter.Write(serial); + headWriter.Write(revision); + headWriter.Write((short)tiles.Length); + headWriter.Position += 3; // Buffer/Plane count + + int bufferLength = 1; // includes plane count + + int width = xMax - xMin + 1; + int height = yMax - yMin + 1; + + Span planeUsed = stackalloc bool[9]; + Span planeBuffers = stackalloc byte[9216]; + Span stairBuffers = stackalloc byte[MaxItemsPerStairBuffer * 30]; + + int totalStairsUsed = 0; + + for (int i = 0; i < tiles.Length; ++i) + { + MultiTileEntry mte = tiles[i]; + int x = mte.m_OffsetX - xMin; + int y = mte.m_OffsetY - yMin; + int z = mte.m_OffsetZ; + bool floor = TileData.ItemTable[mte.m_ItemID & TileData.MaxItemValue].Height <= 0; + int plane, size; + + switch (z) + { + case 0: + plane = 0; + break; + case 7: + plane = 1; + break; + case 27: + plane = 2; + break; + case 47: + plane = 3; + break; + case 67: + plane = 4; + break; + default: + { + int stairBufferIndex = totalStairsUsed / MaxItemsPerStairBuffer; + Span stairBuffer = stairBuffers.Slice(stairBufferIndex, MaxItemsPerStairBuffer); + + int byteIndex = totalStairsUsed % MaxItemsPerStairBuffer * 5; + + stairBuffer[byteIndex++] = (byte)(mte.m_ItemID >> 8); + stairBuffer[byteIndex++] = (byte)mte.m_ItemID; + + stairBuffer[byteIndex++] = (byte)mte.m_OffsetX; + stairBuffer[byteIndex++] = (byte)mte.m_OffsetY; + stairBuffer[byteIndex] = (byte)mte.m_OffsetZ; + + ++totalStairsUsed; + + continue; + } + } + + if (plane == 0) + size = height; + else if (floor) + { + size = height - 2; + x -= 1; + y -= 1; + } + else + { + size = height - 1; + plane += 4; + } + + int index = (x * size + y) * 2; + + if (x < 0 || y < 0 || y >= size || index + 1 >= 0x400) + { + int stairBufferIndex = totalStairsUsed / MaxItemsPerStairBuffer; + Span stairBuffer = stairBuffers.Slice(stairBufferIndex, MaxItemsPerStairBuffer); + + int byteIndex = totalStairsUsed % MaxItemsPerStairBuffer * 5; + + stairBuffer[byteIndex++] = (byte)(mte.m_ItemID >> 8); + stairBuffer[byteIndex++] = (byte)mte.m_ItemID; + + stairBuffer[byteIndex++] = (byte)mte.m_OffsetX; + stairBuffer[byteIndex++] = (byte)mte.m_OffsetY; + stairBuffer[byteIndex] = (byte)mte.m_OffsetZ; + + ++totalStairsUsed; + } + else + { + planeUsed[plane] = true; + planeBuffers[plane * 0x400 + index] = (byte)(mte.m_ItemID >> 8); + planeBuffers[plane * 0x400 + index + 1] = (byte)mte.m_ItemID; + } + } + + int planeCount = 0; + int bound = (int)Compression.Compressor.CompressBound(0x400); + + for (int i = 0; i < 9; ++i) + { + if (!planeUsed[i]) + continue; + + ++planeCount; + + int size; + + if (i == 0) + size = width * height * 2; + else if (i < 5) + size = (width - 1) * (height - 2) * 2; + else + size = width * (height - 1) * 2; + + Span inflatedBuffer = planeBuffers.Slice(i * 0x400, 0x400); + Span deflatedBuffer = bufferWriter.GetSpan(bound + 4); + + ulong deflatedLength = (ulong)bound; + ZLibError ce = Compression.Pack(deflatedBuffer.Slice(4), ref deflatedLength, inflatedBuffer, (ulong)size, ZLibQuality.Default); + + if (ce != ZLibError.Okay) + { + Console.WriteLine("ZLib error: {0} (#{1})", ce, (int)ce); + size = 0; + } + + int length = (int)deflatedLength; + + deflatedBuffer[0] = (byte)(0x20 | i); + deflatedBuffer[1] = (byte)size; + deflatedBuffer[2] = (byte)length; + deflatedBuffer[3] = (byte)(((size >> 4) & 0xF0) | ((length >> 8) & 0xF)); + + bufferLength += 4 + length; + bufferWriter.Advance(length + 4); + } + + int totalStairBuffersUsed = (totalStairsUsed + (MaxItemsPerStairBuffer - 1)) / MaxItemsPerStairBuffer; + bound = (int)Compression.Compressor.CompressBound(MaxItemsPerStairBuffer); + + for (int i = 0; i < totalStairBuffersUsed; ++i) + { + ++planeCount; + + int count = totalStairsUsed - i * MaxItemsPerStairBuffer; + + if (count > MaxItemsPerStairBuffer) + count = MaxItemsPerStairBuffer; + + int size = count * 5; + + Span inflatedBuffer = stairBuffers.Slice(i * MaxItemsPerStairBuffer, MaxItemsPerStairBuffer); + Span deflatedBuffer = bufferWriter.GetSpan(bound + 4); + + ulong deflatedLength = (ulong)bound; + ZLibError ce = Compression.Pack(deflatedBuffer.Slice(4), ref deflatedLength, inflatedBuffer, (ulong)size, ZLibQuality.Default); + + if (ce != ZLibError.Okay) + { + Console.WriteLine("ZLib error: {0} (#{1})", ce, (int)ce); + deflatedLength = 0; + size = 0; + } + + int length = (int)deflatedLength; + + deflatedBuffer[0] = (byte)(9 + i); + deflatedBuffer[1] = (byte)size; + deflatedBuffer[2] = (byte)length; + deflatedBuffer[3] = (byte)(((size >> 4) & 0xF0) | ((length >> 8) & 0xF)); + + bufferLength += 4 + length; + bufferWriter.Advance(length + 4); + } + + headWriter.Position = 15; + + headWriter.Write((short)bufferLength); // Buffer length + headWriter.Write((byte)planeCount); // Plane count + + headWriter.Position = 1; + int written = headWriter.WrittenCount + bufferWriter.WrittenCount; + headWriter.Write((ushort)written); + + byte[] packet = new byte[written]; + headWriter.CopyTo(packet); + bufferWriter.WrittenSpan.CopyTo(packet.AsSpan(headWriter.WrittenCount)); + + return packet; + } + + private class SendQueueEntry + { + public NetState m_NetState; + public DesignState m_DesignState; + public int m_Revision; + public uint m_Serial; + public MultiTileEntry[] m_Tiles; + public int m_xMin, m_yMin, m_xMax, m_yMax; + + public SendQueueEntry(NetState ns, HouseFoundation foundation, DesignState state) + { + m_NetState = ns; + m_Serial = foundation.Serial; + m_Revision = state.Revision; + m_DesignState = state; + + MultiComponentList mcl = state.Components; + + m_xMin = mcl.Min.X; + m_yMin = mcl.Min.Y; + m_xMax = mcl.Max.X; + m_yMax = mcl.Max.Y; + + m_Tiles = mcl.List; + } + } + + public static void SendDesignDetails(NetState ns, HouseFoundation house, DesignState state) + { + m_SendQueue.Enqueue(new SendQueueEntry(ns, house, state)); + m_Sync.Set(); + } + } +} diff --git a/Projects/Scripts/Multis/PreviewHouse.cs b/Projects/Scripts/Multis/Houses/PreviewHouse.cs similarity index 100% rename from Projects/Scripts/Multis/PreviewHouse.cs rename to Projects/Scripts/Multis/Houses/PreviewHouse.cs diff --git a/Projects/Scripts/Network/Packets.cs b/Projects/Scripts/Network/Packets.cs new file mode 100644 index 000000000..7bcbb06b7 --- /dev/null +++ b/Projects/Scripts/Network/Packets.cs @@ -0,0 +1,24 @@ +using Server.Buffers; + +namespace Server.Network +{ + public static class ContentPackets + { + public static void SendDisplayHelpTopic(NetState ns, int topicID, bool display) + { + if (ns == null) + return; + + SpanWriter writer = new SpanWriter(stackalloc byte[11]); + writer.Write((byte)0xBF); // Packet ID + writer.Write((ushort)11); // Dynamic Length + + writer.Write((short)0x17); // Command + writer.Write((byte)1); + writer.Write(topicID); + writer.Write(display); + + ns.Send(writer.Span); + } + } +} diff --git a/Projects/Scripts/Regions/GuardedRegion.cs b/Projects/Scripts/Regions/GuardedRegion.cs index 39a6df5d8..c12319f00 100644 --- a/Projects/Scripts/Regions/GuardedRegion.cs +++ b/Projects/Scripts/Regions/GuardedRegion.cs @@ -90,17 +90,14 @@ namespace Server.Regions GuardedRegion reg = from.Region.GetRegion(); if (reg == null) - { from.SendMessage("You are not in a guardable region."); - } else { reg.Disabled = !e.GetBoolean(0); - if (reg.Disabled) - from.SendMessage("The guards in this region have been disabled."); - else - from.SendMessage("The guards in this region have been enabled."); + from.SendMessage(reg.Disabled + ? "The guards in this region have been disabled." + : "The guards in this region have been enabled."); } } else @@ -193,12 +190,6 @@ namespace Server.Regions CheckGuardCandidate(m); } - public override void OnExit(Mobile m) - { -// if (IsDisabled()) - return; - } - public override void OnSpeech(SpeechEventArgs args) { base.OnSpeech(args); diff --git a/Projects/Scripts/Regions/Spawning/SpawnEntry.cs b/Projects/Scripts/Regions/Spawning/SpawnEntry.cs index 471577845..4ff99d1eb 100644 --- a/Projects/Scripts/Regions/Spawning/SpawnEntry.cs +++ b/Projects/Scripts/Regions/Spawning/SpawnEntry.cs @@ -264,9 +264,7 @@ namespace Server.Regions if (entity != null) { - if (m_RemoveList == null) - m_RemoveList = new List(); - + m_RemoveList ??= new List(); m_RemoveList.Add(entity); } } diff --git a/Projects/Scripts/Regions/Spawning/SpawnPersistence.cs b/Projects/Scripts/Regions/Spawning/SpawnPersistence.cs index e4c827e68..7999f8718 100644 --- a/Projects/Scripts/Regions/Spawning/SpawnPersistence.cs +++ b/Projects/Scripts/Regions/Spawning/SpawnPersistence.cs @@ -15,8 +15,7 @@ namespace Server.Regions public static void EnsureExistence() { - if (m_Instance == null) - m_Instance = new SpawnPersistence(); + m_Instance ??= new SpawnPersistence(); } public override void Serialize(GenericWriter writer) @@ -54,4 +53,4 @@ namespace Server.Regions } } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Scripts.csproj b/Projects/Scripts/Scripts.csproj index f3b49987e..cf2ce83f4 100644 --- a/Projects/Scripts/Scripts.csproj +++ b/Projects/Scripts/Scripts.csproj @@ -15,6 +15,7 @@ ..\..\Distribution\Assemblies ..\..\Distribution\Assemblies ..\..\Distribution\Assemblies + ..\..\Distribution\Assemblies TRACE;DEBUG diff --git a/Projects/Scripts/Skills/Anatomy.cs b/Projects/Scripts/Skills/Anatomy.cs index e4ab479a5..e6580f8be 100644 --- a/Projects/Scripts/Skills/Anatomy.cs +++ b/Projects/Scripts/Skills/Anatomy.cs @@ -83,7 +83,7 @@ namespace Server.SkillHandlers } else { - (targeted as Item)?.SendLocalizedMessageTo(from, 500323, ""); // Only living things have anatomies! + (targeted as Item)?.SendLocalizedMessageTo(from, 500323); // Only living things have anatomies! } } } diff --git a/Projects/Scripts/Skills/AnimalTaming.cs b/Projects/Scripts/Skills/AnimalTaming.cs index a24a80936..040f55549 100644 --- a/Projects/Scripts/Skills/AnimalTaming.cs +++ b/Projects/Scripts/Skills/AnimalTaming.cs @@ -338,8 +338,7 @@ namespace Server.SkillHandlers if (!alreadyOwned) // Passively check animal lore for gain m_Tamer.CheckTargetSkill(SkillName.AnimalLore, m_Creature, 0.0, 120.0); - if (m_Creature.Paralyzed) - m_Paralyzed = true; + m_Paralyzed |= m_Creature.Paralyzed; } else { @@ -347,8 +346,7 @@ namespace Server.SkillHandlers m_Tamer.NextSkillTime = Core.TickCount; m_BeingTamed.Remove(m_Creature); - if (m_Creature.Paralyzed) - m_Paralyzed = true; + m_Paralyzed |= m_Creature.Paralyzed; if (!alreadyOwned) // Passively check animal lore for gain m_Tamer.CheckTargetSkill(SkillName.AnimalLore, m_Creature, 0.0, 120.0); diff --git a/Projects/Scripts/Skills/Discordance.cs b/Projects/Scripts/Skills/Discordance.cs index 25ea05e79..f003c124a 100644 --- a/Projects/Scripts/Skills/Discordance.cs +++ b/Projects/Scripts/Skills/Discordance.cs @@ -50,16 +50,13 @@ namespace Server.SkillHandlers // According to uoherald bard must remain alive, visible, and // within range of the target or the effect ends in 15 seconds. if (!targ.Alive || targ.Deleted || !from.Alive || from.Hidden) - { ends = true; - } else { int range = (int)targ.GetDistanceToSqrt(from); int maxRange = BaseInstrument.GetBardRange(from, SkillName.Discordance); - if (from.Map != targ.Map || range > maxRange) - ends = true; + ends |= from.Map != targ.Map || range > maxRange; } if (ends && info.m_Ending && info.m_EndTime < DateTime.UtcNow) diff --git a/Projects/Scripts/Skills/EvalInt.cs b/Projects/Scripts/Skills/EvalInt.cs index 60524153f..1e61bbc66 100644 --- a/Projects/Scripts/Skills/EvalInt.cs +++ b/Projects/Scripts/Skills/EvalInt.cs @@ -84,8 +84,7 @@ namespace Server.SkillHandlers } else { - (targeted as Item)?.SendLocalizedMessageTo(from, 500908, - ""); // It looks smarter than a rock, but dumber than a piece of wood. + (targeted as Item)?.SendLocalizedMessageTo(from, 500908); // It looks smarter than a rock, but dumber than a piece of wood. } } } diff --git a/Projects/Scripts/Skills/Hiding.cs b/Projects/Scripts/Skills/Hiding.cs index c136c666e..7143ffffd 100644 --- a/Projects/Scripts/Skills/Hiding.cs +++ b/Projects/Scripts/Skills/Hiding.cs @@ -30,13 +30,10 @@ namespace Server.SkillHandlers BaseHouse house = BaseHouse.FindHouseAt(m); if (house?.IsFriend(m) == true) - { bonus = 100.0; - } else if (!Core.AOS) { - if (house == null) - house = BaseHouse.FindHouseAt(new Point3D(m.X - 1, m.Y, 127), m.Map, 16) ?? + house ??= BaseHouse.FindHouseAt(new Point3D(m.X - 1, m.Y, 127), m.Map, 16) ?? BaseHouse.FindHouseAt(new Point3D(m.X + 1, m.Y, 127), m.Map, 16) ?? BaseHouse.FindHouseAt(new Point3D(m.X, m.Y - 1, 127), m.Map, 16) ?? BaseHouse.FindHouseAt(new Point3D(m.X, m.Y + 1, 127), m.Map, 16); @@ -80,7 +77,6 @@ namespace Server.SkillHandlers else { m.RevealingAction(); - m.LocalOverheadMessage(MessageType.Regular, 0x22, 501241); // You can't seem to hide here. } diff --git a/Projects/Scripts/Skills/ItemIdentification.cs b/Projects/Scripts/Skills/ItemIdentification.cs index e3a168a19..bedc35364 100644 --- a/Projects/Scripts/Skills/ItemIdentification.cs +++ b/Projects/Scripts/Skills/ItemIdentification.cs @@ -39,19 +39,13 @@ namespace Server.Items item.OnSingleClick(from); } else - { from.SendLocalizedMessage(500353); // You are not certain... - } } else if (o is Mobile mobile) - { mobile.OnSingleClick(from); - } else - { from.SendLocalizedMessage(500353); // You are not certain... - } } } } -} \ No newline at end of file +} diff --git a/Projects/Scripts/Skills/SpiritSpeak.cs b/Projects/Scripts/Skills/SpiritSpeak.cs index d24077635..94e184297 100644 --- a/Projects/Scripts/Skills/SpiritSpeak.cs +++ b/Projects/Scripts/Skills/SpiritSpeak.cs @@ -127,7 +127,7 @@ namespace Server.SkillHandlers public override void OnCast() { IPooledEnumerable eable = Caster.GetItemsInRange(3); - Corpse toChannel = eable.FirstOrDefault(item => item is Corpse corpse && !corpse.Channeled); + Corpse toChannel = eable.FirstOrDefault(corpse => corpse?.Channeled == false); eable.Free(); int min = 1 + (int)(Caster.Skills.SpiritSpeak.Value * 0.25); diff --git a/Projects/Scripts/Skills/Tracking.cs b/Projects/Scripts/Skills/Tracking.cs index 391c88e0b..5f071b20b 100644 --- a/Projects/Scripts/Skills/Tracking.cs +++ b/Projects/Scripts/Skills/Tracking.cs @@ -106,7 +106,7 @@ namespace Server.SkillHandlers AddHtmlLocalized(320, 90, 100, 20, 1018090); // Players } - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { if (info.ButtonID >= 1 && info.ButtonID <= 4) TrackWhoGump.DisplayTo(m_Success, m_From, info.ButtonID - 1); @@ -261,7 +261,7 @@ namespace Server.SkillHandlers private static bool IsPlayer(Mobile m) => m.Player; - public override void OnResponse(NetState state, RelayInfo info) + public override void OnResponse(NetState sender, RelayInfo info) { int index = info.ButtonID - 1; diff --git a/Projects/Scripts/SpecialSystems/Engines/TestCenter.cs b/Projects/Scripts/SpecialSystems/Engines/TestCenter.cs index 5e8944f8a..b60d06ebd 100644 --- a/Projects/Scripts/SpecialSystems/Engines/TestCenter.cs +++ b/Projects/Scripts/SpecialSystems/Engines/TestCenter.cs @@ -59,9 +59,7 @@ namespace Server.Misc private static void ChangeStrength(Mobile from, int value) { if (value < 10 || value > 125) - { from.SendLocalizedMessage(1005628); // Stats range between 10 and 125. - } else { if (value + from.RawDex + from.RawInt > from.StatCap) @@ -80,9 +78,7 @@ namespace Server.Misc private static void ChangeDexterity(Mobile from, int value) { if (value < 10 || value > 125) - { from.SendLocalizedMessage(1005628); // Stats range between 10 and 125. - } else { if (from.RawStr + value + from.RawInt > from.StatCap) @@ -101,9 +97,7 @@ namespace Server.Misc private static void ChangeIntelligence(Mobile from, int value) { if (value < 10 || value > 125) - { from.SendLocalizedMessage(1005628); // Stats range between 10 and 125. - } else { if (from.RawStr + from.RawDex + value > from.StatCap) @@ -132,9 +126,7 @@ namespace Server.Misc if (skill != null) { if (value < 0 || value > skill.Cap) - { from.SendMessage($"Your skill in {skill.Info.Name} is capped at {skill.Cap:F1}."); - } else { int newFixedPoint = (int)(value * 10.0); @@ -147,9 +139,7 @@ namespace Server.Misc } } else - { from.SendLocalizedMessage(1005631); // You have specified an invalid skill to set. - } } @@ -199,8 +189,8 @@ namespace Server.Misc if (sb.Length + 1 + v.Length >= 256) { - sender.Send(new AsciiMessage(Server.Serial.MinusOne, -1, MessageType.Label, 0x35, 3, - "System", sb.ToString())); + Packets.SendAsciiMessage(sender, Server.Serial.MinusOne, -1, MessageType.Label, 0x35, 3, + "System", sb.ToString()); sb = new StringBuilder(); sb.Append(v); } @@ -212,8 +202,8 @@ namespace Server.Misc } if (sb.Length > 0) - sender.Send(new AsciiMessage(Server.Serial.MinusOne, -1, MessageType.Label, 0x35, 3, "System", - sb.ToString())); + Packets.SendAsciiMessage(sender, Server.Serial.MinusOne, -1, MessageType.Label, 0x35, 3, "System", + sb.ToString()); break; } diff --git a/Projects/Scripts/SpecialSystems/Items/Stones/GMStone.cs b/Projects/Scripts/SpecialSystems/Items/Stones/GMStone.cs deleted file mode 100644 index 4b7023151..000000000 --- a/Projects/Scripts/SpecialSystems/Items/Stones/GMStone.cs +++ /dev/null @@ -1,56 +0,0 @@ -#if false -using System; -using Server.Network; -using Server.Commands; - -namespace Server.Items -{ - public class GMStone : Item - { - public override string DefaultName - { - get { return "a GM stone"; } - } - - [Constructible] - public GMStone() : base( 0xED4 ) - { - Movable = false; - Hue = 0x489; - } - - public GMStone( Serial serial ) : base( serial ) - { - } - - public override void Serialize( GenericWriter writer ) - { - base.Serialize( writer ); - - writer.Write( (int) 0 ); // version - } - - public override void Deserialize( GenericReader reader ) - { - base.Deserialize( reader ); - - int version = reader.ReadInt(); - } - - public override void OnDoubleClick( Mobile from ) - { - if ( from.AccessLevel < AccessLevel.GameMaster ) - { - from.AccessLevel = AccessLevel.GameMaster; - - from.SendAsciiMessage( 0x482, "The command prefix is \"{0}\"", CommandSystem.Prefix ); - CommandHandlers.Help_OnCommand( new CommandEventArgs( from, "help", "", new string[0] ) ); - } - else - { - from.SendMessage( "The stone has no effect." ); - } - } - } -} -#endif \ No newline at end of file diff --git a/Projects/Scripts/Spells/Base/SpecialMove.cs b/Projects/Scripts/Spells/Base/SpecialMove.cs index c46f4b88f..d42a7a5e1 100644 --- a/Projects/Scripts/Spells/Base/SpecialMove.cs +++ b/Projects/Scripts/Spells/Base/SpecialMove.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Server.Engines.ConPVP; using Server.Items; using Server.Network; @@ -11,7 +12,7 @@ namespace Server.Spells { public abstract class SpecialMove { - private static Dictionary m_PlayersTable = new Dictionary(); + private static readonly Dictionary m_PlayersTable = new Dictionary(); public virtual int BaseMana => 0; @@ -181,13 +182,8 @@ namespace Server.Spells public static void ClearAllMoves(Mobile m) { - foreach (KeyValuePair kvp in SpellRegistry.SpecialMoves) - { - int moveID = kvp.Key; - - if (moveID != -1) - m.Send(new ToggleSpecialAbility(moveID + 1, false)); - } + foreach (var (moveID, _) in SpellRegistry.SpecialMoves.Where(kvp => kvp.Key != -1)) + Packets.SendToggleSpecialAbility(m.NetState, (short)(moveID + 1), false); } public static SpecialMove GetCurrentMove(Mobile m) @@ -242,7 +238,7 @@ namespace Server.Spells int moveID = SpellRegistry.GetRegistryNumber(move); if (moveID > 0) - m.Send(new ToggleSpecialAbility(moveID + 1, true)); + Packets.SendToggleSpecialAbility(m.NetState, (short)(moveID + 1), true); TextDefinition.SendMessageTo(m, move.AbilityMessage); } @@ -259,7 +255,7 @@ namespace Server.Spells int moveID = SpellRegistry.GetRegistryNumber(move); if (moveID > 0) - m.Send(new ToggleSpecialAbility(moveID + 1, false)); + Packets.SendToggleSpecialAbility(m.NetState, (short)(moveID + 1), false); } Table.Remove(m); diff --git a/Projects/Scripts/Spells/Base/SpellHelper.cs b/Projects/Scripts/Spells/Base/SpellHelper.cs index a197a62c8..6512ad3db 100644 --- a/Projects/Scripts/Spells/Base/SpellHelper.cs +++ b/Projects/Scripts/Spells/Base/SpellHelper.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Server.Engines.CannedEvil; using Server.Engines.ConPVP; using Server.Engines.PartySystem; @@ -148,13 +149,8 @@ namespace Server.Spells public static bool DisableSkillCheck{ get; set; } - public static TimeSpan GetDamageDelayForSpell(Spell sp) - { - if (!sp.DelayedDamage) - return TimeSpan.Zero; - - return Core.AOS ? AosDamageDelay : OldDamageDelay; - } + public static TimeSpan GetDamageDelayForSpell(Spell sp) => + !sp.DelayedDamage ? TimeSpan.Zero : Core.AOS ? AosDamageDelay : OldDamageDelay; public static bool CheckMulti(Point3D p, Map map, bool houses = true, int housingrange = 0) { @@ -173,9 +169,7 @@ namespace Server.Spells return true; } else if (multi.Contains(p)) - { return true; - } } return false; @@ -191,36 +185,15 @@ namespace Server.Spells if (item.RootParent != from) from.Direction = from.GetDirectionTo(item.GetWorldLocation()); } - else if (from != target) - { + else if (!ReferenceEquals(from, target)) from.Direction = from.GetDirectionTo(target); - } } - public static bool CheckCombat(Mobile m) - { - if (!RestrictTravelCombat) - return false; - - for (int i = 0; i < m.Aggressed.Count; ++i) - { - AggressorInfo info = m.Aggressed[i]; - - if (info.Defender.Player && DateTime.UtcNow - info.LastCombatTime < CombatHeatDelay) - return true; - } - - if (Core.Expansion == Expansion.AOS) - for (int i = 0; i < m.Aggressors.Count; ++i) - { - AggressorInfo info = m.Aggressors[i]; - - if (info.Attacker.Player && DateTime.UtcNow - info.LastCombatTime < CombatHeatDelay) - return true; - } - - return false; - } + public static bool CheckCombat(Mobile m) => + RestrictTravelCombat && + (m.Aggressed.Any(info => info.Defender.Player && DateTime.UtcNow - info.LastCombatTime < CombatHeatDelay) || + Core.Expansion == Expansion.AOS && m.Aggressors.Any(info => + info.Attacker.Player && DateTime.UtcNow - info.LastCombatTime < CombatHeatDelay)); public static bool AdjustField(ref Point3D p, Map map, int height, bool mobsBlock) { @@ -246,9 +219,7 @@ namespace Server.Spells public static void GetSurfaceTop(ref IPoint3D p) { if (p is Item item) - { p = item.GetSurfaceTop(); - } else if (p is StaticTarget t) { int z = t.Z; @@ -260,15 +231,10 @@ namespace Server.Spells } } - public static bool AddStatOffset(Mobile m, StatType type, int offset, TimeSpan duration) - { - if (offset > 0) - return AddStatBonus(m, m, type, offset, duration); - if (offset < 0) - return AddStatCurse(m, m, type, -offset, duration); - - return true; - } + public static bool AddStatOffset(Mobile m, StatType type, int offset, TimeSpan duration) => + offset > 0 + ? AddStatBonus(m, m, type, offset, duration) + : offset >= 0 || AddStatCurse(m, m, type, -offset, duration); public static bool AddStatBonus(Mobile caster, Mobile target, StatType type) => AddStatBonus(caster, target, type, GetOffset(caster, target, type, false), GetDuration(caster, target)); @@ -604,7 +570,7 @@ namespace Server.Spells // Always allow monsters to teleport if (caster is BaseCreature bc && !bc.Controlled && !bc.Summoned && (type == TravelCheckType.TeleportTo || type == TravelCheckType.TeleportFrom)) - return true; + return true; m_TravelCaster = caster; m_TravelType = type; diff --git a/Projects/Scripts/Spells/Bushido/SamuraiSpell.cs b/Projects/Scripts/Spells/Bushido/SamuraiSpell.cs index 4af7c7ca7..61fe27436 100644 --- a/Projects/Scripts/Spells/Bushido/SamuraiSpell.cs +++ b/Projects/Scripts/Spells/Bushido/SamuraiSpell.cs @@ -106,7 +106,7 @@ namespace Server.Spells.Bushido int spellID = SpellRegistry.GetRegistryNumber(this); if (spellID > 0) - caster.Send(new ToggleSpecialAbility(spellID + 1, true)); + Packets.SendToggleSpecialAbility(caster.NetState, (short)(spellID + 1), true); } public static void OnEffectEnd(Mobile caster, Type type) @@ -114,7 +114,7 @@ namespace Server.Spells.Bushido int spellID = SpellRegistry.GetRegistryNumber(type); if (spellID > 0) - caster.Send(new ToggleSpecialAbility(spellID + 1, false)); + Packets.SendToggleSpecialAbility(caster.NetState, (short)(spellID + 1), false); } } } diff --git a/Projects/Scripts/Spells/Chivalry/DispelEvil.cs b/Projects/Scripts/Spells/Chivalry/DispelEvil.cs index d76a6bebc..9677bb90c 100644 --- a/Projects/Scripts/Spells/Chivalry/DispelEvil.cs +++ b/Projects/Scripts/Spells/Chivalry/DispelEvil.cs @@ -74,7 +74,7 @@ namespace Server.Spells.Chivalry if (evil) { // TODO: Is this right? - double fleeChance = (100 - Math.Sqrt(m.Fame / 2)) * chiv * dispelSkill; + double fleeChance = (100 - Math.Sqrt(m.Fame / 2.0)) * chiv * dispelSkill; fleeChance /= 1000000; if (fleeChance > Utility.RandomDouble()) bc.BeginFlee(TimeSpan.FromSeconds(30.0)); diff --git a/Projects/Scripts/Spells/Chivalry/NobleSacrifice.cs b/Projects/Scripts/Spells/Chivalry/NobleSacrifice.cs index 1bb57d30a..dc091a26a 100644 --- a/Projects/Scripts/Spells/Chivalry/NobleSacrifice.cs +++ b/Projects/Scripts/Spells/Chivalry/NobleSacrifice.cs @@ -135,16 +135,10 @@ namespace Server.Spells.Chivalry sendEffect = true; } - if (EvilOmenSpell.TryEndEffect(m)) - sendEffect = true; - - if (StrangleSpell.RemoveCurse(m)) - sendEffect = true; - - if (CorpseSkinSpell.RemoveCurse(m)) - sendEffect = true; - // TODO: Should this remove blood oath? Pain spike? + sendEffect |= EvilOmenSpell.TryEndEffect(m); + sendEffect |= StrangleSpell.RemoveCurse(m); + sendEffect |= CorpseSkinSpell.RemoveCurse(m); if (sendEffect) { diff --git a/Projects/Scripts/Spells/Chivalry/SacredJourney.cs b/Projects/Scripts/Spells/Chivalry/SacredJourney.cs index 5ca1a4152..58d14c605 100644 --- a/Projects/Scripts/Spells/Chivalry/SacredJourney.cs +++ b/Projects/Scripts/Spells/Chivalry/SacredJourney.cs @@ -76,13 +76,9 @@ namespace Server.Spells.Chivalry public void Effect(Point3D loc, Map map, bool checkMulti) { if (Sigil.ExistsOn(Caster)) - { Caster.SendLocalizedMessage(1061632); // You can't do that while carrying the sigil. - } else if (map == null || !Core.AOS && Caster.Map != map) - { Caster.SendLocalizedMessage(1005569); // You can not recall to another facet. - } else if (!SpellHelper.CheckTravel(Caster, TravelCheckType.RecallFrom)) { } @@ -90,37 +86,21 @@ namespace Server.Spells.Chivalry { } else if (map == Map.Felucca && Caster is PlayerMobile mobile && mobile.Young) - { mobile.SendLocalizedMessage(1049543); // You decide against traveling to Felucca while you are still young. - } else if (Caster.Kills >= 5 && map != Map.Felucca) - { Caster.SendLocalizedMessage(1019004); // You are not allowed to travel there. - } else if (Caster.Criminal) - { Caster.SendLocalizedMessage(1005561, "", 0x22); // Thou'rt a criminal and cannot escape so easily. - } else if (SpellHelper.CheckCombat(Caster)) - { Caster.SendLocalizedMessage(1061282); // You cannot use the Sacred Journey ability to flee from combat. - } else if (WeightOverloading.IsOverloaded(Caster)) - { Caster.SendLocalizedMessage(502359, "", 0x22); // Thou art too encumbered to move. - } else if (!map.CanSpawnMobile(loc.X, loc.Y, loc.Z)) - { Caster.SendLocalizedMessage(501942); // That location is blocked. - } else if (checkMulti && SpellHelper.CheckMulti(loc, map)) - { Caster.SendLocalizedMessage(501942); // That location is blocked. - } else if (m_Book != null && m_Book.CurCharges <= 0) - { Caster.SendLocalizedMessage(502412); // There are no charges left on that item. - } else if (CheckSequence()) { BaseCreature.TeleportPets(Caster, loc, map, true); diff --git a/Projects/Scripts/Spells/Eighth/AirElemental.cs b/Projects/Scripts/Spells/Eighth/AirElemental.cs index 0aec5b631..fb5c60b0f 100644 --- a/Projects/Scripts/Spells/Eighth/AirElemental.cs +++ b/Projects/Scripts/Spells/Eighth/AirElemental.cs @@ -39,7 +39,7 @@ namespace Server.Spells.Eighth { if (CheckSequence()) { - TimeSpan duration = TimeSpan.FromSeconds(2 * Caster.Skills.Magery.Fixed / 5); + TimeSpan duration = TimeSpan.FromSeconds(2 * Caster.Skills.Magery.Fixed / 5.0); if (Core.AOS) SpellHelper.Summon(new SummonedAirElemental(), Caster, 0x217, duration, false, false); diff --git a/Projects/Scripts/Spells/Eighth/EarthElemental.cs b/Projects/Scripts/Spells/Eighth/EarthElemental.cs index 18dfceb2a..53c93a25b 100644 --- a/Projects/Scripts/Spells/Eighth/EarthElemental.cs +++ b/Projects/Scripts/Spells/Eighth/EarthElemental.cs @@ -39,7 +39,7 @@ namespace Server.Spells.Eighth { if (CheckSequence()) { - TimeSpan duration = TimeSpan.FromSeconds(2 * Caster.Skills.Magery.Fixed / 5); + TimeSpan duration = TimeSpan.FromSeconds(2 * Caster.Skills.Magery.Fixed / 5.0); if (Core.AOS) SpellHelper.Summon(new SummonedEarthElemental(), Caster, 0x217, duration, false, false); diff --git a/Projects/Scripts/Spells/Eighth/FireElemental.cs b/Projects/Scripts/Spells/Eighth/FireElemental.cs index 62e37ff46..4c20faa05 100644 --- a/Projects/Scripts/Spells/Eighth/FireElemental.cs +++ b/Projects/Scripts/Spells/Eighth/FireElemental.cs @@ -40,7 +40,7 @@ namespace Server.Spells.Eighth { if (CheckSequence()) { - TimeSpan duration = TimeSpan.FromSeconds(2 * Caster.Skills.Magery.Fixed / 5); + TimeSpan duration = TimeSpan.FromSeconds(2 * Caster.Skills.Magery.Fixed / 5.0); if (Core.AOS) SpellHelper.Summon(new SummonedFireElemental(), Caster, 0x217, duration, false, false); diff --git a/Projects/Scripts/Spells/Eighth/SummonDaemon.cs b/Projects/Scripts/Spells/Eighth/SummonDaemon.cs index b5853ac02..eb97176f4 100644 --- a/Projects/Scripts/Spells/Eighth/SummonDaemon.cs +++ b/Projects/Scripts/Spells/Eighth/SummonDaemon.cs @@ -40,7 +40,7 @@ namespace Server.Spells.Eighth { if (CheckSequence()) { - TimeSpan duration = TimeSpan.FromSeconds(2 * Caster.Skills.Magery.Fixed / 5); + TimeSpan duration = TimeSpan.FromSeconds(2 * Caster.Skills.Magery.Fixed / 5.0); if (Core.AOS) /* Why two diff daemons? TODO: solve this */ { diff --git a/Projects/Scripts/Spells/Eighth/WaterElemental.cs b/Projects/Scripts/Spells/Eighth/WaterElemental.cs index 122871ba5..a0672ffce 100644 --- a/Projects/Scripts/Spells/Eighth/WaterElemental.cs +++ b/Projects/Scripts/Spells/Eighth/WaterElemental.cs @@ -39,7 +39,7 @@ namespace Server.Spells.Eighth { if (CheckSequence()) { - TimeSpan duration = TimeSpan.FromSeconds(2 * Caster.Skills.Magery.Fixed / 5); + TimeSpan duration = TimeSpan.FromSeconds(2 * Caster.Skills.Magery.Fixed / 5.0); if (Core.AOS) SpellHelper.Summon(new SummonedWaterElemental(), Caster, 0x217, duration, false, false); diff --git a/Projects/Scripts/Spells/Fifth/PoisonField.cs b/Projects/Scripts/Spells/Fifth/PoisonField.cs index 4eb0f9aae..3d3eefff2 100644 --- a/Projects/Scripts/Spells/Fifth/PoisonField.cs +++ b/Projects/Scripts/Spells/Fifth/PoisonField.cs @@ -47,16 +47,7 @@ namespace Server.Spells.Fifth int rx = (dx - dy) * 44; int ry = (dx + dy) * 44; - bool eastToWest; - - if (rx >= 0 && ry >= 0) - eastToWest = false; - else if (rx >= 0) - eastToWest = true; - else if (ry >= 0) - eastToWest = true; - else - eastToWest = false; + bool eastToWest = (rx < 0 || ry < 0) && (rx >= 0 || ry >= 0); Effects.PlaySound(p, Caster.Map, 0x20B); diff --git a/Projects/Scripts/Spells/Fifth/SummonCreature.cs b/Projects/Scripts/Spells/Fifth/SummonCreature.cs index 4786ce796..2450b148b 100644 --- a/Projects/Scripts/Spells/Fifth/SummonCreature.cs +++ b/Projects/Scripts/Spells/Fifth/SummonCreature.cs @@ -70,7 +70,7 @@ namespace Server.Spells.Fifth TimeSpan duration; if (Core.AOS) - duration = TimeSpan.FromSeconds(2 * Caster.Skills.Magery.Fixed / 5); + duration = TimeSpan.FromSeconds(2 * Caster.Skills.Magery.Fixed / 5.0); else duration = TimeSpan.FromSeconds(4.0 * Caster.Skills.Magery.Value); diff --git a/Projects/Scripts/Spells/First/Clumsy.cs b/Projects/Scripts/Spells/First/Clumsy.cs index e0d0e1e49..7f1f952c0 100644 --- a/Projects/Scripts/Spells/First/Clumsy.cs +++ b/Projects/Scripts/Spells/First/Clumsy.cs @@ -51,7 +51,7 @@ namespace Server.Spells.First int percentage = (int)(SpellHelper.GetOffsetScalar(Caster, m, true) * 100); TimeSpan length = SpellHelper.GetDuration(Caster, m); - BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Clumsy, 1075831, length, m, percentage.ToString())); + BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Clumsy, 1075831, percentage.ToString(), length, m)); HarmfulSpell(m); } diff --git a/Projects/Scripts/Spells/First/Feeblemind.cs b/Projects/Scripts/Spells/First/Feeblemind.cs index 37344a029..bb4d08dcb 100644 --- a/Projects/Scripts/Spells/First/Feeblemind.cs +++ b/Projects/Scripts/Spells/First/Feeblemind.cs @@ -49,7 +49,7 @@ namespace Server.Spells.First int percentage = (int)(SpellHelper.GetOffsetScalar(Caster, m, true) * 100); TimeSpan length = SpellHelper.GetDuration(Caster, m); - BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.FeebleMind, 1075833, length, m, percentage.ToString())); + BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.FeebleMind, 1075833, percentage.ToString(), length, m)); HarmfulSpell(m); } diff --git a/Projects/Scripts/Spells/First/NightSight.cs b/Projects/Scripts/Spells/First/NightSight.cs index 7de4cf18f..bc835d146 100644 --- a/Projects/Scripts/Spells/First/NightSight.cs +++ b/Projects/Scripts/Spells/First/NightSight.cs @@ -35,7 +35,7 @@ namespace Server.Spells.First { SpellHelper.Turn(m_Spell.Caster, targ); - if (targ.BeginAction()) + if (targ.BeginAction()) { new LightCycle.NightSightTimer(targ).Start(); int level = (int)(LightCycle.DungeonLevel * diff --git a/Projects/Scripts/Spells/First/ReactiveArmor.cs b/Projects/Scripts/Spells/First/ReactiveArmor.cs index 521b6397a..3184dd922 100644 --- a/Projects/Scripts/Spells/First/ReactiveArmor.cs +++ b/Projects/Scripts/Spells/First/ReactiveArmor.cs @@ -80,7 +80,7 @@ namespace Server.Spells.First int physresist = 15 + (int)(targ.Skills.Inscribe.Value / 20); string args = $"{physresist}\t{5}\t{5}\t{5}\t{5}"; - BuffInfo.AddBuff(Caster, new BuffInfo(BuffIcon.ReactiveArmor, 1075812, 1075813, args)); + BuffInfo.AddBuff(Caster, new BuffInfo(BuffIcon.ReactiveArmor, 1075812, args)); } else { diff --git a/Projects/Scripts/Spells/First/Weaken.cs b/Projects/Scripts/Spells/First/Weaken.cs index 8584877e0..abe97a0c7 100644 --- a/Projects/Scripts/Spells/First/Weaken.cs +++ b/Projects/Scripts/Spells/First/Weaken.cs @@ -49,7 +49,7 @@ namespace Server.Spells.First int percentage = (int)(SpellHelper.GetOffsetScalar(Caster, m, true) * 100); TimeSpan length = SpellHelper.GetDuration(Caster, m); - BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Weaken, 1075837, length, m, percentage.ToString())); + BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Weaken, 1075837, percentage.ToString(), length, m)); HarmfulSpell(m); } diff --git a/Projects/Scripts/Spells/Fourth/ArchCure.cs b/Projects/Scripts/Spells/Fourth/ArchCure.cs index 7f9f0d27e..57e763ad6 100644 --- a/Projects/Scripts/Spells/Fourth/ArchCure.cs +++ b/Projects/Scripts/Spells/Fourth/ArchCure.cs @@ -124,23 +124,9 @@ namespace Server.Spells.Fourth return true; } - private bool IsAggressor(Mobile m) - { - foreach (AggressorInfo info in Caster.Aggressors) - if (m == info.Attacker && !info.Expired) - return true; + private bool IsAggressor(Mobile m) => Caster.Aggressors.Any(info => m == info.Attacker && !info.Expired); - return false; - } - - private bool IsAggressed(Mobile m) - { - foreach (AggressorInfo info in Caster.Aggressed) - if (m == info.Defender && !info.Expired) - return true; - - return false; - } + private bool IsAggressed(Mobile m) => Caster.Aggressed.Any(info => m == info.Defender && !info.Expired); private static bool IsInnocentTo(Mobile from, Mobile to) => Notoriety.Compute(from, to) == Notoriety.Innocent; diff --git a/Projects/Scripts/Spells/Fourth/Curse.cs b/Projects/Scripts/Spells/Fourth/Curse.cs index 59e66a42a..29209a4f4 100644 --- a/Projects/Scripts/Spells/Fourth/Curse.cs +++ b/Projects/Scripts/Spells/Fourth/Curse.cs @@ -77,7 +77,7 @@ namespace Server.Spells.Fourth string args = $"{percentage}\t{percentage}\t{percentage}\t{10}\t{10}\t{10}\t{10}"; - BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Curse, 1075835, 1075836, length, m, args)); + BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Curse, 1075835, args, length, m)); HarmfulSpell(m); } diff --git a/Projects/Scripts/Spells/Fourth/FireField.cs b/Projects/Scripts/Spells/Fourth/FireField.cs index 376732848..6a603c400 100644 --- a/Projects/Scripts/Spells/Fourth/FireField.cs +++ b/Projects/Scripts/Spells/Fourth/FireField.cs @@ -47,16 +47,7 @@ namespace Server.Spells.Fourth int rx = (dx - dy) * 44; int ry = (dx + dy) * 44; - bool eastToWest; - - if (rx >= 0 && ry >= 0) - eastToWest = false; - else if (rx >= 0) - eastToWest = true; - else if (ry >= 0) - eastToWest = true; - else - eastToWest = false; + bool eastToWest = (rx < 0 || ry < 0) && (rx >= 0 || ry >= 0); Effects.PlaySound(p, Caster.Map, 0x20C); @@ -65,7 +56,7 @@ namespace Server.Spells.Fourth TimeSpan duration; if (Core.AOS) - duration = TimeSpan.FromSeconds((15 + Caster.Skills.Magery.Fixed / 5) / 4); + duration = TimeSpan.FromSeconds((15 + Caster.Skills.Magery.Fixed / 5.0) / 4.0); else duration = TimeSpan.FromSeconds(4.0 + Caster.Skills.Magery.Value * 0.5); diff --git a/Projects/Scripts/Spells/Fourth/Lightning.cs b/Projects/Scripts/Spells/Fourth/Lightning.cs index 151054b36..0ead57c77 100644 --- a/Projects/Scripts/Spells/Fourth/Lightning.cs +++ b/Projects/Scripts/Spells/Fourth/Lightning.cs @@ -58,7 +58,7 @@ namespace Server.Spells.Fourth damage *= GetDamageScalar(m); } - m.BoltEffect(0); + m.BoltEffect(); SpellHelper.Damage(this, m, damage, 0, 0, 0, 0, 100); } diff --git a/Projects/Scripts/Spells/Mysticism/HailStormSpell.cs b/Projects/Scripts/Spells/Mysticism/HailStormSpell.cs index 53c2b8fa4..338bbaaae 100644 --- a/Projects/Scripts/Spells/Mysticism/HailStormSpell.cs +++ b/Projects/Scripts/Spells/Mysticism/HailStormSpell.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using Server.Network; namespace Server.Spells.Mysticism { @@ -67,8 +66,7 @@ namespace Server.Spells.Mysticism targets.Add(m); - if (m.Player) - pvp = true; + pvp |= m.Player; } } } @@ -113,9 +111,7 @@ namespace Server.Spells.Mysticism private static void SendEffectPacket(IPoint3D p, Map map, Point3D orig, Point3D dest) { - Effects.SendPacket(p, map, - new HuedEffect(EffectType.Moving, Serial.Zero, Serial.Zero, 0x36D4, orig, dest, 0, 0, false, false, 0x63, - 0x4)); + Effects.SendMovingEffect(p, orig, dest, map, 0x36D4, 0, 0, false, false, 0x63, 4); } } } diff --git a/Projects/Scripts/Spells/Mysticism/NetherCycloneSpell.cs b/Projects/Scripts/Spells/Mysticism/NetherCycloneSpell.cs index 36ec20616..bc2bd0758 100644 --- a/Projects/Scripts/Spells/Mysticism/NetherCycloneSpell.cs +++ b/Projects/Scripts/Spells/Mysticism/NetherCycloneSpell.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using Server.Network; namespace Server.Spells.Mysticism { @@ -70,8 +69,7 @@ namespace Server.Spells.Mysticism targets.Add(m); - if (m.Player) - pvp = true; + pvp |= m.Player; } } } @@ -122,9 +120,7 @@ namespace Server.Spells.Mysticism private static void SendEffectPacket(IPoint3D p, Map map, Point3D orig, Point3D dest) { - Effects.SendPacket(p, map, - new HuedEffect(EffectType.Moving, Serial.Zero, Serial.Zero, 0x375A, orig, dest, 0, 0, false, false, 0x49A, - 0x4)); + Effects.SendMovingEffect(p, orig, dest, map, 0x375A, 0, 0, false, false, 0x49A, 4); } } } diff --git a/Projects/Scripts/Spells/Mysticism/StoneFormSpell.cs b/Projects/Scripts/Spells/Mysticism/StoneFormSpell.cs index d3ede2835..ac5d5656b 100644 --- a/Projects/Scripts/Spells/Mysticism/StoneFormSpell.cs +++ b/Projects/Scripts/Spells/Mysticism/StoneFormSpell.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using Server.Factions; -using Server.Mobiles; using Server.Spells.Fifth; using Server.Spells.Ninjitsu; using Server.Spells.Seventh; @@ -118,7 +117,7 @@ namespace Server.Spells.Mysticism Caster.PlaySound(0x65A); Caster.Delta(MobileDelta.Resistances); - BuffInfo.AddBuff(Caster, new BuffInfo(BuffIcon.StoneForm, 1080145, 1080146, + BuffInfo.AddBuff(Caster, new BuffInfo(BuffIcon.StoneForm, 1080145, $"-10\t-2\t{offset}\t{GetResistCapBonus(Caster)}\t{GetDIBonus(Caster)}", false)); } } diff --git a/Projects/Scripts/Spells/Necromancy/BloodOathSpell.cs b/Projects/Scripts/Spells/Necromancy/BloodOathSpell.cs index d30a5b2f6..58727cf9b 100644 --- a/Projects/Scripts/Spells/Necromancy/BloodOathSpell.cs +++ b/Projects/Scripts/Spells/Necromancy/BloodOathSpell.cs @@ -81,8 +81,8 @@ namespace Server.Spells.Necromancy timer = new ExpireTimer(Caster, m, duration); timer.Start(); - BuffInfo.AddBuff(Caster, new BuffInfo(BuffIcon.BloodOathCaster, 1075659, duration, Caster, m.Name)); - BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.BloodOathCurse, 1075661, duration, m, Caster.Name)); + BuffInfo.AddBuff(Caster, new BuffInfo(BuffIcon.BloodOathCaster, 1075659, m.Name, duration, Caster)); + BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.BloodOathCurse, 1075661, Caster.Name, duration, m)); m_Table[m] = timer; HarmfulSpell(m); diff --git a/Projects/Scripts/Spells/Necromancy/Exorcism.cs b/Projects/Scripts/Spells/Necromancy/Exorcism.cs index 9d7c8940d..efcb84ef3 100644 --- a/Projects/Scripts/Spells/Necromancy/Exorcism.cs +++ b/Projects/Scripts/Spells/Necromancy/Exorcism.cs @@ -87,9 +87,7 @@ namespace Server.Spells.Necromancy { ChampionSpawnRegion r = Caster.Region.GetRegion(); if (r == null || !Caster.InRange(r.ChampionSpawn, Range)) - { Caster.SendLocalizedMessage(1072111); // You are not in a valid exorcism region. - } else if (CheckSequence()) { Map map = Caster.Map; @@ -98,6 +96,7 @@ namespace Server.Spells.Necromancy { IEnumerable targets = r.ChampionSpawn.GetMobilesInRange(Range).Where(IsValidTarget); + //Surprisingly, no sparkle type effects foreach (Mobile m in targets) //Surprisingly, no sparkle type effects m.Location = GetNearestShrine(m); @@ -134,7 +133,7 @@ namespace Server.Spells.Necromancy Guild mGuild = m.Guild as Guild; Guild cGuild = Caster.Guild as Guild; - if (mGuild.IsAlly(cGuild)) + if (mGuild?.IsAlly(cGuild) == true) return false; if (mGuild == cGuild) diff --git a/Projects/Scripts/Spells/Necromancy/PainSpike.cs b/Projects/Scripts/Spells/Necromancy/PainSpike.cs index 79b03d0f0..5b48e06ac 100644 --- a/Projects/Scripts/Spells/Necromancy/PainSpike.cs +++ b/Projects/Scripts/Spells/Necromancy/PainSpike.cs @@ -73,7 +73,7 @@ namespace Server.Spells.Necromancy buffTime = timer.Next - DateTime.UtcNow; } - BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.PainSpike, 1075667, buffTime, m, Convert.ToString((int)damage))); + BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.PainSpike, 1075667, ((int)damage).ToString(), buffTime, m)); // TODO: Find a better way to do this WeightOverloading.DFA = DFAlgorithm.PainSpike; diff --git a/Projects/Scripts/Spells/Necromancy/Strangle.cs b/Projects/Scripts/Spells/Necromancy/Strangle.cs index 5d02a6627..f5f4ecc9b 100644 --- a/Projects/Scripts/Spells/Necromancy/Strangle.cs +++ b/Projects/Scripts/Spells/Necromancy/Strangle.cs @@ -14,7 +14,7 @@ namespace Server.Spells.Necromancy Reagent.NoxCrystal ); - private static Dictionary m_Table = new Dictionary(); + private static readonly Dictionary m_Table = new Dictionary(); public StrangleSpell(Mobile caster, Item scroll = null) : base(caster, scroll, m_Info) { @@ -104,7 +104,7 @@ namespace Server.Spells.Necromancy } TimeSpan t_Duration = TimeSpan.FromSeconds(i_Length); - BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Strangle, 1075794, 1075795, t_Duration, m, args)); + BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Strangle, 1075794, args, t_Duration, m)); FinishSequence(); } diff --git a/Projects/Scripts/Spells/Ninjitsu/AnimalForm.cs b/Projects/Scripts/Spells/Ninjitsu/AnimalForm.cs index 96711d893..5968c49aa 100644 --- a/Projects/Scripts/Spells/Ninjitsu/AnimalForm.cs +++ b/Projects/Scripts/Spells/Ninjitsu/AnimalForm.cs @@ -70,7 +70,7 @@ namespace Server.Spells.Ninjitsu public static void OnLogin(LoginEventArgs e) { if (GetContext(e.Mobile)?.SpeedBoost == true) - e.Mobile.Send(SpeedControl.MountSpeed); + Packets.SendSpeedControlMount(e.Mobile.NetState); } public override bool CheckCast() @@ -228,7 +228,7 @@ namespace Server.Spells.Ninjitsu m.HueMod = hueMod; if (entry.SpeedBoost) - m.Send(SpeedControl.MountSpeed); + Packets.SendSpeedControlMount(m.NetState); SkillMod mod = null; @@ -275,7 +275,7 @@ namespace Server.Spells.Ninjitsu m_Table.Remove(m); if (context.SpeedBoost) - m.Send(SpeedControl.Disable); + Packets.SendSpeedControlDisabled(m.NetState); SkillMod mod = context.Mod; @@ -575,7 +575,7 @@ namespace Server.Spells.Ninjitsu { m_Mobile.RevealingAction(); m_Mobile.PlaySound(0x227); - Effects.SendMovingEffect(m_Mobile, target, 0x36D4, 5, 0, false, false); + Effects.SendMovingEffect(m_Mobile, target, 0x36D4, 5, 0); DelayCall(TimeSpan.FromSeconds(1), BreathDamage_Callback, target); } diff --git a/Projects/Scripts/Spells/Second/Agility.cs b/Projects/Scripts/Spells/Second/Agility.cs index ce8b7e4c0..8520e4762 100644 --- a/Projects/Scripts/Spells/Second/Agility.cs +++ b/Projects/Scripts/Spells/Second/Agility.cs @@ -55,7 +55,7 @@ namespace Server.Spells.Second int percentage = (int)(SpellHelper.GetOffsetScalar(Caster, m, false) * 100); TimeSpan length = SpellHelper.GetDuration(Caster, m); - BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Agility, 1075841, length, m, percentage.ToString())); + BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Agility, 1075841, percentage.ToString(), length, m)); } FinishSequence(); diff --git a/Projects/Scripts/Spells/Second/Cunning.cs b/Projects/Scripts/Spells/Second/Cunning.cs index fac065ce5..bc822edb6 100644 --- a/Projects/Scripts/Spells/Second/Cunning.cs +++ b/Projects/Scripts/Spells/Second/Cunning.cs @@ -55,7 +55,7 @@ namespace Server.Spells.Second int percentage = (int)(SpellHelper.GetOffsetScalar(Caster, m, false) * 100); TimeSpan length = SpellHelper.GetDuration(Caster, m); - BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Cunning, 1075843, length, m, percentage.ToString())); + BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Cunning, 1075843, percentage.ToString(), length, m)); } FinishSequence(); diff --git a/Projects/Scripts/Spells/Second/Protection.cs b/Projects/Scripts/Spells/Second/Protection.cs index f4587ed26..ac2ec16ac 100644 --- a/Projects/Scripts/Spells/Second/Protection.cs +++ b/Projects/Scripts/Spells/Second/Protection.cs @@ -75,7 +75,7 @@ namespace Server.Spells.Second int physloss = -15 + (int)(caster.Skills.Inscribe.Value / 20); int resistloss = -35 + (int)(caster.Skills.Inscribe.Value / 20); string args = $"{physloss}\t{resistloss}"; - BuffInfo.AddBuff(target, new BuffInfo(BuffIcon.Protection, 1075814, 1075815, args)); + BuffInfo.AddBuff(target, new BuffInfo(BuffIcon.Protection, 1075814, args)); } else { diff --git a/Projects/Scripts/Spells/Second/Strength.cs b/Projects/Scripts/Spells/Second/Strength.cs index bc05a93ff..8faf62cee 100644 --- a/Projects/Scripts/Spells/Second/Strength.cs +++ b/Projects/Scripts/Spells/Second/Strength.cs @@ -55,7 +55,7 @@ namespace Server.Spells.Second int percentage = (int)(SpellHelper.GetOffsetScalar(Caster, m, false) * 100); TimeSpan length = SpellHelper.GetDuration(Caster, m); - BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Strength, 1075845, length, m, percentage.ToString())); + BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Strength, 1075845, percentage.ToString(), length, m)); } FinishSequence(); diff --git a/Projects/Scripts/Spells/Seventh/ChainLightning.cs b/Projects/Scripts/Spells/Seventh/ChainLightning.cs index 9609f56f3..9db5df46c 100644 --- a/Projects/Scripts/Spells/Seventh/ChainLightning.cs +++ b/Projects/Scripts/Spells/Seventh/ChainLightning.cs @@ -59,8 +59,7 @@ namespace Server.Spells.Seventh !Caster.CanBeHarmful(m, false)) return false; - if (m.Player) - playerVsPlayer = true; + playerVsPlayer |= m.Player; return true; }).ToList()); @@ -68,9 +67,7 @@ namespace Server.Spells.Seventh eable.Free(); } - double damage; - - damage = Core.AOS ? GetNewAosDamage(51, 1, 5, playerVsPlayer) + double damage = Core.AOS ? GetNewAosDamage(51, 1, 5, playerVsPlayer) : Utility.Random(27, 22); if (targets.Count > 0) @@ -96,13 +93,11 @@ namespace Server.Spells.Seventh Caster.DoHarmful(m); SpellHelper.Damage(this, m, toDeal, 0, 0, 0, 0, 100); - m.BoltEffect(0); + m.BoltEffect(); } } else - { Caster.PlaySound(0x29); - } } FinishSequence(); diff --git a/Projects/Scripts/Spells/Seventh/EnergyField.cs b/Projects/Scripts/Spells/Seventh/EnergyField.cs index f14dbe3c6..802985ba0 100644 --- a/Projects/Scripts/Spells/Seventh/EnergyField.cs +++ b/Projects/Scripts/Spells/Seventh/EnergyField.cs @@ -47,16 +47,7 @@ namespace Server.Spells.Seventh int rx = (dx - dy) * 44; int ry = (dx + dy) * 44; - bool eastToWest; - - if (rx >= 0 && ry >= 0) - eastToWest = false; - else if (rx >= 0) - eastToWest = true; - else if (ry >= 0) - eastToWest = true; - else - eastToWest = false; + bool eastToWest = (rx < 0 || ry < 0) && (rx >= 0 || ry >= 0); Effects.PlaySound(p, Caster.Map, 0x20B); @@ -143,7 +134,7 @@ namespace Server.Spells.Seventh { if (!(m is PlayerMobile)) return base.OnMoveOver(m); - + int noto = Notoriety.Compute(m_Caster, m); return noto != Notoriety.Enemy && noto != Notoriety.Ally && base.OnMoveOver(m); } diff --git a/Projects/Scripts/Spells/Seventh/GateTravel.cs b/Projects/Scripts/Spells/Seventh/GateTravel.cs index bca60d29c..4770aea31 100644 --- a/Projects/Scripts/Spells/Seventh/GateTravel.cs +++ b/Projects/Scripts/Spells/Seventh/GateTravel.cs @@ -67,13 +67,9 @@ namespace Server.Spells.Seventh public void Effect(Point3D loc, Map map, bool checkMulti) { if (Sigil.ExistsOn(Caster)) - { Caster.SendLocalizedMessage(1061632); // You can't do that while carrying the sigil. - } else if (map == null || !Core.AOS && Caster.Map != map) - { Caster.SendLocalizedMessage(1005570); // You can not gate to another facet. - } else if (!SpellHelper.CheckTravel(Caster, TravelCheckType.GateFrom)) { } @@ -81,34 +77,19 @@ namespace Server.Spells.Seventh { } else if (map == Map.Felucca && Caster is PlayerMobile mobile && mobile.Young) - { mobile.SendLocalizedMessage(1049543); // You decide against traveling to Felucca while you are still young. - } else if (Caster.Kills >= 5 && map != Map.Felucca) - { Caster.SendLocalizedMessage(1019004); // You are not allowed to travel there. - } else if (Caster.Criminal) - { Caster.SendLocalizedMessage(1005561, "", 0x22); // Thou'rt a criminal and cannot escape so easily. - } else if (SpellHelper.CheckCombat(Caster)) - { Caster.SendLocalizedMessage(1005564, "", 0x22); // Wouldst thou flee during the heat of battle?? - } else if (!map.CanSpawnMobile(loc.X, loc.Y, loc.Z)) - { Caster.SendLocalizedMessage(501942); // That location is blocked. - } else if (checkMulti && SpellHelper.CheckMulti(loc, map)) - { Caster.SendLocalizedMessage(501942); // That location is blocked. - } - else if (Core.SE && (GateExistsAt(map, loc) || GateExistsAt(Caster.Map, Caster.Location)) - ) // SE restricted stacking gates - { + else if (Core.SE && (GateExistsAt(map, loc) || GateExistsAt(Caster.Map, Caster.Location))) // SE restricted stacking gates Caster.SendLocalizedMessage(1071242); // There is already a gate there. - } else if (CheckSequence()) { Caster.SendLocalizedMessage(501024); // You open a magical gate to another location diff --git a/Projects/Scripts/Spells/Seventh/MeteorSwarm.cs b/Projects/Scripts/Spells/Seventh/MeteorSwarm.cs index 3acc34147..0aa30c2c6 100644 --- a/Projects/Scripts/Spells/Seventh/MeteorSwarm.cs +++ b/Projects/Scripts/Spells/Seventh/MeteorSwarm.cs @@ -59,8 +59,7 @@ namespace Server.Spells.Seventh Core.AOS && !Caster.InLOS(m)) return false; - if (m.Player) - playerVsPlayer = true; + playerVsPlayer |= m.Player; return true; }).ToList(); @@ -72,9 +71,7 @@ namespace Server.Spells.Seventh targets = new List(); } - double damage; - - damage = Core.AOS ? GetNewAosDamage(51, 1, 5, playerVsPlayer) + double damage = Core.AOS ? GetNewAosDamage(51, 1, 5, playerVsPlayer) : Utility.Random(27, 22); if (targets.Count > 0) diff --git a/Projects/Scripts/Spells/Seventh/Polymorph.cs b/Projects/Scripts/Spells/Seventh/Polymorph.cs index b1842fbb2..2031fbe95 100644 --- a/Projects/Scripts/Spells/Seventh/Polymorph.cs +++ b/Projects/Scripts/Spells/Seventh/Polymorph.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using Server.Factions; using Server.Gumps; using Server.Items; -using Server.Mobiles; using Server.Spells.Fifth; namespace Server.Spells.Seventh diff --git a/Projects/Scripts/Spells/Sixth/Mark.cs b/Projects/Scripts/Spells/Sixth/Mark.cs index 336e25172..1ffb89196 100644 --- a/Projects/Scripts/Spells/Sixth/Mark.cs +++ b/Projects/Scripts/Spells/Sixth/Mark.cs @@ -31,8 +31,8 @@ namespace Server.Spells.Sixth public void Target(Item item) { if (!(item is RecallRune rune)) - Caster.Send(new MessageLocalized(Caster.Serial, Caster.Body, MessageType.Regular, 0x3B2, 3, 501797, Caster.Name, - "")); // I cannot mark that object. + Packets.SendMessageLocalized(Caster.NetState, Caster.Serial, Caster.Body, MessageType.Regular, + 0x3B2, 3, 501797, Caster.Name); // I cannot mark that object. else if (!Caster.CanSee(rune)) Caster.SendLocalizedMessage(500237); // Target can not be seen. else if (!SpellHelper.CheckTravel(Caster, TravelCheckType.Mark)) diff --git a/Projects/Scripts/Spells/Sixth/ParalyzeField.cs b/Projects/Scripts/Spells/Sixth/ParalyzeField.cs index 4f16ac735..78ad1a38b 100644 --- a/Projects/Scripts/Spells/Sixth/ParalyzeField.cs +++ b/Projects/Scripts/Spells/Sixth/ParalyzeField.cs @@ -46,16 +46,7 @@ namespace Server.Spells.Sixth int rx = (dx - dy) * 44; int ry = (dx + dy) * 44; - bool eastToWest; - - if (rx >= 0 && ry >= 0) - eastToWest = false; - else if (rx >= 0) - eastToWest = true; - else if (ry >= 0) - eastToWest = true; - else - eastToWest = false; + bool eastToWest = (rx < 0 || ry < 0) && (rx >= 0 || ry >= 0); Effects.PlaySound(p, Caster.Map, 0x20B); diff --git a/Projects/Scripts/Spells/Spellweaving/AttuneWeapon.cs b/Projects/Scripts/Spells/Spellweaving/AttuneWeapon.cs index 938cfdc44..2376fc843 100644 --- a/Projects/Scripts/Spells/Spellweaving/AttuneWeapon.cs +++ b/Projects/Scripts/Spells/Spellweaving/AttuneWeapon.cs @@ -61,7 +61,7 @@ namespace Server.Spells.Spellweaving Caster.BeginAction(); BuffInfo.AddBuff(Caster, - new BuffInfo(BuffIcon.AttuneWeapon, 1075798, duration, Caster, damageAbsorb.ToString())); + new BuffInfo(BuffIcon.AttuneWeapon, 1075798, damageAbsorb.ToString(), duration, Caster)); } FinishSequence(); diff --git a/Projects/Scripts/Spells/Spellweaving/EssenceOfWind.cs b/Projects/Scripts/Spells/Spellweaving/EssenceOfWind.cs index 11fc81d31..70c04b7dc 100644 --- a/Projects/Scripts/Spells/Spellweaving/EssenceOfWind.cs +++ b/Projects/Scripts/Spells/Spellweaving/EssenceOfWind.cs @@ -51,8 +51,7 @@ namespace Server.Spells.Spellweaving m_Table[m] = new EssenceOfWindInfo(m, fcMalus, ssiMalus, duration); - BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.EssenceOfWind, 1075802, duration, m, - $"{fcMalus.ToString()}\t{ssiMalus.ToString()}")); + BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.EssenceOfWind, 1075802, $"{fcMalus}\t{ssiMalus}", duration, m)); } eable.Free(); diff --git a/Projects/Scripts/Spells/Spellweaving/GiftOfLife.cs b/Projects/Scripts/Spells/Spellweaving/GiftOfLife.cs index f04154d49..fe3425e57 100644 --- a/Projects/Scripts/Spells/Spellweaving/GiftOfLife.cs +++ b/Projects/Scripts/Spells/Spellweaving/GiftOfLife.cs @@ -77,7 +77,7 @@ namespace Server.Spells.Spellweaving m_Table[m] = t; - BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.GiftOfLife, 1031615, 1075807, duration, m, null, true)); + BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.GiftOfLife, 1031615, 1075807, duration, true, m)); } FinishSequence(); diff --git a/Projects/Scripts/Spells/Spellweaving/GiftOfRenewal.cs b/Projects/Scripts/Spells/Spellweaving/GiftOfRenewal.cs index b1734b3dd..45fdea610 100644 --- a/Projects/Scripts/Spells/Spellweaving/GiftOfRenewal.cs +++ b/Projects/Scripts/Spells/Spellweaving/GiftOfRenewal.cs @@ -75,7 +75,7 @@ namespace Server.Spells.Spellweaving Caster.BeginAction(); BuffInfo.AddBuff(m, - new BuffInfo(BuffIcon.GiftOfRenewal, 1031602, 1075797, duration, m, hitsPerRound.ToString())); + new BuffInfo(BuffIcon.GiftOfRenewal, 1031602, 1075797, hitsPerRound.ToString(), duration, m)); } } diff --git a/Projects/Scripts/Spells/Spellweaving/ReaperForm.cs b/Projects/Scripts/Spells/Spellweaving/ReaperForm.cs index ff693ec24..80530393f 100644 --- a/Projects/Scripts/Spells/Spellweaving/ReaperForm.cs +++ b/Projects/Scripts/Spells/Spellweaving/ReaperForm.cs @@ -37,19 +37,19 @@ namespace Server.Spells.Spellweaving TransformContext context = TransformationSpellHelper.GetContext(e.Mobile); if (context?.Type == typeof(ReaperFormSpell)) - e.Mobile.Send(SpeedControl.WalkSpeed); + Packets.SendSpeedControlWalk(e.Mobile.NetState); } public override void DoEffect(Mobile m) { m.PlaySound(0x1BA); - m.Send(SpeedControl.WalkSpeed); + Packets.SendSpeedControlWalk(m.NetState); } public override void RemoveEffect(Mobile m) { - m.Send(SpeedControl.Disable); + Packets.SendSpeedControlDisabled(m.NetState); } } } diff --git a/Projects/Scripts/Spells/Spellweaving/Thunderstorm.cs b/Projects/Scripts/Spells/Spellweaving/Thunderstorm.cs index f4d2c558c..6fe73c0e1 100644 --- a/Projects/Scripts/Spells/Spellweaving/Thunderstorm.cs +++ b/Projects/Scripts/Spells/Spellweaving/Thunderstorm.cs @@ -66,7 +66,7 @@ namespace Server.Spells.Spellweaving m_Table[m] = Timer.DelayCall(duration, DoExpire, m); BuffInfo.AddBuff(m, - new BuffInfo(BuffIcon.Thunderstorm, 1075800, duration, m, GetCastRecoveryMalus(m))); + new BuffInfo(BuffIcon.Thunderstorm, 1075800, GetCastRecoveryMalus(m).ToString(), duration, m)); } eable.Free(); diff --git a/Projects/Scripts/Spells/Targeting/RecallSpellTarget.cs b/Projects/Scripts/Spells/Targeting/RecallSpellTarget.cs index b74530dfb..f032f96ee 100644 --- a/Projects/Scripts/Spells/Targeting/RecallSpellTarget.cs +++ b/Projects/Scripts/Spells/Targeting/RecallSpellTarget.cs @@ -40,18 +40,13 @@ namespace Server.Spells if (!boat.Deleted && boat.CheckKey(key.KeyValue)) m_Spell.Effect(boat.GetMarkedLocation(), boat.Map, false); else - from.Send(new MessageLocalized(from.Serial, from.Body, MessageType.Regular, 0x3B2, 3, 502357, - from.Name, "")); // I can not recall from that object. + Packets.SendMessageLocalized(from.NetState, from.Serial, from.Body, MessageType.Regular, 0x3B2, 3, 502357, + from.Name); // I can not recall from that object. } else if (o is HouseRaffleDeed deed && deed.ValidLocation()) - { m_Spell.Effect(deed.PlotLocation, deed.PlotFacet, true); - } else - { - from.Send(new MessageLocalized(from.Serial, from.Body, MessageType.Regular, 0x3B2, 3, 502357, from.Name, - "")); // I can not recall from that object. - } + Packets.SendMessageLocalized(from.NetState, from.Serial, from.Body, MessageType.Regular, 0x3B2, 3, 502357, from.Name); // I can not recall from that object. } protected override void OnNonlocalTarget(Mobile from, object o) diff --git a/Projects/Scripts/Spells/Third/Bless.cs b/Projects/Scripts/Spells/Third/Bless.cs index 47e26354a..f11c740dd 100644 --- a/Projects/Scripts/Spells/Third/Bless.cs +++ b/Projects/Scripts/Spells/Third/Bless.cs @@ -61,7 +61,7 @@ namespace Server.Spells.Third string args = $"{percentage}\t{percentage}\t{percentage}"; - BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Bless, 1075847, 1075848, length, m, args)); + BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Bless, 1075847, 1075848, args, length, m)); } FinishSequence(); diff --git a/Projects/Scripts/Spells/Third/WallOfStone.cs b/Projects/Scripts/Spells/Third/WallOfStone.cs index 430a37b69..6346344d0 100644 --- a/Projects/Scripts/Spells/Third/WallOfStone.cs +++ b/Projects/Scripts/Spells/Third/WallOfStone.cs @@ -44,16 +44,7 @@ namespace Server.Spells.Third int rx = (dx - dy) * 44; int ry = (dx + dy) * 44; - bool eastToWest; - - if (rx >= 0 && ry >= 0) - eastToWest = false; - else if (rx >= 0) - eastToWest = true; - else if (ry >= 0) - eastToWest = true; - else - eastToWest = false; + bool eastToWest = (rx < 0 || ry < 0) && (rx >= 0 || ry >= 0); Effects.PlaySound(p, Caster.Map, 0x1F6); diff --git a/Projects/Server/Diagnostics/BaseProfile.cs b/Projects/Server/Diagnostics/BaseProfile.cs index bbc7804a5..316cad869 100644 --- a/Projects/Server/Diagnostics/BaseProfile.cs +++ b/Projects/Server/Diagnostics/BaseProfile.cs @@ -50,7 +50,7 @@ namespace Server.Diagnostics { List list = new List(profiles); - list.Sort(delegate(T a, T b) { return -a.TotalTime.CompareTo(b.TotalTime); }); + list.Sort((a, b) => -a.TotalTime.CompareTo(b.TotalTime)); foreach (T prof in list) { @@ -85,4 +85,4 @@ namespace Server.Diagnostics PeakTime.TotalSeconds, TotalTime.TotalSeconds); } } -} \ No newline at end of file +} diff --git a/Projects/Server/Effects.cs b/Projects/Server/Effects.cs index ead626d02..bbe7dd0f0 100644 --- a/Projects/Server/Effects.cs +++ b/Projects/Server/Effects.cs @@ -48,44 +48,26 @@ namespace Server ParticleSupportType == ParticleSupportType.Full || ParticleSupportType == ParticleSupportType.Detect && state.IsUOTDClient; - public static void PlaySound(IPoint3D p, Map map, int soundID) + public static void PlaySound(IPoint3D p, Map map, int soundId) { - if (soundID <= -1) + if (soundId <= -1) return; if (map != null) { - Packet playSound = null; - - IPooledEnumerable eable = map.GetClientsInRange(new Point3D(p)); + IPooledEnumerable eable = map.GetClientsInRange(p); foreach (NetState state in eable) { state.Mobile.ProcessDelta(); - - if (playSound == null) - playSound = Packet.Acquire(new PlaySound(soundID, p)); - - state.Send(playSound); + Packets.SendPlaySound(state, soundId, p); } - Packet.Release(playSound); - eable.Free(); } } - public static void SendBoltEffect(IEntity e) - { - SendBoltEffect(e, true, 0); - } - - public static void SendBoltEffect(IEntity e, bool sound) - { - SendBoltEffect(e, sound, 0); - } - - public static void SendBoltEffect(IEntity e, bool sound, int hue) + public static void SendBoltEffect(IEntity e, bool sound = true) { Map map = e.Map; @@ -94,61 +76,35 @@ namespace Server e.ProcessDelta(); - Packet preEffect = null, boltEffect = null, playSound = null; - IPooledEnumerable eable = map.GetClientsInRange(e.Location); foreach (NetState state in eable) if (state.Mobile.CanSee(e)) { if (SendParticlesTo(state)) - { - if (preEffect == null) - preEffect = Packet.Acquire(new TargetParticleEffect(e, 0, 10, 5, 0, 0, 5031, 3, 0)); + Packets.SendTargetParticleEffect(state, e, 0, 10, 5, 0, 0, 5031, 3, 0); - state.Send(preEffect); - } - - if (boltEffect == null) - boltEffect = Packet.Acquire(new BoltEffect(e, hue)); - - state.Send(boltEffect); + Packets.SendBoltEffect(state, e); if (sound) - { - if (playSound == null) - playSound = Packet.Acquire(new PlaySound(0x29, e)); - - state.Send(playSound); - } + Packets.SendPlaySound(state, 0x29, e); } - Packet.Release(preEffect); - Packet.Release(boltEffect); - Packet.Release(playSound); - eable.Free(); } - public static void SendLocationEffect(IPoint3D p, Map map, int itemID, int duration) + public static void SendLocationEffect(IPoint3D p, Map map, int itemID, int duration, int speed = 10, int hue = 0, + int renderMode = 0) { - SendLocationEffect(p, map, itemID, duration, 10, 0, 0); - } + IPooledEnumerable eable = map.GetClientsInRange(p); - public static void SendLocationEffect(IPoint3D p, Map map, int itemID, int duration, int speed) - { - SendLocationEffect(p, map, itemID, duration, speed, 0, 0); - } + foreach (NetState state in eable) + { + state.Mobile.ProcessDelta(); + Packets.SendLocationHuedEffect(state, p, itemID, speed, duration, hue, renderMode); + } - public static void SendLocationEffect(IPoint3D p, Map map, int itemID, int duration, int hue, int renderMode) - { - SendLocationEffect(p, map, itemID, duration, 10, hue, renderMode); - } - - public static void SendLocationEffect(IPoint3D p, Map map, int itemID, int duration, int speed, int hue, - int renderMode) - { - SendPacket(p, map, new LocationEffect(p, itemID, speed, duration, hue, renderMode)); + eable.Free(); } public static void SendLocationParticles(IEntity e, int itemID, int speed, int duration, int effect) @@ -166,63 +122,39 @@ namespace Server { Map map = e.Map; - if (map != null) + if (map == null) + return; + + IPooledEnumerable eable = map.GetClientsInRange(e.Location); + + foreach (NetState state in eable) { - Packet particles = null, regular = null; + state.Mobile.ProcessDelta(); - IPooledEnumerable eable = map.GetClientsInRange(e.Location); - - foreach (NetState state in eable) - { - state.Mobile.ProcessDelta(); - - if (SendParticlesTo(state)) - { - if (particles == null) - particles = Packet.Acquire(new LocationParticleEffect(e, itemID, speed, duration, hue, - renderMode, effect, unknown)); - - state.Send(particles); - } - else if (itemID != 0) - { - if (regular == null) - regular = Packet.Acquire(new LocationEffect(e, itemID, speed, duration, hue, renderMode)); - - state.Send(regular); - } - } - - Packet.Release(particles); - Packet.Release(regular); - - eable.Free(); + if (SendParticlesTo(state)) + Packets.SendLocationParticleEffect(state, e, itemID, speed, duration, hue, + renderMode, effect, unknown); + else if (itemID != 0) + Packets.SendLocationHuedEffect(state, e, itemID, speed, duration, hue, renderMode); } - //SendPacket( e.Location, e.Map, new LocationParticleEffect( e, itemID, speed, duration, hue, renderMode, effect, unknown ) ); + eable.Free(); } - public static void SendTargetEffect(IEntity target, int itemID, int duration) - { - SendTargetEffect(target, itemID, duration, 0, 0); - } - - public static void SendTargetEffect(IEntity target, int itemID, int speed, int duration) - { - SendTargetEffect(target, itemID, speed, duration, 0, 0); - } - - public static void SendTargetEffect(IEntity target, int itemID, int duration, int hue, int renderMode) - { - SendTargetEffect(target, itemID, 10, duration, hue, renderMode); - } - - public static void SendTargetEffect(IEntity target, int itemID, int speed, int duration, int hue, int renderMode) + public static void SendTargetEffect(IEntity target, int itemID, int speed, int duration, int hue = 0, int renderMode = 0) { if (target is Mobile mobile) mobile.ProcessDelta(); - SendPacket(target.Location, target.Map, new TargetEffect(target, itemID, speed, duration, hue, renderMode)); + IPooledEnumerable eable = target.Map.GetClientsInRange(target.Location); + + foreach (NetState state in eable) + { + state.Mobile.ProcessDelta(); + Packets.SendTargetHuedEffect(state, target, itemID, speed, duration, hue, renderMode); + } + + eable.Free(); } public static void SendTargetParticles(IEntity target, int itemID, int speed, int duration, int effect, @@ -245,44 +177,47 @@ namespace Server Map map = target.Map; - if (map != null) + if (map == null) + return; + + IPooledEnumerable eable = map.GetClientsInRange(target.Location); + + foreach (NetState state in eable) { - Packet particles = null, regular = null; + state.Mobile.ProcessDelta(); - IPooledEnumerable eable = map.GetClientsInRange(target.Location); - - foreach (NetState state in eable) - { - state.Mobile.ProcessDelta(); - - if (SendParticlesTo(state)) - { - if (particles == null) - particles = Packet.Acquire(new TargetParticleEffect(target, itemID, speed, duration, hue, - renderMode, effect, (int)layer, unknown)); - - state.Send(particles); - } - else if (itemID != 0) - { - if (regular == null) - regular = Packet.Acquire(new TargetEffect(target, itemID, speed, duration, hue, renderMode)); - - state.Send(regular); - } - } - - Packet.Release(particles); - Packet.Release(regular); - - eable.Free(); + if (SendParticlesTo(state)) + Packets.SendTargetParticleEffect(state, target, itemID, speed, duration, hue, + renderMode, effect, (int)layer, unknown); + else if (itemID != 0) + Packets.SendTargetHuedEffect(state, target, itemID, speed, duration, hue, renderMode); } - //SendPacket( target.Location, target.Map, new TargetParticleEffect( target, itemID, speed, duration, hue, renderMode, effect, (int)layer, unknown ) ); + eable.Free(); + } + + public static void SendMovingEffect(IPoint3D from, IPoint3D to, Map map, int itemID, int speed = 0, int duration = 0, + bool fixedDirection = false, bool explodes = false, int hue = 0, int renderMode = 0) + { + SendMovingEffect(from, from, to, map, itemID, speed, duration, fixedDirection, explodes, hue, renderMode); + } + + public static void SendMovingEffect(IPoint3D range, IPoint3D from, IPoint3D to, Map map, int itemID, int speed = 0, int duration = 0, + bool fixedDirection = false, bool explodes = false, int hue = 0, int renderMode = 0) + { + IPooledEnumerable eable = map.GetClientsInRange(range); + + foreach (NetState state in eable) + { + state.Mobile.ProcessDelta(); + Packets.SendMovingHuedEffect(state, from, to, itemID, speed, duration, fixedDirection, explodes, hue, renderMode); + } + + eable.Free(); } public static void SendMovingEffect(IEntity from, IEntity to, int itemID, int speed, int duration, - bool fixedDirection, bool explodes, int hue = 0, int renderMode = 0) + bool fixedDirection = false, bool explodes = false, int hue = 0, int renderMode = 0) { if (from is Mobile mobile) mobile.ProcessDelta(); @@ -290,8 +225,15 @@ namespace Server if (to is Mobile mobile1) mobile1.ProcessDelta(); - SendPacket(from.Location, from.Map, - new MovingEffect(from, to, itemID, speed, duration, fixedDirection, explodes, hue, renderMode)); + IPooledEnumerable eable = from.Map.GetClientsInRange(from.Location); + + foreach (NetState state in eable) + { + state.Mobile.ProcessDelta(); + Packets.SendMovingHuedEffect(state, from, to, itemID, speed, duration, fixedDirection, explodes, hue, renderMode); + } + + eable.Free(); } public static void SendMovingParticles(IEntity from, IEntity to, int itemID, int speed, int duration, @@ -328,82 +270,25 @@ namespace Server Map map = from.Map; - if (map != null) - { - Packet particles = null, regular = null; - - IPooledEnumerable eable = map.GetClientsInRange(from.Location); - - foreach (NetState state in eable) - { - state.Mobile.ProcessDelta(); - - if (SendParticlesTo(state)) - { - if (particles == null) - particles = Packet.Acquire(new MovingParticleEffect(from, to, itemID, speed, duration, - fixedDirection, explodes, hue, renderMode, effect, explodeEffect, explodeSound, layer, - unknown)); - - state.Send(particles); - } - else if (itemID > 1) - { - if (regular == null) - regular = Packet.Acquire(new MovingEffect(from, to, itemID, speed, duration, fixedDirection, - explodes, hue, renderMode)); - - state.Send(regular); - } - } - - Packet.Release(particles); - Packet.Release(regular); - - eable.Free(); - } - - //SendPacket( from.Location, from.Map, new MovingParticleEffect( from, to, itemID, speed, duration, fixedDirection, explodes, hue, renderMode, effect, explodeEffect, explodeSound, unknown ) ); - } - - public static void SendPacket(Point3D origin, Map map, Packet p) - { if (map == null) return; - - IPooledEnumerable eable = map.GetClientsInRange(origin); - p.Acquire(); + IPooledEnumerable eable = map.GetClientsInRange(from.Location); foreach (NetState state in eable) { state.Mobile.ProcessDelta(); - state.Send(p); + + if (SendParticlesTo(state)) + Packets.SendMovingParticleEffect(state, from, to, itemID, speed, duration, + fixedDirection, explodes, hue, renderMode, effect, explodeEffect, explodeSound, layer, + unknown); + else if (itemID > 1) + Packets.SendMovingHuedEffect(state, from, to, itemID, speed, duration, fixedDirection, + explodes, hue, renderMode); } - p.Release(); - - eable.Free(); - } - - public static void SendPacket(IPoint3D origin, Map map, Packet p) - { - if (map == null) - return; - - IPooledEnumerable eable = map.GetClientsInRange(new Point3D(origin)); - - p.Acquire(); - - foreach (NetState state in eable) - { - state.Mobile.ProcessDelta(); - state.Send(p); - } - - p.Release(); - eable.Free(); } } -} \ No newline at end of file +} diff --git a/Projects/Server/ExpansionInfo.cs b/Projects/Server/ExpansionInfo.cs index d5770fd26..39a17be40 100644 --- a/Projects/Server/ExpansionInfo.cs +++ b/Projects/Server/ExpansionInfo.cs @@ -72,6 +72,7 @@ namespace Server RoleplayFaces = 0x00002000, TrialAccount = 0x00004000, LiveAccount = 0x00008000, + SA = 0x00010000, HS = 0x00020000, Gothic = 0x00040000, @@ -321,4 +322,4 @@ namespace Server public override string ToString() => Name; } -} \ No newline at end of file +} diff --git a/Projects/Server/Geometry.cs b/Projects/Server/Geometry.cs index a86248fff..fe703e488 100644 --- a/Projects/Server/Geometry.cs +++ b/Projects/Server/Geometry.cs @@ -134,13 +134,11 @@ namespace Server m_Z = z; } - public Point3D(IPoint3D p) - : this(p.X, p.Y, p.Z) + public Point3D(IPoint3D p) : this(p.X, p.Y, p.Z) { } - public Point3D(IPoint2D p, int z) - : this(p.X, p.Y, z) + public Point3D(IPoint2D p, int z) : this(p.X, p.Y, z) { } diff --git a/Projects/Server/Guild.cs b/Projects/Server/Guild.cs index 76f892474..83d5b5803 100644 --- a/Projects/Server/Guild.cs +++ b/Projects/Server/Guild.cs @@ -19,8 +19,9 @@ ***************************************************************************/ using System.Collections.Generic; +using System.Linq; -namespace Server.Guilds +namespace Server { public enum GuildType { @@ -72,23 +73,9 @@ namespace Server.Guilds return g; } - public static BaseGuild FindByName(string name) - { - foreach (BaseGuild g in List.Values) - if (g.Name == name) - return g; + public static BaseGuild FindByName(string name) => List.Values.FirstOrDefault(g => g.Name == name); - return null; - } - - public static BaseGuild FindByAbbrev(string abbr) - { - foreach (BaseGuild g in List.Values) - if (g.Abbreviation == abbr) - return g; - - return null; - } + public static BaseGuild FindByAbbrev(string abbr) => List.Values.FirstOrDefault(g => g.Abbreviation == abbr); public static List Search(string find) { @@ -96,19 +83,8 @@ namespace Server.Guilds List results = new List(); foreach (BaseGuild g in List.Values) - { - bool match = true; - string name = g.Name.ToLower(); - for (int i = 0; i < words.Length; i++) - if (name.IndexOf(words[i]) == -1) - { - match = false; - break; - } - - if (match) + if (words.All(t => g.Name.ToLower().IndexOf(t) != -1)) results.Add(g); - } return results; } diff --git a/Projects/Server/Gumps/Gump.cs b/Projects/Server/Gumps/Gump.cs index 0d5cc707a..8644d9cbd 100644 --- a/Projects/Server/Gumps/Gump.cs +++ b/Projects/Server/Gumps/Gump.cs @@ -19,8 +19,13 @@ ***************************************************************************/ using System; +using System.Buffers; using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; using System.Text; +using Server.Buffers; +using Server.Collections; using Server.Network; namespace Server.Gumps @@ -29,135 +34,45 @@ namespace Server.Gumps { private static uint m_NextSerial = 1; - private static byte[] m_BeginLayout = StringToBuffer("{ "); - private static byte[] m_EndLayout = StringToBuffer(" }"); - private static byte[] m_NoMove = StringToBuffer("{ nomove }"); private static byte[] m_NoClose = StringToBuffer("{ noclose }"); private static byte[] m_NoDispose = StringToBuffer("{ nodispose }"); private static byte[] m_NoResize = StringToBuffer("{ noresize }"); - private bool m_Closable = true; - private bool m_Disposable = true; - - private bool m_Draggable = true; - private bool m_Resizable = true; - - private uint m_Serial; - private List m_Strings; internal int m_TextEntries, m_Switches; - private int m_X, m_Y; public Gump(int x, int y) { do { - m_Serial = m_NextSerial++; - } while (m_Serial == 0); // standard client apparently doesn't send a gump response packet if serial == 0 + Serial = m_NextSerial++; + } while (Serial == 0); // standard client apparently doesn't send a gump response packet if serial == 0 - m_X = x; - m_Y = y; + X = x; + Y = y; TypeID = GetTypeID(GetType()); Entries = new List(); - m_Strings = new List(); } public int TypeID{ get; } public List Entries{ get; } - public uint Serial - { - get => m_Serial; - set - { - if (m_Serial != value) - { - m_Serial = value; - Invalidate(); - } - } - } + public uint Serial { get; set; } - public int X - { - get => m_X; - set - { - if (m_X != value) - { - m_X = value; - Invalidate(); - } - } - } + public int X { get; set; } - public int Y - { - get => m_Y; - set - { - if (m_Y != value) - { - m_Y = value; - Invalidate(); - } - } - } + public int Y { get; set; } - public bool Disposable - { - get => m_Disposable; - set - { - if (m_Disposable != value) - { - m_Disposable = value; - Invalidate(); - } - } - } + public bool Disposable { get; set; } = true; - public bool Resizable - { - get => m_Resizable; - set - { - if (m_Resizable != value) - { - m_Resizable = value; - Invalidate(); - } - } - } + public bool Resizable { get; set; } = true; - public bool Draggable - { - get => m_Draggable; - set - { - if (m_Draggable != value) - { - m_Draggable = value; - Invalidate(); - } - } - } + public bool Draggable { get; set; } = true; - public bool Closable - { - get => m_Closable; - set - { - if (m_Closable != value) - { - m_Closable = value; - Invalidate(); - } - } - } + public bool Closable { get; set; } = true; public static int GetTypeID(Type type) => type?.FullName?.GetHashCode() ?? -1; @@ -262,7 +177,12 @@ namespace Server.Gumps Add(new GumpRadio(x, y, inactiveID, activeID, initialState, switchID)); } - public void AddTextEntry(int x, int y, int width, int height, int hue, int entryID, string initialText, int size = 0) + public void AddTextEntry( int x, int y, int width, int height, int hue, int entryID, string initialText ) + { + Add( new GumpTextEntry( x, y, width, height, hue, entryID, initialText ) ); + } + + public void AddTextEntry(int x, int y, int width, int height, int hue, int entryID, string initialText, int size) { Add(new GumpTextEntryLimited(x, y, width, height, hue, entryID, initialText, size)); } @@ -275,14 +195,8 @@ namespace Server.Gumps public void Add(GumpEntry g) { if (g.Parent != this) - { g.Parent = this; - } - else if (!Entries.Contains(g)) - { - Invalidate(); - Entries.Add(g); - } + else if (!Entries.Contains(g)) Entries.Add(g); } public void Remove(GumpEntry g) @@ -290,70 +204,120 @@ namespace Server.Gumps if (g == null || !Entries.Contains(g)) return; - Invalidate(); Entries.Remove(g); g.Parent = null; } - public int Intern(string value) - { - int indexOf = m_Strings.IndexOf(value); - - if (indexOf >= 0) return indexOf; - - Invalidate(); - m_Strings.Add(value); - return m_Strings.Count - 1; - } + public static byte[] StringToBuffer(string str) => Encoding.ASCII.GetBytes(str); public void SendTo(NetState state) { state.AddGump(this); - state.Send(Compile(state)); + ArrayBufferWriter bufferWriter = new ArrayBufferWriter(0x10000); + m_TextEntries = 0; + m_Switches = 0; + if (state.Unpack) + CompilePacked(bufferWriter); + else + CompileFast(bufferWriter); + state.Send(bufferWriter.WrittenSpan); + } + + private void WriteLayout(ArrayBufferWriter layoutBuffer, ArraySet strings) + { + if (!Draggable) + layoutBuffer.Write(m_NoMove); + + if (!Closable) + layoutBuffer.Write(m_NoClose); + + if (!Disposable) + layoutBuffer.Write(m_NoDispose); + + if (!Resizable) + layoutBuffer.Write(m_NoResize); + + for (int i = 0; i < Entries.Count; ++i) + Entries[i].AppendTo(layoutBuffer, strings, ref m_TextEntries, ref m_Switches); + } + + private static void WriteStrings(IBufferWriter stringsBuffer, IList strings) + { + int stringLength = 2 * strings.Count + strings.Sum(t => t.Length * 2); + SpanWriter rawStringsWriter = new SpanWriter(stringsBuffer.GetSpan(stringLength)); + + for (int i = 0; i < strings.Count; ++i) + { + string v = strings[i] ?? ""; + + rawStringsWriter.Write((ushort)v.Length); + rawStringsWriter.WriteBigUni(v); + } + + stringsBuffer.Advance(stringLength); } public static byte[] StringToBuffer(string str) => Encoding.ASCII.GetBytes(str); - private Packet Compile(NetState ns = null) + private void CompileFast(IBufferWriter bufferWriter) { - IGumpWriter disp; + SpanWriter writer = new SpanWriter(bufferWriter.GetSpan(21)); + writer.Write((byte)0xB0); // Packed ID + writer.Position += 2; // Dynamic Length - if (ns?.Unpack == true) - disp = new DisplayGumpPacked(this); - else - disp = new DisplayGumpFast(this); + writer.Write(Serial); + writer.Write(TypeID); + writer.Write(X); + writer.Write(Y); - if (!m_Draggable) - disp.AppendLayout(m_NoMove); + ArraySet strings = new ArraySet(); + ArrayBufferWriter layoutBuffer = new ArrayBufferWriter(); + WriteLayout(layoutBuffer, strings); - if (!m_Closable) - disp.AppendLayout(m_NoClose); + writer.Write((ushort)layoutBuffer.WrittenCount); - if (!m_Disposable) - disp.AppendLayout(m_NoDispose); + ArrayBufferWriter stringsBuffer = new ArrayBufferWriter(); + Span span = stringsBuffer.GetSpan(2); + span[0] = (byte)(strings.Count >> 8); + span[1] = (byte)strings.Count; + bufferWriter.Advance(2); + WriteStrings(stringsBuffer, strings); - if (!m_Resizable) - disp.AppendLayout(m_NoResize); + writer.Position = 1; + writer.Write((ushort)(23 + layoutBuffer.WrittenCount + stringsBuffer.WrittenCount)); - int count = Entries.Count; + // Write the header + bufferWriter.Advance(21); - for (int i = 0; i < count; ++i) + // Write the layout + bufferWriter.Write(layoutBuffer.WrittenSpan); + + // Write strings + bufferWriter.Write(stringsBuffer.WrittenSpan); + } + + private static int GetMaxPackedSize(int sourceLength) => 8 + (int)Compression.MaxPackSize((ulong)sourceLength); + + private static int WritePacked(ReadOnlySpan source, Span dest) + { + int length = source.Length; + + if (length == 0) { - GumpEntry e = Entries[i]; - - disp.AppendLayout(m_BeginLayout); - e.AppendTo(ns, disp); - disp.AppendLayout(m_EndLayout); + dest.Clear(); + return 4; } - disp.WriteStrings(m_Strings); + ulong packLength = (ulong)dest.Length - 8; - disp.Flush(); + ZLibError ce = Compression.Pack(dest.Slice(8), ref packLength, source, ZLibQuality.Default); + if (ce != ZLibError.Okay) Console.WriteLine("ZLib error: {0} (#{1})", ce, (int)ce); + SpanWriter writer = new SpanWriter(dest); + int packLengthInt = (int)packLength; + writer.Write(4 + packLengthInt); + writer.Write(length); - m_TextEntries = disp.TextEntries; - m_Switches = disp.Switches; - - return (Packet)disp; + return 8 + packLengthInt; } public virtual void OnResponse(NetState sender, RelayInfo info) diff --git a/Projects/Server/Gumps/GumpAlphaRegion.cs b/Projects/Server/Gumps/GumpAlphaRegion.cs index 20cfefe0d..a26304df0 100644 --- a/Projects/Server/Gumps/GumpAlphaRegion.cs +++ b/Projects/Server/Gumps/GumpAlphaRegion.cs @@ -18,57 +18,46 @@ * ***************************************************************************/ -using Server.Network; +using System.Buffers; +using Server.Buffers; +using Server.Collections; namespace Server.Gumps { public class GumpAlphaRegion : GumpEntry { - private static byte[] m_LayoutName = Gump.StringToBuffer("checkertrans"); - private int m_Width, m_Height; - private int m_X, m_Y; - public GumpAlphaRegion(int x, int y, int width, int height) { - m_X = x; - m_Y = y; - m_Width = width; - m_Height = height; + X = x; + Y = y; + Width = width; + Height = height; } - public int X - { - get => m_X; - set => Delta(ref m_X, value); - } + public int X { get; set; } - public int Y - { - get => m_Y; - set => Delta(ref m_Y, value); - } + public int Y { get; set; } - public int Width - { - get => m_Width; - set => Delta(ref m_Width, value); - } + public int Width { get; set; } - public int Height - { - get => m_Height; - set => Delta(ref m_Height, value); - } + public int Height { get; set; } public override string Compile(NetState ns) => $"{{ checkertrans {m_X} {m_Y} {m_Width} {m_Height} }}"; - public override void AppendTo(NetState ns, IGumpWriter disp) + public override void AppendTo(ArrayBufferWriter buffer, ArraySet strings, ref int entries, ref int switches) { - disp.AppendLayout(m_LayoutName); - disp.AppendLayout(m_X); - disp.AppendLayout(m_Y); - disp.AppendLayout(m_Width); - disp.AppendLayout(m_Height); + SpanWriter writer = new SpanWriter(buffer.GetSpan(60)); + writer.Write(m_LayoutName); + writer.WriteAscii(X.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Y.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Width.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Height.ToString()); + writer.Write((byte)0x20); // ' ' + writer.Write((byte)0x7D); // '}' + buffer.Advance(writer.WrittenCount); } } -} \ No newline at end of file +} diff --git a/Projects/Server/Gumps/GumpBackground.cs b/Projects/Server/Gumps/GumpBackground.cs index 8016cfe1b..a6ea217b9 100644 --- a/Projects/Server/Gumps/GumpBackground.cs +++ b/Projects/Server/Gumps/GumpBackground.cs @@ -18,66 +18,53 @@ * ***************************************************************************/ -using Server.Network; +using System.Buffers; +using Server.Buffers; +using Server.Collections; namespace Server.Gumps { public class GumpBackground : GumpEntry { - private static byte[] m_LayoutName = Gump.StringToBuffer("resizepic"); private int m_GumpID; - private int m_Width, m_Height; - private int m_X, m_Y; public GumpBackground(int x, int y, int width, int height, int gumpID) { - m_X = x; - m_Y = y; - m_Width = width; - m_Height = height; + X = x; + Y = y; + Width = width; + Height = height; m_GumpID = gumpID; } - public int X - { - get => m_X; - set => Delta(ref m_X, value); - } + public int X { get; set; } - public int Y - { - get => m_Y; - set => Delta(ref m_Y, value); - } + public int Y { get; set; } - public int Width - { - get => m_Width; - set => Delta(ref m_Width, value); - } + public int Width { get; set; } - public int Height - { - get => m_Height; - set => Delta(ref m_Height, value); - } + public int Height { get; set; } - public int GumpID - { - get => m_GumpID; - set => Delta(ref m_GumpID, value); - } + public override string Compile(ArraySet strings) => $"{{ resizepic {X} {Y} {m_GumpID} {Width} {Height} }}"; public override string Compile(NetState ns) => $"{{ resizepic {m_X} {m_Y} {m_GumpID} {m_Width} {m_Height} }}"; - public override void AppendTo(NetState ns, IGumpWriter disp) + public override void AppendTo(ArrayBufferWriter buffer, ArraySet strings, ref int entries, ref int switches) { - disp.AppendLayout(m_LayoutName); - disp.AppendLayout(m_X); - disp.AppendLayout(m_Y); - disp.AppendLayout(m_GumpID); - disp.AppendLayout(m_Width); - disp.AppendLayout(m_Height); + SpanWriter writer = new SpanWriter(buffer.GetSpan(68)); + writer.Write(m_LayoutName); + writer.WriteAscii(X.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Y.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(m_GumpID.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Width.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Height.ToString()); + writer.Write((byte)0x20); // ' ' + writer.Write((byte)0x7D); // '}' + buffer.Advance(writer.WrittenCount); } } -} \ No newline at end of file +} diff --git a/Projects/Server/Gumps/GumpButton.cs b/Projects/Server/Gumps/GumpButton.cs index 9186b8e37..db6ccd84d 100644 --- a/Projects/Server/Gumps/GumpButton.cs +++ b/Projects/Server/Gumps/GumpButton.cs @@ -18,7 +18,9 @@ * ***************************************************************************/ -using Server.Network; +using System.Buffers; +using Server.Buffers; +using Server.Collections; namespace Server.Gumps { @@ -30,89 +32,56 @@ namespace Server.Gumps public class GumpButton : GumpEntry { - private static byte[] m_LayoutName = Gump.StringToBuffer("button"); - private int m_ButtonID; - private int m_ID1, m_ID2; - private int m_Param; - private GumpButtonType m_Type; - private int m_X, m_Y; - public GumpButton(int x, int y, int normalID, int pressedID, int buttonID, GumpButtonType type = GumpButtonType.Reply, int param = 0) { - m_X = x; - m_Y = y; - m_ID1 = normalID; - m_ID2 = pressedID; - m_ButtonID = buttonID; - m_Type = type; - m_Param = param; + X = x; + Y = y; + NormalID = normalID; + PressedID = pressedID; + ButtonID = buttonID; + Type = type; + Param = param; } - public int X - { - get => m_X; - set => Delta(ref m_X, value); - } + public int X { get; set; } - public int Y - { - get => m_Y; - set => Delta(ref m_Y, value); - } + public int Y { get; set; } - public int NormalID - { - get => m_ID1; - set => Delta(ref m_ID1, value); - } + public int NormalID { get; set; } - public int PressedID - { - get => m_ID2; - set => Delta(ref m_ID2, value); - } + public int PressedID { get; set; } - public int ButtonID - { - get => m_ButtonID; - set => Delta(ref m_ButtonID, value); - } + public int ButtonID { get; set; } - public GumpButtonType Type - { - get => m_Type; - set - { - if (m_Type != value) - { - m_Type = value; + public GumpButtonType Type { get; set; } - Gump parent = Parent; + public int Param { get; set; } - parent?.Invalidate(); - } - } - } - - public int Param - { - get => m_Param; - set => Delta(ref m_Param, value); - } + public override string Compile(ArraySet strings) => $"{{ button {X} {Y} {NormalID} {PressedID} {(int)Type} {Param} {ButtonID} }}"; public override string Compile(NetState ns) => $"{{ button {m_X} {m_Y} {m_ID1} {m_ID2} {(int)m_Type} {m_Param} {m_ButtonID} }}"; - public override void AppendTo(NetState ns, IGumpWriter disp) + public override void AppendTo(ArrayBufferWriter buffer, ArraySet strings, ref int entries, ref int switches) { - disp.AppendLayout(m_LayoutName); - disp.AppendLayout(m_X); - disp.AppendLayout(m_Y); - disp.AppendLayout(m_ID1); - disp.AppendLayout(m_ID2); - disp.AppendLayout((int)m_Type); - disp.AppendLayout(m_Param); - disp.AppendLayout(m_ButtonID); + SpanWriter writer = new SpanWriter(buffer.GetSpan(68)); + writer.Write(m_LayoutName); + writer.WriteAscii(X.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Y.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(NormalID.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(PressedID.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(((int)Type).ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Param.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(ButtonID.ToString()); + writer.Write((byte)0x20); // ' ' + writer.Write((byte)0x7D); // '}' + buffer.Advance(writer.WrittenCount); } } } diff --git a/Projects/Server/Gumps/GumpCheck.cs b/Projects/Server/Gumps/GumpCheck.cs index afc3a54d0..a765337b7 100644 --- a/Projects/Server/Gumps/GumpCheck.cs +++ b/Projects/Server/Gumps/GumpCheck.cs @@ -18,77 +18,58 @@ * ***************************************************************************/ -using Server.Network; +using System.Buffers; +using Server.Buffers; +using Server.Collections; namespace Server.Gumps { public class GumpCheck : GumpEntry { - private static byte[] m_LayoutName = Gump.StringToBuffer("checkbox"); - private int m_ID1, m_ID2; - private bool m_InitialState; - private int m_SwitchID; - private int m_X, m_Y; - public GumpCheck(int x, int y, int inactiveID, int activeID, bool initialState, int switchID) { - m_X = x; - m_Y = y; - m_ID1 = inactiveID; - m_ID2 = activeID; - m_InitialState = initialState; - m_SwitchID = switchID; + X = x; + Y = y; + InactiveID = inactiveID; + ActiveID = activeID; + InitialState = initialState; + SwitchID = switchID; } - public int X - { - get => m_X; - set => Delta(ref m_X, value); - } + public int X { get; set; } - public int Y - { - get => m_Y; - set => Delta(ref m_Y, value); - } + public int Y { get; set; } - public int InactiveID - { - get => m_ID1; - set => Delta(ref m_ID1, value); - } + public int InactiveID { get; set; } - public int ActiveID - { - get => m_ID2; - set => Delta(ref m_ID2, value); - } + public int ActiveID { get; set; } - public bool InitialState - { - get => m_InitialState; - set => Delta(ref m_InitialState, value); - } + public bool InitialState { get; set; } - public int SwitchID - { - get => m_SwitchID; - set => Delta(ref m_SwitchID, value); - } + public int SwitchID { get; set; } public override string Compile(NetState ns) => $"{{ checkbox {m_X} {m_Y} {m_ID1} {m_ID2} {(m_InitialState ? 1 : 0)} {m_SwitchID} }}"; - public override void AppendTo(NetState ns, IGumpWriter disp) - { - disp.AppendLayout(m_LayoutName); - disp.AppendLayout(m_X); - disp.AppendLayout(m_Y); - disp.AppendLayout(m_ID1); - disp.AppendLayout(m_ID2); - disp.AppendLayout(m_InitialState); - disp.AppendLayout(m_SwitchID); + private static readonly byte[] m_LayoutName = Gump.StringToBuffer("{ checkbox "); - disp.Switches++; + public override void AppendTo(ArrayBufferWriter buffer, ArraySet strings, ref int entries, ref int switches) + { + SpanWriter writer = new SpanWriter(buffer.GetSpan(69)); + writer.Write(m_LayoutName); + writer.WriteAscii(X.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Y.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(InactiveID.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(ActiveID.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(InitialState ? "1" : "0"); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(SwitchID.ToString()); + writer.Write((byte)0x20); // ' ' + writer.Write((byte)0x7D); // '}' + buffer.Advance(writer.WrittenCount); } } -} \ No newline at end of file +} diff --git a/Projects/Server/Gumps/GumpEntry.cs b/Projects/Server/Gumps/GumpEntry.cs index 732125b15..e67726f82 100644 --- a/Projects/Server/Gumps/GumpEntry.cs +++ b/Projects/Server/Gumps/GumpEntry.cs @@ -18,7 +18,8 @@ * ***************************************************************************/ -using Server.Network; +using System.Buffers; +using Server.Collections; namespace Server.Gumps { @@ -42,37 +43,7 @@ namespace Server.Gumps } } - protected void Delta(ref uint var, uint val) - { - if (var != val) - var = val; - } - - protected void Delta(ref int var, int val) - { - if (var != val) - var = val; - } - - protected void Delta(ref bool var, bool val) - { - if (var != val) - var = val; - } - - protected void Delta(ref string var, string val) - { - if (var != val) - var = val; - } - - protected void Delta(ref object[] var, object[] val) - { - if (var != val) - var = val; - } - - public abstract string Compile(NetState ns); - public abstract void AppendTo(NetState ns, IGumpWriter disp); + public abstract string Compile(ArraySet strings); + public abstract void AppendTo(ArrayBufferWriter buffer, ArraySet strings, ref int entries, ref int switches); } } diff --git a/Projects/Server/Gumps/GumpGroup.cs b/Projects/Server/Gumps/GumpGroup.cs index 93418d837..3d32b9da9 100644 --- a/Projects/Server/Gumps/GumpGroup.cs +++ b/Projects/Server/Gumps/GumpGroup.cs @@ -18,29 +18,30 @@ * ***************************************************************************/ -using Server.Network; +using System.Buffers; +using Server.Buffers; +using Server.Collections; namespace Server.Gumps { public class GumpGroup : GumpEntry { - private static byte[] m_LayoutName = Gump.StringToBuffer("group"); - private int m_Group; + public GumpGroup(int group) => Group = group; public GumpGroup(int group) => m_Group = group; - public int Group - { - get => m_Group; - set => Delta(ref m_Group, value); - } + public override string Compile(ArraySet strings) => $"{{ group {Group} }}"; public override string Compile(NetState ns) => $"{{ group {m_Group} }}"; - public override void AppendTo(NetState ns, IGumpWriter disp) + public override void AppendTo(ArrayBufferWriter buffer, ArraySet strings, ref int entries, ref int switches) { - disp.AppendLayout(m_LayoutName); - disp.AppendLayout(m_Group); + SpanWriter writer = new SpanWriter(buffer.GetSpan(20)); + writer.Write(m_LayoutName); + writer.WriteAscii(Group.ToString()); + writer.Write((byte)0x20); // ' ' + writer.Write((byte)0x7D); // '}' + buffer.Advance(writer.WrittenCount); } } -} \ No newline at end of file +} diff --git a/Projects/Server/Gumps/GumpHtml.cs b/Projects/Server/Gumps/GumpHtml.cs index 12cd813e4..a9dde3634 100644 --- a/Projects/Server/Gumps/GumpHtml.cs +++ b/Projects/Server/Gumps/GumpHtml.cs @@ -18,83 +18,61 @@ * ***************************************************************************/ -using Server.Network; +using System.Buffers; +using Server.Buffers; +using Server.Collections; namespace Server.Gumps { public class GumpHtml : GumpEntry { - private static byte[] m_LayoutName = Gump.StringToBuffer("htmlgump"); - private bool m_Background, m_Scrollbar; - private string m_Text; - private int m_Width, m_Height; - private int m_X, m_Y; - public GumpHtml(int x, int y, int width, int height, string text, bool background, bool scrollbar) { - m_X = x; - m_Y = y; - m_Width = width; - m_Height = height; - m_Text = text; - m_Background = background; - m_Scrollbar = scrollbar; + X = x; + Y = y; + Width = width; + Height = height; + Text = text; + Background = background; + Scrollbar = scrollbar; } - public int X - { - get => m_X; - set => Delta(ref m_X, value); - } + public int X { get; set; } - public int Y - { - get => m_Y; - set => Delta(ref m_Y, value); - } + public int Y { get; set; } - public int Width - { - get => m_Width; - set => Delta(ref m_Width, value); - } + public int Width { get; set; } - public int Height - { - get => m_Height; - set => Delta(ref m_Height, value); - } + public int Height { get; set; } - public string Text - { - get => m_Text; - set => Delta(ref m_Text, value); - } + public string Text { get; set; } - public bool Background - { - get => m_Background; - set => Delta(ref m_Background, value); - } + public bool Background { get; set; } - public bool Scrollbar - { - get => m_Scrollbar; - set => Delta(ref m_Scrollbar, value); - } + public bool Scrollbar { get; set; } public override string Compile(NetState ns) => $"{{ htmlgump {m_X} {m_Y} {m_Width} {m_Height} {Parent.Intern(m_Text)} {(m_Background ? 1 : 0)} {(m_Scrollbar ? 1 : 0)} }}"; - public override void AppendTo(NetState ns, IGumpWriter disp) + public override void AppendTo(ArrayBufferWriter buffer, ArraySet strings, ref int entries, ref int switches) { - disp.AppendLayout(m_LayoutName); - disp.AppendLayout(m_X); - disp.AppendLayout(m_Y); - disp.AppendLayout(m_Width); - disp.AppendLayout(m_Height); - disp.AppendLayout(Parent.Intern(m_Text)); - disp.AppendLayout(m_Background); - disp.AppendLayout(m_Scrollbar); + SpanWriter writer = new SpanWriter(buffer.GetSpan(71)); + writer.Write(m_LayoutName); + writer.WriteAscii(X.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Y.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Width.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Height.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(strings.Add(Text).ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Background ? "1" : "0"); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Scrollbar ? "1" : "0"); + writer.Write((byte)0x20); // ' ' + writer.Write((byte)0x7D); // '}' + buffer.Advance(writer.WrittenCount); } } -} \ No newline at end of file +} diff --git a/Projects/Server/Gumps/GumpHtmlLocalized.cs b/Projects/Server/Gumps/GumpHtmlLocalized.cs index ad8bf533e..e87af43d0 100644 --- a/Projects/Server/Gumps/GumpHtmlLocalized.cs +++ b/Projects/Server/Gumps/GumpHtmlLocalized.cs @@ -18,7 +18,9 @@ * ***************************************************************************/ -using Server.Network; +using System.Buffers; +using Server.Buffers; +using Server.Collections; namespace Server.Gumps { @@ -31,45 +33,33 @@ namespace Server.Gumps public class GumpHtmlLocalized : GumpEntry { - private static byte[] m_LayoutNamePlain = Gump.StringToBuffer("xmfhtmlgump"); - private static byte[] m_LayoutNameColor = Gump.StringToBuffer("xmfhtmlgumpcolor"); - private static byte[] m_LayoutNameArgs = Gump.StringToBuffer("xmfhtmltok"); - private string m_Args; - private bool m_Background, m_Scrollbar; - private int m_Color; - private int m_Number; - - private GumpHtmlLocalizedType m_Type; - private int m_Width, m_Height; - private int m_X, m_Y; - public GumpHtmlLocalized(int x, int y, int width, int height, int number, bool background = false, bool scrollbar = false) { - m_X = x; - m_Y = y; - m_Width = width; - m_Height = height; - m_Number = number; - m_Background = background; - m_Scrollbar = scrollbar; + X = x; + Y = y; + Width = width; + Height = height; + Number = number; + Background = background; + Scrollbar = scrollbar; - m_Type = GumpHtmlLocalizedType.Plain; + Type = GumpHtmlLocalizedType.Plain; } public GumpHtmlLocalized(int x, int y, int width, int height, int number, int color, bool background = false, bool scrollbar = false) { - m_X = x; - m_Y = y; - m_Width = width; - m_Height = height; - m_Number = number; - m_Color = color; - m_Background = background; - m_Scrollbar = scrollbar; + X = x; + Y = y; + Width = width; + Height = height; + Number = number; + Color = color; + Background = background; + Scrollbar = scrollbar; - m_Type = GumpHtmlLocalizedType.Color; + Type = GumpHtmlLocalizedType.Color; } public GumpHtmlLocalized(int x, int y, int width, int height, int number, string args, int color, @@ -77,81 +67,38 @@ namespace Server.Gumps { // Are multiple arguments unsupported? And what about non ASCII arguments? - m_X = x; - m_Y = y; - m_Width = width; - m_Height = height; - m_Number = number; - m_Args = args; - m_Color = color; - m_Background = background; - m_Scrollbar = scrollbar; + X = x; + Y = y; + Width = width; + Height = height; + Number = number; + Args = args; + Color = color; + Background = background; + Scrollbar = scrollbar; - m_Type = GumpHtmlLocalizedType.Args; + Type = GumpHtmlLocalizedType.Args; } - public int X - { - get => m_X; - set => Delta(ref m_X, value); - } + public int X { get; set; } - public int Y - { - get => m_Y; - set => Delta(ref m_Y, value); - } + public int Y { get; set; } - public int Width - { - get => m_Width; - set => Delta(ref m_Width, value); - } + public int Width { get; set; } - public int Height - { - get => m_Height; - set => Delta(ref m_Height, value); - } + public int Height { get; set; } - public int Number - { - get => m_Number; - set => Delta(ref m_Number, value); - } + public int Number { get; set; } - public string Args - { - get => m_Args; - set => Delta(ref m_Args, value); - } + public string Args { get; set; } - public int Color - { - get => m_Color; - set => Delta(ref m_Color, value); - } + public int Color { get; set; } - public bool Background - { - get => m_Background; - set => Delta(ref m_Background, value); - } + public bool Background { get; set; } - public bool Scrollbar - { - get => m_Scrollbar; - set => Delta(ref m_Scrollbar, value); - } + public bool Scrollbar { get; set; } - public GumpHtmlLocalizedType Type - { - get => m_Type; - set - { - if (m_Type != value) - { - m_Type = value; + public GumpHtmlLocalizedType Type { get; set; } Parent?.Invalidate(); } @@ -173,56 +120,81 @@ namespace Server.Gumps public override void AppendTo(NetState ns, IGumpWriter disp) { - switch (m_Type) + SpanWriter writer = new SpanWriter(buffer.GetSpan(90 + Args?.Length ?? 0)); + switch (Type) { case GumpHtmlLocalizedType.Plain: { - disp.AppendLayout(m_LayoutNamePlain); - - disp.AppendLayout(m_X); - disp.AppendLayout(m_Y); - disp.AppendLayout(m_Width); - disp.AppendLayout(m_Height); - disp.AppendLayout(m_Number); - disp.AppendLayout(m_Background); - disp.AppendLayout(m_Scrollbar); + writer.Write(m_LayoutNamePlain); + writer.WriteAscii(X.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Y.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Width.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Height.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Number.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Background ? "1" : "0"); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Scrollbar ? "1" : "0"); break; } case GumpHtmlLocalizedType.Color: { - disp.AppendLayout(m_LayoutNameColor); - - disp.AppendLayout(m_X); - disp.AppendLayout(m_Y); - disp.AppendLayout(m_Width); - disp.AppendLayout(m_Height); - disp.AppendLayout(m_Number); - disp.AppendLayout(m_Background); - disp.AppendLayout(m_Scrollbar); - disp.AppendLayout(m_Color); + writer.Write(m_LayoutNameColor); + writer.WriteAscii(X.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Y.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Width.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Height.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Number.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Background ? "1" : "0"); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Scrollbar ? "1" : "0"); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Color.ToString()); break; } case GumpHtmlLocalizedType.Args: { - disp.AppendLayout(m_LayoutNameArgs); - - disp.AppendLayout(m_X); - disp.AppendLayout(m_Y); - disp.AppendLayout(m_Width); - disp.AppendLayout(m_Height); - disp.AppendLayout(m_Background); - disp.AppendLayout(m_Scrollbar); - disp.AppendLayout(m_Color); - disp.AppendLayout(m_Number); - disp.AppendLayout(m_Args); + writer.Write(m_LayoutNameArgs); + writer.WriteAscii(X.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Y.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Width.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Height.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Background ? "1" : "0"); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Scrollbar ? "1" : "0"); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Color.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Number.ToString()); + writer.Write((byte)0x20); // ' ' + writer.Write((byte)0x40); // '@' + writer.WriteAscii(Args ?? ""); + writer.Write((byte)0x40); // '@' break; } } + + writer.Write((byte)0x20); // ' ' + writer.Write((byte)0x7D); // '}' + buffer.Advance(writer.WrittenCount); } } } diff --git a/Projects/Server/Gumps/GumpImage.cs b/Projects/Server/Gumps/GumpImage.cs index 26d013222..401b90b35 100644 --- a/Projects/Server/Gumps/GumpImage.cs +++ b/Projects/Server/Gumps/GumpImage.cs @@ -18,66 +18,68 @@ * ***************************************************************************/ -using Server.Network; +using System.Buffers; +using Server.Buffers; +using Server.Collections; namespace Server.Gumps { public class GumpImage : GumpEntry { - private static byte[] m_LayoutName = Gump.StringToBuffer("gumppic"); - private static byte[] m_HueEquals = Gump.StringToBuffer(" hue="); - private int m_GumpID; - private int m_Hue; - private int m_X, m_Y; - public GumpImage(int x, int y, int gumpID, int hue = 0) { - m_X = x; - m_Y = y; - m_GumpID = gumpID; - m_Hue = hue; + X = x; + Y = y; + GumpID = gumpID; + Hue = hue; } - public int X + public GumpImage(int x, int y, int gumpID, int hue = 0, string cls = null) { - get => m_X; - set => Delta(ref m_X, value); + X = x; + Y = y; + GumpID = gumpID; + Hue = hue; + Class = cls; } - public int Y - { - get => m_Y; - set => Delta(ref m_Y, value); - } + public int X { get; set; } - public int GumpID - { - get => m_GumpID; - set => Delta(ref m_GumpID, value); - } + public int Y { get; set; } - public int Hue - { - get => m_Hue; - set => Delta(ref m_Hue, value); - } + public int GumpID { get; set; } public override string Compile(NetState ns) => m_Hue == 0 ? $"{{ gumppic {m_X} {m_Y} {m_GumpID} }}" : $"{{ gumppic {m_X} {m_Y} {m_GumpID} hue={m_Hue} }}"; - public override void AppendTo(NetState ns, IGumpWriter disp) + public override void AppendTo(ArrayBufferWriter buffer, ArraySet strings, ref int entries, ref int switches) { - disp.AppendLayout(m_LayoutName); - disp.AppendLayout(m_X); - disp.AppendLayout(m_Y); - disp.AppendLayout(m_GumpID); + SpanWriter writer = new SpanWriter(buffer.GetSpan(66 + Class?.Length ?? 0)); + writer.Write(m_LayoutName); + writer.WriteAscii(X.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Y.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(GumpID.ToString()); + writer.Write((byte)0x20); // ' ' - if (m_Hue != 0) + if (Hue != 0) { - disp.AppendLayout(m_HueEquals); - disp.AppendLayoutNS(m_Hue); + writer.Write(m_HueEquals); + writer.WriteAscii(Hue.ToString()); + writer.Write((byte)0x20); // ' ' } + + if (!string.IsNullOrWhiteSpace(Class)) + { + writer.Write(m_ClassEquals); + writer.WriteAscii(Class); + writer.Write((byte)0x20); // ' ' + } + + writer.Write((byte)0x7D); // '}' + buffer.Advance(writer.WrittenCount); } } } diff --git a/Projects/Server/Gumps/GumpImageTileButton.cs b/Projects/Server/Gumps/GumpImageTileButton.cs index a7fcfc4c0..58417cc3b 100644 --- a/Projects/Server/Gumps/GumpImageTileButton.cs +++ b/Projects/Server/Gumps/GumpImageTileButton.cs @@ -18,155 +18,101 @@ * ***************************************************************************/ -using Server.Network; +using System.Buffers; +using Server.Buffers; +using Server.Collections; namespace Server.Gumps { public class GumpImageTileButton : GumpEntry { - private static byte[] m_LayoutName = Gump.StringToBuffer("buttontileart"); - private static byte[] m_LayoutTooltip = Gump.StringToBuffer(" }{ tooltip"); - private int m_ButtonID; - private int m_Height; - private int m_Hue; - private int m_ID1, m_ID2; - - private int m_ItemID; - private int m_Param; - private GumpButtonType m_Type; - - private int m_Width; - //Note, on OSI, The tooltip supports ONLY clilocs as far as I can figure out, and the tooltip ONLY works after the buttonTileArt (as far as I can tell from testing) - private int m_X, m_Y; public GumpImageTileButton(int x, int y, int normalID, int pressedID, int buttonID, GumpButtonType type, int param, int itemID, int hue, int width, int height, int localizedTooltip = -1) { - m_X = x; - m_Y = y; - m_ID1 = normalID; - m_ID2 = pressedID; - m_ButtonID = buttonID; - m_Type = type; - m_Param = param; + X = x; + Y = y; + NormalID = normalID; + PressedID = pressedID; + ButtonID = buttonID; + Type = type; + Param = param; - m_ItemID = itemID; - m_Hue = hue; - m_Width = width; - m_Height = height; + ItemID = itemID; + Hue = hue; + Width = width; + Height = height; LocalizedTooltip = localizedTooltip; } - public int X - { - get => m_X; - set => Delta(ref m_X, value); - } + public int X { get; set; } - public int Y - { - get => m_Y; - set => Delta(ref m_Y, value); - } + public int Y { get; set; } - public int NormalID - { - get => m_ID1; - set => Delta(ref m_ID1, value); - } + public int NormalID { get; set; } - public int PressedID - { - get => m_ID2; - set => Delta(ref m_ID2, value); - } + public int PressedID { get; set; } - public int ButtonID - { - get => m_ButtonID; - set => Delta(ref m_ButtonID, value); - } + public int ButtonID { get; set; } - public GumpButtonType Type - { - get => m_Type; - set - { - if (m_Type != value) - { - m_Type = value; + public GumpButtonType Type { get; set; } - Gump parent = Parent; + public int Param { get; set; } - parent?.Invalidate(); - } - } - } + public int ItemID { get; set; } - public int Param - { - get => m_Param; - set => Delta(ref m_Param, value); - } + public int Hue { get; set; } - public int ItemID - { - get => m_ItemID; - set => Delta(ref m_ItemID, value); - } + public int Width { get; set; } - public int Hue - { - get => m_Hue; - set => Delta(ref m_Hue, value); - } - - public int Width - { - get => m_Width; - set => Delta(ref m_Width, value); - } - - public int Height - { - get => m_Height; - set => Delta(ref m_Height, value); - } + public int Height { get; set; } public int LocalizedTooltip{ get; set; } - public override string Compile(NetState ns) - { - if (LocalizedTooltip > 0) - return - $"{{ buttontileart {m_X} {m_Y} {m_ID1} {m_ID2} {(int)m_Type} {m_Param} {m_ButtonID} {m_ItemID} {m_Hue} {m_Width} {m_Height} }}{{ tooltip {LocalizedTooltip} }}"; - return - $"{{ buttontileart {m_X} {m_Y} {m_ID1} {m_ID2} {(int)m_Type} {m_Param} {m_ButtonID} {m_ItemID} {m_Hue} {m_Width} {m_Height} }}"; - } + public override string Compile(ArraySet strings) => + $"{{ buttontileart {X} {Y} {NormalID} {PressedID} {(int)Type} {Param} {ButtonID} {ItemID} {Hue} {Width} {Height} }}{(LocalizedTooltip > 0 ? $"{{ tooltip {LocalizedTooltip} }}" : "")}"; - public override void AppendTo(NetState ns, IGumpWriter disp) - { - disp.AppendLayout(m_LayoutName); - disp.AppendLayout(m_X); - disp.AppendLayout(m_Y); - disp.AppendLayout(m_ID1); - disp.AppendLayout(m_ID2); - disp.AppendLayout((int)m_Type); - disp.AppendLayout(m_Param); - disp.AppendLayout(m_ButtonID); + private static readonly byte[] m_LayoutName = Gump.StringToBuffer("{ buttontileart "); + private static readonly byte[] m_LayoutTooltip = Gump.StringToBuffer(" }{ tooltip "); - disp.AppendLayout(m_ItemID); - disp.AppendLayout(m_Hue); - disp.AppendLayout(m_Width); - disp.AppendLayout(m_Height); + public override void AppendTo(ArrayBufferWriter buffer, ArraySet strings, ref int entries, ref int switches) + { + SpanWriter writer = new SpanWriter(buffer.GetSpan(160)); + writer.Write(m_LayoutName); + writer.WriteAscii(X.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Y.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(NormalID.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(PressedID.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(((int)Type).ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Param.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(ButtonID.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(ItemID.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Hue.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Width.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Height.ToString()); + writer.Write((byte)0x20); // ' ' if (LocalizedTooltip > 0) { - disp.AppendLayout(m_LayoutTooltip); - disp.AppendLayout(LocalizedTooltip); + writer.Write(m_LayoutTooltip); + writer.WriteAscii(LocalizedTooltip.ToString()); + writer.Write((byte)0x20); // ' ' } + + writer.Write((byte)0x7D); // '}' + buffer.Advance(writer.WrittenCount); } } } diff --git a/Projects/Server/Gumps/GumpImageTiled.cs b/Projects/Server/Gumps/GumpImageTiled.cs index e090bdf3a..af8854d44 100644 --- a/Projects/Server/Gumps/GumpImageTiled.cs +++ b/Projects/Server/Gumps/GumpImageTiled.cs @@ -18,66 +18,51 @@ * ***************************************************************************/ -using Server.Network; +using System.Buffers; +using Server.Buffers; +using Server.Collections; namespace Server.Gumps { public class GumpImageTiled : GumpEntry { - private static byte[] m_LayoutName = Gump.StringToBuffer("gumppictiled"); - private int m_GumpID; - private int m_Width, m_Height; - private int m_X, m_Y; - public GumpImageTiled(int x, int y, int width, int height, int gumpID) { - m_X = x; - m_Y = y; - m_Width = width; - m_Height = height; - m_GumpID = gumpID; + X = x; + Y = y; + Width = width; + Height = height; + GumpID = gumpID; } - public int X - { - get => m_X; - set => Delta(ref m_X, value); - } + public int X { get; set; } - public int Y - { - get => m_Y; - set => Delta(ref m_Y, value); - } + public int Y { get; set; } - public int Width - { - get => m_Width; - set => Delta(ref m_Width, value); - } + public int Width { get; set; } - public int Height - { - get => m_Height; - set => Delta(ref m_Height, value); - } + public int Height { get; set; } - public int GumpID - { - get => m_GumpID; - set => Delta(ref m_GumpID, value); - } + public int GumpID { get; set; } public override string Compile(NetState ns) => $"{{ gumppictiled {m_X} {m_Y} {m_Width} {m_Height} {m_GumpID} }}"; - public override void AppendTo(NetState ns, IGumpWriter disp) + public override void AppendTo(ArrayBufferWriter buffer, ArraySet strings, ref int entries, ref int switches) { - disp.AppendLayout(m_LayoutName); - disp.AppendLayout(m_X); - disp.AppendLayout(m_Y); - disp.AppendLayout(m_Width); - disp.AppendLayout(m_Height); - disp.AppendLayout(m_GumpID); + SpanWriter writer = new SpanWriter(buffer.GetSpan(71)); + writer.Write(m_LayoutName); + writer.WriteAscii(X.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Y.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Width.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Height.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(GumpID.ToString()); + writer.Write((byte)0x20); // ' ' + writer.Write((byte)0x7D); // '}' + buffer.Advance(writer.WrittenCount); } } -} \ No newline at end of file +} diff --git a/Projects/Server/Gumps/GumpItem.cs b/Projects/Server/Gumps/GumpItem.cs index 8420886ea..f2e08327f 100644 --- a/Projects/Server/Gumps/GumpItem.cs +++ b/Projects/Server/Gumps/GumpItem.cs @@ -18,63 +18,58 @@ * ***************************************************************************/ -using Server.Network; +using System.Buffers; +using Server.Buffers; +using Server.Collections; namespace Server.Gumps { public class GumpItem : GumpEntry { - private static byte[] m_LayoutName = Gump.StringToBuffer("tilepic"); - private static byte[] m_LayoutNameHue = Gump.StringToBuffer("tilepichue"); - private int m_Hue; - private int m_ItemID; - private int m_X, m_Y; - public GumpItem(int x, int y, int itemID, int hue = 0) { - m_X = x; - m_Y = y; - m_ItemID = itemID; - m_Hue = hue; + X = x; + Y = y; + ItemID = itemID; + Hue = hue; } - public int X - { - get => m_X; - set => Delta(ref m_X, value); - } + public int X { get; set; } - public int Y - { - get => m_Y; - set => Delta(ref m_Y, value); - } + public int Y { get; set; } - public int ItemID - { - get => m_ItemID; - set => Delta(ref m_ItemID, value); - } + public int ItemID { get; set; } - public int Hue - { - get => m_Hue; - set => Delta(ref m_Hue, value); - } + public int Hue { get; set; } public override string Compile(NetState ns) => m_Hue == 0 ? $"{{ tilepic {m_X} {m_Y} {m_ItemID} }}" : $"{{ tilepichue {m_X} {m_Y} {m_ItemID} {m_Hue} }}"; - public override void AppendTo(NetState ns, IGumpWriter disp) - { - disp.AppendLayout(m_Hue == 0 ? m_LayoutName : m_LayoutNameHue); - disp.AppendLayout(m_X); - disp.AppendLayout(m_Y); - disp.AppendLayout(m_ItemID); + private static readonly byte[] m_LayoutName = Gump.StringToBuffer("{ tilepic "); + private static readonly byte[] m_LayoutNameHue = Gump.StringToBuffer("{ tilepichue "); - if (m_Hue != 0) - disp.AppendLayout(m_Hue); + public override void AppendTo(ArrayBufferWriter buffer, ArraySet strings, ref int entries, ref int switches) + { + SpanWriter writer = new SpanWriter(buffer.GetSpan(57)); + writer.Write(Hue == 0 ? m_LayoutName : m_LayoutNameHue); + writer.WriteAscii(X.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Y.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(ItemID.ToString()); + writer.Write((byte)0x20); // ' ' + + if (Hue != 0) + { + writer.WriteAscii(Hue.ToString()); + writer.Write((byte)0x20); // ' ' + } + + writer.Write((byte)0x20); // ' ' + writer.Write((byte)0x7D); // '}' + + buffer.Advance(writer.WrittenCount); } } } diff --git a/Projects/Server/Gumps/GumpItemProperty.cs b/Projects/Server/Gumps/GumpItemProperty.cs index 5ce65e19e..b791cde3f 100644 --- a/Projects/Server/Gumps/GumpItemProperty.cs +++ b/Projects/Server/Gumps/GumpItemProperty.cs @@ -18,29 +18,31 @@ * ***************************************************************************/ -using Server.Network; +using System.Buffers; +using Server.Buffers; +using Server.Collections; namespace Server.Gumps { public class GumpItemProperty : GumpEntry { - private static byte[] m_LayoutName = Gump.StringToBuffer("itemproperty"); - private uint m_Serial; + public GumpItemProperty(uint serial) => Serial = serial; public GumpItemProperty(uint serial) => m_Serial = serial; - public uint Serial - { - get => m_Serial; - set => Delta(ref m_Serial, value); - } + public override string Compile(ArraySet strings) => $"{{ itemproperty {Serial} }}"; public override string Compile(NetState ns) => $"{{ itemproperty {m_Serial} }}"; - public override void AppendTo(NetState ns, IGumpWriter disp) + public override void AppendTo(ArrayBufferWriter buffer, ArraySet strings, ref int entries, ref int switches) { - disp.AppendLayout(m_LayoutName); - disp.AppendLayout(m_Serial); + SpanWriter writer = new SpanWriter(buffer.GetSpan(27)); + writer.Write(m_LayoutName); + writer.WriteAscii(Serial.ToString()); + writer.Write((byte)0x20); // ' ' + writer.Write((byte)0x7D); // '}' + + buffer.Advance(writer.WrittenCount); } } -} \ No newline at end of file +} diff --git a/Projects/Server/Gumps/GumpLabel.cs b/Projects/Server/Gumps/GumpLabel.cs index d8a0c3389..52028d4e7 100644 --- a/Projects/Server/Gumps/GumpLabel.cs +++ b/Projects/Server/Gumps/GumpLabel.cs @@ -18,58 +18,47 @@ * ***************************************************************************/ -using Server.Network; +using System.Buffers; +using Server.Buffers; +using Server.Collections; namespace Server.Gumps { public class GumpLabel : GumpEntry { - private static byte[] m_LayoutName = Gump.StringToBuffer("text"); - private int m_Hue; - private string m_Text; - private int m_X, m_Y; - public GumpLabel(int x, int y, int hue, string text) { - m_X = x; - m_Y = y; - m_Hue = hue; - m_Text = text; + X = x; + Y = y; + Hue = hue; + Text = text; } - public int X - { - get => m_X; - set => Delta(ref m_X, value); - } + public int X { get; set; } - public int Y - { - get => m_Y; - set => Delta(ref m_Y, value); - } + public int Y { get; set; } - public int Hue - { - get => m_Hue; - set => Delta(ref m_Hue, value); - } + public int Hue { get; set; } - public string Text - { - get => m_Text; - set => Delta(ref m_Text, value); - } + public string Text { get; set; } public override string Compile(NetState ns) => $"{{ text {m_X} {m_Y} {m_Hue} {Parent.Intern(m_Text)} }}"; - public override void AppendTo(NetState ns, IGumpWriter disp) + public override void AppendTo(ArrayBufferWriter buffer, ArraySet strings, ref int entries, ref int switches) { - disp.AppendLayout(m_LayoutName); - disp.AppendLayout(m_X); - disp.AppendLayout(m_Y); - disp.AppendLayout(m_Hue); - disp.AppendLayout(Parent.Intern(m_Text)); + SpanWriter writer = new SpanWriter(buffer.GetSpan(52)); + writer.Write(m_LayoutName); + writer.WriteAscii(X.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Y.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Hue.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(strings.Add(Text).ToString()); + writer.Write((byte)0x20); // ' ' + writer.Write((byte)0x7D); // '}' + + buffer.Advance(writer.WrittenCount); } } -} \ No newline at end of file +} diff --git a/Projects/Server/Gumps/GumpLabelCropped.cs b/Projects/Server/Gumps/GumpLabelCropped.cs index 462968311..62243a73d 100644 --- a/Projects/Server/Gumps/GumpLabelCropped.cs +++ b/Projects/Server/Gumps/GumpLabelCropped.cs @@ -18,75 +18,59 @@ * ***************************************************************************/ -using Server.Network; +using System.Buffers; +using Server.Buffers; +using Server.Collections; namespace Server.Gumps { public class GumpLabelCropped : GumpEntry { - private static byte[] m_LayoutName = Gump.StringToBuffer("croppedtext"); - private int m_Hue; - private string m_Text; - private int m_Width, m_Height; - private int m_X, m_Y; - public GumpLabelCropped(int x, int y, int width, int height, int hue, string text) { - m_X = x; - m_Y = y; - m_Width = width; - m_Height = height; - m_Hue = hue; - m_Text = text; + X = x; + Y = y; + Width = width; + Height = height; + Hue = hue; + Text = text; } - public int X - { - get => m_X; - set => Delta(ref m_X, value); - } + public int X { get; set; } - public int Y - { - get => m_Y; - set => Delta(ref m_Y, value); - } + public int Y { get; set; } - public int Width - { - get => m_Width; - set => Delta(ref m_Width, value); - } + public int Width { get; set; } - public int Height - { - get => m_Height; - set => Delta(ref m_Height, value); - } + public int Height { get; set; } - public int Hue - { - get => m_Hue; - set => Delta(ref m_Hue, value); - } + public int Hue { get; set; } - public string Text - { - get => m_Text; - set => Delta(ref m_Text, value); - } + public string Text { get; set; } public override string Compile(NetState ns) => $"{{ croppedtext {m_X} {m_Y} {m_Width} {m_Height} {m_Hue} {Parent.Intern(m_Text)} }}"; - public override void AppendTo(NetState ns, IGumpWriter disp) + private static readonly byte[] m_LayoutName = Gump.StringToBuffer("{ croppedtext "); + + public override void AppendTo(ArrayBufferWriter buffer, ArraySet strings, ref int entries, ref int switches) { - disp.AppendLayout(m_LayoutName); - disp.AppendLayout(m_X); - disp.AppendLayout(m_Y); - disp.AppendLayout(m_Width); - disp.AppendLayout(m_Height); - disp.AppendLayout(m_Hue); - disp.AppendLayout(Parent.Intern(m_Text)); + SpanWriter writer = new SpanWriter(buffer.GetSpan(81)); + writer.Write(m_LayoutName); + writer.WriteAscii(X.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Y.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Width.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Height.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Hue.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(strings.Add(Text).ToString()); + writer.Write((byte)0x20); // ' ' + writer.Write((byte)0x7D); // '}' + + buffer.Advance(writer.WrittenCount); } } -} \ No newline at end of file +} diff --git a/Projects/Server/Gumps/GumpPage.cs b/Projects/Server/Gumps/GumpPage.cs index 8b5479512..38b99e88d 100644 --- a/Projects/Server/Gumps/GumpPage.cs +++ b/Projects/Server/Gumps/GumpPage.cs @@ -18,29 +18,31 @@ * ***************************************************************************/ -using Server.Network; +using System.Buffers; +using Server.Buffers; +using Server.Collections; namespace Server.Gumps { public class GumpPage : GumpEntry { - private static byte[] m_LayoutName = Gump.StringToBuffer("page"); - private int m_Page; + public GumpPage(int page) => Page = page; public GumpPage(int page) => m_Page = page; - public int Page - { - get => m_Page; - set => Delta(ref m_Page, value); - } + public override string Compile(ArraySet strings) => $"{{ page {Page} }}"; public override string Compile(NetState ns) => $"{{ page {m_Page} }}"; - public override void AppendTo(NetState ns, IGumpWriter disp) + public override void AppendTo(ArrayBufferWriter buffer, ArraySet strings, ref int entries, ref int switches) { - disp.AppendLayout(m_LayoutName); - disp.AppendLayout(m_Page); + SpanWriter writer = new SpanWriter(buffer.GetSpan(19)); + writer.Write(m_LayoutName); + writer.WriteAscii(Page.ToString()); + writer.Write((byte)0x20); // ' ' + writer.Write((byte)0x7D); // '}' + + buffer.Advance(writer.WrittenCount); } } -} \ No newline at end of file +} diff --git a/Projects/Server/Gumps/GumpRadio.cs b/Projects/Server/Gumps/GumpRadio.cs index 740c3d9b1..011693c3a 100644 --- a/Projects/Server/Gumps/GumpRadio.cs +++ b/Projects/Server/Gumps/GumpRadio.cs @@ -18,77 +18,61 @@ * ***************************************************************************/ -using Server.Network; +using System.Buffers; +using Server.Buffers; +using Server.Collections; namespace Server.Gumps { public class GumpRadio : GumpEntry { - private static byte[] m_LayoutName = Gump.StringToBuffer("radio"); - private int m_ID1, m_ID2; - private bool m_InitialState; - private int m_SwitchID; - private int m_X, m_Y; - public GumpRadio(int x, int y, int inactiveID, int activeID, bool initialState, int switchID) { - m_X = x; - m_Y = y; - m_ID1 = inactiveID; - m_ID2 = activeID; - m_InitialState = initialState; - m_SwitchID = switchID; + X = x; + Y = y; + InactiveID = inactiveID; + ActiveID = activeID; + InitialState = initialState; + SwitchID = switchID; } - public int X - { - get => m_X; - set => Delta(ref m_X, value); - } + public int X { get; set; } - public int Y - { - get => m_Y; - set => Delta(ref m_Y, value); - } + public int Y { get; set; } - public int InactiveID - { - get => m_ID1; - set => Delta(ref m_ID1, value); - } + public int InactiveID { get; set; } - public int ActiveID - { - get => m_ID2; - set => Delta(ref m_ID2, value); - } + public int ActiveID { get; set; } - public bool InitialState - { - get => m_InitialState; - set => Delta(ref m_InitialState, value); - } + public bool InitialState { get; set; } - public int SwitchID - { - get => m_SwitchID; - set => Delta(ref m_SwitchID, value); - } + public int SwitchID { get; set; } public override string Compile(NetState ns) => $"{{ radio {m_X} {m_Y} {m_ID1} {m_ID2} {(m_InitialState ? 1 : 0)} {m_SwitchID} }}"; - public override void AppendTo(NetState ns, IGumpWriter disp) - { - disp.AppendLayout(m_LayoutName); - disp.AppendLayout(m_X); - disp.AppendLayout(m_Y); - disp.AppendLayout(m_ID1); - disp.AppendLayout(m_ID2); - disp.AppendLayout(m_InitialState); - disp.AppendLayout(m_SwitchID); + private static readonly byte[] m_LayoutName = Gump.StringToBuffer("{ radio "); - disp.Switches++; + public override void AppendTo(ArrayBufferWriter buffer, ArraySet strings, ref int entries, ref int switches) + { + SpanWriter writer = new SpanWriter(buffer.GetSpan(66)); + writer.Write(m_LayoutName); + writer.WriteAscii(X.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Y.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(InactiveID.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(ActiveID.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(InitialState ? "1" : "0"); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(SwitchID.ToString()); + writer.Write((byte)0x20); // ' ' + writer.Write((byte)0x7D); // '}' + + buffer.Advance(writer.WrittenCount); + + switches++; } } -} \ No newline at end of file +} diff --git a/Projects/Server/Gumps/GumpTextEntry.cs b/Projects/Server/Gumps/GumpTextEntry.cs index 8ebd49f83..8f1702b8f 100644 --- a/Projects/Server/Gumps/GumpTextEntry.cs +++ b/Projects/Server/Gumps/GumpTextEntry.cs @@ -18,86 +18,66 @@ * ***************************************************************************/ -using Server.Network; +using System.Buffers; +using Server.Buffers; +using Server.Collections; namespace Server.Gumps { public class GumpTextEntry : GumpEntry { - private static byte[] m_LayoutName = Gump.StringToBuffer("textentry"); - private int m_EntryID; - private int m_Hue; - private string m_InitialText; - private int m_Width, m_Height; - private int m_X, m_Y; - public GumpTextEntry(int x, int y, int width, int height, int hue, int entryID, string initialText) { - m_X = x; - m_Y = y; - m_Width = width; - m_Height = height; - m_Hue = hue; - m_EntryID = entryID; - m_InitialText = initialText; + X = x; + Y = y; + Width = width; + Height = height; + Hue = hue; + EntryID = entryID; + InitialText = initialText; } - public int X - { - get => m_X; - set => Delta(ref m_X, value); - } + public int X { get; set; } - public int Y - { - get => m_Y; - set => Delta(ref m_Y, value); - } + public int Y { get; set; } - public int Width - { - get => m_Width; - set => Delta(ref m_Width, value); - } + public int Width { get; set; } - public int Height - { - get => m_Height; - set => Delta(ref m_Height, value); - } + public int Height { get; set; } - public int Hue - { - get => m_Hue; - set => Delta(ref m_Hue, value); - } + public int Hue { get; set; } - public int EntryID - { - get => m_EntryID; - set => Delta(ref m_EntryID, value); - } + public int EntryID { get; set; } - public string InitialText - { - get => m_InitialText; - set => Delta(ref m_InitialText, value); - } + public string InitialText { get; set; } public override string Compile(NetState ns) => $"{{ textentry {m_X} {m_Y} {m_Width} {m_Height} {m_Hue} {m_EntryID} {Parent.Intern(m_InitialText)} }}"; - public override void AppendTo(NetState ns, IGumpWriter disp) - { - disp.AppendLayout(m_LayoutName); - disp.AppendLayout(m_X); - disp.AppendLayout(m_Y); - disp.AppendLayout(m_Width); - disp.AppendLayout(m_Height); - disp.AppendLayout(m_Hue); - disp.AppendLayout(m_EntryID); - disp.AppendLayout(Parent.Intern(m_InitialText)); + private static readonly byte[] m_LayoutName = Gump.StringToBuffer(" { textentry "); - disp.TextEntries++; + public override void AppendTo(ArrayBufferWriter buffer, ArraySet strings, ref int entries, ref int switches) + { + SpanWriter writer = new SpanWriter(buffer.GetSpan(90)); + writer.Write(m_LayoutName); + writer.WriteAscii(X.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Y.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Width.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Height.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Hue.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(EntryID.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(strings.Add(InitialText).ToString()); + writer.Write((byte)0x20); // ' ' + writer.Write((byte)0x7D); // '}' + + buffer.Advance(writer.WrittenCount); + + entries++; } } -} \ No newline at end of file +} diff --git a/Projects/Server/Gumps/GumpTextEntryLimited.cs b/Projects/Server/Gumps/GumpTextEntryLimited.cs index 2b4d983aa..d9258f39f 100644 --- a/Projects/Server/Gumps/GumpTextEntryLimited.cs +++ b/Projects/Server/Gumps/GumpTextEntryLimited.cs @@ -18,95 +18,69 @@ * ***************************************************************************/ -using Server.Network; +using System.Buffers; +using Server.Buffers; +using Server.Collections; namespace Server.Gumps { public class GumpTextEntryLimited : GumpEntry { - private static byte[] m_LayoutName = Gump.StringToBuffer("textentrylimited"); - private int m_EntryID; - private int m_Hue; - private string m_InitialText; - private int m_Size; - private int m_Width, m_Height; - private int m_X, m_Y; - public GumpTextEntryLimited(int x, int y, int width, int height, int hue, int entryID, string initialText, int size = 0) { - m_X = x; - m_Y = y; - m_Width = width; - m_Height = height; - m_Hue = hue; - m_EntryID = entryID; - m_InitialText = initialText; - m_Size = size; + X = x; + Y = y; + Width = width; + Height = height; + Hue = hue; + EntryID = entryID; + InitialText = initialText; + Size = size; } - public int X - { - get => m_X; - set => Delta(ref m_X, value); - } + public int X { get; set; } - public int Y - { - get => m_Y; - set => Delta(ref m_Y, value); - } + public int Y { get; set; } - public int Width - { - get => m_Width; - set => Delta(ref m_Width, value); - } + public int Width { get; set; } - public int Height - { - get => m_Height; - set => Delta(ref m_Height, value); - } + public int Height { get; set; } - public int Hue - { - get => m_Hue; - set => Delta(ref m_Hue, value); - } + public int Hue { get; set; } - public int EntryID - { - get => m_EntryID; - set => Delta(ref m_EntryID, value); - } + public int EntryID { get; set; } - public string InitialText - { - get => m_InitialText; - set => Delta(ref m_InitialText, value); - } + public string InitialText { get; set; } - public int Size - { - get => m_Size; - set => Delta(ref m_Size, value); - } + public int Size { get; set; } public override string Compile(NetState ns) => $"{{ textentrylimited {m_X} {m_Y} {m_Width} {m_Height} {m_Hue} {m_EntryID} {Parent.Intern(m_InitialText)} {m_Size} }}"; - public override void AppendTo(NetState ns, IGumpWriter disp) + public override void AppendTo(ArrayBufferWriter buffer, ArraySet strings, ref int entries, ref int switches) { - disp.AppendLayout(m_LayoutName); - disp.AppendLayout(m_X); - disp.AppendLayout(m_Y); - disp.AppendLayout(m_Width); - disp.AppendLayout(m_Height); - disp.AppendLayout(m_Hue); - disp.AppendLayout(m_EntryID); - disp.AppendLayout(Parent.Intern(m_InitialText)); - disp.AppendLayout(m_Size); + SpanWriter writer = new SpanWriter(buffer.GetSpan(107)); + writer.Write(m_LayoutName); + writer.WriteAscii(X.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Y.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Width.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Height.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Hue.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(EntryID.ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(strings.Add(InitialText).ToString()); + writer.Write((byte)0x20); // ' ' + writer.WriteAscii(Size.ToString()); + writer.Write((byte)0x20); // ' ' + writer.Write((byte)0x7D); // '}' - disp.TextEntries++; + buffer.Advance(writer.WrittenCount); + + entries++; } } } diff --git a/Projects/Server/Gumps/GumpTooltip.cs b/Projects/Server/Gumps/GumpTooltip.cs index 2982ebecc..063d0f879 100644 --- a/Projects/Server/Gumps/GumpTooltip.cs +++ b/Projects/Server/Gumps/GumpTooltip.cs @@ -18,29 +18,31 @@ * ***************************************************************************/ -using Server.Network; +using System.Buffers; +using Server.Buffers; +using Server.Collections; namespace Server.Gumps { public class GumpTooltip : GumpEntry { - private static byte[] m_LayoutName = Gump.StringToBuffer("tooltip"); - private int m_Number; + public GumpTooltip(int number) => Number = number; public GumpTooltip(int number) => m_Number = number; - public int Number - { - get => m_Number; - set => Delta(ref m_Number, value); - } + public override string Compile(ArraySet strings) => $"{{ tooltip {Number} }}"; public override string Compile(NetState ns) => $"{{ tooltip {m_Number} }}"; - public override void AppendTo(NetState ns, IGumpWriter disp) + public override void AppendTo(ArrayBufferWriter buffer, ArraySet strings, ref int entries, ref int switches) { - disp.AppendLayout(m_LayoutName); - disp.AppendLayout(m_Number); + SpanWriter writer = new SpanWriter(buffer.GetSpan(22)); + writer.Write(m_LayoutName); + writer.WriteAscii(Number.ToString()); + writer.Write((byte)0x20); // ' ' + writer.Write((byte)0x7D); // '}' + + buffer.Advance(writer.WrittenCount); } } -} \ No newline at end of file +} diff --git a/Projects/Server/HuePicker.cs b/Projects/Server/HuePicker.cs index a020fb6ff..e30f84df4 100644 --- a/Projects/Server/HuePicker.cs +++ b/Projects/Server/HuePicker.cs @@ -20,11 +20,11 @@ using Server.Network; -namespace Server.HuePickers +namespace Server { public class HuePicker { - private static int m_NextSerial = 1; + private static Serial m_NextSerial = 1; public HuePicker(int itemID) { @@ -36,7 +36,7 @@ namespace Server.HuePickers ItemID = itemID; } - public int Serial{ get; } + public Serial Serial{ get; } public int ItemID{ get; } @@ -46,8 +46,8 @@ namespace Server.HuePickers public void SendTo(NetState state) { - state.Send(new DisplayHuePicker(this)); + Packets.SendDisplayHuePicker(state, Serial, ItemID); state.AddHuePicker(this); } } -} \ No newline at end of file +} diff --git a/Projects/Server/IAccount.cs b/Projects/Server/IAccount.cs index cbe1cc46d..3cdd8c90a 100644 --- a/Projects/Server/IAccount.cs +++ b/Projects/Server/IAccount.cs @@ -20,7 +20,7 @@ using System; -namespace Server.Accounting +namespace Server { public static class AccountGold { diff --git a/Projects/Server/Insensitive.cs b/Projects/Server/Insensitive.cs index 8156b85a1..6146e48d7 100644 --- a/Projects/Server/Insensitive.cs +++ b/Projects/Server/Insensitive.cs @@ -29,16 +29,14 @@ namespace Server public static int Compare(string a, string b) => Comparer.Compare(a, b); - public static bool Equals(string a, string b) => - a == null && b == null || a != null && b != null && a.Length == b.Length && Comparer.Compare(a, b) == 0; + public static bool Equals(string a, string b) => a == null && b == null + || a != null && b != null && a.Length == b.Length && Comparer.Compare(a, b) == 0; - public static bool StartsWith(string a, string b) => - a != null && b != null && a.Length >= b.Length && Comparer.Compare(a.Substring(0, b.Length), b) == 0; + public static bool StartsWith(string a, string b) => a != null && b != null && a.Length >= b.Length && Comparer.Compare(a.Substring(0, b.Length), b) == 0; - public static bool EndsWith(string a, string b) => - a != null && b != null && a.Length >= b.Length && Comparer.Compare(a.Substring(a.Length - b.Length), b) == 0; + public static bool EndsWith(string a, string b) => a != null && b != null && a.Length >= b.Length && Comparer.Compare(a.Substring(a.Length - b.Length), b) == 0; + + public static bool Contains(string a, string b) => a != null && b != null && a.Length >= b.Length && a.IndexOf(b, StringComparison.OrdinalIgnoreCase) >= 0; - public static bool Contains(string a, string b) => - a != null && b != null && a.Length >= b.Length && a.IndexOf(b, StringComparison.OrdinalIgnoreCase) >= 0; } } diff --git a/Projects/Server/Interfaces.cs b/Projects/Server/Interfaces.cs index 0294efa88..d3d556014 100644 --- a/Projects/Server/Interfaces.cs +++ b/Projects/Server/Interfaces.cs @@ -21,7 +21,7 @@ using System; using System.Collections.Generic; -namespace Server.Mobiles +namespace Server { public interface IMount { @@ -33,10 +33,7 @@ namespace Server.Mobiles { IMount Mount{ get; } } -} -namespace Server -{ public interface IVendor { DateTime LastRestock{ get; set; } @@ -111,4 +108,4 @@ namespace Server void OnBeforeSpawn(Point3D location, Map map); void OnAfterSpawn(); } -} +} \ No newline at end of file diff --git a/Projects/Server/Item.cs b/Projects/Server/Item.cs index 66a4e9257..e6655cded 100644 --- a/Projects/Server/Item.cs +++ b/Projects/Server/Item.cs @@ -14,7 +14,7 @@ * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * (at your option) any later version.1 * ***************************************************************************/ @@ -199,7 +199,7 @@ namespace Server Spawner = 0x100 } - public class Item : IHued, IComparable, ISerializable, ISpawnable, IPropertyListObject + public class Item : IHued, IComparable, ISerializable, ISpawnable, ITile { public const int QuestItemHue = 0x4EA; // Hmmmm... "for EA"? public static readonly List EmptyItems = new List(); @@ -340,20 +340,22 @@ namespace Server set => SetFlag(ImplFlag.Stackable, value); } - public Packet RemovePacket => StaticPacketHandlers.GetRemoveEntityPacket(this); - public OPLInfo OPLPacket => StaticPacketHandlers.GetOPLInfoPacket(this); - public ObjectPropertyList PropertyList => StaticPacketHandlers.GetOPLPacket(this); + private ObjectPropertyList m_PropertyList; - // World packets need to be invalidated when any of the following changes: - // - ItemID - // - Amount - // - Location - // - Hue - // - Packet Flags - // - Direction - public Packet WorldPacket => StaticPacketHandlers.GetWorldItemPacket(this); - public Packet WorldPacketSA => StaticPacketHandlers.GetWorldItemSAPacket(this); - public Packet WorldPacketHS => StaticPacketHandlers.GetWorldItemHSPacket(this); + public ObjectPropertyList PropertyList + { + get + { + if (m_PropertyList == null) + { + m_PropertyList = new ObjectPropertyList(this); + GetProperties(m_PropertyList); + AppendChildProperties(m_PropertyList); + } + + return m_PropertyList; + } + } [CommandProperty(AccessLevel.GameMaster)] public bool Visible @@ -364,7 +366,6 @@ namespace Server if (GetFlag(ImplFlag.Visible) != value) { SetFlag(ImplFlag.Visible, value); - ReleaseWorldPackets(); if (m_Map != null) { @@ -377,7 +378,7 @@ namespace Server Mobile m = state.Mobile; if (!m.CanSee(this) && m.InRange(worldLoc, GetUpdateRange(m))) - state.Send(RemovePacket); + Packets.SendRemoveEntity(state, Serial); } eable.Free(); @@ -397,7 +398,6 @@ namespace Server if (GetFlag(ImplFlag.Movable) != value) { SetFlag(ImplFlag.Movable, value); - ReleaseWorldPackets(); Delta(ItemDelta.Update); } } @@ -433,16 +433,7 @@ namespace Server public virtual bool IsVirtualItem => false; - public virtual int LabelNumber - { - get - { - if (m_ItemID < 0x4000) - return 1020000 + m_ItemID; - - return 1078872 + m_ItemID; - } - } + public virtual int LabelNumber => m_ItemID < 0x4000 ? 1020000 + m_ItemID : 1078872 + m_ItemID; [CommandProperty(AccessLevel.GameMaster)] public int TotalGold => GetTotal(TotalType.Gold); @@ -513,8 +504,6 @@ namespace Server if (m_Hue != value) { m_Hue = value; - ReleaseWorldPackets(); - Delta(ItemDelta.Update); } } @@ -576,7 +565,6 @@ namespace Server int oldPileWeight = PileWeight; m_ItemID = value; - ReleaseWorldPackets(); int newPileWeight = PileWeight; @@ -642,8 +630,6 @@ namespace Server if ((LightType)m_Direction != value) { m_Direction = (Direction)value; - ReleaseWorldPackets(); - Delta(ItemDelta.Update); } } @@ -658,8 +644,6 @@ namespace Server if (m_Direction != value) { m_Direction = value; - ReleaseWorldPackets(); - Delta(ItemDelta.Update); } } @@ -678,7 +662,6 @@ namespace Server int oldPileWeight = PileWeight; m_Amount = value; - ReleaseWorldPackets(); int newPileWeight = PileWeight; @@ -706,6 +689,8 @@ namespace Server public ItemData ItemData => TileData.ItemTable[m_ItemID & TileData.MaxItemValue]; + int ITile.ID => ItemData.Value; + public virtual bool CanTarget => true; public virtual bool DisplayLootType => true; @@ -721,8 +706,6 @@ namespace Server InvalidateProperties(); - ReleaseWorldPackets(); - Delta(ItemDelta.Update); } } @@ -798,7 +781,7 @@ namespace Server Mobile m = state.Mobile; if (m.InRange(oldLocation, GetUpdateRange(m))) - state.Send(RemovePacket); + Packets.SendRemoveEntity(state, Serial); } eable.Free(); @@ -808,8 +791,6 @@ namespace Server m_Location = location; OnLocationChange(oldRealLocation); - ReleaseWorldPackets(); - List items = LookupItems(); if (items != null) @@ -853,7 +834,8 @@ namespace Server { Mobile m = state.Mobile; - if (!m.InRange(location, GetUpdateRange(m))) state.Send(RemovePacket); + if (!m.InRange(location, GetUpdateRange(m))) + Packets.SendRemoveEntity(state, Serial); } eable.Free(); @@ -864,8 +846,6 @@ namespace Server m_Location = location; OnLocationChange(oldRealLocation); - ReleaseWorldPackets(); - eable = m_Map.GetClientsInRange(m_Location, GetMaxUpdateRange()); foreach (NetState state in eable) @@ -955,17 +935,13 @@ namespace Server { NetState ns = rootParent.NetState; - if (ns != null) - if (rootParent.CanSee(this) && rootParent.InRange(worldLoc, GetUpdateRange(rootParent))) - { - if (ns.ContainerGridLines) - ns.Send(new ContainerContentUpdate6017(this)); - else - ns.Send(new ContainerContentUpdate(this)); + if (ns != null && rootParent.CanSee(this) && rootParent.InRange(worldLoc, GetUpdateRange(rootParent))) + { + Packets.SendContainerContentUpdate(ns, this); - if (ObjectPropertyList.Enabled) - ns.Send(OPLPacket); - } + if (ObjectPropertyList.Enabled) + PropertyList.Send(ns); + } } SecureTrade st = GetSecureTradeCont()?.Trade; @@ -986,19 +962,16 @@ namespace Server if (ns != null && tradeRecip.CanSee(this) && tradeRecip.InRange(worldLoc, GetUpdateRange(tradeRecip))) { - if (ns.ContainerGridLines) - ns.Send(new ContainerContentUpdate6017(this)); - else - ns.Send(new ContainerContentUpdate(this)); + Packets.SendContainerContentUpdate(ns, this); if (ObjectPropertyList.Enabled) - ns.Send(OPLPacket); + PropertyList.Send(ns); } } List openers = contParent.Openers; - if (openers != null) + if (openers?.Count > 0) lock (openers) { for (int i = 0; i < openers.Count; ++i) @@ -1008,9 +981,7 @@ namespace Server int range = GetUpdateRange(mob); if (mob.Map != map || !mob.InRange(worldLoc, range)) - { openers.RemoveAt(i--); - } else { if (mob == rootParent || mob == tradeRecip) @@ -1020,13 +991,10 @@ namespace Server if (ns != null && mob.CanSee(this)) { - if (ns.ContainerGridLines) - ns.Send(new ContainerContentUpdate6017(this)); - else - ns.Send(new ContainerContentUpdate(this)); + Packets.SendContainerContentUpdate(ns, this); if (ObjectPropertyList.Enabled) - ns.Send(OPLPacket); + PropertyList.Send(ns); } } } @@ -1038,8 +1006,6 @@ namespace Server return; } - Packet p = null; - IPooledEnumerable eable = map.GetClientsInRange(worldLoc, GetMaxUpdateRange()); foreach (NetState state in eable) @@ -1054,39 +1020,26 @@ namespace Server SendInfoTo(state, ObjectPropertyList.Enabled); else { - if (p != null) - state.Send(p); - else if (m_Parent is Item) - { - if (state.ContainerGridLines) - state.Send(new ContainerContentUpdate6017(this)); - else - state.Send(new ContainerContentUpdate(this)); - } + if (m_Parent is Item) + Packets.SendContainerContentUpdate(state, this); else if (m_Parent is Mobile) - { - p = new EquipUpdate(this); - p.Acquire(); - - state.Send(p); - } + Packets.SendEquipUpdate(state, this); if (ObjectPropertyList.Enabled) - state.Send(OPLPacket); + PropertyList.Send(state); } } else if ((flags & ItemDelta.EquipOnly) != 0 && m_Parent is Mobile) { - state.Send(p ?? (p = Packet.Acquire(new EquipUpdate(this)))); + Packets.SendEquipUpdate(state, this); if (ObjectPropertyList.Enabled) - state.Send(OPLPacket); + PropertyList.Send(state); } else if (ObjectPropertyList.Enabled && (flags & ItemDelta.Properties) != 0) - state.Send(OPLPacket); + PropertyList.Send(state); } } - Packet.Release(p); eable.Free(); } @@ -1126,7 +1079,7 @@ namespace Server OnAfterDelete(); - FreeCache(); + ClearProperties(); } [CommandProperty(AccessLevel.Counselor)] @@ -1237,17 +1190,7 @@ namespace Server long ticks = LastMoved.Ticks; long now = DateTime.UtcNow.Ticks; - TimeSpan d; - - try - { - d = new TimeSpan(ticks - now); - } - catch - { - if (ticks < now) d = TimeSpan.MaxValue; - else d = TimeSpan.MaxValue; - } + TimeSpan d = new TimeSpan(ticks - now); double minutes = -d.TotalMinutes; @@ -1306,13 +1249,7 @@ namespace Server if (GetSaveFlag(flags, SaveFlag.Name)) writer.Write(info.m_Name); - if (GetSaveFlag(flags, SaveFlag.Parent)) - { - if (m_Parent?.Deleted == false) - writer.Write(m_Parent.Serial); - else - writer.Write(Serial.MinusOne); - } + if (GetSaveFlag(flags, SaveFlag.Parent)) writer.Write(m_Parent?.Deleted == false ? m_Parent.Serial : Serial.MinusOne); if (GetSaveFlag(flags, SaveFlag.Items)) writer.Write(items, false); @@ -1443,10 +1380,10 @@ namespace Server public List AcquireItems() { if (this is Container cont) - return cont.m_Items ?? (cont.m_Items = new List()); + return cont.m_Items ??= new List(); CompactInfo info = AcquireCompactInfo(); - return info.m_Items ?? (info.m_Items = new List()); + return info.m_Items ??= new List(); } private void SetFlag(ImplFlag flag, bool value) @@ -1538,7 +1475,7 @@ namespace Server /// public virtual void SendPropertiesTo(Mobile from) { - from.Send(PropertyList); + PropertyList.Send(from?.NetState); } /// @@ -1687,23 +1624,23 @@ namespace Server list.Add(1062203, "{0}", m.Name); // Blessed for ~1_NAME~ } - /// - /// Overridable. Fills an with everything applicable. By default, this invokes - /// , then Item.GetChildProperties or - /// Mobile.GetChildProperties. This method should be overridden to add any custom - /// properties. - /// - public virtual void GetProperties(ObjectPropertyList list) + /// + /// Overridable. Fills an with everything applicable. By default, this invokes + /// , then Item.GetChildProperties or + /// Mobile.GetChildProperties. This method should be overridden to add any custom + /// properties. + /// + public virtual void GetProperties(ObjectPropertyList list) { AddNameProperties(list); } - /// - /// Overridable. Event invoked when a child () is building it's . - /// Recursively calls Item.GetChildProperties or - /// Mobile.GetChildProperties. - /// - public virtual void GetChildProperties(ObjectPropertyList list, Item item) + /// + /// Overridable. Event invoked when a child () is building it's . + /// Recursively calls Item.GetChildProperties or + /// Mobile.GetChildProperties. + /// + public virtual void GetChildProperties(ObjectPropertyList list, Item item) { if (m_Parent is Item parentItem) parentItem.GetChildProperties(list, item); @@ -1711,12 +1648,12 @@ namespace Server parentMobile.GetChildProperties(list, item); } - /// - /// Overridable. Event invoked when a child () is building it's Name - /// . Recursively calls Item.GetChildNameProperties or - /// Mobile.GetChildNameProperties. - /// - public virtual void GetChildNameProperties(ObjectPropertyList list, Item item) + /// + /// Overridable. Event invoked when a child () is building it's Name + /// . Recursively calls Item.GetChildNameProperties or + /// Mobile.GetChildNameProperties. + /// + public virtual void GetChildNameProperties(ObjectPropertyList list, Item item) { if (m_Parent is Item parentItem) parentItem.GetChildNameProperties(list, item); @@ -1742,9 +1679,7 @@ namespace Server IEntity parent = bounce.m_Parent; if (parent?.Deleted != false) - { MoveToWorld(bounce.m_WorldLoc, bounce.m_Map); - } else if (parent is Item p) { IEntity root = p.RootParent; @@ -1756,9 +1691,7 @@ namespace Server p.AddItem(this); } else - { MoveToWorld(from.Location, from.Map); - } } else if (parent is Mobile parentMobile) { @@ -1766,9 +1699,7 @@ namespace Server MoveToWorld(bounce.m_WorldLoc, bounce.m_Map); } else - { MoveToWorld(bounce.m_WorldLoc, bounce.m_Map); - } ClearBounce(); } @@ -1859,19 +1790,14 @@ namespace Server MoveToWorld(location, m_Map); } - public void LabelTo(Mobile to, int number) + public void LabelTo(Mobile to, int number, string args = "") { - to.Send(new MessageLocalized(Serial, m_ItemID, MessageType.Label, 0x3B2, 3, number, "", "")); - } - - public void LabelTo(Mobile to, int number, string args) - { - to.Send(new MessageLocalized(Serial, m_ItemID, MessageType.Label, 0x3B2, 3, number, "", args)); + Packets.SendMessageLocalized(to?.NetState, Serial, m_ItemID, MessageType.Label, 0x3B2, 3, number, "", args); } public void LabelTo(Mobile to, string text) { - to.Send(new UnicodeMessage(Serial, m_ItemID, MessageType.Label, 0x3B2, 3, "ENU", "", text)); + Packets.SendUnicodeMessage(to?.NetState, Serial, m_ItemID, MessageType.Label, 0x3B2, 3, "ENU", "", text); } public void LabelTo(Mobile to, string format, params object[] args) @@ -1879,14 +1805,9 @@ namespace Server LabelTo(to, string.Format(format, args)); } - public void LabelToAffix(Mobile to, int number, AffixType type, string affix) + public void LabelToAffix(Mobile to, int number, AffixType type, string affix, string args = "") { - to.Send(new MessageLocalizedAffix(Serial, m_ItemID, MessageType.Label, 0x3B2, 3, number, "", type, affix, "")); - } - - public void LabelToAffix(Mobile to, int number, AffixType type, string affix, string args) - { - to.Send(new MessageLocalizedAffix(Serial, m_ItemID, MessageType.Label, 0x3B2, 3, number, "", type, affix, args)); + Packets.SendMessageLocalizedAffix(to?.NetState, Serial, m_ItemID, MessageType.Label, 0x3B2, 3, number, "", type, affix, args); } public virtual void LabelLootTypeTo(Mobile to) @@ -2000,8 +1921,7 @@ namespace Server public void ClearProperties() { - StaticPacketHandlers.FreeOPLPacket(this); - StaticPacketHandlers.FreeOPLInfoPacket(this); + m_PropertyList = null; } public void InvalidateProperties() @@ -2011,23 +1931,14 @@ namespace Server if (m_Map != null && m_Map != Map.Internal && !World.Loading) { - ObjectPropertyList oldList = StaticPacketHandlers.FreeOPLPacket(this); + ObjectPropertyList oldList = m_PropertyList; + m_PropertyList = null; if (oldList?.Hash != PropertyList.Hash) - { - StaticPacketHandlers.FreeOPLInfoPacket(this); Delta(ItemDelta.Properties); - } } else - { ClearProperties(); - } - } - - public void ReleaseWorldPackets() - { - StaticPacketHandlers.FreeWorldItemPackets(this); } public virtual int GetPacketFlags() @@ -2076,18 +1987,17 @@ namespace Server private static bool GetSaveFlag(SaveFlag flags, SaveFlag toGet) => (flags & toGet) != 0; - public IPooledEnumerable GetObjectsInRange(int range) - { - Map map = m_Map; + public IPooledEnumerable GetObjectsInRange(int range) => + m_Map?.GetObjectsInRange(m_Parent == null ? m_Location : GetWorldLocation(), range) ?? Map.NullEnumerable.Instance; - if (map == null) - return Map.NullEnumerable.Instance; + public IPooledEnumerable GetItemsInRange(int range) => + m_Map?.GetItemsInRange(m_Parent == null ? m_Location : GetWorldLocation(), range) ?? Map.NullEnumerable.Instance; - if (m_Parent == null) - return map.GetObjectsInRange(m_Location, range); + public IPooledEnumerable GetMobilesInRange(int range) => + m_Map?.GetMobilesInRange(m_Parent == null ? m_Location : GetWorldLocation(), range) ?? Map.NullEnumerable.Instance; - return map.GetObjectsInRange(GetWorldLocation(), range); - } + public IPooledEnumerable GetClientsInRange(int range) => + m_Map?.GetClientsInRange(m_Parent == null ? m_Location : GetWorldLocation(), range) ?? Map.NullEnumerable.Instance; public IPooledEnumerable GetItemsInRange(int range) { @@ -2538,9 +2448,7 @@ namespace Server if (heldBy != null) { if (GetBounce() != null) - { Bounce(heldBy); - } else { heldBy.Holding = null; @@ -2561,18 +2469,22 @@ namespace Server public virtual void SendInfoTo(NetState state, bool sendOplPacket) { - state.Send(GetWorldPacketFor(state)); + SendWorldPacketFor(state); - if (sendOplPacket) state.Send(OPLPacket); + if (sendOplPacket) + PropertyList.Send(state); } - protected virtual Packet GetWorldPacketFor(NetState state) + // World packets need to be invalidated when any of the following changes: + // - ItemID + // - Amount + // - Location + // - Hue + // - Packet Flags + // - Direction + protected virtual void SendWorldPacketFor(NetState state) { - if (state.HighSeas) - return WorldPacketHS; - if (state.StygianAbyss) - return WorldPacketSA; - return WorldPacket; + Packets.SendWorldItem(state, this); } public virtual int GetTotal(TotalType type) => 0; @@ -2752,10 +2664,7 @@ namespace Server public virtual void FreeCache() { - ReleaseWorldPackets(); - StaticPacketHandlers.FreeRemoveItemPacket(this); - StaticPacketHandlers.FreeOPLInfoPacket(this); - StaticPacketHandlers.FreeOPLPacket(this); + m_PropertyList = null; } public void PublicOverheadMessage(MessageType type, int hue, bool ascii, string text) @@ -2763,7 +2672,6 @@ namespace Server if (m_Map == null) return; - Packet p = null; Point3D worldLoc = GetWorldLocation(); IPooledEnumerable eable = m_Map.GetClientsInRange(worldLoc, GetMaxUpdateRange()); @@ -2774,36 +2682,21 @@ namespace Server if (m.CanSee(this) && m.InRange(worldLoc, GetUpdateRange(m))) { - if (p == null) - { - if (ascii) - p = new AsciiMessage(Serial, m_ItemID, type, hue, 3, Name, text); - else - p = new UnicodeMessage(Serial, m_ItemID, type, hue, 3, "ENU", Name, text); - - p.Acquire(); - } - - state.Send(p); + if (ascii) + Packets.SendAsciiMessage(state, Serial, m_ItemID, type, hue, 3, Name, text); + else + Packets.SendUnicodeMessage(state, Serial, m_ItemID, type, hue, 3, "ENU", Name, text); } } - Packet.Release(p); - eable.Free(); } - public void PublicOverheadMessage(MessageType type, int hue, int number) - { - PublicOverheadMessage(type, hue, number, ""); - } - - public void PublicOverheadMessage(MessageType type, int hue, int number, string args) + public void PublicOverheadMessage(MessageType type, int hue, int number, string args = "") { if (m_Map == null) return; - Packet p = null; Point3D worldLoc = GetWorldLocation(); IPooledEnumerable eable = m_Map.GetClientsInRange(worldLoc, GetMaxUpdateRange()); @@ -2813,16 +2706,9 @@ namespace Server Mobile m = state.Mobile; if (m.CanSee(this) && m.InRange(worldLoc, GetUpdateRange(m))) - { - if (p == null) - p = Packet.Acquire(new MessageLocalized(Serial, m_ItemID, type, hue, 3, number, Name, args)); - - state.Send(p); - } + Packets.SendMessageLocalized(state, Serial, m_ItemID, type, hue, 3, number, Name, args); } - Packet.Release(p); - eable.Free(); } @@ -3187,7 +3073,8 @@ namespace Server { Mobile m = state.Mobile; - if (m.InRange(worldLoc, GetUpdateRange(m))) state.Send(RemovePacket); + if (m.InRange(worldLoc, GetUpdateRange(m))) + Packets.SendRemoveEntity(state, Serial); } eable.Free(); @@ -3227,21 +3114,21 @@ namespace Server to.Send(new MessageLocalized(Serial, ItemID, MessageType.Regular, 0x3B2, 3, number, "", "")); } - public void SendLocalizedMessageTo(Mobile to, int number, string args) + public void SendLocalizedMessageTo(Mobile to, int number, string args = "") { if (Deleted || !to.CanSee(this)) return; - to.Send(new MessageLocalized(Serial, ItemID, MessageType.Regular, 0x3B2, 3, number, "", args)); + Packets.SendMessageLocalized(to.NetState, Serial, ItemID, MessageType.Regular, 0x3B2, 3, number, "", args); } - public void SendLocalizedMessageTo(Mobile to, int number, AffixType affixType, string affix, string args) + public void SendLocalizedMessageTo(Mobile to, int number, AffixType affixType, string affix = "", string args = "") { if (Deleted || !to.CanSee(this)) return; - to.Send(new MessageLocalizedAffix(Serial, ItemID, MessageType.Regular, 0x3B2, 3, number, "", affixType, affix, - args)); + Packets.SendMessageLocalizedAffix(to.NetState, Serial, ItemID, MessageType.Regular, 0x3B2, 3, number, "", affixType, affix, + args); } public virtual void OnSnoop(Mobile from) @@ -3393,7 +3280,7 @@ namespace Server public bool CheckLift(Mobile from) { - LRReason reject = LRReason.Inspecific; + LRReason reject = LRReason.Unspecific; return CheckLift(from, this, ref reject); } @@ -3420,8 +3307,8 @@ namespace Server ObjectPropertyList opl = PropertyList; if (opl.Header > 0) - from.Send(new MessageLocalized(Serial, m_ItemID, MessageType.Label, 0x3B2, 3, opl.Header, Name, - opl.HeaderArgs)); + Packets.SendMessageLocalized(from.NetState, Serial, m_ItemID, MessageType.Label, 0x3B2, 3, opl.Header, Name, + opl.HeaderArgs); } public virtual void OnSingleClick(Mobile from) @@ -3440,11 +3327,10 @@ namespace Server if (Name == null) { if (m_Amount <= 1) - ns.Send(new MessageLocalized(Serial, m_ItemID, MessageType.Label, 0x3B2, 3, LabelNumber, "", "")); + Packets.SendMessageLocalized(ns, Serial, m_ItemID, MessageType.Label, 0x3B2, 3, LabelNumber); else - ns.Send(new MessageLocalizedAffix(Serial, m_ItemID, MessageType.Label, 0x3B2, 3, LabelNumber, "", - AffixType.Append, - $" : {m_Amount}", "")); + Packets.SendMessageLocalizedAffix(ns, Serial, m_ItemID, MessageType.Label, 0x3B2, 3, LabelNumber, "", + AffixType.Append, $" : {m_Amount}"); } else { @@ -3534,8 +3420,8 @@ namespace Server if (BlessedFor != null) return false; - return m_LootType == LootType.Regular; - } + public virtual bool IsStandardLoot() => + !(Mobile.InsuranceEnabled && Insured) && BlessedFor == null && m_LootType == LootType.Regular; public override string ToString() => $"0x{Serial.Value:X} \"{GetType().Name}\""; @@ -3623,11 +3509,9 @@ namespace Server private Map m_Map; private LootType m_LootType; private Direction m_Direction; - #endregion #region Location Location Location! - public virtual void OnLocationChange(Point3D oldLocation) { } @@ -3656,7 +3540,8 @@ namespace Server { Mobile m = state.Mobile; - if (!m.InRange(value, GetUpdateRange(m))) state.Send(RemovePacket); + if (!m.InRange(value, GetUpdateRange(m))) + Packets.SendRemoveEntity(state, Serial); } eable.Free(); @@ -3664,7 +3549,6 @@ namespace Server Point3D oldLoc = m_Location; m_Location = value; - ReleaseWorldPackets(); SetLastMoved(); @@ -3687,24 +3571,17 @@ namespace Server else if (m_Parent is Item) { m_Location = value; - ReleaseWorldPackets(); Delta(ItemDelta.Update); } else - { m_Location = value; - ReleaseWorldPackets(); - } if (m_Parent == null) m_Map.OnMove(oldLocation, this); } else - { m_Location = value; - ReleaseWorldPackets(); - } OnLocationChange(oldLocation); } @@ -3730,11 +3607,9 @@ namespace Server get => m_Location.m_Z; set => Location = new Point3D(m_Location.m_X, m_Location.m_Y, value); } - #endregion #region OnDoubleClick[...] - public virtual void OnDoubleClick(Mobile from) { } @@ -3761,7 +3636,6 @@ namespace Server { from.SendLocalizedMessage(500447); // That is not accessible. } - #endregion } } diff --git a/Projects/Server/Items/Container.cs b/Projects/Server/Items/Container.cs index 150597e64..92c86305f 100644 --- a/Projects/Server/Items/Container.cs +++ b/Projects/Server/Items/Container.cs @@ -485,9 +485,6 @@ namespace Server.Items int extraItems = 0; int extraWeight = 0; -// from.SendMessage( String.Format( "There are {0} items in this container.", this.Items.Count ) ); -// from.SendMessage( String.Format( "There are {0} items being dropped into this container.", droppedItems.Length ) ); - for (int i = 0; i < droppedItems.Length; i++) { Item dropped = droppedItems[i]; @@ -596,9 +593,7 @@ namespace Server.Items } } else - { from.SendLocalizedMessage(500446); // That is too far away. - } } public virtual bool CheckContentDisplay(Mobile from) => @@ -630,10 +625,7 @@ namespace Server.Items if (ns != null) { - if (ns.HighSeas) - to.Send(new ContainerDisplayHS(this)); - else - to.Send(new ContainerDisplay(this)); + Packets.SendDisplayContainer(ns, Serial, (short)GumpID); SendContentTo(ns); @@ -642,7 +634,7 @@ namespace Server.Items List items = Items; for (int i = 0; i < items.Count; ++i) - to.Send(items[i].OPLPacket); + items[i].PropertyList.SendOPLInfo(ns); } } } @@ -664,9 +656,7 @@ namespace Server.Items Mobile mob = Openers[i]; if (mob == opener) - { contains = true; - } else { int range = GetUpdateRange(mob); @@ -679,24 +669,14 @@ namespace Server.Items if (!contains) { - if (Openers == null) - Openers = new List(); - + Openers ??= new List(); Openers.Add(opener); } else if (Openers?.Count == 0) - { Openers = null; - } } - public virtual void SendContentTo(NetState state) - { - if (state?.ContainerGridLines == true) - state.Send(new ContainerContent6017(state.Mobile, this)); - else - state.Send(new ContainerContent(state.Mobile, this)); - } + public virtual void SendContentTo(NetState state) => Packets.SendContainerContent(state, state.Mobile, this); public override void GetProperties(ObjectPropertyList list) { @@ -808,8 +788,7 @@ namespace Server.Items for (int j = 0; j < items[i].Length; ++j) totals[i] += items[i][j].Amount; - if (totals[i] >= amount) - hasEnough = true; + hasEnough |= totals[i] >= amount; } if (!hasEnough) @@ -901,8 +880,7 @@ namespace Server.Items for (int k = 0; k < items[i][j].Length; ++k) totals[i][j] += items[i][j][k].Amount; - if (totals[i][j] >= amounts[i]) - hasEnough = true; + hasEnough |= totals[i][j] >= amounts[i]; } if (!hasEnough) @@ -996,8 +974,7 @@ namespace Server.Items for (int k = 0; k < items[i][j].Length; ++k) totals[i][j] += items[i][j][k].Amount; - if (totals[i][j] >= amounts[i]) - hasEnough = true; + hasEnough |= totals[i][j] >= amounts[i]; } if (!hasEnough) @@ -1598,12 +1575,10 @@ namespace Server.Items public class ContainerData { - private static Dictionary m_Table; + private static readonly Dictionary Table = new Dictionary(); static ContainerData() { - m_Table = new Dictionary(); - string path = Path.Combine(Core.BaseDirectory, "Data/containers.cfg"); if (!File.Exists(path)) @@ -1629,7 +1604,7 @@ namespace Server.Items if (split.Length >= 3) { - int gumpID = Utility.ToInt32(split[0]); + int gumpId = Utility.ToInt32(split[0]); string[] aRect = split[1].Split(' '); if (aRect.Length < 4) @@ -1644,10 +1619,9 @@ namespace Server.Items int dropSound = Utility.ToInt32(split[2]); - ContainerData data = new ContainerData(gumpID, bounds, dropSound); + ContainerData data = new ContainerData(gumpId, bounds, dropSound); - if (Default == null) - Default = data; + Default ??= data; if (split.Length >= 4) { @@ -1657,10 +1631,10 @@ namespace Server.Items { int id = Utility.ToInt32(aIDs[i]); - if (m_Table.ContainsKey(id)) + if (Table.ContainsKey(id)) Console.WriteLine(@"Warning: double ItemID entry in Data\containers.cfg"); else - m_Table[id] = data; + Table[id] = data; } } } @@ -1672,13 +1646,12 @@ namespace Server.Items } } - if (Default == null) - Default = new ContainerData(0x3C, new Rectangle2D(44, 65, 142, 94), 0x48); + Default ??= new ContainerData(0x3C, new Rectangle2D(44, 65, 142, 94), 0x48); } - public ContainerData(int gumpID, Rectangle2D bounds, int dropSound) + public ContainerData(int gumpId, Rectangle2D bounds, int dropSound) { - GumpID = gumpID; + GumpID = gumpId; Bounds = bounds; DropSound = dropSound; } @@ -1691,9 +1664,9 @@ namespace Server.Items public int DropSound{ get; } - public static ContainerData GetData(int itemID) + public static ContainerData GetData(int itemId) { - m_Table.TryGetValue(itemID, out ContainerData data); + Table.TryGetValue(itemId, out ContainerData data); return data ?? Default; } } diff --git a/Projects/Server/Items/Containers.cs b/Projects/Server/Items/Containers.cs index 181481652..eaa794144 100644 --- a/Projects/Server/Items/Containers.cs +++ b/Projects/Server/Items/Containers.cs @@ -18,7 +18,6 @@ * ***************************************************************************/ -using Server.Accounting; using Server.Network; namespace Server.Items @@ -54,7 +53,9 @@ namespace Server.Items { Owner.PrivateOverheadMessage(MessageType.Regular, 0x3B2, true, $"Bank container has {TotalItems} items, {TotalWeight} stones", Owner.NetState); - Owner.Send(new EquipUpdate(this)); + + if (Owner.NetState != null) + Packets.SendEquipUpdate(Owner.NetState, this); DisplayTo(Owner); } } @@ -97,8 +98,8 @@ namespace Server.Items { Opened = false; - if (SendDeleteOnClose) - Owner?.Send(RemovePacket); + if (SendDeleteOnClose && Owner != null) + Packets.SendRemoveEntity(Owner.NetState, Serial); } public override void OnSingleClick(Mobile from) diff --git a/Projects/Server/Items/SecureTradeContainer.cs b/Projects/Server/Items/SecureTradeContainer.cs index e759a29a0..063400fd2 100644 --- a/Projects/Server/Items/SecureTradeContainer.cs +++ b/Projects/Server/Items/SecureTradeContainer.cs @@ -18,7 +18,6 @@ * ***************************************************************************/ -using Server.Accounting; using Server.Network; namespace Server.Items diff --git a/Projects/Server/Items/VirtualCheck.cs b/Projects/Server/Items/VirtualCheck.cs index 514e60739..88e64fa94 100644 --- a/Projects/Server/Items/VirtualCheck.cs +++ b/Projects/Server/Items/VirtualCheck.cs @@ -1,8 +1,7 @@ using Server.Gumps; -using Server.Items; using Server.Network; -namespace Server +namespace Server.Items { public sealed class VirtualCheck : Item { @@ -35,7 +34,7 @@ namespace Server public override string DefaultName => "Offer Of Currency"; - public EditGump Editor{ get; private set; } + public EditGump Editor { get; private set; } [CommandProperty(AccessLevel.Administrator)] public int Plat @@ -171,8 +170,8 @@ namespace Server CompileLayout(); } - public Mobile User{ get; } - public VirtualCheck Check{ get; private set; } + public Mobile User { get; } + public VirtualCheck Check { get; private set; } public override void OnServerClose(NetState owner) { diff --git a/Projects/Server/Items/VirtualHair.cs b/Projects/Server/Items/VirtualHair.cs index db38e9743..697c7ce1b 100644 --- a/Projects/Server/Items/VirtualHair.cs +++ b/Projects/Server/Items/VirtualHair.cs @@ -18,9 +18,7 @@ * ***************************************************************************/ -using Server.Network; - -namespace Server +namespace Server.Items { public abstract class BaseHairInfo { @@ -61,12 +59,7 @@ namespace Server public class HairInfo : BaseHairInfo { - public HairInfo(int itemid) - : base(itemid) - { - } - - public HairInfo(int itemid, int hue) + public HairInfo(int itemid, int hue = 0) : base(itemid, hue) { } @@ -82,12 +75,7 @@ namespace Server public class FacialHairInfo : BaseHairInfo { - public FacialHairInfo(int itemid) - : base(itemid) - { - } - - public FacialHairInfo(int itemid, int hue) + public FacialHairInfo(int itemid, int hue = 0) : base(itemid, hue) { } @@ -156,4 +144,4 @@ namespace Server m_Stream.Write(FacialHairInfo.FakeSerial(parent)); } } -} \ No newline at end of file +} diff --git a/Projects/Server/Layer.cs b/Projects/Server/Layer.cs index 936917bf6..99f7c2ec0 100644 --- a/Projects/Server/Layer.cs +++ b/Projects/Server/Layer.cs @@ -1,3 +1,23 @@ +/*************************************************************************** + * Layer.cs + * ------------------- + * begin : May 1, 2002 + * copyright : (C) The RunUO Software Team + * email : info@runuo.com + * + * $Id$ + * + ***************************************************************************/ + +/*************************************************************************** + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + ***************************************************************************/ + namespace Server { /// diff --git a/Projects/Server/LightType.cs b/Projects/Server/LightType.cs index cdab2e58b..61637af3d 100644 --- a/Projects/Server/LightType.cs +++ b/Projects/Server/LightType.cs @@ -1,3 +1,23 @@ +/*************************************************************************** + * LightType.cs + * ------------------- + * begin : May 1, 2002 + * copyright : (C) The RunUO Software Team + * email : info@runuo.com + * + * $Id$ + * + ***************************************************************************/ + +/*************************************************************************** + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + ***************************************************************************/ + namespace Server { public enum LightType diff --git a/Projects/Server/Main.cs b/Projects/Server/Main.cs index 53a975885..7f9273ea5 100644 --- a/Projects/Server/Main.cs +++ b/Projects/Server/Main.cs @@ -39,10 +39,6 @@ namespace Server { private static bool m_Crashed; private static Thread timerThread; - private static string m_BaseDirectory; - private static string m_ExePath; - - private static bool m_Cache = true; private static bool m_Profiling; private static DateTime m_ProfileStart; @@ -56,18 +52,16 @@ namespace Server * GetTickCount and GetTickCount64 have poor resolution. * GetTickCount64 is unavailable on Windows XP and Windows Server 2003. * Stopwatch.GetTimestamp() (QueryPerformanceCounter) is high resolution, but - * somewhat expensive to call because of its defference to DateTime.Now, + * somewhat expensive to call because of its difference to DateTime.Now, * which is why Stopwatch has been used to verify HRT before calling GetTimestamp(), * enabling the usage of DateTime.UtcNow instead. */ - private static readonly bool _HighRes = Stopwatch.IsHighResolution; + private static readonly bool UsingHighResolutionTiming = Stopwatch.IsHighResolution; private static readonly double _HighFrequency = 1000.0 / Stopwatch.Frequency; private static readonly double _LowFrequency = 1000.0 / TimeSpan.TicksPerSecond; - private static bool _UseHRT; - public static readonly bool Is64Bit = Environment.Is64BitProcess; internal static ConsoleEventHandler m_ConsoleEventHandler; @@ -99,16 +93,8 @@ namespace Server } } - public static TimeSpan ProfileTime - { - get - { - if (m_ProfileStart > DateTime.MinValue) - return m_ProfileTime + (DateTime.UtcNow - m_ProfileStart); - - return m_ProfileTime; - } - } + public static TimeSpan ProfileTime => + m_ProfileStart > DateTime.MinValue ? m_ProfileTime + (DateTime.UtcNow - m_ProfileStart) : m_ProfileTime; public static bool Service{ get; private set; } @@ -116,28 +102,22 @@ namespace Server internal static bool HaltOnWarning{ get; private set; } - public static Assembly Assembly{ get; set; } + public static List DataDirectories{ get; } = new List(); - public static Version Version => Assembly.GetName().Version; - public static Process Process{ get; private set; } + public static Assembly Assembly { get; } = Assembly.GetEntryAssembly(); + + public static readonly Version Version = Assembly.GetName().Version; + + public static Process Process { get; } = Process.GetCurrentProcess(); public static Thread Thread{ get; private set; } public static MultiTextWriter MultiConsoleOut{ get; private set; } - public static bool UsingHighResolutionTiming => _UseHRT && _HighRes && !Unix; - public static long TickCount => (long)Ticks; - public static double Ticks - { - get - { - if (_UseHRT && _HighRes && !Unix) return Stopwatch.GetTimestamp() * _HighFrequency; - - return DateTime.UtcNow.Ticks * _LowFrequency; - } - } + public static double Ticks => + UsingHighResolutionTiming ? Stopwatch.GetTimestamp() * _HighFrequency : DateTime.UtcNow.Ticks * _LowFrequency; public static bool MultiProcessor{ get; private set; } @@ -145,28 +125,9 @@ namespace Server public static bool Unix{ get; private set; } - public static string ExePath => m_ExePath ?? (m_ExePath = Assembly.Location); + public static string ExePath => Process.MainModule?.FileName; - public static string BaseDirectory - { - get - { - if (m_BaseDirectory == null) - try - { - m_BaseDirectory = ExePath; - - if (m_BaseDirectory.Length > 0) - m_BaseDirectory = Path.GetDirectoryName(m_BaseDirectory); - } - catch - { - m_BaseDirectory = ""; - } - - return m_BaseDirectory; - } - } + public static readonly string BaseDirectory = Path.GetDirectoryName(ExePath ?? "") ?? ""; public static bool Closing{ get; private set; } @@ -189,15 +150,9 @@ namespace Server if (m_Profiling) Utility.Separate(sb, "-profile", " "); - if (!m_Cache) - Utility.Separate(sb, "-nocache", " "); - if (HaltOnWarning) Utility.Separate(sb, "-haltonwarning", " "); - if (_UseHRT) - Utility.Separate(sb, "-usehrt", " "); - return sb.ToString(); } } @@ -279,10 +234,8 @@ namespace Server private static bool OnConsoleEvent(ConsoleEventType type) { - if (World.Saving || Service && type == ConsoleEventType.CTRL_LOGOFF_EVENT) - return true; - - Kill(); //Kill -> HandleClosed will handle waiting for the completion of flushing to disk + if (!(World.Saving || Service && type == ConsoleEventType.CTRL_LOGOFF_EVENT)) + Kill(); //Kill -> HandleClosed will handle waiting for the completion of flushing to disk return true; } @@ -321,10 +274,7 @@ namespace Server Console.WriteLine("done"); } - public static void Set() - { - m_Signal.Set(); - } + public static void Set() => m_Signal.Set(); public static void Main(string[] args) { @@ -332,18 +282,12 @@ namespace Server AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit; foreach (string a in args) - if (Insensitive.Equals(a, "-debug")) - Debug = true; - else if (Insensitive.Equals(a, "-service")) - Service = true; - else if (Insensitive.Equals(a, "-profile")) - Profiling = true; - else if (Insensitive.Equals(a, "-nocache")) - m_Cache = false; - else if (Insensitive.Equals(a, "-haltonwarning")) - HaltOnWarning = true; - else if (Insensitive.Equals(a, "-usehrt")) - _UseHRT = true; + { + Debug |= Insensitive.Equals(a, "-debug"); + Service |= Insensitive.Equals(a, "-service"); + Profiling |= Insensitive.Equals(a, "-profiling"); + HaltOnWarning |= Insensitive.Equals(a, "-haltonwarning"); + } try { @@ -355,9 +299,7 @@ namespace Server Console.SetOut(MultiConsoleOut = new MultiTextWriter(new FileLogger("Logs/Console.log"))); } else - { Console.SetOut(MultiConsoleOut = new MultiTextWriter(Console.Out)); - } } catch { @@ -365,8 +307,6 @@ namespace Server } Thread = Thread.CurrentThread; - Process = Process.GetCurrentProcess(); - Assembly = Assembly.GetEntryAssembly(); if (Thread != null) Thread.Name = "Core Thread"; @@ -399,6 +339,12 @@ namespace Server Name = "Timer Thread" }; + Version ver = Version; + + // Added to help future code support on forums, as a 'check' people can ask for to it see if they recompiled core or not + Console.WriteLine("ModernUO - [https://github.com/modernuo/modernuo] v{0}.{1}.{2}{3}", ver.Major, ver.Minor, ver.Build, ver.Revision != 0 ? ver.Revision.ToString() : ""); + Console.WriteLine("Core: Running on {0}", RuntimeInformation.FrameworkDescription); + string s = Arguments; if (s.Length > 0) @@ -406,17 +352,15 @@ namespace Server ProcessorCount = Environment.ProcessorCount; - if (ProcessorCount > 1) - MultiProcessor = true; + MultiProcessor |= ProcessorCount > 1; - if (MultiProcessor || Is64Bit) - Console.WriteLine("Core: Optimizing for {0} {2}processor{1}", ProcessorCount, ProcessorCount == 1 ? "" : "s", - Is64Bit ? "64-bit " : ""); + if (!Is64Bit) throw new NotSupportedException("Core: 32-bit operating systems are not supported"); - int platform = (int)Environment.OSVersion.Platform; - if (platform == 4 || platform == 128) + if (MultiProcessor) + Console.WriteLine("Core: Optimizing for {0} processor{1}", ProcessorCount, ProcessorCount == 1 ? "" : "s"); + + if (Environment.OSVersion.Platform == PlatformID.Unix) { - // MS 4, MONO 128 Unix = true; Console.WriteLine("Core: Unix environment detected"); } @@ -429,9 +373,8 @@ namespace Server if (GCSettings.IsServerGC) Console.WriteLine("Core: Server garbage collection mode enabled"); - if (_UseHRT) - Console.WriteLine("Core: Requested high resolution timing ({0})", - UsingHighResolutionTiming ? "Supported" : "Unsupported"); + if (UsingHighResolutionTiming) + Console.WriteLine("Core: High resolution timing detected"); Console.WriteLine("RandomImpl: {0} ({1})", RandomImpl.Type.Name, RandomImpl.IsHardwareRNG ? "Hardware" : "Software"); @@ -473,7 +416,9 @@ namespace Server { m_Signal.WaitOne(); - Task.WaitAll( + + Task.WhenAll( + Task.Run(Mobile.ProcessDeltaQueue), Task.Run(Item.ProcessDeltaQueue) ); @@ -539,8 +484,7 @@ namespace Server BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly) == null) { - if (warningSb == null) warningSb = new StringBuilder(); - + warningSb ??= new StringBuilder(); warningSb.AppendLine(" - No Serialize() method"); } @@ -550,8 +494,7 @@ namespace Server BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly) == null) { - if (warningSb == null) warningSb = new StringBuilder(); - + warningSb ??= new StringBuilder(); warningSb.AppendLine(" - No Deserialize() method"); } @@ -565,7 +508,8 @@ namespace Server private static void VerifySerialization(Assembly a) { - if (a != null) Parallel.ForEach(a.GetTypes(), VerifyType); + if (a != null) + Parallel.ForEach(a.GetTypes(), VerifyType); } internal enum ConsoleEventType diff --git a/Projects/Server/Map.cs b/Projects/Server/Map.cs index 9f7235197..af0513343 100644 --- a/Projects/Server/Map.cs +++ b/Projects/Server/Map.cs @@ -20,8 +20,10 @@ using System; using System.Collections; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; +using System.Threading; using Server.Items; using Server.Network; using Server.Targeting; @@ -45,7 +47,7 @@ namespace Server void Free(); } - public interface IPooledEnumerable : IPooledEnumerable, IEnumerable + public interface IPooledEnumerable : IPooledEnumerable, IEnumerable { } @@ -88,21 +90,15 @@ namespace Server return eable.Where(bounds.Contains); } - public static IEnumerable SelectMobiles(Sector s, Rectangle2D bounds) where T : Mobile - { - return s.Mobiles.OfType().Where(o => !o.Deleted && bounds.Contains(o)); - } + public static IEnumerable SelectMobiles(Sector s, Rectangle2D bounds) where T : Mobile => + s.Mobiles.OfType().Where(o => !o.Deleted && bounds.Contains(o)); - public static IEnumerable SelectItems(Sector s, Rectangle2D bounds) where T : Item - { - return s.Items.OfType() + public static IEnumerable SelectItems(Sector s, Rectangle2D bounds) where T : Item => + s.Items.OfType() .Where(o => o.Deleted == false && o.Parent == null && bounds.Contains(o)); - } - public static IEnumerable SelectMultis(Sector s, Rectangle2D bounds) - { - return s.Multis.Where(o => o?.Deleted == false && bounds.Contains(o.Location)); - } + public static IEnumerable SelectMultis(Sector s, Rectangle2D bounds) => + s.Multis.Where(o => o?.Deleted == false && bounds.Contains(o.Location)); public static IEnumerable SelectMultiTiles(Sector s, Rectangle2D bounds) { @@ -110,26 +106,23 @@ namespace Server { MultiComponentList c = o.Components; - int x, y, xo, yo; - StaticTile[] t, r; - - for (x = bounds.Start.X; x < bounds.End.X; x++) + for (int x = bounds.Start.X; x < bounds.End.X; x++) { - xo = x - (o.X + c.Min.X); + int xo = x - (o.X + c.Min.X); if (xo < 0 || xo >= c.Width) continue; - for (y = bounds.Start.Y; y < bounds.End.Y; y++) + for (int y = bounds.Start.Y; y < bounds.End.Y; y++) { - yo = y - (o.Y + c.Min.Y); + int yo = y - (o.Y + c.Min.Y); if (yo < 0 || yo >= c.Height) continue; - t = c.Tiles[xo][yo]; + StaticTile[] t = c.Tiles[xo][yo]; if (t.Length <= 0) continue; - r = new StaticTile[t.Length]; + StaticTile[] r = new StaticTile[t.Length]; for (int i = 0; i < t.Length; i++) { @@ -257,7 +250,7 @@ namespace Server public const int SectorShift = 4; public static int SectorActiveRange = 2; - private static readonly Queue> _FixPool = new Queue>(128); + private static readonly ConcurrentQueue> _FixPool = new ConcurrentQueue>(); private static readonly List _EmptyFixItems = new List(); private Region m_DefaultRegion; @@ -271,9 +264,7 @@ namespace Server private TileMatrix m_Tiles; - private object tileLock = new object(); - - public Map(int mapID, int mapIndex, int fileIndex, int width, int height, int season, string name, MapRules rules) + public Map(int mapID, int mapIndex, int fileIndex, int width, int height, byte season, string name, MapRules rules) { MapID = mapID; MapIndex = mapIndex; @@ -302,17 +293,14 @@ namespace Server public static List AllMaps{ get; } = new List(); - public int Season{ get; set; } + public byte Season{ get; set; } public TileMatrix Tiles { get { if (m_Tiles == null) - lock (tileLock) - { - m_Tiles = new TileMatrix(this, m_FileIndex, MapID, Width, Height); - } + Interlocked.Exchange(ref m_Tiles, new TileMatrix(this, m_FileIndex, MapID, Width, Height)); return m_Tiles; } @@ -330,8 +318,7 @@ namespace Server public Region DefaultRegion { - get => m_DefaultRegion ?? - (m_DefaultRegion = new Region(null, this, 0, new Rectangle3D[0])); + get => m_DefaultRegion ??= new Region(null, this, 0, new Rectangle3D[0]); set => m_DefaultRegion = value; } @@ -369,15 +356,9 @@ namespace Server public int CompareTo(Map other) => other == null ? -1 : MapID.CompareTo(other.MapID); - public static string[] GetMapNames() - { - return Maps.Where(m => m != null).Select(m => m.Name).ToArray(); - } + public static string[] GetMapNames() => Maps.Where(m => m != null).Select(m => m.Name).ToArray(); - public static Map[] GetMapValues() - { - return Maps.Where(m => m != null).ToArray(); - } + public static Map[] GetMapValues() => Maps.Where(m => m != null).ToArray(); public static Map Parse(string value) { @@ -388,7 +369,7 @@ namespace Server return Internal; if (!int.TryParse(value, out int index)) - return Maps.FirstOrDefault(m => m != null && Insensitive.Equals(m.Name, value)); + return Maps.FirstOrDefault(m => Insensitive.Equals(m?.Name ?? "", value)); return index == 127 ? Internal : Maps.FirstOrDefault(m => m?.MapIndex == index); } @@ -448,15 +429,7 @@ namespace Server if (map == null || map == Internal || x < 0 || x > map.Width || y < 0 || y > map.Height) return _EmptyFixItems; - List pool = null; - - lock (_FixPool) - { - if (_FixPool.Count > 0) - pool = _FixPool.Dequeue(); - } - - if (pool == null) + if (!_FixPool.TryDequeue(out List pool) || pool == null) pool = new List(128); // Arbitrary limit IPooledEnumerable eable = map.GetItemsInRange(new Point3D(x, y, 0), 0); @@ -478,11 +451,8 @@ namespace Server pool.Clear(); - lock (_FixPool) - { - if (_FixPool.Count < 128) - _FixPool.Enqueue(pool); - } + if (_FixPool.Count < 128) + _FixPool.Enqueue(pool); } public void FixColumn(int x, int y) @@ -578,13 +548,13 @@ namespace Server /// Gets the highest surface that is lower than . /// /// The reference point. - /// A surface or . - public object GetTopSurface(Point3D p) + /// A surface ITile + public ITile GetTopSurface(Point3D p) { if (this == Internal) return null; - object surface = null; + ITile surface = null; int surfaceZ = int.MinValue; @@ -936,7 +906,7 @@ namespace Server public sealed class PooledEnumerable : IPooledEnumerable, IDisposable { - private static readonly Queue> _Buffer = new Queue>(0x400); + private static readonly ConcurrentQueue> _Buffer = new ConcurrentQueue>(); private bool _IsDisposed; @@ -968,29 +938,20 @@ namespace Server _Pool.Clear(); _Pool.Capacity = Math.Max(_Pool.Capacity, 0x100); - lock (((ICollection)_Buffer).SyncRoot) - { - _Buffer.Enqueue(this); - } + _Buffer.Enqueue(this); } public static PooledEnumerable Instantiate(Map map, Rectangle2D bounds, PooledEnumeration.Selector selector) { - PooledEnumerable e = null; - - lock (((ICollection)_Buffer).SyncRoot) - { - if (_Buffer.Count > 0) - e = _Buffer.Dequeue(); - } - IEnumerable pool = PooledEnumeration.EnumerateSectors(map, bounds).SelectMany(s => selector(s, bounds)); - if (e == null) - return new PooledEnumerable(pool); + if (_Buffer.TryDequeue(out PooledEnumerable e) && e != null) + { + e._Pool.AddRange(pool); + return e; + } - e._Pool.AddRange(pool); - return e; + return new PooledEnumerable(pool); } } @@ -1031,6 +992,7 @@ namespace Server public IPooledEnumerable GetMobilesInBounds(Rectangle2D bounds) where T : Mobile => PooledEnumeration.GetMobiles(this, bounds); + public IPooledEnumerable GetMobilesInBounds(Rectangle2D bounds) where T : Mobile => PooledEnumeration.GetMobiles(this, bounds); #endregion #region CanFit @@ -1063,8 +1025,7 @@ namespace Server if ((landFlags & TileFlag.Impassable) != 0 && avgZ > z && z + height > lowZ) return false; - if ((landFlags & TileFlag.Impassable) == 0 && z == avgZ && !lt.Ignored) - hasSurface = true; + hasSurface |= (landFlags & TileFlag.Impassable) == 0 && z == avgZ && !lt.Ignored; StaticTile[] staticTiles = Tiles.GetStaticTiles(x, y, true); @@ -1079,8 +1040,7 @@ namespace Server if ((surface || impassable) && staticTiles[i].Z + id.CalcHeight > z && z + height > staticTiles[i].Z) return false; - if (surface && !impassable && z == staticTiles[i].Z + id.CalcHeight) - hasSurface = true; + hasSurface |= surface && !impassable && z == staticTiles[i].Z + id.CalcHeight; } Sector sector = GetSector(x, y); @@ -1101,22 +1061,14 @@ namespace Server z + height > item.Z) return false; - if (surface && !impassable && !item.Movable && z == item.Z + id.CalcHeight) - hasSurface = true; + hasSurface |= surface && !impassable && !item.Movable && z == item.Z + id.CalcHeight; } } - if (checkMobiles) - for (int i = 0; i < mobs.Count; ++i) - { - Mobile m = mobs[i]; - - if (m.Location.m_X == x && m.Location.m_Y == y && (m.AccessLevel == AccessLevel.Player || !m.Hidden) && - m.Z + 16 > z && z + height > m.Z) - return false; - } - - return !requireSurface || hasSurface; + return !(checkMobiles && mobs.Any(m => m.Location.m_X == x && m.Location.m_Y == y && + (m.AccessLevel == AccessLevel.Player || !m.Hidden) && + m.Z + 16 > z && z + height > m.Z)) && + (!requireSurface || hasSurface); } #endregion @@ -1127,13 +1079,8 @@ namespace Server public bool CanSpawnMobile(Point2D p, int z) => CanSpawnMobile(p.m_X, p.m_Y, z); - public bool CanSpawnMobile(int x, int y, int z) - { - if (!Region.Find(new Point3D(x, y, z), this).AllowSpawn()) - return false; - - return CanFit(x, y, z, 16); - } + public bool CanSpawnMobile(int x, int y, int z) => + Region.Find(new Point3D(x, y, z), this).AllowSpawn() && CanFit(x, y, z, 16); #endregion diff --git a/Projects/Server/Menus/IMenu.cs b/Projects/Server/Menus/IMenu.cs index 56405f32e..075767f8b 100644 --- a/Projects/Server/Menus/IMenu.cs +++ b/Projects/Server/Menus/IMenu.cs @@ -24,10 +24,10 @@ namespace Server.Menus { public interface IMenu { - int Serial{ get; } + Serial Serial{ get; } int EntryLength{ get; } void SendTo(NetState state); void OnCancel(NetState state); void OnResponse(NetState state, int index); } -} \ No newline at end of file +} diff --git a/Projects/Server/Menus/ItemListMenu.cs b/Projects/Server/Menus/ItemListMenu.cs index 8fc57a153..0ad2e424d 100644 --- a/Projects/Server/Menus/ItemListMenu.cs +++ b/Projects/Server/Menus/ItemListMenu.cs @@ -20,7 +20,7 @@ using Server.Network; -namespace Server.Menus.ItemLists +namespace Server.Menus { public class ItemListEntry { @@ -40,8 +40,7 @@ namespace Server.Menus.ItemLists public class ItemListMenu : IMenu { - private static int m_NextSerial; - private int m_Serial; + private static Serial m_NextSerial; public ItemListMenu(string question, ItemListEntry[] entries) { @@ -50,18 +49,18 @@ namespace Server.Menus.ItemLists do { - m_Serial = m_NextSerial++; - m_Serial &= 0x7FFFFFFF; - } while (m_Serial == 0); + Serial = m_NextSerial++; + Serial &= 0x7FFFFFFF; + } while (Serial == 0); - m_Serial = (int)((uint)m_Serial | 0x80000000); + Serial |= 0x80000000; } public string Question{ get; } public ItemListEntry[] Entries{ get; set; } - int IMenu.Serial => m_Serial; + public Serial Serial { get; private set; } int IMenu.EntryLength => Entries.Length; @@ -76,7 +75,7 @@ namespace Server.Menus.ItemLists public void SendTo(NetState state) { state.AddMenu(this); - state.Send(new DisplayItemListMenu(this)); + Packets.SendDisplayItemListMenu(state, this); } } } diff --git a/Projects/Server/Menus/QuestionMenu.cs b/Projects/Server/Menus/QuestionMenu.cs index 0fe6a5aa2..3e65603d0 100644 --- a/Projects/Server/Menus/QuestionMenu.cs +++ b/Projects/Server/Menus/QuestionMenu.cs @@ -20,12 +20,11 @@ using Server.Network; -namespace Server.Menus.Questions +namespace Server.Menus { public class QuestionMenu : IMenu { - private static int m_NextSerial; - private int m_Serial; + private static Serial m_NextSerial; public QuestionMenu(string question, string[] answers) { @@ -34,16 +33,16 @@ namespace Server.Menus.Questions do { - m_Serial = ++m_NextSerial; - m_Serial &= 0x7FFFFFFF; - } while (m_Serial == 0); + Serial = ++m_NextSerial; + Serial &= 0x7FFFFFFF; + } while (Serial == 0); } public string Question{ get; set; } public string[] Answers{ get; } - int IMenu.Serial => m_Serial; + public Serial Serial { get; private set; } int IMenu.EntryLength => Answers.Length; @@ -58,7 +57,7 @@ namespace Server.Menus.Questions public void SendTo(NetState state) { state.AddMenu(this); - state.Send(new DisplayQuestionMenu(this)); + Packets.SendDisplayQuestionMenu(state, this); } } -} \ No newline at end of file +} diff --git a/Projects/Server/Mobile.cs b/Projects/Server/Mobile.cs index 0fe1f420e..55e1bed38 100644 --- a/Projects/Server/Mobile.cs +++ b/Projects/Server/Mobile.cs @@ -19,21 +19,20 @@ ***************************************************************************/ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.IO; +using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; using Server.Accounting; using Server.ContextMenus; -using Server.Guilds; using Server.Gumps; -using Server.HuePickers; using Server.Items; using Server.Menus; -using Server.Mobiles; using Server.Network; -using Server.Prompts; using Server.Targeting; namespace Server @@ -62,15 +61,10 @@ namespace Server } public TimedSkillMod(SkillName skill, bool relative, double value, DateTime expire) - : base(skill, relative, value) - { + : base(skill, relative, value) => m_Expire = expire; - } - public override bool CheckCondition() - { - return DateTime.UtcNow < m_Expire; - } + public override bool CheckCondition() => DateTime.UtcNow < m_Expire; } public class EquippedSkillMod : SkillMod @@ -85,10 +79,7 @@ namespace Server m_Mobile = mobile; } - public override bool CheckCondition() - { - return !m_Item.Deleted && !m_Mobile.Deleted && m_Item.Parent == m_Mobile; - } + public override bool CheckCondition() => !m_Item.Deleted && !m_Mobile.Deleted && m_Item.Parent == m_Mobile; } public class DefaultSkillMod : SkillMod @@ -98,10 +89,7 @@ namespace Server { } - public override bool CheckCondition() - { - return true; - } + public override bool CheckCondition() => true; } public abstract class SkillMod @@ -281,23 +269,14 @@ namespace Server public int Offset{ get; } - public bool HasElapsed() - { - if (m_Duration == TimeSpan.Zero) - return false; - - return DateTime.UtcNow - m_Added >= m_Duration; - } + public bool HasElapsed() => m_Duration != TimeSpan.Zero && DateTime.UtcNow - m_Added >= m_Duration; } #endregion public class DamageEntry { - public DamageEntry(Mobile damager) - { - Damager = damager; - } + public DamageEntry(Mobile damager) => Damager = damager; public Mobile Damager{ get; } @@ -423,10 +402,8 @@ namespace Server public class MobileNotConnectedException : Exception { public MobileNotConnectedException(Mobile source, string message) - : base(message) - { + : base(message) => Source = source.ToString(); - } } #region Delegates @@ -456,7 +433,7 @@ namespace Server /// /// Base class representing players, npcs, and creatures. /// - public class Mobile : IHued, IComparable, ISerializable, ISpawnable, IPropertyListObject + public class Mobile : IHued, IComparable, ISerializable, ISpawnable { private const int WarmodeCatchCount = 4; // Allow four warmode changes in 0.5 seconds, any more will be delay for two seconds @@ -501,8 +478,8 @@ namespace Server 198 }; - private static Queue m_DeltaQueue = new Queue(); - private static Queue m_DeltaQueueR = new Queue(); + private static ConcurrentQueue m_DeltaQueue = new ConcurrentQueue(); + private static ConcurrentQueue m_DeltaQueueR = new ConcurrentQueue(); private static bool _processing; @@ -605,7 +582,7 @@ namespace Server [CommandProperty(AccessLevel.GameMaster)] public Race Race { - get => m_Race ?? (m_Race = Race.DefaultRace); + get => m_Race ??= Race.DefaultRace; set { Race oldRace = Race; @@ -756,9 +733,7 @@ namespace Server if (m_Holding != null) { UpdateTotal(m_Holding, TotalType.Weight, m_Holding.TotalWeight + m_Holding.PileWeight); - - if (m_Holding.HeldBy == null) - m_Holding.HeldBy = this; + m_Holding.HeldBy ??= this; } } } @@ -826,8 +801,7 @@ namespace Server if (m_StrLock != value) { m_StrLock = value; - - m_NetState?.Send(new StatLockInfo(this)); + Packets.SendStatLockInfo(m_NetState, this); } } } @@ -844,8 +818,7 @@ namespace Server if (m_DexLock != value) { m_DexLock = value; - - m_NetState?.Send(new StatLockInfo(this)); + Packets.SendStatLockInfo(m_NetState, this); } } } @@ -862,8 +835,7 @@ namespace Server if (m_IntLock != value) { m_IntLock = value; - - m_NetState?.Send(new StatLockInfo(this)); + Packets.SendStatLockInfo(m_NetState, this); } } } @@ -918,7 +890,7 @@ namespace Server return; } - m_NetState?.Send(new ChangeCombatant(m_Combatant)); + Packets.SendChangeCombatant(m_NetState, m_Combatant?.Serial ?? Serial.Zero); if (m_Combatant == null) { @@ -931,14 +903,10 @@ namespace Server } else { - if (m_ExpireCombatant == null) - m_ExpireCombatant = new ExpireCombatantTimer(this); - + m_ExpireCombatant ??= new ExpireCombatantTimer(this); m_ExpireCombatant.Start(); - if (m_CombatTimer == null) - m_CombatTimer = new CombatTimer(this); - + m_CombatTimer ??= new CombatTimer(this); m_CombatTimer.Start(); } @@ -1029,8 +997,8 @@ namespace Server m_Target = newTarget; - if (newTarget != null && m_NetState != null && !TargetLocked) - m_NetState.Send(newTarget.GetPacketFor(m_NetState)); + if (!TargetLocked) + Packets.SendTargetReq(m_NetState, newTarget); OnTargetChange(); } @@ -1047,9 +1015,9 @@ namespace Server { // Old packet is preferred until assistants catch up if (m_NetState.NewHaven && m_ContextMenu.RequiresNewPacket) - Send(new DisplayContextMenu(m_ContextMenu)); + Packets.SendDisplayContextMenu(m_NetState, m_ContextMenu); else - Send(new DisplayContextMenuOld(m_ContextMenu)); + Packets.SendDisplayContextMenuOld(m_NetState, m_ContextMenu); } } } @@ -1068,7 +1036,7 @@ namespace Server public static bool FwdEnabled{ get; set; } = true; - public static bool FwdUOTDOverride{ get; set; } = false; + public static bool FwdUOTDOverride{ get; set; } public static int FwdMaxSteps{ get; set; } = 4; @@ -1124,7 +1092,7 @@ namespace Server [CommandProperty(AccessLevel.GameMaster)] public Container Corpse{ get; set; } - public static char[] GhostChars{ get; set; } = new char[2] { 'o', 'O' }; + public static char[] GhostChars{ get; set; } = { 'o', 'O' }; public static bool NoSpeechLOS{ get; set; } @@ -1141,20 +1109,12 @@ namespace Server [CommandProperty(AccessLevel.GameMaster)] public Mobile LastKiller{ get; set; } - public static bool DefaultShowVisibleDamage - { - get => m_DefaultShowVisibleDamage; - set => m_DefaultShowVisibleDamage = value; - } + public static bool DefaultShowVisibleDamage { get; set; } - public static bool DefaultCanSeeVisibleDamage - { - get => m_DefaultCanSeeVisibleDamage; - set => m_DefaultCanSeeVisibleDamage = value; - } + public static bool DefaultCanSeeVisibleDamage { get; set; } - public virtual bool ShowVisibleDamage => m_DefaultShowVisibleDamage; - public virtual bool CanSeeVisibleDamage => m_DefaultCanSeeVisibleDamage; + public virtual bool ShowVisibleDamage => DefaultShowVisibleDamage; + public virtual bool CanSeeVisibleDamage => DefaultCanSeeVisibleDamage; [CommandProperty(AccessLevel.GameMaster)] public bool Squelched{ get; set; } @@ -1407,8 +1367,7 @@ namespace Server m_Warmode = value; Delta(MobileDelta.Flags); - if (m_NetState != null) - Send(SetWarMode.Instantiate(value)); + Packets.SendSetWarMode(m_NetState, m_Warmode); if (!m_Warmode) Combatant = null; @@ -1537,11 +1496,7 @@ namespace Server public string Language { get => m_Language; - set - { - if (m_Language != value) - m_Language = value; - } + set => m_Language = value; } [CommandProperty(AccessLevel.GameMaster)] @@ -1768,9 +1723,22 @@ namespace Server public Region Region => m_Region ?? (Map == null ? Map.Internal.DefaultRegion : Map.DefaultRegion); - public Packet RemovePacket => StaticPacketHandlers.GetRemoveEntityPacket(this); - public OPLInfo OPLPacket => StaticPacketHandlers.GetOPLInfoPacket(this); - public ObjectPropertyList PropertyList => StaticPacketHandlers.GetOPLPacket(this); + private ObjectPropertyList m_PropertyList; + + public ObjectPropertyList PropertyList + { + get + { + if (m_PropertyList == null) + { + // TODO: Object Pool OPL + m_PropertyList = new ObjectPropertyList(this); + GetProperties(m_PropertyList); + } + + return m_PropertyList; + } + } [CommandProperty(AccessLevel.GameMaster)] public int SolidHueOverride @@ -1811,10 +1779,8 @@ namespace Server if (m_BankBox?.Deleted == false && m_BankBox.Parent == this) return m_BankBox; - m_BankBox = FindItemOnLayer(Layer.Bank) as BankBox; - - if (m_BankBox == null) - AddItem(m_BankBox = new BankBox(this)); + m_BankBox = FindItemOnLayer(Layer.Bank) as BankBox ?? new BankBox(this); + AddItem(m_BankBox); return m_BankBox; } @@ -1836,13 +1802,7 @@ namespace Server public bool HasTrade { - get - { - if (m_NetState != null) - return m_NetState.Trades.Count > 0; - - return false; - } + get => m_NetState?.Trades.Count > 0; } public bool NoMoveHS{ get; set; } @@ -1933,8 +1893,7 @@ namespace Server if (m_MountItem?.Deleted == false && m_MountItem.Parent == this) item = m_MountItem; - if (item == null) - item = FindItemOnLayer(Layer.Mount); + item ??= FindItemOnLayer(Layer.Mount); if (!(item is IMountItem mountItem)) return null; @@ -1964,7 +1923,7 @@ namespace Server public virtual bool CanTarget => true; public virtual bool ClickTitle => true; - public virtual bool PropertyTitle => OldPropertyTitles ? ClickTitle : true; + public virtual bool PropertyTitle => !OldPropertyTitles || ClickTitle; public static bool DisableHiddenSelfClick{ get; set; } = true; @@ -2020,10 +1979,7 @@ namespace Server public virtual void Delete() { - if (Deleted) - return; - - if (!World.OnDelete(this)) + if (Deleted || !World.OnDelete(this)) return; if (m_NetState != null) @@ -2067,7 +2023,7 @@ namespace Server OnAfterDelete(); - FreeCache(); + ClearProperties(); } [CommandProperty(AccessLevel.Counselor, AccessLevel.GameMaster)] @@ -2107,14 +2063,10 @@ namespace Server if (ns != null && m_Map != null) { ns.Sequence = 0; - ns.Send(new MapChange(this)); - ns.Send(new MapPatches()); - ns.Send(SeasonChange.Instantiate(GetSeason(), true)); - - if (ns.StygianAbyss) - ns.Send(new MobileUpdate(this)); - else - ns.Send(new MobileUpdateOld(this)); + Packets.SendMapChange(ns, m_Map); + Packets.SendMapPatches(ns); + Packets.SendSeasonChange(ns, GetSeason(), 1); + Packets.SendMobileUpdate(ns, this); ClearFastwalkStack(); } @@ -2122,25 +2074,15 @@ namespace Server if (ns != null) { if (m_Map != null) - ns.Send(new ServerChange(this, m_Map)); + Packets.SendServerChange(ns, this, m_Map); ns.Sequence = 0; ClearFastwalkStack(); - ns.Send(MobileIncoming.Create(ns, this, this)); - - if (ns.StygianAbyss) - { - ns.Send(new MobileUpdate(this)); - CheckLightLevels(true); - ns.Send(new MobileUpdate(this)); - } - else - { - ns.Send(new MobileUpdateOld(this)); - CheckLightLevels(true); - ns.Send(new MobileUpdateOld(this)); - } + Packets.SendMobileIncoming(ns, this, this); + Packets.SendMobileUpdate(ns, this); + CheckLightLevels(true); + Packets.SendMobileUpdate(ns, this); } SendEverything(); @@ -2151,20 +2093,10 @@ namespace Server ns.Sequence = 0; ClearFastwalkStack(); - ns.Send(MobileIncoming.Create(ns, this, this)); - - if (ns.StygianAbyss) - { - ns.Send(SupportedFeatures.Instantiate(ns)); - ns.Send(new MobileUpdate(this)); - ns.Send(new MobileAttributes(this)); - } - else - { - ns.Send(SupportedFeatures.Instantiate(ns)); - ns.Send(new MobileUpdateOld(this)); - ns.Send(new MobileAttributes(this)); - } + Packets.SendMobileIncoming(ns, this, this); + Packets.SendSupportedFeatures(ns); + Packets.SendMobileUpdate(ns, this); + Packets.SendMobileAttributes(ns, this); } OnMapChange(oldMap); @@ -2229,14 +2161,10 @@ namespace Server if (ns != null && m_Map != null) { ns.Sequence = 0; - ns.Send(new MapChange(this)); - ns.Send(new MapPatches()); - ns.Send(SeasonChange.Instantiate(GetSeason(), true)); - - if (ns.StygianAbyss) - ns.Send(new MobileUpdate(this)); - else - ns.Send(new MobileUpdateOld(this)); + Packets.SendMapChange(ns, m_Map); + Packets.SendMapPatches(ns); + Packets.SendSeasonChange(ns, GetSeason(), 1); + Packets.SendMobileUpdate(ns, this); ClearFastwalkStack(); } @@ -2249,25 +2177,15 @@ namespace Server if (ns != null) { if (m_Map != null) - Send(new ServerChange(this, m_Map)); + Packets.SendServerChange(ns, this, m_Map); ns.Sequence = 0; ClearFastwalkStack(); - ns.Send(MobileIncoming.Create(ns, this, this)); - - if (ns.StygianAbyss) - { - ns.Send(new MobileUpdate(this)); - CheckLightLevels(true); - ns.Send(new MobileUpdate(this)); - } - else - { - ns.Send(new MobileUpdateOld(this)); - CheckLightLevels(true); - ns.Send(new MobileUpdateOld(this)); - } + Packets.SendMobileIncoming(ns, this, this); + Packets.SendMobileUpdate(ns, this); + CheckLightLevels(true); + Packets.SendMobileUpdate(ns, this); } SendEverything(); @@ -2278,20 +2196,10 @@ namespace Server ns.Sequence = 0; ClearFastwalkStack(); - ns.Send(MobileIncoming.Create(ns, this, this)); - - if (ns.StygianAbyss) - { - ns.Send(SupportedFeatures.Instantiate(ns)); - ns.Send(new MobileUpdate(this)); - ns.Send(new MobileAttributes(this)); - } - else - { - ns.Send(SupportedFeatures.Instantiate(ns)); - ns.Send(new MobileUpdateOld(this)); - ns.Send(new MobileAttributes(this)); - } + Packets.SendMobileIncoming(ns, this, this); + Packets.SendSupportedFeatures(ns); + Packets.SendMobileUpdate(ns, this); + Packets.SendMobileUpdate(ns, this); } OnMapChange(oldMap); @@ -2350,9 +2258,7 @@ namespace Server sendAny = true; if (attrs == MobileDelta.Attributes) - { sendAll = true; - } else { sendHits = (attrs & MobileDelta.Hits) != 0; @@ -2361,7 +2267,7 @@ namespace Server } } - if ((delta & MobileDelta.GhostUpdate) != 0) sendNonlocalIncoming = true; + sendNonlocalIncoming |= (delta & MobileDelta.GhostUpdate) != 0; if ((delta & MobileDelta.Hue) != 0) { @@ -2393,11 +2299,11 @@ namespace Server sendUpdate = true; } else*/ - if ((delta & (MobileDelta.Flags | MobileDelta.Noto)) != 0) sendMoving = true; + sendMoving |= (delta & (MobileDelta.Flags | MobileDelta.Noto)) != 0; - if ((delta & MobileDelta.HealthbarPoison) != 0) sendHealthbarPoison = true; + sendHealthbarPoison |= (delta & MobileDelta.HealthbarPoison) != 0; - if ((delta & MobileDelta.HealthbarYellow) != 0) sendHealthbarYellow = true; + sendHealthbarYellow |= (delta & MobileDelta.HealthbarYellow) != 0; if ((delta & MobileDelta.Name) != 0) { @@ -2407,24 +2313,17 @@ namespace Server sendPublicStats = true; } - if ((delta & (MobileDelta.WeaponDamage | MobileDelta.Resistances | MobileDelta.Stat | - MobileDelta.Weight | MobileDelta.Gold | MobileDelta.Armor | MobileDelta.StatCap | - MobileDelta.Followers | MobileDelta.TithingPoints | MobileDelta.Race)) != 0) - sendPrivateStats = true; + sendPrivateStats |= (delta & (MobileDelta.WeaponDamage | MobileDelta.Resistances | MobileDelta.Stat | MobileDelta.Weight | MobileDelta.Gold | MobileDelta.Armor | MobileDelta.StatCap | MobileDelta.Followers | MobileDelta.TithingPoints | MobileDelta.Race)) != 0; if ((delta & MobileDelta.Hair) != 0) { - if (m.HairItemID <= 0) - removeHair = true; - + removeHair |= m.HairItemID <= 0; sendHair = true; } if ((delta & MobileDelta.FacialHair) != 0) { - if (m.FacialHairItemID <= 0) - removeFacialHair = true; - + removeFacialHair |= m.FacialHairItemID <= 0; sendFacialHair = true; } @@ -2438,58 +2337,42 @@ namespace Server { ourState.Sequence = 0; - if (ourState.StygianAbyss) - ourState.Send(new MobileUpdate(m)); - else - ourState.Send(new MobileUpdateOld(m)); + Packets.SendMobileUpdate(ourState, m); ClearFastwalkStack(); } if (sendIncoming) - ourState.Send(MobileIncoming.Create(ourState, m, m)); + Packets.SendMobileIncoming(ourState, m, m); if (ourState.StygianAbyss) { if (sendMoving) - { - int noto = Notoriety.Compute(m, m); - ourState.Send(cache[0][noto] = Packet.Acquire(new MobileMoving(m, noto))); - } + Packets.SendMobileMoving(ourState, m, Notoriety.Compute(m, m)); if (sendHealthbarPoison) - ourState.Send(new HealthbarPoison(m)); + Packets.SendHealthbarPoison(ourState, m); if (sendHealthbarYellow) - ourState.Send(new HealthbarYellow(m)); - } - else - { - if (sendMoving || sendHealthbarPoison || sendHealthbarYellow) - { - int noto = Notoriety.Compute(m, m); - ourState.Send(cache[1][noto] = Packet.Acquire(new MobileMovingOld(m, noto))); - } + Packets.SendHealthbarYellow(ourState, m); } + else if (sendMoving || sendHealthbarPoison || sendHealthbarYellow) + Packets.SendMobileMovingOld(ourState, m, Notoriety.Compute(m, m)); if (sendPublicStats || sendPrivateStats) - { - ourState.Send(new MobileStatusExtended(m, m_NetState)); - } + Packets.SendMobileStatusExtended(ourState, m); else if (sendAll) - { - ourState.Send(new MobileAttributes(m)); - } + Packets.SendMobileAttributes(ourState, m); else if (sendAny) { if (sendHits) - ourState.Send(new MobileHits(m)); + Packets.SendMobileHits(ourState, m); if (sendStam) - ourState.Send(new MobileStam(m)); + Packets.SendMobileStam(ourState, m); if (sendMana) - ourState.Send(new MobileMana(m)); + Packets.SendMobileMana(ourState, m); } if (sendStam || sendMana) @@ -2505,21 +2388,21 @@ namespace Server if (sendHair) { if (removeHair) - ourState.Send(new RemoveHair(m)); + Packets.SendRemoveHair(ourState, m); else - ourState.Send(new HairEquipUpdate(m)); + Packets.SendHairEquipUpdate(ourState, m); } if (sendFacialHair) { if (removeFacialHair) - ourState.Send(new RemoveFacialHair(m)); + Packets.SendRemoveFacialHair(ourState, m); else - ourState.Send(new FacialHairEquipUpdate(m)); + Packets.SendFacialHairEquipUpdate(ourState, m); } if (sendOPLUpdate) - ourState.Send(OPLPacket); + PropertyList.Send(ourState); } sendMoving = sendMoving || sendNonlocalMoving; @@ -2530,158 +2413,67 @@ namespace Server sendOPLUpdate || sendHair || sendFacialHair || sendHealthbarPoison || sendHealthbarYellow)) { - Mobile beholder; - - Packet hitsPacket = null; - Packet statPacketTrue = null; - Packet statPacketFalse = null; - Packet deadPacket = null; - Packet hairPacket = null; - Packet facialhairPacket = null; - Packet hbpPacket = null; - Packet hbyPacket = null; - IPooledEnumerable eable = m.Map.GetClientsInRange(m.m_Location); foreach (NetState state in eable) { - beholder = state.Mobile; + var beholder = state.Mobile; if (beholder != m && beholder.CanSee(m)) { if (sendRemove) - state.Send(RemovePacket); + Packets.SendRemoveEntity(state, Serial); if (sendIncoming) { - state.Send(MobileIncoming.Create(state, beholder, m)); + Packets.SendMobileIncoming(state, beholder, m); if (m.IsDeadBondedPet) - { - if (deadPacket == null) - deadPacket = Packet.Acquire(new BondedStatus(0, m.Serial, 1)); - - state.Send(deadPacket); - } + Packets.SendBondStatus(state, m.Serial, true); } if (state.StygianAbyss) { if (sendMoving) - { - int noto = Notoriety.Compute(beholder, m); - - Packet p = cache[0][noto]; - - if (p == null) - cache[0][noto] = p = Packet.Acquire(new MobileMoving(m, noto)); - - state.Send(p); - } + Packets.SendMobileMoving(state, m, Notoriety.Compute(beholder, m)); if (sendHealthbarPoison) - { - if (hbpPacket == null) - hbpPacket = Packet.Acquire(new HealthbarPoison(m)); - - state.Send(hbpPacket); - } + Packets.SendHealthbarPoison(state, m); if (sendHealthbarYellow) - { - if (hbyPacket == null) - hbyPacket = Packet.Acquire(new HealthbarYellow(m)); - - state.Send(hbyPacket); - } - } - else - { - if (sendMoving || sendHealthbarPoison || sendHealthbarYellow) - { - int noto = Notoriety.Compute(beholder, m); - - Packet p = cache[1][noto]; - - if (p == null) - cache[1][noto] = p = Packet.Acquire(new MobileMovingOld(m, noto)); - - state.Send(p); - } + Packets.SendHealthbarYellow(state, m); } + else if (sendMoving || sendHealthbarPoison || sendHealthbarYellow) + Packets.SendMobileMovingOld(state, m, Notoriety.Compute(beholder, m)); if (sendPublicStats) - { - if (m.CanBeRenamedBy(beholder)) - { - if (statPacketTrue == null) - statPacketTrue = Packet.Acquire(new MobileStatusCompact(true, m)); - - state.Send(statPacketTrue); - } - else - { - if (statPacketFalse == null) - statPacketFalse = Packet.Acquire(new MobileStatusCompact(false, m)); - - state.Send(statPacketFalse); - } - } + Packets.SendMobileStatusCompact(state, m, m.CanBeRenamedBy(beholder)); else if (sendHits) - { - if (hitsPacket == null) - hitsPacket = Packet.Acquire(new MobileHitsN(m)); - - state.Send(hitsPacket); - } + Packets.SendNormalizedMobileHits(state, m); if (sendHair) { - if (hairPacket == null) - { - if (removeHair) - hairPacket = Packet.Acquire(new RemoveHair(m)); - else - hairPacket = Packet.Acquire(new HairEquipUpdate(m)); - } - - state.Send(hairPacket); + if (removeHair) + Packets.SendRemoveHair(state, m); + else + Packets.SendHairEquipUpdate(state, m); } if (sendFacialHair) { - if (facialhairPacket == null) - { - if (removeFacialHair) - facialhairPacket = Packet.Acquire(new RemoveFacialHair(m)); - else - facialhairPacket = Packet.Acquire(new FacialHairEquipUpdate(m)); - } - - state.Send(facialhairPacket); + if (removeFacialHair) + Packets.SendRemoveFacialHair(state, m); + else + Packets.SendFacialHairEquipUpdate(state, m); } if (sendOPLUpdate) - state.Send(OPLPacket); + PropertyList.Send(state); } } - Packet.Release(hitsPacket); - Packet.Release(statPacketTrue); - Packet.Release(statPacketFalse); - Packet.Release(deadPacket); - Packet.Release(hairPacket); - Packet.Release(facialhairPacket); - Packet.Release(hbpPacket); - Packet.Release(hbyPacket); - eable.Free(); } - - if (sendMoving || sendNonlocalMoving || sendHealthbarPoison || sendHealthbarYellow) - for (int i = 0; i < cache.Length; ++i) - for (int j = 0; j < cache[i].Length; ++j) - Packet.Release(ref cache[i][j]); } public virtual int HuedItemID => m_Female ? 0x2107 : 0x2106; @@ -2775,7 +2567,7 @@ namespace Server writer.Write(EmoteHue); writer.Write(WhisperHue); writer.Write(YellHue); - writer.Write(m_Language); + writer.Write(Language); writer.Write(m_Female); writer.Write(m_Warmode); writer.Write(m_Hidden); @@ -2845,8 +2637,7 @@ namespace Server public virtual void UpdateResistances() { - if (Resistances == null) - Resistances = new int[5] { int.MinValue, int.MinValue, int.MinValue, int.MinValue, int.MinValue }; + Resistances ??= new[] { int.MinValue, int.MinValue, int.MinValue, int.MinValue, int.MinValue }; bool delta = false; @@ -2863,8 +2654,7 @@ namespace Server public virtual int GetResistance(ResistanceType type) { - if (Resistances == null) - Resistances = new int[5] { int.MinValue, int.MinValue, int.MinValue, int.MinValue, int.MinValue }; + Resistances ??= new[] { int.MinValue, int.MinValue, int.MinValue, int.MinValue, int.MinValue }; int v = (int)type; @@ -2884,8 +2674,7 @@ namespace Server public virtual void AddResistanceMod(ResistanceMod toAdd) { - if (ResistanceMods == null) ResistanceMods = new List(); - + ResistanceMods ??= new List(); ResistanceMods.Add(toAdd); UpdateResistances(); } @@ -2905,8 +2694,7 @@ namespace Server public virtual void ComputeResistances() { - if (Resistances == null) - Resistances = new int[] { int.MinValue, int.MinValue, int.MinValue, int.MinValue, int.MinValue }; + Resistances ??= new[] { int.MinValue, int.MinValue, int.MinValue, int.MinValue, int.MinValue }; for (int i = 0; i < Resistances.Length; ++i) Resistances[i] = 0; @@ -2955,49 +2743,37 @@ namespace Server } } - public virtual int GetMinResistance(ResistanceType type) - { - return int.MinValue; - } + public virtual int GetMinResistance(ResistanceType type) => int.MinValue; - public virtual int GetMaxResistance(ResistanceType type) - { - return m_Player ? MaxPlayerResistance : int.MaxValue; - } + public virtual int GetMaxResistance(ResistanceType type) => m_Player ? MaxPlayerResistance : int.MaxValue; - public int GetAOSStatus(int index) - { - return AOSStatusHandler?.Invoke(this, index) ?? 0; - } + public int GetAOSStatus(int index) => AOSStatusHandler?.Invoke(this, index) ?? 0; public virtual void SendPropertiesTo(Mobile from) { - from.Send(PropertyList); + PropertyList.Send(from.NetState); } public virtual void OnAosSingleClick(Mobile from) { ObjectPropertyList opl = PropertyList; - if (opl.Header > 0) - { - int hue; + if (opl.Header <= 0) + return; - if (NameHue != -1) - hue = NameHue; - else if (m_AccessLevel > AccessLevel.Player) - hue = 11; - else - hue = Notoriety.GetHue(Notoriety.Compute(from, this)); + int hue; - from.Send(new MessageLocalized(Serial, Body, MessageType.Label, hue, 3, opl.Header, Name, opl.HeaderArgs)); - } + if (NameHue != -1) + hue = NameHue; + else if (m_AccessLevel > AccessLevel.Player) + hue = 11; + else + hue = Notoriety.GetHue(Notoriety.Compute(from, this)); + + Packets.SendMessageLocalized(from.NetState, Serial, Body, MessageType.Label, hue, 3, opl.Header, Name, opl.HeaderArgs); } - public virtual string ApplyNameSuffix(string suffix) - { - return suffix; - } + public virtual string ApplyNameSuffix(string suffix) => suffix; public virtual void AddNameProperties(ObjectPropertyList list) { @@ -3008,18 +2784,13 @@ namespace Server if (ShowFameTitle && (m_Player || m_Body.IsHuman) && m_Fame >= 10000) prefix = m_Female ? "Lady" : "Lord"; - string suffix = ""; - - if (PropertyTitle && !string.IsNullOrEmpty(Title)) - suffix = Title; + string suffix = PropertyTitle && !string.IsNullOrEmpty(Title) ? Title : ""; BaseGuild guild = m_Guild; if (guild != null && (m_Player || m_DisplayGuildTitle)) - { suffix = suffix.Length > 0 ? $"{suffix} [{Utility.FixHtml(guild.Abbreviation)}]" : $"[{Utility.FixHtml(guild.Abbreviation)}]"; - } suffix = ApplyNameSuffix(suffix); @@ -3037,9 +2808,7 @@ namespace Server string title = GuildTitle?.Trim() ?? ""; if (NewGuildDisplay && title.Length > 0) - { list.Add("{0}, {1}", Utility.FixHtml(title), Utility.FixHtml(guild.Name)); - } else { if (title.Length > 0) @@ -3066,9 +2835,7 @@ namespace Server private void UpdateAggrExpire() { if (Deleted || Aggressors.Count == 0 && Aggressed.Count == 0) - { StopAggrExpire(); - } else if (m_ExpireAggrTimer == null) { m_ExpireAggrTimer = new ExpireAggressorsTimer(this); @@ -3101,7 +2868,7 @@ namespace Server info.Free(); if (m_NetState != null && CanSee(attacker) && Utility.InUpdateRange(m_Location, attacker.m_Location)) - m_NetState.Send(MobileIncoming.Create(m_NetState, this, attacker)); + Packets.SendMobileIncoming(m_NetState, this, attacker); } } @@ -3121,7 +2888,7 @@ namespace Server info.Free(); if (m_NetState != null && CanSee(defender) && Utility.InUpdateRange(m_Location, defender.m_Location)) - m_NetState.Send(MobileIncoming.Create(m_NetState, this, defender)); + Packets.SendMobileIncoming(m_NetState, this, defender); } } @@ -3233,44 +3000,23 @@ namespace Server return; } else - { ++m_WarmodeChanges; - } Warmode = value; } - public bool InLOS(Mobile target) - { - if (Deleted || m_Map == null) - return false; - if (target == this || m_AccessLevel > AccessLevel.Player) - return true; + public bool InLOS(Mobile target) => + !Deleted && m_Map != null && + (target == this || m_AccessLevel > AccessLevel.Player || m_Map.LineOfSight(this, target)); - return m_Map.LineOfSight(this, target); - } + public bool InLOS(object target) => + !Deleted && m_Map != null && + (target == this || m_AccessLevel > AccessLevel.Player || target is Item item && item.RootParent == this || m_Map.LineOfSight(this, target)); - public bool InLOS(object target) - { - if (Deleted || m_Map == null) - return false; - if (target == this || m_AccessLevel > AccessLevel.Player) - return true; - if (target is Item item && item.RootParent == this) - return true; + public bool InLOS(Point3D target) => + !Deleted && m_Map != null && (m_AccessLevel > AccessLevel.Player || m_Map.LineOfSight(this, target)); - return m_Map.LineOfSight(this, target); - } - - public bool InLOS(Point3D target) - { - return !Deleted && m_Map != null && (m_AccessLevel > AccessLevel.Player || m_Map.LineOfSight(this, target)); - } - - public bool BeginAction() - { - return BeginAction(typeof(T)); - } + public bool BeginAction() => BeginAction(typeof(T)); public bool BeginAction(object toLock) { @@ -3289,20 +3035,11 @@ namespace Server return false; } - public bool CanBeginAction() - { - return CanBeginAction(typeof(T)); - } + public bool CanBeginAction() => CanBeginAction(typeof(T)); - public bool CanBeginAction(object toLock) - { - return _actions == null || !_actions.Contains(toLock); - } + public bool CanBeginAction(object toLock) => _actions?.Contains(toLock) != true; - public void EndAction() - { - EndAction(typeof(T)); - } + public void EndAction() => EndAction(typeof(T)); public void EndAction(object toLock) { @@ -3314,10 +3051,7 @@ namespace Server } } - public virtual TimeSpan GetLogoutDelay() - { - return Region.GetLogoutDelay(this); - } + public virtual TimeSpan GetLogoutDelay() => Region.GetLogoutDelay(this); public void Paralyze(TimeSpan duration) { @@ -3341,10 +3075,7 @@ namespace Server } } - public override string ToString() - { - return $"0x{Serial.Value:X} \"{Name}\""; - } + public override string ToString() => $"0x{Serial.Value:X} \"{Name}\""; public virtual void SendSkillMessage() { @@ -3391,10 +3122,7 @@ namespace Server Combatant = m; } - public virtual bool CheckAttack(Mobile m) - { - return Utility.InUpdateRange(this, m) && CanSee(m) && InLOS(m); - } + public virtual bool CheckAttack(Mobile m) => Utility.InUpdateRange(this, m) && CanSee(m) && InLOS(m); /// /// Overridable. Virtual event invoked after the property has changed. @@ -3525,10 +3253,10 @@ namespace Server Aggressors.Add(AggressorInfo.Create(aggressor, this, criminal)); // new AggressorInfo( aggressor, this, criminal, true ) ); - if (CanSee(aggressor)) m_NetState?.Send(MobileIncoming.Create(m_NetState, this, aggressor)); + if (CanSee(aggressor)) + Packets.SendMobileIncoming(m_NetState, this, aggressor); - if (Combatant == null) - setCombatant = true; + setCombatant |= Combatant == null; UpdateAggrExpire(); } @@ -3538,10 +3266,10 @@ namespace Server aggressor.Aggressed.Add(AggressorInfo.Create(aggressor, this, criminal)); // new AggressorInfo( aggressor, this, criminal, false ) ); - if (CanSee(aggressor)) m_NetState?.Send(MobileIncoming.Create(m_NetState, this, aggressor)); + if (CanSee(aggressor)) + Packets.SendMobileIncoming(m_NetState, this, aggressor); - if (Combatant == null) - setCombatant = true; + setCombatant |= Combatant == null; UpdateAggrExpire(); } @@ -3568,8 +3296,8 @@ namespace Server Aggressed.RemoveAt(i); info.Free(); - if (m_NetState != null && CanSee(aggressed)) - m_NetState.Send(MobileIncoming.Create(m_NetState, this, aggressed)); + if (CanSee(aggressed)) + Packets.SendMobileIncoming(m_NetState, this, aggressed); break; } @@ -3594,8 +3322,8 @@ namespace Server Aggressors.RemoveAt(i); info.Free(); - if (m_NetState != null && CanSee(aggressor)) - m_NetState.Send(MobileIncoming.Create(m_NetState, this, aggressor)); + if (CanSee(aggressor)) + Packets.SendMobileIncoming(m_NetState, this, aggressor); break; } @@ -3604,22 +3332,14 @@ namespace Server UpdateAggrExpire(); } - public virtual int GetTotal(TotalType type) - { - switch (type) + public virtual int GetTotal(TotalType type) => + type switch { - case TotalType.Gold: - return m_TotalGold; - - case TotalType.Items: - return m_TotalItems; - - case TotalType.Weight: - return m_TotalWeight; - } - - return 0; - } + TotalType.Gold => m_TotalGold, + TotalType.Items => m_TotalItems, + TotalType.Weight => m_TotalWeight, + _ => 0 + }; public virtual void UpdateTotal(Item sender, TotalType type, int delta) { @@ -3682,21 +3402,13 @@ namespace Server m_QuestArrow = null; } - public void ClearTarget() - { - m_Target = null; - } + public void ClearTarget() => m_Target = null; - public Target BeginTarget(int range, bool allowGround, TargetFlags flags, TargetCallback callback) - { - return Target = new SimpleTarget(range, flags, allowGround, callback); - } + public Target BeginTarget(int range, bool allowGround, TargetFlags flags, TargetCallback callback) => + Target = new SimpleTarget(range, flags, allowGround, callback); public Target BeginTarget(int range, bool allowGround, TargetFlags flags, TargetStateCallback callback, - T state) - { - return Target = new SimpleStateTarget(range, flags, allowGround, callback, state); - } + T state) => Target = new SimpleStateTarget(range, flags, allowGround, callback, state); /// /// Overridable. Virtual event invoked after the Target property has changed. @@ -3705,10 +3417,7 @@ namespace Server { } - public virtual bool CheckContextMenuDisplay(IEntity target) - { - return true; - } + public virtual bool CheckContextMenuDisplay(IEntity target) => true; private bool InternalOnMove(Direction d) { @@ -3741,16 +3450,13 @@ namespace Server public virtual void ClearFastwalkStack() { - if (m_MoveRecords != null && m_MoveRecords.Count > 0) + if (m_MoveRecords?.Count > 0) m_MoveRecords.Clear(); m_EndQueue = Core.TickCount; } - public virtual bool CheckMovement(Direction d, out int newZ) - { - return Movement.Movement.CheckMovement(this, d, out newZ); - } + public virtual bool CheckMovement(Direction d, out int newZ) => Movement.CheckMovement(this, d, out newZ); public virtual bool Move(Direction d) { @@ -3832,42 +3538,21 @@ namespace Server if (oldSector != newSector) { - for (int i = 0; i < oldSector.Mobiles.Count; ++i) - { - Mobile m = oldSector.Mobiles[i]; + if (oldSector.Mobiles.Any( + m => m != this && m.X == oldX && m.Y == oldY && m.Z + 15 > oldZ && oldZ + 15 > m.Z && !m.OnMoveOff(this))) + return false; - if (m != this && m.X == oldX && m.Y == oldY && m.Z + 15 > oldZ && oldZ + 15 > m.Z && - !m.OnMoveOff(this)) - return false; - } + if (oldSector.Items.Any(item => item.AtWorldPoint(oldX, oldY) && + (item.Z == oldZ || item.Z + item.ItemData.Height > oldZ && oldZ + 15 > item.Z) && + !item.OnMoveOff(this))) + return false; - for (int i = 0; i < oldSector.Items.Count; ++i) - { - Item item = oldSector.Items[i]; + if (newSector.Mobiles.Any(m => m.X == x && m.Y == y && m.Z + 15 > newZ && newZ + 15 > m.Z && !m.OnMoveOver(this))) return false; - if (item.AtWorldPoint(oldX, oldY) && - (item.Z == oldZ || item.Z + item.ItemData.Height > oldZ && oldZ + 15 > item.Z) && - !item.OnMoveOff(this)) - return false; - } - - for (int i = 0; i < newSector.Mobiles.Count; ++i) - { - Mobile m = newSector.Mobiles[i]; - - if (m.X == x && m.Y == y && m.Z + 15 > newZ && newZ + 15 > m.Z && !m.OnMoveOver(this)) - return false; - } - - for (int i = 0; i < newSector.Items.Count; ++i) - { - Item item = newSector.Items[i]; - - if (item.AtWorldPoint(x, y) && - (item.Z == newZ || item.Z + item.ItemData.Height > newZ && newZ + 15 > item.Z) && - !item.OnMoveOver(this)) - return false; - } + if (newSector.Items.Any(item => item.AtWorldPoint(x, y) && + (item.Z == newZ || item.Z + item.ItemData.Height > newZ && newZ + 15 > item.Z) && + !item.OnMoveOver(this))) + return false; } else { @@ -3901,9 +3586,7 @@ namespace Server return false; } else - { return false; - } if (!InternalOnMove(d)) return false; @@ -3911,8 +3594,7 @@ namespace Server if (FwdEnabled && m_NetState != null && m_AccessLevel < FwdAccessOverride && (!FwdUOTDOverride || !m_NetState.IsUOTDClient)) { - if (m_MoveRecords == null) - m_MoveRecords = new Queue(6); + m_MoveRecords ??= new Queue(6); while (m_MoveRecords.Count > 0) { @@ -3957,8 +3639,7 @@ namespace Server DisruptiveAction(); } - m_NetState?.Send(MovementAck.Instantiate(m_NetState.Sequence, - this)); //new MovementAck( m_NetState.Sequence, this ) ); + Packets.SendMovementAck(m_NetState, this); SetLocation(newLocation, false); SetDirection(d); @@ -3979,59 +3660,27 @@ namespace Server m_MoveList.Add(mob); } else if (o is Item item && item.HandlesOnMovement) - { m_MoveList.Add(item); - } } eable.Free(); - Packet[][] cache = m_MovingPacketCache; - - /*for( int i = 0; i < cache.Length; ++i ) - for( int j = 0; j < cache[i].Length; ++j ) - Packet.Release( ref cache[i][j] );*/ - foreach (Mobile m in m_MoveClientList) { NetState ns = m.NetState; if (ns != null && Utility.InUpdateRange(m_Location, m.m_Location) && m.CanSee(this)) - { - if (ns.StygianAbyss) - { - int noto = Notoriety.Compute(m, this); - Packet p = cache[0][noto]; - - if (p == null) - cache[0][noto] = p = Packet.Acquire(new MobileMoving(this, noto)); - - ns.Send(p); - } - else - { - int noto = Notoriety.Compute(m, this); - Packet p = cache[1][noto]; - - if (p == null) - cache[1][noto] = p = Packet.Acquire(new MobileMovingOld(this, noto)); - - ns.Send(p); - } - } + Packets.SendMobileMoving(ns, this, Notoriety.Compute(m, this)); } - for (int i = 0; i < cache.Length; ++i) - for (int j = 0; j < cache[i].Length; ++j) - Packet.Release(ref cache[i][j]); - for (int i = 0; i < m_MoveList.Count; ++i) { IEntity o = m_MoveList[i]; if (o is Mobile mobile) mobile.OnMovement(this, oldLocation); - else if (o is Item item) item.OnMovement(this, oldLocation); + else if (o is Item item) + item.OnMovement(this, oldLocation); } if (m_MoveList.Count > 0) @@ -4049,15 +3698,9 @@ namespace Server { } - public int ComputeMovementSpeed() - { - return ComputeMovementSpeed(Direction, false); - } + public int ComputeMovementSpeed() => ComputeMovementSpeed(Direction, false); - public int ComputeMovementSpeed(Direction dir) - { - return ComputeMovementSpeed(dir, true); - } + public int ComputeMovementSpeed(Direction dir) => ComputeMovementSpeed(dir, true); public virtual int ComputeMovementSpeed(Direction dir, bool checkTurning) { @@ -4075,22 +3718,13 @@ namespace Server /// Overridable. Virtual event invoked when a Mobile moves off this Mobile. /// /// True if the move is allowed, false if not. - public virtual bool OnMoveOff(Mobile m) - { - return true; - } + public virtual bool OnMoveOff(Mobile m) => true; /// /// Overridable. Event invoked when a Mobile moves over this Mobile. /// /// True if the move is allowed, false if not. - public virtual bool OnMoveOver(Mobile m) - { - if (m_Map == null || Deleted) - return true; - - return m.CheckShove(this); - } + public virtual bool OnMoveOver(Mobile m) => m_Map == null || Deleted || m.CheckShove(this); public virtual bool CheckShove(Mobile shoved) { @@ -4150,10 +3784,7 @@ namespace Server Region.OnCriminalAction(this, message); } - public virtual bool IsSnoop(Mobile from) - { - return from != this; - } + public virtual bool IsSnoop(Mobile from) => from != this; /// /// Overridable. Any call to will silently fail if this method returns false. @@ -4253,10 +3884,7 @@ namespace Server Spawner = null; } - public virtual bool CheckSpellCast(ISpell spell) - { - return true; - } + public virtual bool CheckSpellCast(ISpell spell) => true; /// /// Overridable. Virtual event invoked when the Mobile casts a . @@ -4315,30 +3943,15 @@ namespace Server m_AutoManifestTimer?.Stop(); } - public virtual bool AllowSkillUse(SkillName name) - { - return true; - } + public virtual bool AllowSkillUse(SkillName name) => true; - public virtual bool UseSkill(SkillName name) - { - return Skills.UseSkill(this, name); - } + public virtual bool UseSkill(SkillName name) => Skills.UseSkill(this, name); - public virtual bool UseSkill(int skillID) - { - return Skills.UseSkill(this, skillID); - } + public virtual bool UseSkill(int skillID) => Skills.UseSkill(this, skillID); - public virtual DeathMoveResult GetParentMoveResultFor(Item item) - { - return item.OnParentDeath(this); - } + public virtual DeathMoveResult GetParentMoveResultFor(Item item) => item.OnParentDeath(this); - public virtual DeathMoveResult GetInventoryMoveResultFor(Item item) - { - return item.OnInventoryDeath(this); - } + public virtual DeathMoveResult GetInventoryMoveResultFor(Item item) => item.OnInventoryDeath(this); public virtual void Kill() { @@ -4462,20 +4075,10 @@ namespace Server Container c = CreateCorpseHandler?.Invoke(this, hair, facialhair, content, equip); - - /*m_Corpse = c; - - for ( int i = 0; c != null && i < content.Count; ++i ) - c.DropItem( (Item)content[i] ); - - if ( c != null ) - c.MoveToWorld( this.Location, this.Map );*/ - if (m_Map != null) { - Packet animPacket = null; - IPooledEnumerable eable = m_Map.GetClientsInRange(m_Location); + Serial cSerial = c?.Serial ?? Serial.Zero; foreach (NetState state in eable) if (state != m_NetState) @@ -4483,13 +4086,10 @@ namespace Server if (animPacket == null) animPacket = Packet.Acquire(new DeathAnimation(this, c)); - state.Send(animPacket); - - if (!state.Mobile.CanSee(this)) state.Send(RemovePacket); + if (!state.Mobile.CanSee(this)) + Packets.SendRemoveEntity(state, Serial); } - Packet.Release(animPacket); - eable.Free(); } @@ -4522,12 +4122,10 @@ namespace Server Effects.PlaySound(this, Map, sound); if (!m_Player) - { Delete(); - } else { - Send(DeathStatus.Instantiate(true)); + Packets.SendDeathStatus_Dead(NetState); Warmode = false; @@ -4553,16 +4151,13 @@ namespace Server ProcessDeltaQueue(); - Send(DeathStatus.Instantiate(false)); + Packets.SendDeathStatus_Alive(NetState); CheckStatTimers(); } } - public virtual bool CheckTarget(Mobile from, Target targ, object targeted) - { - return true; - } + public virtual bool CheckTarget(Mobile from, Target targ, object targeted) => true; public virtual void Use(Item item) { @@ -4578,28 +4173,18 @@ namespace Server bool okay = false; if (!Utility.InUpdateRange(this, item.GetWorldLocation())) - { item.OnDoubleClickOutOfRange(this); - } else if (!CanSee(item)) - { item.OnDoubleClickCantSee(this); - } else if (!item.IsAccessibleTo(this)) { - Region reg = Region.Find(item.GetWorldLocation(), item.Map); - - if (reg?.SendInaccessibleMessage(item, this) != true) + if (Region.Find(item.GetWorldLocation(), item.Map)?.SendInaccessibleMessage(item, this) != true) item.OnDoubleClickNotAccessible(this); } else if (!CheckAlive(false)) - { item.OnDoubleClickDead(this); - } else if (item.InSecureTrade) - { item.OnDoubleClickSecureTrade(this); - } else if (!AllowItemUse(item)) { } @@ -4607,13 +4192,9 @@ namespace Server { } else if (root is Mobile mobile && mobile.IsSnoop(this)) - { item.OnSnoop(this); - } - else if (Region.OnDoubleClick(this, item)) - { - okay = true; - } + else + okay |= Region.OnDoubleClick(this, item); if (okay) { @@ -4650,7 +4231,7 @@ namespace Server public virtual void Lift(Item item, int amount, out bool rejected, out LRReason reject) { rejected = true; - reject = LRReason.Inspecific; + reject = LRReason.Unspecific; if (item == null) return; @@ -4665,25 +4246,15 @@ namespace Server from.DisruptiveAction(); if (from.Holding != null) - { reject = LRReason.AreHolding; - } else if (from.AccessLevel < AccessLevel.GameMaster && !from.InRange(item.GetWorldLocation(), 2)) - { reject = LRReason.OutOfRange; - } else if (!from.CanSee(item) || !from.InLOS(item)) - { reject = LRReason.OutOfSight; - } else if (!item.VerifyMove(from)) - { reject = LRReason.CannotLift; - } else if (!item.IsAccessibleTo(from)) - { reject = LRReason.CannotLift; - } else if (item.Nontransferable && amount != item.Amount) { if (item.QuestItem) @@ -4699,17 +4270,11 @@ namespace Server IEntity root = item.RootParent; if (root is Mobile mobile && !mobile.CheckNonlocalLift(from, item)) - { reject = LRReason.TryToSteal; - } else if (!from.OnDragLift(item) || !item.OnDragLift(from)) - { - reject = LRReason.Inspecific; - } + reject = LRReason.Unspecific; else if (!from.CheckAlive()) - { - reject = LRReason.Inspecific; - } + reject = LRReason.Unspecific; else { item.SetLastMoved(); @@ -4738,25 +4303,14 @@ namespace Server if (DragEffects && map != null && (root == null || root is Item)) { IPooledEnumerable eable = map.GetClientsInRange(from.Location); - Packet p = null; Item rootItem = root as Item; + IEntity src = new Entity(rootItem?.Serial ?? Serial.Zero, + rootItem?.Location ?? item.Location, map); foreach (NetState ns in eable) if (ns.Mobile != from && ns.Mobile.CanSee(from) && ns.Mobile.InLOS(from) && ns.Mobile.CanSee(root)) - { - if (p == null) - { - IEntity src = new Entity(rootItem?.Serial ?? Serial.Zero, - rootItem?.Location ?? item.Location, map); - - p = Packet.Acquire(new DragEffect(src, from, item.ItemID, item.Hue, amount)); - } - - ns.Send(p); - } - - Packet.Release(p); + Packets.SendDragEffect(ns, src, from, item.ItemID, item.Hue, amount); eable.Free(); } @@ -4774,54 +4328,43 @@ namespace Server int liftSound = item.GetLiftSound(from); if (liftSound != -1) - from.Send(new PlaySound(liftSound, from)); + Packets.SendPlaySound(from.NetState, liftSound, from); from.NextActionTime = Core.TickCount + ActionDelay; - if (fixMap != null && shouldFix) - fixMap.FixColumn(fixLoc.m_X, fixLoc.m_Y); + if (shouldFix) + fixMap?.FixColumn(fixLoc.m_X, fixLoc.m_Y); - reject = LRReason.Inspecific; + reject = LRReason.Unspecific; rejected = false; } } } else - { - reject = LRReason.Inspecific; - } + reject = LRReason.Unspecific; } else { SendActionMessage(); - reject = LRReason.Inspecific; + reject = LRReason.Unspecific; } if (rejected && state != null) { - state.Send(new LiftRej(reject)); + Packets.SendLiftRej(state, reject); if (item.Deleted) return; if (item.Parent is Item) - { - if (state.ContainerGridLines) - state.Send(new ContainerContentUpdate6017(item)); - else - state.Send(new ContainerContentUpdate(item)); - } + Packets.SendContainerContentUpdate(state, item); else if (item.Parent is Mobile) - { - state.Send(new EquipUpdate(item)); - } + Packets.SendEquipUpdate(state, item); else - { item.SendInfoTo(state); - } if (ObjectPropertyList.Enabled && item.Parent != null) - state.Send(item.OPLPacket); + item.PropertyList.Send(state); } } @@ -4830,6 +4373,7 @@ namespace Server Item item; try { + // TODO: Kill this with a vengence... item = (Item)Activator.CreateInstance(oldItem.GetType()); } catch @@ -4859,7 +4403,8 @@ namespace Server if (oldItem.Parent is Mobile parentMobile) parentMobile.AddItem(item); - else if (oldItem.Parent is Item parentItem) parentItem.AddItem(item); + else if (oldItem.Parent is Item parentItem) + parentItem.AddItem(item); item.Delta(ItemDelta.Update); @@ -4876,8 +4421,8 @@ namespace Server if (map != null && (root == null || root is Item)) { IPooledEnumerable eable = map.GetClientsInRange(m_Location); - Packet p = null; Item rootItem = root as Item; + IEntity trg = new Entity(rootItem?.Serial ?? Serial.Zero, rootItem?.Location ?? item.Location, map); foreach (NetState ns in eable) { @@ -4885,21 +4430,9 @@ namespace Server continue; if (ns.Mobile != this && ns.Mobile.CanSee(this) && ns.Mobile.InLOS(this) && ns.Mobile.CanSee(root)) - { - if (p == null) - { - IEntity trg = new Entity(rootItem?.Serial ?? Serial.Zero, - rootItem?.Location ?? item.Location, map); - - p = Packet.Acquire(new DragEffect(this, trg, item.ItemID, item.Hue, item.Amount)); - } - - ns.Send(p); - } + Packets.SendDragEffect(ns, this, trg, item.ItemID, item.Hue, item.Amount); } - Packet.Release(p); - eable.Free(); } } @@ -5148,14 +4681,9 @@ namespace Server mutatedArgs = new SpeechEventArgs(this, mutatedText, type, hue, new int[0]); CheckSpeechManifest(); - ProcessDelta(); - Packet regp = null; - Packet mutp = null; - // TODO: Should this be sorted like onSpeech is below? - for (int i = 0; i < hears.Count; ++i) { Mobile heard = hears[i]; @@ -5165,36 +4693,21 @@ namespace Server heard.OnSpeech(regArgs); NetState ns = heard.NetState; - if (ns != null) - { - if (regp == null) - regp = Packet.Acquire(new UnicodeMessage(Serial, Body, type, hue, 3, m_Language, Name, - text)); - - ns.Send(regp); - } + Packets.SendUnicodeMessage(ns, Serial, Body, type, hue, 3, Language, Name, + text); } else { heard.OnSpeech(mutatedArgs); NetState ns = heard.NetState; - if (ns != null) - { - if (mutp == null) - mutp = Packet.Acquire(new UnicodeMessage(Serial, Body, type, hue, 3, m_Language, Name, - mutatedText)); - - ns.Send(mutp); - } + Packets.SendUnicodeMessage(ns, Serial, Body, type, hue, 3, Language, Name, + mutatedText); } } - Packet.Release(regp); - Packet.Release(mutp); - if (onSpeech.Count > 1) onSpeech.Sort(LocationComparer.GetInstance(this)); @@ -5210,9 +4723,7 @@ namespace Server heard.OnSpeech(mutatedArgs); } else - { ((Item)obj).OnSpeech(regArgs); - } } if (m_Hears.Count > 0) @@ -5223,15 +4734,9 @@ namespace Server } } - public static Mobile GetDamagerFrom(DamageEntry de) - { - return de?.Damager; - } + public static Mobile GetDamagerFrom(DamageEntry de) => de?.Damager; - public Mobile FindMostRecentDamager(bool allowSelf) - { - return GetDamagerFrom(FindMostRecentDamageEntry(allowSelf)); - } + public Mobile FindMostRecentDamager(bool allowSelf) => GetDamagerFrom(FindMostRecentDamageEntry(allowSelf)); public DamageEntry FindMostRecentDamageEntry(bool allowSelf) { @@ -5251,10 +4756,7 @@ namespace Server return null; } - public Mobile FindLeastRecentDamager(bool allowSelf) - { - return GetDamagerFrom(FindLeastRecentDamageEntry(allowSelf)); - } + public Mobile FindLeastRecentDamager(bool allowSelf) => GetDamagerFrom(FindLeastRecentDamageEntry(allowSelf)); public DamageEntry FindLeastRecentDamageEntry(bool allowSelf) { @@ -5279,10 +4781,7 @@ namespace Server return null; } - public Mobile FindMostTotalDamger(bool allowSelf) - { - return GetDamagerFrom(FindMostTotalDamageEntry(allowSelf)); - } + public Mobile FindMostTotalDamger(bool allowSelf) => GetDamagerFrom(FindMostTotalDamageEntry(allowSelf)); public DamageEntry FindMostTotalDamageEntry(bool allowSelf) { @@ -5304,10 +4803,7 @@ namespace Server return mostTotal; } - public Mobile FindLeastTotalDamger(bool allowSelf) - { - return GetDamagerFrom(FindLeastTotalDamageEntry(allowSelf)); - } + public Mobile FindLeastTotalDamger(bool allowSelf) => GetDamagerFrom(FindLeastTotalDamageEntry(allowSelf)); public DamageEntry FindLeastTotalDamageEntry(bool allowSelf) { @@ -5347,10 +4843,7 @@ namespace Server return null; } - public virtual Mobile GetDamageMaster(Mobile damagee) - { - return null; - } + public virtual Mobile GetDamageMaster(Mobile damagee) => null; public virtual DamageEntry RegisterDamage(int amount, Mobile from) { @@ -5366,23 +4859,9 @@ namespace Server if (master != null) { - List list = de.Responsible; + List list = de.Responsible ?? new List(); - if (list == null) - de.Responsible = list = new List(); - - DamageEntry resp = null; - - for (int i = 0; i < list.Count; ++i) - { - DamageEntry check = list[i]; - - if (check.Damager == master) - { - resp = check; - break; - } - } + DamageEntry resp = list.FirstOrDefault(check => check.Damager == master); if (resp == null) list.Add(resp = new DamageEntry(master)); @@ -5412,15 +4891,11 @@ namespace Server public virtual bool CanBeDamaged() { - return !m_Blessed; } - public virtual void Damage(int amount, Mobile from) - { - Damage(amount, from, true); - } + public virtual bool CanBeDamaged() => !m_Blessed; - public virtual void Damage(int amount, Mobile from, bool informMount) + public virtual void Damage(int amount, Mobile from = null, bool informMount = true) { if (!CanBeDamaged() || Deleted) return; @@ -5467,8 +4942,8 @@ namespace Server OnDamage(amount, from, newHits < 0); IMount m = Mount; - if (m != null && informMount) - m.OnRiderDamaged(amount, from, newHits < 0); + if (informMount) + m?.OnRiderDamaged(amount, from, newHits < 0); if (newHits < 0) { @@ -5480,64 +4955,22 @@ namespace Server Kill(); } else - { Hits = newHits; - } } } public void SendVisibleDamageRelated(Mobile from, int amount) { - NetState ourState = m_NetState, theirState = from?.m_NetState; + if (amount <= 0) + return; - if (ourState == null) - { - Mobile master = GetDamageMaster(from); + NetState ourState = m_NetState ?? GetDamageMaster(from)?.m_NetState; + NetState theirState = from?.m_NetState ?? from?.GetDamageMaster(this)?.m_NetState; - if (master != null) - ourState = master.m_NetState; - } + Packets.SendDamage(ourState, Serial, amount); - if (theirState == null && from != null) - { - Mobile master = from.GetDamageMaster(this); - - if (master != null) - theirState = master.m_NetState; - } - - if (amount > 0 && (ourState != null || theirState != null)) - { - Packet p = null; // = new DamagePacket( this, amount ); - - if (ourState != null) - { - p = ourState.DamagePacket ? Packet.Acquire(new DamagePacket(this, amount)) : - Packet.Acquire(new DamagePacketOld(this, amount)); - - ourState.Send(p); - } - - if (theirState != null && theirState != ourState) - { - bool newPacket = theirState.DamagePacket; - - if (newPacket && !(p is DamagePacket)) - { - Packet.Release(p); - p = Packet.Acquire(new DamagePacket(this, amount)); - } - else if (!newPacket && !(p is DamagePacketOld)) - { - Packet.Release(p); - p = Packet.Acquire(new DamagePacketOld(this, amount)); - } - - theirState.Send(p); - } - - Packet.Release(p); - } + if (theirState != ourState) + Packets.SendDamage(theirState, Serial, amount); } public void SendVisibleDamageEveryone(int amount) @@ -5552,41 +4985,24 @@ namespace Server IPooledEnumerable eable = map.GetClientsInRange(m_Location); - Packet pNew = null; - Packet pOld = null; - foreach (NetState ns in eable) if (ns.Mobile.CanSee(this)) - { - if (ns.DamagePacket) - { - if (pNew == null) - pNew = Packet.Acquire(new DamagePacket(this, amount)); - - ns.Send(pNew); - } - else - { - if (pOld == null) - pOld = Packet.Acquire(new DamagePacketOld(this, amount)); - - ns.Send(pOld); - } - } - - Packet.Release(pNew); - Packet.Release(pOld); + Packets.SendDamage(ns, Serial, amount); eable.Free(); } public void SendVisibleDamageSelective(Mobile from, int amount) { - NetState ourState = m_NetState, theirState = from?.m_NetState; + if (amount <= 0) + return; Mobile damager = from; Mobile damaged = this; + NetState ourState = m_NetState; + NetState theirState = from?.m_NetState; + if (ourState == null) { Mobile master = GetDamageMaster(from); @@ -5612,53 +5028,33 @@ namespace Server } } - if (amount > 0 && (ourState != null || theirState != null)) - { - if (damaged.CanSeeVisibleDamage && ourState != null) - { - if (ourState.DamagePacket) - ourState.Send(new DamagePacket(this, amount)); - else - ourState.Send(new DamagePacketOld(this, amount)); - } + if (damaged.CanSeeVisibleDamage) + Packets.SendDamage(ourState, Serial, amount); - if (theirState != null && theirState != ourState && damager.CanSeeVisibleDamage) - { - if (theirState.DamagePacket) - theirState.Send(new DamagePacket(this, amount)); - else - theirState.Send(new DamagePacketOld(this, amount)); - } - } + if (theirState != ourState && damager.CanSeeVisibleDamage) + Packets.SendDamage(theirState, Serial, amount); } public void Heal(int amount) { - Heal(amount, this, true); + Heal(amount, this); } - public void Heal(int amount, Mobile from) + public void Heal(int amount, Mobile from, bool message = true) { - Heal(amount, from, true); - } - - public void Heal(int amount, Mobile from, bool message) - { - if (!Alive || IsDeadBondedPet) - return; - - if (!Region.OnHeal(this, ref amount)) + if (!Alive || IsDeadBondedPet || !Region.OnHeal(this, ref amount)) return; OnHeal(ref amount, from); - if (Hits + amount > HitsMax) amount = HitsMax - Hits; + if (Hits + amount > HitsMax) + amount = HitsMax - Hits; Hits += amount; if (message && amount > 0) - m_NetState?.Send(new MessageLocalizedAffix(Serial.MinusOne, -1, MessageType.Label, 0x3B2, 3, 1008158, "", - AffixType.Append | AffixType.System, amount.ToString(), "")); + Packets.SendMessageLocalizedAffix(m_NetState, Serial.MinusOne, -1, MessageType.Label, 0x3B2, 3, 1008158, "", + AffixType.Append | AffixType.System, amount.ToString()); } public virtual void OnHeal(ref int amount, Mobile from) @@ -5868,8 +5264,7 @@ namespace Server if (version < 18) Virtues = new VirtueInfo(); - if (version < 11) - m_DisplayGuildTitle = true; + m_DisplayGuildTitle |= version < 11; if (version < 3) m_StatCap = 225; @@ -5890,7 +5285,7 @@ namespace Server EmoteHue = reader.ReadInt(); WhisperHue = reader.ReadInt(); YellHue = reader.ReadInt(); - m_Language = reader.ReadString(); + Language = reader.ReadString(); m_Female = reader.ReadBool(); m_Warmode = reader.ReadBool(); m_Hidden = reader.ReadBool(); @@ -5955,9 +5350,7 @@ namespace Server if (m_Criminal) { - if (m_ExpireCriminal == null) - m_ExpireCriminal = new ExpireCriminalTimer(this); - + m_ExpireCriminal ??= new ExpireCriminalTimer(this); m_ExpireCriminal.Start(); } @@ -6017,69 +5410,45 @@ namespace Server { if (CanRegenHits) { - if (m_HitsTimer == null) - m_HitsTimer = new HitsTimer(this); - + m_HitsTimer ??= new HitsTimer(this); m_HitsTimer.Start(); } else - { m_HitsTimer?.Stop(); - } } else - { Hits = HitsMax; - } if (Stam < StamMax) { if (CanRegenStam) { - if (m_StamTimer == null) - m_StamTimer = new StamTimer(this); - + m_StamTimer ??= new StamTimer(this); m_StamTimer.Start(); } else - { m_StamTimer?.Stop(); - } } else - { Stam = StamMax; - } if (Mana < ManaMax) { if (CanRegenMana) { - if (m_ManaTimer == null) - m_ManaTimer = new ManaTimer(this); - + m_ManaTimer ??= new ManaTimer(this); m_ManaTimer.Start(); } else - { m_ManaTimer?.Stop(); - } } else - { Mana = ManaMax; - } } - public static string GetAccessLevelName(AccessLevel level) - { - return m_AccessLevelNames[(int)level]; - } + public static string GetAccessLevelName(AccessLevel level) => m_AccessLevelNames[(int)level]; - public virtual bool CanPaperdollBeOpenedBy(Mobile from) - { - return Body.IsHuman || Body.IsGhost || IsBodyMod; - } + public virtual bool CanPaperdollBeOpenedBy(Mobile from) => Body.IsHuman || Body.IsGhost || IsBodyMod; public virtual void GetChildContextMenuEntries(Mobile from, List list, Item item) { @@ -6222,10 +5591,8 @@ namespace Server if (map == null) return; - ProcessDelta(); - Packet p = null; - //Packet pNew = null; + ProcessDelta(); IPooledEnumerable eable = map.GetClientsInRange(m_Location); @@ -6234,70 +5601,52 @@ namespace Server { state.Mobile.ProcessDelta(); - //if ( state.StygianAbyss ) { - //if ( pNew == null ) - //pNew = Packet.Acquire( new NewMobileAnimation( this, action, frameCount, delay ) ); - - //state.Send( pNew ); - //} else { - if (p == null) + if (Body.IsGargoyle) { - #region SA + frameCount = 10; - if (Body.IsGargoyle) + if (Flying) { - frameCount = 10; - - if (Flying) - { - if (action >= 9 && action <= 11) - action = 71; - else if (action >= 12 && action <= 14) - action = 72; - else if (action == 20) - action = 77; - else if (action == 31) - action = 71; - else if (action == 34) - action = 78; - else if (action >= 200 && action <= 259) - action = 75; - else if (action >= 260 && action <= 270) action = 75; - } - else - { - if (action >= 200 && action <= 259) - action = 17; - else if (action >= 260 && action <= 270) action = 16; - } + if (action >= 9 && action <= 11) + action = 71; + else if (action >= 12 && action <= 14) + action = 72; + else if (action == 20) + action = 77; + else if (action == 31) + action = 71; + else if (action == 34) + action = 78; + else if (action >= 200 && action <= 259) + action = 75; + else if (action >= 260 && action <= 270) action = 75; + } + else + { + if (action >= 200 && action <= 259) + action = 17; + else if (action >= 260 && action <= 270) + action = 16; } - - #endregion - - p = Packet.Acquire(new MobileAnimation(this, action, frameCount, repeatCount, forward, repeat, - delay)); } - state.Send(p); - //} + Packets.SendMobileAnimation(state, this, action, frameCount, repeatCount, forward, repeat, delay); } - Packet.Release(p); - //Packet.Release( pNew ); - eable.Free(); } public void SendSound(int soundID) { - if (soundID != -1 && m_NetState != null) - Send(new PlaySound(soundID, this)); + SendSound(soundID, this); } public void SendSound(int soundID, IPoint3D p) { - if (soundID != -1 && m_NetState != null) - Send(new PlaySound(soundID, p)); + if (soundID == -1) + return; + + Packets.SendPlaySound(m_NetState, soundID, p); } public void PlaySound(int soundID) @@ -6305,15 +5654,11 @@ namespace Server if (soundID == -1 || m_Map == null) return; - Packet p = Packet.Acquire(new PlaySound(soundID, this)); - IPooledEnumerable eable = m_Map.GetClientsInRange(m_Location); foreach (NetState state in eable) if (state.Mobile.CanSee(this)) - state.Send(p); - - Packet.Release(p); + Packets.SendPlaySound(m_NetState, soundID, this); eable.Free(); } @@ -6333,18 +5678,12 @@ namespace Server // Mobile did something which should unhide him public virtual void RevealingAction() { - if (m_Hidden && m_AccessLevel == AccessLevel.Player) - Hidden = false; + Hidden |= m_Hidden && m_AccessLevel == AccessLevel.Player; DisruptiveAction(); // Anything that unhides you will also distrupt meditation } - public void SendRemovePacket() - { - SendRemovePacket(true); - } - - public void SendRemovePacket(bool everyone) + public void SendRemovePacket(bool everyone = true) { if (m_Map == null) return; @@ -6353,7 +5692,7 @@ namespace Server foreach (NetState state in eable) if (state != m_NetState && (everyone || !state.Mobile.CanSee(this))) - state.Send(RemovePacket); + Packets.SendRemoveEntity(state, Serial); eable.Free(); } @@ -6369,12 +5708,12 @@ namespace Server if (o is Mobile m) { if (m != this && Utility.InUpdateRange(m_Location, m.m_Location)) - m_NetState.Send(m.RemovePacket); + Packets.SendRemoveEntity(m_NetState, m.Serial); } else if (o is Item item) { if (InRange(item.Location, item.GetUpdateRange(this))) - m_NetState.Send(item.RemovePacket); + Packets.SendRemoveEntity(m_NetState, item.Serial); } eable.Free(); @@ -6419,10 +5758,7 @@ namespace Server RevealingAction(); } - public virtual bool HandlesOnSpeech(Mobile from) - { - return false; - } + public virtual bool HandlesOnSpeech(Mobile from) => false; /// /// Overridable. Virtual event invoked when the Mobile hears speech. This event will only be invoked if @@ -6451,21 +5787,22 @@ namespace Server { if (CanSee(m) && Utility.InUpdateRange(m_Location, m.m_Location)) { - ns.Send(MobileIncoming.Create(ns, this, m)); + Packets.SendMobileIncoming(ns, this, m); if (ns.StygianAbyss) { if (m.Poisoned) - ns.Send(new HealthbarPoison(m)); + Packets.SendHealthbarPoison(ns, m); if (m.Blessed || m.YellowHealthbar) - ns.Send(new HealthbarYellow(m)); + Packets.SendHealthbarYellow(ns, m); } if (m.IsDeadBondedPet) - ns.Send(new BondedStatus(0, m.Serial, 1)); + Packets.SendBondStatus(ns, m.Serial, true); - if (ObjectPropertyList.Enabled) ns.Send(m.OPLPacket); + if (ObjectPropertyList.Enabled) + m.PropertyList.SendOPLInfo(ns); } } @@ -6502,10 +5839,7 @@ namespace Server m_Direction = dir; } - public virtual int GetSeason() - { - return m_Map?.Season ?? 1; - } + public virtual byte GetSeason() => m_Map?.Season ?? 1; public virtual int GetPacketFlags() { @@ -6584,17 +5918,15 @@ namespace Server foreach (NetState state in eable) if (!state.Mobile.CanSee(this)) - { - state.Send(RemovePacket); - } + Packets.SendRemoveEntity(state, Serial); else { - state.Send(MobileIncoming.Create(state, state.Mobile, this)); + Packets.SendMobileIncoming(state, state.Mobile, this); if (IsDeadBondedPet) - state.Send(new BondedStatus(0, Serial, 1)); + Packets.SendBondStatus(state, Serial, true); - if (ObjectPropertyList.Enabled) state.Send(OPLPacket); + if (ObjectPropertyList.Enabled) PropertyList.Send(state); } eable.Free(); @@ -6670,10 +6002,7 @@ namespace Server m_AccessLevel > AccessLevel.Player || m.Warmode); } - public virtual bool CanBeRenamedBy(Mobile from) - { - return from.AccessLevel >= AccessLevel.GameMaster && from.m_AccessLevel > m_AccessLevel; - } + public virtual bool CanBeRenamedBy(Mobile from) => from.AccessLevel >= AccessLevel.GameMaster && from.m_AccessLevel > m_AccessLevel; public virtual void OnGuildTitleChange(string oldTitle) { @@ -6697,17 +6026,9 @@ namespace Server return delta != 0 ? body : 0; } - public virtual void FreeCache() - { - StaticPacketHandlers.FreeRemoveItemPacket(this); - StaticPacketHandlers.FreeOPLInfoPacket(this); - StaticPacketHandlers.FreeOPLPacket(this); - } - public void ClearProperties() { - StaticPacketHandlers.FreeOPLPacket(this); - StaticPacketHandlers.FreeOPLInfoPacket(this); + m_PropertyList = null; } public void InvalidateProperties() @@ -6717,18 +6038,14 @@ namespace Server if (m_Map != null && m_Map != Map.Internal && !World.Loading) { - ObjectPropertyList oldList = StaticPacketHandlers.FreeOPLPacket(this); + ObjectPropertyList oldList = m_PropertyList; + ClearProperties(); if (oldList?.Hash != PropertyList.Hash) - { - StaticPacketHandlers.FreeOPLInfoPacket(this); Delta(MobileDelta.Properties); - } } else - { ClearProperties(); - } } public virtual void SetLocation(Point3D newLocation, bool isTeleport) @@ -6757,10 +6074,7 @@ namespace Server { m_NetState.Sequence = 0; - if (m_NetState.StygianAbyss) - m_NetState.Send(new MobileUpdate(this)); - else - m_NetState.Send(new MobileUpdateOld(this)); + Packets.SendMobileUpdate(m_NetState, this); ClearFastwalkStack(); } @@ -6775,7 +6089,7 @@ namespace Server foreach (NetState ns in eable) if (ns != m_NetState && !Utility.InUpdateRange(newLocation, ns.Mobile.Location)) - ns.Send(RemovePacket); + Packets.SendRemoveEntity(ns, Serial); eable.Free(); @@ -6805,44 +6119,40 @@ namespace Server bool inOldRange = Utility.InUpdateRange(oldLocation, m.m_Location); - if (m.m_NetState != null && + if (m.NetState != null && (isTeleport && (!m.m_NetState.HighSeas || !NoMoveHS) || !inOldRange) && m.CanSee(this)) { - m.m_NetState.Send(MobileIncoming.Create(m.m_NetState, m, this)); + Packets.SendMobileIncoming(m.m_NetState, m, this); if (m.m_NetState.StygianAbyss) { - //if ( m_Poison != null ) - m.m_NetState.Send(new HealthbarPoison(this)); - - //if ( m_Blessed || m_YellowHealthbar ) - m.m_NetState.Send(new HealthbarYellow(this)); + Packets.SendHealthbarPoison(m.m_NetState, this); + Packets.SendHealthbarYellow(m.m_NetState, this); } if (IsDeadBondedPet) - m.m_NetState.Send(new BondedStatus(0, Serial, 1)); + Packets.SendBondStatus(NetState, Serial, true); - if (ObjectPropertyList.Enabled) m.m_NetState.Send(OPLPacket); + if (ObjectPropertyList.Enabled) + PropertyList.Send(m.NetState); } if (inOldRange || !CanSee(m)) continue; - ourState.Send(MobileIncoming.Create(ourState, this, m)); + Packets.SendMobileIncoming(ourState, this, m); if (ourState.StygianAbyss) { - //if ( m.Poisoned ) - ourState.Send(new HealthbarPoison(m)); - - //if ( m.Blessed || m.YellowHealthbar ) - ourState.Send(new HealthbarYellow(m)); + Packets.SendHealthbarPoison(ourState, m); + Packets.SendHealthbarYellow(ourState, m); } if (m.IsDeadBondedPet) - ourState.Send(new BondedStatus(0, m.Serial, 1)); + Packets.SendBondStatus(ourState, Serial, true); - if (ObjectPropertyList.Enabled) ourState.Send(m.OPLPacket); + if (ObjectPropertyList.Enabled) + m.PropertyList.Send(ourState); } eeable.Free(); @@ -6856,21 +6166,19 @@ namespace Server if ((isTeleport && (!ns.HighSeas || !NoMoveHS) || !Utility.InUpdateRange(oldLocation, ns.Mobile.Location)) && ns.Mobile.CanSee(this)) { - ns.Send(MobileIncoming.Create(ns, ns.Mobile, this)); + Packets.SendMobileIncoming(ns, ns.Mobile, this); if (ns.StygianAbyss) { - //if ( m_Poison != null ) - ns.Send(new HealthbarPoison(this)); - - //if ( m_Blessed || m_YellowHealthbar ) - ns.Send(new HealthbarYellow(this)); + Packets.SendHealthbarPoison(ns, this); + Packets.SendHealthbarYellow(ns, this); } if (IsDeadBondedPet) - ns.Send(new BondedStatus(0, Serial, 1)); + Packets.SendBondStatus(ns, Serial, true); - if (ObjectPropertyList.Enabled) ns.Send(OPLPacket); + if (ObjectPropertyList.Enabled) + PropertyList.Send(ns); } eable.Free(); @@ -6889,15 +6197,9 @@ namespace Server { } - public bool HasFreeHand() - { - return FindItemOnLayer(Layer.TwoHanded) == null; - } + public bool HasFreeHand() => FindItemOnLayer(Layer.TwoHanded) == null; - public virtual IWeapon GetDefaultWeapon() - { - return DefaultWeapon; - } + public virtual IWeapon GetDefaultWeapon() => DefaultWeapon; public BankBox FindBankNoCreate() { @@ -6932,72 +6234,58 @@ namespace Server foreach (NetState state in eable) if (state.Mobile.CanSee(this)) { - state.Send(MobileIncoming.Create(state, state.Mobile, this)); + Packets.SendMobileIncoming(state, state.Mobile, this); if (state.StygianAbyss) { if (m_Poison != null) - state.Send(new HealthbarPoison(this)); + Packets.SendHealthbarPoison(state, this); if (m_Blessed || m_YellowHealthbar) - state.Send(new HealthbarYellow(this)); + Packets.SendHealthbarYellow(state, this); } if (IsDeadBondedPet) - state.Send(new BondedStatus(0, Serial, 1)); + Packets.SendBondStatus(state, Serial, true); - if (ObjectPropertyList.Enabled) state.Send(OPLPacket); + if (ObjectPropertyList.Enabled) + PropertyList.Send(state); } eable.Free(); } - public bool PlaceInBackpack(Item item) - { - if (item.Deleted) - return false; - - return Backpack?.TryDropItem(this, item, false) == true; - } + public bool PlaceInBackpack(Item item) => + !item.Deleted && Backpack?.TryDropItem(this, item, false) == true; public bool AddToBackpack(Item item) { if (item.Deleted) return false; - if (!PlaceInBackpack(item)) + if (PlaceInBackpack(item)) + return true; + + Point3D loc = m_Location; + Map map = m_Map; + + if ((map == null || map == Map.Internal) && LogoutMap != null) { - Point3D loc = m_Location; - Map map = m_Map; - - if ((map == null || map == Map.Internal) && LogoutMap != null) - { - loc = LogoutLocation; - map = LogoutMap; - } - - item.MoveToWorld(loc, map); - return false; + loc = LogoutLocation; + map = LogoutMap; } - return true; + item.MoveToWorld(loc, map); + return false; } - public virtual bool CheckLift(Mobile from, Item item, ref LRReason reject) - { - return true; - } + public virtual bool CheckLift(Mobile from, Item item, ref LRReason reject) => true; - public virtual bool CheckNonlocalLift(Mobile from, Item item) - { - return from == this || from.AccessLevel > AccessLevel && from.AccessLevel >= AccessLevel.GameMaster; - } + public virtual bool CheckNonlocalLift(Mobile from, Item item) => + from == this || from.AccessLevel > AccessLevel && from.AccessLevel >= AccessLevel.GameMaster; public virtual bool CheckTrade(Mobile to, Item item, SecureTradeContainer cont, bool message, bool checkItems, - int plusItems, int plusWeight) - { - return true; - } + int plusItems, int plusWeight) => true; public virtual bool OpenTrade(Mobile from, Item offer = null) { @@ -7012,7 +6300,7 @@ namespace Server if (!from.CheckTrade(this, offer, cont, true, true, 0, 0)) return false; - if (cont == null) cont = theirState.AddTrade(ourState); + cont ??= theirState.AddTrade(ourState); if (offer != null) cont.DropItem(offer); @@ -7153,15 +6441,10 @@ namespace Server { } - public virtual bool CheckNonlocalDrop(Mobile from, Item item, Item target) - { - return from == this || from.AccessLevel > AccessLevel && from.AccessLevel >= AccessLevel.GameMaster; - } + public virtual bool CheckNonlocalDrop(Mobile from, Item item, Item target) => + from == this || from.AccessLevel > AccessLevel && from.AccessLevel >= AccessLevel.GameMaster; - public virtual bool CheckItemUse(Mobile from, Item item) - { - return true; - } + public virtual bool CheckItemUse(Mobile from, Item item) => true; /// /// Overridable. Virtual event invoked when successfully lifts from this @@ -7172,15 +6455,9 @@ namespace Server { } - public virtual bool AllowItemUse(Item item) - { - return true; - } + public virtual bool AllowItemUse(Item item) => true; - public virtual bool AllowEquipFrom(Mobile mob) - { - return mob == this || mob.AccessLevel >= AccessLevel.GameMaster && mob.AccessLevel > AccessLevel; - } + public virtual bool AllowEquipFrom(Mobile mob) => mob == this || mob.AccessLevel >= AccessLevel.GameMaster && mob.AccessLevel > AccessLevel; public virtual bool EquipItem(Item item) { @@ -7234,24 +6511,21 @@ namespace Server m_InDeltaQueue = true; if (_processing) - lock (m_DeltaQueueR) - { - m_DeltaQueueR.Enqueue(this); + { + m_DeltaQueueR.Enqueue(this); - try - { - using (StreamWriter op = new StreamWriter("delta-recursion.log", true)) - { - op.WriteLine("# {0}", DateTime.UtcNow); - op.WriteLine(new StackTrace()); - op.WriteLine(); - } - } - catch - { - // ignored - } + try + { + using StreamWriter op = new StreamWriter("delta-recursion.log", true); + op.WriteLine("# {0}", DateTime.UtcNow); + op.WriteLine(new StackTrace()); + op.WriteLine(); } + catch + { + // ignored + } + } else m_DeltaQueue.Enqueue(this); } @@ -7265,19 +6539,26 @@ namespace Server if (m_DeltaQueue.Count >= 512) { - Parallel.ForEach(m_DeltaQueue, m => m.ProcessDelta()); - m_DeltaQueue.Clear(); + ConcurrentQueue queue = new ConcurrentQueue(); + queue = Interlocked.Exchange(ref m_DeltaQueue, queue); + do + { + Parallel.For(0, queue.Count, + _ => + { + if (queue.TryDequeue(out Mobile m)) + m.ProcessDelta(); + }); + } while (queue.Count > 0); } else - { - while (m_DeltaQueue.Count > 0) - m_DeltaQueue.Dequeue().ProcessDelta(); - } + while (m_DeltaQueue.TryDequeue(out Mobile m)) + m.ProcessDelta(); _processing = false; - while (m_DeltaQueueR.Count > 0) - m_DeltaQueueR.Dequeue().ProcessDelta(); + while (m_DeltaQueueR.TryDequeue(out Mobile m)) + m.ProcessDelta(); } public virtual void OnKillsChange(int oldValue) @@ -7334,10 +6615,10 @@ namespace Server public virtual void OnStatsQuery(Mobile from) { if (from.Map == Map && Utility.InUpdateRange(this, from) && from.CanSee(this)) - from.Send(new MobileStatus(from, this, m_NetState)); + Packets.SendMobileStatus(from.NetState, from, this, m_NetState); if (from == this) - Send(new StatLockInfo(this)); + Packets.SendStatLockInfo(m_NetState, this); if (Party is IParty ip) ip.OnStatsQuery(from, this); @@ -7349,7 +6630,7 @@ namespace Server public virtual void OnSkillsQuery(Mobile from) { if (from == this) - Send(new SkillUpdate(Skills)); + Packets.SendSkillsUpdate(m_NetState, Skills); } /// @@ -7374,14 +6655,9 @@ namespace Server if (guild != null && (m_DisplayGuildTitle || m_Player && guild.Type != GuildType.Regular)) { - string title = GuildTitle; + string title = GuildTitle?.Trim() ?? ""; string type; - if (title == null) - title = ""; - else - title = title.Trim(); - if (guild.Type >= 0 && (int)guild.Type < m_GuildTypes.Length) type = m_GuildTypes[(int)guild.Type]; else @@ -7420,36 +6696,28 @@ namespace Server string val; if (prefix.Length > 0 && suffix.Length > 0) - val = string.Concat(prefix, " ", name, " ", suffix); + val = $"{prefix} {name} {suffix}"; else if (prefix.Length > 0) - val = string.Concat(prefix, " ", name); + val = $"{prefix} {name}"; else if (suffix.Length > 0) - val = string.Concat(name, " ", suffix); + val = $"{name} {suffix}"; else val = name; PrivateOverheadMessage(MessageType.Label, hue, AsciiClickMessage, val, from.NetState); } - public bool CheckSkill(SkillName skill, double minSkill, double maxSkill) - { - return SkillCheckLocationHandler?.Invoke(this, skill, minSkill, maxSkill) == true; - } + public bool CheckSkill(SkillName skill, double minSkill, double maxSkill) => + SkillCheckLocationHandler?.Invoke(this, skill, minSkill, maxSkill) == true; - public bool CheckSkill(SkillName skill, double chance) - { - return SkillCheckDirectLocationHandler?.Invoke(this, skill, chance) == true; - } + public bool CheckSkill(SkillName skill, double chance) => + SkillCheckDirectLocationHandler?.Invoke(this, skill, chance) == true; - public bool CheckTargetSkill(SkillName skill, object target, double minSkill, double maxSkill) - { - return SkillCheckTargetHandler?.Invoke(this, skill, target, minSkill, maxSkill) == true; - } + public bool CheckTargetSkill(SkillName skill, object target, double minSkill, double maxSkill) => + SkillCheckTargetHandler?.Invoke(this, skill, target, minSkill, maxSkill) == true; - public bool CheckTargetSkill(SkillName skill, object target, double chance) - { - return SkillCheckDirectTargetHandler?.Invoke(this, skill, target, chance) == true; - } + public bool CheckTargetSkill(SkillName skill, object target, double chance) => + SkillCheckDirectTargetHandler?.Invoke(this, skill, target, chance) == true; public virtual void DisruptiveAction() { @@ -7479,10 +6747,7 @@ namespace Server private static Queue m_InstancePool = new Queue(); public long m_End; - private MovementRecord(long end) - { - m_End = end; - } + private MovementRecord(long end) => m_End = end; public static MovementRecord NewInstance(long end) { @@ -7540,10 +6805,8 @@ namespace Server private TargetCallback m_Callback; public SimpleTarget(int range, TargetFlags flags, bool allowGround, TargetCallback callback) - : base(range, allowGround, flags) - { + : base(range, allowGround, flags) => m_Callback = callback; - } protected override void OnTarget(Mobile from, object targeted) { @@ -7575,10 +6838,8 @@ namespace Server private Mobile m_Mobile; public AutoManifestTimer(Mobile m, TimeSpan delay) - : base(delay) - { + : base(delay) => m_Mobile = m; - } protected override void OnTick() { @@ -7591,17 +6852,11 @@ namespace Server { private static LocationComparer m_Instance; - public LocationComparer(IEntity relativeTo) - { - RelativeTo = relativeTo; - } + public LocationComparer(IEntity relativeTo) => RelativeTo = relativeTo; public IEntity RelativeTo{ get; set; } - public int Compare(IEntity x, IEntity y) - { - return GetDistance(x) - GetDistance(y); - } + public int Compare(IEntity x, IEntity y) => GetDistance(x) - GetDistance(y); public static LocationComparer GetInstance(IEntity relativeTo) { @@ -7626,15 +6881,9 @@ namespace Server } } - int IComparable.CompareTo(IEntity other) - { - return other == null ? -1 : Serial.CompareTo(other.Serial); - } + int IComparable.CompareTo(IEntity other) => other == null ? -1 : Serial.CompareTo(other.Serial); - public int CompareTo(Mobile other) - { - return other == null ? -1 : Serial.CompareTo(other.Serial); - } + public int CompareTo(Mobile other) => other == null ? -1 : Serial.CompareTo(other.Serial); #region Handlers @@ -8002,9 +7251,7 @@ namespace Server if (m_CallbackHandlesCancel && m_Callback != null) m_Callback(from, ""); else - { m_CancelCallback?.Invoke(from, ""); - } } } @@ -8064,10 +7311,7 @@ namespace Server return Prompt = new SimpleStatePrompt(callback, callbackHandlesCancel, state); } - public Prompt BeginPrompt(PromptStateCallback callback, T state) - { - return BeginPrompt(callback, false, state); - } + public Prompt BeginPrompt(PromptStateCallback callback, T state) => BeginPrompt(callback, false, state); public Prompt Prompt { @@ -8088,14 +7332,12 @@ namespace Server m_Prompt = newPrompt; if (newPrompt != null) - Send(new UnicodePrompt(newPrompt)); + Packets.SendUnicodePrompt(m_NetState, newPrompt.Serial); } } - #endregion #region Get*Sound - public virtual int GetAngerSound() { if (BaseSoundID != 0) @@ -8135,65 +7377,27 @@ namespace Server if (m_Body.IsHuman) return Utility.Random(m_Female ? 0x314 : 0x423, m_Female ? 4 : 5); return -1; } - #endregion #region Get*InRange + public IPooledEnumerable GetItemsInRange(int range) => GetItemsInRange(range); - public IPooledEnumerable GetItemsInRange(int range) - { - return GetItemsInRange(range); - } + public IPooledEnumerable GetItemsInRange(int range) where T : Item => + m_Map?.GetItemsInRange(m_Location, range) ?? Map.NullEnumerable.Instance; - public IPooledEnumerable GetItemsInRange(int range) where T : Item - { - Map map = m_Map; + public IPooledEnumerable GetObjectsInRange(int range) => + m_Map?.GetObjectsInRange(m_Location, range) ?? Map.NullEnumerable.Instance; - if (map == null) - return Map.NullEnumerable.Instance; + public IPooledEnumerable GetMobilesInRange(int range) => GetMobilesInRange(range); - return map.GetItemsInRange(m_Location, range); - } - - public IPooledEnumerable GetObjectsInRange(int range) - { - Map map = m_Map; - - if (map == null) - return Map.NullEnumerable.Instance; - - return map.GetObjectsInRange(m_Location, range); - } - - public IPooledEnumerable GetMobilesInRange(int range) - { - return GetMobilesInRange(range); - } - - public IPooledEnumerable GetMobilesInRange(int range) where T : Mobile - { - Map map = m_Map; - - if (map == null) - return Map.NullEnumerable.Instance; - - return map.GetMobilesInRange(m_Location, range); - } - - public IPooledEnumerable GetClientsInRange(int range) - { - Map map = m_Map; - - if (map == null) - return Map.NullEnumerable.Instance; - - return map.GetClientsInRange(m_Location, range); - } + public IPooledEnumerable GetMobilesInRange(int range) where T : Mobile => + m_Map?.GetMobilesInRange(m_Location, range) ?? Map.NullEnumerable.Instance; + public IPooledEnumerable GetClientsInRange(int range) => + m_Map.GetClientsInRange(m_Location, range) ?? Map.NullEnumerable.Instance; #endregion #region Say/SayTo/Emote/Whisper/Yell - public void SayTo(Mobile to, bool ascii, string text) { PrivateOverheadMessage(MessageType.Regular, SpeechHue, ascii, text, to.NetState); @@ -8216,12 +7420,12 @@ namespace Server public void SayTo(Mobile to, int number) { - to.Send(new MessageLocalized(Serial, Body, MessageType.Regular, SpeechHue, 3, number, Name, "")); + Packets.SendMessageLocalized(to?.NetState, Serial, Body, MessageType.Regular, SpeechHue, 3, number, Name); } public void SayTo(Mobile to, int number, string args) { - to.Send(new MessageLocalized(Serial, Body, MessageType.Regular, SpeechHue, 3, number, Name, args)); + Packets.SendMessageLocalized(to?.NetState, Serial, Body, MessageType.Regular, SpeechHue, 3, number, Name, args); } public void Say(bool ascii, string text) @@ -8293,28 +7497,16 @@ namespace Server { PublicOverheadMessage(MessageType.Yell, YellHue, number, args); } - #endregion #region Gumps/Menus - - public bool SendHuePicker(HuePicker p, bool throwOnOffline = false) + public void SendHuePicker(HuePicker p) { if (m_NetState != null) - { p.SendTo(m_NetState); - return true; - } - - if (throwOnOffline) throw new MobileNotConnectedException(this, "Hue picker could not be sent."); - - return false; } - public Gump FindGump() where T : Gump - { - return m_NetState?.Gumps.Find(g => g is T); - } + public Gump FindGump() where T : Gump => m_NetState?.Gumps.Find(g => g is T); public bool CloseGump() where T : Gump { @@ -8325,8 +7517,7 @@ namespace Server if (gump != null) { - // TODO: Recycle CloseGump - m_NetState.Send(new CloseGump(gump.TypeID, 0)); + Packets.SendCloseGump(m_NetState, gump.TypeID, 0); m_NetState.RemoveGump(gump); gump.OnServerClose(m_NetState); } @@ -8347,18 +7538,14 @@ namespace Server foreach (Gump gump in gumps) { - ns.Send(new CloseGump(gump.TypeID, 0)); - + Packets.SendCloseGump(ns, gump.TypeID, 0); gump.OnServerClose(ns); } return true; } - public bool HasGump() where T : Gump - { - return FindGump() != null; - } + public bool HasGump() where T : Gump => FindGump() != null; public bool SendGump(Gump g) { @@ -8382,15 +7569,9 @@ namespace Server #region Beneficial Checks/Actions - public virtual bool CanBeBeneficial(Mobile target) - { - return CanBeBeneficial(target, true, false); - } + public virtual bool CanBeBeneficial(Mobile target) => CanBeBeneficial(target, true, false); - public virtual bool CanBeBeneficial(Mobile target, bool message) - { - return CanBeBeneficial(target, message, false); - } + public virtual bool CanBeBeneficial(Mobile target, bool message) => CanBeBeneficial(target, message, false); public virtual bool CanBeBeneficial(Mobile target, bool message, bool allowDead) { @@ -8469,15 +7650,9 @@ namespace Server #region Harmful Checks/Actions - public virtual bool CanBeHarmful(Mobile target) - { - return CanBeHarmful(target, true); - } + public virtual bool CanBeHarmful(Mobile target) => CanBeHarmful(target, true); - public virtual bool CanBeHarmful(Mobile target, bool message) - { - return CanBeHarmful(target, message, false); - } + public virtual bool CanBeHarmful(Mobile target, bool message) => CanBeHarmful(target, message, false); public virtual bool CanBeHarmful(Mobile target, bool message, bool ignoreOurBlessedness) { @@ -8735,15 +7910,10 @@ namespace Server if (Hits < HitsMax) { - if (m_HitsTimer == null) - m_HitsTimer = new HitsTimer(this); - + m_HitsTimer ??= new HitsTimer(this); m_HitsTimer.Start(); } - else if (Hits > HitsMax) - { - Hits = HitsMax; - } + else if (Hits > HitsMax) Hits = HitsMax; OnRawStrChange(oldValue); OnRawStatChange(StatType.Str, oldValue); @@ -8806,15 +7976,11 @@ namespace Server if (Stam < StamMax) { - if (m_StamTimer == null) - m_StamTimer = new StamTimer(this); - + m_StamTimer ??= new StamTimer(this); m_StamTimer.Start(); } else if (Stam > StamMax) - { Stam = StamMax; - } OnRawDexChange(oldValue); OnRawStatChange(StatType.Dex, oldValue); @@ -8877,15 +8043,11 @@ namespace Server if (Mana < ManaMax) { - if (m_ManaTimer == null) - m_ManaTimer = new ManaTimer(this); - + m_ManaTimer ??= new ManaTimer(this); m_ManaTimer.Start(); } else if (Mana > ManaMax) - { Mana = ManaMax; - } OnRawIntChange(oldValue); OnRawStatChange(StatType.Int, oldValue); @@ -8968,15 +8130,11 @@ namespace Server { if (CanRegenHits) { - if (m_HitsTimer == null) - m_HitsTimer = new HitsTimer(this); - + m_HitsTimer ??= new HitsTimer(this); m_HitsTimer.Start(); } else - { m_HitsTimer?.Stop(); - } } if (m_Hits != value) @@ -9008,9 +8166,7 @@ namespace Server return; if (value < 0) - { value = 0; - } else if (value >= StamMax) { value = StamMax; @@ -9022,15 +8178,11 @@ namespace Server { if (CanRegenStam) { - if (m_StamTimer == null) - m_StamTimer = new StamTimer(this); - + m_StamTimer ??= new StamTimer(this); m_StamTimer.Start(); } else - { m_StamTimer?.Stop(); - } } if (m_Stam != value) @@ -9085,15 +8237,11 @@ namespace Server { if (CanRegenMana) { - if (m_ManaTimer == null) - m_ManaTimer = new ManaTimer(this); - + m_ManaTimer ??= new ManaTimer(this); m_ManaTimer.Start(); } else - { m_ManaTimer?.Stop(); - } } if (m_Mana != value) @@ -9127,8 +8275,6 @@ namespace Server get => m_Poison; set { - /*if ( m_Poison != value && (m_Poison == null || value == null || m_Poison.Level < value.Level) ) - {*/ m_Poison = value; Delta(MobileDelta.HealthbarPoison); @@ -9146,7 +8292,6 @@ namespace Server } CheckStatTimers(); - /*}*/ } } @@ -9342,20 +8487,14 @@ namespace Server [CommandProperty(AccessLevel.GameMaster)] public int HairItemID { - get - { - if (m_Hair == null) - return 0; - - return m_Hair.ItemID; - } + get => m_Hair?.ItemID ?? 0; set { if (m_Hair == null && value > 0) m_Hair = new HairInfo(value); else if (value <= 0) m_Hair = null; - else + else if (m_Hair != null) m_Hair.ItemID = value; Delta(MobileDelta.Hair); @@ -9368,20 +8507,14 @@ namespace Server [CommandProperty(AccessLevel.GameMaster)] public int FacialHairItemID { - get - { - if (m_FacialHair == null) - return 0; - - return m_FacialHair.ItemID; - } + get => m_FacialHair?.ItemID ?? 0; set { if (m_FacialHair == null && value > 0) m_FacialHair = new FacialHairInfo(value); else if (value <= 0) m_FacialHair = null; - else + else if (m_FacialHair != null) m_FacialHair.ItemID = value; Delta(MobileDelta.FacialHair); @@ -9394,12 +8527,7 @@ namespace Server [CommandProperty(AccessLevel.GameMaster)] public int HairHue { - get - { - if (m_Hair == null) - return 0; - return m_Hair.Hue; - } + get => m_Hair?.Hue ?? 0; set { if (m_Hair != null) @@ -9413,13 +8541,7 @@ namespace Server [CommandProperty(AccessLevel.GameMaster)] public int FacialHairHue { - get - { - if (m_FacialHair == null) - return 0; - - return m_FacialHair.Hue; - } + get => m_FacialHair?.Hue ?? 0; set { if (m_FacialHair != null) @@ -9480,7 +8602,7 @@ namespace Server public void FixedEffect(int itemID, int speed, int duration) { - Effects.SendTargetEffect(this, itemID, speed, duration, 0, 0); + Effects.SendTargetEffect(this, itemID, speed, duration); } public void FixedParticles(int itemID, int speed, int duration, int effect, int hue, int renderMode, @@ -9505,9 +8627,9 @@ namespace Server Effects.SendTargetParticles(this, itemID, speed, duration, 0, 0, effect, layer, 0); } - public void BoltEffect(int hue) + public void BoltEffect() { - Effects.SendBoltEffect(this, true, hue); + Effects.SendBoltEffect(this); } #endregion @@ -9543,23 +8665,11 @@ namespace Server return ret; } - public Direction GetDirectionTo(Point2D p) - { - return GetDirectionTo(p.m_X, p.m_Y); - } + public Direction GetDirectionTo(Point2D p) => GetDirectionTo(p.m_X, p.m_Y); - public Direction GetDirectionTo(Point3D p) - { - return GetDirectionTo(p.m_X, p.m_Y); - } + public Direction GetDirectionTo(Point3D p) => GetDirectionTo(p.m_X, p.m_Y); - public Direction GetDirectionTo(IPoint2D p) - { - if (p == null) - return Direction.North; - - return GetDirectionTo(p.X, p.Y); - } + public Direction GetDirectionTo(IPoint2D p) => p == null ? Direction.North : GetDirectionTo(p.X, p.Y); #endregion @@ -9570,19 +8680,16 @@ namespace Server if (m_Map == null) return; - Packet p = ascii - ? (Packet)new AsciiMessage(Serial, Body, type, hue, 3, Name, text) - : new UnicodeMessage(Serial, Body, type, hue, 3, m_Language, Name, text); - - p.Acquire(); - IPooledEnumerable eable = m_Map.GetClientsInRange(m_Location); foreach (NetState state in eable) if (state.Mobile.CanSee(this) && (noLineOfSight || state.Mobile.InLOS(this))) - state.Send(p); - - Packet.Release(p); + { + if (ascii) + Packets.SendAsciiMessage(state, Serial, Body, type, hue, 3, Name, text); + else + Packets.SendUnicodeMessage(state, Serial, Body, type, hue, 3, Language, Name, text); + } eable.Free(); } @@ -9592,15 +8699,11 @@ namespace Server if (m_Map == null) return; - Packet p = Packet.Acquire(new MessageLocalized(Serial, Body, type, hue, 3, number, Name, args)); - IPooledEnumerable eable = m_Map.GetClientsInRange(m_Location); foreach (NetState state in eable) if (state.Mobile.CanSee(this) && (noLineOfSight || state.Mobile.InLOS(this))) - state.Send(p); - - Packet.Release(p); + Packets.SendMessageLocalized(state, Serial, Body, type, hue, 3, number, Name, args); eable.Free(); } @@ -9611,16 +8714,12 @@ namespace Server if (m_Map == null) return; - Packet p = Packet.Acquire(new MessageLocalizedAffix(Serial, Body, type, hue, 3, number, Name, affixType, - affix, args)); - IPooledEnumerable eable = m_Map.GetClientsInRange(m_Location); foreach (NetState state in eable) if (state.Mobile.CanSee(this) && (noLineOfSight || state.Mobile.InLOS(this))) - state.Send(p); - - Packet.Release(p); + Packets.SendMessageLocalizedAffix(state, Serial, Body, type, hue, 3, number, Name, affixType, + affix, args); eable.Free(); } @@ -9631,9 +8730,9 @@ namespace Server return; if (ascii) - state.Send(new AsciiMessage(Serial, Body, type, hue, 3, Name, text)); + Packets.SendAsciiMessage(state, Serial, Body, type, hue, 3, Name, text); else - state.Send(new UnicodeMessage(Serial, Body, type, hue, 3, m_Language, Name, text)); + Packets.SendUnicodeMessage(state, Serial, Body, type, hue, 3, Language, Name, text); } public void PrivateOverheadMessage(MessageType type, int hue, int number, NetState state) @@ -9643,25 +8742,23 @@ namespace Server public void PrivateOverheadMessage(MessageType type, int hue, int number, string args, NetState state) { - state?.Send(new MessageLocalized(Serial, Body, type, hue, 3, number, Name, args)); + Packets.SendMessageLocalized(state, Serial, Body, type, hue, 3, number, Name, args); } public void LocalOverheadMessage(MessageType type, int hue, bool ascii, string text) { - NetState ns = m_NetState; - - if (ns == null) + if (m_NetState == null) return; if (ascii) - ns.Send(new AsciiMessage(Serial, Body, type, hue, 3, Name, text)); + Packets.SendAsciiMessage(m_NetState, Serial, Body, type, hue, 3, Name, text); else - ns.Send(new UnicodeMessage(Serial, Body, type, hue, 3, m_Language, Name, text)); + Packets.SendUnicodeMessage(m_NetState, Serial, Body, type, hue, 3, Language, Name, text); } public void LocalOverheadMessage(MessageType type, int hue, int number, string args = "") { - m_NetState?.Send(new MessageLocalized(Serial, Body, type, hue, 3, number, Name, args)); + Packets.SendMessageLocalized(m_NetState, Serial, Body, type, hue, 3, number, Name, args); } public void NonlocalOverheadMessage(MessageType type, int hue, int number, string args = "") @@ -9669,15 +8766,11 @@ namespace Server if (m_Map == null) return; - Packet p = Packet.Acquire(new MessageLocalized(Serial, Body, type, hue, 3, number, Name, args)); - IPooledEnumerable eable = m_Map.GetClientsInRange(m_Location); foreach (NetState state in eable) if (state != m_NetState && state.Mobile.CanSee(this)) - state.Send(p); - - Packet.Release(p); + Packets.SendMessageLocalized(state, Serial, Body, type, hue, 3, number, Name, args); eable.Free(); } @@ -9687,19 +8780,16 @@ namespace Server if (m_Map == null) return; - Packet p = ascii - ? (Packet)new AsciiMessage(Serial, Body, type, hue, 3, Name, text) - : new UnicodeMessage(Serial, Body, type, hue, 3, Language, Name, text); - - p.Acquire(); - IPooledEnumerable eable = m_Map.GetClientsInRange(m_Location); foreach (NetState state in eable) if (state != m_NetState && state.Mobile.CanSee(this)) - state.Send(p); - - Packet.Release(p); + { + if (ascii) + Packets.SendAsciiMessage(state, Serial, Body, type, hue, 3, Name, text); + else + Packets.SendUnicodeMessage(state, Serial, Body, type, hue, 3, Language, Name, text); + } eable.Free(); } @@ -9708,29 +8798,22 @@ namespace Server #region SendLocalizedMessage - public void SendLocalizedMessage(int number) - { - m_NetState?.Send(MessageLocalized.InstantiateGeneric(number)); - } - - public void SendLocalizedMessage(int number, string args, int hue = 0x3B2) + public void SendLocalizedMessage(int number, string args = "", int hue = 0x3B2) { if (hue == 0x3B2 && string.IsNullOrEmpty(args)) - m_NetState?.Send(MessageLocalized.InstantiateGeneric(number)); + Packets.SendMessageLocalized(m_NetState, number); else - m_NetState?.Send(new MessageLocalized(Serial.MinusOne, -1, MessageType.Regular, hue, 3, number, "System", args)); + Packets.SendMessageLocalized(m_NetState, Serial.MinusOne, -1, MessageType.Regular, hue, 3, number, "System", args); } public void SendLocalizedMessage(int number, bool append, string affix, string args = "", int hue = 0x3B2) { - m_NetState?.Send(new MessageLocalizedAffix(Serial.MinusOne, -1, MessageType.Regular, hue, 3, number, "System", - (append ? AffixType.Append : AffixType.Prepend) | AffixType.System, affix, args)); + Packets.SendMessageLocalizedAffix(m_NetState, Serial.MinusOne, -1, MessageType.Regular, hue, 3, number, "System", + (append ? AffixType.Append : AffixType.Prepend) | AffixType.System, affix, args); } - #endregion #region Send[ASCII]Message - public void SendMessage(string text) { SendMessage(0x3B2, text); @@ -9743,7 +8826,7 @@ namespace Server public void SendMessage(int hue, string text) { - m_NetState?.Send(new UnicodeMessage(Serial.MinusOne, -1, MessageType.Regular, hue, 3, "ENU", "System", text)); + Packets.SendUnicodeMessage(m_NetState, Serial.MinusOne, -1, MessageType.Regular, hue, 3, "ENU", "System", text); } public void SendMessage(int hue, string format, params object[] args) @@ -9763,46 +8846,36 @@ namespace Server public void SendAsciiMessage(int hue, string text) { - m_NetState?.Send(new AsciiMessage(Serial.MinusOne, -1, MessageType.Regular, hue, 3, "System", text)); + Packets.SendAsciiMessage(m_NetState, Serial.MinusOne, -1, MessageType.Regular, hue, 3, "System", text); } public void SendAsciiMessage(int hue, string format, params object[] args) { SendAsciiMessage(hue, string.Format(format, args)); } - #endregion #region InRange + public bool InRange(Point2D p, int range) => + p.m_X >= m_Location.m_X - range + && p.m_X <= m_Location.m_X + range + && p.m_Y >= m_Location.m_Y - range + && p.m_Y <= m_Location.m_Y + range; - public bool InRange(Point2D p, int range) - { - return p.m_X >= m_Location.m_X - range - && p.m_X <= m_Location.m_X + range - && p.m_Y >= m_Location.m_Y - range - && p.m_Y <= m_Location.m_Y + range; - } - - public bool InRange(Point3D p, int range) - { - return p.m_X >= m_Location.m_X - range - && p.m_X <= m_Location.m_X + range - && p.m_Y >= m_Location.m_Y - range - && p.m_Y <= m_Location.m_Y + range; - } - - public bool InRange(IPoint2D p, int range) - { - return p.X >= m_Location.m_X - range - && p.X <= m_Location.m_X + range - && p.Y >= m_Location.m_Y - range - && p.Y <= m_Location.m_Y + range; - } + public bool InRange(Point3D p, int range) => + p.m_X >= m_Location.m_X - range + && p.m_X <= m_Location.m_X + range + && p.m_Y >= m_Location.m_Y - range + && p.m_Y <= m_Location.m_Y + range; + public bool InRange(IPoint2D p, int range) => + p.X >= m_Location.m_X - range + && p.X <= m_Location.m_X + range + && p.Y >= m_Location.m_Y - range + && p.Y <= m_Location.m_Y + range; #endregion #region OnDoubleClick[..] - /// /// Overridable. Event invoked when the Mobile is double clicked. By default, this method can either dismount or open the /// paperdoll. @@ -9854,45 +8927,17 @@ namespace Server if (CanPaperdollBeOpenedBy(from)) DisplayPaperdollTo(from); } - #endregion #region Armor - public Item ShieldArmor => FindItemOnLayer(Layer.TwoHanded); - public Item NeckArmor => FindItemOnLayer(Layer.Neck); - public Item HandArmor => FindItemOnLayer(Layer.Gloves); - public Item HeadArmor => FindItemOnLayer(Layer.Helm); - public Item ArmsArmor => FindItemOnLayer(Layer.Arms); - - public Item LegsArmor - { - get - { - if (!(FindItemOnLayer(Layer.InnerLegs) is Item ar)) - ar = FindItemOnLayer(Layer.Pants); - - return ar; - } - } - - public Item ChestArmor - { - get - { - if (!(FindItemOnLayer(Layer.InnerTorso) is Item ar)) - ar = FindItemOnLayer(Layer.Shirt); - - return ar; - } - } - + public Item LegsArmor => FindItemOnLayer(Layer.InnerLegs) ?? FindItemOnLayer(Layer.Pants); + public Item ChestArmor => FindItemOnLayer(Layer.InnerTorso) ?? FindItemOnLayer(Layer.Shirt); public Item Talisman => FindItemOnLayer(Layer.Talisman); - #endregion } } diff --git a/Projects/Server/Movement.cs b/Projects/Server/Movement.cs index 6544f6767..4d2748ffc 100644 --- a/Projects/Server/Movement.cs +++ b/Projects/Server/Movement.cs @@ -18,7 +18,7 @@ * ***************************************************************************/ -namespace Server.Movement +namespace Server { public static class Movement { diff --git a/Projects/Server/Network/Listener.cs b/Projects/Server/Network/Listener.cs index 2146f9e16..5865f3b31 100644 --- a/Projects/Server/Network/Listener.cs +++ b/Projects/Server/Network/Listener.cs @@ -76,7 +76,7 @@ namespace Server.Network DisplayListener(); - while (true) + while (!Core.Closing) { Socket s; try @@ -90,7 +90,7 @@ namespace Server.Network } if (VerifySocket(s)) - _ = new NetState(s, pump); + new NetState(s, pump); else Release(s); } @@ -105,12 +105,9 @@ namespace Server.Network { NetworkInterface[] adapters = NetworkInterface.GetAllNetworkInterfaces(); foreach (NetworkInterface adapter in adapters) - { - IPInterfaceProperties properties = adapter.GetIPProperties(); - foreach (UnicastIPAddressInformation unicast in properties.UnicastAddresses) - if (ipep.AddressFamily == unicast.Address.AddressFamily) - Console.WriteLine("Listening: {0}:{1}", unicast.Address, ipep.Port); - } + foreach (UnicastIPAddressInformation unicast in adapter.GetIPProperties().UnicastAddresses) + if (ipep.AddressFamily == unicast.Address.AddressFamily) + Console.WriteLine("Listening: {0}:{1}", unicast.Address, ipep.Port); } else { diff --git a/Projects/Server/Network/NetState.cs b/Projects/Server/Network/NetState.cs index 14355146d..bba0c0a3b 100644 --- a/Projects/Server/Network/NetState.cs +++ b/Projects/Server/Network/NetState.cs @@ -26,14 +26,13 @@ using System.IO; using System.IO.Pipelines; using System.Net; using System.Net.Sockets; +using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; -using Server.Accounting; -using Server.Diagnostics; using Server.Gumps; -using Server.HuePickers; using Server.Items; using Server.Menus; +using NetworkPackets = Server.Network.Packets; namespace Server.Network { @@ -93,7 +92,6 @@ namespace Server.Network { private string m_ToString; private ClientVersion m_Version; - private SendQueue m_SendQueue = new SendQueue(); public DateTime ConnectedOn { get; } @@ -111,6 +109,8 @@ namespace Server.Network private static AsyncState m_AsyncState = m_ResumeState; + public bool UseCompression { get; set; } + public IPacketEncoder PacketEncoder { get; set; } public static NetStateCreatedCallback CreatedCallback { get; set; } @@ -158,7 +158,8 @@ namespace Server.Network ProtocolChanges = ProtocolChanges.Version500a; else if (value >= m_Version407a) ProtocolChanges = ProtocolChanges.Version407a; - else if (value >= m_Version400a) ProtocolChanges = ProtocolChanges.Version400a; + else if (value >= m_Version400a) + ProtocolChanges = ProtocolChanges.Version400a; } } @@ -272,9 +273,7 @@ namespace Server.Network public Socket Socket { get; private set; } - public bool CompressionEnabled { get; set; } - - public int Sequence { get; set; } + public byte Sequence { get; set; } public List Gumps { get; private set; } @@ -300,8 +299,7 @@ namespace Server.Network public void AddMenu(IMenu menu) { - if (Menus == null) - Menus = new List(); + Menus ??= new List(); if (Menus.Count < MenuCap) Menus.Add(menu); @@ -329,8 +327,7 @@ namespace Server.Network public void AddHuePicker(HuePicker huePicker) { - if (HuePickers == null) - HuePickers = new List(); + HuePickers ??= new List(); if (HuePickers.Count < HuePickerCap) HuePickers.Add(huePicker); @@ -358,8 +355,7 @@ namespace Server.Network public void AddGump(Gump gump) { - if (Gumps == null) - Gumps = new List(); + Gumps ??= new List(); if (Gumps.Count < GumpCap) Gumps.Add(gump); @@ -387,8 +383,8 @@ namespace Server.Network public void LaunchBrowser(string url) { - Send(new MessageLocalized(Serial.MinusOne, -1, MessageType.Label, 0x35, 3, 501231, "", "")); - Send(new LaunchBrowser(url)); + NetworkPackets.SendMessageLocalized(this, Serial.MinusOne, -1, MessageType.Label, 0x35, 3, 501231); + NetworkPackets.SendLaunchBrowser(this, url); } public CityInfo[] CityInfo { get; set; } @@ -446,17 +442,6 @@ namespace Server.Network m_AsyncState = Interlocked.Exchange(ref m_AsyncState, m_ResumeState); } - public virtual void Send(Packet p) - { - if (Socket == null || BlockAllPackets) - { - p.OnSend(); - return; - } - - m_SendQueue.Enqueue(p); - } - public bool CheckEncrypted(int packetID) { if (!SentFirstPacket && packetID != 0xF0 && packetID != 0xF1 && packetID != 0xCF && packetID != 0x80 && @@ -470,32 +455,35 @@ namespace Server.Network return false; } - private Pipe m_RecvdPipe; + public Pipe RecvdPipe { get; private set; } + public Pipe SendPipe { get; private set; } private async Task Start(MessagePump pump) { - m_RecvdPipe = new Pipe(); + RecvdPipe = new Pipe(); + SendPipe = new Pipe(); Running = true; - await Task.WhenAll(ProcessSends(), ProcessRecvs(), HandlePackets(pump)).ConfigureAwait(false); + await Task.WhenAll(HandlePackets(pump), ProcessSends(), ProcessRecvs()); } private async Task ProcessRecvs() { - PipeWriter w = m_RecvdPipe.Writer; + PipeWriter w = RecvdPipe.Writer; - while (true) + while (!Core.Closing) { if (m_AsyncState.Paused) { - await Timer.Pause(50).ConfigureAwait(false); + Interlocked.Exchange(ref m_NextCheckActivity, Core.TickCount + 90000); + await Timer.Pause(50); continue; } try { Memory memory = w.GetMemory(); - int bytesRead = await Socket.ReceiveAsync(memory, SocketFlags.None).ConfigureAwait(false); + int bytesRead = await Socket.ReceiveAsync(memory, SocketFlags.None); if (bytesRead == 0) break; @@ -503,7 +491,7 @@ namespace Server.Network w.Advance(bytesRead); - FlushResult result = await w.FlushAsync().ConfigureAwait(false); + FlushResult result = await w.FlushAsync(); if (result.IsCompleted || result.IsCanceled) break; } @@ -517,7 +505,7 @@ namespace Server.Network Dispose(); } - private async Task ProcessSends() + private async Task HandlePackets(MessagePump pump) { while (true) try @@ -526,26 +514,31 @@ namespace Server.Network if (p == null) break; - ReadOnlyMemory buffer = p.Compile(CompressionEnabled, out int length); + long pos = PacketHandlers.ProcessPacket(pump, this, seq); - if (buffer.Length <= 0 || length <= 0) - { - p.OnSend(); - return; - } + if (pos <= 0) + break; - buffer = buffer.Slice(0, length); + pr.AdvanceTo(seq.GetPosition(pos, seq.Start)); - PacketSendProfile prof = null; + if (result.IsCompleted || result.IsCanceled) + break; + } - if (Core.Profiling) - prof = PacketSendProfile.Acquire(p.GetType()); + pr.Complete(); + } - prof?.Start(); + public async Task Flush(int bytesWritten) + { + if (IsDisposing || BlockAllPackets) + return; - await Socket.SendAsync(buffer, SocketFlags.None).ConfigureAwait(false); + SendPipe.Writer.Advance(bytesWritten); + FlushResult result = await SendPipe.Writer.FlushAsync(); - p.OnSend(); + if (result.IsCompleted || result.IsCanceled) + Dispose(); + } prof?.Finish(length); } @@ -562,29 +555,44 @@ namespace Server.Network } } - private async Task HandlePackets(MessagePump pump) + private async Task ProcessSends() { - PipeReader pr = m_RecvdPipe.Reader; + PipeReader pr = SendPipe.Reader; - while (true) + while (!Core.Closing) { + if (m_AsyncState.Paused) + { + await Timer.Pause(50); + continue; + } + ReadResult result = await pr.ReadAsync(); ReadOnlySequence seq = result.Buffer; if (seq.Length == 0) break; - long pos = PacketHandlers.ProcessPacket(pump, this, seq); - - if (pos <= 0) + if (!SequenceMarshal.TryGetReadOnlyMemory(seq, out ReadOnlyMemory memory)) break; - pr.AdvanceTo(seq.GetPosition(pos, seq.Start)); + try + { + int bytesWritten = await Socket.SendAsync(memory, SocketFlags.None); + + pr.AdvanceTo(seq.GetPosition(bytesWritten)); + } + catch (SocketException ex) + { + Console.WriteLine(ex); + TraceException(ex); + break; + } if (result.IsCompleted || result.IsCanceled) break; } - pr.Complete(); + Dispose(); } public PacketHandler GetHandler(int packetID) => @@ -639,17 +647,17 @@ namespace Server.Network Task.Run(async () => { - m_RecvdPipe.Reader.CancelPendingRead(); - m_RecvdPipe.Reader.Complete(); - await m_RecvdPipe.Writer.FlushAsync().ConfigureAwait(false); - m_RecvdPipe.Writer.Complete(); + RecvdPipe.Reader.CancelPendingRead(); + RecvdPipe.Reader.Complete(); + await SendPipe.Writer.FlushAsync(); + SendPipe.Writer.Complete(); try { Socket.Shutdown(SocketShutdown.Both); } catch (Exception ex) { TraceException(ex); } try { Socket.Close(); } catch (Exception ex) { TraceException(ex); } Socket = null; - m_RecvdPipe = null; - m_SendQueue = null; + RecvdPipe = null; + SendPipe = null; m_Disposed.Enqueue(this); }); } diff --git a/Projects/Server/Network/Packet.cs b/Projects/Server/Network/Packet.cs deleted file mode 100644 index bb96362d5..000000000 --- a/Projects/Server/Network/Packet.cs +++ /dev/null @@ -1,267 +0,0 @@ -/*************************************************************************** - * Packet.cs - * ------------------- - * begin : August 2, 2019 - * copyright : (C) The RunUO Software Team - * email : info@runuo.com - * - * $Id$ - * - ***************************************************************************/ - -/*************************************************************************** - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - ***************************************************************************/ - -using Server.Diagnostics; -using System; -using System.Buffers; -using System.Diagnostics; -using System.IO; - -namespace Server.Network -{ - public abstract class Packet - { - private const int CompressorBufferSize = 0x10000; - - private const int BufferSize = 4096; - - private byte[] m_CompiledBuffer; - private int m_CompiledLength; - private int m_Length; - private State m_State; - - protected PacketWriter m_Stream; - - protected Packet(int packetID) - { - PacketID = packetID; - - if (Core.Profiling) - { - PacketSendProfile prof = PacketSendProfile.Acquire(GetType()); - prof.Increment(); - } - } - - protected Packet(int packetID, int length) - { - PacketID = packetID; - m_Length = length; - - m_Stream = PacketWriter.CreateInstance(length); // new PacketWriter( length ); - m_Stream.Write((byte)packetID); - - if (Core.Profiling) - { - PacketSendProfile prof = PacketSendProfile.Acquire(GetType()); - prof.Increment(); - } - } - - public int PacketID { get; } - - public PacketWriter UnderlyingStream => m_Stream; - - public void EnsureCapacity(int length) - { - m_Stream = PacketWriter.CreateInstance(length); // new PacketWriter( length ); - m_Stream.Write((byte)PacketID); - m_Stream.Write((short)0); - } - - public static Packet SetStatic(Packet p) - { - p.SetStatic(); - return p; - } - - public static Packet Acquire(Packet p) - { - p.Acquire(); - return p; - } - - public static void Release(ref Packet p) - { - p?.Release(); - p = null; - } - - public static void Release(Packet p) - { - p?.Release(); - } - - public void SetStatic() - { - m_State |= State.Static | State.Acquired; - } - - public void Acquire() - { - m_State |= State.Acquired; - } - - public void OnSend() - { - Core.Set(); // Is this still needed if this is done async? - - if ((m_State & (State.Acquired | State.Static)) == 0) - Free(); - } - - private void Free() - { - if (m_CompiledBuffer == null) - return; - - if ((m_State & State.Buffered) != 0) - ArrayPool.Shared.Return(m_CompiledBuffer); - - m_State &= ~(State.Static | State.Acquired | State.Buffered); - - m_CompiledBuffer = null; - } - - public void Release() - { - if ((m_State & State.Acquired) != 0) - Free(); - } - - public byte[] Compile(bool compress, out int length) - { - lock (this) - { - if (m_CompiledBuffer == null) - { - if ((m_State & State.Accessed) == 0) - { - m_State |= State.Accessed; - } - else - { - if ((m_State & State.Warned) == 0) - { - m_State |= State.Warned; - - try - { - using StreamWriter op = new StreamWriter("net_opt.log", true); - op.WriteLine("Redundant compile for packet {0}, use Acquire() and Release()", GetType()); - op.WriteLine(new StackTrace()); - } - catch - { - // ignored - } - } - - m_CompiledBuffer = new byte[0]; - m_CompiledLength = 0; - - length = m_CompiledLength; - return m_CompiledBuffer; - } - - InternalCompile(compress); - } - - length = m_CompiledLength; - return m_CompiledBuffer; - } - } - - private void InternalCompile(bool compress) - { - if (m_Length == 0) - { - long streamLen = m_Stream.Length; - - m_Stream.Seek(1, SeekOrigin.Begin); - m_Stream.Write((ushort)streamLen); - } - else if (m_Stream.Length != m_Length) - { - int diff = (int)m_Stream.Length - m_Length; - - Console.WriteLine("Packet: 0x{0:X2}: Bad packet length! ({1}{2} bytes)", PacketID, diff >= 0 ? "+" : "", - diff); - } - - MemoryStream ms = m_Stream.UnderlyingStream; - - m_CompiledBuffer = ms.GetBuffer(); - int length = (int)ms.Length; - - if (compress) - { - byte[] buffer = ArrayPool.Shared.Rent(CompressorBufferSize); - - Compression.Compress(m_CompiledBuffer, 0, length, buffer, out length); - - if (length <= 0) - { - Console.WriteLine("Warning: Compression buffer overflowed on packet 0x{0:X2} ('{1}') (length={2})", - PacketID, GetType().Name, length); - using StreamWriter op = new StreamWriter("compression_overflow.log", true); - op.WriteLine("{0} Warning: Compression buffer overflowed on packet 0x{1:X2} ('{2}') (length={3})", - DateTime.UtcNow, PacketID, GetType().Name, length); - op.WriteLine(new StackTrace()); - } - else - { - m_CompiledLength = length; - - if ((m_State & State.Static) != 0) - { - m_CompiledBuffer = new byte[length]; - Buffer.BlockCopy(buffer, 0, m_CompiledBuffer, 0, length); - ArrayPool.Shared.Return(buffer); - } - else - { - m_CompiledBuffer = buffer; - m_State |= State.Buffered; - } - } - } - else if (length > 0) - { - byte[] old = m_CompiledBuffer; - m_CompiledLength = length; - - if ((m_State & State.Static) != 0) - m_CompiledBuffer = new byte[length]; - else - { - m_CompiledBuffer = ArrayPool.Shared.Rent(length); - m_State |= State.Buffered; - } - - Buffer.BlockCopy(old, 0, m_CompiledBuffer, 0, length); - } - - PacketWriter.ReleaseInstance(m_Stream); - m_Stream = null; - } - - [Flags] - private enum State - { - Inactive = 0x00, - Static = 0x01, - Acquired = 0x02, - Accessed = 0x04, - Buffered = 0x08, - Warned = 0x10 - } - } -} diff --git a/Projects/Server/Network/PacketHandlers.cs b/Projects/Server/Network/PacketHandlers.cs index 37ec26672..b29769a26 100644 --- a/Projects/Server/Network/PacketHandlers.cs +++ b/Projects/Server/Network/PacketHandlers.cs @@ -26,7 +26,6 @@ using Server.Accounting; using Server.ContextMenus; using Server.Diagnostics; using Server.Gumps; -using Server.HuePickers; using Server.Items; using Server.Menus; using Server.Prompts; @@ -56,11 +55,6 @@ namespace Server.Network public static class PacketHandlers { - public delegate void PlayCharCallback(NetState state, bool val); - - private const int BadFood = unchecked((int)0xBAADF00D); - private const int BadUOTD = unchecked((int)0xFFCEFFCE); - private const int m_AuthIDWindowSize = 128; private static PacketHandler[] m_6017Handlers; @@ -109,43 +103,32 @@ namespace Server.Network Register(0x01, 5, false, Disconnect); Register(0x02, 7, true, MovementReq); Register(0x03, 0, true, AsciiSpeech); - Register(0x04, 2, true, GodModeRequest); Register(0x05, 5, true, AttackReq); Register(0x06, 5, true, UseReq); Register(0x07, 7, true, LiftReq); Register(0x08, 14, true, DropReq); Register(0x09, 5, true, LookReq); - Register(0x0A, 11, true, Edit); Register(0x12, 0, true, TextCommand); Register(0x13, 10, true, EquipReq); - Register(0x14, 6, true, ChangeZ); Register(0x22, 3, true, Resynchronize); Register(0x2C, 2, true, DeathStatusResponse); Register(0x34, 10, true, MobileQuery); Register(0x3A, 0, true, ChangeSkillLock); Register(0x3B, 0, true, VendorBuyReply); - Register(0x47, 11, true, NewTerrain); - Register(0x48, 73, true, NewAnimData); - Register(0x58, 106, true, NewRegion); Register(0x5D, 73, false, PlayCharacter); - Register(0x61, 9, true, DeleteStatic); Register(0x6C, 19, true, TargetResponse); Register(0x6F, 0, true, SecureTrade); Register(0x72, 5, true, SetWarMode); Register(0x73, 2, false, PingReq); Register(0x75, 35, true, RenameRequest); - Register(0x79, 9, true, ResourceQuery); - Register(0x7E, 2, true, GodviewQuery); Register(0x7D, 13, true, MenuResponse); Register(0x80, 62, false, AccountLogin); Register(0x83, 39, false, DeleteCharacter); Register(0x91, 65, false, GameLogin); Register(0x95, 9, true, HuePickerResponse); - Register(0x96, 0, true, GameCentralMoniter); Register(0x98, 0, true, MobileNameRequest); Register(0x9A, 0, true, AsciiPromptResponse); Register(0x9B, 258, true, HelpRequest); - Register(0x9D, 51, true, GMSingle); Register(0x9F, 0, true, VendorSellReply); Register(0xA0, 3, false, PlayServer); Register(0xA4, 149, false, SystemInfo); @@ -161,8 +144,6 @@ namespace Server.Network Register(0xBF, 0, true, ExtendedCommand); Register(0xC2, 0, true, UnicodePromptResponse); Register(0xC8, 2, true, SetUpdateRange); - Register(0xC9, 6, true, TripTime); - Register(0xCA, 6, true, UTripTime); Register(0xCF, 0, false, AccountLogin); Register(0xD0, 0, true, ConfigurationFile); Register(0xD1, 2, true, LogoutReq); @@ -214,9 +195,7 @@ namespace Server.Network public static void Register(int packetID, int length, bool ingame, OnPacketReceive onReceive) { Handlers[packetID] = new PacketHandler(packetID, length, ingame, onReceive); - - if (m_6017Handlers[packetID] == null) - m_6017Handlers[packetID] = new PacketHandler(packetID, length, ingame, onReceive); + m_6017Handlers[packetID] ??= new PacketHandler(packetID, length, ingame, onReceive); } public static PacketHandler GetHandler(int packetID) => Handlers[packetID]; @@ -342,6 +321,8 @@ namespace Server.Network return -1; } + // Console.WriteLine("Packet Handler {0:X}", handler.PacketID); + long packetLength = handler.Length; if (handler.Length <= 0 && r.Length >= 3) { @@ -413,9 +394,9 @@ namespace Server.Network public static void EncodedCommand(NetState state, PacketReader pvSrc) { IEntity e = World.FindEntity(pvSrc.ReadUInt32()); - int packetID = pvSrc.ReadUInt16(); + int packetId = pvSrc.ReadUInt16(); - EncodedPacketHandler ph = GetEncodedHandler(packetID); + EncodedPacketHandler ph = GetEncodedHandler(packetId); if (ph != null) { @@ -423,7 +404,7 @@ namespace Server.Network { Console.WriteLine( "Client: {0}: Sent ingame packet (0xD7x{1:X2}) before having been attached to a mobile", state, - packetID); + packetId); state.Dispose(); } else if (ph.Ingame && state.Mobile.Deleted) @@ -536,37 +517,30 @@ namespace Server.Network if (vendor == null) return; - if (vendor.Deleted || !Utility.RangeCheck(vendor.Location, state.Mobile.Location, 10)) + if (vendor.Deleted || !Utility.RangeCheck(vendor.Location, state.Mobile.Location, 10) || flag != 0x02) { - state.Send(new EndVendorBuy(vendor)); + Packets.SendEndVendorBuyOrSell(state, vendor.Serial); return; } - if (flag == 0x02) + msgSize -= 1 + 2 + 4 + 1; + + if (msgSize / 7 > 100) + return; + + List buyList = new List(msgSize / 7); + while (msgSize > 0) { - msgSize -= 1 + 2 + 4 + 1; + pvSrc.ReadByte(); // layer + Serial serial = pvSrc.ReadUInt32(); + int amount = pvSrc.ReadInt16(); - if (msgSize / 7 > 100) - return; - - List buyList = new List(msgSize / 7); - while (msgSize > 0) - { - byte layer = pvSrc.ReadByte(); - Serial serial = pvSrc.ReadUInt32(); - int amount = pvSrc.ReadInt16(); - - buyList.Add(new BuyItemResponse(serial, amount)); - msgSize -= 7; - } - - if (buyList.Count > 0 && vendor is IVendor v && v.OnBuyItems(state.Mobile, buyList)) - state.Send(new EndVendorBuy(vendor)); - } - else - { - state.Send(new EndVendorBuy(vendor)); + buyList.Add(new BuyItemResponse(serial, amount)); + msgSize -= 7; } + + if (buyList.Count > 0 && vendor is IVendor v && v.OnBuyItems(state.Mobile, buyList)) + Packets.SendEndVendorBuyOrSell(state, vendor.Serial); } public static void VendorSellReply(NetState state, PacketReader pvSrc) @@ -578,7 +552,7 @@ namespace Server.Network if (vendor.Deleted || !Utility.RangeCheck(vendor.Location, state.Mobile.Location, 10)) { - state.Send(new EndVendorSell(vendor)); + Packets.SendEndVendorBuyOrSell(state, vendor.Serial); return; } @@ -590,14 +564,14 @@ namespace Server.Network for (int i = 0; i < count; i++) { Item item = World.FindItem(pvSrc.ReadUInt32()); - int Amount = pvSrc.ReadInt16(); + int amount = pvSrc.ReadInt16(); - if (item != null && Amount > 0) - sellList.Add(new SellItemResponse(item, Amount)); + if (item != null && amount > 0) + sellList.Add(new SellItemResponse(item, amount)); } if (sellList.Count > 0 && vendor is IVendor v && v.OnSellItems(state.Mobile, sellList)) - state.Send(new EndVendorSell(vendor)); + Packets.SendEndVendorBuyOrSell(state, vendor.Serial); } } @@ -609,39 +583,6 @@ namespace Server.Network EventSink.InvokeDeleteRequest(new DeleteRequestEventArgs(state, index)); } - public static void ResourceQuery(NetState state, PacketReader pvSrc) - { - if (VerifyGC(state)) - { - } - } - - public static void GameCentralMoniter(NetState state, PacketReader pvSrc) - { - if (VerifyGC(state)) - { - int type = pvSrc.ReadByte(); - int num1 = pvSrc.ReadInt32(); - - Console.WriteLine("God Client: {0}: Game central moniter", state); - Console.WriteLine(" - Type: {0}", type); - Console.WriteLine(" - Number: {0}", num1); - - pvSrc.Trace(state); - } - } - - public static void GodviewQuery(NetState state, PacketReader pvSrc) - { - if (VerifyGC(state)) Console.WriteLine("God Client: {0}: Godview query 0x{1:X}", state, pvSrc.ReadByte()); - } - - public static void GMSingle(NetState state, PacketReader pvSrc) - { - if (VerifyGC(state)) - pvSrc.Trace(state); - } - public static void DeathStatusResponse(NetState state, PacketReader pvSrc) { // Ignored @@ -677,7 +618,7 @@ namespace Server.Network Mobile m = World.FindMobile(pvSrc.ReadUInt32()); if (m != null && Utility.InUpdateRange(state.Mobile, m) && state.Mobile.CanSee(m)) - state.Send(new MobileName(m)); + Packets.SendMobileName(state, m); } public static void RequestScrollWindow(NetState state, PacketReader pvSrc) @@ -714,34 +655,6 @@ namespace Server.Network } } - public static void TripTime(NetState state, PacketReader pvSrc) - { - int unk1 = pvSrc.ReadByte(); - int unk2 = pvSrc.ReadInt32(); - - state.Send(new TripTimeResponse(unk1)); - } - - public static void UTripTime(NetState state, PacketReader pvSrc) - { - int unk1 = pvSrc.ReadByte(); - int unk2 = pvSrc.ReadInt32(); - - state.Send(new UTripTimeResponse(unk1)); - } - - public static void ChangeZ(NetState state, PacketReader pvSrc) - { - if (VerifyGC(state)) - { - int x = pvSrc.ReadInt16(); - int y = pvSrc.ReadInt16(); - int z = pvSrc.ReadSByte(); - - Console.WriteLine("God Client: {0}: Change Z ({1}, {2}, {3})", state, x, y, z); - } - } - public static void SystemInfo(NetState state, PacketReader pvSrc) { int v1 = pvSrc.ReadByte(); @@ -758,83 +671,6 @@ namespace Server.Network int v8 = pvSrc.ReadInt32(); } - public static void Edit(NetState state, PacketReader pvSrc) - { - if (VerifyGC(state)) - { - int type = pvSrc.ReadByte(); // 10 = static, 7 = npc, 4 = dynamic - int x = pvSrc.ReadInt16(); - int y = pvSrc.ReadInt16(); - int id = pvSrc.ReadInt16(); - int z = pvSrc.ReadSByte(); - int hue = pvSrc.ReadUInt16(); - - Console.WriteLine("God Client: {0}: Edit {6} ({1}, {2}, {3}) 0x{4:X} (0x{5:X})", state, x, y, z, id, hue, - type); - } - } - - public static void DeleteStatic(NetState state, PacketReader pvSrc) - { - if (VerifyGC(state)) - { - int x = pvSrc.ReadInt16(); - int y = pvSrc.ReadInt16(); - int z = pvSrc.ReadInt16(); - int id = pvSrc.ReadUInt16(); - - Console.WriteLine("God Client: {0}: Delete Static ({1}, {2}, {3}) 0x{4:X}", state, x, y, z, id); - } - } - - public static void NewAnimData(NetState state, PacketReader pvSrc) - { - if (VerifyGC(state)) - { - Console.WriteLine("God Client: {0}: New tile animation", state); - - pvSrc.Trace(state); - } - } - - public static void NewTerrain(NetState state, PacketReader pvSrc) - { - if (VerifyGC(state)) - { - int x = pvSrc.ReadInt16(); - int y = pvSrc.ReadInt16(); - int id = pvSrc.ReadUInt16(); - int width = pvSrc.ReadInt16(); - int height = pvSrc.ReadInt16(); - - Console.WriteLine("God Client: {0}: New Terrain ({1}, {2})+({3}, {4}) 0x{5:X4}", state, x, y, width, height, - id); - } - } - - public static void NewRegion(NetState state, PacketReader pvSrc) - { - if (VerifyGC(state)) - { - string name = pvSrc.ReadString(40); - int unk = pvSrc.ReadInt32(); - int x = pvSrc.ReadInt16(); - int y = pvSrc.ReadInt16(); - int width = pvSrc.ReadInt16(); - int height = pvSrc.ReadInt16(); - int zStart = pvSrc.ReadInt16(); - int zEnd = pvSrc.ReadInt16(); - string desc = pvSrc.ReadString(40); - int soundFX = pvSrc.ReadInt16(); - int music = pvSrc.ReadInt16(); - int nightFX = pvSrc.ReadInt16(); - int dungeon = pvSrc.ReadByte(); - int light = pvSrc.ReadInt16(); - - Console.WriteLine("God Client: {0}: New Region '{1}' ('{2}')", state, name, desc); - } - } - public static void AccountID(NetState state, PacketReader pvSrc) { } @@ -970,12 +806,6 @@ namespace Server.Network } } - public static void GodModeRequest(NetState state, PacketReader pvSrc) - { - if (VerifyGC(state)) - state.Send(new GodModeReply(pvSrc.ReadBoolean())); - } - public static void AsciiPromptResponse(NetState state, PacketReader pvSrc) { uint serial = pvSrc.ReadUInt32(); @@ -1200,14 +1030,12 @@ namespace Server.Network public static void LogoutReq(NetState state, PacketReader pvSrc) { - state.Send(new LogoutAck()); + Packets.SendLogoutAck(state); } public static void ChangeSkillLock(NetState state, PacketReader pvSrc) { - Skill s = state.Mobile.Skills[pvSrc.ReadInt16()]; - - s?.SetLockNoRelay((SkillLock)pvSrc.ReadByte()); + state.Mobile.Skills[pvSrc.ReadInt16()]?.SetLockNoRelay((SkillLock)pvSrc.ReadByte()); } public static void HelpRequest(NetState state, PacketReader pvSrc) @@ -1218,13 +1046,13 @@ namespace Server.Network public static void TargetResponse(NetState state, PacketReader pvSrc) { int type = pvSrc.ReadByte(); - int targetID = pvSrc.ReadInt32(); + int targetId = pvSrc.ReadInt32(); int flags = pvSrc.ReadByte(); Serial serial = pvSrc.ReadUInt32(); int x = pvSrc.ReadInt16(), y = pvSrc.ReadInt16(), z = pvSrc.ReadInt16(); int graphic = pvSrc.ReadUInt16(); - if (targetID == unchecked((int)0xDEADBEEF)) + if (targetId == unchecked((int)0xDEADBEEF)) return; Mobile from = state.Mobile; @@ -1244,7 +1072,7 @@ namespace Server.Network // User pressed escape t.Cancel(from, TargetCancelType.Canceled); } - else if (t.TargetID != targetID) + else if (t.TargetID != targetId) { // Sanity, prevent fake target } @@ -1267,42 +1095,28 @@ namespace Server.Network t.Cancel(from, TargetCancelType.Canceled); return; } - else + + StaticTile[] tiles = map.Tiles.GetStaticTiles(x, y, !t.DisallowMultis); + + if (state.HighSeas) { - StaticTile[] tiles = map.Tiles.GetStaticTiles(x, y, !t.DisallowMultis); - - bool valid = false; - - if (state.HighSeas) - { - ItemData id = TileData.ItemTable[graphic & TileData.MaxItemValue]; - if (id.Surface) z -= id.Height; - } - - for (int i = 0; !valid && i < tiles.Length; ++i) - if (tiles[i].Z == z && tiles[i].ID == graphic) - valid = true; - - if (!valid) - { - t.Cancel(from, TargetCancelType.Canceled); - return; - } - else - { - toTarget = new StaticTarget(new Point3D(x, y, z), graphic); - } + ItemData id = TileData.ItemTable[graphic & TileData.MaxItemValue]; + if (id.Surface) z -= id.Height; } + + if (tiles.All(tile => tile.Z != z || tile.ID != graphic)) + { + t.Cancel(from, TargetCancelType.Canceled); + return; + } + + toTarget = new StaticTarget(new Point3D(x, y, z), graphic); } } else if (serial.IsMobile) - { toTarget = World.FindMobile(serial); - } else if (serial.IsItem) - { toTarget = World.FindItem(serial); - } else { t.Cancel(from, TargetCancelType.Canceled); @@ -1438,13 +1252,8 @@ namespace Server.Network { Mobile m = state.Mobile; - if (state.StygianAbyss) - state.Send(new MobileUpdate(m)); - else - state.Send(new MobileUpdateOld(m)); - - state.Send(MobileIncoming.Create(state, m, m)); - + Packets.SendMobileUpdate(state, m); + Packets.SendMobileIncoming(state, m, m); m.SendEverything(); state.Sequence = 0; @@ -1496,24 +1305,24 @@ namespace Server.Network for (int i = 0; i < count; ++i) { - int speechID; + int speechId; if ((i & 1) == 0) { hold <<= 8; hold |= pvSrc.ReadByte(); - speechID = hold; + speechId = hold; hold = 0; } else { value = pvSrc.ReadInt16(); - speechID = (value & 0xFFF0) >> 4; + speechId = (value & 0xFFF0) >> 4; hold = value & 0xF; } - if (!keyList.Contains(speechID)) - keyList.Add(speechID); + if (!keyList.Contains(speechId)) + keyList.Add(speechId); } text = pvSrc.ReadUTF8StringSafe(); @@ -1550,9 +1359,7 @@ namespace Server.Network uint value = pvSrc.ReadUInt32(); if ((value & ~0x7FFFFFFF) != 0) - { from.OnPaperdollRequest(); - } else { Serial s = value; @@ -1576,9 +1383,7 @@ namespace Server.Network from.NextActionTime = Core.TickCount + Mobile.ActionDelay; } else - { from.SendActionMessage(); - } } public static void LookReq(NetState state, PacketReader pvSrc) @@ -1594,9 +1399,7 @@ namespace Server.Network if (m != null && from.CanSee(m) && Utility.InUpdateRange(from, m)) { if (SingleClickProps) - { m.OnAosSingleClick(from); - } else { if (from.Region.OnSingleClick(from, m)) @@ -1612,9 +1415,7 @@ namespace Server.Network Utility.InUpdateRange(from.Location, item.GetWorldLocation())) { if (SingleClickProps) - { item.OnAosSingleClick(from); - } else if (from.Region.OnSingleClick(from, item)) { if (item.Parent is Item item1) @@ -1628,25 +1429,25 @@ namespace Server.Network public static void PingReq(NetState state, PacketReader pvSrc) { - state.Send(PingAck.Instantiate(pvSrc.ReadByte())); + Packets.SendPingAck(state, pvSrc.ReadByte()); } public static void SetUpdateRange(NetState state, PacketReader pvSrc) { - state.Send(ChangeUpdateRange.Instantiate(18)); + Packets.SendChangeUpdateRange(state); } public static void MovementReq(NetState state, PacketReader pvSrc) { Direction dir = (Direction)pvSrc.ReadByte(); - int seq = pvSrc.ReadByte(); - int key = pvSrc.ReadInt32(); + byte seq = pvSrc.ReadByte(); + pvSrc.ReadInt32(); // key Mobile m = state.Mobile; if (state.Sequence == 0 && seq != 0 || !m.Move(dir)) { - state.Send(new MovementRej(seq, m)); + Packets.SendMovementRej(state, seq, m); state.Sequence = 0; m.ClearFastwalkStack(); @@ -1655,7 +1456,7 @@ namespace Server.Network { ++seq; - if (seq == 256) + if (seq == 0) seq = 1; state.Sequence = seq; @@ -1688,7 +1489,7 @@ namespace Server.Network { int packetID = pvSrc.ReadUInt16(); - Console.WriteLine("Extended Packet: {0:X}", packetID); + // Console.WriteLine("Extended Packet: {0:X}", packetID); PacketHandler ph = GetExtendedHandler(packetID); if (ph == null) @@ -2062,13 +1863,6 @@ namespace Server.Network if (m != null) switch (type) { - case 0x00: // Unknown, sent by godclient - { - if (VerifyGC(state)) - Console.WriteLine("God Client: {0}: Query 0x{1:X2} on {2} '{3}'", state, type, m.Serial, m.Name); - - break; - } case 0x04: // Stats { m.OnStatsQuery(from); @@ -2093,47 +1887,17 @@ namespace Server.Network string name = pvSrc.ReadString(30); - pvSrc.Seek(2, SeekOrigin.Current); + pvSrc.ReadInt16(); // Unknown + int flags = pvSrc.ReadInt32(); -/* if (FeatureProtection.DisabledFeatures != 0 && ThirdPartyAuthCallback != null) - { - bool authOK = false; - - ulong razorFeatures = ((ulong)pvSrc.ReadUInt32() << 32) | pvSrc.ReadUInt32(); - - if (razorFeatures == (ulong)FeatureProtection.DisabledFeatures) - { - bool doesNotMatch = false; - for (int i = 0; !doesNotMatch && i < m_ThirdPartyAuthKey.Length; i++) - doesNotMatch = pvSrc.ReadByte() != m_ThirdPartyAuthKey[i]; - - if (!doesNotMatch) - authOK = true; - } - else - { - pvSrc.Seek(16, SeekOrigin.Current); - } - - ThirdPartyAuthCallback(state, authOK); - }*/ -/* else - {*/ - pvSrc.Seek(24, SeekOrigin.Current); -/* }*/ - -/* if (ThirdPartyHackedCallback != null) - { - pvSrc.Seek(-2, SeekOrigin.Current); - if (pvSrc.ReadUInt16() == 0xDEAD) - ThirdPartyHackedCallback(state, true); - }*/ + pvSrc.Seek(24, SeekOrigin.Current); if (!state.Running) return; int charSlot = pvSrc.ReadInt32(); + // TODO: Handle IP address. int clientIP = pvSrc.ReadInt32(); IAccount a = state.Account; @@ -2152,7 +1916,7 @@ namespace Server.Network if (check != null && check.Map != Map.Internal && check != m) { Console.WriteLine("Login: {0}: Account in use", state); - state.Send(new PopupMessage(PMMessage.CharInWorld)); + Packets.SendPopupMessage(state, PMMessage.CharInWorld); return; } } @@ -2167,11 +1931,9 @@ namespace Server.Network // TODO: Make this wait one tick so we don't have to call it unnecessarily NetState.ProcessDisposedQueue(); - - state.Send(new ClientVersionReq()); + Packets.SendClientVersionReq(state); state.BlockAllPackets = true; - state.Flags = (ClientFlags)flags; state.Mobile = m; @@ -2183,93 +1945,38 @@ namespace Server.Network public static void DoLogin(NetState state, Mobile m) { - state.Send(new LoginConfirm(m)); + Packets.SendLoginConfirm(state, m); if (m.Map != null) - state.Send(new MapChange(m)); + Packets.SendMapChange(state, m.Map); - state.Send(new MapPatches()); - - state.Send(SeasonChange.Instantiate(m.GetSeason(), true)); - - state.Send(SupportedFeatures.Instantiate(state)); + Packets.SendMapPatches(state); + Packets.SendSeasonChange(state, m.GetSeason(), 1); + Packets.SendSupportedFeatures(state); state.Sequence = 0; - if (state.NewMobileIncoming) - { - state.Send(new MobileUpdate(m)); - state.Send(new MobileUpdate(m)); + // TODO: Verify if we need this twice + Packets.SendMobileUpdate(state, m); + m.CheckLightLevels(true); + Packets.SendMobileUpdate(state, m); - m.CheckLightLevels(true); + Packets.SendMobileIncoming(state, m, m); + Packets.SendMobileStatus(state, m, m); + Packets.SendSetWarMode(state, m.Warmode); - state.Send(new MobileUpdate(m)); + m.SendEverything(); - state.Send(new MobileIncoming(m, m)); - //state.Send( new MobileAttributes( m ) ); - state.Send(new MobileStatus(m, m)); - state.Send(Network.SetWarMode.Instantiate(m.Warmode)); + Packets.SendSupportedFeatures(state); + Packets.SendMobileUpdate(state, m); + Packets.SendMobileStatus(state, m, m); + Packets.SendSetWarMode(state, m.Warmode); + Packets.SendMobileIncoming(state, m, m); - m.SendEverything(); - - state.Send(SupportedFeatures.Instantiate(state)); - state.Send(new MobileUpdate(m)); - //state.Send( new MobileAttributes( m ) ); - state.Send(new MobileStatus(m, m)); - state.Send(Network.SetWarMode.Instantiate(m.Warmode)); - state.Send(new MobileIncoming(m, m)); - } - else if (state.StygianAbyss) - { - state.Send(new MobileUpdate(m)); - state.Send(new MobileUpdate(m)); - - m.CheckLightLevels(true); - - state.Send(new MobileUpdate(m)); - - state.Send(new MobileIncomingSA(m, m)); - //state.Send( new MobileAttributes( m ) ); - state.Send(new MobileStatus(m, m)); - state.Send(Network.SetWarMode.Instantiate(m.Warmode)); - - m.SendEverything(); - - state.Send(SupportedFeatures.Instantiate(state)); - state.Send(new MobileUpdate(m)); - //state.Send( new MobileAttributes( m ) ); - state.Send(new MobileStatus(m, m)); - state.Send(Network.SetWarMode.Instantiate(m.Warmode)); - state.Send(new MobileIncomingSA(m, m)); - } - else - { - state.Send(new MobileUpdateOld(m)); - state.Send(new MobileUpdateOld(m)); - - m.CheckLightLevels(true); - - state.Send(new MobileUpdateOld(m)); - - state.Send(new MobileIncomingOld(m, m)); - //state.Send( new MobileAttributes( m ) ); - state.Send(new MobileStatus(m, m)); - state.Send(Network.SetWarMode.Instantiate(m.Warmode)); - - m.SendEverything(); - - state.Send(SupportedFeatures.Instantiate(state)); - state.Send(new MobileUpdateOld(m)); - //state.Send( new MobileAttributes( m ) ); - state.Send(new MobileStatus(m, m)); - state.Send(Network.SetWarMode.Instantiate(m.Warmode)); - state.Send(new MobileIncomingOld(m, m)); - } - - state.Send(LoginComplete.Instance); - state.Send(new CurrentTime()); - state.Send(SeasonChange.Instantiate(m.GetSeason(), true)); - state.Send(new MapChange(m)); + Packets.SendLoginComplete(state); + Packets.SendCurrentTime(state); + Packets.SendMapChange(state, m.Map); + Packets.SendSeasonChange(state, m.GetSeason(), 1); EventSink.InvokeLogin(new LoginEventArgs(m)); @@ -2334,20 +2041,14 @@ namespace Server.Network race = Race.Races[raceID]; } else - { race = Race.Races[(byte)(genderRace / 2)]; - } - - if (race == null) - race = Race.DefaultRace; + race ??= Race.DefaultRace; CityInfo[] info = state.CityInfo; IAccount a = state.Account; if (info == null || a == null || cityIndex < 0 || cityIndex >= info.Length) - { state.Dispose(); - } else { // Check if anyone is using this account @@ -2358,7 +2059,7 @@ namespace Server.Network if (check != null && check.Map != Map.Internal) { Console.WriteLine("Login: {0}: Account in use", state); - state.Send(new PopupMessage(PMMessage.CharInWorld)); + Packets.SendPopupMessage(state, PMMessage.CharInWorld); return; } } @@ -2383,7 +2084,7 @@ namespace Server.Network race ); - state.Send(new ClientVersionReq()); + Packets.SendClientVersionReq(state); state.BlockAllPackets = true; @@ -2453,10 +2154,8 @@ namespace Server.Network bool female = genderRace % 2 != 0; - Race race; - - byte raceID = (byte)(genderRace < 4 ? 0 : genderRace / 2 - 1); - race = Race.Races[raceID] ?? Race.DefaultRace; + byte raceId = (byte)(genderRace < 4 ? 0 : genderRace / 2 - 1); + Race race = Race.Races[raceId] ?? Race.DefaultRace; CityInfo[] info = state.CityInfo; IAccount a = state.Account; @@ -2475,7 +2174,7 @@ namespace Server.Network if (check != null && check.Map != Map.Internal) { Console.WriteLine("Login: {0}: Account in use", state); - state.Send(new PopupMessage(PMMessage.CharInWorld)); + Packets.SendPopupMessage(state, PMMessage.CharInWorld); return; } } @@ -2501,25 +2200,20 @@ namespace Server.Network race ); - state.Send(new ClientVersionReq()); - - state.BlockAllPackets = true; - + Packets.SendClientVersionReq(state); EventSink.InvokeCharacterCreated(args); Mobile m = args.Mobile; if (m != null) { + state.BlockAllPackets = true; state.Mobile = m; m.NetState = state; new LoginTimer(state, m).Start(); } else - { - state.BlockAllPackets = false; state.Dispose(); - } } } @@ -2530,11 +2224,11 @@ namespace Server.Network int oldestID = 0; DateTime oldest = DateTime.MaxValue; - foreach (KeyValuePair kvp in m_AuthIDWindow) - if (kvp.Value.Age < oldest) + foreach (var (key, value) in m_AuthIDWindow) + if (value.Age < oldest) { - oldestID = kvp.Key; - oldest = kvp.Value.Age; + oldestID = key; + oldest = value.Age; } m_AuthIDWindow.Remove(oldestID); @@ -2564,13 +2258,13 @@ namespace Server.Network } state.SentFirstPacket = true; + state.UseCompression = true; int authID = pvSrc.ReadInt32(); if (m_AuthIDWindow.TryGetValue(authID, out AuthIDPersistence ap)) { m_AuthIDWindow.Remove(authID); - state.Version = ap.Version; } else if (ClientVerification) @@ -2604,19 +2298,12 @@ namespace Server.Network if (e.Accepted) { state.CityInfo = e.CityInfo; - state.CompressionEnabled = true; - state.Send(SupportedFeatures.Instantiate(state)); - - if (state.NewCharacterList) - state.Send(new CharacterList(state.Account, state.CityInfo)); - else - state.Send(new CharacterListOld(state.Account, state.CityInfo)); + Packets.SendSupportedFeatures(state); + Packets.SendCharacterList(state, state.CityInfo); } else - { state.Dispose(); - } } public static void PlayServer(NetState state, PacketReader pvSrc) @@ -2626,17 +2313,15 @@ namespace Server.Network IAccount a = state.Account; if (info == null || a == null || index < 0 || index >= info.Length) - { state.Dispose(); - } else { ServerInfo si = info[index]; - state.m_AuthID = PlayServerAck.m_AuthID = GenerateAuthID(state); + state.m_AuthID = GenerateAuthID(state); state.SentFirstPacket = false; - state.Send(new PlayServerAck(si)); + Packets.SendPlayServerAck(state, si); } } @@ -2734,13 +2419,13 @@ namespace Server.Network state.ServerInfo = info; - state.Send(new AccountLoginAck(info)); + Packets.SendAccountLoginAck(state, info); } } public static void AccountLogin_ReplyRej(NetState state, ALRReason reason) { - state.Send(new AccountLoginRej(reason)); + Packets.SendAccountLoginRej(state, reason); state.Dispose(); } @@ -2758,7 +2443,10 @@ namespace Server.Network protected override void OnTick() { if (m_State == null) + { Stop(); + return; + } if (m_State.Version != null) { diff --git a/Projects/Server/Network/PacketReader.cs b/Projects/Server/Network/PacketReader.cs index de6159bb1..2f33fc423 100644 --- a/Projects/Server/Network/PacketReader.cs +++ b/Projects/Server/Network/PacketReader.cs @@ -104,31 +104,206 @@ namespace Server.Network public sbyte ReadSByte() => (sbyte)ReadByte(); - public bool ReadBoolean() => ReadByte() > 0; + public bool ReadBoolean() => ReadByte() != 0; - public string ReadUnicodeStringLE() + public bool IsSafeChar(int c) => c >= 0x20 && c < 0xFFFE; + + public string ReadUTF8StringSafe() { StringBuilder sb = new StringBuilder(); + bool end = false; - while (m_Reader.TryReadLittleEndian(out short c) && c != 0) - sb.Append((char)c); + while (!(end |= m_Reader.End)) + { + ReadOnlySpan span = m_Reader.UnreadSpan; + int count = 0; + bool safe = true; + while (count < span.Length) + { + byte chr = span[count]; + if (chr == 0) + { + end = true; + break; + } + + if (!IsSafeChar(chr)) + { + safe = false; + break; + } + + count++; + } + + sb.Append(Encoding.UTF8.GetString(span.Slice(0, count))); + m_Reader.Advance(count + (safe ? 1 : 0)); + } return sb.ToString(); } - public string ReadUnicodeStringLE(int fixedLength) + public string ReadUTF8String() { StringBuilder sb = new StringBuilder(); + bool end = false; - while (fixedLength-- > 0 && m_Reader.TryReadLittleEndian(out short c) && c != 0) - sb.Append((char)c); + while (!(end |= m_Reader.End)) + { + ReadOnlySpan span = m_Reader.UnreadSpan; + int count = 0; + while (count < span.Length) + { + if (span[count] == 0) + { + end = true; + break; + } - if (fixedLength > 0) - m_Reader.Advance(fixedLength); + count++; + } + + sb.Append(Encoding.UTF8.GetString(span.Slice(0, count))); + m_Reader.Advance(count); + } return sb.ToString(); } + public string ReadString() + { + StringBuilder sb = new StringBuilder(); + bool end = false; + + while (!(end |= m_Reader.End)) + { + ReadOnlySpan span = m_Reader.UnreadSpan; + int count = 0; + while (count < span.Length) + { + if (span[count] == 0) + { + end = true; + break; + } + + count++; + } + + sb.Append(Encoding.ASCII.GetString(span.Slice(0, count))); + m_Reader.Advance(count); + } + + return sb.ToString(); + } + + public string ReadString(int size) + { + StringBuilder sb = new StringBuilder(); + bool end = false; + + while (!(end |= m_Reader.End) && size > 0) + { + ReadOnlySpan span = m_Reader.UnreadSpan; + int count = 0; + while (count < span.Length && size > 0) + { + if (span[count] == 0) + { + end = true; + break; + } + + count++; + size--; + } + + sb.Append(Encoding.ASCII.GetString(span.Slice(0, count))); + m_Reader.Advance(count); + } + + if (size > 0) + m_Reader.Advance(size); + + return sb.ToString(); + } + + public bool IsSafeChar(int c) => c >= 0x20 && c < 0xFFFE; + + public string ReadUTF8StringSafe(int fixedLength) + { + StringBuilder sb = new StringBuilder(); + bool end = false; + + while (!(end |= m_Reader.End)) + { + ReadOnlySpan span = m_Reader.UnreadSpan; + int count = 0; + bool safe = true; + while (count < span.Length) + { + byte chr = span[count]; + if (chr == 0) + { + end = true; + break; + } + + if (!IsSafeChar(chr)) + { + safe = false; + break; + } + + count++; + } + + sb.Append(Encoding.ASCII.GetString(span.Slice(0, count))); + m_Reader.Advance(count + (safe ? 1 : 0)); + } + + return sb.ToString(); + } + + public string ReadStringSafe(int size) + { + StringBuilder sb = new StringBuilder(); + bool end = false; + + while (!(end |= m_Reader.End) && size > 0) + { + ReadOnlySpan span = m_Reader.UnreadSpan; + int count = 0; + bool safe = true; + while (count < span.Length && size > 0) + { + byte chr = span[count]; + if (chr == 0) + { + end = true; + break; + } + + if (!IsSafeChar(chr)) + { + safe = false; + break; + } + + count++; + size--; + } + + sb.Append(Encoding.ASCII.GetString(span.Slice(0, count))); + m_Reader.Advance(size + (safe ? 1 : 0)); + } + + public string ReadUTF8String() => + Utility.UTF8.GetString( + m_Reader.TryReadTo(out ReadOnlySpan span, (byte)'\0', true) ? span : + m_Reader.Sequence.Slice(m_Reader.Position, m_Reader.Remaining).ToArray() + ); + public string ReadUnicodeStringLESafe(int fixedLength) { StringBuilder sb = new StringBuilder(); @@ -154,17 +329,6 @@ namespace Server.Network return sb.ToString(); } - public string ReadUnicodeStringSafe() - { - StringBuilder sb = new StringBuilder(); - - while (m_Reader.TryReadBigEndian(out short c) && c != 0) - if (IsSafeChar(c)) - sb.Append((char)c); - - return sb.ToString(); - } - public string ReadUnicodeString() { StringBuilder sb = new StringBuilder(); @@ -175,72 +339,24 @@ namespace Server.Network return sb.ToString(); } - public bool IsSafeChar(int c) => c >= 0x20 && c < 0xFFFE; - - public string ReadUTF8StringSafe(int fixedLength) - { - string s; - - if (m_Reader.TryReadTo(out ReadOnlySpan span, (byte)'\0', true)) - s = Utility.UTF8.GetString(span.Length > fixedLength ? span.Slice(0, fixedLength) : span); - else - { - long size = Math.Min(m_Reader.Remaining, fixedLength); - s = Utility.UTF8.GetString(m_Reader.Sequence.Slice(m_Reader.Position, size).ToArray()); - m_Reader.Advance(size); - } - - StringBuilder sb = new StringBuilder(s.Length); - - for (int i = 0; i < s.Length; ++i) - if (IsSafeChar(s[i])) - sb.Append(s[i]); - - return sb.ToString(); - } - - public string ReadUTF8StringSafe() - { - string s; - - if (m_Reader.TryReadTo(out ReadOnlySpan span, (byte)'\0', true)) - s = Utility.UTF8.GetString(span); - else - { - s = Utility.UTF8.GetString(m_Reader.Sequence.Slice(m_Reader.Position, m_Reader.Remaining).ToArray()); - m_Reader.Advance(m_Reader.Remaining); - } - - StringBuilder sb = new StringBuilder(s.Length); - - for (int i = 0; i < s.Length; ++i) - if (IsSafeChar(s[i])) - sb.Append(s[i]); - - return sb.ToString(); - } - - public string ReadUTF8String() => - Utility.UTF8.GetString( - m_Reader.TryReadTo(out ReadOnlySpan span, (byte)'\0', true) ? span : - m_Reader.Sequence.Slice(m_Reader.Position, m_Reader.Remaining).ToArray() - ); - - public string ReadString() + public string ReadUnicodeString(int fixedLength) { StringBuilder sb = new StringBuilder(); - while (m_Reader.TryRead(out byte c)) + while (fixedLength-- > 0 && m_Reader.TryReadBigEndian(out short c) && c != 0) sb.Append((char)c); + if (fixedLength > 0) + m_Reader.Advance(fixedLength * 2); + return sb.ToString(); } - public string ReadStringSafe() + public string ReadUnicodeStringSafe() { StringBuilder sb = new StringBuilder(); - while (m_Reader.TryRead(out byte c)) + while (m_Reader.TryReadBigEndian(out short c) && c != 0) if (IsSafeChar(c)) sb.Append((char)c); @@ -260,45 +376,5 @@ namespace Server.Network return sb.ToString(); } - - public string ReadUnicodeString(int fixedLength) - { - StringBuilder sb = new StringBuilder(); - - while (fixedLength-- > 0 && m_Reader.TryReadBigEndian(out short c) && c != 0) - sb.Append((char)c); - - if (fixedLength > 0) - m_Reader.Advance(fixedLength * 2); - - return sb.ToString(); - } - - public string ReadStringSafe(int fixedLength) - { - StringBuilder sb = new StringBuilder(); - - while (fixedLength-- > 0 && m_Reader.TryRead(out byte c) && c != 0) - if (IsSafeChar(c)) - sb.Append((char)c); - - if (fixedLength > 0) - m_Reader.Advance(fixedLength); - - return sb.ToString(); - } - - public string ReadString(int fixedLength) - { - StringBuilder sb = new StringBuilder(); - - while (fixedLength-- > 0 && m_Reader.TryRead(out byte c) && c != 0) - sb.Append((char)c); - - if (fixedLength > 0) - m_Reader.Advance(fixedLength); - - return sb.ToString(); - } } } diff --git a/Projects/Server/Network/PacketWriter.cs b/Projects/Server/Network/PacketWriter.cs deleted file mode 100644 index 6587e3a7a..000000000 --- a/Projects/Server/Network/PacketWriter.cs +++ /dev/null @@ -1,346 +0,0 @@ -/*************************************************************************** - * PacketWriter.cs - * ------------------- - * begin : May 1, 2002 - * copyright : (C) The RunUO Software Team - * email : info@runuo.com - * - * $Id$ - * - ***************************************************************************/ - -/*************************************************************************** - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - ***************************************************************************/ - -using System; -using System.Collections.Concurrent; -using System.IO; -using System.Text; - -namespace Server.Network -{ - /// - /// Provides functionality for writing primitive binary data. - /// - public class PacketWriter - { - private static ConcurrentQueue m_Pool = new ConcurrentQueue(); - - /// - /// Internal format buffer. - /// - private byte[] m_Buffer = new byte[4]; - - private int m_Capacity; - - /// - /// Instantiates a new PacketWriter instance with a given capacity. - /// - /// Initial capacity for the internal stream. - public PacketWriter(int capacity = 32) - { - UnderlyingStream = new MemoryStream(capacity); - m_Capacity = capacity; - } - - /// - /// Gets the total stream length. - /// - public long Length => UnderlyingStream.Length; - - /// - /// Gets or sets the current stream position. - /// - public long Position - { - get => UnderlyingStream.Position; - set => UnderlyingStream.Position = value; - } - - /// - /// The internal stream used by this PacketWriter instance. - /// - public MemoryStream UnderlyingStream { get; private set; } - - public static PacketWriter CreateInstance(int capacity = 32) - { - if (m_Pool.TryDequeue(out PacketWriter pw)) - { - pw.m_Capacity = capacity; - pw.UnderlyingStream.SetLength(0); - return pw; - } - - return new PacketWriter(capacity); - } - - public static void ReleaseInstance(PacketWriter pw) - { - m_Pool.Enqueue(pw); - } - - /// - /// Writes a 1-byte boolean value to the underlying stream. False is represented by 0, true by 1. - /// - public void Write(bool value) - { - UnderlyingStream.WriteByte((byte)(value ? 1 : 0)); - } - - /// - /// Writes a 1-byte unsigned integer value to the underlying stream. - /// - public void Write(byte value) - { - UnderlyingStream.WriteByte(value); - } - - /// - /// Writes a 1-byte signed integer value to the underlying stream. - /// - public void Write(sbyte value) - { - UnderlyingStream.WriteByte((byte)value); - } - - /// - /// Writes a 2-byte signed integer value to the underlying stream. - /// - public void Write(short value) - { - m_Buffer[0] = (byte)(value >> 8); - m_Buffer[1] = (byte)value; - - UnderlyingStream.Write(m_Buffer, 0, 2); - } - - /// - /// Writes a 2-byte unsigned integer value to the underlying stream. - /// - public void Write(ushort value) - { - m_Buffer[0] = (byte)(value >> 8); - m_Buffer[1] = (byte)value; - - UnderlyingStream.Write(m_Buffer, 0, 2); - } - - /// - /// Writes a 4-byte signed integer value to the underlying stream. - /// - public void Write(int value) - { - m_Buffer[0] = (byte)(value >> 24); - m_Buffer[1] = (byte)(value >> 16); - m_Buffer[2] = (byte)(value >> 8); - m_Buffer[3] = (byte)value; - - UnderlyingStream.Write(m_Buffer, 0, 4); - } - - /// - /// Writes a 4-byte unsigned integer value to the underlying stream. - /// - public void Write(uint value) - { - m_Buffer[0] = (byte)(value >> 24); - m_Buffer[1] = (byte)(value >> 16); - m_Buffer[2] = (byte)(value >> 8); - m_Buffer[3] = (byte)value; - - UnderlyingStream.Write(m_Buffer, 0, 4); - } - - /// - /// Writes a sequence of bytes to the underlying stream - /// - public void Write(byte[] buffer, int offset, int size) - { - UnderlyingStream.Write(buffer, offset, size); - } - - /// - /// Writes a fixed-length ASCII-encoded string value to the underlying stream. To fit (size), the string content is either - /// truncated or padded with null characters. - /// - public void WriteAsciiFixed(string value, int size) - { - if (value == null) - { - Console.WriteLine("Network: Attempted to WriteAsciiFixed() with null value"); - value = string.Empty; - } - - int length = value.Length; - - UnderlyingStream.SetLength(UnderlyingStream.Length + size); - - if (length >= size) - { - UnderlyingStream.Position += - Encoding.ASCII.GetBytes(value, 0, size, UnderlyingStream.GetBuffer(), (int)UnderlyingStream.Position); - } - else - { - Encoding.ASCII.GetBytes(value, 0, length, UnderlyingStream.GetBuffer(), (int)UnderlyingStream.Position); - UnderlyingStream.Position += size; - } - } - - /// - /// Writes a dynamic-length ASCII-encoded string value to the underlying stream, followed by a 1-byte null character. - /// - public void WriteAsciiNull(string value) - { - if (value == null) - { - Console.WriteLine("Network: Attempted to WriteAsciiNull() with null value"); - value = string.Empty; - } - - int length = value.Length; - - UnderlyingStream.SetLength(UnderlyingStream.Length + length + 1); - - Encoding.ASCII.GetBytes(value, 0, length, UnderlyingStream.GetBuffer(), (int)UnderlyingStream.Position); - UnderlyingStream.Position += length + 1; - } - - /// - /// Writes a dynamic-length little-endian unicode string value to the underlying stream, followed by a 2-byte null character. - /// - public void WriteLittleUniNull(string value) - { - if (value == null) - { - Console.WriteLine("Network: Attempted to WriteLittleUniNull() with null value"); - value = string.Empty; - } - - int length = value.Length; - - UnderlyingStream.SetLength(UnderlyingStream.Length + (length + 1) * 2); - - UnderlyingStream.Position += Encoding.Unicode.GetBytes(value, 0, length, UnderlyingStream.GetBuffer(), (int)UnderlyingStream.Position); - UnderlyingStream.Position += 2; - } - - /// - /// Writes a fixed-length little-endian unicode string value to the underlying stream. To fit (size), the string content is - /// either truncated or padded with null characters. - /// - public void WriteLittleUniFixed(string value, int size) - { - if (value == null) - { - Console.WriteLine("Network: Attempted to WriteLittleUniFixed() with null value"); - value = string.Empty; - } - - int length = value.Length; - size *= 2; - - UnderlyingStream.SetLength(UnderlyingStream.Length + size); - - if (length * 2 >= size) - { - UnderlyingStream.Position += - Encoding.Unicode.GetBytes(value, 0, size / 2, UnderlyingStream.GetBuffer(), (int)UnderlyingStream.Position); - } - else - { - Encoding.Unicode.GetBytes(value, 0, length, UnderlyingStream.GetBuffer(), (int)UnderlyingStream.Position); - UnderlyingStream.Position += size; - } - } - - /// - /// Writes a dynamic-length big-endian unicode string value to the underlying stream, followed by a 2-byte null character. - /// - public void WriteBigUniNull(string value) - { - if (value == null) - { - Console.WriteLine("Network: Attempted to WriteBigUniNull() with null value"); - value = string.Empty; - } - - int length = value.Length; - - UnderlyingStream.SetLength(UnderlyingStream.Length + (length + 1) * 2); - - UnderlyingStream.Position += - Encoding.BigEndianUnicode.GetBytes(value, 0, length, UnderlyingStream.GetBuffer(), (int)UnderlyingStream.Position); - UnderlyingStream.Position += 2; - } - - /// - /// Writes a fixed-length big-endian unicode string value to the underlying stream. To fit (size), the string content is - /// either truncated or padded with null characters. - /// - public void WriteBigUniFixed(string value, int size) - { - if (value == null) - { - Console.WriteLine("Network: Attempted to WriteBigUniFixed() with null value"); - value = string.Empty; - } - - int length = value.Length; - size *= 2; - - UnderlyingStream.SetLength(UnderlyingStream.Length + size); - - if (length * 2 >= size ) - { - UnderlyingStream.Position += - Encoding.BigEndianUnicode.GetBytes(value, 0, size / 2, UnderlyingStream.GetBuffer(), (int)UnderlyingStream.Position); - } - else - { - Encoding.BigEndianUnicode.GetBytes(value, 0, length, UnderlyingStream.GetBuffer(), (int)UnderlyingStream.Position); - UnderlyingStream.Position += size; - } - } - - /// - /// Fills the stream from the current position up to (capacity) with 0x00's - /// - public void Fill() - { - Fill(m_Capacity - UnderlyingStream.Length); - } - - /// - /// Writes a number of 0x00 byte values to the underlying stream. - /// - public void Fill(long length) - { - if (UnderlyingStream.Position == UnderlyingStream.Length) - { - UnderlyingStream.SetLength(UnderlyingStream.Length + length); - UnderlyingStream.Seek(0, SeekOrigin.End); - } - else - { - UnderlyingStream.Write(new byte[length], 0, (int)length); - } - } - - /// - /// Offsets the current position from an origin. - /// - public long Seek(long offset, SeekOrigin origin) => UnderlyingStream.Seek(offset, origin); - - /// - /// Gets the entire stream content as a byte array. - /// - public byte[] ToArray() => UnderlyingStream.ToArray(); - } -} diff --git a/Projects/Server/Network/Packets.cs b/Projects/Server/Network/Packets.cs deleted file mode 100644 index 330f3d3fe..000000000 --- a/Projects/Server/Network/Packets.cs +++ /dev/null @@ -1,4170 +0,0 @@ -/*************************************************************************** - * Packets.cs - * ------------------- - * begin : May 1, 2002 - * copyright : (C) The RunUO Software Team - * email : info@runuo.com - * - * $Id$ - * - ***************************************************************************/ - -/*************************************************************************** - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - ***************************************************************************/ - -using System; -using System.Buffers; -using System.Collections.Generic; -using System.IO; -using System.Net; -using System.Text; -using System.Threading; -using Server.Accounting; -using Server.ContextMenus; -using Server.Gumps; -using Server.HuePickers; -using Server.Items; -using Server.Menus; -using Server.Menus.ItemLists; -using Server.Menus.Questions; -using Server.Prompts; -using Server.Targeting; - -namespace Server.Network -{ - public enum PMMessage : byte - { - CharNoExist = 1, - CharExists = 2, - CharInWorld = 5, - LoginSyncError = 6, - IdleWarning = 7 - } - - public enum LRReason : byte - { - CannotLift = 0, - OutOfRange = 1, - OutOfSight = 2, - TryToSteal = 3, - AreHolding = 4, - Inspecific = 5 - } - - /*public enum CMEFlags - { - None = 0x00, - Locked = 0x01, - Arrow = 0x02, - x0004 = 0x04, - Color = 0x20, - x0040 = 0x40, - x0080 = 0x80 - }*/ - - public sealed class DamagePacketOld : Packet - { - public DamagePacketOld(Mobile m, int amount) : base(0xBF) - { - EnsureCapacity(11); - - m_Stream.Write((short)0x22); - m_Stream.Write((byte)1); - m_Stream.Write(m.Serial); - - if (amount > 255) - amount = 255; - else if (amount < 0) - amount = 0; - - m_Stream.Write((byte)amount); - } - } - - public sealed class DamagePacket : Packet - { - public DamagePacket(Mobile m, int amount) : base(0x0B, 7) - { - m_Stream.Write(m.Serial); - - if (amount > 0xFFFF) - amount = 0xFFFF; - else if (amount < 0) - amount = 0; - - m_Stream.Write((ushort)amount); - } - - /*public DamagePacket( Mobile m, int amount ) : base( 0xBF ) - { - EnsureCapacity( 11 ); - - m_Stream.Write( (short) 0x22 ); - m_Stream.Write( (byte) 1 ); - m_Stream.Write( (int) m.Serial ); - - if ( amount > 255 ) - amount = 255; - else if ( amount < 0 ) - amount = 0; - - m_Stream.Write( (byte)amount ); - }*/ - } - - public sealed class CancelArrow : Packet - { - public CancelArrow() : base(0xBA, 6) - { - m_Stream.Write((byte)0); - m_Stream.Write((short)-1); - m_Stream.Write((short)-1); - } - } - - public sealed class SetArrow : Packet - { - public SetArrow(int x, int y) : base(0xBA, 6) - { - m_Stream.Write((byte)1); - m_Stream.Write((short)x); - m_Stream.Write((short)y); - } - } - - public sealed class CancelArrowHS : Packet - { - public CancelArrowHS(int x, int y, Serial s) : base(0xBA, 10) - { - m_Stream.Write((byte)0); - m_Stream.Write((short)x); - m_Stream.Write((short)y); - m_Stream.Write(s); - } - } - - public sealed class SetArrowHS : Packet - { - public SetArrowHS(int x, int y, Serial s) : base(0xBA, 10) - { - m_Stream.Write((byte)1); - m_Stream.Write((short)x); - m_Stream.Write((short)y); - m_Stream.Write(s); - } - } - - public sealed class DisplaySecureTrade : Packet - { - public DisplaySecureTrade(Mobile them, Container first, Container second, string name) - : base(0x6F) - { - if (name == null) name = ""; - - EnsureCapacity(18 + name.Length); - - m_Stream.Write((byte)0); // Display - m_Stream.Write(them.Serial); - m_Stream.Write(first.Serial); - m_Stream.Write(second.Serial); - m_Stream.Write(true); - - m_Stream.WriteAsciiFixed(name, 30); - } - } - - public sealed class CloseSecureTrade : Packet - { - public CloseSecureTrade(Container cont) - : base(0x6F) - { - EnsureCapacity(8); - - m_Stream.Write((byte)1); // Close - m_Stream.Write(cont.Serial); - } - } - - public enum TradeFlag : byte - { - Display = 0x0, - Close = 0x1, - Update = 0x2, - UpdateGold = 0x3, - UpdateLedger = 0x4 - } - - public sealed class UpdateSecureTrade : Packet - { - public UpdateSecureTrade(Container cont, bool first, bool second) - : this(cont, TradeFlag.Update, first ? 1 : 0, second ? 1 : 0) - { - } - - public UpdateSecureTrade(Container cont, TradeFlag flag, int first, int second) - : base(0x6F) - { - EnsureCapacity(17); - - m_Stream.Write((byte)flag); - m_Stream.Write(cont.Serial); - m_Stream.Write(first); - m_Stream.Write(second); - } - } - - public sealed class SecureTradeEquip : Packet - { - public SecureTradeEquip(Item item, Mobile m) : base(0x25, 20) - { - m_Stream.Write(item.Serial); - m_Stream.Write((short)item.ItemID); - m_Stream.Write((byte)0); - m_Stream.Write((short)item.Amount); - m_Stream.Write((short)item.X); - m_Stream.Write((short)item.Y); - m_Stream.Write(m.Serial); - m_Stream.Write((short)item.Hue); - } - } - - public sealed class SecureTradeEquip6017 : Packet - { - public SecureTradeEquip6017(Item item, Mobile m) : base(0x25, 21) - { - m_Stream.Write(item.Serial); - m_Stream.Write((short)item.ItemID); - m_Stream.Write((byte)0); - m_Stream.Write((short)item.Amount); - m_Stream.Write((short)item.X); - m_Stream.Write((short)item.Y); - m_Stream.Write((byte)0); // Grid Location? - m_Stream.Write(m.Serial); - m_Stream.Write((short)item.Hue); - } - } - - public sealed class MapPatches : Packet - { - public MapPatches() : base(0xBF) - { - EnsureCapacity(9 + 3 * 8); - - m_Stream.Write((short)0x0018); - - m_Stream.Write(4); - - m_Stream.Write(Map.Felucca.Tiles.Patch.StaticBlocks); - m_Stream.Write(Map.Felucca.Tiles.Patch.LandBlocks); - - m_Stream.Write(Map.Trammel.Tiles.Patch.StaticBlocks); - m_Stream.Write(Map.Trammel.Tiles.Patch.LandBlocks); - - m_Stream.Write(Map.Ilshenar.Tiles.Patch.StaticBlocks); - m_Stream.Write(Map.Ilshenar.Tiles.Patch.LandBlocks); - - m_Stream.Write(Map.Malas.Tiles.Patch.StaticBlocks); - m_Stream.Write(Map.Malas.Tiles.Patch.LandBlocks); - } - } - - public sealed class ObjectHelpResponse : Packet - { - public ObjectHelpResponse(IEntity e, string text) : base(0xB7) - { - EnsureCapacity(9 + text.Length * 2); - - m_Stream.Write(e.Serial); - m_Stream.WriteBigUniNull(text); - } - } - - public sealed class VendorBuyContent : Packet - { - public VendorBuyContent(List list) - : base(0x3c) - { - EnsureCapacity(list.Count * 19 + 5); - - m_Stream.Write((short)list.Count); - - //The client sorts these by their X/Y value. - //OSI sends these in weird order. X/Y highest to lowest and serial lowest to highest - //These are already sorted by serial (done by the vendor class) but we have to send them by x/y - //(the x74 packet is sent in 'correct' order.) - for (int i = list.Count - 1; i >= 0; --i) - { - BuyItemState bis = list[i]; - - m_Stream.Write(bis.MySerial); - m_Stream.Write((ushort)bis.ItemID); - m_Stream.Write((byte)0); //itemid offset - m_Stream.Write((ushort)bis.Amount); - m_Stream.Write((short)(i + 1)); //x - m_Stream.Write((short)1); //y - m_Stream.Write(bis.ContainerSerial); - m_Stream.Write((ushort)bis.Hue); - } - } - } - - public sealed class VendorBuyContent6017 : Packet - { - public VendorBuyContent6017(List list) : base(0x3c) - { - EnsureCapacity(list.Count * 20 + 5); - - m_Stream.Write((short)list.Count); - - //The client sorts these by their X/Y value. - //OSI sends these in weird order. X/Y highest to lowest and serial loewst to highest - //These are already sorted by serial (done by the vendor class) but we have to send them by x/y - //(the x74 packet is sent in 'correct' order.) - for (int i = list.Count - 1; i >= 0; --i) - { - BuyItemState bis = list[i]; - - m_Stream.Write(bis.MySerial); - m_Stream.Write((ushort)bis.ItemID); - m_Stream.Write((byte)0); //itemid offset - m_Stream.Write((ushort)bis.Amount); - m_Stream.Write((short)(i + 1)); //x - m_Stream.Write((short)1); //y - m_Stream.Write((byte)0); // Grid Location? - m_Stream.Write(bis.ContainerSerial); - m_Stream.Write((ushort)bis.Hue); - } - } - } - - public sealed class DisplayBuyList : Packet - { - public DisplayBuyList(Mobile vendor) : base(0x24, 7) - { - m_Stream.Write(vendor.Serial); - m_Stream.Write((short)0x30); // buy window id? - } - } - - public sealed class DisplayBuyListHS : Packet - { - public DisplayBuyListHS(Mobile vendor) : base(0x24, 9) - { - m_Stream.Write(vendor.Serial); - m_Stream.Write((short)0x30); // buy window id? - m_Stream.Write((short)0x00); - } - } - - public sealed class VendorBuyList : Packet - { - public VendorBuyList(Mobile vendor, List list) - : base(0x74) - { - EnsureCapacity(256); - - m_Stream.Write(!(vendor.FindItemOnLayer(Layer.ShopBuy) is Container BuyPack) ? Serial.MinusOne : BuyPack.Serial); - - m_Stream.Write((byte)list.Count); - - for (int i = 0; i < list.Count; ++i) - { - BuyItemState bis = list[i]; - - m_Stream.Write(bis.Price); - - string desc = bis.Description ?? ""; - - m_Stream.Write((byte)(desc.Length + 1)); - m_Stream.WriteAsciiNull(desc); - } - } - } - - public sealed class VendorSellList : Packet - { - public VendorSellList(Mobile shopkeeper, ICollection sis) : base(0x9E) - { - EnsureCapacity(256); - - m_Stream.Write(shopkeeper.Serial); - - m_Stream.Write((ushort)sis.Count); - - foreach (SellItemState state in sis) - { - m_Stream.Write(state.Item.Serial); - m_Stream.Write((ushort)state.Item.ItemID); - m_Stream.Write((ushort)state.Item.Hue); - m_Stream.Write((ushort)state.Item.Amount); - m_Stream.Write((ushort)state.Price); - - string name = state.Item.Name; - - if (name == null || (name = name.Trim()).Length <= 0) - name = state.Name; - - if (name == null) - name = ""; - - m_Stream.Write((ushort)name.Length); - m_Stream.WriteAsciiFixed(name, (ushort)name.Length); - } - } - } - - public sealed class EndVendorSell : Packet - { - public EndVendorSell(Mobile Vendor) : base(0x3B, 8) - { - m_Stream.Write((ushort)8); //length - m_Stream.Write(Vendor.Serial); - m_Stream.Write((byte)0); - } - } - - public sealed class EndVendorBuy : Packet - { - public EndVendorBuy(Mobile Vendor) : base(0x3B, 8) - { - m_Stream.Write((ushort)8); //length - m_Stream.Write(Vendor.Serial); - m_Stream.Write((byte)0); - } - } - - public sealed class DeathAnimation : Packet - { - public DeathAnimation(Mobile killed, Item corpse) : base(0xAF, 13) - { - m_Stream.Write(killed.Serial); - m_Stream.Write(corpse?.Serial ?? Serial.Zero); - m_Stream.Write(0); - } - } - - public sealed class StatLockInfo : Packet - { - public StatLockInfo(Mobile m) : base(0xBF) - { - EnsureCapacity(12); - - m_Stream.Write((short)0x19); - m_Stream.Write((byte)2); - m_Stream.Write(m.Serial); - m_Stream.Write((byte)0); - - int lockBits = (int)m.StrLock << 4 | (int)m.DexLock << 2 | (int)m.IntLock; - - m_Stream.Write((byte)lockBits); - } - } - - public class EquipInfoAttribute - { - public EquipInfoAttribute(int number, int charges = -1) - { - Number = number; - Charges = charges; - } - - public int Number{ get; } - - public int Charges{ get; } - } - - public class EquipmentInfo - { - public EquipmentInfo(int number, Mobile crafter, bool unidentified, EquipInfoAttribute[] attributes) - { - Number = number; - Crafter = crafter; - Unidentified = unidentified; - Attributes = attributes; - } - - public int Number{ get; } - - public Mobile Crafter{ get; } - - public bool Unidentified{ get; } - - public EquipInfoAttribute[] Attributes{ get; } - } - - public sealed class DisplayEquipmentInfo : Packet - { - public DisplayEquipmentInfo(Item item, EquipmentInfo info) : base(0xBF) - { - EquipInfoAttribute[] attrs = info.Attributes; - - EnsureCapacity(17 + (info.Crafter?.Name.Length ?? 0) + - (info.Unidentified ? 4 : 0) + attrs.Length * 6); - - m_Stream.Write((short)0x10); - m_Stream.Write(item.Serial); - - m_Stream.Write(info.Number); - - if (info.Crafter != null) - { - string name = info.Crafter.Name; - - m_Stream.Write(-3); - - if (name == null) - { - m_Stream.Write((ushort)0); - } - else - { - int length = name.Length; - m_Stream.Write((ushort)length); - m_Stream.WriteAsciiFixed(name, length); - } - } - - if (info.Unidentified) m_Stream.Write(-4); - - for (int i = 0; i < attrs.Length; ++i) - { - m_Stream.Write(attrs[i].Number); - m_Stream.Write((short)attrs[i].Charges); - } - - m_Stream.Write(-1); - } - } - - public sealed class ChangeUpdateRange : Packet - { - private static ChangeUpdateRange[] m_Cache = new ChangeUpdateRange[0x100]; - - public ChangeUpdateRange(int range) : base(0xC8, 2) - { - m_Stream.Write((byte)range); - } - - public static ChangeUpdateRange Instantiate(int range) - { - byte idx = (byte)range; - ChangeUpdateRange p = m_Cache[idx]; - - if (p == null) - { - m_Cache[idx] = p = new ChangeUpdateRange(range); - p.SetStatic(); - } - - return p; - } - } - - public sealed class ChangeCombatant : Packet - { - public ChangeCombatant(Mobile combatant) : base(0xAA, 5) - { - m_Stream.Write(combatant?.Serial ?? Serial.Zero); - } - } - - public sealed class DisplayHuePicker : Packet - { - public DisplayHuePicker(HuePicker huePicker) : base(0x95, 9) - { - m_Stream.Write(huePicker.Serial); - m_Stream.Write((short)0); - m_Stream.Write((short)huePicker.ItemID); - } - } - - public sealed class TripTimeResponse : Packet - { - public TripTimeResponse(int unk) : base(0xC9, 6) - { - m_Stream.Write((byte)unk); - m_Stream.Write(Environment.TickCount); - } - } - - public sealed class UTripTimeResponse : Packet - { - public UTripTimeResponse(int unk) : base(0xCA, 6) - { - m_Stream.Write((byte)unk); - m_Stream.Write(Environment.TickCount); - } - } - - public sealed class UnicodePrompt : Packet - { - public UnicodePrompt(Prompt prompt) : base(0xC2) - { - EnsureCapacity(21); - - m_Stream.Write(prompt.Serial); - m_Stream.Write(prompt.Serial); - m_Stream.Write(0); - m_Stream.Write(0); - m_Stream.Write((short)0); - } - } - - public sealed class ChangeCharacter : Packet - { - public ChangeCharacter(IAccount a) : base(0x81) - { - EnsureCapacity(305); - - int count = 0; - - for (int i = 0; i < a.Length; ++i) - if (a[i] != null) - ++count; - - m_Stream.Write((byte)count); - m_Stream.Write((byte)0); - - for (int i = 0; i < a.Length; ++i) - if (a[i] != null) - { - string name = a[i].Name; - - if (name == null) - name = "-null-"; - else if ((name = name.Trim()).Length == 0) - name = "-empty-"; - - m_Stream.WriteAsciiFixed(name, 30); - m_Stream.Fill(30); // password - } - else - { - m_Stream.Fill(60); - } - } - } - - public sealed class DeathStatus : Packet - { - public static readonly Packet Dead = SetStatic(new DeathStatus(true)); - public static readonly Packet Alive = SetStatic(new DeathStatus(false)); - - public DeathStatus(bool dead) : base(0x2C, 2) - { - m_Stream.Write((byte)(dead ? 0 : 2)); - } - - public static Packet Instantiate(bool dead) => dead ? Dead : Alive; - } - - public sealed class SpeedControl : Packet - { - public static readonly Packet WalkSpeed = SetStatic(new SpeedControl(2)); - public static readonly Packet MountSpeed = SetStatic(new SpeedControl(1)); - public static readonly Packet Disable = SetStatic(new SpeedControl(0)); - - public SpeedControl(int speedControl) - : base(0xBF) - { - EnsureCapacity(3); - - m_Stream.Write((short)0x26); - m_Stream.Write((byte)speedControl); - } - } - - public sealed class InvalidMapEnable : Packet - { - public InvalidMapEnable() : base(0xC6, 1) - { - } - } - - public sealed class BondedStatus : Packet - { - public BondedStatus(int val1, Serial serial, int val2) : base(0xBF) - { - EnsureCapacity(11); - - m_Stream.Write((short)0x19); - m_Stream.Write((byte)val1); - m_Stream.Write(serial); - m_Stream.Write((byte)val2); - } - } - - public sealed class ToggleSpecialAbility : Packet - { - public ToggleSpecialAbility(int abilityID, bool active) - : base(0xBF) - { - EnsureCapacity(7); - - m_Stream.Write((short)0x25); - - m_Stream.Write((short)abilityID); - m_Stream.Write(active); - } - } - - public sealed class DisplayItemListMenu : Packet - { - public DisplayItemListMenu(ItemListMenu menu) : base(0x7C) - { - EnsureCapacity(256); - - m_Stream.Write(((IMenu)menu).Serial); - m_Stream.Write((short)0); - - string question = menu.Question; - - if (question == null) - { - m_Stream.Write((byte)0); - } - else - { - int questionLength = question.Length; - m_Stream.Write((byte)questionLength); - m_Stream.WriteAsciiFixed(question, questionLength); - } - - ItemListEntry[] entries = menu.Entries; - - int entriesLength = (byte)entries.Length; - - m_Stream.Write((byte)entriesLength); - - for (int i = 0; i < entriesLength; ++i) - { - ItemListEntry e = entries[i]; - - m_Stream.Write((ushort)e.ItemID); - m_Stream.Write((short)e.Hue); - - string name = e.Name; - - if (name == null) - { - m_Stream.Write((byte)0); - } - else - { - int nameLength = name.Length; - m_Stream.Write((byte)nameLength); - m_Stream.WriteAsciiFixed(name, nameLength); - } - } - } - } - - public sealed class DisplayQuestionMenu : Packet - { - public DisplayQuestionMenu(QuestionMenu menu) : base(0x7C) - { - EnsureCapacity(256); - - m_Stream.Write(((IMenu)menu).Serial); - m_Stream.Write((short)0); - - string question = menu.Question; - - if (question == null) - { - m_Stream.Write((byte)0); - } - else - { - int questionLength = question.Length; - m_Stream.Write((byte)questionLength); - m_Stream.WriteAsciiFixed(question, questionLength); - } - - string[] answers = menu.Answers; - - int answersLength = (byte)answers.Length; - - m_Stream.Write((byte)answersLength); - - for (int i = 0; i < answersLength; ++i) - { - m_Stream.Write(0); - - string answer = answers[i]; - - if (answer == null) - { - m_Stream.Write((byte)0); - } - else - { - int answerLength = answer.Length; - m_Stream.Write((byte)answerLength); - m_Stream.WriteAsciiFixed(answer, answerLength); - } - } - } - } - - public sealed class GlobalLightLevel : Packet - { - private static GlobalLightLevel[] m_Cache = new GlobalLightLevel[0x100]; - - public GlobalLightLevel(int level) : base(0x4F, 2) - { - m_Stream.Write((sbyte)level); - } - - public static GlobalLightLevel Instantiate(int level) - { - byte lvl = (byte)level; - GlobalLightLevel p = m_Cache[lvl]; - - if (p == null) - { - m_Cache[lvl] = p = new GlobalLightLevel(level); - p.SetStatic(); - } - - return p; - } - } - - public sealed class PersonalLightLevel : Packet - { - public PersonalLightLevel(Mobile m) : this(m, m.LightLevel) - { - } - - public PersonalLightLevel(Mobile m, int level) : base(0x4E, 6) - { - m_Stream.Write(m.Serial); - m_Stream.Write((sbyte)level); - } - } - - public sealed class PersonalLightLevelZero : Packet - { - public PersonalLightLevelZero(Mobile m) : base(0x4E, 6) - { - m_Stream.Write(m.Serial); - m_Stream.Write((sbyte)0); - } - } - - [Flags] - public enum CMEFlags - { - None = 0x00, - Disabled = 0x01, - Arrow = 0x02, - Highlighted = 0x04, - Colored = 0x20 - } - - public sealed class DisplayContextMenu : Packet - { - public DisplayContextMenu(ContextMenu menu) : base(0xBF) - { - ContextMenuEntry[] entries = menu.Entries; - - int length = (byte)entries.Length; - - EnsureCapacity(12 + length * 8); - - m_Stream.Write((short)0x14); - m_Stream.Write((short)0x02); - - IEntity target = menu.Target as IEntity; - - m_Stream.Write(target?.Serial ?? Serial.MinusOne); - - m_Stream.Write((byte)length); - - Point3D p; - - if (target is Mobile) - p = target.Location; - else if (target is Item item) - p = item.GetWorldLocation(); - else - p = Point3D.Zero; - - for (int i = 0; i < length; ++i) - { - ContextMenuEntry e = entries[i]; - - m_Stream.Write(e.Number); - m_Stream.Write((short)i); - - int range = e.Range; - - if (range == -1) - range = 18; - - CMEFlags flags = e.Enabled && menu.From.InRange(p, range) ? CMEFlags.None : CMEFlags.Disabled; - - flags |= e.Flags; - - m_Stream.Write((short)flags); - } - } - } - - public sealed class DisplayContextMenuOld : Packet - { - public DisplayContextMenuOld(ContextMenu menu) : base(0xBF) - { - ContextMenuEntry[] entries = menu.Entries; - - int length = (byte)entries.Length; - - EnsureCapacity(12 + length * 8); - - m_Stream.Write((short)0x14); - m_Stream.Write((short)0x01); - - IEntity target = menu.Target as IEntity; - - m_Stream.Write(target?.Serial ?? Serial.MinusOne); - - m_Stream.Write((byte)length); - - Point3D p; - - if (target is Mobile) - p = target.Location; - else if (target is Item item) - p = item.GetWorldLocation(); - else - p = Point3D.Zero; - - for (int i = 0; i < length; ++i) - { - ContextMenuEntry e = entries[i]; - - m_Stream.Write((short)i); - m_Stream.Write((ushort)(e.Number - 3000000)); - - int range = e.Range; - - if (range == -1) - range = 18; - - CMEFlags flags = e.Enabled && menu.From.InRange(p, range) ? CMEFlags.None : CMEFlags.Disabled; - - int color = e.Color & 0xFFFF; - - if (color != 0xFFFF) - flags |= CMEFlags.Colored; - - flags |= e.Flags; - - m_Stream.Write((short)flags); - - if ((flags & CMEFlags.Colored) != 0) - m_Stream.Write((short)color); - } - } - } - - public sealed class DisplayProfile : Packet - { - public DisplayProfile(bool realSerial, Mobile m, string header, string body, string footer) : base(0xB8) - { - if (header == null) - header = ""; - - if (body == null) - body = ""; - - if (footer == null) - footer = ""; - - EnsureCapacity(12 + header.Length + footer.Length * 2 + body.Length * 2); - - m_Stream.Write(realSerial ? m.Serial : Serial.Zero); - m_Stream.WriteAsciiNull(header); - m_Stream.WriteBigUniNull(footer); - m_Stream.WriteBigUniNull(body); - } - } - - public sealed class CloseGump : Packet - { - public CloseGump(int typeID, int buttonID) : base(0xBF) - { - EnsureCapacity(13); - - m_Stream.Write((short)0x04); - m_Stream.Write(typeID); - m_Stream.Write(buttonID); - } - } - - public sealed class EquipUpdate : Packet - { - public EquipUpdate(Item item) : base(0x2E, 15) - { - Serial parentSerial; - - Mobile parent = item.Parent as Mobile; - - if (parent != null) - { - parentSerial = parent.Serial; - } - else - { - Console.WriteLine("Warning: EquipUpdate on item with !(parent is Mobile)"); - parentSerial = Serial.Zero; - } - - int hue = item.Hue; - - if (parent?.SolidHueOverride >= 0) - hue = parent.SolidHueOverride; - - m_Stream.Write(item.Serial); - m_Stream.Write((short)item.ItemID); - m_Stream.Write((byte)0); - m_Stream.Write((byte)item.Layer); - m_Stream.Write(parentSerial); - m_Stream.Write((short)hue); - } - } - - public sealed class WorldItem : Packet - { - public WorldItem(Item item) : base(0x1A) - { - EnsureCapacity(20); - - // 14 base length - // +2 - Amount - // +2 - Hue - // +1 - Flags - - uint serial = item.Serial.Value; - int itemID = item.ItemID & 0x3FFF; - int amount = item.Amount; - Point3D loc = item.Location; - int x = loc.m_X; - int y = loc.m_Y; - int hue = item.Hue; - int flags = item.GetPacketFlags(); - int direction = (int)item.Direction; - - if (amount != 0) - serial |= 0x80000000; - else - serial &= 0x7FFFFFFF; - - m_Stream.Write(serial); - - if (item is BaseMulti) - m_Stream.Write((short)(itemID | 0x4000)); - else - m_Stream.Write((short)itemID); - - if (amount != 0) m_Stream.Write((short)amount); - - x &= 0x7FFF; - - if (direction != 0) x |= 0x8000; - - m_Stream.Write((short)x); - - y &= 0x3FFF; - - if (hue != 0) y |= 0x8000; - - if (flags != 0) y |= 0x4000; - - m_Stream.Write((short)y); - - if (direction != 0) - m_Stream.Write((byte)direction); - - m_Stream.Write((sbyte)loc.m_Z); - - if (hue != 0) - m_Stream.Write((ushort)hue); - - if (flags != 0) - m_Stream.Write((byte)flags); - } - } - - public sealed class WorldItemSA : Packet - { - public WorldItemSA(Item item) : base(0xF3, 24) - { - m_Stream.Write((short)0x1); - - int itemID = item.ItemID; - - if (item is BaseMulti) - { - m_Stream.Write((byte)0x02); - - m_Stream.Write(item.Serial); - - itemID &= 0x3FFF; - - m_Stream.Write((short)itemID); - - m_Stream.Write((byte)0); - /*} else if ( ) { - m_Stream.Write( (byte) 0x01 ); - - m_Stream.Write( (int) item.Serial ); - - m_Stream.Write( (short) itemID ); - - m_Stream.Write( (byte) item.Direction );*/ - } - else - { - m_Stream.Write((byte)0x00); - - m_Stream.Write(item.Serial); - - itemID &= 0x7FFF; - - m_Stream.Write((short)itemID); - - m_Stream.Write((byte)0); - } - - int amount = item.Amount; - m_Stream.Write((short)amount); - m_Stream.Write((short)amount); - - Point3D loc = item.Location; - int x = loc.m_X & 0x7FFF; - int y = loc.m_Y & 0x3FFF; - m_Stream.Write((short)x); - m_Stream.Write((short)y); - m_Stream.Write((sbyte)loc.m_Z); - - m_Stream.Write((byte)item.Light); - m_Stream.Write((short)item.Hue); - m_Stream.Write((byte)item.GetPacketFlags()); - } - } - - public sealed class WorldItemHS : Packet - { - public WorldItemHS(Item item) : base(0xF3, 26) - { - m_Stream.Write((short)0x1); - - int itemID = item.ItemID; - - if (item is BaseMulti) - { - m_Stream.Write((byte)0x02); - - m_Stream.Write(item.Serial); - - itemID &= 0x3FFF; - - m_Stream.Write((ushort)itemID); - - m_Stream.Write((byte)0); - /*} else if ( ) { - m_Stream.Write( (byte) 0x01 ); - - m_Stream.Write( (int) item.Serial ); - - m_Stream.Write( (ushort) itemID ); - - m_Stream.Write( (byte) item.Direction );*/ - } - else - { - m_Stream.Write((byte)0x00); - - m_Stream.Write(item.Serial); - - itemID &= 0xFFFF; - - m_Stream.Write((ushort)itemID); - - m_Stream.Write((byte)0); - } - - int amount = item.Amount; - m_Stream.Write((short)amount); - m_Stream.Write((short)amount); - - Point3D loc = item.Location; - int x = loc.m_X & 0x7FFF; - int y = loc.m_Y & 0x3FFF; - m_Stream.Write((short)x); - m_Stream.Write((short)y); - m_Stream.Write((sbyte)loc.m_Z); - - m_Stream.Write((byte)item.Light); - m_Stream.Write((short)item.Hue); - m_Stream.Write((byte)item.GetPacketFlags()); - - m_Stream.Write((short)0x00); // ?? - } - } - - public sealed class LiftRej : Packet - { - public LiftRej(LRReason reason) : base(0x27, 2) - { - m_Stream.Write((byte)reason); - } - } - - public sealed class LogoutAck : Packet - { - public LogoutAck() : base(0xD1, 2) - { - m_Stream.Write((byte)0x01); - } - } - - public sealed class Weather : Packet - { - public Weather(int v1, int v2, int v3) : base(0x65, 4) - { - m_Stream.Write((byte)v1); - m_Stream.Write((byte)v2); - m_Stream.Write((byte)v3); - } - } - - public sealed class UnkD3 : Packet - { - public UnkD3(Mobile beholder, Mobile beheld) : base(0xD3) - { - EnsureCapacity(256); - - //int - //short - //short - //short - //byte - //byte - //short - //byte - //byte - //short - //short - //short - //while ( int != 0 ) - //{ - //short - //byte - //short - //} - - m_Stream.Write(beheld.Serial); - m_Stream.Write((short)beheld.Body); - m_Stream.Write((short)beheld.X); - m_Stream.Write((short)beheld.Y); - m_Stream.Write((sbyte)beheld.Z); - m_Stream.Write((byte)beheld.Direction); - m_Stream.Write((ushort)beheld.Hue); - m_Stream.Write((byte)beheld.GetPacketFlags()); - m_Stream.Write((byte)Notoriety.Compute(beholder, beheld)); - - m_Stream.Write((short)0); - m_Stream.Write((short)0); - m_Stream.Write((short)0); - - m_Stream.Write(0); - } - } - - public sealed class GQRequest : Packet - { - public GQRequest() : base(0xC3) - { - EnsureCapacity(256); - - m_Stream.Write(1); - m_Stream.Write(2); // ID - m_Stream.Write(3); // Customer ? (this) - m_Stream.Write(4); // Customer this (?) - m_Stream.Write(0); - m_Stream.Write((short)0); - m_Stream.Write((short)6); - m_Stream.Write((byte)'r'); - m_Stream.Write((byte)'e'); - m_Stream.Write((byte)'g'); - m_Stream.Write((byte)'i'); - m_Stream.Write((byte)'o'); - m_Stream.Write((byte)'n'); - m_Stream.Write(7); // Call time in seconds - m_Stream.Write((short)2); // Map (0=fel,1=tram,2=ilsh) - m_Stream.Write(8); // X - m_Stream.Write(9); // Y - m_Stream.Write(10); // Z - m_Stream.Write(11); // Volume - m_Stream.Write(12); // Rank - m_Stream.Write(-1); - m_Stream.Write(1); // type - } - } - - /// - /// Causes the client to walk in a given direction. It does not send a movement request. - /// - public sealed class PlayerMove : Packet - { - public PlayerMove(Direction d) : base(0x97, 2) - { - m_Stream.Write((byte)d); - - // @4C63B0 - } - } - - /// - /// Displays a message "There are currently [count] available calls in the global queue.". - /// - public sealed class GQCount : Packet - { - public GQCount(int unk, int count) : base(0xCB, 7) - { - m_Stream.Write((short)unk); - m_Stream.Write(count); - } - } - - /// - /// Asks the client for it's version - /// - public sealed class ClientVersionReq : Packet - { - public ClientVersionReq() : base(0xBD) - { - EnsureCapacity(3); - } - } - - /// - /// Asks the client for it's "assist version". (Perhaps for UOAssist?) - /// - public sealed class AssistVersionReq : Packet - { - public AssistVersionReq(int unk) : base(0xBE) - { - EnsureCapacity(7); - - m_Stream.Write(unk); - } - } - - public enum EffectType - { - Moving = 0x00, - Lightning = 0x01, - FixedXYZ = 0x02, - FixedFrom = 0x03 - } - - public class ParticleEffect : Packet - { - public ParticleEffect(EffectType type, Serial from, Serial to, int itemID, Point3D fromPoint, Point3D toPoint, - int speed, int duration, bool fixedDirection, bool explode, int hue, int renderMode, int effect, - int explodeEffect, int explodeSound, Serial serial, int layer, int unknown) : base(0xC7, 49) - { - m_Stream.Write((byte)type); - m_Stream.Write(from); - m_Stream.Write(to); - m_Stream.Write((short)itemID); - m_Stream.Write((short)fromPoint.m_X); - m_Stream.Write((short)fromPoint.m_Y); - m_Stream.Write((sbyte)fromPoint.m_Z); - m_Stream.Write((short)toPoint.m_X); - m_Stream.Write((short)toPoint.m_Y); - m_Stream.Write((sbyte)toPoint.m_Z); - m_Stream.Write((byte)speed); - m_Stream.Write((byte)duration); - m_Stream.Write((byte)0); - m_Stream.Write((byte)0); - m_Stream.Write(fixedDirection); - m_Stream.Write(explode); - m_Stream.Write(hue); - m_Stream.Write(renderMode); - m_Stream.Write((short)effect); - m_Stream.Write((short)explodeEffect); - m_Stream.Write((short)explodeSound); - m_Stream.Write(serial); - m_Stream.Write((byte)layer); - m_Stream.Write((short)unknown); - } - - public ParticleEffect(EffectType type, Serial from, Serial to, int itemID, IPoint3D fromPoint, IPoint3D toPoint, - int speed, int duration, bool fixedDirection, bool explode, int hue, int renderMode, int effect, - int explodeEffect, int explodeSound, Serial serial, int layer, int unknown) : base(0xC7, 49) - { - m_Stream.Write((byte)type); - m_Stream.Write(from); - m_Stream.Write(to); - m_Stream.Write((short)itemID); - m_Stream.Write((short)fromPoint.X); - m_Stream.Write((short)fromPoint.Y); - m_Stream.Write((sbyte)fromPoint.Z); - m_Stream.Write((short)toPoint.X); - m_Stream.Write((short)toPoint.Y); - m_Stream.Write((sbyte)toPoint.Z); - m_Stream.Write((byte)speed); - m_Stream.Write((byte)duration); - m_Stream.Write((byte)0); - m_Stream.Write((byte)0); - m_Stream.Write(fixedDirection); - m_Stream.Write(explode); - m_Stream.Write(hue); - m_Stream.Write(renderMode); - m_Stream.Write((short)effect); - m_Stream.Write((short)explodeEffect); - m_Stream.Write((short)explodeSound); - m_Stream.Write(serial); - m_Stream.Write((byte)layer); - m_Stream.Write((short)unknown); - } - } - - public class HuedEffect : Packet - { - public HuedEffect(EffectType type, Serial from, Serial to, int itemID, Point3D fromPoint, Point3D toPoint, int speed, - int duration, bool fixedDirection, bool explode, int hue, int renderMode) : base(0xC0, 36) - { - m_Stream.Write((byte)type); - m_Stream.Write(from); - m_Stream.Write(to); - m_Stream.Write((short)itemID); - m_Stream.Write((short)fromPoint.m_X); - m_Stream.Write((short)fromPoint.m_Y); - m_Stream.Write((sbyte)fromPoint.m_Z); - m_Stream.Write((short)toPoint.m_X); - m_Stream.Write((short)toPoint.m_Y); - m_Stream.Write((sbyte)toPoint.m_Z); - m_Stream.Write((byte)speed); - m_Stream.Write((byte)duration); - m_Stream.Write((byte)0); - m_Stream.Write((byte)0); - m_Stream.Write(fixedDirection); - m_Stream.Write(explode); - m_Stream.Write(hue); - m_Stream.Write(renderMode); - } - - public HuedEffect(EffectType type, Serial from, Serial to, int itemID, IPoint3D fromPoint, IPoint3D toPoint, - int speed, int duration, bool fixedDirection, bool explode, int hue, int renderMode) : base(0xC0, 36) - { - m_Stream.Write((byte)type); - m_Stream.Write(from); - m_Stream.Write(to); - m_Stream.Write((short)itemID); - m_Stream.Write((short)fromPoint.X); - m_Stream.Write((short)fromPoint.Y); - m_Stream.Write((sbyte)fromPoint.Z); - m_Stream.Write((short)toPoint.X); - m_Stream.Write((short)toPoint.Y); - m_Stream.Write((sbyte)toPoint.Z); - m_Stream.Write((byte)speed); - m_Stream.Write((byte)duration); - m_Stream.Write((byte)0); - m_Stream.Write((byte)0); - m_Stream.Write(fixedDirection); - m_Stream.Write(explode); - m_Stream.Write(hue); - m_Stream.Write(renderMode); - } - } - - public sealed class TargetParticleEffect : ParticleEffect - { - public TargetParticleEffect(IEntity e, int itemID, int speed, int duration, int hue, int renderMode, int effect, - int layer, int unknown) : base(EffectType.FixedFrom, e.Serial, Serial.Zero, itemID, e.Location, e.Location, - speed, duration, true, false, hue, renderMode, effect, 1, 0, e.Serial, layer, unknown) - { - } - } - - public sealed class TargetEffect : HuedEffect - { - public TargetEffect(IEntity e, int itemID, int speed, int duration, int hue, int renderMode) : base( - EffectType.FixedFrom, e.Serial, Serial.Zero, itemID, e.Location, e.Location, speed, duration, true, false, hue, - renderMode) - { - } - } - - public sealed class LocationParticleEffect : ParticleEffect - { - public LocationParticleEffect(IEntity e, int itemID, int speed, int duration, int hue, int renderMode, int effect, - int unknown) : base(EffectType.FixedXYZ, e.Serial, Serial.Zero, itemID, e.Location, e.Location, speed, duration, - true, false, hue, renderMode, effect, 1, 0, e.Serial, 255, unknown) - { - } - } - - public sealed class LocationEffect : HuedEffect - { - public LocationEffect(IPoint3D p, int itemID, int speed, int duration, int hue, int renderMode) : base( - EffectType.FixedXYZ, Serial.Zero, Serial.Zero, itemID, p, p, speed, duration, true, false, hue, renderMode) - { - } - } - - public sealed class MovingParticleEffect : ParticleEffect - { - public MovingParticleEffect(IEntity from, IEntity to, int itemID, int speed, int duration, bool fixedDirection, - bool explodes, int hue, int renderMode, int effect, int explodeEffect, int explodeSound, EffectLayer layer, - int unknown) : base(EffectType.Moving, from.Serial, to.Serial, itemID, from.Location, to.Location, speed, - duration, fixedDirection, explodes, hue, renderMode, effect, explodeEffect, explodeSound, Serial.Zero, - (int)layer, unknown) - { - } - } - - public sealed class MovingEffect : HuedEffect - { - public MovingEffect(IEntity from, IEntity to, int itemID, int speed, int duration, bool fixedDirection, - bool explodes, int hue, int renderMode) : base(EffectType.Moving, from.Serial, to.Serial, itemID, from.Location, - to.Location, speed, duration, fixedDirection, explodes, hue, renderMode) - { - } - } - - public enum ScreenEffectType - { - FadeOut = 0x00, - FadeIn = 0x01, - LightFlash = 0x02, - FadeInOut = 0x03, - DarkFlash = 0x04 - } - - public class ScreenEffect : Packet - { - public ScreenEffect(ScreenEffectType type) - : base(0x70, 28) - { - m_Stream.Write((byte)0x04); - m_Stream.Fill(8); - m_Stream.Write((short)type); - m_Stream.Fill(16); - } - } - - public sealed class ScreenFadeOut : ScreenEffect - { - public static readonly Packet Instance = SetStatic(new ScreenFadeOut()); - - public ScreenFadeOut() - : base(ScreenEffectType.FadeOut) - { - } - } - - public sealed class ScreenFadeIn : ScreenEffect - { - public static readonly Packet Instance = SetStatic(new ScreenFadeIn()); - - public ScreenFadeIn() - : base(ScreenEffectType.FadeIn) - { - } - } - - public sealed class ScreenFadeInOut : ScreenEffect - { - public static readonly Packet Instance = SetStatic(new ScreenFadeInOut()); - - public ScreenFadeInOut() - : base(ScreenEffectType.FadeInOut) - { - } - } - - public sealed class ScreenLightFlash : ScreenEffect - { - public static readonly Packet Instance = SetStatic(new ScreenLightFlash()); - - public ScreenLightFlash() - : base(ScreenEffectType.LightFlash) - { - } - } - - public sealed class ScreenDarkFlash : ScreenEffect - { - public static readonly Packet Instance = SetStatic(new ScreenDarkFlash()); - - public ScreenDarkFlash() - : base(ScreenEffectType.DarkFlash) - { - } - } - - public enum DeleteResultType - { - PasswordInvalid, - CharNotExist, - CharBeingPlayed, - CharTooYoung, - CharQueued, - BadRequest - } - - public sealed class DeleteResult : Packet - { - public DeleteResult(DeleteResultType res) : base(0x85, 2) - { - m_Stream.Write((byte)res); - } - } - - /*public sealed class MovingEffect : Packet - { - public MovingEffect( IEntity from, IEntity to, int itemID, int speed, int duration, bool fixedDirection, bool turn, int hue, int renderMode ) : base( 0xC0, 36 ) - { - m_Stream.Write( (byte) 0x00 ); - m_Stream.Write( (int) from.Serial ); - m_Stream.Write( (int) to.Serial ); - m_Stream.Write( (short) itemID ); - m_Stream.Write( (short) from.Location.m_X ); - m_Stream.Write( (short) from.Location.m_Y ); - m_Stream.Write( (sbyte) from.Location.m_Z ); - m_Stream.Write( (short) to.Location.m_X ); - m_Stream.Write( (short) to.Location.m_Y ); - m_Stream.Write( (sbyte) to.Location.m_Z ); - m_Stream.Write( (byte) speed ); - m_Stream.Write( (byte) duration ); - m_Stream.Write( (byte) 0 ); - m_Stream.Write( (byte) 0 ); - m_Stream.Write( (bool) fixedDirection ); - m_Stream.Write( (bool) turn ); - m_Stream.Write( (int) hue ); - m_Stream.Write( (int) renderMode ); - } - }*/ - - /*public sealed class LocationEffect : Packet - { - public LocationEffect( IPoint3D p, int itemID, int duration, int hue, int renderMode ) : base( 0xC0, 36 ) - { - m_Stream.Write( (byte) 0x02 ); - m_Stream.Write( (int) Serial.Zero ); - m_Stream.Write( (int) Serial.Zero ); - m_Stream.Write( (short) itemID ); - m_Stream.Write( (short) p.X ); - m_Stream.Write( (short) p.Y ); - m_Stream.Write( (sbyte) p.Z ); - m_Stream.Write( (short) p.X ); - m_Stream.Write( (short) p.Y ); - m_Stream.Write( (sbyte) p.Z ); - m_Stream.Write( (byte) 10 ); - m_Stream.Write( (byte) duration ); - m_Stream.Write( (byte) 0 ); - m_Stream.Write( (byte) 0 ); - m_Stream.Write( (byte) 1 ); - m_Stream.Write( (byte) 0 ); - m_Stream.Write( (int) hue ); - m_Stream.Write( (int) renderMode ); - } - }*/ - - public sealed class BoltEffect : Packet - { - public BoltEffect(IEntity target, int hue) : base(0xC0, 36) - { - m_Stream.Write((byte)0x01); // type - m_Stream.Write(target.Serial); - m_Stream.Write(Serial.Zero); - m_Stream.Write((short)0); // itemID - m_Stream.Write((short)target.X); - m_Stream.Write((short)target.Y); - m_Stream.Write((sbyte)target.Z); - m_Stream.Write((short)target.X); - m_Stream.Write((short)target.Y); - m_Stream.Write((sbyte)target.Z); - m_Stream.Write((byte)0); // speed - m_Stream.Write((byte)0); // duration - m_Stream.Write((short)0); // unk - m_Stream.Write(false); // fixed direction - m_Stream.Write(false); // explode - m_Stream.Write(hue); - m_Stream.Write(0); // render mode - } - } - - public sealed class DisplaySpellbook : Packet - { - public DisplaySpellbook(Item book) : base(0x24, 7) - { - m_Stream.Write(book.Serial); - m_Stream.Write((short)-1); - } - } - - public sealed class DisplaySpellbookHS : Packet - { - public DisplaySpellbookHS(Item book) : base(0x24, 9) - { - m_Stream.Write(book.Serial); - m_Stream.Write((short)-1); - m_Stream.Write((short)0x7D); - } - } - - public sealed class NewSpellbookContent : Packet - { - public NewSpellbookContent(Item item, int graphic, int offset, ulong content) : base(0xBF) - { - EnsureCapacity(23); - - m_Stream.Write((short)0x1B); - m_Stream.Write((short)0x01); - - m_Stream.Write(item.Serial); - m_Stream.Write((short)graphic); - m_Stream.Write((short)offset); - - for (int i = 0; i < 8; ++i) - m_Stream.Write((byte)(content >> i * 8)); - } - } - - public sealed class SpellbookContent : Packet - { - public SpellbookContent(int count, int offset, ulong content, Item item) : base(0x3C) - { - EnsureCapacity(5 + count * 19); - - int written = 0; - - m_Stream.Write((ushort)0); - - ulong mask = 1; - - for (int i = 0; i < 64; ++i, mask <<= 1) - if ((content & mask) != 0) - { - m_Stream.Write(0x7FFFFFFF - i); - m_Stream.Write((ushort)0); - m_Stream.Write((byte)0); - m_Stream.Write((ushort)(i + offset)); - m_Stream.Write((short)0); - m_Stream.Write((short)0); - m_Stream.Write(item.Serial); - m_Stream.Write((short)0); - - ++written; - } - - m_Stream.Seek(3, SeekOrigin.Begin); - m_Stream.Write((ushort)written); - } - } - - public sealed class SpellbookContent6017 : Packet - { - public SpellbookContent6017(int count, int offset, ulong content, Item item) : base(0x3C) - { - EnsureCapacity(5 + count * 20); - - int written = 0; - - m_Stream.Write((ushort)0); - - ulong mask = 1; - - for (int i = 0; i < 64; ++i, mask <<= 1) - if ((content & mask) != 0) - { - m_Stream.Write(0x7FFFFFFF - i); - m_Stream.Write((ushort)0); - m_Stream.Write((byte)0); - m_Stream.Write((ushort)(i + offset)); - m_Stream.Write((short)0); - m_Stream.Write((short)0); - m_Stream.Write((byte)0); // Grid Location? - m_Stream.Write(item.Serial); - m_Stream.Write((short)0); - - ++written; - } - - m_Stream.Seek(3, SeekOrigin.Begin); - m_Stream.Write((ushort)written); - } - } - - public sealed class ContainerDisplay : Packet - { - public ContainerDisplay(Container c) : base(0x24, 7) - { - m_Stream.Write(c.Serial); - m_Stream.Write((short)c.GumpID); - } - } - - public sealed class ContainerDisplayHS : Packet - { - public ContainerDisplayHS(Container c) : base(0x24, 9) - { - m_Stream.Write(c.Serial); - m_Stream.Write((short)c.GumpID); - m_Stream.Write((short)0x7D); - } - } - - public sealed class ContainerContentUpdate : Packet - { - public ContainerContentUpdate(Item item) : base(0x25, 20) - { - Serial parentSerial; - - if (item.Parent is Item parentItem) - { - parentSerial = parentItem.Serial; - } - else - { - Console.WriteLine("Warning: ContainerContentUpdate on item with !(parent is Item)"); - parentSerial = Serial.Zero; - } - - m_Stream.Write(item.Serial); - m_Stream.Write((ushort)item.ItemID); - m_Stream.Write((byte)0); // signed, itemID offset - m_Stream.Write((ushort)item.Amount); - m_Stream.Write((short)item.X); - m_Stream.Write((short)item.Y); - m_Stream.Write(parentSerial); - m_Stream.Write((ushort)(item.QuestItem ? Item.QuestItemHue : item.Hue)); - } - } - - public sealed class ContainerContentUpdate6017 : Packet - { - public ContainerContentUpdate6017(Item item) : base(0x25, 21) - { - Serial parentSerial; - - if (item.Parent is Item parentItem) - { - parentSerial = parentItem.Serial; - } - else - { - Console.WriteLine("Warning: ContainerContentUpdate on item with !(parent is Item)"); - parentSerial = Serial.Zero; - } - - m_Stream.Write(item.Serial); - m_Stream.Write((ushort)item.ItemID); - m_Stream.Write((byte)0); // signed, itemID offset - m_Stream.Write((ushort)item.Amount); - m_Stream.Write((short)item.X); - m_Stream.Write((short)item.Y); - m_Stream.Write((byte)0); // Grid Location? - m_Stream.Write(parentSerial); - m_Stream.Write((ushort)(item.QuestItem ? Item.QuestItemHue : item.Hue)); - } - } - - public sealed class ContainerContent : Packet - { - public ContainerContent(Mobile beholder, Item beheld) : base(0x3C) - { - List items = beheld.Items; - int count = items.Count; - - EnsureCapacity(5 + count * 19); - - long pos = m_Stream.Position; - - int written = 0; - - m_Stream.Write((ushort)0); - - for (int i = 0; i < count; ++i) - { - Item child = items[i]; - - if (!child.Deleted && beholder.CanSee(child)) - { - Point3D loc = child.Location; - - m_Stream.Write(child.Serial); - m_Stream.Write((ushort)child.ItemID); - m_Stream.Write((byte)0); // signed, itemID offset - m_Stream.Write((ushort)child.Amount); - m_Stream.Write((short)loc.m_X); - m_Stream.Write((short)loc.m_Y); - m_Stream.Write(beheld.Serial); - m_Stream.Write((ushort)(child.QuestItem ? Item.QuestItemHue : child.Hue)); - - ++written; - } - } - - m_Stream.Seek(pos, SeekOrigin.Begin); - m_Stream.Write((ushort)written); - } - } - - public sealed class ContainerContent6017 : Packet - { - public ContainerContent6017(Mobile beholder, Item beheld) : base(0x3C) - { - List items = beheld.Items; - int count = items.Count; - - EnsureCapacity(5 + count * 20); - - long pos = m_Stream.Position; - - int written = 0; - - m_Stream.Write((ushort)0); - - for (int i = 0; i < count; ++i) - { - Item child = items[i]; - - if (!child.Deleted && beholder.CanSee(child)) - { - Point3D loc = child.Location; - - m_Stream.Write(child.Serial); - m_Stream.Write((ushort)child.ItemID); - m_Stream.Write((byte)0); // signed, itemID offset - m_Stream.Write((ushort)child.Amount); - m_Stream.Write((short)loc.m_X); - m_Stream.Write((short)loc.m_Y); - m_Stream.Write((byte)0); // Grid Location? - m_Stream.Write(beheld.Serial); - m_Stream.Write((ushort)(child.QuestItem ? Item.QuestItemHue : child.Hue)); - - ++written; - } - } - - m_Stream.Seek(pos, SeekOrigin.Begin); - m_Stream.Write((ushort)written); - } - } - - public sealed class SetWarMode : Packet - { - public static readonly Packet InWarMode = SetStatic(new SetWarMode(true)); - public static readonly Packet InPeaceMode = SetStatic(new SetWarMode(false)); - - public SetWarMode(bool mode) : base(0x72, 5) - { - m_Stream.Write(mode); - m_Stream.Write((byte)0x00); - m_Stream.Write((byte)0x32); - m_Stream.Write((byte)0x00); - //m_Stream.Fill(); - } - - public static Packet Instantiate(bool mode) => mode ? InWarMode : InPeaceMode; - } - - public sealed class Swing : Packet - { - public Swing(int flag, Mobile attacker, Mobile defender) : base(0x2F, 10) - { - m_Stream.Write((byte)flag); - m_Stream.Write(attacker.Serial); - m_Stream.Write(defender.Serial); - } - } - - public sealed class NullFastwalkStack : Packet - { - public NullFastwalkStack() : base(0xBF) - { - EnsureCapacity(256); - m_Stream.Write((short)0x1); - m_Stream.Write(0x0); - m_Stream.Write(0x0); - m_Stream.Write(0x0); - m_Stream.Write(0x0); - m_Stream.Write(0x0); - m_Stream.Write(0x0); - } - } - - public sealed class RemoveEntity : Packet - { - public RemoveEntity(IEntity entity) : base(0x1D, 5) - { - m_Stream.Write(entity.Serial); - } - } - - public sealed class ServerChange : Packet - { - public ServerChange(Mobile m, Map map) : base(0x76, 16) - { - m_Stream.Write((short)m.X); - m_Stream.Write((short)m.Y); - m_Stream.Write((short)m.Z); - m_Stream.Write((byte)0); - m_Stream.Write((short)0); - m_Stream.Write((short)0); - m_Stream.Write((short)map.Width); - m_Stream.Write((short)map.Height); - } - } - - public sealed class SkillUpdate : Packet - { - public SkillUpdate(Skills skills) : base(0x3A) - { - EnsureCapacity(6 + skills.Length * 9); - - m_Stream.Write((byte)0x02); // type: absolute, capped - - for (int i = 0; i < skills.Length; ++i) - { - Skill s = skills[i]; - - double v = s.NonRacialValue; - int uv = (int)(v * 10); - - if (uv < 0) - uv = 0; - else if (uv >= 0x10000) - uv = 0xFFFF; - - m_Stream.Write((ushort)(s.Info.SkillID + 1)); - m_Stream.Write((ushort)uv); - m_Stream.Write((ushort)s.BaseFixedPoint); - m_Stream.Write((byte)s.Lock); - m_Stream.Write((ushort)s.CapFixedPoint); - } - - m_Stream.Write((short)0); // terminate - } - } - - public sealed class Sequence : Packet - { - public Sequence(int num) : base(0x7B, 2) - { - m_Stream.Write((byte)num); - } - } - - public sealed class SkillChange : Packet - { - public SkillChange(Skill skill) : base(0x3A) - { - EnsureCapacity(13); - - double v = skill.NonRacialValue; - int uv = (int)(v * 10); - - if (uv < 0) - uv = 0; - else if (uv >= 0x10000) - uv = 0xFFFF; - - m_Stream.Write((byte)0xDF); // type: delta, capped - m_Stream.Write((ushort)skill.Info.SkillID); - m_Stream.Write((ushort)uv); - m_Stream.Write((ushort)skill.BaseFixedPoint); - m_Stream.Write((byte)skill.Lock); - m_Stream.Write((ushort)skill.CapFixedPoint); - - /*m_Stream.Write( (short) skill.Info.SkillID ); - m_Stream.Write( (short) (skill.Value * 10.0) ); - m_Stream.Write( (short) (skill.Base * 10.0) ); - m_Stream.Write( (byte) skill.Lock ); - m_Stream.Write( (short) skill.CapFixedPoint );*/ - } - } - - public sealed class LaunchBrowser : Packet - { - public LaunchBrowser(string url) : base(0xA5) - { - if (url == null) url = ""; - - EnsureCapacity(4 + url.Length); - - m_Stream.WriteAsciiNull(url); - } - } - - public sealed class MessageLocalized : Packet - { - private static MessageLocalized[] m_Cache_IntLoc = new MessageLocalized[15000]; - private static MessageLocalized[] m_Cache_CliLoc = new MessageLocalized[100000]; - private static MessageLocalized[] m_Cache_CliLocCmp = new MessageLocalized[5000]; - - public MessageLocalized(Serial serial, int graphic, MessageType type, int hue, int font, int number, string name, - string args) : base(0xC1) - { - if (name == null) name = ""; - if (args == null) args = ""; - - if (hue == 0) - hue = 0x3B2; - - EnsureCapacity(50 + args.Length * 2); - - m_Stream.Write(serial); - m_Stream.Write((short)graphic); - m_Stream.Write((byte)type); - m_Stream.Write((short)hue); - m_Stream.Write((short)font); - m_Stream.Write(number); - m_Stream.WriteAsciiFixed(name, 30); - m_Stream.WriteLittleUniNull(args); - } - - public static MessageLocalized InstantiateGeneric(int number) - { - MessageLocalized[] cache = null; - int index = 0; - - if (number >= 3000000) - { - cache = m_Cache_IntLoc; - index = number - 3000000; - } - else if (number >= 1000000) - { - cache = m_Cache_CliLoc; - index = number - 1000000; - } - else if (number >= 500000) - { - cache = m_Cache_CliLocCmp; - index = number - 500000; - } - - MessageLocalized p; - - if (cache != null && index >= 0 && index < cache.Length) - { - p = cache[index]; - - if (p == null) - { - cache[index] = p = new MessageLocalized(Serial.MinusOne, -1, MessageType.Regular, 0x3B2, 3, number, - "System", ""); - p.SetStatic(); - } - } - else - { - p = new MessageLocalized(Serial.MinusOne, -1, MessageType.Regular, 0x3B2, 3, number, "System", ""); - } - - return p; - } - } - - public sealed class MobileMoving : Packet - { - public MobileMoving(Mobile m, int noto) : base(0x77, 17) - { - Point3D loc = m.Location; - - int hue = m.Hue; - - if (m.SolidHueOverride >= 0) - hue = m.SolidHueOverride; - - m_Stream.Write(m.Serial); - m_Stream.Write((short)m.Body); - m_Stream.Write((short)loc.m_X); - m_Stream.Write((short)loc.m_Y); - m_Stream.Write((sbyte)loc.m_Z); - m_Stream.Write((byte)m.Direction); - m_Stream.Write((short)hue); - m_Stream.Write((byte)m.GetPacketFlags()); - m_Stream.Write((byte)noto); - } - } - - // Pre-7.0.0.0 Mobile Moving - public sealed class MobileMovingOld : Packet - { - public MobileMovingOld(Mobile m, int noto) : base(0x77, 17) - { - Point3D loc = m.Location; - - int hue = m.Hue; - - if (m.SolidHueOverride >= 0) - hue = m.SolidHueOverride; - - m_Stream.Write(m.Serial); - m_Stream.Write((short)m.Body); - m_Stream.Write((short)loc.m_X); - m_Stream.Write((short)loc.m_Y); - m_Stream.Write((sbyte)loc.m_Z); - m_Stream.Write((byte)m.Direction); - m_Stream.Write((short)hue); - m_Stream.Write((byte)m.GetOldPacketFlags()); - m_Stream.Write((byte)noto); - } - } - - public sealed class MultiTargetReqHS : Packet - { - public MultiTargetReqHS(MultiTarget t) : base(0x99, 30) - { - m_Stream.Write(t.AllowGround); - m_Stream.Write(t.TargetID); - m_Stream.Write((byte)t.Flags); - - m_Stream.Fill(); - - m_Stream.Seek(18, SeekOrigin.Begin); - m_Stream.Write((short)t.MultiID); - m_Stream.Write((short)t.Offset.X); - m_Stream.Write((short)t.Offset.Y); - m_Stream.Write((short)t.Offset.Z); - - // DWORD Hue - } - } - - public sealed class MultiTargetReq : Packet - { - public MultiTargetReq(MultiTarget t) : base(0x99, 26) - { - m_Stream.Write(t.AllowGround); - m_Stream.Write(t.TargetID); - m_Stream.Write((byte)t.Flags); - - m_Stream.Fill(); - - m_Stream.Seek(18, SeekOrigin.Begin); - m_Stream.Write((short)t.MultiID); - m_Stream.Write((short)t.Offset.X); - m_Stream.Write((short)t.Offset.Y); - m_Stream.Write((short)t.Offset.Z); - } - } - - public sealed class CancelTarget : Packet - { - public static readonly Packet Instance = SetStatic(new CancelTarget()); - - public CancelTarget() : base(0x6C, 19) - { - m_Stream.Write((byte)0); - m_Stream.Write(0); - m_Stream.Write((byte)3); - m_Stream.Fill(); - } - } - - public sealed class TargetReq : Packet - { - public TargetReq(Target t) : base(0x6C, 19) - { - m_Stream.Write(t.AllowGround); - m_Stream.Write(t.TargetID); - m_Stream.Write((byte)t.Flags); - m_Stream.Fill(); - } - } - - public sealed class DragEffect : Packet - { - public DragEffect(IEntity src, IEntity trg, int itemID, int hue, int amount) : base(0x23, 26) - { - m_Stream.Write((short)itemID); - m_Stream.Write((byte)0); - m_Stream.Write((short)hue); - m_Stream.Write((short)amount); - m_Stream.Write(src.Serial); - m_Stream.Write((short)src.X); - m_Stream.Write((short)src.Y); - m_Stream.Write((sbyte)src.Z); - m_Stream.Write(trg.Serial); - m_Stream.Write((short)trg.X); - m_Stream.Write((short)trg.Y); - m_Stream.Write((sbyte)trg.Z); - } - } - - public interface IGumpWriter - { - int TextEntries{ get; set; } - int Switches{ get; set; } - - void AppendLayout(bool val); - void AppendLayout(int val); - void AppendLayout(uint val); - void AppendLayoutNS(int val); - void AppendLayout(string text); - void AppendLayout(byte[] buffer); - void WriteStrings(List strings); - void Flush(); - } - - public sealed class DisplayGumpPacked : Packet, IGumpWriter - { - private static byte[] m_True = Gump.StringToBuffer(" 1"); - private static byte[] m_False = Gump.StringToBuffer(" 0"); - - private static byte[] m_BeginTextSeparator = Gump.StringToBuffer(" @"); - private static byte[] m_EndTextSeparator = Gump.StringToBuffer("@"); - - private static byte[] m_Buffer = new byte[48]; - - private Gump m_Gump; - - private PacketWriter m_Layout; - - private int m_StringCount; - private PacketWriter m_Strings; - - static DisplayGumpPacked() => m_Buffer[0] = (byte)' '; - - public DisplayGumpPacked(Gump gump) - : base(0xDD) - { - m_Gump = gump; - - m_Layout = PacketWriter.CreateInstance(8192); - m_Strings = PacketWriter.CreateInstance(8192); - } - - public int TextEntries{ get; set; } - - public int Switches{ get; set; } - - public void AppendLayout(bool val) - { - AppendLayout(val ? m_True : m_False); - } - - public void AppendLayout(int val) - { - string toString = val.ToString(); - int bytes = Encoding.ASCII.GetBytes(toString, 0, toString.Length, m_Buffer, 1) + 1; - - m_Layout.Write(m_Buffer, 0, bytes); - } - - public void AppendLayout(uint val) - { - string toString = val.ToString(); - int bytes = Encoding.ASCII.GetBytes(toString, 0, toString.Length, m_Buffer, 1) + 1; - - m_Layout.Write(m_Buffer, 0, bytes); - } - - public void AppendLayoutNS(int val) - { - string toString = val.ToString(); - int bytes = Encoding.ASCII.GetBytes(toString, 0, toString.Length, m_Buffer, 1); - - m_Layout.Write(m_Buffer, 1, bytes); - } - - public void AppendLayout(string text) - { - AppendLayout(m_BeginTextSeparator); - - m_Layout.WriteAsciiFixed(text, text.Length); - - AppendLayout(m_EndTextSeparator); - } - - public void AppendLayout(byte[] buffer) - { - m_Layout.Write(buffer, 0, buffer.Length); - } - - public void WriteStrings(List strings) - { - m_StringCount = strings.Count; - - for (int i = 0; i < strings.Count; ++i) - { - string v = strings[i] ?? ""; - - m_Strings.Write((ushort)v.Length); - m_Strings.WriteBigUniFixed(v, v.Length); - } - } - - public void Flush() - { - EnsureCapacity(28 + (int)m_Layout.Length + (int)m_Strings.Length); - - m_Stream.Write(m_Gump.Serial); - m_Stream.Write(m_Gump.TypeID); - m_Stream.Write(m_Gump.X); - m_Stream.Write(m_Gump.Y); - - // Note: layout MUST be null terminated (don't listen to krrios) - m_Layout.Write((byte)0); - WritePacked(m_Layout); - - m_Stream.Write(m_StringCount); - - WritePacked(m_Strings); - - PacketWriter.ReleaseInstance(m_Layout); - PacketWriter.ReleaseInstance(m_Strings); - } - - private void WritePacked(PacketWriter src) - { - byte[] buffer = src.UnderlyingStream.GetBuffer(); - int length = (int)src.Length; - - if (length == 0) - { - m_Stream.Write(0); - return; - } - - int wantLength = 1 + buffer.Length * 1024 / 1000; - - wantLength += 4095; - wantLength &= ~4095; - - byte[] packBuffer = ArrayPool.Shared.Rent(wantLength); - - int packLength = wantLength; - - Compression.Pack(packBuffer, ref packLength, buffer, length, ZLibQuality.Default); - - m_Stream.Write(4 + packLength); - m_Stream.Write(length); - m_Stream.Write(packBuffer, 0, packLength); - - ArrayPool.Shared.Return(packBuffer); - } - } - - public sealed class DisplayGumpFast : Packet, IGumpWriter - { - private static byte[] m_True = Gump.StringToBuffer(" 1"); - private static byte[] m_False = Gump.StringToBuffer(" 0"); - - private static byte[] m_BeginTextSeparator = Gump.StringToBuffer(" @"); - private static byte[] m_EndTextSeparator = Gump.StringToBuffer("@"); - - private byte[] m_Buffer = new byte[48]; - private int m_LayoutLength; - - public DisplayGumpFast(Gump g) : base(0xB0) - { - m_Buffer[0] = (byte)' '; - - EnsureCapacity(4096); - - m_Stream.Write(g.Serial); - m_Stream.Write(g.TypeID); - m_Stream.Write(g.X); - m_Stream.Write(g.Y); - m_Stream.Write((ushort)0xFFFF); - } - - public int TextEntries{ get; set; } - - public int Switches{ get; set; } - - public void AppendLayout(bool val) - { - AppendLayout(val ? m_True : m_False); - } - - public void AppendLayout(int val) - { - string toString = val.ToString(); - int bytes = Encoding.ASCII.GetBytes(toString, 0, toString.Length, m_Buffer, 1) + 1; - - m_Stream.Write(m_Buffer, 0, bytes); - m_LayoutLength += bytes; - } - - public void AppendLayout(uint val) - { - string toString = val.ToString(); - int bytes = Encoding.ASCII.GetBytes(toString, 0, toString.Length, m_Buffer, 1) + 1; - - m_Stream.Write(m_Buffer, 0, bytes); - m_LayoutLength += bytes; - } - - public void AppendLayoutNS(int val) - { - string toString = val.ToString(); - int bytes = Encoding.ASCII.GetBytes(toString, 0, toString.Length, m_Buffer, 1); - - m_Stream.Write(m_Buffer, 1, bytes); - m_LayoutLength += bytes; - } - - public void AppendLayout(string text) - { - AppendLayout(m_BeginTextSeparator); - - int length = text.Length; - m_Stream.WriteAsciiFixed(text, length); - m_LayoutLength += length; - - AppendLayout(m_EndTextSeparator); - } - - public void AppendLayout(byte[] buffer) - { - int length = buffer.Length; - m_Stream.Write(buffer, 0, length); - m_LayoutLength += length; - } - - public void WriteStrings(List text) - { - m_Stream.Seek(19, SeekOrigin.Begin); - m_Stream.Write((ushort)m_LayoutLength); - m_Stream.Seek(0, SeekOrigin.End); - - m_Stream.Write((ushort)text.Count); - - for (int i = 0; i < text.Count; ++i) - { - string v = text[i] ?? ""; - - int length = (ushort)v.Length; - - m_Stream.Write((ushort)length); - m_Stream.WriteBigUniFixed(v, length); - } - } - - public void Flush() - { - } - } - - public sealed class DisplayGump : Packet - { - public DisplayGump(Gump g, string layout, string[] text) : base(0xB0) - { - if (layout == null) layout = ""; - - EnsureCapacity(256); - - m_Stream.Write(g.Serial); - m_Stream.Write(g.TypeID); - m_Stream.Write(g.X); - m_Stream.Write(g.Y); - m_Stream.Write((ushort)(layout.Length + 1)); - m_Stream.WriteAsciiNull(layout); - - m_Stream.Write((ushort)text.Length); - - for (int i = 0; i < text.Length; ++i) - { - string v = text[i] ?? ""; - - ushort length = (ushort)v.Length; - - m_Stream.Write(length); - m_Stream.WriteBigUniFixed(v, length); - } - } - } - - public sealed class DisplayPaperdoll : Packet - { - public DisplayPaperdoll(Mobile m, string text, bool canLift) : base(0x88, 66) - { - byte flags = 0x00; - - if (m.Warmode) - flags |= 0x01; - - if (canLift) - flags |= 0x02; - - m_Stream.Write(m.Serial); - m_Stream.WriteAsciiFixed(text, 60); - m_Stream.Write(flags); - } - } - - public sealed class PopupMessage : Packet - { - public PopupMessage(PMMessage msg) : base(0x53, 2) - { - m_Stream.Write((byte)msg); - } - } - - public sealed class PlaySound : Packet - { - public PlaySound(int soundID, IPoint3D target) : base(0x54, 12) - { - m_Stream.Write((byte)1); // flags - m_Stream.Write((short)soundID); - m_Stream.Write((short)0); // volume - m_Stream.Write((short)target.X); - m_Stream.Write((short)target.Y); - m_Stream.Write((short)target.Z); - } - } - - public sealed class PlayMusic : Packet - { - public static readonly Packet InvalidInstance = SetStatic(new PlayMusic(MusicName.Invalid)); - - private static Packet[] m_Instances = new Packet[60]; - - public PlayMusic(MusicName name) : base(0x6D, 3) - { - m_Stream.Write((short)name); - } - - public static Packet GetInstance(MusicName name) - { - if (name == MusicName.Invalid) - return InvalidInstance; - - int v = (int)name; - Packet p; - - if (v >= 0 && v < m_Instances.Length) - { - p = m_Instances[v]; - - if (p == null) - m_Instances[v] = p = SetStatic(new PlayMusic(name)); - } - else - { - p = new PlayMusic(name); - } - - return p; - } - } - - public sealed class ScrollMessage : Packet - { - public ScrollMessage(int type, int tip, string text) : base(0xA6) - { - if (text == null) text = ""; - - EnsureCapacity(10 + text.Length); - - m_Stream.Write((byte)type); - m_Stream.Write(tip); - m_Stream.Write((ushort)text.Length); - m_Stream.WriteAsciiFixed(text, text.Length); - } - } - - public sealed class CurrentTime : Packet - { - public CurrentTime() : base(0x5B, 4) - { - DateTime now = DateTime.UtcNow; - - m_Stream.Write((byte)now.Hour); - m_Stream.Write((byte)now.Minute); - m_Stream.Write((byte)now.Second); - } - } - - public sealed class MapChange : Packet - { - public MapChange(Mobile m) : base(0xBF) - { - EnsureCapacity(6); - - m_Stream.Write((short)0x08); - m_Stream.Write((byte)(m.Map?.MapID ?? 0)); - } - } - - public sealed class SeasonChange : Packet - { - private static SeasonChange[][] m_Cache = new SeasonChange[][] - { - new SeasonChange[2], - new SeasonChange[2], - new SeasonChange[2], - new SeasonChange[2], - new SeasonChange[2] - }; - - public SeasonChange(int season, bool playSound = true) : base(0xBC, 3) - { - m_Stream.Write((byte)season); - m_Stream.Write(playSound); - } - - public static SeasonChange Instantiate(int season) => Instantiate(season, true); - - public static SeasonChange Instantiate(int season, bool playSound) - { - if (season >= 0 && season < m_Cache.Length) - { - int idx = playSound ? 1 : 0; - - SeasonChange p = m_Cache[season][idx]; - - if (p == null) - { - m_Cache[season][idx] = p = new SeasonChange(season, playSound); - p.SetStatic(); - } - - return p; - } - - return new SeasonChange(season, playSound); - } - } - - public sealed class SupportedFeatures : Packet - { - public SupportedFeatures(NetState ns) : base(0xB9, ns.ExtendedSupportedFeatures ? 5 : 3) - { - FeatureFlags flags = ExpansionInfo.CoreExpansion.SupportedFeatures; - - flags |= Value; - - if (ns.Account is IAccount acct && acct.Limit >= 6) - { - flags |= FeatureFlags.LiveAccount; - flags &= ~FeatureFlags.UOTD; - - if (acct.Limit > 6) - flags |= FeatureFlags.SeventhCharacterSlot; - else - flags |= FeatureFlags.SixthCharacterSlot; - } - - if (ns.ExtendedSupportedFeatures) - m_Stream.Write((uint)flags); - else - m_Stream.Write((ushort)flags); - } - - public static FeatureFlags Value{ get; set; } - - public static SupportedFeatures Instantiate(NetState ns) => new SupportedFeatures(ns); - } - - public static class AttributeNormalizer - { - public static int Maximum{ get; set; } = 25; - - public static bool Enabled{ get; set; } = true; - - public static void Write(PacketWriter stream, int cur, int max) - { - if (Enabled && max != 0) - { - stream.Write((short)Maximum); - stream.Write((short)(cur * Maximum / max)); - } - else - { - stream.Write((short)max); - stream.Write((short)cur); - } - } - - public static void WriteReverse(PacketWriter stream, int cur, int max) - { - if (Enabled && max != 0) - { - stream.Write((short)(cur * Maximum / max)); - stream.Write((short)Maximum); - } - else - { - stream.Write((short)cur); - stream.Write((short)max); - } - } - } - - public sealed class MobileHits : Packet - { - public MobileHits(Mobile m) : base(0xA1, 9) - { - m_Stream.Write(m.Serial); - m_Stream.Write((short)m.HitsMax); - m_Stream.Write((short)m.Hits); - } - } - - public sealed class MobileHitsN : Packet - { - public MobileHitsN(Mobile m) : base(0xA1, 9) - { - m_Stream.Write(m.Serial); - AttributeNormalizer.Write(m_Stream, m.Hits, m.HitsMax); - } - } - - public sealed class MobileMana : Packet - { - public MobileMana(Mobile m) : base(0xA2, 9) - { - m_Stream.Write(m.Serial); - m_Stream.Write((short)m.ManaMax); - m_Stream.Write((short)m.Mana); - } - } - - public sealed class MobileManaN : Packet - { - public MobileManaN(Mobile m) : base(0xA2, 9) - { - m_Stream.Write(m.Serial); - AttributeNormalizer.Write(m_Stream, m.Mana, m.ManaMax); - } - } - - public sealed class MobileStam : Packet - { - public MobileStam(Mobile m) : base(0xA3, 9) - { - m_Stream.Write(m.Serial); - m_Stream.Write((short)m.StamMax); - m_Stream.Write((short)m.Stam); - } - } - - public sealed class MobileStamN : Packet - { - public MobileStamN(Mobile m) : base(0xA3, 9) - { - m_Stream.Write(m.Serial); - AttributeNormalizer.Write(m_Stream, m.Stam, m.StamMax); - } - } - - public sealed class MobileAttributes : Packet - { - public MobileAttributes(Mobile m) : base(0x2D, 17) - { - m_Stream.Write(m.Serial); - - m_Stream.Write((short)m.HitsMax); - m_Stream.Write((short)m.Hits); - - m_Stream.Write((short)m.ManaMax); - m_Stream.Write((short)m.Mana); - - m_Stream.Write((short)m.StamMax); - m_Stream.Write((short)m.Stam); - } - } - - public sealed class MobileAttributesN : Packet - { - public MobileAttributesN(Mobile m) : base(0x2D, 17) - { - m_Stream.Write(m.Serial); - - AttributeNormalizer.Write(m_Stream, m.Hits, m.HitsMax); - AttributeNormalizer.Write(m_Stream, m.Mana, m.ManaMax); - AttributeNormalizer.Write(m_Stream, m.Stam, m.StamMax); - } - } - - public sealed class PathfindMessage : Packet - { - public PathfindMessage(IPoint3D p) : base(0x38, 7) - { - m_Stream.Write((short)p.X); - m_Stream.Write((short)p.Y); - m_Stream.Write((short)p.Z); - } - } - - // unsure of proper format, client crashes - public sealed class MobileName : Packet - { - public MobileName(Mobile m) : base(0x98) - { - EnsureCapacity(37); - - m_Stream.Write(m.Serial); - m_Stream.WriteAsciiFixed(m.Name ?? "", 30); - } - } - - public sealed class MobileAnimation : Packet - { - public MobileAnimation(Mobile m, int action, int frameCount, int repeatCount, bool forward, bool repeat, int delay) : - base(0x6E, 14) - { - m_Stream.Write(m.Serial); - m_Stream.Write((short)action); - m_Stream.Write((short)frameCount); - m_Stream.Write((short)repeatCount); - m_Stream.Write(!forward); // protocol has really "reverse" but I find this more intuitive - m_Stream.Write(repeat); - m_Stream.Write((byte)delay); - } - } - - public sealed class NewMobileAnimation : Packet - { - public NewMobileAnimation(Mobile m, int action, int frameCount, int delay) : base(0xE2, 10) - { - m_Stream.Write(m.Serial); - m_Stream.Write((short)action); - m_Stream.Write((short)frameCount); - m_Stream.Write((byte)delay); - } - } - - public sealed class MobileStatusCompact : Packet - { - public MobileStatusCompact(bool canBeRenamed, Mobile m) : base(0x11) - { - EnsureCapacity(43); - - m_Stream.Write(m.Serial); - m_Stream.WriteAsciiFixed(m.Name ?? "", 30); - - AttributeNormalizer.WriteReverse(m_Stream, m.Hits, m.HitsMax); - - m_Stream.Write(canBeRenamed); - - m_Stream.Write((byte)0); // type - } - } - - public sealed class MobileStatusExtended : Packet - { - public MobileStatusExtended(Mobile m) : this(m, m.NetState) - { - } - - public MobileStatusExtended(Mobile m, NetState ns) : base(0x11) - { - string name = m.Name ?? ""; - - int type; - - if (Core.HS && ns?.ExtendedStatus == true) - { - type = 6; - EnsureCapacity(121); - } - else if (Core.ML && ns?.SupportsExpansion(Expansion.ML) == true) - { - type = 5; - EnsureCapacity(91); - } - else - { - type = Core.AOS ? 4 : 3; - EnsureCapacity(88); - } - - m_Stream.Write(m.Serial); - m_Stream.WriteAsciiFixed(name, 30); - - m_Stream.Write((short)m.Hits); - m_Stream.Write((short)m.HitsMax); - - m_Stream.Write(m.CanBeRenamedBy(m)); - - m_Stream.Write((byte)type); - - m_Stream.Write(m.Female); - - m_Stream.Write((short)m.Str); - m_Stream.Write((short)m.Dex); - m_Stream.Write((short)m.Int); - - m_Stream.Write((short)m.Stam); - m_Stream.Write((short)m.StamMax); - - m_Stream.Write((short)m.Mana); - m_Stream.Write((short)m.ManaMax); - - m_Stream.Write(m.TotalGold); - m_Stream.Write((short)(Core.AOS ? m.PhysicalResistance : (int)(m.ArmorRating + 0.5))); - m_Stream.Write((short)(Mobile.BodyWeight + m.TotalWeight)); - - if (type >= 5) - { - m_Stream.Write((short)m.MaxWeight); - m_Stream.Write((byte)(m.Race.RaceID + 1)); // Would be 0x00 if it's a non-ML enabled account but... - } - - m_Stream.Write((short)m.StatCap); - - m_Stream.Write((byte)m.Followers); - m_Stream.Write((byte)m.FollowersMax); - - if (type >= 4) - { - m_Stream.Write((short)m.FireResistance); // Fire - m_Stream.Write((short)m.ColdResistance); // Cold - m_Stream.Write((short)m.PoisonResistance); // Poison - m_Stream.Write((short)m.EnergyResistance); // Energy - m_Stream.Write((short)m.Luck); // Luck - - IWeapon weapon = m.Weapon; - - if (weapon != null) - { - weapon.GetStatusDamage(m, out int min, out int max); - m_Stream.Write((short)min); // Damage min - m_Stream.Write((short)max); // Damage max - } - else - { - m_Stream.Write((short)0); // Damage min - m_Stream.Write((short)0); // Damage max - } - - m_Stream.Write(m.TithingPoints); - } - - if (type >= 6) - for (int i = 0; i < 15; ++i) - m_Stream.Write((short)m.GetAOSStatus(i)); - } - } - - public sealed class MobileStatus : Packet - { - public MobileStatus(Mobile beholder, Mobile beheld) : this(beholder, beheld, beheld.NetState) - { - } - - public MobileStatus(Mobile beholder, Mobile beheld, NetState ns) : base(0x11) - { - string name = beheld.Name ?? ""; - - int type; - - if (beholder != beheld) - { - type = 0; - EnsureCapacity(43); - } - else if (Core.HS && ns?.ExtendedStatus == true) - { - type = 6; - EnsureCapacity(121); - } - else if (Core.ML && ns?.SupportsExpansion(Expansion.ML) == true) - { - type = 5; - EnsureCapacity(91); - } - else - { - type = Core.AOS ? 4 : 3; - EnsureCapacity(88); - } - - m_Stream.Write(beheld.Serial); - - m_Stream.WriteAsciiFixed(name, 30); - - if (beholder == beheld) - WriteAttr(beheld.Hits, beheld.HitsMax); - else - WriteAttrNorm(beheld.Hits, beheld.HitsMax); - - m_Stream.Write(beheld.CanBeRenamedBy(beholder)); - - m_Stream.Write((byte)type); - - if (type <= 0) - return; - - m_Stream.Write(beheld.Female); - - m_Stream.Write((short)beheld.Str); - m_Stream.Write((short)beheld.Dex); - m_Stream.Write((short)beheld.Int); - - WriteAttr(beheld.Stam, beheld.StamMax); - WriteAttr(beheld.Mana, beheld.ManaMax); - - m_Stream.Write(beheld.TotalGold); - m_Stream.Write((short)(Core.AOS ? beheld.PhysicalResistance : (int)(beheld.ArmorRating + 0.5))); - m_Stream.Write((short)(Mobile.BodyWeight + beheld.TotalWeight)); - - if (type >= 5) - { - m_Stream.Write((short)beheld.MaxWeight); - m_Stream.Write((byte)(beheld.Race.RaceID + 1)); // Would be 0x00 if it's a non-ML enabled account but... - } - - m_Stream.Write((short)beheld.StatCap); - - m_Stream.Write((byte)beheld.Followers); - m_Stream.Write((byte)beheld.FollowersMax); - - if (type >= 4) - { - m_Stream.Write((short)beheld.FireResistance); // Fire - m_Stream.Write((short)beheld.ColdResistance); // Cold - m_Stream.Write((short)beheld.PoisonResistance); // Poison - m_Stream.Write((short)beheld.EnergyResistance); // Energy - m_Stream.Write((short)beheld.Luck); // Luck - - IWeapon weapon = beheld.Weapon; - - if (weapon != null) - { - weapon.GetStatusDamage(beheld, out int min, out int max); - m_Stream.Write((short)min); // Damage min - m_Stream.Write((short)max); // Damage max - } - else - { - m_Stream.Write((short)0); // Damage min - m_Stream.Write((short)0); // Damage max - } - - m_Stream.Write(beheld.TithingPoints); - } - - if (type >= 6) - for (int i = 0; i < 15; ++i) - m_Stream.Write((short)beheld.GetAOSStatus(i)); - } - - private void WriteAttr(int current, int maximum) - { - m_Stream.Write((short)current); - m_Stream.Write((short)maximum); - } - - private void WriteAttrNorm(int current, int maximum) - { - AttributeNormalizer.WriteReverse(m_Stream, current, maximum); - } - } - - public sealed class HealthbarPoison : Packet - { - public HealthbarPoison(Mobile m) : base(0x17) - { - EnsureCapacity(12); - - m_Stream.Write(m.Serial); - m_Stream.Write((short)1); - - m_Stream.Write((short)1); - - Poison p = m.Poison; - - if (p != null) - m_Stream.Write((byte)(p.Level + 1)); - else - m_Stream.Write((byte)0); - } - } - - public sealed class HealthbarYellow : Packet - { - public HealthbarYellow(Mobile m) : base(0x17) - { - EnsureCapacity(12); - - m_Stream.Write(m.Serial); - m_Stream.Write((short)1); - - m_Stream.Write((short)2); - - if (m.Blessed || m.YellowHealthbar) - m_Stream.Write((byte)1); - else - m_Stream.Write((byte)0); - } - } - - public sealed class MobileUpdate : Packet - { - public MobileUpdate(Mobile m) : base(0x20, 19) - { - int hue = m.Hue; - - if (m.SolidHueOverride >= 0) - hue = m.SolidHueOverride; - - m_Stream.Write(m.Serial); - m_Stream.Write((short)m.Body); - m_Stream.Write((byte)0); - m_Stream.Write((short)hue); - m_Stream.Write((byte)m.GetPacketFlags()); - m_Stream.Write((short)m.X); - m_Stream.Write((short)m.Y); - m_Stream.Write((short)0); - m_Stream.Write((byte)m.Direction); - m_Stream.Write((sbyte)m.Z); - } - } - - // Pre-7.0.0.0 Mobile Update - public sealed class MobileUpdateOld : Packet - { - public MobileUpdateOld(Mobile m) : base(0x20, 19) - { - int hue = m.Hue; - - if (m.SolidHueOverride >= 0) - hue = m.SolidHueOverride; - - m_Stream.Write(m.Serial); - m_Stream.Write((short)m.Body); - m_Stream.Write((byte)0); - m_Stream.Write((short)hue); - m_Stream.Write((byte)m.GetOldPacketFlags()); - m_Stream.Write((short)m.X); - m_Stream.Write((short)m.Y); - m_Stream.Write((short)0); - m_Stream.Write((byte)m.Direction); - m_Stream.Write((sbyte)m.Z); - } - } - - public sealed class MobileIncoming : Packet - { - private static ThreadLocal m_DupedLayersTL = new ThreadLocal(() => { return new int[256]; }); - private static ThreadLocal m_VersionTL = new ThreadLocal(); - - public Mobile m_Beheld; - - public MobileIncoming(Mobile beholder, Mobile beheld) : base(0x78) - { - m_Beheld = beheld; - - int m_Version = ++m_VersionTL.Value; - int[] m_DupedLayers = m_DupedLayersTL.Value; - - List eq = beheld.Items; - int count = eq.Count; - - if (beheld.HairItemID > 0) - count++; - if (beheld.FacialHairItemID > 0) - count++; - - EnsureCapacity(23 + count * 9); - - int hue = beheld.Hue; - - if (beheld.SolidHueOverride >= 0) - hue = beheld.SolidHueOverride; - - m_Stream.Write(beheld.Serial); - m_Stream.Write((short)beheld.Body); - m_Stream.Write((short)beheld.X); - m_Stream.Write((short)beheld.Y); - m_Stream.Write((sbyte)beheld.Z); - m_Stream.Write((byte)beheld.Direction); - m_Stream.Write((short)hue); - m_Stream.Write((byte)beheld.GetPacketFlags()); - m_Stream.Write((byte)Notoriety.Compute(beholder, beheld)); - - for (int i = 0; i < eq.Count; ++i) - { - Item item = eq[i]; - - byte layer = (byte)item.Layer; - - if (!item.Deleted && beholder.CanSee(item) && m_DupedLayers[layer] != m_Version) - { - m_DupedLayers[layer] = m_Version; - - hue = item.Hue; - - if (beheld.SolidHueOverride >= 0) - hue = beheld.SolidHueOverride; - - int itemID = item.ItemID & 0xFFFF; - - m_Stream.Write(item.Serial); - m_Stream.Write((ushort)itemID); - m_Stream.Write(layer); - - m_Stream.Write((short)hue); - } - } - - if (beheld.HairItemID > 0) - if (m_DupedLayers[(int)Layer.Hair] != m_Version) - { - m_DupedLayers[(int)Layer.Hair] = m_Version; - hue = beheld.HairHue; - - if (beheld.SolidHueOverride >= 0) - hue = beheld.SolidHueOverride; - - int itemID = beheld.HairItemID & 0xFFFF; - - m_Stream.Write(HairInfo.FakeSerial(beheld)); - m_Stream.Write((ushort)itemID); - m_Stream.Write((byte)Layer.Hair); - - m_Stream.Write((short)hue); - } - - if (beheld.FacialHairItemID > 0) - if (m_DupedLayers[(int)Layer.FacialHair] != m_Version) - { - m_DupedLayers[(int)Layer.FacialHair] = m_Version; - hue = beheld.FacialHairHue; - - if (beheld.SolidHueOverride >= 0) - hue = beheld.SolidHueOverride; - - int itemID = beheld.FacialHairItemID & 0xFFFF; - - m_Stream.Write(FacialHairInfo.FakeSerial(beheld)); - m_Stream.Write((ushort)itemID); - m_Stream.Write((byte)Layer.FacialHair); - - m_Stream.Write((short)hue); - } - - m_Stream.Write(0); // terminate - } - - public static Packet Create(NetState ns, Mobile beholder, Mobile beheld) - { - if (ns.NewMobileIncoming) - return new MobileIncoming(beholder, beheld); - if (ns.StygianAbyss) - return new MobileIncomingSA(beholder, beheld); - return new MobileIncomingOld(beholder, beheld); - } - } - - public sealed class MobileIncomingSA : Packet - { - private static ThreadLocal m_DupedLayersTL = new ThreadLocal(() => { return new int[256]; }); - private static ThreadLocal m_VersionTL = new ThreadLocal(); - - public Mobile m_Beheld; - - public MobileIncomingSA(Mobile beholder, Mobile beheld) : base(0x78) - { - m_Beheld = beheld; - - int m_Version = ++m_VersionTL.Value; - int[] m_DupedLayers = m_DupedLayersTL.Value; - - List eq = beheld.Items; - int count = eq.Count; - - if (beheld.HairItemID > 0) - count++; - if (beheld.FacialHairItemID > 0) - count++; - - EnsureCapacity(23 + count * 9); - - int hue = beheld.Hue; - - if (beheld.SolidHueOverride >= 0) - hue = beheld.SolidHueOverride; - - m_Stream.Write(beheld.Serial); - m_Stream.Write((short)beheld.Body); - m_Stream.Write((short)beheld.X); - m_Stream.Write((short)beheld.Y); - m_Stream.Write((sbyte)beheld.Z); - m_Stream.Write((byte)beheld.Direction); - m_Stream.Write((short)hue); - m_Stream.Write((byte)beheld.GetPacketFlags()); - m_Stream.Write((byte)Notoriety.Compute(beholder, beheld)); - - for (int i = 0; i < eq.Count; ++i) - { - Item item = eq[i]; - - byte layer = (byte)item.Layer; - - if (!item.Deleted && beholder.CanSee(item) && m_DupedLayers[layer] != m_Version) - { - m_DupedLayers[layer] = m_Version; - - hue = item.Hue; - - if (beheld.SolidHueOverride >= 0) - hue = beheld.SolidHueOverride; - - int itemID = item.ItemID & 0x7FFF; - bool writeHue = hue != 0; - - if (writeHue) - itemID |= 0x8000; - - m_Stream.Write(item.Serial); - m_Stream.Write((ushort)itemID); - m_Stream.Write(layer); - - if (writeHue) - m_Stream.Write((short)hue); - } - } - - if (beheld.HairItemID > 0) - if (m_DupedLayers[(int)Layer.Hair] != m_Version) - { - m_DupedLayers[(int)Layer.Hair] = m_Version; - hue = beheld.HairHue; - - if (beheld.SolidHueOverride >= 0) - hue = beheld.SolidHueOverride; - - int itemID = beheld.HairItemID & 0x7FFF; - - bool writeHue = hue != 0; - - if (writeHue) - itemID |= 0x8000; - - m_Stream.Write(HairInfo.FakeSerial(beheld)); - m_Stream.Write((ushort)itemID); - m_Stream.Write((byte)Layer.Hair); - - if (writeHue) - m_Stream.Write((short)hue); - } - - if (beheld.FacialHairItemID > 0) - if (m_DupedLayers[(int)Layer.FacialHair] != m_Version) - { - m_DupedLayers[(int)Layer.FacialHair] = m_Version; - hue = beheld.FacialHairHue; - - if (beheld.SolidHueOverride >= 0) - hue = beheld.SolidHueOverride; - - int itemID = beheld.FacialHairItemID & 0x7FFF; - - bool writeHue = hue != 0; - - if (writeHue) - itemID |= 0x8000; - - m_Stream.Write(FacialHairInfo.FakeSerial(beheld)); - m_Stream.Write((ushort)itemID); - m_Stream.Write((byte)Layer.FacialHair); - - if (writeHue) - m_Stream.Write((short)hue); - } - - m_Stream.Write(0); // terminate - } - } - - // Pre-7.0.0.0 Mobile Incoming - public sealed class MobileIncomingOld : Packet - { - private static ThreadLocal m_DupedLayersTL = new ThreadLocal(() => { return new int[256]; }); - private static ThreadLocal m_VersionTL = new ThreadLocal(); - - public Mobile m_Beheld; - - public MobileIncomingOld(Mobile beholder, Mobile beheld) : base(0x78) - { - m_Beheld = beheld; - - int m_Version = ++m_VersionTL.Value; - int[] m_DupedLayers = m_DupedLayersTL.Value; - - List eq = beheld.Items; - int count = eq.Count; - - if (beheld.HairItemID > 0) - count++; - if (beheld.FacialHairItemID > 0) - count++; - - EnsureCapacity(23 + count * 9); - - int hue = beheld.Hue; - - if (beheld.SolidHueOverride >= 0) - hue = beheld.SolidHueOverride; - - m_Stream.Write(beheld.Serial); - m_Stream.Write((short)beheld.Body); - m_Stream.Write((short)beheld.X); - m_Stream.Write((short)beheld.Y); - m_Stream.Write((sbyte)beheld.Z); - m_Stream.Write((byte)beheld.Direction); - m_Stream.Write((short)hue); - m_Stream.Write((byte)beheld.GetOldPacketFlags()); - m_Stream.Write((byte)Notoriety.Compute(beholder, beheld)); - - for (int i = 0; i < eq.Count; ++i) - { - Item item = eq[i]; - - byte layer = (byte)item.Layer; - - if (!item.Deleted && beholder.CanSee(item) && m_DupedLayers[layer] != m_Version) - { - m_DupedLayers[layer] = m_Version; - - hue = item.Hue; - - if (beheld.SolidHueOverride >= 0) - hue = beheld.SolidHueOverride; - - int itemID = item.ItemID & 0x7FFF; - bool writeHue = hue != 0; - - if (writeHue) - itemID |= 0x8000; - - m_Stream.Write(item.Serial); - m_Stream.Write((ushort)itemID); - m_Stream.Write(layer); - - if (writeHue) - m_Stream.Write((short)hue); - } - } - - if (beheld.HairItemID > 0) - if (m_DupedLayers[(int)Layer.Hair] != m_Version) - { - m_DupedLayers[(int)Layer.Hair] = m_Version; - hue = beheld.HairHue; - - if (beheld.SolidHueOverride >= 0) - hue = beheld.SolidHueOverride; - - int itemID = beheld.HairItemID & 0x7FFF; - - bool writeHue = hue != 0; - - if (writeHue) - itemID |= 0x8000; - - m_Stream.Write(HairInfo.FakeSerial(beheld)); - m_Stream.Write((ushort)itemID); - m_Stream.Write((byte)Layer.Hair); - - if (writeHue) - m_Stream.Write((short)hue); - } - - if (beheld.FacialHairItemID > 0) - if (m_DupedLayers[(int)Layer.FacialHair] != m_Version) - { - m_DupedLayers[(int)Layer.FacialHair] = m_Version; - hue = beheld.FacialHairHue; - - if (beheld.SolidHueOverride >= 0) - hue = beheld.SolidHueOverride; - - int itemID = beheld.FacialHairItemID & 0x7FFF; - - bool writeHue = hue != 0; - - if (writeHue) - itemID |= 0x8000; - - m_Stream.Write(FacialHairInfo.FakeSerial(beheld)); - m_Stream.Write((ushort)itemID); - m_Stream.Write((byte)Layer.FacialHair); - - if (writeHue) - m_Stream.Write((short)hue); - } - - m_Stream.Write(0); // terminate - } - } - - public sealed class AsciiMessage : Packet - { - public AsciiMessage(Serial serial, int graphic, MessageType type, int hue, int font, string name, string text) : - base(0x1C) - { - if (name == null) - name = ""; - - if (text == null) - text = ""; - - if (hue == 0) - hue = 0x3B2; - - EnsureCapacity(45 + text.Length); - - m_Stream.Write(serial); - m_Stream.Write((short)graphic); - m_Stream.Write((byte)type); - m_Stream.Write((short)hue); - m_Stream.Write((short)font); - m_Stream.WriteAsciiFixed(name, 30); - m_Stream.WriteAsciiNull(text); - } - } - - public sealed class UnicodeMessage : Packet - { - public UnicodeMessage(Serial serial, int graphic, MessageType type, int hue, int font, string lang, string name, - string text) : base(0xAE) - { - if (string.IsNullOrEmpty(lang)) lang = "ENU"; - if (name == null) name = ""; - if (text == null) text = ""; - - if (hue == 0) - hue = 0x3B2; - - EnsureCapacity(50 + text.Length * 2); - - m_Stream.Write(serial); - m_Stream.Write((short)graphic); - m_Stream.Write((byte)type); - m_Stream.Write((short)hue); - m_Stream.Write((short)font); - m_Stream.WriteAsciiFixed(lang, 4); - m_Stream.WriteAsciiFixed(name, 30); - m_Stream.WriteBigUniNull(text); - } - } - - public sealed class PingAck : Packet - { - private static PingAck[] m_Cache = new PingAck[0x100]; - - public PingAck(byte ping) : base(0x73, 2) - { - m_Stream.Write(ping); - } - - public static PingAck Instantiate(byte ping) - { - PingAck p = m_Cache[ping]; - - if (p == null) - { - m_Cache[ping] = p = new PingAck(ping); - p.SetStatic(); - } - - return p; - } - } - - public sealed class MovementRej : Packet - { - public MovementRej(int seq, Mobile m) : base(0x21, 8) - { - m_Stream.Write((byte)seq); - m_Stream.Write((short)m.X); - m_Stream.Write((short)m.Y); - m_Stream.Write((byte)m.Direction); - m_Stream.Write((sbyte)m.Z); - } - } - - public sealed class MovementAck : Packet - { - private static MovementAck[] m_Cache = new MovementAck[8 * 256]; - - private MovementAck(int seq, int noto) : base(0x22, 3) - { - m_Stream.Write((byte)seq); - m_Stream.Write((byte)noto); - } - - public static MovementAck Instantiate(int seq, Mobile m) - { - int noto = Notoriety.Compute(m, m); - - MovementAck p = m_Cache[noto * seq]; - - if (p == null) - { - m_Cache[noto * seq] = p = new MovementAck(seq, noto); - p.SetStatic(); - } - - return p; - } - } - - public sealed class LoginConfirm : Packet - { - public LoginConfirm(Mobile m) : base(0x1B, 37) - { - m_Stream.Write(m.Serial); - m_Stream.Write(0); - m_Stream.Write((short)m.Body); - m_Stream.Write((short)m.X); - m_Stream.Write((short)m.Y); - m_Stream.Write((short)m.Z); - m_Stream.Write((byte)m.Direction); - m_Stream.Write((byte)0); - m_Stream.Write(-1); - - Map map = m.Map; - - if (map == null || map == Map.Internal) - map = m.LogoutMap; - - m_Stream.Write((short)0); - m_Stream.Write((short)0); - m_Stream.Write((short)(map?.Width ?? 6144)); - m_Stream.Write((short)(map?.Height ?? 4096)); - - m_Stream.Fill(); - } - } - - public sealed class LoginComplete : Packet - { - public static readonly Packet Instance = SetStatic(new LoginComplete()); - - public LoginComplete() : base(0x55, 1) - { - } - } - - public sealed class CharacterListUpdate : Packet - { - public CharacterListUpdate(IAccount a) : base(0x86) - { - EnsureCapacity(4 + a.Length * 60); - - int highSlot = -1; - - for (int i = 0; i < a.Length; ++i) - if (a[i] != null) - highSlot = i; - - int count = Math.Max(Math.Max(highSlot + 1, a.Limit), 5); - - m_Stream.Write((byte)count); - - for (int i = 0; i < count; ++i) - { - Mobile m = a[i]; - - if (m != null) - { - m_Stream.WriteAsciiFixed(m.Name, 30); - m_Stream.Fill(30); // password - } - else - { - m_Stream.Fill(60); - } - } - } - } - - [Flags] - public enum ThirdPartyFeature : ulong - { - FilterWeather = 1, - FilterLight = 1 << 1, - - SmartTarget = 1 << 2, - RangedTarget = 1 << 3, - - AutoOpenDoors = 1 << 4, - - DequipOnCast = 1 << 5, - AutoPotionEquip = 1 << 6, - - ProtectHeals = 1 << 7, - - LoopedMacros = 1 << 8, - - UseOnceAgent = 1 << 9, - RestockAgent = 1 << 10, - SellAgent = 1 << 11, - BuyAgent = 1 << 12, - - PotionHotkeys = 1 << 13, - - RandomTargets = 1 << 14, - ClosestTargets = 1 << 15, // All closest target hotkeys - OverheadHealth = 1 << 16, // Health and Mana/Stam messages shown over player's heads - - AutolootAgent = 1 << 17, - BoneCutterAgent = 1 << 18, - AdvancedMacros = 1 << 19, - AutoRemount = 1 << 20, - AutoBandage = 1 << 21, - EnemyTargetShare = 1 << 22, - FilterSeason = 1 << 23, - SpellTargetShare = 1 << 24, - - All = ulong.MaxValue - } - - public static class FeatureProtection - { - public static ThirdPartyFeature DisabledFeatures{ get; private set; } = 0; - - public static void Disable(ThirdPartyFeature feature) - { - SetDisabled(feature, true); - } - - public static void Enable(ThirdPartyFeature feature) - { - SetDisabled(feature, false); - } - - public static void SetDisabled(ThirdPartyFeature feature, bool value) - { - if (value) - DisabledFeatures |= feature; - else - DisabledFeatures &= ~feature; - } - } - - public sealed class CharacterList : Packet - { - //private static MD5CryptoServiceProvider m_MD5Provider; - - public CharacterList(IAccount a, CityInfo[] info) : base(0xA9) - { - EnsureCapacity(11 + a.Length * 60 + info.Length * 89); - - int highSlot = -1; - - for (int i = 0; i < a.Length; ++i) - if (a[i] != null) - highSlot = i; - - int count = Math.Max(Math.Max(highSlot + 1, a.Limit), 5); - - m_Stream.Write((byte)count); - - for (int i = 0; i < count; ++i) - if (a[i] != null) - { - m_Stream.WriteAsciiFixed(a[i].Name, 30); - m_Stream.Fill(30); // password - } - else - { - m_Stream.Fill(60); - } - - m_Stream.Write((byte)info.Length); - - for (int i = 0; i < info.Length; ++i) - { - CityInfo ci = info[i]; - - m_Stream.Write((byte)i); - m_Stream.WriteAsciiFixed(ci.City, 32); - m_Stream.WriteAsciiFixed(ci.Building, 32); - m_Stream.Write(ci.X); - m_Stream.Write(ci.Y); - m_Stream.Write(ci.Z); - m_Stream.Write(ci.Map.MapID); - m_Stream.Write(ci.Description); - m_Stream.Write(0); - } - - CharacterListFlags flags = ExpansionInfo.CoreExpansion.CharacterListFlags; - - if (count > 6) - flags |= CharacterListFlags.SeventhCharacterSlot | - CharacterListFlags.SixthCharacterSlot; // 7th Character Slot - TODO: Is SixthCharacterSlot Required? - else if (count == 6) - flags |= CharacterListFlags.SixthCharacterSlot; // 6th Character Slot - else if (a.Limit == 1) - flags |= CharacterListFlags.SlotLimit & - CharacterListFlags.OneCharacterSlot; // Limit Characters & One Character - - m_Stream.Write((int)(flags | AdditionalFlags)); // Additional Flags - - m_Stream.Write((short)-1); - - /*ThirdPartyFeature disabled = FeatureProtection.DisabledFeatures; - - if (disabled != 0) - { - if (m_MD5Provider == null) - m_MD5Provider = new MD5CryptoServiceProvider(); - - m_Stream.UnderlyingStream.Flush(); - - byte[] hashCode = m_MD5Provider.ComputeHash(m_Stream.UnderlyingStream.GetBuffer(), 0, - (int)m_Stream.UnderlyingStream.Length); - byte[] buffer = new byte[28]; - - for (int i = 0; i < count; ++i) - { - Utility.RandomBytes(buffer); - - m_Stream.Seek(35 + i * 60, SeekOrigin.Begin); - m_Stream.Write(buffer, 0, buffer.Length); - } - - m_Stream.Seek(35, SeekOrigin.Begin); - m_Stream.Write((int)((long)disabled >> 32)); - m_Stream.Write((int)disabled); - - m_Stream.Seek(95, SeekOrigin.Begin); - m_Stream.Write(hashCode, 0, hashCode.Length); - }*/ - } - - public static CharacterListFlags AdditionalFlags{ get; set; } - } - - public sealed class CharacterListOld : Packet - { - // private static MD5CryptoServiceProvider m_MD5Provider; - - public CharacterListOld(IAccount a, CityInfo[] info) : base(0xA9) - { - EnsureCapacity(9 + a.Length * 60 + info.Length * 63); - - int highSlot = -1; - - for (int i = 0; i < a.Length; ++i) - if (a[i] != null) - highSlot = i; - - int count = Math.Max(Math.Max(highSlot + 1, a.Limit), 5); - - m_Stream.Write((byte)count); - - for (int i = 0; i < count; ++i) - if (a[i] != null) - { - m_Stream.WriteAsciiFixed(a[i].Name, 30); - m_Stream.Fill(30); // password - } - else - { - m_Stream.Fill(60); - } - - m_Stream.Write((byte)info.Length); - - for (int i = 0; i < info.Length; ++i) - { - CityInfo ci = info[i]; - - m_Stream.Write((byte)i); - m_Stream.WriteAsciiFixed(ci.City, 31); - m_Stream.WriteAsciiFixed(ci.Building, 31); - } - - CharacterListFlags flags = ExpansionInfo.CoreExpansion.CharacterListFlags; - - if (count > 6) - flags |= CharacterListFlags.SeventhCharacterSlot | - CharacterListFlags.SixthCharacterSlot; // 7th Character Slot - TODO: Is SixthCharacterSlot Required? - else if (count == 6) - flags |= CharacterListFlags.SixthCharacterSlot; // 6th Character Slot - else if (a.Limit == 1) - flags |= CharacterListFlags.SlotLimit & - CharacterListFlags.OneCharacterSlot; // Limit Characters & One Character - - m_Stream.Write((int)(flags | CharacterList.AdditionalFlags)); // Additional Flags - } - } - - public sealed class ClearWeaponAbility : Packet - { - public static readonly Packet Instance = SetStatic(new ClearWeaponAbility()); - - public ClearWeaponAbility() : base(0xBF) - { - EnsureCapacity(5); - - m_Stream.Write((short)0x21); - } - } - - public enum ALRReason : byte - { - Invalid = 0x00, - InUse = 0x01, - Blocked = 0x02, - BadPass = 0x03, - Idle = 0xFE, - BadComm = 0xFF - } - - public sealed class AccountLoginRej : Packet - { - public AccountLoginRej(ALRReason reason) : base(0x82, 2) - { - m_Stream.Write((byte)reason); - } - } - - [Flags] - public enum AffixType : byte - { - Append = 0x00, - Prepend = 0x01, - System = 0x02 - } - - public sealed class MessageLocalizedAffix : Packet - { - public MessageLocalizedAffix(Serial serial, int graphic, MessageType messageType, int hue, int font, int number, - string name, AffixType affixType, string affix, string args) : base(0xCC) - { - if (name == null) name = ""; - if (affix == null) affix = ""; - if (args == null) args = ""; - - if (hue == 0) - hue = 0x3B2; - - EnsureCapacity(52 + affix.Length + args.Length * 2); - - m_Stream.Write(serial); - m_Stream.Write((short)graphic); - m_Stream.Write((byte)messageType); - m_Stream.Write((short)hue); - m_Stream.Write((short)font); - m_Stream.Write(number); - m_Stream.Write((byte)affixType); - m_Stream.WriteAsciiFixed(name, 30); - m_Stream.WriteAsciiNull(affix); - m_Stream.WriteBigUniNull(args); - } - } - - public sealed class ServerInfo - { - public ServerInfo(string name, int fullPercent, TimeZoneInfo tz, IPEndPoint address) - { - Name = name; - FullPercent = fullPercent; - TimeZone = tz.GetUtcOffset(DateTime.Now).Hours; - Address = address; - } - - public string Name{ get; set; } - - public int FullPercent{ get; set; } - - public int TimeZone{ get; set; } - - public IPEndPoint Address{ get; set; } - } - - public sealed class FollowMessage : Packet - { - public FollowMessage(Serial serial1, Serial serial2) : base(0x15, 9) - { - m_Stream.Write(serial1); - m_Stream.Write(serial2); - } - } - - public sealed class AccountLoginAck : Packet - { - public AccountLoginAck(ServerInfo[] info) : base(0xA8) - { - EnsureCapacity(6 + info.Length * 40); - - m_Stream.Write((byte)0x5D); // Unknown - - m_Stream.Write((ushort)info.Length); - - for (int i = 0; i < info.Length; ++i) - { - ServerInfo si = info[i]; - - m_Stream.Write((ushort)i); - m_Stream.WriteAsciiFixed(si.Name, 32); - m_Stream.Write((byte)si.FullPercent); - m_Stream.Write((sbyte)si.TimeZone); - m_Stream.Write(Utility.GetAddressValue(si.Address.Address)); - } - } - } - - public sealed class DisplaySignGump : Packet - { - public DisplaySignGump(Serial serial, int gumpID, string unknown, string caption) : base(0x8B) - { - if (unknown == null) unknown = ""; - if (caption == null) caption = ""; - - EnsureCapacity(16 + unknown.Length + caption.Length); - - m_Stream.Write(serial); - m_Stream.Write((short)gumpID); - m_Stream.Write((short)unknown.Length); - m_Stream.WriteAsciiFixed(unknown, unknown.Length); - m_Stream.Write((short)(caption.Length + 1)); - m_Stream.WriteAsciiFixed(caption, caption.Length + 1); - } - } - - public sealed class GodModeReply : Packet - { - public GodModeReply(bool reply) : base(0x2B, 2) - { - m_Stream.Write(reply); - } - } - - public sealed class PlayServerAck : Packet - { - internal static int m_AuthID = -1; - - public PlayServerAck(ServerInfo si) : base(0x8C, 11) - { - int addr = Utility.GetAddressValue(si.Address.Address); - - m_Stream.Write((byte)addr); - m_Stream.Write((byte)(addr >> 8)); - m_Stream.Write((byte)(addr >> 16)); - m_Stream.Write((byte)(addr >> 24)); - - m_Stream.Write((short)si.Address.Port); - m_Stream.Write(m_AuthID); - } - } -} diff --git a/Projects/Server/Network/Packets/Accounts.cs b/Projects/Server/Network/Packets/Accounts.cs new file mode 100644 index 000000000..83715af62 --- /dev/null +++ b/Projects/Server/Network/Packets/Accounts.cs @@ -0,0 +1,325 @@ +using System; +using Server.Buffers; + +namespace Server.Network +{ + public enum DeleteResultType : byte + { + PasswordInvalid, + CharNotExist, + CharBeingPlayed, + CharTooYoung, + CharQueued, + BadRequest + } + + public enum PMMessage : byte + { + CharNoExist = 1, + CharExists = 2, + CharInWorld = 5, + LoginSyncError = 6, + IdleWarning = 7 + } + + public enum ALRReason : byte + { + Invalid = 0x00, + InUse = 0x01, + Blocked = 0x02, + BadPass = 0x03, + Idle = 0xFE, + BadComm = 0xFF + } + + public static partial class Packets + { + public static void SendDeleteResult(NetState ns, DeleteResultType res) + { + if (ns == null) + return; + + Span span = ns.SendPipe.Writer.GetSpan(2); + span[0] = 0x85; // Packet ID + span[1] = (byte)res; + + // Not compressed with Huffman + _ = ns.Flush(2); + } + + public static void SendPopupMessage(NetState ns, PMMessage msg) + { + ns?.Send(stackalloc byte[] + { + 0x53, // Packet ID + (byte)msg + }); + } + + public static void SendAccountLoginRej(NetState ns, ALRReason reason) + { + if (ns == null) + return; + + Span span = ns.SendPipe.Writer.GetSpan(2); + span[0] = 0x82; // Packet ID + span[1] = (byte)reason; + + // Not compressed with Huffman + _ = ns.Flush(2); + } + + public static void SendSupportedFeatures(NetState ns) + { + if (ns == null) + return; + + int length = ns.ExtendedSupportedFeatures ? 5 : 3; + + Span bytes = stackalloc byte[length]; + + SpanWriter w = new SpanWriter(bytes); + w.Write((byte)0xB9); // Packet ID + + FeatureFlags flags = ExpansionInfo.CoreExpansion.SupportedFeatures; + + if (ns.Account?.Limit >= 6) + { + flags &= ~FeatureFlags.UOTD; + flags |= FeatureFlags.LiveAccount | + (ns.Account.Limit > 6 ? FeatureFlags.SeventhCharacterSlot : FeatureFlags.SixthCharacterSlot); + } + + if (ns.ExtendedSupportedFeatures) + w.Write((uint)flags); + else + w.Write((ushort)flags); + + ns.Send(w.RawSpan); + } + + public static void SendCharacterList(NetState ns, CityInfo[] info) + { + if (ns == null) + return; + + if (ns.NewCharacterList) + SendCharacterListNew(ns, ns.Account, info); + else + SendCharacterListOld(ns, ns.Account, info); + } + + public static void SendCharacterListNew(NetState ns, IAccount a, CityInfo[] info) + { + if (ns == null) + return; + + int highSlot = -1; + + for (int i = 0; i < a.Length; ++i) + if (a[i] != null) + highSlot = i; + + int count = Math.Max(Math.Max(highSlot + 1, a.Limit), 5); + int length = 11 + count * 60 + info.Length * 89; + + SpanWriter w = new SpanWriter(stackalloc byte[length]); + w.Write((byte)0xA9); // Packet ID + w.Write((short)length); // Length + + w.Write((byte)count); + + for (int i = 0; i < count; ++i) + if (a[i] != null) + { + w.WriteAsciiFixed(a[i].Name, 30); + w.Position += 30; + } + else + w.Position += 60; + + w.Write((byte)info.Length); + + for (int i = 0; i < info.Length; ++i) + { + CityInfo ci = info[i]; + + w.Write((byte)i); + w.WriteAsciiFixed(ci.City, 32); + w.WriteAsciiFixed(ci.Building, 32); + w.Write(ci.X); + w.Write(ci.Y); + w.Write(ci.Z); + w.Write(ci.Map.MapID); + w.Write(ci.Description); + w.Position += 4; // w.Write(0); + } + + CharacterListFlags flags = ExpansionInfo.CoreExpansion.CharacterListFlags; + + if (count > 6) + flags |= CharacterListFlags.SeventhCharacterSlot | + CharacterListFlags.SixthCharacterSlot; // 7th Character Slot - TODO: Is SixthCharacterSlot Required? + else if (count == 6) + flags |= CharacterListFlags.SixthCharacterSlot; // 6th Character Slot + else if (a.Limit == 1) + flags |= CharacterListFlags.SlotLimit & + CharacterListFlags.OneCharacterSlot; // Limit Characters & One Character + + w.Write((int)flags); + + w.Write((short)-1); + + ns.Send(w.Span); + + // TODO: Razor support? + } + + public static void SendCharacterListOld(NetState ns, IAccount a, CityInfo[] info) + { + if (ns == null) + return; + + int highSlot = -1; + + for (int i = 0; i < a.Length; ++i) + if (a[i] != null) + highSlot = i; + + int count = Math.Max(Math.Max(highSlot + 1, a.Limit), 5); + int length = 9 + count * 60 + info.Length * 63; + + SpanWriter w = new SpanWriter(stackalloc byte[length]); + w.Write((byte)0xA9); // Packet ID + w.Write((short)length); // Length + + w.Write((byte)count); + + for (int i = 0; i < count; ++i) + if (a[i] != null) + { + w.WriteAsciiFixed(a[i].Name, 30); + w.Position += 30; + } + else + w.Position += 60; + + w.Write((byte)info.Length); + + for (int i = 0; i < info.Length; ++i) + { + CityInfo ci = info[i]; + + w.Write((byte)i); + w.WriteAsciiFixed(ci.City, 31); + w.WriteAsciiFixed(ci.Building, 31); + } + + CharacterListFlags flags = ExpansionInfo.CoreExpansion.CharacterListFlags; + + if (count > 6) + flags |= CharacterListFlags.SeventhCharacterSlot | + CharacterListFlags.SixthCharacterSlot; // 7th Character Slot - TODO: Is SixthCharacterSlot Required? + else if (count == 6) + flags |= CharacterListFlags.SixthCharacterSlot; // 6th Character Slot + else if (a.Limit == 1) + flags |= CharacterListFlags.SlotLimit & + CharacterListFlags.OneCharacterSlot; // Limit Characters & One Character + + w.Write((int)flags); + + ns.Send(w.RawSpan); + + // TODO: Razor support? + } + + public static void SendCharacterListUpdate(NetState ns, IAccount a) + { + if (ns == null) + return; + + int highSlot = -1; + + for (int i = 0; i < a.Length; ++i) + if (a[i] != null) + highSlot = i; + + int count = Math.Max(Math.Max(highSlot + 1, a.Limit), 5); + + int length = 4 + count * 60; + + SpanWriter w = new SpanWriter(stackalloc byte[length]); + w.Write((byte)0x86); // Packet ID + w.Write((short)length); // Length + + w.Write((byte)count); + + for (int i = 0; i < count; ++i) + { + Mobile m = a[i]; + + if (m != null) + { + w.WriteAsciiFixed(m.Name, 30); + w.Position += 30; + } + else + w.Position += 60; + } + + ns.Send(w.RawSpan); + } + + public static void SendPlayServerAck(NetState ns, ServerInfo si) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(ns.SendPipe.Writer.GetSpan(11)); + w.Write((byte)0x8C); // Packet ID + + int addr = Utility.GetAddressValue(si.Address.Address); + + w.Write((byte)addr); + w.Write((byte)(addr >> 8)); + w.Write((byte)(addr >> 16)); + w.Write((byte)(addr >> 24)); + + w.Write((short)si.Address.Port); + w.Write(ns.m_AuthID); + + // Not compressed with Huffman + _ = ns.Flush(11); + } + + public static void SendAccountLoginAck(NetState ns, ServerInfo[] info) + { + if (ns == null) + return; + + int length = 6 + info.Length * 40; + + SpanWriter w = new SpanWriter(ns.SendPipe.Writer.GetSpan(length)); + w.Write((byte)0xA8); // Packet ID + w.Write((short)length); + + w.Write((byte)0x5D); // Unknown + + w.Write((ushort)info.Length); + + for (int i = 0; i < info.Length; ++i) + { + ServerInfo si = info[i]; + + w.Write((ushort)i); + w.WriteAsciiFixed(si.Name, 32, true); + w.Write((byte)si.FullPercent); + w.Write((sbyte)si.TimeZone); + w.Write(Utility.GetAddressValue(si.Address.Address)); + } + + // Not compressed with Huffman + _ = ns.Flush(length); + } + } +} diff --git a/Projects/Server/Network/Packets/Arrow.cs b/Projects/Server/Network/Packets/Arrow.cs new file mode 100644 index 000000000..373140c9b --- /dev/null +++ b/Projects/Server/Network/Packets/Arrow.cs @@ -0,0 +1,69 @@ +using Server.Buffers; + +namespace Server.Network +{ + public static partial class Packets + { + public static void SendSetArrow(NetState ns, short x, short y) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[6]); + w.Write((byte)0xBA); // Packet ID + + w.Write((byte)1); + w.Write(x); + w.Write(y); + + ns.Send(w.RawSpan); + } + + private static byte[] _cancelArrowPacket; + + public static void SendCancelArrow(NetState ns) + { + ns?.Send(_cancelArrowPacket ??= new byte[] + { + 0xBA, // Packet ID + 0x00, + 0xFF, + 0xFF, + 0xFF, + 0xFF + }); + } + + public static void SendSetArrowHS(NetState ns, Serial s, short x, short y) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[10]); + w.Write((byte)0xBA); // Packet ID + + w.Write((byte)1); + w.Write(x); + w.Write(y); + w.Write(s); + + ns.Send(w.RawSpan); + } + + public static void SendCancelArrowHS(NetState ns, Serial s, short x, short y) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[10]); + w.Write((byte)0xBA); // Packet ID + + w.Position++; + w.Write(x); + w.Write(y); + w.Write(s); + + ns.Send(w.RawSpan); + } + } +} diff --git a/Projects/Server/Network/Packets/Attributes.cs b/Projects/Server/Network/Packets/Attributes.cs new file mode 100644 index 000000000..b228912d5 --- /dev/null +++ b/Projects/Server/Network/Packets/Attributes.cs @@ -0,0 +1,168 @@ +using Server.Buffers; + +namespace Server.Network +{ + public static partial class Packets + { + public static class AttributeNormalizer + { + public static int Maximum { get; set; } = 25; + + public static bool Enabled { get; set; } = true; + + public static void Write(SpanWriter w, int cur, int max) + { + if (Enabled && max != 0) + { + w.Write((short)Maximum); + w.Write((short)(cur * Maximum / max)); + } + else + { + w.Write((short)max); + w.Write((short)cur); + } + } + + public static void WriteReverse(SpanWriter w, int cur, int max) + { + if (Enabled && max != 0) + { + w.Write((short)(cur * Maximum / max)); + w.Write((short)Maximum); + } + else + { + w.Write((short)cur); + w.Write((short)max); + } + } + } + + public static void SendMobileHits(NetState ns, Mobile m) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[9]); + w.Write((byte)0xA1); // Packet ID + + w.Write(m.Serial); + w.Write((short)m.HitsMax); + w.Write((short)m.Hits); + + ns.Send(w.RawSpan); + } + + public static void SendNormalizedMobileHits(NetState ns, Mobile m) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[9]); + w.Write((byte)0xA1); // Packet ID + + w.Write(m.Serial); + AttributeNormalizer.Write(w, m.Hits, m.HitsMax); + + ns.Send(w.RawSpan); + } + + public static void SendMobileMana(NetState ns, Mobile m) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[9]); + w.Write((byte)0xA2); // Packet ID + + w.Write(m.Serial); + w.Write((short)m.ManaMax); + w.Write((short)m.Mana); + + ns.Send(w.RawSpan); + } + + public static void SendNormalizedMobileMana(NetState ns, Mobile m) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[9]); + w.Write((byte)0xA2); // Packet ID + + w.Write(m.Serial); + AttributeNormalizer.Write(w, m.Mana, m.ManaMax); + + ns.Send(w.RawSpan); + } + + public static void SendMobileStam(NetState ns, Mobile m) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[9]); + w.Write((byte)0xA3); // Packet ID + + w.Write(m.Serial); + w.Write((short)m.StamMax); + w.Write((short)m.Stam); + + ns.Send(w.RawSpan); + } + + public static void SendNormalizedMobileStam(NetState ns, Mobile m) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[9]); + w.Write((byte)0xA3); // Packet ID + + w.Write(m.Serial); + AttributeNormalizer.Write(w, m.Stam, m.StamMax); + + ns.Send(w.RawSpan); + } + + public static void SendMobileAttributes(NetState ns, Mobile m) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[17]); + w.Write((byte)0x2D); // Packet ID + + w.Write(m.Serial); + + w.Write((short)m.HitsMax); + w.Write((short)m.Hits); + + w.Write((short)m.ManaMax); + w.Write((short)m.Mana); + + w.Write((short)m.StamMax); + w.Write((short)m.Stam); + + ns.Send(w.RawSpan); + } + + public static void SendNormalizedMobileAttributes(NetState ns, Mobile m) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[17]); + w.Write((byte)0x2D); // Packet ID + + w.Write(m.Serial); + + AttributeNormalizer.Write(w, m.Hits, m.HitsMax); + AttributeNormalizer.Write(w, m.Mana, m.ManaMax); + AttributeNormalizer.Write(w, m.Stam, m.StamMax); + + ns.Send(w.RawSpan); + } + } +} diff --git a/Projects/Server/Network/Packets/Containers.cs b/Projects/Server/Network/Packets/Containers.cs new file mode 100644 index 000000000..e57acd250 --- /dev/null +++ b/Projects/Server/Network/Packets/Containers.cs @@ -0,0 +1,217 @@ +using System; +using System.Collections.Generic; +using Server.Buffers; + +namespace Server.Network +{ + public static partial class Packets + { + public static void SendDisplayContainer(NetState ns, Serial s, short gumpId = -1) + { + if (ns == null) + return; + + if (ns.HighSeas) + SendDisplayContainerHS(ns, s, gumpId); + else + SendDisplayContainerOld(ns, s, gumpId); + } + + public static void SendDisplayContainerOld(NetState ns, Serial s, short gumpId = -1) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[7]); + w.Write((byte)0x24); // Packet ID + + w.Write(s); + w.Write(gumpId); + + ns.Send(w.RawSpan); + } + + public static void SendDisplayContainerHS(NetState ns, Serial s, short gumpId = -1) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[9]); + w.Write((byte)0x24); // Packet ID + + w.Write(s); + w.Write(gumpId); + w.Write((short)0x7D); + + ns.Send(w.RawSpan); + } + + public static void SendContainerContentUpdate(NetState ns, Item item) + { + if (ns == null) + return; + + if (ns.ContainerGridLines) + SendContainerContentUpdateNew(ns, item); + else + SendContainerContentUpdateOld(ns, item); + } + + public static void SendContainerContentUpdateOld(NetState ns, Item item) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[20]); + w.Write((byte)0x25); // Packet ID + + Serial parentSerial; + + if (item.Parent is Item parentItem) + parentSerial = parentItem.Serial; + else + { + Console.WriteLine("Warning: ContainerContentUpdate on item with !(parent is Item)"); + parentSerial = Serial.Zero; + } + + w.Write(item.Serial); + w.Write((ushort)item.ItemID); + w.Position++; // w.Write((byte)0); // signed, itemID offset + w.Write((ushort)item.Amount); + w.Write((short)item.X); + w.Write((short)item.Y); + w.Write(parentSerial); + w.Write((ushort)(item.QuestItem ? Item.QuestItemHue : item.Hue)); + + ns.Send(w.RawSpan); + } + + public static void SendContainerContentUpdateNew(NetState ns, Item item) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[21]); + w.Write((byte)0x25); // Packet ID + + Serial parentSerial; + + if (item.Parent is Item parentItem) + parentSerial = parentItem.Serial; + else + { + Console.WriteLine("Warning: ContainerContentUpdate on item with !(parent is Item)"); + parentSerial = Serial.Zero; + } + + w.Write(item.Serial); + w.Write((ushort)item.ItemID); + w.Position++; // signed, itemID offset + w.Write((ushort)item.Amount); + w.Write((short)item.X); + w.Write((short)item.Y); + w.Position++; // Grid Location? + w.Write(parentSerial); + w.Write((ushort)(item.QuestItem ? Item.QuestItemHue : item.Hue)); + + ns.Send(w.RawSpan); + } + + public static void SendContainerContent(NetState ns, Mobile beholder, Item beheld) + { + if (ns == null) + return; + + if (ns.ContainerGridLines) + SendContainerContentNew(ns, beholder, beheld); + else + SendContainerContentOld(ns, beholder, beheld); + } + + public static void SendContainerContentOld(NetState ns, Mobile beholder, Item beheld) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[5 + beheld.Items.Count * 19]); + w.Write((byte)0x3C); // Packet ID + w.Position += 4; // Dynamic Length, Item Count + + List items = beheld.Items; + int count = items.Count; + + ushort written = 0; + + for (int i = 0; i < count; ++i) + { + Item child = items[i]; + + if (!child.Deleted && beholder.CanSee(child)) + { + Point3D loc = child.Location; + + w.Write(child.Serial); + w.Write((ushort)child.ItemID); + w.Position++; // signed, itemID offset + w.Write((ushort)child.Amount); + w.Write((short)loc.m_X); + w.Write((short)loc.m_Y); + w.Write(beheld.Serial); + w.Write((ushort)(child.QuestItem ? Item.QuestItemHue : child.Hue)); + + ++written; + } + } + + w.Position = 1; + w.Write((ushort)w.WrittenCount); + w.Write(written); + + ns.Send(w.Span); + } + + public static void SendContainerContentNew(NetState ns, Mobile beholder, Item beheld) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[5 + beheld.Items.Count * 20]); + w.Write((byte)0x3C); // Packet ID + w.Position += 4; // Dynamic Length, Item Count + + List items = beheld.Items; + int count = items.Count; + + ushort written = 0; + + for (int i = 0; i < count; ++i) + { + Item child = items[i]; + + if (!child.Deleted && beholder.CanSee(child)) + { + Point3D loc = child.Location; + + w.Write(child.Serial); + w.Write((ushort)child.ItemID); + w.Position++; // signed, itemID offset + w.Write((ushort)child.Amount); + w.Write((short)loc.m_X); + w.Write((short)loc.m_Y); + w.Position++; // Grid Location? + w.Write(beheld.Serial); + w.Write((ushort)(child.QuestItem ? Item.QuestItemHue : child.Hue)); + + ++written; + } + } + + w.Position = 1; + w.Write((ushort)w.WrittenCount); + w.Write(written); + + ns.Send(w.Span); + } + } +} diff --git a/Projects/Server/Network/Packets/Damage.cs b/Projects/Server/Network/Packets/Damage.cs new file mode 100644 index 000000000..d7c734b8d --- /dev/null +++ b/Projects/Server/Network/Packets/Damage.cs @@ -0,0 +1,61 @@ +using Server.Buffers; + +namespace Server.Network +{ + public static partial class Packets + { + public static void SendDamage(NetState ns, Serial m, int amount) + { + if (ns == null) + return; + + if (ns.DamagePacket) + SendDamageNew(ns, m, amount); + else + SendDamageOld(ns, m, amount); + } + public static void SendDamageOld(NetState ns, Serial m, int amount) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[11]); + w.Write((byte)0xBF); // Extended Packet ID + w.Write((ushort)11); // Length + + w.Write((short)0x22); + w.Write((byte)1); + w.Write(m); + + if (amount > 255) + amount = 255; + else if (amount < 0) + amount = 0; + + w.Write((byte)amount); + + ns.Send(w.Span); + } + + public static void SendDamageNew(NetState ns, Serial m, int amount) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[9]); + w.Write((byte)0xBF); // Extended Packet ID + w.Write((ushort)9); // Length + + w.Write(m); + + if (amount > 0xFFFF) + amount = 0xFFFF; + else if (amount < 0) + amount = 0; + + w.Write((ushort)amount); + + ns.Send(w.Span); + } + } +} diff --git a/Projects/Server/Network/Packets/Effects.cs b/Projects/Server/Network/Packets/Effects.cs new file mode 100644 index 000000000..0ca33ac71 --- /dev/null +++ b/Projects/Server/Network/Packets/Effects.cs @@ -0,0 +1,283 @@ +using Server.Buffers; + +namespace Server.Network +{ + public enum EffectType : byte + { + Moving, + Lightning, + FixedXYZ, + FixedFrom, + Screen + } + + public enum ScreenEffectType : short + { + FadeOut, + FadeIn, + LightFlash, + FadeInOut, + DarkFlash + } + + public static partial class Packets + { + private static readonly int ParticleEffectPacketLength = 49; + private static readonly int HuedEffectPacketLength = 36; + private static readonly int OldEffectPacketLength = 28; + + public static void SendParticalEffect(NetState ns, EffectType type, Serial from, Serial to, + int itemId, IPoint3D fromPoint, IPoint3D toPoint, int speed, int duration, bool fixedDirection, + bool explode, int hue, int renderMode, int effect, int explodeEffect, int explodeSound, Serial serial, + int layer, int unknown) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[ParticleEffectPacketLength]); + w.Write((byte)0xC7); // Packet ID + + w.Write((byte)type); + w.Write(from); + w.Write(to); + w.Write((short)itemId); + w.Write((short)fromPoint.X); + w.Write((short)fromPoint.Y); + w.Write((sbyte)fromPoint.Z); + w.Write((short)toPoint.X); + w.Write((short)toPoint.Y); + w.Write((sbyte)toPoint.Z); + w.Write((byte)speed); + w.Write((byte)duration); + w.Position += 2; + // w.Write((byte)0); + // w.Write((byte)0); + w.Write(fixedDirection); + w.Write(explode); + w.Write(hue); + w.Write(renderMode); + w.Write((short)effect); + w.Write((short)explodeEffect); + w.Write((short)explodeSound); + w.Write(serial); + w.Write((byte)layer); + w.Write((short)unknown); + + ns.Send(w.RawSpan); + } + + public static void SendHuedEffect(NetState ns, EffectType type, Serial from, Serial to, int itemId, + IPoint3D fromPoint, IPoint3D toPoint, int speed, int duration, bool fixedDirection, bool explode, int hue, + int renderMode) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[HuedEffectPacketLength]); + w.Write((byte)0xC0); // Packet ID + + w.Write((byte)type); + w.Write(from); + w.Write(to); + w.Write((short)itemId); + w.Write((short)fromPoint.X); + w.Write((short)fromPoint.Y); + w.Write((sbyte)fromPoint.Z); + w.Write((short)toPoint.X); + w.Write((short)toPoint.Y); + w.Write((sbyte)toPoint.Z); + w.Write((byte)speed); + w.Write((byte)duration); + w.Position += 2; + // w.Write((byte)0); + // w.Write((byte)0); + w.Write(fixedDirection); + w.Write(explode); + w.Write(hue); + w.Write(renderMode); + + ns.Send(w.RawSpan); + } + + public static void SendScreenEffect(NetState ns, ScreenEffectType screen) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[HuedEffectPacketLength]); + w.Write((byte)0xC0); // Packet ID + + w.Write((byte)0x04); + w.Position += 8; + w.Write((short)screen); + + ns.Send(w.RawSpan); + } + + public static void SendScreenOldEffect(NetState ns, ScreenEffectType screen) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[OldEffectPacketLength]); + w.Write((byte)0x70); // Packet ID + + w.Write((byte)0x04); + w.Position += 8; + w.Write((short)screen); + + ns.Send(w.RawSpan); + } + + public static void SendBoltEffect(NetState ns, IEntity target) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[HuedEffectPacketLength]); + w.Write((byte)0xC0); // Packet ID + + w.Write((byte)0x01); + w.Write(target.Serial); + w.Position += 6; + w.Write((short)target.X); + w.Write((short)target.Y); + w.Write((sbyte)target.Z); + w.Write((short)target.X); + w.Write((short)target.Y); + w.Write((sbyte)target.Z); + + ns.Send(w.RawSpan); + } + + public static void SendOldBoltEffect(NetState ns, IEntity target) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[OldEffectPacketLength]); + w.Write((byte)0x70); // Packet ID + + w.Write((byte)0x01); + w.Write(target.Serial); + w.Position += 6; + w.Write((short)target.X); + w.Write((short)target.Y); + w.Write((sbyte)target.Z); + w.Write((short)target.X); + w.Write((short)target.Y); + w.Write((sbyte)target.Z); + + ns.Send(w.RawSpan); + } + + public static void SendEffect(NetState ns, EffectType type, Serial from, Serial to, int itemId, + IPoint3D fromPoint, IPoint3D toPoint, int speed, int duration, bool fixedDirection, bool explode) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[HuedEffectPacketLength]); + w.Write((byte)0xC0); // Packet ID + + w.Write((byte)type); + w.Write(from); + w.Write(to); + w.Write((short)itemId); + w.Write((short)fromPoint.X); + w.Write((short)fromPoint.Y); + w.Write((sbyte)fromPoint.Z); + w.Write((short)toPoint.X); + w.Write((short)toPoint.Y); + w.Write((sbyte)toPoint.Z); + w.Write((byte)speed); + w.Write((byte)duration); + w.Position += 2; + // w.Write((byte)0); + // w.Write((byte)0); + w.Write(fixedDirection); + w.Write(explode); + + ns.Send(w.RawSpan); + } + + public static void SendOldEffect(NetState ns, EffectType type, Serial from, Serial to, int itemId, + IPoint3D fromPoint, IPoint3D toPoint, int speed, int duration, bool fixedDirection, bool explode) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[OldEffectPacketLength]); + w.Write((byte)0x70); // Packet ID + + w.Write((byte)type); + w.Write(from); + w.Write(to); + w.Write((short)itemId); + w.Write((short)fromPoint.X); + w.Write((short)fromPoint.Y); + w.Write((sbyte)fromPoint.Z); + w.Write((short)toPoint.X); + w.Write((short)toPoint.Y); + w.Write((sbyte)toPoint.Z); + w.Write((byte)speed); + w.Write((byte)duration); + w.Position += 2; + // w.Write((byte)0); + // w.Write((byte)0); + w.Write(fixedDirection); + w.Write(explode); + + ns.Send(w.RawSpan); + } + + public static void SendLocationParticleEffect(NetState ns, IEntity e, int itemId, int speed, int duration, int hue, int renderMode, + int effect, int unknown) + { + SendParticalEffect(ns, EffectType.FixedXYZ, e.Serial, Serial.Zero, itemId, e.Location, e.Location, speed, duration, + true, false, hue, renderMode, effect, 1, 0, e.Serial, 255, unknown); + } + + public static void SendLocationHuedEffect(NetState ns, IPoint3D p, int itemId, int speed, int duration, int hue, int renderMode) + { + SendHuedEffect(ns, EffectType.FixedXYZ, Serial.Zero, Serial.Zero, itemId, p, p, speed, duration, true, false, + hue, renderMode); + } + + public static void SendMovingParticleEffect(NetState ns, IEntity from, IEntity to, int itemId, int speed, int duration, bool fixedDirection, + bool explodes, int hue, int renderMode, int effect, int explodeEffect, int explodeSound, EffectLayer layer, + int unknown) + { + SendParticalEffect(ns, EffectType.Moving, from.Serial, to.Serial, itemId, from.Location, to.Location, speed, + duration, fixedDirection, explodes, hue, renderMode, effect, explodeEffect, explodeSound, Serial.Zero, + (int)layer, unknown); + } + + public static void SendMovingHuedEffect(NetState ns, IEntity from, IEntity to, int itemId, int speed, int duration, bool fixedDirection, + bool explodes, int hue, int renderMode) + { + SendHuedEffect(ns, EffectType.Moving, from.Serial, to.Serial, itemId, from.Location, + to.Location, speed, duration, fixedDirection, explodes, hue, renderMode); + } + + public static void SendMovingHuedEffect(NetState ns, IPoint3D from, IPoint3D to, int itemId, int speed, int duration, bool fixedDirection, + bool explodes, int hue, int renderMode) + { + SendHuedEffect(ns, EffectType.Moving, Serial.Zero, Serial.Zero, itemId, from, + to, speed, duration, fixedDirection, explodes, hue, renderMode); + } + + public static void SendTargetParticleEffect(NetState ns, IEntity e, int itemId, int speed, int duration, int hue, int renderMode, + int effect, int layer, int unknown) + { + SendParticalEffect(ns, EffectType.FixedFrom, e.Serial, Serial.Zero, itemId, e.Location, e.Location, + speed, duration, true, false, hue, renderMode, effect, 1, 0, e.Serial, layer, unknown); + } + + public static void SendTargetHuedEffect(NetState ns, IEntity e, int itemId, int speed, int duration, int hue, int renderMode) + { + SendHuedEffect(ns, EffectType.FixedFrom, e.Serial, Serial.Zero, itemId, e.Location, e.Location, speed, duration, + true, false, hue, renderMode); + } + } +} diff --git a/Projects/Server/Network/Packets/Gumps.cs b/Projects/Server/Network/Packets/Gumps.cs new file mode 100644 index 000000000..9591a5dfc --- /dev/null +++ b/Projects/Server/Network/Packets/Gumps.cs @@ -0,0 +1,94 @@ +using System.Buffers; +using System.Collections.Generic; +using Server.Buffers; +using Server.Gumps; + +namespace Server.Network +{ + public interface IGumpWriter + { + int TextEntries { get; set; } + int Switches { get; set; } + ArrayBufferWriter Layout { get; } + + int Intern(string value); + void WriteStrings(List strings); + void Flush(NetState ns); + } + + public static partial class Packets + { + public static void SendCloseGump(NetState ns, int typeId, int buttonId) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[13]); + w.Write((byte)0xBF); // Packet ID + w.Write((short)13); // Length + + w.Write((short)0x04); // Command + w.Write(typeId); + w.Write(buttonId); + + ns.Send(w.Span); + } + + public static void SendDisplayGump(NetState ns, Gump g, string layout, string[] text) + { + if (ns == null) + return; + + layout ??= ""; + + // Assume no longer than 128 characters per text element + SpanWriter w = new SpanWriter(stackalloc byte[20 + layout.Length + 1 + (258 * text?.Length ?? 0)]); + w.Write((byte)0xB0); // Packet ID + w.Position += 2; // Dynamic Length + + w.Write(g.Serial); + w.Write(g.TypeID); + w.Write(g.X); + w.Write(g.Y); + w.Write((ushort)(layout.Length + 1)); + w.WriteAsciiNull(layout); + + w.Write((ushort)(text?.Length ?? 0)); + + for (int i = 0; i < text?.Length; ++i) + { + string v = text[i] ?? ""; + + ushort length = (ushort)v.Length; + + w.Write(length); + w.WriteBigUni(v); + } + + w.Position = 1; + w.Write((ushort)w.WrittenCount); + + ns.Send(w.Span); + } + + public static void SendDisplaySignGump(NetState ns, Serial serial, int gumpId, string unknown, string caption) + { + if (ns == null) + return; + + int length = 14 + caption.Length + unknown.Length; + SpanWriter w = new SpanWriter(stackalloc byte[length]); + w.Write((byte)0x8B); // Packet ID + w.Write((short)length); + + w.Write(serial); + w.Write((short)gumpId); + w.Write((short)unknown.Length); + w.WriteAsciiFixed(unknown, unknown.Length); + w.Write((short)(caption.Length + 1)); + w.WriteAsciiFixed(caption, caption.Length); + + ns.Send(w.Span); + } + } +} diff --git a/Projects/Server/Network/Packets/Items.cs b/Projects/Server/Network/Packets/Items.cs new file mode 100644 index 000000000..ccc42e042 --- /dev/null +++ b/Projects/Server/Network/Packets/Items.cs @@ -0,0 +1,330 @@ +using Server.Buffers; +using Server.Items; + +namespace Server.Network +{ + public enum LRReason : byte + { + CannotLift, + OutOfRange, + OutOfSight, + TryToSteal, + AreHolding, + Unspecific + } + + public static partial class Packets + { + public static void SendWorldItem(NetState ns, Item item) + { + if (ns == null) + return; + + if (ns.HighSeas) + SendWorldItemHS(ns, item); + else if (ns.StygianAbyss) + SendWorldItemSA(ns, item); + else + SendWorldItemOld(ns, item); + } + + public static void SendWorldItemOld(NetState ns, Item item) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[20]); + w.Write((byte)0x1A); // Packet ID + w.Position += 2; // Dynamic Length + + uint serial = item.Serial.Value; + int itemId = item.ItemID & 0x3FFF; + int amount = item.Amount; + Point3D loc = item.Location; + int x = loc.m_X; + int y = loc.m_Y; + int hue = item.Hue; + int flags = item.GetPacketFlags(); + int direction = (int)item.Direction; + + if (amount != 0) + serial |= 0x80000000; + else + serial &= 0x7FFFFFFF; + + w.Write(serial); + + if (item is BaseMulti) + w.Write((short)(itemId | 0x4000)); + else + w.Write((short)itemId); + + if (amount != 0) + w.Write((short)amount); + + x &= 0x7FFF; + + if (direction != 0) x |= 0x8000; + + w.Write((short)x); + + y &= 0x3FFF; + + if (hue != 0) y |= 0x8000; + + if (flags != 0) y |= 0x4000; + + w.Write((short)y); + + if (direction != 0) + w.Write((byte)direction); + + w.Write((sbyte)loc.m_Z); + + if (hue != 0) + w.Write((ushort)hue); + + if (flags != 0) + w.Write((byte)flags); + + w.Position = 1; + w.Write((ushort)w.WrittenCount); + + ns.Send(w.Span); + } + + public static void SendWorldItemSA(NetState ns, Item item) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[24]); + w.Write((byte)0xF3); // Packet ID + + w.Write((short)0x01); + + int itemId = item.ItemID; + + if (item is BaseMulti) + { + w.Write((byte)0x02); + + w.Write(item.Serial); + + itemId &= 0x3FFF; + + w.Write((short)itemId); + + w.Position++; // w.Write((byte)0); + } + else + { + w.Position++; // w.Write((byte)0); + + w.Write(item.Serial); + + itemId &= 0x7FFF; + + w.Write((short)itemId); + + w.Write((byte)item.Direction); + } + + short amount = (short)item.Amount; + w.Write(amount); + w.Write(amount); + + Point3D loc = item.Location; + w.Write((short)(loc.m_X & 0x7FFF)); + w.Write((short)(loc.m_Y & 0x3FFF)); + w.Write((sbyte)loc.m_Z); + + w.Write((byte)item.Light); + w.Write((short)item.Hue); + w.Write((byte)item.GetPacketFlags()); + + ns.Send(w.Span); + } + + public static void SendWorldItemHS(NetState ns, Item item) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[26]); + w.Write((byte)0xF3); // Packet ID + + w.Write((short)0x01); + + int itemId = item.ItemID; + + if (item is BaseMulti) + { + w.Write((byte)0x02); + + w.Write(item.Serial); + + itemId &= 0x3FFF; + + w.Write((short)itemId); + + w.Position++; // w.Write((byte)0); + } + else + { + w.Position++; // w.Write((byte)0); + + w.Write(item.Serial); + + itemId &= 0x7FFF; + + w.Write((short)itemId); + + w.Write((byte)item.Direction); + } + + short amount = (short)item.Amount; + w.Write(amount); + w.Write(amount); + + Point3D loc = item.Location; + w.Write((short)(loc.m_X & 0x7FFF)); + w.Write((short)(loc.m_Y & 0x3FFF)); + w.Write((sbyte)loc.m_Z); + + w.Write((byte)item.Light); + w.Write((short)item.Hue); + w.Write((byte)item.GetPacketFlags()); + w.Position += 2; + + ns.Send(w.Span); + } + + public static void SendLiftRej(NetState ns, LRReason reason) + { + ns?.Send(stackalloc byte[] + { + 0x27, // Packet ID + (byte)reason + }); + } + + public static void SendSpellbookContent(NetState ns, Serial s, int count, int offset, ulong content) + { + if (ns == null) + return; + + if (ObjectPropertyList.Enabled && ns.NewSpellbook) + SendSpellbookContentNew(ns, s, count, offset, content); + else if (ns.ContainerGridLines) + SendSpellbookContent6017(ns, s, count, offset, content); + else + SendSpellbookContentOld(ns, s, count, offset, content); + } + + public static void SendSpellbookContentOld(NetState ns, Serial s, int count, int offset, ulong content) + { + if (ns == null) + return; + + int length = 5 + count * 19; + SpanWriter w = new SpanWriter(stackalloc byte[length]); + w.Write((byte)0x3C); // Packet ID + w.Write((short)length); // Length + + // This should always be the same as written + w.Write((ushort)count); + + ulong mask = 1; + + for (int i = 0; i < 64; ++i, mask <<= 1) + if ((content & mask) != 0) + { + w.Write(0x7FFFFFFF - i); + w.Position += 3; + w.Write((ushort)(i + offset)); + w.Position += 4; + w.Write(s); + w.Position += 2; + } + + ns.Send(w.Span); + } + + public static void SendSpellbookContent6017(NetState ns, Serial s, int count, int offset, ulong content) + { + if (ns == null) + return; + + int length = 5 + count * 20; + SpanWriter w = new SpanWriter(stackalloc byte[length]); + w.Write((byte)0x3C); // Packet ID + w.Write((short)length); // Length + + // This should always be the same as written + w.Write((ushort)count); + + ulong mask = 1; + + for (int i = 0; i < 64; ++i, mask <<= 1) + if ((content & mask) != 0) + { + w.Write(0x7FFFFFFF - i); + w.Position += 3; + w.Write((ushort)(i + offset)); + w.Position += 5; // Grid Location? + w.Write(s); + w.Position += 2; + } + + ns.Send(w.Span); + } + + public static void SendSpellbookContentNew(NetState ns, Serial s, int graphic, int offset, ulong content) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[23]); + w.Write((byte)0x3C); // Packet ID + w.Write((short)23); // Length + + + w.Write((short)0x1B); + w.Write((short)0x01); + + w.Write(s); + w.Write((short)graphic); + w.Write((short)offset); + + for (int i = 0; i < 8; ++i) + w.Write((byte)(content >> (i * 8))); + + ns.Send(w.Span); + } + + public static void SendDragEffect(NetState ns, IEntity src, IEntity trg, int itemID, int hue, int amount) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[26]); + w.Write((byte)0x23); // Packet ID + + w.Write((short)itemID); + w.Position++; // w.Write((byte)0); + w.Write((short)hue); + w.Write((short)amount); + w.Write(src.Serial); + w.Write((short)src.X); + w.Write((short)src.Y); + w.Write((sbyte)src.Z); + w.Write(trg.Serial); + w.Write((short)trg.X); + w.Write((short)trg.Y); + w.Write((sbyte)trg.Z); + + ns.Send(w.Span); + } + } +} diff --git a/Projects/Server/Network/Packets/Map.cs b/Projects/Server/Network/Packets/Map.cs new file mode 100644 index 000000000..336a859e6 --- /dev/null +++ b/Projects/Server/Network/Packets/Map.cs @@ -0,0 +1,72 @@ +using Server.Buffers; + +namespace Server.Network +{ + public static partial class Packets + { + private static byte[] m_MapPatchesPacket; + + public static void SendMapPatches(NetState ns) + { + if (ns == null) + return; + + if (m_MapPatchesPacket == null) + { + SpanWriter w = new SpanWriter(m_MapPatchesPacket = new byte[57]); + w.Write((byte)0xBF); // Extended Packet ID + w.Write((ushort)57); // Dynamic Length + + w.Write((short)0x18); // Map Patches + w.Write(6); // Map count + + w.Write(Map.Felucca.Tiles.Patch.StaticBlocks); + w.Write(Map.Felucca.Tiles.Patch.LandBlocks); + + w.Write(Map.Trammel.Tiles.Patch.StaticBlocks); + w.Write(Map.Trammel.Tiles.Patch.LandBlocks); + + w.Write(Map.Ilshenar.Tiles.Patch.StaticBlocks); + w.Write(Map.Ilshenar.Tiles.Patch.LandBlocks); + + w.Write(Map.Malas.Tiles.Patch.StaticBlocks); + w.Write(Map.Malas.Tiles.Patch.LandBlocks); + + w.Write(Map.Tokuno.Tiles.Patch.StaticBlocks); + w.Write(Map.Tokuno.Tiles.Patch.LandBlocks); + + w.Write(Map.TerMur.Tiles.Patch.StaticBlocks); + w.Write(Map.TerMur.Tiles.Patch.LandBlocks); + } + + ns.Send(m_MapPatchesPacket); + } + + private static readonly byte[][][] _seasonChangePackets = { + new byte[2][], new byte[2][], new byte[2][], new byte[2][], new byte[2][] + }; + + public static void SendSeasonChange(NetState ns, byte season, byte playSound) + { + ns?.Send(_seasonChangePackets[season][playSound] ??= new byte[] + { + 0xBC, // Packet ID + season, + playSound + }); + } + + public static void SendMapChange(NetState ns, Map map) + { + ns?.Send(stackalloc byte[6] + { + 0xBF, // Extended Packet ID + 0x00, + 0x06, // Length + 0x00, + 0x08, // Command + (byte)(map?.MapID ?? 0) + }); + } + } +} diff --git a/Projects/Server/Network/Packets/Menus.cs b/Projects/Server/Network/Packets/Menus.cs new file mode 100644 index 000000000..a17af9506 --- /dev/null +++ b/Projects/Server/Network/Packets/Menus.cs @@ -0,0 +1,235 @@ +using System; +using Server.Buffers; +using Server.ContextMenus; +using Server.Menus; + +namespace Server.Network +{ + [Flags] + public enum CMEFlags + { + None = 0x00, + Disabled = 0x01, + Arrow = 0x02, + Highlighted = 0x04, + Colored = 0x20 + } + + public static partial class Packets + { + public static void SendDisplayItemListMenu(NetState ns, ItemListMenu menu) + { + if (ns == null) + return; + + // 10 + 128 + (255 * (128 + 5)) + SpanWriter w = new SpanWriter(stackalloc byte[138 + menu.Entries.Length * 133]); + w.Write((byte)0x7C); // Packet ID + w.Position += 2; // Dynamic Length + + w.Write(menu.Serial); + w.Position += 2; // w.Write((short)0); + + string question = menu.Question; + + if (question == null) + w.Position++; // w.Write((byte)0); + else + { + int questionLength = question.Length; + w.Write((byte)questionLength); + w.WriteAsciiFixed(question, questionLength); + } + + ItemListEntry[] entries = menu.Entries; + + int entriesLength = (byte)entries.Length; + + w.Write((byte)entriesLength); + + for (int i = 0; i < entriesLength; ++i) + { + ItemListEntry e = entries[i]; + + w.Write((ushort)e.ItemID); + w.Write((short)e.Hue); + + string name = e.Name; + + if (name == null) + w.Position++; // w.Write((byte)0); + else + { + int nameLength = name.Length; + w.Write((byte)nameLength); + w.WriteAsciiFixed(name, nameLength); + } + } + + w.Position = 1; + w.Write((ushort)w.WrittenCount); + + ns.Send(w.Span); + } + + public static void SendDisplayQuestionMenu(NetState ns, QuestionMenu menu) + { + if (ns == null) + return; + + // 10 + 128 + (255 * (128 + 5)) + SpanWriter w = new SpanWriter(stackalloc byte[138 + menu.Answers.Length * 133]); + w.Write((byte)0x7C); // Packet ID + w.Position += 2; // Dynamic Length + + w.Write(menu.Serial); + w.Position += 2; // w.Write((short)0); + + string question = menu.Question; + + if (question == null) + w.Position++; // w.Write((byte)0); + else + { + int questionLength = question.Length; + w.Write((byte)questionLength); + w.WriteAsciiFixed(question, questionLength); + } + + string[] answers = menu.Answers; + + int answersLength = (byte)answers.Length; + + w.Write((byte)answersLength); + + for (int i = 0; i < answersLength; ++i) + { + w.Position += 4; // w.Write(0); + + string answer = answers[i]; + + if (answer == null) + w.Position++; // w.Write((byte)0); + else + { + int answerLength = answer.Length; + w.Write((byte)answerLength); + w.WriteAsciiFixed(answer, answerLength); + } + } + + w.Position = 1; + w.Write((ushort)w.WrittenCount); + + ns.Send(w.Span); + } + + public static void SendDisplayContextMenu(NetState ns, ContextMenu menu) + { + if (ns == null) + return; + + ContextMenuEntry[] entries = menu.Entries; + + int length = 12 + entries.Length * 8; + SpanWriter w = new SpanWriter(stackalloc byte[length]); + w.Write((byte)0xBF); // Packet ID + w.Write((short)length); // Length + + w.Write((short)0x14); // Command + w.Write((short)0x02); + + IEntity target = menu.Target as IEntity; + + w.Write(target?.Serial ?? Serial.MinusOne); + + w.Write((byte)entries.Length); + + Point3D p; + + if (target is Mobile) + p = target.Location; + else if (target is Item item) + p = item.GetWorldLocation(); + else + p = Point3D.Zero; + + for (int i = 0; i < entries.Length; ++i) + { + ContextMenuEntry e = entries[i]; + + w.Write(e.Number); + w.Write((short)i); + + int range = e.Range; + + if (range == -1) + range = 18; + + w.Write((short)(e.Flags | (e.Enabled && menu.From.InRange(p, range) ? CMEFlags.None : CMEFlags.Disabled))); + } + + ns.Send(w.Span); + } + + public static void SendDisplayContextMenuOld(NetState ns, ContextMenu menu) + { + if (ns == null) + return; + + ContextMenuEntry[] entries = menu.Entries; + + SpanWriter w = new SpanWriter(stackalloc byte[12 + entries.Length * 8]); + w.Write((byte)0xBF); // Packet ID + w.Position += 2; // Dynamic Length + + w.Write((short)0x14); // Command + w.Write((short)0x01); // Old! + + IEntity target = menu.Target as IEntity; + + w.Write(target?.Serial ?? Serial.MinusOne); + + w.Write((byte)entries.Length); + + Point3D p; + + if (target is Mobile) + p = target.Location; + else if (target is Item item) + p = item.GetWorldLocation(); + else + p = Point3D.Zero; + + for (int i = 0; i < entries.Length; ++i) + { + ContextMenuEntry e = entries[i]; + + w.Write((short)i); + w.Write((ushort)(e.Number - 3000000)); + + int range = e.Range; + + if (range == -1) + range = 18; + + CMEFlags flags = e.Flags | (e.Enabled && menu.From.InRange(p, range) ? CMEFlags.None : CMEFlags.Disabled); + + int color = e.Color & 0xFFFF; + + if (color != 0xFFFF) + flags |= CMEFlags.Colored; + + w.Write((short)flags); + + if ((flags & CMEFlags.Colored) != 0) + w.Write((short)color); + } + + w.Position = 1; + w.Write((ushort)w.WrittenCount); + + ns.Send(w.Span); + } + } +} diff --git a/Projects/Server/Network/Packets/Messages.cs b/Projects/Server/Network/Packets/Messages.cs new file mode 100644 index 000000000..5a4426f30 --- /dev/null +++ b/Projects/Server/Network/Packets/Messages.cs @@ -0,0 +1,161 @@ +using System; +using System.Collections.Generic; +using Server.Buffers; + +namespace Server.Network +{ + [Flags] + public enum AffixType : byte + { + Append = 0x00, + Prepend = 0x01, + System = 0x02 + } + + public static partial class Packets + { + private static readonly Dictionary _messageLocalizedPackets = new Dictionary(); + + public static void SendMessageLocalized(NetState ns, int number) + { + if (ns == null) + return; + + if (_messageLocalizedPackets.TryGetValue(number, out byte[] packet)) + { + ns.Send(packet); + return; + } + + SpanWriter w = new SpanWriter(packet = new byte[50]); + w.Write((byte)0xC1); // Packet ID + w.Write((short)50); // Length + + w.Write(Serial.MinusOne); + w.Write((short)-1); + w.Position++; // w.Write((byte)MessageType.Regular); + w.Write((short)0x3B2); + w.Write((short)3); + w.Write(number); + w.WriteAsciiFixed("System", 30); + + _messageLocalizedPackets[number] = packet; + + ns.Send(packet); + } + + public static void SendMessageLocalized(NetState ns, Serial serial, int graphic, MessageType type, int hue, int font, int number, string name = "", + string args = "") + { + if (ns == null) + return; + + int length = 50 + args.Length * 2; + + SpanWriter w = new SpanWriter(stackalloc byte[length]); + w.Write((byte)0xC1); // Packet ID + w.Write((short)length); // Length + + if (hue == 0) hue = 0x3B2; + + w.Write(serial); + w.Write((short)graphic); + w.Write((byte)type); + w.Write((short)hue); + w.Write((short)font); + w.Write(number); + w.WriteAsciiFixed(name ?? "", 30); + w.WriteLittleUniNull(args); + + ns.Send(w.Span); + } + + public static void SendMessageLocalizedAffix(NetState ns, Serial serial, int graphic, MessageType type, int hue, int font, int number, + string name = "", AffixType affixType = AffixType.System, string affix = "", string args = "") + { + if (ns == null) + return; + + affix ??= ""; + args ??= ""; + + if (hue == 0) hue = 0x3B2; + + int length = 52 + affix.Length + args.Length * 2; + + SpanWriter w = new SpanWriter(stackalloc byte[length]); + w.Write((byte)0xCC); // Packet ID + w.Write((short)length); // Length + + w.Write(serial); + w.Write((short)graphic); + w.Write((byte)type); + w.Write((short)hue); + w.Write((short)font); + w.Write(number); + w.Write((byte)affixType); + w.WriteAsciiFixed(name ?? "", 30); + w.WriteAsciiNull(affix); + w.WriteBigUniNull(args); // Not little endian? Ugh + + ns.Send(w.Span); + } + + // TODO: Handle IEnumerable + public static void SendAsciiMessage(NetState ns, Serial serial, int graphic, MessageType type, int hue, int font, string name, string text) + { + if (ns == null) + return; + + text ??= ""; + + if (hue == 0) hue = 0x3B2; + + int length = 45 + text.Length; + + SpanWriter w = new SpanWriter(stackalloc byte[length]); + w.Write((byte)0x1C); // Packet ID + w.Write((short)length); // Length + + w.Write(serial); + w.Write((short)graphic); + w.Write((byte)type); + w.Write((short)hue); + w.Write((short)font); + w.WriteAsciiFixed(name ?? "", 30); + w.WriteAsciiNull(text); + + ns.Send(w.Span); + } + + // TODO: Handle IEnumerable + public static void SendUnicodeMessage(NetState ns, Serial serial, int graphic, MessageType type, int hue, int font, string lang, string name, + string text) + { + if (ns == null) + return; + + if (string.IsNullOrEmpty(lang)) lang = "ENU"; + name ??= ""; + text ??= ""; + if (hue == 0) hue = 0x3B2; + + int length = 50 + text.Length * 2; + + SpanWriter w = new SpanWriter(stackalloc byte[length]); + w.Write((byte)0xAE); // Packet ID + w.Write((short)length); // Length + + w.Write(serial); + w.Write((short)graphic); + w.Write((byte)type); + w.Write((short)hue); + w.Write((short)font); + w.WriteAsciiFixed(lang, 4); + w.WriteAsciiFixed(name, 30); + w.WriteBigUniNull(text); + + ns.Send(w.Span); + } + } +} diff --git a/Projects/Server/Network/Packets/Mobiles.cs b/Projects/Server/Network/Packets/Mobiles.cs new file mode 100644 index 000000000..fd55b230b --- /dev/null +++ b/Projects/Server/Network/Packets/Mobiles.cs @@ -0,0 +1,959 @@ +using System; +using System.Collections.Generic; +using Server.Buffers; +using Server.Items; + +namespace Server.Network +{ + public static partial class Packets + { + public static void SendDeathAnimation(NetState ns, Serial killed, Serial corpse) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[13]); + w.Write((byte)0xAF); // Packet ID + + w.Write(killed); + w.Write(corpse); + w.Position++; w.Write(0); + + ns.Send(w.Span); + } + + public static void SendStatLockInfo(NetState ns, Mobile m) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[12]); + w.Write((byte)0xBF); // Extended Packet ID + w.Write((short)12); // Length + + w.Write((short)0x19); // Subcommand + w.Write((byte)2); + w.Write(m.Serial); + w.Write((short)((int)m.StrLock << 4 | (int)m.DexLock << 2 | (int)m.IntLock)); + + ns.Send(w.Span); + } + + public static void SendBondStatus(NetState ns, Serial m, bool bonded) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[11]); + w.Write((byte)0xBF); // Extended Packet ID + w.Write((short)11); // Length + + w.Write((short)0x19); // Command + w.Position++; // w.Write((byte)0); // Subcommand + w.Write(m); + w.Write(bonded); + + ns.Send(w.Span); + } + + public static void SendPersonalLightLevel(NetState ns, Serial m, sbyte level) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[6]); + w.Write((byte)0x4E); // Packet ID + + w.Write(m); + w.Write(level); + + ns.Send(w.Span); + } + + public static void SendPersonalLightLevelZero(NetState ns, Serial m) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[6]); + w.Write((byte)0x4E); // Packet ID + + w.Write(m); + w.Position++; // level 0 + + ns.Send(w.Span); + } + + public static void SendEquipUpdate(NetState ns, Item item) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[15]); + w.Write((byte)0x2E); // Packet ID + + Serial parentSerial = Serial.Zero; + int hue = item.Hue; + + if (item.Parent is Mobile parent) + { + parentSerial = parent.Serial; + if (parent.SolidHueOverride >= 0) + hue = parent.SolidHueOverride; + } + else + Console.WriteLine("Warning: EquipUpdate on item with an invalid parent"); + + w.Write(item.Serial); + w.Write((short)item.ItemID); + w.Write((short)item.Layer); + w.Write(parentSerial); + w.Write((short)hue); + + ns.Send(w.Span); + } + + public static void SendSwing(NetState ns, Serial attacker, Serial defender) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[10]); + w.Write((byte)0x2F); // Packet ID + + w.Position++; // ? + w.Write(attacker); + w.Write(defender); + + ns.Send(w.Span); + } + + public static void SendMobileMoving(NetState ns, Mobile m, int noto) + { + if (ns == null) + return; + + if (ns.StygianAbyss) + SendMobileMovingNew(ns, m, noto); + else + SendMobileMovingOld(ns, m, noto); + } + + public static void SendMobileMovingNew(NetState ns, Mobile m, int noto) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[17]); + w.Write((byte)0x77); // Packet ID + + Point3D loc = m.Location; + + w.Write(m.Serial); + w.Write((short)m.Body); + w.Write((short)loc.m_X); + w.Write((short)loc.m_Y); + w.Write((sbyte)loc.m_Z); + w.Write((byte)m.Direction); + w.Write((short)(m.SolidHueOverride >= 0 ? m.SolidHueOverride : m.Hue)); + w.Write((byte)m.GetPacketFlags()); + w.Write((byte)noto); + + ns.Send(w.Span); + } + + public static void SendMobileMovingOld(NetState ns, Mobile m, int noto) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[17]); + w.Write((byte)0x77); // Packet ID + + Point3D loc = m.Location; + + w.Write(m.Serial); + w.Write((short)m.Body); + w.Write((short)loc.m_X); + w.Write((short)loc.m_Y); + w.Write((sbyte)loc.m_Z); + w.Write((byte)m.Direction); + w.Write((short)(m.SolidHueOverride >= 0 ? m.SolidHueOverride : m.Hue)); + w.Write((byte)m.GetOldPacketFlags()); + w.Write((byte)noto); + + ns.Send(w.Span); + } + + public static void SendDisplayPaperdoll(NetState ns, Mobile m, string text, bool canLift) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[66]); + w.Write((byte)0x88); // Packet ID + + byte flags = 0x00; + + if (m.Warmode) + flags |= 0x01; + + if (canLift) + flags |= 0x02; + + w.Write(m.Serial); + w.WriteAsciiFixed(text, 60); + w.Write(flags); + + ns.Send(w.Span); + } + + public static void SendMobileName(NetState ns, Mobile m) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[37]); + w.Write((byte)0x98); // Packet ID + w.Write((ushort)37); // Dynamic Length + + w.Write(m.Serial); + w.WriteAsciiFixed(m.Name ?? "", 30); + + ns.Send(w.Span); + } + + public static void SendMobileAnimation(NetState ns, Mobile m, int action, int frameCount, int repeatCount, bool forward, bool repeat, int delay) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[14]); + w.Write((byte)0x6E); // Packet ID + + w.Write(m.Serial); + w.Write((short)action); + w.Write((short)frameCount); + w.Write((short)repeatCount); + w.Write(!forward); // protocol has really "reverse" but I find this more intuitive + w.Write(repeat); + w.Write((byte)delay); + + ns.Send(w.Span); + } + + public static void SendNewMobileAnimation(NetState ns, Mobile m, int action, int frameCount, int delay) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[10]); + w.Write((byte)0xE2); // Packet ID + + w.Write(m.Serial); + w.Write((short)action); + w.Write((short)frameCount); + w.Write((byte)delay); + + ns.Send(w.Span); + } + + public static void SendMobileStatusCompact(NetState ns, Mobile m, bool canBeRenamed = false) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[43]); + w.Write((byte)0x11); // Packet ID + w.Write((ushort)43); // Length + + w.Write(m.Serial); + w.WriteAsciiFixed(m.Name ?? "", 30); + + AttributeNormalizer.WriteReverse(w, m.Hits, m.HitsMax); + + w.Write(canBeRenamed); + + w.Position++; // type + + ns.Send(w.Span); + } + + public static void SendMobileStatusExtended(NetState to, Mobile m) + { + SendMobileStatusExtended(to, m, m.NetState); + } + + public static void SendMobileStatusExtended(NetState to, Mobile m, NetState ns) + { + if (to == null) + return; + + byte type; + short length; + + if (Core.HS && ns?.ExtendedStatus == true) + { + type = 6; + length = 121; + } + else if (Core.ML && ns?.SupportsExpansion(Expansion.ML) == true) + { + type = 5; + length = 91; + } + else if (Core.AOS) + { + type = 4; + length = 88; + } + else + { + type = 3; + length = 70; + } + + SpanWriter w = new SpanWriter(stackalloc byte[length]); + w.Write((byte)0x11); // Packet ID + w.Write(length); // Length + + w.Write(m.Serial); + w.WriteAsciiFixed(m.Name ?? "", 30); + + w.Write((short)m.Hits); + w.Write((short)m.HitsMax); + + w.Write(m.CanBeRenamedBy(m)); + + w.Write(type); + + w.Write(m.Female); + + w.Write((short)m.Str); + w.Write((short)m.Dex); + w.Write((short)m.Int); + + w.Write((short)m.Stam); + w.Write((short)m.StamMax); + + w.Write((short)m.Mana); + w.Write((short)m.ManaMax); + + w.Write(m.TotalGold); + w.Write((short)(Core.AOS ? m.PhysicalResistance : (int)(m.ArmorRating + 0.5))); + w.Write((short)(Mobile.BodyWeight + m.TotalWeight)); + + if (type >= 5) + { + w.Write((short)m.MaxWeight); + w.Write((byte)(m.Race.RaceID + 1)); // Would be 0x00 if it's a non-ML enabled account but... + } + + w.Write((short)m.StatCap); + + w.Write((byte)m.Followers); + w.Write((byte)m.FollowersMax); + + if (type >= 4) + { + w.Write((short)m.FireResistance); // Fire + w.Write((short)m.ColdResistance); // Cold + w.Write((short)m.PoisonResistance); // Poison + w.Write((short)m.EnergyResistance); // Energy + w.Write((short)m.Luck); // Luck + + IWeapon weapon = m.Weapon; + + if (weapon != null) + { + weapon.GetStatusDamage(m, out int min, out int max); + w.Write((short)min); // Damage min + w.Write((short)max); // Damage max + } + else + w.Position += 4; // Damage min, Damage max + + w.Write(m.TithingPoints); + } + + if (type >= 6) + for (int i = 0; i < 15; ++i) + w.Write((short)m.GetAOSStatus(i)); + + to.Send(w.Span); + } + + public static void SendMobileStatus(NetState to, Mobile beholder, Mobile beheld) + { + SendMobileStatus(to, beholder, beheld, beheld.NetState); + } + + public static void SendMobileStatus(NetState to, Mobile beholder, Mobile beheld, NetState ns) + { + if (to == null) + return; + + int type; + short length; + + if (beholder != beheld) + { + type = 0; + length = 43; + } + else if (Core.HS && ns?.ExtendedStatus == true) + { + type = 6; + length = 121; + } + else if (Core.ML && ns?.SupportsExpansion(Expansion.ML) == true) + { + type = 5; + length = 91; + } + else if (Core.AOS) + { + type = 4; + length = 88; + } + else + { + type = 3; + length = 70; + } + + SpanWriter w = new SpanWriter(stackalloc byte[length]); + w.Write((byte)0x11); // Packet ID + w.Write((ushort)length); // Length + + w.Write(beheld.Serial); + + w.WriteAsciiFixed(beheld.Name ?? "", 30); + + if (beholder == beheld) + { + w.Write((short)beheld.Hits); + w.Write((short)beheld.HitsMax); + } + else + AttributeNormalizer.WriteReverse(w, beheld.Hits, beheld.HitsMax); + + w.Write(beheld.CanBeRenamedBy(beholder)); + + w.Write((byte)type); + + if (type <= 0) + return; + + w.Write(beheld.Female); + + w.Write((short)beheld.Str); + w.Write((short)beheld.Dex); + w.Write((short)beheld.Int); + + w.Write((short)beheld.Stam); + w.Write((short)beheld.StamMax); + + w.Write((short)beheld.Mana); + w.Write((short)beheld.ManaMax); + + w.Write(beheld.TotalGold); + w.Write((short)(Core.AOS ? beheld.PhysicalResistance : (int)(beheld.ArmorRating + 0.5))); + w.Write((short)(Mobile.BodyWeight + beheld.TotalWeight)); + + if (type >= 5) + { + w.Write((short)beheld.MaxWeight); + w.Write((byte)(beheld.Race.RaceID + 1)); // Would be 0x00 if it's a non-ML enabled account but... + } + + w.Write((short)beheld.StatCap); + + w.Write((byte)beheld.Followers); + w.Write((byte)beheld.FollowersMax); + + if (type >= 4) + { + w.Write((short)beheld.FireResistance); // Fire + w.Write((short)beheld.ColdResistance); // Cold + w.Write((short)beheld.PoisonResistance); // Poison + w.Write((short)beheld.EnergyResistance); // Energy + w.Write((short)beheld.Luck); // Luck + + IWeapon weapon = beheld.Weapon; + + if (weapon != null) + { + weapon.GetStatusDamage(beheld, out int min, out int max); + w.Write((short)min); // Damage min + w.Write((short)max); // Damage max + } + else + w.Position += 2; // Damage min, Damage max + + w.Write(beheld.TithingPoints); + } + + if (type >= 6) + for (int i = 0; i < 15; ++i) + w.Write((short)beheld.GetAOSStatus(i)); + + to.Send(w.Span); + } + + public static void SendHealthbarPoison(NetState ns, Mobile m) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[12]); + w.Write((byte)0x17); // Packet ID + w.Write((ushort)12); // Length + + w.Write(m.Serial); + w.Write((short)1); + w.Write((short)1); + + Poison p = m.Poison; + + if (p != null) + w.Write((byte)(p.Level + 1)); + else + w.Position++; + + ns.Send(w.Span); + } + + public static void SendHealthbarYellow(NetState ns, Mobile m) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[12]); + w.Write((byte)0x17); // Packet ID + w.Write((ushort)12); // Length + + w.Write(m.Serial); + w.Write((short)1); + w.Write((short)2); + + w.Write(m.Blessed || m.YellowHealthbar); + + ns.Send(w.Span); + } + + public static void SendMobileUpdate(NetState ns, Mobile m) + { + if (ns == null) + return; + + if (ns.StygianAbyss) + SendMobileUpdateSA(ns, m); + else + SendMobileUpdateOld(ns, m); + } + + public static void SendMobileUpdateSA(NetState ns, Mobile m) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[19]); + w.Write((byte)0x20); // Packet ID + + int hue = m.Hue; + + if (m.SolidHueOverride >= 0) + hue = m.SolidHueOverride; + + w.Write(m.Serial); + w.Write((short)m.Body); + w.Position++; // w.Write((byte)0); + w.Write((short)hue); + w.Write((byte)m.GetPacketFlags()); + w.Write((short)m.X); + w.Write((short)m.Y); + w.Position += 2; // w.Write((short)0); + w.Write((byte)m.Direction); + w.Write((sbyte)m.Z); + + ns.Send(w.Span); + } + + public static void SendMobileUpdateOld(NetState ns, Mobile m) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[19]); + w.Write((byte)0x20); // Packet ID + + int hue = m.Hue; + + if (m.SolidHueOverride >= 0) + hue = m.SolidHueOverride; + + w.Write(m.Serial); + w.Write((short)m.Body); + w.Position++; // w.Write((byte)0); + w.Write((short)hue); + w.Write((byte)m.GetOldPacketFlags()); + w.Write((short)m.X); + w.Write((short)m.Y); + w.Position += 2; // w.Write((short)0); + w.Write((byte)m.Direction); + w.Write((sbyte)m.Z); + + ns.Send(w.Span); + } + + public static void SendMobileIncoming(NetState ns, Mobile beholder, Mobile beheld) + { + if (ns == null) + return; + + if (ns.NewMobileIncoming) + SendMobileIncomingNew(ns, beholder, beheld); + else if (ns.StygianAbyss) + SendMobileIncomingSA(ns, beholder, beheld); + else + SendMobileIncomingOld(ns, beholder, beheld); + } + + public static void SendMobileIncomingNew(NetState ns, Mobile beholder, Mobile beheld) + { + if (ns == null) + return; + + Span dupedLayers = stackalloc bool[256]; + + List eq = beheld.Items; + int count = eq.Count; + + if (beheld.HairItemID > 0) + count++; + if (beheld.FacialHairItemID > 0) + count++; + + SpanWriter w = new SpanWriter(stackalloc byte[23 + count * 9]); + w.Write((byte)0x78); // Packet ID + w.Position += 2; // Dynamic Length + + int hue = beheld.Hue; + + if (beheld.SolidHueOverride >= 0) + hue = beheld.SolidHueOverride; + + w.Write(beheld.Serial); + w.Write((short)beheld.Body); + w.Write((short)beheld.X); + w.Write((short)beheld.Y); + w.Write((sbyte)beheld.Z); + w.Write((byte)beheld.Direction); + w.Write((short)hue); + w.Write((byte)beheld.GetPacketFlags()); + w.Write(Notoriety.Compute(beholder, beheld)); + + for (int i = 0; i < eq.Count; ++i) + { + Item item = eq[i]; + + byte layer = (byte)item.Layer; + + if (!item.Deleted && beholder.CanSee(item) && !dupedLayers[layer]) + { + dupedLayers[layer] = true; + + hue = item.Hue; + + if (beheld.SolidHueOverride >= 0) + hue = beheld.SolidHueOverride; + + w.Write(item.Serial); + w.Write((ushort)(item.ItemID & 0xFFFF)); + w.Write(layer); + w.Write((short)hue); + } + } + + if (beheld.HairItemID > 0 && !dupedLayers[(int)Layer.Hair]) + { + hue = beheld.HairHue; + + if (beheld.SolidHueOverride >= 0) + hue = beheld.SolidHueOverride; + + w.Write(HairInfo.FakeSerial(beheld.Serial)); + w.Write((ushort)(beheld.HairItemID & 0xFFFF)); + w.Write((byte)Layer.Hair); + w.Write((short)hue); + } + + if (beheld.FacialHairItemID > 0 && !dupedLayers[(int)Layer.FacialHair]) + { + hue = beheld.FacialHairHue; + + if (beheld.SolidHueOverride >= 0) + hue = beheld.SolidHueOverride; + + w.Write(FacialHairInfo.FakeSerial(beheld.Serial)); + w.Write((ushort)(beheld.FacialHairItemID & 0xFFFF)); + w.Write((byte)Layer.FacialHair); + w.Write((short)hue); + } + + w.Position += 4; // w.Write(0) + + w.Position = 1; + w.Write((ushort)w.WrittenCount); + + ns.Send(w.Span); + } + + public static void SendMobileIncomingSA(NetState ns, Mobile beholder, Mobile beheld) + { + if (ns == null) + return; + + Span dupedLayers = stackalloc bool[256]; + + List eq = beheld.Items; + int count = eq.Count; + + if (beheld.HairItemID > 0) + count++; + if (beheld.FacialHairItemID > 0) + count++; + + SpanWriter w = new SpanWriter(stackalloc byte[23 + count * 9]); + w.Write((byte)0x78); // Packet ID + w.Position += 2; // Dynamic Length + + int hue = beheld.Hue; + + if (beheld.SolidHueOverride >= 0) + hue = beheld.SolidHueOverride; + + w.Write(beheld.Serial); + w.Write((short)beheld.Body); + w.Write((short)beheld.X); + w.Write((short)beheld.Y); + w.Write((sbyte)beheld.Z); + w.Write((byte)beheld.Direction); + w.Write((short)hue); + w.Write((byte)beheld.GetPacketFlags()); + w.Write(Notoriety.Compute(beholder, beheld)); + + for (int i = 0; i < eq.Count; ++i) + { + Item item = eq[i]; + + byte layer = (byte)item.Layer; + + if (!item.Deleted && beholder.CanSee(item) && !dupedLayers[layer]) + { + dupedLayers[layer] = true; + + hue = item.Hue; + + if (beheld.SolidHueOverride >= 0) + hue = beheld.SolidHueOverride; + + int itemId = item.ItemID & 0x7FFF; + bool writeHue = hue != 0; + + if (writeHue) + itemId |= 0x8000; + + w.Write(item.Serial); + w.Write((ushort)itemId); + w.Write(layer); + + if (writeHue) + w.Write((short)hue); + } + } + + if (beheld.HairItemID > 0 && !dupedLayers[(int)Layer.Hair]) + { + hue = beheld.HairHue; + + if (beheld.SolidHueOverride >= 0) + hue = beheld.SolidHueOverride; + + int itemId = beheld.HairItemID & 0x7FFF; + + bool writeHue = hue != 0; + + if (writeHue) + itemId |= 0x8000; + + w.Write(HairInfo.FakeSerial(beheld.Serial)); + w.Write((ushort)itemId); + w.Write((byte)Layer.Hair); + + if (writeHue) + w.Write((short)hue); + } + + if (beheld.FacialHairItemID > 0 && !dupedLayers[(int)Layer.FacialHair]) + { + hue = beheld.FacialHairHue; + + if (beheld.SolidHueOverride >= 0) + hue = beheld.SolidHueOverride; + + int itemId = beheld.FacialHairItemID & 0x7FFF; + + bool writeHue = hue != 0; + + if (writeHue) + itemId |= 0x8000; + + w.Write(FacialHairInfo.FakeSerial(beheld.Serial)); + w.Write((ushort)itemId); + w.Write((byte)Layer.FacialHair); + + if (writeHue) + w.Write((short)hue); + } + + w.Position += 4; // w.Write(0) + + w.Position = 1; + w.Write((ushort)w.WrittenCount); + + ns.Send(w.Span); + } + + public static void SendMobileIncomingOld(NetState ns, Mobile beholder, Mobile beheld) + { + if (ns == null) + return; + + Span dupedLayers = stackalloc bool[256]; + + List eq = beheld.Items; + int count = eq.Count; + + if (beheld.HairItemID > 0) + count++; + if (beheld.FacialHairItemID > 0) + count++; + + SpanWriter w = new SpanWriter(stackalloc byte[23 + count * 9]); + w.Write((byte)0x78); // Packet ID + w.Position += 2; // Dynamic Length + + int hue = beheld.Hue; + + if (beheld.SolidHueOverride >= 0) + hue = beheld.SolidHueOverride; + + w.Write(beheld.Serial); + w.Write((short)beheld.Body); + w.Write((short)beheld.X); + w.Write((short)beheld.Y); + w.Write((sbyte)beheld.Z); + w.Write((byte)beheld.Direction); + w.Write((short)hue); + w.Write((byte)beheld.GetOldPacketFlags()); + w.Write(Notoriety.Compute(beholder, beheld)); + + for (int i = 0; i < eq.Count; ++i) + { + Item item = eq[i]; + + byte layer = (byte)item.Layer; + + if (!item.Deleted && beholder.CanSee(item) && !dupedLayers[layer]) + { + dupedLayers[layer] = true; + + hue = item.Hue; + + if (beheld.SolidHueOverride >= 0) + hue = beheld.SolidHueOverride; + + int itemId = item.ItemID & 0x7FFF; + bool writeHue = hue != 0; + + if (writeHue) + itemId |= 0x8000; + + w.Write(item.Serial); + w.Write((ushort)itemId); + w.Write(layer); + + if (writeHue) + w.Write((short)hue); + } + } + + if (beheld.HairItemID > 0 && !dupedLayers[(int)Layer.Hair]) + { + hue = beheld.HairHue; + + if (beheld.SolidHueOverride >= 0) + hue = beheld.SolidHueOverride; + + int itemId = beheld.HairItemID & 0x7FFF; + + bool writeHue = hue != 0; + + if (writeHue) + itemId |= 0x8000; + + w.Write(HairInfo.FakeSerial(beheld.Serial)); + w.Write((ushort)itemId); + w.Write((byte)Layer.Hair); + + if (writeHue) + w.Write((short)hue); + } + + if (beheld.FacialHairItemID > 0 && !dupedLayers[(int)Layer.FacialHair]) + { + hue = beheld.FacialHairHue; + + if (beheld.SolidHueOverride >= 0) + hue = beheld.SolidHueOverride; + + int itemId = beheld.FacialHairItemID & 0x7FFF; + + bool writeHue = hue != 0; + + if (writeHue) + itemId |= 0x8000; + + w.Write(FacialHairInfo.FakeSerial(beheld.Serial)); + w.Write((ushort)itemId); + w.Write((byte)Layer.FacialHair); + + if (writeHue) + w.Write((short)hue); + } + + w.Position += 4; // w.Write(0) + + w.Position = 1; + w.Write((ushort)w.WrittenCount); + + ns.Send(w.Span); + } + + public static void SendFollowMessage(NetState ns, Serial s1, Serial s2) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[9]); + w.Write((byte)0x15); // Packet ID + + w.Write(s1); + w.Write(s2); + + ns.Send(w.Span); + } + } +} diff --git a/Projects/Server/Network/Packets/Player.cs b/Projects/Server/Network/Packets/Player.cs new file mode 100644 index 000000000..0346d6626 --- /dev/null +++ b/Projects/Server/Network/Packets/Player.cs @@ -0,0 +1,550 @@ +using System; +using Server.Buffers; + +namespace Server.Network +{ + public static partial class Packets + { + public static void SendObjectHelpResponse(NetState ns, Serial e, string text) + { + if (ns == null) + return; + + text ??= ""; + + int length = 9 + text.Length * 2; + SpanWriter w = new SpanWriter(stackalloc byte[length]); + w.Write((byte) 0xB7); // Extended Packet ID + w.Write((ushort) length); // Length + + w.Write(e); + w.WriteBigUniNull(text); + + ns.Send(w.Span); + } + + public static void SendChangeUpdateRange(NetState ns, byte range = 18) + { + ns?.Send(stackalloc byte[] + { + 0xC8, // Packet ID + range + }); + } + + public static void SendChangeCombatant(NetState ns, Serial combatant) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[5]); + w.Write((byte)0xAA); // Packet ID + + w.Write(combatant); + + ns.Send(w.Span); + } + + public static void SendDisplayHuePicker(NetState ns, Serial s, int itemId) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[9]); + w.Write((byte)0x95); // Packet ID + + w.Write(s); + w.Position += 2; // w.Write((short)0); + w.Write((short)itemId); + + ns.Send(w.Span); + } + + public static void SendUnicodePrompt(NetState ns, Serial message) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[21]); + w.Write((byte)0xC2); // Packet ID + w.Write((short)21); // Length + + w.Write(message); // Should be Player serial? + w.Write(message); + w.Position += 10; + + ns.Send(w.Span); + } + + public static void SendDeathStatus_Dead(NetState ns) + { + ns?.Send(stackalloc byte[] + { + 0x2C, // Packet ID + 0x00 + }); + } + + public static void SendDeathStatus_Alive(NetState ns) + { + ns?.Send(stackalloc byte[] + { + 0x2C, // Packet ID + 0x02 // Why not 1? + }); + } + + private static readonly byte[][] _speedControlPackets = new byte[3][]; + + public static void SendSpeedControlDisabled(NetState ns) + { + ns?.Send(_speedControlPackets[0] ??= new byte[] + { + 0xBF, // Extended Packet ID + 0x00, + 0x06, // Length + 0x26, + 0x00 // Disabled + }); + } + + public static void SendSpeedControlMount(NetState ns) + { + ns?.Send(_speedControlPackets[1] ??= new byte[] + { + 0xBF, // Extended Packet ID + 0x00, + 0x06, // Length + 0x26, + 0x01 // Mount + }); + } + + public static void SendSpeedControlWalk(NetState ns) + { + ns?.Send(_speedControlPackets[2] ??= new byte[] + { + 0xBF, // Extended Packet ID + 0x00, + 0x06, // Length + 0x26, + 0x02 // Walk + }); + } + + public static void SendToggleSpecialAbility(NetState ns, short ability, bool active) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[8]); + w.Write((byte)0xBF); // Packet ID + w.Write((short)8); // Length + + w.Write((short)0x25); // Command + w.Write(ability); + w.Write(active); + + ns.Send(w.Span); + } + + public static void SendGlobalLightLevel(NetState ns, sbyte level) + { + ns?.Send(stackalloc byte[] + { + 0x4F, // Packet ID + (byte)level + }); + } + + public static void SendLogoutAck(NetState ns) + { + ns?.Send(stackalloc byte[] + { + 0xD1, // Packet ID + 0x01 + }); + } + + public static void SendWeather(NetState ns, byte type, byte density, sbyte temperature) + { + ns?.Send(stackalloc byte[] + { + 0x65, // Packet ID + type, + density, + (byte)temperature + }); + } + + public static void SendPlayerMove(NetState ns, Direction d) + { + ns?.Send(stackalloc byte[] + { + 0x97, // Packet ID + (byte)d + }); + } + + public static void SendClientVersionReq(NetState ns) + { + ns?.Send(stackalloc byte[] + { + 0xBD, // Packet ID + 0x00, + 0x03 + }); + } + + public static void SendSetWarMode(NetState ns, bool warmode) + { + if (warmode) + SendInWarMode(ns); + else + SendInPeaceMode(ns); + } + + public static void SendInWarMode(NetState ns) + { + ns?.Send(stackalloc byte[] + { + 0x72, // Packet ID + 0x01, // War mode + 0x00, + 0x32, // ? + 0x00 + }); + } + + public static void SendInPeaceMode(NetState ns) + { + ns?.Send(stackalloc byte[] + { + 0x72, // Packet ID + 0x00, // Peace mode + 0x00, + 0x32, // ? + 0x00 + }); + } + + public static void SendRemoveEntity(NetState ns, Serial entity) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[5]); + w.Write((byte)0x1D); // Packet ID + + w.Write(entity); + + ns.Send(w.Span); + } + + public static void SendServerChange(NetState ns, Mobile m, Map map) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[16]); + w.Write((byte)0x76); // Packet ID + + w.Write((short)m.X); + w.Write((short)m.Y); + w.Write((short)m.Z); + w.Position += 5; + w.Write((short)map.Width); + w.Write((short)map.Height); + + ns.Send(w.Span); + } + + public static void SendSkillsUpdate(NetState ns, Skills skills) + { + if (ns == null) + return; + + int length = 6 + skills.Length * 9; + + SpanWriter w = new SpanWriter(stackalloc byte[length]); + w.Write((byte)0x3A); // Packet ID + w.Write((short)length); // Length + + w.Write((byte)0x02); // type: absolute, capped + + for (int i = 0; i < skills.Length; ++i) + { + Skill s = skills[i]; + + double v = s.NonRacialValue; + int uv = (int)(v * 10); + + if (uv < 0) + uv = 0; + else if (uv >= 0x10000) + uv = 0xFFFF; + + w.Write((ushort)(s.Info.SkillID + 1)); + w.Write((ushort)uv); + w.Write((ushort)s.BaseFixedPoint); + w.Write((byte)s.Lock); + w.Write((ushort)s.CapFixedPoint); + } + + w.Position += 2; + + ns.Send(w.Span); + } + + public static void SendSkillChange(NetState ns, Skill skill) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[13]); + w.Write((byte)0x3A); // Packet ID + w.Write((short)13); // Length + + + double v = skill.NonRacialValue; + int uv = (int)(v * 10); + + if (uv < 0) + uv = 0; + else if (uv >= 0x10000) + uv = 0xFFFF; + + w.Write((byte)0xDF); // type: delta, capped + w.Write((ushort)skill.Info.SkillID); + w.Write((ushort)uv); + w.Write((ushort)skill.BaseFixedPoint); + w.Write((byte)skill.Lock); + w.Write((ushort)skill.CapFixedPoint); + + ns.Send(w.Span); + } + + public static void SendLaunchBrowser(NetState ns, string url) + { + if (ns == null) + return; + + url ??= ""; + + int length = 4 + url.Length; + SpanWriter w = new SpanWriter(stackalloc byte[length]); + w.Write((byte)0xA5); // Packet ID + w.Write((short)length); // Length + + w.WriteAsciiNull(url); + + ns.Send(w.Span); + } + + // TODO: Optimize for IEnumerable + public static void SendPlaySound(NetState ns, int soundId, IPoint3D target) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[12]); + w.Write((byte)0x54); // Packet ID + + w.Write((byte)1); // flags + w.Write((short)soundId); + w.Position += 2; // volume? + w.Write((short)target.X); + w.Write((short)target.Y); + w.Write((short)target.Z); + + ns.Send(w.Span); + } + + public static void SendPlayRepeatingSound(NetState ns, int soundId, IPoint3D target) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[12]); + w.Write((byte)0x54); // Packet ID + + w.Position++; // flags + w.Write((short)soundId); + w.Position += 2; // volume? + w.Write((short)target.X); + w.Write((short)target.Y); + w.Write((short)target.Z); + + ns.Send(w.Span); + } + + public static void SendPlayMusic(NetState ns, MusicName music) + { + ushort value = (ushort)music; + ns?.Send(stackalloc byte[] + { + 0x6D, // Packet ID + (byte)(value >> 8), + (byte)(value & 0xFF) + }); + } + + public static void SendStopMusic(NetState ns) + { + ns?.Send(stackalloc byte[] + { + 0x6D, // Packet ID + 0x1F, + 0xFF + }); + } + + public static void SendScrollMessage(NetState ns, int type, int tip, string text) + { + if (ns == null) + return; + + text ??= ""; + + int length = 10 + text.Length; + + SpanWriter w = new SpanWriter(stackalloc byte[length]); + w.Write((byte)0xA6); // Packet ID + w.Write((short)length); // Length + + w.Write((byte)type); + w.Write(tip); + w.Write((ushort)text.Length); + w.WriteAsciiFixed(text, text.Length); + + ns.Send(w.Span); + } + + public static void SendCurrentTime(NetState ns) + { + if (ns == null) + return; + + // TODO: Don't call UtcNow so readily. + DateTime now = DateTime.UtcNow; + + ns.Send(stackalloc byte[] + { + 0x5B, // Packet ID + (byte)now.Hour, + (byte)now.Minute, + (byte)now.Second + }); + } + + public static void SendPathfindMessage(NetState ns, IPoint3D p) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[7]); + w.Write((byte)0x38); // Packet ID + + w.Write((short)p.X); + w.Write((short)p.Y); + w.Write((short)p.Z); + + ns.Send(w.Span); + } + + public static void SendPingAck(NetState ns, byte ping) + { + ns?.Send(stackalloc byte[2] + { + 0x73, // Packet ID + ping + }); + } + + public static void SendMovementRej(NetState ns, int seq, Mobile m) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[8]); + w.Write((byte)0x21); // Packet ID + + w.Write((byte)seq); + w.Write((short)m.X); + w.Write((short)m.Y); + w.Write((byte)m.Direction); + w.Write((sbyte)m.Z); + + ns.Send(w.Span); + } + + public static void SendMovementAck(NetState ns, Mobile m) + { + if (ns == null) + return; + + SendMovementAck(ns, ns.Sequence, Notoriety.Compute(m, m)); + } + + public static void SendMovementAck(NetState ns, byte seq, byte noto) + { + ns?.Send(stackalloc byte[3] + { + 0x22, + seq, + noto + }); + } + + public static void SendLoginConfirm(NetState ns, Mobile m) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[37]); + w.Write((byte)0x1B); // Packet ID + + w.Write(m.Serial); + w.Position++; + w.Write((short)m.Body); + w.Write((short)m.X); + w.Write((short)m.Y); + w.Write((short)m.Z); + w.Write((byte)m.Direction); + w.Position++; + w.Write(-1); + + Map map = m.Map; + + if (map == null || map == Map.Internal) + map = m.LogoutMap; + + w.Position += 4; + w.Write((short)(map?.Width ?? 6144)); + w.Write((short)(map?.Height ?? 4096)); + w.Position += 9; + + ns.Send(w.Span); + } + + public static void SendLoginComplete(NetState ns) + { + ns?.Send(stackalloc byte[] + { + 0x55 // Packet ID + }); + } + + public static void SendClearWeaponAbility(NetState ns) + { + ns?.Send(stackalloc byte[] + { + 0xBF, // Extended Packet ID + 0x00, + 0x05, // Length + 0x21, // Command + 0x00 + }); + } + } +} diff --git a/Projects/Server/Network/Packets/Profile.cs b/Projects/Server/Network/Packets/Profile.cs new file mode 100644 index 000000000..5a0106623 --- /dev/null +++ b/Projects/Server/Network/Packets/Profile.cs @@ -0,0 +1,29 @@ +using Server.Buffers; + +namespace Server.Network +{ + public static partial class Packets + { + public static void SendDisplayProfile(NetState ns, Serial m, string header, string body, string footer) + { + if (ns == null) + return; + + header ??= ""; + body ??= ""; + footer ??= ""; + + int length = 12 + header.Length + footer.Length * 2 + body.Length * 2; + SpanWriter w = new SpanWriter(stackalloc byte[length]); + w.Write((byte)0xB8); // Packet ID + w.Write((short)length); // Length + + w.Write(m); + w.WriteAsciiNull(header); + w.WriteBigUniNull(footer); + w.WriteBigUniNull(body); + + ns.Send(w.Span); + } + } +} diff --git a/Projects/Server/Network/Packets/Targeting.cs b/Projects/Server/Network/Packets/Targeting.cs new file mode 100644 index 000000000..68c4aee7f --- /dev/null +++ b/Projects/Server/Network/Packets/Targeting.cs @@ -0,0 +1,81 @@ +using Server.Buffers; +using Server.Targeting; + +namespace Server.Network +{ + public static partial class Packets + { + public static void SendMultiTargetReqHS(NetState ns, MultiTarget t) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[30]); + w.Write((byte)0x99); // Packet ID + + w.Write(t.AllowGround); + w.Write(t.TargetID); + w.Write((byte)t.Flags); + w.Position += 11; + w.Write((short)t.MultiID); + w.Write((short)t.Offset.X); + w.Write((short)t.Offset.Y); + w.Write((short)t.Offset.Z); + // 4 bytes unknown? + + ns.Send(w.Span); + } + + public static void SendMultiTargetReq(NetState ns, MultiTarget t) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[26]); + w.Write((byte)0x99); // Packet ID + + w.Write(t.AllowGround); + w.Write(t.TargetID); + w.Write((byte)t.Flags); + w.Position += 14; + w.Write((short)t.MultiID); + w.Write((short)t.Offset.X); + w.Write((short)t.Offset.Y); + w.Write((short)t.Offset.Z); + + ns.Send(w.Span); + } + + private static byte[] _targetReqPacket; + + public static void SendCancelTarget(NetState ns) + { + if (ns == null) + return; + + if (_targetReqPacket == null) + { + _targetReqPacket = new byte[19]; + _targetReqPacket[0] = 0x6C; // Packet ID + _targetReqPacket[6] = 0x03; // ? + } + + ns.Send(_targetReqPacket); + } + + public static void SendTargetReq(NetState ns, Target t) + { + if (ns == null || t == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[19]); + w.Write((byte)0x6C); // Packet ID + + w.Write(t.AllowGround); + w.Write(t.TargetID); + w.Write((byte)t.Flags); + + ns.Send(w.Span); + } + } +} diff --git a/Projects/Server/Network/Packets/Trade.cs b/Projects/Server/Network/Packets/Trade.cs new file mode 100644 index 000000000..2e8745928 --- /dev/null +++ b/Projects/Server/Network/Packets/Trade.cs @@ -0,0 +1,139 @@ +using Server.Buffers; + +namespace Server.Network +{ + public enum TradeFlag : byte + { + Display = 0x0, + Close = 0x1, + Update = 0x2, + UpdateGold = 0x3, + UpdateLedger = 0x4 + } + + public static partial class Packets + { + public static void SendDisplaySecureTrade(NetState ns, Serial them, Serial firstCont, Serial secondCont, string name = "") + { + if (ns == null) + return; + + name ??= ""; + + int length = 17 + name.Length; + SpanWriter w = new SpanWriter(stackalloc byte[length]); + w.Write((byte)0x6F); // Packet ID + w.Write((short)length); // Length + + w.Position++; // Display + w.Write(them); + w.Write(firstCont); + w.Write(secondCont); + w.Write(name.Length > 0); + w.WriteAscii(name); + + ns.Send(w.Span); + } + + public static void SendCloseSecureTrade(NetState ns, Serial cont) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[8]); + w.Write((byte)0x6F); // Packet ID + w.Write((ushort)8); // Length + + w.Write((byte)1); // Close + w.Write(cont); + + ns.Send(w.Span); + } + + public static void SendUpdateSecureTrade(NetState ns, Serial cont, bool fromAccepted, bool toAccepted) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[10]); + w.Write((byte)0x6F); // Packet ID + w.Write((ushort)10); // Length + + w.Write((byte)TradeFlag.Update); + w.Write(cont); + w.Write(fromAccepted); + w.Write(toAccepted); + + ns.Send(w.Span); + } + + public static void SendUpdateSecureTrade(NetState ns, Serial cont, TradeFlag flag, int first, int second) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[16]); + w.Write((byte)0x6F); // Packet ID + w.Write((ushort)16); // Length + + w.Write((byte)flag); + w.Write(cont); + w.Write(first); + w.Write(second); + + ns.Send(w.Span); + } + + public static void SendSecureTradeEquip(NetState ns, Item item, Serial m) + { + if (ns == null) + return; + + if (ns.ContainerGridLines) + SendSecureTradeEquipNew(ns, item, m); + else + SendSecureTradeEquipOld(ns, item, m); + } + + public static void SendSecureTradeEquipOld(NetState ns, Item item, Serial m) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[20]); + w.Write((byte)0x25); // Packet ID + + w.Write(item.Serial); + w.Write((short)item.ItemID); + w.Position++; // Write((byte)0) + w.Write((short)item.Amount); + w.Write((short)item.X); + w.Write((short)item.Y); + w.Write(m); + w.Write((short)item.Hue); + + ns.Send(w.Span); + } + + public static void SendSecureTradeEquipNew(NetState ns, Item item, Serial m) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[21]); + w.Write((byte)0x25); // Packet ID + + w.Write(item.Serial); + w.Write((short)item.ItemID); + w.Position++; // Write((byte)0) + w.Write((short)item.Amount); + w.Write((short)item.X); + w.Write((short)item.Y); + w.Write(m); + w.Position++; // Write((byte)0) Grid Location? + w.Write((short)item.Hue); + + ns.Send(w.Span); + } + } +} diff --git a/Projects/Server/Network/Packets/Vendors.cs b/Projects/Server/Network/Packets/Vendors.cs new file mode 100644 index 000000000..257a468cd --- /dev/null +++ b/Projects/Server/Network/Packets/Vendors.cs @@ -0,0 +1,207 @@ +using System.Collections.Generic; +using Server.Buffers; +using Server.Items; + +namespace Server.Network +{ + public static partial class Packets + { + public static void SendVendorBuyContent(NetState ns, IList list) + { + if (ns == null) + return; + + if (ns.ContainerGridLines) + SendVendorBuyContentNew(ns, list); + else + SendVendorBuyContentOld(ns, list); + } + + public static void SendVendorBuyContentOld(NetState ns, IList list) + { + if (ns == null) + return; + + int length = 5 + list.Count * 19; + SpanWriter w = new SpanWriter(stackalloc byte[length]); + w.Write((byte)0x3C); // Packet ID + w.Write((ushort)length); // Length + + w.Write((short)list.Count); + + //The client sorts these by their X/Y value. + //OSI sends these in weird order. X/Y highest to lowest and serial lowest to highest + //These are already sorted by serial (done by the vendor class) but we have to send them by x/y + //(the x74 packet is sent in 'correct' order.) + for (int i = list.Count - 1; i >= 0; --i) + { + BuyItemState bis = list[i]; + + w.Write(bis.MySerial); + w.Write((ushort)bis.ItemID); + w.Position++; // Write((byte)0); itemid offset + w.Write((ushort)bis.Amount); + w.Write((short)(i + 1)); //x + w.Write((short)1); //y + w.Write(bis.ContainerSerial); + w.Write((ushort)bis.Hue); + } + + ns.Send(w.RawSpan); + } + + public static void SendVendorBuyContentNew(NetState ns, IList list) + { + if (ns == null) + return; + + int length = 5 + list.Count * 20; + SpanWriter w = new SpanWriter(stackalloc byte[length]); + w.Write((byte)0x3C); // Packet ID + w.Write((ushort)length); // Length + + w.Write((short)list.Count); + + //The client sorts these by their X/Y value. + //OSI sends these in weird order. X/Y highest to lowest and serial lowest to highest + //These are already sorted by serial (done by the vendor class) but we have to send them by x/y + //(the x74 packet is sent in 'correct' order.) + for (int i = list.Count - 1; i >= 0; --i) + { + BuyItemState bis = list[i]; + + w.Write(bis.MySerial); + w.Write((ushort)bis.ItemID); + w.Position++; // Write((byte)0); itemid offset + w.Write((ushort)bis.Amount); + w.Write((short)(i + 1)); //x + w.Write((short)1); //y + w.Position++; // Write((byte)0); Grid Location? + w.Write(bis.ContainerSerial); + w.Write((ushort)bis.Hue); + } + + ns.Send(w.RawSpan); + } + + public static void SendDisplayBuyList(NetState ns, Serial vendor) + { + if (ns == null) + return; + + if (ns.HighSeas) + SendDisplayBuyListHS(ns, vendor); + else + SendDisplayBuyListOld(ns, vendor); + } + + public static void SendDisplayBuyListOld(NetState ns, Serial vendor) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[7]); + w.Write((byte)0x24); // Packet ID + + w.Write(vendor); + w.Write((short)0x30); // buy window id? + + ns.Send(w.RawSpan); + } + + public static void SendDisplayBuyListHS(NetState ns, Serial vendor) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[9]); + w.Write((byte)0x24); // Packet ID + + w.Write(vendor); + w.Write((short)0x30); // buy window id? + //w.Write((short)0x00); // Unknown + + ns.Send(w.RawSpan); + } + + public static void SendVendorBuyList(NetState ns, Mobile vendor, IList list) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[8 + 135 * list.Count]); + w.Write((byte)0x74); // Packet ID + w.Position += 2; // Dynamic Length + + w.Write(!(vendor.FindItemOnLayer(Layer.ShopBuy) is Container BuyPack) ? Serial.MinusOne : BuyPack.Serial); + + w.Write((byte)list.Count); + + for (int i = 0; i < list.Count; ++i) + { + BuyItemState bis = list[i]; + + w.Write(bis.Price); + + string desc = bis.Description ?? ""; + w.Write((byte)(desc.Length + 1)); + w.WriteAsciiNull(desc); + } + + w.Position = 1; + w.Write((ushort)w.WrittenCount); + ns.Send(w.Span); + } + + public static void SendVendorSellList(NetState ns, Serial shopkeeper, IList list) + { + if (ns == null) + return; + + ushort count = (ushort)list.Count; + SpanWriter w = new SpanWriter(stackalloc byte[9 + 140 * count]); + w.Write((byte)0x9E); // Packet ID + w.Position += 2; //( Dynamic Length + + w.Write(shopkeeper); + + w.Write(count); + + for (int i = 0; i < count; ++i) + { + SellItemState state = list[i]; + + w.Write(state.Item.Serial); + w.Write((ushort)state.Item.ItemID); + w.Write((ushort)state.Item.Hue); + w.Write((ushort)state.Item.Amount); + w.Write((ushort)state.Price); + + string name = state.Item.Name; + + if (name == null || (name = name.Trim()).Length <= 0) + name = state.Name ?? ""; + + w.Write((ushort)name.Length); + w.WriteAsciiFixed(name, (ushort)name.Length); + } + + w.Position = 1; + w.Write((ushort)w.WrittenCount); + ns.Send(w.Span); + } + + public static void SendEndVendorBuyOrSell(NetState ns, Serial vendor) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[8]); + w.Write((byte)0x3B); // Packet ID + + w.Write(vendor); + + ns.Send(w.RawSpan); + } + } +} diff --git a/Projects/Server/Network/Packets/VirtualHair.cs b/Projects/Server/Network/Packets/VirtualHair.cs new file mode 100644 index 000000000..05622a480 --- /dev/null +++ b/Projects/Server/Network/Packets/VirtualHair.cs @@ -0,0 +1,78 @@ +using Server.Buffers; +using Server.Items; + +namespace Server.Network +{ + public static partial class Packets + { + public static void SendHairEquipUpdate(NetState ns, Mobile parent) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[15]); + w.Write((byte)0x2E); // Packet ID + + int hue = parent.HairHue; + + if (parent.SolidHueOverride >= 0) + hue = parent.SolidHueOverride; + + w.Write(HairInfo.FakeSerial(parent.Serial)); + w.Write((short)parent.HairItemID); + w.Write((short)Layer.Hair); + w.Write(parent.Serial); + w.Write((short)hue); + + ns.Send(w.Span); + } + + public static void SendFacialHairEquipUpdate(NetState ns, Mobile parent) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[15]); + w.Write((byte)0x2E); // Packet ID + + int hue = parent.FacialHairHue; + + if (parent.SolidHueOverride >= 0) + hue = parent.SolidHueOverride; + + w.Write(FacialHairInfo.FakeSerial(parent.Serial)); + w.Write((short)parent.FacialHairItemID); + w.Write((short)Layer.Hair); + w.Write(parent.Serial); + w.Write((short)hue); + + ns.Send(w.Span); + } + + public static void SendRemoveHair(NetState ns, Mobile parent) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[5]); + w.Write((byte)0x1D); // Packet ID + + w.Write(HairInfo.FakeSerial(parent.Serial)); + + ns.Send(w.Span); + } + + public static void SendRemoveFacialHair(NetState ns, Mobile parent) + { + if (ns == null) + return; + + SpanWriter w = new SpanWriter(stackalloc byte[5]); + w.Write((byte)0x1D); // Packet ID + + w.Write(FacialHairInfo.FakeSerial(parent.Serial)); + + ns.Send(w.Span); + } + } +} diff --git a/Projects/Server/Network/SendQueue.cs b/Projects/Server/Network/SendQueue.cs deleted file mode 100644 index c074de17e..000000000 --- a/Projects/Server/Network/SendQueue.cs +++ /dev/null @@ -1,44 +0,0 @@ -/*************************************************************************** - * SendQueue.cs - * ------------------- - * begin : May 1, 2002 - * copyright : (C) The RunUO Software Team - * email : info@runuo.com - * - * $Id$ - * - ***************************************************************************/ - -/*************************************************************************** - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - ***************************************************************************/ - -using System.Collections.Concurrent; -using System.Threading.Tasks; - -namespace Server.Network -{ - public class SendQueue - { - private BlockingCollection m_Queue = new BlockingCollection(new ConcurrentQueue()); - - public void Enqueue(T t) - { - m_Queue.Add(t); - } - - public Task DequeueAsync() - { - TaskCompletionSource taskCompletion = new TaskCompletionSource(); - Task.Run(() => taskCompletion.SetResult(Dequeue())); - return taskCompletion.Task; - } - - public T Dequeue() => m_Queue.Take(); - } -} diff --git a/Projects/Server/Network/ServerInfo.cs b/Projects/Server/Network/ServerInfo.cs new file mode 100644 index 000000000..0215ff29d --- /dev/null +++ b/Projects/Server/Network/ServerInfo.cs @@ -0,0 +1,24 @@ +using System; +using System.Net; + +namespace Server.Network +{ + public sealed class ServerInfo + { + public ServerInfo(string name, int fullPercent, TimeZoneInfo tz, IPEndPoint address) + { + Name = name; + FullPercent = fullPercent; + TimeZone = tz.GetUtcOffset(DateTime.Now).Hours; + Address = address; + } + + public string Name { get; set; } + + public int FullPercent { get; set; } + + public int TimeZone { get; set; } + + public IPEndPoint Address { get; set; } + } +} diff --git a/Projects/Server/Network/SocketExtensions.cs b/Projects/Server/Network/SocketExtensions.cs index e03a79243..0b50b9909 100644 --- a/Projects/Server/Network/SocketExtensions.cs +++ b/Projects/Server/Network/SocketExtensions.cs @@ -34,7 +34,7 @@ namespace Server.Network public static ArraySegment GetArray(this ReadOnlyMemory memory) { - if (MemoryMarshal.TryGetArray(memory, out var result)) + if (MemoryMarshal.TryGetArray(memory, out ArraySegment result)) return result; throw new InvalidOperationException("Buffer backed by array was expected"); @@ -42,7 +42,7 @@ namespace Server.Network public static ArraySegment GetArray(this ReadOnlySequence memory) { - if (SequenceMarshal.TryGetArray(memory, out var result)) + if (SequenceMarshal.TryGetArray(memory, out ArraySegment result)) return result; throw new InvalidOperationException("Buffer backed by array was expected"); diff --git a/Projects/Server/Network/StaticPacketHandlers.cs b/Projects/Server/Network/StaticPacketHandlers.cs deleted file mode 100644 index b2c710581..000000000 --- a/Projects/Server/Network/StaticPacketHandlers.cs +++ /dev/null @@ -1,135 +0,0 @@ -/*************************************************************************** - * StaticPacketHandlers.cs - * ------------------- - * begin : March 15, 2019 - * copyright : (C) The ModernUO Team - * email : hi@modernuo.com - * - * $Id$ - * - ***************************************************************************/ - -/*************************************************************************** - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - ***************************************************************************/ - -using System.Collections.Concurrent; - -namespace Server.Network -{ - public static class StaticPacketHandlers - { - private static ConcurrentDictionary OPLInfoPackets = new ConcurrentDictionary(); - private static ConcurrentDictionary ObjectPropertyListPackets = new ConcurrentDictionary(); - private static ConcurrentDictionary RemoveEntityPackets = new ConcurrentDictionary(); - - private static ConcurrentDictionary WorldItemPackets = new ConcurrentDictionary(); - private static ConcurrentDictionary WorldItemSAPackets = new ConcurrentDictionary(); - private static ConcurrentDictionary WorldItemHSPackets = new ConcurrentDictionary(); - - public static OPLInfo GetOPLInfoPacket(IPropertyListObject obj) - { - return OPLInfoPackets.GetOrAdd(obj, value => - { - OPLInfo packet = new OPLInfo(value.PropertyList); - packet.SetStatic(); - return packet; - }); - } - - public static OPLInfo FreeOPLInfoPacket(IPropertyListObject obj) - { - if (OPLInfoPackets.TryRemove(obj, out OPLInfo p)) - Packet.Release(p); - - return p; - } - - public static ObjectPropertyList GetOPLPacket(IPropertyListObject obj) - { - return ObjectPropertyListPackets.GetOrAdd(obj, value => - { - ObjectPropertyList list = new ObjectPropertyList(value); - - value.GetProperties(list); - if (value is Item item) - item.AppendChildProperties(list); - - list.Terminate(); - list.SetStatic(); - return list; - }); - } - - public static ObjectPropertyList FreeOPLPacket(IPropertyListObject obj) - { - if (ObjectPropertyListPackets.TryRemove(obj, out ObjectPropertyList list)) - Packet.Release(list); - - return list; - } - - public static RemoveEntity GetRemoveEntityPacket(IEntity entity) - { - return RemoveEntityPackets.GetOrAdd(entity, value => - { - RemoveEntity packet = new RemoveEntity(value); - packet.SetStatic(); - return packet; - }); - } - - public static void FreeRemoveItemPacket(IEntity entity) - { - if (RemoveEntityPackets.TryRemove(entity, out RemoveEntity p)) - Packet.Release(p); - } - - public static WorldItem GetWorldItemPacket(Item item) - { - return WorldItemPackets.GetOrAdd(item, value => - { - WorldItem packet = new WorldItem(value); - packet.SetStatic(); - return packet; - }); - } - - public static WorldItemSA GetWorldItemSAPacket(Item item) - { - return WorldItemSAPackets.GetOrAdd(item, value => - { - WorldItemSA packet = new WorldItemSA(value); - packet.SetStatic(); - return packet; - }); - } - - public static WorldItemHS GetWorldItemHSPacket(Item item) - { - return WorldItemHSPackets.GetOrAdd(item, value => - { - WorldItemHS packet = new WorldItemHS(value); - packet.SetStatic(); - return packet; - }); - } - - public static void FreeWorldItemPackets(Item item) - { - if (WorldItemPackets.TryRemove(item, out WorldItem wi)) - Packet.Release(wi); - - if (WorldItemSAPackets.TryRemove(item, out WorldItemSA wisa)) - Packet.Release(wisa); - - if (WorldItemHSPackets.TryRemove(item, out WorldItemHS wihs)) - Packet.Release(wihs); - } - } -} diff --git a/Projects/Server/Notoriety.cs b/Projects/Server/Notoriety.cs index 60dd4e3b6..a5e025a60 100644 --- a/Projects/Server/Notoriety.cs +++ b/Projects/Server/Notoriety.cs @@ -20,17 +20,17 @@ namespace Server { - public delegate int NotorietyHandler(Mobile source, Mobile target); + public delegate byte NotorietyHandler(Mobile source, Mobile target); public static class Notoriety { - public const int Innocent = 1; - public const int Ally = 2; - public const int CanBeAttacked = 3; - public const int Criminal = 4; - public const int Enemy = 5; - public const int Murderer = 6; - public const int Invulnerable = 7; + public const byte Innocent = 1; + public const byte Ally = 2; + public const byte CanBeAttacked = 3; + public const byte Criminal = 4; + public const byte Enemy = 5; + public const byte Murderer = 6; + public const byte Invulnerable = 7; public static NotorietyHandler Handler{ get; set; } @@ -46,13 +46,7 @@ namespace Server 0x035 }; - public static int GetHue(int noto) - { - if (noto < 0 || noto >= Hues.Length) - return 0; - - return Hues[noto]; - } + public static int GetHue(int noto) => noto < 0 || noto >= Hues.Length ? 0 : Hues[noto]; public static int Compute(Mobile source, Mobile target) => Handler?.Invoke(source, target) ?? CanBeAttacked; } diff --git a/Projects/Server/ObjectPropertyList.cs b/Projects/Server/ObjectPropertyList.cs index abb437934..fc1c8aaf5 100644 --- a/Projects/Server/ObjectPropertyList.cs +++ b/Projects/Server/ObjectPropertyList.cs @@ -18,27 +18,19 @@ * ***************************************************************************/ -using System.IO; +using System; +using System.Buffers; using System.Text; +using Server.Buffers; using Server.Network; namespace Server { - public interface IPropertyListObject : IEntity + public sealed class ObjectPropertyList { - ObjectPropertyList PropertyList{ get; } - OPLInfo OPLPacket{ get; } - - void GetProperties(ObjectPropertyList list); - } - - public sealed class ObjectPropertyList : Packet - { - private static byte[] m_Buffer = new byte[1024]; - private static Encoding m_Encoding = Encoding.Unicode; - // Each of these are localized to "~1_NOTHING~" which allows the string argument to be used - private static int[] m_StringNumbers = + // TODO: There are more of these, add them. + private static readonly int[] m_StringNumbers = { 1042971, 1070722 @@ -47,18 +39,9 @@ namespace Server private int m_Hash; private int m_Strings; - public ObjectPropertyList(IEntity e) : base(0xD6) - { - EnsureCapacity(128); + private ArrayBufferWriter m_Buffer = new ArrayBufferWriter(); - Entity = e; - - m_Stream.Write((short)1); - m_Stream.Write(e.Serial); - m_Stream.Write((byte)0); - m_Stream.Write((byte)0); - m_Stream.Write(e.Serial); - } + public ObjectPropertyList(IEntity e) => Entity = e; public IEntity Entity{ get; } @@ -70,29 +53,26 @@ namespace Server public static bool Enabled{ get; set; } - public void Add(int number) + public void Send(NetState ns) { - if (number == 0) + if (ns == null) return; - AddHash(number); + ReadOnlySpan body = m_Buffer.WrittenSpan; - if (Header == 0) - { - Header = number; - HeaderArgs = ""; - } + ushort length = (ushort)(19 + body.Length); + SpanWriter writer = new SpanWriter(stackalloc byte[length]); + writer.Write((byte)0xD6); // Packet ID + writer.Write(length); // Dynamic Length - m_Stream.Write(number); - m_Stream.Write((short)0); - } + writer.Write((short)1); // Command + writer.Write(Entity.Serial); + writer.Position += 2; + writer.Write(m_Hash); + writer.Write(body); + writer.Position += 4; - public void Terminate() - { - m_Stream.Write(0); - - m_Stream.Seek(11, SeekOrigin.Begin); - m_Stream.Write(m_Hash); + ns.Send(writer.Span); } public void AddHash(int val) @@ -101,13 +81,12 @@ namespace Server m_Hash ^= val >> 26 & 0x3F; } - public void Add(int number, string arguments) + public void Add(int number, string arguments = "") { if (number == 0) return; - if (arguments == null) - arguments = ""; + arguments ??= ""; if (Header == 0) { @@ -116,34 +95,17 @@ namespace Server } AddHash(number); - AddHash(arguments.GetHashCode()); + if (arguments != "") + AddHash(arguments.GetHashCode()); - m_Stream.Write(number); + int argLength = Encoding.Unicode.GetByteCount(arguments); + int length = 6 + argLength; + SpanWriter writer = new SpanWriter(m_Buffer.GetSpan(length)); + writer.Write(number); + writer.Write((short)argLength); + writer.WriteLittleUni(arguments); - int byteCount = m_Encoding.GetByteCount(arguments); - - if (byteCount > m_Buffer.Length) - m_Buffer = new byte[byteCount]; - - byteCount = m_Encoding.GetBytes(arguments, 0, arguments.Length, m_Buffer, 0); - - m_Stream.Write((short)byteCount); - m_Stream.Write(m_Buffer, 0, byteCount); - } - - public void Add(int number, string format, object arg0) - { - Add(number, string.Format(format, arg0)); - } - - public void Add(int number, string format, object arg0, object arg1) - { - Add(number, string.Format(format, arg0, arg1)); - } - - public void Add(int number, string format, object arg0, object arg1, object arg2) - { - Add(number, string.Format(format, arg0, arg1, arg2)); + m_Buffer.Advance(length); } public void Add(int number, string format, params object[] args) @@ -158,42 +120,20 @@ namespace Server Add(GetStringNumber(), text); } - public void Add(string format, string arg0) - { - Add(GetStringNumber(), string.Format(format, arg0)); - } - - public void Add(string format, string arg0, string arg1) - { - Add(GetStringNumber(), string.Format(format, arg0, arg1)); - } - - public void Add(string format, string arg0, string arg1, string arg2) - { - Add(GetStringNumber(), string.Format(format, arg0, arg1, arg2)); - } - public void Add(string format, params object[] args) { Add(GetStringNumber(), string.Format(format, args)); } - } - public sealed class OPLInfo : Packet - { - /*public OPLInfo( ObjectPropertyList list ) : base( 0xBF ) + public void SendOPLInfo(NetState ns) { - EnsureCapacity( 13 ); + SpanWriter writer = new SpanWriter(stackalloc byte[9]); + writer.Write((byte)0xDC); // Packet ID - m_Stream.Write( (short) 0x10 ); - m_Stream.Write( (int) list.Entity.Serial ); - m_Stream.Write( (int) list.Hash ); - }*/ + writer.Write(Entity.Serial); + writer.Write(m_Hash); - public OPLInfo(ObjectPropertyList list) : base(0xDC, 9) - { - m_Stream.Write(list.Entity.Serial); - m_Stream.Write(list.Hash); + ns.Send(writer.Span); } } } diff --git a/Projects/Server/Persistence/BinaryMemoryWriter.cs b/Projects/Server/Persistence/BinaryMemoryWriter.cs index 266cc76cf..d84f04238 100644 --- a/Projects/Server/Persistence/BinaryMemoryWriter.cs +++ b/Projects/Server/Persistence/BinaryMemoryWriter.cs @@ -20,7 +20,7 @@ using System.IO; -namespace Server +namespace Server.Persistence { public sealed class BinaryMemoryWriter : BinaryFileWriter { diff --git a/Projects/Server/Persistence/DualSaveStrategy.cs b/Projects/Server/Persistence/DualSaveStrategy.cs index 8e9ce9785..090484330 100644 --- a/Projects/Server/Persistence/DualSaveStrategy.cs +++ b/Projects/Server/Persistence/DualSaveStrategy.cs @@ -20,7 +20,7 @@ using System.Threading; -namespace Server +namespace Server.Persistence { public sealed class DualSaveStrategy : StandardSaveStrategy { diff --git a/Projects/Server/Persistence/DynamicSaveStrategy.cs b/Projects/Server/Persistence/DynamicSaveStrategy.cs index 0132c1f52..5e87114f5 100644 --- a/Projects/Server/Persistence/DynamicSaveStrategy.cs +++ b/Projects/Server/Persistence/DynamicSaveStrategy.cs @@ -23,9 +23,8 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Threading.Tasks; -using Server.Guilds; -namespace Server +namespace Server.Persistence { public sealed class DynamicSaveStrategy : SaveStrategy { diff --git a/Projects/Server/Persistence/FileOperations.cs b/Projects/Server/Persistence/FileOperations.cs index 3939c9e48..89ec8a90a 100644 --- a/Projects/Server/Persistence/FileOperations.cs +++ b/Projects/Server/Persistence/FileOperations.cs @@ -18,16 +18,9 @@ * ***************************************************************************/ - -using System; using System.IO; -#if !MONO -using System.Runtime.InteropServices; -using Microsoft.Win32.SafeHandles; -#endif - -namespace Server +namespace Server.Persistence { public static class FileOperations { @@ -38,12 +31,8 @@ namespace Server public static int Concurrency{ get; set; } = 1; - public static bool Unbuffered{ get; set; } = true; - public static bool AreSynchronous => Concurrency < 1; - public static bool AreAsynchronous => Concurrency > 0; - public static FileStream OpenSequentialStream(string path, FileMode mode, FileAccess access, FileShare share) { FileOptions options = FileOptions.SequentialScan; @@ -104,6 +93,5 @@ namespace Server internal static extern SafeFileHandle CreateFile(string lpFileName, int dwDesiredAccess, FileShare dwShareMode, IntPtr securityAttrs, FileMode dwCreationDisposition, int dwFlagsAndAttributes, IntPtr hTemplateFile); } -#endif } } diff --git a/Projects/Server/Persistence/FileQueue.cs b/Projects/Server/Persistence/FileQueue.cs index 082c11ded..9390bc6e6 100644 --- a/Projects/Server/Persistence/FileQueue.cs +++ b/Projects/Server/Persistence/FileQueue.cs @@ -23,7 +23,7 @@ using System.Buffers; using System.Collections.Generic; using System.Threading; -namespace Server +namespace Server.Persistence { public delegate void FileCommitCallback(FileQueue.Chunk chunk); @@ -47,7 +47,7 @@ namespace Server public FileQueue(int concurrentWrites, FileCommitCallback callback) { - if (concurrentWrites < 1) throw new ArgumentOutOfRangeException("concurrentWrites"); + if (concurrentWrites < 1) throw new ArgumentOutOfRangeException(nameof(concurrentWrites)); if (bufferSize < 1) throw new ArgumentOutOfRangeException("bufferSize"); @@ -134,7 +134,7 @@ namespace Server { if (active[slot] != chunk) throw new ArgumentException(); - ArrayPool.Shared.Return(chunk.Buffer); + ArrayPool.Shared.Return(chunk.Buffer, true); if (pending.Count > 0) { @@ -157,18 +157,17 @@ namespace Server public void Enqueue(byte[] buffer, int offset, int size) { - if (buffer == null) throw new ArgumentNullException("buffer"); + if (buffer == null) throw new ArgumentNullException(nameof(buffer)); - if (offset < 0) throw new ArgumentOutOfRangeException("offset"); - if (size < 0) throw new ArgumentOutOfRangeException("size"); + if (offset < 0) throw new ArgumentOutOfRangeException(nameof(offset)); + if (size < 0) throw new ArgumentOutOfRangeException(nameof(size)); if (buffer.Length - offset < size) throw new ArgumentException(); Position += size; while (size > 0) { - if (buffered.buffer == null) - buffered.buffer = ArrayPool.Shared.Rent(bufferSize); + buffered.buffer ??= ArrayPool.Shared.Rent(bufferSize); byte[] page = buffered.buffer; // buffer page int pageSpace = page.Length - buffered.length; // available bytes in page diff --git a/Projects/Server/Persistence/ParallelSaveStrategy.cs b/Projects/Server/Persistence/ParallelSaveStrategy.cs index 80614bc3c..b79c9ca5f 100644 --- a/Projects/Server/Persistence/ParallelSaveStrategy.cs +++ b/Projects/Server/Persistence/ParallelSaveStrategy.cs @@ -22,9 +22,8 @@ using System; using System.Collections; using System.Collections.Generic; using System.Threading; -using Server.Guilds; -namespace Server +namespace Server.Persistence { public sealed class ParallelSaveStrategy : SaveStrategy { diff --git a/Projects/Server/Persistence/Persistence.cs b/Projects/Server/Persistence/Persistence.cs index 61c3dc9c7..c8f9f291f 100644 --- a/Projects/Server/Persistence/Persistence.cs +++ b/Projects/Server/Persistence/Persistence.cs @@ -5,7 +5,7 @@ using System.IO; #endregion -namespace Server +namespace Server.Persistence { public static class Persistence { diff --git a/Projects/Server/Persistence/QueuedMemoryWriter.cs b/Projects/Server/Persistence/QueuedMemoryWriter.cs index 1bcd67982..468183a9b 100644 --- a/Projects/Server/Persistence/QueuedMemoryWriter.cs +++ b/Projects/Server/Persistence/QueuedMemoryWriter.cs @@ -21,7 +21,7 @@ using System.Collections.Generic; using System.IO; -namespace Server +namespace Server.Persistence { public sealed class QueuedMemoryWriter : BinaryFileWriter { diff --git a/Projects/Server/Persistence/SaveStrategy.cs b/Projects/Server/Persistence/SaveStrategy.cs index dbf7f6938..b53ad34a6 100644 --- a/Projects/Server/Persistence/SaveStrategy.cs +++ b/Projects/Server/Persistence/SaveStrategy.cs @@ -18,7 +18,7 @@ * ***************************************************************************/ -namespace Server +namespace Server.Persistence { public abstract class SaveStrategy { diff --git a/Projects/Server/Persistence/SequentialFileWriter.cs b/Projects/Server/Persistence/SequentialFileWriter.cs index 9b1d327b6..d232639cd 100644 --- a/Projects/Server/Persistence/SequentialFileWriter.cs +++ b/Projects/Server/Persistence/SequentialFileWriter.cs @@ -21,7 +21,7 @@ using System; using System.IO; -namespace Server +namespace Server.Persistence { public sealed class SequentialFileWriter : Stream { diff --git a/Projects/Server/Persistence/StandardSaveStrategy.cs b/Projects/Server/Persistence/StandardSaveStrategy.cs index 8b32c1cd0..810564058 100644 --- a/Projects/Server/Persistence/StandardSaveStrategy.cs +++ b/Projects/Server/Persistence/StandardSaveStrategy.cs @@ -20,9 +20,8 @@ using System; using System.Collections.Generic; -using Server.Guilds; -namespace Server +namespace Server.Persistence { public class StandardSaveStrategy : SaveStrategy { @@ -91,7 +90,7 @@ namespace Server idx.Write((int)(bin.Position - start)); - m.FreeCache(); + m.ClearProperties(); } tdb.Write(World.m_MobileTypes.Count); @@ -144,7 +143,7 @@ namespace Server idx.Write((int)(bin.Position - start)); - item.FreeCache(); + item.ClearProperties(); } tdb.Write(World.m_ItemTypes.Count); diff --git a/Projects/Server/Prompt.cs b/Projects/Server/Prompt.cs index 36c9de092..d54c87edf 100644 --- a/Projects/Server/Prompt.cs +++ b/Projects/Server/Prompt.cs @@ -18,11 +18,11 @@ * ***************************************************************************/ -namespace Server.Prompts +namespace Server { public abstract class Prompt { - private static int m_Serials; + private static Serial m_Serials; protected Prompt() { @@ -32,7 +32,7 @@ namespace Server.Prompts } while (Serial == 0); } - public int Serial{ get; } + public Serial Serial{ get; } public virtual void OnCancel(Mobile from) { @@ -42,4 +42,4 @@ namespace Server.Prompts { } } -} \ No newline at end of file +} diff --git a/Projects/Server/QuestArrow.cs b/Projects/Server/QuestArrow.cs index 5dd3cef2e..c36a3f637 100644 --- a/Projects/Server/QuestArrow.cs +++ b/Projects/Server/QuestArrow.cs @@ -58,9 +58,9 @@ namespace Server return; if (ns.HighSeas) - ns.Send(new SetArrowHS(x, y, Target.Serial)); + Packets.SendSetArrowHS(ns, Target.Serial, (short)x, (short)y); else - ns.Send(new SetArrow(x, y)); + Packets.SendSetArrow(ns, (short)x, (short)y); } public void Stop() @@ -80,9 +80,9 @@ namespace Server if (ns != null) { if (ns.HighSeas) - ns.Send(new CancelArrowHS(x, y, Target.Serial)); + Packets.SendCancelArrowHS(ns, Target.Serial, (short)x, (short)y); else - ns.Send(new CancelArrow()); + Packets.SendCancelArrow(ns); } Running = false; @@ -97,4 +97,4 @@ namespace Server { } } -} \ No newline at end of file +} diff --git a/Projects/Server/Region.cs b/Projects/Server/Region.cs index 572d4750a..649645e5d 100644 --- a/Projects/Server/Region.cs +++ b/Projects/Server/Region.cs @@ -21,15 +21,17 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Xml; using Server.Network; using Server.Targeting; namespace Server { - public enum MusicName + public enum MusicName : ushort { - Invalid = -1, + Invalid = 0xFFFF, + None = 0x1FFF, OldUlt01 = 0, Create1, DragFlit, @@ -473,13 +475,7 @@ namespace Server List list = new List(); for (int i = 0; i < Sectors?.Length; i++) - { - Sector sector = Sectors[i]; - - foreach (Mobile player in sector.Players) - if (player.Region.IsPartOf(this)) - list.Add(player); - } + list.AddRange(Sectors[i].Players.Where(player => player.Region.IsPartOf(this))); return list; } @@ -489,13 +485,7 @@ namespace Server int count = 0; for (int i = 0; i < Sectors?.Length; i++) - { - Sector sector = Sectors[i]; - - foreach (Mobile player in sector.Players) - if (player.Region.IsPartOf(this)) - count++; - } + count += Sectors[i].Players.Count(player => player.Region.IsPartOf(this)); return count; } @@ -504,13 +494,7 @@ namespace Server List list = new List(); for (int i = 0; i < Sectors?.Length; i++) - { - Sector sector = Sectors[i]; - - foreach (Mobile mobile in sector.Mobiles) - if (mobile.Region.IsPartOf(this)) - list.Add(mobile); - } + list.AddRange(Sectors[i].Mobiles.Where(mobile => mobile.Region.IsPartOf(this))); return list; } @@ -519,13 +503,7 @@ namespace Server int count = 0; for (int i = 0; i < Sectors?.Length; i++) - { - Sector sector = Sectors[i]; - - foreach (Mobile mobile in sector.Mobiles) - if (mobile.Region.IsPartOf(this)) - count++; - } + count += Sectors[i].Mobiles.Count(mobile => mobile.Region.IsPartOf(this)); return count; } @@ -701,7 +679,8 @@ namespace Server { m.CheckLightLevels(false); - if (oldRegion == null || oldRegion.Music != newRegion.Music) m.Send(PlayMusic.GetInstance(newRegion.Music)); + if (oldRegion == null || oldRegion.Music != newRegion.Music) + Packets.SendPlayMusic(m.NetState, newRegion.Music); } Region oldR = oldRegion; diff --git a/Projects/Server/Sector.cs b/Projects/Server/Sector.cs index 32d9810cf..57f708064 100644 --- a/Projects/Server/Sector.cs +++ b/Projects/Server/Sector.cs @@ -91,8 +91,7 @@ namespace Server private void Add(ref List list, T value) { - if (list == null) list = new List(); - + list ??= new List(); list.Add(value); } diff --git a/Projects/Server/SecureTrade.cs b/Projects/Server/SecureTrade.cs index a1d3872e3..ae20e2f62 100644 --- a/Projects/Server/SecureTrade.cs +++ b/Projects/Server/SecureTrade.cs @@ -18,16 +18,11 @@ * ***************************************************************************/ -#region References - using System; using System.Collections.Generic; -using Server.Accounting; using Server.Items; using Server.Network; -#endregion - namespace Server { public class SecureTrade @@ -39,56 +34,33 @@ namespace Server From = new SecureTradeInfo(this, from, new SecureTradeContainer(this)); To = new SecureTradeInfo(this, to, new SecureTradeContainer(this)); - bool from6017 = from.NetState?.ContainerGridLines == true; - bool to6017 = to.NetState?.ContainerGridLines == true; + NetState fromNS = from.NetState; + NetState toNS = to.NetState; - bool from704565 = from.NetState?.NewSecureTrading == true; - bool to704565 = to.NetState?.NewSecureTrading == true; - - from.Send(new MobileStatus(from, to)); - from.Send(new UpdateSecureTrade(From.Container, false, false)); - - if (from6017) - from.Send(new SecureTradeEquip6017(To.Container, to)); - else - from.Send(new SecureTradeEquip(To.Container, to)); - - from.Send(new UpdateSecureTrade(From.Container, false, false)); - - if (from6017) - from.Send(new SecureTradeEquip6017(From.Container, from)); - else - from.Send(new SecureTradeEquip(From.Container, from)); - - from.Send(new DisplaySecureTrade(to, From.Container, To.Container, to.Name)); - from.Send(new UpdateSecureTrade(From.Container, false, false)); + bool from704565 = fromNS?.NewSecureTrading == true; + bool to704565 = toNS?.NewSecureTrading == true; + Packets.SendMobileStatus(fromNS, from, to); + Packets.SendUpdateSecureTrade(fromNS, From.Container.Serial, false, false); + Packets.SendSecureTradeEquip(fromNS, To.Container, to.Serial); + Packets.SendUpdateSecureTrade(fromNS, From.Container.Serial, false, false); + Packets.SendSecureTradeEquip(fromNS, To.Container, from.Serial); + Packets.SendDisplaySecureTrade(fromNS, to.Serial, From.Container.Serial, To.Container.Serial, to.Name); + Packets.SendUpdateSecureTrade(fromNS, From.Container.Serial, false, false); if (from.Account != null && from704565) - from.Send( - new UpdateSecureTrade(From.Container, TradeFlag.UpdateLedger, from.Account.TotalGold, - from.Account.TotalPlat)); - - to.Send(new MobileStatus(to, from)); - to.Send(new UpdateSecureTrade(To.Container, false, false)); - - if (to6017) - to.Send(new SecureTradeEquip6017(From.Container, from)); - else - to.Send(new SecureTradeEquip(From.Container, from)); - - to.Send(new UpdateSecureTrade(To.Container, false, false)); - - if (to6017) - to.Send(new SecureTradeEquip6017(To.Container, to)); - else - to.Send(new SecureTradeEquip(To.Container, to)); - - to.Send(new DisplaySecureTrade(from, To.Container, From.Container, from.Name)); - to.Send(new UpdateSecureTrade(To.Container, false, false)); + Packets.SendUpdateSecureTrade(fromNS, From.Container.Serial, TradeFlag.UpdateLedger,from.Account.TotalGold, + from.Account.TotalPlat); + Packets.SendMobileStatus(toNS, to, from); + Packets.SendUpdateSecureTrade(toNS, To.Container.Serial, false, false); + Packets.SendSecureTradeEquip(toNS, From.Container, from.Serial); + Packets.SendUpdateSecureTrade(toNS, To.Container.Serial, false, false); + Packets.SendSecureTradeEquip(toNS, From.Container, to.Serial); + Packets.SendDisplaySecureTrade(toNS, from.Serial, To.Container.Serial, From.Container.Serial, from.Name); + Packets.SendUpdateSecureTrade(toNS, To.Container.Serial, false, false); if (to.Account != null && to704565) - to.Send(new UpdateSecureTrade(To.Container, TradeFlag.UpdateLedger, to.Account.TotalGold, - to.Account.TotalPlat)); + Packets.SendUpdateSecureTrade(toNS, To.Container.Serial, TradeFlag.UpdateLedger,to.Account.TotalGold, + to.Account.TotalPlat); } public SecureTradeInfo From{ get; } @@ -112,7 +84,8 @@ namespace Server item.OnSecureTrade(From.Mobile, To.Mobile, From.Mobile, false); - if (!item.Deleted) From.Mobile.AddToBackpack(item); + if (!item.Deleted) + From.Mobile.AddToBackpack(item); } list = To.Container.Items; @@ -136,16 +109,15 @@ namespace Server { if (!Valid) return; - From.Mobile.Send(new CloseSecureTrade(From.Container)); - To.Mobile.Send(new CloseSecureTrade(To.Container)); - Valid = false; NetState ns = From.Mobile.NetState; + Packets.SendCloseSecureTrade(ns, From.Container.Serial); ns?.RemoveTrade(this); ns = To.Mobile.NetState; + Packets.SendCloseSecureTrade(ns, To.Container.Serial); ns?.RemoveTrade(this); @@ -170,8 +142,9 @@ namespace Server int plat = left.Mobile.Account.TotalPlat; int gold = left.Mobile.Account.TotalGold; - left.Mobile.Send(new UpdateSecureTrade(left.Container, TradeFlag.UpdateLedger, gold, plat)); - } + if (from.NetState?.NewSecureTrading == true) + Packets.SendUpdateSecureTrade(from.NetState, left.Container.Serial, TradeFlag.UpdateLedger, + from.Account.TotalPlat, from.Account.TotalGold); if (right.Mobile.NetState?.NewSecureTrading == true) right.Mobile.Send(new UpdateSecureTrade(right.Container, TradeFlag.UpdateGold, left.Gold, left.Plat)); @@ -241,8 +214,8 @@ namespace Server From.Accepted = false; To.Accepted = false; - From.Mobile.Send(new UpdateSecureTrade(From.Container, From.Accepted, To.Accepted)); - To.Mobile.Send(new UpdateSecureTrade(To.Container, To.Accepted, From.Accepted)); + Packets.SendUpdateSecureTrade(From.Mobile.NetState, From.Container.Serial, From.Accepted, To.Accepted); + Packets.SendUpdateSecureTrade(To.Mobile.NetState, To.Container.Serial, To.Accepted, From.Accepted); return; } @@ -282,8 +255,8 @@ namespace Server } else if (!From.IsDisposed && !To.IsDisposed) { - From.Mobile.Send(new UpdateSecureTrade(From.Container, From.Accepted, To.Accepted)); - To.Mobile.Send(new UpdateSecureTrade(To.Container, To.Accepted, From.Accepted)); + Packets.SendUpdateSecureTrade(From.Mobile.NetState, From.Container.Serial, From.Accepted, To.Accepted); + Packets.SendUpdateSecureTrade(To.Mobile.NetState, To.Container.Serial, To.Accepted, From.Accepted); } } diff --git a/Projects/Server/Serial.cs b/Projects/Server/Serial.cs index b7d7678e9..1b88958dd 100644 --- a/Projects/Server/Serial.cs +++ b/Projects/Server/Serial.cs @@ -35,7 +35,7 @@ namespace Server { get { - while (World.FindMobile(LastMobile = LastMobile + 1) != null) + while (World.FindMobile(LastMobile += 1) != null) { } @@ -47,7 +47,7 @@ namespace Server { get { - while (World.FindItem(LastItem = LastItem + 1) != null) + while (World.FindItem(LastItem += 1) != null) { } diff --git a/Projects/Server/Serialization.cs b/Projects/Server/Serialization.cs index 106e9c731..85545c962 100644 --- a/Projects/Server/Serialization.cs +++ b/Projects/Server/Serialization.cs @@ -24,7 +24,6 @@ using System.IO; using System.Net; using System.Text; using System.Threading; -using Server.Guilds; namespace Server { @@ -584,10 +583,7 @@ namespace Server public override void Write(BaseGuild value) { - if (value == null) - Write(0); - else - Write(value.Id); + Write(value?.Id ?? 0); } public override void WriteItem(T value) @@ -916,10 +912,7 @@ namespace Server public override IEntity ReadEntity() { Serial serial = ReadUInt(); - IEntity entity = World.FindEntity(serial); - if (entity == null) - return new Entity(serial, new Point3D(0, 0, 0), Map.Internal); - return entity; + return World.FindEntity(serial) ?? new Entity(serial, new Point3D(0, 0, 0), Map.Internal); } public override Item ReadItem() => World.FindItem(ReadUInt()); @@ -1370,10 +1363,7 @@ namespace Server public override void Write(BaseGuild value) { - if (value == null) - Write(0); - else - Write(value.Id); + Write(value?.Id ?? 0); } public override void WriteItem(T value) diff --git a/Projects/Server/Server.csproj b/Projects/Server/Server.csproj index e7ce12400..9af9d04e5 100644 --- a/Projects/Server/Server.csproj +++ b/Projects/Server/Server.csproj @@ -37,6 +37,10 @@ ..\..\Distribution ..\..\Distribution 8.0 + DEBUG;TRACE + false + full + true diff --git a/Projects/Server/Skills.cs b/Projects/Server/Skills.cs index 46eea944d..94c9fb6b6 100644 --- a/Projects/Server/Skills.cs +++ b/Projects/Server/Skills.cs @@ -543,10 +543,8 @@ namespace Server } } else - { // Will be discarded new Skill(this, null, reader); - } //for ( int i = count; i < info.Length; ++i ) // m_Skills[i] = new Skill( this, info[i], 0, 1000, SkillLock.Up ); @@ -701,7 +699,7 @@ namespace Server m_Highest = skill; Owner.OnSkillInvalidated(skill); - Owner.NetState?.Send(new SkillChange(skill)); + Packets.SendSkillChange(Owner.NetState, skill); } #region Skill Getters & Setters @@ -882,4 +880,4 @@ namespace Server #endregion } -} \ No newline at end of file +} diff --git a/Projects/Server/Targeting/MultiTarget.cs b/Projects/Server/Targeting/MultiTarget.cs index b0f7ac754..726a1f324 100644 --- a/Projects/Server/Targeting/MultiTarget.cs +++ b/Projects/Server/Targeting/MultiTarget.cs @@ -24,10 +24,10 @@ namespace Server.Targeting { public abstract class MultiTarget : Target { - protected MultiTarget(int multiID, Point3D offset, int range = 10, bool allowGround = true, TargetFlags flags = TargetFlags.None) + protected MultiTarget(int multiId, Point3D offset, int range = 10, bool allowGround = true, TargetFlags flags = TargetFlags.None) : base(range, allowGround, flags) { - MultiID = multiID; + MultiID = multiId; Offset = offset; } @@ -35,11 +35,12 @@ namespace Server.Targeting public Point3D Offset{ get; set; } - public override Packet GetPacketFor(NetState ns) + public override void Send(NetState ns) { if (ns.HighSeas) - return new MultiTargetReqHS(this); - return new MultiTargetReq(this); + Packets.SendMultiTargetReqHS(ns, this); + else + Packets.SendMultiTargetReq(ns, this); } } } diff --git a/Projects/Server/Targeting/Target.cs b/Projects/Server/Targeting/Target.cs index 72f595a95..baa66cb17 100644 --- a/Projects/Server/Targeting/Target.cs +++ b/Projects/Server/Targeting/Target.cs @@ -25,13 +25,13 @@ namespace Server.Targeting { public abstract class Target { - private static int m_NextTargetID; + private static int _nextTargetId; private Timer m_TimeoutTimer; protected Target(int range, bool allowGround, TargetFlags flags) { - TargetID = ++m_NextTargetID; + TargetID = ++_nextTargetId; Range = range; AllowGround = allowGround; Flags = flags; @@ -57,7 +57,7 @@ namespace Server.Targeting public static void Cancel(Mobile m) { - m.NetState?.Send(CancelTarget.Instance); + Packets.SendCancelTarget(m.NetState); m.Target?.OnTargetCancel(m, TargetCancelType.Canceled); } diff --git a/Projects/Server/TileData.cs b/Projects/Server/TileData.cs index ff97764af..637c8379d 100644 --- a/Projects/Server/TileData.cs +++ b/Projects/Server/TileData.cs @@ -316,9 +316,10 @@ namespace Server { bin.Read(m_StringBuffer, 0, 20); - int count; - - for (count = 0; count < 20 && m_StringBuffer[count] != 0; ++count) ; + int count = 0; + while (count < 20 && m_StringBuffer[count++] != 0) + { + } return Encoding.ASCII.GetString(m_StringBuffer, 0, count); } diff --git a/Projects/Server/TileMatrix.cs b/Projects/Server/TileMatrix.cs index 953da3dd7..310b4f1ac 100644 --- a/Projects/Server/TileMatrix.cs +++ b/Projects/Server/TileMatrix.cs @@ -191,8 +191,7 @@ namespace Server if (x < 0 || y < 0 || x >= BlockWidth || y >= BlockHeight) return; - if (m_StaticTiles[x] == null) - m_StaticTiles[x] = new StaticTile[BlockHeight][][][]; + m_StaticTiles[x] ??= new StaticTile[BlockHeight][][][]; m_StaticTiles[x][y] = value; @@ -208,8 +207,7 @@ namespace Server if (x < 0 || y < 0 || x >= BlockWidth || y >= BlockHeight || DataStream == null || IndexStream == null) return EmptyStaticBlock; - if (m_StaticTiles[x] == null) - m_StaticTiles[x] = new StaticTile[BlockHeight][][][]; + m_StaticTiles[x] ??= new StaticTile[BlockHeight][][][]; StaticTile[][][] tiles = m_StaticTiles[x][y]; @@ -287,9 +285,7 @@ namespace Server if (x < 0 || y < 0 || x >= BlockWidth || y >= BlockHeight) return; - if (m_LandTiles[x] == null) - m_LandTiles[x] = new LandTile[BlockHeight][]; - + m_LandTiles[x] ??= new LandTile[BlockHeight][]; m_LandTiles[x][y] = value; if (m_LandPatches[x] == null) @@ -304,8 +300,7 @@ namespace Server if (x < 0 || y < 0 || x >= BlockWidth || y >= BlockHeight || MapStream == null) return m_InvalidLandBlock; - if (m_LandTiles[x] == null) - m_LandTiles[x] = new LandTile[BlockHeight][]; + m_LandTiles[x] ??= new LandTile[BlockHeight][]; LandTile[] tiles = m_LandTiles[x][y]; @@ -389,7 +384,7 @@ namespace Server while (pCur < pEnd) { lists[pCur->m_X & 0x7][pCur->m_Y & 0x7].Add(pCur->m_ID, pCur->m_Z); - pCur = pCur + 1; + pCur += 1; } StaticTile[][][] tiles = new StaticTile[8][][]; @@ -469,8 +464,13 @@ namespace Server } } + public interface ITile + { + int ID { get; } + } + [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct LandTile + public struct LandTile : ITile { internal short m_ID; internal sbyte m_Z; @@ -501,7 +501,7 @@ namespace Server } [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct StaticTile + public struct StaticTile : ITile { internal ushort m_ID; internal byte m_X; diff --git a/Projects/Server/Timer.cs b/Projects/Server/Timer.cs index 9d37b32f5..b2ece459b 100644 --- a/Projects/Server/Timer.cs +++ b/Projects/Server/Timer.cs @@ -87,8 +87,7 @@ namespace Server get => m_Priority; set { - if (!m_PrioritySet) - m_PrioritySet = true; + m_PrioritySet |= !m_PrioritySet; if (m_Priority != value) { @@ -196,17 +195,13 @@ namespace Server if (ts >= TimeSpan.FromSeconds(5.0)) return TimerPriority.TwoFiftyMS; - if (ts >= TimeSpan.FromSeconds(2.5)) - return TimerPriority.FiftyMS; - - if (ts >= TimeSpan.FromSeconds(1.0)) - return TimerPriority.TwentyFiveMS; - - if (ts >= TimeSpan.FromSeconds(0.5)) - return TimerPriority.TenMS; - - return TimerPriority.EveryTick; - } + public static TimerPriority ComputePriority(TimeSpan ts) => + ts >= TimeSpan.FromMinutes(1.0) ? TimerPriority.FiveSeconds : + ts >= TimeSpan.FromSeconds(10.0) ? TimerPriority.OneSecond : + ts >= TimeSpan.FromSeconds(5.0) ? TimerPriority.TwoFiftyMS : + ts >= TimeSpan.FromSeconds(2.5) ? TimerPriority.FiftyMS : + ts >= TimeSpan.FromSeconds(1.0) ? TimerPriority.TwentyFiveMS : + ts >= TimeSpan.FromSeconds(0.5) ? TimerPriority.TenMS : TimerPriority.EveryTick; public void Start() { @@ -240,11 +235,11 @@ namespace Server public class TimerThread { - private static Dictionary m_Changed = new Dictionary(); + private static readonly Dictionary m_Changed = new Dictionary(); - private static long[] m_NextPriorities = new long[8]; + private static readonly long[] m_NextPriorities = new long[8]; - private static long[] m_PriorityDelays = { + private static readonly long[] m_PriorityDelays = { 0, 10, 25, @@ -266,7 +261,7 @@ namespace Server new List() }; - private static AutoResetEvent m_Signal = new AutoResetEvent(false); + private static readonly AutoResetEvent m_Signal = new AutoResetEvent(false); public static void DumpInfo(TextWriter tw) { @@ -289,14 +284,9 @@ namespace Server list.Add(t); } - foreach (KeyValuePair> kv in hash) - { - string key = kv.Key; - List list = kv.Value; - + foreach (var (key, list) in hash) tw.WriteLine("Type: {0}; Count: {1}; Percent: {2}%", key, list.Count, (int)(100 * (list.Count / (double)m_Timers[i].Count))); - } tw.WriteLine(); tw.WriteLine(); @@ -306,9 +296,7 @@ namespace Server public static void Change(Timer t, int newIndex, bool isAdd) { lock (m_Changed) - { m_Changed[t] = TimerChangeEntry.GetInstance(t, newIndex, isAdd); - } m_Signal.Set(); } diff --git a/Projects/Server/Utility.cs b/Projects/Server/Utility.cs index d4c4a1b70..4041a5e1c 100644 --- a/Projects/Server/Utility.cs +++ b/Projects/Server/Utility.cs @@ -22,6 +22,7 @@ using System; using System.Collections.Generic; using System.Globalization; using System.IO; +using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; @@ -118,8 +119,8 @@ namespace Server private static Stack m_ConsoleColors = new Stack(); - public static Encoding UTF8 => m_UTF8 ?? (m_UTF8 = new UTF8Encoding(false, false)); - public static Encoding UTF8WithEncoding => m_UTF8WithEncoding ?? (m_UTF8WithEncoding = new UTF8Encoding(true, false)); + public static Encoding UTF8 => m_UTF8 ??= new UTF8Encoding(false, false); + public static Encoding UTF8WithEncoding => m_UTF8WithEncoding ??= new UTF8Encoding(true, false); public static void Separate(StringBuilder sb, string value, string separator) { @@ -138,8 +139,7 @@ namespace Server public static IPAddress Intern(IPAddress ipAddress) { - if (_ipAddressTable == null) - _ipAddressTable = new Dictionary(); + _ipAddressTable ??= new Dictionary(); if (!_ipAddressTable.TryGetValue(ipAddress, out IPAddress interned)) { @@ -518,79 +518,15 @@ namespace Server int adx = Math.Abs(dx); int ady = Math.Abs(dy); - if (adx >= ady * 3) - { - if (dx > 0) - return Direction.East; - return Direction.West; - } + if (adx >= ady * 3) return dx > 0 ? Direction.East : Direction.West; - if (ady >= adx * 3) - { - if (dy > 0) - return Direction.South; - return Direction.North; - } + if (ady >= adx * 3) return dy > 0 ? Direction.South : Direction.North; - if (dx > 0) - { - if (dy > 0) - return Direction.Down; - return Direction.Right; - } + if (dx > 0) return dy > 0 ? Direction.Down : Direction.Right; return dy > 0 ? Direction.Left : Direction.Up; } - /* Should probably be rewritten to use an ITile interface - - public static bool CanMobileFit( int z, StaticTile[] tiles ) - { - int checkHeight = 15; - int checkZ = z; - - for ( int i = 0; i < tiles.Length; ++i ) - { - StaticTile tile = tiles[i]; - - if ( ((checkZ + checkHeight) > tile.Z && checkZ < (tile.Z + tile.Height))*/ - /* || (tile.Z < (checkZ + checkHeight) && (tile.Z + tile.Height) > checkZ)*/ /* ) - { - return false; - } - else if ( checkHeight == 0 && tile.Height == 0 && checkZ == tile.Z ) - { - return false; - } - } - - return true; - } - - public static bool IsInContact( StaticTile check, StaticTile[] tiles ) - { - int checkHeight = check.Height; - int checkZ = check.Z; - - for ( int i = 0; i < tiles.Length; ++i ) - { - StaticTile tile = tiles[i]; - - if ( ((checkZ + checkHeight) > tile.Z && checkZ < (tile.Z + tile.Height))*/ - /* || (tile.Z < (checkZ + checkHeight) && (tile.Z + tile.Height) > checkZ)*/ /* ) - { - return true; - } - else if ( checkHeight == 0 && tile.Height == 0 && checkZ == tile.Z ) - { - return true; - } - } - - return false; - } - */ - public static object GetArrayCap(Array array, int index, object emptyValue = null) { if (array.Length > 0) @@ -793,14 +729,7 @@ namespace Server public static List SafeConvertList(List list) where TOutput : class { List output = new List(list.Capacity); - - for (int i = 0; i < list.Count; i++) - { - TOutput t = list[i] as TOutput; - - if (t != null) - output.Add(t); - } + output.AddRange(list.OfType()); return output; } @@ -1031,6 +960,8 @@ namespace Server public static double RandomDouble() => RandomImpl.NextDouble(); + public static double RandomDouble() => RandomImpl.NextDouble(); + #endregion #region Random Hues diff --git a/Projects/Server/VirtueInfo.cs b/Projects/Server/VirtueInfo.cs index 833e03071..1b6130197 100644 --- a/Projects/Server/VirtueInfo.cs +++ b/Projects/Server/VirtueInfo.cs @@ -130,8 +130,7 @@ namespace Server public void SetValue(int index, int value) { - if (Values == null) - Values = new int[8]; + Values ??= new int[8]; Values[index] = value; } @@ -162,4 +161,4 @@ namespace Server } } } -} \ No newline at end of file +} diff --git a/Projects/Server/World.cs b/Projects/Server/World.cs index 9f4f67b98..911d1f8cc 100644 --- a/Projects/Server/World.cs +++ b/Projects/Server/World.cs @@ -24,14 +24,14 @@ using System.Diagnostics; using System.IO; using System.Reflection; using System.Threading; -using Server.Guilds; using Server.Network; +using Server.Persistence; namespace Server { public static class World { - private static ManualResetEvent m_DiskWriteHandle = new ManualResetEvent(true); + private static readonly ManualResetEvent m_DiskWriteHandle = new ManualResetEvent(true); private static Queue _addQueue, _deleteQueue; @@ -91,22 +91,19 @@ namespace Server public static void Broadcast(int hue, bool ascii, string text) { - Packet p; - - if (ascii) - p = new AsciiMessage(Serial.MinusOne, -1, MessageType.Regular, hue, 3, "System", text); - else - p = new UnicodeMessage(Serial.MinusOne, -1, MessageType.Regular, hue, 3, "ENU", "System", text); - List list = NetState.Instances; - p.Acquire(); - for (int i = 0; i < list.Count; ++i) - if (list[i].Mobile != null) - list[i].Send(p); + { + NetState state = list[i]; + if (state == null) + continue; - p.Release(); + if (ascii) + Packets.SendAsciiMessage(state, Serial.MinusOne, -1, MessageType.Regular, hue, 3, "System", text); + else + Packets.SendUnicodeMessage(state, Serial.MinusOne, -1, MessageType.Regular, hue, 3, "ENU", "System", text); + } } public static void Broadcast(int hue, bool ascii, string format, params object[] args) @@ -179,8 +176,6 @@ namespace Server _addQueue = new Queue(); _deleteQueue = new Queue(); - int mobileCount, itemCount, guildCount; - object[] ctorArgs = new object[1]; List items = new List(); @@ -574,7 +569,7 @@ namespace Server } } - private static void SaveIndex(List list, string path) where T : IEntityEntry + private static void SaveIndex(IReadOnlyList list, string path) where T : IEntityEntry { if (!Directory.Exists("Saves/Mobiles/")) Directory.CreateDirectory("Saves/Mobiles/"); @@ -603,12 +598,10 @@ namespace Server idxWriter.Close(); } - public static void Save() - { - Save(true, false); + idxWriter.Close(); } - public static void Save(bool message, bool permitBackgroundWrite) + public static void Save(bool message = true, bool permitBackgroundWrite = false) { if (Saving) return; @@ -672,15 +665,7 @@ namespace Server NetState.Resume(); } - public static IEntity FindEntity(Serial serial) - { - if (serial.IsItem) - return FindItem(serial); - if (serial.IsMobile) - return FindMobile(serial); - - return null; - } + public static IEntity FindEntity(Serial serial) => serial.IsItem ? (IEntity)FindItem(serial) : serial.IsMobile ? FindMobile(serial) : null; public static Mobile FindMobile(Serial serial) {