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); } } }
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); } } }