FAQ  •  Register  •  Login

minefield.lua

<<

Lamp

User avatar

Posts: 426

Joined: Fri Jan 11, 2013 3:07 pm

Post Sun Apr 28, 2013 11:29 pm

minefield.lua

kaen wrote:Here's a usage guide for minefield.lua, which was a central component to my Bebop and Ricochet submissions to the Wild West design contest. It periodically spawns mines in specified zones, allowing you to create minefield(s) with respawning and randomly placed mines.

The levelgen was meant to be used without needing to edit it at all. In fact many different levels can use the same script file in different ways by simply changing the arguments you pass to it. When you type the name of the levelgen into the editor, you can pass it "arguments" (i.e. options) by typing things after the name. The general form is:

  Code:
minefield.lua [time] [min_mines] [max_mines] [zones]


"time" is in milliseconds (thousandths of a second), and is the time between each spawned wave of mines. min_mines and max_mines are the inclusive bounds for the number of mines to spawn, and zones is a lua table of zone ids. If you wanted to spawn 1 to 3 mines every ten seconds in zones 1, 2, and 3, you would type:

  Code:
minefield.lua 10000 1 3 {1,2,3}


These are also the default values, so the above is the same as simply typing:

  Code:
minefield.lua


Finally, the first three arguments can be mathematical expressions (or actually any valid lua) that includes a variable "t" which represents the number of milliseconds since the level started. For example, to lay a number of mines (every second) between 0 and the number of seconds which has passed since the level started, you could use:

  Code:
minefield.lua 1000 0 t/1000


Bugs:
  • Bitfighter uses spaces to parse arguments to levelgens, so you must not put spaces into your expressions or zone lists. Cram it all together, but put a single space between each argument
  • It uses the rectangular extents of zones, so your 16-sided curvilinear minefield will actually behave like the smallest axis-aligned rectangle which contains it. (tl;dr: use rectangular zones)

minefield.lua:
  Code:

-- minefield.lua [interval] [min_mines] [max_mines] [mine_zones]
-- interval - time in milliseconds between mine spawns
-- min/max_mines - inclusive bounds for the number of mines to spawn
-- mine_zones - a table (array) of ids of zones which are minefields
--
-- interval and min/max mines are processed using 'evaluate' below for each
-- invocation of mineEvent. This allows you to express these values in terms of
-- 't', which is the number of milliseconds since the level was loaded. For
-- instance, "minefield.lua 1000 1 1+t/1000" will spawn upto as many mines as
-- the number of full seconds since the level was loaded

START_TIME = getMachineTime()

-- find the value of the string at time t
function evaluate(str)
    return loadstring("t = " .. (getMachineTime() - START_TIME) .. " ; return " .. str)()
end

-- pick a random point within extents
function randomPoint(extents)
    return point.new(math.random(extents.minX, extents.maxX), math.random(extents.minY, extents.maxY))
end

-- return a well-labeled table of extents
function getExtents(zone)
    minX, minY, maxX, maxY = math.huge, math.huge, -math.huge, -math.huge
    for index, p in pairs(zone:getGeom()) do
        minX = math.min(minX, p.x)
        minY = math.min(minY, p.y)
        maxX = math.max(maxX, p.x)
        maxY = math.max(maxY, p.y)
    end
    extents = {}
    extents.minX = minX
    extents.maxX = maxX
    extents.minY = minY
    extents.maxY = maxY
    return extents
end

-- lay some mines in the minefields
function layMines()
    -- for each minefield
    for index, id in pairs(MINE_FIELDS) do
        -- lay between min and max mines
        for i = 1, math.random(MINE_MIN, evaluate(MINE_MAX)) do
            mineField = levelgen:findObjectById(id)
            -- only if the minefield exists
            if mineField ~= nil then
                p = randomPoint(getExtents(mineField))
                mine = Mine.new(p)
                levelgen:addItem(mine)
            end
        end
    end
end

function mineEvent()
    layMines()
    Timer:scheduleOnce(mineEvent, math.max(100, evaluate(MINE_INTERVAL)))
end

MINE_INTERVAL = 10000
MINE_MIN = 1
MINE_MAX = 3
MINE_FIELDS = {1, 2, 3}

function main()
    MINE_INTERVAL = arg[1] or MINE_INTERVAL
    MINE_MIN = arg[2] or MINE_MIN
    MINE_MAX = arg[3] or MINE_MAX
    MINE_FIELDS = loadstring("return " .. (arg[4] or "false"))() or MINE_FIELDS

    mineEvent()
end
 
Image
<<

bobdaduck

User avatar

Global Moderator

Posts: 790

Joined: Thu Mar 11, 2010 1:39 pm

Location: Utah

Post Mon Apr 29, 2013 7:03 am

Re: minefield.lua

Thanks Lamp!

I was debating moving the original post, but then realized that we may have other changes for the levelgen gallery forum subsection which I dunno might wipe all the posts inside it. Posting a copy means I don't have to worry.

So is this the version where he fixed that they only spawn in the top-right quadrant or whatever?
Little_Apple wrote:DnD: the REAL bitfighter levelgen documentation

Santiago ZAP wrote:bob doesn't make new maps, he makes new gamemodes
<<

kaen

User avatar

Posts: 209

Joined: Thu Jun 14, 2012 11:54 am

Post Mon Apr 29, 2013 10:14 am

Re: minefield.lua

bobdaduck wrote:So is this the version where he fixed that they only spawn in the top-right quadrant or whatever?


Unfortunately, that version exists only in my empty promises to create it.
bobdaduck wrote:Next, the moon!

└────────┘
⎈⎈⎈⎈
┌────────┐

Return to Levelgen Gallery

Who is online

Users browsing this forum: No registered users and 2 guests

cron