Commit graph

101 commits

Author SHA1 Message Date
Kamron Batman
16bf3016fb
feat: Pre-Publish 14 Crafting (supersedes #2181, #2381) (#2476)
## Summary

Adds authentic **T2A-era (pre-UO:Third-Dawn) packet-based crafting menus**, enabled via the **`t2aCraftMenus` server setting** (read once at startup; default **`!Core.UOTD`**, so a pre-UO:TD shard gets them automatically). When enabled, double-clicking a crafting tool opens the classic `0x7C`/`0x7D` item-list menu — skill- and material-filtered — instead of the modern gump, covering all 8 tool/skill crafts (blacksmithy, tailoring, tinkering, carpentry, alchemy, bowcraft/fletching, inscription, cartography). It is **not** a runtime/admin-flippable feature flag.

This is the **definitive, reconciled** branch and **supersedes**:
- **#2181** (Delphi — `T2A_CraftingMenus`): the original effort.
- **#2381** (Jack/UOLL — `t2a_crafting_menus`): the research-grounded superset (Delphi's base + 12 corrections), rebased onto current `main`.

Original authorship is preserved across the cherry-picked history: foundation commit **@Delphi79**, mechanic fixes **@jackuoll (Jack Ward)**, reconciliation/fixes/docs mine.

## How it was built

1. Cherry-picked Jack's 13 commits onto current `main` (superset of Delphi's; only 2 trivial FeatureFlags conflicts).
2. Applied targeted fixes (below) with tests.
3. Full convention audit, build, and test pass.

Grounded in independent historical research plus Jack's deep dive. Maintainer reference: `dev-docs/t2a-crafting.md`.

## Mechanics (highlights)

- Double-click tool → target resource → skill/material-filtered menu → craft. Resource pre-selection per skill; make-last by targeting the tool.
- **Stacked-gem jewelry:** target a gem stack → the **full stack** is consumed and the piece is named by count ("a 1000 diamond ring"); count persists (`BaseJewel` serialization **v4 → v5**, new `_gemCount`).
- **Tool-less inscription & cartography** (skill-list invoked; no pen/sextant); inscription consumes reagents+scroll on success and failure, mana only on success.
- **Tailoring matching-hue consumption:** targeting hued cloth/leather consumes only that hue. Crafted items take color from their **`CraftResource`** (not the dyed hue), so dyed leather/cloth don't tint the product; in T2A only colored ingots/ore color items (metal armor/shields).
- **Half-resources on failed non-scroll crafts** (pre-UO:TD).
- **Maker's mark** always prompted for exceptional items, via the shared `QueryMakersMarkGump`.
- Server-side menu infra changes are additive (`ItemListEntry.CraftIndex`, `Entries` setter, `HasSent`).

## Notable changes on top of the cherry-pick

- **Toggle is a startup server setting, not a feature flag.** Removed `ContentFeatureFlags.T2ACraftMenus` (and its admin-flippable plumbing); the value is read once via `ServerConfiguration.GetSetting("t2aCraftMenus", !Core.UOTD)` into `T2ACraftSystem.Enabled`. Since the default tracks the era and it can't be flipped at runtime, there's no incoherent "menus-on / UO:TD-era" state.
- **Stacked-gem consumption (B3a/B3):** consume the full `PendingGemCount` (was deliberately consuming 1 while naming by the stack), null-safe gem type, plain-piece fallback + message. New `T2AJewelGemCraftTests`.
- **Convention audit:** `new List<Item>()` → `PooledRefList<Item>` on the hue-aware consume path; removed dead code.

## Decisions & deviations

- `make-last` kept as **QoL** (post-T2A gump-era feature).
- `half-on-failure` (non-scroll) kept as a **reconstruction** (not OSI-confirmed).
- **Stacked-gem** behavior set per shard authority (overrides the "single gem" reconstruction).
- **Cooking** out of scope (no T2A crafting menu existed for it).
- **No colored items from dyed materials:** crafted color comes from the `CraftResource` type. Pre-AOS leather has no colored variant, so leather is always uncolored; weapons retain resource color only in AOS+ (unchanged, intended).

## Test plan

- Automated: `dotnet build ModernUO.slnx -c Debug` clean; `dotnet test Projects/UOContent.Tests` → **421 passed** (incl. 3 new jewelry tests).
- Manual (needs a running T2A shard + client):
  - [ ] Each of the 8 skills opens the correct menu; empty-menu guard fires.
  - [ ] Make-last repeats the last craft (jewelry re-prompts gem).
  - [ ] Jewelry consumes the full targeted gem stack and names by count.
  - [ ] Cartography consumes blank maps only with T2A enabled / maps+scrolls when disabled.
  - [ ] Tailoring consumes only the targeted-hue material; crafted items are not tinted by dyed cloth/leather.
  - [ ] Maker's-mark prompt on exceptional.
  - [ ] Failed non-scroll craft consumes half resources.
  - [ ] Inscription: reagents+scroll on success/failure, mana only on success.
  - [ ] T2A disabled: gump crafting unchanged.

## Credits

Co-authored-by: @Delphi79
Co-authored-by: @jackuoll
2026-06-07 20:27:22 -07:00
Kamron Batman
50599e0453
perf: Migrate NPC and Skill UI gumps to DynamicGump/StaticGump (#2414)
## Summary

Migrates five legacy `Gump`-derived UI dialogs in the NPC and Skill domains to the modern `DynamicGump` builder pipeline. All five gumps were chosen as `DynamicGump` rather than `StaticGump<T>` because their layout shape varies per instance, and several of them carry per-instance localization numbers (cliloc IDs) that the static cache cannot bake (see CLAUDE.md gump-system rule and `dev-docs/gump-system.md`).

Per-gump rationale:

- **`TownCrierGump` (`Mobiles/Townfolk/TownCrier.cs`)** - DynamicGump. Announcement count varies, expiration text is rebuilt per render via `ValueStringBuilder`, and one button per entry is emitted in a loop.
- **`ClaimListGump` (`Mobiles/Vendors/NPC/AnimalTrainer.cs`)** - DynamicGump. The pet list and resulting background/alpha-region heights vary per stabling player.
- **`AnimalLoreGump` (`Skills/AnimalLore.cs`)** - DynamicGump. Page count itself varies (3 pages pre-AOS, 5 pages on AOS) and several `AddHtmlLocalized` calls use cliloc IDs computed from per-creature data (loyalty rating `1049595 + c.Loyalty / 10`, food preference, pack instinct), which violates the StaticGump cliloc-bake rule.
- **`DisguiseGump` (`Items/Skill Items/Thief/DisguiseKit.cs`)** - DynamicGump. Page count and entry order shift on `from.Female`, `Body.IsFemale`, and `startAtHair`.
- **`CommentsGump` (`Gumps/CommentsGump.cs`)** - DynamicGump. Comment list and pagination depend on `Account.Comments` size; the title label encodes the variable account username string.

All five are now `Singleton => true`, have `private` constructors, and expose static `DisplayTo(...)` entry points that validate prerequisites before constructing - guaranteeing no empty gumps (CLAUDE.md Sec.13). All internal refresh paths (prompts, `OnDoubleClick`, command handlers, target callbacks) were updated to call `DisplayTo` rather than `new XGump(...)`. Legacy `m_`-prefixed fields renamed to `_camelCase` (CLAUDE.md Sec.12), and `DisguiseEntry`'s `m_`-prefixed public readonly fields converted to PascalCase auto-properties. `OnResponse` signatures updated to `in RelayInfo info`. No external callers needed updating - all `new XGump(...)` sites lived inside the same files.
2026-04-25 19:51:42 -07:00
Jack
597c81345e
feat: Adjusts fame and karma system with era gates for OSI accuracy (#2389)
## Summary

Overhauls the fame and karma system to be more era-accurate, based on original design documents and publish notes.

### Karma on player kill → karma on murder report
- Removes karma gain/loss on player kill (was immediate on death)
- Karma is now set to `Kills * -1000` on murder **report** instead
- Fame on player kill now uses the same formula as monster kills (`Fame / 100`)

This karma loss on murder report behaviour was tested on both the demo and live servers, behaviour was matching in terms of karma loss on report. Official UO servers karma loss AMOUNT match with my memory of T2A/UOR with one caveat - it's doubled on live servers (-2000 * kill count). I'm not sure when this changed and this behaviour has always had very poor and incorrect documentation, even 10-20 years ago.  I was obsessed with the dread lord title on OSI and the only way I knew how to get it was reach 10 kills then macro them off. Even in publish 16 (when "The Murderer" title was removed) it still required 10 kills. Maybe it changed to -2000*Kills in AOS - that's where I've put the era gating diff.

### Era gates
- **Karma lock** (ankh toggle + auto-lock on negative karma) gated to `Core.UOTD && !Core.AOS` — [didn't exist before Jan 28, 2001](https://web.archive.org/web/20010128092700/http://update.uo.com/design_300.html)
- **Felucca fame/karma +30% bonus** gated to `Core.LBR` — [added in Publish 16, July 2002](https://uo.com/wiki/ultima-online-wiki/technical/previous-publishes/2002-2/publish-16-part-2-5-23rd-july/)
- **Fame/karma splitting** among damage dealers gated to `Core.UOR` — pre-UOR awards go to last hit only

### Skill karma penalties
- **Provocation** on innocent NPC: NPC says cliloc 501591, karma loss (floor -7500)
- **Stealing** attempt: karma loss on every attempt (floor -5000). Stealing did not cause karma loss at all before!
- **Summon Daemon**: karma loss on successful cast (floor -7000)
- **Corpse carving** (human): -70 for innocent corpses (floor -7000), -20 for freely-aggressable (floor -2000)
- **Bounty head turn-in**: karma gain capped at 2000 (was awarding flat +2000)

### Beneficial action karma
- **Beneficial spells** (heal, cure, etc.): `AwardKarma(caster, target.Karma / 5)` — healing good targets raises karma, healing evil targets lowers it - source is UO98 demo scripts
- **Bandages**: same formula but gain only (skipped if target karma ≤ 0) - see stratics link ("only ever gain karma, not lose it")

Sources: UO98 Demo scripts and playing, [Fame and Karma wiki](https://uo.com/wiki/ultima-online-wiki/player/fame-and-karma/), [UO design doc (Jan 2001)](https://web.archive.org/web/20010128092700/http://update.uo.com/design_300.html), [Publish 16](https://uo.com/wiki/ultima-online-wiki/technical/previous-publishes/2002-2/publish-16-part-2-5-23rd-july/), [Stratics healing reference](https://web.archive.org/web/20001209014200fw_/http://uo.stratics.com/heal.shtml)

### Refactoring
- Extracted `Titles.ComputeKillAwards(killed, map)` shared by player kill and creature kill paths
- Extracted `Titles.SetKarma(m, value, message)` for direct karma assignment (used by murder report)
- Extracted `SendKarmaMessage` and `CheckKarmaLock` helpers from `AwardKarma`
2026-04-25 11:19:57 -07:00
Kamron Batman
61e41df00c
feat: Add zero-alloc interpolation handler to ValueStringBuilder, replace all StringBuilder usage (#2387)
## Summary

- **Add a self-referencing `InterpolationHandler` to `ValueStringBuilder`** that writes directly into the builder's buffer — zero intermediate allocation, works with `stackalloc`-backed builders
- **Replace all `System.Text.StringBuilder` usage** across the codebase with `ValueStringBuilder`
- **Convert `ValueStringBuilder.Create()` to `stackalloc`** at 10 sites where output length is provably bounded
- **Convert manual `Dispose()` to `using var`** where possible, and hoist loop-scoped builders outside loops with `Reset()`
- **Convert verbose `Append()` chains to `Append($"...")`** interpolation for readability
- **Add comprehensive documentation** for string handling patterns

## InterpolationHandler Design

`ValueStringBuilder` is a `ref struct`, which creates challenges for C#'s interpolated string handler pattern:

- **`ref` fields to ref structs are not allowed** (CS9050)
- **`[InterpolatedStringHandlerArgument("")]` passes struct receivers by value**, not by ref
- **`ISelfInterpolatedStringHandler` requires boxing** ref structs into interface fields

**Solution: Copy-and-reconcile pattern.** The handler receives a value copy of the builder. The copy shares the same underlying `char` buffer (`Span` points to the same `stackalloc`/pooled memory), so writes go to the original buffer. `Append()` reconciles by `this = handler._builder`, updating `_length` and any buffer references changed by `Grow()`.

This is safe because:
- The game loop is single-threaded — no concurrent access between handler construction and reconciliation
- If `Grow()` occurs in the copy, the original's stale buffer isn't accessed until `Append()` replaces it
- `Dispose()` correctly returns the reconciled buffer to the pool

## Changes by Category

### ValueStringBuilder (`Projects/Server/Buffers/ValueStringBuilder.cs`)
- Added nested `InterpolationHandler` ref struct with copy-and-reconcile pattern
- Added `Append([InterpolatedStringHandlerArgument("")] scoped ref InterpolationHandler)` method
- Removed `RawInterpolatedStringHandler` overloads (new handler replaces them)
- All `AppendFormatted` overloads delegate to existing `Append` methods (no code duplication)
- Alignment support via direct private field access (nested type privilege)

### StringBuilder → ValueStringBuilder (15 files)
Replaced all `new StringBuilder()` with `ValueStringBuilder.Create()` or `stackalloc`:
- ConPVP games: KingOfTheHill, DoubleDom, CTF, BombingRun, TourneyMatch
- ConPVP infrastructure: Tournament, Participant, TourneyParticipant
- ConPVP gumps: ArenaGump, TournamentBracketGump, AcceptTeamGump, ConfirmSignupGump
- Commands: Handlers, Logging, Add
- Other: TownCrier, SpeechLogGump, TestCenter

Key patterns:
- `sb = new StringBuilder()` reassignment → `sb.Reset()`
- `sb.AppendFormat("{0:N0}", value)` → `sb.Append($"{value:N0}")`
- `sb.Append(x).Append(y)` chains → separate statements (VSB returns void)

### Create() → stackalloc (10 files)
Converted heap-allocated builders to stackalloc where output is bounded:
- ClientVersion (32), MapSelection (160), HouseRaffleStone (48)
- HolySense (96), UnholySense (96), ClientVerification (192)
- AcceptTeamGump (64), ConfirmSignupGump (64)
- BaseWeapon (160), BaseArmor (128)

### Loop optimizations (2 files)
Hoisted `ValueStringBuilder` creation outside loops with `Reset()` per iteration:
- TourneyMatch.cs: `using var` inside for loop → stackalloc before loop
- ArenaGump.cs: `Create()` + `Dispose()` per iteration → stackalloc before loop

### Append chain → interpolation (5 files)
Converted multi-line `Append()` chains to `Append($"...")`:
- BountyMessage.cs: title switch (6 cases), paragraph (15→1 Append), description lines, closing
- AcceptTeamGump, ConfirmSignupGump, TournamentBracketGump: tournament type strings
- AdminGump: comment/tag formatting in loops

### Documentation
- `dev-docs/string-handling.md`: Full reference — construction, interpolation, disposal, decision guide
- `dev-docs/claude-skills/modernuo-string-handling.md`: Claude skill with quick reference
- `CLAUDE.md`: Added rule 17 (no StringBuilder), dev-docs table entry, skills table entry
- `dev-docs/code-standards.md`: Updated memory management section

## Test Plan

- [x] `dotnet build` — 0 errors, 0 warnings
- [x] `dotnet test` — 940/940 tests pass
- [x] 28 ValueStringBuilder tests covering all reconciliation scenarios:
  - Stackalloc no-grow, stackalloc with grow (→pool transition)
  - Heap no-grow, heap with grow, heap double grow
  - Pre-existing content with and without grow
  - Sequential multiple `Append($"...")` calls
  - Mixed plain + interpolated Append
  - Empty interpolation, literal-only, format specifiers
  - Null string holes, ISpanFormattable types
  - Dispose after stackalloc→pool grow
2026-03-22 14:23:44 -07:00
Joe
e1ae970636
fix: Fixes multiple factions bugs with sigil generation, lighting, and theft (#2375) 2026-03-15 11:02:56 -07:00
Kamron Batman
e1e1a7c640
fix: Bumps deps. Updates copyrights (#2353) 2026-03-05 19:36:54 -08:00
Joe
e77a566f32
feat: Implements passive Detect Hidden mechanics (#2342) 2026-02-28 11:24:49 -08:00
Kamron Batman
ebaf104935
chore: Use var everywhere (#2294) 2025-12-27 16:47:28 -08:00
Kamron Batman
5fb0e806c5
feat: Adds proper OSI tracking up to 120 tiles. (#2281)
### Summary

Fixes tracking skill to 10 tiles per 10% up to 120 tiles.
2025-11-29 09:55:52 -08:00
Kamron Batman
55d653d752
fix: Fixes skill cooldown for some target skills (#2231)
### Summary

Stealing, Detect Hidden, and Begging will now give credit for the time it took the player to use the targeter against the total skill cooldown. So if the player takes longer than 10s to target, then they can use a skill again immediately.

> [!NOTE]
> This does not change the requirement that players can no longer stack target these skills.
2025-07-06 22:50:40 -07:00
Kamron Batman
c8d489b72b
fix: Fixes detect hidden skill cooldown (#2213) 2025-06-07 14:05:49 -07:00
Kamron Batman
14bc38e375
fix: Removes the absurb 6 hour skill edge case and fixes target cancellations (#2212) 2025-06-07 13:58:01 -07:00
Kamron Batman
a07e225911
fix: Changes stealing to use proper defaults per era (#2200) 2025-05-26 22:27:54 -07:00
Kamron Batman
cbae44ef20
fix: Updates SummonFamiliar & Tracking gumps to static (#2098) 2025-01-27 17:57:25 -08:00
mark1145
d5160bd6db
fix: Fixes buffs don't start/stop properly. Streamlines constructor and Add/Remove buffs. (#2082) 2025-01-24 18:20:23 -08:00
Kamron Batman
84d9383294
feat: Fixes beneficial notoriety checks and adds better young restrictions/messaging (#2000) 2025-01-20 11:27:19 -08:00
Bohica
8f8d88b5ff
fix: Creature is given follow orders upon taming. (#2076) 2025-01-18 16:58:13 -08:00
Kamron Batman
09d6420320
fix: Fixes Item ID so it doesn't gain from non-identifiable items (#2075) 2025-01-18 10:58:22 -08:00
Kamron Batman
66a257ece2
feat: Converts OnLogin to a coded generated event (#2070) 2025-01-17 15:21:45 -08:00
Guyute
95cd8749a3
feat: Adds PlayerDeathEvent and CreatureDeathEvent using code generated events (#1927)
### Summary
- Adds [Code Generated Events](https://github.com/modernuo/CodeGeneratedEvents)
- Removes EventSink.PlayerDeath
- Adds `PlayerDeathEvent` and `CreatureDeathEvent` using code generated events

> [!Important]
> **Developer Note**
> Use `[OnEvent(nameof(PlayerMobile.PlayerDeathEvent))]` instead of `EventSink.PlayerDeath` delegate
> Check this commit for examples of how to use this.
2024-09-05 21:23:03 -07:00
Kamron Batman
8282b00ca2
feat: Moves gumps out of the core (#1916)
> [!Important]
> **Developer Note**
> This code change will **completely move gumps out of the core**


### Summary

- Adds `GetGumps()` convenience which exposes methods to Find/Close/Send multiple gumps. This helper is a performance improvement by eliminating the Dictionary<Player, List> lookup for gumps.
2024-08-09 19:07:32 -07:00
Kamron Batman
06e05f2e52
fix: Fixes random skill maximum (#1860) 2024-07-06 12:37:33 -07:00
Kamron Batman
46c7c77b41
fix: Adds random bard skill option (#1847) 2024-06-23 16:58:23 -07:00
Kamron Batman
16de17e8a6
fix: Fixes random skills and groupings (#1846) 2024-06-23 16:49:17 -07:00
Marcelo Paez Sequeira
00908d030f
fix: Moves many EventSinks out of core. (#1783) 2024-05-21 10:02:30 -07:00
Kamron Batman
974062b0d4
feat: Adds leather/metal food, fixes weapons/armors with wrong materials (#1718)
### Summary
- Fixes the name `Vegies` to `Veggies`
- Adds feeding leather to goats
- Adds metal for Lava Lizards
- Fixes Bone Helm being classified as plate instead of bone.
- Fixes wooden shields not classified as wood.

### Note
On OSI, the preferred foods on the animal lore gump doesn't contain all possible favorite food categories. Furthermore, the one listed is not necessarily always the "first" in the list of possible categories. We aren't going to try and fix that since it isn't important.
2024-04-04 19:43:02 -07:00
Kamron Batman
cfe9e04c78
fix: Optimizes gump relay info (Prep for Static Gumps) (#1698) 2024-03-07 20:54:53 -08:00
Kamron Batman
7d9bc9ff0a
fix: Fixes thread guard and cleans up incoming packet reader (#1641)
### Summary
* Fixes syntax compile error when THREADGUARD is enabled.
* Removes `int packetLength` from incoming packet handles since they aren't needed.

### Developer Notes
Incoming packet handler `SpanReader` is now properly scoped to that packet by length.
2023-12-19 17:04:09 -08:00
Kamron Batman
e9642d61f1
fix: Removes custom BitArray (#1597)
### Summary

The BitArray class will be optimized over the next several years for various platforms/hardware and maintaining a duplicate for serialization is not practical. Removing the custom implementation. Recommend against using BitArray for serialization unless it is absolutely necessary.
2023-11-17 14:37:07 -08:00
Kamron Batman
a1dffd10ce
fix: Acquired recipes are now a Set (#1596) 2023-11-17 00:04:46 -08:00
Kamron Batman
cde59a82f2
fix: Adds GetClients to map iterators (#1574)
### Summary

Eliminates `IPooledEnumerable<NetState>` and `eable.Free()` from `Map` for clients. This drastically simplifies code that iterates in range, for example:

```cs
foreach (var m in m.GetClientsInRange(5))
{
}
```
The code above no longer requires an eable and calling `Free()`.
2023-10-30 18:49:00 -07:00
Kamron Batman
28c06c1cc0
fix: Changes Map.Sector.Mobiles to link list & Fixes various related crash bugs (#1553)
### Summary

Eliminates `IPooledEnumerable<T>` and `eable.Free()` from `Map` for mobiles. This drastically simplifies code that iterates in range, for example:

```cs
foreach (var m in m.GetMobilesInRange(5))
{
}
```
The code above no longer requires an eable and calling `Free()`.

- [X] Fixed several locations where an NPC that was damaged would cause a server crash.
- [X] Removed an unnecessary allocation in guard fake calls (NPCs calling guards on you)
- [X] Fixes damage precision loss in Poison Strike Spell
- [X] BogThing no longer attempts to "search" for boglings to eat when it is at full health
2023-10-29 22:42:46 -07:00
Kamron Batman
27f0cec1fa
fix: Cleans up Tracking skill and makes it much faster (#1571) 2023-10-29 19:38:59 -07:00
Kamron Batman
aaf0fc32fa
fix: Fixes skill gain issue (#1558) 2023-10-21 10:03:50 -07:00
Kamron Batman
24858f3989
fix: Changes Map.Sector.Items to link list. (#1547)
### Summary

Eliminates `IPooledEnumerable<T>` and `eable.Free()` from `Map` for items. This drastically simplifies code that iterates in range, for example:

```cs
foreach (var item in m.GetItemsInRange(5))
{
}
```
The code above no longer requires an eable and calling `Free()`.
2023-10-16 20:51:02 -07:00
Kamron Batman
d57f1fecc1
fix: Prepares for IPooledEnumerable removal (#1548)
### Summary

- Removes `IPooledEnumerable` (non-generic)
- Changes `IPooledEnumerable<T>` so that  `Free()` is replaced with the `IDisposable` pattern
2023-10-15 11:20:49 -07:00
Vitalii Zurian
f9517854d0
feat: Adds configurable skill and stat gain (#1489)
### Summary

- Adds the following configurations:
```json
"stats.statMax": "125",
"stats.gainChanceMultiplier": 1.0,
"stats.primaryStatGainChance": 0.75,
"stats.gainDelay": "00:10:00",
"stats.petGainDelay": "00:05:00",
"stats.usePub45StatGain": "False"
```

- Adds Pub 45 stat gain rate for UOML+.
- Reduces the gain delay for legacy stat gain from 15 minutes to 10 minutes.
- Legacy gain no longer requires a gain in skill to gain in a stat.
2023-10-14 12:02:36 -07:00
Kamron Batman
10a69bf754
feat: Adds a memory mirrored ring buffer for networking. (#1533)
## Breaking Changes

Incoming packet registration signature has changed to:
```cs
delegate* void OnReceiveCallback(NetState state, SpanReader reader, int packetLength);

IncomingPackets.Register(int packetID, int length, bool ingame, OnReceiveCallback onReceive);
```

For example, an incoming packet handler signature would now look like this:
```cs
public static void SomeIncomingPacket(NetState state, SpanReader reader, int packetLength)
{
    // Parse the data
}
```

## Summary

Updates the network Pipe class to use a mirrored memory technique. This technique involves mapping the same physical memory to two contiguous virtual memory spaces so the byte buffer appears duplicated. This allows writing to a double-sized array to wrap around without the need for the `CircularBuffer` classes.

In practice this allows us to use `Span<byte>` as if the buffer was a regular array.


### Bug Fixes

- [X] Fixes bad fixed length string parsing
2023-10-09 00:57:53 -07:00
Kamron Batman
f2de2fbb77
fix: Cleans up entity persistence. Generalizes Mobiles/Items/Guilds (#1528)
### Summary
- [X] Fixed a bug where entity persistence was serialized out of order, causing world corruption.
- [X] Fixed LastSerialized not being utilized properly and dangling references still becoming an issue.
- [X] Added a new `GenericEntityPersistence<T>` type to encapsulate `ISerializable` serialization.
- [X] Removing the custom logic and moved Items, Mobiles, Guilds, and Accounts  to GenericEntityPersistence.
- [X] Changed serialization to use the singleton pattern to reduce calling methods from stored variables.
2023-10-01 22:10:47 -07:00
Kamron Batman
8389bfacfe
chore: Updates copyright (#1448) 2023-08-09 09:09:26 -07:00
mdodkins
a9a2a89908
feat: Customize expansion and set maps on first boot (#1425) 2023-07-31 20:46:49 -07:00
Kamron Batman
f77dd91811
fix: Overhauls virtue system (#1376)
## MAJOR CHANGE (API BREAKING)

Moved the virtues to it's own system _VirtueSystem_. This should make it easier to extend or remove the virtue system. Virtues will be saved to a new folder called _Virtues_.

### Motivation

The motivation was also two-fold, performance/stability, and to fix bugs.

First, virtues is the second system (first is murders), that has a pre-world-save check on _every mobile in the game_ to atrophy virtue stats. This is taxing since it freexes the world and makes world saves take longer. Every mobile had Gain/Loss dates for each virtue, whether they needed them or not. Most players don't even use the virtue system, so this will increase performance considerably.

Second, when I tried to optimize/refactor the code, I found several bugs that needed to be fixed.

### Major API Changes

- [X] The properties on players related to virtues are gone. Use `pm.GetVirtues()?.<PropertyName>` instead.
- [X] Virtues were removed from non-player Mobiles.
- [X] `pm.JusticeProtectors` was removed. Use `JusticeVirtue.GetProtector()` or `JusticeVirtue.GetProtected()` instead.

### Screenshots

<img width="221" alt="Props-1" src="https://github.com/modernuo/ModernUO/assets/3953314/5c09cb83-b8d5-44a2-b899-a7ed7cd736ac">
<img width="220" alt="props-2" src="https://github.com/modernuo/ModernUO/assets/3953314/aeade4d3-8df0-47bd-955a-a864d0946cf7">
2023-07-19 21:43:47 -07:00
Kamron Batman
db4b01567f
fix: Fixes crash with antimacro code (#1415) 2023-06-23 17:10:47 -07:00
Kamron Batman
baed849f10
feat: Moves skills to json file (#1411) 2023-06-16 05:55:55 -07:00
Kamron Batman
734d20cbaf
fix: Overhauls antimacro system (#1403)
### Summary
- [X] Moves AntiMacro to it's own system.
- [X] Removes antimacro from PlayerMobile.
- [X] Adds `LastExpiration` to antimacro to easily clear out all antimacro tracking when a player logs out, or during world save.
- [X] Optimizes the code somewhat.
2023-05-19 16:32:51 -07:00
Kamron Batman
dda55889f6
fix: Fixes tick count calculcations (#1366) 2023-03-09 21:00:17 -08:00
Kamron Batman
d14e864c85
fix: Updates disguises and codegens tinkering items (#1353) 2023-02-25 12:01:06 -08:00
Kamron Batman
42012538bc
fix: Fixes crafter deserialize, cleans up bandages, and codegens misc items (#1350) 2023-02-25 00:54:12 -08:00
Kamron Batman
65c196a8ae
fix: Fixes Point2D ctor (#1340) 2023-02-13 23:28:23 -08:00
Kamron Batman
f24c6a08dd
fix: Fixes string interpolation in value string builder (#1339) 2023-02-13 23:09:50 -08:00