Browse Source

Merge branch 'staging' into 'master'

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 !71
tags/v0.1.2^0
Big Bad Waffle 7 years ago
parent
commit
962217c360
46 changed files with 606 additions and 105 deletions
  1. BIN
     
  2. BIN
     
  3. +10
    -0
      src/client/js/components/chatter.js
  4. +0
    -1
      src/client/js/components/keyboardMover.js
  5. +4
    -2
      src/client/js/components/pather.js
  6. +6
    -2
      src/client/js/components/spellbook.js
  7. +1
    -0
      src/client/js/input.js
  8. +47
    -0
      src/client/js/misc/statTranslations.js
  9. +4
    -2
      src/client/js/renderer.js
  10. +4
    -3
      src/client/ui/templates/equipment/equipment.js
  11. +19
    -0
      src/client/ui/templates/equipment/styles.less
  12. +1
    -0
      src/client/ui/templates/help/template.html
  13. +20
    -1
      src/client/ui/templates/inventory/inventory.js
  14. +46
    -6
      src/client/ui/templates/messages/messages.js
  15. +2
    -0
      src/client/ui/templates/messages/styles.less
  16. +10
    -4
      src/client/ui/templates/party/party.js
  17. +5
    -3
      src/client/ui/templates/smithing/smithing.js
  18. +1
    -0
      src/client/ui/templates/spells/styles.less
  19. +5
    -0
      src/client/ui/templates/talk/talk.js
  20. +12
    -0
      src/client/ui/templates/target/target.js
  21. +5
    -41
      src/client/ui/templates/tooltipItem/tooltipItem.js
  22. +7
    -0
      src/client/ui/templates/trade/template.html
  23. +10
    -2
      src/client/ui/templates/trade/trade.js
  24. +14
    -2
      src/server/components/auth.js
  25. +33
    -3
      src/server/components/dialogue.js
  26. +8
    -4
      src/server/components/inventory.js
  27. +6
    -1
      src/server/components/quests.js
  28. +2
    -0
      src/server/components/reputation.js
  29. +5
    -1
      src/server/components/social.js
  30. +16
    -8
      src/server/components/stats.js
  31. +3
    -3
      src/server/config/factions/gaekatla.js
  32. +1
    -1
      src/server/config/maps/city/zone.js
  33. +2
    -1
      src/server/config/quests/questBuilder.js
  34. +2
    -0
      src/server/config/quests/templates/questGatherResource.js
  35. +14
    -4
      src/server/config/quests/templates/questKillX.js
  36. +2
    -0
      src/server/config/quests/templates/questLoot.js
  37. +15
    -2
      src/server/config/quests/templates/questLootGen.js
  38. +5
    -1
      src/server/config/quests/templates/questTemplate.js
  39. +1
    -0
      src/server/config/spells/spellHealingCircle.js
  40. +2
    -0
      src/server/config/spells/spellWarnBlast.js
  41. +4
    -1
      src/server/items/enchanter.js
  42. +6
    -2
      src/server/items/generators/stats.js
  43. +1
    -1
      src/server/items/salvager.js
  44. +1
    -0
      src/server/misc/messages.js
  45. +233
    -0
      src/server/misc/profanities.js
  46. +11
    -3
      src/server/world/physics.js

BIN
View File


BIN
View File


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

@@ -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
});
}
};
});

+ 0
- 1
src/client/js/components/keyboardMover.js View File

@@ -10,7 +10,6 @@ define([
return {
type: 'keyboardMover',

path: [],
moveCd: 0,
moveCdMax: 8,
direction: {


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

@@ -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),


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

@@ -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);


+ 1
- 0
src/client/js/input.js View File

@@ -22,6 +22,7 @@ define([
'9': 'tab',
'13': 'enter',
'16': 'shift',
'17': 'ctrl',
'27': 'esc',
'37': 'left',
'38': 'up',


+ 47
- 0
src/client/js/misc/statTranslations.js View File

@@ -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];
}
};
});

+ 4
- 2
src/client/js/renderer.js View File

@@ -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) {


+ 4
- 3
src/client/ui/templates/equipment/equipment.js View File

@@ -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()


+ 19
- 0
src/client/ui/templates/equipment/styles.less View File

@@ -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
- 0
src/client/ui/templates/help/template.html View File

@@ -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>


+ 20
- 1
src/client/ui/templates/inventory/inventory.js View File

@@ -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;
}
};
});

+ 46
- 6
src/client/ui/templates/messages/messages.js View File

@@ -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;


+ 2
- 0
src/client/ui/templates/messages/styles.less View File

@@ -14,6 +14,8 @@
pointer-events: none;

&.typing {
pointer-events: all;

.el.message {
display: block;
}


+ 10
- 4
src/client/ui/templates/party/party.js View File

@@ -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;


+ 5
- 3
src/client/ui/templates/smithing/smithing.js View File

@@ -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);


+ 1
- 0
src/client/ui/templates/spells/styles.less View File

@@ -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,


+ 5
- 0
src/client/ui/templates/talk/talk.js View File

@@ -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) {


+ 12
- 0
src/client/ui/templates/target/target.js View File

@@ -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;


+ 5
- 41
src/client/ui/templates/tooltipItem/tooltipItem.js View File

@@ -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];
}
};
});

+ 7
- 0
src/client/ui/templates/trade/template.html View File

@@ -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>

+ 10
- 2
src/client/ui/templates/trade/trade.js View File

@@ -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);


+ 14
- 2
src/server/components/auth.js View File

@@ -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',


+ 33
- 3
src/server/components/dialogue.js View File

@@ -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;
}
};
});

+ 8
- 4
src/server/components/inventory.js View File

@@ -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 + ')',


+ 6
- 1
src/server/components/quests.js View File

@@ -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) {


+ 2
- 0
src/server/components/reputation.js View File

@@ -81,6 +81,8 @@ define([

if (t.rep > rep)
break;
else if (i == tLen - 1)
tier = i;
}

if (tier < 0)


+ 5
- 1
src/server/components/social.js View File

@@ -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) {


+ 16
- 8
src/server/components/stats.js View File

@@ -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);


+ 3
- 3
src/server/config/factions/gaekatla.js View File

@@ -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({


+ 1
- 1
src/server/config/maps/city/zone.js View File

@@ -111,7 +111,7 @@ module.exports = {
},
faction: {
id: 'gaekatla',
tier: 1
tier: 6
},
markup: {
buy: 0.25,


+ 2
- 1
src/server/config/quests/questBuilder.js View File

@@ -61,7 +61,8 @@ define([
quest.obj = obj;
quest.zoneName = zoneName;

oQuests.obtain(quest, !!template);
if (!oQuests.obtain(quest, !!template))
this.obtain(obj, template);
}
};
});

+ 2
- 0
src/server/config/quests/templates/questGatherResource.js View File

@@ -15,6 +15,8 @@ define([
}

this.description = 'Gather ' + this.have + '/' + this.need + ' herbs';

return true;
},

events: {


+ 14
- 4
src/server/config/quests/templates/questKillX.js View File

@@ -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: {


+ 2
- 0
src/server/config/quests/templates/questLoot.js View File

@@ -17,6 +17,8 @@ define([
}

this.description = 'Loot 1x ' + this.slotName + ' slot item';

return true;
},

events: {


+ 15
- 2
src/server/config/quests/templates/questLootGen.js View File

@@ -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
- 1
src/server/config/quests/templates/questTemplate.js View File

@@ -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() {


+ 1
- 0
src/server/config/spells/spellHealingCircle.js View File

@@ -67,6 +67,7 @@ define([
duration: 70,

targetGround: true,
needLos: true,

cast: function(action) {
var obj = this.obj;


+ 2
- 0
src/server/config/spells/spellWarnBlast.js View File

@@ -16,6 +16,8 @@ define([
statMult: 1,
targetGround: true,

needLos: true,

damage: 10,

delay: 10,


+ 4
- 1
src/server/items/enchanter.js View File

@@ -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];


+ 6
- 2
src/server/items/generators/stats.js View File

@@ -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 = {};


+ 1
- 1
src/server/items/salvager.js View File

@@ -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);



+ 1
- 0
src/server/misc/messages.js View File

@@ -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',


+ 233
- 0
src/server/misc/profanities.js View File

@@ -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;
}
};
});

+ 11
- 3
src/server/world/physics.js View File

@@ -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))


Loading…
Cancel
Save