brand new start
This commit is contained in:
parent
a41ca5669b
commit
f15f38bfc4
464 changed files with 5 additions and 20007 deletions
|
|
@ -1,56 +0,0 @@
|
|||
using Godot;
|
||||
using Newlon.Components.Level;
|
||||
|
||||
namespace Newlon;
|
||||
|
||||
public partial class Cursor : Node2D
|
||||
{
|
||||
#region Textures
|
||||
private readonly Texture2D defaultArrow = ResourceLoader.Load<Texture2D>("uid://c20dwjohaljdk");
|
||||
private readonly Texture2D defaultPoint = ResourceLoader.Load<Texture2D>("uid://cw0rqtl8ulndd");
|
||||
private readonly Texture2D shovelArrow = ResourceLoader.Load<Texture2D>("uid://dq375kjjo17g2");
|
||||
private readonly Texture2D plantArrow = ResourceLoader.Load<Texture2D>("uid://dx123mhv4oee");
|
||||
#endregion
|
||||
|
||||
public static Cursor Instance { get; private set; }
|
||||
public bool shovel = false;
|
||||
public bool plant = false;
|
||||
public static CursorMode Mode = CursorMode.Mouse;
|
||||
private float sensitivity = 200.0f;
|
||||
|
||||
public enum CursorMode
|
||||
{
|
||||
Mouse,
|
||||
Gamepad
|
||||
}
|
||||
public override void _EnterTree()
|
||||
{
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
switch (Mode)
|
||||
{
|
||||
case CursorMode.Mouse:
|
||||
break;
|
||||
case CursorMode.Gamepad:
|
||||
if (GamepadHandler.Instance.IsGamepadControlled == false) return;
|
||||
|
||||
var vector = Input.GetVector("cursor_left", "cursor_right", "cursor_up", "cursor_down");
|
||||
|
||||
if (vector == Vector2.Zero) return;
|
||||
|
||||
var set_position = GetGlobalMousePosition() + vector * (float)delta * sensitivity / (float)Engine.TimeScale;
|
||||
|
||||
GetViewport().WarpMouse(GetGlobalTransformWithCanvas() * set_position);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
public static Vector2 GetCursorPosition()
|
||||
{
|
||||
return Instance.GetGlobalMousePosition();
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://c6ucy48qwaxuc
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
using Godot;
|
||||
|
||||
namespace Newlon;
|
||||
|
||||
public static class LON
|
||||
{
|
||||
public static void ForceFinishTween(Tween tween)
|
||||
{
|
||||
if (tween == null) return;
|
||||
|
||||
tween.Pause();
|
||||
tween.CustomStep(Mathf.Inf);
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://bkr8vxejk4n2u
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
using Godot;
|
||||
|
||||
using Newlon.Resources;
|
||||
using System.Text.Json;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Newlon;
|
||||
|
||||
public partial class SaveSerializer : Node
|
||||
{
|
||||
const string SAVE_PATH = "user://save.json";
|
||||
public override void _Ready()
|
||||
{
|
||||
GetTree().AutoAcceptQuit = false;
|
||||
LoadGame();
|
||||
}
|
||||
|
||||
public override void _Notification(int what)
|
||||
{
|
||||
if (what == NotificationWMCloseRequest)
|
||||
{
|
||||
SaveGame();
|
||||
GetTree().Quit();
|
||||
}
|
||||
}
|
||||
public static void SaveGame()
|
||||
{
|
||||
var access = FileAccess.Open(SAVE_PATH, FileAccess.ModeFlags.Write);
|
||||
var playerProgress = PlayerProgress.Instance;
|
||||
var save = new SaveData
|
||||
{
|
||||
|
||||
SFXVolume = (float)Settings.SFX,
|
||||
MusicVolume = (float)Settings.Music,
|
||||
SplashSeen = Settings.Splash,
|
||||
Money = playerProgress.Money,
|
||||
SeedpacketSlots = playerProgress.MaxSeedpackets,
|
||||
PlayerPlants = [],
|
||||
|
||||
SaveGameVersion = (string)ProjectSettings.GetSetting("application/config/version")
|
||||
};
|
||||
|
||||
foreach (var plant in playerProgress.PlayerPlants)
|
||||
{
|
||||
save.PlayerPlants.Add(plant.GetInternalID());
|
||||
}
|
||||
|
||||
access.StoreString(JsonSerializer.Serialize<SaveData>(save));
|
||||
|
||||
access.Close();
|
||||
}
|
||||
public static void LoadGame()
|
||||
{
|
||||
if (FileAccess.FileExists(SAVE_PATH) == false)
|
||||
{
|
||||
InitiateCleanSave();
|
||||
return;
|
||||
}
|
||||
|
||||
var access = FileAccess.Open(SAVE_PATH, FileAccess.ModeFlags.Read);
|
||||
|
||||
var parsed = JsonSerializer.Deserialize<SaveData>(access.GetAsText());
|
||||
|
||||
Settings.SFX = parsed.SFXVolume;
|
||||
Settings.Music = parsed.MusicVolume;
|
||||
Settings.Splash = parsed.SplashSeen;
|
||||
|
||||
AudioServer.SetBusVolumeDb(2, Mathf.LinearToDb(Mathf.Exp((float)Settings.SFX) - 1));
|
||||
AudioServer.SetBusVolumeDb(1, Mathf.LinearToDb(Mathf.Exp((float)Settings.Music) - 1));
|
||||
|
||||
var playerProgress = PlayerProgress.Instance;
|
||||
playerProgress.MaxSeedpackets = parsed.SeedpacketSlots;
|
||||
playerProgress.PlayerPlants = [];
|
||||
|
||||
foreach (var plantId in parsed.PlayerPlants)
|
||||
{
|
||||
playerProgress.PlayerPlants.Add((PlantResource)GameRegistry.GetEntityByName(plantId));
|
||||
}
|
||||
|
||||
|
||||
access.Close();
|
||||
}
|
||||
private static void InitiateCleanSave()
|
||||
{
|
||||
PlayerProgress.Instance.PlayerPlants = new List<PlantResource>([(PlantResource)GameRegistry.GetEntityByName("peashooter")]);
|
||||
PlayerProgress.Instance.Money = 0;
|
||||
|
||||
SaveGame();
|
||||
}
|
||||
private partial class SaveData
|
||||
{
|
||||
public float SFXVolume { get; set; }
|
||||
public float MusicVolume { get; set; }
|
||||
public string SaveGameVersion { get; set; }
|
||||
public bool SplashSeen { get; set; }
|
||||
public List<string> PlayerPlants { get; set; }
|
||||
public int Money { get; set; } = 0;
|
||||
public int SeedpacketSlots { get; set; } = 6;
|
||||
public List<string> FinishedLevels { get; set; } = new();
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://bflvotmed7jfy
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
using Godot;
|
||||
|
||||
namespace Newlon.Components;
|
||||
|
||||
public partial class TimeScalableAnimationTree : AnimationTree
|
||||
{
|
||||
[Export] private Entity entity;
|
||||
public override void _Ready()
|
||||
{
|
||||
entity.OnLocalTimescaleChanged += OnTimescaleChanged;
|
||||
}
|
||||
|
||||
private void OnTimescaleChanged(float timescale)
|
||||
{
|
||||
Set("parameters/TimeScale/scale", timescale);
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://dwlwi42smgxkb
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
using Godot;
|
||||
|
||||
namespace Newlon.Components;
|
||||
|
||||
public partial class TimeScalableTimer : Timer
|
||||
{
|
||||
[Export] private Entity entity;
|
||||
|
||||
private float internal_timescale;
|
||||
public override void _Ready()
|
||||
{
|
||||
internal_timescale = entity.LocalTimescale;
|
||||
entity.OnLocalTimescaleChanged += OnTimescaleChanged;
|
||||
}
|
||||
|
||||
private void OnTimescaleChanged(float timescale)
|
||||
{
|
||||
WaitTime *= internal_timescale / timescale;
|
||||
internal_timescale = timescale;
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://c4jy0cnbnx33h
|
||||
|
|
@ -1,94 +0,0 @@
|
|||
using Godot;
|
||||
using Godot.Collections;
|
||||
|
||||
public partial class AudioSequencer : Node
|
||||
{
|
||||
private static AudioSequencer instance;
|
||||
[Export]private Dictionary<string, AudioStreamPlayer> channels = [];
|
||||
[Export]private Dictionary<string, bool> channelProcess = [];
|
||||
[Export]private Dictionary<string, ChannelSettings> channelSettings = [];
|
||||
|
||||
[Export]
|
||||
private ChannelSettings standardSettings;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
instance = this;
|
||||
}
|
||||
|
||||
public static bool IsChannelPlaying(string id)
|
||||
{
|
||||
if (instance.channels.ContainsKey(id) == false)
|
||||
{
|
||||
instance.InitiateChannel(id);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (instance.channelSettings[id].restartTreshold == 0)
|
||||
return false;
|
||||
if (instance.channelSettings[id].restartTreshold < 0)
|
||||
return instance.channelProcess[id];
|
||||
|
||||
return instance.channelProcess[id] && instance.channels[id].GetPlaybackPosition() < instance.channelSettings[id].restartTreshold / Engine.TimeScale;
|
||||
}
|
||||
|
||||
public static void Play(string id, AudioStream what, ChannelSettings settings = null)
|
||||
{
|
||||
if (IsChannelPlaying(id)) return;
|
||||
if (settings != null) ChangeSettings(id, settings);
|
||||
instance.PlayAtChannel(id, what);
|
||||
}
|
||||
|
||||
public static void ChangeSettings(string id, ChannelSettings settings)
|
||||
{
|
||||
|
||||
if (instance.channels.ContainsKey(id) == false)
|
||||
{
|
||||
instance.InitiateChannel(id, settings);
|
||||
return;
|
||||
}
|
||||
if (settings == null)
|
||||
{
|
||||
instance.channelSettings[id] = instance.standardSettings;
|
||||
return;
|
||||
}
|
||||
instance.channelSettings[id] = settings;
|
||||
}
|
||||
|
||||
private AudioStreamPlayer InitiateChannel(string id, ChannelSettings settings = null)
|
||||
{
|
||||
AudioStreamPlayer player = new();
|
||||
|
||||
AddChild(player);
|
||||
channels.Add(id, player);
|
||||
channelProcess.Add(id, false);
|
||||
player.Name = id;
|
||||
player.MaxPolyphony = 5;
|
||||
player.Bus = "SFXBus";
|
||||
|
||||
player.Finished += () => { MarkChannel(id, false); };
|
||||
|
||||
if (settings != null)
|
||||
{
|
||||
channelSettings.Add(id, settings);
|
||||
}
|
||||
else
|
||||
{
|
||||
channelSettings.Add(id, standardSettings);
|
||||
}
|
||||
|
||||
return player;
|
||||
}
|
||||
|
||||
private void PlayAtChannel(string id, AudioStream what)
|
||||
{
|
||||
channels[id].Stream = what;
|
||||
channels[id].Play();
|
||||
MarkChannel(id, true);
|
||||
}
|
||||
|
||||
private void MarkChannel(string id, bool how)
|
||||
{
|
||||
channelProcess[id] = how;
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://cauc1ieq84fwg
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
using Godot;
|
||||
using Newlon;
|
||||
|
||||
public partial class AudioSlider : HSlider
|
||||
{
|
||||
enum TYPE
|
||||
{
|
||||
SFX,
|
||||
MUSIC
|
||||
}
|
||||
|
||||
[Export] private TYPE affects;
|
||||
public override void _Ready()
|
||||
{
|
||||
ValueChanged += OnValueChanged;
|
||||
if (affects == TYPE.SFX)
|
||||
{
|
||||
SetValueNoSignal(Settings.SFX);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetValueNoSignal(Settings.Music);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnValueChanged(double value)
|
||||
{
|
||||
if (affects == TYPE.SFX)
|
||||
{
|
||||
var volume = Mathf.LinearToDb(Mathf.Exp((float)value) - 1); ;
|
||||
Settings.SFX = value;
|
||||
AudioServer.SetBusVolumeDb(2, volume);
|
||||
}
|
||||
else
|
||||
{
|
||||
var volume = Mathf.LinearToDb(Mathf.Exp((float)value) - 1); ;
|
||||
Settings.Music = value;
|
||||
AudioServer.SetBusVolumeDb(1, volume);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://ciccaxqo70s13
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
using Godot;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class ChannelPlayer : Node
|
||||
{
|
||||
[Export] private ChannelSettings settings;
|
||||
[Export] private AudioStream audioStream;
|
||||
[Export] private string channel;
|
||||
|
||||
public void Play()
|
||||
{
|
||||
AudioSequencer.Play(channel, audioStream);
|
||||
if (settings != null)
|
||||
AudioSequencer.ChangeSettings(channel, settings);
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://c36bj8u7jghc7
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
using Godot;
|
||||
using Godot.Collections;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class ChannelPlaylist : Node
|
||||
{
|
||||
[Export] private Array<AudioStream> playlist;
|
||||
[Export] private Array<string> channels;
|
||||
[Export] private ChannelSettings channelSettings;
|
||||
private int internal_index = 0;
|
||||
|
||||
public void Play()
|
||||
{
|
||||
AudioSequencer.Play(channels[internal_index], playlist[internal_index]);
|
||||
}
|
||||
|
||||
public void SetIndex(int index)
|
||||
{
|
||||
internal_index = index;
|
||||
if (internal_index >= playlist.Count)
|
||||
{
|
||||
internal_index = 0;
|
||||
}
|
||||
else if (internal_index < 0)
|
||||
{
|
||||
internal_index = playlist.Count - 1;
|
||||
}
|
||||
}
|
||||
|
||||
public void Next()
|
||||
{
|
||||
SetIndex(internal_index + 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://cnn0ymuhypdff
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
using Godot;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class ChannelSettings : Resource
|
||||
{
|
||||
[Export] public float restartTreshold;
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://c1x4n4nqyq72f
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
using Godot;
|
||||
using Newlon.Components.Level;
|
||||
|
||||
public partial class ChooseYourSeedsMusic : AudioStreamPlayer
|
||||
{
|
||||
public override void _Ready()
|
||||
{
|
||||
RuntimeLevelData.Instance.OnLevelStateChanged += OnLevelStateChanged;
|
||||
}
|
||||
|
||||
private void OnLevelStateChanged(RuntimeLevelData.LevelStates state)
|
||||
{
|
||||
if (state == RuntimeLevelData.LevelStates.ChooseYourSeeds)
|
||||
{
|
||||
Play();
|
||||
}
|
||||
else
|
||||
{
|
||||
var tween = CreateTween();
|
||||
tween.TweenProperty(this, "volume_linear", 0, 1);
|
||||
tween.TweenCallback(Callable.From(Stop));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://b4ysi1iutmju3
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
using Godot;
|
||||
using Godot.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Newlon.Components;
|
||||
using Newlon.Systems.Effects;
|
||||
|
||||
public partial class EffectBasedPlayer : Node
|
||||
{
|
||||
[Export] public Array<Effect> effectsToMap;
|
||||
[Export] public Array<AudioStream> streamsToMapTo;
|
||||
[Export] public Array<ChannelSettings> streamSettings;
|
||||
private System.Collections.Generic.Dictionary<Effect, (AudioStream,ChannelSettings)> effectToAudioMap = new();
|
||||
public override void _Ready()
|
||||
{
|
||||
GetParent<Entity>().EffectStarted += OnEffectStarted;
|
||||
|
||||
for (int i = 0; i < effectsToMap.Count; i++)
|
||||
{
|
||||
effectToAudioMap.Add(effectsToMap[i], (streamsToMapTo[i],streamSettings[i]));
|
||||
}
|
||||
}
|
||||
|
||||
public void OnEffectStarted(Effect what)
|
||||
{
|
||||
if (effectToAudioMap.ContainsKey(what) == false) return;
|
||||
AudioSequencer.Play(what.Slot, effectToAudioMap[what].Item1);
|
||||
AudioSequencer.ChangeSettings(what.Slot, effectToAudioMap[what].Item2);
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://b8r6fxsfjdo3a
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
using Godot;
|
||||
using Newlon.Components.Level;
|
||||
using System;
|
||||
|
||||
public partial class MusicTransitioner : AudioStreamPlayer
|
||||
{
|
||||
private AudioStreamPlaybackInteractive playback;
|
||||
private Timer timer;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
RuntimeLevelData.Instance.OnLevelStateChanged += OnLevelStateChanged;
|
||||
timer = GetNode<Timer>("Timer");
|
||||
}
|
||||
|
||||
private void OnLevelStateChanged(RuntimeLevelData.LevelStates state)
|
||||
{
|
||||
if (state == RuntimeLevelData.LevelStates.Game)
|
||||
{
|
||||
Play();
|
||||
playback = (AudioStreamPlaybackInteractive)GetStreamPlayback();
|
||||
VolumeLinear = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
var tween = CreateTween();
|
||||
tween.TweenProperty(this, "volume_linear", 0, 1);
|
||||
tween.TweenCallback(Callable.From(Stop));
|
||||
}
|
||||
}
|
||||
|
||||
public void OnHugeWaveApproaching()
|
||||
{
|
||||
playback.SwitchToClip(1);
|
||||
timer.Start();
|
||||
}
|
||||
public void OnTimerTimeout()
|
||||
{
|
||||
playback.SwitchToClip(0);
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://bnj5tlcpmep2o
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
using Godot;
|
||||
using Newlon.Components.Level;
|
||||
|
||||
namespace Newlon.Debug;
|
||||
|
||||
public partial class Cheats : Node
|
||||
{
|
||||
public override void _Input(InputEvent @event)
|
||||
{
|
||||
if (OS.IsDebugBuild() == false) return;
|
||||
if (@event.IsActionPressed("cheat_add_sun"))
|
||||
{
|
||||
RuntimeLevelData.Instance.AddSun(50);
|
||||
}
|
||||
if (@event.IsActionPressed("cheat_unlock_all"))
|
||||
{
|
||||
PlayerProgress.Instance.PlayerPlants = GameRegistry.GetPlants();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://cb8n22kkqa8ig
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
using Godot;
|
||||
using System;
|
||||
|
||||
namespace Newlon.Debug;
|
||||
|
||||
//
|
||||
// Debug tool to check time since clock loaded
|
||||
//
|
||||
|
||||
public partial class Clock : Label
|
||||
{
|
||||
private ulong _time = 0;
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
_time += (ulong)(delta*1000);
|
||||
ulong seconds = _time / 1000 % 60;
|
||||
ulong minutes = seconds / 60 % 60;
|
||||
Text = minutes.ToString()+":"+seconds.ToString();
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://d2aq2wjq0gt7x
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
using Godot;
|
||||
|
||||
namespace Newlon.Components.Droppables;
|
||||
|
||||
public partial class DropMover : Node
|
||||
{
|
||||
public float ySpeed = -200.0f;
|
||||
public float xSpeed = 150.0f;
|
||||
|
||||
|
||||
private float stop_y;
|
||||
private Node2D parent;
|
||||
private Vector2 velocity;
|
||||
private float gravity;
|
||||
public override void _Ready()
|
||||
{
|
||||
parent = GetParent<Node2D>();
|
||||
stop_y = ((parent.GlobalPosition / FieldParams.Tile).Ceil() * FieldParams.Tile).Y;
|
||||
gravity = (float)ProjectSettings.GetSetting("physics/2d/default_gravity");
|
||||
|
||||
velocity = new Vector2((GD.Randf() - 0.5f) * xSpeed, ySpeed);
|
||||
}
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
if (parent.GlobalPosition.Y >= stop_y) QueueFree();
|
||||
|
||||
velocity += Vector2.Down * gravity * (float)delta;
|
||||
|
||||
parent.GlobalPosition += velocity * (float)delta;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://b2j41pq6cmpgm
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
using Godot;
|
||||
|
||||
namespace Newlon.Components.Droppables;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class DroppableItem : Area2D
|
||||
{
|
||||
[Signal] public delegate void PickedUpEventHandler();
|
||||
public override void _MouseEnter()
|
||||
{
|
||||
if (GamepadHandler.Instance.IsGamepadControlled)
|
||||
{
|
||||
GetViewport().SetInputAsHandled();
|
||||
PickUp();
|
||||
EmitSignal(SignalName.PickedUp);
|
||||
}
|
||||
}
|
||||
|
||||
public override void _InputEvent(Viewport viewport, InputEvent @event, int shapeIdx)
|
||||
{
|
||||
if (@event.IsActionPressed("primary_action"))
|
||||
{
|
||||
GetViewport().SetInputAsHandled();
|
||||
PickUp();
|
||||
EmitSignal(SignalName.PickedUp);
|
||||
}
|
||||
}
|
||||
public virtual void PickUp() {}
|
||||
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://cwf2y3pxi6psc
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
using Godot;
|
||||
using Newlon.Resources;
|
||||
|
||||
namespace Newlon.Components.Droppables;
|
||||
|
||||
public partial class DroppableSeedpacket : DroppableItem
|
||||
{
|
||||
public PlantResource plant;
|
||||
[Export] private Label _cost;
|
||||
[Export] private TextureRect _icon;
|
||||
[Export] private TextureRect _packet;
|
||||
public override void _Ready()
|
||||
{
|
||||
_cost.Text = plant.Cost.ToString();
|
||||
_icon.Texture = plant.Preview;
|
||||
if (plant.CustomFrame != null)
|
||||
{
|
||||
_packet.Texture = plant.CustomFrame.frame;
|
||||
_cost.LabelSettings = plant.CustomFrame.font;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://gymo10tjruj2
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
using Godot;
|
||||
|
||||
public partial class AnimationStatistics : Node
|
||||
{
|
||||
[Export]
|
||||
private string animationName;
|
||||
[Export]
|
||||
private string trackToFind;
|
||||
private float invokationsPerSecond;
|
||||
public override void _Ready()
|
||||
{
|
||||
var animation = GetParent<AnimationPlayer>().GetAnimation(animationName);
|
||||
|
||||
var track_id = animation.FindTrack(trackToFind,Animation.TrackType.Method);
|
||||
invokationsPerSecond = animation.TrackGetKeyCount(track_id)/ animation.Length;
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://dw7v3s4kbu7ma
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
using Godot;
|
||||
using Newlon.Systems.Effects;
|
||||
|
||||
namespace Newlon.Components;
|
||||
|
||||
public partial class AreaOfEffect : Area2D
|
||||
{
|
||||
[Export] public Effect givenEffect;
|
||||
public override void _Ready()
|
||||
{
|
||||
AreaEntered += OnAreaEntered;
|
||||
}
|
||||
|
||||
public void OnAreaEntered(Area2D what)
|
||||
{
|
||||
if (what.GetParent() is Entity entity)
|
||||
{
|
||||
entity.GiveEffect(givenEffect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://bd1f7x1nin0i0
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
using Godot;
|
||||
|
||||
namespace Newlon.Components;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class Armor : Node
|
||||
{
|
||||
[Signal]
|
||||
public delegate void DamagedEventHandler();
|
||||
[Signal]
|
||||
public delegate void HpChangedEventHandler(float hp);
|
||||
[Signal]
|
||||
public delegate void ArmorLostEventHandler();
|
||||
|
||||
[Export]
|
||||
public float MaxHP { get; private set; }
|
||||
public float _hp;
|
||||
private bool _lost = false;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_hp = MaxHP;
|
||||
}
|
||||
|
||||
public float RecieveDamage(float damage)
|
||||
{
|
||||
if(_lost)
|
||||
return damage;
|
||||
|
||||
float returnAmount = damage - _hp;
|
||||
if (returnAmount < 0)
|
||||
returnAmount = 0;
|
||||
if (_hp - damage <= 0)
|
||||
{
|
||||
var delta = _hp;
|
||||
_hp = 0;
|
||||
EmitSignal(SignalName.HpChanged, -delta);
|
||||
EmitSignal(SignalName.Damaged);
|
||||
EmitSignal(SignalName.ArmorLost);
|
||||
_lost = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_hp -= damage;
|
||||
EmitSignal(SignalName.HpChanged, -damage);
|
||||
EmitSignal(SignalName.Damaged);
|
||||
}
|
||||
return returnAmount;
|
||||
}
|
||||
|
||||
public float Heal(float amount)
|
||||
{
|
||||
if(_lost)
|
||||
return amount;
|
||||
float returnAmount = 0;
|
||||
_hp += amount;
|
||||
if (_hp >= MaxHP)
|
||||
{
|
||||
returnAmount = _hp-MaxHP;
|
||||
_hp = MaxHP;
|
||||
}
|
||||
EmitSignal(SignalName.HpChanged,_hp);
|
||||
return returnAmount;
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://fd4im1fmwc5n
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
using Godot;
|
||||
|
||||
namespace Newlon.Components;
|
||||
|
||||
public partial class ArmorHPObserver : Node
|
||||
{
|
||||
[Export] private float _threshold = 0.5f;
|
||||
[Export] private bool _setGreater = false;
|
||||
[Export] private Armor _observedArmor;
|
||||
[Signal] public delegate void ThresholdReachedEventHandler();
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_observedArmor.Damaged += OnDamaged;
|
||||
}
|
||||
|
||||
private void OnDamaged()
|
||||
{
|
||||
if (_setGreater == false && _observedArmor._hp / _observedArmor.MaxHP < _threshold)
|
||||
{
|
||||
EmitSignal(SignalName.ThresholdReached);
|
||||
_observedArmor.Damaged -= OnDamaged;
|
||||
QueueFree();
|
||||
}
|
||||
else if (_setGreater && _observedArmor._hp / _observedArmor.MaxHP > _threshold)
|
||||
{
|
||||
EmitSignal(SignalName.ThresholdReached);
|
||||
_observedArmor.Damaged -= OnDamaged;
|
||||
QueueFree();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://d3l8e8ko5r5i3
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
using Godot;
|
||||
using Godot.Collections;
|
||||
|
||||
namespace Newlon.Components.Zombies;
|
||||
|
||||
public partial class DegradingSprite : Sprite2D
|
||||
{
|
||||
[Export] private Armor armor;
|
||||
[Export] private Array<Texture2D> degradationStages;
|
||||
[Export] private Array<float> thresholdPercentage;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
armor.Damaged += OnDamaged;
|
||||
}
|
||||
|
||||
private void OnDamaged()
|
||||
{
|
||||
float percent = armor._hp / armor.MaxHP;
|
||||
for (int i = 0; i < degradationStages.Count; i++)
|
||||
{
|
||||
if (percent <= thresholdPercentage[i])
|
||||
{
|
||||
Texture = degradationStages[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://bbw848msxb4re
|
||||
|
|
@ -1,218 +0,0 @@
|
|||
using Godot;
|
||||
using Godot.Collections;
|
||||
using Newlon.Components.Level;
|
||||
using Newlon.Systems.Effects;
|
||||
|
||||
namespace Newlon.Components;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class Entity : Node2D
|
||||
{
|
||||
#region Health points
|
||||
[Export] public float MaxHP;
|
||||
[Export]public float HP;
|
||||
[Signal] public delegate void OnHPChangedEventHandler(EntitySignalContext context);
|
||||
[Signal] public delegate void OnDamagedEventHandler();
|
||||
[Signal] public delegate void HasBeenKilledEventHandler(Entity who);
|
||||
|
||||
|
||||
public virtual void TakeDamage(float amount, Node origin)
|
||||
{
|
||||
if (amount > 0)
|
||||
EmitSignal(SignalName.OnDamaged);
|
||||
|
||||
var context = new EntitySignalContext()
|
||||
{
|
||||
target = this,
|
||||
source = (Entity)origin,
|
||||
actionAmount = amount
|
||||
};
|
||||
if (HP - amount <= 0)
|
||||
{
|
||||
context.deltaHP = -HP;
|
||||
EmitSignal(SignalName.OnHPChanged, context);
|
||||
HP = 0;
|
||||
KillByDamage();
|
||||
}
|
||||
else
|
||||
{
|
||||
context.deltaHP = -amount;
|
||||
HP -= amount;
|
||||
EmitSignal(SignalName.OnHPChanged, context);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Heal(float amount, Node origin)
|
||||
{
|
||||
var context = new EntitySignalContext()
|
||||
{
|
||||
target = this,
|
||||
source = (Entity)origin,
|
||||
actionAmount = amount
|
||||
};
|
||||
if (HP + amount > MaxHP)
|
||||
{
|
||||
context.deltaHP = MaxHP - HP;
|
||||
EmitSignal(SignalName.OnHPChanged, context);
|
||||
HP = MaxHP;
|
||||
}
|
||||
else
|
||||
{
|
||||
context.deltaHP = amount;
|
||||
HP += amount;
|
||||
EmitSignal(SignalName.OnHPChanged, context);
|
||||
}
|
||||
}
|
||||
|
||||
public bool Killed = false;
|
||||
public virtual void KillByDamage()
|
||||
{
|
||||
if (Killed) return;
|
||||
Killed = true;
|
||||
EmitSignal(SignalName.HasBeenKilled,this);
|
||||
ClearEffects();
|
||||
Kill();
|
||||
}
|
||||
|
||||
public virtual void Kill()
|
||||
{
|
||||
QueueFree();
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
#region Brain
|
||||
[Export] private AnimationPlayer _player;
|
||||
[Export] private AnimationTree _tree;
|
||||
private bool forceToggledBrain = false;
|
||||
private bool brainEnabled = true;
|
||||
public virtual void DisableBrain(bool force = true)
|
||||
{
|
||||
if (brainEnabled == false) return;
|
||||
if (_player != null)
|
||||
_player.ProcessMode = ProcessModeEnum.Pausable;
|
||||
if (_tree != null)
|
||||
_tree.ProcessMode = ProcessModeEnum.Pausable;
|
||||
ProcessMode = ProcessModeEnum.Disabled;
|
||||
forceToggledBrain = force;
|
||||
brainEnabled = false;
|
||||
}
|
||||
|
||||
public virtual void EnableBrain(bool force = true)
|
||||
{
|
||||
if (brainEnabled) return;
|
||||
if (_player != null)
|
||||
_player.ProcessMode = ProcessModeEnum.Inherit;
|
||||
if (_tree != null)
|
||||
_tree.ProcessMode = ProcessModeEnum.Inherit;
|
||||
ProcessMode = ProcessModeEnum.Inherit;
|
||||
forceToggledBrain = force;
|
||||
brainEnabled = true;
|
||||
}
|
||||
#endregion
|
||||
#region Effects
|
||||
[Export] private Array<Effect> _effectImmunities = new();
|
||||
[Export] private bool completeInvulnerability = false;
|
||||
private readonly Dictionary<string, EffectHandler> effectHandlers = new();
|
||||
|
||||
[Signal] public delegate void EffectStartedEventHandler(Effect what);
|
||||
[Signal] public delegate void EffectEndedEventHandler(Effect what);
|
||||
[Signal] public delegate void EffectContinuedEventHandler(Effect what);
|
||||
|
||||
|
||||
public virtual void GiveEffect(Effect what)
|
||||
{
|
||||
if (what == null ||
|
||||
Killed ||
|
||||
completeInvulnerability || _effectImmunities.Contains(what))
|
||||
return;
|
||||
|
||||
var slot = what.Slot;
|
||||
if (effectHandlers.ContainsKey(slot) == false)
|
||||
InitSlot(slot);
|
||||
|
||||
if (effectHandlers[slot].HandledEffect == what)
|
||||
{
|
||||
effectHandlers[slot].Restart();
|
||||
}
|
||||
else
|
||||
{
|
||||
effectHandlers[slot].HandledEffect = what;
|
||||
effectHandlers[slot].Start();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void EndEffect(Effect what)
|
||||
{
|
||||
EndEffectAtSlot(what.Slot);
|
||||
}
|
||||
|
||||
public Tween CreateTweenEffect(Effect effect)
|
||||
{
|
||||
Tween tween = CreateTween();
|
||||
|
||||
effectHandlers[effect.Slot].EffectTween = tween;
|
||||
|
||||
return tween;
|
||||
}
|
||||
|
||||
protected void ClearEffects()
|
||||
{
|
||||
foreach (var slot in effectHandlers.Keys)
|
||||
{
|
||||
effectHandlers[slot].End();
|
||||
}
|
||||
}
|
||||
private void InitSlot(string key)
|
||||
{
|
||||
effectHandlers.Add(key, new EffectHandler());
|
||||
effectHandlers[key].handler = this;
|
||||
effectHandlers[key].EffectTimer = new();
|
||||
|
||||
AddChild(effectHandlers[key].EffectTimer);
|
||||
effectHandlers[key].EffectTimer.Name = key + "Timer";
|
||||
|
||||
effectHandlers[key].EffectTimer.Timeout += () => { EndEffectAtSlot(key); };
|
||||
}
|
||||
|
||||
public void ProcessEffects()
|
||||
{
|
||||
foreach (var slot in effectHandlers.Keys)
|
||||
{
|
||||
effectHandlers[slot].Process();
|
||||
}
|
||||
}
|
||||
|
||||
private void EndEffectAtSlot(string slot)
|
||||
{
|
||||
EmitSignal(SignalName.EffectEnded, effectHandlers[slot].HandledEffect);
|
||||
effectHandlers[slot].End();
|
||||
}
|
||||
|
||||
#endregion
|
||||
#region LocalTimescale
|
||||
private float _localTimescale = 1.0f;
|
||||
[Signal] public delegate void OnLocalTimescaleChangedEventHandler(float scale);
|
||||
public float LocalTimescale
|
||||
{
|
||||
get => _localTimescale;
|
||||
set
|
||||
{
|
||||
_localTimescale = value;
|
||||
EmitSignal(SignalName.OnLocalTimescaleChanged, _localTimescale);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
#region Godot overrides
|
||||
public override void _Ready()
|
||||
{
|
||||
HP = MaxHP;
|
||||
if (RuntimeLevelData.Instance != null)
|
||||
{
|
||||
if (RuntimeLevelData.Instance.GetLevelState() != RuntimeLevelData.LevelStates.Game) DisableBrain(false);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://3tw88wj1nrj1
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
using Godot;
|
||||
|
||||
namespace Newlon.Components;
|
||||
|
||||
public partial class EntityHPObserver : Node
|
||||
{
|
||||
[Export] private float _threshold = 0.5f;
|
||||
[Export] private bool _setGreater = false;
|
||||
[Export] private Entity _observedEntity;
|
||||
[Signal] public delegate void ThresholdReachedEventHandler();
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_observedEntity.OnHPChanged += OnHPChanged;
|
||||
}
|
||||
|
||||
private void OnHPChanged(EntitySignalContext context)
|
||||
{
|
||||
if (_setGreater == false && _observedEntity.HP / _observedEntity.MaxHP <= _threshold)
|
||||
{
|
||||
EmitSignal(SignalName.ThresholdReached);
|
||||
_observedEntity.OnHPChanged -= OnHPChanged;
|
||||
QueueFree();
|
||||
}
|
||||
else if (_setGreater && _observedEntity.HP / _observedEntity.MaxHP >= _threshold)
|
||||
{
|
||||
EmitSignal(SignalName.ThresholdReached);
|
||||
_observedEntity.OnHPChanged -= OnHPChanged;
|
||||
QueueFree();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://dau0tfmlfiqmo
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
using Godot;
|
||||
|
||||
namespace Newlon.Components;
|
||||
|
||||
public partial class EntitySignalContext : RefCounted
|
||||
{
|
||||
public Node source;
|
||||
public Entity target;
|
||||
public float actionAmount;
|
||||
public float deltaHP;
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://cbdvo20dhiadw
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
using Godot;
|
||||
using Newlon.Components;
|
||||
|
||||
public partial class FlashShaderController : Node
|
||||
{
|
||||
[Export] public float flashTime = 0.5f;
|
||||
[Export]
|
||||
private ShaderMaterial shaderMaterial;
|
||||
private uint toggleStack = 0;
|
||||
private Tween flashTween;
|
||||
public void DamageFlash()
|
||||
{
|
||||
Flash();
|
||||
}
|
||||
public void Flash(float customFlashTime = 0)
|
||||
{
|
||||
if (flashTween != null)
|
||||
flashTween.Kill();
|
||||
var time = flashTime;
|
||||
if (customFlashTime > 0)
|
||||
time = customFlashTime;
|
||||
|
||||
flashTween = CreateTween();
|
||||
flashTween.TweenMethod(Callable.From<float>(SetBlend), 1.0, 0.0, time);
|
||||
}
|
||||
public void Select()
|
||||
{
|
||||
toggleStack++;
|
||||
UpdateSelected();
|
||||
}
|
||||
public void Deselect()
|
||||
{
|
||||
toggleStack--;
|
||||
UpdateSelected();
|
||||
}
|
||||
private void SetBlend(float blend)
|
||||
{
|
||||
shaderMaterial.SetShaderParameter("blend", blend);
|
||||
}
|
||||
private void UpdateSelected()
|
||||
{
|
||||
if (toggleStack > 0)
|
||||
{
|
||||
shaderMaterial.SetShaderParameter("selected", true);
|
||||
}
|
||||
else
|
||||
{
|
||||
shaderMaterial.SetShaderParameter("selected", false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://30pbgasu64aw
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
using Godot;
|
||||
|
||||
namespace Newlon.Components;
|
||||
|
||||
public partial class InvulnerableEntity : Entity
|
||||
{
|
||||
public override void TakeDamage(float amount, Node origin)
|
||||
{
|
||||
}
|
||||
public override void Heal(float amount, Node origin)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://cq1dl578rbvrj
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
using Godot;
|
||||
using Newlon.Components.Zombies;
|
||||
|
||||
namespace Newlon.Components.Plants;
|
||||
|
||||
public partial class AreaAttack : Area2D
|
||||
{
|
||||
[Export] private int _damage;
|
||||
|
||||
public void Attack()
|
||||
{
|
||||
foreach (var zombie in GetOverlappingAreas())
|
||||
{
|
||||
var zombieData = zombie.GetParent<RuntimeZombieData>();
|
||||
zombieData?.TakeDamage(_damage,GetParent());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://co7ttejdo2qot
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
using Godot;
|
||||
|
||||
namespace Newlon.Components.Plants;
|
||||
|
||||
public partial class DragAction : Node
|
||||
{
|
||||
[Signal] public delegate void DragBeginEventHandler();
|
||||
[Signal] public delegate void DragEndEventHandler(bool aborted);
|
||||
private bool dragging = false;
|
||||
private bool toggle = false;
|
||||
private bool can_end = false;
|
||||
private bool mouseIn = false;
|
||||
public override void _Ready()
|
||||
{
|
||||
GetParent<Area2D>().MouseEntered += OnMouseEntered;
|
||||
GetParent<Area2D>().MouseExited += OnMouseExited;
|
||||
}
|
||||
public void OnMouseEntered()
|
||||
{
|
||||
mouseIn = true;
|
||||
}
|
||||
public void OnMouseExited()
|
||||
{
|
||||
mouseIn = false;
|
||||
}
|
||||
|
||||
public override void _Input(InputEvent @event)
|
||||
{
|
||||
if (mouseIn && @event.IsActionPressed("primary_action"))
|
||||
{
|
||||
dragging = true;
|
||||
toggle = false;
|
||||
can_end = false;
|
||||
EmitSignal(SignalName.DragBegin);
|
||||
GetTree().CreateTimer(0.2, ignoreTimeScale: true).Timeout += OnToggleTimeout;
|
||||
GetViewport().SetInputAsHandled();
|
||||
}
|
||||
if (dragging && can_end && (toggle == false && @event.IsActionReleased("primary_action") || (toggle == true && @event.IsActionPressed("primary_action"))))
|
||||
{
|
||||
dragging = false;
|
||||
EmitSignal(SignalName.DragEnd,false);
|
||||
GetViewport().SetInputAsHandled();
|
||||
}
|
||||
if (dragging && @event.IsActionPressed("cancel_action"))
|
||||
{
|
||||
dragging = false;
|
||||
EmitSignal(SignalName.DragEnd,true);
|
||||
}
|
||||
}
|
||||
public void OnToggleTimeout()
|
||||
{
|
||||
can_end = true;
|
||||
if (Input.IsActionPressed("primary_action") == false)
|
||||
{
|
||||
toggle = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://cu63aiowp5bqd
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
using Godot;
|
||||
using Newlon.Components.Level;
|
||||
using Newlon.Components.Zombies;
|
||||
|
||||
namespace Newlon.Components.Plants;
|
||||
|
||||
public partial class ExplosionComponent : Area2D
|
||||
{
|
||||
[Export] private int damage;
|
||||
[Export] private PackedScene particles;
|
||||
|
||||
public void Explode()
|
||||
{
|
||||
foreach (var zombie in GetOverlappingAreas())
|
||||
{
|
||||
var zombieData = zombie.GetParent<RuntimeZombieData>();
|
||||
zombieData?.TakeDamage(damage, GetParent());
|
||||
}
|
||||
|
||||
PoolContainer.Instance.SpawnParticles(particles, GetParent<RuntimePlantData>().GlobalPosition);
|
||||
|
||||
GetNode<ChannelPlayer>("ExplosionPlayer").Play();
|
||||
GetParent<RuntimePlantData>().Kill();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://bhl6o2m3fn4xg
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
using Godot;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Newlon.Components.Plants;
|
||||
|
||||
public partial class Eyesight : Area2D
|
||||
{
|
||||
private bool _enemyDetected;
|
||||
public bool EnemyDetected => _enemyDetected;
|
||||
private readonly List<Entity> _detectedEntities = new List<Entity>();
|
||||
private RuntimePlantData _plantData;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_plantData = GetParent<RuntimePlantData>();
|
||||
AreaEntered += OnAreaEntered;
|
||||
AreaExited += OnAreaExited;
|
||||
}
|
||||
|
||||
public void OnAreaEntered(Area2D area)
|
||||
{
|
||||
var entity = area.GetParent<Entity>();
|
||||
if (entity != null)
|
||||
{
|
||||
_detectedEntities.Add(entity);
|
||||
}
|
||||
|
||||
_enemyDetected = _detectedEntities.Count > 0;
|
||||
}
|
||||
|
||||
public void OnAreaExited(Area2D area)
|
||||
{
|
||||
var entity = area.GetParent<Entity>();
|
||||
if (entity != null)
|
||||
{
|
||||
if (_detectedEntities.Contains(entity))
|
||||
{
|
||||
_detectedEntities.Remove(entity);
|
||||
}
|
||||
}
|
||||
|
||||
_enemyDetected = _detectedEntities.Count > 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://dn53jvpjyg63l
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
using Godot;
|
||||
|
||||
namespace Newlon.Components.Plants;
|
||||
|
||||
public partial class LoseZone : RuntimePlantData
|
||||
{
|
||||
public override void TakeDamage(float amount, Node origin)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
public override void Kill()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://c0ov2bq5er0gh
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
using Godot;
|
||||
using Newlon.Systems.Effects;
|
||||
using System.Collections.Generic;
|
||||
namespace Newlon.Components.Plants;
|
||||
|
||||
public partial class NerdusReturnAttack : Area2D
|
||||
{
|
||||
private float returnAmount;
|
||||
[Export] private Effect returnEffect;
|
||||
[Export] private float bitesToPeas = 1;
|
||||
public bool triggered = false;
|
||||
private List<Entity> entities = new();
|
||||
public override void _Ready()
|
||||
{
|
||||
AreaEntered += OnAreaEntered;
|
||||
AreaExited += OnAreaExited;
|
||||
}
|
||||
private void OnAreaEntered(Area2D area)
|
||||
{
|
||||
if (area.GetParent() is Entity entity)
|
||||
{
|
||||
entities.Add(entity);
|
||||
}
|
||||
}
|
||||
private void OnAreaExited(Area2D area)
|
||||
{
|
||||
if (area.GetParent() is Entity entity && entities.Contains(entity))
|
||||
{
|
||||
entities.Remove(entity);
|
||||
}
|
||||
}
|
||||
private void OnHPChanged(EntitySignalContext context)
|
||||
{
|
||||
if (context.deltaHP >= 0) return;
|
||||
returnAmount -= context.deltaHP;
|
||||
triggered = true;
|
||||
}
|
||||
public void ReturnAllDamage()
|
||||
{
|
||||
foreach (var entity in entities)
|
||||
{
|
||||
entity.TakeDamage(returnAmount * bitesToPeas, GetParent<Entity>());
|
||||
entity.GiveEffect(returnEffect);
|
||||
}
|
||||
returnAmount = 0;
|
||||
triggered = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://dcokqes5wwo3k
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
using Godot;
|
||||
|
||||
namespace Newlon.Components.Plants;
|
||||
|
||||
public partial class PlantEyesightLimiter : CollisionShape2D
|
||||
{
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
if (Shape is SegmentShape2D segment)
|
||||
{
|
||||
segment.B = new Vector2(FieldParams.RightFieldBoundary.X - GlobalPosition.X+FieldParams.TileWidth/2.0f, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://hccb0aee0x0o
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
using Godot;
|
||||
using Newlon.Projectiles;
|
||||
using Newlon.Components.Level;
|
||||
using Newlon.Components.Droppables;
|
||||
|
||||
namespace Newlon.Components.Plants;
|
||||
|
||||
public partial class PlantSunSpawner : Node2D
|
||||
{
|
||||
[Export]
|
||||
private PackedScene _sunScene;
|
||||
[Export]
|
||||
private int _amountPerSun;
|
||||
|
||||
public void Spawn()
|
||||
{
|
||||
var sun = _sunScene.Instantiate<Sun>();
|
||||
|
||||
sun.amount = _amountPerSun;
|
||||
|
||||
PoolContainer.Instance.Projectiles.AddChild(sun);
|
||||
sun.GlobalPosition = GlobalPosition;
|
||||
|
||||
var mover = new DropMover();
|
||||
sun.AddChild(mover);
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://b71gebny84s81
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
using Godot;
|
||||
using Newlon.Components.Zombies;
|
||||
using Newlon.Systems.Effects;
|
||||
|
||||
namespace Newlon.Components.Plants;
|
||||
|
||||
public partial class ReturnEffect : Node
|
||||
{
|
||||
[Export]
|
||||
private Effect _effectToReturn;
|
||||
|
||||
public void OnDamageRecieved(EntitySignalContext context)
|
||||
{
|
||||
if (context.deltaHP >= 0) return;
|
||||
if (context.source is RuntimeZombieData zombie)
|
||||
{
|
||||
zombie.GiveEffect(_effectToReturn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://bmtukcq10m8wo
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
using Godot;
|
||||
using Newlon.Components.Level;
|
||||
using Newlon.Resources;
|
||||
|
||||
namespace Newlon.Components.Plants;
|
||||
|
||||
//
|
||||
// Data that plant stores during runtime
|
||||
//
|
||||
|
||||
public partial class RuntimePlantData : Entity
|
||||
{
|
||||
public int Line { get; set; }
|
||||
public PlantResource Resource;
|
||||
private AudioStream eatenSound = ResourceLoader.Load<AudioStream>("res://assets/audio/sfx/gulp.mp3");
|
||||
public override void KillByDamage()
|
||||
{
|
||||
AudioSequencer.Play("plant_eaten", eatenSound);
|
||||
base.KillByDamage();
|
||||
}
|
||||
public override void Kill()
|
||||
{
|
||||
PoolContainer.Instance.RemoveEntity(GlobalPosition, Resource.Layer);
|
||||
QueueFree();
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://dli2i6albvugt
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
using Godot;
|
||||
using Newlon.Components.Level;
|
||||
|
||||
namespace Newlon.Components.Plants;
|
||||
|
||||
// Shoot component of some plants
|
||||
public partial class Shooter : Node2D
|
||||
{
|
||||
[Export] public PackedScene _projectile { get; protected set;}
|
||||
[Export] protected Timer _timer;
|
||||
|
||||
protected RuntimePlantData _plantData;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_plantData = GetParent<RuntimePlantData>();
|
||||
}
|
||||
|
||||
|
||||
public void Shoot()
|
||||
{
|
||||
if (_timer.TimeLeft > 0) return;
|
||||
|
||||
_timer.Start();
|
||||
SpawnProjectile();
|
||||
}
|
||||
|
||||
public virtual void SpawnProjectile()
|
||||
{
|
||||
var instance = _projectile.Instantiate<Node2D>();
|
||||
PoolContainer.Instance.Projectiles.AddChild(instance);
|
||||
instance.GlobalTransform = GlobalTransform;
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://ceprqkraw3v6m
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
using Godot;
|
||||
using Newlon.Components.Level;
|
||||
|
||||
namespace Newlon.Components.Plants;
|
||||
|
||||
public partial class ThreepeaterShooter : Shooter
|
||||
{
|
||||
public override void SpawnProjectile()
|
||||
{
|
||||
for(int i = -1; i <= 1; i++)
|
||||
{
|
||||
if (GetParent<Node2D>().GlobalPosition.Y+i*FieldParams.TileHeight >= FieldParams.RightFieldBoundary.Y || GetParent<Node2D>().GlobalPosition.Y+i*FieldParams.TileHeight <= FieldParams.LeftFieldBoundary.Y)
|
||||
continue;
|
||||
|
||||
var instance = _projectile.Instantiate<Node2D>();
|
||||
PoolContainer.Instance.Projectiles.AddChild(instance);
|
||||
instance.GlobalTransform = GlobalTransform;
|
||||
|
||||
if(i != 0)
|
||||
{
|
||||
var tween = CreateTween().SetEase(Tween.EaseType.Out).SetTrans(Tween.TransitionType.Sine);
|
||||
tween.TweenProperty(instance,"position:y",instance.Position.Y+i*FieldParams.TileHeight,0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://djpc0kvagpadv
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
using Godot;
|
||||
using Newlon.Components.Level;
|
||||
|
||||
namespace Newlon.Components.Plants.Behaviours;
|
||||
|
||||
public partial class AloeBehaviour : BaseBehaviour
|
||||
{
|
||||
[Export] private float _hpTreshold = 0.25f;
|
||||
private Timer _timer;
|
||||
private bool _charge = true;
|
||||
private PackedScene particlesPacked = ResourceLoader.Load<PackedScene>("uid://b3na62o5pu1gt");
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
base._Ready();
|
||||
_timer = GetNode<Timer>("Timer");
|
||||
}
|
||||
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
_tree.Set("parameters/Tree/conditions/charged",_charge);
|
||||
|
||||
var checkPos = GetParent<Node2D>().GlobalPosition + Vector2.Right * FieldParams.TileWidth;
|
||||
if(_charge && PoolContainer.Instance.TryGetEntity(checkPos, out RuntimePlantData plantData))
|
||||
{
|
||||
if((float)plantData.HP / (float)plantData.MaxHP < _hpTreshold)
|
||||
{
|
||||
_charge = false;
|
||||
_tree.Set("parameters/Tree/conditions/heal",true);
|
||||
_timer.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Heal()
|
||||
{
|
||||
var checkPos = GetParent<Node2D>().GlobalPosition + Vector2.Right * FieldParams.TileWidth;
|
||||
if (PoolContainer.Instance.TryGetEntity(checkPos, out RuntimePlantData plantData))
|
||||
{
|
||||
plantData.Heal(300, GetParent());
|
||||
var particles = particlesPacked.Instantiate<Node2D>();
|
||||
PoolContainer.Instance.Particles.AddChild(particles);
|
||||
particles.GlobalPosition = plantData.GlobalPosition;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnTimeout()
|
||||
{
|
||||
_charge = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://cljytsmqac0w7
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
using Godot;
|
||||
|
||||
namespace Newlon.Components;
|
||||
|
||||
public abstract partial class BaseBehaviour : Node
|
||||
{
|
||||
protected AnimationTree _tree;
|
||||
public override void _Ready()
|
||||
{
|
||||
_tree = GetNode<AnimationTree>("../AnimationTree");
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://3dbmgnr7qxee
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
using Godot;
|
||||
using Godot.Collections;
|
||||
|
||||
namespace Newlon.Components.Plants.Behaviours;
|
||||
|
||||
public partial class HpBasedBehaviour : BaseBehaviour
|
||||
{
|
||||
[Export] private Array<string> parameters;
|
||||
|
||||
public void OnHPChanged(EntitySignalContext context)
|
||||
{
|
||||
var calc = context.target.HP / context.target.MaxHP;
|
||||
foreach (var par in parameters)
|
||||
{
|
||||
_tree.Set(par, calc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://btkmd86pn828y
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
using Godot;
|
||||
|
||||
namespace Newlon.Components.Plants.Behaviours;
|
||||
|
||||
public partial class PeashooterBehaviour : BaseBehaviour
|
||||
{
|
||||
[Export] private Timer _shootTimer;
|
||||
[Export] private Eyesight _sight;
|
||||
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
bool readyToShoot = _sight.EnemyDetected && _shootTimer.TimeLeft <= 0;
|
||||
|
||||
_tree.Set("parameters/Tree/conditions/ready",readyToShoot);
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://bdk5iqtw4xbkl
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
using Godot;
|
||||
|
||||
namespace Newlon.Components.Plants.Behaviours;
|
||||
|
||||
public partial class PotatomineBehaviour : BaseBehaviour
|
||||
{
|
||||
[Export] private Area2D _hitbox;
|
||||
[Export] private Area2D detectionBox;
|
||||
[Export] private CollisionShape2D _unprimedShape;
|
||||
[Export] private CollisionShape2D _primedShape;
|
||||
private bool _primed = false;
|
||||
public void Prime()
|
||||
{
|
||||
_tree.Set("parameters/Tree/conditions/primed", true);
|
||||
|
||||
_hitbox.Monitorable = false;
|
||||
|
||||
_primed = true;
|
||||
_unprimedShape.Disabled = true;
|
||||
_primedShape.Disabled = false;
|
||||
|
||||
if (detectionBox.HasOverlappingAreas())
|
||||
{
|
||||
SetupExplosion();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnAreaEntered(Area2D area)
|
||||
{
|
||||
if (_primed == false) return;
|
||||
SetupExplosion();
|
||||
}
|
||||
private void SetupExplosion()
|
||||
{
|
||||
_tree.Set("parameters/Tree/conditions/explode", true);
|
||||
_primed = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://c7qfh4py0uulo
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
using Godot;
|
||||
|
||||
namespace Newlon.Components.Plants;
|
||||
|
||||
public partial class SnipachBehaviour : BaseBehaviour
|
||||
{
|
||||
[Export] public AreaAttack attackBox;
|
||||
[Export] public Timer timer;
|
||||
[Export] public Timer guardTimer;
|
||||
private bool dragging = false;
|
||||
|
||||
public void OnDragBegin()
|
||||
{
|
||||
if (timer.TimeLeft > 0 || guardTimer.TimeLeft > 0) return;
|
||||
dragging = true;
|
||||
attackBox.Visible = dragging;
|
||||
}
|
||||
|
||||
public void OnDragEnd(bool aborted)
|
||||
{
|
||||
if (dragging == false) return;
|
||||
dragging = false;
|
||||
attackBox.Visible = dragging;
|
||||
if (aborted) return;
|
||||
attackBox.Attack();
|
||||
timer.Start();
|
||||
}
|
||||
|
||||
public override void _PhysicsProcess(double delta)
|
||||
{
|
||||
if (dragging)
|
||||
{
|
||||
attackBox.GlobalPosition = (Cursor.GetCursorPosition() / FieldParams.Tile).Ceil() * FieldParams.Tile - new Vector2(20, 14);
|
||||
}
|
||||
if (timer.TimeLeft > 0)
|
||||
{
|
||||
GetParent<Node2D>().Modulate = Colors.DeepSkyBlue;
|
||||
}
|
||||
else
|
||||
{
|
||||
GetParent<Node2D>().Modulate = Colors.White;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://csgksiyma0h4t
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
using Godot;
|
||||
|
||||
namespace Newlon.Components.Plants.Behaviours;
|
||||
|
||||
public partial class SpikeweedBehaviour : BaseBehaviour
|
||||
{
|
||||
private int _inCount = 0;
|
||||
public void OnHitboxEntered(Area2D _area)
|
||||
{
|
||||
if (_inCount++ == 0)
|
||||
_tree.Set("parameters/Tree/blend_position",1);
|
||||
}
|
||||
|
||||
public void OnHitboxExited(Area2D _area)
|
||||
{
|
||||
if (--_inCount == 0)
|
||||
_tree.Set("parameters/Tree/blend_position",0);
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://dqquodxaijmem
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
using Godot;
|
||||
|
||||
namespace Newlon.Components.Plants.Behaviours;
|
||||
|
||||
public partial class SunflowerBehaviour : BaseBehaviour
|
||||
{
|
||||
public void Timeout()
|
||||
{
|
||||
_tree.Set("parameters/Tree/conditions/produce", true);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://bth7gah4tn7uj
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
using Godot;
|
||||
|
||||
namespace Newlon.Components.Zombies;
|
||||
|
||||
public partial class AudioDamage : AudioStreamPlayer2D
|
||||
{
|
||||
public void OnDamaged(int amount, Node origin)
|
||||
{
|
||||
Play();
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://bsg4utgc0u0vo
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
using Godot;
|
||||
using Newlon.Components.Plants;
|
||||
|
||||
|
||||
namespace Newlon.Components.Zombies;
|
||||
|
||||
public partial class EatBox : Area2D
|
||||
{
|
||||
// Rewrite this class completely when field system will be introduced.
|
||||
|
||||
[Export] public FloatModifiers _damage;
|
||||
[Export]
|
||||
private AudioStream biteSound = ResourceLoader.Load<AudioStream>("uid://dyid55nhflwyn");
|
||||
private RuntimePlantData plant;
|
||||
public float Damage => _damage.GetValue();
|
||||
|
||||
public bool isEating = false;
|
||||
|
||||
public void Bite()
|
||||
{
|
||||
if (GetParent<RuntimeZombieData>().AbleToEat)
|
||||
{
|
||||
plant?.TakeDamage(Damage, GetParent());
|
||||
AudioSequencer.Play("bite", biteSound);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void OnAreaEntered(Area2D area)
|
||||
{
|
||||
var parent = area.GetParent();
|
||||
|
||||
if (parent != null && parent is RuntimePlantData plantData)
|
||||
{
|
||||
plant = plantData;
|
||||
isEating = true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void OnAreaExited(Area2D area)
|
||||
{
|
||||
var parent = area.GetParent();
|
||||
|
||||
if (parent == plant)
|
||||
{
|
||||
plant = null;
|
||||
isEating = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://dqyony6jxt2p0
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue