Rewrote directors so that they can work in the new system. Began adding content groups to the map server.

This commit is contained in:
Filip Maj 2017-01-29 11:07:28 -05:00
parent ad88c0b28a
commit f7482781e5
26 changed files with 638 additions and 359 deletions

View File

@ -84,27 +84,22 @@
<Compile Include="actors\chara\player\Equipment.cs" />
<Compile Include="actors\chara\player\Inventory.cs" />
<Compile Include="actors\chara\Work.cs" />
<Compile Include="actors\group\Group.cs" />
<Compile Include="actors\group\Party.cs" />
<Compile Include="actors\group\Relation.cs" />
<Compile Include="actors\group\work\ContentWork.cs" />
<Compile Include="actors\debug\Debug.cs" />
<Compile Include="actors\director\Director.cs" />
<Compile Include="actors\director\OpeningDirector.cs" />
<Compile Include="actors\director\quest\QuestDirectorMan0g001.cs" />
<Compile Include="actors\director\quest\QuestDirectorMan0l001.cs" />
<Compile Include="actors\director\quest\QuestDirectorMan0u001.cs" />
<Compile Include="actors\director\WeatherDirector.cs" />
<Compile Include="actors\EventList.cs" />
<Compile Include="actors\group\work\GroupGlobalSave.cs" />
<Compile Include="actors\group\work\GroupGlobalTemp.cs" />
<Compile Include="actors\group\work\GroupMemberSave.cs" />
<Compile Include="actors\group\ContentGroup.cs" />
<Compile Include="actors\group\Group.cs" />
<Compile Include="actors\group\MonsterParty.cs" />
<Compile Include="actors\group\Party.cs" />
<Compile Include="actors\group\Relation.cs" />
<Compile Include="actors\group\Work\ContentWork.cs" />
<Compile Include="actors\group\Work\GroupGlobalSave.cs" />
<Compile Include="actors\group\Work\GroupGlobalTemp.cs" />
<Compile Include="actors\group\Work\GroupMemberSave.cs" />
<Compile Include="actors\group\Work\PartyWork.cs" />
<Compile Include="actors\group\Work\RelationWork.cs" />
<Compile Include="actors\judge\Judge.cs" />
<Compile Include="actors\group\work\LinkshellWork.cs" />
<Compile Include="actors\group\work\PartyWork.cs" />
<Compile Include="actors\quest\Quest.cs" />
<Compile Include="actors\group\work\RelationWork.cs" />
<Compile Include="actors\group\work\RetainerWork.cs" />
<Compile Include="actors\StaticActors.cs" />
<Compile Include="actors\world\WorldMaster.cs" />
<Compile Include="dataobjects\ZoneConnection.cs" />

View File

@ -19,7 +19,8 @@ using FFXIVClassic_Map_Server.packets.receive.events;
using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.packets.WorldPackets.Send;
using FFXIVClassic_Map_Server.packets.WorldPackets.Receive;
using FFXIVClassic_Map_Server.packets.WorldPackets.Receive;
using FFXIVClassic_Map_Server.actors.director;
namespace FFXIVClassic_Map_Server
{
@ -183,9 +184,10 @@ namespace FFXIVClassic_Map_Server
ownerActor = Server.GetWorldManager().GetActorInWorld(session.GetActor().currentEventOwner);
if (ownerActor == null)
{
//Is it a Director?
if (session.GetActor().currentDirector != null && session.GetActor().currentEventOwner == session.GetActor().currentDirector.actorId)
ownerActor = session.GetActor().currentDirector;
//Is it a Director?
Director director = session.GetActor().GetDirector(eventStart.scriptOwnerActorID);
if (director != null)
ownerActor = director;
else
{
Program.Log.Debug("\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.triggerName, LuaUtils.DumpParams(eventStart.luaParams));

View File

@ -22,6 +22,7 @@ using FFXIVClassic_Map_Server.packets.WorldPackets.Receive;
using FFXIVClassic_Map_Server.packets.WorldPackets.Send.Group;
using System.Threading;
using System.Diagnostics;
using FFXIVClassic_Map_Server.actors.director;
namespace FFXIVClassic_Map_Server
{

View File

@ -14,6 +14,8 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic_Map_Server.packets.send;
using FFXIVClassic_Map_Server.actors.group;
using FFXIVClassic_Map_Server.actors.director;
namespace FFXIVClassic_Map_Server.Actors
{
@ -30,13 +32,24 @@ namespace FFXIVClassic_Map_Server.Actors
public int boundingGridSize = 50;
public int minX = -1000, minY = -1000, maxX = 1000, maxY = 1000;
protected int numXBlocks, numYBlocks;
protected int halfWidth, halfHeight;
protected int halfWidth, halfHeight;
private Dictionary<uint, Director> currentDirectors = new Dictionary<uint, Director>();
private Object directorLock = new Object();
private uint directorIdCount = 0;
protected Director mWeatherDirector;
protected List<SpawnLocation> mSpawnLocations = new List<SpawnLocation>();
protected Dictionary<uint, Actor> mActorList = new Dictionary<uint, Actor>();
protected List<Actor>[,] mActorBlock;
LuaScript areaScript;
LuaScript areaScript;
//Content Groups
public Dictionary<ulong, Group> mContentGroups = new Dictionary<ulong, Group>();
private Object groupLock = new Object();
public ulong groupIndexId = 0;
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)
@ -353,6 +366,11 @@ namespace FFXIVClassic_Map_Server.Actors
AddActorToZone(npc);
}
public Director GetWeatherDirector()
{
return mWeatherDirector;
}
public void ChangeWeather(ushort weather, ushort transitionTime, Player player, bool zoneWide = false)
{
weatherNormal = weather;
@ -374,6 +392,65 @@ namespace FFXIVClassic_Map_Server.Actors
}
}
public void CreateContentGroup(uint[] initialMembers)
{
lock (groupLock)
{
ContentGroup contentGroup = new ContentGroup(groupIndexId, initialMembers == null ? new uint[0] : initialMembers);
mContentGroups.Add(groupIndexId, contentGroup);
groupIndexId++;
if (initialMembers != null && initialMembers.Length != 0)
contentGroup.SendAll();
}
}
public void DeleteContentGroup(ulong groupId)
{
lock (groupLock)
{
if (mContentGroups.ContainsKey(groupId) && mContentGroups[groupId] is ContentGroup)
{
ContentGroup group = (ContentGroup) mContentGroups[groupId];
group.SendDeletePackets();
mContentGroups.Remove(groupId);
}
}
}
public Director CreateDirector(string path)
{
lock (directorLock)
{
Director director = new Director(directorIdCount, this, path);
if (!director.IsCreated())
return null;
currentDirectors.Add(directorIdCount, director);
directorIdCount++;
return director;
}
}
public void DeleteDirector(uint id)
{
lock (directorLock)
{
if (currentDirectors.ContainsKey(id))
{
currentDirectors[id].RemoveChildren();
currentDirectors.Remove(id);
}
}
}
public Director GetDirectorById(uint id)
{
if (currentDirectors.ContainsKey(id))
return currentDirectors[id];
return null;
}
public void Update(double deltaTime)
{
lock (mActorList)

View File

@ -121,9 +121,10 @@ namespace FFXIVClassic_Map_Server.Actors
//Quest Actors (MUST MATCH playerWork.questScenario/questGuildleve)
public Quest[] questScenario = new Quest[16];
public Quest[] questGuildleve = new Quest[8];
public Director currentDirector;
public Quest[] questGuildleve = new Quest[8];
private List<Director> ownedDirectors = new List<Director>();
private Director loginInitDirector = null;
public PlayerWork playerWork = new PlayerWork();
@ -253,8 +254,8 @@ namespace FFXIVClassic_Map_Server.Actors
List<LuaParam> lParams;
if (IsMyPlayer(playerActorId))
{
if (currentDirector != null)
lParams = LuaUtils.CreateLuaParamList("/Chara/Player/Player_work", false, false, true, currentDirector, true, 0, false, timers, true);
if (loginInitDirector != null)
lParams = LuaUtils.CreateLuaParamList("/Chara/Player/Player_work", false, false, true, loginInitDirector, true, 0, false, timers, true);
else
lParams = LuaUtils.CreateLuaParamList("/Chara/Player/Player_work", false, false, false, true, 0, false, timers, true);
}
@ -500,26 +501,12 @@ namespace FFXIVClassic_Map_Server.Actors
playerSession.QueuePacket(GetInitPackets(actorId));
BasePacket areaMasterSpawn = zone.GetSpawnPackets(actorId);
BasePacket debugSpawn = world.GetDebugActor().GetSpawnPackets(actorId);
BasePacket worldMasterSpawn = world.GetActor().GetSpawnPackets(actorId);
BasePacket weatherDirectorSpawn = new WeatherDirector(this, 8003).GetSpawnPackets(actorId);
BasePacket directorSpawn = null;
BasePacket worldMasterSpawn = world.GetActor().GetSpawnPackets(actorId);
if (currentDirector != null)
directorSpawn = currentDirector.GetSpawnPackets(actorId);
playerSession.QueuePacket(areaMasterSpawn);
playerSession.QueuePacket(debugSpawn);
if (directorSpawn != null)
{
//directorSpawn.DebugPrintPacket();
// currentDirector.GetInitPackets(actorId).DebugPrintPacket();
QueuePacket(directorSpawn);
QueuePacket(currentDirector.GetInitPackets(actorId));
//QueuePacket(currentDirector.GetSetEventStatusPackets(actorId));
}
playerSession.QueuePacket(debugSpawn);
playerSession.QueuePacket(worldMasterSpawn);
if (zone.isInn)
@ -532,20 +519,22 @@ namespace FFXIVClassic_Map_Server.Actors
packet.DebugPrintSubPacket();
QueuePacket(packet);
}
}
if (zone.GetWeatherDirector() != null)
{
BasePacket weatherDirectorSpawn = zone.GetWeatherDirector().GetSpawnPackets(actorId);
playerSession.QueuePacket(weatherDirectorSpawn);
}
foreach (Director director in ownedDirectors)
{
director.GetSpawnPackets(actorId).DebugPrintPacket();
QueuePacket(director.GetSpawnPackets(actorId));
QueuePacket(director.GetInitPackets(actorId));
//QueuePacket(director.GetSetEventStatusPackets(actorId));
}
playerSession.QueuePacket(weatherDirectorSpawn);
/*
#region hardcode
BasePacket reply10 = new BasePacket("./packets/login/login10.bin"); //Item Storage, Inn Door Created
BasePacket reply11 = new BasePacket("./packets/login/login11.bin"); //NPC Create ??? Final init
reply10.ReplaceActorID(actorId);
reply11.ReplaceActorID(actorId);
//playerSession.QueuePacket(reply10);
// playerSession.QueuePacket(reply11);
#endregion
*/
}
private void SendRemoveInventoryPackets(List<ushort> slots)
@ -714,6 +703,11 @@ namespace FFXIVClassic_Map_Server.Actors
return playTime;
}
public void SavePlayTime()
{
Database.SavePlayerPlayTime(this);
}
public void ChangeMusic(ushort musicId)
{
QueuePacket(SetMusicPacket.BuildPacket(actorId, musicId, 1));
@ -1096,40 +1090,56 @@ namespace FFXIVClassic_Map_Server.Actors
return -1;
}
public void SetDirector(string directorType, bool sendPackets)
{
if (directorType.Equals("openingDirector"))
{
currentDirector = new OpeningDirector(this, 0x46080012);
}
else if (directorType.Equals("QuestDirectorMan0l001"))
{
currentDirector = new QuestDirectorMan0l001(this, 0x46080012);
}
else if (directorType.Equals("QuestDirectorMan0g001"))
{
currentDirector = new QuestDirectorMan0g001(this, 0x46080012);
}
else if (directorType.Equals("QuestDirectorMan0u001"))
{
currentDirector = new QuestDirectorMan0u001(this, 0x46080012);
}
if (sendPackets)
{
QueuePacket(RemoveActorPacket.BuildPacket(actorId, 0x46080012));
QueuePacket(currentDirector.GetSpawnPackets(actorId));
QueuePacket(currentDirector.GetInitPackets(actorId));
//QueuePacket(currentDirector.GetSetEventStatusPackets(actorId));
//currentDirector.GetSpawnPackets(actorId).DebugPrintPacket();
//currentDirector.GetInitPackets(actorId).DebugPrintPacket();
}
public void SetLoginDirector(Director director)
{
if (ownedDirectors.Contains(director))
loginInitDirector = director;
}
public Director GetDirector()
public void AddDirector(Director director)
{
if (!ownedDirectors.Contains(director))
{
ownedDirectors.Add(director);
director.AddChild(this);
//director.GetSpawnPackets(actorId).DebugPrintPacket();
//QueuePacket(director.GetSpawnPackets(actorId));
//QueuePacket(director.GetInitPackets(actorId));
//QueuePacket(director.GetSetEventStatusPackets(actorId));
}
}
public void RemoveDirector(Director director)
{
if (!ownedDirectors.Contains(director))
{
ownedDirectors.Remove(director);
director.RemoveChild(this);
}
}
public Director GetDirector(string directorName)
{
return currentDirector;
foreach (Director d in ownedDirectors)
{
if (d.className.Equals(directorName))
return d;
}
return null;
}
public Director GetDirector(uint id)
{
foreach (Director d in ownedDirectors)
{
if (d.actorId == id)
return d;
}
return null;
}
public void ExaminePlayer(Actor examinee)
@ -1185,6 +1195,27 @@ namespace FFXIVClassic_Map_Server.Actors
EndEvent();
}
}
else if (owner is Director)
{
currentEventRunning = ((Director)owner).GetEventStartCoroutine(this);
if (currentEventRunning != null)
{
try
{
currentEventRunning.Resume(objects.ToArray());
}
catch (ScriptRuntimeException e)
{
Program.Log.Error("[LUA] {0}", e.DecoratedMessage);
EndEvent();
}
}
else
{
EndEvent();
}
}
else
{
currentEventRunning = LuaEngine.DoActorOnEventStarted(this, owner, start);

View File

@ -1,22 +1,53 @@

using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.actors.area;
using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Map_Server.packets.send.actor;
using MoonSharp.Interpreter;
using System;
using System.Collections.Generic;
using System.IO;
namespace FFXIVClassic_Map_Server.actors.director
{
class Director : Actor
{
Player owner;
private uint directorId;
private string directorScriptPath;
private List<Actor> childrenOwners = new List<Actor>();
private bool isCreated = false;
public Director(Player owner, uint id) : base(id)
public Director(uint id, Area zone, string directorPath)
: base((6 << 28 | zone.actorId << 19 | (uint)id))
{
this.owner = owner;
directorId = id;
this.zone = zone;
directorScriptPath = directorPath;
DoActorInit(directorScriptPath);
GenerateActorName((int)id);
eventConditions = new EventList();
eventConditions.noticeEventConditions = new List<EventList.NoticeEventCondition>();
eventConditions.noticeEventConditions.Add(new EventList.NoticeEventCondition("noticeEvent", 0xE,0x0));
eventConditions.noticeEventConditions.Add(new EventList.NoticeEventCondition("noticeRequest",0x0,0x1));
}
public override SubPacket CreateScriptBindPacket(uint playerActorId)
{
List<LuaParam> actualLParams = new List<LuaParam>();
actualLParams.Insert(0, new LuaParam(2, classPath));
actualLParams.Insert(1, new LuaParam(4, 4));
actualLParams.Insert(2, new LuaParam(4, 4));
actualLParams.Insert(3, new LuaParam(4, 4));
actualLParams.Insert(4, new LuaParam(4, 4));
actualLParams.Insert(5, new LuaParam(4, 4));
actualLParams.Insert(6, new LuaParam(0, (int)0x13883));
return ActorInstantiatePacket.BuildPacket(actorId, playerActorId, actorName, className, actualLParams);
}
public virtual BasePacket GetSpawnPackets(uint playerActorId, uint spawnType)
public override BasePacket GetSpawnPackets(uint playerActorId, ushort spawnType)
{
List<SubPacket> subpackets = new List<SubPacket>();
subpackets.Add(CreateAddActorPacket(playerActorId, 0));
@ -37,14 +68,127 @@ namespace FFXIVClassic_Map_Server.actors.director
return BasePacket.CreatePacket(initProperties.BuildPacket(playerActorId, actorId), true, false);
}
public void OnTalked(Npc npc)
public void OnTalked(Player player, Npc npc)
{
LuaEngine.DoDirectorOnTalked(this, owner, npc);
LuaEngine.DoDirectorOnTalked(this, player, npc);
}
public void OnCommand(Command command)
public void OnCommand(Player player, Command command)
{
LuaEngine.DoDirectorOnCommand(this, owner, command);
LuaEngine.DoDirectorOnCommand(this, player, command);
}
public void AddChild(Actor actor)
{
if (!childrenOwners.Contains(actor))
childrenOwners.Add(actor);
}
public void RemoveChild(Actor actor)
{
if (childrenOwners.Contains(actor))
childrenOwners.Remove(actor);
if (childrenOwners.Count == 0)
Server.GetWorldManager().GetZone(zoneId).DeleteDirector(actorId);
}
public void RemoveChildren()
{
childrenOwners.Clear();
Server.GetWorldManager().GetZone(zoneId).DeleteDirector(actorId);
}
public void DoActorInit(string directorPath)
{
LuaScript script = null;
if (File.Exists("./scripts/directors/" + directorPath + ".lua"))
script = LuaEngine.LoadScript("./scripts/directors/" + directorPath + ".lua");
else
return;
DynValue result;
if (script != null && script.Globals["init"] != null)
result = script.Call(script.Globals["init"], this);
else
return;
List<LuaParam> lparams = LuaUtils.CreateLuaParamList(result);
if (lparams.Count == 1 && lparams[0].value is string)
{
classPath = (string)lparams[0].value;
className = classPath.Substring(classPath.LastIndexOf("/") + 1);
isCreated = true;
}
}
public Coroutine GetEventStartCoroutine(Player player)
{
LuaScript script = null;
if (File.Exists("./scripts/directors/" + directorScriptPath + ".lua"))
script = LuaEngine.LoadScript("./scripts/directors/" + directorScriptPath + ".lua");
else
return null;
//Run Script
Coroutine coroutine;
if (script != null && !script.Globals.Get("onEventStarted").IsNil())
coroutine = script.CreateCoroutine(script.Globals["onEventStarted"]).Coroutine;
else
return null;
return coroutine;
}
public bool IsCreated()
{
return isCreated;
}
public void GenerateActorName(int actorNumber)
{
//Format Class Name
string className = this.className;
className = Char.ToLowerInvariant(className[0]) + className.Substring(1);
//Format Zone Name
string zoneName = zone.zoneName.Replace("Field", "Fld")
.Replace("Dungeon", "Dgn")
.Replace("Town", "Twn")
.Replace("Battle", "Btl")
.Replace("Test", "Tes")
.Replace("Event", "Evt")
.Replace("Ship", "Shp")
.Replace("Office", "Ofc");
if (zone is PrivateArea)
{
//Check if "normal"
zoneName = zoneName.Remove(zoneName.Length - 1, 1) + "P";
}
zoneName = Char.ToLowerInvariant(zoneName[0]) + zoneName.Substring(1);
try
{
className = className.Substring(0, 20 - zoneName.Length);
}
catch (ArgumentOutOfRangeException e)
{ }
//Convert actor number to base 63
string classNumber = Utils.ToStringBase63(actorNumber);
//Get stuff after @
uint zoneId = zone.actorId;
uint privLevel = 0;
if (zone is PrivateArea)
privLevel = ((PrivateArea)zone).GetPrivateAreaLevel();
actorName = String.Format("{0}_{1}_{2}@{3:X3}{4:X2}", className, zoneName, classNumber, zoneId, privLevel);
}
}

View File

@ -1,41 +0,0 @@

using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Map_Server.packets.send.actor;
using System;
using System.Collections.Generic;
namespace FFXIVClassic_Map_Server.actors.director
{
class OpeningDirector : Director
{
public OpeningDirector(Player player, uint id) : base(player, id)
{
this.displayNameId = 0;
this.customDisplayName = String.Format("openingDire_{0}_{1}", player.zone.zoneName, "04");
this.actorName = String.Format("openingDire_{0}_{1}@{2:x3}{3:x2}", player.zone.zoneName, "04", player.zoneId, 0);
this.actorName = this.actorName.Replace("Battle", "Btl");
this.className = "OpeningDirector";
this.eventConditions = new EventList();
List<EventList.NoticeEventCondition> noticeEventList = new List<EventList.NoticeEventCondition>();
noticeEventList.Add(new EventList.NoticeEventCondition("noticeEvent", 0xE, 0x0));
noticeEventList.Add(new EventList.NoticeEventCondition("noticeRequest", 0x0, 0x1));
this.eventConditions.noticeEventConditions = noticeEventList;
}
public override SubPacket CreateScriptBindPacket(uint playerActorId)
{
List<LuaParam> lParams;
lParams = LuaUtils.CreateLuaParamList("/Director/OpeningDirector", false, false, false, false, 0x13881);
return ActorInstantiatePacket.BuildPacket(actorId, playerActorId, actorName, className, lParams);
}
}
}

View File

@ -1,49 +0,0 @@

using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.actors.director;
using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Map_Server.packets.send.actor;
using System;
using System.Collections.Generic;
namespace FFXIVClassic_Map_Server.Actors
{
class WeatherDirector : Director
{
private uint weatherId;
public WeatherDirector(Player player, uint weatherId)
: base(player, 0x5FF80003)
{
this.weatherId = weatherId;
this.displayNameId = 0;
this.customDisplayName = String.Format("weatherDire_{0}_{1}", player.zone.zoneName, "07");
this.actorName = String.Format("weatherDire_{0}_{1}@{2:x3}{3:x2}", player.zone.zoneName, "04", player.zoneId, 0);
this.className = "Debug";
}
public override SubPacket CreateScriptBindPacket(uint playerActorId)
{
List<LuaParam> lParams;
lParams = LuaUtils.CreateLuaParamList("/Director/Weather/WeatherDirector", false, false, false, false, weatherId);
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));
return BasePacket.CreatePacket(subpackets, true, false);
}
}
}

View File

@ -1,38 +0,0 @@

using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Map_Server.packets.send.actor;
using System.Collections.Generic;
namespace FFXIVClassic_Map_Server.actors.director
{
class QuestDirectorMan0g001 : Director
{
public QuestDirectorMan0g001(Player player, uint id)
: base(player, id)
{
this.displayNameId = 0;
this.customDisplayName = "questDirect_fst0Btl03_01";
this.actorName = "questDirect_fst0Btl03_01@0A615";
this.className = "QuestDirectorMan0g001";
this.eventConditions = new EventList();
List<EventList.NoticeEventCondition> noticeEventList = new List<EventList.NoticeEventCondition>();
noticeEventList.Add(new EventList.NoticeEventCondition("noticeEvent", 0xE, 0x0));
noticeEventList.Add(new EventList.NoticeEventCondition("noticeRequest", 0x0, 0x1));
this.eventConditions.noticeEventConditions = noticeEventList;
}
public override SubPacket CreateScriptBindPacket(uint playerActorId)
{
List<LuaParam> lParams;
lParams = LuaUtils.CreateLuaParamList("/Director/Quest/QuestDirectorMan0g001", false, false, false, false, false, 0x753A);
return ActorInstantiatePacket.BuildPacket(actorId, playerActorId, actorName, className, lParams);
}
}
}

View File

@ -1,38 +0,0 @@

using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Map_Server.packets.send.actor;
using System.Collections.Generic;
namespace FFXIVClassic_Map_Server.actors.director
{
class QuestDirectorMan0l001 : Director
{
public QuestDirectorMan0l001(Player player, uint id)
: base(player, id)
{
this.displayNameId = 0;
this.customDisplayName = "questDirect_ocn0Btl02_01";
this.actorName = "questDirect_ocn0Btl02_01@0C196";
this.className = "QuestDirectorMan0l001";
this.eventConditions = new EventList();
List<EventList.NoticeEventCondition> noticeEventList = new List<EventList.NoticeEventCondition>();
noticeEventList.Add(new EventList.NoticeEventCondition("noticeEvent", 0xE, 0x0));
noticeEventList.Add(new EventList.NoticeEventCondition("noticeRequest", 0x0, 0x1));
this.eventConditions.noticeEventConditions = noticeEventList;
}
public override SubPacket CreateScriptBindPacket(uint playerActorId)
{
List<LuaParam> lParams;
lParams = LuaUtils.CreateLuaParamList("/Director/Quest/QuestDirectorMan0l001", false, false, false, false, false, 0x7532);
return ActorInstantiatePacket.BuildPacket(actorId, playerActorId, actorName, className, lParams);
}
}
}

View File

@ -1,38 +0,0 @@

using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Map_Server.packets.send.actor;
using System.Collections.Generic;
namespace FFXIVClassic_Map_Server.actors.director
{
class QuestDirectorMan0u001 : Director
{
public QuestDirectorMan0u001(Player player, uint id)
: base(player, id)
{
this.displayNameId = 0;
this.customDisplayName = "questDirect_wil0Btl01_01";
this.actorName = "questDirect_wil0Btl01_01@0A615";
this.className = "QuestDirectorMan0u001";
this.eventConditions = new EventList();
List<EventList.NoticeEventCondition> noticeEventList = new List<EventList.NoticeEventCondition>();
noticeEventList.Add(new EventList.NoticeEventCondition("noticeEvent", 0xE, 0x0));
noticeEventList.Add(new EventList.NoticeEventCondition("noticeRequest", 0x0, 0x1));
this.eventConditions.noticeEventConditions = noticeEventList;
}
public override SubPacket CreateScriptBindPacket(uint playerActorId)
{
List<LuaParam> lParams;
lParams = LuaUtils.CreateLuaParamList("/Director/Quest/QuestDirectorMan0u001", false, false, false, false, false, 0x757F);
return ActorInstantiatePacket.BuildPacket(actorId, playerActorId, actorName, className, lParams);
}
}
}

View File

@ -0,0 +1,73 @@
using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Map_Server.packets.send.group;
using FFXIVClassic_Map_Server.packets.send.groups;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.group
{
class ContentGroup : Group
{
private List<uint> members = new List<uint>();
public ContentGroup(ulong groupIndex, uint[] initialMembers) : base(groupIndex)
{
for (int i = 0; i < initialMembers.Length; i++)
members.Add(initialMembers[i]);
}
public void AddMember(uint memberId)
{
members.Add(memberId);
SendGroupPacketsAll(members);
}
public void RemoveMember(uint memberId)
{
members.Remove(memberId);
SendGroupPacketsAll(members);
}
public override List<GroupMember> BuildMemberList(uint id)
{
List<GroupMember> groupMembers = new List<GroupMember>();
groupMembers.Add(new GroupMember(id, -1, 0, false, true, Server.GetWorldManager().GetActorInWorld(id).customDisplayName));
foreach (uint charaId in members)
{
if (charaId != id)
groupMembers.Add(new GroupMember(charaId, -1, 0, false, true, Server.GetWorldManager().GetActorInWorld(charaId).customDisplayName));
}
return groupMembers;
}
public override void SendInitWorkValues(Session session)
{
SynchGroupWorkValuesPacket groupWork = new SynchGroupWorkValuesPacket(groupIndex);
groupWork.setTarget("/_init");
SubPacket test = groupWork.buildPacket(session.id, session.id);
session.QueuePacket(test, true, false);
}
public override uint GetTypeId()
{
return Group.ContentGroup_SimpleContentGroup24A;
}
public void SendAll()
{
SendGroupPacketsAll(members);
}
public void DeleteAll()
{
SendDeletePackets(members);
}
}
}

View File

@ -1,6 +1,7 @@
using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Map_Server.packets.send.group;
using FFXIVClassic_Map_Server.packets.send.groups;
using System;
using System.Collections.Generic;
@ -17,6 +18,27 @@ namespace FFXIVClassic_Map_Server.actors.group
public const uint RetainerGroup = 80001;
public const uint MonsterPartyGroup = 10002;
public const uint ContentGroup_GuildleveGroup = 30001;
public const uint ContentGroup_PublicPopGroup = 30002;
public const uint ContentGroup_SimpleContentGroup24A = 30003;
public const uint ContentGroup_SimpleContentGroup32A = 30004;
public const uint ContentGroup_SimpleContentGroup128 = 30005;
public const uint ContentGroup_SimpleContentGroup24B = 30006;
public const uint ContentGroup_SimpleContentGroup32B = 30007;
public const uint ContentGroup_RetainerAccessGroup = 30008;
public const uint ContentGroup_SimpleContentGroup99999 = 30009;
public const uint ContentGroup_SimpleContentGroup512 = 30010;
public const uint ContentGroup_SimpleContentGroup64A = 30011;
public const uint ContentGroup_SimpleContentGroup64B = 30012;
public const uint ContentGroup_SimpleContentGroup64C = 30013;
public const uint ContentGroup_SimpleContentGroup64D = 30014;
public const uint ContentGroup_SimpleContentGroup64E = 30015;
public const uint ContentGroup_SimpleContentGroup64F = 30016;
public const uint ContentGroup_SimpleContentGroup64G = 30017;
public const uint ContentGroup_SimpleContentGroup24C = 30018;
public readonly ulong groupIndex;
public Group(ulong groupIndex)
@ -44,39 +66,89 @@ namespace FFXIVClassic_Map_Server.actors.group
return -1;
}
public virtual List<GroupMember> BuildMemberList()
public virtual List<GroupMember> BuildMemberList(uint id)
{
return new List<GroupMember>();
}
public void SendGroupPacketsAll(params uint[] ids)
{
for (int i = 0; i < ids.Length; i++)
{
Session session = Server.GetServer().GetSession(ids[i]);
if (session != null)
SendGroupPackets(session);
}
}
public void SendGroupPacketsAll(List<uint> ids)
{
for (int i = 0; i < ids.Count; i++)
{
Session session = Server.GetServer().GetSession(ids[i]);
if (session != null)
SendGroupPackets(session);
}
}
public void SendDeletePackets(params uint[] ids)
{
for (int i = 0; i < ids.Length; i++)
{
Session session = Server.GetServer().GetSession(ids[i]);
if (session != null)
SendDeletePacket(session);
}
}
public void SendDeletePackets(List<uint> ids)
{
for (int i = 0; i < ids.Count; i++)
{
Session session = Server.GetServer().GetSession(ids[i]);
if (session != null)
SendDeletePacket(session);
}
}
public void SendGroupPackets(Session session)
{
ulong time = Utils.MilisUnixTimeStampUTC();
List<GroupMember> members = BuildMemberList();
List<GroupMember> members = BuildMemberList(session.id);
Server.GetWorldConnection().QueuePacket(GroupHeaderPacket.buildPacket(session.id, session.GetActor().zoneId, time, this), true, false);
Server.GetWorldConnection().QueuePacket(GroupMembersBeginPacket.buildPacket(session.id, session.GetActor().zoneId, time, this), true, false);
session.QueuePacket(GroupHeaderPacket.buildPacket(session.id, session.GetActor().zoneId, time, this), true, false);
session.QueuePacket(GroupMembersBeginPacket.buildPacket(session.id, session.GetActor().zoneId, time, this), true, false);
int currentIndex = 0;
while (true)
{
if (GetMemberCount() - currentIndex >= 64)
Server.GetWorldConnection().QueuePacket(GroupMembersX64Packet.buildPacket(session.id, session.GetActor().zoneId, time, members, ref currentIndex), true, false);
session.QueuePacket(GroupMembersX64Packet.buildPacket(session.id, session.GetActor().zoneId, time, members, ref currentIndex), true, false);
else if (GetMemberCount() - currentIndex >= 32)
Server.GetWorldConnection().QueuePacket(GroupMembersX32Packet.buildPacket(session.id, session.GetActor().zoneId, time, members, ref currentIndex), true, false);
session.QueuePacket(GroupMembersX32Packet.buildPacket(session.id, session.GetActor().zoneId, time, members, ref currentIndex), true, false);
else if (GetMemberCount() - currentIndex >= 16)
Server.GetWorldConnection().QueuePacket(GroupMembersX16Packet.buildPacket(session.id, session.GetActor().zoneId, time, members, ref currentIndex), true, false);
session.QueuePacket(GroupMembersX16Packet.buildPacket(session.id, session.GetActor().zoneId, time, members, ref currentIndex), true, false);
else if (GetMemberCount() - currentIndex > 0)
Server.GetWorldConnection().QueuePacket(GroupMembersX08Packet.buildPacket(session.id, session.GetActor().zoneId, time, members, ref currentIndex), true, false);
session.QueuePacket(GroupMembersX08Packet.buildPacket(session.id, session.GetActor().zoneId, time, members, ref currentIndex), true, false);
else
break;
}
Server.GetWorldConnection().QueuePacket(GroupMembersEndPacket.buildPacket(session.id, session.GetActor().zoneId, time, this), true, false);
session.QueuePacket(GroupMembersEndPacket.buildPacket(session.id, session.GetActor().zoneId, time, this), true, false);
}
public void SendDeletePacket(Session session)
{
if (session != null)
session.QueuePacket(DeleteGroupPacket.buildPacket(session.id, this), true, false);
}
public virtual void SendInitWorkValues(Session session)
{

View File

@ -0,0 +1,63 @@
using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Map_Server.packets.send.group;
using FFXIVClassic_Map_Server.packets.send.groups;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.group
{
class MonsterParty : Group
{
private List<uint> monsterMembers = new List<uint>();
public MonsterParty(ulong groupIndex, uint[] initialMonsterMembers)
: base(groupIndex)
{
for (int i = 0; i < initialMonsterMembers.Length; i++)
monsterMembers.Add(initialMonsterMembers[i]);
}
public void AddMember(uint memberId)
{
monsterMembers.Add(memberId);
SendGroupPacketsAll(monsterMembers);
}
public void RemoveMember(uint memberId)
{
monsterMembers.Remove(memberId);
SendGroupPacketsAll(monsterMembers);
}
public override List<GroupMember> BuildMemberList(uint id)
{
List<GroupMember> groupMembers = new List<GroupMember>();
groupMembers.Add(new GroupMember(id, -1, 0, false, true, Server.GetWorldManager().GetActorInWorld(id).customDisplayName));
foreach (uint charaId in monsterMembers)
{
if (charaId != id)
groupMembers.Add(new GroupMember(charaId, -1, 0, false, true, Server.GetWorldManager().GetActorInWorld(charaId).customDisplayName));
}
return groupMembers;
}
public override void SendInitWorkValues(Session session)
{
SynchGroupWorkValuesPacket groupWork = new SynchGroupWorkValuesPacket(groupIndex);
groupWork.setTarget("/_init");
SubPacket test = groupWork.buildPacket(session.id, session.id);
session.QueuePacket(test, true, false);
}
public override uint GetTypeId()
{
return Group.MonsterPartyGroup;
}
}
}

View File

@ -1,6 +1,7 @@
using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.actors.group.work;
using FFXIVClassic_Map_Server.actors.group.Work;
using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Map_Server.packets.send.group;
using System;
using System.Collections.Generic;
using System.Linq;
@ -20,23 +21,31 @@ namespace FFXIVClassic_Map_Server.actors.group
members.Add(leaderCharaId);
}
public void SetLeader(uint leaderCharaId)
public void SetLeader(uint actorId)
{
partyGroupWork._globalTemp.owner = (ulong)(((ulong)leaderCharaId << 32) | 0xB36F92);
partyGroupWork._globalTemp.owner = (ulong)(((ulong)actorId << 32) | 0xB36F92);
}
public uint GetLeader()
{
return (uint)((ulong)(partyGroupWork._globalTemp.owner >> 32) & 0xFFFFFFFF);
return (uint)(((ulong)partyGroupWork._globalTemp.owner >> 32) & 0xFFFFFFFF);
}
public uint GetIdForName(string name)
{
for (int i = 0; i < members.Count; i++)
{
if (Server.GetWorldManager().GetActorInWorld(members[i]).customDisplayName.Equals(name))
{
return members[i];
}
}
return 0;
}
public bool IsInParty(uint charaId)
{
return members.Contains(charaId);
}
public override void SendInitWorkValues(Session session)
{
}
public override int GetMemberCount()
@ -49,5 +58,17 @@ namespace FFXIVClassic_Map_Server.actors.group
return Group.PlayerPartyGroup;
}
public override List<GroupMember> BuildMemberList(uint id)
{
List<GroupMember> groupMembers = new List<GroupMember>();
groupMembers.Add(new GroupMember(id, -1, 0, false, true, Server.GetWorldManager().GetActorInWorld(id).customDisplayName));
foreach (uint charaId in members)
{
if (charaId != id)
groupMembers.Add(new GroupMember(charaId, -1, 0, false, true, Server.GetWorldManager().GetActorInWorld(charaId).customDisplayName));
}
return groupMembers;
}
}
}

View File

@ -1,7 +1,8 @@
using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.actors.group.work;
using FFXIVClassic_Map_Server.actors.group.Work;
using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Map_Server.packets.send.group;
using FFXIVClassic_Map_Server.packets.send.groups;
using System;
using System.Collections.Generic;
using System.Linq;
@ -13,13 +14,25 @@ namespace FFXIVClassic_Map_Server.actors.group
class Relation : Group
{
public RelationWork work = new RelationWork();
public uint charaOther;
private uint charaOther;
private ulong topicGroup;
public Relation(ulong groupIndex, uint host, uint other, uint command) : base (groupIndex)
public Relation(ulong groupIndex, uint host, uint other, uint command, ulong topicGroup) : base (groupIndex)
{
this.charaOther = other;
work._globalTemp.host = ((ulong)host << 32) | (0xc17909);
work._globalTemp.variableCommand = command;
this.topicGroup = topicGroup;
}
public uint GetHost()
{
return (uint)(((ulong)work._globalTemp.host >> 32) & 0xFFFFFFFF);
}
public uint GetOther()
{
return charaOther;
}
public override int GetMemberCount()
@ -32,14 +45,32 @@ namespace FFXIVClassic_Map_Server.actors.group
return Group.GroupInvitationRelationGroup;
}
public override List<GroupMember> BuildMemberList()
public ulong GetTopicGroupIndex()
{
return null;
return topicGroup;
}
public override List<GroupMember> BuildMemberList(uint id)
{
List<GroupMember> groupMembers = new List<GroupMember>();
uint hostId = (uint)((work._globalTemp.host >> 32) & 0xFFFFFFFF);
groupMembers.Add(new GroupMember(hostId, -1, 0, false, Server.GetServer().GetSession(hostId) != null, Server.GetWorldManager().GetActorInWorld(hostId).customDisplayName));
groupMembers.Add(new GroupMember(charaOther, -1, 0, false, Server.GetServer().GetSession(charaOther) != null, Server.GetWorldManager().GetActorInWorld(charaOther).customDisplayName));
return groupMembers;
}
public override void SendInitWorkValues(Session session)
{
SynchGroupWorkValuesPacket groupWork = new SynchGroupWorkValuesPacket(groupIndex);
groupWork.addProperty(this, "work._globalTemp.host");
groupWork.addProperty(this, "work._globalTemp.variableCommand");
groupWork.setTarget("/_init");
SubPacket test = groupWork.buildPacket(session.id, session.id);
test.DebugPrintSubPacket();
session.QueuePacket(test, true, false);
}
}

View File

@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.group.work
namespace FFXIVClassic_Map_Server.actors.group.Work
{
class ContentWork
{

View File

@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.group.work
namespace FFXIVClassic_Map_Server.actors.group.Work
{
class GroupGlobalSave
{

View File

@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.group.work
namespace FFXIVClassic_Map_Server.actors.group.Work
{
class GroupGlobalTemp
{

View File

@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.group.work
namespace FFXIVClassic_Map_Server.actors.group.Work
{
class GroupMemberSave
{

View File

@ -1,14 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.group.work
{
class LinkshellWork
{
public GroupGlobalSave _globalSave = new GroupGlobalSave();
public GroupMemberSave[] _memberSave = new GroupMemberSave[128];
}
}

View File

@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.group.work
namespace FFXIVClassic_Map_Server.actors.group.Work
{
class PartyWork
{

View File

@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.group.work
namespace FFXIVClassic_Map_Server.actors.group.Work
{
class RelationWork
{

View File

@ -1,13 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.group.work
{
class RetainerWork
{
public GroupMemberSave[] _memberSave = new GroupMemberSave[128];
}
}

View File

@ -20,7 +20,7 @@ namespace FFXIVClassic_Map_Server.lua
class LuaEngine
{
const string FILEPATH_PLAYER = "./scripts/player.lua";
const string FILEPATH_ZONE = "./scripts/zones/{0}/zone.lua";
const string FILEPATH_ZONE = "./scripts/unique/{0}/zone.lua";
const string FILEPATH_COMMANDS = "./scripts/commands/{0}.lua";
const string FILEPATH_DIRECTORS = "./scripts/directors/{0}.lua";
const string FILEPATH_NPCS = "./scripts/zones/{0}/npcs/{1}.lua";
@ -158,7 +158,7 @@ namespace FFXIVClassic_Map_Server.lua
public static void OnZoneIn(Player player)
{
string luaPath = String.Format(FILEPATH_ZONE, player.GetZone().actorId);
string luaPath = String.Format(FILEPATH_ZONE, player.GetZone().zoneName);
if (File.Exists(luaPath))
{
@ -169,7 +169,7 @@ namespace FFXIVClassic_Map_Server.lua
//Run Script
if (!script.Globals.Get("onZoneIn").IsNil())
script.Call(script.Globals["onZoneIn"], player);
script.Call(script.Globals["onZoneIn"], player.GetZone(), player);
}
}

View File

@ -24,7 +24,7 @@ namespace FFXIVClassic_Map_Server.packets.send.events
binWriter.Write((UInt32)playerActorId);
binWriter.Write((UInt32)targetActorId);
int test = 0x75DC8705; //This will crash if set to 0 on pushCommand but not for mining which has to be 0????
int test = 0x75dc8705; //This will crash if set to 0 on pushCommand but not for mining which has to be 0????
binWriter.Write((UInt32)test);
binWriter.Write((UInt32)0x30400000);