Ver a proveniência

polygon notices and map sound defs

tags/v0.3.0
big bad waffle há 6 anos
ascendente
cometimento
55894d7ed5
12 ficheiros alterados com 259 adições e 451 eliminações
  1. +2
    -1
      src/client/js/components/components.js
  2. +18
    -0
      src/client/js/components/sound.js
  3. +17
    -395
      src/client/js/misc/physics.js
  4. +2
    -2
      src/client/js/objects/objects.js
  5. +53
    -32
      src/client/js/sound/sound.js
  6. +20
    -0
      src/server/components/sound.js
  7. +10
    -8
      src/server/config/maps/dungeon/map.json
  8. +33
    -7
      src/server/config/maps/dungeon/zone.js
  9. +1
    -2
      src/server/objects/objBase.js
  10. +4
    -1
      src/server/objects/objects.js
  11. +62
    -1
      src/server/world/map.js
  12. +37
    -2
      src/server/world/physics.js

+ 2
- 1
src/client/js/components/components.js Ver ficheiro

@@ -32,7 +32,8 @@ var components = [
'reputation',
'serverActions',
'social',
'passives'
'passives',
'sound'
].map(function (c) {
return 'js/components/' + c;
});


+ 18
- 0
src/client/js/components/sound.js Ver ficheiro

@@ -0,0 +1,18 @@
define([
'js/sound/sound'
], function (
sound
) {
return {
type: 'sound',

sound: null,
volume: 0,

init: function () {
var obj = this.obj;
console.log(this.obj);
sound.addSound(obj.zoneId, this.sound, this.volume, obj.x, obj.y, obj.width, obj.height, obj.area);
}
};
});

+ 17
- 395
src/client/js/misc/physics.js Ver ficheiro

@@ -3,10 +3,6 @@ define([
], function (
pathfinder
) {
var sqrt = Math.sqrt.bind(Math);
var ceil = Math.ceil.bind(Math);
var random = Math.random.bind(Math);

return {
graph: null,

@@ -28,233 +24,6 @@ define([
});
},

addRegion: function (obj) {
var lowX = obj.x;
var lowY = obj.y;
var highX = lowX + obj.width;
var highY = lowY + obj.height;
var cells = this.cells;

for (var i = lowX; i <= highX; i++) {
var row = cells[i];
for (var j = lowY; j <= highY; j++) {
row[j].push(obj);
}
}
},

addObject: function (obj, x, y, fromX, fromY) {
var row = this.cells[x];

if (!row)
return;

var cell = row[y];

if (!cell)
return;

var cLen = cell.length;
for (var i = 0; i < cLen; i++) {
var c = cell[i];

//If we have fromX and fromY, check if the target cell doesn't contain the same obj (like a notice area)
if ((c.width) && (fromX)) {
if ((fromX < c.x) || (fromY < c.y) || (fromX >= c.x + c.width) || (fromY >= c.y + c.height)) {
c.collisionEnter(obj);
obj.collisionEnter(c);
}
} else {
c.collisionEnter(obj);
obj.collisionEnter(c);
}
}

cell.push(obj);
return true;
},
removeObject: function (obj, x, y, toX, toY) {
var row = this.cells[x];

if (!row)
return;

var cell = row[y];

if (!cell)
return;

var oId = obj.id;
var cLen = cell.length;
for (var i = 0; i < cLen; i++) {
var c = cell[i];

if (c.id != oId) {
//If we have toX and toY, check if the target cell doesn't contain the same obj (like a notice area)
if ((c.width) && (toX)) {
if ((toX < c.x) || (toY < c.y) || (toX >= c.x + c.width) || (toY >= c.y + c.height)) {
c.collisionExit(obj);
obj.collisionExit(c);
}
} else {
c.collisionExit(obj);
obj.collisionExit(c);
}
} else {
cell.splice(i, 1);
i--;
cLen--;
}
}
},

isValid: function (x, y) {
var row = this.cells[x];

if ((!row) || (row.length <= y) || (!this.graph.grid[x][y]))
return false;
else
return true;
},

getCell: function (x, y) {
var row = this.cells[x];

if (!row)
return [];

var cell = row[y];

if (!cell)
return [];

return cell;
},
getArea: function (x1, y1, x2, y2, filter) {
var width = this.width;
var height = this.height;

x1 = ~~x1;
y1 = ~~y1;

x2 = ~~x2;
y2 = ~~y2;

if (x1 < 0)
x1 = 0;
else if (x2 >= width)
x2 = width - 1;
if (y1 < 0)
y1 = 0;
else if (y2 >= height)
y2 = height - 1;

var cells = this.cells;
var grid = this.graph.grid;

var result = [];
for (var i = x1; i <= x2; i++) {
var row = cells[i];
var gridRow = grid[i];
for (var j = y1; j <= y2; j++) {
if (!gridRow[j])
continue;

var cell = row[j];
var cLen = cell.length;
for (var k = 0; k < cLen; k++) {
var c = cell[k];

if (filter) {
if (filter(c))
result.push(c);
} else
result.push(c);
}
}
}

return result;
},

getOpenCellInArea: function (x1, y1, x2, y2) {
var width = this.width;
var height = this.height;

x1 = ~~x1;
y1 = ~~y1;

x2 = ~~x2;
y2 = ~~y2;

if (x1 < 0)
x1 = 0;
else if (x2 >= width)
x2 = width - 1;
if (y1 < 0)
y1 = 0;
else if (y2 >= height)
y2 = height - 1;

var cells = this.cells;
var grid = this.graph.grid;

var result = [];
for (var i = x1; i <= x2; i++) {
var row = cells[i];
var gridRow = grid[i];
for (var j = y1; j <= y2; j++) {
if (!gridRow[j])
continue;

var cell = row[j];
if (cell.length == 0) {
return {
x: i,
y: j
};
}
}
}

return result;
},

getPath: function (from, to) {
var graph = this.graph;
var grid = graph.grid;

if (!to) {
to = {
x: ~~(random() * grid.length),
y: ~~(random() * grid[0].length)
};
}

var fromX = ~~from.x;
var fromY = ~~from.y;

if ((!grid[fromX]) || (grid[fromX].length <= fromY) || (fromX < 0) || (fromY < 0))
return [];

var toX = ~~to.x;
var toY = ~~to.y;

if ((!grid[toX]) || (grid[toX].length <= toY) || (toX < 0) || (toY < 0))
return [];

var path = pathfinder.astar.search(graph, {
x: fromX,
y: fromY
}, {
x: toX,
y: toY
}, {
closest: true
});

return path;
},
isTileBlocking: function (x, y, mob, obj) {
if ((x < 0) || (y < 0) || (x >= this.width) | (y >= this.height))
return true;
@@ -266,177 +35,30 @@ define([

return ((!node) || (node.weight == 0));
},
isCellOpen: function (x, y) {
if ((x < 0) || (y < 0) || (x >= this.width) | (y >= this.height))
return true;

return (this.cells[x][y].length == 0);
},
hasLos: function (fromX, fromY, toX, toY) {
if ((fromX < 0) || (fromY < 0) || (fromX >= this.width) | (fromY >= this.height) || (toX < 0) || (toY < 0) || (toX >= this.width) | (toY >= this.height))
return false;

var graphGrid = this.graph.grid;

if ((!graphGrid[fromX][fromY]) || (!graphGrid[toX][toY]))
return false;

var dx = toX - fromX;
var dy = toY - fromY;

var distance = sqrt((dx * dx) + (dy * dy));

dx /= distance;
dy /= distance;

fromX += 0.5;
fromY += 0.5;

distance = ceil(distance);

var x = 0;
var y = 0;

for (var i = 0; i < distance; i++) {
fromX += dx;
fromY += dy;

x = ~~fromX;
y = ~~fromY;

if (!graphGrid[x][y])
return false;
else if ((x == toX) && (y == toY))
return true;
}

return true;
},

getClosestPos: function (fromX, fromY, toX, toY, target) {
var tried = {};

var hasLos = this.hasLos.bind(this, toX, toY);

var width = this.width;
var height = this.height;

var collisionMap = this.collisionMap;
var cells = this.cells;

var reverseX = (fromX > toX);
var reverseY = (fromY > toY);

for (var c = 1; c <= 10; c++) {
var x1 = toX - c;
var y1 = toY - c;
var x2 = toX + c;
var y2 = toY + c;

var lowX, lowY, highX, highY, incX, incY;

if (reverseX) {
incX = -1;
lowX = x2;
highX = x1 - 1;
} else {
incX = 1;
lowX = x1;
highX = x2 + 1;
}

if (reverseY) {
incY = -1;
lowY = y2;
highY = y1 - 1;
} else {
incY = 1;
lowY = y1;
highY = y2 + 1;
}

for (var i = lowX; i != highX; i += incX) {
if ((i < 0) || (i >= width))
continue;

var row = collisionMap[i];
var cellRow = cells[i];

var t = tried[i];
if (!t) {
t = tried[i] = {};
}

for (var j = lowY; j != highY; j += incY) {
if (t[j])
continue;

t[j] = 1;

if (
((i == toX) && (j == toY)) ||
((j < 0) || (j >= height)) ||
(row[j])
)
continue;

var cell = cellRow[j];
var cLen = cell.length;
var blocking = false;
for (var k = 0; k < cLen; k++) {
var aggro = cell[k].aggro;
if (aggro) {
blocking = aggro.list.some(a => a.obj == target);
if (blocking)
break;
}
}
if (blocking)
continue;
else if (!hasLos(i, j))
continue;

return {
x: i,
y: j
};
}
}
}
},

mobsCollide: function (x, y, obj) {
if ((x < 0) || (y < 0) || (x >= this.width) | (y >= this.height))
return true;

var cell = this.cells[x][y];
var cLen = cell.length;
isInPolygon: function (x, y, verts) {
var inside = false;

if (cLen == 1)
return false;
var vLen = verts.length;
for (var i = 0, j = vLen - 1; i < vLen; j = i++) {
var vi = verts[i];
var vj = verts[j];

var found = false;
for (var i = 0; i < cLen; i++) {
var c = cell[i];
if (c.aggro) {
if ((!found) && (c == obj))
found = true;
else
return true;
}
}
var xi = vi[0];
var yi = vi[1];
var xj = vj[0];
var yj = vj[1];

return false;
},
var doesIntersect = (
((yi > y) != (yj > y)) &&
(x < ((((xj - xi) * (y - yi)) / (yj - yi)) + xi))
);

setCollision: function (x, y, collides) {
var node = this.graph.grid[x][y];
if (!node) {
var grid = this.graph.grid;
node = grid[x][y] = new pathfinder.gridNode(x, y, collides ? 0 : 1);
if (doesIntersect)
inside = !inside
}

node.weight = collides ? 0 : 1;
return inside;
}
};
});

+ 2
- 2
src/client/js/objects/objects.js Ver ficheiro

@@ -133,7 +133,7 @@ define([
var components = template.components || [];
delete template.components;

var syncTypes = ['portrait'];
var syncTypes = ['portrait', 'area'];

for (var p in template) {
var value = template[p];
@@ -183,7 +183,7 @@ define([
events.emit('onGetPlayer', obj);
window.player = obj;

sound.init(obj.zoneName);
sound.init(obj.zoneId);

renderer.setPosition({
x: (obj.x - (renderer.width / (scale * 2))) * scale,


+ 53
- 32
src/client/js/sound/sound.js Ver ficheiro

@@ -1,49 +1,65 @@
define([
'howler'
'howler',
'js/misc/physics'
], function (
howler
howler,
physics
) {
return {
sounds: [],

init: function (zone) {
this.unload();

if (zone != 'fjolarok')
return;

this.addSound('fire.ogg', 123, 123);
this.addSound('stream.ogg', 107, 69);
this.addSound('wind.ogg', 176, 104);
init: function (zoneId) {
this.unload(zoneId);
},

unload: function () {
unload: function (zoneId) {
this.sounds.forEach(function (s) {
if (s.sound)
if ((s.sound) && (s.zoneId != zoneId))
s.sound.unload();
});

this.sounds = [];
this.sounds.spliceWhere(function (s) {
return (s.zoneId != zoneId);
});
},

update: function (x, y) {
this.sounds.forEach(function (s) {
var dx = Math.abs(s.x - x);
if (dx > 10) {
if (s.sound)
s.sound.volume(0);
return;
}
var dy = Math.abs(s.y - y);
if (dy > 10) {
if (s.sound)
s.sound.volume(0);
return;
}
var volume = 1;
if (!s.w) {
var dx = Math.abs(s.x - x);
if (dx > 10) {
if (s.sound)
s.sound.volume(0);
return;
}
var dy = Math.abs(s.y - y);
if (dy > 10) {
if (s.sound)
s.sound.volume(0);
return;
}

var dist = 10 - Math.max(dx, dy);
dist = (dist * dist) / 100;
var volume = 0.3 * dist;
var dist = 10 - Math.max(dx, dy);
dist = (dist * dist) / 100;
volume = 0.3 * dist;
} else {
if (!s.area) {
var inside = (!((x < s.x) || (y < s.y) || (x >= s.x + s.w) || (y >= s.y + s.h)));
if (!inside) {
if (s.sound)
s.sound.volume(0);
return;
}
} else {
var inside = physics.isInPolygon(x, y, s.area);
if (!inside) {
if (s.sound)
s.sound.volume(0);
return;
}
}
}

if (!s.sound) {
s.sound = new Howl({
@@ -54,16 +70,21 @@ define([
});
}

s.sound.volume(volume);
s.sound.volume(volume * s.volume);
});
},

addSound: function (file, x, y) {
addSound: function (zoneId, file, volume, x, y, w, h, area) {
var sound = {
file: file,
x: x,
y: y,
sound: null
w: w,
h: h,
volume: volume,
area: area,
sound: null,
zoneId: zoneId
};

this.sounds.push(sound);


+ 20
- 0
src/server/components/sound.js Ver ficheiro

@@ -0,0 +1,20 @@
define([

], function (

) {
return {
type: 'sound',

sound: null,
volume: 0,

simplify: function () {
return {
type: 'sound',
sound: this.sound,
volume: this.volume
};
}
};
});

+ 10
- 8
src/server/config/maps/dungeon/map.json
A apresentação das diferenças no ficheiro foi suprimida por ser demasiado grande
Ver ficheiro


+ 33
- 7
src/server/config/maps/dungeon/zone.js Ver ficheiro

@@ -3,14 +3,40 @@ module.exports = {
level: [18, 20],

mobs: {
acowlyte: {
level: 20,
default: {
faction: 'hostile',
grantRep: {
gaekatla: 15
},

patrol: [
[25, 90],
[67, 90]
],
faction: 'hostile'
regular: {
hpMult: 4,
dmgMult: 2.2,

drops: {
chance: 45,
rolls: 1,
magicFind: 500
}
},

rare: {
hpMult: 7,
dmgMult: 3,

drops: {
chance: 100,
rolls: 1,
magicFind: 2000
}
}
},
snekk: {
level: 15
},

snekkboss: {
level: 15,
}
}
};

+ 1
- 2
src/server/objects/objBase.js Ver ficheiro

@@ -104,7 +104,7 @@ define([
o = this;
}

var syncTypes = ['portrait'];
var syncTypes = ['portrait', 'area'];

for (var p in o) {
var value = o[p];
@@ -112,7 +112,6 @@ define([
continue;

var type = typeof (value);

//build component
if (type == 'object') {
if (value.type) {


+ 4
- 1
src/server/objects/objects.js Ver ficheiro

@@ -88,6 +88,9 @@ define([
obj.height = l.height;
}

if (l.area)
obj.area = l.area;

//Add components (certain ones need to happen first)
//TODO: Clean this part up
var properties = extend(true, {}, l.properties);
@@ -134,7 +137,7 @@ define([

if ((this.physics) && (!obj.dead)) {
if (!obj.width)
this.physics.addObject(obj, obj.x, obj.y);
this.physics.addObject(obj, obj.x, obj.y);
else
this.physics.addRegion(obj);
}


+ 62
- 1
src/server/world/map.js Ver ficheiro

@@ -385,7 +385,36 @@ define([
} else if (layerName == 'hiddenRooms') {
this.hiddenRooms.push(blueprint);
} else if (!clientObj) {
if (!mapFile.properties.isRandom)
if (cell.polyline) {
var lowX = this.size.w;
var lowY = this.size.h;
var highX = 0;
var highY = 0;

blueprint.area = cell.polyline.map(function (v) {
var x = ~~((v.x + cell.x) / mapScale);
var y = ~~((v.y + cell.y) / mapScale);

if (x < lowX)
lowX = x;
if (x > highX)
highX = x;

if (y < lowY)
lowY = y;
if (y > highY)
highY = y;

return [x, y];
});

blueprint.x = lowX;
blueprint.y = lowY;
blueprint.width = (highX - lowX);
blueprint.height = (highY - lowY);

spawners.register(blueprint, blueprint.spawnCd || mapFile.properties.spawnCd);
} else if (!mapFile.properties.isRandom)
spawners.register(blueprint, blueprint.spawnCd || mapFile.properties.spawnCd);
else {
var room = this.rooms.find(function (r) {
@@ -399,6 +428,38 @@ define([
room.objects.push(blueprint);
}
} else {
if (cell.polyline) {
var lowX = this.size.w;
var lowY = this.size.h;
var highX = 0;
var highY = 0;

blueprint.area = cell.polyline.map(function (v) {
var x = ~~((v.x + cell.x) / mapScale);
var y = ~~((v.y + cell.y) / mapScale);

if (x < lowX)
lowX = x;
if (x > highX)
highX = x;

if (y < lowY)
lowY = y;
if (y > highY)
highY = y;

return [x, y];
});

blueprint.x = lowX;
blueprint.y = lowY;
blueprint.width = (highX - lowX);
blueprint.height = (highY - lowY);
} else if (cell.width) {
blueprint.width = cell.width / mapScale;
blueprint.height = cell.height / mapScale;
}

var obj = objects.buildObjects([blueprint], true).getSimple(true);
this.objBlueprints.push(obj);
}


+ 37
- 2
src/server/world/physics.js Ver ficheiro

@@ -106,7 +106,12 @@ define([

//If we have fromX and fromY, check if the target cell doesn't contain the same obj (like a notice area)
if ((c.width) && (fromX)) {
if ((fromX < c.x) || (fromY < c.y) || (fromX >= c.x + c.width) || (fromY >= c.y + c.height)) {
if (c.area) {
if ((this.isInPolygon(x, y, c.area)) && (!this.isInPolygon(fromX, fromY, c.area))) {
c.collisionEnter(obj);
obj.collisionEnter(c);
}
} else if ((fromX < c.x) || (fromY < c.y) || (fromX >= c.x + c.width) || (fromY >= c.y + c.height)) {
c.collisionEnter(obj);
obj.collisionEnter(c);
}
@@ -140,7 +145,12 @@ define([
if (c.id != oId) {
//If we have toX and toY, check if the target cell doesn't contain the same obj (like a notice area)
if ((c.width) && (toX)) {
if ((toX < c.x) || (toY < c.y) || (toX >= c.x + c.width) || (toY >= c.y + c.height)) {
if (c.area) {
if ((this.isInPolygon(x, y, c.area)) && (!this.isInPolygon(toX, toY, c.area))) {
c.collisionExit(obj);
obj.collisionExit(c);
}
} else if ((toX < c.x) || (toY < c.y) || (toX >= c.x + c.width) || (toY >= c.y + c.height)) {
c.collisionExit(obj);
obj.collisionExit(c);
}
@@ -509,6 +519,31 @@ define([
grid[x][y].weight = collides ? 0 : 1;
pathfinder.astar.cleanNode(grid[x][y]);
}
},

isInPolygon: function (x, y, verts) {
var inside = false;

var vLen = verts.length;
for (var i = 0, j = vLen - 1; i < vLen; j = i++) {
var vi = verts[i];
var vj = verts[j];

var xi = vi[0];
var yi = vi[1];
var xj = vj[0];
var yj = vj[1];

var doesIntersect = (
((yi > y) != (yj > y)) &&
(x < ((((xj - xi) * (y - yi)) / (yj - yi)) + xi))
);

if (doesIntersect)
inside = !inside
}

return inside;
}
};
});

Carregando…
Cancelar
Guardar