using Godot; using System.Collections.Generic; namespace Rokojori { [Tool] [GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Sensor.svg")] public abstract partial class Sensor: Resource { [Export] public LocaleText name; [Export] public LocaleText info; [Export] public bool continous = false; protected float _value = 0; protected bool _wasActive = false; protected bool _active = false; protected float _activeTreshold = 0.5f; protected bool _consumed = false; public void ProcessSensor( SensorRunner runner, float delta ) { _wasActive = _active; UpdateValue(); } public bool isDown => ! _wasActive && _active; public bool isUp => _wasActive && ! _active; public bool isHold => _active; public bool wasActive => _wasActive; public bool isActive => _active; public float value => _value; public virtual int deviceID => 0; public virtual bool isMultiDevice => false; public virtual float GetValue( int device ) => value; public virtual bool IsDown( int device ) => isDown; public virtual bool IsUp( int device ) => isUp; public virtual bool WasActive( int device ) => isUp; public virtual bool IsActive( int device ) => isUp; public virtual bool IsDown( InputEvent ie ){ return IsSensor( ie ) && ie.IsPressed(); } public virtual bool IsUp( InputEvent ie ){ return IsSensor( ie ) && ie.IsReleased(); } public abstract bool IsSensor( InputEvent ie ); public virtual bool IsRepeatDown( ref float lastActivation, float delay = 0.5f, float repeatDuration = 0.1f ) { var now = TimeLine.osTime; if ( isDown ) { lastActivation = now + delay; return true; } var value = isActive && ( now - lastActivation ) > repeatDuration; if ( value ) { lastActivation = now; } return value; } public static string GetInputEventInfo( InputEvent ie ) { var type = ie.GetType().Name; var isPressed = ie.IsPressed(); var isReleeased = ie.IsReleased(); var details = ""; if ( ie is InputEventKey k ) { details = "key: " + k.Keycode + " " + k.KeyLabel; } else if ( ie is InputEventJoypadButton b ) { details = "gamepad button: " + b.ButtonIndex; } else if ( ie is InputEventJoypadMotion a ) { details = "gamepad axis: " + a.Axis + " " + a.AxisValue; } else if ( ie is InputEventMouseButton mb ) { details = "mouse button: " + mb.ButtonIndex + " " + mb.ButtonMask; } else if ( ie is InputEventMouseMotion mm ) { details = "mouse motion: " + mm.Position + " " + mm.Relative; } return type + " pressed:" + isPressed + " released: " + isReleeased + " " + details; } public bool consumed => _consumed; public void Consume() { _consumed = true; } protected virtual void UpdateValue() { } protected void SetBoolValue( bool activeState ) { _active = activeState; _value = activeState ? 1 : 0; _consumed = false; } protected void SetFloatValue( float value ) { _value = value; _active = value > _activeTreshold; _consumed = false; } public virtual List GetInputIcons() { return new List(); } protected void UpdateSensorUsage( int index = 0 ) { var sm = Unique.Get(); if ( sm == null ) { return; } sm.UpdateLastActiveDevice( this, index ); } } }