diff --git a/gm4_horsemanship/README.md b/gm4_horsemanship/README.md new file mode 100644 index 0000000000..224b45232c --- /dev/null +++ b/gm4_horsemanship/README.md @@ -0,0 +1,9 @@ +# Shapeless Portals + +TODO! + +There is 1 portal among us + +### Features +- Light portals of any shape with Flint and Steel or Fire Charges. +- Portals can use Crying Obsidian. diff --git a/gm4_horsemanship/beet.yaml b/gm4_horsemanship/beet.yaml new file mode 100644 index 0000000000..7d94f5ecbb --- /dev/null +++ b/gm4_horsemanship/beet.yaml @@ -0,0 +1,28 @@ +id: gm4_horsemanship +name: Horsemanship +version: 1.0.X + +data_pack: + load: . + +pipeline: + - gm4.plugins.extend.module + - gm4.plugins.include.lib_forceload + +meta: + gm4: + versioning: + required: + lib_forceload: 1.1.0 + schedule_loops: + - main + - tick + website: + description: Form a bond with your horses + recommended: [] + notes: [] + video: null + wiki: https://wiki.gm4.co/wiki/Horsemanship + credits: + Creator: + - Thanathor diff --git a/gm4_horsemanship/data/gm4_horsemanship/advancement/feed_horse.json b/gm4_horsemanship/data/gm4_horsemanship/advancement/feed_horse.json new file mode 100644 index 0000000000..10a03aee3d --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/advancement/feed_horse.json @@ -0,0 +1,165 @@ +{ + "criteria": { + "apple": { + "trigger": "minecraft:player_interacted_with_entity", + "conditions": { + "player": [], + "item": { + "items": [ + "minecraft:apple" + ] + }, + "entity": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type": "#gm4_horsemanship:trainable", + "nbt": "{Tags:[\"gm4_horse\"]}" + } + } + ] + } + }, + "golden_apple": { + "trigger": "minecraft:player_interacted_with_entity", + "conditions": { + "player": [], + "item": { + "items": [ + "minecraft:golden_apple" + ] + }, + "entity": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type": "#gm4_horsemanship:trainable", + "nbt": "{Tags:[\"gm4_horse\"]}" + } + } + ] + } + }, + "enchanted_golden_apple": { + "trigger": "minecraft:player_interacted_with_entity", + "conditions": { + "player": [], + "item": { + "items": [ + "minecraft:enchanted_golden_apple" + ] + }, + "entity": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type": "#gm4_horsemanship:trainable", + "nbt": "{Tags:[\"gm4_horse\"]}" + } + } + ] + } + }, + "golden_carrot": { + "trigger": "minecraft:player_interacted_with_entity", + "conditions": { + "player": [], + "item": { + "items": [ + "minecraft:golden_carrot" + ] + }, + "entity": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type": "#gm4_horsemanship:trainable", + "nbt": "{Tags:[\"gm4_horse\"]}" + } + } + ] + } + }, + "sugar": { + "trigger": "minecraft:player_interacted_with_entity", + "conditions": { + "player": [], + "item": { + "items": [ + "minecraft:sugar" + ] + }, + "entity": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type": "#gm4_horsemanship:trainable", + "nbt": "{Tags:[\"gm4_horse\"]}" + } + } + ] + } + }, + "wheat": { + "trigger": "minecraft:player_interacted_with_entity", + "conditions": { + "player": [], + "item": { + "items": [ + "minecraft:wheat" + ] + }, + "entity": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type": "#gm4_horsemanship:trainable", + "nbt": "{Tags:[\"gm4_horse\"]}" + } + } + ] + } + }, + "hay_block": { + "trigger": "minecraft:player_interacted_with_entity", + "conditions": { + "player": [], + "item": { + "items": [ + "minecraft:hay_block" + ] + }, + "entity": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type": "#gm4_horsemanship:trainable", + "nbt": "{Tags:[\"gm4_horse\"]}" + } + } + ] + } + } + }, + "requirements": [ + [ + "apple", + "golden_apple", + "enchanted_golden_apple", + "golden_carrot", + "sugar", + "wheat", + "hay_block" + ] + ], + "rewards": { + "function": "gm4_horsemanship:need/food/feed_original_food" + } +} diff --git a/gm4_horsemanship/data/gm4_horsemanship/advancement/start_riding_horse.json b/gm4_horsemanship/data/gm4_horsemanship/advancement/start_riding_horse.json new file mode 100644 index 0000000000..e1aa5708e5 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/advancement/start_riding_horse.json @@ -0,0 +1,24 @@ +{ + "criteria": { + "requirement": { + "trigger": "minecraft:started_riding", + "conditions": { + "player": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "vehicle": { + "type": "#gm4_horsemanship:trainable", + "nbt": "{Tags:[\"gm4_horse\"]}" + } + } + } + ] + } + } + }, + "rewards": { + "function": "gm4_horsemanship:horse_processing/start_riding_horse" + } +} diff --git a/gm4_horsemanship/data/gm4_horsemanship/advancement/tame_horse.json b/gm4_horsemanship/data/gm4_horsemanship/advancement/tame_horse.json new file mode 100644 index 0000000000..325674e490 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/advancement/tame_horse.json @@ -0,0 +1,21 @@ +{ + "criteria": { + "requirement": { + "trigger": "minecraft:tame_animal", + "conditions": { + "entity": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type": "#gm4_horsemanship:trainable" + } + } + ] + } + } + }, + "rewards": { + "function": "gm4_horsemanship:horse_processing/tame_horse" + } +} diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/dev.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/dev.mcfunction new file mode 100644 index 0000000000..9b78b9376e --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/dev.mcfunction @@ -0,0 +1,10 @@ + +tellraw @s "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" + +tellraw @s "-= HORSE STAT TRACKER =-" +tellraw @s {text:"click here to disable",color:"red","click_event":{action:"run_command",command:"tag @s remove gm4_horse_dev"}} +tellraw @s "" +tellraw @s {text:"Tracked Horse: ",color:"red","click_event":{action:"run_command",command:"tag @s remove gm4_horse_dev"}} + + +execute as @e[type=#gm4_horsemanship:trainable,limit=1,sort=nearest] run return 0 diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/dev/log.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/dev/log.mcfunction new file mode 100644 index 0000000000..88153db6b7 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/dev/log.mcfunction @@ -0,0 +1,32 @@ + + +tellraw @p "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" + +tellraw @p [{text:"| Tracked Horse: "},{selector:"@s"}] +tellraw @p [{text:"Stamina: ","color":"gray"},{"score":{"name":"@s","objective":"gm4_horse_need.stamina"},"color":"white"},{text:"/"},{"score":{"name":"@s","objective":"gm4_horse.stamina_cap"}}] + +tellraw @p "" + +scoreboard players set $potential_loss.mult gm4_horse_data 1 +execute unless score @s gm4_horse_need.brushing matches 50.. run scoreboard players add $potential_loss.mult gm4_horse_data 1 +execute if entity @s[tag=gm4_horse.tired] run scoreboard players add $potential_loss.mult gm4_horse_data 1 +execute unless score @s gm4_horse_need.graze matches 1.. run scoreboard players add $potential_loss.mult gm4_horse_data 1 + +scoreboard players operation $xp_conversion gm4_horse_data = @s gm4_horse_potential.realized +scoreboard players operation $xp_conversion gm4_horse_data /= @s gm4_horse_potential.total + +tellraw @p [{text:"Level: ","color":"gray"},{"score":{"name":"@s","objective":"gm4_horse_level"},"color":"white"},\ +{text:" XP: "},{"score":{"name":"@s","objective":"gm4_horse_experience"},"color":"white"},\ +{text:" Potential: "},{"score":{"name":"@s","objective":"gm4_horse_potential.total"},"color":"white"},{text:"/1125 | "},{"score":{"name":"@s","objective":"gm4_horse_potential.realized"},"color":"white"},\ +{"text":" (","color":"dark_gray"},{"score":{"name":"@s","objective":"gm4_horse_comfort"},"color":"dark_gray"},{"text":"% | ","color":"dark_gray"},{"score":{"name":"$potential_loss.mult","objective":"gm4_horse_data"},"color":"dark_gray"},{"text":"x | ","color":"dark_gray"},{"score":{"name":"$xp_conversion","objective":"gm4_horse_data"},"color":"dark_gray"},{"text":")","color":"dark_gray"}\ +] + + +tellraw @p "" + +tellraw @p [{text:"Graze: ","color":"gray"},{"score":{"name":"@s","objective":"gm4_horse_need.graze"},"color":"white"},\ +{text:"/2160 | Brush: "},{"score":{"name":"@s","objective":"gm4_horse_need.brushing"},"color":"white"},\ +{text:"/1500 | On Leash: "},{"score":{"name":"@s","objective":"gm4_horse_need.on_leash"},"color":"white"},\ +{text:"/1125 | Fed Treat: "},{"score":{"name":"@s","objective":"gm4_horse_need.fed_treat"},"color":"white"},\ +{text:"/15"},\ +] diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/horse_processing/cap_health.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/horse_processing/cap_health.mcfunction new file mode 100644 index 0000000000..c0927a699b --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/horse_processing/cap_health.mcfunction @@ -0,0 +1,12 @@ +# cap health just below the real max health +# @s = gm4_horse +# at @s +# run from horse_processing/general + + +execute store result score $max_health gm4_horse_data run attribute @s max_health get 100 +scoreboard players remove $max_health gm4_horse_data 101 +execute store result score $curr_health gm4_horse_data run data get entity @s Health 100 +execute if score $curr_health gm4_horse_data > $max_health gm4_horse_data store result entity @s Health float 0.01 run scoreboard players get $max_health gm4_horse_data + +tag @s remove gm4_horse.check_health diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/horse_processing/general.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/horse_processing/general.mcfunction new file mode 100644 index 0000000000..c704c1e5c5 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/horse_processing/general.mcfunction @@ -0,0 +1,130 @@ +# process gm4 horses, variants, donkeys and mules +# @s = gm4_horse +# at @s +# run from main + +# check health for fed horses +execute if entity @s[tag=gm4_horse.check_health] run function gm4_horsemanship:horse_processing/cap_health + +## | Health Status +# health should always be slightly below max, to allow for feeding the horse at any time +execute store result score $max_health gm4_horse_data run attribute @s max_health get 100 +scoreboard players remove $max_health gm4_horse_data 101 +execute store result score $curr_health gm4_horse_data run data get entity @s Health 100 +execute if score $curr_health gm4_horse_data > $max_health gm4_horse_data store result entity @s Health float 0.01 run scoreboard players get $max_health gm4_horse_data + +## | Riding Status +# stores all relevant statuses of the horse in scores +scoreboard players set $mounted gm4_horse_data 0 +scoreboard players set $riding gm4_horse_data 0 +execute store success score $mounted gm4_horse_data on controller if entity @s[type=player] +execute if score $mounted gm4_horse_data matches 1 on controller if score @s gm4_horse_riding matches 1.. run scoreboard players set $riding gm4_horse_data 1 +execute store success score $saddled gm4_horse_data if data entity @s equipment.saddle +execute store success score $on_leash gm4_horse_data if data entity @s leash.UUID +execute store result score $on_ground gm4_horse_data run data get entity @s OnGround + +## | Stamina +# cap of 75 - 450 depending on level +# riding = -1 +# swimming = -1 +execute if score $riding gm4_horse_data matches 1 run scoreboard players remove @s[scores={gm4_horse_need.stamina=1..}] gm4_horse_need.stamina 1 +execute if entity @s[tag=gm4_horse.swimming] run scoreboard players remove @s[scores={gm4_horse_need.stamina=1..}] gm4_horse_need.stamina 1 +# mounted = +1 +# unmounted = +3 +level +# on leash = +2*level +execute if score $mounted gm4_horse_data matches 1 if score $on_ground gm4_horse_data matches 1 if score $riding gm4_horse_data matches 0 run scoreboard players add @s gm4_horse_need.stamina 1 +execute if score $mounted gm4_horse_data matches 0 if score $on_ground gm4_horse_data matches 1 run scoreboard players add @s gm4_horse_need.stamina 3 +execute if score $mounted gm4_horse_data matches 0 if score $on_ground gm4_horse_data matches 1 run scoreboard players operation @s gm4_horse_need.stamina += @s gm4_horse_level +execute if score $on_leash gm4_horse_data matches 1 run scoreboard players operation @s gm4_horse_need.stamina += @s gm4_horse_level +execute if score $on_leash gm4_horse_data matches 1 run scoreboard players operation @s gm4_horse_need.stamina += @s gm4_horse_level +scoreboard players operation @s gm4_horse_need.stamina < @s gm4_horse.stamina_cap +# tired +execute if score @s[tag=!gm4_horse.tired] gm4_horse_need.stamina matches 0 run function gm4_horsemanship:riding/stamina/tired +execute if entity @s[tag=gm4_horse.tired] run particle entity_effect{color:[0.290,0.259,0.090,0.75]} ~ ~1 ~ 0.5 0.5 0.5 1 4 normal +execute if score @s[tag=gm4_horse.tired] gm4_horse_need.stamina matches 30.. run function gm4_horsemanship:riding/stamina/rested + +## | Grazing +# cap of 1800 +# always = -1 +# riding = -2 +execute if score $riding gm4_horse_data matches 1 run scoreboard players remove @s[scores={gm4_horse_need.graze=2..}] gm4_horse_need.graze 2 +scoreboard players remove @s[scores={gm4_horse_need.graze=1..}] gm4_horse_need.graze 1 +# grazed = +360, or set to 1800 if on Hay Bale +# if score >300 force grazing if not riding, or >850 if on Hay Bale and unmounted +execute if score $on_ground gm4_horse_data matches 1 if score @s[tag=!gm4_horse.force_graze] gm4_horse_need.graze matches ..300 if score $riding gm4_horse_data matches 0 if block ~ ~-1 ~ grass_block if block ~ ~ ~ #gm4_horsemanship:can_eat_through run function gm4_horsemanship:need/graze/force +execute if score $on_ground gm4_horse_data matches 1 if score @s[tag=!gm4_horse.force_graze] gm4_horse_need.graze matches ..950 if score $mounted gm4_horse_data matches 0 if block ~ ~-1 ~ hay_block if block ~ ~ ~ #gm4_horsemanship:can_eat_through run function gm4_horsemanship:need/graze/force +execute if score $riding gm4_horse_data matches 1 if entity @s[nbt={EatingHaystack:1b}] run function gm4_horsemanship:need/graze/cancel +# hungry +execute if score @s gm4_horse_need.graze matches 0 run particle entity_effect{color:[0.345,0.463,0.325,0.75]} ~ ~1 ~ 0.5 0.5 0.5 1 4 normal + +## | Brushing +# cap of 1500 +# saddled = -2 +# riding = -1 +# always = -1 +execute if score $saddled gm4_horse_data matches 1 run scoreboard players remove @s[scores={gm4_horse_need.brushing=2..}] gm4_horse_need.brushing 2 +execute if score $riding gm4_horse_data matches 1 run scoreboard players remove @s[scores={gm4_horse_need.brushing=1..}] gm4_horse_need.brushing 1 +scoreboard players remove @s[scores={gm4_horse_need.brushing=1..}] gm4_horse_need.brushing 1 +# brushed = +75 per tick (from advancement, only if brushing is 1450 or less) +execute unless score @s gm4_horse_need.brushing matches 100.. run particle block{block_state:"dirt"} ~ ~1 ~ 0.4 0.3 0.4 0 1 + +## | On Leash +# cap of 1125 +# on leash = +75 +# not mounted = -1 +execute if score $on_leash gm4_horse_data matches 1 run scoreboard players add @s gm4_horse_need.on_leash 75 +scoreboard players operation @s gm4_horse_need.on_leash < $need_cap.on_leash gm4_horse_data +execute if score $mounted gm4_horse_data matches 0 run scoreboard players remove @s[scores={gm4_horse_need.on_leash=1..}] gm4_horse_need.on_leash 1 + +## | Fed Treat +# cap of 15 +# fed a treat = set to 15 +# always = -1 +execute if score $riding gm4_horse_data matches 1 run scoreboard players remove @s[scores={gm4_horse_need.fed_treat=1..}] gm4_horse_need.fed_treat 1 +execute if score $on_leash gm4_horse_data matches 1 run scoreboard players remove @s[scores={gm4_horse_need.fed_treat=1..}] gm4_horse_need.fed_treat 1 + +## | Comfort +# 0 - 100% +scoreboard players operation @s gm4_horse_comfort = @s gm4_horse_need.graze +scoreboard players operation @s gm4_horse_comfort /= #2 gm4_horse_data +scoreboard players operation @s gm4_horse_comfort < #1000 gm4_horse_data +scoreboard players add @s gm4_horse_comfort 1500 +execute store result score $nearby_horses gm4_horse_data if entity @e[type=#gm4_horsemanship:trainable,distance=0.01..24,limit=10] +scoreboard players operation $nearby_horses gm4_horse_data *= #100 gm4_horse_data +scoreboard players operation @s gm4_horse_comfort += $nearby_horses gm4_horse_data +execute if score @s gm4_horse_need.on_leash matches 1.. unless score $on_leash gm4_horse_data matches 1 run scoreboard players add @s gm4_horse_comfort 750 +execute if score @s gm4_horse_need.fed_treat matches 1.. run scoreboard players add @s gm4_horse_comfort 750 +scoreboard players operation @s gm4_horse_comfort /= #50 gm4_horse_data + + +## || Potential & Level-Up +# potential goes up when not riding +scoreboard players set $potential_change gm4_horse_data 0 +execute if score $riding gm4_horse_data matches 0 unless score @s gm4_horse_potential.total matches 1125.. run scoreboard players set $potential_change gm4_horse_data 1 +execute if score $riding gm4_horse_data matches 1 if score @s gm4_horse_potential.total matches 1.. run scoreboard players set $potential_change gm4_horse_data -1 + +# add comfort to realized potential when total potential goes up +execute if score $potential_change gm4_horse_data matches 1 run scoreboard players operation @s gm4_horse_potential.realized += @s gm4_horse_comfort + +# potential loss multiplier is increased by +# brush score below 50 = +1 +# horse is tired = +1 +# graze score is below 1 = +1 +# on leash is below 1000 = +1 +scoreboard players set $potential_loss.mult gm4_horse_data 1 +execute unless score @s gm4_horse_need.brushing matches 50.. run scoreboard players add $potential_loss.mult gm4_horse_data 1 +execute if entity @s[tag=gm4_horse.tired] run scoreboard players add $potential_loss.mult gm4_horse_data 1 +execute unless score @s gm4_horse_need.graze matches 1.. run scoreboard players add $potential_loss.mult gm4_horse_data 1 +execute unless score @s gm4_horse_need.on_leash matches 1000.. run scoreboard players add $potential_loss.mult gm4_horse_data 1 + +# horse realized potential goes down +scoreboard players operation $potential_loss gm4_horse_data = @s gm4_horse_potential.realized +scoreboard players operation $potential_loss gm4_horse_data /= @s gm4_horse_potential.total + +# horse realized potential goes down when riding, the base is subtracted from needed experience, then the multiplied amount is subtracted from realized potential +execute if score $potential_change gm4_horse_data matches -1 run scoreboard players operation @s gm4_horse_experience -= $potential_loss gm4_horse_data +scoreboard players operation $potential_loss gm4_horse_data *= $potential_loss.mult gm4_horse_data +execute if score $potential_change gm4_horse_data matches -1 run scoreboard players operation @s gm4_horse_potential.realized -= $potential_loss gm4_horse_data +execute if score @s[scores={gm4_horse_level=..14}] gm4_horse_experience matches ..0 run function gm4_horsemanship:level/level_up + +scoreboard players operation @s gm4_horse_potential.total += $potential_change gm4_horse_data diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/horse_processing/start_riding_horse.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/horse_processing/start_riding_horse.mcfunction new file mode 100644 index 0000000000..58a8d955f4 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/horse_processing/start_riding_horse.mcfunction @@ -0,0 +1,12 @@ +# process a player that just mounted a horse with gm4_horse tag (or equivalent) +# @s = player riding the horse +# at @s (before mounting) +advancement revoke @s only gm4_horsemanship:start_riding_horse + +scoreboard players set $interaction_resolved gm4_horse_data 0 + +# check for brushing +execute if score $interaction_resolved gm4_horse_data matches 0 if predicate gm4_horsemanship:holding_brush run function gm4_horsemanship:need/care/brush/process + +# check for food +execute if score $interaction_resolved gm4_horse_data matches 0 if predicate gm4_horsemanship:holding_food run function gm4_horsemanship:need/food/feed_added_food diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/horse_processing/tame_horse.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/horse_processing/tame_horse.mcfunction new file mode 100644 index 0000000000..ef42854bb4 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/horse_processing/tame_horse.mcfunction @@ -0,0 +1,7 @@ +# process a player that just tamed a horse (or equivalent) +# @s = player taming the horse +# at @s +advancement revoke @s only gm4_horsemanship:tame_horse + +execute on vehicle if entity @s[type=#gm4_horsemanship:trainable,tag=gm4_horse,tag=!gm4_horse.tamed] run function gm4_horsemanship:level/tame_horse + diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/init.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/init.mcfunction new file mode 100644 index 0000000000..2aa59dae68 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/init.mcfunction @@ -0,0 +1,49 @@ +execute unless score horsemanship gm4_modules matches 1 run data modify storage gm4:log queue append value {type:"install",module:"Horsemanship"} +scoreboard players set horsemanship gm4_modules 1 + +# add scoreboards +scoreboard objectives add gm4_horse_data dummy + +scoreboard objectives add gm4_horse_level dummy +scoreboard objectives add gm4_horse_riding minecraft.custom:minecraft.horse_one_cm +scoreboard objectives add gm4_horse_speed_step dummy +scoreboard objectives add gm4_horse_jump_step dummy +scoreboard objectives add gm4_horse_experience dummy +scoreboard objectives add gm4_horse_comfort dummy + +scoreboard objectives add gm4_horse_need.stamina dummy +scoreboard objectives add gm4_horse_need.on_leash dummy +scoreboard objectives add gm4_horse_need.fed_treat dummy +scoreboard objectives add gm4_horse_need.brushing dummy +scoreboard objectives add gm4_horse_need.graze dummy + +scoreboard objectives add gm4_horse_potential.total dummy +scoreboard objectives add gm4_horse_potential.realized dummy + +scoreboard objectives add gm4_horse.stamina_cap dummy +scoreboard objectives add gm4_horse.swim_power dummy + +# constants +scoreboard players set #0 gm4_horse_data 0 +scoreboard players set #4 gm4_horse_data 4 +scoreboard players set #10 gm4_horse_data 10 +scoreboard players set #15 gm4_horse_data 15 +scoreboard players set #50 gm4_horse_data 50 +scoreboard players set #100 gm4_horse_data 100 +scoreboard players set #1000 gm4_horse_data 1000 +scoreboard players set #1405 gm4_horse_data 1405 +scoreboard players set #4216 gm4_horse_data 4216 +scoreboard players set #100000 gm4_horse_data 100000 + +# Horse need caps +scoreboard players set $need_cap.graze gm4_horse_data 2160 +scoreboard players set $need_cap.brushing gm4_horse_data 1500 +scoreboard players set $need_cap.on_leash gm4_horse_data 1125 +scoreboard players set $need_cap.stamina_start gm4_horse_data 75 +scoreboard players set $need_cap.stamina_step gm4_horse_data 25 +scoreboard players set $need_cap.fed_treat gm4_horse_data 15 + +schedule function gm4_horsemanship:tick 1t +schedule function gm4_horsemanship:main 1t + +#$moduleUpdateList diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/level/init_horse.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/level/init_horse.mcfunction new file mode 100644 index 0000000000..6b9d4788bb --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/level/init_horse.mcfunction @@ -0,0 +1,53 @@ +# init a new gm4_horse +# @s = new gm4_horse +# at @s +# run from tame_horse + +tag @s add gm4_horse + +# | Max Health & Scale +execute store result storage gm4_horse:temp attribute.health_remove_base float -0.01 run attribute @s max_health base get 100 +# 0.8 - 1.2 +execute store result score $scale gm4_horse_data run attribute @s scale base get 100 +execute store result score $scale_add gm4_horse_data run attribute @s max_health base get 2.666666666 +scoreboard players remove $scale gm4_horse_data 160 +scoreboard players operation $scale gm4_horse_data += $scale_add gm4_horse_data +execute store result storage gm4_horse:temp attribute.scale float 0.01 run scoreboard players get $scale gm4_horse_data + +# | Movement Speed +execute store result storage gm4_horse:temp attribute.speed_remove_base float -0.00001 run attribute @s movement_speed base get 100000 +execute store result score $speed.start gm4_horse_data run attribute @s movement_speed base get 100000 +scoreboard players operation @s gm4_horse_speed_step = $speed.start gm4_horse_data +scoreboard players operation @s gm4_horse_speed_step *= #1405 gm4_horse_data +scoreboard players operation @s gm4_horse_speed_step /= #1000 gm4_horse_data + +scoreboard players add $speed.start gm4_horse_data 20000 +scoreboard players operation $speed.start gm4_horse_data *= #1000 gm4_horse_data +scoreboard players operation $speed.start gm4_horse_data /= #4216 gm4_horse_data +execute store result storage gm4_horse:temp attribute.speed_start float 0.00001 run scoreboard players get $speed.start gm4_horse_data + +scoreboard players operation @s gm4_horse_speed_step -= $speed.start gm4_horse_data +scoreboard players operation @s gm4_horse_speed_step /= #15 gm4_horse_data + +# | Jump Strength (uses a lower scale to avoid going over the int limit) +execute store result storage gm4_horse:temp attribute.jump_remove_base float -0.00001 run attribute @s jump_strength base get 100000 +execute store result score $jump.start gm4_horse_data run attribute @s jump_strength base get 10000 +scoreboard players set @s gm4_horse_jump_step 21000 +scoreboard players operation @s gm4_horse_jump_step -= $jump.start gm4_horse_data +scoreboard players operation @s gm4_horse_jump_step *= $jump.start gm4_horse_data +scoreboard players operation @s gm4_horse_jump_step /= #1000 gm4_horse_data + +scoreboard players remove $jump.start gm4_horse_data 4000 +scoreboard players operation $jump.start gm4_horse_data *= #10 gm4_horse_data +scoreboard players operation $jump.start gm4_horse_data /= #4 gm4_horse_data +scoreboard players add $jump.start gm4_horse_data 44500 +execute store result storage gm4_horse:temp attribute.jump_start float 0.00001 run scoreboard players get $jump.start gm4_horse_data + +scoreboard players operation @s gm4_horse_jump_step -= $jump.start gm4_horse_data +scoreboard players operation @s gm4_horse_jump_step /= #15 gm4_horse_data + +# modify attributes from storage +function gm4_horsemanship:level/init_horse_eval with storage gm4_horse:temp attribute +data remove storage gm4_horse:temp attribute + +effect give @s regeneration 4 9 true diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/level/init_horse_eval.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/level/init_horse_eval.mcfunction new file mode 100644 index 0000000000..c2e5f2d72d --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/level/init_horse_eval.mcfunction @@ -0,0 +1,16 @@ +# eval stats on this new horse +# @s = new gm4_horse +# at @s +# run from level/init_horse + +$attribute @s max_health modifier add gm4_horse.health.remove_base $(health_remove_base) add_value +$attribute @s movement_speed modifier add gm4_horse.speed.remove_base $(speed_remove_base) add_value +$attribute @s jump_strength modifier add gm4_horse.jump.remove_base $(jump_remove_base) add_value + +attribute @s max_health modifier add gm4_horse.untamed 10 add_value + +attribute @s max_health modifier add gm4_horse.health 11.01 add_value +$attribute @s movement_speed modifier add gm4_horse.speed $(speed_start) add_value +$attribute @s jump_strength modifier add gm4_horse.jump $(jump_start) add_value + +$attribute @s scale modifier add gm4_horse.scale $(scale) add_value diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/level/level_up.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/level/level_up.mcfunction new file mode 100644 index 0000000000..860ae84656 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/level/level_up.mcfunction @@ -0,0 +1,53 @@ +# apply level-up to gm4_horse +# @s = gm4_horse +# at @s +# run from horse_processsing/general + +# | Max Health +execute store result score $health gm4_horse_data run attribute @s max_health modifier value get gm4_horse.health 10 +scoreboard players add $health gm4_horse_data 20 +execute store result storage gm4_horse:temp attribute.health float 0.1 run scoreboard players get $health gm4_horse_data + +# | Movement Speed +execute store result score $speed gm4_horse_data run attribute @s movement_speed modifier value get gm4_horse.speed 100000 +scoreboard players operation $speed gm4_horse_data += @s gm4_horse_speed_step +execute store result storage gm4_horse:temp attribute.speed float 0.00001 run scoreboard players get $speed gm4_horse_data + +# | Jump Strength +execute store result score $jump gm4_horse_data run attribute @s jump_strength modifier value get gm4_horse.jump 100000 +scoreboard players operation $jump gm4_horse_data += @s gm4_horse_jump_step +execute store result storage gm4_horse:temp attribute.jump float 0.00001 run scoreboard players get $jump gm4_horse_data + +# | Scores +scoreboard players add @s gm4_horse_level 1 +scoreboard players operation @s gm4_horse.stamina_cap += $need_cap.stamina_step gm4_horse_data +scoreboard players operation @s gm4_horse_need.stamina += $need_cap.stamina_step gm4_horse_data +scoreboard players set @s gm4_horse_experience 0 + +# set new needed experience +execute if score @s gm4_horse_level matches 1 run scoreboard players set @s gm4_horse_experience 7500 +execute if score @s gm4_horse_level matches 2 run scoreboard players set @s gm4_horse_experience 10000 +execute if score @s gm4_horse_level matches 3 run scoreboard players set @s gm4_horse_experience 15000 +execute if score @s gm4_horse_level matches 4 run scoreboard players set @s gm4_horse_experience 22500 +execute if score @s gm4_horse_level matches 5 run scoreboard players set @s gm4_horse_experience 32500 +execute if score @s gm4_horse_level matches 6 run scoreboard players set @s gm4_horse_experience 45000 +execute if score @s gm4_horse_level matches 7 run scoreboard players set @s gm4_horse_experience 60000 +execute if score @s gm4_horse_level matches 8 run scoreboard players set @s gm4_horse_experience 82500 +execute if score @s gm4_horse_level matches 9 run scoreboard players set @s gm4_horse_experience 112500 +execute if score @s gm4_horse_level matches 10 run scoreboard players set @s gm4_horse_experience 150000 +execute if score @s gm4_horse_level matches 11 run scoreboard players set @s gm4_horse_experience 210000 +execute if score @s gm4_horse_level matches 12 run scoreboard players set @s gm4_horse_experience 300000 +execute if score @s gm4_horse_level matches 13 run scoreboard players set @s gm4_horse_experience 450000 +execute if score @s gm4_horse_level matches 14 run scoreboard players set @s gm4_horse_experience 675000 + +# modify attributes from storage +attribute @s max_health modifier remove gm4_horse.health +attribute @s movement_speed modifier remove gm4_horse.speed +attribute @s jump_strength modifier remove gm4_horse.jump +function gm4_horsemanship:level/level_up_eval with storage gm4_horse:temp attribute +data remove storage gm4_horse:temp attribute + +# vfx +particle happy_villager ~ ~1 ~ 1 1 1 0 16 +playsound entity.player.levelup neutral @a ~ ~1 ~ 0.7 1.6 +effect give @s minecraft:regeneration 3 1 diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/level/level_up_eval.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/level/level_up_eval.mcfunction new file mode 100644 index 0000000000..feb7f55545 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/level/level_up_eval.mcfunction @@ -0,0 +1,8 @@ +# eval stats on this new horse +# @s = new gm4_horse +# at @s +# run from level/init_horse + +$attribute @s max_health modifier add gm4_horse.health $(health) add_value +$attribute @s movement_speed modifier add gm4_horse.speed $(speed) add_value +$attribute @s jump_strength modifier add gm4_horse.jump $(jump) add_value diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/level/tame_horse.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/level/tame_horse.mcfunction new file mode 100644 index 0000000000..fd926d08de --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/level/tame_horse.mcfunction @@ -0,0 +1,13 @@ + +tag @s add gm4_horse.tamed + +scoreboard players set @s gm4_horse_level 0 +scoreboard players set @s gm4_horse_experience 6000 +scoreboard players operation @s gm4_horse.stamina_cap = $need_cap.stamina_start gm4_horse_data +scoreboard players operation @s gm4_horse_need.stamina = @s gm4_horse.stamina_cap +scoreboard players operation @s gm4_horse_need.graze = $need_cap.graze gm4_horse_data +scoreboard players operation @s gm4_horse_need.brushing = $need_cap.brushing gm4_horse_data +scoreboard players operation @s gm4_horse_need.fed_treat = $need_cap.fed_treat gm4_horse_data +scoreboard players operation @s gm4_horse_need.on_leash = $need_cap.on_leash gm4_horse_data + +attribute @s max_health modifier remove gm4_horse.untamed diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/main.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/main.mcfunction new file mode 100644 index 0000000000..119cf64f23 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/main.mcfunction @@ -0,0 +1,14 @@ +schedule function gm4_horsemanship:main 16t + +# init new horses +execute as @e[type=#gm4_horsemanship:trainable,tag=!gm4_horse,tag=!smithed.entity] run function gm4_horsemanship:level/init_horse + +# horse processing +execute as @e[type=#gm4_horsemanship:trainable,tag=gm4_horse.tamed] at @s run function gm4_horsemanship:horse_processing/general +scoreboard players reset @a gm4_horse_riding + +# horse grazing +execute as @e[type=#gm4_horsemanship:trainable,tag=!gm4_horse.grazing,nbt={EatingHaystack:1b}] run function gm4_horsemanship:need/graze/start + +# TEMP DEV COMMAND - TODO: remove +execute as @a[tag=gm4_horse_dev] at @s as @e[type=#gm4_horsemanship:trainable,tag=gm4_horse.tamed,limit=1,sort=nearest] run function gm4_horsemanship:dev/log diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/need/care/brush/apply.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/need/care/brush/apply.mcfunction new file mode 100644 index 0000000000..d689c95cc8 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/need/care/brush/apply.mcfunction @@ -0,0 +1,13 @@ +# apply brushing effects +# @s = gm4_horse being brushed +# at @s +# run from need/care/brush/process + +# vfx +particle block{block_state:"dirt"} ~ ~0.6 ~ 0.4 1 0.4 0 12 +execute if score @s gm4_horse_need.brushing matches 1375.. run playsound minecraft:entity.horse.ambient neutral @a ~ ~ ~ 2 0.7 +execute at @p[tag=gm4_horse_self] run playsound item.brush.brushing.generic player @a ~ ~ ~ 3 0 + +# scoreboards +scoreboard players add @s gm4_horse_need.brushing 75 +scoreboard players operation @s gm4_horse_need.brushing < $need_cap.brushing gm4_horse_data diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/need/care/brush/process.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/need/care/brush/process.mcfunction new file mode 100644 index 0000000000..b1effe7d9a --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/need/care/brush/process.mcfunction @@ -0,0 +1,15 @@ +# process gm4_horses being brushed +# @s = player riding the gm4_horse +# at @s (before mounting) +# run from start_riding_horse + +# brushing effect +tag @s add gm4_horse_self +execute on vehicle unless score @s gm4_horse_need.brushing matches 1450.. at @s run function gm4_horsemanship:need/care/brush/apply +tag @s remove gm4_horse_self + +# restore player location +function gm4_horsemanship:riding/restore_location/prep + +# mark this interaction as resolved +scoreboard players set $interaction_resolved gm4_horse_data 1 diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/need/food/check_horse.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/check_horse.mcfunction new file mode 100644 index 0000000000..d9a2fb9e99 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/check_horse.mcfunction @@ -0,0 +1,8 @@ +# check if this gm4_horse was fed by checking if player is looking at it +# @s = gm4_horse +# at @s +# run from need/food/feed_original_food + +tag @s add gm4_horse_check +execute as @p[tag=gm4_horse_check_player] if predicate gm4_horsemanship:check_horse_looking_at run tag @e[type=#gm4_horsemanship:trainable,tag=gm4_horse_check,distance=..8,limit=1] add gm4_horse_target +tag @s remove gm4_horse_check diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/need/food/feed_added_food.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/feed_added_food.mcfunction new file mode 100644 index 0000000000..b453a47f01 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/feed_added_food.mcfunction @@ -0,0 +1,29 @@ +# check feeding the gm4_horse a food item added by this module +# @s = player feeding the gm4_horse +# at @s +# run from start_riding_horse + +# check which item was fed +scoreboard players set $food_processed gm4_horse_data 0 +item replace block 29999998 1 7134 container.0 from entity @s weapon.mainhand +data modify storage gm4_horsemanship:temp item_id set from block 29999998 1 7134 Items[{Slot:0b}].id +execute if score $food_processed gm4_horse_data matches 0 if data storage gm4_horsemanship:temp {item_id:"minecraft:short_grass"} on vehicle at @s run function gm4_horsemanship:need/food/type/short_grass +execute if score $food_processed gm4_horse_data matches 0 if data storage gm4_horsemanship:temp {item_id:"minecraft:carrot"} on vehicle at @s run function gm4_horsemanship:need/food/type/carrot +execute if score $food_processed gm4_horse_data matches 0 if data storage gm4_horsemanship:temp {item_id:"minecraft:sweet_berries"} on vehicle at @s run function gm4_horsemanship:need/food/type/sweet_berries +execute if score $food_processed gm4_horse_data matches 0 if data storage gm4_horsemanship:temp {item_id:"minecraft:glow_berries"} on vehicle at @s run function gm4_horsemanship:need/food/type/glow_berries +execute if score $food_processed gm4_horse_data matches 0 if data storage gm4_horsemanship:temp {item_id:"minecraft:chorus_fruit"} on vehicle at @s run function gm4_horsemanship:need/food/type/chorus_fruit +execute if score $food_processed gm4_horse_data matches 0 if data storage gm4_horsemanship:temp {item_id:"minecraft:dried_kelp"} on vehicle at @s run function gm4_horsemanship:need/food/type/dried_kelp +execute if score $food_processed gm4_horse_data matches 0 if data storage gm4_horsemanship:temp {item_id:"minecraft:melon_slice"} on vehicle at @s run function gm4_horsemanship:need/food/type/melon_slice +execute if score $food_processed gm4_horse_data matches 0 if data storage gm4_horsemanship:temp {item_id:"minecraft:beetroot"} on vehicle at @s run function gm4_horsemanship:need/food/type/beetroot +execute if score $food_processed gm4_horse_data matches 0 if data storage gm4_horsemanship:temp {item_id:"minecraft:bread"} on vehicle at @s run function gm4_horsemanship:need/food/type/bread +execute if score $food_processed gm4_horse_data matches 0 if data storage gm4_horsemanship:temp {item_id:"minecraft:baked_potato"} on vehicle at @s run function gm4_horsemanship:need/food/type/baked_potato +data remove storage gm4_horsemanship:temp item_id + +# playsound and remove the fed item +execute on vehicle at @s run playsound entity.horse.eat neutral @a ~ ~ ~ 1 1 +item modify entity @s[gamemode=!creative] weapon.mainhand {"function": "minecraft:set_count","count":-1,"add":true} + +execute on vehicle run scoreboard players operation @s[tag=gm4_horse.tamed] gm4_horse_need.fed_treat = $need_cap.fed_treat gm4_horse_data + +# restore player location +function gm4_horsemanship:riding/restore_location/prep diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/need/food/feed_original_food.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/feed_original_food.mcfunction new file mode 100644 index 0000000000..2fba9ef9a0 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/feed_original_food.mcfunction @@ -0,0 +1,22 @@ +# check feeding the gm4_horse an actual food item +# @s = player feeding the gm4_horse +# at @s +# run from advancement feed_horse + +# check nearby horses to find the one that was fed +tag @s add gm4_horse_check_player +execute as @e[type=#gm4_horsemanship:trainable,distance=..8] run function gm4_horsemanship:need/food/check_horse +tag @s remove gm4_horse_check_player + +execute as @e[type=#gm4_horsemanship:trainable,tag=gm4_horse_target,distance=..8,limit=1] run scoreboard players operation @s[tag=gm4_horse.tamed] gm4_horse_need.fed_treat = $need_cap.fed_treat gm4_horse_data + +# check advancement criteria to find used food item +scoreboard players set $food_processed gm4_horse_data 0 +execute if score $food_processed gm4_horse_data matches 0 if entity @s[advancements={gm4_horsemanship:feed_horse={apple=true}}] as @e[type=#gm4_horsemanship:trainable,tag=gm4_horse_target,distance=..8,limit=1] at @s run function gm4_horsemanship:need/food/type/apple +execute if score $food_processed gm4_horse_data matches 0 if entity @s[advancements={gm4_horsemanship:feed_horse={golden_apple=true}}] as @e[type=#gm4_horsemanship:trainable,tag=gm4_horse_target,distance=..8,limit=1] at @s run function gm4_horsemanship:need/food/type/golden_apple +execute if score $food_processed gm4_horse_data matches 0 if entity @s[advancements={gm4_horsemanship:feed_horse={enchanted_golden_apple=true}}] as @e[type=#gm4_horsemanship:trainable,tag=gm4_horse_target,distance=..8,limit=1] at @s run function gm4_horsemanship:need/food/type/enchanted_golden_apple +execute if score $food_processed gm4_horse_data matches 0 if entity @s[advancements={gm4_horsemanship:feed_horse={golden_carrot=true}}] as @e[type=#gm4_horsemanship:trainable,tag=gm4_horse_target,distance=..8,limit=1] at @s run function gm4_horsemanship:need/food/type/golden_carrot +execute if score $food_processed gm4_horse_data matches 0 if entity @s[advancements={gm4_horsemanship:feed_horse={sugar=true}}] as @e[type=#gm4_horsemanship:trainable,tag=gm4_horse_target,distance=..8,limit=1] at @s run function gm4_horsemanship:need/food/type/sugar +execute if score $food_processed gm4_horse_data matches 0 if entity @s[advancements={gm4_horsemanship:feed_horse={wheat=true}}] as @e[type=#gm4_horsemanship:trainable,tag=gm4_horse_target,distance=..8,limit=1] at @s run function gm4_horsemanship:need/food/type/wheat +execute if score $food_processed gm4_horse_data matches 0 if entity @s[advancements={gm4_horsemanship:feed_horse={hay_block=true}}] as @e[type=#gm4_horsemanship:trainable,tag=gm4_horse_target,distance=..8,limit=1] at @s run function gm4_horsemanship:need/food/type/hay_block +advancement revoke @s only gm4_horsemanship:feed_horse diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/apple.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/apple.mcfunction new file mode 100644 index 0000000000..52d048470f --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/apple.mcfunction @@ -0,0 +1,10 @@ +# process horse being fed food +# @s = gm4_horse +# at @s +# run from need/food/feed_original_food + +tag @s remove gm4_horse_target + +tag @s add gm4_horse.check_health + +scoreboard players set $food_processed gm4_horse_data 1 diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/baked_potato.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/baked_potato.mcfunction new file mode 100644 index 0000000000..8aeeff96b8 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/baked_potato.mcfunction @@ -0,0 +1,6 @@ +# process horse being fed food +# @s = gm4_horse +# at @s +# run from need/food/feed_added_food + +scoreboard players set $food_processed gm4_horse_data 1 diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/beetroot.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/beetroot.mcfunction new file mode 100644 index 0000000000..8aeeff96b8 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/beetroot.mcfunction @@ -0,0 +1,6 @@ +# process horse being fed food +# @s = gm4_horse +# at @s +# run from need/food/feed_added_food + +scoreboard players set $food_processed gm4_horse_data 1 diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/bread.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/bread.mcfunction new file mode 100644 index 0000000000..8aeeff96b8 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/bread.mcfunction @@ -0,0 +1,6 @@ +# process horse being fed food +# @s = gm4_horse +# at @s +# run from need/food/feed_added_food + +scoreboard players set $food_processed gm4_horse_data 1 diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/carrot.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/carrot.mcfunction new file mode 100644 index 0000000000..8aeeff96b8 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/carrot.mcfunction @@ -0,0 +1,6 @@ +# process horse being fed food +# @s = gm4_horse +# at @s +# run from need/food/feed_added_food + +scoreboard players set $food_processed gm4_horse_data 1 diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/chorus_fruit.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/chorus_fruit.mcfunction new file mode 100644 index 0000000000..8aeeff96b8 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/chorus_fruit.mcfunction @@ -0,0 +1,6 @@ +# process horse being fed food +# @s = gm4_horse +# at @s +# run from need/food/feed_added_food + +scoreboard players set $food_processed gm4_horse_data 1 diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/dried_kelp.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/dried_kelp.mcfunction new file mode 100644 index 0000000000..8aeeff96b8 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/dried_kelp.mcfunction @@ -0,0 +1,6 @@ +# process horse being fed food +# @s = gm4_horse +# at @s +# run from need/food/feed_added_food + +scoreboard players set $food_processed gm4_horse_data 1 diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/enchanted_golden_apple.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/enchanted_golden_apple.mcfunction new file mode 100644 index 0000000000..c1dfc342c2 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/enchanted_golden_apple.mcfunction @@ -0,0 +1,12 @@ +# process horse being fed food +# @s = gm4_horse +# at @s +# run from need/food/feed_original_food + +tag @s remove gm4_horse_target + +tag @s add gm4_horse.check_health + +scoreboard players set $food_processed gm4_horse_data 1 + +# Also enables breeding diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/glow_berries.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/glow_berries.mcfunction new file mode 100644 index 0000000000..8aeeff96b8 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/glow_berries.mcfunction @@ -0,0 +1,6 @@ +# process horse being fed food +# @s = gm4_horse +# at @s +# run from need/food/feed_added_food + +scoreboard players set $food_processed gm4_horse_data 1 diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/golden_apple.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/golden_apple.mcfunction new file mode 100644 index 0000000000..c1dfc342c2 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/golden_apple.mcfunction @@ -0,0 +1,12 @@ +# process horse being fed food +# @s = gm4_horse +# at @s +# run from need/food/feed_original_food + +tag @s remove gm4_horse_target + +tag @s add gm4_horse.check_health + +scoreboard players set $food_processed gm4_horse_data 1 + +# Also enables breeding diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/golden_carrot.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/golden_carrot.mcfunction new file mode 100644 index 0000000000..c1dfc342c2 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/golden_carrot.mcfunction @@ -0,0 +1,12 @@ +# process horse being fed food +# @s = gm4_horse +# at @s +# run from need/food/feed_original_food + +tag @s remove gm4_horse_target + +tag @s add gm4_horse.check_health + +scoreboard players set $food_processed gm4_horse_data 1 + +# Also enables breeding diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/hay_block.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/hay_block.mcfunction new file mode 100644 index 0000000000..52d048470f --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/hay_block.mcfunction @@ -0,0 +1,10 @@ +# process horse being fed food +# @s = gm4_horse +# at @s +# run from need/food/feed_original_food + +tag @s remove gm4_horse_target + +tag @s add gm4_horse.check_health + +scoreboard players set $food_processed gm4_horse_data 1 diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/melon_slice.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/melon_slice.mcfunction new file mode 100644 index 0000000000..8aeeff96b8 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/melon_slice.mcfunction @@ -0,0 +1,6 @@ +# process horse being fed food +# @s = gm4_horse +# at @s +# run from need/food/feed_added_food + +scoreboard players set $food_processed gm4_horse_data 1 diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/short_grass.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/short_grass.mcfunction new file mode 100644 index 0000000000..8aeeff96b8 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/short_grass.mcfunction @@ -0,0 +1,6 @@ +# process horse being fed food +# @s = gm4_horse +# at @s +# run from need/food/feed_added_food + +scoreboard players set $food_processed gm4_horse_data 1 diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/sugar.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/sugar.mcfunction new file mode 100644 index 0000000000..52d048470f --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/sugar.mcfunction @@ -0,0 +1,10 @@ +# process horse being fed food +# @s = gm4_horse +# at @s +# run from need/food/feed_original_food + +tag @s remove gm4_horse_target + +tag @s add gm4_horse.check_health + +scoreboard players set $food_processed gm4_horse_data 1 diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/sweet_berries.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/sweet_berries.mcfunction new file mode 100644 index 0000000000..8aeeff96b8 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/sweet_berries.mcfunction @@ -0,0 +1,6 @@ +# process horse being fed food +# @s = gm4_horse +# at @s +# run from need/food/feed_added_food + +scoreboard players set $food_processed gm4_horse_data 1 diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/wheat.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/wheat.mcfunction new file mode 100644 index 0000000000..52d048470f --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/need/food/type/wheat.mcfunction @@ -0,0 +1,10 @@ +# process horse being fed food +# @s = gm4_horse +# at @s +# run from need/food/feed_original_food + +tag @s remove gm4_horse_target + +tag @s add gm4_horse.check_health + +scoreboard players set $food_processed gm4_horse_data 1 diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/need/graze/cancel.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/need/graze/cancel.mcfunction new file mode 100644 index 0000000000..dffe6bddd0 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/need/graze/cancel.mcfunction @@ -0,0 +1,8 @@ +# cancel grazing gm4_horses if they are being ridden +# @s = gm4_horse +# at @s +# run from horse_processsing/general + +tag @s remove gm4_horse.grazing +tag @s remove gm4_horse.force_graze +data modify entity @s EatingHaystack set value 0b diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/need/graze/complete.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/need/graze/complete.mcfunction new file mode 100644 index 0000000000..9055688e7c --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/need/graze/complete.mcfunction @@ -0,0 +1,26 @@ +# process (gm4_)horses that completed grazing +# @s = (gm4_)horse +# at @s +# run from need/graze/tick + +tag @s remove gm4_horse.grazing +tag @s remove gm4_horse.force_graze + +# if this is a baby horse accelerate its growth by 10% (same effect as on sheep) +execute store result score $Age gm4_horse_data run data get entity @s Age +execute if score $Age gm4_horse_data matches ..-1 store result entity @s Age int 0.9 run data get entity @s Age + +# if block was hay bale grant more score and don't run rest +execute if block ~ ~-1 ~ hay_block run return run function gm4_horsemanship:need/graze/hay_block + +# if this is a gm4_horse fill its grazing needs +execute if entity @s[tag=gm4_horse.tamed] run scoreboard players add @s gm4_horse_need.graze 360 +scoreboard players operation @s[tag=gm4_horse.tamed] gm4_horse_need.graze < $need_cap.graze gm4_horse_data + +# break grass (block) if mobGriefing is enabled +# horses can only eat grass or grass blocks but not flowers or tall grass, similar to sheep +execute store result score $mobGriefing gm4_horse_data run gamerule mobGriefing +execute if score $mobGriefing gm4_horse_data matches 1 unless block ~ ~ ~ short_grass run fill ~ ~ ~ ~ ~-1 ~ dirt replace grass_block +execute if score $mobGriefing gm4_horse_data matches 1 if block ~ ~ ~ short_grass run fill ~ ~ ~ ~ ~ ~ air replace short_grass +playsound minecraft:block.grass.break block @a ~ ~ ~ 1 1 +particle block{block_state:"grass_block"} ~ ~ ~ 0.2 0.05 0.2 0 4 diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/need/graze/force.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/need/graze/force.mcfunction new file mode 100644 index 0000000000..455fd6e956 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/need/graze/force.mcfunction @@ -0,0 +1,7 @@ +# force starving gm4_horse to graze while being mounted +# @s = gm4_horse +# at @s +# run from horse_processsing/general + +tag @s add gm4_horse.force_graze +data modify entity @s EatingHaystack set value 1b diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/need/graze/hay_block.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/need/graze/hay_block.mcfunction new file mode 100644 index 0000000000..3519366931 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/need/graze/hay_block.mcfunction @@ -0,0 +1,11 @@ +# process (gm4_)horses that completed grazing a hay block +# @s = (gm4_)horse +# at @s +# run from need/graze/complete + +# if this is a gm4_horse fill its grazing need to 1050 +execute if entity @s[tag=gm4_horse.tamed] run scoreboard players set @s[scores={gm4_horse_need.graze=..1049}] gm4_horse_need.graze 1050 + +# particles and sound +playsound minecraft:block.grass.break block @a ~ ~ ~ 1 1 +particle block{block_state:"hay_block"} ~ ~ ~ 0.2 0.05 0.2 0 4 diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/need/graze/start.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/need/graze/start.mcfunction new file mode 100644 index 0000000000..44bdcff917 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/need/graze/start.mcfunction @@ -0,0 +1,7 @@ +# mark this gm4_horse as grazing +# @s = gm4_horse +# at @s +# run from main + +schedule function gm4_horsemanship:need/graze/tick 1t +tag @s add gm4_horse.grazing diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/need/graze/tick.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/need/graze/tick.mcfunction new file mode 100644 index 0000000000..faee4619b1 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/need/graze/tick.mcfunction @@ -0,0 +1,8 @@ +# process grazing (gm4_)horses +# @s = unspecified +# at unspecified +# schedule from need/graze/start +# schedule from here + +execute as @e[type=#gm4_horsemanship:trainable,tag=gm4_horse.grazing,nbt={EatingHaystack:0b}] at @s run function gm4_horsemanship:need/graze/complete +execute if entity @e[type=#gm4_horsemanship:trainable,tag=gm4_horse.grazing] run schedule function gm4_horsemanship:need/graze/tick 1t diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/need/social/_.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/need/social/_.mcfunction new file mode 100644 index 0000000000..e69de29bb2 diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/riding/restore_location/prep.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/riding/restore_location/prep.mcfunction new file mode 100644 index 0000000000..0cb58aaeac --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/riding/restore_location/prep.mcfunction @@ -0,0 +1,9 @@ +# prep restoring the location of this player +# @s = player that just mounted a gm4_horse +# at @s (before mounting) +# run from need/care/brush/process +# run from need/food/feed_added_food + +tag @s add gm4_horse_self +execute summon marker run function gm4_horsemanship:riding/restore_location/restore +tag @s remove gm4_horse_self diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/riding/restore_location/restore.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/riding/restore_location/restore.mcfunction new file mode 100644 index 0000000000..df6a31200e --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/riding/restore_location/restore.mcfunction @@ -0,0 +1,7 @@ +# restore player location to before mounting +# @s = marker +# at @s +# run from riding/restore_location/prep + +execute positioned as @s run tp @p[tag=gm4_horse_self] ~ ~ ~ +kill @s diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/riding/stamina/rested.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/riding/stamina/rested.mcfunction new file mode 100644 index 0000000000..061d2965dc --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/riding/stamina/rested.mcfunction @@ -0,0 +1,8 @@ +# remove tired horse mark once needs are met again +# @s = gm4_horse +# at @s +# run from horse_processsing/general + +attribute @s movement_speed modifier remove gm4_horse.speed.tired +attribute @s jump_strength modifier remove gm4_horse.jump.tired +tag @s remove gm4_horse.tired diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/riding/stamina/tired.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/riding/stamina/tired.mcfunction new file mode 100644 index 0000000000..7926958e23 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/riding/stamina/tired.mcfunction @@ -0,0 +1,8 @@ +# mark horse as tired if its needs are not met +# @s = gm4_horse +# at @s +# run from horse_processsing/general + +attribute @s movement_speed modifier add gm4_horse.speed.tired -0.5 add_multiplied_total +attribute @s jump_strength modifier add gm4_horse.jump.tired -0.5 add_multiplied_total +tag @s add gm4_horse.tired diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/riding/swim/process.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/riding/swim/process.mcfunction new file mode 100644 index 0000000000..5455a15eb8 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/riding/swim/process.mcfunction @@ -0,0 +1,11 @@ + +scoreboard players set $mounted gm4_horse_data 0 +execute store success score $mounted gm4_horse_data on controller if entity @s[type=player] + + +execute if score $mounted gm4_horse_data matches 1 if entity @s[tag=!gm4_horse.swimming] if block ~ ~0.6 ~ water run tag @s add gm4_horse.swimming +execute if score $mounted gm4_horse_data matches 1 if entity @s[tag=gm4_horse.swimming] unless block ~ ~0.35 ~ water run tag @s remove gm4_horse.swimming +execute if score $mounted gm4_horse_data matches 0 if entity @s[tag=gm4_horse.swimming] run tag @s remove gm4_horse.swimming + +scoreboard players set @s[tag=!gm4_horse.swimming] gm4_horse.swim_power 0 +execute if entity @s[tag=gm4_horse.swimming,tag=!gm4_horse.tired] run function gm4_horsemanship:riding/swim/upwards diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/riding/swim/upwards.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/riding/swim/upwards.mcfunction new file mode 100644 index 0000000000..e117b1b665 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/riding/swim/upwards.mcfunction @@ -0,0 +1,7 @@ + +execute store result score $motion_y gm4_horse_data run data get entity @s Motion[1] 200 + +scoreboard players add @s[scores={gm4_horse.swim_power=..19}] gm4_horse.swim_power 1 + +execute if score $motion_y gm4_horse_data matches ..0 run scoreboard players operation $motion_y gm4_horse_data += @s gm4_horse.swim_power +execute store result entity @s Motion[1] double 0.005 run scoreboard players get $motion_y gm4_horse_data diff --git a/gm4_horsemanship/data/gm4_horsemanship/function/tick.mcfunction b/gm4_horsemanship/data/gm4_horsemanship/function/tick.mcfunction new file mode 100644 index 0000000000..b74abe19f1 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/function/tick.mcfunction @@ -0,0 +1,3 @@ +schedule function gm4_horsemanship:tick 1t + +execute as @e[type=#gm4_horsemanship:trainable,tag=gm4_horse.tamed] at @s run function gm4_horsemanship:riding/swim/process diff --git a/gm4_horsemanship/data/gm4_horsemanship/predicate/check_horse_looking_at.json b/gm4_horsemanship/data/gm4_horsemanship/predicate/check_horse_looking_at.json new file mode 100644 index 0000000000..69c8d45967 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/predicate/check_horse_looking_at.json @@ -0,0 +1,13 @@ +{ + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type_specific": { + "type": "player", + "looking_at": { + "type": "#gm4_horsemanship:trainable", + "nbt": "{Tags:[\"gm4_horse_check\"]}" + } + } + } +} diff --git a/gm4_horsemanship/data/gm4_horsemanship/predicate/holding_brush.json b/gm4_horsemanship/data/gm4_horsemanship/predicate/holding_brush.json new file mode 100644 index 0000000000..be8124b229 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/predicate/holding_brush.json @@ -0,0 +1,13 @@ +{ + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "equipment": { + "mainhand": { + "items": [ + "minecraft:brush" + ] + } + } + } +} diff --git a/gm4_horsemanship/data/gm4_horsemanship/predicate/holding_food.json b/gm4_horsemanship/data/gm4_horsemanship/predicate/holding_food.json new file mode 100644 index 0000000000..dfbd928109 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/predicate/holding_food.json @@ -0,0 +1,11 @@ +{ + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "equipment": { + "mainhand": { + "items": "#gm4_horsemanship:added_food" + } + } + } +} diff --git a/gm4_horsemanship/data/gm4_horsemanship/tags/block/can_eat_through.json b/gm4_horsemanship/data/gm4_horsemanship/tags/block/can_eat_through.json new file mode 100644 index 0000000000..c55d1d1db2 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/tags/block/can_eat_through.json @@ -0,0 +1,6 @@ +{ + "values": [ + "#gm4:no_collision", + "snow" + ] +} diff --git a/gm4_horsemanship/data/gm4_horsemanship/tags/entity_type/trainable.json b/gm4_horsemanship/data/gm4_horsemanship/tags/entity_type/trainable.json new file mode 100644 index 0000000000..626ac89312 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/tags/entity_type/trainable.json @@ -0,0 +1,7 @@ +{ + "values": [ + "minecraft:donkey", + "minecraft:horse", + "minecraft:mule" + ] +} diff --git a/gm4_horsemanship/data/gm4_horsemanship/tags/item/added_food.json b/gm4_horsemanship/data/gm4_horsemanship/tags/item/added_food.json new file mode 100644 index 0000000000..adf8942545 --- /dev/null +++ b/gm4_horsemanship/data/gm4_horsemanship/tags/item/added_food.json @@ -0,0 +1,14 @@ +{ + "values": [ + "minecraft:short_grass", + "minecraft:carrot", + "minecraft:sweet_berries", + "minecraft:glow_berries", + "minecraft:chorus_fruit", + "minecraft:dried_kelp", + "minecraft:melon_slice", + "minecraft:beetroot", + "minecraft:bread", + "minecraft:baked_potato" + ] +}