Staging Closes #25, #69, #90, #73, #64, #88, #96, #99, #100, #101, #76, #54, #63, #66, #57, #56, #11, #86, #83, #81, #80, #8, #10, and #46 See merge request !71tags/v0.1.2^0
@@ -56,6 +56,16 @@ define([ | |||
obj.chatSprite.visible = true; | |||
this.cd = this.cdMax; | |||
}, | |||
destroy: function() { | |||
var chatSprite = this.obj.chatSprite; | |||
if (!chatSprite) | |||
return; | |||
renderer.destroyObject({ | |||
sprite: chatSprite | |||
}); | |||
} | |||
}; | |||
}); |
@@ -10,7 +10,6 @@ define([ | |||
return { | |||
type: 'keyboardMover', | |||
path: [], | |||
moveCd: 0, | |||
moveCdMax: 8, | |||
direction: { | |||
@@ -13,7 +13,8 @@ define([ | |||
path: [], | |||
pathColor: 'rgba(255, 255, 255, 0.5)', | |||
pathColor: '0x48edff', | |||
pathAlpha: 0.2, | |||
pathPos: { | |||
x: 0, | |||
@@ -50,7 +51,8 @@ define([ | |||
y: y, | |||
sprite: renderer.buildRectangle({ | |||
layerName: 'effects', | |||
alpha: 0.2, | |||
color: this.pathColor, | |||
alpha: this.pathAlpha, | |||
x: (x * scale) + scaleMult, | |||
y: (y * scale) + scaleMult, | |||
w: scale - (scaleMult * 2), | |||
@@ -72,10 +72,14 @@ define([ | |||
if (blueprint.getSpells) { | |||
blueprint.getSpells.forEach(function(s) { | |||
if (this.spells.find(function(spell) { | |||
var existIndex = this.spells.firstIndex(function(spell) { | |||
return (spell.id == s.id); | |||
})) | |||
}); | |||
if (existIndex > -1) { | |||
this.spells.splice(existIndex, 1, s); | |||
return; | |||
} | |||
if (this.spells.length - 1 >= s.id) | |||
this.spells.splice(s.id, 0, s); | |||
@@ -22,6 +22,7 @@ define([ | |||
'9': 'tab', | |||
'13': 'enter', | |||
'16': 'shift', | |||
'17': 'ctrl', | |||
'27': 'esc', | |||
'37': 'left', | |||
'38': 'up', | |||
@@ -0,0 +1,47 @@ | |||
define([ | |||
], function( | |||
) { | |||
var stats = { | |||
'vit': 'vitality', | |||
'hpMax': 'vitality', | |||
'regenHp': 'health regeneration', | |||
'manaMax': 'maximum mana', | |||
'regenMana': 'mana regeneration', | |||
'str': 'strength', | |||
'int': 'intellect', | |||
'dex': 'dexterity', | |||
'armor': 'armor', | |||
'addCritChance': 'increased crit chance', | |||
'magicFind': 'magic find', | |||
'sprintChance': 'sprint chance', | |||
'dmgPercent': 'to all damage', | |||
'allAttributes': 'to all attributes', | |||
'xpIncrease': 'additional xp per kill', | |||
'elementArcanePercent': 'increased arcane damage', | |||
'elementFrostPercent': 'increased frost damage', | |||
'elementFirePercent': 'increased fire damage', | |||
'elementHolyPercent': 'increased holy damage', | |||
'elementPhysicalPercent': 'increased physical damage', | |||
'elementPoisonPercent': 'increased poison damage', | |||
'elementArcaneResist': 'arcane resistance', | |||
'elementFrostResist': 'frost resistance', | |||
'elementFireResist': 'fire resistance', | |||
'elementHolyResist': 'holy resistance', | |||
'elementPhysicalResist': 'physical resistance', | |||
'elementPoisonResist': 'poison resistance', | |||
'elementAllResist': 'all resistance', | |||
//This stat is used for gambling when you can't see the stats | |||
'stats': 'stats' | |||
}; | |||
return { | |||
translate: function(stat) { | |||
return stats[stat]; | |||
} | |||
}; | |||
}); |
@@ -181,8 +181,10 @@ define([ | |||
}, | |||
onResize: function() { | |||
this.width = $('body').width(); | |||
this.height = $('body').height(); | |||
var zoom = window.devicePixelRatio; | |||
this.width = $('body').width() * zoom; | |||
this.height = $('body').height() * zoom; | |||
this.renderer.resize(this.width, this.height); | |||
if (window.player) { | |||
@@ -90,10 +90,11 @@ define([ | |||
this.find('[slot]') | |||
.removeData('item') | |||
.addClass('empty') | |||
.addClass('empty show-default-icon') | |||
.find('.icon') | |||
.off() | |||
.css('background', '') | |||
.css('background-image', '') | |||
.css('background-position', '') | |||
.on('click', this.buildSlot.bind(this)); | |||
items | |||
@@ -121,7 +122,7 @@ define([ | |||
var elSlot = this.find('[slot="' + slot + '"]'); | |||
elSlot | |||
.data('item', item) | |||
.removeClass('empty') | |||
.removeClass('empty show-default-icon') | |||
.find('.icon') | |||
.css('background', 'url("' + spritesheet + '") ' + imgX + 'px ' + imgY + 'px') | |||
.off() | |||
@@ -77,6 +77,25 @@ | |||
margin-bottom: 0px; | |||
} | |||
&.show-default-icon { | |||
.icon { | |||
opacity: 0.5; | |||
background-image: url('../../../images/uiIcons.png') !important; | |||
} | |||
&[slot="head"] .icon { background-position: -0px -448px; } | |||
&[slot="neck"] .icon { background-position: -64px -448px; } | |||
&[slot="chest"] .icon { background-position: -128px -448px; } | |||
&[slot="hands"] .icon { background-position: -192px -448px; } | |||
&[slot="finger"] .icon { background-position: -256px -448px; } | |||
&[slot="waist"] .icon { background-position: -320px -448px; } | |||
&[slot="legs"] .icon { background-position: -384px -448px; } | |||
&[slot="feet"] .icon { background-position: -448px -448px; } | |||
&[slot="trinket"] .icon { background-position: -448px -384px; } | |||
&[slot="twoHanded"] .icon { background-position: -384px -384px; } | |||
&[slot^="rune"] .icon { background-position: -320px -384px; } | |||
} | |||
.icon { | |||
height: 100%; | |||
} | |||
@@ -1,5 +1,6 @@ | |||
<div class="uiHelp"> | |||
<div class="row"><span class="topic">Movement: </span><br />WASD / Arrow Keys</div> | |||
<div class="row"><span class="topic">Cancel Movement: </span><br />Esc</div> | |||
<div class="row"><span class="topic">Combat: </span><br />Hover on an enemy and press 1 to enable auto-attack</div> | |||
<div class="row"><span class="topic">Chat: </span><br />Press Enter to open the chat window</div> | |||
<div class="row"><span class="topic">Inventory: </span><br />Press i to open your inventory</div> | |||
@@ -47,6 +47,7 @@ define([ | |||
items: [], | |||
shiftDown: false, | |||
ctrlDown: false, | |||
dragItem: null, | |||
dragEl: null, | |||
@@ -127,7 +128,7 @@ define([ | |||
itemEl | |||
.data('item', item) | |||
//.on('click', this.onClick.bind(this, itemEl, item)) | |||
.on('click', this.onClick.bind(this, item)) | |||
.on('mousedown', this.onMouseDown.bind(this, itemEl, item, true)) | |||
.on('mouseup', this.onMouseDown.bind(this, null, null, false)) | |||
.on('mousemove', this.onHover.bind(this, itemEl, item)) | |||
@@ -150,6 +151,20 @@ define([ | |||
} | |||
}, | |||
onClick: function(item) { | |||
if (!this.ctrlDown) | |||
return; | |||
client.request({ | |||
cpn: 'social', | |||
method: 'chat', | |||
data: { | |||
message: '{' + item.name + '}', | |||
item: item | |||
} | |||
}); | |||
}, | |||
onMouseDown: function(el, item, down, e) { | |||
if (e.button != 0) | |||
return; | |||
@@ -467,6 +482,8 @@ define([ | |||
if (this.hoverItem) | |||
this.onHover(); | |||
} | |||
else if (key == 'ctrl') | |||
this.ctrlDown = true; | |||
}, | |||
onKeyUp: function(key) { | |||
if (key == 'shift') { | |||
@@ -474,6 +491,8 @@ define([ | |||
if (this.hoverItem) | |||
this.onHover(); | |||
} | |||
else if (key == 'ctrl') | |||
this.ctrlDown = false; | |||
} | |||
}; | |||
}); |
@@ -17,12 +17,12 @@ define([ | |||
messages: [], | |||
maxTtl: 500, | |||
shiftDown: false, | |||
hoverItem: null, | |||
hoverFilter: false, | |||
postRender: function() { | |||
//HACK: Write a global manager | |||
//setInterval(this.fade.bind(this), 100); | |||
this.onEvent('onGetMessages', this.onGetMessages.bind(this)); | |||
this.onEvent('onDoWhisper', this.onDoWhisper.bind(this)); | |||
@@ -53,9 +53,8 @@ define([ | |||
}, | |||
onKeyDown: function(key, state) { | |||
if (key == 'enter') { | |||
if (key == 'enter') | |||
this.toggle(true); | |||
} | |||
}, | |||
onDoWhisper: function(charName) { | |||
@@ -75,7 +74,13 @@ define([ | |||
var container = this.find('.list'); | |||
messages.forEach(function(m) { | |||
var el = $('<div class="list-message ' + m.class + '">' + m.message + '</div>') | |||
var message = m.message; | |||
if (m.item) { | |||
var source = message.split(':')[0] + ': '; | |||
message = source + '<span class="q' + (m.item.quality || 0) + '">' + message.replace(source, '') + '</span>'; | |||
} | |||
var el = $('<div class="list-message ' + m.class + '">' + message + '</div>') | |||
.appendTo(container); | |||
if (m.type != null) | |||
@@ -83,6 +88,12 @@ define([ | |||
else | |||
el.addClass('info'); | |||
if (m.item) { | |||
el.find('span') | |||
.on('mousemove', this.showItemTooltip.bind(this, el, m.item)) | |||
.on('mouseleave', this.hideItemTooltip.bind(this)); | |||
} | |||
this.messages.push({ | |||
ttl: this.maxTtl, | |||
el: el | |||
@@ -92,6 +103,35 @@ define([ | |||
container.scrollTop(9999999); | |||
}, | |||
hideItemTooltip: function() { | |||
if (this.dragEl) { | |||
this.hoverCell = null; | |||
return; | |||
} | |||
events.emit('onHideItemTooltip', this.hoverItem); | |||
this.hoverItem = null; | |||
}, | |||
showItemTooltip: function(el, item, e) { | |||
if (item) | |||
this.hoverItem = item; | |||
else | |||
item = this.hoverItem; | |||
if (!item) | |||
return; | |||
var ttPos = null; | |||
if (el) { | |||
ttPos = { | |||
x: ~~(e.clientX + 32), | |||
y: ~~(e.clientY) | |||
}; | |||
} | |||
events.emit('onShowItemTooltip', item, ttPos, null, true); | |||
}, | |||
update: function() { | |||
return; | |||
var maxTtl = this.maxTtl; | |||
@@ -14,6 +14,8 @@ | |||
pointer-events: none; | |||
&.typing { | |||
pointer-events: all; | |||
.el.message { | |||
display: block; | |||
} | |||
@@ -100,6 +100,10 @@ define([ | |||
}, | |||
onGetParty: function(party) { | |||
// Destroy invite frame if you join a party | |||
if (this.invite) | |||
this.destroyInvite(); | |||
var container = this.find('.party .list') | |||
.empty(); | |||
@@ -179,10 +183,12 @@ define([ | |||
}, | |||
destroyInvite: function(e) { | |||
if ($(e.target).hasClass('btnAccept')) | |||
this.acceptInvite(); | |||
else | |||
this.declineInvite(); | |||
if (e) { | |||
if ($(e.target).hasClass('btnAccept')) | |||
this.acceptInvite(); | |||
else | |||
this.declineInvite(); | |||
} | |||
this.invite.el.remove(); | |||
this.invite = null; | |||
@@ -3,13 +3,15 @@ define([ | |||
'js/system/client', | |||
'html!ui/templates/smithing/template', | |||
'css!ui/templates/smithing/styles', | |||
'html!/ui/templates/smithing/templateItem' | |||
'html!/ui/templates/smithing/templateItem', | |||
'js/misc/statTranslations' | |||
], function( | |||
events, | |||
client, | |||
template, | |||
styles, | |||
templateItem | |||
templateItem, | |||
statTranslations | |||
) { | |||
return { | |||
tpl: template, | |||
@@ -89,7 +91,7 @@ define([ | |||
} | |||
result.addStatMsgs.forEach(function(a) { | |||
msg.msg += '<br /> ' + a; | |||
msg.msg += '<br /> ' + ((a.value > 0) ? '+' : '') + a.value + ' ' + statTranslations.translate(a.stat); | |||
}); | |||
events.emit('onGetAnnouncement', msg); | |||
@@ -48,6 +48,7 @@ | |||
bottom: -6px; | |||
color: @white; | |||
font-size: 18px; | |||
z-index: 2; | |||
text-shadow: 2px 2px 0 #2d2136, | |||
-2px -2px 0 #2d2136, | |||
2px -2px 0 #2d2136, | |||
@@ -18,6 +18,11 @@ define([ | |||
postRender: function() { | |||
this.onEvent('onGetTalk', this.onGetTalk.bind(this)); | |||
this.onEvent('onRezone', this.onRezone.bind(this)); | |||
}, | |||
onRezone: function() { | |||
this.hide(); | |||
}, | |||
onGetTalk: function(dialogue) { | |||
@@ -13,6 +13,7 @@ define([ | |||
target: null, | |||
lastHp: null, | |||
lastMana: null, | |||
lastLevel: null, | |||
postRender: function() { | |||
this.onEvent('onSetTarget', this.onSetTarget.bind(this)); | |||
@@ -50,6 +51,7 @@ define([ | |||
if (!this.target) { | |||
this.lastHp = null; | |||
this.lastMana = null; | |||
this.lastLevel = null; | |||
this.el.hide(); | |||
} else { | |||
var el = this.el; | |||
@@ -91,6 +93,16 @@ define([ | |||
var stats = target.stats.values; | |||
if (stats.level != this.lastLevel) { | |||
this.el.find('.infoLevel') | |||
.html('(' + stats.level + ')') | |||
.removeClass('high-level'); | |||
var crushing = (stats.level - 5 >= window.player.stats.level); | |||
if (crushing) | |||
this.el.find('.infoLevel').addClass('high-level'); | |||
} | |||
if (stats.hp != this.lastHp) { | |||
this.buildBar(0, stats.hp, stats.hpMax); | |||
this.lastHp = stats.hp; | |||
@@ -2,12 +2,14 @@ define([ | |||
'js/system/events', | |||
'css!ui/templates/tooltipItem/styles', | |||
'html!ui/templates/tooltipItem/template', | |||
'html!ui/templates/tooltipItem/templateTooltip' | |||
'html!ui/templates/tooltipItem/templateTooltip', | |||
'js/misc/statTranslations' | |||
], function( | |||
events, | |||
styles, | |||
template, | |||
tplTooltip | |||
tplTooltip, | |||
statTranslations | |||
) { | |||
return { | |||
tpl: template, | |||
@@ -59,7 +61,7 @@ define([ | |||
stats = Object.keys(tempStats) | |||
.map(function(s) { | |||
var statName = this.mapStat(s); | |||
var statName = statTranslations.translate(s); | |||
var value = tempStats[s]; | |||
if (['addCritChance', 'sprintChance', 'dmgPercent', 'xpIncrease'].indexOf(s) > -1) | |||
@@ -216,44 +218,6 @@ define([ | |||
if (!canAfford) | |||
this.tooltip.find('.worth').addClass('no-afford'); | |||
}, | |||
mapStat: function(stat) { | |||
return { | |||
'vit': 'vitality', | |||
'hpMax': 'vitality', | |||
'regenHp': 'health regeneration', | |||
'manaMax': 'maximum mana', | |||
'regenMana': 'mana regeneration', | |||
'str': 'strength', | |||
'int': 'intellect', | |||
'dex': 'dexterity', | |||
'armor': 'armor', | |||
'addCritChance': 'increased crit chance', | |||
'magicFind': 'magic find', | |||
'sprintChance': 'sprint chance', | |||
'dmgPercent': 'to all damage', | |||
'allAttributes': 'to all attributes', | |||
'xpIncrease': 'additional xp per kill', | |||
'elementArcanePercent': 'increased arcane damage', | |||
'elementFrostPercent': 'increased frost damage', | |||
'elementFirePercent': 'increased fire damage', | |||
'elementHolyPercent': 'increased holy damage', | |||
'elementPhysicalPercent': 'increased physical damage', | |||
'elementPoisonPercent': 'increased poison damage', | |||
'elementArcaneResist': 'arcane resistance', | |||
'elementFrostResist': 'frost resistance', | |||
'elementFireResist': 'fire resistance', | |||
'elementHolyResist': 'holy resistance', | |||
'elementPhysicalResist': 'physical resistance', | |||
'elementPoisonResist': 'poison resistance', | |||
'elementAllResist': 'all resistance', | |||
//This stat is used for gambling when you can't see the stats | |||
'stats': 'stats' | |||
}[stat]; | |||
} | |||
}; | |||
}); |
@@ -1,3 +1,10 @@ | |||
<div class="uiTrade uiInventory"> | |||
<div class="heading"> | |||
<div class="heading-text">trade</div> | |||
</div> | |||
<div class="stats"> | |||
<div class="list"></div> | |||
</div> | |||
<div class="grid"></div> | |||
<div class="tooltip"></div> | |||
</div> |
@@ -23,6 +23,8 @@ define([ | |||
}, | |||
onGetTradeList: function(itemList, action) { | |||
this.find('.heading-text').html(action); | |||
var uiInventory = $('.uiInventory').data('ui'); | |||
var container = this.el.find('.grid') | |||
@@ -54,8 +56,14 @@ define([ | |||
return 0; | |||
}); | |||
var iLen = buyItems.length; | |||
var iLen = Math.max(buyItems.length, 50); | |||
for (var i = 0; i < iLen; i++) { | |||
if (!buyItems[i]) { | |||
$(tplItem).appendTo(container); | |||
continue; | |||
} | |||
var item = $.extend(true, {}, buyItems[i]); | |||
item.worth = ~~(itemList.markup * item.worth); | |||
@@ -74,7 +82,7 @@ define([ | |||
} | |||
var imgX = (-item.sprite[0] * size) + offset; | |||
var imgY = (-item.sprite[1] * size) + offset + 4; | |||
var imgY = (-item.sprite[1] * size) + offset; | |||
var itemEl = $(tplItem) | |||
.appendTo(container); | |||
@@ -3,13 +3,15 @@ define([ | |||
'misc/messages', | |||
'security/connections', | |||
'leaderboard/leaderboard', | |||
'config/skins' | |||
'config/skins', | |||
'misc/profanities' | |||
], function( | |||
io, | |||
messages, | |||
connections, | |||
leaderboard, | |||
skins | |||
skins, | |||
profanities | |||
) { | |||
return { | |||
type: 'auth', | |||
@@ -252,6 +254,11 @@ define([ | |||
} | |||
} | |||
if (!profanities.isClean(credentials.username)) { | |||
msg.callback(messages.login.invalid); | |||
return; | |||
} | |||
io.get({ | |||
ent: credentials.username, | |||
field: 'login', | |||
@@ -295,6 +302,11 @@ define([ | |||
return; | |||
} | |||
if (!profanities.isClean(data.name)) { | |||
msg.callback(messages.login.invalid); | |||
return; | |||
} | |||
io.get({ | |||
ent: data.name, | |||
field: 'character', | |||
@@ -26,7 +26,7 @@ define([ | |||
return false; | |||
} | |||
else if (targetName != null) { | |||
target = this.obj.instance.objects.objects.find(o => o.name.toLowerCase() == targetName); | |||
target = this.obj.instance.objects.objects.find(o => ((o.name) && (o.name.toLowerCase() == targetName))); | |||
if (!target) | |||
return false; | |||
} | |||
@@ -95,8 +95,18 @@ define([ | |||
if (stateConfig.cpn) { | |||
var cpn = sourceObj[stateConfig.cpn]; | |||
cpn[stateConfig.method].apply(cpn, stateConfig.args); | |||
return; | |||
var newArgs = extend(true, [], stateConfig.args); | |||
newArgs.push(this.obj); | |||
var result = cpn[stateConfig.method].apply(cpn, newArgs); | |||
if (stateConfig.goto) { | |||
if (result) | |||
return this.getState(sourceObj, stateConfig.goto.success); | |||
else | |||
return this.getState(sourceObj, stateConfig.goto.failure); | |||
} | |||
else | |||
return null; | |||
} | |||
var result = { | |||
@@ -158,6 +168,26 @@ define([ | |||
return { | |||
type: 'dialogue' | |||
}; | |||
}, | |||
//These don't belong here, but I can't figure out where to put them right now | |||
//They are actions that can be performed while chatting with someone | |||
teleport: function(msg) { | |||
this.obj.syncer.set(true, 'dialogue', 'state', null); | |||
var portal = extend(true, {}, require('./components/portal'), msg); | |||
portal.collisionEnter(this.obj); | |||
}, | |||
getItem: function(msg, source) { | |||
var inventory = this.obj.inventory; | |||
var exists = inventory.items.find(i => (i.name == msg.item.name)); | |||
if (!exists) { | |||
inventory.getItem(msg.item); | |||
return true; | |||
} | |||
else | |||
return false; | |||
} | |||
}; | |||
}); |
@@ -153,9 +153,10 @@ define([ | |||
var stash = this.obj.stash; | |||
if (!stash.active) | |||
return; | |||
var clonedItem = extend(true, {}, item); | |||
this.destroyItem(id); | |||
stash.deposit(item); | |||
stash.deposit(clonedItem); | |||
}, | |||
salvageItem: function(id) { | |||
@@ -376,6 +377,9 @@ define([ | |||
if (this.obj.player) | |||
delete item.fromMob; | |||
//Store the quantity to send to the player | |||
var quantity = item.quantity; | |||
//Material? | |||
var exists = false; | |||
if ((item.material) || (item.quest)) { | |||
@@ -437,8 +441,8 @@ define([ | |||
var messages = []; | |||
var msg = item.name; | |||
if (item.quantity) | |||
msg += ' x' + item.quantity; | |||
if (quantity) | |||
msg += ' x' + quantity; | |||
messages.push({ | |||
class: 'q' + item.quality, | |||
message: 'loot (' + msg + ')', | |||
@@ -30,7 +30,12 @@ define([ | |||
quest.active = (this.obj.zoneName == quest.zoneName); | |||
this.quests.push(quest); | |||
quest.init(hideMessage); | |||
if (!quest.init(hideMessage)) { | |||
this.quests.spliceWhere(q => (q == quest)); | |||
return false; | |||
} | |||
else | |||
return true; | |||
}, | |||
complete: function(id) { | |||
@@ -81,6 +81,8 @@ define([ | |||
if (t.rep > rep) | |||
break; | |||
else if (i == tLen - 1) | |||
tier = i; | |||
} | |||
if (tier < 0) | |||
@@ -130,6 +130,7 @@ define([ | |||
messages: [{ | |||
class: msgStyle, | |||
message: prefix + charname + ': ' + msg.data.message, | |||
item: msg.data.item, | |||
type: 'chat' | |||
}] | |||
} | |||
@@ -181,7 +182,10 @@ define([ | |||
this.updatePartyOnThread(); | |||
} | |||
this.party.push(sourceId); | |||
// Only add if not yet in party | |||
if (!this.party.find(id => (id === sourceId))) | |||
this.party.push(sourceId); | |||
this.updatePartyOnThread(); | |||
this.party.forEach(function(p) { | |||
@@ -205,7 +205,6 @@ define([ | |||
kill: function(target) { | |||
var level = target.stats.values.level; | |||
var inc = level * 10; | |||
//Who should get xp? | |||
var aggroList = target.aggro.list; | |||
@@ -217,21 +216,30 @@ define([ | |||
if (dmg <= 0) | |||
continue; | |||
var get = inc; | |||
var mult = 1; | |||
//How many party members contributed | |||
// Remember, maybe one of the aggro-ees might be a mob too | |||
var party = a.obj.social ? a.obj.social.party : null; | |||
if (party) { | |||
var mult = aggroList.filter(function(f) { | |||
var partySize = aggroList.filter(function(f) { | |||
return ((a.damage > 0) && (party.indexOf(f.obj.serverId) > -1)); | |||
}).length; | |||
mult--; | |||
get *= (1 + (mult * 0.1)); | |||
get = ~~get; | |||
partySize--; | |||
mult = (1 + (partySize * 0.1)); | |||
} | |||
if (a.obj.stats) | |||
a.obj.stats.getXp(inc); | |||
if (a.obj.stats) { | |||
//Scale xp by source level so you can't just farm low level mobs (or get boosted on high level mobs). | |||
//Mobs that are farther then 10 levels from you, give no xp | |||
//We don't currently do this for quests/herb gathering | |||
var sourceLevel = a.obj.stats.values.level; | |||
var levelDelta = level - sourceLevel; | |||
var amount = level * 10 * mult; | |||
if (Math.abs(levelDelta) <= 10) | |||
amount = ~~(((sourceLevel + levelDelta) * 10) * Math.pow(1 - (Math.abs(levelDelta) / 10), 2) * mult); | |||
a.obj.stats.getXp(amount, this.obj); | |||
} | |||
a.obj.fireEvent('afterKillMob', target); | |||
@@ -52,9 +52,9 @@ define([ | |||
afterKillMob: function(item, mob) { | |||
var effect = item.effects.find(e => (e.factionId == 'gaekatla')); | |||
//var roll = Math.random() * 100; | |||
//if (roll >= this.chance) | |||
// return; | |||
var roll = Math.random() * 100; | |||
if (roll >= this.chance) | |||
return; | |||
//Spawn a mob | |||
var mob = mob.instance.spawners.spawn({ | |||
@@ -111,7 +111,7 @@ module.exports = { | |||
}, | |||
faction: { | |||
id: 'gaekatla', | |||
tier: 1 | |||
tier: 6 | |||
}, | |||
markup: { | |||
buy: 0.25, | |||
@@ -61,7 +61,8 @@ define([ | |||
quest.obj = obj; | |||
quest.zoneName = zoneName; | |||
oQuests.obtain(quest, !!template); | |||
if (!oQuests.obtain(quest, !!template)) | |||
this.obtain(obj, template); | |||
} | |||
}; | |||
}); |
@@ -15,6 +15,8 @@ define([ | |||
} | |||
this.description = 'Gather ' + this.have + '/' + this.need + ' herbs'; | |||
return true; | |||
}, | |||
events: { | |||
@@ -26,14 +26,22 @@ define([ | |||
if (!this.mobName) { | |||
var mobCounts = this.obj.instance.spawners.mobTypes; | |||
var keys = Object.keys(mobTypes).filter(function(m) { | |||
var mobBlueprint = mobTypes[m]; | |||
return ( | |||
(m != 'default') && | |||
( | |||
(mobTypes[m].attackable) || | |||
(mobTypes[m].attackable == null) | |||
) | |||
(mobBlueprint.attackable) || | |||
(mobBlueprint.attackable == null) | |||
) && | |||
(mobBlueprint.level <= ~~(this.obj.stats.values.level * 1.35)) | |||
); | |||
}); | |||
}, this); | |||
//No level appropriate mobs found | |||
if (keys.length == 0) | |||
return false; | |||
this.mobType = keys[~~(Math.random() * keys.length)]; | |||
var needMax = 8; | |||
this.mobName = this.mobType.replace(/\w\S*/g, function(txt) { | |||
@@ -45,6 +53,8 @@ define([ | |||
} | |||
this.description = 'Kill ' + this.have + '/' + this.need + ' ' + this.mobName; | |||
return true; | |||
}, | |||
events: { | |||
@@ -17,6 +17,8 @@ define([ | |||
} | |||
this.description = 'Loot 1x ' + this.slotName + ' slot item'; | |||
return true; | |||
}, | |||
events: { | |||
@@ -18,8 +18,19 @@ define([ | |||
var mobTypes = this.obj.instance.spawners.zone.mobs; | |||
var mobCounts = this.obj.instance.spawners.mobTypes; | |||
var keys = Object.keys(mobTypes).filter(function(m) { | |||
return ((m != 'default') && (mobTypes[m].questItem)); | |||
}); | |||
var mobBlueprint = mobTypes[m]; | |||
return ( | |||
(m != 'default') && | |||
(mobBlueprint.questItem) && | |||
(mobBlueprint.level <= (this.obj.stats.values.level * 1.35)) | |||
); | |||
}, this); | |||
//No level appropriate mobs found | |||
if (keys.length == 0) | |||
return false; | |||
this.mobType = keys[~~(Math.random() * keys.length)]; | |||
var needMax = 8; | |||
this.mobName = this.mobType.replace(/\w\S*/g, function(txt) { | |||
@@ -33,6 +44,8 @@ define([ | |||
this.name = this.item.name + ' Gatherer'; | |||
this.description = 'Loot ' + this.have + '/' + this.need + ' ' + this.item.name + ' from ' + this.mobName; | |||
return true; | |||
}, | |||
oComplete: function() { | |||
@@ -5,7 +5,9 @@ define([ | |||
) { | |||
return { | |||
init: function(hideMessage) { | |||
this.build(); | |||
if (!this.build()) | |||
return false; | |||
this.obj.syncer.setArray(true, 'quests', 'obtainQuests', this.simplify(true)); | |||
if (!hideMessage) { | |||
@@ -17,6 +19,8 @@ define([ | |||
}] | |||
}, [this.obj.serverId]); | |||
} | |||
return true; | |||
}, | |||
ready: function() { | |||
@@ -67,6 +67,7 @@ define([ | |||
duration: 70, | |||
targetGround: true, | |||
needLos: true, | |||
cast: function(action) { | |||
var obj = this.obj; | |||
@@ -16,6 +16,8 @@ define([ | |||
statMult: 1, | |||
targetGround: true, | |||
needLos: true, | |||
damage: 10, | |||
delay: 10, | |||
@@ -45,7 +45,10 @@ define([ | |||
var value = item.enchantedStats[p]; | |||
if (item.stats[p]) { | |||
result.addStatMsgs.push('-' + value + ' ' + p); | |||
result.addStatMsgs.push({ | |||
stat: p, | |||
value: -value | |||
}); | |||
item.stats[p] -= value; | |||
if (item.stats[p] <= 0) | |||
delete item.stats[p]; | |||
@@ -245,8 +245,12 @@ define([ | |||
value = Math.ceil(random.norm(statBlueprint.min, statBlueprint.max)); | |||
if (blueprint.statCount) { | |||
if (result) | |||
result.addStatMsgs.push('+' + value + ' ' + stat); | |||
if (result) { | |||
result.addStatMsgs.push({ | |||
stat: stat, | |||
value: value | |||
}); | |||
} | |||
if (!item.enchantedStats) | |||
item.enchantedStats = {}; | |||
@@ -120,7 +120,7 @@ define([ | |||
if (m.qualityMult) | |||
max *= (m.qualityMult * (item.quality + 1)); | |||
var quantity = Math.ceil(random.norm(0, 1) * max); | |||
var quantity = Math.ceil(random.norm(0, 1) * max) || 1; | |||
if (maxRoll) | |||
quantity = Math.ceil(max); | |||
@@ -5,6 +5,7 @@ define([ | |||
) { | |||
return { | |||
login: { | |||
invalid: 'invalid name chosen', | |||
exists: 'username exists, please try another', | |||
allFields: 'please complete all fields', | |||
illegal: 'illegal characters in username/password', | |||
@@ -0,0 +1,233 @@ | |||
define([ | |||
], function( | |||
) { | |||
var config = [ | |||
'ahole', | |||
'anal', | |||
'anilingus', | |||
'anus', | |||
'areola', | |||
'ass', | |||
'b1tch', | |||
'ballsack', | |||
'bimbo', | |||
'bitch', | |||
'blowjob', | |||
'bollock', | |||
'boner', | |||
'boob', | |||
'breast', | |||
'breasts', | |||
'bukkake', | |||
'bullshit', | |||
'busty', | |||
'butt', | |||
'cameltoe', | |||
'carpetmuncher', | |||
'chinc', | |||
'chink', | |||
'chode', | |||
'climax', | |||
'clit', | |||
'cock', | |||
'coital', | |||
'condom', | |||
'coon', | |||
'crap', | |||
'cum', | |||
'cunilingus', | |||
'cunnilingus', | |||
'cunt', | |||
'dammit', | |||
'damn', | |||
'dick', | |||
'dike', | |||
'dildo', | |||
'dong', | |||
'douche', | |||
'dumbass', | |||
'dumbasses', | |||
'dyke', | |||
'ejaculate', | |||
'erection', | |||
'erotic', | |||
'fack', | |||
'fag', | |||
'fart', | |||
'felch', | |||
'fellate', | |||
'fellatio', | |||
'feltch', | |||
'fisting', | |||
'fondle', | |||
'foreskin', | |||
'fubar', | |||
'fuck', | |||
'fuk', | |||
'gay', | |||
'goatse', | |||
'godamn', | |||
'goddammit', | |||
'goddamn', | |||
'goldenshower', | |||
'gonad', | |||
'gspot', | |||
'gtfo', | |||
'handjob', | |||
'hardon', | |||
'hell', | |||
'herpes', | |||
'hitler', | |||
'hiv', | |||
'homo', | |||
'hooker', | |||
'hooter', | |||
'horny', | |||
'hump', | |||
'hymen', | |||
'incest', | |||
'jap', | |||
'jerkoff', | |||
'jism', | |||
'jiz', | |||
'kinky', | |||
'kkk', | |||
'labia', | |||
'lech', | |||
'lesbian', | |||
'lesbo', | |||
'lezbian', | |||
'lezbo', | |||
'lube', | |||
'masterbat', | |||
'masturbat', | |||
'menstruat', | |||
'muff', | |||
'nad', | |||
'naked', | |||
'nazi', | |||
'negro', | |||
'nigga', | |||
'nigger', | |||
'nipple', | |||
'nympho', | |||
'oral', | |||
'orgasm', | |||
'orgies', | |||
'orgy', | |||
'pantie', | |||
'panty', | |||
'pedo', | |||
'pee', | |||
'penetrat', | |||
'penial', | |||
'penile', | |||
'penis', | |||
'phalli', | |||
'phuck', | |||
'pimp', | |||
'piss', | |||
'pms', | |||
'poon', | |||
'porn', | |||
'prick', | |||
'prostitut', | |||
'pube', | |||
'pubic', | |||
'pubis', | |||
'puss', | |||
'pussies', | |||
'pussy', | |||
'puto', | |||
'queaf', | |||
'queef', | |||
'queer', | |||
'rape', | |||
'rapist', | |||
'rectal', | |||
'rectum', | |||
'rectus', | |||
'reich', | |||
'retard', | |||
'rimjob', | |||
'ritard', | |||
'rump', | |||
'schlong', | |||
'screw', | |||
'scrote', | |||
'scrotum', | |||
'semen', | |||
'sex', | |||
'shit', | |||
'skank', | |||
'slut', | |||
'smut', | |||
'snatch', | |||
'sodom', | |||
'sperm', | |||
'spunk', | |||
'stfu', | |||
'stiffy', | |||
'strip', | |||
'stroke', | |||
'stupid', | |||
'suck', | |||
'tampon', | |||
'tard', | |||
'teabag', | |||
'teat', | |||
'teste', | |||
'testicle', | |||
'testis', | |||
'thrust', | |||
'tit', | |||
'tramp', | |||
'transsex', | |||
'turd', | |||
'tush', | |||
'twat', | |||
'undies', | |||
'urinal', | |||
'urine', | |||
'uterus', | |||
'vag', | |||
'vagina', | |||
'viagra', | |||
'virgin', | |||
'vomit', | |||
'voyeur', | |||
'vulva', | |||
'wang', | |||
'wank', | |||
'weenie', | |||
'weewee', | |||
'weiner', | |||
'wench', | |||
'wetback', | |||
'whoralicious', | |||
'whore', | |||
'whoring', | |||
'wigger', | |||
'womb', | |||
'woody', | |||
'wtf', | |||
'xxx' | |||
]; | |||
var cLen = config.length; | |||
return { | |||
isClean: function(text) { | |||
var cb = text.indexOf.bind(text); | |||
for (var i = 0; i < cLen; i++) { | |||
if (cb(config[i]) > -1) | |||
return false; | |||
} | |||
return true; | |||
} | |||
}; | |||
}); |
@@ -203,7 +203,6 @@ define([ | |||
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]; | |||
@@ -217,11 +216,20 @@ define([ | |||
x: i, | |||
y: j | |||
}; | |||
} else { | |||
//If the only contents are notices, we can still use it | |||
var allNotices = !cell.some(c => !c.notice); | |||
if (allNotices) { | |||
return { | |||
x: i, | |||
y: j | |||
}; | |||
} | |||
} | |||
} | |||
} | |||
return result; | |||
return null; | |||
}, | |||
getPath: function(from, to) { | |||
@@ -270,7 +278,7 @@ define([ | |||
if (node) | |||
return node.isWall(); | |||
else | |||
return false; | |||
return true; | |||
}, | |||
isCellOpen: function(x, y) { | |||
if ((x < 0) || (y < 0) || (x >= this.width) | (y >= this.height)) | |||