fix: fishing by era: deep water, serpents, SOS, big fish and magic fish (#2718)
Part of #2687, after #2709. One commit per section, in the same order. ### Failures, maps, bottles and colored nets A GM's cast fails about a quarter of the time in any water, from the fishing table's last row, and deep water is no harder than a river. Maps and bottles are 0.5% per roll from T2A on, and 1 net in 100 is colored in every era. This removes the last row, so a cast only fails its skill check. From UO:R a cast in deep water checks skill from 65 to 115, through a `Fishing.MutateResource` override. Publish 5, which "was known as the Renaissance Publish", made deep water harder: "because the difficulty level is higher, the rate of success for pulling up SoS bottles will be lower." [O3] From LBR maps and bottles come up more often and 1 net in 10 is colored, both from Publish 16, which came out in parts during LBR [O14]. | Change | Era | Source | |---|---|---| | No "nothing" row | All | #2687 found no source for it; "A prepatch, you never failed catching something at GM" [S15]; a GM succeeds every time in lakes and rivers [C1] | | Deep water: nothing below 65 skill | UO:R on | "The minimum required skill level to catch *anything* in deep water is 65." [S5–S7] | | Deep water: 10% at 70, 70% at GM | UO:R on | "Even at 70, it is only about a 10% chance of success in deep water." [S14]; 29% of casts fail before Publish 16 and 30% after [F1, F2]; 70% success at 100 offshore [C1] | | Maps (skill − 80) / 2400, bottles (skill − 80) / 1500 | LBR on | A bottle "about once per hour" until October 2002 [S1–S6], then "a special item (a net, a message in a bottle or a treasure map) about five times per hour" [S7]; bottles went from 0.4% of catches before Publish 16 [F1] to 1.7% after [F2] | | Colored nets: none, then 10% | LBR on | "With Publish 16, we got a nice surprise--colored special fish nets!" [F4]; "Any net created has a 10% chance of being colored." [F3] | - From LBR a GM's deep-water catches are 0.8% maps and 1.3% bottles. Chrome counted 0.9% and 1.3% [C1], the FCB 0.7% and 1.7% after Publish 16 [F2]. Nets and big fish stay at 0.5%, close to both counts. - At Stratics' 280 casts an hour [S1–S6], that is about one bottle an hour from UO:R to UOTD and five nets, maps or bottles an hour from LBR, the two rates Stratics gives. - The gain chance rises as the success chance falls, so above 65 a cast in deep water gains faster than one near land, Publish 5's "best method for gaining at high levels" [O3]. Below 65 it neither catches nor gains. - Chrome's table also has three kinds of water near land, with difficulties of 15, 35 and 55. No other source has them, so near land stays at 0–100. ### Deep water is at least 14 tiles from land `SpecialFishingNet.FullValidation` decides what counts as deep water: where a special fishing net works, where maps, bottles, nets and big fish can be caught, and from UO:R where a cast is harder. It checks the target and 20 points on its four diagonals, 5 to 25 tiles out. Nothing off those points is read, so a spot 8 tiles from shore can count as deep, while one with land 15 to 25 tiles away on a diagonal does not. The sources give one rule in every era: land at least 14 tiles away. This checks every land tile within 13 of the target. ModernUO has no server lines inside a map, so the only boundary is the map's edge, which counts as land as before. Only land tiles are read, so statics such as rocks are ignored. `SOS.FindLocation` had its own copy of the old check and now calls `FullValidation`, so wrecks follow the same rule. - 1999 to 2000: "which means you must be at least 14 tiles away from all land" [S1–S4] - March 2001: "14 tiles away from any land mass" [F5] - 2001 to 2002: "which means you must be at least 14 tiles away from all land and server lines" [S5–S7] - Today: "You need to be a minimum of 14 tiles from land or a server boundary to be in ‘deep water’." [O9] One guide from January 2000 says "16 tiles away from land" [S9]; every other source says 14. - In the area an SOS picks from on Felucca, 59% of spots pass the old check and 63% pass the new one; in Ilshenar's two sea regions, 16% and 30%. - The check reads up to 729 land tiles instead of 21: about 6 µs per check in a Release build, against under 0.1 µs before; a cast makes at most two. ### Sea serpents In ModernUO a sea serpent comes up from fishing only with a treasure map, a bottle or a net, which it carries. A quarter are deep sea serpents. It has no timer, and nothing makes it attack the fisherman first. This follows the notes of March 28, 1999 and Publish 4. A fished serpent attacks the fisherman at once. Five minutes after it surfaced it goes back to deep water, taking what it carries, unless someone is still fighting it: it took damage in the last two minutes and has not healed to full since, which is what ModernUO's damage entries record. From T2A, at 80 skill or more in deep water, 1% of casts also bring up a serpent that carries nothing, whether the cast catches something or not. 1 serpent in 10 is a deep sea serpent. | Change | Era | Source | |---|---|---| | Attacks the fisherman at once | All | "Sea Serpents will now immediately attack the fisherman that brought them from the deep." [O1] | | Goes back after 5 minutes unless fought | All | "Sea Serpents will return to deep water after 5 minutes if not attacked." [O1]; "will return to the depths after a brief period if they are not engaged" [S10] | | 1% of casts bring up an empty serpent | T2A on | "Fishermen at over 80 skill will have a chance to pull up a sea serpent regardless of whether they succeed or fail at fishing when in deep sea." [O2]; 1% at 80 or more, before the skill check [B1] | | 1 in 10 is a deep sea serpent | All | "A small percentage of Sea Serpents will be Deep-Sea Serpents." [O1]; about 10% [B1]; 9.8% and 10.8% of the serpents counted [F1, F2] | - Publish 4 gives no rate. The 1% comes from a post by Hance, a UO developer, in December 2000 [B1]; T2A uses it too, since it is the rule Publish 4 brought in (our inference). The FCB's counts agree: 1.76% of casts brought up a serpent and 55% of serpents carried nothing, so about 1% of casts brought up an empty one [F1] (our calculation). - Before Publish 4 serpents came up "on failure" [O1], and Stratics kept "if you are fishing with 80+ skill and you fail" from July 1999 to 2002 [S1–S7]. Publish 4 is the last rule in T2A, so it is the one used from T2A. - Hance also relays a side comment that the empty serpent cancels the rest of the cast [B1]. If it did, no cast could bring up two serpents, but the FCB saw two from one cast on 0.96% of serpents [F1], and Chrome caught empty serpents together with fish and footwear [C1]. So the cast goes on. - Hance's post also needs room in the backpack for a fish and fish left in the spot [B1]. A spot with no fish left already ends the cast before the roll, unless an SOS keeps the cast going (next section). A full backpack doesn't: ModernUO doesn't check for room before a cast, so neither does the serpent. - Serpents from a special fishing net are unchanged; Hance's post says nets don't follow its formula [B1]. ### The SOS chest In ModernUO, a fisherman carrying an SOS within 60 tiles of its spot brings up the chest on 1 catch in 8 and a shipwrecked item on the other 7. The SOS also lets a cast go on where the fish have run out. This makes the chest 1 catch in 4, in every era. From UO:R an SOS needs 65 skill, and below that the cast is an ordinary one. | Change | Era | Source | |---|---|---| | The chest on 1 catch in 4 | All | "You have a 25% chance of getting the chest and a 75% chance of getting something else with each cast." [F3]; "a 25% chance to fish up the actual treasure chest" [S7] | | An SOS needs 65 skill | UO:R on | 65 in the chest's row of Stratics' table: "The skills mentioned above are minimum skills needed to fish up the corresponding item." [S5–S7] | - No source gives a number before October 2002, or any for ModernUO's 1 in 8, so the 25% applies in every era. The other catches keep ModernUO's seven kinds of shipwrecked items, equally likely. Hanse's die splits them in three: "One roll is body parts; another roll is shells, barrel staves, globes, etc.; another roll is paintings, broken clocks, etc.; and another is the chest itself." [F3] - Stratics' guide of November 2000 has neither the chest's row nor the 65 for deep water [S4]. The May 2001 version, during Third Dawn, has both: "The minimum required skill level to catch *anything* in deep water is 65." [S5] The first section applies that from UO:R, after Publish 5 made deep water harder [O3], so the chest follows it (our inference). An SOS's spot is picked in deep water, but a cast within 60 tiles of it can be nearer land, so the 65 is checked on its own. - Below 65 there are no shipwrecked items either, because Hanse's die is rolled once you "can even attempt to get a treasure chest" [F3] (our reading). Before UO:R an SOS still works at any skill; the only period line on it is "You do not have to be GM Fisherman to actually fish up the treasure from a bottle, only to fish up A bottle." [S9] ### Fishing reveals from T2A ModernUO reveals a hidden fisherman from ML. The notes of March 28, 1999 already say "If you are hidden, fishing will now unhide you." [O1], so this reveals from T2A, at the same two points: the splash and the end of the cast. ### Big fish and the leviathan's artifact In ModernUO every big fish weighs 3 to 200 stones and gives max(16, weight) / 4 steaks, and the net thrower has a 1 in 4 chance at an artifact at any skill. | Change | Era | Source | |---|---|---| | Big fish weigh 100 stones | Before SE | "They weigh 100 stones each" [S5–S7]; Publish 28 "Added variable weight and fisherman's mark on big fish" [O6] | | A steak per 5 stones, at least 4 | SE on | "now its weight / 5 will determine number of fish steaks (minimum of 4)" [O7] | | The net thrower's own chance at an artifact: 1 in 4, only at GM | SE on | "Give the fabled net thrower (if a GM Fisherman) a 1 in 4 chance of getting a minor artifact (not modified by luck or damage)." [O6] | - Before SE a big fish keeps ModernUO's weight / 4 steaks, 25 for 100 stones: no source gives a number before Publish 29. - Publish 27 names only the attackers' chance: "Minor Artifacts will have a chance of spawning in each attacker's backpack after a paragon creature or a leviathan is slain." [O5] Publish 28 adds the thrower's roll [O6], so before SE there is none (our inference). The attackers' chance is unchanged. ### Magic fish From SE the prized, wondrous and truly rare fish give +1 for 12 seconds instead of +5 for a minute [C1]. A Stratics FAQ of January 5, 2005 already says "The stat boost fish used to provide the person who ate it a +5 boost, but now it's only one or two points, and lasts only a short while." [S16] - Stratics still gives +5 in December 2002 [S7] and no note dates the change. [S16], during SE, is the earliest source with the new values, so the eras before SE keep +5 and ModernUO's minute (our inference). - Today's guide gives "Adds 8 – 12% to your Dexterity for 150 seconds when eaten" [O9]. No note dates that change either, so it is left out. ### The white pearl at an SOS's spot From ML the white pearl is a bonus on top of the catch, but it went through `Fishing.Construct`'s SOS branch: at an SOS's spot the fisherman read "You have found a white pearl!" and got a shipwrecked item or the chest, a second SOS roll in the same cast. The pearl now skips that branch. The keys are #2687's, plus: - [O14] uo.com, the 2002 publishes: Publish 16 in parts on April 23, July 23, September 20 and December 2, 2002. https://uo.com/wiki/ultima-online-wiki/technical/previous-publishes/2002-2/ - [S14] Stratics fishing board, FAQ 1.2 "How do I train fishing?", January 5, 2005. https://web.archive.org/web/20050410171430/http://boards.stratics.com/php-bin/uo/showthreaded.php?Cat=&Board=uofisherman&Number=5622892 - [S15] Stratics fishing board, a post on Publish 5's SOS change, April 25, 2000. https://web.archive.org/web/20000511000424/http://boards.stratics.com:80/cgi-bin/forums/showflat.pl?Cat=21&Board=uofisherman&Number=144300&page=0&view=collapsed&sb=5 - [S16] The FAQ of [S14], 1.4 "What's with the horned leather and scales? (Resources)", January 5, 2005, in the FAQ's flat view. https://web.archive.org/web/20050410171356/http://boards.stratics.com/php-bin/uo/showflat.php?Cat=&Number=5622877&page=0&view=collapsed&sb=5&o=&fpart=1 - [F1] The Fishin' Statistician, 11,101 casts from August 2001 to April 2002, before Publish 16. Skill and water not stated; most likely GM and mostly deep water, since the counts include big fish and serpents. https://web.archive.org/web/20020609120859/http://www.thefcb.com:80/novellettes/stats.html - [F2] The same page, 7,371 casts from July 2002 to February 2003, after Publish 16, with nets, maps and bottles counted too. https://web.archive.org/web/20030216074120/http://www.thefcb.com:80/novellettes/stats.html - [F3] The FCB's interview with Hanse, an OSI designer, October 21, 2002. https://web.archive.org/web/20021104194424/http://www.thefcb.com:80/Hanse.htm - [F4] The FCB's encyclopaedia, colored nets, last modified July 13, 2002. https://web.archive.org/web/20020715111230/http://www.thefcb.com:80/encyclopaedia/colornets.html - [F5] The FCB's "Illustrated Treatise on Deep Water Defined", by Captain Pickles and Mason, last modified March 20, 2001. https://web.archive.org/web/20010419135823/http://www.thefcb.com:80/novellettes/deep-water.html - [B1] Brikan's skill guide, which quotes a post on Origin's boards by Hance, a UO developer, on December 20, 2000; most likely Hanse, the OSI designer the FCB interviewed in 2002. Page last modified February 3, 2007. https://web.archive.org/web/20070715201811/http://www.jgnn.com:80/uo/bk/2skill/skill.htm - [C1] Chrome's fishing page on OSI's Yamato shard, captured November 25, 2007: 5,000 offshore catches at GM, a table of success by water and what each magic fish does. https://web.archive.org/web/20071125144104/http://www.geocities.co.jp:80/Playtown-Yoyo/4812/fishing02.html
This commit is contained in:
parent
410a964789
commit
b2c9b18ca1
7 changed files with 883 additions and 249 deletions
|
|
@ -12,12 +12,6 @@ public partial class SOS : Item
|
|||
// By default let's use the old gump, because we can.
|
||||
private static bool UseNewMessages = false;
|
||||
|
||||
private static int[] WaterTiles =
|
||||
{
|
||||
0x00A8, 0x00AB,
|
||||
0x0136, 0x0137
|
||||
};
|
||||
|
||||
private static Rectangle2D[] BritRegions = { new(0, 0, 5120, 4096) };
|
||||
|
||||
private static Rectangle2D[] IlshRegions =
|
||||
|
|
@ -179,34 +173,7 @@ public partial class SOS : Item
|
|||
var x = Utility.Random(reg.X, reg.Width);
|
||||
var y = Utility.Random(reg.Y, reg.Height);
|
||||
|
||||
if (!ValidateDeepWater(map, x, y))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var valid = true;
|
||||
|
||||
for (int j = 1, offset = 5; valid && j <= 5; ++j, offset += 5)
|
||||
{
|
||||
if (!ValidateDeepWater(map, x + offset, y + offset))
|
||||
{
|
||||
valid = false;
|
||||
}
|
||||
else if (!ValidateDeepWater(map, x + offset, y - offset))
|
||||
{
|
||||
valid = false;
|
||||
}
|
||||
else if (!ValidateDeepWater(map, x - offset, y + offset))
|
||||
{
|
||||
valid = false;
|
||||
}
|
||||
else if (!ValidateDeepWater(map, x - offset, y - offset))
|
||||
{
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (valid)
|
||||
if (SpecialFishingNet.FullValidation(map, x, y))
|
||||
{
|
||||
return new Point3D(x, y, 0);
|
||||
}
|
||||
|
|
@ -215,19 +182,6 @@ public partial class SOS : Item
|
|||
return Point3D.Zero;
|
||||
}
|
||||
|
||||
private static bool ValidateDeepWater(Map map, int x, int y)
|
||||
{
|
||||
var tileID = map.Tiles.GetLandTile(x, y).ID;
|
||||
var water = false;
|
||||
|
||||
for (var i = 0; !water && i < WaterTiles.Length; i += 2)
|
||||
{
|
||||
water = tileID >= WaterTiles[i] && tileID <= WaterTiles[i + 1];
|
||||
}
|
||||
|
||||
return water;
|
||||
}
|
||||
|
||||
private class MessageGump : StaticGump<MessageGump>
|
||||
{
|
||||
private readonly string _fmt;
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ namespace Server.Items;
|
|||
[SerializationGenerator(0, false)]
|
||||
public partial class SpecialFishingNet : Item
|
||||
{
|
||||
private static int[] _hues =
|
||||
{
|
||||
private static readonly int[] _hues =
|
||||
[
|
||||
0x09B,
|
||||
0x0CD,
|
||||
0x0D3,
|
||||
|
|
@ -26,25 +26,19 @@ public partial class SpecialFishingNet : Item
|
|||
0x492,
|
||||
0x4B5,
|
||||
0x8AA
|
||||
};
|
||||
];
|
||||
|
||||
private static int[] _waterTiles =
|
||||
{
|
||||
0x00A8, 0x00AB,
|
||||
0x0136, 0x0137
|
||||
};
|
||||
private static readonly int[] _waterTiles = [0x00A8, 0x00AB, 0x0136, 0x0137 ];
|
||||
|
||||
private static int[] _shallowWaterTiles =
|
||||
{
|
||||
0x1797, 0x179C
|
||||
};
|
||||
private static readonly int[] _shallowWaterTiles = [0x1797, 0x179C];
|
||||
|
||||
[SerializableField(0)]
|
||||
[SerializedCommandProperty(AccessLevel.GameMaster)]
|
||||
private bool _inUse;
|
||||
|
||||
[Constructible]
|
||||
public SpecialFishingNet() : base(0x0DCA) => Hue = Utility.RandomDouble() < 0.01 ? _hues.RandomElement() : 0x8A0;
|
||||
public SpecialFishingNet() : base(0x0DCA) =>
|
||||
Hue = Core.LBR && Utility.RandomDouble() < 0.1 ? _hues.RandomElement() : 0x8A0;
|
||||
|
||||
public override double DefaultWeight => 1.0;
|
||||
|
||||
|
|
@ -322,31 +316,15 @@ public partial class SpecialFishingNet : Item
|
|||
|
||||
public static bool FullValidation(Map map, int x, int y)
|
||||
{
|
||||
if (!ValidateDeepWater(map, x, y))
|
||||
// Every tile closer than 14 must be water, so land and the edge of the map are at least 14 tiles away.
|
||||
for (var ty = y - 13; ty <= y + 13; ++ty)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int j = 1, offset = 5; j <= 5; ++j, offset += 5)
|
||||
{
|
||||
if (!ValidateDeepWater(map, x + offset, y + offset))
|
||||
for (var tx = x - 13; tx <= x + 13; ++tx)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ValidateDeepWater(map, x + offset, y - offset))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ValidateDeepWater(map, x - offset, y + offset))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ValidateDeepWater(map, x - offset, y - offset))
|
||||
{
|
||||
return false;
|
||||
if (!ValidateDeepWater(map, tx, ty))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue