Date: 2023/04/02 15:08:57 UTC-07:00
Type: Denizen Script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
breaking_time:
type: procedure
debug: false
definitions: args
script:
- define args <[args].as[map].if_null[<[args]>]> if:<[args].object_type.equals[element].is_truthy>
- define null <util.random_decimal>
# ~~~ ARGS ~~~ #
- define hardness <[args.hardness].if_null[]>
- define item <[args.item].if_null[]>
- define hand <[args.is_hand_valid].if_null[]>
- define tools <[args.valid_tools].if_null[]>
# ~~~ DEFAULTS ~~~ #
- define hardness <[args].if_null[<[null]>]> if:<[hardness].equals[]>
- define item <item[air]> if:<[item].equals[]>
- define hand false if:<[hand].equals[]>
- define tools <list> if:<[tools].equals[]>
# ~~~ ERROR CHECKING ~~~ #
- define error <proc[error_missing_check].context[hardness|<[null]>|<[hardness]>|<queue>]>
- define error <proc[error_type_check].context[item|item|<[item]>|<queue>]> if:<[error].not>
- define error <proc[error_type_check].context[is_hand_vaid|element|<[hand]>|<queue>]> if:<[error].not>
- define error <proc[error_type_check].context[valid_tools|list|<[tools]>|<queue>]> if:<[error].not>
- foreach <[tools]>:
- define error <proc[error_type_check].context[valid_tools[<[loop_index]>]|item,element|<[value]>|<queue>]> if:<[error].not>
- define error <proc[error_boolean_check].context[is_hand_vaid|<[hand]>|<queue>]> if:<[error].not>
- determine <empty> if:<[error]>
# ~~~ LOGIC ~~~ #
- determine <util.int_max> if:<[hardness].equals[<util.int_max>]>
- determine 0 if:<[hardness].equals[-1]>
- determine 0.30 if:<[hardness].equals[0]>
- foreach <[tools]>:
- if <[item]> matches <[key]>:
- define speed <[value]>
- define harvestable true
- foreach stop
- define speed <empty> if:<[speed].if_null[true]>
- define in_air <player.location.material.is_solid.not>
- define in_water <player.eye_location.material.advanced_matches[*water]>
- define aqua_affinity <player.equipment_map.filter_tag[<[filter_value].enchantment_map.get[aqua_affinity].exists>].any>
- define haste <player.effects_data.filter_tag[<[filter_value.type].equals[fast_digging]>].first.if_null[]>
- define fatigue <player.effects_data.filter_tag[<[filter_value.type].equals[slow_digging]>].first.if_null[]>
- define efficiency <[item].enchantment_map.get[efficiency].if_null[]>
- define harvestable false
- define haste 0 if:<[haste].equals[]>
- define fatigue 0 if:<[fatigue].equals[]>
- define efficiency 0 if:<[efficiency].equals[]>
- define speed 1 if:<[speed].equals[]>
- define harvestable true if:<[hand].is_truthy>
- define speed:+:<[efficiency].mul[<[efficiency]>].add[1]> if:<[harvestable].and[<[efficiency].is_more_than[0]>]>
- define speed:*:<[haste].mul[0.2].add[1]> if:<player.has_effect[fast_digging]>
- define speed:*:<element[0.3].power[<[fatigue].min[4]>]> if:<player.has_effect[slow_digging]>
- if <[in_air]> and not <[aqua_affinity]>:
- define speed:/:5
- else if <[in_air]>:
- define speed:/:5
- define damage <[speed].div[<[hardness]>]>
- if <[harvestable]>:
- define damage:*:0.03333333
- else:
- define damage:*:0.01
# If the tool and enchantments immediately exceed the hardness times 30, the block breaks with no delay
- determine 0 if:<[damage].is_more_than[<[hardness].mul[30]>]>
- determine 0.3 if:<[damage].is_more_than[1]>
- determine <element[1].div[<[damage]>].round_up.div[20]>
data:
args:
hardness:
type: elementTag
description: A number between -1 and <util.int_max>. <util.int_max> is treated as an infinite break time, and will return <util.int_max> seconds. A hardness of zero returns a break time of zero, which is a delayed infinite break time (similiar to breaking blocks in creative while just holding down left click). A hardness of -1 is treated as a no delay break time, similar to mining stone with an Efficency 5 diamond pickaxe and Haste 3. Everything else uses the vanilla breaking formula which can be found <&click[https://minecraft.fandom.com/wiki/Breaking#:~:text=Combining<&pc>20all<&pc>20of<&pc>20the<&pc>20information<&pc>20above].on_click[open_url]>here<&end_click>.
required: true
valid_tools:
type: mapTag<<>itemTag|elementTag=elementTag<>>
description: A map of items/item names, with the speed at which the item can break the block at. For example, you may want an iron sword to be twice as effective as a wooden sword, so you'd create a map that looked something like <<>map[iron_sword=10;wooden_sword=5]<>>. You can also input item script names, or use a matcher, such as *sword. These values are used in the process of finding the breaking speed, and are not directly translatable to amount of time. The vanilla values of tool materials can be found <&click[https://minecraft.fandom.com/wiki/Breaking#:~:text=Tool<&pc>20Speed].on_click[open_url]>here<&end_click>.
required: false
is_hand_valid:
type: elementTag
description: Whether a hand is a valid "tool" to break with. If this is true, it effectively overwrites valid_tools, since every tool is valid if a hand is valid. If not specified, defaults to false.
required: false
item:
type: itemTag
description: The item you're using to break with. If no item is provided, the equation is run assuming a hand. An air item is also treated as attempting to break with a hand.
required: false
description: Takes an item, and a hardness value, and calculates the amount of seconds it would take to be mined. Attempts to follow vanilla Minecraft breaking logic, based on the information from the <&click[https://minecraft.fandom.com/wiki/Breaking].on_click[open_url]>Breaking<&end_click> page on the Minecraft wiki.
determines: elementTag
usage:
- define tools:->:<player.item_in_hand>
- define hardness <player.eye_location.ray_trace[return=block].material.hardness>
- narrate "It will take <proc[breaking_time].context[valid_tools=<[tools]>;item=<[tools].first>;hardness=<[hardness]>]> seconds to break the block I'm looking at with the tool in my hand."
#========================================#
error_type_check:
type: procedure
debug: false
definitions: name|types|object|queue
script:
- define types <[types].split[,]> if:<[types].object_type.equals[element]>
- define actual <[object].object_type>
- if <[actual].to_lowercase> not in <[types]>:
- define formatted <&sq><[types].first><&sq>
- foreach <[types].get[2].to[-2]> if:<[types].size.is_more_than[2]>:
- define formatted "<[formatted]>, '<[value]>'"
- define formatted "<[formatted]> or '<[types].last>'" if:<[types].size.is_more_than[1]>
- debug error "<[queue].script.name.to_uppercase>: Argument '<[name]>' is supposed to be of <[formatted]>, but was instead of type '<[actual]>'."
- determine true
- determine false
error_missing_check:
type: procedure
debug: false
definitions: name|null|object|queue
script:
- if <[object]> == <[null]>:
- debug error "<[queue].script.name.to_uppercase>: Missing argument '<[name]>'."
- determine true
- determine false
error_boolean_check:
type: procedure
debug: false
definitions: name|object|queue
script:
- if not <[object].is_boolean>:
- debug error "<[queue].script.name.to_uppercase>: Argument '<[name]>' is not a boolean value."
- determine true
- determine false