mirror of
https://github.com/horizon-rust/horizon.git
synced 2026-11-07 11:06:11 -10:00
Add potential natural spawns hook
This commit is contained in:
1 parent
c5c8a33a8a
commit
92ecb918ed
5 files changed
+52
-1
No files matched your search
@@ -4685,6 +4685,21 @@ impl Game<'_> {
|
||||
mod_api::dispatch_time_skip(self, mod_api::mods(), dimension, from, to, cause, cancel);
|
||||
}
|
||||
|
||||
/// Possible natural spawns at a server position (NeoForge's
|
||||
/// `LevelEvent.PotentialSpawns`, `NaturalSpawner.mobsAt`). Mods may add or
|
||||
/// remove entries, or cancel to make the list empty. Added entries must
|
||||
/// be globally unique instances. @API:native_potential_spawns@.
|
||||
pub(super) fn native_potential_spawns(
|
||||
&self,
|
||||
dimension: &str,
|
||||
category: &str,
|
||||
pos: [i32; 3],
|
||||
entries: &mut Vec<horizon_client::biome::SpawnEntry>,
|
||||
canceled: &mut bool,
|
||||
) {
|
||||
let _ = (dimension, category, pos, entries, canceled);
|
||||
}
|
||||
|
||||
/// The world's spawn point changed to `pos` and `angle`. @API:native_spawn_change@.
|
||||
pub(super) fn native_spawn_change(&mut self, pos: [i32; 3], angle: [f32; 2]) {
|
||||
mod_api::dispatch_spawn_change(self, mod_api::mods(), pos, angle);
|
||||
|
||||
@@ -233,6 +233,19 @@ impl SpawnLevel for GameLevel<'_, '_> {
|
||||
}
|
||||
}
|
||||
impl NaturalLevel for GameLevel<'_, '_> {
|
||||
fn potential_spawns(&self, category: Category, pos: [i32; 3], entries: &mut Vec<SpawnEntry>) {
|
||||
let mut canceled = false;
|
||||
self.game.native_potential_spawns(
|
||||
self.game.dim.id(),
|
||||
category.name(),
|
||||
pos,
|
||||
entries,
|
||||
&mut canceled,
|
||||
);
|
||||
if canceled {
|
||||
entries.clear();
|
||||
}
|
||||
}
|
||||
fn min_y(&self) -> i32 {
|
||||
self.w.world.bottom_y()
|
||||
}
|
||||
|
||||
@@ -301,6 +301,8 @@ fn spawns_far_from_player(s: Species, category: Category) -> bool {
|
||||
pub type MobType = (Species, f32, f32, Category);
|
||||
|
||||
pub trait NaturalLevel: SpawnLevel {
|
||||
/// Let server mods change the possible spawns at a position.
|
||||
fn potential_spawns(&self, _category: Category, _pos: [i32; 3], _entries: &mut Vec<SpawnEntry>) {}
|
||||
fn min_y(&self) -> i32;
|
||||
/// `getMaxY()`: the highest buildable block.
|
||||
fn max_y(&self) -> i32;
|
||||
@@ -1057,7 +1059,9 @@ pub fn spawn_category_for_position<L: NaturalLevel, R: RandomSource>(
|
||||
{
|
||||
None
|
||||
} else {
|
||||
weighted_pick(mobs_at(l, category, x, y, z), random)
|
||||
let mut entries = mobs_at(l, category, x, y, z).to_vec();
|
||||
l.potential_spawns(category, [x, y, z], &mut entries);
|
||||
weighted_pick(&entries, random)
|
||||
};
|
||||
let Some(entry) = list else {
|
||||
break;
|
||||
|
||||
@@ -934,6 +934,8 @@ API 142 adds an energy buffer on a mod block's block entity (`Capabilities.Energ
|
||||
|
||||
API 143 adds data maps (`RegisterDataMapTypesEvent`). `native_data_map_types(types)` pushes the types a mod registers: an `id` (`mod_id:name`, not in `minecraft`) for a `registry`, `minecraft:item` or `minecraft:block` so far; asked once per load of the server's data (a world's first open and every `/reload`). The values come from `data/<mod_id>/data_maps/<registry path>/<name>.json` in the world's data packs and from files a mod pushes through `native_data_pack_files` under the key `data_maps/<mod_id>:<registry path>/<name>`: `{"replace": false, "values": {"minecraft:coal": ..., "#minecraft:logs": ...}, "remove": [...]}`, an entry's value being the data itself or `{"value": ..., "replace": false}`; `replace` clears what earlier files set, a tag gives every entry in it the value, `remove` applies after the file's own values, and a newer value overrides an older one. `native_data_map(registry, type, entry)` reads an entry's value (the JSON the file held) and `native_data_map_entries(registry, type)` lists them. Server side only and not synced to clients; mergers, conditions, other registries and mod datapack registries are not here yet. Bundles need "hooks": 143.
|
||||
|
||||
`native_potential_spawns(dimension, category, pos, entries, canceled)` runs on the server when natural spawning builds its possible spawn list (NeoForge's `LevelEvent.PotentialSpawns`, vanilla's `NaturalSpawner.mobsAt`). Mods may add or remove entries; canceling empties the list. Added entries must be globally unique instances. Bundles need "hooks": @API:native_potential_spawns@.
|
||||
|
||||
API 144 adds a player's or mob's breathing, on the single player server thread and on a dedicated server: `native_living_breathe(entity, kind, can_breathe, consume, refill)` every tick for a player and for a mob with the generic air logic (NeoForge's `LivingBreatheEvent`, vanilla's `LivingEntity.baseTick`), with Horizon's answers as the defaults: set `can_breathe` and how much air `consume` takes or `refill` gives (up to 300); at -20 the entity is set to 0 air and takes 2 drowning damage. It is a free function in `horizon_client::breathing`, so it answers and cannot call helpers. Axolotls and `WaterAnimal`s keep their own air logic. Bundles that use it need "hooks": 144.
|
||||
|
||||
API 145 adds blocks and items a native mod declares in code, as NeoForge's `DeferredRegister.Blocks` and `.Items` drained by `RegisterEvent`, instead of one content file each: `native_blocks(blocks)` and `native_items(items)`, asked once at start on every side, take `horizon_mods::content::Block` and `Item`, the declarations a content mod's `data/<id>/horizon/block/` and `item/` files hold (a vanilla template and what differs; `item: true` gives a block its item). Ids are in the mod's namespace. They join the content mods' blocks and items, inside the content mod whose id is that namespace when it is on (its models, textures, loot and recipes), else on their own with the template's look, so their network ids, saves and the joining client's content check are the files' (docs/mods.md). They pass the files' checks; a namespace whose declarations don't is logged and left out. Bundles that use them need `"hooks": 145`.
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"hooks": [
|
||||
{
|
||||
"name": "potential_spawns",
|
||||
"target": "horizon_client::game::native_hooks::Game<'_>::native_potential_spawns",
|
||||
"side": "server",
|
||||
"cancellable": true,
|
||||
"neoforge": "LevelEvent.PotentialSpawns",
|
||||
"mod_api": {
|
||||
"contract": "cancel",
|
||||
"out": "canceled"
|
||||
}
|
||||
}
|
||||
],
|
||||
"rust_summary": "Possible natural spawn entries, mutable and cancellable (`native_potential_spawns`).",
|
||||
"doc_summary": "`native_potential_spawns(dimension, category, pos, entries, canceled)` lets server mods add or remove possible natural spawn entries, or cancel to empty the list. Added entries must be globally unique instances. Bundles need \"hooks\": @API:native_potential_spawns@."
|
||||
}
|
||||
Reference in new issue
Block a user