mirror of
https://github.com/Nighthawk42/roll20-character-sheets.git
synced 2026-08-30 11:42:29 +00:00
2025/02/24 - Version 1.0.1
Modified Skill structure for better usability: {Attr + Base + Lvl + Mod = Total} → {Attr + Skill + Mod = Total}
Buttons to change Layout Appearance (Skills, Talents...) now work on the first click instead of requiring two.
1721 lines
63 KiB
HTML
1721 lines
63 KiB
HTML
<div style="display: none">
|
|
<rolltemplate class="sheet-rolltemplate-rolldice">
|
|
<div class="sheet-p-card"> {{#n}}
|
|
<div class="sheet-p-title">{{n}}</div>
|
|
{{/n}}
|
|
<div class="sheet-p-result">
|
|
<!-- -->
|
|
{{#rollTotal() md 0}}
|
|
<div class="sheet-p-r-solo sheet-no-color">
|
|
<div class="sheet-p-rd-r">{{computed::d1}}</div>
|
|
</div>
|
|
{{/rollTotal() md 0}}
|
|
<!-- -->
|
|
{{#rollTotal() md 1}}
|
|
<div class="sheet-p-r-solo">
|
|
<div class="sheet-p-rd-r">{{computed::d1}}</div>
|
|
</div>
|
|
{{/rollTotal() md 1}}
|
|
<div class="sheet-p-r-double"> {{#rollTotal() md 2}}
|
|
<!-- -->
|
|
<div class="sheet-p-rd-adv">
|
|
<!-- -->
|
|
{{#rollGreater() d1 d2}}
|
|
<div class="sheet-p-rd-rw">{{computed::d1}}</div>
|
|
<div class="sheet-p-rd-r">{{computed::d2}}</div>
|
|
{{/rollGreater() d1 d2}}
|
|
|
|
<!-- -->
|
|
|
|
{{#rollGreater() d2 d1}}
|
|
<div class="sheet-p-rd-r">{{computed::d1}}</div>
|
|
<div class="sheet-p-rd-rw">{{computed::d2}}</div>
|
|
{{/rollGreater() d2 d1}}
|
|
|
|
{{#rollTotal() d1 d2}}
|
|
<div class="sheet-p-rd-rw">{{computed::d1}}</div>
|
|
<div class="sheet-p-rd-r">{{computed::d2}}</div>
|
|
{{/rollTotal() d1 d2}}
|
|
|
|
<!-- -->
|
|
|
|
</div>
|
|
{{/rollTotal() md 2}}
|
|
|
|
<!-- -->
|
|
|
|
{{#rollTotal() md 3}}
|
|
<div class="sheet-p-rd-dsv">
|
|
<!-- -->
|
|
{{#rollLess() d1 d2}}
|
|
<div class="sheet-p-rd-rw">{{computed::d1}}</div>
|
|
<div class="sheet-p-rd-r">{{computed::d2}}</div>
|
|
{{/rollLess() d1 d2}}
|
|
|
|
<!-- -->
|
|
|
|
{{#rollLess() d2 d1}}
|
|
<div class="sheet-p-rd-r">{{computed::d1}}</div>
|
|
<div class="sheet-p-rd-rw">{{computed::d2}}</div>
|
|
{{/rollLess() d2 d1}}
|
|
|
|
{{#rollTotal() d1 d2}}
|
|
<div class="sheet-p-rd-rw">{{computed::d1}}</div>
|
|
<div class="sheet-p-rd-r">{{computed::d2}}</div>
|
|
{{/rollTotal() d1 d2}}
|
|
|
|
<!-- -->
|
|
|
|
</div>
|
|
{{/rollTotal() md 3}}
|
|
|
|
<!-- -->
|
|
</div>
|
|
</div>
|
|
{{#sk}}
|
|
<div class="sheet-p-label">{{sk}} {{#tm}}({{tm}}){{/tm}}</div>
|
|
{{/sk}}
|
|
{{#s}}
|
|
<div class="sheet-p-label">{{s}} {{#c}}<br>
|
|
({{c}}){{/c}}</div>
|
|
<div class="sheet-p-text">{{e}}</div>
|
|
{{/s}}
|
|
{{#t}}
|
|
<div class="sheet-p-label">{{t}} {{#o}}<small>({{o}}{{#r}} - {{r}}{{/r}})</small>{{/o}}</div>
|
|
<div class="sheet-p-text">{{d}}</div>
|
|
{{/t}}
|
|
<input type="checkbox" value="1">
|
|
</div>
|
|
</rolltemplate>
|
|
</div>
|
|
<div class="s_fg">
|
|
<input type="hidden" name="attr_new_sheet" value="1">
|
|
<input type="hidden" name="attr_svg" class="is_svg" value="0">
|
|
<input type="hidden" name="attr_gm_config" class="is_gm" value="0">
|
|
<input type="hidden" name="attr_hidden_s01" class="hs01">
|
|
<input type="hidden" name="attr_hidden_s02" class="hs02">
|
|
<input type="hidden" name="attr_hidden_s03" class="hs03">
|
|
<input type="hidden" name="attr_hidden_s04" class="hs04">
|
|
<input type="hidden" name="attr_hidden_s05" class="hs05">
|
|
<input type="hidden" name="attr_hidden_s06" class="hs06">
|
|
<input type="hidden" name="attr_hidden_s07" class="hs07">
|
|
<input type="hidden" name="attr_hidden_s08" class="hs08">
|
|
<input type="hidden" name="attr_hidden_s09" class="hs09">
|
|
<input type="hidden" name="attr_hidden_s10" class="hs10">
|
|
<input type="hidden" name="attr_hidden_s11" class="hs11">
|
|
<input type="hidden" name="attr_hidden_s12" class="hs12">
|
|
<input type="hidden" name="attr_hidden_s13" class="hs13">
|
|
<input type="hidden" name="attr_hidden_s14" class="hs14">
|
|
<div class="s_sector sc1">
|
|
<div class="s_flex">
|
|
<div class="s_logo"><img src="https://raw.githubusercontent.com/Roll20/roll20-character-sheets/refs/heads/master/Fantasy-Gits/svg/logo_fantasy_gits.svg" alt="Fantasy Gits"></div>
|
|
<div class="s_header">
|
|
<label class="s_item i-merc">
|
|
<div class="s_title"><span>Merc Troop</span></div>
|
|
<div class="bg_line s_spaninput"><span name="attr_merctroop"></span>
|
|
<input type="text" name="attr_merctroop" placeholder="..." value="" title="@{merctroop}">
|
|
</div>
|
|
</label>
|
|
<label class="s_item i-wealth" title="@{wealth}">
|
|
<div class="s_area">
|
|
<div class="s_title"><span>Wealth</span></div>
|
|
<div class="s_spantext"><span name="attr_wealth"></span>
|
|
<textarea name="attr_wealth" placeholder="..."></textarea>
|
|
</div>
|
|
</div>
|
|
<div class="s_borders">
|
|
<div class="s_border_left">
|
|
<div class="s_bt"></div>
|
|
<div class="s_bm"></div>
|
|
<div class="s_bb"></div>
|
|
</div>
|
|
<div class="s_border_right">
|
|
<div class="s_bt"></div>
|
|
<div class="s_bm"></div>
|
|
<div class="s_bb"></div>
|
|
</div>
|
|
</div>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="s_flex s_character f_center gap-20">
|
|
<label class="s_item i-name x-colon">
|
|
<span>Name</span>
|
|
<div class="bg_line s_spaninput"><span name="attr_character_name"></span>
|
|
<input type="text" name="attr_character_name" placeholder="..." title="@{character_name}">
|
|
</div>
|
|
</label>
|
|
<label class="s_item i-origin x-colon">
|
|
<span>Origin</span>
|
|
<div class="bg_line s_spaninput"><span name="attr_character_origin"></span>
|
|
<input type="text" name="attr_character_origin" placeholder="..." title="@{character_origin}">
|
|
</div>
|
|
</label>
|
|
<label class="s_item i-background x-colon">
|
|
<span>Background</span>
|
|
<div class="bg_line s_spaninput"><span name="attr_character_background"></span>
|
|
<input type="text" name="attr_character_background" placeholder="..." title="@{character_background}">
|
|
</div>
|
|
</label>
|
|
<label class="s_item i-position x-colon">
|
|
<span>Position</span>
|
|
<div class="bg_line s_spaninput"><span name="attr_character_position"></span>
|
|
<input type="text" name="attr_character_position" placeholder="..." title="@{character_position}">
|
|
</div>
|
|
</label>
|
|
<label class="s_item i-age x-colon">
|
|
<span>Age</span>
|
|
<div class="bg_line s_spaninput"><span name="attr_character_age"></span>
|
|
<input type="text" name="attr_character_age" placeholder="..." title="@{character_age}">
|
|
</div>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="s_sector sc2 s_flex flex_wrap f_center gap-20">
|
|
<div class="s_attributes">
|
|
<div class="s_attribute i-str" title="@{str}">
|
|
<input type="hidden" name="attr_str_plus" class="is_plus" value="0">
|
|
<div class="s_title">
|
|
<button type="roll" name="roll_str" value="@{str_btn}" tabindex="-1"></button>
|
|
<button type="action" name="act_str_act" tabindex="-1"></button>
|
|
<input type="hidden" name="attr_str_btn" value="%{str_act}">
|
|
<span>str</span></div>
|
|
<div class="s_value">
|
|
<input type="number" name="attr_str" value="10">
|
|
</div>
|
|
<div class="s_mod" title="@{str_mod}">
|
|
<input type="number" name="attr_str_mod" value="0" tabindex="-1">
|
|
<span class="p_plus"><span>+</span></span><span name="attr_str_mod">0</span></div>
|
|
</div>
|
|
<div class="s_attribute i-dex" title="@{dex}">
|
|
<input type="hidden" name="attr_dex_plus" class="is_plus" value="0">
|
|
<div class="s_title">
|
|
<button type="roll" name="roll_dex" value="@{dex_btn}" tabindex="-1"></button>
|
|
<button type="action" name="act_dex_act" tabindex="-1"></button>
|
|
<input type="hidden" name="attr_dex_btn" value="%{dex_act}">
|
|
<span>dex</span></div>
|
|
<div class="s_value">
|
|
<input type="number" name="attr_dex" value="10">
|
|
</div>
|
|
<div class="s_mod" title="@{dex_mod}">
|
|
<input type="number" name="attr_dex_mod" value="0" tabindex="-1">
|
|
<span class="p_plus"><span>+</span></span><span name="attr_dex_mod">0</span></div>
|
|
</div>
|
|
<div class="s_attribute i-hea" title="@{hea}">
|
|
<input type="hidden" name="attr_hea_plus" class="is_plus" value="0">
|
|
<div class="s_title">
|
|
<button type="roll" name="roll_hea" value="@{hea_btn}" tabindex="-1"></button>
|
|
<button type="action" name="act_hea_act" tabindex="-1"></button>
|
|
<input type="hidden" name="attr_hea_btn" value="%{hea_act}">
|
|
<span>hea</span></div>
|
|
<div class="s_value">
|
|
<input type="number" name="attr_hea" value="10">
|
|
</div>
|
|
<div class="s_mod" title="@{hea_mod}">
|
|
<input type="number" name="attr_hea_mod" value="0" tabindex="-1">
|
|
<span class="p_plus"><span>+</span></span><span name="attr_hea_mod">0</span></div>
|
|
</div>
|
|
<div class="s_attribute i-int" title="@{int}">
|
|
<input type="hidden" name="attr_int_plus" class="is_plus" value="0">
|
|
<div class="s_title">
|
|
<button type="roll" name="roll_int" value="@{int_btn}" tabindex="-1"></button>
|
|
<button type="action" name="act_int_act" tabindex="-1"></button>
|
|
<input type="hidden" name="attr_int_btn" value="%{int_act}">
|
|
<span>int</span></div>
|
|
<div class="s_value">
|
|
<input type="number" name="attr_int" value="10">
|
|
</div>
|
|
<div class="s_mod" title="@{int_mod}">
|
|
<input type="number" name="attr_int_mod" value="0" tabindex="-1">
|
|
<span class="p_plus"><span>+</span></span><span name="attr_int_mod">0</span></div>
|
|
</div>
|
|
<div class="s_attribute i-wis" title="@{wis}">
|
|
<input type="hidden" name="attr_wis_plus" class="is_plus" value="0">
|
|
<div class="s_title">
|
|
<button type="roll" name="roll_wis" value="@{wis_btn}" tabindex="-1"></button>
|
|
<button type="action" name="act_wis_act" tabindex="-1"></button>
|
|
<input type="hidden" name="attr_wis_btn" value="%{wis_act}">
|
|
<span>wis</span></div>
|
|
<div class="s_value">
|
|
<input type="number" name="attr_wis" value="10">
|
|
</div>
|
|
<div class="s_mod" title="@{wis_mod}">
|
|
<input type="number" name="attr_wis_mod" value="0" tabindex="-1">
|
|
<span class="p_plus"><span>+</span></span><span name="attr_wis_mod">0</span></div>
|
|
</div>
|
|
<div class="s_attribute i-cha" title="@{cha}">
|
|
<input type="hidden" name="attr_cha_plus" class="is_plus" value="0">
|
|
<div class="s_title">
|
|
<button type="roll" name="roll_cha" value="@{cha_btn}" tabindex="-1"></button>
|
|
<button type="action" name="act_cha_act" tabindex="-1"></button>
|
|
<input type="hidden" name="attr_cha_btn" value="%{cha_act}">
|
|
<span>cha</span></div>
|
|
<div class="s_value">
|
|
<input type="number" name="attr_cha" value="10">
|
|
</div>
|
|
<div class="s_mod" title="@{cha_mod}">
|
|
<input type="number" name="attr_cha_mod" value="0" tabindex="-1">
|
|
<span class="p_plus"><span>+</span></span><span name="attr_cha_mod">0</span></div>
|
|
</div>
|
|
</div>
|
|
<div class="s_others s_flex flex_wrap gap-20">
|
|
<div class="s_resources">
|
|
<label class="s_item i-wounds">
|
|
<div class="s_title"><span class="i-wou"></span></div>
|
|
<div class="s_value">
|
|
<input type="number" name="attr_wounds" value="0" title="@{wounds}">
|
|
</div>
|
|
<div class="s_value s_is_max">
|
|
<input type="number" name="attr_wounds_max" value="0" title="@{wounds|max}">
|
|
</div>
|
|
</label>
|
|
<label class="s_item i-defence">
|
|
<div class="s_title"><span class="i-def"></span><span class="i-cla"></span> </div>
|
|
<div class="s_value">
|
|
<input type="number" name="attr_defence" value="0" title="@{defence}">
|
|
</div>
|
|
</label>
|
|
<label class="s_item i-mana">
|
|
<div class="s_title"><span>Mana</span> </div>
|
|
<div class="s_value">
|
|
<input type="number" name="attr_mana" value="0" title="@{mana}">
|
|
</div>
|
|
<div class="s_value s_is_max">
|
|
<input type="number" name="attr_mana_max" value="0" title="@{mana|max}">
|
|
</div>
|
|
</label>
|
|
</div>
|
|
<div class="s_status">
|
|
<div class="s_s_l">
|
|
<label class="s_item i-initiative x-colon">
|
|
<span class="btn_full">
|
|
<button type="roll" name="roll_ini" value="@{m_gm}&{template:rolldice} {{n=@{character_name}}} {{md=[[0]]}} {{d1=[[d6+@{initiative} &{tracker}]]}} {{sk=Initiative}} {{tm=d6+@{initiative}}}"></button>
|
|
<span>Initiative</span></span>
|
|
<div class="bg_line s_spaninput"><span name="attr_initiative">0</span>
|
|
<input type="text" name="attr_initiative" value="0" title="@{initiative}">
|
|
</div>
|
|
</label>
|
|
<label class="s_item i-movement x-colon">
|
|
<span>Movement</span>
|
|
<div class="bg_line s_spaninput"><span name="attr_movement">0</span>
|
|
<input type="text" name="attr_movement" value="0" title="@{movement}">
|
|
</div>
|
|
</label>
|
|
<label class="s_item i-luck x-colon">
|
|
<span>Luck</span>
|
|
<div class="bg_line s_spaninput"><span name="attr_luck">0</span>
|
|
<input type="text" name="attr_luck" value="0" title="@{luck}">
|
|
</div>
|
|
</label>
|
|
<label class="s_item i-exp x-colon">
|
|
<span class="btn_full">
|
|
<button type="roll" name="roll_exp" value="@{m_gm}&{template:rolldice} {{n=@{character_name}}} {{md=[[0]]}} {{d1=[[@{exp}]]}} {{sk=EXP. Dice}} {{tm=@{exp}}}"></button>
|
|
<span>Exp. Dice</span></span>
|
|
<div class="bg_line s_spaninput"><span name="attr_exp">-</span>
|
|
<input type="text" name="attr_exp" placeholder="-" title="@{exp}">
|
|
</div>
|
|
</label>
|
|
</div>
|
|
<label class="s_s_r s_item i-reknown">
|
|
<div class="s_title"><span>Reknown</span></div>
|
|
<div class="s_box">
|
|
<div class="s_value">
|
|
<input type="number" name="attr_reknown" value="0" title="@{reknown}">
|
|
</div>
|
|
</div>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="s_sector sc3 s_flex flex_wrap m_10 f_center gap-30">
|
|
<div class="s_side s_flex gap-10 flex_wrap">
|
|
<div class="s_papper s_skills">
|
|
<input type="hidden" name="attr_skill_layout_1" class="layout_icon" value="1">
|
|
<div class="s_s_config">
|
|
<label class="layout_icon">
|
|
<button type="action" name="act_skill_layout_1"></button>
|
|
<span></span></label>
|
|
</div>
|
|
<div class="s_area">
|
|
<div class="s_title"><span>Skills</span></div>
|
|
<div class="s_spantext"><span name="attr_skills">...</span>
|
|
<textarea name="attr_skills">...</textarea>
|
|
</div>
|
|
<div class="s_skill_list">
|
|
<fieldset class="repeating_skill">
|
|
<input type="hidden" name="attr_attr" class="has1" value="—">
|
|
<input type="hidden" name="attr_desc_show" class="hasdesc" value="1">
|
|
<div class="s_skill_item">
|
|
<input type="checkbox" name="attr_edit" value="1" style="display: none" checked>
|
|
<div class="no_edit"> <span class="ss_name">
|
|
<button type="roll" name="roll_skill" value="@{skill_btn}" tabindex="-1"></button>
|
|
<button type="action" name="act_skill_act" tabindex="-1"></button>
|
|
<input type="hidden" name="attr_skill_btn" value="%{skill_act}">
|
|
<span name="attr_name"></span> </span><span class="ss_attr">(<span name="attr_attr"></span>) </span><span class="ss_mod"><span class="is_plus"><span>+</span></span><span name="attr_total"></span></span><span class="ss_desc" name="attr_desc"></span></div>
|
|
<div class="is_edit">
|
|
<label><span>Name</span>
|
|
<input type="text" name="attr_name" placeholder="Skill name">
|
|
</label>
|
|
<div>
|
|
<div class="s_table">
|
|
<div class="s_t_head">
|
|
<div class="s_t_cell">Attr</div>
|
|
<div class="s_t_cell" style="pointer-events: none"><span>+</span></div>
|
|
<div class="s_t_cell">Skill</div>
|
|
<div class="s_t_cell" style="pointer-events: none"><span>+</span></div>
|
|
<div class="s_t_cell">Mod</div>
|
|
<div class="s_t_cell" style="pointer-events: none"><span>=</span></div>
|
|
<div class="s_t_cell">Total</div>
|
|
</div>
|
|
<div class="s_t_body">
|
|
<div class="s_t_row">
|
|
<div class="s_t_cell">
|
|
<select name="attr_attr" style="-webkit-appearance: none; font-family: monospace; font-size: 0.85em; font-weight: bold; text-align: center; border-radius: 5px; border-bottom: 2px solid rgba(255, 255, 255, 0.33); background: rgba(0, 0, 0, 0.25); width: 100%; max-width: 100%">
|
|
<option value="—">—</option>
|
|
<option value="s">str</option>
|
|
<option value="d">dex</option>
|
|
<option value="h">hea</option>
|
|
<option value="i">int</option>
|
|
<option value="w">wis</option>
|
|
<option value="c">cha</option>
|
|
</select>
|
|
</div>
|
|
<div class="s_t_cell" style="pointer-events: none"><span>+</span></div>
|
|
<div class="s_t_cell">
|
|
<input type="text" name="attr_base" value="0">
|
|
</div>
|
|
<div class="s_t_cell" style="pointer-events: none"><span>+</span></div>
|
|
<div class="s_t_cell">
|
|
<input type="text" name="attr_mod" value="0">
|
|
</div>
|
|
<div class="s_t_cell" style="pointer-events: none"><span>=</span></div>
|
|
<div class="s_t_cell">
|
|
<input type="hidden" name="attr_lvl" value="0">
|
|
<input type="text" name="attr_total" value="0">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<label class="flex_wrap">
|
|
<input type="checkbox" name="attr_desc_show" value="1" checked>
|
|
<span>Desc. </span>
|
|
<textarea name="attr_desc" placeholder="Effect here..."></textarea>
|
|
</label>
|
|
</div>
|
|
<label class="s_edit_info w_edit">
|
|
<input type="checkbox" name="attr_edit" value="1" checked>
|
|
<span></span></label>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="s_papper s_talents">
|
|
<input type="hidden" name="attr_talent_layout_1" class="layout_icon" value="1">
|
|
<div class="s_s_config">
|
|
<label class="layout_icon">
|
|
<button type="action" name="act_talent_layout_1"></button>
|
|
<span></span></label>
|
|
</div>
|
|
<div class="s_area">
|
|
<div class="s_title"><span>Talents</span><span> & </span><span>Specialisations</span></div>
|
|
<div class="s_spantext"> <span name="attr_talents">...</span>
|
|
<textarea name="attr_talents">...</textarea>
|
|
</div>
|
|
<div class="s_skill_list">
|
|
<fieldset class="repeating_talent">
|
|
<input type="hidden" name="attr_origin" class="has1" value="—">
|
|
<input type="hidden" name="attr_ref" class="has2" value="">
|
|
<input type="hidden" name="attr_desc_show" class="hasdesc" value="1">
|
|
<div class="s_skill_item">
|
|
<input type="checkbox" name="attr_edit" value="1" style="display: none" checked>
|
|
<div class="no_edit"> <span class="ss_name">
|
|
<button type="roll" name="roll_talent" value="@{m_gm}&{template:rolldice} {{n=@{character_name}}} {{t=@{name}}} {{o=@{origin}}} {{r=@{ref}}} {{d=@{desc}}}" tabindex="-1"></button>
|
|
<span name="attr_name"></span> </span><span class="ss_attr">(<span name="attr_origin"></span><span class="ss_ref"> - <span name="attr_ref"></span></span>) </span><span class="ss_desc" name="attr_desc"></span></div>
|
|
<div class="is_edit">
|
|
<label><span>Name</span>
|
|
<input type="text" name="attr_name" placeholder="Talent name">
|
|
</label>
|
|
<label><span>Origin</span>
|
|
<input type="text" name="attr_origin" value="—">
|
|
<span>Ref</span>
|
|
<input type="text" name="attr_ref" placeholder="pg.000">
|
|
</label>
|
|
<label class="flex_wrap">
|
|
<input type="checkbox" name="attr_desc_show" value="1" checked>
|
|
<span>Desc. </span>
|
|
<textarea name="attr_desc" placeholder="Effect here..."></textarea>
|
|
</label>
|
|
</div>
|
|
<label class="s_edit_info w_edit">
|
|
<input type="checkbox" name="attr_edit" value="1" checked>
|
|
<span></span></label>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="s_papper s_items">
|
|
<input type="hidden" name="attr_item_layout_1" class="layout_icon" value="4">
|
|
<div class="s_s_config">
|
|
<label class="layout_icon">
|
|
<button type="action" name="act_item_layout_1"></button>
|
|
<span></span></label>
|
|
</div>
|
|
<div class="s_area">
|
|
<div class="s_title"><span>Items</span></div>
|
|
<div class="s_spantext"> <span name="attr_items">...</span>
|
|
<textarea name="attr_items">...</textarea>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="s_side s_flex gap-10 flex_wrap">
|
|
<div class="s_tabled s_weapons">
|
|
<div class="s_area">
|
|
<div class="s_table">
|
|
<div class="s_t_head">
|
|
<div class="s_t_row">
|
|
<div class="s_t_cell"><span>Weapon</span></div>
|
|
<div class="s_t_cell"><span>Type</span></div>
|
|
<div class="s_t_cell"><span>Dam</span></div>
|
|
<div class="s_t_cell"><span>Parry</span></div>
|
|
<div class="s_t_cell"><span>Upgrades</span></div>
|
|
</div>
|
|
</div>
|
|
<div class="s_t_body">
|
|
<fieldset class="repeating_weapon">
|
|
<div class="s_t_row">
|
|
<input type="hidden" name="attr_dam" class="hasdmg" value="">
|
|
<input type="hidden" name="attr_last_selected" value="">
|
|
<input type="hidden" name="attr_has_mod" class="hasdam" value="0">
|
|
<input type="hidden" name="attr_dam_2_is_plus" class="is_plus" value="0">
|
|
<input type="checkbox" name="attr_edit" value="1" style="display: none" checked>
|
|
<div class="no_edit">
|
|
<div class="s_t_cell btn_full m-atk">
|
|
<button type="roll" name="roll_weapon" value="@{weapon_btn}" tabindex="-1"></button>
|
|
<button type="action" name="act_weapon_act" tabindex="-1"></button>
|
|
<input type="hidden" name="attr_weapon_btn" value="%{weapon_act}">
|
|
<span name="attr_name"></span></div>
|
|
<div class="s_t_cell"><span name="attr_type"></span></div>
|
|
<div class="s_t_cell btn_full m-dmg">
|
|
<button type="roll" name="roll_dmg" value="@{dmg_btn}" tabindex="-1"></button>
|
|
<button type="action" name="act_dmg_act" tabindex="-1"></button>
|
|
<input type="hidden" name="attr_dmg_btn" value="%{dmg_act}">
|
|
<span name="attr_dam_1"></span><span class="hasdam"><span class="is_plus">+</span><span name="attr_dam_total"></span></span></div>
|
|
<div class="s_t_cell"><span name="attr_parry"></span></div>
|
|
<div class="s_t_cell"><span name="attr_upgrades"></span></div>
|
|
<input type="checkbox" name="attr_moreinfo" value="1" style="display: none">
|
|
<div class="s_t_srow">
|
|
<div class="s_t_cell"><span>Weight:</span><span> </span><span name="attr_weight"></span></div>
|
|
<div class="s_t_cell"><span>Cost:</span><span> </span><span class="has"><span name="attr_cost_mult">1</span>x</span><span name="attr_cost"></span></div>
|
|
<div class="s_t_cell" style="pointer-events: none"></div>
|
|
<div class="s_t_cell"><span>RNG:</span><span> </span><span name="attr_rng"></span></div>
|
|
<div class="s_t_cell" style="pointer-events: none"></div>
|
|
</div>
|
|
</div>
|
|
<div class="is_edit">
|
|
<label><span>Weapon</span>
|
|
<input type="text" name="attr_name" placeholder="Weapon name">
|
|
</label>
|
|
<label><span>Type</span>
|
|
<input type="text" name="attr_type" placeholder="1-Handed">
|
|
</label>
|
|
<label><span>Damage</span>
|
|
<input type="text" name="attr_dam" placeholder="2d4">
|
|
<span><span>+</span></span>
|
|
<select name="attr_dam_2">
|
|
<option value="0">—</option>
|
|
<option value="@{str_mod}">str</option>
|
|
<option value="@{dex_mod}">dex</option>
|
|
<option value="@{hea_mod}">hea</option>
|
|
<option value="@{int_mod}">int</option>
|
|
<option value="@{wis_mod}">wis</option>
|
|
<option value="@{cha_mod}">cha</option>
|
|
<option value="@{dam_mod}">—»</option>
|
|
</select>
|
|
<input type="hidden" name="attr_dam_1">
|
|
<input type="hidden" name="attr_dam_2_mod" placeholder="+0">
|
|
<input type="hidden" name="attr_dam_2" value="0">
|
|
<input type="text" name="attr_dam_mod" class="is_dam" placeholder="+0">
|
|
<input type="hidden" name="attr_dam_total" value="0">
|
|
</label>
|
|
<label><span>Parry</span>
|
|
<input type="text" name="attr_parry" placeholder="—">
|
|
</label>
|
|
<label><span>Upgrades</span>
|
|
<input type="text" name="attr_upgrades" placeholder="+1">
|
|
</label>
|
|
<label><span>Weight</span>
|
|
<input type="text" name="attr_weight" placeholder="—">
|
|
</label>
|
|
<label><span>Cost</span>
|
|
<input type="text" name="attr_cost" placeholder="—">
|
|
<span>x</span>
|
|
<input type="text" name="attr_cost_mult" value="1" style="max-width: 40px; text-align: center">
|
|
</label>
|
|
<label><span>Range</span>
|
|
<input type="text" name="attr_rng" placeholder="Close">
|
|
</label>
|
|
</div>
|
|
<label class="s_check_info w_show">
|
|
<input type="checkbox" name="attr_moreinfo" value="1">
|
|
<span></span></label>
|
|
<label class="s_edit_info w_edit">
|
|
<input type="checkbox" name="attr_edit" value="1" checked>
|
|
<span></span></label>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
<div class="s_borders">
|
|
<div class="s_border1"></div>
|
|
<div class="s_border2"></div>
|
|
<div class="s_border3"></div>
|
|
<div class="s_border4"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<small class="s-tips"><span>If you cancel, please wait <span name="attr_m_cd">6</span> seconds before clicking again</span></small>
|
|
<div class="s_tabled s_armours">
|
|
<div class="s_area">
|
|
<div class="s_table">
|
|
<div class="s_t_head">
|
|
<div class="s_t_row">
|
|
<div class="s_t_cell"><span>Armour</span><span>/</span><span>Shield</span></div>
|
|
<div class="s_t_cell"><span>Rating</span><span>/</span><span>Parry</span></div>
|
|
<div class="s_t_cell"><span>Modifier</span></div>
|
|
</div>
|
|
</div>
|
|
<div class="s_t_body">
|
|
<fieldset class="repeating_armour">
|
|
<div class="s_t_row">
|
|
<input type="checkbox" name="attr_edit" value="1" style="display: none" checked>
|
|
<div class="no_edit">
|
|
<div class="s_t_cell"><span name="attr_name"></span></div>
|
|
<div class="s_t_cell"><span name="attr_rating"></span><span>/<span name="attr_parry"></span></span></div>
|
|
<div class="s_t_cell"><span name="attr_modifier"></span></div>
|
|
<input type="checkbox" name="attr_moreinfo" value="1" style="display: none">
|
|
<div class="s_t_srow">
|
|
<div class="s_t_cell"><span>Weight</span><span> </span><span name="attr_weight"></span></div>
|
|
<div class="s_t_cell"><span>Cost</span><span> </span><span><span name="attr_cost_mult"></span>x</span><span name="attr_cost"></span></div>
|
|
<div class="s_t_cell" style="pointer-events: none"></div>
|
|
</div>
|
|
</div>
|
|
<div class="is_edit">
|
|
<label><span>Name</span>
|
|
<input type="text" name="attr_name" placeholder="Armour/Shield name">
|
|
</label>
|
|
<label><span>Rating</span>
|
|
<input type="text" name="attr_rating" placeholder="—">
|
|
</label>
|
|
<label><span>Parry</span>
|
|
<input type="text" name="attr_parry" placeholder="—">
|
|
</label>
|
|
<label><span>Modifier</span>
|
|
<input type="text" name="attr_modifier" placeholder="—">
|
|
</label>
|
|
<label><span>Weight</span>
|
|
<input type="text" name="attr_weight" placeholder="—">
|
|
</label>
|
|
<label><span>Cost</span>
|
|
<input type="text" name="attr_cost" placeholder="—">
|
|
<span>x</span>
|
|
<input type="text" name="attr_cost_mult" value="1" style="max-width: 40px; text-align: center">
|
|
</label>
|
|
</div>
|
|
<label class="s_check_info w_show">
|
|
<input type="checkbox" name="attr_moreinfo" value="1">
|
|
<span></span></label>
|
|
<label class="s_edit_info w_edit">
|
|
<input type="checkbox" name="attr_edit" value="1" checked>
|
|
<span></span></label>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
<div class="s_borders">
|
|
<div class="s_border1"></div>
|
|
<div class="s_border2"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="s_tabled s_spells">
|
|
<div class="s_area">
|
|
<div class="s_table">
|
|
<div class="s_t_head">
|
|
<div class="s_t_row">
|
|
<div class="s_t_cell"><span>Spell</span></div>
|
|
<div class="s_t_cell"><span>Cost</span></div>
|
|
</div>
|
|
<div class="s_t_row">
|
|
<div class="s_t_cell"><span>Spell</span></div>
|
|
<div class="s_t_cell"><span>Cost</span></div>
|
|
</div>
|
|
</div>
|
|
<div class="s_t_body">
|
|
<fieldset class="repeating_spell">
|
|
<div class="s_t_row">
|
|
<input type="checkbox" name="attr_edit" value="1" style="display: none" checked>
|
|
<div class="no_edit">
|
|
<div class="s_t_cell"> <span class="ss_name">
|
|
<button type="roll" name="roll_spell" value="@{spell_btn}" tabindex="-1"></button>
|
|
<button type="action" name="act_spell_act" tabindex="-1"></button>
|
|
<input type="hidden" name="attr_spell_btn" value="%{spell_act}">
|
|
<span name="attr_name"></span></span></div>
|
|
<div class="s_t_cell"><span name="attr_cost"></span></div>
|
|
<input type="checkbox" name="attr_moreinfo" value="1" id="moreinfo" style="display: none">
|
|
<div class="s_t_srow">
|
|
<div class="s_t_cell"><span name="attr_effect"></span></div>
|
|
</div>
|
|
</div>
|
|
<div class="is_edit">
|
|
<label><span>Spell</span>
|
|
<input type="text" name="attr_name" placeholder="Spell name">
|
|
</label>
|
|
<label><span>Cost</span>
|
|
<input type="text" name="attr_cost" placeholder="—">
|
|
</label>
|
|
<label><span>Extra Mana</span>
|
|
<input type="checkbox" name="attr_extra_mana" value="1">
|
|
Yes </label>
|
|
<label><span>Effect</span>
|
|
<textarea name="attr_effect" placeholder="Effect here..."></textarea>
|
|
</label>
|
|
</div>
|
|
<label class="s_check_info w_show">
|
|
<input type="checkbox" name="attr_moreinfo" value="1">
|
|
<span></span></label>
|
|
<label class="s_edit_info w_edit">
|
|
<input type="checkbox" name="attr_edit" value="1" checked>
|
|
<span></span></label>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
<div class="s_borders">
|
|
<div class="s_border1"></div>
|
|
<div class="s_border2"></div>
|
|
<div class="s_border3"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="configs">
|
|
<div class="options">
|
|
<div class="option"> <span>Only GM?</span>
|
|
<select name="attr_m_gm">
|
|
<option value="">No</option>
|
|
<option value="/w GM ">Yes</option>
|
|
</select>
|
|
</div>
|
|
<div class="option"> <span>Dice Mod</span>
|
|
<select name="attr_m_dice">
|
|
<option value="1">Normal</option>
|
|
<option value="2">Advantage</option>
|
|
<option value="3">Disvantage</option>
|
|
<option value="4">Ask</option>
|
|
</select>
|
|
</div>
|
|
<div class="option"> <span>Extra Mod</span>
|
|
<select name="attr_m_mod">
|
|
<option value="">No</option>
|
|
<option value="+?{Extra Mod|0} [extra mod]">Yes</option>
|
|
</select>
|
|
</div>
|
|
<div class="option"> <span>Cast Mana</span>
|
|
<select name="attr_m_cast">
|
|
<option value="1">Yes</option>
|
|
<option value="2">No</option>
|
|
</select>
|
|
</div>
|
|
<div class="option"> <span>Cooldown Default (Xs)</span>
|
|
<input type="number" name="attr_m_cd" value="6">
|
|
<small>The time the script will wait for a response or 'reset' after a cancellation.</small> </div>
|
|
<div class="option"> <span>SVG</span>
|
|
<select name="attr_svg">
|
|
<option value="0">No</option>
|
|
<option value="1">Yes</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="hidden_sectors">
|
|
<h4>Hidden...</h4>
|
|
<div style="column-count: 3">
|
|
<label>
|
|
<input type="checkbox" name="attr_hidden_s01">
|
|
<span>Logo</span></label>
|
|
<label>
|
|
<input type="checkbox" name="attr_hidden_s02">
|
|
<span>Merc</span></label>
|
|
<label>
|
|
<input type="checkbox" name="attr_hidden_s03">
|
|
<span>Wealth</span></label>
|
|
<label>
|
|
<input type="checkbox" name="attr_hidden_s04">
|
|
<span>Character's Info</span></label>
|
|
<label>
|
|
<input type="checkbox" name="attr_hidden_s05">
|
|
<span>Attributes</span></label>
|
|
<label>
|
|
<input type="checkbox" name="attr_hidden_s06">
|
|
<span>Resources</span></label>
|
|
<label>
|
|
<input type="checkbox" name="attr_hidden_s07">
|
|
<span>Extras</span></label>
|
|
<label>
|
|
<input type="checkbox" name="attr_hidden_s08">
|
|
<span>Reknown</span></label>
|
|
<label>
|
|
<input type="checkbox" name="attr_hidden_s09">
|
|
<span>Skills</span></label>
|
|
<label>
|
|
<input type="checkbox" name="attr_hidden_s10">
|
|
<span>Talents/Specialisations</span></label>
|
|
<label>
|
|
<input type="checkbox" name="attr_hidden_s11">
|
|
<span>Items</span></label>
|
|
<label>
|
|
<input type="checkbox" name="attr_hidden_s12">
|
|
<span>Weapons</span></label>
|
|
<label>
|
|
<input type="checkbox" name="attr_hidden_s13">
|
|
<span>Armours/Shields</span></label>
|
|
<label>
|
|
<input type="checkbox" name="attr_hidden_s14">
|
|
<span>Spells</span></label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<label class="s_gm_config_btn">
|
|
<input type="checkbox" name="attr_gm_config" value="1">
|
|
<div><span></span></div>
|
|
</label>
|
|
</div>
|
|
<script type="text/worker">// text/worker
|
|
console.log("Ficha criada por Patrick Leo");
|
|
const Fila = {
|
|
fila: {},
|
|
ativa: false,
|
|
pausada: false,
|
|
tde: 150, // Tempo de espera entre cada item da fila (em milissegundos)
|
|
// ==
|
|
adicionar: function (func, prioridade = 0) {
|
|
prioridade = typeof prioridade == "string" && (prioridade == "Primeiro" || prioridade == "Ultimo") ? prioridade : parseInt(prioridade, 10) || 0;
|
|
if (!this.fila[prioridade]) this.fila[prioridade] = [];
|
|
this.fila[prioridade].push(func);
|
|
if (!this.ativa) {
|
|
setTimeout(() => this.Fila_on(), this.tde); // Ativa a fila após um ciclo de tde
|
|
}
|
|
},
|
|
// ==
|
|
Fila_on: async function () {
|
|
if (this.ativa) return; // Verifica se a fila já está ativa
|
|
this.ativa = true;
|
|
|
|
// Verifica se o tempo de espera é menor que 100 e ajusta para 0 se for
|
|
if (this.tde < 100) this.tde = 0;
|
|
|
|
while (this.temItens()) {
|
|
if (this.pausada) {
|
|
await new Promise(resolve => setTimeout(resolve, this.tde)); // Pausa por tde se estiver pausada
|
|
this.pausada = false;
|
|
continue;
|
|
}
|
|
|
|
const proximaPrioridade = this.proximaPrioridade();
|
|
if (proximaPrioridade == "Ultimo" && this.temPrioridadeMaisAlta()) {
|
|
await new Promise(resolve => setTimeout(resolve, this.tde)); // Pausa por tde se for "Ultimo" e tiver prioridade mais alta
|
|
continue;
|
|
}
|
|
|
|
const func = this.fila[proximaPrioridade].shift();
|
|
await func(); // Executa a função da fila
|
|
await new Promise(resolve => setTimeout(resolve, this.tde)); // Atraso de tde entre cada item da fila
|
|
|
|
if (this.fila[proximaPrioridade].length == 0) delete this.fila[proximaPrioridade]; // Remove a prioridade se estiver vazia
|
|
}
|
|
|
|
this.ativa = false;
|
|
},
|
|
// ==
|
|
temItens: function () {
|
|
return Object.keys(this.fila).length > 0; // Verifica se há itens na fila
|
|
},
|
|
// ==
|
|
proximaPrioridade: function () {
|
|
if (this.fila["Primeiro"] && this.fila["Primeiro"].length > 0) return "Primeiro"; // Prioridade "Primeiro"
|
|
const prioridades = Object.keys(this.fila).filter(p => p != "Primeiro" && p != "Ultimo").map(p => parseInt(p, 10));
|
|
return prioridades.length > 0 ? Math.min(...prioridades) : "Ultimo"; // Seleciona a prioridade mais baixa, ou "Ultimo"
|
|
},
|
|
// ==
|
|
temPrioridadeMaisAlta: function () {
|
|
const prioridades = Object.keys(this.fila).filter(p => p != "Ultimo" && p != "Primeiro").map(p => parseInt(p, 10));
|
|
return prioridades.length > 0; // Verifica se há prioridades maiores que "Ultimo"
|
|
}
|
|
};
|
|
|
|
const PK = {
|
|
PersAtivo: function (charId) {
|
|
var PersID = getActiveCharacterId();
|
|
var msg = {
|
|
"id": "0",
|
|
"type": "setActiveCharacter",
|
|
"data": charId
|
|
};
|
|
if (typeof self.dispatchEvent != "undefined") {
|
|
var ev = new CustomEvent("message");
|
|
ev.data = msg;
|
|
self.dispatchEvent(ev);
|
|
} else {
|
|
self.onmessage({
|
|
data: msg
|
|
});
|
|
}
|
|
return PersID;
|
|
},
|
|
// ==
|
|
pegarAtributos: function (atributos) {
|
|
var PersID = getActiveCharacterId();
|
|
return new Promise((resolve, reject) => {
|
|
var p_PersID = this.PersAtivo(PersID);
|
|
try {
|
|
getAttrs(atributos, (values) => resolve(values));
|
|
} catch {
|
|
reject();
|
|
}
|
|
}).finally(() => {
|
|
this.PersAtivo(PersID);
|
|
});
|
|
},
|
|
// ==
|
|
salvarAtributos: function (atributosObj, opcoes) {
|
|
var PersID = getActiveCharacterId();
|
|
return new Promise((resolve, reject) => {
|
|
var p_PersID = this.PersAtivo(PersID);
|
|
try {
|
|
setAttrs(atributosObj, opcoes, (values) => resolve(values));
|
|
} catch {
|
|
reject();
|
|
}
|
|
}).finally(() => {
|
|
this.PersAtivo(PersID);
|
|
});
|
|
},
|
|
// ==
|
|
pegarSecao: function (secao) {
|
|
secao = secao.startsWith("repeating_") ? secao : `repeating_${secao}`;
|
|
var PersID = getActiveCharacterId();
|
|
return new Promise((resolve, reject) => {
|
|
var p_PersID = this.PersAtivo(PersID);
|
|
try {
|
|
getSectionIDs(secao, (values) => resolve(values));
|
|
} catch {
|
|
reject();
|
|
}
|
|
}).finally(() => {
|
|
this.PersAtivo(PersID);
|
|
});
|
|
},
|
|
// ==
|
|
jogarDados: async function (query) {
|
|
let j = await startRoll(query);
|
|
finishRoll(j.rollId, {});
|
|
return j;
|
|
}
|
|
};
|
|
|
|
(function () {
|
|
const _sIn = setInterval;
|
|
const _sto = setTimeout;
|
|
// ==
|
|
setInterval = function (callback, tempo) {
|
|
var PersID = getActiveCharacterId();
|
|
_sIn(function () {
|
|
var p_PersID = PK.PersAtivo(PersID);
|
|
callback();
|
|
PK.PersAtivo(PersID);
|
|
}, tempo);
|
|
};
|
|
// ==
|
|
setTimeout = function (callback, tempo) {
|
|
var PersID = getActiveCharacterId();
|
|
_sto(function () {
|
|
var p_PersID = PK.PersAtivo(PersID);
|
|
callback();
|
|
PK.PersAtivo(PersID);
|
|
}, tempo);
|
|
};
|
|
})();
|
|
|
|
//
|
|
// ==================================================================
|
|
//
|
|
|
|
var mmod = ``;
|
|
|
|
const _attrs = ["str", "dex", "hea", "int", "wis", "cha"];
|
|
|
|
// Função auxiliar para atualizar atributos
|
|
const upm = async (attr) => {
|
|
let {
|
|
[attr]: valor = 0
|
|
} = await PK.pegarAtributos([attr]);
|
|
let mod = parseInt(valor) - 10;
|
|
let plus = mod > 0 ? 1 : 0;
|
|
await PK.salvarAtributos({
|
|
[`${attr}_mod`]: mod,
|
|
[`${attr}_plus`]: plus
|
|
}, {});
|
|
};
|
|
|
|
|
|
// Gatilho genérico para mudanças em atributos
|
|
_attrs.forEach((attr) => {
|
|
on(`change:${attr}`, async () => {
|
|
Fila.adicionar(() => upm(attr), 1);
|
|
});
|
|
|
|
on(`change:${attr}_mod`, async () => {
|
|
Fila.adicionar(async () => {
|
|
let {
|
|
[`${attr}_mod`]: mod = 0
|
|
} = await PK.pegarAtributos([`${attr}_mod`]);
|
|
await PK.salvarAtributos({
|
|
[`${attr}_plus`]: parseInt(mod) > 0 ? 1 : 0
|
|
}, {});
|
|
}, 0);
|
|
});
|
|
|
|
on(`clicked:${attr}_act`, async () => {
|
|
Fila.adicionar(async () => {
|
|
let {
|
|
character_name,
|
|
m_dice,
|
|
m_cd,
|
|
[attr]: valor
|
|
} = await PK.pegarAtributos([
|
|
"character_name",
|
|
"m_dice",
|
|
"m_cd",
|
|
attr,
|
|
]);
|
|
|
|
mmod = `+@{${attr}_mod} [${attr.toUpperCase()} mod]`;
|
|
|
|
|
|
m_cd = parseInt(m_cd || 0) * 1000;
|
|
|
|
const ddMap = {
|
|
"1": `{{md=[[1]]}} {{d1=[[d20${mmod}@{m_mod}]]}}`,
|
|
"2": `{{md=[[2]]}} {{d1=[[d20${mmod}@{m_mod}]]}} {{d2=[[d20${mmod}@{m_mod}]]}}`,
|
|
"3": `{{md=[[3]]}} {{d1=[[d20${mmod}@{m_mod}]]}} {{d2=[[d20${mmod}@{m_mod}]]}}`,
|
|
};
|
|
|
|
let dd = ddMap[m_dice] || "";
|
|
if (!dd) {
|
|
let ask;
|
|
let timeoutId;
|
|
let timedOut = false;
|
|
|
|
const timeout = new Promise((resolve) => {
|
|
timeoutId = setTimeout(() => {
|
|
timedOut = true;
|
|
resolve();
|
|
}, m_cd);
|
|
});
|
|
|
|
try {
|
|
ask = await Promise.race([
|
|
PK.jogarDados(
|
|
"!&{template:rolldice}{{v1=[[?{Mod Dice|Normal,1|Advantage,2|Disvantage,3}]]}}"
|
|
),
|
|
timeout,
|
|
]);
|
|
} catch {
|
|
return;
|
|
}
|
|
|
|
clearTimeout(timeoutId);
|
|
|
|
if (timedOut || !ask || !ask.results || !ask.results.v1) {
|
|
return;
|
|
}
|
|
|
|
dd = ddMap[ask.results.v1.result] || "";
|
|
}
|
|
|
|
let nm = character_name.split(" ")[0];
|
|
console.log(mmod);
|
|
let qr = `@{m_gm}&{template:rolldice} {{n=${nm}}} {{sk=${attr.toUpperCase()}}} ${dd} {{tm=[[@{${attr}_mod} [${attr.toUpperCase()} mod] ]]@{m_mod}}}`;
|
|
console.log(qr);
|
|
|
|
let sr;
|
|
let timeoutId2;
|
|
let timedOut2 = false;
|
|
|
|
const rollTimeout = new Promise((resolve) => {
|
|
timeoutId2 = setTimeout(() => {
|
|
timedOut2 = true;
|
|
resolve();
|
|
}, m_cd);
|
|
});
|
|
|
|
try {
|
|
sr = await Promise.race([startRoll(qr), rollTimeout]);
|
|
} catch {
|
|
return;
|
|
}
|
|
|
|
clearTimeout(timeoutId2);
|
|
|
|
if (timedOut2 || !sr) {
|
|
return;
|
|
}
|
|
|
|
finishRoll(sr.rollId, {});
|
|
}, 5);
|
|
});
|
|
|
|
});
|
|
|
|
on(`change:repeating_skill:base change:repeating_skill:lvl change:repeating_skill:mod`, async (e) => {
|
|
Fila.adicionar(async () => {
|
|
let id = `repeating_skill_${e.sourceAttribute.split("_")[2]}_`;
|
|
let v1 = await PK.pegarAtributos([`${id}base`, `${id}lvl`, `${id}mod`]);
|
|
let total = (parseInt(v1[`${id}base`] || 0) + parseInt(v1[`${id}lvl`] || 0) + parseInt(v1[`${id}mod`] || 0));
|
|
await PK.salvarAtributos({
|
|
[`${id}total`]: total
|
|
});
|
|
}, 0);
|
|
});
|
|
|
|
|
|
on(`clicked:repeating_skill:skill_act`, async (e) => {
|
|
Fila.adicionar(async () => {
|
|
let id = `repeating_skill_${e.sourceAttribute.split("_")[2]}_`;
|
|
let v1 = await PK.pegarAtributos([`${id}name`, `${id}attr`]);
|
|
let x = {
|
|
"—": "—",
|
|
"s": "str",
|
|
"d": "dex",
|
|
"h": "hea",
|
|
"i": "int",
|
|
"w": "wis",
|
|
"c": "cha"
|
|
} [v1[`${id}attr`]] || "—";
|
|
|
|
let {
|
|
character_name,
|
|
m_dice,
|
|
m_cd
|
|
} = await PK.pegarAtributos(["character_name", "m_dice", "m_cd"]);
|
|
|
|
|
|
m_cd = parseInt(m_cd || 0) * 1000;
|
|
|
|
let sn = v1[`${id}name`];
|
|
let ap = x !== "—" ? `${x.toUpperCase()} + ` : "";
|
|
let mp = x !== "—"
|
|
? ` @{${x}_mod} [${x.toUpperCase()} mod] + @{${id}total} [${sn}] `
|
|
: ` @{${id}total} [${sn}] ]]`;
|
|
|
|
mmod = ` + ${mp}`;
|
|
|
|
const ddMap = {
|
|
"1": `{{md=[[1]]}} {{d1=[[d20${mmod}@{m_mod}]]}}`,
|
|
"2": `{{md=[[2]]}} {{d1=[[d20${mmod}@{m_mod}]]}} {{d2=[[d20${mmod}@{m_mod}]]}}`,
|
|
"3": `{{md=[[3]]}} {{d1=[[d20${mmod}@{m_mod}]]}} {{d2=[[d20${mmod}@{m_mod}]]}}`,
|
|
};
|
|
|
|
let dd = ddMap[m_dice];
|
|
if (!dd) {
|
|
let ask;
|
|
let timeoutId;
|
|
let timedOut = false;
|
|
|
|
const timeout = new Promise((resolve) => {
|
|
timeoutId = setTimeout(() => {
|
|
timedOut = true;
|
|
resolve();
|
|
}, m_cd);
|
|
});
|
|
|
|
try {
|
|
ask = await Promise.race([
|
|
PK.jogarDados("!&{template:rolldice}{{v1=[[?{Mod Dice|Normal,1|Advantage,2|Disvantage,3}]]}}"),
|
|
timeout
|
|
]);
|
|
} catch {
|
|
return;
|
|
}
|
|
|
|
clearTimeout(timeoutId);
|
|
|
|
if (timedOut || !ask || !ask.results || !ask.results.v1) {
|
|
return;
|
|
}
|
|
|
|
dd = ddMap[ask.results.v1.result];
|
|
}
|
|
|
|
let qr = `@{m_gm}&{template:rolldice} {{n=${character_name.split(" ")[0]}}} {{sk=${ap}${sn}}} ${dd} {{tm=[[${mp}]]@{m_mod}}}`;
|
|
|
|
let sr;
|
|
let timeoutId2;
|
|
let timedOut2 = false;
|
|
|
|
const rollTimeout = new Promise((resolve) => {
|
|
timeoutId2 = setTimeout(() => {
|
|
timedOut2 = true;
|
|
resolve();
|
|
}, m_cd);
|
|
});
|
|
|
|
try {
|
|
sr = await Promise.race([startRoll(qr), rollTimeout]);
|
|
} catch {
|
|
return;
|
|
}
|
|
|
|
clearTimeout(timeoutId2);
|
|
|
|
if (timedOut2 || !sr) {
|
|
return;
|
|
}
|
|
|
|
finishRoll(sr.rollId, {});
|
|
}, 5);
|
|
});
|
|
|
|
|
|
on(`clicked:repeating_weapon:dmg_act`, async (e) => {
|
|
Fila.adicionar(async () => {
|
|
let id = `repeating_weapon_${e.sourceAttribute.split("_")[2]}_`;
|
|
let v1 = await PK.pegarAtributos([`character_name`, `${id}name`, `${id}dam`, `${id}dam_1`, `${id}dam_2`, `${id}dam_total`]);
|
|
|
|
let qr = `@{m_gm}&{template:rolldice} {{sk=${v1[`${id}name`]}}} {{md=[[0]]}} {{d1=[[${v1[`${id}dam`]} + ${v1[`${id}dam_total`]}]]}} {{tm=${v1[`${id}dam_1`]}+${v1[`${id}dam_2`]}}}`;
|
|
|
|
let sr = await startRoll(qr);
|
|
finishRoll(sr.rollId, {});
|
|
}, 5);
|
|
});
|
|
|
|
on(`clicked:skill_layout_1 clicked:talent_layout_1 clicked:item_layout_1`, async (e) => {
|
|
let n = e.htmlAttributes.name.replace("act_", "");
|
|
|
|
Fila.adicionar(async () => {
|
|
let v1 = await PK.pegarAtributos([`${n}`]);
|
|
let v = parseInt(v1[`${n}`] || 1);
|
|
let x = (v + 1) > 4 ? 1 : v + 1;
|
|
await PK.salvarAtributos({
|
|
[`${n}`]: x
|
|
});
|
|
});
|
|
});
|
|
|
|
|
|
on(`change:repeating_weapon:dam change:repeating_weapon:dam_2 change:repeating_weapon:dam_mod`, async (e) => {
|
|
Fila.adicionar(async () => {
|
|
let r = `repeating_weapon_${e.sourceAttribute.split("_")[2]}_`;
|
|
let v = await PK.pegarAtributos([`character_id`, `str_mod`, `dex_mod`, `hea_mod`, `int_mod`, `wis_mod`, `cha_mod`, `${r}dam`, `${r}dam_2`, `${r}dam_mod`, `${r}dam_2_mod`, `${r}has_mod`, `${r}dam_2_is_plus`, `${r}dam_total`]);
|
|
let t = 0;
|
|
|
|
const cleanExpression = (expression) => {
|
|
return expression.replace(/\((\d+\+\?\{[^}]+\})\)/g, "$1").replace(/\+\?\{[^}]+\}/g, "");
|
|
};
|
|
|
|
const eMath = async (expression) => {
|
|
let refs = [];
|
|
let tokens = expression.match(/([+\-*/()])|(@\{[^}]+\})|(\d+)/g);
|
|
|
|
if (!tokens) return 0;
|
|
|
|
for (let i = 0; i < tokens.length; i++) {
|
|
if (tokens[i].startsWith("@{")) {
|
|
let attr = tokens[i].slice(2, -1);
|
|
refs.push(attr);
|
|
}
|
|
}
|
|
|
|
if (refs.length > 0) {
|
|
let fetched = await PK.pegarAtributos(refs);
|
|
tokens = tokens.map(tok =>
|
|
tok.startsWith("@{") ? (parseInt(fetched[tok.slice(2, -1)]) || 0) : tok
|
|
);
|
|
}
|
|
|
|
return Function(`return ${tokens.join("")}`)();
|
|
};
|
|
|
|
let dam = cleanExpression(v[`${r}dam`] || "0");
|
|
|
|
if (v[`${r}dam_2`] == "@{dam_mod}") {
|
|
t = await eMath(cleanExpression(v[`${r}dam_mod`] || "0"));
|
|
} else {
|
|
let attr = v[`${r}dam_2`].replace("@{", "").replace("}", "");
|
|
t = parseInt(v[attr] || 0);
|
|
}
|
|
|
|
let h = t !== 0 ? 1 : 0;
|
|
let p = t > 0 ? 1 : 0;
|
|
|
|
await PK.salvarAtributos({
|
|
[`${r}dam_1`]: dam,
|
|
[`${r}dam_total`]: t,
|
|
[`${r}dam_2_is_plus`]: p,
|
|
[`${r}has_mod`]: h
|
|
});
|
|
}, 0);
|
|
});
|
|
|
|
on(`clicked:repeating_weapon:weapon_act`, async (e) => {
|
|
Fila.adicionar(async () => {
|
|
const s = await PK.pegarSecao("repeating_skill");
|
|
|
|
const baseAttrs = [{
|
|
name: "STR",
|
|
id: "1001",
|
|
pos: s.length + 1
|
|
},
|
|
{
|
|
name: "DEX",
|
|
id: "1002",
|
|
pos: s.length + 2
|
|
},
|
|
{
|
|
name: "HEA",
|
|
id: "1003",
|
|
pos: s.length + 3
|
|
},
|
|
{
|
|
name: "INT",
|
|
id: "1004",
|
|
pos: s.length + 4
|
|
},
|
|
{
|
|
name: "WIS",
|
|
id: "1005",
|
|
pos: s.length + 5
|
|
},
|
|
{
|
|
name: "CHA",
|
|
id: "1006",
|
|
pos: s.length + 6
|
|
}
|
|
];
|
|
|
|
let sl = [];
|
|
const r = `repeating_weapon_${e.sourceAttribute.split("_")[2]}_`;
|
|
const v = await PK.pegarAtributos([
|
|
`character_id`,
|
|
`character_name`,
|
|
`${r}last_selected`,
|
|
"m_dice",
|
|
"m_cd"
|
|
]);
|
|
|
|
|
|
let m_cd = parseInt(v.m_cd || 0) * 1000;
|
|
|
|
const l = v[`${r}last_selected`] || "";
|
|
|
|
if (s.length > 0) {
|
|
const a = await PK.pegarAtributos(s.map(i => `repeating_skill_${i}_name`));
|
|
sl = s.map((i, idx) => ({
|
|
name: a[`repeating_skill_${i}_name`] || "",
|
|
id: i,
|
|
pos: idx + 1
|
|
})).sort((x, y) => x.name.localeCompare(y.name));
|
|
}
|
|
|
|
sl = [...sl, ...baseAttrs];
|
|
const qStart = l ? `→${sl.find(sk => sk.id == l)?.name},${sl.find(sk => sk.id == l)?.pos}` : "";
|
|
sl = l ? sl.filter(sk => sk.id !== l) : sl;
|
|
const q = qStart ? `${qStart}|${sl.map(sk => `${sk.name},${sk.pos}`).join("|")}` : sl.map(sk => `${sk.name},${sk.pos}`).join("|");
|
|
|
|
let sr;
|
|
let timeoutId;
|
|
let timedOut = false;
|
|
|
|
const timeout = new Promise((resolve) => {
|
|
timeoutId = setTimeout(() => {
|
|
timedOut = true;
|
|
resolve();
|
|
}, m_cd);
|
|
});
|
|
|
|
try {
|
|
sr = await Promise.race([startRoll(`!&{template:rolldice}{{v1=[[?{Select|${q}}]]}}`), timeout]);
|
|
} catch {
|
|
return;
|
|
}
|
|
|
|
clearTimeout(timeoutId);
|
|
|
|
if (timedOut || !sr || !sr.results || !sr.results.v1) {
|
|
return;
|
|
}
|
|
|
|
const ch = sr.results.v1.result || 1;
|
|
const cs = sl.find(sk => sk.pos == ch) || {
|
|
id: l
|
|
};
|
|
|
|
finishRoll(sr.rollId, {});
|
|
|
|
await PK.salvarAtributos({
|
|
[`${r}last_selected`]: cs.id
|
|
});
|
|
|
|
let diceType = v.m_dice || "1";
|
|
|
|
console.log(diceType);
|
|
|
|
if (!diceType || diceType == "4") {
|
|
let ask;
|
|
timedOut = false;
|
|
|
|
const diceTimeout = new Promise((resolve) => {
|
|
timeoutId = setTimeout(() => {
|
|
timedOut = true;
|
|
resolve();
|
|
}, m_cd);
|
|
});
|
|
|
|
try {
|
|
ask = await Promise.race([
|
|
PK.jogarDados("!&{template:rolldice}{{v1=[[?{Mod Dice|Normal,1|Advantage,2|Disadvantage,3}]]}}"),
|
|
diceTimeout
|
|
]);
|
|
} catch {
|
|
return;
|
|
}
|
|
|
|
clearTimeout(timeoutId);
|
|
|
|
if (timedOut || !ask || !ask.results || !ask.results.v1) {
|
|
return;
|
|
}
|
|
|
|
diceType = ask.results.v1.result;
|
|
|
|
console.log(diceType);
|
|
}
|
|
|
|
const {
|
|
character_name
|
|
} = v;
|
|
|
|
if (baseAttrs.some(attr => attr.id == cs.id)) {
|
|
const attrName = baseAttrs.find(attr => attr.id == cs.id)?.name.toLowerCase();
|
|
const mmod = ` + @{${attrName}_mod} [${attrName.toUpperCase()} Mod]`;
|
|
const dd = diceType == "2"
|
|
? `{{md=[[2]]}} {{d1=[[d20${mmod}@{m_mod}]]}} {{d2=[[d20${mmod}@{m_mod}]]}}`
|
|
: diceType == "3"
|
|
? `{{md=[[3]]}} {{d1=[[d20${mmod}@{m_mod}]]}} {{d2=[[d20${mmod}@{m_mod}]]}}`
|
|
: `{{md=[[1]]}} {{d1=[[d20${mmod}@{m_mod}]]}}`;
|
|
|
|
const sr2 = await startRoll(`@{m_gm}&{template:rolldice} {{n=${character_name.split(" ")[0]}}} {{sk=${attrName.toUpperCase()}}} ${dd} {{tm=[[ @{${attrName}_mod} [${attrName.toUpperCase()} Mod] ]]@{m_mod}}}`);
|
|
|
|
console.log(`&{template:rolldice} {{n=${character_name.split(" ")[0]}}} {{sk=${attrName.toUpperCase()}}} ${dd} {{tm=[[ @{${attrName}_mod} [${attrName.toUpperCase()} Mod] ]]@{m_mod}}}`);
|
|
|
|
finishRoll(sr2.rollId, {});
|
|
} else {
|
|
const id = `repeating_skill_${cs.id}_`;
|
|
const v1 = await PK.pegarAtributos([`${id}name`, `${id}attr`]);
|
|
const x = {
|
|
s: "str",
|
|
d: "dex",
|
|
h: "hea",
|
|
i: "int",
|
|
w: "wis",
|
|
c: "cha"
|
|
} [v1[`${id}attr`]] || "—";
|
|
const sn = v1[`${id}name`];
|
|
const mp = x !== "—"
|
|
? `@{${x}_mod} [${x.toUpperCase()} mod] + @{${id}total} [${sn}]`
|
|
: `@{${id}total} [${sn}]`;
|
|
|
|
const dd = diceType == "2"
|
|
? `{{md=[[2]]}} {{d1=[[d20 + ${mp}@{m_mod}]]}} {{d2=[[d20 + ${mp}@{m_mod}]]}}`
|
|
: diceType == "3"
|
|
? `{{md=[[3]]}} {{d1=[[d20 + ${mp}@{m_mod}]]}} {{d2=[[d20 + ${mp}@{m_mod}]]}}`
|
|
: `{{md=[[1]]}} {{d1=[[d20 + ${mp}@{m_mod}]]}}`;
|
|
|
|
const sr2 = await startRoll(`@{m_gm}&{template:rolldice} {{n=${character_name.split(" ")[0]}}} {{sk=${x !== "—" ? `${x.toUpperCase()} + ` : ""}${sn}}} ${dd} {{tm=[[ ${mp} ]]@{m_mod}}}`);
|
|
|
|
finishRoll(sr2.rollId, {});
|
|
}
|
|
}, 5);
|
|
});
|
|
|
|
|
|
on(`sheet:opened`, async (e) => {
|
|
let v1 = await PK.pegarAtributos(["new_sheet", "hea_mod"]);
|
|
|
|
if (v1[`new_sheet`] == 1) {
|
|
|
|
let wounds = parseInt(v1[`hea_mod`] || 0) + 10;
|
|
|
|
await PK.salvarAtributos({
|
|
[`new_sheet`]: 0,
|
|
[`wounds_max`]: wounds
|
|
}, {});
|
|
}
|
|
});
|
|
|
|
on(`change:hea_mod`, async (e) => {
|
|
Fila.adicionar(async () => {
|
|
let v1 = await PK.pegarAtributos(["hea_mod"]);
|
|
|
|
let wounds = parseInt(v1[`hea_mod`] || 0) + 10;
|
|
|
|
await PK.salvarAtributos({
|
|
[`wounds_max`]: wounds
|
|
}, {});
|
|
}, 1);
|
|
|
|
});
|
|
|
|
on(`clicked:repeating_spell:spell_act`, async (e) => {
|
|
const r = `repeating_spell_${e.sourceAttribute.split("_")[2]}_`;
|
|
|
|
Fila.adicionar(async () => {
|
|
let v1 = await PK.pegarAtributos([
|
|
"mana",
|
|
"mana_max",
|
|
`${r}cost`,
|
|
`${r}name`,
|
|
`${r}extra_mana`,
|
|
"character_name",
|
|
"m_cast",
|
|
"m_cd"
|
|
]);
|
|
|
|
let m_cd = parseInt(v1.m_cd || 0) * 1000;
|
|
|
|
let curMana = parseInt(v1.mana || 0);
|
|
let cost = Math.max(parseInt(v1[`${r}cost`] || 0), 0);
|
|
let spell = v1[`${r}name`] || "—";
|
|
let char = v1.character_name.split(" ")[0] || "—";
|
|
let castEnabled = parseInt(v1.m_cast || 0);
|
|
let extraManaEnabled = parseInt(v1[`${r}extra_mana`] || 0);
|
|
|
|
let mm = "";
|
|
let useMana = false;
|
|
let additionalMana = 0;
|
|
|
|
if (castEnabled === 1 && cost > 0 && curMana >= cost) {
|
|
let timedOut = false;
|
|
const timeout = new Promise((resolve) => setTimeout(() => {
|
|
timedOut = true;
|
|
resolve();
|
|
}, m_cd));
|
|
|
|
const conf = await Promise.race([
|
|
startRoll(`!&{template:default}{{v=[[?{Spend Mana (${cost})? ${curMana} left|Yes,1|No,0}]]}}`),
|
|
timeout
|
|
]);
|
|
|
|
if (!timedOut && conf && conf.results && conf.results.v) {
|
|
finishRoll(conf.rollId, {});
|
|
useMana = conf.results.v.result === 1;
|
|
}
|
|
|
|
if (useMana && extraManaEnabled === 1) {
|
|
let maxExtraMana = curMana - cost;
|
|
if (maxExtraMana > 0) {
|
|
timedOut = false;
|
|
const extraTimeout = new Promise((resolve) => setTimeout(() => {
|
|
timedOut = true;
|
|
resolve();
|
|
}, m_cd));
|
|
|
|
const addManaRoll = await Promise.race([
|
|
startRoll(`!&{template:default}{{v=[[?{Extra Mana? Max: ${maxExtraMana}|0}]]}}`),
|
|
extraTimeout
|
|
]);
|
|
|
|
if (!timedOut && addManaRoll && addManaRoll.results && addManaRoll.results.v) {
|
|
finishRoll(addManaRoll.rollId, {});
|
|
additionalMana = parseInt(addManaRoll.results.v.result || 0);
|
|
} else {
|
|
additionalMana = 0; // Default to 0 if no response
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (useMana && curMana >= cost) {
|
|
let spentMana = cost + additionalMana;
|
|
let manaLeft = Math.max(curMana - spentMana, 0);
|
|
|
|
if (additionalMana === 0) {
|
|
mm = `{{c=spent ${spentMana} mana, left: ${manaLeft}}}`;
|
|
} else {
|
|
let extraDesc = additionalMana > 0 ? `+${additionalMana} extra` : `${additionalMana} extra`;
|
|
mm = `{{c=spent (${cost}${extraDesc}) mana, left: ${manaLeft}}}`;
|
|
}
|
|
}
|
|
|
|
const roll = await startRoll(`@{m_gm}&{template:rolldice} {{n=${char}}} {{s=@{${r}name}}} ${mm} {{e=@{${r}effect}}}`);
|
|
finishRoll(roll.rollId, {});
|
|
|
|
if (useMana && curMana >= cost) {
|
|
let newMana = Math.max(curMana - (cost + additionalMana), 0);
|
|
await PK.salvarAtributos({
|
|
mana: newMana
|
|
}, {});
|
|
}
|
|
}, 1);
|
|
});
|
|
|
|
|
|
|
|
const updateActions = async (type, ids) => {
|
|
Fila.adicionar(async () => {
|
|
let {
|
|
character_id
|
|
} = await PK.pegarAtributos([`character_id`]);
|
|
let updates = {};
|
|
|
|
ids.forEach((id) => {
|
|
let r = `repeating_${type}_${id}_`;
|
|
updates[`${r}${type}_btn`] = `%{${character_id}|${r}${type}_act}`;
|
|
|
|
if (type === "weapon") {
|
|
updates[`${r}dmg_btn`] = `%{${character_id}|${r}dmg_act}`;
|
|
}
|
|
});
|
|
|
|
await PK.salvarAtributos(updates, {});
|
|
}, 0);
|
|
};
|
|
|
|
on("sheet:opened change:character_name", async () => {
|
|
Fila.adicionar(async () => {
|
|
let {
|
|
character_id,
|
|
...attrs
|
|
} = await PK.pegarAtributos(["character_id", ..._attrs]);
|
|
let updates = Object.fromEntries(
|
|
_attrs.map((x) => [`${x}_btn`, `%{${character_id}|${x}_act}`])
|
|
);
|
|
|
|
const repeatingSections = ["skill", "spell", "weapon"];
|
|
for (let type of repeatingSections) {
|
|
const ids = await PK.pegarSecao(`repeating_${type}`);
|
|
await updateActions(type, ids);
|
|
}
|
|
|
|
await PK.salvarAtributos(updates, {});
|
|
}, 1);
|
|
});
|
|
|
|
on(`change:repeating_skill:attr`, async (e) => {
|
|
updateActions("skill", [e.sourceAttribute.split("_")[2]]);
|
|
});
|
|
|
|
on(`change:repeating_spell`, async (e) => {
|
|
updateActions("spell", [e.sourceAttribute.split("_")[2]]);
|
|
});
|
|
|
|
on(`change:repeating_weapon`, async (e) => {
|
|
if (!e.newValue) return;
|
|
updateActions("weapon", [e.sourceAttribute.split("_")[2]]);
|
|
});
|
|
|
|
// UPDATE
|
|
on(`sheet:opened`, async (e) => {
|
|
let newversion = "1.0.1";
|
|
let date = "2025/02/24";
|
|
|
|
let v1 = await PK.pegarAtributos(["old_version", "version", "update", "last_update"]);
|
|
let version = v1.version || "0.0.0"; // Garante que tenha um valor padrão
|
|
let update = v1.update || "no";
|
|
|
|
if (version === newversion && update === "yes") {
|
|
console.log(`Sheet is already updated to version ${newversion}`);
|
|
return;
|
|
}
|
|
|
|
console.log(`Updating from version ${version} to ${newversion}...`);
|
|
|
|
let attr = {
|
|
"old_version": version,
|
|
"version": newversion,
|
|
"update": "yes",
|
|
"last_update": date
|
|
};
|
|
|
|
let updateComplete = await updateSheet250224();
|
|
|
|
if (updateComplete) {
|
|
await PK.salvarAtributos(attr);
|
|
console.log(`Update completed! New version: ${newversion} (${date})`);
|
|
} else {
|
|
console.log("Update failed or no changes needed.");
|
|
}
|
|
});
|
|
|
|
async function updateSheet250224() {
|
|
let s1 = await PK.pegarSecao("skill") ?? [];
|
|
|
|
if (s1.length === 0) {
|
|
console.log("No skills found. Skipping update.");
|
|
return false;
|
|
}
|
|
|
|
let atributos = await PK.pegarAtributos(s1.flatMap(i => [
|
|
`repeating_skill_${i}_name`,
|
|
`repeating_skill_${i}_base`,
|
|
`repeating_skill_${i}_lvl`,
|
|
`repeating_skill_${i}_mod`
|
|
]));
|
|
|
|
let updates = s1.map(i => {
|
|
let base = parseInt(atributos[`repeating_skill_${i}_base`]) || 0;
|
|
let lvl = parseInt(atributos[`repeating_skill_${i}_lvl`]) || 0;
|
|
let mod = parseInt(atributos[`repeating_skill_${i}_mod`]) || 0;
|
|
|
|
return {
|
|
[`repeating_skill_${i}_base`]: base + lvl,
|
|
[`repeating_skill_${i}_lvl`]: 0,
|
|
[`repeating_skill_${i}_mod`]: mod
|
|
};
|
|
});
|
|
|
|
// Aplica todas as atualizações em paralelo
|
|
await Promise.all(updates.map(update => PK.salvarAtributos(update)));
|
|
|
|
console.log(`Updated ${s1.length} skills.`);
|
|
return true;
|
|
}
|
|
|
|
</script>
|
|
<div class="s-register">
|
|
<label>
|
|
<span style="font-weight: bold"><span>Sheet Version </span><span name="attr_version"></span> (<span name="attr_last_update"></span>)</span>
|
|
<input type="checkbox" name="attr_update_log" value="1">
|
|
Log
|
|
<div class="s-log">
|
|
<ul>
|
|
<li>2025/02/24 - <strong>Version 1.0.1</strong>
|
|
<ul>
|
|
<li>Modified <strong>Skill structure</strong> for better usability: <code>{Attr + Base + Lvl + Mod = Total} → {Attr + Skill + Mod = Total}</code> </li>
|
|
<li>Buttons to change Layout Appearance (Skills, Talents...) now work on the first click instead of requiring two.</li>
|
|
</ul>
|
|
</li>
|
|
<li>2024/12/24 - <strong>Version 1.0.0</strong> - Initial release</li>
|
|
</ul>
|
|
</div>
|
|
</label>
|
|
</div>
|
|
<input type="hidden" name="attr_old_version" value="1.0.0">
|
|
<input type="hidden" name="attr_version" value="1.0.0">
|
|
<input type="hidden" name="attr_update" value="no">
|
|
<input type="hidden" name="attr_last_update" value="2024/12/24">
|