Skip to content
12 changes: 12 additions & 0 deletions src/Economics.Skill/Enumerates/ScheduleState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@


namespace Economics.Skill;

public enum ScheduleState
{
Wait,

Running,

Success
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
using Terraria;
using TShockAPI;

namespace Economics.Skill;
namespace Economics.Skill.Internal;

public class AIStyle
internal class AIStyle
{
private static readonly ConcurrentDictionary<string, (Projectile, AIStyleOption)> projectiles = new();

Expand Down
42 changes: 42 additions & 0 deletions src/Economics.Skill/Internal/JobjManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@


namespace Economics.Skill.Internal;
internal class JobjManager
{
private readonly static List<Scheduler> _schedulers = new();

internal static void FrameUpdate()
{
for (var i = 0; i < _schedulers.Count; i++)
{
var scheduler = _schedulers[i];
scheduler.Update().CanRun();
if (scheduler.Running == ScheduleState.Success)
{
_schedulers.Remove(scheduler);
}
}
}

public static Scheduler Add(Action action, bool autoRest = false)
{
var sch = new Scheduler(action, autoRest);
_schedulers.Add(sch);
return sch;
}

public static Scheduler Add(Action action, TimeSpan ts, bool autoRest = false)
{
return Add(action, autoRest).AddTimeSpan(ts);
}

public static int RemoveAll(Guid guid)
{
return _schedulers.RemoveAll(s => s.Guid == guid);
}

public static bool Remove(Scheduler scheduler)
{
return _schedulers.Remove(scheduler);
}
}
74 changes: 74 additions & 0 deletions src/Economics.Skill/Internal/Scheduler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
namespace Economics.Skill.Internal;

internal class Scheduler
{
public int NextRun
{
get => this._nextRun;
private set
{
this._nextRun = value;
this.Running = ScheduleState.Running;
}
}

private int _nextRun = 0;

private Action _action { get; }

public int Count { get; private set; }

public bool Autoreset { get; private set; }

public ScheduleState Running { get; private set; } = ScheduleState.Wait;

public Guid Guid { get; private set; }

public Scheduler(Action action, bool autoreset)
{
this._action = action;
this.Autoreset = autoreset;
this.Guid = Guid.NewGuid();
}

public Scheduler Update()
{
this.Count += 1;
return this;
}

public Scheduler CanRun()
{
if (this.Count > this.NextRun && this.Running == ScheduleState.Running)
{
this._action();
this.Count = 0;
if (!this.Autoreset)
{
this.Running = ScheduleState.Success;
}
}
return this;
}

public Scheduler AddMilliSeconds(int millisecond)
{
this.NextRun = Convert.ToInt32(Math.Ceiling(millisecond / 1000f * 60));
return this;
}

public Scheduler AddSeconds(int seconds)
{
return this.AddMilliSeconds(seconds * 1000);
}

public Scheduler AddMinute(int minutes)
{
return this.AddSeconds(minutes * 60);
}

public Scheduler AddTimeSpan(TimeSpan ts)
{
return this.AddMilliSeconds((int) ts.TotalMilliseconds);
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@

using Economics.Skill.Events;
using Economics.Skill.Events;
using System.Collections.Concurrent;
using TShockAPI;

namespace Economics.Skill;
namespace Economics.Skill.Internal;

internal class SkillCD
{
private readonly static ConcurrentDictionary<TSPlayer, int> God = new();

private static long Count = 0;

private readonly static List<Scheduler> _schedulers = new();

public static void Updata()
{

foreach (var player in Skill.PlayerSKillManager.PlayerSkills)
{
if (player.Player != null && player.Player.Active)
Expand Down
3 changes: 2 additions & 1 deletion src/Economics.Skill/Model/SkillContext.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Economics.Skill.JSInterpreter;
using Economics.Skill.Internal;
using Economics.Skill.JSInterpreter;
using Economics.Skill.Model.Options;
using Economics.Skill.Model.Options.Projectile;
using Economics.Skill.Model.Options.Range;
Expand Down
2 changes: 2 additions & 0 deletions src/Economics.Skill/Skill.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Economics.Skill.DB;
using Economics.Skill.Events;
using Economics.Skill.Internal;
using Economics.Skill.JSInterpreter;
using Economics.Skill.Setting;
using EconomicsAPI.Configured;
Expand Down Expand Up @@ -142,6 +143,7 @@ private void OnPlayerCountertop(PlayerCountertopArgs args)
private void OnUpdate(EventArgs args)
{
this.TimerCount++;
JobjManager.FrameUpdate();
if ((this.TimerCount % 6) == 0)
{
SkillCD.SendGodPacket();
Expand Down
161 changes: 83 additions & 78 deletions src/Economics.Skill/Utils.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using Economics.Skill.Enumerates;
using Economics.Skill.Internal;
using Economics.Skill.JSInterpreter;
using Economics.Skill.Model;
using Economics.Skill.Model.Options.Projectile;
using EconomicsAPI.Extensions;
using Microsoft.Xna.Framework;
using Terraria;
Expand Down Expand Up @@ -65,7 +67,82 @@ public static void EmitGeneralSkill(TSPlayer Player, SkillContext skill)
}


internal static void CycleAdapr(TSPlayer ply, Vector2 vel, Vector2 pos, ProjectileOption option, NPC? lockNpc = null)
{
foreach (var opt in option.ProjectileCycle.ProjectileCycles)
{
Vector2 _vel;
#region 锁定敌怪
if (option.LockNpcOption.Enable && option.LockNpcOption.Lock && lockNpc != null)
{
pos.Distance(lockNpc.Center);
_vel = (pos.DirectionTo(lockNpc.Center).SafeNormalize(-Vector2.UnitY) * lockNpc.velocity.Length()).ToLenOf(option.Speed);
}
else
{
_vel = vel.RotationAngle(option.StartAngle).ToLenOf(option.Speed);
}
#endregion

var _pos = pos + new Vector2(option.X * 16, option.Y * 16);
var oldpos = _pos;
var cpos = _pos.GetPointsOnCircle(opt.Radius * 16, option.StartAngle, opt.GrowAngle, opt.Count);

foreach (var i in Enumerable.Range(0, opt.Count))
{
JobjManager.Add(() =>
{
if (opt.NewPos)
{
_vel = oldpos.DirectionTo(cpos[i]).SafeNormalize(-Vector2.UnitY).ToLenOf(option.Speed);
_pos = cpos[i];
}
//判断锁定敌怪
if (option.LockNpcOption.Enable && option.LockNpcOption.Lock && lockNpc != null)
{
_vel = _pos.DirectionTo(lockNpc.Center).SafeNormalize(-Vector2.UnitY).ToLenOf(option.Speed);
}
#region 生成弹幕
var guid = Guid.NewGuid().ToString();
var index = EconomicsAPI.Utils.SpawnProjectile.NewProjectile(
//发射原无期
ply.TPlayer.GetProjectileSource_Item(ply.TPlayer.HeldItem),
//发射位置
_pos,
_vel * (opt.Reverse ? -1 : 1),
option.ID,
option.Damage,
option.Knockback,
ply.Index,
option.AI[0],
option.AI[1],
option.AI[2],
option.TimeLeft,
guid);
TSPlayer.All.SendData(PacketTypes.ProjectileNew, "", index);
#endregion
AIStyle.Set(Main.projectile[index], option.AISytle, guid);
#region 数值重置

if (!opt.NewPos)
{
_vel = _vel.RotationAngle(opt.GrowAngle).ToLenOf(option.Speed);
}

if (opt.FollowPlayer)
{
_pos = ply.TPlayer.Center + ply.TPlayer.ItemOffSet() + new Vector2(opt.GrowX * 16, opt.GrowY * 16);
}
else
{
_pos += new Vector2(opt.GrowX * 16, opt.GrowY * 16);
}

#endregion
}).AddMilliSeconds(i * opt.Dealy);
}
}
}


/// <summary>
Expand All @@ -78,9 +155,10 @@ public static void EmitGeneralSkill(TSPlayer Player, SkillContext skill)
public static void SpawnSkillProjectile(TSPlayer Player, SkillContext skill, Vector2 vel, Vector2 pos)
{
EmitGeneralSkill(Player, skill);
Task.Run(async () =>
foreach (var i in Enumerable.Range(0, skill.Projectiles.Count))
{
foreach (var proj in skill.Projectiles)
var proj = skill.Projectiles[i];
JobjManager.Add(() =>
{
if (!proj.AutoDirection)
{
Expand All @@ -99,82 +177,9 @@ public static void SpawnSkillProjectile(TSPlayer Player, SkillContext skill, Vec
}
}
}

foreach (var opt in proj.ProjectileCycle.ProjectileCycles)
{
Vector2 _vel;
#region 锁定敌怪
if (proj.LockNpcOption.Enable && proj.LockNpcOption.Lock && lockNpc != null)
{
pos.Distance(lockNpc.Center);
_vel = (pos.DirectionTo(lockNpc.Center).SafeNormalize(-Vector2.UnitY) * lockNpc.velocity.Length()).ToLenOf(proj.Speed);
}
else
{
_vel = vel.RotationAngle(proj.StartAngle).ToLenOf(proj.Speed);
}
#endregion

var _pos = pos + new Vector2(proj.X * 16, proj.Y * 16);
var oldpos = _pos;
var cpos = _pos.GetPointsOnCircle(opt.Radius * 16, proj.StartAngle, opt.GrowAngle, opt.Count);

for (var i = 0; i < opt.Count; i++)
{

if (opt.NewPos)
{
_vel = oldpos.DirectionTo(cpos[i]).SafeNormalize(-Vector2.UnitY).ToLenOf(proj.Speed);
_pos = cpos[i];
}
//判断锁定敌怪
if (proj.LockNpcOption.Enable && proj.LockNpcOption.Lock && lockNpc != null)
{
_vel = _pos.DirectionTo(lockNpc.Center).SafeNormalize(-Vector2.UnitY).ToLenOf(proj.Speed);
}
#region 生成弹幕
var guid = Guid.NewGuid().ToString();
var index = EconomicsAPI.Utils.SpawnProjectile.NewProjectile(
//发射原无期
Player.TPlayer.GetProjectileSource_Item(Player.TPlayer.HeldItem),
//发射位置
_pos,
_vel * (opt.Reverse ? -1 : 1),
proj.ID,
proj.Damage,
proj.Knockback,
Player.Index,
proj.AI[0],
proj.AI[1],
proj.AI[2],
proj.TimeLeft,
guid);
TSPlayer.All.SendData(PacketTypes.ProjectileNew, "", index);
#endregion
AIStyle.Set(Main.projectile[index], proj.AISytle, guid);
#region 数值重置

if (!opt.NewPos)
{
_vel = _vel.RotationAngle(opt.GrowAngle).ToLenOf(proj.Speed);
}

if (opt.FollowPlayer)
{
_pos = Player.TPlayer.Center + Player.TPlayer.ItemOffSet() + new Vector2(opt.GrowX * 16, opt.GrowY * 16);
}
else
{
_pos += new Vector2(opt.GrowX * 16, opt.GrowY * 16);
}

#endregion
await Task.Delay(opt.Dealy);
}
}
await Task.Delay(proj.Dealy);
}
});
CycleAdapr(Player, vel, pos, proj, lockNpc);
}).AddMilliSeconds(proj.Dealy * i);
}
}
/// <summary>
/// 释放技能
Expand Down