Skip to content

Commit 41d2250

Browse files
committed
Feat: Allow changing max robots in UI
1 parent 7bf5508 commit 41d2250

File tree

13 files changed

+248
-159
lines changed

13 files changed

+248
-159
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<script setup lang="ts">
2+
import {computed, inject} from "vue";
3+
import NumberInput from "@/components/common/NumberInput.vue";
4+
import {useMatchStateStore} from "@/store/matchState";
5+
import type {ControlApi} from "@/providers/controlApi";
6+
7+
const store = useMatchStateStore()
8+
const control = inject<ControlApi>('control-api')
9+
10+
const model = computed(() => {
11+
return store.matchState.maxBotsPerTeam
12+
})
13+
14+
const updateValue = (value: number | undefined) => {
15+
if (value !== undefined) {
16+
control?.UpdateMatchConfig({
17+
maxRobotsPerTeam: value,
18+
})
19+
}
20+
}
21+
22+
</script>
23+
24+
<template>
25+
<NumberInput
26+
:modelValue="model"
27+
label="Max robots"
28+
@update:model-value="updateValue"
29+
/>
30+
</template>

frontend/src/helpers/ChangeDetails.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,8 @@ function configChangeTitle(config: Change_UpdateConfig): string {
158158
return `First kick-off team: ${config.firstKickoffTeam}`
159159
} else if (config.division !== undefined && config.division !== 'DIV_UNKNOWN') {
160160
return `Division: ${config.division}`
161+
} else if (config.maxRobotsPerTeam !== undefined) {
162+
return `Max Robots: ${config.maxRobotsPerTeam}`
161163
} else if (config.matchType !== undefined) {
162164
return `Match type: ${config.matchType}`
163165
}

frontend/src/proto/ssl_gc_change.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ export interface Change_UpdateConfig {
126126
firstKickoffTeam?: Team;
127127
/** The match type */
128128
matchType?: MatchType;
129+
/** The number of robots per team */
130+
maxRobotsPerTeam?: number;
129131
}
130132

131133
/** Update the current state of a team (all fields that should be updated are set) */
@@ -485,6 +487,7 @@ export const Change_UpdateConfig = {
485487
division: isSet(object.division) ? divisionFromJSON(object.division) : Division.DIV_UNKNOWN,
486488
firstKickoffTeam: isSet(object.firstKickoffTeam) ? teamFromJSON(object.firstKickoffTeam) : Team.UNKNOWN,
487489
matchType: isSet(object.matchType) ? matchTypeFromJSON(object.matchType) : MatchType.UNKNOWN_MATCH,
490+
maxRobotsPerTeam: isSet(object.maxRobotsPerTeam) ? Number(object.maxRobotsPerTeam) : undefined,
488491
};
489492
},
490493

@@ -493,6 +496,7 @@ export const Change_UpdateConfig = {
493496
message.division !== undefined && (obj.division = divisionToJSON(message.division));
494497
message.firstKickoffTeam !== undefined && (obj.firstKickoffTeam = teamToJSON(message.firstKickoffTeam));
495498
message.matchType !== undefined && (obj.matchType = matchTypeToJSON(message.matchType));
499+
message.maxRobotsPerTeam !== undefined && (obj.maxRobotsPerTeam = message.maxRobotsPerTeam);
496500
return obj;
497501
},
498502
};

frontend/src/proto/ssl_gc_state.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,8 @@ export interface State {
254254
readyContinueTime?: Date;
255255
shootoutState?: ShootoutState;
256256
statusMessage?: string;
257+
/** The maximum number of bots per team (overwrites the division config) */
258+
maxBotsPerTeam?: number;
257259
}
258260

259261
export interface State_TeamStateEntry {
@@ -514,6 +516,7 @@ export const State = {
514516
readyContinueTime: isSet(object.readyContinueTime) ? fromJsonTimestamp(object.readyContinueTime) : undefined,
515517
shootoutState: isSet(object.shootoutState) ? ShootoutState.fromJSON(object.shootoutState) : undefined,
516518
statusMessage: isSet(object.statusMessage) ? String(object.statusMessage) : "",
519+
maxBotsPerTeam: isSet(object.maxBotsPerTeam) ? Number(object.maxBotsPerTeam) : 0,
517520
};
518521
},
519522

@@ -559,6 +562,7 @@ export const State = {
559562
message.shootoutState !== undefined &&
560563
(obj.shootoutState = message.shootoutState ? ShootoutState.toJSON(message.shootoutState) : undefined);
561564
message.statusMessage !== undefined && (obj.statusMessage = message.statusMessage);
565+
message.maxBotsPerTeam !== undefined && (obj.maxBotsPerTeam = Math.round(message.maxBotsPerTeam));
562566
return obj;
563567
},
564568
};

frontend/src/views/StartView.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import FirstKickOffInput from "@/components/team/FirstKickOffInput.vue";
1414
import FieldHalfInput from "@/components/team/FieldHalfInput.vue";
1515
import StageInput from "@/components/start/StageInput.vue";
1616
import {teams} from "@/helpers";
17+
import MaxRobotsPerTeamInput from "@/components/start/MaxRobotsPerTeamInput.vue";
1718
</script>
1819

1920
<template>
@@ -77,6 +78,7 @@ import {teams} from "@/helpers";
7778
<q-separator spaced/>
7879

7980
<div class="row justify-evenly">
81+
<MaxRobotsPerTeamInput/>
8082
<StageInput/>
8183
<div class="q-pa-md">
8284
<EndMatchButton/>

internal/app/engine/engine.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,9 @@ func (e *Engine) Start() error {
240240

241241
initializeAddedTeamInfoFields(e.currentState.TeamInfo(state.Team_BLUE))
242242
initializeAddedTeamInfoFields(e.currentState.TeamInfo(state.Team_YELLOW))
243+
if e.currentState.MaxBotsPerTeam == nil {
244+
e.currentState.MaxBotsPerTeam = new(int32)
245+
}
243246

244247
e.stateMachine.Geometry = e.gameConfig.DefaultGeometry[e.currentState.Division.Div()]
245248
log.Printf("Loaded default geometry for DivA: %+v", e.stateMachine.Geometry)
@@ -459,10 +462,11 @@ func (e *Engine) initialStateFromStore() *state.State {
459462
func (e *Engine) createInitialState() (s *state.State) {
460463
s = state.NewState()
461464
s.Division = state.ToDiv(e.gameConfig.DefaultDivision)
465+
*s.MaxBotsPerTeam = e.gameConfig.MaxBots[e.gameConfig.DefaultDivision]
462466
for _, team := range state.BothTeams() {
463467
*s.TeamInfo(team).TimeoutsLeft = e.gameConfig.Normal.Timeouts
464468
s.TeamInfo(team).TimeoutTimeLeft = durationpb.New(e.gameConfig.Normal.TimeoutDuration)
465-
*s.TeamInfo(team).MaxAllowedBots = e.gameConfig.MaxBots[e.gameConfig.DefaultDivision]
469+
*s.TeamInfo(team).MaxAllowedBots = *s.MaxBotsPerTeam
466470
*s.TeamInfo(team).ChallengeFlags = e.gameConfig.ChallengeFlags
467471
*s.TeamInfo(team).BotSubstitutionsLeft = e.gameConfig.BotSubstitutionBudget
468472
}

internal/app/state/ssl_gc_state.pb.go

Lines changed: 36 additions & 24 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/app/state/state.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ func NewState() (s *State) {
2020
s.Division = new(Division)
2121
s.FirstKickoffTeam = new(Team)
2222
s.MatchType = new(MatchType)
23+
s.MaxBotsPerTeam = new(int32)
2324

2425
*s.MatchType = MatchType_UNKNOWN_MATCH
2526
*s.Stage = Referee_NORMAL_FIRST_HALF_PRE

internal/app/statemachine/change_cards.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ func (s *StateMachine) processChangeYellowCardOver(newState *state.State) (chang
2828

2929
func (s *StateMachine) updateMaxBots(newState *state.State) {
3030
for _, team := range state.BothTeams() {
31-
max := s.gameConfig.MaxBots[newState.Division.Div()]
31+
maxBots := *newState.MaxBotsPerTeam
3232
yellowCards := activeYellowCards(newState.TeamInfo(team).YellowCards)
3333
redCards := int32(len(newState.TeamInfo(team).RedCards))
34-
*newState.TeamInfo(team).MaxAllowedBots = max - yellowCards - redCards
34+
*newState.TeamInfo(team).MaxAllowedBots = maxBots - yellowCards - redCards
3535
}
3636
}
3737

internal/app/statemachine/change_config.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ func (s *StateMachine) processChangeUpdateConfig(newState *state.State, change *
99
if change.Division != nil {
1010
log.Printf("Change division to %v", *change.Division)
1111
newState.Division = change.Division
12+
*newState.MaxBotsPerTeam = s.gameConfig.MaxBots[change.Division.Div()]
1213
s.updateMaxBots(newState)
1314
s.Geometry = s.gameConfig.DefaultGeometry[change.Division.Div()]
1415
log.Printf("Updated geometry to %+v", s.Geometry)
@@ -30,5 +31,15 @@ func (s *StateMachine) processChangeUpdateConfig(newState *state.State, change *
3031
log.Printf("Change match type to %s", change.MatchType.String())
3132
newState.MatchType = change.MatchType
3233
}
34+
if change.MaxRobotsPerTeam != nil {
35+
maxRobots := change.MaxRobotsPerTeam.GetValue()
36+
if maxRobots <= 0 {
37+
log.Printf("Ignoring invalid max robots per team: %d", maxRobots)
38+
} else {
39+
log.Printf("Change max robots per team to %d", maxRobots)
40+
*newState.MaxBotsPerTeam = maxRobots
41+
s.updateMaxBots(newState)
42+
}
43+
}
3344
return
3445
}

0 commit comments

Comments
 (0)