ModernUO/Scripts/Engines/Harvest/Fishing.cs
asayre 2ad37d54aa Lots of fixes, changes, rewrites of various things, including but not limited to:
Logging of staff crafting items,
Fixes for the OSI client changes
The potion stacking stuff
BaseWeapon fix, so that damage increase things don't multiply themselves.
admin gump fixes for Firewall
Various display tweaks for weight
SoS no longer spawn in Tokuno
Hiryu hues happified to OSI standards
staff now see alliance chat correctly
Play barkeeper text increased per OSI
Various other OSI skill requirement changes
Various unimplemented features of the SE moves
EventSink for when the client version is received from client.
Client validation moved out of the core.
Client version validation now has options to ignore/kick/warn/annoy.  Automagically tries to detect current client.
Reverted the delayeddamagecontext back to OSI standards.
Can no longer use bags of sending in jail.

MagerySpell implemented. Now only Magery spells have a circle, and various other properties of 'em.
TransformationSpellHelper now implemented.  Things moved around for this.
Spells now need a Timespan for the cast delay, instead of arbitrarily based on Circle.  Circle doesn't make sense for non-Magery spells!
Alot of the spellweaving spells added to OSI standards.
2007-05-26 03:12:41 +00:00

531 lines
No EOL
14 KiB
C#

using System;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Engines.Quests;
using Server.Engines.Quests.Collector;
using System.Collections.Generic;
namespace Server.Engines.Harvest
{
public class Fishing : HarvestSystem
{
private static Fishing m_System;
public static Fishing System
{
get
{
if ( m_System == null )
m_System = new Fishing();
return m_System;
}
}
private HarvestDefinition m_Definition;
public HarvestDefinition Definition
{
get{ return m_Definition; }
}
private Fishing()
{
HarvestResource[] res;
HarvestVein[] veins;
#region Fishing
HarvestDefinition fish = new HarvestDefinition();
// Resource banks are every 8x8 tiles
fish.BankWidth = 8;
fish.BankHeight = 8;
// Every bank holds from 5 to 15 fish
fish.MinTotal = 5;
fish.MaxTotal = 15;
// A resource bank will respawn its content every 10 to 20 minutes
fish.MinRespawn = TimeSpan.FromMinutes( 10.0 );
fish.MaxRespawn = TimeSpan.FromMinutes( 20.0 );
// Skill checking is done on the Fishing skill
fish.Skill = SkillName.Fishing;
// Set the list of harvestable tiles
fish.Tiles = m_WaterTiles;
fish.RangedTiles = true;
// Players must be within 4 tiles to harvest
fish.MaxRange = 4;
// One fish per harvest action
fish.ConsumedPerHarvest = 1;
fish.ConsumedPerFeluccaHarvest = 1;
// The fishing
fish.EffectActions = new int[]{ 12 };
fish.EffectSounds = new int[0];
fish.EffectCounts = new int[]{ 1 };
fish.EffectDelay = TimeSpan.Zero;
fish.EffectSoundDelay = TimeSpan.FromSeconds( 8.0 );
fish.NoResourcesMessage = 503172; // The fish don't seem to be biting here.
fish.FailMessage = 503171; // You fish a while, but fail to catch anything.
fish.TimedOutOfRangeMessage = 500976; // You need to be closer to the water to fish!
fish.OutOfRangeMessage = 500976; // You need to be closer to the water to fish!
fish.PackFullMessage = 503176; // You do not have room in your backpack for a fish.
fish.ToolBrokeMessage = 503174; // You broke your fishing pole.
res = new HarvestResource[]
{
new HarvestResource( 00.0, 00.0, 100.0, 1043297, typeof( Fish ) )
};
veins = new HarvestVein[]
{
new HarvestVein( 100.0, 0.0, res[0], null )
};
fish.Resources = res;
fish.Veins = veins;
m_Definition = fish;
Definitions.Add( fish );
#endregion
}
public override void OnConcurrentHarvest( Mobile from, Item tool, HarvestDefinition def, object toHarvest )
{
from.SendLocalizedMessage( 500972 ); // You are already fishing.
}
private class MutateEntry
{
public double m_ReqSkill, m_MinSkill, m_MaxSkill;
public bool m_DeepWater;
public Type[] m_Types;
public MutateEntry( double reqSkill, double minSkill, double maxSkill, bool deepWater, params Type[] types )
{
m_ReqSkill = reqSkill;
m_MinSkill = minSkill;
m_MaxSkill = maxSkill;
m_DeepWater = deepWater;
m_Types = types;
}
}
private static MutateEntry[] m_MutateTable = new MutateEntry[]
{
new MutateEntry( 80.0, 80.0, 4080.0, true, typeof( SpecialFishingNet ) ),
new MutateEntry( 80.0, 80.0, 4080.0, true, typeof( BigFish ) ),
new MutateEntry( 90.0, 80.0, 4080.0, true, typeof( TreasureMap ) ),
new MutateEntry( 100.0, 80.0, 4080.0, true, typeof( MessageInABottle ) ),
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 } )
};
public override bool SpecialHarvest( Mobile from, Item tool, HarvestDefinition def, Map map, Point3D loc )
{
PlayerMobile player = from as PlayerMobile;
if ( player != null )
{
QuestSystem qs = player.Quest;
if ( qs is CollectorQuest )
{
QuestObjective obj = qs.FindObjective( typeof( FishPearlsObjective ) );
if ( obj != null && !obj.Completed )
{
if ( Utility.RandomDouble() < 0.5 )
{
player.SendLocalizedMessage( 1055086, "", 0x59 ); // You pull a shellfish out of the water, and find a rainbow pearl inside of it.
obj.CurProgress++;
}
else
{
player.SendLocalizedMessage( 1055087, "", 0x2C ); // You pull a shellfish out of the water, but it doesn't have a rainbow pearl.
}
return true;
}
}
}
return false;
}
public override Type MutateType( Type type, Mobile from, Item tool, HarvestDefinition def, Map map, Point3D loc, HarvestResource resource )
{
bool deepWater = SpecialFishingNet.FullValidation( map, loc.X, loc.Y );
double skillBase = from.Skills[SkillName.Fishing].Base;
double skillValue = from.Skills[SkillName.Fishing].Value;
for ( int i = 0; i < m_MutateTable.Length; ++i )
{
MutateEntry entry = m_MutateTable[i];
if ( !deepWater && entry.m_DeepWater )
continue;
if ( skillBase >= entry.m_ReqSkill )
{
double chance = (skillValue - entry.m_MinSkill) / (entry.m_MaxSkill - entry.m_MinSkill);
if ( chance > Utility.RandomDouble() )
return entry.m_Types[Utility.Random( entry.m_Types.Length )];
}
}
return type;
}
private static Map SafeMap( Map map )
{
if ( map == null || map == Map.Internal )
return Map.Trammel;
return map;
}
public override bool CheckResources( Mobile from, Item tool, HarvestDefinition def, Map map, Point3D loc, bool timed )
{
Container pack = from.Backpack;
if ( pack != null )
{
List<SOS> messages = pack.FindItemsByType<SOS>();
for ( int i = 0; i < messages.Count; ++i )
{
SOS sos = messages[i];
if ( from.Map == sos.TargetMap && from.InRange( sos.TargetLocation, 60 ) )
return true;
}
}
return base.CheckResources( from, tool, def, map, loc, timed );
}
public override Item Construct( Type type, Mobile from )
{
if ( type == typeof( TreasureMap ) )
{
int level;
if ( from is PlayerMobile && ((PlayerMobile)from).Young && from.Map == Map.Trammel && TreasureMap.IsInHavenIsland( from ) )
level = 0;
else
level = 1;
return new TreasureMap( level, from.Map == Map.Felucca ? Map.Felucca : Map.Trammel );
}
else if ( type == typeof( MessageInABottle ) )
{
return new MessageInABottle( from.Map == Map.Felucca ? Map.Felucca : Map.Trammel );
}
Container pack = from.Backpack;
if ( pack != null )
{
List<SOS> messages = pack.FindItemsByType<SOS>();
for ( int i = 0; i < messages.Count; ++i )
{
SOS sos = messages[i];
if ( from.Map == sos.TargetMap && from.InRange( sos.TargetLocation, 60 ) )
{
Item preLoot = null;
switch ( Utility.Random( 7 ) )
{
case 0: // Body parts
{
int[] list = new int[]
{
0x1CDD, 0x1CE5, // arm
0x1CE0, 0x1CE8, // torso
0x1CE1, 0x1CE9, // head
0x1CE2, 0x1CEC // leg
};
preLoot = new ShipwreckedItem( Utility.RandomList( list ) );
break;
}
case 1: // Bone parts
{
int[] list = new int[]
{
0x1AE0, 0x1AE1, 0x1AE2, 0x1AE3, 0x1AE4, // skulls
0x1B09, 0x1B0A, 0x1B0B, 0x1B0C, 0x1B0D, 0x1B0E, 0x1B0F, 0x1B10, // bone piles
0x1B15, 0x1B16 // pelvis bones
};
preLoot = new ShipwreckedItem( Utility.RandomList( list ) );
break;
}
case 2: // Paintings and portraits
{
preLoot = new ShipwreckedItem( Utility.Random( 0xE9F, 10 ) );
break;
}
case 3: // Pillows
{
preLoot = new ShipwreckedItem( Utility.Random( 0x13A4, 11 ) );
break;
}
case 4: // Shells
{
preLoot = new ShipwreckedItem( Utility.Random( 0xFC4, 9 ) );
break;
}
case 5: // Misc
{
int[] list = new int[]
{
0x1EB5, // unfinished barrel
0xA2A, // stool
0xC1F, // broken clock
0x1047, 0x1048, // globe
0x1EB1, 0x1EB2, 0x1EB3, 0x1EB4 // barrel staves
};
preLoot = new ShipwreckedItem( Utility.RandomList( list ) );
break;
}
}
if ( preLoot != null )
return preLoot;
LockableContainer chest;
if ( Utility.RandomBool() )
chest = new MetalGoldenChest();
else
chest = new WoodenChest();
if ( sos.IsAncient )
chest.Hue = 0x481;
TreasureMapChest.Fill( chest, Math.Max( 1, Math.Max( 4, sos.Level ) ) );
if ( sos.IsAncient )
chest.DropItem( new FabledFishingNet() );
else
chest.DropItem( new SpecialFishingNet() );
chest.Movable = true;
chest.Locked = false;
chest.TrapType = TrapType.None;
chest.TrapPower = 0;
chest.TrapLevel = 0;
sos.Delete();
return chest;
}
}
}
return base.Construct( type, from );
}
public override bool Give( Mobile m, Item item, bool placeAtFeet )
{
if ( item is TreasureMap || item is MessageInABottle || item is SpecialFishingNet )
{
BaseCreature serp;
if ( 0.25 > Utility.RandomDouble() )
serp = new DeepSeaSerpent();
else
serp = new SeaSerpent();
int x = m.X, y = m.Y;
Map map = m.Map;
for ( int i = 0; map != null && i < 20; ++i )
{
int tx = m.X - 10 + Utility.Random( 21 );
int ty = m.Y - 10 + Utility.Random( 21 );
Tile t = map.Tiles.GetLandTile( tx, ty );
if ( t.Z == -5 && ( (t.ID >= 0xA8 && t.ID <= 0xAB) || (t.ID >= 0x136 && t.ID <= 0x137) ) && !Spells.SpellHelper.CheckMulti( new Point3D( tx, ty, -5 ), map ) )
{
x = tx;
y = ty;
break;
}
}
serp.MoveToWorld( new Point3D( x, y, -5 ), map );
serp.Home = serp.Location;
serp.RangeHome = 10;
serp.PackItem( item );
m.SendLocalizedMessage( 503170 ); // Uh oh! That doesn't look like a fish!
return true; // we don't want to give the item to the player, it's on the serpent
}
if ( item is BigFish || item is WoodenChest || item is MetalGoldenChest )
placeAtFeet = true;
return base.Give( m, item, placeAtFeet );
}
public override void SendSuccessTo( Mobile from, Item item, HarvestResource resource )
{
if ( item is BigFish )
{
from.SendLocalizedMessage( 1042635 ); // Your fishing pole bends as you pull a big fish from the depths!
((BigFish)item).Fisher = from;
}
else if ( item is WoodenChest || item is MetalGoldenChest )
{
from.SendLocalizedMessage( 503175 ); // You pull up a heavy chest from the depths of the ocean!
}
else
{
int number;
string name;
if ( item is BaseMagicFish )
{
number = 1008124;
name = "a mess of small fish";
}
else if ( item is Fish )
{
number = 1008124;
name = "a fish";
}
else if ( item is BaseShoes )
{
number = 1008124;
name = item.ItemData.Name;
}
else if ( item is TreasureMap )
{
number = 1008125;
name = "a sodden piece of parchment";
}
else if ( item is MessageInABottle )
{
number = 1008125;
name = "a bottle, with a message in it";
}
else if ( item is SpecialFishingNet )
{
number = 1008125;
name = "a special fishing net"; // TODO: this is just a guess--what should it really be named?
}
else
{
number = 1043297;
if ( (item.ItemData.Flags & TileFlag.ArticleA) != 0 )
name = "a " + item.ItemData.Name;
else if ( (item.ItemData.Flags & TileFlag.ArticleAn) != 0 )
name = "an " + item.ItemData.Name;
else
name = item.ItemData.Name;
}
if ( number == 1043297 )
from.SendLocalizedMessage( number, name );
else
from.SendLocalizedMessage( number, true, name );
}
}
public override void OnHarvestStarted( Mobile from, Item tool, HarvestDefinition def, object toHarvest )
{
base.OnHarvestStarted( from, tool, def, toHarvest );
int tileID;
Map map;
Point3D loc;
if ( GetHarvestDetails( from, tool, toHarvest, out tileID, out map, out loc ) )
Timer.DelayCall( TimeSpan.FromSeconds( 1.5 ), new TimerStateCallback( Splash_Callback ), new object[]{ loc, map } );
}
private void Splash_Callback( object state )
{
object[] args = (object[])state;
Point3D loc = (Point3D)args[0];
Map map = (Map)args[1];
Effects.SendLocationEffect( loc, map, 0x352D, 16, 4 );
Effects.PlaySound( loc, map, 0x364 );
}
public override object GetLock( Mobile from, Item tool, HarvestDefinition def, object toHarvest )
{
return this;
}
public override bool BeginHarvesting( Mobile from, Item tool )
{
if ( !base.BeginHarvesting( from, tool ) )
return false;
from.SendLocalizedMessage( 500974 ); // What water do you want to fish in?
return true;
}
public override bool CheckHarvest( Mobile from, Item tool )
{
if ( !base.CheckHarvest( from, tool ) )
return false;
if ( from.Mounted )
{
from.SendLocalizedMessage( 500971 ); // You can't fish while riding!
return false;
}
return true;
}
public override bool CheckHarvest( Mobile from, Item tool, HarvestDefinition def, object toHarvest )
{
if ( !base.CheckHarvest( from, tool, def, toHarvest ) )
return false;
if ( from.Mounted )
{
from.SendLocalizedMessage( 500971 ); // You can't fish while riding!
return false;
}
return true;
}
private static int[] m_WaterTiles = new int[]
{
0x00A8, 0x00AB,
0x0136, 0x0137,
0x5797, 0x579C,
0x746E, 0x7485,
0x7490, 0x74AB,
0x74B5, 0x75D5
};
}
}