Emberveil source

tests/TribalTotemWorldCheck.java

import java.nio.file.*;import java.util.*;import org.apollo.cache.*;import org.apollo.cache.decoder.*;import com.rs2.world.clip.*;import com.rs2.game.content.quests.impl.TribalTotem;
public class TribalTotemWorldCheck {
 static int checks;
 static int[][] objects={{1557,2635,3307,0},{1558,2636,3307,0},{2705,2634,3323,0},{2706,2635,3321,0},{2711,2631,3322,0},{1723,2631,3322,1},{1755,2632,9694,0},
 {1533,2636,3323,0},{1533,2639,3323,0},{1533,2632,3319,1},{1533,2638,3319,1},{1530,2644,3273,0},{1530,2648,3299,0},{1530,2650,3297,0},{1516,2678,3325,0},{1519,2678,3324,0}};

 static long key(int x,int y,int z){return ((long)z<<32)|((long)x<<16)|y;}
 static void add(ArrayDeque<int[]> q,Set<Long>s,int x,int y,int z){if(x<2600||x>2700||!((y>=3260&&y<=3345)||(y>=9680&&y<=9745)))return;if(s.add(key(x,y,z)))q.add(new int[]{x,y,z});}
 static void route(int sx,int sy,int sz,int tx,int ty,int tz,int radius,int flags,String label){
  TribalTotemCheck.F p=new TribalTotemCheck.F();p.tribalTotem=1;p.tribalFlags=flags;
  ArrayDeque<int[]> q=new ArrayDeque<>();Set<Long>s=new HashSet<>();add(q,s,sx,sy,sz);int best=9999,bx=0,by=0;
  while(!q.isEmpty()){
   int[] t=q.remove();int x=t[0],y=t[1],z=t[2];
   if(z==tz){int d=Math.max(Math.abs(x-tx),Math.abs(y-ty));if(d<best){best=d;bx=x;by=y;}if(d<=radius){checks++;System.out.println("ROUTE PASS "+label+" goal="+x+","+y+","+z+" explored="+s.size());return;}}
   for(int dx=-1;dx<=1;dx++)for(int dy=-1;dy<=1;dy++)if((dx!=0||dy!=0)&&Region.canMove(x,y,x+dx,y+dy,z,1,1))add(q,s,x+dx,y+dy,z);
   for(int[] a:objects)if(a[3]==z&&Math.abs(x-a[1])<=1&&Math.abs(y-a[2])<=1){
    for(int action=1;action<=3;action++){p.pos(x,y,z);TribalTotem.object(p,a[0],a[1],a[2],action);if(p.teleportToX!=0)add(q,s,p.teleportToX,p.teleportToY,p.teleHeight);}
   }
  }throw new AssertionError(label+" inaccessible, closest="+bx+","+by+" d="+best+" visited="+s.size());
 }
 static void safe(int id,int x,int y,int size){for(int dx=0;dx<size;dx++)for(int dy=0;dy<size;dy++)if((Region.getClipping(x+dx,y+dy,0)&0x1280100)!=0)throw new AssertionError("Blocked NPC "+id+" "+x+","+y);checks++;}
 public static void main(String[]args)throws Exception{
  IndexedFileSystem c=new IndexedFileSystem(Paths.get("data/cache"),true);new ObjectDefinitionDecoder(c).run();RegionFactory.load(c);
  route(2638,3321,0,2634,3323,0,1,127,"mansion block through room door to combination lock");
  route(2633,3323,0,2631,3322,0,2,127,"inner lock to stairs");
  route(2633,3321,1,2638,3324,1,1,127,"upper landing to chest");
  route(2638,3323,1,2631,3322,1,2,127,"chest back to stairs");
  route(2635,9720,0,2632,9694,0,1,127,"trap landing to sewer exit");
  route(2651,3272,0,2650,3273,0,1,127,"RPDT block to label");
  route(2651,3272,0,2650,3271,0,1,127,"RPDT block to marked crate");
  route(2651,3272,0,2649,3274,0,1,127,"RPDT block to employee");
  route(2649,3274,0,2681,3325,0,1,127,"RPDT employee back to wizard");
  route(2633,3294,0,2681,3325,0,1,127,"sewer exit back to wizard");
  route(2628,3311,0,2681,3325,0,1,127,"gardener to wizard");
  for(int[]a:new int[][]{{846,2790,3182,1},{845,2628,3311,1},{843,2649,3274,1},{844,2681,3325,1}})safe(a[0],a[1],a[2],a[3]);
  System.out.println("PASS "+checks+" Tribal Totem traversals and NPC footprints");
 }
}