GameBattleController.kt
package io.github.lishangbu.avalon.game.controller
import io.github.lishangbu.avalon.game.battle.api.CreateImportedBattleSessionApiRequest
import io.github.lishangbu.avalon.game.battle.api.GameBattleRequestAssembler
import io.github.lishangbu.avalon.game.battle.api.GameBattleSessionView
import io.github.lishangbu.avalon.game.battle.api.GameBattleSettlementView
import io.github.lishangbu.avalon.game.battle.api.GameBattleTargetQueryView
import io.github.lishangbu.avalon.game.battle.api.GameBattleTurnResultView
import io.github.lishangbu.avalon.game.battle.api.GameBattleViewAssembler
import io.github.lishangbu.avalon.game.battle.api.SmartCaptureChoiceRequest
import io.github.lishangbu.avalon.game.battle.api.SmartItemChoiceRequest
import io.github.lishangbu.avalon.game.battle.api.SmartMoveChoiceRequest
import io.github.lishangbu.avalon.game.battle.api.SubmitReplacementChoiceRequest
import io.github.lishangbu.avalon.game.battle.api.SubmitRunChoiceRequest
import io.github.lishangbu.avalon.game.battle.api.SubmitSwitchChoiceRequest
import io.github.lishangbu.avalon.game.battle.engine.application.BattleEngineService
import io.github.lishangbu.avalon.game.battle.init.BattleInitializationService
import io.github.lishangbu.avalon.game.battle.settlement.BattleSettlementExecutor
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController
/** 游戏对战业务控制器。 */
@RestController
@RequestMapping("/game/battle")
class GameBattleController(
private val battleInitializationService: BattleInitializationService,
private val battleEngineService: BattleEngineService,
private val battleSettlementExecutor: BattleSettlementExecutor,
private val gameBattleRequestAssembler: GameBattleRequestAssembler,
private val gameBattleViewAssembler: GameBattleViewAssembler,
) {
/** 使用真实数据直接创建并导入战斗会话。 */
@PostMapping("/sessions/imported")
fun createImportedSession(
@RequestBody request: CreateImportedBattleSessionApiRequest,
): GameBattleSessionView =
gameBattleViewAssembler.toSessionView(
battleInitializationService.createImportedSession(
gameBattleRequestAssembler.toCreateImportedSessionRequest(request),
),
)
/** 启动已创建的战斗会话。 */
@PostMapping("/sessions/{sessionId}/start")
fun startSession(
@PathVariable sessionId: String,
): GameBattleSessionView = gameBattleViewAssembler.toSessionView(battleEngineService.startSession(sessionId))
/** 查询当前战斗会话。 */
@GetMapping("/sessions/{sessionId}")
fun querySession(
@PathVariable sessionId: String,
): GameBattleSessionView = gameBattleViewAssembler.toSessionView(battleEngineService.querySession(sessionId))
/** 查询当前 effect 在会话中的可选目标。 */
@GetMapping("/sessions/{sessionId}/targets")
fun queryTargets(
@PathVariable sessionId: String,
@RequestParam effectId: String,
@RequestParam actorUnitId: String,
): GameBattleTargetQueryView =
gameBattleViewAssembler.toTargetQueryView(
battleEngineService.queryTargets(sessionId, effectId, actorUnitId),
)
/** 提交智能出招。 */
@PostMapping("/sessions/{sessionId}/choices/move")
fun submitMoveChoice(
@PathVariable sessionId: String,
@RequestBody request: SmartMoveChoiceRequest,
): GameBattleSessionView =
gameBattleViewAssembler.toSessionView(
battleEngineService.submitMoveChoice(
sessionId,
gameBattleRequestAssembler.toSubmitMoveChoiceCommand(request),
),
)
/** 提交智能用道具。 */
@PostMapping("/sessions/{sessionId}/choices/item")
fun submitItemChoice(
@PathVariable sessionId: String,
@RequestBody request: SmartItemChoiceRequest,
): GameBattleSessionView =
gameBattleViewAssembler.toSessionView(
battleEngineService.submitItemChoice(
sessionId,
gameBattleRequestAssembler.toSubmitItemChoiceCommand(request),
),
)
/** 提交捕捉动作。 */
@PostMapping("/sessions/{sessionId}/choices/capture")
fun submitCaptureChoice(
@PathVariable sessionId: String,
@RequestBody request: SmartCaptureChoiceRequest,
): GameBattleSessionView =
gameBattleViewAssembler.toSessionView(
battleEngineService.submitCaptureChoice(
sessionId,
gameBattleRequestAssembler.toSubmitCaptureChoiceCommand(request),
),
)
/** 提交换人。 */
@PostMapping("/sessions/{sessionId}/choices/switch")
fun submitSwitchChoice(
@PathVariable sessionId: String,
@RequestBody request: SubmitSwitchChoiceRequest,
): GameBattleSessionView =
gameBattleViewAssembler.toSessionView(
battleEngineService.submitSwitchChoice(
sessionId,
gameBattleRequestAssembler.toSubmitSwitchChoiceCommand(request),
),
)
/** 提交逃跑。 */
@PostMapping("/sessions/{sessionId}/choices/run")
fun submitRunChoice(
@PathVariable sessionId: String,
@RequestBody request: SubmitRunChoiceRequest,
): GameBattleSessionView =
gameBattleViewAssembler.toSessionView(
battleEngineService.submitRunChoice(
sessionId,
gameBattleRequestAssembler.toSubmitRunChoiceCommand(request),
),
)
/** 提交替补上场。 */
@PostMapping("/sessions/{sessionId}/replacement")
fun submitReplacementChoice(
@PathVariable sessionId: String,
@RequestBody request: SubmitReplacementChoiceRequest,
): GameBattleSessionView =
gameBattleViewAssembler.toSessionView(
battleEngineService.submitReplacementChoice(
sessionId,
gameBattleRequestAssembler.toSubmitReplacementChoiceCommand(request),
),
)
/** 结算当前回合。 */
@PostMapping("/sessions/{sessionId}/resolve-turn")
fun resolveTurn(
@PathVariable sessionId: String,
): GameBattleTurnResultView = gameBattleViewAssembler.toTurnResultView(battleEngineService.resolveTurn(sessionId))
/** 对已结束 battle 执行统一结算。 */
@PostMapping("/sessions/{sessionId}/settle")
fun settleSession(
@PathVariable sessionId: String,
): GameBattleSettlementView =
gameBattleViewAssembler.toSettlementView(
battleSettlementExecutor.execute(
battleEngineService.buildSettlementPlan(sessionId),
),
)
}