-
December 1st, 2018, 20:14 #1
Advanced Bestiary NPC Factory for 3.5
Hello everyone,
I am having trouble using the NPC factory for 3.5 creatures. I just can't seem to figure out the correct format for importing monster data. I have searched for days now. Granted, I'm not the best at using advanced search functions, but I have tried my best.
Literally, everything I come across is for Pathfinder and the PF format. I bought the Advanced Bestiary because it specifically states compatibility with 3.5 and not just Pathfinder. I guess I wouldn't ask for a refund, because the template tool is also handy, but not having this functionality detracts from the value to a significant degree. It's 80% of the reason I bought it. I feel like it's something simple and I'm just missing it. Is there an example of D&D 3.5 NPC format necessary for the import function to work? (again, i only ever see PF examples and that doesn't work w/o so much editing I might as well type everything in by hand anyway).
I tried searching for a thread addressing this. This has to have been addressed before, but I can't find it.
Thank you.
-
December 2nd, 2018, 15:28 #2
Use the Paizo statblock format. Info here: https://legacy.aonprd.com/bestiary/introduction.html
Also see the video on the product page for some guidelines: https://www.fantasygrounds.com/store...hp?id=GRR2901ePrivate Messages: My inbox is forever filling up with PMs. Please don't send me PMs unless they are actually private/personal messages. General FG questions should be asked in the forums - don't be afraid, the FG community don't bite and you're giving everyone the chance to respond and learn!
-
December 2nd, 2018, 16:07 #3
It looks like this one was a little light on the documentation for the statblock importer. It was tested with statblocks I could find at the time for 3.5E and Pathfinder, but I remember there being some finicky bits. Do you have a sample stat block you are trying to do?
During the 3.5E era, it was hard to find any two companies or sites that did them the same.
From this page: https://mikael.borjesson.net/dnd/mon...l,+Astral+Deva
ORIGINAL:
Code:Angel, Astral Deva CR 14 Always good (any) Medium Outsider (Angel, Extraplanar, Good) Init +8; Senses darkvision 60 ft., low-light vision; Listen +23, Spot +23 Languages Celestal, Infernal, Draconic; tongues AC 29, touch 14, flat-footed 25; protective aura, uncanny dodge (+4 Dex, +15 natural) hp 102 (12 HD); DR 10/evil Immune acid, cold, petrification Resist electricity 10, fire 10; SR 30 Fort +14 (+18 against poison), Ref +12, Will +12 Speed 50 ft., fly 100 ft. (good) Melee +3 heavy mace of disruption +21/+16/+11 (1d8+12 plus stun); or Melee Slam +18 (1d8+9) Space 5 ft.; Reach 5 ft. Base Atk +12; Grp +18 Atk Options Cleave, Power Attack Special Actions change shape Spell-like Abilities (CL 12): At will—aid, continual flame, detect evil, discern lies (DC 19), dispel evil (DC 20), dispel magic, holy aura (DC 23), holy smite (DC 19), holy word (DC 22), invisibility (self only), plane shift (DC 22), remove curse (DC 18), remove disease (DC 18), remove fear (DC 16) 7/day—cure light wounds (DC 16), see invisibility 1/day—blade barrier (DC 21), heal (DC 21) The save DCs are Charisma-based Abilities Str 22, Dex 18, Con 18, Int 18, Wis 18, Cha 20 Feats Alertness, Cleave, Great Fortitude, Improved Initiative, Power Attack Skills Concentration +19, Craft or Knowledge (any three) +19, Diplomacy +22, Escape Artist +19, Hide +19, Intimidate +20, Listen +23, Move Silently +19, Sense Motive +19, Spot +23, Use Rope +4 (+6 with bindings) Advancement 13-18 HD (Medium); 19-36 HD (Large) Level adjustment +8 Stun (Su) If an astral deva strikes an opponent twice in one round with its mace, that creature must succeed on a DC 22 Fortitude save or be stunned for 1d6 rounds. The save DC is Strength-based. Uncanny Dodge (Ex) An astral deva retains its Dexterity bonus to AC when flat-footed, and it cannot be flanked except by a rogue of at least 16th level. It can flank characters with the uncanny dodge ability as if it were a 12th-level rogue. Change Shape (Su) An astral deva can assume the form of any Small or Medium humanoid.
Code:Angel, Astral Deva CR 14 LG Medium Outsider (Angel, Extraplanar, Good) Init +8; Senses darkvision 60 ft., low-light vision; Listen +23, Spot +23 Languages Celestal, Infernal, Draconic; tongues AC 29, touch 14, flat-footed 25; protective aura, uncanny dodge (+4 Dex, +15 natural) hp 102 (12 HD); DR 10/evil Immune acid, cold, petrification; Resist electricity 10, fire 10; SR 30; OFFENSE Fort +14 (+18 against poison), Ref +12, Will +12 Speed 50 ft., fly 100 ft. (good) Melee +3 heavy mace of disruption +21/+16/+11 (1d8+12 plus stun); or Melee Slam +18 (1d8+9) Space 5 ft.; Reach 5 ft. Base Atk +12; Grp +18 Special Attacks Cleave, Power Attack, Change Shape. Spell-like Abilities (CL 12): At will—aid, continual flame, detect evil, discern lies (DC 19), dispel evil (DC 20), dispel magic, holy aura (DC 23), holy smite (DC 19), holy word (DC 22), invisibility (self only), plane shift (DC 22), remove curse (DC 18), remove disease (DC 18), remove fear (DC 16);7/day—cure light wounds (DC 16), see invisibility;1/day—blade barrier (DC 21), heal (DC 21) The save DCs are Charisma-based STATISTICS Abilities Str 22, Dex 18, Con 18, Int 18, Wis 18, Cha 20 Feats Alertness, Cleave, Great Fortitude, Improved Initiative, Power Attack Skills Concentration +19, Craft or Knowledge (any three) +19, Diplomacy +22, Escape Artist +19, Hide +19, Intimidate +20, Listen +23, Move Silently +19, Sense Motive +19, Spot +23, Use Rope +4 (+6 with bindings). Advancement 13-18 HD (Medium); 19-36 HD (Large) Level Adjustment: +8 Stun (Su) If an astral deva strikes an opponent twice in one round with its mace, that creature must succeed on a DC 22 Fortitude save or be stunned for 1d6 rounds. The save DC is Strength-based. Uncanny Dodge (Ex) An astral deva retains its Dexterity bonus to AC when flat-footed, and it cannot be flanked except by a rogue of at least 16th level. It can flank characters with the uncanny dodge ability as if it were a 12th-level rogue. Change Shape (Su) An astral deva can assume the form of any Small or Medium humanoid.
- For the type, it looks for alignment to be one of the standard values like LG, CG, LE, etc. and then grabs the type from the rest of that line.
- Put CR on a new line
- Special Actions should actually be Special Attacks: {whatever}
- After the Special Attacks, there should be a section called STATISTICS just before the abilities start. That tells the parser to grab everything between for the SA section
- You can add an OFFENSE tag as well, just before the saves
- If it is picking up "extra" stuff for certain fields, you can often control this by appending a ; or a . at the end of a line.
The new NPC should be added to the NPCs window under the New group heading.
-
December 2nd, 2018, 16:13 #4
Here is the extension for this. It has an ext extension that you can unzip into a folder in your extensions folder and then modify from there. The script with the statblock importer is found in the template_npc_factory_build_npc_rom_statblock.lua file.
Here is the relative code for the parsing routine:
PART 1:
Code:function onButtonPress() local templateFactory = DB.findNode("template_npc_factory_data"); strStatblock = DB.getText(templateFactory,"statblock",""); ABUtility.Trace(strStatblock); wndNPCs = Interface.openWindow("masterindex","npc"); wndNPCs.setRecordType("npc"); local nodeNPC = DB.createChild("npc"); --ABUtility.update(nodeNPC,"name","New NPC"); -- Name and CR _,_,sName,sCR = string.find(strStatblock,"^(.-)%s*%(*CR*%s*(%d+)%)*"); if sName == nil then _,_,sName = string.find(strStatblock,"^(.-)%s*[:;\n]+"); end setNodeValue(nodeNPC,"name",stripCRLF(sName),"string","New NPC"); setNodeValue(nodeNPC,"cr",sCR,"number",0); -- Abilities _,_,sSTR = string.find(strStatblock,"[sS][tT][rR]:?%s*(%d+),*%s*"); _,_,sDEX = string.find(strStatblock,"[dD][eE][xX]:?%s*(%d+),*%s*"); _,_,sCON = string.find(strStatblock,"[cC][oO][nN]:?%s*(%d+),*%s*"); _,_,sWIS = string.find(strStatblock,"[wW][iI][sS]:?%s*(%d+),*%s*"); _,_,sINT = string.find(strStatblock,"[iI][nN][tT]:?%s*(%d+),*%s*"); _,_,sCHA = string.find(strStatblock,"[cC][hH][aA]:?%s*(%d+),*%s*"); setNodeValue(nodeNPC,"strength",sSTR,"number",0); setNodeValue(nodeNPC,"dexterity",sDEX,"number",0); setNodeValue(nodeNPC,"constitution",sCON,"number",0); setNodeValue(nodeNPC,"wisdom",sWIS,"number",0); setNodeValue(nodeNPC,"intelligence",sINT,"number",0); setNodeValue(nodeNPC,"charisma",sCHA,"number",0); -- AC, HP and HD _,_,sAC1,sAC2,sHP,sHD = string.find(strStatblock,"[aA][cC]:?%s*(%d+)(.-)%s*[hH][pP]:?%s*(%d+)%s*%((.-)%)%s*[fF][oO][rR][tT]"); if sAC1 == nil then _,_,sAC1,sAC2 = string.find(strStatblock,"[aA][cC]:?%s*(%d+)%s*(.-)[.;\n]"); end if sAC1 == nil then -- look for armor class spelled out _,_,sAC1,sAC2 = string.find(strStatblock,"[aA][rR][mM][oO][rR]%s*[cC][lL][aA][sS][sS]:?%s*(%d+)%s*(.-);"); end if sAC1 == nil then sAC1 = 10; sAC2 = ""; end if sHP == nil then _,_,sHP,sHD = string.find(strStatblock,"[hH][pP]:?%s*(%d+)%s*%((.-)%);?%s*"); end if sHP == nil then -- look for older hit point style 2d8+2 (11 hp) _,_,sHP = string.find(strStatblock,"%((%d+) [hH][pP]"); end if sHD == nil then _,_,sHD = string.find(strStatblock,"[hH][dD]:?%s*(.-)%s*;"); _,_,sHD2 = string.find(strStatblock,"[hH][iI][tT]%s*[dD][iI][cC][eE]:?%s*(.-)%s*;"); sHD = getSmallest(sHD,sHD2); end setNodeValue(nodeNPC,"hp",sHP,"number",0); setNodeValue(nodeNPC,"ac",stripCRLF(sAC1 .. sAC2), "string","0"); setNodeValue(nodeNPC,"hd",stripCRLF(sHD), "string", "0"); -- Saves _,_,sFort = string.find(strStatblock,"[fF][oO][rR][tT]:?%s*%+%s*(%d+)"); _,_,sRef = string.find(strStatblock,"[rR][eE][fF]:?%s*%+%s*(%d+)"); _,_,sWill = string.find(strStatblock,"[wW][iI][lL][lL]:?%s*%+%s*(%d+)"); setNodeValue(nodeNPC,"fortitudesave",sFort,"number",0); setNodeValue(nodeNPC,"reflexsave",sRef,"number",0); setNodeValue(nodeNPC,"willsave",sWill,"number",0); -- Senses _,_,sSenses = string.find(strStatblock,"[sS][eE][nN][sS][eE][sS]:?%s*(.-)%s*[aAdD][uUeE][rRfF][aAeE]"); _,_,sSenses2 = string.find(strStatblock,"[dD][eE][tT][eE][cC][tT][iI][oO][nN]%s*:?%-?%s*(.-)%s*[.;\n]"); sSenses = getSmallest(sSenses,sSenses2); setNodeValue(nodeNPC,"senses",stripCRLF(sSenses),"string",""); -- Initiative _,_,sInit = string.find(strStatblock,"[iI][nN][iI][tT]:?%s*%+?%-?(%d+)"); setNodeValue(nodeNPC,"init",sInit,"number",0); -- Space / Reach _,_,sSpace = string.find(strStatblock,"[sS][pP][aA][cC][eE]:?%s*(%d+)%s?[fF][tT]"); _,_,sReach = string.find(strStatblock,"[rR][eE][aA][cC][hH]:?%s*(%d+)%s?[fF][tT]"); if sSpace then if sReach then sSpaceReach = sSpace .. " ft./" .. sReach .. " ft."; end end setNodeValue(nodeNPC,"spacereach",sSpaceReach,"string","5 ft./5 ft."); -- Attack -- Replace cases like Crossbow, Heavy and Crossbow, Light in attack strings. strStatblock = string.gsub(strStatblock,"%s+[oO][rR]%s*[\n]%s*"," or "); strStatblock = string.gsub(strStatblock,"%s+[aA][nN][dD]%s*[\n]%s*"," and "); strStatblock = string.gsub(strStatblock, "(%w+),%s?[hH][eE][aA][vV][yY]","Heavy %1"); strStatblock = string.gsub(strStatblock, "(%w+),%s?[lL][iI][gG][hH][tT]","Light %1"); ABUtility.Trace(strStatblock); _,_,sAtk = string.find(strStatblock,"[mM][eE][lL][eE][eE]:?%s*(.-)%s*[sStT][aApP][aAcCeE][cCtT][eEiI]"); _,_,sAtk2 = string.find(strStatblock,"[aA][tT][tT][aA][cC][kK]:+%s*(.-)%s*;"); sAtk = getSmallest(sAtk,sAtk2); if sAtk then sAtk = string.gsub(sAtk,"\n[rR][aA][nN][gG][eE][dD]"," or Ranged"); --sAtk = ABUtility.stringReplace(sAtk,")%s*ranged"," or"); end if sAtk == nil then _,_,sAtk = string.find(strStatblock,"[mM][eE][lL][eE][eE]%s*(.-)%s*[sS][pP][aAeE][cC][eEiI]"); end if sAtk == nil then _,_,sAtk = string.find(strStatblock,"[mMrR][eEaA][lLnN][eEgG][eEeE][dD]*%s*(.-)%s*[.;]"); end setNodeValue(nodeNPC,"atk",ABUtility.stringReplace(stripCRLF(sAtk),","," or "),"string",""); setNodeValue(nodeNPC,"fullatk",ABUtility.stringReplace(stripCRLF(sAtk),","," and "),"string",""); -- Aura (may be missing from many statblocks _,_,sAura = string.find(strStatblock,"[aA][uU][rR][aA]:?%s+(.-)[)]"); if sAura then sAura = sAura .. ")"; end if sAura == nil then _,_,sAura = string.find(strStatblock,"[aA][uU][rR][aA]:?%s+(.-);"); end setNodeValue(nodeNPC,"aura",stripCRLF(sAura),"string",""); -- Speed _,_,sSpeed = string.find(strStatblock,"[sS][pP][eE]*[eE]*[dD]:?%s*(.-)%s*;?%s*[mMrR][eEaA][lLnN][eEgG][eE]"); _,_,sSpeed2 = string.find(strStatblock,"[sS][pP][eE]*[eE]*[dD]:?%s*(.-)%s*;"); sSpeed = getSmallest(sSpeed,sSpeed2); setNodeValue(nodeNPC,"speed",stripCRLF(sSpeed),"string",""); -- BAB, CM and CMD _,_,sBAB = string.find(strStatblock,"[bB][aA][sS][eE] [aA][tT][kK]:?%s*%+?(%d+);+%s*"); _,_,sCM = string.find(strStatblock,"[cC][mM][bB]:?%s*%+?(%d+);?%s*"); _,_,sCMD = string.find(strStatblock,"[cC][mM][dD]:?%s*%+?(.-)%s*[sSfF][kKeE][iIaA][lLtT]"); if sBAB then sBABCMD = "+" .. sBAB; else sBABCMD = "-"; end if sCM then sBABCMD = sBABCMD .. "/+" .. sCM .. "; "; else sBABCMD = sBABCMD .. "/-; "; end if sCMD then sBABCMD = sBABCMD .. "CMD " .. sCMD; end setNodeValue(nodeNPC,"babgrp",sBABCMD,"string",""); -- Feats _,_,sFeats = string.find(strStatblock,"[fF][eE][aA][tT][sS]:?%s*(.-)%s*[eEsS][cCkK][oOiI][lL][oOlL][gGsS]:?"); _,_,sFeats2 = string.find(strStatblock,"[fF][eE][aA][tT][sS]:?%s*(.-)%s*;%s*"); if sFeats2 then sFeats = getSmallest(sFeats, sFeats2); end setNodeValue(nodeNPC,"feats",stripCRLF(sFeats),"string",""); -- Skills _,_,sSkills = string.find(strStatblock,"[sS][kK][iI][lL][lL][sS]:?(.-)%s*[lL][aA][nN][gG][uU][aA][gG][eE][sS]"); if sSkills then setNodeValue(nodeNPC,"skills",stripCRLF(sSkills),"string",""); else _,_,sSkills = string.find(strStatblock,"[sS][kK][iI][lL][lL][sS]:?(.-)[sS][qQ]:?%s+"); end _,_,sSkills2 = string.find(strStatblock,"[sS][kK][iI][lL][lL][sS]:?(.-)%s*;%s*"); if sSkills2 then sSkills = getSmallest(sSkills,sSkills2); end _,_,sSkills2 = string.find(strStatblock,"[sS][kK][iI][lL][lL][sS]:?(.-)[pP][oO][sS][sS][eE][sS][iI][oO][nN]"); if sSkills2 then sSkills = getSmallest(sSkills, sSkills2); end if sSkills then setNodeValue(nodeNPC,"skills",stripCRLF(sSkills),"string",""); end
-
December 2nd, 2018, 16:13 #5
Part 2:
Code:-- SQ _,_,sSQ1 = string.find(strStatblock,"SQ:?%s*(.-)%s*[gG][eE][aA][rR]:?%s*"); _,_,sSQ2 = string.find(strStatblock,"SQ:?%s*(.-)%s*[eE][cC][oO][lL][oO][gG][yY]"); _,_,sSQ3 = string.find(strStatblock,"SQ:?%s*(.-)%s*[sS][pP][eE][cC][iI][aA][lL] [aA][bB][iI][lL][iI][tT][iI][eE][sS]"); _,_,sSQ4 = string.find(strStatblock,"SQ:?%s*(.-)%s*[oO][fF][fF][eE][nN][sS][eE]"); sSQ = getSmallest(sSQ1, sSQ2); sSQ = getSmallest(sSQ, sSQ3); sSQ = getSmallest(sSQ, sSQ4); _,_,sSQ4 = string.find(strStatblock,"SQ:?%s*(.-)%s*;"); sSQ = getSmallest(sSQ, sSQ4); if sSQ then sSQ = sSQ .. "; "; end setNodeValue(nodeNPC,"specialqualities",sSQ,"string",""); _,_,sSA = string.find(strStatblock,"[sS][pP][eE][cC][iI][aA][lL] [aA][tT][tT][aA][cC][kK][sS]:?%s*(.-)%s*[sS][tT][aA][tT][iI][sS][tT][iI][cC][sS]"); setNodeValue(nodeNPC,"specialattacks",sSA,"string",""); -- Languages _,_,sLanguages = string.find(strStatblock,"[lL][aA][nN][gG][uU][aA][gG][eE][sS]*:?%s*(.-)[;.]"); _,_,sLanguages2 = string.find(strStatblock,"[lL][aA][nN][gG][uU][aA][gG][eE][sS]*:?%s*(.-)%s*SQ"); sLanguages = getSmallest(sLanguages,sLanguages2); _,_,sLanguages2 = string.find(strStatblock,"[lL][aA][nN][gG][uU][aA][gG][eE][sS]*:?%s*(.-)%s*[dD][eE][fF][eE][nN][sS][eE]"); if sLanguages2 then sLanguages = getSmallest(sLanguage,sLanguages2); end setNodeValue(nodeNPC,"languages",stripCRLF(sLanguages),"string",""); -- Environment _,_,sEnv = string.find(strStatblock,"[eE][nN][vV][iI][rR][oO][nN][mM][eE][nN][tT]:?%s*(.-)%s*[oO][rR][gG][aA][nN][iI][zZ][aA][tT][iI][oO][nN]"); if not sEnv then _,_,sEnv = string.find(strStatblock,"[eE][nN][vV][iI][rR][oO][nN][mM][eE][nN][tT]:?%s*(.-)[.;]"); end _,_,sEnv2 = string.find(strStatblock,"[eE][nN][vV][iI][rR][oO][nN][mM]?[eE]?[nN]?[tT]?:?%s*(.-)%s*;"); sEnv = getSmallest(sEnv,sEnv2); setNodeValue(nodeNPC,"environment",stripCRLF(sEnv),"string",""); -- Organization _,_,sOrg = string.find(strStatblock,"[oO][rR][gG][aA][nN][iI][zZ][aA][tT][iI][oO][nN]:?%s*(.-)%s*[tT][rR][eE][aA][sS][uU][rR][eE]"); if not sOrg then _,_,sOrg = string.find(strStatblock,"[oO][rR][gG][aA][nN][iI][zZ][aA][tT][iI][oO][nN]:?%s*(.-)[.;]"); end _,_,sOrg2 = string.find(strStatblock,"[oO][rR][gG][aA][nN][iI][zZ][aA][tT][iI][oO][nN]:?%s*(.-)%s*;"); if sOrg2 then sOrg = getSmallest(sOrg,sOrg2); end setNodeValue(nodeNPC,"organization",stripCRLF(sOrg),"string",""); -- Treasure _,_,sTreasure = string.find(strStatblock,"[tT][rR][eE][aA][sS][uU][rR][eE]:?%s*(.-)[.;]"); _,_,sTreasure2 = string.find(strStatblock,"[tT][rR][eE][aA][sS][uU][rR][eE]:?%s*(.-)$"); _,_,sTreasure3 = string.find(strStatblock,"[tT][rR][eE][aA][sS][uU][rR][eE]:?%s*(.-)%s*[sS][pP][eE][cC][iI][aA][lL] [aA][bB]"); sTreasure = getSmallest(sTreasure,sTreasure2); sTreasure = getSmallest(sTreasure,sTreasure3); if sTreasure == nil then _,_,sTreasure = string.find(strStatblock,"[pP][oO][sS][sS][eE][sS][sS][iI][oO][nN][sS]:?%s*(.-)[.;]"); _,_,sTreasure2 = string.find(strStatblock,"[pP][oO][sS][sS][eE][sS][sS][iI][oO][nN][sS]:?%s*(.-)$"); sTreasure = getSmallest(sTreasure,sTreasure2); end if sTreasure == nil then _,_,sTreasure = string.find(strStatblock,"[gG][eE][aA][rR]:?%s*(.-)[.;]"); _,_,sTreasure2 = string.find(strStatblock,"[gG][eE][aA][rR]:?%s*(.-)$"); sTreasure = getSmallest(sTreasure,sTreasure2); _,_,sTreasure2 = string.find(strStatblock,"[gG][eE][aA][rR]:?%s*(.-)[sS][pP][eE][cC][iI][aA][lL] [aA][bB][iI][lL]"); sTreasure = getSmallest(sTreasure,sTreasure2); end setNodeValue(nodeNPC,"treasure",stripCRLF(sTreasure),"string",""); -- DR, Immune, Resist, SR, Weakness -- Immunities _,_,sImmune = string.find(strStatblock,"[iI][mM][mM][uU][nN][eE]:?%s*(.-)[.;\n]"); _,_,sImmune2 = string.find(strStatblock,"[iI][mM][mM][uU][nN][eE]:?%s*(.-)%s*[oO][fF][eE][nN][sS][eE]"); sImmune = getSmallest(sImmune,sImmune2); if sImmune then sImmune = " Immune " .. sImmune .. "; "; end appendNodeValue(nodeNPC,"specialqualities",stripCRLF(sImmune)); -- Resistances _,_,sResist = string.find(strStatblock,"[rR][eE][sS][iI][sS][tT]:?%s*(.-)[.;]"); _,_,sResist2 = string.find(strStatblock,"[rR][eE][sS][iI][sS][tT]:?%s*(.-)%s*[oO][fF][eE][nN][sS][eE]"); sResist = getSmallest(sResist,sResist2); if sResist then sResist = " Resist " .. sResist .. "; "; end appendNodeValue(nodeNPC,"specialqualities",stripCRLF(sResist)); -- Weaknesses _,_,sWeak = string.find(strStatblock,"[wW][eE][aA][kK][nN][eE][sS][sS][eE]?[sS]?:?%s*(.-)[.;]"); _,_,sWeak2 = string.find(strStatblock,"[wW][eE][aA][kK][nN][eE][sS][sS][eE]?[sS]?:?%s*(.-)%s*[oO][fF][eE][nN][sS][eE]"); sWeak = getSmallest(sWeak,sWeak2); if sWeak then sWeak = " Weakness " .. sWeak .. "; "; end appendNodeValue(nodeNPC,"specialqualities",stripCRLF(sWeak)); -- DR _,_,sDR = string.find(strStatblock,"DR:?%s*(.-)[.;]"); _,_,sDR2 = string.find(strStatblock,"DR:?%s*(.-)%s*[oO][fF][eE][nN][sS][eE]"); sDR = getSmallest(sDR,sDR2); if sDR then sDR = " DR " .. sDR .. "; "; end appendNodeValue(nodeNPC,"specialqualities",stripCRLF(sDR)); -- SR _,_,sSR = string.find(strStatblock,"SR:?%s*(.-)[.;]"); _,_,sSR2 = string.find(strStatblock,"SR:?%s*(.-)%s*[oO][fF][eE][nN][sS][eE]"); sSR = getSmallest(sSR,sSR2); if sSR then sSR = " SR " .. sSR .. "; "; end appendNodeValue(nodeNPC,"specialqualities",stripCRLF(sSR)); -- Type _,_,sAlignment,sType = string.find(strStatblock,"%s+([LCN][EGN ])%s*(.-)%s*[dDiI][eEnN][fFiItT][eEtT]"); _,_,sName2,sType2 = string.find(strStatblock,"^(.-)%s*[:](.-);"); sType = getSmallest(sType,sType2); if sAlignment and sType then sType = sAlignment .. " " .. sType; end setNodeValue(nodeNPC,"type",stripCRLF(sType),"string",""); setNodeValue(nodeNPC,"alignment",sAlignment,"string",""); -- Description strStatblock = DB.getValue(templateFactory,"statblock",""); if strStatblock then strStatblock = "<linklist><link class=\"\" recordname=\"\">Image</link></linklist>" .. strStatblock; end setNodeValue(nodeNPC,"text",strStatblock,"formattedtext","<p></p>"); -- Token set to defaul letter of first character in name if sName then _,_,sLetter = string.find(sName,"^(%a)"); if sLetter then sLetter = "tokens/Medium/" .. sLetter .. ".png@Letter Tokens"; setNodeValue(nodeNPC,"token",sLetter,"token",""); end end end
-
December 2nd, 2018, 16:48 #6
Yeah, that's clearly the thought process I see throughout the site. I just don't want to use the PF format. I was hoping it was just a minor alteration, but putting 3.5 into PF format takes slightly longer than it does for me to enter stats by hand. Maybe I type faster than I can highlight, cut, paste, cleanup. Idk, but it's negative value for me to try and convert to PF overall.
So I gave up and started altering a pathfinder import tool. Which is kinda hard, because idk enough about programming in any language. I just barely grasp the entry-level concepts. So I can walk, but I'm blind and deaf. But I'm grabbing 80% of everything (which is nice since i started at 0%) and making steady progress.
Damned's videos should be stickied just about everywhere. By far the best resource I've come across in my search for diy FG problem solving.
I also watched those videos you linked, it's just putting PF creatures into a PF import tool. Which is not what I'm trying to do. Unless someone made a tool to format it correctly form 3.5. Then maybe, as long as the end result is 3.5 format and not PF. There was one part in a third video (I think, I'm very tired) not shown on the product page, but buried on their YT channel, where he struggled with a 3.5 stat block. I can only assume that path was abandoned as the feature is not very usable in the 3.5 ruleset as is. Just a little disappointed that it says 3.5 compatible, but only if you convert everything to PF. Which isn't really 3.5. The templates were still worth the purchase imo. Just a slight bummer is all.
Frankencoding will only get me so far I'm sure.
-
December 2nd, 2018, 16:50 #7
-
December 2nd, 2018, 17:17 #8
[QUOTE=ddavison;416556]It looks like this one was a little light on the documentation for the statblock importer. It was tested with statblocks I could find at the time for 3.5E and Pathfinder, but I remember there being some finicky bits. Do you have a sample stat block you are trying to do?
During the 3.5E era, it was hard to find any two companies or sites that did them the same.
From this page: https://mikael.borjesson.net/dnd/mon...l,+Astral+Deva
I see what you mean, that would make it very difficult. I never thought of all the other products out there. I stayed very close to just the wizards products and didn't notice any variations in stat blocks. Never had anything like FG before though, so wasn't paying attention either. I love this tool, I just want to understand it better =] (again, damned's videos are incredible.)
-
December 2nd, 2018, 18:26 #9
Do you have a link to the stat blocks you are trying to import? It might be a common thing that they are doing that could be accounted for with a few quick changes.
-
December 2nd, 2018, 20:17 #10
I don't have a link but it's the standard mm format and most of the core rules format. I think oozes are safe and not copyrighted (I hope?). This one comes from the planar Handbook.
VOID OOZE
Large Ooze (Extraplanar)
Hit Dice: 10d10+80 (135 hp)
Initiative: –5
Speed: Fly 30 ft. (6 squares) (perfect)
Armor Class: 4 (–5 Dex, –1 size), touch 4, flat-footed 4
Base Attack/Grapple: +7/+16
Attack: Slam +11 melee (2d4+5 plus 1d8 negative energy
plus energy drain)
Full Attack: Slam +11 melee (2d4+5 plus 1d8 negative
energy plus energy drain)
Space/Reach: 10 ft./5 ft.
Special Attacks: Energy drain, engulf
Special Qualities: Blindsight 60 ft., death ward, ooze traits,
shadow shield, split
Saves: Fort +11, Ref +0, Will +0
Abilities: Str 20, Dex 1, Con 26, Int —, Wis 1, Cha 1
Skills: —
Feats: —
Environment: Negative Energy Plane
Organization: Solitary, midnight (2–7)
Challenge Rating: 8
Treasure: None
Alignment: Always neutral
Advancement: —
Level Adjustment: —
I have noticed what you mean that even within wizards own publications they vary a bit from this, but this is the format I see the most. Some other (I assume later publications) seem like they would fit with only a few tweaks like you mention. Some look almost exactly like PF format. I never knew there was such variance. TBH I'm going to put myself through the gauntlet and alter the NPC sheet a tiny bit, so I'm probably going to use your posts to guide me on making my own thing. But I have already learned a lot by hacking up cgen. Which I hope is ok. So I'm going to hack up those functions you pointed out and see what kind of abomination I can come up with. To handle importing that standard mm style statblock.
Thread Information
Users Browsing this Thread
There are currently 1 users browsing this thread. (0 members and 1 guests)
Bookmarks