import { FC, useEffect, useState } from 'react'; import { FaPlus, FaTrash } from 'react-icons/fa'; import { LocalizeText, WiredFurniType } from '../../../../api'; import { Button, Slider, Text } from '../../../../common'; import { useWired } from '../../../../hooks'; import { NitroInput } from '../../../../layout'; import { WiredActionBaseView } from './WiredActionBaseView'; import { WiredSourcesSelector } from '../WiredSourcesSelector'; type RewardType = 'badge' | 'credits' | 'pixels' | 'diamonds' | 'points' | 'furni' | 'respect'; interface RewardEntry { rewardType: RewardType; rewardValue: string; probability: number; pointsType: number; } const DEFAULT_PROBABILITY = 100; const DEFAULT_POINTS_TYPE = 5; const REWARD_TYPES: { value: RewardType, label: string }[] = [ { value: 'badge', label: 'Badge' }, { value: 'credits', label: 'Credits' }, { value: 'pixels', label: 'Pixels / Duckets' }, { value: 'diamonds', label: 'Diamonds' }, { value: 'points', label: 'Extra Currency' }, { value: 'furni', label: 'Furni' }, { value: 'respect', label: 'Respect' } ]; const SELECTABLE_REWARD_TYPES = REWARD_TYPES.filter(entry => (entry.value !== 'respect')); const createReward = (): RewardEntry => ({ rewardType: 'furni', rewardValue: '', probability: DEFAULT_PROBABILITY, pointsType: DEFAULT_POINTS_TYPE }); const getRewardValuePlaceholder = (rewardType: RewardType) => { switch(rewardType) { case 'badge': return 'Badge code'; case 'credits': return 'Credits amount'; case 'pixels': return 'Pixels amount'; case 'diamonds': return 'Diamonds amount'; case 'points': return 'Amount'; case 'furni': return 'Furni base item id'; case 'respect': return 'Respect amount'; } }; const getExtraFieldLabel = (rewardType: RewardType) => { switch(rewardType) { case 'points': return 'Currency Type'; case 'badge': return 'Code'; default: return 'Info'; } }; const getExtraFieldPlaceholder = (rewardType: RewardType) => { switch(rewardType) { case 'points': return 'Type id (e.g. 105)'; case 'badge': return 'Badge'; default: return ''; } }; const parseRewardEntry = (rawType: string, rawCode: string, rawProbability: string): RewardEntry => { const probability = Number(rawProbability); const parsedProbability = Number.isFinite(probability) ? probability : DEFAULT_PROBABILITY; if(rawType === '0') { return { rewardType: 'badge', rewardValue: rawCode, probability: parsedProbability, pointsType: DEFAULT_POINTS_TYPE }; } const separatorIndex = rawCode.indexOf('#'); if(separatorIndex === -1) { return { rewardType: 'furni', rewardValue: rawCode, probability: parsedProbability, pointsType: DEFAULT_POINTS_TYPE }; } const rewardType = rawCode.slice(0, separatorIndex); const rewardValue = rawCode.slice(separatorIndex + 1); if(rewardType.startsWith('points')) { const pointsType = Number(rewardType.slice('points'.length)); return { rewardType: 'points', rewardValue, probability: parsedProbability, pointsType: Number.isFinite(pointsType) ? pointsType : DEFAULT_POINTS_TYPE }; } if(REWARD_TYPES.some(entry => (entry.value === rewardType))) { return { rewardType: rewardType as RewardType, rewardValue, probability: parsedProbability, pointsType: DEFAULT_POINTS_TYPE }; } if(rewardType === 'cata') { return { rewardType: 'furni', rewardValue, probability: parsedProbability, pointsType: DEFAULT_POINTS_TYPE }; } return { rewardType: 'furni', rewardValue: rawCode, probability: parsedProbability, pointsType: DEFAULT_POINTS_TYPE }; }; export const WiredActionGiveRewardView: FC<{}> = props => { const [ limitEnabled, setLimitEnabled ] = useState(false); const [ rewardTime, setRewardTime ] = useState(1); const [ uniqueRewards, setUniqueRewards ] = useState(false); const [ rewardsLimit, setRewardsLimit ] = useState(1); const [ limitationInterval, setLimitationInterval ] = useState(1); const [ rewards, setRewards ] = useState([]); const { trigger = null, setIntParams = null, setStringParam = null } = useWired(); const [ userSource, setUserSource ] = useState(() => { if(trigger?.intData?.length > 4) return trigger.intData[4]; return 0; }); const addReward = () => setRewards(rewards => [ ...rewards, createReward() ]); const hasCustomCurrencyReward = rewards.some(reward => (reward.rewardType === 'points')); const removeReward = (index: number) => { setRewards(prevValue => { const newValues = Array.from(prevValue); newValues.splice(index, 1); return newValues; }); }; const updateReward = (index: number, updater: (reward: RewardEntry) => RewardEntry) => { setRewards(prevValue => prevValue.map((reward, rewardIndex) => ((rewardIndex === index) ? updater(reward) : reward))); }; const save = () => { let stringRewards = []; for(const reward of rewards) { const rewardValue = reward.rewardValue.trim(); if(!rewardValue) continue; const probability = Math.max(0, Number.isFinite(reward.probability) ? reward.probability : DEFAULT_PROBABILITY); const rewardCode = (() => { if(reward.rewardType === 'badge') return rewardValue; if(reward.rewardType === 'points') return `points${ Math.max(0, reward.pointsType) }#${ rewardValue }`; return `${ reward.rewardType }#${ rewardValue }`; })(); const rewardsString = [ reward.rewardType === 'badge' ? '0' : '1', rewardCode, (uniqueRewards ? DEFAULT_PROBABILITY : probability).toString() ]; stringRewards.push(rewardsString.join(',')); } if(stringRewards.length > 0) { setStringParam(stringRewards.join(';')); setIntParams([ rewardTime, uniqueRewards ? 1 : 0, rewardsLimit, limitationInterval, userSource ]); } }; useEffect(() => { const readRewards: RewardEntry[] = []; if(trigger.stringData.length > 0) { const splittedRewards = trigger.stringData.split(';'); for(const rawReward of splittedRewards) { const reward = rawReward.split(','); if(reward.length !== 3) continue; readRewards.push(parseRewardEntry(reward[0], reward[1], reward[2])); } } if(readRewards.length === 0) readRewards.push(createReward()); setRewardTime((trigger.intData.length > 0) ? trigger.intData[0] : 0); setUniqueRewards((trigger.intData.length > 1) ? (trigger.intData[1] === 1) : false); setRewardsLimit((trigger.intData.length > 2) ? trigger.intData[2] : 0); setLimitationInterval((trigger.intData.length > 3) ? trigger.intData[3] : 0); setLimitEnabled((trigger.intData.length > 3) ? trigger.intData[3] > 0 : false); setUserSource((trigger.intData.length > 4) ? trigger.intData[4] : 0); setRewards(readRewards); }, [ trigger ]); return ( }>
setLimitEnabled(event.target.checked) } /> { LocalizeText('wiredfurni.params.prizelimit', [ 'amount' ], [ limitEnabled ? rewardsLimit.toString() : '' ]) }
{ !limitEnabled && Reward limit not set. Make sure rewards are badges or non-tradeable items. } { limitEnabled && setRewardsLimit(event) } /> }
How often can a user be rewarded?
{ (rewardTime > 0) && setLimitationInterval(Number(event.target.value)) } /> }

setUniqueRewards(e.target.checked) } /> Unique rewards
If checked each reward will be given once to each user. This will disable the probabilities option.
Rewards
Type Amount / Value { uniqueRewards ? 'Mode' : 'Chance %' } { hasCustomCurrencyReward ? 'Currency Type' : 'Extra / Info' } Action
{ rewards && rewards.map((reward, index) => { const rewardTypeOptions = (reward.rewardType === 'respect') ? REWARD_TYPES : SELECTABLE_REWARD_TYPES; return (
updateReward(index, prevValue => ({ ...prevValue, rewardValue: event.target.value })) } /> { uniqueRewards ?
Unique
: updateReward(index, prevValue => ({ ...prevValue, probability: Number(event.target.value) })) } /> } { (reward.rewardType === 'points') ? updateReward(index, prevValue => ({ ...prevValue, pointsType: Number(event.target.value) })) } /> :
{ getExtraFieldLabel(reward.rewardType) }
}
{ (index > 0) && }
); }) }
Extra Currency uses Amount as the quantity and Currency Type as the purse type id. Example: amount 200 + type 105.
); };