Files
2006Scape/2006Scape Server/src/main/java/com/rs2/game/npcs/Npc.java
T
ipkpjersi e404eadb3b Added NPC kill counts with message display (#644)
* Added kill counts with message display

* Fixed barrows chest count

* Preserve insertion order of NPC IDs for Constants

* Added KC command and interfaces

* Added more robustness to KC command

* Added alias and documentation to new commands

* Added more aliases for new commands

* Merged slayer KC interface names

* Preserve slayerkc nameToKills insertion order and formatting fix

* Updated comment

* Added missing boss NPC id

* Moved giant mole up in set

* Emptied out quest interface properly for kc

* Fixed whitespace

* Fixed formatting

* Hide boss KC messages by default
2024-09-21 02:40:58 +01:00

492 lines
13 KiB
Java

package com.rs2.game.npcs;
import com.rs2.event.CycleEvent;
import com.rs2.event.CycleEventContainer;
import com.rs2.event.CycleEventHandler;
import com.rs2.game.items.DeprecatedItems;
import com.rs2.game.players.Player;
import com.rs2.game.players.PlayerHandler;
import com.rs2.util.Misc;
import com.rs2.util.Stream;
import static com.rs2.game.content.StaticNpcList.*;
public class Npc {
public int npcId;
public int npcType;
public int absX, absY;
public int heightLevel;
public static int lastX, lastY;
public int makeX, makeY, maxHit, defence, attack, moveX, moveY, direction, walkingType, hitsToHeal;
public int spawnX, spawnY;
public int viewX, viewY;
public boolean summoner;
public int summonedBy, size;
public int focusPointX, focusPointY, masterId;
public boolean turnUpdateRequired;
public int chasingRat = -1;
/**
* attackType: 0 = melee, 1 = range, 2 = mage
*/
public int attackType, projectileId, endGfx, spawnedBy, hitDelayTimer, HP,
MaxHP, hitDiff, animNumber, actionTimer, enemyX, enemyY,
combatLevel;
public boolean applyDead, isDead, needRespawn, respawns, aggressive;
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 boolean transformUpdateRequired = false, isTransformed = false;
public int transformId;
public Npc(int _npcId, int _npcType) {
npcId = _npcId;
npcType = _npcType;
direction = -1;
isDead = false;
applyDead = false;
actionTimer = 0;
randomWalk = true;
}
public void requestTransform(int id) {
transformId = id;
transformUpdateRequired = true;
updateRequired = true;
}
public String name() {
return NpcHandler.getNpcListName(this.npcType);
}
public void shearSheep(Player player, int itemNeeded, int itemGiven, int animation, final int currentId, final int newId, int transformTime) {
if (!player.getItemAssistant().playerHasItem(itemNeeded)) {
player.getPacketSender().sendMessage("You need " + DeprecatedItems.getItemName(itemNeeded).toLowerCase() + " to do that.");
return;
}
if (transformId == newId) {
player.getPacketSender().sendMessage("This sheep has already been shorn.");
return;
}
if (NpcHandler.npcs[npcId].isTransformed) {
return;
}
if (animation > 0) {
player.startAnimation(animation);
}
requestTransform(newId);
player.getItemAssistant().addItem(itemGiven, 1);
player.getPacketSender().sendMessage("You get some " + DeprecatedItems.getItemName(itemGiven).toLowerCase() + ".");
CycleEventHandler.getSingleton().addEvent(player, new CycleEvent() {
@Override
public void execute(CycleEventContainer container) {
requestTransform(currentId);
container.stop();
}
@Override
public void stop() {
NpcHandler.npcs[npcId].isTransformed = false;
}
}, transformTime);
}
public void appendTransformUpdate(Stream str) {
str.writeWordBigEndianA(transformId);
}
public void updateNPCMovement(Stream str) {
if (str != null) {
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);
}
public int startAnimation(int anim, int npcId) {
return animNumber;
}
/**
* 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;
turnUpdateRequired = true;
}
public int getNextWalkingDirection2() {
int dir;
dir = Misc.direction(absX, absY, absX + moveX, absY + moveY);
dir >>= 1;
absX += moveX;
absY += moveY;
return dir;
}
public void getRandomAndHomeNPCWalking(int i) {
direction = -1;
if (NpcHandler.npcs[i].freezeTimer == 0) {
direction = getNextWalkingDirection2();
}
}
public void appendFaceEntity(Stream str) {
str.writeWord(face);
}
/**
* NPC's That Don't Turn To Face The Player When Clicked
*/
private static int[] immobileNpcs = { //TODO Rename Appropriately
OSPAK,
STYRMIR,
TORBRUND,
FRIDGEIR,
};
public void facePlayer(Player player) {
for (int element : immobileNpcs) {
if (npcType == (element)) {
return;
}
}
face = (player != null) ? player.playerId + 32768 : 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 (transformUpdateRequired) {
updateMask |= 2;
}
if (turnUpdateRequired) {
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 (transformUpdateRequired) {
appendTransformUpdate(str);
}
if (turnUpdateRequired) {
appendSetFocusDestination(str);
}
}
public void clearUpdateFlags() {
updateRequired = false;
forcedChatRequired = false;
hitUpdateRequired = false;
hitUpdateRequired2 = false;
animUpdateRequired = false;
dirUpdateRequired = false;
transformUpdateRequired = false;
mask80update = false;
forcedText = null;
moveX = 0;
moveY = 0;
direction = -1;
focusPointX = -1;
focusPointY = -1;
turnUpdateRequired = false;
}
public int getNextWalkingDirection() {
int nextX = absX + moveX;
int nextY = absY + moveY;
int dir;
dir = Misc.direction(absX, absY, absX + moveX, absY + moveY);
for (Npc npc : NpcHandler.npcs) {
if (npc == null) {
continue;
}
if (npc.absX == nextX && npc.absY == nextY
&& npc.heightLevel == heightLevel) {
return -1;
}
}
for (Player p : PlayerHandler.players) {
if (p == null) {
continue;
}
if (p.absX == nextX && p.absY == nextY
&& p.heightLevel == heightLevel) {
return -1;
}
}
if (dir == -1) {
return -1;
}
dir >>= 1;
absX += moveX;
absY += moveY;
return dir;
}
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 int getLastX() {
return lastX;
}
public int getLastY() {
return lastY;
}
public void setAbsX(int absX) {
Npc.lastX = this.absX;
this.absX = absX;
}
public void setAbsY(int absY) {
Npc.lastY = this.absY;
this.absY = absY;
}
public void deleteNPC(Npc npc) {
setAbsX(0);
setAbsY(0);
npc = null;
}
public boolean inLesserNpc() {
return (absX >= 3108 && absX <= 3112 && absY >= 3156 && absY <= 3158 && heightLevel == 2);
}
public boolean inMulti() {
if (absX >= 3136
&& absX <= 3327
&& absY >= 3519
&& absY <= 3607
|| absX >= 2625
&& absX <= 2685
&& absY >= 2550
&& absY <= 2620 // Pest
// Control
|| 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 >= 2667
&& absX <= 2685
&& absY >= 3712
&& absY <= 3730 // rock
// crabs
|| 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) {
return true;
}
return false;
}
public boolean inWild() {// beg, end, beg, end, beg, end, beg, end
if (absX > 2941 && absX < 3392 && absY > 3518 && absY < 3966
|| absX > 2941 && absX < 3392 && absY > 9918 && absY < 10366) {
return true;
}
return false;
}
}