mirror of
				https://bitbucket.org/Ioncannon/project-meteor-server.git
				synced 2025-05-20 08:26:59 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			221 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			221 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| /*
 | |
| ===========================================================================
 | |
| Copyright (C) 2015-2019 Project Meteor Dev Team
 | |
| 
 | |
| This file is part of Project Meteor Server.
 | |
| 
 | |
| Project Meteor Server is free software: you can redistribute it and/or modify
 | |
| it under the terms of the GNU Affero General Public License as published by
 | |
| the Free Software Foundation, either version 3 of the License, or
 | |
| (at your option) any later version.
 | |
| 
 | |
| Project Meteor Server is distributed in the hope that it will be useful,
 | |
| but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 | |
| GNU Affero General Public License for more details.
 | |
| 
 | |
| You should have received a copy of the GNU Affero General Public License
 | |
| along with Project Meteor Server. If not, see <https:www.gnu.org/licenses/>.
 | |
| ===========================================================================
 | |
| */
 | |
| 
 | |
| using Meteor.Common;
 | |
| using Meteor.Map.Actors;
 | |
| using Meteor.Map.lua;
 | |
| using Meteor.Map.packets.send.actor;
 | |
| using System;
 | |
| using System.Collections.Generic;
 | |
| using Meteor.Map.actors.director;
 | |
| 
 | |
| namespace Meteor.Map.actors.area
 | |
| {
 | |
|     class Zone : Area
 | |
|     {        
 | |
|         Dictionary<string, Dictionary<uint, PrivateArea>> privateAreas = new Dictionary<string, Dictionary<uint, PrivateArea>>();
 | |
|         Dictionary<string, List<PrivateAreaContent>> contentAreas = new Dictionary<string, List<PrivateAreaContent>>();
 | |
|         object contentAreasLock = new object();
 | |
| 
 | |
|         public SharpNav.TiledNavMesh tiledNavMesh;
 | |
|         public SharpNav.NavMeshQuery navMeshQuery;
 | |
| 
 | |
|         public long pathCalls;
 | |
|         public long prevPathCalls = 0;
 | |
|         public long 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, bool loadNavMesh = false)
 | |
|             : base(id, zoneName, regionId, classPath, bgmDay, bgmNight, bgmBattle, isIsolated, isInn, canRideChocobo, canStealth, isInstanceRaid)
 | |
|         {
 | |
|             if (loadNavMesh)
 | |
|             {
 | |
|                 try
 | |
|                 {
 | |
|                     tiledNavMesh = utils.NavmeshUtils.LoadNavmesh(tiledNavMesh, zoneName + ".snb");
 | |
|                     navMeshQuery = new SharpNav.NavMeshQuery(tiledNavMesh, 100);
 | |
| 
 | |
|                     if (tiledNavMesh != null && tiledNavMesh.Tiles[0].PolyCount > 0)
 | |
|                         Program.Log.Info($"Loaded navmesh for {zoneName}");
 | |
|                 }
 | |
|                 catch (Exception e)
 | |
|                 {
 | |
|                     Program.Log.Error(e.Message);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public void AddPrivateArea(PrivateArea pa)
 | |
|         {
 | |
|             if (privateAreas.ContainsKey(pa.GetPrivateAreaName()))
 | |
|                 privateAreas[pa.GetPrivateAreaName()][pa.GetPrivateAreaType()] = pa;
 | |
|             else
 | |
|             {
 | |
|                 privateAreas[pa.GetPrivateAreaName()] = new Dictionary<uint, PrivateArea>();
 | |
|                 privateAreas[pa.GetPrivateAreaName()][pa.GetPrivateAreaType()] = pa;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public PrivateArea GetPrivateArea(string type, uint number)
 | |
|         {
 | |
|             if (privateAreas.ContainsKey(type))
 | |
|             {
 | |
|                 Dictionary<uint, PrivateArea> instances = privateAreas[type];
 | |
|                 if (instances.ContainsKey(number))
 | |
|                     return instances[number];
 | |
|                 else
 | |
|                     return null;
 | |
|             }
 | |
|             else
 | |
|                 return null;
 | |
|         }
 | |
| 
 | |
|         public override SubPacket CreateScriptBindPacket()
 | |
|         {
 | |
|             bool isEntranceDesion = false;
 | |
| 
 | |
|             List<LuaParam> lParams;
 | |
|             lParams = LuaUtils.CreateLuaParamList(classPath, false, true, zoneName, "", -1, canRideChocobo ? (byte)1 : (byte)0, canStealth, isInn, false, false, false, true, isInstanceRaid, isEntranceDesion);
 | |
|             return ActorInstantiatePacket.BuildPacket(actorId, actorName, className, lParams);        
 | |
|         }
 | |
| 
 | |
|         public void AddSpawnLocation(SpawnLocation spawn)
 | |
|         {
 | |
|             //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))
 | |
|                         levels[spawn.privAreaLevel].AddSpawnLocation(spawn);
 | |
|                     else
 | |
|                         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);
 | |
|                 }
 | |
|                 else
 | |
|                     Program.Log.Error("Tried to add a spawn location to non-existing private area \"{0}\" in zone {1}", spawn.privAreaName, zoneName);
 | |
|             }
 | |
|             else            
 | |
|                 mSpawnLocations.Add(spawn);            
 | |
|         }
 | |
| 
 | |
|         public void SpawnAllActors(bool doPrivAreas)
 | |
|         {
 | |
|             foreach (SpawnLocation spawn in mSpawnLocations)            
 | |
|                 SpawnActor(spawn);
 | |
| 
 | |
|             if (doPrivAreas)
 | |
|             {
 | |
|                 foreach (Dictionary<uint, PrivateArea> areas in privateAreas.Values)
 | |
|                 {
 | |
|                     foreach (PrivateArea pa in areas.Values)
 | |
|                         pa.SpawnAllActors();
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public Actor FindActorInZone(uint id)
 | |
|         {
 | |
|             lock (mActorList)
 | |
|             {
 | |
|                 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;
 | |
|                         }
 | |
|                     }
 | |
| 
 | |
|                     foreach (List<PrivateAreaContent> paList in contentAreas.Values)
 | |
|                     {
 | |
|                         foreach (PrivateArea pa in paList)
 | |
|                         {
 | |
|                             Actor actor = pa.FindActorInArea(id);
 | |
|                             if (actor != null)
 | |
|                                 return actor;
 | |
|                         }
 | |
|                     }
 | |
| 
 | |
| 
 | |
|                     return null;
 | |
|                 }
 | |
|                 else
 | |
|                     return mActorList[id];
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public PrivateAreaContent CreateContentArea(Player starterPlayer, string areaClassPath, string contentScript, string areaName, string directorName, params object[] args)
 | |
|         {
 | |
|             lock (contentAreasLock)
 | |
|             {
 | |
|                 Director director = CreateDirector(directorName, true, args);
 | |
| 
 | |
|                 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;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public void DeleteContentArea(PrivateAreaContent area)
 | |
|         {
 | |
|             if (contentAreas.ContainsKey(area.GetPrivateAreaName()))
 | |
|             {
 | |
|                 contentAreas[area.GetPrivateAreaName()].Remove(area);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public override void Update(DateTime tick)
 | |
|         {
 | |
|             base.Update(tick);
 | |
| 
 | |
|             foreach (var a in privateAreas.Values)
 | |
|                 foreach(var b in a.Values)
 | |
|                     b.Update(tick);
 | |
| 
 | |
|             foreach (var a in contentAreas.Values)
 | |
|                 foreach (var b in a)
 | |
|                     b.Update(tick);
 | |
| 
 | |
|             // todo: again, this is retarded but debug stuff
 | |
|             var diffTime = tick - lastUpdate;
 | |
|             
 | |
|             if (diffTime.TotalSeconds >= 10)
 | |
|             {
 | |
|                 if (this.pathCalls > 0)
 | |
|                 {
 | |
|                     Program.Log.Debug("Number of pathfinding calls {0} average time {1}ms. {2} this tick", pathCalls, (float)(pathCallTime / pathCalls), pathCalls - prevPathCalls);
 | |
|                     prevPathCalls = pathCalls;
 | |
|                 }
 | |
|                 lastUpdate = tick;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| }
 |