示例#1
0
 public bool TryGetMapping(NpcInst npc, out CharacterMapping mapping)
 {
     lock (_Lock)
     {
         mapping = _ActiveMappings.Values.FirstOrDefault(map => map.CharacterNpc.ID == npc.ID);
         return(mapping != null);
     }
 }
示例#2
0
        public CharacterMapping SpawnAndMapCharacter(Character character)
        {
            if (character == null)
            {
                throw new ArgumentNullException(nameof(character));
            }

            if (character.IsMapped)
            {
                throw new InvalidOperationException($"The character '{character.Name}' ({character.CharacterId}) is already mapped and can not be mapped again!");
            }

            if (!character.IsValid)
            {
                throw new InvalidOperationException($"The given character object is invalid and should not be referenced or used anymore.");
            }

            NpcInst npc;


            if (character is HumanCharacter humanCharacter)
            {
                npc = new NpcInst(character.Template)
                {
                    UseCustoms             = true,
                    CustomBodyTex          = humanCharacter.HumanVisuals.BodyTex,
                    CustomHeadMesh         = humanCharacter.HumanVisuals.HeadMesh,
                    CustomHeadTex          = humanCharacter.HumanVisuals.HeadTex,
                    CustomVoice            = humanCharacter.HumanVisuals.Voice,
                    CustomFatness          = humanCharacter.HumanVisuals.Fatness,
                    CustomScale            = new Vec3f(humanCharacter.HumanVisuals.BodyWidth, 1.0f, humanCharacter.HumanVisuals.BodyWidth),
                    CustomName             = character.Name,
                    DropUnconsciousOnDeath = true,
                    UnconsciousDuration    = 15 * TimeSpan.TicksPerSecond,
                };
            }
            else
            {
                npc = new NpcInst(character.Template)
                {
                    CustomName = character.Name,
                };
            }
            npc.Spawn(character.World, character.LastKnownPosition, character.Rotation);
            character.IsMapped = true;

            var mapping = new CharacterMapping(character, npc);

            lock (_Lock)
            {
                _ActiveMappings.Add(character.CharacterId, mapping);
            }

            return(mapping);
        }
示例#3
0
        public void RemoveMapping(Character character)
        {
            if (character == null)
            {
                throw new ArgumentNullException(nameof(character));
            }
            if (!character.IsValid)
            {
                throw new InvalidOperationException($"The given character object is invalid and should not be referenced or used anymore.");
            }
            if (!character.IsMapped)
            {
                throw new InvalidOperationException($"The character '{character.Name}' ({character.CharacterId}) is not mapped! There is nothing to remove!");
            }


            NpcInst npc = null;

            lock (_Lock)
            {
                if (_ActiveMappings.TryGetValue(character.CharacterId, out CharacterMapping mapping))
                {
                    character.LastKnownPosition = mapping.CharacterNpc.GetPosition();
                    character.Rotation          = mapping.CharacterNpc.GetAngles();
                    character.World             = mapping.CharacterNpc.World;
                    character.Template          = mapping.CharacterNpc.Template;

                    //Despawn the character npc and remove the mapping.
                    npc = mapping.CharacterNpc;
                    _ActiveMappings.Remove(character.CharacterId);
                    character.IsMapped = false;

                    //Check if we can completely unload the character.
                    bool ownerIsActive = _CharactersByOwner.Values.Any(list => list.Contains(character));

                    if (!ownerIsActive)
                    {
                        _LoadedCharacters.Remove(character.CharacterId);
                        _LoadedCharactersByName.Remove(character.Name.ToUpperInvariant());
                        character.IsValid = false;
                    }
                }
            }
            npc?.Despawn();
        }
示例#4
0
 public CharacterMapping(Character character, NpcInst characterNpc)
 {
     Character    = character ?? throw new ArgumentNullException(nameof(character));
     CharacterNpc = characterNpc ?? throw new ArgumentNullException(nameof(characterNpc));
 }
示例#5
0
 /// <summary>
 /// Sets the <see cref="NpcInst"/> that this client is controlling.
 /// </summary>
 /// <param name="npc">The <see cref="NpcInst"/> that should be controlled by the current <see cref="Client"/>.</param>
 public void SetControl(NpcInst npc)
 {
     BaseClient.SetControl(npc?.BaseInst);
 }
示例#6
0
 public bool TryGetControlledNpc(out NpcInst npc)
 {
     npc = ControlledNpc;
     return(npc != null);
 }
示例#7
0
        public void ReadRequest(RequestMessageIDs id, PacketReader stream, NpcInst npc)
        {
            switch (id)
            {
            case RequestMessageIDs.JumpFwd:
                OnJump?.Invoke(npc, JumpMoves.Fwd);
                break;

            case RequestMessageIDs.JumpRun:
                OnJump?.Invoke(npc, JumpMoves.Run);
                break;

            case RequestMessageIDs.JumpUp:
                OnJump?.Invoke(npc, JumpMoves.Up);
                break;

            case RequestMessageIDs.ClimbHigh:
                OnClimb?.Invoke(npc, ClimbMoves.High, new NPC.ClimbingLedge(stream));
                break;

            case RequestMessageIDs.ClimbMid:
                OnClimb?.Invoke(npc, ClimbMoves.Mid, new NPC.ClimbingLedge(stream));
                break;

            case RequestMessageIDs.ClimbLow:
                OnClimb?.Invoke(npc, ClimbMoves.Low, new NPC.ClimbingLedge(stream));
                break;

            case RequestMessageIDs.DrawFists:
                OnDrawFists?.Invoke(npc);
                break;

            case RequestMessageIDs.DrawWeapon:
                OnDrawWeapon?.Invoke(npc, npc.Inventory.GetItem(stream.ReadByte()));
                break;

            case RequestMessageIDs.AttackForward:
                OnFightMove?.Invoke(npc, FightMoves.Fwd);
                break;

            case RequestMessageIDs.AttackLeft:
                OnFightMove?.Invoke(npc, FightMoves.Left);
                break;

            case RequestMessageIDs.AttackRight:
                OnFightMove?.Invoke(npc, FightMoves.Right);
                break;

            case RequestMessageIDs.AttackRun:
                OnFightMove?.Invoke(npc, FightMoves.Run);
                break;

            case RequestMessageIDs.Parry:
                OnFightMove?.Invoke(npc, FightMoves.Parry);
                break;

            case RequestMessageIDs.Dodge:
                OnFightMove?.Invoke(npc, FightMoves.Dodge);
                break;

            case RequestMessageIDs.DropItem:
                OnDropItem?.Invoke(npc, npc.Inventory.GetItem(stream.ReadByte()), stream.ReadUShort());
                break;

            case RequestMessageIDs.TakeItem:
                if (npc.World.TryGetVob(stream.ReadUShort(), out ItemInst item))
                {
                    OnTakeItem?.Invoke(npc, item);
                }
                break;

            case RequestMessageIDs.EquipItem:
                OnEquipItem?.Invoke(npc, npc.Inventory.GetItem(stream.ReadByte()));
                break;

            case RequestMessageIDs.UnequipItem:
                OnUnequipItem?.Invoke(npc, npc.Inventory.GetItem(stream.ReadByte()));
                break;

            case RequestMessageIDs.UseItem:
                OnUseItem?.Invoke(npc, npc.Inventory.GetItem(stream.ReadByte()));
                break;

            case RequestMessageIDs.Aim:
                OnAim?.Invoke(npc);
                break;

            case RequestMessageIDs.Unaim:
                OnUnaim?.Invoke(npc);
                break;

            case RequestMessageIDs.Shoot:
                OnShoot?.Invoke(npc, stream.ReadVec3f(), stream.ReadVec3f());
                break;

            case RequestMessageIDs.Voice:
                OnVoice?.Invoke(npc, (VoiceCmd)stream.ReadByte());
                break;

            case RequestMessageIDs.HelpUp:
                if (npc.World.TryGetVob(stream.ReadUShort(), out NpcInst target))
                {
                    OnHelpUp?.Invoke(npc, target);
                }
                break;

            default:
                GUC.Log.Logger.Log("Received Script RequestMessage with invalid ID: " + id.ToString());
                break;
            }
        }