V3 Doc Event Editor - PokemonWorkshop/PokemonStudio GitHub Wiki
The Event Editor is a central component of Pokémon Studio to manage the event commands. It allows game creators to manage the event commands.
The Event Editor uses the library xyflow (= reactflow). This allows commands to be presented in a graph form. There are three fundamental entities:
- Command: it's a node
- Link between commands: in xyflow, they are named edges
- Handle: the anchor points that can be placed on a node and used to link them
File: src\views\components\world\event\EventEditor.tsx
Users can:
- Drag & Drop a command from the Command Library to add a command in the event
- Delete a command using DEL key
- Move a command
- Edit a command
- Connect a command
Multiple selection is available for deleting and moving commands.
Folder: src\views\components\world\event\commands
- Create a command node component (ex: InsertScriptCommand)
- Follow this template for the implementation:
const MY_COMMAND_EDITOR_SCHEMA = EVENT_COMMAND_MY_COMMAND_VALIDATOR.pick({ /* use the props needed */ });
export const MyCommandCommand = ({ id, data: { dialogsRef, command, comments }, selected }: CommandNodeProps) => {
const { CommandNode, updateCommand } = useCommandNode<StudioEventCommandMyCommand>(id);
const { type: commandType, ...commandData } = command as StudioEventCommandData<StudioEventCommandMyCommand>;
const { canClose, getFormData, reload, defaults, formRef } = useZodForm(MY_COMMAND_EDITOR_SCHEMA, commandData);
const { /* use the components needed */ } = useNodeInputAttrsWithLabel(MY_COMMAND_EDITOR_SCHEMA, defaults);
const { t } = useTranslation();
const onBlur = () => {
const result = canClose() && getFormData();
if (!result || !result.success) return;
updateCommand(result.data);
};
useEffect(() => {
reload(commandData);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [command]);
return (
<CommandNode commandType={commandType} commentCount={comments.length} dialogsRef={dialogsRef} nodeId={id} selected={selected}>
{/*Here you can define more handles (two handles are created by default)*/}
<InputFormContainer ref={formRef} onBlur={onBlur}>
{/*Here is the content of the node*/}
</InputFormContainer>
</CommandNode>
);
};File: src\utils\eventCommandCreation.ts
- Create a function to define default values
Example for the insert script command:
const insertScriptCommand = { script: '' };
export const EventCommandCreation: Record<StudioEventCommandType, Omit<StudioEventCommandData<StudioEventCommand>, 'type'>> = {
show_message: {},
...,
insert_script: insertScriptCommand, /*Add Command here*/
};Folder: src\views\components\world\event\commands\editors
- Create a command editor component (ex: InsertScriptEditor)
- Follow this template for the implementation:
const NEW_COMMAND_EDITOR_SCHEMA = EVENT_COMMAND_NEW_COMMAND_VALIDATOR.pick({ /*Select the useful properties*/ });
export const NewCommandEditor = forwardRef<EditorHandlingClose, EventEditorProps>(({ commandId: defaultCommandId, event }, ref) => {
const { command, updateCommand } = useCommandEditor<StudioEventCommandInsertScript>(event, defaultCommandId);
const { canClose, getFormData, defaults, formRef } = useZodForm(NEW_COMMAND_EDITOR_SCHEMA, command);
const { Input } = useInputAttrsWithLabel(NEW_COMMAND_EDITOR_SCHEMA, defaults);
const { t } = useTranslation();
const onClose = () => {
const result = canClose() && getFormData();
if (!result || !result.success) return;
updateCommand(result.data);
};
useEditorHandlingClose(ref, onClose, canClose);
return (
<Editor type="edit" title={t(`event_command_new_command`)}>
<InputFormContainer ref={formRef}>
<Input name="" label={t(`event_command_label`)} />
</InputFormContainer>
</Editor>
);
});
NewCommandEditor.displayName = 'NewCommandEditor';File: src\views\components\world\event\commands\editors\CommandEditorOverlay.tsx
- Add the command editor in the switch case
Example for the insert script command:
export const CommandEditorOverlay = defineEditorOverlay<CommandEditorAndDeletionKeys, { commandId?: CommandId; event: StudioEvent }>(
'CommandEditorOverlay',
(dialogToShow, handleCloseRef, closeDialog, { commandId, event }) => {
switch (dialogToShow) {
case 'show_message':
...
case 'insert_script':
/* Add Editor here */
return <InsertScriptEditor commandId={commandId} event={event} ref={handleCloseRef} />;
...
}
}
);File: src\views\components\world\event\common\EventIcon.tsx
- Add a new color in
EventColor(if necessary) - Add the icon and the color in
IconsFromCommand