mirror of
https://gitlab.com/2009scape/2009scape.git
synced 2025-12-21 09:02:07 -07:00
Revenants have been reworked to feel much more present, more alive and more dangerous - Beware!
Revenant spawns, patrols and areas of exploration are now based on era-authentic maps New revenant command for admins ::setrevcap to set max number of revenants New server config world option revenant_population
This commit is contained in:
parent
053edc3f34
commit
0e74cf0495
7 changed files with 264 additions and 107 deletions
|
|
@ -15,15 +15,18 @@ import core.game.world.map.path.Pathfinder;
|
|||
import core.game.world.map.zone.ZoneBorders;
|
||||
import core.game.world.map.zone.impl.WildernessZone;
|
||||
import core.game.world.update.flag.context.Animation;
|
||||
import core.plugin.Initializable;
|
||||
import core.tools.RandomFunction;
|
||||
import rs09.game.content.zone.wilderness.RevenantController;
|
||||
import rs09.game.node.entity.combat.CombatSwingHandler;
|
||||
import rs09.game.system.config.NPCConfigParser;
|
||||
import rs09.game.world.GameWorld;
|
||||
|
||||
/**
|
||||
* Handles a revenant NPC.
|
||||
* @author Vexia
|
||||
* @author Ceikry-ish (mostly Vexia code still)
|
||||
*/
|
||||
@Initializable
|
||||
public class RevenantNPC extends AbstractNPC {
|
||||
|
||||
/**
|
||||
|
|
@ -74,21 +77,21 @@ public class RevenantNPC extends AbstractNPC {
|
|||
setWalks(true);
|
||||
setRespawn(false);
|
||||
setAggressive(true);
|
||||
setRenderable(true);
|
||||
setDefaultBehavior();
|
||||
getAggressiveHandler().setRadius(64 * 2);
|
||||
getAggressiveHandler().setChanceRatio(9);
|
||||
getAggressiveHandler().setAllowTolerance(false);
|
||||
getProperties().setCombatTimeOut(120);
|
||||
configureRoute();
|
||||
super.configure();
|
||||
configureBonuses();
|
||||
super.configure();
|
||||
this.swingHandler = new RevenantCombatHandler(getProperties().getAttackAnimation(), getProperties().getMagicAnimation(), getProperties().getRangeAnimation());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
super.init();
|
||||
RevenantPlugin.getRevenants().add(this);
|
||||
RevenantController.registerRevenant(this);
|
||||
int spawnAnim = getDefinition().getConfiguration(NPCConfigParser.SPAWN_ANIMATION, -1);
|
||||
if (spawnAnim != -1) {
|
||||
animate(new Animation(spawnAnim));
|
||||
|
|
@ -98,8 +101,7 @@ public class RevenantNPC extends AbstractNPC {
|
|||
@Override
|
||||
public void clear() {
|
||||
super.clear();
|
||||
RevenantPlugin.getRevenants().remove(this);
|
||||
RevenantPlugin.spawn();
|
||||
RevenantController.unregisterRevenant(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -111,7 +113,11 @@ public class RevenantNPC extends AbstractNPC {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void handleTickActions() {
|
||||
public void tick() {
|
||||
skills.pulse();
|
||||
getWalkingQueue().update();
|
||||
if (this.getViewport().getRegion().isActive())
|
||||
getUpdateMasks().prepare(this);
|
||||
if (!DeathTask.isDead(this) && getSkills().getLifepoints() <= (getSkills().getStaticLevel(Skills.HITPOINTS) / 2) && getAttribute("eat-delay", 0) < GameWorld.getTicks()) {
|
||||
lock(3);
|
||||
getProperties().getCombatPulse().delayNextAttack(3);
|
||||
|
|
@ -121,15 +127,6 @@ public class RevenantNPC extends AbstractNPC {
|
|||
}
|
||||
setAttribute("eat-delay", GameWorld.getTicks() + 6);
|
||||
}
|
||||
if (!getLocks().isMovementLocked()) {
|
||||
if (!getPulseManager().hasPulseRunning() && !getProperties().getCombatPulse().isAttacking() && !getProperties().getCombatPulse().isInCombat() && nextWalk < GameWorld.getTicks()) {
|
||||
setNextWalk();
|
||||
Location l = getMovementDestination();
|
||||
if (canMove(l)) {
|
||||
Pathfinder.find(this, l, true, Pathfinder.SMART).walk(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (aggressiveHandler != null && aggressiveHandler.selectTarget()) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,90 +0,0 @@
|
|||
package core.game.node.entity.npc.revenant;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import core.game.node.entity.npc.NPC;
|
||||
import core.game.world.map.Location;
|
||||
import core.plugin.Initializable;
|
||||
import core.plugin.Plugin;
|
||||
import rs09.plugin.ClassScanner;
|
||||
import core.tools.RandomFunction;
|
||||
|
||||
/**
|
||||
* Handles the revenants.
|
||||
* @author Vexia
|
||||
*/
|
||||
@Initializable
|
||||
public class RevenantPlugin implements Plugin<Object> {
|
||||
|
||||
/**
|
||||
* The revenants npc.
|
||||
*/
|
||||
private static final List<NPC> REVENANTS = new ArrayList<>(20);
|
||||
|
||||
/**
|
||||
* The spawning locations.
|
||||
*/
|
||||
private static final Location[] SPAWN_LOCATIONS = new Location[] { new Location(2968, 3695), new Location(2956, 3716), new Location(2969, 3753), new Location(2967, 3817), new Location(2976, 3849), new Location(2976, 3725), new Location(2973, 3576), new Location(2982, 3850), new Location(3348, 3822), new Location(3362, 3808), new Location(3026, 3734), new Location(2961, 3792), new Location(2984, 3801), new Location(2974, 3744), new Location(2984, 3718), new Location(2990, 3695), new Location(2960, 3590), new Location(3020, 3674), new Location(3019, 3723), new Location(3019, 3822), Location.create(3123, 3567, 0), Location.create(3123, 3567, 0), Location.create(3201, 3678, 0), Location.create(3220, 3755, 0), Location.create(3249, 3882, 0), Location.create(3283, 3893, 0), Location.create(3034, 3938, 0), Location.create(2964, 3617, 0), Location.create(3253, 3922, 0), Location.create(3205, 3907, 0), Location.create(3194, 3895, 0), Location.create(3168, 3788, 0), Location.create(3287, 3557, 0), Location.create(3327, 3558, 0), Location.create(3364, 3536, 0), Location.create(3262, 3595, 0), Location.create(3099, 3957, 0), Location.create(3028, 3915, 0), Location.create(3285, 3922, 0), Location.create(2980, 3855, 0), Location.create(3243, 3917, 0), Location.create(3190, 3630, 0), Location.create(3188, 3585, 0), Location.create(3117, 3590, 0), Location.create(3136, 3624, 0), Location.create(3356, 3701, 0) };
|
||||
|
||||
/**
|
||||
* The maximum amount of revenants spawned.
|
||||
*/
|
||||
private static final int MAX = 20;
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
ClassScanner.definePlugin(new RevenantNPC());
|
||||
//CorruptEquipment.init();
|
||||
//PVPEquipment.init();
|
||||
spawn();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Spawns the revenants.
|
||||
*/
|
||||
public static void spawn() {
|
||||
int size = REVENANTS.size();
|
||||
int left = MAX - size;
|
||||
List<Location> taken = new ArrayList<>(20);
|
||||
for (NPC n : REVENANTS) {
|
||||
taken.add(n.getProperties().getSpawnLocation());
|
||||
}
|
||||
if (left > 0) {
|
||||
int spawnAmount = RandomFunction.random(1, left);
|
||||
if (size == 0) {
|
||||
spawnAmount = MAX;
|
||||
}
|
||||
for (int i = 0; i < spawnAmount; i++) {
|
||||
Location loc = null;
|
||||
while (loc == null) {
|
||||
Location l = RandomFunction.getRandomElement(SPAWN_LOCATIONS);
|
||||
if (taken.contains(l)) {
|
||||
continue;
|
||||
}
|
||||
loc = l;
|
||||
}
|
||||
taken.add(loc);
|
||||
RevenantType type = RandomFunction.getRandomElement(RevenantType.values());
|
||||
int id = type.getIds()[0];
|
||||
NPC revenant = NPC.create(id, loc);
|
||||
revenant.init();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object fireEvent(String identifier, Object... args) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the revenants.
|
||||
* @return the revenants
|
||||
*/
|
||||
public static List<NPC> getRevenants() {
|
||||
return REVENANTS;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -293,4 +293,8 @@ public class RandomFunction {
|
|||
}
|
||||
return RANDOM.nextInt(value);
|
||||
}
|
||||
|
||||
public static boolean nextBool() {
|
||||
return RANDOM.nextBoolean();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,9 @@ import java.math.BigInteger
|
|||
class ServerConstants {
|
||||
companion object {
|
||||
@JvmField
|
||||
var REVENANT_POPULATION: Int = 30
|
||||
|
||||
@JvmField
|
||||
var BOTS_INFLUENCE_PRICE_INDEX = true
|
||||
|
||||
@JvmField
|
||||
|
|
|
|||
|
|
@ -0,0 +1,239 @@
|
|||
package rs09.game.content.zone.wilderness
|
||||
|
||||
import api.Commands
|
||||
import api.TickListener
|
||||
import api.poofClear
|
||||
import api.teleport
|
||||
import core.game.interaction.MovementPulse
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.npc.revenant.RevenantNPC
|
||||
import core.game.node.entity.npc.revenant.RevenantType
|
||||
import core.game.node.entity.player.link.TeleportManager
|
||||
import core.game.system.task.Pulse
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.map.zone.ZoneBorders
|
||||
import core.game.world.update.flag.context.Graphics
|
||||
import core.tools.RandomFunction
|
||||
import rs09.ServerConstants
|
||||
import rs09.game.system.SystemLogger
|
||||
import rs09.game.system.command.Privilege
|
||||
import rs09.game.world.GameWorld
|
||||
import rs09.game.world.repository.Repository
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.collections.HashMap
|
||||
|
||||
class RevenantController : TickListener, Commands {
|
||||
|
||||
companion object {
|
||||
private val trackedRevenants = ArrayList<RevenantNPC>()
|
||||
private val taskTimeRemaining = HashMap<RevenantNPC, Int>()
|
||||
private val currentTask = HashMap<RevenantNPC, RevenantTask>()
|
||||
private var expectedRevAmount: Int = ServerConstants.REVENANT_POPULATION
|
||||
private var groupPatrolQueue = ArrayList<RevenantNPC>()
|
||||
|
||||
@JvmStatic fun registerRevenant(revenantNPC: RevenantNPC) {
|
||||
trackedRevenants.add(revenantNPC)
|
||||
taskTimeRemaining[revenantNPC] = 0
|
||||
currentTask[revenantNPC] = RevenantTask.NONE
|
||||
Repository.RENDERABLE_NPCS.add(revenantNPC)
|
||||
}
|
||||
|
||||
@JvmStatic fun unregisterRevenant(revenantNPC: RevenantNPC) {
|
||||
trackedRevenants.remove(revenantNPC)
|
||||
taskTimeRemaining.remove(revenantNPC)
|
||||
currentTask.remove(revenantNPC)
|
||||
Repository.RENDERABLE_NPCS.remove(revenantNPC)
|
||||
}
|
||||
|
||||
val routes = listOf(
|
||||
arrayOf(Location.create(3070, 3651), Location.create(3083, 3640), Location.create(3106, 3645), Location.create(3133, 3647), Location.create(3149, 3642), Location.create(3160, 3654), Location.create(3171, 3665, 0), Location.create(3189, 3663, 0), Location.create(3202, 3675, 0), Location.create(3217, 3660, 0), Location.create(3235, 3661, 0), Location.create(3235, 3661, 0), Location.create(3279, 3650, 0), Location.create(3269, 3636, 0), Location.create(3253, 3632, 0), Location.create(3236, 3638, 0), Location.create(3220, 3637, 0), Location.create(3203, 3634, 0), Location.create(3187, 3631, 0), Location.create(3166, 3633, 0), Location.create(3160, 3616, 0), Location.create(3148, 3604, 0), Location.create(3134, 3596, 0), Location.create(3118, 3590, 0), Location.create(3104, 3597, 0)),
|
||||
arrayOf(Location.create(3077, 3565, 0), Location.create(3093, 3559, 0), Location.create(3110, 3566, 0), Location.create(3127, 3574, 0), Location.create(3146, 3571, 0), Location.create(3164, 3575, 0), Location.create(3183, 3573, 0), Location.create(3197, 3587, 0), Location.create(3215, 3584, 0), Location.create(3233, 3576, 0), Location.create(3251, 3573, 0), Location.create(3269, 3577, 0), Location.create(3287, 3569, 0), Location.create(3305, 3568, 0), Location.create(3321, 3576, 0), Location.create(3338, 3584, 0), Location.create(3352, 3573, 0), Location.create(3354, 3554, 0), Location.create(3342, 3541, 0), Location.create(3324, 3536, 0), Location.create(3306, 3543, 0), Location.create(3290, 3544, 0), Location.create(3272, 3545, 0), Location.create(3255, 3546, 0), Location.create(3239, 3539, 0), Location.create(3222, 3543, 0), Location.create(3206, 3548, 0), Location.create(3189, 3549, 0), Location.create(3173, 3552, 0), Location.create(3157, 3549, 0), Location.create(3140, 3548, 0), Location.create(3122, 3548, 0), Location.create(3110, 3555, 0)),
|
||||
arrayOf(Location.create(3318, 3691, 0), Location.create(3307, 3700, 0), Location.create(3290, 3696, 0), Location.create(3277, 3706, 0), Location.create(3260, 3706, 0), Location.create(3250, 3707, 0), Location.create(3245, 3723, 0), Location.create(3254, 3735, 0), Location.create(3251, 3754, 0), Location.create(3243, 3768, 0), Location.create(3253, 3780, 0), Location.create(3238, 3783, 0), Location.create(3224, 3793, 0), Location.create(3206, 3786, 0), Location.create(3192, 3780, 0), Location.create(3170, 3787, 0), Location.create(3156, 3800, 0), Location.create(3148, 3814, 0), Location.create(3148, 3814, 0), Location.create(3127, 3840, 0), Location.create(3124, 3856, 0), Location.create(3124, 3872, 0), Location.create(3116, 3892, 0)),
|
||||
arrayOf(Location.create(2949, 3890, 0), Location.create(2965, 3899, 0), Location.create(2984, 3900, 0), Location.create(2998, 3895, 0), Location.create(3016, 3898, 0), Location.create(3032, 3893, 0), Location.create(3048, 3897, 0), Location.create(3068, 3894, 0), Location.create(3084, 3898, 0), Location.create(3101, 3895, 0), Location.create(3118, 3897, 0), Location.create(3136, 3893, 0), Location.create(3154, 3900, 0), Location.create(3172, 3895, 0), Location.create(3189, 3892, 0), Location.create(3206, 3897, 0), Location.create(3222, 3890, 0), Location.create(3240, 3897, 0), Location.create(3259, 3892, 0), Location.create(3278, 3895, 0), Location.create(3296, 3892, 0), Location.create(3313, 3899, 0), Location.create(3331, 3888, 0), Location.create(3345, 3880, 0)),
|
||||
arrayOf(Location.create(3308, 3941, 0), Location.create(3301, 3925, 0), Location.create(3287, 3915, 0), Location.create(3276, 3922, 0), Location.create(3266, 3938, 0), Location.create(3267, 3952, 0), Location.create(3250, 3949, 0), Location.create(3235, 3944, 0), Location.create(3219, 3944, 0), Location.create(3206, 3938, 0), Location.create(3194, 3929, 0), Location.create(3182, 3921, 0), Location.create(3174, 3936, 0), Location.create(3180, 3952, 0), Location.create(3167, 3960, 0), Location.create(3155, 3959, 0), Location.create(3141, 3953, 0), Location.create(3126, 3954, 0), Location.create(3110, 3961, 0), Location.create(3093, 3962, 0), Location.create(3078, 3953, 0), Location.create(3066, 3942, 0), Location.create(3059, 3929, 0), Location.create(3049, 3916, 0), Location.create(3033, 3924, 0), Location.create(3020, 3921, 0), Location.create(3010, 3913, 0), Location.create(2993, 3906, 0), Location.create(2977, 3911, 0), Location.create(2970, 3928, 0))
|
||||
)
|
||||
|
||||
val spawnLocations = listOf(Location.create(3075, 3553, 0), Location.create(3077, 3563, 0), Location.create(3077, 3578, 0), Location.create(3093, 3581, 0), Location.create(3103, 3570, 0), Location.create(3101, 3564, 0), Location.create(3030, 3596, 0), Location.create(3015, 3598, 0), Location.create(3000, 3593, 0), Location.create(2986, 3588, 0), Location.create(2969, 3701, 0), Location.create(2982, 3689, 0), Location.create(2967, 3689, 0), Location.create(2953, 3711, 0), Location.create(2966, 3759, 0), Location.create(2989, 3759, 0), Location.create(2986, 3741, 0), Location.create(2961, 3763, 0), Location.create(2969, 3808, 0), Location.create(3004, 3816, 0))
|
||||
}
|
||||
|
||||
override fun tick() {
|
||||
taskTimeRemaining.replaceAll { _, t -> t - 1 }
|
||||
currentTask.entries.forEach { entry ->
|
||||
if (entry.value == RevenantTask.NONE) {
|
||||
entry.setValue(assignRandomTask(entry.key))
|
||||
} else {
|
||||
entry.value.execute(entry.key)
|
||||
}
|
||||
}
|
||||
spawnMissingRevenants()
|
||||
}
|
||||
|
||||
private fun spawnMissingRevenants() {
|
||||
val amountToSpawn = expectedRevAmount - trackedRevenants.size
|
||||
|
||||
if (amountToSpawn <= 0) return
|
||||
|
||||
for (i in 0 until amountToSpawn) {
|
||||
val type = RevenantType.values().random()
|
||||
val npc = NPC.create(type.ids[0], getRandomSpawnLocation())
|
||||
npc.init()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getRandomSpawnLocation(): Location {
|
||||
return spawnLocations.random()
|
||||
}
|
||||
|
||||
private fun assignRandomTask(npc: RevenantNPC): RevenantTask {
|
||||
return RevenantTask.values().random().also { it.assign(npc) }
|
||||
}
|
||||
|
||||
override fun defineCommands() {
|
||||
define("setrevcap", Privilege.ADMIN) {player, strings ->
|
||||
val amt = strings[1].toInt()
|
||||
expectedRevAmount = amt
|
||||
}
|
||||
|
||||
define("listrevs", Privilege.ADMIN) {player, strings ->
|
||||
for (rev in trackedRevenants) {
|
||||
SystemLogger.logInfo("REV ${rev.id}-${rev.name} @ ${rev.location.toString()}")
|
||||
}
|
||||
|
||||
SystemLogger.logInfo("Total of ${trackedRevenants.size} revenants spawned.")
|
||||
}
|
||||
}
|
||||
|
||||
//The current task for any given revenant - execute is called every tick.
|
||||
enum class RevenantTask {
|
||||
NONE {
|
||||
override fun execute(revenantNPC: RevenantNPC) {}
|
||||
},
|
||||
INTENTIONAL_IDLE {
|
||||
private val MAX_IDLE_TIME: Int = 50
|
||||
|
||||
override fun execute(revenantNPC: RevenantNPC) {
|
||||
if (taskTimeRemaining[revenantNPC] == 0) currentTask[revenantNPC] = NONE
|
||||
}
|
||||
|
||||
override fun assign(revenantNPC: RevenantNPC) {
|
||||
taskTimeRemaining[revenantNPC] = RandomFunction.random(MAX_IDLE_TIME)
|
||||
}
|
||||
},
|
||||
RANDOM_ROAM {
|
||||
private val MAX_ROAM_TICKS: Int = 250
|
||||
|
||||
override fun execute(revenantNPC: RevenantNPC) {
|
||||
if (!canMove(revenantNPC)) return
|
||||
|
||||
revenantNPC.pulseManager.run(object : MovementPulse(revenantNPC, getNextLocation(revenantNPC)) {
|
||||
override fun pulse(): Boolean {
|
||||
if (taskTimeRemaining[revenantNPC]!! <= 0) currentTask[revenantNPC] = NONE
|
||||
return true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun assign(revenantNPC: RevenantNPC) {
|
||||
taskTimeRemaining[revenantNPC] = RandomFunction.random(MAX_ROAM_TICKS)
|
||||
}
|
||||
|
||||
fun canMove(revenantNPC: RevenantNPC) : Boolean {
|
||||
return !revenantNPC.walkingQueue.isMoving
|
||||
&& !revenantNPC.properties.combatPulse.isAttacking
|
||||
&& !revenantNPC.properties.combatPulse.isInCombat
|
||||
}
|
||||
|
||||
fun getNextLocation(revenantNPC: RevenantNPC) : Location {
|
||||
val nextX = RandomFunction.random(-revenantNPC.walkRadius, revenantNPC.walkRadius)
|
||||
val nextY = RandomFunction.random(-revenantNPC.walkRadius, revenantNPC.walkRadius)
|
||||
return revenantNPC.location.transform(nextX, nextY, 0)
|
||||
}
|
||||
},
|
||||
PATROLLING_ROUTE {
|
||||
private val MAXIMUM_GROUP_PATROL_LEVEL = 105
|
||||
|
||||
override fun assign(revenantNPC: RevenantNPC) {
|
||||
if (canGroup(revenantNPC)) {
|
||||
addToPatrolGroup(revenantNPC)
|
||||
} else {
|
||||
revenantNPC.setAttribute("route", routes.random())
|
||||
revenantNPC.setAttribute("routeidx", -1)
|
||||
}
|
||||
}
|
||||
|
||||
private fun addToPatrolGroup(revenantNPC: RevenantNPC) {
|
||||
revenantNPC.setAttribute("group", true)
|
||||
groupPatrolQueue.add(revenantNPC)
|
||||
|
||||
if (groupPatrolQueue.size == 3) {
|
||||
val groupRoute = routes.random()
|
||||
for (rev in groupPatrolQueue) {
|
||||
rev.setAttribute("route", groupRoute)
|
||||
rev.setAttribute("routeidx", -1)
|
||||
}
|
||||
groupPatrolQueue.clear()
|
||||
}
|
||||
}
|
||||
|
||||
private fun canGroup(revenantNPC: RevenantNPC) =
|
||||
revenantNPC.properties.currentCombatLevel <= MAXIMUM_GROUP_PATROL_LEVEL && RandomFunction.nextBool()
|
||||
|
||||
override fun execute(revenantNPC: RevenantNPC) {
|
||||
val isGroup = revenantNPC.getAttribute("group", false)
|
||||
val route = revenantNPC.getAttribute<Array<Location>>("route", null)
|
||||
val routeIdx = revenantNPC.getAttribute("routeidx", -1)
|
||||
|
||||
if (!canMove(revenantNPC)) return
|
||||
|
||||
if (isGroup && route == null) { //if this is a grouped rev and we are waiting on more revs still
|
||||
taskTimeRemaining[revenantNPC] = 50 //just to make sure it doesn't time out roaming...
|
||||
RANDOM_ROAM.execute(revenantNPC)
|
||||
return
|
||||
}
|
||||
|
||||
if (routeIdx == -1) {
|
||||
GameWorld.Pulser.submit(object : Pulse() {
|
||||
override fun pulse(): Boolean {
|
||||
Graphics.send(Graphics(86), revenantNPC.location)
|
||||
return true
|
||||
}
|
||||
})
|
||||
teleport(revenantNPC, route[0], TeleportManager.TeleportType.INSTANT)
|
||||
revenantNPC.setAttribute("routeidx", 1)
|
||||
} else {
|
||||
if (routeIdx == route.size) {
|
||||
poofClear(revenantNPC)
|
||||
revenantNPC.setAttribute("done", true)
|
||||
return
|
||||
}
|
||||
val pathVariance = if (isGroup) 4 else 10
|
||||
val nextLoc = route[routeIdx].transform(
|
||||
RandomFunction.random(-pathVariance, pathVariance),
|
||||
RandomFunction.random(-pathVariance, pathVariance),
|
||||
0
|
||||
)
|
||||
revenantNPC.pulseManager.run(object : MovementPulse(revenantNPC, nextLoc) {
|
||||
override fun pulse(): Boolean {
|
||||
return true
|
||||
}
|
||||
})
|
||||
revenantNPC.setAttribute("routeidx", routeIdx + 1)
|
||||
}
|
||||
}
|
||||
|
||||
fun canMove(revenantNPC: RevenantNPC) : Boolean {
|
||||
return !revenantNPC.walkingQueue.isMoving
|
||||
&& !revenantNPC.pulseManager.hasPulseRunning()
|
||||
&& !revenantNPC.properties.combatPulse.isAttacking
|
||||
&& !revenantNPC.properties.combatPulse.isInCombat
|
||||
&& revenantNPC.properties.teleportLocation == null
|
||||
&& !revenantNPC.getAttribute("done", false)
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
abstract fun execute(revenantNPC: RevenantNPC)
|
||||
open fun assign(revenantNPC: RevenantNPC) {}
|
||||
}
|
||||
}
|
||||
|
|
@ -115,6 +115,7 @@ object ServerConfigParser {
|
|||
ServerConstants.SERVER_GE_NAME = data.getString("world.name_ge") ?: ServerConstants.SERVER_NAME
|
||||
ServerConstants.RULES_AND_INFO_ENABLED = data.getBoolean("world.show_rules", true)
|
||||
ServerConstants.BOTS_INFLUENCE_PRICE_INDEX = data.getBoolean("world.bots_influence_ge_price", true)
|
||||
ServerConstants.REVENANT_POPULATION = data.getLong("world.revenant_population", 30L).toInt()
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package rs09.game.world.repository
|
||||
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.npc.revenant.RevenantNPC
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.map.RegionManager
|
||||
|
|
@ -37,7 +38,7 @@ object Repository {
|
|||
/**
|
||||
* The renderable NPCs.
|
||||
*/
|
||||
private val RENDERABLE_NPCS: MutableList<NPC> = CopyOnWriteArrayList()
|
||||
public val RENDERABLE_NPCS: MutableList<NPC> = CopyOnWriteArrayList()
|
||||
|
||||
/**
|
||||
* A mapping holding the players sorted by their names.
|
||||
|
|
@ -100,6 +101,7 @@ object Repository {
|
|||
*/
|
||||
@JvmStatic
|
||||
fun addRenderableNPC(npc: NPC) {
|
||||
if (npc is RevenantNPC) return // hack to make sure we can update revenants every tick.
|
||||
if (!RENDERABLE_NPCS.contains(npc)) {
|
||||
RENDERABLE_NPCS.add(npc)
|
||||
npc.isRenderable = true
|
||||
|
|
@ -112,6 +114,7 @@ object Repository {
|
|||
*/
|
||||
@JvmStatic
|
||||
fun removeRenderableNPC(npc: NPC) {
|
||||
if (npc is RevenantNPC) return // hack to make sure we can update revenants every tick.
|
||||
RENDERABLE_NPCS.remove(npc)
|
||||
npc.isRenderable = false
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue