Advertisement
hhjfdgdfgdfg

ct

Apr 8th, 2024
19
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 38.76 KB | None | 0 0
  1.  
  2. Search
  3. Introduction
  4. Setup
  5. Creating a module
  6. The Basics
  7. ChatLib
  8. Rendering
  9. Tessellator
  10. Objects
  11. Books
  12. CPS
  13. Displays
  14. Guis
  15. Inventory
  16. Example
  17. KeyBinds
  18. Player
  19. ChatTriggers Website
  20. ChatTriggers Discord
  21. Documentation Powered by Slate
  22. Introduction
  23. ChatTriggers is a framework for Minecraft Forge that allows for mods to be scripted, in languages such as JavaScript. Scripts are able to be hot reloaded, which means you can make changes to your mod without restarting!
  24.  
  25. Currently, only JavaScript is supported.
  26. JavaScript scripts are executed with our custom fork of Mozilla's Rhino library. Our custom fork supports many ES6 and ESNEXT features. For the (almost) full feature list,check our compatibility table;
  27.  
  28. Some of this documentation may be out of date or incomplete.
  29. Setup
  30. To set up ChatTriggers, all you have to do is put the ChatTriggers jar into your mods folder, and launch Minecraft. By default, ChatTriggers modules are stored in .minecraft/config/ChatTriggers/modules/, but this can be changed in the configuration. To access the ChatTriggers settings, type /ct settings in game. The rest of this tutorial will refer to this directory as the "modules directory", and will assume it is in the default location.
  31.  
  32. Creating a module
  33. To create a module, create a folder in your modules folder. The folder can have whatever name you want, but typically it is just the name of the module. Our module will be called ExampleModule. Our folder structure now looks like .minecraft/config/ChatTriggers/modules/ExampleModule.
  34.  
  35. The metadata file
  36. An example metadata.json file
  37.  
  38. {
  39. "name": "ExampleModule",
  40. "creator": "YourNameHere",
  41. "description": "Our first module!",
  42. "version": "1.0.0",
  43. "entry": "index.js"
  44. }
  45. All modules MUST have a metadata.json file. This file contains important information about our module. You can see an example of this file to the right. The metadata file contains a number of important fields, documented here:
  46.  
  47. name: The name of the module
  48. creator: The name of the module creator
  49. version: The version of the module. This should conform to SEMVER and should be the same as the version selected when uploading if you wish to upload it to the website.
  50. entry: This is the name of a file that should actually be ran. This key is necessary if, for example, your module registers triggers or commands. This field is REQUIRED for all modules that wish to run code, without it your module will NOT run. If all your module provides is a library that other modules can use, this is not needed.
  51. requires: An array of names of other modules that your module depends on. These modules are guaranteed to be loaded before your module, allowing you to use them directly.
  52. asmEntry and asmExposedFunctions: The ChatTriggers wiki goes into detail about ASM here
  53. Scripting
  54. We now need to create our script files. Typically, the root file of your module is named index.js. This is a general web development practice. You can name your files whatever your want, however one benefit of having an index.js file is that if someone tries to import from your module folder directly, instead of a specific file in your module, it will be imported from the index.js file, if one exists. If no index.js file exists, other people will have to import directly from the files themselves.
  55.  
  56. The Basics
  57. Registering a Trigger
  58. We register a WorldLoad trigger like so:
  59.  
  60. The argument passed into the register function is the function you want to trigger:
  61.  
  62. function exampleWorldLoad() {
  63.  
  64. }
  65.  
  66. register("worldLoad", exampleWorldLoad);
  67. You can also register an anonymous function for simplicity:
  68.  
  69. register("worldLoad", () => {
  70.  
  71. });
  72. In ChatTriggers, "triggers" are events that get fired when a certain action happens in game, like a sound being played or a chat message being sent. Let's start with one of the simplest triggers: WorldLoad. In order to register a trigger, we use the provided register function. It takes the trigger name as the first argument (case-insensitive), and the function to run as the second argument. You can see a complete list of these triggers on our javadocs, under IRegister.
  73.  
  74. To convert an IRegister name to a trigger name, just remove the "register" from the beginning of the method name.
  75. Now any code inside of our exampleWorldLoad trigger will be ran whenever a world is loaded. From here, you can do many things, such as interacting with Minecraft methods or getting information from arguments that certain triggers may pass in.
  76.  
  77. You can register as many triggers as you want, and you can even use the same function in multiple different triggers.
  78. The "Chat" Trigger
  79. A basic chat trigger
  80.  
  81. register("chat", (player, message, event) => {
  82. ChatLib.chat(player + ": " + message);
  83. }).setCriteria("<${player}> ${message}");
  84. This is how you can set a chat trigger. Chat triggers trigger when a chat message matches the specific criteria that is set. In this case, the trigger will fire whenever a chat message matches a chat message <${player}> ${message}. You can reference variables by adding ${ } around the variable name. All variables must be accounted for in the function parameters, following the order they appear in. Also keep in mind that the event that is fired is always the last parameter.
  85.  
  86. You may notice that the original message is still being sent, which looks really ugly. To fix this, we can cancel the event.
  87.  
  88. register("chat", (player, message, event) => {
  89. cancel(event);
  90. ChatLib.chat(player + ": " + message);
  91. }).setCriteria("<${player}> ${message}");
  92. Setting criteria as it is in the example to the right will try to match the exact message. In order to allow a message to just contain the criteria, you can add .setContains() after setCriteria. An example of this is to the right. With this, hi Player! how are you?, etc. will also trigger. These are just simple examples, but the idea still is there. The message just has to contain the criteria you set when you add .setContains(). There are also setStart and setEnd modifiers you can use instead.
  93.  
  94. Also, if the criteria you set contains color codes (starting with Β§ or &), the message will try to match the exact color throughout the message.
  95.  
  96. This will be triggered if a player says hi User! anywhere inside their message
  97.  
  98. register("chat", (player, event) => {
  99. ChatLib.chat("howdy " + player);
  100. }).setCriteria("hi ${player}!").setContains();
  101. When trying to pick up certain messages that aren't sent by other players, try not to use setContains as a player could type the message that's being matched and trigger your code.
  102.  
  103. MessageSent Trigger
  104. Display "Pong!" in response to YOUR message sent containing "ping"
  105.  
  106. register("messageSent", (message, event) => {
  107. if (message.toLowerCase().includes("ping")) {
  108. ChatLib.chat("Pong!");
  109. }
  110. });
  111. In addition to letting you know when an event has occurred by calling your function, many triggers pass through additional information about their respective event. Let's take a look at a different trigger: MessageSent. This trigger is fired whenever the client (you) sends a message.
  112.  
  113. Let's make a trigger that, whenever you sent a message with the word "ping", displays the message "Pong!". In order to do this, we need to accept the arguments passed in by the MessageSent trigger. You can see all the arguments that a trigger passes through in the javadocs linked above. The MessageSent trigger passes in the message event and the actual message.
  114.  
  115. Many triggers are cancellable, meaning that they actually fire before the event in question happens. In our case, our MessageSent trigger will fire before the chat message is actually sent. Cancelling the event is as easy as calling cancel(event), however we won't do that here.
  116.  
  117. We are interested in the message parameter. We simply check if it contains the word we are interested in, and if so, we use the ChatLib utility to send a message only visible to the player. You can read more about the ChatLib utility here
  118.  
  119. Command Trigger
  120. Another one of the most common triggers is the Command trigger. This allows the user to make custom commands of their choosing.
  121.  
  122. register("command", (user) => {
  123. ChatLib.chat("Hi " + user);
  124. }).setName("mycommand");
  125. Commands are one of the few triggers that do not have event as a parameter. This example creates a command which can be called through /mycommand. The arguments of the function are the arguments the user types into the command. If the user types /mycommand kerbybit, then the function will be triggered, and Hi kerbybit will be printed into chat.
  126.  
  127. Forge has a bug which will make commands with capital letters as the base to not fire. Set the full command name lowercase to avoid the issue.
  128. We can also set command aliases using the setAliases function. It accepts any amount of arguments. Let's say we want /mc and /myc to also be valid commands that will trigger our code. We would just add it anto the trigger, in no specific order.
  129.  
  130. register("command", (user) => {
  131. ChatLib.chat("Hi " + user);
  132. }).setName("mycommand").setAliases("mc", "myc");
  133. Module Organization
  134. ES6 style import syntax (preferred)
  135.  
  136. import playerLocation from "WhereAmi";
  137. This imports a function from WhereAmI's index file. You could specify additional files i.e. WhereAmI/otherfile You can also import from other files within the current module using local file paths such as ./folder/file (where folder resides within WhereAmI).
  138.  
  139. This imports a function from another module, called WhereAmI, to get a players location.
  140.  
  141. When making a module, it is important to know how ChatTriggers loads your files so you can organize them efficiently. When your module is loaded, only the file specified as the entry in metadata.json is loaded. Any other code you want to run must be imported, through the ES6 style import syntax.
  142.  
  143. In order to use variables and functions defined in other modules, you must list those module names in your module's requires array in the metadata.json file, and then import them as needed
  144. ChatLib
  145. The ChatLib is a utility provided to imports for interacting with Minecraft chat. It has functionality to send, edit, and delete messages in Minecraft's chat. You can create clickable, and hoverable, text in chat, run commands, and much more.
  146.  
  147. Sending messages
  148. This sends a client-side message in chat
  149.  
  150. ChatLib.chat("Coming from the code!");
  151. This first example shows how to display a basic chat message. This message differs from normal messages in that it does NOT trigger chat triggers. It is also not visible to other players.
  152.  
  153. Message objects
  154. This example sends messages that have clickable and hoverable text
  155.  
  156. const clickableMessage = new Message(
  157. "This is not clickable. ",
  158. new TextComponent("This is clickable").setClick("run_command", "/help"),
  159. "!"
  160. );
  161.  
  162. const hoverableMessage = new TextComponent("This message does nothing when clicked.").setHoverValue("But it shows this text when hovered over!");
  163.  
  164. ChatLib.chat(clickableMessage);
  165. ChatLib.chat(hoverableMessage);
  166. Here we are creating new Message objects. These are required to send messages that have clickable or hoverable text. The constructor of a Message can take as many Strings or TextComponents as you want, simply separate them with commas as shown in the first example.
  167.  
  168. TextComponents are nice little wrappers that allow you to customize a small chunk of a message. You can change what happens when you click or hover on the message. You can also directly send a TextComponent as seen with the hoverable message. All of these can use formatting codes with the & symbol.
  169.  
  170. Clickables
  171. The first message we create is a message that has clickable, and non-clickable, text. The first part is regular text, followed by a clickable part that runs the /help command when clicked, and shows the hoverText when the mouse is hovering over that part of the message. Then, at the end, it has a non-clickable exclamation point.
  172.  
  173. Hovers
  174. The second message created and chatted is a message that only contains a hoverable message. Nothing will be activated or ran when the message is clicked.
  175.  
  176. You can also use Message#setRecursive(boolean) to make Messages non-recursive.
  177. Message IDs
  178. This is how you send a chat message with an ID, and then delete it
  179.  
  180. new Message("This will be deleted!").setChatLineId(5050).chat();
  181.  
  182. ChatLib.clearChat(5050);
  183. Every message can have an ID specified, which can then be deleted from chat. This is best suited for auto-replacing menus, chat messages you only want to display in chat for a certain amount of time, etc.
  184.  
  185. This example also showcases an alternative method of chatting a Message, as there is a simple helper method, Message#chat()
  186.  
  187. Only one chat message can have the same ID, as it will replace any messages with the same ID before sending. The ID is specified in the message object, and you pass the same ID to ChatLib.clearChat(id) to delete it.
  188.  
  189. Doing ChatLib.clearChat() will delete all messages in chat, no matter the ID
  190. Editing chat
  191. This is how you edit a chat message after it has been sent to chat
  192.  
  193. ChatLib.chat("Hey there! This will change...");
  194.  
  195. ChatLib.editChat("Hey there! This will change...", "And... changed!")
  196. ChatLib.editChat(message, replacer) is a simple method that takes in an unformatted message and replaces all instances of it with the replacer. This is a slightly laggy operation if done extremely rapidly (i.e. around 60 times per second). The editChat method can also take the Message ID as the first argument.
  197.  
  198. Specially formatted messages
  199. This is how you center a chat message
  200.  
  201. ChatLib.chat(ChatLib.getCenteredText("This is in the center of the chat!"));
  202. This is how you make a line break
  203.  
  204. ChatLib.chat(ChatLib.getChatBreak("-"));
  205. Centered messages
  206. To center a message in chat (padded by spaces), use the ChatLib.getCenteredText(text) method, and then chat what's returned.
  207.  
  208. This is a marginally intensive operation, so if you can store this in a variable and re-use it, that's preferable.
  209. Line breaks
  210. To create a line break in chat that will be the exact length of the chat box no matter the user's width and size settings, use the ChatLib.getChatBreak(seperator) method. This can take any seperator, like "-" as we used in the example.
  211.  
  212. Any length string can be used as the seperator, such as "seperate". However, because this is a long string, there will be a gap at the end where another use of the string will not fit
  213. Chat message from event
  214. This is how you get the unformatted message from a chat event
  215.  
  216. function onChatReceived(event) {
  217. const unformattedMessage = ChatLib.getChatMessage(event);
  218. }
  219. This is how you get the formatted message from a chat event
  220.  
  221. function onChatReceived(event) {
  222. const formattedMessage = ChatLib.getChatMessage(event, true);
  223. }
  224. Unformatted chat
  225. To get the unformatted chat from a chat event passed into a function by a Chat Trigger, pass it to the ChatLib.getChatMessage(event) method, which returns an unformatted string.
  226.  
  227. Formatted chat
  228. However, if you want the formatted version of the chat message, append the true flag to the ChatLib.getChatMessage(event, formatted) method.
  229.  
  230. Rendering
  231. Rendering is where modules can draw most anything on to the game screen. All 2D rendering involves calling methods in the Renderer object. 3D rendering involves calling methods in the Tessellator object.
  232.  
  233. If you want to create much more customizable rendering options, the Elementa module is highly encouraged.
  234. All 2D rendering coordinates start at the top left of the screen. X increases from left to right, and Y increases from top to bottom.
  235. Setting up
  236. Function to be ran everytime the game overlay is rendered
  237.  
  238. register("renderOverlay", myRenderOverlay);
  239.  
  240. function myRenderOverlay() {
  241.  
  242. }
  243. Rendering has to be done every frame of the game, otherwise it will only be on the screen for one frame. There are many different render triggers, and they all start with Render. The most common render trigger is RenderOverlay: this trigger fires every frame with no conditions.
  244.  
  245. Setting priority
  246. It is possible to set a certain trigger's priority like so
  247.  
  248. register("renderOverlay", myRenderOverlayLast).setPriority(Priority.LOWEST);
  249. register("renderOverlay", myRenderOverlayFirst).setPriority(Priority.HIGHEST);
  250.  
  251. function myRenderOverlayLast() {
  252.  
  253. }
  254.  
  255. function myRenderOverlayFirst() {
  256.  
  257. }
  258. Here, were are dealing with the priority of triggers. Priorities are LOWEST, LOW, NORMAL, HIGH, HIGHEST. Triggers with a priority of HIGHEST are ran first, because they have first say on an event. Triggers with a priority of LOWEST are ran last. The function lan rast will draw on TOP of anything before it.
  259.  
  260. All trigger types can have a priority set, it's just most commonly used in rendering
  261. Simple text rendering
  262. You can render text onto the screen with this code
  263.  
  264. register("renderOverlay", myRenderOverlay);
  265.  
  266. function myRenderOverlay() {
  267. Renderer.drawString("Hello World!", 10, 10);
  268. }
  269. Every frame, the code inside myRenderOverlay is called. Inside of this function, we make one call to Renderer.drawString(text, screenX, screenY). We make the text say "Hello World!", and place it on the screen at 10, 10 (the top left corner).
  270.  
  271. If all you are rendering is text, it is preferable to use `Display` objects, covered later.
  272. More complex text rendering
  273. This is how you would draw the same string (but colored) with an object
  274.  
  275. register("renderOverlay", myRenderOverlay);
  276.  
  277. const myTextObject = new Text("Hello World!", 10, 10).setColor(Renderer.RED);
  278.  
  279. function myRenderOverlay() {
  280. myTextObject.draw();
  281. }
  282. Here, instead of simply making a method call, we are instatiating an object to do our drawing. This allows for much greater customization, such as rotation, scaling, and as described below, coloring.
  283.  
  284. The other interesting part to take a look at is the call to setColor, which will, as you can guess, set the color of the text. For the color, we use a preset color in Renderer. We could have also made a call to Renderer.color(red, green, blue, alpha), and subsequently passed that in to the method. In this example, that call would be Renderer.color(255, 255, 255, 255). Values should range from 0-255.
  285.  
  286. Do not instantiate objects inside of a render trigger. Create them outside of the trigger, and if necessary, make any changes to the object inside of the trigger.
  287. Rendering of shapes
  288. This example renders a rectangle, circle, and triangle
  289.  
  290. register("renderOverlay", myRenderOverlay);
  291.  
  292. const rectangle = new Rectangle(Renderer.WHITE, 10, 10, 50, 50);
  293. const circle = new Shape(Renderer.WHITE).setCircle(100, 100, 25, 360);
  294. const polygon = new Shape(Renderer.WHITE)
  295. .addVertex(300, 300)
  296. .addVertex(400, 400)
  297. .addVertex(200, 400);
  298.  
  299. function myRenderOverlay() {
  300. rectangle.draw();
  301. circle.draw();
  302. polygon.draw();
  303. }
  304. Let's look at more complex rendering using shapes. We can see our first complex piece of rendering code to the right. The first thing to notice is how we define the shapes outside of our render trigger. This way we aren't create three objects 60+ times a second.
  305.  
  306. The different shape classes
  307. We create the first shape, the rectangle, with the instantiation of the Rectangle class, whose constructor takes the following arguments: color, x, y, width, and height.
  308.  
  309. The next shape is a circle, which we create through the more general Shape class, which is just a collection of (x, y) points to connect together. We use the setCircle method, which automatically populates the Shape's vertices to give us a perfect circle.
  310.  
  311. Finally, we manually configure the vertices of the last shape ourselves with the addVertex method. After we have created all of our shapes outside of the trigger function, we call the draw method inside of the trigger function to render them to the screen.
  312.  
  313. Rendering images
  314. This example renders the images on the screen
  315.  
  316. register("renderOverlay", myRenderImageOverlay);
  317. const image = new Image("ctjs-logo.png", "http://ct.kerbybit.com/ct.js/images/logo.png");
  318.  
  319. function myRenderImageOverlay() {
  320. image.draw(100, 100);
  321. }
  322. As before, we register for a render overlay trigger so we can do our rendering in it. However, this time, we create an Image object with the file name and URL. The file will download to the ChatTriggers assets directory, which defaults to .minecraft/config/ChatTriggers/images.
  323.  
  324. Images can also be put in /Imports/Example/assets/ for the same result, just make sure resource name is the name of the file, and the file has a .png extension.
  325. Advanced rendering
  326. Here we are rendering text that is a rainbow color
  327.  
  328. register("renderOverlay", myRenderOverlay);
  329.  
  330. const text = new Text("Rainbows!", 10, 10);
  331.  
  332. let exampleImportStep = 0;
  333. function myRenderOverlay() {
  334. text.setColor(Renderer.getRainbow(exampleImportStep));
  335. text.draw();
  336.  
  337. exampleImportStep++;
  338. }
  339. This topic covers advanced rendering, like rainbow colors and dynamic positioning.
  340.  
  341. Rainbow colors
  342. Again, we setup the default rendering scheme of a RenderOverlay trigger and its corresponding function. However, this time we also create a "exampleImportStep" variable that starts of at 0. Then, every time we render to the screen, we increment this step variable by 1.
  343.  
  344. This variable is used when it is passed into the Renderer.getRainbow(step) method, which produces rotating colors, which we then use as the color for the drawString method.
  345.  
  346. Dynamic positioning
  347. This example showcases how to make render positioning dynamic
  348.  
  349. register("renderOverlay", myRenderOverlay);
  350.  
  351. const width = Renderer.screen.getWidth();
  352. const rectWidth = 50;
  353. const textStr = "White Text!";
  354.  
  355. const rectangle = new Rectangle(Renderer.WHITE, width / 2 - rectWidth / 2, 200, rectWidth, 50);
  356. const text = new Text(textStr, width / 2 - Renderer.getStringWidth(textStr) / 2, 100).setColor(Renderer.WHITE);
  357.  
  358. function myRenderOverlay() {
  359. text.draw();
  360. rectangle.draw();
  361. }
  362. Here we are making all of our rendered objects be perfectly aligned horizontally on the screen for all windows sizes. We start off by getting the height of the current window, with the call to Renderer.screen.getWidth().
  363.  
  364. Then, for each part we render, we get half the width of the window, and then subtract half the width of our rendered object. For a string, this is done with (width / 2) - (Renderer.getStringWidth(textToRender) / 2). For a fixed width object, you can replace Renderer.getStringWidth(textToRender) with the width of the object. Notice how we use the Text object and instantiate it outside of the render function. The Text object allows you to set additional properties, such as shadow and color.
  365.  
  366. Tessellator
  367. The Tessellator object is meant for rendering in 3 dimensions. You have to call this object under the renderWorld trigger.
  368.  
  369. Drawing Text
  370. You can set floating text at specific world coordinates using Tessellator.drawString(text, x, y, z)
  371.  
  372. register("renderWorld", myWorldRender);
  373.  
  374. function myWorldRender() {
  375. Tessellator.drawString("Hello there!", 100, 100, 100);
  376. }
  377. This will draw the words "Hello There" at the world location (100, 100, 100). You can also change the text color and scale, whether or not to render the shadow, and whether or not the size increases from distance.
  378.  
  379. Drawing Textures
  380. You can also draw specific textures like so
  381.  
  382. register("renderWorld", myWorldRender);
  383.  
  384. const img = new Image("kerbybit.png", "https://www.chattriggers.com/assets/images/kerbybit.png");
  385.  
  386. function myWorldRender() {
  387. Tessellator.bindTexture(img);
  388. Tessellator.begin()
  389. .translate(Player.getX(), Player.getY(), Player.getZ())
  390. .pos(-0.5, 0.5, -0.5).tex(0, 0)
  391. .pos(-0.5, 0.5, 0.5).tex(0, 1)
  392. .pos(0.5, 0.5, 0.5).tex(1, 1)
  393. .pos(0.5, 0.5, -0.5).tex(1, 0)
  394. .draw();
  395. }
  396. This will draw kerbybit's skin texture at the player's feet position. This works by first binding the texture of the image to the Tessellator object. It then associates positions in the 3D world (relative to the Tesselator's current position) to points on the texture. The tex function takes an x and y argument, both ranging from 0.0 to 1.0, which identifies a point on the texture (i.e. .tex(0.3, 0.7) refers to the point 30% across from the left and 70% down from the top). Finally, a call to .draw() finished the operation.
  397.  
  398. Partial Ticks
  399. Partial ticks are a fractional value representing the amount of time that’s passed between the last full tick and now. This is useful in rendering, as the rest of the game runs on the tick system, but rendering uses frames, a much more precise operation. We use this because otherwise the animation would be jittery because there are fewer ticks per second than frames per second.
  400.  
  401. If we wanted to make the example from above not be jittery, we would use partial ticks.
  402.  
  403. const myPlayerMP = new PlayerMP(Player.getPlayer());
  404.  
  405. function myWorldRender(partialTicks) {
  406. const lastX = myPlayerMP.getLastX();
  407. const lastY = myPlayerMP.getLastY();
  408. const lastZ = myPlayerMP.getLastZ();
  409.  
  410. const currentX = Player.getX();
  411. const currentY = Player.getY();
  412. const currentZ = Player.getZ();
  413.  
  414. Tessellator.bindTexture(img);
  415. Tessellator.begin()
  416. .translate(
  417. lastX + (currentX - lastX) * partialTicks,
  418. lastY + (currentY - lastY) * partialTicks,
  419. lastZ + (currentZ - lastZ) * partialTicks
  420. )
  421. .pos(-0.5, 0.5, -0.5).tex(0, 0)
  422. .pos(-0.5, 0.5, 0.5).tex(0, 1)
  423. .pos(0.5, 0.5, 0.5).tex(1, 1)
  424. .pos(0.5, 0.5, -0.5).tex(1, 0)
  425. .draw();
  426. }
  427. The key difference here is that the change in position is multiplied by the change in time every frame. This makes the drawing smooth since it updates every frame instead of every tick.
  428.  
  429. Objects
  430. ChatTriggers provides several objects to expand the functionality of your imports without you needing to delve into base Minecraft code. A list is found below.
  431.  
  432. It is bad practice to create new object every time you use it, they're heavy objects. Create one in the global scope, and refer back to it.
  433. Object Description
  434. Book Makes an openable book in Minecraft
  435. CPS Contains information about the player's clicks per second
  436. Display Renders text on to the game screen
  437. Gui Makes an openable gui in Minecraft
  438. Inventory Contains information about the player's inventory
  439. KeyBind Used for detecting a key's state
  440. ParticleEffect Allows creation of custom particle effects to be displayed client side
  441. Player Used for getting information about the player
  442. Thread This is a pseudo object, used to do tasks that take a long time
  443. Books
  444. Book objects are used for displaying base Minecraft book GUIs with customizable text.
  445.  
  446. Creation
  447. This is how you create a book
  448.  
  449. const book = new Book("Example Book");
  450. We create our book with the Book constructor of new Book(bookName);. We want to create our book in the global scope, as explained below.
  451.  
  452. Adding content
  453. This is how you add pages to the book
  454.  
  455. const book = new Book("Example Book");
  456.  
  457. book.addPage("This is a very simple page with just text.");
  458. book.addPage(new Message("This is a page with a ", new TextComponent("twist!").setHoverValue("Hi! I'm hover text :o")));
  459. To add content to our book, we'll want to utilize the .addPage(message) method. This can take either a simple string as the message for the page, or a Message object if you want to utilize the functionality the provide, covered here. This should be done right after the instantiation of the book.
  460.  
  461. Updating content
  462. This is how to update a page's content
  463.  
  464. book.setPage(1, new Message("lol!"));
  465. To set a page, we use the .setPage(pageNumber, message). Page number is the number of the page you wish to update, 0 based. The message has to be a Message object, there is no method for just a string.
  466.  
  467. This can be done anytime, just re-display the book to see the updated version. The page you try to set must already exist, or else there will be errors. Just add the page if you need to add a new page afterwards.
  468.  
  469. Displaying
  470. This is how to display the book to the user
  471.  
  472. book.display();
  473. This is how to display the book starting on a certain page
  474.  
  475. book.display(1);
  476. This is a very simple operation which just opens the book. You can also specify a page number to open the book to as the first argument, it defaults to 0. If the page you specify doesn't exist, the player will have to click one of the arrows to go to the next available page.
  477.  
  478. CPS
  479. The CPS object gives information about the player's clicks per second.
  480.  
  481. Clicks per second
  482. To get the left clicks per second, use this
  483.  
  484. const leftClicks = CPS.getLeftClicks();
  485. To get the right clicks per second, use this
  486.  
  487. const rightClicks = CPS.getRightClicks();
  488. There are more methods for the CPS object, but these are the most common. You can always see a full list of up to date documentation on the JavaDocs.
  489.  
  490. Displays
  491. Displays are used for rendering simple text on to the players screen. If you would like to utilize other rendering functions found in the rendering section, use custom rendering functions.
  492.  
  493. Creation
  494. This is how you can create a Display object
  495.  
  496. const display = new Display();
  497. This Display object is now created, but it doesn't do much of anything yet.
  498.  
  499. Adding content
  500. This is how you can add lines to a display
  501.  
  502. display.addLine("Ay! First line.");
  503. display.addLines("2nd line", "3rd line");
  504. display.addLines(2);
  505. display.addLine(new DisplayLine("2 line gap above me!"));
  506. Displays consist of lines of text. These lines can be added and set, and they can use color codes. The first call to .addLine(message) adds a line to the display with the text passed in. The second call to .addLines(messages...) adds as many lines as you pass into it, in our case just 2. If you don't pass in Strings or DisplayLines, then it will just add one line per parameter you passed (e.g .addLines(2) will only add 1 empty line despite the number, but .addLines(0, 0) will add 2 empty lines due to there being 2 parameters).
  507.  
  508. Setting content
  509. This is how you set a line in a display
  510.  
  511. display.setLine(3, "Now this line has text :)");
  512. In this example the call to .setLine(lineNumber, message) sets the 4th line in the display (0 based) which was previously blank to our example text. This is what we would use if we want to update a display with information, like the player's current coordinates.
  513.  
  514. Setting positioning
  515. This is how you set the alignment of a display
  516.  
  517. display.setAlign("left");
  518. This aligns your display on the left side of the screen. Other options are "center" and "right".
  519.  
  520. This is how you set the order of the lines. Both of these ways will work, setting the order to go down.
  521.  
  522. display.setOrder("down");
  523. display.setOrder(DisplayHandler.Order.DOWN);
  524. This renders the lines from 0 going downwards, usually what you'd want. The other option is "up".
  525.  
  526. This is how you set the exact position of the display
  527.  
  528. display.setRenderLoc(10, 10);
  529. This sets the X and Y coordinate of where your display should start, with the first argument being X, and the second being Y.
  530.  
  531. Setting background and foreground options
  532. This sets the background color of the display
  533.  
  534. display.setBackgroundColor(Renderer.AQUA);
  535. This makes the background color of the display aqua. Other options are all the colors in Renderer, or a custom color with Renderer.color(r, g, b, a).
  536.  
  537. This sets the type of background for the display to be fit per line. Both of these options will work.
  538.  
  539. display.setBackground(DisplayHandler.Background.PER_LINE);
  540. display.setBackground("per line");
  541. This option sets how the background color should be displayed. PER_LINE says that the background should be the width of each line. NONE would mean don't show background color, and FULL would indicate make the background color draw in a box around the entire display.
  542.  
  543. This sets the foreground (text) color of the display
  544.  
  545. display.setTextColor(Renderer.BLUE);
  546. All text in the display will now show blue. This method can take any Renderer color, including custom ones described above.
  547.  
  548. DisplayLine can also be used to set the text color, background color, and alignment for a specific line.
  549.  
  550. display.addLine(
  551. new DisplayLine("This will have green text!").setTextColor(Renderer.GREEN)
  552. );
  553. This will set the new line to have green text, overriding the blue we set earlier.
  554.  
  555. Guis
  556. Guis are screens that are opened in game, such as the chat gui, or the escape menu. These stop the player from moving.
  557.  
  558. Creation
  559. This is how you create a gui
  560.  
  561. const gui = new Gui();
  562. Like other objects, creating a Gui is very simple.
  563.  
  564. Rendering the gui
  565. This is how you set up a function to render the gui
  566.  
  567. gui.registerDraw(myGuiRenderFunction);
  568.  
  569. function myGuiRenderFunction(mouseX, mouseY, partialTicks) {
  570. Renderer.drawRect(Renderer.WHITE, mouseX, mouseY, 50, 50);
  571. }
  572. Everything inside of the "myGuiRenderFunction" will be ran while the gui is open. Inside of this function you should make use of the Renderer functions to draw what you want on to the screen. The three arguments passed in are the x coordinate of the user's mouse, the y coordinate of the users mouse, and the partial ticks.
  573.  
  574. In this example, we render a 50x50 square with the top left corner being the user's mouse position.
  575.  
  576. Adding interactivity
  577. This is how you detect when a user presses a key
  578.  
  579. gui.registerKeyTyped(myGuiKeyTypedFunction);
  580.  
  581. function myGuiKeyTypedFunction(typedChar, keyCode) {
  582. ChatLib.chat("You typed " + typedChar);
  583. }
  584. This is how you detect when the user clicks
  585.  
  586. gui.registerClicked(myGuiClickedFunction);
  587. gui.registerDraw(myGuiRenderFunction);
  588.  
  589. let renderSquareX = 0;
  590. let renderSquareY = 0;
  591.  
  592. function myGuiRenderFunction(mouseX, mouseY, partialTicks) {
  593. Renderer.drawRect(Renderer.WHITE, renderSquareX, renderSquareY, 50, 50);
  594. }
  595.  
  596. function myGuiClickedFunction(mouseX, mouseY, button) {
  597. renderSquareX = mouseX;
  598. renderSquareY = mouseY;
  599. }
  600. In the first example we register our key typed function to be activated when someone types a key in our Gui. The keyCode passed can be compared with the Keyboard class keys.
  601.  
  602. In the next example we make things more complicated. We register both a draw function and a mouse clicked function. We render the same box as in the previous draw example, however, we make the coordinates of it be the last place the mouse was clicked.
  603.  
  604. Displaying the gui
  605. To display the gui, use this
  606.  
  607. gui.open();
  608. This opens the gui...
  609.  
  610. To close the gui, use this
  611.  
  612. gui.close();
  613. ...and this closes the gui.
  614.  
  615. These very simple methods open and close the gui, and neither take any arguments.
  616.  
  617. Inventory
  618. The Inventory object contains methods used for getting information about the user's inventory. It can be called through Player.getInventory(). More about the Player class can be found later.
  619.  
  620. Example
  621. function hasSponge() {
  622. const inventory = Player.getInventory();
  623.  
  624. // The ID for sponge is 19.
  625. const spongeSlot = inventory.indexOf(19);
  626.  
  627. if (spongeSlot !== -1) {
  628. ChatLib.chat("Sponge found in slot " + spongeSlot + "!");
  629. } else {
  630. ChatLib.chat("Sponge not found!");
  631. }
  632. }
  633. The example above lets us see if the inventory has a sponge item in it, and if so, say the slot it's in. This works by first getting the inventory of the player, then it gets the slot ID of sponge, if there is any. If any slot has a sponge, it will output the slot, otherwise it will return -1.
  634.  
  635. KeyBinds
  636. KeyBinds are used for detecting the state of a key.
  637.  
  638. These aren't meant to be used for Guis, it's preferable to register a keytyped method for detecting if a player pressed a key inside your Gui
  639. Creation
  640. This is the preferred method to get a keybind
  641.  
  642. const wKeyBind = Client.getKeyBindFromKey(Keyboard.KEY_W, "My W Key");
  643. Let's break this down. We call the function Client.getKeyBindFromKey and save the result in a variable. This will result in trying to find an existing Minecraft keybinding in order to try not to override it. If there isn't one being used, it will create a new KeyBind, with the description and key we specified. We pass into this a keyCode from the Keyboard class.
  644.  
  645. In our case, this will return the keybind already used by Minecraft for the run key (unless of course you changed yours to a different key).
  646.  
  647. Using the keybind
  648. To check if they key bind is being held, do this
  649.  
  650. if (wKeyBind.isKeyDown()) {
  651. ChatLib.chat("Key is down!");
  652. }
  653. To check if the key bind was pressed, use this
  654.  
  655. if (wKeyBind.isPressed()) {
  656. ChatLib.chat("Key is pressed!");
  657. }
  658. This first example would spam your chat if it was in an Tick trigger or something of the like, as it will always be true if you are holding down the key.
  659.  
  660. Now, in the second example, we would only get the chat message once every time we press and hold the key. It only returns true one time per key press. If you let go and press again, it will return true once more.
  661.  
  662. Player
  663. The Player object contains many methods used for retrieving information about the player.
  664.  
  665. Location
  666. To get the direction the player is facing, use this
  667.  
  668. const direction = Player.facing();
  669. To get the coordinates of the player, you can use this
  670.  
  671. const playerX = Player.getX();
  672. const playerY = Player.getY();
  673. const playerZ = Player.getZ();
  674. Using this in conjunction with displays, you can make a coordinates HUD.
  675.  
  676. register("tick", locationTracker);
  677.  
  678. const display = new Display();
  679. display.setRenderLoc(10, 10);
  680.  
  681. function locationTracker() {
  682. display.setLine(0, "X: " + Player.getX());
  683. display.setLine(1, "Y: " + Player.getY());
  684. display.setLine(2, "Z: " + Player.getZ());
  685. }
  686. In this case, we just made a display, and every tick it updates to show the player's location.
  687.  
  688. LookingAt
  689. The LookingAt object was replaced with the Player.lookingAt() method.
  690.  
  691. This gets the current object that the player is looking at, whether that be a block or an entity. It returns either the Block, Sign, Entity class, or an air Block when not looking at anything.
  692.  
  693. Health and Various Stats
  694. You can not only get the player's health, hunger, active potion effects, but much more! Here's just a few examples of how to get each part.
  695.  
  696. const health = Player.getHP();
  697. const hunger = Player.getHunger();
  698. const potions = Player.getActivePotionEffects();
  699. const xpLevel = Player.getXPLevel();
  700. Armor
  701. To get the player's armor, you can use Player.armor
  702.  
  703. const helmet = Player.armor.getHelmet();
  704. This would return the item that is in the helmet slot of the player. This can be a pumpkin or any item that is on the helmet slot.
  705.  
  706. Getting Inventory information
  707. Here's an example showing how to find the durability and stack size of the item the player is holding.
  708.  
  709. function displayHeldItemInfo() {
  710. const item = Player.getHeldItem();
  711.  
  712. if (item.getName() !== "tile.air.name") {
  713. let durabilityPercentage = Math.ceil(
  714. (item.getDurability() / item.getMaxDamage()) * 100
  715. );
  716.  
  717. // If NaN, that means it's a block
  718. if (isNaN(durabilityPercentage)) durabilityPercentage = "N/A (not a tool!)";
  719.  
  720. ChatLib.chat("Item: " + item.getName());
  721. ChatLib.chat("Durability: " + durabilityPercentage);
  722. ChatLib.chat("Stack Size: " + item.getStackSize());
  723. } else {
  724. ChatLib.chat("&4You aren't holding anything!");
  725. }
  726. }
  727. In this case, we get the held item of the player. If the item isn't air, then it finds how damaged it is. If the durability isn't a number, that means the item has to be a block. Then, if the player isn't holding anything, it runs the last piece of the code, which is when the hand is empty. If you want to get the player's inventory as a list of Items, use Player.getInventory().
  728.  
  729. javascript
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement