your current location:首页 > news>[1.12] How to control the use of modules, block interaction, block damage [CRT] CRAFTTWEAKER MINECRAFT Game

[1.12] How to control the use of modules, block interaction, block damage [CRT] CRAFTTWEAKER MINECRAFT Game

2024-12-10 17:45:58|Myriagame |source:minecraft skins

This tutorial is set by the author's setting without permission.

Since I did not find how to use the CRT magic to change the use of the CRT magic to use the use of the CRT, the interactiveness of the block, and the damage of the square, I will explain how to use CRT to achieve these functions.

The code analysis in this article is relatively detailed, please read it carefully, and the reading time is longer.

How to prohibit box destruction

This is a very simple feature. If I want to set the player during a certain game (provided by GameStage), it cannot destroy a certain block.

The following code is that players who have not obtained "Forestryage" and "IndustRial" in the survival mode cannot destroy the corresponding MOD blocks.

 Import Crafttweaker.event.blockBreakevent;

import crafttweaker.player.iplayer;

Import Crafttweaker.event.ieventCanceLable;

Import crafttweaker.block.iblock; // guide package

Global Stage as String [String] = {

Forestryage: "Forestry",

Industrialage: "IC2"

};

Events.onBlockBreak (Function (event as crafttweaker.event.blockBreakevent) {{

var block as iBlock = event.block;

var Player as iPlayer = EVENT.Player;

for key in stage {

// Judgment conditions

if (! Player.creation && Block.Definition.id.Contains (Stage [Key]) &&! Player.hasgamestage (KEY)) {

event.cancel (); // Prevent the incident from the event

event.player.sendstatusMessage (format.red ("" You are not familiar with it "); // Output prompt

}}

});

Code analysis:


1. Needless to say, what Event is used to guide the corresponding package. The type of Events can be found on the CRT Wiki.

For example, we use BlockBreakevent here. Its Event Interface includes IEVENTCANTENSIONS and IBLOCKEvent, which means that it can directly use the Getter, Setter, METHOD, or Method, or its succession provided by IEVENTCANTCLEVENT. Actif to the functions of IEVENTCANCANCLABLE and IBLOCKEEVENT.


2. Global Stage ... Here I declare a global variable called Stage. Its type is HashMap (understanding as an array with a custom index), the index type is string, and the content type is also string.Then I filled out two instances, Forestryage: "Forestry", IndustRial: "IC2".

One step here is used to store the GameStage variables that will be used later, and the reason why it is written as HashMap is to facilitate subsequent batch operations.


3. Events.onBlockBreak (Function (event as craftweaker.event.blockBreakevent) {}; this is a CRT -universal function case method that declares the Event in this function refers to the crafttweaker.event.blockb. Reakevent.Write this way. For different events, replace the name inside.

4. VAR BLOCK As IBlock = Event.block;


var Player as iPlayer = EVENT.Player;

This is actually two variables, blocks and players, their types are iBlock and iPlayer, respectively, and the content refers to Event.block and Event.player.

(We have already defined the Event here in 3, in fact, Crafttweaker.event.blockBreakevent))

The declarations in 3 and 4 are actually for abbreviations, which is convenient to follow, and these steps can also be omitted.For example, after the 3 or 4, the block in the subsequent code must write with crafttweaker.event.blockBreakevent.blcok.But for beauty and improvement, let's do this.

5. For Key in Stage {} Here is a traversal of elements in Stage, that is, applying two stages to the judgment statements later.


6. If (! Player.creative && Block.Definition.id.Contains (Stage [Key]) &&! Player.hasgamestage (Key)) The judgment condition here is:


The name of the non -creative mode && event target block contains "Stage [Key]" elements (that is, Forestry, IC2) && players do not have Stage indexes (that is, Forestryage, IndusStric, pay attention to one corresponding).

If you don't want to control the damage of the block through the MOD_ID, you can change to any condition you want, just check the Class provided by the corresponding Event. Note that the source of the condition must be the event you chose or it inherits it.of.

7. Why can't you directly detect the MOD_ID of items?


I also think, but CRT does not provide which MOD method of testing items belongs to, so you can only detect whether the item's definition.id contains keywords in certain mod_ids, which is the contains function.Note that it is not item.Name but item.definition.id. For detailed differences, you can go to print to see the difference yourself.

How to prohibit the use of items

 Import ...

Events.onPlayerrightClickItem (Function (event as crafttweaker.event.playerrightClickitemevent) {{

var Item as IItemstack = Event.Item;

var Player as iPlayer = EVENT.Player;

for key in stage {

If (! Player.creative &&! ISNULL (Item) && item.definition.id.contains (Stage [key]) &&! Player.hasgamestage (KEY)) {

event.cancel ();

event.player.sendstatusMessage (format.red ("You are not familiar with it");

}}

});

How to prohibit items and block interaction

 Events.onPlayerInteractBlock (Function (event as crafttweaker.event.playerinteractBlock) {Var Block As iBlock = Event.block;

var Player as iPlayer = EVENT.Player;

var Item as IItemstack = Event.Item;

for key in stage {

If (! Player.creative && Block.Definition.id.Contains (Stage [Key]) &&! Player.hasgamestage (KEY)) {

event.cancel ();

event.player.sendstatusMessage (format.red ("You are not familiar with it");

}}

for key in stage {

If (! Player.creative &&! Isnull (item) && Player.CURRENTITITEM.DEFINITION.id.Contains (Stage [KEY]) &&! Player.hasgamestage)) {) {

event.cancel ();

event.player.sendstatusMessage (format.red ("You are not familiar with it");

}}

});

Code analysis:

1. This code is worth noting: the first judgment statement detects the name of the event target block, and the second judgment statement detects the items held by the player;


PlayerInteractBlockBlock does not provide us with event target blocks or handheld items, but the PlayerInteract and iPlayrevent classes it inherit provide me with the corresponding return class:

PlayerInteractionEvent provided

The class provided by the iPlayer (iPlayRevent inherits it, which is almost equivalent to one of the grandfather of PlayerInteractBlockevent)

2. Q: Why can't you judge two judgments, and at the same time judge the handheld item or the target block (Event.Item || Event.block)?

A: There is a difference between interactive events and square damage events. The incident of square damage is only judged once on the server, and the interactive event must be communicated between the client and the server twice, and a total of four judgments (here involved the underlying logic of MC's underlying logic hereThis is the author's own guess. If the error is wrong, please contact the author to change it in time). Therefore, after the first judgment, Event will be Cancel. As a result, the subsequent second judgment will beIt has been canceled, and of course there will be no event items), which will cause Pointernull to report an error. The code function can still be realized, but the error will be repeated.Therefore, it will add the second judgment statement to Isnull (item), that is, if item is NULL, there is no need to judge event items, so as not to report the event items for air errors.


3. Q: Why not prevent the PlayerInteract incident directly?

A: Let's take a look at the official wiki


Indeed, PlayerInteractionEvent (the parent class of PlayerInteractBlock) also provides getteds such as ITEM and Block. If you call it, you can also prevent players from interacting.

However, there is actually an error in the official document (unknown reason)

The official document shows that PlayerInteractionEvent inherits the function of IEventCanceLable, which is the function of event.cancel (), so that we can call it.But in fact, PlayerInteraCtevent did not inherit the IEventCanceLable, as shown below::

Obviously, PlayerInteraCtevent only inherits the iPlayRerevent and IEventpositionable, and these two categories do not inherit the IEventCanceLABLE, so we cannot call Event.cancel ();

Let ’s release a piece of code in my own integration package. You can try to analyze and understand according to the previous method to learn how to use CRT to control these events.

#Priority 500

#Loader Crafttweaker ReloadableEvents


import crafttweaker.item.iitemstack;

import crafttweaker.item.iitemDefinition;

Import Crafttweaker.event.playerInteraction;

Import Crafttweaker.event.playerInteractBlockVent;

Import Crafttweaker.event.ieventCanceLable;

import crafttweaker.event.blockBreakevent;

import crafttweaker.player.iplayer;

import crafttweaker.block.iblock;

import crafttweaker.event.playerrickkitemevent;

Import mode.recipestages.Rcipes;

Global Stage as String [String] = {

Rustic: "Rustic",

Harvest: "Harvesstcraft",

Tropic: "Tropicraft",

HAC: "DCS_ClImate",

Animania: "Animania",

Magic: "Magic",

Tech: "RefinedStorage",

Betweenlands: "THEBETWEENLANDS",

Rats: "Rats", Forestry: "Forestry",

Plants: "PMP",

TOFU: "Tofucraft"

};

// StageDevent

Events.onPlayerrightClickItem (Function (event as crafttweaker.event.playerrightClickitemevent) {{

var Item as IItemstack = Event.Item;

var Player as iPlayer = EVENT.Player;

for key in stage {

If (! Player.creative &&! ISNULL (Item) && item.definition.id.contains (Stage [key]) &&! Player.hasgamestage (KEY)) {

event.cancel ();

event.player.sendstatusMessage (format.red ("You are not familiar with it");

}}

});

Events.onBlockBreak (Function (event as crafttweaker.event.blockBreakevent) {{

var block as iBlock = event.block;

var Player as iPlayer = EVENT.Player;

for key in stage {

if (! Player.creation && Block.Definition.id.Contains (Stage [Key]) &&! Player.hasgamestage (KEY)) {

Print (block.definition.id);

Print (Stage [key]);

Print (player.name);

Print (block.definition.id.contains (key));

Print (! Player.hasgamestage (key));

event.cancel ();

event.player.sendstatusMessage (format.red ("You are not familiar with it");

}}

});

Events.onPlayerInteractBlock (Function (event as crafttweaker.event.playerInteractBlock) {{{{{) {{

var block as iBlock = event.block;

Var Player as iPlayer = Event.player; Var it item as IItemstack = Event.Item;

for key in stage {

If (! Player.creative && Block.Definition.id.Contains (Stage [Key]) &&! Player.hasgamestage (KEY)) {

event.cancel ();

event.player.sendstatusMessage (format.red ("You are not familiar with it");

}}

for key in stage {

If (! Player.creative &&! Isnull (item) && Player.CURRENTITITEM.DEFINITION.id.Contains (Stage [KEY]) &&! Player.hasgamestage)) {) {

event.cancel ();

event.player.sendstatusMessage (format.red ("You are not familiar with it");

}}

});

for key in stage {

SetRcipestage (key, stage [key], key! = "Magic");

}

For the addition of GameStage is not a scope of this tutorial, please refer to other tutorials.