import { take , put } from "redux-saga/effects" ; import { select } from "typed-redux-saga" ; import { GamePhase , getXpToNextLevel } from "@creature-chess/models" ; import { PlayerState } from "../state" ; import { updateLevelCommand } from "../state/commands" ; import { getPlayerLevel , getPlayerXp } from "../state/selectors" ; import { getPlayerEntityDependencies } from "../dependencies" ; const ADD_XP_COMMAND = "ADD_XP_COMMAND" ; type ADD_XP_COMMAND = typeof ADD_XP_COMMAND ; type AddXpCommand = ( { type : ADD_XP_COMMAND ; payload : { amount : number ; } ; } ) ; export const addXpCommand = ( amount ) : AddXpCommand => ( { type : ADD_XP_COMMAND , payload : { amount } } ) ; export const playerXpSaga = function * ( ) { const { boardSlices : { boardSlice , benchSlice } } = yield * getPlayerEntityDependencies ( ) ; while ( true ) { const { payload : { amount } } = yield take ( ADD_XP_COMMAND ) ; let level = yield * select ( getPlayerLevel ) ; let xp = yield * select ( getPlayerXp ) ; const oldLevel = level ; for ( let i = 0 ; i < amount ; i ++ ) { const toNextLevel = getXpToNextLevel ( level ) ; const newXp = xp + 1 ; if ( newXp === toNextLevel ) { xp = 0 ; level ++ ; } else { xp = newXp ; } } yield put ( updateLevelCommand ( { level , xp } ) ) ; if ( level !== oldLevel ) { const inPreparingPhase = yield select ( ( state ) => state . roundInfo . phase === GamePhase . PREPARING ) ; if ( inPreparingPhase ) { yield put ( boardSlice . commands . setPieceLimitCommand ( level ) ) ; } } } } ;