Code:
package server.model.npcs;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.stream.IntStream;
import server.Config;
import server.Server;
import server.model.players.Client;
import server.model.players.PlayerHandler;
import server.model.minigames.PestControl;
import server.util.Misc;
import server.world.map.VirtualWorld;
import server.event.EventManager;
import server.event.Event;
import server.event.EventContainer;
import server.clip.region.Region;
public class NPCHandler {
public static int maxNPCs = 10000;
public static int maxListedNPCs = 10000;
public static int maxNPCDrops = 10000;
public static NPC npcs[] = new NPC[maxNPCs];
public static NPCList NpcList[] = new NPCList[maxListedNPCs];
public static void spawnNewNPC(int npcType, int x, int y, int heightLevel, int WalkingType, int HP, int maxHit, int attack, int defence) {
int slot = -1;
for (int i = 1; i < maxNPCs; i++) {
if (npcs[i] == null) {
slot = i;
break;
}
}
if(slot == -1) {
return;
}
NPC newNPC = new NPC(slot, npcType);
newNPC.absX = x;
newNPC.absY = y;
newNPC.makeX = x;
newNPC.makeY = y;
newNPC.heightLevel = heightLevel;
newNPC.walkingType = WalkingType;
newNPC.HP = HP;
newNPC.MaxHP = HP;
newNPC.maxHit = maxHit;
newNPC.attack = attack;
newNPC.defence = defence;
npcs[slot] = newNPC;
}
public String[] voidKnightTalk = {
"We must not fail!",
"Take down the portals",
"The Void Knights will not fall!",
"Hail the Void Knights!",
"We are beating these scum!"
};
public NPCHandler() {
for(int i = 0; i < maxNPCs; i++) {
npcs[i] = null;
}
for(int i = 0; i < maxListedNPCs; i++) {
NpcList[i] = null;
}
loadNPCList("./Data/CFG/npc.cfg");
loadAutoSpawn("./Data/CFG/spawn-config.cfg");
}
public void multiAttackGfx(int i, int gfx) {
if (npcs[i].projectileId < 0)
return;
for (int j = 0; j < PlayerHandler.players.length; j++) {
if (PlayerHandler.players[j] != null) {
Client c = (Client)PlayerHandler.players[j];
if (c.heightLevel != npcs[i].heightLevel)
continue;
if (PlayerHandler.players[j].goodDistance(c.absX, c.absY, npcs[i].absX, npcs[i].absY, 15)) {
int nX = NPCHandler.npcs[i].getX() + offset(i);
int nY = NPCHandler.npcs[i].getY() + offset(i);
int pX = c.getX();
int pY = c.getY();
int offX = (nY - pY)* -1;
int offY = (nX - pX)* -1;
c.getPA().createPlayersProjectile(nX, nY, offX, offY, 50, getProjectileSpeed(i), npcs[i].projectileId, 43, 31, -c.getId() - 1, 65);
}
}
}
}
public boolean switchesAttackers(int i) {
switch(npcs[i].npcType) {
case 2551:
case 2552:
case 2553:
case 2559:
case 2560:
case 2561:
case 2563:
case 2564:
case 2565:
case 2892:
case 2894:
return true;
}
return false;
}
public void multiAttackDamage(int i) {
int max = getMaxHit(i);
for (int j = 0; j < PlayerHandler.players.length; j++) {
if (PlayerHandler.players[j] != null) {
Client c = (Client)PlayerHandler.players[j];
if (c.isDead || c.heightLevel != npcs[i].heightLevel)
continue;
if (PlayerHandler.players[j].goodDistance(c.absX, c.absY, npcs[i].absX, npcs[i].absY, 15)) {
if (npcs[i].attackType == 2) {
if (!c.prayerActive[16]) {
if (Misc.random(500) + 200 > Misc.random(c.getCombat().mageDef())) {
int dam = Misc.random(max);
c.dealDamage(dam);
c.handleHitMask(dam);
} else {
c.dealDamage(0);
c.handleHitMask(0);
}
} else {
c.dealDamage(0);
c.handleHitMask(0);
}
} else if (npcs[i].attackType == 1) {
if (!c.prayerActive[17]) {
int dam = Misc.random(max);
if (Misc.random(500) + 200 > Misc.random(c.getCombat().calculateRangeDefence())) {
c.dealDamage(dam);
c.handleHitMask(dam);
} else {
c.dealDamage(0);
c.handleHitMask(0);
}
} else {
c.dealDamage(0);
c.handleHitMask(0);
}
}
if (npcs[i].endGfx > 0) {
c.gfx0(npcs[i].endGfx);
}
}
c.getPA().refreshSkill(3);
}
}
}
public int getClosePlayer(int i) {
for (int j = 0; j < PlayerHandler.players.length; j++) {
if (PlayerHandler.players[j] != null) {
if (j == npcs[i].spawnedBy)
return j;
if (goodDistance(PlayerHandler.players[j].absX, PlayerHandler.players[j].absY, npcs[i].absX, npcs[i].absY, 2 + distanceRequired(i) + followDistance(i)) || isFightCaveNpc(i)) {
if ((PlayerHandler.players[j].underAttackBy <= 0 && PlayerHandler.players[j].underAttackBy2 <= 0) || PlayerHandler.players[j].inMulti())
if (PlayerHandler.players[j].heightLevel == npcs[i].heightLevel)
return j;
}
}
}
return 0;
}
public int getCloseRandomPlayer(int i) {
ArrayList<Integer> players = new ArrayList<Integer>();
for (int j = 0; j < PlayerHandler.players.length; j++) {
if (PlayerHandler.players[j] != null) {
if (goodDistance(PlayerHandler.players[j].absX, PlayerHandler.players[j].absY, npcs[i].absX, npcs[i].absY, 2 + distanceRequired(i) + followDistance(i)) || isFightCaveNpc(i)) {
if ((PlayerHandler.players[j].underAttackBy <= 0 && PlayerHandler.players[j].underAttackBy2 <= 0) || PlayerHandler.players[j].inMulti())
if (PlayerHandler.players[j].heightLevel == npcs[i].heightLevel)
players.add(j);
}
}
}
if (players.size() > 0)
return players.get(Misc.random(players.size() -1));
else
return 0;
}
public int npcSize(int i) {
switch (npcs[i].npcType) {
case 2883:
case 2882:
case 2881:
return 3;
}
return 0;
}
public boolean isAggressive(int i) {
switch (npcs[i].npcType) {
case 2550:
case 2551:
case 2552:
case 2553:
case 2558:
case 2559:
case 2560:
case 2561:
case 2562:
case 2563:
case 2564:
case 2565:
case 2892:
case 2894:
case 2881:
case 2882:
case 2883:
case 1459:
case 1926:
return true;
}
if (npcs[i].inWild() && npcs[i].MaxHP > 0)
return true;
if (isFightCaveNpc(i))
return true;
return false;
}
public boolean isFightCaveNpc(int i) {
switch (npcs[i].npcType) {
case 2627:
case 2630:
case 2631:
case 2741:
case 2743:
case 2745:
return true;
}
return false;
}
/**
* Summon npc, barrows, etc
**/
public static void spawnNpc(Client c, int npcType, int x, int y, int heightLevel, int WalkingType, int HP, int maxHit, int attack, int defence, boolean attackPlayer, boolean headIcon) {
// first, search for a free slot
int slot = -1;
for (int i = 1; i < maxNPCs; i++) {
if (npcs[i] == null) {
slot = i;
break;
}
}
if(slot == -1) {
//Misc.println("No Free Slot");
return; // no free slot found
}
NPC newNPC = new NPC(slot, npcType);
newNPC.absX = x;
newNPC.absY = y;
newNPC.makeX = x;
newNPC.makeY = y;
newNPC.heightLevel = heightLevel;
newNPC.walkingType = WalkingType;
newNPC.HP = HP;
newNPC.MaxHP = HP;
newNPC.maxHit = maxHit;
newNPC.attack = attack;
newNPC.defence = defence;
newNPC.spawnedBy = c.getId();
if(headIcon)
c.getPA().drawHeadicon(1, slot, 0, 0);
if(attackPlayer) {
newNPC.underAttack = true;
if(c != null) {
if(server.model.minigames.Barrows.COFFIN_AND_BROTHERS[c.randomCoffin][1] != newNPC.npcType) {
if(newNPC.npcType == 2025 || newNPC.npcType == 2026 || newNPC.npcType == 2027 || newNPC.npcType == 2028 || newNPC.npcType == 2029 || newNPC.npcType == 2030) {
newNPC.forceChat("You dare disturb my rest!");
}
}
if(server.model.minigames.Barrows.COFFIN_AND_BROTHERS[c.randomCoffin][1] == newNPC.npcType) {
newNPC.forceChat("You dare steal from us!");
}
newNPC.killerId = c.playerId;
}
}
npcs[slot] = newNPC;
}
public static void spawnNpc2(int npcType, int x, int y, int heightLevel, int WalkingType, int HP, int maxHit, int attack, int defence) {
// first, search for a free slot
int slot = -1;
for (int i = 1; i < maxNPCs; i++) {
if (npcs[i] == null) {
slot = i;
break;
}
}
if(slot == -1) {
//Misc.println("No Free Slot");
return; // no free slot found
}
NPC newNPC = new NPC(slot, npcType);
newNPC.absX = x;
newNPC.absY = y;
newNPC.makeX = x;
newNPC.makeY = y;
newNPC.heightLevel = heightLevel;
newNPC.walkingType = WalkingType;
newNPC.HP = HP;
newNPC.MaxHP = HP;
newNPC.maxHit = maxHit;
newNPC.attack = attack;
newNPC.defence = defence;
npcs[slot] = newNPC;
}
/**
* Attack delays
**/
public int getNpcDelay(int i) {
switch(npcs[i].npcType) {
case 2025:
case 2028:
return 7;
case 2745:
return 8;
case 2558:
case 2559:
case 2560:
case 2561:
case 2550:
return 6;
//saradomin gw boss
case 2562:
return 2;
default:
return 5;
}
}
/**
* Hit delays
**/
public int getHitDelay(int i) {
switch(npcs[i].npcType) {
case 2881:
case 2882:
case 3200:
case 2892:
case 2894:
return 3;
case 2743:
case 2631:
case 2558:
case 2559:
case 2560:
return 3;
case 2745:
if (npcs[i].attackType == 1 || npcs[i].attackType == 2)
return 5;
else
return 2;
case 2025:
return 4;
case 2028:
return 3;
default:
return 2;
}
}
/**
* Npc respawn time
**/
public int getRespawnTime(int i) {
switch(npcs[i].npcType) {
case 182:
case 183:
case 127:
return 60;
case 2881:
case 2882:
case 2883:
case 2558:
case 2559:
case 2560:
case 2561:
case 2562:
case 2563:
case 2564:
case 2550:
case 2551:
case 2552:
case 2553:
case 1926:
return 100;
case 3777:
case 3778:
case 3779:
case 3780:
return 500;
default:
return 25;
}
}
public void newNPC(int npcType, int x, int y, int heightLevel, int WalkingType, int HP, int maxHit, int attack, int defence) {
// first, search for a free slot
int slot = -1;
for (int i = 1; i < maxNPCs; i++) {
if (npcs[i] == null) {
slot = i;
break;
}
}
if(slot == -1) return; // no free slot found
NPC newNPC = new NPC(slot, npcType);
newNPC.absX = x;
newNPC.absY = y;
newNPC.makeX = x;
newNPC.makeY = y;
newNPC.heightLevel = heightLevel;
newNPC.walkingType = WalkingType;
newNPC.HP = HP;
newNPC.MaxHP = HP;
newNPC.maxHit = maxHit;
newNPC.attack = attack;
newNPC.defence = defence;
npcs[slot] = newNPC;
}
public void newNPCList(int npcType, String npcName, int combat, int HP) {
// first, search for a free slot
int slot = -1;
for (int i = 0; i < maxListedNPCs; i++) {
if (NpcList[i] == null) {
slot = i;
break;
}
}
if(slot == -1) return; // no free slot found
NPCList newNPCList = new NPCList(npcType);
newNPCList.npcName = npcName;
newNPCList.npcCombat = combat;
newNPCList.npcHealth = HP;
NpcList[slot] = newNPCList;
}
public void process() {
for (int i = 0; i < maxNPCs; i++) {
if (npcs[i] == null) continue;
npcs[i].clearUpdateFlags();
}
for (int i = 0; i < maxNPCs; i++) {
if (npcs[i] != null) {
if (npcs[i].npcType == 3782 && PestControl.gameStarted){
if (Misc.random(10) == 4)
npcs[i].forceChat(voidKnightTalk[Misc.random3(voidKnightTalk.length)]);
}
if (npcs[i].actionTimer > 0) {
npcs[i].actionTimer--;
}
if (npcs[i].freezeTimer > 0) {
npcs[i].freezeTimer--;
}
if (npcs[i].hitDelayTimer > 0) {
npcs[i].hitDelayTimer--;
}
if (npcs[i].hitDelayTimer == 1) {
npcs[i].hitDelayTimer = 0;
applyDamage(i);
}
if(npcs[i].attackTimer > 0) {
npcs[i].attackTimer--;
}
if(npcs[i].spawnedBy > 0) { // delete summons npc
if(PlayerHandler.players[npcs[i].spawnedBy] == null
|| PlayerHandler.players[npcs[i].spawnedBy].heightLevel != npcs[i].heightLevel
|| PlayerHandler.players[npcs[i].spawnedBy].respawnTimer > 0
|| !PlayerHandler.players[npcs[i].spawnedBy].goodDistance(npcs[i].getX(), npcs[i].getY(), PlayerHandler.players[npcs[i].spawnedBy].getX(), PlayerHandler.players[npcs[i].spawnedBy].getY(), 20)) {
if(PlayerHandler.players[npcs[i].spawnedBy] != null) {
for(int o = 0; o < PlayerHandler.players[npcs[i].spawnedBy].barrowsNpcs.length; o++){
if(npcs[i].npcType == PlayerHandler.players[npcs[i].spawnedBy].barrowsNpcs[o][0]) {
if (PlayerHandler.players[npcs[i].spawnedBy].barrowsNpcs[o][1] == 1)
PlayerHandler.players[npcs[i].spawnedBy].barrowsNpcs[o][1] = 0;
}
}
}
npcs[i] = null;
}
}
if (npcs[i] == null) continue;
/**
* Attacking player
**/
if (isAggressive(i) && !npcs[i].underAttack && !npcs[i].isDead && !switchesAttackers(i)) {
npcs[i].killerId = getCloseRandomPlayer(i);
} else if (isAggressive(i) && !npcs[i].underAttack && !npcs[i].isDead && switchesAttackers(i)) {
npcs[i].killerId = getCloseRandomPlayer(i);
}
if (System.currentTimeMillis() - npcs[i].lastDamageTaken > 5000)
npcs[i].underAttackBy = 0;
if((npcs[i].killerId > 0 || npcs[i].underAttack) && !npcs[i].walkingHome && retaliates(npcs[i].npcType)) {
if(!npcs[i].isDead) {
int p = npcs[i].killerId;
if(PlayerHandler.players[p] != null) {
Client c = (Client) PlayerHandler.players[p];
followPlayer(i, c.playerId);
if (npcs[i] == null) continue;
if(npcs[i].attackTimer == 0) {
if(c != null) {
attackPlayer(c, i);
} else {
npcs[i].killerId = 0;
npcs[i].underAttack = false;
npcs[i].facePlayer(0);
}
}
} else {
npcs[i].killerId = 0;
npcs[i].underAttack = false;
npcs[i].facePlayer(0);
}
}
}
/**
* Random walking and walking home
**/
if (npcs[i] == null) continue;
if((!npcs[i].underAttack || npcs[i].walkingHome) && npcs[i].randomWalk && !npcs[i].isDead) {
npcs[i].facePlayer(0);
npcs[i].killerId = 0;
if(npcs[i].spawnedBy == 0) {
if((npcs[i].absX > npcs[i].makeX + Config.NPC_RANDOM_WALK_DISTANCE) || (npcs[i].absX < npcs[i].makeX - Config.NPC_RANDOM_WALK_DISTANCE) || (npcs[i].absY > npcs[i].makeY + Config.NPC_RANDOM_WALK_DISTANCE) || (npcs[i].absY < npcs[i].makeY - Config.NPC_RANDOM_WALK_DISTANCE)) {
npcs[i].walkingHome = true;
}
}
if (npcs[i].walkingHome && npcs[i].absX == npcs[i].makeX && npcs[i].absY == npcs[i].makeY) {
npcs[i].walkingHome = false;
} else if(npcs[i].walkingHome) {
npcs[i].moveX = GetMove(npcs[i].absX, npcs[i].makeX);
npcs[i].moveY = GetMove(npcs[i].absY, npcs[i].makeY);
handleClipping(i);
npcs[i].getNextNPCMovement(i);
npcs[i].updateRequired = true;
}
if (npcs[i].walkingType >= 0) {
switch(npcs[i].walkingType) {
case 5:
npcs[i].turnNpc(npcs[i].absX-1, npcs[i].absY);
break;
case 4:
npcs[i].turnNpc(npcs[i].absX+1, npcs[i].absY);
break;
case 3:
npcs[i].turnNpc(npcs[i].absX, npcs[i].absY-1);
break;
case 2:
npcs[i].turnNpc(npcs[i].absX, npcs[i].absY+1);
break;
default:
if (npcs[i].walkingType >= 0) {
npcs[i].turnNpc(npcs[i].absX, npcs[i].absY); //makes it when npcs move they dont turn back to one direction
}
break;
}
}
if(npcs[i].walkingType == 1) {
if(Misc.random(3) == 1 && !npcs[i].walkingHome) {
/**
* To be used for Pest Control NPCs.
**/
//boolean isAnPestNPC = false;
//for (int b = 0; b < PestControl.pcPestIDs.length; b++) {
// if (PestControl.pcPestIDs[b] == npcs[i].npcId) {
// isAnPestNPC = true;
// break;
// } else {
// isAnPestNPC = false;
// }
//}
int MoveX = 0;
int MoveY = 0;
int Rnd = Misc.random(9);
if (Rnd == 1) {
MoveX = Misc.random(5);
MoveY = Misc.random(5);
} else if (Rnd == 2) {
MoveX = -Misc.random(5);
} else if (Rnd == 3) {
MoveY = -Misc.random(5);
} else if (Rnd == 4) {
MoveX = Misc.random(5);
} else if (Rnd == 5) {
MoveY = Misc.random(5);
} else if (Rnd == 6) {
MoveX = -Misc.random(5);
MoveY = -Misc.random(5);
} else if (Rnd == 7) {
MoveX = -Misc.random(5);
MoveY = Misc.random(5);
} else if (Rnd == 8) {
MoveX = Misc.random(5);
MoveY = -Misc.random(5);
}
if (MoveX >= 1) {
if (npcs[i].absX + MoveX < npcs[i].makeX + MoveX) {
npcs[i].moveX = MoveX;
} else {
npcs[i].moveX = 0;
}
}
if (MoveX <= -1) {
if (npcs[i].absX - MoveX > npcs[i].makeX - MoveX) {
npcs[i].moveX = MoveX;
} else {
npcs[i].moveX = 0;
}
}
if(MoveY >= 1) {
if(npcs[i].absY + MoveY < npcs[i].makeY + MoveY) {
npcs[i].moveY = MoveY;
} else {
npcs[i].moveY = 0;
}
}
if(MoveY <= -1) {
if(npcs[i].absY - MoveY > npcs[i].makeY - MoveY) {
npcs[i].moveY = MoveY;
} else {
npcs[i].moveY = 0;
}
}
int x = (npcs[i].absX + npcs[i].moveX);
int y = (npcs[i].absY + npcs[i].moveY);
if (VirtualWorld.I(npcs[i].heightLevel, npcs[i].absX, npcs[i].absY, x, y, 0)) {
handleClipping(i);
npcs[i].getNextNPCMovement(i);
}
else
{
npcs[i].moveX = 0;
npcs[i].moveY = 0;
}
npcs[i].updateRequired = true;
}
}
}
if (npcs[i].isDead == true) {
if (npcs[i].actionTimer == 0 && npcs[i].applyDead == false && npcs[i].needRespawn == false) {
npcs[i].updateRequired = true;
npcs[i].facePlayer(0);
npcs[i].killedBy = getNpcKillerId(i);
npcs[i].animNumber = NPCEmotes.getDeadEmote(i);
npcs[i].animUpdateRequired = true;
npcs[i].freezeTimer = 0;
npcs[i].applyDead = true;
killedBarrow(i);
if (isFightCaveNpc(i))
killedTzhaar(i);
npcs[i].actionTimer = 4; // delete time
resetPlayersInCombat(i);
} else if (npcs[i].actionTimer == 0 && npcs[i].applyDead == true && npcs[i].needRespawn == false) {
npcs[i].needRespawn = true;
npcs[i].actionTimer = getRespawnTime(i); // respawn time
dropItems(i); // npc drops items!
appendSlayerExperience(i);
appendKillCount(i);
npcs[i].absX = npcs[i].makeX;
npcs[i].absY = npcs[i].makeY;
npcs[i].HP = npcs[i].MaxHP;
npcs[i].animNumber = 0x328;
npcs[i].updateRequired = true;
npcs[i].animUpdateRequired = true;
if (npcs[i].npcType >= 2440 && npcs[i].npcType <= 2446) {
Server.objectManager.removeObject(npcs[i].absX, npcs[i].absY);
}
if (npcs[i].npcType == 2745) {
handleJadDeath(i);
}
} else if (npcs[i].actionTimer == 0 && npcs[i].needRespawn == true) {
if(npcs[i].spawnedBy > 0) {
npcs[i] = null;
} else {
int old1 = npcs[i].npcType;
int old2 = npcs[i].makeX;
int old3 = npcs[i].makeY;
int old4 = npcs[i].heightLevel;
int old5 = npcs[i].walkingType;
int old6 = npcs[i].MaxHP;
int old7 = npcs[i].maxHit;
int old8 = npcs[i].attack;
int old9 = npcs[i].defence;
npcs[i] = null;
newNPC(old1, old2, old3, old4, old5, old6, old7, old8, old9);
}
}
}
}
}
}
public boolean getsPulled(int i) {
switch (npcs[i].npcType) {
case 2550:
if (npcs[i].firstAttacker > 0)
return false;
break;
}
return true;
}
public boolean multiAttacks(int i) {
switch (npcs[i].npcType) {
case 2558:
return true;
case 2562:
if (npcs[i].attackType == 2)
return true;
case 2550:
if (npcs[i].attackType == 1)
return true;
default:
return false;
}
}
/**
* Npc killer id?
**/
public int getNpcKillerId(int npcId) {
int oldDamage = 0;
int count = 0;
int killerId = 0;
for (int p = 1; p < Config.MAX_PLAYERS; p++) {
if (PlayerHandler.players[p] != null) {
if(PlayerHandler.players[p].lastNpcAttacked == npcId) {
if(PlayerHandler.players[p].totalDamageDealt > oldDamage) {
oldDamage = PlayerHandler.players[p].totalDamageDealt;
killerId = p;
}
PlayerHandler.players[p].totalDamageDealt = 0;
}
}
}
return killerId;
}
/**
*
*/
private void killedBarrow(int i) {
Client c = (Client)PlayerHandler.players[npcs[i].killedBy];
if(c != null) {
for(int o = 0; o < c.barrowsNpcs.length; o++){
if(npcs[i].npcType == c.barrowsNpcs[o][0]) {
c.barrowsNpcs[o][1] = 2; // 2 for dead
c.barrowsKillCount++;
}
}
}
}
private void killedTzhaar(int i) {
final Client c2 = (Client)PlayerHandler.players[npcs[i].spawnedBy];
c2.tzhaarKilled++;
//System.out.println("To kill: " + c2.tzhaarToKill + " killed: " + c2.tzhaarKilled);
if (c2.tzhaarKilled == c2.tzhaarToKill) {
//c2.sendMessage("STARTING EVENT");
c2.waveId++;
EventManager.getSingleton().addEvent(new Event() {
@Override
public void execute(EventContainer c) {
if (c2 != null) {
Server.fightCaves.spawnNextWave(c2);
}
c.stop();
}
}, 7500);
}
}
public void handleJadDeath(int i) {
Client c = (Client)PlayerHandler.players[npcs[i].spawnedBy];
c.getItems().addItem(6570,1);
c.sendMessage("Congratulations on completing the fight caves minigame!");
c.getPA().resetTzhaar();
c.waveId = 300;
}
/**
* Dropping Items!
**/
public boolean rareDrops(int i) {
return Misc.random(NPCDrops.dropRarity.get(npcs[i].npcType)) == 0;
}
public void dropItems(int i) {
int npc = 0;
//long start = System.currentTimeMillis();
Client c = (Client)PlayerHandler.players[npcs[i].killedBy];
if(c != null) {
if (npcs[i].npcType == 912 || npcs[i].npcType == 913 || npcs[i].npcType == 914)
c.magePoints += 1;
if (NPCDrops.constantDrops.get(npcs[i].npcType) != null) {
for (int item : NPCDrops.constantDrops.get(npcs[i].npcType)) {
Server.itemHandler.createGroundItem(c, item, npcs[i].absX, npcs[i].absY, 1, c.playerId);
//if (c.clanId >= 0)
//Server.clanChat.handleLootShare(c, item, 1);
}
}
if (NPCDrops.dropRarity.get(npcs[i].npcType) != null) {
if (rareDrops(i)) {
int random = Misc.random(NPCDrops.rareDrops.get(npcs[i].npcType).length-1);
Server.itemHandler.createGroundItem(c, NPCDrops.rareDrops.get(npcs[i].npcType)[random][0], npcs[i].absX, npcs[i].absY, NPCDrops.rareDrops.get(npcs[i].npcType)[random][1], c.playerId);
if (c.clanId >= 0)
Server.clanChat.handleLootShare(c, NPCDrops.rareDrops.get(npcs[i].npcType)[random][0], NPCDrops.rareDrops.get(npcs[i].npcType)[random][1]);
} else {
int random = Misc.random(NPCDrops.normalDrops.get(npcs[i].npcType).length-1);
Server.itemHandler.createGroundItem(c, NPCDrops.normalDrops.get(npcs[i].npcType)[random][0], npcs[i].absX, npcs[i].absY, NPCDrops.normalDrops.get(npcs[i].npcType)[random][1], c.playerId);
//Server.clanChat.handleLootShare(c, NPCDrops.normalDrops.get(npcs[i].npcType)[random][0], NPCDrops.normalDrops.get(npcs[i].npcType)[random][1]);
}
}
}
//System.out.println("Took: " + (System.currentTimeMillis() - start));
}
public void appendKillCount(int i) {
Client c = (Client)PlayerHandler.players[npcs[i].killedBy];
if(c != null) {
int[] kcMonsters = {122,49,2558,2559,2560,2561,2550,2551,2552,2553,2562,2563,2564,2565};
for (int j : kcMonsters) {
if (npcs[i].npcType == j) {
if (c.killCount < 20) {
c.killCount++;
c.sendMessage("Killcount: " + c.killCount);
} else {
c.sendMessage("You already have 20 kill count");
}
break;
}
}
}
}
//id of bones dropped by npcs
public int boneDrop(int type) {
switch (type) {
case 1://normal bones
case 9:
case 100:
case 12:
case 17:
case 803:
case 18:
case 81:
case 101:
case 41:
case 19:
case 90:
case 75:
case 86:
case 78:
case 912:
case 913:
case 914:
case 1648:
case 1643:
case 1618:
case 1624:
case 181:
case 119:
case 49:
case 26:
case 1341:
return 526;
case 117:
return 532;//big bones
case 50://drags
case 53:
case 54:
case 55:
case 941:
case 1590:
case 1591:
case 1592:
return 536;
case 84:
case 1615:
case 1613:
case 82:
case 3200:
return 592;
case 2881:
case 2882:
case 2883:
return 6729;
default:
return -1;
}
}
public int getStackedDropAmount(int itemId, int npcId) {
switch (itemId) {
case 995:
switch (npcId) {
case 1:
return 50+ Misc.random(50);
case 9:
return 133 + Misc.random(100);
case 1624:
return 1000 + Misc.random(300);
case 1618:
return 1000 + Misc.random(300);
case 1643:
return 1000 + Misc.random(300);
case 1610:
return 1000 + Misc.random(1000);
case 1613:
return 1500 + Misc.random(1250);
case 1615:
return 3000;
case 18:
return 500;
case 101:
return 60;
case 913:
case 912:
case 914:
return 750 + Misc.random(500);
case 1612:
return 250 + Misc.random(500);
case 1648:
return 250 + Misc.random(250);
case 90:
return 200;
case 82:
return 1000 + Misc.random(455);
case 52:
return 400 + Misc.random(200);
case 49:
return 1500 + Misc.random(2000);
case 1341:
return 1500 + Misc.random(500);
case 26:
return 500 + Misc.random(100);
case 20:
return 750 + Misc.random(100);
case 21:
return 890 + Misc.random(125);
case 117:
return 500 + Misc.random(250);
case 2607:
return 500 + Misc.random(350);
}
break;
case 11212:
return 10 + Misc.random(4);
case 565:
case 561:
return 10;
case 560:
case 563:
case 562:
return 15;
case 555:
case 554:
case 556:
case 557:
return 20;
case 892:
return 40;
case 886:
return 100;
case 6522:
return 6 + Misc.random(5);
}
return 1;
}
/**
* Slayer Experience
**/
public void appendSlayerExperience(int i) {
int npc = 0;
Client c = (Client)PlayerHandler.players[npcs[i].killedBy];
if(c != null) {
if (c.slayerTask == npcs[i].npcType){
c.taskAmount--;
c.getPA().addSkillXP(npcs[i].MaxHP * Config.SLAYER_EXPERIENCE, 18);
if (c.taskAmount <= 0) {
c.getPA().addSkillXP((npcs[i].MaxHP * 8) * Config.SLAYER_EXPERIENCE, 18);
c.slayerTask = -1;
c.sendMessage("You completed your slayer task. Please see a slayer master to get a new one.");
}
}
}
}
/**
* Resets players in combat
*/
public void resetPlayersInCombat(int i) {
for (int j = 0; j < PlayerHandler.players.length; j++) {
if (PlayerHandler.players[j] != null)
if (PlayerHandler.players[j].underAttackBy2 == i)
PlayerHandler.players[j].underAttackBy2 = 0;
}
}
/**
* Npc Follow Player
**/
public int GetMove(int Place1,int Place2) {
if ((Place1 - Place2) == 0) {
return 0;
} else if ((Place1 - Place2) < 0) {
return 1;
} else if ((Place1 - Place2) > 0) {
return -1;
}
return 0;
}
public boolean followPlayer(int i) {
switch (npcs[i].npcType) {
case 2892:
case 2894:
return false;
}
return true;
}
public void followPlayer(int i, int playerId) {
if (PlayerHandler.players[playerId] == null) {
return;
}
if (PlayerHandler.players[playerId].respawnTimer > 0) {
npcs[i].facePlayer(0);
npcs[i].randomWalk = true;
npcs[i].underAttack = false;
return;
}
if (!followPlayer(i)) {
npcs[i].facePlayer(playerId);
return;
}
int playerX = PlayerHandler.players[playerId].absX;
int playerY = PlayerHandler.players[playerId].absY;
npcs[i].randomWalk = false;
if (goodDistance(npcs[i].getX(), npcs[i].getY(), playerX, playerY, distanceRequired(i)))
return;
if((npcs[i].spawnedBy > 0) || ((npcs[i].absX < npcs[i].makeX + Config.NPC_FOLLOW_DISTANCE) && (npcs[i].absX > npcs[i].makeX - Config.NPC_FOLLOW_DISTANCE) && (npcs[i].absY < npcs[i].makeY + Config.NPC_FOLLOW_DISTANCE) && (npcs[i].absY > npcs[i].makeY - Config.NPC_FOLLOW_DISTANCE))) {
if(npcs[i].heightLevel == PlayerHandler.players[playerId].heightLevel) {
if(PlayerHandler.players[playerId] != null && npcs[i] != null) {
if(playerY < npcs[i].absY) {
npcs[i].moveX = GetMove(npcs[i].absX, playerX);
npcs[i].moveY = GetMove(npcs[i].absY, playerY);
} else if(playerY > npcs[i].absY) {
npcs[i].moveX = GetMove(npcs[i].absX, playerX);
npcs[i].moveY = GetMove(npcs[i].absY, playerY);
} else if(playerX < npcs[i].absX) {
npcs[i].moveX = GetMove(npcs[i].absX, playerX);
npcs[i].moveY = GetMove(npcs[i].absY, playerY);
} else if(playerX > npcs[i].absX) {
npcs[i].moveX = GetMove(npcs[i].absX, playerX);
npcs[i].moveY = GetMove(npcs[i].absY, playerY);
} else if(playerX == npcs[i].absX || playerY == npcs[i].absY) {
int o = Misc.random(3);
switch(o) {
case 0:
npcs[i].moveX = GetMove(npcs[i].absX, playerX);
npcs[i].moveY = GetMove(npcs[i].absY, playerY+1);
break;
case 1:
npcs[i].moveX = GetMove(npcs[i].absX, playerX);
npcs[i].moveY = GetMove(npcs[i].absY, playerY-1);
break;
case 2:
npcs[i].moveX = GetMove(npcs[i].absX, playerX+1);
npcs[i].moveY = GetMove(npcs[i].absY, playerY);
break;
case 3:
npcs[i].moveX = GetMove(npcs[i].absX, playerX-1);
npcs[i].moveY = GetMove(npcs[i].absY, playerY);
break;
}
}
int x = (npcs[i].absX + npcs[i].moveX);
int y = (npcs[i].absY + npcs[i].moveY);
npcs[i].facePlayer(playerId);
handleClipping(i);
npcs[i].getNextNPCMovement(i);
npcs[i].facePlayer(playerId);
npcs[i].updateRequired = true;
}
}
} else {
npcs[i].facePlayer(0);
npcs[i].randomWalk = true;
npcs[i].underAttack = false;
}
}
public void handleClipping(int i) {
NPC npc = npcs[i];
if(npc.moveX == 1 && npc.moveY == 1) {
if((Region.getClipping(npc.absX + 1, npc.absY + 1, npc.heightLevel) & 0x12801e0) != 0) {
npc.moveX = 0; npc.moveY = 0;
if((Region.getClipping(npc.absX, npc.absY + 1, npc.heightLevel) & 0x1280120) == 0)
npc.moveY = 1;
else
npc.moveX = 1;
}
} else if(npc.moveX == -1 && npc.moveY == -1) {
if((Region.getClipping(npc.absX - 1, npc.absY - 1, npc.heightLevel) & 0x128010e) != 0) {
npc.moveX = 0; npc.moveY = 0;
if((Region.getClipping(npc.absX, npc.absY - 1, npc.heightLevel) & 0x1280102) == 0)
npc.moveY = -1;
else
npc.moveX = -1;
}
} else if(npc.moveX == 1 && npc.moveY == -1) {
if((Region.getClipping(npc.absX + 1, npc.absY - 1, npc.heightLevel) & 0x1280183) != 0) {
npc.moveX = 0; npc.moveY = 0;
if((Region.getClipping(npc.absX, npc.absY - 1, npc.heightLevel) & 0x1280102) == 0)
npc.moveY = -1;
else
npc.moveX = 1;
}
} else if(npc.moveX == -1 && npc.moveY == 1) {
if((Region.getClipping(npc.absX - 1, npc.absY + 1, npc.heightLevel) & 0x128013) != 0) {
npc.moveX = 0; npc.moveY = 0;
if((Region.getClipping(npc.absX, npc.absY + 1, npc.heightLevel) & 0x1280120) == 0)
npc.moveY = 1;
else
npc.moveX = -1;
}
}
if (npc.moveY == -1 ) {
if ((Region.getClipping(npc.absX, npc.absY - 1, npc.heightLevel) & 0x1280102) != 0)
npc.moveY = 0;
} else if( npc.moveY == 1) {
if((Region.getClipping(npc.absX, npc.absY + 1, npc.heightLevel) & 0x1280120) != 0)
npc.moveY = 0;
}
if(npc.moveX == 1) {
if((Region.getClipping(npc.absX + 1, npc.absY, npc.heightLevel) & 0x1280180) != 0)
npc.moveX = 0;
} else if(npc.moveX == -1) {
if((Region.getClipping(npc.absX - 1, npc.absY, npc.heightLevel) & 0x1280108) != 0)
npc.moveX = 0;
}
}
/**
* load spell
**/
public void loadSpell2(int i) {
npcs[i].attackType = 3;
int random = Misc.random(3);
if (random == 0) {
npcs[i].projectileId = 393; //red
npcs[i].endGfx = 430;
} else if (random == 1) {
npcs[i].projectileId = 394; //green
npcs[i].endGfx = 429;
} else if (random == 2) {
npcs[i].projectileId = 395; //white
npcs[i].endGfx = 431;
} else if (random == 3) {
npcs[i].projectileId = 396; //blue
npcs[i].endGfx = 428;
}
}
public void loadSpell(int i) {
switch(npcs[i].npcType) {
case 2892:
npcs[i].projectileId = 94;
npcs[i].attackType = 2;
npcs[i].endGfx = 95;
break;
case 2894:
npcs[i].projectileId = 298;
npcs[i].attackType = 1;
break;
case 50:
int random = Misc.random(4);
if (random == 0) {
npcs[i].projectileId = 393; //red
npcs[i].endGfx = 430;
npcs[i].attackType = 3;
} else if (random == 1) {
npcs[i].projectileId = 394; //green
npcs[i].endGfx = 429;
npcs[i].attackType = 3;
} else if (random == 2) {
npcs[i].projectileId = 395; //white
npcs[i].endGfx = 431;
npcs[i].attackType = 3;
} else if (random == 3) {
npcs[i].projectileId = 396; //blue
npcs[i].endGfx = 428;
npcs[i].attackType = 3;
} else if (random == 4) {
npcs[i].projectileId = -1; //melee
npcs[i].endGfx = -1;
npcs[i].attackType = 0;
}
break;
//arma npcs
case 2561:
npcs[i].attackType = 0;
break;
case 2560:
npcs[i].attackType = 1;
npcs[i].projectileId = 1190;
break;
case 2559:
npcs[i].attackType = 2;
npcs[i].projectileId = 1203;
break;
case 2558:
random = Misc.random(1);
npcs[i].attackType = 1 + random;
if (npcs[i].attackType == 1) {
npcs[i].projectileId = 1197;
} else {
npcs[i].attackType = 2;
npcs[i].projectileId = 1198;
}
break;
//sara npcs
case 2562: //sara
random = Misc.random(1);
if (random == 0) {
npcs[i].attackType = 2;
npcs[i].endGfx = 1224;
npcs[i].projectileId = -1;
} else if (random == 1)
npcs[i].attackType = 0;
break;
case 2563: //star
npcs[i].attackType = 0;
break;
case 2564: //growler
npcs[i].attackType = 2;
npcs[i].projectileId = 1203;
break;
case 2565: //bree
npcs[i].attackType = 1;
npcs[i].projectileId = 9;
break;
//bandos npcs
case 2550:
random = Misc.random(2);
if (random == 0 || random == 1)
npcs[i].attackType = 0;
else {
npcs[i].attackType = 1;
npcs[i].endGfx = 1211;
npcs[i].projectileId = 288;
}
break;
case 2551:
npcs[i].attackType = 0;
break;
case 2552:
npcs[i].attackType = 2;
npcs[i].projectileId = 1203;
break;
case 2553:
npcs[i].attackType = 1;
npcs[i].projectileId = 1206;
break;
case 2025:
npcs[i].attackType = 2;
int r = Misc.random(3);
if(r == 0) {
npcs[i].gfx100(158);
npcs[i].projectileId = 159;
npcs[i].endGfx = 160;
}
if(r == 1) {
npcs[i].gfx100(161);
npcs[i].projectileId = 162;
npcs[i].endGfx = 163;
}
if(r == 2) {
npcs[i].gfx100(164);
npcs[i].projectileId = 165;
npcs[i].endGfx = 166;
}
if(r == 3) {
npcs[i].gfx100(155);
npcs[i].projectileId = 156;
}
break;
case 2881://supreme
npcs[i].attackType = 1;
npcs[i].projectileId = 298;
break;
case 2882://prime
npcs[i].attackType = 2;
npcs[i].projectileId = 162;
npcs[i].endGfx = 477;
break;
case 2028:
npcs[i].attackType = 1;
npcs[i].projectileId = 27;
break;
case 3200:
int r2 = Misc.random(1);
if (r2 == 0) {
npcs[i].attackType = 1;
npcs[i].gfx100(550);
npcs[i].projectileId = 551;
npcs[i].endGfx = 552;
} else {
npcs[i].attackType = 2;
npcs[i].gfx100(553);
npcs[i].projectileId = 554;
npcs[i].endGfx = 555;
}
break;
case 2745:
int r3 = 0;
if (goodDistance(npcs[i].absX, npcs[i].absY, PlayerHandler.players[npcs[i].spawnedBy].absX, PlayerHandler.players[npcs[i].spawnedBy].absY, 1))
r3 = Misc.random(2);
else
r3 = Misc.random(1);
if (r3 == 0) {
npcs[i].attackType = 2;
npcs[i].endGfx = 157;
npcs[i].projectileId = 448;
} else if (r3 == 1) {
npcs[i].attackType = 1;
npcs[i].endGfx = 451;
npcs[i].projectileId = -1;
} else if (r3 == 2) {
npcs[i].attackType = 0;
npcs[i].projectileId = -1;
}
break;
case 2743:
npcs[i].attackType = 2;
npcs[i].projectileId = 445;
npcs[i].endGfx = 446;
break;
case 2631:
npcs[i].attackType = 1;
npcs[i].projectileId = 443;
break;
}
}
/**
* Distanced required to attack
**/
public int distanceRequired(int i) {
switch(npcs[i].npcType) {
case 2025:
case 2028:
return 6;
case 50:
case 2562:
return 2;
case 2881://dag kings
case 2882:
case 3200://chaos ele
case 2743:
case 2631:
case 2745:
return 8;
case 2883://rex
return 1;
case 2552:
case 2553:
case 2556:
case 2557:
case 2558:
case 2559:
case 2560:
case 2564:
case 2565:
return 9;
//things around dags
case 2892:
case 2894:
return 10;
default:
return 1;
}
}
public int followDistance(int i) {
switch (npcs[i].npcType) {
case 2550:
case 2551:
case 2562:
case 2563:
return 8;
case 2883:
return 4;
case 2881:
case 2882:
return 1;
}
return 0;
}
public int getProjectileSpeed(int i) {
switch(npcs[i].npcType) {
case 2881:
case 2882:
case 3200:
return 85;
case 2745:
return 130;
case 50:
return 90;
case 2025:
return 85;
case 2028:
return 80;
default:
return 85;
}
}
/**
*NPC Attacking Player
**/
public void attackPlayer(Client c, int i) {
if(npcs[i] != null) {
if (npcs[i].isDead)
return;
if (!npcs[i].inMulti() && npcs[i].underAttackBy > 0 && npcs[i].underAttackBy != c.playerId) {
npcs[i].killerId = 0;
return;
}
if (!npcs[i].inMulti() && (c.underAttackBy > 0 || (c.underAttackBy2 > 0 && c.underAttackBy2 != i))) {
npcs[i].killerId = 0;
return;
}
if (npcs[i].heightLevel != c.heightLevel) {
npcs[i].killerId = 0;
return;
}
npcs[i].facePlayer(c.playerId);
boolean special = false;//specialCase(c,i);
if(goodDistance(npcs[i].getX(), npcs[i].getY(), c.getX(), c.getY(), distanceRequired(i)) || special) {
if(c.respawnTimer <= 0) {
npcs[i].facePlayer(c.playerId);
npcs[i].attackTimer = getNpcDelay(i);
npcs[i].hitDelayTimer = getHitDelay(i);
npcs[i].attackType = 0;
if (special)
loadSpell2(i);
else
loadSpell(i);
if (npcs[i].attackType == 3)
npcs[i].hitDelayTimer += 2;
if (multiAttacks(i)) {
multiAttackGfx(i, npcs[i].projectileId);
startAnimation(NPCEmotes.getAttackEmote(i), i);
npcs[i].oldIndex = c.playerId;
return;
}
if(npcs[i].projectileId > 0) {
int nX = NPCHandler.npcs[i].getX() + offset(i);
int nY = NPCHandler.npcs[i].getY() + offset(i);
int pX = c.getX();
int pY = c.getY();
int offX = (nY - pY)* -1;
int offY = (nX - pX)* -1;
c.getPA().createPlayersProjectile(nX, nY, offX, offY, 50, getProjectileSpeed(i), npcs[i].projectileId, 43, 31, -c.getId() - 1, 65);
}
c.underAttackBy2 = i;
c.singleCombatDelay2 = System.currentTimeMillis();
npcs[i].oldIndex = c.playerId;
startAnimation(NPCEmotes.getAttackEmote(i), i);
c.getPA().removeAllWindows();
}
}
}
}
public int offset(int i) {
switch (npcs[i].npcType) {
case 50:
return 2;
case 2881:
case 2882:
return 1;
case 2745:
case 2743:
return 1;
}
return 0;
}
public boolean specialCase(Client c, int i) { //responsible for npcs that much
if (goodDistance(npcs[i].getX(), npcs[i].getY(), c.getX(), c.getY(), 8) && !goodDistance(npcs[i].getX(), npcs[i].getY(), c.getX(), c.getY(), distanceRequired(i)))
return true;
return false;
}
public boolean retaliates(int npcType) {
return npcType < 3777 || npcType > 3780 && !(npcType >= 2440 && npcType <= 2446);
}
public void applyDamage(int i) {
if(npcs[i] != null) {
if(PlayerHandler.players[npcs[i].oldIndex] == null) {
return;
}
if (npcs[i].isDead)
return;
Client c = (Client) PlayerHandler.players[npcs[i].oldIndex];
if (multiAttacks(i)) {
multiAttackDamage(i);
return;
}
if (c.playerIndex <= 0 && c.npcIndex <= 0)
if (c.autoRet == 1)
c.npcIndex = i;
if(c.attackTimer <= 3 || c.attackTimer == 0 && c.npcIndex == 0 && c.oldNpcIndex == 0) {
c.startAnimation(NPCEmotes.getBlockEmote(i), i);
}
if(c.respawnTimer <= 0) {
int damage = 0;
if(npcs[i].attackType == 0) {
damage = Misc.random(npcs[i].maxHit);
if (10 + Misc.random(c.getCombat().calculateMeleeDefence()) > Misc.random(NPCHandler.npcs[i].attack)) {
damage = 0;
}
if(c.prayerActive[18]) { // protect from melee
damage = 0;
}
if (c.playerLevel[3] - damage < 0) {
damage = c.playerLevel[3];
}
}
if(npcs[i].attackType == 1) { // range
damage = Misc.random(npcs[i].maxHit);
if (10 + Misc.random(c.getCombat().calculateRangeDefence()) > Misc.random(NPCHandler.npcs[i].attack)) {
damage = 0;
}
if(c.prayerActive[17]) { // protect from range
damage = 0;
}
if (c.playerLevel[3] - damage < 0) {
damage = c.playerLevel[3];
}
}
if(npcs[i].attackType == 2) { // magic
damage = Misc.random(npcs[i].maxHit);
boolean magicFailed = false;
if (10 + Misc.random(c.getCombat().mageDef()) > Misc.random(NPCHandler.npcs[i].attack)) {
damage = 0;
magicFailed = true;
}
if(c.prayerActive[16]) { // protect from magic
damage = 0;
magicFailed = true;
}
if (c.playerLevel[3] - damage < 0) {
damage = c.playerLevel[3];
}
if(npcs[i].endGfx > 0 && (!magicFailed || isFightCaveNpc(i))) {
c.gfx100(npcs[i].endGfx);
} else {
c.gfx100(85);
}
}
if (npcs[i].attackType == 3) { //fire breath
int anti = c.getPA().antiFire();
if (anti == 0) {
damage = Misc.random(30) + 10;
c.sendMessage("You are badly burnt by the dragon fire!");
} else if (anti == 1)
damage = Misc.random(20);
else if (anti == 2)
damage = Misc.random(5);
if (c.playerLevel[3] - damage < 0)
damage = c.playerLevel[3];
c.gfx100(npcs[i].endGfx);
}
handleSpecialEffects(c, i, damage);
c.logoutDelay = System.currentTimeMillis(); // logout delay
//c.setHitDiff(damage);
c.handleHitMask(damage);
c.playerLevel[3] -= damage;
c.getPA().refreshSkill(3);
c.updateRequired = true;
//c.setHitUpdateRequired(true);
}
}
}
public void handleSpecialEffects(Client c, int i, int damage) {
if (npcs[i].npcType == 2892 || npcs[i].npcType == 2894) {
if (damage > 0) {
if (c != null) {
if (c.playerLevel[5] > 0) {
c.playerLevel[5]--;
c.getPA().refreshSkill(5);
c.getPA().appendPoison(12);
}
}
}
}
}
public void startAnimation(int animId, int i) {
npcs[i].animNumber = animId;
npcs[i].animUpdateRequired = true;
npcs[i].updateRequired = true;
}
public boolean goodDistance(int objectX, int objectY, int playerX, int playerY, int distance) {
for (int i = 0; i <= distance; i++) {
for (int j = 0; j <= distance; j++) {
if ((objectX + i) == playerX && ((objectY + j) == playerY || (objectY - j) == playerY || objectY == playerY)) {
return true;
} else if ((objectX - i) == playerX && ((objectY + j) == playerY || (objectY - j) == playerY || objectY == playerY)) {
return true;
} else if (objectX == playerX && ((objectY + j) == playerY || (objectY - j) == playerY || objectY == playerY)) {
return true;
}
}
}
return false;
}
public int getMaxHit(int i) {
switch (npcs[i].npcType) {
case 2558:
if (npcs[i].attackType == 2)
return 28;
else
return 68;
case 2562:
return 31;
case 2550:
return 36;
}
return 1;
}
public boolean loadAutoSpawn(String FileName) {
String line = "";
String token = "";
String token2 = "";
String token2_2 = "";
String[] token3 = new String[10];
boolean EndOfFile = false;
int ReadMode = 0;
BufferedReader characterfile = null;
try {
characterfile = new BufferedReader(new FileReader("./"+FileName));
} catch(FileNotFoundException fileex) {
Misc.println(FileName+": file not found.");
return false;
}
try {
line = characterfile.readLine();
} catch(IOException ioexception) {
Misc.println(FileName+": error loading file.");
return false;
}
while(EndOfFile == false && line != null) {
line = line.trim();
int spot = line.indexOf("=");
if (spot > -1) {
token = line.substring(0, spot);
token = token.trim();
token2 = line.substring(spot + 1);
token2 = token2.trim();
token2_2 = token2.replaceAll("\t\t", "\t");
token2_2 = token2_2.replaceAll("\t\t", "\t");
token2_2 = token2_2.replaceAll("\t\t", "\t");
token2_2 = token2_2.replaceAll("\t\t", "\t");
token2_2 = token2_2.replaceAll("\t\t", "\t");
token3 = token2_2.split("\t");
if (token.equals("spawn")) {
newNPC(Integer.parseInt(token3[0]), Integer.parseInt(token3[1]), Integer.parseInt(token3[2]), Integer.parseInt(token3[3]), Integer.parseInt(token3[4]), getNpcListHP(Integer.parseInt(token3[0])), Integer.parseInt(token3[5]), Integer.parseInt(token3[6]), Integer.parseInt(token3[7]));
}
} else {
if (line.equals("[ENDOFSPAWNLIST]")) {
try { characterfile.close(); } catch(IOException ioexception) { }
return true;
}
}
try {
line = characterfile.readLine();
} catch(IOException ioexception1) { EndOfFile = true; }
}
try { characterfile.close(); } catch(IOException ioexception) { }
return false;
}
public int getNpcListHP(int npcId) {
for (int i = 0; i < maxListedNPCs; i++) {
if (NpcList[i] != null) {
if (NpcList[i].npcId == npcId) {
return NpcList[i].npcHealth;
}
}
}
return 0;
}
public String getNpcListName(int npcId) {
for (int i = 0; i < maxListedNPCs; i++) {
if (NpcList[i] != null) {
if (NpcList[i].npcId == npcId) {
return NpcList[i].npcName;
}
}
}
return "nothing";
}
public boolean loadNPCList(String FileName) {
String line = "";
String token = "";
String token2 = "";
String token2_2 = "";
String[] token3 = new String[10];
boolean EndOfFile = false;
int ReadMode = 0;
BufferedReader characterfile = null;
try {
characterfile = new BufferedReader(new FileReader("./"+FileName));
} catch(FileNotFoundException fileex) {
Misc.println(FileName+": file not found.");
return false;
}
try {
line = characterfile.readLine();
} catch(IOException ioexception) {
Misc.println(FileName+": error loading file.");
return false;
}
while(EndOfFile == false && line != null) {
line = line.trim();
int spot = line.indexOf("=");
if (spot > -1) {
token = line.substring(0, spot);
token = token.trim();
token2 = line.substring(spot + 1);
token2 = token2.trim();
token2_2 = token2.replaceAll("\t\t", "\t");
token2_2 = token2_2.replaceAll("\t\t", "\t");
token2_2 = token2_2.replaceAll("\t\t", "\t");
token2_2 = token2_2.replaceAll("\t\t", "\t");
token2_2 = token2_2.replaceAll("\t\t", "\t");
token3 = token2_2.split("\t");
if (token.equals("npc")) {
newNPCList(Integer.parseInt(token3[0]), token3[1], Integer.parseInt(token3[2]), Integer.parseInt(token3[3]));
}
} else {
if (line.equals("[ENDOFNPCLIST]")) {
try { characterfile.close(); } catch(IOException ioexception) { }
return true;
}
}
try {
line = characterfile.readLine();
} catch(IOException ioexception1) { EndOfFile = true; }
}
try { characterfile.close(); } catch(IOException ioexception) { }
return false;
}
}
NPC.java:
Code:
package server.model.npcs;
import server.Server;
import server.world.WalkingCheck;
import server.world.Tile;
import server.util.Misc;
import server.util.Stream;
public class NPC {
public static NPCHandler nh;
public int npcId;
public int npcType;
public int absX, absY;
public int heightLevel;
public int makeX, makeY, maxHit, defence, attack, moveX, moveY, direction, walkingType;
public int spawnX, spawnY;
public int viewX, viewY;
public Tile currentTile;
/**
* attackType: 0 = melee, 1 = range, 2 = mage
*/
public int attackType, projectileId, endGfx, spawnedBy, hitDelayTimer, HP, MaxHP, hitDiff, animNumber, actionTimer, enemyX, enemyY;
public boolean applyDead, isDead, needRespawn, respawns;
public boolean walkingHome, underAttack;
public int freezeTimer, attackTimer, killerId, killedBy, oldIndex, underAttackBy;
public long lastDamageTaken;
public boolean randomWalk;
public boolean dirUpdateRequired;
public boolean animUpdateRequired;
public boolean hitUpdateRequired;
public boolean updateRequired;
public boolean forcedChatRequired;
public boolean faceToUpdateRequired;
public int firstAttacker;
public String forcedText;
public NPC(int _npcId, int _npcType) {
npcId = _npcId;
npcType = _npcType;
direction = -1;
isDead = false;
applyDead = false;
actionTimer = 0;
randomWalk = true;
}
public void updateNPCMovement(Stream str) {
if (direction == -1) {
if (updateRequired) {
str.writeBits(1, 1);
str.writeBits(2, 0);
} else {
str.writeBits(1, 0);
}
} else {
str.writeBits(1, 1);
str.writeBits(2, 1);
str.writeBits(3, Misc.xlateDirectionToClient[direction]);
if (updateRequired) {
str.writeBits(1, 1);
} else {
str.writeBits(1, 0);
}
}
}
/**
* Text update
**/
public void forceChat(String text) {
forcedText = text;
forcedChatRequired = true;
updateRequired = true;
}
/**
*Graphics
**/
public int mask80var1 = 0;
public int mask80var2 = 0;
protected boolean mask80update = false;
public void appendMask80Update(Stream str) {
str.writeWord(mask80var1);
str.writeDWord(mask80var2);
}
public void gfx100(int gfx){
mask80var1 = gfx;
mask80var2 = 6553600;
mask80update = true;
updateRequired = true;
}
public void gfx0(int gfx){
mask80var1 = gfx;
mask80var2 = 65536;
mask80update = true;
updateRequired = true;
}
public void appendAnimUpdate(Stream str) {
str.writeWordBigEndian(animNumber);
str.writeByte(1);
}
/**
*
Face
*
**/
public int FocusPointX = -1, FocusPointY = -1;
public int face = 0;
private void appendSetFocusDestination(Stream str) {
str.writeWordBigEndian(FocusPointX);
str.writeWordBigEndian(FocusPointY);
}
public void turnNpc(int i, int j) {
FocusPointX = 2 * i + 1;
FocusPointY = 2 * j + 1;
updateRequired = true;
}
public void appendFaceEntity(Stream str) {
str.writeWord(face);
}
public void facePlayer(int player) {
face = player + 32768;
dirUpdateRequired = true;
updateRequired = true;
}
public void appendFaceToUpdate(Stream str) {
str.writeWordBigEndian(viewX);
str.writeWordBigEndian(viewY);
}
public void appendNPCUpdateBlock(Stream str) {
if(!updateRequired) return ;
int updateMask = 0;
if(animUpdateRequired) updateMask |= 0x10;
if(hitUpdateRequired2) updateMask |= 8;
if(mask80update) updateMask |= 0x80;
if(dirUpdateRequired) updateMask |= 0x20;
if(forcedChatRequired) updateMask |= 1;
if(hitUpdateRequired) updateMask |= 0x40;
if(FocusPointX != -1) updateMask |= 4;
str.writeByte(updateMask);
if (animUpdateRequired) appendAnimUpdate(str);
if (hitUpdateRequired2) appendHitUpdate2(str);
if (mask80update) appendMask80Update(str);
if (dirUpdateRequired) appendFaceEntity(str);
if(forcedChatRequired) {
str.writeString(forcedText);
}
if (hitUpdateRequired) appendHitUpdate(str);
if(FocusPointX != -1) appendSetFocusDestination(str);
}
public void clearUpdateFlags() {
updateRequired = false;
forcedChatRequired = false;
hitUpdateRequired = false;
hitUpdateRequired2 = false;
animUpdateRequired = false;
dirUpdateRequired = false;
mask80update = false;
forcedText = null;
moveX = 0;
moveY = 0;
direction = -1;
FocusPointX = -1;
FocusPointY = -1;
}
/*
public int getNextWalkingDirection() {
int dir;
dir = Misc.direction(absX, absY, (absX + moveX), (absY + moveY));
if (dir == -1)
return -1;
dir >>= 1;
absX += moveX;
absY += moveY;
return dir;
}*/
public int getNextWalkingDirection() {
currentTile = new Tile();
currentTile.setX(absX + moveX);
currentTile.setY(absY + moveY);
currentTile.setH(heightLevel);
if(!WalkingCheck.tiles.containsKey(currentTile.getH() << 28 | currentTile.getX() << 14 | currentTile.getY())){
int dir;
dir = Misc.direction(absX, absY, (absX + moveX), (absY + moveY));
if (dir == -1)
return -1;
dir >>= 1;
absX += moveX;
absY += moveY;
return dir;
} else if(WalkingCheck.tiles.get(currentTile.getH() << 28 | currentTile.getX() << 14 | currentTile.getY()) == true) {
return -1;
} else {
return -1;
}
}
public void getNextNPCMovement(int i) {
direction = -1;
if(NPCHandler.npcs[i].freezeTimer == 0) {
direction = getNextWalkingDirection();
}
}
public void appendHitUpdate(Stream str) {
if (HP <= 0) {
isDead = true;
}
str.writeByteC(hitDiff);
if (hitDiff > 0) {
str.writeByteS(1);
} else {
str.writeByteS(0);
}
str.writeByteS(HP);
str.writeByteC(MaxHP);
}
public int hitDiff2 = 0;
public boolean hitUpdateRequired2 = false;
public void appendHitUpdate2(Stream str) {
if (HP <= 0) {
isDead = true;
}
str.writeByteA(hitDiff2);
if (hitDiff2 > 0) {
str.writeByteC(1);
} else {
str.writeByteC(0);
}
str.writeByteA(HP);
str.writeByte(MaxHP);
}
public void handleHitMask(int damage) {
if (!hitUpdateRequired) {
hitUpdateRequired = true;
hitDiff = damage;
} else if (!hitUpdateRequired2) {
hitUpdateRequired2 = true;
hitDiff2 = damage;
}
updateRequired = true;
}
public int getX() {
return absX;
}
public int getY() {
return absY;
}
public boolean inMulti() {
if((absX >= 3136 && absX <= 3327 && absY >= 3519 && absY <= 3607) ||
(absX >= 3190 && absX <= 3327 && absY >= 3648 && absY <= 3839) ||
(absX >= 3200 && absX <= 3390 && absY >= 3840 && absY <= 3967) ||
(absX >= 2992 && absX <= 3007 && absY >= 3912 && absY <= 3967) ||
(absX >= 2946 && absX <= 2959 && absY >= 3816 && absY <= 3831) ||
(absX >= 3008 && absX <= 3199 && absY >= 3856 && absY <= 3903) ||
(absX >= 3008 && absX <= 3071 && absY >= 3600 && absY <= 3711) ||
(absX >= 3072 && absX <= 3327 && absY >= 3608 && absY <= 3647) ||
(absX >= 2624 && absX <= 2690 && absY >= 2550 && absY <= 2619) ||
(absX >= 2371 && absX <= 2422 && absY >= 5062 && absY <= 5117) ||
(absX >= 2896 && absX <= 2927 && absY >= 3595 && absY <= 3630) ||
(absX >= 2892 && absX <= 2932 && absY >= 4435 && absY <= 4464) ||
(absX >= 2256 && absX <= 2287 && absY >= 4680 && absY <= 4711) ||
(absX >= 3157 && absX <= 3191 && absY >= 2965 && absY <= 2995) ||
(absX >= 2785 && absX <= 2809 && absY >= 2775 && absY <= 2795)) {
return true;
}
return false;
}
public boolean inPirateHouse() {
return absX >= 3038 && absX <= 3044 && absY >= 3949 && absY <= 3959;
}
public boolean inAxeHut() {
return absX >= 3187 && absX <= 3194 && absY >= 3958 && absY <= 3962;
}
public boolean inWild() {
if(absX > 2941 && absX < 3392 && absY > 3518 && absY < 3966 ||
absX > 2941 && absX < 3392 && absY > 9918 && absY < 10366) {
return true;
}
return false;
}
}