registry.clj

Bowmap · bowmap.git · Tickets

Branches > main > b6d3d26 > files / src / net / bowmap / server / protocol / registry.clj

(ns net.bowmap.server.protocol.registry
  "The set of registry and tags required by the client.
   The registry is global to the server. Because clients depend on the registry
   as it was sent to them, it is not REPL reloadable without reconfiguration."
  (:require
   [clojure.set :as set]
   [clojure.spec.alpha :as s]
   [net.bowmap.server.protocol.clientbound-packets :as clientbound]
   [net.bowmap.server.protocol.identifier :as identifier]
   [net.bowmap.server.protocol.packet :as packet]
   [net.bowmap.server.protocol.schema :as p]
   [net.bowmap.server.protocol.schema.bowmap :as bowmap]
   [net.bowmap.server.protocol.schema.minecraft :as mc]
   [net.bowmap.server.protocol.world :as world]))

(def core-data-pack
  "The minecraft:core datapack, known by the vanilla client."
  {::p/registry-id ::mc/core
   ::p/pack-version "26.3"})

(def world-dimension ::bowmap/world)
(def plains-biome ::mc/plains)

(def block-transformers
  #{::mc/shovel ::mc/axe ::mc/hoe})

(def chicken-variants
  #{::mc/warm ::mc/cold ::mc/temperate})

(def vanilla-damage-types
  #{::mc/cactus ::mc/campfire ::mc/cramming ::mc/dragon_breath ::mc/drown ::mc/dry_out ::mc/ender_pearl ::mc/fall ::mc/fly_into_wall
    ::mc/freeze ::mc/generic ::mc/generic_kill ::mc/hot_floor ::mc/in_fire ::mc/in_wall ::mc/lava ::mc/lightning_bolt ::mc/magic
    ::mc/on_fire ::mc/out_of_world ::mc/outside_border ::mc/spear ::mc/stalagmite ::mc/starve ::mc/sweet_berry_bush ::mc/wither})

(def decorated-pot-patterns
  #{::mc/angler ::mc/archer ::mc/arms_up ::mc/blade ::mc/brewer ::mc/burn ::mc/danger ::mc/explorer ::mc/flow ::mc/friend
    ::mc/guster ::mc/heart ::mc/heartbreak ::mc/howl ::mc/miner ::mc/mourner ::mc/plenty ::mc/prize ::mc/scrape ::mc/sheaf
    ::mc/shelter ::mc/skull ::mc/snort})

(def jukebox-sounds
  #{::mc/#11 ::mc/#13 ::mc/#5 ::mc/blocks ::mc/bounce ::mc/cat ::mc/chirp ::mc/creator ::mc/creator_music_box ::mc/far ::mc/lava_chicken
    ::mc/mall ::mc/mellohi ::mc/otherside ::mc/pigstep ::mc/precipice ::mc/relic ::mc/stal ::mc/strad ::mc/tears ::mc/wait ::mc/ward})

(def trim-materials
  #{::mc/amethyst ::mc/copper ::mc/diamond ::mc/emerald ::mc/gold ::mc/iron ::mc/lapis ::mc/netherite ::mc/quartz ::mc/redstone ::mc/resin})

(def instruments
  #{::mc/ponder_goat_horn})

(defn compound-with-keys? [keys]
  (s/and map? #(set/subset? keys %)))

(s/def ::mc/block_transformer (compound-with-keys? block-transformers))
(s/def ::mc/chicken_variant (compound-with-keys? chicken-variants))
(s/def ::mc/damage_type (compound-with-keys? vanilla-damage-types))
(s/def ::mc/decorated_pot_pattern (compound-with-keys? decorated-pot-patterns))
(s/def ::mc/instrument (compound-with-keys? instruments))
(s/def ::mc/jukebox_song (compound-with-keys? jukebox-sounds))
(s/def ::mc/trim_material (compound-with-keys? trim-materials))
(s/def ::mc/worldgen:biome (compound-with-keys? #{plains-biome}))

(s/def ::registry (s/keys :req [::mc/block_transformer
                                ::mc/cat_sound_variant
                                ::mc/cat_variant
                                ::mc/chicken_sound_variant
                                ::mc/chicken_variant
                                ::mc/cow_sound_variant
                                ::mc/cow_variant
                                ::mc/damage_type
                                ::mc/decorated_pot_pattern
                                ::mc/dimension_type
                                ::mc/frog_variant
                                ::mc/instrument
                                ::mc/jukebox_song
                                ::mc/painting_variant
                                ::mc/pig_sound_variant
                                ::mc/pig_variant
                                ::mc/trim_material
                                ::mc/wolf_sound_variant
                                ::mc/wolf_variant
                                ::mc/worldgen:biome
                                ::mc/zombie_nautilus_variant]))

(def null-component {:text "null"})
(def null-asset "null")
(def null-translation "null")
(def null-sound {:sound_id "null"})
(def null-entry-id ::bowmap/null)

(def registry-placeholder-values
  "Map of registry ids to placeholder values that satisfy that registry but
   otherwise contain no useful information.
   Used when the registry is required, but contains no important information
   or configuration for the server."
  {::mc/block_transformer
   nil

   ::mc/cat_sound_variant
   {:adult_sounds {:ambient_sound null-sound
                   :beg_for_food_sound null-sound
                   :death_sound null-sound
                   :eat_sound null-sound
                   :hiss_sound null-sound
                   :hurt_sound null-sound
                   :purr_sound null-sound
                   :purreow_sound null-sound
                   :stray_ambient_sound null-sound}
    :baby_sounds {:ambient_sound null-sound
                  :beg_for_food_sound null-sound
                  :death_sound null-sound
                  :eat_sound null-sound
                  :hiss_sound null-sound
                  :hurt_sound null-sound
                  :purr_sound null-sound
                  :purreow_sound null-sound
                  :stray_ambient_sound null-sound}}

   ::mc/cat_variant
   {:asset_id null-asset
    :baby_asset_id null-asset
    :spawn_conditions []}

   ::mc/chicken_sound_variant
   {:adult_sounds {:ambient_sound null-sound
                   :death_sound null-sound
                   :hurt_sound null-sound
                   :step_sound null-sound}
    :baby_sounds {:ambient_sound null-sound
                  :death_sound null-sound
                  :hurt_sound null-sound
                  :step_sound null-sound}}

   ::mc/chicken_variant
   {:asset_id null-asset
    :baby_asset_id null-asset
    :model :normal
    :spawn_conditions []}

   ::mc/cow_sound_variant
   {:ambient_sound null-sound
    :death_sound null-sound
    :hurt_sound null-sound
    :step_sound null-sound}

   ::mc/cow_variant
   {:asset_id null-asset
    :baby_asset_id null-asset
    :model :normal
    :spawn_conditions []}

   ::mc/decorated_pot_pattern
   nil

   ::mc/damage_type
   {:exhaustion 0.0
    :message_id null-translation
    :scaling :never}

   ::mc/frog_variant
   {:asset_id null-asset
    :spawn_condition []}

   ::mc/instrument
   {:description null-component
    :range 1.0
    :sound_event null-sound
    :use_duration 1.0}

   ::mc/jukebox_song
   {:comparator_output 1
    :description null-component
    :length_in_seconds 1.0
    :sound_event null-sound}

   ::mc/painting_variant
   {:asset_id null-asset
    :author null-component
    :height 1
    :title null-component
    :width 1}

   ::mc/pig_sound_variant
   {:adult_sounds {:ambient_sound null-sound
                   :death_sound null-sound
                   :eat_sound null-sound
                   :hurt_sound null-sound
                   :step_sound null-sound}
    :baby_sounds {:ambient_sound null-sound
                  :death_sound null-sound
                  :eat_sound null-sound
                  :hurt_sound null-sound
                  :step_sound null-sound}}

   ::mc/pig_variant
   {:asset_id null-asset
    :baby_asset_id null-asset
    :model :normal
    :spawn_conditions []}

   ::mc/trim_material
   {:palette_id "bowmap:null"
    :description null-component}

   ::mc/wolf_sound_variant
   {:adult_sounds {:ambient_sound null-sound
                   :death_sound null-sound
                   :growl_sound null-sound
                   :hurt_sound null-sound
                   :pant_sound null-sound
                   :step_sound null-sound
                   :whine_sound null-sound}
    :baby_sounds {:ambient_sound null-sound
                  :death_sound null-sound
                  :growl_sound null-sound
                  :hurt_sound null-sound
                  :pant_sound null-sound
                  :step_sound null-sound
                  :whine_sound null-sound}}

   ::mc/wolf_variant
   {:assets {:angry null-asset
             :tame null-asset
             :wild null-asset}
    :baby_assets {:angry null-asset
                  :tame null-asset
                  :wild null-asset}
    :spawn_conditions []}

   ::mc/zombie_nautilus_variant
   {:asset_id null-asset
    :spawn_conditions []}})

(defn placeholder-entries
  "Returns the placeholder registry entries for a given registry id.
   When no entry ids are supplied, returns a map with a 'null' entry id.
   When a collection of entry ids are supplied, returns a map that maps all the
   entry ids to the placeholder value."
  ([registry-id]
   {null-entry-id (req! registry-placeholder-values registry-id)})
  ([entry-ids registry-id]
   (zipmap entry-ids (repeat (req! registry-placeholder-values registry-id)))))

(defonce registry
  {::mc/dimension_type {world-dimension {:ambient_light 1.0
                                         :attributes {}
                                         :coordinate_scale 1.0
                                         :has_ceiling false
                                         :has_ender_dragon_fight false
                                         :has_skylight true
                                         :height world/world-height
                                         :logical_height world/world-height
                                         :infiniburn (identifier/tag ::bowmap/infiniburn)
                                         :min_y world/world-bottom
                                         :monster_spawn_block_light_limit 0
                                         :monster_spawn_light_level 0}}

   ::mc/worldgen:biome {plains-biome {:has_precipitation false
                                      :temperature 1.0
                                      :downfall 1.0
                                      :effects {:fog_color 880000
                                                :water_color 880000
                                                :water_fog_color 880000
                                                :sky_color 880000}}}

   ::mc/block_transformer       (placeholder-entries block-transformers     ::mc/block_transformer)
   ::mc/chicken_variant         (placeholder-entries chicken-variants       ::mc/chicken_variant)
   ::mc/damage_type             (placeholder-entries vanilla-damage-types   ::mc/damage_type)
   ::mc/decorated_pot_pattern   (placeholder-entries decorated-pot-patterns ::mc/decorated_pot_pattern)
   ::mc/instrument              (placeholder-entries instruments            ::mc/instrument)
   ::mc/jukebox_song            (placeholder-entries jukebox-sounds         ::mc/jukebox_song)
   ::mc/trim_material           (placeholder-entries trim-materials         ::mc/trim_material)

   ::mc/cat_sound_variant       (placeholder-entries ::mc/cat_sound_variant)
   ::mc/cat_variant             (placeholder-entries ::mc/cat_variant)
   ::mc/chicken_sound_variant   (placeholder-entries ::mc/chicken_sound_variant)
   ::mc/cow_sound_variant       (placeholder-entries ::mc/cow_sound_variant)
   ::mc/cow_variant             (placeholder-entries ::mc/cow_variant)
   ::mc/frog_variant            (placeholder-entries ::mc/frog_variant)
   ::mc/painting_variant        (placeholder-entries ::mc/painting_variant)
   ::mc/pig_sound_variant       (placeholder-entries ::mc/pig_sound_variant)
   ::mc/pig_variant             (placeholder-entries ::mc/pig_variant)
   ::mc/wolf_sound_variant      (placeholder-entries ::mc/wolf_sound_variant)
   ::mc/wolf_variant            (placeholder-entries ::mc/wolf_variant)
   ::mc/zombie_nautilus_variant (placeholder-entries ::mc/zombie_nautilus_variant)})

(assert (s/valid? ::registry registry))

(defonce tags
  {::mc/block [::bowmap/infiniburn]
   ::mc/damage_type [::mc/is_fire
                     ::mc/is_explosion
                     ::mc/bypasses_shield]
   ::mc/banner_pattern [::mc/pattern_item:bordure_indented
                        ::mc/pattern_item:creeper
                        ::mc/pattern_item:field_masoned
                        ::mc/pattern_item:flow
                        ::mc/pattern_item:flower
                        ::mc/pattern_item:globe
                        ::mc/pattern_item:guster
                        ::mc/pattern_item:mojang
                        ::mc/pattern_item:piglin
                        ::mc/pattern_item:skull]})

(defonce registry-ids->values (update-vals registry #(zipmap (range) (keys %))))
(defonce registry-values->ids (update-vals registry-ids->values set/map-invert))

(defn registry-id [registry value]
  (req! (registry-values->ids registry) value))

(let [registry-packets
      (for [[registry-id entries] registry]
        {::packet/id ::clientbound/registry-data
         ::p/registry-id registry-id
         ::p/registry-entries
         (for [[value] (sort-by val (req! registry-values->ids registry-id))]
           {::p/registry-entry-id value
            ::p/registry-data (entries value)})})

      tag-packets
      (for [[registry tags] tags]
        {::packet/id ::clientbound/update-tags
         ::p/tagged-registries
         [{::p/registry-id registry
           ::p/tags (for [tag-name tags]
                      {::p/tag-name tag-name})}]})]
  (def registry-packets
    "Vector of registry and tag packets required by the client."
    (vec (into registry-packets tag-packets))))