using Luneraria.Core;
using UnityEngine;
namespace Luneraria.View
{
///
/// Heights of the G1 world for placing figures and buildings (presentation only; the rules are
/// flat). Baked from the Godot reference by tools/godot-golden/world_export.gd:
/// the terrain walk height (1 m grid, lane decks instead of the river bed) and the height a
/// figure stands on including plaza, dais steps and grotto terrace (0.5 m grid).
///
public sealed class LuneGround : ScriptableObject
{
public float WalkExtent;
public float WalkStep;
public int WalkSize;
public float[] Walk;
public float StandExtent;
public float StandStep;
public int StandSize;
public float[] Stand;
/// LuneTerrain.walk_height: lane decks, ford and platform instead of the river bed.
public float WalkHeight(Vec2 map)
{
return Bilinear(Walk, WalkSize, WalkExtent, WalkStep, map);
}
/// LuneWorld.height_at: walk height plus plaza, dais and grotto lifts.
public float StandHeight(Vec2 map)
{
return Bilinear(Stand, StandSize, StandExtent, StandStep, map);
}
// Godot LuneTerrain._bilinear, in map coordinates.
static float Bilinear(float[] field, int size, float extent, float step, Vec2 p)
{
if (field == null || field.Length == 0)
return 0f;
float fx = Mathf.Clamp((p.X + extent) / step, 0f, size - 1.001f);
float fz = Mathf.Clamp((p.Y + extent) / step, 0f, size - 1.001f);
int i = (int)fx;
int j = (int)fz;
float tx = fx - i;
float tz = fz - j;
float a = Mathf.Lerp(field[j * size + i], field[j * size + i + 1], tx);
float b = Mathf.Lerp(field[(j + 1) * size + i], field[(j + 1) * size + i + 1], tx);
return Mathf.Lerp(a, b, tz);
}
}
}