-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
05f2e47
commit 0fa9213
Showing
4 changed files
with
183 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
--- | ||
sidebar_position: 3 | ||
id: capabilities | ||
title: Универсальные Capability | ||
description: Сохранит и синхронизирует любые ваши данные! | ||
--- | ||
|
||
Вы решили добавить игроку `шкалу маны` или добавить всем мобам новый параметр `деньги` или какие-либо другие данные? | ||
Для этого HollowCore предоставляет систему Capability с автоматическим сохранением и синхронизацией данных. | ||
|
||
## Создание Capability | ||
|
||
Для начала наследуйтесь от класса `CapabilityInstance` и добавьте какой-либо сериализуемый параметр. (с аннотацией @Serializable или наследуемый от `ru.hollowhorizon.hc.client.utils.nbt.INBTSerializable`) | ||
|
||
Далее добавьте аннотацию `@HollowCapabilityV2` с параметрами объекта, к которому Capability будет привязана ко всем объектам наследованным от указанного. | ||
Доступные варианты: `Entity` (Игроки тоже), `BlockEntity`, `Level`. | ||
Также вы можете создать интерфейс и указать его в качестве цели, тогда все объекты реализующие этот интерфейс будут иметь эту Capability. | ||
|
||
:::info Пример | ||
```kt | ||
@HollowCapabilityV2(Entity::class) | ||
class MoneyCapability : CapabilityInstance() { | ||
var money: Int by syncable(0) // Синхронизируемый параметр типа Int, все примитивные типы тоже сериализуемы | ||
} | ||
``` | ||
::: | ||
|
||
### Синхронизируемые списки | ||
|
||
Создайте делегат при помощи `syncableList<T>()`, тогда при изменении содержимого списка он автоматически будет изменён и у клиентов. | ||
|
||
:::info Пример | ||
```kt | ||
@HollowCapabilityV2(Entity::class) | ||
class DataCapability : CapabilityInstance() { | ||
var dataList by syncableList<String>() | ||
} | ||
``` | ||
::: | ||
|
||
Примечание: Конструктор должен быть пустым во избежании ошибок | ||
|
||
### Синхронизируемые Map'ы | ||
|
||
Создайте делегат при помощи `syncableMap<K, V>()`, где K - ключ, а V - значение, тогда при изменении содержимого Map он автоматически будет изменён и у клиентов. | ||
|
||
:::info Пример | ||
```kt | ||
@HollowCapabilityV2(Entity::class) | ||
class DataCapability : CapabilityInstance() { | ||
var dataList by syncableMap<Int, String>() | ||
} | ||
``` | ||
::: | ||
|
||
Примечание: Параметр K рекомендуется использовать только, как примитивный тип, если это возможно. Кроме того, все объекты рекомендуется делать одного типа, т.е. использовать `syncableMap<Number, Tag>()` - не стоит, это может привести к багам и вылетам. | ||
|
||
## Использование Capability | ||
|
||
Теперь вы можете получить экземпляр вашей Capability. При изменении данных они будут автоматически обновлены у клиентов, а также сохранены при выходе из игры / остановке сервера. | ||
|
||
:::info Пример | ||
```kt | ||
fun example(entity: Entity) { | ||
val capability = entity[MoneyCapability::class] | ||
|
||
val money: Int = capability.money // Получение значения | ||
|
||
capability.money = -100 // Изменение значения | ||
} | ||
::: | ||
|
||
## Как изменить серверное значение будучи на клиенте? | ||
|
||
Во избежании уязвимостей по умолчанию такое сделать нельзя, поскольку тогда бы злоумышленники могли бы со стороны клиента изменить значение условных денег на `99999999` и оно бы обновилось так и на клиенте. | ||
|
||
Но вы можете добавить метод для проверки на игрока (Например только для модераторов сервера), для этого переопределите внутри Capability метод `canAcceptFromClient(player: Player): Boolean`. Проверка будет вызвана только на сервере. | ||
Либо делайте свои пакеты с дополнительной проверкой корректности данных. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
--- | ||
sidebar_position: 4 | ||
id: events | ||
title: Универсальные События | ||
description: Как в Forge, но для любых загрузчиков модов! | ||
--- | ||
|
||
В игре постоянно проиходят всякие события, HollowCore позволяет ловить некоторые из них или даже отменять, если это возможно. | ||
|
||
## Список всех событий | ||
|
||
Все события так сразу и не найдёшь, некоторые из них могут предоставляться другими модами или быть созданы вами. Но основные из них вы можете найти в пакете `ru.hollowhorizon.hc.common.events`. | ||
|
||
## Создание обработчика событий | ||
|
||
Для начала создайте метод и в качестве первого аргумента укажите класс нужного вам события. После чего добавьте аннотацию `@SubscribeEvent`, при необходимости в её параметрах укажите приоритет. Чем он ниже, тем раньше будет вызван в сравнении с событиями других модов. (Это нужно чтобы вы могли отменить событие раньше других модов, если вам это очень важно) | ||
|
||
:::info Пример | ||
```kt | ||
@SubscribeEvent | ||
fun onPlayerJoin(event: PlayerEvent.Join) { // Метод запустится при входе игрока на сервер. | ||
|
||
} | ||
::: | ||
|
||
## Создание своих событий | ||
|
||
Если вам нужно создать своё события, то реализуйте интерфейс `ru.hollowhorizon.hc.common.events.Event` и при необходимости `ru.hollowhorizon.hc.common.events.Cancelable` (Если ваше событие можно будет отменить) | ||
|
||
После чего для вызова события создайте новый экземпляр класса и вызовите метод `EventBus.post(event)`, где event - экземпляр вашего класса. | ||
Если ваше событие кто-то отменил, то значение переменной `isCanceled` изменится на `true`. | ||
|
||
:::info Пример | ||
```kt | ||
class UniverseCollapseEvent(val message: String): Event, Cancelable { | ||
override var isCanceled: Boolean = false // Начальное значение отменяемого события должно быть - false (иначе смысл его отменять, не так ли?) | ||
} | ||
|
||
// Пример запуска вашего события | ||
fun somewhereInYourCode() { | ||
val event = UniverseCollapseEvent("Ой...") // Создаём событие | ||
|
||
EventBus.post(event) // Вызываем событие | ||
|
||
if(event.isCanceled) return // Если событие отменено, то завершаем метод | ||
|
||
Minecraft.crash(...) // Событие не завершено, делайте дальше, что хотите | ||
} | ||
|
||
// Пример использования вашего события | ||
@SubscribeEvent | ||
fun onUniverseCollapse(event: UniverseCollapseEvent) { | ||
event.isCanceled = true | ||
} | ||
::: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
--- | ||
sidebar_position: 1 | ||
id: registries | ||
title: Универсальная регистрация | ||
description: Создано благодаря Kotlin! | ||
--- | ||
|
||
Те, кто когда-либо писал моды под разные загрузчики наверняка заметили, что у каждого из них есть свои уникальные инструменты для регистрации игровых объектов (блоки, предметы, мобы и т.п.) | ||
HollowCore позволяет вам не париться с регистрацией объектов под каждый загрузчик, предоставляя удобную систему регистрации. | ||
|
||
## Создание нового регистратора | ||
|
||
Итак, прежде всего создайте object-класс, наследуемый от `HollowRegistry`, в нём и будет проходить вся регистрация. | ||
|
||
:::info Пример | ||
```kt | ||
object ModItems : HollowRegistry() { | ||
|
||
} | ||
``` | ||
::: | ||
|
||
## Регистрация игрового объекта | ||
|
||
HollowCore позволяет регистрировать практически все игровые объекты. Определяет тип регистратора он автоматически, вам лишь нужно создать делегат с помощью метода `register(location: ResourceLocation, () -> T): RegistryObject<T>`, где T - класс вашего объекта. | ||
|
||
:::info Пример | ||
```kt | ||
object ModItems : HollowRegistry() { | ||
val MY_ITEM by register("modid:my_item".rl) { // .rl - сокращение от ResourceLocation. На разных версиях он создаётся по-разному, так что был создан универсальный вариант. | ||
MyItem() // Объект вашего предмета | ||
} | ||
} | ||
``` | ||
::: | ||
|
||
Аналогично регистрируются и все остальные игровые объекты, просто передаёте нужный объект. | ||
|
||
## Использование игрововых объектов | ||
|
||
Теперь, когда объект зарегистрирован вы можете его получить с помочью метода `RegistryObject<T>.get()`. | ||
|
||
:::info Пример | ||
```kt | ||
fun getMyItem(): MyItem { | ||
return ModItems.MY_ITEM.get() | ||
} | ||
``` | ||
::: |