Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed digfort script from forums #1498

Closed
lethosor opened this issue Feb 15, 2020 · 0 comments
Closed

Fixed digfort script from forums #1498

lethosor opened this issue Feb 15, 2020 · 0 comments
Assignees
Labels
Projects

Comments

@lethosor
Copy link
Member

From Abadrausar: http://www.bay12forums.com/smf/index.php?topic=164123.msg8091067#msg8091067

# designate an area based on a '.csv' plan
=begin

digfort
=======
A script to designate an area for digging according to a plan in csv format.

This script, inspired from quickfort, can designate an area for digging.
Your plan should be stored in a .csv file like this::

    # this is a comment
    d;d;u;d;d;skip this tile;d
    d;d;d;i

Available tile shapes are named after the 'dig' menu shortcuts:
``d`` for dig, ``u`` for upstairs, ``j`` downstairs, ``i`` updown,
``h`` channel, ``r`` upward ramp, ``x`` remove designation.
Unrecognized characters are ignored (eg the 'skip this tile' in the sample).

Empty lines and data after a ``#`` are ignored as comments.
To skip a row in your design, use a single ``;``.

One comment in the file may contain the phrase ``start(3,5)``. It is interpreted
as an offset for the pattern: instead of starting at the cursor, it will start
3 tiles left and 5 tiles up from the cursor.

additionally a comment can have a < for a rise in z level and a > for drop in z.

The script takes the plan filename, starting from the root df folder (where
``Dwarf Fortress.exe`` is found).

=end

fname = $script_args[0].to_s
map = df.world.map
Xsentinel = map.x_count - 1
Ysentinel = map.y_count - 1
Xstamp = false
Ystamp = false
if not $script_args[0] then
    puts "  Usage: digfort <plan filename>"
    throw :script_finished
end
if not fname[-4..-1] == ".csv" then
    puts "  The plan file must be in .csv format."
    throw :script_finished
end
if not File.file?(fname) then
    puts "  The specified file does not exist."
    throw :script_finished
end

planfile = File.read(fname)

if df.cursor.x == -30000
    puts "place the game cursor to the top-left corner of the design and retry"
    throw :script_finished
end

offset = [0, 0]
tiles = []
max_x = 0
max_y = 0
y = 0
planfile.each_line { |l|
    if l =~ /#.*start\s*\(\s*(-?\d+)\s*[,;]\s*(-?\d+)/
        raise "Error: multiple start() comments" if offset != [0, 0]
        offset = [$1.to_i, $2.to_i]
    end
    if l.chomp == '#<'
        l = '<'
        y = 0
    end

    if l.chomp == '#>'
        l = '>'
        y = 0
    end

    l = l.chomp.sub(/#.*/, '')
    next if l == ''
    x = 0
    tiles << l.split(/[;,]/).map { |t|
        t = t.strip
        if x < Xsentinel then x += 1 else x = Xsentinel ; Xstamp = true end
        max_x = x if x > max_x and not t.empty?
        (t[0] == '"') ? t[1..-2] : t
    }
    if y < Ysentinel then y += 1 else y = Ysentinel ; Xstamp = true end

}
 
x = df.cursor.x - offset[0]
y = df.cursor.y - offset[1]
z = df.cursor.z
starty = y - 1

if x < 0 or y < 0 or x+max_x >= map.x_count or y+max_y >= map.y_count
    max_x = max_x + x + 1
    max_y = max_y + y + 1
    raise "Position would designate outside map limits. Selected limits are from (#{x+1}, #{y+1}) to (#{max_x},#{max_y})"
end

tiles.each { |line|
    next if line.empty? or line == ['']
    line.each { |tile|
        if tile.empty?
            if x < Xsentinel then x += 1 else x = Xsentinel ; Xstamp = true end
            next
        end
        t = df.map_tile_at(x, y, z)
        s = t.shape_basic
        case tile
        when 'd'; t.dig(:Default) if s == :Wall
        when 'u'; t.dig(:UpStair) if s == :Wall
        when 'j'; t.dig(:DownStair) if s == :Wall or s == :Floor
        when 'i'; t.dig(:UpDownStair) if s == :Wall
        when 'h'; t.dig(:Channel) if s == :Wall or s == :Floor
        when 'r'; t.dig(:Ramp) if s == :Wall
        when 'x'; t.dig(:No)
        when '<'; y=starty; z += 1
        when '>'; y=starty; z -= 1
        end
        if x < Xsentinel then x += 1 else x = Xsentinel ; Xstamp = true end
    }
    x = df.cursor.x - offset[0]
    if y < Ysentinel then y += 1 else y = Ysentinel ; Ystamp = true end
}

if Xstamp or Ystamp then
  puts 'Warning: ' + (Xstamp ? 'the columns': '') + (Xstamp and Ystamp ? ' and ': '') + (Ystamp ? 'the rows' : '') + ' of the blueprint that overflow the designable area of the Dwarf Fortress embark have been ignored'
  puts '         if your blueprint X or Y dimension is close to that of the embark map, this warning is probably a false positive due to faulty logic in this script'
end

puts '  done'
@lethosor lethosor added the bug label Feb 15, 2020
@lethosor lethosor added this to To do in 0.47.04-r2 via automation Feb 15, 2020
0.47.04-r2 automation moved this from To do to Done Jul 28, 2020
@lethosor lethosor self-assigned this Jul 28, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
No open projects
0.47.04-r2
  
Done
Development

No branches or pull requests

1 participant