Browse Source

fixes #781

tags/v0.2.1^2
Big Bad Waffle 5 years ago
parent
commit
00bb3ea141
24 changed files with 146 additions and 516 deletions
  1. +3
    -1
      src/client/.eslintrc
  2. +0
    -2
      src/client/js/components/attackAnimation.js
  3. +0
    -2
      src/client/js/components/chatter.js
  4. +0
    -2
      src/client/js/components/effects.js
  5. +0
    -2
      src/client/js/components/light.js
  6. +0
    -3
      src/client/js/components/lightPatch.js
  7. +0
    -2
      src/client/js/components/mouseMover.js
  8. +0
    -2
      src/client/js/components/particles.js
  9. +0
    -2
      src/client/js/components/pather.js
  10. +0
    -2
      src/client/js/components/player.js
  11. +0
    -2
      src/client/js/components/projectile.js
  12. +0
    -2
      src/client/js/components/spellbook.js
  13. +0
    -2
      src/client/js/components/stats.js
  14. +4
    -1
      src/client/js/misc/helpers.js
  15. +0
    -3
      src/client/js/objects/objBase.js
  16. +0
    -2
      src/client/js/objects/objects.js
  17. +0
    -3
      src/client/js/rendering/lightningBuilder.js
  18. +0
    -3
      src/client/js/rendering/numbers.js
  19. +0
    -2
      src/client/js/rendering/renderer.js
  20. +7
    -0
      src/server/misc/helpers.js
  21. +128
    -470
      src/server/world/instancer.js
  22. +0
    -3
      src/server/world/map.js
  23. +1
    -1
      src/server/world/physics.js
  24. +3
    -2
      src/server/world/randomMap.js

+ 3
- 1
src/client/.eslintrc View File

@@ -53,7 +53,9 @@
"$": false,
"define": false,
"_": false,
"PIXI": false
"PIXI": false,
"scale": false,
"scaleMult": false
},

"rules": {


+ 0
- 2
src/client/js/components/attackAnimation.js View File

@@ -5,8 +5,6 @@ define([
effects,
renderer
) {
let scale = 40;

return {
type: 'attackAnimation',



+ 0
- 2
src/client/js/components/chatter.js View File

@@ -3,8 +3,6 @@ define([
], function (
renderer
) {
let scale = 40;

return {
type: 'chatter',



+ 0
- 2
src/client/js/components/effects.js View File

@@ -3,8 +3,6 @@ define([
], function (
renderer
) {
let scale = 40;

let auras = {
reflectDamage: 0,
stealth: 1,


+ 0
- 2
src/client/js/components/light.js View File

@@ -5,8 +5,6 @@ define([
effects,
renderer
) {
let scale = 40;

return {
type: 'light',



+ 0
- 3
src/client/js/components/lightPatch.js View File

@@ -5,9 +5,6 @@ define([
renderer,
picture
) {
let scale = 40;
let scaleMult = 5;

return {
type: 'lightPatch',



+ 0
- 2
src/client/js/components/mouseMover.js View File

@@ -11,8 +11,6 @@ define([
input,
objects
) {
let scale = 40;

return {
type: 'mouseMover',



+ 0
- 2
src/client/js/components/particles.js View File

@@ -3,8 +3,6 @@ define([
], function (
renderer
) {
let scale = 40;

return {
type: 'particles',
emitter: null,


+ 0
- 2
src/client/js/components/pather.js View File

@@ -5,8 +5,6 @@ define([
renderer,
events
) {
let scale = 40;
let scaleMult = 5;
let round = Math.round.bind(Math);
let maxPathLength = 50;



+ 0
- 2
src/client/js/components/player.js View File

@@ -9,8 +9,6 @@ define([
physics,
sound
) {
let scale = 40;

return {
type: 'player',



+ 0
- 2
src/client/js/components/projectile.js View File

@@ -3,8 +3,6 @@ define([
], function (
effects
) {
let scale = 40;

return {
type: 'projectile',



+ 0
- 2
src/client/js/components/spellbook.js View File

@@ -7,8 +7,6 @@ define([
renderer,
events
) {
let scale = 40;

let objects = null;
require(['js/objects/objects'], function (o) {
objects = o;


+ 0
- 2
src/client/js/components/stats.js View File

@@ -5,8 +5,6 @@ define([
events,
renderer
) {
let scale = 40;

return {
type: 'stats',



+ 4
- 1
src/client/js/misc/helpers.js View File

@@ -1,4 +1,7 @@
/* global _ */
/* global _, scale, scaleMult */

window.scale = 40;
window.scaleMult = 5;

//eslint-disable-next-line no-extend-native
Array.prototype.firstIndex = function (callback, thisArg) {


+ 0
- 3
src/client/js/objects/objBase.js View File

@@ -7,9 +7,6 @@ define([
renderer,
events
) {
let scale = 40;
let scaleMult = 5;

return {
components: [],
offsetX: 0,


+ 0
- 2
src/client/js/objects/objects.js View File

@@ -9,8 +9,6 @@ define([
renderer,
sound
) {
let scale = 40;

return {
showNames: false,



+ 0
- 3
src/client/js/rendering/lightningBuilder.js View File

@@ -5,9 +5,6 @@ define([
renderer,
picture
) {
let scale = 40;
let scaleMult = 5;

return {
build: function (config) {
let obj = {


+ 0
- 3
src/client/js/rendering/numbers.js View File

@@ -7,9 +7,6 @@ define([
objects,
renderer
) {
let scale = 40;
let scaleMult = 5;

return {
list: [],



+ 0
- 2
src/client/js/rendering/renderer.js View File

@@ -19,8 +19,6 @@ define([
spritePool,
picture
) {
let scale = 40;
let scaleMult = 5;
let pixi = PIXI;

return {


+ 7
- 0
src/server/misc/helpers.js View File

@@ -125,6 +125,13 @@ module.exports = {
return o;
},

getGuid: function () {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
let r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
},

//Only use this method for official logging. Temporary logs should use console.log
// so those instances can be reported by eslint
log: function (msg) {


+ 128
- 470
src/server/world/instancer.js View File

@@ -28,514 +28,172 @@ module.exports = {
herbs.init();
map.init(args);

if (!map.instanced) {
let fakeInstance = {
objects: objects,
syncer: syncer,
physics: physics,
zoneId: this.zoneId,
spawners: spawners,
questBuilder: questBuilder,
events: events,
zone: map.zone,
mail: mail,
let fakeInstance = {
objects: objects,
syncer: syncer,
physics: physics,
zoneId: this.zoneId,
spawners: spawners,
questBuilder: questBuilder,
events: events,
zone: map.zone,
mail: mail,
map: map,
scheduler: scheduler,
eventEmitter: eventEmitter
};

this.instances.push(fakeInstance);

spawners.init(fakeInstance);
scheduler.init();

map.create();
if (map.mapFile.properties.isRandom) {
if (!map.oldCollisionMap)
map.oldCollisionMap = map.collisionMap;

randomMap.generate({
map: map,
scheduler: scheduler,
eventEmitter: eventEmitter
};

this.instances.push(fakeInstance);

spawners.init(fakeInstance);
scheduler.init();

map.create();
map.clientMap.zoneId = this.zoneId;

[resourceSpawner, syncer, objects, questBuilder, events, mail].forEach(i => i.init(fakeInstance));

this.addObject = this.nonInstanced.addObject.bind(this);
this.onAddObject = this.nonInstanced.onAddObject.bind(this);
this.updateObject = this.nonInstanced.updateObject.bind(this);
this.queueAction = this.nonInstanced.queueAction.bind(this);
this.performAction = this.nonInstanced.performAction.bind(this);
this.removeObject = this.nonInstanced.removeObject.bind(this);

this.tick = this.nonInstanced.tick.bind(this);
this.tick();
} else {
spawners.init({
zone: map.zone
physics: physics,
spawners: spawners
});

map.create();
map.clientMap.zoneId = this.zoneId;

this.addObject = this.instanced.addObject.bind(this);
this.onAddObject = this.instanced.onAddObject.bind(this);
this.updateObject = this.instanced.updateObject.bind(this);
this.queueAction = this.instanced.queueAction.bind(this);
this.performAction = this.instanced.performAction.bind(this);
this.removeObject = this.instanced.removeObject.bind(this);

if (map.mapFile.properties.isRandom)
this.ttlGen = 0;

this.tick = this.instanced.tick.bind(this);
this.tick();
map.seed = _.getGuid();
}
},

nonInstanced: {
tick: function () {
events.update();
objects.update();
resourceSpawner.update();
spawners.update();
syncer.update();
scheduler.update();

setTimeout(this.tick.bind(this), this.speed);
},

addObject: function (msg) {
let obj = msg.obj;
obj.serverId = obj.id;
delete obj.id;

if ((msg.keepPos) && (!physics.isValid(obj.x, obj.y)))
msg.keepPos = false;

let spawnPos = map.getSpawnPos(obj);

if (!msg.keepPos || !obj.has('x')) {
obj.x = spawnPos.x;
obj.y = spawnPos.y;
}

obj.spawn = map.spawn;

syncer.queue('onGetMap', map.clientMap, [obj.serverId]);
map.clientMap.zoneId = this.zoneId;

if (!msg.transfer)
objects.addObject(obj, this.onAddObject.bind(this));
else {
let o = objects.transferObject(obj);
questBuilder.obtain(o);
}
},
onAddObject: function (obj) {
if (obj.player)
obj.stats.onLogin();

questBuilder.obtain(obj);
obj.fireEvent('afterMove');

if (obj.dead) {
obj.instance.syncer.queue('onDeath', {
x: obj.x,
y: obj.y
}, [obj.serverId]);
}
},
updateObject: function (msg) {
let obj = objects.find(o => o.serverId === msg.id);
if (!obj)
return;
[resourceSpawner, syncer, objects, questBuilder, events, mail].forEach(i => i.init(fakeInstance));

let msgObj = msg.obj;

let components = msgObj.components || [];
delete msgObj.components;
this.tick();
},

for (let p in msgObj)
obj[p] = msgObj[p];
tick: function () {
events.update();
objects.update();
resourceSpawner.update();
spawners.update();
syncer.update();
scheduler.update();

let cLen = components.length;
for (let i = 0; i < cLen; i++) {
let c = components[i];
let component = obj[c.type];
for (let p in c)
component[p] = c[p];
}
},
setTimeout(this.tick.bind(this), this.speed);
},

queueAction: function (msg) {
let obj = objects.find(o => o.serverId === msg.id);
if (!obj)
return;
else if (msg.action.action === 'move') {
let moveEntries = obj.actionQueue.filter(q => (q.action === 'move')).length;
if (moveEntries >= 50)
return;
}
addObject: function (msg) {
let obj = msg.obj;
obj.serverId = obj.id;
delete obj.id;

obj.queue(msg.action);
},

performAction: function (msg) {
let obj = null;
let targetId = msg.action.targetId;
if (!targetId)
obj = objects.find(o => o.serverId === msg.id);
else {
obj = objects.find(o => o.id === targetId);
if (obj) {
let action = msg.action;
if (!action.data)
action.data = {};
action.data.sourceId = msg.id;
}
}
if ((msg.keepPos) && (!physics.isValid(obj.x, obj.y)))
msg.keepPos = false;

if (!obj)
return;
let spawnPos = map.getSpawnPos(obj);

obj.performAction(msg.action);
},
if (!msg.keepPos || !obj.has('x') || (map.mapFile.properties.isRandom && obj.instanceId !== map.seed)) {
obj.x = spawnPos.x;
obj.y = spawnPos.y;
}

removeObject: function (msg) {
let obj = msg.obj;
obj = objects.find(o => o.serverId === obj.id);
if (!obj) {
//We should probably never reach this
return;
}
obj.instanceId = map.seed;

if (obj.auth)
obj.auth.doSave();
obj.spawn = map.spawn;

if (obj.player)
obj.fireEvent('beforeRezone');
syncer.queue('onGetMap', map.clientMap, [obj.serverId]);

obj.destroyed = true;
if (!msg.transfer)
objects.addObject(obj, this.onAddObject.bind(this));
else {
let o = objects.transferObject(obj);
questBuilder.obtain(o);
}
},
instanced: {
tick: function () {
if (map.mapFile.properties.isRandom) {
if (this.ttlGen <= 0) {
if (!map.oldMap)
map.oldMap = map.clientMap.map;
if (!map.oldCollisionMap)
map.oldCollisionMap = map.collisionMap;

spawners.reset();

randomMap.generate({
map: map,
physics: physics,
spawners: spawners
});

this.ttlGen = 2000;
} else
this.ttlGen--;
}

let instances = this.instances;
let iLen = instances.length;
for (let i = 0; i < iLen; i++) {
let instance = instances[i];

instance.objects.update();
instance.spawners.update();
instance.resourceSpawner.update();
instance.scheduler.update();

instance.syncer.update();

if (instance.closeTtl) {
let hasPlayers = instance.objects.objects.some(o => o.player);
if (hasPlayers) {
delete instance.closeTtl;
continue;
}

instance.closeTtl--;
if (instance.closeTtl <= 0) {
instances.splice(i, 1);
i--;
iLen--;
}
} else {
let isEmpty = !instance.objects.objects.some(o => o.player);
if (isEmpty) {
//Zones reset after being empty for 2 minutes (about 342 ticks)
instance.closeTtl = 342;
}
}
}

setTimeout(this.tick.bind(this), this.speed);
},

addObject: function (msg) {
let obj = msg.obj;
let instanceId = msg.instanceId;

//Maybe a party member is in here already?
let social = obj.components.find(c => c.type === 'social');
if ((social) && (social.party)) {
let party = social.party;
let instances = this.instances;
let iLen = instances.length;
for (let i = 0; i < iLen; i++) {
let instance = instances[i];

let partyInside = instance.objects.objects.some(o => party.indexOf(o.serverId) > -1);
if (partyInside) {
if (instance.id !== obj.instanceId)
msg.keepPos = false;
obj.instanceId = instance.id;
obj.instance = instance;
instanceId = instance.id;
break;
}
}
}
onAddObject: function (obj) {
if (obj.player)
obj.stats.onLogin();

if (msg.transfer)
msg.keepPos = false;
questBuilder.obtain(obj);
obj.fireEvent('afterMove');

let exists = this.instances.find(i => i.id === instanceId);

if (exists) {
if ((msg.keepPos) && (!exists.physics.isValid(obj.x, obj.y)))
msg.keepPos = false;
}

let spawnPos = map.getSpawnPos(obj);

if (exists)
spawnPos = exists.map.getSpawnPos(obj);

if (!msg.keepPos || !obj.has('x')) {
obj.x = spawnPos.x;
obj.y = spawnPos.y;
}

obj.spawn = map.spawn;

if (exists) {
//Keep track of what the connection id is (sent from the server)
obj.serverId = obj.id;
delete obj.id;

obj.spawn = exists.map.spawn;

exists.syncer.queue('onGetMap', exists.map.clientMap, [obj.serverId]);

if (!msg.transfer)
exists.objects.addObject(obj, this.onAddObject.bind(this, msg.keepPos));
else {
let newObj = exists.objects.transferObject(obj);
this.onAddObject(false, newObj);
}

process.send({
method: 'object',
serverId: obj.serverId,
obj: {
instanceId: exists.id
}
});
} else
obj = this.instanced.createInstance.call(this, obj, msg.transfer);
},
onAddObject: function (keepPos, obj) {
if (!keepPos) {
let spawnPos = obj.instance.map.getSpawnPos(obj);

obj.x = spawnPos.x;
obj.y = spawnPos.y;
}

obj.instance.questBuilder.obtain(obj);

if (obj.player)
obj.stats.onLogin();

obj.fireEvent('afterMove');

if (obj.dead) {
obj.instance.syncer.queue('onDeath', {
x: obj.x,
y: obj.y
}, [obj.serverId]);
}
},
updateObject: function (msg) {
let id = msg.id;
let instanceId = msg.instanceId;

let exists = this.instances.find(i => i.id === instanceId);
if (!exists)
return;

let obj = exists.objects.find(o => o.serverId === id);
if (!obj)
return;
if (obj.dead) {
obj.instance.syncer.queue('onDeath', {
x: obj.x,
y: obj.y
}, [obj.serverId]);
}
},

let msgObj = msg.obj;
updateObject: function (msg) {
let obj = objects.find(o => o.serverId === msg.id);
if (!obj)
return;

let components = msgObj.components || [];
delete msgObj.components;
let msgObj = msg.obj;

for (let p in msgObj)
obj[p] = msgObj[p];
let components = msgObj.components || [];
delete msgObj.components;

let cLen = components.length;
for (let i = 0; i < cLen; i++) {
let c = components[i];
let component = obj[c.type];
for (let p in c)
component[p] = c[p];
}
},
for (let p in msgObj)
obj[p] = msgObj[p];

performAction: function (msg) {
let id = msg.id;
let instanceId = msg.instanceId;

let exists = this.instances.find(i => i.id === instanceId);
if (!exists)
return;
let cLen = components.length;
for (let i = 0; i < cLen; i++) {
let c = components[i];
let component = obj[c.type];
for (let p in c)
component[p] = c[p];
}
},

let obj = exists.objects.find(o => o.serverId === id);
if (!obj)
queueAction: function (msg) {
let obj = objects.find(o => o.serverId === msg.id);
if (!obj)
return;
else if (msg.action.action === 'move') {
let moveEntries = obj.actionQueue.filter(q => (q.action === 'move')).length;
if (moveEntries >= 50)
return;
}

obj.performAction(msg.action);
},

queueAction: function (msg) {
let id = msg.id;
let instanceId = msg.instanceId;

let exists = this.instances.find(i => i.id === instanceId);
if (!exists)
return;
obj.queue(msg.action);
},

let obj = exists.objects.find(o => o.serverId === id);
performAction: function (msg) {
let obj = null;
let targetId = msg.action.targetId;
if (!targetId)
obj = objects.find(o => o.serverId === msg.id);
else {
obj = objects.find(o => o.id === targetId);
if (obj) {
if (msg.action.action === 'move') {
let moveEntries = obj.actionQueue.filter(q => (q.action === 'move')).length;
if (moveEntries >= 50)
return;
}

obj.queue(msg.action);
let action = msg.action;
if (!action.data)
action.data = {};
action.data.sourceId = msg.id;
}
},

removeObject: function (msg) {
let obj = msg.obj;
let instanceId = msg.instanceId;

let exists = this.instances.find(i => i.id === instanceId);
if (!exists)
return;
}

obj = exists.objects.find(o => o.serverId === obj.id);
if (!obj)
return;

if (!obj)
return;
obj.performAction(msg.action);
},

if (obj.auth)
obj.auth.doSave();

obj.destroyed = true;
},

createInstance: function (objToAdd, transfer) {
let newMap = {
name: map.name,
spawn: extend([], map.spawn),
clientMap: extend({}, map.clientMap)
};
newMap.getSpawnPos = map.getSpawnPos.bind(newMap);

//Hack: We need to actually just always use the instanced eventEmitter
let eventQueue = eventEmitter.queue;
delete eventEmitter.queue;
let newEventEmitter = extend({
queue: []
}, eventEmitter);
eventEmitter.queue = eventQueue;

let instance = {
id: objToAdd.name + '_' + (+new Date()),
objects: extend({}, objects),
spawners: extend({}, spawners),
syncer: extend({}, syncer),
physics: extend({}, physics),
resourceSpawner: extend({}, resourceSpawner),
zoneId: this.zoneId,
zone: map.zone,
closeTtl: null,
questBuilder: extend({}, questBuilder),
events: extend({}, events),
scheduler: extend({}, scheduler),
mail: extend({}, mail),
map: newMap,
eventEmitter: newEventEmitter,
instanced: true
};

['objects', 'spawners', 'syncer', 'resourceSpawner', 'questBuilder', 'events', 'scheduler', 'mail'].forEach(i => instance[i].init(instance));

this.instances.push(instance);

let onDone = this.instanced.onCreateInstance.bind(this, instance, objToAdd, transfer);

if (map.custom) {
instance.customMap = extend({}, customMap);
instance.customMap.load(instance, objToAdd, onDone);
} else
onDone();
},
onCreateInstance: function (instance, objToAdd, transfer) {
objToAdd.instance = instance;
objToAdd.instanceId = instance.id;

//Keep track of what the connection id is (sent from the server)
objToAdd.serverId = objToAdd.id;
delete objToAdd.id;

let obj = null;

instance.syncer.queue('onGetMap', instance.map.clientMap, [objToAdd.serverId]);

if (!transfer)
obj = instance.objects.addObject(objToAdd, this.onAddObject.bind(this, false));
else {
obj = instance.objects.transferObject(objToAdd);

let spawnPos = instance.map.getSpawnPos(obj);

obj.x = spawnPos.x;
obj.y = spawnPos.y;

instance.questBuilder.obtain(obj);
}
removeObject: function (msg) {
let obj = msg.obj;
obj = objects.find(o => o.serverId === obj.id);
if (!obj) {
//We should probably never reach this
return;
}

process.send({
method: 'object',
serverId: obj.serverId,
obj: {
instanceId: instance.id
}
});
if (obj.auth)
obj.auth.doSave();

if (obj.dead) {
obj.instance.syncer.queue('onDeath', {
x: obj.x,
y: obj.y
}, [obj.serverId]);
}
if (obj.player)
obj.fireEvent('beforeRezone');

return obj;
}
obj.destroyed = true;
}
};

+ 0
- 3
src/server/world/map.js View File

@@ -86,10 +86,7 @@ module.exports = {
this.mapFile.properties = this.mapFile.properties || {};
mapScale = mapFile.tilesets[0].tileheight;

this.instanced = mapFile.properties.instanced;
this.custom = mapFile.properties.custom;
if (this.instanced)
this.instanced = (this.instanced === '1');

if (mapFile.properties.spawn) {
this.spawn = JSON.parse(mapFile.properties.spawn);


+ 1
- 1
src/server/world/physics.js View File

@@ -315,7 +315,7 @@ module.exports = {

let node = this.graph.grid[x][y];
if (node)
return node.isWall();
return (node.weight === 0);
return true;
},
isCellOpen: function (x, y) {


+ 3
- 2
src/server/world/randomMap.js View File

@@ -5,7 +5,7 @@ module.exports = {
rooms: [],
exitAreas: [],

maxDistance: 12,
maxDistance: 14,
minDistance: 0,

bounds: [0, 0, 0, 0],
@@ -374,7 +374,8 @@ module.exports = {
this.updateBounds(room);

if (room.distance < this.maxDistance) {
let count = this.randInt(1, room.template.exits.length);
const maxExits = room.template.exits.length;
let count = this.randInt(Math.min(maxExits, 2), maxExits);
for (let i = 0; i < count; i++)
this.setupConnection(room, !isHallway);
}


Loading…
Cancel
Save