mirror of
https://bitbucket.org/Ioncannon/project-meteor-server.git
synced 2025-04-25 22:27:45 +00:00
initial navmesh stuff
This commit is contained in:
parent
44a76c94af
commit
d72a2af641
19 changed files with 831 additions and 33 deletions
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "FFXIVClassic Map Server/navmesh/rcdtcs"]
|
||||||
|
path = FFXIVClassic Map Server/navmesh/rcdtcs
|
||||||
|
url = https://github.com/jlalleve/rcdtcs
|
|
@ -36,6 +36,7 @@
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<Prefer32Bit>false</Prefer32Bit>
|
<Prefer32Bit>false</Prefer32Bit>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="DotNetZip">
|
<Reference Include="DotNetZip">
|
||||||
|
@ -51,6 +52,7 @@
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Numerics" />
|
||||||
<Reference Include="System.Xml.Linq" />
|
<Reference Include="System.Xml.Linq" />
|
||||||
<Reference Include="System.Data.DataSetExtensions" />
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
<Reference Include="Microsoft.CSharp" />
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
|
|
@ -351,5 +351,32 @@ namespace FFXIVClassic.Common
|
||||||
{
|
{
|
||||||
return (value >> bits) | (value << (16 - bits));
|
return (value >> bits) | (value << (16 - bits));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static float Clamp(float val, float min, float max)
|
||||||
|
{
|
||||||
|
|
||||||
|
return Math.Max(Math.Min(max, val), min);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float Distance(float x, float y, float z, float x2, float y2, float z2)
|
||||||
|
{
|
||||||
|
if (x == x2 && y == y2 && z == z2)
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
|
return (float)Math.Sqrt(DistanceSquared(x, y, z, x2, y2, z2));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float DistanceSquared(float x, float y, float z, float x2, float y2, float z2)
|
||||||
|
{
|
||||||
|
if (x == x2 && y == y2 && z == z2)
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
|
// todo: my maths is shit
|
||||||
|
var dx = x - x2;
|
||||||
|
var dy = y - y2;
|
||||||
|
var dz = z - z2;
|
||||||
|
|
||||||
|
return dx * dx + dy * dy + dz * dz;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,11 +1,20 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<startup>
|
<startup>
|
||||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
|
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1" />
|
||||||
</startup>
|
</startup>
|
||||||
<system.data>
|
<system.data>
|
||||||
<DbProviderFactories>
|
<DbProviderFactories>
|
||||||
<remove invariant="MySql.Data.MySqlClient" />
|
<remove invariant="MySql.Data.MySqlClient" />
|
||||||
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.9.8.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
|
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.9.8.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
|
||||||
</DbProviderFactories>
|
</DbProviderFactories>
|
||||||
</system.data></configuration>
|
</system.data>
|
||||||
|
<runtime>
|
||||||
|
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||||
|
<dependentAssembly>
|
||||||
|
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||||
|
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
|
||||||
|
</dependentAssembly>
|
||||||
|
</assemblyBinding>
|
||||||
|
</runtime>
|
||||||
|
</configuration>
|
||||||
|
|
|
@ -10,9 +10,10 @@
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<RootNamespace>FFXIVClassic_Map_Server</RootNamespace>
|
<RootNamespace>FFXIVClassic_Map_Server</RootNamespace>
|
||||||
<AssemblyName>FFXIVClassic Map Server</AssemblyName>
|
<AssemblyName>FFXIVClassic Map Server</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<NuGetPackageImportStamp>1d22ec4a</NuGetPackageImportStamp>
|
<NuGetPackageImportStamp>1d22ec4a</NuGetPackageImportStamp>
|
||||||
|
<TargetFrameworkProfile />
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
@ -24,6 +25,7 @@
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
<Prefer32Bit>true</Prefer32Bit>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
@ -58,16 +60,20 @@
|
||||||
<HintPath>..\packages\MySql.Data.6.9.8\lib\net45\MySql.Data.dll</HintPath>
|
<HintPath>..\packages\MySql.Data.6.9.8\lib\net45\MySql.Data.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
|
<HintPath>..\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\NLog.4.3.5\lib\net45\NLog.dll</HintPath>
|
<HintPath>..\packages\NLog.4.3.5\lib\net45\NLog.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="SharpNav, Version=1.0.0.1, Culture=neutral, PublicKeyToken=b467138d8cacd85b, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>.\SharpNav.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Numerics" />
|
||||||
<Reference Include="System.Xml.Linq" />
|
<Reference Include="System.Xml.Linq" />
|
||||||
<Reference Include="System.Data.DataSetExtensions" />
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
<Reference Include="Microsoft.CSharp" />
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
@ -131,6 +137,21 @@
|
||||||
<Compile Include="lua\LuaParam.cs" />
|
<Compile Include="lua\LuaParam.cs" />
|
||||||
<Compile Include="lua\LuaScript.cs" />
|
<Compile Include="lua\LuaScript.cs" />
|
||||||
<Compile Include="lua\LuaUtils.cs" />
|
<Compile Include="lua\LuaUtils.cs" />
|
||||||
|
<Compile Include="navmesh\rcdtcs\Assets\Rcdtcs\Detour\DetourCommon.cs" />
|
||||||
|
<Compile Include="navmesh\rcdtcs\Assets\Rcdtcs\Detour\DetourNavMesh.cs" />
|
||||||
|
<Compile Include="navmesh\rcdtcs\Assets\Rcdtcs\Detour\DetourNavMeshBuilder.cs" />
|
||||||
|
<Compile Include="navmesh\rcdtcs\Assets\Rcdtcs\Detour\DetourNavMeshQuery.cs" />
|
||||||
|
<Compile Include="navmesh\rcdtcs\Assets\Rcdtcs\Detour\DetourNode.cs" />
|
||||||
|
<Compile Include="navmesh\rcdtcs\Assets\Rcdtcs\Detour\DetourStatus.cs" />
|
||||||
|
<Compile Include="navmesh\rcdtcs\Assets\Rcdtcs\Recast\Recast.cs" />
|
||||||
|
<Compile Include="navmesh\rcdtcs\Assets\Rcdtcs\Recast\RecastArea.cs" />
|
||||||
|
<Compile Include="navmesh\rcdtcs\Assets\Rcdtcs\Recast\RecastContour.cs" />
|
||||||
|
<Compile Include="navmesh\rcdtcs\Assets\Rcdtcs\Recast\RecastFilter.cs" />
|
||||||
|
<Compile Include="navmesh\rcdtcs\Assets\Rcdtcs\Recast\RecastLayers.cs" />
|
||||||
|
<Compile Include="navmesh\rcdtcs\Assets\Rcdtcs\Recast\RecastMesh.cs" />
|
||||||
|
<Compile Include="navmesh\rcdtcs\Assets\Rcdtcs\Recast\RecastMeshDetail.cs" />
|
||||||
|
<Compile Include="navmesh\rcdtcs\Assets\Rcdtcs\Recast\RecastRasterization.cs" />
|
||||||
|
<Compile Include="navmesh\rcdtcs\Assets\Rcdtcs\Recast\RecastRegion.cs" />
|
||||||
<Compile Include="PacketProcessor.cs" />
|
<Compile Include="PacketProcessor.cs" />
|
||||||
<Compile Include="packets\receive\ChatMessagePacket.cs" />
|
<Compile Include="packets\receive\ChatMessagePacket.cs" />
|
||||||
<Compile Include="packets\receive\events\EventUpdatePacket.cs" />
|
<Compile Include="packets\receive\events\EventUpdatePacket.cs" />
|
||||||
|
@ -310,6 +331,7 @@
|
||||||
<Compile Include="Server.cs" />
|
<Compile Include="Server.cs" />
|
||||||
<Compile Include="utils\ActorPropertyPacketUtil.cs" />
|
<Compile Include="utils\ActorPropertyPacketUtil.cs" />
|
||||||
<Compile Include="utils\CharacterUtils.cs" />
|
<Compile Include="utils\CharacterUtils.cs" />
|
||||||
|
<Compile Include="utils\NavmeshUtils.cs" />
|
||||||
<Compile Include="utils\SQLGeneration.cs" />
|
<Compile Include="utils\SQLGeneration.cs" />
|
||||||
<Compile Include="actors\area\Area.cs" />
|
<Compile Include="actors\area\Area.cs" />
|
||||||
<Compile Include="WorldManager.cs" />
|
<Compile Include="WorldManager.cs" />
|
||||||
|
@ -332,6 +354,7 @@
|
||||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup />
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PostBuildEvent>xcopy "$(SolutionDir)data\map_config.ini" "$(SolutionDir)$(ProjectName)\$(OutDir)" /d
|
<PostBuildEvent>xcopy "$(SolutionDir)data\map_config.ini" "$(SolutionDir)$(ProjectName)\$(OutDir)" /d
|
||||||
|
|
|
@ -16,6 +16,8 @@ namespace FFXIVClassic_Map_Server
|
||||||
class Program
|
class Program
|
||||||
{
|
{
|
||||||
public static Logger Log;
|
public static Logger Log;
|
||||||
|
public static Server Server;
|
||||||
|
public static Random Random;
|
||||||
|
|
||||||
static void Main(string[] args)
|
static void Main(string[] args)
|
||||||
{
|
{
|
||||||
|
@ -55,9 +57,10 @@ namespace FFXIVClassic_Map_Server
|
||||||
//Start server if A-OK
|
//Start server if A-OK
|
||||||
if (startServer)
|
if (startServer)
|
||||||
{
|
{
|
||||||
Server server = new Server();
|
Random = new Random();
|
||||||
|
Server = new Server();
|
||||||
|
|
||||||
server.StartServer();
|
Server.StartServer();
|
||||||
|
|
||||||
while (startServer)
|
while (startServer)
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace FFXIVClassic_Map_Server.Properties {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||||
// class via a tool like ResGen or Visual Studio.
|
// class via a tool like ResGen or Visual Studio.
|
||||||
// To add or Remove a member, edit your .ResX file then rerun ResGen
|
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||||
// with the /str option, or rebuild your VS project.
|
// with the /str option, or rebuild your VS project.
|
||||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
@ -105,7 +105,7 @@ namespace FFXIVClassic_Map_Server.Properties {
|
||||||
///
|
///
|
||||||
///Available commands:
|
///Available commands:
|
||||||
///Standard: mypos, music, warp
|
///Standard: mypos, music, warp
|
||||||
///Server Administration: givecurrency, giveitem, givekeyitem, Removecurrency, Removekeyitem, reloaditems, reloadzones
|
///Server Administration: givecurrency, giveitem, givekeyitem, removecurrency, removekeyitem, reloaditems, reloadzones
|
||||||
///Test: test weather.
|
///Test: test weather.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string CPhelp {
|
public static string CPhelp {
|
||||||
|
@ -176,38 +176,38 @@ namespace FFXIVClassic_Map_Server.Properties {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Removes the specified currency from the current player's inventory
|
/// Looks up a localized string similar to Removes the specified currency from the current player's inventory
|
||||||
///
|
///
|
||||||
///*Syntax: Removecurrency <quantity>
|
///*Syntax: removecurrency <quantity>
|
||||||
/// Removecurrency <type> <quantity>
|
/// removecurrency <type> <quantity>
|
||||||
///<type> is the specific type of currency desired, defaults to gil if no type specified.
|
///<type> is the specific type of currency desired, defaults to gil if no type specified.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string CPRemovecurrency {
|
public static string CPremovecurrency {
|
||||||
get {
|
get {
|
||||||
return ResourceManager.GetString("CPRemovecurrency", resourceCulture);
|
return ResourceManager.GetString("CPremovecurrency", resourceCulture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Removes the specified items to the current player's inventory
|
/// Looks up a localized string similar to Removes the specified items to the current player's inventory
|
||||||
///
|
///
|
||||||
///*Syntax: Removeitem <itemid>
|
///*Syntax: removeitem <itemid>
|
||||||
/// Removeitem <itemid> <quantity>
|
/// removeitem <itemid> <quantity>
|
||||||
///<item id> is the item's specific id as defined in the server database.
|
///<item id> is the item's specific id as defined in the server database.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string CPRemoveitem {
|
public static string CPremoveitem {
|
||||||
get {
|
get {
|
||||||
return ResourceManager.GetString("CPRemoveitem", resourceCulture);
|
return ResourceManager.GetString("CPremoveitem", resourceCulture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Removes the specified key item to the current player's inventory
|
/// Looks up a localized string similar to Removes the specified key item to the current player's inventory
|
||||||
///
|
///
|
||||||
///*Syntax: Removekeyitem <itemid>
|
///*Syntax: removekeyitem <itemid>
|
||||||
///<item id> is the key item's specific id as defined in the server database.
|
///<item id> is the key item's specific id as defined in the server database.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string CPRemovekeyitem {
|
public static string CPremovekeyitem {
|
||||||
get {
|
get {
|
||||||
return ResourceManager.GetString("CPRemovekeyitem", resourceCulture);
|
return ResourceManager.GetString("CPremovekeyitem", resourceCulture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
BIN
FFXIVClassic Map Server/SharpNav.dll
Normal file
BIN
FFXIVClassic Map Server/SharpNav.dll
Normal file
Binary file not shown.
|
@ -40,6 +40,13 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
public string className;
|
public string className;
|
||||||
public List<LuaParam> classParams;
|
public List<LuaParam> classParams;
|
||||||
|
|
||||||
|
public List<utils.Vector3> positionUpdates = new List<utils.Vector3>();
|
||||||
|
public DateTime lastAiUpdate;
|
||||||
|
public DateTime lastMoveUpdate;
|
||||||
|
public Actor target;
|
||||||
|
|
||||||
|
public bool hasMoved = false;
|
||||||
|
public bool isAtSpawn = true;
|
||||||
public EventList eventConditions;
|
public EventList eventConditions;
|
||||||
|
|
||||||
public Actor(uint actorId)
|
public Actor(uint actorId)
|
||||||
|
@ -126,7 +133,30 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
|
|
||||||
public SubPacket CreatePositionUpdatePacket(uint playerActorId)
|
public SubPacket CreatePositionUpdatePacket(uint playerActorId)
|
||||||
{
|
{
|
||||||
return MoveActorToPositionPacket.BuildPacket(actorId, playerActorId, positionX, positionY, positionZ, rotation, moveState);
|
int updateMs = 300;
|
||||||
|
var diffTime = (DateTime.Now - lastMoveUpdate);
|
||||||
|
|
||||||
|
if (this.target != null)
|
||||||
|
{
|
||||||
|
updateMs = 150;
|
||||||
|
}
|
||||||
|
if (diffTime.Milliseconds >= updateMs && hasMoved)
|
||||||
|
{
|
||||||
|
hasMoved = (this.positionUpdates != null && this.positionUpdates.Count > 0);
|
||||||
|
if (hasMoved)
|
||||||
|
{
|
||||||
|
var pos = positionUpdates[0];
|
||||||
|
positionUpdates.Remove(pos);
|
||||||
|
|
||||||
|
positionX = pos.X;
|
||||||
|
positionY = pos.Y;
|
||||||
|
positionZ = pos.Z;
|
||||||
|
//Program.Server.GetInstance().mLuaEngine.OnPath(actor, position, positionUpdates)
|
||||||
|
}
|
||||||
|
lastMoveUpdate = DateTime.Now;
|
||||||
|
return MoveActorToPositionPacket.BuildPacket(actorId, playerActorId, positionX, positionY, positionZ, rotation, moveState);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SubPacket CreateStatePacket(uint playerActorID)
|
public SubPacket CreateStatePacket(uint playerActorID)
|
||||||
|
@ -324,6 +354,77 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
|
|
||||||
public void Update(double deltaTime)
|
public void Update(double deltaTime)
|
||||||
{
|
{
|
||||||
|
// todo: this is retarded
|
||||||
|
if (this is Zone || this is Area || this is Player)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var diffTime = (DateTime.Now - lastAiUpdate);
|
||||||
|
|
||||||
|
// todo: this too
|
||||||
|
if (diffTime.Milliseconds >= deltaTime)
|
||||||
|
{
|
||||||
|
bool foundActor = false;
|
||||||
|
foreach (var actor in ((Area)zone).GetActorsAroundActor(this, 50))
|
||||||
|
{
|
||||||
|
if (actor is Player && actor != this)
|
||||||
|
{
|
||||||
|
var player = actor as Player;
|
||||||
|
|
||||||
|
var distance = Utils.Distance(positionX, positionY, positionZ, player.positionX, player.positionY, player.positionZ);
|
||||||
|
|
||||||
|
int maxDistance = player == target ? 25 : 15;
|
||||||
|
|
||||||
|
if (distance <= maxDistance)
|
||||||
|
{
|
||||||
|
foundActor = true;
|
||||||
|
|
||||||
|
if (!hasMoved)
|
||||||
|
{
|
||||||
|
if (distance >= 3)
|
||||||
|
{
|
||||||
|
FollowTarget(player, 2.0f);
|
||||||
|
}
|
||||||
|
// too close, spread out
|
||||||
|
else if (distance <= 0.64f)
|
||||||
|
{
|
||||||
|
var minRadius = 0.65f;
|
||||||
|
var maxRadius = 0.85f;
|
||||||
|
|
||||||
|
var angle = Program.Random.NextDouble() * Math.PI * 2;
|
||||||
|
var radius = Math.Sqrt(Program.Random.NextDouble() * (maxRadius - minRadius)) + minRadius;
|
||||||
|
|
||||||
|
float x = (float)(radius * Math.Cos(angle));
|
||||||
|
float z = (float)(radius * Math.Sin(angle));
|
||||||
|
|
||||||
|
positionUpdates.Add(new utils.Vector3(positionX + x, positionY, positionZ + z));
|
||||||
|
|
||||||
|
hasMoved = true;
|
||||||
|
}
|
||||||
|
else if (target != null)
|
||||||
|
{
|
||||||
|
// todo: actually make IsFacing work
|
||||||
|
if(!IsFacing(target.positionX, target.positionY))
|
||||||
|
LookAt(target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 5 seconds before back to spawn
|
||||||
|
if ((DateTime.Now - lastMoveUpdate).Seconds >= 5 && !foundActor)
|
||||||
|
{
|
||||||
|
// 10 yalms spawn radius just because
|
||||||
|
this.isAtSpawn = Utils.Distance(positionX, positionY, positionZ, oldPositionX, oldPositionY, oldPositionZ) <= 18.0f;
|
||||||
|
|
||||||
|
if (this.isAtSpawn != true && this.target == null && oldPositionX != 0.0f && oldPositionY != 0.0f && oldPositionZ != 0.0f)
|
||||||
|
PathTo(oldPositionX, oldPositionY, oldPositionZ, 3.0f);
|
||||||
|
|
||||||
|
lastMoveUpdate = DateTime.Now;
|
||||||
|
this.target = null;
|
||||||
|
}
|
||||||
|
lastAiUpdate = DateTime.Now;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GenerateActorName(int actorNumber)
|
public void GenerateActorName(int actorNumber)
|
||||||
|
@ -492,6 +593,110 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
{
|
{
|
||||||
return zoneId;
|
return zoneId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsFacing(float x, float y, byte checkAngle = 45)
|
||||||
|
{
|
||||||
|
var rot1 = this.rotation;
|
||||||
|
|
||||||
|
var dX = this.positionX - x;
|
||||||
|
var dY = this.positionY - y;
|
||||||
|
|
||||||
|
var rot2 = Math.Atan2(dY, dX);
|
||||||
|
|
||||||
|
var dRot = Math.PI - rot2 + Math.PI / 2;
|
||||||
|
|
||||||
|
Program.Log.Error("IsFacing Rotation {0} Rotation2 {1}", rot1, rot2);
|
||||||
|
return rot1 == rot2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LookAt(Actor actor)
|
||||||
|
{
|
||||||
|
if (actor != null)
|
||||||
|
{
|
||||||
|
LookAt(actor.positionX, actor.positionY);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Program.Log.Error("Actor.LookAt() unable to find actor!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LookAt(float x, float y)
|
||||||
|
{
|
||||||
|
var rot1 = this.rotation;
|
||||||
|
|
||||||
|
var dX = this.positionX - x;
|
||||||
|
var dY = this.positionY - y;
|
||||||
|
|
||||||
|
var rot2 = Math.Atan2(dY, dX);
|
||||||
|
|
||||||
|
var dRot = Math.PI - rot2 + Math.PI / 2;
|
||||||
|
|
||||||
|
Program.Log.Error("LookAt Rotation {0} Rotation2 {1}", rot1, rot2);
|
||||||
|
|
||||||
|
this.hasMoved = rot2 != rot1;
|
||||||
|
this.rotation = (float)dRot;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PathTo(float x, float y, float z, float stepSize = 0.70f, int maxPath = 40)
|
||||||
|
{
|
||||||
|
var pos = new utils.Vector3(positionX, positionY, positionZ);
|
||||||
|
var dest = new utils.Vector3(x, y, z);
|
||||||
|
|
||||||
|
var sw = new System.Diagnostics.Stopwatch();
|
||||||
|
sw.Start();
|
||||||
|
|
||||||
|
var path = utils.NavmeshUtils.GetPath(((Zone)GetZone()), pos, dest, stepSize, maxPath);
|
||||||
|
|
||||||
|
if (path != null)
|
||||||
|
{
|
||||||
|
if (oldPositionX == 0.0f && oldPositionY == 0.0f && oldPositionZ == 0.0f)
|
||||||
|
{
|
||||||
|
oldPositionX = positionX;
|
||||||
|
oldPositionY = positionY;
|
||||||
|
oldPositionZ = positionZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo: something went wrong
|
||||||
|
if (path.Count == 0)
|
||||||
|
{
|
||||||
|
positionX = oldPositionX;
|
||||||
|
positionY = oldPositionY;
|
||||||
|
positionZ = oldPositionZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
positionUpdates = path;
|
||||||
|
|
||||||
|
this.hasMoved = true;
|
||||||
|
this.isAtSpawn = false;
|
||||||
|
|
||||||
|
sw.Stop();
|
||||||
|
((Zone)zone).pathCalls++;
|
||||||
|
((Zone)zone).pathCallTime += sw.ElapsedMilliseconds;
|
||||||
|
Program.Log.Error("[{0}][{1}] Created {2} points in {3} milliseconds", actorId, actorName, path.Count, sw.ElapsedMilliseconds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void FollowTarget(Actor target, float stepSize = 1.2f, int maxPath = 25)
|
||||||
|
{
|
||||||
|
if (target != null)
|
||||||
|
{
|
||||||
|
var player = target as Player;
|
||||||
|
|
||||||
|
if (this.target != target)
|
||||||
|
this.target = target;
|
||||||
|
|
||||||
|
this.moveState = player.moveState;
|
||||||
|
this.moveSpeeds = player.moveSpeeds;
|
||||||
|
|
||||||
|
PathTo(player.positionX, player.positionY, player.positionZ, stepSize, maxPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnPath()
|
||||||
|
{
|
||||||
|
// todo: lua function onPath in mob script
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,8 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
using FFXIVClassic_Map_Server.actors.director;
|
using FFXIVClassic_Map_Server.actors.director;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.actors.area
|
namespace FFXIVClassic_Map_Server.actors.area
|
||||||
|
@ -20,10 +22,31 @@ namespace FFXIVClassic_Map_Server.actors.area
|
||||||
Dictionary<string, List<PrivateAreaContent>> contentAreas = new Dictionary<string, List<PrivateAreaContent>>();
|
Dictionary<string, List<PrivateAreaContent>> contentAreas = new Dictionary<string, List<PrivateAreaContent>>();
|
||||||
Object contentAreasLock = new Object();
|
Object contentAreasLock = new Object();
|
||||||
|
|
||||||
|
public Detour.dtNavMesh navMesh;
|
||||||
|
public SharpNav.TiledNavMesh tiledNavMesh;
|
||||||
|
public SharpNav.NavMeshQuery navMeshQuery;
|
||||||
|
public Int64 pathCalls;
|
||||||
|
public Int64 pathCallTime;
|
||||||
|
|
||||||
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)
|
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)
|
||||||
: base(id, zoneName, regionId, classPath, bgmDay, bgmNight, bgmBattle, isIsolated, isInn, canRideChocobo, canStealth, isInstanceRaid)
|
: base(id, zoneName, regionId, classPath, bgmDay, bgmNight, bgmBattle, isIsolated, isInn, canRideChocobo, canStealth, isInstanceRaid)
|
||||||
{
|
{
|
||||||
|
// central thanalan navmesh
|
||||||
|
if (id == 170)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//navMesh = utils.NavmeshUtils.LoadNavmesh("wil_w0_fld01.bin");
|
||||||
|
tiledNavMesh = utils.NavmeshUtils.LoadNavmesh(tiledNavMesh, "wil_w0_fld01.snb");
|
||||||
|
navMeshQuery = new SharpNav.NavMeshQuery(tiledNavMesh, 100);
|
||||||
|
GC.Collect(2);
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
Program.Log.Error(e.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddPrivateArea(PrivateArea pa)
|
public void AddPrivateArea(PrivateArea pa)
|
||||||
|
|
|
@ -151,8 +151,8 @@ namespace FFXIVClassic_Map_Server.Actors
|
||||||
isStatic = true;
|
isStatic = true;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// charaWork.property[2] = 1;
|
charaWork.property[2] = 1;
|
||||||
// npcWork.hateType = 1;
|
npcWork.hateType = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lParams == null)
|
if (lParams == null)
|
||||||
|
|
169
FFXIVClassic Map Server/bin/Debug/scripts/commands/gm/yolo.lua
Normal file
169
FFXIVClassic Map Server/bin/Debug/scripts/commands/gm/yolo.lua
Normal file
|
@ -0,0 +1,169 @@
|
||||||
|
require("global");
|
||||||
|
|
||||||
|
properties = {
|
||||||
|
permissions = 0,
|
||||||
|
parameters = "ssss",
|
||||||
|
description =
|
||||||
|
[[
|
||||||
|
yolo
|
||||||
|
]],
|
||||||
|
}
|
||||||
|
|
||||||
|
local quests =
|
||||||
|
{
|
||||||
|
[111807] = { level = 25, weight = 4, rewardexp = 1080 },
|
||||||
|
[110868] = { level = 50, weight = 4, rewardexp = 4400 },
|
||||||
|
[111603] = { level = 22, weight = 5, rewardexp = 1100 },
|
||||||
|
[111602] = { level = 22, weight = 5, rewardexp = 1100 },
|
||||||
|
[111420] = { level = 45, weight = 5, rewardexp = 4450 },
|
||||||
|
[110811] = { level = 18, weight = 6, rewardexp = 780 },
|
||||||
|
[110814] = { level = 18, weight = 6, rewardexp = 780 },
|
||||||
|
[110707] = { level = 25, weight = 6, rewardexp = 1620 },
|
||||||
|
[110682] = { level = 34, weight = 6, rewardexp = 3180 },
|
||||||
|
[111202] = { level = 35, weight = 6, rewardexp = 3360 },
|
||||||
|
[111222] = { level = 35, weight = 6, rewardexp = 3360 },
|
||||||
|
[111302] = { level = 35, weight = 6, rewardexp = 3360 },
|
||||||
|
[111223] = { level = 40, weight = 6, rewardexp = 4260 },
|
||||||
|
[110819] = { level = 45, weight = 6, rewardexp = 5340 },
|
||||||
|
[111224] = { level = 45, weight = 6, rewardexp = 5340 },
|
||||||
|
[111225] = { level = 45, weight = 6, rewardexp = 5340 },
|
||||||
|
[110867] = { level = 45, weight = 6, rewardexp = 5340 },
|
||||||
|
[110869] = { level = 45, weight = 6, rewardexp = 5340 },
|
||||||
|
[110708] = { level = 45, weight = 6, rewardexp = 5340 },
|
||||||
|
[110627] = { level = 45, weight = 6, rewardexp = 5340 },
|
||||||
|
[111434] = { level = 50, weight = 6, rewardexp = 6600 },
|
||||||
|
[110850] = { level = 1, weight = 7, rewardexp = 40 },
|
||||||
|
[110851] = { level = 1, weight = 7, rewardexp = 40 },
|
||||||
|
[110841] = { level = 20, weight = 7, rewardexp = 1120 },
|
||||||
|
[110642] = { level = 20, weight = 7, rewardexp = 1120 },
|
||||||
|
[110840] = { level = 20, weight = 7, rewardexp = 1120 },
|
||||||
|
[110727] = { level = 21, weight = 7, rewardexp = 1401 },
|
||||||
|
[111221] = { level = 30, weight = 7, rewardexp = 2661 },
|
||||||
|
[111241] = { level = 30, weight = 7, rewardexp = 2661 },
|
||||||
|
[110687] = { level = 28, weight = 9, rewardexp = 2970 },
|
||||||
|
[110016] = { level = 34, weight = 50, rewardexp = 26500 },
|
||||||
|
[110017] = { level = 38, weight = 50, rewardexp = 32500 },
|
||||||
|
[110019] = { level = 46, weight = 50, rewardexp = 46000 }
|
||||||
|
};
|
||||||
|
|
||||||
|
local expTable = {
|
||||||
|
570, -- 1
|
||||||
|
700,
|
||||||
|
880,
|
||||||
|
1100,
|
||||||
|
1500,
|
||||||
|
1800,
|
||||||
|
2300,
|
||||||
|
3200,
|
||||||
|
4300,
|
||||||
|
5000, -- 10
|
||||||
|
5900,
|
||||||
|
6800,
|
||||||
|
7700,
|
||||||
|
8700,
|
||||||
|
9700,
|
||||||
|
11000,
|
||||||
|
12000,
|
||||||
|
13000,
|
||||||
|
15000,
|
||||||
|
16000, -- 20
|
||||||
|
20000,
|
||||||
|
22000,
|
||||||
|
23000,
|
||||||
|
25000,
|
||||||
|
27000,
|
||||||
|
29000,
|
||||||
|
31000,
|
||||||
|
33000,
|
||||||
|
35000,
|
||||||
|
38000, -- 30
|
||||||
|
45000,
|
||||||
|
47000,
|
||||||
|
50000,
|
||||||
|
53000,
|
||||||
|
56000,
|
||||||
|
59000,
|
||||||
|
62000,
|
||||||
|
65000,
|
||||||
|
68000,
|
||||||
|
71000, -- 40
|
||||||
|
74000,
|
||||||
|
78000,
|
||||||
|
81000,
|
||||||
|
85000,
|
||||||
|
89000,
|
||||||
|
92000,
|
||||||
|
96000,
|
||||||
|
100000,
|
||||||
|
100000,
|
||||||
|
110000 -- 50
|
||||||
|
};
|
||||||
|
|
||||||
|
local commandCost = {
|
||||||
|
["raise"] = 150,
|
||||||
|
["cure"] = 40,
|
||||||
|
["cura"] = 100,
|
||||||
|
["curaga"] = 150,
|
||||||
|
};
|
||||||
|
-- stone: (1, 9) (5, 12) (10, )
|
||||||
|
-- cure: (1, 5) (5, 6) (10, )
|
||||||
|
-- aero: (1, 9) (5, 12) (10, )
|
||||||
|
-- protect: (1, 9) (5, 12) (10, )
|
||||||
|
--[[
|
||||||
|
function onTrigger(player, argc, id, level, weight)
|
||||||
|
id = tonumber(id) or 111807;
|
||||||
|
level = tonumber(level) or quests[id].level;
|
||||||
|
weight = tonumber(weight) or quests[id].weight;
|
||||||
|
local messageId = MESSAGE_TYPE_SYSTEM_ERROR;
|
||||||
|
local sender = "yolo";
|
||||||
|
|
||||||
|
if id == 1 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local message = calcSkillPoint(player, level, weight);
|
||||||
|
if player then
|
||||||
|
player.SendMessage(messageId, sender, string.format("calculated %s | expected %s", message, quests[id].rewardexp));
|
||||||
|
end;
|
||||||
|
printf("calculated %s | expected %s", message, quests[id].rewardexp);
|
||||||
|
end;
|
||||||
|
]]
|
||||||
|
|
||||||
|
function onTrigger(player, argc, skillName, level)
|
||||||
|
local messageId = MESSAGE_TYPE_SYSTEM_ERROR;
|
||||||
|
local sender = "yolo";
|
||||||
|
if player then
|
||||||
|
local pos = player:GetPos();
|
||||||
|
local x = tonumber(pos[0]);
|
||||||
|
local y = tonumber(pos[1]);
|
||||||
|
local z = tonumber(pos[2]);
|
||||||
|
local rot = tonumber(pos[3]);
|
||||||
|
local zone = pos[4];
|
||||||
|
|
||||||
|
printf("%f %f %f", x, y, z);
|
||||||
|
--local x, y, z = player.GetPos();
|
||||||
|
for i = 1, 1 do
|
||||||
|
|
||||||
|
local actor = player.GetZone().SpawnActor(1000070, 'ass', x-(13 + 2*i), y, z);
|
||||||
|
|
||||||
|
actor.FollowTarget(player, 3.2);
|
||||||
|
end;
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
level = tonumber(level) or 1;
|
||||||
|
if player then
|
||||||
|
player.SendMessage(messageId, sender, string.format("name %s | cost %d | level %u", skillName, calculateCommandCost(player, skillName, level), level));
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function calculateCommandCost(player, skillName, level)
|
||||||
|
if skillName and level and commandCost[skillName] then
|
||||||
|
return math.ceil((8000 + (level - 70) * 500) * (commandCost[skillName] * 0.001));
|
||||||
|
end;
|
||||||
|
return 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
function calcSkillPoint(player, lvl, weight)
|
||||||
|
weight = weight / 100
|
||||||
|
|
||||||
|
return math.ceil(expTable[lvl] * weight)
|
||||||
|
end
|
|
@ -120,6 +120,7 @@ namespace FFXIVClassic_Map_Server.dataobjects
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool checkedThisTick = false;
|
||||||
//Add new actors or move
|
//Add new actors or move
|
||||||
for (int i = 0; i < list.Count; i++)
|
for (int i = 0; i < list.Count; i++)
|
||||||
{
|
{
|
||||||
|
@ -131,10 +132,25 @@ namespace FFXIVClassic_Map_Server.dataobjects
|
||||||
if (actorInstanceList.Contains(actor))
|
if (actorInstanceList.Contains(actor))
|
||||||
{
|
{
|
||||||
//Don't send for static characters (npcs)
|
//Don't send for static characters (npcs)
|
||||||
if (actor is Character && ((Character)actor).isStatic)
|
// todo: this is retarded, need actual mob class
|
||||||
|
if (actor is Character && !actor.hasMoved && ((Character)actor).isStatic)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
GetActor().QueuePacket(actor.CreatePositionUpdatePacket(playerActor.actorId));
|
// todo: again, this is retarded but debug stuff
|
||||||
|
var zone = (actors.area.Zone)actor.zone;
|
||||||
|
if(zone != null && !checkedThisTick)
|
||||||
|
{
|
||||||
|
if (zone.pathCalls > 0)
|
||||||
|
{
|
||||||
|
checkedThisTick = true;
|
||||||
|
Program.Log.Error("Number of pathfinding calls {0} average time {1}", zone.pathCalls, zone.pathCallTime / zone.pathCalls);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var packet = actor.CreatePositionUpdatePacket(playerActor.actorId);
|
||||||
|
|
||||||
|
if (packet != null)
|
||||||
|
GetActor().QueuePacket(packet);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -533,11 +533,11 @@ namespace FFXIVClassic_Map_Server.lua
|
||||||
LuaParam.Insert(1, i - (playerNull ? 2 : 0));
|
LuaParam.Insert(1, i - (playerNull ? 2 : 0));
|
||||||
|
|
||||||
// run the script
|
// run the script
|
||||||
//script.Call(script.Globals["onTrigger"], LuaParam.ToArray());
|
script.Call(script.Globals["onTrigger"], LuaParam.ToArray());
|
||||||
|
|
||||||
Coroutine coroutine = script.CreateCoroutine(script.Globals["onTrigger"]).Coroutine;
|
//Coroutine coroutine = script.CreateCoroutine(script.Globals["onTrigger"]).Coroutine;
|
||||||
DynValue value = coroutine.Resume(LuaParam.ToArray());
|
//DynValue value = coroutine.Resume(LuaParam.ToArray());
|
||||||
GetInstance().ResolveResume(player, coroutine, value);
|
//GetInstance().ResolveResume(player, coroutine, value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
1
FFXIVClassic Map Server/navmesh/rcdtcs
Submodule
1
FFXIVClassic Map Server/navmesh/rcdtcs
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 8eea27727df5132c5f0e6732d1bd36238ce300ea
|
|
@ -5,7 +5,7 @@
|
||||||
<package id="Microsoft.Net.Compilers" version="2.0.0-beta3" targetFramework="net45" developmentDependency="true" />
|
<package id="Microsoft.Net.Compilers" version="2.0.0-beta3" targetFramework="net45" developmentDependency="true" />
|
||||||
<package id="MoonSharp" version="1.2.1.0" targetFramework="net45" />
|
<package id="MoonSharp" version="1.2.1.0" targetFramework="net45" />
|
||||||
<package id="MySql.Data" version="6.9.8" targetFramework="net45" />
|
<package id="MySql.Data" version="6.9.8" targetFramework="net45" />
|
||||||
<package id="Newtonsoft.Json" version="8.0.3" targetFramework="net45" />
|
<package id="Newtonsoft.Json" version="10.0.2" targetFramework="net451" />
|
||||||
<package id="NLog" version="4.3.5" targetFramework="net45" />
|
<package id="NLog" version="4.3.5" targetFramework="net45" />
|
||||||
<package id="NLog.Config" version="4.3.5" targetFramework="net45" />
|
<package id="NLog.Config" version="4.3.5" targetFramework="net45" />
|
||||||
<package id="NLog.Schema" version="4.3.4" targetFramework="net45" />
|
<package id="NLog.Schema" version="4.3.4" targetFramework="net45" />
|
||||||
|
|
313
FFXIVClassic Map Server/utils/NavmeshUtils.cs
Normal file
313
FFXIVClassic Map Server/utils/NavmeshUtils.cs
Normal file
|
@ -0,0 +1,313 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.IO;
|
||||||
|
using SharpNav;
|
||||||
|
using SharpNav.Pathfinding;
|
||||||
|
using SharpNav.Crowds;
|
||||||
|
using SharpNav.IO;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.utils
|
||||||
|
{
|
||||||
|
public class Vector3
|
||||||
|
{
|
||||||
|
public float X;
|
||||||
|
public float Y;
|
||||||
|
public float Z;
|
||||||
|
public static Vector3 Zero = new Vector3();
|
||||||
|
|
||||||
|
public Vector3(float x, float y, float z)
|
||||||
|
{
|
||||||
|
X = x;
|
||||||
|
Y = y;
|
||||||
|
Z = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3()
|
||||||
|
{
|
||||||
|
X = 0.0f;
|
||||||
|
Y = 0.0f;
|
||||||
|
Z = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3(SharpNav.Geometry.Vector3 vec)
|
||||||
|
{
|
||||||
|
X = vec.X;
|
||||||
|
Y = vec.Y;
|
||||||
|
Z = vec.Z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector3 operator +(Vector3 lhs, Vector3 rhs)
|
||||||
|
{
|
||||||
|
Vector3 newVec = new Vector3(lhs.X, lhs.Y, lhs.Z);
|
||||||
|
newVec.X += rhs.X;
|
||||||
|
newVec.Y += rhs.Y;
|
||||||
|
newVec.Z += rhs.Z;
|
||||||
|
return newVec;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector3 operator -(Vector3 lhs, Vector3 rhs)
|
||||||
|
{
|
||||||
|
return new Vector3(lhs.X - rhs.X, lhs.Y - rhs.Y, lhs.Z - rhs.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector3 operator *(Vector3 lhs, Vector3 rhs)
|
||||||
|
{
|
||||||
|
return new Vector3(lhs.X * rhs.X, lhs.Y * rhs.Y, lhs.Z * rhs.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector3 operator *(float scalar, Vector3 rhs)
|
||||||
|
{
|
||||||
|
return new Vector3(scalar * rhs.X, scalar * rhs.Y, scalar * rhs.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector3 operator /(Vector3 lhs, Vector3 rhs)
|
||||||
|
{
|
||||||
|
return new Vector3(lhs.X - rhs.X, lhs.Y - rhs.Y, lhs.Z - rhs.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float Length()
|
||||||
|
{
|
||||||
|
return (float)Math.Sqrt(this.LengthSquared());
|
||||||
|
}
|
||||||
|
|
||||||
|
public float LengthSquared()
|
||||||
|
{
|
||||||
|
return (this.X * this.X) + (this.Y * this.Y) + (this.Z * this.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float Dot(Vector3 lhs, Vector3 rhs)
|
||||||
|
{
|
||||||
|
return (lhs.X * rhs.X) + (lhs.Y * rhs.Y) + (lhs.Z * rhs.Z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class NavmeshUtils
|
||||||
|
{
|
||||||
|
|
||||||
|
// navmesh
|
||||||
|
public static bool CanSee(float x1, float y1, float z1, float x2, float y2, float z2)
|
||||||
|
{
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Detour.dtNavMesh LoadNavmesh(string path)
|
||||||
|
{
|
||||||
|
var bytes = File.ReadAllBytes(path);
|
||||||
|
var start = 0;
|
||||||
|
|
||||||
|
var navmesh = Detour.NavMeshSetBuild.FromBytes(bytes, ref start);
|
||||||
|
return navmesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SharpNav.TiledNavMesh LoadNavmesh(TiledNavMesh navmesh, string filePath)
|
||||||
|
{
|
||||||
|
var serialiser = new SharpNav.IO.Json.NavMeshJsonSerializer();
|
||||||
|
return serialiser.Deserialize(filePath);
|
||||||
|
//return navmesh = new SharpNav.IO.Json.NavMeshJsonSerializer().Deserialize(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Vector3> GetPath(Detour.dtNavMesh navmesh, Vector3 start, Vector3 end)
|
||||||
|
{
|
||||||
|
var path = new Vector3[] { };
|
||||||
|
|
||||||
|
|
||||||
|
return path.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
#region sharpnav stuff
|
||||||
|
// Copyright (c) 2013-2016 Robert Rouhani <robert.rouhani@gmail.com> and other contributors (see CONTRIBUTORS file).
|
||||||
|
// Licensed under the MIT License - https://raw.github.com/Robmaister/SharpNav/master/LICENSE
|
||||||
|
|
||||||
|
public static List<Vector3> GetPath(FFXIVClassic_Map_Server.actors.area.Zone zone, Vector3 startVec, Vector3 endVec, float stepSize = 0.70f, int pathSize = 2048)
|
||||||
|
{
|
||||||
|
var navMesh = zone.tiledNavMesh;
|
||||||
|
var navMeshQuery = zone.navMeshQuery;
|
||||||
|
|
||||||
|
if (navMesh == null || (startVec.X == endVec.X && startVec.Y == endVec.Y && startVec.Z == endVec.Z))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
float distanceSquared = FFXIVClassic.Common.Utils.DistanceSquared(startVec.X, startVec.Y, startVec.Z, endVec.X, endVec.Y, endVec.Z);
|
||||||
|
|
||||||
|
// no point pathing if in range
|
||||||
|
if (distanceSquared < 4 && Math.Abs(startVec.Y - endVec.Y) < 1.1f)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var smoothPath = new List<Vector3>(pathSize) { };
|
||||||
|
|
||||||
|
NavQueryFilter filter = new NavQueryFilter();
|
||||||
|
|
||||||
|
NavPoint startPt, endPt;
|
||||||
|
RaycastHit hit;
|
||||||
|
PathCorridor corridor = new PathCorridor();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
SharpNav.Geometry.Vector3 c = new SharpNav.Geometry.Vector3(startVec.X, startVec.Y, startVec.Z);
|
||||||
|
SharpNav.Geometry.Vector3 ep = new SharpNav.Geometry.Vector3(endVec.X, endVec.Y, endVec.Z);
|
||||||
|
|
||||||
|
SharpNav.Geometry.Vector3 e = new SharpNav.Geometry.Vector3(5, 5, 5);
|
||||||
|
navMeshQuery.FindNearestPoly(ref c, ref e, out startPt);
|
||||||
|
navMeshQuery.FindNearestPoly(ref ep, ref e, out endPt);
|
||||||
|
|
||||||
|
//calculate the overall path, which contains an array of polygon references
|
||||||
|
int MAX_POLYS = 256;
|
||||||
|
var path = new SharpNav.Pathfinding.Path();
|
||||||
|
|
||||||
|
navMeshQuery.FindPath(ref startPt, ref endPt, filter, path);
|
||||||
|
|
||||||
|
//find a smooth path over the mesh surface
|
||||||
|
int npolys = path.Count;
|
||||||
|
SharpNav.Geometry.Vector3 iterPos = new SharpNav.Geometry.Vector3();
|
||||||
|
SharpNav.Geometry.Vector3 targetPos = new SharpNav.Geometry.Vector3();
|
||||||
|
navMeshQuery.ClosestPointOnPoly(startPt.Polygon, startPt.Position, ref iterPos);
|
||||||
|
navMeshQuery.ClosestPointOnPoly(path[npolys - 1], endPt.Position, ref targetPos);
|
||||||
|
|
||||||
|
smoothPath.Add(new Vector3(iterPos));
|
||||||
|
|
||||||
|
//float STEP_SIZE = 0.70f;
|
||||||
|
float SLOP = 0.15f;
|
||||||
|
while (npolys > 0 && smoothPath.Count < smoothPath.Capacity)
|
||||||
|
{
|
||||||
|
//find location to steer towards
|
||||||
|
SharpNav.Geometry.Vector3 steerPos = new SharpNav.Geometry.Vector3();
|
||||||
|
StraightPathFlags steerPosFlag = 0;
|
||||||
|
NavPolyId steerPosRef = NavPolyId.Null;
|
||||||
|
|
||||||
|
if (!GetSteerTarget(navMeshQuery, iterPos, targetPos, SLOP, path, ref steerPos, ref steerPosFlag, ref steerPosRef))
|
||||||
|
break;
|
||||||
|
|
||||||
|
bool endOfPath = (steerPosFlag & StraightPathFlags.End) != 0 ? true : false;
|
||||||
|
bool offMeshConnection = (steerPosFlag & StraightPathFlags.OffMeshConnection) != 0 ? true : false;
|
||||||
|
|
||||||
|
//find movement delta
|
||||||
|
SharpNav.Geometry.Vector3 delta = steerPos - iterPos;
|
||||||
|
float len = (float)Math.Sqrt(SharpNav.Geometry.Vector3.Dot(delta, delta));
|
||||||
|
|
||||||
|
//if steer target is at end of path or off-mesh link
|
||||||
|
//don't move past location
|
||||||
|
if ((endOfPath || offMeshConnection) && len < stepSize)
|
||||||
|
len = 1;
|
||||||
|
else
|
||||||
|
len = stepSize / len;
|
||||||
|
|
||||||
|
SharpNav.Geometry.Vector3 moveTgt = new SharpNav.Geometry.Vector3();
|
||||||
|
VMad(ref moveTgt, iterPos, delta, len);
|
||||||
|
|
||||||
|
//move
|
||||||
|
SharpNav.Geometry.Vector3 result = new SharpNav.Geometry.Vector3();
|
||||||
|
List<NavPolyId> visited = new List<NavPolyId>(pathSize);
|
||||||
|
NavPoint startPoint = new NavPoint(path[0], iterPos);
|
||||||
|
navMeshQuery.MoveAlongSurface(ref startPoint, ref moveTgt, out result, visited);
|
||||||
|
path.FixupCorridor(visited);
|
||||||
|
npolys = path.Count;
|
||||||
|
float h = 0;
|
||||||
|
navMeshQuery.GetPolyHeight(path[0], result, ref h);
|
||||||
|
result.Y = h;
|
||||||
|
iterPos = result;
|
||||||
|
|
||||||
|
//handle end of path when close enough
|
||||||
|
if (endOfPath && InRange(iterPos, steerPos, SLOP, 1000.0f))
|
||||||
|
{
|
||||||
|
//reached end of path
|
||||||
|
iterPos = targetPos;
|
||||||
|
if (smoothPath.Count < smoothPath.Capacity)
|
||||||
|
{
|
||||||
|
smoothPath.Add(new Vector3(iterPos));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//store results
|
||||||
|
if (smoothPath.Count < smoothPath.Capacity)
|
||||||
|
{
|
||||||
|
smoothPath.Add(new Vector3(iterPos));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
Program.Log.Error(e.Message);
|
||||||
|
Program.Log.Error("Start pos {0} {1} {2} end pos {3} {4} {5}", startVec.X, startVec.Y, startVec.Z, endVec.X, endVec.Y, endVec.Z);
|
||||||
|
// todo: probably log this
|
||||||
|
return new List<Vector3>() { };
|
||||||
|
}
|
||||||
|
return smoothPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Scaled vector addition
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dest">Result</param>
|
||||||
|
/// <param name="v1">Vector 1</param>
|
||||||
|
/// <param name="v2">Vector 2</param>
|
||||||
|
/// <param name="s">Scalar</param>
|
||||||
|
private static void VMad(ref SharpNav.Geometry.Vector3 dest, SharpNav.Geometry.Vector3 v1, SharpNav.Geometry.Vector3 v2, float s)
|
||||||
|
{
|
||||||
|
dest.X = v1.X + v2.X * s;
|
||||||
|
dest.Y = v1.Y + v2.Y * s;
|
||||||
|
dest.Z = v1.Z + v2.Z * s;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool GetSteerTarget(NavMeshQuery navMeshQuery, SharpNav.Geometry.Vector3 startPos, SharpNav.Geometry.Vector3 endPos, float minTargetDist, SharpNav.Pathfinding.Path path,
|
||||||
|
ref SharpNav.Geometry.Vector3 steerPos, ref StraightPathFlags steerPosFlag, ref NavPolyId steerPosRef)
|
||||||
|
{
|
||||||
|
StraightPath steerPath = new StraightPath();
|
||||||
|
navMeshQuery.FindStraightPath(startPos, endPos, path, steerPath, 0);
|
||||||
|
int nsteerPath = steerPath.Count;
|
||||||
|
if (nsteerPath == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//find vertex far enough to steer to
|
||||||
|
int ns = 0;
|
||||||
|
while (ns < nsteerPath)
|
||||||
|
{
|
||||||
|
if ((steerPath[ns].Flags & StraightPathFlags.OffMeshConnection) != 0 ||
|
||||||
|
!InRange(steerPath[ns].Point.Position, startPos, minTargetDist, 1000.0f))
|
||||||
|
break;
|
||||||
|
|
||||||
|
ns++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//failed to find good point to steer to
|
||||||
|
if (ns >= nsteerPath)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
steerPos = steerPath[ns].Point.Position;
|
||||||
|
steerPos.Y = startPos.Y;
|
||||||
|
steerPosFlag = steerPath[ns].Flags;
|
||||||
|
if (steerPosFlag == StraightPathFlags.None && ns == (nsteerPath - 1))
|
||||||
|
steerPosFlag = StraightPathFlags.End; // otherwise seeks path infinitely!!!
|
||||||
|
steerPosRef = steerPath[ns].Point.Polygon;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool InRange(SharpNav.Geometry.Vector3 v1, SharpNav.Geometry.Vector3 v2, float r, float h)
|
||||||
|
{
|
||||||
|
float dx = v2.X - v1.X;
|
||||||
|
float dy = v2.Y - v1.Y;
|
||||||
|
float dz = v2.Z - v1.Z;
|
||||||
|
return (dx * dx + dz * dz) < (r * r) && Math.Abs(dy) < h;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public static Vector3 GamePosToNavmeshPos(float x, float y, float z)
|
||||||
|
{
|
||||||
|
return new Vector3(x, -z, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector3 NavmeshPosToGamePos(float x, float y, float z)
|
||||||
|
{
|
||||||
|
return new Vector3(x, z, -y);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,6 +8,7 @@ Date: 6/19/2017 10:23:48 PM
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SET FOREIGN_KEY_CHECKS=0;
|
SET FOREIGN_KEY_CHECKS=0;
|
||||||
|
SET autocommit=0;
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Table structure for gamedata_actor_class
|
-- Table structure for gamedata_actor_class
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
|
@ -8007,3 +8008,5 @@ INSERT INTO `gamedata_actor_class` VALUES ('9220405', '', '2', '0', null);
|
||||||
INSERT INTO `gamedata_actor_class` VALUES ('9220406', '', '2', '0', null);
|
INSERT INTO `gamedata_actor_class` VALUES ('9220406', '', '2', '0', null);
|
||||||
INSERT INTO `gamedata_actor_class` VALUES ('9220407', '', '2', '0', null);
|
INSERT INTO `gamedata_actor_class` VALUES ('9220407', '', '2', '0', null);
|
||||||
INSERT INTO `gamedata_actor_class` VALUES ('9220408', '', '2', '0', null);
|
INSERT INTO `gamedata_actor_class` VALUES ('9220408', '', '2', '0', null);
|
||||||
|
|
||||||
|
COMMIT;
|
|
@ -6,6 +6,7 @@ Target Host: localhost
|
||||||
Target Database: ffxiv_server
|
Target Database: ffxiv_server
|
||||||
Date: 6/19/2017 10:24:01 PM
|
Date: 6/19/2017 10:24:01 PM
|
||||||
*/
|
*/
|
||||||
|
DROP TABLE IF EXISTS `server_spawn_locations`;
|
||||||
|
|
||||||
SET FOREIGN_KEY_CHECKS=0;
|
SET FOREIGN_KEY_CHECKS=0;
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
|
|
Loading…
Add table
Reference in a new issue