ok i copy and paste tut i guess although im kinda against them its only a base and YOU should improve on it hugly.
now the way im going to do it is one event for all npcs and players with built in agression
if you would rather have one event per npc and player suit yourself and dont use it or whatever lol
first we have the main class for combat (note i didnt even compile this im just writing this off the top of my head lol)
Code:
package com.rs.worldserver.model.npc;
import java.util.Random;
import java.util.List;
import java.util.Map;
import com.rs.worldserver.Server;
import com.rs.worldserver.Constants;
import com.rs.worldserver.content.skill.SkillConstants;
import com.rs.worldserver.events.Event;
import com.rs.worldserver.events.EventContainer;
import com.rs.worldserver.events.EventManager;
import com.rs.worldserver.model.CombatAssistant;
import com.rs.worldserver.model.FloorItem;
import com.rs.worldserver.model.player.Client;
import com.rs.worldserver.model.player.Player;
import com.rs.worldserver.model.player.PlayerConstants;
import com.rs.worldserver.world.AnimationManager;
import com.rs.worldserver.content.skill.Magic;
import com.rs.worldserver.util.Misc;
/**
* Handles anything to do with NPC combat.
* @author Jonas(++)
* @author mad turnip - completly modified
*/
public class NPCCombat {
public NPCCombat(){
// Starting events for player and npc combat
startPlayerOnNpc();
startNpcOnPlayer();
}
public void startNpcOnPlayer(){
EventManager.getSingleton().addEvent(null, new Event() {
@Override
public void execute(EventContainer container) {
for (Map.Entry<Integer, NPC> entry : Server.getNpcManager().npcMap.entrySet()) {
NPC n = entry.getValue();
npcAtkPlayer(n);
}
}
@Override
public void stop() {
// Nothing has to be done.
}
}, 500);
}
public void startPlayerOnNpc(){
EventManager.getSingleton().addEvent(null, new Event() {
@Override
public void execute(EventContainer container) {
for (Player p : Server.getPlayerManager().getPlayers()) {
if(p == null)
continue;
Client c = (Client) p;
if(c.targetNPC != null)
playerAtkNpc(c);
}
}
@Override
public void stop() {
// Nothing has to be done.
}
}, 500);
}
public void resetAtk(NPC n){
n.setAttacker(null);
n.setWalking(n.isWasWalking());
}
public void resetAtk(Client c){
c.targetNPC = null;
}
private static final Random r = new Random();
public void playerAtkNpc(final Client client){
if(client.atkTimer > 0){
client.atkTimer--;
return;
}
final NPC npc = client.targetNPC;
if(npc == null){
return;
}
// Check if we died, teleported.
if (client.isDead() || client.didTeleport) {
resetAtk(client);
resetAtk(npc);
return;
}
// Check if the NPC is dead.
if(npc.isDead()) {
resetAtk(client);
resetAtk(npc);
return;
}
// Face to the npc.
int k = 0/*npc.getDefinition().sizeX*/;//if you add npc sizes
client.getActionAssistant().turnTo(client,npc.getAbsX()+k, npc.getAbsY()+k);
client.atkTimer = 3;//we have client attack timer here
if(client.autocastId > 1000){// i ahve included a small base for autocasting so its done right this time
//Magic.castSpellNPC(client.autocastId, client, npc);//this is magic on npc
} else { // We're now using melee.
//TODO: specials
// Check if we're close enough.
int i = 0/*(npc.getDefinition().sizeX)*/;//distance checks with npc size again you got to add npc sizes
if(Misc.distance(npc.getAbsX()+i,npc.getAbsY()+i,client.getAbsX(),client.getAbsY()) <= (1 + i)){
//stop movement
client.stopMovement();//stop movement because we dont wanna be on top of the npc duh
} else {
return;
}
// Show the animation.
client.getActionAssistant().startAnimation(client,0x326);
// Start a new event for a delay.
EventManager.getSingleton().addEvent(null, new Event() {//hit delay cause i aint god and it takes time to swing your wepon duh
@Override
public void execute(EventContainer container) {
// Check if the NPC still exist.
if(npc == null || client.disconnected) {
container.stop();
return;
}
npc.faceTo(client.playerId);//npc faces us
if (npc.getAttacker() == null) {//npc fights back
npc.setAttacker(client);
}
// Calculate the hit.
CombatAssistant.calculateMaxHit(client);//we get max hit
int hit = (int) Math.floor(Math.random() * (double) client.playerMaxHit);//random value of maxhit
// Show the hit on the NPC.
npc.hit(client, hit, 1);
// Show defend animation on the NPC.
if (npc.getAttacker() == client) {
npc.setAnimNumber(404);
npc.setAnimUpdateRequired(true);
npc.setUpdateRequired(true);
}
client.getActionAssistant().addSkillXP(client,10, 0);
client.getActionAssistant().addSkillXP(client,11, 1);
client.getActionAssistant().addSkillXP(client,12, 2);
client.getActionAssistant().addSkillXP(client,13,SkillConstants.HITPOINTS);
// Stop the event.
container.stop();
}
@Override
public void stop() {
// Nothing has to be done.
}
}, 500);
}
}
public void playerSetNpc(Client c,int npcId){
final NPC npc = Server.getNpcManager().getNPC(npcId);//this is what we do once the player sends attack npc packet
if(npc != null)
npc.getAttackers().put(c, 0);
c.targetNPC = npc;
}
public void agressiveNPC(NPC npc){
for (Player p : Server.getPlayerManager().getPlayers()) {
if(p == null)
continue;
Client client = (Client) p;
if(client.getCombatLevel() / 2 > npc.getDefinition().getCombat() && (npc.getDefinition().getType() < 2627 && npc.getDefinition().getType() > 2745) ){
continue;
}
if(client.getHeightLevel() == npc.getHeightLevel()){
int k = /*npc.getDefinition().sizeX*/0;//npc sizes removed again lol
if(Misc.distance(npc.getAbsX()+k,npc.getAbsY()+k,client.getAbsX(),client.getAbsY()) <= npc.agressive+k){
npc.setAttacker(client);
return;
}
}
}
}
public void npcAtkPlayer(final NPC npc){
// Get the NPCId.
final int npcId = npc.getDefinition().getType();
final Client client = npc.getAttacker();
// Check if the NPC exists.
if (npc == null)
return;
if(npc.atkTimer > 0){//we use this old shit timer lolz a long would be better but oh well lol
npc.atkTimer--;
return;
}
if(npc.getAttacker() == null){
if(npc.agressive > 0){
agressiveNPC(npc);
}
return;
}
npc.atkTimer = 3;
// Check if the NPC died.
if(npc.isDead()){
resetAtk(npc);
return;
}
if(client.getHeightLevel() != npc.getHeightLevel()){
resetAtk(npc);
return;
}
// Face the NPC to the player.
if (npc.getAttacker() == client)
npc.faceTo(client.playerId);
int k = 0/*npc.getDefinition().sizeX*/;//npc size removed again lol
int dis = Misc.distance(npc.getAbsX()+k,npc.getAbsY()+k,client.getAbsX(),client.getAbsY());
// Check if the NPC is close enough.
if(dis > 15){
resetAtk(npc);
return;
}
// Start the animation.
npc.setAnimNumber(0x326);
npc.setAnimUpdateRequired(true);
npc.setUpdateRequired(true);
EventManager.getSingleton().addEvent(null, new Event() {
@Override
public void execute(EventContainer container) {
// Check if the NPC still exist
if(npc == null || client.isDead() || client.disconnected) {
container.stop();
return;
}
// Face the NPC to the player.
npc.faceTo(client.playerId);
// Calculate the hit.
int hit =(int) Math.floor(Math.random() * (double) /*npc.getDefinition().getMaximumHit()*/10);//npc max damg 10?
client.getActionAssistant().hit(client,hit, 1);
// Show the defend animation on the player.
client.getActionAssistant().startAnimation(client,404);
// Stop the event.
container.stop();
}
@Override
public void stop() {
// Nothing has to be done.
}
}, 750);
}
}
now that handles full npc combat only a few other little things we got to add
in Server.java we got to add this
npcCombat = new NPCCombat();
that will make sure the events are run once the server is started
now we got to add those variables to the npcs and palyers
in NPC.java add these
Code:
public int atkTimer = 0;
public int agressive = 0;
private Client attacker = null;
public void setAttacker(Client attacker) {
this.attacker = attacker;
}
/**
* @return the attacker
*/
public Client getAttacker() {
return attacker;
}
there for npcs and heres the player ones
Code:
public NPC targetNPC = null;
public int atkTimer = 0;
now thats it for the variables we got to add a few methods now
Code:
public static double calculateMaxHit(Client c) {
double MaxHit = 0;
int StrBonus = (c.getBonus()[10]+9); // Strength Bonus
int Strength = c.playerLevel[2]; // Strength
int RngBonus = c.getBonus()[4]; // Ranged Bonus
int Range = c.playerLevel[4]; // Ranged
int f = c.getFightType();
if ((f == 1) || (f == 4)) {
// Accurate & Defensive
MaxHit += (double) (1.05 + (double) ((double) (StrBonus * Strength) * 0.00175));
} else if (f == 2) {
// Aggresive
MaxHit += (double) (1.05 + (double) ((double) (StrBonus * Strength) * 0.00175));
} else if (f == 3) {
// Controlled
MaxHit += (double) (1.05 + (double) ((double) (StrBonus * Strength) * 0.00175));
}
MaxHit += (double) (Strength * 0.1);
/*
* if (StrPotion == 1) { // Strength Potion MaxHit += (double) (Strength *
* 0.0014); } else if (StrPotion == 2) { // Super Strength Potion MaxHit +=
* (double) (Strength * 0.0205); }
*/
if (c.getPrayer()[1]) {
// Burst Of Strength
MaxHit += 1;
} else if (c.getPrayer()[7]) {
// Super Human Strength
MaxHit += 2;
} else if (c.getPrayer()[10]) {
// Ultimate Strength
MaxHit += 3;
}
if ((f == 5) || (f == 6)) {
// Accurate and Longranged
MaxHit += (double) (1.05 + (double) ((double) (RngBonus * Range) * 0.00075));
} else if (f == 7) {
// Rapid
MaxHit += (double) (1.35 + (double) ((double) (RngBonus) * 0.00025));
}
// MaxHit += (double) (Range * 0.03);
if(dharokEquipped(c)) {
MaxHit +=(c.getActionAssistant().getLevelForXP(c,c.playerXP[SkillConstants.HITPOINTS])
- c.playerLevel[SkillConstants.HITPOINTS])/3;
}
c.playerMaxHit = (int) Math.floor(MaxHit);
if(c.playerMaxHit <= 2)
c.playerMaxHit = 2;//this gives lvl 3s a chacne to actally do damage
return c.playerMaxHit;
}
add that in combatassistant.java it calculates the players max hit
ok thats the most part done of this tutorial now we got to add the player on npc packet
in model.players.packet open the attack.java or attack packet as it may be different in your version now we got to add case 72 for player on npc combat
Code:
if (packetType == 72) {
int attacknpc = client.getInStream().readUnsignedWordA();
Server.getNPCCombat().playerSetNpc(client,attacknpc);
}
now we have working npc combat :
yay go us lmfao
you will probably be guarteened a few errors anything major post it here but try fix the basic errors yourself
this also includes basic autocasting and full working agression you just got to add one small thing to make agression work 
npc vs player is very basic and player vs npc is a bit more advanced but this is only ment to be a base that is improved on
thanks martin llol