public void PerformGoal(ref NPCBase.NPCState state) { Pipliz.Vector3Int position = GuardJob.Position; state.SetCooldown(1); state.JobIsDone = true; if (!Job.NPC.Inventory.Contains(GuardSettings.ShootItem)) { Shop(Job, ref Job.NPC.state); return; } if (GuardJob.HasTarget) { UnityEngine.Vector3 npcPos = position.Add(0, 1, 0).Vector; UnityEngine.Vector3 targetPos = GuardJob.Target.PositionToAimFor; if (VoxelPhysics.CanSee(npcPos, targetPos)) { GuardJob.NPC.LookAt(targetPos); ShootAtTarget(GuardJob, ref state); return; } } GuardJob.Target = MonsterTracker.Find(position.Add(0, 1, 0), GuardSettings.Range, GuardSettings.Damage); if (GuardJob.HasTarget) { GuardJob.NPC.LookAt(GuardJob.Target.PositionToAimFor); ShootAtTarget(GuardJob, ref state); return; } state.SetCooldown(GuardSettings.CooldownSearchingTarget * Pipliz.Random.NextFloat(0.9f, 1.1f)); UnityEngine.Vector3 pos = GuardJob.NPC.Position.Vector; if (GuardSettings.BlockTypes.ContainsByReference(GuardJob.BlockType, out int index)) { switch (index) { case 1: pos.x += 1f; break; case 2: pos.x -= 1f; break; case 3: pos.z += 1f; break; case 4: pos.z -= 1f; break; } } GuardJob.NPC.LookAt(pos); }
public void OnNPCAtJob(ref NPCBase.NPCState state) { try { var currentposition = NPC.Position; _hadAmmo.Clear(); if (_inv.Weapon != null && !_inv.Weapon.IsEmpty()) { if (_target == null || !_target.IsValid) { _target = MonsterTracker.Find(currentposition, 100, WeaponFactory.WeaponLookup[_inv.Weapon.Id].Damage.TotalDamage()); } if (_target != null && _target.IsValid) { state.SetIndicator(new IndicatorState(COOLDOWN, _inv.Weapon.Id)); state.SetCooldown(COOLDOWN); NPC.LookAt(_target.Position); AudioManager.SendAudio(_target.PositionToAimFor, "punch"); _target.OnHit(WeaponFactory.WeaponLookup[_inv.Weapon.Id].Damage.TotalDamage()); _waitingFor = 0; } else { state.SetIndicator(new IndicatorState(COOLDOWN, ItemId.GetItemId(GameLoader.NAMESPACE + ".Monster").Id, true)); state.SetCooldown(COOLDOWN); _waitingFor++; _target = null; } } else { if (_target == null || !_target.IsValid || !VoxelPhysics.CanSee(NPC.Position.Vector, _target.Position)) { _target = MonsterTracker.Find(currentposition, _weapon.Range, _weapon.Damage); } if (_target != null && _target.IsValid && VoxelPhysics.CanSee(NPC.Position.Vector, _target.Position)) { foreach (var projectile in _weapon.ShootItem) { _hadAmmo[projectile] = false; if (NPC.Inventory.Contains(projectile)) { _hadAmmo[projectile] = true; continue; } if (_stock.Contains(projectile)) { _hadAmmo[projectile] = true; } } if (!_hadAmmo.Any(a => !a.Value)) { state.SetIndicator(new IndicatorState(_weapon.CooldownShot, _weapon.ShootItem[0].Type)); foreach (var ammo in _hadAmmo) { if (NPC.Inventory.Contains(ammo.Key)) { NPC.Inventory.TryRemove(ammo.Key); continue; } if (_stock.Contains(ammo.Key)) { _stock.TryRemove(ammo.Key); } } NPC.LookAt(_target.Position); if (_weapon.OnShootAudio != null) { AudioManager.SendAudio(Position.Vector, _weapon.OnShootAudio); } if (_weapon.OnHitAudio != null) { AudioManager.SendAudio(_target.PositionToAimFor, _weapon.OnHitAudio); } if (_weapon.ShootItem.Count > 0) { foreach (var proj in _weapon.ShootItem) { var projName = ItemTypes.IndexLookup.GetName(proj.Type); if (AnimationManager.AnimatedObjects.ContainsKey(projName)) { AnimationManager.AnimatedObjects[projName].SendMoveToInterpolated(Position.Vector, _target.PositionToAimFor); break; } } } ServerManager.SendParticleTrail(currentposition.Vector, _target.PositionToAimFor, 2); _target.OnHit(_weapon.Damage); state.SetCooldown(_weapon.CooldownShot); _waitingFor = 0; } else { state.SetIndicator(new IndicatorState(_weapon.CooldownMissingItem, _weapon.ShootItem[0].Type, true)); state.SetCooldown(_weapon.CooldownMissingItem); } } else { state.SetIndicator(new IndicatorState(_weapon.CooldownSearchingTarget, ItemId.GetItemId(GameLoader.NAMESPACE + ".Monster").Id, true)); state.SetCooldown(_weapon.CooldownMissingItem); _target = null; } } } catch (Exception) { state.SetIndicator(new IndicatorState(_weapon.CooldownSearchingTarget, ItemId.GetItemId(GameLoader.NAMESPACE + ".Monster").Id, true)); state.SetCooldown(_weapon.CooldownMissingItem); _target = null; } }
// find non friendly targets within given range public static Players.Player FindTarget(Colony owner, Vector3 position, int range) { Players.Player target = null; float shortestDistance = range + 1.0f; List <Players.Player> friendlies = new List <Players.Player>(); foreach (Players.Player ownerPlayer in owner.Owners) { if (friendlyPlayers.ContainsKey(ownerPlayer)) { friendlies.AddRange(friendlyPlayers[ownerPlayer]); } friendlies.Add(ownerPlayer); } bool atWar = false; if (AngryGuards.ColonyWarMode.Contains(owner)) { atWar = true; } for (int i = 0; i < Players.CountConnected; i++) { Players.Player candidate = Players.GetConnectedByIndex(i); if (friendlies.Contains(candidate)) { continue; } if (PermissionsManager.HasPermission(candidate, AngryGuards.PERMISSION_PREFIX + ".peacekeeper")) { continue; } if (candidate.Health <= 0.0f) { continue; } // colonies at war are always active mode and also shoot mounted players if (!atWar) { if (AngryGuards.ModeSetting == GuardMode.Passive) { if (!colonyEnemies.ContainsKey(owner) || !colonyEnemies[owner].Contains(candidate)) { continue; } } // avoid shooting players on gliders. but still shoot them when they kill NPCs if (!AngryGuards.ShootMountedPlayers && MeshedObjectManager.HasVehicle(candidate)) { if (!colonyEnemies.ContainsKey(owner) || !colonyEnemies[owner].Contains(candidate)) { continue; } } } Vector3 candidateEyePosition = candidate.Position; candidateEyePosition[1] += 1; float distance = Vector3.Distance(position, candidate.Position); if (distance < shortestDistance && (VoxelPhysics.CanSee(position, candidate.Position) || VoxelPhysics.CanSee(position, candidateEyePosition))) { shortestDistance = distance; target = candidate; } } return(target); }