mirror of
https://github.com/Nighthawk42/roll20-character-sheets.git
synced 2026-08-30 03:40:32 +00:00
RolemasterUnified Offocial: Tracker significant improvements
Still not really usuable, but it's at a stage people can see the basic stuff it can do. - Add tracker back - Add general "asCharacter" helpers - Tracker: - Can add data using new as character - Characters now remember their tracker - for All Characters methods to tracker - Tracker can set everyones AP/round message - Tracker can roll everyones initiative (not to turn tracker though) - Track base attributes - Add option for non-tracker initiative. - Clean up build so compiled/processed files go to build
This commit is contained in:
@@ -1706,6 +1706,12 @@ div.attacks {
|
||||
}
|
||||
|
||||
|
||||
|
||||
img.avatar {
|
||||
width: 4em;
|
||||
height: 4em;
|
||||
}
|
||||
|
||||
.repitem:nth-of-type(even) .trackedcharacter {
|
||||
background-color: var(--fancylightcolor);
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@
|
||||
</div>
|
||||
</rolltemplate>
|
||||
|
||||
<rolltemplate class='sheet-rolltemplate-rmutrackeradd'>
|
||||
<rolltemplate class="sheet-rolltemplate-rmutrackeradd">
|
||||
<div class='sheet-rolltemplate-rmumsg'>
|
||||
<i>{{whom}}</i> added to template.
|
||||
</div>
|
||||
@@ -2617,7 +2617,7 @@ Lists Selected <input type='number' name='comp_cmbaselistcount'> / 6
|
||||
<option value="13">Leviathan</option>
|
||||
</select>
|
||||
<select class='fancyselect' name='attr_type'>
|
||||
<option value='sl'>Sling</option><option value='sh'>Shield Bash</option><option value='un'>Unarmed Strike</option><option value='sp'>Spear</option><option value='tc'>Two Handed Club</option><option value='sc'>Scimitar</option><option value='rp'>Rapier</option><option value='ra'>Ram</option><option value='cba'>Cold Ball</option><option value='fba'>Fire ball</option><option value='ta'>Thrown Hand Axe</option><option value='all'>Arming Sword</option><option value='ma'>Mace</option><option value='any'>Arming Sword</option><option value='px'>Pole Axe</option><option value='ja'>Javelin</option><option value='ls'>Long Sword</option><option value='bi'>Bite</option><option value='we'>Arming Sword</option><option value='fa'>Falchion</option><option value='be'>Beak</option><option value='bo'>Bola</option><option value='handcrossbow'>Hand Crossbow</option><option value='cu'>Club</option><option value='hc'>Heavy Crossbow</option><option value='da'>Dagger</option><option value='bs'>Broadsword</option><option value='tr'>Trample</option><option value='bx'>Battle Axe</option><option value='si'>Stinger</option><option value='tx'>Two Handed Axe</option><option value='wi'>Whip</option><option value='wbo'>Water Bolt</option><option value='wm'>War Mattock</option><option value='tw'>War Hammer</option><option value='qs'>Quarterstaff</option><option value='fbo'>Fire Bolt</option><option value='ebo'>Earth Ball</option><option value='hx'>Hand Axe</option><option value='tp'>Thrown Spear</option><option value='ts'>Two Handed Sword</option><option value='ibo'>Ice bolt</option><option value='td'>Thrown Dagger</option><option value='rw'>Arming Sword</option><option value='cl'>Claw</option><option value='lc'>Light Crossbow</option><option value='ss'>Short Sword</option><option value='lba'>Lightning Ball</option><option value='sb'>Bow, Short</option><option value='gr'>Grapple</option><option value='lb'>Bow, Long</option><option value='ro'>Thrown Rock</option><option value='rt'>Thrown Rock</option><option value='cr'>Crush</option><option value='as'>Arming Sword</option><option value='ho'>Horn</option><option value='lbo'>Ligtning Bolt</option><option value='hf'>Heavy Flail</option><option value='sw'>Sweep</option>
|
||||
<option value='ss'>Short Sword</option><option value='fbo'>Fire Bolt</option><option value='qs'>Quarterstaff</option><option value='sw'>Sweep</option><option value='rw'>Arming Sword</option><option value='ibo'>Ice bolt</option><option value='ts'>Two Handed Sword</option><option value='ro'>Thrown Rock</option><option value='hf'>Heavy Flail</option><option value='wi'>Whip</option><option value='any'>Arming Sword</option><option value='si'>Stinger</option><option value='cr'>Crush</option><option value='lbo'>Ligtning Bolt</option><option value='lc'>Light Crossbow</option><option value='ra'>Ram</option><option value='gr'>Grapple</option><option value='ta'>Thrown Hand Axe</option><option value='bx'>Battle Axe</option><option value='tr'>Trample</option><option value='ma'>Mace</option><option value='we'>Arming Sword</option><option value='tc'>Two Handed Club</option><option value='ja'>Javelin</option><option value='hx'>Hand Axe</option><option value='lba'>Lightning Ball</option><option value='wm'>War Mattock</option><option value='fa'>Falchion</option><option value='tx'>Two Handed Axe</option><option value='bi'>Bite</option><option value='all'>Arming Sword</option><option value='ebo'>Earth Ball</option><option value='px'>Pole Axe</option><option value='da'>Dagger</option><option value='cba'>Cold Ball</option><option value='un'>Unarmed Strike</option><option value='rp'>Rapier</option><option value='sp'>Spear</option><option value='tp'>Thrown Spear</option><option value='tw'>War Hammer</option><option value='sl'>Sling</option><option value='cl'>Claw</option><option value='hc'>Heavy Crossbow</option><option value='wbo'>Water Bolt</option><option value='bs'>Broadsword</option><option value='as'>Arming Sword</option><option value='sc'>Scimitar</option><option value='ho'>Horn</option><option value='sb'>Bow, Short</option><option value='rt'>Thrown Rock</option><option value='fba'>Fire ball</option><option value='td'>Thrown Dagger</option><option value='cu'>Club</option><option value='bo'>Bola</option><option value='lb'>Bow, Long</option><option value='sh'>Shield Bash</option><option value='handcrossbow'>Hand Crossbow</option><option value='be'>Beak</option><option value='ls'>Long Sword</option>
|
||||
</select>
|
||||
|
||||
|
||||
@@ -3002,12 +3002,15 @@ Lists Selected <input type='number' name='comp_cmbaselistcount'> / 6
|
||||
<!-- Toolbar -->
|
||||
<div class='fancybox'>
|
||||
<button type='action' name='act_trackeraddcreature' class='fancybutton'>Add</button>
|
||||
<!--
|
||||
<button type='action' name='act_trackerrefreshall' class='fancybutton disabled'>Refresh All</button>
|
||||
<select class='fancyselect'>
|
||||
<option>1 AP/Phase</option>
|
||||
<option>2 AP/Phase</option>
|
||||
<option>4 AP/Phase</option>
|
||||
-->
|
||||
<select class='fancyselect' name="attr_apperphase">
|
||||
<option value="1">1 AP/Phase</option>
|
||||
<option value="2">2 AP/Phase</option>
|
||||
<option value="4">4 AP/Phase</option>
|
||||
</select>
|
||||
<button type='action' name='act_trackerrollinitiative' class='fancybutton'>Initiative</button>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -3015,10 +3018,74 @@ Lists Selected <input type='number' name='comp_cmbaselistcount'> / 6
|
||||
|
||||
</div>
|
||||
|
||||
<fieldset class='repeating_trackercharacter'>
|
||||
<div class='trackedcharacter'>
|
||||
<fieldset class='repeating_trackercharacter'>
|
||||
<div class="pcframebox">
|
||||
<img alt="Token" class='avatar' name="attr_character_token">
|
||||
<span name="attr_character_name"></span>
|
||||
<span name="attr_hp"></span>
|
||||
<span name="attr_hp_max"></span>
|
||||
<div>
|
||||
<input type="hidden" class="bar-value" name="attr_hp_percent" value="0">
|
||||
<div class="bar-track"> <div class="bar-progress"></div> </div>
|
||||
</div>
|
||||
<span name="attr_pp"></span>
|
||||
<span name="attr_pp_max"></span>
|
||||
<div>
|
||||
<input type="hidden" class="bar-value" name="attr_pp_percent" value="0">
|
||||
<div class="bar-track"> <div class="bar-progress"></div> </div>
|
||||
</div>
|
||||
|
||||
|
||||
<select name="attr_actionselect" class="fancyselect">
|
||||
<option value="melee">Melee</option>
|
||||
<option value="missile">Missile</option>
|
||||
<option value="spell">Spell</option>
|
||||
<option value="perception">Perception</option>
|
||||
<option value="eat">Eat</option>
|
||||
<option value="stand">Stand</option>
|
||||
<option value="pickup">Pickup Item</option>
|
||||
<option value="mount">Mount</option>
|
||||
<option value="dismount">Dismount</option>
|
||||
<option value="stringbow">String Bow</option>
|
||||
<option value="loadlight">Load Light Xbow</option>
|
||||
<option value="loadheavy">Load Heavy Xbox</option>
|
||||
<option value="fulldodge">Full Dodge</option>
|
||||
<option value="fullblock">Full Block</option>
|
||||
<option value="picklock ">Pick Lock</option>
|
||||
<option value="other">Other</option>
|
||||
</select>
|
||||
|
||||
<button type='action' name='act_deletetracked' class='fancybutton fancybuttoninline'>
|
||||
<span style="font-family:Pictos;">#</span>
|
||||
</button>
|
||||
|
||||
Chan <span name='attr_rr_channeling_bonus'></span>;
|
||||
Ess <span name='attr_rr_essence_bonus'></span>;
|
||||
Ment <span name='attr_rr_mentalism_bonus'></span>;
|
||||
Arcane <span name='attr_rr_arcane_bonus'></span>;
|
||||
Fear<span name='attr_rr_fear_bonus'></span>;
|
||||
Phys <span name='attr_rr_physical_bonus'></span>;
|
||||
|
||||
|
||||
AT (DB) <span name="attr_at"></span><span name="attr_activedb"></span>
|
||||
|
||||
|
||||
Parry <span name="attr_parry_mod"></span>
|
||||
Other <span name="attr_other_mod"></span>
|
||||
DB Mod <span name="attr_dbmod"></span>
|
||||
|
||||
Last Init: <span name='attr_lastinitiative'></span>
|
||||
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
|
||||
<fieldset class='repeating_trackercharacterX'>
|
||||
<div class='trackedcharacter pcframebox'>
|
||||
<div class='trackedname span2'>
|
||||
<span name='attr_trackedname'></span>
|
||||
<span name='attr_tokenid'></span>
|
||||
<span name='attr_characterid'></span>
|
||||
<button type='action' name='act_deletetracked' class='fancybutton fancybuttoninline'>
|
||||
<span style="font-family:Pictos;">#</span>
|
||||
</button>
|
||||
@@ -3122,11 +3189,11 @@ Lists Selected <input type='number' name='comp_cmbaselistcount'> / 6
|
||||
</div>
|
||||
|
||||
<div class='span2'>
|
||||
Chan <span name='attr_trackedchannelingrr'></span>;
|
||||
Ess <span name='attr_trackedessencerr'></span>;
|
||||
Ment <span name='attr_trackedmentalismrr'></span>;
|
||||
Fear<span name='attr_trackedfearrr'></span>;
|
||||
Phys <span name='attr_trackedphysicalrr'></span>;
|
||||
Chan <span name='attr_rr_channeling_bonus'></span>;
|
||||
Ess <span name='attr_rr_essence_bonus'></span>;
|
||||
Ment <span name='attr_rr_mentalism_bonus'></span>;
|
||||
Fear<span name='attr_rr_fear_bonus'></span>;
|
||||
Phys <span name='attr_rr_physical_bonus'></span>;
|
||||
</div>
|
||||
|
||||
<div class='spanall'>
|
||||
@@ -6683,8 +6750,12 @@ bleed and penalties you need side and location. A Z ends the list.<p>
|
||||
|
||||
<h3>Tokens</h3>
|
||||
|
||||
<p>Active Token ID: <input type="text" name="attr_activetokenid"> |
|
||||
Target Character ID: <input type="text" name="attr_target_characterid"></p>
|
||||
<p>Active Token ID: <input type="text" name="attr_activetokenid"> |
|
||||
Target Character ID: <input type="text" name="attr_target_characterid"> |
|
||||
Target Listeners: <input type="text" name="attr_target_listeners"> |
|
||||
Tracker <span name='attr_trackerid'></span>
|
||||
Tracker Prefix <span name='attr_trackerprefix'></span>
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
@@ -6793,7 +6864,7 @@ Sheet Version: <span name='attr_version'></span>
|
||||
|
||||
<br>
|
||||
|
||||
Revision c87c395f3b03746b0e9462fe1b395a3196849103
|
||||
Revision bd680cf8d34be84dc8dbebb09ccac98380a3450a
|
||||
|
||||
|
||||
<hr>
|
||||
@@ -8380,6 +8451,54 @@ function onCheck(str, func) {
|
||||
on(str, func);
|
||||
}
|
||||
|
||||
/** Sets the character ID and returns the current one.*/
|
||||
function setActiveCharacterId(id) {
|
||||
const ocid = getActiveCharacterId();
|
||||
const data = {
|
||||
id: '0',
|
||||
type: 'setActiveCharacter',
|
||||
data: id,
|
||||
};
|
||||
if (self.dispatchEvent) {
|
||||
const event = new CustomEvent('message');
|
||||
event.data = data;
|
||||
self.dispatchEvent(event);
|
||||
}
|
||||
else {
|
||||
self.onmessage({ data });
|
||||
}
|
||||
return ocid;
|
||||
}
|
||||
|
||||
function asCharacter(id, func) {
|
||||
const origid = setActiveCharacterId(id);
|
||||
const rv = func()
|
||||
setActiveCharacterId(origid);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
function rmuSetAttrsRemote(characterid, attrs, done) {
|
||||
// FIXME: Validate the damn args
|
||||
const myid = setActiveCharacterId(characterid);
|
||||
if (myid == characterid) {
|
||||
rmuerror("Set active and current character to the same", characterid);
|
||||
}
|
||||
rmuSetAttrs(attrs, done);
|
||||
setActiveCharacterId(myid);
|
||||
}
|
||||
|
||||
function rmuGetAttrsRemote(characterid, attrs, done) {
|
||||
// FIXME: Validate the damn args
|
||||
const myid = setActiveCharacterId(characterid);
|
||||
if (myid == characterid) {
|
||||
rmuerror("Set active and current character to the same", characterid);
|
||||
}
|
||||
rmuGetAttrs(attrs, done);
|
||||
setActiveCharacterId(myid);
|
||||
}
|
||||
|
||||
|
||||
onCheck("clicked:resetworkers", () => {
|
||||
pendingReset();
|
||||
});
|
||||
@@ -8445,6 +8564,7 @@ const knownproperties = {
|
||||
|
||||
// Roll20 Meta Stuff
|
||||
selectedcharacterid: { type: "string" },
|
||||
target_listeners: { type: "string" },
|
||||
};
|
||||
|
||||
function validateAttributes(attrs) {
|
||||
@@ -8502,13 +8622,13 @@ function VrmuSetAttrs(arg, fn) {
|
||||
}
|
||||
|
||||
function rmuGetAttrs(toget, handler) {
|
||||
validateAttributes(toget);
|
||||
//validateAttributes(toget);
|
||||
|
||||
return getAttrs(toget,handler);
|
||||
}
|
||||
|
||||
function rmuSetAttrs(toset, handler) {
|
||||
validateAttributes(toset);
|
||||
//validateAttributes(toset);
|
||||
|
||||
return setAttrs(toset, handler);
|
||||
}
|
||||
@@ -9023,7 +9143,7 @@ function lookupSkillResult(skill, skillinfo, umroll, total) {
|
||||
update[stat.aname + "_info"] = logmessage;
|
||||
// Update local cache
|
||||
statCache_[stat.abbr] = statBonus;
|
||||
setAttrs(update);
|
||||
//setAttrs(update);
|
||||
});
|
||||
|
||||
function updateAllSkills() {
|
||||
@@ -18698,6 +18818,7 @@ function doRollInitiative() {
|
||||
finishRoll(roll.rollId, {});
|
||||
const activetokenid = attacks.getDataFromRoll(roll.results.activetokenid.expression);
|
||||
const selectedcharacterid = attacks.getDataFromRoll(roll.results.selectedcharacterid.expression);
|
||||
rmuSetAttrs({lastinitiative: roll.results.total.result});
|
||||
const mycharacterid = getActiveCharacterId()
|
||||
// So are we the selected token? If so, update the token id
|
||||
console.log("Selected Char ID/My Char ID/Active Token ID",selectedcharacterid, mycharacterid, activetokenid)
|
||||
@@ -18706,10 +18827,25 @@ function doRollInitiative() {
|
||||
rmuSetAttrs({ activetokenid : activetokenid });
|
||||
console.log("My tokenid is", activetokenid);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
function doRollInitiativeNoTracker() {
|
||||
// roll20 treats floor as round to negative infinity, so ceil since they should be negative
|
||||
startRoll('@{whispertype} &{template:rmuinit} [[ [[ 2d10 ]] + @{initiative} + [[ceil(@{statuspenalty} / 10)]] ]] ' +
|
||||
'{\{actor=@{character_name} }} ' +
|
||||
'{\{bonus=@{initiative} }} ' +
|
||||
'{\{total=$[[2]]}} {\{roll=$[[0]]}} ' +
|
||||
'{\{maneuver=$[[1]] }}',
|
||||
(roll) => {
|
||||
rmuSetAttrs({lastinitiative: roll.results.total.result});
|
||||
finishRoll(roll.rollId, {});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**/
|
||||
function updatetokenmarkers() {
|
||||
console.log("updatetokenmarkers start");
|
||||
@@ -20544,6 +20680,41 @@ function messageHackery() {
|
||||
|
||||
let tracker = {}
|
||||
|
||||
tracker.repeatingprefix = "repeating_trackercharacter";
|
||||
|
||||
/*
|
||||
Movement
|
||||
Attacks
|
||||
Movement skills
|
||||
Footwork
|
||||
Spells.
|
||||
Initiative
|
||||
Perception*/
|
||||
|
||||
tracker.allAttributes = [
|
||||
"hp", "hp_max", "pp", "pp_max",
|
||||
"hp_percent", "pp_percent",
|
||||
"character_token",
|
||||
"character_name",
|
||||
"actionselect",
|
||||
"aptrack_loaded",
|
||||
"aptrack",
|
||||
"lastinitiative",
|
||||
"rr_channeling_bonus",
|
||||
"rr_arcane_bonus",
|
||||
"rr_essence_bonus",
|
||||
"rr_mentalism_bonus",
|
||||
"rr_fear_bonus",
|
||||
"rr_physical_bonus",
|
||||
"parry_mod",
|
||||
"other_mod",
|
||||
"dbmod",
|
||||
"activedb",
|
||||
"at"
|
||||
]
|
||||
|
||||
|
||||
|
||||
onCheck("clicked:trackedreturntocharacter", () => {
|
||||
setAttrs({sheetselect: "playersheet"});
|
||||
});
|
||||
@@ -20553,29 +20724,114 @@ onCheck("clicked:trackerinit", () => {
|
||||
setAttrs({sheetselect: "trackersheet"});
|
||||
});
|
||||
|
||||
|
||||
// Somone clicked the add target button. so lets add them
|
||||
// We just get the token_id and the character_id first.
|
||||
// Then we start getting all the other fields.
|
||||
onCheck("clicked:trackeraddcreature", () =>{
|
||||
tracker.dataGet('target', generateRowID());
|
||||
// tracker.dataGet('target', generateRowID());
|
||||
const roll_string = "&{template:rmutrackeradd} [[1d20]] " +
|
||||
"{\{who=Tracker}} " +
|
||||
"{\{targettokenid=[[0[@{target|token_id}]]]}} " +
|
||||
"{\{targetname=[[0[@{target|character_name}]]]}} " +
|
||||
"{\{targetcharacterid=[[0[@{target|character_id}]]]}}";
|
||||
console.log(roll_string);
|
||||
startRoll(roll_string, roll => {
|
||||
console.log(roll);
|
||||
const tokenid = attacks.getDataFromRoll(roll.results.targettokenid.expression);
|
||||
const characterid = attacks.getDataFromRoll(roll.results.targetcharacterid.expression);
|
||||
const targetname = attacks.getDataFromRoll(roll.results.targetname.expression);
|
||||
const updates = { targetname: targetname };
|
||||
console.log("Got tokenid and characterid", tokenid, characterid, roll);
|
||||
|
||||
tracker.addTarget(targetname, characterid, tokenid);
|
||||
finishRoll(roll.rollId, updates);
|
||||
});
|
||||
});
|
||||
|
||||
onCheck("clicked:repeating_trackercharacter:trackedrefresh", (ev) =>{
|
||||
const basename = ev.sourceAttribute.replace("_trackedrefresh", "");
|
||||
let rowid = basename.match("-.*");
|
||||
getAttrs([`${basename}_trackedname`], (data) => {
|
||||
tracker.dataGet(data[`${basename}_trackedname`], rowid);
|
||||
tracker.appendPrefix = function(prefix, object) {
|
||||
return Object.fromEntries(
|
||||
Object.entries(object).map(([key, value]) => [prefix + key, value])
|
||||
);
|
||||
}
|
||||
|
||||
// So when the AP per phase here triggers, set all the sheets
|
||||
// This si one way - tracker sets teh other sheets.
|
||||
onCheck("change:apperphase", (ev) => {
|
||||
console.log(ev)
|
||||
tracker.setAllSheets({actionapperphase:ev.newValue});
|
||||
});
|
||||
|
||||
/**
|
||||
* This is the main call to add items to the tracker.
|
||||
*/
|
||||
// FIXME: Should check for duplicates
|
||||
// FIXME: Should warn if no character id
|
||||
tracker.addTarget = function(name, characterid, tokenid) {
|
||||
const rowid = generateRowID();
|
||||
const prefix = `repeating_trackercharacter_${rowid}_`;
|
||||
|
||||
// First pass: Lets just add the basic item
|
||||
const updates = {}
|
||||
updates.trackedname = name;
|
||||
updates.tokenid = tokenid;
|
||||
updates.characterid = characterid;
|
||||
|
||||
console.log(tracker.appendPrefix(prefix, updates));
|
||||
setAttrs(tracker.appendPrefix(prefix, updates));
|
||||
|
||||
const trackerid = getActiveCharacterId();
|
||||
|
||||
// So as the character I need to let it know what tracker it has
|
||||
rmuSetAttrsRemote(characterid, {trackerid: trackerid, trackerprefix: prefix});
|
||||
|
||||
rmuGetAttrsRemote(characterid, tracker.allAttributes, (data) => {
|
||||
// this call back is in the context of the character.
|
||||
rmuSetAttrsRemote(trackerid, tracker.appendPrefix(prefix, data));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
tracker.setAllSheets = function(values) {
|
||||
tracker.forAllSheets((id) => {
|
||||
rmuSetAttrsRemote(id, values);
|
||||
});
|
||||
}
|
||||
|
||||
tracker.forAllSheets = function(func) {
|
||||
getSectionIDs(tracker.repeatingprefix, (ids) => {
|
||||
const toget = ids.map((x) => tracker.repeatingprefix + "_" + x + "_characterid");
|
||||
getAttrs(toget, (characterids) => {
|
||||
for (row in characterids) {
|
||||
func(characterids[row])
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
onCheck("clicked:trackerrollinitiative", (_) => {
|
||||
tracker.forAllSheets((id) => {
|
||||
asCharacter(id, () => {doRollInitiativeNoTracker()});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// old call
|
||||
onCheck("clicked:repeating_trackercharacter:deletetracked", (ev) => {
|
||||
const basename = ev.sourceAttribute.replace("_deletetracked", "");
|
||||
removeRepeatingRow(basename);
|
||||
});
|
||||
|
||||
// old call; now borked
|
||||
onCheck("clicked:repeating_trackercharacter:selecttarget", (ev) => {
|
||||
// We are keeping the last '_' as getTargetData doesn;t know about it
|
||||
const basename = ev.sourceAttribute.replace("selecttarget", "");
|
||||
attacks.getTargetData("target", basename)
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
// old call
|
||||
const fields = {
|
||||
// Type is the type of data.
|
||||
// Field is what we pull on the source character
|
||||
@@ -20598,6 +20854,7 @@ const fields = {
|
||||
}
|
||||
|
||||
/**/
|
||||
// old call
|
||||
tracker.extractResults = function(roll, prefix) {
|
||||
const results = {}
|
||||
const rr = roll.results;
|
||||
@@ -20620,6 +20877,7 @@ tracker.extractResults = function(roll, prefix) {
|
||||
return results;
|
||||
}
|
||||
|
||||
// old call
|
||||
tracker.buildString = function(whom) {
|
||||
let reqs = ["&{template:rmuattacktarget} [[1d20]]"];
|
||||
for (const field in fields) {
|
||||
@@ -20636,6 +20894,7 @@ tracker.buildString = function(whom) {
|
||||
}
|
||||
|
||||
|
||||
// old call
|
||||
tracker.dataGet = function(whom, rowid) {
|
||||
const roll_string = tracker.buildString(whom);
|
||||
startRoll(roll_string, roll => {
|
||||
@@ -20655,6 +20914,7 @@ tracker.dataGet = function(whom, rowid) {
|
||||
}
|
||||
|
||||
|
||||
// old call
|
||||
tracker.handleSkillString = function(string, updates) {
|
||||
console.log("Handle skill string", string);
|
||||
if (!string || string == '') return;
|
||||
@@ -20675,6 +20935,7 @@ tracker.handleSkillString = function(string, updates) {
|
||||
// updates[`repeat_trackedskill${rowid}_bonus`] = match[2];
|
||||
}
|
||||
}
|
||||
// old call
|
||||
tracker.handleMoveString = function(string, updates) {
|
||||
console.log("Handle move string", string);
|
||||
if (!string || string == '') return;
|
||||
@@ -20694,6 +20955,7 @@ tracker.handleMoveString = function(string, updates) {
|
||||
}
|
||||
}
|
||||
|
||||
// old call
|
||||
tracker.handleAttackString = function(string, updates) {
|
||||
console.log("Handle attack string", string);
|
||||
if (!string || string == '') return;
|
||||
@@ -20706,6 +20968,33 @@ tracker.handleAttackString = function(string, updates) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sheet Events
|
||||
*
|
||||
* These should all be triggered in the context of the sheet.
|
||||
* And then send the data to the tracker, if any.
|
||||
*/
|
||||
onCheck("change:lastinitiative", () => {
|
||||
getAttrs(["lastinitiative", "trackerid", "trackerprefix"], (data) => {
|
||||
if (data.trackerid && data.trackerprefix) {
|
||||
rmuSetAttrsRemote(data.trackerid,
|
||||
{ [data.trackerprefix + "lastinitiative"] : data.lastinitiative });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
for (attr of tracker.allAttributes) {
|
||||
onCheck("change:" + attr, (ev) => {
|
||||
getAttrs(["trackerid", "trackerprefix"], (data) => {
|
||||
if (data.trackerid && data.trackerprefix) {
|
||||
rmuSetAttrsRemote(data.trackerid,
|
||||
{ [data.trackerprefix + ev.sourceAttribute] : ev.newValue }
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -20807,6 +21096,65 @@ onCheck("clicked:initiative-action", (ev) => {
|
||||
|
||||
// vim: set sw=2 sts=2 syn=javascript :
|
||||
|
||||
/**/
|
||||
|
||||
const target = {}
|
||||
|
||||
|
||||
onCheck("change:target_characterid", (change) => {
|
||||
console.log("Change of target characgter id", change);
|
||||
if (change.newValue == change.previousValue) {
|
||||
return;
|
||||
}
|
||||
|
||||
let oldidtarget = change.oldValue;
|
||||
let newidtarget = change.newValue;
|
||||
const myid = getActiveCharacterId();
|
||||
|
||||
// Remove myself from the old list
|
||||
/*
|
||||
rmuGetAttrsRemote(oldidtarget, ["target_listeners"], (remote) => {
|
||||
const result = remote.target_listeners
|
||||
.split(",")
|
||||
.filter(item => item !== myid)
|
||||
.join(",");
|
||||
setAttrs({target_listeners: result});
|
||||
});*/
|
||||
|
||||
// Add myself to the new list
|
||||
|
||||
rmuGetAttrsRemote(newidtarget, ["target_listeners"], (remote) => {
|
||||
let result = remote.target_listeners
|
||||
if (result) {
|
||||
result += ',' + myid;
|
||||
} else {
|
||||
result = myid;
|
||||
}
|
||||
setAttrs({target_listeners: result})
|
||||
});
|
||||
});
|
||||
|
||||
onCheck("change:db", (db) => {
|
||||
getAttrs(["target_listeners"], (listen) => {
|
||||
console.log("db change", db, listen);
|
||||
if (!listen.target_listeners || listen.target_listeners.length < 2) {
|
||||
console.log("Seems empty; stopping");
|
||||
return;
|
||||
}
|
||||
listen.target_listeners.split(",").forEach((who) => {
|
||||
rmuSetAttrsRemote(who, {target_db: db.newValue});
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* vim:set sw=4 sts=4 syn=javascript : */
|
||||
|
||||
|
||||
|
||||
function getStatFromAName(aname) {
|
||||
|
||||
@@ -123,5 +123,5 @@
|
||||
"description": "Set the version of the sheet in use. You typically want latest"
|
||||
}
|
||||
],
|
||||
"version": "1767856195"
|
||||
"version": "1768234574"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,22 @@
|
||||
# 2026-01-15
|
||||
|
||||
- Add tracker back
|
||||
- Add general "asCharacter" helpers
|
||||
- Tracker:
|
||||
- Can add data using new as character
|
||||
- Characters now remember their tracker
|
||||
- for All Characters methods to tracker
|
||||
- Tracker can set everyones AP/round message
|
||||
- Tracker can roll everyones initiative (not to turn tracker though)
|
||||
- Track base attributes
|
||||
- Add option for non-tracker initiative.
|
||||
- Clean up build so compiled/processed files go to build
|
||||
|
||||
# 2026-01-08
|
||||
|
||||
- Fix for creatures max PP
|
||||
- Fix fetch for targetted creatures
|
||||
- Partial fix for grapple
|
||||
|
||||
# 2026-01-06
|
||||
|
||||
|
||||
Reference in New Issue
Block a user