Fixes code according to modern code style. Fixes a few expression bugs.

This commit is contained in:
Kamron Batman 2018-09-15 09:58:51 -07:00
parent 89eea25e5f
commit 970fd563b2
3324 changed files with 441118 additions and 433755 deletions

View file

@ -2,28 +2,28 @@ using System;
namespace Server.Engines.Harvest
{
public class BonusHarvestResource
{
public Type Type { get; set; }
public class BonusHarvestResource
{
public BonusHarvestResource(double reqSkill, double chance, TextDefinition message, Type type)
{
ReqSkill = reqSkill;
public double ReqSkill { get; set; }
Chance = chance;
Type = type;
SuccessMessage = message;
}
public double Chance { get; set; }
public Type Type{ get; set; }
public TextDefinition SuccessMessage { get; }
public double ReqSkill{ get; set; }
public void SendSuccessTo( Mobile m )
{
TextDefinition.SendMessageTo( m, SuccessMessage );
}
public double Chance{ get; set; }
public BonusHarvestResource( double reqSkill, double chance, TextDefinition message, Type type )
{
ReqSkill = reqSkill;
public TextDefinition SuccessMessage{ get; }
Chance = chance;
Type = type;
SuccessMessage = message;
}
}
}
public void SendSuccessTo(Mobile m)
{
TextDefinition.SendMessageTo(m, SuccessMessage);
}
}
}

View file

@ -2,93 +2,90 @@ using System;
namespace Server.Engines.Harvest
{
public class HarvestBank
{
private int m_Current;
private int m_Maximum;
private DateTime m_NextRespawn;
private HarvestVein m_Vein, m_DefaultVein;
public class HarvestBank
{
private int m_Current;
private int m_Maximum;
private DateTime m_NextRespawn;
private HarvestVein m_Vein, m_DefaultVein;
public HarvestDefinition Definition { get; }
public HarvestBank(HarvestDefinition def, HarvestVein defaultVein)
{
m_Maximum = Utility.RandomMinMax(def.MinTotal, def.MaxTotal);
m_Current = m_Maximum;
m_DefaultVein = defaultVein;
m_Vein = m_DefaultVein;
public int Current
{
get
{
CheckRespawn();
return m_Current;
}
}
Definition = def;
}
public HarvestVein Vein
{
get
{
CheckRespawn();
return m_Vein;
}
set => m_Vein = value;
}
public HarvestDefinition Definition{ get; }
public HarvestVein DefaultVein
{
get
{
CheckRespawn();
return m_DefaultVein;
}
}
public int Current
{
get
{
CheckRespawn();
return m_Current;
}
}
public void CheckRespawn()
{
if ( m_Current == m_Maximum || m_NextRespawn > DateTime.UtcNow )
return;
public HarvestVein Vein
{
get
{
CheckRespawn();
return m_Vein;
}
set => m_Vein = value;
}
m_Current = m_Maximum;
public HarvestVein DefaultVein
{
get
{
CheckRespawn();
return m_DefaultVein;
}
}
if ( Definition.RandomizeVeins )
{
m_DefaultVein = Definition.GetVeinFrom( Utility.RandomDouble() );
}
public void CheckRespawn()
{
if (m_Current == m_Maximum || m_NextRespawn > DateTime.UtcNow)
return;
m_Vein = m_DefaultVein;
}
m_Current = m_Maximum;
public void Consume( int amount, Mobile from )
{
CheckRespawn();
if (Definition.RandomizeVeins) m_DefaultVein = Definition.GetVeinFrom(Utility.RandomDouble());
if ( m_Current == m_Maximum )
{
double min = Definition.MinRespawn.TotalMinutes;
double max = Definition.MaxRespawn.TotalMinutes;
double rnd = Utility.RandomDouble();
m_Vein = m_DefaultVein;
}
m_Current = m_Maximum - amount;
public void Consume(int amount, Mobile from)
{
CheckRespawn();
double minutes = min + (rnd * (max - min));
if ( Definition.RaceBonus && from.Race == Race.Elf ) //def.RaceBonus = Core.ML
minutes *= .75; //25% off the time.
if (m_Current == m_Maximum)
{
double min = Definition.MinRespawn.TotalMinutes;
double max = Definition.MaxRespawn.TotalMinutes;
double rnd = Utility.RandomDouble();
m_NextRespawn = DateTime.UtcNow + TimeSpan.FromMinutes( minutes );
}
else
{
m_Current -= amount;
}
m_Current = m_Maximum - amount;
if ( m_Current < 0 )
m_Current = 0;
}
double minutes = min + rnd * (max - min);
if (Definition.RaceBonus && from.Race == Race.Elf) //def.RaceBonus = Core.ML
minutes *= .75; //25% off the time.
public HarvestBank( HarvestDefinition def, HarvestVein defaultVein )
{
m_Maximum = Utility.RandomMinMax( def.MinTotal, def.MaxTotal );
m_Current = m_Maximum;
m_DefaultVein = defaultVein;
m_Vein = m_DefaultVein;
m_NextRespawn = DateTime.UtcNow + TimeSpan.FromMinutes(minutes);
}
else
{
m_Current -= amount;
}
Definition = def;
}
}
if (m_Current < 0)
m_Current = 0;
}
}
}

View file

@ -3,179 +3,179 @@ using System.Collections.Generic;
namespace Server.Engines.Harvest
{
public class HarvestDefinition
{
public int BankWidth { get; set; }
public class HarvestDefinition
{
public HarvestDefinition()
{
Banks = new Dictionary<Map, Dictionary<Point2D, HarvestBank>>();
}
public int BankHeight { get; set; }
public int BankWidth{ get; set; }
public int MinTotal { get; set; }
public int BankHeight{ get; set; }
public int MaxTotal { get; set; }
public int MinTotal{ get; set; }
public int[] Tiles { get; set; }
public int MaxTotal{ get; set; }
public bool RangedTiles { get; set; }
public int[] Tiles{ get; set; }
public TimeSpan MinRespawn { get; set; }
public bool RangedTiles{ get; set; }
public TimeSpan MaxRespawn { get; set; }
public TimeSpan MinRespawn{ get; set; }
public int MaxRange { get; set; }
public TimeSpan MaxRespawn{ get; set; }
public int ConsumedPerHarvest { get; set; }
public int MaxRange{ get; set; }
public int ConsumedPerFeluccaHarvest { get; set; }
public int ConsumedPerHarvest{ get; set; }
public bool PlaceAtFeetIfFull { get; set; }
public int ConsumedPerFeluccaHarvest{ get; set; }
public SkillName Skill { get; set; }
public bool PlaceAtFeetIfFull{ get; set; }
public int[] EffectActions { get; set; }
public SkillName Skill{ get; set; }
public int[] EffectCounts { get; set; }
public int[] EffectActions{ get; set; }
public int[] EffectSounds { get; set; }
public int[] EffectCounts{ get; set; }
public TimeSpan EffectSoundDelay { get; set; }
public int[] EffectSounds{ get; set; }
public TimeSpan EffectDelay { get; set; }
public TimeSpan EffectSoundDelay{ get; set; }
public object NoResourcesMessage { get; set; }
public TimeSpan EffectDelay{ get; set; }
public object OutOfRangeMessage { get; set; }
public object NoResourcesMessage{ get; set; }
public object TimedOutOfRangeMessage { get; set; }
public object OutOfRangeMessage{ get; set; }
public object DoubleHarvestMessage { get; set; }
public object TimedOutOfRangeMessage{ get; set; }
public object FailMessage { get; set; }
public object DoubleHarvestMessage{ get; set; }
public object PackFullMessage { get; set; }
public object FailMessage{ get; set; }
public object ToolBrokeMessage { get; set; }
public object PackFullMessage{ get; set; }
public HarvestResource[] Resources { get; set; }
public object ToolBrokeMessage{ get; set; }
public HarvestVein[] Veins { get; set; }
public HarvestResource[] Resources{ get; set; }
public BonusHarvestResource[] BonusResources { get; set; }
public HarvestVein[] Veins{ get; set; }
public bool RaceBonus { get; set; }
public BonusHarvestResource[] BonusResources{ get; set; }
public bool RandomizeVeins { get; set; }
public bool RaceBonus{ get; set; }
public Dictionary<Map, Dictionary<Point2D, HarvestBank>> Banks { get; set; }
public bool RandomizeVeins{ get; set; }
public void SendMessageTo( Mobile from, object message )
{
if ( message is int messageInt )
from.SendLocalizedMessage( messageInt );
else
from.SendMessage( message.ToString() );
}
public Dictionary<Map, Dictionary<Point2D, HarvestBank>> Banks{ get; set; }
public HarvestBank GetBank( Map map, int x, int y )
{
if ( map == null || map == Map.Internal )
return null;
public void SendMessageTo(Mobile from, object message)
{
if (message is int messageInt)
from.SendLocalizedMessage(messageInt);
else
from.SendMessage(message.ToString());
}
x /= BankWidth;
y /= BankHeight;
public HarvestBank GetBank(Map map, int x, int y)
{
if (map == null || map == Map.Internal)
return null;
Banks.TryGetValue( map, out Dictionary<Point2D, HarvestBank> banks );
x /= BankWidth;
y /= BankHeight;
if ( banks == null )
Banks[map] = banks = new Dictionary<Point2D, HarvestBank>();
Banks.TryGetValue(map, out Dictionary<Point2D, HarvestBank> banks);
Point2D key = new Point2D( x, y );
banks.TryGetValue( key, out HarvestBank bank );
if (banks == null)
Banks[map] = banks = new Dictionary<Point2D, HarvestBank>();
if ( bank == null )
banks[key] = bank = new HarvestBank( this, GetVeinAt( map, x, y ) );
Point2D key = new Point2D(x, y);
banks.TryGetValue(key, out HarvestBank bank);
return bank;
}
if (bank == null)
banks[key] = bank = new HarvestBank(this, GetVeinAt(map, x, y));
public HarvestVein GetVeinAt( Map map, int x, int y )
{
if ( Veins.Length == 1 )
return Veins[0];
return bank;
}
double randomValue;
public HarvestVein GetVeinAt(Map map, int x, int y)
{
if (Veins.Length == 1)
return Veins[0];
if ( RandomizeVeins )
{
randomValue = Utility.RandomDouble();
}
else
{
Random random = new Random( ( x * 17 ) + ( y * 11 ) + ( map.MapID * 3 ) );
randomValue = random.NextDouble();
}
double randomValue;
return GetVeinFrom( randomValue );
}
if (RandomizeVeins)
{
randomValue = Utility.RandomDouble();
}
else
{
Random random = new Random(x * 17 + y * 11 + map.MapID * 3);
randomValue = random.NextDouble();
}
public HarvestVein GetVeinFrom( double randomValue )
{
if ( Veins.Length == 1 )
return Veins[0];
return GetVeinFrom(randomValue);
}
randomValue *= 100;
public HarvestVein GetVeinFrom(double randomValue)
{
if (Veins.Length == 1)
return Veins[0];
for ( int i = 0; i < Veins.Length; ++i )
{
if ( randomValue <= Veins[i].VeinChance )
return Veins[i];
randomValue *= 100;
randomValue -= Veins[i].VeinChance;
}
for (int i = 0; i < Veins.Length; ++i)
{
if (randomValue <= Veins[i].VeinChance)
return Veins[i];
return null;
}
randomValue -= Veins[i].VeinChance;
}
public BonusHarvestResource GetBonusResource()
{
if ( BonusResources == null )
return null;
return null;
}
double randomValue = Utility.RandomDouble() * 100;
public BonusHarvestResource GetBonusResource()
{
if (BonusResources == null)
return null;
for ( int i = 0; i < BonusResources.Length; ++i )
{
if ( randomValue <= BonusResources[i].Chance )
return BonusResources[i];
double randomValue = Utility.RandomDouble() * 100;
randomValue -= BonusResources[i].Chance;
}
for (int i = 0; i < BonusResources.Length; ++i)
{
if (randomValue <= BonusResources[i].Chance)
return BonusResources[i];
return null;
}
randomValue -= BonusResources[i].Chance;
}
public HarvestDefinition()
{
Banks = new Dictionary<Map, Dictionary<Point2D, HarvestBank>>();
}
return null;
}
public bool Validate( int tileID )
{
if ( RangedTiles )
{
bool contains = false;
public bool Validate(int tileID)
{
if (RangedTiles)
{
bool contains = false;
for ( int i = 0; !contains && i < Tiles.Length; i += 2 )
contains = ( tileID >= Tiles[i] && tileID <= Tiles[i + 1] );
for (int i = 0; !contains && i < Tiles.Length; i += 2)
contains = tileID >= Tiles[i] && tileID <= Tiles[i + 1];
return contains;
}
return contains;
}
int dist = -1;
int dist = -1;
for ( int i = 0; dist < 0 && i < Tiles.Length; ++i )
dist = ( Tiles[i] - tileID );
for (int i = 0; dist < 0 && i < Tiles.Length; ++i)
dist = Tiles[i] - tileID;
return ( dist == 0 );
}
}
}
return dist == 0;
}
}
}

View file

@ -2,33 +2,33 @@ using System;
namespace Server.Engines.Harvest
{
public class HarvestResource
{
public Type[] Types { get; set; }
public class HarvestResource
{
public HarvestResource(double reqSkill, double minSkill, double maxSkill, object message, params Type[] types)
{
ReqSkill = reqSkill;
MinSkill = minSkill;
MaxSkill = maxSkill;
Types = types;
SuccessMessage = message;
}
public double ReqSkill { get; set; }
public Type[] Types{ get; set; }
public double MinSkill { get; set; }
public double ReqSkill{ get; set; }
public double MaxSkill { get; set; }
public double MinSkill{ get; set; }
public object SuccessMessage { get; }
public double MaxSkill{ get; set; }
public void SendSuccessTo( Mobile m )
{
if ( SuccessMessage is int messageInt )
m.SendLocalizedMessage( messageInt );
else
m.SendMessage( SuccessMessage.ToString() );
}
public object SuccessMessage{ get; }
public HarvestResource( double reqSkill, double minSkill, double maxSkill, object message, params Type[] types )
{
ReqSkill = reqSkill;
MinSkill = minSkill;
MaxSkill = maxSkill;
Types = types;
SuccessMessage = message;
}
}
}
public void SendSuccessTo(Mobile m)
{
if (SuccessMessage is int messageInt)
m.SendLocalizedMessage(messageInt);
else
m.SendMessage(SuccessMessage.ToString());
}
}
}

View file

@ -1,31 +1,32 @@
namespace Server.Engines.Harvest
{
public class HarvestSoundTimer : Timer
{
private Mobile m_From;
private Item m_Tool;
private HarvestSystem m_System;
private HarvestDefinition m_Definition;
private object m_ToHarvest, m_Locked;
private bool m_Last;
public class HarvestSoundTimer : Timer
{
private HarvestDefinition m_Definition;
private Mobile m_From;
private bool m_Last;
private HarvestSystem m_System;
private object m_ToHarvest, m_Locked;
private Item m_Tool;
public HarvestSoundTimer( Mobile from, Item tool, HarvestSystem system, HarvestDefinition def, object toHarvest, object locked, bool last ) : base( def.EffectSoundDelay )
{
m_From = from;
m_Tool = tool;
m_System = system;
m_Definition = def;
m_ToHarvest = toHarvest;
m_Locked = locked;
m_Last = last;
}
public HarvestSoundTimer(Mobile from, Item tool, HarvestSystem system, HarvestDefinition def, object toHarvest,
object locked, bool last) : base(def.EffectSoundDelay)
{
m_From = from;
m_Tool = tool;
m_System = system;
m_Definition = def;
m_ToHarvest = toHarvest;
m_Locked = locked;
m_Last = last;
}
protected override void OnTick()
{
m_System.DoHarvestingSound( m_From, m_Tool, m_Definition, m_ToHarvest );
protected override void OnTick()
{
m_System.DoHarvestingSound(m_From, m_Tool, m_Definition, m_ToHarvest);
if ( m_Last )
m_System.FinishHarvesting( m_From, m_Tool, m_Definition, m_ToHarvest, m_Locked );
}
}
if (m_Last)
m_System.FinishHarvesting(m_From, m_Tool, m_Definition, m_ToHarvest, m_Locked);
}
}
}

View file

@ -5,492 +5,502 @@ using Server.Targeting;
namespace Server.Engines.Harvest
{
public abstract class HarvestSystem
{
public List<HarvestDefinition> Definitions { get; }
public HarvestSystem()
{
Definitions = new List<HarvestDefinition>();
}
public virtual bool CheckTool( Mobile from, Item tool )
{
bool wornOut = ( tool == null || tool.Deleted || (tool is IUsesRemaining remaining && remaining.UsesRemaining <= 0) );
if ( wornOut )
from.SendLocalizedMessage( 1044038 ); // You have worn out your tool!
return !wornOut;
}
public virtual bool CheckHarvest( Mobile from, Item tool )
{
return CheckTool( from, tool );
}
public virtual bool CheckHarvest( Mobile from, Item tool, HarvestDefinition def, object toHarvest )
{
return CheckTool( from, tool );
}
public virtual bool CheckRange( Mobile from, Item tool, HarvestDefinition def, Map map, Point3D loc, bool timed )
{
bool inRange = ( from.Map == map && from.InRange( loc, def.MaxRange ) );
if ( !inRange )
def.SendMessageTo( from, timed ? def.TimedOutOfRangeMessage : def.OutOfRangeMessage );
return inRange;
}
public abstract class HarvestSystem
{
public HarvestSystem()
{
Definitions = new List<HarvestDefinition>();
}
public List<HarvestDefinition> Definitions{ get; }
public virtual bool CheckTool(Mobile from, Item tool)
{
bool wornOut = tool == null || tool.Deleted || tool is IUsesRemaining remaining && remaining.UsesRemaining <= 0;
if (wornOut)
from.SendLocalizedMessage(1044038); // You have worn out your tool!
return !wornOut;
}
public virtual bool CheckHarvest(Mobile from, Item tool)
{
return CheckTool(from, tool);
}
public virtual bool CheckHarvest(Mobile from, Item tool, HarvestDefinition def, object toHarvest)
{
return CheckTool(from, tool);
}
public virtual bool CheckRange(Mobile from, Item tool, HarvestDefinition def, Map map, Point3D loc, bool timed)
{
bool inRange = from.Map == map && from.InRange(loc, def.MaxRange);
if (!inRange)
def.SendMessageTo(from, timed ? def.TimedOutOfRangeMessage : def.OutOfRangeMessage);
return inRange;
}
public virtual bool CheckResources( Mobile from, Item tool, HarvestDefinition def, Map map, Point3D loc, bool timed )
{
HarvestBank bank = def.GetBank( map, loc.X, loc.Y );
bool available = ( bank != null && bank.Current >= def.ConsumedPerHarvest );
public virtual bool CheckResources(Mobile from, Item tool, HarvestDefinition def, Map map, Point3D loc, bool timed)
{
HarvestBank bank = def.GetBank(map, loc.X, loc.Y);
bool available = bank != null && bank.Current >= def.ConsumedPerHarvest;
if ( !available )
def.SendMessageTo( from, timed ? def.DoubleHarvestMessage : def.NoResourcesMessage );
if (!available)
def.SendMessageTo(from, timed ? def.DoubleHarvestMessage : def.NoResourcesMessage);
return available;
}
return available;
}
public virtual void OnBadHarvestTarget( Mobile from, Item tool, object toHarvest )
{
}
public virtual void OnBadHarvestTarget(Mobile from, Item tool, object toHarvest)
{
}
public virtual object GetLock( Mobile from, Item tool, HarvestDefinition def, object toHarvest )
{
/* Here we prevent multiple harvesting.
*
* Some options:
* - 'return tool;' : This will allow the player to harvest more than once concurrently, but only if they use multiple tools. This seems to be as OSI.
* - 'return GetType();' : This will disallow multiple harvesting of the same type. That is, we couldn't mine more than once concurrently, but we could be both mining and lumberjacking.
* - 'return typeof( HarvestSystem );' : This will completely restrict concurrent harvesting.
*/
return tool;
}
public virtual void OnConcurrentHarvest( Mobile from, Item tool, HarvestDefinition def, object toHarvest )
{
}
public virtual void OnHarvestStarted( Mobile from, Item tool, HarvestDefinition def, object toHarvest )
{
}
public virtual bool BeginHarvesting( Mobile from, Item tool )
{
if ( !CheckHarvest( from, tool ) )
return false;
from.Target = new HarvestTarget( tool, this );
return true;
}
public virtual void FinishHarvesting( Mobile from, Item tool, HarvestDefinition def, object toHarvest, object locked )
{
from.EndAction( locked );
if ( !CheckHarvest( from, tool ) )
return;
int tileID;
Map map;
Point3D loc;
if ( !GetHarvestDetails( from, tool, toHarvest, out tileID, out map, out loc ) )
{
OnBadHarvestTarget( from, tool, toHarvest );
return;
}
if ( !def.Validate( tileID ) )
{
OnBadHarvestTarget( from, tool, toHarvest );
return;
}
if ( !CheckRange( from, tool, def, map, loc, true ) )
return;
if ( !CheckResources( from, tool, def, map, loc, true ) )
return;
if ( !CheckHarvest( from, tool, def, toHarvest ) )
return;
if ( SpecialHarvest( from, tool, def, map, loc ) )
return;
HarvestBank bank = def.GetBank( map, loc.X, loc.Y );
if ( bank == null )
return;
HarvestVein vein = bank.Vein;
if ( vein != null )
vein = MutateVein( from, tool, def, bank, toHarvest, vein );
if ( vein == null )
return;
HarvestResource primary = vein.PrimaryResource;
HarvestResource fallback = vein.FallbackResource;
HarvestResource resource = MutateResource( from, tool, def, map, loc, vein, primary, fallback );
double skillBase = from.Skills[def.Skill].Base;
double skillValue = from.Skills[def.Skill].Value;
Type type = null;
if ( skillBase >= resource.ReqSkill && from.CheckSkill( def.Skill, resource.MinSkill, resource.MaxSkill ) )
{
type = GetResourceType( from, tool, def, map, loc, resource );
if ( type != null )
type = MutateType( type, from, tool, def, map, loc, resource );
if ( type != null )
{
Item item = Construct( type, from );
if ( item == null )
{
type = null;
}
else
{
//The whole harvest system is kludgy and I'm sure this is just adding to it.
if ( item.Stackable )
{
int amount = def.ConsumedPerHarvest;
int feluccaAmount = def.ConsumedPerFeluccaHarvest;
int racialAmount = (int)Math.Ceiling( amount * 1.1 );
int feluccaRacialAmount = (int)Math.Ceiling( feluccaAmount * 1.1 );
bool eligableForRacialBonus = ( def.RaceBonus && from.Race == Race.Human );
bool inFelucca = (map == Map.Felucca);
if ( eligableForRacialBonus && inFelucca && bank.Current >= feluccaRacialAmount && 0.1 > Utility.RandomDouble() )
item.Amount = feluccaRacialAmount;
else if ( inFelucca && bank.Current >= feluccaAmount )
item.Amount = feluccaAmount;
else if ( eligableForRacialBonus && bank.Current >= racialAmount && 0.1 > Utility.RandomDouble() )
item.Amount = racialAmount;
else
item.Amount = amount;
}
bank.Consume( item.Amount, from );
if ( Give( from, item, def.PlaceAtFeetIfFull ) )
{
SendSuccessTo( from, item, resource );
}
else
{
SendPackFullTo( from, item, def, resource );
item.Delete();
}
BonusHarvestResource bonus = def.GetBonusResource();
if ( bonus != null && bonus.Type != null && skillBase >= bonus.ReqSkill )
{
Item bonusItem = Construct( bonus.Type, from );
if ( Give( from, bonusItem, true ) ) //Bonuses always allow placing at feet, even if pack is full irregrdless of def
{
bonus.SendSuccessTo( from );
}
else
{
item.Delete();
}
}
if ( tool is IUsesRemaining toolWithUses )
{
toolWithUses.ShowUsesRemaining = true;
if ( toolWithUses.UsesRemaining > 0 )
--toolWithUses.UsesRemaining;
if ( toolWithUses.UsesRemaining < 1 )
{
tool.Delete();
def.SendMessageTo( from, def.ToolBrokeMessage );
}
}
}
}
}
if ( type == null )
def.SendMessageTo( from, def.FailMessage );
OnHarvestFinished( from, tool, def, vein, bank, resource, toHarvest );
}
public virtual void OnHarvestFinished( Mobile from, Item tool, HarvestDefinition def, HarvestVein vein, HarvestBank bank, HarvestResource resource, object harvested )
{
}
public virtual bool SpecialHarvest( Mobile from, Item tool, HarvestDefinition def, Map map, Point3D loc )
{
return false;
}
public virtual Item Construct( Type type, Mobile from )
{
try{ return Activator.CreateInstance( type ) as Item; }
catch{ return null; }
}
public virtual HarvestVein MutateVein( Mobile from, Item tool, HarvestDefinition def, HarvestBank bank, object toHarvest, HarvestVein vein )
{
return vein;
}
public virtual void SendSuccessTo( Mobile from, Item item, HarvestResource resource )
{
resource.SendSuccessTo( from );
}
public virtual void SendPackFullTo( Mobile from, Item item, HarvestDefinition def, HarvestResource resource )
{
def.SendMessageTo( from, def.PackFullMessage );
}
public virtual bool Give( Mobile m, Item item, bool placeAtFeet )
{
if ( m.PlaceInBackpack( item ) )
return true;
if ( !placeAtFeet )
return false;
Map map = m.Map;
if ( map == null )
return false;
List<Item> atFeet = new List<Item>();
foreach ( Item obj in m.GetItemsInRange( 0 ) )
atFeet.Add( obj );
for ( int i = 0; i < atFeet.Count; ++i )
{
Item check = atFeet[i];
if ( check.StackWith( m, item, false ) )
return true;
}
item.MoveToWorld( m.Location, map );
return true;
}
public virtual Type MutateType( Type type, Mobile from, Item tool, HarvestDefinition def, Map map, Point3D loc, HarvestResource resource )
{
return from.Region.GetResource( type );
}
public virtual Type GetResourceType( Mobile from, Item tool, HarvestDefinition def, Map map, Point3D loc, HarvestResource resource )
{
if ( resource.Types.Length > 0 )
return resource.Types[Utility.Random( resource.Types.Length )];
return null;
}
public virtual HarvestResource MutateResource( Mobile from, Item tool, HarvestDefinition def, Map map, Point3D loc, HarvestVein vein, HarvestResource primary, HarvestResource fallback )
{
bool racialBonus = (def.RaceBonus && from.Race == Race.Elf );
if ( vein.ChanceToFallback > (Utility.RandomDouble() + (racialBonus ? .20 : 0)) )
return fallback;
double skillValue = from.Skills[def.Skill].Value;
if ( fallback != null && (skillValue < primary.ReqSkill || skillValue < primary.MinSkill) )
return fallback;
return primary;
}
public virtual bool OnHarvesting( Mobile from, Item tool, HarvestDefinition def, object toHarvest, object locked, bool last )
{
if ( !CheckHarvest( from, tool ) )
{
from.EndAction( locked );
return false;
}
int tileID;
Map map;
Point3D loc;
if ( !GetHarvestDetails( from, tool, toHarvest, out tileID, out map, out loc ) )
{
from.EndAction( locked );
OnBadHarvestTarget( from, tool, toHarvest );
return false;
}
if ( !def.Validate( tileID ) )
{
from.EndAction( locked );
OnBadHarvestTarget( from, tool, toHarvest );
return false;
}
if ( !CheckRange( from, tool, def, map, loc, true ) )
{
from.EndAction( locked );
return false;
}
if ( !CheckResources( from, tool, def, map, loc, true ) )
{
from.EndAction( locked );
return false;
}
if ( !CheckHarvest( from, tool, def, toHarvest ) )
{
from.EndAction( locked );
return false;
}
DoHarvestingEffect( from, tool, def, map, loc );
new HarvestSoundTimer( from, tool, this, def, toHarvest, locked, last ).Start();
return !last;
}
public virtual void DoHarvestingSound( Mobile from, Item tool, HarvestDefinition def, object toHarvest )
{
if ( def.EffectSounds.Length > 0 )
from.PlaySound( Utility.RandomList( def.EffectSounds ) );
}
public virtual void DoHarvestingEffect( Mobile from, Item tool, HarvestDefinition def, Map map, Point3D loc )
{
from.Direction = from.GetDirectionTo( loc );
if ( !from.Mounted )
from.Animate( Utility.RandomList( def.EffectActions ), 5, 1, true, false, 0 );
}
public virtual HarvestDefinition GetDefinition( int tileID )
{
HarvestDefinition def = null;
for ( int i = 0; def == null && i < Definitions.Count; ++i )
{
HarvestDefinition check = Definitions[i];
if ( check.Validate( tileID ) )
def = check;
}
return def;
}
public virtual void StartHarvesting( Mobile from, Item tool, object toHarvest )
{
if ( !CheckHarvest( from, tool ) )
return;
int tileID;
Map map;
Point3D loc;
if ( !GetHarvestDetails( from, tool, toHarvest, out tileID, out map, out loc ) )
{
OnBadHarvestTarget( from, tool, toHarvest );
return;
}
HarvestDefinition def = GetDefinition( tileID );
if ( def == null )
{
OnBadHarvestTarget( from, tool, toHarvest );
return;
}
if ( !CheckRange( from, tool, def, map, loc, false ) )
return;
if ( !CheckResources( from, tool, def, map, loc, false ) )
return;
if ( !CheckHarvest( from, tool, def, toHarvest ) )
return;
object toLock = GetLock( from, tool, def, toHarvest );
if ( !from.BeginAction( toLock ) )
{
OnConcurrentHarvest( from, tool, def, toHarvest );
return;
}
new HarvestTimer( from, tool, this, def, toHarvest, toLock ).Start();
OnHarvestStarted( from, tool, def, toHarvest );
}
public virtual bool GetHarvestDetails( Mobile from, Item tool, object toHarvest, out int tileID, out Map map, out Point3D loc )
{
if ( toHarvest is Static staticObj && !staticObj.Movable )
{
tileID = (staticObj.ItemID & 0x3FFF) | 0x4000;
map = staticObj.Map;
loc = staticObj.GetWorldLocation();
}
else if ( toHarvest is StaticTarget staticTarget )
{
tileID = (staticTarget.ItemID & 0x3FFF) | 0x4000;
map = from.Map;
loc = staticTarget.Location;
}
else if ( toHarvest is LandTarget landTarget )
{
tileID = landTarget.TileID;
map = from.Map;
loc = landTarget.Location;
}
else
{
tileID = 0;
map = null;
loc = Point3D.Zero;
return false;
}
return ( map != null && map != Map.Internal );
}
}
public virtual object GetLock(Mobile from, Item tool, HarvestDefinition def, object toHarvest)
{
/* Here we prevent multiple harvesting.
*
* Some options:
* - 'return tool;' : This will allow the player to harvest more than once concurrently, but only if they use multiple tools. This seems to be as OSI.
* - 'return GetType();' : This will disallow multiple harvesting of the same type. That is, we couldn't mine more than once concurrently, but we could be both mining and lumberjacking.
* - 'return typeof( HarvestSystem );' : This will completely restrict concurrent harvesting.
*/
return tool;
}
public virtual void OnConcurrentHarvest(Mobile from, Item tool, HarvestDefinition def, object toHarvest)
{
}
public virtual void OnHarvestStarted(Mobile from, Item tool, HarvestDefinition def, object toHarvest)
{
}
public virtual bool BeginHarvesting(Mobile from, Item tool)
{
if (!CheckHarvest(from, tool))
return false;
from.Target = new HarvestTarget(tool, this);
return true;
}
public virtual void FinishHarvesting(Mobile from, Item tool, HarvestDefinition def, object toHarvest, object locked)
{
from.EndAction(locked);
if (!CheckHarvest(from, tool))
return;
int tileID;
Map map;
Point3D loc;
if (!GetHarvestDetails(from, tool, toHarvest, out tileID, out map, out loc))
{
OnBadHarvestTarget(from, tool, toHarvest);
return;
}
if (!def.Validate(tileID))
{
OnBadHarvestTarget(from, tool, toHarvest);
return;
}
if (!CheckRange(from, tool, def, map, loc, true))
return;
if (!CheckResources(from, tool, def, map, loc, true))
return;
if (!CheckHarvest(from, tool, def, toHarvest))
return;
if (SpecialHarvest(from, tool, def, map, loc))
return;
HarvestBank bank = def.GetBank(map, loc.X, loc.Y);
if (bank == null)
return;
HarvestVein vein = bank.Vein;
if (vein != null)
vein = MutateVein(from, tool, def, bank, toHarvest, vein);
if (vein == null)
return;
HarvestResource primary = vein.PrimaryResource;
HarvestResource fallback = vein.FallbackResource;
HarvestResource resource = MutateResource(from, tool, def, map, loc, vein, primary, fallback);
double skillBase = from.Skills[def.Skill].Base;
double skillValue = from.Skills[def.Skill].Value;
Type type = null;
if (skillBase >= resource.ReqSkill && from.CheckSkill(def.Skill, resource.MinSkill, resource.MaxSkill))
{
type = GetResourceType(from, tool, def, map, loc, resource);
if (type != null)
type = MutateType(type, from, tool, def, map, loc, resource);
if (type != null)
{
Item item = Construct(type, from);
if (item == null)
{
type = null;
}
else
{
//The whole harvest system is kludgy and I'm sure this is just adding to it.
if (item.Stackable)
{
int amount = def.ConsumedPerHarvest;
int feluccaAmount = def.ConsumedPerFeluccaHarvest;
int racialAmount = (int)Math.Ceiling(amount * 1.1);
int feluccaRacialAmount = (int)Math.Ceiling(feluccaAmount * 1.1);
bool eligableForRacialBonus = def.RaceBonus && from.Race == Race.Human;
bool inFelucca = map == Map.Felucca;
if (eligableForRacialBonus && inFelucca && bank.Current >= feluccaRacialAmount &&
0.1 > Utility.RandomDouble())
item.Amount = feluccaRacialAmount;
else if (inFelucca && bank.Current >= feluccaAmount)
item.Amount = feluccaAmount;
else if (eligableForRacialBonus && bank.Current >= racialAmount && 0.1 > Utility.RandomDouble())
item.Amount = racialAmount;
else
item.Amount = amount;
}
bank.Consume(item.Amount, from);
if (Give(from, item, def.PlaceAtFeetIfFull))
{
SendSuccessTo(from, item, resource);
}
else
{
SendPackFullTo(from, item, def, resource);
item.Delete();
}
BonusHarvestResource bonus = def.GetBonusResource();
if (bonus != null && bonus.Type != null && skillBase >= bonus.ReqSkill)
{
Item bonusItem = Construct(bonus.Type, from);
if (Give(from, bonusItem, true)
) //Bonuses always allow placing at feet, even if pack is full irregrdless of def
bonus.SendSuccessTo(from);
else
item.Delete();
}
if (tool is IUsesRemaining toolWithUses)
{
toolWithUses.ShowUsesRemaining = true;
if (toolWithUses.UsesRemaining > 0)
--toolWithUses.UsesRemaining;
if (toolWithUses.UsesRemaining < 1)
{
tool.Delete();
def.SendMessageTo(from, def.ToolBrokeMessage);
}
}
}
}
}
if (type == null)
def.SendMessageTo(from, def.FailMessage);
OnHarvestFinished(from, tool, def, vein, bank, resource, toHarvest);
}
public virtual void OnHarvestFinished(Mobile from, Item tool, HarvestDefinition def, HarvestVein vein,
HarvestBank bank, HarvestResource resource, object harvested)
{
}
public virtual bool SpecialHarvest(Mobile from, Item tool, HarvestDefinition def, Map map, Point3D loc)
{
return false;
}
public virtual Item Construct(Type type, Mobile from)
{
try
{
return Activator.CreateInstance(type) as Item;
}
catch
{
return null;
}
}
public virtual HarvestVein MutateVein(Mobile from, Item tool, HarvestDefinition def, HarvestBank bank,
object toHarvest, HarvestVein vein)
{
return vein;
}
public virtual void SendSuccessTo(Mobile from, Item item, HarvestResource resource)
{
resource.SendSuccessTo(from);
}
public virtual void SendPackFullTo(Mobile from, Item item, HarvestDefinition def, HarvestResource resource)
{
def.SendMessageTo(from, def.PackFullMessage);
}
public virtual bool Give(Mobile m, Item item, bool placeAtFeet)
{
if (m.PlaceInBackpack(item))
return true;
if (!placeAtFeet)
return false;
Map map = m.Map;
if (map == null)
return false;
List<Item> atFeet = new List<Item>();
foreach (Item obj in m.GetItemsInRange(0))
atFeet.Add(obj);
for (int i = 0; i < atFeet.Count; ++i)
{
Item check = atFeet[i];
if (check.StackWith(m, item, false))
return true;
}
item.MoveToWorld(m.Location, map);
return true;
}
public virtual Type MutateType(Type type, Mobile from, Item tool, HarvestDefinition def, Map map, Point3D loc,
HarvestResource resource)
{
return from.Region.GetResource(type);
}
public virtual Type GetResourceType(Mobile from, Item tool, HarvestDefinition def, Map map, Point3D loc,
HarvestResource resource)
{
if (resource.Types.Length > 0)
return resource.Types[Utility.Random(resource.Types.Length)];
return null;
}
public virtual HarvestResource MutateResource(Mobile from, Item tool, HarvestDefinition def, Map map, Point3D loc,
HarvestVein vein, HarvestResource primary, HarvestResource fallback)
{
bool racialBonus = def.RaceBonus && from.Race == Race.Elf;
if (vein.ChanceToFallback > Utility.RandomDouble() + (racialBonus ? .20 : 0))
return fallback;
double skillValue = from.Skills[def.Skill].Value;
if (fallback != null && (skillValue < primary.ReqSkill || skillValue < primary.MinSkill))
return fallback;
return primary;
}
public virtual bool OnHarvesting(Mobile from, Item tool, HarvestDefinition def, object toHarvest, object locked,
bool last)
{
if (!CheckHarvest(from, tool))
{
from.EndAction(locked);
return false;
}
int tileID;
Map map;
Point3D loc;
if (!GetHarvestDetails(from, tool, toHarvest, out tileID, out map, out loc))
{
from.EndAction(locked);
OnBadHarvestTarget(from, tool, toHarvest);
return false;
}
if (!def.Validate(tileID))
{
from.EndAction(locked);
OnBadHarvestTarget(from, tool, toHarvest);
return false;
}
if (!CheckRange(from, tool, def, map, loc, true))
{
from.EndAction(locked);
return false;
}
if (!CheckResources(from, tool, def, map, loc, true))
{
from.EndAction(locked);
return false;
}
if (!CheckHarvest(from, tool, def, toHarvest))
{
from.EndAction(locked);
return false;
}
DoHarvestingEffect(from, tool, def, map, loc);
new HarvestSoundTimer(from, tool, this, def, toHarvest, locked, last).Start();
return !last;
}
public virtual void DoHarvestingSound(Mobile from, Item tool, HarvestDefinition def, object toHarvest)
{
if (def.EffectSounds.Length > 0)
from.PlaySound(Utility.RandomList(def.EffectSounds));
}
public virtual void DoHarvestingEffect(Mobile from, Item tool, HarvestDefinition def, Map map, Point3D loc)
{
from.Direction = from.GetDirectionTo(loc);
if (!from.Mounted)
from.Animate(Utility.RandomList(def.EffectActions), 5, 1, true, false, 0);
}
public virtual HarvestDefinition GetDefinition(int tileID)
{
HarvestDefinition def = null;
for (int i = 0; def == null && i < Definitions.Count; ++i)
{
HarvestDefinition check = Definitions[i];
if (check.Validate(tileID))
def = check;
}
return def;
}
public virtual void StartHarvesting(Mobile from, Item tool, object toHarvest)
{
if (!CheckHarvest(from, tool))
return;
int tileID;
Map map;
Point3D loc;
if (!GetHarvestDetails(from, tool, toHarvest, out tileID, out map, out loc))
{
OnBadHarvestTarget(from, tool, toHarvest);
return;
}
HarvestDefinition def = GetDefinition(tileID);
if (def == null)
{
OnBadHarvestTarget(from, tool, toHarvest);
return;
}
if (!CheckRange(from, tool, def, map, loc, false))
return;
if (!CheckResources(from, tool, def, map, loc, false))
return;
if (!CheckHarvest(from, tool, def, toHarvest))
return;
object toLock = GetLock(from, tool, def, toHarvest);
if (!from.BeginAction(toLock))
{
OnConcurrentHarvest(from, tool, def, toHarvest);
return;
}
new HarvestTimer(from, tool, this, def, toHarvest, toLock).Start();
OnHarvestStarted(from, tool, def, toHarvest);
}
public virtual bool GetHarvestDetails(Mobile from, Item tool, object toHarvest, out int tileID, out Map map,
out Point3D loc)
{
if (toHarvest is Static staticObj && !staticObj.Movable)
{
tileID = (staticObj.ItemID & 0x3FFF) | 0x4000;
map = staticObj.Map;
loc = staticObj.GetWorldLocation();
}
else if (toHarvest is StaticTarget staticTarget)
{
tileID = (staticTarget.ItemID & 0x3FFF) | 0x4000;
map = from.Map;
loc = staticTarget.Location;
}
else if (toHarvest is LandTarget landTarget)
{
tileID = landTarget.TileID;
map = from.Map;
loc = landTarget.Location;
}
else
{
tileID = 0;
map = null;
loc = Point3D.Zero;
return false;
}
return map != null && map != Map.Internal;
}
}
}
namespace Server
{
public interface IChopable
{
void OnChop( Mobile from );
}
public interface IChopable
{
void OnChop(Mobile from);
}
[AttributeUsage( AttributeTargets.Class )]
public class FurnitureAttribute : Attribute
{
public static bool Check( Item item )
{
return ( item != null && item.GetType().IsDefined( typeof( FurnitureAttribute ), false ) );
}
public FurnitureAttribute()
{
}
}
}
[AttributeUsage(AttributeTargets.Class)]
public class FurnitureAttribute : Attribute
{
public static bool Check(Item item)
{
return item != null && item.GetType().IsDefined(typeof(FurnitureAttribute), false);
}
}
}

View file

@ -1,96 +1,109 @@
using Server.Items;
using Server.Targeting;
using Server.Mobiles;
using Server.Engines.Quests;
using Server.Engines.Quests.Hag;
using Server.Items;
using Server.Mobiles;
using Server.Targeting;
namespace Server.Engines.Harvest
{
public class HarvestTarget : Target
{
private Item m_Tool;
private HarvestSystem m_System;
public class HarvestTarget : Target
{
private HarvestSystem m_System;
private Item m_Tool;
public HarvestTarget( Item tool, HarvestSystem system ) : base( -1, true, TargetFlags.None )
{
m_Tool = tool;
m_System = system;
public HarvestTarget(Item tool, HarvestSystem system) : base(-1, true, TargetFlags.None)
{
m_Tool = tool;
m_System = system;
DisallowMultis = true;
}
DisallowMultis = true;
}
protected override void OnTarget( Mobile from, object targeted )
{
if ( m_System is Mining && targeted is StaticTarget target )
{
int itemID = target.ItemID;
protected override void OnTarget(Mobile from, object targeted)
{
if (m_System is Mining && targeted is StaticTarget target)
{
int itemID = target.ItemID;
// grave
if ( itemID == 0xED3 || itemID == 0xEDF || itemID == 0xEE0 || itemID == 0xEE1 || itemID == 0xEE2 || itemID == 0xEE8 )
{
if ( from is PlayerMobile player )
{
QuestSystem qs = player.Quest;
// grave
if (itemID == 0xED3 || itemID == 0xEDF || itemID == 0xEE0 || itemID == 0xEE1 || itemID == 0xEE2 ||
itemID == 0xEE8)
if (from is PlayerMobile player)
{
QuestSystem qs = player.Quest;
if ( qs is WitchApprenticeQuest && qs.FindObjective( typeof( FindIngredientObjective ) ) is FindIngredientObjective obj && !obj.Completed && obj.Ingredient == Ingredient.Bones )
{
player.SendLocalizedMessage( 1055037 ); // You finish your grim work, finding some of the specific bones listed in the Hag's recipe.
obj.Complete();
if (qs is WitchApprenticeQuest &&
qs.FindObjective(typeof(FindIngredientObjective)) is FindIngredientObjective obj &&
!obj.Completed && obj.Ingredient == Ingredient.Bones)
{
player.SendLocalizedMessage(
1055037); // You finish your grim work, finding some of the specific bones listed in the Hag's recipe.
obj.Complete();
return;
}
}
}
}
return;
}
}
}
if ( m_System is Lumberjacking && targeted is IChopable chopable )
chopable.OnChop( from );
else if ( m_System is Lumberjacking && targeted is IAxe obj && m_Tool is BaseAxe axe )
{
Item item = (Item)obj;
if (m_System is Lumberjacking && targeted is IChopable chopable)
{
chopable.OnChop(from);
}
else if (m_System is Lumberjacking && targeted is IAxe obj && m_Tool is BaseAxe axe)
{
Item item = (Item)obj;
if ( !item.IsChildOf( from.Backpack ) )
from.SendLocalizedMessage( 1062334 ); // This item must be in your backpack to be used.
else if ( obj.Axe( from, axe ) )
from.PlaySound( 0x13E );
}
else if ( m_System is Lumberjacking && targeted is ICarvable carvable )
carvable.Carve( from, m_Tool );
else if ( m_System is Lumberjacking && FurnitureAttribute.Check( targeted as Item ) )
DestroyFurniture( from, (Item)targeted );
else if ( m_System is Mining && targeted is TreasureMap map )
map.OnBeginDig( from );
else
m_System.StartHarvesting( from, m_Tool, targeted );
}
if (!item.IsChildOf(from.Backpack))
from.SendLocalizedMessage(1062334); // This item must be in your backpack to be used.
else if (obj.Axe(from, axe))
from.PlaySound(0x13E);
}
else if (m_System is Lumberjacking && targeted is ICarvable carvable)
{
carvable.Carve(from, m_Tool);
}
else if (m_System is Lumberjacking && FurnitureAttribute.Check(targeted as Item))
{
DestroyFurniture(from, (Item)targeted);
}
else if (m_System is Mining && targeted is TreasureMap map)
{
map.OnBeginDig(from);
}
else
{
m_System.StartHarvesting(from, m_Tool, targeted);
}
}
private void DestroyFurniture( Mobile from, Item item )
{
if ( !from.InRange( item.GetWorldLocation(), 3 ) )
{
from.SendLocalizedMessage( 500446 ); // That is too far away.
return;
}
if ( !item.IsChildOf( from.Backpack ) && !item.Movable )
{
from.SendLocalizedMessage( 500462 ); // You can't destroy that while it is here.
return;
}
private void DestroyFurniture(Mobile from, Item item)
{
if (!from.InRange(item.GetWorldLocation(), 3))
{
from.SendLocalizedMessage(500446); // That is too far away.
return;
}
from.SendLocalizedMessage( 500461 ); // You destroy the item.
Effects.PlaySound( item.GetWorldLocation(), item.Map, 0x3B3 );
if (!item.IsChildOf(from.Backpack) && !item.Movable)
{
from.SendLocalizedMessage(500462); // You can't destroy that while it is here.
return;
}
if ( item is Container container )
{
if ( container is TrappableContainer trappableContainer )
trappableContainer.ExecuteTrap( from );
from.SendLocalizedMessage(500461); // You destroy the item.
Effects.PlaySound(item.GetWorldLocation(), item.Map, 0x3B3);
container.Destroy();
}
else
{
item.Delete();
}
}
}
}
if (item is Container container)
{
if (container is TrappableContainer trappableContainer)
trappableContainer.ExecuteTrap(from);
container.Destroy();
}
else
{
item.Delete();
}
}
}
}

View file

@ -2,30 +2,31 @@ using System;
namespace Server.Engines.Harvest
{
public class HarvestTimer : Timer
{
private Mobile m_From;
private Item m_Tool;
private HarvestSystem m_System;
private HarvestDefinition m_Definition;
private object m_ToHarvest, m_Locked;
private int m_Index, m_Count;
public class HarvestTimer : Timer
{
private HarvestDefinition m_Definition;
private Mobile m_From;
private int m_Index, m_Count;
private HarvestSystem m_System;
private object m_ToHarvest, m_Locked;
private Item m_Tool;
public HarvestTimer( Mobile from, Item tool, HarvestSystem system, HarvestDefinition def, object toHarvest, object locked ) : base( TimeSpan.Zero, def.EffectDelay )
{
m_From = from;
m_Tool = tool;
m_System = system;
m_Definition = def;
m_ToHarvest = toHarvest;
m_Locked = locked;
m_Count = Utility.RandomList( def.EffectCounts );
}
public HarvestTimer(Mobile from, Item tool, HarvestSystem system, HarvestDefinition def, object toHarvest,
object locked) : base(TimeSpan.Zero, def.EffectDelay)
{
m_From = from;
m_Tool = tool;
m_System = system;
m_Definition = def;
m_ToHarvest = toHarvest;
m_Locked = locked;
m_Count = Utility.RandomList(def.EffectCounts);
}
protected override void OnTick()
{
if ( !m_System.OnHarvesting( m_From, m_Tool, m_Definition, m_ToHarvest, m_Locked, ++m_Index == m_Count ) )
Stop();
}
}
protected override void OnTick()
{
if (!m_System.OnHarvesting(m_From, m_Tool, m_Definition, m_ToHarvest, m_Locked, ++m_Index == m_Count))
Stop();
}
}
}

View file

@ -1,21 +1,22 @@
namespace Server.Engines.Harvest
{
public class HarvestVein
{
public double VeinChance { get; set; }
public class HarvestVein
{
public HarvestVein(double veinChance, double chanceToFallback, HarvestResource primaryResource,
HarvestResource fallbackResource)
{
VeinChance = veinChance;
ChanceToFallback = chanceToFallback;
PrimaryResource = primaryResource;
FallbackResource = fallbackResource;
}
public double ChanceToFallback { get; set; }
public double VeinChance{ get; set; }
public HarvestResource PrimaryResource { get; set; }
public double ChanceToFallback{ get; set; }
public HarvestResource FallbackResource { get; set; }
public HarvestResource PrimaryResource{ get; set; }
public HarvestVein( double veinChance, double chanceToFallback, HarvestResource primaryResource, HarvestResource fallbackResource )
{
VeinChance = veinChance;
ChanceToFallback = chanceToFallback;
PrimaryResource = primaryResource;
FallbackResource = fallbackResource;
}
}
public HarvestResource FallbackResource{ get; set; }
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,208 +1,215 @@
using System;
using Server.Items;
using Server.Network;
using Server.Targeting;
namespace Server.Engines.Harvest
{
public class Lumberjacking : HarvestSystem
{
private static Lumberjacking m_System;
public class Lumberjacking : HarvestSystem
{
private static Lumberjacking m_System;
public static Lumberjacking System
{
get
{
if ( m_System == null )
m_System = new Lumberjacking();
#region Tile lists
return m_System;
}
}
private static int[] m_TreeTiles =
{
0x4CCA, 0x4CCB, 0x4CCC, 0x4CCD, 0x4CD0, 0x4CD3, 0x4CD6, 0x4CD8,
0x4CDA, 0x4CDD, 0x4CE0, 0x4CE3, 0x4CE6, 0x4CF8, 0x4CFB, 0x4CFE,
0x4D01, 0x4D41, 0x4D42, 0x4D43, 0x4D44, 0x4D57, 0x4D58, 0x4D59,
0x4D5A, 0x4D5B, 0x4D6E, 0x4D6F, 0x4D70, 0x4D71, 0x4D72, 0x4D84,
0x4D85, 0x4D86, 0x52B5, 0x52B6, 0x52B7, 0x52B8, 0x52B9, 0x52BA,
0x52BB, 0x52BC, 0x52BD,
public HarvestDefinition Definition { get; }
0x4CCE, 0x4CCF, 0x4CD1, 0x4CD2, 0x4CD4, 0x4CD5, 0x4CD7, 0x4CD9,
0x4CDB, 0x4CDC, 0x4CDE, 0x4CDF, 0x4CE1, 0x4CE2, 0x4CE4, 0x4CE5,
0x4CE7, 0x4CE8, 0x4CF9, 0x4CFA, 0x4CFC, 0x4CFD, 0x4CFF, 0x4D00,
0x4D02, 0x4D03, 0x4D45, 0x4D46, 0x4D47, 0x4D48, 0x4D49, 0x4D4A,
0x4D4B, 0x4D4C, 0x4D4D, 0x4D4E, 0x4D4F, 0x4D50, 0x4D51, 0x4D52,
0x4D53, 0x4D5C, 0x4D5D, 0x4D5E, 0x4D5F, 0x4D60, 0x4D61, 0x4D62,
0x4D63, 0x4D64, 0x4D65, 0x4D66, 0x4D67, 0x4D68, 0x4D69, 0x4D73,
0x4D74, 0x4D75, 0x4D76, 0x4D77, 0x4D78, 0x4D79, 0x4D7A, 0x4D7B,
0x4D7C, 0x4D7D, 0x4D7E, 0x4D7F, 0x4D87, 0x4D88, 0x4D89, 0x4D8A,
0x4D8B, 0x4D8C, 0x4D8D, 0x4D8E, 0x4D8F, 0x4D90, 0x4D95, 0x4D96,
0x4D97, 0x4D99, 0x4D9A, 0x4D9B, 0x4D9D, 0x4D9E, 0x4D9F, 0x4DA1,
0x4DA2, 0x4DA3, 0x4DA5, 0x4DA6, 0x4DA7, 0x4DA9, 0x4DAA, 0x4DAB,
0x52BE, 0x52BF, 0x52C0, 0x52C1, 0x52C2, 0x52C3, 0x52C4, 0x52C5,
0x52C6, 0x52C7
};
private Lumberjacking()
{
HarvestResource[] res;
HarvestVein[] veins;
#endregion
#region Lumberjacking
HarvestDefinition lumber = new HarvestDefinition();
private Lumberjacking()
{
HarvestResource[] res;
HarvestVein[] veins;
// Resource banks are every 4x3 tiles
lumber.BankWidth = 4;
lumber.BankHeight = 3;
#region Lumberjacking
// Every bank holds from 20 to 45 logs
lumber.MinTotal = 20;
lumber.MaxTotal = 45;
HarvestDefinition lumber = new HarvestDefinition();
// A resource bank will respawn its content every 20 to 30 minutes
lumber.MinRespawn = TimeSpan.FromMinutes( 20.0 );
lumber.MaxRespawn = TimeSpan.FromMinutes( 30.0 );
// Resource banks are every 4x3 tiles
lumber.BankWidth = 4;
lumber.BankHeight = 3;
// Skill checking is done on the Lumberjacking skill
lumber.Skill = SkillName.Lumberjacking;
// Every bank holds from 20 to 45 logs
lumber.MinTotal = 20;
lumber.MaxTotal = 45;
// Set the list of harvestable tiles
lumber.Tiles = m_TreeTiles;
// A resource bank will respawn its content every 20 to 30 minutes
lumber.MinRespawn = TimeSpan.FromMinutes(20.0);
lumber.MaxRespawn = TimeSpan.FromMinutes(30.0);
// Players must be within 2 tiles to harvest
lumber.MaxRange = 2;
// Skill checking is done on the Lumberjacking skill
lumber.Skill = SkillName.Lumberjacking;
// Ten logs per harvest action
lumber.ConsumedPerHarvest = 10;
lumber.ConsumedPerFeluccaHarvest = 20;
// Set the list of harvestable tiles
lumber.Tiles = m_TreeTiles;
// The chopping effect
lumber.EffectActions = new[]{ 13 };
lumber.EffectSounds = new[]{ 0x13E };
lumber.EffectCounts = (Core.AOS ? new[]{ 1 } : new[]{ 1, 2, 2, 2, 3 });
lumber.EffectDelay = TimeSpan.FromSeconds( 1.6 );
lumber.EffectSoundDelay = TimeSpan.FromSeconds( 0.9 );
// Players must be within 2 tiles to harvest
lumber.MaxRange = 2;
lumber.NoResourcesMessage = 500493; // There's not enough wood here to harvest.
lumber.FailMessage = 500495; // You hack at the tree for a while, but fail to produce any useable wood.
lumber.OutOfRangeMessage = 500446; // That is too far away.
lumber.PackFullMessage = 500497; // You can't place any wood into your backpack!
lumber.ToolBrokeMessage = 500499; // You broke your axe.
// Ten logs per harvest action
lumber.ConsumedPerHarvest = 10;
lumber.ConsumedPerFeluccaHarvest = 20;
if ( Core.ML )
{
res = new[]
{
new HarvestResource( 00.0, 00.0, 100.0, 1072540, typeof( Log ) ),
new HarvestResource( 65.0, 25.0, 105.0, 1072541, typeof( OakLog ) ),
new HarvestResource( 80.0, 40.0, 120.0, 1072542, typeof( AshLog ) ),
new HarvestResource( 95.0, 55.0, 135.0, 1072543, typeof( YewLog ) ),
new HarvestResource( 100.0, 60.0, 140.0, 1072544, typeof( HeartwoodLog ) ),
new HarvestResource( 100.0, 60.0, 140.0, 1072545, typeof( BloodwoodLog ) ),
new HarvestResource( 100.0, 60.0, 140.0, 1072546, typeof( FrostwoodLog ) ),
};
// The chopping effect
lumber.EffectActions = new[] { 13 };
lumber.EffectSounds = new[] { 0x13E };
lumber.EffectCounts = Core.AOS ? new[] { 1 } : new[] { 1, 2, 2, 2, 3 };
lumber.EffectDelay = TimeSpan.FromSeconds(1.6);
lumber.EffectSoundDelay = TimeSpan.FromSeconds(0.9);
lumber.NoResourcesMessage = 500493; // There's not enough wood here to harvest.
lumber.FailMessage = 500495; // You hack at the tree for a while, but fail to produce any useable wood.
lumber.OutOfRangeMessage = 500446; // That is too far away.
lumber.PackFullMessage = 500497; // You can't place any wood into your backpack!
lumber.ToolBrokeMessage = 500499; // You broke your axe.
if (Core.ML)
{
res = new[]
{
new HarvestResource(00.0, 00.0, 100.0, 1072540, typeof(Log)),
new HarvestResource(65.0, 25.0, 105.0, 1072541, typeof(OakLog)),
new HarvestResource(80.0, 40.0, 120.0, 1072542, typeof(AshLog)),
new HarvestResource(95.0, 55.0, 135.0, 1072543, typeof(YewLog)),
new HarvestResource(100.0, 60.0, 140.0, 1072544, typeof(HeartwoodLog)),
new HarvestResource(100.0, 60.0, 140.0, 1072545, typeof(BloodwoodLog)),
new HarvestResource(100.0, 60.0, 140.0, 1072546, typeof(FrostwoodLog))
};
veins = new[]
{
new HarvestVein( 49.0, 0.0, res[0], null ), // Ordinary Logs
new HarvestVein( 30.0, 0.5, res[1], res[0] ), // Oak
new HarvestVein( 10.0, 0.5, res[2], res[0] ), // Ash
new HarvestVein( 05.0, 0.5, res[3], res[0] ), // Yew
new HarvestVein( 03.0, 0.5, res[4], res[0] ), // Heartwood
new HarvestVein( 02.0, 0.5, res[5], res[0] ), // Bloodwood
new HarvestVein( 01.0, 0.5, res[6], res[0] ), // Frostwood
};
veins = new[]
{
new HarvestVein(49.0, 0.0, res[0], null), // Ordinary Logs
new HarvestVein(30.0, 0.5, res[1], res[0]), // Oak
new HarvestVein(10.0, 0.5, res[2], res[0]), // Ash
new HarvestVein(05.0, 0.5, res[3], res[0]), // Yew
new HarvestVein(03.0, 0.5, res[4], res[0]), // Heartwood
new HarvestVein(02.0, 0.5, res[5], res[0]), // Bloodwood
new HarvestVein(01.0, 0.5, res[6], res[0]) // Frostwood
};
lumber.BonusResources = new[]
{
new BonusHarvestResource( 0, 83.9, null, null ), //Nothing
new BonusHarvestResource( 100, 10.0, 1072548, typeof( BarkFragment ) ),
new BonusHarvestResource( 100, 03.0, 1072550, typeof( LuminescentFungi ) ),
new BonusHarvestResource( 100, 02.0, 1072547, typeof( SwitchItem ) ),
new BonusHarvestResource( 100, 01.0, 1072549, typeof( ParasiticPlant ) ),
new BonusHarvestResource( 100, 00.1, 1072551, typeof( BrilliantAmber ) )
};
}
else
{
res = new[]
{
new HarvestResource( 00.0, 00.0, 100.0, 500498, typeof( Log ) )
};
lumber.BonusResources = new[]
{
new BonusHarvestResource(0, 83.9, null, null), //Nothing
new BonusHarvestResource(100, 10.0, 1072548, typeof(BarkFragment)),
new BonusHarvestResource(100, 03.0, 1072550, typeof(LuminescentFungi)),
new BonusHarvestResource(100, 02.0, 1072547, typeof(SwitchItem)),
new BonusHarvestResource(100, 01.0, 1072549, typeof(ParasiticPlant)),
new BonusHarvestResource(100, 00.1, 1072551, typeof(BrilliantAmber))
};
}
else
{
res = new[]
{
new HarvestResource(00.0, 00.0, 100.0, 500498, typeof(Log))
};
veins = new[]
{
new HarvestVein( 100.0, 0.0, res[0], null )
};
}
veins = new[]
{
new HarvestVein(100.0, 0.0, res[0], null)
};
}
lumber.Resources = res;
lumber.Veins = veins;
lumber.Resources = res;
lumber.Veins = veins;
lumber.RaceBonus = Core.ML;
lumber.RandomizeVeins = Core.ML;
lumber.RaceBonus = Core.ML;
lumber.RandomizeVeins = Core.ML;
Definition = lumber;
Definitions.Add( lumber );
#endregion
}
Definition = lumber;
Definitions.Add(lumber);
public override bool CheckHarvest( Mobile from, Item tool )
{
if ( !base.CheckHarvest( from, tool ) )
return false;
#endregion
}
if ( tool.Parent != from )
{
from.SendLocalizedMessage( 500487 ); // The axe must be equipped for any serious wood chopping.
return false;
}
public static Lumberjacking System
{
get
{
if (m_System == null)
m_System = new Lumberjacking();
return true;
}
return m_System;
}
}
public override bool CheckHarvest( Mobile from, Item tool, HarvestDefinition def, object toHarvest )
{
if ( !base.CheckHarvest( from, tool, def, toHarvest ) )
return false;
public HarvestDefinition Definition{ get; }
if ( tool.Parent != from )
{
from.SendLocalizedMessage( 500487 ); // The axe must be equipped for any serious wood chopping.
return false;
}
public override bool CheckHarvest(Mobile from, Item tool)
{
if (!base.CheckHarvest(from, tool))
return false;
return true;
}
if (tool.Parent != from)
{
from.SendLocalizedMessage(500487); // The axe must be equipped for any serious wood chopping.
return false;
}
public override void OnBadHarvestTarget( Mobile from, Item tool, object toHarvest )
{
if ( toHarvest is Mobile mobile )
mobile.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 500450, from.NetState ); // You can only skin dead creatures.
else if ( toHarvest is Item item )
item.LabelTo( from, 500464 ); // Use this on corpses to carve away meat and hide
else if ( toHarvest is Targeting.StaticTarget || toHarvest is Targeting.LandTarget )
from.SendLocalizedMessage( 500489 ); // You can't use an axe on that.
else
from.SendLocalizedMessage( 1005213 ); // You can't do that
}
return true;
}
public override void OnHarvestStarted( Mobile from, Item tool, HarvestDefinition def, object toHarvest )
{
base.OnHarvestStarted( from, tool, def, toHarvest );
public override bool CheckHarvest(Mobile from, Item tool, HarvestDefinition def, object toHarvest)
{
if (!base.CheckHarvest(from, tool, def, toHarvest))
return false;
if ( Core.ML )
from.RevealingAction();
}
if (tool.Parent != from)
{
from.SendLocalizedMessage(500487); // The axe must be equipped for any serious wood chopping.
return false;
}
public static void Initialize()
{
Array.Sort( m_TreeTiles );
}
return true;
}
#region Tile lists
private static int[] m_TreeTiles = {
0x4CCA, 0x4CCB, 0x4CCC, 0x4CCD, 0x4CD0, 0x4CD3, 0x4CD6, 0x4CD8,
0x4CDA, 0x4CDD, 0x4CE0, 0x4CE3, 0x4CE6, 0x4CF8, 0x4CFB, 0x4CFE,
0x4D01, 0x4D41, 0x4D42, 0x4D43, 0x4D44, 0x4D57, 0x4D58, 0x4D59,
0x4D5A, 0x4D5B, 0x4D6E, 0x4D6F, 0x4D70, 0x4D71, 0x4D72, 0x4D84,
0x4D85, 0x4D86, 0x52B5, 0x52B6, 0x52B7, 0x52B8, 0x52B9, 0x52BA,
0x52BB, 0x52BC, 0x52BD,
public override void OnBadHarvestTarget(Mobile from, Item tool, object toHarvest)
{
if (toHarvest is Mobile mobile)
mobile.PrivateOverheadMessage(MessageType.Regular, 0x3B2, 500450,
from.NetState); // You can only skin dead creatures.
else if (toHarvest is Item item)
item.LabelTo(from, 500464); // Use this on corpses to carve away meat and hide
else if (toHarvest is StaticTarget || toHarvest is LandTarget)
from.SendLocalizedMessage(500489); // You can't use an axe on that.
else
from.SendLocalizedMessage(1005213); // You can't do that
}
0x4CCE, 0x4CCF, 0x4CD1, 0x4CD2, 0x4CD4, 0x4CD5, 0x4CD7, 0x4CD9,
0x4CDB, 0x4CDC, 0x4CDE, 0x4CDF, 0x4CE1, 0x4CE2, 0x4CE4, 0x4CE5,
0x4CE7, 0x4CE8, 0x4CF9, 0x4CFA, 0x4CFC, 0x4CFD, 0x4CFF, 0x4D00,
0x4D02, 0x4D03, 0x4D45, 0x4D46, 0x4D47, 0x4D48, 0x4D49, 0x4D4A,
0x4D4B, 0x4D4C, 0x4D4D, 0x4D4E, 0x4D4F, 0x4D50, 0x4D51, 0x4D52,
0x4D53, 0x4D5C, 0x4D5D, 0x4D5E, 0x4D5F, 0x4D60, 0x4D61, 0x4D62,
0x4D63, 0x4D64, 0x4D65, 0x4D66, 0x4D67, 0x4D68, 0x4D69, 0x4D73,
0x4D74, 0x4D75, 0x4D76, 0x4D77, 0x4D78, 0x4D79, 0x4D7A, 0x4D7B,
0x4D7C, 0x4D7D, 0x4D7E, 0x4D7F, 0x4D87, 0x4D88, 0x4D89, 0x4D8A,
0x4D8B, 0x4D8C, 0x4D8D, 0x4D8E, 0x4D8F, 0x4D90, 0x4D95, 0x4D96,
0x4D97, 0x4D99, 0x4D9A, 0x4D9B, 0x4D9D, 0x4D9E, 0x4D9F, 0x4DA1,
0x4DA2, 0x4DA3, 0x4DA5, 0x4DA6, 0x4DA7, 0x4DA9, 0x4DAA, 0x4DAB,
0x52BE, 0x52BF, 0x52C0, 0x52C1, 0x52C2, 0x52C3, 0x52C4, 0x52C5,
0x52C6, 0x52C7
};
#endregion
}
}
public override void OnHarvestStarted(Mobile from, Item tool, HarvestDefinition def, object toHarvest)
{
base.OnHarvestStarted(from, tool, def, toHarvest);
if (Core.ML)
from.RevealingAction();
}
public static void Initialize()
{
Array.Sort(m_TreeTiles);
}
}
}

View file

@ -5,413 +5,433 @@ using Server.Targeting;
namespace Server.Engines.Harvest
{
public class Mining : HarvestSystem
{
private static Mining m_System;
public static Mining System
{
get
{
if ( m_System == null )
m_System = new Mining();
return m_System;
}
}
public HarvestDefinition OreAndStone { get; }
public HarvestDefinition Sand { get; }
private Mining()
{
HarvestResource[] res;
HarvestVein[] veins;
#region Mining for ore and stone
HarvestDefinition oreAndStone = OreAndStone = new HarvestDefinition();
// Resource banks are every 8x8 tiles
oreAndStone.BankWidth = 8;
oreAndStone.BankHeight = 8;
// Every bank holds from 10 to 34 ore
oreAndStone.MinTotal = 10;
oreAndStone.MaxTotal = 34;
// A resource bank will respawn its content every 10 to 20 minutes
oreAndStone.MinRespawn = TimeSpan.FromMinutes( 10.0 );
oreAndStone.MaxRespawn = TimeSpan.FromMinutes( 20.0 );
// Skill checking is done on the Mining skill
oreAndStone.Skill = SkillName.Mining;
// Set the list of harvestable tiles
oreAndStone.Tiles = m_MountainAndCaveTiles;
// Players must be within 2 tiles to harvest
oreAndStone.MaxRange = 2;
// One ore per harvest action
oreAndStone.ConsumedPerHarvest = 1;
oreAndStone.ConsumedPerFeluccaHarvest = 2;
// The digging effect
oreAndStone.EffectActions = new[]{ 11 };
oreAndStone.EffectSounds = new[]{ 0x125, 0x126 };
oreAndStone.EffectCounts = new[]{ 1 };
oreAndStone.EffectDelay = TimeSpan.FromSeconds( 1.6 );
oreAndStone.EffectSoundDelay = TimeSpan.FromSeconds( 0.9 );
oreAndStone.NoResourcesMessage = 503040; // There is no metal here to mine.
oreAndStone.DoubleHarvestMessage = 503042; // Someone has gotten to the metal before you.
oreAndStone.TimedOutOfRangeMessage = 503041; // You have moved too far away to continue mining.
oreAndStone.OutOfRangeMessage = 500446; // That is too far away.
oreAndStone.FailMessage = 503043; // You loosen some rocks but fail to find any useable ore.
oreAndStone.PackFullMessage = 1010481; // Your backpack is full, so the ore you mined is lost.
oreAndStone.ToolBrokeMessage = 1044038; // You have worn out your tool!
res = new[]
{
new HarvestResource( 00.0, 00.0, 100.0, 1007072, typeof( IronOre ), typeof( Granite ) ),
new HarvestResource( 65.0, 25.0, 105.0, 1007073, typeof( DullCopperOre ), typeof( DullCopperGranite ), typeof( DullCopperElemental ) ),
new HarvestResource( 70.0, 30.0, 110.0, 1007074, typeof( ShadowIronOre ), typeof( ShadowIronGranite ), typeof( ShadowIronElemental ) ),
new HarvestResource( 75.0, 35.0, 115.0, 1007075, typeof( CopperOre ), typeof( CopperGranite ), typeof( CopperElemental ) ),
new HarvestResource( 80.0, 40.0, 120.0, 1007076, typeof( BronzeOre ), typeof( BronzeGranite ), typeof( BronzeElemental ) ),
new HarvestResource( 85.0, 45.0, 125.0, 1007077, typeof( GoldOre ), typeof( GoldGranite ), typeof( GoldenElemental ) ),
new HarvestResource( 90.0, 50.0, 130.0, 1007078, typeof( AgapiteOre ), typeof( AgapiteGranite ), typeof( AgapiteElemental ) ),
new HarvestResource( 95.0, 55.0, 135.0, 1007079, typeof( VeriteOre ), typeof( VeriteGranite ), typeof( VeriteElemental ) ),
new HarvestResource( 99.0, 59.0, 139.0, 1007080, typeof( ValoriteOre ), typeof( ValoriteGranite ), typeof( ValoriteElemental ) )
};
veins = new[]
{
new HarvestVein( 49.6, 0.0, res[0], null ), // Iron
new HarvestVein( 11.2, 0.5, res[1], res[0] ), // Dull Copper
new HarvestVein( 09.8, 0.5, res[2], res[0] ), // Shadow Iron
new HarvestVein( 08.4, 0.5, res[3], res[0] ), // Copper
new HarvestVein( 07.0, 0.5, res[4], res[0] ), // Bronze
new HarvestVein( 05.6, 0.5, res[5], res[0] ), // Gold
new HarvestVein( 04.2, 0.5, res[6], res[0] ), // Agapite
new HarvestVein( 02.8, 0.5, res[7], res[0] ), // Verite
new HarvestVein( 01.4, 0.5, res[8], res[0] ) // Valorite
};
oreAndStone.Resources = res;
oreAndStone.Veins = veins;
if ( Core.ML )
{
oreAndStone.BonusResources = new[]
{
new BonusHarvestResource( 0, 99.4, null, null ), //Nothing
new BonusHarvestResource( 100, .1, 1072562, typeof( BlueDiamond ) ),
new BonusHarvestResource( 100, .1, 1072567, typeof( DarkSapphire ) ),
new BonusHarvestResource( 100, .1, 1072570, typeof( EcruCitrine ) ),
new BonusHarvestResource( 100, .1, 1072564, typeof( FireRuby ) ),
new BonusHarvestResource( 100, .1, 1072566, typeof( PerfectEmerald ) ),
new BonusHarvestResource( 100, .1, 1072568, typeof( Turquoise ) )
};
}
oreAndStone.RaceBonus = Core.ML;
oreAndStone.RandomizeVeins = Core.ML;
Definitions.Add( oreAndStone );
#endregion
#region Mining for sand
HarvestDefinition sand = Sand = new HarvestDefinition();
// Resource banks are every 8x8 tiles
sand.BankWidth = 8;
sand.BankHeight = 8;
// Every bank holds from 6 to 12 sand
sand.MinTotal = 6;
sand.MaxTotal = 12;
// A resource bank will respawn its content every 10 to 20 minutes
sand.MinRespawn = TimeSpan.FromMinutes( 10.0 );
sand.MaxRespawn = TimeSpan.FromMinutes( 20.0 );
// Skill checking is done on the Mining skill
sand.Skill = SkillName.Mining;
// Set the list of harvestable tiles
sand.Tiles = m_SandTiles;
// Players must be within 2 tiles to harvest
sand.MaxRange = 2;
// One sand per harvest action
sand.ConsumedPerHarvest = 1;
sand.ConsumedPerFeluccaHarvest = 1;
// The digging effect
sand.EffectActions = new[]{ 11 };
sand.EffectSounds = new[]{ 0x125, 0x126 };
sand.EffectCounts = new[]{ 6 };
sand.EffectDelay = TimeSpan.FromSeconds( 1.6 );
sand.EffectSoundDelay = TimeSpan.FromSeconds( 0.9 );
sand.NoResourcesMessage = 1044629; // There is no sand here to mine.
sand.DoubleHarvestMessage = 1044629; // There is no sand here to mine.
sand.TimedOutOfRangeMessage = 503041; // You have moved too far away to continue mining.
sand.OutOfRangeMessage = 500446; // That is too far away.
sand.FailMessage = 1044630; // You dig for a while but fail to find any of sufficient quality for glassblowing.
sand.PackFullMessage = 1044632; // Your backpack can't hold the sand, and it is lost!
sand.ToolBrokeMessage = 1044038; // You have worn out your tool!
res = new[]
{
new HarvestResource( 100.0, 70.0, 400.0, 1044631, typeof( Sand ) )
};
veins = new[]
{
new HarvestVein( 100.0, 0.0, res[0], null )
};
sand.Resources = res;
sand.Veins = veins;
Definitions.Add( sand );
#endregion
}
public override Type GetResourceType( Mobile from, Item tool, HarvestDefinition def, Map map, Point3D loc, HarvestResource resource )
{
if ( def == OreAndStone )
{
if ( from is PlayerMobile pm && pm.StoneMining && pm.ToggleMiningStone && from.Skills[SkillName.Mining].Base >= 100.0 && 0.1 > Utility.RandomDouble() )
return resource.Types[1];
return resource.Types[0];
}
return base.GetResourceType( from, tool, def, map, loc, resource );
}
public override bool CheckHarvest( Mobile from, Item tool )
{
if ( !base.CheckHarvest( from, tool ) )
return false;
if ( from.Mounted )
{
from.SendLocalizedMessage( 501864 ); // You can't mine while riding.
return false;
}
if ( from.IsBodyMod && !from.Body.IsHuman )
{
from.SendLocalizedMessage( 501865 ); // You can't mine while polymorphed.
return false;
}
return true;
}
public override void SendSuccessTo( Mobile from, Item item, HarvestResource resource )
{
if ( item is BaseGranite )
from.SendLocalizedMessage( 1044606 ); // You carefully extract some workable stone from the ore vein!
else
base.SendSuccessTo( from, item, resource );
}
public override bool CheckHarvest( Mobile from, Item tool, HarvestDefinition def, object toHarvest )
{
if ( !base.CheckHarvest( from, tool, def, toHarvest ) )
return false;
if ( def == Sand && !(from is PlayerMobile mobile && mobile.Skills[SkillName.Mining].Base >= 100.0 && mobile.SandMining) )
{
OnBadHarvestTarget( from, tool, toHarvest );
return false;
}
if ( from.Mounted )
{
from.SendLocalizedMessage( 501864 ); // You can't mine while riding.
return false;
}
if ( from.IsBodyMod && !from.Body.IsHuman )
{
from.SendLocalizedMessage( 501865 ); // You can't mine while polymorphed.
return false;
}
return true;
}
public override HarvestVein MutateVein( Mobile from, Item tool, HarvestDefinition def, HarvestBank bank, object toHarvest, HarvestVein vein )
{
if ( tool is GargoylesPickaxe && def == OreAndStone )
{
int veinIndex = Array.IndexOf( def.Veins, vein );
if ( veinIndex >= 0 && veinIndex < (def.Veins.Length - 1) )
return def.Veins[veinIndex + 1];
}
return base.MutateVein( from, tool, def, bank, toHarvest, vein );
}
private static int[] m_Offsets = {
-1, -1,
-1, 0,
-1, 1,
0, -1,
0, 1,
1, -1,
1, 0,
1, 1
};
public override void OnHarvestFinished( Mobile from, Item tool, HarvestDefinition def, HarvestVein vein, HarvestBank bank, HarvestResource resource, object harvested )
{
if ( tool is GargoylesPickaxe && def == OreAndStone && 0.1 > Utility.RandomDouble() )
{
HarvestResource res = vein.PrimaryResource;
if ( res == resource && res.Types.Length >= 3 )
{
try
{
Map map = from.Map;
if ( map == null )
return;
if ( Activator.CreateInstance( res.Types[2], new object[]{ 25 } ) is BaseCreature spawned )
{
int offset = Utility.Random( 8 ) * 2;
for ( int i = 0; i < m_Offsets.Length; i += 2 )
{
int x = from.X + m_Offsets[(offset + i) % m_Offsets.Length];
int y = from.Y + m_Offsets[(offset + i + 1) % m_Offsets.Length];
if ( map.CanSpawnMobile( x, y, from.Z ) )
{
spawned.OnBeforeSpawn( new Point3D( x, y, from.Z ), map );
spawned.MoveToWorld( new Point3D( x, y, from.Z ), map );
spawned.Combatant = from;
return;
}
int z = map.GetAverageZ( x, y );
if ( Math.Abs( z - from.Z ) < 10 && map.CanSpawnMobile( x, y, z ) )
{
spawned.OnBeforeSpawn( new Point3D( x, y, z ), map );
spawned.MoveToWorld( new Point3D( x, y, z ), map );
spawned.Combatant = from;
return;
}
}
spawned.OnBeforeSpawn( from.Location, from.Map );
spawned.MoveToWorld( from.Location, from.Map );
spawned.Combatant = from;
}
}
catch
{
}
}
}
}
public override bool BeginHarvesting( Mobile from, Item tool )
{
if ( !base.BeginHarvesting( from, tool ) )
return false;
from.SendLocalizedMessage( 503033 ); // Where do you wish to dig?
return true;
}
public override void OnHarvestStarted( Mobile from, Item tool, HarvestDefinition def, object toHarvest )
{
base.OnHarvestStarted( from, tool, def, toHarvest );
if ( Core.ML )
from.RevealingAction();
}
public override void OnBadHarvestTarget( Mobile from, Item tool, object toHarvest )
{
if ( toHarvest is LandTarget )
from.SendLocalizedMessage( 501862 ); // You can't mine there.
else
from.SendLocalizedMessage( 501863 ); // You can't mine that.
}
#region Tile lists
private static int[] m_MountainAndCaveTiles = {
220, 221, 222, 223, 224, 225, 226, 227, 228, 229,
230, 231, 236, 237, 238, 239, 240, 241, 242, 243,
244, 245, 246, 247, 252, 253, 254, 255, 256, 257,
258, 259, 260, 261, 262, 263, 268, 269, 270, 271,
272, 273, 274, 275, 276, 277, 278, 279, 286, 287,
288, 289, 290, 291, 292, 293, 294, 296, 296, 297,
321, 322, 323, 324, 467, 468, 469, 470, 471, 472,
473, 474, 476, 477, 478, 479, 480, 481, 482, 483,
484, 485, 486, 487, 492, 493, 494, 495, 543, 544,
545, 546, 547, 548, 549, 550, 551, 552, 553, 554,
555, 556, 557, 558, 559, 560, 561, 562, 563, 564,
565, 566, 567, 568, 569, 570, 571, 572, 573, 574,
575, 576, 577, 578, 579, 581, 582, 583, 584, 585,
586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
596, 597, 598, 599, 600, 601, 610, 611, 612, 613,
1010, 1741, 1742, 1743, 1744, 1745, 1746, 1747, 1748, 1749,
1750, 1751, 1752, 1753, 1754, 1755, 1756, 1757, 1771, 1772,
1773, 1774, 1775, 1776, 1777, 1778, 1779, 1780, 1781, 1782,
1783, 1784, 1785, 1786, 1787, 1788, 1789, 1790, 1801, 1802,
1803, 1804, 1805, 1806, 1807, 1808, 1809, 1811, 1812, 1813,
1814, 1815, 1816, 1817, 1818, 1819, 1820, 1821, 1822, 1823,
1824, 1831, 1832, 1833, 1834, 1835, 1836, 1837, 1838, 1839,
1840, 1841, 1842, 1843, 1844, 1845, 1846, 1847, 1848, 1849,
1850, 1851, 1852, 1853, 1854, 1861, 1862, 1863, 1864, 1865,
1866, 1867, 1868, 1869, 1870, 1871, 1872, 1873, 1874, 1875,
1876, 1877, 1878, 1879, 1880, 1881, 1882, 1883, 1884, 1981,
1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991,
1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
2002, 2003, 2004, 2028, 2029, 2030, 2031, 2032, 2033, 2100,
2101, 2102, 2103, 2104, 2105,
0x453B, 0x453C, 0x453D, 0x453E, 0x453F, 0x4540, 0x4541,
0x4542, 0x4543, 0x4544, 0x4545, 0x4546, 0x4547, 0x4548,
0x4549, 0x454A, 0x454B, 0x454C, 0x454D, 0x454E, 0x454F
};
private static int[] m_SandTiles = {
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
62, 68, 69, 70, 71, 72, 73, 74, 75,
286, 287, 288, 289, 290, 291, 292, 293, 294, 295,
296, 297, 298, 299, 300, 301, 402, 424, 425, 426,
427, 441, 442, 443, 444, 445, 446, 447, 448, 449,
450, 451, 452, 453, 454, 455, 456, 457, 458, 459,
460, 461, 462, 463, 464, 465, 642, 643, 644, 645,
650, 651, 652, 653, 654, 655, 656, 657, 821, 822,
823, 824, 825, 826, 827, 828, 833, 834, 835, 836,
845, 846, 847, 848, 849, 850, 851, 852, 857, 858,
859, 860, 951, 952, 953, 954, 955, 956, 957, 958,
967, 968, 969, 970,
1447, 1448, 1449, 1450, 1451, 1452, 1453, 1454, 1455,
1456, 1457, 1458, 1611, 1612, 1613, 1614, 1615, 1616,
1617, 1618, 1623, 1624, 1625, 1626, 1635, 1636, 1637,
1638, 1639, 1640, 1641, 1642, 1647, 1648, 1649, 1650
};
#endregion
}
}
public class Mining : HarvestSystem
{
private static Mining m_System;
private static int[] m_Offsets =
{
-1, -1,
-1, 0,
-1, 1,
0, -1,
0, 1,
1, -1,
1, 0,
1, 1
};
private Mining()
{
HarvestResource[] res;
HarvestVein[] veins;
#region Mining for ore and stone
HarvestDefinition oreAndStone = OreAndStone = new HarvestDefinition();
// Resource banks are every 8x8 tiles
oreAndStone.BankWidth = 8;
oreAndStone.BankHeight = 8;
// Every bank holds from 10 to 34 ore
oreAndStone.MinTotal = 10;
oreAndStone.MaxTotal = 34;
// A resource bank will respawn its content every 10 to 20 minutes
oreAndStone.MinRespawn = TimeSpan.FromMinutes(10.0);
oreAndStone.MaxRespawn = TimeSpan.FromMinutes(20.0);
// Skill checking is done on the Mining skill
oreAndStone.Skill = SkillName.Mining;
// Set the list of harvestable tiles
oreAndStone.Tiles = m_MountainAndCaveTiles;
// Players must be within 2 tiles to harvest
oreAndStone.MaxRange = 2;
// One ore per harvest action
oreAndStone.ConsumedPerHarvest = 1;
oreAndStone.ConsumedPerFeluccaHarvest = 2;
// The digging effect
oreAndStone.EffectActions = new[] { 11 };
oreAndStone.EffectSounds = new[] { 0x125, 0x126 };
oreAndStone.EffectCounts = new[] { 1 };
oreAndStone.EffectDelay = TimeSpan.FromSeconds(1.6);
oreAndStone.EffectSoundDelay = TimeSpan.FromSeconds(0.9);
oreAndStone.NoResourcesMessage = 503040; // There is no metal here to mine.
oreAndStone.DoubleHarvestMessage = 503042; // Someone has gotten to the metal before you.
oreAndStone.TimedOutOfRangeMessage = 503041; // You have moved too far away to continue mining.
oreAndStone.OutOfRangeMessage = 500446; // That is too far away.
oreAndStone.FailMessage = 503043; // You loosen some rocks but fail to find any useable ore.
oreAndStone.PackFullMessage = 1010481; // Your backpack is full, so the ore you mined is lost.
oreAndStone.ToolBrokeMessage = 1044038; // You have worn out your tool!
res = new[]
{
new HarvestResource(00.0, 00.0, 100.0, 1007072, typeof(IronOre), typeof(Granite)),
new HarvestResource(65.0, 25.0, 105.0, 1007073, typeof(DullCopperOre), typeof(DullCopperGranite),
typeof(DullCopperElemental)),
new HarvestResource(70.0, 30.0, 110.0, 1007074, typeof(ShadowIronOre), typeof(ShadowIronGranite),
typeof(ShadowIronElemental)),
new HarvestResource(75.0, 35.0, 115.0, 1007075, typeof(CopperOre), typeof(CopperGranite),
typeof(CopperElemental)),
new HarvestResource(80.0, 40.0, 120.0, 1007076, typeof(BronzeOre), typeof(BronzeGranite),
typeof(BronzeElemental)),
new HarvestResource(85.0, 45.0, 125.0, 1007077, typeof(GoldOre), typeof(GoldGranite),
typeof(GoldenElemental)),
new HarvestResource(90.0, 50.0, 130.0, 1007078, typeof(AgapiteOre), typeof(AgapiteGranite),
typeof(AgapiteElemental)),
new HarvestResource(95.0, 55.0, 135.0, 1007079, typeof(VeriteOre), typeof(VeriteGranite),
typeof(VeriteElemental)),
new HarvestResource(99.0, 59.0, 139.0, 1007080, typeof(ValoriteOre), typeof(ValoriteGranite),
typeof(ValoriteElemental))
};
veins = new[]
{
new HarvestVein(49.6, 0.0, res[0], null), // Iron
new HarvestVein(11.2, 0.5, res[1], res[0]), // Dull Copper
new HarvestVein(09.8, 0.5, res[2], res[0]), // Shadow Iron
new HarvestVein(08.4, 0.5, res[3], res[0]), // Copper
new HarvestVein(07.0, 0.5, res[4], res[0]), // Bronze
new HarvestVein(05.6, 0.5, res[5], res[0]), // Gold
new HarvestVein(04.2, 0.5, res[6], res[0]), // Agapite
new HarvestVein(02.8, 0.5, res[7], res[0]), // Verite
new HarvestVein(01.4, 0.5, res[8], res[0]) // Valorite
};
oreAndStone.Resources = res;
oreAndStone.Veins = veins;
if (Core.ML)
oreAndStone.BonusResources = new[]
{
new BonusHarvestResource(0, 99.4, null, null), //Nothing
new BonusHarvestResource(100, .1, 1072562, typeof(BlueDiamond)),
new BonusHarvestResource(100, .1, 1072567, typeof(DarkSapphire)),
new BonusHarvestResource(100, .1, 1072570, typeof(EcruCitrine)),
new BonusHarvestResource(100, .1, 1072564, typeof(FireRuby)),
new BonusHarvestResource(100, .1, 1072566, typeof(PerfectEmerald)),
new BonusHarvestResource(100, .1, 1072568, typeof(Turquoise))
};
oreAndStone.RaceBonus = Core.ML;
oreAndStone.RandomizeVeins = Core.ML;
Definitions.Add(oreAndStone);
#endregion
#region Mining for sand
HarvestDefinition sand = Sand = new HarvestDefinition();
// Resource banks are every 8x8 tiles
sand.BankWidth = 8;
sand.BankHeight = 8;
// Every bank holds from 6 to 12 sand
sand.MinTotal = 6;
sand.MaxTotal = 12;
// A resource bank will respawn its content every 10 to 20 minutes
sand.MinRespawn = TimeSpan.FromMinutes(10.0);
sand.MaxRespawn = TimeSpan.FromMinutes(20.0);
// Skill checking is done on the Mining skill
sand.Skill = SkillName.Mining;
// Set the list of harvestable tiles
sand.Tiles = m_SandTiles;
// Players must be within 2 tiles to harvest
sand.MaxRange = 2;
// One sand per harvest action
sand.ConsumedPerHarvest = 1;
sand.ConsumedPerFeluccaHarvest = 1;
// The digging effect
sand.EffectActions = new[] { 11 };
sand.EffectSounds = new[] { 0x125, 0x126 };
sand.EffectCounts = new[] { 6 };
sand.EffectDelay = TimeSpan.FromSeconds(1.6);
sand.EffectSoundDelay = TimeSpan.FromSeconds(0.9);
sand.NoResourcesMessage = 1044629; // There is no sand here to mine.
sand.DoubleHarvestMessage = 1044629; // There is no sand here to mine.
sand.TimedOutOfRangeMessage = 503041; // You have moved too far away to continue mining.
sand.OutOfRangeMessage = 500446; // That is too far away.
sand.FailMessage = 1044630; // You dig for a while but fail to find any of sufficient quality for glassblowing.
sand.PackFullMessage = 1044632; // Your backpack can't hold the sand, and it is lost!
sand.ToolBrokeMessage = 1044038; // You have worn out your tool!
res = new[]
{
new HarvestResource(100.0, 70.0, 400.0, 1044631, typeof(Sand))
};
veins = new[]
{
new HarvestVein(100.0, 0.0, res[0], null)
};
sand.Resources = res;
sand.Veins = veins;
Definitions.Add(sand);
#endregion
}
public static Mining System
{
get
{
if (m_System == null)
m_System = new Mining();
return m_System;
}
}
public HarvestDefinition OreAndStone{ get; }
public HarvestDefinition Sand{ get; }
public override Type GetResourceType(Mobile from, Item tool, HarvestDefinition def, Map map, Point3D loc,
HarvestResource resource)
{
if (def == OreAndStone)
{
if (from is PlayerMobile pm && pm.StoneMining && pm.ToggleMiningStone &&
from.Skills[SkillName.Mining].Base >= 100.0 && 0.1 > Utility.RandomDouble())
return resource.Types[1];
return resource.Types[0];
}
return base.GetResourceType(from, tool, def, map, loc, resource);
}
public override bool CheckHarvest(Mobile from, Item tool)
{
if (!base.CheckHarvest(from, tool))
return false;
if (from.Mounted)
{
from.SendLocalizedMessage(501864); // You can't mine while riding.
return false;
}
if (from.IsBodyMod && !from.Body.IsHuman)
{
from.SendLocalizedMessage(501865); // You can't mine while polymorphed.
return false;
}
return true;
}
public override void SendSuccessTo(Mobile from, Item item, HarvestResource resource)
{
if (item is BaseGranite)
from.SendLocalizedMessage(1044606); // You carefully extract some workable stone from the ore vein!
else
base.SendSuccessTo(from, item, resource);
}
public override bool CheckHarvest(Mobile from, Item tool, HarvestDefinition def, object toHarvest)
{
if (!base.CheckHarvest(from, tool, def, toHarvest))
return false;
if (def == Sand && !(from is PlayerMobile mobile && mobile.Skills[SkillName.Mining].Base >= 100.0 &&
mobile.SandMining))
{
OnBadHarvestTarget(from, tool, toHarvest);
return false;
}
if (from.Mounted)
{
from.SendLocalizedMessage(501864); // You can't mine while riding.
return false;
}
if (from.IsBodyMod && !from.Body.IsHuman)
{
from.SendLocalizedMessage(501865); // You can't mine while polymorphed.
return false;
}
return true;
}
public override HarvestVein MutateVein(Mobile from, Item tool, HarvestDefinition def, HarvestBank bank,
object toHarvest, HarvestVein vein)
{
if (tool is GargoylesPickaxe && def == OreAndStone)
{
int veinIndex = Array.IndexOf(def.Veins, vein);
if (veinIndex >= 0 && veinIndex < def.Veins.Length - 1)
return def.Veins[veinIndex + 1];
}
return base.MutateVein(from, tool, def, bank, toHarvest, vein);
}
public override void OnHarvestFinished(Mobile from, Item tool, HarvestDefinition def, HarvestVein vein,
HarvestBank bank, HarvestResource resource, object harvested)
{
if (tool is GargoylesPickaxe && def == OreAndStone && 0.1 > Utility.RandomDouble())
{
HarvestResource res = vein.PrimaryResource;
if (res == resource && res.Types.Length >= 3)
try
{
Map map = from.Map;
if (map == null)
return;
if (Activator.CreateInstance(res.Types[2], 25) is BaseCreature spawned)
{
int offset = Utility.Random(8) * 2;
for (int i = 0; i < m_Offsets.Length; i += 2)
{
int x = from.X + m_Offsets[(offset + i) % m_Offsets.Length];
int y = from.Y + m_Offsets[(offset + i + 1) % m_Offsets.Length];
if (map.CanSpawnMobile(x, y, from.Z))
{
spawned.OnBeforeSpawn(new Point3D(x, y, from.Z), map);
spawned.MoveToWorld(new Point3D(x, y, from.Z), map);
spawned.Combatant = from;
return;
}
int z = map.GetAverageZ(x, y);
if (Math.Abs(z - from.Z) < 10 && map.CanSpawnMobile(x, y, z))
{
spawned.OnBeforeSpawn(new Point3D(x, y, z), map);
spawned.MoveToWorld(new Point3D(x, y, z), map);
spawned.Combatant = from;
return;
}
}
spawned.OnBeforeSpawn(from.Location, from.Map);
spawned.MoveToWorld(from.Location, from.Map);
spawned.Combatant = from;
}
}
catch
{
}
}
}
public override bool BeginHarvesting(Mobile from, Item tool)
{
if (!base.BeginHarvesting(from, tool))
return false;
from.SendLocalizedMessage(503033); // Where do you wish to dig?
return true;
}
public override void OnHarvestStarted(Mobile from, Item tool, HarvestDefinition def, object toHarvest)
{
base.OnHarvestStarted(from, tool, def, toHarvest);
if (Core.ML)
from.RevealingAction();
}
public override void OnBadHarvestTarget(Mobile from, Item tool, object toHarvest)
{
if (toHarvest is LandTarget)
from.SendLocalizedMessage(501862); // You can't mine there.
else
from.SendLocalizedMessage(501863); // You can't mine that.
}
#region Tile lists
private static int[] m_MountainAndCaveTiles =
{
220, 221, 222, 223, 224, 225, 226, 227, 228, 229,
230, 231, 236, 237, 238, 239, 240, 241, 242, 243,
244, 245, 246, 247, 252, 253, 254, 255, 256, 257,
258, 259, 260, 261, 262, 263, 268, 269, 270, 271,
272, 273, 274, 275, 276, 277, 278, 279, 286, 287,
288, 289, 290, 291, 292, 293, 294, 296, 296, 297,
321, 322, 323, 324, 467, 468, 469, 470, 471, 472,
473, 474, 476, 477, 478, 479, 480, 481, 482, 483,
484, 485, 486, 487, 492, 493, 494, 495, 543, 544,
545, 546, 547, 548, 549, 550, 551, 552, 553, 554,
555, 556, 557, 558, 559, 560, 561, 562, 563, 564,
565, 566, 567, 568, 569, 570, 571, 572, 573, 574,
575, 576, 577, 578, 579, 581, 582, 583, 584, 585,
586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
596, 597, 598, 599, 600, 601, 610, 611, 612, 613,
1010, 1741, 1742, 1743, 1744, 1745, 1746, 1747, 1748, 1749,
1750, 1751, 1752, 1753, 1754, 1755, 1756, 1757, 1771, 1772,
1773, 1774, 1775, 1776, 1777, 1778, 1779, 1780, 1781, 1782,
1783, 1784, 1785, 1786, 1787, 1788, 1789, 1790, 1801, 1802,
1803, 1804, 1805, 1806, 1807, 1808, 1809, 1811, 1812, 1813,
1814, 1815, 1816, 1817, 1818, 1819, 1820, 1821, 1822, 1823,
1824, 1831, 1832, 1833, 1834, 1835, 1836, 1837, 1838, 1839,
1840, 1841, 1842, 1843, 1844, 1845, 1846, 1847, 1848, 1849,
1850, 1851, 1852, 1853, 1854, 1861, 1862, 1863, 1864, 1865,
1866, 1867, 1868, 1869, 1870, 1871, 1872, 1873, 1874, 1875,
1876, 1877, 1878, 1879, 1880, 1881, 1882, 1883, 1884, 1981,
1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991,
1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
2002, 2003, 2004, 2028, 2029, 2030, 2031, 2032, 2033, 2100,
2101, 2102, 2103, 2104, 2105,
0x453B, 0x453C, 0x453D, 0x453E, 0x453F, 0x4540, 0x4541,
0x4542, 0x4543, 0x4544, 0x4545, 0x4546, 0x4547, 0x4548,
0x4549, 0x454A, 0x454B, 0x454C, 0x454D, 0x454E, 0x454F
};
private static int[] m_SandTiles =
{
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
62, 68, 69, 70, 71, 72, 73, 74, 75,
286, 287, 288, 289, 290, 291, 292, 293, 294, 295,
296, 297, 298, 299, 300, 301, 402, 424, 425, 426,
427, 441, 442, 443, 444, 445, 446, 447, 448, 449,
450, 451, 452, 453, 454, 455, 456, 457, 458, 459,
460, 461, 462, 463, 464, 465, 642, 643, 644, 645,
650, 651, 652, 653, 654, 655, 656, 657, 821, 822,
823, 824, 825, 826, 827, 828, 833, 834, 835, 836,
845, 846, 847, 848, 849, 850, 851, 852, 857, 858,
859, 860, 951, 952, 953, 954, 955, 956, 957, 958,
967, 968, 969, 970,
1447, 1448, 1449, 1450, 1451, 1452, 1453, 1454, 1455,
1456, 1457, 1458, 1611, 1612, 1613, 1614, 1615, 1616,
1617, 1618, 1623, 1624, 1625, 1626, 1635, 1636, 1637,
1638, 1639, 1640, 1641, 1642, 1647, 1648, 1649, 1650
};
#endregion
}
}