2016-06-14 22:54:02 +01:00
using FFXIVClassic_Map_Server ;
using FFXIVClassic.Common ;
2016-08-22 10:43:04 -04:00
2016-05-29 15:14:09 -04:00
using FFXIVClassic_Map_Server.actors.chara.npc ;
2016-02-07 13:05:54 -05:00
using FFXIVClassic_Map_Server.Actors ;
2016-01-16 23:03:04 -05:00
using FFXIVClassic_Map_Server.lua ;
using FFXIVClassic_Map_Server.packets.send.actor ;
2015-10-05 19:36:15 -04:00
using System ;
using System.Collections.Generic ;
using System.Linq ;
using System.Text ;
using System.Threading.Tasks ;
2017-05-27 02:17:25 +01:00
using System.IO ;
2017-04-29 20:30:54 -04:00
using FFXIVClassic_Map_Server.actors.director ;
2015-10-05 19:36:15 -04:00
2016-02-07 13:05:54 -05:00
namespace FFXIVClassic_Map_Server.actors.area
2015-10-05 19:36:15 -04:00
{
2016-02-07 13:05:54 -05:00
class Zone : Area
2016-05-29 15:14:09 -04:00
{
2016-02-07 13:05:54 -05:00
Dictionary < string , Dictionary < uint , PrivateArea > > privateAreas = new Dictionary < string , Dictionary < uint , PrivateArea > > ( ) ;
2017-04-15 16:33:56 -04:00
Dictionary < string , List < PrivateAreaContent > > contentAreas = new Dictionary < string , List < PrivateAreaContent > > ( ) ;
2017-04-29 20:30:54 -04:00
Object contentAreasLock = new Object ( ) ;
2016-01-17 23:36:34 -05:00
2017-05-27 02:17:25 +01:00
public SharpNav . TiledNavMesh tiledNavMesh ;
public SharpNav . NavMeshQuery navMeshQuery ;
2017-06-09 04:17:08 +01:00
2017-05-27 02:17:25 +01:00
public Int64 pathCalls ;
public Int64 pathCallTime ;
2017-06-09 04:17:08 +01:00
protected DateTime lastUpdate ;
public Zone ( uint id , string zoneName , ushort regionId , string classPath , ushort bgmDay , ushort bgmNight , ushort bgmBattle , bool isIsolated , bool isInn , bool canRideChocobo , bool canStealth , bool isInstanceRaid , bool loadNavMesh = false )
2017-04-29 20:30:54 -04:00
: base ( id , zoneName , regionId , classPath , bgmDay , bgmNight , bgmBattle , isIsolated , isInn , canRideChocobo , canStealth , isInstanceRaid )
2015-10-13 19:15:44 -04:00
{
2017-06-09 04:17:08 +01:00
var navMeshName = loadNavMesh ? zoneName + ".snb" : "" ;
if ( navMeshName ! = "" )
2017-05-27 02:17:25 +01:00
{
try
{
2017-06-09 04:17:08 +01:00
tiledNavMesh = utils . NavmeshUtils . LoadNavmesh ( tiledNavMesh , navMeshName ) ;
2017-05-27 02:17:25 +01:00
navMeshQuery = new SharpNav . NavMeshQuery ( tiledNavMesh , 100 ) ;
2017-06-09 04:17:08 +01:00
if ( tiledNavMesh ! = null )
Program . Log . Info ( $"Loaded navmesh for {zoneName}" ) ;
2017-05-27 02:17:25 +01:00
}
2017-06-09 04:17:08 +01:00
catch ( Exception e )
2017-05-27 02:17:25 +01:00
{
Program . Log . Error ( e . Message ) ;
}
}
2016-01-24 17:11:35 -05:00
}
2016-06-14 21:29:10 +01:00
public void AddPrivateArea ( PrivateArea pa )
2016-03-20 19:29:38 -04:00
{
2016-06-14 21:29:10 +01:00
if ( privateAreas . ContainsKey ( pa . GetPrivateAreaName ( ) ) )
2017-03-07 00:09:37 -05:00
privateAreas [ pa . GetPrivateAreaName ( ) ] [ pa . GetPrivateAreaType ( ) ] = pa ;
2016-03-20 19:29:38 -04:00
else
{
2016-06-14 21:29:10 +01:00
privateAreas [ pa . GetPrivateAreaName ( ) ] = new Dictionary < uint , PrivateArea > ( ) ;
2017-03-07 00:09:37 -05:00
privateAreas [ pa . GetPrivateAreaName ( ) ] [ pa . GetPrivateAreaType ( ) ] = pa ;
2016-03-20 19:29:38 -04:00
}
}
2016-06-14 21:29:10 +01:00
public PrivateArea GetPrivateArea ( string type , uint number )
2016-01-17 23:36:34 -05:00
{
2016-02-07 13:05:54 -05:00
if ( privateAreas . ContainsKey ( type ) )
2016-01-17 23:36:34 -05:00
{
2016-02-07 13:05:54 -05:00
Dictionary < uint , PrivateArea > instances = privateAreas [ type ] ;
if ( instances . ContainsKey ( number ) )
return instances [ number ] ;
else
return null ;
2016-01-17 23:36:34 -05:00
}
2016-02-07 13:05:54 -05:00
else
2016-01-17 23:36:34 -05:00
return null ;
}
2016-06-14 21:29:10 +01:00
public override SubPacket CreateScriptBindPacket ( uint playerActorId )
2016-01-24 03:10:17 -05:00
{
2016-02-07 13:05:54 -05:00
bool isEntranceDesion = false ;
2016-01-24 03:10:17 -05:00
2016-02-07 13:05:54 -05:00
List < LuaParam > lParams ;
2017-04-29 20:30:54 -04:00
lParams = LuaUtils . CreateLuaParamList ( classPath , false , true , zoneName , "" , - 1 , canRideChocobo ? ( byte ) 1 : ( byte ) 0 , canStealth , isInn , false , false , false , true , isInstanceRaid , isEntranceDesion ) ;
2016-06-14 21:29:10 +01:00
return ActorInstantiatePacket . BuildPacket ( actorId , playerActorId , actorName , className , lParams ) ;
2016-02-02 00:02:06 -05:00
}
2016-06-14 22:54:02 +01:00
public void AddSpawnLocation ( SpawnLocation spawn )
2016-05-29 15:14:09 -04:00
{
//Is it in a private area?
if ( ! spawn . privAreaName . Equals ( "" ) )
{
if ( privateAreas . ContainsKey ( spawn . privAreaName ) )
{
Dictionary < uint , PrivateArea > levels = privateAreas [ spawn . privAreaName ] ;
if ( levels . ContainsKey ( spawn . privAreaLevel ) )
2016-06-14 22:54:02 +01:00
levels [ spawn . privAreaLevel ] . AddSpawnLocation ( spawn ) ;
2016-05-29 15:14:09 -04:00
else
2016-06-14 22:54:02 +01:00
Program . Log . Error ( "Tried to add a spawn location to non-existing private area level \"{0}\" in area {1} in zone {2}" , spawn . privAreaName , spawn . privAreaLevel , zoneName ) ;
2016-05-29 15:14:09 -04:00
}
else
2016-06-14 22:54:02 +01:00
Program . Log . Error ( "Tried to add a spawn location to non-existing private area \"{0}\" in zone {1}" , spawn . privAreaName , zoneName ) ;
2016-05-29 15:14:09 -04:00
}
else
mSpawnLocations . Add ( spawn ) ;
}
2016-06-14 22:54:02 +01:00
public void SpawnAllActors ( bool doPrivAreas )
2016-05-29 15:14:09 -04:00
{
foreach ( SpawnLocation spawn in mSpawnLocations )
2016-06-14 22:54:02 +01:00
SpawnActor ( spawn ) ;
2016-05-29 15:14:09 -04:00
if ( doPrivAreas )
{
foreach ( Dictionary < uint , PrivateArea > areas in privateAreas . Values )
{
foreach ( PrivateArea pa in areas . Values )
2016-06-14 22:54:02 +01:00
pa . SpawnAllActors ( ) ;
2016-05-29 15:14:09 -04:00
}
}
}
2017-04-15 16:33:56 -04:00
public Actor FindActorInZone ( uint id )
{
if ( ! mActorList . ContainsKey ( id ) )
{
foreach ( Dictionary < uint , PrivateArea > paList in privateAreas . Values )
{
foreach ( PrivateArea pa in paList . Values )
{
Actor actor = pa . FindActorInArea ( id ) ;
if ( actor ! = null )
return actor ;
}
}
return null ;
}
else
return mActorList [ id ] ;
}
2017-04-29 20:30:54 -04:00
public PrivateAreaContent CreateContentArea ( Player starterPlayer , string areaClassPath , string contentScript , string areaName , string directorName )
2017-04-15 16:33:56 -04:00
{
2017-04-29 20:30:54 -04:00
lock ( contentAreasLock )
{
Director director = CreateDirector ( directorName ) ;
if ( director = = null )
return null ;
if ( ! contentAreas . ContainsKey ( areaName ) )
contentAreas . Add ( areaName , new List < PrivateAreaContent > ( ) ) ;
PrivateAreaContent contentArea = new PrivateAreaContent ( this , classPath , areaName , 1 , director , starterPlayer ) ;
contentAreas [ areaName ] . Add ( contentArea ) ;
return contentArea ;
}
}
2017-04-15 16:33:56 -04:00
2017-04-29 20:30:54 -04:00
public void DeleteContentArea ( PrivateAreaContent area )
{
if ( contentAreas . ContainsKey ( area . GetPrivateAreaName ( ) ) )
{
contentAreas [ area . GetPrivateAreaName ( ) ] . Remove ( area ) ;
}
2017-04-15 16:33:56 -04:00
}
2017-04-29 20:30:54 -04:00
2017-06-09 04:17:08 +01:00
public void Update ( double deltaTime )
{
// todo: again, this is retarded but debug stuff
var diffTime = DateTime . Now - lastUpdate ;
// arbitrary cap
if ( diffTime . Milliseconds > = 33 )
{
}
if ( diffTime . Seconds > = 10 )
{
if ( this . pathCalls > 0 )
{
Program . Log . Error ( "Number of pathfinding calls {0} average time {1}" , pathCalls , pathCallTime / pathCalls ) ;
}
}
}
2015-10-05 19:36:15 -04:00
}
}