mirror of
https://github.com/billsonnn/nitro-react.git
synced 2025-01-31 10:22:36 +01:00
Merge conflicts
This commit is contained in:
commit
06af222057
BIN
src/assets/images/wired/card-action-corners.png
Normal file
BIN
src/assets/images/wired/card-action-corners.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
@ -1,5 +1,6 @@
|
||||
.nitro-wired {
|
||||
width: 300px;
|
||||
padding:7px;
|
||||
|
||||
.icon {
|
||||
width: 16px;
|
||||
@ -35,4 +36,125 @@
|
||||
background-image: url('../../assets/images/wired/icon_wired_rotate_counter_clockwise.png');
|
||||
}
|
||||
}
|
||||
|
||||
.nitro-wired-header {
|
||||
color: #000;
|
||||
margin-bottom:3px;
|
||||
|
||||
.nitro-wired-title, .nitro-wired-close {
|
||||
border:1px solid rgba($black,.8);
|
||||
background-image: linear-gradient(45deg, #00d9cb 25%, #00bdb0 25%, #00bdb0 50%, #00d9cb 50%, #00d9cb 75%, #00bdb0 75%, #00bdb0 100%);
|
||||
background-size: 197.99px 197.99px;
|
||||
animation: wiredSlider 3s linear infinite;
|
||||
text-align: center;
|
||||
box-shadow:inset 0 0 0 2px rgba($white,.6), 0 2px rgba($black,.4);
|
||||
}
|
||||
|
||||
.nitro-wired-title {
|
||||
margin-right:3px;
|
||||
}
|
||||
|
||||
.nitro-wired-close {
|
||||
min-width: 23px;
|
||||
}
|
||||
}
|
||||
|
||||
&.nitro-wired-trigger {
|
||||
background-color: #3b2516 !important;
|
||||
border: 1px solid #000 !important;
|
||||
box-shadow: inset 0px -2px #50321f,
|
||||
inset 0px -3px #86583b,
|
||||
inset 0 0 0 1px #86583b,
|
||||
inset 0 0 0 3px #644029,
|
||||
inset 0 0 0 4px rgba($black,.4) !important;
|
||||
|
||||
.bg-light,.bg-primary {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
.bg-dark {
|
||||
background-color: #000 !important;
|
||||
}
|
||||
}
|
||||
|
||||
&.nitro-wired-action {
|
||||
background-color: #686868 !important;
|
||||
border: 1px solid #000 !important;
|
||||
box-shadow: inset 0px -2px #9d9d9d,
|
||||
inset 0px -3px #c5c5c5,
|
||||
inset 0 0 0 1px #c5c5c5,
|
||||
inset 0 0 0 3px #9d9d9d,
|
||||
inset 0 0 0 4px rgba($black,.4) !important;
|
||||
|
||||
.bg-light,.bg-primary {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
.bg-dark {
|
||||
background-color: #000 !important;
|
||||
}
|
||||
|
||||
&::before,
|
||||
&::after,
|
||||
.content-area::before,
|
||||
.content-area::after {
|
||||
content: '';
|
||||
height: 6px;
|
||||
width: 6px;
|
||||
position: absolute;
|
||||
background-image: url('../../assets/images/wired/card-action-corners.png');
|
||||
}
|
||||
|
||||
&::before {
|
||||
background-position: 0 0;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
&::after {
|
||||
background-position: 6px 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.content-area {
|
||||
&::before {
|
||||
background-position: 0 6px;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
&::after {
|
||||
background-position: 6px 6px;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.nitro-wired-condition {
|
||||
background-color: #cfd2dd !important;
|
||||
border: 1px solid #000 !important;
|
||||
box-shadow: inset 0 0 0 3px #efefef, inset 4px 4px #abaeb9 !important;
|
||||
color: #000;
|
||||
|
||||
.bg-light,.bg-primary {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
.bg-dark {
|
||||
background-color: #000 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@keyframes wiredSlider {
|
||||
0% {
|
||||
background-position: 0 0;
|
||||
}
|
||||
|
||||
100% {
|
||||
background-position: 0 -197.99px;
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import { WiredActionCallAnotherStackView } from '../views/actions/call-another-s
|
||||
import { WiredActionChaseView } from '../views/actions/chase/WiredActionChaseView';
|
||||
import { WiredActionChatView } from '../views/actions/chat/WiredActionChatView';
|
||||
import { WiredActionFleeView } from '../views/actions/flee/WiredActionFleeView';
|
||||
import { WiredActionGiveRewardView } from '../views/actions/give-reward/WiredActionGiveRewardView';
|
||||
import { WiredActionGiveScoreToPredefinedTeamView } from '../views/actions/give-score-to-predefined-team/WiredActionGiveScoreToPredefinedTeamView';
|
||||
import { WiredActionGiveScoreView } from '../views/actions/give-score/WiredActionGiveScoreView';
|
||||
import { WiredActionJoinTeamView } from '../views/actions/join-team/WiredActionJoinTeamView';
|
||||
@ -50,6 +51,8 @@ export function GetWiredActionLayout(code: number): JSX.Element
|
||||
return <WiredActionChatView />;
|
||||
case WiredActionLayout.FLEE:
|
||||
return <WiredActionFleeView />;
|
||||
case WiredActionLayout.GIVE_REWARD:
|
||||
return <WiredActionGiveRewardView />;
|
||||
case WiredActionLayout.GIVE_SCORE:
|
||||
return <WiredActionGiveScoreView />;
|
||||
case WiredActionLayout.GIVE_SCORE_TO_PREDEFINED_TEAM:
|
||||
|
@ -4,6 +4,7 @@ import { WiredConditionActorIsOnFurniView } from '../views/conditions/actor-is-o
|
||||
import { WiredConditionActorIsTeamMemberView } from '../views/conditions/actor-is-team-member/WiredConditionActorIsTeamMemberView';
|
||||
import { WiredConditionActorIsWearingBadgeView } from '../views/conditions/actor-is-wearing-badge/WiredConditionActorIsWearingBadgeView';
|
||||
import { WiredConditionActorIsWearingEffectView } from '../views/conditions/actor-is-wearing-effect/WiredConditionActorIsWearingEffectView';
|
||||
import { WiredConditionDateRangeView } from '../views/conditions/date-range/WiredConditionDateRangeView';
|
||||
import { WiredConditionFurniHasAvatarOnView } from '../views/conditions/furni-has-avatar-on/WiredConditionFurniHasAvatarOnView';
|
||||
import { WiredConditionFurniHasFurniOnView } from '../views/conditions/furni-has-furni-on/WiredConditionFurniHasFurniOnView';
|
||||
import { WiredConditionFurniHasNotFurniOnView } from '../views/conditions/furni-has-not-furni-on/WiredConditionFurniHasNotFurniOnView';
|
||||
@ -35,6 +36,8 @@ export function GetWiredConditionLayout(code: number): JSX.Element
|
||||
case WiredConditionlayout.ACTOR_IS_WEARING_EFFECT:
|
||||
case WiredConditionlayout.NOT_ACTOR_WEARING_EFFECT:
|
||||
return <WiredConditionActorIsWearingEffectView />;
|
||||
case WiredConditionlayout.DATE_RANGE_ACTIVE:
|
||||
return <WiredConditionDateRangeView />;
|
||||
case WiredConditionlayout.FURNIS_HAVE_AVATARS:
|
||||
case WiredConditionlayout.FURNI_NOT_HAVE_HABBO:
|
||||
return <WiredConditionFurniHasAvatarOnView />;
|
||||
|
@ -0,0 +1,173 @@
|
||||
import Slider from 'rc-slider/lib/Slider';
|
||||
import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { LocalizeText } from '../../../../../utils/LocalizeText';
|
||||
import { useWiredContext } from '../../../context/WiredContext';
|
||||
import { WiredFurniType } from '../../../WiredView.types';
|
||||
import { WiredActionBaseView } from '../base/WiredActionBaseView';
|
||||
|
||||
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<{ isBadge: boolean, itemCode: string, probability: number }[]>([]);
|
||||
|
||||
const { trigger = null, setIntParams = null, setStringParam = null } = useWiredContext();
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
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);
|
||||
|
||||
const readRewards: { isBadge: boolean, itemCode: string, probability: number }[] = [];
|
||||
|
||||
if(trigger.stringData.length > 0 && trigger.stringData.includes(';'))
|
||||
{
|
||||
const splittedRewards = trigger.stringData.split(';');
|
||||
|
||||
for(const rawReward of splittedRewards)
|
||||
{
|
||||
const reward = rawReward.split(',');
|
||||
|
||||
if(reward.length !== 3) continue;
|
||||
|
||||
readRewards.push({ isBadge: reward[0] === '0', itemCode: reward[1], probability: Number(reward[2]) });
|
||||
}
|
||||
}
|
||||
|
||||
if(readRewards.length === 0)
|
||||
{
|
||||
readRewards.push({ isBadge: false, itemCode: '', probability: null });
|
||||
}
|
||||
|
||||
setRewards(readRewards);
|
||||
}, [ trigger ]);
|
||||
|
||||
const addReward = useCallback(() =>
|
||||
{
|
||||
setRewards(rewards => [...rewards, { isBadge: false, itemCode: '', probability: null }]);
|
||||
}, [ setRewards ]);
|
||||
|
||||
const removeReward = useCallback((index: number) =>
|
||||
{
|
||||
const rewardsClone = Array.from(rewards);
|
||||
rewardsClone.splice(index, 1);
|
||||
|
||||
setRewards(rewardsClone);
|
||||
}, [ rewards, setRewards ]);
|
||||
|
||||
const updateReward = useCallback((index: number, isBadge: boolean, itemCode: string, probability: number) =>
|
||||
{
|
||||
const rewardsClone = Array.from(rewards);
|
||||
const reward = rewardsClone[index];
|
||||
|
||||
if(!reward) return;
|
||||
|
||||
reward.isBadge = isBadge;
|
||||
reward.itemCode = itemCode;
|
||||
reward.probability = probability;
|
||||
|
||||
setRewards(rewardsClone);
|
||||
}, [ rewards, setRewards ]);
|
||||
|
||||
const save = useCallback(() =>
|
||||
{
|
||||
let stringRewards = [];
|
||||
|
||||
for(const reward of rewards)
|
||||
{
|
||||
if(!reward.itemCode) continue;
|
||||
|
||||
const rewardsString = [reward.isBadge ? '0' : '1', reward.itemCode, reward.probability.toString()];
|
||||
stringRewards.push(rewardsString.join(','));
|
||||
}
|
||||
|
||||
if(stringRewards.length > 0)
|
||||
{
|
||||
setStringParam(stringRewards.join(';'));
|
||||
setIntParams([rewardTime, uniqueRewards ? 1 : 0, rewardsLimit, limitationInterval]);
|
||||
}
|
||||
}, [ rewardTime, uniqueRewards, rewardsLimit, limitationInterval, rewards, setIntParams, setStringParam ]);
|
||||
|
||||
return (
|
||||
<WiredActionBaseView requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE } save={ save }>
|
||||
<div className="form-check">
|
||||
<input className="form-check-input" type="checkbox" id="limitEnabled" onChange={(e) => setLimitEnabled(e.target.checked)} />
|
||||
<label className="form-check-label" htmlFor="uniqueRewards">
|
||||
{ LocalizeText('wiredfurni.params.prizelimit', ['amount'], [limitEnabled ? rewardsLimit.toString() : '']) }
|
||||
</label>
|
||||
</div>
|
||||
{ !limitEnabled && <div className="bg-muted rounded small text-black p-1 text-center">
|
||||
Reward limit not set. Make sure rewards are badges or non-tradeable items.
|
||||
</div> }
|
||||
{ limitEnabled && <Slider
|
||||
defaultValue={ rewardsLimit }
|
||||
dots={ true }
|
||||
min={ 1 }
|
||||
max={ 1000 }
|
||||
step={ 1 }
|
||||
onChange={ event => setRewardsLimit(event) }
|
||||
/> }
|
||||
<hr className="my-1 mb-2 bg-dark" />
|
||||
<div className="fw-bold">How ofter can a user be rewarded?</div>
|
||||
<div className="d-flex">
|
||||
<select className="form-select form-select-sm w-100" value={ rewardTime } onChange={ (e) => setRewardTime(Number(e.target.value)) }>
|
||||
<option value="0">Once</option>
|
||||
<option value="3">Once every { limitationInterval } minutes</option>
|
||||
<option value="2">Once every { limitationInterval } hours</option>
|
||||
<option value="1">Once every { limitationInterval } days</option>
|
||||
</select>
|
||||
{ rewardTime > 0 && <input type="number" className="ms-2 form-control form-control-sm" value={ limitationInterval } onChange={ event => setLimitationInterval(Number(event.target.value)) } /> }
|
||||
</div>
|
||||
<hr className="my-1 mb-2 bg-dark" />
|
||||
<div className="form-check">
|
||||
<input className="form-check-input" type="checkbox" id="uniqueRewards" checked={ uniqueRewards } onChange={(e) => setUniqueRewards(e.target.checked)} />
|
||||
<label className="form-check-label" htmlFor="uniqueRewards">
|
||||
Unique rewards
|
||||
</label>
|
||||
</div>
|
||||
<div className="bg-muted rounded small text-black p-1 text-center">If checked each reward will be given once to each user. This will disable the probabilities option.</div>
|
||||
<hr className="my-1 mb-2 bg-dark" />
|
||||
<div className="d-flex justify-content-between align-items-center">
|
||||
<div className="fw-bold">Rewards</div>
|
||||
<div className="btn btn-sm btn-success" onClick={ addReward }><i className="fas fa-plus" /></div>
|
||||
</div>
|
||||
<table className="table-sm">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>Badge?</td>
|
||||
<td>Item Code</td>
|
||||
<td>Probability</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{ rewards && rewards.map((reward, index) =>
|
||||
{
|
||||
return (
|
||||
<tr key={ index }>
|
||||
<td className="d-flex align-items-center justify-content-center">
|
||||
<input className="form-check-input" type="checkbox" checked={ reward.isBadge } onChange={(e) => updateReward(index, e.target.checked, reward.itemCode, reward.probability)} />
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" className="form-control form-control-sm" value={ reward.itemCode } onChange={ e => updateReward(index, reward.isBadge, e.target.value, reward.probability) } />
|
||||
</td>
|
||||
<td>
|
||||
<input type="number" className="form-control form-control-sm" value={ reward.probability } onChange={ e => updateReward(index, reward.isBadge, reward.itemCode, Number(e.target.value)) } />
|
||||
</td>
|
||||
<td>
|
||||
{ index > 0 && <button className="btn btn-sm btn-danger" onClick={() => removeReward(index) }><i className="fas fa-trash" /></button> }
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
}) }
|
||||
</tbody>
|
||||
</table>
|
||||
</WiredActionBaseView>
|
||||
);
|
||||
}
|
@ -54,7 +54,7 @@ export const WiredActionMoveAndRotateFurniView: FC<{}> = props =>
|
||||
<WiredActionBaseView requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_BY_ID_BY_TYPE_OR_FROM_CONTEXT } save={ save }>
|
||||
<div className="form-group mb-2">
|
||||
<label className="fw-bold">{ LocalizeText('wiredfurni.params.startdir') }</label>
|
||||
<div className="row row-cold-4">
|
||||
<div className="row row-col-4">
|
||||
{ directionOptions.map(option =>
|
||||
{
|
||||
return (
|
||||
|
@ -2,7 +2,7 @@ import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { GetSessionDataManager } from '../../../../api';
|
||||
import { WiredEvent } from '../../../../events';
|
||||
import { dispatchUiEvent } from '../../../../hooks/events';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout';
|
||||
import { NitroCardContentView, NitroCardView } from '../../../../layout';
|
||||
import { LocalizeText } from '../../../../utils/LocalizeText';
|
||||
import { useWiredContext } from '../../context/WiredContext';
|
||||
import { WiredFurniType } from '../../WiredView.types';
|
||||
@ -52,9 +52,12 @@ export const WiredBaseView: FC<WiredBaseViewProps> = props =>
|
||||
}, [ setTrigger ]);
|
||||
|
||||
return (
|
||||
<NitroCardView className="nitro-wired" simple={ true }>
|
||||
<NitroCardHeaderView headerText={ LocalizeText('wiredfurni.title') } onCloseClick={ close } />
|
||||
<NitroCardContentView className="text-black">
|
||||
<NitroCardView className={`nitro-wired nitro-wired-${wiredType} ` + (wiredType == 'trigger' ? 'rounded-0' : 'rounded-2')}>
|
||||
<div className="nitro-wired-header d-flex">
|
||||
<div className="nitro-wired-title rounded-start w-100 drag-handler">{LocalizeText('wiredfurni.title')}</div>
|
||||
<div className="nitro-wired-close rounded-end flex-shrink-0" onClick={ close }><i className="fas fa-times" /></div>
|
||||
</div>
|
||||
<NitroCardContentView>
|
||||
<div className="d-flex align-items-center">
|
||||
<i className={ `me-2 icon icon-wired-${ wiredType }` } />
|
||||
<div className="fw-bold">{ wiredName }</div>
|
||||
@ -73,8 +76,8 @@ export const WiredBaseView: FC<WiredBaseViewProps> = props =>
|
||||
<div>{ LocalizeText('wiredfurni.pickfurnis.desc') }</div>
|
||||
</> }
|
||||
<div className="d-flex mt-3">
|
||||
<button className="btn btn-success btn-sm me-2 w-100" onClick={ onSave }>{ LocalizeText('wiredfurni.ready') }</button>
|
||||
<button className="btn btn-secondary btn-sm w-100" onClick={ close }>{ LocalizeText('cancel') }</button>
|
||||
<button className="btn btn-sm btn-success me-2 w-100" onClick={ onSave }>{ LocalizeText('wiredfurni.ready') }</button>
|
||||
<button className="btn btn-sm btn-secondary w-100" onClick={ close }>{ LocalizeText('cancel') }</button>
|
||||
</div>
|
||||
</NitroCardContentView>
|
||||
</NitroCardView>
|
||||
|
@ -0,0 +1,62 @@
|
||||
import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { LocalizeText } from '../../../../../utils/LocalizeText';
|
||||
import { useWiredContext } from '../../../context/WiredContext';
|
||||
import { WiredFurniType } from '../../../WiredView.types';
|
||||
import { WiredConditionBaseView } from '../base/WiredConditionBaseView';
|
||||
|
||||
export const WiredConditionDateRangeView: FC<{}> = props =>
|
||||
{
|
||||
const [ startDate, setStartDate ] = useState('');
|
||||
const [ endDate, setEndDate ] = useState('');
|
||||
const { trigger = null, setIntParams = null } = useWiredContext();
|
||||
|
||||
const dateToString = useCallback((date: Date) =>
|
||||
{
|
||||
return `${date.getFullYear()}/${('0' + (date.getMonth() + 1)).slice(-2)}/${('0' + date.getDate()).slice(-2)} ` + `${('0' + date.getHours()).slice(-2)}:${('0' + date.getMinutes()).slice(-2)}`;
|
||||
}, []);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(trigger.intData.length >= 2)
|
||||
{
|
||||
let startDate = new Date();
|
||||
let endDate = new Date();
|
||||
|
||||
if(trigger.intData[0] > 0)
|
||||
startDate = new Date((trigger.intData[0] * 1000));
|
||||
|
||||
if(trigger.intData[1] > 0)
|
||||
endDate = new Date((trigger.intData[1] * 1000));
|
||||
|
||||
setStartDate(dateToString(startDate));
|
||||
setEndDate(dateToString(endDate));
|
||||
}
|
||||
}, [ trigger ]);
|
||||
|
||||
const save = useCallback(() =>
|
||||
{
|
||||
let startDateMili = 0;
|
||||
let endDateMili = 0;
|
||||
|
||||
const startDateInstance = new Date(startDate);
|
||||
const endDateInstance = new Date(endDate);
|
||||
|
||||
if(startDateInstance && endDateInstance)
|
||||
{
|
||||
startDateMili = startDateInstance.getTime() / 1000;
|
||||
endDateMili = endDateInstance.getTime() / 1000;
|
||||
}
|
||||
|
||||
setIntParams([startDateMili, endDateMili]);
|
||||
}, [ startDate, endDate, setIntParams ]);
|
||||
|
||||
return (
|
||||
<WiredConditionBaseView requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE } save={ save }>
|
||||
<div className="fw-bold">{ LocalizeText('wiredfurni.params.startdate') }</div>
|
||||
<input type="text" className="form-control form-control-sm" value={ startDate } onChange={ (e) => setStartDate(e.target.value) } />
|
||||
<hr className="my-1 mb-2 bg-dark" />
|
||||
<div className="fw-bold">{ LocalizeText('wiredfurni.params.enddate') }</div>
|
||||
<input type="text" className="form-control form-control-sm" value={ endDate } onChange={ (e) => setEndDate(e.target.value) } />
|
||||
</WiredConditionBaseView>
|
||||
);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user