battle.go 10 KB

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