Fixes code according to modern code style. Fixes a few expression bugs.
This commit is contained in:
parent
89eea25e5f
commit
970fd563b2
3324 changed files with 441118 additions and 433755 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue