Metin2 game client (P0–P11) + mobile asset pipeline
Networked client on the existing Godot 4.7 + libgr2 renderer:
- net: m2dev wire protocol (libsodium KX + XChaCha20), auth/select/game
phases, EntityStore world model, ~all GC/CG headers. char create/delete,
private shop / mall / cube, SHOP_GC_START_EX, guild, party (+ CG_PARTY_SET_STATE),
quests, dragon soul, refine, safebox, exchange.
- UI: in-game windows migrated 1:1 from the reference uiscript/root .py —
char status (/stat), inventory+equipment, select-item ([SELECT_ITEM] quest
token), system-option + game-option + ESC system menu, private-shop 39-grid,
party info board, shop tabs, atlas, minimap, quickbar, chat, …
- EterGrnLib polish: GR2 material blend/two-sided, LOD crossfade, motion-event
dispatch, contact shadow, ray-AABB picking, weapon grip pre-transform.
Portable asset IO (A1) — all extension/libgr2/formats/mtproto reads routed
through godot::FileAccess (res:// PCK works on iOS/Android); standalone-lib
*_path() kept for the non-Godot CTests. AssetResolver + PropertyRegistry
switched to a baked index (bake_asset_index.gd) instead of std::filesystem.
Mobile builds: build-{android,ios}.sh, export-android.sh, pack-assets.sh,
gen-debug-keystore.sh. Assets ship as a zip mounted at runtime by
project/asset_pack.gd (adb push now; HTTP download is a drop-in later).
ctest 10/10, 34 GDScript suites, macOS/iOS/Android all build.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013EJxkHiNKS4kybHS3XKyAJ
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
# WorldTime (P9) —— 昼夜循环:GC_TIME 的服务器时钟 → 太阳角度 + 光色 + 环境色。
|
||||
#
|
||||
# var wt := preload("res://world/world_time.gd").new()
|
||||
# add_child(wt)
|
||||
# wt.setup(m2client, sun_light, environment) # environment 可空
|
||||
#
|
||||
# GC_TIME 给的是 unix 秒。本地按 delta 累加,得到「日内秒」(0..86400)。
|
||||
# 06:00 日出、12:00 正午、18:00 日落、0:00 午夜。太阳 pitch 随之走。
|
||||
extends Node
|
||||
|
||||
const DAY := 86400.0
|
||||
const CYCLE_SCALE := 1.0 # >1 加速昼夜(调试用)
|
||||
|
||||
var client: Node
|
||||
var sun: DirectionalLight3D
|
||||
var env: Environment
|
||||
var _epoch := 0.0 # 最近一次 GC_TIME 的服务器 unix 秒
|
||||
var _since := 0.0 # 收到后本地经过的秒
|
||||
var _have_time := false
|
||||
|
||||
func setup(m2client: Node, sun_light: DirectionalLight3D, environment: Environment = null) -> void:
|
||||
client = m2client
|
||||
sun = sun_light
|
||||
env = environment
|
||||
if client and client.has_signal("time_changed"):
|
||||
client.time_changed.connect(_on_time)
|
||||
if client and client.has_method("get_server_time"):
|
||||
var t: int = client.get_server_time()
|
||||
if t > 0:
|
||||
_on_time(t)
|
||||
|
||||
func _on_time(server_epoch: int) -> void:
|
||||
_epoch = float(server_epoch)
|
||||
_since = 0.0
|
||||
_have_time = true
|
||||
|
||||
# 当前日内秒(0..86400)。没有 GC_TIME 时固定用「正午」——不要跟着玩家的系统钟
|
||||
# 走到半夜把整个场景变黑(那不是 m2dev-client-main 的行为)。
|
||||
const DEFAULT_NOON := 43200.0
|
||||
|
||||
func seconds_of_day() -> float:
|
||||
if not _have_time:
|
||||
return DEFAULT_NOON
|
||||
return fmod((_epoch + _since) * CYCLE_SCALE, DAY)
|
||||
|
||||
# 0 = 午夜, 0.25 = 日出, 0.5 = 正午, 0.75 = 日落
|
||||
func day_fraction() -> float:
|
||||
return seconds_of_day() / DAY
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
_since += delta
|
||||
if sun == null:
|
||||
return
|
||||
var f := day_fraction()
|
||||
# 太阳高度角:正午(0.5)最高 ~ -85°(朝下),午夜最低 ~ +85°(朝上,被地平线挡)
|
||||
var elevation := sin((f - 0.25) * TAU) * 80.0 # -80..80
|
||||
var azimuth := lerpf(40.0, 220.0, f)
|
||||
sun.rotation = Vector3(deg_to_rad(-elevation), deg_to_rad(azimuth), 0.0)
|
||||
# 光照强度 & 颜色:白天暖白,黄昏偏橙,夜里近黑冷蓝
|
||||
var daylight := clampf(sin((f - 0.25) * TAU) * 1.4 + 0.3, 0.0, 1.0)
|
||||
sun.light_energy = lerpf(0.03, 1.15, daylight)
|
||||
var warm := Color(1.0, 0.55, 0.30)
|
||||
var noon := Color(1.0, 0.97, 0.90)
|
||||
var night := Color(0.35, 0.42, 0.65)
|
||||
if daylight < 0.35:
|
||||
sun.light_color = night.lerp(warm, daylight / 0.35)
|
||||
else:
|
||||
sun.light_color = warm.lerp(noon, (daylight - 0.35) / 0.65)
|
||||
if env:
|
||||
env.ambient_light_energy = lerpf(0.12, 0.6, daylight)
|
||||
env.ambient_light_color = Color(0.16, 0.19, 0.30).lerp(Color(0.5, 0.55, 0.62), daylight)
|
||||
if env.background_mode == Environment.BG_COLOR:
|
||||
env.background_color = Color(0.03, 0.04, 0.09).lerp(Color(0.55, 0.62, 0.72), daylight)
|
||||
@@ -0,0 +1 @@
|
||||
uid://bgp1ppw42yo7
|
||||
Reference in New Issue
Block a user