Yasin 3 Posted November 10, 2018 Report Share Posted November 10, 2018 (edited) I've had to develop this in ~20 hours of total time for a service, with the quality of code not being a matter (by preference of customer). It's external instead of embedded, I didn't want to bother adapting to an already bad system, so I made it cycle based - it's working just fine, beside auto-retaliation (you can force that none the less, figure out on your own) It has: All attacks (Ranged, Prayer deactivation, Poison, Magic, Dragonfire) - as well as the freezing with the small alien pet, the big dragon fire (one-shot) & acid splatters. If you don't use this, at least recognize the approach on how I did the calculation for acid splatters landing AROUND the circle instead because all vorkaths I saw so far had half-assed acid splatters. Lacking stuff: The projectile height of the one-shot ball is a bit too low The delays are off on the smaller dragon balls, yet walking/dodging works fine The projectiles shoot from a tile instead of relative to vorkaths mouth/face The code is utter trash - lets be for real The delays obviously are not the same as OSRS There is no defensive stance animation / vorkath Death animation is lacking / Alien If I forgot a method, let me know link for the standalone classes This is the hidden content, please Sign In or Sign Up Yasin: Me on R-S If I forget anything, I'll tweak it asap on here Media: This is the hidden content, please Sign In or Sign Up This is the hidden content, please Sign In or Sign Up AttackType class package osv.model.npcs.bosses.vorkath; /** * @author Yasin */ public enum AttackType { MAGIC(7952, 1479, 1480), RANGED(7952, 1477, 1478), ONE_HIT(7960, 1491, 157), PRAYER_SNIPE(7952, 1471, 1473), POISON(7952, 1470, 1472), DRAGON_FIRE(7952, 393, 157), SPECIAL_1(7957, 1486, 1473), //acid SPECIAL_2(7952, 395, 369); //jihad private int animationId; private int projectileId; private int endGfx; AttackType(int animationId, int projectileId, int endGfx) { this.animationId = animationId; this.projectileId = projectileId; this.endGfx = endGfx; } public int getAnimationId() { return animationId; } public int getProjectileId() { return projectileId; } public int getEndGfx() { return endGfx; } } Vorkath class package osv.model.npcs.bosses.vorkath; import osv.Server; import osv.event.CycleEvent; import osv.event.CycleEventContainer; import osv.event.CycleEventHandler; import osv.event.DelayEvent; import osv.model.content.instances.InstancedAreaManager; import osv.model.content.instances.SingleInstancedArea; import osv.model.content.instances.impl.SingleInstancedVorkath; import osv.model.entity.HealthStatus; import osv.model.npcs.NPC; import osv.model.npcs.NPCDumbPathFinder; import osv.model.npcs.NPCHandler; import osv.model.npcs.bosses.vorkath.impl.DeathStage; import osv.model.npcs.bosses.vorkath.impl.SpawnStage; import osv.model.npcs.bosses.vorkath.impl.WakeUpStage; import osv.model.players.Player; import osv.model.players.Position; import osv.model.players.combat.Hitmark; import osv.util.Misc; import osv.world.objects.GlobalObject; import java.util.Arrays; import java.util.Optional; import java.util.stream.Collectors; /** * @author Yasin */ public class Vorkath { private final Player player; private AttackType specialAttackType; private AttackType attackType; private VorkathState vorkathState; private final Object eventLock; private int attacks; private NPC vorkath; private boolean zombieSpawned; private boolean forceDeath; private SingleInstancedVorkath vorkathInstance; public Vorkath(Player player) { this.player = player; this.specialAttackType = Arrays.stream(AttackType.values()).filter(type -> type.name().toLowerCase().contains("special")).collect(Collectors.toList()).get(Misc.random(1));//only 0 or 1 this.vorkathState = VorkathState.SLEEPING; this.eventLock = new Object(); } public void start() { if (vorkathInstance != null) { disposeInstance(); //player.sendMessage("Vorkath instance is not null, fyi! Disposing.."); } int height = InstancedAreaManager.getSingleton().getNextOpenHeight(VorkathConstants.VORKATH_BOUNDARY); vorkathInstance = new SingleInstancedVorkath(player, VorkathConstants.VORKATH_BOUNDARY, height); InstancedAreaManager.getSingleton().add(height, vorkathInstance); if (vorkathInstance == null) { player.getDH().sendStatement("Vorkath can't be fought right now.", "Please try again shortly."); player.nextChat = -1; return; } CycleEventHandler.getSingleton().addEvent(eventLock, new SpawnStage(this, player), 1); } public void disposeInstance() { forceDeath = true; if (vorkath != null) { setVorkathState(VorkathState.SLEEPING); Server.npcHandler.kill(vorkath.npcType, vorkathInstance.getHeight()); } attacks = 0; InstancedAreaManager.getSingleton().disposeOf(vorkathInstance); Server.getGlobalObjects().remove(32000, vorkathInstance.getHeight()); vorkathInstance = null; forceDeath = false; } public void resetCombat() { if (vorkath == null) { return; } player.getCombat().resetPlayerAttack(); vorkath.underAttack = false; vorkath.face = 0; if (vorkathState == VorkathState.RESTING) { vorkath.attackTimer += 1; } vorkath.underAttackBy = 0; } public boolean canSpecial() { return attacks % 7 == 0 && attacks > 0; } public void wakeUp() { if(vorkathState == VorkathState.AWAKE) { return; } if (vorkathState != VorkathState.RESTING) { //just to make sure vorkathState = VorkathState.AWAKE; CycleEventHandler.getSingleton().addEvent(eventLock, new WakeUpStage(this, player, false), 1); } if (vorkathState == VorkathState.RESTING) { //just to make sure vorkathState = VorkathState.AWAKE; CycleEventHandler.getSingleton().addEvent(eventLock, new WakeUpStage(this, player, true), 1); } } public void handleAttack() { if (player != null && vorkath != null && !vorkath.isDead && !player.isDead && !zombieSpawned) { int distance = player.distanceToPoint(vorkath.getX(), vorkath.getY()); if (vorkath.actionTimer > 0) { return; } if(distance >= 15) { return; } if(distance <= 3) { vorkath.actionTimer += 2; } vorkath.actionTimer += 5; attacks += 1; if (canSpecial()) { //Every 7 attacks specialAttackType = specialAttackType == AttackType.SPECIAL_1 ? AttackType.SPECIAL_2 : AttackType.SPECIAL_1; vorkath.startAnimation(specialAttackType.getAnimationId()); if (specialAttackType == AttackType.SPECIAL_1) { //acid CycleEventHandler.getSingleton().addEvent(eventLock, handleAcidSpecial(), 1); vorkath.actionTimer += 22; } else if (specialAttackType == AttackType.SPECIAL_2) { //jihad fireTargetedProjectile(specialAttackType.getProjectileId()); CycleEventHandler.getSingleton().addEvent(eventLock, handleJihadSpecial(), 1); player.stopMovement(); vorkath.actionTimer += 7; } } else { attackType = Arrays.stream(AttackType.values()).filter(type -> !type.name().toLowerCase().contains("special")). collect(Collectors.toList()).get(Misc.random(5)); vorkath.actionTimer += 1; vorkath.startAnimation(attackType.getAnimationId()); if (attackType != AttackType.ONE_HIT) { CycleEventHandler.getSingleton().addEvent(eventLock, handleAttackType(), 1); fireTargetedProjectile(attackType.getProjectileId()); } else { CycleEventHandler.getSingleton().addEvent(eventLock, handleOneHit(), 1); fireOneshit(attackType.getProjectileId(), 110, player.getX(), player.getY(), 50, 50); //50 -> current angle, 50 -> current start height } } } } public void jump() { CycleEventHandler.getSingleton().addEvent(eventLock, new CycleEvent() { boolean north; @Override public void execute(CycleEventContainer container) { if (container.getOwner() == null || player == null || player.isDead || player.animationRequest != -1) { container.stop(); return; } int cycle = container.getTotalTicks(); if (cycle == 1) { if (player.getX() <= 2273 && player.getX() >= 2271 && player.getY() == 4052) { north = true; } player.startAnimation(1115); player.sendMessage("You jump over the ice bricks.."); } if (cycle == 3) { player.stopAnimation(); player.sendMessage("and reach the other side.."); if(north && vorkathInstance == null) { start(); } if(vorkathInstance == null) { //height will be set in spawnstage player.getPA().movePlayer(player.getX(), north ? player.getY() + 2 : player.getY() - 2); } else { //so the player can continue player.getPA().movePlayer(player.getX(), north ? player.getY() + 2 : player.getY() - 2, vorkathInstance.getHeight()); } container.stop(); } } }, 1); } private CycleEvent handleJihadSpecial() { return new CycleEvent() { int SPAWN_X; int SPAWN_Y; NPC spawn; private void killSpawn(boolean explode) { spawn.gfx0(542); zombieSpawned = false; spawn.needRespawn = false; spawn.isDead = true; if(explode) { player.appendDamage(Misc.random(60) + 10, Hitmark.HIT); } player.freezeTimer = 0; } @Override public void execute(CycleEventContainer container) { if (container.getOwner() == null || vorkath == null || player == null || player.isDead || vorkathInstance == null) { container.stop(); return; } int cycle = container.getTotalTicks(); if (cycle == 4) { player.gfx0(specialAttackType.getEndGfx()); player.freezeTimer = 500; player.sendMessage("You've been frozen."); } if (cycle == 5) { SPAWN_X = vorkath.getX() + Misc.random(7) + 3; SPAWN_Y = vorkath.getY() - 2; player.sendMessage("The dragon throws a creature towards you.."); zombieSpawned = true; fireProjectileToLocation(1484, 130, SPAWN_X, SPAWN_Y, 50); } if (cycle == 9) { spawn = Server.npcHandler.spawnNpc(player, VorkathConstants.ZOMBIE_SPAWN, SPAWN_X, SPAWN_Y, vorkathInstance.getHeight(), 1, VorkathConstants.ZOMBIE_SPAWN_LIFE_POINTS, 1, 1, 1, false, false); } if (cycle >= 10) { int distance = player.distanceToPoint(spawn.getX(), spawn.getY()); if(zombieSpawned && spawn.isDead) { killSpawn(false); container.stop(); } if (distance <= 1 && zombieSpawned) { killSpawn(true); container.stop(); } } if (zombieSpawned && cycle >= 10) { if (spawn.getX() != player.absX - 1 && spawn.getY() != player.absY - 1) { NPCDumbPathFinder.walkTowards(spawn, player.getX(), player.getY()); } } if (!zombieSpawned && cycle >= 20) { container.stop(); } if (zombieSpawned && cycle >= 20 && player.distanceToPoint(spawn.getX(), spawn.getY()) >= 5) { if (player.distanceToPoint(spawn.getX(), spawn.getY()) < 40) { killSpawn(false); player.sendMessage("The spawn lost its orientation and blew up.."); } } } }; } private CycleEvent handleAcidSpecial() { return new CycleEvent() { int x; int y; @Override public void execute(CycleEventContainer container) { if (container.getOwner() == null || vorkath == null || player == null || player.isDead || vorkathInstance == null) { container.stop(); return; } int cycle = container.getTotalTicks(); if(Server.getGlobalObjects().exists(32000, player.getX(), player.getY(), player.getHeight())) { int randomDamage = Misc.random(10) + 7; vorkath.getHealth().increase(randomDamage); vorkath.updateRequired = true; player.appendDamage(randomDamage, Hitmark.HIT); player.sendMessage("You step on the acid and take some damage"); } if (cycle == 1) { int minX = VorkathConstants.VORKATH_BOUNDARY.getMinimumX(); int maxX = VorkathConstants.VORKATH_BOUNDARY.getMaximumX(); int minY = 4054; //it's bugged in the boundaries int maxY = VorkathConstants.VORKATH_BOUNDARY.getMaximumY(); for (int i = 0; i < 40; i++) { int randomX = minX + Misc.random(maxX - minX); int randomY = minY + Misc.random(maxY - minY); if ((randomX <= 2276 && randomX >= 2268 && randomY <= 4069 && randomY >= 4061)) { continue; } fireProjectileToLocation(1486, 100, randomX, randomY, 60); Server.getEventHandler().submit(new DelayEvent(5) { @Override public void onExecute() { Server.getGlobalObjects().add(new GlobalObject(32000, randomX, randomY, vorkathInstance.getHeight(), Misc.random(3) + 1, 10, -1, -1)); } }); } } if (cycle >= 3 && cycle <= 25) { if (cycle >= 5) { if (x == player.getX() && y == player.getY()) { player.appendDamage(30, Hitmark.HIT); } } x = player.getX(); y = player.getY(); fireProjectileToLocation(1482, 95, x, y, 35); player.getPA().stillGfx(131, x, y, 15, 95); fireProjectileToLocation(1482, 70, x, y, 35); player.getPA().stillGfx(131, x, y, 15, 70); } if (cycle == 30) { Server.getGlobalObjects().remove(32000, vorkathInstance.getHeight()); container.stop(); } } }; } private CycleEvent handleOneHit() { return new CycleEvent() { Position arrival; @Override public void execute(CycleEventContainer container) { if (container.getOwner() == null || vorkath == null || player == null || player.isDead || vorkathInstance == null) { container.stop(); return; } int cycle = container.getTotalTicks(); if (cycle == 0) { arrival = new Position(player.getX(), player.getY()); } if (cycle == 5) { int arrivalX = arrival.getX(); int arrivalY = arrival.getY(); int playerX = player.getX(); int playerY = player.getY(); if (playerX == arrivalX && playerY == arrivalY) { applyRandomDamage(player.getHealth().getMaximum()); player.getPA().stillGfx(attackType.getEndGfx(), arrival.getX(), arrival.getY(), 100, 0); } if(playerX == (arrivalX + 1) || playerX == (arrivalX - 1) || playerY == (arrivalY + 1) || arrivalY == (arrivalY - 1)) { applyRandomDamage(player.getHealth().getMaximum() / 2); player.getPA().stillGfx(attackType.getEndGfx(), arrivalX, arrivalY, 100, 0); } else { player.getPA().stillGfx(attackType.getEndGfx(), arrivalX, arrivalY, 20, 0); } container.stop(); } } }; } private void fireTargetedProjectile(int projectileId) { int offY = (vorkath.getX() - player.getX()) * -1; int offX = (vorkath.getY() - player.getY()) * -1; int delay = 0; player.getPA().createPlayersProjectile(vorkath.getX() + 3, vorkath.getY(), offX, offY, 50, 110, projectileId, 35, 31, -player.getIndex() - 1, 65, delay); } private void fireProjectileToLocation(int projectileId, int projectileSpeed, int targetX, int targetY, int startHeight) { int offY = (vorkath.getX() - targetX) * -1; int offX = (vorkath.getY() - targetY) * -1; int delay = 0; player.getPA().createPlayersProjectile(vorkath.getX() + 3, vorkath.getY(), offX, offY - 3, 50, projectileSpeed, projectileId, startHeight, 31, 0, 65, delay); } private void fireOneshit(int projectileId, int projectileSpeed, int targetX, int targetY, int angle, int startHeight) { int offY = (vorkath.getX() - targetX) * -1; int offX = (vorkath.getY() - targetY) * -1; int delay = 0; player.getPA().createPlayersProjectile(vorkath.getX() + 3, vorkath.getY(), offX, offY - 3, 50, projectileSpeed, projectileId, startHeight, 31, 0, 65, delay); } private CycleEvent handleAttackType() { return new CycleEvent() { @Override public void execute(CycleEventContainer container) { if (container.getOwner() == null || vorkath == null || player == null || player.isDead || vorkathInstance == null) { container.stop(); return; } int cycle = container.getTotalTicks(); //player.getPA().stillGfx(attackType.getEndGfx(), player.getX(), player.getY(), 100, 110); if (cycle == 4) { handleEffect(); } if (cycle == 5) { player.getPA().stillGfx(attackType.getEndGfx(), player.getX(), player.getY(), 100, 0); container.stop(); } } }; } private void applyRandomDamage(int amount) { player.appendDamage(Misc.random(amount) + 1, Hitmark.HIT); } private void handleEffect() { switch (attackType) { case MAGIC: if (player.prayerActive[16]) { player.appendDamage(0, Hitmark.MISS); return; } else { applyRandomDamage(35); } break; case POISON: applyRandomDamage(3); player.getHealth().proposeStatus(HealthStatus.POISON, Misc.random(12), Optional.of(vorkath)); break; case RANGED: if (player.prayerActive[17]) { player.appendDamage(0, Hitmark.MISS); return; } else { applyRandomDamage(30); } break; case DRAGON_FIRE: boolean isResistent = player.getItems().isWearingItem(1540) || player.getItems().isWearingItem(11283) || player.getItems().isWearingItem(11284) || (System.currentTimeMillis() - player.lastAntifirePotion < player.antifireDelay); if (isResistent) { player.sendMessage("Your resistance reflects the dragons fire!"); player.appendDamage(0, Hitmark.MISS); return; } else { applyRandomDamage(35); player.sendMessage("You got horribly burned by the dragons fire."); } break; case PRAYER_SNIPE: for (int i = 0; i < player.prayerActive.length - 1; i++) { if (!player.prayerActive[i]) continue; player.prayerActive[i] = false; player.getPA().sendFrame36(player.PRAYER_GLOW[i], 0); } player.headIcon = -1; player.getPA().requestUpdates(); applyRandomDamage(3); break; default: break; } } public void handleDeath() { vorkathState = VorkathState.RESTING; CycleEventHandler.getSingleton().addEvent(eventLock, new DeathStage(this, player), 1); } public void setVorkathInstance(SingleInstancedVorkath vorkathInstance) { this.vorkathInstance = vorkathInstance; } public AttackType getAttackType() { return attackType; } public VorkathState getVorkathState() { return vorkathState; } public SingleInstancedArea getVorkathInstance() { return vorkathInstance; } public Object getEventLock() { return eventLock; } public AttackType getSpecialAttackType() { return specialAttackType; } public void setVorkathState(VorkathState vorkathState) { this.vorkathState = vorkathState; } public NPC getNpc() { return vorkath; } public void setVorkath(NPC vorkath) { this.vorkath = vorkath; } public int getAttacks() { return attacks; } public void setAttacks(int attacks) { this.attacks = attacks; } public boolean isForceDeath() { return forceDeath; } public void setForceDeath(boolean forceDeath) { this.forceDeath = forceDeath; } public boolean isZombieSpawned() { return zombieSpawned; } } VorkathConstants class package osv.model.npcs.bosses.vorkath; import osv.model.players.Boundary; /** * @author Yasin */ public class VorkathConstants { public static final int SLEEPING_VORKATH_ID = 8059; public static final int AWAKENED_VORKATH_ID = 8061; public static final int ZOMBIE_SPAWN = 8063; public static final int ZOMBIE_SPAWN_LIFE_POINTS = 38; public static final int VORKATH_LIFE_POINTS = 769; public static final int X_COORDINATE = 2269; public static final int Y_COORDINATE = 4062; public static final Boundary VORKATH_BOUNDARY = new Boundary(2262, 4061, 2282, 4072); } VorkathState class package osv.model.npcs.bosses.vorkath; /** * @author Yasin */ public enum VorkathState { SLEEPING(-1, -1), RESTING(-1, -1), AWAKE(-1, -1); private int animation; private int npcId; VorkathState(int animation, int npcId) { this.animation = animation; this.npcId = npcId; } public int getAnimation() { return animation; } public int getNpcId() { return npcId; } } impl/DeathStage package osv.model.npcs.bosses.vorkath.impl; import osv.Server; import osv.event.CycleEventContainer; import osv.event.CycleEventHandler; import osv.model.npcs.NPCHandler; import osv.model.npcs.bosses.vorkath.Vorkath; import osv.model.npcs.bosses.vorkath.VorkathConstants; import osv.model.npcs.bosses.vorkath.VorkathState; import osv.model.players.Player; /** * @author Yasin */ public class DeathStage extends Stage { public DeathStage(Vorkath vorkath, Player player) { super(vorkath, player); } @Override public void execute(CycleEventContainer container) { if (container.getOwner() == null || vorkath == null || player == null || player.isDead || vorkath.getVorkathInstance() == null) { container.stop(); return; } int cycle = container.getTotalTicks(); int height = vorkath.getVorkathInstance().getHeight(); //reset both combat until stage ends vorkath.resetCombat(); player.getCombat().resetPlayerAttack(); // player.sendMessage("Death stage Cycle: " + cycle); if (cycle == 1) { vorkath.setVorkathState(VorkathState.RESTING); vorkath.getNpc().isDead = false; vorkath.getNpc().spawnedMinions = false; player.sendMessage("The dragon died.."); vorkath.getNpc().startAnimation(7949);//death animation vorkath.getNpc().requestTransform(8059); vorkath.setVorkath(Server.npcHandler.getNpc(VorkathConstants.SLEEPING_VORKATH_ID, VorkathConstants.X_COORDINATE, VorkathConstants.Y_COORDINATE, height)); container.stop(); } /*if (cycle == 10) { CycleEventHandler.getSingleton().addEvent(vorkath.getEventLock(), new WakeUpStage(vorkath, player, true), 1); container.stop(); }*/ } } impl/SpawnStage package osv.model.npcs.bosses.vorkath.impl; import osv.Server; import osv.event.CycleEventContainer; import osv.model.npcs.bosses.vorkath.Vorkath; import osv.model.npcs.bosses.vorkath.VorkathConstants; import osv.model.players.Player; /** * @author Yasin */ public class SpawnStage extends Stage { public SpawnStage(Vorkath vorkath, Player player) { super(vorkath, player); } @Override public void execute(CycleEventContainer container) { if (container.getOwner() == null || vorkath == null || player == null || player.isDead || player.disconnected || vorkath.getVorkathInstance() == null) { container.stop(); return; } int cycle = container.getTotalTicks(); int height = vorkath.getVorkathInstance().getHeight(); if(cycle == 1) { // player.sendMessage("Height before:" + player.heightLevel); player.setHeight(height); player.heightLevel = height; Server.getGlobalObjects().remove(32000, height); //player.sendMessage("Height after: " + player.getHeight()); vorkath.setVorkath(Server.npcHandler.spawnNpc(player, VorkathConstants.SLEEPING_VORKATH_ID, VorkathConstants.X_COORDINATE, VorkathConstants.Y_COORDINATE, height, -1, VorkathConstants.VORKATH_LIFE_POINTS, 1, 500, 500, false, false)); //player.sendMessage("On height: " + height); } if(cycle == 2) { player.sendMessage("You find yourself in a cave, with a dragon sleeping.."); } if(cycle >= 3) { container.stop(); } } } **Please move Stage outside of the impl package, hence Stage is not an implementation of itself..** impl/Stage class package osv.model.npcs.bosses.vorkath.impl; import osv.event.CycleEvent; import osv.event.CycleEventContainer; import osv.model.npcs.bosses.vorkath.Vorkath; import osv.model.players.Player; /** * @author Yasin */ public class Stage extends CycleEvent { protected Vorkath vorkath; protected Player player; public Stage(Vorkath vorkath, Player player) { this.vorkath = vorkath; this.player = player; } @Override public void execute(CycleEventContainer container) { } } package osv.model.npcs.bosses.vorkath.impl; import osv.Server; import osv.event.CycleEventContainer; import osv.model.npcs.NPCHandler; import osv.model.npcs.bosses.vorkath.Vorkath; import osv.model.npcs.bosses.vorkath.VorkathConstants; import osv.model.npcs.bosses.vorkath.VorkathState; import osv.model.players.Player; /** * @author Yasin */ public class WakeUpStage extends Stage { private boolean alreadyAlive; public WakeUpStage(Vorkath vorkath, Player player) { super(vorkath, player); } public WakeUpStage(Vorkath vorkath, Player player, boolean alreadyAlive) { super(vorkath, player); this.alreadyAlive = alreadyAlive; } @Override public void execute(CycleEventContainer container) { if (container.getOwner() == null || vorkath == null || player == null || player.isDead) { container.stop(); return; } int cycle = container.getTotalTicks(); //reset both combat until stage ends if(vorkath != null) { vorkath.resetCombat(); } if(alreadyAlive) { if(cycle == 3) { vorkath.getNpc().getHealth().setAmount(VorkathConstants.VORKATH_LIFE_POINTS); } if(cycle == 6) { vorkath.getNpc().startAnimation(7950); } if(cycle == 9) { vorkath.setAttacks(0); vorkath.getNpc().requestTransform(VorkathConstants.AWAKENED_VORKATH_ID); vorkath.setVorkath(Server.npcHandler.getNpc(VorkathConstants.AWAKENED_VORKATH_ID, VorkathConstants.X_COORDINATE, VorkathConstants.Y_COORDINATE, player.getHeight())); vorkath.setVorkathState(VorkathState.AWAKE); } if(cycle >= 12) { container.stop(); } } else { if(cycle == 1) { player.startAnimation(2292); player.sendMessage("You poke the dragon.."); } if(cycle == 2) { vorkath.getNpc().startAnimation(7950); player.turnPlayerTo(vorkath.getNpc().getX(), vorkath.getNpc().getY() - 3); vorkath.getNpc().getHealth().setAmount(VorkathConstants.VORKATH_LIFE_POINTS); } if(cycle == 9) { vorkath.getNpc().requestTransform(VorkathConstants.AWAKENED_VORKATH_ID); vorkath.setVorkathState(VorkathState.AWAKE); container.stop(); } } } } AttackAnimation class, handleEmote method Under the switch case case VorkathConstants.AWAKENED_VORKATH_ID: case VorkathConstants.SLEEPING_VORKATH_ID: Player player = PlayerHandler.players[Server.npcHandler.npcs[i].spawnedBy]; if (player == null || player.getVorkath() == null || player.getVorkath().getNpc() == null) { return -1; } if (player.getVorkath().canSpecial()) { return player.getVorkath().getSpecialAttackType().getAnimationId(); } else if (player.distanceToPoint(Server.npcHandler.npcs[i].getX(), Server.npcHandler.npcs[i].getY()) > 4) { return player.getVorkath().getAttackType().getAnimationId(); //regular attacks (distance) } return 7951; DeathAnimation class, handleEmote method under the switch case case VorkathConstants.ZOMBIE_SPAWN: case VorkathConstants.AWAKENED_VORKATH_ID: case VorkathConstants.SLEEPING_VORKATH_ID: return 102; NPCHandler class, getNpcDelay method under the switch case case VorkathConstants.AWAKENED_VORKATH_ID: case VorkathConstants.SLEEPING_VORKATH_ID: return 4; NPCHandler class, process method under if (npcs[i].actionTimer == 0 && !npcs[i].applyDead && !npcs[i].needRespawn) { add this if(npcs[i].npcType == VorkathConstants.SLEEPING_VORKATH_ID) { npcs[i].isDead = false; //player.sendMessage("HELL NO"); continue; } if (npcs[i].npcType == VorkathConstants.AWAKENED_VORKATH_ID) { if (player.getVorkath().isForceDeath()) { //if forced death (ie player logout) npcs[i].isDead = true; npcs[i].updateRequired = true; } else { //player.sendMessage("Applying death"); npcs[i].killedBy = player.getIndex(); dropItems(i); player.getVorkath().resetCombat(); player.getVorkath().handleDeath(); } continue; } under if (c.respawnTimer <= 0) { add this: if(npcs[i].npcType == VorkathConstants.AWAKENED_VORKATH_ID) { return; } NPCHandler class, followPlayer method under the switch case case VorkathConstants.AWAKENED_VORKATH_ID: case VorkathConstants.SLEEPING_VORKATH_ID: return false; NPCHandler class, attackPlayer method under if (npcs[i].lastX != npcs[i].getX() || npcs[i].lastY != npcs[i].getY()) { return; } add if(npcs[i].npcType == VorkathConstants.SLEEPING_VORKATH_ID) { return; } if (npcs[i].npcType == VorkathConstants.AWAKENED_VORKATH_ID) { if (c.getVorkath() != null) { c.getVorkath().handleAttack(); } } NPCHandler class, isAggressive (this should make vorkath aggressive] case VorkathConstants.AWAKENED_VORKATH_ID: return true; NPCHandler class, dropItems method if (npcs[i].npcType == VorkathConstants.AWAKENED_VORKATH_ID) { dropX = 2267; dropY = 4061; if (player.getNpcDeathTracker().getTracker().get(npcs[i].getName()) != null) { int kills = player.getNpcDeathTracker().getTracker().get(npcs[i].getName()); if (kills == 50) { Server.itemHandler.createGroundItem(player, 21907, dropX, dropY, player.heightLevel, 1); } } } NPCHandler class, distanceRequired method under switch case case VorkathConstants.AWAKENED_VORKATH_ID: return 35; NPCHandler class, retaliates( || npcType == VorkathConstants.AWAKENED_VORKATH_ID Config class, UNDEAD_IDS array, add this element: VorkathConstants.ZOMBIE_SPAWN Disposal of instance on logout: Player class, logout method if (vorkath.getVorkathInstance() != null) { //if logging out from vorkath or while in vorkath instance getPA().movePlayer(2272, 4052, 0); vorkath.disposeInstance(); } [/code] [/SPOILER] Disposal of instance when out of reach [SPOILER=Player, process] if (vorkath != null) { if (vorkath.getVorkathInstance() != null) { if (vorkath.getNpc() != null) { if (distanceToPoint(vorkath.getNpc().getX(), vorkath.getNpc().getY()) >= 40) { vorkath.disposeInstance(); sendMessage("Vorkath seems to have despawned.."); } } } } at last: Player class: declare instance private Vorkath vorkath = new Vorkath(this); declare getters/setters public Vorkath getVorkath() { return vorkath; } public void setVorkath(Vorkath vorkath) { this.vorkath = vorkath; } create class SingleInstancedVorkath class package osv.model.content.instances.impl; import osv.model.content.instances.SingleInstancedArea; import osv.model.npcs.bosses.vorkath.Vorkath; import osv.model.players.Boundary; import osv.model.players.Player; /** * @author Yasin */ public class SingleInstancedVorkath extends SingleInstancedArea { public SingleInstancedVorkath(Boundary boundary, int height) { super(boundary, height); } public SingleInstancedVorkath(Player player, Boundary boundary, int height) { super(player, boundary, height); } @Override public void onDispose() { Vorkath vorkath = player.getVorkath(); if (vorkath != null) { vorkath.disposeInstance(); } } } ObjectOptionOne class, under handleOption1add to the objectType switch: case 31990: if(c.getVorkath().getVorkathInstance() == null) { c.getVorkath().jump(); } break; Edited November 10, 2018 by Yasin 2 Link to comment Share on other sites More sharing options...
Yasin 3 Posted November 11, 2018 Author Report Share Posted November 11, 2018 You're welcome, if there is any bug let me know, trying to keep it updated with my thread on R-S. Link to comment Share on other sites More sharing options...
'Kyle 1 Posted November 19, 2018 Report Share Posted November 19, 2018 So you're going to continue working with this project?.. Or are you just releasing for the public to utilize, seeing as it was a paid project that you were hired to do? Link to comment Share on other sites More sharing options...
Ploy 0 Posted November 19, 2018 Report Share Posted November 19, 2018 thanks. will be useful. Link to comment Share on other sites More sharing options...
siccoblue 2 Posted May 5, 2019 Report Share Posted May 5, 2019 ill be looking into implementing this, good on you for releasing my dude Link to comment Share on other sites More sharing options...
darkk98 1 Posted August 27, 2019 Report Share Posted August 27, 2019 Thank you this should be handy! Link to comment Share on other sites More sharing options...
0xygen 0 Posted February 7, 2020 Report Share Posted February 7, 2020 Thanks for this, I've got a couple of ideas for a buffed vorkath boss so it's useful seeing how you did it Link to comment Share on other sites More sharing options...
Maulage 0 Posted March 11, 2020 Report Share Posted March 11, 2020 Thanks for this it really helped me out. Link to comment Share on other sites More sharing options...
UndeadAlien 0 Posted March 25, 2020 Report Share Posted March 25, 2020 thanks. I would love to work on vorkath when I have time Link to comment Share on other sites More sharing options...
CoinDozer 0 Posted April 21, 2020 Report Share Posted April 21, 2020 Thnx......................... Link to comment Share on other sites More sharing options...
Laced 0 Posted February 9, 2022 Report Share Posted February 9, 2022 Thanks! Link to comment Share on other sites More sharing options...
khonqr 0 Posted April 14, 2022 Report Share Posted April 14, 2022 thank you Link to comment Share on other sites More sharing options...
test710 0 Posted June 3, 2022 Report Share Posted June 3, 2022 Thanks for the contribution. Link to comment Share on other sites More sharing options...
Intarray 0 Posted April 20, 2023 Report Share Posted April 20, 2023 Amazing release ty! Link to comment Share on other sites More sharing options...
iqux93 0 Posted September 24, 2023 Report Share Posted September 24, 2023 Thank you for this Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now