file refactor
This commit is contained in:
parent
da5a3e874b
commit
bffb012a26
175 changed files with 1086 additions and 1107 deletions
|
|
@ -1,54 +0,0 @@
|
|||
using Godot;
|
||||
|
||||
namespace Newlon.Components;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class Armor : Node
|
||||
{
|
||||
[Signal]
|
||||
public delegate void ArmorDamagedEventHandler(float hp);
|
||||
[Signal]
|
||||
public delegate void ArmorLostEventHandler();
|
||||
|
||||
[Export]
|
||||
public float MaxHP { get; private set; }
|
||||
private float _hp;
|
||||
private bool _lost = false;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_hp = MaxHP;
|
||||
}
|
||||
|
||||
public float RecieveDamage(float damage)
|
||||
{
|
||||
if(_lost)
|
||||
return damage;
|
||||
float returnAmount = 0;
|
||||
_hp -= damage;
|
||||
if(_hp <= 0)
|
||||
{
|
||||
returnAmount = -_hp;
|
||||
_hp = 0;
|
||||
EmitSignal(SignalName.ArmorLost);
|
||||
_lost = true;
|
||||
}
|
||||
EmitSignal(SignalName.ArmorDamaged,_hp);
|
||||
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.ArmorDamaged,_hp);
|
||||
return returnAmount;
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://fd4im1fmwc5n
|
||||
|
|
@ -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.ArmorDamaged += OnZombieHPChanged;
|
||||
}
|
||||
|
||||
private void OnZombieHPChanged(float hp)
|
||||
{
|
||||
float percent = 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,158 +0,0 @@
|
|||
using Godot;
|
||||
using Godot.Collections;
|
||||
using Newlon.Systems.Effects;
|
||||
|
||||
namespace Newlon.Components;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class Entity : Node2D
|
||||
{
|
||||
#region Health points
|
||||
[Export] public float MaxHP;
|
||||
public float HP;
|
||||
[Signal] public delegate void OnHPChangedEventHandler(int deltaHP, Node origin);
|
||||
[Signal] public delegate void OnDamagedEventHandler();
|
||||
|
||||
public virtual void TakeDamage(float amount, Node origin)
|
||||
{
|
||||
HP -= amount;
|
||||
EmitSignal(SignalName.OnHPChanged, -amount, origin);
|
||||
EmitSignal(SignalName.OnDamaged);
|
||||
if (HP <= 0)
|
||||
{
|
||||
KillByDamage();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Heal(float amount, Node origin)
|
||||
{
|
||||
EmitSignal(SignalName.OnHPChanged, amount, origin);
|
||||
HP += amount;
|
||||
}
|
||||
|
||||
public virtual void KillByDamage()
|
||||
{
|
||||
Kill();
|
||||
}
|
||||
|
||||
public virtual void Kill()
|
||||
{
|
||||
QueueFree();
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
#region Brain
|
||||
[Export] private AnimationPlayer _player;
|
||||
[Export] private AnimationTree _tree;
|
||||
public virtual void DisableBrain()
|
||||
{
|
||||
_player.ProcessMode = ProcessModeEnum.Always;
|
||||
_tree.ProcessMode = ProcessModeEnum.Always;
|
||||
ProcessMode = ProcessModeEnum.Disabled;
|
||||
}
|
||||
|
||||
public virtual void EnableBrain()
|
||||
{
|
||||
_player.ProcessMode = ProcessModeEnum.Inherit;
|
||||
_tree.ProcessMode = ProcessModeEnum.Inherit;
|
||||
ProcessMode = ProcessModeEnum.Inherit;
|
||||
}
|
||||
#endregion
|
||||
#region Effects
|
||||
[Export] private Array<Effect> _effectImmunities = new();
|
||||
private readonly Dictionary<string, Effect> _activeEffectSlots = new();
|
||||
private readonly Dictionary<string, Timer> _effectSlotTimers = 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 (_effectImmunities.Contains(what))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string slot = what.Slot;
|
||||
if (_activeEffectSlots.ContainsKey(slot) == false)
|
||||
{
|
||||
InitSlot(slot);
|
||||
}
|
||||
|
||||
if (what == _activeEffectSlots[slot])
|
||||
{
|
||||
EmitSignal(SignalName.EffectContinued, what);
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitSignal(SignalName.EffectStarted, what);
|
||||
}
|
||||
|
||||
if (_activeEffectSlots[slot] != null)
|
||||
{
|
||||
_effectSlotTimers[slot].Stop();
|
||||
_activeEffectSlots[slot].Exit(this);
|
||||
}
|
||||
_effectSlotTimers[slot].WaitTime = what.Duration;
|
||||
_effectSlotTimers[slot].Start();
|
||||
|
||||
what.Enter(this);
|
||||
_activeEffectSlots[slot] = what;
|
||||
|
||||
}
|
||||
|
||||
private void InitSlot(string key)
|
||||
{
|
||||
_activeEffectSlots.Add(key, null);
|
||||
|
||||
var timer = new Timer() { Autostart = false, OneShot = true };
|
||||
AddChild(timer);
|
||||
timer.Timeout += () => { EndEffectAtSlot(key); };
|
||||
|
||||
_effectSlotTimers.Add(key, timer);
|
||||
|
||||
}
|
||||
|
||||
public void EndEffect(Effect what)
|
||||
{
|
||||
EndEffectAtSlot(what.Slot);
|
||||
}
|
||||
|
||||
public void ProcessEffects()
|
||||
{
|
||||
foreach (string key in _activeEffectSlots.Keys)
|
||||
_activeEffectSlots[key]?.Process(this);
|
||||
}
|
||||
|
||||
private void EndEffectAtSlot(string slot)
|
||||
{
|
||||
_activeEffectSlots[slot].Exit(this);
|
||||
_activeEffectSlots[slot] = null;
|
||||
|
||||
EmitSignal(SignalName.EffectEnded, _activeEffectSlots[slot]);
|
||||
|
||||
}
|
||||
#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;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://3tw88wj1nrj1
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
using Godot;
|
||||
using System;
|
||||
|
||||
namespace Newlon.Components;
|
||||
|
||||
public partial class FlashComponent : CanvasGroup
|
||||
{
|
||||
[Export] private float _flashDuration = 0.1f;
|
||||
private Tween _tween;
|
||||
private ShaderMaterial _shaderMaterial;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_shaderMaterial = Material as ShaderMaterial;
|
||||
}
|
||||
|
||||
public void DamageFlash(int damage,Node origin)
|
||||
{
|
||||
Flash();
|
||||
}
|
||||
|
||||
|
||||
public void Flash()
|
||||
{
|
||||
_tween?.Kill();
|
||||
_tween = CreateTween();
|
||||
|
||||
Action<float> action = SetAmount;
|
||||
_tween.TweenMethod(Callable.From(action),0.8f,0.0f,_flashDuration);
|
||||
}
|
||||
|
||||
private void SetAmount(float amount)
|
||||
{
|
||||
_shaderMaterial.SetShaderParameter("amount",amount);
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://c5vfccegyy01t
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
namespace Newlon.Components;
|
||||
|
||||
//
|
||||
// Base interface for entities
|
||||
//
|
||||
public interface IProjectile
|
||||
{
|
||||
public int Line { get; set; }
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://blbiq5r0w17hf
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
using Godot;
|
||||
using System;
|
||||
|
||||
namespace Newlon.Components;
|
||||
|
||||
public partial class LevelGUIElements : Control
|
||||
{
|
||||
public static LevelGUIElements Instance;
|
||||
|
||||
[Export]
|
||||
public HBoxContainer SeedpacketsHotbar;
|
||||
[Export]
|
||||
public TextureRect SunCounter;
|
||||
public override void _Ready()
|
||||
{
|
||||
Instance = this;
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://cwa1eydeiy3y4
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
using Godot;
|
||||
using Newlon.Components.Level;
|
||||
using Newlon.Systems.Effects;
|
||||
|
||||
namespace Newlon.Components;
|
||||
|
||||
//
|
||||
// Projectile that travels from left to right
|
||||
//
|
||||
|
||||
public partial class LinearProjectile : Area2D, IProjectile
|
||||
{
|
||||
[Export(hintString: "suffix:tile/sec")]
|
||||
private float _speed;
|
||||
[Export]
|
||||
private int _damage;
|
||||
[Export]
|
||||
private Effect _impactEffect;
|
||||
[Export]
|
||||
private PackedScene particles;
|
||||
private int _line;
|
||||
private bool used = false;
|
||||
public int Line { get => _line; set { _line = value; } }
|
||||
|
||||
|
||||
public override void _PhysicsProcess(double delta)
|
||||
{
|
||||
Translate(Vector2.Right * _speed * (float)delta * Utility.TileWidth);
|
||||
}
|
||||
|
||||
public void OnAreaEntered(Area2D area)
|
||||
{
|
||||
if (used == true) return;
|
||||
var entity = area.GetParent<Entity>();
|
||||
if (entity != null)
|
||||
{
|
||||
entity.TakeDamage(_damage,this);
|
||||
used = true;
|
||||
if (_impactEffect != null)
|
||||
entity.GiveEffect(_impactEffect);
|
||||
|
||||
PoolContainer.Instance.SpawnParticles(particles, GlobalPosition);
|
||||
|
||||
QueueFree();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://dxlwvwy3hj56x
|
||||
|
|
@ -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,9 +0,0 @@
|
|||
using Godot;
|
||||
|
||||
public partial class ExitButton : Button
|
||||
{
|
||||
public override void _Pressed()
|
||||
{
|
||||
GetTree().ChangeSceneToFile("uid://bfstrli64u23y");
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://dpdpv2oyxdna7
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
using Godot;
|
||||
|
||||
namespace Newlon.Components.GUI;
|
||||
|
||||
public partial class FastForwardButton : Button
|
||||
{
|
||||
[Export] private Texture2D firstSpeed;
|
||||
[Export] private Texture2D secondSpeed;
|
||||
[Export] private Texture2D thirdSpeed;
|
||||
|
||||
[Export] private AnimationPlayer flashAnimator;
|
||||
|
||||
private int speed = 1;
|
||||
|
||||
public void OnPressed()
|
||||
{
|
||||
speed = Mathf.Wrap(speed+1, 1, 4);
|
||||
|
||||
switch (speed)
|
||||
{
|
||||
case 1:
|
||||
Icon = firstSpeed;
|
||||
break;
|
||||
case 2:
|
||||
Icon = secondSpeed;
|
||||
break;
|
||||
case 3:
|
||||
Icon = thirdSpeed;
|
||||
break;
|
||||
}
|
||||
|
||||
flashAnimator.Play("flash");
|
||||
|
||||
Engine.TimeScale = speed;
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://cwn3bd2k7mdq6
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
using Godot;
|
||||
using System;
|
||||
|
||||
public partial class PauseButton : Button
|
||||
{
|
||||
public override void _Pressed()
|
||||
{
|
||||
PauseMenu.Pause();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://cmfhiun6yrlr6
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
using Godot;
|
||||
using System;
|
||||
|
||||
public partial class PauseMenu : Control
|
||||
{
|
||||
private static PauseMenu Instance;
|
||||
public override void _Ready()
|
||||
{
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
public void Continue()
|
||||
{
|
||||
GetParent<Control>().Visible = false;
|
||||
GetTree().Paused = false;
|
||||
}
|
||||
public void Restart()
|
||||
{
|
||||
GetTree().Paused = false;
|
||||
GetTree().ReloadCurrentScene();
|
||||
}
|
||||
public void Exit()
|
||||
{
|
||||
GetTree().ChangeSceneToFile("uid://bfstrli64u23y");
|
||||
}
|
||||
public static void Pause()
|
||||
{
|
||||
Instance.GetParent<Control>().Visible = true;
|
||||
Instance.GetTree().Paused = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://gvwhpjoame6m
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
using Godot;
|
||||
using System;
|
||||
|
||||
public partial class RestartButton : Button
|
||||
{
|
||||
public override void _Pressed()
|
||||
{
|
||||
GetTree().Paused = false;
|
||||
GetTree().ReloadCurrentScene();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://btqwxelqxheh3
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
using Godot;
|
||||
using Newlon.Components.Plants;
|
||||
using Newlon.Components.Level;
|
||||
|
||||
namespace Newlon.Components.GUI;
|
||||
|
||||
public partial class ShovelButton : TextureButton
|
||||
{
|
||||
[Export] private PackedScene particles;
|
||||
private void OnFocusExited()
|
||||
{
|
||||
ButtonPressed = false;
|
||||
}
|
||||
public override void _Toggled(bool toggledOn)
|
||||
{
|
||||
Cursor.Instance.shovel = toggledOn;
|
||||
Cursor.Instance.UpdateCursor();
|
||||
}
|
||||
|
||||
public override void _Input(InputEvent @event)
|
||||
{
|
||||
|
||||
if (@event.IsActionPressed("primary_action") && ButtonPressed)
|
||||
{
|
||||
var checkedPosition = (PoolContainer.Instance.Plants.GetGlobalMousePosition() / Utility.Tile).Ceil() * Utility.Tile - new Vector2(20, 14);
|
||||
|
||||
for (int i = Utility.LayersCount-1; i >= 0; i--)
|
||||
{
|
||||
if (PoolContainer.Instance.EntityField[i].TryGetValue(checkedPosition, out var entity) && entity is RuntimePlantData plantData)
|
||||
{
|
||||
plantData.Kill();
|
||||
|
||||
PoolContainer.Instance.SpawnParticles(particles, plantData.GlobalPosition + Vector2.Down * Utility.TileHeight/2.0f);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
ButtonPressed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://d4dbg0us5ngxy
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
using Godot;
|
||||
using Newlon.Components.Level;
|
||||
|
||||
namespace Newlon.Components.GUI;
|
||||
|
||||
public partial class SunCounter : Label
|
||||
{
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
Text = RuntimeLevelData.Instance.SunCount.ToString();
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://dwxohya1exdkh
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
using Godot;
|
||||
using Newlon;
|
||||
using System;
|
||||
|
||||
public partial class SunCounterImage : Control
|
||||
{
|
||||
public override void _Ready()
|
||||
{
|
||||
Sun.Counter = this;
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://0ekxnoq6cyt4
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
using Godot;
|
||||
using Newlon.Components.GUI.Seedpackets;
|
||||
|
||||
namespace Newlon.Components.GUI;
|
||||
|
||||
public partial class VeilResizer : TextureProgressBar
|
||||
{
|
||||
[Export] private Timer _referenceTimer;
|
||||
private Seedpacket seedpacket;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
seedpacket = GetParent<Seedpacket>();
|
||||
}
|
||||
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
if (seedpacket.Disabled && _referenceTimer.IsStopped())
|
||||
Value = 1.0;
|
||||
else
|
||||
Value = _referenceTimer.TimeLeft / _referenceTimer.WaitTime;
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://ddi84kmmq1qla
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
using Godot;
|
||||
using Newlon.Components.GUI.Seedpackets;
|
||||
|
||||
public partial class AlmanachGrid : GridContainer
|
||||
{
|
||||
private PackedScene _plantCard;
|
||||
[Export]
|
||||
private bool _zombies;
|
||||
public override void _Ready()
|
||||
{
|
||||
_plantCard = ResourceLoader.Load<PackedScene>("res://scenes/gui/seedpacket.tscn");
|
||||
|
||||
if (_zombies)
|
||||
{
|
||||
foreach (var resource in GameRegistry.GetZombies())
|
||||
{
|
||||
Seedpacket slot = _plantCard.Instantiate<Seedpacket>();
|
||||
AddChild(slot);
|
||||
|
||||
slot.SetResource(resource);
|
||||
slot.SetHandler(new AlmanachHandler(slot));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var resource in GameRegistry.GetPlants())
|
||||
{
|
||||
Seedpacket slot = _plantCard.Instantiate<Seedpacket>();
|
||||
AddChild(slot);
|
||||
|
||||
slot.SetResource(resource);
|
||||
slot.SetHandler(new AlmanachHandler(slot));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://0mvmfvwe1bc7
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
using Godot;
|
||||
using Newlon.Components.GUI.Seedpackets;
|
||||
|
||||
namespace Newlon.Components.GUI;
|
||||
|
||||
public partial class GridLoader : GridContainer
|
||||
{
|
||||
private const string PLANT_RESOURCE_PATH = "res://resources/plants/";
|
||||
private PackedScene _plantCard;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_plantCard = ResourceLoader.Load<PackedScene>("res://scenes/gui/seedpacket.tscn");
|
||||
|
||||
foreach(var resource in GameRegistry.GetPlants())
|
||||
{
|
||||
Seedpacket slot = _plantCard.Instantiate<Seedpacket>();
|
||||
AddChild(slot);
|
||||
|
||||
slot.SetResource(resource);
|
||||
slot.SetHandler(new ChoosableHandler(slot));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://eq3ecja30mlj
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
using Godot;
|
||||
using Newlon.Components.Level;
|
||||
|
||||
namespace Newlon.Components.GUI;
|
||||
|
||||
public partial class LevelRunButton : Button
|
||||
{
|
||||
[Export] private AnimationPlayer _player;
|
||||
public override void _Pressed()
|
||||
{
|
||||
RuntimeLevelData.Instance.SetLevelState(RuntimeLevelData.LevelStates.Game);
|
||||
GetTree().Paused = false;
|
||||
|
||||
_player.Play("Hide");
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://d26waisd3v488
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
using Godot;
|
||||
using Newlon;
|
||||
using Newlon.Components;
|
||||
using Newlon.Components.GUI.Seedpackets;
|
||||
using Newlon.Components.Plants;
|
||||
|
||||
public partial class Previewport : SubViewport
|
||||
{
|
||||
private Node current_display;
|
||||
private Texture2D start_Field;
|
||||
|
||||
[Export] private Label title;
|
||||
[Export] private RichTextLabel description;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
GetParent().GetViewport().GuiFocusChanged += OnFocusChanged;
|
||||
start_Field = GetNode<Sprite2D>("FrameField").Texture;
|
||||
}
|
||||
|
||||
public void OnFocusChanged(Control node)
|
||||
{
|
||||
if (GetParent<Control>().IsVisibleInTree() == false) return;
|
||||
if (node is Seedpacket packet)
|
||||
{
|
||||
ChangeDisplay(packet.GetResource());
|
||||
}
|
||||
}
|
||||
|
||||
private void ChangeDisplay(DisplayResource resource)
|
||||
{
|
||||
// Expand with updates
|
||||
if (current_display != null)
|
||||
{
|
||||
current_display.QueueFree();
|
||||
}
|
||||
if (resource.customFrame != null && resource.customFrame.almanachField != null)
|
||||
{
|
||||
GetNode<Sprite2D>("FrameField").Texture = resource.customFrame.almanachField;
|
||||
}
|
||||
else
|
||||
GetNode<Sprite2D>("FrameField").Texture = start_Field;
|
||||
current_display = resource.Scene.Instantiate();
|
||||
title.Text = Tr(resource.name_key);
|
||||
description.Text = Tr(resource.description_key);
|
||||
AddChild(current_display);
|
||||
if (current_display is Entity entity)
|
||||
entity.DisableBrain();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://covbig00p22di
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
extends RichTextLabel
|
||||
|
||||
func _on_meta_clicked(meta: Variant) -> void:
|
||||
OS.shell_open(meta)
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://drru785m4eep
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
extends Node
|
||||
|
||||
|
||||
func _on_play_button_pressed() -> void:
|
||||
get_tree().change_scene_to_file("res://scenes/prototype_survival.tscn")
|
||||
$ChannelPlayer.call("Play")
|
||||
|
||||
|
||||
func _on_exit_button_pressed() -> void:
|
||||
get_tree().quit()
|
||||
$ChannelPlayer.call("Play")
|
||||
|
||||
|
||||
func _on_button_pressed() -> void:
|
||||
$"../AboutWindow".popup_centered()
|
||||
$ChannelPlayer.call("Play")
|
||||
|
||||
|
||||
func _on_almanach_button_pressed() -> void:
|
||||
$"../Almanach".visible = true
|
||||
$ChannelPlayer.call("Play")
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://c06k4k3ww48ev
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
extends AcceptDialog
|
||||
|
||||
static var seen = false
|
||||
|
||||
func _ready() -> void:
|
||||
if seen:
|
||||
return
|
||||
seen = true
|
||||
popup_centered()
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://dgevhrbucpwrs
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
using Godot;
|
||||
|
||||
namespace Newlon.Components.GUI.Seedpackets;
|
||||
|
||||
public class AlmanachHandler : SeedpacketHandler
|
||||
{
|
||||
public AlmanachHandler(Seedpacket owner) : base(owner)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://pse018r220mt
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
namespace Newlon.Components.GUI.Seedpackets;
|
||||
|
||||
public class ChoosableHandler : SeedpacketHandler, ISeedpacketPress
|
||||
{
|
||||
public ChoosableHandler(Seedpacket owner) : base(owner)
|
||||
{
|
||||
}
|
||||
|
||||
public void Pressed()
|
||||
{
|
||||
if (LevelGUIElements.Instance.SeedpacketsHotbar.GetChildCount() > 9) return;
|
||||
_owner.disablePacket = true;
|
||||
|
||||
var hotbarSeedpacket = Seedpacket.Prefab.Instantiate<Seedpacket>();
|
||||
LevelGUIElements.Instance.SeedpacketsHotbar.AddChild(hotbarSeedpacket);
|
||||
hotbarSeedpacket.SetResource(_owner.GetResource());
|
||||
|
||||
var pregameHandler = new HotbarPregameHandler(hotbarSeedpacket);
|
||||
hotbarSeedpacket.SetHandler(pregameHandler);
|
||||
pregameHandler.Clicked += OnHotbarClicked;
|
||||
|
||||
AudioSequencer.Play("tap", Seedpacket.TapStream);
|
||||
}
|
||||
|
||||
public void OnHotbarClicked()
|
||||
{
|
||||
_owner.disablePacket = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://b3sut12n56w1y
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
using Godot;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class CustomSeedpacketFrame : Resource
|
||||
{
|
||||
[Export] public Texture2D frame;
|
||||
[Export] public LabelSettings font;
|
||||
[Export] public Texture2D almanachField;
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://3m7xks3xq3hl
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
using Newlon.Components.Level;
|
||||
|
||||
namespace Newlon.Components.GUI.Seedpackets;
|
||||
|
||||
public class HotbarHandler : SeedpacketHandler, ISeedpacketPress, ISeedpacketProcess, ISeedpacketUnfocus
|
||||
{
|
||||
public HotbarHandler(Seedpacket owner) : base(owner)
|
||||
{
|
||||
}
|
||||
|
||||
public void Pressed()
|
||||
{
|
||||
PlantField.Instance.SetPlant(_owner, _owner.GetResource());
|
||||
AudioSequencer.Play("lift_seed", Seedpacket.LiftStream);
|
||||
}
|
||||
|
||||
public void Process()
|
||||
{
|
||||
_owner.disablePacket = RuntimeLevelData.Instance.SunCount < _owner.GetResource().Cost;
|
||||
}
|
||||
public void OnUnfocused()
|
||||
{
|
||||
PlantField.Instance.ResetPlant();
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://gvgt14v1hndn
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
using System;
|
||||
using Newlon.Components.Level;
|
||||
|
||||
namespace Newlon.Components.GUI.Seedpackets;
|
||||
|
||||
public class HotbarPregameHandler : SeedpacketHandler, ISeedpacketPress
|
||||
{
|
||||
public HotbarPregameHandler(Seedpacket owner) : base(owner)
|
||||
{
|
||||
RuntimeLevelData.Instance.OnLevelStateChanged += OnLevelStateChanged;
|
||||
|
||||
}
|
||||
|
||||
public event Action Clicked;
|
||||
public void Pressed()
|
||||
{
|
||||
if (Clicked != null) Clicked();
|
||||
_owner.QueueFree();
|
||||
AudioSequencer.Play("tap", Seedpacket.UntapStream);
|
||||
}
|
||||
|
||||
public void OnLevelStateChanged(RuntimeLevelData.LevelStates state)
|
||||
{
|
||||
if (state == RuntimeLevelData.LevelStates.Game)
|
||||
{
|
||||
_owner.SetHandler(new HotbarHandler(_owner));
|
||||
}
|
||||
else if (state != RuntimeLevelData.LevelStates.ChooseYourSeeds)
|
||||
{
|
||||
_owner.disablePacket = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://bnygd8pcmoewp
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
namespace Newlon.Components.GUI.Seedpackets;
|
||||
|
||||
public interface ISeedpacketPress
|
||||
{
|
||||
public void Pressed();
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://o0ly38oqcuwu
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
namespace Newlon.Components.GUI.Seedpackets;
|
||||
|
||||
public interface ISeedpacketProcess
|
||||
{
|
||||
public void Process();
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://q2r43hym7s82
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
namespace Newlon.Components.GUI.Seedpackets;
|
||||
|
||||
public interface ISeedpacketUnfocus
|
||||
{
|
||||
public void OnUnfocused();
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://mdm8cepvvo4t
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
using Godot;
|
||||
|
||||
namespace Newlon.Components.GUI.Seedpackets;
|
||||
|
||||
public partial class Seedpacket : TextureButton
|
||||
{
|
||||
public static AudioStream TapStream;
|
||||
public static AudioStream UntapStream;
|
||||
public static AudioStream LiftStream;
|
||||
private const string PATH_TO_PACKED_SCENE = "res://scenes/gui/seedpacket.tscn";
|
||||
private DisplayResource _resource;
|
||||
private Label _cost;
|
||||
private TextureRect _icon;
|
||||
private Timer _timer;
|
||||
private SeedpacketHandler _handler;
|
||||
|
||||
public bool disablePacket = false;
|
||||
|
||||
public static PackedScene Prefab { get; private set; }
|
||||
|
||||
// Node overrides
|
||||
public override void _Ready()
|
||||
{
|
||||
if (TapStream == null)
|
||||
{
|
||||
TapStream = ResourceLoader.Load<AudioStream>("res://assets/audio/gui/tap.mp3");
|
||||
UntapStream = ResourceLoader.Load<AudioStream>("res://assets/audio/gui/tap2.mp3");
|
||||
LiftStream = ResourceLoader.Load<AudioStream>("res://assets/audio/gui/seedlift.mp3");
|
||||
}
|
||||
if (_resource != null)
|
||||
UpdateContents();
|
||||
if (Prefab == null)
|
||||
{
|
||||
Prefab = ResourceLoader.Load<PackedScene>(PATH_TO_PACKED_SCENE);
|
||||
}
|
||||
_cost = GetNode<Label>("Cost");
|
||||
_icon = GetNode<TextureRect>("PlantPreviewContainer/Preview");
|
||||
_timer = GetNode<Timer>("RechargeTimer");
|
||||
}
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
Disabled = disablePacket || _timer.TimeLeft > 0;
|
||||
if (Disabled)
|
||||
{
|
||||
FocusMode = FocusModeEnum.None;
|
||||
}
|
||||
else
|
||||
{
|
||||
FocusMode = FocusModeEnum.All;
|
||||
}
|
||||
if (_handler is ISeedpacketProcess processHandler) processHandler.Process();
|
||||
}
|
||||
public void SetResource(DisplayResource resource )
|
||||
{
|
||||
_resource = resource;
|
||||
|
||||
UpdateContents();
|
||||
}
|
||||
|
||||
public DisplayResource GetResource()
|
||||
{
|
||||
return _resource;
|
||||
}
|
||||
|
||||
public void SetHandler(SeedpacketHandler newHandler)
|
||||
{
|
||||
disablePacket = false;
|
||||
_handler = newHandler;
|
||||
}
|
||||
|
||||
protected virtual void UpdateContents()
|
||||
{
|
||||
_cost.Text = _resource.Cost.ToString();
|
||||
_icon.Texture = _resource.Preview;
|
||||
_timer.WaitTime = _resource.ReloadTime;
|
||||
if (_resource.customFrame != null)
|
||||
{
|
||||
TextureNormal = _resource.customFrame.frame;
|
||||
_cost.LabelSettings = _resource.customFrame.font;
|
||||
}
|
||||
}
|
||||
|
||||
public override void _Pressed()
|
||||
{
|
||||
if (_handler is ISeedpacketPress pressHandler)
|
||||
pressHandler.Pressed();
|
||||
}
|
||||
|
||||
public void Recharge()
|
||||
{
|
||||
_timer.Start();
|
||||
ReleaseFocus();
|
||||
}
|
||||
|
||||
public void OnUnfocused()
|
||||
{
|
||||
if (_handler is ISeedpacketUnfocus unfocusHandler) unfocusHandler.OnUnfocused();
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://cn6ddajdtf4ep
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
namespace Newlon.Components.GUI.Seedpackets;
|
||||
|
||||
public class SeedpacketHandler
|
||||
{
|
||||
protected Seedpacket _owner;
|
||||
|
||||
public SeedpacketHandler(Seedpacket owner)
|
||||
{
|
||||
_owner = owner;
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://cr774updc04fu
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
using Godot;
|
||||
using Newlon;
|
||||
|
||||
public partial class LeftBoundaryMarker : Marker2D
|
||||
{
|
||||
public override void _Ready()
|
||||
{
|
||||
Utility.LeftFieldBoundary = (Vector2I)GlobalPosition;
|
||||
QueueFree();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://d2dq6f0bk7pfx
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
using Godot;
|
||||
using Newlon.Components.Zombies;
|
||||
|
||||
namespace Newlon.Components.Level;
|
||||
|
||||
public partial class LoseCheckbox : Area2D
|
||||
{
|
||||
[Export] private CanvasLayer gameOverLayer;
|
||||
[Export] private AnimationPlayer fadeAnimation;
|
||||
public override void _Ready()
|
||||
{
|
||||
AreaEntered += OnAreaEntered;
|
||||
}
|
||||
|
||||
private void OnAreaEntered(Area2D area)
|
||||
{
|
||||
var parent = area.GetParent();
|
||||
if (parent != null && parent is RuntimeZombieData zombieData)
|
||||
{
|
||||
Engine.TimeScale = 1.0;
|
||||
fadeAnimation.Play("fade");
|
||||
GetTree().Paused = true;
|
||||
PhysicsServer2D.SetActive(true);
|
||||
Callable.From(()=>
|
||||
{
|
||||
zombieData.Reparent(gameOverLayer);
|
||||
}).CallDeferred();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://812ldoyxd5n5
|
||||
|
|
@ -1,110 +0,0 @@
|
|||
using Godot;
|
||||
using Newlon.Components.GUI.Seedpackets;
|
||||
using Newlon.Components.Plants;
|
||||
|
||||
namespace Newlon.Components.Level;
|
||||
|
||||
public partial class PlantField : Node2D
|
||||
{
|
||||
private Node2D _plantSetter;
|
||||
private DisplayResource _resource;
|
||||
private Seedpacket _slot;
|
||||
private bool _previousCanPlace;
|
||||
private ChannelPlayer player;
|
||||
[Export] private PackedScene particles;
|
||||
public static PlantField Instance {get; private set;}
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
Instance = this;
|
||||
_plantSetter = GetChild<Node2D>(0);
|
||||
player = GetNode<ChannelPlayer>("PlantPlayer");
|
||||
}
|
||||
|
||||
public void SetPlant(Seedpacket slot, DisplayResource resource)
|
||||
{
|
||||
_resource = resource;
|
||||
_slot = slot;
|
||||
if (resource == null)
|
||||
{
|
||||
foreach(var child in _plantSetter.GetChildren())
|
||||
child.QueueFree();
|
||||
}
|
||||
else
|
||||
{
|
||||
var scene = resource.Scene.Instantiate<Node2D>();
|
||||
_plantSetter.AddChild(scene);
|
||||
scene.UseParentMaterial = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void ResetPlant()
|
||||
{
|
||||
SetPlant(null,null);
|
||||
}
|
||||
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
// Getting and storing global mouse position, setting plant-poiner to it
|
||||
var mouse_pos = GetGlobalMousePosition();
|
||||
_plantSetter.GlobalPosition = mouse_pos;
|
||||
|
||||
// Getting position in grid coordinates
|
||||
var expected_pos = (_plantSetter.GlobalPosition / Utility.Tile).Ceil() * Utility.Tile - new Vector2(20, 14);
|
||||
|
||||
// Checking for boundaries
|
||||
bool inBoundary = expected_pos.X > Utility.LeftFieldBoundary.X && expected_pos.X < Utility.RightFieldBoundary.X && expected_pos.Y > Utility.LeftFieldBoundary.Y && expected_pos.Y < Utility.RightFieldBoundary.Y;
|
||||
|
||||
|
||||
bool canPlace = _resource != null
|
||||
&& inBoundary
|
||||
&& PoolContainer.Instance.EntityField[_resource.Layer].ContainsKey(expected_pos) == false
|
||||
&& RuntimeLevelData.Instance.CheckSpendSun(_resource.Cost);
|
||||
|
||||
// Setting visuals
|
||||
if (_previousCanPlace != canPlace)
|
||||
{
|
||||
if (canPlace)
|
||||
{
|
||||
Material.Set("shader_parameter/amount", 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
Material.Set("shader_parameter/amount", 1);
|
||||
}
|
||||
Cursor.Instance.plant = canPlace;
|
||||
Cursor.Instance.UpdateCursor();
|
||||
}
|
||||
_previousCanPlace = canPlace;
|
||||
|
||||
if (canPlace)
|
||||
_plantSetter.GlobalPosition = expected_pos;
|
||||
}
|
||||
|
||||
public override void _UnhandledInput(InputEvent @event)
|
||||
{
|
||||
if (@event.IsActionPressed("cancel_plant") && _slot != null)
|
||||
{
|
||||
_slot.ReleaseFocus();
|
||||
}
|
||||
|
||||
if (@event.IsActionPressed("primary_action") && _previousCanPlace)
|
||||
{
|
||||
var plant = _resource.Scene.Instantiate<RuntimePlantData>();
|
||||
PoolContainer.Instance.Plants.AddChild(plant);
|
||||
plant.GlobalPosition = (_plantSetter.GlobalPosition / Utility.Tile).Ceil() * Utility.Tile - new Vector2(20, 14);
|
||||
plant.Resource = (PlantResource)_resource;
|
||||
|
||||
PoolContainer.Instance.EntityField[_resource.Layer].Add(plant.GlobalPosition, plant);
|
||||
|
||||
RuntimeLevelData.Instance.SpendSun(_resource.Cost);
|
||||
|
||||
PoolContainer.Instance.SpawnParticles(particles, plant.GlobalPosition + Vector2.Down * Utility.TileHeight/2.0f);
|
||||
|
||||
player.Play();
|
||||
|
||||
// Unfocusing and recharging slot
|
||||
_slot.Recharge();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://bj7rw2f6qu1lg
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
using Godot;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Newlon.Components.Level;
|
||||
|
||||
//
|
||||
// PoolContainer contains nodes that contain different elemnts that generate during runtime
|
||||
// Is not pool in traditional sense, but named like that to prevent repetition
|
||||
//
|
||||
|
||||
public partial class PoolContainer : Node2D
|
||||
{
|
||||
[Export]
|
||||
public Node2D Zombies { get; private set; }
|
||||
[Export]
|
||||
public Node2D Plants { get; private set; }
|
||||
[Export]
|
||||
public Node2D Projectiles { get; private set; }
|
||||
[Export]
|
||||
public Node2D Structures { get; private set; }
|
||||
[Export]
|
||||
public Node2D Particles { get; private set; }
|
||||
|
||||
public static PoolContainer Instance { get; private set; }
|
||||
|
||||
public Dictionary<Vector2, Entity>[] EntityField = { new(), new(), new() };
|
||||
public override void _Ready()
|
||||
{
|
||||
Instance = this;
|
||||
}
|
||||
public bool TryGetEntity(Vector2 key, out Entity result, int layer = 1)
|
||||
{
|
||||
if (EntityField[layer].ContainsKey(key))
|
||||
{
|
||||
result = EntityField[layer][key];
|
||||
}
|
||||
else
|
||||
{
|
||||
result = null;
|
||||
}
|
||||
return EntityField[layer].ContainsKey(key)
|
||||
&& EntityField[layer][key] != null;
|
||||
}
|
||||
|
||||
public bool TryGetEntity<T>(Vector2 key, out T result, int layer = 1) where T : class
|
||||
{
|
||||
if (EntityField[layer].ContainsKey(key))
|
||||
{
|
||||
result = EntityField[layer][key] as T;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = null;
|
||||
}
|
||||
return EntityField[layer].ContainsKey(key)
|
||||
&& EntityField[layer][key] != null
|
||||
&& result != null;
|
||||
}
|
||||
|
||||
public void SpawnParticles(PackedScene particles, Vector2 position)
|
||||
{
|
||||
var emitter = particles.Instantiate<StandardParticles>();
|
||||
Instance.Particles.AddChild(emitter);
|
||||
emitter.GlobalPosition = position;
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://bso32xkw738sy
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
using Godot;
|
||||
using Newlon;
|
||||
|
||||
public partial class RightBoundaryMarker : Marker2D
|
||||
{
|
||||
public override void _Ready()
|
||||
{
|
||||
Utility.RightFieldBoundary = (Vector2I)GlobalPosition;
|
||||
QueueFree();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://bymylx25skfot
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
using System;
|
||||
using Godot;
|
||||
|
||||
namespace Newlon.Components.Level;
|
||||
|
||||
public partial class RuntimeLevelData : Node
|
||||
{
|
||||
public enum LevelStates
|
||||
{
|
||||
ChooseYourSeeds,
|
||||
Pregame,
|
||||
Game,
|
||||
Win,
|
||||
Loose
|
||||
}
|
||||
|
||||
[Export]
|
||||
public float SunCount { get; private set; } = 0;
|
||||
public event Action<LevelStates> OnLevelStateChanged;
|
||||
|
||||
public static RuntimeLevelData Instance { get; private set; }
|
||||
|
||||
private LevelStates _currentState = LevelStates.ChooseYourSeeds;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
Instance = this;
|
||||
GetTree().Paused = true;
|
||||
}
|
||||
|
||||
#region Sun
|
||||
public void AddSun(float amount)
|
||||
{
|
||||
SunCount += amount;
|
||||
}
|
||||
|
||||
public void SpendSun(float amount)
|
||||
{
|
||||
SunCount -= amount;
|
||||
}
|
||||
|
||||
public bool CheckSpendSun(float amount)
|
||||
{
|
||||
if (SunCount - amount < 0) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
#endregion
|
||||
|
||||
public void SetLevelState(LevelStates state)
|
||||
{
|
||||
OnLevelStateChanged(state);
|
||||
_currentState = state;
|
||||
}
|
||||
|
||||
//private Array<PlantResource> _selectedPlants;
|
||||
//private bool _selected;
|
||||
//public Array<PlantResource> GetSelectedPlants();
|
||||
//public bool TrySelectPlants(Array<PlantResource>);
|
||||
//public void ResetSelection();
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://bndu1h5kgcde8
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
using Godot;
|
||||
|
||||
namespace Newlon.Components.Level;
|
||||
|
||||
public partial class SunSpawner : Node
|
||||
{
|
||||
[Export]
|
||||
public int MinSun = 25;
|
||||
[Export]
|
||||
public int MaxSun = 25;
|
||||
|
||||
[Export]
|
||||
private PackedScene SunScene;
|
||||
|
||||
public void Spawn()
|
||||
{
|
||||
float x = GD.Randf()*9*Utility.TileWidth;
|
||||
uint y = GD.Randi() % 5;
|
||||
|
||||
var sun = SunScene.Instantiate<Sun>();
|
||||
PoolContainer.Instance.Projectiles.AddChild(sun);
|
||||
|
||||
sun.GlobalPosition = new Vector2(Utility.LeftFieldBoundary.X + x, -90);
|
||||
|
||||
var moveTween = CreateTween();
|
||||
moveTween.TweenProperty(sun,"global_position", new Vector2(Utility.LeftFieldBoundary.X + x,
|
||||
Utility.LeftFieldBoundary.Y + Utility.TileHeight * y + Utility.TileHeight/2.0f),9-y);
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://cslqjdd5wq4rc
|
||||
|
|
@ -1,170 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
using Godot;
|
||||
using Godot.Collections;
|
||||
|
||||
public partial class SurvivalZombieSpawner : Node
|
||||
{
|
||||
// Zombie pools
|
||||
// Points from pools go in that order: support -> tank -> horde -> bank
|
||||
// Horde pool is allowed to shrink during runtime
|
||||
[Export] private Array<string> supportPool;
|
||||
[Export] private Array<string> tankPool;
|
||||
[Export] private Array<string> hordePool;
|
||||
|
||||
private List<ZombieResource> cachedSupportPool;
|
||||
private List<ZombieResource> cachedTankPool;
|
||||
private List<ZombieResource> cachedHordePool;
|
||||
|
||||
private float minSupportPoints;
|
||||
private float minTankPoints;
|
||||
private float minHordePoints;
|
||||
|
||||
[Export] private float points = 0;
|
||||
[Export] private float huge_wave_points;
|
||||
[Export] private Curve velocity_curve;
|
||||
private float velocity = 0;
|
||||
[Export] private double time = 0.0;
|
||||
private float fin_a;
|
||||
private RandomNumberGenerator rng = new();
|
||||
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
rng.Randomize();
|
||||
|
||||
cachedSupportPool = LoadFromRegistry(supportPool);
|
||||
cachedTankPool = LoadFromRegistry(tankPool);
|
||||
cachedHordePool = LoadFromRegistry(hordePool);
|
||||
|
||||
cachedTankPool.Sort((x, y) =>
|
||||
{
|
||||
return (int)(x.Cost - y.Cost);
|
||||
});
|
||||
cachedHordePool.Sort((x, y) =>
|
||||
{
|
||||
return (int)(x.Cost - y.Cost);
|
||||
});
|
||||
|
||||
minSupportPoints = cachedSupportPool[0].Cost;
|
||||
minTankPoints = cachedTankPool[0].Cost;
|
||||
minHordePoints = cachedHordePool[0].Cost;
|
||||
|
||||
fin_a = (velocity_curve.Sample(velocity_curve.MaxDomain) - velocity_curve.Sample(velocity_curve.MaxDomain - 0.001f)) / 0.001f;
|
||||
}
|
||||
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
points += velocity * (float)delta;
|
||||
|
||||
if (time > velocity_curve.MaxDomain)
|
||||
{
|
||||
velocity += fin_a * (float)delta;
|
||||
}
|
||||
else
|
||||
{
|
||||
velocity = velocity_curve.Sample((float)time);
|
||||
}
|
||||
time += delta;
|
||||
}
|
||||
|
||||
public void SummonWave()
|
||||
{
|
||||
bool big_wave = false;
|
||||
if ((int)time % 300 == 0)
|
||||
{
|
||||
points += velocity/velocity_curve.Sample((float)time)*huge_wave_points;
|
||||
big_wave = true;
|
||||
}
|
||||
|
||||
float support_points = points * 0.2f;
|
||||
float tank_points = points * 0.5f;
|
||||
float horde_points = points * 0.3f;
|
||||
points = 0;
|
||||
|
||||
List<ZombieResource> wave = [];
|
||||
var remaining = SummonTank(tank_points, wave);
|
||||
support_points += remaining * 0.8f;
|
||||
horde_points += remaining * 0.2f;
|
||||
horde_points += SummonSupport(support_points, wave);
|
||||
points += SummonHorde(horde_points, wave, big_wave);
|
||||
|
||||
wave.Sort((x, y) => { return rng.RandiRange(-1, 1); });
|
||||
|
||||
foreach (var zom in wave)
|
||||
{
|
||||
ZombieSequencer.Instance.Add(zom.internal_id);
|
||||
}
|
||||
|
||||
big_wave = false;
|
||||
}
|
||||
|
||||
private float SummonSupport(float given_points, List<ZombieResource> wave)
|
||||
{
|
||||
if (cachedSupportPool.Count == 0)
|
||||
{
|
||||
return given_points;
|
||||
}
|
||||
while (given_points >= minSupportPoints)
|
||||
{
|
||||
var chosen_zombie = cachedSupportPool[rng.RandiRange(0, cachedSupportPool.Count - 1)];
|
||||
if (given_points - chosen_zombie.Cost >= 0)
|
||||
{
|
||||
wave.Add(chosen_zombie);
|
||||
given_points -= chosen_zombie.Cost;
|
||||
}
|
||||
}
|
||||
return given_points;
|
||||
}
|
||||
private float SummonTank(float given_points, List<ZombieResource> wave)
|
||||
{
|
||||
if (cachedTankPool.Count == 0)
|
||||
{
|
||||
return given_points;
|
||||
}
|
||||
int zombieIndex = cachedTankPool.Count - 1;
|
||||
while (given_points >= minSupportPoints && zombieIndex > -1)
|
||||
{
|
||||
if (cachedTankPool[zombieIndex].Cost > given_points)
|
||||
{
|
||||
zombieIndex--;
|
||||
continue;
|
||||
}
|
||||
var chosen_zombie = cachedTankPool[zombieIndex];
|
||||
wave.Add(chosen_zombie);
|
||||
given_points -= chosen_zombie.Cost;
|
||||
}
|
||||
return given_points;
|
||||
}
|
||||
private float SummonHorde(float given_points, List<ZombieResource> wave, bool is_big)
|
||||
{
|
||||
if (cachedHordePool.Count == 0)
|
||||
{
|
||||
return given_points;
|
||||
}
|
||||
while (is_big == false && cachedHordePool.Count > 1 && cachedHordePool[1].Cost * 15 <= given_points)
|
||||
{
|
||||
cachedHordePool.RemoveAt(0);
|
||||
minHordePoints = cachedHordePool[0].Cost;
|
||||
}
|
||||
while (given_points >= minHordePoints)
|
||||
{
|
||||
var chosen_zombie = cachedHordePool[rng.RandiRange(0, cachedHordePool.Count - 1)];
|
||||
if (given_points - chosen_zombie.Cost >= 0)
|
||||
{
|
||||
wave.Add(chosen_zombie);
|
||||
given_points -= chosen_zombie.Cost;
|
||||
}
|
||||
}
|
||||
return given_points;
|
||||
}
|
||||
|
||||
private List<ZombieResource> LoadFromRegistry(Array<string> pool)
|
||||
{
|
||||
List<ZombieResource> list = [];
|
||||
foreach (var res in pool)
|
||||
{
|
||||
list.Add(GameRegistry.GetZombieByName(res));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://nkb6i7lrkl8y
|
||||
|
|
@ -1,90 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
using Godot;
|
||||
using Newlon;
|
||||
using Newlon.Components.Level;
|
||||
using Newlon.Components.Zombies;
|
||||
|
||||
public partial class ZombieSequencer : Node2D
|
||||
{
|
||||
public static ZombieSequencer Instance { get; private set; }
|
||||
private Queue<string> queue = [];
|
||||
private RandomNumberGenerator rng = new();
|
||||
private bool turbo = false;
|
||||
|
||||
[Export] private Timer spawnTimer;
|
||||
[Export] private Timer waveTimer;
|
||||
|
||||
private double startSpawnTime;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
rng.Randomize();
|
||||
Instance = this;
|
||||
startSpawnTime = spawnTimer.WaitTime;
|
||||
}
|
||||
|
||||
|
||||
private void FormSquad()
|
||||
{
|
||||
if (queue.Count == 0) return;
|
||||
int count = rng.RandiRange(1, queue.Count > 5 ? 5 : queue.Count);
|
||||
|
||||
if (count == 5)
|
||||
{
|
||||
Spawn(queue.Dequeue(), 1);
|
||||
Spawn(queue.Dequeue(), 2);
|
||||
Spawn(queue.Dequeue(), 3);
|
||||
Spawn(queue.Dequeue(), 4);
|
||||
Spawn(queue.Dequeue(), 5);
|
||||
}
|
||||
|
||||
List<int> list = [];
|
||||
while (list.Count < count)
|
||||
{
|
||||
int lane = rng.RandiRange(1, 5);
|
||||
if (list.Contains(lane) == true)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
list.Add(lane);
|
||||
}
|
||||
|
||||
foreach (int lane in list)
|
||||
{
|
||||
if (queue.Count > 0)
|
||||
Spawn(queue.Dequeue(), lane);
|
||||
}
|
||||
}
|
||||
|
||||
private void Spawn(string id, int lane)
|
||||
{
|
||||
RuntimeZombieData zombie = GameRegistry.GetZombieByName(id).Scene.Instantiate<RuntimeZombieData>();
|
||||
PoolContainer.Instance.Zombies.AddChild(zombie);
|
||||
|
||||
zombie.GlobalPosition = new Vector2(GlobalPosition.X, Utility.RightFieldBoundary.Y - (lane - 1) * Utility.TileHeight);
|
||||
}
|
||||
|
||||
public void Add(string id)
|
||||
{
|
||||
queue.Enqueue(id);
|
||||
}
|
||||
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
if (turbo == false && queue.Count > waveTimer.WaitTime / startSpawnTime * 5.0)
|
||||
{
|
||||
spawnTimer.WaitTime = waveTimer.WaitTime / queue.Count;
|
||||
turbo = true;
|
||||
}
|
||||
else if(turbo && queue.Count == 0)
|
||||
{
|
||||
spawnTimer.WaitTime = startSpawnTime;
|
||||
turbo = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void DebugClearQueue()
|
||||
{
|
||||
queue.Clear();
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://bsuw5lvnr3kol
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
using System;
|
||||
using Godot;
|
||||
using Godot.Collections;
|
||||
|
||||
public partial class FallFloor : Node2D
|
||||
{
|
||||
private static FallFloor Instance;
|
||||
private Array<StaticBody2D> bodies = [];
|
||||
public override void _Ready()
|
||||
{
|
||||
Instance = this;
|
||||
foreach (StaticBody2D body in GetChildren())
|
||||
{
|
||||
bodies.Add(body);
|
||||
}
|
||||
}
|
||||
public static StaticBody2D GetNearest(Vector2 point)
|
||||
{
|
||||
var selected = Instance.bodies[0];
|
||||
foreach (StaticBody2D body in Instance.bodies)
|
||||
{
|
||||
if (Math.Abs(selected.GlobalPosition.Y - point.Y) > Math.Abs(body.GlobalPosition.Y - point.Y))
|
||||
{
|
||||
selected = body;
|
||||
}
|
||||
}
|
||||
return selected;
|
||||
}
|
||||
public static Array<StaticBody2D> GetEverythingElse(StaticBody2D except)
|
||||
{
|
||||
Array<StaticBody2D> bodys = [];
|
||||
foreach (StaticBody2D body in Instance.bodies)
|
||||
{
|
||||
if (except != body)
|
||||
{
|
||||
bodys.Add(body);
|
||||
}
|
||||
}
|
||||
return bodys;
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://blpu7t8tf6277
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
using Godot;
|
||||
using Newlon.Components.Level;
|
||||
using Newlon.Components.Zombies;
|
||||
|
||||
public partial class FallParticle : RigidBody2D
|
||||
{
|
||||
[Export] private RuntimeZombieData data;
|
||||
[Export] private float minAngle;
|
||||
[Export] private float maxAngle;
|
||||
[Export] private float minTorque;
|
||||
[Export] private float maxTorque;
|
||||
[Export] private float Impulse;
|
||||
public void FallOff()
|
||||
{
|
||||
SetDeferred("freeze", false);
|
||||
foreach (var floor in FallFloor.GetEverythingElse(FallFloor.GetNearest(data.GlobalPosition)))
|
||||
{
|
||||
AddCollisionExceptionWith(floor);
|
||||
}
|
||||
Callable.From(() =>
|
||||
{
|
||||
Reparent(PoolContainer.Instance.Zombies);
|
||||
float rng_angle = Mathf.DegToRad((float)GD.RandRange(minAngle, maxAngle));
|
||||
float rng_torque = Mathf.DegToRad((float)GD.RandRange(minTorque, maxTorque));
|
||||
ApplyImpulse(new Vector2(Mathf.Sin(rng_angle) * Impulse, Mathf.Cos(rng_angle) * Impulse));
|
||||
ApplyTorqueImpulse(rng_torque);
|
||||
}).CallDeferred();
|
||||
var tween = CreateTween();
|
||||
tween.TweenInterval(4.0);
|
||||
tween.TweenProperty(this, "modulate", new Color(Modulate.R, Modulate.G, Modulate.B, 0f), 1.0);
|
||||
tween.TweenCallback(Callable.From(QueueFree));
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://dt5uj25u0g6y3
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
using Godot;
|
||||
|
||||
public partial class StandardParticles : Node2D
|
||||
{
|
||||
private int counter = 0;
|
||||
private int counterMax = 0;
|
||||
public override void _Ready()
|
||||
{
|
||||
foreach (GpuParticles2D emitter in GetChildren())
|
||||
{
|
||||
emitter.Emitting = true;
|
||||
counterMax += 1;
|
||||
emitter.Finished += MarkForDestruction;
|
||||
}
|
||||
}
|
||||
public void MarkForDestruction()
|
||||
{
|
||||
if (Engine.IsEditorHint()) return;
|
||||
if (++counter < counterMax) return;
|
||||
QueueFree();
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://dxcd70o6aa7pr
|
||||
|
|
@ -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,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
|
||||
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