@@ -2,9 +2,11 @@ import { BaseGame } from '@/ps/games/game';
22import {
33 ACTIONS ,
44 AllTokenTypes ,
5+ DEFAULT_POINTS_TO_WIN ,
6+ MAX_POINTS_TO_WIN ,
57 MAX_RESERVE_COUNT ,
68 MAX_TOKEN_COUNT ,
7- POINTS_TO_WIN ,
9+ MIN_POINTS_TO_WIN ,
810 TOKEN_TYPE ,
911 TokenTypes ,
1012 VIEW_ACTION_TYPE ,
@@ -29,6 +31,13 @@ export class Splendor extends BaseGame<State> {
2931
3032 constructor ( ctx : BaseContext ) {
3133 super ( ctx ) ;
34+
35+ const givenCap = ctx . args . join ( '' ) . trim ( ) ;
36+ this . state . pointsToWin = givenCap ? parseInt ( givenCap ) : DEFAULT_POINTS_TO_WIN ;
37+ if ( this . state . pointsToWin < MIN_POINTS_TO_WIN || this . state . pointsToWin > MAX_POINTS_TO_WIN || isNaN ( this . state . pointsToWin ) ) {
38+ this . throw ( 'GAME.SPLENDOR.INVALID_POINTS_CAP' , { cap : givenCap , minCap : MIN_POINTS_TO_WIN , maxCap : MAX_POINTS_TO_WIN } ) ;
39+ }
40+
3241 super . persist ( ctx ) ;
3342
3443 if ( ctx . backup ) return ;
@@ -67,7 +76,7 @@ export class Splendor extends BaseGame<State> {
6776 this . turn === lastPlayerInRound &&
6877 Object . values ( this . players )
6978 . filter ( player => ! player . out )
70- . some ( player => this . state . playerData [ player . turn ] . points >= POINTS_TO_WIN )
79+ . some ( player => this . state . playerData [ player . turn ] . points >= this . state . pointsToWin )
7180 ) ;
7281 }
7382
@@ -216,8 +225,7 @@ export class Splendor extends BaseGame<State> {
216225 case VIEW_ACTION_TYPE . CLICK_DECK : {
217226 if ( ! [ '1' , '2' , '3' ] . includes ( actionCtx ) ) throw new ChatError ( this . $T ( 'GAME.SPLENDOR.WHICH_TIER' ) ) ;
218227 const tier = + actionCtx as 1 | 2 | 3 ;
219- if ( this . state . board . cards [ tier ] . deck . length === 0 )
220- throw new ChatError ( this . $T ( 'GAME.SPLENDOR.DECK_EMPTY' , { tier } ) ) ;
228+ if ( this . state . board . cards [ tier ] . deck . length === 0 ) throw new ChatError ( this . $T ( 'GAME.SPLENDOR.DECK_EMPTY' , { tier } ) ) ;
221229
222230 const canReserve = this . canReserve ( player ) ;
223231 if ( ! canReserve ) throw new ChatError ( this . $T ( 'GAME.SPLENDOR.RESERVE_LIMIT' ) ) ;
@@ -234,10 +242,8 @@ export class Splendor extends BaseGame<State> {
234242 const tokens = this . parseTokens ( actionCtx , true ) ;
235243 const discarding = Object . values ( tokens ) . sum ( ) ;
236244
237- if ( discarding < toDiscard )
238- throw new ChatError ( this . $T ( 'GAME.SPLENDOR.DISCARD_MORE' , { required : toDiscard , discarding } ) ) ;
239- if ( ! this . canAfford ( tokens , playerData . tokens , null , false ) )
240- throw new ChatError ( this . $T ( 'GAME.SPLENDOR.CANNOT_DISCARD' ) ) ;
245+ if ( discarding < toDiscard ) throw new ChatError ( this . $T ( 'GAME.SPLENDOR.DISCARD_MORE' , { required : toDiscard , discarding } ) ) ;
246+ if ( ! this . canAfford ( tokens , playerData . tokens , null , false ) ) throw new ChatError ( this . $T ( 'GAME.SPLENDOR.CANNOT_DISCARD' ) ) ;
241247
242248 this . spendTokens ( tokens , playerData ) ;
243249 logEntry = { turn : player . turn , time : new Date ( ) , action : VIEW_ACTION_TYPE . TOO_MANY_TOKENS , ctx : { discard : tokens } } ;
@@ -278,8 +284,7 @@ export class Splendor extends BaseGame<State> {
278284 let reservedId : string ;
279285 if ( deckReserve ) {
280286 const tier = deckReserve as 1 | 2 | 3 ;
281- if ( this . state . board . cards [ tier ] . deck . length === 0 )
282- throw new ChatError ( this . $T ( 'GAME.SPLENDOR.DECK_EMPTY' , { tier } ) ) ;
287+ if ( this . state . board . cards [ tier ] . deck . length === 0 ) throw new ChatError ( this . $T ( 'GAME.SPLENDOR.DECK_EMPTY' , { tier } ) ) ;
283288
284289 const [ card ] = this . state . board . cards [ tier ] . deck . splice ( 0 , 1 ) ;
285290 playerData . reserved . push ( card ) ;
@@ -421,8 +426,7 @@ export class Splendor extends BaseGame<State> {
421426 const amt = + ( entry . match ( / \d / ) ?? '0' ) ;
422427 if ( ! ( amt >= 0 && amt < 10 ) ) throw new ChatError ( this . $T ( 'GAME.SPLENDOR.INVALID_COUNT' , { value : entry . substring ( 1 ) } ) ) ;
423428 if ( ! AllTokenTypes . includes ( type ) ) throw new ChatError ( this . $T ( 'GAME.SPLENDOR.UNRECOGNIZED_TYPE' , { type } ) ) ;
424- if ( type === TOKEN_TYPE . DRAGON && ! allowDragon )
425- throw new ChatError ( this . $T ( 'GAME.SPLENDOR.DRAGON_NOT_ALLOWED' ) ) ;
429+ if ( type === TOKEN_TYPE . DRAGON && ! allowDragon ) throw new ChatError ( this . $T ( 'GAME.SPLENDOR.DRAGON_NOT_ALLOWED' ) ) ;
426430 tokens [ type ] += amt ;
427431 } ) ;
428432 return tokens ;
@@ -433,8 +437,7 @@ export class Splendor extends BaseGame<State> {
433437 if ( count > 0 ) return { type, count, available : this . state . board . tokens [ type ] , name : metadata . types [ type ] . name } ;
434438 } ) ;
435439
436- if ( tokens [ TOKEN_TYPE . DRAGON ] )
437- return { success : false , error : this . $T ( 'GAME.SPLENDOR.DRAGON_ONLY_BY_RESERVE' ) } ;
440+ if ( tokens [ TOKEN_TYPE . DRAGON ] ) return { success : false , error : this . $T ( 'GAME.SPLENDOR.DRAGON_ONLY_BY_RESERVE' ) } ;
438441
439442 const tooMany = input . filter ( ( { count, available } ) => count > available ) ;
440443 if ( tooMany . length > 0 ) {
@@ -513,7 +516,14 @@ export class Splendor extends BaseGame<State> {
513516 else view = { type : 'player' , active : false , self : side } ;
514517 } else view = { type : 'spectator' , active : false , action : this . winCtx ? VIEW_ACTION_TYPE . GAME_END : null } ;
515518
516- const ctx : RenderCtx = { id : this . id , board : this . state . board , players : this . state . playerData , turns : this . turns , view, $T : this . $T } ;
519+ const ctx : RenderCtx = {
520+ id : this . id ,
521+ board : this . state . board ,
522+ players : this . state . playerData ,
523+ turns : this . turns ,
524+ view,
525+ $T : this . $T ,
526+ } ;
517527
518528 if ( this . winCtx ) {
519529 ctx . header = this . $T ( 'GAME.GAME_ENDED' ) ;
0 commit comments