mirror of
https://bitbucket.org/Ioncannon/project-meteor-server.git
synced 2025-06-08 13:34:38 +02:00
Merge branch 'ai-open' into develop
# Conflicts: # FFXIVClassic Lobby Server/Database.cs # FFXIVClassic Map Server/Database.cs # FFXIVClassic Map Server/FFXIVClassic Map Server.csproj # FFXIVClassic Map Server/actors/chara/player/Inventory.cs # FFXIVClassic Map Server/actors/chara/player/Player.cs # FFXIVClassic Map Server/dataobjects/Session.cs # FFXIVClassic World Server/Server.cs
This commit is contained in:
commit
1e4a1cf263
402 changed files with 20078 additions and 1348 deletions
|
@ -22,6 +22,9 @@ using FFXIVClassic_Map_Server.packets.WorldPackets.Send.Group;
|
|||
using System.Threading;
|
||||
using System.Diagnostics;
|
||||
using FFXIVClassic_Map_Server.actors.director;
|
||||
using FFXIVClassic_Map_Server.actors.chara.ai;
|
||||
using FFXIVClassic_Map_Server.actors.chara;
|
||||
using FFXIVClassic_Map_Server.Actors.Chara;
|
||||
|
||||
namespace FFXIVClassic_Map_Server
|
||||
{
|
||||
|
@ -34,10 +37,18 @@ namespace FFXIVClassic_Map_Server
|
|||
private Dictionary<uint, ZoneEntrance> zoneEntranceList;
|
||||
private Dictionary<uint, ActorClass> actorClasses = new Dictionary<uint,ActorClass>();
|
||||
private Dictionary<ulong, Party> currentPlayerParties = new Dictionary<ulong, Party>(); //GroupId, Party object
|
||||
private Dictionary<uint, StatusEffect> statusEffectList = new Dictionary<uint, StatusEffect>();
|
||||
private Dictionary<ushort, BattleCommand> battleCommandList = new Dictionary<ushort, BattleCommand>();
|
||||
private Dictionary<Tuple<byte, short>, List<uint>> battleCommandIdByLevel = new Dictionary<Tuple<byte, short>, List<uint>>();//Holds battle command ids keyed by class id and level (in that order)
|
||||
private Dictionary<ushort, BattleTrait> battleTraitList = new Dictionary<ushort, BattleTrait>();
|
||||
private Dictionary<byte, List<ushort>> battleTraitIdsForClass = new Dictionary<byte, List<ushort>>();
|
||||
private Dictionary<uint, ModifierList> battleNpcGenusMods = new Dictionary<uint, ModifierList>();
|
||||
private Dictionary<uint, ModifierList> battleNpcPoolMods = new Dictionary<uint, ModifierList>();
|
||||
private Dictionary<uint, ModifierList> battleNpcSpawnMods = new Dictionary<uint, ModifierList>();
|
||||
|
||||
private Server mServer;
|
||||
|
||||
private const int MILIS_LOOPTIME = 10;
|
||||
private const int MILIS_LOOPTIME = 333;
|
||||
private Timer mZoneTimer;
|
||||
|
||||
//Content Groups
|
||||
|
@ -75,7 +86,8 @@ namespace FFXIVClassic_Map_Server
|
|||
isInn,
|
||||
canRideChocobo,
|
||||
canStealth,
|
||||
isInstanceRaid
|
||||
isInstanceRaid,
|
||||
loadNavMesh
|
||||
FROM server_zones
|
||||
WHERE zoneName IS NOT NULL and serverIp = @ip and serverPort = @port";
|
||||
|
||||
|
@ -88,7 +100,8 @@ namespace FFXIVClassic_Map_Server
|
|||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
Zone zone = new Zone(reader.GetUInt32(0), reader.GetString(1), reader.GetUInt16(2), reader.GetString(3), reader.GetUInt16(4), reader.GetUInt16(5), reader.GetUInt16(6), reader.GetBoolean(7), reader.GetBoolean(8), reader.GetBoolean(9), reader.GetBoolean(10), reader.GetBoolean(11));
|
||||
Zone zone = new Zone(reader.GetUInt32(0), reader.GetString(1), reader.GetUInt16(2), reader.GetString(3), reader.GetUInt16(4), reader.GetUInt16(5),
|
||||
reader.GetUInt16(6), reader.GetBoolean(7), reader.GetBoolean(8), reader.GetBoolean(9), reader.GetBoolean(10), reader.GetBoolean(11), reader.GetBoolean(12));
|
||||
zoneList[zone.actorId] = zone;
|
||||
count1++;
|
||||
}
|
||||
|
@ -412,6 +425,121 @@ namespace FFXIVClassic_Map_Server
|
|||
Program.Log.Info(String.Format("Loaded {0} spawn(s).", count));
|
||||
}
|
||||
|
||||
public void LoadBattleNpcs()
|
||||
{
|
||||
LoadBattleNpcModifiers("server_battlenpc_genus_mods", "genusId", battleNpcGenusMods);
|
||||
LoadBattleNpcModifiers("server_battlenpc_pool_mods", "poolId", battleNpcPoolMods);
|
||||
LoadBattleNpcModifiers("server_battlenpc_spawn_mods", "bnpcId", battleNpcSpawnMods);
|
||||
|
||||
using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD)))
|
||||
{
|
||||
try
|
||||
{
|
||||
conn.Open();
|
||||
var query = @"
|
||||
SELECT bsl.bnpcId, bsl.groupId, bsl.positionX, bsl.positionY, bsl.positionZ, bsl.rotation,
|
||||
bgr.groupId, bgr.poolId, bgr.scriptName, bgr.minLevel, bgr.maxLevel, bgr.respawnTime, bgr.hp, bgr.mp,
|
||||
bgr.dropListId, bgr.allegiance, bgr.spawnType, bgr.animationId, bgr.actorState, bgr.privateAreaName, bgr.privateAreaLevel, bgr.zoneId,
|
||||
bpo.poolId, bpo.genusId, bpo.actorClassId, bpo.currentJob, bpo.combatSkill, bpo.combatDelay, bpo.combatDmgMult, bpo.aggroType,
|
||||
bpo.immunity, bpo.linkType, bpo.skillListId, bpo.spellListId,
|
||||
bge.genusId, bge.modelSize, bge.speed, bge.kindredId, bge.detection, bge.hpp, bge.mpp, bge.tpp, bge.str, bge.vit, bge.dex,
|
||||
bge.int, bge.mnd, bge.pie, bge.att, bge.acc, bge.def, bge.eva, bge.slash, bge.pierce, bge.h2h, bge.blunt,
|
||||
bge.fire, bge.ice, bge.wind, bge.lightning, bge.earth, bge.water, bge.element
|
||||
FROM server_battlenpc_spawn_locations bsl
|
||||
INNER JOIN server_battlenpc_groups bgr ON bsl.groupId = bgr.groupId
|
||||
INNER JOIN server_battlenpc_pools bpo ON bgr.poolId = bpo.poolId
|
||||
INNER JOIN server_battlenpc_genus bge ON bpo.genusId = bge.genusId
|
||||
WHERE bgr.zoneId = @zoneId GROUP BY bsl.bnpcId;
|
||||
";
|
||||
|
||||
var count = 0;
|
||||
foreach (var zonePair in zoneList)
|
||||
{
|
||||
Area zone = zonePair.Value;
|
||||
|
||||
MySqlCommand cmd = new MySqlCommand(query, conn);
|
||||
cmd.Parameters.AddWithValue("@zoneId", zonePair.Key);
|
||||
|
||||
using (MySqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
int actorId = zone.GetActorCount() + 1;
|
||||
|
||||
// todo: add to private areas, set up immunity, mob linking,
|
||||
// - load skill/spell/drop lists, set detection icon, load pool/family/group mods
|
||||
|
||||
var battleNpc = new BattleNpc(actorId, Server.GetWorldManager().GetActorClass(reader.GetUInt32("actorClassId")),
|
||||
reader.GetString("scriptName"), zone, reader.GetFloat("positionX"), reader.GetFloat("positionY"), reader.GetFloat("positionZ"), reader.GetFloat("rotation"),
|
||||
reader.GetUInt16("actorState"), reader.GetUInt32("animationId"), "");
|
||||
|
||||
battleNpc.SetBattleNpcId(reader.GetUInt32("bnpcId"));
|
||||
|
||||
battleNpc.poolId = reader.GetUInt32("poolId");
|
||||
battleNpc.genusId = reader.GetUInt32("genusId");
|
||||
battleNpcPoolMods.TryGetValue(battleNpc.poolId, out battleNpc.poolMods);
|
||||
battleNpcGenusMods.TryGetValue(battleNpc.genusId, out battleNpc.genusMods);
|
||||
battleNpcSpawnMods.TryGetValue(battleNpc.GetBattleNpcId(), out battleNpc.spawnMods);
|
||||
|
||||
battleNpc.SetMod((uint)Modifier.Speed, reader.GetByte("speed"));
|
||||
battleNpc.neutral = reader.GetByte("aggroType") == 0;
|
||||
|
||||
battleNpc.SetDetectionType(reader.GetUInt32("detection"));
|
||||
battleNpc.kindredType = (KindredType)reader.GetUInt32("kindredId");
|
||||
battleNpc.npcSpawnType = (NpcSpawnType)reader.GetUInt32("spawnType");
|
||||
|
||||
battleNpc.charaWork.parameterSave.state_mainSkill[0] = reader.GetByte("currentJob");
|
||||
battleNpc.charaWork.parameterSave.state_mainSkillLevel = (short)Program.Random.Next(reader.GetByte("minLevel"), reader.GetByte("maxLevel"));
|
||||
|
||||
battleNpc.allegiance = (CharacterTargetingAllegiance)reader.GetByte("allegiance");
|
||||
|
||||
// todo: setup private areas and other crap and
|
||||
// set up rest of stat resists
|
||||
battleNpc.SetMod((uint)Modifier.Hp, reader.GetUInt32("hp"));
|
||||
battleNpc.SetMod((uint)Modifier.HpPercent, reader.GetUInt32("hpp"));
|
||||
battleNpc.SetMod((uint)Modifier.Mp, reader.GetUInt32("mp"));
|
||||
battleNpc.SetMod((uint)Modifier.MpPercent, reader.GetUInt32("mpp"));
|
||||
battleNpc.SetMod((uint)Modifier.TpPercent, reader.GetUInt32("tpp"));
|
||||
|
||||
battleNpc.SetMod((uint)Modifier.Strength, reader.GetUInt32("str"));
|
||||
battleNpc.SetMod((uint)Modifier.Vitality, reader.GetUInt32("vit"));
|
||||
battleNpc.SetMod((uint)Modifier.Dexterity, reader.GetUInt32("dex"));
|
||||
battleNpc.SetMod((uint)Modifier.Intelligence, reader.GetUInt32("int"));
|
||||
battleNpc.SetMod((uint)Modifier.Mind, reader.GetUInt32("mnd"));
|
||||
battleNpc.SetMod((uint)Modifier.Piety, reader.GetUInt32("pie"));
|
||||
battleNpc.SetMod((uint)Modifier.Attack, reader.GetUInt32("att"));
|
||||
battleNpc.SetMod((uint)Modifier.Accuracy, reader.GetUInt32("acc"));
|
||||
battleNpc.SetMod((uint)Modifier.Defense, reader.GetUInt32("def"));
|
||||
battleNpc.SetMod((uint)Modifier.Evasion, reader.GetUInt32("eva"));
|
||||
|
||||
battleNpc.dropListId = reader.GetUInt32("dropListId");
|
||||
battleNpc.spellListId = reader.GetUInt32("spellListId");
|
||||
battleNpc.skillListId = reader.GetUInt32("skillListId");
|
||||
|
||||
//battleNpc.SetMod((uint)Modifier.ResistFire, )
|
||||
|
||||
// todo: this is dumb
|
||||
if (battleNpc.npcSpawnType == NpcSpawnType.Normal)
|
||||
{
|
||||
zone.AddActorToZone(battleNpc);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Program.Log.Info("Loaded {0} monsters.", count);
|
||||
}
|
||||
catch (MySqlException e)
|
||||
{
|
||||
Program.Log.Error(e.ToString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
conn.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SpawnAllActors()
|
||||
{
|
||||
Program.Log.Info("Spawning actors...");
|
||||
|
@ -419,6 +547,200 @@ namespace FFXIVClassic_Map_Server
|
|||
z.SpawnAllActors(true);
|
||||
}
|
||||
|
||||
public BattleNpc SpawnBattleNpcById(uint id, Area area = null)
|
||||
{
|
||||
BattleNpc bnpc = null;
|
||||
// todo: this is stupid duplicate code and really needs to die, think of a better way later
|
||||
using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD)))
|
||||
{
|
||||
try
|
||||
{
|
||||
conn.Open();
|
||||
var query = @"
|
||||
SELECT bsl.bnpcId, bsl.groupId, bsl.positionX, bsl.positionY, bsl.positionZ, bsl.rotation,
|
||||
bgr.groupId, bgr.poolId, bgr.scriptName, bgr.minLevel, bgr.maxLevel, bgr.respawnTime, bgr.hp, bgr.mp,
|
||||
bgr.dropListId, bgr.allegiance, bgr.spawnType, bgr.animationId, bgr.actorState, bgr.privateAreaName, bgr.privateAreaLevel, bgr.zoneId,
|
||||
bpo.poolId, bpo.genusId, bpo.actorClassId, bpo.currentJob, bpo.combatSkill, bpo.combatDelay, bpo.combatDmgMult, bpo.aggroType,
|
||||
bpo.immunity, bpo.linkType, bpo.skillListId, bpo.spellListId,
|
||||
bge.genusId, bge.modelSize, bge.speed, bge.kindredId, bge.detection, bge.hpp, bge.mpp, bge.tpp, bge.str, bge.vit, bge.dex,
|
||||
bge.int, bge.mnd, bge.pie, bge.att, bge.acc, bge.def, bge.eva, bge.slash, bge.pierce, bge.h2h, bge.blunt,
|
||||
bge.fire, bge.ice, bge.wind, bge.lightning, bge.earth, bge.water, bge.element
|
||||
FROM server_battlenpc_spawn_locations bsl
|
||||
INNER JOIN server_battlenpc_groups bgr ON bsl.groupId = bgr.groupId
|
||||
INNER JOIN server_battlenpc_pools bpo ON bgr.poolId = bpo.poolId
|
||||
INNER JOIN server_battlenpc_genus bge ON bpo.genusId = bge.genusId
|
||||
WHERE bsl.bnpcId = @bnpcId GROUP BY bsl.bnpcId;
|
||||
";
|
||||
|
||||
var count = 0;
|
||||
|
||||
MySqlCommand cmd = new MySqlCommand(query, conn);
|
||||
cmd.Parameters.AddWithValue("@bnpcId", id);
|
||||
|
||||
using (MySqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
area = area ?? Server.GetWorldManager().GetZone(reader.GetUInt16("zoneId"));
|
||||
int actorId = area.GetActorCount() + 1;
|
||||
bnpc = area.GetBattleNpcById(id);
|
||||
|
||||
if (bnpc != null)
|
||||
{
|
||||
bnpc.ForceRespawn();
|
||||
break;
|
||||
}
|
||||
|
||||
// todo: add to private areas, set up immunity, mob linking,
|
||||
// - load skill/spell/drop lists, set detection icon, load pool/family/group mods
|
||||
var allegiance = (CharacterTargetingAllegiance)reader.GetByte("allegiance");
|
||||
BattleNpc battleNpc = null;
|
||||
|
||||
if (allegiance == CharacterTargetingAllegiance.Player)
|
||||
battleNpc = new Ally(actorId, Server.GetWorldManager().GetActorClass(reader.GetUInt32("actorClassId")),
|
||||
reader.GetString("scriptName"), area, reader.GetFloat("positionX"), reader.GetFloat("positionY"), reader.GetFloat("positionZ"), reader.GetFloat("rotation"),
|
||||
reader.GetUInt16("actorState"), reader.GetUInt32("animationId"), "");
|
||||
else
|
||||
battleNpc = new BattleNpc(actorId, Server.GetWorldManager().GetActorClass(reader.GetUInt32("actorClassId")),
|
||||
reader.GetString("scriptName"), area, reader.GetFloat("positionX"), reader.GetFloat("positionY"), reader.GetFloat("positionZ"), reader.GetFloat("rotation"),
|
||||
reader.GetUInt16("actorState"), reader.GetUInt32("animationId"), "");
|
||||
|
||||
battleNpc.SetBattleNpcId(reader.GetUInt32("bnpcId"));
|
||||
battleNpc.SetMod((uint)Modifier.Speed, reader.GetByte("speed"));
|
||||
battleNpc.neutral = reader.GetByte("aggroType") == 0;
|
||||
|
||||
// set mob mods
|
||||
battleNpc.poolId = reader.GetUInt32("poolId");
|
||||
battleNpc.genusId = reader.GetUInt32("genusId");
|
||||
battleNpcPoolMods.TryGetValue(battleNpc.poolId, out battleNpc.poolMods);
|
||||
battleNpcGenusMods.TryGetValue(battleNpc.genusId, out battleNpc.genusMods);
|
||||
battleNpcSpawnMods.TryGetValue(battleNpc.GetBattleNpcId(), out battleNpc.spawnMods);
|
||||
|
||||
battleNpc.SetDetectionType(reader.GetUInt32("detection"));
|
||||
battleNpc.kindredType = (KindredType)reader.GetUInt32("kindredId");
|
||||
battleNpc.npcSpawnType = (NpcSpawnType)reader.GetUInt32("spawnType");
|
||||
|
||||
battleNpc.charaWork.parameterSave.state_mainSkill[0] = reader.GetByte("currentJob");
|
||||
battleNpc.charaWork.parameterSave.state_mainSkillLevel = (short)Program.Random.Next(reader.GetByte("minLevel"), reader.GetByte("maxLevel"));
|
||||
|
||||
battleNpc.allegiance = (CharacterTargetingAllegiance)reader.GetByte("allegiance");
|
||||
|
||||
// todo: setup private areas and other crap and
|
||||
// set up rest of stat resists
|
||||
battleNpc.SetMod((uint)Modifier.Hp, reader.GetUInt32("hp"));
|
||||
battleNpc.SetMod((uint)Modifier.HpPercent, reader.GetUInt32("hpp"));
|
||||
battleNpc.SetMod((uint)Modifier.Mp, reader.GetUInt32("mp"));
|
||||
battleNpc.SetMod((uint)Modifier.MpPercent, reader.GetUInt32("mpp"));
|
||||
battleNpc.SetMod((uint)Modifier.TpPercent, reader.GetUInt32("tpp"));
|
||||
|
||||
battleNpc.SetMod((uint)Modifier.Strength, reader.GetUInt32("str"));
|
||||
battleNpc.SetMod((uint)Modifier.Vitality, reader.GetUInt32("vit"));
|
||||
battleNpc.SetMod((uint)Modifier.Dexterity, reader.GetUInt32("dex"));
|
||||
battleNpc.SetMod((uint)Modifier.Intelligence, reader.GetUInt32("int"));
|
||||
battleNpc.SetMod((uint)Modifier.Mind, reader.GetUInt32("mnd"));
|
||||
battleNpc.SetMod((uint)Modifier.Piety, reader.GetUInt32("pie"));
|
||||
battleNpc.SetMod((uint)Modifier.Attack, reader.GetUInt32("att"));
|
||||
battleNpc.SetMod((uint)Modifier.Accuracy, reader.GetUInt32("acc"));
|
||||
battleNpc.SetMod((uint)Modifier.Defense, reader.GetUInt32("def"));
|
||||
battleNpc.SetMod((uint)Modifier.Evasion, reader.GetUInt32("eva"));
|
||||
|
||||
if (battleNpc.poolMods != null)
|
||||
{
|
||||
foreach (var a in battleNpc.poolMods.mobModList)
|
||||
{
|
||||
battleNpc.SetMobMod(a.Value.id, (long)(a.Value.value));
|
||||
}
|
||||
foreach (var a in battleNpc.poolMods.modList)
|
||||
{
|
||||
battleNpc.SetMod(a.Key, (long)(a.Value.value));
|
||||
}
|
||||
}
|
||||
|
||||
if (battleNpc.genusMods != null)
|
||||
{
|
||||
foreach (var a in battleNpc.genusMods.mobModList)
|
||||
{
|
||||
battleNpc.SetMobMod(a.Key, (long)(a.Value.value));
|
||||
}
|
||||
foreach (var a in battleNpc.genusMods.modList)
|
||||
{
|
||||
battleNpc.SetMod(a.Key, (long)(a.Value.value));
|
||||
}
|
||||
}
|
||||
|
||||
if(battleNpc.spawnMods != null)
|
||||
{
|
||||
foreach (var a in battleNpc.spawnMods.mobModList)
|
||||
{
|
||||
battleNpc.SetMobMod(a.Key, (long)(a.Value.value));
|
||||
}
|
||||
|
||||
foreach (var a in battleNpc.spawnMods.modList)
|
||||
{
|
||||
battleNpc.SetMod(a.Key, (long)(a.Value.value));
|
||||
}
|
||||
}
|
||||
|
||||
battleNpc.dropListId = reader.GetUInt32("dropListId");
|
||||
battleNpc.spellListId = reader.GetUInt32("spellListId");
|
||||
battleNpc.skillListId = reader.GetUInt32("skillListId");
|
||||
battleNpc.SetBattleNpcId(reader.GetUInt32("bnpcId"));
|
||||
battleNpc.SetRespawnTime(reader.GetUInt32("respawnTime"));
|
||||
battleNpc.CalculateBaseStats();
|
||||
battleNpc.RecalculateStats();
|
||||
//battleNpc.SetMod((uint)Modifier.ResistFire, )
|
||||
bnpc = battleNpc;
|
||||
area.AddActorToZone(battleNpc);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
Program.Log.Info("WorldManager.SpawnBattleNpcById spawned BattleNpc {0}.", id);
|
||||
}
|
||||
catch (MySqlException e)
|
||||
{
|
||||
Program.Log.Error(e.ToString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
conn.Dispose();
|
||||
}
|
||||
}
|
||||
return bnpc;
|
||||
}
|
||||
|
||||
public void LoadBattleNpcModifiers(string tableName, string primaryKey, Dictionary<uint, ModifierList> list)
|
||||
{
|
||||
using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD)))
|
||||
{
|
||||
try
|
||||
{
|
||||
conn.Open();
|
||||
var query = $"SELECT {primaryKey}, modId, modVal, isMobMod FROM {tableName}";
|
||||
|
||||
MySqlCommand cmd = new MySqlCommand(query, conn);
|
||||
|
||||
using (MySqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
var id = reader.GetUInt32(primaryKey);
|
||||
ModifierList modList = list.TryGetValue(id, out modList) ? modList : new ModifierList(id);
|
||||
modList.SetModifier(reader.GetUInt16("modId"), reader.GetInt64("modVal"), reader.GetBoolean("isMobMod"));
|
||||
list[id] = modList;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (MySqlException e)
|
||||
{
|
||||
Program.Log.Error(e.ToString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
conn.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Moves the actor to the new zone if exists. No packets are sent nor position changed. Merged zone is removed.
|
||||
public void DoSeamlessZoneChange(Player player, uint destinationZoneId)
|
||||
{
|
||||
|
@ -581,7 +903,6 @@ namespace FFXIVClassic_Map_Server
|
|||
{
|
||||
oldZone.RemoveActorFromZone(player);
|
||||
}
|
||||
|
||||
newArea.AddActorToZone(player);
|
||||
|
||||
//Update player actor's properties
|
||||
|
@ -757,13 +1078,15 @@ namespace FFXIVClassic_Map_Server
|
|||
|
||||
public void ReloadZone(uint zoneId)
|
||||
{
|
||||
if (!zoneList.ContainsKey(zoneId))
|
||||
return;
|
||||
|
||||
Zone zone = zoneList[zoneId];
|
||||
//zone.clear();
|
||||
//LoadNPCs(zone.actorId);
|
||||
lock (zoneList)
|
||||
{
|
||||
if (!zoneList.ContainsKey(zoneId))
|
||||
return;
|
||||
|
||||
Zone zone = zoneList[zoneId];
|
||||
//zone.clear();
|
||||
//LoadNPCs(zone.actorId);
|
||||
}
|
||||
}
|
||||
|
||||
public ContentGroup CreateContentGroup(Director director, params Actor[] actors)
|
||||
|
@ -1005,11 +1328,17 @@ namespace FFXIVClassic_Map_Server
|
|||
}
|
||||
|
||||
public void ZoneThreadLoop(Object state)
|
||||
{
|
||||
{
|
||||
// todo: coroutines GetActorInWorld stuff seems to be causing it to hang
|
||||
// todo: spawn new thread for each zone on startup
|
||||
lock (zoneList)
|
||||
{
|
||||
foreach (Area area in zoneList.Values)
|
||||
area.Update(MILIS_LOOPTIME);
|
||||
Program.Tick = DateTime.Now;
|
||||
foreach (Zone zone in zoneList.Values)
|
||||
{
|
||||
zone.Update(Program.Tick);
|
||||
}
|
||||
Program.LastTick = Program.Tick;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1031,39 +1360,52 @@ namespace FFXIVClassic_Map_Server
|
|||
|
||||
public Actor GetActorInWorld(uint charId)
|
||||
{
|
||||
foreach (Zone zone in zoneList.Values)
|
||||
lock (zoneList)
|
||||
{
|
||||
Actor a = zone.FindActorInZone(charId);
|
||||
if (a != null)
|
||||
return a;
|
||||
foreach (Zone zone in zoneList.Values)
|
||||
{
|
||||
Actor a = zone.FindActorInZone(charId);
|
||||
if (a != null)
|
||||
return a;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Actor GetActorInWorldByUniqueId(string uid)
|
||||
{
|
||||
foreach (Zone zone in zoneList.Values)
|
||||
lock (zoneList)
|
||||
{
|
||||
Actor a = zone.FindActorInZoneByUniqueID(uid);
|
||||
if (a != null)
|
||||
return a;
|
||||
foreach (Zone zone in zoneList.Values)
|
||||
{
|
||||
Actor a = zone.FindActorInZoneByUniqueID(uid);
|
||||
if (a != null)
|
||||
return a;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Zone GetZone(uint zoneId)
|
||||
{
|
||||
if (!zoneList.ContainsKey(zoneId))
|
||||
return null;
|
||||
return zoneList[zoneId];
|
||||
lock (zoneList)
|
||||
{
|
||||
if (!zoneList.ContainsKey(zoneId))
|
||||
return null;
|
||||
|
||||
return zoneList[zoneId];
|
||||
}
|
||||
}
|
||||
|
||||
public PrivateArea GetPrivateArea(uint zoneId, string privateArea, uint privateAreaType)
|
||||
{
|
||||
if (!zoneList.ContainsKey(zoneId))
|
||||
return null;
|
||||
lock (zoneList)
|
||||
{
|
||||
if (!zoneList.ContainsKey(zoneId))
|
||||
return null;
|
||||
|
||||
return zoneList[zoneId].GetPrivateArea(privateArea, privateAreaType);
|
||||
return zoneList[zoneId].GetPrivateArea(privateArea, privateAreaType);
|
||||
}
|
||||
}
|
||||
|
||||
public WorldMaster GetActor()
|
||||
|
@ -1115,5 +1457,52 @@ namespace FFXIVClassic_Map_Server
|
|||
else
|
||||
return null;
|
||||
}
|
||||
public void LoadStatusEffects()
|
||||
{
|
||||
statusEffectList = Database.LoadGlobalStatusEffectList();
|
||||
}
|
||||
|
||||
public StatusEffect GetStatusEffect(uint id)
|
||||
{
|
||||
StatusEffect statusEffect;
|
||||
|
||||
return statusEffectList.TryGetValue(id, out statusEffect) ? new StatusEffect(null, statusEffect) : null;
|
||||
}
|
||||
|
||||
public void LoadBattleCommands()
|
||||
{
|
||||
Database.LoadGlobalBattleCommandList(battleCommandList, battleCommandIdByLevel);
|
||||
}
|
||||
|
||||
public void LoadBattleTraits()
|
||||
{
|
||||
Database.LoadGlobalBattleTraitList(battleTraitList, battleTraitIdsForClass);
|
||||
}
|
||||
|
||||
public BattleCommand GetBattleCommand(uint id)
|
||||
{
|
||||
BattleCommand battleCommand;
|
||||
return battleCommandList.TryGetValue((ushort)id, out battleCommand) ? battleCommand.Clone() : null;
|
||||
}
|
||||
|
||||
public List<uint> GetBattleCommandIdByLevel(byte classId, short level)
|
||||
{
|
||||
List<uint> ids;
|
||||
return battleCommandIdByLevel.TryGetValue(Tuple.Create(classId, level), out ids) ? ids : new List<uint>();
|
||||
}
|
||||
|
||||
public BattleTrait GetBattleTrait(ushort id)
|
||||
{
|
||||
BattleTrait battleTrait;
|
||||
battleTraitList.TryGetValue(id, out battleTrait);
|
||||
return battleTrait;
|
||||
}
|
||||
|
||||
public List<ushort> GetAllBattleTraitIdsForClass(byte classId)
|
||||
{
|
||||
List<ushort> ids;
|
||||
return battleTraitIdsForClass.TryGetValue(classId, out ids) ? ids : new List<ushort>();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue