Permalink
Browse files

add code for instance

  • Loading branch information...
1 parent 192879b commit 019f01168a8d35d09e3a18bb63ad87a915058fd2 @demon0925 demon0925 committed May 21, 2013
Showing with 2,987 additions and 588 deletions.
  1. +2 −2 .jshintrc
  2. +2 −2 game-server/.jshintrc
  3. +25 −9 game-server/app.js
  4. +8 −8 game-server/app/ai/action/moveToTarget.js
  5. +1 −1 game-server/app/ai/action/patrol.js
  6. +9 −10 game-server/app/ai/service/aiManager.js
  7. +24 −16 game-server/app/consts/consts.js
  8. +3 −3 game-server/app/domain/action/move.js
  9. +20 −19 game-server/app/domain/action/revive.js
  10. +21 −15 game-server/app/domain/aoi/aoiEventManager.js
  11. +257 −283 game-server/app/domain/area/area.js
  12. +31 −0 game-server/app/domain/area/instance.js
  13. +72 −0 game-server/app/domain/area/instancePool.js
  14. +67 −0 game-server/app/domain/area/manager.js
  15. +18 −0 game-server/app/domain/area/scene.js
  16. +53 −37 game-server/app/domain/area/timer.js
  17. +11 −5 game-server/app/domain/entity/character.js
  18. +1 −1 game-server/app/domain/entity/entity.js
  19. +23 −13 game-server/app/domain/entity/equipment.js
  20. +10 −0 game-server/app/domain/entity/item.js
  21. +5 −7 game-server/app/domain/entity/mob.js
  22. +16 −7 game-server/app/domain/entity/npc.js
  23. +5 −6 game-server/app/domain/entity/player.js
  24. +18 −16 game-server/app/domain/event/characterEvent.js
  25. +5 −6 game-server/app/domain/event/npcEvent.js
  26. +2 −3 game-server/app/domain/event/playerEvent.js
  27. +2 −3 game-server/app/domain/executeTask.js
  28. +4 −0 game-server/app/domain/map/map.js
  29. +26 −19 game-server/app/domain/map/mobzone.js
  30. +1 −0 game-server/app/domain/map/zone.js
  31. +2 −13 game-server/app/domain/messageService.js
  32. +1 −2 game-server/app/domain/taskReward.js
  33. +0 −1 game-server/app/domain/world.js
  34. +3 −3 game-server/app/modules/sceneInfo.js
  35. +7 −5 game-server/app/servers/area/filter/playerFilter.js
  36. +4 −5 game-server/app/servers/area/handler/equipHandler.js
  37. +10 −12 game-server/app/servers/area/handler/fightHandler.js
  38. +28 −20 game-server/app/servers/area/handler/playerHandler.js
  39. +2 −3 game-server/app/servers/area/handler/resourceHandler.js
  40. +7 −8 game-server/app/servers/area/handler/taskHandler.js
  41. +19 −0 game-server/app/servers/area/remote/areaRemote.js
  42. +16 −8 game-server/app/servers/area/remote/playerRemote.js
  43. +4 −3 game-server/app/servers/connector/handler/entryHandler.js
  44. +26 −0 game-server/app/servers/manager/remote/instanceRemote.js
  45. +139 −0 game-server/app/services/areaService
  46. +108 −0 game-server/app/services/instanceManager.js
  47. +2 −3 game-server/app/util/routeUtil.js
  48. +8 −6 game-server/config/data/area.json
  49. +1 −1 game-server/config/data/npc.json
  50. +1 −1 game-server/config/data/talk.json
  51. +4 −0 game-server/config/instance.json
  52. +385 −0 game-server/config/map/arena.json
  53. +1,459 −0 game-server/config/map/paths.json
  54. +7 −1 game-server/config/servers.json
  55. +1 −1 game-server/package.json
  56. +1 −1 game-server/tmp/map.json
View
4 .jshintrc
@@ -14,8 +14,8 @@
"node": true,
"eqeqeq": true,
"undef": true,
- "curly": true,
- "bitwise": true,
+ "curly": false,
+ "bitwise": false,
"immed": false,
"newcap": true,
"nonew": true,
View
4 game-server/.jshintrc
@@ -11,8 +11,8 @@
"node": true,
"eqeqeq": true,
"undef": true,
- "curly": true,
- "bitwise": true,
+ "curly": false,
+ "bitwise": false,
"immed": false,
"newcap": true,
"nonew": true,
View
34 game-server/app.js
@@ -1,6 +1,8 @@
var pomelo = require('pomelo');
-var world = require('./app/domain/world');
-var area = require('./app/domain/area/area');
+var areaService = require('./app/services/areaService');
+var instanceManager = require('./app/services/instanceManager');
+var scene = require('./app/domain/area/scene');
+var instancePool = require('./app/domain/area/instancePool');
var dataApi = require('./app/util/dataApi');
var routeUtil = require('./app/util/routeUtil');
var playerFilter = require('./app/servers/area/filter/playerFilter');
@@ -20,10 +22,10 @@ app.configure('production', function() {
// configure for global
app.configure('production|development', function() {
- var sceneInfo = require('./app/modules/sceneInfo');
+ //var sceneInfo = require('./app/modules/sceneInfo');
var onlineUser = require('./app/modules/onlineUser');
if(typeof app.registerAdmin === 'function'){
- app.registerAdmin(sceneInfo, {app: app});
+ //app.registerAdmin(sceneInfo, {app: app});
app.registerAdmin(onlineUser, {app: app});
}
//Set areasIdMap, a map from area id to serverId.
@@ -68,12 +70,26 @@ app.configure('production|development', 'area', function(){
app.filter(pomelo.filters.serial());
app.before(playerFilter());
- var areaId = app.get('curServer').area;
- if(!areaId || areaId < 0) {
- throw new Error('load area config failed');
+ //Load scene server and instance server
+ var server = app.curServer;
+ if(server.instance){
+ instancePool.init(require('./config/instance.json'));
+ app.areaManager = instancePool;
+ }else{
+ scene.init(dataApi.area.findById(server.area));
+ app.areaManager = scene;
}
- world.init(dataApi.area.all());
- area.init(dataApi.area.findById(areaId));
+
+ //Init areaService
+ areaService.init();
+});
+
+app.configure('production|development', 'manager', function(){
+ var events = pomelo.events;
+
+ app.event.on(events.ADD_SERVERS, instanceManager.addServers);
+
+ app.event.on(events.REMOVE_SERVERS, instanceManager.removeServers);
});
// Configure database
View
16 game-server/app/ai/action/moveToTarget.js
@@ -42,14 +42,14 @@ pro.doAction = function() {
}
if(formula.inRange(character, target, distance)) {
- this.blackboard.area.timer().abortAction('move', character.entityId);
+ this.blackboard.area.timer.abortAction('move', character.entityId);
this.blackboard.distanceLimit = 0;
this.blackboard.moved = false;
return bt.RES_SUCCESS;
}
if(character.type === consts.EntityType.MOB) {
- if(Math.abs(character.x - character.spawnX) > 500 ||
+ if(Math.abs(character.x - character.spawnX) > 500 ||
Math.abs(character.y - character.spawnY) > 500) {
//we move too far and it is time to turn back
character.forgetHater(targetId);
@@ -58,18 +58,18 @@ pro.doAction = function() {
}
}
-
+
var targetPos = this.blackboard.targetPos;
var closure = this;
-
+
if(!this.blackboard.moved){
character.move(target.x, target.y, false, function(err, result){
if(err || result === false){
closure.blackboard.moved = false;
character.target = null;
}
- });
-
+ });
+
this.blackboard.targetPos = {x: target.x, y : target.y};
this.blackboard.moved = true;
} else if(targetPos && (targetPos.x !== target.x || targetPos.y !== target.y)) {
@@ -80,13 +80,13 @@ pro.doAction = function() {
if(((dis1 * 3 > dis2) && (dis1 < distance)) || !this.blackboard.moved){
targetPos.x = target.x;
targetPos.y = target.y;
-
+
character.move(target.x, target.y, false, function(err, result){
if(err || result === false){
closure.blackboard.moved = false;
character.target = null;
}
- });
+ });
}
}
return bt.RES_WAIT;
View
2 game-server/app/ai/action/patrol.js
@@ -21,7 +21,7 @@ pro.doAction = function() {
var character = this.blackboard.curCharacter;
var area = this.blackboard.area;
- area.timer().patrol(character.entityId);
+ area.timer.patrol(character.entityId);
return bt.RES_SUCCESS;
};
View
19 game-server/app/ai/service/aiManager.js
@@ -1,11 +1,10 @@
var Blackboard = require('../meta/blackboard');
-var area = require('../../domain/area/area');
var exp = module.exports;
var Manager = function(opts) {
this.brainService = opts.brainService;
- this.area = area;
+ this.area = opts.area;
this.players = {};
this.mobs = {};
};
@@ -46,22 +45,22 @@ pro.addCharacters = function(cs) {
if(this.players[c.entityId]) {
continue;
}
-
+
brain = this.brainService.getBrain('player', Blackboard.create({
- manager: this,
- area: this.area,
- curCharacter: c
+ manager: this,
+ area: this.area,
+ curCharacter: c
}));
this.players[c.entityId] = brain;
} else {
if(this.mobs[c.entityId]) {
continue;
}
-
+
brain = this.brainService.getBrain(c.characterName, Blackboard.create({
- manager: this,
- area: this.area,
- curCharacter: c
+ manager: this,
+ area: this.area,
+ curCharacter: c
}));
this.mobs[c.entityId] = brain;
}
View
40 game-server/app/consts/consts.js
@@ -8,7 +8,7 @@ module.exports = {
NOT_COOLDOWN: 6,
ATTACKER_CONFUSED: 7,
ERROR: -1
- },
+ },
RES_CODE : {
SUC_OK : 1, // success
@@ -18,11 +18,11 @@ module.exports = {
ERR_SESSION_NOT_EXIST : -11, // session not exist
ERR_CHANNEL_DUPLICATE : -12, // channel duplicated
ERR_CHANNEL_NOT_EXIST : -13 // channel not exist
- },
+ },
MYSQL : {
ERROR_DUP_ENTRY : 1062
- },
+ },
PLAYER : {
initAreaId : 1,
@@ -36,13 +36,13 @@ module.exports = {
y : 81,
width : 126,
height : 129
- },
+ },
MESSAGE: {
RES: 200,
ERR: 500,
PUSH: 600
- },
+ },
EntityType: {
PLAYER: 'player',
@@ -51,58 +51,66 @@ module.exports = {
EQUIPMENT: 'equipment',
ITEM: 'item',
BAG: 'bag'
- },
+ },
Pick: {
SUCCESS: 1,
VANISH: 2,
- NOT_IN_RANGE: 3,
+ NOT_IN_RANGE: 3,
BAG_FULL: 4
- },
+ },
NPC: {
SUCCESS: 1,
NOT_IN_RANGE: 2
- },
+ },
TaskState: {
COMPLETED:2,
COMPLETED_NOT_DELIVERY:1,
NOT_COMPLETED:0,
NOT_START:-1
- },
+ },
TaskType: {
KILL_MOB: 0,
KILL_PLAYER: 1
- },
+ },
NpcType: {
TALK_NPC: '0',
TRAVERSE_NPC: '1'
- },
+ },
Event:{
chat:'onChat'
- },
+ },
/**
* Traverse npc, the key is the npc id, the value is the taret's area id.
*/
TraverseNpc: {
301 : 2,
+ 302 : 4,
305 : 1,
306 : 3,
- 309 : 2
- },
-
+ 309 : 2,
+ 303 : 5
+ },
+
/**
* Traverse task, the key is traverse npc's id, the value is task id.
*/
TraverseTask: {
//3008: 3
},
+ AreaType : {
+ SCENE : 1,
+ SINGLE_INSTANCE : 2,
+ GROUP_INSTANCE : 3
+ },
+
/**
* check a entity that whether can be picked.
*/
View
6 game-server/app/domain/action/move.js
@@ -1,6 +1,5 @@
var Action = require('./action');
var util = require('util');
-var timer = require('../area/timer');
var messageService = require('../messageService');
var consts = require('../../consts/consts');
var logger = require('pomelo-logger').getLogger(__filename);
@@ -15,6 +14,7 @@ var Move = function(opts){
Action.call(this, opts);
this.entity = opts.entity;
+ this.area = this.entity.area;
this.path = opts.path;
this.speed = Number(opts.speed);
this.time = Date.now();
@@ -74,8 +74,8 @@ Move.prototype.update = function(){
//Update the aoi module
var watcher = {id : this.entity.entityId, type : this.entity.type};
- timer.updateObject(watcher, oldPos, pos);
- timer.updateWatcher(watcher, oldPos, pos, this.entity.range, this.entity.range);
+ this.area.timer.updateObject(watcher, oldPos, pos);
+ this.area.timer.updateWatcher(watcher, oldPos, pos, this.entity.range, this.entity.range);
if(this.entity.type === consts.EntityType.PLAYER){
this.entity.save();
if (this.tickNumber % 10 === 0) {
View
39 game-server/app/domain/action/revive.js
@@ -1,6 +1,4 @@
var Action = require('./action');
-var area = require('../area/area');
-var timer = require('../area/timer');
var messageService = require('../messageService');
var util = require('util');
@@ -11,6 +9,8 @@ var Revive = function(opts){
Action.call(this, opts);
this.entity = opts.entity;
+ this.area = this.entity.area;
+ this.map = opts.map;
this.time = opts.reviveTime;
this.now = Date.now();
};
@@ -23,36 +23,37 @@ util.inherits(Revive, Action);
*/
Revive.prototype.update = function(){
var time = Date.now();
-
+
this.time -= time - this.now;
if(this.time <= 10){
this.entity.died = false;
this.entity.hp = this.entity.maxHp/2;
-
- var bornPlace = area.map().getBornPlace();
-
+
+ var bornPlace = this.map.getBornPlace();
+
var oldPos = {x : this.entity.x, y : this.entity.y};
-
+
var newPos = {
x : bornPlace.x + Math.floor(Math.random() * bornPlace.width),
y : bornPlace.y + Math.floor(Math.random() * bornPlace.height)
};
-
+
var watcher = {id : this.entity.entityId, type : this.entity.type};
- timer.updateObject(watcher, oldPos, newPos);
- timer.updateWatcher(watcher, oldPos, newPos, this.entity.range, this.entity.range);
-
- this.entity.x = newPos.x;
- this.entity.y = newPos.y;
-
+ this.area.timer.updateObject(watcher, oldPos, newPos);
+ this.area.timer.updateWatcher(watcher, oldPos, newPos, this.entity.range, this.entity.range);
+
+ this.entity.x = newPos.x;
+ this.entity.y = newPos.y;
+
messageService.pushMessageByAOI(
+ this.area,
{
- route: 'onRevive',
- entityId : this.entity.entityId,
- x: this.entity.x,
- y: this.entity.y,
+ route: 'onRevive',
+ entityId : this.entity.entityId,
+ x: this.entity.x,
+ y: this.entity.y,
hp: this.entity.hp
- },
+ },
{x : this.entity.x, y : this.entity.y});
this.finished = true;
}
View
36 game-server/app/domain/aoi/aoiEventManager.js
@@ -1,13 +1,13 @@
-var area = require('../area/area');
var messageService = require('../messageService');
var EntityType = require('../../consts/consts').EntityType;
var logger = require('pomelo-logger').getLogger(__filename);
var exp = module.exports;
//Add event for aoi
-exp.addEvent = function(aoi){
+exp.addEvent = function(area, aoi){
aoi.on('add', function(params){
+ params.area = area;
switch(params.type){
case EntityType.PLAYER:
onPlayerAdd(params);
@@ -19,6 +19,7 @@ exp.addEvent = function(aoi){
});
aoi.on('remove', function(params){
+ params.area = area;
switch(params.type){
case EntityType.PLAYER:
onPlayerRemove(params);
@@ -29,6 +30,7 @@ exp.addEvent = function(aoi){
});
aoi.on('update', function(params){
+ params.area = area;
switch(params.type){
case EntityType.PLAYER:
onObjectUpdate(params);
@@ -40,6 +42,7 @@ exp.addEvent = function(aoi){
});
aoi.on('updateWatcher', function(params) {
+ params.area = area;
switch(params.type) {
case EntityType.PLAYER:
onPlayerUpdate(params);
@@ -55,6 +58,7 @@ exp.addEvent = function(aoi){
* @api private
*/
function onPlayerAdd(params) {
+ var area = params.area;
var watchers = params.watchers;
var entityId = params.id;
var player = area.getEntity(entityId);
@@ -74,7 +78,7 @@ function onPlayerAdd(params) {
}
}
if(uids.length > 0){
- onAddEntity(uids, entityId);
+ onAddEntity(uids, player);
}
break;
case EntityType.MOB:
@@ -96,6 +100,7 @@ function onPlayerAdd(params) {
* @api private
*/
function onMobAdd(params){
+ var area = params.area;
var watchers = params.watchers;
var entityId = params.id;
var mob = area.getEntity(entityId);
@@ -113,10 +118,10 @@ function onMobAdd(params){
}
if(uids.length > 0) {
- onAddEntity(uids, entityId);
+ onAddEntity(uids, mob);
}
- var ids = area.aoi().getIdsByRange({x:mob.x, y:mob.y}, mob.range, [EntityType.PLAYER])[EntityType.PLAYER];
+ var ids = area.aoi.getIdsByRange({x:mob.x, y:mob.y}, mob.range, [EntityType.PLAYER])[EntityType.PLAYER];
if(!!ids && ids.length > 0 && !mob.target){
for(var key in ids){
mob.onPlayerCome(ids[key]);
@@ -131,6 +136,7 @@ function onMobAdd(params){
* @api private
*/
function onPlayerRemove(params) {
+ var area = params.area;
var watchers = params.watchers;
var entityId = params.id;
@@ -160,6 +166,7 @@ function onPlayerRemove(params) {
* @api private
*/
function onObjectUpdate(params) {
+ var area = params.area;
var entityId = params.id;
var entity = area.getEntity(entityId);
@@ -204,12 +211,12 @@ function onObjectUpdate(params) {
switch(params.type) {
case EntityType.PLAYER:
- onPlayerAdd({id:params.id, watchers:addWatchers});
- onPlayerRemove({id:params.id, watchers:removeWatchers});
+ onPlayerAdd({area:area, id:params.id, watchers:addWatchers});
+ onPlayerRemove({area:area, id:params.id, watchers:removeWatchers});
break;
case EntityType.MOB:
- onMobAdd({id:params.id, watchers:addWatchers});
- onMobRemove({id:params.id, watchers:removeWatchers});
+ onMobAdd({area:area, id:params.id, watchers:addWatchers});
+ onMobRemove({area:area, id:params.id, watchers:removeWatchers});
break;
}
}
@@ -221,6 +228,7 @@ function onObjectUpdate(params) {
* @api private
*/
function onPlayerUpdate(params) {
+ var area = params.area;
var player = area.getEntity(params.id);
if(player.type !== EntityType.PLAYER) {
return;
@@ -247,6 +255,7 @@ function onPlayerUpdate(params) {
* @api private
*/
function onMobRemove(params) {
+ var area = params.area;
var watchers = params.watchers;
var entityId = params.id;
var uids = [];
@@ -272,12 +281,9 @@ function onMobRemove(params) {
* @param {Number} entityId The entityId to add
* @api private
*/
-function onAddEntity(uids, entityId) {
- var entities = area.getEntities([entityId]);
-
- if(entities.length <= 0 || uids.length <= 0) {
- return;
- }
+function onAddEntity(uids, entity) {
+ var entities = {};
+ entities[entity.type] = [entity];
messageService.pushMessageByUids(uids, 'onAddEntities', entities);
}
View
540 game-server/app/domain/area/area.js
@@ -1,306 +1,318 @@
var dataApi = require('../../util/dataApi');
-var Map = require('./../map/map');
var MobZone = require('./../map/mobzone');
var NPC = require('./../entity/npc');
var pomelo = require('pomelo');
-var Queue = require('pomelo-collection').queue;
var ai = require('../../ai/ai');
var patrol = require('../../patrol/patrol');
var ActionManager = require('./../action/actionManager');
var aoiManager = require('pomelo-aoi');
var eventManager = require('./../event/eventManager');
var aoiEventManager = require('./../aoi/aoiEventManager');
var EntityType = require('../../consts/consts').EntityType;
-var timer = require('./timer');
+var Timer = require('./timer');
var logger = require('pomelo-logger').getLogger(__filename);
-var exp = module.exports;
-
-var id = 0;
-var level = 0;
-var map = null;
-var actionManager = null;
-var aiManager = null;
-var patrolManager = null;
-
-//The map from player to entity
-var players = {};
-var users = {};
-var entities = {};
-var zones = {};
-var items = {};
-var channel = null;
-var aoi = null;
-
/**
* Init areas
* @param {Object} opts
* @api public
*/
-exp.init = function(opts) {
- //Init Map
- id = opts.id;
- level = opts.level;
-
- opts.weightMap = true;
- map = new Map(opts);
- //Init AOI
- aoi = aoiManager.getService(opts);
- aoiEventManager.addEvent(aoi.aoi);
-
- //Init mob zones
- initMobZones(map.getMobZones());
- initNPCs(this);
-
- aiManager = ai.createManager();
- patrolManager = patrol.createManager({area:this});
- actionManager = new ActionManager();
- run();
+var Instance = function(opts){
+ this.areaId = opts.id;
+ this.type = opts.type;
+ this.map = opts.map;
+
+ //The map from player to entity
+ this.players = {};
+ this.users = {};
+ this.entities = {};
+ this.zones = {};
+ this.items = {};
+ this.channel = null;
+
+ this.playerNum = 0;
+ this.emptyTime = Date.now();
+ //Init AOI
+ this.aoi = aoiManager.getService(opts);
+
+ this.aiManager = ai.createManager({area:this});
+ this.patrolManager = patrol.createManager({area:this});
+ this.actionManager = new ActionManager();
+
+ this.timer = new Timer({
+ area : this,
+ interval : 100
+ });
+
+ this.start();
};
+module.exports = Instance;
+
/**
* @api public
*/
-function run() {
- aiManager.start();
- timer.run();
-}
+Instance.prototype.start = function() {
+ aoiEventManager.addEvent(this, this.aoi.aoi);
+
+ //Init mob zones
+ this.initMobZones(this.map.getMobZones());
+ this.initNPCs(this);
+
+ this.aiManager.start();
+ this.timer.run();
+};
+
+Instance.prototype.close = function(){
+ this.timer.close();
+};
/**
* Init npcs
* @api private
*/
-function initNPCs() {
- var npcs = map.getNPCs();
-
- for(var i = 0; i < npcs.length; i++) {
- var data = npcs[i];
-
- data.kindId = data.id;
- var npcInfo = dataApi.npc.findById(data.kindId);
- data.kindName = npcInfo.name;
- data.englishName = npcInfo.englishName;
- data.kindType = npcInfo.kindType;
- data.orientation = data.orientation;
- data.areaId = id;
- exp.addEntity(new NPC(data));
- }
-}
-
-function getChannel() {
- if(channel) {
- return channel;
- }
-
- channel = pomelo.app.get('channelService').getChannel('area_' + id, true);
- return channel;
-}
+Instance.prototype.initNPCs = function() {
+ var npcs = this.map.getNPCs();
+
+ for(var i = 0; i < npcs.length; i++) {
+ var data = npcs[i];
+
+ data.kindId = data.id;
+ var npcInfo = dataApi.npc.findById(data.kindId);
+ data.kindName = npcInfo.name;
+ data.englishName = npcInfo.englishName;
+ data.kindType = npcInfo.kindType;
+ data.orientation = data.orientation;
+ data.areaId = this.id;
+
+ this.addEntity(new NPC(data));
+ }
+};
+
+Instance.prototype.getChannel = function() {
+ if(!this.channel){
+ this.channel = pomelo.app.get('channelService').getChannel('instance_' + this.id, true);
+ }
+
+ return this.channel;
+};
/**
* Init all zones in area
* @api private
*/
-function initMobZones(mobZones) {
- for(var i = 0; i < mobZones.length; i++) {
- var zone = new MobZone(mobZones[i]);
- zones[zone.zoneId] = zone;
- }
-}
+Instance.prototype.initMobZones = function(mobZones) {
+ for(var i = 0; i < mobZones.length; i++) {
+ var opts = mobZones[i];
+ opts.area = this;
+ var zone = new MobZone(opts);
+ this.zones[zone.zoneId] = zone;
+ }
+};
/**
* Add entity to area
* @param {Object} e Entity to add to the area.
*/
-exp.addEntity = function(e) {
- if(!e || !e.entityId) {
- return false;
- }
-
- if(!!players[e.id]) {
- logger.error('add player twice! player : %j', e);
- return false;
- }
-
- entities[e.entityId] = e;
- eventManager.addEvent(e);
-
- if(e.type === EntityType.PLAYER) {
- getChannel().add(e.userId, e.serverId);
- aiManager.addCharacters([e]);
-
- aoi.addWatcher({id: e.entityId, type: e.type}, {x : e.x, y: e.y}, e.range);
- players[e.id] = e.entityId;
- users[e.userId] = e.id;
- }else if(e.type === EntityType.MOB) {
- aiManager.addCharacters([e]);
-
- aoi.addWatcher({id: e.entityId, type: e.type}, {x : e.x, y: e.y}, e.range);
- }else if(e.type === EntityType.NPC) {
-
- }else if(e.type === EntityType.ITEM) {
- items[e.entityId] = e.entityId;
- }else if(e.type === EntityType.EQUIPMENT) {
- items[e.entityId] = e.entityId;
- }
-
- aoi.addObject({id:e.entityId, type:e.type}, {x: e.x, y: e.y});
- return true;
+Instance.prototype.addEntity = function(e) {
+ var entities = this.entities;
+ var players = this.players;
+ var users = this.users;
+
+ if(!e || !e.entityId) {
+ return false;
+ }
+
+ if(!!players[e.id]) {
+ logger.error('add player twice! player : %j', e);
+ return false;
+ }
+
+ //Set area and areaId
+ e.area = this;
+
+ entities[e.entityId] = e;
+ eventManager.addEvent(e);
+
+ if(e.type === EntityType.PLAYER) {
+ this.getChannel().add(e.userId, e.serverId);
+ this.aiManager.addCharacters([e]);
+
+ this.aoi.addWatcher({id: e.entityId, type: e.type}, {x : e.x, y: e.y}, e.range);
+ players[e.id] = e.entityId;
+ users[e.userId] = e.id;
+
+ this.playerNum++;
+ }else if(e.type === EntityType.MOB) {
+ this.aiManager.addCharacters([e]);
+
+ this.aoi.addWatcher({id: e.entityId, type: e.type}, {x : e.x, y: e.y}, e.range);
+ }else if(e.type === EntityType.ITEM) {
+ this.items[e.entityId] = e.entityId;
+ }else if(e.type === EntityType.EQUIPMENT) {
+ this.items[e.entityId] = e.entityId;
+ }
+
+ this.aoi.addObject({id:e.entityId, type:e.type}, {x: e.x, y: e.y});
+ return true;
};
/**
* Remove Entity form area
* @param {Number} entityId The entityId to remove
* @return {boolean} remove result
*/
-exp.removeEntity = function(entityId) {
- var e = entities[entityId];
- if(!e) {
- return true;
- }
-
- //If the entity belong to a subzone, remove it
- if(!!zones[e.zoneId]) {
- zones[e.zoneId].remove(entityId);
- }
-
- //If the entity is a player, remove it
- if(e.type === 'player') {
- getChannel().leave(e.userId, pomelo.app.getServerId());
- aiManager.removeCharacter(e.entityId);
- patrolManager.removeCharacter(e.entityId);
- aoi.removeObject({id:e.entityId, type: e.type}, {x: e.x, y: e.y});
- actionManager.abortAllAction(entityId);
-
- e.forEachEnemy(function(enemy) {
- enemy.forgetHater(e.entityId);
- });
-
- e.forEachHater(function(hater) {
- hater.forgetEnemy(e.entityId);
- });
-
- aoi.removeWatcher(e, {x : e.x, y: e.y}, e.range);
- delete players[e.id];
- delete users[e.userId];
- }else if(e.type === 'mob') {
- aiManager.removeCharacter(e.entityId);
- patrolManager.removeCharacter(e.entityId);
- aoi.removeObject({id: e.entityId, type: e.type}, {x: e.x, y: e.y});
- actionManager.abortAllAction(entityId);
-
- e.forEachEnemy(function(enemy) {
- enemy.forgetHater(e.entityId);
- });
-
- e.forEachHater(function(hater) {
- hater.forgetEnemy(e.entityId);
- });
-
- aoi.removeWatcher(e, {x : e.x, y: e.y}, e.range);
- }else if(e.type === EntityType.ITEM) {
- delete items[entityId];
- }else if(e.type === EntityType.EQUIPMENT) {
- delete items[entityId];
- }
-
- aoi.removeObject(e, {x: e.x, y: e.y});
- delete entities[entityId];
- return true;
+Instance.prototype.removeEntity = function(entityId) {
+ var zones = this.zones;
+ var entities = this.entities;
+ var players = this.players;
+ var users = this.users;
+ var items = this.items;
+
+ var e = entities[entityId];
+ if(!e) return true;
+
+ //If the entity belong to a subzone, remove it
+ if(!!zones[e.zoneId]) {
+ zones[e.zoneId].remove(entityId);
+ }
+
+ //If the entity is a player, remove it
+ if(e.type === 'player') {
+ this.getChannel().leave(e.userId, pomelo.app.getServerId());
+ this.aiManager.removeCharacter(e.entityId);
+ this.patrolManager.removeCharacter(e.entityId);
+ this.aoi.removeObject({id:e.entityId, type: e.type}, {x: e.x, y: e.y});
+ this.actionManager.abortAllAction(entityId);
+
+ e.forEachEnemy(function(enemy) {
+ enemy.forgetHater(e.entityId);
+ });
+
+ e.forEachHater(function(hater) {
+ hater.forgetEnemy(e.entityId);
+ });
+
+ this.aoi.removeWatcher(e, {x : e.x, y: e.y}, e.range);
+ delete players[e.id];
+ delete users[e.userId];
+
+ this.playerNum--;
+
+ if(this.playerNum === 0){
+ this.emptyTime = Date.now();
+ }
+ }else if(e.type === 'mob') {
+ this.aiManager.removeCharacter(e.entityId);
+ this.patrolManager.removeCharacter(e.entityId);
+ this.aoi.removeObject({id: e.entityId, type: e.type}, {x: e.x, y: e.y});
+ this.actionManager.abortAllAction(entityId);
+
+ e.forEachEnemy(function(enemy) {
+ enemy.forgetHater(e.entityId);
+ });
+
+ e.forEachHater(function(hater) {
+ hater.forgetEnemy(e.entityId);
+ });
+
+ this.aoi.removeWatcher(e, {x : e.x, y: e.y}, e.range);
+ }else if(e.type === EntityType.ITEM) {
+ delete items[entityId];
+ }else if(e.type === EntityType.EQUIPMENT) {
+ delete items[entityId];
+ }
+
+ this.aoi.removeObject(e, {x: e.x, y: e.y});
+ delete entities[entityId];
+ return true;
};
/**
* Get entity from area
* @param {Number} entityId.
*/
-exp.getEntity = function(entityId) {
- var entity = entities[entityId];
- if (!entity) {
- return null;
- }
- return entity;
+Instance.prototype.getEntity = function(entityId) {
+ var entity = this.entities[entityId];
+ if (!entity) {
+ return null;
+ }
+ return entity;
};
/**
* Get entities by given id list
* @param {Array} The given entities' list.
* @return {Map} The entities
*/
-exp.getEntities = function(ids) {
- var result = {};
-
- result.length = 0;
- for(var i = 0; i < ids.length; i++) {
- var entity = entities[ids[i]];
- if(!!entity) {
- if(!result[entity.type]){
- result[entity.type] = [];
- }
-
- result[entity.type].push(entity);
- result.length++;
- }
- }
-
- return result;
+Instance.prototype.getEntities = function(ids) {
+ var result = {};
+
+ result.length = 0;
+ for(var i = 0; i < ids.length; i++) {
+ var entity = this.entities[ids[i]];
+ if(!!entity) {
+ if(!result[entity.type]){
+ result[entity.type] = [];
+ }
+
+ result[entity.type].push(entity);
+ result.length++;
+ }
+ }
+
+ return result;
};
-exp.getAllPlayers = function() {
- var _players = [];
- for(var id in players) {
- _players.push(entities[players[id]]);
- }
+Instance.prototype.getAllPlayers = function() {
+ var _players = [];
+ for(var id in this.players) {
+ _players.push(this.entities[this.players[id]]);
+ }
- return _players;
+ return _players;
};
-exp.getAllEntities = function() {
- return entities;
+Instance.prototype.getAllEntities = function() {
+ return this.entities;
};
-exp.getPlayer = function(playerId) {
- var entityId = players[playerId];
+Instance.prototype.getPlayer = function(playerId) {
+ var entityId = this.players[playerId];
- if(!!entityId) {
- return entities[entityId];
- }
+ if(!!entityId) {
+ return this.entities[entityId];
+ }
- return null;
+ return null;
};
-exp.removePlayer = function(playerId) {
- var entityId = players[playerId];
+Instance.prototype.removePlayer = function(playerId) {
+ var entityId = this.players[playerId];
- if(!!entityId) {
- delete players[playerId];
- this.removeEntity(entityId);
- }
+ if(!!entityId) {
+ this.removeEntity(entityId);
+ }
};
-exp.getPlayerByUid = function(uid){
- if(!!users[uid]){
- return this.getPlayer(users[uid]);
- }
+Instance.prototype.removePlayerByUid = function(uid){
+ var users = this.users;
+ var playerId = users[uid];
- return null;
-};
-
-exp.removePlayerByUid = function(uid){
- var playerId = users[uid];
-
- if(!!playerId){
- delete users[uid];
- this.removePlayer(playerId);
- }
+ if(!!playerId){
+ delete users[uid];
+ this.removePlayer(playerId);
+ }
};
/**
* Get area entities for given postion and range.
* @param {Object} pos Given position, like {10,20}.
* @param {Number} range The range of the view, is the circle radius.
*/
-exp.getAreaInfo = function(pos, range) {
- var ids = aoi.getIdsByPos(pos, range);
- return this.getEntities(ids);
+Instance.prototype.getAreaInfo = function(pos, range) {
+ var ids = this.aoi.getIdsByPos(pos, range);
+ return this.getEntities(ids);
};
/**
@@ -309,65 +321,27 @@ exp.getAreaInfo = function(pos, range) {
* @param {Array} types The types of the object need to find.
* @param {Number} range The range of the view, is the circle radius.
*/
-exp.getEntitiesByPos = function(pos, types, range) {
- var idsMap = aoi.getIdsByRange(pos, range, types);
- var result = {};
- for(var type in idsMap) {
- if(!result[type]) {
- result[type] = [];
- }
- for(var i = 0; i < idsMap[type].length; i++) {
- var id = idsMap[type][i];
- if(!!entities[id]) {
- result[type].push(entities[id]);
- }else{
- logger.error('AOI data error ! type : %j, id : %j', type, id);
- }
- }
- }
- return result;
-};
-
-exp.id = function() {
- return id;
+Instance.prototype.getEntitiesByPos = function(pos, types, range) {
+ var entities = this.entities;
+ var idsMap = this.aoi.getIdsByRange(pos, range, types);
+ var result = {};
+ for(var type in idsMap) {
+ if(type === 'npc' || type === 'item') continue;
+ if(!result[type]) {
+ result[type] = [];
+ }
+ for(var i = 0; i < idsMap[type].length; i++) {
+ var id = idsMap[type][i];
+ if(!!entities[id]) {
+ result[type].push(entities[id]);
+ }else{
+ logger.error('AOI data error ! type : %j, id : %j', type, id);
+ }
+ }
+ }
+ return result;
};
-exp.channel = function () {
- return getChannel();
-};
-
-exp.entities = function () {
- return entities;
-};
-
-exp.items = function() {
- return items;
-};
-
-exp.zones = function() {
- return zones;
-};
-
-exp.actionManager = function() {
- return actionManager;
-};
-
-exp.aiManager = function() {
- return aiManager;
-};
-
-exp.patrolManager = function() {
- return patrolManager;
-};
-
-exp.aoi = function() {
- return aoi;
-};
-
-exp.timer = function() {
- return timer;
-};
-
-exp.map = function() {
- return map;
-};
+Instance.prototype.isEmpty = function(){
+ return this.playerNum === 0;
+};
View
31 game-server/app/domain/area/instance.js
@@ -0,0 +1,31 @@
+var Area = require('./area');
+
+var Instance = function(opts){
+ this.id = opts.instanceId;
+ this.area = new Area(opts);
+ this.lifeTime = opts.lifeTime || 1800000;
+};
+
+module.exports = Instance;
+
+Instance.prototype.start = function(){
+ this.area.start();
+};
+
+Instance.prototype.close = function(){
+ this.area.close();
+};
+
+Instance.prototype.getArea = function(){
+ return this.area;
+};
+
+Instance.prototype.isAlive = function(){
+ if(this.area.isEmpty()){
+ if((Date.now() - this.area.emptyTime) > this.lifeTime){
+ return false;
+ }
+ }
+ return true;
+};
+
View
72 game-server/app/domain/area/instancePool.js
@@ -0,0 +1,72 @@
+var Instance = require('./instance');
+var dataApi = require('../../util/dataApi');
+var Map = require('../map/map');
+var pomelo = require('pomelo');
+
+var logger = require('pomelo-logger').getLogger(__filename);
+
+var exp = module.exports;
+
+var instances;
+var intervel;
+
+exp.init = function(opts){
+ instances = {};
+ intervel = opts.intervel||60000;
+
+ setInterval(check, intervel);
+};
+
+exp.create = function(params){
+ var id = params.instanceId;
+
+ if(instances[id]) return false;
+
+ var opts = dataApi.area.findById(params.areaId);
+
+ console.error('targe id : %j, opts : %j', params, opts);
+ opts.map = new Map(opts);
+ var instance = new Instance(opts);
+
+ instances[id] = instance;
+
+ instance.start();
+ return true;
+};
+
+exp.remove = function(params){
+ var id = params.id;
+ if(!instances[id]) return false;
+
+ var instance = instances[id];
+ instance.close();
+ delete instances[id];
+
+ return true;
+};
+
+exp.getArea = function(instanceId){
+ return instances[instanceId].area;
+};
+
+function check(){
+ var app = pomelo.app;
+ for(var id in instances){
+ var instance = instances[id];
+
+ if(!instance.isAlive()){
+ app.rpc.manager.instanceRemote.remove(null, id, onClose);
+ }
+ }
+}
+
+function onClose(err, id){
+ if(!err){
+ instances[id].close();
+ delete instances[id];
+ logger.info('remove instance : %j', id);
+ }else{
+ logger.warn('remove instance error! id : %j, err : %j', id, err);
+ }
+}
+
View
67 game-server/app/domain/area/manager.js
@@ -0,0 +1,67 @@
+var exp = module.exports;
+var pomelo = require('pomelo');
+var utils = require('../../util/utils');
+var dataApi = require('../../util/dataApi');
+var consts = require('../../consts/consts');
+
+var INSTANCE_ID = 'INSTANCE_';
+var INSTANCE_SERVER = 'area';
+var id = 1;
+
+var instances = {};
+var servers = [];
+
+exp.init = function(opts){
+ //Init instance server config
+ var areaServers = pomelo.app.servers[INSTANCE_SERVER];
+ for(var key in areaServers){
+ var server = areaServers[key];
+ if(server.instance){
+ servers.add(server);
+ }
+ }
+
+ //Load instance servers
+ var areas = dataApi.area.all();
+ for(var id in areas){
+ var area = areas[id];
+ //if(area.type === consts)
+ }
+};
+
+exp.createInstance = function(msg, session, cb){
+ var kindId = msg.kindId;
+
+
+ var app = pomelo.app;
+
+ //Check if the create request is valid
+
+ var instanceId = INSTANCE_ID + id++;
+
+ //Allocate a server id
+
+ //rpc invoke
+ var params = {
+ instanceId : instanceId,
+ outerId : session.playerId
+ };
+ app.rpc.area.instanceRemote.create(params, function(err, result){
+ if(!!err) utils.invokeCallback(err, result);
+
+ utils.invokeCallback(null, result);
+ });
+};
+
+exp.remove = function(msg){
+ var instanceId = msg.id;
+ var serverId = msg.serverId;
+
+ if(instances[instanceId]) delete instances[instanceId];
+};
+
+function filter(req){
+ var playerId = req.playerId;
+
+ return true;
+}
View
18 game-server/app/domain/area/scene.js
@@ -0,0 +1,18 @@
+var Area = require('./area');
+var Map = require('../map/map');
+
+var exp = module.exports;
+
+var area = null;
+
+exp.init = function(opts){
+ if(!area) {
+ opts.weightMap = true;
+ opts.map = new Map(opts);
+ area = new Area(opts);
+ }
+};
+
+exp.getArea = function(){
+ return area;
+};
View
90 game-server/app/domain/area/timer.js
@@ -1,86 +1,100 @@
-var area = require('./area');
var messageService = require('./../messageService');
var EntityType = require('../../consts/consts').EntityType;
var logger = require('pomelo-logger').getLogger(__filename);
-var exp = module.exports;
+var Timer = function(opts){
+ this.area = opts.area;
+ this.interval = opts.interval||100;
+};
+
+module.exports = Timer;
-exp.run = function () {
- setInterval(tick, 100);
+Timer.prototype.run = function () {
+ this.interval = setInterval(this.tick.bind(this), this.interval);
};
-function tick() {
+Timer.prototype.close = function () {
+ clearInterval(this.interval);
+};
+
+Timer.prototype.tick = function() {
+ var area = this.area;
+
//Update mob zones
- for(var key in area.zones()) {
- area.zones()[key].update();
+ for(var key in area.zones){
+ area.zones[key].update();
}
//Update all the items
- for(var id in area.items()) {
- var item = area.entities()[id];
+ for(var id in area.items) {
+ var item = area.entities[id];
item.update();
if(item.died) {
- messageService.pushMessage('onRemoveEntities', {entities: [id]});
+ area.channel.pushMessage('onRemoveEntities', {entities: [id]});
area.removeEntity(id);
}
}
//run all the action
- area.actionManager().update();
+ area.actionManager.update();
- area.aiManager().update();
+ area.aiManager.update();
- area.patrolManager().update();
-}
+ area.patrolManager.update();
+};
/**
* Add action for area
* @param action {Object} The action need to add
* @return {Boolean}
*/
-exp.addAction = function(action) {
- return area.actionManager().addAction(action);
+Timer.prototype.addAction = function(action) {
+ return this.area.actionManager.addAction(action);
};
/**
* Abort action for area
* @param type {Number} The type of the action
* @param id {Id} The id of the action
*/
-exp.abortAction = function(type, id) {
- return area.actionManager().abortAction(type, id);
+Timer.prototype.abortAction = function(type, id) {
+ return this.area.actionManager.abortAction(type, id);
};
/**
* Abort all action for a given id in area
* @param id {Number}
*/
-exp.abortAllAction = function(id) {
- area.actionManager().abortAllAction(id);
+Timer.prototype.abortAllAction = function(id) {
+ this.area.actionManager.abortAllAction(id);
};
/**
* Enter AI for given entity
* @param entityId {Number} entityId
*/
-exp.enterAI = function(entityId) {
- area.patrolManager().removeCharacter(entityId);
- exp.abortAction('move', entityId);
- if(!!area.entities()[entityId]) {
- area.aiManager().addCharacters([area.entities()[entityId]]);
+Timer.prototype.enterAI = function(entityId) {
+ var area = this.area;
+
+ area.patrolManager.removeCharacter(entityId);
+ this.abortAction('move', entityId);
+ if(!!area.entities[entityId]) {
+ area.aiManager.addCharacters([area.entities[entityId]]);
}
};
/**
* Enter patrol for given entity
* @param entityId {Number}
*/
-exp.patrol = function(entityId) {
- area.aiManager().removeCharacter(entityId);
+Timer.prototype.patrol = function(entityId) {
+ var area = this.area;
- if(!!area.entities()[entityId]) {
- area.patrolManager().addCharacters([{character: area.entities()[entityId], path: area.entities()[entityId].path}]);
+ area.aiManager.removeCharacter(entityId);
+
+ if(!!area.entities[entityId]) {
+ area.patrolManager.addCharacters([{character: area.entities[entityId], path: area.entities[entityId].path}]);
}
};
@@ -91,8 +105,8 @@ exp.patrol = function(entityId) {
* @param newPos {Object} New position.
* @return {Boolean} If the update success.
*/
-exp.updateObject = function(obj, oldPos, newPos) {
- return area.aoi().updateObject(obj, oldPos, newPos);
+Timer.prototype.updateObject = function(obj, oldPos, newPos) {
+ return this.area.aoi.updateObject(obj, oldPos, newPos);
};
/**
@@ -102,8 +116,10 @@ exp.updateObject = function(obj, oldPos, newPos) {
* @param ignoreList {Array} The ignore watchers' list.
* @return {Array} The qualified watchers id list.
*/
-exp.getWatcherUids = function(pos, types, ignoreList) {
- var watchers = area.aoi().getWatchers(pos, types);
+Timer.prototype.getWatcherUids = function(pos, types, ignoreList) {
+ var area = this.area;
+
+ var watchers = area.aoi.getWatchers(pos, types);
var result = [];
if(!!watchers && !! watchers[EntityType.PLAYER]) {
var pWatchers = watchers[EntityType.PLAYER];
@@ -124,8 +140,8 @@ exp.getWatcherUids = function(pos, types, ignoreList) {
* @param types {Array} Given watcher types.
* @return {Array} Watchers find by given parameters.
*/
-exp.getWatchers = function(pos, types) {
- return area.aoi().getWatchers(pos, types);
+Timer.prototype.getWatchers = function(pos, types) {
+ return this.area.aoi.getWatchers(pos, types);
};
/**
@@ -137,6 +153,6 @@ exp.getWatchers = function(pos, types) {
* @param newRange {Number} The new range of the watcher.
* @return Boolean If the update is success.
*/
-exp.updateWatcher = function(watcher, oldPos, newPos, oldRange, newRange) {
- return area.aoi().updateWatcher(watcher, oldPos, newPos, oldRange, newRange);
+Timer.prototype.updateWatcher = function(watcher, oldPos, newPos, oldRange, newRange) {
+ return this.area.aoi.updateWatcher(watcher, oldPos, newPos, oldRange, newRange);
};
View
16 game-server/app/domain/entity/character.js
@@ -8,7 +8,6 @@ var dataApi = require('../../util/dataApi');
var formula = require('../../consts/formula');
var consts = require('../../consts/consts');
var Entity = require('./entity');
-var area = require('./../area/area');
var fightskill = require('./../fightskill');
var logger = require('pomelo-logger').getLogger(__filename);
@@ -192,8 +191,9 @@ Character.prototype.recoverMp = function(mpValue) {
*/
Character.prototype.move = function(targetX, targetY, useCache, cb) {
useCache = useCache || false;
+
if(useCache){
- var paths = area.map().findPath(this.x, this.y, targetX, targetY, useCache);
+ var paths = this.area.map.findPath(this.x, this.y, targetX, targetY, useCache);
if(!!paths){
this.emit('move', {character: this, paths: paths});
@@ -209,7 +209,7 @@ Character.prototype.move = function(targetX, targetY, useCache, cb) {
closure.emit('move', {character: closure, paths: paths});
utils.invokeCallback(cb, null, true);
}else{
- logger.warn('No path exist! {x: %j, y: %j} , target: {x: %j, y: %j} ', closure.x, closure.y, targetX, targetY);
+ logger.warn('Remote find path failed! No path exist! {x: %j, y: %j} , target: {x: %j, y: %j} ', closure.x, closure.y, targetX, targetY);
utils.invokeCallback(cb, 'find path error', false);
}
});
@@ -240,7 +240,13 @@ Character.prototype.attack = function(target, skillId) {
this.addEnemy(target.entityId);
var result = skill.use(this, target);
- this.emit('attack', {areaId : target.areaId, attackerId : this.entityId, targetId: target.entityId, skillId: skillId, result: result});
+ this.emit('attack', {
+ attacker : this,
+ target: target,
+ skillId: skillId,
+ result: result
+ });
+
return result;
};
@@ -352,7 +358,7 @@ Character.prototype.removeBuff = function(buff) {
Character.prototype.forEachEnemy = function(callback) {
var enemy;
for(var enemyId in this.enemies) {
- enemy = area.getEntity(enemyId);
+ enemy = this.area.getEntity(enemyId);
if(!enemy) {
delete this.enemies[enemyId];
continue;
View
2 game-server/app/domain/entity/entity.js
@@ -26,7 +26,7 @@ var Entity = function(opts) {
this.y = opts.y;
this.areaId = Number(opts.areaId || 1);
-
+ this.area = opts.area;
};
util.inherits(Entity, EventEmitter);
View
36 game-server/app/domain/entity/equipment.js
@@ -1,5 +1,5 @@
/**
- * Module dependencies
+ * Module dependencies
*/
var util = require('util');
var Entity = require('./entity');
@@ -17,18 +17,18 @@ var EntityType = require('../../consts/consts').EntityType;
var Equipment = function(opts) {
Entity.call(this, opts);
this.type = EntityType.EQUIPMENT;
- this.name = opts.name;
- this.desc = opts.desc;
- this.englishDesc = opts.englishDesc;
- this.kind = opts.kind;
- this.attackValue = Number(opts.attackValue);
- this.defenceValue = Number(opts.defenceValue);
- this.price = opts.price;
- this.color = opts.color;
- this.heroLevel = opts.heroLevel;
- this.imgId = opts.imgId;
+ this.name = opts.name;
+ this.desc = opts.desc;
+ this.englishDesc = opts.englishDesc;
+ this.kind = opts.kind;
+ this.attackValue = Number(opts.attackValue);
+ this.defenceValue = Number(opts.defenceValue);
+ this.price = opts.price;
+ this.color = opts.color;
+ this.heroLevel = opts.heroLevel;
+ this.imgId = opts.imgId;
this.playerId = opts.playerId;
-
+
this.lifetime = 30000;
this.time = Date.now();
this.died = false;
@@ -49,9 +49,19 @@ module.exports = Equipment;
Equipment.prototype.update = function(){
var next = Date.now();
this.lifetime -= (next - this.time);
-
+
this.time = next;
if(this.lifetime <= 0) {
this.died = true;
}
};
+
+Equipment.prototype.toJSON = function() {
+ return {
+ entityId: this.entityId,
+ kindId: this.kindId,
+ x: this.x,
+ y: this.y,
+ playerId: this.playerId
+ };
+};
View
10 game-server/app/domain/entity/item.js
@@ -49,3 +49,13 @@ Item.prototype.update = function(){
this.died = true;
}
};
+
+Item.prototype.toJSON = function() {
+ return {
+ entityId: this.entityId,
+ kindId: this.kindId,
+ x: this.x,
+ y: this.y,
+ playerId: this.playerId
+ };
+};
View
12 game-server/app/domain/entity/mob.js
@@ -9,8 +9,6 @@ var Character = require('./character');
var dataApi = require('../../util/dataApi');
var Item = require('./item');
var Equipment = require('./equipment');
-var area = require('./../area/area');
-var timer = require('./../area/timer');
var fightSkill = require('./../fightskill');
var logger = require('pomelo-logger').getLogger(__filename);
@@ -105,7 +103,7 @@ Mob.prototype.increaseHateFor = function(entityId, points) {
this.haters[entityId] = points;
}
this.target = this.getMostHater();
- timer.enterAI(this.entityId);
+ this.area.timer.enterAI(this.entityId);
};
//Get the most hater
@@ -141,7 +139,7 @@ Mob.prototype.forgetHater = function(entityId) {
Mob.prototype.forEachHater = function(cb) {
for(var id in this.haters){
- var hater = area.getEntity(id);
+ var hater = this.area.getEntity(id);
if(hater){
cb(hater);
} else {
@@ -152,7 +150,7 @@ Mob.prototype.forEachHater = function(cb) {
//Increase hate for the player who is coming.
Mob.prototype.onPlayerCome = function(entityId) {
- var player = area.getEntity(entityId);
+ var player = this.area.getEntity(entityId);
//Only hit a live person
if(!!player && !player.died){
@@ -192,7 +190,7 @@ Mob.prototype.dropItems = function(player) {
//Drop Item down
Mob.prototype._dropItem = function(player) {
var level = Math.min(this.level, player.level);
- var pos = area.map().genPos(this, 200);
+ var pos = this.area.map.genPos(this, 200);
if(!pos){
logger.warn('Generate position for drop item error!');
return null;
@@ -226,7 +224,7 @@ Mob.prototype._dropItem = function(player) {
Mob.prototype._dropEquipment = function(player) {
var level = formula.dropItemLv(this.level, player.level);
- var pos = area.map().genPos(this, 200);
+ var pos = this.area.map.genPos(this, 200);
if(!pos){
logger.warn('Generate position for drop equipment error!');
return null;
View
23 game-server/app/domain/entity/npc.js
@@ -9,7 +9,6 @@ var TraverseTask = require('../../consts/consts').TraverseTask;
var consts = require('../../consts/consts');
var formula = require('../../consts/formula');
var executeTask = require('./../executeTask');
-var area = require('../area/area');
var messageService = require('../messageService');
var TaskDao = require('../../dao/taskDao');
@@ -53,7 +52,7 @@ Npc.prototype.talk = function(player) {
return {result: consts.NPC.NOT_IN_RANGE, distance: TALK_RANGE};
}
- this.emit('onNPCTalk', {npc: this.entityId, player : player.entityId});
+ this.emit('onNPCTalk', {npc: this, player : player});
return {result: consts.NPC.SUCCESS};
};
@@ -67,19 +66,20 @@ Npc.prototype.talk = function(player) {
* @api public
*/
Npc.prototype.traverse = function(route, msg) {
- var player = area.getEntity(msg.player);
+ var player = this.area.getEntity(msg.player);
//If don't need task test, just change area.
if (!TraverseTask[msg.kindId]){
- changeArea(route, msg);
+ this.changeArea(route, msg);
return;
}
+
TaskDao.getTaskByIds(player.id, TraverseTask[msg.kindId], function(err, tasks) {
if (tasks && tasks.length > 0) {
var task = tasks[0];
//For test only
task.taskState = consts.TaskState.COMPLETED;
if (task.taskState === consts.TaskState.COMPLETED) {
- changeArea(route, msg);
+ this.changeArea(route, msg);
} else {
messageService.pushMessageToPlayer({uid:player.userId, sid : player.serverId}, route, msg);
}
@@ -89,8 +89,17 @@ Npc.prototype.traverse = function(route, msg) {
});
};
-var changeArea = function(route, msg) {
- var player = area.getEntity(msg.player);
+Npc.prototype.toJSON = function() {
+ return {
+ entityId: this.entityId,
+ kindId: this.kindId,
+ x: this.x,
+ y: this.y
+ };
+};
+
+Npc.prototype.changeArea = function(route, msg) {
+ var player = this.area.getEntity(msg.player);
msg.action = 'changeArea';
msg.params = {target : TraverseNpc[msg.kindId]};
messageService.pushMessageToPlayer({uid: player.userId, sid: player.serverId}, route, msg);
View
11 game-server/app/domain/entity/player.js
@@ -13,7 +13,6 @@ var fightskillDao = require('../../dao/fightskillDao');
var taskDao = require('../../dao/taskDao');
var fightskill = require('./../fightskill');
var logger = require('pomelo-logger').getLogger(__filename);
-var area = require('./../area/area');
/**
* Initialize a new 'Player' with the given 'opts'.
@@ -162,7 +161,7 @@ Player.prototype.unEquip = function(kind) {
*/
Player.prototype.useItem = function(index) {
var item = this.bag.get(index);
- if (!item || item.type != 'item') {
+ if (!item || item.type !== 'item') {
return false;
}
var itm = dataApi.item.findById(item.id);
@@ -221,7 +220,7 @@ Player.prototype.upgradeSkill = function(skillId) {
* @api public
*/
Player.prototype.pickItem = function(entityId) {
- var item = area.getEntity(entityId);
+ var item = this.area.getEntity(entityId);
var result = {player : this, item : item};
@@ -397,7 +396,7 @@ Player.prototype.getMostHater = function() {
if(entityId <= 0) {
return null;
}
- return area.getEntity(entityId);
+ return this.area.getEntity(entityId);
};
// Forget the hater
@@ -418,7 +417,7 @@ Player.prototype.forgetHater = function(entityId) {
*/
Player.prototype.forEachHater = function(cb) {
for(var id in this.haters) {
- var hater = area.getEntity(id);
+ var hater = this.area.getEntity(id);
if(hater) {
cb(hater);
} else {
@@ -430,7 +429,7 @@ Player.prototype.forEachHater = function(cb) {
Player.prototype.setEquipments = function(equipments){
this.equipments = equipments;
this.setTotalAttackAndDefence();
-}
+};
/**
* Get part of curTasks information.
View
34 game-server/app/domain/event/characterEvent.js
@@ -1,6 +1,4 @@
-var area = require('./../area/area');
var messageService = require('./../messageService');
-var timer = require('./../area/timer');
var api = require('../../util/dataApi');
var Move = require('./../action/move');
var consts = require('../../consts/consts');
@@ -20,6 +18,7 @@ exp.addEventForCharacter = function(character) {
*/
character.on('move', function(args){
var character = args.character;
+ var area = character.area;
var speed = character.walkSpeed;
var paths = args.paths;
var action = new Move({
@@ -29,8 +28,8 @@ exp.addEventForCharacter = function(character) {
});
//Add move action to action manager
- if(timer.addAction(action)){
- messageService.pushMessageByAOI({
+ if(area.timer.addAction(action)){
+ messageService.pushMessageByAOI(area, {
route: 'onMove',
entityId: character.entityId,
path: paths.path,
@@ -44,8 +43,10 @@ exp.addEventForCharacter = function(character) {
*/
character.on('attack', function(args){
var result = args.result;
- var attacker = area.getEntity(args.attackerId);
- var target = area.getEntity(args.targetId);
+ var attacker = args.attacker;
+ var target = args.target;
+ var area = target.area;
+ var timer = area.timer;
var attackerPos = {x: attacker.x, y: attacker.y};
//Print an error when attacker or target not exist, this should not happened!
@@ -55,12 +56,12 @@ exp.addEventForCharacter = function(character) {
}