package client import ( "io/fs" "os" "path/filepath" "github.com/chompy/roguelike_rpg/internal/util" "github.com/hajimehoshi/ebiten/v2" lua "github.com/rosbit/luago" ) type VisualEffect struct { Loop bool Time float32 Shader *ebiten.Shader luaCtx *lua.LuaContext } func LoadVisualEffect(assetFS fs.FS, name string) (*VisualEffect, error) { effect := &VisualEffect{} luaScript, err := util.ReadString(assetFS, filepath.Join("visual_effects", name+".lua")) if err != nil && !os.IsNotExist(err) { return nil, err } if err == nil { ctx, err := lua.NewContext() if err != nil { return nil, err } if err := ctx.LoadScript(luaScript, map[string]any{}); err != nil { return nil, err } res, err := ctx.CallFunc("Loop") if err != nil { return nil, err } loop, ok := res.(bool) if !ok { loop = false } effect.Loop = loop effect.luaCtx = ctx } shaderBytes, err := util.ReadBytes(assetFS, filepath.Join("visual_effects", name+".kage")) if err != nil && !os.IsNotExist(err) { return nil, err } if err == nil { shader, err := ebiten.NewShader(shaderBytes) if err != nil { return nil, err } effect.Shader = shader } return effect, nil } func (v *VisualEffect) Apply(time float32, op *ebiten.DrawImageOptions) (bool, error) { if v.luaCtx != nil { res, err := v.luaCtx.CallFunc("Apply", time, map[string]any{ "GeoM": &op.GeoM, "ColorScale": &op.ColorScale, }) if err != nil { return false, err } playing, ok := res.(bool) if ok { return playing, nil } } return false, nil }