Last active
March 8, 2016 07:30
-
-
Save Ragzouken/c32eb99e506363a8afdf to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| -- turn based tactics based on | |
| -- upgrades and supply lines | |
| -- config finish | |
| -- ][ ][ | |
| -- ,-> switch -> report -. | |
| -- [ ] | |
| -- ^- supply <- action <-' | |
| -- note: don't want to allow | |
| -- parking heli/boat on | |
| -- impassables, but what | |
| -- happens when they are | |
| -- blocked by hidden units? | |
| -- | |
| -- "ambush" -> destroyed? | |
| -- just allow it?? | |
| -- costs supply to wait on | |
| -- impassable?? | |
| -- palettes | |
| fac_pal = { | |
| [0] = {}, | |
| { 8, 10, | |
| 2, 9, }, | |
| { 8, 15, | |
| 2, 4, }, | |
| { 8, 4, | |
| 2, 5, }, | |
| } | |
| fog_pal = { | |
| 3, 13, | |
| 11, 6, | |
| 12, 5, | |
| } | |
| function vcl(portrait, | |
| move_gfx, | |
| move_sfx, | |
| movement, | |
| vision) | |
| return { | |
| portrait = portrait, | |
| move_gfx = move_gfx, | |
| move_sfx = move_sfx, | |
| movement = movement, | |
| vision = vision, | |
| } | |
| end | |
| function upgrade(portrait) | |
| return { | |
| portrait = portrait, | |
| movement = 0, | |
| vision = 0, | |
| } | |
| end | |
| v_infantry = vcl(64,36,33,4,2) | |
| v_commando = vcl(66,36,33,4,3) | |
| v_dinghy = vcl(68,36,33,3,2) | |
| v_apc = vcl(70,32,34,6,2) | |
| v_chinook = vcl(72,20,32,8,5) | |
| v_tank = vcl(74,40,34,3,2) | |
| v_commando.supplied = true | |
| u_none = upgrade() | |
| u_binocs = upgrade(96) | |
| u_mortar = upgrade(98) | |
| u_camo = upgrade(100) | |
| u_build = upgrade(102) | |
| u_binocs.vision = 2 | |
| function _init() | |
| music(8) | |
| units = {} | |
| supply = {} | |
| cities = {} | |
| timer = 0 | |
| viewer = -1 | |
| select = o_make() | |
| path = {} | |
| pan_x = 0 | |
| pan_y = 0 | |
| pan_d = 0 | |
| selected = nil | |
| structure = nil | |
| cell_filter = abs | |
| make_unit(0, | |
| 1, 2, | |
| v_chinook, | |
| u_binocs) | |
| t = make_unit(0, | |
| 5, 5, | |
| v_tank) | |
| phase = "config" | |
| fog_clear(1) | |
| for x=0,63 do | |
| for y=0,63 do | |
| if mget(x, y) == 9 then | |
| city = make_city(x, y) | |
| end | |
| end | |
| end | |
| testcity = cities[1] | |
| add(testcity.units, t) | |
| debug = test | |
| end | |
| function _update() | |
| timer += 1 | |
| -- buttons | |
| ok = btnp(4) | |
| done = btnp(4,1) | |
| cancel = btnp(5) | |
| game_input "" | |
| -- camera panning | |
| if pan_d then -- tour | |
| pan_d += 0.005 | |
| pan_x = 64 + cos(pan_d) * 88 | |
| pan_y = 64 + sin(pan_d) * 88 | |
| else -- clamp camera | |
| sx, sy = o_grid(select) | |
| function bound(x) | |
| return x > 104 and -2 | |
| or x < 16 and 2 | |
| or 0 | |
| end | |
| pan_x -= bound(sx - pan_x) | |
| + pan_x % 2 | |
| pan_y -= bound(sy - pan_y) | |
| + pan_y % 2 | |
| end | |
| pan_x = mid(0, 128, pan_x) | |
| pan_y = mid(0, 128, pan_y) | |
| -- animate moving unit | |
| if mover | |
| and timer % 4 == 0 then | |
| d = bite(path) | |
| if d then | |
| sfx(mover.vehicle.move_sfx, | |
| 2) | |
| path = unit_move(mover, d) | |
| and path | |
| or {} | |
| else | |
| city = o_get(cities, mover) | |
| if city then | |
| add(city.units, mover) | |
| del(units, mover) | |
| o_del(units, mover) | |
| end | |
| mover.ad, mover = 1 | |
| sfx(-1, 2) | |
| end | |
| end | |
| if phase == "action" then | |
| for unit in all(units) do | |
| if unit.owner == viewer then | |
| forradius(unit, | |
| stat_vision(unit), | |
| function(x, y) | |
| fog_reveal(x, y, 1) | |
| end) | |
| end | |
| end | |
| end | |
| end | |
| function game_input() | |
| d = arrow "" | |
| if done | |
| and not selected | |
| and not structure then | |
| if phase=="config" | |
| or phase=="supply" | |
| then | |
| music(26) | |
| phase = "switch" | |
| pan_d = 0 | |
| path, selected = {} | |
| viewer = (viewer + 1) % 2 | |
| fog_clear(0) | |
| elseif phase == "switch" | |
| then | |
| music(0) | |
| phase, pan_d = "action" | |
| elseif phase == "action" then | |
| sfx(31, 3) | |
| phase = "supply" | |
| for unit in all(units) do | |
| unit.supplied = false | |
| end | |
| for city in all(cities) do | |
| city.supply | |
| = min(18, city.supply+2) | |
| end | |
| end | |
| elseif phase == "action" | |
| or phase == "supply" then | |
| if selected then | |
| cell_filter = fog_check | |
| -- if cursor was moved, add | |
| -- to path but revoke if the | |
| -- shortened path is invalid | |
| if d >= 0 then | |
| o_imove(select, d) | |
| path_add(path, d) | |
| path_short(path) | |
| if not unit_pass(selected, select) | |
| or #path > stat_move(selected) | |
| then | |
| o_imove(select, inv(d)) | |
| pop(path) | |
| else | |
| sfx(30, 3) | |
| end | |
| end | |
| -- confirm move or cancel | |
| -- selection | |
| if ok then | |
| sfx(31, 3) | |
| mover, selected = selected | |
| elseif cancel then | |
| sfx(35, 3) | |
| path, selected = {} | |
| end | |
| elseif structure then | |
| if cancel then | |
| sfx(35, 4) | |
| structure = nil | |
| end | |
| else | |
| -- move cursor | |
| -- x4 if cancel held | |
| o_imove(select, d, | |
| btn(5) and 4) | |
| -- bound cursor to map | |
| select.x = mid(select.x,0,31) | |
| select.y = mid(select.y,0,31) | |
| -- ok selects hovered | |
| if ok and hovered then | |
| sfx(30, 3) | |
| if hovered.unit then | |
| selected = hovered | |
| elseif hovered.city then | |
| structure, selected = hovered | |
| end | |
| end | |
| end | |
| end | |
| hovered = o_get(units, select) | |
| or o_get(cities, select) | |
| end | |
| function _draw() | |
| cls "" | |
| camera(pan_x, pan_y) | |
| -- map with fog | |
| pal_map(fog_pal) | |
| map(0,0,0,0,32,32) | |
| pal "" | |
| map(64,0,0,0,32,32) | |
| -- | |
| -- range indicator | |
| if selected then | |
| range = unit_range(selected) | |
| flash(5, 13) | |
| for c, pair in pairs(range) do | |
| spr(53, o_grid(pair)) | |
| end | |
| pal "" | |
| end | |
| -- cursor line | |
| if selected then | |
| pal(7, 8) | |
| cell_filter = abs | |
| draw_line(selected, path, 8) | |
| end | |
| foreach(supply, supply_draw) | |
| if phase=="action" | |
| or phase=="supply" then | |
| camera(pan_x, | |
| pan_y + pulse(16,0,1)) | |
| foreach(units, draw_unit) | |
| camera(pan_x, pan_y) | |
| flash(6, 7) | |
| spr(52, o_grid(select)) | |
| pal "" | |
| end | |
| camera "" | |
| if hovered | |
| and fog_check(hovered) | |
| then | |
| rectfill(0, 120, 128, 128, 0) | |
| color(7) | |
| --print("mov "..hovered.move, | |
| -- 1, 122) | |
| end | |
| if phase == "switch" then | |
| prompt("pass to player " | |
| .. (viewer + 1)) | |
| elseif phase == "supply" then | |
| prompt "supply armies" | |
| end | |
| -- city ui | |
| if structure then | |
| city = structure | |
| pal "" | |
| rectfill( 0, 8, | |
| 128, 82, 0) | |
| pal_map(fac_pal[1]) | |
| for i=0,3 do | |
| unit = city.units[i+1] | |
| x = 6 + (i%2) * 43 | |
| y = 14 + flr(i/2) * 25 | |
| rect(x-2, y-2, | |
| x+34, y+17, | |
| pulse(8, 2, 7)) | |
| if unit then | |
| portrait(unit.vehicle, | |
| x, y) | |
| portrait(unit.upgrade, | |
| x+17, y) | |
| end | |
| end | |
| for i=0,7 do | |
| portrait(city.store[i+1], | |
| 90 + (i%2) * 17, | |
| 12 + flr(i/2) * 17, | |
| 106) | |
| end | |
| spend = 4 | |
| for i=0,17 do | |
| x = 4 + (i%9) * 9 | |
| y = 62 + flr(i/9) * 9 | |
| a = i < city.supply | |
| b = i < city.supply - spend | |
| spr(pulse(16, a, b) | |
| and 54 or 55, x, y) | |
| end | |
| end | |
| print(debug, 0, 0) | |
| end | |
| -- | |
| function prompt(s) | |
| y = select.y < 30 and 112 or 8 | |
| rectfill(8, y, | |
| 120, y+7, 0) | |
| color(7) | |
| print(s, 9, y+1) | |
| end | |
| function fog_clear(see) | |
| for x=0,63 do | |
| for y=0,63 do | |
| fog_reveal(x, y, see) | |
| end | |
| end | |
| end | |
| function fog_reveal(x, y, see) | |
| mset(x+64, y, mget(x, y)*see) | |
| end | |
| function fog_check(o) | |
| return mget(o.x+64, o.y) > 0 | |
| end | |
| -- | |
| -- players | |
| function supply_draw(supply) | |
| flash(7, 6) | |
| draw_line(supply, supply) | |
| end | |
| -- | |
| -- units + cities | |
| function make_city(x, y) | |
| city = { | |
| city = true, | |
| x = x, | |
| y = y, | |
| units = {}, | |
| store = { v_apc, u_mortar }, | |
| supply = 0, | |
| } | |
| add(cities, city) | |
| o_add(cities, city) | |
| return city | |
| end | |
| function make_unit(owner, | |
| x, y, | |
| vehicle, | |
| upgrade) | |
| unit = { | |
| unit = true, | |
| owner = owner, | |
| x = x, | |
| y = y, | |
| at = 0, | |
| ad = 0, | |
| supplied = true, | |
| vehicle = vehicle, | |
| upgrade = upgrade or u_none, | |
| } | |
| add(units, unit) | |
| o_add(units, unit) | |
| return unit | |
| end | |
| function stat_supply(unit) | |
| return unit.supplied | |
| or unit.supplied | |
| or unit.upgrade.supplied | |
| end | |
| function stat_move(unit) | |
| return stat_supply(unit) | |
| and unit.vehicle.movement | |
| + unit.upgrade.movement | |
| or 0 | |
| end | |
| function stat_vision(unit) | |
| return stat_supply(unit) | |
| and unit.vehicle.vision | |
| + unit.upgrade.vision | |
| or 0 | |
| end | |
| function draw_unit(unit) | |
| pal_map(fac_pal[unit.owner]) | |
| if not fog_check(unit) then | |
| if unit.owner == viewer then | |
| pal_map(fog_pal) | |
| else | |
| return | |
| end | |
| end | |
| x, y = o_grid(unit) | |
| spr(unit.vehicle.move_gfx | |
| + unit.ad, | |
| move(x, y, | |
| bxor(unit.ad,1), | |
| max(unit.at-timer, | |
| 0) * 2)) | |
| end | |
| function portrait(item, | |
| x, y, | |
| back) | |
| if back then | |
| spr(back, x, y, 2, 2) | |
| end | |
| if item and item.portrait then | |
| spr(item.portrait,x,y,2,2) | |
| end | |
| end | |
| function unit_pass(u, o) | |
| tile = mget(pos(o)) | |
| wall = fget(tile, 7) | |
| unit = cell_filter(o) | |
| and o_get(units, o) | |
| return (not unit or u == unit) | |
| and not wall | |
| end | |
| function unit_move(unit, d) | |
| cell_filter = abs | |
| if unit_pass(unit, | |
| o_move(unit, d)) | |
| then | |
| unit.ad = d | |
| unit.at = timer + 4 | |
| o_del(units, unit) | |
| o_imove(unit, d) | |
| o_add(units, unit) | |
| return true | |
| end | |
| end | |
| function unit_range(unit) | |
| dists = {} | |
| check = { select } | |
| found = {} | |
| limit = stat_move(unit) | |
| - #path | |
| repeat | |
| prev = bite(check) | |
| l = o_get(dists, prev, 0) + 1 | |
| for d=0,3 do | |
| pair = o_copy(prev) | |
| pair.d = l | |
| o_imove(pair, d) | |
| if l < o_get(dists, | |
| pair, | |
| 999) | |
| and l <= limit | |
| and unit_pass(unit, pair) | |
| then | |
| add(check, pair) | |
| o_add(found, pair) | |
| o_add(dists, pair, l) | |
| end | |
| end | |
| until #check == 0 | |
| return found | |
| end | |
| -- | |
| -- utility | |
| function bite(t) | |
| v = t[1] | |
| del(t, v) | |
| return v | |
| end | |
| function pop(t) | |
| v, t[#t] = t[#t] | |
| return v | |
| end | |
| function flash(a, b) | |
| pal(7, pulse(8, a, b)) | |
| end | |
| function pulse(p, a, b) | |
| return timer % p < p/2 and a | |
| or b | |
| end | |
| function o_make(x, y) | |
| return { x = x or 0, | |
| y = y or 0 } | |
| end | |
| function o_coord(o) | |
| return o.x .. "," .. o.y | |
| end | |
| function o_grid(o) | |
| return o.x * 8, o.y * 8 | |
| end | |
| function o_add(t, o, v) | |
| t[o] = v or o | |
| t[o_coord(o)] = v or o | |
| end | |
| function o_get(t, o, v) | |
| return t[o_coord(o)] or v | |
| end | |
| function o_del(t, o) | |
| t[o] = nil | |
| t[o_coord(o)] = nil | |
| end | |
| function o_copy(o) | |
| return o_make(pos(o)) | |
| end | |
| function pos(o) | |
| return o.x, o.y | |
| end | |
| function inv(d) | |
| return d%2 == 0 and d+1 or d-1 | |
| end | |
| function move(x, y, d, l) | |
| l = l or 1 | |
| if (d == 0) x -= l | |
| if (d == 1) x += l | |
| if (d == 2) y -= l | |
| if (d == 3) y += l | |
| return x, y | |
| end | |
| function o_move(o, d, l) | |
| return o_make(move(o.x, o.y, | |
| d, l)) | |
| end | |
| function o_imove(o, d, l) | |
| o.x, o.y = move(o.x, o.y, d, l) | |
| return pos(o) | |
| end | |
| function arrow() | |
| for i=0,3 do | |
| if (btnp(i)) return i | |
| end | |
| return -1 | |
| end | |
| function dist(sx, sy, | |
| ex, ey) | |
| return abs(sx - ex) | |
| + abs(sy - ey) | |
| end | |
| function forradius(o, r, action) | |
| cx, cy = pos(o) | |
| for x=cx-r,cx+r do | |
| for y=cy-r,cy+r do | |
| d = dist(x, y, cx, cy) | |
| if (d <= r) action(x, y, d) | |
| end | |
| end | |
| end | |
| function pal_map(m) | |
| for i=1,#m,2 do | |
| pal(m[i], m[i+1]) | |
| end | |
| end | |
| function draw_line(o, path) | |
| for d in all(path) do | |
| if cell_filter(o) then | |
| spr(48+d, o_grid(o)) | |
| end | |
| o = o_move(o, d) | |
| if cell_filter(o) then | |
| spr(48+inv(d), o_grid(o)) | |
| end | |
| end | |
| end | |
| function path_add(path, d) | |
| last = path[#path] or -1 | |
| if d == inv(last) then | |
| pop(path) | |
| else | |
| add(path, d) | |
| end | |
| end | |
| function path_short(path) | |
| seen = {} | |
| o = o_make() | |
| o_add(seen, o, 1) | |
| for i=1,#path do | |
| o_imove(o, path[i]) | |
| j = o_get(seen, o) | |
| if j then | |
| for v=j,#path do | |
| path[v] = nil | |
| end | |
| else | |
| o_add(seen, o, i + 1) | |
| end | |
| end | |
| return seen | |
| end | |
| -- |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment