Skip to content

Commit

Permalink
feat: health smart items (#915)
Browse files Browse the repository at this point in the history
* feat: added actions to position/scale/rotate on player/camera or any position, and to follow/unfollow player

* fix: clone

* feat: basic smart items working

* feat: customize counter bar

* fix: counter bar default value

* feat: increment/decrease amount

* feat: random and batch actions

* feat: layers and hits

* feat: refactor proximity to damage

* feat: heal player integration

* feat: support relative

* feat: added health category

* feat: upgrade @dcl/asset-packs

* chore: fix test

* feat: feedback

* fix: follow player action
  • Loading branch information
cazala authored Mar 18, 2024
1 parent b928160 commit 1e8de58
Show file tree
Hide file tree
Showing 50 changed files with 1,166 additions and 73 deletions.
36 changes: 19 additions & 17 deletions packages/@dcl/inspector/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/@dcl/inspector/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@dcl/inspector",
"version": "0.1.0",
"dependencies": {
"@dcl/asset-packs": "^1.13.0",
"@dcl/asset-packs": "^1.14.0",
"ts-deepmerge": "^7.0.0"
},
"devDependencies": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ import { DelayAction } from './DelayAction'
import { LoopAction } from './LoopAction'
import { CloneEntityAction } from './CloneEntityAction'
import { ShowImageAction } from './ShowImageAction'
import { FollowPlayerAction } from './FollowPlayerAction'
import TriggerProximityAction from './TriggerProximityAction/TriggerProximityAction'
import SetPositionAction from './SetPositionAction/SetPositionAction'
import { SetRotationAction } from './SetRotationAction'
import { SetScaleAction } from './SetScaleAction'
import { RandomAction } from './RandomAction'
import { BatchAction } from './BatchAction'
import { getDefaultPayload, getPartialPayload, isStates } from './utils'
import { Props } from './types'

Expand Down Expand Up @@ -84,7 +91,21 @@ const ActionMapOption: Record<string, string> = {
[ActionType.CLONE_ENTITY]: 'Clone',
[ActionType.REMOVE_ENTITY]: 'Remove',
[ActionType.SHOW_IMAGE]: 'Show Image',
[ActionType.HIDE_IMAGE]: 'Hide Image'
[ActionType.HIDE_IMAGE]: 'Hide Image',
[ActionType.FOLLOW_PLAYER]: 'Follow Player',
[ActionType.STOP_FOLLOWING_PLAYER]: 'Stop Following Player',
[ActionType.MOVE_PLAYER_HERE]: 'Move Player Here',
[ActionType.DAMAGE]: 'Damage',
[ActionType.PLACE_ON_PLAYER]: 'Place On Player',
[ActionType.ROTATE_AS_PLAYER]: 'Rotate As Player',
[ActionType.PLACE_ON_CAMERA]: 'Place On Camera',
[ActionType.ROTATE_AS_CAMERA]: 'Rotate As Camera',
[ActionType.SET_POSITION]: 'Set Position',
[ActionType.SET_ROTATION]: 'Set Rotation',
[ActionType.SET_SCALE]: 'Set Scale',
[ActionType.RANDOM]: 'Random Action',
[ActionType.BATCH]: 'Batch Actions',
[ActionType.HEAL_PLAYER]: 'Heal Player'
}

export default withSdk<Props>(({ sdk, entity: entityId }) => {
Expand Down Expand Up @@ -341,6 +362,18 @@ export default withSdk<Props>(({ sdk, entity: entityId }) => {
[modifyAction, actions]
)

const handleChangeAmount = useCallback(
({ target: { value } }: React.ChangeEvent<HTMLInputElement>, idx: number) => {
modifyAction(idx, {
...actions[idx],
jsonPayload: getJson<ActionType.INCREMENT_COUNTER | ActionType.DECREASE_COUNTER>({
amount: parseInt(value)
})
})
},
[modifyAction, actions]
)

const handleChangeAnchorPoint = useCallback(
({ target: { value } }: React.ChangeEvent<HTMLSelectElement>, idx: number) => {
modifyAction(idx, {
Expand Down Expand Up @@ -488,6 +521,66 @@ export default withSdk<Props>(({ sdk, entity: entityId }) => {
[modifyAction, actions]
)

const handleChangeFollowPlayer = useCallback(
(value: ActionPayload<ActionType.FOLLOW_PLAYER>, idx: number) => {
modifyAction(idx, {
...actions[idx],
jsonPayload: getJson<ActionType.FOLLOW_PLAYER>(value)
})
},
[modifyAction, actions]
)

const handleChangeTriggerProximity = useCallback(
(value: ActionPayload<ActionType.DAMAGE>, idx: number) => {
modifyAction(idx, {
...actions[idx],
jsonPayload: getJson<ActionType.DAMAGE>(value)
})
},
[modifyAction, actions]
)

const handleSetPosition = useCallback(
(value: ActionPayload<ActionType.SET_POSITION>, idx: number) => {
modifyAction(idx, {
...actions[idx],
jsonPayload: getJson<ActionType.SET_POSITION>(value)
})
},
[modifyAction, actions]
)

const handleSetRotation = useCallback(
(value: ActionPayload<ActionType.SET_ROTATION>, idx: number) => {
modifyAction(idx, {
...actions[idx],
jsonPayload: getJson<ActionType.SET_ROTATION>(value)
})
},
[modifyAction, actions]
)

const handleSetScale = useCallback(
(value: ActionPayload<ActionType.SET_SCALE>, idx: number) => {
modifyAction(idx, {
...actions[idx],
jsonPayload: getJson<ActionType.SET_SCALE>(value)
})
},
[modifyAction, actions]
)

const handleChangeActions = useCallback(
(value: ActionPayload<ActionType.RANDOM | ActionType.BATCH>, idx: number) => {
modifyAction(idx, {
...actions[idx],
jsonPayload: getJson<ActionType.RANDOM | ActionType.BATCH>(value)
})
},
[modifyAction, actions]
)

const handleFocusInput = useCallback(
({ type }: React.FocusEvent<HTMLInputElement>) => {
if (type === 'focus') {
Expand Down Expand Up @@ -519,6 +612,16 @@ export default withSdk<Props>(({ sdk, entity: entityId }) => {
[modifyAction, actions]
)

const createHandler = <T extends ActionType>(getPayload: (value: string) => ActionPayload<T>, idx: number) => {
const handler = ({ target: { value } }: React.ChangeEvent<HTMLInputElement>) => {
modifyAction(idx, {
...actions[idx],
jsonPayload: getJson<T>(getPayload(value))
})
}
return handler
}

const handleRemoveAction = useCallback(
(_e: React.MouseEvent, idx: number) => {
removeAction(idx)
Expand Down Expand Up @@ -578,6 +681,34 @@ export default withSdk<Props>(({ sdk, entity: entityId }) => {
</div>
) : null
}
case ActionType.INCREMENT_COUNTER: {
return hasCounter ? (
<div className="row">
<div className="field">
<TextField
label="Amount"
type="number"
value={getPartialPayload<ActionType.INCREMENT_COUNTER>(action)?.amount}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => handleChangeAmount(e, idx)}
/>
</div>
</div>
) : null
}
case ActionType.DECREASE_COUNTER: {
return hasCounter ? (
<div className="row">
<div className="field">
<TextField
label="Amount"
type="number"
value={getPartialPayload<ActionType.DECREASE_COUNTER>(action)?.amount}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => handleChangeAmount(e, idx)}
/>
</div>
</div>
) : null
}
case ActionType.PLAY_SOUND: {
return (
<PlaySoundAction
Expand Down Expand Up @@ -714,6 +845,71 @@ export default withSdk<Props>(({ sdk, entity: entityId }) => {
/>
)
}
case ActionType.FOLLOW_PLAYER:
return (
<FollowPlayerAction
value={getPartialPayload<ActionType.FOLLOW_PLAYER>(action)}
onUpdate={(e) => handleChangeFollowPlayer(e, idx)}
/>
)
case ActionType.DAMAGE:
return (
<TriggerProximityAction
value={getPartialPayload<ActionType.DAMAGE>(action)}
onUpdate={(e) => handleChangeTriggerProximity(e, idx)}
/>
)
case ActionType.SET_POSITION:
return (
<SetPositionAction
value={getPartialPayload<ActionType.SET_POSITION>(action)}
onUpdate={(e) => handleSetPosition(e, idx)}
/>
)
case ActionType.SET_ROTATION:
return (
<SetRotationAction
value={getPartialPayload<ActionType.SET_ROTATION>(action)}
onUpdate={(e) => handleSetRotation(e, idx)}
/>
)
case ActionType.SET_SCALE:
return (
<SetScaleAction
value={getPartialPayload<ActionType.SET_SCALE>(action)}
onUpdate={(e) => handleSetScale(e, idx)}
/>
)
case ActionType.RANDOM:
return (
<RandomAction
value={getPartialPayload<ActionType.RANDOM>(action)}
availableActions={actions}
onUpdate={(e) => handleChangeActions(e, idx)}
/>
)
case ActionType.BATCH:
return (
<BatchAction
value={getPartialPayload<ActionType.BATCH>(action)}
availableActions={actions}
onUpdate={(e) => handleChangeActions(e, idx)}
/>
)
case ActionType.HEAL_PLAYER: {
return (
<div className="row">
<div className="field">
<TextField
label="Multiplier"
type="number"
value={getPartialPayload<ActionType.HEAL_PLAYER>(action)?.multiplier || 1}
onChange={createHandler<ActionType.HEAL_PLAYER>((value) => ({ multiplier: parseInt(value) }), idx)}
/>
</div>
</div>
)
}
default: {
// TODO: handle generic schemas with something like <JsonSchemaField/>
return null
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.BatchActionContainer {
display: flex;
flex-direction: column;
width: 100%;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React, { useCallback, useEffect, useMemo, useState } from 'react'
import { ActionPayload, ActionType } from '@dcl/asset-packs'
import { recursiveCheck } from 'jest-matcher-deep-close-to/lib/recursiveCheck'
import { Block } from '../../../Block'
import { Dropdown } from '../../../ui'
import type { DropdownChangeEvent } from '../../../ui'
import type { Props } from './types'

import './BatchAction.css'

function isValid(payload: Partial<ActionPayload<ActionType.RANDOM>>): payload is ActionPayload<ActionType.RANDOM> {
return payload.actions !== undefined && payload.actions.length > 0
}

const BatchAction: React.FC<Props> = ({ availableActions, value, onUpdate }: Props) => {
const [payload, setPayload] = useState<Partial<ActionPayload<ActionType.RANDOM>>>({
...value
})

useEffect(() => {
if (!recursiveCheck(payload, value, 2) || !isValid(payload)) return
onUpdate(payload)
}, [payload, onUpdate])

const actions = useMemo(() => {
return availableActions.map((action) => ({ value: action.name, label: action.name }))
}, [availableActions])

const handleChangeAction = useCallback(
({ target: { value } }: DropdownChangeEvent) => {
setPayload({ ...payload, actions: value as any[] })
},
[payload, setPayload]
)

return (
<div className="BatchActionContainer">
<Block>
<Dropdown label="Action(s)" options={actions} value={payload.actions} multiple onChange={handleChangeAction} />
</Block>
</div>
)
}

export default BatchAction
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import BatchAction from './BatchAction'

export { BatchAction }
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Action, ActionPayload, ActionType } from '@dcl/asset-packs'

export interface Props {
availableActions: Action[]
value: Partial<ActionPayload<ActionType.BATCH>>
onUpdate: (value: ActionPayload<ActionType.BATCH>) => void
}
Loading

0 comments on commit 1e8de58

Please sign in to comment.