class_name FarmMapper extends RefCounted var _game_config var _crop_phase_rules: CropPhaseRules func _init(game_config = null, crop_phase_rules: CropPhaseRules = null) -> void: _game_config = game_config _crop_phase_rules = crop_phase_rules func set_dependencies(game_config, crop_phase_rules: CropPhaseRules) -> void: _game_config = game_config _crop_phase_rules = crop_phase_rules func land_data_from_sow_result(result: Dictionary, position: int, item_id: int, existing_land: Dictionary) -> Dictionary: var data := _extract_land_result_data(result) if not data.is_empty(): if not data.has("crop_phase"): data["crop_phase"] = 0 return data var now := int(Time.get_unix_time_from_system()) return { "position": position, "level": int(existing_land.get("level", existing_land.get("landLv", 0))), "crop_id": crop_id_from_seed_item(item_id), "crop_start_time": now, "crop_gather_time": now + 22, "is_ripe": 0, "crop_num": 0, "has_dry": 0, "has_bug": 0, "has_grass": 0, "has_gather": 0, "crop_phase": 0, "is_mystery_seed": 0 } func land_data_from_result(result: Dictionary, position: int, fallback_land: Dictionary) -> Dictionary: var data := _extract_land_result_data(result) if data.is_empty(): return fallback_land.duplicate(true) if not data.has("crop_phase") and _crop_phase_rules != null: data["crop_phase"] = _crop_phase_rules.get_phase(data) if not data.has("position"): data["position"] = position return data func crop_id_from_seed_item(item_id: int) -> int: if _game_config != null: var crop_id := int(_game_config.get_seed_crop_id(item_id)) if crop_id > 0: return crop_id if item_id >= 101000 and item_id < 102000: return item_id - 101000 return maxi(item_id % 1000, 1) func _extract_land_result_data(result: Dictionary) -> Dictionary: var body = result.get("body", {}) if not body is Dictionary: return {} var data = body.get("data", {}) if data is Dictionary and int(data.get("position", -1)) >= 0: return data.duplicate(true) return {}