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; }
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue