@@ -16,6 +16,12 @@ body { | |||
top: 0px; | |||
z-index: 20; | |||
overflow: hidden; | |||
> .right { | |||
position: absolute; | |||
right: 10px; | |||
top: 100px; | |||
} | |||
} | |||
@font-face | |||
@@ -11,6 +11,8 @@ | |||
</head> | |||
<body> | |||
<div class="canvasContainer"></div> | |||
<div class="ui-container"></div> | |||
<div class="ui-container"> | |||
<div class="right"></div> | |||
</div> | |||
</body> | |||
</html> |
@@ -20,6 +20,7 @@ var components = [ | |||
'effects', | |||
'aggro', | |||
'quests', | |||
'events', | |||
'resourceNode', | |||
'gatherer', | |||
'stash', | |||
@@ -0,0 +1,25 @@ | |||
define([ | |||
'js/system/events' | |||
], function( | |||
events | |||
) { | |||
return { | |||
type: 'events', | |||
list: [], | |||
init: function() { | |||
this.list.forEach(function(q) { | |||
events.emit('onObtainEvent', q); | |||
}); | |||
}, | |||
extend: function(blueprint) { | |||
if (blueprint.updateList) { | |||
blueprint.updateList.forEach(function(q) { | |||
events.emit('onObtainEvent', q); | |||
this.list.push(q); | |||
}, this); | |||
} | |||
} | |||
}; | |||
}); |
@@ -14,6 +14,7 @@ define([ | |||
'ui/templates/hud/hud', | |||
'ui/templates/online/online', | |||
'ui/templates/quests/quests', | |||
'ui/templates/events/events', | |||
'ui/templates/dialogue/dialogue', | |||
'ui/templates/smithing/smithing', | |||
'ui/templates/overlay/overlay', | |||
@@ -48,6 +48,18 @@ define([ | |||
} | |||
}, | |||
removeComponent: function(type) { | |||
var cpn = this[type]; | |||
if (!cpn) | |||
return; | |||
this.components.spliceWhere(function(c) { | |||
return (c == cpn); | |||
}); | |||
delete this[type]; | |||
}, | |||
render: function() { | |||
return; | |||
if (this.sheetName) | |||
@@ -210,6 +210,13 @@ define([ | |||
delete template.components; | |||
if (template.removeComponents) { | |||
template.removeComponents.forEach(function(r) { | |||
obj.removeComponent(r); | |||
}); | |||
delete template.removeComponents; | |||
} | |||
var oldX = obj.x; | |||
var sprite = obj.sprite; | |||
@@ -39,6 +39,7 @@ define([ | |||
'tooltipItem', | |||
'announcements', | |||
'quests', | |||
'events', | |||
'progressBar', | |||
'stash', | |||
'smithing', | |||
@@ -0,0 +1,98 @@ | |||
define([ | |||
'js/system/client', | |||
'js/system/events', | |||
'html!ui/templates/events/template', | |||
'html!ui/templates/events/templateEvent', | |||
'css!ui/templates/events/styles' | |||
], function( | |||
client, | |||
events, | |||
tpl, | |||
templateEvent, | |||
styles | |||
) { | |||
return { | |||
tpl: tpl, | |||
list: [], | |||
container: '.right', | |||
postRender: function() { | |||
this.onEvent('onRezone', this.onRezone.bind(this)); | |||
this.onEvent('onObtainEvent', this.onObtainEvent.bind(this)); | |||
this.onEvent('onUpdateEvent', this.onUpdateEvent.bind(this)); | |||
this.onEvent('onCompleteEvent', this.onCompleteEvent.bind(this)); | |||
}, | |||
onRezone: function() { | |||
this.list = []; | |||
this.el.find('.list').empty(); | |||
}, | |||
onObtainEvent: function(event) { | |||
var container = this.el.find('.list'); | |||
var html = templateEvent | |||
.replace('$NAME$', event.name) | |||
.replace('$DESCRIPTION$', event.description); | |||
var el = $(html).appendTo(container); | |||
if (event.isReady) | |||
el.addClass('ready'); | |||
/*if (event.active) | |||
el.addClass('active'); | |||
else if (!event.isReady) | |||
el.addClass('disabled');*/ | |||
this.list.push({ | |||
id: event.id, | |||
el: el, | |||
event: event | |||
}); | |||
var event = container.find('.event'); | |||
event | |||
.sort(function(a, b) { | |||
a = $(a).hasClass('active') ? 1 : 0; | |||
b = $(b).hasClass('active') ? 1 : 0; | |||
return b - a; | |||
}) | |||
.appendTo(container); | |||
}, | |||
onUpdateEvent: function(event) { | |||
var e = this.list.find(function(l) { | |||
return (l.id == event.id); | |||
}); | |||
e.event.isReady = event.isReady; | |||
e.el.find('.description').html(event.description); | |||
e.el.removeClass('ready'); | |||
if (event.isReady) { | |||
e.el.removeClass('disabled'); | |||
e.el.addClass('ready'); | |||
} | |||
}, | |||
onCompleteEvent: function(id) { | |||
var e = this.list.find(function(l) { | |||
return (l.id == id); | |||
}); | |||
if (!e) | |||
return; | |||
e.el.remove(); | |||
this.list.spliceWhere(function(l) { | |||
return (l.id == id); | |||
}); | |||
} | |||
} | |||
}); |
@@ -0,0 +1,49 @@ | |||
@import "../../../css/ui.less"; | |||
.uiEvents { | |||
margin-top: 10px; | |||
width: 320px; | |||
.heading { | |||
color: @yellow; | |||
padding: 8px; | |||
background-color: fade(#3a3b4a, 90%); | |||
} | |||
.list { | |||
.event { | |||
cursor: pointer; | |||
padding: 8px; | |||
background-color: fade(#3a3b4a, 90%); | |||
&:hover { | |||
background-color: fade(lighten(#3a3b4a, 15%), 90%); | |||
} | |||
.name { | |||
color: @white; | |||
margin-bottom: 3px; | |||
} | |||
.description { | |||
color: darken(@white, 35%); | |||
} | |||
&.active { | |||
.name { | |||
color: @blue; | |||
} | |||
} | |||
&.ready { | |||
.name { | |||
color: @green; | |||
} | |||
.description { | |||
display: none; | |||
} | |||
} | |||
} | |||
} | |||
} |
@@ -0,0 +1,4 @@ | |||
<div class="uiEvents"> | |||
<div class="heading">Events</div> | |||
<div class="list"></div> | |||
</div> |
@@ -0,0 +1,4 @@ | |||
<div class="event"> | |||
<div class="name">$NAME$</div> | |||
<div class="description">$DESCRIPTION$</div> | |||
</div> |
@@ -15,6 +15,7 @@ define([ | |||
tpl: tpl, | |||
quests: [], | |||
container: '.right', | |||
postRender: function() { | |||
this.onEvent('onRezone', this.onRezone.bind(this)); | |||
@@ -1,10 +1,7 @@ | |||
@import "../../../css/ui.less"; | |||
.uiQuests { | |||
position: absolute; | |||
right: 10px; | |||
top: 100px; | |||
width: 320px; | |||
.heading { | |||
color: @yellow; | |||
@@ -24,6 +21,7 @@ | |||
.name { | |||
color: @white; | |||
margin-bottom: 3px; | |||
} | |||
.description { | |||
@@ -15,8 +15,8 @@ define([ | |||
render: function() { | |||
var container = '.ui-container'; | |||
if ((this.options) && (this.options.container)) | |||
container = this.options.container;; | |||
if (this.container) | |||
container += ' > ' + this.container; | |||
this.el = $(this.tpl) | |||
.appendTo(container) | |||
@@ -80,7 +80,10 @@ define([ | |||
} else { | |||
var lLen = list.length; | |||
for (var i = 0; i < lLen; i++) { | |||
list[i].obj.aggro.unIgnore(obj); | |||
var targetAggro = list[i].obj.aggro; | |||
//Maybe the aggro component has been removed? | |||
if (targetAggro) | |||
targetAggro.unIgnore(obj); | |||
} | |||
} | |||
@@ -217,7 +220,10 @@ define([ | |||
console.log('aggro obj empty???'); | |||
continue; | |||
} | |||
l.obj.aggro.unAggro(this.obj); | |||
//Maybe the aggro component was removed? | |||
var targetAggro = l.obj.aggro; | |||
if (targetAggro) | |||
targetAggro.unAggro(this.obj); | |||
} | |||
this.list = []; | |||
@@ -19,6 +19,8 @@ define([ | |||
update: function() { | |||
if ((this.obj.aggro) && (this.obj.aggro.list.length > 0)) | |||
return; | |||
else if (this.chats.length == 0) | |||
return; | |||
if ((this.cd == 0) && (Math.random() < this.chance)) { | |||
this.cd = this.cdMax; | |||
@@ -0,0 +1,51 @@ | |||
define([ | |||
], function( | |||
) { | |||
return { | |||
type: 'events', | |||
list: [], | |||
simplify: function(self) { | |||
if (!self) | |||
return; | |||
var result = { | |||
type: 'events' | |||
}; | |||
if (this.list.length > 0) { | |||
result.list = this.list.map(l => ({ | |||
name: l.name, | |||
description: l.description | |||
})); | |||
} | |||
return result; | |||
}, | |||
save: function() { | |||
return null; | |||
}, | |||
events: { | |||
afterMove: function() { | |||
var events = this.obj.instance.events; | |||
var closeEvents = events.getCloseEvents(this.obj); | |||
if (!closeEvents) | |||
return; | |||
closeEvents.forEach(function(c) { | |||
this.list.push(c); | |||
this.obj.syncer.setArray(true, 'events', 'updateList', { | |||
name: c.config.name, | |||
description: c.config.description | |||
}); | |||
}, this); | |||
} | |||
} | |||
}; | |||
}); |
@@ -86,6 +86,7 @@ define([ | |||
obj.addComponent('equipment', character.components.find(c => c.type == 'equipment')); | |||
obj.addComponent('inventory', character.components.find(c => c.type == 'inventory')); | |||
obj.addComponent('quests', character.components.find(c => c.type == 'quests')); | |||
obj.addComponent('events', character.components.find(c => c.type == 'events')); | |||
var blueprintEffects = character.components.find(c => c.type == 'effects') || {}; | |||
if (blueprintEffects.effects) { | |||
@@ -91,6 +91,17 @@ define([ | |||
cpn[property] = []; | |||
cpn[property].push(value); | |||
}, | |||
setSelfArray: function(self, property, value) { | |||
var o = this.o; | |||
if (self) | |||
o = this.oSelf; | |||
if (o[property] == null) | |||
o[property] = []; | |||
o[property].push(value); | |||
} | |||
}; | |||
}); |
@@ -0,0 +1,84 @@ | |||
define([ | |||
], function( | |||
) { | |||
return { | |||
config: null, | |||
state: -1, | |||
cd: 0, | |||
init: function() { | |||
this.update(); | |||
}, | |||
update: function() { | |||
if (this.cd == 0) { | |||
if (this.state < this.config.length - 1) { | |||
this.state++; | |||
var stateConfig = this.config[this.state]; | |||
this.cd = stateConfig.delay; | |||
this.events[stateConfig.type].call(this, stateConfig); | |||
//Sometimes (Like when we make a mob attackable, then check if they're alive in a new phase), the next phase doesn't | |||
// trigger soon enough. So if there's no delay, make sure to switch phases asap. | |||
if (!this.cd) | |||
this.end = true; | |||
} | |||
else | |||
this.end = true; | |||
} | |||
else | |||
this.cd--; | |||
}, | |||
events: { | |||
mobTalk: function(config) { | |||
var mob = this.instance.objects.objects.find(o => (o.id == config.id)); | |||
mob.addComponent('chatter'); | |||
mob.syncer.set(false, 'chatter', 'msg', config.text); | |||
}, | |||
addComponents: function(config) { | |||
var objects = this.instance.objects.objects; | |||
var components = config.components; | |||
if (!components.push) | |||
components = [ components ]; | |||
var cLen = components.length; | |||
var mobs = config.mobs; | |||
if (!mobs.push) | |||
mobs = [ mobs ]; | |||
var mLen = mobs.length; | |||
for (var i = 0; i < mLen; i++) { | |||
var mob = objects.find(o => (o.id == mobs[i])); | |||
for (var j = 0; j < cLen; j++) { | |||
var c = components[j]; | |||
mob.addComponent(c.type, components[j]); | |||
} | |||
} | |||
}, | |||
removeComponents: function(config) { | |||
var objects = this.instance.objects.objects; | |||
var components = config.components; | |||
if (!components.push) | |||
components = [ components ]; | |||
var cLen = components.length; | |||
var mobs = config.mobs; | |||
if (!mobs.push) | |||
mobs = [ mobs ]; | |||
var mLen = mobs.length; | |||
for (var i = 0; i < mLen; i++) { | |||
var mob = objects.find(o => (o.id == mobs[i])); | |||
for (var j = 0; j < cLen; j++) { | |||
mob.removeComponent(components[j]); | |||
} | |||
} | |||
} | |||
} | |||
}; | |||
}); |
@@ -0,0 +1,76 @@ | |||
define([ | |||
], function( | |||
) { | |||
var cpnDeathStopper = { | |||
type: 'deathStopper', | |||
percentage: 0, | |||
end: false, | |||
events: { | |||
beforeTakeDamage: function(damage, source) { | |||
var statValues = this.obj.stats.values; | |||
var minHp = statValues.hpMax * this.percentage; | |||
if (statValues.hp - damage.amount < minHp) { | |||
this.end = true; | |||
damage.amount = Math.max(0, statValues.hp - minHp); | |||
} | |||
} | |||
} | |||
}; | |||
return { | |||
mobs: null, | |||
init: function() { | |||
if (!this.mobs.push) | |||
this.mobs = [ this.mobs ]; | |||
var mobs = this.mobs; | |||
var percentage = this.percentage; | |||
var objects = this.instance.objects.objects; | |||
var oLen = objects.length; | |||
for (var i = 0; i < oLen; i++) { | |||
var o = objects[i]; | |||
var index = mobs.indexOf(o.id); | |||
if (index == -1) | |||
continue; | |||
if (percentage) { | |||
var cpn = extend(true, cpnDeathStopper, { | |||
percentage: percentage | |||
}); | |||
o.components.push(cpn); | |||
cpn.obj = o; | |||
} | |||
mobs.splice(index, 1, o); | |||
} | |||
}, | |||
update: function() { | |||
var mobs = this.mobs; | |||
var mLen = mobs.length; | |||
for (var i = 0; i < mLen; i++) { | |||
var m = mobs[i]; | |||
var destroyed = m.destroyed; | |||
if (!destroyed) { | |||
var deathStopper = m.components.find(c => (c.type == 'deathStopper')); | |||
if (deathStopper) | |||
destroyed = deathStopper.end; | |||
} | |||
if (destroyed) { | |||
mobs.splice(i, 1); | |||
mLen--; | |||
i--; | |||
} | |||
} | |||
if (mobs.length == 0) | |||
this.end = true; | |||
} | |||
}; | |||
}); |
@@ -0,0 +1,56 @@ | |||
define([ | |||
], function( | |||
) { | |||
return { | |||
mobs: null, | |||
init: function() { | |||
if (!this.mobs.push) | |||
this.mobs = [ this.mobs ]; | |||
var mobs = this.mobs; | |||
var objects = this.instance.objects.objects; | |||
var oLen = objects.length; | |||
for (var i = 0; i < oLen; i++) { | |||
var o = objects[i]; | |||
var index = mobs.indexOf(o.id); | |||
if (index == -1) | |||
continue; | |||
mobs.splice(index, 1, o); | |||
} | |||
}, | |||
update: function() { | |||
var players = this.instance.objects.objects.filter(function(o) { | |||
return o.player; | |||
}); | |||
var pLen = players.length; | |||
var distance = this.distance; | |||
var mobs = this.mobs; | |||
var mLen = mobs.length; | |||
for (var i = 0; i < mLen; i++) { | |||
var m = mobs[i]; | |||
for (var j = 0; j < pLen; j++) { | |||
var p = players[j]; | |||
if ((Math.abs(p.x - m.x) <= distance) && (Math.abs(p.y - m.y) <= distance)) { | |||
mobs.splice(i, 1); | |||
mLen--; | |||
i--; | |||
break; | |||
} | |||
} | |||
} | |||
if (mobs.length == 0) | |||
this.end = true; | |||
} | |||
}; | |||
}); |
@@ -0,0 +1,105 @@ | |||
define([ | |||
'../../world/mobBuilder' | |||
], function( | |||
mobBuilder | |||
) { | |||
return { | |||
spawnRect: null, | |||
mobs: null, | |||
init: function() { | |||
var objects = this.instance.objects; | |||
var spawnRect = this.spawnRect; | |||
if (!this.mobs.push) | |||
this.mobs = [this.mobs]; | |||
var usedSpots = ['-1,-1']; | |||
this.mobs.forEach(function(l) { | |||
var amount = l.amount || 1; | |||
delete l.amount; | |||
l.walkDistance = 0; | |||
for (var i = 0; i < amount; i++) { | |||
var x = -1; | |||
var y = -1; | |||
var pos = l.pos; | |||
if (pos) { | |||
if (pos instanceof Array) { | |||
x = pos[i].x; | |||
y = pos[i].y; | |||
} else { | |||
x = pos.x; | |||
y = pos.y; | |||
} | |||
if (spawnRect) { | |||
x += spawnRect.x; | |||
y += spawnRect.y; | |||
} | |||
} else { | |||
while (usedSpots.indexOf(x + ',' + y) > -1) { | |||
x = spawnRect.x + ~~(Math.random() * spawnRect.w); | |||
y = spawnRect.y + ~~(Math.random() * spawnRect.h); | |||
} | |||
usedSpots.push(x + ',' + y); | |||
} | |||
if (l.exists) { | |||
var mob = objects.objects.find(o => (o.name == l.name)); | |||
mob.mob.walkDistance = 0; | |||
this.spawnAnimation(mob); | |||
mob.performMove({ | |||
force: true, | |||
data: { | |||
x: x, | |||
y: y | |||
} | |||
}); | |||
this.spawnAnimation(mob); | |||
this.event.objects.push(mob); | |||
} else { | |||
var mob = objects.buildObjects([{ | |||
x: x, | |||
y: y, | |||
sheetName: 'mobs', | |||
cell: l.cell, | |||
name: l.name | |||
}]); | |||
mobBuilder.build(mob, l); | |||
this.spawnAnimation(mob); | |||
//TESTCODE | |||
mob.stats.values.hp = 0.1; | |||
mob.stats.values.hpMax = 0.1; | |||
if (l.id) { | |||
var id = l.id.split('$').join(i); | |||
mob.id = id; | |||
} | |||
this.event.objects.push(mob); | |||
} | |||
} | |||
}, this); | |||
this.end = true; | |||
}, | |||
spawnAnimation: function(mob) { | |||
this.instance.syncer.queue('onGetObject', { | |||
x: mob.x, | |||
y: mob.y, | |||
components: [{ | |||
type: 'attackAnimation', | |||
row: 0, | |||
col: 4 | |||
}] | |||
}); | |||
} | |||
}; | |||
}); |
@@ -0,0 +1,17 @@ | |||
define([ | |||
], function( | |||
) { | |||
return { | |||
end: false, | |||
init: function() { | |||
}, | |||
update: function() { | |||
} | |||
}; | |||
}); |
@@ -0,0 +1,15 @@ | |||
define([ | |||
], function( | |||
) { | |||
return { | |||
id: 'forestImps', | |||
name: 'The Forest Imps', | |||
description: `The imps of the Forest.`, | |||
relations: { | |||
} | |||
}; | |||
}); |
@@ -0,0 +1,132 @@ | |||
module.exports = [{ | |||
name: 'Rodriguez Heist', | |||
description: `Rodriguez, the Hermit's only chicken companion, has been kidnapped by a band of imps. Who knows what they plan on doing with him.`, | |||
distance: 10, | |||
phases: [{ | |||
type: 'spawnMob', | |||
spawnRect: { | |||
x: 70, | |||
y: 40 | |||
}, | |||
mobs: [{ | |||
amount: 4, | |||
name: 'Thieving Imp', | |||
attackable: false, | |||
level: 5, | |||
cell: 51, | |||
id: 'impthief-$', | |||
hpMult: 5, | |||
dmgMult: 1, | |||
drops: { | |||
rolls: 0 | |||
}, | |||
pos: [{ | |||
x: 0, | |||
y: 0 | |||
}, { | |||
x: 4, | |||
y: 0 | |||
}, { | |||
x: 0, | |||
y: 4 | |||
}, { | |||
x: 4, | |||
y: 4 | |||
}] | |||
}, { | |||
name: 'Imp Kingpin', | |||
level: 8, | |||
attackable: false, | |||
cell: 52, | |||
id: 'imp-kingpin', | |||
hpMult: 10, | |||
dmgMult: 2, | |||
pos: { | |||
x: 2, | |||
y: 2 | |||
} | |||
}, { | |||
name: 'Rodriguez', | |||
exists: true, | |||
pos: { | |||
x: 3, | |||
y: 2 | |||
} | |||
}] | |||
}, { | |||
type: 'locateMob', | |||
announce: 'Locate the thieves', | |||
mobs: 'imp-kingpin', | |||
distance: 3 | |||
}, { | |||
type: 'eventChain', | |||
config: [{ | |||
type: 'mobTalk', | |||
id: 'impthief-1', | |||
text: `Boss! They're onto us!`, | |||
delay: 10 | |||
}, { | |||
type: 'mobTalk', | |||
id: 'impthief-2', | |||
text: `They'll take the chicken. We needs it!`, | |||
delay: 10 | |||
}, { | |||
type: 'mobTalk', | |||
id: 'imp-kingpin', | |||
text: `They'll never have her, she's ours now! Kill them!`, | |||
delay: 10 | |||
}, { | |||
type: 'addComponents', | |||
mobs: ['impthief-0', 'impthief-1', 'impthief-2', 'impthief-3'], | |||
components: [{ | |||
type: 'aggro', | |||
faction: 'forest imps' | |||
}] | |||
}] | |||
}, { | |||
type: 'killMob', | |||
mobs: ['impthief-0', 'impthief-1', 'impthief-2', 'impthief-3'] | |||
}, { | |||
type: 'eventChain', | |||
config: [{ | |||
type: 'mobTalk', | |||
id: 'imp-kingpin', | |||
text: `I have a thousand more imps. Come, I'll finish this now.`, | |||
delay: 10 | |||
}, { | |||
type: 'addComponents', | |||
mobs: 'imp-kingpin', | |||
components: [{ | |||
type: 'aggro', | |||
faction: 'forest imps' | |||
}] | |||
}] | |||
}, { | |||
type: 'killMob', | |||
mobs: 'imp-kingpin', | |||
percentage: 0.2 | |||
}, { | |||
type: 'eventChain', | |||
config: [{ | |||
type: 'removeComponents', | |||
mobs: 'imp-kingpin', | |||
components: 'aggro' | |||
}, { | |||
type: 'mobTalk', | |||
id: 'imp-kingpin', | |||
text: `Aargh, no! I must get to my lair!`, | |||
delay: 10 | |||
}] | |||
}, { | |||
type: 'spawnMob', | |||
mobs: { | |||
name: 'Imp Kingpin', | |||
exists: true, | |||
pos: { | |||
x: 90, | |||
y: 25 | |||
} | |||
} | |||
}] | |||
}]; |
@@ -0,0 +1,145 @@ | |||
define([ | |||
'../config/eventPhases/phaseTemplate' | |||
], function( | |||
phaseTemplate | |||
) { | |||
return { | |||
configs: null, | |||
init: function(instance) { | |||
this.instance = instance; | |||
var configs = null; | |||
try { | |||
configs = require('../config/maps/' + this.instance.map.name + '/events'); | |||
} | |||
catch (e) {} | |||
if (!configs) | |||
return; | |||
this.configs = extend(true, [], configs); | |||
this.configs.forEach(c => (c.ttl = 5)); | |||
}, | |||
update: function() { | |||
var configs = this.configs; | |||
if (!configs) | |||
return; | |||
var cLen = configs.length; | |||
for (var i = 0; i < cLen; i++) { | |||
var c = configs[i]; | |||
if (c.event) { | |||
this.updateEvent(c.event); | |||
continue; | |||
} | |||
else if (c.ttl > 0) { | |||
c.ttl--; | |||
continue; | |||
} | |||
c.event = this.startEvent(c); | |||
} | |||
}, | |||
startEvent: function(config) { | |||
var event = { | |||
config: config, | |||
phases: [], | |||
participators: [], | |||
objects: [], | |||
nextPhase: 0 | |||
}; | |||
return event; | |||
}, | |||
updateEvent: function(event) { | |||
var objects = event.objects; | |||
var oLen = objects.length; | |||
for (var i = 0; i < oLen; i++) { | |||
if (objects[i].destroyed) { | |||
objects.splice(i, 1); | |||
i--; | |||
oLen--; | |||
} | |||
} | |||
var currentPhases = event.phases; | |||
var cLen = currentPhases.length; | |||
var stillBusy = false; | |||
for (var i = 0; i < cLen; i++) { | |||
var phase = currentPhases[i]; | |||
if (phase.end) | |||
continue | |||
else { | |||
stillBusy = true; | |||
phase.update(); | |||
} | |||
} | |||
if (stillBusy) | |||
return; | |||
var config = event.config; | |||
var phases = config.phases; | |||
var pLen = phases.length; | |||
for (var i = event.nextPhase; i < pLen; i++) { | |||
var p = phases[i]; | |||
var phaseFile = 'phase' + p.type[0].toUpperCase() + p.type.substr(1); | |||
var typeTemplate = require('config/eventPhases/' + phaseFile); | |||
var phase = extend(true, { | |||
instance: this.instance, | |||
event: event | |||
}, phaseTemplate, typeTemplate, p); | |||
event.phases.push(phase); | |||
phase.init(); | |||
event.nextPhase = i + 1; | |||
if (!p.auto) | |||
break; | |||
} | |||
}, | |||
getCloseEvents: function(obj) { | |||
var x = obj.x; | |||
var y = obj.y; | |||
var configs = this.configs; | |||
if (!configs) | |||
return; | |||
var cLen = configs.length; | |||
var result = []; | |||
for (var i = 0; i < cLen; i++) { | |||
var event = configs[i].event; | |||
if (!event) | |||
continue; | |||
else if (event.participators.some(p => (p == obj))) | |||
continue; | |||
var distance = event.config.distance; | |||
var objects = event.objects; | |||
var oLen = objects.length; | |||
for (var j = 0; j < oLen; j++) { | |||
var o = objects[j]; | |||
if ((Math.abs(x - o.x) < distance) && (Math.abs(y - o.y) < distance)) { | |||
event.participators.push(obj); | |||
result.push(event); | |||
break; | |||
} | |||
} | |||
} | |||
return result; | |||
} | |||
}; | |||
}); |
@@ -36,6 +36,14 @@ define([ | |||
return cpn; | |||
}, | |||
removeComponent: function(type) { | |||
var cpn = this[type]; | |||
if (!cpn) | |||
return; | |||
cpn.destroyed = true; | |||
}, | |||
extendComponent: function(ext, type, blueprint) { | |||
var template = require('./components/extensions/' + type); | |||
var cpn = this[ext]; | |||
@@ -59,6 +67,14 @@ define([ | |||
if (c.update()) | |||
usedTurn = true; | |||
} | |||
if (c.destroyed) { | |||
this.syncer.setSelfArray(false, 'removeComponents', c.type); | |||
this.components.spliceWhere(f => (f == c)); | |||
delete this[c.type]; | |||
len--; | |||
i--; | |||
} | |||
} | |||
if (!usedTurn) { | |||
@@ -115,6 +131,16 @@ define([ | |||
else | |||
component = value.simplify(self); | |||
if (value.destroyed) { | |||
if (!component) { | |||
component = { | |||
type: value.type | |||
}; | |||
} | |||
component.destroyed = true; | |||
} | |||
if (component) | |||
result.components.push(component); | |||
} | |||
@@ -222,25 +248,27 @@ define([ | |||
var data = action.data; | |||
var physics = this.instance.physics; | |||
if (physics.isTileBlocking(data.x, data.y)) | |||
return false; | |||
if (!action.force) { | |||
if (physics.isTileBlocking(data.x, data.y)) | |||
return false; | |||
data.success = true; | |||
this.fireEvent('beforeMove', data); | |||
if (data.success == false) { | |||
action.priority = true; | |||
this.queue(action); | |||
return true; | |||
} | |||
data.success = true; | |||
this.fireEvent('beforeMove', data); | |||
if (data.success == false) { | |||
action.priority = true; | |||
this.queue(action); | |||
return true; | |||
} | |||
if (!action.isDouble) { | |||
var deltaX = Math.abs(this.x - data.x); | |||
var deltaY = Math.abs(this.y - data.y); | |||
if ( | |||
((deltaX > 1) || (deltaY > 1)) || | |||
((deltaX == 0) && (deltaY == 0)) | |||
) | |||
return false; | |||
if (!action.isDouble) { | |||
var deltaX = Math.abs(this.x - data.x); | |||
var deltaY = Math.abs(this.y - data.y); | |||
if ( | |||
((deltaX > 1) || (deltaY > 1)) || | |||
((deltaX == 0) && (deltaY == 0)) | |||
) | |||
return false; | |||
} | |||
} | |||
//Don't allow mob overlap during combat | |||
@@ -266,6 +294,8 @@ define([ | |||
if (this.aggro) | |||
this.aggro.move(); | |||
this.fireEvent('afterMove'); | |||
return true; | |||
}, | |||
@@ -8,7 +8,8 @@ define([ | |||
'config/spells/spellCallbacks', | |||
'config/quests/questBuilder', | |||
'world/randomMap', | |||
'world/customMap' | |||
'world/customMap', | |||
'events/events' | |||
], function( | |||
map, | |||
syncer, | |||
@@ -19,7 +20,8 @@ define([ | |||
spellCallbacks, | |||
questBuilder, | |||
randomMap, | |||
customMap | |||
customMap, | |||
events | |||
) { | |||
return { | |||
instances: [], | |||
@@ -36,39 +38,24 @@ define([ | |||
map.init(args); | |||
if (!map.instanced) { | |||
spawners.init({ | |||
objects: objects, | |||
syncer: syncer, | |||
zone: map.zone | |||
}); | |||
map.create(); | |||
map.clientMap.zoneId = this.zoneId; | |||
resourceSpawner.init({ | |||
var fakeInstance = { | |||
objects: objects, | |||
syncer: syncer, | |||
zone: map.zone, | |||
physics: physics, | |||
zoneId: this.zoneId, | |||
spawners: spawners, | |||
questBuilder: questBuilder, | |||
events: events, | |||
zone: map.zone, | |||
map: map | |||
}); | |||
}; | |||
syncer.init({ | |||
objects: objects | |||
}); | |||
spawners.init(fakeInstance); | |||
objects.init({ | |||
objects: objects, | |||
syncer: syncer, | |||
physics: physics, | |||
zoneId: this.zoneId, | |||
spawners: spawners, | |||
questBuilder: questBuilder | |||
}); | |||
map.create(); | |||
map.clientMap.zoneId = this.zoneId; | |||
questBuilder.init({ | |||
spawners: spawners | |||
}); | |||
[resourceSpawner, syncer, objects, questBuilder, events].forEach(i => i.init(fakeInstance)); | |||
this.addObject = this.nonInstanced.addObject.bind(this); | |||
this.onAddObject = this.nonInstanced.onAddObject.bind(this); | |||
@@ -109,7 +96,7 @@ define([ | |||
objects.update(); | |||
spawners.update(); | |||
resourceSpawner.update(); | |||
events.update(); | |||
syncer.update(); | |||
setTimeout(this.tick.bind(this), this.speed); | |||
@@ -452,19 +439,16 @@ define([ | |||
zone: map.zone, | |||
closeTtl: null, | |||
questBuilder: extend(true, {}, questBuilder), | |||
events: extend(true, {}, events), | |||
map: { | |||
name: map.name, | |||
spawn: extend(true, [], map.spawn), | |||
clientMap: extend(true, {}, map.clientMap), | |||
getSpawnPos: map.getSpawnPos.bind(map) | |||
} | |||
}; | |||
instance.objects.init(instance); | |||
instance.spawners.init(instance); | |||
instance.syncer.init(instance); | |||
instance.resourceSpawner.init(instance); | |||
instance.questBuilder.init(instance); | |||
['objects', 'spawners', 'syncer', 'resourceSpawner', 'questBuilder', 'events'].forEach(i => instance[i].init(instance)); | |||
this.instances.push(instance); | |||
@@ -9,7 +9,7 @@ define([ | |||
) { | |||
return { | |||
build: function(mob, blueprint, scaleDrops, type) { | |||
var typeDefinition = blueprint[type]; | |||
var typeDefinition = blueprint[type] || blueprint; | |||
var drops = typeDefinition.drops; | |||
@@ -20,15 +20,17 @@ define([ | |||
mob.nonSelectable = true; | |||
mob.addComponent('effects'); | |||
if (type != 'regular') { | |||
mob.effects.addEffect({ | |||
type: type | |||
}); | |||
if (type) { | |||
if (type != 'regular') { | |||
mob.effects.addEffect({ | |||
type: type | |||
}); | |||
mob['is' + type[0].toUpperCase() + type.substr(1)] = true; | |||
mob['is' + type[0].toUpperCase() + type.substr(1)] = true; | |||
mob.baseName = mob.name; | |||
mob.name = typeDefinition.name || mob.baseName; | |||
mob.baseName = mob.name; | |||
mob.name = typeDefinition.name || mob.baseName; | |||
} | |||
} | |||
mob.addComponent('stats', { | |||