-
-
Save shdwjk/f4875b572ab7d2827e9868479a185678 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Easy Experience Script: | |
This script will create a character called ExperienceThresholds that it uses for most of its functionality. If there is already an | |
ExperienceThresholds character present, it will not make one; please make sure that you do not have a self-made ExperienceThresholds character | |
(highly unlikely I would think ;) ) | |
---------------------------------------------------------------------------------------- | |
Use the following chat commands to utilize this script: | |
!xp challenge @{token_id/character_id}: Adds a character's npc-xp attribute value to the Session XP tally in the ExperienceThresholds character. | |
!xp miscXP ###: Adds a manually entered XP value to the Session XP tally in ExperienceThresholds. | |
!xp session: Divides the Session XP by the number of PCs (defined as characters that have a player-name entry), adds that xp to each PC's | |
current experience, and then sets the Session XP max field to the current field before resetting the current field to 0. Will also send | |
a chat message congratulating the character on leveling up if this brings that character's current | |
experience above or equal to the experience|max value. | |
---------------------------------------------------------------------------------------- | |
The script will also automatically set the experience|max value of all PCs based on their current level, and will update this whenever their level | |
changes. Experience Thresholds can be updated by changing the threshold values (2-20) in ExperienceThresholds. | |
*/ | |
var EASYEXPERIENCE = EASYEXPERIENCE || (function() { | |
'use strict'; | |
var version = '0.0.2', | |
lastUpdate = 1461880298, | |
schemaVersion = 0.1, | |
ExperienceThresholds, | |
ch = function (c) { | |
var entities = { | |
'<' : 'lt', | |
'>' : 'gt', | |
"'" : '#39', | |
'@' : '#64', | |
'{' : '#123', | |
'|' : '#124', | |
'}' : '#125', | |
'[' : '#91', | |
']' : '#93', | |
'"' : 'quot', | |
'-' : 'mdash', | |
' ' : 'nbsp' | |
}; | |
if(_.has(entities,c) ){ | |
return ('&'+entities[c]+';'); | |
} | |
return ''; | |
}, | |
checkInstall = function() { | |
log('-=> Character Experience v'+version+' <=- ['+(new Date(lastUpdate*1000))+']'); | |
if( ! _.has(state,'EASYEXPERIENCE') || state.EASYEXPERIENCE.version !== schemaVersion) { | |
log(' > Updating Schema to v'+schemaVersion+' <'); | |
state.EASYEXPERIENCE = { | |
version: schemaVersion, | |
config: { | |
}, | |
policies: { | |
global: { | |
recoveryUpdatesMaximum: false | |
}, | |
byAttribute: { | |
}, | |
byCharacter: { | |
} | |
} | |
}; | |
} | |
createThresholds(); | |
}, | |
playerCharacters = function() { | |
/* start the chain with all the attribute objects named 'player-name' */ | |
return _.chain(filterObjs((o) => { | |
return (o.get('type')==='attribute' && o.get('name')==='player-name'); | |
})) | |
//.tap((o)=>{log('chain started '+o.length);}) | |
/* IN: Array of Attribute Objects */ | |
/* extract the characterid from each */ | |
.reduce((m,o)=>{ | |
let obj={}; | |
obj.cid=o.get('characterid'); | |
obj['player-name']=o; | |
m.push(obj); | |
return m; | |
},[]) | |
//.tap((o)=>{log('after .reduce '+ o.length);}) | |
/* IN: Array of Objects with | |
* Character ID in property cid | |
* attribute in [attributeName] | |
*/ | |
/* add characters to the objects */ | |
.map((o)=>{ | |
o.char=getObj('character',o.cid); | |
return o; | |
}) | |
//.tap((o)=>{log('after character added '+o.length);}) | |
/* IN: Array of Objects with | |
* Character ID in property cid | |
* attribute in [attributeName] | |
* character in property char | |
*/ | |
/* remove any entries that didn't have Characters */ | |
.reject( (o)=> {return _.isUndefined(o.char);} ) | |
//.tap((o)=>{log('after .reject '+o.length);}) | |
/*IN: Array of Objects cleaned of undefined characters | |
* with character ID's, 'player-name' attribute in ['player-name] | |
* and character in property char | |
**** | |
* add the experience attribute to a property called xp for all characters*/ | |
.map( (o)=>{ | |
o.xp = findObjs({ | |
type: 'attribute', | |
name: 'experience', | |
characterid: o.cid | |
})[0]; | |
if(! o.xp.get('current')){ | |
o.xp.set('current', 0); | |
} | |
return o; | |
}) | |
/* IN: Array of Character Objects */ | |
/* Unwrap Chain and return the array */ | |
.value(); | |
}, | |
getThresholds = function(){ | |
return _.chain(filterObjs((o) => { | |
return (o.get('type')==='attribute' && o.get('name')==='Session XP'); | |
})) | |
.reduce((m,o)=>{ | |
let obj={}; | |
obj.cid=o.get('characterid'); | |
obj['Session XP']=o; | |
m.push(obj); | |
return m; | |
},[]) | |
.map((o)=>{ | |
let attrs=filterObjs( (a)=>{ | |
return a.get('type')==='attribute' && a.get('characterid')===o.cid && | |
_.contains(['2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20'],a.get('name')); | |
}); | |
o.attrs=o.attrs||{}; | |
_.each(attrs, (a)=>{ | |
o.attrs[a.get('name')]=a; | |
}); | |
return o; | |
}) | |
.value(); | |
}, | |
applyXP = function(){ | |
var pcs = playerCharacters(), | |
thresholds = getThresholds(), | |
numPCs, | |
sessionXP, | |
eachTrack = parseInt(0); | |
sessionXP = parseInt(thresholds[0]['Session XP'].get('current')); | |
if(sessionXP>0){ | |
numPCs = parseInt(pcs.length); | |
_.each(pcs, function(){ | |
pcs[eachTrack].xp.set('current', parseInt(pcs[eachTrack].xp.get('current')) + sessionXP/numPCs); | |
if(pcs[eachTrack].xp.get('current')>=pcs[eachTrack].xp.get('max')){ | |
sendChat('Congratulations! ' + pcs[eachTrack].char.get('name'), pcs[eachTrack].char.get('name') + ' has leveled up!'); | |
} | |
eachTrack++; | |
}); | |
thresholds[0]['Session XP'].set('max', thresholds[0]['Session XP'].get('current')); | |
thresholds[0]['Session XP'].set('current', 0); | |
}else{ | |
sendChat('Experience Tracker', '/w gm There is currently no experience in the Session XP attribute of the tracker. No XP was applied and your previous Session XP was not overwritten.'); | |
return; | |
} | |
}, | |
recordXP = function(xpAward){ | |
var thresholds=getThresholds(), | |
currXP; | |
currXP=parseInt(thresholds[0]['Session XP'].get('current')); | |
thresholds[0]['Session XP'].set('current', currXP + xpAward); | |
}, | |
HandleInput = function(msg_orig) { | |
var msg = _.clone(msg_orig), | |
args,attr,amount,chr,token,text=''; | |
if (msg.type !== 'api' || !playerIsGM(msg.playerid)){ | |
return; | |
} | |
if(_.has(msg,'inlinerolls')){//calculates inline rolls | |
msg.content = _.chain(msg.inlinerolls) | |
.reduce(function(m,v,k){ | |
m['$[['+k+']]']=v.results.total || 0; | |
return m; | |
},{}) | |
.reduce(function(m,v,k){ | |
return m.replace(k,v); | |
},msg.content) | |
.value(); | |
} | |
args = msg.content.split(/\s+/);//splits the message contents into discrete arguments | |
switch(args[0]) { | |
case '!xp': | |
if(args.length > 1) { | |
switch(args[1]) { | |
case 'session': | |
applyXP();// <character/token_id> <attribute_name> | |
// apply policy to put amounts back in | |
break; | |
case 'challenge': | |
chr = getObj('character', args[2]); | |
if( ! chr ) { | |
token = getObj('graphic', args[2]); | |
if(token) { | |
chr = getObj('character', token.get('represents')); | |
} | |
} | |
if(chr) { | |
attr = findObjs({_type: 'attribute', _characterid: chr.id, name: 'npc-xp'})[0]; | |
amount=parseInt(attr.get('current')); | |
} | |
if(attr) { | |
recordXP(amount); | |
} | |
break; | |
case 'miscXP': | |
amount = parseInt(args[2]); | |
if(amount){ | |
recordXP(amount); | |
} | |
break; | |
} | |
} else { | |
sendChat('Experience', '/w gm Something went wrong'); | |
} | |
break; | |
} | |
}, | |
levelUP = function(level){ | |
var thresholds = getThresholds(), | |
currXP = findObjs({ | |
type: 'attribute', | |
name: 'experience', | |
characterid: level.get('characterid') | |
}), | |
nextLevel; | |
if(level.get('current')<20){ | |
nextLevel = level.get('current') + 1; | |
currXP[0].set('max', thresholds[0].attrs[nextLevel].get('current')); | |
} | |
}, | |
createThresholds = function(){ | |
ExperienceThresholds = findObjs({ | |
_type: "character", | |
name: "ExperienceThresholds" | |
})[0]; | |
if (!ExperienceThresholds) { | |
ExperienceThresholds = createObj("character", { | |
name: "ExperienceThresholds" | |
}); | |
let levels = { | |
"Session XP": 0, | |
"2": 2000, | |
"3": 5000, | |
"4": 9000, | |
"5": 15000, | |
"6": 23000, | |
"7": 35000, | |
"8": 51000, | |
"9": 75000, | |
"10": 105000, | |
"11": 155000, | |
"12": 220000, | |
"13": 315000, | |
"14": 445000, | |
"15": 635000, | |
"16": 890000, | |
"17": 1300000, | |
"18": 1800000, | |
"19": 2550000, | |
"20": 3600000 | |
}; | |
_.each(levels, (xp,lvl) => { | |
createObj('attribute',{ | |
name: lvl, | |
current: xp, | |
characterid: ExperienceThresholds.id | |
}); | |
}); | |
} | |
}, | |
RegisterEventHandlers = function() { | |
on('chat:message', HandleInput); | |
on('change:attribute:current',(a,p)=>{ | |
if(a.get('name') === 'level'){ | |
levelUP(a); | |
} | |
}); | |
}; | |
return { | |
CheckInstall: checkInstall, | |
RegisterEventHandlers: RegisterEventHandlers | |
}; | |
}()); | |
on("ready",function(){ | |
'use strict'; | |
EASYEXPERIENCE.CheckInstall(); | |
EASYEXPERIENCE.RegisterEventHandlers(); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment