Implemented NPC aggression tolerance

This commit is contained in:
ceikry 2021-07-16 21:04:40 -05:00
parent d334a12b33
commit fb2256d6e6
4 changed files with 32 additions and 3 deletions

View file

@ -62,6 +62,12 @@ public class AggressiveBehavior {
* @return {@code True} if the NPC can select the entity as a target. * @return {@code True} if the NPC can select the entity as a target.
*/ */
public boolean canSelectTarget(Entity entity, Entity target) { public boolean canSelectTarget(Entity entity, Entity target) {
int regionId = target.getLocation().getRegionId();
if(target instanceof Player) {
if (RegionManager.forId(regionId).isTolerated(target.asPlayer())) {
return false;
}
}
if (!target.isActive() || DeathTask.isDead(target)) { if (!target.isActive() || DeathTask.isDead(target)) {
return false; return false;
} }

View file

@ -81,9 +81,10 @@ public final class AggressiveHandler {
Entity target = behavior.getLogicalTarget(entity, behavior.getPossibleTargets(entity, radius)); Entity target = behavior.getLogicalTarget(entity, behavior.getPossibleTargets(entity, radius));
if (target instanceof Player) { if (target instanceof Player) {
if (target.getAttribute("ignore_aggression", false)) { if (target.getAttribute("ignore_aggression", false)) {
if (((Player) target).getRights().equals(Rights.ADMINISTRATOR)) { return false;
return false; }
} if (((Player) target).getRights().equals(Rights.ADMINISTRATOR)) {
return false;
} }
} }
if (target != null) { if (target != null) {

View file

@ -5,7 +5,9 @@ import core.game.node.entity.combat.BattleState;
import core.game.node.entity.npc.AbstractNPC; import core.game.node.entity.npc.AbstractNPC;
import core.game.node.entity.npc.agg.AggressiveBehavior; import core.game.node.entity.npc.agg.AggressiveBehavior;
import core.game.node.entity.npc.agg.AggressiveHandler; import core.game.node.entity.npc.agg.AggressiveHandler;
import core.game.node.entity.player.Player;
import core.game.world.map.Location; import core.game.world.map.Location;
import core.game.world.map.RegionManager;
import core.plugin.Initializable; import core.plugin.Initializable;
import core.tools.RandomFunction; import core.tools.RandomFunction;
@ -22,6 +24,10 @@ public final class RockCrabNPC extends AbstractNPC {
private static final AggressiveBehavior AGGRO_BEHAVIOR = new AggressiveBehavior() { private static final AggressiveBehavior AGGRO_BEHAVIOR = new AggressiveBehavior() {
@Override @Override
public boolean canSelectTarget(Entity entity, Entity target) { public boolean canSelectTarget(Entity entity, Entity target) {
int regionId = target.getLocation().getRegionId();
if(target instanceof Player){
if(RegionManager.forId(regionId).isTolerated(target.asPlayer())) return false;
}
RockCrabNPC npc = (RockCrabNPC) entity; RockCrabNPC npc = (RockCrabNPC) entity;
if (entity.getLocation().withinDistance(target.getLocation(), 3)) { if (entity.getLocation().withinDistance(target.getLocation(), 3)) {
npc.aggresor = true; npc.aggresor = true;

View file

@ -16,7 +16,9 @@ import rs09.game.world.repository.Repository;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit;
/** /**
* Represents a region. * Represents a region.
@ -60,6 +62,11 @@ public class Region {
*/ */
private final List<MusicZone> musicZones = new ArrayList<>(20); private final List<MusicZone> musicZones = new ArrayList<>(20);
/**
* Keeps track of players and time in region for tolerance purposes
*/
private final HashMap<String,Long> tolerances = new HashMap<>();
/** /**
* If the region is active. * If the region is active.
*/ */
@ -146,6 +153,7 @@ public class Region {
*/ */
public void add(Player player) { public void add(Player player) {
planes[player.getLocation().getZ()].add(player); planes[player.getLocation().getZ()].add(player);
tolerances.put(player.getUsername(), System.currentTimeMillis());
flagActive(); flagActive();
} }
@ -175,9 +183,17 @@ public class Region {
*/ */
public void remove(Player player) { public void remove(Player player) {
player.getViewport().getCurrentPlane().remove(player); player.getViewport().getCurrentPlane().remove(player);
tolerances.remove(player.getUsername());
checkInactive(); checkInactive();
} }
/**
* Checks if player is tolerated by enemies in this region
*/
public boolean isTolerated(Player player){
return System.currentTimeMillis() - tolerances.getOrDefault(player.getUsername(), System.currentTimeMillis()) > TimeUnit.MINUTES.toMillis(1);
}
/** /**
* Checks if the region is inactive, if so it will start the inactivity flagging. * Checks if the region is inactive, if so it will start the inactivity flagging.
* @return {@code True} if the region is inactive. * @return {@code True} if the region is inactive.