| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350 |
- --------------------------------------------------------
- -- obj.ownerUuid 存在的话,只有指定人能看到
- --------------------------------------------------------
- local Util = require("common.Util")
- local Timer = require("core.Timer")
- local Msg = require("core.Msg")
- local ObjHuman = require("core.ObjHuman")
- TYPE_HUMAN = 1
- TYPE_COLLECT = 2
- objs = objs or {} -- obj_id转换成对象
- scenes = scenes or {} -- 所有的场景 [sceneID][objId] = obj
- scenes_fds = scenes_fds or {} -- 场景fd [sceneID][fd] = obj
- local q_cap = 65536
- local function q_push(id)
- if q_b + 1 == q_f or q_b == q_cap and q_f == 1 then
- assert()
- end
- q[q_b] = id
- q_b = q_b + 1
- if q_b == q_cap + 1 then
- q_b = 1
- end
- end
- function q_pop()
- if q_f + 1 == q_b or q_f == q_cap and q_b == 1 then
- assert()
- end
- local t = q[q_f]
- q_f = q_f + 1
- if q_f == q_cap + 1 then
- q_f = 1
- end
- return t
- end
- local function q_init()
- if q then
- return
- end
- q = {}
- q_b = q_cap
- q_f = 1
- for i = 1, q_cap do
- q[i] = 1000 + i -- 这里的objid从1001开始 0-1000留给客户端的剧情动画角色
- end
- end
- q_init()
- obj_envs = {
- require("core.ObjHuman"),
- }
- function getObj(obj_id, obj_uid)
- local obj = objs[obj_id]
- if not obj then
- return
- end
- if obj_uid and obj_uid ~= obj.uid then
- return
- end
- return obj
- end
- function create(obj, obj_type)
- local id = q_pop()
- if objs[id] then
- assert()
- end
- objs[id] = obj
- obj.id = id
- obj.obj_type = obj_type
- obj.uid = Timer.now
- return obj
- end
- function destroy(obj)
- if objs[obj.id] ~= obj then
- assert()
- end
- objs[obj.id] = nil
- q_push(obj.id)
- end
- function destroyAllType(obj)
- if obj_envs[obj.obj_type].destroy then
- obj_envs[obj.obj_type].destroy(obj)
- else
- destroy(obj)
- end
- end
- function getBodyInfo(obj)
- return obj_envs[obj.obj_type].getBodyInfo(obj)
- end
- function getObjAdd(obj)
- return obj_envs[obj.obj_type].getObjAdd(obj)
- end
- local function getObjDel(obj)
- local mm = Msg.gc.GC_DEL_OBJ
- mm.obj_id = obj.id
- return mm
- end
- function getSpeed(obj)
- return obj_envs[obj.obj_type].getSpeed(obj)
- end
- -- 取场景所有obj fd列表
- local sceneFdObjs = {}
- function getSceneObjFds(sceneID, exceptObj)
- for k in ipairs(sceneFdObjs) do
- sceneFdObjs[k] = nil
- end
- if not scenes_fds[sceneID] then
- return sceneFdObjs
- end
- local len = 0
- for _, obj in pairs(scenes_fds[sceneID]) do
- if obj ~= exceptObj then
- len = len + 1
- sceneFdObjs[len] = obj
- end
- end
- return sceneFdObjs
- end
- local sceneObjs = {}
- function getSceneObjs(sceneID, obj_type, ownerUuid)
- for k in ipairs(sceneObjs) do
- sceneObjs[k] = nil
- end
- if not scenes[sceneID] then
- return sceneObjs
- end
- local len = 0
- for _, obj in pairs(scenes[sceneID]) do
- if (obj_type == nil or obj.obj_type == obj_type) and
- (ownerUuid == nil or obj.ownerUuid == ownerUuid) then
- len = len + 1
- sceneObjs[len] = obj
- end
- end
- return sceneObjs
- end
- -- 清除归属的对象
- function clearOwnerObjs(sceneID, obj, noSend)
- if not sceneID then
- return
- end
- local scene = scenes[sceneID]
- if not scene then
- return
- end
- if not obj.fd or not obj.db then
- return
- end
- for _, tobj in pairs(scene) do
- if not tobj.fd and tobj.ownerUuid and
- tobj.ownerUuid == obj.db._id then
- scene[tobj.id] = nil
- destroyAllType(tobj)
- if not noSend then
- Msg.send(getObjDel(tobj), obj.fd)
- end
- end
- end
- end
- function enterScene(obj, sceneID, x, y)
- if obj.sceneID then
- print("ERROR:has enterScene")
- return
- end
- if obj.fd and obj.db then
- -- 把周围的活动obj告诉这个玩家
- local sceneFdObjs = getSceneObjFds(sceneID, obj)
- for _, sceneObj in ipairs(sceneFdObjs) do
- if not sceneObj.ownerUuid or
- sceneObj.ownerUuid == obj.db._id then
- Msg.send(getObjAdd(sceneObj), obj.fd)
- sendMove(sceneObj, obj)
- end
- end
- end
- resetPathParam(obj)
- obj.sceneID = sceneID
- obj.x = x
- obj.y = y
- if obj.fd then
- obj.way = 4
- end
-
- -- 把这个对象进入场景的信息告诉别的玩家
- if obj.ownerUuid then
- local ownerObj = ObjHuman.onlineUuid[obj.ownerUuid]
- if ownerObj and ownerObj.fd then
- Msg.send(getObjAdd(obj), ownerObj.fd)
- end
- else
- sendScene(getObjAdd(obj), sceneID)
- end
- scenes[sceneID] = scenes[sceneID] or {}
- scenes[sceneID][obj.id] = obj
- scenes_fds[sceneID] = scenes_fds[sceneID] or {}
- if obj.fd then
- scenes_fds[sceneID][obj.fd] = obj
- end
- end
- function leaveScene(obj)
- local sceneID = obj.sceneID
- if not sceneID then
- return
- end
- local scene = scenes[sceneID]
- if not scene then
- return
- end
- obj.sceneID = nil
- if not scene[obj.id] then
- return
- end
- scene[obj.id] = nil
- if obj.fd then
- scenes_fds[sceneID][obj.fd] = nil
- clearOwnerObjs(sceneID, obj, true)
- end
-
- -- 告诉附近玩家 这个对象离开场景了
- if obj.ownerUuid then
- local ownerObj = ObjHuman.onlineUuid[obj.ownerUuid]
- if ownerObj and ownerObj.fd then
- Msg.send(getObjDel(obj), ownerObj.fd)
- end
- else
- sendScene(getObjDel(obj), sceneID)
- end
- return true, sceneID
- end
- function sendScene(mm, sceneID, exceptObj)
- local objs = scenes[sceneID]
- if not objs then
- return
- end
- local list = Msg.list
- local len = 0
- for _, obj in pairs(objs) do
- if obj.fd and obj ~= exceptObj then
- len = len + 1
- list[len] = obj.fd
- end
- end
- list[0] = len
- Msg.sendMulti(mm, list)
- end
- function resetPathParam(obj)
- obj.pathLen = 0
- obj.pathPoints = nil
- end
- function walk(during)
- for sceneID, sceneObjs in pairs(scenes) do
- for objid, obj in pairs(sceneObjs) do
- if obj.pathLen > 0 then
- local speed = getSpeed(obj)
- local oldx = obj.x
- local oldy = obj.y
- local nearx = obj.pathPoints[obj.pathLen * 2 - 1]
- local neary = obj.pathPoints[obj.pathLen * 2]
- local dx = oldx - nearx
- local dy = oldy - neary
- local way = Util.getWay(oldx - nearx, oldy - neary)
- local moveLen = math.floor(speed / 1000 * during)
- if dx * dx + dy * dy <= moveLen * moveLen then
- obj.pathLen = obj.pathLen - 1
- oldx = nearx
- oldy = neary
- else
- oldx, oldy = Util.getTargetPoint(nearx, neary, oldx, oldy, moveLen)
- end
- obj.x = oldx
- obj.y = oldy
- obj.way = way
- end
- end
- end
- end
- function stop(obj)
- if obj.path_len == 0 then return end
- if not obj.sceneID then return end
- resetPathParam(obj)
- local msgRet = Msg.gc.GC_STOP_MOVE
- msgRet.way = obj.way or 4
- msgRet.obj_id = obj.id
- msgRet.x = obj.x
- msgRet.y = obj.y
- sendScene(msgRet, obj.sceneID)
- end
- function sendMove(obj, target)
- if not obj.sceneID then
- return
- end
- if not obj.pathLen or obj.pathLen < 1 then
- return
- end
- local msgRet = Msg.gc.GC_MOVE
- msgRet.obj_id = obj.id
- msgRet.points[0] = obj.pathLen * 2
- for i = 1, obj.pathLen do
- local j = obj.pathLen + 1 - i
- msgRet.points[2 * i - 1] = obj.pathPoints[2 * j - 1]
- msgRet.points[2 * i] = obj.pathPoints[2 * j]
- end
- if target then
- Msg.send(msgRet, target.fd)
- else
- sendScene(msgRet, obj.sceneID, obj)
- end
- end
|