102 lines
3.8 KiB
Text
102 lines
3.8 KiB
Text
# pins.ludic - the player's own marks: a note at a place, with a symbol, a colour, the day it was
|
|
# made and a name. It does not route anyone and it does not move. One may be open (on the map's
|
|
# legend) and one followed (on the compass); the symbol last chosen is the next mark's.
|
|
export property MinimapPin {
|
|
x: float = 0.0
|
|
z: float = 0.0
|
|
icon: int = 0 # 0 .. symbols - 1, the game's
|
|
colour: int = 0 # 0 .. colours - 1, the game's
|
|
day: int = 1
|
|
label: string = ""
|
|
}
|
|
|
|
|
|
export function minimap_config_pins(minimap_st: mut MinimapState, max: int, symbols: int, colours: int) -> void {
|
|
minimap_st.mm_pin_max = Math.max(max, 1)
|
|
minimap_st.mm_symbols = Math.max(symbols, 1)
|
|
minimap_st.mm_colours = Math.max(colours, 1)
|
|
minimap_pins_clear(minimap_st)
|
|
}
|
|
|
|
export function minimap_pins_clear(minimap_st: mut MinimapState) -> void {
|
|
if minimap_st.mm_pins == null {
|
|
@alloc_ok("once: the marks' list, cleared after")
|
|
minimap_st.mm_pins = new []MinimapPin
|
|
} else { List.clear(minimap_st.mm_pins) }
|
|
minimap_st.mm_open = -1
|
|
minimap_st.mm_followed = -1
|
|
minimap_st.mm_last = 0
|
|
minimap_st.mm_placing = false
|
|
}
|
|
|
|
export function minimap_pin_count(minimap_st: MinimapState) -> int {
|
|
if minimap_st.mm_pins == null { return 0 }
|
|
return len(minimap_st.mm_pins)
|
|
}
|
|
|
|
export function minimap_pin_max(minimap_st: MinimapState) -> int { return minimap_st.mm_pin_max }
|
|
export function minimap_pin_full(minimap_st: MinimapState) -> bool { return minimap_pin_count(minimap_st) >= minimap_st.mm_pin_max }
|
|
|
|
# a mark at (x, z) made today, with the colour 0; -1 when the map holds all it will
|
|
export function minimap_pin_add(minimap_st: mut MinimapState, x: float, z: float, icon: int, label: string) -> int {
|
|
if minimap_st.mm_pins == null { minimap_pins_clear(minimap_st) }
|
|
if minimap_pin_full(minimap_st) { return -1 }
|
|
@alloc_ok("a mark put down: kept, and the map holds at most its most")
|
|
let p = new MinimapPin
|
|
p.x = x
|
|
p.z = z
|
|
p.icon = Math.clamp(icon, 0, minimap_st.mm_symbols - 1)
|
|
p.day = MinimapWorld.day()
|
|
p.label = label
|
|
push(minimap_st.mm_pins, p)
|
|
minimap_st.mm_last = p.icon
|
|
return len(minimap_st.mm_pins) - 1
|
|
}
|
|
|
|
# as saved: everything given, the symbol last chosen left alone
|
|
export function minimap_pin_put(minimap_st: mut MinimapState, x: float, z: float, icon: int, colour: int, day: int, label: string) -> int {
|
|
if minimap_st.mm_pins == null { minimap_pins_clear(minimap_st) }
|
|
if minimap_pin_full(minimap_st) { return -1 }
|
|
@alloc_ok("a mark put down: kept, and the map holds at most its most")
|
|
let p = new MinimapPin
|
|
p.x = x
|
|
p.z = z
|
|
p.icon = Math.clamp(icon, 0, minimap_st.mm_symbols - 1)
|
|
p.colour = Math.clamp(colour, 0, minimap_st.mm_colours - 1)
|
|
p.day = day
|
|
p.label = label
|
|
push(minimap_st.mm_pins, p)
|
|
return len(minimap_st.mm_pins) - 1
|
|
}
|
|
|
|
# the i-th mark, or an empty one past the end
|
|
export function minimap_pin(minimap_st: MinimapState, i: int) -> MinimapPin {
|
|
if i < 0 or i >= minimap_pin_count(minimap_st) { return minimap_st.mm_none }
|
|
return minimap_st.mm_pins[i]
|
|
}
|
|
|
|
# the nearest n marks within `within` of (x, z), nearest first, leaving out the followed one
|
|
export function minimap_pins_near(minimap_st: mut MinimapState, x: float, z: float, n: int, within: float) -> []int {
|
|
let out = minimap_st.mm_near
|
|
List.clear(out)
|
|
for k in 0 .. n {
|
|
var best = -1
|
|
var bd = within * within
|
|
for i in 0 .. minimap_pin_count(minimap_st) {
|
|
if i == minimap_st.mm_followed or mm_has(out, i) { continue }
|
|
let d = (minimap_st.mm_pins[i].x - x) * (minimap_st.mm_pins[i].x - x) + (minimap_st.mm_pins[i].z - z) * (minimap_st.mm_pins[i].z - z)
|
|
if d < bd {
|
|
bd = d
|
|
best = i
|
|
}
|
|
}
|
|
if best < 0 { break }
|
|
push(out, best)
|
|
}
|
|
return out
|
|
}
|
|
|
|
function mm_has(xs: []int, v: int) -> bool {
|
|
for i in 0 .. len(xs) { if xs[i] == v { return true } }
|
|
return false
|
|
}
|