rolePlugin.go 8.16 KB
package models

import (
	"fmt"
	"github.com/golang/protobuf/proto"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo/options"
	"math"
	"pro2d/common"
	"pro2d/common/db/mongoproxy"
	"pro2d/common/logger"
	"pro2d/csvdata"
	"pro2d/pb"
	"strconv"
)

// GetItemCount 背包系统
func (m *RoleModel) GetItemCount(key string) int32 {
	c, ok := m.Items[key]
	if !ok {
		c = int32(0)
	}
	return c
}

func (m *RoleModel) CostItem(key string, count int32, param *pb.LogConf) bool {
	if count > m.GetItemCount(key) {
		return false
	}
	return m.AddItem(key, -count, param)
}

func (m *RoleModel) CostItems(params common.IMapStringNum, logconf *pb.LogConf) bool {
	for k, v := range params {
		if v > m.GetItemCount(k) {
			return false
		}

		params[k] = -v
	}

	return m.AddItems(params, logconf)
}

func (m *RoleModel) AddItem(key string, count int32, param *pb.LogConf) bool {
	c := m.GetItemCount(key)

	num := c + count
	if num > 0 {
		m.Items[key] = num
	} else {
		delete(m.Items, key)
		num = 0
	}
	m.SetProperty("items", common.MapNumToString(m.Items))

	id, _ := strconv.Atoi(key)
	param.Cint1 = int64(id)
	param.Cint2 = int64(math.Abs(float64(count)))
	param.Cint3 = int64(num)
	if count < 0 {
		m.MyLog("out_item", param)
	} else {
		m.MyLog("in_item", param)
	}

	rsp, err := proto.Marshal(&pb.RoleUpdateItemsNty{Items: fmt.Sprintf("%s=%d", key, num)})
	if err != nil {
		logger.Error(err.Error())
		return true
	}

	if m.GetConn() != nil {
		m.GetConn().Send(0, uint32(pb.ProtoCode_RoleUpdateItemsNty), rsp, 0)
	}
	return true
}

func (m *RoleModel) AddItems(params common.IMapStringNum, logconf *pb.LogConf) bool {
	tmp := make(common.IMapString)
	for k, v := range params {
		c := m.GetItemCount(k)

		num := c + v
		if num > 0 {
			m.Items[k] = num
		} else {
			num = 0
			delete(m.Items, k)
		}
		tmp[k] = num

		id, _ := strconv.Atoi(k)
		logconf.Cint1 = int64(id)
		logconf.Cint2 = int64(math.Abs(float64(v)))
		logconf.Cint3 = int64(num)
		if v < 0 {
			m.MyLog("out_item", logconf)
		} else {
			m.MyLog("in_item", logconf)
		}
	}

	m.SetProperty("items", common.MapNumToString(m.Items))

	rsp, err := proto.Marshal(&pb.RoleUpdateItemsNty{Items: common.MapToString(tmp)})
	if err != nil {
		logger.Error(err.Error())
		return true
	}

	if m.GetConn() != nil {
		m.GetConn().Send(0, uint32(pb.ProtoCode_RoleUpdateItemsNty), rsp, 0)
	}

	return true
}

func (m *RoleModel) AddHero(hero *pb.Hero) {
	h := NewHero(hero)
	h.Create()
	m.Heros[hero.Id] = h
}

func (m *RoleModel) AddTeam(team *pb.Team) {
	t := NewTeam(team)
	t.Create()
	m.Teams[team.Id] = t
}

func (m *RoleModel) UpdateTeam(teams []*pb.Team) {
	for _, team := range teams {
		team.RoleId = m.Data.Id
		t := m.Teams[team.Id]
		if t != nil {
			t.UpdateSchema(team)
		}
	}
}

func (m *RoleModel) AddEquip(equip *pb.Equipment, conf *pb.LogConf) *EquipModel {
	e := NewEquip(equip)
	e.Create()
	m.Equipments[equip.Id] = e

	conf.Int1 = e.Data.Id
	conf.Int2 = string(e.Data.Pos)
	conf.Cint1 = 1
	m.MyLog("in_equip", conf)
	m.EquipmentAddNotify(equip)
	return e
}

func (m *RoleModel) EquipmentAddNotify(equip *pb.Equipment) {
	update := &pb.EquipmentAddNty{Equip: equip}
	if rsp, err := proto.Marshal(update); err != nil {
		logger.Error(" EquipmentAddNotify  err:", err.Error())
		return
	} else {
		if m.GetConn() != nil {
			m.GetConn().SendSuccess(uint32(pb.ProtoCode_EquipmentAddNty), rsp, 0)
		}
	}
}

func (m *RoleModel) UpLevel(exp int32) (int32, int32) {
	exp = exp + m.Data.Exp
	level := m.Data.Level
	oldLevelExp := csvdata.Get().TbAccountLevelExp.Get(level)
	if oldLevelExp == nil {
		return level, exp
	}

	for exp > 0 {
		if exp >= oldLevelExp.NeedExp {
			exp = exp - oldLevelExp.NeedExp
			level++
		} else {
			break
		}
		oldLevelExp = csvdata.Get().TbAccountLevelExp.Get(level)
		if oldLevelExp == nil {
			return level, exp
		}
	}
	return level, exp
}

func (m *RoleModel) _award(itemId string, count int32, param *pb.LogConf) int32 {
	id, err := strconv.Atoi(itemId)
	if err != nil {
		return 0
	}
	itemData := csvdata.Get().TbItemData.Get(int32(id))
	if itemData == nil {
		return 0
	}

	curType := itemData.MType

	switch curType {
	case common.EquipType:
		equip := &pb.Equipment{
			Id:      m.IncreEquipByKey(1),
			RoleId:  m.Data.Id,
			TbId:    int32(id - common.ItemTypeInterval),
			Quality: 1,
		}
		m.AddEquip(equip, param)
	default:
		m.AddItem(itemId, count, param)
	}
	return count
}

func (m *RoleModel) Award(award common.IMapStringNum, param *pb.LogConf) common.IMapStringNum {
	reward := make(common.IMapStringNum)
	for itemId, rcount := range award {
		count := m._award(itemId, rcount, param)
		if count > 0 {
			reward[itemId] = count
		}
	}
	m.Update()
	return reward
}

func (m *RoleModel) EquipmentRefer(equipId, heroId string, refer bool, pos int32) int32 {
	e, ok := m.Equipments[equipId]
	if !ok {
		return 2
	}

	equip := e.(*EquipModel)

	// 1 脱
	// 1.1 装备直接脱掉
	// 2 戴
	// 2.0.1 如果是戒指,特殊处理, 未被其他英雄穿戴直接穿,同位置装备是否穿戴, 已经被穿戴,则脱了再穿
	// 2.0.2 如果是戒指,特殊处理, 如果其他英雄已经被穿戴,则脱了再穿, 同位置装备是否穿戴, 已经被穿戴,则脱了再穿
	// 2.1.1 如果不是戒指,未被其他英雄穿戴直接穿,同位置装备是否穿戴, 已经被穿戴,则脱了再穿
	// 2.1.2 如果不是戒指,如果其他英雄已经被穿戴,则脱了再穿, 同位置装备是否穿戴, 已经被穿戴,则脱了再穿
	// 可以合并。不用判断是否是戒指。
	h1 := m.Heros[heroId]
	h2 := m.Heros[equip.Data.HeroId]

	var outHero, inHero *HeroModel
	inEquip := csvdata.Get().TbEquipmentData.Get(equip.Data.GetTbId())
	if !refer {
		if h1 != nil {
			outHero = h1.(*HeroModel)
			outHero.DelEquipment(equip.Data.Id)
		}
		if h2 != nil {
			outHero = h2.(*HeroModel)
			outHero.DelEquipment(equip.Data.Id)
		}
		equip.SetProperty("heroid", "")

	} else {
		if h1 == nil {
			return 3
		}
		inHero = h1.(*HeroModel)

		if common.EquipmentTyp(inEquip.EquipType) == common.Ring {
			if pos != common.RingPosL && pos != common.RingPosR {
				return 4
			}
		}
		// 2.1.1
		if equip.Data.HeroId == "" {
			var outEquipID string
			for id, typ := range inHero.Equipments {
				if typ == pos {
					outEquipID = id
					break
				}
			}
			if outEquipID != "" {
				tmpEuqip, ok := m.Equipments[outEquipID]
				if ok {
					outEquip := tmpEuqip.(*EquipModel)
					outEquip.SetProperty("heroid", "")
					inHero.DelEquipment(outEquipID)
				}
			}

			inHero.AddEquipment(equip.Data.Id, pos)
			equip.SetProperty("heroid", inHero.Data.Id)
			equip.SetProperty("pos", pos)
		} else {
			if h2 == nil {
				return 4
			}
			// 2.1.2
			outHero = h2.(*HeroModel)
			var outEquipID string
			for id, tpos := range inHero.Equipments {
				if tpos == pos {
					outEquipID = id
					break
				}
			}

			if outEquipID != "" {
				tmpEquip, ok := m.Equipments[outEquipID]
				if ok {
					outEquip := tmpEquip.(*EquipModel)
					outEquip.SetProperty("heroid", "")
					inHero.DelEquipment(outEquipID)
				}
			}

			outHero.DelEquipment(equip.Data.Id)
			inHero.AddEquipment(equip.Data.Id, pos)
			equip.SetProperty("heroid", inHero.Data.Id)
			equip.SetProperty("pos", pos)
		}

	}
	return 0
}

func (m *RoleModel) DelExpireEmail() error {
	filter := bson.D{{"roleid", m.Data.Id}}
	sort := bson.D{
		{"createtime", -1},
	}

	var limit int64 = 10000
	var skip int64 = EMAIL_LIMIT
	//查询条件
	opts := &options.FindOptions{
		Sort:  sort,
		Limit: &limit,
		Skip:  &skip,
	}
	emails := make([]*pb.Email, EMAIL_LIMIT)
	err := mongoproxy.FindManyFilter("email", filter, opts, &emails)
	if err != nil {
		return err
	}

	var ids []string
	for _, email := range emails {
		ids = append(ids, email.Id)
	}

	filter = append(filter, bson.E{"id", bson.D{{"$in", ids}}})
	err = mongoproxy.DelMany("email", filter)
	if err != nil {
		return err
	}

	return nil
}

func (m *RoleModel) LoadEmails() []*pb.Email {
	//filter := bson.D{{"roleid", m.Data.Id}}
	//sort := bson.D{
	//	{"createtime", -1},
	//}

	//var limit int64 = EMAIL_LIMIT
	////查询条件
	//opts := &options.FindOptions{
	//	Sort:  sort,
	//	Limit: &limit,
	//}
	emails := make([]*pb.Email, EMAIL_LIMIT)
	err := mongoproxy.FindMany("email", "roleid", m.Data.Id, &emails)
	if err != nil {
		return nil
	}
	return emails
}