# solo_guild_domain_system.gd —— Metin2 40250 离线单机个人公会领地与专属建筑建造 1:1 # 对照 40250 服务端 guild.cpp, guild_manager.cpp, building.cpp class_name SoloGuildDomainSystem extends RefCounted signal domain_claimed(guild_name: String, cost: int) signal building_constructed(btype: int, bname: String, level: int) signal building_upgraded(btype: int, new_level: int) signal guild_refine_result(success: bool, new_level: int) enum BuildingType { BLACKSMITH = 1, # 公会神兵铁匠 (强化成功率 +10%) ALCHEMIST = 2, # 公会炼金熔炉 (原矿熔炼成功率 70%) GUARDIAN_ALTAR = 3 # 公会守护神坛 (生命 +1500, 经验 +10%) } const DOMAIN_COST := 20000000 # 2000 万金币 const MIN_GUILD_LEVEL := 10 # 公会等级门槛 const BUILDING_BLUEPRINTS: Dictionary = { BuildingType.BLACKSMITH: { "name": "公会神兵铁匠铺", "cost": 10000000, "wood": 100, "stone": 100, "max_level": 3 }, BuildingType.ALCHEMIST: { "name": "公会炼金大师熔炉", "cost": 8000000, "wood": 80, "stone": 80, "max_level": 3 }, BuildingType.GUARDIAN_ALTAR: { "name": "公会守护天龙神坛", "cost": 15000000, "wood": 150, "stone": 150, "max_level": 3 } } var has_domain: bool = false var guild_name: String = "" var guild_level: int = 1 var constructed_buildings: Dictionary = {} # btype -> { "level": int, "name": String } # 开辟专属公会领地 func claim_domain(gname: String, glevel: int, player_data: Dictionary) -> Dictionary: if has_domain: return {"ok": false, "reason": "ALREADY_HAS_DOMAIN", "msg": "你已拥有一片公会领地!"} if glevel < MIN_GUILD_LEVEL: return {"ok": false, "reason": "GUILD_LEVEL_TOO_LOW", "msg": "开辟领地需要公会等级达到 10 级!"} var gold: int = int(player_data.get("gold", 0)) if gold < DOMAIN_COST: return {"ok": false, "reason": "NOT_ENOUGH_GOLD", "msg": "金币不足!需要 20,000,000 金币买下领地地契。"} player_data["gold"] = gold - DOMAIN_COST has_domain = true guild_name = gname guild_level = glevel constructed_buildings.clear() domain_claimed.emit(guild_name, DOMAIN_COST) return { "ok": true, "guild_name": guild_name, "cost": DOMAIN_COST, "remaining_gold": player_data["gold"], "msg": "【%s】公会专属领地落成!城堡旗帜高高飘扬!" % guild_name } # 建造领地建筑 func construct_building(btype: int, player_data: Dictionary) -> Dictionary: if not has_domain: return {"ok": false, "reason": "NO_DOMAIN", "msg": "尚未开辟领地!"} if not BUILDING_BLUEPRINTS.has(btype): return {"ok": false, "reason": "INVALID_BUILDING_TYPE"} if constructed_buildings.has(btype): return {"ok": false, "reason": "ALREADY_CONSTRUCTED", "msg": "该建筑已建造完成!可选择升级。"} var bp = BUILDING_BLUEPRINTS[btype] var gold: int = int(player_data.get("gold", 0)) var cost: int = bp["cost"] if gold < cost: return {"ok": false, "reason": "NOT_ENOUGH_GOLD", "msg": "建造金币不足!需要 %d 金币。" % cost} player_data["gold"] = gold - cost constructed_buildings[btype] = { "type": btype, "name": bp["name"], "level": 1 } building_constructed.emit(btype, bp["name"], 1) return { "ok": true, "type": btype, "name": bp["name"], "level": 1, "msg": "【%s】在公会领地拔地而起,正式竣工!" % bp["name"] } # 升级领地建筑 func upgrade_building(btype: int, player_data: Dictionary) -> Dictionary: if not constructed_buildings.has(btype): return {"ok": false, "reason": "NOT_CONSTRUCTED_YET"} var b = constructed_buildings[btype] var cur_lvl: int = b["level"] var bp = BUILDING_BLUEPRINTS[btype] if cur_lvl >= bp["max_level"]: return {"ok": false, "reason": "MAX_LEVEL_REACHED", "msg": "该建筑已达最高等级 (3级)!"} var upgrade_cost: int = int(bp["cost"] * 0.8) var gold: int = int(player_data.get("gold", 0)) if gold < upgrade_cost: return {"ok": false, "reason": "NOT_ENOUGH_GOLD", "msg": "升级金币不足!需要 %d 金币。" % upgrade_cost} player_data["gold"] = gold - upgrade_cost b["level"] = cur_lvl + 1 building_upgraded.emit(btype, b["level"]) return { "ok": true, "type": btype, "new_level": b["level"], "msg": "【%s】成功升级至等级 %d!" % [b["name"], b["level"]] } # 公会铁匠专属精炼 (+10% 强化成功率) func guild_blacksmith_refine(item: Dictionary, player_data: Dictionary, force_success: bool = false) -> Dictionary: if not constructed_buildings.has(BuildingType.BLACKSMITH): return {"ok": false, "reason": "BLACKSMITH_NOT_BUILT", "msg": "领地尚未建造公会铁匠铺!"} var cur_refine: int = int(item.get("refine_level", 0)) if cur_refine >= 9: return {"ok": false, "reason": "ALREADY_MAX_REFINE", "msg": "装备强化等级已达 +9 极限!"} # 官方基准成功率 + 公会铁匠额外 +10% 成功率 (随铁匠等级提升) var b_lvl: int = constructed_buildings[BuildingType.BLACKSMITH]["level"] var bonus_rate: int = 10 + (b_lvl - 1) * 3 # Lv1: +10%, Lv2: +13%, Lv3: +16% var base_rates := [100, 90, 80, 70, 60, 50, 40, 30, 20] # +1~+9 var rate = min(100, base_rates[cur_refine] + bonus_rate) var roll = randi_range(1, 100) var is_succ = force_success or (roll <= rate) if is_succ: item["refine_level"] = cur_refine + 1 guild_refine_result.emit(true, item["refine_level"]) return { "ok": true, "success": true, "new_level": item["refine_level"], "msg": "公会神兵铁匠挥锤如电!精炼成功,装备提升至 +%d!" % item["refine_level"] } else: # 失败降 1 级 (最低 0) item["refine_level"] = max(0, cur_refine - 1) guild_refine_result.emit(false, item["refine_level"]) return { "ok": true, "success": false, "new_level": item["refine_level"], "msg": "精炼失败!铁砧迸出火星,装备跌落至 +%d。" % item["refine_level"] } # 公会守护神坛常驻被动光环 func get_altar_passive_buffs() -> Dictionary: if not constructed_buildings.has(BuildingType.GUARDIAN_ALTAR): return {} var b_lvl: int = constructed_buildings[BuildingType.GUARDIAN_ALTAR]["level"] return { "max_hp": 1500 * b_lvl, "exp_rate_pct": 10 * b_lvl, "all_stats": 5 * b_lvl }