Last active
January 24, 2023 15:58
-
-
Save Odex64/ff01ce9f47dca24fb5d99e4b844f5690 to your computer and use it in GitHub Desktop.
Complex script to easily implement your own characters with custom skills through delegates.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Linq; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.Text; | |
using System.Text.RegularExpressions; | |
using SFDGameScriptInterface; | |
class GameScript : GameScriptInterface | |
{ | |
public GameScript() : base(null) { } | |
public static Random rand = new Random(); | |
public sealed class Skill | |
{ | |
public readonly string name; | |
public readonly string description; | |
private readonly uint duration; | |
private readonly uint cooldown; | |
public readonly VirtualKey[] keys; | |
private readonly Func<bool> activate; | |
private readonly Action finish, ready; | |
private readonly bool notifyActivate, notifyReady; | |
public bool available = true; | |
private readonly Vector2 offset = new Vector2(0f, 12f); | |
public Skill(string name, string description, uint duration, uint cooldown, Func<bool> activate, Action finish, Action ready, bool notifyActivate, bool notifyReady, params VirtualKey[] keys) | |
{ | |
if (cooldown < duration) throw new Exception("Cooldown smaller than duration!"); | |
this.name = name; | |
this.description = description; | |
this.duration = duration; | |
this.cooldown = cooldown; | |
this.keys = keys; | |
this.activate = activate; | |
this.finish = finish; | |
this.ready = ready; | |
this.notifyActivate = notifyActivate; | |
this.notifyReady = notifyReady; | |
} | |
public void Trigger(IPlayer player) | |
{ | |
if (!activate()) return; | |
if (notifyActivate) | |
Game.PlayEffect("CFTXT", player.GetWorldPosition() + offset, name.ToUpper() + '!'); | |
available = false; | |
if (finish != null) | |
{ | |
Events.UpdateCallback.Start((float e) => | |
{ | |
finish(); | |
}, duration, 1); | |
} | |
Events.UpdateCallback.Start((float e) => | |
{ | |
if (notifyReady) | |
{ | |
if (player != null && !player.IsRemoved && !player.IsDead) | |
Game.PlayEffect("CFTXT", player.GetWorldPosition() + offset, name.ToUpper() + " READY"); | |
} | |
if (ready != null) | |
ready(); | |
available = true; | |
}, cooldown, 1); | |
} | |
} | |
public sealed class PassiveSkill | |
{ | |
public enum Type | |
{ | |
DEATH, | |
DAMAGE, | |
ALWAYS, | |
PROJCREATED, | |
PROJHIT | |
} | |
public readonly string name, description; | |
public readonly Type type; | |
private readonly Action<object[]> action; | |
public readonly float cooldown; | |
public float currentTime; | |
public PassiveSkill(string name, string description, Type type, Action<object[]> action, float cooldown = 0f) | |
{ | |
this.name = name; | |
this.description = description; | |
this.type = type; | |
this.action = action; | |
if (type == Type.ALWAYS && cooldown > 0f) | |
{ | |
this.cooldown = cooldown; | |
currentTime = Game.TotalElapsedGameTime + cooldown; | |
} | |
} | |
public void Trigger(object[] args = null) | |
{ | |
action(args); | |
} | |
} | |
public abstract class Character | |
{ | |
public bool isDead = false; | |
public static int team = 0; | |
public static List<Character> characters = new List<Character>(); | |
public List<Skill> skills = new List<Skill>(); | |
public List<PassiveSkill> passiveSkills = new List<PassiveSkill>(); | |
public readonly string name; | |
public readonly bool requireTeam, isBoss; | |
public IUser user; | |
public IPlayer player; | |
protected abstract IProfile GetProfile(); | |
protected abstract PlayerModifiers GetModifiers(); | |
protected abstract WeaponItem[] StartingWeapons(); | |
public Character(string name, bool requireTeam = false, bool isBoss = false) | |
{ | |
this.name = name; | |
this.requireTeam = requireTeam; | |
this.isBoss = isBoss; | |
} | |
public virtual void Init(IUser user) | |
{ | |
this.user = user; | |
if (!CheckPlayer()) return; | |
foreach (WeaponItem weapon in StartingWeapons() ?? Enumerable.Empty<WeaponItem>()) | |
player.GiveWeaponItem(weapon); | |
} | |
public bool CheckPlayer() | |
{ | |
player = user.GetPlayer(); | |
if (player == null || player.IsRemoved || player.IsDead) return false; | |
IProfile profile = GetProfile(); | |
if (profile != null) | |
player.SetProfile(profile); | |
PlayerModifiers modifiers = GetModifiers(); | |
if (modifiers != null) | |
player.SetModifiers(modifiers); | |
if (isBoss) | |
player.SetTeam(PlayerTeam.Team2); | |
else if (requireTeam) | |
player.SetTeam((PlayerTeam)team); | |
if (isDead) | |
isDead = false; | |
return true; | |
} | |
} | |
public static class HelperMethods | |
{ | |
private static uint smokeId = 0; | |
public static IPlayer RevivePlayer(IPlayer player) | |
{ | |
IPlayer temp = Game.CreatePlayer(player.GetWorldPosition()); | |
temp.SetModifiers(player.GetModifiers()); | |
temp.SetHealth(temp.GetMaxHealth()); | |
temp.SetProfile(player.GetProfile()); | |
temp.SetTeam(player.GetTeam()); | |
IUser user = player.GetUser(); | |
player.Remove(); | |
temp.SetUser(user); | |
return temp; | |
} | |
public static void DrawCircle(float size, Vector2 position, int effectAmount = 8) | |
{ | |
for (int i = 0; i < size; i++) | |
{ | |
if (rand.Next(300) < effectAmount) | |
{ | |
float angle = (float)(i / size * Math.PI * 2); | |
Vector2 offset = new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle)) * size; | |
Game.PlayEffect("GLM", position + offset); | |
} | |
} | |
} | |
public static void Smoke(float size, Vector2 position, uint duration) | |
{ | |
float radius = (float)(size * Math.PI * 2); | |
for (float y = -radius; y <= radius; y += 8) | |
{ | |
for (float x = -radius; x <= radius; x += 8) | |
{ | |
if (x * x + y * y <= radius * radius) | |
{ | |
Game.CreateObject("SteamSpawner", position + new Vector2(x, y)).CustomId = "smoke " + smokeId; | |
} | |
} | |
} | |
uint temp = smokeId; | |
smokeId++; | |
Events.UpdateCallback.Start((float e) => | |
{ | |
foreach (IObject smoke in Game.GetObjectsByCustomId("smoke " + temp)) | |
smoke.Remove(); | |
}, duration, 1); | |
} | |
} | |
public sealed class TemplateCharacter : Character | |
{ | |
public TemplateCharacter() : base("Template") | |
{ | |
skills.Add(new Skill("Simple Skill", "Testing", 3000u, 5000u, () => // name, description, duration and cooldown of the ability | |
{ | |
Game.ShowChatMessage("Skill started"); | |
return true; // return true if skill was successfully executed, otherwise false won't trigger cooldown (and finish, ready actions) | |
// more code | |
}, | |
() => // can be null | |
{ | |
Game.ShowChatMessage("Skill ended"); | |
// more code | |
}, | |
() => // can be null | |
{ | |
Game.ShowChatMessage("Skill Ready"); | |
// more code | |
}, | |
true, true, VirtualKey.WALKING, VirtualKey.BLOCK)); // if it should notify when the ability is used or ready, and the combination of keys to trigger it | |
// a passive skill | |
passiveSkills.Add(new PassiveSkill("Resurrect", "Resurrect after 3 seconds if not gibbed", PassiveSkill.Type.DEATH, (object[] args) => | |
{ | |
Events.UpdateCallback.Start((float e) => | |
{ | |
if (player == null) return; // always check if player is not null in timed-events | |
HelperMethods.RevivePlayer(player); | |
}, 3000u, 1); // run once after 3 seconds | |
})); | |
passiveSkills.Add(new PassiveSkill("Print Text", "Print a message every 10 seconds", PassiveSkill.Type.ALWAYS, (object[] args) => | |
{ | |
Game.ShowChatMessage("Hey!"); | |
}, 10000f)); // run every 10 seconds, if you don't put any number it will trigger every frame | |
passiveSkills.Add(new PassiveSkill("Projectile Status", "Print projectile info", PassiveSkill.Type.PROJCREATED, (object[] args) => | |
{ | |
IProjectile proj = args[0] as IProjectile; // retain projectile from args | |
Game.ShowChatMessage(proj.ProjectileItem.ToString()); | |
})); | |
passiveSkills.Add(new PassiveSkill("Player Hit", "Print if you hit a player", PassiveSkill.Type.PROJHIT, (object[] args) => | |
{ | |
IProjectile proj = args[0] as IProjectile; | |
ProjectileHitArgs projHit = (ProjectileHitArgs)args[1]; | |
Game.ShowChatMessage(projHit.IsPlayer.ToString()); | |
})); | |
} | |
public override void Init(IUser user) | |
{ | |
base.Init(user); | |
// init variables regarding player | |
} | |
/* YOUR OWN METHODS GO HERE */ | |
/* YOU CAN FILL HelperMethods IF MORE CHARACTERS REQUIRE THE SAME CODE */ | |
protected override IProfile GetProfile() | |
{ | |
return new IProfile() // can return null | |
{ | |
Name = name, | |
Gender = Gender.Female, | |
Skin = new IProfileClothingItem("Normal_fem", "Skin3", "ClothingLightGray"), | |
ChestUnder = new IProfileClothingItem("SweaterBlack_fem", "ClothingDarkGray"), | |
Hands = new IProfileClothingItem("FingerlessGlovesBlack", "ClothingGray"), | |
Legs = new IProfileClothingItem("PantsBlack_fem", "ClothingDarkGray"), | |
Feet = new IProfileClothingItem("ShoesBlack", "ClothingDarkGray"), | |
Accesory = new IProfileClothingItem("Balaclava", "ClothingDarkGray") | |
}; | |
} | |
protected override PlayerModifiers GetModifiers() | |
{ | |
return new PlayerModifiers() // can return null | |
{ | |
SprintSpeedModifier = 2f, | |
RunSpeedModifier = 2f | |
}; | |
} | |
protected override WeaponItem[] StartingWeapons() | |
{ | |
return new WeaponItem[] { WeaponItem.KATANA }; // can return null | |
} | |
} | |
public sealed class Focus : Character | |
{ | |
private Vector2 focusPosition; | |
private const float maxFocus = 85f; | |
private const float idleFocus = 0.16f; | |
private const float focusGain = 0.3f; | |
private const float cursorSpeed = 3f; | |
private const float minimalFocus = 25f; | |
private const float launchSpeed = 10f; | |
private float focusPower = maxFocus; | |
private IObjectText cursor; | |
private List<IProjectile> affectedProjectiles = new List<IProjectile>(); | |
private bool wasInFocus = false; | |
public Focus() : base("Focus") | |
{ | |
passiveSkills.Add(new PassiveSkill("Focus", "Feel into your surroundings (Q)", PassiveSkill.Type.ALWAYS, (object[] args) => | |
{ | |
if (player.KeyPressed(VirtualKey.SHEATHE) && ((wasInFocus && focusPower > 0) || focusPower > minimalFocus)) | |
{ | |
if (!wasInFocus) | |
{ | |
cursor.SetTextScale(2); | |
cursor.SetWorldPosition(player.GetWorldPosition()); | |
player.SetInputMode(PlayerInputMode.ReadOnly); | |
} | |
focusPower -= Game.SlowmotionModifier * idleFocus; | |
if (focusPower < 0) | |
{ | |
ExitFocus(); | |
} | |
player.SetLinearVelocity(Vector2.Zero); | |
player.SetWorldPosition(focusPosition); | |
wasInFocus = true; | |
HelperMethods.DrawCircle(focusPower, player.GetWorldPosition()); | |
Vector2 cursorVector = new Vector2(); | |
if (player.KeyPressed(VirtualKey.AIM_CLIMB_UP)) cursorVector.Y = 1; | |
if (player.KeyPressed(VirtualKey.AIM_CLIMB_DOWN)) cursorVector.Y = -1; | |
if (player.KeyPressed(VirtualKey.AIM_RUN_LEFT)) cursorVector.X = -1; | |
if (player.KeyPressed(VirtualKey.AIM_RUN_RIGHT)) cursorVector.X = 1; | |
if (cursorVector.LengthSquared() != 0) | |
{ | |
float angle = (float)Math.Atan2(cursorVector.Y, cursorVector.X); | |
cursor.SetWorldPosition(cursor.GetWorldPosition() + new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle)) * cursorSpeed); | |
if ((cursor.GetWorldPosition() - player.GetWorldPosition()).Length() > focusPower) | |
{ | |
Vector2 shorter = cursor.GetWorldPosition() - player.GetWorldPosition(); | |
shorter.Normalize(); | |
cursor.SetWorldPosition(player.GetWorldPosition() + shorter * focusPower); | |
} | |
} | |
foreach (IProjectile proj in Game.GetProjectiles()) | |
{ | |
if ((player.GetWorldPosition() - proj.Position).LengthSquared() < focusPower * focusPower) | |
{ | |
if (!affectedProjectiles.Contains(proj)) | |
{ | |
proj.Velocity /= 100; | |
affectedProjectiles.Add(proj); | |
} | |
} | |
else | |
{ | |
if (affectedProjectiles.Contains(proj)) | |
{ | |
proj.Velocity *= 100; | |
affectedProjectiles.Remove(proj); | |
} | |
} | |
} | |
if (PositionCheck(cursor.GetWorldPosition())) | |
{ | |
cursor.SetTextColor(Color.Red); | |
} | |
else | |
{ | |
cursor.SetTextColor(Color.Blue); | |
} | |
} | |
else | |
{ | |
if (wasInFocus) | |
{ | |
ExitFocus(); | |
if (!PositionCheck(cursor.GetWorldPosition())) | |
{ | |
Vector2 direction = (cursor.GetWorldPosition() - player.GetWorldPosition()); | |
float distance = direction.Length(); | |
direction.Normalize(); | |
focusPower -= distance; | |
player.SetWorldPosition(cursor.GetWorldPosition()); | |
player.SetLinearVelocity(direction * distance * launchSpeed / maxFocus); | |
} | |
} | |
focusPosition = player.GetWorldPosition(); | |
focusPower += Game.SlowmotionModifier * focusGain; | |
focusPower = Math.Min(focusPower, maxFocus); | |
} | |
})); | |
} | |
public override void Init(IUser user) | |
{ | |
base.Init(user); | |
cursor = (IObjectText)Game.CreateObject("Text"); | |
cursor.SetTextColor(Color.Blue); | |
cursor.SetText("+"); | |
cursor.SetTextAlignment(TextAlignment.Middle); | |
cursor.SetTextScale(0); | |
} | |
private void ExitFocus() | |
{ | |
cursor.SetTextScale(0); | |
wasInFocus = false; | |
player.SetInputMode(PlayerInputMode.Enabled); | |
foreach (IProjectile proj in affectedProjectiles) | |
{ | |
proj.Velocity *= 100; | |
} | |
affectedProjectiles.Clear(); | |
} | |
private bool PositionCheck(Vector2 position) | |
{ | |
RayCastInput input = new RayCastInput(true) { ProjectileHit = RayCastFilterMode.True, AbsorbProjectile = RayCastFilterMode.True, IncludeOverlap = true }; | |
RayCastResult[] rays = Game.RayCast(position, position, input); | |
return rays.Length > 0 && rays[0].Hit; | |
} | |
protected override IProfile GetProfile() | |
{ | |
return new IProfile() | |
{ | |
Name = name, | |
Gender = Gender.Male, | |
Skin = new IProfileClothingItem("Normal", "Skin5", "ClothingLightGray") | |
}; | |
} | |
protected override PlayerModifiers GetModifiers() | |
{ | |
return new PlayerModifiers() | |
{ | |
SprintSpeedModifier = 2f, | |
RunSpeedModifier = 2f | |
}; | |
} | |
protected override WeaponItem[] StartingWeapons() | |
{ | |
return null; | |
} | |
} | |
public sealed class Santa : Character | |
{ | |
private readonly string[] gifts = new string[] { "CarWheel01", "GasLamp00", "WpnMineThrown", "Chair00" }; | |
private const float offsetX = 12f, offsetY = 4f; | |
private const float velocityX = 15f, velocityY = 2f; | |
private bool elfs = false; | |
public Santa() : base("Santa", true) | |
{ | |
skills.Add(new Skill("Santa's Bag", "Get your magic bag", 0u, 24000u, () => | |
{ | |
if (player.CurrentMeleeMakeshiftWeapon.WeaponItem != WeaponItem.TRASH_BAG) | |
{ | |
player.GiveWeaponItem(WeaponItem.TRASH_BAG); | |
return true; | |
} | |
return false; | |
}, null, null, true, true, VirtualKey.WALKING, VirtualKey.ACTIVATE)); | |
skills.Add(new Skill("Gifts", "Attack while holding a bag", 0u, 800u, () => | |
{ | |
if (player.CurrentMeleeMakeshiftWeapon.WeaponItem == WeaponItem.TRASH_BAG && (player.IsMeleeAttacking || player.IsJumpAttacking)) | |
{ | |
SpawnGifts(); | |
return true; | |
} | |
return false; | |
}, null, null, false, false, VirtualKey.ATTACK)); | |
passiveSkills.Add(new PassiveSkill("Elfs", "Get some help when you're low hp", PassiveSkill.Type.DAMAGE, (object[] args) => | |
{ | |
if (!elfs && player.GetHealth() < 30) | |
{ | |
SpawnElfs(); | |
elfs = true; | |
} | |
})); | |
} | |
public override void Init(IUser user) | |
{ | |
base.Init(user); | |
} | |
private void SpawnGifts() | |
{ | |
IObject gift = Game.CreateObject(gifts[rand.Next(gifts.Length)], player.GetWorldPosition() + new Vector2(offsetX * player.FacingDirection, offsetY)); | |
gift.SetLinearVelocity(player.GetLinearVelocity() + new Vector2(velocityX * player.FacingDirection, velocityY)); | |
} | |
private void SpawnElfs() | |
{ | |
int count = 0; | |
Game.PlaySound("Wilhelm", Vector2.Zero); | |
Game.PlaySound("ChurchBell1", Vector2.Zero); | |
Events.UpdateCallback.Start((float e) => | |
{ | |
if (player == null) return; | |
Game.PlaySound("ChurchBell1", Vector2.Zero); | |
count++; | |
if (count == 3) | |
{ | |
if (player.IsDead) | |
{ | |
Game.TriggerExplosion(player.GetWorldPosition()); | |
return; | |
} | |
for (int i = 0; i < 2; i++) | |
{ | |
IPlayer elf = Game.CreatePlayer(player.GetWorldPosition()); | |
elf.SetProfile(new IProfile() | |
{ | |
Gender = Gender.Female, | |
Skin = new IProfileClothingItem("Tattoos_fem", "Skin3", "ClothingPink"), | |
Head = new IProfileClothingItem("SantaHat", "ClothingGreen"), | |
ChestUnder = new IProfileClothingItem("LeatherJacket_fem", "ClothingGreen", "ClothingLightGray"), | |
Waist = new IProfileClothingItem("Belt_fem", "ClothingDarkGreen", "ClothingLightGray"), | |
Legs = new IProfileClothingItem("Pants_fem", "ClothingGreen"), | |
Feet = new IProfileClothingItem("BootsBlack", "ClothingGray") | |
}); | |
elf.SetModifiers(new PlayerModifiers() | |
{ | |
MaxHealth = 40, | |
CurrentHealth = 40, | |
RunSpeedModifier = 1.8f, | |
SprintSpeedModifier = 1.8f | |
}); | |
elf.SetBotBehavior(new BotBehavior(true, PredefinedAIType.BotA)); | |
elf.SetBotName("Elf"); | |
elf.SetTeam(player.GetTeam()); | |
} | |
} | |
}, 2400u, 3); | |
} | |
protected override IProfile GetProfile() | |
{ | |
return new IProfile() | |
{ | |
Name = name, | |
Gender = Gender.Male, | |
Skin = new IProfileClothingItem("Tattoos", "Skin3", "ClothingPink"), | |
Head = new IProfileClothingItem("SantaHat", "ClothingRed"), | |
ChestOver = new IProfileClothingItem("Coat", "ClothingRed", "ClothingLightGray"), | |
ChestUnder = new IProfileClothingItem("SleevelessShirt", "ClothingLightGray"), | |
Hands = new IProfileClothingItem("SafetyGlovesBlack", "ClothingGray"), | |
Waist = new IProfileClothingItem("Belt", "ClothingDarkRed", "ClothingLightYellow"), | |
Legs = new IProfileClothingItem("Pants", "ClothingRed"), | |
Feet = new IProfileClothingItem("BootsBlack", "ClothingBrown"), | |
Accesory = new IProfileClothingItem("SantaMask", "") | |
}; | |
} | |
protected override PlayerModifiers GetModifiers() | |
{ | |
return new PlayerModifiers() | |
{ | |
MaxHealth = 120, | |
CurrentHealth = 120, | |
MeleeForceModifier = 2, | |
MeleeDamageDealtModifier = 1.2f | |
}; | |
} | |
protected override WeaponItem[] StartingWeapons() | |
{ | |
return new WeaponItem[] { WeaponItem.TRASH_BAG, WeaponItem.AXE }; | |
} | |
} | |
public string TranslateKeys(VirtualKey[] keys) | |
{ | |
string desc = " ("; | |
foreach (VirtualKey key in keys) | |
{ | |
switch (key) | |
{ | |
case VirtualKey.WALKING: | |
desc += "ALT+"; | |
break; | |
case VirtualKey.BLOCK: | |
desc += "D+"; | |
break; | |
case VirtualKey.ATTACK: | |
desc += "A+"; | |
break; | |
case VirtualKey.KICK: | |
desc += "S+"; | |
break; | |
case VirtualKey.ACTIVATE: | |
desc += "F+"; | |
break; | |
case VirtualKey.GRAB: | |
desc += "R+"; | |
break; | |
case VirtualKey.SHEATHE: | |
desc += "Q+"; | |
break; | |
case VirtualKey.DROP: | |
desc += "G+"; | |
break; | |
case VirtualKey.CROUCH_ROLL_DIVE: | |
desc += "DOWN+"; | |
break; | |
case VirtualKey.JUMP: | |
desc += "UP+"; | |
break; | |
} | |
} | |
return desc.Substring(0, desc.Length - 1) + ')'; | |
} | |
public void ShowSkills(Character character, int userId) | |
{ | |
if (character.skills.Count() > 0) | |
{ | |
Game.ShowChatMessage("------------SKILLS------------", Color.Green, userId); | |
foreach (Skill skill in character.skills) | |
Game.ShowChatMessage(skill.name + ": " + skill.description + TranslateKeys(skill.keys), Color.Grey, userId); | |
} | |
if (character.passiveSkills.Count() > 0) | |
{ | |
Game.ShowChatMessage("---------PASSIVE SKILLS--------", Color.Yellow, userId); | |
foreach (PassiveSkill passiveSkill in character.passiveSkills) | |
Game.ShowChatMessage(passiveSkill.name + ": " + passiveSkill.description, Color.Grey, userId); | |
} | |
} | |
public bool IsFFA() | |
{ | |
foreach (IUser user in Game.GetActiveUsers()) | |
{ | |
IPlayer player = user.GetPlayer(); | |
if (player != null && !player.IsRemoved && !player.IsDead) | |
{ | |
if (player.GetTeam() != PlayerTeam.Independent) | |
return false; | |
} | |
} | |
return true; | |
} | |
public void OnStartup() | |
{ | |
List<Character> flaged = new List<Character>(); | |
/*----------BOSSES----------*/ | |
/*----------HEROES----------*/ | |
Character.characters.Add(new TemplateCharacter()); | |
//Character.characters.Add(new Focus()); | |
Character.characters.Add(new Santa()); | |
/*--------HEROES (TEAM)------*/ | |
int count = Character.characters.Count(); | |
bool isFFA = IsFFA(); | |
bool bossRound = false; // TO-DO: randomly generated | |
IPlayer boss = null; | |
if (bossRound) | |
{ | |
Character character = null; | |
while (true) | |
{ | |
character = Character.characters[rand.Next(count)]; | |
if (character.isBoss) break; | |
} | |
IPlayer[] temp = Game.GetPlayers().Where(p => p.IsUser && !p.IsRemoved && !p.IsDead).ToArray(); | |
boss = temp[rand.Next(temp.Count())]; | |
character.Init(boss.GetUser()); | |
Game.ShowChatMessage("You're " + character.name, Color.Red, boss.UserIdentifier); | |
ShowSkills(character, boss.UserIdentifier); | |
} | |
foreach (IPlayer player in Game.GetPlayers()) | |
{ | |
if (bossRound) | |
player.SetTeam(PlayerTeam.Team1); | |
if (!player.IsUser || player == boss || player.IsRemoved || player.IsDead) continue; | |
Character character = null; | |
while (true) | |
{ | |
character = Character.characters[rand.Next(count)]; | |
if (!character.isBoss && !flaged.Contains(character) && (!character.requireTeam || (character.requireTeam && !bossRound && isFFA && Character.team < 4))) | |
{ | |
flaged.Add(character); | |
break; | |
} | |
} | |
if (character.requireTeam) | |
Character.team++; | |
character.Init(player.GetUser()); | |
Game.ShowChatMessage("You're " + character.name, Color.Cyan, player.UserIdentifier); | |
ShowSkills(character, player.UserIdentifier); | |
} | |
Events.PlayerDeathCallback.Start(OnPlayerDeath); | |
Events.PlayerDamageCallback.Start(OnPlayerDamage); | |
Events.ProjectileCreatedCallback.Start(OnProjectileCreated); | |
Events.ProjectileHitCallback.Start(OnProjectileHit); | |
Events.UpdateCallback.Start(OnUpdate); | |
} | |
public void OnPlayerDeath(IPlayer player, PlayerDeathArgs args) | |
{ | |
if (!player.IsUser) return; | |
Character character = Character.characters.Find(c => c.user == player.GetUser()); | |
if (character == null) return; | |
character.isDead = true; | |
if (args.Removed) return; | |
foreach (PassiveSkill passiveSkill in character.passiveSkills) | |
{ | |
if (passiveSkill.type == PassiveSkill.Type.DEATH) | |
passiveSkill.Trigger(); | |
} | |
} | |
public void OnPlayerDamage(IPlayer player, PlayerDamageArgs args) | |
{ | |
if (!player.IsUser) return; | |
Character character = Character.characters.Find(c => c.user == player.GetUser()); | |
if (character == null) return; | |
foreach (PassiveSkill passiveSkill in character.passiveSkills) | |
{ | |
if (passiveSkill.type == PassiveSkill.Type.DAMAGE) | |
passiveSkill.Trigger(); | |
} | |
} | |
public void OnProjectileCreated(IProjectile[] projectiles) | |
{ | |
foreach (IProjectile projectile in projectiles) | |
{ | |
IPlayer player = Game.GetPlayer(projectile.OwnerPlayerID); | |
if (player == null || !player.IsUser) continue; | |
Character character = Character.characters.Find(c => c.user == player.GetUser()); | |
if (character == null) continue; | |
foreach (PassiveSkill passiveSkill in character.passiveSkills) | |
{ | |
if (passiveSkill.type == PassiveSkill.Type.PROJCREATED) | |
passiveSkill.Trigger(new object[] { projectile }); | |
} | |
} | |
} | |
public void OnProjectileHit(IProjectile projectile, ProjectileHitArgs args) | |
{ | |
IPlayer player = Game.GetPlayer(projectile.OwnerPlayerID); | |
if (player == null || !player.IsUser) return; | |
Character character = Character.characters.Find(c => c.user == player.GetUser()); | |
if (character == null) return; | |
foreach (PassiveSkill passiveSkill in character.passiveSkills) | |
{ | |
if (passiveSkill.type == PassiveSkill.Type.PROJHIT) | |
passiveSkill.Trigger(new object[] { projectile, args }); | |
} | |
} | |
public void OnUpdate(float ms) | |
{ | |
foreach (Character character in Character.characters) | |
{ | |
if (character.user == null) continue; | |
if (character.isDead) | |
{ | |
if (!character.CheckPlayer()) continue; | |
} | |
// if (player == null || player.IsRemoved || player.IsDead) continue; | |
foreach (Skill skill in character.skills) | |
{ | |
if (skill.available && skill.keys.All(k => character.player.KeyPressed(k))) | |
skill.Trigger(character.player); | |
} | |
foreach (PassiveSkill passiveSkill in character.passiveSkills) | |
{ | |
if (passiveSkill.type == PassiveSkill.Type.ALWAYS && (passiveSkill.cooldown == 0f || passiveSkill.currentTime < Game.TotalElapsedGameTime)) | |
{ | |
passiveSkill.Trigger(); | |
if (passiveSkill.cooldown > 0f) | |
passiveSkill.currentTime = Game.TotalElapsedGameTime + passiveSkill.cooldown; | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment