extends RefCounted ## A dedicated server's rules (docs/MULTIPLAYER_PLAN.md ยง4): who may use and ## take down whose things, whether players can hurt each other, what death ## costs, and how hard the island is. All checked on the server; single ## player has no rules (everything is yours). ## ## Pieces remember who placed them (meta "owner" = player id, "owner_name"). ## Pieces with no owner (placed before M2.6, or by the world) are anyone's. const DIFFICULTY := { # hunger and diet drain, animal and wolf damage, extra wolves in the pack "easy": {"drain": 0.75, "damage": 0.7, "pack": -1}, "normal": {"drain": 1.0, "damage": 1.0, "pack": 0}, "hard": {"drain": 1.3, "damage": 1.4, "pack": 1}, } static func _cfg() -> RefCounted: var net: Node = (Engine.get_main_loop() as SceneTree).root.get_node_or_null("Net") return net.config if net != null and net.is_server() else null static func v(k: String) -> Variant: var c := _cfg() return c.v(k) if c != null else null static func owner_of(piece: Node) -> String: return String(piece.get_meta("owner", "")) if piece != null else "" static func owner_name(piece: Node) -> String: return String(piece.get_meta("owner_name", "someone")) ## Whether player `id` may open, take from or use `piece` (chests, doors, ## beds, graves), going by `locks`. static func may_use(id: String, piece: Node) -> bool: var c := _cfg() var owner := owner_of(piece) if c == null or owner.is_empty() or owner == id: return true match String(c.v("locks")): "off": return true "owner_and_friends": return c.is_friend(owner, id) return false # "owner" ## Why `id` can't use `piece` ("" = they can). static func use_problem(id: String, piece: Node) -> String: if may_use(id, piece): return "" var what: String = piece.display_name().to_lower() if piece.has_method("display_name") else "that" if piece.item_id == "grave": return "That's %s's grave" % owner_name(piece) return "That %s is %s's (locked)" % [what, owner_name(piece)] ## Taking a piece down: your own, anything you're allowed to use (friends, ## or locks off), or anyone's if raiding is on. static func dismantle_problem(id: String, piece: Node) -> String: if may_use(id, piece) or bool(v("raiding")): return "" return "That's %s's, and raiding is off on this server" % owner_name(piece) static func pvp() -> bool: return bool(v("pvp")) static func death_penalty() -> String: var d: Variant = v("death_penalty") return String(d) if d != null else "grave" static func difficulty(k: String) -> float: var d: Variant = v("difficulty") return float(DIFFICULTY.get(String(d) if d != null else "normal", DIFFICULTY.normal)[k]) ## How fast food rots: "normal", "slow" (half speed) or "off". static func rot() -> String: var r: Variant = v("rot") return String(r) if r != null else "normal" static func grace_days() -> int: var g: Variant = v("wolf_grace_days") return clampi(int(g), 0, 10) if g != null else 3