From b6f48e088a3fa251e881a21ef8e8c92c1861fc66 Mon Sep 17 00:00:00 2001 From: warmist Date: Sat, 25 Jul 2015 15:16:30 +0300 Subject: [PATCH 1/5] Create gm-unit.lua A gui util to (eventually) user friendly edit any unit. --- scripts/gui/gm-unit.lua | 170 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 scripts/gui/gm-unit.lua diff --git a/scripts/gui/gm-unit.lua b/scripts/gui/gm-unit.lua new file mode 100644 index 000000000..5a97928fe --- /dev/null +++ b/scripts/gui/gm-unit.lua @@ -0,0 +1,170 @@ +-- Interface powered (somewhat user friendly) unit editor. +local gui = require 'gui' +local dialog = require 'gui.dialogs' +local widgets =require 'gui.widgets' +local guiScript = require 'gui.script' +local utils = require 'utils' +local args={...} + + +local target +--TODO: add more ways to guess what unit you want to edit +if args[1]~= nil then + target=df.units.find(args[1]) +else + target=dfhack.gui.getSelectedUnit(true) +end + +if target==nil then + qerror("No unit to edit") --TODO: better error message +end +local editors={} +function add_editor(editor_class) + table.insert(editors,{text=editor_class.ATTRS.frame_title,on_submit=function ( unit ) + editor_class{target_unit=unit}:show() + end}) +end +-------------------------------various subeditors--------- +--TODO set local sould or better yet skills vector to reduce long skill list access typing +editor_skills=defclass(editor_skills,gui.FramedScreen) +editor_skills.ATTRS={ + frame_style = gui.GREY_LINE_FRAME, + frame_title = "Skill editor", + target_unit = DEFAULT_NIL, + learned_only= false, +} +function list_skills(unit,learned_only) + local s_=df.job_skill + local u_skills=unit.status.current_soul.skills + local ret={} + for i,v in ipairs(s_) do + if i>0 then + local u_skill=utils.binsearch(u_skills,i,"id") + if u_skill or not learned_only then + if not u_skill then + u_skill={rating=-1,experience=0} + end + + local rating + if u_skill.rating >=0 then + rating=df.skill_rating.attrs[u_skill.rating] + else + rating={caption="",xp_threshold=0} + end + + local text=string.format("%s: %s %d %d/%d",df.job_skill.attrs[i].caption,rating.caption,u_skill.rating,u_skill.experience,rating.xp_threshold) + table.insert(ret,{text=text,id=i}) + end + end + end + return ret +end +function editor_skills:update_list(no_save_place) + local skill_list=list_skills(self.target_unit,self.learned_only) + if no_save_place then + self.subviews.skills:setChoices(skill_list) + else + self.subviews.skills:setChoices(skill_list,self.subviews.skills:getSelected()) + end +end +function editor_skills:init( args ) + if self.target_unit.status.current_soul==nil then + qerror("Unit does not have soul, can't edit skills") + end + + local skill_list=list_skills(self.target_unit,self.learned_only) + + self:addviews{ + widgets.FilteredList{ + choices=skill_list, + frame = {t=0, b=1,l=1}, + view_id="skills", + }, + widgets.Label{ + frame = { b=0,l=1}, + text ={{text= ": exit editor ", + key = "LEAVESCREEN", + on_activate= self:callback("dismiss") + }, + {text=": remove level ", + key = "SECONDSCROLL_UP", + on_activate=self:callback("level_skill",-1)}, + {text=": add level ", + key = "SECONDSCROLL_DOWN", + on_activate=self:callback("level_skill",1)} + , + {text=": show learned only ", + key = "CHANGETAB", + on_activate=function () + self.learned_only=not self.learned_only + self:update_list(true) + end} + } + }, + } +end +function editor_skills:get_cur_skill() + local list_wid=self.subviews.skills + local _,choice=list_wid:getSelected() + if choice==nil then + qerror("Nothing selected") + end + local u_skill=utils.binsearch(self.target_unit.status.current_soul.skills,choice.id,"id") + return choice,u_skill +end +function editor_skills:level_skill(lvl) + local sk_en,sk=self:get_cur_skill() + if lvl >0 then + local rating + + if sk then + rating=sk.rating+lvl + else + rating=lvl-1 + end + + utils.insert_or_update(self.target_unit.status.current_soul.skills, {new=true, id=sk_en.id, rating=rating}, 'id') --TODO set exp? + elseif sk and sk.rating==0 and lvl<0 then + utils.erase_sorted_key(self.target_unit.status.current_soul.skills,sk_en.id,"id") + elseif sk and lvl<0 then + utils.insert_or_update(self.target_unit.status.current_soul.skills, {new=true, id=sk_en.id, rating=sk.rating+lvl}, 'id') --TODO set exp? + end + self:update_list() +end +function editor_skills:remove_rust(skill) + --TODO +end +add_editor(editor_skills) +-------------------------------main window---------------- +unit_editor = defclass(unit_editor, gui.FramedScreen) +unit_editor.ATTRS={ + frame_style = gui.GREY_LINE_FRAME, + frame_title = "GameMaster's unit editor", + target_unit = DEFAULT_NIL, + } + + +function unit_editor:init(args) + + self:addviews{ + widgets.FilteredList{ + choices=editors, + on_submit=function (idx,choice) + if choice.on_submit then + choice.on_submit(self.target_unit) + end + end + }, + widgets.Label{ + frame = { b=0,l=1}, + text ={{text= ": exit editor", + key = "LEAVESCREEN", + on_activate= self:callback("dismiss") + }, + } + }, + } +end + + +unit_editor{target_unit=target}:show() From 0e939531ab630176c005cee12d4a84f0fdb1771c Mon Sep 17 00:00:00 2001 From: warmist Date: Sun, 26 Jul 2015 12:53:48 +0300 Subject: [PATCH 2/5] Update gm-unit.lua Add counter editor. --- scripts/gui/gm-unit.lua | 99 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 98 insertions(+), 1 deletion(-) diff --git a/scripts/gui/gm-unit.lua b/scripts/gui/gm-unit.lua index 5a97928fe..e9b245f3a 100644 --- a/scripts/gui/gm-unit.lua +++ b/scripts/gui/gm-unit.lua @@ -131,10 +131,107 @@ function editor_skills:level_skill(lvl) end self:update_list() end -function editor_skills:remove_rust(skill) +function editor_skills:remove_rust(skill) --TODO end add_editor(editor_skills) +------- counters editor +editor_counters=defclass(editor_counters,gui.FramedScreen) +editor_counters.ATTRS={ + frame_style = gui.GREY_LINE_FRAME, + frame_title = "Counters editor", + target_unit = DEFAULT_NIL, + counters1={ + "think_counter", + "job_counter", + "swap_counter", + "winded", + "stunned", + "unconscious", + "suffocation", + "webbed", + "soldier_mood_countdown", + "soldier_mood", --todo enum, + "pain", + "nausea", + "dizziness", + }, + counters2={ + "paralysis", + "numbness", + "fever", + "exhaustion", + "hunger_timer", + "thirst_timer", + "sleepiness_timer", + "stomach_content", + "stomach_food", + "vomit_timeout", + "stored_fat" --TODO what to reset to? + } +} +function editor_counters:fill_counters() + local ret={} + local u=self.target_unit + for i,v in ipairs(self.counters1) do + table.insert(ret,{f=u.counters:_field(v),name=v}) + end + for i,v in ipairs(self.counters2) do + table.insert(ret,{f=u.counters2:_field(v),name=v}) + end + return ret +end +function editor_counters:update_counters() + for i,v in ipairs(self.counter_list) do + v.text=string.format("%s:%d",v.name,v.f.value) + end + self.subviews.counters:setChoices(self.counter_list) +end +function editor_counters:set_cur_counter(value,index,choice) + choice.f.value=value + self:update_counters() +end +function editor_counters:choose_cur_counter(index,choice) + dialog.showInputPrompt(choice.name,"Enter new value:",COLOR_WHITE, + tostring(choice.f.value),function(new_value) + self:set_cur_counter(new_value,index,choice) + end) +end +function editor_counters:init( args ) + if self.target_unit==nil then + qerror("invalid unit") + end + + self.counter_list=self:fill_counters() + + + self:addviews{ + widgets.FilteredList{ + choices=self.counter_list, + frame = {t=0, b=1,l=1}, + view_id="counters", + on_submit=self:callback("choose_cur_counter"), + on_submit2=self:callback("set_cur_counter",0),--TODO some things need to be set to different defaults + }, + widgets.Label{ + frame = { b=0,l=1}, + text ={{text= ": exit editor ", + key = "LEAVESCREEN", + on_activate= self:callback("dismiss") + }, + {text=": reset counter ", + key = "SEC_SELECT", + }, + {text=": set counter ", + key = "SELECT", + } + + } + }, + } + self:update_counters() +end +add_editor(editor_counters) -------------------------------main window---------------- unit_editor = defclass(unit_editor, gui.FramedScreen) unit_editor.ATTRS={ From d9da55f6bd4726c06cb764f77250a0a0320389d1 Mon Sep 17 00:00:00 2001 From: warmist Date: Sun, 26 Jul 2015 12:54:23 +0300 Subject: [PATCH 3/5] Update gm-unit.lua tabs to spaces. --- scripts/gui/gm-unit.lua | 300 ++++++++++++++++++++-------------------- 1 file changed, 150 insertions(+), 150 deletions(-) diff --git a/scripts/gui/gm-unit.lua b/scripts/gui/gm-unit.lua index e9b245f3a..2aecd98bf 100644 --- a/scripts/gui/gm-unit.lua +++ b/scripts/gui/gm-unit.lua @@ -10,186 +10,186 @@ local args={...} local target --TODO: add more ways to guess what unit you want to edit if args[1]~= nil then - target=df.units.find(args[1]) + target=df.units.find(args[1]) else - target=dfhack.gui.getSelectedUnit(true) + target=dfhack.gui.getSelectedUnit(true) end if target==nil then - qerror("No unit to edit") --TODO: better error message + qerror("No unit to edit") --TODO: better error message end local editors={} function add_editor(editor_class) - table.insert(editors,{text=editor_class.ATTRS.frame_title,on_submit=function ( unit ) - editor_class{target_unit=unit}:show() - end}) + table.insert(editors,{text=editor_class.ATTRS.frame_title,on_submit=function ( unit ) + editor_class{target_unit=unit}:show() + end}) end -------------------------------various subeditors--------- --TODO set local sould or better yet skills vector to reduce long skill list access typing editor_skills=defclass(editor_skills,gui.FramedScreen) editor_skills.ATTRS={ - frame_style = gui.GREY_LINE_FRAME, + frame_style = gui.GREY_LINE_FRAME, frame_title = "Skill editor", target_unit = DEFAULT_NIL, learned_only= false, } function list_skills(unit,learned_only) - local s_=df.job_skill - local u_skills=unit.status.current_soul.skills - local ret={} - for i,v in ipairs(s_) do - if i>0 then - local u_skill=utils.binsearch(u_skills,i,"id") - if u_skill or not learned_only then - if not u_skill then - u_skill={rating=-1,experience=0} - end + local s_=df.job_skill + local u_skills=unit.status.current_soul.skills + local ret={} + for i,v in ipairs(s_) do + if i>0 then + local u_skill=utils.binsearch(u_skills,i,"id") + if u_skill or not learned_only then + if not u_skill then + u_skill={rating=-1,experience=0} + end - local rating - if u_skill.rating >=0 then - rating=df.skill_rating.attrs[u_skill.rating] - else - rating={caption="",xp_threshold=0} - end + local rating + if u_skill.rating >=0 then + rating=df.skill_rating.attrs[u_skill.rating] + else + rating={caption="",xp_threshold=0} + end - local text=string.format("%s: %s %d %d/%d",df.job_skill.attrs[i].caption,rating.caption,u_skill.rating,u_skill.experience,rating.xp_threshold) - table.insert(ret,{text=text,id=i}) - end - end - end - return ret + local text=string.format("%s: %s %d %d/%d",df.job_skill.attrs[i].caption,rating.caption,u_skill.rating,u_skill.experience,rating.xp_threshold) + table.insert(ret,{text=text,id=i}) + end + end + end + return ret end function editor_skills:update_list(no_save_place) - local skill_list=list_skills(self.target_unit,self.learned_only) - if no_save_place then - self.subviews.skills:setChoices(skill_list) - else - self.subviews.skills:setChoices(skill_list,self.subviews.skills:getSelected()) - end + local skill_list=list_skills(self.target_unit,self.learned_only) + if no_save_place then + self.subviews.skills:setChoices(skill_list) + else + self.subviews.skills:setChoices(skill_list,self.subviews.skills:getSelected()) + end end function editor_skills:init( args ) - if self.target_unit.status.current_soul==nil then - qerror("Unit does not have soul, can't edit skills") - end + if self.target_unit.status.current_soul==nil then + qerror("Unit does not have soul, can't edit skills") + end - local skill_list=list_skills(self.target_unit,self.learned_only) + local skill_list=list_skills(self.target_unit,self.learned_only) - self:addviews{ - widgets.FilteredList{ - choices=skill_list, - frame = {t=0, b=1,l=1}, - view_id="skills", - }, - widgets.Label{ + self:addviews{ + widgets.FilteredList{ + choices=skill_list, + frame = {t=0, b=1,l=1}, + view_id="skills", + }, + widgets.Label{ frame = { b=0,l=1}, text ={{text= ": exit editor ", key = "LEAVESCREEN", on_activate= self:callback("dismiss") }, {text=": remove level ", - key = "SECONDSCROLL_UP", - on_activate=self:callback("level_skill",-1)}, - {text=": add level ", - key = "SECONDSCROLL_DOWN", - on_activate=self:callback("level_skill",1)} + key = "SECONDSCROLL_UP", + on_activate=self:callback("level_skill",-1)}, + {text=": add level ", + key = "SECONDSCROLL_DOWN", + on_activate=self:callback("level_skill",1)} , {text=": show learned only ", - key = "CHANGETAB", - on_activate=function () - self.learned_only=not self.learned_only - self:update_list(true) - end} + key = "CHANGETAB", + on_activate=function () + self.learned_only=not self.learned_only + self:update_list(true) + end} } }, } end function editor_skills:get_cur_skill() - local list_wid=self.subviews.skills - local _,choice=list_wid:getSelected() - if choice==nil then - qerror("Nothing selected") - end - local u_skill=utils.binsearch(self.target_unit.status.current_soul.skills,choice.id,"id") - return choice,u_skill + local list_wid=self.subviews.skills + local _,choice=list_wid:getSelected() + if choice==nil then + qerror("Nothing selected") + end + local u_skill=utils.binsearch(self.target_unit.status.current_soul.skills,choice.id,"id") + return choice,u_skill end function editor_skills:level_skill(lvl) - local sk_en,sk=self:get_cur_skill() - if lvl >0 then - local rating + local sk_en,sk=self:get_cur_skill() + if lvl >0 then + local rating - if sk then - rating=sk.rating+lvl - else - rating=lvl-1 - end + if sk then + rating=sk.rating+lvl + else + rating=lvl-1 + end - utils.insert_or_update(self.target_unit.status.current_soul.skills, {new=true, id=sk_en.id, rating=rating}, 'id') --TODO set exp? - elseif sk and sk.rating==0 and lvl<0 then - utils.erase_sorted_key(self.target_unit.status.current_soul.skills,sk_en.id,"id") - elseif sk and lvl<0 then - utils.insert_or_update(self.target_unit.status.current_soul.skills, {new=true, id=sk_en.id, rating=sk.rating+lvl}, 'id') --TODO set exp? - end - self:update_list() + utils.insert_or_update(self.target_unit.status.current_soul.skills, {new=true, id=sk_en.id, rating=rating}, 'id') --TODO set exp? + elseif sk and sk.rating==0 and lvl<0 then + utils.erase_sorted_key(self.target_unit.status.current_soul.skills,sk_en.id,"id") + elseif sk and lvl<0 then + utils.insert_or_update(self.target_unit.status.current_soul.skills, {new=true, id=sk_en.id, rating=sk.rating+lvl}, 'id') --TODO set exp? + end + self:update_list() end function editor_skills:remove_rust(skill) - --TODO + --TODO end add_editor(editor_skills) ------- counters editor editor_counters=defclass(editor_counters,gui.FramedScreen) editor_counters.ATTRS={ - frame_style = gui.GREY_LINE_FRAME, + frame_style = gui.GREY_LINE_FRAME, frame_title = "Counters editor", target_unit = DEFAULT_NIL, counters1={ "think_counter", - "job_counter", - "swap_counter", - "winded", - "stunned", - "unconscious", - "suffocation", - "webbed", - "soldier_mood_countdown", - "soldier_mood", --todo enum, - "pain", - "nausea", - "dizziness", - }, - counters2={ - "paralysis", - "numbness", - "fever", - "exhaustion", - "hunger_timer", - "thirst_timer", - "sleepiness_timer", - "stomach_content", - "stomach_food", - "vomit_timeout", - "stored_fat" --TODO what to reset to? - } + "job_counter", + "swap_counter", + "winded", + "stunned", + "unconscious", + "suffocation", + "webbed", + "soldier_mood_countdown", + "soldier_mood", --todo enum, + "pain", + "nausea", + "dizziness", + }, + counters2={ + "paralysis", + "numbness", + "fever", + "exhaustion", + "hunger_timer", + "thirst_timer", + "sleepiness_timer", + "stomach_content", + "stomach_food", + "vomit_timeout", + "stored_fat" --TODO what to reset to? + } } function editor_counters:fill_counters() - local ret={} - local u=self.target_unit - for i,v in ipairs(self.counters1) do - table.insert(ret,{f=u.counters:_field(v),name=v}) - end - for i,v in ipairs(self.counters2) do - table.insert(ret,{f=u.counters2:_field(v),name=v}) - end - return ret + local ret={} + local u=self.target_unit + for i,v in ipairs(self.counters1) do + table.insert(ret,{f=u.counters:_field(v),name=v}) + end + for i,v in ipairs(self.counters2) do + table.insert(ret,{f=u.counters2:_field(v),name=v}) + end + return ret end function editor_counters:update_counters() - for i,v in ipairs(self.counter_list) do - v.text=string.format("%s:%d",v.name,v.f.value) - end - self.subviews.counters:setChoices(self.counter_list) + for i,v in ipairs(self.counter_list) do + v.text=string.format("%s:%d",v.name,v.f.value) + end + self.subviews.counters:setChoices(self.counter_list) end function editor_counters:set_cur_counter(value,index,choice) - choice.f.value=value - self:update_counters() + choice.f.value=value + self:update_counters() end function editor_counters:choose_cur_counter(index,choice) dialog.showInputPrompt(choice.name,"Enter new value:",COLOR_WHITE, @@ -198,38 +198,38 @@ function editor_counters:choose_cur_counter(index,choice) end) end function editor_counters:init( args ) - if self.target_unit==nil then - qerror("invalid unit") - end + if self.target_unit==nil then + qerror("invalid unit") + end - self.counter_list=self:fill_counters() + self.counter_list=self:fill_counters() - self:addviews{ - widgets.FilteredList{ - choices=self.counter_list, - frame = {t=0, b=1,l=1}, - view_id="counters", - on_submit=self:callback("choose_cur_counter"), - on_submit2=self:callback("set_cur_counter",0),--TODO some things need to be set to different defaults - }, - widgets.Label{ + self:addviews{ + widgets.FilteredList{ + choices=self.counter_list, + frame = {t=0, b=1,l=1}, + view_id="counters", + on_submit=self:callback("choose_cur_counter"), + on_submit2=self:callback("set_cur_counter",0),--TODO some things need to be set to different defaults + }, + widgets.Label{ frame = { b=0,l=1}, text ={{text= ": exit editor ", key = "LEAVESCREEN", on_activate= self:callback("dismiss") }, {text=": reset counter ", - key = "SEC_SELECT", - }, - {text=": set counter ", - key = "SELECT", - } + key = "SEC_SELECT", + }, + {text=": set counter ", + key = "SELECT", + } } }, } - self:update_counters() + self:update_counters() end add_editor(editor_counters) -------------------------------main window---------------- @@ -243,16 +243,16 @@ unit_editor.ATTRS={ function unit_editor:init(args) - self:addviews{ - widgets.FilteredList{ - choices=editors, - on_submit=function (idx,choice) - if choice.on_submit then - choice.on_submit(self.target_unit) - end - end - }, - widgets.Label{ + self:addviews{ + widgets.FilteredList{ + choices=editors, + on_submit=function (idx,choice) + if choice.on_submit then + choice.on_submit(self.target_unit) + end + end + }, + widgets.Label{ frame = { b=0,l=1}, text ={{text= ": exit editor", key = "LEAVESCREEN", From a7e1b15db5c4a79679fa680f632aee09405df902 Mon Sep 17 00:00:00 2001 From: warmist Date: Sun, 23 Aug 2015 14:33:14 +0300 Subject: [PATCH 4/5] Add civilization chooser Adds a civilization chooser, also there is race choice dialog and civ choice dialog (with race filtering). --- scripts/gui/gm-unit.lua | 329 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 329 insertions(+) diff --git a/scripts/gui/gm-unit.lua b/scripts/gui/gm-unit.lua index 2aecd98bf..ee021b9df 100644 --- a/scripts/gui/gm-unit.lua +++ b/scripts/gui/gm-unit.lua @@ -135,6 +135,179 @@ function editor_skills:remove_rust(skill) --TODO end add_editor(editor_skills) +------- civ editor +RaceBox = defclass(RaceBox, dialog.ListBox) +RaceBox.focus_path = 'RaceBox' + +RaceBox.ATTRS{ + format_name="$NAME ($TOKEN)", + with_filter=true, + allow_none=false, +} +function RaceBox:format_creature(creature_raw) + local t = {NAME=creature_raw.name[0],TOKEN=creature_raw.creature_id} + return string.gsub(self.format_name, "%$(%w+)", t) +end +function RaceBox:preinit(info) + self.format_name=RaceBox.ATTRS.format_name or info.format_name -- preinit does not have ATTRS set yet + local choices={} + if RaceBox.ATTRS.allow_none or info.allow_none then + table.insert(choices,{text="",num=-1}) + end + for i,v in ipairs(df.global.world.raws.creatures.all) do + local text=self:format_creature(v) + table.insert(choices,{text=text,raw=v,num=i,search_key=text:lower()}) + end + info.choices=choices +end +function showRacePrompt(title, text, tcolor, on_select, on_cancel, min_width,allow_none) + RaceBox{ + frame_title = title, + text = text, + text_pen = tcolor, + on_select = on_select, + on_cancel = on_cancel, + frame_width = min_width, + allow_none = allow_none, + }:show() +end +CivBox = defclass(CivBox,dialog.ListBox) +CivBox.focus_path = "CivBox" + +CivBox.ATTRS={ + format_name="$NAME ($ENGLISH):$ID", + format_no_name=":$ID", + name_other="", + with_filter=true, + allow_other=false, +} + +function civ_name(id,format_name,format_no_name,name_other,name_invalid) + if id==-1 then + return name_other or "" + end + local civ + if type(id)=='userdata' then + civ=id + else + civ=df.historical_entity.find(id) + if civ==nil then + return name_invalid or "" + end + end + local t={NAME=dfhack.TranslateName(civ.name),ENGLISH=dfhack.TranslateName(civ.name,true),ID=civ.id} --TODO race?, maybe something from raws? + if t.NAME=="" then + return string.gsub(format_no_name or ":$ID", "%$(%w+)", t) + end + return string.gsub(format_name or "$NAME ($ENGLISH):$ID", "%$(%w+)", t) +end +function CivBox:update_choices() + local choices={} + if self.allow_other then + table.insert(choices,{text=self.name_other,num=-1}) + end + + for i,v in ipairs(df.global.world.entities.all) do + if not self.race_filter or (v.race==self.race_filter) then --TODO filter type + local text=civ_name(v,self.format_name,self.format_no_name,self.name_other,self.name_invalid) + table.insert(choices,{text=text,raw=v,num=i}) + end + end + self.choices=choices + if self.subviews.list then + self.subviews.list:setChoices(self.choices) + end +end +function CivBox:update_race_filter(id) + local raw=df.creature_raw.find(id) + if raw then + self.subviews.race_label:setText(": "..raw.name[0]) + self.race_filter=id + else + self.subviews.race_label:setText(": ") + self.race_filter=nil + end + + self:update_choices() +end +function CivBox:choose_race() + showRacePrompt("Choose race","Select new race:",nil,function (id,choice) + self:update_race_filter(choice.num) + end,nil,nil,true) +end +function CivBox:init(info) + self.subviews.list.frame={t=3,r=0,l=0} + self:addviews{ + widgets.Label{frame={t=1,l=0},text={ + {text="Filter race ",key="CUSTOM_CTRL_A",key_sep="()",on_activate=self:callback("choose_race")}, + }}, + widgets.Label{frame={t=1,l=21},view_id="race_label", + text=": ", + } + } + self:update_choices() +end +function showCivPrompt(title, text, tcolor, on_select, on_cancel, min_width,allow_other) + CivBox{ + frame_title = title, + text = text, + text_pen = tcolor, + on_select = on_select, + on_cancel = on_cancel, + frame_width = min_width, + allow_other = allow_other, + }:show() +end + +editor_civ=defclass(editor_civ,gui.FramedScreen) +editor_civ.ATTRS={ + frame_style = gui.GREY_LINE_FRAME, + frame_title = "Civilization editor", + target_unit = DEFAULT_NIL, + } + +function editor_civ:update_curren_civ() + self.subviews.civ_name:setText("Currently: "..civ_name(self.target_unit.civ_id)) +end +function editor_civ:init( args ) + if self.target_unit==nil then + qerror("invalid unit") + end + + self:addviews{ + widgets.Label{view_id="civ_name",frame = { t=1,l=1}, text="Currently: "..civ_name(self.target_unit.civ_id)}, + widgets.Label{frame = { t=2,l=1}, text={{text=": set to other (-1, usually enemy)",key="CUSTOM_N", + on_activate= function() self.target_unit.civ_id=-1;self:update_curren_civ() end}}}, + widgets.Label{frame = { t=3,l=1}, text={{text=": set to current civ("..df.global.ui.civ_id..")",key="CUSTOM_C", + on_activate= function() self.target_unit.civ_id=df.global.ui.civ_id;self:update_curren_civ() end}}}, + widgets.Label{frame = { t=4,l=1}, text={{text=": manually enter",key="CUSTOM_E", + on_activate=function () + dialog.showInputPrompt("Civ id","Enter new civ id:",COLOR_WHITE, + tostring(self.target_unit.civ_id),function(new_value) + self.target_unit.civ_id=new_value + self:update_curren_civ() + end) + end}} + }, + widgets.Label{frame= {t=5,l=1}, text={{text=": select from list",key="CUSTOM_L", + on_activate=function ( ) + showCivPrompt("Choose civilization", "Select units civilization",nil,function ( id,choice ) + self.target_unit.civ_id=choice.num + self:update_curren_civ() + end,nil,nil,true) + end + }}}, + widgets.Label{ + frame = { b=0,l=1}, + text ={{text= ": exit editor ", + key = "LEAVESCREEN", + on_activate= self:callback("dismiss") + }, + } + }, + } +end +add_editor(editor_civ) ------- counters editor editor_counters=defclass(editor_counters,gui.FramedScreen) editor_counters.ATTRS={ @@ -232,6 +405,162 @@ function editor_counters:init( args ) self:update_counters() end add_editor(editor_counters) + +wound_creator=defclass(wound_creator,gui.FramedScreen) +wound_creator.ATTRS={ + frame_style = gui.GREY_LINE_FRAME, + frame_title = "Wound creator", + target_wound = DEFAULT_NIL, + --filter +} +function wound_creator:init( args ) + if self.target_wound==nil then + qerror("invalid wound") + end + + + self:addviews{ + widgets.List{ + + frame = {t=0, b=1,l=1}, + view_id="fields", + on_submit=self:callback("edit_cur_wound"), + on_submit2=self:callback("delete_current_wound") + }, + widgets.Label{ + frame = { b=0,l=1}, + text ={{text= ": exit editor ", + key = "LEAVESCREEN", + on_activate= self:callback("dismiss")}, + + {text=": edit wound ", + key = "SELECT"}, + + {text=": delete wound ", + key = "SEC_SELECT"}, + {text=": create wound ", + key = "CUSTOM_CTRL_I", + on_activate= self:callback("create_new_wound")}, + + } + }, + } + self:update_wounds() +end +------------------- +editor_wounds=defclass(editor_wounds,gui.FramedScreen) +editor_wounds.ATTRS={ + frame_style = gui.GREY_LINE_FRAME, + frame_title = "Wound editor", + target_unit = DEFAULT_NIL, + --filter +} +function is_scar( wound_part ) + return wound_part.flags1.scar_cut or wound_part.flags1.scar_smashed or + wound_part.flags1.scar_edged_shake1 or wound_part.flags1.scar_blunt_shake1 +end +function format_flag_name( fname ) + return fname:sub(1,1):upper()..fname:sub(2):gsub("_"," ") +end +function name_from_flags( wp ) + for i,v in ipairs(wp.flags1) do + if v then + return format_flag_name(df.wound_damage_flags1[i]) + end + end + for i,v in ipairs(wp.flags2) do + if v then + return format_flag_name(df.wound_damage_flags2[i]) + end + end + return "" +end +function format_wound( list_id,wound, unit) + + local name="" + if #wound.parts>0 and #wound.parts[0].effect_type>0 then --try to make wound name by effect... + name=tostring(df.wound_effect_type[wound.parts[0].effect_type[0]]) + if #wound.parts>1 then --cheap and probably incorrect... + name=name.."s" + end + elseif #wound.parts>0 and is_scar(wound.parts[0]) then + name="Scar" + elseif #wound.parts>0 then + local wp=wound.parts[0] + name=name_from_flags(wp) + end + + return string.format("%d. %s id=%d",list_id,name,wound.id) +end +function editor_wounds:update_wounds() + local ret={} + for i,v in ipairs(self.trg_wounds) do + table.insert(ret,{text=format_wound(i,v,self.target_unit),wound=v}) + end + self.subviews.wounds:setChoices(ret) + self.wound_list=ret +end +function editor_wounds:dirty_unit() + print("todo: implement unit status recalculation") +end +function editor_wounds:get_cur_wound() + local list_wid=self.subviews.wounds + local _,choice=list_wid:getSelected() + if choice==nil then + qerror("Nothing selected") + end + local ret_wound=utils.binsearch(self.trg_wounds,choice.id,"id") + return choice,ret_wound +end +function editor_wounds:delete_current_wound(index,choice) + + utils.erase_sorted(self.trg_wounds,choice.wound,"id") + choice.wound:delete() + self:dirty_unit() + self:update_wounds() +end +function editor_wounds:create_new_wound() + print("Creating") +end +function editor_wounds:edit_cur_wound(index,choice) + +end +function editor_wounds:init( args ) + if self.target_unit==nil then + qerror("invalid unit") + end + self.trg_wounds=self.target_unit.body.wounds + + self:addviews{ + widgets.List{ + + frame = {t=0, b=1,l=1}, + view_id="wounds", + on_submit=self:callback("edit_cur_wound"), + on_submit2=self:callback("delete_current_wound") + }, + widgets.Label{ + frame = { b=0,l=1}, + text ={{text= ": exit editor ", + key = "LEAVESCREEN", + on_activate= self:callback("dismiss")}, + + {text=": edit wound ", + key = "SELECT"}, + + {text=": delete wound ", + key = "SEC_SELECT"}, + {text=": create wound ", + key = "CUSTOM_CTRL_I", + on_activate= self:callback("create_new_wound")}, + + } + }, + } + self:update_wounds() +end +add_editor(editor_wounds) + -------------------------------main window---------------- unit_editor = defclass(unit_editor, gui.FramedScreen) unit_editor.ATTRS={ From 5e38689a62c780a97ef422ab2121b69dd56d0ab0 Mon Sep 17 00:00:00 2001 From: warmist Date: Sun, 23 Aug 2015 15:03:15 +0300 Subject: [PATCH 5/5] Whitespace removal oh why oh why, my editor does not do this automagically? We are after all in year 2015... --- scripts/gui/gm-unit.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/gui/gm-unit.lua b/scripts/gui/gm-unit.lua index ee021b9df..485552729 100644 --- a/scripts/gui/gm-unit.lua +++ b/scripts/gui/gm-unit.lua @@ -198,7 +198,7 @@ function civ_name(id,format_name,format_no_name,name_other,name_invalid) local t={NAME=dfhack.TranslateName(civ.name),ENGLISH=dfhack.TranslateName(civ.name,true),ID=civ.id} --TODO race?, maybe something from raws? if t.NAME=="" then return string.gsub(format_no_name or ":$ID", "%$(%w+)", t) - end + end return string.gsub(format_name or "$NAME ($ENGLISH):$ID", "%$(%w+)", t) end function CivBox:update_choices() @@ -231,7 +231,7 @@ function CivBox:update_race_filter(id) self:update_choices() end function CivBox:choose_race() - showRacePrompt("Choose race","Select new race:",nil,function (id,choice) + showRacePrompt("Choose race","Select new race:",nil,function (id,choice) self:update_race_filter(choice.num) end,nil,nil,true) end @@ -281,7 +281,7 @@ function editor_civ:init( args ) widgets.Label{frame = { t=3,l=1}, text={{text=": set to current civ("..df.global.ui.civ_id..")",key="CUSTOM_C", on_activate= function() self.target_unit.civ_id=df.global.ui.civ_id;self:update_curren_civ() end}}}, widgets.Label{frame = { t=4,l=1}, text={{text=": manually enter",key="CUSTOM_E", - on_activate=function () + on_activate=function () dialog.showInputPrompt("Civ id","Enter new civ id:",COLOR_WHITE, tostring(self.target_unit.civ_id),function(new_value) self.target_unit.civ_id=new_value @@ -456,8 +456,8 @@ editor_wounds.ATTRS={ --filter } function is_scar( wound_part ) - return wound_part.flags1.scar_cut or wound_part.flags1.scar_smashed or - wound_part.flags1.scar_edged_shake1 or wound_part.flags1.scar_blunt_shake1 + return wound_part.flags1.scar_cut or wound_part.flags1.scar_smashed or + wound_part.flags1.scar_edged_shake1 or wound_part.flags1.scar_blunt_shake1 end function format_flag_name( fname ) return fname:sub(1,1):upper()..fname:sub(2):gsub("_"," ")