LogoPixi’VN

Activity

The activity are actions the player can take, and they can be linked to a navigation element. The developer will decide how the player interacts with them.

Inizializzare

To initialize a activity, create a new instance of the ActivityBaseModel class (or your custom class) and add it to the game activity dictionary when the game is initialized.

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

To create a new instance of ActivityBaseModel, you need the following parameters:

  • id: Un identificatore univoco (stringa). Used to reference the activity in the game (must be unique).
  • onRun: A function that is called when the activity is run. 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.jumpLabel(napLabel, props);
        } else {
            await narration.jumpLabel(sleepLabel, props);
        }
    },
    {
        name: "bed",
    }
);

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

export const takeProduct = new ActivityBaseModel(
    "take_product",
    async (_, props) => await narration.jumpLabel(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.

To link an activity to a navigation element, you have two options:

  • Link it during navigation element initialization
  • Link it during the game

During navigation element initialization

When the game starts, a list of related activities will be defined. This list will not be saved when the game is saved. Therefore, the developer can modify this list from one version of the game to another without having to worry about migrations for older versions.

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]);

During the game

You can also link an activity to a navigation element during the game. This feature is useful if you want to temporarily add an activity. The list of activities added this way will be included in your game saves.

To link an activity to a navigation element during the game, you can use the addActivity method.

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);

Ottieni

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

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

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

Ottieni tutti

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

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

const activities = RegisteredActivities.values();

Classe personalizzata

Templates

In all templates, the Activity class is already defined in the file models/nqtr/Activity.ts. Puoi utilizzarla direttamente o modificarla in base alle tue esigenze.

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. (Per maggiori informazioni su come creare una classe in TypeScript, leggi la documentazione ufficiale)

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;
    }
}