From 94cadbf1ec14f961e322e3e9f92f9e9f5979ee12 Mon Sep 17 00:00:00 2001 From: PeridexisErrant Date: Wed, 28 Oct 2015 21:13:17 +1100 Subject: [PATCH 1/8] Add FPS-boosting 'state of decay' scripts By Omniclasm. http://www.bay12forums.com/smf/index.php?topic=150782.msg6482346#msg6482346 --- scripts/deteriorateclothes.rb | 81 ++++++++++++++++++++++++++ scripts/deterioratecorpses.rb | 106 ++++++++++++++++++++++++++++++++++ scripts/deterioratefood.rb | 96 ++++++++++++++++++++++++++++++ scripts/starvingdead.rb | 92 +++++++++++++++++++++++++++++ 4 files changed, 375 insertions(+) create mode 100644 scripts/deteriorateclothes.rb create mode 100644 scripts/deterioratecorpses.rb create mode 100644 scripts/deterioratefood.rb create mode 100644 scripts/starvingdead.rb diff --git a/scripts/deteriorateclothes.rb b/scripts/deteriorateclothes.rb new file mode 100644 index 000000000..33084185e --- /dev/null +++ b/scripts/deteriorateclothes.rb @@ -0,0 +1,81 @@ +# Increase the rate at which clothes wear out +=begin + +deteriorateclothes +================== +Somewhere between a "mod" and a "fps booster", with a small impact on +vanilla gameplay. All of those slightly worn wool shoes that dwarves +scatter all over the place will deteriorate at a greatly increased rate, +and eventually just crumble into nothing. As warm and fuzzy as a dining +room full of used socks makes your dwarves feel, your FPS does not like it. + +Usage: ``deteriorateclothes (start|stop)`` + +=end + +class DeteriorateClothes + + def initialize + end + + def process + return false unless @running + + items = [df.world.items.other[:GLOVES], + df.world.items.other[:ARMOR], + df.world.items.other[:SHOES], + df.world.items.other[:PANTS], + df.world.items.other[:HELM]] + + items.each { |type| + type.each { |i| + if (i.subtype.armorlevel == 0 and i.flags.on_ground == true and i.wear > 0) + i.wear_timer *= i.wear + 0.5 + if (i.wear > 2) + i.flags.garbage_collect = true + end + end + } + } + + + end + + def start + @onupdate = df.onupdate_register('deteriorateclothes', 1200, 1200) { process } + @running = true + + puts "Deterioration of old clothes commencing..." + + end + + def stop + df.onupdate_unregister(@onupdate) + @running = false + end + + def status + @running ? 'Running.' : 'Stopped.' + end + +end + +case $script_args[0] +when 'start' + if ($DeteriorateClothes) + $DeteriorateClothes.stop + end + + $DeteriorateClothes = DeteriorateClothes.new + $DeteriorateClothes.start + +when 'end', 'stop' + $DeteriorateClothes.stop + +else + if $DeteriorateClothes + puts $DeteriorateClothes.status + else + puts 'Not loaded.' + end +end \ No newline at end of file diff --git a/scripts/deterioratecorpses.rb b/scripts/deterioratecorpses.rb new file mode 100644 index 000000000..56003f6d0 --- /dev/null +++ b/scripts/deterioratecorpses.rb @@ -0,0 +1,106 @@ +# Make corpse parts decay and vanish over time +=begin + +deterioratecorpses +================== +Somewhere between a "mod" and a "fps booster", with a small impact on +vanilla gameplay. + +In long running forts, especially evil biomes, you end up with a lot +of toes, teeth, fingers, and limbs scattered all over the place. +Various corpses from various sieges, stray kitten corpses, probably +some heads. Basically, your map will look like a giant pile of +assorted body parts, all of which individually eat up a small part +of your FPS, which collectively eat up quite a bit. + +In addition, this script also targets various butchery byproducts. +Enjoying your thriving animal industry? Your FPS does not. Those +thousands of skulls, bones, hooves, and wool eat up precious FPS +that could be used to kill goblins and elves. Whose corpses will +also get destroyed by the script to kill more goblins and elves. + +This script causes all of those to rot away into nothing after +several months. + +Usage: ``deterioratecorpses (start|stop)`` + +=end + +class DeteriorateCorpses + + def initialize + end + + def process + return false unless @running + + df.world.items.other[:ANY_CORPSE].each { |i| + if (i.flags.dead_dwarf == false) + i.wear_timer += 1 + if (i.wear_timer > 24 + rand(8)) + i.wear_timer = 0 + i.wear += 1 + end + if (i.wear > 3) + i.flags.garbage_collect = true + end + + end + + } + + df.world.items.other[:REMAINS].each { |i| + if (i.flags.dead_dwarf == false) + i.wear_timer += 1 + if (i.wear_timer > 6) + i.wear_timer = 0 + i.wear += 1 + end + if (i.wear > 3) + i.flags.garbage_collect = true + end + + end + + } + + end + + def start + @onupdate = df.onupdate_register('deterioratecorpses', 1200, 1200) { process } + @running = true + + puts "Deterioration of body parts commencing..." + + end + + def stop + df.onupdate_unregister(@onupdate) + @running = false + end + + def status + @running ? 'Running.' : 'Stopped.' + end + +end + +case $script_args[0] +when 'start' + if ($DeteriorateCorpses) + $DeteriorateCorpses.stop + end + + $DeteriorateCorpses = DeteriorateCorpses.new + $DeteriorateCorpses.start + +when 'end', 'stop' + $DeteriorateCorpses.stop + +else + if $DeteriorateCorpses + puts $DeteriorateCorpses.status + else + puts 'Not loaded.' + end +end \ No newline at end of file diff --git a/scripts/deterioratefood.rb b/scripts/deterioratefood.rb new file mode 100644 index 000000000..729a9962f --- /dev/null +++ b/scripts/deterioratefood.rb @@ -0,0 +1,96 @@ +# Make food and plants decay, and vanish after a few months +=begin + +deterioratefood +=============== +Somewhere between a "mod" and a "fps booster", with a small impact on +vanilla gameplay. + +With this script running, all food and plants wear out and disappear +after several months. Barrels and stockpiles will keep them from +rotting, but it won't keep them from decaying. No more sitting on a +hundred years worth of food. No more keeping barrels of pig tails +sitting around until you decide to use them. Either use it, eat it, +or lose it. Seeds, are excluded from this, if you aren't planning on +using your pig tails, hold onto the seeds for a rainy day. + +This script is...pretty far reaching. However, almost all long +running forts I've had end up sitting on thousands and thousands of +food items. Several thousand cooked meals, three thousand plump +helmets, just as many fish and meat. It gets pretty absurd. And your +FPS doesn't like it. + +Usage: ``deterioratefood (start|stop)`` + +=end + +class DeteriorateFood + + def initialize + end + + def process + return false unless @running + + items = [df.world.items.other[:FISH], + df.world.items.other[:FISH_RAW], + df.world.items.other[:EGG], + df.world.items.other[:CHEESE], + df.world.items.other[:PLANT], + df.world.items.other[:PLANT_GROWTH], + df.world.items.other[:FOOD]] + + items.each { |type| + type.each { |i| + i.wear_timer += 1 + if (i.wear_timer > 24 + rand(8)) + i.wear_timer = 0 + i.wear += 1 + end + if (i.wear > 3) + i.flags.garbage_collect = true + end + } + } + + + end + + def start + @onupdate = df.onupdate_register('deterioratefood', 1200, 1200) { process } + @running = true + + puts "Deterioration of food commencing..." + + end + + def stop + df.onupdate_unregister(@onupdate) + @running = false + end + + def status + @running ? 'Running.' : 'Stopped.' + end + +end + +case $script_args[0] +when 'start' + if ($DeteriorateFood) + $DeteriorateFood.stop + end + + $DeteriorateFood = DeteriorateFood.new + $DeteriorateFood.start + +when 'end', 'stop' + $DeteriorateFood.stop + +else + if $DeteriorateFood + puts $DeteriorateFood.status + else + puts 'Not loaded.' + end +end \ No newline at end of file diff --git a/scripts/starvingdead.rb b/scripts/starvingdead.rb new file mode 100644 index 000000000..2e9e8f4a8 --- /dev/null +++ b/scripts/starvingdead.rb @@ -0,0 +1,92 @@ +# Make undead units weaken after one month, and vanish after six +=begin + +starvingdead +============ +Somewhere between a "mod" and a "fps booster", with a small impact on +vanilla gameplay. It mostly helps prevent undead cascades in the caverns, +where constant combat leads to hundreds of undead roaming the +caverns and destroying your FPS. + +With this script running, all undead that have been on the map for +one month gradually decay, losing strength, speed, and toughness. +After six months, they collapse upon themselves, never to be reanimated. + +Usage: ``starvingdead (start|stop)`` + +=end + +class StarvingDead + + def initialize + @threshold = 1 + @die_threshold = 6 + end + + def process + return false unless @running + month_length = 67200 + if (@undead_count >= 25) + month_length *= 25 / @undead_count + end + + @undead_count = 0 + df.world.units.active.each { |u| + if (u.enemy.undead and not u.flags1.dead) + @undead_count += 1 + if (u.curse.time_on_site > month_length * @threshold) + u.body.physical_attrs.each { |att| + att.value = att.value - (att.value * 0.02) + } + end + + if (u.curse.time_on_site > month_length * @die_threshold) + u.flags1.dead = true + u.curse.rem_tags2.FIT_FOR_ANIMATION = true + end + end + } + end + + def start + @onupdate = df.onupdate_register('starvingdead', 1200, 1200) { process } + @running = true + @undead_count = 0 + + if ($script_args[1] and $script_args[1].gsub(/[^0-9\.]/,'').to_f > 0) + @threshold = $script_args[1].gsub(/[^0-9\.]/,'').to_f + end + + if ($script_args[2] and $script_args[2].gsub(/[^0-9\.]/,'').to_f > 0) + @die_threshold = $script_args[2].gsub(/[^0-9\.]/,'').to_f + end + + puts "Starving Dead starting...weakness starts at #{@threshold} months, true death at #{@die_threshold} months" + end + + def stop + df.onupdate_unregister(@onupdate) + @running = false + end + def status + @running ? 'Running.' : 'Stopped.' + end +end + +case $script_args[0] +when 'start' + if ($StarvingDead) + $StarvingDead.stop + end + $StarvingDead = StarvingDead.new + $StarvingDead.start + +when 'end', 'stop' + $StarvingDead.stop +else + if $StarvingDead + puts $StarvingDead.status + else + puts 'Not loaded.' + end +end From ff4f7203c5f393a328826755c60b3730fa72bca8 Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 30 Oct 2015 17:08:39 -0400 Subject: [PATCH 2/8] Update stonesense --- plugins/stonesense | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/stonesense b/plugins/stonesense index 8121de557..a0966c0e1 160000 --- a/plugins/stonesense +++ b/plugins/stonesense @@ -1 +1 @@ -Subproject commit 8121de557102eb11cb805f8a25b43ba43077a967 +Subproject commit a0966c0e171de1ed2383b758a26d8250400ca93d From ac71fa8070c5839ad9f51975242f1fa48701c2bd Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 30 Oct 2015 18:41:09 -0400 Subject: [PATCH 3/8] Add isValidLabor() to Units module Closes #711 and could avoid potential issues when editing units from other civs with manipulator. --- library/LuaApi.cpp | 1 + library/include/modules/Units.h | 2 ++ library/modules/Units.cpp | 13 +++++++++++++ plugins/autohauler.cpp | 2 ++ plugins/autolabor.cpp | 5 +++-- plugins/manipulator.cpp | 20 ++++++-------------- 6 files changed, 27 insertions(+), 16 deletions(-) diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 996cae8f1..62f274902 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -1519,6 +1519,7 @@ static const LuaWrapper::FunctionReg dfhack_units_module[] = { WRAPM(Units, getNominalSkill), WRAPM(Units, getEffectiveSkill), WRAPM(Units, getExperience), + WRAPM(Units, isValidLabor), WRAPM(Units, computeMovementSpeed), WRAPM(Units, computeSlowdownFactor), WRAPM(Units, getProfessionName), diff --git a/library/include/modules/Units.h b/library/include/modules/Units.h index 655f13b5a..d706778b6 100644 --- a/library/include/modules/Units.h +++ b/library/include/modules/Units.h @@ -269,6 +269,8 @@ DFHACK_EXPORT int getNominalSkill(df::unit *unit, df::job_skill skill_id, bool u DFHACK_EXPORT int getEffectiveSkill(df::unit *unit, df::job_skill skill_id); DFHACK_EXPORT int getExperience(df::unit *unit, df::job_skill skill_id, bool total = false); +DFHACK_EXPORT bool isValidLabor(df::unit *unit, df::unit_labor labor); + DFHACK_EXPORT int computeMovementSpeed(df::unit *unit); DFHACK_EXPORT float computeSlowdownFactor(df::unit *unit); diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index 99c0ebca7..4bd2b49aa 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -1223,6 +1223,19 @@ int Units::getEffectiveSkill(df::unit *unit, df::job_skill skill_id) return rating; } +bool Units::isValidLabor(df::unit *unit, df::unit_labor labor) +{ + CHECK_NULL_POINTER(unit); + if (!is_valid_enum_item(labor)) + return false; + if (labor == df::unit_labor::NONE) + return false; + df::historical_entity *entity = df::historical_entity::find(unit->civ_id); + if (entity && entity->entity_raw && !entity->entity_raw->jobs.permitted_labor[labor]) + return false; + return true; +} + inline void adjust_speed_rating(int &rating, bool is_adventure, int value, int dwarf100, int dwarf200, int adv50, int adv75, int adv100, int adv200) { if (is_adventure) diff --git a/plugins/autohauler.cpp b/plugins/autohauler.cpp index 47c64c0aa..9814b678e 100644 --- a/plugins/autohauler.cpp +++ b/plugins/autohauler.cpp @@ -951,6 +951,8 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out ) // For every dwarf... for(int dwarf = 0; dwarf < dwarfs.size(); dwarf++) { + if (!Units::isValidLabor(dwarfs[dwarf], labor)) + continue; // Set hauling labors based on employment states if(dwarf_info[dwarf].state == IDLE) { diff --git a/plugins/autolabor.cpp b/plugins/autolabor.cpp index 0ab28ca65..21b979416 100644 --- a/plugins/autolabor.cpp +++ b/plugins/autolabor.cpp @@ -658,7 +658,7 @@ static void enable_plugin(color_ostream &out) setOptionEnabled(CF_ENABLED, true); enable_autolabor = true; - out << "Enabling the plugin." << endl; + out << "Enabling autolabor." << endl; cleanup_state(); init_state(); @@ -975,7 +975,8 @@ static void assign_labor(unit_labor::unit_labor labor, if (!dwarfs[dwarf]->status.labors[labor]) dwarf_info[dwarf].assigned_jobs++; - dwarfs[dwarf]->status.labors[labor] = true; + if (Units::isValidLabor(dwarfs[dwarf], labor)) + dwarfs[dwarf]->status.labors[labor] = true; if (labor_infos[labor].is_exclusive) { diff --git a/plugins/manipulator.cpp b/plugins/manipulator.cpp index d6d2cb222..c2f6759a5 100644 --- a/plugins/manipulator.cpp +++ b/plugins/manipulator.cpp @@ -95,14 +95,6 @@ struct SkillColumn df::job_skill skill; // displayed rating char label[3]; // column header bool special; // specified labor is mutually exclusive with all other special labors - bool isValidLabor (df::historical_entity *entity = NULL) const - { - if (labor == unit_labor::NONE) - return false; - if (entity && entity->entity_raw && !entity->entity_raw->jobs.permitted_labor[labor]) - return false; - return true; - } }; #define NUM_COLUMNS (sizeof(columns) / sizeof(SkillColumn)) @@ -1631,9 +1623,10 @@ void viewscreen_unitlaborsst::feed(set *events) } UnitInfo *cur = units[input_row]; - if (events->count(interface_key::SELECT) && (cur->allowEdit) && columns[input_column].isValidLabor(ui->main.fortress_entity)) + df::unit *unit = cur->unit; + df::unit_labor cur_labor = columns[input_column].labor; + if (events->count(interface_key::SELECT) && (cur->allowEdit) && Units::isValidLabor(unit, cur_labor)) { - df::unit *unit = cur->unit; const SkillColumn &col = columns[input_column]; bool newstatus = !unit->status.labors[col.labor]; if (col.special) @@ -1650,16 +1643,15 @@ void viewscreen_unitlaborsst::feed(set *events) } unit->status.labors[col.labor] = newstatus; } - if (events->count(interface_key::SELECT_ALL) && (cur->allowEdit) && columns[input_column].isValidLabor(ui->main.fortress_entity)) + if (events->count(interface_key::SELECT_ALL) && (cur->allowEdit) && Units::isValidLabor(unit, cur_labor)) { - df::unit *unit = cur->unit; const SkillColumn &col = columns[input_column]; bool newstatus = !unit->status.labors[col.labor]; for (int i = 0; i < NUM_COLUMNS; i++) { if (columns[i].group != col.group) continue; - if (!columns[i].isValidLabor(ui->main.fortress_entity)) + if (!Units::isValidLabor(unit, columns[i].labor)) continue; if (columns[i].special) { @@ -2055,7 +2047,7 @@ void viewscreen_unitlaborsst::render() } - canToggle = (cur->allowEdit) && columns[sel_column].isValidLabor(ui->main.fortress_entity); + canToggle = (cur->allowEdit) && Units::isValidLabor(unit, columns[sel_column].labor); } int x = 2, y = dim.y - 4; From 83991d2a2282a412f1f31181977f43b449054490 Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 30 Oct 2015 18:45:55 -0400 Subject: [PATCH 4/8] plug: Don't color loaded plugins --- library/Core.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/Core.cpp b/library/Core.cpp index ea3eca5f8..2d537c1b3 100644 --- a/library/Core.cpp +++ b/library/Core.cpp @@ -882,7 +882,7 @@ command_result Core::runCommand(color_ostream &con, const std::string &first_, v switch (plug->getState()) { case Plugin::PS_LOADED: - color = COLOR_LIGHTGREEN; + color = COLOR_RESET; break; case Plugin::PS_UNLOADED: case Plugin::PS_UNLOADING: From 7da3c65079f0d15fe4014c757518a1320950b1f1 Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 30 Oct 2015 19:16:29 -0400 Subject: [PATCH 5/8] Fix display of arrows in lua filtered list widgets Fixes #718 --- library/lua/gui/materials.lua | 1 + library/lua/gui/widgets.lua | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/library/lua/gui/materials.lua b/library/lua/gui/materials.lua index f29f530a5..3128f4292 100644 --- a/library/lua/gui/materials.lua +++ b/library/lua/gui/materials.lua @@ -179,6 +179,7 @@ function MaterialDialog:onSelectObj(item) end function MaterialDialog:addMaterial(choices, mat, typ, idx, pfix, parent) + if not mat then return end -- Check the filter if self.mat_filter and not self.mat_filter(mat, parent, typ, idx) then return diff --git a/library/lua/gui/widgets.lua b/library/lua/gui/widgets.lua index cb9e1c9be..6e789d35d 100644 --- a/library/lua/gui/widgets.lua +++ b/library/lua/gui/widgets.lua @@ -540,6 +540,7 @@ function List:onRenderBody(dc) local current = (i == self.selected) local cur_pen = self.cursor_pen local cur_dpen = self.text_pen + local active_pen = current and cur_pen or cur_dpen if not self.active then cur_pen = self.inactive_pen or self.cursor_pen @@ -549,7 +550,7 @@ function List:onRenderBody(dc) local icon = getval(obj.icon) if iw and icon then - dc:seek(0, y) + dc:seek(0, y):pen(active_pen) paint_icon(icon, obj) end @@ -565,7 +566,7 @@ function List:onRenderBody(dc) end if icon and not iw then - dc:seek(ip-1,y) + dc:seek(ip-1,y):pen(active_pen) paint_icon(icon, obj) end end From aa2ada4cbcfa64467e782f6d7fcf9ebce5712f9d Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 30 Oct 2015 22:58:58 -0400 Subject: [PATCH 6/8] Use TRAVIS_BRANCH environment variable Ref #713 --- travis/pr-check-base.py | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/travis/pr-check-base.py b/travis/pr-check-base.py index f3cbab18c..47605b051 100644 --- a/travis/pr-check-base.py +++ b/travis/pr-check-base.py @@ -1,11 +1,7 @@ -import json, os, sys -if sys.version.startswith('2'): - from urllib2 import urlopen, HTTPError -else: - from urllib.request import urlopen - from urllib.error import HTTPError +import os, sys +repo = os.environ.get('TRAVIS_REPO_SLUG', 'dfhack/dfhack').lower() +branch = os.environ.get('TRAVIS_BRANCH', 'master') try: - repo = os.environ.get('TRAVIS_REPO_SLUG', 'dfhack/dfhack').lower() pr_id = int(os.environ.get('TRAVIS_PULL_REQUEST', 'false')) except ValueError: print('Not a pull request') @@ -14,18 +10,7 @@ print('Pull request %s#%i' % (repo, pr_id)) if repo != 'dfhack/dfhack': print('Not in dfhack/dfhack') sys.exit(0) -res = {} -try: - res = json.loads(urlopen('https://api.github.com/repos/%s/pulls/%i' % (repo, pr_id)).read().decode('utf-8')) -except ValueError: - pass -except HTTPError as e: - print('Failed to retrieve PR information from API: %s' % e) - sys.exit(2) -if 'base' not in res or 'ref' not in res['base']: - print('Invalid JSON returned from API') - sys.exit(2) -if res['base']['ref'] != 'develop': +if branch != 'develop': print('Not based on develop branch') sys.exit(1) else: From 68ae59d4bc21159a92e1862e3f62bab6b082655e Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 30 Oct 2015 23:11:14 -0400 Subject: [PATCH 7/8] log git commit in travis build --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 8b3a882bb..ac0d12869 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,6 +13,7 @@ before_install: pip install --user sphinx script: - git tag tmp-travis-build +- git log --pretty="commit %h (parents: %p): %s" -1 - python travis/pr-check-base.py - python travis/lint.py - python travis/script-in-readme.py From b7a69846d9e84b2dcd94f3d38e788c223c810215 Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 30 Oct 2015 23:30:06 -0400 Subject: [PATCH 8/8] Fix travis.yml syntax issue --- .travis.yml | 2 +- travis/git-info.sh | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 travis/git-info.sh diff --git a/.travis.yml b/.travis.yml index ac0d12869..1863835f1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ before_install: pip install --user sphinx script: - git tag tmp-travis-build -- git log --pretty="commit %h (parents: %p): %s" -1 +- sh travis/git-info.sh - python travis/pr-check-base.py - python travis/lint.py - python travis/script-in-readme.py diff --git a/travis/git-info.sh b/travis/git-info.sh new file mode 100644 index 000000000..333d13bc1 --- /dev/null +++ b/travis/git-info.sh @@ -0,0 +1,2 @@ +#!/bin/sh +git log --pretty="commit %h (parents: %p): %s" -1