pet_home_server/src/server/game/mod/playroom/playroom.go
2025-03-26 09:48:02 +08:00

625 lines
15 KiB
Go

package playroom
import (
"fmt"
"math"
"server/GoUtil"
limitedTimeEventCfg "server/conf/limitedTimeEvent"
playroomCfg "server/conf/playroom"
"server/game/mod/item"
"server/msg"
)
type PlayroomMod struct {
Collect map[int]int // 装饰
Room map[int]int // 房间
Dress map[int][]int // 服装仓库
DressSet map[int]int // 服装穿戴
PetAir []int // 宠物空气背包
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 // 失去的物品
Chip int // 碎片
Flip map[int]int // 翻牌
FlipReward []*item.Item // 翻牌奖励
WorkOutline int // 是否离线
LastFlip int // 上次翻牌奖励档次
NoFlip int // 连续未获取最高翻牌奖励次数
TodayFlip bool // 今日是否已获得最高档奖励
JackpotNum int // 每日转盘数量
Physiology map[int]*Physiology
}
const (
STATUS_IDLE = 0 // 未开始
STATUS_VISIT = 1 // 拜访
MOOD_TYPE_ENTER = 1 // 娱乐
MOOD_TYPE_FOOD = 2 // 食物
MOOD_TYPE_CLEAN = 3 // 清洁
MOOD_TYPE_TAKE = 4 // 照料
MOOD_TYPE_PLAY = 5 // 玩耍
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 // 捉迷藏
)
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{})
}
InitCollect := playroomCfg.GetInitDecorate()
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.Reward == nil {
p.Reward = make([]*item.Item, 0)
}
if p.HasVisit == nil {
p.HasVisit = make(map[int]int64)
}
if p.GameReward == nil {
p.GameReward = make(map[int]*item.Item)
}
if p.LoseItem == nil {
p.LoseItem = make([]*item.Item, 0)
}
if p.Flip == nil {
p.Flip = make(map[int]int)
}
}
func (p *PlayroomMod) ZeroUpdate() {
p.TodayFlip = false
p.LastFlip = 0
p.JackpotNum = playroomCfg.GetJackpotNum()
}
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) 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]int {
return p.Collect
}
func (p *PlayroomMod) GetRoom() map[int]int {
return p.Room
}
func (p *PlayroomMod) GetStatus() int {
return p.Status
}
func (p *PlayroomMod) GetChip() int {
return p.Chip
}
func (p *PlayroomMod) AddChip() {
p.Chip = min(p.Chip+1, 5)
}
func (p *PlayroomMod) SetTarget(Target int) {
p.Target = Target
p.Status = 1
p.HasVisit[Target] = GoUtil.Now()
}
func (p *PlayroomMod) SetGameId(GameId int) {
if (p.GameId == GAME_TYPE_HOOK || p.GameId == GAME_TYPE_HIDE) && GameId == GAME_TYPE_HOOK {
return
}
p.GameId = GameId
}
func (p *PlayroomMod) CreateOrderReward(Star int, itemMod *item.ItemMod) {
if Star == 0 {
return
}
p.Reward = make([]*item.Item, 0)
NormalFoodId, NormalCleanId := playroomCfg.GetNormalItem()
PremiumFoodId, PremiumCleanId := playroomCfg.GetPremiumItem()
NormalFoodNum := itemMod.GetItem(NormalFoodId)
NormalCleanNum := itemMod.GetItem(NormalCleanId)
PremiumFoodNum := itemMod.GetItem(PremiumFoodId)
PremiumCleanNum := itemMod.GetItem(PremiumCleanId)
p.TriggerTime = GoUtil.Now()
if NormalFoodNum == 0 {
p.Reward = append(p.Reward, &item.Item{Id: NormalFoodId, Num: 1})
return
}
if NormalCleanNum == 0 {
p.Reward = append(p.Reward, &item.Item{Id: NormalCleanId, Num: 1})
return
}
if PremiumFoodNum == 0 {
p.Reward = append(p.Reward, &item.Item{Id: PremiumFoodId, Num: 1})
return
}
if PremiumCleanNum == 0 {
p.Reward = append(p.Reward, &item.Item{Id: PremiumCleanId, Num: 1})
return
}
var RandSlice []int
if math.Abs(float64((NormalCleanNum+PremiumCleanNum)-(NormalFoodNum+PremiumFoodNum))) > 3 {
RandSlice := GoUtil.IfTrue((NormalCleanNum+PremiumCleanNum) > (NormalFoodNum+PremiumFoodNum), []int{PremiumCleanId, NormalCleanId}, []int{NormalFoodId, PremiumFoodId}).([]int)
Prob := GoUtil.RandSlice(RandSlice)
p.Reward = append(p.Reward, &item.Item{Id: Prob, Num: 1})
return
}
RandSlice = []int{NormalFoodId, NormalCleanId, PremiumFoodId, PremiumCleanId}
Prob := GoUtil.RandSlice(RandSlice)
p.Reward = append(p.Reward, &item.Item{Id: Prob, Num: 1})
}
func (p *PlayroomMod) GetReward() []*item.Item {
return p.Reward
}
func (p *PlayroomMod) Interact(Id, Type int) ([]*item.Item, int, error) {
MoodType, ItemList, Effect := playroomCfg.GetInteract(Id, Type)
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 ItemList, MoodType, nil
}
func (p *PlayroomMod) AddMood(Id, Num int) {
_, ok := p.MoodInfo[Id]
if !ok {
p.MoodInfo[Id] = &Mood{Id: Id, Num: 0}
}
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) AddPhysiology(Id, Num int) {
Phy := p.GetPhysiology(Id)
if Phy == nil {
Phy = &Physiology{Id: Id, Num: 0, Time: 0}
}
Max := playroomCfg.GetPhysiologyMax(Id)
Phy.Num = max(0, min(Phy.Num+Num, Max))
if Phy.Num != 0 && Phy.Time == 0 {
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) error {
p.Room = Room
return nil
}
func (p *PlayroomMod) AddCollect(Id int) {
p.Collect[Id]++
}
func (p *PlayroomMod) ResetGame() {
p.Target = 0
p.Status = 0
p.GameId = 0
p.GameReward = make(map[int]*item.Item)
}
func (p *PlayroomMod) ResetLose() {
p.LoseItem = make([]*item.Item, 0)
}
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) 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
}
return []*item.Item{v}
}
func (p *PlayroomMod) Lose(Item []*item.Item) {
p.LoseItem = append(p.LoseItem, Item...)
}
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()
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) Draw() (int, []*item.Item, error) {
// if p.AllMood < 100 {
// return 0, nil, fmt.Errorf("Draw AllMood < 100")
// }
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)
return Id, limitedTimeEventCfg.GetSenceJackpotReward(Id), nil
}
func (p *PlayroomMod) NotifyWork() *msg.NotifyPlayroomWork {
return &msg.NotifyPlayroomWork{
WorkStatus: int32(p.WorkStatus),
StartTime: int32(p.Starttime),
}
}
func (p *PlayroomMod) NotifyLose() *msg.NotifyPlayroomLose {
return &msg.NotifyPlayroomLose{
LoseItem: item.ItemToMsg(p.LoseItem),
Chip: int32(p.Chip),
}
}
func (p *PlayroomMod) NotifyStatus() *msg.NofiPlayroomStatus {
return &msg.NofiPlayroomStatus{
WorkOutline: int32(p.WorkOutline),
}
}
func (p *PlayroomMod) NotifyMood() *msg.NotifyPlayroomMood {
Mood := make(map[int32]int32, 0)
for k, v := range p.MoodInfo {
Mood[int32(k)] = int32(v.Num)
}
return &msg.NotifyPlayroomMood{
AllMood: int32(p.AllMood),
Mood: Mood,
Physiology: GoUtil.MapIntToInt32(p.GetPhysiologyList()),
}
}
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(Num int) []*item.Item {
Num = min(Num, p.Chip)
p.Chip -= Num
return []*item.Item{item.NewItem(item.ITEM_STAR_ID, Num*50)}
}
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, error) {
check := make(map[int]int)
Items := make([]*item.Item, 0)
T := p.Target
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++
Items = append(Items, p.GameReward[FLIP_TYPE_SILVER])
case FLIP_TYPE_GOLD:
p.NoFlip = 0
p.TodayFlip = true
Items = append(Items, p.GameReward[FLIP_TYPE_GOLD])
}
p.LastFlip = v
p.Status = STATUS_IDLE
p.GameId = 0
p.Flip = make(map[int]int)
p.Target = 0
return Items, T, nil
}
}
return Items, T, 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) {
UnlockLv := playroomCfg.GetUnLockLv()
if Lv < UnlockLv {
return
}
if len(p.Physiology) == 0 {
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}
}
}
if len(p.Dress) == 0 {
p.Dress = make(map[int][]int)
InitDressList := playroomCfg.GetInitDressList()
for _, v := range InitDressList {
Part := playroomCfg.GetDressPart(v)
p.Dress[Part] = append(p.Dress[Part], v)
}
}
if len(p.PetAir) == 0 {
p.PetAir = make([]int, 0)
InitPetAir := playroomCfg.GetInitAirList()
p.PetAir = append(p.PetAir, InitPetAir...)
}
}
// shop
func (p *PlayroomMod) ShopBuy(Id, Num int) ([]*item.Item, []*item.Item, error) {
AddItemId, CostItem := playroomCfg.GetShopItem(Id)
if AddItemId == 0 {
return nil, nil, fmt.Errorf("ShopBuy AddItemId is 0")
}
NewCostItem := item.MutilItem(CostItem, Num)
return []*item.Item{item.NewItem(AddItemId, Num)}, NewCostItem, nil
}
func (p *PlayroomMod) UnlockDress(Type, Id int) error {
_, ok := p.Dress[Type]
if !ok {
p.Dress[Type] = make([]int, 0)
}
p.Dress[Type] = append(p.Dress[Type], Id)
return nil
}
func (p *PlayroomMod) UnlockPetAir(Id int) {
p.PetAir = append(p.PetAir, Id)
}
func (p *PlayroomMod) PlayroomDressSet(DressSet map[int]int) error {
// 判断服装是否存在
for Type, Id := range DressSet {
dresses, ok := p.Dress[Type]
if Id == 0 {
continue
}
if !ok {
return fmt.Errorf("dress type not found")
}
if !GoUtil.InArray(Id, dresses) {
return fmt.Errorf("dress not found")
}
}
p.DressSet = DressSet
return nil
}
func (p *PlayroomMod) PlayroomPetAirSet(Id int) error {
if !GoUtil.InArray(Id, p.PetAir) {
return fmt.Errorf("pet air not found")
}
p.PetAirSet = Id
return nil
}
func (p *PlayroomMod) GetDressSet() map[int]int {
return p.DressSet
}
func (p *PlayroomMod) GetPetAirSet() int {
return p.PetAirSet
}
func (p *PlayroomMod) GetDress() map[int][]int {
return p.Dress
}
func (p *PlayroomMod) GetPetAir() []int {
return p.PetAir
}