From d588af2a8b7d68d089acc27f49c6f3b8a2c9f4ef Mon Sep 17 00:00:00 2001 From: Michael Hansen Date: Sun, 28 Jul 2019 16:36:52 -0700 Subject: [PATCH] new traits + attribute questions pdf --- CHANGELOG.md | 11 ++-- src/app.rb | 2 +- src/data/bauerbodoni.ttf | Bin 0 -> 64652 bytes src/lib/data.rb | 3 + src/lib/pdf.rb | 103 ++++++++++++++++++++++++++++++- src/public/js/server_settings.js | 2 +- 6 files changed, 113 insertions(+), 8 deletions(-) create mode 100644 src/data/bauerbodoni.ttf diff --git a/CHANGELOG.md b/CHANGELOG.md index cf343a2..213aee3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,17 +5,20 @@ The format is based on [Keep a Changelog](changelog), and this project adheres to [Semantic Versioning](semver). ## [Unreleased] -- Add emotional attributes to the PDF -- Add a page to the pdf for Health + Steel questions -- Add a page to the pdf for trait descriptions +- Add Great Spiders - Add weapon info to the pdf based on some educated guesses (e.g. do you have the arms resource and the Spear skill?) - Write a guide on creating your own JSON data files - Custom upload for your own data files - Updates to Roden and Great Wolves files (currently the data comes from Monster Burner and not Codex) -## [2.2.1] - 2019-07-28 +## [2.3.0] - 2019-07-28 +### Added +- Display emotional attribute traits on PDF +- Append a page to the PDF with trait descriptions and attribute questions + ### Fixed - Wizard's Apprentice should count as Neophyte Sorcerer, and Junior Student counts as Arcane Devotee and Neophyte Sorcerer (thanks StubbsPKS!) +- Alphabetize skill and trait dropdown lists ## [2.2.0] - 2019-07-14 ### Added diff --git a/src/app.rb b/src/app.rb index 3eee175..ec82f7b 100644 --- a/src/app.rb +++ b/src/app.rb @@ -104,7 +104,7 @@ get '/get_file' do data = CACHE.delete(params['file']) if data cs = CharSheet.new(data) - data = cs.render(logger) + data = cs.render(logger, DATA) end else content_type 'application/octet-stream' diff --git a/src/data/bauerbodoni.ttf b/src/data/bauerbodoni.ttf new file mode 100644 index 0000000000000000000000000000000000000000..418b8deb48d24f4f80faa4cba3cefd07f1269af6 GIT binary patch literal 64652 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 [x+xs, y+ys], :size => @t2 end - def render(logger) + def render_trait(pdf, name, trait) + trait_type = { + "die" => "Die", + "call_on" => "Call-on", + "character" => "Character" + }[trait["type"]] + + trait_desc = trait["desc"] + + pdf.font @mediaeval + pdf.text "#{name}", :size => @t2 + pdf.move_down 5 + + pdf.font @bauerbodoni + pdf.text "#{trait_type}", :size => @t3b + + if trait_desc + pdf.move_down 5 + pdf.text "#{trait["desc"]}", :width => 200, :size => @t2b + end + + pdf.move_down 10 + end + + def render_questions(pdf, name, questions) + pdf.font @mediaeval + pdf.text "#{name}", :size => @t2 + + pdf.font @bauerbodoni + questions.each do |q| + pdf.move_down 5 + yes = q["answer"] + pdf.text "#{q["question"]} #{yes ? "Yes." : "No."}", :size => @t2b + end + + pdf.move_down 10 + end + + def render(logger, data) pdf = Prawn::Document.new(:template => 'data/gold.pdf') - pdf.font 'data/caliban.ttf' + pdf.font @caliban pdf.default_leading -4 # logger.info @character @@ -123,6 +166,23 @@ class CharSheet self.render_shade_exponent(pdf, ref_attr[0], ref_attr[1], [279, 396.5]) self.render_shade_exponent(pdf, mor_attr[0], mor_attr[1], [278.5, 346]) + emo_name = '' + emo_attr = nil + + ['Spite', 'Grief', 'Greed', 'Faith', 'Hatred', 'Ancestral Taint'].each do |emo| + if not @character['attributes'][emo.downcase].nil? + emo_name = emo + emo_attr = @character['attributes'][emo.downcase] + emo_name = 'Taint' if emo_name == 'Ancestral Taint' # two words is too big + break + end + end + + if not emo_attr.nil? + pdf.draw_text emo_name, :at => [127, 398], :size => @t2 + self.render_shade_exponent(pdf, emo_attr[0], emo_attr[1], [164.5, 398.3]) + end + ptgs = @character['ptgs'] ["Su", "Li", "Mi", "Se", "Tr", "Mo"].each do |tol| tol_c = ptgs[tol.downcase] @@ -147,6 +207,45 @@ class CharSheet end end + options = { + :page_layout => :landscape, + :margin => 0 + } + + pdf.start_new_page(:layout => :landscape, :margin => 36) + pdf.default_leading = 0 + + pdf.column_box([0, pdf.cursor], :columns => 3, :width => pdf.bounds.width) do + pdf.font @mediaeval + pdf.text "Traits", :size => @t1 + pdf.move_down 10 + + trait_list = @character['traits'].sort { |a, b| a <=> b } + trait_list.each_with_index do |t, i| + name = t[0] + trait = DATA[:traits][name] + + if trait.nil? + trait = { + "type" => "character" + } + end + + self.render_trait(pdf, name, trait) + end + + pdf.move_down 10 + pdf.font @mediaeval + pdf.text "Attribute Questions", :size => @t1 + pdf.move_down 10 + + attr_mods = @character['attr_mod_questions'] + + attr_mods.each do |name, questions| + self.render_questions(pdf, name, questions) + end + end + pdf.render end end diff --git a/src/public/js/server_settings.js b/src/public/js/server_settings.js index d8fa9c8..cd41c5b 100644 --- a/src/public/js/server_settings.js +++ b/src/public/js/server_settings.js @@ -1,5 +1,5 @@ var serverSettings = { - 'versionString' : '2.2.1', + 'versionString' : '2.3.0', 'storageType' : 'client', 'displayAttrMath' : 'false' }