package mapLogic import ( capp "f1-game/internal/cherry_app" "f1-game/internal/data" "f1-game/internal/enum" mapCall "f1-game/nodes/map/internal/call" "f1-game/nodes/map/internal/db" clog "github.com/cherry-game/cherry/logger" ) func (p *actor) initMonster() { // 补充怪物 for _, monsterFlush := range p.MonsterFlushTables { var save bool monsterFlush.FlushLimit.Range(func(monsterConfigID int32, limit int32) bool { currCount := monsterFlush.GetMonsterCount(monsterConfigID) if currCount >= limit { return true } monsterRow, ok := data.MapMonster.GetByConfigID(monsterConfigID) if !ok { clog.Errorf("[initMonster] AreaID = %v, MonsterID = %v is invalid.", monsterFlush.AreaID, monsterConfigID) return true } // 需要补充多少个怪物 for i := currCount; i < limit; i++ { monsterTable := db.NewLogicMonsterTable(db.NewGUID(), capp.NodeID(), 0, 0, monsterConfigID, monsterFlush.AreaID) monsterTable.Save2Queue() // 拷贝属性 monsterTable.LoadConfig(monsterRow) p.MonsterTables.Put(monsterTable.ObjectID, monsterTable) monsterFlush.FlushCount[monsterTable.ConfigID]++ } save = true return true }) if save { monsterFlush.Save2Queue() } } } func (p *actor) monsterTimer() { p.updateTime() for _, monsterTable := range p.MonsterTables { p.monsterTicker(monsterTable) if monsterTable.IsDataChanged { monsterTable.IsDataChanged = false monsterTable.Save2Queue() } } } func (p *actor) monsterTicker(monsterTable *db.LogicMonsterTable) { if monsterTable.IsDelete { p.monsterInvalid(monsterTable) return } if monsterTable.CheckFlush(p.nowMillis) { p.monsterFlush(monsterTable) } } func (p *actor) monsterInvalid(monsterTable *db.LogicMonsterTable) { p.removeMonster(monsterTable) monsterTable.IsDelete = true monsterTable.IsDataChanged = true // 清理地块 tileTable := p.TileTables.GetValue(monsterTable.GetTileID()) tileTable.SetMonsterObjectID(0) p.addTileProcess(tileTable) } // monsterFlush 怪物刷新 func (p *actor) monsterFlush(monsterTable *db.LogicMonsterTable) { if monsterTable.IsAlive { oldTileTable := p.TileTables.GetValue(monsterTable.GetTileID()) oldTileTable.SetMonsterObjectID(0) // 离开aoi mapCall.AOI.Leave(monsterTable.ObjectID, enum.ObjectType_Monster) } monsterArea := p.MonsterFlushTables.GetValue(monsterTable.AreaID) point, ok := monsterArea.RandomPoint() if !ok { // 无法生成坐标,删除该资源点 clog.Warnf("[monsterFlush] AreaID = %v, MonsterID = %v Point is invalid.", monsterArea.AreaID, monsterTable.ObjectID) // p.removeMonster(monsterTable) monsterTable.IsDelete = true monsterTable.IsDataChanged = true return } // 重置怪物 monsterTable.ResetByFlush(point.X, point.Y, p.now) // 添加坐标到过滤列表 monsterArea.AddFilterPoint(point.X, point.Y) // 对象进入AOI p.addMonsterAOI(monsterTable) // 存放到 tileTable tileTable := p.TileTables.GetValue(monsterTable.GetTileID()) tileTable.SetMonsterObjectID(monsterTable.ObjectID) p.addTileProcess(tileTable) monsterTable.IsDataChanged = true } func (p *actor) monsterDead(monsterTable *db.LogicMonsterTable) { // 移除忽略的怪物刷新点 p.removeMonsterAreaIDFileterPoint(monsterTable.AreaID, monsterTable.X(), monsterTable.Y()) // 重置属性 monsterTable.ResetByDead() // 怪物对象离开地图 mapCall.AOI.Leave(monsterTable.ObjectID, monsterTable.Type) // 清理地块 tileTable := p.TileTables.GetValue(monsterTable.GetTileID()) tileTable.SetMonsterObjectID(0) p.addTileProcess(tileTable) } func (p *actor) removeMonster(monsterTable *db.LogicMonsterTable) { p.MonsterTables.Remove(monsterTable.ObjectID) if area, ok := p.MonsterFlushTables.Get(monsterTable.AreaID); ok { area.RemoveFilterPoint(monsterTable.X(), monsterTable.Y()) area.Save2Queue() } } func (p *actor) addMonsterAreaFilterPoint(x, y int32) { area := p.getMonsterAreaByPoint(x, y) if area != nil { area.AddFilterPoint(x, y) area.Save2Queue() } } func (p *actor) getMonsterAreaByPoint(x, y int32) *db.LogicMonsterFlushTable { for _, area := range p.MonsterFlushTables { if area.ContainsPoint(x, y) { return area } } return nil } func (p *actor) addMonsterAOI(monsterTable *db.LogicMonsterTable) { marker := monsterTable.ToAOIMarker() mapCall.AOI.Enter(marker) } func (p *actor) removeMonsterAreaIDFileterPoint(areaID int32, x, y int32) { if area, ok := p.MonsterFlushTables.Get(areaID); ok { area.RemoveFilterPoint(x, y) area.Save2Queue() } }