| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883 |
- package gamelogic
- import (
- "encoding/json"
- "fmt"
- "math"
- "math/rand"
- "time"
- coreservice "bet24.com/servers/coreservice/client"
- "bet24.com/servers/games/quickludo/config"
- robotmanager "bet24.com/servers/insecureframe/robot"
- waterpool "bet24.com/servers/micros/waterpool/proto"
- "bet24.com/servers/user"
- )
- func (ts *tablesink) checkAndStartGame() {
- if ts.gameScene.Phase != Phase_Free && ts.gameScene.Phase != Phase_End {
- return
- }
- // 查看是否所有人都ready
- readyCount := 0
- for i := 0; i < CHAIR_COUNT; i++ {
- usr := ts.table.GetUserByChair(i)
- if usr == nil {
- continue
- }
- userStatus := usr.GetUserStatus()
- // 旁观不判断
- if userStatus <= user.UserStatus_Free ||
- userStatus == user.UserStatus_Watch {
- continue
- }
- // 如果是开始
- if userStatus == user.UserStatus_Play {
- ts.table.LogWithTableId("-----checkAndStartGame: chair[%d]: %d, playing kicked", i, usr.GetUserId())
- //ts.table.KickUserByChair(i, true)
- continue
- }
- if userStatus != user.UserStatus_Ready {
- ts.table.LogWithTableId("-----checkAndStartGame: chair[%d]: %d, status: %d", i, usr.GetUserId(), usr.GetUserStatus())
- return
- }
- readyCount++
- }
- ts.table.LogWithTableId("-----checkAndStartGame IsDual:%v readyCount:%d ", ts.IsDual(), readyCount)
- if (ts.IsDual() && readyCount == 2) || (!ts.IsDual() && readyCount == 4) {
- ts.startGame()
- }
- }
- func (ts *tablesink) checkIsNeedRobot() {
- if !robotmanager.IsRunning() {
- return
- }
- //私人场不补机器人
- if ts.table.IsPrivate() {
- return
- }
- if ts.gameScene.Phase != Phase_Free && ts.gameScene.Phase != Phase_End {
- return
- }
- count := 0
- for i := 0; i < CHAIR_COUNT; i++ {
- usr := ts.table.GetUserByChair(i)
- if usr == nil {
- continue
- }
- /*if usr.IsRobot() {
- continue
- }*/
- if usr.GetUserStatus() <= user.UserStatus_Free {
- continue
- }
- count++
- }
- chairCount := CHAIR_COUNT
- if ts.IsDual() {
- chairCount = 2
- }
- if count >= chairCount {
- return
- }
- robotCount := 1
- if !ts.IsDual() {
- robotCount = rand.Intn(chairCount-count) + 1
- }
- ts.table.LogWithTableId("-------checkIsNeedRobot. need: %d ------", robotCount)
- for i := 0; i < robotCount; i++ {
- sec := rand.Intn(robotCount*3*1000) + 1000
- time.AfterFunc(time.Duration(sec)*time.Millisecond, func() {
- if ts.gameScene.Phase != Phase_Free && ts.gameScene.Phase != Phase_End {
- return
- }
- tableID := ts.table.GetTableID()
- robotmanager.GetOneRobotEnterTable(tableID, ts.roomInfo.MinGold, ts.roomInfo.MaxGold)
- })
- }
- }
- func (ts *tablesink) removeOneRobot() {
- if ts.gameScene.Phase != Phase_End {
- return
- }
- for i := 0; i < CHAIR_COUNT; i++ {
- usr := ts.table.GetUserByChair(i)
- if usr == nil {
- continue
- }
- if !usr.IsRobot() {
- continue
- }
- ts.table.KickUserByChair(i, false)
- return
- }
- }
- func (ts *tablesink) checkUserReadyStatus(chair int) {
- if ts.gameScene.Phase != Phase_Free && ts.gameScene.Phase != Phase_End {
- return
- }
- usr := ts.table.GetUserByChair(chair)
- if usr == nil {
- return
- }
- if !usr.IsRobot() {
- ts.table.LogWithTableId("1111111------checkUserReadyStatus: %d %d", chair, usr.GetUserId())
- //超时没有准备则踢出
- ts.table.KickUserByChair(chair, true)
- return
- }
- //桌上还有没有真人,有就准备,没有就踢走
- count := 0
- for i := 0; i < CHAIR_COUNT; i++ {
- u := ts.table.GetUserByChair(i)
- if u == nil {
- continue
- }
- if u.IsRobot() {
- continue
- }
- if u.GetUserStatus() <= user.UserStatus_Free {
- continue
- }
- count++
- }
- //只要有一个真人在就准备
- if count >= 1 {
- ts.table.LogWithTableId("tablesink.checkUserReadyStatus: %d robot to ready ", usr.GetUserId())
- ts.table.SetUserReadyStatus(usr.GetUserIndex(), true)
- } else {
- ts.table.LogWithTableId("------checkUserReadyStatus: %d ", usr.GetUserId())
- //超时没有准备则踢出
- ts.table.KickUser(usr.GetUserIndex(), !usr.IsRobot())
- // if usr.IsRobot() {
- // //ts.table.UserWatch(usr.GetUserIndex())
- // ts.table.KickUser(usr.GetUserIndex(), false)
- // } else {
- // ts.table.UserWatch(usr.GetUserIndex())
- // }
- }
- }
- func (ts *tablesink) checkUserQuitStatus(chair int) {
- if ts.gameScene.Phase != Phase_End {
- return
- }
- usr := ts.table.GetUserByChair(chair)
- if usr == nil {
- return
- }
- if usr.IsRobot() {
- ts.table.KillTimer(TIMER_QUIT_0 + chair)
- ts.table.KillTimer(TIMER_READY_0 + chair)
- ts.table.KickUser(usr.GetUserIndex(), !usr.IsRobot())
- return
- }
- }
- // 匹配阶段超时
- func (ts *tablesink) dealMatchTimeOut() {
- ts.gameScene.Phase = Phase_Move
- ts.LastOpraTime = time.Now()
- ts.gameScene.Index++
- ts.table.NotifySceneChanged(-1)
- ts.resetGameTimer(false, false, 0)
- }
- // 移动棋子或掷骰子 阶段超时
- func (ts *tablesink) dealPlayTimeOut() {
- if ts.gameScene.Phase != Phase_Dice && ts.gameScene.Phase != Phase_Move {
- return
- }
- if isValidChair(ts.gameScene.WhoseTurn) {
- ts.gameScene.Players[ts.gameScene.WhoseTurn].AutoOut = true
- }
- ts.dealGamePlay()
- }
- // 处理游戏阶段逻辑 包含掷骰子和移动飞机
- func (ts *tablesink) dealGamePlay() {
- ts.LastOpraTime = time.Now()
- chairId := ts.gameScene.WhoseTurn
- if !isValidChair(chairId) {
- ts.table.LogWithTableId("tablesink.dealGamePlay whoseturn invalid %d", chairId)
- return
- }
- player := ts.gameScene.Players[chairId]
- // 掷骰子
- if player.LastAction == Action_Move {
- ts.doAction(chairId, Action_Dice, 0, nil)
- } else {
- ts.doAction(chairId, Action_Move, -1, nil)
- }
- }
- func (ts *tablesink) onRobotChatTimer() {
- start := rand.Intn(4)
- for i := 0; i < CHAIR_COUNT; i++ {
- chair := (start + i) % CHAIR_COUNT
- usr := ts.table.GetUserByChair(chair)
- if usr == nil || !usr.IsRobot() {
- continue
- }
- whoseturn := ts.table.GetUserByChair(ts.gameScene.WhoseTurn)
- if whoseturn == nil {
- return
- }
- ts.sendBatChat(usr.GetUserIndex(), usr.GetUserId(), whoseturn.GetUserId())
- return
- }
- }
- func (ts *tablesink) sendBatChat(userIndex int32, sender, receiver int) {
- if sender == receiver {
- return
- }
- if rand.Intn(100) >= 35 {
- return
- }
- chatIds := []int{0, 4, 10, 11}
- chatId := chatIds[rand.Intn(4)]
- data := fmt.Sprintf("3/%d/%d/%d", chatId, sender, receiver)
- ts.table.LogWithTableId("tablesink.sendBatChat ,%s", data)
- ts.recvChatMsg(userIndex, data)
- }
- // 检查机器人操作
- func (ts *tablesink) checkRobotAction(isCanMove, isNextChair bool, moveDuration int) {
- chairId := ts.gameScene.WhoseTurn
- usr := ts.table.GetUserByChair(chairId)
- if usr == nil {
- return
- }
- if !usr.IsRobot() {
- return
- }
- //机器人也要考虑延迟问题 否则会导致前端收消息过快
- delay := SEC_DELAY //掷骰子时间 机器人用等待时间
- switch ts.gameScene.Phase {
- case Phase_Dice:
- //如果没有可以移动的则直接进入掷骰子阶段的定时间
- if isNextChair && !isCanMove {
- //没有移动直接换人 加延迟
- delay += SEC_NEXT_CHAIR
- } else if isCanMove {
- //移动棋子时间
- delay -= SEC_NEXT_CHAIR
- //机器人要判断是否只有一个棋子可以移动
- count := ts.gameScene.Players[chairId].canMovePlaneCountByPosition()
- if count != 1 {
- //有多个棋子时增加选择时间
- delay += rand.Intn(2500)
- }
- }
- case Phase_Move:
- //前一个有移动的话 要算上移动的等待时间
- if isCanMove {
- delay += moveDuration
- }
- }
- time.AfterFunc(time.Duration(delay)*time.Millisecond, func() {
- ts.dealGamePlay()
- })
- }
- func (ts *tablesink) startGame() {
- // 创建场景
- tableId := ts.table.GetTableID()
- ts.gameScene.initData(tableId)
- ts.gameScene.base = ts.roomInfo.BaseScore
- validChairs := []int{}
- for i := 0; i < CHAIR_COUNT; i++ {
- usr := ts.table.GetUserByChair(i)
- if usr == nil {
- continue
- }
- userStatus := usr.GetUserStatus()
- if userStatus != user.UserStatus_Ready {
- ts.table.LogWithTableId("ts.startGame chair[%d] userStatue = %d", i, userStatus)
- if usr.IsRobot() {
- go ts.table.KickUser(usr.GetUserIndex(), false)
- }
- return
- }
- userGold := ts.table.GetUserChipOrGoldByUser(usr)
- if userGold < ts.roomInfo.MinGold || (ts.roomInfo.MaxGold > 0 && userGold > ts.roomInfo.MaxGold) {
- ts.table.LogWithTableId("tablesink.startGame %d 金币不足, 站起", usr.GetUserId())
- if usr.IsRobot() {
- go ts.table.KickUser(usr.GetUserIndex(), false)
- } else {
- go ts.table.UserWatch(usr.GetUserIndex())
- }
- break
- }
- // 先投注
- ok := ts.writeScore(usr.GetUserId(), -ts.roomInfo.BaseScore, 0, 0, ScoreType_Bet, ts.roomInfo.RoomName, usr.IsRobot())
- if !ok {
- break
- }
- ts.gameScene.Players[i].initData(i, usr.GetUserId(), userGold)
- ts.gameScene.Players[i].IsValid = true
- ts.gameScene.Players[i].userId = usr.GetUserId()
- ts.gameScene.Players[i].bet = ts.roomInfo.BaseScore
- ts.gameScene.Players[i].isRobot = usr.IsRobot()
- ts.gameScene.pool += ts.roomInfo.BaseScore
- validChairs = append(validChairs, i)
- }
- readyCount := len(validChairs)
- if (ts.IsDual() && readyCount != 2) || (!ts.IsDual() && readyCount < CHAIR_COUNT) {
- ts.table.LogWithTableId("游戏开始,用户不足")
- ts.gameScene.Phase = Phase_End
- // 分数还原
- for i := 0; i < CHAIR_COUNT; i++ {
- if !ts.gameScene.Players[i].IsValid {
- continue
- }
- if ts.gameScene.Players[i].bet > 0 {
- ts.writeScore(ts.gameScene.Players[i].userId, ts.gameScene.Players[i].bet, 0, 0,
- ScoreType_Return, ts.roomInfo.RoomName, ts.gameScene.Players[i].isRobot)
- }
- }
- ts.endGame()
- ts.gameScene.initData(tableId)
- return
- }
- ts.gameScene.gameInit(validChairs[rand.Intn(len(validChairs))])
- ts.sendMatchEnd()
- ts.gameScene.dump(false)
- ts.table.StartGame()
- }
- // 发送匹配结束
- func (ts *tablesink) sendMatchEnd() {
- //发送匹配结束
- ts.gameScene.Phase = Phase_Match
- ts.table.SetTimer(TIMER_MATCH, SEC_MATCH)
- ts.table.KillTimer(TIMER_ROBOT)
- }
- func (ts *tablesink) endGame() {
- ts.table.LogWithTableId("--------endGame-----------")
- ts.gameScene.dump(true)
- ts.gameScene.Index = 0
- ts.table.KillAllTimer()
- if ts.table.IsPrivate() {
- // ts.table.SetTimer(TIMER_DELAY_END, 1000)
- // 私人场,不继续下一把
- //if ts.roomInfo.BaseScore == 0 {
- //ts.gameScene.pointsToEndScore()
- //}
- return
- }
- // 先调用框架的EngGame,保证旁观用户状态改变
- ts.table.EndGame()
- realUserCount := 0
- robotCount := 0
- for i := 0; i < CHAIR_COUNT; i++ {
- usr := ts.table.GetUserByChair(i)
- if usr == nil {
- continue
- }
- // 机器人,随机3-5秒准备
- if !usr.IsRobot() {
- ts.table.SetTimer(TIMER_READY_0+i, SEC_READY)
- realUserCount++
- } else {
- ts.table.SetTimer(TIMER_READY_0+i, 100)
- robotCount++
- }
- }
- if (ts.IsDual() && realUserCount >= 1 && robotCount > 0) || !ts.IsDual() && realUserCount >= 3 && robotCount > 0 {
- ts.table.SetTimer(TIMER_REMOVE_ROBOT, 6000+rand.Intn(3000))
- }
- }
- // 聊天
- func (ts *tablesink) recvChatMsg(userIndex int32, data string) {
- usr := ts.table.GetPlayer(userIndex)
- if usr == nil {
- ts.table.LogWithTableId("tablesink.recvChatMsg,usr[%d] not exist", userIndex)
- return
- }
- ts.table.SendGameData(-1, CMD_TABLECHAT, data)
- }
- // 取消托管消息
- func (ts *tablesink) recvCancleAutoMsg(userIndex int32, data string) {
- usr := ts.table.GetPlayer(userIndex)
- if usr == nil {
- ts.table.LogWithTableId("tablesink.recvCancleAutoMsg,usr[%d] not exist", userIndex)
- return
- }
- chairId := usr.GetUserChairId()
- if chairId == -1 {
- return
- }
- ts.gameScene.Players[chairId].AutoOut = false
- // 重启倒计时
- if ts.gameScene.WhoseTurn != chairId {
- return
- }
- ts.table.KillTimer(TIMER_GAME)
- switch ts.gameScene.Phase {
- case Phase_Dice:
- ts.table.SetTimer(TIMER_GAME, ts.GetMoveSec())
- return
- case Phase_Move:
- ts.table.SetTimer(TIMER_GAME, ts.GetDiceSec())
- return
- }
- }
- // 操作掷骰子或者移动飞机
- func (ts *tablesink) recvAction(userIndex int32, data string) {
- if ts.gameScene.Phase != Phase_Dice && ts.gameScene.Phase != Phase_Move {
- ts.table.LogWithTableId("tablesink.recvAction,phase is wrong! %d ", ts.gameScene.Phase)
- return
- }
- usr := ts.table.GetPlayer(userIndex)
- if usr == nil {
- ts.table.LogWithTableId("tablesink.recvAction,usr[%d] not exist", userIndex)
- return
- }
- chairId := usr.GetUserChairId()
- if !isValidChair(chairId) {
- ts.table.LogWithTableId("tablesink.recvAction invalid chair %d", chairId)
- return
- }
- var action CmdAction
- err := json.Unmarshal([]byte(data), &action)
- if err != nil {
- ts.table.LogWithTableId("tablesink.recvAction,Unmarshal failed[%d] %s", userIndex, data)
- return
- }
- if action.Action == Action_Drop {
- ts.table.LogWithTableId("tablesink.recvAction,dealDrop[%d] %s", userIndex, data)
- ts.dealDrop(chairId)
- return
- }
- ts.doAction(chairId, action.Action, action.PlaneId, usr)
- }
- // 获得骰子点数
- func (ts *tablesink) getDicePoint(chairId int, isRobot bool) int {
- number := 0
- round := ts.gameScene.Players[chairId].round
- hopeRound := ts.gameScene.Players[chairId].hopeRound
- hope := ts.gameScene.Players[chairId].hope
- if isRobot {
- //如果是机器人出点的时候 检查是否有可以攻击的对手
- rnd := rand.Intn(100)
- points := []int{1, 2, 3, 4, 5, 6}
- if rnd <= config.Rooms.GetParam1(ts.roomInfo.RoomID) {
- //检查前方是否有非机器人棋子
- for _, v := range ts.gameScene.Players[chairId].Planes {
- //没有出机场或者已经到终点和快到终点的过滤
- if v.Position == 0 || v.Position == MAX_STEP || v.Position >= SAFE_START {
- continue
- }
- for _, p := range points {
- //可以攻击优先
- total, _, _ := ts.gameScene.checkPositionIsCrashed(chairId, v.Position+p, v.Id)
- if total == 1 {
- number = 6
- if p < 6 {
- number = p
- }
- if number == hope {
- ts.gameScene.Players[chairId].isShakeOutHope = true
- }
- return number
- }
- }
- }
- }
- }
- //每过4轮检查一次期待点数
- if hopeRound%4 == 0 {
- if !ts.gameScene.Players[chairId].isShakeOutHope {
- //如果3轮内没有出过 则必出期待点
- number = hope
- ts.gameScene.Players[chairId].isShakeOutHope = true
- return number
- }
- ts.gameScene.Players[chairId].isShakeOutHope = false
- }
- //随机取
- number = ts.getRandomNumber(round)
- if ts.IsDual() && !isRobot {
- //如果是两人场 减少机器人被攻击的可能性
- rnd := rand.Intn(100)
- if rnd <= config.Rooms.GetParam1(ts.roomInfo.RoomID) {
- //可以攻击 则替换点数
- unAttackPoint := ts.gameScene.getUnAttackPoint(chairId)
- if len(unAttackPoint) > 0 {
- number = unAttackPoint[rand.Intn(len(unAttackPoint))]
- }
- }
- } else if ts.IsDual() && isRobot && number < 3 && ts.gameScene.checkIsBehind(chairId) {
- //从3,4,5,6中随机取一个
- number = rand.Intn(4) + 3
- }
- if number == hope {
- ts.gameScene.Players[chairId].isShakeOutHope = true
- }
- return number
- }
- func (ts *tablesink) doAction(chairId, action, planeId int, usr *user.UserInfo) {
- isRobot := ts.isRobot(chairId)
- number := 0
- if action == Action_Dice {
- ts.gameScene.Players[chairId].round++
- ts.gameScene.Players[chairId].hopeRound++
- number = ts.getDicePoint(chairId, isRobot)
- //ts.sendWinChat(usr.GetUserIndex(), usr.GetUserId(), 2000+rand.Intn(2000))
- }
- ok, errMsg, isNextChair, stepCount := ts.gameScene.addAction(chairId, action, number, planeId, isRobot)
- if !ok {
- if usr != nil {
- ts.table.SendGameData(usr.GetUserIndex(), CMD_ACTION, errMsg)
- }
- return
- }
- ts.table.KillTimer(TIMER_GAME)
- if ts.gameScene.Players[chairId].isWin() {
- ts.checkAndEndGame(chairId, stepCount)
- return
- }
- isCanMove := true
- moveDuration := 0
- if isNextChair {
- ts.gameScene.nextChair()
- //如果切换玩家并且前一个玩家是移动棋子则需要增加延迟
- if action == Action_Dice {
- isCanMove = false
- }
- }
- if action == Action_Move {
- ts.gameScene.Phase = Phase_Move
- moveDuration = stepCount * SEC_MOVE_TIME
- if ts.gameScene.ActionResult.CrashedChairId >= 0 && ts.gameScene.ActionResult.CrashedPlaneId >= 0 {
- //有攻击则增加时间
- moveDuration += SEC_DELAY
- }
- } else {
- ts.gameScene.Phase = Phase_Dice
- }
- ts.gameScene.Index++
- ts.table.NotifySceneChanged(-1)
- ts.resetGameTimer(isCanMove, isNextChair, moveDuration)
- }
- // 重置游戏计时器
- func (ts *tablesink) resetGameTimer(isCanMove, isNextChair bool, moveDuration int) {
- ts.table.KillTimer(TIMER_GAME)
- ts.table.KillTimer(TIMER_ROBOT)
- if !isValidChair(ts.gameScene.WhoseTurn) {
- return
- }
- switch ts.gameScene.Phase {
- case Phase_Dice:
- if ts.gameScene.Players[ts.gameScene.WhoseTurn].AutoOut {
- times := SEC_AUTO
- if isNextChair && !isCanMove {
- //没有移动直接换人 加延迟
- times += SEC_NEXT_CHAIR
- } else if isCanMove {
- times = SEC_AUTO + SEC_DELAY
- }
- ts.table.SetTimer(TIMER_GAME, times)
- } else {
- //如果没有可以移动的则直接进入掷骰子阶段的定时间
- times := ts.GetDiceSec()
- if isNextChair && !isCanMove {
- //没有移动直接换人 加延迟
- times += SEC_NEXT_CHAIR
- } else if isCanMove {
- times = ts.GetMoveSec() + SEC_DELAY
- }
- ts.table.SetTimer(TIMER_GAME, times)
- }
- case Phase_Move:
- if ts.gameScene.WhoseTurn != -1 && ts.gameScene.Players[ts.gameScene.WhoseTurn].AutoOut {
- //移动棋子时间要长一些
- times := SEC_AUTO
- if isCanMove {
- times += moveDuration
- }
- ts.table.SetTimer(TIMER_GAME, times)
- } else {
- //前一个有移动的话 要算上移动的等待时间
- times := ts.GetDiceSec()
- if isCanMove {
- times += moveDuration
- }
- ts.table.SetTimer(TIMER_GAME, times)
- }
- }
- ts.table.SetTimer(TIMER_ROBOT, SEC_ROBOT_CHAT)
- ts.LastOpraTime = time.Now()
- ts.checkRobotAction(isCanMove, isNextChair, moveDuration)
- }
- func (ts *tablesink) checkAndEndGame(winner, stepCount int) {
- _, ended := ts.gameScene.addWinner(winner)
- if ended {
- // 结束了,把没写分的都写分
- for i := 0; i < CHAIR_COUNT; i++ {
- ts.writeChairScore(i)
- }
- //私人房上报获胜玩家,这个游戏只会有一个玩家获胜
- if ts.table.IsPrivate() {
- winnerUsers := make([]int, 1)
- for i := 0; i < 1; i++ {
- winnerUsers[i] = ts.gameScene.Players[winner].userId
- }
- ts.table.PrivateRoomSetWinners(winnerUsers)
- }
- ts.enterEndPhase()
- } else {
- // 没有结束,先写分
- ts.writeChairScore(winner)
- ts.table.SetUserEndGame(winner)
- ts.gameScene.Players[winner].IsValid = false
- ts.gameScene.Index++
- ts.gameScene.nextChair()
- ts.table.NotifySceneChanged(-1)
- //额外增加播放旗子动画
- moveDuration := stepCount*SEC_MOVE_TIME + SEC_DELAY*2
- ts.resetGameTimer(true, true, moveDuration)
- }
- }
- func (ts *tablesink) writeChairScore(chairId int) {
- if !ts.gameScene.Players[chairId].IsValid {
- return
- }
- if ts.gameScene.Players[chairId].writtenScore {
- return
- }
- player := &ts.gameScene.Players[chairId]
- if player.Dropped {
- return
- }
- score := ts.gameScene.Players[chairId].Score
- if score <= 0 {
- ts.gameScene.Players[chairId].Score = -ts.roomInfo.BaseScore
- ts.writeScore(player.userId, 0, 0, 1, ScoreType_End, ts.roomInfo.RoomName, ts.isRobot(chairId))
- ts.writeExpScore(chairId)
- go ts.table.WriteBetRecord(player.userId, ts.roomInfo.BaseScore, 0, 1.0, "lose", "lose", GAME_NAME)
- player.writtenScore = true
- usr := ts.table.GetUserByChair(chairId)
- if usr != nil {
- go ts.table.RequestADAward(usr.GetUserIndex(), -ts.roomInfo.BaseScore)
- }
- return
- }
- tax := (score - ts.roomInfo.BaseScore) * ts.roomInfo.RoomInfoBase.TaxRate / 100
- ts.writeScore(player.userId, score-tax, tax, 1, ScoreType_End, ts.roomInfo.RoomName, ts.isRobot(chairId))
- ts.writeExpScore(chairId)
- go ts.table.WriteBetRecord(player.userId, ts.roomInfo.BaseScore, score-tax, 1.0, "win", fmt.Sprintf("win[%d]", player.Place), GAME_NAME)
- player.writtenScore = true
- }
- // 写经验分数
- func (ts *tablesink) writeExpScore(chairId int) {
- if !ts.table.IsPrivate() && ts.roomInfo.LevelParam >= 100 {
- exp := 400
- if ts.gameScene.Players[chairId].Score <= 0 {
- exp = 200
- }
- value := (ts.roomInfo.LevelParam * exp) / 100
- value = ts.table.AddExperience(ts.gameScene.Players[chairId].userId, value)
- ts.gameScene.Players[chairId].LevelValue = value
- }
- }
- func (ts *tablesink) enterEndPhase() {
- ts.gameScene.Phase = Phase_End
- ts.gameScene.WhoseTurn = -1
- ts.gameScene.Index++
- ts.table.NotifySceneChanged(-1)
- ts.endGame()
- ts.gameScene.initData(ts.table.GetTableID())
- }
- func (ts *tablesink) writeScore(userId int, amount, tax int, status, scoreType int, sourceName string, isRobot bool) bool {
- if !isRobot {
- config.Rooms.AddWinAmount(ts.roomInfo.RoomID, -amount)
- }
- if config.Server.LoseTax > 0 && scoreType == ScoreType_End {
- if amount > 0 && tax > 0 {
- go coreservice.ModifyJackpot(tax/10, GAMEID, userId, GAME_NAME, config.Server.IsChipRoom > 0)
- tax = 0
- } else {
- // 如果是退出、放弃,则加税
- score := ts.gameScene.getScore(userId)
- if score < 0 {
- tax = int(math.Abs(float64(score))) * ts.roomInfo.RoomInfoBase.TaxRate / 100
- }
- }
- }
- ok, _ := ts.table.WriteUserMoney(userId, amount, tax, status, scoreType, sourceName)
- if ok && !isRobot {
- waterpool.ReduceInventoryValue(GAMEID, ts.roomInfo.RoomName, amount, waterpool.RoomType_Normal)
- }
- return ok
- }
- func (ts *tablesink) isRobot(chairId int) bool {
- usr := ts.table.GetUserByChair(chairId)
- if usr == nil {
- return false
- }
- return usr.IsRobot()
- }
- func (ts *tablesink) dealDrop(chairId int) bool {
- ts.table.LogWithTableId("tablesink.dealDrop 用户弃权 chairId:%d Players:%v", chairId, ts.gameScene.Players[chairId])
- if !isValidChair(chairId) {
- ts.table.LogWithTableId("tablesink.dealDrop invalid ChairId %d", chairId)
- return false
- }
- if !ts.gameScene.Players[chairId].IsValid {
- ts.table.LogWithTableId("tablesink.dealDrop invalid ChairId2 %d", chairId)
- return false
- }
- if ts.gameScene.Players[chairId].Place > 0 {
- ts.table.LogWithTableId("tablesink.dealDrop Winning users cannot dropped %d", chairId)
- return false
- }
- if ts.gameScene.Players[chairId].Dropped {
- ts.table.LogWithTableId("tablesink.dealDrop already dropped %d", chairId)
- return false
- }
- ts.gameScene.Index++
- ts.gameScene.Players[chairId].drop()
- ts.gameScene.Players[chairId].LastAction = Action_Drop
- // 如果没人了,结算并写分
- validPlayerCount := 0
- winner := -1 //获胜者
- for i := 0; i < CHAIR_COUNT; i++ {
- if !ts.gameScene.Players[i].IsValid {
- continue
- }
- if ts.gameScene.Players[i].Dropped {
- continue
- }
- validPlayerCount++
- winner = i
- }
- usr := ts.table.GetUserByChair(chairId)
- ts.gameScene.Players[chairId].Score = -ts.roomInfo.BaseScore
- if ts.gameScene.Players[chairId].Score+ts.gameScene.Players[chairId].enterGold < 0 {
- ts.table.LogWithTableId("tablesink.dealDrop 分数不够扣 %d %d",
- ts.gameScene.Players[chairId].Score, ts.gameScene.Players[chairId].enterGold)
- ts.gameScene.Players[chairId].Score = -ts.gameScene.Players[chairId].enterGold
- }
- //逃跑也写分
- ts.writeScore(usr.GetUserId(), 0, 0, 1, ScoreType_End, ts.roomInfo.RoomName, ts.isRobot(chairId))
- go ts.table.WriteBetRecord(ts.gameScene.Players[chairId].userId, ts.roomInfo.BaseScore, 0, 1.0, "drop", "drop", GAME_NAME)
- if usr != nil {
- go ts.table.RequestADAward(usr.GetUserIndex(), -ts.roomInfo.BaseScore)
- }
- ts.table.SetUserEndGame(chairId)
- ts.gameScene.Players[chairId].gameInit()
- ts.broadcastDrop(chairId) //广播弃权消息滞后避免广播弃权消息时,用户已经退出
- if validPlayerCount <= 1 {
- ts.gameScene.LastTurn = chairId
- ts.checkAndEndGame(winner, 0)
- return true
- }
- // 其他人还能继续
- if ts.gameScene.WhoseTurn == chairId {
- ts.gameScene.nextChair()
- ts.resetGameTimer(true, true, 0)
- ts.table.NotifySceneChanged(-1)
- }
- return true
- }
- func (ts *tablesink) broadcastDrop(chairId int) {
- var cmd CmdDrop
- cmd.ChairId = chairId
- d, _ := json.Marshal(cmd)
- ts.table.SendGameData(-1, CMD_DROP, string(d))
- }
|