Obj.lua 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. --------------------------------------------------------
  2. -- obj.ownerUuid 存在的话,只有指定人能看到
  3. --------------------------------------------------------
  4. local Util = require("common.Util")
  5. local Timer = require("core.Timer")
  6. local Msg = require("core.Msg")
  7. local ObjHuman = require("core.ObjHuman")
  8. TYPE_HUMAN = 1
  9. TYPE_COLLECT = 2
  10. objs = objs or {} -- obj_id转换成对象
  11. scenes = scenes or {} -- 所有的场景 [sceneID][objId] = obj
  12. scenes_fds = scenes_fds or {} -- 场景fd [sceneID][fd] = obj
  13. local q_cap = 65536
  14. local function q_push(id)
  15. if q_b + 1 == q_f or q_b == q_cap and q_f == 1 then
  16. assert()
  17. end
  18. q[q_b] = id
  19. q_b = q_b + 1
  20. if q_b == q_cap + 1 then
  21. q_b = 1
  22. end
  23. end
  24. function q_pop()
  25. if q_f + 1 == q_b or q_f == q_cap and q_b == 1 then
  26. assert()
  27. end
  28. local t = q[q_f]
  29. q_f = q_f + 1
  30. if q_f == q_cap + 1 then
  31. q_f = 1
  32. end
  33. return t
  34. end
  35. local function q_init()
  36. if q then
  37. return
  38. end
  39. q = {}
  40. q_b = q_cap
  41. q_f = 1
  42. for i = 1, q_cap do
  43. q[i] = 1000 + i -- 这里的objid从1001开始 0-1000留给客户端的剧情动画角色
  44. end
  45. end
  46. q_init()
  47. obj_envs = {
  48. require("core.ObjHuman"),
  49. }
  50. function getObj(obj_id, obj_uid)
  51. local obj = objs[obj_id]
  52. if not obj then
  53. return
  54. end
  55. if obj_uid and obj_uid ~= obj.uid then
  56. return
  57. end
  58. return obj
  59. end
  60. function create(obj, obj_type)
  61. local id = q_pop()
  62. if objs[id] then
  63. assert()
  64. end
  65. objs[id] = obj
  66. obj.id = id
  67. obj.obj_type = obj_type
  68. obj.uid = Timer.now
  69. return obj
  70. end
  71. function destroy(obj)
  72. if objs[obj.id] ~= obj then
  73. assert()
  74. end
  75. objs[obj.id] = nil
  76. q_push(obj.id)
  77. end
  78. function destroyAllType(obj)
  79. if obj_envs[obj.obj_type].destroy then
  80. obj_envs[obj.obj_type].destroy(obj)
  81. else
  82. destroy(obj)
  83. end
  84. end
  85. function getBodyInfo(obj)
  86. return obj_envs[obj.obj_type].getBodyInfo(obj)
  87. end
  88. function getObjAdd(obj)
  89. return obj_envs[obj.obj_type].getObjAdd(obj)
  90. end
  91. local function getObjDel(obj)
  92. local mm = Msg.gc.GC_DEL_OBJ
  93. mm.obj_id = obj.id
  94. return mm
  95. end
  96. function getSpeed(obj)
  97. return obj_envs[obj.obj_type].getSpeed(obj)
  98. end
  99. -- 取场景所有obj fd列表
  100. local sceneFdObjs = {}
  101. function getSceneObjFds(sceneID, exceptObj)
  102. for k in ipairs(sceneFdObjs) do
  103. sceneFdObjs[k] = nil
  104. end
  105. if not scenes_fds[sceneID] then
  106. return sceneFdObjs
  107. end
  108. local len = 0
  109. for _, obj in pairs(scenes_fds[sceneID]) do
  110. if obj ~= exceptObj then
  111. len = len + 1
  112. sceneFdObjs[len] = obj
  113. end
  114. end
  115. return sceneFdObjs
  116. end
  117. local sceneObjs = {}
  118. function getSceneObjs(sceneID, obj_type, ownerUuid)
  119. for k in ipairs(sceneObjs) do
  120. sceneObjs[k] = nil
  121. end
  122. if not scenes[sceneID] then
  123. return sceneObjs
  124. end
  125. local len = 0
  126. for _, obj in pairs(scenes[sceneID]) do
  127. if (obj_type == nil or obj.obj_type == obj_type) and
  128. (ownerUuid == nil or obj.ownerUuid == ownerUuid) then
  129. len = len + 1
  130. sceneObjs[len] = obj
  131. end
  132. end
  133. return sceneObjs
  134. end
  135. -- 清除归属的对象
  136. function clearOwnerObjs(sceneID, obj, noSend)
  137. if not sceneID then
  138. return
  139. end
  140. local scene = scenes[sceneID]
  141. if not scene then
  142. return
  143. end
  144. if not obj.fd or not obj.db then
  145. return
  146. end
  147. for _, tobj in pairs(scene) do
  148. if not tobj.fd and tobj.ownerUuid and
  149. tobj.ownerUuid == obj.db._id then
  150. scene[tobj.id] = nil
  151. destroyAllType(tobj)
  152. if not noSend then
  153. Msg.send(getObjDel(tobj), obj.fd)
  154. end
  155. end
  156. end
  157. end
  158. function enterScene(obj, sceneID, x, y)
  159. if obj.sceneID then
  160. print("ERROR:has enterScene")
  161. return
  162. end
  163. if obj.fd and obj.db then
  164. -- 把周围的活动obj告诉这个玩家
  165. local sceneFdObjs = getSceneObjFds(sceneID, obj)
  166. for _, sceneObj in ipairs(sceneFdObjs) do
  167. if not sceneObj.ownerUuid or
  168. sceneObj.ownerUuid == obj.db._id then
  169. Msg.send(getObjAdd(sceneObj), obj.fd)
  170. sendMove(sceneObj, obj)
  171. end
  172. end
  173. end
  174. resetPathParam(obj)
  175. obj.sceneID = sceneID
  176. obj.x = x
  177. obj.y = y
  178. if obj.fd then
  179. obj.way = 4
  180. end
  181. -- 把这个对象进入场景的信息告诉别的玩家
  182. if obj.ownerUuid then
  183. local ownerObj = ObjHuman.onlineUuid[obj.ownerUuid]
  184. if ownerObj and ownerObj.fd then
  185. Msg.send(getObjAdd(obj), ownerObj.fd)
  186. end
  187. else
  188. sendScene(getObjAdd(obj), sceneID)
  189. end
  190. scenes[sceneID] = scenes[sceneID] or {}
  191. scenes[sceneID][obj.id] = obj
  192. scenes_fds[sceneID] = scenes_fds[sceneID] or {}
  193. if obj.fd then
  194. scenes_fds[sceneID][obj.fd] = obj
  195. end
  196. end
  197. function leaveScene(obj)
  198. local sceneID = obj.sceneID
  199. if not sceneID then
  200. return
  201. end
  202. local scene = scenes[sceneID]
  203. if not scene then
  204. return
  205. end
  206. obj.sceneID = nil
  207. if not scene[obj.id] then
  208. return
  209. end
  210. scene[obj.id] = nil
  211. if obj.fd then
  212. scenes_fds[sceneID][obj.fd] = nil
  213. clearOwnerObjs(sceneID, obj, true)
  214. end
  215. -- 告诉附近玩家 这个对象离开场景了
  216. if obj.ownerUuid then
  217. local ownerObj = ObjHuman.onlineUuid[obj.ownerUuid]
  218. if ownerObj and ownerObj.fd then
  219. Msg.send(getObjDel(obj), ownerObj.fd)
  220. end
  221. else
  222. sendScene(getObjDel(obj), sceneID)
  223. end
  224. return true, sceneID
  225. end
  226. function sendScene(mm, sceneID, exceptObj)
  227. local objs = scenes[sceneID]
  228. if not objs then
  229. return
  230. end
  231. local list = Msg.list
  232. local len = 0
  233. for _, obj in pairs(objs) do
  234. if obj.fd and obj ~= exceptObj then
  235. len = len + 1
  236. list[len] = obj.fd
  237. end
  238. end
  239. list[0] = len
  240. Msg.sendMulti(mm, list)
  241. end
  242. function resetPathParam(obj)
  243. obj.pathLen = 0
  244. obj.pathPoints = nil
  245. end
  246. function walk(during)
  247. for sceneID, sceneObjs in pairs(scenes) do
  248. for objid, obj in pairs(sceneObjs) do
  249. if obj.pathLen > 0 then
  250. local speed = getSpeed(obj)
  251. local oldx = obj.x
  252. local oldy = obj.y
  253. local nearx = obj.pathPoints[obj.pathLen * 2 - 1]
  254. local neary = obj.pathPoints[obj.pathLen * 2]
  255. local dx = oldx - nearx
  256. local dy = oldy - neary
  257. local way = Util.getWay(oldx - nearx, oldy - neary)
  258. local moveLen = math.floor(speed / 1000 * during)
  259. if dx * dx + dy * dy <= moveLen * moveLen then
  260. obj.pathLen = obj.pathLen - 1
  261. oldx = nearx
  262. oldy = neary
  263. else
  264. oldx, oldy = Util.getTargetPoint(nearx, neary, oldx, oldy, moveLen)
  265. end
  266. obj.x = oldx
  267. obj.y = oldy
  268. obj.way = way
  269. end
  270. end
  271. end
  272. end
  273. function stop(obj)
  274. if obj.path_len == 0 then return end
  275. if not obj.sceneID then return end
  276. resetPathParam(obj)
  277. local msgRet = Msg.gc.GC_STOP_MOVE
  278. msgRet.way = obj.way or 4
  279. msgRet.obj_id = obj.id
  280. msgRet.x = obj.x
  281. msgRet.y = obj.y
  282. sendScene(msgRet, obj.sceneID)
  283. end
  284. function sendMove(obj, target)
  285. if not obj.sceneID then
  286. return
  287. end
  288. if not obj.pathLen or obj.pathLen < 1 then
  289. return
  290. end
  291. local msgRet = Msg.gc.GC_MOVE
  292. msgRet.obj_id = obj.id
  293. msgRet.points[0] = obj.pathLen * 2
  294. for i = 1, obj.pathLen do
  295. local j = obj.pathLen + 1 - i
  296. msgRet.points[2 * i - 1] = obj.pathPoints[2 * j - 1]
  297. msgRet.points[2 * i] = obj.pathPoints[2 * j]
  298. end
  299. if target then
  300. Msg.send(msgRet, target.fd)
  301. else
  302. sendScene(msgRet, obj.sceneID, obj)
  303. end
  304. end