İlk commit: Stepstead Godot istemci (4.6 Mobile)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
jts 2026-07-11 11:31:35 +03:00
commit 6a1706051d
346 changed files with 14415 additions and 0 deletions

281
autoload/game_state.gd Normal file
View file

@ -0,0 +1,281 @@
extends Node
## Oyun durumu — karakter, skill, envanter cache.
signal character_loaded(character: Dictionary)
signal step_balance_changed(new_value: int)
var character: Dictionary = {}
var skills: Array = []
var inventory: Array = []
signal inventory_changed
signal harvest_succeeded(payload: Dictionary)
signal level_up(kind: String, new_level: int) # "skill" veya "character"
signal item_used(payload: Dictionary)
func has_character() -> bool:
return character.has("id")
func load_character() -> Dictionary:
var res: Dictionary = await Api.request("GET", "/character/me", null, true)
if res.ok:
character = res.body
skills = character.get("skills", [])
character_loaded.emit(character)
return res
func create_character(name: String) -> Dictionary:
var res: Dictionary = await Api.request("POST", "/character", {"name": name}, true)
if res.ok:
character = res.body
skills = character.get("skills", [])
character_loaded.emit(character)
return res
func load_inventory() -> Dictionary:
var res: Dictionary = await Api.request("GET", "/world/inventory", null, true)
if res.ok:
inventory = res.body if res.body is Array else []
inventory_changed.emit()
return res
func list_recipes() -> Array:
var res: Dictionary = await Api.request("GET", "/craft/recipes", null, true)
return res.body if res.ok and res.body is Array else []
func craft_recipe(code: String, qty: int = 1) -> Dictionary:
var res: Dictionary = await Api.request("POST", "/craft", {"recipe_code": code, "qty": qty}, true)
if res.ok and res.body is Dictionary:
var b: Dictionary = res.body
character["step_balance"] = b["step_balance"]
character["level"] = b["character_level"]
character["total_xp"] = b.get("total_xp", character.get("total_xp", 0))
for s in skills:
if s.get("skill_name") == b["skill"]:
s["xp"] = s.get("xp", 0) + b["xp_gained"]
s["level"] = b["skill_level"]
break
character_loaded.emit(character)
await load_inventory()
# Toast yeniden kullan
harvest_succeeded.emit({
"item_name": "%dx %s" % [int(b["output_qty"]), b["output_item_name"]],
"xp_gained": b["xp_gained"],
"skill": b["skill"],
})
if b.get("skill_level_up", false):
level_up.emit("skill", b["skill_level"])
if b.get("character_level_up", false):
level_up.emit("character", b["character_level"])
return res
func use_item(item_code: String, qty: int = 1) -> Dictionary:
var res: Dictionary = await Api.request("POST", "/world/use-item",
{"item_code": item_code, "qty": qty}, true)
if res.ok and res.body is Dictionary:
var b: Dictionary = res.body
character["step_balance"] = b["step_balance"]
character_loaded.emit(character)
await load_inventory()
item_used.emit(b)
return res
# --- Lokasyon-graf dünya ---
signal map_loaded(map_data: Dictionary)
signal traveled(payload: Dictionary)
signal event_started(event: Dictionary)
signal event_resolved(result: Dictionary)
var map_data: Dictionary = {}
func load_map() -> Dictionary:
var res: Dictionary = await Api.request("GET", "/world/map", null, true)
if res.ok and res.body is Dictionary:
map_data = res.body
map_loaded.emit(map_data)
var pe: Variant = map_data.get("pending_event")
if pe is Dictionary:
event_started.emit(pe)
return res
func load_location() -> Dictionary:
return await Api.request("GET", "/world/location", null, true)
func travel(to_code: String) -> Dictionary:
var res: Dictionary = await Api.request("POST", "/world/travel", {"to_code": to_code}, true)
if res.ok and res.body is Dictionary:
var b: Dictionary = res.body
character["step_balance"] = b["step_balance"]
character["location_code"] = b["location_code"]
character["location_name"] = b["location_name"]
character_loaded.emit(character)
traveled.emit(b)
var ev: Variant = b.get("event")
if ev is Dictionary:
event_started.emit(ev)
return res
func gather(item_code: String) -> Dictionary:
var res: Dictionary = await Api.request("POST", "/world/gather", {"item_code": item_code}, true)
if res.ok and res.body is Dictionary:
var b: Dictionary = res.body
character["step_balance"] = b["step_balance"]
character["level"] = b["character_level"]
character["total_xp"] = b["total_xp"]
for s in skills:
if s.get("skill_name") == b["skill"]:
s["xp"] = s.get("xp", 0) + b["xp_gained"]
s["level"] = b["skill_level"]
break
character_loaded.emit(character)
await load_inventory()
harvest_succeeded.emit(b) # toast aynı formatı kullanır
if b.get("skill_level_up", false):
level_up.emit("skill", b["skill_level"])
if b.get("character_level_up", false):
level_up.emit("character", b["character_level"])
return res
func resolve_event(choice: int) -> Dictionary:
var res: Dictionary = await Api.request("POST", "/world/event/resolve", {"choice": choice}, true)
if res.ok and res.body is Dictionary:
var b: Dictionary = res.body
character["step_balance"] = b["step_balance"]
if b.has("gold"):
character["gold"] = b["gold"]
character_loaded.emit(character)
await load_inventory()
event_resolved.emit(b)
return res
# --- Pazar (market + vendor) ---
func market_listings(q: String = "", mine: bool = false) -> Array:
var path := "/market/listings?q=%s&mine=%s" % [q.uri_encode(), "true" if mine else "false"]
var res: Dictionary = await Api.request("GET", path, null, true)
return res.body if res.ok and res.body is Array else []
func market_list(item_code: String, qty: int, unit_price: int) -> Dictionary:
var res: Dictionary = await Api.request("POST", "/market/list",
{"item_code": item_code, "qty": qty, "unit_price": unit_price}, true)
if res.ok:
await load_inventory()
return res
func market_buy(listing_id: int, qty: int = 0) -> Dictionary:
var body := {"listing_id": listing_id}
if qty > 0:
body["qty"] = qty
var res: Dictionary = await Api.request("POST", "/market/buy", body, true)
if res.ok and res.body is Dictionary:
character["gold"] = res.body["gold"]
character_loaded.emit(character)
await load_inventory()
return res
func market_cancel(listing_id: int) -> Dictionary:
var res: Dictionary = await Api.request("POST", "/market/cancel", {"listing_id": listing_id}, true)
if res.ok:
await load_inventory()
return res
func vendor_prices() -> Array:
var res: Dictionary = await Api.request("GET", "/market/vendor", null, true)
return res.body if res.ok and res.body is Array else []
func vendor_sell(item_code: String, qty: int) -> Dictionary:
var res: Dictionary = await Api.request("POST", "/market/vendor/sell",
{"item_code": item_code, "qty": qty}, true)
if res.ok and res.body is Dictionary:
character["gold"] = res.body["gold"]
character_loaded.emit(character)
await load_inventory()
return res
func vendor_stock() -> Array:
var res: Dictionary = await Api.request("GET", "/market/vendor/stock", null, true)
return res.body if res.ok and res.body is Array else []
func vendor_buy(item_code: String, qty: int) -> Dictionary:
var res: Dictionary = await Api.request("POST", "/market/vendor/buy",
{"item_code": item_code, "qty": qty}, true)
if res.ok and res.body is Dictionary:
character["gold"] = res.body["gold"]
character_loaded.emit(character)
await load_inventory()
return res
# --- Şehir vendor'ları (şehir haritası) ---
func city_vendors() -> Dictionary:
return await Api.request("GET", "/market/city", null, true)
func npc_shop(npc_id: int) -> Dictionary:
return await Api.request("GET", "/market/vendor/%d/shop" % npc_id, null, true)
func npc_buy(npc_id: int, item_code: String, qty: int) -> Dictionary:
var res: Dictionary = await Api.request("POST", "/market/vendor/%d/buy" % npc_id,
{"item_code": item_code, "qty": qty}, true)
if res.ok and res.body is Dictionary:
character["gold"] = res.body["gold"]
character_loaded.emit(character)
await load_inventory()
return res
func npc_sell(npc_id: int, item_code: String, qty: int) -> Dictionary:
var res: Dictionary = await Api.request("POST", "/market/vendor/%d/sell" % npc_id,
{"item_code": item_code, "qty": qty}, true)
if res.ok and res.body is Dictionary:
character["gold"] = res.body["gold"]
character_loaded.emit(character)
await load_inventory()
return res
# --- Kamp ---
func build_camp() -> Dictionary:
var res: Dictionary = await Api.request("POST", "/world/camp/build", null, true)
if res.ok and res.body is Dictionary:
var b: Dictionary = res.body
character["step_balance"] = b["step_balance"]
character["level"] = b["character_level"]
for s in skills:
if s.get("skill_name") == "construction":
s["xp"] = s.get("xp", 0) + int(b["xp_gained"])
s["level"] = b["skill_level"]
break
character_loaded.emit(character)
await load_inventory()
harvest_succeeded.emit({
"item_name": "⛺ Kamp",
"xp_gained": b["xp_gained"],
"skill": "construction",
})
if b.get("skill_level_up", false):
level_up.emit("skill", b["skill_level"])
if b.get("character_level_up", false):
level_up.emit("character", b["character_level"])
return res
# --- Liderlik ---
func leaderboard(by: String = "steps") -> Dictionary:
return await Api.request("GET", "/leaderboard?by=" + by, null, true)
# --- Günlük hedef + streak ---
signal daily_claimed(result: Dictionary)
func daily_status() -> Dictionary:
return await Api.request("GET", "/world/daily", null, true)
func daily_claim() -> Dictionary:
var res: Dictionary = await Api.request("POST", "/world/daily/claim", null, true)
if res.ok and res.body is Dictionary:
var b: Dictionary = res.body
character["step_balance"] = b["step_balance"]
character["gold"] = b["gold"]
character_loaded.emit(character)
daily_claimed.emit(b)
return res