mirror of
https://github.com/duckietm/Nitro-V3.git
synced 2026-06-19 15:06:20 +00:00
🆙 Small fixes for the Area and Neighborhood Wired
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { GetRoomEngine, RoomAreaSelectionManager } from '@nitrots/nitro-renderer';
|
||||
import { GetRoomEngine, RoomAreaSelectionManager, RoomObjectCategory } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { LocalizeText } from '../../../../api';
|
||||
import { Button, Text } from '../../../../common';
|
||||
@@ -11,13 +11,16 @@ export const WiredActionFurniAreaView: FC<{}> = props =>
|
||||
const [ rootY, setRootY ] = useState(0);
|
||||
const [ areaWidth, setAreaWidth ] = useState(0);
|
||||
const [ areaHeight, setAreaHeight ] = useState(0);
|
||||
const [ filterExisting, setFilterExisting ] = useState(false);
|
||||
const [ invert, setInvert ] = useState(false);
|
||||
const { trigger = null, setIntParams } = useWired();
|
||||
|
||||
const save = useCallback(() =>
|
||||
{
|
||||
setIntParams([ rootX, rootY, areaWidth, areaHeight ]);
|
||||
}, [ rootX, rootY, areaWidth, areaHeight, setIntParams ]);
|
||||
setIntParams([ rootX, rootY, areaWidth, areaHeight, filterExisting ? 1 : 0, invert ? 1 : 0 ]);
|
||||
}, [ rootX, rootY, areaWidth, areaHeight, filterExisting, invert, setIntParams ]);
|
||||
|
||||
// Activate the area selection manager when dialog opens, deactivate on close
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!trigger) return;
|
||||
@@ -34,6 +37,7 @@ export const WiredActionFurniAreaView: FC<{}> = props =>
|
||||
|
||||
if(activated)
|
||||
{
|
||||
// Restore previously saved area highlight when re-opening dialog
|
||||
if(trigger.intData.length >= 4 && trigger.intData[2] > 0 && trigger.intData[3] > 0)
|
||||
{
|
||||
GetRoomEngine().areaSelectionManager.setHighlight(
|
||||
@@ -69,19 +73,38 @@ export const WiredActionFurniAreaView: FC<{}> = props =>
|
||||
setAreaWidth(0);
|
||||
setAreaHeight(0);
|
||||
}
|
||||
|
||||
setFilterExisting(trigger.intData.length >= 5 && trigger.intData[4] === 1);
|
||||
setInvert(trigger.intData.length >= 6 && trigger.intData[5] === 1);
|
||||
}, [ trigger ]);
|
||||
|
||||
const hasArea = areaWidth > 0 && areaHeight > 0;
|
||||
|
||||
const pickedLimit = trigger?.maximumItemSelectionCount ?? 20;
|
||||
const pickedCount = hasArea
|
||||
? GetRoomEngine().getRoomObjects(GetRoomEngine().activeRoomId, RoomObjectCategory.FLOOR)
|
||||
.filter(obj =>
|
||||
{
|
||||
const loc = obj.location;
|
||||
const inArea = loc.x >= rootX && loc.x < rootX + areaWidth && loc.y >= rootY && loc.y < rootY + areaHeight;
|
||||
return invert ? !inArea : inArea;
|
||||
}).length
|
||||
: 0;
|
||||
|
||||
return (
|
||||
<WiredActionBaseView hasSpecialInput={ true } requiresFurni={ 0 } save={ save } cardStyle={ { width: '385px', height: '365px' } }>
|
||||
<WiredActionBaseView hasSpecialInput={ true } requiresFurni={ 0 } save={ save } hideDelay={ true } cardStyle={ { width: '385px'} }>
|
||||
<div className="flex flex-col gap-2">
|
||||
<Text bold>{ LocalizeText('wiredfurni.params.area_selection') }</Text>
|
||||
<Text small>{ LocalizeText('wiredfurni.params.area_selection.info') }</Text>
|
||||
|
||||
{ hasArea &&
|
||||
<Text small>
|
||||
{ LocalizeText('wiredfurni.params.area_selection.selected', [ 'x', 'y', 'w', 'h' ], [ rootX.toString(), rootY.toString(), areaWidth.toString(), areaHeight.toString() ]) }
|
||||
{ LocalizeText('wiredfurni.params.area_selection:', [ 'x', 'y', 'w', 'h' ], [ rootX.toString(), rootY.toString(), areaWidth.toString(), areaHeight.toString() ]) }
|
||||
</Text> }
|
||||
|
||||
{ hasArea &&
|
||||
<Text small>
|
||||
{ LocalizeText('wiredfurni.pickfurnis.caption', [ 'count', 'limit' ], [ pickedCount.toString(), pickedLimit.toString() ]) }
|
||||
</Text> }
|
||||
|
||||
<div className="flex gap-1">
|
||||
@@ -92,6 +115,28 @@ export const WiredActionFurniAreaView: FC<{}> = props =>
|
||||
{ LocalizeText('wiredfurni.params.area_selection.clear') }
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<hr className="m-0 bg-dark" />
|
||||
|
||||
<Text bold>{ LocalizeText('wiredfurni.params.selector_options_selector') }</Text>
|
||||
|
||||
<label className="flex items-center gap-1">
|
||||
<input
|
||||
type="checkbox"
|
||||
className="form-check-input"
|
||||
checked={ filterExisting }
|
||||
onChange={ e => setFilterExisting(e.target.checked) } />
|
||||
<Text small>{ LocalizeText('wiredfurni.params.selector_option.0') }</Text>
|
||||
</label>
|
||||
|
||||
<label className="flex items-center gap-1">
|
||||
<input
|
||||
type="checkbox"
|
||||
className="form-check-input"
|
||||
checked={ invert }
|
||||
onChange={ e => setInvert(e.target.checked) } />
|
||||
<Text small>{ LocalizeText('wiredfurni.params.selector_option.1') }</Text>
|
||||
</label>
|
||||
</div>
|
||||
</WiredActionBaseView>
|
||||
);
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { GetRoomEngine, RoomObjectCategory } from '@nitrots/nitro-renderer';
|
||||
import { CSSProperties, FC, useCallback, useEffect, useState } from 'react';
|
||||
import { FaMinus, FaPlus, FaTimes } from 'react-icons/fa';
|
||||
import { MdGridOn } from 'react-icons/md';
|
||||
import { LocalizeText, WiredFurniType } from '../../../../api';
|
||||
import { GetRoomSession, LocalizeText, WiredFurniType, WiredSelectionVisualizer } from '../../../../api';
|
||||
import { Button, Text } from '../../../../common';
|
||||
import { useWired } from '../../../../hooks';
|
||||
import { WiredActionBaseView } from '../actions/WiredActionBaseView';
|
||||
@@ -46,10 +47,11 @@ const tileTop = (rx: number, ry: number) =>
|
||||
|
||||
interface GridProps {
|
||||
selectedTiles: Tile[];
|
||||
invert: boolean;
|
||||
onToggle: (x: number, y: number) => void;
|
||||
}
|
||||
|
||||
const NeighborhoodGrid: FC<GridProps> = ({ selectedTiles, onToggle }) =>
|
||||
const NeighborhoodGrid: FC<GridProps> = ({ selectedTiles, invert, onToggle }) =>
|
||||
{
|
||||
const tiles: JSX.Element[] = [];
|
||||
|
||||
@@ -59,19 +61,20 @@ const NeighborhoodGrid: FC<GridProps> = ({ selectedTiles, onToggle }) =>
|
||||
{
|
||||
const isCenter = rx === 0 && ry === 0;
|
||||
const isSelected = tileIncluded(selectedTiles, rx, ry);
|
||||
const isActive = invert ? !isSelected : isSelected;
|
||||
const left = tileLeft(rx, ry);
|
||||
const top_ = tileTop(rx, ry);
|
||||
const zIdx = rx + ry + GRID_RANGE * 2 + 10;
|
||||
|
||||
const bgColor = isCenter
|
||||
? '#ff9500'
|
||||
: isSelected
|
||||
: isActive
|
||||
? '#3399ff'
|
||||
: '#2a3042';
|
||||
|
||||
const borderColor = isCenter
|
||||
? '#cc6600'
|
||||
: isSelected
|
||||
: isActive
|
||||
? '#1166cc'
|
||||
: '#1a2032';
|
||||
|
||||
@@ -127,7 +130,7 @@ export const WiredSelectorFurniNeighborhoodView: FC<{}> = () =>
|
||||
const [ curX, setCurX ] = useState(0);
|
||||
const [ curY, setCurY ] = useState(0);
|
||||
|
||||
const { trigger = null, furniIds = [], setIntParams } = useWired();
|
||||
const { trigger = null, furniIds = [], setIntParams, setFurniIds } = useWired();
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
@@ -157,6 +160,46 @@ export const WiredSelectorFurniNeighborhoodView: FC<{}> = () =>
|
||||
}
|
||||
}, [ trigger ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(sourceType !== SOURCE_FURNI_PICKED || !trigger) return;
|
||||
|
||||
const roomId = GetRoomSession().roomId;
|
||||
const wiredObj = GetRoomEngine().getRoomObject(roomId, trigger.id, RoomObjectCategory.FLOOR);
|
||||
|
||||
if(!wiredObj) return;
|
||||
|
||||
const wiredPos = wiredObj.getLocation();
|
||||
const tileSet = new Set(selectedTiles.map(t => `${ t.x },${ t.y }`));
|
||||
const limit = trigger.maximumItemSelectionCount;
|
||||
|
||||
const allFloorObjects = GetRoomEngine().getRoomObjects(roomId, RoomObjectCategory.FLOOR);
|
||||
const newIds: number[] = [];
|
||||
|
||||
for(const obj of allFloorObjects)
|
||||
{
|
||||
if(newIds.length >= limit) break;
|
||||
if(obj.id < 0 || obj.id === trigger.id) continue;
|
||||
|
||||
const pos = obj.getLocation();
|
||||
const relX = Math.round(pos.x - wiredPos.x);
|
||||
const relY = Math.round(pos.y - wiredPos.y);
|
||||
|
||||
const isInTiles = tileSet.has(`${ relX },${ relY }`);
|
||||
|
||||
if(invert ? !isInTiles : isInTiles) newIds.push(obj.id);
|
||||
}
|
||||
|
||||
setFurniIds(prevValue =>
|
||||
{
|
||||
if(prevValue && prevValue.length) WiredSelectionVisualizer.clearSelectionShaderFromFurni(prevValue);
|
||||
|
||||
WiredSelectionVisualizer.applySelectionShaderToFurni(newIds);
|
||||
|
||||
return newIds;
|
||||
});
|
||||
}, [ sourceType, selectedTiles, invert, trigger, setFurniIds ]);
|
||||
|
||||
const save = useCallback(() =>
|
||||
{
|
||||
const params: number[] = [
|
||||
@@ -235,7 +278,7 @@ export const WiredSelectorFurniNeighborhoodView: FC<{}> = () =>
|
||||
const pickedLimit = trigger?.maximumItemSelectionCount ?? 20;
|
||||
|
||||
return (
|
||||
<WiredActionBaseView hasSpecialInput={ true } requiresFurni={ requiresFurni } save={ save } cardStyle={ { width: '480px', height: '750px' } }>
|
||||
<WiredActionBaseView hasSpecialInput={ true } requiresFurni={ requiresFurni } save={ save } hideDelay={ true } cardStyle={ { width: '400px' } }>
|
||||
<div className="flex flex-col gap-2">
|
||||
|
||||
<Text bold>{ LocalizeText('wiredfurni.params.neighborhood_selection') }</Text>
|
||||
@@ -256,7 +299,7 @@ export const WiredSelectorFurniNeighborhoodView: FC<{}> = () =>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-center">
|
||||
<NeighborhoodGrid selectedTiles={ selectedTiles } onToggle={ toggleTile } />
|
||||
<NeighborhoodGrid selectedTiles={ selectedTiles } invert={ invert } onToggle={ toggleTile } />
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
|
||||
@@ -15,6 +15,8 @@ const useWiredState = () =>
|
||||
const [ allowsFurni, setAllowsFurni ] = useState<number>(WiredFurniType.STUFF_SELECTION_OPTION_NONE);
|
||||
const [ selectByType, setSelectByType ] = useState<boolean>(false);
|
||||
const [ invertSelection, setInvertSelection ] = useState<boolean>(false);
|
||||
const [ neighborhoodTiles, setNeighborhoodTiles ] = useState<{ x: number; y: number }[] | null>(null);
|
||||
const [ neighborhoodInvert, setNeighborhoodInvert ] = useState<boolean>(false);
|
||||
const { showConfirm = null } = useNotification();
|
||||
|
||||
const saveWired = () =>
|
||||
@@ -206,10 +208,12 @@ const useWiredState = () =>
|
||||
setAllowsFurni(WiredFurniType.STUFF_SELECTION_OPTION_NONE);
|
||||
setSelectByType(false);
|
||||
setInvertSelection(false);
|
||||
setNeighborhoodTiles(null);
|
||||
setNeighborhoodInvert(false);
|
||||
};
|
||||
}, [ trigger ]);
|
||||
|
||||
return { trigger, setTrigger, intParams, setIntParams, stringParam, setStringParam, furniIds, setFurniIds, actionDelay, setActionDelay, setAllowsFurni, saveWired, selectObjectForWired, setSelectByType, setInvertSelection };
|
||||
return { trigger, setTrigger, intParams, setIntParams, stringParam, setStringParam, furniIds, setFurniIds, actionDelay, setActionDelay, setAllowsFurni, saveWired, selectObjectForWired, setSelectByType, setInvertSelection, setNeighborhoodTiles, setNeighborhoodInvert };
|
||||
};
|
||||
|
||||
export const useWired = () => useBetween(useWiredState);
|
||||
|
||||
Reference in New Issue
Block a user