Advertisement
Guest User

Untitled

a guest
Jan 31st, 2018
156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.56 KB | None | 0 0
  1. package com.TheRPGAdventurer.ROTD.client.userinput;
  2.  
  3. /**
  4. * The purpose of this class is to intercept key presses (especially left and right mouse button clicks) and allow
  5. * greater flexibility in responding to them.
  6. * The class replaces KeyBindings in GameSettings. When interception is on:
  7. * .isPressed() is overridden to return false so that the vanilla code never receives the clicks.
  8. * .pressed is always false.
  9. * The true .isPressed() and .pressed are available using .retrieveClick() and .isKeyDown()
  10. * Usage:
  11. * (1) replace KeyBinding with a newly generated interceptor
  12. * eg
  13. * KeyBindingInterceptor attackButtonInterceptor(GameSettings.keyBindAttack);
  14. * GameSettings.keyBindAttack = attackButtonInterceptor;
  15. * This creates an interceptor linked to the existing keyBindAttack. The original keyBindAttack remains in the
  16. * KeyBinding hashmap and keyBindArray.
  17. * (2) Set the interception mode (eg true = on)
  18. * eg setInterceptionActive(false);
  19. * (3) read the underlying clicks using .retrieveClick() or .isUnderlyingKeyDown();
  20. * (4) when Interceptor is no longer required, call .getOriginalKeyBinding();
  21. * eg GameSettings.keyBindAttack = attackButtonInterceptor.getOriginalKeyBinding();
  22. *
  23. * NOTES -
  24. * (a) the interceptor does not update the .pressed field until .isPressed() is called. The vanilla Minecraft.runTick
  25. * currently always accesses .isPressed() before attempting to read .pressed.
  26. * (b) In the current vanilla code, if the bindings are changed it will affect the original keybinding. The new binding will
  27. * be copied to the interceptor at the first call to .retrieveClick(), .isKeyDown(), or .isPressed().
  28. * (c) Will not work in GUI
  29. */
  30.  
  31. import com.google.common.base.Throwables;
  32. import com.google.common.collect.Maps;
  33.  
  34. import net.minecraft.client.settings.KeyBinding;
  35. import net.minecraftforge.fml.relauncher.ReflectionHelper;
  36. import net.minecraftforge.fml.relauncher.Side;
  37. import net.minecraftforge.fml.relauncher.SideOnly;
  38.  
  39. import java.lang.reflect.Field;
  40. import java.util.List;
  41. import java.util.Map;
  42.  
  43. @SideOnly(Side.CLIENT)
  44. public class KeyBindingInterceptor extends KeyBinding {
  45. private static final Field keybindArrayField = ReflectionHelper.findField(KeyBinding.class, "keybindArray", "field_74516_a");
  46. private static final Field keyCodeField = ReflectionHelper.findField(KeyBinding.class, "keyCode", "field_74512_d");
  47. private static final Field pressedField = ReflectionHelper.findField(KeyBinding.class, "pressed", "field_74513_e");
  48. private static final Field pressTimeField = ReflectionHelper.findField(KeyBinding.class, "pressTime", "field_151474_i");
  49.  
  50. /**
  51. * Create an Interceptor based on an existing binding.
  52. * The initial interception mode is OFF.
  53. * If existingKeyBinding is already a KeyBindingInterceptor, a reinitialised copy will be created but no further effect.
  54. * @param existingKeyBinding - the binding that will be intercepted.
  55. */
  56. public KeyBindingInterceptor(KeyBinding existingKeyBinding)
  57. {
  58. super(existingKeyBinding.getKeyDescription(), existingKeyBinding.getKeyCode(), existingKeyBinding.getKeyCategory());
  59. try {
  60. // the base constructor automatically adds the class to the keybindArray and hash, which we don't want, so undo it
  61. List reflectkeybindArray = (List) keybindArrayField.get(this);
  62. reflectkeybindArray.remove(this);
  63.  
  64. pressedField.setBoolean(this, false);
  65. pressTimeField.setInt(this, 0);
  66. // this.pressed = false;
  67. // this.pressTime = 0;
  68.  
  69. } catch (Exception e) {
  70. throw Throwables.propagate(e);
  71. }
  72. this.interceptionActive = false;
  73. this.interceptedPressTime = 0;
  74.  
  75. if (existingKeyBinding instanceof KeyBindingInterceptor) {
  76. interceptedKeyBinding = ((KeyBindingInterceptor)existingKeyBinding).getOriginalKeyBinding();
  77. } else {
  78. interceptedKeyBinding = existingKeyBinding;
  79. }
  80.  
  81. KeyBinding.resetKeyBindingArrayAndHash();
  82. }
  83.  
  84. public void setInterceptionActive(boolean newMode)
  85. {
  86. if (newMode && !interceptionActive) {
  87. this.interceptedPressTime = 0;
  88. }
  89. interceptionActive = newMode;
  90. }
  91.  
  92. @Override
  93. public boolean isKeyDown()
  94. {
  95. if (interceptionActive) {
  96. return false;
  97. } else {
  98. return super.isKeyDown();
  99. }
  100. }
  101.  
  102. public boolean isUnderlyingKeyDown()
  103. {
  104. copyKeyCodeToOriginal();
  105. // return interceptedKeyBinding.pressed;
  106. try {
  107. return pressedField.getBoolean(interceptedKeyBinding);
  108. } catch (Exception e) {
  109. Throwables.propagate(e);
  110. return false;
  111. }
  112. }
  113.  
  114. /**
  115. *
  116. * @return returns false if interception isn't active. Otherwise, retrieves one of the clicks (true) or false if no clicks left
  117. */
  118. public boolean retrieveClick()
  119. {
  120. copyKeyCodeToOriginal();
  121. if (interceptionActive) {
  122. copyClickInfoFromOriginal();
  123.  
  124. if (this.interceptedPressTime == 0) {
  125. return false;
  126. } else {
  127. --this.interceptedPressTime;
  128. return true;
  129. }
  130. } else {
  131. return false;
  132. }
  133. }
  134.  
  135. /** A better name for this method would be retrieveClick.
  136. * If interception is on, resets .pressed and .pressTime to zero.
  137. * Otherwise, copies these from the intercepted KeyBinding.
  138. * @return If interception is on, this will return false; Otherwise, it will pass on any clicks in the intercepted KeyBinding
  139. */
  140. @Override
  141. public boolean isPressed()
  142. {
  143. copyKeyCodeToOriginal();
  144. copyClickInfoFromOriginal();
  145.  
  146. try {
  147.  
  148. if (interceptionActive) {
  149. pressTimeField.setInt(this, 0);
  150. pressedField.setBoolean(this, false);
  151. // this.pressTime = 0;
  152. // this.pressed = false;
  153. return false;
  154. } else {
  155. // if (this.pressTime == 0) {
  156. if (pressTimeField.getInt(this) == 0) {
  157. return false;
  158. } else {
  159. pressTimeField.setInt(this, pressTimeField.getInt(this) - 1);
  160. // --this.pressTime;
  161. return true;
  162. }
  163. }
  164. } catch (Exception e) {
  165. Throwables.propagate(e);
  166. return false;
  167. }
  168. }
  169.  
  170. public KeyBinding getOriginalKeyBinding() {
  171. return interceptedKeyBinding;
  172. }
  173.  
  174. protected KeyBinding interceptedKeyBinding;
  175. private boolean interceptionActive;
  176.  
  177. private int interceptedPressTime;
  178.  
  179. protected void copyClickInfoFromOriginal()
  180. {
  181. try {
  182. // this.pressTime += interceptedKeyBinding.pressTime;
  183. // this.interceptedPressTime += interceptedKeyBinding.pressTime;
  184. // interceptedKeyBinding.pressTime = 0;
  185. // this.pressed = interceptedKeyBinding.pressed;
  186. int value = pressTimeField.getInt(this);
  187. value += pressTimeField.getInt(interceptedKeyBinding);
  188. pressTimeField.setInt(this, value);
  189. this.interceptedPressTime += pressTimeField.getInt(interceptedKeyBinding);
  190. pressTimeField.setInt(interceptedKeyBinding, 0);
  191. pressedField.setBoolean(this, pressedField.getBoolean(interceptedKeyBinding));
  192. } catch (Exception e) {
  193. Throwables.propagate(e);
  194. }
  195. }
  196.  
  197. protected void copyKeyCodeToOriginal()
  198. {
  199. try {
  200. // only copy if necessary
  201. // if (this.keyCode != interceptedKeyBinding.keyCode) {
  202. // this.keyCode = interceptedKeyBinding.keyCode;
  203. if (keyCodeField.getInt(this) != keyCodeField.getInt(interceptedKeyBinding)) {
  204. keyCodeField.setInt(this, keyCodeField.getInt(interceptedKeyBinding));
  205. resetKeyBindingArrayAndHash();
  206. }
  207. } catch (Exception e) {
  208. Throwables.propagate(e);
  209. }
  210. }
  211.  
  212. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement