Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using wServer.realm.entities;
using System.Collections.Concurrent;
namespace wServer.realm
{
public abstract class World
{
public const int TUT_ID = -1;
public const int NEXUS_ID = -2;
public const int RAND_REALM = -3;
public const int NEXUS_LIMBO = -4;
public const int VAULT_ID = -5;
public const int TEST_ID = -6;
public const int BANANA_ID = -10; //remove this line when its underlined in red
protected World()
{
Players = new ConcurrentDictionary<int, Player>();
Enemies = new ConcurrentDictionary<int, Enemy>();
Quests = new ConcurrentDictionary<int, Enemy>();
Projectiles = new ConcurrentDictionary<Tuple<int, byte>, Projectile>();
StaticObjects = new ConcurrentDictionary<int, StaticObject>();
Timers = new List<WorldTimer>();
EnemiesCollision = new SpatialStorage();
PlayersCollision = new SpatialStorage();
ClientXML = ExtraXML = Empty<string>.Array;
Map = new Wmap();
AllowTeleport = true;
ShowDisplays = true;
ExtraXML = new string[] { XmlDatas.AdditionXml };
}
public bool IsLimbo { get; protected set; }
public virtual World GetInstance(ClientProcessor psr) { return null; }
public int Id { get; internal set; }
public string Name { get; protected set; }
public ConcurrentDictionary<int, Player> Players { get; private set; }
public ConcurrentDictionary<int, Enemy> Enemies { get; private set; }
public ConcurrentDictionary<Tuple<int, byte>, Projectile> Projectiles { get; private set; }
public ConcurrentDictionary<int, StaticObject> StaticObjects { get; private set; }
public List<WorldTimer> Timers { get; private set; }
public int Background { get; protected set; }
public SpatialStorage EnemiesCollision { get; private set; }
public SpatialStorage PlayersCollision { get; private set; }
public byte[,] Obstacles { get; private set; }
public bool AllowTeleport { get; protected set; }
public bool ShowDisplays { get; protected set; }
public string[] ClientXML { get; protected set; }
public string[] ExtraXML { get; protected set; }
public Wmap Map { get; private set; }
private int entityInc = 0;
public int GetNextEntityId()
{
return Interlocked.Increment(ref entityInc);
}
public bool Delete()
{
lock (this)
{
if (Players.Count > 0) return false;
Id = 0;
}
Map = null;
Players = null;
Enemies = null;
Projectiles = null;
StaticObjects = null;
return true;
}
protected void FromWorldMap(System****.Stream dat)
{
Wmap map = new Wmap();
this.Map = map;
entityInc = 0;
entityInc += map.Load(dat, 0);
int w = map.Width, h = map.Height;
Obstacles = new byte[w, h];
for (int y = 0; y < h; y++)
for (int x = 0; x < w; x++)
{
var tile = map[x, y];
ObjectDesc desc;
if (XmlDatas.TileDescs[tile.TileId].NoWalk)
Obstacles[x, y] = 3;
if (XmlDatas.ObjectDescs.TryGetValue(tile.ObjType, out desc))
{
if (desc.Class == "Wall" ||
desc.Class == "ConnectedWall" ||
desc.Class == "CaveWall")
Obstacles[x, y] = 2;
else if (desc.OccupySquare || desc.EnemyOccupySquare)
Obstacles[x, y] = 1;
}
}
Projectiles.Clear();
StaticObjects.Clear();
Enemies.Clear();
Players.Clear();
foreach (var i in map.InstantiateEntities())
{
if (i.ObjectDesc != null &&
(i.ObjectDesc.OccupySquare || i.ObjectDesc.EnemyOccupySquare))
Obstacles[(int)(i.X - 0.5), (int)(i.Y - 0.5)] = 2;
EnterWorld(i);
}
}
public virtual int EnterWorld(Entity entity)
{
if (entity is Player)
{
entity.Id = GetNextEntityId();
entity.Init(this);
Players.TryAdd(entity.Id, entity as Player);
PlayersCollision.Insert(entity);
}
else if (entity is Enemy)
{
entity.Id = GetNextEntityId();
entity.Init(this);
Enemies.TryAdd(entity.Id, entity as Enemy);
if (entity.ObjectDesc.Quest)
Quests.TryAdd(entity.Id, entity as Enemy);
}
else if (entity is Projectile)
{
entity.Init(this);
Projectile prj = entity as Projectile;
Projectiles[new Tuple<int, byte>(prj.ProjectileOwner.Self.Id, prj.ProjectileId)] = prj;
}
else if (entity is StaticObject)
{
entity.Id = GetNextEntityId();
entity.Init(this);
StaticObjects.TryAdd(entity.Id, entity as StaticObject);
if (entity is Decoy)
PlayersCollision.Insert(entity);
else
EnemiesCollision.Insert(entity);
}
return entity.Id;
}
public virtual void LeaveWorld(Entity entity)
{
if (entity is Player)
{
Player dummy;
Players.TryRemove(entity.Id, out dummy);
PlayersCollision.Remove(entity);
}
else if (entity is Enemy)
{
Enemy dummy;
Enemies.TryRemove(entity.Id, out dummy);
EnemiesCollision.Remove(entity);
if (entity.ObjectDesc.Quest)
Quests.TryRemove(entity.Id, out dummy);
}
else if (entity is Projectile)
{
Projectile p = entity as Projectile;
Projectiles.TryRemove(new Tuple<int, byte>(p.ProjectileOwner.Self.Id, p.ProjectileId), out p);
}
else if (entity is StaticObject)
{
StaticObject dummy;
StaticObjects.TryRemove(entity.Id, out dummy);
if (entity is Decoy)
PlayersCollision.Remove(entity);
else
EnemiesCollision.Remove(entity);
}
entity.Owner = null;
}
public Entity GetEntity(int id)
{
Player ret1;
if (Players.TryGetValue(id, out ret1)) return ret1;
Enemy ret2;
if (Enemies.TryGetValue(id, out ret2)) return ret2;
StaticObject ret3;
if (StaticObjects.TryGetValue(id, out ret3)) return ret3;
return null;
}
public Player GetUniqueNamedPlayer(string name)
{
foreach (var i in Players)
{
if (i.Value.NameChosen && i.Value.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase))
return i.Value;
}
return null;
}
public void BroadcastPacket(Packet pkt, Player exclude)
{
foreach (var i in Players)
if (i.Value != exclude)
i.Value.Client.SendPacket(pkt);
}
public void BroadcastPackets(IEnumerable<Packet> pkts, Player exclude)
{
foreach (var i in Players)
if (i.Value != exclude)
i.Value.Client.SendPackets(pkts);
}
public virtual void Tick(RealmTime time)
{
if (IsLimbo) return;
for (int i = 0; i < Timers.Count; i++)
if (Timers[i].Tick(this, time))
{
Timers.RemoveAt(i);
i--;
}
foreach (var i in Players)
i.Value.Tick(time);
foreach (var i in Enemies)
i.Value.Tick(time);
foreach (var i in Projectiles)
i.Value.Tick(time);
foreach (var i in StaticObjects)
i.Value.Tick(time);
}
public ConcurrentDictionary<int, Enemy> Quests { get; private set; }
}
}
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using wServer.svrPackets;
using System.Xml;
using System.Xml.Linq;
namespace wServer.realm.entities
{
public partial class Player
{
static int GetExpGoal(int level)
{
return 50 + (level - 1) * 100;
}
static int GetLevelExp(int level)
{
if (level == 1) return 0;
return 50 * (level - 1) + (level - 2) * (level - 1) * 50;
}
static int GetFameGoal(int fame)
{
if (fame >= 2000) return 0;
else if (fame >= 800) return 2000;
else if (fame >= 400) return 800;
else if (fame >= 150) return 400;
else if (fame >= 20) return 150;
else return 20;
}
public int GetStars()
{
int ret = 0;
foreach (var i in psr.Account.Stats.ClassStates)
{
if (i******Fame >= 2000) ret += 5;
else if (i******Fame >= 800) ret += 4;
else if (i******Fame >= 400) ret += 3;
else if (i******Fame >= 150) ret += 2;
else if (i******Fame >= 20) ret += 1;
}
return ret;
}
static readonly Dictionary<string, Tuple<int, int, int>> QuestDat =
new Dictionary<string, Tuple<int, int, int>>() //Priority, Min, Max
{
{ "Scorpion Queen", Tuple.Create(1, 1, 6) },
{ "Bandit Leader", Tuple.Create(1, 1, 6) },
{ "Hobbit Mage", Tuple.Create(3, 3, 8) },
{ "Undead Hobbit Mage", Tuple.Create(3, 3, 8) },
{ "Giant Crab", Tuple.Create(3, 3, 8) },
{ "Desert Werewolf", Tuple.Create(3, 3, 8) },
{ "Sandsman King", Tuple.Create(4, 4, 9) },
{ "Goblin Mage", Tuple.Create(4, 4, 9) },
{ "Elf Wizard", Tuple.Create(4, 4, 9) },
{ "Dwarf King", Tuple.Create(5, 5, 10) },
{ "Swarm", Tuple.Create(6, 6, 11) },
{ "Shambling Sludge", Tuple.Create(6, 6, 11) },
{ "Great Lizard", Tuple.Create(7, 7, 12) },
{ "Wasp Queen", Tuple.Create(8, 7, 20) },
{ "Horned Drake", Tuple.Create(8, 7, 20) },
{ "Deathmage", Tuple.Create(5, 6, 11) },
{ "Great Coil Snake", Tuple.Create(6, 6, 12) },
{ "Lich", Tuple.Create(8, 6, 20) },
{ "Actual Lich", Tuple.Create(8, 7, 20) },
{ "Ent Ancient", Tuple.Create(9, 7, 20) },
{ "Actual Ent Ancient", Tuple.Create(9, 7, 20) },
{ "Oasis Giant", Tuple.Create(10, 8, 20) },
{ "Phoenix Lord", Tuple.Create(10, 9, 20) },
{ "Ghost King", Tuple.Create(11,10, 20) },
{ "Actual Ghost King", Tuple.Create(11,10, 20) },
{ "Cyclops God", Tuple.Create(12,10, 20) },
{ "Red Demon", Tuple.Create(14,15, 20) },
{ "Skull Shrine", Tuple.Create(13,15, 20) },
{ "Pentaract", Tuple.Create(13,15, 20) },
{ "Cube God", Tuple.Create(13,15, 20) },
{ "Grand Sphinx", Tuple.Create(13,15, 20) },
{ "Lord of the Lost Lands", Tuple.Create(13,15, 20) },
{ "Hermit God", Tuple.Create(13,15, 20) },
{ "Ghost Ship", Tuple.Create(13,15, 20) },
{ "Evil Chicken God", Tuple.Create(15,1, 20) },
{ "Bonegrind The Butcher", Tuple.Create(15,1, 20) },
{ "Dreadstump the Pirate King", Tuple.Create(15,1, 20) },
{ "Arachna the Spider Queen", Tuple.Create(15,1, 20) },
{ "Stheno the Snake Queen", Tuple.Create(15,1, 20) },
{ "Mixcoatl the Masked God", Tuple.Create(15,1, 20) },
{ "Limon the Sprite God", Tuple.Create(15,1, 20) },
{ "Septavius the Ghost God", Tuple.Create(15,1, 20) },
{ "Davy Jones", Tuple.Create(15,1, 20) },
{ "Lord Ruthven", Tuple.Create(15,1, 20) },
{ "Archdemon Malphas", Tuple.Create(15,1, 20) },
{ "Thessal the Mermaid Goddess",Tuple.Create(15,1, 20) },
{ "Dr. Terrible", Tuple.Create(15,1, 20) },
{ "Horrific Creation", Tuple.Create(15,1, 20) },
{ "Masked Party God", Tuple.Create(15,1, 20) },
{ "Stone Guardian Left", Tuple.Create(15,1, 20) },
{ "Stone Guardian Right", Tuple.Create(15,1, 20) },
{ "Oryx the Mad God 1", Tuple.Create(15,1, 20) },
{ "Oryx the Mad God 2", Tuple.Create(15,1, 20) },
{ "Oryx the Mad God 3", Tuple.Create(15,1, 20) },
};
float Dist(Entity a, Entity b)
{
var dx = a.X - b.X;
var dy = a.Y - b.Y;
return (float)Math.Sqrt(dx * dx + dy * dy);
}
Entity FindQuest()
{
Entity ret = null;
float bestScore = 0;
foreach (var i in Owner.Quests.Values
.OrderBy(quest => DistanceSquared(quest.X, quest.Y, X, Y)))
{
if (i.ObjectDesc == null || !i.ObjectDesc.Quest) continue;
Tuple<int, int, int> x;
if (!QuestDat.TryGetValue(i.ObjectDesc.ObjectId, out x)) continue;
if ((Level >= x.Item2 && Level <= x.Item3))
{
var score = (20 - Math.Abs((i.ObjectDesc.Level ?? 0) - Level)) * x.Item1 - //priority * level diff
Dist(this, i) / 100; //minus 1 for every 100 tile distance
if (score > bestScore)
{
bestScore = score;
ret = i;
}
}
}
return ret;
}
Entity questEntity;
public Entity Quest { get { return questEntity; } }
void HandleQuest(RealmTime time)
{
if (time.tickCount % 500 == 0 || questEntity == null || questEntity.Owner == null)
{
var newQuest = FindQuest();
if (newQuest != null && newQuest != questEntity)
{
Owner.Timers.Add(new WorldTimer(100, (w, t) =>
{
psr.SendPacket(new QuestObjIdPacket()
{
ObjectID = newQuest.Id
});
}));
questEntity = newQuest;
}
}
}
void CalculateFame()
{
int newFame = 0;
if (Experience < 200 * 1000) newFame = Experience / 1000;
else newFame = 200 + (Experience - 200 * 1000) / 1000;
if (newFame != Fame)
{
Fame = newFame;
int newGoal;
var state = psr.Account.Stats.ClassStates.SingleOrDefault(_ => _.ObjectType == ObjectType);
if (state != null && state******Fame > Fame)
newGoal = GetFameGoal(state******Fame);
else
newGoal = GetFameGoal(Fame);
if (newGoal > FameGoal)
{
Owner.BroadcastPacket(new NotificationPacket()
{
ObjectId = Id,
Color = new ARGB(0xFF00FF00),
Text = "Class Quest Complete!"
}, null);
Stars = GetStars();
}
FameGoal = newGoal;
UpdateCount++;
}
}
bool CheckLevelUp()
{
if (Experience - GetLevelExp(Level) >= ExperienceGoal && Level < 20)
{
Level++;
ExperienceGoal = GetExpGoal(Level);
foreach (XElement i in XmlDatas.TypeToElement[ObjectType].Elements("LevelIncrease"))
{
Random rand = new System.Random();
int min = int.Parse(i.Attribute("min").Value);
int max = int.Parse(i.Attribute("max").Value) + 1;
int limit = int.Parse(XmlDatas.TypeToElement[ObjectType].Element(i.Value).Attribute("max").Value);
int idx = StatsManager.StatsNameToIndex(i.Value);
Stats[idx] += rand.Next(min, max);
if (Stats[idx] > limit) Stats[idx] = limit;
}
HP = Stats[0] + Boost[0];
MP = Stats[1] + Boost[1];
UpdateCount++;
if (Level == 20)
Owner.BroadcastPacket(new TextPacket()
{
BubbleTime = 0,
Stars = -1,
Name = "",
Text = Name + " achieved level 20"
}, null);
questEntity = null;
return true;
}
CalculateFame();
return false;
}
public bool EnemyKilled(Enemy enemy, int exp, bool killer)
{
if (enemy == questEntity)
Owner.BroadcastPacket(new NotificationPacket()
{
ObjectId = Id,
Color = new ARGB(0xFF00FF00),
Text = "Quest Complete!"
}, null);
if (exp != 0)
{
Experience += exp;
UpdateCount++;
}
fames.Killed(enemy, killer);
return CheckLevelUp();
}
}
}