Skip to content

Commit

Permalink
[MIK-255] Add custom item creation to novel builder (#126)
Browse files Browse the repository at this point in the history
* Add scene conditions

* add scenes conditions component

* add condition edit modal

* wip

* add styles and fix scene selection

* add inventory in novel state

* create item list and item edit modal

* add tooltip and fix styles in inventory item list

* create item edit form

* add item selection in condition

* add item selection and lock by condition and/or scene

* migration fron scene conditions to novel objectives

* SuperFIX novel actions state

* WIP general style fixing

* add scenes and items in NovelActionForm

* add items selection and lock by scene

* add action selection in itemEditModal

* Change itemEditModal styles

* hot fixes

* add objective selection by scene

* Add custom items in  interactor novel loader

* hot fix inputs in item edit modal

* add only scene visibility

* Change some style details

* FIX remove current item from the list in novelActionForm

* WIP add warnings

* change error messages and severities

* hot fixes in errors displayer

* hot fix item selection

* add multiple usage actions for item action

* Fix NovelAction import

* Use single component for Scene selection, remove duplicated code

* remove item selection from scene edit modal

* create action edit modal, and remove  action form from item edit

* [HOT-FIX] scene selector in place edit modal

* Fix styles in item edit modal and add scene selector for scene lock

* remove unused code in novel actions form

* add title in item edit modal

* [HOT-FIX] change selectEditingAction in selectors

* Fix inventory order, non-locked should be disabled

* Remove deprecated field in novel builder

* Fix typo

* Fix inventory style for novel-only items

---------

Co-authored-by: mikudev <[email protected]>
  • Loading branch information
Lredigonda and miku448 authored Jul 11, 2024
1 parent c3da403 commit 90d2221
Show file tree
Hide file tree
Showing 45 changed files with 2,760 additions and 485 deletions.
3 changes: 2 additions & 1 deletion apps/bot-directory/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ node_modules
dist
_temp
db
!db/assets/RenPyExport.zip
!db/assets/RenPyExport.zip
!db/assets/add_item.jpg
Binary file added apps/bot-directory/db/assets/add_item.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
52 changes: 39 additions & 13 deletions apps/interactor/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,18 @@ import queryString from 'query-string'
import { PersonaResult } from './src/libs/listSearch'
import { loadNovelFromSingleCard } from './src/libs/loadNovel'

import { DEFAULT_INVENTORY } from './src/libs/inventoryItems'
import {
getUnlockableAchievements,
getUnlockedItems,
} from './src/libs/platformAPI'
import { initialState as initialCreationState } from './src/state/slices/creationSlice'
import { initialState as initialSettingsState } from './src/state/slices/settingsSlice'
import { initialState as initialInventoryState } from './src/state/slices/inventorySlice'
import { scenesToObjectives } from './src/state/slices/objectivesSlice'
import { initialState as initialSettingsState } from './src/state/slices/settingsSlice'
import { RootState } from './src/state/store'
import { VersionId } from './src/state/versioning'
import { migrateV1toV2, migrateV2toV3 } from './src/state/versioning/migrations'
import { scenesToObjectives } from './src/state/slices/objectivesSlice'
import {
getUnlockableAchievements,
getUnlockedItems,
} from './src/libs/platformAPI'
import { DEFAULT_INVENTORY } from './src/libs/inventoryItems'

if (import.meta.env.VITE_SENTRY_DSN) {
Sentry.init({
Expand Down Expand Up @@ -193,11 +193,16 @@ export const loadNarration = async (): Promise<RootState> => {
...migrated,
objectives: [
...scenesToObjectives(migrated.novel.scenes),
...(migrated.novel.objectives || []),
...achievements,
],
inventory: {
...initialInventoryState,
items: [...inventoryItems, ...DEFAULT_INVENTORY],
items: [
...(migrated.novel.inventory || []),
...inventoryItems,
...DEFAULT_INVENTORY,
],
},
creation: initialCreationState,
settings: mergeWith(
Expand All @@ -216,11 +221,16 @@ export const loadNarration = async (): Promise<RootState> => {
...migrated,
objectives: [
...scenesToObjectives(migrated.novel.scenes),
...(migrated.novel.objectives || []),
...achievements,
],
inventory: {
...initialInventoryState,
items: [...inventoryItems, ...DEFAULT_INVENTORY],
items: [
...(migrated.novel.inventory || []),
...inventoryItems,
...DEFAULT_INVENTORY,
],
},
creation: initialCreationState,
settings: mergeWith(
Expand All @@ -237,10 +247,18 @@ export const loadNarration = async (): Promise<RootState> => {
}
return {
...data,
objectives: [...scenesToObjectives(data.novel.scenes), ...achievements],
objectives: [
...scenesToObjectives(data.novel.scenes),
...(data.novel.objectives || []),
...achievements,
],
inventory: {
...initialInventoryState,
items: [...inventoryItems, ...DEFAULT_INVENTORY],
items: [
...(data.novel.inventory || []),
...inventoryItems,
...DEFAULT_INVENTORY,
],
},
creation: initialCreationState,
settings: mergeWith(
Expand All @@ -258,10 +276,18 @@ export const loadNarration = async (): Promise<RootState> => {
return {
novel,
narration,
objectives: [...scenesToObjectives(novel.scenes), ...achievements],
objectives: [
...scenesToObjectives(novel.scenes),
...(novel.objectives || []),
...achievements,
],
inventory: {
...initialInventoryState,
items: [...inventoryItems, ...DEFAULT_INVENTORY],
items: [
...(novel.inventory || []),
...inventoryItems,
...DEFAULT_INVENTORY,
],
},
creation: initialCreationState,
settings: mergeWith(
Expand Down
5 changes: 4 additions & 1 deletion apps/interactor/src/components/history/History.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,10 @@ const HistoryActions = () => {
dispatch(
replaceState({
...stateJson,
objectives: [...scenesToObjectives(stateJson.novel.scenes)],
objectives: [
...scenesToObjectives(stateJson.novel.scenes),
...(stateJson.novel.objectives || []),
],
inventory: {
...initialInventoryState,
...(stateJson.inventory || {}),
Expand Down
25 changes: 22 additions & 3 deletions apps/interactor/src/components/interactor/Inventory.scss
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@
width: 74px;
height: 74px;

opacity: 0.5;
background-color: $background-1;

border-radius: 10px;
Expand Down Expand Up @@ -153,11 +152,11 @@
&.disabled {
// back and white filter
filter: grayscale(100%);
opacity: 0.5;
opacity: 0.7;

&:hover {
border: 2px solid transparent;
opacity: 0.5;
opacity: 0.7;

.Inventory__item-price {
background-color: $background-1;
Expand All @@ -169,6 +168,22 @@
}
}

&.highlighted {
border: 2px solid $color-gold !important;
opacity: 1;
// animate box shadow
animation: box-shadow-animation 0.5s ease-in-out infinite alternate;

@keyframes box-shadow-animation {
0% {
box-shadow: 0 0 0px $color-gold;
}
100% {
box-shadow: 0 0 20px $color-gold;
}
}
}

&:hover {
border: 2px solid #aaa1ff;
opacity: 1;
Expand Down Expand Up @@ -196,6 +211,10 @@
}
}

.hidden {
display: none;
}

.InventoryItemModal {
width: 163px;
min-width: 163px;
Expand Down
62 changes: 38 additions & 24 deletions apps/interactor/src/components/interactor/Inventory.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
import { Button, Tooltip } from '@mikugg/ui-kit'
import { useAppDispatch, useAppSelector } from '../../state/store'
import { NovelV3 } from '@mikugg/bot-utils'
import {
setInventoryVisibility,
setItemModalVisibility,
setSelectedItem,
} from '../../state/slices/inventorySlice'
import { Button, Tooltip } from '@mikugg/ui-kit'
import { FaTimes } from 'react-icons/fa'
import './Inventory.scss'
import { toast } from 'react-toastify'
import { useAppContext } from '../../App.context'
import { interactionStart } from '../../state/slices/narrationSlice'
import { novelActionToStateAction } from '../../state/mutations'
import {
selectConditionStatus,
selectCurrentScene,
selectLastLoadedResponse,
} from '../../state/selectors'
import { toast } from 'react-toastify'
import { mutationToAction } from '../../state/mutations'
import {
setInventoryVisibility,
setItemModalVisibility,
setSelectedItem,
} from '../../state/slices/inventorySlice'
import { interactionStart } from '../../state/slices/narrationSlice'
import { useAppDispatch, useAppSelector } from '../../state/store'
import './Inventory.scss'
import classNames from 'classnames'

export default function Inventory() {
const dispatch = useAppDispatch()
const { isPremium } = useAppSelector((state) => state.settings.user)
const { showInventory, selectedItem, items } = useAppSelector(
(state) => state.inventory
)
const currentScene = useAppSelector(selectCurrentScene)
const {
servicesEndpoint,
isInteractionDisabled,
Expand Down Expand Up @@ -54,15 +56,22 @@ export default function Inventory() {
const position = Math.max(item.name.length + 10, 20)
const animationDuration = Math.max(item.name.length / speed, 3)
const isSelectedItem = item.id === selectedItem?.id
const disabled = !isPremium && item.isPremium

const isLocked = item.locked?.config.sceneIds.includes(
currentScene?.id || ''
)
const disabled =
(!isPremium && item.isPremium) || (item.locked && !isLocked)
const isHidden = item.hidden
return (
<div
key={item.id}
className={`Inventory__item ${
isSelectedItem ? 'selected' : ''
} ${disabled ? 'disabled' : ''}
`}
className={classNames({
Inventory__item: true,
selected: isSelectedItem,
disabled: disabled,
hidden: isHidden,
highlighted: item.isNovelOnly && !disabled,
})}
onClick={() => {
if (disabled) return
if (!isSelectedItem) {
Expand All @@ -76,10 +85,14 @@ export default function Inventory() {
}, 150)
}
}}
data-tooltip-id={disabled ? 'premium-item-invetory' : undefined}
data-tooltip-id={
disabled ? 'premium-item-inventory' : undefined
}
data-tooltip-varaint="light"
data-tooltip-content={
disabled ? 'This is a premium-only item' : undefined
disabled && item.isPremium
? 'This is a premium-only item'
: undefined
}
>
<img
Expand All @@ -105,7 +118,7 @@ export default function Inventory() {
)
})}
</div>
<Tooltip id="premium-item-invetory" place="right" />
<Tooltip id="premium-item-inventory" place="right" />
<Tooltip id="item-name" place="top" />
<InventoryItemModal
item={selectedItem}
Expand Down Expand Up @@ -133,10 +146,11 @@ export default function Inventory() {
})
)
}
if (action.usageMutations) {
action.usageMutations.forEach((mutation) =>
dispatch(mutationToAction(mutation))
)
if (action.usageActions) {
action.usageActions.forEach((novelAction) => {
const action = novelActionToStateAction(novelAction)
if (action) dispatch(action)
})
}
}}
/>
Expand Down
44 changes: 26 additions & 18 deletions apps/interactor/src/libs/platformAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,27 +70,35 @@ export const getUnlockableAchievements = async (
id: achievement.id,
name: achievement.name,
description: achievement.description,
sceneIds: achievement.scenes,
singleUse: true,
stateCondition: {
type: 'IN_SCENE',
config: {
sceneIds: achievement.scenes,
},
},
condition: achievement.condition,
action: {
type: NovelV3.NovelObjectiveActionType.ACHIEVEMENT_UNLOCK,
params: {
achievementId: achievement.id,
reward: {
id: achievement.inventoryItem.id,
name: achievement.inventoryItem.name,
description: achievement.inventoryItem.description,
icon: achievement.inventoryItem.icon,
isPremium: achievement.inventoryItem.isPremium,
actions: achievement.inventoryItem.actions.map((action) => {
return {
name: action.name,
prompt: action.prompt,
}
}),
actions: [
{
type: NovelV3.NovelActionType.ACHIEVEMENT_UNLOCK,
params: {
achievementId: achievement.id,
reward: {
id: achievement.inventoryItem.id,
name: achievement.inventoryItem.name,
description: achievement.inventoryItem.description,
icon: achievement.inventoryItem.icon,
isPremium: achievement.inventoryItem.isPremium,
actions: achievement.inventoryItem.actions.map((action) => {
return {
name: action.name,
prompt: action.prompt,
}
}),
},
},
},
},
],
}
})
} catch (error) {
Expand Down
Loading

0 comments on commit 90d2221

Please sign in to comment.