LogoPixi’VN

Activity

Activity - действия, которые игрок может предпринять, и они могут быть связаны с элементом навигации. Разработчик решает, как игрок будет с ними взаимодействовать.

Инициализация

Чтобы инициализировать персонажа, создайте новый экземпляр класса CharacterBaseModel (или вашего пользовательского класса) и добавьте его в словарь игровых персонажей, когда игра будет инициализирована.

It is recommended to import the instances at project startup, see the src/main.ts file.

Чтобы создать новый экземпляр CharacterBaseModel, вам нужны следующие параметры:

  • id: A unique identifier (string). Used to reference the activity in the game (must be unique).
  • onRun: Функция, которая вызывается при запуске активности. It receives two parameters:
    • The activity instance itself.
    • props: the properties that will be passed to the activity. Its interface corresponds to OnRunProps.
  • props: An object with the activity's properties:
    • name: The name of the activity (Optional).
    • timeSlot: The time slot in which the activity will be active (Optional).
    • dateScheduling: Used to schedule what date it will be added and removed (Optional).
    • disabled: Whether the activity is disabled. You can also pass a Pixi'VN flag name (optional, default is false).
    • hidden: Whether the activity is hidden. You can also pass a Pixi'VN flag name (optional, default is false).
    • renderIcon: The icon of the activity (Optional).
import { ActivityBaseModel, RegisteredActivities, timeTracker } from "@drincs/nqtr";
import { narration } from "@drincs/pixi-vn";
import { napLabel, sleepLabel } from "../labels/sleepNapLabels";
import { orderProductLabel, takeKeyLabel } from "../labels/variousActionsLabels";

export const bed = new ActivityBaseModel(
    "bed",
    async (_, props) => {
        if (timeTracker.nowIsBetween(5, 22)) {
            await narration.jump(napLabel, props);
        } else {
            await narration.jump(sleepLabel, props);
        }
    },
    {
        name: "bed",
    }
);

export const orderProduct = new ActivityBaseModel(
    "order_product",
    async (_, props) => await narration.jump(orderProductLabel, props),
    {
        name: "order_product",
    }
);

export const takeProduct = new ActivityBaseModel(
    "take_product",
    async (_, props) => await narration.jump(takeKeyLabel, props),
    {
        name: "take_product",
    }
);

RegisteredActivities.add([bed, orderProduct, takeProduct]);

RegisteredActivities.add is required to save the activities in the game.

You can also create a function to load activities. The important thing is that it is called at least once before the activities are used in the game, otherwise they will not be available.

Ссылка

Чтобы связать действие с элементом навигации, у вас есть два варианта:

During game initialization

Когда игра начнется, будет определен список связанных с ней действий. Этот список не будет сохранен при сохранении игры. Таким образом, разработчик может изменять этот список от одной версии игры к другой, не беспокоясь о переносе старых версий.

import { RegisteredRooms, RoomBaseModel } from "@drincs/nqtr";
import { bed } from "./activity";
import { mcHome } from "./locations";

export const mcRoom = new RoomBaseModel("mc_room", mcHome, {
    name: "MC room",
    image: "location_myroom",
    activities: [bed],
});

RegisteredRooms.add([mcRoom]);

В ходе игры

Вы также можете связать действие с элементом навигации во время игры. Эта функция полезна, если вы хотите временно добавить активность. Список действий, добавленных таким образом, будет включен в ваши игровые сохранения.

Чтобы привязать активность к элементу навигации во время игры, можно использовать метод addActivity.

import { orderProduct } from "../activities";
import { mcRoom } from "../rooms";

mcRoom.addActivity(orderProduct); 

To unlink an activity from a navigation element, you can use the removeActivity method.

import { orderProduct } from "../activities";
import { mcRoom } from "../rooms";

mcRoom.removeActivity(orderProduct);

Get

To get a activity by its id, use the RegisteredActivities.get function.

import { RegisteredActivities } from "@drincs/nqtr";

const orderProduct = RegisteredActivities.get('order_product');

Получить все

To get all activities, use the RegisteredActivities.values function.

import { RegisteredActivities } from "@drincs/nqtr";

const activities = RegisteredActivities.values();

Пользовательский класс

Templates

In all templates, the Activity class is already defined in the file models/nqtr/Activity.ts. Вы можете использовать это напрямую или изменить его в соответствии с вашими потребностями.

It is recommended to create your own class Activity that extends ActivityStoredClass and "override" the interface ActivityInterface to add, edit, or remove properties or methods.

For example, if you want to create a class Activity, you must "override" the interface ActivityInterface to use your properties or methods. (See the file nqtr.d.ts)

Now you can create a class Activity that extends ActivityStoredClass and implements the ActivityInterface. (Для получения дополнительной информации о том, как создать класс в TypeScript, прочитайте официальную документацию)

To create a property that stores its value in the game storage, you can create Getters/Setters and use the this.getStorageProperty() / this.setStorageProperty() methods. (See the file Activity.ts)

import { ActivityInterface, ActivityStoredClass, ActivityStoredClassProps, OnRunEvent, OnRunProps } from "@drincs/nqtr";
import { ReactElement } from "react";

export default class Activity extends ActivityStoredClass implements ActivityInterface {
    constructor(
        id: string,
        onRun: OnRunEvent<ActivityInterface>,
        props: {
            name?: string;
            sprite?: string | ContainerChild | ((props: Activity, runProps: OnRunProps) => ContainerChild);
            icon?: ReactElement | ((props: Activity, runProps: OnRunProps) => ReactElement);
            disabled?: boolean | (() => boolean);
            hidden?: boolean | (() => boolean);
        } & ActivityStoredClassProps
    ) {
        super(id, onRun, props);
        this.name = props.name || "";
        this._sprite = props.sprite;
        this._icon = props.icon;
        this._defaultDisabled = props.disabled || false;
        this._defaultHidden = props.hidden || false;
    }
    readonly name: string;
    private readonly _sprite?: string | ContainerChild | ((props: Activity, runProps: OnRunProps) => ContainerChild);
    get sprite(): string | ContainerChild | ((props: OnRunProps) => ContainerChild) | undefined {
        const sprite = this._sprite;
        if (typeof sprite === "function") {
            return (runProps: OnRunProps) => sprite(this, runProps);
        }
        return sprite;
    }
    private readonly _icon?: ReactElement | ((props: Activity, runProps: OnRunProps) => ReactElement);
    get icon(): ReactElement | ((props: OnRunProps) => ReactElement) | undefined {
        const icon = this._icon;
        if (typeof icon === "function") {
            return (runProps: OnRunProps) => icon(this, runProps);
        }
        return icon;
    }
    private _defaultDisabled: boolean | (() => boolean) = false;
    get disabled(): boolean {
        let value = this.getStorageProperty<boolean>("disabled") || this._defaultDisabled;
        if (typeof value === "function") {
            return value();
        }
        return value;
    }
    set disabled(value: boolean) {
        this.setStorageProperty("disabled", value);
    }
    private _defaultHidden: boolean | (() => boolean) = false;
    get hidden(): boolean {
        let value = this.getStorageProperty<boolean>("hidden") || this._defaultHidden;
        if (typeof value === "function") {
            return value();
        }
        return value;
    }
    set hidden(value: boolean) {
        this.setStorageProperty("hidden", value);
    }
    override get isActive(): boolean {
        if (this.hidden) {
            return false;
        }
        return super.isActive;
    }
}