1
Fork 0
mirror of https://bitbucket.org/Ioncannon/project-meteor-server.git synced 2025-04-23 13:17:45 +00:00

Reworked zones to allow for isolated zones (IE Opening Zone) and private area instances.

This commit is contained in:
Filip Maj 2016-02-07 13:05:54 -05:00
parent c83b4a12b9
commit 42ba95b69d
14 changed files with 482 additions and 317 deletions

View file

@ -61,6 +61,8 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="actors\area\PrivateArea.cs" />
<Compile Include="actors\area\Zone.cs" />
<Compile Include="actors\chara\npc\NpcWork.cs" />
<Compile Include="actors\chara\AetheryteWork.cs" />
<Compile Include="actors\chara\Work.cs" />
@ -221,7 +223,7 @@
<Compile Include="utils\ActorPropertyPacketUtil.cs" />
<Compile Include="utils\CharacterUtils.cs" />
<Compile Include="utils\SQLGeneration.cs" />
<Compile Include="actors\area\Zone.cs" />
<Compile Include="actors\area\Area.cs" />
<Compile Include="WorldManager.cs" />
</ItemGroup>
<ItemGroup>

View file

@ -195,14 +195,7 @@ namespace FFXIVClassic_Lobby_Server
//subpacket.debugPrintSubPacket();
UpdatePlayerPositionPacket posUpdate = new UpdatePlayerPositionPacket(subpacket.data);
player.updatePlayerActorPosition(posUpdate.x, posUpdate.y, posUpdate.z, posUpdate.rot, posUpdate.moveState);
//Update Instance
List<BasePacket> instanceUpdatePackets = player.updateInstance(player.getActor().zone.getActorsAroundActor(player.getActor(), 50));
foreach (BasePacket bp in instanceUpdatePackets)
{
// bp.debugPrintPacket();
client.queuePacket(bp);
}
player.getActor().sendInstanceUpdate();
break;
//Set Target
case 0x00CD:
@ -221,6 +214,19 @@ namespace FFXIVClassic_Lobby_Server
case 0x012D:
subpacket.debugPrintSubPacket();
EventStartPacket eventStart = new EventStartPacket(subpacket.data);
/*
if (eventStart.error != null)
{
player.errorMessage += eventStart.error;
if (eventStart.errorIndex == eventStart.errorNum - 1)
Log.error("\n"+player.errorMessage);
break;
}
*/
player.getActor().eventCurrentOwner = eventStart.scriptOwnerActorID;
player.getActor().eventCurrentStarter = eventStart.eventStarter;
@ -230,8 +236,11 @@ namespace FFXIVClassic_Lobby_Server
{
ownerActor = mServer.GetWorldManager().GetActorInWorld(player.getActor().eventCurrentOwner);
if (ownerActor == null)
{
Log.debug(String.Format("\n===Event START===\nCould not find actor 0x{0:X} for event started by caller: 0x{1:X}\nEvent Starter: {2}\nParams: {3}", eventStart.actorID, eventStart.scriptOwnerActorID, eventStart.eventStarter, LuaUtils.dumpParams(eventStart.luaParams)));
break;
}
}
mServer.GetLuaEngine().doActorOnEventStarted(player.getActor(), ownerActor, eventStart);

View file

@ -429,7 +429,12 @@ namespace FFXIVClassic_Lobby_Server
{
Log.info(String.Format("Got request to reset zone: {0}", client.getActor().zoneId));
if (client != null)
{
client.getActor().zone.clear();
client.getActor().zone.addActorToZone(client.getActor());
client.getActor().sendInstanceUpdate();
client.queuePacket(BasePacket.createPacket(SendMessagePacket.buildPacket(client.actorID, client.actorID, SendMessagePacket.MESSAGE_TYPE_GENERAL_INFO, "", String.Format("Resting zone {0}...", client.getActor().zoneId)), true, false));
}
mWorldManager.reloadZone(client.getActor().zoneId);
}
}
@ -462,7 +467,7 @@ namespace FFXIVClassic_Lobby_Server
doWarp(client, split[1]);
}
}
if (split.Length >= 3)
if (split.Length >= 5)
{
if (split[0].Equals("warp"))
{

View file

@ -1,10 +1,12 @@
using FFXIVClassic_Lobby_Server;
using FFXIVClassic_Lobby_Server.common;
using FFXIVClassic_Map_Server.actors.area;
using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.common.EfficientHashTables;
using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Map_Server.dataobjects.chara;
using FFXIVClassic_Map_Server.packets.send;
using FFXIVClassic_Map_Server.packets.send.actor;
using FFXIVClassic_Map_Server.packets.send.login;
using MySql.Data.MySqlClient;
using System;
@ -42,11 +44,13 @@ namespace FFXIVClassic_Map_Server
string query = @"
SELECT
id,
regionId,
zoneName,
regionId,
className,
dayMusic,
nightMusic,
battleMusic,
isIsolated,
isInn,
canRideChocobo,
canStealth,
@ -60,7 +64,7 @@ namespace FFXIVClassic_Map_Server
{
while (reader.Read())
{
Zone zone = new Zone(reader.GetUInt32(0), reader.GetString(2), reader.GetUInt16(1), reader.GetUInt16(3), reader.GetUInt16(4), reader.GetUInt16(5), reader.GetBoolean(6), reader.GetBoolean(7), reader.GetBoolean(8), reader.GetBoolean(9));
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));
zoneList[zone.actorId] = zone;
count++;
}
@ -147,7 +151,7 @@ namespace FFXIVClassic_Map_Server
actorClassName,
eventConditions
FROM gamedata_actor_class
WHERE name is not NULL
WHERE name is not NULL AND zoneId > 0
";
MySqlCommand cmd = new MySqlCommand(query, conn);
@ -216,7 +220,7 @@ namespace FFXIVClassic_Map_Server
customDisplayName,
actorClassName,
eventConditions
FROM gamedata_actorclass
FROM gamedata_actor_class
WHERE name is not NULL AND zoneId = @zoneId
";
@ -228,14 +232,14 @@ namespace FFXIVClassic_Map_Server
while (reader.Read())
{
string customName = null;
if (reader.IsDBNull(10))
if (!reader.IsDBNull(10))
customName = reader.GetString(10);
Npc npc = new Npc(reader.GetUInt32(0), reader.GetString(1), reader.GetUInt32(2), reader.GetFloat(3), reader.GetFloat(4), reader.GetFloat(5), reader.GetFloat(6), reader.GetUInt16(7), reader.GetUInt32(8), reader.GetUInt32(9), customName, reader.GetString(11));
if (!reader.IsDBNull(11))
if (!reader.IsDBNull(12))
{
string eventConditions = reader.GetString(11);
string eventConditions = reader.GetString(12);
npc.loadEventConditions(eventConditions);
}
@ -327,8 +331,11 @@ namespace FFXIVClassic_Map_Server
player.rotation = spawnRotation;
//Send packets
player.playerSession.queuePacket(_0xE2Packet.buildPacket(0x6c, 0xF), true, false);
player.playerSession.queuePacket(DeleteAllActorsPacket.buildPacket(player.actorId), true, false);
player.playerSession.queuePacket(_0xE2Packet.buildPacket(player.actorId, 0x0), true, false);
player.sendZoneInPackets(this, spawnType);
player.playerSession.clearInstance();
player.sendInstanceUpdate();
}
//Login Zone In
@ -346,8 +353,11 @@ namespace FFXIVClassic_Map_Server
zone.addActorToZone(player);
//Send packets
player.playerSession.queuePacket(DeleteAllActorsPacket.buildPacket(player.actorId), true, false);
player.playerSession.queuePacket(_0x2Packet.buildPacket(player.actorId), true, false);
player.sendZoneInPackets(this, 0x1);
player.playerSession.clearInstance();
player.sendInstanceUpdate();
}
public void reloadZone(uint zoneId)
@ -356,7 +366,7 @@ namespace FFXIVClassic_Map_Server
return;
Zone zone = zoneList[zoneId];
zone.clear();
//zone.clear();
LoadNPCs(zone.actorId);
}

View file

@ -2,6 +2,7 @@
using FFXIVClassic_Lobby_Server.common;
using FFXIVClassic_Lobby_Server.packets;
using FFXIVClassic_Map_Server.actors;
using FFXIVClassic_Map_Server.actors.area;
using FFXIVClassic_Map_Server.dataobjects.chara;
using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Map_Server.packets.send.actor;

View file

@ -0,0 +1,322 @@
using FFXIVClassic_Lobby_Server.common;
using FFXIVClassic_Lobby_Server.packets;
using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Map_Server.dataobjects.chara;
using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Map_Server.packets.send.actor;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.Actors
{
class Area : Actor
{
public string zoneName;
public ushort regionId;
public bool isIsolated, canStealth, isInn, canRideChocobo, isInstanceRaid;
public ushort weatherNormal, weatherCommon, weatherRare;
public ushort bgmDay, bgmNight, bgmBattle;
private string classPath;
public int boundingGridSize = 50;
public int minX = -1000, minY = -1000, maxX = 1000, maxY = 1000;
private int numXBlocks, numYBlocks;
private int halfWidth, halfHeight;
private Dictionary<uint, Actor> mActorList = new Dictionary<uint,Actor>();
private List<Actor>[,] mActorBlock;
public Area(uint id, string zoneName, ushort regionId, string className, ushort bgmDay, ushort bgmNight, ushort bgmBattle, bool isIsolated, bool isInn, bool canRideChocobo, bool canStealth, bool isInstanceRaid)
: base(id)
{
this.zoneName = zoneName;
this.regionId = regionId;
this.canStealth = canStealth;
this.isIsolated = isIsolated;
this.isInn = isInn;
this.canRideChocobo = canRideChocobo;
this.isInstanceRaid = isInstanceRaid;
this.bgmDay = bgmDay;
this.bgmNight = bgmNight;
this.bgmBattle = bgmBattle;
this.displayNameId = 0;
this.customDisplayName = "_areaMaster";
this.actorName = String.Format("_areaMaster@{0:X5}",id<<8);
this.className = className;
numXBlocks = (maxX - minX) / boundingGridSize;
numYBlocks = (maxY - minY) / boundingGridSize;
mActorBlock = new List<Actor>[numXBlocks, numYBlocks];
halfWidth = numXBlocks / 2;
halfHeight = numYBlocks / 2;
for (int y = 0; y < numYBlocks; y++)
{
for (int x = 0; x < numXBlocks; x++ )
{
mActorBlock[x, y] = new List<Actor>();
}
}
}
public override SubPacket createScriptBindPacket(uint playerActorId)
{
List<LuaParam> lParams;
lParams = LuaUtils.createLuaParamList(classPath, false, true, zoneName, "/Area/Zone/ZoneDefault", -1, (byte)1, true, false, false, false, false, false, false, false);
return ActorInstantiatePacket.buildPacket(actorId, playerActorId, actorName, "ZoneDefault", lParams);
}
public override BasePacket getSpawnPackets(uint playerActorId)
{
List<SubPacket> subpackets = new List<SubPacket>();
subpackets.Add(createAddActorPacket(playerActorId, 0));
subpackets.Add(createSpeedPacket(playerActorId));
subpackets.Add(createSpawnPositonPacket(playerActorId, 0x1));
subpackets.Add(createNamePacket(playerActorId));
subpackets.Add(createStatePacket(playerActorId));
subpackets.Add(createIsZoneingPacket(playerActorId));
subpackets.Add(createScriptBindPacket(playerActorId));
subpackets[6].debugPrintSubPacket();
return BasePacket.createPacket(subpackets, true, false);
}
#region Actor Management
public void addActorToZone(Actor actor)
{
if (!mActorList.ContainsKey(actor.actorId))
mActorList.Add(actor.actorId, actor);
int gridX = (int)actor.positionX / boundingGridSize;
int gridY = (int)actor.positionZ / boundingGridSize;
gridX += halfWidth;
gridY += halfHeight;
//Boundries
if (gridX < 0)
gridX = 0;
if (gridX >= numXBlocks)
gridX = numXBlocks - 1;
if (gridY < 0)
gridY = 0;
if (gridY >= numYBlocks)
gridY = numYBlocks - 1;
lock (mActorBlock)
mActorBlock[gridX, gridY].Add(actor);
}
public void removeActorToZone(Actor actor)
{
mActorList.Remove(actor.actorId);
int gridX = (int)actor.positionX / boundingGridSize;
int gridY = (int)actor.positionZ / boundingGridSize;
gridX += halfWidth;
gridY += halfHeight;
//Boundries
if (gridX < 0)
gridX = 0;
if (gridX >= numXBlocks)
gridX = numXBlocks - 1;
if (gridY < 0)
gridY = 0;
if (gridY >= numYBlocks)
gridY = numYBlocks - 1;
lock (mActorBlock)
mActorBlock[gridX, gridY].Remove(actor);
}
public void updateActorPosition(Actor actor)
{
int gridX = (int)actor.positionX / boundingGridSize;
int gridY = (int)actor.positionZ / boundingGridSize;
gridX += halfWidth;
gridY += halfHeight;
//Boundries
if (gridX < 0)
gridX = 0;
if (gridX >= numXBlocks)
gridX = numXBlocks - 1;
if (gridY < 0)
gridY = 0;
if (gridY >= numYBlocks)
gridY = numYBlocks - 1;
int gridOldX = (int)actor.oldPositionX / boundingGridSize;
int gridOldY = (int)actor.oldPositionZ / boundingGridSize;
gridOldX += halfWidth;
gridOldY += halfHeight;
//Boundries
if (gridOldX < 0)
gridOldX = 0;
if (gridOldX >= numXBlocks)
gridOldX = numXBlocks - 1;
if (gridOldY < 0)
gridOldY = 0;
if (gridOldY >= numYBlocks)
gridOldY = numYBlocks - 1;
//Still in same block
if (gridX == gridOldX && gridY == gridOldY)
return;
lock (mActorBlock)
{
mActorBlock[gridOldX, gridOldY].Remove(actor);
mActorBlock[gridX, gridY].Add(actor);
}
}
public List<Actor> getActorsAroundPoint(float x, float y, int checkDistance)
{
checkDistance /= boundingGridSize;
int gridX = (int)x/boundingGridSize;
int gridY = (int)y/boundingGridSize;
gridX += halfWidth;
gridY += halfHeight;
//Boundries
if (gridX < 0)
gridX = 0;
if (gridX >= numXBlocks)
gridX = numXBlocks - 1;
if (gridY < 0)
gridY = 0;
if (gridY >= numYBlocks)
gridY = numYBlocks - 1;
List<Actor> result = new List<Actor>();
for (int gx = gridX - checkDistance; gx <= gridX + checkDistance; gx++)
{
for (int gy = gridY - checkDistance; gy <= gridY + checkDistance; gy++)
{
result.AddRange(mActorBlock[gx, gy]);
}
}
return result;
}
public List<Actor> getActorsAroundActor(Actor actor, int checkDistance)
{
checkDistance /= boundingGridSize;
int gridX = (int)actor.positionX / boundingGridSize;
int gridY = (int)actor.positionZ / boundingGridSize;
gridX += halfWidth;
gridY += halfHeight;
//Boundries
if (gridX < 0)
gridX = 0;
if (gridX >= numXBlocks)
gridX = numXBlocks - 1;
if (gridY < 0)
gridY = 0;
if (gridY >= numYBlocks)
gridY = numYBlocks - 1;
List<Actor> result = new List<Actor>();
for (int gy = ((gridY - checkDistance) < 0 ? 0 : (gridY - checkDistance)); gy <= ((gridY + checkDistance) >= numYBlocks ? numYBlocks - 1 : (gridY + checkDistance)); gy++)
{
for (int gx = ((gridX - checkDistance) < 0 ? 0 : (gridX - checkDistance)); gx <= ((gridX + checkDistance) >= numXBlocks ? numXBlocks - 1 : (gridX + checkDistance)); gx++)
{
result.AddRange(mActorBlock[gx, gy]);
}
}
//Remove players if isolation zone
if (isIsolated)
{
for (int i = 0; i < result.Count; i++)
{
if (result[i] is Player)
result.RemoveAt(i);
}
}
return result;
}
#endregion
public Actor FindActorInZone(uint id)
{
if (!mActorList.ContainsKey(id))
return null;
return mActorList[id];
}
public Player FindPCInZone(string name)
{
foreach (Actor a in mActorList.Values)
{
if (a is Player)
{
if (((Player)a).customDisplayName.Equals(name))
return (Player)a;
}
}
return null;
}
public Player FindPCInZone(uint id)
{
if (!mActorList.ContainsKey(id))
return null;
return (Player)mActorList[id];
}
public void clear()
{
//Clear All
mActorList.Clear();
for (int y = 0; y < numYBlocks; y++)
{
for (int x = 0; x < numXBlocks; x++)
{
mActorBlock[x, y].Clear();
}
}
}
public void broadcastPacketAroundActor(Actor actor, SubPacket packet)
{
List<Actor> aroundActor = getActorsAroundActor(actor, 50);
foreach (Actor a in aroundActor)
{
if (a is Player)
{
SubPacket clonedPacket = new SubPacket(packet, actor.actorId);
Player p = (Player)a;
p.queuePacket(clonedPacket);
}
}
}
}
}

View file

@ -0,0 +1,32 @@
using FFXIVClassic_Lobby_Server.packets;
using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Map_Server.packets.send.actor;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.area
{
class PrivateArea : Area
{
private Zone parentZone;
private string privateAreaName;
public PrivateArea(Zone parent, uint id, string className, string privateAreaName,ushort bgmDay, ushort bgmNight, ushort bgmBattle)
: base(id, parent.zoneName, parent.regionId, className, bgmDay, bgmNight, bgmBattle, parent.isIsolated, parent.isInn, parent.canRideChocobo, parent.canStealth, true)
{
this.parentZone = parent;
this.privateAreaName = privateAreaName;
}
public override SubPacket createScriptBindPacket(uint playerActorId)
{
List<LuaParam> lParams;
lParams = LuaUtils.createLuaParamList("/Area/PrivateArea/" + className, false, true, zoneName, privateAreaName, 0xE1, canRideChocobo ? (byte)1 : (byte)0, canStealth, isInn, false, false, false, false, false, false);
return ActorInstantiatePacket.buildPacket(actorId, playerActorId, actorName, className, lParams);
}
}
}

View file

@ -1,7 +1,5 @@
using FFXIVClassic_Lobby_Server.common;
using FFXIVClassic_Lobby_Server.packets;
using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Map_Server.dataobjects.chara;
using FFXIVClassic_Lobby_Server.packets;
using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Map_Server.packets.send.actor;
using System;
@ -10,299 +8,40 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.Actors
namespace FFXIVClassic_Map_Server.actors.area
{
class Zone : Actor
class Zone : Area
{
public string zoneName;
public ushort regionId;
public bool canStealth, isInn, canRideChocobo, isInstanceRaid;
public ushort weatherNormal, weatherCommon, weatherRare;
public ushort bgmDay, bgmNight, bgmBattle;
Dictionary<string, Dictionary<uint, PrivateArea>> privateAreas = new Dictionary<string, Dictionary<uint, PrivateArea>>();
public int boundingGridSize = 50;
public int minX = -1000, minY = -1000, maxX = 1000, maxY = 1000;
private int numXBlocks, numYBlocks;
private int halfWidth, halfHeight;
private Dictionary<uint, Actor> mActorList = new Dictionary<uint,Actor>();
private List<Actor>[,] mActorBlock;
public Zone(uint id, string zoneName, ushort regionId, ushort bgmDay, ushort bgmNight, ushort bgmBattle, bool isInn, bool canRideChocobo, bool canStealth, bool isInstanceRaid)
: base(id)
public Zone(uint id, string zoneName, ushort regionId, string className, ushort bgmDay, ushort bgmNight, ushort bgmBattle, bool isIsolated, bool isInn, bool canRideChocobo, bool canStealth, bool isInstanceRaid)
: base(id, zoneName, regionId, className, bgmDay, bgmNight, bgmBattle, isIsolated, isInn, canRideChocobo, canStealth, isInstanceRaid)
{
this.zoneName = zoneName;
this.regionId = regionId;
this.canStealth = canStealth;
this.isInn = isInn;
this.canRideChocobo = canRideChocobo;
this.isInstanceRaid = isInstanceRaid;
this.bgmDay = bgmDay;
this.bgmNight = bgmNight;
this.bgmBattle = bgmBattle;
this.displayNameId = 0;
this.customDisplayName = "_areaMaster";
this.actorName = String.Format("_areaMaster@{0:X5}",id<<8);
this.className = "ZoneMasterPrvI0";
numXBlocks = (maxX - minX) / boundingGridSize;
numYBlocks = (maxY - minY) / boundingGridSize;
mActorBlock = new List<Actor>[numXBlocks, numYBlocks];
halfWidth = numXBlocks / 2;
halfHeight = numYBlocks / 2;
for (int y = 0; y < numYBlocks; y++)
{
for (int x = 0; x < numXBlocks; x++ )
{
mActorBlock[x, y] = new List<Actor>();
}
}
public PrivateArea getPrivateArea(string type, uint number)
{
if (privateAreas.ContainsKey(type))
{
Dictionary<uint, PrivateArea> instances = privateAreas[type];
if (instances.ContainsKey(number))
return instances[number];
else
return null;
}
else
return null;
}
public override SubPacket createScriptBindPacket(uint playerActorId)
{
bool isEntranceDesion = false;
List<LuaParam> lParams;
lParams = LuaUtils.createLuaParamList("/Area/Zone/ZoneMasterPrvI0", false, true, zoneName, "", -1, canRideChocobo ? (byte)1 : (byte)0, canStealth, isInn, false, false, false, false, false, false);
lParams = LuaUtils.createLuaParamList("/Area/Zone/" + className, false, true, zoneName, "", -1, canRideChocobo ? (byte)1 : (byte)0, canStealth, isInn, false, false, false, true, isInstanceRaid, isEntranceDesion);
return ActorInstantiatePacket.buildPacket(actorId, playerActorId, actorName, className, lParams);
}
public override BasePacket getSpawnPackets(uint playerActorId)
{
List<SubPacket> subpackets = new List<SubPacket>();
subpackets.Add(createAddActorPacket(playerActorId, 0));
subpackets.Add(createSpeedPacket(playerActorId));
subpackets.Add(createSpawnPositonPacket(playerActorId, 0x1));
subpackets.Add(createNamePacket(playerActorId));
subpackets.Add(createStatePacket(playerActorId));
subpackets.Add(createIsZoneingPacket(playerActorId));
subpackets.Add(createScriptBindPacket(playerActorId));
subpackets[6].debugPrintSubPacket();
return BasePacket.createPacket(subpackets, true, false);
}
#region Actor Management
public void addActorToZone(Actor actor)
{
if (!mActorList.ContainsKey(actor.actorId))
mActorList.Add(actor.actorId, actor);
int gridX = (int)actor.positionX / boundingGridSize;
int gridY = (int)actor.positionZ / boundingGridSize;
gridX += halfWidth;
gridY += halfHeight;
//Boundries
if (gridX < 0)
gridX = 0;
if (gridX >= numXBlocks)
gridX = numXBlocks - 1;
if (gridY < 0)
gridY = 0;
if (gridY >= numYBlocks)
gridY = numYBlocks - 1;
lock (mActorBlock)
mActorBlock[gridX, gridY].Add(actor);
}
public void removeActorToZone(Actor actor)
{
mActorList.Remove(actor.actorId);
int gridX = (int)actor.positionX / boundingGridSize;
int gridY = (int)actor.positionZ / boundingGridSize;
gridX += halfWidth;
gridY += halfHeight;
//Boundries
if (gridX < 0)
gridX = 0;
if (gridX >= numXBlocks)
gridX = numXBlocks - 1;
if (gridY < 0)
gridY = 0;
if (gridY >= numYBlocks)
gridY = numYBlocks - 1;
lock (mActorBlock)
mActorBlock[gridX, gridY].Remove(actor);
}
public void updateActorPosition(Actor actor)
{
int gridX = (int)actor.positionX / boundingGridSize;
int gridY = (int)actor.positionZ / boundingGridSize;
gridX += halfWidth;
gridY += halfHeight;
//Boundries
if (gridX < 0)
gridX = 0;
if (gridX >= numXBlocks)
gridX = numXBlocks - 1;
if (gridY < 0)
gridY = 0;
if (gridY >= numYBlocks)
gridY = numYBlocks - 1;
int gridOldX = (int)actor.oldPositionX / boundingGridSize;
int gridOldY = (int)actor.oldPositionZ / boundingGridSize;
gridOldX += halfWidth;
gridOldY += halfHeight;
//Boundries
if (gridOldX < 0)
gridOldX = 0;
if (gridOldX >= numXBlocks)
gridOldX = numXBlocks - 1;
if (gridOldY < 0)
gridOldY = 0;
if (gridOldY >= numYBlocks)
gridOldY = numYBlocks - 1;
//Still in same block
if (gridX == gridOldX && gridY == gridOldY)
return;
lock (mActorBlock)
{
mActorBlock[gridOldX, gridOldY].Remove(actor);
mActorBlock[gridX, gridY].Add(actor);
}
}
public List<Actor> getActorsAroundPoint(float x, float y, int checkDistance)
{
checkDistance /= boundingGridSize;
int gridX = (int)x/boundingGridSize;
int gridY = (int)y/boundingGridSize;
gridX += halfWidth;
gridY += halfHeight;
//Boundries
if (gridX < 0)
gridX = 0;
if (gridX >= numXBlocks)
gridX = numXBlocks - 1;
if (gridY < 0)
gridY = 0;
if (gridY >= numYBlocks)
gridY = numYBlocks - 1;
List<Actor> result = new List<Actor>();
for (int gx = gridX - checkDistance; gx <= gridX + checkDistance; gx++)
{
for (int gy = gridY - checkDistance; gy <= gridY + checkDistance; gy++)
{
result.AddRange(mActorBlock[gx, gy]);
}
}
return result;
}
public List<Actor> getActorsAroundActor(Actor actor, int checkDistance)
{
checkDistance /= boundingGridSize;
int gridX = (int)actor.positionX / boundingGridSize;
int gridY = (int)actor.positionZ / boundingGridSize;
gridX += halfWidth;
gridY += halfHeight;
//Boundries
if (gridX < 0)
gridX = 0;
if (gridX >= numXBlocks)
gridX = numXBlocks - 1;
if (gridY < 0)
gridY = 0;
if (gridY >= numYBlocks)
gridY = numYBlocks - 1;
List<Actor> result = new List<Actor>();
for (int gy = ((gridY - checkDistance) < 0 ? 0 : (gridY - checkDistance)); gy <= ((gridY + checkDistance) >= numYBlocks ? numYBlocks - 1 : (gridY + checkDistance)); gy++)
{
for (int gx = ((gridX - checkDistance) < 0 ? 0 : (gridX - checkDistance)); gx <= ((gridX + checkDistance) >= numXBlocks ? numXBlocks - 1 : (gridX + checkDistance)); gx++)
{
result.AddRange(mActorBlock[gx, gy]);
}
}
return result;
}
#endregion
public Actor FindActorInZone(uint id)
{
if (!mActorList.ContainsKey(id))
return null;
return mActorList[id];
}
public Player FindPCInZone(string name)
{
foreach (Actor a in mActorList.Values)
{
if (a is Player)
{
if (((Player)a).customDisplayName.Equals(name))
return (Player)a;
}
}
return null;
}
public Player FindPCInZone(uint id)
{
if (!mActorList.ContainsKey(id))
return null;
return (Player)mActorList[id];
}
public void clear()
{
//Clear All
mActorList.Clear();
for (int y = 0; y < numYBlocks; y++)
{
for (int x = 0; x < numXBlocks; x++)
{
mActorBlock[x, y].Clear();
}
}
}
public void broadcastPacketAroundActor(Actor actor, SubPacket packet)
{
List<Actor> aroundActor = getActorsAroundActor(actor, 50);
foreach (Actor a in aroundActor)
{
if (a is Player)
{
SubPacket clonedPacket = new SubPacket(packet, actor.actorId);
Player p = (Player)a;
p.queuePacket(clonedPacket);
}
}
}
}
}

View file

@ -1,6 +1,7 @@
using FFXIVClassic_Lobby_Server;
using FFXIVClassic_Lobby_Server.common;
using FFXIVClassic_Lobby_Server.packets;
using FFXIVClassic_Map_Server.actors.area;
using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Map_Server.dataobjects.chara;
using FFXIVClassic_Map_Server.lua;
@ -87,8 +88,9 @@ namespace FFXIVClassic_Map_Server.Actors
charaWork.property[4] = 1;
charaWork.command[0] = 0xA0F00000 | 21001;
charaWork.command[1] = 0xA0F00000 | 21002;
charaWork.command[2] = 0xA0F00000 | 12003;
charaWork.command[1] = 0xA0F00000 | 21001;
charaWork.command[2] = 0xA0F00000 | 21002;
charaWork.command[3] = 0xA0F00000 | 12004;
charaWork.command[4] = 0xA0F00000 | 21005;
charaWork.command[5] = 0xA0F00000 | 21006;
@ -103,9 +105,6 @@ namespace FFXIVClassic_Map_Server.Actors
charaWork.command[14] = 0xA0F00000 | 29497;
charaWork.command[15] = 0xA0F00000 | 22015;
charaWork.command[32] = 0xA0F00000 | 27155;
//charaWork.command[33] = 0xA0F00000 | 27150;
charaWork.command[34] = 0xA0F00000 | 27300;
charaWork.commandAcquired[27150 - 26000] = true;
@ -120,10 +119,15 @@ namespace FFXIVClassic_Map_Server.Actors
charaWork.battleTemp.generalParameter[3] = 1;
charaWork.eventSave.bazaarTax = 5;
charaWork.battleSave.potencial = 6.6f;
charaWork.commandCategory[0] = 1;
charaWork.commandCategory[1] = 1;
charaWork.parameterSave.commandSlot_compatibility[0] = true;
charaWork.parameterSave.commandSlot_compatibility[1] = true;
charaWork.commandBorder = 0x20;
Database.loadPlayerCharacter(this);
@ -737,5 +741,18 @@ namespace FFXIVClassic_Map_Server.Actors
return eventMenuId;
}
internal void sendInstanceUpdate()
{
//Update Instance
List<BasePacket> instanceUpdatePackets = playerSession.updateInstance(zone.getActorsAroundActor(this, 50));
foreach (BasePacket bp in instanceUpdatePackets)
{
// bp.debugPrintPacket();
queuePacket(bp);
}
}
}
}

View file

@ -14,7 +14,7 @@ namespace FFXIVClassic_Map_Server.Actors
{
private uint weatherId;
public WeatherDirector(uint weatherId, Zone zone)
public WeatherDirector(uint weatherId)
: base(0x5FF80002)
{
this.weatherId = weatherId;

View file

@ -19,6 +19,8 @@ namespace FFXIVClassic_Map_Server.dataobjects
private ClientConnection zoneConnection;
private ClientConnection chatConnection;
public string errorMessage = "";
bool isDisconnected;
public ConnectedPlayer(uint actorId)
@ -142,5 +144,11 @@ namespace FFXIVClassic_Map_Server.dataobjects
return basePackets;
}
public void clearInstance()
{
actorInstanceList.Clear();
}
}
}

View file

@ -163,7 +163,7 @@ namespace FFXIVClassic_Lobby_Server.packets
while (binreader.BaseStream.Position + 4 < data.Length)
{
uint read = binreader.ReadUInt32();
if (read == 0x029B2941 || read == 0x02977DC7 || read == 0x0297D2C8 || read == 0x0230d573 || read == 0x23317df || read == 0x23344a3) //Original ID
if (read == 0x029B2941 || read == 0x02977DC7 || read == 0x0297D2C8 || read == 0x0230d573 || read == 0x23317df || read == 0x23344a3 || read == 0x1730bdb) //Original ID
{
binWriter.BaseStream.Seek(binreader.BaseStream.Position - 0x4, SeekOrigin.Begin);
binWriter.Write(actorID);

View file

@ -1,4 +1,5 @@
using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Lobby_Server.common;
using FFXIVClassic_Map_Server.lua;
using System;
using System.Collections.Generic;
using System.IO;
@ -21,6 +22,10 @@ namespace FFXIVClassic_Map_Server.packets.receive.events
public uint val2;
public byte val3;
public uint errorIndex;
public uint errorNum;
public string error = null;
public string eventStarter;
public List<LuaParam> luaParams;
@ -37,7 +42,20 @@ namespace FFXIVClassic_Map_Server.packets.receive.events
val1 = binReader.ReadUInt32();
val2 = binReader.ReadUInt32();
val3 = binReader.ReadByte();
/*
//Lua Error Dump
if (val1 == 0x39800010)
{
errorIndex = actorID;
errorNum = scriptOwnerActorID;
error = ASCIIEncoding.ASCII.GetString(binReader.ReadBytes(0x80)).Replace("\0", "");
if (errorIndex == 0)
Log.error("LUA ERROR:");
return;
}
*/
List<byte> strList = new List<byte>();
byte curByte;
while ((curByte = binReader.ReadByte())!=0)

View file

@ -22,8 +22,10 @@ namespace FFXIVClassic_Map_Server.packets.send.actor
{
using (BinaryWriter binWriter = new BinaryWriter(mem))
{
int value = 0;
binWriter.Write((Int32)value);
int value1 = 0x10; //Instance ID?
int value2 = 0x3980;
binWriter.Write((Int16)value1);
binWriter.Write((Int16)value2);
binWriter.Write(Encoding.ASCII.GetBytes(objectName), 0, Encoding.ASCII.GetByteCount(objectName) >= 0x20 ? 0x20 : Encoding.ASCII.GetByteCount(objectName));
binWriter.BaseStream.Seek(0x24, SeekOrigin.Begin);
binWriter.Write(Encoding.ASCII.GetBytes(className), 0, Encoding.ASCII.GetByteCount(className) >= 0x20 ? 0x20 : Encoding.ASCII.GetByteCount(className));