pet_home_server/src/server/game/mod/playroom/playroom.go
2026-03-30 20:00:19 +08:00

1097 lines
27 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package playroom
import (
"fmt"
"math"
limitedTimeEventCfg "server/conf/limited_time_event"
playroomCfg "server/conf/playroom"
"server/game/mod/item"
"server/game/mod/quest"
GoUtil "server/game_util"
"server/msg"
"sort"
)
type PlayroomMod struct {
Collect map[int]int // 装饰
NewCollect map[int]*CollectInfo
Room map[int]int // 房间
Dress map[int][]int // 服装仓库
NewDress map[int]*DressInfo
DressSet map[int]int // 服装穿戴
PetAir []int // 宠物空气背包
NewPetAir map[int]*PetAirInfo // 新宠物空气背包
PetAirSet int // 宠物空气背包穿戴
Status int // 0: 未拜访 1: 拜访
Endtime int64 // 结束时间
Starttime int64 // 开始时间
WorkStatus int // 0: 未开始 1: 进行中 2: 结束
Visitor map[int]*Info // 访客
MoodInfo map[int]*Mood // 心情
AllMood int // 总心情
Reward []*item.Item // 奖励
DayFirstT int // 每日未首次触发次数
Trigger int // 未触发次数
TriggerTime int64 // 触发时间
HasVisit map[int]int64 // 今日已拜访的玩家
Target int // 拜访的目标
GameId int // 游戏ID
GameReward map[int]*item.Item // 游戏奖励
GameStatus int // 游戏状态
GameInfo map[int]interface{} // 游戏信息
Exclude bool // 是否排除
LoseItem []*item.Item // 失去的物品
ChipList []*ChipInfo // 碎片列表
Flip map[int]int // 翻牌
FlipReward []*item.Item // 翻牌奖励
WorkOutline int // 是否离线
LastFlip int // 上次翻牌奖励档次
NoFlip int // 连续未获取最高翻牌奖励次数
TodayFlip bool // 今日是否已获得最高档奖励
JackpotNum int // 每日转盘数量
Upvote int // 收到点赞次数
UpvoteList []int // 点赞列表
RoomPoint int // 房间点数
UnlockList map[int]int64 // 解锁
DailyTask map[int]*DailyTask // 每日任务
DailyTaskReward []int // 每日任务奖励
Physiology map[int]*Physiology
InteractNum int // 互动次数
RevengeUid int64 // 复仇Uid
FilterVisitor bool // 是否过滤访客
TodayVisitedUsers []int // 今日已拜访过的用户
ADItem map[int]*ItemInfo
WeeklyDiscount map[int]int // 每周折扣
}
type DressInfo struct {
Id int // 服装ID
Part int // 服装部位
AddTime int64 // 添加时间
EndTime int64 // 结束时间
Label string // 标签
Num int // 数量
}
type PetAirInfo struct {
Id int // 空气ID
Part int // 空气部位
AddTime int64 // 添加时间
EndTime int64 // 结束时间
Label string // 标签
Num int // 数量
}
type CollectInfo struct {
Id int // 空气ID
Part int // 空气部位
AddTime int64 // 添加时间
EndTime int64 // 结束时间
Label string // 标签
Num int // 数量
}
type ItemInfo struct {
Watch int // 观看次数
LastTime int64 // 上次观看时间
}
type DailyTask struct {
Items []*item.Item
Status int
Quest quest.QuestProgress
UnLock bool
Index int
}
const (
STATUS_IDLE = 0 // 未开始
STATUS_VISIT = 1 // 拜访
MOOD_TYPE_ENTER = 1 // 娱乐
MOOD_TYPE_CLEAN = 2 // 清洁
MOOD_TYPE_FOOD = 3 // 食物
GAME_RESULT_LOSE = 0 // 输
GAME_RESULT_LOW = 1 // 低
GAME_RESULT_MIDDLE = 2 // 中
GAME_RESULT_HIGH = 3 // 高
FLIP_TYPE_COPPER = 1 // 铜
FLIP_TYPE_SILVER = 2 // 银
FLIP_TYPE_GOLD = 3 // 金
PHYSIOLOGY_TYPE_STROKE = 1 // 抚摸
PHYSIOLOGY_TYPE_PLAY = 2 // 玩耍
PHYSIOLOGY_TYPE_FEED = 3 // 进食
PHYSIOLOGY_TYPE_CLEAN = 4 // 清洁
PHYSIOLOGY_TYPE_TOLIET = 5 // 上厕所
GAME_TYPE_HOOK = 1 // 愿者上钩
GAME_TYPE_FILP = 2 // 翻牌
GAME_TYPE_HIDE = 3 // 捉迷藏
DAILY_TASK_TYPE_ONE = 1 // 一阶段任务
DAILY_TASK_TYPE_TWO = 2 // 二阶段任务
ROOM_POINT_UNLOCK_LV = 6 // 房间点数解锁等级
)
type ChipInfo struct {
Uid int
Time int64
Emoji int
}
type Mood struct {
Id int
Num int
Time int64
}
type Physiology struct {
Id int
Num int
Time int64
}
type Info struct {
Time int64
Times int
}
func (p *PlayroomMod) InitData() {
if p.Collect == nil {
p.Collect = make(map[int]int)
}
if p.Dress == nil {
p.Dress = make(map[int][]int)
}
if p.DressSet == nil {
p.DressSet = make(map[int]int)
}
if p.GameInfo == nil {
p.GameInfo = make(map[int]interface{})
}
if p.NewCollect == nil {
p.NewCollect = make(map[int]*CollectInfo)
}
initCollect := playroomCfg.GetInitDecorate()
if len(p.NewCollect) == 0 {
for _, v := range initCollect {
p.NewCollect[v] = &CollectInfo{
Id: v,
AddTime: GoUtil.Now(),
Num: 1,
}
}
}
if len(p.Collect) > 0 {
for k, v := range p.Collect {
p.NewCollect[k] = &CollectInfo{
Id: k,
AddTime: GoUtil.Now(),
Num: v,
}
}
p.Collect = make(map[int]int)
}
for _, v := range initCollect {
p.Collect[v] = 1
}
if p.Room == nil {
p.Room = make(map[int]int)
p.JackpotNum = playroomCfg.GetJackpotNum()
}
if p.Visitor == nil {
p.Visitor = make(map[int]*Info)
}
if p.MoodInfo == nil {
p.MoodInfo = make(map[int]*Mood)
}
if p.Physiology == nil {
p.Physiology = make(map[int]*Physiology)
}
if p.HasVisit == nil {
p.HasVisit = make(map[int]int64)
}
if p.GameReward == nil {
p.GameReward = make(map[int]*item.Item)
}
if p.Flip == nil {
p.Flip = make(map[int]int)
}
if p.UnlockList == nil {
p.UnlockList = make(map[int]int64)
}
if p.DailyTask == nil {
p.DailyTask = make(map[int]*DailyTask)
}
if len(p.NewPetAir) == 0 {
p.NewPetAir = make(map[int]*PetAirInfo)
initPetAir := playroomCfg.GetInitAirList()
for _, v := range initPetAir {
p.NewPetAir[v] = &PetAirInfo{
Id: v,
AddTime: GoUtil.Now(),
Num: 1,
}
}
}
if len(p.PetAir) > 0 {
for _, v := range p.PetAir {
p.NewPetAir[v] = &PetAirInfo{
Id: v,
AddTime: GoUtil.Now(),
Num: 1,
}
}
p.PetAir = nil
}
if p.NewDress == nil {
p.NewDress = make(map[int]*DressInfo)
}
if len(p.NewDress) == 0 {
initDressList := playroomCfg.GetInitDressList()
for _, v := range initDressList {
part := playroomCfg.GetDressPart(v)
p.NewDress[v] = &DressInfo{
Id: v,
Part: part,
AddTime: GoUtil.Now(),
Num: 1,
}
}
}
// Dress仓库重构
if len(p.Dress) != 0 {
for _, v := range p.Dress {
for _, id := range v {
part := playroomCfg.GetDressPart(id)
p.NewDress[id] = &DressInfo{
Id: id,
Part: part,
AddTime: GoUtil.Now(),
Num: 1,
}
}
}
p.Dress = nil
}
if p.ADItem == nil {
p.ADItem = make(map[int]*ItemInfo)
}
if p.WeeklyDiscount == nil {
p.WeeklyDiscount = make(map[int]int)
}
}
func (p *PlayroomMod) ZeroUpdate() {
p.TodayFlip = false
p.LastFlip = 0
p.JackpotNum = playroomCfg.GetJackpotNum()
p.UpvoteList = nil
p.DailyTaskReward = nil
p.TodayVisitedUsers = nil
p.ADItem = make(map[int]*ItemInfo)
p.InitDailyTask()
}
func (p *PlayroomMod) InitDailyTask() {
p.DailyTask = make(map[int]*DailyTask)
index := 1
taskList1 := playroomCfg.GetDailyTask(DAILY_TASK_TYPE_ONE)
for k, v := range taskList1 {
items := playroomCfg.GetDailyTaskReward(index)
quest, _ := quest.ParseQuest(v)
p.DailyTask[k] = &DailyTask{
Items: items,
Quest: quest,
UnLock: true,
Index: index,
}
index++
}
taskList2 := playroomCfg.GetDailyTask(DAILY_TASK_TYPE_TWO)
for k, v := range taskList2 {
items := playroomCfg.GetDailyTaskReward(index)
quest, _ := quest.ParseQuest(v)
p.DailyTask[k] = &DailyTask{
Items: items,
Quest: quest,
UnLock: false,
Index: index,
}
index++
}
}
func (p *PlayroomMod) QuestTrigger(tr *quest.Trigger) bool {
update := false
unlock := true
for k, v := range p.DailyTask {
if !v.UnLock {
continue
}
if v.Status != quest.QUEST_STATUS_UNFINISH {
continue
}
update = quest.TriggerQuestProgress(&v.Quest, tr) || update
if v.Quest.Status {
v.Status = quest.QUEST_STATUS_FINISH
}
qType := playroomCfg.GetDailyTaskType(k)
if qType == DAILY_TASK_TYPE_ONE && v.Status == quest.QUEST_STATUS_UNFINISH {
unlock = false
}
}
if unlock {
for _, v := range p.DailyTask {
v.UnLock = true
}
}
return update
}
func (p *PlayroomMod) DailyTaskCanReward(id int) bool {
idList := playroomCfg.GetDailyTaskListById(id)
for _, v := range idList {
v, ok := p.DailyTask[v]
if !ok {
return false
}
if v.Status != quest.QUEST_STATUS_FINISH {
return false
}
}
return true
}
func (p *PlayroomMod) GetDailyTaskReward(id int) ([]*item.Item, error) {
v, ok := p.DailyTask[id]
if !ok {
return nil, fmt.Errorf("GetDailyTaskReward Id is not ok")
}
if v.Status != quest.QUEST_STATUS_FINISH {
return nil, fmt.Errorf("GetDailyTaskReward Status is not finish")
}
v.Status = quest.QUEST_STATUS_REWARD
return v.Items, nil
}
func (p *PlayroomMod) GetVisitor() map[int]*Info {
return p.Visitor
}
func (p *PlayroomMod) GetTarget() int {
return p.Target
}
func (p *PlayroomMod) GetHasVisit() map[int]int64 {
return p.HasVisit
}
func (p *PlayroomMod) GetTodayVisitedUsers() []int {
return p.TodayVisitedUsers
}
func (p *PlayroomMod) GetMood() map[int]int {
Mood := make(map[int]int)
for k, v := range p.MoodInfo {
Mood[k] = v.Num
}
return Mood
}
func (p *PlayroomMod) GetPhysiologyList() map[int]int {
Physiology := make(map[int]int)
for k, v := range p.Physiology {
Physiology[k] = v.Num
}
return Physiology
}
func (p *PlayroomMod) GetMoodInfo(id int) *Mood {
return p.MoodInfo[id]
}
func (p *PlayroomMod) GetPhysiology(id int) *Physiology {
return p.Physiology[id]
}
func (p *PlayroomMod) GetCollect() map[int]*CollectInfo {
return p.NewCollect
}
func (p *PlayroomMod) GetRoom() map[int]int {
return p.Room
}
func (p *PlayroomMod) GetStatus() int {
return p.Status
}
func (p *PlayroomMod) GetChip() int {
return len(p.ChipList)
}
func (p *PlayroomMod) AddChip(uid int, time int64, emoji int) {
if len(p.ChipList) >= playroomCfg.GetChipNum() {
return
}
p.ChipList = append(p.ChipList, &ChipInfo{Uid: uid, Time: time, Emoji: emoji})
p.RevengeUid = int64(uid)
}
func (p *PlayroomMod) SetTarget(target int) {
p.Target = target
p.Status = 1
p.HasVisit[target] = GoUtil.Now()
}
func (p *PlayroomMod) SetGameId(gameId int) {
p.GameId = gameId
}
func (p *PlayroomMod) CreateOrderReward(star int, itemMod *item.ItemMod) {
if star == 0 {
return
}
foodItem := playroomCfg.GetFoodItem()
cleanItem := playroomCfg.GetCleanItem()
toyItem := playroomCfg.GetToyItem()
dailyItem := playroomCfg.GetDailyItem()
foodItemNum := itemMod.GetItemNumByList(foodItem)
cleanItemNum := itemMod.GetItemNumByList(cleanItem)
toyItemNum := itemMod.GetItemNumByList(toyItem)
dailyItemNum := itemMod.GetItemNumByList(dailyItem)
type d struct {
Id []int
Num int
}
sortList := []d{
{Id: foodItem, Num: foodItemNum},
{Id: cleanItem, Num: cleanItemNum},
{Id: toyItem, Num: toyItemNum},
{Id: dailyItem, Num: dailyItemNum},
}
sort.Slice(sortList, func(i, j int) bool {
return sortList[i].Num < sortList[j].Num
})
prob := GoUtil.RandSlice(sortList[0].Id)
p.Reward = []*item.Item{{Id: prob, Num: 1}}
}
func (p *PlayroomMod) GetReward() []*item.Item {
return p.Reward
}
func (p *PlayroomMod) Interact(id, iType int) ([]*item.Item, int, error) {
moodType, items, effect := playroomCfg.GetInteract(id, iType)
if moodType == 0 {
return nil, 0, fmt.Errorf("Interact MoodType is 0")
}
if effect > 0 {
p.AllMood = min(100, p.AllMood+10)
}
pType, pEffect := playroomCfg.GetInteractPhysiology(id)
p.AddPhysiology(pType, pEffect)
p.AddMood(moodType, effect)
return items, pType, nil
}
func (p *PlayroomMod) AddInteractNum(lv int) {
unlock := playroomCfg.GetInteractUnlock()
if lv < unlock {
return
}
p.InteractNum++
p.InteractNum = min(p.InteractNum, playroomCfg.GetInteractNum())
}
func (p *PlayroomMod) AddMood(id, num int) {
_, ok := p.MoodInfo[id]
if !ok {
p.MoodInfo[id] = &Mood{Id: id}
}
p.MoodInfo[id].Num = max(0, min(p.MoodInfo[id].Num+num, 100))
if p.MoodInfo[id].Num != 0 && p.MoodInfo[id].Time == 0 {
p.MoodInfo[id].Time = GoUtil.Now()
}
if p.MoodInfo[id].Num == 0 {
p.MoodInfo[id].Time = 0
}
}
func (p *PlayroomMod) GetMoodNum(moodType int) int {
mood, ok := p.MoodInfo[moodType]
if !ok {
return 0
}
return mood.Num
}
func (p *PlayroomMod) AddPhysiology(id, num int) {
phy := p.GetPhysiology(id)
if phy == nil {
phy = &Physiology{Id: id}
p.Physiology[id] = phy
}
maxNum := playroomCfg.GetPhysiologyMax(id)
phy.Num = max(0, min(phy.Num+num, maxNum))
phy.Time = GoUtil.Now()
if phy.Num == 0 {
phy.Time = 0
}
}
func (p *PlayroomMod) AddVisitor(id int, time int64) {
v, ok := p.Visitor[id]
if !ok {
p.Visitor[id] = &Info{Time: time, Times: 1}
return
}
v.Times++
v.Time = time
}
func (p *PlayroomMod) SetRoom(room map[int]int) (map[int]int, error) {
diff := GoUtil.DiffMap(p.Room, room)
p.Room = room
return diff, nil
}
func (p *PlayroomMod) AddCollect(id int, label string) {
p.NewCollect[id] = &CollectInfo{
Id: id,
AddTime: GoUtil.Now(),
Label: label,
}
}
func (p *PlayroomMod) AddDress(id int, label string) {
part := playroomCfg.GetDressPart(id)
if _, ok := p.NewDress[id]; !ok {
p.NewDress[id] = &DressInfo{
Id: id,
Part: part,
AddTime: GoUtil.Now(),
Label: label,
Num: 1,
}
} else {
p.NewDress[id].Num++
}
}
func (p *PlayroomMod) ResetGame() {
p.TodayVisitedUsers = append(p.TodayVisitedUsers, p.Target)
p.Target = 0
p.Status = STATUS_IDLE
p.GameId = 0
p.GameReward = make(map[int]*item.Item)
p.InteractNum = 0
p.RevengeUid = 0
}
func (p *PlayroomMod) GetGameId() int {
return p.GameId
}
func (p *PlayroomMod) ResetLose() {
p.LoseItem = nil
}
func (p *PlayroomMod) SetGameReward(chess1, chess2, star int) {
p.GameReward[1] = &item.Item{Id: chess1, Num: 1}
p.GameReward[2] = &item.Item{Id: chess2, Num: 1}
p.GameReward[3] = &item.Item{Id: item.ITEM_STAR_ID, Num: star}
}
func (p *PlayroomMod) SetGameReward2(chess1, star int) {
p.GameReward[1] = &item.Item{Id: chess1, Num: 1}
p.GameReward[2] = &item.Item{Id: item.ITEM_STAR_ID, Num: star}
p.GameReward[3] = &item.Item{Id: item.ITEM_STAR_ID, Num: star}
}
func (p *PlayroomMod) SetGameReward3(star int) {
p.GameReward[1] = &item.Item{Id: item.ITEM_STAR_ID, Num: star}
p.GameReward[2] = &item.Item{Id: item.ITEM_STAR_ID, Num: star}
p.GameReward[3] = &item.Item{Id: item.ITEM_STAR_ID, Num: star}
}
// N1, N2, N3分别是铜、银、金翻牌的奖励数量经过玩家的加成后再设置到GameReward中
func (p *PlayroomMod) SetGameRewardFlip(n1, n2, n3 int) {
p.GameReward[1] = &item.Item{Id: item.ITEM_STAR_ID, Num: n1}
p.GameReward[2] = &item.Item{Id: item.ITEM_STAR_ID, Num: n2}
p.GameReward[3] = &item.Item{Id: item.ITEM_STAR_ID, Num: n3}
}
func (p *PlayroomMod) SelectReward(id int) []*item.Item {
v, ok := p.GameReward[id]
if !ok {
return nil
}
var items []*item.Item
items = append(items, v)
if id < 3 {
items = append(items, item.NewItem(item.ITEM_STAR_ID, 5))
}
return items
}
func (p *PlayroomMod) Lose(items []*item.Item) {
p.LoseItem = append(p.LoseItem, items...)
}
func (p *PlayroomMod) Work() ([]*item.Item, error) {
if p.Endtime > GoUtil.Now() {
p.WorkStatus = 1
return nil, nil
}
p.Starttime = GoUtil.Now()
p.Endtime = GoUtil.Now() + 86400
p.WorkStatus = 1
itemId := playroomCfg.GetWorkItem()
if itemId == 0 {
return nil, fmt.Errorf("Work ItemId is 0")
}
return []*item.Item{item.NewItem(itemId, 1)}, nil
}
func (p *PlayroomMod) Rest() {
p.WorkStatus = 2
}
func (p *PlayroomMod) SetWorkOutline(status int) {
p.WorkOutline = status
}
func (p *PlayroomMod) ResetWork() {
p.WorkStatus = 0
p.Endtime = 0
}
func (p *PlayroomMod) Outline() {
p.WorkOutline = 1
}
func (p *PlayroomMod) GetVisitorInfo(id int) (int, int64) {
v, ok := p.Visitor[id]
if !ok {
return 0, 0
}
return v.Times, v.Time
}
func (p *PlayroomMod) GetTaskReward(taskType int) (int, []*item.Item, error) {
if GoUtil.InArray(taskType, p.DailyTaskReward) {
return 0, nil, fmt.Errorf("GetTaskReward Type is already in DailyTaskReward")
}
finish := 0
for _, v := range p.DailyTask {
if v.Status >= quest.QUEST_STATUS_FINISH {
finish++
}
}
if taskType == DAILY_TASK_TYPE_ONE && finish < playroomCfg.GetPlayroomTaskDailyNum1() {
return 0, nil, fmt.Errorf("GetTaskReward Type is DAILY_TASK_TYPE_ONE but finish is %d", finish)
}
if taskType == DAILY_TASK_TYPE_TWO && finish < playroomCfg.GetPlayroomTaskDailyNum1()+playroomCfg.GetPlayroomTaskDailyNum2() {
return 0, nil, fmt.Errorf("GetTaskReward Type is DAILY_TASK_TYPE_TWO but finish is %d", finish)
}
p.DailyTaskReward = append(p.DailyTaskReward, taskType)
id := 0
var items []*item.Item
probList := playroomCfg.GetTaskJackpotProb()
id = GoUtil.RandMap(probList)
items = playroomCfg.GetTaskJackpotReward(id)
if len(items) > 1 {
// 多个奖励时,随机选择一个
items = []*item.Item{GoUtil.RandItem(items)}
}
return id, items, nil
}
func (p *PlayroomMod) Draw() (int, []*item.Item, error) {
if p.JackpotNum == 0 {
return 0, nil, fmt.Errorf("Draw JackpotNum is 0")
}
p.JackpotNum--
p.AllMood = 0
probList := limitedTimeEventCfg.GetSenceJackpotProb()
id := GoUtil.RandMap(probList)
items := limitedTimeEventCfg.GetSenceJackpotReward(id)
if len(items) > 1 {
// 多个奖励时,随机选择一个
items = []*item.Item{GoUtil.RandItem(items)}
}
return id, items, nil
}
func (p *PlayroomMod) NotifyWork() *msg.NotifyPlayroomWork {
return &msg.NotifyPlayroomWork{
WorkStatus: int32(p.WorkStatus),
StartTime: int32(p.Starttime),
}
}
func (p *PlayroomMod) NotifyLose() *msg.NotifyPlayroomLose {
chipMessage := make([]*msg.ChipInfo, 0, len(p.ChipList))
for _, v := range p.ChipList {
chipMessage = append(chipMessage, &msg.ChipInfo{
Uid: int64(v.Uid),
})
}
return &msg.NotifyPlayroomLose{
LoseItem: item.ItemToMsg(p.LoseItem),
Chip: chipMessage,
Revenge: p.RevengeUid,
}
}
func (p *PlayroomMod) ResetPhysiology(MoodType int) {
physiologyList := playroomCfg.GetPhysiologyList(MoodType)
for _, v := range physiologyList {
phy := p.GetPhysiology(v)
if phy != nil {
phy.Num = 0
phy.Time = 0
}
}
}
func (p *PlayroomMod) NotifyStatus() *msg.NofiPlayroomStatus {
return &msg.NofiPlayroomStatus{
WorkOutline: int32(p.WorkOutline),
}
}
func (p *PlayroomMod) NotifyMood() *msg.NotifyPlayroomMood {
mood := make(map[int32]int32)
for k, v := range p.MoodInfo {
mood[int32(k)] = int32(v.Num)
}
var resAdItems []*msg.AdItem
for k, v := range p.ADItem {
resAdItems = append(resAdItems, &msg.AdItem{
ItemId: int32(k),
Watch: int32(v.Watch),
LastWatch: int32(v.LastTime),
})
}
return &msg.NotifyPlayroomMood{
AllMood: int32(p.AllMood),
Mood: mood,
Physiology: GoUtil.MapIntToInt32(p.GetPhysiologyList()),
AdItem: resAdItems,
}
}
func (p *PlayroomMod) Fire(chargeId int) []*item.Item {
workChargeId := playroomCfg.GetWorkChargeId()
if chargeId == workChargeId {
itemId := playroomCfg.GetWorkItem()
return []*item.Item{item.NewItem(itemId, 1)}
}
return nil
}
func (p *PlayroomMod) RemoveChip(uids []int64) ([]*item.Item, int, error) {
len1 := len(p.ChipList)
len2 := len(uids)
if len1 == 0 {
return nil, 0, fmt.Errorf("RemoveChip Uids is 0")
}
if len1 == len2 {
p.ChipList = nil
} else {
uidCount := make(map[int64]int)
for _, uid := range uids {
uidCount[uid]++
}
var newChipList []*ChipInfo
for _, chip := range p.ChipList {
if uidCount[int64(chip.Uid)] > 0 {
uidCount[int64(chip.Uid)]--
} else {
newChipList = append(newChipList, chip)
}
}
p.ChipList = newChipList
}
return []*item.Item{item.NewItem(item.ITEM_STAR_ID, len2*25)}, len2, nil
}
func (p *PlayroomMod) FlipCard(pos int) (int, error) {
if p.Status != STATUS_VISIT {
return 0, fmt.Errorf("FlipCard Status is not STATUS_VISIT")
}
randMap := map[int]int{
FLIP_TYPE_COPPER: 35,
FLIP_TYPE_SILVER: 45,
FLIP_TYPE_GOLD: 20,
}
Prob := GoUtil.RandMap(randMap)
/**
若玩家同一天内上一次游玩猫猫小金库未能获得金币档位奖励,且当天还未获得过金币档位奖励
或玩家已连续三次未能获得金币档位奖励,则启用以下保底逻辑
玩家已翻出两个银币或铜币图案的情况下,后续翻牌必然为金币
*/
check := make(map[int]int)
for _, v := range p.Flip {
check[v]++
}
if check[FLIP_TYPE_COPPER] == 2 || check[FLIP_TYPE_SILVER] == 2 {
if p.LastFlip != FLIP_TYPE_GOLD && !p.TodayFlip {
Prob = FLIP_TYPE_GOLD
}
if p.NoFlip == 3 {
Prob = FLIP_TYPE_GOLD
}
}
p.Flip[pos] = Prob
return Prob, nil
}
func (p *PlayroomMod) GetFlipReward() ([]*item.Item, int, int, error) {
check := make(map[int]int)
var items []*item.Item
target := p.Target
result := FLIP_TYPE_COPPER
for _, v := range p.Flip {
check[v]++
if check[v] == 3 {
switch v {
case FLIP_TYPE_COPPER:
p.NoFlip++
items = append(items, p.GameReward[FLIP_TYPE_COPPER])
case FLIP_TYPE_SILVER:
p.NoFlip++
result = FLIP_TYPE_SILVER
items = append(items, p.GameReward[FLIP_TYPE_SILVER])
case FLIP_TYPE_GOLD:
p.NoFlip = 0
p.TodayFlip = true
result = FLIP_TYPE_GOLD
items = append(items, p.GameReward[FLIP_TYPE_GOLD])
}
p.LastFlip = v
p.Flip = make(map[int]int)
p.ResetGame()
return items, target, result, nil
}
}
return items, target, result, fmt.Errorf("GetFlipReward check is not 3")
}
func (p *PlayroomMod) BuyItem(id int) ([]*item.Item, []*item.Item) {
return playroomCfg.GetBuyItem(id)
}
func (p *PlayroomMod) UnLock(lv int) bool {
UnlockLv := playroomCfg.GetUnLockLv()
if lv < UnlockLv || len(p.Physiology) != 0 {
return false
}
now := GoUtil.Now()
p.Physiology = make(map[int]*Physiology)
typeList := playroomCfg.GetPhysiologyTypeList()
for _, v := range typeList {
max := playroomCfg.GetPhysiologyMax(v)
p.Physiology[v] = &Physiology{Id: v, Num: max, Time: now}
}
if len(p.MoodInfo) == 0 {
p.MoodInfo = make(map[int]*Mood)
for k := 1; k <= 3; k++ {
p.MoodInfo[k] = &Mood{Id: k, Num: 100}
}
}
return true
}
func (p *PlayroomMod) FixUnLock(lv int) bool {
unlockLv := playroomCfg.GetUnLockLv()
if lv < unlockLv || len(p.Physiology) != 0 {
return false
}
now := GoUtil.Now()
p.Physiology = make(map[int]*Physiology)
typeList := playroomCfg.GetPhysiologyTypeList()
for _, v := range typeList {
max := playroomCfg.GetPhysiologyMax(v)
p.Physiology[v] = &Physiology{Id: v, Num: max, Time: now}
}
if len(p.MoodInfo) == 0 {
p.MoodInfo = make(map[int]*Mood)
for k := 1; k <= 3; k++ {
p.MoodInfo[k] = &Mood{Id: k, Num: 100}
}
}
return true
}
// shop
func (p *PlayroomMod) ShopBuy(id, num int, weeklyDiscount bool) ([]*item.Item, []*item.Item, error) {
addItemId, costItem, discount, limit := playroomCfg.GetShopItem(id)
if addItemId == 0 {
return nil, nil, fmt.Errorf("ShopBuy AddItemId is 0")
}
if costItem == nil || len(costItem) == 0 {
return nil, nil, fmt.Errorf("ShopBuy CostItem is nil or length is 0")
}
newCostItem := costItem[0].Num * num
if weeklyDiscount {
limitNum := p.WeeklyDiscount[id]
if limitNum < limit {
newCostItem = int(math.Ceil(float64(newCostItem) * float64(discount) / 100))
}
p.WeeklyDiscount[id] = limitNum + num
}
costItem[0].Num = newCostItem
return []*item.Item{item.NewItem(addItemId, num)}, costItem, nil
}
func (p *PlayroomMod) UnlockDress(dType, id int) error {
p.NewDress[id] = &DressInfo{
Id: id,
Part: dType,
AddTime: GoUtil.Now(),
Num: 1,
}
return nil
}
func (p *PlayroomMod) RandGameType() int {
return GoUtil.RandMap(map[int]int{1: 50, 3: 50})
}
func (p *PlayroomMod) UnlockPetAir(id int) {
p.NewPetAir[id] = &PetAirInfo{
Id: id,
AddTime: GoUtil.Now(),
Num: 1,
}
}
func (p *PlayroomMod) PlayroomDressSet(dressSet map[int]int) ([]int, map[int]int, error) {
// 判断服装是否存在
var Part []int
diff := GoUtil.DiffMap(dressSet, p.DressSet)
for dType, id := range dressSet {
if id == 0 {
continue
}
dressInfo, ok := p.NewDress[id]
if !ok {
return nil, nil, fmt.Errorf("dress Id not found")
}
if dressInfo.EndTime < GoUtil.Now() && dressInfo.EndTime != 0 {
return nil, nil, fmt.Errorf("dress timeout")
}
if p.DressSet[dType] != id && id != 0 {
Part = append(Part, dType)
}
}
p.DressSet = dressSet
return Part, diff, nil
}
func (p *PlayroomMod) GiveUpvote(uid int) ([]*item.Item, error) {
if GoUtil.InArray(uid, p.UpvoteList) {
return nil, fmt.Errorf("upvote already")
}
p.UpvoteList = append(p.UpvoteList, uid)
return []*item.Item{item.NewItem(item.ITEM_ENERGY_ID, 5)}, nil
}
func (p *PlayroomMod) AddUpvote() {
p.Upvote++
}
func (p *PlayroomMod) PlayroomPetAirSet(id int) error {
if _, ok := p.NewPetAir[id]; !ok {
return fmt.Errorf("PlayroomPetAirSet Id is not ok")
}
p.PetAirSet = id
return nil
}
func (p *PlayroomMod) Unlock(id int) error {
need := playroomCfg.GetUnlockNeed(id)
if need == 0 || need > p.RoomPoint {
return fmt.Errorf("unlock need is 0 or need > RoomPoint")
}
p.UnlockList[id] = GoUtil.Now()
return nil
}
func (p *PlayroomMod) GetUnlockIds() []int32 {
unlockIds := make([]int32, 0, len(p.UnlockList))
for k := range p.UnlockList {
unlockIds = append(unlockIds, int32(k))
}
return unlockIds
}
func (p *PlayroomMod) GetDressSet() map[int]int {
return p.DressSet
}
func (p *PlayroomMod) GetPetAirSet() int {
return p.PetAirSet
}
func (p *PlayroomMod) GetDress() map[int]*DressInfo {
return p.NewDress
}
func (p *PlayroomMod) GetPetAir() map[int]*PetAirInfo {
return p.NewPetAir
}
func (p *PlayroomMod) BackDataTask() []*msg.DailyTask {
dailyTask := make([]*msg.DailyTask, 0, len(p.DailyTask))
for k, v := range p.DailyTask {
dailyTask = append(dailyTask, &msg.DailyTask{
Status: int32(v.Status),
UnLock: v.UnLock,
Progress: quest.QuestProgressToMsg(&v.Quest),
Items: item.ItemToMsg(v.Items),
Index: int32(v.Index),
Id: int32(k),
})
}
sort.Slice(dailyTask, func(i, j int) bool {
return dailyTask[i].Index < dailyTask[j].Index
})
return dailyTask
}
func (p *PlayroomMod) Guide(Type int) error {
if _, ok := p.Physiology[Type]; !ok {
return fmt.Errorf("Guide Type is not ok")
}
p.Physiology[Type].Num = 0
return nil
}
func (p *PlayroomMod) AdWatch(Id int) error {
if _, ok := p.ADItem[Id]; !ok {
p.ADItem[Id] = &ItemInfo{}
}
p.ADItem[Id].Watch++
p.ADItem[Id].LastTime = GoUtil.Now()
if p.ADItem[Id].Watch > playroomCfg.GetShopItemAdNum(Id) {
return fmt.Errorf("AdWatch Watch is over limit")
}
return nil
}
func (p *PlayroomMod) ResetWeeklyDiscount() {
p.WeeklyDiscount = make(map[int]int)
}