battle.go 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. // 逻辑脚本,方法以小写加下划线命名 例:get_money_func
  2. package ludo
  3. import (
  4. "fmt"
  5. "server/game"
  6. "server/msg"
  7. "server/tools"
  8. "time"
  9. )
  10. type RoomInfoWrapper struct {
  11. *msg.RoomInfo
  12. TimerManager *tools.TimerManager
  13. startOptTime time.Time
  14. }
  15. func init() {
  16. }
  17. // 清理解散的房间
  18. func ClearRoomInfoWrapperDisbandRoom() {
  19. gameConfig.mu.Lock()
  20. defer gameConfig.mu.Unlock()
  21. for k := range gameConfig.BattleRoom {
  22. if gameConfig.BattleRoom[k].RoomStatus == msg.RoomStatus_END {
  23. delete(gameConfig.BattleRoom, k)
  24. }
  25. }
  26. }
  27. func runBattle(room_info *RoomInfoWrapper) {
  28. gameConfig.mu.Lock()
  29. defer gameConfig.mu.Unlock()
  30. // cur_color_key := getCurColorEventKey(room_info)
  31. // TimerManager.AddEvent(cur_color_key,)
  32. gameConfig.BattleRoom[room_info.Id] = room_info
  33. game.Module.AfterFunc(time.Second*time.Duration(3), func() {
  34. room_info.notify_player_sz()
  35. })
  36. }
  37. func GetBattleRoomById(id int32) *RoomInfoWrapper {
  38. gameConfig.mu.Lock()
  39. defer gameConfig.mu.Unlock()
  40. room_info, exists := gameConfig.BattleRoom[id]
  41. if !exists {
  42. return nil
  43. }
  44. return room_info
  45. }
  46. // 根据玩家的骰子数进行相关处理
  47. func (room_info *RoomInfoWrapper) process_sz(msg_body *msg.NotifyPlayerSzNumber) {
  48. if msg_body.SzNumber == 6 {
  49. canMoveList := room_info.getRolesBySzNumber(msg_body.Color, msg_body.SzNumber)
  50. if len(canMoveList) > 0 {
  51. room_info.notify_player_move(canMoveList)
  52. } else {
  53. room_info.setNextPlayerRound()
  54. room_info.notify_player_sz()
  55. }
  56. } else {
  57. notAtHomeRoles := room_info.getRoleNotAtHomeByColor(msg_body.Color)
  58. if len(notAtHomeRoles) <= 0 { //全部都在家
  59. room_info.setNextPlayerRound()
  60. room_info.notify_player_sz()
  61. } else if len(notAtHomeRoles) == 4 { //全部都从家里出来了
  62. canMoveList := room_info.getCanMoveRoles(notAtHomeRoles, msg_body.SzNumber)
  63. if len(canMoveList) > 0 {
  64. room_info.notify_player_move(canMoveList)
  65. } else {
  66. room_info.setNextPlayerRound()
  67. room_info.notify_player_sz()
  68. }
  69. } else {
  70. if len(notAtHomeRoles) == 1 { //只有一个选择,那么直接让他走
  71. //如果一个玩家离终点剩余的步骤不等于筛子数,也将会跳到下个人回合
  72. if room_info.roleIsCanMove(notAtHomeRoles[0].MId, msg_body.SzNumber) {
  73. room_info.send_role_move(msg_body.Color, notAtHomeRoles[0].MId)
  74. } else {
  75. room_info.setNextPlayerRound()
  76. room_info.notify_player_sz()
  77. }
  78. } else {
  79. canMoveList := room_info.getCanMoveRoles(notAtHomeRoles, msg_body.SzNumber)
  80. if len(canMoveList) > 0 {
  81. room_info.notify_player_move(canMoveList)
  82. } else {
  83. room_info.setNextPlayerRound()
  84. room_info.notify_player_sz()
  85. }
  86. }
  87. }
  88. }
  89. }
  90. // 根据玩家走的步数进行相关处理
  91. func (room_info *RoomInfoWrapper) process_move(color msg.RoleType, szNumber int32, isAddRound bool, isFinish bool) {
  92. if room_info.IsOverGame() { //宣布游戏结束
  93. room_info.notify_settlement()
  94. } else {
  95. if szNumber == 6 || isAddRound || isFinish { //加一个回合
  96. } else { //下个人回合
  97. room_info.setNextPlayerRound()
  98. }
  99. room_info.notify_player_sz()
  100. }
  101. }
  102. // 通知玩家结算
  103. func (room_info *RoomInfoWrapper) notify_settlement() {
  104. message := &msg.NotifySettlement{}
  105. message.FinishColors = room_info.getFinishColors()
  106. room_info.notify_to_all_player(message)
  107. }
  108. // 通知玩家开始移动角色
  109. func (room_info *RoomInfoWrapper) notify_player_move(list []*msg.RoleData) {
  110. cur_color := room_info.CurRoundColor
  111. if len(list) == 1 {
  112. room_info.send_role_move(cur_color, list[0].MId)
  113. } else {
  114. if room_info.containsRobot(cur_color) {
  115. //如果是机器人,思考一秒然后执行移动角色
  116. room_info.delay_action_move_robot(1000, cur_color, list)
  117. }
  118. }
  119. room_info.StartCountdownPlayerOpt()
  120. message := &msg.NotifyPlayerOpt{
  121. Color: room_info.CurRoundColor,
  122. Opt: msg.OptType_SELECT_ROLE,
  123. CanMoveRoles: list,
  124. OptTime: room_info.get_cur_color_opt_time(),
  125. }
  126. room_info.notify_to_all_player(message)
  127. room_info.setCurColorOpt(message)
  128. }
  129. // 通知玩家状态
  130. func (room_info *RoomInfoWrapper) notify_player_status(color msg.RoleType, status msg.PlayerStatus, colors []*msg.ColorData) {
  131. message := &msg.NotifyPlayerStatus{
  132. Color: color,
  133. Status: status,
  134. Colors: colors,
  135. }
  136. room_info.notify_to_all_player(message)
  137. }
  138. // 获取当前回合玩家的操作时间
  139. func (room_info *RoomInfoWrapper) get_cur_color_opt_time() int32 {
  140. end := time.Now()
  141. // 计算整数秒(直接截断小数部分)
  142. seconds := int(end.Sub(room_info.startOptTime).Seconds())
  143. opt_time := gameRule.OPT_TIME - int32(seconds)
  144. fmt.Printf("room_info.OptTime:%d,%d\n", seconds, opt_time)
  145. return opt_time
  146. }
  147. // 通知玩家要骰子
  148. func (room_info *RoomInfoWrapper) notify_player_sz() {
  149. cur_color := room_info.CurRoundColor
  150. room_info.StartCountdownPlayerOpt()
  151. message := &msg.NotifyPlayerOpt{
  152. Color: cur_color,
  153. Opt: msg.OptType_ZHI_SHAI_ZI,
  154. OptTime: room_info.get_cur_color_opt_time(),
  155. }
  156. room_info.notify_to_all_player(message)
  157. room_info.setCurColorOpt(message)
  158. }
  159. // 托管操作一次
  160. func (room_info *RoomInfoWrapper) tuo_guan_opt() {
  161. curColorOpt := room_info.CurColorOptData.Opt
  162. curColor := room_info.CurRoundColor
  163. if curColorOpt == msg.OptType_SELECT_ROLE {
  164. role_id := room_info.CurColorOptData.CanMoveRoles[0].MId
  165. room_info.send_role_move(curColor, role_id)
  166. } else if curColorOpt == msg.OptType_ZHI_SHAI_ZI {
  167. room_info.send_sz(curColor)
  168. }
  169. message := &msg.NotifyPlayerStatus{
  170. Color: curColor,
  171. TimeOutColor: room_info.getColorDataByColor(curColor),
  172. Status: msg.PlayerStatus_COLOR_TIME_OUT,
  173. }
  174. room_info.notify_to_all_player(message)
  175. }
  176. // 超过10秒玩家没有操作,将他的timeout 累计加1,然后给他托管一次
  177. func (room_info *RoomInfoWrapper) time_out_tuo_guan() {
  178. cur_color := room_info.CurRoundColor
  179. color_data := room_info.getColorDataByColor(cur_color)
  180. color_data.TimeOutNum = color_data.TimeOutNum + 1
  181. if color_data.TimeOutNum > 5 { //如果玩家累计5次托管行为,将玩家踢出房间
  182. room_info.tick_color_of_room(cur_color)
  183. if room_info.IsOverGame() { //宣布游戏结束
  184. room_info.notify_settlement()
  185. }
  186. } else {
  187. room_info.tuo_guan_opt()
  188. }
  189. }
  190. // 开始计时玩家操作
  191. func (room_info *RoomInfoWrapper) StartCountdownPlayerOpt() {
  192. room_info.startOptTime = time.Now()
  193. room_info.OptTime = gameRule.OPT_TIME
  194. room_info.TimerManager.AddEvent(room_info.GetRoomTimeOutKey(), time.Duration(gameRule.OPT_TIME)*time.Second, room_info.time_out_tuo_guan)
  195. }
  196. // 取消玩家计时
  197. func (room_info *RoomInfoWrapper) CancelCountdownPlayerOpt() {
  198. room_info.TimerManager.RemoveEvent(room_info.GetRoomTimeOutKey())
  199. }
  200. // 房间里通知所有玩家
  201. func (room_info *RoomInfoWrapper) notify_to_all_player(message interface{}) {
  202. for i := range room_info.Colors {
  203. user_id := room_info.Colors[i].MId
  204. user_agent := getAgentByUserId(user_id)
  205. if user_agent != nil {
  206. user_agent.WriteMsg(message)
  207. }
  208. }
  209. }
  210. // 给前端展示一段时间后,再操作
  211. func (room_info *RoomInfoWrapper) delayActionNextRound(td int32, color msg.RoleType, szNumber int32, isAddRound bool, isFinish bool) {
  212. dtn := time.Duration(td) * time.Microsecond
  213. game.Module.Skeleton.AfterFunc(dtn, func() {
  214. room_info.process_move(color, szNumber, isAddRound, isFinish)
  215. })
  216. }
  217. // 给前端展示一段时间后,再操作
  218. func (room_info *RoomInfoWrapper) delay_action_sz(td int, msg_body *msg.NotifyPlayerSzNumber) {
  219. dtn := time.Duration(td) * time.Microsecond
  220. game.Module.Skeleton.AfterFunc(dtn, func() {
  221. room_info.process_sz(msg_body)
  222. })
  223. }
  224. // 延迟后,移动机器人
  225. func (room_info *RoomInfoWrapper) delay_action_move_robot(td int, color msg.RoleType, list []*msg.RoleData) {
  226. dtn := time.Duration(td) * time.Microsecond
  227. game.Module.Skeleton.AfterFunc(dtn, func() {
  228. role := getRandomItem(list)
  229. room_info.send_role_move(color, role.MId)
  230. })
  231. }
  232. // 更新房间信息发送给玩家
  233. func (room_info *RoomInfoWrapper) notify_update_room_info() {
  234. room_info.notify_to_all_player(&msg.NotifyUpdateRoomInfo{
  235. RoomInfo: room_info.RoomInfo,
  236. })
  237. }
  238. // 将玩家从房间踢出
  239. func (room_info *RoomInfoWrapper) tick_color_of_room(color msg.RoleType) {
  240. room_info.tickColor(color)
  241. message := &msg.NotifyPlayerStatus{
  242. Color: color,
  243. Status: msg.PlayerStatus_COLOR_KICK,
  244. Colors: room_info.Colors,
  245. }
  246. room_info.notify_to_all_player(message)
  247. }
  248. // 解散房间
  249. func (room_info *RoomInfoWrapper) dismiss_room() {
  250. }