Esempio n. 1
0
        public List <Character> GetCharactersRange(Vector3 position, int range)
        {
            List <Character> characters = new List <Character>();

            foreach (NecClient client in ClientLookup.GetAll())
            {
                Character character    = client.Character;
                Vector3   characterPos = new Vector3(character.X, character.Y, character.Z);
                if (Vector3.Distance(position, characterPos) <= range)
                {
                    characters.Add(character);
                }
            }

            return(characters);
        }
Esempio n. 2
0
        public void Leave(NecClient client)
        {
            Logger.Info(client, $"Leaving Map: {Id}:{FullName}");
            ClientLookup.Remove(client);
            if (!_server.Database.UpdateCharacter(client.Character))
            {
                Logger.Error("Could not update the database with last known player position");
            }

            client.Map = null;

            RecvObjectDisappearNotify objectDisappearData = new RecvObjectDisappearNotify(client.Character.InstanceId);

            _server.Router.Send(this, objectDisappearData, client);
            if (ClientLookup.GetAll().Count == 0)
            {
                foreach (MonsterSpawn monsterSpawn in this.MonsterSpawns.Values)
                {
                    monsterSpawn.SpawnActive = false;
                }
            }

            Logger.Debug($"Client Lookup count is now : {ClientLookup.GetAll().Count}  for map  {this.Id} ");
        }
Esempio n. 3
0
        public Map(MapData mapData, NecServer server)
        {
            _server             = server;
            clientLookup        = new ClientLookup();
            this.npcSpawns      = new Dictionary <uint, NpcSpawn>();
            this.monsterSpawns  = new Dictionary <uint, MonsterSpawn>();
            this.gimmickSpawns  = new Dictionary <uint, Gimmick>();
            this.mapTransitions = new Dictionary <uint, MapTransition>();
            this.gGateSpawns    = new Dictionary <uint, GGateSpawn>();
            deadBodies          = new Dictionary <uint, DeadBody>();


            id          = mapData.id;
            x           = mapData.x;
            y           = mapData.y;
            z           = mapData.z;
            country     = mapData.country;
            area        = mapData.area;
            place       = mapData.place;
            orientation = (byte)(mapData.orientation / 2); // Client uses 180 degree orientation
            traps       = new Dictionary <uint, TrapStack>();

            List <MapTransition> mapTransitions = server.database.SelectMapTransitionsByMapId(mapData.id);

            foreach (MapTransition mapTran in mapTransitions)
            {
                if (mapTran.id == 0) //Only one special transition
                {
                    double angle = mapTran.maplinkHeading / 255.0;
                    mapTran.leftPos.X  = (float)((mapTran.referencePos.X + mapTran.maplinkWidth / 2) * Math.Cos(angle));
                    mapTran.leftPos.Y  = (float)(mapTran.referencePos.Y * Math.Cos(angle));
                    mapTran.rightPos.X = (float)((mapTran.referencePos.X - mapTran.maplinkWidth / 2) * Math.Cos(angle));
                    mapTran.rightPos.Y = mapTran.referencePos.Y + mapTran.maplinkWidth / 2;
                }
                else if (mapTran.invertedTransition != true) //map is x dominant
                {
                    mapTran.leftPos.X  = mapTran.referencePos.X + mapTran.maplinkWidth / 2;
                    mapTran.leftPos.Y  = mapTran.referencePos.Y;
                    mapTran.rightPos.X = mapTran.referencePos.X - mapTran.maplinkWidth / 2;
                    mapTran.rightPos.Y = mapTran.referencePos.Y;
                }
                else if (mapTran.invertedTransition) //map is y dominant
                {
                    mapTran.leftPos.X  = mapTran.referencePos.X;
                    mapTran.leftPos.Y  = mapTran.referencePos.Y + mapTran.maplinkWidth / 2;
                    mapTran.rightPos.X = mapTran.referencePos.X;
                    mapTran.rightPos.Y = mapTran.referencePos.Y - mapTran.maplinkWidth / 2;
                }

                server.instances.AssignInstance(mapTran);
                this.mapTransitions.Add(mapTran.instanceId, mapTran);
                _Logger.Debug($"Loaded Map transition {mapTran.id} on map {fullName}");
            }

            //Assign Unique Instance ID to each NPC per map. Add to dictionary stored with the Map object
            List <NpcSpawn> npcSpawns = server.database.SelectNpcSpawnsByMapId(mapData.id);

            foreach (NpcSpawn npcSpawn in npcSpawns)
            {
                server.instances.AssignInstance(npcSpawn);
                this.npcSpawns.Add(npcSpawn.instanceId, npcSpawn);
            }

            //Assign Unique Instance ID to each Gimmick per map. Add to dictionary stored with the Map object
            List <Gimmick> gimmickSpawns = server.database.SelectGimmicksByMapId(mapData.id);

            foreach (Gimmick gimmickSpawn in gimmickSpawns)
            {
                server.instances.AssignInstance(gimmickSpawn);
                this.gimmickSpawns.Add(gimmickSpawn.instanceId, gimmickSpawn);
            }

            List <GGateSpawn> gGateSpawns = server.database.SelectGGateSpawnsByMapId(mapData.id);

            foreach (GGateSpawn gGateSpawn in gGateSpawns)
            {
                server.instances.AssignInstance(gGateSpawn);
                this.gGateSpawns.Add(gGateSpawn.instanceId, gGateSpawn);
            }

            //To-Do   | for each deadBody in Deadbodies {RecvDataNotifyCharabodyData}

            List <MonsterSpawn> monsterSpawns = server.database.SelectMonsterSpawnsByMapId(mapData.id);

            foreach (MonsterSpawn monsterSpawn in monsterSpawns)
            {
                server.instances.AssignInstance(monsterSpawn);
                if (!_server.settingRepository.modelCommon.TryGetValue(monsterSpawn.modelId,
                                                                       out ModelCommonSetting modelSetting))
                {
                    _Logger.Error($"Error getting ModelCommonSetting for ModelId {monsterSpawn.modelId}");
                    continue;
                }

                if (!_server.settingRepository.monster.TryGetValue(monsterSpawn.monsterId,
                                                                   out MonsterSetting monsterSetting))
                {
                    _Logger.Error($"Error getting MonsterSetting for MonsterId {monsterSpawn.monsterId}");
                    continue;
                }

                monsterSpawn.modelId = modelSetting.id;
                //monsterSpawn.Size = (short) (modelSetting.Height / 2);   //commenting out to use size setting from database.
                monsterSpawn.radius = (short)modelSetting.radius;
                monsterSpawn.hp.SetMax(300);
                monsterSpawn.hp.SetCurrent(300);
                monsterSpawn.attackSkillId = monsterSetting.attackSkillId;
                //monsterSpawn.Level = (byte) monsterSetting.Level;
                monsterSpawn.combatMode  = monsterSetting.combatMode;
                monsterSpawn.catalogId   = monsterSetting.catalogId;
                monsterSpawn.textureType = monsterSetting.textureType;
                monsterSpawn.map         = this;
                this.monsterSpawns.Add(monsterSpawn.instanceId, monsterSpawn);

                List <MonsterCoord> coords = server.database.SelectMonsterCoordsByMonsterId(monsterSpawn.id);
                if (coords.Count > 0)
                {
                    monsterSpawn.defaultCoords = false;
                    monsterSpawn.monsterCoords.Clear();
                    foreach (MonsterCoord monsterCoord in coords)
                    {
                        //Console.WriteLine($"added coord {monsterCoord} to monster {monsterSpawn.InstanceId}");
                        monsterSpawn.monsterCoords.Add(monsterCoord);
                    }
                }
                else
                {
                    //home coordinate set to monster X,Y,Z from database
                    Vector3      homeVector3 = new Vector3(monsterSpawn.x, monsterSpawn.y, monsterSpawn.z);
                    MonsterCoord homeCoord   = new MonsterCoord();
                    homeCoord.id          = monsterSpawn.id;
                    homeCoord.monsterId   = (uint)monsterSpawn.monsterId;
                    homeCoord.mapId       = (uint)monsterSpawn.mapId;
                    homeCoord.coordIdx    = 0;
                    homeCoord.destination = homeVector3;
                    monsterSpawn.monsterCoords.Add(homeCoord);

                    //default path part 2
                    Vector3 defaultVector3 = new Vector3(monsterSpawn.x, monsterSpawn.y + Util.GetRandomNumber(50, 150),
                                                         monsterSpawn.z);
                    MonsterCoord defaultCoord = new MonsterCoord();
                    defaultCoord.id          = monsterSpawn.id;
                    defaultCoord.monsterId   = (uint)monsterSpawn.monsterId;
                    defaultCoord.mapId       = (uint)monsterSpawn.mapId;
                    defaultCoord.coordIdx    = 1;
                    defaultCoord.destination = defaultVector3;

                    monsterSpawn.monsterCoords.Add(defaultCoord);

                    //default path part 3
                    Vector3 defaultVector32 = new Vector3(monsterSpawn.x + Util.GetRandomNumber(50, 150),
                                                          monsterSpawn.y + Util.GetRandomNumber(50, 150), monsterSpawn.z);
                    MonsterCoord defaultCoord2 = new MonsterCoord();
                    defaultCoord2.id          = monsterSpawn.id;
                    defaultCoord2.monsterId   = (uint)monsterSpawn.monsterId;
                    defaultCoord2.mapId       = (uint)monsterSpawn.mapId;
                    defaultCoord2.coordIdx    = 2; //64 is currently the Idx of monsterHome on send_map_get_info.cs
                    defaultCoord2.destination = defaultVector32;

                    monsterSpawn.monsterCoords.Add(defaultCoord2);
                }
            }
        }
Esempio n. 4
0
 public Map()
 {
     _logger      = LogProvider.Logger <NecLogger>(this);
     ClientLookup = new ClientLookup();
 }
Esempio n. 5
0
        public Map(MapSetting setting, NecServer server)
        {
            _server        = server;
            ClientLookup   = new ClientLookup();
            NpcSpawns      = new Dictionary <uint, NpcSpawn>();
            MonsterSpawns  = new Dictionary <uint, MonsterSpawn>();
            GimmickSpawns  = new Dictionary <uint, Gimmick>();
            MapTransitions = new Dictionary <uint, MapTransition>();
            GGateSpawns    = new Dictionary <uint, GGateSpawn>();
            DeadBodies     = new Dictionary <uint, DeadBody>();


            Id          = setting.Id;
            X           = setting.X;
            Y           = setting.Y;
            Z           = setting.Z;
            Country     = setting.Country;
            Area        = setting.Area;
            Place       = setting.Place;
            Orientation = (byte)(setting.Orientation / 2);  // Client uses 180 degree orientation
            Traps       = new Dictionary <uint, TrapStack>();

            List <MapTransition> mapTransitions = server.Database.SelectMapTransitionsByMapId(setting.Id);

            foreach (MapTransition mapTran in mapTransitions)
            {
                server.Instances.AssignInstance(mapTran);
                mapTran.Start(_server, this);
                MapTransitions.Add(mapTran.InstanceId, mapTran);
            }

            //Assign Unique Instance ID to each NPC per map. Add to dictionary stored with the Map object
            List <NpcSpawn> npcSpawns = server.Database.SelectNpcSpawnsByMapId(setting.Id);

            foreach (NpcSpawn npcSpawn in npcSpawns)
            {
                server.Instances.AssignInstance(npcSpawn);
                NpcSpawns.Add(npcSpawn.InstanceId, npcSpawn);
            }

            //Assign Unique Instance ID to each Gimmick per map. Add to dictionary stored with the Map object
            List <Gimmick> gimmickSpawns = server.Database.SelectGimmicksByMapId(setting.Id);

            foreach (Gimmick gimmickSpawn in gimmickSpawns)
            {
                server.Instances.AssignInstance(gimmickSpawn);
                GimmickSpawns.Add(gimmickSpawn.InstanceId, gimmickSpawn);
            }

            List <GGateSpawn> gGateSpawns = server.Database.SelectGGateSpawnsByMapId(setting.Id);

            foreach (GGateSpawn gGateSpawn in gGateSpawns)
            {
                server.Instances.AssignInstance(gGateSpawn);
                GGateSpawns.Add(gGateSpawn.InstanceId, gGateSpawn);
            }

            //To-Do   | for each deadBody in Deadbodies {RecvDataNotifyCharabodyData}

            List <MonsterSpawn> monsterSpawns = server.Database.SelectMonsterSpawnsByMapId(setting.Id);

            foreach (MonsterSpawn monsterSpawn in monsterSpawns)
            {
                server.Instances.AssignInstance(monsterSpawn);
                if (!_server.SettingRepository.ModelCommon.TryGetValue(monsterSpawn.ModelId,
                                                                       out ModelCommonSetting modelSetting))
                {
                    Logger.Error($"Error getting ModelCommonSetting for ModelId {monsterSpawn.ModelId}");
                    continue;
                }

                if (!_server.SettingRepository.Monster.TryGetValue(monsterSpawn.MonsterId,
                                                                   out MonsterSetting monsterSetting))
                {
                    Logger.Error($"Error getting MonsterSetting for MonsterId {monsterSpawn.MonsterId}");
                    continue;
                }

                monsterSpawn.ModelId = modelSetting.Id;
                monsterSpawn.Size    = (short)(modelSetting.Height / 2);
                monsterSpawn.Radius  = (short)modelSetting.Radius;
                monsterSpawn.Hp.setMax(300);
                monsterSpawn.Hp.setCurrent(300);
                monsterSpawn.AttackSkillId = monsterSetting.AttackSkillId;
                monsterSpawn.Level         = (byte)monsterSetting.Level;
                monsterSpawn.CombatMode    = monsterSetting.CombatMode;
                monsterSpawn.CatalogId     = monsterSetting.CatalogId;
                monsterSpawn.TextureType   = monsterSetting.TextureType;
                monsterSpawn.Map           = this;
                MonsterSpawns.Add(monsterSpawn.InstanceId, monsterSpawn);

                List <MonsterCoord> coords = server.Database.SelectMonsterCoordsByMonsterId(monsterSpawn.Id);
                if (coords.Count > 0)
                {
                    monsterSpawn.defaultCoords = false;
                    monsterSpawn.monsterCoords.Clear();
                    foreach (MonsterCoord monsterCoord in coords)
                    {
                        //Console.WriteLine($"added coord {monsterCoord} to monster {monsterSpawn.InstanceId}");
                        monsterSpawn.monsterCoords.Add(monsterCoord);
                    }
                }
                else
                {
                    //home coordinate set to monster X,Y,Z from database
                    Vector3      homeVector3 = new Vector3(monsterSpawn.X, monsterSpawn.Y, monsterSpawn.Z);
                    MonsterCoord homeCoord   = new MonsterCoord();
                    homeCoord.Id          = monsterSpawn.Id;
                    homeCoord.MonsterId   = (uint)monsterSpawn.MonsterId;
                    homeCoord.MapId       = (uint)monsterSpawn.MapId;
                    homeCoord.CoordIdx    = 0;
                    homeCoord.destination = homeVector3;
                    monsterSpawn.monsterCoords.Add(homeCoord);

                    //default path part 2
                    Vector3 defaultVector3 = new Vector3(monsterSpawn.X, monsterSpawn.Y + Util.GetRandomNumber(50, 150),
                                                         monsterSpawn.Z);
                    MonsterCoord defaultCoord = new MonsterCoord();
                    defaultCoord.Id          = monsterSpawn.Id;
                    defaultCoord.MonsterId   = (uint)monsterSpawn.MonsterId;
                    defaultCoord.MapId       = (uint)monsterSpawn.MapId;
                    defaultCoord.CoordIdx    = 1;
                    defaultCoord.destination = defaultVector3;

                    monsterSpawn.monsterCoords.Add(defaultCoord);

                    //default path part 3
                    Vector3 defaultVector32 = new Vector3(monsterSpawn.X + Util.GetRandomNumber(50, 150),
                                                          monsterSpawn.Y + Util.GetRandomNumber(50, 150), monsterSpawn.Z);
                    MonsterCoord defaultCoord2 = new MonsterCoord();
                    defaultCoord2.Id          = monsterSpawn.Id;
                    defaultCoord2.MonsterId   = (uint)monsterSpawn.MonsterId;
                    defaultCoord2.MapId       = (uint)monsterSpawn.MapId;
                    defaultCoord2.CoordIdx    = 2; //64 is currently the Idx of monsterHome on send_map_get_info.cs
                    defaultCoord2.destination = defaultVector32;

                    monsterSpawn.monsterCoords.Add(defaultCoord2);
                }
            }
        }
Esempio n. 6
0
        public void Enter(NecClient client, MapPosition mapPosition = null)
        {
            if (client.Map != null)
            {
                client.Map.Leave(client);
            }

            Logger.Info(client, $"Entering Map: {Id}:{FullName}");
            // If position is passed in use it and set character position, if null then use map default coords
            // If this isn't set here, the wrong coords are in character until send_movement_info updates it.
            if (mapPosition != null)
            {
                client.Character.X       = mapPosition.X;
                client.Character.Y       = mapPosition.Y;
                client.Character.Z       = mapPosition.Z;
                client.Character.Heading = mapPosition.Heading;
            }
            else
            {
                client.Character.X       = this.X;
                client.Character.Y       = this.Y;
                client.Character.Z       = this.Z;
                client.Character.Heading = this.Orientation;
            }

            client.Map                 = this;
            client.Character.MapId     = Id;
            client.Character.mapChange = false;
            ClientLookup.Add(client);
            Logger.Debug($"Client Lookup count is now : {ClientLookup.GetAll().Count}  for map  {this.Id} ");

            RecvDataNotifyCharaData myCharacterData = new RecvDataNotifyCharaData(client.Character, client.Soul.Name);

            _server.Router.Send(this, myCharacterData, client);
            if (client.Union != null)
            {
                RecvDataNotifyUnionData myUnionData = new RecvDataNotifyUnionData(client.Character, client.Union.Name);
                _server.Router.Send(this, myUnionData, client);
            }

            foreach (MonsterSpawn monsterSpawn in this.MonsterSpawns.Values)
            {
                if (monsterSpawn.Active == true)
                {
                    monsterSpawn.SpawnActive = true;
                    if (!monsterSpawn.TaskActive)
                    {
                        MonsterTask monsterTask = new MonsterTask(_server, monsterSpawn);
                        if (monsterSpawn.defaultCoords)
                        {
                            monsterTask.monsterHome = monsterSpawn.monsterCoords[0];
                        }
                        else
                        {
                            monsterTask.monsterHome = monsterSpawn.monsterCoords.Find(x => x.CoordIdx == 64);
                        }
                        monsterTask.Start();
                    }
                    else
                    {
                        if (monsterSpawn.MonsterVisible)
                        {
                            Logger.Debug($"MonsterTask already running for [{monsterSpawn.Name}]");
                            RecvDataNotifyMonsterData monsterData = new RecvDataNotifyMonsterData(monsterSpawn);
                            _server.Router.Send(monsterData, client);
                            if (!monsterSpawn.GetAgro())
                            {
                                monsterSpawn.MonsterMove(_server, client, monsterSpawn.MonsterWalkVelocity, (byte)2,
                                                         (byte)0);
                            }
                        }
                    }
                }
            }

            //on successful map entry, update the client database position
            if (!_server.Database.UpdateCharacter(client.Character))
            {
                Logger.Error("Could not update the database with current known player position");
            }
        }