001 /** 002 * HitBlox.java - Class for getting blocks along line of sight 003 * 004 * NOTES: This class is designed to handle the annoying parts of the seemingly 005 * simple task of getting the coordinates of the block a player is currently 006 * aimed at. This class abstracts the simpler tasks of finding the current 007 * target block and the adjacent unoccupied block to their own methods, but it 008 * also provides a public getNextBlock method for processing the entire 009 * line-of-sight from the player for more specialized tasks. This method can be 010 * used exactly as it is in getTargetBlock, for instance. 011 * 012 * WARNING: Servers with map coordinate bugs may experience a one or more block 013 * inaccuracy when in affected parts of the world. A good way to test areas for 014 * the offset bug is to use Chrisinajar's Magic Carpet plugin. 015 * 016 * Contact: For questions, contact Ho0ber@gmail.com or channel #hey0 on 017 * irc.esper.net 018 * 019 * @author Ho0ber 020 */ 021 public class HitBlox { 022 023 private Location player_loc; 024 private double rot_x, rot_y, view_height; 025 private double length, h_length, step; 026 private int range; 027 private double x_offset, y_offset, z_offset; 028 private int last_x, last_y, last_z; 029 private int target_x, target_y, target_z, target_type; 030 031 /** 032 * Constructor requiring player, uses default values 033 * 034 * @param in_player 035 */ 036 public HitBlox(Player in_player) { 037 init(in_player.getLocation(), 200, 0.2, 1.65); // Reasonable default 038 // values 039 } 040 041 /** 042 * Constructor requiring location, uses default values 043 * 044 * @param in_location 045 */ 046 public HitBlox(Location in_location) { 047 init(in_location, 200, 0.2, 0); 048 } 049 050 /** 051 * Constructor requiring player, max range, and a stepping value 052 * 053 * @param in_player 054 * @param in_range 055 * @param in_step 056 */ 057 public HitBlox(Player in_player, int in_range, double in_step) { 058 init(in_player.getLocation(), in_range, in_step, 1.65); 059 } 060 061 /** 062 * Constructor requiring location, max range, and a stepping value 063 * 064 * @param in_location 065 * @param in_range 066 * @param in_step 067 */ 068 public HitBlox(Location in_location, int in_range, double in_step) { 069 init(in_location, in_range, in_step, 0); 070 } 071 072 /** 073 * Initialization method 074 * 075 * @param in_location 076 * @param in_range 077 * @param in_step 078 * @param in_view_height 079 */ 080 public void init(Location in_location, int in_range, double in_step, double in_view_height) { 081 player_loc = in_location; 082 view_height = in_view_height; 083 range = in_range; 084 step = in_step; 085 length = 0; 086 rot_x = (player_loc.rotX + 90) % 360; 087 rot_y = player_loc.rotY * -1; 088 089 target_x = (int) Math.floor(player_loc.x); 090 target_y = (int) Math.floor(player_loc.y + view_height); 091 target_z = (int) Math.floor(player_loc.z); 092 last_x = target_x; 093 last_y = target_y; 094 last_z = target_z; 095 } 096 097 /** 098 * Returns the block at the cursor, or null if out of range 099 * 100 * @return Block 101 */ 102 public Block getTargetBlock() { 103 while ((getNextBlock() != null) && (getCurBlock().getType() == 0)); 104 return getCurBlock(); 105 } 106 107 /** 108 * Sets the type of the block at the cursor 109 * 110 * @param type 111 */ 112 public void setTargetBlock(int type) { 113 while ((getNextBlock() != null) && (getCurBlock().getType() == 0)); 114 if (getCurBlock() != null) { 115 etc.getServer().setBlockAt(type, target_x, target_y, target_z); 116 } 117 } 118 119 /** 120 * Returns the block attached to the face at the cursor, or null if out of 121 * range 122 * 123 * @return Block 124 */ 125 public Block getFaceBlock() { 126 while ((getNextBlock() != null) && (getCurBlock().getType() == 0)); 127 if (getCurBlock() != null) { 128 return getLastBlock(); 129 } else { 130 return null; 131 } 132 } 133 134 /** 135 * Sets the type of the block attached to the face at the cursor 136 * 137 * @param type 138 */ 139 public void setFaceBlock(int type) { 140 while ((getNextBlock() != null) && (getCurBlock().getType() == 0)); 141 if (getCurBlock() != null) { 142 etc.getServer().setBlockAt(type, last_x, last_y, last_z); 143 } 144 } 145 146 /** 147 * Returns STEPS forward along line of vision and returns block 148 * 149 * @return Block 150 */ 151 public Block getNextBlock() { 152 last_x = target_x; 153 last_y = target_y; 154 last_z = target_z; 155 156 do { 157 length += step; 158 159 h_length = (length * Math.cos(Math.toRadians(rot_y))); 160 y_offset = (length * Math.sin(Math.toRadians(rot_y))); 161 x_offset = (h_length * Math.cos(Math.toRadians(rot_x))); 162 z_offset = (h_length * Math.sin(Math.toRadians(rot_x))); 163 164 target_x = (int) Math.floor(x_offset + player_loc.x); 165 target_y = (int) Math.floor(y_offset + player_loc.y + view_height); 166 target_z = (int) Math.floor(z_offset + player_loc.z); 167 168 } while ((length <= range) && ((target_x == last_x) && (target_y == last_y) && (target_z == last_z))); 169 170 if (length > range) { 171 return null; 172 } 173 174 return etc.getServer().getBlockAt(target_x, target_y, target_z); 175 } 176 177 /** 178 * Returns the current block along the line of vision 179 * 180 * @return Block 181 */ 182 public Block getCurBlock() { 183 if (length > range) { 184 return null; 185 } else { 186 return etc.getServer().getBlockAt(target_x, target_y, target_z); 187 } 188 } 189 190 /** 191 * Sets current block type id 192 * 193 * @param type 194 */ 195 public void setCurBlock(int type) { 196 if (getCurBlock() != null) { 197 etc.getServer().setBlockAt(type, target_x, target_y, target_z); 198 } 199 } 200 201 /** 202 * Returns the previous block along the line of vision 203 * 204 * @return Block 205 */ 206 public Block getLastBlock() { 207 return etc.getServer().getBlockAt(last_x, last_y, last_z); 208 } 209 210 /** 211 * Sets previous block type id 212 * 213 * @param type 214 */ 215 public void setLastBlock(int type) { 216 if (getLastBlock() != null) { 217 etc.getServer().setBlockAt(type, last_x, last_y, last_z); 218 } 219 } 220 }