@@ -12,7 +12,8 @@ define([ | |||
cdMax: 150, | |||
init: function(blueprint) { | |||
if (blueprint.msg) | |||
this.extend(blueprint); | |||
}, | |||
update: function() { | |||
@@ -17,6 +17,9 @@ define([ | |||
}, | |||
update: function() { | |||
if (this.chats.length == 0) | |||
return; | |||
if ((this.cd == 0) && (Math.random() < this.chance)) { | |||
this.cd = this.cdMax; | |||
@@ -0,0 +1,64 @@ | |||
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]); | |||
} | |||
} | |||
} | |||
} | |||
}; | |||
}); |
@@ -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; | |||
} | |||
}; | |||
}); |
@@ -4,14 +4,53 @@ define([ | |||
) { | |||
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; | |||
} | |||
}; | |||
}); |
@@ -5,42 +5,98 @@ define([ | |||
) { | |||
return { | |||
spawnRect: null, | |||
mob: null, | |||
mobs: null, | |||
init: function() { | |||
var objects = this.instance.objects; | |||
var spawnRect = this.spawnRect; | |||
if (!this.mob.push) | |||
this.mob = [ this.mob ]; | |||
if (!this.mobs.push) | |||
this.mobs = [this.mobs]; | |||
this.mob.forEach(function(l) { | |||
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 = spawnRect.x + ~~(Math.random() * spawnRect.w); | |||
var y = spawnRect.y + ~~(Math.random() * spawnRect.h); | |||
var mob = objects.buildObjects([{ | |||
x: x, | |||
y: y, | |||
sheetName: 'mobs', | |||
cell: l.cell, | |||
name: l.name | |||
}]); | |||
mobBuilder.build(mob, l); | |||
if (l.id) { | |||
var id = l.id.split('$').join(i); | |||
mob.id = id; | |||
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); | |||
} 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); | |||
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,15 @@ | |||
define([ | |||
], function( | |||
) { | |||
return { | |||
id: 'forestImps', | |||
name: 'The Forest Imps', | |||
description: `The imps of the Forest.`, | |||
relations: { | |||
} | |||
}; | |||
}); |
@@ -5,14 +5,13 @@ module.exports = [{ | |||
phases: [{ | |||
type: 'spawnMob', | |||
spawnRect: { | |||
x: 69, | |||
y: 39, | |||
w: 7, | |||
h: 6 | |||
x: 70, | |||
y: 40 | |||
}, | |||
mob: [{ | |||
amount: 5, | |||
name: 'thieving imp', | |||
mobs: [{ | |||
amount: 4, | |||
name: 'Thieving Imp', | |||
attackable: false, | |||
level: 5, | |||
cell: 51, | |||
id: 'impthief-$', | |||
@@ -20,43 +19,109 @@ module.exports = [{ | |||
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', | |||
name: 'Imp Kingpin', | |||
level: 8, | |||
attackable: false, | |||
cell: 52, | |||
id: 'imp-kingpin', | |||
hpMult: 10, | |||
dmgMult: 2 | |||
dmgMult: 2, | |||
pos: { | |||
x: 2, | |||
y: 2 | |||
} | |||
}, { | |||
name: 'Rodriguez', | |||
exists: true, | |||
pos: { | |||
x: 3, | |||
y: 2 | |||
} | |||
}] | |||
}, { | |||
type: 'locateMob', | |||
announce: 'Locate the thieves', | |||
mobName: 'imp kingpin', | |||
distance: 5 | |||
mobs: 'imp-kingpin', | |||
distance: 3 | |||
}, { | |||
type: 'eventChain', | |||
events: [{ | |||
config: [{ | |||
type: 'mobTalk', | |||
id: 'impthief-1', | |||
text: `Boss! They're on to us!`, | |||
text: `Boss! They're onto us!`, | |||
delay: 10 | |||
}, { | |||
type: 'mobTalk', | |||
id: 'impthief-3', | |||
id: 'impthief-2', | |||
text: `They'll take the chicken. We needs it!`, | |||
delay: 10 | |||
}, { | |||
type: 'mobTalk', | |||
id: 'impkingpin', | |||
id: 'imp-kingpin', | |||
text: `They'll never have her, she's ours now! Kill them!`, | |||
delay: 15 | |||
delay: 10 | |||
}, { | |||
type: 'addComponents', | |||
mobs: ['impthief-0', 'impthief-1', 'impthief-2', 'impthief-3'], | |||
components: [{ | |||
type: 'aggro', | |||
faction: 'forest imps' | |||
}] | |||
}] | |||
}, { | |||
type: 'giveReward', | |||
item: { | |||
name: 'The Moonspoon', | |||
sprite: [0, 0], | |||
level: 1 | |||
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: '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 | |||
} | |||
} | |||
}] | |||
}]; |
@@ -219,25 +219,27 @@ define([ | |||
var data = action.data; | |||
var physics = this.instance.physics; | |||
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; | |||
} | |||
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)) | |||
) | |||
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; | |||
} | |||
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 | |||