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:
parent
c83b4a12b9
commit
42ba95b69d
14 changed files with 482 additions and 317 deletions
|
@ -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>
|
||||
|
|
|
@ -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:
|
||||
|
@ -218,9 +211,22 @@ namespace FFXIVClassic_Lobby_Server
|
|||
player.getActor().currentLockedTarget = lockTarget.actorID;
|
||||
break;
|
||||
//Start Event
|
||||
case 0x012D:
|
||||
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,7 +236,10 @@ 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);
|
||||
|
|
|
@ -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"))
|
||||
{
|
||||
|
|
|
@ -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.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);
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
322
FFXIVClassic Map Server/actors/area/Area.cs
Normal file
322
FFXIVClassic Map Server/actors/area/Area.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
32
FFXIVClassic Map Server/actors/area/PrivateArea.cs
Normal file
32
FFXIVClassic Map Server/actors/area/PrivateArea.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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,298 +8,39 @@ 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;
|
||||
|
||||
public int boundingGridSize = 50;
|
||||
public int minX = -1000, minY = -1000, maxX = 1000, maxY = 1000;
|
||||
private int numXBlocks, numYBlocks;
|
||||
private int halfWidth, halfHeight;
|
||||
Dictionary<string, Dictionary<uint, PrivateArea>> privateAreas = new Dictionary<string, Dictionary<uint, PrivateArea>>();
|
||||
|
||||
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++)
|
||||
public PrivateArea getPrivateArea(string type, uint number)
|
||||
{
|
||||
if (privateAreas.ContainsKey(type))
|
||||
{
|
||||
for (int x = 0; x < numXBlocks; x++ )
|
||||
{
|
||||
mActorBlock[x, y] = new List<Actor>();
|
||||
}
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -19,6 +19,8 @@ namespace FFXIVClassic_Map_Server.dataobjects
|
|||
private ClientConnection zoneConnection;
|
||||
private ClientConnection chatConnection;
|
||||
|
||||
public string errorMessage = "";
|
||||
|
||||
bool isDisconnected;
|
||||
|
||||
public ConnectedPlayer(uint actorId)
|
||||
|
@ -60,7 +62,7 @@ namespace FFXIVClassic_Map_Server.dataobjects
|
|||
|
||||
public void queuePacket(SubPacket subPacket, bool isAuthed, bool isEncrypted)
|
||||
{
|
||||
zoneConnection.queuePacket(subPacket, isAuthed, isEncrypted);
|
||||
zoneConnection.queuePacket(subPacket, isAuthed, isEncrypted);
|
||||
}
|
||||
|
||||
public Player getActor()
|
||||
|
@ -142,5 +144,11 @@ namespace FFXIVClassic_Map_Server.dataobjects
|
|||
return basePackets;
|
||||
}
|
||||
|
||||
|
||||
public void clearInstance()
|
||||
{
|
||||
actorInstanceList.Clear();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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));
|
||||
|
|
Loading…
Add table
Reference in a new issue