mirror of
https://git.rezel.net/LudoTech/traque.git
synced 2026-02-09 02:10:18 +01:00
Timer zone
This commit is contained in:
@@ -38,6 +38,8 @@ export default {
|
|||||||
updateIntervalId: null,
|
updateIntervalId: null,
|
||||||
nextZoneTimeoutId: null,
|
nextZoneTimeoutId: null,
|
||||||
|
|
||||||
|
nextZoneDate: null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test if a given configuration object is valid, i.e if all needed values are well defined
|
* Test if a given configuration object is valid, i.e if all needed values are well defined
|
||||||
* @param {Object} settings Settings object describing a config of a zone manager
|
* @param {Object} settings Settings object describing a config of a zone manager
|
||||||
@@ -143,6 +145,7 @@ export default {
|
|||||||
* Wait for the appropriate duration before starting a new zone reduction if needed
|
* Wait for the appropriate duration before starting a new zone reduction if needed
|
||||||
*/
|
*/
|
||||||
setNextZone() {
|
setNextZone() {
|
||||||
|
this.nextZoneDate = Date.now() + this.zoneSettings.reductionInterval * 60 * 1000;
|
||||||
//At this point, nextZone == currentZone, we need to update the next zone, the raidus decrement, and start a timer before the next shrink
|
//At this point, nextZone == currentZone, we need to update the next zone, the raidus decrement, and start a timer before the next shrink
|
||||||
//last zone
|
//last zone
|
||||||
if (this.currentZoneCount == this.zoneSettings.reductionCount) {
|
if (this.currentZoneCount == this.zoneSettings.reductionCount) {
|
||||||
@@ -168,7 +171,8 @@ export default {
|
|||||||
this.onZoneUpdate(JSON.parse(JSON.stringify(this.currentStartZone)))
|
this.onZoneUpdate(JSON.parse(JSON.stringify(this.currentStartZone)))
|
||||||
this.onNextZoneUpdate({
|
this.onNextZoneUpdate({
|
||||||
begin: JSON.parse(JSON.stringify(this.currentStartZone)),
|
begin: JSON.parse(JSON.stringify(this.currentStartZone)),
|
||||||
end: JSON.parse(JSON.stringify(this.nextZone))
|
end: JSON.parse(JSON.stringify(this.nextZone)),
|
||||||
|
endDate: JSON.parse(JSON.stringify(this.nextZoneDate)),
|
||||||
})
|
})
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
@@ -179,6 +183,8 @@ export default {
|
|||||||
* If the reduction is over this function will call setNextZone
|
* If the reduction is over this function will call setNextZone
|
||||||
*/
|
*/
|
||||||
startShrinking() {
|
startShrinking() {
|
||||||
|
this.nextZoneDate = Date.now() + this.zoneSettings.reductionDuration * 60 * 1000;
|
||||||
|
this.onZoneUpdateStart(JSON.parse(JSON.stringify(this.nextZoneDate)));
|
||||||
const startTime = new Date();
|
const startTime = new Date();
|
||||||
this.updateIntervalId = setInterval(() => {
|
this.updateIntervalId = setInterval(() => {
|
||||||
const completed = ((new Date() - startTime) / (1000 * 60)) / this.zoneSettings.reductionDuration;
|
const completed = ((new Date() - startTime) / (1000 * 60)) / this.zoneSettings.reductionDuration;
|
||||||
@@ -202,6 +208,12 @@ export default {
|
|||||||
secureAdminBroadcast("new_zone", newZone)
|
secureAdminBroadcast("new_zone", newZone)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
//a call to onZoneUpdateStart will be made when the zone reduction starts
|
||||||
|
onZoneUpdateStart(date) {
|
||||||
|
playersBroadcast("zone_start", date)
|
||||||
|
secureAdminBroadcast("zone_start", date)
|
||||||
|
},
|
||||||
|
|
||||||
//a call to onZoneUpdate will be made every updateIntervalSeconds when the zone is changing
|
//a call to onZoneUpdate will be made every updateIntervalSeconds when the zone is changing
|
||||||
onZoneUpdate(zone) {
|
onZoneUpdate(zone) {
|
||||||
playersBroadcast("zone", zone)
|
playersBroadcast("zone", zone)
|
||||||
|
|||||||
@@ -105,30 +105,55 @@ export function ZonePicker({ minZone, setMinZone, maxZone, setMaxZone, editMode,
|
|||||||
|
|
||||||
export function LiveMap() {
|
export function LiveMap() {
|
||||||
const location = useLocation(Infinity);
|
const location = useLocation(Infinity);
|
||||||
const { zone, zoneExtremities, teams, getTeamName } = useAdmin();
|
const [timeLeftNextZone, setTimeLeftNextZone] = useState(null);
|
||||||
|
const { zone, zoneExtremities, teams, getTeamName, nextZoneDate, isShrinking } = useAdmin();
|
||||||
|
|
||||||
|
// Remaining time before sending position
|
||||||
|
useEffect(() => {
|
||||||
|
const updateTime = () => {
|
||||||
|
setTimeLeftNextZone(Math.max(0, Math.floor((nextZoneDate - Date.now()) / 1000)));
|
||||||
|
};
|
||||||
|
|
||||||
|
updateTime();
|
||||||
|
const interval = setInterval(updateTime, 1000);
|
||||||
|
|
||||||
|
return () => clearInterval(interval);
|
||||||
|
}, [nextZoneDate]);
|
||||||
|
|
||||||
|
function formatTime(time) {
|
||||||
|
// time is in seconds
|
||||||
|
if (time < 0) return "00:00";
|
||||||
|
const minutes = Math.floor(time / 60);
|
||||||
|
const seconds = Math.floor(time % 60);
|
||||||
|
return String(minutes).padStart(2,"0") + ":" + String(seconds).padStart(2,"0");
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MapContainer className='min-h-full w-full ' center={location} zoom={DEFAULT_ZOOM} scrollWheelZoom={true}>
|
<div className='min-h-full w-full'>
|
||||||
<TileLayer
|
<p>{`${isShrinking ? "Fin" : "Début"} du rétrécissement de la zone dans : ${formatTime(timeLeftNextZone)}`}</p>
|
||||||
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
<MapContainer className='min-h-full w-full' center={location} zoom={DEFAULT_ZOOM} scrollWheelZoom={true}>
|
||||||
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
<TileLayer
|
||||||
/>
|
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||||
<MapPan center={location} zoom={DEFAULT_ZOOM} />
|
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
||||||
{zone && <Circle center={zone.center} radius={zone.radius} color="blue" />}
|
/>
|
||||||
{zoneExtremities && <Circle center={zoneExtremities.begin.center} radius={zoneExtremities.begin.radius} color='black' fill={false} />}
|
<MapPan center={location} zoom={DEFAULT_ZOOM} />
|
||||||
{zoneExtremities && <Circle center={zoneExtremities.end.center} radius={zoneExtremities.end.radius} color='red' fill={false} />}
|
{zone && <Circle center={zone.center} radius={zone.radius} color="blue" />}
|
||||||
{teams.map((team) => team.currentLocation && !team.captured && <Marker key={team.id} position={team.currentLocation} icon={new L.Icon({
|
{zoneExtremities && <Circle center={zoneExtremities.begin.center} radius={zoneExtremities.begin.radius} color='black' fill={false} />}
|
||||||
iconUrl: '/icons/location.png',
|
{zoneExtremities && <Circle center={zoneExtremities.end.center} radius={zoneExtremities.end.radius} color='red' fill={false} />}
|
||||||
iconSize: [41, 41],
|
{teams.map((team) => team.currentLocation && !team.captured && <Marker key={team.id} position={team.currentLocation} icon={new L.Icon({
|
||||||
iconAnchor: [12, 41],
|
iconUrl: '/icons/location.png',
|
||||||
popupAnchor: [1, -34],
|
iconSize: [41, 41],
|
||||||
shadowSize: [41, 41]
|
iconAnchor: [12, 41],
|
||||||
})}>
|
popupAnchor: [1, -34],
|
||||||
<Popup>
|
shadowSize: [41, 41]
|
||||||
<strong className="text-lg">{team.name}</strong>
|
})}>
|
||||||
<p className="text-md">Chasing : {getTeamName(team.chasing)}</p>
|
<Popup>
|
||||||
<p className="text-md">Chased by : {getTeamName(team.chased)}</p>
|
<strong className="text-lg">{team.name}</strong>
|
||||||
</Popup>
|
<p className="text-md">Chasing : {getTeamName(team.chasing)}</p>
|
||||||
</Marker>)}
|
<p className="text-md">Chased by : {getTeamName(team.chased)}</p>
|
||||||
</MapContainer>
|
</Popup>
|
||||||
|
</Marker>)}
|
||||||
|
</MapContainer>
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -14,6 +14,8 @@ function AdminProvider({ children }) {
|
|||||||
const [gameSettings, setGameSettings] = useState(null);
|
const [gameSettings, setGameSettings] = useState(null);
|
||||||
const [zone, setZone] = useState(null);
|
const [zone, setZone] = useState(null);
|
||||||
const [zoneExtremities, setZoneExtremities] = useState(null);
|
const [zoneExtremities, setZoneExtremities] = useState(null);
|
||||||
|
const [nextZoneDate, setNextZoneDate] = useState(null);
|
||||||
|
const [isShrinking, setIsShrinking] = useState(false);
|
||||||
const { adminSocket } = useSocket();
|
const { adminSocket } = useSocket();
|
||||||
const { loggedIn } = useAdminConnexion();
|
const { loggedIn } = useAdminConnexion();
|
||||||
const [gameState, setGameState] = useState(GameState.SETUP);
|
const [gameState, setGameState] = useState(GameState.SETUP);
|
||||||
@@ -24,15 +26,27 @@ function AdminProvider({ children }) {
|
|||||||
adminSocket.emit("get_teams");
|
adminSocket.emit("get_teams");
|
||||||
}, [loggedIn]);
|
}, [loggedIn]);
|
||||||
|
|
||||||
|
function waiting(data) {
|
||||||
|
setIsShrinking(false);
|
||||||
|
setZoneExtremities({begin: data.begin, end: data.end});
|
||||||
|
setNextZoneDate(data.endDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
function shrinking(data) {
|
||||||
|
setIsShrinking(true);
|
||||||
|
setNextZoneDate(data);
|
||||||
|
}
|
||||||
|
|
||||||
//Bind listeners to update the team list and the game status on socket message
|
//Bind listeners to update the team list and the game status on socket message
|
||||||
useSocketListener(adminSocket, "teams", setTeams);
|
useSocketListener(adminSocket, "teams", setTeams);
|
||||||
useSocketListener(adminSocket, "zone_settings", setZoneSettings);
|
useSocketListener(adminSocket, "zone_settings", setZoneSettings);
|
||||||
useSocketListener(adminSocket, "game_settings", setGameSettings);
|
useSocketListener(adminSocket, "game_settings", setGameSettings);
|
||||||
useSocketListener(adminSocket, "penalty_settings", setPenaltySettings);
|
useSocketListener(adminSocket, "penalty_settings", setPenaltySettings);
|
||||||
useSocketListener(adminSocket, "zone", setZone);
|
useSocketListener(adminSocket, "zone", setZone);
|
||||||
useSocketListener(adminSocket, "new_zone", setZoneExtremities);
|
useSocketListener(adminSocket, "zone_start", shrinking);
|
||||||
|
useSocketListener(adminSocket, "new_zone", waiting);
|
||||||
|
|
||||||
const value = useMemo(() => ({ zone, zoneExtremities, teams, zoneSettings, penaltySettings, gameSettings, gameState }), [zoneSettings, teams, gameState, zone, zoneExtremities, penaltySettings, gameSettings]);
|
const value = useMemo(() => ({ zone, zoneExtremities, teams, zoneSettings, penaltySettings, gameSettings, gameState, nextZoneDate, isShrinking }), [zoneSettings, teams, gameState, zone, zoneExtremities, penaltySettings, gameSettings, nextZoneDate, isShrinking]);
|
||||||
return (
|
return (
|
||||||
<adminContext.Provider value={value}>
|
<adminContext.Provider value={value}>
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
Reference in New Issue
Block a user