/* * Save a slope */ static void vinfo_init_aux(vinfo_hack hack, int y, int x, long m) { int i; /* Handle "legal" slopes */ if ((m > 0) && (m <= SCALE)) { /* Look for that slope */ for (i = 0; i < hack.num_slopes; i++) { if (hack.slopes[i] == m) break; } /* New slope */ if (i == hack.num_slopes) { /* Paranoia */ if (hack.num_slopes >= VINFO_MAX_SLOPES) { Utilities.quit("Too many slopes (" + VINFO_MAX_SLOPES +")!"); } /* Save the slope, and advance */ hack.slopes[hack.num_slopes++] = m; } } /* Track slope range */ if (hack.slopes_min[y,x] > m) hack.slopes_min[y,x] = m; if (hack.slopes_max[y,x] < m) hack.slopes_max[y,x] = m; }
/* * Initialize the "vinfo" array * * Full Octagon (radius 20), Grids=1149 * * Quadrant (south east), Grids=308, Slopes=251 * * Octant (east then south), Grids=161, Slopes=126 * * This function assumes that VINFO_MAX_GRIDS and VINFO_MAX_SLOPES * have the correct values, which can be derived by setting them to * a number which is too high, running this function, and using the * error messages to obtain the correct values. */ public static int vinfo_init() { int i, g; long m; int num_grids = 0; int queue_head = 0; int queue_tail = 0; vinfo_type[] queue = new vinfo_type[VINFO_MAX_GRIDS*2]; //Nick: initialize v_info here, fill it with new stuffs to play with instead of nulls for (int n = 0; n < vinfo.Count(); n++){ vinfo[n] = new vinfo_type(); } /* Make hack */ vinfo_hack hack = new vinfo_hack(); /* Analyze grids */ for (int y = 0; y <= Misc.MAX_SIGHT; ++y) { //Triangular array? Weird... Triangle is on top right corner for (int x = y; x <= Misc.MAX_SIGHT; ++x) { /* Skip grids which are out of sight range */ if (distance(0, 0, y, x) > Misc.MAX_SIGHT) continue; /* Default slope range */ hack.slopes_min[y,x] = 999999999; hack.slopes_max[y,x] = 0; /* Paranoia */ if (num_grids >= VINFO_MAX_GRIDS) { Utilities.quit("Too many grids (" + num_grids + " >= " + VINFO_MAX_GRIDS + ")!"); } /* Count grids */ num_grids++; /* Slope to the top right corner */ m = SCALE * (1000L * y - 500) / (1000L * x + 500); /* Handle "legal" slopes */ vinfo_init_aux(hack, y, x, m); /* Slope to top left corner */ m = SCALE * (1000L * y - 500) / (1000L * x - 500); /* Handle "legal" slopes */ vinfo_init_aux(hack, y, x, m); /* Slope to bottom right corner */ m = SCALE * (1000L * y + 500) / (1000L * x + 500); /* Handle "legal" slopes */ vinfo_init_aux(hack, y, x, m); /* Slope to bottom left corner */ m = SCALE * (1000L * y + 500) / (1000L * x - 500); /* Handle "legal" slopes */ vinfo_init_aux(hack, y, x, m); } } /* Enforce maximal efficiency */ if (num_grids < VINFO_MAX_GRIDS) { Utilities.quit("Too few grids (" + num_grids + " < " + VINFO_MAX_GRIDS + ")!"); } /* Enforce maximal efficiency */ if (hack.num_slopes < VINFO_MAX_SLOPES) { Utilities.quit("Too few slopes (" + hack.num_slopes + " < " + VINFO_MAX_SLOPES + ")!"); } Utilities.sort(hack.slopes, cmp_longs); /* Enqueue player grid */ queue[queue_tail++] = vinfo[0]; /* Process queue */ while (queue_head < queue_tail) { int e; /* Index */ e = queue_head++; /* Main Grid */ g = vinfo[e].grid[0]; /* Location */ int y = GRID_Y(g); int x = GRID_X(g); /* Compute grid offsets */ vinfo[e].grid[0] = (short)GRID(+y,+x); vinfo[e].grid[1] = (short)GRID(+x,+y); vinfo[e].grid[2] = (short)GRID(+x,-y); vinfo[e].grid[3] = (short)GRID(+y,-x); vinfo[e].grid[4] = (short)GRID(-y,-x); vinfo[e].grid[5] = (short)GRID(-x,-y); vinfo[e].grid[6] = (short)GRID(-x,+y); vinfo[e].grid[7] = (short)GRID(-y,+x); /* Analyze slopes */ for (i = 0; i < hack.num_slopes; ++i) { m = hack.slopes[i]; /* Memorize intersection slopes (for non-player-grids) */ if ((e > 0) && (hack.slopes_min[y,x] < m) && (m < hack.slopes_max[y,x])) { switch (i / 32) { case 3: vinfo[e].bits_3 |= (uint)(1L << (i % 32)); break; case 2: vinfo[e].bits_2 |= (uint)(1L << (i % 32)); break; case 1: vinfo[e].bits_1 |= (uint)(1L << (i % 32)); break; case 0: vinfo[e].bits_0 |= (uint)(1L << (i % 32)); break; } } } /* Default */ vinfo[e].next_0 = vinfo[0]; /* Grid next child */ if (distance(0, 0, y, x+1) <= Misc.MAX_SIGHT) { g = GRID(y,x+1); if (queue[queue_tail-1].grid[0] != g) { vinfo[queue_tail].grid[0] = (short)g; queue[queue_tail] = vinfo[queue_tail]; queue_tail++; } vinfo[e].next_0 = vinfo[queue_tail - 1]; } /* Default */ vinfo[e].next_1 = vinfo[0]; /* Grid diag child */ if (distance(0, 0, y+1, x+1) <= Misc.MAX_SIGHT) { g = GRID(y+1,x+1); if (queue[queue_tail-1].grid[0] != g) { vinfo[queue_tail].grid[0] = (short)g; queue[queue_tail] = vinfo[queue_tail]; queue_tail++; } vinfo[e].next_1 = vinfo[queue_tail - 1]; } /* Hack -- main diagonal has special children */ if (y == x) vinfo[e].next_0 = vinfo[e].next_1; /* Extra values */ vinfo[e].y = (byte)y; vinfo[e].x = (byte)x; vinfo[e].d = (byte)((y > x) ? (y + x/2) : (x + y/2)); vinfo[e].r = (byte)((y==0) ? x : (x==0) ? y : (y == x) ? y : 0); } /* Verify maximal bits XXX XXX XXX */ if (((vinfo[1].bits_3 | vinfo[2].bits_3) != VINFO_BITS_3) || ((vinfo[1].bits_2 | vinfo[2].bits_2) != VINFO_BITS_2) || ((vinfo[1].bits_1 | vinfo[2].bits_1) != VINFO_BITS_1) || ((vinfo[1].bits_0 | vinfo[2].bits_0) != VINFO_BITS_0)) { Utilities.quit("Incorrect bit masks!"); } /* Kill hack */ //FREE(hack); //lolc /* Success */ return (0); }