private static INPC EnsureCorrectXAndY(INPC npc, byte destinationX, byte destinationY) { var opposite = npc.Direction.Opposite(); var tempNPC = npc .WithDirection(opposite) .WithX(destinationX) .WithY(destinationY); return(npc .WithX((byte)tempNPC.GetDestinationX()) .WithY((byte)tempNPC.GetDestinationY())); }
private void HandleNPCWalk(IPacket packet, INPC npc) { //npc remove from view sets x/y to either 0,0 or 252,252 based on target coords var x = packet.ReadChar(); var y = packet.ReadChar(); var npcDirection = (EODirection)packet.ReadChar(); if (packet.ReadBytes(3).Any(b => b != 255)) { throw new MalformedPacketException("Expected 3 bytes of value 0xFF in NPC_PLAYER packet for Walk action", packet); } var updatedNPC = npc.WithDirection(npcDirection); updatedNPC = EnsureCorrectXAndY(updatedNPC, x, y); _currentMapStateRepository.NPCs.Remove(npc); _currentMapStateRepository.NPCs.Add(updatedNPC); foreach (var notifier in _npcAnimationNotifiers) { notifier.StartNPCWalkAnimation(npc.Index); } }
private Optional <INPC> HandleNPCAttack(IPacket packet, INPC npc) { var isDead = packet.ReadChar() == 2; //2 if target player is dead, 1 if alive var npcDirection = (EODirection)packet.ReadChar(); var characterID = packet.ReadShort(); var damageTaken = packet.ReadThree(); var playerPercentHealth = packet.ReadThree(); if (packet.ReadBytes(2).Any(b => b != 255)) { throw new MalformedPacketException("Expected 2 bytes of value 0xFF in NPC_PLAYER packet for Attack action", packet); } if (characterID == _characterRepository.MainCharacter.ID) { var characterToUpdate = _characterRepository.MainCharacter; var stats = characterToUpdate.Stats; stats = stats.WithNewStat(CharacterStat.HP, (short)Math.Max(stats[CharacterStat.HP] - damageTaken, 0)); var props = characterToUpdate.RenderProperties; if (isDead) { props = props.WithDead(); } _characterRepository.MainCharacter = characterToUpdate.WithStats(stats).WithRenderProperties(props); foreach (var notifier in _mainCharacterNotifiers) { notifier.NotifyTakeDamage(damageTaken, playerPercentHealth); } } else { var characterToUpdate = _currentMapStateRepository.Characters.Single(x => x.ID == characterID); var stats = characterToUpdate.Stats; stats = stats.WithNewStat(CharacterStat.HP, (short)Math.Max(stats[CharacterStat.HP] - damageTaken, 0)); var props = characterToUpdate.RenderProperties; if (isDead) { props = props.WithDead(); } var updatedCharacter = characterToUpdate.WithStats(stats).WithRenderProperties(props); _currentMapStateRepository.Characters.Remove(characterToUpdate); _currentMapStateRepository.Characters.Add(updatedCharacter); foreach (var notifier in _otherCharacterNotifiers) { notifier.OtherCharacterTakeDamage(characterID, playerPercentHealth, damageTaken); } } foreach (var notifier in _npcAnimationNotifiers) { notifier.StartNPCAttackAnimation(npc.Index); } return(new Optional <INPC>(npc.WithDirection(npcDirection))); }