refactor(packages): 0.R5 - the rest of the lazy starts are defaults - hints' rail (sized by hints_config), lab's CRC table, rpg's crafting / items / inventory / quests / dialog, shooter's weapons, prefs, and npc's and gameplay's empty ensures gone; gameplay's faction table sits beside its state, since a default names only what is declared before it; --tighten over their tests and examples
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
9e4f4edb92
commit
f516148e46
15 changed files with 73 additions and 169 deletions
|
|
@ -10,20 +10,12 @@ const CRAFT_MAX: int = 128
|
|||
const CRAFT_ING_MAX: int = 512
|
||||
|
||||
|
||||
function craft_ensure(rpg_st: mut RpgState) -> void {
|
||||
if rpg_st.recipe_reg == null {
|
||||
rpg_st.recipe_reg = Dict.new()
|
||||
rpg_st.recipe_out = pointers(CRAFT_MAX); rpg_st.recipe_outqty = words(CRAFT_MAX)
|
||||
rpg_st.ing_rid = words(CRAFT_ING_MAX); rpg_st.ing_name = pointers(CRAFT_ING_MAX); rpg_st.ing_qty = words(CRAFT_ING_MAX)
|
||||
}
|
||||
}
|
||||
|
||||
event cancellable CraftRequested { e: int = 0, recipe: int = 0 }
|
||||
event CraftCompleted { e: int = 0, recipe: int = 0 }
|
||||
|
||||
# Craft.recipe(name, out_item, out_qty) — declare a recipe; returns its id.
|
||||
@Namespace(Craft) function craft_recipe(rpg_st: mut RpgState, name: pointer, out_item: pointer, out_qty: int) -> int {
|
||||
craft_ensure(rpg_st)
|
||||
if rpg_st.recipe_n >= CRAFT_MAX { return -1 }
|
||||
let id = rpg_st.recipe_n
|
||||
rpg_st.recipe_out[id] = out_item; rpg_st.recipe_outqty[id] = out_qty
|
||||
|
|
@ -31,10 +23,9 @@ event CraftCompleted { e: int = 0, recipe: int = 0 }
|
|||
Dict.set(rpg_st.recipe_reg, name, id)
|
||||
return id
|
||||
}
|
||||
@Namespace(Craft) function craft_id(rpg_st: mut RpgState, name: pointer) -> int { craft_ensure(rpg_st); return Dict.get_or(rpg_st.recipe_reg, name, -1) }
|
||||
@Namespace(Craft) function craft_id(rpg_st: mut RpgState, name: pointer) -> int { return Dict.get_or(rpg_st.recipe_reg, name, -1) }
|
||||
# Craft.ingredient(recipe_name, item, qty) — add an ingredient requirement.
|
||||
@Namespace(Craft) function craft_ingredient(rpg_st: mut RpgState, recipe_name: pointer, item: pointer, qty: int) -> void {
|
||||
craft_ensure(rpg_st)
|
||||
let rid = craft_id(rpg_st, recipe_name)
|
||||
if rid < 0 { return }
|
||||
if rpg_st.ing_n >= CRAFT_ING_MAX { return }
|
||||
|
|
@ -44,7 +35,6 @@ event CraftCompleted { e: int = 0, recipe: int = 0 }
|
|||
|
||||
# Craft.can(e, recipe_name) — does the owner hold every ingredient?
|
||||
@Namespace(Craft) function craft_can(rpg_st: mut RpgState, e: int, recipe_name: pointer) -> int {
|
||||
craft_ensure(rpg_st)
|
||||
let rid = craft_id(rpg_st, recipe_name)
|
||||
if rid < 0 { return 0 }
|
||||
var i = 0
|
||||
|
|
@ -59,7 +49,6 @@ event CraftCompleted { e: int = 0, recipe: int = 0 }
|
|||
|
||||
# Craft.make(e, recipe_name) — consume ingredients + produce output; 1 on success.
|
||||
@Namespace(Craft) function craft_make(rpg_st: mut RpgState, e: int, recipe_name: pointer) -> int {
|
||||
craft_ensure(rpg_st)
|
||||
let rid = craft_id(rpg_st, recipe_name)
|
||||
if rid < 0 { return 0 }
|
||||
if craft_can(rpg_st, e, recipe_name) == 0 { return 0 }
|
||||
|
|
|
|||
|
|
@ -9,14 +9,6 @@ const DLG_NODE_MAX: int = 512
|
|||
const DLG_CHOICE_MAX: int = 1024
|
||||
|
||||
|
||||
function dlg_ensure(rpg_st: mut RpgState) -> void {
|
||||
if rpg_st.dlg_reg == null {
|
||||
rpg_st.dlg_reg = Dict.new()
|
||||
rpg_st.dlg_tree_start = words(DLG_TREE_MAX)
|
||||
rpg_st.dlg_node_tree = words(DLG_NODE_MAX); rpg_st.dlg_node_text = pointers(DLG_NODE_MAX)
|
||||
rpg_st.dlg_choice_node = words(DLG_CHOICE_MAX); rpg_st.dlg_choice_label = pointers(DLG_CHOICE_MAX); rpg_st.dlg_choice_next = words(DLG_CHOICE_MAX)
|
||||
}
|
||||
}
|
||||
|
||||
property Dialog { tree: int = 0, node: int = 0, active: int = 0 }
|
||||
|
||||
|
|
@ -27,7 +19,6 @@ event DialogEnded { e: int = 0 }
|
|||
|
||||
# Dialog.tree(name) — register (or fetch) a tree id.
|
||||
@Namespace(Dialog) function dialog_tree(rpg_st: mut RpgState, name: pointer) -> int {
|
||||
dlg_ensure(rpg_st)
|
||||
let ex = Dict.get_or(rpg_st.dlg_reg, name, -1)
|
||||
if ex >= 0 { return ex }
|
||||
if rpg_st.dlg_tree_n >= DLG_TREE_MAX { return -1 }
|
||||
|
|
@ -40,7 +31,6 @@ event DialogEnded { e: int = 0 }
|
|||
# Dialog.node(tree_name, text) — add a line node; the first node added to a tree is
|
||||
# its entry point. Returns the node id.
|
||||
@Namespace(Dialog) function dialog_node(rpg_st: mut RpgState, tree_name: pointer, text: pointer) -> int {
|
||||
dlg_ensure(rpg_st)
|
||||
let tid = dialog_tree(rpg_st, tree_name)
|
||||
if tid < 0 { return -1 }
|
||||
if rpg_st.dlg_node_n >= DLG_NODE_MAX { return -1 }
|
||||
|
|
@ -52,7 +42,6 @@ event DialogEnded { e: int = 0 }
|
|||
}
|
||||
# Dialog.choice(node, label, next_node) — add a branch (next_node -1 ends).
|
||||
@Namespace(Dialog) function dialog_choice(rpg_st: mut RpgState, node: int, label: pointer, next_node: int) -> int {
|
||||
dlg_ensure(rpg_st)
|
||||
if rpg_st.dlg_choice_n >= DLG_CHOICE_MAX { return -1 }
|
||||
let id = rpg_st.dlg_choice_n
|
||||
rpg_st.dlg_choice_node[id] = node; rpg_st.dlg_choice_label[id] = label; rpg_st.dlg_choice_next[id] = next_node
|
||||
|
|
@ -71,7 +60,6 @@ function dlg_set(e: int, name: pointer, v: int) -> void {
|
|||
|
||||
# Dialog.start(e, tree_name) — open the tree on a speaker (DialogStarted + Line).
|
||||
@Namespace(Dialog) function dialog_start(rpg_st: mut RpgState, e: int, tree_name: pointer) -> void {
|
||||
dlg_ensure(rpg_st)
|
||||
let tid = dialog_tree(rpg_st, tree_name)
|
||||
if tid < 0 { return }
|
||||
dlg_set(e, "tree", tid)
|
||||
|
|
@ -87,7 +75,6 @@ function dlg_set(e: int, name: pointer, v: int) -> void {
|
|||
}
|
||||
# Dialog.count(e) — number of choices at the current node.
|
||||
@Namespace(Dialog) function dialog_count(rpg_st: mut RpgState, e: int) -> int {
|
||||
dlg_ensure(rpg_st)
|
||||
if dlg_get(e, "active") == 0 { return 0 }
|
||||
let node = dlg_get(e, "node")
|
||||
var n = 0; var i = 0
|
||||
|
|
@ -96,7 +83,6 @@ function dlg_set(e: int, name: pointer, v: int) -> void {
|
|||
}
|
||||
# Dialog.choose(e, i) — take the i-th choice (veto-able); advance or end.
|
||||
@Namespace(Dialog) function dialog_choose(rpg_st: mut RpgState, e: int, idx: int) -> int {
|
||||
dlg_ensure(rpg_st)
|
||||
if dlg_get(e, "active") == 0 { return 0 }
|
||||
let node = dlg_get(e, "node")
|
||||
var seen = 0; var i = 0; var pick = -1
|
||||
|
|
|
|||
|
|
@ -11,52 +11,45 @@ const INV_MAX: int = 256
|
|||
|
||||
# ---- item registry --------------------------------------------------------
|
||||
state RpgState {
|
||||
recipe_reg: Dict = null # recipe name -> id
|
||||
recipe_reg: Dict = Dict.new() # recipe name -> id
|
||||
recipe_n: int = 0
|
||||
recipe_out: pointers = null # output item name
|
||||
recipe_outqty: words = null
|
||||
recipe_out: pointers = pointers(CRAFT_MAX) # output item name
|
||||
recipe_outqty: words = words(CRAFT_MAX)
|
||||
ing_n: int = 0
|
||||
ing_rid: words = null # owning recipe id
|
||||
ing_name: pointers = null # ingredient item name
|
||||
ing_qty: words = null
|
||||
dlg_reg: Dict = null # tree name -> tree id
|
||||
ing_rid: words = words(CRAFT_ING_MAX) # owning recipe id
|
||||
ing_name: pointers = pointers(CRAFT_ING_MAX) # ingredient item name
|
||||
ing_qty: words = words(CRAFT_ING_MAX)
|
||||
dlg_reg: Dict = Dict.new() # tree name -> tree id
|
||||
dlg_tree_n: int = 0
|
||||
dlg_tree_start: words = null # first node id per tree
|
||||
dlg_tree_start: words = words(DLG_TREE_MAX) # first node id per tree
|
||||
dlg_node_n: int = 0
|
||||
dlg_node_tree: words = null
|
||||
dlg_node_text: pointers = null
|
||||
dlg_node_tree: words = words(DLG_NODE_MAX)
|
||||
dlg_node_text: pointers = pointers(DLG_NODE_MAX)
|
||||
dlg_choice_n: int = 0
|
||||
dlg_choice_node: words = null # owning node
|
||||
dlg_choice_label: pointers = null
|
||||
dlg_choice_next: words = null # next node id, or -1 to end
|
||||
item_reg: Dict = null
|
||||
dlg_choice_node: words = words(DLG_CHOICE_MAX) # owning node
|
||||
dlg_choice_label: pointers = pointers(DLG_CHOICE_MAX)
|
||||
dlg_choice_next: words = words(DLG_CHOICE_MAX) # next node id, or -1 to end
|
||||
item_reg: Dict = Dict.new()
|
||||
item_n: int = 0
|
||||
item_stackmax: words = null
|
||||
item_weight: words = null
|
||||
item_value: words = null
|
||||
inv_counts: Dict = null
|
||||
quest_reg: Dict = null # quest name -> id
|
||||
item_stackmax: words = words(INV_MAX)
|
||||
item_weight: words = words(INV_MAX)
|
||||
item_value: words = words(INV_MAX)
|
||||
inv_counts: Dict = Dict.new()
|
||||
quest_reg: Dict = Dict.new() # quest name -> id
|
||||
quest_n: int = 0
|
||||
quest_state: words = null
|
||||
quest_state: words = words(QUEST_MAX)
|
||||
obj_n: int = 0
|
||||
obj_qid: words = null # owning quest id
|
||||
obj_kind: words = null
|
||||
obj_target: words = null # a target id/tag (kind-specific; 0 = any)
|
||||
obj_need: words = null
|
||||
obj_have: words = null
|
||||
quest_flags: Dict = null # global flag store
|
||||
obj_qid: words = words(OBJ_MAX) # owning quest id
|
||||
obj_kind: words = words(OBJ_MAX)
|
||||
obj_target: words = words(OBJ_MAX) # a target id/tag (kind-specific; 0 = any)
|
||||
obj_need: words = words(OBJ_MAX)
|
||||
obj_have: words = words(OBJ_MAX)
|
||||
quest_flags: Dict = Dict.new() # global flag store
|
||||
}
|
||||
|
||||
function item_ensure(rpg_st: mut RpgState) -> void {
|
||||
if rpg_st.item_reg == null {
|
||||
rpg_st.item_reg = Dict.new()
|
||||
rpg_st.item_stackmax = words(INV_MAX); rpg_st.item_weight = words(INV_MAX); rpg_st.item_value = words(INV_MAX)
|
||||
}
|
||||
}
|
||||
|
||||
# Item.def(name, stack_max, weight, value) — register an item template. Returns id.
|
||||
@Namespace(Item) function item_def(rpg_st: mut RpgState, name: pointer, stack_max: int, weight: int, value: int) -> int {
|
||||
item_ensure(rpg_st)
|
||||
if rpg_st.item_n >= INV_MAX { return -1 }
|
||||
let id = rpg_st.item_n
|
||||
rpg_st.item_stackmax[id] = stack_max; rpg_st.item_weight[id] = weight; rpg_st.item_value[id] = value
|
||||
|
|
@ -64,7 +57,7 @@ function item_ensure(rpg_st: mut RpgState) -> void {
|
|||
Dict.set(rpg_st.item_reg, name, id)
|
||||
return id
|
||||
}
|
||||
@Namespace(Item) function item_id(rpg_st: mut RpgState, name: pointer) -> int { item_ensure(rpg_st); return Dict.get_or(rpg_st.item_reg, name, -1) }
|
||||
@Namespace(Item) function item_id(rpg_st: mut RpgState, name: pointer) -> int { return Dict.get_or(rpg_st.item_reg, name, -1) }
|
||||
@Namespace(Item) function item_value_of(rpg_st: mut RpgState, name: pointer) -> int {
|
||||
let id = item_id(rpg_st, name); if id < 0 { return 0 }
|
||||
return rpg_st.item_value[id]
|
||||
|
|
@ -73,7 +66,6 @@ function item_ensure(rpg_st: mut RpgState) -> void {
|
|||
# ---- per-owner counts -----------------------------------------------------
|
||||
property Inventory { gold: int = 0, weight_max: int = 0, slots: int = 0 }
|
||||
|
||||
function inv_ensure(rpg_st: mut RpgState) -> void { if rpg_st.inv_counts == null { rpg_st.inv_counts = Dict.new() } }
|
||||
function inv_key(e: int, name: pointer) -> pointer { return `{e}/{name}` }
|
||||
|
||||
event ItemAdded { e: int = 0, item: int = 0, qty: int = 0 } # item = registry id
|
||||
|
|
@ -82,14 +74,12 @@ event cancellable ItemUse { e: int = 0, item: int = 0 } # veto a use (
|
|||
|
||||
# Inventory.add(e, name, n) — add n of an item; emits ItemAdded.
|
||||
@Namespace(Inventory) function inventory_add(rpg_st: mut RpgState, e: int, name: pointer, n: int) -> void {
|
||||
inv_ensure(rpg_st)
|
||||
let k = inv_key(e, name)
|
||||
Dict.set(rpg_st.inv_counts, k, Dict.get_or(rpg_st.inv_counts, k, 0) + n)
|
||||
emit ItemAdded(e: e, item: item_id(rpg_st, name), qty: n)
|
||||
}
|
||||
# Inventory.count(e, name) — how many the owner holds.
|
||||
@Namespace(Inventory) function inventory_count(rpg_st: mut RpgState, e: int, name: pointer) -> int {
|
||||
inv_ensure(rpg_st)
|
||||
return Dict.get_or(rpg_st.inv_counts, inv_key(e, name), 0)
|
||||
}
|
||||
@Namespace(Inventory) function inventory_has(rpg_st: mut RpgState, e: int, name: pointer) -> int {
|
||||
|
|
@ -98,7 +88,6 @@ event cancellable ItemUse { e: int = 0, item: int = 0 } # veto a use (
|
|||
}
|
||||
# Inventory.remove(e, name, n) — remove up to n; returns 1 if it had enough.
|
||||
@Namespace(Inventory) function inventory_remove(rpg_st: mut RpgState, e: int, name: pointer, n: int) -> int {
|
||||
inv_ensure(rpg_st)
|
||||
let k = inv_key(e, name)
|
||||
let have = Dict.get_or(rpg_st.inv_counts, k, 0)
|
||||
if have < n { return 0 }
|
||||
|
|
|
|||
|
|
@ -15,14 +15,6 @@ const QUEST_MAX: int = 128
|
|||
const OBJ_MAX: int = 512
|
||||
|
||||
|
||||
function quest_ensure(rpg_st: mut RpgState) -> void {
|
||||
if rpg_st.quest_reg == null {
|
||||
rpg_st.quest_reg = Dict.new(); rpg_st.quest_flags = Dict.new()
|
||||
rpg_st.quest_state = words(QUEST_MAX)
|
||||
rpg_st.obj_qid = words(OBJ_MAX); rpg_st.obj_kind = words(OBJ_MAX); rpg_st.obj_target = words(OBJ_MAX)
|
||||
rpg_st.obj_need = words(OBJ_MAX); rpg_st.obj_have = words(OBJ_MAX)
|
||||
}
|
||||
}
|
||||
|
||||
event QuestStarted { quest: int = 0 }
|
||||
event QuestCompleted { quest: int = 0 }
|
||||
|
|
@ -30,7 +22,6 @@ event ObjectiveProgressed { quest: int = 0, objective: int = 0, have: int = 0, n
|
|||
|
||||
# Quest.define(name) — register a quest (state hidden). Returns id.
|
||||
@Namespace(Quest) function quest_define(rpg_st: mut RpgState, name: pointer) -> int {
|
||||
quest_ensure(rpg_st)
|
||||
if rpg_st.quest_n >= QUEST_MAX { return -1 }
|
||||
let id = rpg_st.quest_n
|
||||
rpg_st.quest_state[id] = 0
|
||||
|
|
@ -38,10 +29,9 @@ event ObjectiveProgressed { quest: int = 0, objective: int = 0, have: int = 0, n
|
|||
Dict.set(rpg_st.quest_reg, name, id)
|
||||
return id
|
||||
}
|
||||
@Namespace(Quest) function quest_id(rpg_st: mut RpgState, name: pointer) -> int { quest_ensure(rpg_st); return Dict.get_or(rpg_st.quest_reg, name, -1) }
|
||||
@Namespace(Quest) function quest_id(rpg_st: mut RpgState, name: pointer) -> int { return Dict.get_or(rpg_st.quest_reg, name, -1) }
|
||||
# Quest.objective(quest_name, kind, target, need) — add an objective.
|
||||
@Namespace(Quest) function quest_objective(rpg_st: mut RpgState, quest_name: pointer, kind: int, target: int, need: int) -> int {
|
||||
quest_ensure(rpg_st)
|
||||
let qid = quest_id(rpg_st, quest_name)
|
||||
if qid < 0 { return -1 }
|
||||
if rpg_st.obj_n >= OBJ_MAX { return -1 }
|
||||
|
|
@ -53,14 +43,12 @@ event ObjectiveProgressed { quest: int = 0, objective: int = 0, have: int = 0, n
|
|||
}
|
||||
# Quest.start(name) — activate a quest (emits QuestStarted).
|
||||
@Namespace(Quest) function quest_start(rpg_st: mut RpgState, name: pointer) -> void {
|
||||
quest_ensure(rpg_st)
|
||||
let qid = quest_id(rpg_st, name)
|
||||
if qid < 0 { return }
|
||||
rpg_st.quest_state[qid] = 2
|
||||
emit QuestStarted(quest: qid)
|
||||
}
|
||||
@Namespace(Quest) function quest_state_of(rpg_st: mut RpgState, name: pointer) -> int {
|
||||
quest_ensure(rpg_st)
|
||||
let qid = quest_id(rpg_st, name)
|
||||
if qid < 0 { return -1 }
|
||||
return rpg_st.quest_state[qid]
|
||||
|
|
@ -80,7 +68,6 @@ function quest_all_done(rpg_st: RpgState, qid: int) -> int {
|
|||
# quest's matching objectives tick up (target 0 on the objective = "any"); a quest
|
||||
# whose objectives are all met auto-completes.
|
||||
@Namespace(Quest) function quest_notify(rpg_st: mut RpgState, kind: int, target: int, amount: int) -> void {
|
||||
quest_ensure(rpg_st)
|
||||
var i = 0
|
||||
while i < rpg_st.obj_n {
|
||||
let qid = rpg_st.obj_qid[i]
|
||||
|
|
@ -104,5 +91,5 @@ function quest_all_done(rpg_st: RpgState, qid: int) -> int {
|
|||
}
|
||||
|
||||
# ---- global flag store (branching / world state) --------------------------
|
||||
@Namespace(Quest) function quest_flag(rpg_st: mut RpgState, name: pointer, value: int) -> void { quest_ensure(rpg_st); Dict.set(rpg_st.quest_flags, name, value) }
|
||||
@Namespace(Quest) function quest_flag_get(rpg_st: mut RpgState, name: pointer) -> int { quest_ensure(rpg_st); return Dict.get_or(rpg_st.quest_flags, name, 0) }
|
||||
@Namespace(Quest) function quest_flag(rpg_st: mut RpgState, name: pointer, value: int) -> void { Dict.set(rpg_st.quest_flags, name, value) }
|
||||
@Namespace(Quest) function quest_flag_get(rpg_st: mut RpgState, name: pointer) -> int { return Dict.get_or(rpg_st.quest_flags, name, 0) }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue