diff --git a/src/generated/resources/assets/anvilcraft/lang/en_ud.json b/src/generated/resources/assets/anvilcraft/lang/en_ud.json index 5d87220a88..8e9a118f3e 100644 --- a/src/generated/resources/assets/anvilcraft/lang/en_ud.json +++ b/src/generated/resources/assets/anvilcraft/lang/en_ud.json @@ -7,6 +7,12 @@ "advancements.anvilcraft.anvil_accelerator.title": "ɹoʇɐɹǝꞁǝɔɔɐ ꞁᴉʌuⱯ", "advancements.anvilcraft.anvilon.description": "uoꞁᴉʌuɐ pǝuᴉɟuoɔ ɟo ǝdʎʇ ʎuɐ ʇɟɐɹɔ oʇ uoᴉsᴉꞁꞁoɔ ꞁᴉʌuɐ ᵷuᴉs∩", "advancements.anvilcraft.anvilon.title": "uoꞁᴉʌuⱯ", + "advancements.anvilcraft.black_hole.description": "ǝꞁoɥ ʞɔɐꞁq ɐ oʇuᴉ ʇᴉ ǝsdɐꞁꞁoɔ puɐ puǝ ǝɥʇ oʇ uoᴉʇnꞁoʌǝ s,ɹɐʇs ɐ ǝʌᴉɹᗡ", + "advancements.anvilcraft.black_hole.title": "sǝdɐɔsƎ ʇɥᵷᴉꞀ uǝʌƎ ʇoN", + "advancements.anvilcraft.cannon_fodder.description": "ʇǝuɐꞁd ǝʞᴉꞀ-pꞁɹoʍɹǝʌO uɐ ǝpᴉsuᴉ ǝsdɐꞁꞁoɔ ʎɹɐʇǝuɐꞁd ɐ oʇ ǝᴉᗡ", + "advancements.anvilcraft.cannon_fodder.title": "ɹǝppoℲ uouuɐƆ", + "advancements.anvilcraft.come_at_night.description": "ɹɐʇs ɐ ʎq pǝꞁꞁᴉʞ ʇǝ⅁", + "advancements.anvilcraft.come_at_night.title": "ʇɥᵷᴉN ʇⱯ ǝɯoƆ pꞁnoɥS no⅄", "advancements.anvilcraft.crab_claw.description": "sʍɐꞁɔ qɐɹɔ uᴉɐʇqO", "advancements.anvilcraft.crab_claw.title": "ǝɔɐɹ uoᴉʇɔǝɹɹnsǝɹ ǝɥʇ ɟo ɟꞁɐɥ uᴉM", "advancements.anvilcraft.dang.description": "ᵷuᴉʇɟɐɹɔ ꞁᴉʌuɐ ʎuɐ ɯɹoɟɹǝԀ", @@ -15,6 +21,8 @@ "advancements.anvilcraft.devourer.title": "sɹǝʇsᴉʍʇ ǝnᵷuoʇ ʎuɐɯ oo⟘", "advancements.anvilcraft.durable_goods.description": "ǝpɐɹᵷ ꞁǝǝʇs ꞁɐʎoᴚ oʇ ꞁooʇ ʎuɐ ǝpɐɹᵷd∩", "advancements.anvilcraft.durable_goods.title": "spooᵷ ǝꞁqɐɹnᗡ", + "advancements.anvilcraft.efficiency.description": "ʇɹɐdɐ ʇǝuɐꞁd ǝɥʇ ʍoꞁq puɐ ɹoʇɐʌɐɔxǝ ʇǝuɐꞁd ǝɥʇ oʇuᴉ ɹǝsɐꞁ ɐɯɯɐᵷ ɐ pǝǝℲ", + "advancements.anvilcraft.efficiency.title": "ʎɔuǝᴉɔᴉɟɟǝ ˙˙˙ʇᴉ pǝꞁꞁɐɔ ǝM", "advancements.anvilcraft.electric_allergy.description": "ɯǝʇsʎs ɹǝʍod ʇnoɥʇᴉʍ ꞁᴉʌuɐ ᵷuᴉᵷɹoɟ ꞁɐᴉʇsǝꞁǝɔ uᴉɐʇqO", "advancements.anvilcraft.electric_allergy.title": "ʎᵷɹǝꞁꞁɐ ɔᴉɹʇɔǝꞁƎ", "advancements.anvilcraft.electric_filed_rhythm.description": "pᴉɹᵷ ɹǝʍod ǝɥʇ ɟo ǝdoɔs ǝɥʇ uᴉ dǝʇS", @@ -63,10 +71,14 @@ "advancements.anvilcraft.mining_void.title": "pᴉoʌ ᵷuᴉuᴉW", "advancements.anvilcraft.networking.description": "ǝꞁod uoᴉssᴉɯsuɐɹʇ ǝɔɐꞁd puɐ ʇɟɐɹƆ", "advancements.anvilcraft.networking.title": "ᵷuᴉʞɹoʍʇǝN", + "advancements.anvilcraft.neutron_star.description": "puᴉɥǝq ɹɐʇs uoɹʇnǝu ɐ ǝʌɐǝꞁ puɐ puǝ ǝɥʇ oʇ uoᴉʇnꞁoʌǝ s,ɹɐʇs ɐ ǝʌᴉɹᗡ", + "advancements.anvilcraft.neutron_star.title": "uᴉɐʇunoW ɐ sɥᵷᴉǝM uoodsɐǝ⟘ Ɐ", "advancements.anvilcraft.new_cycle.description": "ꞁᴉʌuⱯ ᵷuᴉᵷɹoℲ ꞁɐᴉʇsǝꞁǝƆ ǝɥʇ ɯoɹɟ ɹɐǝddɐsᴉp uoᴉʇɐzᴉꞁᴉʌᴉɔ ɐ ssǝuʇᴉM", "advancements.anvilcraft.new_cycle.title": "ǝꞁɔʎƆ ʍǝN Ɐ", "advancements.anvilcraft.new_matter.description": "ɹǝʇʇɐɯ ǝʌᴉʇɐᵷǝu ɹo ɹǝʇʇɐɯ ǝsɐɥdᴉʇꞁnɯ 'ɯnᴉuɐɹn ʇɟɐɹɔ oʇ uoᴉsᴉꞁꞁoɔ ꞁᴉʌuɐ ᵷuᴉs∩", "advancements.anvilcraft.new_matter.title": "ɹǝʇʇɐW ʍǝN", + "advancements.anvilcraft.no_remnant.description": "ʇuɐuɯǝɹ ou ǝʌɐǝꞁ ʇᴉ ɥɔʇɐʍ puɐ puǝ ǝɥʇ oʇ sꞁᴉʌuɐ ssɐɯ ߈9 ɥʇᴉʍ pǝᵷɹoɟ ʎpoq ꞁɐᴉʇsǝꞁǝɔ ɐ ǝʌꞁoʌƎ", + "advancements.anvilcraft.no_remnant.title": "puᴉɥǝᗺ ʇɟǝꞀ ᵷuᴉɥʇoN", "advancements.anvilcraft.noble_metal.description": "ꞁǝǝʇs ꞁɐʎoɹ ᵷuᴉʇꞁǝɯS", "advancements.anvilcraft.noble_metal.title": "ꞁɐʇǝɯ ǝꞁqoN", "advancements.anvilcraft.not_beacon.description": "ɹoʇɔǝꞁꞁoɔ ǝᵷɹɐɥɔ ɐ ǝɔɐꞁd puɐ ʇɟɐɹƆ", @@ -933,12 +945,15 @@ "config.waila.plugin_anvilcraft.power_provider": "ɹǝʍoԀ ʇɟɐɹƆ ꞁᴉʌuⱯ", "config.waila.plugin_anvilcraft.warning_percent": "pꞁoɥsǝɹɥ⟘ ᵷuᴉuɹɐM", "curios.identifier.ionocraft_backpack": "ʞɔɐdʞɔɐᗺ ʇɟɐɹɔouoI", + "death.attack.anvilcraft.black_hole_contact": "ʇɥᵷᴉꞁ unɹʇno pꞁnoɔ ʎǝɥʇ ʇɥᵷnoɥʇ %1$s", "death.attack.anvilcraft.falling_giant_anvil": "suoᴉʇɐɹqᴉʌ punoɹᵷ ʎq pǝsnɐɔ ǝɔuɐuosǝɹ ɔᴉɯǝʇsʎs oʇ ǝnp pǝᴉp %1$s", "death.attack.anvilcraft.heater_burn": "ɹǝʇɐǝɥ ǝɥʇ ʎq ǝuop ꞁꞁǝʍ sɐʍ %1$s", "death.attack.anvilcraft.laser": "ɹǝsɐꞁ ʎq pǝɔɹǝᴉd sɐʍ %1$s", "death.attack.anvilcraft.lost_in_time": "ǝɯᴉʇ ɟo ɹǝʌᴉɹ ǝɥʇ uᴉ ʇsoꞁ sɐʍ %1$s", + "death.attack.anvilcraft.planet_contact": "sǝɔǝᴉd uᴉ 'ʇᴉɯᴉꞁ ǝɥɔoᴚ ǝɥʇ pǝɹǝʌoɔsᴉp %1$s", "death.attack.anvilcraft.planetary_collapse": "ǝsdɐꞁꞁoɔ ʎɹɐʇǝuɐꞁd ʎq pǝɯnsuoɔ sɐʍ %1$s", "death.attack.anvilcraft.plasma_jet": "˙ʞɔɐq ǝʌᴉɟ-ɥᵷᴉɥ ʇou pᴉp ʎǝɥ⟘ ˙sʇǝɾ ɐɯsɐꞁd ǝɥʇ ǝʌᴉɟ-ɥᵷᴉɥ oʇ pǝᴉɹʇ %1$s", + "death.attack.anvilcraft.star_contact": "ɐuoɹoɔ ǝɥʇ ɟo ʇɹɐd ʍou sᴉ %1$s", "effect.anvilcraft.invulnerable": "ǝꞁqɐɹǝuꞁnʌuI", "effect.anvilcraft.rage": "ǝᵷɐᴚ", "enchantment.anvilcraft.beheading": "ᵷuᴉpɐǝɥǝᗺ", diff --git a/src/generated/resources/assets/anvilcraft/lang/en_us.json b/src/generated/resources/assets/anvilcraft/lang/en_us.json index 6dfa052280..0e6ef5f83b 100644 --- a/src/generated/resources/assets/anvilcraft/lang/en_us.json +++ b/src/generated/resources/assets/anvilcraft/lang/en_us.json @@ -7,6 +7,12 @@ "advancements.anvilcraft.anvil_accelerator.title": "Anvil accelerator", "advancements.anvilcraft.anvilon.description": "Using anvil collision to craft any type of confined anvilon", "advancements.anvilcraft.anvilon.title": "Anvilon", + "advancements.anvilcraft.black_hole.description": "Drive a star's evolution to the end and collapse it into a black hole", + "advancements.anvilcraft.black_hole.title": "Not Even Light Escapes", + "advancements.anvilcraft.cannon_fodder.description": "Die to a planetary collapse inside an Overworld-Like planet", + "advancements.anvilcraft.cannon_fodder.title": "Cannon Fodder", + "advancements.anvilcraft.come_at_night.description": "Get killed by a star", + "advancements.anvilcraft.come_at_night.title": "You Should Come At Night", "advancements.anvilcraft.crab_claw.description": "Obtain crab claws", "advancements.anvilcraft.crab_claw.title": "Win half of the resurrection race", "advancements.anvilcraft.dang.description": "Perform any anvil crafting", @@ -15,6 +21,8 @@ "advancements.anvilcraft.devourer.title": "Too many tongue twisters", "advancements.anvilcraft.durable_goods.description": "Upgrade any tool to Royal steel grade", "advancements.anvilcraft.durable_goods.title": "Durable goods", + "advancements.anvilcraft.efficiency.description": "Feed a gamma laser into the planet excavator and blow the planet apart", + "advancements.anvilcraft.efficiency.title": "We called it... efficiency", "advancements.anvilcraft.electric_allergy.description": "Obtain celestial forging anvil without power system", "advancements.anvilcraft.electric_allergy.title": "Electric allergy", "advancements.anvilcraft.electric_filed_rhythm.description": "Step in the scope of the power grid", @@ -63,10 +71,14 @@ "advancements.anvilcraft.mining_void.title": "Mining void", "advancements.anvilcraft.networking.description": "Craft and place transmission pole", "advancements.anvilcraft.networking.title": "Networking", + "advancements.anvilcraft.neutron_star.description": "Drive a star's evolution to the end and leave a neutron star behind", + "advancements.anvilcraft.neutron_star.title": "A Teaspoon Weighs a Mountain", "advancements.anvilcraft.new_cycle.description": "Witness a civilization disappear from the Celestial Forging Anvil", "advancements.anvilcraft.new_cycle.title": "A New Cycle", "advancements.anvilcraft.new_matter.description": "Using anvil collision to craft uranium, multiphase matter or negative matter", "advancements.anvilcraft.new_matter.title": "New Matter", + "advancements.anvilcraft.no_remnant.description": "Evolve a celestial body forged with 64 mass anvils to the end and watch it leave no remnant", + "advancements.anvilcraft.no_remnant.title": "Nothing Left Behind", "advancements.anvilcraft.noble_metal.description": "Smelting royal steel", "advancements.anvilcraft.noble_metal.title": "Noble metal", "advancements.anvilcraft.not_beacon.description": "Craft and place a charge collector", @@ -933,12 +945,15 @@ "config.waila.plugin_anvilcraft.power_provider": "Anvil Craft Power", "config.waila.plugin_anvilcraft.warning_percent": "Warning Threshold", "curios.identifier.ionocraft_backpack": "Ionocraft Backpack", + "death.attack.anvilcraft.black_hole_contact": "%1$s thought they could outrun light", "death.attack.anvilcraft.falling_giant_anvil": "%1$s died due to systemic resonance caused by ground vibrations", "death.attack.anvilcraft.heater_burn": "%1$s was well done by the heater", "death.attack.anvilcraft.laser": "%1$s was pierced by laser", "death.attack.anvilcraft.lost_in_time": "%1$s was lost in the river of time", + "death.attack.anvilcraft.planet_contact": "%1$s discovered the Roche limit, in pieces", "death.attack.anvilcraft.planetary_collapse": "%1$s was consumed by planetary collapse", "death.attack.anvilcraft.plasma_jet": "%1$s tried to high-five the plasma jets. They did not high-five back.", + "death.attack.anvilcraft.star_contact": "%1$s is now part of the corona", "effect.anvilcraft.invulnerable": "Invulnerable", "effect.anvilcraft.rage": "Rage", "enchantment.anvilcraft.beheading": "Beheading", diff --git a/src/generated/resources/assets/anvilcraft/sounds.json b/src/generated/resources/assets/anvilcraft/sounds.json index 233e628372..df099d73a4 100644 --- a/src/generated/resources/assets/anvilcraft/sounds.json +++ b/src/generated/resources/assets/anvilcraft/sounds.json @@ -99,7 +99,10 @@ }, "quenched_out": { "sounds": [ - "anvilcraft:quenched_out" + { + "attenuation_distance": 64, + "name": "anvilcraft:quenched_out" + } ], "subtitle": "subtitles.anvilcraft.quenched_out" }, diff --git a/src/generated/resources/data/anvilcraft/advancement/anvilcraft/black_hole.json b/src/generated/resources/data/anvilcraft/advancement/anvilcraft/black_hole.json new file mode 100644 index 0000000000..0067b8e350 --- /dev/null +++ b/src/generated/resources/data/anvilcraft/advancement/anvilcraft/black_hole.json @@ -0,0 +1,29 @@ +{ + "parent": "anvilcraft:anvilcraft/the_start", + "criteria": { + "black_hole": { + "conditions": { + "terminal": "black_hole" + }, + "trigger": "anvilcraft:celestial_evolution" + } + }, + "display": { + "description": { + "translate": "advancements.anvilcraft.black_hole.description" + }, + "frame": "challenge", + "icon": { + "id": "anvilcraft:black_hole" + }, + "title": { + "translate": "advancements.anvilcraft.black_hole.title" + } + }, + "requirements": [ + [ + "black_hole" + ] + ], + "sends_telemetry_event": true +} \ No newline at end of file diff --git a/src/generated/resources/data/anvilcraft/advancement/anvilcraft/cannon_fodder.json b/src/generated/resources/data/anvilcraft/advancement/anvilcraft/cannon_fodder.json new file mode 100644 index 0000000000..f0b52f37a8 --- /dev/null +++ b/src/generated/resources/data/anvilcraft/advancement/anvilcraft/cannon_fodder.json @@ -0,0 +1,27 @@ +{ + "parent": "anvilcraft:anvilcraft/the_start", + "criteria": { + "cannon_fodder": { + "trigger": "anvilcraft:planetary_collapse_death" + } + }, + "display": { + "description": { + "translate": "advancements.anvilcraft.cannon_fodder.description" + }, + "frame": "challenge", + "hidden": true, + "icon": { + "id": "minecraft:player_head" + }, + "title": { + "translate": "advancements.anvilcraft.cannon_fodder.title" + } + }, + "requirements": [ + [ + "cannon_fodder" + ] + ], + "sends_telemetry_event": true +} \ No newline at end of file diff --git a/src/generated/resources/data/anvilcraft/advancement/anvilcraft/come_at_night.json b/src/generated/resources/data/anvilcraft/advancement/anvilcraft/come_at_night.json new file mode 100644 index 0000000000..1de261eb3c --- /dev/null +++ b/src/generated/resources/data/anvilcraft/advancement/anvilcraft/come_at_night.json @@ -0,0 +1,26 @@ +{ + "parent": "anvilcraft:anvilcraft/the_start", + "criteria": { + "come_at_night": { + "trigger": "anvilcraft:star_contact_death" + } + }, + "display": { + "description": { + "translate": "advancements.anvilcraft.come_at_night.description" + }, + "hidden": true, + "icon": { + "id": "anvilcraft:celestial_forging_anvil" + }, + "title": { + "translate": "advancements.anvilcraft.come_at_night.title" + } + }, + "requirements": [ + [ + "come_at_night" + ] + ], + "sends_telemetry_event": true +} \ No newline at end of file diff --git a/src/generated/resources/data/anvilcraft/advancement/anvilcraft/efficiency.json b/src/generated/resources/data/anvilcraft/advancement/anvilcraft/efficiency.json new file mode 100644 index 0000000000..b435a413f5 --- /dev/null +++ b/src/generated/resources/data/anvilcraft/advancement/anvilcraft/efficiency.json @@ -0,0 +1,27 @@ +{ + "parent": "anvilcraft:anvilcraft/the_start", + "criteria": { + "efficiency": { + "trigger": "anvilcraft:planet_detonation" + } + }, + "display": { + "description": { + "translate": "advancements.anvilcraft.efficiency.description" + }, + "frame": "challenge", + "hidden": true, + "icon": { + "id": "anvilcraft:earth_core_shard" + }, + "title": { + "translate": "advancements.anvilcraft.efficiency.title" + } + }, + "requirements": [ + [ + "efficiency" + ] + ], + "sends_telemetry_event": true +} \ No newline at end of file diff --git a/src/generated/resources/data/anvilcraft/advancement/anvilcraft/neutron_star.json b/src/generated/resources/data/anvilcraft/advancement/anvilcraft/neutron_star.json new file mode 100644 index 0000000000..494cf8cbce --- /dev/null +++ b/src/generated/resources/data/anvilcraft/advancement/anvilcraft/neutron_star.json @@ -0,0 +1,29 @@ +{ + "parent": "anvilcraft:anvilcraft/the_start", + "criteria": { + "neutron_star": { + "conditions": { + "terminal": "neutron_star" + }, + "trigger": "anvilcraft:celestial_evolution" + } + }, + "display": { + "description": { + "translate": "advancements.anvilcraft.neutron_star.description" + }, + "frame": "challenge", + "icon": { + "id": "anvilcraft:magnetar_coil_component" + }, + "title": { + "translate": "advancements.anvilcraft.neutron_star.title" + } + }, + "requirements": [ + [ + "neutron_star" + ] + ], + "sends_telemetry_event": true +} \ No newline at end of file diff --git a/src/generated/resources/data/anvilcraft/advancement/anvilcraft/new_cycle.json b/src/generated/resources/data/anvilcraft/advancement/anvilcraft/new_cycle.json index 86ffd9e2a2..9d71c0d836 100644 --- a/src/generated/resources/data/anvilcraft/advancement/anvilcraft/new_cycle.json +++ b/src/generated/resources/data/anvilcraft/advancement/anvilcraft/new_cycle.json @@ -1,5 +1,5 @@ { - "parent": "anvilcraft:anvilcraft/the_start", + "parent": "anvilcraft:anvilcraft/no_remnant", "criteria": { "new_cycle": { "trigger": "minecraft:impossible" diff --git a/src/generated/resources/data/anvilcraft/advancement/anvilcraft/no_remnant.json b/src/generated/resources/data/anvilcraft/advancement/anvilcraft/no_remnant.json new file mode 100644 index 0000000000..5c6366319a --- /dev/null +++ b/src/generated/resources/data/anvilcraft/advancement/anvilcraft/no_remnant.json @@ -0,0 +1,30 @@ +{ + "parent": "anvilcraft:anvilcraft/the_start", + "criteria": { + "no_remnant": { + "conditions": { + "mass_anvils": 64 + }, + "trigger": "anvilcraft:celestial_evolution" + } + }, + "display": { + "description": { + "translate": "advancements.anvilcraft.no_remnant.description" + }, + "frame": "challenge", + "hidden": true, + "icon": { + "id": "anvilcraft:stellar_evolution_accelerator_component" + }, + "title": { + "translate": "advancements.anvilcraft.no_remnant.title" + } + }, + "requirements": [ + [ + "no_remnant" + ] + ], + "sends_telemetry_event": true +} \ No newline at end of file diff --git a/src/generated/resources/data/anvilcraft/damage_type/black_hole_contact.json b/src/generated/resources/data/anvilcraft/damage_type/black_hole_contact.json new file mode 100644 index 0000000000..f5c9d67d27 --- /dev/null +++ b/src/generated/resources/data/anvilcraft/damage_type/black_hole_contact.json @@ -0,0 +1,5 @@ +{ + "exhaustion": 0.1, + "message_id": "anvilcraft.black_hole_contact", + "scaling": "when_caused_by_living_non_player" +} \ No newline at end of file diff --git a/src/generated/resources/data/anvilcraft/damage_type/planet_contact.json b/src/generated/resources/data/anvilcraft/damage_type/planet_contact.json new file mode 100644 index 0000000000..5bcb8fbe25 --- /dev/null +++ b/src/generated/resources/data/anvilcraft/damage_type/planet_contact.json @@ -0,0 +1,5 @@ +{ + "exhaustion": 0.0, + "message_id": "anvilcraft.planet_contact", + "scaling": "when_caused_by_living_non_player" +} \ No newline at end of file diff --git a/src/generated/resources/data/anvilcraft/damage_type/star_contact.json b/src/generated/resources/data/anvilcraft/damage_type/star_contact.json new file mode 100644 index 0000000000..c2564afa83 --- /dev/null +++ b/src/generated/resources/data/anvilcraft/damage_type/star_contact.json @@ -0,0 +1,6 @@ +{ + "effects": "burning", + "exhaustion": 0.1, + "message_id": "anvilcraft.star_contact", + "scaling": "when_caused_by_living_non_player" +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/damage_type/bypasses_armor.json b/src/generated/resources/data/minecraft/tags/damage_type/bypasses_armor.json index d96bdc8f3d..1e689cb18a 100644 --- a/src/generated/resources/data/minecraft/tags/damage_type/bypasses_armor.json +++ b/src/generated/resources/data/minecraft/tags/damage_type/bypasses_armor.json @@ -4,6 +4,10 @@ "id": "anvilcraft:planetary_collapse", "required": false }, + { + "id": "anvilcraft:black_hole_contact", + "required": false + }, { "id": "anvilcraft:lost_in_time", "required": false diff --git a/src/generated/resources/data/minecraft/tags/damage_type/bypasses_resistance.json b/src/generated/resources/data/minecraft/tags/damage_type/bypasses_resistance.json index d96bdc8f3d..1e689cb18a 100644 --- a/src/generated/resources/data/minecraft/tags/damage_type/bypasses_resistance.json +++ b/src/generated/resources/data/minecraft/tags/damage_type/bypasses_resistance.json @@ -4,6 +4,10 @@ "id": "anvilcraft:planetary_collapse", "required": false }, + { + "id": "anvilcraft:black_hole_contact", + "required": false + }, { "id": "anvilcraft:lost_in_time", "required": false diff --git a/src/generated/resources/data/minecraft/tags/damage_type/is_fall.json b/src/generated/resources/data/minecraft/tags/damage_type/is_fall.json new file mode 100644 index 0000000000..4bbb509cb5 --- /dev/null +++ b/src/generated/resources/data/minecraft/tags/damage_type/is_fall.json @@ -0,0 +1,8 @@ +{ + "values": [ + { + "id": "anvilcraft:planet_contact", + "required": false + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/damage_type/is_fire.json b/src/generated/resources/data/minecraft/tags/damage_type/is_fire.json index f99dc4adbc..035a8091ed 100644 --- a/src/generated/resources/data/minecraft/tags/damage_type/is_fire.json +++ b/src/generated/resources/data/minecraft/tags/damage_type/is_fire.json @@ -4,6 +4,10 @@ "id": "anvilcraft:heater_burn", "required": false }, + { + "id": "anvilcraft:star_contact", + "required": false + }, { "id": "anvilcraft:plasma_jet", "required": false diff --git a/src/generated/resources/data/minecraft/tags/damage_type/no_knockback.json b/src/generated/resources/data/minecraft/tags/damage_type/no_knockback.json index b3a4ca393d..47cd8092b6 100644 --- a/src/generated/resources/data/minecraft/tags/damage_type/no_knockback.json +++ b/src/generated/resources/data/minecraft/tags/damage_type/no_knockback.json @@ -4,6 +4,10 @@ "id": "anvilcraft:planetary_collapse", "required": false }, + { + "id": "anvilcraft:black_hole_contact", + "required": false + }, { "id": "anvilcraft:lost_in_time", "required": false diff --git a/src/generated/resources/data/neoforge/tags/damage_type/is_magic.json b/src/generated/resources/data/neoforge/tags/damage_type/is_magic.json index 0ccc6bb9cb..7c15ea028a 100644 --- a/src/generated/resources/data/neoforge/tags/damage_type/is_magic.json +++ b/src/generated/resources/data/neoforge/tags/damage_type/is_magic.json @@ -1,5 +1,9 @@ { "values": [ + { + "id": "anvilcraft:black_hole_contact", + "required": false + }, { "id": "anvilcraft:lost_in_time", "required": false diff --git a/src/main/java/dev/dubhe/anvilcraft/advancements/criterion/CelestialEvolutionTrigger.java b/src/main/java/dev/dubhe/anvilcraft/advancements/criterion/CelestialEvolutionTrigger.java new file mode 100644 index 0000000000..5ffd20cc9b --- /dev/null +++ b/src/main/java/dev/dubhe/anvilcraft/advancements/criterion/CelestialEvolutionTrigger.java @@ -0,0 +1,54 @@ +package dev.dubhe.anvilcraft.advancements.criterion; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import dev.dubhe.anvilcraft.block.entity.celestial.StellarTerminal; +import dev.dubhe.anvilcraft.init.ModCriterionTriggers; +import net.minecraft.advancements.Criterion; +import net.minecraft.advancements.criterion.ContextAwarePredicate; +import net.minecraft.advancements.criterion.EntityPredicate; +import net.minecraft.advancements.criterion.MinMaxBounds; +import net.minecraft.advancements.criterion.SimpleCriterionTrigger; +import net.minecraft.server.level.ServerPlayer; + +import java.util.Optional; + +public class CelestialEvolutionTrigger extends SimpleCriterionTrigger { + @Override + public Codec codec() { + return TriggerInstance.CODEC; + } + + public void trigger(ServerPlayer player, int massAnvils, StellarTerminal.Kind terminal) { + this.trigger(player, (instance) -> instance.matches(massAnvils, terminal)); + } + + public record TriggerInstance( + Optional player, + Optional massAnvils, + Optional terminal + ) implements SimpleInstance { + public static final Codec CODEC = RecordCodecBuilder.create((instance) -> instance.group( + EntityPredicate.ADVANCEMENT_CODEC.optionalFieldOf("player").forGetter(TriggerInstance::player), + MinMaxBounds.Ints.CODEC.optionalFieldOf("mass_anvils").forGetter(TriggerInstance::massAnvils), + StellarTerminal.Kind.CODEC.optionalFieldOf("terminal").forGetter(TriggerInstance::terminal) + ).apply(instance, TriggerInstance::new)); + + public static Criterion evolved(MinMaxBounds.Ints massAnvils) { + return ModCriterionTriggers.CELESTIAL_EVOLUTION.get().createCriterion( + new TriggerInstance(Optional.empty(), Optional.of(massAnvils), Optional.empty()) + ); + } + + public static Criterion evolved(StellarTerminal.Kind terminal) { + return ModCriterionTriggers.CELESTIAL_EVOLUTION.get().createCriterion( + new TriggerInstance(Optional.empty(), Optional.empty(), Optional.of(terminal)) + ); + } + + public boolean matches(int massAnvils, StellarTerminal.Kind terminal) { + if (this.massAnvils.isPresent() && !this.massAnvils.get().matches(massAnvils)) return false; + return this.terminal.isEmpty() || this.terminal.get() == terminal; + } + } +} diff --git a/src/main/java/dev/dubhe/anvilcraft/advancements/criterion/PlanetDetonationTrigger.java b/src/main/java/dev/dubhe/anvilcraft/advancements/criterion/PlanetDetonationTrigger.java new file mode 100644 index 0000000000..8910a7e23c --- /dev/null +++ b/src/main/java/dev/dubhe/anvilcraft/advancements/criterion/PlanetDetonationTrigger.java @@ -0,0 +1,39 @@ +package dev.dubhe.anvilcraft.advancements.criterion; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import dev.dubhe.anvilcraft.init.ModCriterionTriggers; +import net.minecraft.advancements.Criterion; +import net.minecraft.advancements.criterion.ContextAwarePredicate; +import net.minecraft.advancements.criterion.EntityPredicate; +import net.minecraft.advancements.criterion.SimpleCriterionTrigger; +import net.minecraft.server.level.ServerPlayer; + +import java.util.Optional; + +public class PlanetDetonationTrigger extends SimpleCriterionTrigger { + @Override + public Codec codec() { + return TriggerInstance.CODEC; + } + + public void trigger(ServerPlayer player) { + this.trigger(player, TriggerInstance::matches); + } + + public record TriggerInstance(Optional player) implements SimpleInstance { + public static final Codec CODEC = RecordCodecBuilder.create((instance) -> instance.group( + EntityPredicate.ADVANCEMENT_CODEC.optionalFieldOf("player").forGetter(TriggerInstance::player) + ).apply(instance, TriggerInstance::new)); + + public static Criterion detonated() { + return ModCriterionTriggers.PLANET_DETONATION.get().createCriterion( + new TriggerInstance(Optional.empty()) + ); + } + + public boolean matches() { + return true; + } + } +} diff --git a/src/main/java/dev/dubhe/anvilcraft/advancements/criterion/PlanetaryCollapseDeathTrigger.java b/src/main/java/dev/dubhe/anvilcraft/advancements/criterion/PlanetaryCollapseDeathTrigger.java new file mode 100644 index 0000000000..cdb04636a9 --- /dev/null +++ b/src/main/java/dev/dubhe/anvilcraft/advancements/criterion/PlanetaryCollapseDeathTrigger.java @@ -0,0 +1,39 @@ +package dev.dubhe.anvilcraft.advancements.criterion; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import dev.dubhe.anvilcraft.init.ModCriterionTriggers; +import net.minecraft.advancements.Criterion; +import net.minecraft.advancements.criterion.ContextAwarePredicate; +import net.minecraft.advancements.criterion.EntityPredicate; +import net.minecraft.advancements.criterion.SimpleCriterionTrigger; +import net.minecraft.server.level.ServerPlayer; + +import java.util.Optional; + +public class PlanetaryCollapseDeathTrigger extends SimpleCriterionTrigger { + @Override + public Codec codec() { + return TriggerInstance.CODEC; + } + + public void trigger(ServerPlayer player) { + this.trigger(player, TriggerInstance::matches); + } + + public record TriggerInstance(Optional player) implements SimpleInstance { + public static final Codec CODEC = RecordCodecBuilder.create((instance) -> instance.group( + EntityPredicate.ADVANCEMENT_CODEC.optionalFieldOf("player").forGetter(TriggerInstance::player) + ).apply(instance, TriggerInstance::new)); + + public static Criterion died() { + return ModCriterionTriggers.PLANETARY_COLLAPSE_DEATH.get().createCriterion( + new TriggerInstance(Optional.empty()) + ); + } + + public boolean matches() { + return true; + } + } +} diff --git a/src/main/java/dev/dubhe/anvilcraft/advancements/criterion/StarContactDeathTrigger.java b/src/main/java/dev/dubhe/anvilcraft/advancements/criterion/StarContactDeathTrigger.java new file mode 100644 index 0000000000..dc6681a7ef --- /dev/null +++ b/src/main/java/dev/dubhe/anvilcraft/advancements/criterion/StarContactDeathTrigger.java @@ -0,0 +1,39 @@ +package dev.dubhe.anvilcraft.advancements.criterion; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import dev.dubhe.anvilcraft.init.ModCriterionTriggers; +import net.minecraft.advancements.Criterion; +import net.minecraft.advancements.criterion.ContextAwarePredicate; +import net.minecraft.advancements.criterion.EntityPredicate; +import net.minecraft.advancements.criterion.SimpleCriterionTrigger; +import net.minecraft.server.level.ServerPlayer; + +import java.util.Optional; + +public class StarContactDeathTrigger extends SimpleCriterionTrigger { + @Override + public Codec codec() { + return TriggerInstance.CODEC; + } + + public void trigger(ServerPlayer player) { + this.trigger(player, TriggerInstance::matches); + } + + public record TriggerInstance(Optional player) implements SimpleInstance { + public static final Codec CODEC = RecordCodecBuilder.create((instance) -> instance.group( + EntityPredicate.ADVANCEMENT_CODEC.optionalFieldOf("player").forGetter(TriggerInstance::player) + ).apply(instance, TriggerInstance::new)); + + public static Criterion died() { + return ModCriterionTriggers.STAR_CONTACT_DEATH.get().createCriterion( + new TriggerInstance(Optional.empty()) + ); + } + + public boolean matches() { + return true; + } + } +} diff --git a/src/main/java/dev/dubhe/anvilcraft/api/advancement/AdvancementLineHelper.java b/src/main/java/dev/dubhe/anvilcraft/api/advancement/AdvancementLineHelper.java index 51924d50bd..1882701639 100644 --- a/src/main/java/dev/dubhe/anvilcraft/api/advancement/AdvancementLineHelper.java +++ b/src/main/java/dev/dubhe/anvilcraft/api/advancement/AdvancementLineHelper.java @@ -10,6 +10,7 @@ import dev.dubhe.anvilcraft.advancements.criterion.AnvilLootingTrigger; import dev.dubhe.anvilcraft.advancements.criterion.AnvilOnGroundTrigger; import dev.dubhe.anvilcraft.advancements.criterion.BlockComparatorTurnOverTrigger; +import dev.dubhe.anvilcraft.advancements.criterion.CelestialEvolutionTrigger; import dev.dubhe.anvilcraft.advancements.criterion.ConvertBeaconTrigger; import dev.dubhe.anvilcraft.advancements.criterion.DevourerDevourTrigger; import dev.dubhe.anvilcraft.advancements.criterion.DispenserRepairIronGolem; @@ -25,11 +26,15 @@ import dev.dubhe.anvilcraft.advancements.criterion.PipeConnectContainersTrigger; import dev.dubhe.anvilcraft.advancements.criterion.PlacerPlaceTrigger; import dev.dubhe.anvilcraft.advancements.criterion.PlacerShuttleTrigger; +import dev.dubhe.anvilcraft.advancements.criterion.PlanetDetonationTrigger; +import dev.dubhe.anvilcraft.advancements.criterion.PlanetaryCollapseDeathTrigger; import dev.dubhe.anvilcraft.advancements.criterion.PlayerKilledEntityByAnvilHammerTrigger; import dev.dubhe.anvilcraft.advancements.criterion.PlayerWearAnvilHammerTrigger; +import dev.dubhe.anvilcraft.advancements.criterion.StarContactDeathTrigger; import dev.dubhe.anvilcraft.advancements.criterion.UseItemTrigger; import dev.dubhe.anvilcraft.advancements.criterion.VoidCollectorTrigger; import dev.dubhe.anvilcraft.advancements.criterion.VoidEnergyCollectorWorkingTrigger; +import dev.dubhe.anvilcraft.block.entity.celestial.StellarTerminal; import net.minecraft.advancements.Advancement; import net.minecraft.advancements.AdvancementHolder; import net.minecraft.advancements.AdvancementRequirements; @@ -481,6 +486,26 @@ public AdvancementHelper blockComparatorTurnOver(String key) { return this.addCriterion(key, BlockComparatorTurnOverTrigger.TriggerInstance.turnOver()); } + public AdvancementHelper celestialEvolution(String key, MinMaxBounds.Ints massAnvils) { + return this.addCriterion(key, CelestialEvolutionTrigger.TriggerInstance.evolved(massAnvils)); + } + + public AdvancementHelper celestialEvolution(String key, StellarTerminal.Kind terminal) { + return this.addCriterion(key, CelestialEvolutionTrigger.TriggerInstance.evolved(terminal)); + } + + public AdvancementHelper planetDetonation(String key) { + return this.addCriterion(key, PlanetDetonationTrigger.TriggerInstance.detonated()); + } + + public AdvancementHelper planetaryCollapseDeath(String key) { + return this.addCriterion(key, PlanetaryCollapseDeathTrigger.TriggerInstance.died()); + } + + public AdvancementHelper starContactDeath(String key) { + return this.addCriterion(key, StarContactDeathTrigger.TriggerInstance.died()); + } + public AdvancementHolder build(String id) { AdvancementHolder holder = this.current.build( Identifier.fromNamespaceAndPath(this.lineHelper.namespace, this.lineHelper.namespace + "/" + id) diff --git a/src/main/java/dev/dubhe/anvilcraft/block/entity/BigRedButtonBlockEntity.java b/src/main/java/dev/dubhe/anvilcraft/block/entity/BigRedButtonBlockEntity.java index 8f65b373fb..074c068fab 100644 --- a/src/main/java/dev/dubhe/anvilcraft/block/entity/BigRedButtonBlockEntity.java +++ b/src/main/java/dev/dubhe/anvilcraft/block/entity/BigRedButtonBlockEntity.java @@ -37,12 +37,13 @@ public void onLoad() { } } - public void press(Player player) { + public boolean press(Player player) { if (this.level == null || this.level.isClientSide() || !player.isAlive() || player.isSpectator() || player.isShiftKeyDown() - || player.getMainHandItem().is(ModItems.BUILDING_ROD)) return; + || player.getMainHandItem().is(ModItems.BUILDING_ROD)) return false; this.holders.put(player.getUUID(), this.level.getGameTime()); this.setPressed(true); this.level.scheduleTick(this.worldPosition, this.getBlockState().getBlock(), 1); + return true; } public void release(Player player) { diff --git a/src/main/java/dev/dubhe/anvilcraft/block/entity/CelestialForgingAnvilBlockEntity.java b/src/main/java/dev/dubhe/anvilcraft/block/entity/CelestialForgingAnvilBlockEntity.java index db1a7ababe..d2d3f4abfe 100644 --- a/src/main/java/dev/dubhe/anvilcraft/block/entity/CelestialForgingAnvilBlockEntity.java +++ b/src/main/java/dev/dubhe/anvilcraft/block/entity/CelestialForgingAnvilBlockEntity.java @@ -37,6 +37,7 @@ import net.minecraft.core.HolderLookup; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtOps; +import net.minecraft.network.Connection; import net.minecraft.network.chat.Component; import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.game.ClientGamePacketListener; @@ -1262,6 +1263,11 @@ public Packet getUpdatePacket() { return ClientboundBlockEntityDataPacket.create(this); } + @Override + public void onDataPacket(Connection connection, ValueInput input) { + this.handleUpdateTag(input); + } + // === 巨构 === /** diff --git a/src/main/java/dev/dubhe/anvilcraft/block/entity/CfaGravityController.java b/src/main/java/dev/dubhe/anvilcraft/block/entity/CfaGravityController.java index f3b5bf77e7..70b7766263 100644 --- a/src/main/java/dev/dubhe/anvilcraft/block/entity/CfaGravityController.java +++ b/src/main/java/dev/dubhe/anvilcraft/block/entity/CfaGravityController.java @@ -141,18 +141,18 @@ private static boolean isEternal(Entity entity) { private static void applyCelestialDamage(Level level, CelestialBodyData body, LivingEntity living) { if (body instanceof StarData star) { if (star.bodyClass() == CelestialBodyClass.BLACK_HOLE) { - EntityUtil.hurtOrSimulate(living, ModDamageTypes.lostInTime(level), Float.MAX_VALUE); + EntityUtil.hurtOrSimulate(living, ModDamageTypes.blackHoleContact(level), Float.MAX_VALUE); } else { EntityUtil.hurtOrSimulate( living, - level.damageSources().inFire(), + ModDamageTypes.starContact(level), CfaGravityController.STAR_CONTACT_DAMAGE ); } } else { EntityUtil.hurtOrSimulate( living, - level.damageSources().fall(), + ModDamageTypes.planetContact(level), CfaGravityController.PLANET_CONTACT_DAMAGE ); } diff --git a/src/main/java/dev/dubhe/anvilcraft/block/entity/ItemSplitterBlockEntity.java b/src/main/java/dev/dubhe/anvilcraft/block/entity/ItemSplitterBlockEntity.java index cbae97108a..70c1d2a4db 100644 --- a/src/main/java/dev/dubhe/anvilcraft/block/entity/ItemSplitterBlockEntity.java +++ b/src/main/java/dev/dubhe/anvilcraft/block/entity/ItemSplitterBlockEntity.java @@ -188,9 +188,13 @@ private int extractTotal(ItemResource resource, int amount, TransactionContext t private void dropAt(BlockPos target, ItemStack stack) { if (this.level == null) return; Vec3 center = target.getCenter(); - ItemEntity item = new ItemEntity(this.level, center.x, center.y, center.z, stack, 0, 0, 0); - item.setDefaultPickUpDelay(); - this.level.addFreshEntity(item); + while (!stack.isEmpty()) { + ItemEntity item = new ItemEntity( + this.level, center.x, center.y, center.z, stack.split(stack.getMaxStackSize()), 0, 0, 0 + ); + item.setDefaultPickUpDelay(); + this.level.addFreshEntity(item); + } } public Direction getFacing() { diff --git a/src/main/java/dev/dubhe/anvilcraft/block/entity/megastructure/AcceleratorHandler.java b/src/main/java/dev/dubhe/anvilcraft/block/entity/megastructure/AcceleratorHandler.java index abfd638a97..fc3153266a 100644 --- a/src/main/java/dev/dubhe/anvilcraft/block/entity/megastructure/AcceleratorHandler.java +++ b/src/main/java/dev/dubhe/anvilcraft/block/entity/megastructure/AcceleratorHandler.java @@ -17,6 +17,7 @@ import dev.dubhe.anvilcraft.block.entity.celestial.StellarVisualState; import dev.dubhe.anvilcraft.init.ModMegastructures; import dev.dubhe.anvilcraft.network.QuenchedOutMusicPacket; +import dev.dubhe.anvilcraft.util.TriggerUtil; import lombok.Getter; import net.minecraft.core.HolderLookup; import net.minecraft.nbt.CompoundTag; @@ -598,6 +599,7 @@ private void completeEvolution(CelestialForgingAnvilBlockEntity be) { // KEEP 的冷却外观继续从快照采样。 } } + TriggerUtil.celestialEvolution(be.getLevel(), be.getBlockPos(), this.evolutionState.initialMass(), terminal.kind()); this.finishAccelerator(be); this.syncToClient(be); } diff --git a/src/main/java/dev/dubhe/anvilcraft/block/entity/megastructure/ExcavatorHandler.java b/src/main/java/dev/dubhe/anvilcraft/block/entity/megastructure/ExcavatorHandler.java index 52a6dee9fd..57b4a871d4 100644 --- a/src/main/java/dev/dubhe/anvilcraft/block/entity/megastructure/ExcavatorHandler.java +++ b/src/main/java/dev/dubhe/anvilcraft/block/entity/megastructure/ExcavatorHandler.java @@ -9,6 +9,7 @@ import dev.dubhe.anvilcraft.block.entity.celestial.ShatteredPlanet; import dev.dubhe.anvilcraft.block.entity.celestial.SpecialCelestialBodyData; import dev.dubhe.anvilcraft.util.BreakBlockUtil; +import dev.dubhe.anvilcraft.util.TriggerUtil; import dev.dubhe.anvilcraft.worldgen.OverworldLikeResetManager; import lombok.Getter; import net.minecraft.core.HolderLookup; @@ -152,6 +153,7 @@ private boolean tryShatterPlanet( be.setPlanetaryResourceSet(ShatteredPlanet.createResources()); be.setAgeAnvilCount(ShatteredPlanet.AGE_ANVIL_COUNT); be.setStellarMass(ShatteredPlanet.MASS_ANVIL_COUNT); + TriggerUtil.planetDetonation(be.getLevel(), be.getBlockPos()); be.setChanged(); be.getLevel().sendBlockUpdated(be.getBlockPos(), be.getBlockState(), be.getBlockState(), Block.UPDATE_ALL); be.getLevel().explode( diff --git a/src/main/java/dev/dubhe/anvilcraft/block/logistics/storage/StorageFluidPortBlock.java b/src/main/java/dev/dubhe/anvilcraft/block/logistics/storage/StorageFluidPortBlock.java index 2dbb292912..d43a158bf0 100644 --- a/src/main/java/dev/dubhe/anvilcraft/block/logistics/storage/StorageFluidPortBlock.java +++ b/src/main/java/dev/dubhe/anvilcraft/block/logistics/storage/StorageFluidPortBlock.java @@ -60,10 +60,11 @@ public ItemStack getCloneItemStack( ) { ItemStack stack = super.getCloneItemStack(level, pos, state, includeData, player); // 中键克隆(或其它拾取路径)也保留流体,保证物品模型与 tooltip 有数据可显示 + // 使用调用方的数据标志,避免服务端拾取或扫描读取客户端按键状态。 if ( - level instanceof Level realLevel + includeData + && level instanceof Level realLevel && realLevel.getBlockEntity(pos) instanceof StorageFluidPortBlockEntity port - && includeData ) { port.saveToDrop(stack, realLevel.registryAccess()); } diff --git a/src/main/java/dev/dubhe/anvilcraft/block/logistics/storage/StoragePortBlock.java b/src/main/java/dev/dubhe/anvilcraft/block/logistics/storage/StoragePortBlock.java index 412afb9732..d6df9cd858 100644 --- a/src/main/java/dev/dubhe/anvilcraft/block/logistics/storage/StoragePortBlock.java +++ b/src/main/java/dev/dubhe/anvilcraft/block/logistics/storage/StoragePortBlock.java @@ -73,10 +73,11 @@ public ItemStack getCloneItemStack( ) { ItemStack stack = super.getCloneItemStack(level, pos, state, includeData, player); // 中键克隆(或其它拾取路径)也保留缓存与标记,保证物品模型与 tooltip 有数据可显示 + // 使用调用方的数据标志,避免服务端拾取或扫描读取客户端按键状态。 if ( - level instanceof Level realLevel + includeData + && level instanceof Level realLevel && realLevel.getBlockEntity(pos) instanceof StoragePortBlockEntity port - && includeData ) { port.saveToDrop(stack, realLevel.registryAccess()); } diff --git a/src/main/java/dev/dubhe/anvilcraft/building/BuildingUndoResources.java b/src/main/java/dev/dubhe/anvilcraft/building/BuildingUndoResources.java index e199533569..f47d7aefa5 100644 --- a/src/main/java/dev/dubhe/anvilcraft/building/BuildingUndoResources.java +++ b/src/main/java/dev/dubhe/anvilcraft/building/BuildingUndoResources.java @@ -4,6 +4,8 @@ import dev.dubhe.anvilcraft.block.UseItemOnBlock; import dev.dubhe.anvilcraft.block.cake.LargeCakeBlock; import dev.dubhe.anvilcraft.block.entity.storage.StorageBlockEntity; +import dev.dubhe.anvilcraft.entity.FallingSpectralBlockEntity; +import dev.dubhe.anvilcraft.init.block.ModBlocks; import dev.dubhe.anvilcraft.item.block.LargeCakeBlockItem; import net.minecraft.core.BlockPos; import net.minecraft.core.component.DataComponents; @@ -155,6 +157,10 @@ void entity(ServerLevel level, CompoundTag data, ItemStack supplied) { if (plan.unsupported()) throw new IllegalArgumentException("Unknown entity resources"); if (probe instanceof Mob && plan.material().isEmpty()) throw new IllegalArgumentException("Missing creature material"); ItemStack material = supplied.isEmpty() ? plan.material().copy() : supplied.copyWithCount(1); + if (probe instanceof FallingSpectralBlockEntity falling && falling.getBlockState().is(ModBlocks.SPECTRAL_ANVIL) + && copy.getBooleanOr("Ghost", true) && !falling.dropItem) { + material = ItemStack.EMPTY; + } if (!material.isEmpty() && !(probe instanceof ItemEntity)) { if (probe.getCustomName() == null) material.remove(DataComponents.CUSTOM_NAME); else material.set(DataComponents.CUSTOM_NAME, probe.getCustomName()); diff --git a/src/main/java/dev/dubhe/anvilcraft/client/event/BigRedButtonInputListener.java b/src/main/java/dev/dubhe/anvilcraft/client/event/BigRedButtonInputListener.java index 24afa55d08..2faec36134 100644 --- a/src/main/java/dev/dubhe/anvilcraft/client/event/BigRedButtonInputListener.java +++ b/src/main/java/dev/dubhe/anvilcraft/client/event/BigRedButtonInputListener.java @@ -1,6 +1,7 @@ package dev.dubhe.anvilcraft.client.event; import dev.dubhe.anvilcraft.AnvilCraft; +import dev.dubhe.anvilcraft.block.utility.redstone.BigRedButtonBlock; import dev.dubhe.anvilcraft.init.block.ModBlocks; import dev.dubhe.anvilcraft.item.BuildingRodItem; import dev.dubhe.anvilcraft.network.BigRedButtonHoldPacket; @@ -12,6 +13,7 @@ import net.minecraft.world.InteractionHand; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.HitResult; +import net.minecraft.world.phys.Vec3; import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.EventPriority; import net.neoforged.bus.api.SubscribeEvent; @@ -27,6 +29,8 @@ public class BigRedButtonInputListener { private static @Nullable BlockPos heldPos; private static @Nullable ClientLevel heldLevel; private static int heartbeatTicks; + private static int holdId; + private static boolean confirmed; private static final float HELD_SWING_PROGRESS = 0.125f; private static @Nullable ClientLevel animationLevel; private static float previousSwingProgress; @@ -36,8 +40,9 @@ public class BigRedButtonInputListener { public static void onUse(InputEvent.InteractionKeyMappingTriggered event) { if (!event.isUseItem()) return; Minecraft minecraft = Minecraft.getInstance(); - BlockPos pos = targetedButton(minecraft); - if (pos == null) return; + BlockHitResult hit = targetedButton(minecraft); + if (hit == null) return; + BlockPos pos = hit.getBlockPos(); event.setCanceled(true); event.setSwingHand(false); if (pos.equals(heldPos) && minecraft.level == heldLevel) return; @@ -45,7 +50,7 @@ public static void onUse(InputEvent.InteractionKeyMappingTriggered event) { heldPos = pos; heldLevel = minecraft.level; heartbeatTicks = 0; - ClientPacketDistributor.sendToServer(new BigRedButtonHoldPacket(pos, true)); + ClientPacketDistributor.sendToServer(new BigRedButtonHoldPacket(pos, hit.getLocation(), true, holdId)); } @SubscribeEvent @@ -68,14 +73,15 @@ public static void onKey(InputEvent.Key event) { public static void onClientTick(ClientTickEvent.Pre event) { if (heldPos == null) return; Minecraft minecraft = Minecraft.getInstance(); + BlockHitResult hit = targetedButton(minecraft); if (minecraft.level != heldLevel || !minecraft.options.keyUse.isDown() - || !heldPos.equals(targetedButton(minecraft))) { + || hit == null || !heldPos.equals(hit.getBlockPos())) { release(); return; } if (++heartbeatTicks >= 5) { heartbeatTicks = 0; - ClientPacketDistributor.sendToServer(new BigRedButtonHoldPacket(heldPos, true)); + ClientPacketDistributor.sendToServer(new BigRedButtonHoldPacket(heldPos, hit.getLocation(), true, holdId)); } } @@ -88,7 +94,16 @@ public static void onAnimationTick(ClientTickEvent.Post event) { swingProgress = 0; } previousSwingProgress = swingProgress; - swingProgress = Mth.approach(swingProgress, heldPos == null ? 0 : HELD_SWING_PROGRESS, HELD_SWING_PROGRESS / 2); + boolean pressed = confirmed && heldPos != null && minecraft.player != null + && minecraft.level == heldLevel && minecraft.level != null + && minecraft.level.getBlockState(heldPos).is(ModBlocks.BIG_RED_BUTTON) + && minecraft.level.getBlockState(heldPos).getValue(BigRedButtonBlock.PRESSED); + swingProgress = Mth.approach(swingProgress, pressed ? HELD_SWING_PROGRESS : 0, HELD_SWING_PROGRESS / 2); + } + + public static void handleHoldResult(BlockPos pos, int id, boolean accepted) { + if (id != holdId || !pos.equals(heldPos) || Minecraft.getInstance().level != heldLevel) return; + confirmed = accepted; } public static float getHandSwingProgress(InteractionHand hand, float partialTick, float vanillaProgress) { @@ -99,21 +114,23 @@ public static float getHandSwingProgress(InteractionHand hand, float partialTick } @Nullable - private static BlockPos targetedButton(Minecraft minecraft) { + private static BlockHitResult targetedButton(Minecraft minecraft) { if (minecraft.level == null || minecraft.player == null || minecraft.screen != null || !minecraft.isWindowActive() || !minecraft.player.isAlive() || minecraft.player.isSpectator() || minecraft.player.isShiftKeyDown() || BuildingRodItem.isHeld(minecraft.player)) return null; if (!(minecraft.hitResult instanceof BlockHitResult hit) || hit.getType() != HitResult.Type.BLOCK) return null; - return minecraft.level.getBlockState(hit.getBlockPos()).is(ModBlocks.BIG_RED_BUTTON) ? hit.getBlockPos() : null; + return minecraft.level.getBlockState(hit.getBlockPos()).is(ModBlocks.BIG_RED_BUTTON) ? hit : null; } private static void release() { Minecraft minecraft = Minecraft.getInstance(); if (heldPos != null && minecraft.level == heldLevel && minecraft.getConnection() != null) { - ClientPacketDistributor.sendToServer(new BigRedButtonHoldPacket(heldPos, false)); + ClientPacketDistributor.sendToServer(new BigRedButtonHoldPacket(heldPos, Vec3.ZERO, false, holdId)); } heldPos = null; heldLevel = null; + holdId++; + confirmed = false; heartbeatTicks = 0; } } diff --git a/src/main/java/dev/dubhe/anvilcraft/client/event/QuenchedOutMusicHandler.java b/src/main/java/dev/dubhe/anvilcraft/client/event/QuenchedOutMusicHandler.java index 2b89f205a0..a19970f7d3 100644 --- a/src/main/java/dev/dubhe/anvilcraft/client/event/QuenchedOutMusicHandler.java +++ b/src/main/java/dev/dubhe/anvilcraft/client/event/QuenchedOutMusicHandler.java @@ -67,7 +67,7 @@ public static void onLogout(ClientPlayerNetworkEvent.LoggingOut event) { /** 固定在锻星砧位置的单次播放实例,不跟随玩家。 */ private static final class QuenchedOutSound extends AbstractTickableSoundInstance { private QuenchedOutSound(BlockPos pos) { - super(ModSoundEvents.QUENCHED_OUT.get(), SoundSource.MUSIC, SoundInstance.createUnseededRandom()); + super(ModSoundEvents.QUENCHED_OUT.get(), SoundSource.RECORDS, SoundInstance.createUnseededRandom()); this.looping = false; this.delay = 0; this.volume = 1.0F; diff --git a/src/main/java/dev/dubhe/anvilcraft/data/advancement/ModAdvancementsHandler.java b/src/main/java/dev/dubhe/anvilcraft/data/advancement/ModAdvancementsHandler.java index 24ab742a6f..48cc6a8f7f 100644 --- a/src/main/java/dev/dubhe/anvilcraft/data/advancement/ModAdvancementsHandler.java +++ b/src/main/java/dev/dubhe/anvilcraft/data/advancement/ModAdvancementsHandler.java @@ -6,6 +6,7 @@ import dev.dubhe.anvilcraft.advancements.criterion.AnvilHammerHurtEntityTrigger; import dev.dubhe.anvilcraft.api.advancement.AdvancementLineHelper; import dev.dubhe.anvilcraft.block.entity.HeatCollectorBlockEntity; +import dev.dubhe.anvilcraft.block.entity.celestial.StellarTerminal; import dev.dubhe.anvilcraft.init.block.ModBlockTags; import dev.dubhe.anvilcraft.init.block.ModBlocks; import dev.dubhe.anvilcraft.init.item.ModItems; @@ -785,6 +786,64 @@ public static void init(RegistrumAdvancementProvider provider) { ) .hasItems("has_celestial_forging_anvil", ModBlocks.CELESTIAL_FORGING_ANVIL) .save(provider, "the_start"); + mainLine.createBranch().next() + .display( + ModItems.EARTH_CORE_SHARD, + Component.translatable("advancements.anvilcraft.efficiency.title"), + Component.translatable("advancements.anvilcraft.efficiency.description"), + AdvancementType.CHALLENGE, + true + ) + .planetDetonation("efficiency") + .save(provider, "efficiency"); + mainLine.createBranch().next() + .display( + Items.PLAYER_HEAD, + Component.translatable("advancements.anvilcraft.cannon_fodder.title"), + Component.translatable("advancements.anvilcraft.cannon_fodder.description"), + AdvancementType.CHALLENGE, + true + ) + .planetaryCollapseDeath("cannon_fodder") + .save(provider, "cannon_fodder"); + mainLine.createBranch().next() + .display( + ModBlocks.BLACK_HOLE, + Component.translatable("advancements.anvilcraft.black_hole.title"), + Component.translatable("advancements.anvilcraft.black_hole.description"), + AdvancementType.CHALLENGE + ) + .celestialEvolution("black_hole", StellarTerminal.Kind.BLACK_HOLE) + .save(provider, "black_hole"); + mainLine.createBranch().next() + .display( + ModItems.MAGNETAR_COIL_COMPONENT, + Component.translatable("advancements.anvilcraft.neutron_star.title"), + Component.translatable("advancements.anvilcraft.neutron_star.description"), + AdvancementType.CHALLENGE + ) + .celestialEvolution("neutron_star", StellarTerminal.Kind.NEUTRON_STAR) + .save(provider, "neutron_star"); + mainLine.createBranch().next() + .display( + ModBlocks.CELESTIAL_FORGING_ANVIL, + Component.translatable("advancements.anvilcraft.come_at_night.title"), + Component.translatable("advancements.anvilcraft.come_at_night.description"), + AdvancementType.TASK, + true + ) + .starContactDeath("come_at_night") + .save(provider, "come_at_night"); + mainLine.next() + .display( + ModItems.STELLAR_EVOLUTION_ACCELERATOR_COMPONENT, + Component.translatable("advancements.anvilcraft.no_remnant.title"), + Component.translatable("advancements.anvilcraft.no_remnant.description"), + AdvancementType.CHALLENGE, + true + ) + .celestialEvolution("no_remnant", MinMaxBounds.Ints.exactly(64)) + .save(provider, "no_remnant"); mainLine.next() .display( ModItems.CIVILIZATION_CATALYST, diff --git a/src/main/java/dev/dubhe/anvilcraft/data/lang/AdvancementLang.java b/src/main/java/dev/dubhe/anvilcraft/data/lang/AdvancementLang.java index 65c325207d..7a2a9185e0 100644 --- a/src/main/java/dev/dubhe/anvilcraft/data/lang/AdvancementLang.java +++ b/src/main/java/dev/dubhe/anvilcraft/data/lang/AdvancementLang.java @@ -222,6 +222,19 @@ public static void init(RegistrumLangProvider provider) { provider.add("advancements.anvilcraft.the_start.title", "The start"); provider.add("advancements.anvilcraft.the_start.description", "Obtain celestial forging anvil"); + provider.add("advancements.anvilcraft.no_remnant.title", "Nothing Left Behind"); + provider.add("advancements.anvilcraft.no_remnant.description", "Evolve a celestial body forged with 64 mass anvils to the end and watch it leave no remnant"); + provider.add("advancements.anvilcraft.efficiency.title", "We called it... efficiency"); + provider.add("advancements.anvilcraft.efficiency.description", "Feed a gamma laser into the planet excavator and blow the planet apart"); + provider.add("advancements.anvilcraft.cannon_fodder.title", "Cannon Fodder"); + provider.add("advancements.anvilcraft.cannon_fodder.description", "Die to a planetary collapse inside an Overworld-Like planet"); + provider.add("advancements.anvilcraft.come_at_night.title", "You Should Come At Night"); + provider.add("advancements.anvilcraft.come_at_night.description", "Get killed by a star"); + provider.add("advancements.anvilcraft.black_hole.title", "Not Even Light Escapes"); + provider.add("advancements.anvilcraft.black_hole.description", "Drive a star's evolution to the end and collapse it into a black hole"); + provider.add("advancements.anvilcraft.neutron_star.title", "A Teaspoon Weighs a Mountain"); + provider.add("advancements.anvilcraft.neutron_star.description", "Drive a star's evolution to the end and leave a neutron star behind"); + provider.add("advancements.anvilcraft.new_cycle.title", "A New Cycle"); provider.add("advancements.anvilcraft.new_cycle.description", "Witness a civilization disappear from the Celestial Forging Anvil"); // endregion diff --git a/src/main/java/dev/dubhe/anvilcraft/data/lang/OtherLang.java b/src/main/java/dev/dubhe/anvilcraft/data/lang/OtherLang.java index 25dc905fd9..65cf7bfba7 100644 --- a/src/main/java/dev/dubhe/anvilcraft/data/lang/OtherLang.java +++ b/src/main/java/dev/dubhe/anvilcraft/data/lang/OtherLang.java @@ -66,6 +66,12 @@ public static void init(RegistrumLangProvider provider) { provider.add("subtitles.anvilcraft.smart_block_placer_shulker_open", "Smart Block Placer whirs"); provider.add("subtitles.anvilcraft.anvil_hammer_rotate_block", "Anvil Hammer rotates block"); provider.add("death.attack.anvilcraft.planetary_collapse", "%1$s was consumed by planetary collapse"); + provider.add("death.attack.anvilcraft.star_contact", + "%1$s is now part of the corona"); + provider.add("death.attack.anvilcraft.planet_contact", + "%1$s discovered the Roche limit, in pieces"); + provider.add("death.attack.anvilcraft.black_hole_contact", + "%1$s thought they could outrun light"); provider.add("death.attack.anvilcraft.laser", "%1$s was pierced by laser"); provider.add("death.attack.anvilcraft.lost_in_time", "%1$s was lost in the river of time"); provider.add("death.attack.anvilcraft.heater_burn", "%1$s was well done by the heater"); diff --git a/src/main/java/dev/dubhe/anvilcraft/data/provider/ModSoundDefinitionsProvider.java b/src/main/java/dev/dubhe/anvilcraft/data/provider/ModSoundDefinitionsProvider.java index 5401172b6f..7f51c9cde9 100644 --- a/src/main/java/dev/dubhe/anvilcraft/data/provider/ModSoundDefinitionsProvider.java +++ b/src/main/java/dev/dubhe/anvilcraft/data/provider/ModSoundDefinitionsProvider.java @@ -121,6 +121,6 @@ public void registerSounds() { ); this.add(ModSoundEvents.QUENCHED_OUT.get(), SoundDefinitionsProvider.definition() .subtitle("subtitles.anvilcraft.quenched_out") - .with(SoundDefinitionsProvider.sound(AnvilCraft.of("quenched_out")))); + .with(SoundDefinitionsProvider.sound(AnvilCraft.of("quenched_out")).attenuationDistance(64))); } } diff --git a/src/main/java/dev/dubhe/anvilcraft/data/tags/DamageTypeTagLoader.java b/src/main/java/dev/dubhe/anvilcraft/data/tags/DamageTypeTagLoader.java index 0d0f84444a..fa6a747a34 100644 --- a/src/main/java/dev/dubhe/anvilcraft/data/tags/DamageTypeTagLoader.java +++ b/src/main/java/dev/dubhe/anvilcraft/data/tags/DamageTypeTagLoader.java @@ -21,23 +21,31 @@ public static void init(RegistrumTagsProvider provider) { } provider.rawBuilder(DamageTypeTags.BYPASSES_ARMOR) + .addOptionalElement(ModDamageTypes.BLACK_HOLE_CONTACT.identifier()) .addOptionalElement(ModDamageTypes.LOST_IN_TIME.identifier()); provider.rawBuilder(DamageTypeTags.BYPASSES_RESISTANCE) + .addOptionalElement(ModDamageTypes.BLACK_HOLE_CONTACT.identifier()) .addOptionalElement(ModDamageTypes.LOST_IN_TIME.identifier()); provider.rawBuilder(DamageTypeTags.NO_KNOCKBACK) + .addOptionalElement(ModDamageTypes.BLACK_HOLE_CONTACT.identifier()) .addOptionalElement(ModDamageTypes.LOST_IN_TIME.identifier()) .addOptionalElement(ModDamageTypes.HEATER_BURN.identifier()); provider.rawBuilder(DamageTypeTags.IS_FIRE) .addOptionalElement(ModDamageTypes.HEATER_BURN.identifier()) + .addOptionalElement(ModDamageTypes.STAR_CONTACT.identifier()) .addOptionalElement(ModDamageTypes.PLASMA_JET.identifier()) .addOptionalElement(ModDamageTypes.LASER.identifier()); provider.rawBuilder(Tags.DamageTypes.IS_MAGIC) + .addOptionalElement(ModDamageTypes.BLACK_HOLE_CONTACT.identifier()) .addOptionalElement(ModDamageTypes.LOST_IN_TIME.identifier()); + provider.rawBuilder(DamageTypeTags.IS_FALL) + .addOptionalElement(ModDamageTypes.PLANET_CONTACT.identifier()); + provider.rawBuilder(ModDamageTypeTags.AMULET_VALID) .addOptionalTag(ModDamageTypeTags.TOPAZ_AMULET_VALID.location()) .addOptionalTag(ModDamageTypeTags.RUBY_AMULET_VALID.location()) diff --git a/src/main/java/dev/dubhe/anvilcraft/event/OverworldLikeEventListener.java b/src/main/java/dev/dubhe/anvilcraft/event/OverworldLikeEventListener.java index 2942217e2c..18a03f1702 100644 --- a/src/main/java/dev/dubhe/anvilcraft/event/OverworldLikeEventListener.java +++ b/src/main/java/dev/dubhe/anvilcraft/event/OverworldLikeEventListener.java @@ -2,12 +2,14 @@ import dev.dubhe.anvilcraft.AnvilCraft; import dev.dubhe.anvilcraft.init.entity.ModDamageTypes; +import dev.dubhe.anvilcraft.util.TriggerUtil; import dev.dubhe.anvilcraft.worldgen.OverworldLikeGenerationBootstrap; import dev.dubhe.anvilcraft.worldgen.OverworldLikeResetManager; import net.minecraft.server.level.ServerPlayer; import net.neoforged.bus.api.EventPriority; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.event.entity.living.LivingDeathEvent; import net.neoforged.neoforge.event.entity.living.LivingIncomingDamageEvent; import net.neoforged.neoforge.event.entity.player.PlayerEvent; import net.neoforged.neoforge.event.server.ServerStoppedEvent; @@ -49,6 +51,22 @@ public static void keepPlanetaryCollapseUnavoidable(LivingIncomingDamageEvent ev } } + @SubscribeEvent + public static void onPlanetaryCollapseDeath(LivingDeathEvent event) { + if (!event.getSource().is(ModDamageTypes.PLANETARY_COLLAPSE)) return; + if (event.getEntity() instanceof ServerPlayer player) { + TriggerUtil.planetaryCollapseDeath(player); + } + } + + @SubscribeEvent + public static void onStarContactDeath(LivingDeathEvent event) { + if (!event.getSource().is(ModDamageTypes.STAR_CONTACT)) return; + if (event.getEntity() instanceof ServerPlayer player) { + TriggerUtil.starContactDeath(player); + } + } + @SubscribeEvent public static void onServerStopped(ServerStoppedEvent event) { OverworldLikeGenerationBootstrap.clear(event.getServer()); diff --git a/src/main/java/dev/dubhe/anvilcraft/init/ModCriterionTriggers.java b/src/main/java/dev/dubhe/anvilcraft/init/ModCriterionTriggers.java index 8f52c30ac1..4d2facfd4d 100644 --- a/src/main/java/dev/dubhe/anvilcraft/init/ModCriterionTriggers.java +++ b/src/main/java/dev/dubhe/anvilcraft/init/ModCriterionTriggers.java @@ -8,6 +8,7 @@ import dev.dubhe.anvilcraft.advancements.criterion.AnvilLootingTrigger; import dev.dubhe.anvilcraft.advancements.criterion.AnvilOnGroundTrigger; import dev.dubhe.anvilcraft.advancements.criterion.BlockComparatorTurnOverTrigger; +import dev.dubhe.anvilcraft.advancements.criterion.CelestialEvolutionTrigger; import dev.dubhe.anvilcraft.advancements.criterion.ConnectFluidContainersTrigger; import dev.dubhe.anvilcraft.advancements.criterion.ConvertBeaconTrigger; import dev.dubhe.anvilcraft.advancements.criterion.DevourerDevourTrigger; @@ -24,8 +25,11 @@ import dev.dubhe.anvilcraft.advancements.criterion.PipeConnectContainersTrigger; import dev.dubhe.anvilcraft.advancements.criterion.PlacerPlaceTrigger; import dev.dubhe.anvilcraft.advancements.criterion.PlacerShuttleTrigger; +import dev.dubhe.anvilcraft.advancements.criterion.PlanetDetonationTrigger; +import dev.dubhe.anvilcraft.advancements.criterion.PlanetaryCollapseDeathTrigger; import dev.dubhe.anvilcraft.advancements.criterion.PlayerKilledEntityByAnvilHammerTrigger; import dev.dubhe.anvilcraft.advancements.criterion.PlayerWearAnvilHammerTrigger; +import dev.dubhe.anvilcraft.advancements.criterion.StarContactDeathTrigger; import dev.dubhe.anvilcraft.advancements.criterion.UseItemTrigger; import dev.dubhe.anvilcraft.advancements.criterion.VoidCollectorTrigger; import dev.dubhe.anvilcraft.advancements.criterion.VoidEnergyCollectorWorkingTrigger; @@ -175,6 +179,18 @@ public class ModCriterionTriggers { public static final DeferredHolder, VoidEnergyCollectorWorkingTrigger> VOID_ENERGY_COLLECTOR_WORKING = ModCriterionTriggers.REGISTER.register("void_energy_collector_working", VoidEnergyCollectorWorkingTrigger::new); + public static final DeferredHolder, CelestialEvolutionTrigger> CELESTIAL_EVOLUTION = + REGISTER.register("celestial_evolution", CelestialEvolutionTrigger::new); + + public static final DeferredHolder, PlanetDetonationTrigger> PLANET_DETONATION = + REGISTER.register("planet_detonation", PlanetDetonationTrigger::new); + + public static final DeferredHolder, PlanetaryCollapseDeathTrigger> PLANETARY_COLLAPSE_DEATH = + REGISTER.register("planetary_collapse_death", PlanetaryCollapseDeathTrigger::new); + + public static final DeferredHolder, StarContactDeathTrigger> STAR_CONTACT_DEATH = + REGISTER.register("star_contact_death", StarContactDeathTrigger::new); + public static void register(IEventBus eventBus) { ModCriterionTriggers.REGISTER.register(eventBus); } diff --git a/src/main/java/dev/dubhe/anvilcraft/init/entity/ModDamageTypes.java b/src/main/java/dev/dubhe/anvilcraft/init/entity/ModDamageTypes.java index a7506ec3d4..203fae7082 100644 --- a/src/main/java/dev/dubhe/anvilcraft/init/entity/ModDamageTypes.java +++ b/src/main/java/dev/dubhe/anvilcraft/init/entity/ModDamageTypes.java @@ -45,6 +45,13 @@ public class ModDamageTypes { public static final ResourceKey PLANETARY_COLLAPSE = ResourceKey.create( Registries.DAMAGE_TYPE, AnvilCraft.of("planetary_collapse")); + public static final ResourceKey STAR_CONTACT = ResourceKey.create( + Registries.DAMAGE_TYPE, AnvilCraft.of("star_contact")); + public static final ResourceKey PLANET_CONTACT = ResourceKey.create( + Registries.DAMAGE_TYPE, AnvilCraft.of("planet_contact")); + public static final ResourceKey BLACK_HOLE_CONTACT = ResourceKey.create( + Registries.DAMAGE_TYPE, AnvilCraft.of("black_hole_contact")); + @ApiStatus.Internal public static void bootstrap(BootstrapContext ctx) { ctx.register(PLANETARY_COLLAPSE, new DamageType("anvilcraft.planetary_collapse", DamageScaling.NEVER, 0.0F, @@ -55,6 +62,9 @@ public static void bootstrap(BootstrapContext ctx) { ctx.register(ModDamageTypes.HEATER_BURN, new DamageType("anvilcraft.heater_burn", 0.1F, DamageEffects.BURNING)); ctx.register(ModDamageTypes.GAMMA_LASER, new DamageType("anvilcraft.gamma_laser", 0.1F, DamageEffects.BURNING)); ctx.register(ModDamageTypes.PLASMA_JET, new DamageType("anvilcraft.plasma_jet", 0.1F, DamageEffects.BURNING)); + ctx.register(STAR_CONTACT, new DamageType("anvilcraft.star_contact", 0.1F, DamageEffects.BURNING)); + ctx.register(PLANET_CONTACT, new DamageType("anvilcraft.planet_contact", 0.0F, DamageEffects.HURT)); + ctx.register(BLACK_HOLE_CONTACT, new DamageType("anvilcraft.black_hole_contact", 0.1F)); } public static DamageSource planetaryCollapse(Level level) { @@ -93,6 +103,18 @@ public static DamageSource plasmaJet(Level level) { return ModDamageTypes.source(ModDamageTypes.PLASMA_JET, level); } + public static DamageSource starContact(Level level) { + return ModDamageTypes.source(ModDamageTypes.STAR_CONTACT, level); + } + + public static DamageSource planetContact(Level level) { + return ModDamageTypes.source(ModDamageTypes.PLANET_CONTACT, level); + } + + public static DamageSource blackHoleContact(Level level) { + return ModDamageTypes.source(ModDamageTypes.BLACK_HOLE_CONTACT, level); + } + private static DamageSource source(ResourceKey key, LevelReader level) { Holder.Reference holder = level.registryAccess().lookupOrThrow(Registries.DAMAGE_TYPE).getOrThrow(key); return new DamageSource(holder); diff --git a/src/main/java/dev/dubhe/anvilcraft/mixin/PlayerHitEntityMixin.java b/src/main/java/dev/dubhe/anvilcraft/mixin/PlayerHitEntityMixin.java index bcb328fc3c..dc08e3cb79 100644 --- a/src/main/java/dev/dubhe/anvilcraft/mixin/PlayerHitEntityMixin.java +++ b/src/main/java/dev/dubhe/anvilcraft/mixin/PlayerHitEntityMixin.java @@ -1,6 +1,7 @@ package dev.dubhe.anvilcraft.mixin; import dev.anvilcraft.lib.v2.util.Util; +import dev.dubhe.anvilcraft.init.entity.ModDamageTypes; import dev.dubhe.anvilcraft.init.item.ModItems; import dev.dubhe.anvilcraft.item.tool.AnvilHammerItem; import dev.dubhe.anvilcraft.util.EntityUtil; @@ -58,7 +59,8 @@ private void onFlyingHitBlock(ServerLevel level, DamageSource source, float dama cir.setReturnValue(false); cir.cancel(); } else { - if (source.type().equals(this.level().damageSources().fall().type())) { + if (source.type().equals(this.level().damageSources().fall().type()) + || source.is(ModDamageTypes.PLANET_CONTACT)) { for (LivingEntity entity : entities) { EntityUtil.hurt(entity, this.damageSources().playerAttack(thiS), hurtAmount); PlayerHitEntityMixin.anvilcraft$damageItem(thiS, this.getItemBySlot(EquipmentSlot.HEAD)); diff --git a/src/main/java/dev/dubhe/anvilcraft/network/BigRedButtonHoldPacket.java b/src/main/java/dev/dubhe/anvilcraft/network/BigRedButtonHoldPacket.java index 34089dc9b8..0bf1472726 100644 --- a/src/main/java/dev/dubhe/anvilcraft/network/BigRedButtonHoldPacket.java +++ b/src/main/java/dev/dubhe/anvilcraft/network/BigRedButtonHoldPacket.java @@ -1,26 +1,32 @@ package dev.dubhe.anvilcraft.network; +import dev.anvilcraft.lib.v2.codec.StreamCodecUtil; import dev.anvilcraft.lib.v2.network.packet.IPacket; -import dev.anvilcraft.lib.v2.network.packet.IServerboundPacket; +import dev.anvilcraft.lib.v2.network.packet.ISensitiveBiPacket; +import dev.anvilcraft.lib.v2.util.Util; import dev.dubhe.anvilcraft.AnvilCraft; import dev.dubhe.anvilcraft.block.entity.BigRedButtonBlockEntity; -import dev.dubhe.anvilcraft.block.utility.redstone.BigRedButtonBlock; -import io.netty.buffer.ByteBuf; +import dev.dubhe.anvilcraft.client.event.BigRedButtonInputListener; import net.minecraft.core.BlockPos; +import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.ClipContext; +import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; +import net.neoforged.neoforge.network.PacketDistributor; -public record BigRedButtonHoldPacket(BlockPos pos, boolean held) implements IServerboundPacket { +public record BigRedButtonHoldPacket(BlockPos pos, Vec3 hitLocation, boolean held, int holdId) implements ISensitiveBiPacket { public static final Type TYPE = IPacket.type(AnvilCraft.of("big_red_button_hold")); - public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( BlockPos.STREAM_CODEC, BigRedButtonHoldPacket::pos, + StreamCodecUtil.VEC3, BigRedButtonHoldPacket::hitLocation, ByteBufCodecs.BOOL, BigRedButtonHoldPacket::held, + ByteBufCodecs.VAR_INT, BigRedButtonHoldPacket::holdId, BigRedButtonHoldPacket::new ); @@ -29,21 +35,38 @@ public Type type() { return TYPE; } + @Override + public void handleOnClient(Player player) { + BigRedButtonInputListener.handleHoldResult(this.pos, this.holdId, this.held); + } + @Override public void handleOnServer(Player player) { - if (!player.level().hasChunkAt(this.pos)) return; - if (!(player.level().getBlockEntity(this.pos) instanceof BigRedButtonBlockEntity button)) return; - if (!this.held) { + boolean accepted = this.updateButton(player); + PacketDistributor.sendToPlayer( + Util.cast(player), new BigRedButtonHoldPacket(this.pos, this.hitLocation, accepted, this.holdId) + ); + } + + private boolean updateButton(Player player) { + if (!player.level().hasChunkAt(this.pos)) return false; + if (!(player.level().getBlockEntity(this.pos) instanceof BigRedButtonBlockEntity button)) return false; + if (!this.held || !this.canPress(player)) { button.release(player); - return; + return false; } - if (!player.isAlive() || player.isSpectator() || !player.isWithinBlockInteractionRange(this.pos, 1.0)) return; - Vec3 target = this.pos.getCenter().relative(button.getBlockState().getValue(BigRedButtonBlock.FACING), -0.375); - HitResult hit = player.level().clip(new ClipContext( - player.getEyePosition(), target, ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, player + return button.press(player); + } + + private boolean canPress(Player player) { + if (!player.isAlive() || player.isSpectator() || !player.isWithinBlockInteractionRange(this.pos, 1.0)) return false; + if (!Double.isFinite(this.hitLocation.x) || !Double.isFinite(this.hitLocation.y) || !Double.isFinite(this.hitLocation.z) + || !new AABB(this.pos).inflate(1.0E-5).contains(this.hitLocation)) return false; + Vec3 eye = player.getEyePosition(); + Vec3 target = this.hitLocation.add(this.hitLocation.subtract(eye).normalize().scale(1.0E-4)); + BlockHitResult hit = player.level().clip(new ClipContext( + eye, target, ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, player )); - if (!(hit instanceof BlockHitResult blockHit) || hit.getType() != HitResult.Type.BLOCK - || !blockHit.getBlockPos().equals(this.pos)) return; - button.press(player); + return hit.getType() == HitResult.Type.BLOCK && hit.getBlockPos().equals(this.pos); } } diff --git a/src/main/java/dev/dubhe/anvilcraft/util/TriggerUtil.java b/src/main/java/dev/dubhe/anvilcraft/util/TriggerUtil.java index 54637fc70a..a5bd3a2f20 100644 --- a/src/main/java/dev/dubhe/anvilcraft/util/TriggerUtil.java +++ b/src/main/java/dev/dubhe/anvilcraft/util/TriggerUtil.java @@ -1,5 +1,6 @@ package dev.dubhe.anvilcraft.util; +import dev.dubhe.anvilcraft.block.entity.celestial.StellarTerminal; import dev.dubhe.anvilcraft.init.ModCriterionTriggers; import net.minecraft.advancements.CriteriaTriggers; import net.minecraft.core.BlockPos; @@ -235,4 +236,30 @@ public static void multiBlockForm(Level level, BlockPos pos) { } } + /** 演化终局伴随超新星爆发,玩家多在爆炸范围外观察,因此搜索半径对齐震屏半径。 */ + public static void celestialEvolution(Level level, BlockPos pos, int massAnvils, StellarTerminal.Kind terminal) { + if (!level.isClientSide()) { + for (ServerPlayer player : PlayerUtil.searchPlayerByPos(level, pos, 32)) { + ModCriterionTriggers.CELESTIAL_EVOLUTION.get().trigger(player, massAnvils, terminal); + } + } + } + + public static void planetDetonation(Level level, BlockPos pos) { + if (!level.isClientSide()) { + for (ServerPlayer player : PlayerUtil.searchPlayerByPos(level, pos, 7)) { + ModCriterionTriggers.PLANET_DETONATION.get().trigger(player); + } + } + } + + /** 死亡事件只涉及当事玩家,不需要按位置搜索。 */ + public static void planetaryCollapseDeath(ServerPlayer player) { + ModCriterionTriggers.PLANETARY_COLLAPSE_DEATH.get().trigger(player); + } + + /** 死亡事件只涉及当事玩家,不需要按位置搜索。 */ + public static void starContactDeath(ServerPlayer player) { + ModCriterionTriggers.STAR_CONTACT_DEATH.get().trigger(player); + } } diff --git a/src/main/resources/assets/anvilcraft/sounds/quenched_out.ogg b/src/main/resources/assets/anvilcraft/sounds/quenched_out.ogg index 649c6f9129..0319b7ed24 100644 Binary files a/src/main/resources/assets/anvilcraft/sounds/quenched_out.ogg and b/src/main/resources/assets/anvilcraft/sounds/quenched_out.ogg differ