Compare commits

...

2 Commits

Author SHA1 Message Date
4061371945 Parse critical tables 2024-10-20 18:21:19 +02:00
973d8733b2 Sync with latest fixes 2024-09-30 13:41:44 +02:00
17 changed files with 371 additions and 29 deletions

View File

@ -212,7 +212,10 @@
"critical_table": "Critical Table",
"lsl_crit_column": "LSL",
"range_modifier": "Range Modifier",
"weapon_bonus": "Weapon Bonus"
"weapon_bonus": "Weapon Bonus",
"fumble_value": "Fumble Max Value",
"fumble_table": "Fumble Table",
"fumble_column": "Fumble Column"
},
"herb_or_poison": {
"codes": "Codes",

View File

@ -11,9 +11,10 @@ const tables = {};
fs.readdirSync(tablesDir).forEach(file => {
const table = require(path.join(tablesDir, file));
tables[file] = table;
console.log(`Processing ${file} ${table}`);
//tables[file] = table;
}
);
fs.writeFileSync(path.join(__dirname, 'tables.js'), `module.exports = ${JSON.stringify(tables, null, 2)};`);
console.log('Tables created');
//fs.writeFileSync(path.join(__dirname, 'tables.js'), `module.exports = ${JSON.stringify(tables, null, 2)};`);
console.log('Tables created');a

View File

@ -0,0 +1,138 @@
local lfs = require "lfs"
local json = require "dkjson"
local _CRIT_KEYS = {"A", "B", "C", "D", "E"}
local function process_values(rest, condition)
-- Get the +XH (with X being a number)
local damage = rest:match("%+(%d*)H")
-- π = mustparry
local mustparry = false
if rest:match(" π") then
mustparry = 1
end
if rest:match(" (%d)π") then
mustparry = rest:match(" (%d*)π")
end
local mustparry_duration = false
local mustparry_value = false
local duration, value = rest:match(" (%d?)%((π%-?%d+)%)")
if duration or value then
mustparry_duration = tonumber(duration) or 1
mustparry_value = tonumber(value)
end
-- ∑ = stunned
local stunned = false
local match = rest:match(" (%d*)∑")
if match then
stunned = tonumber(match) or 1
end
-- ∏ = cannot parry
local cannot_parry = false
match = rest:match(" (%d*)∑?∏")
if match then
cannot_parry = tonumber(match) or 1
end
match = rest:match(" (%d*)∏")
if match then
cannot_parry = tonumber(match) or 1
end
-- ∫ = wounds per rounds
local wounds_per_round = false
match = rest:match(" (%d?)∫")
if match then
wounds_per_round = tonumber(match) or 1
end
-- Round penalty
local round_penalty_duration = false
local nbRounds, round_penalty_value = rest:match(" (%d?)%((%-?%d+)%)")
if nbRounds or round_penalty_value then
round_penalty_duration = tonumber(nbRounds) or 1
round_penalty_value = tonumber(round_penalty_value)
end
-- Round bonus
local round_bonus_duration = false
local nbRounds, round_bonus_value = rest:match(" (%d?)%((%+?%d+)%)")
if nbRounds or round_bonus_value then
round_bonus_duration = tonumber(nbRounds) or 1
round_bonus_value = tonumber(round_bonus_value)
end
print(rest, damage, mustparry, stunned, cannot_parry, wounds_per_round, round_penalty_duration, round_penalty_value,
round_bonus_duration, round_bonus_value)
return {
condition = condition or "none",
damage = damage,
mustparry = mustparry,
stunned = stunned,
cannot_parry = cannot_parry,
wounds_per_round = wounds_per_round,
round_penalty_duration = round_penalty_duration,
round_penalty_value = round_penalty_value,
round_bonus_duration = round_bonus_duration,
round_bonus_value = round_bonus_value,
mustparry_duration = mustparry_duration,
mustparry_value = mustparry_value
}
end
local all_criticals = {}
-- Loop thru all JSON files in the criticals_data directory
for file in lfs.dir("./") do
if file:match("json$") then
local json_file = io.open("./" .. file, "r")
local json_data = json_file:read("*a")
json_file:close()
local crit = {
name = string.match(file, "(%w+).json"),
criticals = {}
}
local rows = json.decode(json_data)
for _, c in ipairs(rows) do
local new_crit = {
score = c.Score,
levels = {}
}
for _, key in ipairs(_CRIT_KEYS) do
local effects = {}
local line = c[key]
-- Get description (ie all text befire the first \n)
local desc = line:match("([^\n]+)")
-- Get the rest of the text
local rest = line:match("\n(.+)")
if rest:match("with ") then
local reasonwith, with, reasonwithout , without = rest:match("(with[^:]*): ([^w]+)(w/o[^:]*): (.+)")
print("SPLITTEW WITH", desc)
effects[1] = process_values(with, reasonwith)
effects[2] = process_values(without, reasonwithout)
else
effects[1] = process_values(rest)
end
new_crit.levels[key] = {
key = key,
description = desc,
effects = effects
}
end
table.insert(crit.criticals, new_crit)
end
all_criticals[crit.name] = crit
end
end
-- Convert to JSON
local json_data = json.encode(all_criticals, {indent = true})
print(json_data)

View File

@ -0,0 +1,154 @@
[
{
"Score": "01-05",
"A": "Weak strike.\n+0H",
"B": "Feeble strike falls clear of target.\n+0H",
"C": "Firm shot. Good recovery. Try again.\n+1H",
"D": "Strike lands poorly.\n+2H",
"E": "Your attack is weak.\n+3H"
},
{
"Score": "06-10",
"A": "Good form, but it disappoints.\n+1H",
"B": "Hard strike with no edge. Foe steps clear before you sort it out.\n+2H",
"C": "Strike foe with more force than edge.\n+3H",
"D": "An opening appears and all you can to is smack foe lightly.\n+4H",
"E": "Unbalance foe. You receive initiative next round.\n+5H"
},
{
"Score": "11-15",
"A": "Blade misses foe's face by inches. You receive initiative next round.\n+1H",
"B": "Foe steps quickly out of your reach. You receive initiative next round.\n+3H",
"C": "Blow to foe's side yields the initiative to you next round.\n+6H",
"D": "You force your opponent back. He keeps you at bay with wild swings.\n+3H π",
"E": "You push aside foe's weapon and force him back.\n+4H π"
},
{
"Score": "16-20",
"A": "Strike passes under foe's arm. It fails to bite deep. He recoils.\n+1H π",
"B": "Blow to foe's side. Foe defends energetically.\n+2H (π-10)",
"C": "Your assault catches foe in side and forces him back 5 feet.\n+4H (π-20)",
"D": "You lean in and slash foe's side. You receive initiative next round.\n+2H (-10)",
"E": "Strong blow to foe's ribs. Foe drops his guard and almost his weapon.\n∑∏ (+10)"
},
{
"Score": "21-35",
"A": "Foe's evasion puts him out of an aggressive posture.\n+2H π (+10)",
"B": "Foe is shaken by your blow to his side. His defensive measures look clumsy.\n+2H (π-20)",
"C": "You break foe's rib with a lightning strike to his chest. He recovers quickly. His shield side still faces you.\n+3H ∑",
"D": "Arm and chest strike. Foe cannot defend himself for a moment. You step around his shielded side.\n+3H ∑∏",
"E": "Foe avoids your main effort, but you nick him on your recovery. Foe receives minor side wound and stumbles back 10 feet.\n+3H (-10)"
},
{
"Score": "36-45",
"A": "Minor thigh wound. Cut foe with the smallest of slashes.\n∫",
"B": "Strike foe in shin. If he doesn't have greaves, you slash open foe's shin.\nwith leg greaves: +2H π w/o leg greaves: +2H ∫",
"C": "The blow does nothing more than open a wide cut in foe.\n+2H 2∫",
"D": "Foe blocks your attack on his chest. You slash foe's upper area.\n+3H 2∫",
"E": "Blow to foe's upper leg. Leg armor helps block the blow.\nwith leg greaves: +5H w/o leg greaves: +3H 3∫"
},
{
"Score": "46-50",
"A": "Blow to foe's back. Foe attempts to ward you off with a wild swing.\n+2H (π-30)",
"B": "Foe twists oddly to avoid your attack. Blow strikes foe's back.\n+4H (π-30)",
"C": "Blow to foe's back. Foe twists out of it and you turn your weapon to magnify the wound. Foe yells out.\n+3H ∑∏ ∫",
"D": "Reach long and catch foe in his lower back. He twists out of it, but is unbalanced.\n+3H ∑∏ 2∫",
"E": "Strike to foe's stomach. He doubles over in pain and you pull your sword clean with one more sweep.\n+4H ∑∏ 3∫"
},
{
"Score": "51-55",
"A": "Blow to foe's chest. Foe stumbles back and puts up a feeble guard.\n+2H (π-25) ∫",
"B": "Quality strike. Minor chest wound. If foe has armor, he only staggers. If not, the wound is effective.\nwith chest armor: +4H π w/o chest armor: +3H (-5)",
"C": "Blow lands solidly upon foe's chest. You get some slashing action, but not a mortal wound.\n+4H π 2∫ (-10)",
"D": "Heavy blow to upper torso. Wound falls open and foe is in pain. His guard is still up, amazingly enough.\n+5H π 3∫ (-15)",
"E": "Cut foe open with little grace. You are unsure of your success until you see all the blood coming out of his chest.\n+6H 2∑ 4∫ (-10)"
},
{
"Score": "56-60",
"A": "You recover from your initial swing and bring edge across foe's thigh.\n+3H π 2∫",
"B": "Edge makes contact well enough. Minor thigh wound.\n+4H 2∫",
"C": "Strike to side slips down onto foe's thigh. The wound is effective.\n+5H 2∫",
"D": "Tip of your blade gets a hit on foe's thigh. You twist your weapon.\n+6H 2∑ 2∫",
"E": "Thigh wound. Your blow cuts deep and severs an important vein.\n+8H 2∑ 5∫"
},
{
"Score": "61-65",
"A": "You feign high and strike low. Slash foe in back of upper leg.\n+3H 2∫ (-10)",
"B": "Nick foe in his forearm. Wound bleeds surprisingly strongly.\n+4H 2∫ (-10)",
"C": "Catch part of foe's forearm. You make a long slice in foe's arm.\n+4H 3∫ (-10)",
"D": "You are lucky to strike foe's forearm while recovering from a lunge.\n+4H 2∑ 3∫ (-10)",
"E": "Foe tries to disarm you and pays with a nasty cut to his forearm.\n+6H 2∑ 3∫ (-15)"
},
{
"Score": 66,
"A": "Foe blocks your attack with his shield arm. Shoulder is broken and arm is useless. You have initiative.\n+9H 3∑ (+10)",
"B": "Your strike misses torso and breaks foe's elbow. Foe drops his weapon and his weapon arm is useless.\n+8H 4∑ 2∏",
"C": "Your swing falls short when foe leaps back. You shatter foe's knee. Foe is knocked down.\n+6H 3∏ (-90)",
"D": "You knock foe out for 6 hours with a strike to side of head. If foe has no helm, you kill him instantly.\n+15H",
"E": "Block foe's weapon arm away and then sever it. Foe drops immediately and expires in 12 rounds. Good shot!\n+12H (+10)"
},
{
"Score": "67-70",
"A": "Strike lands close against foe's neck. Foe is horrified.\n+6H 3∑ ∏",
"B": "Your attempt to behead foe almost works. Neck strike. Foe is not happy.\n+7H 2∑ 3∫ (-5)",
"C": "Slash foe's neck. Your weapon cuts neck garments (and armor) free.\n+8H 4∑ 2∏ (+10)",
"D": "You strike foe's shoulder and slash muscles.\n+5H 3∑ (-20) (+10)",
"E": "Slash tendons and crush the bones in foe's shield arm shoulder. Arm is useless.\n4∑ 2∫"
},
{
"Score": "71-75",
"A": "Blow falls on lower leg. Slash tendons. Poor sucker.\n+4H 2∑ 2∫ (-30)",
"B": "Slash muscle in foe's calf. Foe is in too much pain to regain footing quickly.\n+6H 3∑ (-40)",
"C": "Slash muscle and tendons in foe's lower leg. Foe stumbles forward into you with his guard down.\n+7H 2∑∏ (-45)",
"D": "Slash muscle and sever tendons in foe's lower leg. He can't stand much longer. His guard is feeble.\n3∑ 2∏ (-50)",
"E": "Slash foe's lower leg and sever muscle and tendons. Foe will fall without something to lean against.\n+8H 6∑ (-70)"
},
{
"Score": "76-80",
"A": "Foe goes low, but you still catch his upper arm. It's a bleeder.\n+5H 2∑∏ 3∫ (-25)",
"B": "Foe moves his shield arm too slowly. You gladly slash his arm.\n+6H 2∑∏ 3∫ (-30)",
"C": "You come in high and fast. Slash muscle and tendons in foe's shield arm. Foe's arm is useless.\n+9H 6∑ 4∫",
"D": "Foe mistakenly brings his weapon arm across your blade. Sever tendons.Foe's arm is limp and useless.\n+10H 4∑ 2∏",
"E": "Foe reaches out to block your blow. You sever two fingers and break his shield arm making it useless.\n+12H 3∑∏"
},
{
"Score": "81-85",
"A": "Foe steps right into your swing. You make a large wound.\n+6H 5∑ 6∫ (+20)",
"B": "Your edge bites half its width into foe. Open up a terrible wound. Blood goes everywhere.\n+7H 2∑∏ 6∫",
"C": "You follow your training well. You extend on your slashing arc. Strike lands against foe's side.\n+8H 2∑∏ 4∫ (-20)",
"D": "You plunge your weapon into foe's stomach. Major abdomenal wound. Foe is instantly pale from blood loss.\n+10H 4∑ 2∏ 8∫ (-10)",
"E": "Sever opponent's hand. Sad. Foe is down and in shock for 12 rounds, then dies.\n+5H 12∑∏"
},
{
"Score": "86-90",
"A": "Foe turns out and away from your swing. You still catch his side.\n+8H 2∑∏ 2∫ (-10)",
"B": "Strike to back. Foe goes prone trying to avoid your strike. He gets up facing the wrong direction.\n+10H 3∑∏ 3∫",
"C": "Blast to back breaks bone. Foe stumbles forward before falling down. He is having trouble standing.\n+9H 4∑∏ (-10)",
"D": "Your attempt to disarm foe is even more effective. Sever opponent's hand. Foe is in shock for 6 rounds and then dies.\n+6H 6∑∏",
"E": "Meat chopping strike severs foe's leg. Foe drops and lapses in unconsciousness. Foe dies in 9 rounds.\n+15H (+10)"
},
{
"Score": "91-95",
"A": "Blow to foe's head. If no helmet, cut off foe's ear (all hearing ability is halved).\nwith helmet: +3H 2∑∏ w/o helmet: +3H 3∑ 3∫",
"B": "Strike to foe's hip. The blow has little edge, but much impact. Your blow staggers foe. His recovery is slow.\n+7H 3∑ (-20) (+10)",
"C": "Chop the top of foe's thigh. Sever foe's leg. Foe drops immediately and dies in 6 rounds due to shock and blood loss.\n+20H",
"D": "Sever foe's weapon arm and bury your sword into foe's side. Foe falls prone. Foe is in shock for 12 rounds, then dies.\n+15H 9∑∏",
"E": "Sever foe's spine. Foe collapses, paralyzed from the neck down permanently.\n+20H"
},
{
"Score": "96-99",
"A": "The tip of your weapon slashes foe's nose. Minor wound and a permanent scar.\n+2H 6∑ 2∫ (-30)",
"B": "Strike to foe's head breaks skull and causes massive brain damage. Foe drops and dies in 6 rounds.\n+20H",
"C": "You cleave shield and arm in half Foe attempts to catch his falling arm. Foe is in shock for 12 rounds then dies.\n+18H 12∑∏",
"D": "Slash foe's side. Foe dies in 3 rounds due to internal organ damage. Foe is down and unconscious immediately.\n+20H",
"E": "Strike to foe's head destroys brain and makes life difficult for the poor fool. Foe expires in a heap—immediately.\n—"
},
{
"Score": 100,
"A": "Strike severs carotid artery and jugular vein, breaking foe's neck. Foe dies in 6 rounds of agony.\n—",
"B": "Disembowel foe, killing him instantly. 25% chance your weapon is stuck in opponent for 1 round.\n—",
"C": "Strike up, in, and across foe's forehead. Destroy foe's eyes. Foe flips onto his back in pain.\n+5H 30∑∏",
"D": "Impale foe in heart. Foe dies instantly. Heart is destroyed. 25% chance your weapon is stuck in for 2 rounds.\n+12H",
"E": "Very close! Strike to foe's groin area. All vital organs are destroyed immediately. Foe dies after 24 rounds of agony.\n+10H 12∑∏"
}
]

View File

@ -31,6 +31,7 @@ export default class RMFRPWeaponSheet extends ItemSheet {
skills: {},
criticalTables: {},
attackTables: game.rmfrp.attackTables.getTableDef(),
fumbleTables: {},
enrichedDescription: enrichedDescription
}
console.log("Parent", this.object)

View File

@ -1 +1 @@
MANIFEST-000168
MANIFEST-000188

View File

@ -1,8 +1,8 @@
2024/08/23-11:39:46.394926 7fa527e006c0 Recovering log #167
2024/08/23-11:39:46.405233 7fa527e006c0 Delete type=0 #167
2024/08/23-11:39:46.405284 7fa527e006c0 Delete type=3 #166
2024/08/23-11:44:39.425049 7fa525a006c0 Level-0 table #171: started
2024/08/23-11:44:39.425122 7fa525a006c0 Level-0 table #171: 0 bytes OK
2024/08/23-11:44:39.431462 7fa525a006c0 Delete type=0 #169
2024/08/23-11:44:39.441660 7fa525a006c0 Manual compaction at level-0 from '!items!1HevhbCbvMonyQXe' @ 72057594037927935 : 1 .. '!items!yRIFroc5VC9Oj3qY' @ 0 : 0; will stop at (end)
2024/08/23-11:44:39.441685 7fa525a006c0 Manual compaction at level-1 from '!items!1HevhbCbvMonyQXe' @ 72057594037927935 : 1 .. '!items!yRIFroc5VC9Oj3qY' @ 0 : 0; will stop at (end)
2024/10/20-13:37:02.626902 7f6d6fe006c0 Recovering log #186
2024/10/20-13:37:02.677174 7f6d6fe006c0 Delete type=3 #184
2024/10/20-13:37:02.677257 7f6d6fe006c0 Delete type=0 #186
2024/10/20-18:19:58.494225 7f6d6d6006c0 Level-0 table #191: started
2024/10/20-18:19:58.494287 7f6d6d6006c0 Level-0 table #191: 0 bytes OK
2024/10/20-18:19:58.501124 7f6d6d6006c0 Delete type=0 #189
2024/10/20-18:19:58.515079 7f6d6d6006c0 Manual compaction at level-0 from '!items!1HevhbCbvMonyQXe' @ 72057594037927935 : 1 .. '!items!yRIFroc5VC9Oj3qY' @ 0 : 0; will stop at (end)
2024/10/20-18:19:58.530691 7f6d6d6006c0 Manual compaction at level-1 from '!items!1HevhbCbvMonyQXe' @ 72057594037927935 : 1 .. '!items!yRIFroc5VC9Oj3qY' @ 0 : 0; will stop at (end)

View File

@ -1,3 +1,8 @@
2024/08/23-10:14:01.919789 7f67a10006c0 Recovering log #164
2024/08/23-10:14:01.965430 7f67a10006c0 Delete type=3 #162
2024/08/23-10:14:01.965586 7f67a10006c0 Delete type=0 #164
2024/09/17-13:11:02.171459 7fe046a006c0 Recovering log #182
2024/09/17-13:11:02.180765 7fe046a006c0 Delete type=3 #180
2024/09/17-13:11:02.180823 7fe046a006c0 Delete type=0 #182
2024/09/17-13:12:47.967572 7fe045a006c0 Level-0 table #187: started
2024/09/17-13:12:47.967635 7fe045a006c0 Level-0 table #187: 0 bytes OK
2024/09/17-13:12:47.974711 7fe045a006c0 Delete type=0 #185
2024/09/17-13:12:47.987784 7fe045a006c0 Manual compaction at level-0 from '!items!1HevhbCbvMonyQXe' @ 72057594037927935 : 1 .. '!items!yRIFroc5VC9Oj3qY' @ 0 : 0; will stop at (end)
2024/09/17-13:12:47.987823 7fe045a006c0 Manual compaction at level-1 from '!items!1HevhbCbvMonyQXe' @ 72057594037927935 : 1 .. '!items!yRIFroc5VC9Oj3qY' @ 0 : 0; will stop at (end)

View File

@ -1 +1 @@
MANIFEST-000074
MANIFEST-000094

View File

@ -1,8 +1,8 @@
2024/08/23-11:39:46.408879 7fa526a006c0 Recovering log #73
2024/08/23-11:39:46.419408 7fa526a006c0 Delete type=0 #73
2024/08/23-11:39:46.419471 7fa526a006c0 Delete type=3 #72
2024/08/23-11:44:39.417619 7fa525a006c0 Level-0 table #77: started
2024/08/23-11:44:39.417692 7fa525a006c0 Level-0 table #77: 0 bytes OK
2024/08/23-11:44:39.424844 7fa525a006c0 Delete type=0 #75
2024/08/23-11:44:39.441644 7fa525a006c0 Manual compaction at level-0 from '!folders!Lr9SCthdWWHecwEI' @ 72057594037927935 : 1 .. '!items!zvdsAxlRZnL6gqms' @ 0 : 0; will stop at (end)
2024/08/23-11:44:39.453852 7fa525a006c0 Manual compaction at level-1 from '!folders!Lr9SCthdWWHecwEI' @ 72057594037927935 : 1 .. '!items!zvdsAxlRZnL6gqms' @ 0 : 0; will stop at (end)
2024/10/20-13:37:02.691373 7f6d6e0006c0 Recovering log #92
2024/10/20-13:37:02.785568 7f6d6e0006c0 Delete type=3 #90
2024/10/20-13:37:02.785678 7f6d6e0006c0 Delete type=0 #92
2024/10/20-18:19:58.508330 7f6d6d6006c0 Level-0 table #97: started
2024/10/20-18:19:58.508379 7f6d6d6006c0 Level-0 table #97: 0 bytes OK
2024/10/20-18:19:58.514650 7f6d6d6006c0 Delete type=0 #95
2024/10/20-18:19:58.515134 7f6d6d6006c0 Manual compaction at level-0 from '!folders!Lr9SCthdWWHecwEI' @ 72057594037927935 : 1 .. '!items!zvdsAxlRZnL6gqms' @ 0 : 0; will stop at (end)
2024/10/20-18:19:58.530714 7f6d6d6006c0 Manual compaction at level-1 from '!folders!Lr9SCthdWWHecwEI' @ 72057594037927935 : 1 .. '!items!zvdsAxlRZnL6gqms' @ 0 : 0; will stop at (end)

View File

@ -1,3 +1,8 @@
2024/08/23-10:14:01.974311 7f679b4006c0 Recovering log #70
2024/08/23-10:14:02.026991 7f679b4006c0 Delete type=3 #68
2024/08/23-10:14:02.027094 7f679b4006c0 Delete type=0 #70
2024/09/17-13:11:02.184351 7fe047e006c0 Recovering log #88
2024/09/17-13:11:02.193926 7fe047e006c0 Delete type=3 #86
2024/09/17-13:11:02.193975 7fe047e006c0 Delete type=0 #88
2024/09/17-13:12:47.974848 7fe045a006c0 Level-0 table #93: started
2024/09/17-13:12:47.974889 7fe045a006c0 Level-0 table #93: 0 bytes OK
2024/09/17-13:12:47.981263 7fe045a006c0 Delete type=0 #91
2024/09/17-13:12:47.987803 7fe045a006c0 Manual compaction at level-0 from '!folders!Lr9SCthdWWHecwEI' @ 72057594037927935 : 1 .. '!items!zvdsAxlRZnL6gqms' @ 0 : 0; will stop at (end)
2024/09/17-13:12:47.987838 7fe045a006c0 Manual compaction at level-1 from '!folders!Lr9SCthdWWHecwEI' @ 72057594037927935 : 1 .. '!items!zvdsAxlRZnL6gqms' @ 0 : 0; will stop at (end)

View File

@ -49,5 +49,21 @@
"distance": 5,
"units": "ft"
},
"license": "LICENSE.txt"
"license": "LICENSE.txt",
"flags": {
"hotReload": {
"extensions": [
"css",
"hbs",
"html",
"json"
],
"paths": [
"./",
"lang/",
"assets/",
"templates/"
]
}
}
}

View File

@ -74,6 +74,25 @@
</td>
</table>
<table>
<tr>
<th>{{localize "rmfrp.weapon.fumble_value"}}</th>
<th>{{localize "rmfrp.weapon.fumble_table"}}</th>
<th>{{localize "rmfrp.weapon.fumble_column"}}</th>
</tr>
<td>
<input class="short-input" name="system.fumble_value" type="text" value="{{system.fumble_value}}" data-dtype="Number"/>
</td>
<td>
<select class="long-input" name="system.fumble_table" type="text" value="{{system.fumble_table}}" data-dtype="String">
{{selectOptions fumbleTables selected=system.fumble_table nameAttr="key" valueAttr="key" labelAttr="name"}}
</select>
<td>
<input class="short-input" name="system.fumble_column" type="text" value="{{system.fumble_column}}" data-dtype="String"/>
</td>
</td>
</table>
<table>
<tr>
<th>{{localize "rmfrp.weapon.critical_table"}}</th>