Emberveil source

tests/CompanionPetsCheck.java

import com.rs2.*;import com.rs2.game.content.emberveil.*;import com.rs2.game.players.*;import com.rs2.game.npcs.*;import com.rs2.game.items.*;import org.apollo.cache.*;import org.apollo.cache.decoder.*;import com.rs2.world.clip.*;import java.nio.file.*;import java.util.*;
/** Runs only in the isolated pets-test-world, with disposable local characters. */
public class CompanionPetsCheck {
 static int checks;static void check(boolean b,String s){checks++;if(!b)throw new AssertionError(s);}
 static class F extends Client {F(String name,int id){super(null,id);playerName=playerName2=name;playerPass="local-fixture";playerRights=0;saveFile=saveCharacter=true;newPlayer=false;isActive=true;tutorialProgress=36;absX=3233;absY=3229;Arrays.fill(playerLevel,99);Arrays.fill(playerXP,13034431);Arrays.fill(playerEquipment,-1);getOutStream().packetEncryption=new org.apollo.util.security.IsaacRandom(new int[]{1,2,3,4});}public void flushOutStream(){getOutStream().currentOffset=0;}}
 static int petSlot(F p){for(int i=1;i<NpcHandler.npcs.length;i++)if(NpcHandler.npcs[i]!=null&&NpcHandler.npcs[i].summoner&&NpcHandler.npcs[i].summonedBy==p.playerId)return i;return -1;}
 public static void main(String[] args)throws Exception {
  check(Paths.get("").toAbsolutePath().toString().endsWith("pets-test-world"),"isolated test world only");
  IndexedFileSystem cache=new IndexedFileSystem(Paths.get("data/cache"),true);new ItemDefinitionDecoder(cache).run();new ObjectDefinitionDecoder(cache).run();RegionFactory.load(cache);ItemDefinitions.load();GameEngine.npcHandler=new NpcHandler();
  F a=new F("petfixturea",1),b=new F("petfixtureb",2);PlayerHandler.players[1]=a;PlayerHandler.players[2]=b;
  try{
   for(int item=14800;item<=14818;item++){
    check(org.apollo.cache.def.ItemDefinition.lookup(item).getName()!=null,"real server definition "+item);check(a.getItemAssistant().addItem(item,1),"grant pet fixture");int inv=a.getItemAssistant().getItemSlot(item);
    CompanionPets.release(a,item,27);check(!a.hasNpc,"forged slot rejected");CompanionPets.release(a,item,inv);int slot=petSlot(a);check(slot>0&&a.hasNpc&&a.summonId==3981+item-14800,"release follower");check(!a.getItemAssistant().playerHasItem(item),"item consumed once");check(NpcHandler.npcs[slot].MaxHP==0&&!NpcHandler.npcs[slot].underAttack,"non-combat follower");
    CompanionPets.pickup(b,slot);check(NpcHandler.npcs[slot]!=null&&a.hasNpc,"other player cannot steal pet");
    Npc n=NpcHandler.npcs[slot];n.absX=a.absX-5;n.absY=a.absY;int before=n.absX;CompanionPets.process(slot);check(n.absX>before,"pet actually follows walking player");a.heightLevel=1;CompanionPets.process(slot);check(n.heightLevel==1&&n.absX==a.absX,"follows floor changes");a.heightLevel=0;CompanionPets.process(slot);
    CompanionPets.pickup(a,slot);check(!a.hasNpc&&a.summonId==0&&NpcHandler.npcs[slot]==null,"pickup clears only owner state");check(a.getItemAssistant().playerHasItem(item),"same pet returned to inventory");CompanionPets.pickup(a,slot);check(a.getItemAssistant().getItemAmount(item)==1,"repeated pickup cannot duplicate");a.getItemAssistant().deleteItem(item,1);
   }
   a.getItemAssistant().addItem(14800,1);CompanionPets.release(a,14800,a.getItemAssistant().getItemSlot(14800));int slot=petSlot(a);check(PlayerSave.saveGame(a),"save active pet");F reload=new F("petfixturea",3);check(PlayerSave.loadGame(reload,"petfixturea","local-fixture")==1,"reload account");check(reload.hasNpc&&reload.summonId==3981,"follower survives save/relog");
   Arrays.fill(a.playerItems,996);Arrays.fill(a.playerItemsN,1);CompanionPets.returnToInventory(a,3981,true);check(a.hasNpc&&NpcHandler.npcs[slot]!=null,"full backpack retains active pet");a.playerItems[0]=a.playerItemsN[0]=0;CompanionPets.returnToInventory(a,3981,true);check(!a.hasNpc&&a.getItemAssistant().playerHasItem(14800),"pickup after freeing space");Arrays.fill(a.playerItems,0);Arrays.fill(a.playerItemsN,0);
   int[] skills={10,14,8,16,19,17,20};
   for(int i=0;i<skills.length;i++){final int expected=100000-99*25;check(CompanionPets.rollSkill(a,skills[i],100000,bound->{check(bound==expected,"base-level pet chance");return 0;}),"successful skill reward");check(a.getItemAssistant().playerHasItem(14812+i),"matching skill pet");check(!a.getItemAssistant().wearItem(14812+i,a.getItemAssistant().getItemSlot(14812+i)),"forged pet equip rejected");a.getItemAssistant().deleteItem(14812+i,1);}
   check(!CompanionPets.rollSkill(a,0,100000,bound->0),"combat XP cannot award skill pets");a.tutorialProgress=0;check(!CompanionPets.rollSkill(a,10,100000,bound->0),"tutorial has no pet rolls");a.tutorialProgress=36;
   int[] bosses={50,1160,3340,2881,2882,2883,3200,3957,3919,3944,3900,2745};
   for(int i=0;i<bosses.length;i++){
    final int rate=CompanionPets.bossRate(bosses[i]);check(rate>0,"boss drop configured");check(!CompanionPets.rollBoss(a,bosses[i],bound->{check(bound==rate,"exact denominator");return bound-1;}),"miss roll");check(CompanionPets.rollBoss(a,bosses[i],bound->0),"rare roll awards matching pet");check(a.getItemAssistant().playerHasItem(14800+i),"right boss pet");check(!CompanionPets.rollBoss(a,bosses[i],bound->0),"already-owned pet cannot duplicate");a.getItemAssistant().deleteItem(14800+i,1);
   }
   check(!CompanionPets.rollBoss(a,9,bound->0),"ordinary monsters have no boss pet");Arrays.fill(a.playerItems,996);Arrays.fill(a.playerItemsN,1);check(CompanionPets.rollBoss(a,50,bound->0),"full backpack rare roll safely banks");check(CompanionPets.owned(a,14800),"bank ownership detected");Arrays.fill(a.playerItems,0);Arrays.fill(a.playerItemsN,0);
   a.getItemAssistant().addItem(14996,1);check(a.getItemAssistant().wearItem(14996,a.getItemAssistant().getItemSlot(14996)),"max cape equips in real handler");check(a.playerEquipment[1]==14996,"max cape correct slot");a.getItemAssistant().removeItem(1);a.playerXP[8]=0;check(!a.getItemAssistant().wearItem(14996,a.getItemAssistant().getItemSlot(14996)),"all skills requirement enforced");a.playerXP[8]=13034431;
   a.getItemAssistant().addItem(9760,1);check(a.getItemAssistant().wearItem(9760,a.getItemAssistant().getItemSlot(9760)),"trimmed Prayer cape equips");check(a.playerEquipment[1]==9760,"Prayer cape correct slot");check(ItemDefinitions.getBonus(9760)[11]==4&&ItemDefinitions.getBonus(14996)[10]==4,"cape stats loaded");
   System.out.println("PASS "+checks+" pet ownership, release, real movement, floors, pickup, save/relog, exact boss rolls, full inventory and cape-equipping checks");
  }finally{PlayerHandler.players[1]=PlayerHandler.players[2]=null;for(String name:new String[]{"petfixturea","petfixtureb"})for(String suffix:new String[]{".txt",".txt.bak"})Files.deleteIfExists(Paths.get("data/characters/"+name+suffix));}
 }
}