public void MonsterMove(NecServer server, int monsterVelocity, byte pose, byte animation,
                                MonsterCoord monsterCoord = null)
        {
            if (monsterCoord == null)
            {
                monsterCoord = monsterCoords[currentCoordIndex];
            }
            Vector3 destPos = new Vector3(monsterCoord.destination.X, monsterCoord.destination.Y,
                                          monsterCoord.destination.Z);
            Vector3 monsterPos = new Vector3(x, y, z);
            Vector3 moveTo     = Vector3.Subtract(destPos, monsterPos);
            float   distance   = Vector3.Distance(monsterPos, destPos);
            float   travelTime = distance / monsterVelocity;
            float   xTick      = moveTo.X / travelTime;
            float   yTick      = moveTo.Y / travelTime;
            float   zTick      = moveTo.Z / travelTime;

            IBuffer res = BufferProvider.Provide();

            res.WriteUInt32(instanceId); //Monster ID
            res.WriteFloat(x);
            res.WriteFloat(y);
            res.WriteFloat(z);
            res.WriteFloat(moveTo.X);       //X per tick
            res.WriteFloat(moveTo.Y);       //Y Per tick
            res.WriteFloat(1);              //verticalMovementSpeedMultiplier

            res.WriteFloat(1 / travelTime); //movementMultiplier
            res.WriteFloat(travelTime);     //Seconds to move

            res.WriteByte(pose);            //MOVEMENT ANIM
            res.WriteByte(animation);       //JUMP & FALLING ANIM
            server.router.Send(map, (ushort)AreaPacketId.recv_0x8D92, res, ServerType.Area);
        }
        public void MonsterMove(NecServer server, NecClient client, int monsterVelocity, byte pose, byte animation,
                                MonsterCoord monsterCoord = null)
        {
            if (monsterCoord == null)
            {
                monsterCoord = monsterCoords[CurrentCoordIndex];
            }
            Vector3 destPos = new Vector3(monsterCoord.destination.X, monsterCoord.destination.Y,
                                          monsterCoord.destination.Z);
            Vector3 monsterPos = new Vector3(this.X, this.Y, this.Z);
            Vector3 moveTo     = Vector3.Subtract(destPos, monsterPos);
            float   distance   = Vector3.Distance(monsterPos, destPos);
            float   travelTime = distance / monsterVelocity;

            IBuffer res = BufferProvider.Provide();

            res.WriteUInt32(this.InstanceId); //Monster ID
            res.WriteFloat(this.X);
            res.WriteFloat(this.Y);
            res.WriteFloat(this.Z);
            res.WriteFloat(moveTo.X);              //X per tick
            res.WriteFloat(moveTo.Y);              //Y Per tick
            res.WriteFloat((float)1);              //verticalMovementSpeedMultiplier

            res.WriteFloat((float)1 / travelTime); //movementMultiplier
            res.WriteFloat((float)travelTime);     //Seconds to move

            res.WriteByte(pose);                   //MOVEMENT ANIM
            res.WriteByte(animation);              //JUMP & FALLING ANIM
            server.Router.Send(client, (ushort)AreaPacketId.recv_0x8D92, res,
                               ServerType.Area);   //recv_0xE8B9  recv_0x1FC1
        }
        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);
                }
            }
        }
Example #4
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);
                }
            }
        }