github.com/lianghucheng/zrddz@v0.0.0-20200923083010-c71f680932e2/src/game/internal/landlord_game.go (about) 1 package internal 2 3 import ( 4 "common" 5 "conf" 6 "game/poker" 7 "math/rand" 8 "msg" 9 "sort" 10 "time" 11 12 "github.com/name5566/leaf/log" 13 ) 14 15 // 叫地主 16 func (room *LandlordRoom) bid(userID int) { 17 playerData := room.userIDPlayerDatas[userID] 18 playerData.state = landlordActionBid 19 20 broadcast(&msg.S2C_ActionLandlordBid{ 21 Position: playerData.position, 22 Countdown: conf.GetCfgTimeout().LandlordBid, 23 }, room.positionUserIDs, -1) 24 25 playerData.actionTimestamp = time.Now().Unix() 26 log.Debug("等待 userID %v 叫地主", userID) 27 room.bidTimer = skeleton.AfterFunc((time.Duration(conf.GetCfgTimeout().LandlordBid+2))*time.Second, func() { 28 log.Debug("userID %v 自动不叫", userID) 29 room.doBid(userID, false) 30 }) 31 } 32 33 // 抢地主 34 func (room *LandlordRoom) grab(userID int) { 35 playerData := room.userIDPlayerDatas[userID] 36 playerData.state = landlordActionGrab 37 38 broadcast(&msg.S2C_ActionLandlordGrab{ 39 Position: playerData.position, 40 Countdown: conf.GetCfgTimeout().LandlordGrab, 41 }, room.positionUserIDs, -1) 42 43 playerData.actionTimestamp = time.Now().Unix() 44 log.Debug("等待 userID %v 抢地主", userID) 45 room.grabTimer = skeleton.AfterFunc(time.Duration(conf.GetCfgTimeout().LandlordGrab+2)*time.Second, func() { 46 log.Debug("userID %v 自动不抢", userID) 47 room.doGrab(userID, false) 48 }) 49 } 50 51 // 确定地主 52 func (room *LandlordRoom) decideLandlord(userID int) { 53 broadcast(&msg.S2C_ClearAction{}, room.positionUserIDs, -1) 54 55 room.doTask(userID, 7) // 累计当地主10次 56 room.doTask(userID, 54) // 当地主15次 57 58 room.landlordUserID = userID 59 playerData := room.userIDPlayerDatas[room.landlordUserID] 60 //新人任务 累计当地主5次 1002 61 if room.rule.RoomType == roomBaseScoreMatching { 62 playerData.user.updateRedPacketTask(1002) 63 //初级任务 当地主10次 (1010) 64 playerData.user.updateRedPacketTask(1010) 65 } 66 if room.rule.BaseScore == 3000 { 67 //中级任务 普通场当地主8次 2006 68 playerData.user.updateRedPacketTask(2006) 69 room.doTask(userID, 44) // 普通场当地主8次 70 } 71 //高级任务 当地主20次 3001 72 playerData.user.updateRedPacketTask(3001) 73 for i := 1; i < room.rule.MaxPlayers; i++ { 74 peasantUserID := room.positionUserIDs[(playerData.position+i)%room.rule.MaxPlayers] 75 room.peasantUserIDs = append(room.peasantUserIDs, peasantUserID) 76 } 77 room.calculateLandlordMultiple() 78 79 broadcast(&msg.S2C_DecideLandlord{ 80 Position: playerData.position, 81 }, room.positionUserIDs, -1) 82 // 最后三张 83 room.lastThree = room.rests[:3] 84 room.rests = []int{} 85 sort.Sort(sort.Reverse(sort.IntSlice(room.lastThree))) 86 log.Debug("三张: %v", poker.ToCardsString(room.lastThree)) 87 88 broadcast(&msg.S2C_UpdateLandlordLastThree{ 89 Cards: room.lastThree, 90 }, room.positionUserIDs, -1) 91 92 playerData.hands = append(playerData.hands, room.lastThree...) 93 playerData.taskID51 = 0 // 单局打出2个顺子3次计数初始化 94 playerData.taskID2001 = 0 95 sort.Sort(sort.Reverse(sort.IntSlice(playerData.hands))) 96 97 if user, ok := userIDUsers[userID]; ok { 98 user.WriteMsg(&msg.S2C_UpdatePokerHands{ 99 Position: playerData.position, 100 Hands: playerData.hands, 101 NumberOfHands: len(playerData.hands), 102 ShowCards: playerData.showCards, 103 }) 104 user.WriteMsg(&msg.S2C_UpdateLandlordMultiple{ 105 Multiple: playerData.multiple, 106 }) 107 } 108 if playerData.showCards { 109 broadcast(&msg.S2C_UpdatePokerHands{ 110 Position: playerData.position, 111 Hands: playerData.hands, 112 NumberOfHands: len(playerData.hands), 113 ShowCards: true, 114 }, room.positionUserIDs, playerData.position) 115 } else { 116 broadcast(&msg.S2C_UpdatePokerHands{ 117 Position: playerData.position, 118 Hands: []int{}, 119 NumberOfHands: len(playerData.hands), 120 }, room.positionUserIDs, playerData.position) 121 } 122 switch room.rule.RoomType { 123 case roomPractice: 124 skeleton.AfterFunc(1*time.Second, func() { 125 room.showCards() 126 }) 127 case roomBaseScoreMatching, roomBaseScorePrivate: 128 skeleton.AfterFunc(1*time.Second, func() { 129 room.double() 130 }) 131 case roomVIPPrivate, roomRedPacketMatching, roomRedPacketPrivate: 132 broadcast(&msg.S2C_ClearAction{}, room.positionUserIDs, -1) 133 room.discard(room.landlordUserID, poker.ActionLandlordDiscardMust) 134 } 135 } 136 137 // 加倍 138 func (room *LandlordRoom) double() { 139 actionTimestamp := time.Now().Unix() 140 for _, userID := range room.positionUserIDs { 141 playerData := room.userIDPlayerDatas[userID] 142 playerData.state = landlordActionDouble 143 playerData.actionTimestamp = actionTimestamp 144 145 if user, ok := userIDUsers[userID]; ok { 146 user.WriteMsg(&msg.S2C_ActionLandlordDouble{ 147 Countdown: conf.GetCfgTimeout().LandlordDouble, 148 }) 149 } 150 } 151 log.Debug("等待所有人加倍") 152 room.doubleTimer = skeleton.AfterFunc(time.Duration(conf.GetCfgTimeout().LandlordDouble+2)*time.Second, func() { 153 for _, userID := range room.positionUserIDs { 154 playerData := room.userIDPlayerDatas[userID] 155 if playerData.state == landlordActionDouble { 156 log.Debug("userID %v 自动不加倍", userID) 157 room.doDouble(userID, false) 158 } 159 } 160 }) 161 } 162 163 // 明牌 164 func (room *LandlordRoom) showCards() { 165 broadcast(&msg.S2C_ClearAction{}, room.positionUserIDs, -1) 166 167 actionTimestamp := time.Now().Unix() 168 switch room.rule.RoomType { 169 case roomBaseScoreMatching: 170 landlordPlayData := room.userIDPlayerDatas[room.landlordUserID] 171 if landlordPlayData.showCards { 172 room.discard(room.landlordUserID, poker.ActionLandlordDiscardMust) 173 return 174 } 175 landlordPlayData.state = landlordActionShowCards 176 landlordPlayData.actionTimestamp = actionTimestamp 177 landlordPlayData.user.WriteMsg(&msg.S2C_ActionLandlordShowCards{ 178 Countdown: conf.GetCfgTimeout().LandlordShowCards, 179 }) 180 181 log.Debug("等待地主明牌") 182 room.showCardsTimer = skeleton.AfterFunc(time.Duration(conf.GetCfgTimeout().LandlordShowCards+2)*time.Second, func() { 183 if landlordPlayData.state == landlordActionShowCards { 184 log.Debug("地主: %v 自动不明牌", room.landlordUserID) 185 room.doShowCards(room.landlordUserID, false) 186 } 187 }) 188 default: 189 if len(room.getShowCardsUserIDs()) == room.rule.MaxPlayers { 190 room.discard(room.landlordUserID, poker.ActionLandlordDiscardMust) 191 return 192 } 193 for _, userID := range room.positionUserIDs { 194 playerData := room.userIDPlayerDatas[userID] 195 if !playerData.showCards { 196 playerData.state = landlordActionShowCards 197 playerData.actionTimestamp = actionTimestamp 198 playerData.user.WriteMsg(&msg.S2C_ActionLandlordShowCards{ 199 Countdown: conf.GetCfgTimeout().LandlordShowCards, 200 }) 201 } 202 } 203 log.Debug("等待其他人明牌") 204 room.showCardsTimer = skeleton.AfterFunc(time.Duration(conf.GetCfgTimeout().LandlordShowCards+2)*time.Second, func() { 205 for _, userID := range room.positionUserIDs { 206 playerData := room.userIDPlayerDatas[userID] 207 if playerData.state == landlordActionShowCards { 208 log.Debug("userID %v 自动不明牌", userID) 209 room.doShowCards(userID, false) 210 } 211 } 212 }) 213 } 214 } 215 216 // 出牌 217 func (room *LandlordRoom) discard(userID int, actionDiscardType int) { 218 playerData := room.userIDPlayerDatas[userID] 219 playerData.state = landlordActionDiscard 220 playerData.actionDiscardType = actionDiscardType 221 222 broadcast(&msg.S2C_ActionLandlordDiscard{ 223 ActionDiscardType: poker.ActionLandlordDiscardAlternative, 224 Position: playerData.position, 225 Countdown: conf.GetCfgTimeout().LandlordDiscard, 226 }, room.positionUserIDs, playerData.position) 227 228 prevDiscards := []int{} 229 countdown := conf.GetCfgTimeout().LandlordDiscard 230 hint := make([][]int, 0) 231 switch playerData.actionDiscardType { 232 case poker.ActionLandlordDiscardNothing: 233 if playerData.hosted { 234 goto HOST 235 } 236 countdown = conf.GetCfgTimeout().LandlordDiscardNothing 237 case poker.ActionLandlordDiscardAlternative: 238 discarderPlayerData := room.userIDPlayerDatas[room.discarderUserID] 239 prevDiscards = discarderPlayerData.discards[len(discarderPlayerData.discards)-1] 240 if poker.CompareLandlordDiscard(playerData.hands, prevDiscards) { 241 goto DISCARD_HANDS 242 } 243 if playerData.hosted { 244 goto HOST 245 } 246 hint = poker.GetDiscardHint(prevDiscards, playerData.hands) 247 log.Debug("提示出牌: %v", poker.ToMeldsString(hint)) 248 case poker.ActionLandlordDiscardMust: 249 if len(playerData.hands) > 1 && poker.GetLandlordCardsType(playerData.hands[:2]) == poker.KingBomb && poker.GetLandlordCardsType(playerData.hands[2:]) > poker.Error { 250 goto DISCARD_KINGBOMB 251 } 252 handsType := poker.GetLandlordCardsType(playerData.hands) 253 if handsType != poker.Error && handsType != poker.FourDualsolo && handsType != poker.FourDualpair { 254 goto DISCARD_HANDS 255 } 256 if playerData.hosted { 257 goto HOST 258 } 259 } 260 if user, ok := userIDUsers[userID]; ok { 261 user.WriteMsg(&msg.S2C_ActionLandlordDiscard{ 262 ActionDiscardType: playerData.actionDiscardType, 263 Position: playerData.position, 264 Countdown: countdown, 265 PrevDiscards: prevDiscards, 266 Hint: hint, 267 }) 268 } 269 playerData.actionTimestamp = time.Now().Unix() 270 log.Debug("等待 userID %v 出牌 动作: %v", userID, playerData.actionDiscardType) 271 room.discardTimer = skeleton.AfterFunc(time.Duration(countdown+2)*time.Second, func() { 272 switch playerData.actionDiscardType { 273 case poker.ActionLandlordDiscardNothing: 274 log.Debug("userID %v 自动不出", userID) 275 room.doDiscard(userID, []int{}) 276 default: 277 room.doSystemHost(userID, true) 278 } 279 }) 280 return 281 HOST: // 托管出牌 282 skeleton.AfterFunc(1500*time.Millisecond, func() { 283 room.doHostDiscard(userID) 284 }) 285 return 286 DISCARD_HANDS: // 自动出手牌 287 skeleton.AfterFunc(1500*time.Millisecond, func() { 288 log.Debug("userID %v 自动出: %v", userID, poker.ToCardsString(playerData.hands)) 289 room.doDiscard(userID, playerData.hands) 290 }) 291 return 292 DISCARD_KINGBOMB: // 自动出王炸 293 skeleton.AfterFunc(1500*time.Millisecond, func() { 294 log.Debug("userID %v 自动出王炸", userID) 295 room.doDiscard(userID, []int{53, 52}) 296 }) 297 } 298 299 func (room *LandlordRoom) doPrepare(userID int, showCards bool) { 300 playerData := room.userIDPlayerDatas[userID] 301 if room.rule.RoomType == roomVIPPrivate && playerData.vipChips == 0 { 302 if user, ok := userIDUsers[userID]; ok { 303 user.WriteMsg(&msg.S2C_SetVIPRoomChips{ 304 Error: msg.S2C_SetVIPChips_ChipsUnset, 305 Position: playerData.position, 306 }) 307 } 308 return 309 } 310 311 playerData.state = landlordReady 312 playerData.showCards = showCards 313 314 broadcast(&msg.S2C_Prepare{ 315 Position: playerData.position, 316 Ready: true, 317 }, room.positionUserIDs, -1) 318 319 if room.allReady() { 320 room.state = roomGame 321 skeleton.AfterFunc(1*time.Second, func() { 322 room.StartGame() 323 }) 324 } 325 } 326 327 func (room *LandlordRoom) doBid(userID int, bid bool) { 328 playerData := room.userIDPlayerDatas[userID] 329 if playerData.state != landlordActionBid { 330 return 331 } 332 room.bidTimer.Stop() 333 playerData.state = landlordWaiting 334 335 broadcast(&msg.S2C_LandlordBid{ 336 Position: playerData.position, 337 Bid: bid, 338 }, room.positionUserIDs, -1) 339 340 dealerPlayerData := room.userIDPlayerDatas[room.dealerUserID] 341 nextUserID := room.positionUserIDs[(playerData.position+1)%room.rule.MaxPlayers] 342 lastPos := (dealerPlayerData.position + room.rule.MaxPlayers - 1) % room.rule.MaxPlayers 343 if bid { 344 room.bidUserID = userID 345 if room.rule.BaseScore == 3000 { 346 //中级任务 普通场叫地主6次 2007 347 playerData.user.updateRedPacketTask(2007) 348 room.doTask(userID, 45) // 普通场叫地主6次 349 } 350 if playerData.position == lastPos { 351 skeleton.AfterFunc(1*time.Second, func() { 352 room.decideLandlord(userID) 353 }) 354 } else { 355 room.grab(nextUserID) 356 } 357 } else { 358 if playerData.position == lastPos { 359 if room.shuffleTimes == 2 { 360 skeleton.AfterFunc(1*time.Second, func() { 361 landlordUserID := room.positionUserIDs[rand.Intn(room.rule.MaxPlayers)] 362 room.decideLandlord(landlordUserID) 363 }) 364 return 365 } 366 if len(room.getShowCardsUserIDs()) == 0 { 367 skeleton.AfterFunc(1*time.Second, func() { 368 room.StartGame() 369 }) 370 } else { 371 skeleton.AfterFunc(1*time.Second, func() { 372 room.decideLandlord(room.getShowCardsUserIDs()[0]) 373 }) 374 } 375 } else { 376 room.bid(nextUserID) 377 } 378 } 379 } 380 381 func (room *LandlordRoom) doGrab(userID int, grab bool) { 382 playerData := room.userIDPlayerDatas[userID] 383 if playerData.state != landlordActionGrab { 384 return 385 } 386 room.grabTimer.Stop() 387 playerData.state = landlordWaiting 388 389 broadcast(&msg.S2C_LandlordGrab{ 390 Position: playerData.position, 391 Grab: grab, 392 Again: userID == room.bidUserID, 393 }, room.positionUserIDs, -1) 394 395 dealerPlayerData := room.userIDPlayerDatas[room.dealerUserID] 396 nextUserID := room.positionUserIDs[(playerData.position+1)%room.rule.MaxPlayers] 397 lastPos := (dealerPlayerData.position + room.rule.MaxPlayers - 1) % room.rule.MaxPlayers 398 if grab { 399 room.doTask(userID, 8) // 累计抢地主10次 400 //初级任务 抢地主10次 1011 401 playerData.user.updateRedPacketTask(1011) 402 room.calculateMultiple(-1, 2) 403 room.grabUserIDs = append(room.grabUserIDs, userID) 404 if userID == room.bidUserID { 405 skeleton.AfterFunc(1*time.Second, func() { 406 room.decideLandlord(userID) 407 }) 408 } else { 409 if playerData.position == lastPos { 410 room.grab(room.bidUserID) 411 } else { 412 room.grab(nextUserID) 413 } 414 } 415 } else { 416 numberOfGrab := len(room.grabUserIDs) 417 if userID == room.bidUserID { 418 skeleton.AfterFunc(1*time.Second, func() { 419 room.decideLandlord(room.grabUserIDs[numberOfGrab-1]) 420 }) 421 } else { 422 if playerData.position == lastPos { 423 if numberOfGrab == 0 { 424 skeleton.AfterFunc(1*time.Second, func() { 425 room.decideLandlord(room.bidUserID) 426 }) 427 } else { 428 room.grab(room.bidUserID) 429 } 430 } else { 431 room.grab(nextUserID) 432 } 433 } 434 } 435 } 436 437 func (room *LandlordRoom) doDouble(userID int, double bool) { 438 playerData := room.userIDPlayerDatas[userID] 439 if playerData.state != landlordActionDouble { 440 return 441 } 442 playerData.state = landlordWaiting 443 444 broadcast(&msg.S2C_LandlordDouble{ 445 Position: playerData.position, 446 Double: double, 447 }, room.positionUserIDs, -1) 448 449 if double { 450 room.doTask(userID, 10) // 累计加倍底分10次 451 //初级任务 菜鸟场加倍底分4次 1016 452 if room.rule.BaseScore == 500 { 453 playerData.user.updateRedPacketTask(1016) 454 } 455 if room.rule.BaseScore == 3000 { 456 //中级任务 普通场加倍底分4次 2005 457 playerData.user.updateRedPacketTask(2005) 458 //高级任务 普通场加倍底分8次 3008 459 playerData.user.updateRedPacketTask(3008) 460 room.doTask(userID, 43) // 普通场加倍8次 461 } 462 463 room.calculateMultiple(userID, 2) 464 } 465 if room.allWaiting() { 466 room.doubleTimer.Stop() 467 skeleton.AfterFunc(1*time.Second, func() { 468 room.showCards() 469 }) 470 } 471 } 472 473 func (room *LandlordRoom) doShowCards(userID int, showCards bool) { 474 playerData := room.userIDPlayerDatas[userID] 475 if playerData.state != landlordActionShowCards { 476 return 477 } 478 playerData.state = landlordWaiting 479 playerData.showCards = showCards 480 481 if playerData.showCards { 482 room.calculateMultiple(userID, 2) 483 484 broadcast(&msg.S2C_LandlordShowCards{ 485 Position: playerData.position, 486 }, room.positionUserIDs, -1) 487 488 broadcast(&msg.S2C_UpdatePokerHands{ 489 Position: playerData.position, 490 Hands: playerData.hands, 491 NumberOfHands: len(playerData.hands), 492 ShowCards: true, 493 }, room.positionUserIDs, playerData.position) 494 //初级任务 累计明牌开始10次 1012 495 playerData.user.updateRedPacketTask(1012) 496 //高级任务 普通场明牌开始10次 3005 497 if room.rule.BaseScore == 3000 { 498 playerData.user.updateRedPacketTask(3005) 499 } 500 } 501 if room.allWaiting() { 502 room.showCardsTimer.Stop() 503 broadcast(&msg.S2C_ClearAction{}, room.positionUserIDs, -1) 504 room.discard(room.landlordUserID, poker.ActionLandlordDiscardMust) 505 } 506 } 507 508 // cards 长度为零时表示不出 509 func (room *LandlordRoom) doDiscard(userID int, cards []int) { 510 playerData := room.userIDPlayerDatas[userID] 511 if playerData.state != landlordActionDiscard { 512 return 513 } 514 cards = poker.ReSortLandlordCards(cards) 515 cardsLen := len(cards) 516 cardsType := poker.GetLandlordCardsType(cards) 517 contain := common.Contain(playerData.hands, cards) 518 519 var prevDiscards []int 520 if room.discarderUserID > 0 && room.discarderUserID != userID { 521 discarderPlayerData := room.userIDPlayerDatas[room.discarderUserID] 522 prevDiscards = discarderPlayerData.discards[len(discarderPlayerData.discards)-1] 523 } 524 if cardsLen == 0 && playerData.actionDiscardType == poker.ActionLandlordDiscardMust || 525 cardsLen > 0 && playerData.actionDiscardType == poker.ActionLandlordDiscardNothing || 526 cardsLen > 0 && !contain || cardsLen > 0 && cardsType == poker.Error || 527 cardsLen > 0 && playerData.actionDiscardType == poker.ActionLandlordDiscardAlternative && !poker.CompareLandlordDiscard(cards, prevDiscards) { 528 if user, ok := userIDUsers[userID]; ok { 529 after := int(time.Now().Unix() - playerData.actionTimestamp) 530 countdown := conf.GetCfgTimeout().LandlordDiscard - after 531 if countdown > 1 { 532 user.WriteMsg(&msg.S2C_ActionLandlordDiscard{ 533 ActionDiscardType: playerData.actionDiscardType, 534 Position: playerData.position, 535 Countdown: countdown - 1, 536 PrevDiscards: prevDiscards, 537 }) 538 } 539 } 540 return 541 } 542 if room.discardTimer != nil { 543 room.discardTimer.Stop() 544 room.discardTimer = nil 545 } 546 playerData.state = landlordWaiting 547 548 broadcast(&msg.S2C_LandlordDiscard{ 549 Position: playerData.position, 550 Cards: cards, 551 }, room.positionUserIDs, -1) 552 553 nextUserID := room.positionUserIDs[(playerData.position+1)%room.rule.MaxPlayers] 554 if cardsLen == 0 { 555 log.Debug("userID %v 不出", userID) 556 if room.discarderUserID == nextUserID { 557 room.discard(nextUserID, poker.ActionLandlordDiscardMust) 558 } else { 559 nextUserPlayerData := room.userIDPlayerDatas[nextUserID] 560 if poker.CompareLandlordHands(prevDiscards, nextUserPlayerData.hands) { 561 room.discard(nextUserID, poker.ActionLandlordDiscardNothing) 562 } else { 563 room.discard(nextUserID, poker.ActionLandlordDiscardAlternative) 564 } 565 } 566 return 567 } 568 switch cardsType { 569 case poker.AirplaneChain, poker.TrioSoloAirplane, poker.TrioPairChain: 570 room.doTask(userID, 1) // 累计打出3个飞机 571 room.doTask(userID, 23) // 累计打出3个飞机,奖励3000金币 572 //初级任务 累计打出3个飞机 1006 573 playerData.user.updateRedPacketTask(1006) 574 if room.rule.BaseScore == 3000 { 575 room.doTask(userID, 38) // 普通场打出1个飞机 576 room.doTask(userID, 55) // 普通场打出2个飞机 577 } 578 case poker.PairSisters: 579 room.doTask(userID, 2) // 累计打出5个连对 580 room.doTask(userID, 33) // 累计打出6个连对 581 //初级任务 累计打出5个连对 1007 582 playerData.user.updateRedPacketTask(1007) 583 //中级任务 累计打出10个连对 2002 584 playerData.user.updateRedPacketTask(2002) 585 if room.rule.BaseScore == 3000 { 586 room.doTask(userID, 39) // 普通场打出2个连对 587 room.doTask(userID, 56) // 普通场打出4个连对 588 } 589 case poker.KingBomb: 590 room.doTask(userID, 3) // 累计打出3个炸弹 591 //初级任务 累计打出3个炸弹 1008 592 playerData.user.updateRedPacketTask(1008) 593 //初级任务 累计打出3个王炸 1009 594 playerData.user.updateRedPacketTask(1009) 595 //中级任务 累计打出5个王炸 596 playerData.user.updateRedPacketTask(2000) 597 room.doTask(userID, 4) // 累计打出3个王炸 598 room.doTask(userID, 24) // 累计打出2个王炸,奖励3000金币 599 room.doTask(userID, 25) // 累计打出3个炸弹,奖励3000金币 600 601 room.doTask(userID, 30) // 打出4个炸弹 602 room.doTask(userID, 31) // 打出4个王炸 603 room.doTask(userID, 34) // 打出5个炸弹 604 room.doTask(userID, 46) // 打出6个炸弹 605 room.doTask(userID, 47) // 打出5个王炸 606 //中级任务 单局打出2个炸弹 607 //playerData.user.updateRedPacketTask(2001) 608 playerData.taskID2001++ 609 room.doTask(userID, 32) // 单局打出2个炸弹 610 if room.rule.BaseScore == 3000 { 611 room.doTask(userID, 40) // 普通场打出2个炸弹 612 room.doTask(userID, 41) // 普通场打出2个王炸 613 room.doTask(userID, 57) // 普通场打出3个炸弹 614 } 615 616 room.calculateMultiple(-1, 2) 617 case poker.Bomb: 618 //初级任务 累计打出3个炸弹 1008 619 playerData.user.updateRedPacketTask(1008) 620 //中级任务 单局打出2个炸弹 621 //playerData.user.updateRedPacketTask(2001) 622 playerData.taskID2001++ 623 room.doTask(userID, 3) // 累计打出3个炸弹 624 room.doTask(userID, 25) // 累计打出3个炸弹,奖励3000金币 625 626 room.doTask(userID, 30) // 打出4个炸弹 627 room.doTask(userID, 32) // 单局打出2个炸弹 628 room.doTask(userID, 34) // 打出5个炸弹 629 room.doTask(userID, 46) // 打出6个炸弹 630 631 if room.rule.BaseScore == 3000 { 632 room.doTask(userID, 40) // 普通场打出2个炸弹 633 room.doTask(userID, 57) // 普通场打出3个炸弹 634 } 635 room.calculateMultiple(-1, 2) 636 case poker.SoloChain: 637 room.doTask(userID, 36) // 打出10个顺子 638 playerData.taskID51++ // 单局打出2个顺子3次 639 640 if room.rule.BaseScore == 3000 { 641 //中级任务 普通场打出6个顺子 2004 642 playerData.user.updateRedPacketTask(2004) 643 room.doTask(userID, 42) // 普通场打出6个顺子 644 room.doTask(userID, 58) // 普通场打出10个顺子 645 } 646 case poker.TrioPair: 647 room.doTask(userID, 52) // 打出8次三带二 648 //中级任务 打出8次三带二 2009 649 playerData.user.updateRedPacketTask(2009) 650 651 if room.rule.BaseScore == 3000 { 652 room.doTask(userID, 63) // 普通场打出8次三带二 653 //高级任务 普通场打出8次三带二 3002 654 playerData.user.updateRedPacketTask(3002) 655 } 656 case poker.FourDualsolo: 657 //中级任务 打出三次四带二 2010 658 playerData.user.updateRedPacketTask(2010) 659 room.doTask(userID, 53) // 打出3次四带二 660 } 661 room.discarderUserID = userID 662 room.discards = append(room.discards, cards...) 663 playerData.discards = append(playerData.discards, cards) 664 playerData.hands = common.Remove(playerData.hands, cards) 665 log.Debug("userID %v, 出牌: %v, 剩余: %v", userID, poker.ToCardsString(cards), poker.ToCardsString(playerData.hands)) 666 if playerData.showCards { 667 broadcast(&msg.S2C_UpdatePokerHands{ 668 Position: playerData.position, 669 Hands: playerData.hands, 670 NumberOfHands: len(playerData.hands), 671 ShowCards: true, 672 }, room.positionUserIDs, -1) 673 } else { 674 if user, ok := userIDUsers[userID]; ok { 675 user.WriteMsg(&msg.S2C_UpdatePokerHands{ 676 Position: playerData.position, 677 Hands: playerData.hands, 678 NumberOfHands: len(playerData.hands), 679 }) 680 } 681 broadcast(&msg.S2C_UpdatePokerHands{ 682 Position: playerData.position, 683 Hands: []int{}, 684 NumberOfHands: len(playerData.hands), 685 }, room.positionUserIDs, playerData.position) 686 } 687 if len(playerData.hands) == 0 { 688 room.winnerUserIDs = append(room.winnerUserIDs, userID) 689 skeleton.AfterFunc(1*time.Second, func() { 690 room.EndGame() 691 }) 692 return 693 } 694 if room.discarderUserID == nextUserID { 695 room.discard(nextUserID, poker.ActionLandlordDiscardMust) 696 } else { 697 nextUserPlayerData := room.userIDPlayerDatas[nextUserID] 698 if poker.CompareLandlordHands(cards, nextUserPlayerData.hands) { 699 room.discard(nextUserID, poker.ActionLandlordDiscardNothing) 700 } else { 701 room.discard(nextUserID, poker.ActionLandlordDiscardAlternative) 702 } 703 } 704 } 705 706 // 托管出牌 707 func (room *LandlordRoom) doHostDiscard(userID int) { 708 playerData := room.userIDPlayerDatas[userID] 709 if playerData.state != landlordActionDiscard { 710 return 711 } 712 switch playerData.actionDiscardType { 713 case poker.ActionLandlordDiscardNothing: 714 room.doDiscard(userID, []int{}) 715 return 716 case poker.ActionLandlordDiscardAlternative: 717 discarderPlayerData := room.userIDPlayerDatas[room.discarderUserID] 718 prevDiscards := discarderPlayerData.discards[len(discarderPlayerData.discards)-1] 719 hint := poker.GetDiscardHint(prevDiscards, playerData.hands) 720 if len(hint) == 0 { 721 room.doDiscard(userID, []int{}) 722 return 723 } 724 hintType := poker.GetLandlordCardsType(hint[0]) 725 if len(playerData.discards) == 0 { // 还没有出过牌 726 switch hintType { 727 case poker.KingBomb, poker.Bomb: 728 room.doDiscard(userID, []int{}) 729 } 730 } 731 if playerData.user.isRobot() { 732 if common.InArray(room.peasantUserIDs, playerData.user.baseData.userData.UserID) && 733 common.InArray(room.peasantUserIDs, discarderPlayerData.user.baseData.userData.UserID) { 734 switch hintType { 735 case poker.Solo: 736 if poker.CardValue(hint[0][0]) < 12 { 737 room.doDiscard(userID, hint[0]) 738 return 739 } 740 case poker.Pair: 741 if poker.CardValue(hint[0][0]) < 11 { 742 room.doDiscard(userID, hint[0]) 743 return 744 } 745 } 746 room.doDiscard(userID, []int{}) 747 return 748 } 749 } 750 log.Debug("userID %v 托管出牌: %v", userID, poker.ToCardsString(hint[0])) 751 room.doDiscard(userID, hint[0]) 752 return 753 case poker.ActionLandlordDiscardMust: 754 analyzer := new(poker.LandlordAnalyzer) 755 minCards := analyzer.GetMinDiscards(playerData.hands) 756 log.Debug("userID %v 托管出牌: %v", userID, poker.ToCardsString(minCards)) 757 room.doDiscard(userID, minCards) 758 return 759 } 760 } 761 762 func (room *LandlordRoom) doSystemHost(userID int, host bool) { 763 playerData := room.userIDPlayerDatas[userID] 764 if playerData.hosted == host { 765 return 766 } 767 playerData.hosted = host 768 // 托管不让别人知道 769 playerData.user.WriteMsg(&msg.S2C_SystemHost{ 770 Position: playerData.position, 771 Host: host, 772 }) 773 //broadcast(&msg.S2C_SystemHost{ 774 // Position: playerData.position, 775 // Host: host, 776 //}, room.positionUserIDs, -1) 777 778 if host { 779 room.doHostDiscard(userID) 780 } 781 } 782 783 // 重置任务 784 func (room *LandlordRoom) resetTask(userID int, taskID int) { 785 if room.rule.RoomType == roomBaseScoreMatching { 786 if user, ok := userIDUsers[userID]; ok { 787 if task, ok := user.baseData.taskIDTaskDatas[taskID]; ok { 788 if task.Progress < TaskList[taskID].Total { 789 task.Progress = 0 790 user.WriteMsg(&msg.S2C_UpdateTaskProgress{ 791 TaskID: task.TaskID, 792 Progress: task.Progress, 793 }) 794 } 795 } 796 } else { 797 resetTaskProgress(userID, taskID) 798 } 799 } 800 } 801 802 // 做任务 803 func (room *LandlordRoom) doTask(userID int, taskID int) { 804 if room.rule.RoomType == roomBaseScoreMatching || taskID == 28 || taskID == 29 { 805 if user, ok := userIDUsers[userID]; ok { 806 user.doTask(taskID) 807 } else { 808 addTaskProgress(userID, taskID) 809 } 810 } 811 }