ludic/packages/ludic.npc/port.ludic
Orkuncakilkaya 19fcf60599 wip(0.S3): packages and examples migrated again from their pre-0.S sources in one run
ludic migrate state packages <every example program> packages/ludic.lab/example/plate.ludic
  1804 vars into 126 states, 64 into lets; 23498 edits in 460 files

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 15:31:34 +03:00

69 lines
3.1 KiB
Text

# port.ludic - what the people ask the place. Unbound: a flat dry field at noon on day one, one
# player at the origin, nobody wanted, every name free, and nothing drawn
export port NpcWorld {
ground: fn(float, float) -> float = fn nw_zero2
water: fn(float, float) -> float = fn nw_dry # the water's surface there
slope: fn(float, float) -> float = fn nw_zero2
allowed: fn(float, float) -> bool = fn nw_yes2 # a person may stop here (not the player's camp)
hour: fn() -> float = fn nw_noon
day: fn() -> int = fn nw_day_one
players: fn() -> int = fn nw_one # player slots
player_on: fn(int) -> bool = fn nw_first
player_x: fn(int) -> float = fn nw_zero1
player_z: fn(int) -> float = fn nw_zero1
want: fn() -> int = fn nw_none # walkers the place wants at this hour
extra: fn() -> int = fn nw_no_kind # a kind to bring out whatever the crowd (-1)
origin_x: fn() -> float = fn nw_zero0 # where anyone is put when nowhere else will do
origin_z: fn() -> float = fn nw_zero0
next_id: fn() -> int = fn nw_next_id
body_of: fn(int) -> int = fn nw_body_of # a look seed's body
taken: fn(string) -> bool = fn nw_free # a name the place already uses
born: fn(NpcPerson) -> void = fn nw_nothing # a new one (or a slot reused): draw it
gone: fn(NpcPerson) -> void = fn nw_nothing # left: stop drawing it
}
# what the story says through them: the words of a line whose `fill` is set ("" when it has nothing
# to say now), and a greeting (a vendor's, when talked to)
export port NpcTalk {
say: fn(NpcPerson, int) -> string = fn nw_silent
greeting: fn(NpcPerson) -> string = fn nw_hello
}
function nw_zero0() -> float { return 0.0 }
function nw_zero1(p: int) -> float { return 0.0 }
function nw_zero2(x: float, z: float) -> float { return 0.0 }
function nw_dry(x: float, z: float) -> float { return -1000.0 }
function nw_yes2(x: float, z: float) -> bool { return true }
function nw_noon() -> float { return 12.0 }
function nw_day_one() -> int { return 1 }
function nw_one() -> int { return 1 }
function nw_first(p: int) -> bool { return p == 0 }
function nw_none() -> int { return 0 }
function nw_no_kind() -> int { return -1 }
function nw_body_of(look: int) -> int { return look % 2 }
function nw_free(n: string) -> bool { return false }
function nw_nothing(p: NpcPerson) -> void { }
function nw_silent(p: NpcPerson, line: int) -> string { return "" }
function nw_hello(p: NpcPerson) -> string { return "" }
function nw_next_id(npc_st: mut NpcState) -> int {
npc_st.nw_ids += 1
return npc_st.nw_ids
}
# the nearest player on and their distance (npc_near_i: -1 when nobody is on)
export function npc_near(npc_st: mut NpcState, x: float, z: float) -> float {
var bd = 1000000.0
npc_st.np_near_i = -1
for i in 0 .. NpcWorld.players() {
if not NpcWorld.player_on(i) { continue }
let d = npc_d(x, z, NpcWorld.player_x(i), NpcWorld.player_z(i))
if d < bd {
bd = d
npc_st.np_near_i = i
}
}
return bd
}
export function npc_near_i(npc_st: NpcState) -> int { return npc_st.np_near_i }