Exemplo n.º 1
0
        public void Enter(NecClient client, MapPosition mapPosition = null)
        {
            if (client.map != null)
            {
                client.map.Leave(client);
            }
            client.map = this;

            _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;
            }
            //set character coords to default map entry coords If arriving form another map.
            else if (client.character.mapId != id)
            {
                client.character.x       = x;
                client.character.y       = y;
                client.character.z       = z;
                client.character.heading = orientation;
            }

            client.character.mapId     = id;
            client.character.mapChange = false;
            clientLookup.Add(client);
            _Logger.Debug($"Client Lookup count is now : {clientLookup.GetAll().Count}  for map  {id} ");
            _Logger.Debug($"Character State for character {client.character.name} is {client.character.state}");
            //Send your character data to the other living or dead players on the map.

            //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");
            }
            if (!_server.database.UpdateSoul(client.soul))
            {
                _Logger.Error("Could not update the database with soul details ");
            }

            //ToDo  move all this rendering logic to Send_Map_Entry.   We dont need a copy of this logic on every map instance.
            RecvDataNotifyCharaData myCharacterData = new RecvDataNotifyCharaData(client.character, client.soul.name);

            //dead
            //you are dead here.  only getting soul form characters. sorry bro.
            if (client.character.state.HasFlag(CharacterState.SoulForm))
            {
                foreach (NecClient otherClient in clientLookup.GetAll())
                {
                    if (otherClient == client)
                    {
                        continue;
                    }
                    if (otherClient.character.state.HasFlag(CharacterState.SoulForm))
                    {
                        _server.router.Send(myCharacterData, otherClient);
                    }
                }
            }
            else //Bro, you alive! You gon see living characters!
            {
                foreach (NecClient otherClient in clientLookup.GetAll())
                {
                    if (otherClient == client)
                    {
                        continue;
                    }
                    if (otherClient.character.state.HasFlag(CharacterState.SoulForm))
                    {
                        continue;
                    }
                    _server.router.Send(myCharacterData, otherClient);
                }
            }

            if (client.union != null)
            {
                RecvDataNotifyUnionData myUnionData = new RecvDataNotifyUnionData(client.character, client.union.name);
                _server.router.Send(this, myUnionData, client);
            }

            Task.Delay(TimeSpan.FromSeconds(10)).ContinueWith
                (t1 =>
            {
                foreach (MonsterSpawn monsterSpawn in monsterSpawns.Values)
                {
                    if (monsterSpawn.active)
                    {
                        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, 2,
                                                             0);
                                }
                            }
                        }
                    }
                }
            }
                );
        }
        private void AttackObjectsInRange(NecClient client, int damage)
        {
            float perHp = 100.0f;

            //Damage Players in range
            foreach (NecClient targetClient in client.map.clientLookup.GetAll())
            {
                if (targetClient == client)
                {
                    continue;                         //skip damaging yourself
                }
                if (targetClient.character.partyId == client.character.partyId && client.character.partyId != 0)
                {
                    continue;                                                                                              //skip damaging party members
                }
                //if (targetClient.Soul.CriminalLevel == 0 && client.CriminalOnlyDamage == true) continue; //skip attacking non criminal players.  TODO

                double distanceToCharacter = Distance(targetClient.character.x, targetClient.character.y,
                                                      client.character.x, client.character.y);
                _Logger.Debug(
                    $"target Character name [{targetClient.character.name}] distanceToCharacter [{distanceToCharacter}] Radius { /*[{monsterSpawn.Radius}]*/" 125 "} {targetClient.character.name}");
                if (distanceToCharacter > /*targetClient.Character.Radius +*/ 125)
                {
                    continue;
                }

                if (targetClient.character.hp.depleted)
                {
                    continue;
                }

                damage -= targetClient.character.battleParam.plusPhysicalDefence;
                if (damage < 0)
                {
                    damage = 1;             //pity damage
                }
                targetClient.character.hp.Modify(-damage, client.character.instanceId);
                perHp = (float)targetClient.character.hp.current / targetClient.character.hp.max * 100;
                _Logger.Debug(
                    $"CurrentHp [{targetClient.character.hp.current}] MaxHp[{targetClient.character.hp.max}] perHp[{perHp}]");
                RecvCharaUpdateHp cHpUpdate = new RecvCharaUpdateHp(targetClient.character.hp.current);
                _server.router.Send(targetClient, cHpUpdate.ToPacket());

                //logic to turn characters to criminals on criminal actions.  possibly should move to character task.
                client.character.criminalState += 1;
                if ((client.character.criminalState == 1) | (client.character.criminalState == 2) |
                    (client.character.criminalState == 3))
                {
                    IBuffer res40 = BufferProvider.Provide();
                    res40.WriteUInt32(client.character.instanceId);
                    res40.WriteByte(client.character.criminalState);

                    _Logger.Debug($"Setting crime level for Character {client.character.name} to {client.character.criminalState}");
                    router.Send(client.map, (ushort)AreaPacketId.recv_chara_update_notify_crime_lv, res40, ServerType.Area);
                    //Router.Send(client.Map, (ushort) AreaPacketId.recv_charabody_notify_crime_lv, res40, ServerType.Area, client);
                }

                if (client.character.criminalState > 255)
                {
                    client.character.criminalState = 255;
                }

                DamageTheObject(client, targetClient.character.instanceId, damage, perHp);
            }

            //Damage Monsters in range
            foreach (MonsterSpawn monsterSpawn in client.map.monsterSpawns.Values)
            {
                double distanceToObject =
                    Distance(monsterSpawn.x, monsterSpawn.y, client.character.x, client.character.y);
                //_Logger.Debug($"target Monster name [{monsterSpawn.name}] distanceToObject [{distanceToObject}] Radius [{monsterSpawn.radius}] {monsterSpawn.name}");
                if (distanceToObject > monsterSpawn.radius * 5
                    ) //increased hitbox for monsters by a factor of 5.  Beetle radius is 40
                {
                    continue;
                }

                if (monsterSpawn.hp.depleted)
                {
                    continue;
                }

                monsterSpawn.hp.Modify(-damage, client.character.instanceId);
                perHp = (float)monsterSpawn.hp.current / monsterSpawn.hp.max * 100;
                _Logger.Debug($"CurrentHp [{monsterSpawn.hp.current}] MaxHp[{monsterSpawn.hp.max}] perHp[{perHp}]");

                //just for fun. turn on inactive monsters
                if (monsterSpawn.active == false)
                {
                    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();
                    }
                }

                DamageTheObject(client, monsterSpawn.instanceId, damage, perHp);
            }

            //Damage NPCs in range
            foreach (NpcSpawn npcSpawn in client.map.npcSpawns.Values)
            {
                double distanceToObject = Distance(npcSpawn.x, npcSpawn.y, client.character.x, client.character.y);
                // _Logger.Debug($"target NPC name [{npcSpawn.name}] distanceToObject [{distanceToObject}] Radius [{npcSpawn.radius}] {npcSpawn.name}");
                if (distanceToObject > npcSpawn.radius)
                {
                    continue;
                }

                //attacking an NPC is a misdimeanor crime for non-criminals.
                if ((client.character.criminalState == 0))
                {
                    client.character.criminalState += 1;
                    IBuffer res40 = BufferProvider.Provide();
                    res40.WriteUInt32(client.character.instanceId);
                    res40.WriteByte(client.character.criminalState);

                    router.Send(client.map, (ushort)AreaPacketId.recv_chara_update_notify_crime_lv, res40, ServerType.Area);
                }

                DamageTheObject(client, npcSpawn.instanceId, damage, perHp);
            }
        }
Exemplo n.º 3
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");
            }
        }