diff options
Diffstat (limited to 'GameCode')
460 files changed, 31506 insertions, 0 deletions
diff --git a/GameCode/AbyssalCountdown.cs b/GameCode/AbyssalCountdown.cs new file mode 100644 index 0000000..062e920 --- /dev/null +++ b/GameCode/AbyssalCountdown.cs @@ -0,0 +1,189 @@ +using System; +using Sonigon; +using UnityEngine; +using UnityEngine.UI.ProceduralImage; + +public class AbyssalCountdown : MonoBehaviour +{ + public SoundEvent soundAbyssalChargeLoop; + + private bool soundChargeIsPlaying; + + private float soundCounterLast; + + private SoundParameterIntensity soundParameterIntensity = new SoundParameterIntensity(0f, UpdateMode.Continuous); + + [Range(0f, 1f)] + public float counter; + + public float timeToFill = 10f; + + public float timeToEmpty = 3f; + + public float duration; + + public float hpMultiplier = 2f; + + public ProceduralImage outerRing; + + public ProceduralImage fill; + + public Transform rotator; + + public Transform still; + + private CharacterData data; + + public GameObject[] abyssalObjects; + + private float remainingDuration; + + private bool isAbyssalForm; + + private float startCounter; + + private void Start() + { + soundCounterLast = counter; + data = GetComponentInParent<CharacterData>(); + HealthHandler healthHandler = data.healthHandler; + healthHandler.reviveAction = (Action)Delegate.Combine(healthHandler.reviveAction, new Action(ResetStuff)); + GetComponentInParent<ChildRPC>().childRPCs.Add("Abyssal", RPCA_Activate); + } + + private void OnDestroy() + { + HealthHandler healthHandler = data.healthHandler; + healthHandler.reviveAction = (Action)Delegate.Combine(healthHandler.reviveAction, new Action(ResetStuff)); + GetComponentInParent<ChildRPC>().childRPCs.Remove("Abyssal"); + SoundStop(); + } + + private void OnDisable() + { + SoundStop(); + } + + private void SoundPlay() + { + if (!soundChargeIsPlaying) + { + soundChargeIsPlaying = true; + SoundManager.Instance.Play(soundAbyssalChargeLoop, base.transform, soundParameterIntensity); + } + } + + private void SoundStop() + { + if (soundChargeIsPlaying) + { + soundChargeIsPlaying = false; + SoundManager.Instance.Stop(soundAbyssalChargeLoop, base.transform); + } + } + + private void ResetStuff() + { + SoundStop(); + remainingDuration = 0f; + counter = 0f; + if (isAbyssalForm) + { + for (int i = 0; i < abyssalObjects.Length; i++) + { + abyssalObjects[i].gameObject.SetActive(value: false); + } + data.maxHealth /= hpMultiplier; + data.health /= hpMultiplier; + data.stats.ConfigureMassAndSize(); + isAbyssalForm = false; + rotator.gameObject.SetActive(value: false); + still.gameObject.SetActive(value: false); + } + SoundStop(); + } + + private void RPCA_Activate() + { + remainingDuration = duration; + } + + private void Update() + { + if (soundCounterLast < counter) + { + SoundPlay(); + } + else + { + SoundStop(); + } + soundCounterLast = counter; + soundParameterIntensity.intensity = counter; + outerRing.fillAmount = counter; + fill.fillAmount = counter; + rotator.transform.localEulerAngles = new Vector3(0f, 0f, 0f - Mathf.Lerp(0f, 360f, counter)); + if (!data.playerVel.simulated) + { + startCounter = 1f; + return; + } + startCounter -= TimeHandler.deltaTime; + if (startCounter > 0f) + { + return; + } + if (remainingDuration > 0f) + { + if (!isAbyssalForm) + { + for (int i = 0; i < abyssalObjects.Length; i++) + { + abyssalObjects[i].gameObject.SetActive(value: true); + } + data.maxHealth *= hpMultiplier; + data.health *= hpMultiplier; + data.stats.ConfigureMassAndSize(); + isAbyssalForm = true; + } + remainingDuration -= TimeHandler.deltaTime; + counter = remainingDuration / duration; + return; + } + if (isAbyssalForm) + { + for (int j = 0; j < abyssalObjects.Length; j++) + { + abyssalObjects[j].gameObject.SetActive(value: false); + } + data.maxHealth /= hpMultiplier; + data.health /= hpMultiplier; + data.stats.ConfigureMassAndSize(); + isAbyssalForm = false; + } + if (data.input.direction == Vector3.zero || data.input.direction == Vector3.down) + { + counter += TimeHandler.deltaTime / timeToFill; + } + else + { + counter -= TimeHandler.deltaTime / timeToEmpty; + } + counter = Mathf.Clamp(counter, -0.1f / timeToFill, 1f); + if (counter >= 1f && data.view.IsMine) + { + remainingDuration = duration; + GetComponentInParent<ChildRPC>().CallFunction("Abyssal"); + } + if (counter <= 0f) + { + rotator.gameObject.SetActive(value: false); + still.gameObject.SetActive(value: false); + } + else + { + rotator.gameObject.SetActive(value: true); + still.gameObject.SetActive(value: true); + } + } +} diff --git a/GameCode/Accelerate.cs b/GameCode/Accelerate.cs new file mode 100644 index 0000000..9bc086b --- /dev/null +++ b/GameCode/Accelerate.cs @@ -0,0 +1,24 @@ +using UnityEngine; + +public class Accelerate : MonoBehaviour +{ + private MoveTransform move; + + public float startMultiplier = 0.5f; + + public float acceleratonPerSecond = 2f; + + public float pow = 1f; + + private void Start() + { + move = GetComponentInParent<MoveTransform>(); + move.multiplier *= startMultiplier; + move.multiplier = Mathf.Clamp(move.multiplier, 0.01f, float.PositiveInfinity); + } + + private void Update() + { + move.multiplier = Mathf.Clamp(move.multiplier + TimeHandler.deltaTime * acceleratonPerSecond * Mathf.Pow(move.multiplier, pow), 0f, 25f); + } +} diff --git a/GameCode/ActivateSciptWhenCanSeeOtherPlayer.cs b/GameCode/ActivateSciptWhenCanSeeOtherPlayer.cs new file mode 100644 index 0000000..5a527fc --- /dev/null +++ b/GameCode/ActivateSciptWhenCanSeeOtherPlayer.cs @@ -0,0 +1,42 @@ +using UnityEngine; + +public class ActivateSciptWhenCanSeeOtherPlayer : MonoBehaviour +{ + public enum Target + { + OtherPlayer, + Closest + } + + public Target target; + + private SpawnedAttack spawned; + + public MonoBehaviour script; + + private void Start() + { + spawned = GetComponentInParent<SpawnedAttack>(); + } + + private void Update() + { + Player player = null; + player = ((target != 0) ? PlayerManager.instance.GetClosestPlayer(base.transform.position, needVision: true) : PlayerManager.instance.GetOtherPlayer(spawned.spawner)); + if ((bool)player) + { + if (PlayerManager.instance.CanSeePlayer(base.transform.position, player).canSee) + { + script.enabled = true; + } + else + { + script.enabled = false; + } + } + else + { + script.enabled = false; + } + } +} diff --git a/GameCode/AddShake.cs b/GameCode/AddShake.cs new file mode 100644 index 0000000..227a243 --- /dev/null +++ b/GameCode/AddShake.cs @@ -0,0 +1,25 @@ +using UnityEngine; + +public class AddShake : MonoBehaviour +{ + public Vector2 shake; + + public bool auto = true; + + public bool inheritScale; + + public float max = float.PositiveInfinity; + + private void Start() + { + if (auto) + { + DoShake(); + } + } + + public void DoShake() + { + GamefeelManager.GameFeel(shake * Mathf.Clamp(inheritScale ? base.transform.localScale.x : 1f, 0f, max)); + } +} diff --git a/GameCode/Aim.cs b/GameCode/Aim.cs new file mode 100644 index 0000000..45288a5 --- /dev/null +++ b/GameCode/Aim.cs @@ -0,0 +1,39 @@ +using UnityEngine; + +public class Aim : MonoBehaviour +{ + private GeneralInput input; + + private HoldingObject holdingObject; + + private CharacterData data; + + private Vector3 aimDirection; + + private void Awake() + { + input = GetComponent<GeneralInput>(); + data = GetComponent<CharacterData>(); + holdingObject = GetComponentInChildren<HoldingObject>(); + } + + private void Update() + { + if ((double)input.aimDirection.magnitude > 0.2) + { + aimDirection = input.aimDirection; + } + if (input.direction.magnitude > 0.2f && Optionshandler.leftStickAim && input.aimDirection == Vector3.zero) + { + aimDirection = input.direction; + } + if ((bool)holdingObject) + { + if (aimDirection != Vector3.zero) + { + holdingObject.transform.rotation = Quaternion.LookRotation(aimDirection); + } + data.aimDirection = aimDirection; + } + } +} diff --git a/GameCode/AimForPlayer.cs b/GameCode/AimForPlayer.cs new file mode 100644 index 0000000..5a9ab24 --- /dev/null +++ b/GameCode/AimForPlayer.cs @@ -0,0 +1,31 @@ +using UnityEngine; + +public class AimForPlayer : MonoBehaviour +{ + public enum Target + { + OtherPlayer, + Closest + } + + public float upOffset; + + public Target target; + + private SpawnedAttack spawned; + + private void Start() + { + spawned = GetComponentInParent<SpawnedAttack>(); + } + + private void Update() + { + Player player = null; + player = ((target != 0) ? PlayerManager.instance.GetClosestPlayer(base.transform.position, needVision: true) : PlayerManager.instance.GetOtherPlayer(spawned.spawner)); + if ((bool)player && PlayerManager.instance.CanSeePlayer(base.transform.position, player).canSee) + { + base.transform.rotation = Quaternion.LookRotation(player.transform.position + Vector3.up * Vector3.Distance(player.transform.position, base.transform.position) * 0.1f * upOffset - base.transform.position, Vector3.forward); + } + } +} diff --git a/GameCode/AmplifyColorBase.cs b/GameCode/AmplifyColorBase.cs new file mode 100644 index 0000000..214d0a4 --- /dev/null +++ b/GameCode/AmplifyColorBase.cs @@ -0,0 +1,879 @@ +using System; +using System.Collections.Generic; +using AmplifyColor; +using UnityEngine; +using UnityEngine.Rendering; +using UnityEngine.Serialization; + +[AddComponentMenu("")] +public class AmplifyColorBase : MonoBehaviour +{ + public const int LutSize = 32; + + public const int LutWidth = 1024; + + public const int LutHeight = 32; + + private const int DepthCurveLutRange = 1024; + + public Tonemapping Tonemapper; + + public float Exposure = 1f; + + public float LinearWhitePoint = 11.2f; + + [FormerlySerializedAs("UseDithering")] + public bool ApplyDithering; + + public Quality QualityLevel = Quality.Standard; + + public float BlendAmount; + + public Texture LutTexture; + + public Texture LutBlendTexture; + + public Texture MaskTexture; + + public bool UseDepthMask; + + public AnimationCurve DepthMaskCurve = new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 1f)); + + public bool UseVolumes; + + public float ExitVolumeBlendTime = 1f; + + public Transform TriggerVolumeProxy; + + public LayerMask VolumeCollisionMask = -1; + + private Camera ownerCamera; + + private Shader shaderBase; + + private Shader shaderBlend; + + private Shader shaderBlendCache; + + private Shader shaderMask; + + private Shader shaderMaskBlend; + + private Shader shaderDepthMask; + + private Shader shaderDepthMaskBlend; + + private Shader shaderProcessOnly; + + private RenderTexture blendCacheLut; + + private Texture2D defaultLut; + + private Texture2D depthCurveLut; + + private Color32[] depthCurveColors; + + private ColorSpace colorSpace = ColorSpace.Uninitialized; + + private Quality qualityLevel = Quality.Standard; + + private Material materialBase; + + private Material materialBlend; + + private Material materialBlendCache; + + private Material materialMask; + + private Material materialMaskBlend; + + private Material materialDepthMask; + + private Material materialDepthMaskBlend; + + private Material materialProcessOnly; + + private bool blending; + + private float blendingTime; + + private float blendingTimeCountdown; + + private Action onFinishBlend; + + private AnimationCurve prevDepthMaskCurve = new AnimationCurve(); + + private bool volumesBlending; + + private float volumesBlendingTime; + + private float volumesBlendingTimeCountdown; + + private Texture volumesLutBlendTexture; + + private float volumesBlendAmount; + + private Texture worldLUT; + + private AmplifyColorVolumeBase currentVolumeLut; + + private RenderTexture midBlendLUT; + + private bool blendingFromMidBlend; + + private VolumeEffect worldVolumeEffects; + + private VolumeEffect currentVolumeEffects; + + private VolumeEffect blendVolumeEffects; + + private float worldExposure = 1f; + + private float currentExposure = 1f; + + private float blendExposure = 1f; + + private float effectVolumesBlendAdjust; + + private List<AmplifyColorVolumeBase> enteredVolumes = new List<AmplifyColorVolumeBase>(); + + private AmplifyColorTriggerProxyBase actualTriggerProxy; + + [HideInInspector] + public VolumeEffectFlags EffectFlags = new VolumeEffectFlags(); + + [SerializeField] + [HideInInspector] + private string sharedInstanceID = ""; + + private bool silentError; + + public Texture2D DefaultLut + { + get + { + if (!(defaultLut == null)) + { + return defaultLut; + } + return CreateDefaultLut(); + } + } + + public bool IsBlending => blending; + + private float effectVolumesBlendAdjusted => Mathf.Clamp01((effectVolumesBlendAdjust < 0.99f) ? ((volumesBlendAmount - effectVolumesBlendAdjust) / (1f - effectVolumesBlendAdjust)) : 1f); + + public string SharedInstanceID => sharedInstanceID; + + public bool WillItBlend + { + get + { + if (LutTexture != null && LutBlendTexture != null) + { + return !blending; + } + return false; + } + } + + public void NewSharedInstanceID() + { + sharedInstanceID = Guid.NewGuid().ToString(); + } + + private void ReportMissingShaders() + { + Debug.LogError("[AmplifyColor] Failed to initialize shaders. Please attempt to re-enable the Amplify Color Effect component. If that fails, please reinstall Amplify Color."); + base.enabled = false; + } + + private void ReportNotSupported() + { + Debug.LogError("[AmplifyColor] This image effect is not supported on this platform."); + base.enabled = false; + } + + private bool CheckShader(Shader s) + { + if (s == null) + { + ReportMissingShaders(); + return false; + } + if (!s.isSupported) + { + ReportNotSupported(); + return false; + } + return true; + } + + private bool CheckShaders() + { + if (CheckShader(shaderBase) && CheckShader(shaderBlend) && CheckShader(shaderBlendCache) && CheckShader(shaderMask) && CheckShader(shaderMaskBlend)) + { + return CheckShader(shaderProcessOnly); + } + return false; + } + + private bool CheckSupport() + { + if (!SystemInfo.supportsImageEffects) + { + ReportNotSupported(); + return false; + } + return true; + } + + private void OnEnable() + { + if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Null) + { + Debug.LogWarning("[AmplifyColor] Null graphics device detected. Skipping effect silently."); + silentError = true; + } + else if (CheckSupport() && CreateMaterials()) + { + Texture2D texture2D = LutTexture as Texture2D; + Texture2D texture2D2 = LutBlendTexture as Texture2D; + if ((texture2D != null && texture2D.mipmapCount > 1) || (texture2D2 != null && texture2D2.mipmapCount > 1)) + { + Debug.LogError("[AmplifyColor] Please disable \"Generate Mip Maps\" import settings on all LUT textures to avoid visual glitches. Change Texture Type to \"Advanced\" to access Mip settings."); + } + } + } + + private void OnDisable() + { + if (actualTriggerProxy != null) + { + UnityEngine.Object.DestroyImmediate(actualTriggerProxy.gameObject); + actualTriggerProxy = null; + } + ReleaseMaterials(); + ReleaseTextures(); + } + + private void VolumesBlendTo(Texture blendTargetLUT, float blendTimeInSec) + { + volumesLutBlendTexture = blendTargetLUT; + volumesBlendAmount = 0f; + volumesBlendingTime = blendTimeInSec; + volumesBlendingTimeCountdown = blendTimeInSec; + volumesBlending = true; + } + + public void BlendTo(Texture blendTargetLUT, float blendTimeInSec, Action onFinishBlend) + { + LutBlendTexture = blendTargetLUT; + BlendAmount = 0f; + this.onFinishBlend = onFinishBlend; + blendingTime = blendTimeInSec; + blendingTimeCountdown = blendTimeInSec; + blending = true; + } + + private void CheckCamera() + { + if (ownerCamera == null) + { + ownerCamera = GetComponent<Camera>(); + } + if (UseDepthMask && (ownerCamera.depthTextureMode & DepthTextureMode.Depth) == 0) + { + ownerCamera.depthTextureMode |= DepthTextureMode.Depth; + } + } + + private void Start() + { + if (!silentError) + { + CheckCamera(); + worldLUT = LutTexture; + worldVolumeEffects = EffectFlags.GenerateEffectData(this); + blendVolumeEffects = (currentVolumeEffects = worldVolumeEffects); + worldExposure = Exposure; + blendExposure = (currentExposure = worldExposure); + } + } + + private void Update() + { + if (silentError) + { + return; + } + CheckCamera(); + bool flag = false; + if (volumesBlending) + { + volumesBlendAmount = (volumesBlendingTime - volumesBlendingTimeCountdown) / volumesBlendingTime; + volumesBlendingTimeCountdown -= Time.smoothDeltaTime; + if (volumesBlendAmount >= 1f) + { + volumesBlendAmount = 1f; + flag = true; + } + } + else + { + volumesBlendAmount = Mathf.Clamp01(volumesBlendAmount); + } + if (blending) + { + BlendAmount = (blendingTime - blendingTimeCountdown) / blendingTime; + blendingTimeCountdown -= Time.smoothDeltaTime; + if (BlendAmount >= 1f) + { + LutTexture = LutBlendTexture; + BlendAmount = 0f; + blending = false; + LutBlendTexture = null; + if (onFinishBlend != null) + { + onFinishBlend(); + } + } + } + else + { + BlendAmount = Mathf.Clamp01(BlendAmount); + } + if (UseVolumes) + { + if (actualTriggerProxy == null) + { + GameObject gameObject = new GameObject(base.name + "+ACVolumeProxy") + { + hideFlags = HideFlags.HideAndDontSave + }; + if (TriggerVolumeProxy != null && TriggerVolumeProxy.GetComponent<Collider2D>() != null) + { + actualTriggerProxy = gameObject.AddComponent<AmplifyColorTriggerProxy2D>(); + } + else + { + actualTriggerProxy = gameObject.AddComponent<AmplifyColorTriggerProxy>(); + } + actualTriggerProxy.OwnerEffect = this; + } + UpdateVolumes(); + } + else if (actualTriggerProxy != null) + { + UnityEngine.Object.DestroyImmediate(actualTriggerProxy.gameObject); + actualTriggerProxy = null; + } + if (flag) + { + LutTexture = volumesLutBlendTexture; + volumesBlendAmount = 0f; + volumesBlending = false; + volumesLutBlendTexture = null; + effectVolumesBlendAdjust = 0f; + currentVolumeEffects = blendVolumeEffects; + currentVolumeEffects.SetValues(this); + currentExposure = blendExposure; + if (blendingFromMidBlend && midBlendLUT != null) + { + midBlendLUT.DiscardContents(); + } + blendingFromMidBlend = false; + } + } + + public void EnterVolume(AmplifyColorVolumeBase volume) + { + if (!enteredVolumes.Contains(volume)) + { + enteredVolumes.Insert(0, volume); + } + } + + public void ExitVolume(AmplifyColorVolumeBase volume) + { + if (enteredVolumes.Contains(volume)) + { + enteredVolumes.Remove(volume); + } + } + + private void UpdateVolumes() + { + if (volumesBlending) + { + currentVolumeEffects.BlendValues(this, blendVolumeEffects, effectVolumesBlendAdjusted); + } + if (volumesBlending) + { + Exposure = Mathf.Lerp(currentExposure, blendExposure, effectVolumesBlendAdjusted); + } + Transform transform = ((TriggerVolumeProxy == null) ? base.transform : TriggerVolumeProxy); + if (actualTriggerProxy.transform.parent != transform) + { + actualTriggerProxy.Reference = transform; + actualTriggerProxy.gameObject.layer = transform.gameObject.layer; + } + AmplifyColorVolumeBase amplifyColorVolumeBase = null; + int num = int.MinValue; + for (int i = 0; i < enteredVolumes.Count; i++) + { + AmplifyColorVolumeBase amplifyColorVolumeBase2 = enteredVolumes[i]; + if (amplifyColorVolumeBase2.Priority > num) + { + amplifyColorVolumeBase = amplifyColorVolumeBase2; + num = amplifyColorVolumeBase2.Priority; + } + } + if (!(amplifyColorVolumeBase != currentVolumeLut)) + { + return; + } + currentVolumeLut = amplifyColorVolumeBase; + Texture texture = ((amplifyColorVolumeBase == null) ? worldLUT : amplifyColorVolumeBase.LutTexture); + float num2 = ((amplifyColorVolumeBase == null) ? ExitVolumeBlendTime : amplifyColorVolumeBase.EnterBlendTime); + if (volumesBlending && !blendingFromMidBlend && texture == LutTexture) + { + LutTexture = volumesLutBlendTexture; + volumesLutBlendTexture = texture; + volumesBlendingTimeCountdown = num2 * ((volumesBlendingTime - volumesBlendingTimeCountdown) / volumesBlendingTime); + volumesBlendingTime = num2; + currentVolumeEffects = VolumeEffect.BlendValuesToVolumeEffect(EffectFlags, currentVolumeEffects, blendVolumeEffects, effectVolumesBlendAdjusted); + currentExposure = Mathf.Lerp(currentExposure, blendExposure, effectVolumesBlendAdjusted); + effectVolumesBlendAdjust = 1f - volumesBlendAmount; + volumesBlendAmount = 1f - volumesBlendAmount; + } + else + { + if (volumesBlending) + { + materialBlendCache.SetFloat("_LerpAmount", volumesBlendAmount); + if (blendingFromMidBlend) + { + Graphics.Blit(midBlendLUT, blendCacheLut); + materialBlendCache.SetTexture("_RgbTex", blendCacheLut); + } + else + { + materialBlendCache.SetTexture("_RgbTex", LutTexture); + } + materialBlendCache.SetTexture("_LerpRgbTex", (volumesLutBlendTexture != null) ? volumesLutBlendTexture : defaultLut); + Graphics.Blit(midBlendLUT, midBlendLUT, materialBlendCache); + blendCacheLut.DiscardContents(); + currentVolumeEffects = VolumeEffect.BlendValuesToVolumeEffect(EffectFlags, currentVolumeEffects, blendVolumeEffects, effectVolumesBlendAdjusted); + currentExposure = Mathf.Lerp(currentExposure, blendExposure, effectVolumesBlendAdjusted); + effectVolumesBlendAdjust = 0f; + blendingFromMidBlend = true; + } + VolumesBlendTo(texture, num2); + } + blendVolumeEffects = ((amplifyColorVolumeBase == null) ? worldVolumeEffects : amplifyColorVolumeBase.EffectContainer.FindVolumeEffect(this)); + blendExposure = ((amplifyColorVolumeBase == null) ? worldExposure : amplifyColorVolumeBase.Exposure); + if (blendVolumeEffects == null) + { + blendVolumeEffects = worldVolumeEffects; + } + } + + private void SetupShader() + { + colorSpace = QualitySettings.activeColorSpace; + qualityLevel = QualityLevel; + shaderBase = Shader.Find("Hidden/Amplify Color/Base"); + shaderBlend = Shader.Find("Hidden/Amplify Color/Blend"); + shaderBlendCache = Shader.Find("Hidden/Amplify Color/BlendCache"); + shaderMask = Shader.Find("Hidden/Amplify Color/Mask"); + shaderMaskBlend = Shader.Find("Hidden/Amplify Color/MaskBlend"); + shaderDepthMask = Shader.Find("Hidden/Amplify Color/DepthMask"); + shaderDepthMaskBlend = Shader.Find("Hidden/Amplify Color/DepthMaskBlend"); + shaderProcessOnly = Shader.Find("Hidden/Amplify Color/ProcessOnly"); + } + + private void ReleaseMaterials() + { + SafeRelease(ref materialBase); + SafeRelease(ref materialBlend); + SafeRelease(ref materialBlendCache); + SafeRelease(ref materialMask); + SafeRelease(ref materialMaskBlend); + SafeRelease(ref materialDepthMask); + SafeRelease(ref materialDepthMaskBlend); + SafeRelease(ref materialProcessOnly); + } + + private Texture2D CreateDefaultLut() + { + defaultLut = new Texture2D(1024, 32, TextureFormat.RGB24, mipChain: false, linear: true) + { + hideFlags = HideFlags.HideAndDontSave + }; + defaultLut.name = "DefaultLut"; + defaultLut.hideFlags = HideFlags.DontSave; + defaultLut.anisoLevel = 1; + defaultLut.filterMode = FilterMode.Bilinear; + Color32[] array = new Color32[32768]; + for (int i = 0; i < 32; i++) + { + int num = i * 32; + for (int j = 0; j < 32; j++) + { + int num2 = num + j * 1024; + for (int k = 0; k < 32; k++) + { + float num3 = (float)k / 31f; + float num4 = (float)j / 31f; + float num5 = (float)i / 31f; + byte r = (byte)(num3 * 255f); + byte g = (byte)(num4 * 255f); + byte b = (byte)(num5 * 255f); + array[num2 + k] = new Color32(r, g, b, byte.MaxValue); + } + } + } + defaultLut.SetPixels32(array); + defaultLut.Apply(); + return defaultLut; + } + + private Texture2D CreateDepthCurveLut() + { + SafeRelease(ref depthCurveLut); + depthCurveLut = new Texture2D(1024, 1, TextureFormat.Alpha8, mipChain: false, linear: true) + { + hideFlags = HideFlags.HideAndDontSave + }; + depthCurveLut.name = "DepthCurveLut"; + depthCurveLut.hideFlags = HideFlags.DontSave; + depthCurveLut.anisoLevel = 1; + depthCurveLut.wrapMode = TextureWrapMode.Clamp; + depthCurveLut.filterMode = FilterMode.Bilinear; + depthCurveColors = new Color32[1024]; + return depthCurveLut; + } + + private void UpdateDepthCurveLut() + { + if (depthCurveLut == null) + { + CreateDepthCurveLut(); + } + float num = 0f; + int num2 = 0; + while (num2 < 1024) + { + depthCurveColors[num2].a = (byte)Mathf.FloorToInt(Mathf.Clamp01(DepthMaskCurve.Evaluate(num)) * 255f); + num2++; + num += 0.0009775171f; + } + depthCurveLut.SetPixels32(depthCurveColors); + depthCurveLut.Apply(); + } + + private void CheckUpdateDepthCurveLut() + { + bool flag = false; + if (DepthMaskCurve.length != prevDepthMaskCurve.length) + { + flag = true; + } + else + { + float num = 0f; + int num2 = 0; + while (num2 < DepthMaskCurve.length) + { + if (Mathf.Abs(DepthMaskCurve.Evaluate(num) - prevDepthMaskCurve.Evaluate(num)) > float.Epsilon) + { + flag = true; + break; + } + num2++; + num += 0.0009775171f; + } + } + if (depthCurveLut == null || flag) + { + UpdateDepthCurveLut(); + prevDepthMaskCurve = new AnimationCurve(DepthMaskCurve.keys); + } + } + + private void CreateHelperTextures() + { + ReleaseTextures(); + blendCacheLut = new RenderTexture(1024, 32, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear) + { + hideFlags = HideFlags.HideAndDontSave + }; + blendCacheLut.name = "BlendCacheLut"; + blendCacheLut.wrapMode = TextureWrapMode.Clamp; + blendCacheLut.useMipMap = false; + blendCacheLut.anisoLevel = 0; + blendCacheLut.Create(); + midBlendLUT = new RenderTexture(1024, 32, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear) + { + hideFlags = HideFlags.HideAndDontSave + }; + midBlendLUT.name = "MidBlendLut"; + midBlendLUT.wrapMode = TextureWrapMode.Clamp; + midBlendLUT.useMipMap = false; + midBlendLUT.anisoLevel = 0; + midBlendLUT.Create(); + CreateDefaultLut(); + if (UseDepthMask) + { + CreateDepthCurveLut(); + } + } + + private bool CheckMaterialAndShader(Material material, string name) + { + if (material == null || material.shader == null) + { + Debug.LogWarning("[AmplifyColor] Error creating " + name + " material. Effect disabled."); + base.enabled = false; + } + else if (!material.shader.isSupported) + { + Debug.LogWarning("[AmplifyColor] " + name + " shader not supported on this platform. Effect disabled."); + base.enabled = false; + } + else + { + material.hideFlags = HideFlags.HideAndDontSave; + } + return base.enabled; + } + + private bool CreateMaterials() + { + SetupShader(); + if (!CheckShaders()) + { + return false; + } + ReleaseMaterials(); + materialBase = new Material(shaderBase); + materialBlend = new Material(shaderBlend); + materialBlendCache = new Material(shaderBlendCache); + materialMask = new Material(shaderMask); + materialMaskBlend = new Material(shaderMaskBlend); + materialDepthMask = new Material(shaderDepthMask); + materialDepthMaskBlend = new Material(shaderDepthMaskBlend); + materialProcessOnly = new Material(shaderProcessOnly); + if (1 == 0 || !CheckMaterialAndShader(materialBase, "BaseMaterial") || !CheckMaterialAndShader(materialBlend, "BlendMaterial") || !CheckMaterialAndShader(materialBlendCache, "BlendCacheMaterial") || !CheckMaterialAndShader(materialMask, "MaskMaterial") || !CheckMaterialAndShader(materialMaskBlend, "MaskBlendMaterial") || !CheckMaterialAndShader(materialDepthMask, "DepthMaskMaterial") || !CheckMaterialAndShader(materialDepthMaskBlend, "DepthMaskBlendMaterial") || !CheckMaterialAndShader(materialProcessOnly, "ProcessOnlyMaterial")) + { + return false; + } + CreateHelperTextures(); + return true; + } + + private void SetMaterialKeyword(string keyword, bool state) + { + bool flag = materialBase.IsKeywordEnabled(keyword); + if (state && !flag) + { + materialBase.EnableKeyword(keyword); + materialBlend.EnableKeyword(keyword); + materialBlendCache.EnableKeyword(keyword); + materialMask.EnableKeyword(keyword); + materialMaskBlend.EnableKeyword(keyword); + materialDepthMask.EnableKeyword(keyword); + materialDepthMaskBlend.EnableKeyword(keyword); + materialProcessOnly.EnableKeyword(keyword); + } + else if (!state && materialBase.IsKeywordEnabled(keyword)) + { + materialBase.DisableKeyword(keyword); + materialBlend.DisableKeyword(keyword); + materialBlendCache.DisableKeyword(keyword); + materialMask.DisableKeyword(keyword); + materialMaskBlend.DisableKeyword(keyword); + materialDepthMask.DisableKeyword(keyword); + materialDepthMaskBlend.DisableKeyword(keyword); + materialProcessOnly.DisableKeyword(keyword); + } + } + + private void SafeRelease<T>(ref T obj) where T : UnityEngine.Object + { + if ((UnityEngine.Object)obj != (UnityEngine.Object)null) + { + if (obj.GetType() == typeof(RenderTexture)) + { + (obj as RenderTexture).Release(); + } + UnityEngine.Object.DestroyImmediate(obj); + obj = null; + } + } + + private void ReleaseTextures() + { + RenderTexture.active = null; + SafeRelease(ref blendCacheLut); + SafeRelease(ref midBlendLUT); + SafeRelease(ref defaultLut); + SafeRelease(ref depthCurveLut); + } + + public static bool ValidateLutDimensions(Texture lut) + { + bool result = true; + if (lut != null) + { + if (lut.width / lut.height != lut.height) + { + Debug.LogWarning("[AmplifyColor] Lut " + lut.name + " has invalid dimensions."); + result = false; + } + else if (lut.anisoLevel != 0) + { + lut.anisoLevel = 0; + } + } + return result; + } + + private void UpdatePostEffectParams() + { + if (UseDepthMask) + { + CheckUpdateDepthCurveLut(); + } + Exposure = Mathf.Max(Exposure, 0f); + } + + private int ComputeShaderPass() + { + bool flag = QualityLevel == Quality.Mobile; + bool flag2 = colorSpace == ColorSpace.Linear; + bool allowHDR = ownerCamera.allowHDR; + int num = (flag ? 18 : 0); + if (allowHDR) + { + num += 2; + num += (flag2 ? 8 : 0); + num += (ApplyDithering ? 4 : 0); + return (int)(num + Tonemapper); + } + return num + (flag2 ? 1 : 0); + } + + private void OnRenderImage(RenderTexture source, RenderTexture destination) + { + if (silentError) + { + Graphics.Blit(source, destination); + return; + } + BlendAmount = Mathf.Clamp01(BlendAmount); + if (colorSpace != QualitySettings.activeColorSpace || qualityLevel != QualityLevel) + { + CreateMaterials(); + } + UpdatePostEffectParams(); + bool num = ValidateLutDimensions(LutTexture); + bool flag = ValidateLutDimensions(LutBlendTexture); + bool flag2 = LutTexture == null && LutBlendTexture == null && volumesLutBlendTexture == null; + Texture texture = ((LutTexture == null) ? defaultLut : LutTexture); + Texture lutBlendTexture = LutBlendTexture; + int pass = ComputeShaderPass(); + bool flag3 = BlendAmount != 0f || blending; + bool flag4 = flag3 || (flag3 && lutBlendTexture != null); + bool flag5 = flag4; + bool num2 = !num || !flag || flag2; + Material material = (num2 ? materialProcessOnly : ((flag4 || volumesBlending) ? ((!UseDepthMask) ? ((MaskTexture != null) ? materialMaskBlend : materialBlend) : materialDepthMaskBlend) : ((!UseDepthMask) ? ((MaskTexture != null) ? materialMask : materialBase) : materialDepthMask))); + material.SetFloat("_Exposure", Exposure); + material.SetFloat("_ShoulderStrength", 0.22f); + material.SetFloat("_LinearStrength", 0.3f); + material.SetFloat("_LinearAngle", 0.1f); + material.SetFloat("_ToeStrength", 0.2f); + material.SetFloat("_ToeNumerator", 0.01f); + material.SetFloat("_ToeDenominator", 0.3f); + material.SetFloat("_LinearWhite", LinearWhitePoint); + material.SetFloat("_LerpAmount", BlendAmount); + if (MaskTexture != null) + { + material.SetTexture("_MaskTex", MaskTexture); + } + if (UseDepthMask) + { + material.SetTexture("_DepthCurveLut", depthCurveLut); + } + if (MaskTexture != null && source.dimension == TextureDimension.Tex2DArray) + { + material.SetVector("_StereoScale", new Vector4(0.5f, 1f, 0.5f, 0f)); + } + else + { + material.SetVector("_StereoScale", new Vector4(1f, 1f, 0f, 0f)); + } + if (!num2) + { + if (volumesBlending) + { + volumesBlendAmount = Mathf.Clamp01(volumesBlendAmount); + materialBlendCache.SetFloat("_LerpAmount", volumesBlendAmount); + if (blendingFromMidBlend) + { + materialBlendCache.SetTexture("_RgbTex", midBlendLUT); + } + else + { + materialBlendCache.SetTexture("_RgbTex", texture); + } + materialBlendCache.SetTexture("_LerpRgbTex", (volumesLutBlendTexture != null) ? volumesLutBlendTexture : defaultLut); + Graphics.Blit(texture, blendCacheLut, materialBlendCache); + } + if (flag5) + { + materialBlendCache.SetFloat("_LerpAmount", BlendAmount); + RenderTexture renderTexture = null; + if (volumesBlending) + { + renderTexture = RenderTexture.GetTemporary(blendCacheLut.width, blendCacheLut.height, blendCacheLut.depth, blendCacheLut.format, RenderTextureReadWrite.Linear); + Graphics.Blit(blendCacheLut, renderTexture); + materialBlendCache.SetTexture("_RgbTex", renderTexture); + } + else + { + materialBlendCache.SetTexture("_RgbTex", texture); + } + materialBlendCache.SetTexture("_LerpRgbTex", (lutBlendTexture != null) ? lutBlendTexture : defaultLut); + Graphics.Blit(texture, blendCacheLut, materialBlendCache); + if (renderTexture != null) + { + RenderTexture.ReleaseTemporary(renderTexture); + } + material.SetTexture("_RgbBlendCacheTex", blendCacheLut); + } + else if (volumesBlending) + { + material.SetTexture("_RgbBlendCacheTex", blendCacheLut); + } + else + { + if (texture != null) + { + material.SetTexture("_RgbTex", texture); + } + if (lutBlendTexture != null) + { + material.SetTexture("_LerpRgbTex", lutBlendTexture); + } + } + } + Graphics.Blit(source, destination, material, pass); + if (flag5 || volumesBlending) + { + blendCacheLut.DiscardContents(); + } + } +} diff --git a/GameCode/AmplifyColorEffect.cs b/GameCode/AmplifyColorEffect.cs new file mode 100644 index 0000000..ca37822 --- /dev/null +++ b/GameCode/AmplifyColorEffect.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +[ImageEffectAllowedInSceneView] +[ImageEffectTransformsToLDR] +[ExecuteInEditMode] +[AddComponentMenu("Image Effects/Amplify Color")] +public sealed class AmplifyColorEffect : AmplifyColorBase +{ +} diff --git a/GameCode/AmplifyColorRenderMask.cs b/GameCode/AmplifyColorRenderMask.cs new file mode 100644 index 0000000..8890a0e --- /dev/null +++ b/GameCode/AmplifyColorRenderMask.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +[ExecuteInEditMode] +[RequireComponent(typeof(Camera))] +[RequireComponent(typeof(AmplifyColorEffect))] +[AddComponentMenu("Image Effects/Amplify Color Render Mask")] +public class AmplifyColorRenderMask : AmplifyColorRenderMaskBase +{ +} diff --git a/GameCode/AmplifyColorRenderMaskBase.cs b/GameCode/AmplifyColorRenderMaskBase.cs new file mode 100644 index 0000000..589c64a --- /dev/null +++ b/GameCode/AmplifyColorRenderMaskBase.cs @@ -0,0 +1,174 @@ +using AmplifyColor; +using UnityEngine; +using UnityEngine.Serialization; +using UnityEngine.XR; + +[ExecuteInEditMode] +[RequireComponent(typeof(Camera))] +[AddComponentMenu("")] +public class AmplifyColorRenderMaskBase : MonoBehaviour +{ + [FormerlySerializedAs("clearColor")] + public Color ClearColor = Color.black; + + [FormerlySerializedAs("renderLayers")] + public RenderLayer[] RenderLayers = new RenderLayer[0]; + + [FormerlySerializedAs("debug")] + public bool DebugMask; + + private Camera referenceCamera; + + private Camera maskCamera; + + private AmplifyColorBase colorEffect; + + private int width; + + private int height; + + private RenderTexture maskTexture; + + private Shader colorMaskShader; + + private bool singlePassStereo; + + private void OnEnable() + { + if (maskCamera == null) + { + GameObject gameObject = new GameObject("Mask Camera", typeof(Camera)) + { + hideFlags = HideFlags.HideAndDontSave + }; + gameObject.transform.parent = base.gameObject.transform; + maskCamera = gameObject.GetComponent<Camera>(); + } + referenceCamera = GetComponent<Camera>(); + colorEffect = GetComponent<AmplifyColorBase>(); + colorMaskShader = Shader.Find("Hidden/RenderMask"); + } + + private void OnDisable() + { + DestroyCamera(); + DestroyRenderTextures(); + } + + private void DestroyCamera() + { + if (maskCamera != null) + { + Object.DestroyImmediate(maskCamera.gameObject); + maskCamera = null; + } + } + + private void DestroyRenderTextures() + { + if (maskTexture != null) + { + RenderTexture.active = null; + Object.DestroyImmediate(maskTexture); + maskTexture = null; + } + } + + private void UpdateRenderTextures(bool singlePassStereo) + { + int num = referenceCamera.pixelWidth; + int num2 = referenceCamera.pixelHeight; + if (maskTexture == null || width != num || height != num2 || !maskTexture.IsCreated() || this.singlePassStereo != singlePassStereo) + { + width = num; + height = num2; + DestroyRenderTextures(); + if (XRSettings.enabled) + { + num = XRSettings.eyeTextureWidth * ((!singlePassStereo) ? 1 : 2); + num2 = XRSettings.eyeTextureHeight; + } + if (maskTexture == null) + { + maskTexture = new RenderTexture(num, num2, 24, RenderTextureFormat.Default, RenderTextureReadWrite.sRGB) + { + hideFlags = HideFlags.HideAndDontSave, + name = "MaskTexture" + }; + maskTexture.name = "AmplifyColorMaskTexture"; + bool allowMSAA = maskCamera.allowMSAA; + maskTexture.antiAliasing = ((!allowMSAA || QualitySettings.antiAliasing <= 0) ? 1 : QualitySettings.antiAliasing); + } + maskTexture.Create(); + this.singlePassStereo = singlePassStereo; + } + if (colorEffect != null) + { + colorEffect.MaskTexture = maskTexture; + } + } + + private void UpdateCameraProperties() + { + maskCamera.CopyFrom(referenceCamera); + maskCamera.targetTexture = maskTexture; + maskCamera.clearFlags = CameraClearFlags.Nothing; + maskCamera.renderingPath = RenderingPath.VertexLit; + maskCamera.pixelRect = new Rect(0f, 0f, width, height); + maskCamera.depthTextureMode = DepthTextureMode.None; + maskCamera.allowHDR = false; + maskCamera.enabled = false; + } + + private void OnPreRender() + { + if (!(maskCamera != null)) + { + return; + } + RenderBuffer activeColorBuffer = Graphics.activeColorBuffer; + RenderBuffer activeDepthBuffer = Graphics.activeDepthBuffer; + bool flag = false; + if (referenceCamera.stereoEnabled) + { + flag = XRSettings.eyeTextureDesc.vrUsage == VRTextureUsage.TwoEyes; + maskCamera.SetStereoViewMatrix(Camera.StereoscopicEye.Left, referenceCamera.GetStereoViewMatrix(Camera.StereoscopicEye.Left)); + maskCamera.SetStereoViewMatrix(Camera.StereoscopicEye.Right, referenceCamera.GetStereoViewMatrix(Camera.StereoscopicEye.Right)); + maskCamera.SetStereoProjectionMatrix(Camera.StereoscopicEye.Left, referenceCamera.GetStereoProjectionMatrix(Camera.StereoscopicEye.Left)); + maskCamera.SetStereoProjectionMatrix(Camera.StereoscopicEye.Right, referenceCamera.GetStereoProjectionMatrix(Camera.StereoscopicEye.Right)); + } + UpdateRenderTextures(flag); + UpdateCameraProperties(); + Graphics.SetRenderTarget(maskTexture); + GL.Clear(clearDepth: true, clearColor: true, ClearColor); + if (flag) + { + maskCamera.worldToCameraMatrix = referenceCamera.GetStereoViewMatrix(Camera.StereoscopicEye.Left); + maskCamera.projectionMatrix = referenceCamera.GetStereoProjectionMatrix(Camera.StereoscopicEye.Left); + maskCamera.rect = new Rect(0f, 0f, 0.5f, 1f); + } + RenderLayer[] renderLayers = RenderLayers; + for (int i = 0; i < renderLayers.Length; i++) + { + RenderLayer renderLayer = renderLayers[i]; + Shader.SetGlobalColor("_COLORMASK_Color", renderLayer.color); + maskCamera.cullingMask = renderLayer.mask; + maskCamera.RenderWithShader(colorMaskShader, "RenderType"); + } + if (flag) + { + maskCamera.worldToCameraMatrix = referenceCamera.GetStereoViewMatrix(Camera.StereoscopicEye.Right); + maskCamera.projectionMatrix = referenceCamera.GetStereoProjectionMatrix(Camera.StereoscopicEye.Right); + maskCamera.rect = new Rect(0.5f, 0f, 0.5f, 1f); + renderLayers = RenderLayers; + for (int i = 0; i < renderLayers.Length; i++) + { + RenderLayer renderLayer2 = renderLayers[i]; + Shader.SetGlobalColor("_COLORMASK_Color", renderLayer2.color); + maskCamera.cullingMask = renderLayer2.mask; + maskCamera.RenderWithShader(colorMaskShader, "RenderType"); + } + } + Graphics.SetRenderTarget(activeColorBuffer, activeDepthBuffer); + } +} diff --git a/GameCode/AmplifyColorTriggerProxy.cs b/GameCode/AmplifyColorTriggerProxy.cs new file mode 100644 index 0000000..916f8f1 --- /dev/null +++ b/GameCode/AmplifyColorTriggerProxy.cs @@ -0,0 +1,27 @@ +using UnityEngine; + +[RequireComponent(typeof(Rigidbody))] +[RequireComponent(typeof(SphereCollider))] +[AddComponentMenu("")] +public class AmplifyColorTriggerProxy : AmplifyColorTriggerProxyBase +{ + private SphereCollider sphereCollider; + + private Rigidbody rigidBody; + + private void Start() + { + sphereCollider = GetComponent<SphereCollider>(); + sphereCollider.radius = 0.01f; + sphereCollider.isTrigger = true; + rigidBody = GetComponent<Rigidbody>(); + rigidBody.useGravity = false; + rigidBody.isKinematic = true; + } + + private void LateUpdate() + { + base.transform.position = Reference.position; + base.transform.rotation = Reference.rotation; + } +} diff --git a/GameCode/AmplifyColorTriggerProxy2D.cs b/GameCode/AmplifyColorTriggerProxy2D.cs new file mode 100644 index 0000000..c4bc606 --- /dev/null +++ b/GameCode/AmplifyColorTriggerProxy2D.cs @@ -0,0 +1,27 @@ +using UnityEngine; + +[RequireComponent(typeof(Rigidbody2D))] +[RequireComponent(typeof(CircleCollider2D))] +[AddComponentMenu("")] +public class AmplifyColorTriggerProxy2D : AmplifyColorTriggerProxyBase +{ + private CircleCollider2D circleCollider; + + private Rigidbody2D rigidBody; + + private void Start() + { + circleCollider = GetComponent<CircleCollider2D>(); + circleCollider.radius = 0.01f; + circleCollider.isTrigger = true; + rigidBody = GetComponent<Rigidbody2D>(); + rigidBody.gravityScale = 0f; + rigidBody.isKinematic = true; + } + + private void LateUpdate() + { + base.transform.position = Reference.position; + base.transform.rotation = Reference.rotation; + } +} diff --git a/GameCode/AmplifyColorTriggerProxyBase.cs b/GameCode/AmplifyColorTriggerProxyBase.cs new file mode 100644 index 0000000..efb1cac --- /dev/null +++ b/GameCode/AmplifyColorTriggerProxyBase.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +[AddComponentMenu("")] +public class AmplifyColorTriggerProxyBase : MonoBehaviour +{ + public Transform Reference; + + public AmplifyColorBase OwnerEffect; +} diff --git a/GameCode/AmplifyColorVolume.cs b/GameCode/AmplifyColorVolume.cs new file mode 100644 index 0000000..e616e57 --- /dev/null +++ b/GameCode/AmplifyColorVolume.cs @@ -0,0 +1,24 @@ +using UnityEngine; + +[RequireComponent(typeof(BoxCollider))] +[AddComponentMenu("Image Effects/Amplify Color Volume")] +public class AmplifyColorVolume : AmplifyColorVolumeBase +{ + private void OnTriggerEnter(Collider other) + { + AmplifyColorTriggerProxy component = other.GetComponent<AmplifyColorTriggerProxy>(); + if (component != null && component.OwnerEffect.UseVolumes && ((int)component.OwnerEffect.VolumeCollisionMask & (1 << base.gameObject.layer)) != 0) + { + component.OwnerEffect.EnterVolume(this); + } + } + + private void OnTriggerExit(Collider other) + { + AmplifyColorTriggerProxy component = other.GetComponent<AmplifyColorTriggerProxy>(); + if (component != null && component.OwnerEffect.UseVolumes && ((int)component.OwnerEffect.VolumeCollisionMask & (1 << base.gameObject.layer)) != 0) + { + component.OwnerEffect.ExitVolume(this); + } + } +} diff --git a/GameCode/AmplifyColorVolume2D.cs b/GameCode/AmplifyColorVolume2D.cs new file mode 100644 index 0000000..3dd0bbd --- /dev/null +++ b/GameCode/AmplifyColorVolume2D.cs @@ -0,0 +1,24 @@ +using UnityEngine; + +[RequireComponent(typeof(BoxCollider2D))] +[AddComponentMenu("Image Effects/Amplify Color Volume 2D")] +public class AmplifyColorVolume2D : AmplifyColorVolumeBase +{ + private void OnTriggerEnter2D(Collider2D other) + { + AmplifyColorTriggerProxy2D component = other.GetComponent<AmplifyColorTriggerProxy2D>(); + if (component != null && component.OwnerEffect.UseVolumes && ((int)component.OwnerEffect.VolumeCollisionMask & (1 << base.gameObject.layer)) != 0) + { + component.OwnerEffect.EnterVolume(this); + } + } + + private void OnTriggerExit2D(Collider2D other) + { + AmplifyColorTriggerProxy2D component = other.GetComponent<AmplifyColorTriggerProxy2D>(); + if (component != null && component.OwnerEffect.UseVolumes && ((int)component.OwnerEffect.VolumeCollisionMask & (1 << base.gameObject.layer)) != 0) + { + component.OwnerEffect.ExitVolume(this); + } + } +} diff --git a/GameCode/AmplifyColorVolumeBase.cs b/GameCode/AmplifyColorVolumeBase.cs new file mode 100644 index 0000000..b241f7f --- /dev/null +++ b/GameCode/AmplifyColorVolumeBase.cs @@ -0,0 +1,74 @@ +using AmplifyColor; +using UnityEngine; + +[ExecuteInEditMode] +[AddComponentMenu("")] +public class AmplifyColorVolumeBase : MonoBehaviour +{ + public Texture2D LutTexture; + + public float Exposure = 1f; + + public float EnterBlendTime = 1f; + + public int Priority; + + public bool ShowInSceneView = true; + + [HideInInspector] + public VolumeEffectContainer EffectContainer = new VolumeEffectContainer(); + + private void OnDrawGizmos() + { + if (!ShowInSceneView) + { + return; + } + BoxCollider component = GetComponent<BoxCollider>(); + BoxCollider2D component2 = GetComponent<BoxCollider2D>(); + if (component != null || component2 != null) + { + Vector3 center; + Vector3 size; + if (component != null) + { + center = component.center; + size = component.size; + } + else + { + center = component2.offset; + size = component2.size; + } + Gizmos.color = Color.green; + Gizmos.matrix = base.transform.localToWorldMatrix; + Gizmos.DrawWireCube(center, size); + } + } + + private void OnDrawGizmosSelected() + { + BoxCollider component = GetComponent<BoxCollider>(); + BoxCollider2D component2 = GetComponent<BoxCollider2D>(); + if (component != null || component2 != null) + { + Color green = Color.green; + green.a = 0.2f; + Gizmos.color = green; + Gizmos.matrix = base.transform.localToWorldMatrix; + Vector3 center; + Vector3 size; + if (component != null) + { + center = component.center; + size = component.size; + } + else + { + center = component2.offset; + size = component2.size; + } + Gizmos.DrawCube(center, size); + } + } +} diff --git a/GameCode/ApplyCardStats.cs b/GameCode/ApplyCardStats.cs new file mode 100644 index 0000000..378db39 --- /dev/null +++ b/GameCode/ApplyCardStats.cs @@ -0,0 +1,305 @@ +using System.Collections.Generic; +using Photon.Pun; +using UnityEngine; + +public class ApplyCardStats : MonoBehaviour +{ + private Gun myGunStats; + + private CharacterStatModifiers myPlayerStats; + + private Block myBlock; + + private Player playerToUpgrade; + + private CardAudioModifier cardAudio; + + private bool done; + + private DamagableEvent damagable; + + public bool shootToPick; + + private void Start() + { + myGunStats = GetComponent<Gun>(); + myPlayerStats = GetComponent<CharacterStatModifiers>(); + myBlock = GetComponentInChildren<Block>(); + cardAudio = GetComponent<CardAudioModifier>(); + damagable = GetComponentInChildren<DamagableEvent>(); + } + + private void Update() + { + if (shootToPick && damagable.dead && (bool)damagable.lastPlayer) + { + Pick(damagable.lastPlayer.teamID); + Object.Destroy(base.gameObject); + } + } + + [PunRPC] + public void RPCA_Pick(int[] actorIDs) + { + for (int i = 0; i < actorIDs.Length; i++) + { + playerToUpgrade = PlayerManager.instance.GetPlayerWithActorID(actorIDs[i]); + ApplyStats(); + CardBarHandler.instance.AddCard(playerToUpgrade.playerID, GetComponent<CardInfo>().sourceCard); + } + } + + [PunRPC] + public void OFFLINE_Pick(Player[] players) + { + for (int i = 0; i < players.Length; i++) + { + playerToUpgrade = players[i]; + ApplyStats(); + CardBarHandler.instance.AddCard(playerToUpgrade.playerID, GetComponent<CardInfo>().sourceCard); + } + } + + public void Pick(int pickerID, bool forcePick = false, PickerType pickerType = PickerType.Team) + { + Start(); + if (done && !forcePick) + { + return; + } + done = true; + Player[] array = PlayerManager.instance.GetPlayersInTeam(pickerID); + if (pickerType == PickerType.Player) + { + array = new Player[1] { PlayerManager.instance.players[pickerID] }; + } + if (PhotonNetwork.OfflineMode) + { + OFFLINE_Pick(array); + return; + } + int[] array2 = new int[array.Length]; + for (int i = 0; i < array.Length; i++) + { + array2[i] = array[i].data.view.ControllerActorNr; + } + GetComponent<PhotonView>().RPC("RPCA_Pick", RpcTarget.All, array2); + } + + private void ApplyStats() + { + done = true; + PlayerAudioModifyers component = playerToUpgrade.GetComponent<PlayerAudioModifyers>(); + Gun component2 = playerToUpgrade.GetComponent<Holding>().holdable.GetComponent<Gun>(); + Player component3 = playerToUpgrade.GetComponent<Player>(); + CharacterData component4 = playerToUpgrade.GetComponent<CharacterData>(); + HealthHandler component5 = playerToUpgrade.GetComponent<HealthHandler>(); + playerToUpgrade.GetComponent<Movement>(); + Gravity component6 = playerToUpgrade.GetComponent<Gravity>(); + Block component7 = playerToUpgrade.GetComponent<Block>(); + CharacterStatModifiers component8 = component3.GetComponent<CharacterStatModifiers>(); + GunAmmo componentInChildren = component2.GetComponentInChildren<GunAmmo>(); + if ((bool)componentInChildren && (bool)myGunStats) + { + componentInChildren.ammoReg += myGunStats.ammoReg; + componentInChildren.maxAmmo += myGunStats.ammo; + componentInChildren.maxAmmo = Mathf.Clamp(componentInChildren.maxAmmo, 1, 90); + componentInChildren.reloadTimeMultiplier *= myGunStats.reloadTime; + componentInChildren.reloadTimeAdd += myGunStats.reloadTimeAdd; + } + component3.data.currentCards.Add(GetComponent<CardInfo>().sourceCard); + if ((bool)myGunStats) + { + if (myGunStats.lockGunToDefault) + { + component2.defaultCooldown = myGunStats.forceSpecificAttackSpeed; + component2.lockGunToDefault = myGunStats.lockGunToDefault; + } + if ((bool)myGunStats && myGunStats.projectiles.Length != 0) + { + component2.projectiles[0].objectToSpawn = myGunStats.projectiles[0].objectToSpawn; + } + if ((bool)myGunStats) + { + CopyGunStats(myGunStats, component2); + } + } + if ((bool)myPlayerStats) + { + component8.sizeMultiplier *= myPlayerStats.sizeMultiplier; + component4.maxHealth *= myPlayerStats.health; + component8.ConfigureMassAndSize(); + component8.movementSpeed *= myPlayerStats.movementSpeed; + component8.jump *= myPlayerStats.jump; + component4.jumps += myPlayerStats.numberOfJumps; + component6.gravityForce *= myPlayerStats.gravity; + component5.regeneration += myPlayerStats.regen; + if ((bool)myPlayerStats.AddObjectToPlayer) + { + component8.objectsAddedToPlayer.Add(Object.Instantiate(myPlayerStats.AddObjectToPlayer, component3.transform.position, component3.transform.rotation, component3.transform)); + } + component8.lifeSteal += myPlayerStats.lifeSteal; + component8.respawns += myPlayerStats.respawns; + component8.secondsToTakeDamageOver += myPlayerStats.secondsToTakeDamageOver; + if (myPlayerStats.refreshOnDamage) + { + component8.refreshOnDamage = true; + } + if (!myPlayerStats.automaticReload) + { + component8.automaticReload = false; + } + } + if ((bool)myBlock) + { + if (myBlock.objectsToSpawn != null) + { + for (int i = 0; i < myBlock.objectsToSpawn.Count; i++) + { + component7.objectsToSpawn.Add(myBlock.objectsToSpawn[i]); + } + } + component7.cdMultiplier *= myBlock.cdMultiplier; + component7.cdAdd += myBlock.cdAdd; + component7.forceToAdd += myBlock.forceToAdd; + component7.forceToAddUp += myBlock.forceToAddUp; + component7.additionalBlocks += myBlock.additionalBlocks; + component7.healing += myBlock.healing; + if (myBlock.autoBlock) + { + component7.autoBlock = myBlock.autoBlock; + } + } + if ((bool)component && (bool)cardAudio) + { + component.AddToStack(cardAudio); + } + component8.WasUpdated(); + component5.Revive(); + } + + public static void CopyGunStats(Gun copyFromGun, Gun copyToGun) + { + if (copyFromGun.unblockable) + { + copyToGun.unblockable = copyFromGun.unblockable; + } + if (copyFromGun.ignoreWalls) + { + copyToGun.ignoreWalls = copyFromGun.ignoreWalls; + } + float num = 1f; + if (copyFromGun.numberOfProjectiles != 0 && copyToGun.numberOfProjectiles != 1) + { + num = (float)copyFromGun.numberOfProjectiles / ((float)copyFromGun.numberOfProjectiles + (float)copyToGun.numberOfProjectiles); + } + copyToGun.damage *= 1f - num * (1f - copyFromGun.damage); + if (copyToGun.damage < 0.25f) + { + copyToGun.damage = 0.25f; + } + copyToGun.size += copyFromGun.size; + float num2 = 1f; + if (copyFromGun.chargeNumberOfProjectilesTo != 0f) + { + num2 = copyFromGun.chargeNumberOfProjectilesTo / (copyFromGun.chargeNumberOfProjectilesTo + copyToGun.chargeNumberOfProjectilesTo); + } + copyToGun.chargeDamageMultiplier *= 1f - num2 * (1f - copyFromGun.chargeDamageMultiplier); + copyToGun.knockback *= 1f - num * (1f - copyFromGun.knockback); + copyToGun.projectileSpeed *= copyFromGun.projectileSpeed; + copyToGun.projectielSimulatonSpeed *= copyFromGun.projectielSimulatonSpeed; + copyToGun.gravity *= copyFromGun.gravity; + copyToGun.multiplySpread *= copyFromGun.multiplySpread; + copyToGun.attackSpeed *= copyFromGun.attackSpeed; + copyToGun.bodyRecoil *= copyFromGun.recoilMuiltiplier; + copyToGun.speedMOnBounce *= copyFromGun.speedMOnBounce; + copyToGun.dmgMOnBounce *= copyFromGun.dmgMOnBounce; + copyToGun.bulletDamageMultiplier *= copyFromGun.bulletDamageMultiplier; + copyToGun.spread += copyFromGun.spread; + copyToGun.drag += copyFromGun.drag; + copyToGun.timeBetweenBullets += copyFromGun.timeBetweenBullets; + copyToGun.dragMinSpeed += copyFromGun.dragMinSpeed; + copyToGun.evenSpread += copyFromGun.evenSpread; + copyToGun.numberOfProjectiles += copyFromGun.numberOfProjectiles; + copyToGun.reflects += copyFromGun.reflects; + copyToGun.smartBounce += copyFromGun.smartBounce; + copyToGun.bulletPortal += copyFromGun.bulletPortal; + copyToGun.randomBounces += copyFromGun.randomBounces; + copyToGun.bursts += copyFromGun.bursts; + copyToGun.slow += copyFromGun.slow; + copyToGun.overheatMultiplier += copyFromGun.overheatMultiplier; + copyToGun.projectileSize += copyFromGun.projectileSize; + copyToGun.percentageDamage += copyFromGun.percentageDamage; + copyToGun.damageAfterDistanceMultiplier *= copyFromGun.damageAfterDistanceMultiplier; + copyToGun.timeToReachFullMovementMultiplier *= copyFromGun.timeToReachFullMovementMultiplier; + copyToGun.cos += copyFromGun.cos; + if (copyFromGun.dontAllowAutoFire) + { + copyToGun.dontAllowAutoFire = true; + } + if (copyFromGun.destroyBulletAfter != 0f) + { + copyToGun.destroyBulletAfter = copyFromGun.destroyBulletAfter; + } + copyToGun.chargeSpreadTo += copyFromGun.chargeSpreadTo; + copyToGun.chargeSpeedTo += copyFromGun.chargeSpeedTo; + copyToGun.chargeEvenSpreadTo += copyFromGun.chargeEvenSpreadTo; + copyToGun.chargeNumberOfProjectilesTo += copyFromGun.chargeNumberOfProjectilesTo; + copyToGun.chargeRecoilTo += copyFromGun.chargeRecoilTo; + if (copyFromGun.projectileColor != Color.black) + { + if (copyToGun.projectileColor == Color.black) + { + copyToGun.projectileColor = copyFromGun.projectileColor; + } + float r = Mathf.Pow((copyToGun.projectileColor.r * copyToGun.projectileColor.r + copyFromGun.projectileColor.r * copyFromGun.projectileColor.r) / 2f, 0.5f); + float g = Mathf.Pow((copyToGun.projectileColor.g * copyToGun.projectileColor.g + copyFromGun.projectileColor.g * copyFromGun.projectileColor.g) / 2f, 0.5f); + float b = Mathf.Pow((copyToGun.projectileColor.b * copyToGun.projectileColor.b + copyFromGun.projectileColor.b * copyFromGun.projectileColor.b) / 2f, 0.5f); + Color rgbColor = new Color(r, g, b, 1f); + float H = 0f; + float S = 0f; + float V = 0f; + Color.RGBToHSV(rgbColor, out H, out S, out V); + S = 1f; + V = 1f; + copyToGun.projectileColor = Color.HSVToRGB(H, S, V); + } + List<ObjectsToSpawn> list = new List<ObjectsToSpawn>(); + for (int i = 0; i < copyToGun.objectsToSpawn.Length; i++) + { + list.Add(copyToGun.objectsToSpawn[i]); + } + for (int j = 0; j < copyFromGun.objectsToSpawn.Length; j++) + { + bool flag = false; + for (int k = 0; k < list.Count; k++) + { + if ((bool)list[k].effect && (bool)copyFromGun.objectsToSpawn[j].effect) + { + if (list[k].effect.name == copyFromGun.objectsToSpawn[j].effect.name && list[k].scaleStacks) + { + list[k].stacks++; + flag = true; + } + } + else if ((bool)list[k].AddToProjectile && (bool)copyFromGun.objectsToSpawn[j].AddToProjectile && list[k].AddToProjectile.name == copyFromGun.objectsToSpawn[j].AddToProjectile.name && list[k].scaleStacks) + { + list[k].stacks++; + flag = true; + } + } + if (!flag) + { + list.Add(copyFromGun.objectsToSpawn[j]); + } + } + copyToGun.objectsToSpawn = list.ToArray(); + if (copyFromGun.useCharge) + { + copyToGun.useCharge = copyFromGun.useCharge; + } + copyToGun.soundGun.AddSoundShotModifier(copyFromGun.soundShotModifier); + copyToGun.soundGun.AddSoundImpactModifier(copyFromGun.soundImpactModifier); + copyToGun.soundGun.RefreshSoundModifiers(); + } +} diff --git a/GameCode/ApplyRootScale.cs b/GameCode/ApplyRootScale.cs new file mode 100644 index 0000000..36ef87a --- /dev/null +++ b/GameCode/ApplyRootScale.cs @@ -0,0 +1,11 @@ +using UnityEngine; + +public class ApplyRootScale : MonoBehaviour +{ + public float amount = 0.5f; + + private void Start() + { + base.transform.localScale = Vector3.Lerp(base.transform.localScale, base.transform.root.localScale, amount); + } +} diff --git a/GameCode/ArmRotator.cs b/GameCode/ArmRotator.cs new file mode 100644 index 0000000..a8f02a9 --- /dev/null +++ b/GameCode/ArmRotator.cs @@ -0,0 +1,11 @@ +using UnityEngine; + +public class ArmRotator : MonoBehaviour +{ + public Vector3 rotation; + + private void Start() + { + base.transform.localEulerAngles = rotation; + } +} diff --git a/GameCode/ArtHandler.cs b/GameCode/ArtHandler.cs new file mode 100644 index 0000000..1421de0 --- /dev/null +++ b/GameCode/ArtHandler.cs @@ -0,0 +1,84 @@ +using UnityEngine; +using UnityEngine.Rendering.PostProcessing; + +public class ArtHandler : MonoBehaviour +{ + public ArtInstance[] arts; + + public PostProcessVolume volume; + + public static ArtHandler instance; + + private ColorGrading colorGrading; + + private int currentArt = -1; + + private void Awake() + { + instance = this; + } + + private void Update() + { + if (Input.GetKeyDown(KeyCode.LeftShift)) + { + NextArt(); + } + } + + public void NextArt() + { + for (int i = 0; i < arts.Length; i++) + { + arts[i].TogglePart(on: false); + } + int num = Random.Range(0, arts.Length); + if (num >= arts.Length) + { + num = 0; + } + ApplyArt(arts[num]); + } + + private void ApplyArt(ArtInstance art) + { + art.TogglePart(on: true); + currentArt = GetArtID(art); + volume.profile = art.profile; + } + + public void SetSpecificArt(ArtInstance art) + { + ApplyArt(art); + } + + public void ApplyPost(PostProcessProfile profileToSet) + { + volume.profile = profileToSet; + } + + public void SetSpecificArt(string artName) + { + for (int i = 0; i < arts.Length; i++) + { + if (arts[i].profile.name == artName) + { + ApplyArt(arts[i]); + break; + } + } + } + + private int GetArtID(ArtInstance art) + { + int result = -1; + for (int i = 0; i < arts.Length; i++) + { + if (art == arts[i]) + { + result = i; + } + } + return result; + } +} diff --git a/GameCode/ArtInstance.cs b/GameCode/ArtInstance.cs new file mode 100644 index 0000000..49c24b3 --- /dev/null +++ b/GameCode/ArtInstance.cs @@ -0,0 +1,23 @@ +using System; +using Sirenix.OdinInspector; +using UnityEngine; +using UnityEngine.Rendering.PostProcessing; + +[Serializable] +public class ArtInstance +{ + [FoldoutGroup("$profile", 0)] + public PostProcessProfile profile; + + [FoldoutGroup("$profile", 0)] + public ParticleSystem[] parts; + + public void TogglePart(bool on) + { + for (int i = 0; i < parts.Length; i++) + { + parts[i].gameObject.SetActive(on); + parts[i].Play(); + } + } +} diff --git a/GameCode/AttackLevel.cs b/GameCode/AttackLevel.cs new file mode 100644 index 0000000..78c92dd --- /dev/null +++ b/GameCode/AttackLevel.cs @@ -0,0 +1,53 @@ +using System; +using UnityEngine; + +public class AttackLevel : MonoBehaviour +{ + public int attackLevel = 1; + + public float levelScaleM = 0.7f; + + public Action<int> LevelUpAction; + + private void Start() + { + SpawnedAttack componentInParent = GetComponentInParent<SpawnedAttack>(); + if ((bool)componentInParent) + { + attackLevel = componentInParent.attackLevel; + } + bool flag = false; + AttackLevel[] componentsInChildren = base.transform.root.GetComponentsInChildren<AttackLevel>(); + for (int i = 0; i < componentsInChildren.Length; i++) + { + if (!(componentsInChildren[i] == this) && componentsInChildren[i].gameObject.name == base.gameObject.name) + { + componentsInChildren[i].LevelUp(); + flag = true; + } + } + if (flag) + { + UnityEngine.Object.Destroy(base.gameObject); + } + } + + public float LevelScale() + { + return 1f + ((float)attackLevel - 1f) * levelScaleM; + } + + public int LevelsUp() + { + return attackLevel - 1; + } + + public void LevelUp() + { + attackLevel++; + if (LevelUpAction != null) + { + LevelUpAction(attackLevel); + } + } +} diff --git a/GameCode/AttackTrigger.cs b/GameCode/AttackTrigger.cs new file mode 100644 index 0000000..a452de0 --- /dev/null +++ b/GameCode/AttackTrigger.cs @@ -0,0 +1,43 @@ +using System; +using UnityEngine; +using UnityEngine.Events; + +public class AttackTrigger : MonoBehaviour +{ + public bool triggerOnEveryShot = true; + + public UnityEvent triggerEvent; + + private CharacterData data; + + private void Start() + { + data = GetComponentInParent<CharacterData>(); + Gun gun = data.weaponHandler.gun; + gun.ShootPojectileAction = (Action<GameObject>)Delegate.Combine(gun.ShootPojectileAction, new Action<GameObject>(Shoot)); + data.weaponHandler.gun.AddAttackAction(Attack); + } + + private void OnDestroy() + { + Gun gun = data.weaponHandler.gun; + gun.ShootPojectileAction = (Action<GameObject>)Delegate.Remove(gun.ShootPojectileAction, new Action<GameObject>(Shoot)); + data.weaponHandler.gun.RemoveAttackAction(Attack); + } + + public void Attack() + { + if (!triggerOnEveryShot) + { + triggerEvent.Invoke(); + } + } + + public void Shoot(GameObject projectile) + { + if (triggerOnEveryShot) + { + triggerEvent.Invoke(); + } + } +} diff --git a/GameCode/AudioModifyer.cs b/GameCode/AudioModifyer.cs new file mode 100644 index 0000000..ddfaad9 --- /dev/null +++ b/GameCode/AudioModifyer.cs @@ -0,0 +1,9 @@ +using System; + +[Serializable] +public class AudioModifyer +{ + public CardAudioModifier modifier; + + public int stacks; +} diff --git a/GameCode/Background.cs b/GameCode/Background.cs new file mode 100644 index 0000000..0b694c7 --- /dev/null +++ b/GameCode/Background.cs @@ -0,0 +1,33 @@ +using UnityEngine; + +public class Background : MonoBehaviour +{ + private ParticleSystem[] parts; + + private bool hasBeenInitiated; + + private void Init() + { + parts = GetComponentsInChildren<ParticleSystem>(); + hasBeenInitiated = true; + } + + public void ToggleBackground(bool on) + { + if (!hasBeenInitiated) + { + Init(); + } + for (int i = 0; i < parts.Length; i++) + { + if (on) + { + parts[i].Play(); + } + else + { + parts[i].Stop(); + } + } + } +} diff --git a/GameCode/BackgroundHandler.cs b/GameCode/BackgroundHandler.cs new file mode 100644 index 0000000..90823de --- /dev/null +++ b/GameCode/BackgroundHandler.cs @@ -0,0 +1,39 @@ +using System.Collections; +using UnityEngine; + +public class BackgroundHandler : MonoBehaviour +{ + private Background[] backgrounds; + + private float untilSwitch; + + private void Start() + { + backgrounds = GetComponentsInChildren<Background>(includeInactive: true); + } + + private void Update() + { + untilSwitch -= TimeHandler.deltaTime; + if (untilSwitch < 0f) + { + SwitchBackground(); + } + } + + private void SwitchBackground() + { + untilSwitch = Random.Range(30, 60); + for (int i = 0; i < backgrounds.Length; i++) + { + backgrounds[i].ToggleBackground(on: false); + } + StartCoroutine(StartBackGroundSoon()); + } + + private IEnumerator StartBackGroundSoon() + { + yield return new WaitForSeconds(5f); + backgrounds[Random.Range(0, backgrounds.Length)].ToggleBackground(on: true); + } +} diff --git a/GameCode/BeamAttack.cs b/GameCode/BeamAttack.cs new file mode 100644 index 0000000..a05ee28 --- /dev/null +++ b/GameCode/BeamAttack.cs @@ -0,0 +1,145 @@ +using System.Collections; +using UnityEngine; + +public class BeamAttack : MonoBehaviour +{ + public float selfHeal; + + public float damage = 8f; + + public float force = 2500f; + + public float scalingForce; + + public float overTimeForce; + + public float overTimeScalingForce; + + public float overTimeDrag; + + public float effectOverTimeTime = 0.1f; + + public float interval = 0.2f; + + public float slow; + + public float maxSlow = 1f; + + public Color dmgColor; + + private Player attacker; + + private Player thisPlayer; + + private LineEffect[] lineEffects; + + private ParticleSystem[] parts; + + private CharacterStatModifiers stats; + + private float scaleMultiplier = 1f; + + private SpawnedAttack spawnedAttack; + + private float counter; + + private void Start() + { + lineEffects = GetComponentsInChildren<LineEffect>(includeInactive: true); + parts = GetComponentsInChildren<ParticleSystem>(); + thisPlayer = GetComponentInParent<Player>(); + stats = thisPlayer.GetComponent<CharacterStatModifiers>(); + attacker = PlayerManager.instance.GetOtherPlayer(thisPlayer); + scaleMultiplier = base.transform.localScale.x; + spawnedAttack = GetComponentInParent<SpawnedAttack>(); + if (thisPlayer == spawnedAttack.spawner) + { + Object.Destroy(base.gameObject); + } + } + + private void Update() + { + if (!attacker || !thisPlayer) + { + return; + } + counter += TimeHandler.deltaTime; + if (!(counter > interval)) + { + return; + } + CanSeeInfo canSeeInfo = PlayerManager.instance.CanSeePlayer(attacker.transform.position, thisPlayer); + if (canSeeInfo.canSee) + { + Vector2 vector = thisPlayer.transform.position - attacker.transform.position; + Vector2 normalized = vector.normalized; + if (force != 0f) + { + thisPlayer.data.healthHandler.TakeForce(normalized * scaleMultiplier * force); + } + if (scalingForce != 0f) + { + thisPlayer.data.healthHandler.TakeForce(vector * scaleMultiplier * scalingForce); + } + if (damage != 0f) + { + thisPlayer.data.healthHandler.TakeDamage(damage * scaleMultiplier * normalized, base.transform.position, dmgColor, null, attacker); + } + if (selfHeal != 0f) + { + attacker.data.healthHandler.Heal(selfHeal * scaleMultiplier); + } + for (int i = 0; i < lineEffects.Length; i++) + { + lineEffects[i].Play(attacker.transform, thisPlayer.transform); + } + StartCoroutine(DoOverTimeEffects(attacker)); + if (slow > 0f && (bool)stats) + { + stats.AddSlowAddative(slow * scaleMultiplier, maxSlow); + } + } + else + { + for (int j = 0; j < lineEffects.Length; j++) + { + lineEffects[j].Play(attacker.transform, canSeeInfo.hitPoint); + } + for (int k = 0; k < parts.Length; k++) + { + parts[k].transform.position = canSeeInfo.hitPoint; + parts[k].transform.localScale = Vector3.one * scaleMultiplier; + parts[k].Play(); + } + } + counter = 0f; + } + + private IEnumerator DoOverTimeEffects(Player attacker) + { + float c = 0f; + while (c < effectOverTimeTime) + { + c += TimeHandler.deltaTime; + if ((bool)attacker && (bool)thisPlayer) + { + Vector2 vector = thisPlayer.transform.position - attacker.transform.position; + Vector2 normalized = vector.normalized; + if (overTimeForce != 0f) + { + thisPlayer.data.healthHandler.TakeForce(normalized * scaleMultiplier * TimeHandler.deltaTime * overTimeForce); + } + if (overTimeScalingForce != 0f) + { + thisPlayer.data.healthHandler.TakeForce(vector * scaleMultiplier * TimeHandler.deltaTime * overTimeScalingForce, ForceMode2D.Force); + } + if (overTimeDrag > 0f) + { + thisPlayer.data.playerVel.AddForce(-thisPlayer.data.playerVel.velocity * Mathf.Clamp(TimeHandler.deltaTime * scaleMultiplier * overTimeDrag, 0f, 0.95f), ForceMode2D.Force); + } + } + yield return null; + } + } +} diff --git a/GameCode/BezierCurve.cs b/GameCode/BezierCurve.cs new file mode 100644 index 0000000..5fb99b8 --- /dev/null +++ b/GameCode/BezierCurve.cs @@ -0,0 +1,19 @@ +using UnityEngine; + +public static class BezierCurve +{ + public static Vector3 CubicBezier(Vector3 Start, Vector3 _P1, Vector3 _P2, Vector3 end, float _t) + { + return (1f - _t) * QuadraticBezier(Start, _P1, _P2, _t) + _t * QuadraticBezier(_P1, _P2, end, _t); + } + + public static Vector3 QuadraticBezier(Vector3 start, Vector3 _P1, Vector3 end, float _t) + { + return (1f - _t) * LinearBezier(start, _P1, _t) + _t * LinearBezier(_P1, end, _t); + } + + public static Vector3 LinearBezier(Vector3 start, Vector3 end, float _t) + { + return (1f - _t) * start + _t * end; + } +} diff --git a/GameCode/BlinkStep.cs b/GameCode/BlinkStep.cs new file mode 100644 index 0000000..4a52737 --- /dev/null +++ b/GameCode/BlinkStep.cs @@ -0,0 +1,28 @@ +using UnityEngine; + +public class BlinkStep : MonoBehaviour +{ + public float interval = 0.29f; + + private CharacterData data; + + private float counter; + + private void Start() + { + data = GetComponentInParent<CharacterData>(); + } + + private void Update() + { + if (data.view.IsMine) + { + counter += TimeHandler.deltaTime; + if (counter > interval) + { + counter = 0f; + data.block.CallDoBlock(firstBlock: true, dontSetCD: true); + } + } + } +} diff --git a/GameCode/Block.cs b/GameCode/Block.cs new file mode 100644 index 0000000..b48d264 --- /dev/null +++ b/GameCode/Block.cs @@ -0,0 +1,353 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using Photon.Pun; +using Sonigon; +using UnityEngine; + +public class Block : MonoBehaviour +{ + [Header("Sounds")] + public SoundEvent soundBlockStart; + + public SoundEvent soundBlockRecharged; + + public SoundEvent soundBlockBlocked; + + public SoundEvent soundBlockStatusEffect; + + [Header("Settings")] + public List<GameObject> objectsToSpawn = new List<GameObject>(); + + public float sinceBlock; + + private GeneralInput input; + + public ParticleSystem particle; + + public ParticleSystem reloadParticle; + + public ParticleSystem blockedPart; + + public float cooldown; + + public float counter = 1000f; + + public float cdMultiplier = 1f; + + public float cdAdd; + + public float forceToAdd; + + public float forceToAddUp; + + public bool autoBlock; + + public bool blockedThisFrame; + + public int additionalBlocks; + + public float healing; + + private float timeBetweenBlocks = 0.2f; + + private CharacterData data; + + private HealthHandler health; + + private bool active = true; + + public Action BlockRechargeAction; + + private bool blockedLastFrame; + + public Action<BlockTrigger.BlockTriggerType> BlockAction; + + public Action<BlockTrigger.BlockTriggerType> BlockActionEarly; + + public Action<BlockTrigger.BlockTriggerType> FirstBlockActionThatDelaysOthers; + + public Action<BlockTrigger.BlockTriggerType> SuperFirstBlockAction; + + public Vector3 blockedAtPos; + + public bool delayOtherActions; + + public ParticleSystem statusBlockPart; + + private float lastStatusBlock; + + public Action<GameObject, Vector3, Vector3> BlockProjectileAction; + + public float Cooldown() + { + return (cooldown + cdAdd) * cdMultiplier; + } + + private void Start() + { + input = GetComponent<GeneralInput>(); + data = GetComponent<CharacterData>(); + health = GetComponent<HealthHandler>(); + sinceBlock = 100f; + } + + private void Update() + { + if ((bool)input && data.playerVel.simulated) + { + if (!blockedLastFrame) + { + blockedThisFrame = false; + } + blockedLastFrame = false; + sinceBlock += TimeHandler.deltaTime; + counter += TimeHandler.deltaTime; + if (counter > Cooldown() && !active) + { + active = true; + reloadParticle.Play(); + BlockRechargeAction(); + SoundManager.Instance.Play(soundBlockRecharged, base.transform); + } + if (input.shieldWasPressed) + { + TryBlock(); + } + } + } + + public void DoBlockAtPosition(bool firstBlock, bool dontSetCD = false, BlockTrigger.BlockTriggerType triggerType = BlockTrigger.BlockTriggerType.Default, Vector3 blockPos = default(Vector3), bool onlyBlockEffects = false) + { + blockedAtPos = blockPos; + RPCA_DoBlock(firstBlock, dontSetCD, triggerType, blockPos, onlyBlockEffects); + } + + internal void ResetStats() + { + objectsToSpawn = new List<GameObject>(); + sinceBlock = 10f; + cooldown = 4f; + counter = 1000f; + cdMultiplier = 1f; + cdAdd = 0f; + forceToAdd = 0f; + forceToAddUp = 0f; + autoBlock = false; + blockedThisFrame = false; + additionalBlocks = 0; + healing = 0f; + delayOtherActions = false; + } + + public void CallDoBlock(bool firstBlock, bool dontSetCD = false, BlockTrigger.BlockTriggerType triggerType = BlockTrigger.BlockTriggerType.Default, Vector3 useBlockPos = default(Vector3), bool onlyBlockEffects = false) + { + data.view.RPC("RPCA_DoBlock", RpcTarget.All, firstBlock, dontSetCD, (int)triggerType, useBlockPos, onlyBlockEffects); + } + + [PunRPC] + public void RPCA_DoBlock(bool firstBlock, bool dontSetCD = false, BlockTrigger.BlockTriggerType triggerType = BlockTrigger.BlockTriggerType.Default, Vector3 useBlockPos = default(Vector3), bool onlyBlockEffects = false) + { + if (triggerType == BlockTrigger.BlockTriggerType.Default && firstBlock) + { + for (int i = 0; i < additionalBlocks; i++) + { + StartCoroutine(DelayBlock(((float)i + 1f) * timeBetweenBlocks)); + } + } + StartCoroutine(IDoBlock(firstBlock, dontSetCD, triggerType, useBlockPos, onlyBlockEffects)); + } + + private IEnumerator IDoBlock(bool firstBlock, bool dontSetCD = false, BlockTrigger.BlockTriggerType triggerType = BlockTrigger.BlockTriggerType.Default, Vector3 useBlockPos = default(Vector3), bool onlyBlockEffects = false) + { + active = false; + Vector3 position = base.transform.position; + if (useBlockPos != Vector3.zero) + { + base.transform.position = useBlockPos; + } + if (SuperFirstBlockAction != null) + { + SuperFirstBlockAction(triggerType); + } + if (FirstBlockActionThatDelaysOthers != null) + { + FirstBlockActionThatDelaysOthers(triggerType); + } + if (useBlockPos != Vector3.zero) + { + base.transform.position = position; + } + if (!onlyBlockEffects) + { + sinceBlock = 0f; + } + if (delayOtherActions) + { + yield return new WaitForSeconds(0.2f); + } + position = base.transform.position; + if (useBlockPos != Vector3.zero) + { + base.transform.position = useBlockPos; + } + if (BlockActionEarly != null) + { + BlockActionEarly(triggerType); + } + if (BlockAction != null) + { + BlockAction(triggerType); + } + if (firstBlock) + { + if (forceToAdd != 0f) + { + health.TakeForce(data.hand.transform.forward * forceToAdd * data.playerVel.mass * 0.01f); + } + if (forceToAddUp != 0f) + { + health.TakeForce(Vector3.up * forceToAddUp * data.playerVel.mass * 0.01f); + } + } + blockedLastFrame = true; + bool flag = false; + for (int i = 0; i < data.currentCards.Count; i++) + { + if (data.currentCards[i].soundDisableBlockBasic) + { + flag = true; + break; + } + } + if (!flag && triggerType != BlockTrigger.BlockTriggerType.ShieldCharge) + { + SoundManager.Instance.Play(soundBlockStart, base.transform); + } + if (!onlyBlockEffects) + { + particle.Play(); + } + if (!dontSetCD) + { + counter = 0f; + } + GamefeelManager.GameFeel(UnityEngine.Random.insideUnitCircle.normalized * 1f); + if (!onlyBlockEffects) + { + sinceBlock = 0f; + } + Spawn(); + health.Heal(healing); + if (useBlockPos != Vector3.zero) + { + base.transform.position = position; + } + } + + public void ShowStatusEffectBlock() + { + if (!(Time.unscaledTime < lastStatusBlock + 0.25f) && data.view.IsMine) + { + lastStatusBlock = Time.unscaledTime; + data.view.RPC("RPCA_ShowStatusEffectBlock", RpcTarget.All); + } + } + + [PunRPC] + public void RPCA_ShowStatusEffectBlock() + { + SoundManager.Instance.Play(soundBlockStatusEffect, base.transform); + statusBlockPart.Play(); + } + + public void TryBlock() + { + if (!(counter < Cooldown())) + { + RPCA_DoBlock(firstBlock: true); + counter = 0f; + } + } + + private IEnumerator DelayBlock(float t) + { + yield return new WaitForSeconds(t); + yield return new WaitForEndOfFrame(); + RPCA_DoBlock(firstBlock: false, dontSetCD: true, BlockTrigger.BlockTriggerType.Echo); + } + + public void Spawn() + { + for (int i = 0; i < objectsToSpawn.Count; i++) + { + SpawnedAttack component = UnityEngine.Object.Instantiate(objectsToSpawn[i], base.transform.position, Quaternion.identity).GetComponent<SpawnedAttack>(); + if ((bool)component) + { + component.spawner = GetComponent<Player>(); + } + } + } + + public void blocked(GameObject projectile, Vector3 forward, Vector3 hitPos) + { + SoundManager.Instance.Play(soundBlockBlocked, base.transform); + projectile.GetComponent<ProjectileHit>().RemoveOwnPlayerFromPlayersHit(); + projectile.GetComponent<ProjectileHit>().AddPlayerToHeld(GetComponent<HealthHandler>()); + projectile.GetComponent<MoveTransform>().velocity *= -1f; + projectile.GetComponent<RayCastTrail>().WasBlocked(); + blockedPart.transform.position = hitPos + base.transform.forward * 5f; + blockedPart.transform.rotation = Quaternion.LookRotation(-forward * 1.5f); + GamefeelManager.GameFeel(forward); + blockedPart.Play(); + SpawnedAttack componentInParent = projectile.GetComponentInParent<SpawnedAttack>(); + if ((!componentInParent || !(componentInParent.spawner.gameObject == base.transform.root.gameObject)) && BlockProjectileAction != null) + { + BlockProjectileAction(projectile, forward, hitPos); + } + } + + public void ResetCD(bool soundPlay) + { + active = true; + reloadParticle.Play(); + counter = Cooldown() + 1f; + if (soundPlay) + { + SoundManager.Instance.Play(soundBlockRecharged, base.transform); + } + } + + public bool TryBlockMe(GameObject toBlock, Vector3 forward, Vector3 hitPos) + { + if (sinceBlock < 0.3f) + { + blocked(toBlock, forward, hitPos); + sinceBlock = 0f; + particle.Play(); + return true; + } + return false; + } + + public void DoBlock(GameObject toBlock, Vector3 forward, Vector3 hitPos) + { + sinceBlock = 0f; + blocked(toBlock, forward, hitPos); + particle.Play(); + } + + public bool IsBlocking() + { + if (sinceBlock < 0.3f) + { + ShowStatusEffectBlock(); + } + return sinceBlock < 0.3f; + } + + public bool IsOnCD() + { + return counter < Cooldown(); + } +} diff --git a/GameCode/BlockEffect.cs b/GameCode/BlockEffect.cs new file mode 100644 index 0000000..3cc771c --- /dev/null +++ b/GameCode/BlockEffect.cs @@ -0,0 +1,6 @@ +using UnityEngine; + +public abstract class BlockEffect : MonoBehaviour +{ + public abstract void DoBlockedProjectile(GameObject projectile, Vector3 forward, Vector3 hitPos); +} diff --git a/GameCode/BlockEffectCounter.cs b/GameCode/BlockEffectCounter.cs new file mode 100644 index 0000000..56c7e39 --- /dev/null +++ b/GameCode/BlockEffectCounter.cs @@ -0,0 +1,21 @@ +using UnityEngine; + +public class BlockEffectCounter : BlockEffect +{ + public int ownAttacksToSendBack; + + private SpawnObjectEffect spawn; + + private void Start() + { + spawn = GetComponentInParent<SpawnObjectEffect>(); + } + + public override void DoBlockedProjectile(GameObject projectile, Vector3 forward, Vector3 hitPos) + { + for (int i = 0; i < ownAttacksToSendBack; i++) + { + spawn.DoEffect(forward); + } + } +} diff --git a/GameCode/BlockRechargeUI.cs b/GameCode/BlockRechargeUI.cs new file mode 100644 index 0000000..d2ad92a --- /dev/null +++ b/GameCode/BlockRechargeUI.cs @@ -0,0 +1,20 @@ +using UnityEngine; +using UnityEngine.UI; + +public class BlockRechargeUI : MonoBehaviour +{ + private Block block; + + private Image img; + + private void Start() + { + img = GetComponentInChildren<Image>(); + block = GetComponentInParent<Block>(); + } + + private void Update() + { + img.fillAmount = block.counter / block.Cooldown(); + } +} diff --git a/GameCode/BlockTrigger.cs b/GameCode/BlockTrigger.cs new file mode 100644 index 0000000..604c466 --- /dev/null +++ b/GameCode/BlockTrigger.cs @@ -0,0 +1,140 @@ +using System; +using UnityEngine; +using UnityEngine.Events; + +public class BlockTrigger : MonoBehaviour +{ + public enum BlockTriggerType + { + Default, + None, + ShieldCharge, + Echo, + Empower + } + + public UnityEvent triggerEvent; + + public UnityEvent triggerEventEarly; + + public bool delayOtherActions; + + public UnityEvent triggerFirstBlockThatDelaysOthers; + + public UnityEvent triggerSuperFirstBlock; + + public UnityEvent successfulBlockEvent; + + public UnityEvent blockRechargeEvent; + + private BlockEffect[] effects; + + public float cooldown; + + private float lastTriggerTime = -5f; + + public BlockTriggerType blackListedType = BlockTriggerType.None; + + public float cooldownSuccess; + + private float lastTriggerTimeSuccessful = -5f; + + private void Start() + { + effects = GetComponents<BlockEffect>(); + Block componentInParent = GetComponentInParent<Block>(); + componentInParent.SuperFirstBlockAction = (Action<BlockTriggerType>)Delegate.Combine(componentInParent.SuperFirstBlockAction, new Action<BlockTriggerType>(DoSuperFirstBlock)); + componentInParent.FirstBlockActionThatDelaysOthers = (Action<BlockTriggerType>)Delegate.Combine(componentInParent.FirstBlockActionThatDelaysOthers, new Action<BlockTriggerType>(DoFirstBlockThatDelaysOthers)); + componentInParent.BlockAction = (Action<BlockTriggerType>)Delegate.Combine(componentInParent.BlockAction, new Action<BlockTriggerType>(DoBlock)); + componentInParent.BlockActionEarly = (Action<BlockTriggerType>)Delegate.Combine(componentInParent.BlockActionEarly, new Action<BlockTriggerType>(DoBlockEarly)); + componentInParent.BlockProjectileAction = (Action<GameObject, Vector3, Vector3>)Delegate.Combine(componentInParent.BlockProjectileAction, new Action<GameObject, Vector3, Vector3>(DoBlockedProjectile)); + componentInParent.BlockRechargeAction = (Action)Delegate.Combine(componentInParent.BlockRechargeAction, new Action(DoBlockRecharge)); + if (delayOtherActions) + { + GetComponentInParent<Block>().delayOtherActions = true; + } + } + + private void OnDestroy() + { + Block componentInParent = GetComponentInParent<Block>(); + if ((bool)componentInParent && componentInParent.SuperFirstBlockAction != null) + { + componentInParent.SuperFirstBlockAction = (Action<BlockTriggerType>)Delegate.Remove(componentInParent.SuperFirstBlockAction, new Action<BlockTriggerType>(DoSuperFirstBlock)); + } + if ((bool)componentInParent && componentInParent.FirstBlockActionThatDelaysOthers != null) + { + componentInParent.FirstBlockActionThatDelaysOthers = (Action<BlockTriggerType>)Delegate.Remove(componentInParent.FirstBlockActionThatDelaysOthers, new Action<BlockTriggerType>(DoFirstBlockThatDelaysOthers)); + } + if ((bool)componentInParent && componentInParent.BlockAction != null) + { + componentInParent.BlockAction = (Action<BlockTriggerType>)Delegate.Remove(componentInParent.BlockAction, new Action<BlockTriggerType>(DoBlock)); + } + if ((bool)componentInParent && componentInParent.BlockActionEarly != null) + { + componentInParent.BlockActionEarly = (Action<BlockTriggerType>)Delegate.Remove(componentInParent.BlockActionEarly, new Action<BlockTriggerType>(DoBlockEarly)); + } + if ((bool)componentInParent && componentInParent.BlockProjectileAction != null) + { + componentInParent.BlockProjectileAction = (Action<GameObject, Vector3, Vector3>)Delegate.Remove(componentInParent.BlockProjectileAction, new Action<GameObject, Vector3, Vector3>(DoBlockedProjectile)); + } + if ((bool)componentInParent && componentInParent.BlockRechargeAction != null) + { + componentInParent.BlockRechargeAction = (Action)Delegate.Remove(componentInParent.BlockRechargeAction, new Action(DoBlockRecharge)); + } + } + + public void DoSuperFirstBlock(BlockTriggerType triggerType) + { + if (triggerType != blackListedType && !(lastTriggerTime + cooldown > Time.time)) + { + lastTriggerTime = Time.time; + triggerSuperFirstBlock.Invoke(); + } + } + + public void DoFirstBlockThatDelaysOthers(BlockTriggerType triggerType) + { + if (triggerType != blackListedType && !(lastTriggerTime + cooldown > Time.time)) + { + lastTriggerTime = Time.time; + triggerFirstBlockThatDelaysOthers.Invoke(); + } + } + + public void DoBlockEarly(BlockTriggerType triggerType) + { + if (triggerType != blackListedType && !(lastTriggerTime + cooldown > Time.time)) + { + lastTriggerTime = Time.time; + triggerEventEarly.Invoke(); + } + } + + public void DoBlock(BlockTriggerType triggerType) + { + if (triggerType != blackListedType && !(lastTriggerTime + cooldown > Time.time)) + { + lastTriggerTime = Time.time; + triggerEvent.Invoke(); + } + } + + public void DoBlockedProjectile(GameObject projectile, Vector3 forward, Vector3 hitPos) + { + if (!(lastTriggerTimeSuccessful + cooldownSuccess > Time.time)) + { + lastTriggerTimeSuccessful = Time.time; + successfulBlockEvent.Invoke(); + for (int i = 0; i < effects.Length; i++) + { + effects[i].DoBlockedProjectile(projectile, forward, hitPos); + } + } + } + + public void DoBlockRecharge() + { + blockRechargeEvent.Invoke(); + } +} diff --git a/GameCode/BlurPost.cs b/GameCode/BlurPost.cs new file mode 100644 index 0000000..1e10746 --- /dev/null +++ b/GameCode/BlurPost.cs @@ -0,0 +1,16 @@ +using UnityEngine; + +[ExecuteInEditMode] +public class BlurPost : MonoBehaviour +{ + [SerializeField] + private Material postprocessMaterial; + + private void OnRenderImage(RenderTexture source, RenderTexture destination) + { + RenderTexture temporary = RenderTexture.GetTemporary(source.width, source.height); + Graphics.Blit(source, temporary, postprocessMaterial, 0); + Graphics.Blit(temporary, destination, postprocessMaterial, 1); + RenderTexture.ReleaseTemporary(temporary); + } +} diff --git a/GameCode/BounceEffect.cs b/GameCode/BounceEffect.cs new file mode 100644 index 0000000..ff98414 --- /dev/null +++ b/GameCode/BounceEffect.cs @@ -0,0 +1,6 @@ +using UnityEngine; + +public abstract class BounceEffect : MonoBehaviour +{ + public abstract void DoBounce(HitInfo hit); +} diff --git a/GameCode/BounceEffectRetarget.cs b/GameCode/BounceEffectRetarget.cs new file mode 100644 index 0000000..8e1ef79 --- /dev/null +++ b/GameCode/BounceEffectRetarget.cs @@ -0,0 +1,103 @@ +using System.Collections; +using Photon.Pun; +using Sonigon; +using UnityEngine; + +public class BounceEffectRetarget : BounceEffect +{ + [Header("Sound")] + public SoundEvent soundTargetBounceTargetPlayer; + + private MoveTransform move; + + private PhotonView view; + + private void Start() + { + view = GetComponentInParent<PhotonView>(); + move = GetComponentInParent<MoveTransform>(); + GetComponentInParent<ChildRPC>().childRPCsVector2.Add("TargetBounce", SetNewVel); + GetComponentInParent<ChildRPC>().childRPCsInt.Add("TargetBounceLine", DrawLineTo); + } + + public override void DoBounce(HitInfo hit) + { + StartCoroutine(DelayMove(hit)); + } + + private void ActuallyDoBounce(int playerId) + { + Player playerWithID = PlayerManager.instance.GetPlayerWithID(playerId); + if ((bool)playerWithID) + { + GetComponentInParent<ChildRPC>().CallFunction("TargetBounce", (playerWithID.data.playerVel.position + Vector2.up * move.GetUpwardsCompensation(base.transform.position, playerWithID.data.playerVel.position) - (Vector2)base.transform.position).normalized * move.velocity.magnitude); + SoundManager.Instance.PlayAtPosition(soundTargetBounceTargetPlayer, SoundManager.Instance.GetTransform(), base.transform); + } + else + { + GetComponentInParent<ChildRPC>().CallFunction("TargetBounce", move.velocity); + } + } + + private void SetNewVel(Vector2 newVel) + { + move.enabled = true; + move.velocity = newVel; + } + + private Player FindTarget(HitInfo hit) + { + Player closestPlayer = PlayerManager.instance.GetClosestPlayer(base.transform.position + (Vector3)hit.normal * 0.1f); + if (PlayerManager.instance.CanSeePlayer(base.transform.position, closestPlayer).canSee) + { + return closestPlayer; + } + return null; + } + + private IEnumerator DelayMove(HitInfo hit) + { + Player p = FindTarget(hit); + if ((bool)p && view.IsMine) + { + GetComponentInParent<ChildRPC>().CallFunction("TargetBounceLine", p.playerID); + } + move.enabled = false; + if ((bool)hit.rigidbody) + { + move.GetComponent<RayCastTrail>().IgnoreRigFor(hit.rigidbody, 0.5f); + } + yield return new WaitForSeconds(0.1f); + if (view.IsMine) + { + if ((bool)p) + { + ActuallyDoBounce(p.playerID); + } + else + { + ActuallyDoBounce(-1); + } + } + } + + private void DrawLineTo(int playerID) + { + Player playerWithID = PlayerManager.instance.GetPlayerWithID(playerID); + if ((bool)playerWithID) + { + StartCoroutine(DrawLine(playerWithID.transform)); + } + } + + private IEnumerator DrawLine(Transform target) + { + LineEffect line = GetComponentInChildren<LineEffect>(includeInactive: true); + line.StartDraw(); + while ((bool)line) + { + line.DrawLine(base.transform.position, target.position); + yield return null; + } + } +} diff --git a/GameCode/BounceTrigger.cs b/GameCode/BounceTrigger.cs new file mode 100644 index 0000000..8d7a1b5 --- /dev/null +++ b/GameCode/BounceTrigger.cs @@ -0,0 +1,22 @@ +using System; +using UnityEngine; + +public class BounceTrigger : MonoBehaviour +{ + private BounceEffect[] bounceEffects; + + private void Start() + { + bounceEffects = GetComponents<BounceEffect>(); + RayHitReflect componentInParent = GetComponentInParent<RayHitReflect>(); + componentInParent.reflectAction = (Action<HitInfo>)Delegate.Combine(componentInParent.reflectAction, new Action<HitInfo>(Reflect)); + } + + public void Reflect(HitInfo hit) + { + for (int i = 0; i < bounceEffects.Length; i++) + { + bounceEffects[i].DoBounce(hit); + } + } +} diff --git a/GameCode/BrodalAIController.cs b/GameCode/BrodalAIController.cs new file mode 100644 index 0000000..1d0d60f --- /dev/null +++ b/GameCode/BrodalAIController.cs @@ -0,0 +1,164 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +public class BrodalAIController : MonoBehaviour +{ + private PlayerAPI m_playerAPI; + + private int m_sampleCount = 250; + + private float m_sampleSize; + + private LayerMask m_layerMask; + + private Dictionary<Guid, Platform> m_platforms = new Dictionary<Guid, Platform>(); + + private Platform m_currentPlatform; + + private Vector2 m_pointOnLine; + + private bool inited; + + private void Start() + { + m_playerAPI = GetComponentInParent<PlayerAPI>(); + HealthHandler healthHandler = m_playerAPI.player.data.healthHandler; + healthHandler.delayedReviveAction = (Action)Delegate.Combine(healthHandler.delayedReviveAction, new Action(Init)); + } + + public void Init() + { + m_platforms.Clear(); + m_currentPlatform = null; + PlotPlatforms(); + RaycastMap(); + PostProcessPlatforms(); + inited = true; + Debug.Log("Revived"); + } + + private void PostProcessPlatforms() + { + foreach (KeyValuePair<Guid, Platform> platform in m_platforms) + { + platform.Value.PostProcessPlatformPoints(); + } + } + + private void PlotPlatforms() + { + BoxCollider2D[] array = UnityEngine.Object.FindObjectsOfType<BoxCollider2D>(); + foreach (BoxCollider2D boxCollider2D in array) + { + if (boxCollider2D.gameObject.layer == LayerMask.GetMask("Player")) + { + continue; + } + bool flag = false; + foreach (KeyValuePair<Guid, Platform> platform in m_platforms) + { + foreach (BoxCollider2D boxCollider in platform.Value.BoxColliders) + { + bool flag2 = false; + if (boxCollider2D.bounds.Intersects(boxCollider.bounds)) + { + flag2 = true; + } + if (flag2) + { + m_platforms[platform.Key].AddCollider(boxCollider2D); + flag = true; + break; + } + } + if (flag) + { + break; + } + } + if (!flag) + { + Guid key = Guid.NewGuid(); + m_platforms.Add(key, new Platform()); + m_platforms[key].AddCollider(boxCollider2D); + } + } + } + + private void MergePlatforms() + { + } + + private void RaycastMap() + { + m_layerMask = LayerMask.GetMask("Default"); + Camera component = MainCam.instance.transform.GetComponent<Camera>(); + Vector3 vector = component.ViewportToWorldPoint(new Vector2(0f, 1f)); + Vector3 vector2 = component.ViewportToWorldPoint(new Vector2(1f, 1f)); + m_sampleSize = (vector2.x - vector.x) / (float)m_sampleCount; + for (float num = vector.x; num < vector2.x; num += m_sampleSize) + { + RaycastHit2D[] array = Physics2D.RaycastAll(new Vector3(num, vector.y, 0f), Vector2.down, 9999f, m_layerMask); + for (int i = 0; i < array.Length; i++) + { + RaycastHit2D raycastHit2D = array[i]; + foreach (KeyValuePair<Guid, Platform> platform in m_platforms) + { + if (platform.Value.ContainsCollider((BoxCollider2D)raycastHit2D.collider)) + { + m_platforms[platform.Key].AddPlatformPoint(raycastHit2D.point); + break; + } + } + } + } + } + + private void Update() + { + if (inited) + { + FindClosestPlatform(base.transform.position); + Vector2 vector = m_playerAPI.OtherPlayerPosition() - base.transform.position; + float magnitude = vector.magnitude; + vector.Normalize(); + Vector2 normalized = (vector + new Vector2(0f, 0.15f)).normalized; + m_playerAPI.SetAimDirection(normalized); + Vector2 position = new Vector2(base.transform.position.x, base.transform.position.y) + vector * 1.5f; + bool num = m_currentPlatform.IsPositionOutsidePlatform(position); + m_playerAPI.Move(m_playerAPI.TowardsOtherPlayer()); + if (num) + { + m_playerAPI.Jump(); + } + vector.y = 0f; + vector.Normalize(); + RaycastHit2D raycastHit2D = Physics2D.Raycast(base.transform.position, vector, 0.85f, m_layerMask); + RaycastHit2D raycastHit2D2 = Physics2D.Raycast(base.transform.position, vector, magnitude, m_layerMask); + if ((bool)raycastHit2D.collider) + { + m_playerAPI.Jump(); + } + if (raycastHit2D2.collider == null) + { + m_playerAPI.Attack(); + } + m_playerAPI.Block(); + } + } + + private void FindClosestPlatform(Vector2 position) + { + float num = float.MaxValue; + foreach (KeyValuePair<Guid, Platform> platform in m_platforms) + { + float closestDistance = platform.Value.GetClosestDistance(position); + if (closestDistance < num) + { + m_currentPlatform = platform.Value; + num = closestDistance; + } + } + } +} diff --git a/GameCode/BuildOnly.cs b/GameCode/BuildOnly.cs new file mode 100644 index 0000000..48988a5 --- /dev/null +++ b/GameCode/BuildOnly.cs @@ -0,0 +1,12 @@ +using UnityEngine; + +public class BuildOnly : MonoBehaviour +{ + private void Start() + { + if (Application.isEditor) + { + base.gameObject.SetActive(value: false); + } + } +} diff --git a/GameCode/BulletBase.cs b/GameCode/BulletBase.cs new file mode 100644 index 0000000..446970a --- /dev/null +++ b/GameCode/BulletBase.cs @@ -0,0 +1,12 @@ +using UnityEngine; + +public class BulletBase : MonoBehaviour +{ + private void Start() + { + } + + private void Update() + { + } +} diff --git a/GameCode/BulletDamageEvents.cs b/GameCode/BulletDamageEvents.cs new file mode 100644 index 0000000..09dae56 --- /dev/null +++ b/GameCode/BulletDamageEvents.cs @@ -0,0 +1,18 @@ +using UnityEngine; + +public class BulletDamageEvents : MonoBehaviour +{ + public DmgEvent[] damageEvents; + + public void Start() + { + ProjectileHit componentInParent = GetComponentInParent<ProjectileHit>(); + for (int i = 0; i < damageEvents.Length; i++) + { + if (componentInParent.damage > damageEvents[i].dmg) + { + damageEvents[i].eventToCall.Invoke(); + } + } + } +} diff --git a/GameCode/BulletPoint.cs b/GameCode/BulletPoint.cs new file mode 100644 index 0000000..d7a9157 --- /dev/null +++ b/GameCode/BulletPoint.cs @@ -0,0 +1,56 @@ +using System; +using UnityEngine; + +public class BulletPoint : MonoBehaviour +{ + public LayerMask mask; + + private Gun gun; + + private MoveTransform move; + + private ProjectileHit hit; + + private float counter = 5f; + + private void Start() + { + gun = GetComponent<Gun>(); + Gun obj = gun; + obj.ShootPojectileAction = (Action<GameObject>)Delegate.Combine(obj.ShootPojectileAction, new Action<GameObject>(Fire)); + } + + private void Attack() + { + gun.Attack(1f, forceAttack: true); + } + + private void Fire(GameObject projectile) + { + move = projectile.GetComponent<MoveTransform>(); + } + + private void Update() + { + if ((bool)move) + { + counter = 0f; + Vector3 vector = base.transform.position - base.transform.root.position; + RaycastHit2D raycastHit2D = Physics2D.Raycast(base.transform.root.position, vector, vector.magnitude, mask, -10000f); + Vector3 vector2 = base.transform.position; + if (raycastHit2D.transform != null) + { + vector2 = raycastHit2D.point - (Vector2)vector.normalized * 0.1f; + } + move.velocity = Vector2.Lerp(move.velocity, (vector2 - move.transform.position) * 50f, TimeHandler.deltaTime * 50f); + } + else + { + counter += TimeHandler.deltaTime; + if (counter > 2f) + { + Attack(); + } + } + } +} diff --git a/GameCode/BulletSurf.cs b/GameCode/BulletSurf.cs new file mode 100644 index 0000000..23579ee --- /dev/null +++ b/GameCode/BulletSurf.cs @@ -0,0 +1,12 @@ +using UnityEngine; + +public class BulletSurf : MonoBehaviour +{ + private void Start() + { + } + + private void Update() + { + } +} diff --git a/GameCode/BulletWrapper.cs b/GameCode/BulletWrapper.cs new file mode 100644 index 0000000..1229787 --- /dev/null +++ b/GameCode/BulletWrapper.cs @@ -0,0 +1,12 @@ +using UnityEngine; + +public class BulletWrapper +{ + public float damage; + + public Vector2 velocity; + + public ProjectileHit projectileHit; + + public MoveTransform projectileMovement; +} diff --git a/GameCode/CameraZoomHandler.cs b/GameCode/CameraZoomHandler.cs new file mode 100644 index 0000000..56c8b86 --- /dev/null +++ b/GameCode/CameraZoomHandler.cs @@ -0,0 +1,24 @@ +using UnityEngine; + +public class CameraZoomHandler : MonoBehaviour +{ + private Camera[] cameras; + + private void Start() + { + cameras = GetComponentsInChildren<Camera>(); + } + + private void Update() + { + float b = 20f; + if (MapManager.instance.currentMap != null) + { + b = MapManager.instance.currentMap.Map.size; + } + for (int i = 0; i < cameras.Length; i++) + { + cameras[i].orthographicSize = Mathf.Lerp(cameras[i].orthographicSize, b, Time.unscaledDeltaTime * 5f); + } + } +} diff --git a/GameCode/CanSeeInfo.cs b/GameCode/CanSeeInfo.cs new file mode 100644 index 0000000..947131d --- /dev/null +++ b/GameCode/CanSeeInfo.cs @@ -0,0 +1,10 @@ +using UnityEngine; + +public class CanSeeInfo +{ + public bool canSee; + + public Vector2 hitPoint; + + public float distance; +} diff --git a/GameCode/CapScale.cs b/GameCode/CapScale.cs new file mode 100644 index 0000000..bcb62a0 --- /dev/null +++ b/GameCode/CapScale.cs @@ -0,0 +1,20 @@ +using UnityEngine; + +public class CapScale : MonoBehaviour +{ + public float min = 2f; + + public float max = 10f; + + private void Start() + { + if (base.transform.localScale.x < min) + { + base.transform.localScale = Vector3.one * min; + } + if (base.transform.localScale.x > max) + { + base.transform.localScale = Vector3.one * max; + } + } +} diff --git a/GameCode/CappedDeltaTime.cs b/GameCode/CappedDeltaTime.cs new file mode 100644 index 0000000..8bb24c6 --- /dev/null +++ b/GameCode/CappedDeltaTime.cs @@ -0,0 +1,11 @@ +using UnityEngine; + +public class CappedDeltaTime : MonoBehaviour +{ + public static float time; + + private void Update() + { + time = Mathf.Clamp(TimeHandler.deltaTime, 0f, 0.02f); + } +} diff --git a/GameCode/CardAnimation.cs b/GameCode/CardAnimation.cs new file mode 100644 index 0000000..3578ec6 --- /dev/null +++ b/GameCode/CardAnimation.cs @@ -0,0 +1,5 @@ +using UnityEngine; + +public class CardAnimation : MonoBehaviour +{ +} diff --git a/GameCode/CardAudioModifier.cs b/GameCode/CardAudioModifier.cs new file mode 100644 index 0000000..f6206c0 --- /dev/null +++ b/GameCode/CardAudioModifier.cs @@ -0,0 +1,14 @@ +using UnityEngine; + +public class CardAudioModifier : MonoBehaviour +{ + public enum StackType + { + RTPCValue, + PostEvent + } + + public string stackName; + + public StackType stackType; +} diff --git a/GameCode/CardBar.cs b/GameCode/CardBar.cs new file mode 100644 index 0000000..e985288 --- /dev/null +++ b/GameCode/CardBar.cs @@ -0,0 +1,95 @@ +using Sonigon; +using TMPro; +using UnityEngine; +using UnityEngine.UI; + +public class CardBar : MonoBehaviour +{ + [Header("Sounds")] + public SoundEvent soundCardPick; + + [Header("Settings")] + public GameObject pointer; + + [Header("Settings")] + public GameObject cardPos; + + private GameObject source; + + private CardInfo ci; + + private GameObject currentCard; + + private void Start() + { + source = base.transform.GetChild(0).gameObject; + } + + public void ClearBar() + { + if ((bool)currentCard) + { + Object.Destroy(currentCard); + } + for (int num = base.transform.childCount - 1; num >= 0; num--) + { + if (base.transform.GetChild(num).gameObject.activeSelf) + { + Object.Destroy(base.transform.GetChild(num).gameObject); + } + } + } + + public void AddCard(CardInfo card) + { + SoundManager.Instance.Play(soundCardPick, base.transform); + ci = card; + GameObject obj = Object.Instantiate(source, source.transform.position, source.transform.rotation, source.transform.parent); + obj.transform.localScale = Vector3.one; + string cardName = card.cardName; + cardName = cardName.Substring(0, 2); + string text = cardName[0].ToString().ToUpper(); + if (cardName.Length > 1) + { + string text2 = cardName[1].ToString().ToLower(); + cardName = text + text2; + } + else + { + cardName = text; + } + obj.GetComponentInChildren<TextMeshProUGUI>().text = cardName; + obj.GetComponent<CardBarButton>().card = card; + obj.gameObject.SetActive(value: true); + } + + public void OnHover(CardInfo card, Vector3 hoverPos) + { + if ((bool)currentCard) + { + Object.Destroy(currentCard); + } + currentCard = CardChoice.instance.AddCardVisual(card, cardPos.transform.position); + Collider2D[] componentsInChildren = currentCard.transform.root.GetComponentsInChildren<Collider2D>(); + for (int i = 0; i < componentsInChildren.Length; i++) + { + componentsInChildren[i].enabled = false; + } + currentCard.GetComponentInChildren<Canvas>().sortingLayerName = "MostFront"; + currentCard.GetComponentInChildren<GraphicRaycaster>().enabled = false; + currentCard.GetComponentInChildren<SetScaleToZero>().enabled = false; + currentCard.GetComponentInChildren<SetScaleToZero>().transform.localScale = Vector3.one * 1.15f; + } + + public void StopHover() + { + if ((bool)currentCard) + { + Object.Destroy(currentCard); + } + } + + private void Update() + { + } +} diff --git a/GameCode/CardBarButton.cs b/GameCode/CardBarButton.cs new file mode 100644 index 0000000..13d9c62 --- /dev/null +++ b/GameCode/CardBarButton.cs @@ -0,0 +1,19 @@ +using UnityEngine; +using UnityEngine.EventSystems; + +public class CardBarButton : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler +{ + internal CardInfo card; + + public void OnPointerEnter(PointerEventData eventData) + { + GetComponentInParent<CardBar>().OnHover(card, base.transform.position); + base.transform.localScale = Vector3.one * 1.1f; + } + + public void OnPointerExit(PointerEventData eventData) + { + GetComponentInParent<CardBar>().StopHover(); + base.transform.localScale = Vector3.one * 1f; + } +} diff --git a/GameCode/CardBarHandler.cs b/GameCode/CardBarHandler.cs new file mode 100644 index 0000000..f6ceea2 --- /dev/null +++ b/GameCode/CardBarHandler.cs @@ -0,0 +1,27 @@ +using UnityEngine; + +public class CardBarHandler : MonoBehaviour +{ + private CardBar[] cardBars; + + public static CardBarHandler instance; + + private void Start() + { + instance = this; + cardBars = GetComponentsInChildren<CardBar>(); + } + + public void AddCard(int teamId, CardInfo card) + { + cardBars[teamId].AddCard(card); + } + + public void ResetCardBards() + { + for (int i = 0; i < cardBars.Length; i++) + { + cardBars[i].ClearBar(); + } + } +} diff --git a/GameCode/CardCategories.cs b/GameCode/CardCategories.cs new file mode 100644 index 0000000..055dc4c --- /dev/null +++ b/GameCode/CardCategories.cs @@ -0,0 +1,5 @@ +using UnityEngine; + +public class CardCategories : MonoBehaviour +{ +} diff --git a/GameCode/CardCategory.cs b/GameCode/CardCategory.cs new file mode 100644 index 0000000..7961b24 --- /dev/null +++ b/GameCode/CardCategory.cs @@ -0,0 +1,6 @@ +using UnityEngine; + +[CreateAssetMenu(fileName = "Card Category", menuName = "Square Brawl/Card Category", order = 1)] +public class CardCategory : ScriptableObject +{ +} diff --git a/GameCode/CardChoice.cs b/GameCode/CardChoice.cs new file mode 100644 index 0000000..ac3ebb8 --- /dev/null +++ b/GameCode/CardChoice.cs @@ -0,0 +1,460 @@ +using System.Collections; +using System.Collections.Generic; +using Photon.Pun; +using SoundImplementation; +using UnityEngine; + +public class CardChoice : MonoBehaviour +{ + private enum StickDirection + { + Left, + Right, + None + } + + public int pickrID = -1; + + public ArtInstance cardPickArt; + + private Transform[] children; + + public CardInfo[] cards; + + public int picks = 6; + + public static CardChoice instance; + + public bool IsPicking; + + private List<GameObject> spawnedCards = new List<GameObject>(); + + public AnimationCurve curve = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f); + + private float speed = 4f; + + private bool isPlaying; + + private StickDirection lastStickDirection; + + private int currentlySelectedCard; + + private float counter = 1f; + + private PickerType pickerType; + + public CardThemeColor[] cardThemes; + + private void Awake() + { + instance = this; + } + + private void Start() + { + for (int i = 0; i < cards.Length; i++) + { + PhotonNetwork.PrefabPool.RegisterPrefab(cards[i].gameObject.name, cards[i].gameObject); + } + children = new Transform[base.transform.childCount]; + for (int j = 0; j < children.Length; j++) + { + children[j] = base.transform.GetChild(j); + } + } + + public CardInfo GetSourceCard(CardInfo info) + { + for (int i = 0; i < cards.Length; i++) + { + if (cards[i].cardName == info.cardName) + { + return cards[i]; + } + } + return null; + } + + public void Pick(GameObject pickedCard = null, bool clear = false) + { + if ((bool)pickedCard) + { + pickedCard.GetComponentInChildren<ApplyCardStats>().Pick(pickrID, forcePick: false, pickerType); + GetComponent<PhotonView>().RPC("RPCA_DoEndPick", RpcTarget.All, CardIDs(), pickedCard.GetComponent<PhotonView>().ViewID, pickedCard.GetComponent<PublicInt>().theInt, pickrID); + } + else if (PlayerManager.instance.GetPlayerWithID(pickrID).data.view.IsMine) + { + StartCoroutine(ReplaceCards(pickedCard, clear)); + } + } + + private int[] CardIDs() + { + int[] array = new int[spawnedCards.Count]; + for (int i = 0; i < spawnedCards.Count; i++) + { + array[i] = spawnedCards[i].GetComponent<PhotonView>().ViewID; + } + return array; + } + + private List<GameObject> CardFromIDs(int[] cardIDs) + { + List<GameObject> list = new List<GameObject>(); + for (int i = 0; i < cardIDs.Length; i++) + { + list.Add(PhotonNetwork.GetPhotonView(cardIDs[i]).gameObject); + } + return list; + } + + [PunRPC] + private void RPCA_DoEndPick(int[] cardIDs, int targetCardID, int theInt = 0, int pickId = -1) + { + GameObject pickedCard = PhotonNetwork.GetPhotonView(targetCardID).gameObject; + spawnedCards = CardFromIDs(cardIDs); + StartCoroutine(IDoEndPick(pickedCard, theInt, pickId)); + } + + public IEnumerator IDoEndPick(GameObject pickedCard = null, int theInt = 0, int pickId = -1) + { + Vector3 startPos = pickedCard.transform.position; + Vector3 endPos = CardChoiceVisuals.instance.transform.position; + float c2 = 0f; + while (c2 < 1f) + { + CardChoiceVisuals.instance.framesToSnap = 1; + Vector3 position = Vector3.LerpUnclamped(startPos, endPos, curve.Evaluate(c2)); + pickedCard.transform.position = position; + base.transform.GetChild(theInt).position = position; + c2 += Time.deltaTime * speed; + yield return null; + } + GamefeelManager.GameFeel((startPos - endPos).normalized * 2f); + for (int i = 0; i < spawnedCards.Count; i++) + { + if ((bool)spawnedCards[i]) + { + if (spawnedCards[i].gameObject != pickedCard) + { + spawnedCards[i].AddComponent<Rigidbody>().AddForce((spawnedCards[i].transform.position - endPos) * Random.Range(0f, 50f)); + spawnedCards[i].GetComponent<Rigidbody>().AddTorque(Random.onUnitSphere * Random.Range(0f, 200f)); + spawnedCards[i].AddComponent<RemoveAfterSeconds>().seconds = Random.Range(0.5f, 1f); + spawnedCards[i].GetComponent<RemoveAfterSeconds>().shrink = true; + } + else + { + spawnedCards[i].GetComponentInChildren<CardVisuals>().Leave(); + } + } + } + yield return new WaitForSeconds(0.25f); + AnimationCurve softCurve = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f); + Vector3 startPos2 = base.transform.GetChild(theInt).transform.position; + Vector3 endPos2 = startPos; + c2 = 0f; + while (c2 < 1f) + { + Vector3 position2 = Vector3.LerpUnclamped(startPos2, endPos2, softCurve.Evaluate(c2)); + base.transform.GetChild(theInt).position = position2; + c2 += Time.deltaTime * speed * 1.5f; + yield return null; + } + SoundPlayerStatic.Instance.PlayPlayerBallDisappear(); + base.transform.GetChild(theInt).position = startPos; + spawnedCards.Clear(); + if (PlayerManager.instance.GetPlayerWithID(pickId).data.view.IsMine) + { + StartCoroutine(ReplaceCards(pickedCard)); + } + } + + private GameObject Spawn(GameObject objToSpawn, Vector3 pos, Quaternion rot) + { + return PhotonNetwork.Instantiate(GetCardPath(objToSpawn), pos, rot, 0); + } + + private string GetCardPath(GameObject targetObj) + { + return targetObj.name; + } + + public GameObject AddCard(CardInfo cardToSpawn) + { + GameObject gameObject = Spawn(cardToSpawn.gameObject, new Vector3(30f, -10f, 0f), Quaternion.identity); + spawnedCards.Add(gameObject); + return gameObject; + } + + public GameObject AddCardVisual(CardInfo cardToSpawn, Vector3 pos) + { + GameObject obj = Object.Instantiate(cardToSpawn.gameObject, pos, Quaternion.identity); + obj.GetComponentInChildren<CardVisuals>().firstValueToSet = true; + return obj; + } + + private IEnumerator ReplaceCards(GameObject pickedCard = null, bool clear = false) + { + if (picks > 0) + { + SoundPlayerStatic.Instance.PlayPlayerBallAppear(); + } + isPlaying = true; + if (clear && spawnedCards != null) + { + for (int j = 0; j < spawnedCards.Count; j++) + { + if (pickedCard != spawnedCards[j]) + { + spawnedCards[j].GetComponentInChildren<CardVisuals>().Leave(); + yield return new WaitForSecondsRealtime(0.1f); + } + } + yield return new WaitForSecondsRealtime(0.2f); + if ((bool)pickedCard) + { + pickedCard.GetComponentInChildren<CardVisuals>().Pick(); + } + spawnedCards.Clear(); + } + yield return new WaitForSecondsRealtime(0.2f); + if (picks > 0) + { + for (int j = 0; j < children.Length; j++) + { + spawnedCards.Add(SpawnUniqueCard(children[j].transform.position, children[j].transform.rotation)); + spawnedCards[j].AddComponent<PublicInt>().theInt = j; + yield return new WaitForSecondsRealtime(0.1f); + } + } + else + { + GetComponent<PhotonView>().RPC("RPCA_DonePicking", RpcTarget.All); + } + picks--; + isPlaying = false; + } + + [PunRPC] + private void RPCA_DonePicking() + { + IsPicking = false; + } + + private GameObject GetRanomCard() + { + GameObject result = null; + float num = 0f; + for (int i = 0; i < cards.Length; i++) + { + if (cards[i].rarity == CardInfo.Rarity.Common) + { + num += 10f; + } + if (cards[i].rarity == CardInfo.Rarity.Uncommon) + { + num += 4f; + } + if (cards[i].rarity == CardInfo.Rarity.Rare) + { + num += 1f; + } + } + float num2 = Random.Range(0f, num); + for (int j = 0; j < cards.Length; j++) + { + if (cards[j].rarity == CardInfo.Rarity.Common) + { + num2 -= 10f; + } + if (cards[j].rarity == CardInfo.Rarity.Uncommon) + { + num2 -= 4f; + } + if (cards[j].rarity == CardInfo.Rarity.Rare) + { + num2 -= 1f; + } + if (num2 <= 0f) + { + result = cards[j].gameObject; + break; + } + } + return result; + } + + private GameObject SpawnUniqueCard(Vector3 pos, Quaternion rot) + { + GameObject ranomCard = GetRanomCard(); + CardInfo component = ranomCard.GetComponent<CardInfo>(); + Player player = null; + player = ((pickerType != 0) ? PlayerManager.instance.players[pickrID] : PlayerManager.instance.GetPlayersInTeam(pickrID)[0]); + for (int i = 0; i < spawnedCards.Count; i++) + { + bool flag = spawnedCards[i].GetComponent<CardInfo>().cardName == ranomCard.GetComponent<CardInfo>().cardName; + if (pickrID != -1) + { + Holdable holdable = player.data.GetComponent<Holding>().holdable; + if ((bool)holdable) + { + Gun component2 = holdable.GetComponent<Gun>(); + Gun component3 = ranomCard.GetComponent<Gun>(); + if ((bool)component3 && (bool)component2 && component3.lockGunToDefault && component2.lockGunToDefault) + { + flag = true; + } + } + for (int j = 0; j < player.data.currentCards.Count; j++) + { + CardInfo component4 = player.data.currentCards[j].GetComponent<CardInfo>(); + for (int k = 0; k < component4.blacklistedCategories.Length; k++) + { + for (int l = 0; l < component.categories.Length; l++) + { + if (component.categories[l] == component4.blacklistedCategories[k]) + { + flag = true; + } + } + } + if (!component4.allowMultiple && component.cardName == component4.cardName) + { + flag = true; + } + } + } + if (flag) + { + return SpawnUniqueCard(pos, rot); + } + } + GameObject obj = Spawn(ranomCard.gameObject, pos, rot); + obj.GetComponent<CardInfo>().sourceCard = ranomCard.GetComponent<CardInfo>(); + obj.GetComponentInChildren<DamagableEvent>().GetComponent<Collider2D>().enabled = false; + return obj; + } + + private void Update() + { + counter += Time.deltaTime; + _ = isPlaying; + if (pickrID != -1 && IsPicking) + { + DoPlayerSelect(); + } + if (Application.isEditor && !DevConsole.isTyping && Input.GetKeyDown(KeyCode.N)) + { + picks++; + instance.Pick(null, clear: true); + } + } + + private void DoPlayerSelect() + { + SoundMusicManager.Instance.PlayIngame(isCard: true); + if (spawnedCards.Count == 0 || pickrID == -1) + { + return; + } + PlayerActions[] array = null; + array = ((pickerType != 0) ? PlayerManager.instance.GetActionsFromPlayer(pickrID) : PlayerManager.instance.GetActionsFromTeam(pickrID)); + if (array == null) + { + Pick(spawnedCards[0]); + return; + } + StickDirection stickDirection = StickDirection.None; + for (int i = 0; i < array.Length; i++) + { + if (array[i] == null) + { + continue; + } + if (array[i].Right.Value > 0.7f) + { + stickDirection = StickDirection.Right; + } + if (array[i].Left.Value > 0.7f) + { + stickDirection = StickDirection.Left; + } + currentlySelectedCard = Mathf.Clamp(currentlySelectedCard, 0, spawnedCards.Count - 1); + for (int j = 0; j < spawnedCards.Count; j++) + { + if ((bool)spawnedCards[j] && (spawnedCards[j].GetComponentInChildren<CardVisuals>().isSelected != (currentlySelectedCard == j) || counter > 0.2f)) + { + counter = 0f; + spawnedCards[j].GetComponent<PhotonView>().RPC("RPCA_ChangeSelected", RpcTarget.All, currentlySelectedCard == j); + } + } + if (array[i].Jump.WasPressed && !isPlaying && spawnedCards[currentlySelectedCard] != null) + { + Pick(spawnedCards[currentlySelectedCard]); + pickrID = -1; + break; + } + } + if (stickDirection != lastStickDirection) + { + if (stickDirection == StickDirection.Left) + { + currentlySelectedCard--; + } + if (stickDirection == StickDirection.Right) + { + currentlySelectedCard++; + } + lastStickDirection = stickDirection; + } + if (CardChoiceVisuals.instance.currentCardSelected != currentlySelectedCard) + { + CardChoiceVisuals.instance.SetCurrentSelected(currentlySelectedCard); + } + } + + public IEnumerator DoPick(int picksToSet, int picketIDToSet, PickerType pType = PickerType.Team) + { + pickerType = pType; + StartPick(picksToSet, picketIDToSet); + while (IsPicking) + { + yield return null; + } + UIHandler.instance.StopShowPicker(); + CardChoiceVisuals.instance.Hide(); + } + + public void StartPick(int picksToSet, int pickerIDToSet) + { + pickrID = pickerIDToSet; + IsPicking = true; + picks = picksToSet; + ArtHandler.instance.SetSpecificArt(cardPickArt); + Pick(); + } + + public Color GetCardColor(CardThemeColor.CardThemeColorType colorType) + { + for (int i = 0; i < cardThemes.Length; i++) + { + if (cardThemes[i].themeType == colorType) + { + return cardThemes[i].targetColor; + } + } + return Color.black; + } + + public Color GetCardColor2(CardThemeColor.CardThemeColorType colorType) + { + for (int i = 0; i < cardThemes.Length; i++) + { + if (cardThemes[i].themeType == colorType) + { + return cardThemes[i].bgColor; + } + } + return Color.black; + } +} diff --git a/GameCode/CardChoiceVisuals.cs b/GameCode/CardChoiceVisuals.cs new file mode 100644 index 0000000..bf09e08 --- /dev/null +++ b/GameCode/CardChoiceVisuals.cs @@ -0,0 +1,162 @@ +using System.Collections; +using Photon.Pun; +using Sonigon; +using UnityEngine; + +public class CardChoiceVisuals : MonoBehaviour +{ + [Header("Sounds")] + public SoundEvent soundCardSwitch; + + public static CardChoiceVisuals instance; + + [Header("Settings")] + public int currentCardSelected; + + public GameObject cardParent; + + public Transform leftHandTarget; + + public Transform rightHandTarget; + + public Transform shieldGem; + + private Vector3 leftHandRestPos; + + private Vector3 rightHandRestPos; + + private Vector3 leftHandVel; + + private Vector3 rightHandVel; + + public float spring = 40f; + + public float drag = 10f; + + public float sway = 1f; + + public float swaySpeed = 1f; + + public int framesToSnap; + + private bool isShowinig; + + private GameObject currentSkin; + + private void Awake() + { + instance = this; + leftHandRestPos = leftHandTarget.position; + rightHandRestPos = rightHandTarget.position; + } + + private void Start() + { + } + + private void Update() + { + if (!isShowinig || Time.unscaledDeltaTime > 0.1f || currentCardSelected >= cardParent.transform.childCount || currentCardSelected < 0) + { + return; + } + if (rightHandTarget.position.x == float.NaN || rightHandTarget.position.y == float.NaN || rightHandTarget.position.z == float.NaN) + { + rightHandTarget.position = Vector3.zero; + rightHandVel = Vector3.zero; + } + if (leftHandTarget.position.x == float.NaN || leftHandTarget.position.y == float.NaN || leftHandTarget.position.z == float.NaN) + { + leftHandTarget.position = Vector3.zero; + leftHandVel = Vector3.zero; + } + GameObject obj = cardParent.transform.GetChild(currentCardSelected).gameObject; + Vector3 zero = Vector3.zero; + zero = obj.transform.GetChild(0).position; + if (currentCardSelected < 2) + { + leftHandVel += (zero - leftHandTarget.position) * spring * Time.unscaledDeltaTime; + leftHandVel -= leftHandVel * Time.unscaledDeltaTime * drag; + rightHandVel += (rightHandRestPos - rightHandTarget.position) * spring * Time.unscaledDeltaTime * 0.5f; + rightHandVel -= rightHandVel * Time.unscaledDeltaTime * drag * 0.5f; + rightHandVel += sway * new Vector3(-0.5f + Mathf.PerlinNoise(Time.unscaledTime * swaySpeed, 0f), -0.5f + Mathf.PerlinNoise(Time.unscaledTime * swaySpeed + 100f, 0f), 0f) * Time.unscaledDeltaTime; + shieldGem.transform.position = rightHandTarget.position; + if (framesToSnap > 0) + { + leftHandTarget.position = zero; + } + } + else + { + rightHandVel += (zero - rightHandTarget.position) * spring * Time.unscaledDeltaTime; + rightHandVel -= rightHandVel * Time.unscaledDeltaTime * drag; + leftHandVel += (leftHandRestPos - leftHandTarget.position) * spring * Time.unscaledDeltaTime * 0.5f; + leftHandVel -= leftHandVel * Time.unscaledDeltaTime * drag * 0.5f; + leftHandVel += sway * new Vector3(-0.5f + Mathf.PerlinNoise(Time.unscaledTime * swaySpeed, Time.unscaledTime * swaySpeed), -0.5f + Mathf.PerlinNoise(Time.unscaledTime * swaySpeed + 100f, Time.unscaledTime * swaySpeed + 100f), 0f) * Time.unscaledDeltaTime; + shieldGem.transform.position = leftHandTarget.position; + if (framesToSnap > 0) + { + rightHandTarget.position = zero; + } + } + framesToSnap--; + leftHandTarget.position += leftHandVel * Time.unscaledDeltaTime; + rightHandTarget.position += rightHandVel * Time.unscaledDeltaTime; + } + + public void Show(int pickerID = 0, bool animateIn = false) + { + isShowinig = true; + base.transform.GetChild(0).gameObject.SetActive(value: true); + if (animateIn) + { + GetComponent<CurveAnimation>().PlayIn(); + } + else + { + base.transform.localScale = Vector3.one * 33f; + } + if ((bool)currentSkin) + { + Object.Destroy(currentSkin); + } + if (PlayerManager.instance.players[pickerID].data.view.IsMine) + { + PlayerFace playerFace = null; + playerFace = ((!PhotonNetwork.OfflineMode) ? CharacterCreatorHandler.instance.selectedPlayerFaces[0] : CharacterCreatorHandler.instance.selectedPlayerFaces[pickerID]); + GetComponent<PhotonView>().RPC("RPCA_SetFace", RpcTarget.All, playerFace.eyeID, playerFace.eyeOffset, playerFace.mouthID, playerFace.mouthOffset, playerFace.detailID, playerFace.detailOffset, playerFace.detail2ID, playerFace.detail2Offset); + } + currentSkin = Object.Instantiate(PlayerSkinBank.GetPlayerSkinColors(pickerID).gameObject, base.transform.GetChild(0).transform.position, Quaternion.identity, base.transform.GetChild(0).transform); + currentSkin.GetComponentInChildren<ParticleSystem>().Play(); + leftHandTarget.position = base.transform.GetChild(0).position; + rightHandTarget.position = base.transform.GetChild(0).position; + leftHandVel *= 0f; + rightHandVel *= 0f; + StopAllCoroutines(); + } + + public void Hide() + { + GetComponent<CurveAnimation>().PlayOut(); + StartCoroutine(DelayHide()); + } + + private IEnumerator DelayHide() + { + yield return new WaitForSecondsRealtime(0.3f); + base.transform.GetChild(0).gameObject.SetActive(value: false); + isShowinig = false; + } + + internal void SetCurrentSelected(int toSet) + { + GetComponent<PhotonView>().RPC("RPCA_SetCurrentSelected", RpcTarget.All, toSet); + } + + [PunRPC] + internal void RPCA_SetCurrentSelected(int toSet) + { + SoundManager.Instance.Play(soundCardSwitch, base.transform); + currentCardSelected = toSet; + } +} diff --git a/GameCode/CardInfo.cs b/GameCode/CardInfo.cs new file mode 100644 index 0000000..e0b39fc --- /dev/null +++ b/GameCode/CardInfo.cs @@ -0,0 +1,68 @@ +using Photon.Pun; +using Sirenix.OdinInspector; +using UnityEngine; + +public class CardInfo : MonoBehaviour +{ + public enum Rarity + { + Common, + Uncommon, + Rare + } + + [Header("Sound Settings")] + public bool soundDisableBlockBasic; + + [Header("Settings")] + public string cardName = ""; + + [TextArea] + public string cardDestription = ""; + + public CardInfoStat[] cardStats; + + public Rarity rarity; + + public GameObject cardArt; + + public Sprite sprite; + + [HideInInspector] + public CardInfo sourceCard; + + public Color cardColor = new Color(0.14509805f, 0.14509805f, 0.14509805f); + + public CardCategory[] categories; + + [FoldoutGroup("Restrictions", 0)] + public bool allowMultiple = true; + + [FoldoutGroup("Restrictions", 0)] + public CardCategory[] blacklistedCategories; + + public GameObject cardBase; + + public CardThemeColor.CardThemeColorType colorTheme; + + private void Awake() + { + sourceCard = CardChoice.instance.GetSourceCard(this); + cardBase = Object.Instantiate(cardBase, base.transform.position, base.transform.rotation); + cardBase.transform.SetParent(base.transform, worldPositionStays: true); + bool charge = false; + Gun component = GetComponent<Gun>(); + if ((bool)component && component.useCharge) + { + charge = true; + } + cardBase.GetComponent<CardInfoDisplayer>().DrawCard(cardStats, cardName, cardDestription, sprite, charge); + cardBase.GetComponentInChildren<GeneralParticleSystem>().particleSettings.randomColor = cardColor; + } + + [PunRPC] + public void RPCA_ChangeSelected(bool setSelected) + { + GetComponentInChildren<CardVisuals>().ChangeSelected(setSelected); + } +} diff --git a/GameCode/CardInfoDisplayer.cs b/GameCode/CardInfoDisplayer.cs new file mode 100644 index 0000000..7c19bfe --- /dev/null +++ b/GameCode/CardInfoDisplayer.cs @@ -0,0 +1,61 @@ +using TMPro; +using UnityEngine; +using UnityEngine.UI; + +public class CardInfoDisplayer : MonoBehaviour +{ + public Color negativeColor; + + public Color positiveColor; + + public GameObject statObject; + + public GameObject grid; + + public GameObject chargeObj; + + public TextMeshProUGUI effectText; + + public TextMeshProUGUI nameText; + + public Image icon; + + public void DrawCard(CardInfoStat[] stats, string cardName, string description = "", Sprite image = null, bool charge = false) + { + if (charge) + { + chargeObj.SetActive(value: true); + chargeObj.transform.SetParent(grid.transform, worldPositionStays: true); + } + if (description != "") + { + effectText.text = description; + effectText.gameObject.SetActive(value: true); + effectText.transform.SetParent(grid.transform, worldPositionStays: true); + } + nameText.text = cardName.ToUpper(); + for (int i = 0; i < stats.Length; i++) + { + GameObject obj = Object.Instantiate(statObject, grid.transform.position, grid.transform.rotation, grid.transform); + obj.SetActive(value: true); + obj.transform.localScale = Vector3.one; + TextMeshProUGUI component = obj.transform.GetChild(0).GetComponent<TextMeshProUGUI>(); + TextMeshProUGUI component2 = obj.transform.GetChild(1).GetComponent<TextMeshProUGUI>(); + component.text = stats[i].stat; + if (stats[i].simepleAmount != 0 && !Optionshandler.showCardStatNumbers) + { + component2.text = stats[i].GetSimpleAmount(); + } + else + { + component2.text = stats[i].amount; + } + component2.color = (stats[i].positive ? positiveColor : negativeColor); + } + if ((bool)image) + { + icon.sprite = image; + } + effectText.transform.position += Vector3.up * 0.3f; + } +} diff --git a/GameCode/CardInfoStat.cs b/GameCode/CardInfoStat.cs new file mode 100644 index 0000000..943936c --- /dev/null +++ b/GameCode/CardInfoStat.cs @@ -0,0 +1,69 @@ +using System; + +[Serializable] +public class CardInfoStat +{ + public enum SimpleAmount + { + notAssigned, + aLittleBitOf, + Some, + aLotOf, + aHugeAmountOf, + slightlyLower, + lower, + aLotLower, + slightlySmaller, + smaller + } + + public bool positive; + + public string amount; + + public SimpleAmount simepleAmount; + + public string stat; + + public string GetSimpleAmount() + { + string result = ""; + if (simepleAmount == SimpleAmount.aLittleBitOf) + { + result = "Slightly more "; + } + if (simepleAmount == SimpleAmount.Some) + { + result = "More "; + } + if (simepleAmount == SimpleAmount.aLotOf) + { + result = "A bunch more "; + } + if (simepleAmount == SimpleAmount.aHugeAmountOf) + { + result = "A huge amount of"; + } + if (simepleAmount == SimpleAmount.slightlyLower) + { + result = "Slightly lower "; + } + if (simepleAmount == SimpleAmount.lower) + { + result = "Lower "; + } + if (simepleAmount == SimpleAmount.aLotLower) + { + result = "A lot lower"; + } + if (simepleAmount == SimpleAmount.smaller) + { + result = "Smaller"; + } + if (simepleAmount == SimpleAmount.slightlySmaller) + { + result = "Slightly smaller"; + } + return result; + } +} diff --git a/GameCode/CardRarityColor.cs b/GameCode/CardRarityColor.cs new file mode 100644 index 0000000..3008ae7 --- /dev/null +++ b/GameCode/CardRarityColor.cs @@ -0,0 +1,33 @@ +using System; +using UnityEngine; +using UnityEngine.UI; + +public class CardRarityColor : MonoBehaviour +{ + public Color uncommonColor; + + public Color rareColor; + + public Color uncommonColorOff; + + public Color rareColorOff; + + private void Awake() + { + CardVisuals componentInParent = GetComponentInParent<CardVisuals>(); + componentInParent.toggleSelectionAction = (Action<bool>)Delegate.Combine(componentInParent.toggleSelectionAction, new Action<bool>(Toggle)); + } + + public void Toggle(bool isOn) + { + CardInfo componentInParent = GetComponentInParent<CardInfo>(); + if (componentInParent.rarity == CardInfo.Rarity.Uncommon) + { + GetComponent<Image>().color = (isOn ? uncommonColor : uncommonColorOff); + } + if (componentInParent.rarity == CardInfo.Rarity.Rare) + { + GetComponent<Image>().color = (isOn ? rareColor : rareColorOff); + } + } +} diff --git a/GameCode/CardThemeColor.cs b/GameCode/CardThemeColor.cs new file mode 100644 index 0000000..780dcd5 --- /dev/null +++ b/GameCode/CardThemeColor.cs @@ -0,0 +1,25 @@ +using System; +using UnityEngine; + +[Serializable] +public class CardThemeColor +{ + public enum CardThemeColorType + { + DestructiveRed, + FirepowerYellow, + DefensiveBlue, + TechWhite, + EvilPurple, + PoisonGreen, + NatureBrown, + ColdBlue, + MagicPink + } + + public CardThemeColorType themeType; + + public Color targetColor; + + public Color bgColor; +} diff --git a/GameCode/CardVisuals.cs b/GameCode/CardVisuals.cs new file mode 100644 index 0000000..483d5d7 --- /dev/null +++ b/GameCode/CardVisuals.cs @@ -0,0 +1,138 @@ +using System; +using Photon.Pun; +using TMPro; +using UnityEngine; +using UnityEngine.UI; + +public class CardVisuals : MonoBehaviour +{ + private ScaleShake shake; + + public bool isSelected; + + private GeneralParticleSystem part; + + private Color selectedColor; + + private Color unSelectedColor = new Color(0.1f, 0.1f, 0.1f); + + public Color defaultColor; + + public Color chillColor; + + public Image[] images; + + public TextMeshProUGUI nameText; + + public GameObject statsObj; + + public GameObject[] objectsToToggle; + + private CardAnimation[] cardAnims; + + private CanvasGroup group; + + public bool firstValueToSet; + + public Action<bool> toggleSelectionAction; + + private void Start() + { + group = base.transform.Find("Canvas/Front/Grid").GetComponent<CanvasGroup>(); + selectedColor = GetComponentInParent<CardInfo>().cardColor; + part = GetComponentInChildren<GeneralParticleSystem>(); + shake = GetComponent<ScaleShake>(); + Transform transform = base.transform.Find("Canvas/Front/Background/Art"); + CardInfo componentInParent = GetComponentInParent<CardInfo>(); + defaultColor = CardChoice.instance.GetCardColor(componentInParent.colorTheme); + selectedColor = CardChoice.instance.GetCardColor2(componentInParent.colorTheme); + if ((bool)componentInParent.cardArt) + { + GameObject obj = UnityEngine.Object.Instantiate(componentInParent.cardArt, transform.transform.position, transform.transform.rotation, transform); + obj.transform.localPosition = Vector3.zero; + obj.transform.SetAsFirstSibling(); + obj.transform.localScale = Vector3.one; + } + cardAnims = GetComponentsInChildren<CardAnimation>(); + isSelected = !firstValueToSet; + ChangeSelected(firstValueToSet); + } + + public void Leave() + { + UnityEngine.Object.Destroy(base.transform.root.gameObject); + } + + public void Pick() + { + PhotonNetwork.Destroy(base.transform.root.gameObject); + } + + public void ChangeSelected(bool setSelected) + { + if (!part || isSelected == setSelected) + { + return; + } + isSelected = setSelected; + toggleSelectionAction?.Invoke(isSelected); + if (isSelected) + { + part.simulationSpeedMultiplier = 1.25f; + part.particleSettings.randomColor = selectedColor; + shake.targetScale = 1.15f; + group.alpha = 1f; + for (int i = 0; i < images.Length; i++) + { + images[i].color = defaultColor; + } + for (int j = 0; j < objectsToToggle.Length; j++) + { + objectsToToggle[j].SetActive(value: false); + } + for (int k = 0; k < cardAnims.Length; k++) + { + cardAnims[k].enabled = true; + } + nameText.color = defaultColor; + CurveAnimation[] componentsInChildren = GetComponentsInChildren<CurveAnimation>(); + for (int l = 0; l < componentsInChildren.Length; l++) + { + if (componentsInChildren[l].transform.parent != base.transform) + { + componentsInChildren[l].PlayIn(); + } + else if (componentsInChildren[l].currentState != 0) + { + componentsInChildren[l].PlayIn(); + } + } + return; + } + part.simulationSpeedMultiplier = 0.5f; + part.particleSettings.randomColor = unSelectedColor; + shake.targetScale = 0.9f; + group.alpha = 0.15f; + for (int m = 0; m < images.Length; m++) + { + images[m].color = chillColor; + } + for (int n = 0; n < objectsToToggle.Length; n++) + { + objectsToToggle[n].SetActive(value: true); + } + for (int num = 0; num < cardAnims.Length; num++) + { + cardAnims[num].enabled = false; + } + nameText.color = chillColor; + CurveAnimation[] componentsInChildren2 = GetComponentsInChildren<CurveAnimation>(); + for (int num2 = 0; num2 < componentsInChildren2.Length; num2++) + { + if (componentsInChildren2[num2].transform.parent != base.transform) + { + componentsInChildren2[num2].PlayOut(); + } + } + } +} diff --git a/GameCode/ChangeColor.cs b/GameCode/ChangeColor.cs new file mode 100644 index 0000000..a0d61bf --- /dev/null +++ b/GameCode/ChangeColor.cs @@ -0,0 +1,12 @@ +using UnityEngine; + +public class ChangeColor : MonoBehaviour +{ + private void Start() + { + } + + private void Update() + { + } +} diff --git a/GameCode/ChangeDamageMultiplierAfterDistanceTravelled.cs b/GameCode/ChangeDamageMultiplierAfterDistanceTravelled.cs new file mode 100644 index 0000000..7bd1bf8 --- /dev/null +++ b/GameCode/ChangeDamageMultiplierAfterDistanceTravelled.cs @@ -0,0 +1,39 @@ +using UnityEngine; + +public class ChangeDamageMultiplierAfterDistanceTravelled : MonoBehaviour +{ + public float muiltiplier = 2f; + + public float distance = 10f; + + private ProjectileHit hit; + + private MoveTransform move; + + private TrailRenderer trail; + + private void Awake() + { + trail = GetComponentInChildren<TrailRenderer>(); + } + + private void Start() + { + hit = GetComponent<ProjectileHit>(); + move = GetComponent<MoveTransform>(); + } + + private void Update() + { + if (move.distanceTravelled > distance) + { + hit.damage *= muiltiplier; + hit.shake *= muiltiplier; + if ((bool)trail) + { + trail.widthMultiplier *= 2f; + } + Object.Destroy(this); + } + } +} diff --git a/GameCode/ChannelMessage.cs b/GameCode/ChannelMessage.cs new file mode 100644 index 0000000..2349349 --- /dev/null +++ b/GameCode/ChannelMessage.cs @@ -0,0 +1,3 @@ +using Irc; + +public delegate void ChannelMessage(ChannelMessageEventArgs channelMessageArgs); diff --git a/GameCode/CharacterCreator.cs b/GameCode/CharacterCreator.cs new file mode 100644 index 0000000..55d31ed --- /dev/null +++ b/GameCode/CharacterCreator.cs @@ -0,0 +1,101 @@ +using System; +using UnityEngine; + +public class CharacterCreator : MonoBehaviour +{ + public PlayerFace currentPlayerFace; + + public GameObject objectToEnable; + + public int playerID; + + public int portraitID; + + public bool ready; + + public PlayerActions playerActions; + + public GeneralInput.InputType inputType; + + public MenuControllerHandler.MenuControl currentControl = MenuControllerHandler.MenuControl.Unassigned; + + public MenuControllerHandler.MenuControl lastControl = MenuControllerHandler.MenuControl.Unassigned; + + public Action<MenuControllerHandler.MenuControl> SwitchAction; + + public CharacterCreatorNavigation nav; + + private void Start() + { + nav = GetComponentInChildren<CharacterCreatorNavigation>(); + } + + private void Update() + { + if (currentControl != lastControl) + { + SwitchAction?.Invoke(currentControl); + } + lastControl = currentControl; + } + + public void Close() + { + CharacterCreatorHandler.instance.ReleasePortrait(portraitID); + if (playerActions == null) + { + base.gameObject.SetActive(value: false); + MainMenuHandler.instance.Open(); + } + else + { + objectToEnable.SetActive(value: true); + base.gameObject.SetActive(value: false); + } + } + + public void Finish() + { + CharacterCreatorHandler.instance.ReleasePortrait(portraitID); + CharacterCreatorHandler.instance.SetFacePreset(portraitID, currentPlayerFace); + CharacterCreatorHandler.instance.SelectFace(0, currentPlayerFace, portraitID); + if (playerActions == null) + { + base.gameObject.SetActive(value: false); + MainMenuHandler.instance.Open(); + } + else + { + objectToEnable.SetActive(value: true); + base.gameObject.SetActive(value: false); + } + } + + internal void SetOffset(Vector2 offset, CharacterItemType itemType, int slotID) + { + if (itemType == CharacterItemType.Eyes) + { + currentPlayerFace.eyeOffset = offset; + } + if (itemType == CharacterItemType.Mouth) + { + currentPlayerFace.mouthOffset = offset; + } + if (itemType == CharacterItemType.Detail) + { + if (slotID == 0) + { + currentPlayerFace.detailOffset = offset; + } + if (slotID == 1) + { + currentPlayerFace.detail2Offset = offset; + } + } + } + + internal void SpawnFace(PlayerFace currentFace) + { + GetComponentInChildren<CharacterCreatorItemEquipper>().SpawnPlayerFace(currentFace); + } +} diff --git a/GameCode/CharacterCreatorButtonSpawner.cs b/GameCode/CharacterCreatorButtonSpawner.cs new file mode 100644 index 0000000..9e0fffb --- /dev/null +++ b/GameCode/CharacterCreatorButtonSpawner.cs @@ -0,0 +1,146 @@ +using UnityEngine; + +public class CharacterCreatorButtonSpawner : MonoBehaviour +{ + public GameObject sourceButton; + + private CharacterCreatorItemLoader loader; + + private CharacterCreator creator; + + private void Start() + { + creator = GetComponent<CharacterCreator>(); + loader = CharacterCreatorItemLoader.instance; + OpenMenu(CharacterItemType.Eyes, 0); + } + + public void OpenMenu(int id) + { + if (id == 0) + { + OpenMenu(CharacterItemType.Eyes, 0); + } + if (id == 1) + { + OpenMenu(CharacterItemType.Mouth, 0); + } + if (id == 2) + { + OpenMenu(CharacterItemType.Detail, 0); + } + if (id == 3) + { + OpenMenu(CharacterItemType.Detail, 1); + } + } + + public void OpenMenu(CharacterItemType target, int slotNr) + { + CharacterItem[] array = null; + if (target == CharacterItemType.Eyes) + { + array = loader.eyes; + } + if (target == CharacterItemType.Mouth) + { + array = loader.mouths; + } + if (target == CharacterItemType.Detail) + { + array = loader.accessories; + } + for (int i = 0; i < sourceButton.transform.parent.childCount; i++) + { + if (sourceButton.transform.parent.GetChild(i).gameObject.activeSelf) + { + Object.Destroy(sourceButton.transform.parent.GetChild(i).gameObject); + } + } + for (int j = 0; j < array.Length; j++) + { + GameObject gameObject = Object.Instantiate(sourceButton, sourceButton.transform.parent); + gameObject.SetActive(value: true); + Transform parent = gameObject.transform.Find("ItemParent"); + GameObject gameObject2 = Object.Instantiate(array[j].gameObject, parent); + gameObject.GetComponent<CharacterItemButton>().itemType = target; + gameObject.GetComponent<CharacterItemButton>().slotNr = slotNr; + gameObject.GetComponentInChildren<CharacterItem>().sprite = array[j].gameObject.GetComponent<SpriteRenderer>().sprite; + gameObject2.GetComponentInChildren<CharacterItem>().GetComponent<SpriteRenderer>().sortingOrder = array[j].gameObject.GetComponent<SpriteRenderer>().sortingOrder; + gameObject2.GetComponentInChildren<CharacterItem>().scale = array[j].scale; + gameObject2.GetComponentInChildren<CharacterItem>().itemType = target; + gameObject2.GetComponentInChildren<CharacterItem>().offset = array[j].offset; + gameObject2.GetComponentInChildren<CharacterItem>().slotNr = slotNr; + gameObject2.GetComponentInChildren<SpriteRenderer>().transform.localPosition = array[j].offset; + gameObject2.GetComponentInChildren<SpriteRenderer>().transform.localScale = array[j].scale * Vector2.one; + if (target == CharacterItemType.Eyes && j == creator.currentPlayerFace.eyeID) + { + gameObject.transform.Find("SelectedDot").gameObject.SetActive(value: true); + } + if (target == CharacterItemType.Mouth && j == creator.currentPlayerFace.mouthID) + { + gameObject.transform.Find("SelectedDot").gameObject.SetActive(value: true); + } + if (target == CharacterItemType.Detail && j == creator.currentPlayerFace.detailID && slotNr == 0) + { + gameObject.transform.Find("SelectedDot").gameObject.SetActive(value: true); + } + if (target == CharacterItemType.Detail && slotNr == 1 && j == creator.currentPlayerFace.detail2ID) + { + gameObject.transform.Find("SelectedDot").gameObject.SetActive(value: true); + } + } + } + + public void SelectButton(CharacterItemType itemType, int slotNr) + { + for (int i = 0; i < sourceButton.transform.parent.childCount; i++) + { + GameObject gameObject = sourceButton.transform.parent.GetChild(i).gameObject; + if (itemType == CharacterItemType.Eyes) + { + if (i - 1 == creator.currentPlayerFace.eyeID) + { + gameObject.transform.Find("SelectedDot").gameObject.SetActive(value: true); + } + else + { + gameObject.transform.Find("SelectedDot").gameObject.SetActive(value: false); + } + } + if (itemType == CharacterItemType.Mouth) + { + if (i - 1 == creator.currentPlayerFace.mouthID) + { + gameObject.transform.Find("SelectedDot").gameObject.SetActive(value: true); + } + else + { + gameObject.transform.Find("SelectedDot").gameObject.SetActive(value: false); + } + } + if (itemType == CharacterItemType.Detail) + { + if (i - 1 == creator.currentPlayerFace.detailID && slotNr == 0) + { + gameObject.transform.Find("SelectedDot").gameObject.SetActive(value: true); + } + else + { + gameObject.transform.Find("SelectedDot").gameObject.SetActive(value: false); + } + } + if (itemType == CharacterItemType.Detail && slotNr == 1) + { + if (i - 1 == creator.currentPlayerFace.detail2ID) + { + gameObject.transform.Find("SelectedDot").gameObject.SetActive(value: true); + } + else + { + gameObject.transform.Find("SelectedDot").gameObject.SetActive(value: false); + } + } + } + } +} diff --git a/GameCode/CharacterCreatorDragging.cs b/GameCode/CharacterCreatorDragging.cs new file mode 100644 index 0000000..21ec9f1 --- /dev/null +++ b/GameCode/CharacterCreatorDragging.cs @@ -0,0 +1,116 @@ +using InControl; +using UnityEngine; + +public class CharacterCreatorDragging : MonoBehaviour +{ + public Vector2 rightStick; + + private CharacterCreator creator; + + private Transform draggedObject; + + private Vector2 lastMouse = Vector3.zero; + + private void Start() + { + creator = GetComponentInParent<CharacterCreator>(); + } + + private void Update() + { + if (creator.inputType == GeneralInput.InputType.Keyboard || creator.inputType == GeneralInput.InputType.Either) + { + DoMouse(); + } + if (creator.inputType == GeneralInput.InputType.Controller || creator.inputType == GeneralInput.InputType.Either) + { + DoController(); + } + } + + private void DoController() + { + int num = -1; + int barPos = creator.nav.barPos; + for (int i = 0; i < base.transform.childCount; i++) + { + CharacterItem component = base.transform.GetChild(i).GetComponent<CharacterItem>(); + if (barPos == 0 && component.itemType == CharacterItemType.Eyes) + { + num = i; + } + if (barPos == 1 && component.itemType == CharacterItemType.Mouth) + { + num = i; + } + if (barPos == 2 && component.itemType == CharacterItemType.Detail && component.slotNr == 0) + { + num = i; + } + if (barPos == 3 && component.itemType == CharacterItemType.Detail && component.slotNr == 1) + { + num = i; + } + } + if (num >= base.transform.childCount) + { + return; + } + Vector2 vector = Vector2.zero; + if (creator.playerActions != null) + { + vector = creator.playerActions.Aim.Value; + } + else + { + for (int j = 0; j < InputManager.ActiveDevices.Count; j++) + { + vector = InputManager.ActiveDevices[j].RightStick.Value; + } + } + base.transform.GetChild(num).transform.position += (Vector3)vector * Time.deltaTime * 3f; + if (vector != Vector2.zero) + { + CharacterItem component2 = base.transform.GetChild(num).GetComponent<CharacterItem>(); + Vector2 offset = (Vector2)base.transform.GetChild(num).localPosition - component2.offset; + creator.SetOffset(offset, component2.itemType, component2.slotNr); + } + } + + private void DoMouse() + { + Vector2 vector = MainCam.instance.cam.ScreenToWorldPoint(Input.mousePosition); + if (Input.GetKeyDown(KeyCode.Mouse0)) + { + float num = 2f; + int num2 = -1; + for (int i = 0; i < base.transform.childCount; i++) + { + float num3 = Vector2.Distance(vector, base.transform.GetChild(i).transform.position); + Debug.DrawLine(vector, base.transform.GetChild(i).GetComponent<SpriteRenderer>().bounds.center, Color.red, 2f); + if (num3 < num) + { + num = num3; + num2 = i; + } + } + if (num2 != -1) + { + draggedObject = base.transform.GetChild(num2); + } + } + if (Input.GetKeyUp(KeyCode.Mouse0) && (bool)draggedObject) + { + CharacterItem component = draggedObject.GetComponent<CharacterItem>(); + Vector2 offset = (Vector2)draggedObject.transform.localPosition - component.offset; + creator.SetOffset(offset, component.itemType, component.slotNr); + draggedObject = null; + } + if ((bool)draggedObject) + { + draggedObject.transform.position += (Vector3)(vector - lastMouse); + draggedObject.transform.localPosition = Vector2.ClampMagnitude(draggedObject.transform.localPosition, 4.5f); + } + lastMouse = vector; + } +} diff --git a/GameCode/CharacterCreatorHandler.cs b/GameCode/CharacterCreatorHandler.cs new file mode 100644 index 0000000..1dd23c7 --- /dev/null +++ b/GameCode/CharacterCreatorHandler.cs @@ -0,0 +1,135 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +public class CharacterCreatorHandler : MonoBehaviour +{ + public static CharacterCreatorHandler instance; + + public PlayerFace[] playerFaces = new PlayerFace[10]; + + public PlayerFace[] selectedPlayerFaces = new PlayerFace[4]; + + public int[] selectedFaceID = new int[4]; + + public List<int> lockedPortraits; + + public Action lockedPortraitAction; + + public Action<int> faceWasUpdatedAction; + + public void LockPortrait(int portrait) + { + lockedPortraits.Add(portrait); + lockedPortraitAction?.Invoke(); + } + + public void ReleasePortrait(int porttrait) + { + for (int i = 0; i < lockedPortraits.Count; i++) + { + if (porttrait == lockedPortraits[i]) + { + lockedPortraits.RemoveAt(i); + break; + } + } + lockedPortraitAction?.Invoke(); + } + + private void ReleaseAllPortraits() + { + lockedPortraits.Clear(); + lockedPortraitAction?.Invoke(); + } + + private void Awake() + { + instance = this; + for (int i = 0; i < playerFaces.Length; i++) + { + playerFaces[i].LoadFace(i.ToString()); + } + for (int j = 0; j < selectedFaceID.Length; j++) + { + selectedFaceID[j] = PlayerPrefs.GetInt("SelectedFace" + j); + SelectFace(j, playerFaces[selectedFaceID[j]], selectedFaceID[j]); + } + } + + internal void SelectFace(int faceID, PlayerFace selectedFace, int faceSlot) + { + selectedFaceID[faceID] = faceSlot; + PlayerPrefs.SetInt("SelectedFace" + faceID, selectedFaceID[faceID]); + selectedPlayerFaces[faceID] = selectedFace; + } + + public PlayerFace GetFacePreset(int faceID) + { + return playerFaces[faceID]; + } + + public bool SomeoneIsEditing() + { + for (int i = 0; i < base.transform.childCount; i++) + { + if (base.transform.GetChild(i).gameObject.activeSelf) + { + return true; + } + } + return false; + } + + internal void SetFacePreset(int faceID, PlayerFace currentPlayerFace) + { + playerFaces[faceID] = PlayerFace.CopyFace(currentPlayerFace); + playerFaces[faceID].SaveFace(faceID.ToString()); + faceWasUpdatedAction?.Invoke(faceID); + } + + public void EditCharacterLocalMultiplayer(int playerId, int portraitID, GameObject objectToEnable, PlayerFace currentFace) + { + LockPortrait(portraitID); + CharacterCreator component = base.transform.GetChild(playerId + 1).GetComponent<CharacterCreator>(); + component.playerActions = PlayerManager.instance.players[playerId].data.playerActions; + component.inputType = PlayerManager.instance.players[playerId].data.input.inputType; + component.gameObject.SetActive(value: true); + component.playerID = playerId; + component.objectToEnable = objectToEnable; + component.currentPlayerFace = currentFace; + component.portraitID = portraitID; + component.SpawnFace(currentFace); + } + + public void EditCharacterPortrait(int portraitID, PlayerFace currentFace) + { + LockPortrait(portraitID); + MainMenuHandler.instance.Close(); + CharacterCreator component = base.transform.GetChild(0).GetComponent<CharacterCreator>(); + component.inputType = GeneralInput.InputType.Either; + component.currentPlayerFace = currentFace; + component.gameObject.SetActive(value: true); + component.playerID = 0; + component.portraitID = portraitID; + component.SpawnFace(currentFace); + } + + public void CloseMenus() + { + for (int i = 0; i < base.transform.childCount; i++) + { + base.transform.GetChild(i).GetComponent<CharacterCreator>().Close(); + } + ReleaseAllPortraits(); + } + + public void EndCustomization(int playerId = -1) + { + if (playerId == -1) + { + GetComponentInChildren<CharacterCreator>(includeInactive: true).Finish(); + base.transform.GetChild(0).gameObject.SetActive(value: false); + } + } +} diff --git a/GameCode/CharacterCreatorItemEquipper.cs b/GameCode/CharacterCreatorItemEquipper.cs new file mode 100644 index 0000000..ba03491 --- /dev/null +++ b/GameCode/CharacterCreatorItemEquipper.cs @@ -0,0 +1,130 @@ +using Photon.Pun; +using UnityEngine; + +public class CharacterCreatorItemEquipper : MonoBehaviour +{ + public GameObject itemParent; + + public GameObject defaultEyes; + + public GameObject defaultMouth; + + private CharacterCreatorItemLoader itemLoader; + + private CharacterCreator creator; + + public float scaleM = 1f; + + private bool spawnedSpecific; + + private bool inited; + + private void Start() + { + Init(); + if ((bool)creator && !spawnedSpecific) + { + Equip(defaultEyes.GetComponent<CharacterItem>(), CharacterItemType.Eyes); + Equip(defaultMouth.GetComponent<CharacterItem>(), CharacterItemType.Mouth); + } + } + + public void SpawnPlayerFace(PlayerFace newFace) + { + spawnedSpecific = true; + EquipFace(newFace); + } + + private void Init() + { + if (!inited) + { + inited = true; + creator = GetComponent<CharacterCreator>(); + itemLoader = CharacterCreatorItemLoader.instance; + } + } + + [PunRPC] + public void RPCA_SetFace(int eyeID, Vector2 eyeOffset, int mouthID, Vector2 mouthOffset, int detailID, Vector2 detailOffset, int detail2ID, Vector2 detail2Offset) + { + PlayerFace face = PlayerFace.CreateFace(eyeID, eyeOffset, mouthID, mouthOffset, detailID, detailOffset, detail2ID, detail2Offset); + EquipFace(face); + } + + public void EquipFace(PlayerFace face) + { + Init(); + Equip(itemLoader.GetItem(face.eyeID, CharacterItemType.Eyes), CharacterItemType.Eyes, face.eyeOffset); + Equip(itemLoader.GetItem(face.mouthID, CharacterItemType.Mouth), CharacterItemType.Mouth, face.mouthOffset); + Equip(itemLoader.GetItem(face.detailID, CharacterItemType.Detail), CharacterItemType.Detail, face.detailOffset); + Equip(itemLoader.GetItem(face.detail2ID, CharacterItemType.Detail), CharacterItemType.Detail, face.detail2Offset, 1); + } + + public void Equip(CharacterItem newSprite, CharacterItemType itemType, Vector2 offset = default(Vector2), int slotNr = 0) + { + if (newSprite == null) + { + return; + } + Init(); + if ((bool)creator) + { + if (itemType == CharacterItemType.Eyes) + { + creator.currentPlayerFace.eyeID = itemLoader.GetItemID(newSprite, itemType); + } + if (itemType == CharacterItemType.Mouth) + { + creator.currentPlayerFace.mouthID = itemLoader.GetItemID(newSprite, itemType); + } + if (itemType == CharacterItemType.Detail) + { + if (slotNr == 0) + { + creator.currentPlayerFace.detailID = itemLoader.GetItemID(newSprite, itemType); + } + if (slotNr == 1) + { + creator.currentPlayerFace.detail2ID = itemLoader.GetItemID(newSprite, itemType); + } + } + } + Clear(itemType, slotNr); + SpawnItem(newSprite, itemType, offset, slotNr); + CopyChildren[] componentsInChildren = GetComponentsInChildren<CopyChildren>(); + for (int i = 0; i < componentsInChildren.Length; i++) + { + componentsInChildren[i].DoUpdate(); + } + } + + private void SpawnItem(CharacterItem newSprite, CharacterItemType itemType, Vector2 offset = default(Vector2), int slotNr = 0) + { + GameObject obj = Object.Instantiate(newSprite.gameObject); + obj.gameObject.SetActive(value: true); + obj.transform.SetParent(itemParent.transform); + obj.GetComponent<SpriteRenderer>().sprite = newSprite.GetComponent<CharacterItem>().sprite; + obj.GetComponent<SpriteRenderer>().sortingOrder = newSprite.GetComponent<CharacterItem>().GetComponent<SpriteRenderer>().sortingOrder; + obj.GetComponent<CharacterItem>().itemType = itemType; + obj.GetComponent<SpriteRenderer>().color = newSprite.GetComponent<SpriteRenderer>().color; + obj.GetComponentInChildren<CharacterItem>().offset = newSprite.GetComponent<CharacterItem>().offset; + obj.GetComponentInChildren<CharacterItem>().sprite = newSprite.GetComponent<CharacterItem>().sprite; + obj.GetComponentInChildren<CharacterItem>().slotNr = slotNr; + obj.transform.localScale = newSprite.GetComponent<CharacterItem>().scale * Vector3.one * scaleM; + obj.transform.localPosition = (newSprite.GetComponent<CharacterItem>().offset + offset) * scaleM; + creator?.SetOffset(offset, itemType, slotNr); + } + + private void Clear(CharacterItemType itemType, int slotNr = 0) + { + for (int i = 0; i < itemParent.transform.childCount; i++) + { + CharacterItem component = itemParent.transform.GetChild(i).GetComponent<CharacterItem>(); + if (component.itemType == itemType && component.slotNr == slotNr) + { + Object.DestroyImmediate(itemParent.transform.GetChild(i).gameObject); + } + } + } +} diff --git a/GameCode/CharacterCreatorItemLoader.cs b/GameCode/CharacterCreatorItemLoader.cs new file mode 100644 index 0000000..2a79940 --- /dev/null +++ b/GameCode/CharacterCreatorItemLoader.cs @@ -0,0 +1,77 @@ +using UnityEngine; + +public class CharacterCreatorItemLoader : MonoBehaviour +{ + public CharacterItem[] eyes; + + public CharacterItem[] mouths; + + public CharacterItem[] accessories; + + public static CharacterCreatorItemLoader instance; + + private void Awake() + { + instance = this; + } + + private void Update() + { + } + + internal CharacterItem GetItem(int itemID, CharacterItemType itemType) + { + try + { + return itemType switch + { + CharacterItemType.Eyes => eyes[itemID], + CharacterItemType.Mouth => mouths[itemID], + _ => accessories[itemID], + }; + } + catch + { + return null; + } + } + + internal int GetItemID(CharacterItem newSprite, CharacterItemType itemType) + { + CharacterItem[] array = null; + array = itemType switch + { + CharacterItemType.Eyes => eyes, + CharacterItemType.Mouth => mouths, + _ => accessories, + }; + for (int i = 0; i < array.Length; i++) + { + if (array[i].sprite == newSprite.sprite) + { + return i; + } + } + return -1; + } + + public void UpdateItems(CharacterItemType target, CharacterItem[] items) + { + for (int i = 0; i < items.Length; i++) + { + items[i].sprite = items[i].GetComponent<SpriteRenderer>().sprite; + } + if (target == CharacterItemType.Eyes) + { + eyes = items; + } + if (target == CharacterItemType.Mouth) + { + mouths = items; + } + if (target == CharacterItemType.Detail) + { + accessories = items; + } + } +} diff --git a/GameCode/CharacterCreatorNavigation.cs b/GameCode/CharacterCreatorNavigation.cs new file mode 100644 index 0000000..46292e4 --- /dev/null +++ b/GameCode/CharacterCreatorNavigation.cs @@ -0,0 +1,162 @@ +using InControl; +using UnityEngine; +using UnityEngine.UI; + +public class CharacterCreatorNavigation : MonoBehaviour +{ + private int itemsInRow = 7; + + private CharacterCreator creator; + + private Transform grid; + + private Transform bar; + + private GameObject currentObject; + + private GameObject currentBarObject; + + private CharacterCreatorDragging dragging; + + public int x; + + public int y; + + public int barPos; + + private float cd; + + private void Awake() + { + creator = GetComponent<CharacterCreator>(); + dragging = GetComponentInChildren<CharacterCreatorDragging>(); + grid = base.transform.GetChild(0).GetChild(0); + bar = base.transform.GetChild(0).GetChild(1); + } + + private void Update() + { + if (creator.playerActions != null) + { + PlayerActionUpdate(creator.playerActions.Device); + } + else if (creator.playerActions == null) + { + creator.currentControl = MenuControllerHandler.menuControl; + for (int i = 0; i < InputManager.ActiveDevices.Count; i++) + { + InputDevice device = InputManager.ActiveDevices[i]; + PlayerActionUpdate(device); + } + } + } + + private void PlayerActionUpdate(InputDevice device) + { + cd += Time.unscaledDeltaTime; + if (device != null) + { + if (device.CommandWasPressed) + { + creator.Finish(); + } + dragging.rightStick = device.RightStick.Value; + GridMovement(device); + BarMovement(device); + } + } + + private void BarMovement(InputDevice device) + { + if (!currentBarObject) + { + MoveNav(0); + } + if (device.LeftTrigger.WasPressed) + { + MoveNav(-1); + } + if (device.RightTrigger.WasPressed) + { + MoveNav(1); + } + } + + private void MoveNav(int delta) + { + cd = 0f; + if (delta > 0) + { + barPos++; + } + if (delta < 0) + { + barPos--; + } + VerifyBarPos(); + } + + private void VerifyBarPos() + { + if ((bool)currentBarObject) + { + currentBarObject.GetComponent<HoverEvent>().exitEvent.Invoke(); + } + barPos = Mathf.Clamp(barPos, 0, 3); + currentBarObject = bar.GetChild(barPos).gameObject; + currentBarObject.GetComponent<HoverEvent>().enterEvent.Invoke(); + currentBarObject.GetComponent<Button>().onClick.Invoke(); + } + + private void GridMovement(InputDevice device) + { + if (!currentObject) + { + MoveNav(Vector2.zero); + } + if (device.LeftStick.Value.magnitude > 0.75f && cd > 0.1f) + { + MoveNav(device.LeftStick); + } + if (device.Action1.WasPressed) + { + currentObject.GetComponent<Button>().onClick.Invoke(); + } + } + + private void MoveNav(Vector2 delta) + { + cd = 0f; + if (delta.x > 0.5f) + { + x++; + } + if (delta.x < -0.5f) + { + x--; + } + if (delta.y > 0.5f) + { + y--; + } + if (delta.y < -0.5f) + { + y++; + } + VerifyPos(); + } + + private void VerifyPos() + { + if ((bool)currentObject) + { + currentObject.GetComponent<HoverEvent>().exitEvent.Invoke(); + } + x = Mathf.Clamp(x, 1, itemsInRow); + y = Mathf.Clamp(y, 0, Mathf.CeilToInt((grid.childCount - 2) / itemsInRow)); + x = Mathf.Clamp(x, 1, grid.childCount - y * itemsInRow - 1); + int index = x + y * itemsInRow; + currentObject = grid.GetChild(index).gameObject; + currentObject.GetComponent<HoverEvent>().enterEvent.Invoke(); + } +} diff --git a/GameCode/CharacterCreatorPortrait.cs b/GameCode/CharacterCreatorPortrait.cs new file mode 100644 index 0000000..1c14cc2 --- /dev/null +++ b/GameCode/CharacterCreatorPortrait.cs @@ -0,0 +1,121 @@ +using System; +using InControl; +using UnityEngine; +using UnityEngine.UI; + +public class CharacterCreatorPortrait : MonoBehaviour +{ + public int playerId = -1; + + public PlayerFace myFace; + + public GameObject selectedObj; + + public MenuControllerHandler.MenuControl controlType = MenuControllerHandler.MenuControl.Unassigned; + + private Color defColor; + + private HoverEvent hoverEvent; + + public GameObject lockedObj; + + private bool isLocked; + + private void Start() + { + defColor = base.transform.Find("BG").GetComponent<Image>().color; + CharacterCreatorHandler instance = CharacterCreatorHandler.instance; + instance.faceWasUpdatedAction = (Action<int>)Delegate.Combine(instance.faceWasUpdatedAction, new Action<int>(FaceUpdated)); + myFace = CharacterCreatorHandler.instance.GetFacePreset(base.transform.GetSiblingIndex()); + hoverEvent = GetComponent<HoverEvent>(); + GetComponentInChildren<CharacterCreatorItemEquipper>().EquipFace(myFace); + if (CharacterCreatorHandler.instance.selectedFaceID[0] == base.transform.GetSiblingIndex()) + { + ClickButton(); + } + CharacterCreatorHandler instance2 = CharacterCreatorHandler.instance; + instance2.lockedPortraitAction = (Action)Delegate.Combine(instance2.lockedPortraitAction, new Action(CheckLocked)); + CheckLocked(); + } + + private void CheckLocked() + { + isLocked = false; + for (int i = 0; i < CharacterCreatorHandler.instance.lockedPortraits.Count; i++) + { + if (base.transform.GetSiblingIndex() == CharacterCreatorHandler.instance.lockedPortraits[i]) + { + isLocked = true; + } + } + if (isLocked) + { + lockedObj.SetActive(value: true); + } + else + { + lockedObj.SetActive(value: false); + } + } + + private void FaceUpdated(int faceID) + { + if (faceID == base.transform.GetSiblingIndex()) + { + myFace = CharacterCreatorHandler.instance.GetFacePreset(faceID); + GetComponent<CharacterCreatorItemEquipper>().EquipFace(myFace); + } + } + + public void ClickButton() + { + CharacterCreatorHandler.instance.SelectFace(Mathf.Clamp(playerId, 0, 10), myFace, base.transform.GetSiblingIndex()); + ShownFace(); + } + + private void ShownFace() + { + for (int i = 0; i < base.transform.parent.childCount; i++) + { + if (base.transform.parent.GetChild(i) == base.transform) + { + base.transform.parent.GetChild(i).Find("Frame").gameObject.SetActive(value: true); + } + else + { + base.transform.parent.GetChild(i).Find("Frame").gameObject.SetActive(value: false); + } + } + } + + public void EditCharacter() + { + if (!isLocked) + { + ClickButton(); + if (playerId == -1) + { + CharacterCreatorHandler.instance.EditCharacterPortrait(base.transform.GetSiblingIndex(), myFace); + return; + } + GameObject gameObject = base.transform.parent.parent.parent.gameObject; + gameObject.SetActive(value: false); + CharacterCreatorHandler.instance.EditCharacterLocalMultiplayer(playerId, base.transform.GetSiblingIndex(), gameObject, myFace); + } + } + + private void Update() + { + for (int i = 0; i < InputManager.ActiveDevices.Count; i++) + { + if (InputManager.ActiveDevices[i].Action4.WasPressed && hoverEvent.isSelected) + { + EditCharacter(); + } + } + if (Input.GetKeyDown(KeyCode.Mouse1) && controlType != 0 && hoverEvent.isHovered) + { + EditCharacter(); + } + } +} diff --git a/GameCode/CharacterData.cs b/GameCode/CharacterData.cs new file mode 100644 index 0000000..2f41ef3 --- /dev/null +++ b/GameCode/CharacterData.cs @@ -0,0 +1,291 @@ +using System; +using System.Collections.Generic; +using Photon.Pun; +using UnityEngine; + +public class CharacterData : MonoBehaviour +{ + public Vector3 aimDirection; + + public List<CardInfo> currentCards; + + public float sinceGroundedMultiplierWhenWallGrab = 0.2f; + + public PlayerActions playerActions; + + public ParticleSystem[] landParts; + + public int jumps = 1; + + public int currentJumps = 1; + + public bool isPlaying; + + public bool dead; + + public bool isStunned; + + public bool isSilenced; + + public float stunTime; + + public float silenceTime; + + public float health = 100f; + + public float maxHealth = 100f; + + public AnimationCurve slamCurve; + + public Vector3 wallPos; + + public Vector2 wallNormal; + + public Vector3 groundPos; + + public Transform hand; + + public float sinceWallGrab = float.PositiveInfinity; + + public bool isWallGrab; + + public float wallDistance = 1f; + + private bool wasWallGrabLastFrame; + + public float sinceGrounded; + + public bool isGrounded = true; + + private bool wasGroundedLastFrame = true; + + public Player player; + + public float sinceJump = 1f; + + public PlayerVelocity playerVel; + + public HealthHandler healthHandler; + + public GeneralInput input; + + public PlayerMovement movement; + + public PlayerJump jump; + + public Block block; + + public CharacterStatModifiers stats; + + public WeaponHandler weaponHandler; + + public StunHandler stunHandler; + + public SilenceHandler silenceHandler; + + public Player lastSourceOfDamage; + + public Player master; + + public Player lastDamagedPlayer; + + public Collider2D mainCol; + + public PlayerSounds playerSounds; + + private Transform wobblePos; + + private LayerMask groundMask; + + public PhotonView view; + + private CrownPos crownPos; + + public Rigidbody2D standOnRig; + + public Action<float, Vector3, Vector3, Transform> TouchGroundAction; + + public Action<float, Vector3, Vector3> TouchWallAction; + + public float HealthPercentage + { + get + { + return health / maxHealth; + } + internal set + { + } + } + + private void Awake() + { + crownPos = GetComponentInChildren<CrownPos>(); + view = GetComponent<PhotonView>(); + mainCol = GetComponent<Collider2D>(); + wobblePos = GetComponentInChildren<PlayerWobblePosition>().transform; + stats = GetComponent<CharacterStatModifiers>(); + player = GetComponent<Player>(); + weaponHandler = GetComponent<WeaponHandler>(); + block = GetComponent<Block>(); + input = GetComponent<GeneralInput>(); + movement = GetComponent<PlayerMovement>(); + jump = GetComponent<PlayerJump>(); + stunHandler = GetComponent<StunHandler>(); + silenceHandler = GetComponent<SilenceHandler>(); + hand = GetComponentInChildren<HandPos>().transform; + playerVel = GetComponent<PlayerVelocity>(); + healthHandler = GetComponent<HealthHandler>(); + playerSounds = GetComponent<PlayerSounds>(); + } + + internal Vector3 GetCrownPos() + { + if ((bool)crownPos) + { + return crownPos.transform.position + Vector3.up * crownPos.GetOffset(); + } + Debug.LogError("NO CROWN POS!?"); + return Vector3.up * 1000f; + } + + private void Start() + { + groundMask = LayerMask.GetMask("Default"); + if (!view.IsMine) + { + PlayerManager.RegisterPlayer(player); + } + } + + private void Update() + { + if (!playerVel.simulated) + { + sinceGrounded = 0f; + } + sinceJump += TimeHandler.deltaTime; + Wall(); + } + + private void FixedUpdate() + { + Ground(); + } + + private void Ground() + { + if (!isPlaying) + { + return; + } + if (!isGrounded) + { + sinceGrounded += TimeHandler.fixedDeltaTime * ((isWallGrab && wallDistance < 0.7f) ? sinceGroundedMultiplierWhenWallGrab : 1f); + if (sinceGrounded < 0f) + { + sinceGrounded = Mathf.Lerp(sinceGrounded, 0f, TimeHandler.fixedDeltaTime * 15f); + } + } + if (!wasGroundedLastFrame) + { + isGrounded = false; + } + wasGroundedLastFrame = false; + } + + private void Wall() + { + if (!isWallGrab) + { + sinceWallGrab += TimeHandler.deltaTime; + } + if (!wasWallGrabLastFrame) + { + isWallGrab = false; + } + wasWallGrabLastFrame = false; + } + + public void TouchGround(Vector3 pos, Vector3 groundNormal, Rigidbody2D groundRig, Transform groundTransform = null) + { + if (sinceJump > 0.2f) + { + currentJumps = jumps; + } + if (TouchGroundAction != null) + { + TouchGroundAction(sinceGrounded, pos, groundNormal, groundTransform); + } + if (groundRig == null) + { + standOnRig = null; + } + else if (!groundRig.GetComponent<NetworkPhysicsObject>()) + { + standOnRig = groundRig; + } + if (playerVel.velocity.y < -20f && !isGrounded) + { + for (int i = 0; i < landParts.Length; i++) + { + landParts[i].transform.localScale = Vector3.one * Mathf.Clamp((0f - playerVel.velocity.y) / 40f, 0.5f, 1f) * 0.5f; + landParts[i].transform.position = new Vector3(base.transform.position.x + playerVel.velocity.x * 0.03f, pos.y, 5f); + landParts[i].transform.rotation = Quaternion.LookRotation(groundNormal); + landParts[i].Play(); + } + GamefeelManager.instance.AddGameFeel(Vector2.down * Mathf.Clamp((sinceGrounded - 0.5f) * 1f, 0f, 4f)); + } + groundPos = pos; + wasGroundedLastFrame = true; + isGrounded = true; + sinceGrounded = 0f; + } + + public void TouchWall(Vector2 normal, Vector3 pos) + { + if (isGrounded) + { + return; + } + wallNormal = normal; + wallPos = pos; + groundPos = pos; + wallDistance = Vector2.Distance(base.transform.position, pos); + if (!(sinceJump < 0.15f)) + { + currentJumps = jumps; + if (TouchWallAction != null) + { + TouchWallAction(sinceWallGrab, pos, normal); + } + _ = sinceWallGrab; + _ = 0.15f; + sinceWallGrab = 0f; + wasWallGrabLastFrame = true; + isWallGrab = true; + } + } + + public bool ThereIsGroundBelow(Vector3 pos, float range = 5f) + { + RaycastHit2D raycastHit2D = Physics2D.Raycast(pos, Vector2.down, range, groundMask); + if ((bool)raycastHit2D.transform && raycastHit2D.distance > 0.1f) + { + return true; + } + return false; + } + + public void SetAI(Player aiMaster = null) + { + master = aiMaster; + input.controlledElseWhere = true; + GetComponent<PlayerAPI>().enabled = true; + } + + public void SetWobbleObjectChild(Transform obj) + { + obj.transform.SetParent(wobblePos, worldPositionStays: true); + } +} diff --git a/GameCode/CharacterItem.cs b/GameCode/CharacterItem.cs new file mode 100644 index 0000000..4588084 --- /dev/null +++ b/GameCode/CharacterItem.cs @@ -0,0 +1,42 @@ +using Sirenix.OdinInspector; +using UnityEngine; + +public class CharacterItem : MonoBehaviour +{ + public Sprite sprite; + + public float scale = 1f; + + public Vector2 offset = Vector2.zero; + + public CharacterItemType itemType; + + internal int slotNr; + + [ShowIf("itemType", CharacterItemType.Detail, true)] + public float moveHealthBarUp; + + [Button] + public void SaveTransform() + { + offset = base.transform.localPosition; + scale = base.transform.localScale.x; + } + + private void Start() + { + if (!base.transform.root.GetComponent<Player>()) + { + return; + } + base.gameObject.AddComponent<CharacterItemMirror>(); + if (moveHealthBarUp != 0f) + { + HealthBar componentInChildren = base.transform.root.GetComponentInChildren<HealthBar>(); + if ((bool)componentInChildren) + { + componentInChildren.transform.localPosition += Vector3.up * moveHealthBarUp; + } + } + } +} diff --git a/GameCode/CharacterItemButton.cs b/GameCode/CharacterItemButton.cs new file mode 100644 index 0000000..576dce0 --- /dev/null +++ b/GameCode/CharacterItemButton.cs @@ -0,0 +1,16 @@ +using SoundImplementation; +using UnityEngine; + +public class CharacterItemButton : MonoBehaviour +{ + public CharacterItemType itemType; + + public int slotNr; + + public void Click() + { + SoundPlayerStatic.Instance.PlayButtonClick(); + GetComponentInParent<CharacterCreatorItemEquipper>().Equip(base.gameObject.GetComponentInChildren<CharacterItem>(), itemType, Vector2.zero, slotNr); + GetComponentInParent<CharacterCreatorButtonSpawner>().SelectButton(itemType, slotNr); + } +} diff --git a/GameCode/CharacterItemMirror.cs b/GameCode/CharacterItemMirror.cs new file mode 100644 index 0000000..d3ff572 --- /dev/null +++ b/GameCode/CharacterItemMirror.cs @@ -0,0 +1,42 @@ +using UnityEngine; + +public class CharacterItemMirror : MonoBehaviour +{ + private float speedThreshol = 3f; + + private LeftRight leftRight; + + private Player player; + + private void Start() + { + player = GetComponentInParent<Player>(); + if (base.transform.localPosition.x > 0f) + { + leftRight = LeftRight.Right; + } + else + { + leftRight = LeftRight.Left; + } + } + + private void Update() + { + LeftRight leftRight = this.leftRight; + if (player.data.playerVel.velocity.x > speedThreshol) + { + leftRight = LeftRight.Right; + } + if (player.data.playerVel.velocity.x < 0f - speedThreshol) + { + leftRight = LeftRight.Left; + } + if (leftRight != this.leftRight) + { + base.transform.localPosition = new Vector3(base.transform.localPosition.x * -1f, base.transform.localPosition.y, base.transform.localPosition.z); + base.transform.localScale = new Vector3(base.transform.localScale.x * -1f, base.transform.localScale.y, base.transform.localScale.z); + this.leftRight = leftRight; + } + } +} diff --git a/GameCode/CharacterItemType.cs b/GameCode/CharacterItemType.cs new file mode 100644 index 0000000..395a8ab --- /dev/null +++ b/GameCode/CharacterItemType.cs @@ -0,0 +1,6 @@ +public enum CharacterItemType +{ + Eyes, + Mouth, + Detail +} diff --git a/GameCode/CharacterSelectionInstance.cs b/GameCode/CharacterSelectionInstance.cs new file mode 100644 index 0000000..dd11ab4 --- /dev/null +++ b/GameCode/CharacterSelectionInstance.cs @@ -0,0 +1,157 @@ +using TMPro; +using UnityEngine; +using UnityEngine.UI; + +public class CharacterSelectionInstance : MonoBehaviour +{ + public int currentlySelectedFace; + + public Player currentPlayer; + + public GameObject getReadyObj; + + private HoverEvent currentButton; + + private CharacterSelectionInstance[] selectors; + + private HoverEvent[] buttons; + + public bool isReady; + + private float counter; + + private void Start() + { + selectors = base.transform.parent.GetComponentsInChildren<CharacterSelectionInstance>(); + } + + public void ResetMenu() + { + base.transform.GetChild(0).gameObject.SetActive(value: false); + currentPlayer = null; + getReadyObj.gameObject.SetActive(value: false); + PlayerManager.instance.RemovePlayers(); + } + + private void OnEnable() + { + if (!base.transform.GetChild(0).gameObject.activeSelf) + { + GetComponentInChildren<GeneralParticleSystem>(includeInactive: true).gameObject.SetActive(value: true); + GetComponentInChildren<GeneralParticleSystem>(includeInactive: true).Play(); + } + } + + public void StartPicking(Player pickingPlayer) + { + currentPlayer = pickingPlayer; + currentlySelectedFace = 0; + GetComponentInChildren<GeneralParticleSystem>(includeInactive: true).gameObject.SetActive(value: false); + GetComponentInChildren<GeneralParticleSystem>(includeInactive: true).Stop(); + base.transform.GetChild(0).gameObject.SetActive(value: true); + getReadyObj.gameObject.SetActive(value: true); + if (currentPlayer.data.input.inputType == GeneralInput.InputType.Keyboard) + { + getReadyObj.GetComponent<TextMeshProUGUI>().text = "PRESS [SPACE] WHEN READY"; + } + else + { + getReadyObj.GetComponent<TextMeshProUGUI>().text = "PRESS [START] WHEN READY"; + } + buttons = base.transform.GetComponentsInChildren<HoverEvent>(); + for (int i = 0; i < buttons.Length; i++) + { + if (pickingPlayer.data.input.inputType == GeneralInput.InputType.Controller) + { + buttons[i].enabled = false; + buttons[i].GetComponent<Button>().interactable = false; + buttons[i].GetComponent<CharacterCreatorPortrait>().controlType = MenuControllerHandler.MenuControl.Controller; + continue; + } + buttons[i].enabled = true; + buttons[i].GetComponent<Button>().interactable = true; + buttons[i].GetComponent<CharacterCreatorPortrait>().controlType = MenuControllerHandler.MenuControl.Mouse; + Navigation navigation = buttons[i].GetComponent<Button>().navigation; + navigation.mode = Navigation.Mode.None; + buttons[i].GetComponent<Button>().navigation = navigation; + } + } + + public void ReadyUp() + { + isReady = !isReady; + bool flag = true; + for (int i = 0; i < selectors.Length; i++) + { + if (!selectors[i].isReady) + { + flag = false; + } + } + if (flag) + { + MainMenuHandler.instance.Close(); + GM_ArmsRace.instance.StartGame(); + } + if (currentPlayer.data.input.inputType == GeneralInput.InputType.Keyboard) + { + getReadyObj.GetComponent<TextMeshProUGUI>().text = (isReady ? "READY" : "PRESS [SPACE] WHEN READY"); + } + else + { + getReadyObj.GetComponent<TextMeshProUGUI>().text = (isReady ? "READY" : "PRESS [START] WHEN READY"); + } + } + + private void Update() + { + if (!currentPlayer) + { + return; + } + if (currentPlayer.data.input.inputType != 0) + { + if (Input.GetKeyDown(KeyCode.Space)) + { + ReadyUp(); + } + return; + } + if (currentPlayer.data.playerActions.Device.CommandWasPressed) + { + ReadyUp(); + } + HoverEvent component = buttons[currentlySelectedFace].GetComponent<HoverEvent>(); + if (currentButton != component) + { + if ((bool)currentButton) + { + currentButton.GetComponent<SimulatedSelection>().Deselect(); + } + currentButton = component; + currentButton.GetComponent<SimulatedSelection>().Select(); + } + counter += Time.deltaTime; + if (Mathf.Abs(currentPlayer.data.playerActions.Move.X) > 0.5f && counter > 0.2f) + { + if (currentPlayer.data.playerActions.Move.X > 0.5f) + { + currentlySelectedFace++; + } + else + { + currentlySelectedFace--; + } + counter = 0f; + } + if (currentPlayer.data.playerActions.Jump.WasPressed) + { + currentButton.GetComponent<Button>().onClick.Invoke(); + } + if (currentPlayer.data.playerActions.Device.Action4.WasPressed) + { + currentButton.GetComponent<CharacterCreatorPortrait>().EditCharacter(); + } + currentlySelectedFace = Mathf.Clamp(currentlySelectedFace, 0, buttons.Length - 1); + } +} diff --git a/GameCode/CharacterSelectionMenu.cs b/GameCode/CharacterSelectionMenu.cs new file mode 100644 index 0000000..ed6c36a --- /dev/null +++ b/GameCode/CharacterSelectionMenu.cs @@ -0,0 +1,21 @@ +using System; +using UnityEngine; + +public class CharacterSelectionMenu : MonoBehaviour +{ + private void Start() + { + PlayerManager instance = PlayerManager.instance; + instance.PlayerJoinedAction = (Action<Player>)Delegate.Combine(instance.PlayerJoinedAction, new Action<Player>(PlayerJoined)); + } + + private void PlayerJoined(Player joinedPlayer) + { + base.transform.GetChild(0).GetChild(PlayerManager.instance.players.Count - 1).GetComponent<CharacterSelectionInstance>() + .StartPicking(joinedPlayer); + } + + private void Update() + { + } +} diff --git a/GameCode/CharacterStatModifiers.cs b/GameCode/CharacterStatModifiers.cs new file mode 100644 index 0000000..9122d66 --- /dev/null +++ b/GameCode/CharacterStatModifiers.cs @@ -0,0 +1,281 @@ +using System; +using System.Collections.Generic; +using Photon.Pun; +using Sonigon; +using UnityEngine; + +public class CharacterStatModifiers : MonoBehaviour +{ + [Header("Sounds")] + public SoundEvent soundCharacterSlowFreeze; + + private float soundSlowTime; + + private float soundSlowSpeedSec = 0.3f; + + [Header("Settings")] + public GameObject AddObjectToPlayer; + + [HideInInspector] + public List<GameObject> objectsAddedToPlayer; + + [Header("Multiply")] + public float sizeMultiplier = 1f; + + public float health = 1f; + + public float movementSpeed = 1f; + + public float jump = 1f; + + public float gravity = 1f; + + public float slow; + + public float slowSlow; + + public float fastSlow; + + [Header("Add")] + public float secondsToTakeDamageOver; + + public int numberOfJumps; + + public float regen; + + public float lifeSteal; + + public bool refreshOnDamage; + + public bool automaticReload = true; + + public int respawns; + + [HideInInspector] + public int remainingRespawns; + + [HideInInspector] + public float tasteOfBloodSpeed = 1f; + + [HideInInspector] + public float rageSpeed = 1f; + + public float attackSpeedMultiplier = 1f; + + private WasDealtDamageEffect[] wasDealtDamageEffects; + + private DealtDamageEffect[] dealtDamageEffects; + + private CharacterData data; + + public ParticleSystem slowPart; + + private float soundBigThreshold = 1.5f; + + public Action<Vector2, bool> DealtDamageAction; + + public Action<Vector2, bool> WasDealtDamageAction; + + public Action<int> OnReloadDoneAction; + + public Action<int> OutOfAmmpAction; + + internal float sinceDealtDamage; + + public bool SoundTransformScaleThresholdReached() + { + if (base.transform.localScale.x > soundBigThreshold) + { + return true; + } + return false; + } + + private void Start() + { + data = GetComponent<CharacterData>(); + } + + public float GetSlow() + { + return Mathf.Clamp(slow, 0f, 0.9f); + } + + private void Update() + { + attackSpeedMultiplier = tasteOfBloodSpeed * rageSpeed; + sinceDealtDamage += TimeHandler.deltaTime; + if ((bool)data && !data.isPlaying) + { + sinceDealtDamage = 100f; + } + slow = slowSlow; + if (fastSlow > slowSlow) + { + slow = fastSlow; + } + if (slowSlow > 0f) + { + slowSlow = Mathf.Clamp(slowSlow - TimeHandler.deltaTime * 0.3f, 0f, 10f); + } + if (fastSlow > 0f) + { + fastSlow = Mathf.Clamp(fastSlow - TimeHandler.deltaTime * 2f, 0f, 1f); + } + } + + public void DealtDamage(Vector2 damage, bool selfDamage, Player damagedPlayer = null) + { + if (lifeSteal != 0f && !selfDamage) + { + GetComponent<HealthHandler>().Heal(damage.magnitude * lifeSteal); + } + if (refreshOnDamage) + { + GetComponent<Holding>().holdable.GetComponent<Weapon>().sinceAttack = float.PositiveInfinity; + } + if (DealtDamageAction != null) + { + DealtDamageAction(damage, selfDamage); + } + if ((bool)damagedPlayer) + { + data.lastDamagedPlayer = damagedPlayer; + } + if (!selfDamage) + { + sinceDealtDamage = 0f; + } + if (dealtDamageEffects != null) + { + for (int i = 0; i < dealtDamageEffects.Length; i++) + { + dealtDamageEffects[i].DealtDamage(damage, selfDamage, damagedPlayer); + } + } + } + + internal void ResetStats() + { + for (int i = 0; i < objectsAddedToPlayer.Count; i++) + { + UnityEngine.Object.Destroy(objectsAddedToPlayer[i]); + } + objectsAddedToPlayer.Clear(); + data.health = 100f; + data.maxHealth = 100f; + sizeMultiplier = 1f; + health = 1f; + movementSpeed = 1f; + jump = 1f; + gravity = 1f; + slow = 0f; + slowSlow = 0f; + fastSlow = 0f; + secondsToTakeDamageOver = 0f; + numberOfJumps = 0; + regen = 0f; + lifeSteal = 0f; + respawns = 0; + refreshOnDamage = false; + automaticReload = true; + tasteOfBloodSpeed = 1f; + rageSpeed = 1f; + attackSpeedMultiplier = 1f; + WasUpdated(); + ConfigureMassAndSize(); + } + + public void WasDealtDamage(Vector2 damage, bool selfDamage) + { + if (WasDealtDamageAction != null) + { + WasDealtDamageAction(damage, selfDamage); + } + if (wasDealtDamageEffects != null) + { + for (int i = 0; i < wasDealtDamageEffects.Length; i++) + { + wasDealtDamageEffects[i].WasDealtDamage(damage, selfDamage); + } + } + } + + public void WasUpdated() + { + GetComponent<ForceMultiplier>().multiplier = 1f / base.transform.root.localScale.x; + wasDealtDamageEffects = GetComponentsInChildren<WasDealtDamageEffect>(); + dealtDamageEffects = GetComponentsInChildren<DealtDamageEffect>(); + } + + public void AddSlowAddative(float slowToAdd, float maxValue = 1f, bool isFastSlow = false) + { + if (data.block.IsBlocking()) + { + return; + } + DoSlowDown(slowToAdd); + if (isFastSlow) + { + if (fastSlow < maxValue) + { + fastSlow += slowToAdd; + fastSlow = Mathf.Clamp(slow, 0f, maxValue); + } + } + else if (slowSlow < maxValue) + { + slowSlow += slowToAdd; + slowSlow = Mathf.Clamp(slowSlow, 0f, maxValue); + } + } + + [PunRPC] + public void RPCA_AddSlow(float slowToAdd, bool isFastSlow = false) + { + DoSlowDown(slowToAdd); + if (isFastSlow) + { + fastSlow = Mathf.Clamp(fastSlow, slowToAdd, 1f); + } + else + { + slowSlow = Mathf.Clamp(slowSlow, slowToAdd, 10f); + } + } + + private void DoSlowDown(float newSlow) + { + if (soundSlowTime + soundSlowSpeedSec < Time.time) + { + soundSlowTime = Time.time; + SoundManager.Instance.Play(soundCharacterSlowFreeze, base.transform); + } + float num = Mathf.Clamp(newSlow - slow, 0f, 1f); + slowPart.Emit((int)Mathf.Clamp((newSlow * 0.1f + num * 0.7f) * 50f, 1f, 50f)); + data.playerVel.velocity *= 1f - num * 1f; + data.sinceGrounded *= 1f - num * 1f; + } + + internal void ConfigureMassAndSize() + { + base.transform.localScale = Vector3.one * 1.2f * Mathf.Pow(data.maxHealth / 100f * 1.2f, 0.2f) * sizeMultiplier; + data.playerVel.mass = 100f * Mathf.Pow(data.maxHealth / 100f * 1.2f, 0.8f) * sizeMultiplier; + } + + internal void OnReload(int bulletsReloaded) + { + if (OnReloadDoneAction != null) + { + OnReloadDoneAction(bulletsReloaded); + } + } + + internal void OnOutOfAmmp(int maxAmmo) + { + if (OutOfAmmpAction != null) + { + OutOfAmmpAction(maxAmmo); + } + } +} diff --git a/GameCode/ChargeFeedback.cs b/GameCode/ChargeFeedback.cs new file mode 100644 index 0000000..322fe89 --- /dev/null +++ b/GameCode/ChargeFeedback.cs @@ -0,0 +1,44 @@ +using UnityEngine; + +public class ChargeFeedback : MonoBehaviour +{ + private Gun gun; + + public float drag = 1f; + + public float spring = 1f; + + public float angle = 45f; + + public float chargeAngle = 15f; + + private float currentAngle; + + private float velocity; + + public float charge; + + private void Start() + { + gun = GetComponentInParent<Gun>(); + gun.AddAttackAction(Shoot); + } + + private void Update() + { + charge = 0f; + if (!gun.IsReady(0.15f)) + { + charge = 1f; + } + velocity += (charge * chargeAngle - currentAngle) * CappedDeltaTime.time * spring; + velocity -= velocity * CappedDeltaTime.time * drag; + currentAngle += CappedDeltaTime.time * velocity; + base.transform.localEulerAngles = new Vector3(currentAngle, 0f, 0f); + } + + public void Shoot() + { + velocity += (0f - angle) * 1000f * (gun.damage / 55f); + } +} diff --git a/GameCode/Chase.cs b/GameCode/Chase.cs new file mode 100644 index 0000000..1101987 --- /dev/null +++ b/GameCode/Chase.cs @@ -0,0 +1,62 @@ +using UnityEngine; +using UnityEngine.Events; + +public class Chase : MonoBehaviour +{ + public UnityEvent turnOnEvent; + + public UnityEvent turnOffEvent; + + public UnityEvent switchTargetEvent; + + private Player player; + + private LineEffect lineEffect; + + private bool isOn; + + private Player currentTarget; + + private void Start() + { + lineEffect = GetComponentInChildren<LineEffect>(includeInactive: true); + player = GetComponentInParent<Player>(); + } + + private void Update() + { + Player player = PlayerManager.instance.GetClosestPlayerInTeam(base.transform.position, PlayerManager.instance.GetOtherTeam(this.player.teamID), needVision: true); + if ((bool)player && (Vector2.Angle(player.transform.position - base.transform.position, this.player.data.input.direction) > 70f || this.player.data.input.direction == Vector3.zero)) + { + player = null; + } + if ((bool)player) + { + if (currentTarget != this.player) + { + currentTarget = this.player; + switchTargetEvent.Invoke(); + lineEffect.Play(base.transform, player.transform); + } + if (!isOn) + { + isOn = true; + turnOnEvent.Invoke(); + } + } + else + { + if (isOn) + { + isOn = false; + turnOffEvent.Invoke(); + } + if (lineEffect.isPlaying) + { + lineEffect.Stop(); + lineEffect.gameObject.SetActive(value: false); + } + currentTarget = null; + } + } +} diff --git a/GameCode/ChatFilter.cs b/GameCode/ChatFilter.cs new file mode 100644 index 0000000..91b8c96 --- /dev/null +++ b/GameCode/ChatFilter.cs @@ -0,0 +1,75 @@ +using Sirenix.OdinInspector; +using UnityEngine; + +public class ChatFilter : MonoBehaviour +{ + [TextArea] + public string enterData; + + public string category; + + public static ChatFilter instance; + + public ChatFilterInstance[] filters; + + private void Awake() + { + instance = this; + } + + [Button] + private void EnterData() + { + string[] array = enterData.Replace('"', ' ').Trim().Split(','); + ChatFilterInstance chatFilterInstance = null; + for (int i = 0; i < filters.Length; i++) + { + if (filters[i].category == category) + { + chatFilterInstance = filters[i]; + break; + } + } + if (chatFilterInstance == null) + { + UnityEngine.Debug.LogError("No valid category target!"); + return; + } + for (int j = 0; j < array.Length; j++) + { + array[j] = array[j].Trim(); + array[j] = array[j].ToUpper(); + if (array[j] == "") + { + continue; + } + bool flag = false; + for (int k = 0; k < chatFilterInstance.words.Count; k++) + { + if (chatFilterInstance.words[k] == array[j]) + { + flag = true; + } + } + if (!flag) + { + chatFilterInstance.words.Add(array[j]); + } + } + } + + public string FilterMessage(string message) + { + for (int i = 0; i < filters.Length; i++) + { + for (int j = 0; j < filters[i].words.Count; j++) + { + if (message.ToUpper().Contains(filters[i].words[j])) + { + return filters[i].replacement; + } + } + } + return message; + } +} diff --git a/GameCode/ChatFilterInstance.cs b/GameCode/ChatFilterInstance.cs new file mode 100644 index 0000000..ef6d153 --- /dev/null +++ b/GameCode/ChatFilterInstance.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +[Serializable] +public class ChatFilterInstance +{ + public List<string> words = new List<string>(); + + public string category; + + [TextArea] + public string replacement; +} diff --git a/GameCode/ChildRPC.cs b/GameCode/ChildRPC.cs new file mode 100644 index 0000000..1305ce1 --- /dev/null +++ b/GameCode/ChildRPC.cs @@ -0,0 +1,110 @@ +using System; +using System.Collections.Generic; +using Photon.Pun; +using UnityEngine; + +public class ChildRPC : MonoBehaviour +{ + public Dictionary<string, Action<Vector2, Vector2, int>> childRPCsVector2Vector2Int = new Dictionary<string, Action<Vector2, Vector2, int>>(); + + public Dictionary<string, Action<Vector2, Vector2, int, int>> childRPCsVector2Vector2IntInt = new Dictionary<string, Action<Vector2, Vector2, int, int>>(); + + public Dictionary<string, Action<Vector2>> childRPCsVector2 = new Dictionary<string, Action<Vector2>>(); + + public Dictionary<string, Action<Vector3, Quaternion>> childRPCsVector3Quaternion = new Dictionary<string, Action<Vector3, Quaternion>>(); + + public Dictionary<string, Action<int>> childRPCsInt = new Dictionary<string, Action<int>>(); + + public Dictionary<string, Action> childRPCs = new Dictionary<string, Action>(); + + private PhotonView view; + + private void Start() + { + view = GetComponent<PhotonView>(); + } + + public void CallFunction(string key) + { + view.RPC("RPCA_RecieveFunction", RpcTarget.All, key); + } + + [PunRPC] + public void RPCA_RecieveFunction(string key) + { + if (childRPCs.ContainsKey(key)) + { + childRPCs[key](); + } + } + + public void CallFunction(string key, int intData) + { + view.RPC("RPCA_RecieveFunction", RpcTarget.All, key, intData); + } + + [PunRPC] + public void RPCA_RecieveFunction(string key, int intData) + { + if (childRPCsInt.ContainsKey(key)) + { + childRPCsInt[key](intData); + } + } + + public void CallFunction(string key, Vector2 vectorData) + { + view.RPC("RPCA_RecieveFunction", RpcTarget.All, key, vectorData); + } + + [PunRPC] + public void RPCA_RecieveFunction(string key, Vector2 vectorData) + { + if (childRPCsVector2.ContainsKey(key)) + { + childRPCsVector2[key](vectorData); + } + } + + public void CallFunction(string key, Vector2 vectorData, Vector2 vectorData2, int intData) + { + view.RPC("RPCA_RecieveFunction", RpcTarget.All, key, vectorData, vectorData2, intData); + } + + [PunRPC] + public void RPCA_RecieveFunction(string key, Vector2 vectorData, Vector2 vectorData2, int intData) + { + if (childRPCsVector2Vector2Int.ContainsKey(key)) + { + childRPCsVector2Vector2Int[key](vectorData, vectorData2, intData); + } + } + + public void CallFunction(string key, Vector2 vectorData, Vector2 vectorData2, int intData, int intData2) + { + view.RPC("RPCA_RecieveFunction", RpcTarget.All, key, vectorData, vectorData2, intData, intData2); + } + + [PunRPC] + public void RPCA_RecieveFunction(string key, Vector2 vectorData, Vector2 vectorData2, int intData, int intData2) + { + if (childRPCsVector2Vector2IntInt.ContainsKey(key)) + { + childRPCsVector2Vector2IntInt[key](vectorData, vectorData2, intData, intData2); + } + } + + public void CallFunction(string key, Vector3 vectorData, Quaternion quaterion) + { + view.RPC("RPCA_RecieveFunction", RpcTarget.All, key, vectorData, quaterion); + } + + [PunRPC] + public void RPCA_RecieveFunction(string key, Vector3 vectorData, Quaternion quaterion) + { + if (childRPCsVector3Quaternion.ContainsKey(key)) + { + childRPCsVector3Quaternion[key](vectorData, quaterion); + } + } +} diff --git a/GameCode/ChillingTouch.cs b/GameCode/ChillingTouch.cs new file mode 100644 index 0000000..487ab51 --- /dev/null +++ b/GameCode/ChillingTouch.cs @@ -0,0 +1,20 @@ +using UnityEngine; + +public class ChillingTouch : DamageEffect +{ + public float baseSlow = 0.2f; + + public float scalingSlow = 0.01f; + + private AttackLevel level; + + private void Start() + { + level = GetComponent<AttackLevel>(); + } + + public override void DoDamageEffect(Vector2 dmg, bool selfDmg, Player damagedPlayer = null) + { + damagedPlayer.data.stats.RPCA_AddSlow((baseSlow + dmg.magnitude * scalingSlow) * (1f + ((float)level.attackLevel - 1f) * 0.3f)); + } +} diff --git a/GameCode/ChomaticAberrationFeeler.cs b/GameCode/ChomaticAberrationFeeler.cs new file mode 100644 index 0000000..ebe7c16 --- /dev/null +++ b/GameCode/ChomaticAberrationFeeler.cs @@ -0,0 +1,63 @@ +using UnityEngine; +using UnityEngine.Rendering.PostProcessing; + +public class ChomaticAberrationFeeler : GameFeeler +{ + public float force = 10f; + + public float damper = 0.95f; + + public float damperSpring = 0.95f; + + public float threshold; + + private PostProcessVolume postProcessVolume; + + private ChromaticAberration chromaticAberration; + + private float intensity; + + private float velocity; + + private float targetIntensity; + + public override void OnAwake() + { + postProcessVolume = GetComponent<PostProcessVolume>(); + if (!postProcessVolume.profile.TryGetSettings<ChromaticAberration>(out chromaticAberration)) + { + Debug.LogError("No ChromaticAberration in post!"); + } + else + { + targetIntensity = chromaticAberration.intensity.value; + } + } + + public override void OnGameFeel(Vector2 feelDirection) + { + feelDirection = Vector2.ClampMagnitude(feelDirection, 50f); + if (feelDirection.magnitude < threshold) + { + feelDirection = feelDirection.normalized * threshold * 0.3f; + } + velocity += feelDirection.sqrMagnitude * 0.2f * force; + } + + private void Update() + { + velocity *= damper; + intensity *= damperSpring; + intensity += velocity * Mathf.Clamp(TimeHandler.deltaTime, 0f, 0.02f); + chromaticAberration.intensity.value = intensity + targetIntensity; + } + + private void FixedUpdate() + { + intensity *= 0.9f; + } + + public override void OnUIGameFeel(Vector2 feelDirection) + { + } +} diff --git a/GameCode/Cluster.cs b/GameCode/Cluster.cs new file mode 100644 index 0000000..2e5c648 --- /dev/null +++ b/GameCode/Cluster.cs @@ -0,0 +1,46 @@ +using UnityEngine; + +public class Cluster : MonoBehaviour +{ + public float distanceToTravel = 8f; + + public float spread; + + public float velocitySpread; + + public int clusters = 3; + + private MoveTransform move; + + private void Start() + { + move = GetComponentInParent<MoveTransform>(); + } + + private void Update() + { + if (!(move.distanceTravelled > distanceToTravel)) + { + return; + } + for (int i = 0; i < clusters; i++) + { + GameObject obj = Object.Instantiate(base.transform.root.gameObject, base.transform.root.position, base.transform.root.rotation); + Cluster componentInChildren = obj.GetComponentInChildren<Cluster>(); + if ((bool)componentInChildren) + { + Object.Destroy(componentInChildren); + } + MoveTransform component = obj.GetComponent<MoveTransform>(); + if ((bool)component) + { + component.DontRunStart = true; + component.velocity = base.transform.root.GetComponent<MoveTransform>().velocity; + component.multiplier = base.transform.root.GetComponent<MoveTransform>().multiplier; + component.velocity += base.transform.right * Random.Range(0f - spread, spread); + component.velocity *= Random.Range(1f - velocitySpread * 0.01f, 1f + velocitySpread * 0.01f); + } + } + Object.Destroy(this); + } +} diff --git a/GameCode/CodeAnimation.cs b/GameCode/CodeAnimation.cs new file mode 100644 index 0000000..ae132b3 --- /dev/null +++ b/GameCode/CodeAnimation.cs @@ -0,0 +1,205 @@ +using System; +using System.Collections; +using Sirenix.OdinInspector; +using UnityEngine; +using UnityEngine.Events; + +public class CodeAnimation : MonoBehaviour +{ + [HideInInspector] + public bool isPlaying; + + public bool loonIn; + + public bool playInOnAwake; + + public bool playInOnEnable; + + public float enablePlayDelay; + + public bool interuptAnimations = true; + + public bool setFirstFrame; + + public bool useTimeScale = true; + + private Vector3 defaultScale; + + private Vector3 defaultLocalPosition; + + private Vector3 defaultRectPosition; + + private Vector3 defaultLocalRotation; + + public CodeAnimationInstance[] animations; + + private RectTransform rectTransform; + + [HideInInspector] + public CodeAnimationInstance.AnimationUse currentState; + + [HideInInspector] + public float animationValue; + + private Action AnimationChangeAction; + + public void Start() + { + currentState = CodeAnimationInstance.AnimationUse.None; + rectTransform = GetComponent<RectTransform>(); + for (int i = 0; i < animations.Length; i++) + { + animations[i].animationSpeed += UnityEngine.Random.Range((0f - animations[i].animationSpeed) * animations[i].randomSpeedAmount, animations[i].animationSpeed * animations[i].randomSpeedAmount); + if (animations[i].animationUse == CodeAnimationInstance.AnimationUse.In) + { + float num = animations[i].curve[animations[i].curve.length - 1].value - animations[i].curve[0].value; + if ((bool)rectTransform && animations[i].animationType == CodeAnimationInstance.AnimationType.rectPosition) + { + rectTransform.anchoredPosition += num * (Vector2)animations[i].direction * (0f - animations[i].multiplier); + } + } + } + SetDefaults(); + if (playInOnAwake) + { + PlayIn(); + } + if (setFirstFrame) + { + ApplyValues(animations[0], 0f); + } + } + + private void OnEnable() + { + if (playInOnEnable) + { + StartCoroutine(DelayEnablePlay()); + } + } + + private IEnumerator DelayEnablePlay() + { + yield return new WaitForSecondsRealtime(enablePlayDelay); + PlayIn(); + } + + private void SetDefaults() + { + defaultScale = base.transform.localScale; + defaultLocalPosition = base.transform.localPosition; + defaultLocalRotation = base.transform.localRotation.eulerAngles; + if ((bool)rectTransform) + { + defaultRectPosition = rectTransform.anchoredPosition; + } + } + + public void Animate(CodeAnimationInstance.AnimationUse use) + { + currentState = use; + if (interuptAnimations) + { + StopAllCoroutines(); + } + for (int i = 0; i < animations.Length; i++) + { + if (animations[i].animationUse == use) + { + StartCoroutine(PlayAnimations(animations[i])); + } + } + } + + [Button] + public void PlayIn() + { + Animate(CodeAnimationInstance.AnimationUse.In); + } + + [Button] + public void PlayOut() + { + Animate(CodeAnimationInstance.AnimationUse.Out); + } + + [Button] + public void PlayBoop() + { + Animate(CodeAnimationInstance.AnimationUse.Boop); + } + + private IEnumerator PlayAnimations(CodeAnimationInstance animation) + { + isPlaying = true; + animation.startEvent.Invoke(); + StartCoroutine(DelayTimedEvent(animation.eventTiming / animation.animationSpeed, animation.timedEvent)); + float t = animation.curve.keys[animation.curve.keys.Length - 1].time; + float c = 0f; + while (c < t) + { + ApplyValues(animation, c); + c += (useTimeScale ? TimeHandler.deltaTime : Time.unscaledDeltaTime) * animation.animationSpeed; + yield return null; + } + ApplyValues(animation, t); + isPlaying = false; + animation.endEvent.Invoke(); + if (loonIn) + { + PlayIn(); + } + } + + private void ApplyValues(CodeAnimationInstance animation, float time) + { + if (animation.animationType == CodeAnimationInstance.AnimationType.rectPosition && (bool)rectTransform) + { + rectTransform.anchoredPosition = defaultRectPosition + animation.direction * animation.curve.Evaluate(time) * animation.multiplier; + } + if (animation.animationType == CodeAnimationInstance.AnimationType.position) + { + base.transform.localPosition = defaultLocalPosition + animation.direction * animation.curve.Evaluate(time) * animation.multiplier; + } + if (animation.animationType == CodeAnimationInstance.AnimationType.scale) + { + Vector3 localScale = defaultScale * animation.curve.Evaluate(time) * animation.multiplier; + if (!animation.X) + { + localScale.x = base.transform.localScale.x; + } + if (!animation.Y) + { + localScale.y = base.transform.localScale.y; + } + if (!animation.Z) + { + localScale.z = base.transform.localScale.z; + } + base.transform.localScale = localScale; + } + if (animation.animationType == CodeAnimationInstance.AnimationType.floatNumber) + { + animationValue = animation.curve.Evaluate(time) * animation.multiplier; + } + if (animation.animationType == CodeAnimationInstance.AnimationType.rotation) + { + base.transform.localRotation = Quaternion.Euler(animation.curve.Evaluate(time) * animation.direction + defaultLocalRotation); + } + if (AnimationChangeAction != null) + { + AnimationChangeAction(); + } + } + + public void AddAnimationChangeAction(Action action) + { + AnimationChangeAction = (Action)Delegate.Combine(AnimationChangeAction, action); + } + + private IEnumerator DelayTimedEvent(float time, UnityEvent eventToCall) + { + yield return new WaitForSeconds(time); + eventToCall.Invoke(); + } +} diff --git a/GameCode/CodeAnimationInstance.cs b/GameCode/CodeAnimationInstance.cs new file mode 100644 index 0000000..be847e3 --- /dev/null +++ b/GameCode/CodeAnimationInstance.cs @@ -0,0 +1,62 @@ +using System; +using Sirenix.OdinInspector; +using UnityEngine; +using UnityEngine.Events; + +[Serializable] +public class CodeAnimationInstance +{ + public enum AnimationType + { + position, + scale, + rectPosition, + floatNumber, + rotation + } + + public enum AnimationUse + { + In, + Out, + None, + Boop + } + + public float animationSpeed = 1f; + + [FoldoutGroup("Random", 0)] + public float randomSpeedAmount; + + [FoldoutGroup("USE", 0)] + public bool X = true; + + [FoldoutGroup("USE", 0)] + public bool Y = true; + + [FoldoutGroup("USE", 0)] + public bool Z = true; + + [Space(15f)] + public AnimationType animationType; + + public AnimationUse animationUse; + + public AnimationCurve curve; + + public float multiplier = 1f; + + public Vector3 direction; + + [FoldoutGroup("Events", 0)] + public UnityEvent startEvent; + + [FoldoutGroup("Events", 0)] + public UnityEvent timedEvent; + + [FoldoutGroup("Events", 0)] + public float eventTiming; + + [FoldoutGroup("Events", 0)] + public UnityEvent endEvent; +} diff --git a/GameCode/CollisionChecker.cs b/GameCode/CollisionChecker.cs new file mode 100644 index 0000000..a344911 --- /dev/null +++ b/GameCode/CollisionChecker.cs @@ -0,0 +1,41 @@ +using System; +using UnityEngine; + +public class CollisionChecker : MonoBehaviour +{ + private CharacterData data; + + public Action<Collision2D> collisionAction; + + private void Awake() + { + data = GetComponent<CharacterData>(); + } + + private void OnCollisionEnter2D(Collision2D collision) + { + Collide(collision); + } + + private void OnCollisionStay2D(Collision2D collision) + { + Collide(collision); + } + + private void Collide(Collision2D collision) + { + if (collisionAction != null) + { + collisionAction(collision); + } + if (Vector3.Angle(Vector3.up, collision.contacts[0].normal) > 70f) + { + Vector3.Angle(Vector3.up, collision.contacts[0].normal); + _ = 110f; + } + else + { + data.TouchGround(collision.contacts[0].point, collision.contacts[0].normal, collision.otherRigidbody, collision.transform); + } + } +} diff --git a/GameCode/ColorBlink.cs b/GameCode/ColorBlink.cs new file mode 100644 index 0000000..35ebf03 --- /dev/null +++ b/GameCode/ColorBlink.cs @@ -0,0 +1,42 @@ +using System.Collections; +using UnityEngine; + +public class ColorBlink : MonoBehaviour +{ + public Color blinkColor; + + public float timeAmount; + + private Color defaultColor; + + private SpriteRenderer sprite; + + private bool inited; + + private void Start() + { + if (!inited) + { + inited = true; + sprite = GetComponent<SpriteRenderer>(); + defaultColor = sprite.color; + } + } + + public void DoBlink() + { + StopAllCoroutines(); + StartCoroutine(IDoBlink()); + } + + private IEnumerator IDoBlink() + { + if (!sprite) + { + Start(); + } + sprite.color = blinkColor; + yield return new WaitForSeconds(timeAmount); + sprite.color = defaultColor; + } +} diff --git a/GameCode/ColorHandler.cs b/GameCode/ColorHandler.cs new file mode 100644 index 0000000..b185b72 --- /dev/null +++ b/GameCode/ColorHandler.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; +using Sirenix.OdinInspector; +using UnityEngine; + +public class ColorHandler : SerializedMonoBehaviour +{ + public enum ColorType + { + PhysicsObject + } + + public Dictionary<ColorType, Color> colors = new Dictionary<ColorType, Color>(); + + public static ColorHandler instance; + + private void Awake() + { + instance = this; + } + + public Color GetColor(ColorType colorType) + { + return colors[colorType]; + } +} diff --git a/GameCode/Comment.cs b/GameCode/Comment.cs new file mode 100644 index 0000000..020c8e3 --- /dev/null +++ b/GameCode/Comment.cs @@ -0,0 +1,7 @@ +using UnityEngine; + +public class Comment : MonoBehaviour +{ + [TextArea(20, 100)] + public string comment; +} diff --git a/GameCode/Connected.cs b/GameCode/Connected.cs new file mode 100644 index 0000000..4ccc116 --- /dev/null +++ b/GameCode/Connected.cs @@ -0,0 +1 @@ +public delegate void Connected(); diff --git a/GameCode/ControllerImageToggler.cs b/GameCode/ControllerImageToggler.cs new file mode 100644 index 0000000..22463f4 --- /dev/null +++ b/GameCode/ControllerImageToggler.cs @@ -0,0 +1,71 @@ +using System; +using UnityEngine; +using UnityEngine.UI; + +public class ControllerImageToggler : MonoBehaviour +{ + public Sprite MKSprite; + + public Sprite controllerSprite; + + private Image img; + + private CharacterCreatorPortrait portrait; + + private CharacterSelectionInstance selector; + + private void Awake() + { + selector = GetComponentInParent<CharacterSelectionInstance>(); + portrait = GetComponentInParent<CharacterCreatorPortrait>(); + if ((bool)portrait && portrait.controlType != MenuControllerHandler.MenuControl.Unassigned) + { + Switch(portrait.controlType); + } + } + + private void Start() + { + img = GetComponent<Image>(); + MenuControllerHandler instance = MenuControllerHandler.instance; + instance.switchControlAction = (Action<MenuControllerHandler.MenuControl>)Delegate.Combine(instance.switchControlAction, new Action<MenuControllerHandler.MenuControl>(Switch)); + if (!selector && portrait.controlType == MenuControllerHandler.MenuControl.Unassigned) + { + Switch(MenuControllerHandler.menuControl); + } + } + + private void Update() + { + if ((bool)selector && (bool)selector.currentPlayer) + { + if (selector.currentPlayer.data.input.inputType == GeneralInput.InputType.Controller) + { + img.sprite = controllerSprite; + } + else + { + img.sprite = MKSprite; + } + } + } + + private void Switch(MenuControllerHandler.MenuControl control) + { + if (!img) + { + img = GetComponent<Image>(); + } + if (!selector) + { + if (control == MenuControllerHandler.MenuControl.Controller) + { + img.sprite = controllerSprite; + } + else + { + img.sprite = MKSprite; + } + } + } +} diff --git a/GameCode/CooldownCondition.cs b/GameCode/CooldownCondition.cs new file mode 100644 index 0000000..51bbbf6 --- /dev/null +++ b/GameCode/CooldownCondition.cs @@ -0,0 +1,20 @@ +using UnityEngine; +using UnityEngine.Events; + +public class CooldownCondition : MonoBehaviour +{ + public UnityEvent triggerEvent; + + public float cooldown = 0.25f; + + private float lastTime = -100f; + + public void TryEvent() + { + if (!(Time.time < lastTime + cooldown)) + { + lastTime = Time.time; + triggerEvent.Invoke(); + } + } +} diff --git a/GameCode/CooldownWindUp.cs b/GameCode/CooldownWindUp.cs new file mode 100644 index 0000000..3d443a0 --- /dev/null +++ b/GameCode/CooldownWindUp.cs @@ -0,0 +1,39 @@ +using UnityEngine; + +public class CooldownWindUp : MonoBehaviour +{ + public AnimationCurve multiplierCurve; + + private float currentMultiplier = 1f; + + private float startValue; + + private float currentValue; + + public float increasePerShot = 1f; + + private CooldownCondition cooldown; + + private void Start() + { + cooldown = GetComponent<CooldownCondition>(); + startValue = cooldown.cooldown; + } + + private void Update() + { + currentMultiplier = multiplierCurve.Evaluate(currentValue); + currentValue = Mathf.Clamp(currentValue, 0f, 100f); + cooldown.cooldown = startValue / currentMultiplier; + } + + public void Reset() + { + currentValue = 0f; + } + + public void Add() + { + currentValue += increasePerShot / currentMultiplier; + } +} diff --git a/GameCode/CopyChildren.cs b/GameCode/CopyChildren.cs new file mode 100644 index 0000000..6c1757d --- /dev/null +++ b/GameCode/CopyChildren.cs @@ -0,0 +1,24 @@ +using UnityEngine; + +public class CopyChildren : MonoBehaviour +{ + public GameObject target; + + public void DoUpdate() + { + for (int num = base.transform.childCount - 1; num >= 0; num--) + { + Object.Destroy(base.transform.GetChild(num).gameObject); + } + for (int i = 0; i < target.transform.childCount; i++) + { + Transform child = target.transform.GetChild(i); + Object.Instantiate(child.gameObject, base.transform.TransformPoint(child.localPosition), Quaternion.identity, base.transform).transform.localScale = child.localScale; + } + } + + private void Update() + { + DoUpdate(); + } +} diff --git a/GameCode/CopyObject.cs b/GameCode/CopyObject.cs new file mode 100644 index 0000000..c8ca2ed --- /dev/null +++ b/GameCode/CopyObject.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +public class CopyObject : MonoBehaviour +{ + public void CopySelf() + { + Object.Instantiate(base.gameObject, base.transform.position, base.transform.rotation, base.transform.parent); + } +} diff --git a/GameCode/CopyOwnerGunStats.cs b/GameCode/CopyOwnerGunStats.cs new file mode 100644 index 0000000..d9497a1 --- /dev/null +++ b/GameCode/CopyOwnerGunStats.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +public class CopyOwnerGunStats : MonoBehaviour +{ + private void Start() + { + ApplyCardStats.CopyGunStats(base.transform.root.GetComponent<SpawnedAttack>().spawner.GetComponent<WeaponHandler>().gun, GetComponent<Gun>()); + } +} diff --git a/GameCode/CopyPlayerAim.cs b/GameCode/CopyPlayerAim.cs new file mode 100644 index 0000000..46f2300 --- /dev/null +++ b/GameCode/CopyPlayerAim.cs @@ -0,0 +1,32 @@ +using UnityEngine; + +public class CopyPlayerAim : MonoBehaviour +{ + public float spreadPerLevel; + + public float spread; + + private AttackLevel level; + + private void Start() + { + level = GetComponentInParent<AttackLevel>(); + } + + public void Go() + { + float num = Random.Range(0f - spread, spread); + float num2 = 0f; + if ((bool)level) + { + num2 = (float)level.attackLevel * spreadPerLevel; + } + num += Random.Range(0f - num2, num2); + Holding component = base.transform.root.GetComponent<Holding>(); + if ((bool)component) + { + base.transform.rotation = component.holdable.GetComponentInChildren<ShootPos>().transform.rotation; + } + base.transform.Rotate(Vector3.Cross(Vector3.forward, base.transform.forward) * num); + } +} diff --git a/GameCode/Cos.cs b/GameCode/Cos.cs new file mode 100644 index 0000000..d547ade --- /dev/null +++ b/GameCode/Cos.cs @@ -0,0 +1,11 @@ +using UnityEngine; + +public class Cos : MonoBehaviour +{ + public float multiplier = 1f; + + private void Update() + { + base.transform.root.position += base.transform.right * Mathf.Cos(Time.time * 20f * multiplier) * 10f * multiplier * Time.smoothDeltaTime; + } +} diff --git a/GameCode/CounterUI.cs b/GameCode/CounterUI.cs new file mode 100644 index 0000000..a23dd69 --- /dev/null +++ b/GameCode/CounterUI.cs @@ -0,0 +1,59 @@ +using UnityEngine; +using UnityEngine.Events; +using UnityEngine.UI.ProceduralImage; + +public class CounterUI : MonoBehaviour +{ + [Range(0f, 1f)] + public float counter; + + public float timeToFill = 10f; + + public ProceduralImage outerRing; + + public ProceduralImage fill; + + public Transform rotator; + + public Transform still; + + private float remainingDuration; + + private bool isAbyssalForm; + + private bool done; + + public UnityEvent doneEvent; + + private void ResetStuff() + { + counter = 0f; + } + + private void Update() + { + if (!done) + { + outerRing.fillAmount = counter; + fill.fillAmount = counter; + rotator.transform.localEulerAngles = new Vector3(0f, 0f, 0f - Mathf.Lerp(0f, 360f, counter)); + counter += TimeHandler.deltaTime / timeToFill; + counter = Mathf.Clamp(counter, -0.1f / timeToFill, 1f); + if (counter >= 1f) + { + done = true; + doneEvent.Invoke(); + } + if (counter <= 0f) + { + rotator.gameObject.SetActive(value: false); + still.gameObject.SetActive(value: false); + } + else + { + rotator.gameObject.SetActive(value: true); + still.gameObject.SetActive(value: true); + } + } + } +} diff --git a/GameCode/CrownPos.cs b/GameCode/CrownPos.cs new file mode 100644 index 0000000..f8cd30a --- /dev/null +++ b/GameCode/CrownPos.cs @@ -0,0 +1,16 @@ +using TMPro; +using UnityEngine; + +public class CrownPos : MonoBehaviour +{ + public TextMeshProUGUI text; + + public float GetOffset() + { + if (!(text.text == "")) + { + return 0.45f; + } + return 0f; + } +} diff --git a/GameCode/CurveAnimation.cs b/GameCode/CurveAnimation.cs new file mode 100644 index 0000000..cf4611f --- /dev/null +++ b/GameCode/CurveAnimation.cs @@ -0,0 +1,249 @@ +using System.Collections; +using Sirenix.OdinInspector; +using Sonigon; +using SoundImplementation; +using UnityEngine; +using UnityEngine.Events; + +public class CurveAnimation : MonoBehaviour +{ + [Header("Sound")] + public SoundAnimationPlay[] soundPlay = new SoundAnimationPlay[0]; + + [Header("Settings")] + public CurveAnimationInstance[] animations; + + [HideInInspector] + public Vector3 startScale; + + [HideInInspector] + public Vector3 startLocalPos; + + [HideInInspector] + public Vector3 startAnchoredPos; + + [HideInInspector] + public Vector3 startRotation; + + public CurveAnimationUse currentState = CurveAnimationUse.Out; + + private RectTransform rectTransform; + + [FoldoutGroup("Global settings", 0)] + public bool useTimeScale = true; + + [FoldoutGroup("Global settings", 0)] + public bool X = true; + + [FoldoutGroup("Global settings", 0)] + public bool Y = true; + + [FoldoutGroup("Global settings", 0)] + public bool Z = true; + + [FoldoutGroup("Global settings", 0)] + public bool stopAllAnimations; + + private bool inited; + + private void Init() + { + if (!inited) + { + startScale = base.transform.localScale; + startLocalPos = base.transform.localScale; + rectTransform = GetComponent<RectTransform>(); + if ((bool)rectTransform) + { + startAnchoredPos = rectTransform.anchoredPosition; + } + startRotation = base.transform.localEulerAngles; + } + } + + private void Awake() + { + Init(); + } + + private void OnDisable() + { + StopAllCoroutines(); + ResetAnimationState(); + for (int i = 0; i < animations.Length; i++) + { + animations[i].isPlaying = false; + } + } + + private void OnEnable() + { + ResetAnimationState(); + for (int i = 0; i < animations.Length; i++) + { + if (animations[i].playOnAwake) + { + PlayAnimation(animations[i]); + } + } + } + + [Button] + public void PlayIn() + { + PlayAnimationWithUse(CurveAnimationUse.In); + } + + [Button] + public void PlayOut() + { + PlayAnimationWithUse(CurveAnimationUse.Out); + } + + [Button] + public void PlayBoop() + { + PlayAnimationWithUse(CurveAnimationUse.Boop); + } + + [Button] + public void Stop() + { + StopAllCoroutines(); + } + + private void ResetAnimationState() + { + ApplyAnimationFrame(GetAnimationWithUse(CurveAnimationUse.In), 0f); + } + + private CurveAnimationInstance GetAnimationWithUse(CurveAnimationUse use) + { + for (int i = 0; i < animations.Length; i++) + { + if (animations[i].animationUse == use) + { + return animations[i]; + } + } + return animations[0]; + } + + public void PlayAnimation(CurveAnimationInstance animation) + { + for (int i = 0; i < soundPlay.Length; i++) + { + if (soundPlay[i] != null) + { + soundPlay[i].soundHasPlayed = false; + } + } + if (stopAllAnimations) + { + StopAllCoroutines(); + } + if (animation.isPlaying && animation.animation != null) + { + StopCoroutine(animation.animation); + } + animation.animation = StartCoroutine(DoAnimation(animation)); + } + + public void PlayAnimationWithUse(CurveAnimationUse animationUse) + { + for (int i = 0; i < soundPlay.Length; i++) + { + if (soundPlay[i] != null) + { + soundPlay[i].soundHasPlayed = false; + } + } + if (stopAllAnimations) + { + StopAllCoroutines(); + } + currentState = animationUse; + for (int j = 0; j < animations.Length; j++) + { + if (animations[j].animationUse == animationUse) + { + if (animations[j].isPlaying && animations[j].animation != null) + { + StopCoroutine(animations[j].animation); + } + animations[j].animation = StartCoroutine(DoAnimation(animations[j])); + } + } + } + + private IEnumerator DoAnimation(CurveAnimationInstance animation) + { + StartCoroutine(DelayEvent(animation.delay / animation.speed, animation.delayedEvent)); + animation.statEvent.Invoke(); + animation.isPlaying = true; + float c = 0f; + float t = animation.Curve().keys[animation.Curve().keys.Length - 1].time; + while (c < t) + { + c += (useTimeScale ? (TimeHandler.deltaTime * animation.speed) : (Time.unscaledDeltaTime * animation.speed)); + for (int i = 0; i < soundPlay.Length; i++) + { + if (soundPlay[i] != null && soundPlay[i].soundEvent != null && c >= soundPlay[i].soundDelay && animation.animationUse == soundPlay[i].curveAnimationUse && !soundPlay[i].soundHasPlayed && (bool)SoundManager.Instance) + { + soundPlay[i].soundHasPlayed = true; + SoundManager.Instance.Play(soundPlay[i].soundEvent, base.transform); + } + } + ApplyAnimationFrame(animation, c); + yield return null; + } + ApplyAnimationFrame(animation, t); + animation.isPlaying = false; + animation.endEvent.Invoke(); + if (animation.loop) + { + PlayAnimationWithUse(animation.animationUse); + } + } + + private IEnumerator DelayEvent(float seconds, UnityEvent eventToCall) + { + yield return new WaitForSeconds(seconds); + eventToCall.Invoke(); + } + + private void ApplyAnimationFrame(CurveAnimationInstance anim, float time) + { + if (anim.animationType == CurveAnimationType.Scale) + { + Vector3 vector = startScale * anim.Curve().Evaluate(time) * anim.multiplier; + Vector3 localScale = new Vector3(X ? vector.x : base.transform.localScale.x, Y ? vector.y : base.transform.localScale.y, Z ? vector.z : base.transform.localScale.z); + base.transform.localScale = localScale; + } + else if (anim.animationType == CurveAnimationType.Position) + { + base.transform.localPosition = startLocalPos + anim.animDirection * anim.Curve().Evaluate(time) * anim.multiplier; + } + else if (anim.animationType == CurveAnimationType.RectPosition) + { + rectTransform.anchoredPosition = startAnchoredPos + anim.animDirection * anim.Curve().Evaluate(time) * anim.multiplier; + } + else if (anim.animationType == CurveAnimationType.Rotation) + { + base.transform.localEulerAngles = startRotation + anim.animDirection * anim.Curve().Evaluate(time) * anim.multiplier; + } + } + + public bool IsPlaying() + { + bool result = false; + for (int i = 0; i < animations.Length; i++) + { + if (animations[i].isPlaying) + { + result = true; + } + } + return result; + } +} diff --git a/GameCode/CurveAnimationInstance.cs b/GameCode/CurveAnimationInstance.cs new file mode 100644 index 0000000..6d5ed2f --- /dev/null +++ b/GameCode/CurveAnimationInstance.cs @@ -0,0 +1,73 @@ +using System; +using Sirenix.OdinInspector; +using UnityEngine; +using UnityEngine.Events; + +[Serializable] +public class CurveAnimationInstance +{ + [FoldoutGroup("$animationUse", 0)] + public CurveAnimationType animationType; + + [FoldoutGroup("$animationUse", 0)] + public CurveAnimationUse animationUse; + + [ShowIf("animationUse", CurveAnimationUse.In, true)] + [FoldoutGroup("$animationUse", 0)] + public AnimationCurve inCurve = AnimationCurve.Linear(0f, 0f, 1f, 1f); + + [ShowIf("animationUse", CurveAnimationUse.Out, true)] + [FoldoutGroup("$animationUse", 0)] + public AnimationCurve outCurve = AnimationCurve.Linear(0f, 1f, 1f, 0f); + + [ShowIf("animationUse", CurveAnimationUse.Boop, true)] + [FoldoutGroup("$animationUse", 0)] + public AnimationCurve boopCurve = AnimationCurve.Linear(0f, 1f, 1f, 1f); + + [HideIf("animationType", CurveAnimationType.Scale, true)] + [FoldoutGroup("$animationUse", 0)] + public Vector3 animDirection; + + [FoldoutGroup("$animationUse/Settings", 0)] + public bool loop; + + [FoldoutGroup("$animationUse/Settings", 0)] + public bool playOnAwake; + + [FoldoutGroup("$animationUse/Settings", 0)] + public float speed = 1f; + + [FoldoutGroup("$animationUse/Settings", 0)] + public float multiplier = 1f; + + [FoldoutGroup("$animationUse/Events", 0)] + public UnityEvent statEvent; + + [FoldoutGroup("$animationUse/Events", 0)] + public UnityEvent endEvent; + + [FoldoutGroup("$animationUse/Events", 0)] + public UnityEvent delayedEvent; + + [FoldoutGroup("$animationUse/Events", 0)] + public float delay; + + [FoldoutGroup("$animationUse/Debug", 0, Order = 0, Expanded = false)] + public bool isPlaying; + + [HideInInspector] + public Coroutine animation; + + public AnimationCurve Curve() + { + if (animationUse == CurveAnimationUse.Boop) + { + return boopCurve; + } + if (animationUse != 0) + { + return outCurve; + } + return inCurve; + } +} diff --git a/GameCode/CurveAnimationType.cs b/GameCode/CurveAnimationType.cs new file mode 100644 index 0000000..ad2e885 --- /dev/null +++ b/GameCode/CurveAnimationType.cs @@ -0,0 +1,7 @@ +public enum CurveAnimationType +{ + Scale, + Position, + RectPosition, + Rotation +} diff --git a/GameCode/CurveAnimationUse.cs b/GameCode/CurveAnimationUse.cs new file mode 100644 index 0000000..f56a698 --- /dev/null +++ b/GameCode/CurveAnimationUse.cs @@ -0,0 +1,6 @@ +public enum CurveAnimationUse +{ + In, + Out, + Boop +} diff --git a/GameCode/Damagable.cs b/GameCode/Damagable.cs new file mode 100644 index 0000000..69afa0a --- /dev/null +++ b/GameCode/Damagable.cs @@ -0,0 +1,10 @@ +using UnityEngine; + +public abstract class Damagable : MonoBehaviour +{ + public abstract void CallTakeDamage(Vector2 damage, Vector2 damagePosition, GameObject damagingWeapon = null, Player damagingPlayer = null, bool lethal = true); + + public abstract void TakeDamage(Vector2 damage, Vector2 damagePosition, GameObject damagingWeapon = null, Player damagingPlayer = null, bool lethal = true, bool ignoreBlock = false); + + public abstract void TakeDamage(Vector2 damage, Vector2 damagePosition, Color dmgColor, GameObject damagingWeapon = null, Player damagingPlayer = null, bool lethal = true, bool ignoreBlock = false); +} diff --git a/GameCode/DamagableEvent.cs b/GameCode/DamagableEvent.cs new file mode 100644 index 0000000..3d70256 --- /dev/null +++ b/GameCode/DamagableEvent.cs @@ -0,0 +1,134 @@ +using System; +using Photon.Pun; +using UnityEngine; +using UnityEngine.Events; + +public class DamagableEvent : Damagable +{ + public bool networkedDamage; + + public bool disabled; + + [HideInInspector] + public bool dead; + + public float currentHP = 100f; + + public float regenDelay = 1f; + + public float regenPerSecond; + + [HideInInspector] + public float maxHP = 100f; + + public UnityEvent damageEvent; + + public UnityEvent deathEvent; + + private float sinceDamage = 1f; + + [HideInInspector] + public Player lastPlayer; + + [HideInInspector] + public GameObject lastWeapon; + + private PhotonView view; + + public Action<Vector2> DieAction; + + private void Start() + { + view = GetComponent<PhotonView>(); + maxHP = currentHP; + } + + public override void TakeDamage(Vector2 damage, Vector2 damagePosition, GameObject damagingWeapon = null, Player damagingPlayer = null, bool lethal = true, bool ignoreBlock = false) + { + if (disabled || dead) + { + return; + } + if (networkedDamage) + { + if ((bool)damagingPlayer) + { + if (!damagingPlayer.data.view.IsMine) + { + return; + } + view.RPC("RPCA_TakeDamage", RpcTarget.Others, damage, damagePosition); + } + else + { + if (!view.IsMine) + { + return; + } + view.RPC("RPCA_TakeDamage", RpcTarget.Others, damage, damagePosition); + } + } + DoDamage(damage, damagePosition, damagingWeapon, damagingPlayer, lethal, ignoreBlock); + } + + [PunRPC] + public void RPCA_TakeDamage(Vector2 damage, Vector2 damagePosition) + { + DoDamage(damage, damagePosition); + } + + private void DoDamage(Vector2 damage, Vector2 damagePosition, GameObject damagingWeapon = null, Player damagingPlayer = null, bool lethal = true, bool ignoreBlock = false) + { + if ((bool)damagingPlayer) + { + lastPlayer = damagingPlayer; + } + if ((bool)damagingWeapon) + { + lastWeapon = damagingWeapon; + } + sinceDamage = 0f; + currentHP -= damage.magnitude; + if (currentHP <= 0f) + { + Die(damage); + } + else + { + damageEvent.Invoke(); + } + } + + private void Die(Vector2 damage = default(Vector2)) + { + if (!dead && !disabled) + { + DieAction?.Invoke(damage); + deathEvent.Invoke(); + dead = true; + } + } + + private void Update() + { + if (!dead && !disabled) + { + sinceDamage += TimeHandler.deltaTime; + if (sinceDamage > regenDelay && currentHP < maxHP) + { + currentHP += regenPerSecond * TimeHandler.deltaTime; + currentHP = Mathf.Clamp(currentHP, float.NegativeInfinity, maxHP); + } + } + } + + public override void TakeDamage(Vector2 damage, Vector2 damagePosition, Color dmgColor, GameObject damagingWeapon = null, Player damagingPlayer = null, bool lethal = true, bool ignoreBlock = false) + { + TakeDamage(damage, damagePosition, damagingWeapon, damagingPlayer, lethal); + } + + public override void CallTakeDamage(Vector2 damage, Vector2 damagePosition, GameObject damagingWeapon = null, Player damagingPlayer = null, bool lethal = true) + { + TakeDamage(damage, damagePosition, Color.red, damagingWeapon, damagingPlayer, lethal); + } +} diff --git a/GameCode/DamageBox.cs b/GameCode/DamageBox.cs new file mode 100644 index 0000000..e86d79f --- /dev/null +++ b/GameCode/DamageBox.cs @@ -0,0 +1,96 @@ +using Sonigon; +using UnityEngine; + +public class DamageBox : MonoBehaviour +{ + [Header("Sound")] + public bool soundPlaySawDamage; + + public SoundEvent soundSawDamage; + + [Header("Settings")] + public bool towardsCenterOfMap; + + public bool awayFromMe; + + public float damage = 25f; + + public float force; + + public float setFlyingFor; + + public float shake; + + public float cd = 0.3f; + + public bool ignoreBlock; + + public ParticleSystem dmgPart; + + private float time; + + private SpawnedAttack spawned; + + private void Start() + { + spawned = GetComponentInParent<SpawnedAttack>(); + } + + private void OnCollisionEnter2D(Collision2D collision) + { + Collide(collision); + } + + private void OnCollisionStay2D(Collision2D collision) + { + Collide(collision); + } + + private void Collide(Collision2D collision) + { + if (Time.time < time + cd) + { + return; + } + Vector3 vector = base.transform.root.forward; + if (towardsCenterOfMap) + { + vector = -collision.contacts[0].point.normalized; + } + if (awayFromMe) + { + vector = (collision.transform.position - base.transform.position).normalized; + } + Damagable componentInParent = collision.transform.GetComponentInParent<Damagable>(); + if (!componentInParent) + { + return; + } + time = Time.time; + HealthHandler component = componentInParent.GetComponent<HealthHandler>(); + CharacterData component2 = component.GetComponent<CharacterData>(); + if (!component2 || component2.view.IsMine) + { + if ((bool)component) + { + component.CallTakeForce(vector * force, ForceMode2D.Impulse, forceIgnoreMass: false, ignoreBlock, setFlyingFor); + } + componentInParent.CallTakeDamage(damage * vector, base.transform.position, null, (spawned != null) ? spawned.spawner : null); + if (soundPlaySawDamage) + { + SoundManager.Instance.PlayAtPosition(soundSawDamage, SoundManager.Instance.GetTransform(), base.transform); + } + if ((bool)dmgPart) + { + Vector3 forward = vector; + vector.z = 0f; + dmgPart.transform.parent.rotation = Quaternion.LookRotation(forward); + dmgPart.Play(); + } + if (shake != 0f) + { + component2.player.Call_AllGameFeel(shake * (Vector2)vector); + } + } + } +} diff --git a/GameCode/DamageEffect.cs b/GameCode/DamageEffect.cs new file mode 100644 index 0000000..d8d4907 --- /dev/null +++ b/GameCode/DamageEffect.cs @@ -0,0 +1,6 @@ +using UnityEngine; + +public abstract class DamageEffect : MonoBehaviour +{ + public abstract void DoDamageEffect(Vector2 dmg, bool selfDmg, Player damagedPlayer = null); +} diff --git a/GameCode/DamageOverTime.cs b/GameCode/DamageOverTime.cs new file mode 100644 index 0000000..c1c6a17 --- /dev/null +++ b/GameCode/DamageOverTime.cs @@ -0,0 +1,38 @@ +using System.Collections; +using Sonigon; +using UnityEngine; + +public class DamageOverTime : MonoBehaviour +{ + private HealthHandler health; + + private CharacterData data; + + private void Start() + { + health = GetComponent<HealthHandler>(); + data = GetComponent<CharacterData>(); + } + + public void TakeDamageOverTime(Vector2 damage, Vector2 position, float time, float interval, Color color, SoundEvent soundDamageOverTime, GameObject damagingWeapon = null, Player damagingPlayer = null, bool lethal = true) + { + StartCoroutine(DoDamageOverTime(damage, position, time, interval, color, soundDamageOverTime, damagingWeapon, damagingPlayer, lethal)); + } + + private IEnumerator DoDamageOverTime(Vector2 damage, Vector2 position, float time, float interval, Color color, SoundEvent soundDamageOverTime, GameObject damagingWeapon = null, Player damagingPlayer = null, bool lethal = true) + { + float damageDealt = 0f; + float damageToDeal = damage.magnitude; + float dpt = damageToDeal / time * interval; + while (damageDealt < damageToDeal) + { + if (soundDamageOverTime != null && data.isPlaying && !data.dead) + { + SoundManager.Instance.Play(soundDamageOverTime, base.transform); + } + damageDealt += dpt; + health.DoDamage(damage.normalized * dpt, position, color, damagingWeapon, damagingPlayer, healthRemoval: true, lethal); + yield return new WaitForSeconds(interval / TimeHandler.timeScale); + } + } +} diff --git a/GameCode/DealDamageToPlayer.cs b/GameCode/DealDamageToPlayer.cs new file mode 100644 index 0000000..bfad181 --- /dev/null +++ b/GameCode/DealDamageToPlayer.cs @@ -0,0 +1,47 @@ +using Sonigon; +using UnityEngine; + +public class DealDamageToPlayer : MonoBehaviour +{ + public enum TargetPlayer + { + Own, + Other + } + + [Header("Sounds")] + public SoundEvent soundDamage; + + [Header("Settings")] + public float damage = 25f; + + public bool lethal = true; + + public TargetPlayer targetPlayer; + + private CharacterData data; + + private Player target; + + private void Start() + { + data = GetComponentInParent<CharacterData>(); + } + + public void Go() + { + if (!target) + { + target = data.player; + if (targetPlayer == TargetPlayer.Other) + { + target = PlayerManager.instance.GetOtherPlayer(target); + } + } + if (soundDamage != null && target != null && target.data != null && target.data.isPlaying && !target.data.dead && !target.data.block.IsBlocking()) + { + SoundManager.Instance.Play(soundDamage, target.transform); + } + target.data.healthHandler.TakeDamage(damage * Vector2.up, base.transform.position, null, data.player, lethal); + } +} diff --git a/GameCode/DealtDamageEffect.cs b/GameCode/DealtDamageEffect.cs new file mode 100644 index 0000000..ec5cddc --- /dev/null +++ b/GameCode/DealtDamageEffect.cs @@ -0,0 +1,6 @@ +using UnityEngine; + +public abstract class DealtDamageEffect : MonoBehaviour +{ + public abstract void DealtDamage(Vector2 damage, bool selfDamage, Player damagedPlayer = null); +} diff --git a/GameCode/DealtDamageTrigger.cs b/GameCode/DealtDamageTrigger.cs new file mode 100644 index 0000000..d596b4d --- /dev/null +++ b/GameCode/DealtDamageTrigger.cs @@ -0,0 +1,19 @@ +using System; +using UnityEngine; +using UnityEngine.Events; + +public class DealtDamageTrigger : MonoBehaviour +{ + public UnityEvent triggerEvent; + + private void Start() + { + CharacterStatModifiers stats = GetComponentInParent<Player>().data.stats; + stats.DealtDamageAction = (Action<Vector2, bool>)Delegate.Combine(stats.DealtDamageAction, new Action<Vector2, bool>(DealtDamage)); + } + + private void DealtDamage(Vector2 dmg, bool lethal) + { + triggerEvent.Invoke(); + } +} diff --git a/GameCode/DeathEffect.cs b/GameCode/DeathEffect.cs new file mode 100644 index 0000000..5819e64 --- /dev/null +++ b/GameCode/DeathEffect.cs @@ -0,0 +1,101 @@ +using System.Collections; +using Sonigon; +using UnityEngine; + +public class DeathEffect : MonoBehaviour +{ + [Header("Sounds")] + public SoundEvent soundPhoenixActivate; + + public SoundEvent soundPhoenixChargeLoop; + + public SoundEvent soundPhoenixRespawn; + + private SoundParameterIntensity soundParameterChargeLoopIntensity = new SoundParameterIntensity(0f, UpdateMode.Continuous); + + [Header("Settings")] + public float forceMulti = 1f; + + public float minScale = 0.9f; + + public float maxScale = 1.1f; + + public float minDrag = 0.9f; + + public float maxDrag = 1.1f; + + public float minForce = 0.9f; + + public float maxForce = 1.1f; + + public float spread = 0.5f; + + private Rigidbody2D[] rigs; + + private Color baseColor; + + private ParticleSystem[] parts; + + public ParticleSystem partToColor; + + public ParticleSystem[] partsToColor; + + private float respawnTimeCurrent; + + private float respawnTime = 2.53f; + + private void Update() + { + } + + public void PlayDeath(Color color, PlayerVelocity playerRig, Vector2 vel, int playerIDToRevive = -1) + { + if (vel.magnitude < 30f) + { + vel = vel.normalized * 30f; + } + vel *= 1f; + parts = GetComponentsInChildren<ParticleSystem>(); + for (int i = 0; i < parts.Length; i++) + { + _ = parts[i].main; + if (parts[i].name.Contains("ROT")) + { + parts[i].transform.rotation = Quaternion.LookRotation(vel); + } + } + ParticleSystem.MainModule main = partToColor.main; + main.startColor = PlayerSkinBank.GetPlayerSkinColors(playerRig.GetComponent<Player>().playerID).color; + for (int j = 0; j < partsToColor.Length; j++) + { + ParticleSystem.MainModule main2 = partsToColor[j].main; + main2.startColor = PlayerSkinBank.GetPlayerSkinColors(playerRig.GetComponent<Player>().playerID).color; + } + if (playerIDToRevive != -1) + { + SoundManager.Instance.Play(soundPhoenixActivate, base.transform); + SoundManager.Instance.Play(soundPhoenixChargeLoop, base.transform, soundParameterChargeLoopIntensity); + StartCoroutine(RespawnPlayer(playerIDToRevive)); + } + } + + private IEnumerator RespawnPlayer(int playerIDToRevive = -1) + { + while (respawnTimeCurrent < respawnTime) + { + soundParameterChargeLoopIntensity.intensity = respawnTimeCurrent / respawnTime; + respawnTimeCurrent += 0.1f; + yield return new WaitForSeconds(0.1f); + } + SoundManager.Instance.Play(soundPhoenixRespawn, base.transform); + SoundManager.Instance.Stop(soundPhoenixChargeLoop, base.transform); + PlayerManager.instance.players[playerIDToRevive].data.healthHandler.Revive(isFullRevive: false); + PlayerManager.instance.players[playerIDToRevive].data.block.RPCA_DoBlock(firstBlock: true); + } + + private IEnumerator DoEffect(Rigidbody2D rig) + { + yield return new WaitForSeconds(Random.Range(0.05f, 0.15f)); + rig.GetComponent<SpriteRenderer>().color = baseColor; + } +} diff --git a/GameCode/Debug.cs b/GameCode/Debug.cs new file mode 100644 index 0000000..b35bd1d --- /dev/null +++ b/GameCode/Debug.cs @@ -0,0 +1,53 @@ +using System; +using UnityEngine; + +public static class Debug +{ + public static void Log(object logMsg) + { + } + + public static void Log(string logMsg) + { + } + + public static void Log(Exception exeption) + { + } + + public static void LogError(string logMsg) + { + } + + public static void LogError(string logMsg, object ob) + { + } + + public static void LogError(string logMsg, GameObject go) + { + } + + public static void LogWarning(string logMsg) + { + } + + public static void LogWarning(string logMsg, object ob) + { + } + + public static void ClearDeveloperConsole() + { + } + + public static void Assert(Transform t, string m) + { + } + + public static void DrawLine(Vector3 v1, Vector3 v2, Color c, float t) + { + } + + public static void DrawLine(Vector3 v1, Vector3 v2, Color c) + { + } +} diff --git a/GameCode/DelayEvent.cs b/GameCode/DelayEvent.cs new file mode 100644 index 0000000..0ebea56 --- /dev/null +++ b/GameCode/DelayEvent.cs @@ -0,0 +1,61 @@ +using System.Collections; +using UnityEngine; +using UnityEngine.Events; + +public class DelayEvent : MonoBehaviour +{ + public UnityEvent delayedEvent; + + public float time = 1f; + + public bool auto; + + public bool repeating; + + public bool usedTimeScale = true; + + private void Start() + { + CodeAnimation componentInParent = GetComponentInParent<CodeAnimation>(); + if ((bool)componentInParent) + { + time /= componentInParent.animations[0].animationSpeed; + } + if (auto) + { + Go(); + } + } + + public void Go() + { + StartCoroutine(DelayEventCall()); + } + + private IEnumerator DelayEventCall() + { + yield return 1; + if (usedTimeScale) + { + yield return new WaitForSeconds(time); + } + else + { + yield return new WaitForSecondsRealtime(time); + } + if (base.enabled) + { + delayedEvent.Invoke(); + if (repeating) + { + Go(); + } + } + } + + public void DoEvent() + { + StopAllCoroutines(); + delayedEvent.Invoke(); + } +} diff --git a/GameCode/DelayedEvent.cs b/GameCode/DelayedEvent.cs new file mode 100644 index 0000000..cfde350 --- /dev/null +++ b/GameCode/DelayedEvent.cs @@ -0,0 +1,14 @@ +using System; +using UnityEngine.Events; + +[Serializable] +public class DelayedEvent +{ + public UnityEvent eventTrigger; + + public float delay; + + public int cycles = 1; + + public int cyclesPerLvl; +} diff --git a/GameCode/DestroyEvent.cs b/GameCode/DestroyEvent.cs new file mode 100644 index 0000000..2e4fe63 --- /dev/null +++ b/GameCode/DestroyEvent.cs @@ -0,0 +1,22 @@ +using UnityEngine; +using UnityEngine.Events; + +public class DestroyEvent : MonoBehaviour +{ + public UnityEvent deathEvent; + + private bool m_isQuitting; + + private void OnDestroy() + { + if (!m_isQuitting) + { + deathEvent.Invoke(); + } + } + + private void OnApplicationQuit() + { + m_isQuitting = true; + } +} diff --git a/GameCode/DestroyObjects.cs b/GameCode/DestroyObjects.cs new file mode 100644 index 0000000..8cb52e2 --- /dev/null +++ b/GameCode/DestroyObjects.cs @@ -0,0 +1,19 @@ +using UnityEngine; + +public class DestroyObjects : MonoBehaviour +{ + public GameObject[] objectsToDestroy; + + public void DestroySelf() + { + Object.Destroy(base.gameObject); + } + + public void DestroyAllObjects() + { + for (int i = 0; i < objectsToDestroy.Length; i++) + { + Object.Destroy(objectsToDestroy[i]); + } + } +} diff --git a/GameCode/DestroyOnAwake.cs b/GameCode/DestroyOnAwake.cs new file mode 100644 index 0000000..47d4227 --- /dev/null +++ b/GameCode/DestroyOnAwake.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +public class DestroyOnAwake : MonoBehaviour +{ + private void Awake() + { + Object.Destroy(base.gameObject); + } +} diff --git a/GameCode/Destructible.cs b/GameCode/Destructible.cs new file mode 100644 index 0000000..e2b71b0 --- /dev/null +++ b/GameCode/Destructible.cs @@ -0,0 +1,45 @@ +using System; +using UnityEngine; + +public class Destructible : Damagable +{ + public float threshold = 25f; + + public float force = 1f; + + public float rangeMulti = 1f; + + public override void CallTakeDamage(Vector2 damage, Vector2 damagePosition, GameObject damagingWeapon = null, Player damagingPlayer = null, bool lethal = true) + { + throw new NotImplementedException(); + } + + public override void TakeDamage(Vector2 damage, Vector2 position, GameObject damagingWeapon = null, Player damagingPlayer = null, bool lethal = true, bool ignoreBlock = false) + { + if (!(damage.magnitude < threshold)) + { + damage = damage.normalized * 100f; + Transform[] array = new Transform[base.transform.childCount]; + for (int i = 0; i < array.Length; i++) + { + array[i] = base.transform.GetChild(i); + } + foreach (Transform transform in array) + { + transform.gameObject.SetActive(value: true); + transform.SetParent(null, worldPositionStays: true); + float num = damage.magnitude * 0.02f * rangeMulti; + float num2 = Mathf.Clamp((num - Vector2.Distance(transform.position, position)) / num, 0f, 1f); + Rigidbody2D component = transform.GetComponent<Rigidbody2D>(); + component.AddForce(damage * num2 * force * 0.1f * component.mass, ForceMode2D.Impulse); + transform.gameObject.AddComponent<RemoveAfterSeconds>().seconds = UnityEngine.Random.Range(1f, 3f); + } + base.gameObject.SetActive(value: false); + } + } + + public override void TakeDamage(Vector2 damage, Vector2 damagePosition, Color dmgColor, GameObject damagingWeapon = null, Player damagingPlayer = null, bool lethal = true, bool ignoreBlock = false) + { + TakeDamage(damage, damagePosition, dmgColor, damagingWeapon, damagingPlayer, lethal); + } +} diff --git a/GameCode/DestructibleBoxDestruction.cs b/GameCode/DestructibleBoxDestruction.cs new file mode 100644 index 0000000..d7f7fb8 --- /dev/null +++ b/GameCode/DestructibleBoxDestruction.cs @@ -0,0 +1,40 @@ +using System; +using Sonigon; +using UnityEngine; + +public class DestructibleBoxDestruction : MonoBehaviour +{ + public bool soundPlayDestruction; + + public SoundEvent soundBoxDestruction; + + private void Start() + { + DamagableEvent componentInParent = GetComponentInParent<DamagableEvent>(); + componentInParent.DieAction = (Action<Vector2>)Delegate.Combine(componentInParent.DieAction, new Action<Vector2>(Die)); + } + + private void Die(Vector2 dmg) + { + if (soundPlayDestruction) + { + SoundManager.Instance.PlayAtPosition(soundBoxDestruction, SoundManager.Instance.GetTransform(), base.transform); + } + Rigidbody2D[] componentsInChildren = GetComponentsInChildren<Rigidbody2D>(includeInactive: true); + for (int i = 0; i < componentsInChildren.Length; i++) + { + if (base.transform != componentsInChildren[i].transform) + { + componentsInChildren[i].transform.SetParent(base.transform.root); + componentsInChildren[i].transform.gameObject.SetActive(value: true); + componentsInChildren[i].AddForce(dmg * UnityEngine.Random.Range(0f, 1f) * 500f, ForceMode2D.Impulse); + componentsInChildren[i].AddTorque(UnityEngine.Random.Range(-1f, 1f) * 1000f, ForceMode2D.Impulse); + componentsInChildren[i].GetComponent<RemoveAfterSeconds>().seconds = UnityEngine.Random.Range(0f, 0.5f); + componentsInChildren[i].GetComponentInChildren<GetColor>().Start(); + componentsInChildren[i].GetComponentInChildren<ColorBlink>().timeAmount *= UnityEngine.Random.Range(0.5f, 2f); + componentsInChildren[i].GetComponentInChildren<ColorBlink>().DoBlink(); + componentsInChildren[i].gameObject.layer = 18; + } + } + } +} diff --git a/GameCode/DevConsole.cs b/GameCode/DevConsole.cs new file mode 100644 index 0000000..e972cba --- /dev/null +++ b/GameCode/DevConsole.cs @@ -0,0 +1,128 @@ +using Photon.Pun; +using TMPro; +using UnityEngine; + +public class DevConsole : MonoBehaviour +{ + public TMP_InputField inputField; + + public static bool isTyping; + + private void Start() + { + isTyping = false; + } + + private void Update() + { + if (Input.GetKeyDown(KeyCode.Return)) + { + inputField.gameObject.SetActive(!inputField.gameObject.activeSelf); + isTyping = inputField.gameObject.activeSelf; + GameManager.lockInput = isTyping; + if (inputField.gameObject.activeSelf) + { + inputField.ActivateInputField(); + } + else + { + Send(inputField.text); + } + } + } + + private void Send(string message) + { + if (Application.isEditor || ((bool)GM_Test.instance && GM_Test.instance.gameObject.activeSelf)) + { + SpawnCard(message); + } + if (Application.isEditor) + { + SpawnMap(message); + } + int viewID = PlayerManager.instance.GetPlayerWithActorID(PhotonNetwork.LocalPlayer.ActorNumber).data.view.ViewID; + GetComponent<PhotonView>().RPC("RPCA_SendChat", RpcTarget.All, message, viewID); + } + + private void SpawnMap(string message) + { + try + { + int iD = int.Parse(message); + MapManager.instance.LoadLevelFromID(iD, onlyMaster: false, callInImidetly: true); + } + catch + { + } + } + + [PunRPC] + private void RPCA_SendChat(string message, int playerViewID) + { + PhotonNetwork.GetPhotonView(playerViewID).GetComponentInChildren<PlayerChat>().Send(message); + } + + private void SpawnCard(string message) + { + CardInfo[] cards = CardChoice.instance.cards; + int num = -1; + float num2 = 0f; + for (int i = 0; i < cards.Length; i++) + { + string text = cards[i].GetComponent<CardInfo>().cardName.ToUpper(); + text = text.Replace(" ", ""); + string text2 = message.ToUpper(); + text2 = text2.Replace(" ", ""); + float num3 = 0f; + for (int j = 0; j < text2.Length; j++) + { + if (text.Length > j && text2[j] == text[j]) + { + num3 += 1f / (float)text2.Length; + } + } + num3 -= (float)Mathf.Abs(text2.Length - text.Length) * 0.001f; + if (num3 > 0.1f && num3 > num2) + { + num2 = num3; + num = i; + } + } + if (num != -1) + { + GameObject obj = CardChoice.instance.AddCard(cards[num]); + obj.GetComponentInChildren<CardVisuals>().firstValueToSet = true; + obj.transform.root.GetComponentInChildren<ApplyCardStats>().shootToPick = true; + } + } + + public static int GetClosestString(string inputText, string[] compareTo) + { + CardInfo[] cards = CardChoice.instance.cards; + int result = -1; + float num = 0f; + for (int i = 0; i < cards.Length; i++) + { + string text = compareTo[i]; + text = text.Replace(" ", ""); + string text2 = inputText.ToUpper(); + text2 = text2.Replace(" ", ""); + float num2 = 0f; + for (int j = 0; j < text2.Length; j++) + { + if (text.Length > j && text2[j] == text[j]) + { + num2 += 1f / (float)text2.Length; + } + } + num2 -= (float)Mathf.Abs(text2.Length - text.Length) * 0.001f; + if (num2 > 0.1f && num2 > num) + { + num = num2; + result = i; + } + } + return result; + } +} diff --git a/GameCode/DisableChildren.cs b/GameCode/DisableChildren.cs new file mode 100644 index 0000000..e51223c --- /dev/null +++ b/GameCode/DisableChildren.cs @@ -0,0 +1,13 @@ +using UnityEngine; + +public class DisableChildren : MonoBehaviour +{ + private void Start() + { + ParticleSystem[] componentsInChildren = GetComponentsInChildren<ParticleSystem>(); + for (int i = 0; i < componentsInChildren.Length; i++) + { + componentsInChildren[i].gameObject.SetActive(value: false); + } + } +} diff --git a/GameCode/DisableEvent.cs b/GameCode/DisableEvent.cs new file mode 100644 index 0000000..698d2e2 --- /dev/null +++ b/GameCode/DisableEvent.cs @@ -0,0 +1,12 @@ +using UnityEngine; +using UnityEngine.Events; + +public class DisableEvent : MonoBehaviour +{ + public UnityEvent disableEvent; + + public void OnDisable() + { + disableEvent.Invoke(); + } +} diff --git a/GameCode/DisableIfSimple.cs b/GameCode/DisableIfSimple.cs new file mode 100644 index 0000000..514da3d --- /dev/null +++ b/GameCode/DisableIfSimple.cs @@ -0,0 +1,17 @@ +using UnityEngine; + +public class DisableIfSimple : MonoBehaviour +{ + private void Start() + { + Unparent componentInParent = GetComponentInParent<Unparent>(); + if ((bool)componentInParent && (bool)componentInParent.parent) + { + base.gameObject.SetActive(!componentInParent.parent.root.GetComponentInChildren<PlayerSkinHandler>().simpleSkin); + } + else + { + base.gameObject.SetActive(!base.transform.root.GetComponentInChildren<PlayerSkinHandler>().simpleSkin); + } + } +} diff --git a/GameCode/DisableObjects.cs b/GameCode/DisableObjects.cs new file mode 100644 index 0000000..e6c7516 --- /dev/null +++ b/GameCode/DisableObjects.cs @@ -0,0 +1,24 @@ +using UnityEngine; + +public class DisableObjects : MonoBehaviour +{ + public bool playOnAwake = true; + + public GameObject[] objects; + + private void Start() + { + if (playOnAwake) + { + DoIt(); + } + } + + private void DoIt() + { + for (int i = 0; i < objects.Length; i++) + { + objects[i].SetActive(value: false); + } + } +} diff --git a/GameCode/DisplayMatchPlayerNames.cs b/GameCode/DisplayMatchPlayerNames.cs new file mode 100644 index 0000000..10e3cf5 --- /dev/null +++ b/GameCode/DisplayMatchPlayerNames.cs @@ -0,0 +1,32 @@ +using System.Collections.Generic; +using System.Linq; +using Photon.Pun; +using Photon.Realtime; +using TMPro; +using UnityEngine; + +public class DisplayMatchPlayerNames : MonoBehaviour +{ + public TextMeshProUGUI local; + + public TextMeshProUGUI other; + + public void ShowNames() + { + List<Photon.Realtime.Player> list = PhotonNetwork.CurrentRoom.Players.Select((KeyValuePair<int, Photon.Realtime.Player> p) => p.Value).ToList(); + bool flag = false; + flag = PhotonNetwork.CurrentRoom.CustomProperties.ContainsKey(NetworkConnectionHandler.TWITCH_ROOM_AUDIENCE_RATING_KEY); + for (int i = 0; i < list.Count; i++) + { + string text = (flag ? (" (" + list[i].CustomProperties[NetworkConnectionHandler.TWITCH_PLAYER_SCORE_KEY].ToString() + ")") : string.Empty); + if (i == 0) + { + local.text = list[i].NickName + text; + } + else + { + other.text = list[i].NickName + text; + } + } + } +} diff --git a/GameCode/DmgEvent.cs b/GameCode/DmgEvent.cs new file mode 100644 index 0000000..16d50b1 --- /dev/null +++ b/GameCode/DmgEvent.cs @@ -0,0 +1,10 @@ +using System; +using UnityEngine.Events; + +[Serializable] +public class DmgEvent +{ + public UnityEvent eventToCall; + + public float dmg; +} diff --git a/GameCode/DoPlayerReload.cs b/GameCode/DoPlayerReload.cs new file mode 100644 index 0000000..8faa4e6 --- /dev/null +++ b/GameCode/DoPlayerReload.cs @@ -0,0 +1,16 @@ +using UnityEngine; + +public class DoPlayerReload : MonoBehaviour +{ + private WeaponHandler wh; + + private void Start() + { + wh = GetComponentInParent<WeaponHandler>(); + } + + public void DoReload() + { + wh.DoReload(); + } +} diff --git a/GameCode/DodgeGround.cs b/GameCode/DodgeGround.cs new file mode 100644 index 0000000..a7d3815 --- /dev/null +++ b/GameCode/DodgeGround.cs @@ -0,0 +1,141 @@ +using Photon.Pun; +using Sonigon; +using UnityEngine; + +public class DodgeGround : MonoBehaviour +{ + [Header("Sound")] + public SoundEvent soundSneakyDodgeGroundLoop; + + private bool soundIsPlaying; + + private float soundTimeToStopPlaying = 0.5f; + + private float soundTimeCurrent; + + private Transform spawnedSpawnerTransform; + + [Header("Settings")] + public float rayLength = 3f; + + public float rayUp = 0.3f; + + public float force; + + public LayerMask mask; + + private MoveTransform move; + + private SpawnedAttack spawned; + + public ParticleSystem p1; + + public ParticleSystem p2; + + public ParticleSystem p3; + + public LineRenderer l1; + + public LineRenderer l2; + + private float c3; + + private void Start() + { + spawned = GetComponentInParent<SpawnedAttack>(); + move = GetComponentInParent<MoveTransform>(); + GetComponentInParent<SyncProjectile>().active = true; + if (spawned != null && spawned.spawner != null) + { + spawnedSpawnerTransform = spawned.spawner.transform; + } + } + + private void SoundStart() + { + if (!soundIsPlaying && spawnedSpawnerTransform != null) + { + soundIsPlaying = true; + SoundManager.Instance.PlayAtPosition(soundSneakyDodgeGroundLoop, spawnedSpawnerTransform, base.transform); + } + } + + private void SoundStop() + { + if (soundIsPlaying && spawnedSpawnerTransform != null) + { + soundIsPlaying = false; + SoundManager.Instance.StopAtPosition(soundSneakyDodgeGroundLoop, base.transform); + } + } + + private void OnDestroy() + { + SoundStop(); + } + + private void Update() + { + float magnitude = move.velocity.magnitude; + c3 += TimeHandler.deltaTime; + l1.enabled = false; + l2.enabled = false; + bool flag = false; + float num = 1f; + RaycastHit2D raycastHit2D = Physics2D.Raycast(base.transform.position, base.transform.forward + base.transform.right * rayUp, rayLength, mask); + if ((bool)raycastHit2D && (bool)raycastHit2D.transform && !raycastHit2D.collider.GetComponent<Damagable>() && raycastHit2D.transform.gameObject.layer != 10) + { + flag = true; + } + bool flag2 = false; + RaycastHit2D raycastHit2D2 = Physics2D.Raycast(base.transform.position, base.transform.forward + base.transform.right * (0f - rayUp), rayLength, mask); + if ((bool)raycastHit2D2 && (bool)raycastHit2D2.transform && !raycastHit2D2.collider.GetComponent<Damagable>() && raycastHit2D2.transform.gameObject.layer != 10) + { + flag2 = true; + } + if (flag && flag2 && raycastHit2D.transform == raycastHit2D2.transform) + { + if (raycastHit2D.distance < raycastHit2D2.distance) + { + flag2 = false; + } + else + { + flag = false; + } + } + if (flag) + { + move.velocity += (Vector3)raycastHit2D.normal * force * move.velocity.magnitude * num * TimeHandler.deltaTime; + l1.enabled = true; + l1.SetPosition(0, base.transform.position); + l1.SetPosition(1, raycastHit2D.point); + } + if (flag2) + { + move.velocity += (Vector3)raycastHit2D2.normal * force * move.velocity.magnitude * num * TimeHandler.deltaTime; + l2.enabled = true; + l2.SetPosition(0, base.transform.position); + l2.SetPosition(1, raycastHit2D2.point); + } + if (flag || flag2) + { + soundTimeCurrent = soundTimeToStopPlaying; + SoundStart(); + } + else if (soundIsPlaying) + { + soundTimeCurrent -= TimeHandler.deltaTime; + if (soundTimeCurrent < 0f) + { + SoundStop(); + } + } + move.velocity = move.velocity.normalized * magnitude; + if (flag && c3 > 0.05f) + { + c3 = 0f; + p3.Emit(1); + } + } +} diff --git a/GameCode/DontChangeMe.cs b/GameCode/DontChangeMe.cs new file mode 100644 index 0000000..cbef7b6 --- /dev/null +++ b/GameCode/DontChangeMe.cs @@ -0,0 +1,12 @@ +using UnityEngine; + +public class DontChangeMe : MonoBehaviour +{ + private void Start() + { + } + + private void Update() + { + } +} diff --git a/GameCode/DuringReloadTrigger.cs b/GameCode/DuringReloadTrigger.cs new file mode 100644 index 0000000..6f3609f --- /dev/null +++ b/GameCode/DuringReloadTrigger.cs @@ -0,0 +1,38 @@ +using UnityEngine; +using UnityEngine.Events; + +public class DuringReloadTrigger : MonoBehaviour +{ + public UnityEvent triggerEvent; + + public UnityEvent triggerStartEvent; + + public UnityEvent triggerEndEvent; + + private Gun gunAmmo; + + private bool triggering; + + private void Start() + { + gunAmmo = GetComponentInParent<WeaponHandler>().gun; + } + + private void Update() + { + if (gunAmmo.isReloading) + { + if (!triggering) + { + triggerStartEvent.Invoke(); + triggering = true; + } + triggerEvent.Invoke(); + } + else if (triggering) + { + triggerEndEvent.Invoke(); + triggering = false; + } + } +} diff --git a/GameCode/DynamicParticleSet.cs b/GameCode/DynamicParticleSet.cs new file mode 100644 index 0000000..44931b9 --- /dev/null +++ b/GameCode/DynamicParticleSet.cs @@ -0,0 +1,9 @@ +using System; + +[Serializable] +public class DynamicParticleSet +{ + public ObjectsToSpawn objectsToSpawn; + + public float dmg; +} diff --git a/GameCode/DynamicParticles.cs b/GameCode/DynamicParticles.cs new file mode 100644 index 0000000..26a0cad --- /dev/null +++ b/GameCode/DynamicParticles.cs @@ -0,0 +1,50 @@ +using UnityEngine; + +public class DynamicParticles : MonoBehaviour +{ + public static DynamicParticles instance; + + public DynamicParticleSet[] bulletHit; + + private int spawnsThisFrame; + + private void Start() + { + instance = this; + } + + private void Update() + { + spawnsThisFrame = 0; + } + + public void PlayBulletHit(float damage, Transform spawnerTransform, HitInfo hit, Color projectielColor) + { + if ((float)spawnsThisFrame > 5f) + { + return; + } + spawnsThisFrame++; + int num = 0; + for (int i = 1; i < bulletHit.Length && !(bulletHit[i].dmg > damage); i++) + { + num = i; + } + GameObject[] array = ObjectsToSpawn.SpawnObject(base.transform, hit, bulletHit[num].objectsToSpawn, null, null); + if (!(projectielColor != Color.black)) + { + return; + } + for (int j = 0; j < array.Length; j++) + { + for (int k = 0; k < array[j].transform.childCount; k++) + { + ChangeColor componentInChildren = array[j].transform.GetChild(k).GetComponentInChildren<ChangeColor>(); + if ((bool)componentInChildren) + { + componentInChildren.GetComponent<ParticleSystemRenderer>().material.color = projectielColor; + } + } + } + } +} diff --git a/GameCode/Emoji.cs b/GameCode/Emoji.cs new file mode 100644 index 0000000..14f1e06 --- /dev/null +++ b/GameCode/Emoji.cs @@ -0,0 +1,7 @@ +using System; + +[Serializable] +public class Emoji +{ + public CharacterItem[] emojiPieces; +} diff --git a/GameCode/EmojiButton.cs b/GameCode/EmojiButton.cs new file mode 100644 index 0000000..08e434a --- /dev/null +++ b/GameCode/EmojiButton.cs @@ -0,0 +1,8 @@ +using UnityEngine; + +public class EmojiButton : MonoBehaviour +{ + private void Update() + { + } +} diff --git a/GameCode/EmojiCombiner.cs b/GameCode/EmojiCombiner.cs new file mode 100644 index 0000000..08039c4 --- /dev/null +++ b/GameCode/EmojiCombiner.cs @@ -0,0 +1,49 @@ +using UnityEngine; + +public class EmojiCombiner : MonoBehaviour +{ + public GameObject currentEmoji; + + public void AddEmoji(GameObject newEmoji) + { + CharacterItem characterItem = FindEmojiPiece(currentEmoji, "M"); + CharacterItem characterItem2 = FindEmojiPiece(newEmoji, "M"); + float delta = GetDelta(characterItem, characterItem2); + CharacterItem characterItem3 = FindEmojiPiece(currentEmoji, "E"); + CharacterItem characterItem4 = FindEmojiPiece(newEmoji, "E"); + float delta2 = GetDelta(characterItem3, characterItem4); + if (delta > delta2) + { + Object.Destroy(characterItem.gameObject); + GameObject obj = Object.Instantiate(characterItem2.gameObject); + obj.transform.SetParent(currentEmoji.transform); + obj.transform.localPosition = characterItem2.transform.localPosition; + } + else + { + Object.Destroy(characterItem3.gameObject); + GameObject obj2 = Object.Instantiate(characterItem4.gameObject); + obj2.transform.SetParent(currentEmoji.transform); + obj2.transform.localPosition = characterItem4.transform.localPosition; + } + } + + private float GetDelta(CharacterItem from, CharacterItem to) + { + return 1f; + } + + private CharacterItem FindEmojiPiece(GameObject emoji, string target) + { + target = target.ToUpper(); + CharacterItem[] componentsInChildren = emoji.GetComponentsInChildren<CharacterItem>(); + for (int i = 0; i < componentsInChildren.Length; i++) + { + if (componentsInChildren[i].name.ToUpper()[0] == target.ToCharArray()[0]) + { + return componentsInChildren[i]; + } + } + return null; + } +} diff --git a/GameCode/Empower.cs b/GameCode/Empower.cs new file mode 100644 index 0000000..742e29a --- /dev/null +++ b/GameCode/Empower.cs @@ -0,0 +1,110 @@ +using System; +using Sonigon; +using UnityEngine; + +public class Empower : MonoBehaviour +{ + public SoundEvent soundEmpowerSpawn; + + public GameObject addObjectToBullet; + + public float dmgMultiplier = 2f; + + public float speedMultiplier = 2f; + + public Color empowerColor; + + private CharacterData data; + + private ParticleSystem[] parts; + + private Transform particleTransform; + + private bool empowered; + + private bool isOn; + + private void Start() + { + particleTransform = base.transform.GetChild(0); + data = GetComponentInParent<CharacterData>(); + parts = GetComponentsInChildren<ParticleSystem>(); + HealthHandler healthHandler = GetComponentInParent<Player>().data.healthHandler; + healthHandler.reviveAction = (Action)Delegate.Combine(healthHandler.reviveAction, new Action(ResetEmpower)); + Gun gun = data.weaponHandler.gun; + gun.ShootPojectileAction = (Action<GameObject>)Delegate.Combine(gun.ShootPojectileAction, new Action<GameObject>(Attack)); + Block componentInParent = GetComponentInParent<Block>(); + componentInParent.BlockAction = (Action<BlockTrigger.BlockTriggerType>)Delegate.Combine(componentInParent.BlockAction, new Action<BlockTrigger.BlockTriggerType>(Block)); + } + + private void OnDestroy() + { + HealthHandler healthHandler = GetComponentInParent<Player>().data.healthHandler; + healthHandler.reviveAction = (Action)Delegate.Remove(healthHandler.reviveAction, new Action(ResetEmpower)); + Gun gun = data.weaponHandler.gun; + gun.ShootPojectileAction = (Action<GameObject>)Delegate.Remove(gun.ShootPojectileAction, new Action<GameObject>(Attack)); + Block componentInParent = GetComponentInParent<Block>(); + componentInParent.BlockAction = (Action<BlockTrigger.BlockTriggerType>)Delegate.Remove(componentInParent.BlockAction, new Action<BlockTrigger.BlockTriggerType>(Block)); + } + + private void ResetEmpower() + { + empowered = false; + } + + public void Block(BlockTrigger.BlockTriggerType trigger) + { + if (trigger != BlockTrigger.BlockTriggerType.Echo && trigger != BlockTrigger.BlockTriggerType.Empower && trigger != BlockTrigger.BlockTriggerType.ShieldCharge) + { + empowered = true; + } + } + + public void Attack(GameObject projectile) + { + SpawnedAttack component = projectile.GetComponent<SpawnedAttack>(); + if (!component) + { + return; + } + if (empowered) + { + ProjectileHit component2 = projectile.GetComponent<ProjectileHit>(); + MoveTransform component3 = projectile.GetComponent<MoveTransform>(); + component.SetColor(empowerColor); + component2.damage *= dmgMultiplier; + component3.localForce *= speedMultiplier; + if ((bool)addObjectToBullet) + { + UnityEngine.Object.Instantiate(addObjectToBullet, projectile.transform.position, projectile.transform.rotation, projectile.transform); + } + } + empowered = false; + } + + private void Update() + { + if (empowered) + { + particleTransform.transform.position = data.weaponHandler.gun.transform.position; + particleTransform.transform.rotation = data.weaponHandler.gun.transform.rotation; + if (!isOn) + { + SoundManager.Instance.PlayAtPosition(soundEmpowerSpawn, SoundManager.Instance.GetTransform(), base.transform); + for (int i = 0; i < parts.Length; i++) + { + parts[i].Play(); + } + isOn = true; + } + } + else if (isOn) + { + for (int j = 0; j < parts.Length; j++) + { + parts[j].Stop(); + } + isOn = false; + } + } +} diff --git a/GameCode/EmpowerStopBlockObjectFollow.cs b/GameCode/EmpowerStopBlockObjectFollow.cs new file mode 100644 index 0000000..dd64869 --- /dev/null +++ b/GameCode/EmpowerStopBlockObjectFollow.cs @@ -0,0 +1,25 @@ +using System; +using UnityEngine; + +public class EmpowerStopBlockObjectFollow : MonoBehaviour +{ + private void Start() + { + Block componentInParent = GetComponentInParent<Block>(); + componentInParent.BlockAction = (Action<BlockTrigger.BlockTriggerType>)Delegate.Combine(componentInParent.BlockAction, new Action<BlockTrigger.BlockTriggerType>(Block)); + } + + private void OnDestroy() + { + Block componentInParent = GetComponentInParent<Block>(); + componentInParent.BlockAction = (Action<BlockTrigger.BlockTriggerType>)Delegate.Remove(componentInParent.BlockAction, new Action<BlockTrigger.BlockTriggerType>(Block)); + } + + private void Block(BlockTrigger.BlockTriggerType triggerTyp) + { + if (triggerTyp == BlockTrigger.BlockTriggerType.Empower && (bool)GetComponent<SpawnObjects>()) + { + GetComponent<SpawnObjects>().mostRecentlySpawnedObject.GetComponent<FollowPlayer>().enabled = false; + } + } +} diff --git a/GameCode/EmptySprite.cs b/GameCode/EmptySprite.cs new file mode 100644 index 0000000..4442b89 --- /dev/null +++ b/GameCode/EmptySprite.cs @@ -0,0 +1,24 @@ +using UnityEngine; + +public static class EmptySprite +{ + private static Sprite instance; + + public static Sprite Get() + { + if (instance == null) + { + instance = Resources.Load<Sprite>("procedural_ui_image_default_sprite"); + } + return instance; + } + + public static bool IsEmptySprite(Sprite s) + { + if (Get() == s) + { + return true; + } + return false; + } +} diff --git a/GameCode/EnableEvent.cs b/GameCode/EnableEvent.cs new file mode 100644 index 0000000..2a2cfa0 --- /dev/null +++ b/GameCode/EnableEvent.cs @@ -0,0 +1,12 @@ +using UnityEngine; +using UnityEngine.Events; + +public class EnableEvent : MonoBehaviour +{ + public UnityEvent enableEvent; + + public void OnEnable() + { + enableEvent.Invoke(); + } +} diff --git a/GameCode/EnableObjectPerLevel.cs b/GameCode/EnableObjectPerLevel.cs new file mode 100644 index 0000000..ce1606c --- /dev/null +++ b/GameCode/EnableObjectPerLevel.cs @@ -0,0 +1,12 @@ +using UnityEngine; + +public class EnableObjectPerLevel : MonoBehaviour +{ + private void Start() + { + } + + private void Update() + { + } +} diff --git a/GameCode/EnsnareEffect.cs b/GameCode/EnsnareEffect.cs new file mode 100644 index 0000000..834d154 --- /dev/null +++ b/GameCode/EnsnareEffect.cs @@ -0,0 +1,98 @@ +using Sirenix.OdinInspector; +using Sonigon; +using UnityEngine; + +public class EnsnareEffect : MonoBehaviour +{ + [Header("Sounds")] + public SoundEvent soundEnsnare; + + public SoundEvent soundEnsnareBreak; + + public bool soundEnsnareJumpChange; + + public float range = 1f; + + private float seconds = 1f; + + public float force = 2000f; + + public float breakDistance = 2f; + + public float drag = 0.98f; + + private CharacterData target; + + private Vector2 startPos; + + public bool startPosIsMyPos; + + private float scale = 1f; + + private LineEffect line; + + [FoldoutGroup("SNAP", 0)] + public float snapCapLineTime = 0.5f; + + [FoldoutGroup("SNAP", 0)] + public float snapCapTimeTime = 0.5f; + + private bool done; + + private bool doneDone; + + private void Start() + { + scale *= base.transform.localScale.x; + range *= (1f + base.transform.localScale.x) * 0.5f; + Player closestPlayer = PlayerManager.instance.GetClosestPlayer(base.transform.position, needVision: true); + if ((bool)closestPlayer && Vector3.Distance(base.transform.position, closestPlayer.transform.position) < range) + { + target = closestPlayer.data; + startPos = target.transform.position; + if (startPosIsMyPos) + { + startPos = base.transform.position; + } + float bezierOffset = 1f; + if (startPosIsMyPos) + { + bezierOffset = 0f; + } + line = GetComponentInChildren<LineEffect>(includeInactive: true); + line.Play(base.transform, closestPlayer.transform, bezierOffset); + if (soundEnsnare != null) + { + SoundManager.Instance.Play(soundEnsnare, target.transform); + } + if (soundEnsnareJumpChange) + { + target.playerSounds.AddEnsnareEffect(this); + } + } + } + + private void FixedUpdate() + { + if (!target || !(line.currentWidth > 0f)) + { + return; + } + target.sinceGrounded = 0f; + target.playerVel.velocity *= Mathf.Pow(drag, scale); + target.playerVel.AddForce(Vector2.ClampMagnitude(startPos - (Vector2)target.transform.position, 60f) * scale * force, ForceMode2D.Force); + if (!done && Vector2.Distance(startPos, target.transform.position) > breakDistance) + { + done = true; + line.counter = Mathf.Clamp(line.counter, snapCapLineTime, float.PositiveInfinity); + if (soundEnsnareJumpChange) + { + target.playerSounds.RemoveEnsnareEffect(this); + } + if (soundEnsnareBreak != null) + { + SoundManager.Instance.Play(soundEnsnareBreak, target.transform); + } + } + } +} diff --git a/GameCode/ErrorHandler.cs b/GameCode/ErrorHandler.cs new file mode 100644 index 0000000..e9ffc17 --- /dev/null +++ b/GameCode/ErrorHandler.cs @@ -0,0 +1,30 @@ +using TMPro; +using UnityEngine; + +public class ErrorHandler : MonoBehaviour +{ + public static ErrorHandler instance; + + public TextMeshProUGUI contextText; + + public TextMeshProUGUI reasonText; + + public GameObject UI; + + private void Awake() + { + instance = this; + } + + public void ShowError(string context, string reason) + { + contextText.text = context; + reasonText.text = reason; + UI.SetActive(value: true); + } + + public void HideError() + { + UI.SetActive(value: false); + } +} diff --git a/GameCode/EscapeMenuHandler.cs b/GameCode/EscapeMenuHandler.cs new file mode 100644 index 0000000..0204501 --- /dev/null +++ b/GameCode/EscapeMenuHandler.cs @@ -0,0 +1,62 @@ +using InControl; +using UnityEngine; + +public class EscapeMenuHandler : MonoBehaviour +{ + public static bool isEscMenu; + + public GameObject[] togglers; + + public GameObject canvs; + + private void Start() + { + isEscMenu = false; + } + + private void Update() + { + if (CharacterCreatorHandler.instance.SomeoneIsEditing() || canvs.activeInHierarchy) + { + return; + } + if (Input.GetKeyDown(KeyCode.Escape)) + { + ToggleEsc(); + } + for (int i = 0; i < InputManager.ActiveDevices.Count; i++) + { + if (InputManager.ActiveDevices[i].CommandWasPressed) + { + ToggleEsc(); + } + } + } + + public void ToggleEsc() + { + isEscMenu = !isEscMenu; + if (isEscMenu) + { + ListMenu.instance.SelectButton(GetComponentInChildren<ListMenuPage>().firstSelected); + } + else + { + ListMenu.instance.SelectButton(GetComponentsInChildren<ListMenuButton>()[1]); + } + for (int i = 0; i < togglers.Length; i++) + { + togglers[i].SetActive(isEscMenu); + } + if (isEscMenu) + { + ListMenu.instance.SelectButton(GetComponentInChildren<ListMenuPage>().firstSelected); + return; + } + ListMenuButton[] componentsInChildren = GetComponentsInChildren<ListMenuButton>(includeInactive: true); + if (componentsInChildren.Length > 2) + { + ListMenu.instance.SelectButton(componentsInChildren[1]); + } + } +} diff --git a/GameCode/EventSequence.cs b/GameCode/EventSequence.cs new file mode 100644 index 0000000..f875669 --- /dev/null +++ b/GameCode/EventSequence.cs @@ -0,0 +1,52 @@ +using System.Collections; +using UnityEngine; + +public class EventSequence : MonoBehaviour +{ + public bool playOnAwake = true; + + public bool useTimeScale = true; + + public DelayedEvent[] events; + + private int level; + + private void Start() + { + level = GetComponentInParent<AttackLevel>().attackLevel; + if (playOnAwake) + { + Go(); + } + } + + public void Go() + { + StartCoroutine(DoSequence()); + } + + private IEnumerator DoSequence() + { + for (int i = 0; i < events.Length; i++) + { + float num = 0f; + for (int i2 = 0; i2 < events[i].cycles + events[i].cyclesPerLvl * level; i2++) + { + num += events[i].delay; + if (num > TimeHandler.deltaTime) + { + if (useTimeScale) + { + yield return new WaitForSeconds(num); + } + else + { + yield return new WaitForSecondsRealtime(num); + } + num = 0f; + } + events[i].eventTrigger.Invoke(); + } + } + } +} diff --git a/GameCode/ExceptionThrown.cs b/GameCode/ExceptionThrown.cs new file mode 100644 index 0000000..1ba81e0 --- /dev/null +++ b/GameCode/ExceptionThrown.cs @@ -0,0 +1,3 @@ +using System; + +public delegate void ExceptionThrown(Exception exeption); diff --git a/GameCode/Explosion.cs b/GameCode/Explosion.cs new file mode 100644 index 0000000..02af031 --- /dev/null +++ b/GameCode/Explosion.cs @@ -0,0 +1,216 @@ +using System; +using Photon.Pun; +using Sirenix.OdinInspector; +using Sonigon; +using UnityEngine; + +public class Explosion : MonoBehaviour +{ + [Header("Sounds")] + public SoundEvent soundDamage; + + [Header("Settings")] + public float slow; + + public float silence; + + public bool fastSlow; + + public float stun; + + public float force = 2000f; + + public float objectForceMultiplier = 1f; + + public bool forceIgnoreMass; + + public float damage = 25f; + + public Color dmgColor = Color.black; + + public float range = 2f; + + public float flyingFor; + + public bool auto = true; + + public bool ignoreTeam; + + public bool ignoreWalls; + + public bool staticRangeMultiplier; + + [FoldoutGroup("Scaling", 0)] + public bool scaleSlow = true; + + [FoldoutGroup("Scaling", 0)] + public bool scaleSilence = true; + + [FoldoutGroup("Scaling", 0)] + public bool scaleDmg = true; + + [FoldoutGroup("Scaling", 0)] + public bool scaleRadius = true; + + [FoldoutGroup("Scaling", 0)] + public bool scaleStun = true; + + [FoldoutGroup("Scaling", 0)] + public bool scaleForce = true; + + [FoldoutGroup("Immunity", 0)] + public float immunity; + + private SpawnedAttack spawned; + + public bool locallySimulated; + + public Action<Damagable> DealDamageAction; + + public Action<Damagable> DealHealAction; + + public Action<Damagable, float> HitTargetAction; + + private PhotonView view; + + public Action<CharacterData, float> hitPlayerAction; + + private void Start() + { + spawned = GetComponent<SpawnedAttack>(); + view = GetComponent<PhotonView>(); + if (auto) + { + Explode(); + } + } + + private void DoExplosionEffects(Collider2D hitCol, float rangeMultiplier, float distance) + { + float num = (scaleDmg ? base.transform.localScale.x : 1f); + float num2 = (scaleForce ? base.transform.localScale.x : 1f); + float num3 = (scaleSlow ? base.transform.localScale.x : 1f); + float num4 = (scaleSilence ? base.transform.localScale.x : 1f); + float num5 = (scaleStun ? ((1f + base.transform.localScale.x) * 0.5f) : 1f); + Damagable componentInParent = hitCol.gameObject.GetComponentInParent<Damagable>(); + CharacterData characterData = null; + if ((bool)componentInParent) + { + characterData = hitCol.gameObject.GetComponentInParent<CharacterData>(); + if ((immunity > 0f && (bool)characterData && characterData.GetComponent<PlayerImmunity>().IsImune(immunity, num * damage * rangeMultiplier, base.gameObject.name)) || (!ignoreWalls && (bool)characterData && !PlayerManager.instance.CanSeePlayer(base.transform.position, characterData.player).canSee)) + { + return; + } + if (slow != 0f && (bool)componentInParent.GetComponent<CharacterStatModifiers>()) + { + if (locallySimulated) + { + if (spawned.IsMine() && !characterData.block.IsBlocking()) + { + characterData.stats.RPCA_AddSlow(slow * rangeMultiplier * num3, fastSlow); + } + } + else if (spawned.IsMine() && !characterData.block.IsBlocking()) + { + characterData.view.RPC("RPCA_AddSlow", RpcTarget.All, slow * rangeMultiplier * num3, fastSlow); + } + } + if (silence != 0f && (bool)componentInParent.GetComponent<SilenceHandler>() && spawned.IsMine() && !characterData.block.IsBlocking()) + { + characterData.view.RPC("RPCA_AddSilence", RpcTarget.All, silence * rangeMultiplier * num4); + } + if ((bool)spawned) + { + _ = spawned.spawner; + } + hitPlayerAction?.Invoke(characterData, rangeMultiplier); + if (damage < 0f) + { + if ((bool)characterData) + { + characterData.healthHandler.Heal(0f - damage); + } + if (DealHealAction != null) + { + DealHealAction(componentInParent); + } + } + else if (damage > 0f) + { + if (soundDamage != null && characterData != null) + { + SoundManager.Instance.Play(soundDamage, characterData.transform); + } + Vector2 vector = ((Vector2)hitCol.bounds.ClosestPoint(base.transform.position) - (Vector2)base.transform.position).normalized; + if (vector == Vector2.zero) + { + vector = Vector2.up; + } + if (spawned.IsMine()) + { + componentInParent.CallTakeDamage(num * damage * rangeMultiplier * vector, base.transform.position, null, spawned.spawner); + } + if (DealDamageAction != null) + { + DealDamageAction(componentInParent); + } + } + } + if ((bool)characterData) + { + if (HitTargetAction != null) + { + HitTargetAction(componentInParent, distance); + } + if (force != 0f) + { + if (locallySimulated) + { + characterData.healthHandler.TakeForce(((Vector2)hitCol.bounds.ClosestPoint(base.transform.position) - (Vector2)base.transform.position).normalized * rangeMultiplier * force * num2, ForceMode2D.Impulse, forceIgnoreMass); + } + else if (spawned.IsMine()) + { + characterData.healthHandler.CallTakeForce(((Vector2)hitCol.bounds.ClosestPoint(base.transform.position) - (Vector2)base.transform.position).normalized * rangeMultiplier * force * num2, ForceMode2D.Impulse, forceIgnoreMass, ignoreBlock: false, flyingFor * rangeMultiplier); + } + } + if (stun > 0f) + { + characterData.stunHandler.AddStun(stun * num5); + } + } + else if ((bool)hitCol.attachedRigidbody) + { + hitCol.attachedRigidbody.AddForce(((Vector2)hitCol.bounds.ClosestPoint(base.transform.position) - (Vector2)base.transform.position).normalized * rangeMultiplier * force * num2, ForceMode2D.Impulse); + } + } + + public void Explode() + { + float num = (scaleRadius ? base.transform.localScale.x : 1f); + Collider2D[] array = Physics2D.OverlapCircleAll(base.transform.position, range * num); + for (int i = 0; i < array.Length; i++) + { + if (array[i].gameObject.layer != 19) + { + Damagable componentInParent = array[i].gameObject.GetComponentInParent<Damagable>(); + float num2 = Vector2.Distance(base.transform.position, array[i].bounds.ClosestPoint(base.transform.position)); + float value = 1f - num2 / (range * num); + if (staticRangeMultiplier) + { + value = 1f; + } + value = Mathf.Clamp(value, 0f, 1f); + NetworkPhysicsObject component = array[i].GetComponent<NetworkPhysicsObject>(); + if ((bool)component && component.photonView.IsMine) + { + float num3 = (scaleForce ? base.transform.localScale.x : 1f); + component.BulletPush((Vector2)(component.transform.position - base.transform.position).normalized * objectForceMultiplier * 1f * value * force * num3, Vector2.zero, null); + } + if (((bool)componentInParent || (bool)array[i].attachedRigidbody) && (!ignoreTeam || !spawned || !(spawned.spawner.gameObject == array[i].transform.gameObject))) + { + DoExplosionEffects(array[i], value, num2); + } + } + } + } +} diff --git a/GameCode/Explosion_Overpower.cs b/GameCode/Explosion_Overpower.cs new file mode 100644 index 0000000..13a98ac --- /dev/null +++ b/GameCode/Explosion_Overpower.cs @@ -0,0 +1,23 @@ +using System; +using UnityEngine; + +public class Explosion_Overpower : MonoBehaviour +{ + public float dmgPer100Hp; + + private void Awake() + { + Explosion component = GetComponent<Explosion>(); + component.hitPlayerAction = (Action<CharacterData, float>)Delegate.Combine(component.hitPlayerAction, new Action<CharacterData, float>(HitPlayer)); + } + + private void HitPlayer(CharacterData data, float rangeMultiplier) + { + SpawnedAttack component = GetComponent<SpawnedAttack>(); + if (component.IsMine()) + { + float num = component.spawner.data.maxHealth * dmgPer100Hp * 0.01f * base.transform.localScale.x; + data.healthHandler.CallTakeDamage(num * (data.transform.position - component.spawner.transform.position).normalized, base.transform.position, null, GetComponent<SpawnedAttack>().spawner); + } + } +} diff --git a/GameCode/Extensions.cs b/GameCode/Extensions.cs new file mode 100644 index 0000000..41040bc --- /dev/null +++ b/GameCode/Extensions.cs @@ -0,0 +1,19 @@ +using System; + +public static class Extensions +{ + public static double NextGaussianDouble(this Random r) + { + double num; + double num3; + do + { + num = 2.0 * r.NextDouble() - 1.0; + double num2 = 2.0 * r.NextDouble() - 1.0; + num3 = num * num + num2 * num2; + } + while (num3 >= 1.0); + double num4 = Math.Sqrt(-2.0 * Math.Log(num3) / num3); + return num * num4; + } +} diff --git a/GameCode/ExtraBlock.cs b/GameCode/ExtraBlock.cs new file mode 100644 index 0000000..a14cdab --- /dev/null +++ b/GameCode/ExtraBlock.cs @@ -0,0 +1,16 @@ +using UnityEngine; + +public class ExtraBlock : MonoBehaviour +{ + private CharacterData data; + + private void Start() + { + data = GetComponentInParent<CharacterData>(); + } + + public void Go() + { + data.block.RPCA_DoBlock(firstBlock: false, dontSetCD: true); + } +} diff --git a/GameCode/FRILerp.cs b/GameCode/FRILerp.cs new file mode 100644 index 0000000..f27815b --- /dev/null +++ b/GameCode/FRILerp.cs @@ -0,0 +1,48 @@ +using UnityEngine; + +public class FRILerp : MonoBehaviour +{ + private void Start() + { + } + + public static Vector3 Lerp(Vector3 from, Vector3 target, float speed) + { + return Vector3.Lerp(from, target, 1f - Mathf.Exp((0f - speed) * TimeHandler.deltaTime)); + } + + public static Vector3 LerpUnclamped(Vector3 from, Vector3 target, float speed) + { + return Vector3.LerpUnclamped(from, target, 1f - Mathf.Exp((0f - speed) * TimeHandler.deltaTime)); + } + + public static float Lerp(float from, float target, float speed) + { + return Mathf.Lerp(from, target, 1f - Mathf.Exp((0f - speed) * TimeHandler.deltaTime)); + } + + public static float LerpUnclamped(float from, float target, float speed) + { + return Mathf.LerpUnclamped(from, target, 1f - Mathf.Exp((0f - speed) * TimeHandler.deltaTime)); + } + + public static Vector3 Slerp(Vector3 from, Vector3 target, float speed) + { + return Vector3.Slerp(from, target, 1f - Mathf.Exp((0f - speed) * TimeHandler.deltaTime)); + } + + public static Vector3 SlerpUnclamped(Vector3 from, Vector3 target, float speed) + { + return Vector3.SlerpUnclamped(from, target, 1f - Mathf.Exp((0f - speed) * TimeHandler.deltaTime)); + } + + public static Quaternion Lerp(Quaternion from, Quaternion target, float speed) + { + return Quaternion.Lerp(from, target, 1f - Mathf.Exp((0f - speed) * TimeHandler.deltaTime)); + } + + public static Quaternion LerpUnclamped(Quaternion from, Quaternion target, float speed) + { + return Quaternion.LerpUnclamped(from, target, 1f - Mathf.Exp((0f - speed) * TimeHandler.deltaTime)); + } +} diff --git a/GameCode/FakeParticleDB.cs b/GameCode/FakeParticleDB.cs new file mode 100644 index 0000000..0e82935 --- /dev/null +++ b/GameCode/FakeParticleDB.cs @@ -0,0 +1,33 @@ +using UnityEngine; + +[CreateAssetMenu(fileName = "FakeParticleDB", menuName = "FakeParticleDB", order = 999999999)] +public class FakeParticleDB : ScriptableObject +{ + public Material m_DefaultMaterial; + + public Material m_ParticleMaterial; + + private static FakeParticleDB _inst; + + private static FakeParticleDB instance + { + get + { + if (_inst == null) + { + _inst = Resources.Load("FakeParticleDB") as FakeParticleDB; + } + return _inst; + } + } + + public static Material GetParticleMaterial() + { + return instance.m_ParticleMaterial; + } + + public static Material GetDefaultMaterial() + { + return instance.m_DefaultMaterial; + } +} diff --git a/GameCode/FlickerEvent.cs b/GameCode/FlickerEvent.cs new file mode 100644 index 0000000..dd4096e --- /dev/null +++ b/GameCode/FlickerEvent.cs @@ -0,0 +1,48 @@ +using UnityEngine; +using UnityEngine.Events; + +public class FlickerEvent : MonoBehaviour +{ + public UnityEvent onEvent; + + public UnityEvent offEvent; + + public float interval; + + private float c; + + public bool isOn; + + private bool flickedOn; + + private void Start() + { + } + + private void Update() + { + c += TimeHandler.deltaTime; + if (isOn) + { + if (c > interval) + { + flickedOn = !flickedOn; + if (flickedOn) + { + onEvent.Invoke(); + } + else + { + offEvent.Invoke(); + } + c = 0f; + } + } + else if (flickedOn && c > interval) + { + c = 0f; + offEvent.Invoke(); + flickedOn = false; + } + } +} diff --git a/GameCode/FollowInactiveHand.cs b/GameCode/FollowInactiveHand.cs new file mode 100644 index 0000000..a52b5e7 --- /dev/null +++ b/GameCode/FollowInactiveHand.cs @@ -0,0 +1,29 @@ +using UnityEngine; + +public class FollowInactiveHand : MonoBehaviour +{ + private CharacterData data; + + public Vector3 offSet; + + public GameObject leftHand; + + public GameObject rightHand; + + private void Start() + { + data = base.transform.root.GetComponent<CharacterData>(); + } + + private void Update() + { + if (data.aimDirection.x < 0f) + { + base.transform.position = rightHand.transform.TransformPoint(offSet); + } + else + { + base.transform.position = leftHand.transform.TransformPoint(offSet); + } + } +} diff --git a/GameCode/FollowLocalPos.cs b/GameCode/FollowLocalPos.cs new file mode 100644 index 0000000..194f947 --- /dev/null +++ b/GameCode/FollowLocalPos.cs @@ -0,0 +1,57 @@ +using UnityEngine; + +public class FollowLocalPos : MonoBehaviour +{ + private Vector3 relative; + + private Vector3 relativeForward; + + private Vector3 relativeUp; + + public Transform target; + + public Player targetPlayer; + + private void Start() + { + if ((bool)target && relative == Vector3.zero) + { + Follow(target); + } + } + + private void LateUpdate() + { + if ((bool)target && target.gameObject.activeInHierarchy) + { + base.transform.position = target.TransformPoint(relative); + base.transform.rotation = Quaternion.LookRotation(target.TransformDirection(relativeForward), target.TransformDirection(relativeUp)); + } + else + { + Object.Destroy(base.gameObject); + } + } + + public void Follow(Transform targetTransform) + { + if ((bool)targetTransform) + { + target = targetTransform; + Player component = target.transform.root.GetComponent<Player>(); + Vector3 position = base.transform.position; + if ((bool)component) + { + targetPlayer = component; + base.transform.position -= base.transform.forward * 2f; + Vector3 position2 = target.position; + Vector3 vector = (base.transform.position - target.position).normalized * 1.1f; + position = position2 + vector; + base.transform.position = new Vector3(base.transform.position.x, base.transform.position.y, component.transform.position.z); + } + relative = targetTransform.InverseTransformPoint(position); + relativeForward = targetTransform.InverseTransformDirection(base.transform.forward); + relativeUp = targetTransform.InverseTransformDirection(base.transform.up); + } + } +} diff --git a/GameCode/FollowPlayer.cs b/GameCode/FollowPlayer.cs new file mode 100644 index 0000000..cd3c826 --- /dev/null +++ b/GameCode/FollowPlayer.cs @@ -0,0 +1,40 @@ +using UnityEngine; + +public class FollowPlayer : MonoBehaviour +{ + public enum Target + { + Self, + Other + } + + public Target target; + + public bool inheritScale = true; + + private Vector3 startScale; + + private Player ownPlayer; + + private void Start() + { + startScale = base.transform.localScale; + ownPlayer = GetComponentInParent<Player>(); + if (!ownPlayer) + { + ownPlayer = GetComponentInParent<SpawnedAttack>().spawner; + } + } + + private void LateUpdate() + { + Player player = null; + player = ((target != Target.Other) ? ownPlayer : PlayerManager.instance.GetOtherPlayer(ownPlayer)); + if (inheritScale) + { + base.transform.localScale = new Vector3(player.transform.localScale.x * startScale.x, player.transform.localScale.y * startScale.y, player.transform.localScale.z * startScale.z); + } + base.transform.position = player.transform.position; + base.transform.rotation = player.transform.rotation; + } +} diff --git a/GameCode/FollowRandomPlayer.cs b/GameCode/FollowRandomPlayer.cs new file mode 100644 index 0000000..c8d8516 --- /dev/null +++ b/GameCode/FollowRandomPlayer.cs @@ -0,0 +1,40 @@ +using UnityEngine; + +public class FollowRandomPlayer : MonoBehaviour +{ + public bool X = true; + + public bool Y = true; + + private Transform targetPlayer; + + public bool snap; + + private void Start() + { + } + + private void Update() + { + if (!targetPlayer) + { + GetNewPlayer(); + } + else if (snap) + { + base.transform.position = new Vector3(X ? targetPlayer.position.x : base.transform.position.x, Y ? targetPlayer.position.y : base.transform.position.y, 0f); + } + else + { + base.transform.position = Vector3.Lerp(base.transform.position, new Vector3(X ? targetPlayer.position.x : base.transform.position.x, Y ? targetPlayer.position.y : base.transform.position.y, 0f), TimeHandler.deltaTime * 5f); + } + } + + private void GetNewPlayer() + { + if (PlayerManager.instance.players.Count > 0) + { + targetPlayer = PlayerManager.instance.players[Random.Range(0, PlayerManager.instance.players.Count)].transform; + } + } +} diff --git a/GameCode/FollowScale.cs b/GameCode/FollowScale.cs new file mode 100644 index 0000000..6666c05 --- /dev/null +++ b/GameCode/FollowScale.cs @@ -0,0 +1,14 @@ +using UnityEngine; + +public class FollowScale : MonoBehaviour +{ + public Transform target; + + private void Update() + { + if ((bool)target) + { + base.transform.localScale = target.transform.localScale; + } + } +} diff --git a/GameCode/FollowTransform.cs b/GameCode/FollowTransform.cs new file mode 100644 index 0000000..32c0671 --- /dev/null +++ b/GameCode/FollowTransform.cs @@ -0,0 +1,23 @@ +using UnityEngine; + +public class FollowTransform : MonoBehaviour +{ + public Transform target; + + private Vector3 spawnOffset; + + public Vector3 offset; + + private void Start() + { + spawnOffset = base.transform.position - target.position; + } + + private void LateUpdate() + { + if ((bool)target) + { + base.transform.position = target.position + spawnOffset + offset; + } + } +} diff --git a/GameCode/ForceMultiplier.cs b/GameCode/ForceMultiplier.cs new file mode 100644 index 0000000..064bbfc --- /dev/null +++ b/GameCode/ForceMultiplier.cs @@ -0,0 +1,6 @@ +using UnityEngine; + +public class ForceMultiplier : MonoBehaviour +{ + public float multiplier = 1f; +} diff --git a/GameCode/FreeModifier.cs b/GameCode/FreeModifier.cs new file mode 100644 index 0000000..4f8badf --- /dev/null +++ b/GameCode/FreeModifier.cs @@ -0,0 +1,35 @@ +using UnityEngine; +using UnityEngine.UI.ProceduralImage; + +[ModifierID("Free")] +public class FreeModifier : ProceduralImageModifier +{ + [SerializeField] + private Vector4 radius; + + public Vector4 Radius + { + get + { + return radius; + } + set + { + radius = value; + base._Graphic.SetVerticesDirty(); + } + } + + public override Vector4 CalculateRadius(Rect imageRect) + { + return radius; + } + + protected void OnValidate() + { + radius.x = Mathf.Max(0f, radius.x); + radius.y = Mathf.Max(0f, radius.y); + radius.z = Mathf.Max(0f, radius.z); + radius.w = Mathf.Max(0f, radius.w); + } +} diff --git a/GameCode/GM_ArmsRace.cs b/GameCode/GM_ArmsRace.cs new file mode 100644 index 0000000..3d309ae --- /dev/null +++ b/GameCode/GM_ArmsRace.cs @@ -0,0 +1,465 @@ +using System; +using System.Collections; +using Photon.Pun; +using UnityEngine; + +public class GM_ArmsRace : MonoBehaviour +{ + private int playersNeededToStart = 2; + + private int pointsToWinRound = 2; + + public int roundsToWinGame = 5; + + public int p1Points; + + public int p2Points; + + public int p1Rounds; + + public int p2Rounds; + + private PhotonView view; + + public static GM_ArmsRace instance; + + private bool isWaiting; + + public Action StartGameAction; + + public bool pickPhase = true; + + [HideInInspector] + public bool isPicking; + + private bool waitingForOtherPlayer = true; + + private int currentWinningTeamID = -1; + + public Action pointOverAction; + + private bool isTransitioning; + + private void Awake() + { + instance = this; + } + + private void Start() + { + view = GetComponent<PhotonView>(); + PlayerManager.instance.SetPlayersSimulated(simulated: false); + PlayerAssigner.instance.maxPlayers = playersNeededToStart; + PlayerAssigner.instance.SetPlayersCanJoin(canJoin: true); + PlayerManager.instance.AddPlayerDiedAction(PlayerDied); + PlayerManager playerManager = PlayerManager.instance; + playerManager.PlayerJoinedAction = (Action<Player>)Delegate.Combine(playerManager.PlayerJoinedAction, new Action<Player>(PlayerJoined)); + ArtHandler.instance.NextArt(); + playersNeededToStart = 2; + UIHandler.instance.SetNumberOfRounds(roundsToWinGame); + PlayerAssigner.instance.maxPlayers = playersNeededToStart; + if (!PhotonNetwork.OfflineMode) + { + UIHandler.instance.ShowJoinGameText("PRESS JUMP\n TO JOIN", PlayerSkinBank.GetPlayerSkinColors(0).winText); + } + } + + private void Update() + { + if (Input.GetKey(KeyCode.Alpha4)) + { + playersNeededToStart = 4; + PlayerAssigner.instance.maxPlayers = playersNeededToStart; + } + if (Input.GetKey(KeyCode.Alpha2)) + { + playersNeededToStart = 2; + PlayerAssigner.instance.maxPlayers = playersNeededToStart; + } + } + + public void PlayerJoined(Player player) + { + if (PhotonNetwork.OfflineMode) + { + return; + } + if (!PhotonNetwork.OfflineMode) + { + if (player.data.view.IsMine) + { + UIHandler.instance.ShowJoinGameText("WAITING", PlayerSkinBank.GetPlayerSkinColors(1).winText); + } + else + { + UIHandler.instance.ShowJoinGameText("PRESS JUMP\n TO JOIN", PlayerSkinBank.GetPlayerSkinColors(1).winText); + } + } + player.data.isPlaying = false; + int count = PlayerManager.instance.players.Count; + if (count >= playersNeededToStart) + { + StartGame(); + } + else if (PhotonNetwork.OfflineMode) + { + if (playersNeededToStart - count == 3) + { + UIHandler.instance.ShowJoinGameText("ADD THREE MORE PLAYER TO START", PlayerSkinBank.GetPlayerSkinColors(count).winText); + } + if (playersNeededToStart - count == 2) + { + UIHandler.instance.ShowJoinGameText("ADD TWO MORE PLAYER TO START", PlayerSkinBank.GetPlayerSkinColors(count).winText); + } + if (playersNeededToStart - count == 1) + { + UIHandler.instance.ShowJoinGameText("ADD ONE MORE PLAYER TO START", PlayerSkinBank.GetPlayerSkinColors(count).winText); + } + } + } + + [PunRPC] + private void RPCO_RequestSyncUp() + { + view.RPC("RPCM_ReturnSyncUp", RpcTarget.Others); + } + + [PunRPC] + private void RPCM_ReturnSyncUp() + { + isWaiting = false; + } + + private IEnumerator WaitForSyncUp() + { + if (!PhotonNetwork.OfflineMode) + { + isWaiting = true; + view.RPC("RPCO_RequestSyncUp", RpcTarget.Others); + while (isWaiting) + { + yield return null; + } + } + } + + public void StartGame() + { + if (!GameManager.instance.isPlaying) + { + StartGameAction?.Invoke(); + GameManager.instance.isPlaying = true; + StartCoroutine(DoStartGame()); + } + } + + private IEnumerator DoStartGame() + { + GameManager.instance.battleOngoing = false; + UIHandler.instance.ShowJoinGameText("LETS GOO!", PlayerSkinBank.GetPlayerSkinColors(1).winText); + yield return new WaitForSeconds(0.25f); + UIHandler.instance.HideJoinGameText(); + PlayerManager.instance.SetPlayersSimulated(simulated: false); + PlayerManager.instance.SetPlayersVisible(visible: false); + MapManager.instance.LoadNextLevel(); + TimeHandler.instance.DoSpeedUp(); + yield return new WaitForSecondsRealtime(1f); + if (pickPhase) + { + for (int i = 0; i < PlayerManager.instance.players.Count; i++) + { + yield return StartCoroutine(WaitForSyncUp()); + CardChoiceVisuals.instance.Show(i, animateIn: true); + yield return CardChoice.instance.DoPick(1, PlayerManager.instance.players[i].playerID, PickerType.Player); + yield return new WaitForSecondsRealtime(0.1f); + } + yield return StartCoroutine(WaitForSyncUp()); + CardChoiceVisuals.instance.Hide(); + } + MapManager.instance.CallInNewMapAndMovePlayers(MapManager.instance.currentLevelID); + TimeHandler.instance.DoSpeedUp(); + TimeHandler.instance.StartGame(); + GameManager.instance.battleOngoing = true; + UIHandler.instance.ShowRoundCounterSmall(p1Rounds, p2Rounds, p1Points, p2Points); + PlayerManager.instance.SetPlayersVisible(visible: true); + } + + private IEnumerator PointTransition(int winningTeamID, string winTextBefore, string winText) + { + StartCoroutine(PointVisualizer.instance.DoSequence(p1Points, p2Points, winningTeamID == 0)); + yield return new WaitForSecondsRealtime(1f); + MapManager.instance.LoadNextLevel(); + yield return new WaitForSecondsRealtime(0.5f); + yield return StartCoroutine(WaitForSyncUp()); + MapManager.instance.CallInNewMapAndMovePlayers(MapManager.instance.currentLevelID); + PlayerManager.instance.RevivePlayers(); + yield return new WaitForSecondsRealtime(0.3f); + TimeHandler.instance.DoSpeedUp(); + GameManager.instance.battleOngoing = true; + isTransitioning = false; + } + + private void PointOver(int winningTeamID) + { + int num = p1Points; + int num2 = p2Points; + if (winningTeamID == 0) + { + num--; + } + else + { + num2--; + } + string winTextBefore = num + " - " + num2; + string winText = p1Points + " - " + p2Points; + StartCoroutine(PointTransition(winningTeamID, winTextBefore, winText)); + UIHandler.instance.ShowRoundCounterSmall(p1Rounds, p2Rounds, p1Points, p2Points); + } + + private IEnumerator RoundTransition(int winningTeamID, int killedTeamID) + { + StartCoroutine(PointVisualizer.instance.DoWinSequence(p1Points, p2Points, p1Rounds, p2Rounds, winningTeamID == 0)); + yield return new WaitForSecondsRealtime(1f); + MapManager.instance.LoadNextLevel(); + yield return new WaitForSecondsRealtime(0.3f); + yield return new WaitForSecondsRealtime(1f); + TimeHandler.instance.DoSpeedUp(); + if (pickPhase) + { + Debug.Log("PICK PHASE"); + PlayerManager.instance.SetPlayersVisible(visible: false); + Player[] players = PlayerManager.instance.GetPlayersInTeam(killedTeamID); + for (int i = 0; i < players.Length; i++) + { + yield return StartCoroutine(WaitForSyncUp()); + yield return CardChoice.instance.DoPick(1, players[i].playerID, PickerType.Player); + yield return new WaitForSecondsRealtime(0.1f); + } + PlayerManager.instance.SetPlayersVisible(visible: true); + } + yield return StartCoroutine(WaitForSyncUp()); + TimeHandler.instance.DoSlowDown(); + MapManager.instance.CallInNewMapAndMovePlayers(MapManager.instance.currentLevelID); + PlayerManager.instance.RevivePlayers(); + yield return new WaitForSecondsRealtime(0.3f); + TimeHandler.instance.DoSpeedUp(); + isTransitioning = false; + GameManager.instance.battleOngoing = true; + UIHandler.instance.ShowRoundCounterSmall(p1Rounds, p2Rounds, p1Points, p2Points); + } + + private void RoundOver(int winningTeamID, int losingTeamID) + { + currentWinningTeamID = winningTeamID; + StartCoroutine(RoundTransition(winningTeamID, losingTeamID)); + p1Points = 0; + p2Points = 0; + } + + private IEnumerator GameOverTransition(int winningTeamID) + { + UIHandler.instance.ShowRoundCounterSmall(p1Rounds, p2Rounds, p1Points, p2Points); + UIHandler.instance.DisplayScreenText(PlayerManager.instance.GetColorFromTeam(winningTeamID).winText, "VICTORY!", 1f); + yield return new WaitForSecondsRealtime(2f); + GameOverRematch(winningTeamID); + } + + private void GameOverRematch(int winningTeamID) + { + UIHandler.instance.DisplayScreenTextLoop(PlayerManager.instance.GetColorFromTeam(winningTeamID).winText, "REMATCH?"); + UIHandler.instance.DisplayYesNoLoop(PlayerManager.instance.GetFirstPlayerInTeam(winningTeamID), GetRematchYesNo); + MapManager.instance.LoadNextLevel(); + } + + private void GetRematchYesNo(PopUpHandler.YesNo yesNo) + { + if (yesNo == PopUpHandler.YesNo.Yes) + { + StartCoroutine(IDoRematch()); + } + else + { + DoRestart(); + } + } + + [PunRPC] + public void RPCA_PlayAgain() + { + waitingForOtherPlayer = false; + } + + private IEnumerator IDoRematch() + { + if (!PhotonNetwork.OfflineMode) + { + GetComponent<PhotonView>().RPC("RPCA_PlayAgain", RpcTarget.Others); + UIHandler.instance.DisplayScreenTextLoop("WAITING"); + float c = 0f; + while (waitingForOtherPlayer) + { + c += Time.unscaledDeltaTime; + if (c > 10f) + { + DoRestart(); + yield break; + } + yield return null; + } + } + yield return null; + UIHandler.instance.StopScreenTextLoop(); + PlayerManager.instance.ResetCharacters(); + ResetMatch(); + StartCoroutine(DoStartGame()); + waitingForOtherPlayer = true; + } + + private void ResetMatch() + { + p1Points = 0; + p1Rounds = 0; + p2Points = 0; + p2Rounds = 0; + isTransitioning = false; + waitingForOtherPlayer = false; + UIHandler.instance.ShowRoundCounterSmall(p1Rounds, p2Rounds, p1Points, p2Points); + CardBarHandler.instance.ResetCardBards(); + PointVisualizer.instance.ResetPoints(); + } + + private void GameOverContinue(int winningTeamID) + { + UIHandler.instance.DisplayScreenTextLoop(PlayerManager.instance.GetColorFromTeam(winningTeamID).winText, "CONTINUE?"); + UIHandler.instance.DisplayYesNoLoop(PlayerManager.instance.GetFirstPlayerInTeam(winningTeamID), GetContinueYesNo); + MapManager.instance.LoadNextLevel(); + } + + private void GetContinueYesNo(PopUpHandler.YesNo yesNo) + { + if (yesNo == PopUpHandler.YesNo.Yes) + { + DoContinue(); + } + else + { + DoRestart(); + } + } + + private void DoContinue() + { + UIHandler.instance.StopScreenTextLoop(); + roundsToWinGame += 2; + UIHandler.instance.SetNumberOfRounds(roundsToWinGame); + RoundOver(currentWinningTeamID, PlayerManager.instance.GetOtherTeam(currentWinningTeamID)); + } + + private void DoRestart() + { + GameManager.instance.battleOngoing = false; + if (PhotonNetwork.OfflineMode) + { + Application.LoadLevel(Application.loadedLevel); + } + else + { + NetworkConnectionHandler.instance.NetworkRestart(); + } + } + + private void GameOver(int winningTeamID) + { + currentWinningTeamID = winningTeamID; + StartCoroutine(GameOverTransition(winningTeamID)); + } + + public void PlayerDied(Player killedPlayer, int playersAlive) + { + if (!PhotonNetwork.OfflineMode) + { + Debug.Log("PlayerDied: " + killedPlayer.data.view.Owner.NickName); + } + if (PlayerManager.instance.TeamsAlive() < 2) + { + TimeHandler.instance.DoSlowDown(); + if (PhotonNetwork.IsMasterClient) + { + view.RPC("RPCA_NextRound", RpcTarget.All, PlayerManager.instance.GetOtherTeam(PlayerManager.instance.GetLastTeamAlive()), PlayerManager.instance.GetLastTeamAlive(), p1Points, p2Points, p1Rounds, p2Rounds); + } + } + } + + [PunRPC] + public void RPCA_NextRound(int losingTeamID, int winningTeamID, int p1PointsSet, int p2PointsSet, int p1RoundsSet, int p2RoundsSet) + { + if (isTransitioning) + { + return; + } + GameManager.instance.battleOngoing = false; + p1Points = p1PointsSet; + p2Points = p2PointsSet; + p1Rounds = p1RoundsSet; + p2Rounds = p2RoundsSet; + Debug.Log("Winning team: " + winningTeamID); + Debug.Log("Losing team: " + losingTeamID); + isTransitioning = true; + GameManager.instance.GameOver(winningTeamID, losingTeamID); + PlayerManager.instance.SetPlayersSimulated(simulated: false); + switch (winningTeamID) + { + case 0: + p1Points++; + if (p1Points >= pointsToWinRound) + { + p1Rounds++; + if (p1Rounds >= roundsToWinGame) + { + Debug.Log("Game over, winning team: " + winningTeamID); + GameOver(winningTeamID); + pointOverAction(); + } + else + { + Debug.Log("Round over, winning team: " + winningTeamID); + RoundOver(winningTeamID, losingTeamID); + pointOverAction(); + } + } + else + { + Debug.Log("Point over, winning team: " + winningTeamID); + PointOver(winningTeamID); + pointOverAction(); + } + break; + case 1: + p2Points++; + if (p2Points >= pointsToWinRound) + { + p2Rounds++; + if (p2Rounds >= roundsToWinGame) + { + Debug.Log("Game over, winning team: " + winningTeamID); + GameOver(winningTeamID); + pointOverAction(); + } + else + { + Debug.Log("Round over, winning team: " + winningTeamID); + RoundOver(winningTeamID, losingTeamID); + pointOverAction(); + } + } + else + { + Debug.Log("Point over, winning team: " + winningTeamID); + PointOver(winningTeamID); + pointOverAction(); + } + break; + } + } +} diff --git a/GameCode/GM_Test.cs b/GameCode/GM_Test.cs new file mode 100644 index 0000000..b5d7ef6 --- /dev/null +++ b/GameCode/GM_Test.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections; +using UnityEngine; + +public class GM_Test : MonoBehaviour +{ + public bool testMap; + + public static GM_Test instance; + + private void Awake() + { + instance = this; + if (base.gameObject.activeSelf && !Application.isEditor) + { + testMap = false; + } + } + + private void Start() + { + if (testMap) + { + base.transform.root.GetComponent<SetOfflineMode>().SetOffline(); + } + if (testMap) + { + MapManager.instance.isTestingMap = true; + } + if (base.gameObject.activeSelf) + { + if (!testMap) + { + MapManager.instance.LoadNextLevel(callInImidetly: true, forceLoad: true); + } + else + { + MapManager.instance.currentMap = new MapWrapper(UnityEngine.Object.FindObjectOfType<Map>(), UnityEngine.Object.FindObjectOfType<Map>().gameObject.scene); + ArtHandler.instance.NextArt(); + } + PlayerAssigner.instance.SetPlayersCanJoin(canJoin: true); + TimeHandler.instance.StartGame(); + PlayerManager playerManager = PlayerManager.instance; + playerManager.PlayerJoinedAction = (Action<Player>)Delegate.Combine(playerManager.PlayerJoinedAction, new Action<Player>(PlayerWasAdded)); + PlayerManager.instance.AddPlayerDiedAction(PlayerDied); + GameManager.instance.isPlaying = true; + GameManager.instance.battleOngoing = true; + } + } + + private void PlayerWasAdded(Player player) + { + PlayerManager.instance.SetPlayersSimulated(simulated: true); + player.data.GetComponent<PlayerCollision>().IgnoreWallForFrames(2); + player.transform.position = MapManager.instance.currentMap.Map.GetRandomSpawnPos(); + PlayerManager.instance.SetPlayersSimulated(simulated: true); + PlayerManager.instance.SetPlayersPlaying(playing: true); + } + + private void PlayerDied(Player player, int unused) + { + StartCoroutine(DelayRevive(player)); + } + + private IEnumerator DelayRevive(Player player) + { + yield return new WaitForSecondsRealtime(2.5f); + PlayerWasAdded(player); + player.data.healthHandler.Revive(); + } +} diff --git a/GameCode/GameAnalytics.cs b/GameCode/GameAnalytics.cs new file mode 100644 index 0000000..4451ccb --- /dev/null +++ b/GameCode/GameAnalytics.cs @@ -0,0 +1,17 @@ +using UnityEngine; +using UnityEngine.Analytics; + +public class GameAnalytics : MonoBehaviour +{ + private void Start() + { + } + + private void Update() + { + if (Input.GetKeyDown(KeyCode.P)) + { + Analytics.SendEvent("PlayerKills", 5); + } + } +} diff --git a/GameCode/GameCrownHandler.cs b/GameCode/GameCrownHandler.cs new file mode 100644 index 0000000..8e555d5 --- /dev/null +++ b/GameCode/GameCrownHandler.cs @@ -0,0 +1,116 @@ +using System; +using System.Collections; +using UnityEngine; + +public class GameCrownHandler : MonoBehaviour +{ + private float crownPos; + + public AnimationCurve transitionCurve; + + private GM_ArmsRace gm; + + private int currentCrownHolder = -1; + + private void Start() + { + gm = GetComponentInParent<GM_ArmsRace>(); + GM_ArmsRace gM_ArmsRace = gm; + gM_ArmsRace.pointOverAction = (Action)Delegate.Combine(gM_ArmsRace.pointOverAction, new Action(PointOver)); + } + + public void PointOver() + { + int num = -1; + int num2 = -1; + if (gm.p1Rounds > gm.p2Rounds) + { + num2 = 0; + } + if (gm.p1Rounds < gm.p2Rounds) + { + num2 = 1; + } + if (num2 == -1) + { + int num3 = -1; + if (gm.p1Points > gm.p2Points) + { + num3 = 0; + } + if (gm.p1Points < gm.p2Points) + { + num3 = 1; + } + if (num3 != -1) + { + num = num3; + } + } + else + { + num = num2; + } + if (num != -1 && num != currentCrownHolder) + { + if (currentCrownHolder == -1) + { + currentCrownHolder = num; + crownPos = currentCrownHolder; + GetComponent<CurveAnimation>().PlayIn(); + } + else + { + GiveCrownToPlayer(num); + } + } + } + + private void LateUpdate() + { + if (currentCrownHolder == -1) + { + return; + } + if (PlayerManager.instance.players[currentCrownHolder].gameObject.activeInHierarchy) + { + if (!base.transform.GetChild(0).gameObject.activeSelf) + { + base.transform.GetChild(0).gameObject.SetActive(value: true); + } + } + else if (base.transform.GetChild(0).gameObject.activeSelf) + { + base.transform.GetChild(0).gameObject.SetActive(value: false); + } + Vector3 position = Vector3.LerpUnclamped(PlayerManager.instance.players[0].data.GetCrownPos(), PlayerManager.instance.players[1].data.GetCrownPos(), crownPos); + base.transform.position = position; + } + + private void GiveCrownToPlayer(int playerID) + { + currentCrownHolder = playerID; + StartCoroutine(IGiveCrownToPlayer(playerID)); + } + + private IEnumerator IGiveCrownToPlayer(int playerID) + { + int fromInt; + int toInt; + if (playerID == 0) + { + fromInt = 1; + toInt = 0; + } + else + { + fromInt = 0; + toInt = 1; + } + for (float i = 0f; i < transitionCurve.keys[transitionCurve.keys.Length - 1].time; i += Time.unscaledDeltaTime) + { + crownPos = Mathf.LerpUnclamped(fromInt, toInt, transitionCurve.Evaluate(i)); + yield return null; + } + } +} diff --git a/GameCode/GameFeeler.cs b/GameCode/GameFeeler.cs new file mode 100644 index 0000000..7021a3e --- /dev/null +++ b/GameCode/GameFeeler.cs @@ -0,0 +1,18 @@ +using UnityEngine; + +public abstract class GameFeeler : MonoBehaviour +{ + private void Awake() + { + GamefeelManager.RegisterGamefeeler(this); + OnAwake(); + } + + public abstract void OnGameFeel(Vector2 feelDirection); + + public abstract void OnUIGameFeel(Vector2 feelDirection); + + public virtual void OnAwake() + { + } +} diff --git a/GameCode/GameManager.cs b/GameCode/GameManager.cs new file mode 100644 index 0000000..45aaeee --- /dev/null +++ b/GameCode/GameManager.cs @@ -0,0 +1,38 @@ +using System; +using UnityEngine; + +public class GameManager : MonoBehaviour +{ + [Header("Settings")] + public static bool lockInput; + + public static GameManager instance; + + public bool isPlaying; + + public bool battleOngoing; + + public Action<int, int> GameOverAction; + + public void Awake() + { + instance = this; + } + + private void Start() + { + lockInput = false; + } + + private void Update() + { + } + + public void GameOver(int winingTeamID, int killedTeamID) + { + if (GameOverAction != null) + { + GameOverAction(winingTeamID, killedTeamID); + } + } +} diff --git a/GameCode/GamefeelManager.cs b/GameCode/GamefeelManager.cs new file mode 100644 index 0000000..ac99a47 --- /dev/null +++ b/GameCode/GamefeelManager.cs @@ -0,0 +1,60 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class GamefeelManager : MonoBehaviour +{ + public static GamefeelManager instance; + + private List<GameFeeler> m_GameFeelers = new List<GameFeeler>(); + + private void Awake() + { + instance = this; + } + + public static void RegisterGamefeeler(GameFeeler gameFeeler) + { + instance.m_GameFeelers.Add(gameFeeler); + } + + public void AddUIGameFeel(Vector2 directionForce) + { + for (int i = 0; i < instance.m_GameFeelers.Count; i++) + { + instance.m_GameFeelers[i].OnUIGameFeel(directionForce); + } + } + + public void AddGameFeel(Vector2 directionForce) + { + for (int i = 0; i < instance.m_GameFeelers.Count; i++) + { + instance.m_GameFeelers[i].OnGameFeel(directionForce); + } + } + + public static void GameFeel(Vector2 directionForce) + { + for (int i = 0; i < instance.m_GameFeelers.Count; i++) + { + instance.m_GameFeelers[i].OnGameFeel(directionForce); + } + } + + public void AddUIGameFeelOverTime(float amount, float time) + { + StartCoroutine(DoUIGameFeelOverTime(amount, time)); + } + + private IEnumerator DoUIGameFeelOverTime(float amount, float time) + { + float startTime = time; + while (time > 0f) + { + instance.AddUIGameFeel(amount * (Vector2)Random.onUnitSphere * Time.unscaledDeltaTime * (time / startTime)); + time -= Time.unscaledDeltaTime; + yield return null; + } + } +} diff --git a/GameCode/GeneralInput.cs b/GameCode/GeneralInput.cs new file mode 100644 index 0000000..0487def --- /dev/null +++ b/GameCode/GeneralInput.cs @@ -0,0 +1,274 @@ +using System.Collections; +using UnityEngine; + +public class GeneralInput : MonoBehaviour +{ + public enum InputType + { + Controller, + Keyboard, + Either + } + + public enum StickDirection + { + Left, + Right, + None + } + + public bool controlledElseWhere; + + public bool stunnedInput; + + public bool silencedInput; + + public KeyCode left; + + public KeyCode right; + + public KeyCode up; + + public KeyCode down; + + public KeyCode jump; + + public KeyCode shoot; + + public KeyCode shield; + + public Vector3 direction; + + public Vector3 latestPressedDirection; + + public Vector3 aimDirection; + + public Vector3 lastAimDirection; + + public bool jumpWasPressed; + + public bool jumpIsPressed; + + public bool shootWasPressed; + + public bool shootIsPressed; + + public bool shootWasReleased; + + public bool shieldWasPressed; + + public bool acceptWasPressed; + + public InputType inputType; + + private StickDirection lastStickDirection; + + public StickDirection stickPressDir = StickDirection.None; + + private CharacterData data; + + private int snapNumber = 16; + + private void Start() + { + data = GetComponent<CharacterData>(); + } + + public void ResetInput() + { + direction = Vector3.zero; + aimDirection = Vector3.zero; + jumpIsPressed = false; + jumpWasPressed = false; + shootIsPressed = false; + shootWasPressed = false; + shootWasReleased = false; + shieldWasPressed = false; + acceptWasPressed = false; + } + + private void Update() + { + if (controlledElseWhere) + { + return; + } + ResetInput(); + DoUIInput(); + if (GameManager.lockInput || stunnedInput || !data.isPlaying || data.playerActions == null) + { + return; + } + direction += (Vector3)data.playerActions.Move; + direction = MakeEightDirections(direction); + if (direction != Vector3.zero) + { + latestPressedDirection = direction; + } + if (data.playerActions.Device == null) + { + aimDirection = MainCam.instance.cam.ScreenToWorldPoint(Input.mousePosition) - base.transform.position; + aimDirection.z = 0f; + aimDirection.Normalize(); + if (Optionshandler.lockMouse) + { + aimDirection = MakeEightDirections(aimDirection); + } + } + else + { + aimDirection.x += data.playerActions.Aim.X; + aimDirection.y += data.playerActions.Aim.Y; + if (Optionshandler.lockStick) + { + aimDirection = MakeEightDirections(aimDirection); + } + } + if (aimDirection != Vector3.zero) + { + aimDirection += Vector3.up * 0.13f / Mathf.Clamp(data.weaponHandler.gun.projectileSpeed, 1f, 100f); + } + if (aimDirection != Vector3.zero) + { + lastAimDirection = aimDirection; + } + if (data.playerActions.Jump.IsPressed) + { + jumpIsPressed = true; + } + if (data.playerActions.Jump.WasPressed) + { + jumpWasPressed = true; + } + if (!silencedInput) + { + if (data.playerActions.Fire.IsPressed) + { + shootIsPressed = true; + } + if (data.playerActions.Fire.WasPressed) + { + shootWasPressed = true; + } + if (data.playerActions.Fire.WasReleased) + { + shootWasReleased = true; + } + if (data.playerActions.Block.WasPressed) + { + shieldWasPressed = true; + } + } + } + + private void DoUIInput() + { + StickDirection stickDirection = StickDirection.None; + if (data.playerActions.Move.X > 0.7f) + { + stickDirection = StickDirection.Right; + } + if (data.playerActions.Move.X < -0.7f) + { + stickDirection = StickDirection.Left; + } + if (stickDirection != lastStickDirection) + { + stickPressDir = stickDirection; + lastStickDirection = stickDirection; + } + else + { + stickPressDir = StickDirection.None; + } + if (data.playerActions.Jump.WasPressed) + { + acceptWasPressed = true; + } + } + + public void DoStun(float stun) + { + if (base.gameObject.activeSelf) + { + StartCoroutine(Stun(stun)); + } + } + + private IEnumerator Stun(float stun) + { + base.enabled = false; + ResetInput(); + yield return new WaitForSeconds(stun); + base.enabled = true; + } + + public void SetState(Vector3 pos, bool isGrounded) + { + base.transform.position = pos; + } + + public void Move(bool right, bool left, bool up, bool down, bool jump) + { + ResetInput(); + if (left) + { + direction += Vector3.left; + } + if (right) + { + direction += Vector3.right; + } + if (up) + { + direction += Vector3.up; + } + if (down) + { + direction += Vector3.down; + } + if (jump) + { + jumpWasPressed = true; + } + Debug.Log("Move: Right: " + right + " Left: " + left + " Jump: " + jump); + if (Input.GetKey(shoot)) + { + shootIsPressed = true; + } + if (Input.GetKeyDown(shoot)) + { + shootWasPressed = true; + } + if (Input.GetKeyUp(shoot)) + { + shootWasReleased = true; + } + } + + private Vector3 MakeEightDirections(Vector3 dir) + { + _ = Vector3.zero; + float num = 360f / (float)snapNumber; + Vector3 vector = Vector3.up; + Vector3 vector2 = vector; + float num2 = 999f; + Vector3 result = dir; + for (int i = 0; i < snapNumber; i++) + { + vector2 = Quaternion.Euler(Vector3.forward * num * i) * vector; + float num3 = Vector3.Angle(dir, vector2); + if (num3 < num2) + { + num2 = num3; + result = vector2; + } + } + if (dir == Vector3.zero) + { + return Vector3.zero; + } + dir = dir.normalized; + return result; + } +} diff --git a/GameCode/GeneralParticleSystem.cs b/GameCode/GeneralParticleSystem.cs new file mode 100644 index 0000000..8f3203a --- /dev/null +++ b/GameCode/GeneralParticleSystem.cs @@ -0,0 +1,304 @@ +using System.Collections; +using Sirenix.OdinInspector; +using UnityEngine; +using UnityEngine.Events; +using UnityEngine.UI; + +public class GeneralParticleSystem : MonoBehaviour +{ + public GameObject particleObject; + + public bool useTimeScale; + + private ObjectPool particlePool; + + [FoldoutGroup("Spawn settings", 0)] + public float randomXPos; + + [FoldoutGroup("Spawn settings", 0)] + public float randomYPos; + + [FoldoutGroup("Spawn settings", 0)] + public float rate = 10f; + + [FoldoutGroup("Spawn settings", 0)] + public bool playOnAwake = true; + + [FoldoutGroup("Spawn settings", 0)] + public bool playOnEnablee; + + [FoldoutGroup("Spawn settings", 0)] + public bool loop; + + [FoldoutGroup("Spawn settings", 0)] + public float duration = 2f; + + [FoldoutGroup("Spawn settings", 0)] + public AnimationCurve sizeMultiplierOverTime = AnimationCurve.Linear(0f, 1f, 1f, 1f); + + public AnimationCurve emissionMultiplierOverTime = AnimationCurve.Linear(0f, 1f, 1f, 1f); + + public ObjectParticle particleSettings; + + [FoldoutGroup("Global settings", 0)] + public float simulationSpeed = 1f; + + [HideInInspector] + public float simulationSpeedMultiplier = 1f; + + [FoldoutGroup("Global settings", 0)] + public float saturationMultiplier = 1f; + + [FoldoutGroup("Events", 0)] + public UnityEvent startEvent; + + [FoldoutGroup("Events", 0)] + public float startEventDelay; + + [FoldoutGroup("Events", 0)] + public UnityEvent endEvent; + + [FoldoutGroup("Events", 0)] + public float endEventDelay; + + private float sizeOverTimeAnimationCurveLength; + + private float sizeMultiplierOverTimeAnimationCurveLength; + + private float alphaOverTimeAnimationCurveLength; + + private float emissionOverTimeAnimationCurveLength; + + private bool inited; + + private Coroutine emissionLoop; + + private float lastEmissionTime; + + private bool isPlaying; + + private void OnEnable() + { + isPlaying = false; + if (playOnEnablee) + { + Play(); + } + } + + private void Start() + { + if (playOnAwake) + { + Play(); + } + Mask component = base.transform.parent.GetComponent<Mask>(); + if ((bool)component) + { + component.showMaskGraphic = false; + } + } + + private void Init() + { + if (!inited) + { + inited = true; + if (particleSettings.sizeOverTime.keys.Length > 1) + { + sizeOverTimeAnimationCurveLength = particleSettings.sizeOverTime.keys[particleSettings.sizeOverTime.keys.Length - 1].time - particleSettings.sizeOverTime.keys[0].time; + } + if (particleSettings.alphaOverTime.keys.Length > 1) + { + alphaOverTimeAnimationCurveLength = particleSettings.alphaOverTime.keys[particleSettings.alphaOverTime.keys.Length - 1].time - particleSettings.alphaOverTime.keys[0].time; + } + if (sizeMultiplierOverTime.keys.Length > 1) + { + sizeMultiplierOverTimeAnimationCurveLength = sizeMultiplierOverTime.keys[sizeMultiplierOverTime.keys.Length - 1].time - sizeMultiplierOverTime.keys[0].time; + } + if (emissionMultiplierOverTime.keys.Length > 1) + { + emissionOverTimeAnimationCurveLength = emissionMultiplierOverTime.keys[emissionMultiplierOverTime.keys.Length - 1].time - emissionMultiplierOverTime.keys[0].time; + } + particleObject.SetActive(value: false); + particlePool = new ObjectPool(particleObject, 100, base.transform); + } + } + + public void StartLooping() + { + loop = true; + Play(); + } + + public void EndLooping() + { + loop = false; + if (emissionLoop != null) + { + StopCoroutine(emissionLoop); + } + } + + [Button] + public void Play() + { + Init(); + if (!isPlaying) + { + emissionLoop = StartCoroutine(DoPlay()); + } + } + + private void OnDisable() + { + Stop(); + } + + public void Stop() + { + isPlaying = false; + DisableAllParticles(); + if (emissionLoop != null) + { + StopCoroutine(emissionLoop); + } + } + + private void DisableAllParticles() + { + if (base.transform.childCount > 0) + { + for (int i = 0; i < base.transform.GetChild(0).childCount; i++) + { + base.transform.GetChild(0).GetChild(i).gameObject.SetActive(value: false); + } + } + } + + private IEnumerator DoPlay() + { + isPlaying = true; + if (startEvent != null) + { + if (startEventDelay != 0f) + { + StartCoroutine(DelayEvent(startEvent, startEventDelay)); + } + else + { + startEvent.Invoke(); + } + } + float counter = 0f; + while (counter < duration) + { + CheckIfShouldEmit(counter / duration); + counter += (useTimeScale ? TimeHandler.deltaTime : Time.unscaledDeltaTime) * (simulationSpeed * simulationSpeedMultiplier); + yield return null; + } + isPlaying = false; + if (loop) + { + Play(); + } + else if (endEvent != null) + { + if (endEventDelay != 0f) + { + StartCoroutine(DelayEvent(endEvent, endEventDelay)); + } + else + { + endEvent.Invoke(); + } + } + } + + private void CheckIfShouldEmit(float currentAnimationTime) + { + if ((useTimeScale ? Time.time : Time.unscaledTime) > lastEmissionTime + 1f / rate / (simulationSpeed * simulationSpeedMultiplier) / emissionMultiplierOverTime.Evaluate(currentAnimationTime * emissionOverTimeAnimationCurveLength) * Time.timeScale) + { + StartCoroutine(DoPlarticleLife(currentAnimationTime)); + lastEmissionTime = Time.time; + } + } + + private IEnumerator DoPlarticleLife(float currentAnimationTime) + { + GameObject spawned = particlePool.GetObject(); + float counter = 0f; + float t = particleSettings.lifetime; + Vector3 startSize = spawned.transform.localScale; + Vector3 modifiedStartSize = spawned.transform.localScale * particleSettings.size * sizeMultiplierOverTime.Evaluate(currentAnimationTime * sizeMultiplierOverTimeAnimationCurveLength); + Image img = spawned.GetComponent<Image>(); + Color startColor = Color.magenta; + if ((bool)img) + { + startColor = img.color; + } + if ((bool)img) + { + float value = Random.value; + if (particleSettings.color != Color.magenta) + { + img.color = particleSettings.color; + } + if (particleSettings.randomColor != Color.magenta) + { + img.color = Color.Lerp(img.color, particleSettings.randomColor, value); + } + if (!particleSettings.singleRandomValueColor) + { + value = Random.value; + } + if (particleSettings.randomAddedColor != Color.black) + { + img.color += Color.Lerp(Color.black, particleSettings.randomAddedColor, value); + } + if (!particleSettings.singleRandomValueColor) + { + value = Random.value; + } + if (particleSettings.randomAddedSaturation != 0f || saturationMultiplier != 1f) + { + Color.RGBToHSV(img.color, out var H, out var S, out var V); + S += value * particleSettings.randomAddedSaturation; + S *= saturationMultiplier; + img.color = Color.HSVToRGB(H, S, V); + } + } + spawned.transform.Rotate(base.transform.forward * particleSettings.rotation); + spawned.transform.Rotate(base.transform.forward * Random.Range(0f - particleSettings.randomRotation, particleSettings.randomRotation)); + spawned.transform.localPosition = Vector3.zero; + spawned.transform.position += base.transform.up * Random.Range(0f - randomYPos, randomYPos); + spawned.transform.position += base.transform.right * Random.Range(0f - randomXPos, randomXPos); + spawned.transform.position += base.transform.forward * Random.Range(-0.1f, 0.1f); + while (counter < t) + { + if (particleSettings.sizeOverTime.keys.Length > 1) + { + spawned.transform.localScale = modifiedStartSize * particleSettings.sizeOverTime.Evaluate(counter / t * sizeOverTimeAnimationCurveLength); + } + float num = particleSettings.alphaOverTime.Evaluate(counter / t * alphaOverTimeAnimationCurveLength); + if ((bool)img && img.color.a != num) + { + img.color = new Color(img.color.r, img.color.g, img.color.b, num); + } + counter += (useTimeScale ? TimeHandler.deltaTime : Time.unscaledDeltaTime) * (simulationSpeed * simulationSpeedMultiplier); + yield return null; + } + if ((bool)img) + { + img.color = startColor; + } + spawned.transform.localScale = startSize; + particlePool.ReleaseObject(spawned); + } + + private IEnumerator DelayEvent(UnityEvent e, float t) + { + yield return new WaitForSeconds(t); + e?.Invoke(); + } +} diff --git a/GameCode/GeneralShooter.cs b/GameCode/GeneralShooter.cs new file mode 100644 index 0000000..3d39423 --- /dev/null +++ b/GameCode/GeneralShooter.cs @@ -0,0 +1,43 @@ +using System.Collections; +using UnityEngine; + +public class GeneralShooter : MonoBehaviour +{ + private Gun gun; + + [HideInInspector] + public float charge; + + public Transform[] shooters; + + private void Start() + { + gun = GetComponent<Gun>(); + } + + public void Attack() + { + if (base.enabled) + { + StartCoroutine(DoAttack()); + } + } + + private IEnumerator DoAttack() + { + int shotsToMake = Mathf.Clamp(Mathf.RoundToInt(0.5f / gun.attackSpeed), 1, 5); + for (int i = 0; i < shotsToMake; i++) + { + for (int j = 0; j < shooters.Length; j++) + { + gun.transform.position = shooters[j].position; + gun.transform.rotation = shooters[j].rotation; + gun.Attack(gun.currentCharge, forceAttack: true); + } + if (shotsToMake > i) + { + yield return new WaitForSeconds(0.1f); + } + } + } +} diff --git a/GameCode/GetColor.cs b/GameCode/GetColor.cs new file mode 100644 index 0000000..89dad00 --- /dev/null +++ b/GameCode/GetColor.cs @@ -0,0 +1,21 @@ +using UnityEngine; + +public class GetColor : MonoBehaviour +{ + public ColorHandler.ColorType colorType; + + private bool inited; + + public void Start() + { + if (!inited) + { + inited = true; + SpriteRenderer component = GetComponent<SpriteRenderer>(); + if ((bool)component) + { + component.color = ColorHandler.instance.GetColor(colorType); + } + } + } +} diff --git a/GameCode/GetControllerButton.cs b/GameCode/GetControllerButton.cs new file mode 100644 index 0000000..bcb331e --- /dev/null +++ b/GameCode/GetControllerButton.cs @@ -0,0 +1,3 @@ +public class GetControllerButton +{ +} diff --git a/GameCode/GifCam.cs b/GameCode/GifCam.cs new file mode 100644 index 0000000..d7152c4 --- /dev/null +++ b/GameCode/GifCam.cs @@ -0,0 +1,25 @@ +using UnityEngine; + +public class GifCam : MonoBehaviour +{ + public static bool isGifCam; + + private Camera[] cameras; + + private Vector3 camStartPos; + + private float cameraStartSize; + + private bool follow = true; + + private void Start() + { + cameras = GetComponentsInChildren<Camera>(); + camStartPos = cameras[0].transform.position; + cameraStartSize = cameras[0].orthographicSize; + } + + private void Update() + { + } +} diff --git a/GameCode/GoBack.cs b/GameCode/GoBack.cs new file mode 100644 index 0000000..2853d6d --- /dev/null +++ b/GameCode/GoBack.cs @@ -0,0 +1,31 @@ +using InControl; +using UnityEngine; +using UnityEngine.Events; + +public class GoBack : MonoBehaviour +{ + public UnityEvent goBackEvent; + + public ListMenuPage target; + + private void Start() + { + } + + private void Update() + { + for (int i = 0; i < InputManager.ActiveDevices.Count; i++) + { + if (InputManager.ActiveDevices[i].Action2.WasPressed) + { + goBackEvent.Invoke(); + target.Open(); + } + } + if (Input.GetKeyDown(KeyCode.Escape)) + { + goBackEvent.Invoke(); + target.Open(); + } + } +} diff --git a/GameCode/Grass.cs b/GameCode/Grass.cs new file mode 100644 index 0000000..0557f48 --- /dev/null +++ b/GameCode/Grass.cs @@ -0,0 +1,63 @@ +using UnityEngine; + +public class Grass : MonoBehaviour +{ + public float target; + + private float velocity; + + private float currentRot; + + public float minSpring; + + public float maxSpring; + + public float minDrag; + + public float maxDrag; + + private float spring; + + private float drag; + + public float minPlayerEffect; + + public float maxPlayerEffect; + + private float playerEffect; + + public Sprite[] sprites; + + private void Start() + { + if (Random.value > 0.5f) + { + Object.Destroy(base.gameObject); + return; + } + GetComponentInChildren<SpriteRenderer>().sprite = sprites[Random.Range(0, sprites.Length)]; + spring = Random.Range(minSpring, maxSpring); + drag = Random.Range(minDrag, maxDrag); + playerEffect = Random.Range(minPlayerEffect, maxPlayerEffect); + currentRot = base.transform.localEulerAngles.z; + } + + private void Update() + { + velocity = Mathf.Lerp(velocity, (target - currentRot) * spring, CappedDeltaTime.time * drag); + currentRot += velocity * CappedDeltaTime.time; + base.transform.localEulerAngles = new Vector3(0f, 0f, currentRot); + if (PlayerManager.instance.players != null && PlayerManager.instance.players.Count > 0 && Vector2.Distance(PlayerManager.instance.players[0].data.playerVel.position, base.transform.position) < 1.5f) + { + AddForce(PlayerManager.instance.players[0].data.playerVel.velocity.x * playerEffect * CappedDeltaTime.time * 60f); + } + float num = 0.5f; + float num2 = 0.05f; + AddForce((Mathf.PerlinNoise(base.transform.position.x * num2 + Time.time * num, base.transform.position.y * num2 + Time.time * num) - 0.5f) * 30f * playerEffect * CappedDeltaTime.time * 60f); + } + + public void AddForce(float f) + { + velocity += f; + } +} diff --git a/GameCode/Gravity.cs b/GameCode/Gravity.cs new file mode 100644 index 0000000..1d9cb83 --- /dev/null +++ b/GameCode/Gravity.cs @@ -0,0 +1,35 @@ +using UnityEngine; + +public class Gravity : MonoBehaviour +{ + public float gravityForce; + + public float exponent = 1f; + + private PlayerVelocity rig; + + private CharacterData data; + + private void Start() + { + data = GetComponent<CharacterData>(); + rig = GetComponent<PlayerVelocity>(); + } + + private void FixedUpdate() + { + float num = data.sinceGrounded; + if (data.sinceWallGrab < num) + { + num = data.sinceWallGrab; + } + if (num > 0f) + { + rig.AddForce(Vector3.down * TimeHandler.timeScale * Mathf.Pow(num, exponent) * gravityForce * rig.mass, ForceMode2D.Force); + } + else + { + rig.AddForce(Vector3.down * TimeHandler.timeScale * num * gravityForce * rig.mass, ForceMode2D.Force); + } + } +} diff --git a/GameCode/GridBounceCircle.cs b/GameCode/GridBounceCircle.cs new file mode 100644 index 0000000..f0c6b53 --- /dev/null +++ b/GameCode/GridBounceCircle.cs @@ -0,0 +1,57 @@ +using System.Collections; +using UnityEngine; + +public class GridBounceCircle : GridObject +{ + private float m_startSize; + + private bool isBlooping; + + private float currentDistance; + + private void Start() + { + m_startSize = base.transform.localScale.x; + } + + public override void BopCall(float power) + { + if (!isBlooping || (isBlooping && power > currentDistance)) + { + StopAllCoroutines(); + StartCoroutine(Blop(power)); + } + } + + public override void OnSetSize(float size) + { + if (!isBlooping) + { + base.transform.localScale = Vector3.one * size * m_startSize; + } + } + + private IEnumerator Blop(float power) + { + isBlooping = true; + currentDistance = power; + float maxSize = Mathf.Lerp(1f * m_startSize, 3f * m_startSize, power); + float timer2 = 0f; + while (timer2 < 1f) + { + timer2 += TimeHandler.deltaTime * 10f; + base.transform.localScale = Vector3.one * Mathf.Lerp(m_startSize, maxSize, timer2); + yield return null; + } + yield return new WaitForSeconds(0.2f); + timer2 = 0f; + while (timer2 < 1f) + { + timer2 += TimeHandler.deltaTime * 6f; + base.transform.localScale = Vector3.one * Mathf.Lerp(maxSize, m_startSize, timer2); + yield return null; + } + base.transform.localScale = Vector3.one * m_startSize; + isBlooping = false; + } +} diff --git a/GameCode/GridLightBulb.cs b/GameCode/GridLightBulb.cs new file mode 100644 index 0000000..8fa2523 --- /dev/null +++ b/GameCode/GridLightBulb.cs @@ -0,0 +1,57 @@ +using System.Collections; +using UnityEngine; + +public class GridLightBulb : GridObject +{ + private SpriteRenderer rend; + + public Color maxLightColor; + + private Color baseColor; + + private bool isLitUp; + + private float currentDistance; + + private void Start() + { + rend = GetComponent<SpriteRenderer>(); + baseColor = rend.color; + } + + public override void BopCall(float distance) + { + distance = 1f - distance; + if (!isLitUp || (isLitUp && distance > currentDistance)) + { + StopAllCoroutines(); + StartCoroutine(LightUp(distance)); + } + } + + private IEnumerator LightUp(float distance) + { + isLitUp = true; + currentDistance = distance; + Color lightColor = Color.Lerp(maxLightColor, baseColor, distance); + rend.color = lightColor; + yield return new WaitForSeconds(Random.Range(0.5f, 2f)); + int blinks = Random.Range(0, 8); + bool isOn = true; + for (int i = 0; i < blinks; i++) + { + if (isOn) + { + rend.color = baseColor; + } + else + { + rend.color = lightColor; + } + isOn = !isOn; + yield return new WaitForSeconds(Random.Range(0.05f, 0.1f)); + } + rend.color = baseColor; + isLitUp = false; + } +} diff --git a/GameCode/GridObject.cs b/GameCode/GridObject.cs new file mode 100644 index 0000000..6b4fcdd --- /dev/null +++ b/GameCode/GridObject.cs @@ -0,0 +1,26 @@ +using UnityEngine; + +public class GridObject : MonoBehaviour +{ + public virtual void BopCall(float power) + { + } + + public virtual void BulletCall(float distance) + { + distance = Mathf.Clamp(0f, 1f, distance); + BopCall(1f - distance); + } + + public virtual void OnPlayerKilled(float distance) + { + } + + public virtual void OnGameOverOver(float distance) + { + } + + public virtual void OnSetSize(float size) + { + } +} diff --git a/GameCode/GridVisualizer.cs b/GameCode/GridVisualizer.cs new file mode 100644 index 0000000..ed73bf2 --- /dev/null +++ b/GameCode/GridVisualizer.cs @@ -0,0 +1,56 @@ +using UnityEngine; + +public class GridVisualizer : MonoBehaviour +{ + public Vector2 min; + + public Vector2 max; + + public GameObject prefab; + + public Vector2Int numberOfObjects; + + internal GridObject[,] spawnedObjects; + + public static GridVisualizer instance; + + private void Start() + { + instance = this; + SpawnGrid(); + } + + public void BulletCall(Vector2 worldSpacePosition) + { + Vector2Int gridPos = WorldToGridSpace(worldSpacePosition); + float power = Vector2.Distance(worldSpacePosition, GridToWorldSpace(gridPos)); + spawnedObjects[gridPos.x, gridPos.y].BopCall(power); + } + + public Vector2 GridToWorldSpace(int x, int y) + { + return GridToWorldSpace(new Vector2Int(x, y)); + } + + public Vector2 GridToWorldSpace(Vector2Int gridPos) + { + return new Vector2(Mathf.Lerp(min.x, max.x, (float)gridPos.x / (float)numberOfObjects.x), Mathf.Lerp(min.y, max.y, (float)gridPos.y / (float)numberOfObjects.y)); + } + + public Vector2Int WorldToGridSpace(Vector2 pos) + { + return new Vector2Int((int)(Mathf.InverseLerp(min.x, max.x, pos.x) * (float)numberOfObjects.x), (int)(Mathf.InverseLerp(min.y, max.y, pos.y) * (float)numberOfObjects.y)); + } + + private void SpawnGrid() + { + spawnedObjects = new GridObject[numberOfObjects.x, numberOfObjects.y]; + for (int i = 0; i < numberOfObjects.x; i++) + { + for (int j = 0; j < numberOfObjects.y; j++) + { + spawnedObjects[i, j] = Object.Instantiate(prefab, GridToWorldSpace(i, j), Quaternion.identity).GetComponent<GridObject>(); + } + } + } +} diff --git a/GameCode/Gun.cs b/GameCode/Gun.cs new file mode 100644 index 0000000..36e8df2 --- /dev/null +++ b/GameCode/Gun.cs @@ -0,0 +1,698 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using Photon.Pun; +using Sirenix.OdinInspector; +using SoundImplementation; +using UnityEngine; + +public class Gun : Weapon +{ + [Header("Sound Player Settings")] + public SoundGun soundGun = new SoundGun(); + + [Header("Sound Card Settings")] + public SoundShotModifier soundShotModifier; + + public SoundImpactModifier soundImpactModifier; + + public bool soundDisableRayHitBulletSound; + + [Header("Settings")] + public float recoil; + + public float bodyRecoil; + + public float shake; + + public bool forceSpecificShake; + + public ProjectilesToSpawn[] projectiles; + + private Rigidbody2D rig; + + public Transform shootPosition; + + [HideInInspector] + public Player player; + + [HideInInspector] + public bool isReloading; + + [Header("Multiply")] + [FoldoutGroup("Stats", 0)] + public float damage = 1f; + + [FoldoutGroup("Stats", 0)] + public float reloadTime = 1f; + + [FoldoutGroup("Stats", 0)] + public float reloadTimeAdd; + + [FoldoutGroup("Stats", 0)] + public float recoilMuiltiplier = 1f; + + [FoldoutGroup("Stats", 0)] + public float knockback = 1f; + + [FoldoutGroup("Stats", 0)] + public float attackSpeed = 1f; + + [FoldoutGroup("Stats", 0)] + public float projectileSpeed = 1f; + + [FoldoutGroup("Stats", 0)] + public float projectielSimulatonSpeed = 1f; + + [FoldoutGroup("Stats", 0)] + public float gravity = 1f; + + [FoldoutGroup("Stats", 0)] + public float damageAfterDistanceMultiplier = 1f; + + [FoldoutGroup("Stats", 0)] + public float bulletDamageMultiplier = 1f; + + [FoldoutGroup("Stats", 0)] + public float multiplySpread = 1f; + + [FoldoutGroup("Stats", 0)] + public float shakeM = 1f; + + [Header("Add")] + [FoldoutGroup("Stats", 0)] + public int ammo; + + [FoldoutGroup("Stats", 0)] + public float ammoReg; + + [FoldoutGroup("Stats", 0)] + public float size; + + [FoldoutGroup("Stats", 0)] + public float overheatMultiplier; + + [FoldoutGroup("Stats", 0)] + public float timeToReachFullMovementMultiplier; + + [FoldoutGroup("Stats", 0)] + public int numberOfProjectiles; + + [FoldoutGroup("Stats", 0)] + public int bursts; + + [FoldoutGroup("Stats", 0)] + public int reflects; + + [FoldoutGroup("Stats", 0)] + public int smartBounce; + + [FoldoutGroup("Stats", 0)] + public int bulletPortal; + + [FoldoutGroup("Stats", 0)] + public int randomBounces; + + [FoldoutGroup("Stats", 0)] + public float timeBetweenBullets; + + [FoldoutGroup("Stats", 0)] + public float projectileSize; + + [FoldoutGroup("Stats", 0)] + public float speedMOnBounce = 1f; + + [FoldoutGroup("Stats", 0)] + public float dmgMOnBounce = 1f; + + [FoldoutGroup("Stats", 0)] + public float drag; + + [FoldoutGroup("Stats", 0)] + public float dragMinSpeed = 1f; + + [FoldoutGroup("Stats", 0)] + public float spread; + + [FoldoutGroup("Stats", 0)] + public float evenSpread; + + [FoldoutGroup("Stats", 0)] + public float percentageDamage; + + [FoldoutGroup("Stats", 0)] + public float cos; + + [FoldoutGroup("Stats", 0)] + public float slow; + + [FoldoutGroup("Stats", 0)] + [Header("Charge Multiply")] + public float chargeDamageMultiplier = 1f; + + [FoldoutGroup("Stats", 0)] + [Header("(1 + Charge * x) Multiply")] + public float chargeSpreadTo; + + [FoldoutGroup("Stats", 0)] + public float chargeEvenSpreadTo; + + [FoldoutGroup("Stats", 0)] + public float chargeSpeedTo; + + [FoldoutGroup("Stats", 0)] + public float chargeRecoilTo; + + [FoldoutGroup("Stats", 0)] + [Header("(1 + Charge * x) Add")] + public float chargeNumberOfProjectilesTo; + + [FoldoutGroup("Stats", 0)] + [Header("Special")] + public float destroyBulletAfter; + + [FoldoutGroup("Stats", 0)] + public float forceSpecificAttackSpeed; + + [FoldoutGroup("Stats", 0)] + public bool lockGunToDefault; + + [FoldoutGroup("Stats", 0)] + public bool unblockable; + + [FoldoutGroup("Stats", 0)] + public bool ignoreWalls; + + [HideInInspector] + public float currentCharge; + + public bool useCharge; + + public bool dontAllowAutoFire; + + public ObjectsToSpawn[] objectsToSpawn; + + public Color projectileColor = Color.black; + + public bool waveMovement; + + public bool teleport; + + public bool spawnSkelletonSquare; + + public float explodeNearEnemyRange; + + public float explodeNearEnemyDamage; + + public float hitMovementMultiplier = 1f; + + private Action attackAction; + + [HideInInspector] + public bool isProjectileGun; + + [HideInInspector] + public float defaultCooldown = 1f; + + [HideInInspector] + public int attackID = -1; + + public float attackSpeedMultiplier = 1f; + + private int gunID = -1; + + private GunAmmo gunAmmo; + + private Vector3 spawnPos; + + public Action<GameObject> ShootPojectileAction; + + private float spreadOfLastBullet; + + private SpawnedAttack spawnedAttack; + + [HideInInspector] + internal Vector3 forceShootDir; + + private float usedCooldown + { + get + { + if (!lockGunToDefault) + { + return attackSpeed; + } + return defaultCooldown; + } + } + + internal float GetRangeCompensation(float distance) + { + return Mathf.Pow(distance, 2f) * 0.015f / projectileSpeed; + } + + internal void ResetStats() + { + isReloading = false; + damage = 1f; + reloadTime = 1f; + reloadTimeAdd = 0f; + recoilMuiltiplier = 1f; + gunAmmo.reloadTimeMultiplier = 1f; + gunAmmo.reloadTimeAdd = 0f; + knockback = 1f; + attackSpeed = 0.3f; + projectileSpeed = 1f; + projectielSimulatonSpeed = 1f; + gravity = 1f; + damageAfterDistanceMultiplier = 1f; + bulletDamageMultiplier = 1f; + multiplySpread = 1f; + shakeM = 1f; + ammo = 0; + ammoReg = 0f; + size = 0f; + overheatMultiplier = 0f; + timeToReachFullMovementMultiplier = 0f; + numberOfProjectiles = 1; + bursts = 0; + reflects = 0; + smartBounce = 0; + bulletPortal = 0; + randomBounces = 0; + timeBetweenBullets = 0f; + projectileSize = 0f; + speedMOnBounce = 1f; + dmgMOnBounce = 1f; + drag = 0f; + dragMinSpeed = 1f; + spread = 0f; + evenSpread = 0f; + percentageDamage = 0f; + cos = 0f; + slow = 0f; + chargeNumberOfProjectilesTo = 0f; + destroyBulletAfter = 0f; + forceSpecificAttackSpeed = 0f; + lockGunToDefault = false; + unblockable = false; + ignoreWalls = false; + currentCharge = 0f; + useCharge = false; + waveMovement = false; + teleport = false; + spawnSkelletonSquare = false; + explodeNearEnemyRange = 0f; + explodeNearEnemyDamage = 0f; + hitMovementMultiplier = 1f; + isProjectileGun = false; + defaultCooldown = 1f; + attackSpeedMultiplier = 1f; + objectsToSpawn = new ObjectsToSpawn[0]; + GetComponentInChildren<GunAmmo>().maxAmmo = 3; + GetComponentInChildren<GunAmmo>().ReDrawTotalBullets(); + projectileColor = Color.black; + } + + private void Start() + { + gunAmmo = GetComponentInChildren<GunAmmo>(); + Gun[] componentsInChildren = base.transform.root.GetComponentsInChildren<Gun>(); + for (int i = 0; i < componentsInChildren.Length; i++) + { + if (componentsInChildren[i] == this) + { + gunID = i; + } + } + if (!player) + { + player = GetComponentInParent<Player>(); + } + if (!player) + { + ProjectileHit componentInParent = GetComponentInParent<ProjectileHit>(); + if ((bool)componentInParent) + { + player = componentInParent.ownPlayer; + } + } + if (!player) + { + SpawnedAttack component = base.transform.root.GetComponent<SpawnedAttack>(); + if ((bool)component) + { + player = component.spawner; + } + } + holdable = GetComponent<Holdable>(); + defaultCooldown = usedCooldown; + ShootPos componentInChildren = GetComponentInChildren<ShootPos>(); + if ((bool)componentInChildren) + { + shootPosition = componentInChildren.transform; + } + else + { + shootPosition = base.transform; + } + rig = GetComponent<Rigidbody2D>(); + soundGun.SetGun(this); + soundGun.SetGunTransform(base.transform); + soundGun.RefreshSoundModifiers(); + } + + private void Update() + { + if ((bool)holdable && (bool)holdable.holder && (bool)holdable.holder.player) + { + player = holdable.holder.player; + } + sinceAttack += TimeHandler.deltaTime * attackSpeedMultiplier; + if (!GameManager.instance.battleOngoing || (player != null && (!player.data.isPlaying || player.data.dead))) + { + soundGun.StopAutoPlayTail(); + } + } + + private void OnDestroy() + { + soundGun.StopAutoPlayTail(); + } + + public bool IsReady(float readuIn = 0f) + { + return sinceAttack + readuIn * attackSpeedMultiplier > usedCooldown; + } + + public float ReadyAmount() + { + return sinceAttack / usedCooldown; + } + + public override bool Attack(float charge, bool forceAttack = false, float damageM = 1f, float recoilM = 1f, bool useAmmo = true) + { + if (sinceAttack < usedCooldown && !forceAttack) + { + return false; + } + if (isReloading && !forceAttack) + { + return false; + } + sinceAttack = 0f; + int attacks = Mathf.Clamp(Mathf.RoundToInt(0.5f * charge / attackSpeed), 1, 10); + if (lockGunToDefault) + { + attacks = 1; + } + StartCoroutine(DoAttacks(charge, forceAttack, damageM, attacks, recoilM, useAmmo)); + return true; + } + + private IEnumerator DoAttacks(float charge, bool forceAttack = false, float damageM = 1f, int attacks = 1, float recoilM = 1f, bool useAmmo = true) + { + for (int i = 0; i < attacks; i++) + { + DoAttack(charge, forceAttack, damageM, recoilM, useAmmo); + yield return new WaitForSeconds(0.3f / (float)attacks); + } + } + + private void DoAttack(float charge, bool forceAttack = false, float damageM = 1f, float recoilM = 1f, bool useAmmo = true) + { + float num = 1f * (1f + charge * chargeRecoilTo) * recoilM; + if ((bool)rig) + { + rig.AddForce(rig.mass * recoil * Mathf.Clamp(usedCooldown, 0f, 1f) * -base.transform.up, ForceMode2D.Impulse); + } + _ = (bool)holdable; + if (attackAction != null) + { + attackAction(); + } + StartCoroutine(FireBurst(charge, forceAttack, damageM, recoilM, useAmmo)); + } + + private bool CheckIsMine() + { + bool result = false; + if ((bool)holdable && (bool)holdable.holder) + { + result = holdable.holder.player.data.view.IsMine; + } + else + { + Player componentInParent = GetComponentInParent<Player>(); + if ((bool)componentInParent) + { + result = componentInParent.data.view.IsMine; + } + } + return result; + } + + private IEnumerator FireBurst(float charge, bool forceAttack = false, float damageM = 1f, float recoilM = 1f, bool useAmmo = true) + { + int currentNumberOfProjectiles = (lockGunToDefault ? 1 : (numberOfProjectiles + Mathf.RoundToInt(chargeNumberOfProjectilesTo * charge))); + if (!lockGunToDefault) + { + _ = currentNumberOfProjectiles; + } + if (timeBetweenBullets == 0f) + { + GamefeelManager.GameFeel(base.transform.up * shake); + soundGun.PlayShot(currentNumberOfProjectiles); + } + for (int ii = 0; ii < Mathf.Clamp(bursts, 1, 100); ii++) + { + for (int i = 0; i < projectiles.Length; i++) + { + for (int j = 0; j < currentNumberOfProjectiles; j++) + { + if (CheckIsMine()) + { + spawnPos = base.transform.position; + if ((bool)player) + { + player.GetComponent<PlayerAudioModifyers>().SetStacks(); + if ((bool)holdable) + { + spawnPos = player.transform.position; + } + } + GameObject gameObject = PhotonNetwork.Instantiate(projectiles[i].objectToSpawn.gameObject.name, spawnPos, getShootRotation(j, currentNumberOfProjectiles, charge), 0); + if ((bool)holdable) + { + if (useAmmo) + { + if (PhotonNetwork.OfflineMode) + { + gameObject.GetComponent<ProjectileInit>().OFFLINE_Init(holdable.holder.player.playerID, currentNumberOfProjectiles, damageM, UnityEngine.Random.Range(0f, 1f)); + } + else + { + gameObject.GetComponent<PhotonView>().RPC("RPCA_Init", RpcTarget.All, holdable.holder.view.OwnerActorNr, currentNumberOfProjectiles, damageM, UnityEngine.Random.Range(0f, 1f)); + } + } + else if (PhotonNetwork.OfflineMode) + { + gameObject.GetComponent<ProjectileInit>().OFFLINE_Init_noAmmoUse(holdable.holder.player.playerID, currentNumberOfProjectiles, damageM, UnityEngine.Random.Range(0f, 1f)); + } + else + { + gameObject.GetComponent<PhotonView>().RPC("RPCA_Init_noAmmoUse", RpcTarget.All, holdable.holder.view.OwnerActorNr, currentNumberOfProjectiles, damageM, UnityEngine.Random.Range(0f, 1f)); + } + } + else if (PhotonNetwork.OfflineMode) + { + gameObject.GetComponent<ProjectileInit>().OFFLINE_Init_SeparateGun(GetComponentInParent<Player>().playerID, gunID, currentNumberOfProjectiles, damageM, UnityEngine.Random.Range(0f, 1f)); + } + else + { + gameObject.GetComponent<PhotonView>().RPC("RPCA_Init_SeparateGun", RpcTarget.All, GetComponentInParent<CharacterData>().view.OwnerActorNr, gunID, currentNumberOfProjectiles, damageM, UnityEngine.Random.Range(0f, 1f)); + } + } + if (timeBetweenBullets != 0f) + { + GamefeelManager.GameFeel(base.transform.up * shake); + soundGun.PlayShot(currentNumberOfProjectiles); + } + } + } + if (bursts > 1 && ii + 1 == Mathf.Clamp(bursts, 1, 100)) + { + soundGun.StopAutoPlayTail(); + } + if (timeBetweenBullets > 0f) + { + yield return new WaitForSeconds(timeBetweenBullets); + } + } + } + + public void BulletInit(GameObject bullet, int usedNumberOfProjectiles, float damageM, float randomSeed, bool useAmmo = true) + { + spawnedAttack = bullet.GetComponent<SpawnedAttack>(); + if (!spawnedAttack) + { + spawnedAttack = bullet.AddComponent<SpawnedAttack>(); + } + if (!bullet.GetComponentInChildren<DontChangeMe>()) + { + ApplyProjectileStats(bullet, usedNumberOfProjectiles, damageM, randomSeed); + } + if (soundDisableRayHitBulletSound) + { + RayHitBulletSound component = bullet.GetComponent<RayHitBulletSound>(); + if (component != null) + { + component.disableImpact = true; + } + } + ApplyPlayerStuff(bullet); + if (ShootPojectileAction != null) + { + ShootPojectileAction(bullet); + } + if (useAmmo && (bool)gunAmmo) + { + gunAmmo.Shoot(bullet); + } + } + + private Quaternion getShootRotation(int bulletID, int numOfProj, float charge) + { + Vector3 forward = shootPosition.forward; + if (forceShootDir != Vector3.zero) + { + forward = forceShootDir; + } + float num = multiplySpread * Mathf.Clamp(1f + charge * chargeSpreadTo, 0f, float.PositiveInfinity); + float num2 = UnityEngine.Random.Range(0f - spread, spread); + num2 /= (1f + projectileSpeed * 0.5f) * 0.5f; + forward += Vector3.Cross(forward, Vector3.forward) * num2 * num; + return Quaternion.LookRotation(lockGunToDefault ? shootPosition.forward : forward); + } + + private void ApplyPlayerStuff(GameObject obj) + { + ProjectileHit component = obj.GetComponent<ProjectileHit>(); + component.ownWeapon = base.gameObject; + if ((bool)player) + { + component.ownPlayer = player; + } + spawnedAttack.spawner = player; + spawnedAttack.attackID = attackID; + } + + private void ApplyProjectileStats(GameObject obj, int numOfProj = 1, float damageM = 1f, float randomSeed = 0f) + { + ProjectileHit component = obj.GetComponent<ProjectileHit>(); + component.dealDamageMultiplierr *= bulletDamageMultiplier; + component.damage *= damage * damageM; + component.percentageDamage = percentageDamage; + component.stun = component.damage / 150f; + component.force *= knockback; + component.movementSlow = slow; + component.hasControl = CheckIsMine(); + component.projectileColor = projectileColor; + component.unblockable = unblockable; + RayCastTrail component2 = obj.GetComponent<RayCastTrail>(); + if (ignoreWalls) + { + component2.mask = component2.ignoreWallsMask; + } + if ((bool)component2) + { + component2.extraSize += size; + } + if ((bool)player) + { + PlayerSkin teamColor = (component.team = PlayerSkinBank.GetPlayerSkinColors(player.playerID)); + obj.GetComponent<RayCastTrail>().teamID = player.playerID; + SetTeamColor.TeamColorThis(obj, teamColor); + } + List<ObjectsToSpawn> list = new List<ObjectsToSpawn>(); + for (int i = 0; i < objectsToSpawn.Length; i++) + { + list.Add(objectsToSpawn[i]); + if (!objectsToSpawn[i].AddToProjectile || ((bool)objectsToSpawn[i].AddToProjectile.gameObject.GetComponent<StopRecursion>() && isProjectileGun)) + { + continue; + } + GameObject gameObject = UnityEngine.Object.Instantiate(objectsToSpawn[i].AddToProjectile, component.transform.position, component.transform.rotation, component.transform); + gameObject.transform.localScale *= 1f * (1f - objectsToSpawn[i].scaleFromDamage) + component.damage / 55f * objectsToSpawn[i].scaleFromDamage; + if (objectsToSpawn[i].scaleStacks) + { + gameObject.transform.localScale *= 1f + (float)objectsToSpawn[i].stacks * objectsToSpawn[i].scaleStackM; + } + if (!objectsToSpawn[i].removeScriptsFromProjectileObject) + { + continue; + } + MonoBehaviour[] componentsInChildren = gameObject.GetComponentsInChildren<MonoBehaviour>(); + for (int j = 0; j < componentsInChildren.Length; j++) + { + if (componentsInChildren[j].GetType().ToString() != "SoundImplementation.SoundUnityEventPlayer") + { + UnityEngine.Object.Destroy(componentsInChildren[j]); + } + Debug.Log(componentsInChildren[j].GetType().ToString()); + } + } + component.objectsToSpawn = list.ToArray(); + if (reflects > 0) + { + RayHitReflect rayHitReflect = obj.gameObject.AddComponent<RayHitReflect>(); + rayHitReflect.reflects = reflects; + rayHitReflect.speedM = speedMOnBounce; + rayHitReflect.dmgM = dmgMOnBounce; + } + if (!forceSpecificShake) + { + float num = component.damage / 100f * ((1f + usedCooldown) / 2f) / ((1f + (float)numOfProj) / 2f) * 2f; + float num2 = Mathf.Clamp((0.2f + component.damage * (((float)numberOfProjectiles + 2f) / 2f) / 100f * ((1f + usedCooldown) / 2f)) * 1f, 0f, 3f); + component.shake = num * shakeM; + shake = num2; + } + MoveTransform component3 = obj.GetComponent<MoveTransform>(); + component3.localForce *= projectileSpeed; + component3.simulationSpeed *= projectielSimulatonSpeed; + component3.gravity *= gravity; + component3.worldForce *= gravity; + component3.drag = drag; + component3.drag = Mathf.Clamp(component3.drag, 0f, 45f); + component3.velocitySpread = Mathf.Clamp(spread * 50f, 0f, 50f); + component3.dragMinSpeed = dragMinSpeed; + component3.localForce *= Mathf.Lerp(1f - component3.velocitySpread * 0.01f, 1f + component3.velocitySpread * 0.01f, randomSeed); + component3.selectedSpread = 0f; + if (damageAfterDistanceMultiplier != 1f) + { + obj.AddComponent<ChangeDamageMultiplierAfterDistanceTravelled>().muiltiplier = damageAfterDistanceMultiplier; + } + if (cos > 0f) + { + obj.gameObject.AddComponent<Cos>().multiplier = cos; + } + if (destroyBulletAfter != 0f) + { + obj.GetComponent<RemoveAfterSeconds>().seconds = destroyBulletAfter; + } + if ((bool)spawnedAttack && projectileColor != Color.black) + { + spawnedAttack.SetColor(projectileColor); + } + } + + public void AddAttackAction(Action action) + { + attackAction = (Action)Delegate.Combine(attackAction, action); + } + + internal void RemoveAttackAction(Action action) + { + attackAction = (Action)Delegate.Remove(attackAction, action); + } +} diff --git a/GameCode/GunAmmo.cs b/GameCode/GunAmmo.cs new file mode 100644 index 0000000..102b4d4 --- /dev/null +++ b/GameCode/GunAmmo.cs @@ -0,0 +1,212 @@ +using Sonigon; +using UnityEngine; +using UnityEngine.UI; + +public class GunAmmo : MonoBehaviour +{ + [Header("Sounds")] + public SoundEvent soundReloadInProgressLoop; + + public SoundEvent soundReloadComplete; + + private SoundParameterIntensity soundReloadInProgressIntensity = new SoundParameterIntensity(0f, UpdateMode.Continuous); + + private bool soundReloadInProgressPlaying; + + private float soundReloadTime; + + [Header("Settings")] + public int maxAmmo = 3; + + private int lastMaxAmmo; + + private int currentAmmo; + + public float reloadTime = 1.5f; + + public float reloadTimeMultiplier = 1f; + + public float reloadTimeAdd; + + private Gun gun; + + public CurveAnimation reloadAnim; + + private Image reloadRing; + + public Image cooldownRing; + + private float reloadCounter; + + private float freeReloadCounter; + + public Populate populate; + + public float ammoReg; + + private float currentRegCounter; + + private void Start() + { + reloadRing = reloadAnim.GetComponent<Image>(); + lastMaxAmmo = maxAmmo; + currentAmmo = maxAmmo; + gun = GetComponentInParent<Gun>(); + ReDrawTotalBullets(); + } + + private void OnDisable() + { + SoundStopReloadInProgress(); + } + + private void OnDestroy() + { + SoundStopReloadInProgress(); + } + + private void SoundStopReloadInProgress() + { + if (soundReloadInProgressPlaying) + { + soundReloadInProgressPlaying = false; + SoundManager.Instance.Stop(soundReloadInProgressLoop, base.transform); + } + } + + private float ReloadTime() + { + return (reloadTime + reloadTimeAdd) * reloadTimeMultiplier; + } + + private void Update() + { + if (!gun.isReloading) + { + SoundStopReloadInProgress(); + } + if (gun.isReloading) + { + reloadCounter -= TimeHandler.deltaTime; + if (!soundReloadInProgressPlaying) + { + soundReloadInProgressPlaying = true; + soundReloadTime = ReloadTime(); + soundReloadInProgressIntensity.intensity = 0f; + SoundManager.Instance.Play(soundReloadInProgressLoop, base.transform, soundReloadInProgressIntensity); + } + if (soundReloadInProgressPlaying && soundReloadTime > 0f) + { + soundReloadInProgressIntensity.intensity = 1f - reloadCounter / soundReloadTime; + } + if (reloadCounter < 0f) + { + ReloadAmmo(); + } + } + else if (currentAmmo != maxAmmo) + { + freeReloadCounter += TimeHandler.deltaTime; + if (freeReloadCounter > ReloadTime() && gun.player.data.stats.automaticReload) + { + currentAmmo = maxAmmo; + SetActiveBullets(); + } + currentRegCounter += ammoReg * TimeHandler.deltaTime * (float)maxAmmo; + if (currentRegCounter > 1f) + { + currentAmmo++; + currentRegCounter = 0f; + SetActiveBullets(); + } + } + if (currentAmmo <= 0) + { + if (reloadAnim.currentState != 0) + { + reloadAnim.PlayIn(); + } + } + else if (reloadAnim.currentState != CurveAnimationUse.Out) + { + reloadAnim.PlayOut(); + } + reloadRing.fillAmount = (ReloadTime() - reloadCounter) / ReloadTime(); + if (gun.attackSpeed > 0.4f) + { + cooldownRing.fillAmount = gun.ReadyAmount(); + if (gun.ReadyAmount() >= 1f) + { + cooldownRing.fillAmount = 0f; + } + } + else + { + cooldownRing.fillAmount = 0f; + } + if (maxAmmo != lastMaxAmmo) + { + ReDrawTotalBullets(); + } + lastMaxAmmo = maxAmmo; + } + + public void ReloadAmmo(bool playSound = true) + { + gun.player.data.stats.OnReload(maxAmmo - currentAmmo); + gun.isReloading = false; + currentAmmo = maxAmmo; + SoundStopReloadInProgress(); + if (playSound) + { + SoundManager.Instance.Play(soundReloadComplete, base.transform); + } + SetActiveBullets(); + } + + public void Shoot(GameObject projectile) + { + currentAmmo--; + freeReloadCounter = 0f; + SetActiveBullets(); + if (currentAmmo <= 0) + { + reloadCounter = ReloadTime(); + gun.isReloading = true; + gun.player.data.stats.OnOutOfAmmp(maxAmmo); + } + } + + public void ReDrawTotalBullets() + { + currentAmmo = maxAmmo; + for (int num = populate.transform.childCount - 1; num >= 0; num--) + { + if (populate.transform.GetChild(num).gameObject.activeSelf) + { + Object.Destroy(populate.transform.GetChild(num).gameObject); + } + } + populate.times = maxAmmo; + populate.DoPopulate(); + SetActiveBullets(forceTurnOn: true); + } + + private void SetActiveBullets(bool forceTurnOn = false) + { + for (int i = 1; i < populate.transform.childCount; i++) + { + if (i <= currentAmmo || forceTurnOn) + { + if (populate.transform.GetChild(i).GetComponent<CurveAnimation>().currentState != CurveAnimationUse.In || forceTurnOn) + { + populate.transform.GetChild(i).GetComponent<CurveAnimation>().PlayIn(); + } + } + else if (populate.transform.GetChild(i).GetComponent<CurveAnimation>().currentState != CurveAnimationUse.Out) + { + populate.transform.GetChild(i).GetComponent<CurveAnimation>().PlayOut(); + } + } + } +} diff --git a/GameCode/GunLevel.cs b/GameCode/GunLevel.cs new file mode 100644 index 0000000..427e442 --- /dev/null +++ b/GameCode/GunLevel.cs @@ -0,0 +1,21 @@ +using System; +using UnityEngine; + +public class GunLevel : MonoBehaviour +{ + public Gun copyTo; + + private Gun copyFrom; + + private void Start() + { + copyFrom = GetComponent<Gun>(); + AttackLevel componentInParent = GetComponentInParent<AttackLevel>(); + componentInParent.LevelUpAction = (Action<int>)Delegate.Combine(componentInParent.LevelUpAction, new Action<int>(BuffGun)); + } + + public void BuffGun(int level) + { + ApplyCardStats.CopyGunStats(copyFrom, copyTo); + } +} diff --git a/GameCode/HandPos.cs b/GameCode/HandPos.cs new file mode 100644 index 0000000..a0e6af6 --- /dev/null +++ b/GameCode/HandPos.cs @@ -0,0 +1,5 @@ +using UnityEngine; + +public class HandPos : MonoBehaviour +{ +} diff --git a/GameCode/HasToReturn.cs b/GameCode/HasToReturn.cs new file mode 100644 index 0000000..4cf01d8 --- /dev/null +++ b/GameCode/HasToReturn.cs @@ -0,0 +1,6 @@ +public enum HasToReturn +{ + hasToReturn, + canContinue, + hasToReturnNow +} diff --git a/GameCode/HealthBar.cs b/GameCode/HealthBar.cs new file mode 100644 index 0000000..98e08ec --- /dev/null +++ b/GameCode/HealthBar.cs @@ -0,0 +1,58 @@ +using System; +using UnityEngine; +using UnityEngine.UI; + +public class HealthBar : MonoBehaviour +{ + public Image hp; + + public Image white; + + private float drag = 25f; + + private float spring = 25f; + + private float hpCur; + + private float hpVel; + + private float hpTarg; + + private float whiteCur; + + private float whiteVel; + + private float whiteTarg; + + private float sinceDamage; + + private CharacterData data; + + private void Start() + { + data = GetComponentInParent<CharacterData>(); + CharacterStatModifiers componentInParent = GetComponentInParent<CharacterStatModifiers>(); + componentInParent.WasDealtDamageAction = (Action<Vector2, bool>)Delegate.Combine(componentInParent.WasDealtDamageAction, new Action<Vector2, bool>(TakeDamage)); + } + + private void Update() + { + hpTarg = data.health / data.maxHealth; + sinceDamage += TimeHandler.deltaTime; + hpVel = FRILerp.Lerp(hpVel, (hpTarg - hpCur) * spring, drag); + whiteVel = FRILerp.Lerp(whiteVel, (whiteTarg - whiteCur) * spring, drag); + hpCur += hpVel * TimeHandler.deltaTime; + whiteCur += whiteVel * TimeHandler.deltaTime; + hp.fillAmount = hpCur; + white.fillAmount = whiteCur; + if (sinceDamage > 0.5f) + { + whiteTarg = hpTarg; + } + } + + public void TakeDamage(Vector2 dmg, bool selfDmg) + { + sinceDamage = 0f; + } +} diff --git a/GameCode/HealthHandler.cs b/GameCode/HealthHandler.cs new file mode 100644 index 0000000..bbc739f --- /dev/null +++ b/GameCode/HealthHandler.cs @@ -0,0 +1,362 @@ +using System; +using System.Collections; +using Photon.Pun; +using Sonigon; +using UnityEngine; + +public class HealthHandler : Damagable +{ + [Header("Sounds")] + public SoundEvent soundDie; + + public SoundEvent soundHeal; + + public SoundEvent soundDamagePassive; + + public SoundEvent soundDamageLifeSteal; + + public SoundEvent soundBounce; + + [Header("Settings")] + public SpriteRenderer hpSprite; + + public GameObject deathEffect; + + public float regeneration; + + private CharacterData data; + + private CodeAnimation anim; + + private Player player; + + private CharacterStatModifiers stats; + + public ParticleSystem healPart; + + private DamageOverTime dot; + + private Vector3 startHealthSpriteScale; + + public float flyingFor; + + private float lastDamaged; + + public Action delayedReviveAction; + + public Action reviveAction; + + [HideInInspector] + public bool DestroyOnDeath; + + public bool isRespawning; + + public GameObject deathEffectPhoenix; + + private void Awake() + { + dot = GetComponent<DamageOverTime>(); + data = GetComponent<CharacterData>(); + anim = GetComponentInChildren<CodeAnimation>(); + player = GetComponent<Player>(); + stats = GetComponent<CharacterStatModifiers>(); + } + + private void Start() + { + startHealthSpriteScale = hpSprite.transform.localScale; + } + + private void Update() + { + flyingFor -= TimeHandler.deltaTime; + if (regeneration > 0f) + { + Heal(regeneration * TimeHandler.deltaTime); + } + } + + public void Heal(float healAmount) + { + if (healAmount != 0f && data.health != data.maxHealth) + { + SoundManager.Instance.Play(soundHeal, base.transform); + data.health += healAmount; + data.health = Mathf.Clamp(data.health, float.NegativeInfinity, data.maxHealth); + healPart.Emit((int)Mathf.Clamp(healAmount * 0.2f, 1f, 10f)); + } + } + + public void CallTakeForce(Vector2 force, ForceMode2D forceMode = ForceMode2D.Impulse, bool forceIgnoreMass = false, bool ignoreBlock = false, float setFlying = 0f) + { + if (data.isPlaying && (!data.block.IsBlocking() || ignoreBlock)) + { + data.view.RPC("RPCA_SendTakeForce", RpcTarget.All, force, (int)forceMode, forceIgnoreMass, true, setFlying); + } + } + + [PunRPC] + public void RPCA_SendTakeForce(Vector2 force, int forceMode, bool forceIgnoreMass = false, bool ignoreBlock = false, float setFlying = 0f) + { + TakeForce(force, (ForceMode2D)forceMode, forceIgnoreMass, ignoreBlock, setFlying); + data.GetComponent<SyncPlayerMovement>().SetDontSyncFor((float)PhotonNetwork.GetPing() * 0.001f + 0.2f); + } + + [PunRPC] + public void RPCA_SendForceOverTime(Vector2 force, float time, int forceMode, bool forceIgnoreMass = false, bool ignoreBlock = false) + { + StartCoroutine(IForceOverTime(force, time, forceMode, forceIgnoreMass, ignoreBlock)); + } + + private IEnumerator IForceOverTime(Vector2 force, float time, int forceMode, bool forceIgnoreMass = false, bool ignoreBlock = false) + { + for (float i = 0f; i < time; i += TimeHandler.deltaTime) + { + TakeForce(force, (ForceMode2D)forceMode, forceIgnoreMass, ignoreBlock); + data.GetComponent<SyncPlayerMovement>().SetDontSyncFor((float)PhotonNetwork.GetPing() * 0.001f + 0.2f); + yield return new WaitForFixedUpdate(); + } + } + + [PunRPC] + public void RPCA_SendForceTowardsPointOverTime(float force, float drag, float clampDistancce, Vector2 point, float time, int forceMode, bool forceIgnoreMass = false, bool ignoreBlock = false) + { + StartCoroutine(IForceTowardsPointOverTime(force, drag, clampDistancce, point, time, forceMode, forceIgnoreMass, ignoreBlock)); + } + + private IEnumerator IForceTowardsPointOverTime(float force, float drag, float clampDistancce, Vector2 point, float time, int forceMode, bool forceIgnoreMass = false, bool ignoreBlock = false) + { + for (float i = 0f; i < time; i += TimeHandler.fixedDeltaTime) + { + Vector2 vector = point - (Vector2)base.transform.position; + vector = Vector2.ClampMagnitude(vector, clampDistancce); + Vector2 vector2 = data.playerVel.velocity * (0f - drag) * TimeHandler.fixedDeltaTime; + TakeForce(force * vector + vector2 * drag * TimeHandler.timeScale, (ForceMode2D)forceMode, forceIgnoreMass, ignoreBlock); + data.GetComponent<SyncPlayerMovement>().SetDontSyncFor((float)PhotonNetwork.GetPing() * 0.001f + 0.2f); + yield return new WaitForFixedUpdate(); + } + } + + public void TakeForce(Vector2 force, ForceMode2D forceMode = ForceMode2D.Impulse, bool forceIgnoreMass = false, bool ignoreBlock = false, float setFlying = 0f) + { + if (!data.isPlaying || !data.playerVel.simulated) + { + return; + } + bool flag = data.block.IsBlocking(); + if (flag && !ignoreBlock) + { + return; + } + if (!flag) + { + if (setFlying > flyingFor && setFlying > 0.25f) + { + flyingFor = setFlying; + SoundManager.Instance.Play(soundBounce, base.transform); + } + } + if (forceIgnoreMass) + { + force *= data.playerVel.mass / 100f; + } + data.playerVel.AddForce(force, forceMode); + if (force.y > 0f) + { + if (!forceIgnoreMass) + { + force.y /= data.playerVel.mass / 100f; + } + if (forceMode == ForceMode2D.Force) + { + force *= 0.003f; + } + data.sinceGrounded -= force.y * 0.003f; + } + data.sinceGrounded = Mathf.Clamp(data.sinceGrounded, -0.5f, 100f); + } + + public override void CallTakeDamage(Vector2 damage, Vector2 position, GameObject damagingWeapon = null, Player damagingPlayer = null, bool lethal = true) + { + if (!(damage == Vector2.zero) && !data.block.IsBlocking()) + { + data.view.RPC("RPCA_SendTakeDamage", RpcTarget.All, damage, position, lethal, (damagingPlayer != null) ? damagingPlayer.playerID : (-1)); + } + } + + [PunRPC] + public void RPCA_SendTakeDamage(Vector2 damage, Vector2 position, bool lethal = true, int playerID = -1) + { + if (!(damage == Vector2.zero)) + { + Player playerWithID = PlayerManager.instance.GetPlayerWithID(playerID); + GameObject damagingWeapon = null; + if ((bool)playerWithID) + { + damagingWeapon = playerWithID.data.weaponHandler.gun.gameObject; + } + TakeDamage(damage, position, damagingWeapon, playerWithID, lethal, ignoreBlock: true); + } + } + + public override void TakeDamage(Vector2 damage, Vector2 position, GameObject damagingWeapon = null, Player damagingPlayer = null, bool lethal = true, bool ignoreBlock = false) + { + if (!(damage == Vector2.zero)) + { + TakeDamage(damage, position, Color.white * 0.85f, damagingWeapon, damagingPlayer, lethal, ignoreBlock); + } + } + + public override void TakeDamage(Vector2 damage, Vector2 position, Color dmgColor, GameObject damagingWeapon = null, Player damagingPlayer = null, bool lethal = true, bool ignoreBlock = false) + { + if (!(damage == Vector2.zero) && data.isPlaying && data.playerVel.simulated && !data.dead && (!data.block.IsBlocking() || ignoreBlock)) + { + if (dmgColor == Color.black) + { + dmgColor = Color.white * 0.85f; + } + if (stats.secondsToTakeDamageOver == 0f) + { + DoDamage(damage, position, dmgColor, damagingWeapon, damagingPlayer, healthRemoval: false, lethal, ignoreBlock); + } + else + { + TakeDamageOverTime(damage, position, stats.secondsToTakeDamageOver, 0.25f, dmgColor, damagingWeapon, damagingPlayer, lethal); + } + } + } + + public void DoDamage(Vector2 damage, Vector2 position, Color blinkColor, GameObject damagingWeapon = null, Player damagingPlayer = null, bool healthRemoval = false, bool lethal = true, bool ignoreBlock = false) + { + if (damage == Vector2.zero || !data.isPlaying || data.dead || (data.block.IsBlocking() && !ignoreBlock) || isRespawning) + { + return; + } + if ((bool)damagingPlayer) + { + damagingPlayer.GetComponent<CharacterStatModifiers>().DealtDamage(damage, damagingPlayer != null && damagingPlayer.transform.root == base.transform, data.player); + } + StopAllCoroutines(); + DisplayDamage(blinkColor); + data.lastSourceOfDamage = damagingPlayer; + data.health -= damage.magnitude; + stats.WasDealtDamage(damage, damagingPlayer != null && damagingPlayer.transform.root == base.transform); + if (!lethal) + { + data.health = Mathf.Clamp(data.health, 1f, data.maxHealth); + } + if (data.health < 0f && !data.dead) + { + if (data.stats.remainingRespawns > 0) + { + data.view.RPC("RPCA_Die_Phoenix", RpcTarget.All, damage); + } + else + { + data.view.RPC("RPCA_Die", RpcTarget.All, damage); + } + } + if (lastDamaged + 0.15f < Time.time && damagingPlayer != null && damagingPlayer.data.stats.lifeSteal != 0f) + { + SoundManager.Instance.Play(soundDamageLifeSteal, base.transform); + } + lastDamaged = Time.time; + } + + public void TakeDamageOverTime(Vector2 damage, Vector2 position, float time, float interval, Color color, GameObject damagingWeapon = null, Player damagingPlayer = null, bool lethal = true) + { + dot.TakeDamageOverTime(damage, position, time, interval, color, soundDamagePassive, damagingWeapon, damagingPlayer, lethal); + } + + private void DisplayDamage(Color blinkColor) + { + GetComponentInChildren<PlayerSkinHandler>().BlinkColor(blinkColor); + } + + private IEnumerator DelayReviveAction() + { + yield return new WaitForSecondsRealtime(2f); + delayedReviveAction?.Invoke(); + } + + public void Revive(bool isFullRevive = true) + { + reviveAction?.Invoke(); + if (base.gameObject.activeInHierarchy) + { + StartCoroutine(DelayReviveAction()); + } + flyingFor = 0f; + if (isFullRevive) + { + data.stats.remainingRespawns = data.stats.respawns; + } + data.healthHandler.isRespawning = false; + data.health = data.maxHealth; + data.playerVel.velocity = Vector2.zero; + data.playerVel.angularVelocity = 0f; + data.stunTime = 0f; + data.block.ResetCD(soundPlay: false); + data.weaponHandler.gun.GetComponentInChildren<GunAmmo>().ReloadAmmo(playSound: false); + data.GetComponent<PlayerCollision>().IgnoreWallForFrames(5); + base.gameObject.SetActive(value: true); + if ((bool)deathEffect && data.dead) + { + anim.PlayIn(); + } + data.dead = false; + hpSprite.color = PlayerSkinBank.GetPlayerSkinColors(player.playerID).color; + data.stunHandler.StopStun(); + data.silenceHandler.StopSilence(); + GetComponent<CharacterStatModifiers>().slow = 0f; + GetComponent<CharacterStatModifiers>().slowSlow = 0f; + GetComponent<CharacterStatModifiers>().fastSlow = 0f; + GetComponent<WeaponHandler>().isOverHeated = false; + GetComponent<Block>().sinceBlock = float.PositiveInfinity; + dot.StopAllCoroutines(); + } + + [PunRPC] + private void RPCA_Die(Vector2 deathDirection) + { + if (data.isPlaying && !data.dead) + { + SoundManager.Instance.Play(soundDie, base.transform); + data.dead = true; + if (!DestroyOnDeath) + { + base.gameObject.SetActive(value: false); + GamefeelManager.GameFeel(deathDirection.normalized * 3f); + UnityEngine.Object.Instantiate(deathEffect, base.transform.position, base.transform.rotation).GetComponent<DeathEffect>().PlayDeath(PlayerSkinBank.GetPlayerSkinColors(player.playerID).color, data.playerVel, deathDirection); + dot.StopAllCoroutines(); + data.stunHandler.StopStun(); + data.silenceHandler.StopSilence(); + PlayerManager.instance.PlayerDied(player); + } + else + { + UnityEngine.Object.Destroy(base.transform.root.gameObject); + } + } + } + + [PunRPC] + private void RPCA_Die_Phoenix(Vector2 deathDirection) + { + if (data.isPlaying && !data.dead) + { + data.stats.remainingRespawns--; + isRespawning = true; + SoundManager.Instance.Play(soundDie, base.transform); + if (!DestroyOnDeath) + { + base.gameObject.SetActive(value: false); + GamefeelManager.GameFeel(deathDirection.normalized * 3f); + UnityEngine.Object.Instantiate(deathEffectPhoenix, base.transform.position, base.transform.rotation).GetComponent<DeathEffect>().PlayDeath(PlayerSkinBank.GetPlayerSkinColors(player.playerID).color, data.playerVel, deathDirection, player.playerID); + dot.StopAllCoroutines(); + data.stunHandler.StopStun(); + data.silenceHandler.StopSilence(); + } + } + } +} diff --git a/GameCode/HitInfo.cs b/GameCode/HitInfo.cs new file mode 100644 index 0000000..782dce3 --- /dev/null +++ b/GameCode/HitInfo.cs @@ -0,0 +1,26 @@ +using UnityEngine; + +public class HitInfo +{ + public Vector2 point; + + public Vector2 normal; + + public Collider2D collider; + + public Transform transform; + + public Rigidbody2D rigidbody; + + internal static HitInfo GetHitInfo(RaycastHit2D raycastHit2D) + { + return new HitInfo + { + point = raycastHit2D.point, + normal = raycastHit2D.normal, + transform = raycastHit2D.transform, + collider = raycastHit2D.collider, + rigidbody = raycastHit2D.rigidbody + }; + } +} diff --git a/GameCode/Holdable.cs b/GameCode/Holdable.cs new file mode 100644 index 0000000..c2329b5 --- /dev/null +++ b/GameCode/Holdable.cs @@ -0,0 +1,22 @@ +using UnityEngine; + +public class Holdable : MonoBehaviour +{ + public Rigidbody2D rig; + + public CharacterData holder; + + private void Awake() + { + rig = GetComponent<Rigidbody2D>(); + } + + private void Start() + { + } + + public void SetTeamColors(PlayerSkin teamColor, Player player) + { + SetTeamColor.TeamColorThis(base.gameObject, teamColor); + } +} diff --git a/GameCode/Holding.cs b/GameCode/Holding.cs new file mode 100644 index 0000000..1f1839f --- /dev/null +++ b/GameCode/Holding.cs @@ -0,0 +1,75 @@ +using UnityEngine; + +public class Holding : MonoBehaviour +{ + public float force; + + public float drag; + + public Holdable holdable; + + private Transform handPos; + + private PlayerVelocity rig; + + private GeneralInput input; + + private CharacterData data; + + private Player player; + + private Gun gun; + + private bool hasSpawnedGun; + + public void Awake() + { + if (hasSpawnedGun) + { + Object.Destroy(holdable.gameObject); + } + hasSpawnedGun = true; + holdable = Object.Instantiate(holdable, base.transform.position, Quaternion.identity); + player = GetComponent<Player>(); + holdable.GetComponent<Holdable>().holder = player.data; + handPos = GetComponentInChildren<HandPos>().transform; + rig = GetComponent<PlayerVelocity>(); + input = GetComponent<GeneralInput>(); + data = GetComponent<CharacterData>(); + if ((bool)holdable) + { + gun = holdable.GetComponent<Gun>(); + GetComponentInChildren<WeaponHandler>().gun = holdable.GetComponent<Gun>(); + } + } + + private void Start() + { + if ((bool)holdable) + { + holdable.SetTeamColors(PlayerSkinBank.GetPlayerSkinColors(player.playerID), player); + } + } + + private void FixedUpdate() + { + if ((bool)holdable && (bool)holdable.rig) + { + holdable.rig.AddForce((handPos.transform.position + (Vector3)rig.velocity * 0.04f - holdable.transform.position) * force * holdable.rig.mass, ForceMode2D.Force); + holdable.rig.AddForce(holdable.rig.velocity * (0f - drag) * holdable.rig.mass, ForceMode2D.Force); + holdable.rig.transform.rotation = Quaternion.LookRotation(Vector3.forward, handPos.transform.forward); + } + } + + private void Update() + { + } + + private void OnDestroy() + { + if ((bool)holdable) + { + Object.Destroy(holdable.gameObject); + } + } +} diff --git a/GameCode/HoldingObject.cs b/GameCode/HoldingObject.cs new file mode 100644 index 0000000..c06d79f --- /dev/null +++ b/GameCode/HoldingObject.cs @@ -0,0 +1,22 @@ +using UnityEngine; + +public class HoldingObject : MonoBehaviour +{ + public Holding holder; + + private void Start() + { + } + + private void Update() + { + if (CardChoice.instance.IsPicking) + { + base.transform.position = Vector3.up * 10000f; + } + else if (Vector3.Distance(holder.transform.position, base.transform.position) > 100f) + { + base.transform.position = holder.transform.position; + } + } +} diff --git a/GameCode/Homing.cs b/GameCode/Homing.cs new file mode 100644 index 0000000..39a12c1 --- /dev/null +++ b/GameCode/Homing.cs @@ -0,0 +1,104 @@ +using Photon.Pun; +using Sonigon; +using UnityEngine; + +public class Homing : MonoBehaviour +{ + [Header("Sound")] + public SoundEvent soundHomingFound; + + private bool soundHomingCanPlay = true; + + [Header("Settings")] + public float amount = 1f; + + public float scalingDrag = 1f; + + public float drag = 1f; + + public float spread = 1f; + + private MoveTransform move; + + private bool isOn; + + public RotSpring rot1; + + public RotSpring rot2; + + private FlickerEvent[] flicks; + + private PhotonView view; + + private void Start() + { + move = GetComponentInParent<MoveTransform>(); + flicks = GetComponentsInChildren<FlickerEvent>(); + view = GetComponentInParent<PhotonView>(); + GetComponentInParent<SyncProjectile>().active = true; + } + + private void Update() + { + Player closestPlayer = PlayerManager.instance.GetClosestPlayer(base.transform.position, needVision: true); + if ((bool)closestPlayer) + { + Vector3 vector = closestPlayer.transform.position + base.transform.right * move.selectedSpread * Vector3.Distance(base.transform.position, closestPlayer.transform.position) * spread; + float num = Vector3.Angle(base.transform.root.forward, vector - base.transform.position); + if (num < 70f) + { + move.velocity -= move.velocity * num * TimeHandler.deltaTime * scalingDrag; + move.velocity -= move.velocity * TimeHandler.deltaTime * drag; + move.velocity += Vector3.ClampMagnitude(vector - base.transform.position, 1f) * TimeHandler.deltaTime * move.localForce.magnitude * 0.025f * amount; + move.velocity.z = 0f; + move.velocity += Vector3.up * TimeHandler.deltaTime * move.gravity * move.multiplier; + if (!isOn) + { + move.simulateGravity++; + if (soundHomingCanPlay) + { + soundHomingCanPlay = false; + SoundManager.Instance.PlayAtPosition(soundHomingFound, SoundManager.Instance.GetTransform(), base.transform); + } + } + isOn = true; + for (int i = 0; i < flicks.Length; i++) + { + flicks[i].isOn = true; + } + rot1.target = 10f; + rot2.target = -10f; + } + else + { + if (isOn) + { + move.simulateGravity--; + soundHomingCanPlay = true; + } + isOn = false; + for (int j = 0; j < flicks.Length; j++) + { + flicks[j].isOn = false; + } + rot1.target = 50f; + rot2.target = -50f; + } + } + else + { + if (isOn) + { + move.simulateGravity--; + soundHomingCanPlay = true; + } + isOn = false; + for (int k = 0; k < flicks.Length; k++) + { + flicks[k].isOn = false; + } + rot1.target = 50f; + rot2.target = -50f; + } + } +} diff --git a/GameCode/HoverEvent.cs b/GameCode/HoverEvent.cs new file mode 100644 index 0000000..6e9f332 --- /dev/null +++ b/GameCode/HoverEvent.cs @@ -0,0 +1,38 @@ +using SoundImplementation; +using UnityEngine; +using UnityEngine.Events; +using UnityEngine.EventSystems; + +public class HoverEvent : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler +{ + public UnityEvent enterEvent; + + public UnityEvent exitEvent; + + public bool isHovered; + + public bool isSelected; + + public void OnPointerEnter(PointerEventData eventData) + { + SoundPlayerStatic.Instance.PlayButtonHover(); + enterEvent.Invoke(); + isHovered = true; + } + + public void OnPointerExit(PointerEventData eventData) + { + exitEvent.Invoke(); + isHovered = false; + } + + private void Update() + { + isSelected = EventSystem.current.currentSelectedGameObject == base.gameObject; + } + + private void OnDisable() + { + isHovered = false; + } +} diff --git a/GameCode/HoverEventColor.cs b/GameCode/HoverEventColor.cs new file mode 100644 index 0000000..d6fa9c3 --- /dev/null +++ b/GameCode/HoverEventColor.cs @@ -0,0 +1,32 @@ +using UnityEngine; +using UnityEngine.UI; + +public class HoverEventColor : MonoBehaviour +{ + public Color hoverColor; + + private Color defaultColor; + + private HoverEvent hover; + + private Image img; + + private void Start() + { + img = GetComponent<Image>(); + defaultColor = img.color; + hover = GetComponent<HoverEvent>(); + hover.enterEvent.AddListener(Enter); + hover.exitEvent.AddListener(Exit); + } + + private void Enter() + { + img.color = hoverColor; + } + + private void Exit() + { + img.color = defaultColor; + } +} diff --git a/GameCode/HoverEvent_WobbleButton.cs b/GameCode/HoverEvent_WobbleButton.cs new file mode 100644 index 0000000..83e6079 --- /dev/null +++ b/GameCode/HoverEvent_WobbleButton.cs @@ -0,0 +1,45 @@ +using UnityEngine; +using UnityEngine.Events; +using UnityEngine.UI; + +public class HoverEvent_WobbleButton : MonoBehaviour +{ + public float min = 1f; + + public float max = 1.1f; + + public float spring = 1f; + + public float drag = 1f; + + public float force = -0.1f; + + private ScaleShake sh; + + private void Awake() + { + HoverEvent hoverEvent = base.gameObject.AddComponent<HoverEvent>(); + sh = base.gameObject.AddComponent<ScaleShake>(); + Button component = GetComponent<Button>(); + sh.spring = spring; + sh.drag = drag; + sh.multiplier = force; + sh.high = max; + sh.low = min; + sh.useTimeScale = false; + sh.SetTarget(min); + UnityEvent unityEvent = new UnityEvent(); + unityEvent.AddListener(sh.SetHigh); + hoverEvent.enterEvent = unityEvent; + UnityEvent unityEvent2 = new UnityEvent(); + unityEvent2.AddListener(sh.SetLow); + hoverEvent.exitEvent = unityEvent2; + component.onClick.AddListener(sh.AddForce); + } + + private void OnDisable() + { + base.transform.localScale = Vector3.one * min; + sh.SetTarget(min); + } +} diff --git a/GameCode/HoveredTooltip.cs b/GameCode/HoveredTooltip.cs new file mode 100644 index 0000000..4fa3cb7 --- /dev/null +++ b/GameCode/HoveredTooltip.cs @@ -0,0 +1,47 @@ +using UnityEngine; + +public class HoveredTooltip : MonoBehaviour +{ + private CurveAnimation anim; + + private HoverEvent hoverEvent; + + private void Start() + { + anim = GetComponent<CurveAnimation>(); + hoverEvent = GetComponentInParent<HoverEvent>(); + } + + private void Update() + { + if (!anim.IsPlaying()) + { + if ((hoverEvent.isHovered || hoverEvent.isSelected) && anim.currentState != 0) + { + anim.PlayIn(); + } + if (!hoverEvent.isHovered && !hoverEvent.isSelected && anim.currentState != CurveAnimationUse.Out) + { + anim.PlayOut(); + } + } + } + + private void OnEnable() + { + if ((bool)anim) + { + anim.currentState = CurveAnimationUse.Out; + anim.transform.localScale = Vector3.zero; + } + } + + private void OnDisable() + { + if ((bool)anim) + { + anim.currentState = CurveAnimationUse.Out; + anim.transform.localScale = Vector3.zero; + } + } +} diff --git a/GameCode/IKArmMove.cs b/GameCode/IKArmMove.cs new file mode 100644 index 0000000..ee14990 --- /dev/null +++ b/GameCode/IKArmMove.cs @@ -0,0 +1,56 @@ +using UnityEngine; + +public class IKArmMove : MonoBehaviour +{ + private CharacterData data; + + private PlayerVelocity rig; + + public Transform target; + + private Vector3 startPos; + + private Holding holding; + + private bool isActive; + + private Vector3 velolcity; + + private float sinceRaise = 10f; + + private void Start() + { + data = GetComponentInParent<CharacterData>(); + rig = GetComponentInParent<PlayerVelocity>(); + startPos = target.localPosition; + holding = GetComponentInParent<Holding>(); + } + + private void Update() + { + isActive = false; + sinceRaise += TimeHandler.deltaTime; + if ((bool)holding.holdable && (bool)holding.holdable.rig && holding.holdable.rig.transform.position.x > rig.transform.position.x == base.transform.position.x > rig.transform.position.x) + { + target.position = holding.holdable.rig.transform.position; + velolcity = Vector3.zero; + isActive = true; + return; + } + Vector3 vector = base.transform.parent.TransformPoint(startPos) + ((sinceRaise < 0.3f) ? Vector3.up : Vector3.zero); + Vector3 vector2 = rig.velocity; + vector2.x *= 0.3f; + velolcity = FRILerp.Lerp(velolcity, (vector - target.position) * 15f, 15f); + target.position += velolcity * TimeHandler.deltaTime; + target.position += vector2 * -0.3f * TimeHandler.deltaTime; + } + + public void RaiseHands() + { + if (!isActive) + { + sinceRaise = 0f; + velolcity += Vector3.up * 20f; + } + } +} diff --git a/GameCode/IKLegMove.cs b/GameCode/IKLegMove.cs new file mode 100644 index 0000000..cc6d6e6 --- /dev/null +++ b/GameCode/IKLegMove.cs @@ -0,0 +1,142 @@ +using UnityEngine; + +public class IKLegMove : MonoBehaviour +{ + private Rigidbody2D rig; + + public bool touchesGround; + + public IKLegMove otherLeg; + + public Transform target; + + public Transform foot; + + private Vector3 transformGroundPos; + + private Vector3 currentTransformGroundPos; + + private Vector3 previousTransformGroundPos; + + private Transform hitTransform; + + private Transform currentHitTransform; + + [HideInInspector] + public float allowedFootDistance; + + private float defaultAllowedFootDistance; + + public AnimationCurve footCurveUp; + + private float distanceToFoot; + + public LayerMask mask; + + [HideInInspector] + public float animationTime = 1f; + + private Vector3 velocity; + + private CharacterData data; + + private float animationLength; + + private bool hasLanded; + + private void Start() + { + rig = GetComponentInParent<Rigidbody2D>(); + data = GetComponentInParent<CharacterData>(); + defaultAllowedFootDistance = Vector3.Distance(base.transform.position, foot.position); + } + + private void LateUpdate() + { + allowedFootDistance = (defaultAllowedFootDistance = base.transform.root.localScale.x); + animationLength = footCurveUp.keys[footCurveUp.keys.Length - 1].time; + if (!data.isGrounded) + { + animationTime = 1f; + hasLanded = false; + } + distanceToFoot = Vector3.Distance(base.transform.position + (Vector3)rig.velocity * 0.01f, target.position); + velocity = rig.velocity; + if (velocity.y > 0f) + { + velocity.y *= -1f; + } + animationTime += TimeHandler.deltaTime; + RayCastForFootPosition(); + touchesGround = footCurveUp.Evaluate(animationTime) < 0.1f; + DoSteps(); + MoveFoot(); + } + + private void DoSteps() + { + float num = 0f; + if (target.position.x > base.transform.position.x == rig.velocity.x > 0f) + { + num += Mathf.Abs(rig.velocity.x) * 0.25f; + } + float num2 = Mathf.Clamp(animationTime * 0.4f - 0.23f, 0f, 0.2f); + if ((distanceToFoot > allowedFootDistance + num - num2 && data.isGrounded && (otherLeg.animationTime > animationLength * 0.5f || animationLength > 2f) && animationTime > animationLength) || !hasLanded) + { + hasLanded = true; + currentHitTransform = hitTransform; + previousTransformGroundPos = currentTransformGroundPos; + currentTransformGroundPos = transformGroundPos; + animationTime = 0f; + } + else + { + Vector3 vector = transformGroundPos - currentTransformGroundPos; + vector *= Mathf.Clamp(footCurveUp.Evaluate(animationTime) * 1f, 0f, 1f); + previousTransformGroundPos += vector; + currentTransformGroundPos += vector; + } + } + + private void MoveFoot() + { + if (!data.isGrounded) + { + target.position = Vector3.Lerp(target.position, base.transform.position + Vector3.down * allowedFootDistance * 0.5f, TimeHandler.deltaTime * 1f); + target.position += (Vector3)rig.velocity * 0.1f * TimeHandler.deltaTime; + } + else if ((bool)currentHitTransform) + { + Vector3 vector = currentHitTransform.TransformPoint(currentTransformGroundPos); + Vector3 a = currentHitTransform.TransformPoint(previousTransformGroundPos); + Vector3 vector2 = vector; + float num = 0f; + if (animationTime < animationLength) + { + vector2 = Vector3.Lerp(a, vector, animationTime / animationLength); + num = footCurveUp.Evaluate(animationTime); + } + target.position = vector2 + Vector3.up * num; + } + } + + private void RayCastForFootPosition() + { + RaycastHit2D[] array = Physics2D.RaycastAll(base.transform.position, Vector3.down + velocity * 0.2f, 3f, mask); + RaycastHit2D raycastHit2D = default(RaycastHit2D); + float num = float.PositiveInfinity; + for (int i = 0; i < array.Length; i++) + { + if (array[i].transform.root != base.transform.root && array[i].distance < num) + { + raycastHit2D = array[i]; + num = array[i].distance; + } + } + if ((bool)raycastHit2D.transform) + { + hitTransform = raycastHit2D.transform; + transformGroundPos = hitTransform.InverseTransformPoint(raycastHit2D.point); + } + } +} diff --git a/GameCode/IkLeg.cs b/GameCode/IkLeg.cs new file mode 100644 index 0000000..d8dd137 --- /dev/null +++ b/GameCode/IkLeg.cs @@ -0,0 +1,290 @@ +using Sonigon; +using UnityEngine; + +public class IkLeg : MonoBehaviour +{ + [Header("Sounds")] + [SerializeField] + private SoundEvent soundCharacterStep; + + [SerializeField] + private SoundEvent soundCharacterStepBig; + + private SoundParameterIntensity soundParameterIntensity = new SoundParameterIntensity(); + + private CharacterData data; + + private float legLenth; + + public Transform legRoot; + + public Transform footTarget; + + public LayerMask mask; + + public AnimationCurve upCurve; + + public AnimationCurve forwardCurve; + + public Transform moveDeltaTransform; + + [HideInInspector] + public float stepTime; + + public float stepSpeed = 1f; + + private float footDownTime; + + [HideInInspector] + public bool footDown = true; + + public IkLeg otherLeg; + + private Vector2 restPosition; + + private Vector2 startOffset; + + private Vector2 legRootOffset; + + private float scale = 1f; + + public float prediction = 1f; + + private Vector2 raycastPosLocal; + + private Vector2 raycastPosWorld; + + private Vector2 previousRaycastPosLocal; + + private Vector2 previousRaycastPosWorld; + + private Transform raycastTransform; + + private Transform previousRaycastTransform; + + private Vector2 footPosition; + + private Vector2 deltaPos; + + private Vector2 lastPos; + + private void Start() + { + data = GetComponentInParent<CharacterData>(); + legLenth = Vector3.Distance(base.transform.position, footTarget.position); + startOffset = footTarget.position - data.transform.position; + legRootOffset = legRoot.position - data.transform.position; + } + + private void FixedUpdate() + { + if ((bool)data) + { + SetValuesFixed(); + } + } + + private void LateUpdate() + { + if ((bool)data) + { + DoRayCast(); + UpdateRayCastWorldPos(); + DoStep(); + UpdatePreviousRayCastWorldPos(); + UpdateMiscVariables(); + SetFootPos(); + Apply(); + } + } + + private void AirFootMovement() + { + footPosition = Vector3.Lerp(footPosition, restPosition + data.playerVel.velocity * 0.08f, TimeHandler.deltaTime * 15f); + raycastTransform = null; + } + + private bool stepWasLost() + { + if (Vector3.Distance(footPosition, legRoot.position) > legLenth * 0.5f) + { + return true; + } + return false; + } + + private void DoStep() + { + if (footDown) + { + footDownTime += TimeHandler.deltaTime * stepSpeed / scale; + if (!(footDownTime > 1f) || !otherLeg.footDown || (!(Mathf.Abs(data.playerVel.velocity.x) > 1f) && !stepWasLost())) + { + return; + } + StartStep(); + footDownTime = 0f; + footDown = false; + if (!data.dead && data.isPlaying && data.isGrounded && !data.isWallGrab) + { + soundParameterIntensity.intensity = Mathf.Abs(data.playerVel.velocity.x); + if (data.stats.SoundTransformScaleThresholdReached()) + { + SoundManager.Instance.Play(soundCharacterStepBig, data.transform, soundParameterIntensity); + } + else + { + SoundManager.Instance.Play(soundCharacterStep, data.transform, soundParameterIntensity); + } + } + } + else + { + stepTime += TimeHandler.deltaTime * stepSpeed / scale; + if (stepTime > 1f) + { + EndStep(); + stepTime = 0f; + footDown = true; + } + } + } + + private void EndStep() + { + if ((bool)raycastTransform) + { + previousRaycastTransform = raycastTransform; + previousRaycastPosLocal = raycastPosLocal; + } + } + + private void StartStep() + { + } + + private void SetFootPos() + { + if (data.isGrounded) + { + if ((bool)raycastTransform) + { + if (footDown) + { + footPosition = previousRaycastPosWorld; + } + else + { + footPosition = Vector3.Lerp(previousRaycastPosWorld, raycastPosWorld, forwardCurve.Evaluate(stepTime)) + Vector3.up * upCurve.Evaluate(stepTime); + } + } + } + else + { + AirFootMovement(); + } + } + + private void Apply() + { + legRoot.position = (Vector2)data.transform.position + legRootOffset * scale; + footTarget.position = footPosition; + } + + private void DoRayCast() + { + Vector2 vector = deltaPos * prediction; + Vector2 origin = data.transform.position + base.transform.right * base.transform.localPosition.x; + Vector2 direction = Vector2.down + vector; + float distance = legLenth * 1.5f * scale + vector.magnitude; + RaycastHit2D[] array = Physics2D.RaycastAll(origin, direction, distance, mask); + RaycastHit2D hit = default(RaycastHit2D); + for (int i = 0; i < array.Length; i++) + { + if (!(array[i].transform.root == data.transform) && (bool)array[i].transform) + { + if (!hit.transform) + { + hit = array[i]; + } + else if (array[i].distance < hit.distance) + { + hit = array[i]; + } + } + } + if ((bool)hit.transform) + { + HitGround(hit); + } + else + { + HitNothing(); + } + } + + private void HitNothing() + { + } + + private void HitGround(RaycastHit2D hit) + { + bool flag = false; + if (!raycastTransform && (bool)hit.transform) + { + flag = true; + } + if ((bool)raycastTransform && raycastTransform != hit.transform) + { + MigrateGroundHit(raycastTransform, hit.transform, hit); + } + raycastTransform = hit.transform; + raycastPosLocal = raycastTransform.InverseTransformPoint(hit.point); + if (flag) + { + Land(hit); + } + } + + private void MigrateGroundHit(Transform from, Transform to, RaycastHit2D hit) + { + } + + private void Land(RaycastHit2D hit) + { + EndStep(); + UpdatePreviousRayCastWorldPos(); + } + + private void UpdateRayCastWorldPos() + { + if ((bool)raycastTransform) + { + raycastPosWorld = raycastTransform.TransformPoint(raycastPosLocal); + } + } + + private void UpdatePreviousRayCastWorldPos() + { + if ((bool)previousRaycastTransform) + { + previousRaycastPosWorld = previousRaycastTransform.TransformPoint(previousRaycastPosLocal); + } + } + + private void UpdateMiscVariables() + { + scale = data.transform.localScale.x; + restPosition = (Vector2)data.transform.position + startOffset * 0.7f * scale; + } + + private void SetValuesFixed() + { + if ((bool)moveDeltaTransform) + { + deltaPos = Vector3.Lerp(deltaPos, (Vector2)moveDeltaTransform.position - lastPos, TimeHandler.deltaTime * 15f); + lastPos = moveDeltaTransform.position; + deltaPos.y = 0f; + } + } +} diff --git a/GameCode/Immunities.cs b/GameCode/Immunities.cs new file mode 100644 index 0000000..e35e4dd --- /dev/null +++ b/GameCode/Immunities.cs @@ -0,0 +1,15 @@ +public class Immunities +{ + public float time; + + public float dmg; + + public string name; + + public Immunities(float time, float dmg, string name) + { + this.time = time; + this.dmg = dmg; + this.name = name; + } +} diff --git a/GameCode/Implosion.cs b/GameCode/Implosion.cs new file mode 100644 index 0000000..080936a --- /dev/null +++ b/GameCode/Implosion.cs @@ -0,0 +1,39 @@ +using System; +using Photon.Pun; +using UnityEngine; + +public class Implosion : MonoBehaviour +{ + public float force; + + public float drag; + + public float time; + + public float clampDist; + + private void Start() + { + Explosion component = GetComponent<Explosion>(); + component.HitTargetAction = (Action<Damagable, float>)Delegate.Combine(component.HitTargetAction, new Action<Damagable, float>(HitTarget)); + clampDist *= base.transform.localScale.x; + force *= base.transform.localScale.x; + } + + public void HitTarget(Damagable damageble, float distance) + { + DoPull(damageble, distance); + } + + private void DoPull(Damagable damageble, float distance) + { + bool num = GetComponent<SpawnedAttack>().IsMine(); + HealthHandler component = damageble.GetComponent<HealthHandler>(); + CharacterData component2 = damageble.GetComponent<CharacterData>(); + _ = (Vector2)((base.transform.position - component.transform.position) * 0.25f); + if (num) + { + component2.view.RPC("RPCA_SendForceTowardsPointOverTime", RpcTarget.All, force, drag, clampDist, (Vector2)base.transform.position, time, 0, false, false); + } + } +} diff --git a/GameCode/InitPackage.cs b/GameCode/InitPackage.cs new file mode 100644 index 0000000..8014287 --- /dev/null +++ b/GameCode/InitPackage.cs @@ -0,0 +1,4 @@ +public class InitPackage +{ + public int currentMapID; +} diff --git a/GameCode/IsMineEvent.cs b/GameCode/IsMineEvent.cs new file mode 100644 index 0000000..11e2ce3 --- /dev/null +++ b/GameCode/IsMineEvent.cs @@ -0,0 +1,12 @@ +using UnityEngine; + +public class IsMineEvent : MonoBehaviour +{ + private void Start() + { + } + + private void Update() + { + } +} diff --git a/GameCode/JustEvent.cs b/GameCode/JustEvent.cs new file mode 100644 index 0000000..2ca4c81 --- /dev/null +++ b/GameCode/JustEvent.cs @@ -0,0 +1,12 @@ +using UnityEngine; +using UnityEngine.Events; + +public class JustEvent : MonoBehaviour +{ + public UnityEvent justEvent; + + public void Go() + { + justEvent.Invoke(); + } +} diff --git a/GameCode/KillBox.cs b/GameCode/KillBox.cs new file mode 100644 index 0000000..eb69a56 --- /dev/null +++ b/GameCode/KillBox.cs @@ -0,0 +1,40 @@ +using UnityEngine; + +public class KillBox : MonoBehaviour +{ + public bool alwaysOn; + + public float toggleTime = 0.3f; + + private float timeActivated = -10f; + + public bool readyToKill; + + private BoxCollider2D box; + + private void Start() + { + box = GetComponent<BoxCollider2D>(); + } + + private void Update() + { + readyToKill = timeActivated + toggleTime > Time.time; + if (!readyToKill) + { + return; + } + for (int i = 0; i < PlayerManager.instance.players.Count; i++) + { + if (box.OverlapPoint(PlayerManager.instance.players[i].transform.position)) + { + PlayerManager.instance.players[i].data.healthHandler.TakeDamage(Vector2.up * 1000f, base.transform.position); + } + } + } + + public void Activate() + { + timeActivated = Time.time; + } +} diff --git a/GameCode/LeftRight.cs b/GameCode/LeftRight.cs new file mode 100644 index 0000000..d4777ee --- /dev/null +++ b/GameCode/LeftRight.cs @@ -0,0 +1,5 @@ +public enum LeftRight +{ + Left, + Right +} diff --git a/GameCode/LegRaycasters.cs b/GameCode/LegRaycasters.cs new file mode 100644 index 0000000..db676b0 --- /dev/null +++ b/GameCode/LegRaycasters.cs @@ -0,0 +1,77 @@ +using UnityEngine; + +public class LegRaycasters : MonoBehaviour +{ + public LayerMask mask; + + public float force; + + public float drag; + + public Transform[] legCastPositions; + + public AnimationCurve animationCurve; + + private PlayerVelocity rig; + + private CharacterData data; + + public AnimationCurve wobbleCurve; + + public AnimationCurve forceCurve; + + private IkLeg[] legs; + + private float totalStepTime; + + private void Awake() + { + legs = base.transform.root.GetComponentsInChildren<IkLeg>(); + } + + private void Start() + { + rig = GetComponentInParent<PlayerVelocity>(); + data = GetComponentInParent<CharacterData>(); + } + + private void FixedUpdate() + { + totalStepTime = 0f; + for (int i = 0; i < legs.Length; i++) + { + if (!legs[i].footDown) + { + totalStepTime += legs[i].stepTime; + } + } + for (int j = 0; j < legCastPositions.Length; j++) + { + RaycastHit2D[] array = Physics2D.RaycastAll(legCastPositions[j].transform.position + Vector3.up * 0.5f, Vector2.down, 1f * base.transform.root.localScale.x, mask); + for (int k = 0; k < array.Length; k++) + { + if ((bool)array[k].transform && array[k].transform.root != base.transform.root) + { + HitGround(legCastPositions[j], array[k]); + break; + } + } + } + } + + private void HitGround(Transform leg, RaycastHit2D hit) + { + if (!(data.sinceJump < 0.2f) && !(Vector3.Angle(Vector3.up, hit.normal) > 70f)) + { + data.TouchGround(hit.point, hit.normal, hit.rigidbody); + Vector3 vector = ((Vector3)hit.point - leg.transform.position) / base.transform.root.localScale.x; + if (data.input.direction.x != 0f) + { + vector.y += wobbleCurve.Evaluate(totalStepTime) * base.transform.root.localScale.x; + rig.AddForce(Vector3.up * forceCurve.Evaluate(totalStepTime) * rig.mass); + } + rig.AddForce(animationCurve.Evaluate(Mathf.Abs(vector.y)) * Vector3.up * rig.mass * force); + rig.AddForce(animationCurve.Evaluate(Mathf.Abs(vector.y)) * (0f - rig.velocity.y) * Vector2.up * rig.mass * drag); + } + } +} diff --git a/GameCode/LegRenderer.cs b/GameCode/LegRenderer.cs new file mode 100644 index 0000000..094b0c9 --- /dev/null +++ b/GameCode/LegRenderer.cs @@ -0,0 +1,77 @@ +using System.Collections.Generic; +using UnityEngine; + +public class LegRenderer : MonoBehaviour +{ + public Transform start; + + public Transform mid; + + public Transform end; + + public int segmentCount = 10; + + public GameObject segment; + + public float segmentLength = 1f; + + private List<Transform> segments = new List<Transform>(); + + private void Awake() + { + for (int i = 0; i < segmentCount; i++) + { + GameObject gameObject = Object.Instantiate(segment, base.transform); + gameObject.SetActive(value: true); + segments.Add(gameObject.transform); + if (i == segmentCount - 1) + { + gameObject.transform.localScale *= 0f; + } + } + } + + private void LateUpdate() + { + for (int i = 0; i < segments.Count; i++) + { + float t = (float)i / ((float)segments.Count - 1f); + _ = Vector3.zero; + if (i == 0) + { + _ = segments[i + 1].position - segments[i].position; + } + else if (i == segments.Count - 1) + { + _ = segments[i].position - segments[i - 1].position; + } + else + { + Vector3 vector = segments[i].position - segments[i - 1].position; + Vector3 vector2 = segments[i + 1].position - segments[i].position; + _ = (vector + vector2) * 0.5f; + } + segments[i].position = BezierCurve.QuadraticBezier(start.position, mid.position, end.position, t); + } + for (int j = 0; j < segments.Count; j++) + { + _ = (float)j / ((float)segments.Count - 1f); + Vector3 zero = Vector3.zero; + if (j == 0) + { + zero = segments[j + 1].position - segments[j].position; + } + else if (j == segments.Count - 1) + { + zero = segments[j].position - segments[j - 1].position; + } + else + { + Vector3 vector3 = segments[j].position - segments[j - 1].position; + Vector3 vector4 = segments[j + 1].position - segments[j].position; + zero = (vector3 + vector4) * 0.5f; + } + segments[j].rotation = Quaternion.LookRotation(Vector3.forward, zero); + } + } +} diff --git a/GameCode/LegRotator.cs b/GameCode/LegRotator.cs new file mode 100644 index 0000000..35e95b7 --- /dev/null +++ b/GameCode/LegRotator.cs @@ -0,0 +1,26 @@ +using UnityEngine; + +public class LegRotator : MonoBehaviour +{ + private PlayerVelocity rig; + + private void Start() + { + rig = GetComponentInParent<PlayerVelocity>(); + } + + private void Update() + { + if ((bool)rig) + { + if (rig.velocity.x < 0f) + { + base.transform.localEulerAngles = Vector3.Lerp(base.transform.localEulerAngles, new Vector3(0f, 0f, 0f), TimeHandler.deltaTime * 15f * Mathf.Clamp(Mathf.Abs(rig.velocity.x), 0f, 1f)); + } + else + { + base.transform.localEulerAngles = Vector3.Lerp(base.transform.localEulerAngles, new Vector3(0f, 180f, 0f), TimeHandler.deltaTime * 15f * Mathf.Clamp(Mathf.Abs(rig.velocity.x), 0f, 1f)); + } + } + } +} diff --git a/GameCode/LerpBackToStartPos.cs b/GameCode/LerpBackToStartPos.cs new file mode 100644 index 0000000..cf73c0b --- /dev/null +++ b/GameCode/LerpBackToStartPos.cs @@ -0,0 +1,12 @@ +using UnityEngine; + +public class LerpBackToStartPos : MonoBehaviour +{ + private void Start() + { + } + + private void Update() + { + } +} diff --git a/GameCode/LevelMapper.cs b/GameCode/LevelMapper.cs new file mode 100644 index 0000000..63e1e06 --- /dev/null +++ b/GameCode/LevelMapper.cs @@ -0,0 +1,132 @@ +using System; +using UnityEngine; + +public class LevelMapper : MonoBehaviour +{ + private CharacterData data; + + private PlayerJump jump; + + private PlayerMovement movement; + + private bool isJumping; + + private bool isRunning; + + public GameObject node; + + public GameObject line; + + public GameObject line2; + + private Vector3 jumpPos; + + private Vector3 landPos; + + private Vector3 startRunPos; + + private Vector3 leaveGroundPos; + + private void Start() + { + data = GetComponentInParent<CharacterData>(); + jump = data.jump; + movement = data.movement; + PlayerJump playerJump = jump; + playerJump.JumpAction = (Action)Delegate.Combine(playerJump.JumpAction, new Action(Jump)); + CharacterData characterData = data; + characterData.TouchGroundAction = (Action<float, Vector3, Vector3, Transform>)Delegate.Combine(characterData.TouchGroundAction, new Action<float, Vector3, Vector3, Transform>(Ground)); + CharacterData characterData2 = data; + characterData2.TouchWallAction = (Action<float, Vector3, Vector3>)Delegate.Combine(characterData2.TouchWallAction, new Action<float, Vector3, Vector3>(Wall)); + } + + private void Update() + { + if (!data.isGrounded) + { + LeaveGround(); + } + } + + private void Jump() + { + isJumping = true; + jumpPos = base.transform.position; + } + + private void Wall(float sinceWall, Vector3 pos, Vector3 normal) + { + if (!data.isWallGrab) + { + if (data.sinceJump < 0.1f) + { + isJumping = false; + } + else + { + Land(); + } + } + } + + private void Ground(float sinceGround, Vector3 pos, Vector3 groundNormal, Transform groundTransform = null) + { + if (!isRunning) + { + startRunPos = pos; + isRunning = true; + } + if (!data.isGrounded) + { + if (data.sinceJump < 0.1f) + { + isJumping = false; + } + else + { + Land(); + } + } + } + + private void Land() + { + landPos = base.transform.position; + if (Vector3.Distance(landPos, jumpPos) > 3f && isJumping) + { + SaveJump(); + } + isJumping = false; + } + + private void LeaveGround() + { + if (isRunning) + { + leaveGroundPos = data.groundPos; + SaveRun(); + isRunning = false; + } + } + + private void SaveJump() + { + UnityEngine.Object.Instantiate(node, jumpPos, Quaternion.identity).GetComponent<SpriteRenderer>().color = Color.green; + UnityEngine.Object.Instantiate(node, landPos, Quaternion.identity).GetComponent<SpriteRenderer>().color = Color.red; + LineRenderer component = UnityEngine.Object.Instantiate(line, Vector3.zero, Quaternion.identity).GetComponent<LineRenderer>(); + component.SetPosition(0, jumpPos); + component.SetPosition(1, landPos); + } + + private void SaveRun() + { + if (!(Vector3.Distance(startRunPos, jumpPos) < 2f)) + { + UnityEngine.Object.Instantiate(node, startRunPos, Quaternion.identity).GetComponent<SpriteRenderer>().color = Color.blue; + UnityEngine.Object.Instantiate(node, leaveGroundPos, Quaternion.identity).GetComponent<SpriteRenderer>().color = Color.blue; + LineRenderer component = UnityEngine.Object.Instantiate(line2, Vector3.zero, Quaternion.identity).GetComponent<LineRenderer>(); + component.SetPosition(0, startRunPos); + component.SetPosition(1, leaveGroundPos); + } + } +} diff --git a/GameCode/LevelScale.cs b/GameCode/LevelScale.cs new file mode 100644 index 0000000..39969ca --- /dev/null +++ b/GameCode/LevelScale.cs @@ -0,0 +1,45 @@ +using System; +using UnityEngine; + +public class LevelScale : MonoBehaviour +{ + public bool onLevelUp = true; + + public bool onStart; + + private AttackLevel level; + + private Vector3 startScale; + + private bool inited; + + private void Init() + { + if (!inited) + { + inited = true; + startScale = base.transform.localScale; + } + } + + private void Start() + { + Init(); + level = GetComponent<AttackLevel>(); + if (onStart) + { + base.transform.localScale *= level.LevelScale(); + } + if (onLevelUp) + { + AttackLevel attackLevel = level; + attackLevel.LevelUpAction = (Action<int>)Delegate.Combine(attackLevel.LevelUpAction, new Action<int>(LevelUp)); + } + } + + public void LevelUp(int lvl) + { + Init(); + base.transform.localScale = startScale * level.LevelScale(); + } +} diff --git a/GameCode/LifeSteal.cs b/GameCode/LifeSteal.cs new file mode 100644 index 0000000..6608cdb --- /dev/null +++ b/GameCode/LifeSteal.cs @@ -0,0 +1,20 @@ +using UnityEngine; + +public class LifeSteal : DealtDamageEffect +{ + private HealthHandler health; + + public float multiplier; + + public override void DealtDamage(Vector2 damage, bool selfDamage, Player damagedPlayer = null) + { + if (!selfDamage) + { + if (!health) + { + health = GetComponentInParent<HealthHandler>(); + } + health.Heal(damage.magnitude * multiplier); + } + } +} diff --git a/GameCode/LineEffect.cs b/GameCode/LineEffect.cs new file mode 100644 index 0000000..ee2cd03 --- /dev/null +++ b/GameCode/LineEffect.cs @@ -0,0 +1,454 @@ +using System; +using System.Collections; +using Sirenix.OdinInspector; +using UnityEngine; + +public class LineEffect : MonoBehaviour +{ + public enum LineType + { + Line, + Ring + } + + public enum AnimType + { + Width, + Offset + } + + public bool playOnAwake; + + public bool loop; + + public LineType lineType; + + public int segments = 20; + + public float globalTimeSpeed = 1f; + + public bool raycastCollision; + + [FoldoutGroup("Animation", 0)] + public AnimationCurve lineWidthOverTimeCurve = AnimationCurve.Linear(0f, 1f, 1f, 1f); + + [Space(10f)] + [FoldoutGroup("Animation", 0)] + public bool useColorOverTime; + + [FoldoutGroup("Animation", 0)] + [ShowIf("useColorOverTime", true)] + public Gradient colorOverTime; + + [Space(10f)] + [FoldoutGroup("Animation", 0)] + [ShowIf("lineType", LineType.Ring, true)] + public float radius = 5f; + + [FoldoutGroup("Animation", 0)] + [ShowIf("lineType", LineType.Ring, true)] + public AnimationCurve radiusOverTime = AnimationCurve.Linear(0f, 1f, 1f, 1f); + + [Space(10f)] + [FoldoutGroup("Special", 0)] + public float inheritScaleFactor; + + [Space(10f)] + public LineEffectInstance[] effects; + + private LineRenderer line; + + [HideInInspector] + public float counter; + + private float startWidth; + + [HideInInspector] + public float currentWidth; + + [FoldoutGroup("Debug", 0)] + public bool debug; + + [FoldoutGroup("Debug", 0)] + public Transform fromPos; + + [FoldoutGroup("Debug", 0)] + public Transform toPos; + + [FoldoutGroup("Debug", 0)] + public Transform bezierPos; + + [HideInInspector] + public float offsetMultiplier = 1f; + + [HideInInspector] + public float widthMultiplier = 1f; + + private float scaleMultiplier = 1f; + + private bool inited; + + public bool isPlaying; + + private Coroutine widthAnim; + + private Coroutine offsetAnim; + + private void Start() + { + globalTimeSpeed *= UnityEngine.Random.Range(0.95f, 1.05f); + } + + private void OnEnable() + { + if (!inited) + { + Init(); + } + if (playOnAwake && lineType == LineType.Ring) + { + Play(base.transform); + } + } + + private void Init() + { + if (!inited) + { + line = GetComponent<LineRenderer>(); + line.positionCount = segments; + line.useWorldSpace = true; + startWidth = line.widthMultiplier; + inited = true; + scaleMultiplier = 1f - inheritScaleFactor + base.transform.lossyScale.x * inheritScaleFactor; + } + } + + private void Update() + { + if (!debug) + { + return; + } + if (lineType == LineType.Line && (bool)fromPos && (bool)toPos) + { + if ((bool)bezierPos) + { + DrawLine(fromPos.position, toPos.position, bezierPos.position); + } + else + { + DrawLine(fromPos.position, toPos.position); + } + } + if (lineType == LineType.Ring && (bool)fromPos) + { + DrawLine(fromPos.position, Vector3.zero); + } + } + + public void StartDraw() + { + if (!base.gameObject.activeSelf) + { + base.gameObject.SetActive(value: true); + } + counter = 0f; + } + + public void DrawLine(Vector3 start, Vector3 end) + { + DrawLine(start, end, Vector3.one * 100f); + } + + public void DrawLine(Vector3 start, Vector3 end, Vector3 bezier) + { + Init(); + Vector3 vector = Vector3.zero; + for (int i = 0; i < line.positionCount; i++) + { + float num = 0f; + for (int j = 0; j < effects.Length; j++) + { + if (!effects[j].active) + { + continue; + } + float num2 = 0f; + float num3 = (float)i / ((float)line.positionCount - 1f); + float time = num3; + float num4 = effects[j].mainCurveTiling; + if (effects[j].tilingPerMeter) + { + if (lineType == LineType.Line) + { + num4 *= (start - end).magnitude; + } + if (lineType == LineType.Ring) + { + num4 *= radius; + } + } + num3 *= num4; + if (effects[j].mainCurveScrollSpeed > 0f) + { + num3 += effects[j].mainCurveScrollSpeed * Time.unscaledTime; + } + if (effects[j].mainCurveScrollSpeed < 0f) + { + num3 += (0f - effects[j].mainCurveScrollSpeed) * (100000f - Time.unscaledTime); + } + num3 %= 1f; + num2 = effects[j].mainCurve.Evaluate(num3); + num2 *= effects[j].mainCurveMultiplier; + num2 *= effects[j].effectOverLineCurve.Evaluate(time); + num2 *= effects[j].effectOverTimeCurve.Evaluate(counter); + if (effects[j].curveType == LineEffectInstance.CurveType.Add) + { + num += num2; + } + else if (effects[j].curveType == LineEffectInstance.CurveType.Multiply) + { + num *= num2; + } + } + float t = (float)i / ((float)line.positionCount - 1f); + Vector3 vector2 = Vector3.zero; + Vector3 vector3 = Vector3.zero; + if (lineType == LineType.Ring) + { + float f = (float)Math.PI / 180f * ((float)i * 360f / (float)(segments - 1)); + vector2 = start + new Vector3(Mathf.Sin(f) * (radius * base.transform.root.localScale.x * radiusOverTime.Evaluate(counter)), Mathf.Cos(f) * (radius * base.transform.root.localScale.x * radiusOverTime.Evaluate(counter)), 0f); + vector3 = ((!(vector != Vector3.zero)) ? Vector3.up : Vector3.Cross(Vector3.forward, vector2 - vector).normalized); + } + if (lineType == LineType.Line) + { + vector2 = Vector3.Lerp(start, end, t); + vector3 = Vector3.Cross(start - end, Vector3.forward).normalized; + if (bezier != Vector3.one * 100f) + { + vector2 = BezierCurve.QuadraticBezier(start, bezier, end, t); + } + } + vector = vector2; + line.SetPosition(i, vector2 + vector3 * num * offsetMultiplier); + } + if (raycastCollision) + { + RaycastPositions(); + } + if (lineType == LineType.Ring) + { + SmoothSeam(); + } + line.widthMultiplier = lineWidthOverTimeCurve.Evaluate(counter) * startWidth * scaleMultiplier * widthMultiplier; + currentWidth = line.widthMultiplier; + if (useColorOverTime) + { + line.startColor = colorOverTime.Evaluate(counter); + line.endColor = colorOverTime.Evaluate(counter); + } + counter += Time.unscaledDeltaTime * globalTimeSpeed; + if (counter > 1f) + { + if (debug || loop) + { + StartDraw(); + } + else + { + base.gameObject.SetActive(value: false); + } + } + } + + private void RaycastPositions() + { + for (int i = 0; i < line.positionCount; i++) + { + line.SetPosition(i, PhysicsFunctions.ObstructionPoint(base.transform.position, line.GetPosition(i))); + } + } + + private void SmoothSeam() + { + float num = 0.1f; + Vector3 b = (line.GetPosition(0) + line.GetPosition(line.positionCount - 1)) * 0.5f; + for (int i = 0; i < line.positionCount; i++) + { + float num2 = (float)i / ((float)line.positionCount - 1f); + _ = Vector3.zero; + Vector3 zero = Vector3.zero; + Vector3 position = line.GetPosition(i); + float t; + if (num2 > 0.5f) + { + t = Mathf.Clamp((num2 - (1f - num)) / num, 0f, 1f); + } + else + { + t = Mathf.Clamp(num2 * (1f / num), 0f, 1f); + t = 1f - t; + } + zero = Vector3.Lerp(position, b, t) - position; + zero.x *= 0.5f; + line.SetPosition(i, position + zero); + } + line.SetPosition(1, new Vector3(line.GetPosition(1).x, b.y)); + line.SetPosition(line.positionCount - 2, new Vector3(line.GetPosition(line.positionCount - 2).x, b.y)); + } + + public void Stop() + { + StopAllCoroutines(); + if (!loop) + { + base.gameObject.SetActive(value: false); + } + } + + public void Play() + { + Play(base.transform); + } + + private void OnDisable() + { + Stop(); + } + + public void ResetMultipliers() + { + offsetMultiplier = 1f; + scaleMultiplier = 1f; + widthMultiplier = 1f; + } + + public void Play(Transform fromTransform, Transform toTransform, float bezierOffset = 0f) + { + StartDraw(); + StopAllCoroutines(); + StartCoroutine(DoPlay(fromTransform, toTransform, bezierOffset)); + } + + private IEnumerator DoPlay(Transform fromTransform, Transform toTransform, float bezierOffset = 0f) + { + isPlaying = true; + Vector3 currentBez = Vector3.zero; + while (base.gameObject.activeSelf && (bool)fromTransform && (bool)toTransform) + { + if (bezierOffset != 0f) + { + float num = 1f; + if (toTransform.position.x < fromTransform.position.x) + { + num = -1f; + } + Vector3 vector = Vector3.Cross(Vector3.forward, toTransform.position - fromTransform.position).normalized * bezierOffset * num; + currentBez = ((!(currentBez == Vector3.zero)) ? Vector3.Lerp(currentBez, vector, TimeHandler.deltaTime * 5f) : vector); + Vector3 bezier = currentBez + (fromTransform.position + toTransform.position) * 0.5f; + DrawLine(fromTransform.position, toTransform.position, bezier); + } + else + { + DrawLine(fromTransform.position, toTransform.position); + } + yield return null; + } + isPlaying = false; + } + + public void Play(Transform fromTransform, Vector3 toPosition, float bezierOffset = 0f) + { + StartDraw(); + StopAllCoroutines(); + StartCoroutine(DoPlay(fromTransform, toPosition, bezierOffset)); + } + + private IEnumerator DoPlay(Transform fromTransform, Vector3 toPosition, float bezierOffset = 0f) + { + Vector3 currentBezOffset = Vector3.zero; + while (base.gameObject.activeSelf && (bool)fromTransform) + { + if (bezierOffset != 0f) + { + float num = 1f; + if (toPosition.x < fromTransform.position.x) + { + num = -1f; + } + Vector3 vector = Vector3.Cross(Vector3.forward, toPosition - fromTransform.position).normalized * bezierOffset * num; + currentBezOffset = ((!(currentBezOffset == Vector3.zero)) ? Vector3.Lerp(currentBezOffset, vector, TimeHandler.deltaTime * 2f) : vector); + _ = currentBezOffset + (fromTransform.position + toPosition) * 0.5f; + Vector3 bezier = (fromTransform.position + toPosition) * 0.5f; + DrawLine(fromTransform.position, toPosition, bezier); + } + else + { + DrawLine(fromTransform.position, toPosition); + } + yield return null; + } + } + + public void Play(Transform fromTransform) + { + StartDraw(); + StopAllCoroutines(); + StartCoroutine(DoPlay(fromTransform)); + } + + private IEnumerator DoPlay(Transform fromTransform) + { + while (base.gameObject.activeSelf && (bool)fromTransform) + { + DrawLine(fromTransform.position, Vector3.zero); + yield return null; + } + } + + public void PlayAnim(AnimType animType, AnimationCurve curve, float speed = 1f) + { + if (animType == AnimType.Offset && offsetAnim != null) + { + StopCoroutine(offsetAnim); + } + if (animType == AnimType.Width && widthAnim != null) + { + StopCoroutine(widthAnim); + } + Coroutine coroutine = StartCoroutine(DoPlayAnim(animType, curve, speed)); + if (animType == AnimType.Offset) + { + offsetAnim = coroutine; + } + if (animType == AnimType.Width) + { + widthAnim = coroutine; + } + } + + private IEnumerator DoPlayAnim(AnimType animType, AnimationCurve curve, float speed = 1f) + { + float c = 0f; + float t = curve.keys[curve.keys.Length - 1].time; + while (c < t) + { + if (animType == AnimType.Offset) + { + offsetMultiplier = curve.Evaluate(c); + } + if (animType == AnimType.Width) + { + widthMultiplier = curve.Evaluate(c); + } + c += TimeHandler.deltaTime * speed; + yield return null; + } + } + + internal float GetRadius() + { + return radius * base.transform.root.localScale.x * radiusOverTime.Evaluate(counter); + } +} diff --git a/GameCode/LineEffectExplosionModifier.cs b/GameCode/LineEffectExplosionModifier.cs new file mode 100644 index 0000000..3f1c66b --- /dev/null +++ b/GameCode/LineEffectExplosionModifier.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections; +using UnityEngine; + +public class LineEffectExplosionModifier : MonoBehaviour +{ + public AnimationCurve curve; + + public float speed = 1f; + + private LineEffect effect; + + private Coroutine corutine; + + private void Start() + { + effect = GetComponent<LineEffect>(); + Explosion componentInParent = GetComponentInParent<Explosion>(); + componentInParent.DealDamageAction = (Action<Damagable>)Delegate.Combine(componentInParent.DealDamageAction, new Action<Damagable>(DealDamage)); + Explosion componentInParent2 = GetComponentInParent<Explosion>(); + componentInParent2.DealHealAction = (Action<Damagable>)Delegate.Combine(componentInParent2.DealHealAction, new Action<Damagable>(DealDamage)); + } + + public void DealDamage(Damagable damagable) + { + if (corutine != null) + { + StopCoroutine(corutine); + } + corutine = StartCoroutine(DoCurve()); + } + + private IEnumerator DoCurve() + { + float c = 0f; + float t = curve.keys[curve.keys.Length - 1].time; + while (c < t) + { + effect.offsetMultiplier = curve.Evaluate(c); + c += TimeHandler.deltaTime * speed; + yield return null; + } + } +} diff --git a/GameCode/LineEffectInstance.cs b/GameCode/LineEffectInstance.cs new file mode 100644 index 0000000..a154130 --- /dev/null +++ b/GameCode/LineEffectInstance.cs @@ -0,0 +1,40 @@ +using System; +using Sirenix.OdinInspector; +using UnityEngine; + +[Serializable] +public class LineEffectInstance +{ + public enum CurveType + { + Add, + Multiply + } + + [Space(20f)] + public bool active = true; + + [FoldoutGroup("Main Curve", 0, Order = 0, Expanded = true)] + public CurveType curveType; + + [FoldoutGroup("Main Curve", 0, Order = 0, Expanded = true)] + public AnimationCurve mainCurve = AnimationCurve.Linear(0f, 0f, 1f, 0f); + + [FoldoutGroup("Main Curve", 0, Order = 0, Expanded = true)] + public float mainCurveMultiplier = 1f; + + [FoldoutGroup("Main Curve", 0, Order = 0, Expanded = true)] + public float mainCurveTiling = 1f; + + [FoldoutGroup("Main Curve", 0, Order = 0, Expanded = true)] + public bool tilingPerMeter = true; + + [FoldoutGroup("Modifiers", 0)] + public AnimationCurve effectOverLineCurve = AnimationCurve.Linear(0f, 1f, 1f, 1f); + + [FoldoutGroup("Animation", 0)] + public float mainCurveScrollSpeed; + + [FoldoutGroup("Animation", 0)] + public AnimationCurve effectOverTimeCurve = AnimationCurve.Linear(0f, 1f, 1f, 0f); +} diff --git a/GameCode/LineOfSightTrigger.cs b/GameCode/LineOfSightTrigger.cs new file mode 100644 index 0000000..99fca28 --- /dev/null +++ b/GameCode/LineOfSightTrigger.cs @@ -0,0 +1,59 @@ +using System; +using UnityEngine; +using UnityEngine.Events; + +public class LineOfSightTrigger : MonoBehaviour +{ + public UnityEvent turnOnEvent; + + public UnityEvent turnOffEvent; + + public UnityEvent switchTargetEvent; + + public Action<Player> turnOnAction; + + public Action<Player> switchTargetAction; + + public Action turnOffAction; + + private Player player; + + private bool isOn; + + private Player currentTarget; + + private void Start() + { + player = GetComponentInParent<Player>(); + } + + private void Update() + { + Player closestPlayerInTeam = PlayerManager.instance.GetClosestPlayerInTeam(base.transform.position, PlayerManager.instance.GetOtherTeam(player.teamID)); + if ((bool)closestPlayerInTeam) + { + if (currentTarget != player) + { + switchTargetEvent.Invoke(); + switchTargetAction?.Invoke(player); + currentTarget = closestPlayerInTeam; + } + if (!isOn) + { + isOn = true; + turnOnAction?.Invoke(player); + turnOnEvent.Invoke(); + } + } + else + { + if (isOn) + { + isOn = false; + turnOffAction?.Invoke(); + turnOffEvent.Invoke(); + } + currentTarget = null; + } + } +} diff --git a/GameCode/LineRangeEffect.cs b/GameCode/LineRangeEffect.cs new file mode 100644 index 0000000..6671fcc --- /dev/null +++ b/GameCode/LineRangeEffect.cs @@ -0,0 +1,44 @@ +using UnityEngine; + +public class LineRangeEffect : MonoBehaviour +{ + public float dmg; + + public float knockback; + + private LineEffect lineEffect; + + private Player owner; + + private SpawnedAttack spawned; + + private bool done; + + private void Start() + { + spawned = GetComponent<SpawnedAttack>(); + owner = GetComponent<SpawnedAttack>().spawner; + lineEffect = GetComponentInChildren<LineEffect>(); + } + + private void Update() + { + if (done || !spawned.IsMine()) + { + return; + } + Player closestPlayerInTeam = PlayerManager.instance.GetClosestPlayerInTeam(base.transform.position, PlayerManager.instance.GetOtherTeam(owner.teamID), needVision: true); + if ((bool)closestPlayerInTeam) + { + float num = 2f; + float radius = lineEffect.GetRadius(); + float num2 = Vector2.Distance(base.transform.position, closestPlayerInTeam.transform.position); + if (num2 < radius + num && num2 > radius - num) + { + done = true; + closestPlayerInTeam.data.healthHandler.CallTakeDamage(dmg * base.transform.localScale.x * (closestPlayerInTeam.transform.position - base.transform.position).normalized, closestPlayerInTeam.transform.position, null, owner); + closestPlayerInTeam.data.healthHandler.CallTakeForce(knockback * base.transform.localScale.x * (closestPlayerInTeam.transform.position - base.transform.position).normalized); + } + } + } +} diff --git a/GameCode/ListMenu.cs b/GameCode/ListMenu.cs new file mode 100644 index 0000000..1ed98f6 --- /dev/null +++ b/GameCode/ListMenu.cs @@ -0,0 +1,136 @@ +using System.Collections; +using SoundImplementation; +using UnityEngine; +using UnityEngine.EventSystems; + +public class ListMenu : MonoBehaviour +{ + [Header("Settings")] + public GameObject bar; + + [Header("Settings")] + public GameObject particle; + + public ListMenuButton selectedButton; + + public ListMenuPage selectedPage; + + public static ListMenu instance; + + public GameObject menuCanvas; + + private bool isActive = true; + + private Vector3 lastPos; + + private bool playButtonHoverFirst = true; + + private void Awake() + { + instance = this; + } + + private void Start() + { + GetComponentInChildren<ListMenuPage>(includeInactive: true).Open(); + } + + private void Update() + { + if ((lastPos - bar.transform.position).sqrMagnitude > 0.5f && (MainMenuHandler.instance.isOpen || EscapeMenuHandler.isEscMenu)) + { + if (!playButtonHoverFirst) + { + SoundPlayerStatic.Instance.PlayButtonHover(); + } + else + { + playButtonHoverFirst = false; + } + } + lastPos = bar.transform.position; + if ((bool)selectedButton && EventSystem.current.currentSelectedGameObject == null) + { + EventSystem.current.SetSelectedGameObject(selectedButton.gameObject); + } + if (EscapeMenuHandler.isEscMenu || menuCanvas.activeInHierarchy) + { + if (!bar.activeSelf) + { + bar.SetActive(value: true); + particle.SetActive(value: true); + } + } + else if (bar.activeSelf) + { + bar.SetActive(value: false); + particle.SetActive(value: false); + } + } + + internal void DeselectButton() + { + if ((bool)selectedButton) + { + selectedButton.Deselect(); + } + } + + public void OpenPage(ListMenuPage pageToOpen) + { + if ((bool)selectedPage) + { + selectedPage.Close(); + } + bar.transform.localScale = new Vector3(bar.transform.localScale.x, pageToOpen.barHeight, 1f); + selectedPage = pageToOpen; + if (MenuControllerHandler.menuControl == MenuControllerHandler.MenuControl.Controller) + { + SelectButton(selectedPage.firstSelected); + } + else + { + bar.transform.position = Vector3.up * 10000f; + } + } + + public void SelectButton(ListMenuButton buttonToSelect) + { + if (!buttonToSelect || buttonToSelect.hideBar) + { + bar.transform.position = Vector3.up * 10000f; + } + else + { + StartCoroutine(ISelectButton(buttonToSelect)); + } + } + + public IEnumerator ISelectButton(ListMenuButton buttonToSelect) + { + if ((bool)selectedButton) + { + selectedButton.Deselect(); + } + yield return new WaitForEndOfFrame(); + buttonToSelect.Select(); + selectedButton = buttonToSelect; + bar.transform.position = buttonToSelect.transform.position; + if (EventSystem.current.currentSelectedGameObject != selectedButton.gameObject) + { + EventSystem.current.SetSelectedGameObject(selectedButton.gameObject); + } + if (buttonToSelect.setBarHeight != 0f) + { + bar.transform.localScale = new Vector3(bar.transform.localScale.x, buttonToSelect.setBarHeight, 1f); + } + } + + public void ClearBar() + { + if (MenuControllerHandler.menuControl != 0) + { + bar.transform.position = Vector3.up * 10000f; + } + } +} diff --git a/GameCode/ListMenuButton.cs b/GameCode/ListMenuButton.cs new file mode 100644 index 0000000..b208a12 --- /dev/null +++ b/GameCode/ListMenuButton.cs @@ -0,0 +1,102 @@ +using SoundImplementation; +using TMPro; +using UnityEngine; +using UnityEngine.EventSystems; + +public class ListMenuButton : MonoBehaviour, IPointerClickHandler, IEventSystemHandler, IPointerEnterHandler, IPointerExitHandler, IUpdateSelectedHandler, ISelectHandler +{ + private TextMeshProUGUI text; + + private Color defaultColor; + + private Vector3 defaultPos; + + public bool changeFontSize = true; + + public bool hideBar; + + public float setBarHeight; + + public bool toggleTextColor; + + public Color selectedTextColor; + + public Color defaultTextColor; + + private float smallFont = 40f; + + private bool inited; + + private void Awake() + { + } + + private void Start() + { + Init(); + smallFont = text.fontSize; + defaultPos = text.transform.localPosition; + defaultColor = text.color; + } + + public void Nope() + { + Init(); + MenuEffects.instance.BlinkInColor(text, MenuEffects.instance.nopeColor, defaultColor, 0.15f); + MenuEffects.instance.ShakeObject(text.gameObject, defaultPos, 15f, 0.2f); + } + + public void Deselect() + { + Init(); + text.fontStyle = FontStyles.Normal; + _ = changeFontSize; + if (toggleTextColor) + { + GetComponentInChildren<TextMeshProUGUI>().color = defaultTextColor; + } + } + + public void Select() + { + Init(); + text.fontStyle = FontStyles.Bold; + _ = changeFontSize; + if (toggleTextColor) + { + GetComponentInChildren<TextMeshProUGUI>().color = selectedTextColor; + } + } + + public void OnPointerClick(PointerEventData eventData) + { + SoundPlayerStatic.Instance.PlayButtonClick(); + } + + public void OnPointerEnter(PointerEventData eventData) + { + ListMenu.instance.SelectButton(this); + } + + public void OnPointerExit(PointerEventData eventData) + { + } + + public void OnUpdateSelected(BaseEventData eventData) + { + } + + public void OnSelect(BaseEventData eventData) + { + ListMenu.instance.SelectButton(this); + } + + private void Init() + { + if (!inited) + { + inited = true; + text = GetComponentInChildren<TextMeshProUGUI>(); + } + } +} diff --git a/GameCode/ListMenuPage.cs b/GameCode/ListMenuPage.cs new file mode 100644 index 0000000..e4735b4 --- /dev/null +++ b/GameCode/ListMenuPage.cs @@ -0,0 +1,36 @@ +using UnityEngine; + +public class ListMenuPage : MonoBehaviour +{ + public ListMenuButton firstSelected; + + public float barHeight = 92f; + + private GameObject grid; + + private void Awake() + { + grid = base.transform.GetChild(0).gameObject; + } + + public void Open() + { + ListMenu.instance.OpenPage(this); + grid.SetActive(value: true); + } + + public void Close() + { + DeselectAll(); + grid.SetActive(value: false); + } + + private void DeselectAll() + { + ListMenuButton[] componentsInChildren = GetComponentsInChildren<ListMenuButton>(); + for (int i = 0; i < componentsInChildren.Length; i++) + { + componentsInChildren[i].Deselect(); + } + } +} diff --git a/GameCode/LoadingScreen.cs b/GameCode/LoadingScreen.cs new file mode 100644 index 0000000..72d65fd --- /dev/null +++ b/GameCode/LoadingScreen.cs @@ -0,0 +1,81 @@ +using System.Collections; +using SoundImplementation; +using TMPro; +using UnityEngine; + +public class LoadingScreen : MonoBehaviour +{ + private const string SEARCHING_TEXT = "SEARCHING"; + + private const string SEARCHING_PRIVATE_TEXT = "WAITING FOR FRIEND"; + + [SerializeField] + private TextMeshProUGUI m_SearchingText; + + public GameObject gameMode; + + public GeneralParticleSystem searchingSystem; + + public GeneralParticleSystem matchFoundSystem; + + public GeneralParticleSystem[] playerNamesSystem; + + public float matchFoundTime = 0.5f; + + public float playerNameTime = 2f; + + public static LoadingScreen instance; + + private void Awake() + { + instance = this; + } + + public void StartLoading(bool privateGame = false) + { + StopAllCoroutines(); + matchFoundSystem.Stop(); + for (int i = 0; i < playerNamesSystem.Length; i++) + { + playerNamesSystem[i].Stop(); + } + searchingSystem.Play(); + m_SearchingText.text = GetSearchingString(privateGame); + } + + private string GetSearchingString(bool privGame) + { + if (privGame) + { + return "WAITING FOR FRIEND"; + } + return "SEARCHING"; + } + + private IEnumerator IDoLoading() + { + SoundPlayerStatic.Instance.PlayMatchFound(); + matchFoundSystem.Play(); + yield return new WaitForSeconds(matchFoundTime); + matchFoundSystem.Stop(); + GetComponentInChildren<DisplayMatchPlayerNames>().ShowNames(); + for (int i = 0; i < playerNamesSystem.Length; i++) + { + playerNamesSystem[i].Play(); + } + yield return new WaitForSeconds(playerNameTime); + for (int j = 0; j < playerNamesSystem.Length; j++) + { + playerNamesSystem[j].Stop(); + playerNamesSystem[j].GetComponentInParent<TextMeshProUGUI>().text = ""; + } + gameMode.SetActive(value: true); + } + + public void StopLoading() + { + StopAllCoroutines(); + searchingSystem.Stop(); + StartCoroutine(IDoLoading()); + } +} diff --git a/GameCode/LobbyHandler.cs b/GameCode/LobbyHandler.cs new file mode 100644 index 0000000..acf5511 --- /dev/null +++ b/GameCode/LobbyHandler.cs @@ -0,0 +1,8 @@ +using UnityEngine; + +public class LobbyHandler : MonoBehaviour +{ + private void Start() + { + } +} diff --git a/GameCode/Looper.cs b/GameCode/Looper.cs new file mode 100644 index 0000000..ec7f469 --- /dev/null +++ b/GameCode/Looper.cs @@ -0,0 +1,66 @@ +using UnityEngine; + +public class Looper : MonoBehaviour +{ + private float sinceLoop = 1f; + + private Camera mainCam; + + private TrailRenderer trail; + + private RayCastTrail rayTrail; + + private int loops = 3; + + private void Awake() + { + mainCam = MainCam.instance.transform.GetComponent<Camera>(); + trail = base.transform.root.GetComponentInChildren<TrailRenderer>(); + rayTrail = GetComponentInParent<RayCastTrail>(); + } + + private void Update() + { + if (loops <= 0 && sinceLoop > 0.3f) + { + Object.Destroy(this); + } + Vector3 vector = mainCam.WorldToScreenPoint(base.transform.position); + vector.x /= Screen.width; + vector.y /= Screen.height; + vector = new Vector3(Mathf.Clamp(vector.x, 0f, 1f), Mathf.Clamp(vector.y, 0f, 1f), vector.z); + if ((vector.x == 0f || vector.x == 1f || vector.y == 1f || vector.y == 0f) && sinceLoop > 0.1f) + { + if (vector.x == 0f) + { + vector.x = 1f; + } + else if (vector.x == 1f) + { + vector.x = 0f; + } + if (vector.y == 0f) + { + vector.y = 1f; + } + else if (vector.y == 1f) + { + vector.y = 0f; + } + vector.x *= Screen.width; + vector.y *= Screen.height; + base.transform.root.position = mainCam.ScreenToWorldPoint(vector); + rayTrail.MoveRay(); + for (int i = 0; i < trail.positionCount; i++) + { + trail.SetPosition(i, base.transform.position); + } + sinceLoop = 0f; + loops--; + } + else + { + sinceLoop += TimeHandler.deltaTime; + } + } +} diff --git a/GameCode/LowFrameRate.cs b/GameCode/LowFrameRate.cs new file mode 100644 index 0000000..1c86586 --- /dev/null +++ b/GameCode/LowFrameRate.cs @@ -0,0 +1,30 @@ +using Photon.Pun; +using UnityEngine; + +public class LowFrameRate : MonoBehaviourPunCallbacks +{ + public enum SlowWhat + { + Both, + Server, + Client + } + + public SlowWhat slowWhat = SlowWhat.Server; + + public int targetFrameRate = 10; + + public override void OnJoinedRoom() + { + base.OnJoinedRoom(); + if (slowWhat == SlowWhat.Both || (PhotonNetwork.IsMasterClient && slowWhat == SlowWhat.Server) || (!PhotonNetwork.IsMasterClient && slowWhat == SlowWhat.Client)) + { + Application.targetFrameRate = targetFrameRate; + QualitySettings.vSyncCount = 0; + } + else + { + Application.targetFrameRate = 100; + } + } +} diff --git a/GameCode/LowerScreenshakePerPlayer.cs b/GameCode/LowerScreenshakePerPlayer.cs new file mode 100644 index 0000000..77d6814 --- /dev/null +++ b/GameCode/LowerScreenshakePerPlayer.cs @@ -0,0 +1,15 @@ +using UnityEngine; + +public class LowerScreenshakePerPlayer : MonoBehaviour +{ + public Screenshaker shake; + + private void Update() + { + if (PlayerManager.instance.players.Count > 2) + { + shake.shakeforce *= 0.5f; + Object.Destroy(this); + } + } +} diff --git a/GameCode/MainCam.cs b/GameCode/MainCam.cs new file mode 100644 index 0000000..fc79454 --- /dev/null +++ b/GameCode/MainCam.cs @@ -0,0 +1,14 @@ +using UnityEngine; + +public class MainCam : MonoBehaviour +{ + public static MainCam instance; + + public Camera cam; + + private void Awake() + { + cam = GetComponent<Camera>(); + instance = this; + } +} diff --git a/GameCode/MainMenuHandler.cs b/GameCode/MainMenuHandler.cs new file mode 100644 index 0000000..2be5e82 --- /dev/null +++ b/GameCode/MainMenuHandler.cs @@ -0,0 +1,25 @@ +using UnityEngine; + +public class MainMenuHandler : MonoBehaviour +{ + public static MainMenuHandler instance; + + public bool isOpen = true; + + private void Awake() + { + instance = this; + } + + public void Close() + { + isOpen = false; + base.transform.GetChild(0).gameObject.SetActive(value: false); + } + + public void Open() + { + isOpen = true; + base.transform.GetChild(0).gameObject.SetActive(value: true); + } +} diff --git a/GameCode/Map.cs b/GameCode/Map.cs new file mode 100644 index 0000000..c5a6c94 --- /dev/null +++ b/GameCode/Map.cs @@ -0,0 +1,137 @@ +using System; +using System.Collections; +using Photon.Pun; +using UnityEngine; + +public class Map : MonoBehaviour +{ + public bool wasSpawned; + + public float size = 15f; + + public bool hasEntered; + + internal int levelID; + + internal int missingObjects; + + private float counter; + + private int readyForFrames; + + private bool hasCalledReady; + + public Rigidbody2D[] allRigs; + + private SpawnPoint[] spawnPoints; + + public Action mapIsReadyAction; + + public Action mapIsReadyEarlyAction; + + public Action mapMovingOutAction; + + internal bool hasRope; + + internal bool LoadedForAll() + { + return MapManager.instance.otherPlayersMostRecentlyLoadedLevel == levelID; + } + + private void Awake() + { + if (!GameManager.instance || !GameManager.instance.isPlaying) + { + GM_Test componentInChildren = GameManager.instance.transform.root.GetComponentInChildren<GM_Test>(includeInactive: true); + componentInChildren.gameObject.SetActive(value: true); + componentInChildren.testMap = true; + MapManager.instance.isTestingMap = true; + componentInChildren.transform.root.Find("UI/UI_MainMenu").gameObject.SetActive(value: false); + hasEntered = true; + } + } + + private void Update() + { + counter += Time.deltaTime; + if (!hasCalledReady && ((PhotonNetwork.OfflineMode && counter > 1f && hasEntered) || (hasEntered && LoadedForAll()))) + { + if (missingObjects <= 0) + { + readyForFrames++; + } + if (readyForFrames > 2) + { + StartCoroutine(StartMatch()); + } + } + } + + public void MapMoveOut() + { + mapMovingOutAction?.Invoke(); + } + + internal Vector3 GetRandomSpawnPos() + { + if (spawnPoints == null) + { + spawnPoints = GetComponentsInChildren<SpawnPoint>(); + } + return spawnPoints[UnityEngine.Random.Range(0, spawnPoints.Length)].transform.position; + } + + private IEnumerator StartMatch() + { + hasCalledReady = true; + mapIsReadyEarlyAction?.Invoke(); + yield return new WaitForSecondsRealtime(0f); + allRigs = GetComponentsInChildren<Rigidbody2D>(); + mapIsReadyAction?.Invoke(); + } + + private void Start() + { + if (!PhotonNetwork.OfflineMode) + { + MapManager.instance.ReportMapLoaded(levelID); + } + if (MapManager.instance.isTestingMap) + { + wasSpawned = true; + } + if (!wasSpawned) + { + MapManager.instance.UnloadScene(base.gameObject.scene); + } + SpriteRenderer[] componentsInChildren = GetComponentsInChildren<SpriteRenderer>(includeInactive: true); + for (int i = 0; i < componentsInChildren.Length; i++) + { + if ((double)componentsInChildren[i].color.a < 0.5) + { + continue; + } + componentsInChildren[i].transform.position = new Vector3(componentsInChildren[i].transform.position.x, componentsInChildren[i].transform.position.y, -3f); + if (!(componentsInChildren[i].gameObject.tag == "NoMask")) + { + componentsInChildren[i].color = new Color(11f / 51f, 11f / 51f, 11f / 51f); + if (!componentsInChildren[i].GetComponent<SpriteMask>()) + { + componentsInChildren[i].gameObject.AddComponent<SpriteMask>().sprite = componentsInChildren[i].sprite; + } + } + } + SpriteMask[] componentsInChildren2 = GetComponentsInChildren<SpriteMask>(); + for (int j = 0; j < componentsInChildren2.Length; j++) + { + if (!(componentsInChildren2[j].gameObject.tag == "NoMask")) + { + componentsInChildren2[j].isCustomRangeActive = true; + componentsInChildren2[j].frontSortingLayerID = SortingLayer.NameToID("MapParticle"); + componentsInChildren2[j].frontSortingOrder = 1; + componentsInChildren2[j].backSortingLayerID = SortingLayer.NameToID("MapParticle"); + componentsInChildren2[j].backSortingOrder = 0; + } + } + } +} diff --git a/GameCode/MapManager.cs b/GameCode/MapManager.cs new file mode 100644 index 0000000..ace02f0 --- /dev/null +++ b/GameCode/MapManager.cs @@ -0,0 +1,200 @@ +using System.Collections; +using Photon.Pun; +using UnityEngine; +using UnityEngine.SceneManagement; + +public class MapManager : MonoBehaviour +{ + [SerializeField] + public string[] levels; + + public int currentLevelID; + + public static MapManager instance; + + [HideInInspector] + public bool isTestingMap; + + public MapWrapper currentMap; + + private PhotonView view; + + internal int otherPlayersMostRecentlyLoadedLevel = -1; + + public string forceMap = ""; + + private bool callInNextMap; + + private void Awake() + { + instance = this; + view = GetComponent<PhotonView>(); + } + + internal void ReportMapLoaded(int levelID) + { + view.RPC("RPCA_ReportMapLoaded", RpcTarget.Others, levelID); + } + + [PunRPC] + internal void RPCA_ReportMapLoaded(int levelID) + { + otherPlayersMostRecentlyLoadedLevel = levelID; + } + + private string GetRandomMap() + { + if (forceMap != "") + { + return forceMap; + } + int num = Random.Range(0, levels.Length); + while (num == currentLevelID && levels.Length > 1) + { + num = Random.Range(0, levels.Length); + } + return levels[num]; + } + + public void LoadNextLevel(bool callInImidetly = false, bool forceLoad = false) + { + if (forceLoad || PhotonNetwork.IsMasterClient || PhotonNetwork.OfflineMode) + { + view.RPC("RPCA_SetCallInNextMap", RpcTarget.All, callInImidetly); + view.RPC("RPCA_LoadLevel", RpcTarget.All, GetRandomMap()); + } + } + + [PunRPC] + private void RPCA_SetCallInNextMap(bool toSet) + { + callInNextMap = toSet; + } + + public void LoadLevelFromID(int ID, bool onlyMaster = false, bool callInImidetly = false) + { + if (!(!PhotonNetwork.IsMasterClient && onlyMaster)) + { + callInNextMap = callInImidetly; + RPCA_LoadLevel(levels[ID]); + } + } + + [PunRPC] + public void RPCA_CallInNewMapAndMovePlayers(int mapID) + { + StartCoroutine(WaitForMapToBeLoaded(mapID)); + } + + private IEnumerator WaitForMapToBeLoaded(int mapID) + { + while (currentLevelID != mapID) + { + yield return null; + } + Debug.Log("CALL IN NEW MAP AND MOVE PLAYERS"); + if (currentMap != null) + { + MapTransition.instance.Enter(currentMap.Map); + } + MapTransition.instance.ClearObjects(); + PlayerManager.instance.RPCA_MovePlayers(); + } + + public void CallInNewMapAndMovePlayers(int mapID) + { + if (PhotonNetwork.IsMasterClient || PhotonNetwork.OfflineMode) + { + view.RPC("RPCA_CallInNewMapAndMovePlayers", RpcTarget.All, mapID); + } + } + + [PunRPC] + public void RPCA_CallInNewMap() + { + if (currentMap != null) + { + MapTransition.instance.Enter(currentMap.Map); + } + MapTransition.instance.ClearObjects(); + } + + public void CallInNewMap() + { + if (PhotonNetwork.IsMasterClient || PhotonNetwork.OfflineMode) + { + view.RPC("RPCA_CallInNewMap", RpcTarget.All); + } + } + + public SpawnPoint[] GetSpawnPoints() + { + return currentMap.Map.GetComponentsInChildren<SpawnPoint>(); + } + + private void OnLevelFinishedLoading(Scene scene, LoadSceneMode mode) + { + Map map = null; + for (int i = 0; i < scene.GetRootGameObjects().Length; i++) + { + map = scene.GetRootGameObjects()[i].GetComponent<Map>(); + if ((bool)map) + { + break; + } + } + if (!map) + { + Debug.LogError("NO MAP WAS FOUND WHEN LOADING NEW MAP"); + } + map.wasSpawned = true; + SceneManager.sceneLoaded -= OnLevelFinishedLoading; + if (currentMap != null) + { + StartCoroutine(UnloadAfterSeconds(currentMap.Scene)); + MapTransition.instance.Exit(currentMap.Map); + } + MapTransition.instance.SetStartPos(map); + map.levelID = currentLevelID; + currentMap = new MapWrapper(map, scene); + currentLevelID = GetIDFromScene(scene); + if (callInNextMap) + { + CallInNewMap(); + callInNextMap = false; + } + Debug.Log("FINISHED LOADING SCENE"); + } + + private int GetIDFromScene(Scene scene) + { + int result = -1; + for (int i = 0; i < levels.Length; i++) + { + if (levels[i] == scene.name) + { + result = i; + } + } + return result; + } + + [PunRPC] + public void RPCA_LoadLevel(string sceneName) + { + Debug.Log("LOADING SCENE"); + SceneManager.LoadScene(sceneName, LoadSceneMode.Additive); + SceneManager.sceneLoaded += OnLevelFinishedLoading; + } + + private IEnumerator UnloadAfterSeconds(Scene scene) + { + yield return new WaitForSecondsRealtime(2f); + SceneManager.UnloadSceneAsync(scene); + } + + public void UnloadScene(Scene scene) + { + SceneManager.UnloadSceneAsync(scene); + } +} diff --git a/GameCode/MapObjet_Rope.cs b/GameCode/MapObjet_Rope.cs new file mode 100644 index 0000000..463a1ec --- /dev/null +++ b/GameCode/MapObjet_Rope.cs @@ -0,0 +1,274 @@ +using System; +using System.Collections; +using Sonigon; +using UnityEngine; + +public class MapObjet_Rope : MonoBehaviour +{ + public enum JointType + { + spring, + Distance + } + + [Header("Sound")] + public bool soundRopePlay; + + public SoundEvent soundRopeLoop; + + private SoundParameterIntensity soundParameterIntensity = new SoundParameterIntensity(0f, UpdateMode.Continuous); + + private bool soundIsPlaying; + + private bool soundInitialized; + + private float soundRopeLengthCurrent; + + private float soundRopeLengthLast; + + private float soundRopeLengthVelocity; + + [Header("Settings")] + public JointType jointType; + + private Map map; + + private LineRenderer lineRenderer; + + private AnchoredJoint2D joint; + + private Vector3 lastPos; + + private Vector3 vel1; + + private Vector3 vel2; + + private Vector3 postSnapPos1; + + private Vector3 postSnapPos2; + + private float sinceBreak; + + private void Start() + { + map = GetComponentInParent<Map>(); + map.hasRope = true; + lineRenderer = GetComponent<LineRenderer>(); + Map obj = map; + obj.mapIsReadyAction = (Action)Delegate.Combine(obj.mapIsReadyAction, new Action(Go)); + Map obj2 = map; + obj2.mapMovingOutAction = (Action)Delegate.Combine(obj2.mapMovingOutAction, new Action(Leave)); + } + + private void Leave() + { + if ((bool)joint) + { + UnityEngine.Object.Destroy(joint); + } + } + + public void Go() + { + StartCoroutine(IGo()); + } + + private IEnumerator IGo() + { + yield return new WaitForSeconds(0f); + Rigidbody2D rigidbody2D = null; + Rigidbody2D rigidbody2D2 = null; + for (int i = 0; i < map.allRigs.Length; i++) + { + Collider2D component = map.allRigs[i].GetComponent<Collider2D>(); + if ((bool)component) + { + if (component.OverlapPoint(base.transform.position)) + { + rigidbody2D = map.allRigs[i]; + } + if (component.OverlapPoint(base.transform.GetChild(0).position)) + { + rigidbody2D2 = map.allRigs[i]; + } + } + } + if ((bool)rigidbody2D) + { + AddJoint(rigidbody2D); + if ((bool)rigidbody2D2) + { + joint.connectedBody = rigidbody2D2; + joint.anchor = rigidbody2D.transform.InverseTransformPoint(base.transform.position); + joint.connectedAnchor = rigidbody2D2.transform.InverseTransformPoint(base.transform.GetChild(0).position); + } + else + { + joint.anchor = rigidbody2D.transform.InverseTransformPoint(base.transform.position); + joint.connectedAnchor = base.transform.GetChild(0).position; + } + joint.enableCollision = true; + } + else if ((bool)rigidbody2D2) + { + AddJoint(rigidbody2D2); + joint.anchor = rigidbody2D2.transform.InverseTransformPoint(base.transform.GetChild(0).position); + joint.connectedAnchor = base.transform.position; + joint.enableCollision = true; + } + else + { + UnityEngine.Object.Destroy(base.gameObject); + } + } + + private void AddJoint(Rigidbody2D target) + { + switch (jointType) + { + case JointType.spring: + joint = target.gameObject.AddComponent<SpringJoint2D>(); + break; + case JointType.Distance: + joint = target.gameObject.AddComponent<DistanceJoint2D>(); + break; + } + } + + private void OnDrawGizmos() + { + if (!joint) + { + if (!lineRenderer) + { + lineRenderer = GetComponent<LineRenderer>(); + } + lineRenderer.SetPosition(0, base.transform.position); + lineRenderer.SetPosition(1, base.transform.GetChild(0).position); + if (Event.current.shift) + { + base.transform.GetChild(0).position = lastPos; + } + lastPos = base.transform.GetChild(0).position; + } + } + + private void OnDestroy() + { + soundIsPlaying = false; + soundInitialized = false; + SoundManager.Instance.StopAtPosition(soundRopeLoop, base.transform); + } + + private void OnDisable() + { + soundIsPlaying = false; + soundInitialized = false; + SoundManager.Instance.StopAtPosition(soundRopeLoop, base.transform); + } + + private void Update() + { + if ((bool)joint) + { + if ((bool)joint.attachedRigidbody && !joint.attachedRigidbody.gameObject.activeSelf) + { + postSnapPos1 = lineRenderer.GetPosition(0); + } + if ((bool)joint.connectedBody && !joint.connectedBody.gameObject.activeSelf) + { + postSnapPos2 = lineRenderer.GetPosition(1); + } + if (((bool)joint.attachedRigidbody && !joint.attachedRigidbody.gameObject.activeSelf) || ((bool)joint.connectedBody && !joint.connectedBody.gameObject.activeSelf)) + { + sinceBreak += Time.deltaTime; + if (Vector2.Distance(lineRenderer.GetPosition(0), lineRenderer.GetPosition(1)) < 0.2f) + { + if (soundIsPlaying) + { + SoundManager.Instance.StopAtPosition(soundRopeLoop, base.transform); + } + lineRenderer.enabled = false; + return; + } + } + if ((bool)joint.attachedRigidbody && joint.attachedRigidbody.gameObject.activeSelf) + { + vel1 = joint.attachedRigidbody.velocity * 1.5f; + } + if ((bool)joint.attachedRigidbody && !joint.attachedRigidbody.gameObject.activeSelf) + { + vel1 = FRILerp.Lerp(vel1, (lineRenderer.GetPosition(1) - lineRenderer.GetPosition(0)) * 15f * Mathf.Clamp(sinceBreak * 2f, 0f, 1f), 10f); + postSnapPos1 += vel1 * Time.deltaTime; + } + if (postSnapPos1 == Vector3.zero) + { + lineRenderer.SetPosition(0, joint.attachedRigidbody.transform.TransformPoint(joint.anchor)); + } + else + { + lineRenderer.SetPosition(0, postSnapPos1); + } + if ((bool)joint.connectedBody) + { + if (!joint.connectedBody.gameObject.activeSelf) + { + vel2 = FRILerp.Lerp(vel2, (lineRenderer.GetPosition(0) - lineRenderer.GetPosition(1)) * 15f * Mathf.Clamp(sinceBreak * 2f, 0f, 1f), 10f); + postSnapPos2 += vel2 * Time.deltaTime; + } + else + { + vel2 = joint.connectedBody.velocity * 1.5f; + } + if (postSnapPos2 == Vector3.zero) + { + lineRenderer.SetPosition(1, joint.connectedBody.transform.TransformPoint(joint.connectedAnchor)); + } + else + { + lineRenderer.SetPosition(1, postSnapPos2); + } + } + else if (postSnapPos2 == Vector3.zero) + { + lineRenderer.SetPosition(1, joint.connectedAnchor); + } + else + { + lineRenderer.SetPosition(1, postSnapPos2); + } + } + else + { + lineRenderer.SetPosition(0, Vector3.up * 200f); + lineRenderer.SetPosition(1, Vector3.up * 200f); + } + if (!soundRopePlay || lineRenderer.positionCount < 1) + { + return; + } + if (!soundInitialized) + { + soundInitialized = true; + soundRopeLengthLast = Vector3.Distance(lineRenderer.GetPosition(0), lineRenderer.GetPosition(1)); + } + soundRopeLengthCurrent = Vector3.Distance(lineRenderer.GetPosition(0), lineRenderer.GetPosition(1)); + soundRopeLengthVelocity = Mathf.Abs(soundRopeLengthLast - soundRopeLengthCurrent); + soundParameterIntensity.intensity = soundRopeLengthVelocity; + if (soundRopeLengthVelocity > 0.03f) + { + if (!soundIsPlaying) + { + soundIsPlaying = true; + SoundManager.Instance.PlayAtPosition(soundRopeLoop, SoundManager.Instance.transform, base.transform, soundParameterIntensity); + } + } + else if (soundIsPlaying) + { + soundIsPlaying = false; + soundInitialized = false; + SoundManager.Instance.StopAtPosition(soundRopeLoop, base.transform); + } + soundRopeLengthLast = Vector3.Distance(lineRenderer.GetPosition(0), lineRenderer.GetPosition(1)); + } +} diff --git a/GameCode/MapTransition.cs b/GameCode/MapTransition.cs new file mode 100644 index 0000000..bb238da --- /dev/null +++ b/GameCode/MapTransition.cs @@ -0,0 +1,145 @@ +using System.Collections; +using SoundImplementation; +using UnityEngine; +using UnityEngine.Events; + +public class MapTransition : MonoBehaviour +{ + [Header("Settings")] + public UnityEvent switchMapEvent; + + public AnimationCurve curve; + + public AnimationCurve gravityCurve; + + public static MapTransition instance; + + private const float mapPadding = 90f; + + public static bool isTransitioning; + + private void Awake() + { + instance = this; + } + + private void Start() + { + } + + public void SetStartPos(Map map) + { + map.transform.position = Vector3.right * 90f; + } + + public void Enter(Map map) + { + MoveObject(map.gameObject, Vector3.zero); + StartCoroutine(DelayEvent(0.1f)); + SoundPlayerStatic.Instance.PlayLevelTransitionIn(); + SoundMusicManager.Instance.PlayIngame(isCard: false); + } + + public void Exit(Map map) + { + SoundPlayerStatic.Instance.PlayLevelTransitionOut(); + map.MapMoveOut(); + MoveObject(map.gameObject, Vector3.right * -90f); + StartCoroutine(ClearObjectsAfterSeconds(1f)); + } + + private void MoveObject(GameObject target, Vector3 targetPos) + { + for (int i = 0; i < target.transform.childCount; i++) + { + Toggle(target.transform.GetChild(i).gameObject, enabled: false); + StartCoroutine(Move(target.transform.GetChild(i).gameObject, targetPos - target.transform.position, (i == 0) ? target.GetComponent<Map>() : null)); + } + } + + private void Toggle(GameObject obj, bool enabled) + { + Rigidbody2D component = obj.GetComponent<Rigidbody2D>(); + if ((bool)component) + { + component.simulated = enabled; + if (enabled) + { + StartCoroutine(LerpDrag(component)); + } + } + Collider2D component2 = obj.GetComponent<Collider2D>(); + if ((bool)component2) + { + component2.enabled = enabled; + } + CodeAnimation component3 = obj.GetComponent<CodeAnimation>(); + if ((bool)component3) + { + component3.enabled = enabled; + } + } + + private IEnumerator DelayEvent(float delay) + { + yield return new WaitForSecondsRealtime(delay); + switchMapEvent.Invoke(); + } + + private IEnumerator Move(GameObject target, Vector3 distance, Map targetMap = null) + { + isTransitioning = true; + float maxRandomDelay = 0.25f; + float randomDelay = Random.Range(0f, maxRandomDelay); + yield return new WaitForSecondsRealtime(randomDelay); + Vector3 targetStartPos = target.transform.position; + float t = curve.keys[curve.keys.Length - 1].time; + float c = 0f; + while (c < t) + { + c += Time.unscaledDeltaTime; + target.transform.position = targetStartPos + distance * curve.Evaluate(c); + yield return null; + } + target.transform.position = targetStartPos + distance; + Toggle(target, enabled: true); + yield return new WaitForSecondsRealtime(maxRandomDelay - randomDelay); + isTransitioning = false; + if ((bool)targetMap) + { + targetMap.hasEntered = true; + } + } + + private IEnumerator LerpDrag(Rigidbody2D target) + { + target.gravityScale = 0f; + float t = gravityCurve.keys[gravityCurve.keys.Length - 1].time; + float c = 0f; + while (c < t && (bool)target) + { + target.gravityScale = gravityCurve.Evaluate(c); + c += Time.unscaledDeltaTime; + yield return null; + } + if ((bool)target) + { + target.gravityScale = 1f; + } + } + + private IEnumerator ClearObjectsAfterSeconds(float time) + { + yield return new WaitForSecondsRealtime(time); + ClearObjects(); + } + + public void ClearObjects() + { + RemoveAfterSeconds[] array = Object.FindObjectsOfType<RemoveAfterSeconds>(); + for (int i = 0; i < array.Length; i++) + { + Object.Destroy(array[i].gameObject); + } + } +} diff --git a/GameCode/MapWrapper.cs b/GameCode/MapWrapper.cs new file mode 100644 index 0000000..9a6fe7d --- /dev/null +++ b/GameCode/MapWrapper.cs @@ -0,0 +1,14 @@ +using UnityEngine.SceneManagement; + +public class MapWrapper +{ + public Map Map { get; private set; } + + public Scene Scene { get; private set; } + + public MapWrapper(Map map, Scene scene) + { + Map = map; + Scene = scene; + } +} diff --git a/GameCode/MenuControllerEvent.cs b/GameCode/MenuControllerEvent.cs new file mode 100644 index 0000000..edd60c6 --- /dev/null +++ b/GameCode/MenuControllerEvent.cs @@ -0,0 +1,12 @@ +using UnityEngine; + +public class MenuControllerEvent : MonoBehaviour +{ + private void Start() + { + } + + private void Update() + { + } +} diff --git a/GameCode/MenuControllerHandler.cs b/GameCode/MenuControllerHandler.cs new file mode 100644 index 0000000..4f399bd --- /dev/null +++ b/GameCode/MenuControllerHandler.cs @@ -0,0 +1,75 @@ +using System; +using InControl; +using UnityEngine; +using UnityEngine.EventSystems; + +public class MenuControllerHandler : MonoBehaviour +{ + public enum MenuControl + { + Controller, + Mouse, + Unassigned + } + + public static MenuControl menuControl; + + public MenuControl lastMenuControl; + + public Action<MenuControl> switchControlAction; + + public static MenuControllerHandler instance; + + private void Awake() + { + instance = this; + } + + private void Start() + { + Switch(); + } + + private void Update() + { + if (Input.GetKeyDown(KeyCode.Mouse0)) + { + menuControl = MenuControl.Mouse; + } + if (Input.GetKeyDown(KeyCode.Mouse1)) + { + menuControl = MenuControl.Mouse; + } + for (int i = 0; i < InputManager.ActiveDevices.Count; i++) + { + InputDevice inputDevice = InputManager.ActiveDevices[i]; + if (!inputDevice.AnyButtonWasPressed && !(Mathf.Abs(inputDevice.LeftStick.Value.y) > 0.1f)) + { + continue; + } + menuControl = MenuControl.Controller; + if (EventSystem.current.currentSelectedGameObject.activeInHierarchy) + { + continue; + } + ListMenuButton[] array = UnityEngine.Object.FindObjectsOfType<ListMenuButton>(); + for (int j = 0; j < array.Length; j++) + { + if (array[j].enabled) + { + ListMenu.instance.SelectButton(array[j]); + } + } + } + if (menuControl != lastMenuControl) + { + Switch(); + } + lastMenuControl = menuControl; + } + + private void Switch() + { + switchControlAction?.Invoke(menuControl); + } +} diff --git a/GameCode/MenuControllerToggler.cs b/GameCode/MenuControllerToggler.cs new file mode 100644 index 0000000..465cf16 --- /dev/null +++ b/GameCode/MenuControllerToggler.cs @@ -0,0 +1,75 @@ +using System; +using UnityEngine; + +public class MenuControllerToggler : MonoBehaviour +{ + public bool creatorControl; + + public GameObject controllerObject; + + public GameObject keyboardObject; + + private CharacterCreator creator; + + private void Awake() + { + CharacterCreator componentInParent = GetComponentInParent<CharacterCreator>(); + if (componentInParent.playerActions == null) + { + if (creatorControl) + { + componentInParent.SwitchAction = (Action<MenuControllerHandler.MenuControl>)Delegate.Combine(componentInParent.SwitchAction, new Action<MenuControllerHandler.MenuControl>(Switch)); + Switch(GetComponentInParent<CharacterCreator>().currentControl); + } + else + { + MenuControllerHandler instance = MenuControllerHandler.instance; + instance.switchControlAction = (Action<MenuControllerHandler.MenuControl>)Delegate.Combine(instance.switchControlAction, new Action<MenuControllerHandler.MenuControl>(Switch)); + Switch(MenuControllerHandler.menuControl); + } + } + } + + private void OnEnable() + { + CharacterCreator componentInParent = GetComponentInParent<CharacterCreator>(); + if (componentInParent.playerActions != null) + { + componentInParent.SwitchAction = (Action<MenuControllerHandler.MenuControl>)Delegate.Combine(componentInParent.SwitchAction, new Action<MenuControllerHandler.MenuControl>(Switch)); + if (componentInParent.inputType == GeneralInput.InputType.Controller) + { + Switch(MenuControllerHandler.MenuControl.Controller); + } + if (componentInParent.inputType == GeneralInput.InputType.Keyboard) + { + Switch(MenuControllerHandler.MenuControl.Mouse); + } + } + } + + private void Switch(MenuControllerHandler.MenuControl control) + { + if (control == MenuControllerHandler.MenuControl.Controller) + { + if ((bool)controllerObject) + { + controllerObject.SetActive(value: true); + } + if ((bool)keyboardObject) + { + keyboardObject.SetActive(value: false); + } + } + else + { + if ((bool)controllerObject) + { + controllerObject.SetActive(value: false); + } + if ((bool)keyboardObject) + { + keyboardObject.SetActive(value: true); + } + } + } +} diff --git a/GameCode/MenuEffects.cs b/GameCode/MenuEffects.cs new file mode 100644 index 0000000..5345984 --- /dev/null +++ b/GameCode/MenuEffects.cs @@ -0,0 +1,51 @@ +using System.Collections; +using TMPro; +using UnityEngine; + +public class MenuEffects : MonoBehaviour +{ + public static MenuEffects instance; + + public Color nopeColor; + + private void Awake() + { + instance = this; + } + + public void ShakeObject(GameObject objectToShake, Vector3 defaultPos, float amount, float time) + { + StartCoroutine(DoShakeObject(objectToShake, defaultPos, amount, time)); + } + + private IEnumerator DoShakeObject(GameObject objectToShake, Vector3 defaultPos, float amount, float time) + { + float c = 0f; + while (c < time) + { + Vector3 localPosition = defaultPos + Random.onUnitSphere * amount * ((time - c) / time); + localPosition.z = defaultPos.z; + objectToShake.transform.localPosition = localPosition; + c += Time.unscaledDeltaTime; + yield return null; + } + objectToShake.transform.localPosition = defaultPos; + } + + public void BlinkInColor(TextMeshProUGUI textToBlink, Color blinkColor, Color defaultColor, float seconds) + { + StartCoroutine(DoTextColorBlink(textToBlink, blinkColor, defaultColor, seconds)); + } + + private IEnumerator DoTextColorBlink(TextMeshProUGUI textToBlink, Color blinkColor, Color defaultColor, float seconds) + { + float c = 0f; + while (c < seconds) + { + textToBlink.color = blinkColor; + c += Time.unscaledDeltaTime; + yield return null; + } + textToBlink.color = defaultColor; + } +} diff --git a/GameCode/MoveForward.cs b/GameCode/MoveForward.cs new file mode 100644 index 0000000..4171a26 --- /dev/null +++ b/GameCode/MoveForward.cs @@ -0,0 +1,11 @@ +using UnityEngine; + +public class MoveForward : MonoBehaviour +{ + public float amount = 3f; + + private void Start() + { + base.transform.position += Vector3.forward * amount; + } +} diff --git a/GameCode/MoveSequence.cs b/GameCode/MoveSequence.cs new file mode 100644 index 0000000..1437614 --- /dev/null +++ b/GameCode/MoveSequence.cs @@ -0,0 +1,99 @@ +using Photon.Pun; +using UnityEngine; + +public class MoveSequence : MonoBehaviour +{ + private int targetID; + + public Vector2[] positions; + + public float drag = 1f; + + public float spring = 1f; + + public float cap = 1f; + + public float threshold = 1f; + + public float timeAtPos; + + private float counter; + + private Vector2 startPos; + + private Vector2 velocity; + + private Rigidbody2D rig; + + private Map map; + + private string myKey; + + private void Start() + { + base.gameObject.layer = 17; + startPos = base.transform.localPosition; + rig = GetComponent<Rigidbody2D>(); + map = GetComponentInParent<Map>(); + myKey = "MapObect " + GetComponentInParent<Map>().levelID + " " + base.transform.GetSiblingIndex(); + MapManager.instance.GetComponent<ChildRPC>().childRPCsInt.Add(myKey, RPCA_SetTargetID); + } + + private void OnDestroy() + { + if ((bool)MapManager.instance) + { + MapManager.instance.GetComponent<ChildRPC>().childRPCsInt.Remove(myKey); + } + } + + private void OnDrawGizmos() + { + for (int i = 0; i < positions.Length; i++) + { + Gizmos.DrawSphere((Vector2)base.transform.position + positions[i], 0.25f + (float)i * 0.15f); + } + } + + private void Update() + { + if (MapTransition.isTransitioning || !map.hasEntered) + { + return; + } + Vector2 vector = positions[targetID] + startPos; + Vector2 vector2 = vector - (Vector2)base.transform.position; + vector2 = Vector3.ClampMagnitude(vector2, cap); + if ((bool)rig) + { + rig.gravityScale = 0f; + rig.AddForce(vector2 * spring * CappedDeltaTime.time * rig.mass); + } + else + { + velocity += vector2 * spring * CappedDeltaTime.time; + velocity -= velocity * drag * CappedDeltaTime.time; + base.transform.position += (Vector3)velocity * TimeHandler.deltaTime; + } + if (!PhotonNetwork.IsMasterClient || !(Vector2.Distance(base.transform.position, vector) < threshold)) + { + return; + } + counter += TimeHandler.deltaTime; + if (counter > timeAtPos) + { + targetID++; + if (targetID >= positions.Length) + { + targetID = 0; + } + MapManager.instance.GetComponent<ChildRPC>().CallFunction(myKey, targetID); + counter = 0f; + } + } + + private void RPCA_SetTargetID(int setValue) + { + targetID = setValue; + } +} diff --git a/GameCode/MoveTransform.cs b/GameCode/MoveTransform.cs new file mode 100644 index 0000000..e6b8d0f --- /dev/null +++ b/GameCode/MoveTransform.cs @@ -0,0 +1,78 @@ +using UnityEngine; + +public class MoveTransform : MonoBehaviour +{ + public float gravity = 30f; + + public float drag; + + public float dragMinSpeed = 1f; + + public float velocitySpread; + + public float spread; + + public Vector3 localForce; + + public Vector3 worldForce; + + public float multiplier = 1f; + + public Vector3 velocity; + + [HideInInspector] + public float distanceTravelled; + + [HideInInspector] + public bool DontRunStart; + + public float selectedSpread; + + public bool allowStop; + + public int simulateGravity; + + private int randomSeed; + + [HideInInspector] + internal float simulationSpeed = 1f; + + private void Start() + { + if (!DontRunStart) + { + velocity += base.transform.TransformDirection(localForce) + worldForce; + base.transform.rotation = Quaternion.LookRotation(velocity, Vector3.forward); + if (spread != 0f) + { + velocity += base.transform.up * selectedSpread; + } + } + } + + private void Update() + { + float num = Mathf.Clamp(TimeHandler.deltaTime, 0f, 0.02f); + float deltaTime = TimeHandler.deltaTime; + num *= simulationSpeed; + deltaTime *= simulationSpeed; + if (simulateGravity == 0) + { + velocity += gravity * Vector3.down * deltaTime * multiplier; + } + if ((velocity.magnitude > 2f || allowStop) && velocity.magnitude > dragMinSpeed) + { + velocity -= velocity * Mathf.Clamp(drag * num * Mathf.Clamp(multiplier, 0f, 1f), 0f, 1f); + } + base.transform.position += velocity * deltaTime * multiplier; + distanceTravelled += velocity.magnitude * deltaTime * multiplier; + base.transform.rotation = Quaternion.LookRotation(velocity, Vector3.forward); + } + + public float GetUpwardsCompensation(Vector2 start, Vector2 end) + { + start.y = 0.5f; + end.y = 0.5f; + return Mathf.Pow(Vector3.Distance(start, end), 2.06f) * gravity / velocity.magnitude * 0.012f; + } +} diff --git a/GameCode/MoveTransformGravity.cs b/GameCode/MoveTransformGravity.cs new file mode 100644 index 0000000..fd822fe --- /dev/null +++ b/GameCode/MoveTransformGravity.cs @@ -0,0 +1,23 @@ +using UnityEngine; + +public class MoveTransformGravity : MonoBehaviour +{ + public float amount = 1f; + + public float pow = 1.5f; + + private MoveTransform move; + + private float counter; + + private void Start() + { + move = GetComponentInParent<MoveTransform>(); + } + + private void Update() + { + counter += TimeHandler.deltaTime; + move.velocity += Vector3.down * Mathf.Pow(amount * counter, pow); + } +} diff --git a/GameCode/Movement.cs b/GameCode/Movement.cs new file mode 100644 index 0000000..17d7b11 --- /dev/null +++ b/GameCode/Movement.cs @@ -0,0 +1,137 @@ +using UnityEngine; + +public class Movement : MonoBehaviour +{ + public float jumpForce; + + public float force; + + public float torque; + + public float drag = 1f; + + public float Angulardrag = 1f; + + public ParticleSystem[] jumpPart; + + private GeneralInput input; + + private Rigidbody2D rig; + + private CharacterData data; + + private CharacterStatModifiers stats; + + public Vector2 knockBack; + + private HealthHandler health; + + private Vector3 moveDir; + + private Vector3 idleForce; + + private void Start() + { + rig = GetComponent<Rigidbody2D>(); + input = GetComponent<GeneralInput>(); + data = GetComponent<CharacterData>(); + stats = GetComponent<CharacterStatModifiers>(); + health = GetComponent<HealthHandler>(); + } + + private void FixedUpdate() + { + if (input.direction != Vector3.zero) + { + moveDir = input.direction; + idleForce = Vector3.Lerp(idleForce, moveDir, Time.fixedDeltaTime * 6f); + } + else if (data.isGrounded || data.isWallGrab) + { + idleForce = Vector3.Lerp(idleForce, Vector3.zero, 15f * Time.fixedDeltaTime); + } + else + { + idleForce = Vector3.Lerp(idleForce, Vector3.zero, 3f * Time.fixedDeltaTime); + } + if (input.direction == Vector3.zero) + { + moveDir = idleForce; + } + if (data.isGrounded || data.isWallGrab) + { + knockBack = Vector3.Lerp(knockBack, Vector3.zero, 10f * Time.fixedDeltaTime); + } + else + { + knockBack = Vector3.Lerp(knockBack, Vector3.zero, 7f * Time.fixedDeltaTime); + } + rig.AddForce(knockBack * 0.1f * rig.mass, ForceMode2D.Force); + if (moveDir.y > 0f) + { + moveDir.y = 0f; + } + rig.AddForce(-rig.velocity * 0.01f * drag * rig.mass, ForceMode2D.Force); + rig.AddTorque((0f - rig.angularVelocity) * 0.01f * Angulardrag * rig.mass, ForceMode2D.Force); + if (input.jumpIsPressed) + { + rig.AddForce(Vector2.up * 20f * rig.mass, ForceMode2D.Force); + } + rig.AddForce(moveDir * force * (1f - stats.GetSlow()) * rig.mass, ForceMode2D.Force); + } + + private void Update() + { + if (input.jumpWasPressed) + { + Jump(); + } + if (data.isGrounded && data.sinceJump > 0.2f) + { + data.currentJumps = data.jumps; + } + } + + private void Jump() + { + if (data.sinceJump < 0.15f) + { + return; + } + Vector3 vector = Vector3.up; + Vector3 vector2 = data.groundPos; + if (data.sinceGrounded < 0.1f) + { + if (data.sinceGrounded > 0.05f) + { + vector2 = base.transform.position; + } + data.currentJumps = data.jumps; + } + else if (data.sinceWallGrab < 0.1f) + { + vector = Vector2.up + data.wallNormal; + vector2 = data.wallPos; + data.currentJumps = data.jumps; + } + else + { + if (data.currentJumps <= 0) + { + return; + } + vector2 = base.transform.position; + } + data.currentJumps--; + rig.velocity = new Vector3(rig.velocity.x, 0f); + health.TakeForce(Vector2.up * jumpForce * 1f * (1f - stats.GetSlow()) * rig.mass); + data.sinceJump = 0f; + data.sinceGrounded = 0f; + for (int i = 0; i < jumpPart.Length; i++) + { + jumpPart[i].transform.position = new Vector3(vector2.x, vector2.y, 5f) - vector * 0f; + jumpPart[i].transform.rotation = Quaternion.LookRotation(rig.velocity); + jumpPart[i].Play(); + } + } +} diff --git a/GameCode/MultiOptions.cs b/GameCode/MultiOptions.cs new file mode 100644 index 0000000..82bb9e0 --- /dev/null +++ b/GameCode/MultiOptions.cs @@ -0,0 +1,168 @@ +using System.Collections; +using System.Collections.Generic; +using TMPro; +using UnityEngine; + +public class MultiOptions : MonoBehaviour +{ + private GameObject source; + + private OptionsButton targetButton; + + private void Start() + { + } + + private void Update() + { + if (Input.GetKeyUp(KeyCode.Mouse0) || Input.GetKeyDown(KeyCode.Escape)) + { + Close(); + } + } + + internal void ClickRessButton(MultiOptionsButton buttonPressed) + { + targetButton.SetResolutionAndFullscreen(buttonPressed.currentRess, buttonPressed.currentFull); + Close(); + } + + public void Open(OptionsButton.SettingsTarget settingsTarget, Vector3 pos, OptionsButton askingButton) + { + targetButton = askingButton; + base.transform.position = pos; + source = base.transform.GetChild(0).gameObject; + if (settingsTarget == OptionsButton.SettingsTarget.Resolution) + { + PopulateRess(Screen.resolutions); + } + else + { + PopulateFullScreens(new Optionshandler.FullScreenOption[3] + { + Optionshandler.FullScreenOption.FullScreen, + Optionshandler.FullScreenOption.WindowedFullScreen, + Optionshandler.FullScreenOption.Windowed + }); + } + base.gameObject.SetActive(value: true); + ListMenuButton[] componentsInChildren = base.transform.parent.GetComponentsInChildren<ListMenuButton>(); + for (int i = 0; i < componentsInChildren.Length; i++) + { + if (componentsInChildren[i].transform.parent != base.transform) + { + componentsInChildren[i].enabled = false; + } + } + CanvasGroup[] componentsInChildren2 = base.transform.parent.GetComponentsInChildren<CanvasGroup>(); + for (int j = 0; j < componentsInChildren2.Length; j++) + { + componentsInChildren2[j].alpha = 0.05f; + componentsInChildren2[j].interactable = false; + } + if (MenuControllerHandler.menuControl == MenuControllerHandler.MenuControl.Controller) + { + StartCoroutine(WaitFrame()); + } + else + { + ListMenu.instance.ClearBar(); + } + } + + private IEnumerator WaitFrame() + { + yield return new WaitForSecondsRealtime(0f); + ListMenu.instance.SelectButton(GetComponentInChildren<ListMenuButton>()); + } + + public void Close() + { + base.gameObject.SetActive(value: false); + ListMenuButton[] componentsInChildren = base.transform.parent.GetComponentsInChildren<ListMenuButton>(); + for (int i = 0; i < componentsInChildren.Length; i++) + { + if (componentsInChildren[i].transform.parent != base.transform) + { + componentsInChildren[i].enabled = true; + } + } + CanvasGroup[] componentsInChildren2 = base.transform.parent.GetComponentsInChildren<CanvasGroup>(); + for (int j = 0; j < componentsInChildren2.Length; j++) + { + componentsInChildren2[j].alpha = 1f; + componentsInChildren2[j].interactable = true; + } + if (MenuControllerHandler.menuControl == MenuControllerHandler.MenuControl.Controller) + { + ListMenu.instance.SelectButton(targetButton.transform.GetComponent<ListMenuButton>()); + } + else + { + ListMenu.instance.ClearBar(); + } + } + + private void PopulateRess(Resolution[] allRess) + { + for (int num = base.transform.childCount - 1; num > 0; num--) + { + Object.Destroy(base.transform.GetChild(num).gameObject); + } + allRess = GetBestResolutions(); + for (int i = 0; i < allRess.Length; i++) + { + GameObject obj = Object.Instantiate(source, source.transform.position, source.transform.rotation, source.transform.parent); + obj.GetComponentInChildren<TextMeshProUGUI>().text = allRess[i].width + " x " + allRess[i].height; + obj.GetComponent<MultiOptionsButton>().currentRess = allRess[i]; + obj.gameObject.SetActive(value: true); + } + } + + private Resolution[] GetBestResolutions() + { + List<Resolution> list = new List<Resolution>(); + for (int i = 0; i < Screen.resolutions.Length; i++) + { + if (IsBestRess(Screen.resolutions[i])) + { + list.Add(Screen.resolutions[i]); + } + } + return list.ToArray(); + } + + private bool IsBestRess(Resolution newRess) + { + for (int i = 0; i < Screen.resolutions.Length; i++) + { + if (Screen.resolutions[i].width == newRess.width && Screen.resolutions[i].height == newRess.height && newRess.refreshRate < Screen.resolutions[i].refreshRate) + { + return false; + } + } + return true; + } + + private void PopulateFullScreens(Optionshandler.FullScreenOption[] allScreens) + { + for (int num = base.transform.childCount - 1; num > 0; num--) + { + Object.Destroy(base.transform.GetChild(num).gameObject); + } + for (int i = 0; i < allScreens.Length; i++) + { + GameObject gameObject = Object.Instantiate(source, source.transform.position, source.transform.rotation, source.transform.parent); + if (allScreens[i] == Optionshandler.FullScreenOption.WindowedFullScreen) + { + gameObject.GetComponentInChildren<TextMeshProUGUI>().text = "WINDOWED FULLSCREEN"; + } + else + { + gameObject.GetComponentInChildren<TextMeshProUGUI>().text = allScreens[i].ToString().ToUpper(); + } + gameObject.GetComponent<MultiOptionsButton>().currentFull = allScreens[i]; + gameObject.gameObject.SetActive(value: true); + } + } +} diff --git a/GameCode/MultiOptionsButton.cs b/GameCode/MultiOptionsButton.cs new file mode 100644 index 0000000..7b8bf79 --- /dev/null +++ b/GameCode/MultiOptionsButton.cs @@ -0,0 +1,13 @@ +using UnityEngine; + +public class MultiOptionsButton : MonoBehaviour +{ + public Resolution currentRess; + + public Optionshandler.FullScreenOption currentFull; + + public void Click() + { + GetComponentInParent<MultiOptions>().ClickRessButton(this); + } +} diff --git a/GameCode/MusicGridVisualizer.cs b/GameCode/MusicGridVisualizer.cs new file mode 100644 index 0000000..c7fc064 --- /dev/null +++ b/GameCode/MusicGridVisualizer.cs @@ -0,0 +1,13 @@ +public class MusicGridVisualizer : GridVisualizer +{ + private void Update() + { + for (int i = 0; i < numberOfObjects.x; i++) + { + for (int j = 0; j < numberOfObjects.y; j++) + { + spawnedObjects[i, j].OnSetSize(MusicVisualizerData.Samples[i + j] * 200f); + } + } + } +} diff --git a/GameCode/MusicVisualizerData.cs b/GameCode/MusicVisualizerData.cs new file mode 100644 index 0000000..078940e --- /dev/null +++ b/GameCode/MusicVisualizerData.cs @@ -0,0 +1,18 @@ +using UnityEngine; + +public class MusicVisualizerData : MonoBehaviour +{ + public static float[] Samples = new float[512]; + + private AudioSource m_audioSource; + + private void Awake() + { + m_audioSource = GetComponent<AudioSource>(); + } + + private void Update() + { + m_audioSource.GetSpectrumData(Samples, 0, FFTWindow.Blackman); + } +} diff --git a/GameCode/NetworkConnectionHandler.cs b/GameCode/NetworkConnectionHandler.cs new file mode 100644 index 0000000..b55d8bc --- /dev/null +++ b/GameCode/NetworkConnectionHandler.cs @@ -0,0 +1,450 @@ +using System; +using System.Collections; +using ExitGames.Client.Photon; +using Landfall.Network; +using Photon.Pun; +using Photon.Realtime; +using SoundImplementation; +using Steamworks; +using UnityEngine; + +public class NetworkConnectionHandler : MonoBehaviourPunCallbacks +{ + public static readonly string TWITCH_PLAYER_SCORE_KEY = "TwitchScore"; + + public static readonly string TWITCH_ROOM_AUDIENCE_RATING_KEY = "C0"; + + public static NetworkConnectionHandler instance; + + private static ClientSteamLobby m_SteamLobby; + + private bool m_SearchingQuickMatch; + + private bool m_SearchingTwitch; + + private int currentViewers = 100; + + private TypedLobby sqlLobby = new TypedLobby("customSqlLobby", LobbyType.SqlLobby); + + public bool hasRegionSelect; + + private bool m_ForceRegion; + + private bool isConnectedToMaster; + + private float untilTryOtherRegionCounter; + + private void Start() + { + instance = this; + PhotonNetwork.ServerPortOverrides = PhotonPortDefinition.AlternativeUdpPorts; + PhotonNetwork.CrcCheckEnabled = true; + PhotonNetwork.NetworkingClient.LoadBalancingPeer.DisconnectTimeout = 30000; + if (m_SteamLobby == null) + { + m_SteamLobby = new ClientSteamLobby(); + } + else + { + m_SteamLobby.LeaveLobby(); + } + } + + private void Update() + { + if (m_SearchingQuickMatch && PhotonNetwork.InRoom && !PhotonNetwork.OfflineMode && !GM_ArmsRace.instance) + { + untilTryOtherRegionCounter -= Time.deltaTime; + if (untilTryOtherRegionCounter < 0f) + { + StartCoroutine(PlayOnBestActiveRegion()); + } + } + } + + public void QuickMatch() + { + m_SearchingQuickMatch = true; + m_SearchingTwitch = false; + TimeHandler.instance.gameStartTime = 1f; + LoadingScreen.instance?.StartLoading(); + StartCoroutine(DoActionWhenConnected(JoinRandomRoom)); + } + + public void TwitchJoin(int score) + { + currentViewers = Mathf.Clamp(score, 1, score); + m_SearchingQuickMatch = false; + m_SearchingTwitch = true; + ExitGames.Client.Photon.Hashtable customProperties = PhotonNetwork.LocalPlayer.CustomProperties; + if (customProperties.ContainsKey(TWITCH_PLAYER_SCORE_KEY)) + { + customProperties[TWITCH_PLAYER_SCORE_KEY] = score; + } + else + { + customProperties.Add(TWITCH_PLAYER_SCORE_KEY, score); + } + PhotonNetwork.LocalPlayer.SetCustomProperties(customProperties); + TimeHandler.instance.gameStartTime = 1f; + LoadingScreen.instance?.StartLoading(); + StartCoroutine(DoActionWhenConnected(JoinSpecificTWITCHRoom)); + } + + public void HostPrivateAndInviteFriend() + { + m_SearchingQuickMatch = false; + m_SearchingTwitch = false; + TimeHandler.instance.gameStartTime = 1f; + LoadingScreen.instance?.StartLoading(privateGame: true); + RoomOptions options = new RoomOptions(); + options.MaxPlayers = 2; + options.IsOpen = true; + options.IsVisible = false; + m_SteamLobby.ShowInviteScreenWhenConnected(); + StartCoroutine(DoActionWhenConnected(delegate + { + CreateRoom(options); + })); + } + + private void JoinRandomRoom() + { + Debug.Log("Joining random room"); + PhotonNetwork.JoinRandomRoom(); + } + + private void CreateSpecificTWITCHRoom() + { + Debug.Log("Creating SPECIFIC TWITCH ROOM!"); + RoomOptions roomOptions = new RoomOptions(); + roomOptions.CustomRoomProperties = new ExitGames.Client.Photon.Hashtable { { TWITCH_ROOM_AUDIENCE_RATING_KEY, currentViewers } }; + roomOptions.CustomRoomPropertiesForLobby = new string[1] { TWITCH_ROOM_AUDIENCE_RATING_KEY }; + PhotonNetwork.CreateRoom(null, roomOptions, sqlLobby); + } + + private void JoinSpecificTWITCHRoom() + { + Debug.Log("JOINING SPECIFIC TWITCH ROOM!"); + int num = 5; + int num2 = currentViewers * num; + int num3 = currentViewers / num; + int num4 = 10; + int num5 = currentViewers * num4; + int num6 = currentViewers / num4; + int num7 = 10000000; + int num8 = currentViewers * num7; + int num9 = currentViewers / num7; + string text = ""; + text = text + "C0 BETWEEN " + num3 + " AND " + num2 + ";"; + text = text + "C0 BETWEEN " + num6 + " AND " + num5 + ";"; + text = text + "C0 BETWEEN " + num9 + " AND " + num8; + PhotonNetwork.JoinRandomRoom(null, 0, MatchmakingMode.FillRoom, sqlLobby, text); + } + + public override void OnJoinRoomFailed(short returnCode, string message) + { + Debug.Log("JOINED RANDOM ROOM FAILED!"); + if (!m_SearchingTwitch) + { + JoinRandomRoom(); + } + else + { + CreateSpecificTWITCHRoom(); + } + } + + private IEnumerator DoActionWhenConnected(Action action) + { + yield return WaitForConnect(); + action(); + } + + private IEnumerator PlayOnBestActiveRegion() + { + if (PhotonNetwork.InRoom) + { + PhotonNetwork.LeaveRoom(); + while (PhotonNetwork.InRoom) + { + yield return null; + } + } + string[] regionsToTry = new string[13] + { + "usw", "eu", "us", "au", "ru", "za", "asia", "cae", "in", "jp", + "rue", "sa", "kr" + }; + float bestRegionScore = 0f; + string bestRegion = ""; + for (int i = 0; i < regionsToTry.Length; i++) + { + isConnectedToMaster = false; + PhotonNetwork.Disconnect(); + while (PhotonNetwork.IsConnected) + { + yield return null; + } + PhotonNetwork.ConnectToRegion(regionsToTry[i]); + Debug.Log("connectToRegion " + regionsToTry[i]); + isConnectedToMaster = false; + while (!isConnectedToMaster) + { + yield return null; + } + int countOfPlayersInRooms = PhotonNetwork.CountOfPlayersInRooms; + int ping = PhotonNetwork.GetPing(); + float num = (float)Mathf.Clamp(countOfPlayersInRooms, 0, 50) / Mathf.Clamp(ping, 10f, 1E+11f); + Debug.Log("Ping: " + Mathf.Clamp(PhotonNetwork.GetPing(), 10f, 1E+11f)); + Debug.Log(regionsToTry[i] + ": " + PhotonNetwork.CountOfPlayersInRooms); + if (num > bestRegionScore) + { + bestRegion = regionsToTry[i]; + bestRegionScore = num; + if (ping < 50 && countOfPlayersInRooms > 50) + { + break; + } + } + } + isConnectedToMaster = false; + PhotonNetwork.Disconnect(); + PhotonNetwork.LocalPlayer.NickName = "PlayerName"; + if (bestRegion == "") + { + PhotonNetwork.ConnectToBestCloudServer(); + } + else + { + Debug.Log("Connecting to " + bestRegion); + PhotonNetwork.ConnectToRegion(bestRegion); + } + while (!isConnectedToMaster) + { + yield return null; + } + JoinRandomRoom(); + } + + private IEnumerator WaitForConnect() + { + if (!PhotonNetwork.IsConnectedAndReady) + { + PhotonNetwork.LocalPlayer.NickName = "PlayerName"; + PhotonNetwork.ConnectUsingSettings(); + if (hasRegionSelect || m_ForceRegion) + { + PhotonNetwork.ConnectToRegion(RegionSelector.region); + } + else + { + PhotonNetwork.ConnectToBestCloudServer(); + } + } + while (!isConnectedToMaster) + { + Debug.Log("Trying to connect to photon"); + yield return null; + } + Debug.Log("Is connected"); + } + + public void ForceRegionJoin(string region, string room) + { + Debug.Log("CREEASDSSD"); + if (PhotonNetwork.InRoom) + { + PhotonNetwork.Disconnect(); + } + CharacterCreatorHandler.instance.CloseMenus(); + MainMenuHandler.instance.Close(); + RegionSelector.region = region; + TimeHandler.instance.gameStartTime = 1f; + LoadingScreen.instance?.StartLoading(); + m_ForceRegion = true; + StartCoroutine(DoActionWhenConnected(delegate + { + JoinSpecificRoom(room); + })); + } + + private void JoinSpecificRoom(string room) + { + PhotonNetwork.JoinRoom(room); + m_ForceRegion = false; + } + + public override void OnEnable() + { + base.OnEnable(); + Debug.Log("Add me!"); + PhotonNetwork.AddCallbackTarget(this); + } + + public override void OnDisable() + { + base.OnDisable(); + Debug.Log("Remove me!"); + PhotonNetwork.RemoveCallbackTarget(this); + } + + public override void OnConnectedToMaster() + { + isConnectedToMaster = true; + } + + public override void OnJoinRandomFailed(short returnCode, string message) + { + Debug.Log("JOINED RANDOM ROOM FAILED!"); + if (m_SearchingTwitch) + { + CreateSpecificTWITCHRoom(); + return; + } + RoomOptions roomOptions = new RoomOptions(); + roomOptions.MaxPlayers = 2; + roomOptions.IsOpen = true; + roomOptions.IsVisible = true; + if (!SteamManager.Initialized) + { + Debug.LogError("SteamManager is not initialized!"); + } + else + { + CreateRoom(roomOptions); + } + } + + private void CreateRoom(RoomOptions roomOptions) + { + m_SteamLobby.CreateLobby(roomOptions.MaxPlayers, delegate(string RoomName) + { + PhotonNetwork.CreateRoom(RoomName, roomOptions); + }); + } + + public override void OnJoinedRoom() + { + if (!PhotonNetwork.OfflineMode) + { + isConnectedToMaster = false; + Debug.Log("Room joined successfully"); + Debug.Log(PhotonNetwork.CloudRegion); + untilTryOtherRegionCounter = 15f; + PhotonNetwork.LocalPlayer.NickName = (m_SearchingTwitch ? TwitchUIHandler.TWITCH_NAME_KEY : SteamFriends.GetPersonaName()); + } + } + + public override void OnPlayerEnteredRoom(Photon.Realtime.Player newPlayer) + { + SoundPlayerStatic.Instance.PlayPlayerAdded(); + if (PhotonNetwork.PlayerList.Length == 2) + { + if (PhotonNetwork.IsMasterClient) + { + GetComponent<PhotonView>().RPC("RPCA_FoundGame", RpcTarget.All); + } + if (m_SteamLobby != null) + { + m_SteamLobby.HideLobby(); + } + } + Debug.Log("PlayerJoined"); + base.OnPlayerEnteredRoom(newPlayer); + } + + [PunRPC] + private void RPCA_FoundGame() + { + LoadingScreen.instance?.StopLoading(); + } + + public override void OnLeftRoom() + { + isConnectedToMaster = false; + } + + public override void OnPlayerLeftRoom(Photon.Realtime.Player otherPlayer) + { + _ = GM_ArmsRace.instance == null; + StartCoroutine(DoDisconnect("DISCONNECTED", "Other player left")); + base.OnPlayerLeftRoom(otherPlayer); + } + + public override void OnDisconnected(DisconnectCause cause) + { + if (cause != 0 && cause != DisconnectCause.DisconnectByClientLogic) + { + StartCoroutine(DoDisconnect("DISCONNECTED", cause.ToString())); + isConnectedToMaster = false; + } + } + + private IEnumerator DoRetry() + { + LoadingScreen.instance.StartLoading(); + if (PhotonNetwork.InRoom) + { + PhotonNetwork.LeaveRoom(); + while (PhotonNetwork.InRoom) + { + yield return null; + } + } + JoinRandomRoom(); + } + + private IEnumerator DoDisconnect(string context, string reason) + { + ErrorHandler.instance.ShowError(context, reason); + yield return new WaitForSecondsRealtime(2f); + ErrorHandler.instance.HideError(); + NetworkRestart(); + } + + public override void OnRegionListReceived(RegionHandler regionHandler) + { + Debug.Log(regionHandler); + } + + public void NetworkRestart() + { + isConnectedToMaster = false; + if (PhotonNetwork.OfflineMode) + { + Application.LoadLevel(Application.loadedLevel); + } + else + { + StartCoroutine(WaitForRestart()); + } + } + + private IEnumerator WaitForRestart() + { + if (m_SteamLobby != null) + { + m_SteamLobby.LeaveLobby(); + } + if (PhotonNetwork.InRoom) + { + PhotonNetwork.LeaveRoom(); + while (PhotonNetwork.InRoom) + { + yield return null; + } + } + if (PhotonNetwork.IsConnected) + { + PhotonNetwork.Disconnect(); + while (PhotonNetwork.IsConnected) + { + yield return null; + } + } + EscapeMenuHandler.isEscMenu = false; + DevConsole.isTyping = false; + Application.LoadLevel(Application.loadedLevel); + } +} diff --git a/GameCode/NetworkData.cs b/GameCode/NetworkData.cs new file mode 100644 index 0000000..293da46 --- /dev/null +++ b/GameCode/NetworkData.cs @@ -0,0 +1,58 @@ +using Photon.Pun; +using UnityEngine; + +public class NetworkData : MonoBehaviour +{ + private PhotonView photonView; + + private bool inited; + + private void Start() + { + photonView = GetComponent<PhotonView>(); + } + + private void Init() + { + if (!inited) + { + inited = true; + if (PhotonNetwork.IsMasterClient) + { + Debug.Log("Why am i the master?"); + } + } + } + + private void Update() + { + if (PhotonNetwork.InRoom) + { + Init(); + } + } + + private void RequestJoin() + { + photonView.RPC("RequestJoinMaster", RpcTarget.MasterClient); + Debug.Log("Request join"); + } + + [PunRPC] + public void RequestJoinMaster() + { + string text = JsonUtility.ToJson(new InitPackage + { + currentMapID = MapManager.instance.currentLevelID + }); + photonView.RPC("RequestJoinResponse", RpcTarget.Others, text); + } + + [PunRPC] + public void RequestJoinResponse(string jsonResponse) + { + InitPackage initPackage = (InitPackage)JsonUtility.FromJson(jsonResponse, typeof(InitPackage)); + MapManager.instance.LoadLevelFromID(initPackage.currentMapID, onlyMaster: false, callInImidetly: true); + Debug.Log("Got response"); + } +} diff --git a/GameCode/NetworkPhysicsObject.cs b/GameCode/NetworkPhysicsObject.cs new file mode 100644 index 0000000..9ffb4d6 --- /dev/null +++ b/GameCode/NetworkPhysicsObject.cs @@ -0,0 +1,248 @@ +using System.Collections.Generic; +using Photon.Pun; +using Sonigon; +using UnityEngine; + +public class NetworkPhysicsObject : MonoBehaviour, IPunObservable +{ + [Header("Sounds")] + public SoundEvent soundBoxImpact; + + public float soundPitchSemitone; + + private SoundParameterPitchSemitone soundParameterPitchSemitone = new SoundParameterPitchSemitone(); + + private SoundParameterIntensity soundParameterIntensity = new SoundParameterIntensity(); + + [Header("Settings")] + public PhotonView photonView; + + private Rigidbody2D rig2D; + + private Collider2D col; + + public int sendFreq = 5; + + private int currentFrame; + + private float lastTime; + + private List<ObjectSyncPackage> syncPackages = new List<ObjectSyncPackage>(); + + private float sinceCol; + + public float collisionThreshold; + + public float shakeAmount; + + public float maxShake; + + public float playerColThreshold = 1f; + + public float dmgAmount = 1f; + + public float forceAmount = 1f; + + private float sinceDealDMG; + + private List<Player> hitPlayers = new List<Player>(); + + public float speed = 100f; + + private float sinceRequest; + + private float sincePushed; + + public float bulletPushMultiplier = 1f; + + private Vector2 currentForceToSend; + + private Vector2 currentForcePos; + + private float sendForceRate = 0.1f; + + private float sendForceCounter; + + public float sleepThreshold = 1f; + + public void Awake() + { + soundParameterPitchSemitone.pitchSemitone = soundPitchSemitone; + currentFrame = Random.Range(0, sendFreq); + photonView = GetComponent<PhotonView>(); + col = GetComponent<Collider2D>(); + rig2D = GetComponent<Rigidbody2D>(); + } + + private void Update() + { + if (!photonView) + { + return; + } + sinceRequest += Time.deltaTime; + sinceDealDMG += Time.deltaTime; + sendForceCounter += Time.deltaTime; + if (sendForceCounter > sendForceRate) + { + _ = photonView.IsMine; + if (currentForceToSend != Vector2.zero) + { + photonView.RPC("RPCA_SendForce", photonView.Owner, currentForceToSend, currentForcePos); + sendForceCounter = 0f; + currentForceToSend = Vector2.zero; + } + } + if (syncPackages.Count > 0) + { + if (syncPackages[0].timeDelta > 0f) + { + syncPackages[0].timeDelta -= Time.deltaTime * 1.5f * (1f + (float)syncPackages.Count * 0.5f); + } + else + { + if (syncPackages.Count > 2) + { + syncPackages.RemoveAt(0); + } + rig2D.isKinematic = false; + base.transform.position = syncPackages[0].pos; + base.transform.rotation = Quaternion.LookRotation(Vector3.forward, syncPackages[0].rot); + rig2D.velocity = syncPackages[0].vel; + rig2D.angularVelocity = syncPackages[0].angularVel; + syncPackages.RemoveAt(0); + } + } + sinceCol += Time.deltaTime; + } + + public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info) + { + currentFrame++; + if (stream.IsWriting) + { + if (currentFrame >= sendFreq) + { + currentFrame = 0; + stream.SendNext((Vector2)base.transform.position); + stream.SendNext((Vector2)base.transform.up); + stream.SendNext(rig2D.velocity); + stream.SendNext(rig2D.angularVelocity); + if (lastTime == 0f) + { + lastTime = Time.time; + } + stream.SendNext(Time.time - lastTime); + lastTime = Time.time; + } + } + else + { + ObjectSyncPackage objectSyncPackage = new ObjectSyncPackage(); + objectSyncPackage.pos = (Vector2)stream.ReceiveNext(); + objectSyncPackage.rot = (Vector2)stream.ReceiveNext(); + objectSyncPackage.vel = (Vector2)stream.ReceiveNext(); + objectSyncPackage.angularVel = (float)stream.ReceiveNext(); + objectSyncPackage.timeDelta = (float)stream.ReceiveNext(); + syncPackages.Add(objectSyncPackage); + } + } + + [PunRPC] + public void RPCA_Collide(Vector2 colForce) + { + soundParameterIntensity.intensity = colForce.magnitude; + SoundManager.Instance.PlayAtPosition(soundBoxImpact, SoundManager.Instance.GetTransform(), base.transform, soundParameterIntensity, soundParameterPitchSemitone); + GamefeelManager.instance.AddGameFeel(colForce); + } + + private void OnCollisionEnter2D(Collision2D collision) + { + if (photonView.IsMine && !(collision.contacts[0].normalImpulse < collisionThreshold) && !(sinceCol < 0.1f)) + { + sinceCol = 0f; + photonView.RPC("RPCA_Collide", RpcTarget.All, Mathf.Clamp(collision.contacts[0].normalImpulse, 0f, maxShake) * collision.contacts[0].normal * shakeAmount); + } + } + + private void OnPlayerCollision(Vector2 collision, CharacterData player) + { + if (!player.view.IsMine || sinceDealDMG < 1f) + { + return; + } + Vector3 vector = collision * dmgAmount; + if (!(vector.magnitude < playerColThreshold)) + { + float num = Mathf.Pow(rig2D.mass / 20000f, 2f); + float num2 = Mathf.Pow(rig2D.mass / 20000f, 0.5f); + player.healthHandler.CallTakeDamage(vector * 0.3f * num, player.transform.position); + player.healthHandler.CallTakeForce(collision * forceAmount * num2, ForceMode2D.Impulse, forceIgnoreMass: false, ignoreBlock: false, vector.magnitude * 0.05f); + if (player.block.IsBlocking()) + { + rig2D.velocity *= -1.1f; + rig2D.angularVelocity *= -1.1f; + } + else if (rig2D.mass < 80000f) + { + rig2D.velocity *= -0.5f * (20000f / rig2D.mass); + rig2D.angularVelocity *= -0.5f * (20000f / rig2D.mass); + } + sinceDealDMG = 0f; + photonView.RPC("RPCA_PlayerCollision", RpcTarget.AllViaServer, collision, rig2D.velocity, base.transform.position, player.view.ViewID); + } + } + + [PunRPC] + public void RPCM_RequestCollide(Vector2 collision, Vector2 afterVel, Vector3 position, int playerId) + { + photonView.RPC("RPCA_PlayerCollision", RpcTarget.AllViaServer, collision, afterVel, position, playerId); + } + + [PunRPC] + private void RPCA_PlayerCollision(Vector2 collision, Vector2 velAfter, Vector3 position, int playerID) + { + CharacterData component = PhotonNetwork.GetPhotonView(playerID).GetComponent<CharacterData>(); + base.transform.position = position; + rig2D.velocity = velAfter; + sinceDealDMG = 0f; + StartCoroutine(component.GetComponent<PlayerCollision>().IDoBounce(component.playerVel.velocity)); + } + + public void BulletPush(Vector2 force, Vector2 localPoint, CharacterData asker) + { + if (photonView.IsMine) + { + rig2D.AddForceAtPosition(force * bulletPushMultiplier, base.transform.TransformPoint(localPoint), ForceMode2D.Impulse); + } + } + + [PunRPC] + public void RPCA_SendForce(Vector2 forceSent, Vector2 sentForcePos) + { + rig2D.AddForceAtPosition(forceSent, base.transform.TransformPoint(currentForcePos)); + } + + public Vector3 Push(CharacterData data) + { + if (!data.view.IsMine) + { + return Vector3.zero; + } + sincePushed = 0f; + Vector2 vector = data.input.direction * 8f; + Vector2 vector2 = col.bounds.ClosestPoint(data.transform.position); + float num = Vector2.Angle(vector, vector2 - (Vector2)data.transform.position); + float num2 = (90f - num) / 90f; + Vector2 vector3 = TimeHandler.fixedDeltaTime * vector * num2 * speed * 1000f; + currentForceToSend += vector3; + currentForcePos = base.transform.InverseTransformPoint(vector2); + float num3 = Mathf.Clamp((Vector2.Angle(rig2D.velocity, (Vector2)base.transform.position - (Vector2)data.transform.position) - 90f) / 90f, 0f, 1f); + OnPlayerCollision(rig2D.velocity * num3, data); + return -vector; + } + + public void RequestOwnership(CharacterData player) + { + } +} diff --git a/GameCode/NetworkPlayer.cs b/GameCode/NetworkPlayer.cs new file mode 100644 index 0000000..47619c9 --- /dev/null +++ b/GameCode/NetworkPlayer.cs @@ -0,0 +1,4 @@ +public class NetworkPlayer +{ + private int playerID; +} diff --git a/GameCode/NetworkSettings.cs b/GameCode/NetworkSettings.cs new file mode 100644 index 0000000..1375488 --- /dev/null +++ b/GameCode/NetworkSettings.cs @@ -0,0 +1,11 @@ +using Photon.Pun; +using UnityEngine; + +public class NetworkSettings : MonoBehaviour +{ + private void Start() + { + PhotonNetwork.SendRate = 30; + PhotonNetwork.SerializationRate = 30; + } +} diff --git a/GameCode/NewScript.cs b/GameCode/NewScript.cs new file mode 100644 index 0000000..8bde104 --- /dev/null +++ b/GameCode/NewScript.cs @@ -0,0 +1,12 @@ +using UnityEngine; + +public class NewScript : MonoBehaviour +{ + private void Start() + { + } + + private void Update() + { + } +} diff --git a/GameCode/NextArt.cs b/GameCode/NextArt.cs new file mode 100644 index 0000000..9300887 --- /dev/null +++ b/GameCode/NextArt.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +public class NextArt : MonoBehaviour +{ + private void Start() + { + ArtHandler.instance.NextArt(); + } +} diff --git a/GameCode/ObjectParticle.cs b/GameCode/ObjectParticle.cs new file mode 100644 index 0000000..5e3927b --- /dev/null +++ b/GameCode/ObjectParticle.cs @@ -0,0 +1,34 @@ +using System; +using Sirenix.OdinInspector; +using UnityEngine; + +[Serializable] +public class ObjectParticle +{ + public float size = 1f; + + public AnimationCurve sizeOverTime = AnimationCurve.Linear(0f, 1f, 1f, 1f); + + public float lifetime = 1f; + + public float rotation; + + public float randomRotation; + + [FoldoutGroup("Color", 0)] + public Color color = Color.magenta; + + [FoldoutGroup("Color", 0)] + public Color randomColor = Color.magenta; + + [FoldoutGroup("Color", 0)] + public Color randomAddedColor = Color.black; + + [FoldoutGroup("Color", 0)] + public float randomAddedSaturation; + + [FoldoutGroup("Color", 0)] + public bool singleRandomValueColor = true; + + public AnimationCurve alphaOverTime = AnimationCurve.Linear(0f, 1f, 1f, 1f); +} diff --git a/GameCode/ObjectPool.cs b/GameCode/ObjectPool.cs new file mode 100644 index 0000000..b17adae --- /dev/null +++ b/GameCode/ObjectPool.cs @@ -0,0 +1,70 @@ +using System.Collections.Generic; +using UnityEngine; + +public class ObjectPool +{ + private Stack<GameObject> m_availableObjects = new Stack<GameObject>(); + + private List<GameObject> m_usedObjects = new List<GameObject>(); + + private GameObject m_objectPrefab; + + private Transform m_objectRoot; + + private int testCounter = 1; + + public ObjectPool(GameObject prefab, int initSpawn = 0, Transform parent = null) + { + m_objectPrefab = prefab; + m_objectRoot = new GameObject(prefab.name + "_root").transform; + m_objectRoot.transform.position = parent.position; + m_objectRoot.transform.rotation = parent.rotation; + m_objectRoot.transform.SetParent(parent, worldPositionStays: true); + m_objectRoot.transform.localScale = Vector3.one; + for (int i = 0; i < initSpawn; i++) + { + GameObject gameObject = Object.Instantiate(m_objectPrefab, m_objectRoot); + gameObject.SetActive(value: false); + m_availableObjects.Push(gameObject); + } + } + + public GameObject GetObject() + { + if (m_availableObjects.Count > 0) + { + GameObject gameObject = m_availableObjects.Pop(); + m_usedObjects.Add(gameObject); + gameObject.SetActive(value: true); + return gameObject; + } + GameObject gameObject2 = Object.Instantiate(m_objectPrefab, m_objectRoot); + m_usedObjects.Add(gameObject2); + gameObject2.SetActive(value: true); + return gameObject2; + } + + public bool ReleaseObject(GameObject obj) + { + bool num = m_usedObjects.Remove(obj); + if (num) + { + m_availableObjects.Push(obj); + obj.SetActive(value: false); + } + return num; + } + + public void ClearPool() + { + while (m_availableObjects.Count > 0) + { + Object.Destroy(m_availableObjects.Pop()); + } + for (int i = 0; i < m_usedObjects.Count; i++) + { + Object.Destroy(m_usedObjects[i]); + } + m_usedObjects.Clear(); + } +} diff --git a/GameCode/ObjectScaleToBulletStats.cs b/GameCode/ObjectScaleToBulletStats.cs new file mode 100644 index 0000000..da5e7d6 --- /dev/null +++ b/GameCode/ObjectScaleToBulletStats.cs @@ -0,0 +1,24 @@ +using UnityEngine; + +public class ObjectScaleToBulletStats : MonoBehaviour +{ + public GameObject target; + + public float dmgAmount = 1f; + + public float speedAmount = 1f; + + private void Start() + { + ProjectileHit component = GetComponent<ProjectileHit>(); + MoveTransform component2 = GetComponent<MoveTransform>(); + if ((bool)component) + { + component.damage = Mathf.Lerp(component.damage, component.damage * target.transform.localScale.x, dmgAmount); + } + if ((bool)component2) + { + component2.localForce.z = Mathf.Lerp(component2.localForce.z, component2.localForce.z * target.transform.localScale.x, speedAmount); + } + } +} diff --git a/GameCode/ObjectShake.cs b/GameCode/ObjectShake.cs new file mode 100644 index 0000000..f4e8059 --- /dev/null +++ b/GameCode/ObjectShake.cs @@ -0,0 +1,29 @@ +using UnityEngine; + +public class ObjectShake : MonoBehaviour +{ + public float globalMultiplier = 1f; + + public float interval = 0.1f; + + public float movementMultiplier = 1f; + + public float rotationMultiplier = 1f; + + private float counter; + + private void Start() + { + } + + private void Update() + { + counter += TimeHandler.deltaTime; + if (counter > interval) + { + base.transform.localPosition = Random.insideUnitCircle * movementMultiplier * globalMultiplier * 0.1f; + base.transform.localEulerAngles = new Vector3(base.transform.localEulerAngles.x, base.transform.localEulerAngles.y, (float)Random.Range(-10, 10) * globalMultiplier * rotationMultiplier); + counter = 0f; + } + } +} diff --git a/GameCode/ObjectSyncPackage.cs b/GameCode/ObjectSyncPackage.cs new file mode 100644 index 0000000..7affc5f --- /dev/null +++ b/GameCode/ObjectSyncPackage.cs @@ -0,0 +1,14 @@ +using UnityEngine; + +public class ObjectSyncPackage +{ + public Vector2 pos; + + public Vector2 rot; + + public Vector2 vel; + + public float angularVel; + + public float timeDelta; +} diff --git a/GameCode/ObjectsToSpawn.cs b/GameCode/ObjectsToSpawn.cs new file mode 100644 index 0000000..cf688ce --- /dev/null +++ b/GameCode/ObjectsToSpawn.cs @@ -0,0 +1,123 @@ +using System; +using Sirenix.OdinInspector; +using UnityEngine; + +[Serializable] +public class ObjectsToSpawn +{ + public enum Direction + { + forward, + normal, + identity + } + + public enum SpawnOn + { + all, + player, + notPlayer + } + + [FoldoutGroup("OnHit", 0)] + public GameObject effect; + + [FoldoutGroup("OnHit", 0)] + public Direction direction; + + [FoldoutGroup("OnHit", 0)] + public SpawnOn spawnOn; + + [FoldoutGroup("OnHit", 0)] + public bool spawnAsChild; + + [FoldoutGroup("OnHit", 0)] + public int numberOfSpawns = 1; + + [FoldoutGroup("OnHit", 0)] + public float normalOffset; + + [FoldoutGroup("OnHit", 0)] + public bool stickToBigTargets; + + [FoldoutGroup("OnHit", 0)] + public bool stickToAllTargets; + + [FoldoutGroup("OnHit", 0)] + public bool zeroZ; + + [FoldoutGroup("OnProjectile", 0)] + public GameObject AddToProjectile; + + [FoldoutGroup("OnProjectile", 0)] + public bool removeScriptsFromProjectileObject; + + [FoldoutGroup("Stacking", 0)] + public bool scaleStacks; + + [FoldoutGroup("Stacking", 0)] + public float scaleStackM = 0.5f; + + [FoldoutGroup("Scaling", 0)] + public float scaleFromDamage; + + [HideInInspector] + public int stacks; + + public static GameObject[] SpawnObject(Transform spawnerTransform, HitInfo hit, ObjectsToSpawn objectToSpawn, HealthHandler playerHealth, PlayerSkin playerSkins, float damage = 55f, SpawnedAttack spawnedAttack = null, bool wasBlocked = false) + { + GameObject[] array = new GameObject[objectToSpawn.numberOfSpawns]; + for (int i = 0; i < objectToSpawn.numberOfSpawns; i++) + { + if (wasBlocked && objectToSpawn.stickToAllTargets) + { + continue; + } + Vector3 position = (Vector3)hit.point + (Vector3)hit.normal * objectToSpawn.normalOffset + (objectToSpawn.zeroZ ? Vector3.zero : (Vector3.forward * 5f)); + Quaternion rotation = Quaternion.LookRotation(spawnerTransform.forward); + if (objectToSpawn.direction == Direction.normal) + { + rotation = Quaternion.LookRotation(hit.normal + Vector2.right * 0.005f); + } + if (objectToSpawn.direction == Direction.identity) + { + rotation = Quaternion.identity; + } + if ((objectToSpawn.spawnOn != SpawnOn.notPlayer || !playerHealth) && (objectToSpawn.spawnOn != SpawnOn.player || (bool)playerHealth) && (bool)objectToSpawn.effect) + { + GameObject gameObject = UnityEngine.Object.Instantiate(objectToSpawn.effect, position, rotation); + if (objectToSpawn.spawnAsChild && (bool)hit.transform) + { + gameObject.transform.SetParent(hit.transform, worldPositionStays: true); + } + if ((bool)spawnedAttack) + { + spawnedAttack.CopySpawnedAttackTo(gameObject); + } + array[i] = gameObject; + SetTeamColor.TeamColorThis(gameObject, playerSkins); + if ((objectToSpawn.stickToBigTargets && !playerHealth && (!hit.rigidbody || hit.rigidbody.mass > 500f)) || objectToSpawn.stickToAllTargets) + { + gameObject.AddComponent<FollowLocalPos>().Follow(hit.transform); + } + if (objectToSpawn.scaleFromDamage != 0f) + { + gameObject.transform.localScale *= 1f * (1f - objectToSpawn.scaleFromDamage) + damage / 55f * objectToSpawn.scaleFromDamage; + } + if (objectToSpawn.scaleStacks) + { + gameObject.transform.localScale *= 1f + (float)objectToSpawn.stacks * objectToSpawn.scaleStackM; + } + } + } + return array; + } + + public static void SpawnObject(ObjectsToSpawn objectToSpawn, Vector3 position, Quaternion rotation) + { + for (int i = 0; i < objectToSpawn.numberOfSpawns; i++) + { + UnityEngine.Object.Instantiate(objectToSpawn.effect, position, rotation); + } + } +} diff --git a/GameCode/OnlineNameSelect.cs b/GameCode/OnlineNameSelect.cs new file mode 100644 index 0000000..c9fd43a --- /dev/null +++ b/GameCode/OnlineNameSelect.cs @@ -0,0 +1,21 @@ +using Photon.Pun; +using TMPro; +using UnityEngine; + +public class OnlineNameSelect : MonoBehaviour +{ + private TMP_InputField nameField; + + private void Start() + { + nameField = GetComponentInChildren<TMP_InputField>(); + nameField.text = PlayerPrefs.GetString("PlayerName", ""); + PhotonNetwork.LocalPlayer.NickName = nameField.text; + } + + public void OnChangedVal(string newVal) + { + PlayerPrefs.SetString("PlayerName", nameField.text); + PhotonNetwork.LocalPlayer.NickName = nameField.text; + } +} diff --git a/GameCode/OnlyOneEdgeModifier.cs b/GameCode/OnlyOneEdgeModifier.cs new file mode 100644 index 0000000..080423c --- /dev/null +++ b/GameCode/OnlyOneEdgeModifier.cs @@ -0,0 +1,57 @@ +using UnityEngine; +using UnityEngine.UI.ProceduralImage; + +[ModifierID("Only One Edge")] +public class OnlyOneEdgeModifier : ProceduralImageModifier +{ + public enum ProceduralImageEdge + { + Top, + Bottom, + Left, + Right + } + + [SerializeField] + private float radius; + + [SerializeField] + private ProceduralImageEdge side; + + public float Radius + { + get + { + return radius; + } + set + { + radius = value; + base._Graphic.SetVerticesDirty(); + } + } + + public ProceduralImageEdge Side + { + get + { + return side; + } + set + { + side = value; + } + } + + public override Vector4 CalculateRadius(Rect imageRect) + { + return side switch + { + ProceduralImageEdge.Top => new Vector4(radius, radius, 0f, 0f), + ProceduralImageEdge.Right => new Vector4(0f, radius, radius, 0f), + ProceduralImageEdge.Bottom => new Vector4(0f, 0f, radius, radius), + ProceduralImageEdge.Left => new Vector4(radius, 0f, 0f, radius), + _ => new Vector4(0f, 0f, 0f, 0f), + }; + } +} diff --git a/GameCode/OptionsButton.cs b/GameCode/OptionsButton.cs new file mode 100644 index 0000000..f33bfc6 --- /dev/null +++ b/GameCode/OptionsButton.cs @@ -0,0 +1,204 @@ +using TMPro; +using UnityEngine; +using UnityEngine.UI; + +public class OptionsButton : MonoBehaviour +{ + public enum SettingsTarget + { + Resolution, + Vol_Master, + Vol_SFX, + Vol_Music, + CharacterPattern, + MapPattern, + leftStickAim, + lockAimDirections, + ShowCardStarts, + FullScreen, + FreeStickAim, + Vsync + } + + public enum SettingsType + { + Binary, + Slider, + MultiOption + } + + public SettingsTarget settingsTarget; + + public SettingsType settingsType; + + public bool currentBoolValue; + + public Resolution currentResolutionValue; + + public Optionshandler.FullScreenOption currentFullscreenValue; + + public float currentFloatValue; + + private TextMeshProUGUI text; + + public Slider slider; + + private void Awake() + { + text = GetComponentsInChildren<TextMeshProUGUI>(includeInactive: true)[1]; + if (settingsType == SettingsType.Slider) + { + slider = GetComponentInChildren<Slider>(includeInactive: true); + slider.onValueChanged.AddListener(SliderSlide); + } + else + { + GetComponent<Button>().onClick.AddListener(ClickButton); + } + } + + private void OnEnable() + { + switch (settingsTarget) + { + case SettingsTarget.Resolution: + currentResolutionValue = Optionshandler.resolution; + break; + case SettingsTarget.Vol_Master: + currentFloatValue = Optionshandler.vol_Master; + break; + case SettingsTarget.Vol_SFX: + currentFloatValue = Optionshandler.vol_Sfx; + break; + case SettingsTarget.Vol_Music: + currentFloatValue = Optionshandler.vol_Music; + break; + case SettingsTarget.CharacterPattern: + currentBoolValue = Optionshandler.characterPattrens; + break; + case SettingsTarget.MapPattern: + currentBoolValue = Optionshandler.mapPatterns; + break; + case SettingsTarget.leftStickAim: + currentBoolValue = Optionshandler.leftStickAim; + break; + case SettingsTarget.lockAimDirections: + currentBoolValue = Optionshandler.lockMouse; + break; + case SettingsTarget.FreeStickAim: + currentBoolValue = Optionshandler.lockStick; + break; + case SettingsTarget.ShowCardStarts: + currentBoolValue = Optionshandler.showCardStatNumbers; + break; + case SettingsTarget.FullScreen: + currentFullscreenValue = Optionshandler.fullScreen; + break; + case SettingsTarget.Vsync: + currentBoolValue = Optionshandler.vSync; + break; + } + if (settingsType == SettingsType.Slider) + { + slider.value = currentFloatValue; + } + ReDraw(); + } + + public void SetResolutionAndFullscreen(Resolution newRess, Optionshandler.FullScreenOption fullScreen) + { + currentResolutionValue = newRess; + currentFullscreenValue = fullScreen; + ClickButton(); + if (settingsTarget == SettingsTarget.Resolution) + { + Optionshandler.instance.SetResolution(newRess); + } + if (settingsTarget == SettingsTarget.FullScreen) + { + Optionshandler.instance.SetFullScreen(fullScreen); + } + } + + public void SliderChanged() + { + currentFloatValue = slider.value; + } + + private void SliderSlide(float newVal) + { + currentFloatValue = newVal; + ClickButton(); + } + + public void ClickButton() + { + if (settingsType == SettingsType.Binary) + { + currentBoolValue = !currentBoolValue; + } + switch (settingsTarget) + { + case SettingsTarget.Resolution: + base.transform.parent.parent.GetComponentInChildren<MultiOptions>(includeInactive: true).Open(settingsTarget, base.transform.GetChild(1).position, this); + break; + case SettingsTarget.Vol_Master: + Optionshandler.instance.SetVolMaster(currentFloatValue); + break; + case SettingsTarget.Vol_SFX: + Optionshandler.instance.SetVolSFX(currentFloatValue); + break; + case SettingsTarget.Vol_Music: + Optionshandler.instance.SetVolMusic(currentFloatValue); + break; + case SettingsTarget.CharacterPattern: + Optionshandler.instance.SetCharacterPatterns(currentBoolValue); + break; + case SettingsTarget.MapPattern: + Optionshandler.instance.SetMapPatterns(currentBoolValue); + break; + case SettingsTarget.leftStickAim: + Optionshandler.instance.SetLeftStickAim(currentBoolValue); + break; + case SettingsTarget.lockAimDirections: + Optionshandler.instance.lockMouseAim(currentBoolValue); + break; + case SettingsTarget.FreeStickAim: + Optionshandler.instance.lockStickAim(currentBoolValue); + break; + case SettingsTarget.ShowCardStarts: + Optionshandler.instance.SetShowCardStatNumbers(currentBoolValue); + break; + case SettingsTarget.FullScreen: + base.transform.parent.parent.GetComponentInChildren<MultiOptions>(includeInactive: true).Open(settingsTarget, base.transform.GetChild(1).position, this); + break; + case SettingsTarget.Vsync: + Optionshandler.instance.SetVSync(currentBoolValue); + break; + } + ReDraw(); + } + + private void ReDraw() + { + if (settingsType == SettingsType.Binary) + { + text.text = (currentBoolValue ? "YES" : "NO"); + } + if (settingsType == SettingsType.MultiOption) + { + if (settingsTarget == SettingsTarget.Resolution) + { + text.text = currentResolutionValue.width + " X " + currentResolutionValue.height; + } + else if (currentFullscreenValue == Optionshandler.FullScreenOption.WindowedFullScreen) + { + text.text = "WINDOWED FULLSCREEN"; + } + else + { + text.text = currentFullscreenValue.ToString().ToUpper(); + } + } + } +} diff --git a/GameCode/Optionshandler.cs b/GameCode/Optionshandler.cs new file mode 100644 index 0000000..21130c1 --- /dev/null +++ b/GameCode/Optionshandler.cs @@ -0,0 +1,187 @@ +using SoundImplementation; +using UnityEngine; + +public class Optionshandler : MonoBehaviour +{ + public enum FullScreenOption + { + FullScreen, + WindowedFullScreen, + MaximizedWindow, + Windowed + } + + public static Resolution resolution; + + public static float vol_Master; + + public static float vol_Sfx; + + public static float vol_Music; + + public static FullScreenOption fullScreen; + + public static bool characterPattrens; + + public static bool mapPatterns; + + public static bool vSync; + + public static bool leftStickAim; + + public static bool lockMouse; + + public static bool showCardStatNumbers; + + public static bool lockStick; + + public static Optionshandler instance; + + private void Start() + { + instance = this; + LoadOptions(); + ApplyOptions(); + } + + private void LoadOptions() + { + vol_Master = PlayerPrefs.GetFloat("Vol_Master", 1f); + vol_Sfx = PlayerPrefs.GetFloat("vol_Sfx", 1f); + vol_Music = PlayerPrefs.GetFloat("vol_Music", 1f); + resolution.width = PlayerPrefs.GetInt("res_X", 0); + resolution.height = PlayerPrefs.GetInt("res_Y", 0); + fullScreen = (FullScreenOption)PlayerPrefs.GetInt("fullScreen", 1); + characterPattrens = GetBool(PlayerPrefs.GetInt("characterPattrens", 1)); + mapPatterns = GetBool(PlayerPrefs.GetInt("mapPatterns", 1)); + leftStickAim = GetBool(PlayerPrefs.GetInt("leftStickAim", 1)); + vSync = GetBool(PlayerPrefs.GetInt("vSync", 0)); + lockStick = GetBool(PlayerPrefs.GetInt("lockStick", 0)); + lockMouse = GetBool(PlayerPrefs.GetInt("lockMouse", 0)); + showCardStatNumbers = GetBool(PlayerPrefs.GetInt("showCardStatNumbers", 0)); + if (resolution.height == 0 || resolution.width == 0) + { + resolution = Screen.currentResolution; + SaveOptions(); + } + else + { + ApplyOptions(); + } + } + + private void SaveOptions() + { + PlayerPrefs.SetFloat("Vol_Master", vol_Master); + PlayerPrefs.SetFloat("vol_Sfx", vol_Sfx); + PlayerPrefs.SetFloat("vol_Music", vol_Music); + PlayerPrefs.SetInt("res_X", resolution.width); + PlayerPrefs.SetInt("res_Y", resolution.height); + PlayerPrefs.SetInt("fullScreen", (int)fullScreen); + PlayerPrefs.SetInt("characterPattrens", GetInt(characterPattrens)); + PlayerPrefs.SetInt("mapPatterns", GetInt(mapPatterns)); + PlayerPrefs.SetInt("leftStickAim", GetInt(leftStickAim)); + PlayerPrefs.SetInt("vSync", GetInt(vSync)); + PlayerPrefs.SetInt("lockMouse", GetInt(lockMouse)); + PlayerPrefs.SetInt("lockStick", GetInt(lockStick)); + PlayerPrefs.SetInt("showCardStatNumbers", GetInt(showCardStatNumbers)); + ApplyOptions(); + } + + private void ApplyOptions() + { + Screen.SetResolution(resolution.width, resolution.height, (FullScreenMode)fullScreen); + QualitySettings.vSyncCount = (vSync ? 1 : 0); + SoundVolumeManager.Instance.SetAudioMixerVolumes(vol_Master, vol_Music, vol_Sfx); + } + + private bool GetBool(int value) + { + if (value != 1) + { + return false; + } + return true; + } + + private int GetInt(bool value) + { + if (!value) + { + return 0; + } + return 1; + } + + public void SetResolution(Resolution resolutionToSet) + { + resolution = resolutionToSet; + SaveOptions(); + } + + public void SetVSync(bool vSyncToSet) + { + vSync = vSyncToSet; + SaveOptions(); + } + + public void SetVolMaster(float vol_Master_ToSet) + { + vol_Master = vol_Master_ToSet; + SaveOptions(); + } + + public void SetVolSFX(float vol_SFX_ToSet) + { + vol_Sfx = vol_SFX_ToSet; + SaveOptions(); + } + + public void SetVolMusic(float vol_Music_ToSet) + { + vol_Music = vol_Music_ToSet; + SaveOptions(); + } + + public void SetCharacterPatterns(bool characterPatternsToSet) + { + characterPattrens = characterPatternsToSet; + SaveOptions(); + } + + public void SetMapPatterns(bool mapPatternsToSet) + { + mapPatterns = mapPatternsToSet; + SaveOptions(); + } + + public void SetLeftStickAim(bool leftStickAimToSet) + { + leftStickAim = leftStickAimToSet; + SaveOptions(); + } + + public void lockMouseAim(bool setLockMouse) + { + lockMouse = setLockMouse; + SaveOptions(); + } + + public void lockStickAim(bool setLockStick) + { + lockStick = setLockStick; + SaveOptions(); + } + + public void SetShowCardStatNumbers(bool showCardStatNumbersToSet) + { + showCardStatNumbers = showCardStatNumbersToSet; + SaveOptions(); + } + + public void SetFullScreen(FullScreenOption fullscreenToSet) + { + fullScreen = fullscreenToSet; + SaveOptions(); + } +} diff --git a/GameCode/Orbit.cs b/GameCode/Orbit.cs new file mode 100644 index 0000000..0e63f89 --- /dev/null +++ b/GameCode/Orbit.cs @@ -0,0 +1,24 @@ +using System; +using UnityEngine; + +public class Orbit : MonoBehaviour +{ + public GameObject[] objectsPerLevel; + + private void Start() + { + AttackLevel component = GetComponent<AttackLevel>(); + component.LevelUpAction = (Action<int>)Delegate.Combine(component.LevelUpAction, new Action<int>(UpdateLevel)); + } + + private void UpdateLevel(int newLevel) + { + for (int i = 0; i < objectsPerLevel.Length; i++) + { + if (i <= newLevel - 1) + { + objectsPerLevel[i].SetActive(value: true); + } + } + } +} diff --git a/GameCode/OutOfBoundsHandler.cs b/GameCode/OutOfBoundsHandler.cs new file mode 100644 index 0000000..a7ed350 --- /dev/null +++ b/GameCode/OutOfBoundsHandler.cs @@ -0,0 +1,149 @@ +using Sonigon; +using UnityEngine; + +public class OutOfBoundsHandler : MonoBehaviour +{ + private bool outOfBounds; + + private bool almostOutOfBounds; + + private Camera mainCam; + + private CharacterData data; + + public ParticleSystem wall; + + public ParticleSystem burst; + + public ParticleSystem burstBig; + + public ParticleSystem warning; + + public ParticleSystem shieldWall; + + public ParticleSystem shieldBurst; + + public ParticleSystem shieldBurstBig; + + private ChildRPC rpc; + + private float counter; + + private float warningPercentage = 0.1f; + + private void Start() + { + base.transform.position = Vector3.up * 200f; + data = base.transform.root.GetComponent<CharacterData>(); + rpc = data.GetComponent<ChildRPC>(); + rpc.childRPCs.Add("OutOfBounds", RPCA_DisplayOutOfBounds); + rpc.childRPCs.Add("ShieldOutOfBounds", RPCA_DisplayOutOfBoundsShield); + mainCam = MainCam.instance.transform.GetComponent<Camera>(); + base.transform.SetParent(null); + } + + private void LateUpdate() + { + if (!data) + { + Object.Destroy(base.gameObject); + } + else + { + if (!data.playerVel.simulated || !data.isPlaying) + { + return; + } + float x = Mathf.InverseLerp(-35.56f, 35.56f, data.transform.position.x); + float y = Mathf.InverseLerp(-20f, 20f, data.transform.position.y); + Vector3 vector = new Vector3(x, y, 0f); + vector = new Vector3(Mathf.Clamp(vector.x, 0f, 1f), Mathf.Clamp(vector.y, 0f, 1f), vector.z); + almostOutOfBounds = false; + outOfBounds = false; + if (vector.x <= 0f || vector.x >= 1f || vector.y >= 1f || vector.y <= 0f) + { + outOfBounds = true; + } + else if (vector.x < warningPercentage || vector.x > 1f - warningPercentage || vector.y > 1f - warningPercentage || vector.y < warningPercentage) + { + almostOutOfBounds = true; + if (vector.x < warningPercentage) + { + vector.x = 0f; + } + if (vector.x > 1f - warningPercentage) + { + vector.x = 1f; + } + if (vector.y < warningPercentage) + { + vector.y = 0f; + } + if (vector.y > 1f - warningPercentage) + { + vector.y = 1f; + } + } + counter += TimeHandler.deltaTime; + if (almostOutOfBounds && !data.dead) + { + base.transform.position = GetPoint(vector); + base.transform.rotation = Quaternion.LookRotation(Vector3.forward, -(data.transform.position - base.transform.position)); + if (counter > 0.1f) + { + counter = 0f; + warning.Play(); + } + } + if (!outOfBounds || data.dead) + { + return; + } + data.sinceGrounded = 0f; + base.transform.position = GetPoint(vector); + base.transform.rotation = Quaternion.LookRotation(Vector3.forward, -(data.transform.position - base.transform.position)); + if (counter > 0.1f && data.view.IsMine) + { + counter = 0f; + if (data.block.IsBlocking()) + { + rpc.CallFunction("ShieldOutOfBounds"); + data.playerVel.velocity *= 0f; + data.healthHandler.CallTakeForce(base.transform.up * 400f * data.playerVel.mass, ForceMode2D.Impulse, forceIgnoreMass: false, ignoreBlock: true); + data.transform.position = base.transform.position; + } + else + { + rpc.CallFunction("OutOfBounds"); + data.healthHandler.CallTakeForce(base.transform.up * 200f * data.playerVel.mass, ForceMode2D.Impulse, forceIgnoreMass: false, ignoreBlock: true); + data.healthHandler.CallTakeDamage(51f * base.transform.up, data.transform.position); + } + } + } + } + + private Vector3 GetPoint(Vector3 p) + { + float x = Mathf.Lerp(-35.56f, 35.56f, p.x); + float y = Mathf.Lerp(-20f, 20f, p.y); + return new Vector3(x, y, 0f); + } + + private void RPCA_DisplayOutOfBounds() + { + SoundManager.Instance.Play(data.playerSounds.soundCharacterDamageScreenEdge, data.transform); + burst.Play(); + wall.Play(); + burstBig.Play(); + data.sinceGrounded = 0f; + } + + private void RPCA_DisplayOutOfBoundsShield() + { + SoundManager.Instance.Play(data.playerSounds.soundCharacterDamageScreenEdge, data.transform); + shieldBurst.Play(); + shieldWall.Play(); + shieldBurstBig.Play(); + data.sinceGrounded = 0f; + } +} diff --git a/GameCode/ParticleExplosionModifier.cs b/GameCode/ParticleExplosionModifier.cs new file mode 100644 index 0000000..ca3a6f6 --- /dev/null +++ b/GameCode/ParticleExplosionModifier.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections; +using UnityEngine; + +public class ParticleExplosionModifier : MonoBehaviour +{ + public AnimationCurve curve; + + public float speed = 1f; + + private ParticleSystem effect; + + private ParticleSystem.MainModule main; + + private Coroutine corutine; + + private void Start() + { + effect = GetComponent<ParticleSystem>(); + main = effect.main; + Explosion componentInParent = GetComponentInParent<Explosion>(); + componentInParent.DealDamageAction = (Action<Damagable>)Delegate.Combine(componentInParent.DealDamageAction, new Action<Damagable>(DealDamage)); + Explosion componentInParent2 = GetComponentInParent<Explosion>(); + componentInParent2.DealHealAction = (Action<Damagable>)Delegate.Combine(componentInParent2.DealHealAction, new Action<Damagable>(DealDamage)); + } + + public void DealDamage(Damagable damagable) + { + if (corutine != null) + { + StopCoroutine(corutine); + } + corutine = StartCoroutine(DoCurve()); + } + + private IEnumerator DoCurve() + { + float c = 0f; + float t = curve.keys[curve.keys.Length - 1].time; + while (c < t) + { + ParticleSystem.MinMaxCurve startSize = main.startSize; + startSize.constantMin = curve.Evaluate(c) * 0.5f; + startSize.constantMax = curve.Evaluate(c); + main.startSize = startSize; + c += TimeHandler.deltaTime * speed; + yield return null; + } + } +} diff --git a/GameCode/ParticlePlayer.cs b/GameCode/ParticlePlayer.cs new file mode 100644 index 0000000..c834a68 --- /dev/null +++ b/GameCode/ParticlePlayer.cs @@ -0,0 +1,53 @@ +using UnityEngine; + +public class ParticlePlayer : MonoBehaviour +{ + public static ParticlePlayer instance; + + private int spawnsThisFrame; + + private void Awake() + { + instance = this; + } + + private void Update() + { + spawnsThisFrame = 0; + } + + public void PlayEffect(string effectName, Vector3 position, Quaternion rotation, float scale = 1f, Transform followTransform = null) + { + if ((float)spawnsThisFrame > 5f) + { + return; + } + spawnsThisFrame++; + Transform transform = base.transform.Find(effectName); + if (!transform) + { + return; + } + if ((bool)followTransform) + { + transform = Object.Instantiate(transform.gameObject, null).transform; + } + transform.transform.position = position; + transform.transform.localScale = scale * Vector3.one; + transform.transform.rotation = rotation; + if ((bool)followTransform) + { + transform.gameObject.AddComponent<FollowLocalPos>().Follow(followTransform); + } + ParticleSystem[] componentsInChildren = transform.GetComponentsInChildren<ParticleSystem>(); + for (int i = 0; i < componentsInChildren.Length; i++) + { + if ((bool)followTransform) + { + ParticleSystem.MainModule main = componentsInChildren[i].main; + main.simulationSpace = ParticleSystemSimulationSpace.Local; + } + componentsInChildren[i].Play(); + } + } +} diff --git a/GameCode/ParticleTime.cs b/GameCode/ParticleTime.cs new file mode 100644 index 0000000..a3daa16 --- /dev/null +++ b/GameCode/ParticleTime.cs @@ -0,0 +1,19 @@ +using UnityEngine; + +public class ParticleTime : MonoBehaviour +{ + private float startTime = 1f; + + private ParticleSystem.MainModule main; + + private void Start() + { + main = GetComponentInParent<ParticleSystem>().main; + startTime = main.simulationSpeed; + } + + private void Update() + { + main.simulationSpeed = startTime * TimeHandler.timeScale; + } +} diff --git a/GameCode/PerlinWordScale.cs b/GameCode/PerlinWordScale.cs new file mode 100644 index 0000000..f59f4c2 --- /dev/null +++ b/GameCode/PerlinWordScale.cs @@ -0,0 +1,16 @@ +using UnityEngine; + +public class PerlinWordScale : MonoBehaviour +{ + public float scale = 1f; + + public float min = 0.5f; + + public float max = 2f; + + private void Start() + { + float t = Mathf.PerlinNoise(base.transform.position.x * scale, base.transform.position.y * scale); + base.transform.localScale *= Mathf.Lerp(min, max, t); + } +} diff --git a/GameCode/PhotonMapObject.cs b/GameCode/PhotonMapObject.cs new file mode 100644 index 0000000..8bfe674 --- /dev/null +++ b/GameCode/PhotonMapObject.cs @@ -0,0 +1,98 @@ +using System; +using System.Collections; +using Photon.Pun; +using UnityEngine; + +public class PhotonMapObject : MonoBehaviour +{ + private Map map; + + private bool photonSpawned; + + private float counter; + + private bool waitingToBeRemoved; + + private void Awake() + { + if (base.transform.parent != null) + { + UnityEngine.Object.DestroyImmediate(GetComponent<PhotonView>()); + } + } + + private void Start() + { + Rigidbody2D component = GetComponent<Rigidbody2D>(); + component.isKinematic = true; + component.simulated = false; + if (base.transform.parent == null) + { + photonSpawned = true; + base.transform.SetParent(MapManager.instance.currentMap.Map.transform, worldPositionStays: true); + map = GetComponentInParent<Map>(); + map.missingObjects--; + Map obj = map; + obj.mapIsReadyAction = (Action)Delegate.Combine(obj.mapIsReadyAction, new Action(Go)); + if (map.hasRope && !GetComponent<PhotonView>().IsMine) + { + component.gravityScale = 0f; + } + } + else + { + map = GetComponentInParent<Map>(); + Map obj2 = map; + obj2.mapIsReadyEarlyAction = (Action)Delegate.Combine(obj2.mapIsReadyEarlyAction, new Action(GoEarly)); + } + } + + private void GoEarly() + { + if (waitingToBeRemoved) + { + UnityEngine.Object.DestroyImmediate(base.gameObject); + } + } + + private void Go() + { + StartCoroutine(IGo()); + } + + private IEnumerator IGo() + { + Rigidbody2D rig = GetComponent<Rigidbody2D>(); + yield return new WaitForSeconds(0f); + yield return new WaitForSeconds(0f); + yield return new WaitForSeconds(0f); + rig.isKinematic = false; + rig.simulated = true; + if ((bool)rig) + { + for (float i = 0f; i < 1f; i += Time.deltaTime * 1f) + { + rig.velocity -= rig.velocity * i * 0.05f; + yield return null; + } + } + } + + private void Update() + { + if (waitingToBeRemoved || photonSpawned) + { + return; + } + counter += Mathf.Clamp(Time.deltaTime, 0f, 0.1f); + if ((PhotonNetwork.OfflineMode && counter > 1f && map.hasEntered) || ((bool)map && map.hasEntered && map.LoadedForAll())) + { + if (PhotonNetwork.IsMasterClient) + { + PhotonNetwork.Instantiate("4 Map Objects/" + base.gameObject.name.Split(char.Parse(" "))[0], base.transform.position, base.transform.rotation, 0); + } + map.missingObjects++; + waitingToBeRemoved = true; + } + } +} diff --git a/GameCode/PhysicsFunctions.cs b/GameCode/PhysicsFunctions.cs new file mode 100644 index 0000000..61cad4c --- /dev/null +++ b/GameCode/PhysicsFunctions.cs @@ -0,0 +1,16 @@ +using UnityEngine; + +public class PhysicsFunctions : MonoBehaviour +{ + private static LayerMask mask = LayerMask.GetMask("Default", "IgnorePlayer", "IgnoreMap"); + + public static Vector2 ObstructionPoint(Vector2 from, Vector2 to) + { + RaycastHit2D raycastHit2D = Physics2D.Raycast(from, to - from, Vector2.Distance(from, to), mask); + if ((bool)raycastHit2D.transform) + { + return raycastHit2D.point; + } + return to; + } +} diff --git a/GameCode/PickerType.cs b/GameCode/PickerType.cs new file mode 100644 index 0000000..b4f79a2 --- /dev/null +++ b/GameCode/PickerType.cs @@ -0,0 +1,5 @@ +public enum PickerType +{ + Team, + Player +} diff --git a/GameCode/Platform.cs b/GameCode/Platform.cs new file mode 100644 index 0000000..9d25a0b --- /dev/null +++ b/GameCode/Platform.cs @@ -0,0 +1,203 @@ +using System.Collections.Generic; +using System.Linq; +using UnityEngine; + +public class Platform +{ + private List<BoxCollider2D> m_boxColliders = new List<BoxCollider2D>(); + + private List<Vector2> m_platformPoints = new List<Vector2>(); + + public List<Vector2> m_edges = new List<Vector2>(); + + private static float EPSILON = Mathf.Epsilon * 10f; + + private int m_lastCalculatedClosestPoint = -1; + + public List<BoxCollider2D> BoxColliders => m_boxColliders; + + public List<Vector2> PlatformPoints + { + get + { + return m_platformPoints; + } + set + { + m_platformPoints = value; + } + } + + public List<Vector2> Edges => m_edges; + + public Color Color { get; set; } + + public Platform() + { + Color = new Color(Random.Range(0f, 1f), Random.Range(0f, 1f), Random.Range(0f, 1f)); + } + + public bool ContainsCollider(BoxCollider2D collider) + { + foreach (BoxCollider2D boxCollider in m_boxColliders) + { + if (collider == boxCollider) + { + return true; + } + } + return false; + } + + public void AddCollider(BoxCollider2D collider) + { + m_boxColliders.Add(collider); + } + + public void AddPlatformPoint(Vector2 point) + { + m_platformPoints.Add(point); + } + + public float GetClosestDistance(Vector2 position) + { + float num = float.MaxValue; + for (int i = 0; i < m_edges.Count; i++) + { + float num2 = Vector2.Distance(position, m_edges[i]); + if (num2 < num) + { + m_lastCalculatedClosestPoint = i; + num = num2; + } + } + return num; + } + + public bool IsPositionOutsidePlatform(Vector2 position) + { + Vector2 vector = m_edges[m_lastCalculatedClosestPoint]; + if (position.x > vector.x && m_lastCalculatedClosestPoint == m_edges.Count - 1) + { + return true; + } + if (position.x < vector.x && m_lastCalculatedClosestPoint == 0) + { + return true; + } + return false; + } + + public Vector2 GetPointOnPath(Vector2 position) + { + Vector2 vector = m_edges[m_lastCalculatedClosestPoint]; + if (position.x > vector.x && m_lastCalculatedClosestPoint == m_edges.Count - 1) + { + return vector; + } + if (position.x < vector.x && m_lastCalculatedClosestPoint == 0) + { + return vector; + } + int index = -1; + int num = 0; + if (position.x > vector.x) + { + index = m_lastCalculatedClosestPoint + 1; + num = 1; + } + else if (position.x <= vector.x) + { + index = m_lastCalculatedClosestPoint - 1; + num = -1; + } + if (num == 1) + { + return GetClosestPointOnLineSegment(vector, m_edges[index], position); + } + return GetClosestPointOnLineSegment(m_edges[index], vector, position); + } + + private Vector2 Project(Vector2 line1, Vector2 line2, Vector2 toProject) + { + float num = (line2.y - line1.y) / (line2.x - line1.x); + float num2 = line1.y - num * line1.x; + float x = (num * toProject.y + toProject.x - num * num2) / (num * num + 1f); + float y = (num * num * toProject.y + num * toProject.x + num2) / (num * num + 1f); + return new Vector2(x, y); + } + + public static Vector2 GetClosestPointOnLineSegment(Vector2 A, Vector2 B, Vector2 P) + { + Vector2 lhs = P - A; + Vector2 vector = B - A; + float sqrMagnitude = vector.sqrMagnitude; + float num = Vector2.Dot(lhs, vector) / sqrMagnitude; + if (num < 0f) + { + return A; + } + if (num > 1f) + { + return B; + } + return A + vector * num; + } + + public void PostProcessPlatformPoints() + { + int mask = LayerMask.GetMask("Default"); + List<Vector2> list = new List<Vector2>(m_platformPoints.OrderBy((Vector2 v) => v.x).ToArray()); + new HashSet<int>(); + for (int num = list.Count - 1; num > 0; num--) + { + if (Physics2D.OverlapCircle(list[num] + new Vector2(0f, 0.25f), 0.2f, mask) != null) + { + list.RemoveAt(num); + } + } + m_platformPoints = list; + DetectEdges(); + } + + public void DetectEdges() + { + if (m_platformPoints.Count == 0) + { + return; + } + List<Vector2> list = new List<Vector2>(); + for (int i = 0; i < m_platformPoints.Count - 2; i++) + { + Vector2 item = m_platformPoints[i]; + Vector2 item2 = m_platformPoints[i + 1]; + if (i == 0) + { + list.Add(item); + } + else if (i == m_platformPoints.Count - 3) + { + list.Add(item2); + } + else if (item2.y - item.y > Mathf.Epsilon) + { + list.Add(item); + list.Add(item2); + } + } + m_edges = list; + } + + public void DrawGizmos() + { + Gizmos.color = Color; + for (int i = 0; i < m_edges.Count; i++) + { + Gizmos.DrawSphere(m_edges[i], 0.2f); + } + for (int j = 0; j < m_edges.Count - 1; j++) + { + Gizmos.DrawLine(m_edges[j], m_edges[j + 1]); + } + } +} diff --git a/GameCode/PlayLineAnimation.cs b/GameCode/PlayLineAnimation.cs new file mode 100644 index 0000000..01cea4d --- /dev/null +++ b/GameCode/PlayLineAnimation.cs @@ -0,0 +1,29 @@ +using UnityEngine; + +public class PlayLineAnimation : MonoBehaviour +{ + private LineEffect lineEffect; + + public AnimationCurve offsetCurve; + + public float offsetSpeed = 1f; + + public AnimationCurve widthCurve; + + public float widthSpeed = 1f; + + private void Start() + { + lineEffect = GetComponent<LineEffect>(); + } + + public void PlayOffset() + { + lineEffect.PlayAnim(LineEffect.AnimType.Offset, offsetCurve, offsetSpeed); + } + + public void PlayWidth() + { + lineEffect.PlayAnim(LineEffect.AnimType.Width, widthCurve, widthSpeed); + } +} diff --git a/GameCode/Player.cs b/GameCode/Player.cs new file mode 100644 index 0000000..d912f63 --- /dev/null +++ b/GameCode/Player.cs @@ -0,0 +1,153 @@ +using System; +using ExitGames.Client.Photon; +using Photon.Pun; +using UnityEngine; + +public class Player : MonoBehaviour +{ + public int playerID; + + public int teamID; + + [HideInInspector] + public CharacterData data; + + public PlayerSkinBank colors; + + private void Awake() + { + data = GetComponent<CharacterData>(); + } + + private void Start() + { + if (!data.view.IsMine) + { + ReadPlayerID(); + ReadTeamID(); + PlayerAssigner.instance.OtherPlayerWasCreated(); + } + else + { + int num = 0; + if (!PhotonNetwork.OfflineMode) + { + try + { + num = 0; + PlayerFace playerFace = CharacterCreatorHandler.instance.selectedPlayerFaces[num]; + data.view.RPC("RPCA_SetFace", RpcTarget.All, playerFace.eyeID, playerFace.eyeOffset, playerFace.mouthID, playerFace.mouthOffset, playerFace.detailID, playerFace.detailOffset, playerFace.detail2ID, playerFace.detail2Offset); + } + catch + { + } + } + else if (GM_ArmsRace.instance != null) + { + GM_ArmsRace instance = GM_ArmsRace.instance; + instance.StartGameAction = (Action)Delegate.Combine(instance.StartGameAction, new Action(GetFaceOffline)); + } + } + PlayerManager.instance.PlayerJoined(this); + } + + public void GetFaceOffline() + { + PlayerFace playerFace = CharacterCreatorHandler.instance.selectedPlayerFaces[playerID]; + data.view.RPC("RPCA_SetFace", RpcTarget.All, playerFace.eyeID, playerFace.eyeOffset, playerFace.mouthID, playerFace.mouthOffset, playerFace.detailID, playerFace.detailOffset, playerFace.detail2ID, playerFace.detail2Offset); + } + + [PunRPC] + public void RPCA_SetFace(int eyeID, Vector2 eyeOffset, int mouthID, Vector2 mouthOffset, int detailID, Vector2 detailOffset, int detail2ID, Vector2 detail2Offset) + { + PlayerFace face = PlayerFace.CreateFace(eyeID, eyeOffset, mouthID, mouthOffset, detailID, detailOffset, detail2ID, detail2Offset); + GetComponentInChildren<CharacterCreatorItemEquipper>().EquipFace(face); + } + + internal void Call_AllGameFeel(Vector2 vector2) + { + data.view.RPC("RPCA_AllGameFeel", RpcTarget.All, vector2); + } + + [PunRPC] + internal void RPCA_AllGameFeel(Vector2 vector2) + { + GamefeelManager.instance.AddGameFeel(vector2); + } + + public void AssignPlayerID(int ID) + { + playerID = ID; + SetColors(); + if (!PhotonNetwork.OfflineMode) + { + Hashtable customProperties = PhotonNetwork.LocalPlayer.CustomProperties; + if (customProperties.ContainsKey("PlayerID")) + { + customProperties["PlayerID"] = playerID; + } + else + { + customProperties.Add("PlayerID", playerID); + } + PhotonNetwork.LocalPlayer.SetCustomProperties(customProperties); + } + } + + internal float GetRadius() + { + return 5f; + } + + private void ReadPlayerID() + { + if (!PhotonNetwork.OfflineMode) + { + playerID = (int)data.view.Owner.CustomProperties["PlayerID"]; + SetColors(); + } + } + + public void AssignTeamID(int ID) + { + teamID = ID; + if (!PhotonNetwork.OfflineMode) + { + Hashtable customProperties = PhotonNetwork.LocalPlayer.CustomProperties; + if (customProperties.ContainsKey("TeamID")) + { + customProperties["TeamID"] = playerID; + } + else + { + customProperties.Add("TeamID", teamID); + } + PhotonNetwork.LocalPlayer.SetCustomProperties(customProperties); + } + } + + private void ReadTeamID() + { + if (!PhotonNetwork.OfflineMode) + { + teamID = (int)data.view.Owner.CustomProperties["TeamID"]; + } + } + + public void SetColors() + { + SetTeamColor.TeamColorThis(base.gameObject, PlayerSkinBank.GetPlayerSkinColors(playerID)); + } + + public PlayerSkin GetTeamColors() + { + return PlayerSkinBank.GetPlayerSkinColors(playerID); + } + + internal void FullReset() + { + data.weaponHandler.NewGun(); + data.stats.ResetStats(); + data.block.ResetStats(); + } +} diff --git a/GameCode/PlayerAI.cs b/GameCode/PlayerAI.cs new file mode 100644 index 0000000..f7a3d38 --- /dev/null +++ b/GameCode/PlayerAI.cs @@ -0,0 +1,119 @@ +using UnityEngine; + +public class PlayerAI : MonoBehaviour +{ + private float range = 6f; + + private CharacterData data; + + private GeneralInput input; + + private Vector3 moveDir = Vector3.zero; + + private Vector3 aimDir = Vector3.zero; + + private Vector3 targetPos; + + private Player target; + + private bool canSeeTarget; + + private float untilNextDataUpdate; + + private float getRandomTargetPosCounter; + + private bool isShooting; + + private float distanceToTarget = 5f; + + private void Start() + { + data = GetComponentInParent<CharacterData>(); + input = data.input; + } + + private void Update() + { + target = PlayerManager.instance.GetOtherPlayer(data.player); + untilNextDataUpdate -= TimeHandler.deltaTime; + if (!target) + { + return; + } + canSeeTarget = PlayerManager.instance.CanSeePlayer(base.transform.position, target).canSee; + input.ResetInput(); + if (!canSeeTarget) + { + getRandomTargetPosCounter -= TimeHandler.deltaTime; + if (getRandomTargetPosCounter < 0f) + { + getRandomTargetPosCounter = Random.Range(0.5f, 2f); + GetRandomPos(); + } + } + if (untilNextDataUpdate <= 0f) + { + if (Random.value < 0.25f / Mathf.Clamp(distanceToTarget * 0.1f, 0.1f, 10f) && canSeeTarget) + { + input.shieldWasPressed = true; + } + if (Random.value < 0.4f && canSeeTarget) + { + isShooting = true; + } + else + { + isShooting = false; + } + if (Random.value < 0.2f || data.isWallGrab) + { + input.jumpWasPressed = true; + } + untilNextDataUpdate = Random.Range(0f, 0.25f); + UpdateData(); + } + input.shootIsPressed = isShooting; + input.shootWasPressed = isShooting; + input.aimDirection = aimDir; + input.direction = moveDir; + } + + private void GetRandomPos() + { + Vector3 vector = Vector3.zero; + int num = 200; + while (vector == Vector3.zero && num > 0) + { + num--; + Vector3 vector2 = base.transform.position + Vector3.up * 5f + (Vector3)Random.insideUnitCircle * 15f; + if (data.ThereIsGroundBelow(vector2, 8f)) + { + vector = vector2; + } + } + targetPos = vector; + } + + private void UpdateData() + { + if (canSeeTarget) + { + targetPos = target.transform.position; + } + distanceToTarget = Vector3.Distance(base.transform.position, target.transform.position); + aimDir = (targetPos - base.transform.position).normalized; + moveDir = aimDir; + if (moveDir.x > 0f) + { + moveDir.x = 1f; + } + if (moveDir.x < 0f) + { + moveDir.x = -1f; + } + if (canSeeTarget && distanceToTarget < range && data.ThereIsGroundBelow(base.transform.position, 10f)) + { + moveDir = Vector3.zero; + } + } +} diff --git a/GameCode/PlayerAIDavid.cs b/GameCode/PlayerAIDavid.cs new file mode 100644 index 0000000..bb0b654 --- /dev/null +++ b/GameCode/PlayerAIDavid.cs @@ -0,0 +1,86 @@ +using System.Collections.Generic; +using Landfall.AI; +using UnityEngine; + +public class PlayerAIDavid : MonoBehaviour +{ + public static int[] topology = new int[4] { 2, 10, 16, 5 }; + + [SerializeField] + private bool m_useWeights; + + [SerializeField] + private WeightDataAsset m_weightData; + + private PlayerAPI m_api; + + private NeuralNet m_neuralNet; + + private double[] m_cachedInput; + + private float m_startTime; + + private Vector2 m_movement = Vector2.zero; + + private float m_aiTimer; + + private void Awake() + { + m_api = GetComponentInParent<PlayerAPI>(); + m_cachedInput = new double[2]; + m_neuralNet = new NeuralNet(topology); + if (m_weightData != null && m_useWeights) + { + m_neuralNet.SetWeights(m_weightData.m_weightDatas[m_weightData.m_weightDatas.Count - 1].m_weights); + } + m_startTime = Time.time + 0.8f; + } + + public void SetWeights(double[] weights) + { + m_neuralNet.SetWeights(new List<double>(weights)); + } + + public void SetWeights(List<double> weights) + { + m_neuralNet.SetWeights(weights); + } + + private void Update() + { + if (Time.time < m_startTime) + { + return; + } + if (m_aiTimer >= 0.1f) + { + m_aiTimer -= 0.1f; + Vector3 vector = m_api.OtherPlayerPosition() - m_api.PlayerPosition(); + m_cachedInput[0] = vector.x; + m_cachedInput[1] = vector.y; + m_neuralNet.FeedForward(m_cachedInput, 1.0); + double[] results = m_neuralNet.GetResults(); + m_api.SetAimDirection(new Vector2((float)results[3], (float)results[4])); + if (results[0] > 0.5) + { + m_api.Jump(); + } + if (results[1] > 0.5) + { + m_api.Attack(); + } + Vector2 zero = Vector2.zero; + if (results[2] > 0.5) + { + zero.x = 1f; + } + else if (results[2] < -0.5) + { + zero.x = -1f; + } + m_movement = zero; + } + m_api.Move(m_movement); + m_aiTimer += TimeHandler.deltaTime; + } +} diff --git a/GameCode/PlayerAIMinion.cs b/GameCode/PlayerAIMinion.cs new file mode 100644 index 0000000..8aea87b --- /dev/null +++ b/GameCode/PlayerAIMinion.cs @@ -0,0 +1,63 @@ +using UnityEngine; + +public class PlayerAIMinion : MonoBehaviour +{ + public AnimationCurve m_AimCompensastionCurve; + + public float range = 5f; + + private PlayerAPI api; + + private Vector2 moveDirection; + + private void Start() + { + api = GetComponentInParent<PlayerAPI>(); + moveDirection = api.data.master.data.aimDirection; + if (moveDirection.x > 0.5f) + { + moveDirection.x = 1f; + } + else if (moveDirection.x < -0.5f) + { + moveDirection.x = -1f; + } + else + { + moveDirection.x = 0f; + } + moveDirection.y = 0f; + base.transform.root.gameObject.AddComponent<RemoveAfterSeconds>().seconds = 4f; + } + + private void Update() + { + Player otherPlayer = PlayerManager.instance.GetOtherPlayer(api.data.master); + api.Move(moveDirection); + if (api.data.isWallGrab) + { + api.Jump(); + } + if (!api.data.isGrounded) + { + api.Jump(); + } + if ((bool)otherPlayer) + { + api.SetAimDirection(GetAimDirForHitting(otherPlayer.transform.position)); + if (PlayerManager.instance.CanSeePlayer(base.transform.position, otherPlayer).canSee && Vector2.Distance(base.transform.position, otherPlayer.transform.position) < range) + { + api.Attack(); + } + } + } + + private Vector2 GetAimDirForHitting(Vector3 point) + { + Vector3 vector = point - base.transform.position; + api.SetAimDirection(vector); + api.GetMyBullet(); + float time = Mathf.Abs(point.x - base.transform.position.x); + return point + Vector3.up * m_AimCompensastionCurve.Evaluate(time) - base.transform.position; + } +} diff --git a/GameCode/PlayerAIPetter.cs b/GameCode/PlayerAIPetter.cs new file mode 100644 index 0000000..0c235f5 --- /dev/null +++ b/GameCode/PlayerAIPetter.cs @@ -0,0 +1,66 @@ +using UnityEngine; + +public class PlayerAIPetter : MonoBehaviour +{ + private PlayerAPI api; + + public LayerMask m_layer; + + public AnimationCurve aimCurve; + + public float m_shootRandom = 0.9f; + + public float m_predDist = 1f; + + public float m_timeSinceGround = 0.1f; + + private BoxCollider2D m_collider; + + private void Start() + { + api = GetComponentInParent<PlayerAPI>(); + m_collider = api.GetComponentInChildren<BoxCollider2D>(); + } + + private void Update() + { + if ((double)Random.Range(0f, 1f) > 0.9) + { + api.Move(api.TowardsOtherPlayer() * -1f); + } + else + { + api.Move(api.TowardsOtherPlayer()); + } + PredictionHit(); + api.Attack(); + if ((double)Random.Range(0f, 1f) > 0.9) + { + api.Jump(); + } + AutoBlock(); + } + + private void AutoBlock() + { + foreach (BulletWrapper allBullet in api.GetAllBullets()) + { + RaycastHit2D raycastHit2D = Physics2D.Raycast(allBullet.projectileMovement.transform.position, ((Vector2)allBullet.projectileMovement.velocity).normalized, allBullet.velocity.magnitude * 5f * TimeHandler.deltaTime, m_layer); + if ((bool)raycastHit2D.transform && (!allBullet.projectileHit.ownPlayer || allBullet.projectileHit.ownPlayer != api.player) && raycastHit2D.transform.root == base.transform.root) + { + Debug.Log("BLICOK"); + api.Block(); + } + } + } + + private void PredictionHit() + { + if ((bool)api.GetOtherPlayer()) + { + float magnitude = (api.OtherPlayerPosition() - base.transform.position).magnitude; + Vector2 vector = api.GetOtherPlayer().data.playerVel.velocity * m_predDist * 0.1f * magnitude * 0.05f; + api.SetAimDirection(api.TowardsOtherPlayer() + Vector2.up * aimCurve.Evaluate(magnitude) + vector); + } + } +} diff --git a/GameCode/PlayerAIPhilip.cs b/GameCode/PlayerAIPhilip.cs new file mode 100644 index 0000000..25e6c79 --- /dev/null +++ b/GameCode/PlayerAIPhilip.cs @@ -0,0 +1,280 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +public class PlayerAIPhilip : MonoBehaviour +{ + private enum BattleMorale : byte + { + Blood, + Coward, + Defend + } + + private enum BattleBehaviour : byte + { + Attack, + HighGround, + MoveSegments + } + + private PlayerAPI m_PlayerAPI; + + private Player m_Enemy; + + private BattleMorale m_CurrentMorale; + + private BattleBehaviour m_CurrentBehaviour; + + private Vector2 m_Direction; + + private Vector2 m_TargetPos; + + private Vector2[] m_Boundaries; + + private Vector2[] m_Segments; + + private int m_CurrentSegment; + + private float m_Tick; + + private int m_BehaviourChangeTick; + + private int m_BehaviourTimeMin = 3; + + private int m_BehaviourTimeMax = 8; + + private float m_AttackDistance = 15f; + + private void Awake() + { + InitReferences(); + MakeBoundaries(); + NextBehaviour(); + } + + private void InitReferences() + { + m_PlayerAPI = GetComponentInParent<PlayerAPI>(); + } + + private void MakeBoundaries() + { + int num = 20; + int num2 = 35; + Vector2 vector = new Vector2(num2, num); + Vector2 vector2 = new Vector2(-num2, num); + Vector2 vector3 = new Vector2(num2, -num); + Vector2 vector4 = new Vector2(-num2, -num); + m_Boundaries = new Vector2[4] { vector, vector2, vector3, vector4 }; + m_Segments = new Vector2[4] + { + vector / 2f, + vector2 / 2f, + vector3 / 2f, + vector4 / 2f + }; + } + + private bool CheckForValidEnemy() + { + m_Enemy = m_PlayerAPI.GetOtherPlayer(); + return m_Enemy != null; + } + + private void Start() + { + CheckForValidEnemy(); + } + + private void Update() + { + if (CheckForValidEnemy()) + { + CheckMorale(); + CheckDirection(); + CheckGround(); + Move(); + Jump(); + DoAim(); + ShouldAttack(); + ShouldBlock(); + TickBehaviour(); + } + } + + private void SeedBehaviourChange() + { + m_BehaviourChangeTick = UnityEngine.Random.Range(m_BehaviourTimeMin, m_BehaviourTimeMax); + } + + private void TickBehaviour() + { + m_Tick += TimeHandler.deltaTime; + if (m_Tick >= (float)m_BehaviourChangeTick) + { + NextBehaviour(); + } + } + + private void NextBehaviour() + { + ResetTick(); + int length = Enum.GetValues(typeof(BattleBehaviour)).Length; + m_CurrentBehaviour = (BattleBehaviour)UnityEngine.Random.Range(0, length); + SeedBehaviourChange(); + CheckBehaviour(); + } + + private void ResetTick() + { + m_Tick = 0f; + } + + private void ShouldBlock() + { + if (CheckIncommingBullets()) + { + m_PlayerAPI.Block(); + } + } + + private bool CheckIncommingBullets() + { + Vector3 vector = m_PlayerAPI.PlayerPosition(); + Vector2 a = new Vector2(vector.x, vector.y); + float num = 1.5f; + List<BulletWrapper> allBullets = m_PlayerAPI.GetAllBullets(); + int count = allBullets.Count; + for (int i = 0; i < count; i++) + { + Vector2 vector2 = allBullets[i].projectileHit.transform.position; + float num2 = Vector2.Distance(a, vector2); + if (num2 <= num && Vector2.Distance(a, vector2 + allBullets[i].velocity.normalized) < num2) + { + return true; + } + } + return false; + } + + private void ShouldAttack() + { + if (CanSee() && Vector3.Distance(m_PlayerAPI.PlayerPosition(), m_PlayerAPI.OtherPlayerPosition()) <= m_AttackDistance) + { + m_PlayerAPI.Attack(); + } + } + + private bool CanSee() + { + Vector2 vector = m_PlayerAPI.TowardsOtherPlayer(); + Vector3 vector2 = new Vector3(vector.x, vector.y, 0f); + vector2.Normalize(); + Collider2D collider = Physics2D.Raycast(base.transform.position + vector2, vector2, 20f).collider; + if ((bool)collider && (bool)collider.GetComponent<Player>()) + { + return true; + } + return false; + } + + private void DoAim() + { + m_PlayerAPI.SetAimDirection(m_PlayerAPI.TowardsOtherPlayer() + m_PlayerAPI.GetOtherPlayer().data.playerVel.velocity * 0.1f); + } + + private void Move() + { + m_PlayerAPI.Move(m_Direction); + } + + private void Jump() + { + m_PlayerAPI.Jump(); + } + + private void CheckGround() + { + Vector2 vector = m_PlayerAPI.PlayerPosition(); + if (!(vector.y < 0f) || m_PlayerAPI.CheckGroundBelow(vector + Vector2.down * 0.5f, 10f)) + { + return; + } + m_Direction = Vector2.right; + float num = float.PositiveInfinity; + RaycastHit2D raycastHit2D = Physics2D.Raycast(base.transform.position + Vector3.right, Vector2.right, 5f); + if ((bool)raycastHit2D.collider) + { + num = raycastHit2D.distance; + } + raycastHit2D = Physics2D.Raycast(base.transform.position + Vector3.left, Vector2.left, 5f); + if ((bool)raycastHit2D.collider) + { + if (raycastHit2D.distance < num) + { + m_Direction = Vector2.left; + } + } + else + { + m_Direction = Vector2.right; + } + } + + private void CheckDirection() + { + if (m_CurrentBehaviour == BattleBehaviour.Attack) + { + switch (m_CurrentMorale) + { + case BattleMorale.Blood: + m_Direction = m_PlayerAPI.TowardsOtherPlayer(); + break; + case BattleMorale.Coward: + m_Direction = -m_PlayerAPI.TowardsOtherPlayer(); + break; + case BattleMorale.Defend: + m_Direction = -m_PlayerAPI.TowardsOtherPlayer(); + break; + } + } + else + { + Vector3 vector = m_PlayerAPI.PlayerPosition(); + Vector2 vector2 = new Vector2(vector.x, vector.y); + m_Direction = m_TargetPos - vector2; + } + } + + private void CheckBehaviour() + { + switch (m_CurrentBehaviour) + { + case BattleBehaviour.HighGround: + m_TargetPos = m_Segments[0]; + break; + case BattleBehaviour.MoveSegments: + { + int max = m_Segments.Length; + int num; + for (num = UnityEngine.Random.Range(0, max); num == m_CurrentSegment; num = UnityEngine.Random.Range(0, max)) + { + } + m_CurrentSegment = num; + m_TargetPos = m_Segments[m_CurrentSegment]; + break; + } + case BattleBehaviour.Attack: + break; + } + } + + private void CheckMorale() + { + if (m_PlayerAPI.CanShoot()) + { + m_CurrentMorale = BattleMorale.Blood; + } + } +} diff --git a/GameCode/PlayerAIWilhelm.cs b/GameCode/PlayerAIWilhelm.cs new file mode 100644 index 0000000..b71a530 --- /dev/null +++ b/GameCode/PlayerAIWilhelm.cs @@ -0,0 +1,20 @@ +using UnityEngine; + +public class PlayerAIWilhelm : MonoBehaviour +{ + private PlayerAPI api; + + private void Start() + { + api = GetComponentInParent<PlayerAPI>(); + } + + private void Update() + { + api.Move(api.TowardsOtherPlayer()); + api.SetAimDirection(api.TowardsOtherPlayer() + api.GetOtherPlayer().data.playerVel.velocity * 0.1f); + api.Attack(); + api.Jump(); + api.Block(); + } +} diff --git a/GameCode/PlayerAIZorro.cs b/GameCode/PlayerAIZorro.cs new file mode 100644 index 0000000..c475f3f --- /dev/null +++ b/GameCode/PlayerAIZorro.cs @@ -0,0 +1,208 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class PlayerAIZorro : MonoBehaviour +{ + public AnimationCurve m_AimCompensastionCurve; + + public LayerMask m_MapMask; + + public LayerMask m_PlayerMask; + + private PlayerAPI api; + + private Camera m_camera; + + private int framesSinceShot; + + private Vector3[] surfacesToHideOn; + + private Vector3 m_CurrentHidePos; + + private float tiemSpentOverDeath; + + private float timeSinceCouldShoot; + + private void Start() + { + api = GetComponentInParent<PlayerAPI>(); + m_camera = Camera.main; + HealthHandler healthHandler = api.player.data.healthHandler; + healthHandler.delayedReviveAction = (Action)Delegate.Combine(healthHandler.delayedReviveAction, new Action(Init)); + } + + public void Init() + { + StopAllCoroutines(); + BakeMapSurfaces(); + StartCoroutine(GetNewPos()); + } + + private void Update() + { + framesSinceShot++; + if (api.CanShoot()) + { + timeSinceCouldShoot += TimeHandler.deltaTime; + } + else + { + timeSinceCouldShoot = 0f; + } + Vector3 vector = api.OtherPlayerPosition() + (Vector3)api.GetOtherPlayer().data.playerVel.velocity * Vector3.Distance(base.transform.position, api.OtherPlayerPosition()) * 0.01f + Vector3.down * api.GetOtherPlayer().data.playerVel.velocity.y * Vector3.Distance(base.transform.position, api.OtherPlayerPosition()) * 0.005f; + bool flag = false; + if (Physics2D.Raycast(base.transform.position, Vector3.down, 18f, m_MapMask).transform == null) + { + flag = false; + tiemSpentOverDeath += TimeHandler.deltaTime; + } + else + { + flag = true; + tiemSpentOverDeath = 0f; + } + if (api.CanBlock() && Vector3.Distance(base.transform.position, api.OtherPlayerPosition()) > 5f && (flag || tiemSpentOverDeath < 0.25f)) + { + api.Move(vector - base.transform.position + new Vector3(Mathf.PerlinNoise(Time.time, 0f) * 5f * Mathf.Sin(Time.time * 2f), 0f, 0f)); + } + else + { + api.Move(m_CurrentHidePos - base.transform.position + new Vector3(Mathf.PerlinNoise(Time.time, 0f) * 8f * Mathf.Sin(Time.time * 3f), 0f, 0f)); + } + api.Jump(); + ShootAt(vector); + MakeSureToBlock(); + } + + public void MakeSureToBlock() + { + BulletWrapper[] array = api.GetAllBullets().ToArray(); + for (int i = 0; i < array.Length; i++) + { + float num = Vector3.Distance(array[i].projectileMovement.transform.position, base.transform.position); + float num2 = Vector3.Angle(array[i].velocity.normalized, base.transform.position - array[i].projectileMovement.transform.position); + if (num < 1.3f && num2 < 65f && framesSinceShot >= 4) + { + api.Block(); + } + } + } + + public BulletWrapper GetMostDangerousBullet(BulletWrapper[] bullets, out bool exsists) + { + float num = 999999f; + int num2 = -1; + for (int i = 0; i < bullets.Length; i++) + { + float num3 = Vector3.Distance(bullets[i].projectileMovement.transform.position, base.transform.position); + if (num3 < num && num3 < 5f) + { + num = num3; + num2 = i; + } + } + if (num2 != -1) + { + exsists = true; + return bullets[num2]; + } + exsists = false; + return new BulletWrapper(); + } + + public BulletWrapper[] GetAllBulletsComingAtMe() + { + List<BulletWrapper> list = new List<BulletWrapper>(); + BulletWrapper[] array = api.GetAllBullets().ToArray(); + for (int i = 0; i < array.Length; i++) + { + if (Vector3.Angle(array[i].velocity.normalized, base.transform.position - array[i].projectileMovement.transform.position) < 35f) + { + list.Add(array[i]); + } + } + return list.ToArray(); + } + + public void ShootAt(Vector3 point) + { + api.SetAimDirection(GetAimDirForHitting(point)); + api.Attack(); + } + + private Vector2 GetAimDirForHitting(Vector3 point) + { + Vector3 vector = point - base.transform.position; + api.SetAimDirection(vector); + api.GetMyBullet(); + float time = Mathf.Abs(point.x - base.transform.position.x); + Vector3 vector2 = point + Vector3.up * m_AimCompensastionCurve.Evaluate(time); + Debug.DrawLine(point, vector2, Color.red, 0.2f); + return vector2 - base.transform.position; + } + + public void BakeMapSurfaces() + { + Vector2 vector = m_camera.ViewportToWorldPoint(new Vector3(1f, 1f)); + Vector2 vector2 = m_camera.ViewportToWorldPoint(new Vector3(0f, 1f)); + Vector2 vector3 = m_camera.ViewportToWorldPoint(new Vector3(1f, 0f)); + Vector2 vector4 = m_camera.ViewportToWorldPoint(new Vector3(0f, 0f)); + Vector3 v = m_camera.ViewportToWorldPoint(new Vector3(0.5f, 0.5f)); + Debug.DrawLine(vector, v, Color.cyan); + Debug.DrawLine(vector2, v, Color.cyan); + Debug.DrawLine(vector3, v, Color.cyan); + Debug.DrawLine(vector4, v, Color.cyan); + List<Vector3> list = new List<Vector3>(); + for (int i = 0; i < 360; i++) + { + for (int j = 0; j < 40; j++) + { + RaycastHit2D raycastHit2D = Physics2D.Raycast(new Vector2(Mathf.Lerp(vector2.x, vector.x, (float)i / 359f), Mathf.Lerp(vector3.y, vector.y, (float)j / 39f)), Vector3.down, 6f, m_MapMask); + if ((bool)raycastHit2D.transform) + { + list.Add(raycastHit2D.point); + } + } + } + List<Vector3> list2 = new List<Vector3>(); + for (int k = 0; k < list.Count; k++) + { + if (Physics2D.OverlapCircleAll(list[k] + Vector3.up * 0.26f, 0.1f, m_MapMask).Length != 0) + { + list2.Add(list[k]); + } + } + for (int l = 0; l < list2.Count; l++) + { + list.Remove(list2[l]); + } + Debug.Log("Points: " + list.Count); + for (int m = 0; m < list.Count; m++) + { + Debug.DrawLine(list[m], list[m] + Vector3.up * 0.2f, Color.magenta, 1000f); + } + surfacesToHideOn = list.ToArray(); + } + + private IEnumerator GetNewPos() + { + while (true) + { + m_CurrentHidePos = GetPosAwayFrom(api.OtherPlayerPosition()); + yield return new WaitForSeconds(4f); + } + } + + public Vector3 GetPosAwayFrom(Vector3 point) + { + Vector3 result; + do + { + result = surfacesToHideOn[UnityEngine.Random.Range(0, surfacesToHideOn.Length)]; + } + while (!(Mathf.Abs(result.x - point.x) > 13f)); + return result; + } +} diff --git a/GameCode/PlayerAPI.cs b/GameCode/PlayerAPI.cs new file mode 100644 index 0000000..3edf9c5 --- /dev/null +++ b/GameCode/PlayerAPI.cs @@ -0,0 +1,172 @@ +using System.Collections.Generic; +using UnityEngine; + +public class PlayerAPI : MonoBehaviour +{ + public Player player; + + public CharacterData data; + + private GeneralInput input; + + private bool movedThisFrame; + + private bool attackedThisFrame; + + private bool blockedThisFrame; + + private void Awake() + { + player = GetComponent<Player>(); + data = GetComponent<CharacterData>(); + input = GetComponent<GeneralInput>(); + } + + public void Move(Vector2 direction) + { + direction = Vector2.ClampMagnitude(direction, 1f); + movedThisFrame = true; + data.input.direction = direction; + } + + public void Jump() + { + data.jump.Jump(); + } + + public void Attack() + { + attackedThisFrame = true; + data.input.shootWasPressed = true; + data.input.shootIsPressed = true; + } + + public void Block() + { + data.input.shieldWasPressed = true; + } + + public void SetAimDirection(Vector2 direction) + { + data.input.aimDirection = direction; + } + + public void AimForOtherPlayer() + { + Player otherPlayer = PlayerManager.instance.GetOtherPlayer(player); + if ((bool)otherPlayer) + { + data.input.aimDirection = otherPlayer.transform.position - base.transform.position; + } + } + + public Vector2 TowardsOtherPlayer() + { + if (PlayerManager.instance.players.Count < 2) + { + return Vector2.zero; + } + return PlayerManager.instance.GetOtherPlayer(player).transform.position - base.transform.position; + } + + public RaycastHit2D RayCastDirection(Vector2 direction, float distance) + { + return Physics2D.Raycast(base.transform.position, direction, distance); + } + + public bool CheckGroundBelow(Vector2 pos, float range) + { + return data.ThereIsGroundBelow(pos, range); + } + + public bool CanBlock() + { + return !data.block.IsOnCD(); + } + + public Player GetOtherPlayer() + { + return PlayerManager.instance.GetOtherPlayer(player); + } + + public Vector3 OtherPlayerPosition() + { + Player otherPlayer = PlayerManager.instance.GetOtherPlayer(player); + if ((bool)otherPlayer) + { + return otherPlayer.transform.position; + } + return Vector3.zero; + } + + public Vector3 PlayerPosition() + { + return base.transform.position; + } + + public List<BulletWrapper> GetAllBullets() + { + List<BulletWrapper> list = new List<BulletWrapper>(); + ProjectileHit[] array = Object.FindObjectsOfType<ProjectileHit>(); + for (int i = 0; i < array.Length; i++) + { + BulletWrapper bulletWrapper = new BulletWrapper(); + bulletWrapper.projectileHit = array[i].GetComponent<ProjectileHit>(); + bulletWrapper.projectileMovement = array[i].GetComponent<MoveTransform>(); + bulletWrapper.damage = bulletWrapper.projectileHit.damage; + bulletWrapper.velocity = bulletWrapper.projectileMovement.velocity; + list.Add(bulletWrapper); + } + return list; + } + + public SpawnedAttack[] GetAllSpawnedAttacks() + { + return Object.FindObjectsOfType<SpawnedAttack>(); + } + + public bool CanShoot() + { + return player.data.weaponHandler.gun.IsReady(); + } + + public BulletWrapper GetMyBullet() + { + BulletWrapper bulletWrapper = new BulletWrapper(); + GameObject objectToSpawn = player.data.weaponHandler.gun.projectiles[0].objectToSpawn; + MoveTransform component = objectToSpawn.GetComponent<MoveTransform>(); + ProjectileHit component2 = objectToSpawn.GetComponent<ProjectileHit>(); + bulletWrapper.projectileMovement = component; + bulletWrapper.projectileHit = component2; + bulletWrapper.damage = component2.damage; + bulletWrapper.velocity = player.data.aimDirection.normalized * component.localForce.magnitude + component.worldForce; + return bulletWrapper; + } + + private void Update() + { + if (blockedThisFrame) + { + blockedThisFrame = false; + } + else + { + data.input.shieldWasPressed = false; + } + if (movedThisFrame) + { + movedThisFrame = false; + } + else + { + data.input.direction = Vector3.zero; + } + if (attackedThisFrame) + { + attackedThisFrame = false; + return; + } + data.input.shootWasPressed = false; + data.input.shootIsPressed = false; + } +} diff --git a/GameCode/PlayerActions.cs b/GameCode/PlayerActions.cs new file mode 100644 index 0000000..8c6d6f1 --- /dev/null +++ b/GameCode/PlayerActions.cs @@ -0,0 +1,131 @@ +using System; +using InControl; + +public class PlayerActions : PlayerActionSet +{ + public PlayerAction Fire; + + public PlayerAction Block; + + public PlayerAction Jump; + + public PlayerAction Left; + + public PlayerAction Right; + + public PlayerAction Up; + + public PlayerAction Down; + + public PlayerTwoAxisAction Move; + + public PlayerTwoAxisAction Aim; + + public PlayerAction AimLeft; + + public PlayerAction AimRight; + + public PlayerAction AimUp; + + public PlayerAction AimDown; + + public PlayerAction Start; + + public PlayerActions() + { + Fire = CreatePlayerAction("Fire"); + Start = CreatePlayerAction("Start"); + Block = CreatePlayerAction("Block"); + Jump = CreatePlayerAction("Jump"); + Left = CreatePlayerAction("Move Left"); + Right = CreatePlayerAction("Move Right"); + Up = CreatePlayerAction("Move Up"); + Down = CreatePlayerAction("Move Down"); + AimLeft = CreatePlayerAction("Aim Left"); + AimRight = CreatePlayerAction("Aim Right"); + AimUp = CreatePlayerAction("Aim Up"); + AimDown = CreatePlayerAction("Aim Down"); + Move = CreateTwoAxisPlayerAction(Left, Right, Down, Up); + Aim = CreateTwoAxisPlayerAction(AimLeft, AimRight, AimDown, AimUp); + } + + public static PlayerActions CreateWithKeyboardBindings() + { + PlayerActions playerActions = new PlayerActions(); + playerActions.Fire.AddDefaultBinding(Mouse.LeftButton); + playerActions.Block.AddDefaultBinding(Mouse.RightButton); + playerActions.Jump.AddDefaultBinding(Key.Space); + playerActions.Up.AddDefaultBinding(Key.W); + playerActions.Down.AddDefaultBinding(Key.S); + playerActions.Left.AddDefaultBinding(Key.A); + playerActions.Right.AddDefaultBinding(Key.D); + playerActions.Start.AddDefaultBinding(Key.Return); + playerActions.ListenOptions.IncludeUnknownControllers = true; + playerActions.ListenOptions.MaxAllowedBindings = 4u; + playerActions.ListenOptions.UnsetDuplicateBindingsOnSet = true; + playerActions.ListenOptions.OnBindingFound = delegate(PlayerAction action, BindingSource binding) + { + if (binding == new KeyBindingSource(Key.Escape)) + { + action.StopListeningForBinding(); + return false; + } + return true; + }; + BindingListenOptions bindingListenOptions = playerActions.ListenOptions; + bindingListenOptions.OnBindingAdded = (Action<PlayerAction, BindingSource>)Delegate.Combine(bindingListenOptions.OnBindingAdded, (Action<PlayerAction, BindingSource>)delegate(PlayerAction action, BindingSource binding) + { + Debug.Log("Binding added... " + binding.DeviceName + ": " + binding.Name); + }); + BindingListenOptions bindingListenOptions2 = playerActions.ListenOptions; + bindingListenOptions2.OnBindingRejected = (Action<PlayerAction, BindingSource, BindingSourceRejectionType>)Delegate.Combine(bindingListenOptions2.OnBindingRejected, (Action<PlayerAction, BindingSource, BindingSourceRejectionType>)delegate(PlayerAction action, BindingSource binding, BindingSourceRejectionType reason) + { + Debug.Log("Binding rejected... " + reason); + }); + return playerActions; + } + + public static PlayerActions CreateWithControllerBindings() + { + PlayerActions playerActions = new PlayerActions(); + playerActions.Fire.AddDefaultBinding(InputControlType.Action3); + playerActions.Fire.AddDefaultBinding(InputControlType.RightTrigger); + playerActions.Block.AddDefaultBinding(InputControlType.Action2); + playerActions.Block.AddDefaultBinding(InputControlType.LeftTrigger); + playerActions.Jump.AddDefaultBinding(InputControlType.Action1); + playerActions.Jump.AddDefaultBinding(InputControlType.LeftBumper); + playerActions.Jump.AddDefaultBinding(InputControlType.RightBumper); + playerActions.Start.AddDefaultBinding(InputControlType.Start); + playerActions.Left.AddDefaultBinding(InputControlType.LeftStickLeft); + playerActions.Right.AddDefaultBinding(InputControlType.LeftStickRight); + playerActions.Up.AddDefaultBinding(InputControlType.LeftStickUp); + playerActions.Down.AddDefaultBinding(InputControlType.LeftStickDown); + playerActions.AimLeft.AddDefaultBinding(InputControlType.RightStickLeft); + playerActions.AimRight.AddDefaultBinding(InputControlType.RightStickRight); + playerActions.AimUp.AddDefaultBinding(InputControlType.RightStickUp); + playerActions.AimDown.AddDefaultBinding(InputControlType.RightStickDown); + playerActions.ListenOptions.IncludeUnknownControllers = true; + playerActions.ListenOptions.MaxAllowedBindings = 4u; + playerActions.ListenOptions.UnsetDuplicateBindingsOnSet = true; + playerActions.ListenOptions.OnBindingFound = delegate(PlayerAction action, BindingSource binding) + { + if (binding == new KeyBindingSource(Key.Escape)) + { + action.StopListeningForBinding(); + return false; + } + return true; + }; + BindingListenOptions bindingListenOptions = playerActions.ListenOptions; + bindingListenOptions.OnBindingAdded = (Action<PlayerAction, BindingSource>)Delegate.Combine(bindingListenOptions.OnBindingAdded, (Action<PlayerAction, BindingSource>)delegate(PlayerAction action, BindingSource binding) + { + Debug.Log("Binding added... " + binding.DeviceName + ": " + binding.Name); + }); + BindingListenOptions bindingListenOptions2 = playerActions.ListenOptions; + bindingListenOptions2.OnBindingRejected = (Action<PlayerAction, BindingSource, BindingSourceRejectionType>)Delegate.Combine(bindingListenOptions2.OnBindingRejected, (Action<PlayerAction, BindingSource, BindingSourceRejectionType>)delegate(PlayerAction action, BindingSource binding, BindingSourceRejectionType reason) + { + Debug.Log("Binding rejected... " + reason); + }); + return playerActions; + } +} diff --git a/GameCode/PlayerAssigner.cs b/GameCode/PlayerAssigner.cs new file mode 100644 index 0000000..d4c4880 --- /dev/null +++ b/GameCode/PlayerAssigner.cs @@ -0,0 +1,220 @@ +using System.Collections; +using System.Collections.Generic; +using InControl; +using Photon.Pun; +using SoundImplementation; +using UnityEngine; + +public class PlayerAssigner : MonoBehaviour +{ + public GameObject player1AI; + + public GameObject player2AI; + + public static PlayerAssigner instance; + + public GameObject playerPrefab; + + public int maxPlayers = 4; + + public List<CharacterData> players = new List<CharacterData>(4); + + private bool playersCanJoin; + + private int playerIDToSet = -1; + + private int teamIDToSet = -1; + + private bool waitingForRegisterResponse; + + private bool hasCreatedLocalPlayer; + + private void Awake() + { + instance = this; + } + + internal void SetPlayersCanJoin(bool canJoin) + { + playersCanJoin = canJoin; + } + + private void Start() + { + InputManager.OnDeviceDetached += OnDeviceDetached; + } + + private void LateUpdate() + { + if (!playersCanJoin || players.Count >= maxPlayers || DevConsole.isTyping) + { + return; + } + if (Input.GetKeyDown(KeyCode.B) && !GameManager.lockInput) + { + StartCoroutine(CreatePlayer(null, isAI: true)); + } + if (Input.GetKey(KeyCode.Space)) + { + bool flag = true; + for (int i = 0; i < players.Count; i++) + { + if (players[i].playerActions.Device == null) + { + flag = false; + } + } + if (flag) + { + StartCoroutine(CreatePlayer(null)); + } + } + for (int j = 0; j < InputManager.ActiveDevices.Count; j++) + { + InputDevice inputDevice = InputManager.ActiveDevices[j]; + if (JoinButtonWasPressedOnDevice(inputDevice) && ThereIsNoPlayerUsingDevice(inputDevice)) + { + StartCoroutine(CreatePlayer(inputDevice)); + } + } + } + + private bool JoinButtonWasPressedOnDevice(InputDevice inputDevice) + { + if (!inputDevice.Action1.WasPressed && !inputDevice.Action2.WasPressed && !inputDevice.Action3.WasPressed) + { + return inputDevice.Action4.WasPressed; + } + return true; + } + + private CharacterData FindPlayerUsingDevice(InputDevice inputDevice) + { + int count = players.Count; + for (int i = 0; i < count; i++) + { + CharacterData characterData = players[i]; + if (characterData.playerActions.Device == inputDevice) + { + return characterData; + } + } + return null; + } + + public void ClearPlayers() + { + players.Clear(); + } + + private bool ThereIsNoPlayerUsingDevice(InputDevice inputDevice) + { + return FindPlayerUsingDevice(inputDevice) == null; + } + + private void OnDeviceDetached(InputDevice inputDevice) + { + CharacterData characterData = FindPlayerUsingDevice(inputDevice); + if (characterData != null) + { + RemovePlayer(characterData); + } + } + + [PunRPC] + public void RPCM_RequestTeamAndPlayerID(int askingPlayer) + { + int count = PlayerManager.instance.players.Count; + int num = ((count % 2 != 0) ? 1 : 0); + GetComponent<PhotonView>().RPC("RPC_ReturnPlayerAndTeamID", PhotonNetwork.CurrentRoom.GetPlayer(askingPlayer), count, num); + waitingForRegisterResponse = true; + } + + [PunRPC] + public void RPC_ReturnPlayerAndTeamID(int teamId, int playerID) + { + waitingForRegisterResponse = false; + playerIDToSet = playerID; + teamIDToSet = teamId; + } + + public void OtherPlayerWasCreated() + { + waitingForRegisterResponse = false; + } + + public IEnumerator CreatePlayer(InputDevice inputDevice, bool isAI = false) + { + if (waitingForRegisterResponse || (!PhotonNetwork.OfflineMode && hasCreatedLocalPlayer) || players.Count >= maxPlayers) + { + yield break; + } + if (!PhotonNetwork.OfflineMode && !PhotonNetwork.IsMasterClient) + { + GetComponent<PhotonView>().RPC("RPCM_RequestTeamAndPlayerID", RpcTarget.MasterClient, PhotonNetwork.LocalPlayer.ActorNumber); + waitingForRegisterResponse = true; + } + while (waitingForRegisterResponse) + { + yield return null; + } + if (!PhotonNetwork.OfflineMode) + { + if (PhotonNetwork.IsMasterClient) + { + playerIDToSet = PlayerManager.instance.players.Count; + teamIDToSet = ((playerIDToSet % 2 != 0) ? 1 : 0); + } + } + else + { + playerIDToSet = PlayerManager.instance.players.Count; + teamIDToSet = ((playerIDToSet % 2 != 0) ? 1 : 0); + } + hasCreatedLocalPlayer = true; + SoundPlayerStatic.Instance.PlayPlayerAdded(); + Vector3 position = Vector3.up * 100f; + CharacterData component = PhotonNetwork.Instantiate(playerPrefab.name, position, Quaternion.identity, 0).GetComponent<CharacterData>(); + if (isAI) + { + GameObject original = player1AI; + if (players.Count > 0) + { + original = player2AI; + } + component.GetComponent<CharacterData>().SetAI(); + Object.Instantiate(original, component.transform.position, component.transform.rotation, component.transform); + } + else + { + if (inputDevice != null) + { + component.input.inputType = GeneralInput.InputType.Controller; + component.playerActions = PlayerActions.CreateWithControllerBindings(); + } + else + { + component.input.inputType = GeneralInput.InputType.Keyboard; + component.playerActions = PlayerActions.CreateWithKeyboardBindings(); + } + component.playerActions.Device = inputDevice; + } + players.Add(component); + RegisterPlayer(component, teamIDToSet, playerIDToSet); + } + + private void RegisterPlayer(CharacterData player, int teamID, int playerID) + { + PlayerManager.RegisterPlayer(player.player); + player.player.AssignPlayerID(playerID); + player.player.AssignTeamID(teamID); + } + + private void RemovePlayer(CharacterData player) + { + } + + private void AssignPlayer(CharacterData player, InputDevice device) + { + } +} diff --git a/GameCode/PlayerAudioModifyers.cs b/GameCode/PlayerAudioModifyers.cs new file mode 100644 index 0000000..7f82b58 --- /dev/null +++ b/GameCode/PlayerAudioModifyers.cs @@ -0,0 +1,50 @@ +using System.Collections.Generic; +using UnityEngine; + +public class PlayerAudioModifyers : MonoBehaviour +{ + public List<AudioModifyer> modifyers = new List<AudioModifyer>(); + + public static List<CardAudioModifier> activeModifyer = new List<CardAudioModifier>(); + + public void AddToStack(CardAudioModifier mod) + { + int num = -1; + for (int i = 0; i < modifyers.Count; i++) + { + if (modifyers[i].modifier.stackName == mod.stackName) + { + num = i; + break; + } + } + if (num != -1) + { + modifyers[num].stacks++; + return; + } + AudioModifyer audioModifyer = new AudioModifyer(); + audioModifyer.modifier = new CardAudioModifier(); + audioModifyer.modifier.stackName = mod.stackName; + audioModifyer.modifier.stackType = mod.stackType; + audioModifyer.stacks = 1; + activeModifyer.Add(audioModifyer.modifier); + modifyers.Add(audioModifyer); + } + + public void SetStacks() + { + for (int i = 0; i < activeModifyer.Count; i++) + { + _ = activeModifyer[i].stackType; + _ = 1; + _ = activeModifyer[i].stackType; + } + for (int j = 0; j < modifyers.Count; j++) + { + _ = modifyers[j].modifier.stackType; + _ = 1; + _ = modifyers[j].modifier.stackType; + } + } +} diff --git a/GameCode/PlayerChat.cs b/GameCode/PlayerChat.cs new file mode 100644 index 0000000..61c9578 --- /dev/null +++ b/GameCode/PlayerChat.cs @@ -0,0 +1,87 @@ +using System.Collections; +using TMPro; +using UnityEngine; + +public class PlayerChat : MonoBehaviour +{ + public float spring = 15f; + + public float damper = 15f; + + public float impulse; + + public float targetScale; + + private TextMeshProUGUI messageText; + + private ScaleShake scaleShake; + + private float currentScale; + + private float vel; + + public Transform target; + + private Screenshaker shaker; + + private float sinceType; + + public float shakeAmount; + + public float shakeSpeed = 1f; + + private void Start() + { + messageText = target.GetComponentInChildren<TextMeshProUGUI>(); + shaker = target.GetComponentInChildren<Screenshaker>(); + target.transform.localScale = Vector3.zero; + } + + private void Update() + { + sinceType -= Time.unscaledDeltaTime; + if (sinceType < 0f) + { + targetScale = 0f; + } + else + { + targetScale = 1f; + } + vel = FRILerp.Lerp(vel, (targetScale - currentScale) * spring, damper); + currentScale += Time.unscaledDeltaTime * vel; + if (currentScale < 0f) + { + vel = 0f; + currentScale = 0f; + } + target.transform.localScale = Vector3.one * currentScale; + } + + public void Send(string message) + { + message = ChatFilter.instance.FilterMessage(message); + messageText.text = message; + if (sinceType > 0f) + { + vel += impulse; + } + sinceType = 2f + (float)message.Length * 0.05f; + targetScale = 1f; + if (message.ToUpper() == message) + { + StartCoroutine(ShakeOverTime(sinceType)); + } + } + + private IEnumerator ShakeOverTime(float t) + { + float a = t; + while (a > 0f) + { + shaker.OnUIGameFeel(shakeAmount * Random.insideUnitCircle); + a -= Time.unscaledDeltaTime * shakeSpeed; + yield return null; + } + } +} diff --git a/GameCode/PlayerCollision.cs b/GameCode/PlayerCollision.cs new file mode 100644 index 0000000..6055a69 --- /dev/null +++ b/GameCode/PlayerCollision.cs @@ -0,0 +1,152 @@ +using System; +using System.Collections; +using Photon.Pun; +using Sonigon; +using UnityEngine; + +public class PlayerCollision : MonoBehaviour +{ + [Header("Sounds")] + public SoundEvent soundBounce; + + [Header("Settings")] + public LayerMask mask; + + private Vector2 lastPos; + + public bool checkForGoThroughWall = true; + + private int ignoreWallFor; + + private Collider2D col; + + private CircleCollider2D cirCol; + + private PlayerVelocity vel; + + private CharacterData data; + + public Action<Vector2, Vector2, Player> collideWithPlayerAction; + + public float bounceTreshold = 1f; + + private bool isBounce; + + public void IgnoreWallForFrames(int frames) + { + ignoreWallFor = frames; + } + + private void Start() + { + data = GetComponent<CharacterData>(); + col = GetComponent<Collider2D>(); + cirCol = GetComponent<CircleCollider2D>(); + vel = GetComponent<PlayerVelocity>(); + } + + private void FixedUpdate() + { + if (checkForGoThroughWall && ignoreWallFor <= 0) + { + RaycastHit2D raycastHit2D = default(RaycastHit2D); + RaycastHit2D[] array = Physics2D.RaycastAll(lastPos, (Vector2)base.transform.position - lastPos, Vector2.Distance(base.transform.position, lastPos), mask); + for (int i = 0; i < array.Length; i++) + { + if (!(array[i].transform.root == base.transform.root)) + { + Debug.DrawLine(lastPos, array[i].point, Color.green, 1f); + if (!(Vector2.Angle(array[i].normal, (Vector2)base.transform.position - lastPos) < 90f) && (!raycastHit2D.transform || array[i].distance < raycastHit2D.distance)) + { + raycastHit2D = array[i]; + } + } + } + if ((bool)raycastHit2D) + { + base.transform.position = raycastHit2D.point + raycastHit2D.normal * 0.5f; + if (data.healthHandler.flyingFor > 0f) + { + DoBounce(raycastHit2D); + } + } + } + ignoreWallFor--; + lastPos = base.transform.position; + float num = cirCol.radius * base.transform.localScale.x; + float num2 = cirCol.radius * base.transform.localScale.x * 0.75f; + RaycastHit2D[] array2 = Physics2D.CircleCastAll(lastPos, num, (Vector2)base.transform.position - lastPos, Vector2.Distance(base.transform.position, lastPos), mask); + for (int j = 0; j < array2.Length; j++) + { + if (array2[j].transform.root == base.transform.root) + { + continue; + } + Vector2 vector = base.transform.position; + Vector2 point = array2[j].point; + float num3 = Vector2.Distance(vector, point); + Vector2 normalized = (vector - point).normalized; + float value = num + (0f - num3); + float value2 = num2 + (0f - num3); + value = Mathf.Clamp(value, 0f, 10f); + value2 = Mathf.Clamp(value2, 0f, 10f); + NetworkPhysicsObject component = array2[j].transform.GetComponent<NetworkPhysicsObject>(); + if ((bool)component) + { + component.Push(data); + } + if (vel.simulated || !vel.isKinematic) + { + vel.transform.position += (Vector3)normalized * value2; + if (Mathf.Abs(normalized.y) < 0.45f && Mathf.Abs(data.input.direction.x) > 0.1f && Vector3.Angle(data.input.direction, normalized) > 90f) + { + data.TouchWall(normalized, point); + } + vel.velocity += normalized * value * 10f * TimeHandler.timeScale; + vel.velocity -= vel.velocity * value * 1f * TimeHandler.timeScale; + } + Player componentInParent = array2[j].transform.GetComponentInParent<Player>(); + if (componentInParent != null && collideWithPlayerAction != null) + { + collideWithPlayerAction(point, value * normalized, componentInParent); + } + if (data.healthHandler.flyingFor > 0f) + { + DoBounce(array2[j]); + } + } + lastPos = base.transform.position; + } + + private void DoBounce(RaycastHit2D hit) + { + if (!(Vector2.Angle(data.playerVel.velocity, hit.normal) < 90f) && !isBounce && data.view.IsMine && data.playerVel.velocity.magnitude > bounceTreshold) + { + data.view.RPC("RPCADoBounce", RpcTarget.All, hit.normal, base.transform.position); + } + } + + [PunRPC] + private void RPCADoBounce(Vector2 hit, Vector3 playerPos) + { + base.transform.position = playerPos; + StartCoroutine(IDoBounce(Vector2.Reflect(data.playerVel.velocity, hit))); + SoundManager.Instance.Play(soundBounce, base.transform); + } + + public IEnumerator IDoBounce(Vector2 targetVel) + { + isBounce = true; + data.stunHandler.AddStun(0.2f); + data.healthHandler.CallTakeDamage(targetVel.normalized * 5f, base.transform.position); + GamefeelManager.instance.AddGameFeel(targetVel.normalized * 4f); + yield return new WaitForSeconds(0.25f); + data.playerVel.velocity = targetVel; + isBounce = false; + } + + private void OnDisable() + { + isBounce = false; + } +} diff --git a/GameCode/PlayerDoBlock.cs b/GameCode/PlayerDoBlock.cs new file mode 100644 index 0000000..5f14851 --- /dev/null +++ b/GameCode/PlayerDoBlock.cs @@ -0,0 +1,23 @@ +using Photon.Pun; +using UnityEngine; + +public class PlayerDoBlock : MonoBehaviour +{ + private CharacterData data; + + private SyncPlayerMovement sync; + + private void Start() + { + data = GetComponentInParent<CharacterData>(); + sync = GetComponentInParent<SyncPlayerMovement>(); + } + + public void DoBlock() + { + if (data.view.IsMine) + { + sync.SendBlock(BlockTrigger.BlockTriggerType.Default, firstBlock: true, dontSetCD: true); + } + } +} diff --git a/GameCode/PlayerDoJump.cs b/GameCode/PlayerDoJump.cs new file mode 100644 index 0000000..9d718be --- /dev/null +++ b/GameCode/PlayerDoJump.cs @@ -0,0 +1,18 @@ +using UnityEngine; + +public class PlayerDoJump : MonoBehaviour +{ + private PlayerJump jump; + + public float multiplier = 0.25f; + + private void Start() + { + jump = GetComponentInParent<PlayerJump>(); + } + + public void DoJump() + { + jump.Jump(forceJump: true, multiplier); + } +} diff --git a/GameCode/PlayerEffects.cs b/GameCode/PlayerEffects.cs new file mode 100644 index 0000000..c122706 --- /dev/null +++ b/GameCode/PlayerEffects.cs @@ -0,0 +1,10 @@ +using UnityEngine; + +public class PlayerEffects : MonoBehaviour +{ + public float lifeSteal; + + private void Start() + { + } +} diff --git a/GameCode/PlayerFace.cs b/GameCode/PlayerFace.cs new file mode 100644 index 0000000..f6e69f3 --- /dev/null +++ b/GameCode/PlayerFace.cs @@ -0,0 +1,84 @@ +using System; +using UnityEngine; + +[Serializable] +public class PlayerFace +{ + public int eyeID; + + public Vector2 eyeOffset; + + public int mouthID; + + public Vector2 mouthOffset; + + public int detailID; + + public Vector2 detailOffset; + + public int detail2ID; + + public Vector2 detail2Offset; + + public void LoadFace(string key) + { + eyeID = PlayerPrefs.GetInt("eyeID-" + key); + eyeOffset.x = PlayerPrefs.GetFloat("eyeOffsetX-" + key); + eyeOffset.y = PlayerPrefs.GetFloat("eyeOffsetY-" + key); + mouthID = PlayerPrefs.GetInt("mouthID-" + key); + mouthOffset.x = PlayerPrefs.GetFloat("mouthOffsetX-" + key); + mouthOffset.y = PlayerPrefs.GetFloat("mouthOffsetY-" + key); + detailID = PlayerPrefs.GetInt("detailID-" + key); + detailOffset.x = PlayerPrefs.GetFloat("detailOffsetX-" + key); + detailOffset.y = PlayerPrefs.GetFloat("detailOffsetY-" + key); + detail2ID = PlayerPrefs.GetInt("detail2ID-" + key); + detail2Offset.x = PlayerPrefs.GetFloat("detail2OffsetX-" + key); + detail2Offset.y = PlayerPrefs.GetFloat("detail2OffsetY-" + key); + } + + internal static PlayerFace CopyFace(PlayerFace currentPlayerFace) + { + return new PlayerFace + { + eyeID = currentPlayerFace.eyeID, + eyeOffset = currentPlayerFace.eyeOffset, + mouthID = currentPlayerFace.mouthID, + mouthOffset = currentPlayerFace.mouthOffset, + detailID = currentPlayerFace.detailID, + detailOffset = currentPlayerFace.detailOffset, + detail2ID = currentPlayerFace.detail2ID, + detail2Offset = currentPlayerFace.detail2Offset + }; + } + + internal static PlayerFace CreateFace(int eyeID, Vector2 eyeOffset, int mouthID, Vector2 mouthOffset, int detailID, Vector2 detailOffset, int detail2ID, Vector2 detail2Offset) + { + return new PlayerFace + { + eyeID = eyeID, + eyeOffset = eyeOffset, + mouthID = mouthID, + mouthOffset = mouthOffset, + detailID = detailID, + detailOffset = detailOffset, + detail2ID = detail2ID, + detail2Offset = detail2Offset + }; + } + + public void SaveFace(string key) + { + PlayerPrefs.SetInt("eyeID-" + key, eyeID); + PlayerPrefs.SetFloat("eyeOffsetX-" + key, eyeOffset.x); + PlayerPrefs.SetFloat("eyeOffsetY-" + key, eyeOffset.y); + PlayerPrefs.SetInt("mouthID-" + key, mouthID); + PlayerPrefs.SetFloat("mouthOffsetX-" + key, mouthOffset.x); + PlayerPrefs.SetFloat("mouthOffsetY-" + key, mouthOffset.y); + PlayerPrefs.SetInt("detailID-" + key, detailID); + PlayerPrefs.SetFloat("detailOffsetX-" + key, detailOffset.x); + PlayerPrefs.SetFloat("detailOffsetY-" + key, detailOffset.y); + PlayerPrefs.SetInt("detail2ID-" + key, detail2ID); + PlayerPrefs.SetFloat("detail2OffsetX-" + key, detail2Offset.x); + PlayerPrefs.SetFloat("detail2OffsetY-" + key, detail2Offset.y); + } +} diff --git a/GameCode/PlayerFlyParticle.cs b/GameCode/PlayerFlyParticle.cs new file mode 100644 index 0000000..a58db02 --- /dev/null +++ b/GameCode/PlayerFlyParticle.cs @@ -0,0 +1,29 @@ +using UnityEngine; + +public class PlayerFlyParticle : MonoBehaviour +{ + private ParticleSystem part; + + private HealthHandler health; + + private void Start() + { + part = GetComponent<ParticleSystem>(); + health = GetComponentInParent<HealthHandler>(); + } + + private void Update() + { + if (part.isPlaying) + { + if (health.flyingFor < 0f) + { + part.Stop(); + } + } + else if (health.flyingFor > 0f) + { + part.Play(); + } + } +} diff --git a/GameCode/PlayerFollowGround.cs b/GameCode/PlayerFollowGround.cs new file mode 100644 index 0000000..c200f89 --- /dev/null +++ b/GameCode/PlayerFollowGround.cs @@ -0,0 +1,30 @@ +using UnityEngine; + +public class PlayerFollowGround : MonoBehaviour +{ + private CharacterData data; + + private Vector2 lastPos; + + private Rigidbody2D lastRig; + + private void Start() + { + data = GetComponent<CharacterData>(); + } + + private void FixedUpdate() + { + if (data.standOnRig == null || !data.isGrounded) + { + lastPos = Vector2.zero; + return; + } + if (lastPos != Vector2.zero && data.standOnRig == lastRig) + { + data.playerVel.transform.position = data.playerVel.position + (data.standOnRig.position - lastPos); + } + lastPos = data.standOnRig.position; + lastRig = data.standOnRig; + } +} diff --git a/GameCode/PlayerImmunity.cs b/GameCode/PlayerImmunity.cs new file mode 100644 index 0000000..791fadf --- /dev/null +++ b/GameCode/PlayerImmunity.cs @@ -0,0 +1,43 @@ +using System.Collections.Generic; +using UnityEngine; + +public class PlayerImmunity : MonoBehaviour +{ + private List<Immunities> immunities = new List<Immunities>(); + + private void Start() + { + } + + private void Update() + { + for (int num = immunities.Count - 1; num >= 0; num--) + { + immunities[num].time -= TimeHandler.deltaTime; + if (immunities[num].time <= 0f) + { + immunities.RemoveAt(num); + } + } + } + + public bool IsImune(float time, float dmg, string name) + { + for (int i = 0; i < immunities.Count; i++) + { + if (immunities[i].name == name) + { + if (dmg > immunities[i].dmg) + { + immunities[i].dmg = dmg; + immunities[i].name = name; + immunities[i].time = time; + return false; + } + return true; + } + } + immunities.Add(new Immunities(time, dmg, name)); + return false; + } +} diff --git a/GameCode/PlayerInRangeSlow.cs b/GameCode/PlayerInRangeSlow.cs new file mode 100644 index 0000000..dd1f0cf --- /dev/null +++ b/GameCode/PlayerInRangeSlow.cs @@ -0,0 +1,26 @@ +using UnityEngine; + +public class PlayerInRangeSlow : MonoBehaviour +{ + public float slowAmount = 0.1f; + + public float maxSlow = 0.5f; + + private PlayerInRangeTrigger trigger; + + private AttackLevel level; + + private void Start() + { + trigger = GetComponent<PlayerInRangeTrigger>(); + level = GetComponent<AttackLevel>(); + } + + private void Update() + { + if (trigger.inRange) + { + trigger.target.data.stats.AddSlowAddative(slowAmount * (float)level.attackLevel, maxSlow + ((float)level.attackLevel - 1f) * 0.25f); + } + } +} diff --git a/GameCode/PlayerInRangeTrigger.cs b/GameCode/PlayerInRangeTrigger.cs new file mode 100644 index 0000000..a6bad07 --- /dev/null +++ b/GameCode/PlayerInRangeTrigger.cs @@ -0,0 +1,79 @@ +using UnityEngine; +using UnityEngine.Events; + +public class PlayerInRangeTrigger : MonoBehaviour +{ + public enum TargetType + { + Any, + OtherPlayer + } + + public TargetType targetType; + + public float range = 5f; + + public float cooldown; + + public bool repeating; + + private float counter; + + private bool done; + + [HideInInspector] + public bool inRange; + + public UnityEvent triggerEvent; + + [HideInInspector] + public Player target; + + private Player ownPlayer; + + public bool scaleWithRange; + + private void Start() + { + ownPlayer = base.transform.root.GetComponent<Player>(); + if (!ownPlayer) + { + ownPlayer = base.transform.root.GetComponentInParent<SpawnedAttack>().spawner; + } + if (scaleWithRange) + { + range *= base.transform.localScale.x; + } + } + + private void Update() + { + counter += TimeHandler.deltaTime; + inRange = false; + target = null; + if (done) + { + return; + } + Player player = null; + if (targetType == TargetType.OtherPlayer) + { + player = PlayerManager.instance.GetOtherPlayer(ownPlayer); + } + if (targetType == TargetType.Any) + { + player = PlayerManager.instance.GetClosestPlayer(base.transform.position); + } + if (PlayerManager.instance.CanSeePlayer(base.transform.position, player).canSee && Vector3.Distance(base.transform.position, player.transform.position) < range * base.transform.root.localScale.x && !player.data.dead && counter >= cooldown) + { + counter = 0f; + triggerEvent.Invoke(); + inRange = true; + target = player; + if (!repeating) + { + done = true; + } + } + } +} diff --git a/GameCode/PlayerJump.cs b/GameCode/PlayerJump.cs new file mode 100644 index 0000000..3bad574 --- /dev/null +++ b/GameCode/PlayerJump.cs @@ -0,0 +1,85 @@ +using System; +using UnityEngine; + +public class PlayerJump : MonoBehaviour +{ + private CharacterData data; + + public float upForce; + + private CharacterStatModifiers stats; + + public ParticleSystem[] jumpPart; + + public float sideForce = 1f; + + public Action JumpAction; + + private void Start() + { + stats = GetComponent<CharacterStatModifiers>(); + data = GetComponent<CharacterData>(); + } + + private void Update() + { + if (data.input.jumpWasPressed) + { + Jump(); + } + if (data.input.jumpIsPressed && data.sinceJump < 0.2f) + { + data.playerVel.AddForce(Vector2.up * TimeHandler.deltaTime * 2f * data.stats.jump * data.playerVel.mass * (1f - stats.GetSlow()) * upForce, ForceMode2D.Force); + } + } + + public void Jump(bool forceJump = false, float multiplier = 1f) + { + if (!forceJump && (data.sinceJump < 0.1f || (data.currentJumps <= 0 && data.sinceWallGrab > 0.1f))) + { + return; + } + Vector3 vector = Vector3.up; + Vector3 vector2 = data.groundPos; + if (JumpAction != null) + { + JumpAction(); + } + bool flag = false; + if (data.sinceWallGrab < 0.1f && !data.isGrounded) + { + vector = Vector2.up * 0.8f + data.wallNormal * 0.4f; + vector2 = data.wallPos; + data.currentJumps = data.jumps; + flag = true; + } + else + { + if (data.sinceGrounded > 0.05f) + { + vector2 = base.transform.position; + } + data.currentJumps = data.jumps; + } + if (data.playerVel.velocity.y < 0f) + { + data.playerVel.velocity = new Vector2(data.playerVel.velocity.x, 0f); + } + data.sinceGrounded = 0f; + data.sinceJump = 0f; + data.isGrounded = false; + data.isWallGrab = false; + data.currentJumps--; + data.playerVel.AddForce(vector * multiplier * 0.01f * data.stats.jump * data.playerVel.mass * (1f - stats.GetSlow()) * upForce, ForceMode2D.Impulse); + if (!flag) + { + data.playerVel.AddForce(Vector2.right * multiplier * sideForce * 0.01f * data.stats.jump * data.playerVel.mass * (1f - stats.GetSlow()) * data.playerVel.velocity.x, ForceMode2D.Impulse); + } + for (int i = 0; i < jumpPart.Length; i++) + { + jumpPart[i].transform.position = new Vector3(vector2.x, vector2.y, 5f) - vector * 0f; + jumpPart[i].transform.rotation = Quaternion.LookRotation(data.playerVel.velocity); + jumpPart[i].Play(); + } + } +} diff --git a/GameCode/PlayerManager.cs b/GameCode/PlayerManager.cs new file mode 100644 index 0000000..1c72689 --- /dev/null +++ b/GameCode/PlayerManager.cs @@ -0,0 +1,415 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using Photon.Pun; +using Sonigon; +using UnityEngine; + +public class PlayerManager : MonoBehaviour +{ + [Header("Sounds")] + public SoundEvent[] soundCharacterSpawn; + + public static PlayerManager instance; + + public LayerMask canSeePlayerMask; + + public List<Player> players = new List<Player>(); + + public PhotonView view; + + private Action<Player, int> PlayerDiedAction; + + private bool playersShouldBeActive; + + public AnimationCurve playerMoveCurve; + + public Action<Player> PlayerJoinedAction { get; internal set; } + + private void Awake() + { + instance = this; + view = GetComponent<PhotonView>(); + } + + public Player GetOtherPlayer(Player asker) + { + return GetClosestPlayerInTeam(asker.transform.position, GetOtherTeam(asker.teamID)); + } + + public Player GetClosestPlayer(Vector2 refPos, bool needVision = false) + { + Player result = null; + float num = float.PositiveInfinity; + for (int i = 0; i < players.Count; i++) + { + if (!players[i].data.dead) + { + float num2 = Vector2.Distance(refPos, players[i].data.playerVel.position); + if ((!needVision || CanSeePlayer(refPos, players[i]).canSee) && num2 < num) + { + num = num2; + result = players[i]; + } + } + } + return result; + } + + internal Player GetPlayerWithActorID(int actorID) + { + for (int i = 0; i < players.Count; i++) + { + if (players[i].data.view.OwnerActorNr == actorID) + { + return players[i]; + } + } + return null; + } + + public Player GetClosestPlayerInTeam(Vector3 position, int team, bool needVision = false) + { + float num = float.MaxValue; + Player[] playersInTeam = GetPlayersInTeam(team); + Player result = null; + for (int i = 0; i < playersInTeam.Length; i++) + { + if (!players[i].data.dead) + { + float num2 = Vector2.Distance(position, playersInTeam[i].transform.position); + if ((!needVision || CanSeePlayer(position, playersInTeam[i]).canSee) && num2 < num) + { + num = num2; + result = playersInTeam[i]; + } + } + } + return result; + } + + public Player GetClosestPlayer(Vector2 refPos, Vector2 forward) + { + Player result = null; + float num = float.PositiveInfinity; + for (int i = 0; i < players.Count; i++) + { + if (!players[i].data.dead && CanSeePlayer(refPos, players[i]).canSee) + { + float num2 = Vector2.Distance(refPos, players[i].data.playerVel.position); + num2 += Vector2.Angle(forward, players[i].data.playerVel.position - refPos); + if (num2 < num) + { + num = num2; + result = players[i]; + } + } + } + return result; + } + + public CanSeeInfo CanSeePlayer(Vector2 from, Player player) + { + CanSeeInfo canSeeInfo = new CanSeeInfo(); + canSeeInfo.canSee = true; + canSeeInfo.distance = float.PositiveInfinity; + if (!player) + { + canSeeInfo.canSee = false; + return canSeeInfo; + } + RaycastHit2D[] array = Physics2D.RaycastAll(from, (player.data.playerVel.position - from).normalized, Vector2.Distance(from, player.data.playerVel.position), canSeePlayerMask); + for (int i = 0; i < array.Length; i++) + { + if ((bool)array[i].transform && !array[i].transform.root.GetComponent<SpawnedAttack>() && !array[i].transform.root.GetComponent<Player>() && array[i].distance < canSeeInfo.distance) + { + canSeeInfo.canSee = false; + canSeeInfo.hitPoint = array[i].point; + canSeeInfo.distance = array[i].distance; + } + } + return canSeeInfo; + } + + internal Player GetPlayerWithID(int playerID) + { + for (int i = 0; i < players.Count; i++) + { + if (players[i].playerID == playerID) + { + return players[i]; + } + } + return null; + } + + public Player GetLastPlayerAlive() + { + Player result = null; + for (int i = 0; i < players.Count; i++) + { + if (!players[i].data.dead) + { + result = players[i]; + break; + } + } + return result; + } + + public int GetLastTeamAlive() + { + return GetLastPlayerAlive().teamID; + } + + public int TeamsAlive() + { + bool flag = false; + bool flag2 = false; + for (int i = 0; i < players.Count; i++) + { + if (players[i].teamID == 0 && !players[i].data.dead) + { + flag = true; + } + if (players[i].teamID == 1 && !players[i].data.dead) + { + flag2 = true; + } + } + int num = 0; + if (flag) + { + num++; + } + if (flag2) + { + num++; + } + return num; + } + + public static void RegisterPlayer(Player player) + { + instance.players.Add(player); + if (instance.playersShouldBeActive) + { + player.data.isPlaying = true; + } + } + + public void RemovePlayer(Player player) + { + players.Remove(player); + UnityEngine.Object.Destroy(player.gameObject); + } + + public void RemovePlayers() + { + for (int num = players.Count - 1; num >= 0; num--) + { + if ((bool)players[num]) + { + UnityEngine.Object.Destroy(players[num].gameObject); + } + } + players.Clear(); + PlayerAssigner.instance.ClearPlayers(); + } + + public void RevivePlayers() + { + for (int i = 0; i < players.Count; i++) + { + players[i].data.healthHandler.Revive(); + players[i].GetComponent<GeneralInput>().enabled = true; + } + } + + [PunRPC] + public void RPCA_MovePlayers() + { + MovePlayers(MapManager.instance.GetSpawnPoints()); + } + + public void MovePlayers(SpawnPoint[] spawnPoints) + { + for (int i = 0; i < players.Count; i++) + { + StartCoroutine(Move(players[i].data.playerVel, spawnPoints[i].localStartPos)); + int num; + for (num = i; num >= soundCharacterSpawn.Length; num -= soundCharacterSpawn.Length) + { + } + SoundManager.Instance.Play(soundCharacterSpawn[num], players[i].transform); + } + } + + public void AddPlayerDiedAction(Action<Player, int> action) + { + PlayerDiedAction = (Action<Player, int>)Delegate.Combine(PlayerDiedAction, action); + } + + public void PlayerDied(Player player) + { + int num = 0; + for (int i = 0; i < players.Count; i++) + { + if (!instance.players[i].data.dead) + { + num++; + } + } + if (PlayerDiedAction != null) + { + PlayerDiedAction(player, num); + } + } + + public PlayerSkin GetColorFromTeam(int teamID) + { + return PlayerSkinBank.GetPlayerSkinColors(GetPlayersInTeam(teamID)[0].playerID); + } + + public PlayerSkin GetColorFromPlayer(int playerID) + { + return PlayerSkinBank.GetPlayerSkinColors(playerID); + } + + public Player[] GetPlayersInTeam(int teamID) + { + List<Player> list = new List<Player>(); + for (int i = 0; i < players.Count; i++) + { + if (players[i].teamID == teamID) + { + list.Add(players[i]); + } + } + return list.ToArray(); + } + + internal Player GetFirstPlayerInTeam(int teamID) + { + return GetPlayersInTeam(teamID)[0]; + } + + public int GetOtherTeam(int team) + { + if (team == 0) + { + return 1; + } + return 0; + } + + public void SetPlayersPlaying(bool playing) + { + playersShouldBeActive = playing; + for (int i = 0; i < players.Count; i++) + { + players[i].data.isPlaying = playing; + } + } + + public void SetPlayersSimulated(bool simulated) + { + playersShouldBeActive = simulated; + for (int i = 0; i < players.Count; i++) + { + players[i].data.playerVel.simulated = simulated; + } + } + + internal void SetPlayersVisible(bool visible) + { + for (int i = 0; i < players.Count; i++) + { + players[i].data.gameObject.transform.position = Vector3.up * 200f; + } + } + + public void PlayerJoined(Player player) + { + if (PlayerJoinedAction != null) + { + PlayerJoinedAction(player); + } + } + + private IEnumerator Move(PlayerVelocity player, Vector3 targetPos) + { + Debug.Log("MOVE PLAYERS START " + Time.unscaledTime); + player.GetComponent<Player>().data.isPlaying = false; + player.simulated = false; + player.isKinematic = true; + Vector3 distance = targetPos - player.transform.position; + Vector3 targetStartPos = player.transform.position; + PlayerCollision col = player.GetComponent<PlayerCollision>(); + float t = playerMoveCurve.keys[playerMoveCurve.keys.Length - 1].time; + float c = 0f; + while (c < t) + { + col.IgnoreWallForFrames(2); + c += Mathf.Clamp(Time.unscaledDeltaTime, 0f, 0.02f); + player.transform.position = targetStartPos + distance * playerMoveCurve.Evaluate(c); + yield return null; + } + int frames = 0; + while (frames < 10) + { + player.transform.position = targetStartPos + distance; + frames++; + yield return null; + } + player.simulated = true; + player.isKinematic = false; + Debug.Log("MOVE PLAYERS END " + Time.unscaledTime); + player.GetComponent<Player>().data.isPlaying = true; + player.GetComponent<Player>().data.healthHandler.Revive(); + CardChoiceVisuals.instance.Hide(); + } + + private void Update() + { + if (Input.GetKeyDown(KeyCode.R) && !DevConsole.isTyping && Application.isEditor) + { + ResetCharacters(); + } + } + + internal void ResetCharacters() + { + CardBarHandler.instance.ResetCardBards(); + for (int i = 0; i < players.Count; i++) + { + players[i].FullReset(); + } + } + + public PlayerActions[] GetActionsFromTeam(int selectingTeamID) + { + List<PlayerActions> list = new List<PlayerActions>(); + for (int i = 0; i < players.Count; i++) + { + if (players[i].teamID == selectingTeamID) + { + list.Add(players[i].data.playerActions); + } + } + return list.ToArray(); + } + + public PlayerActions[] GetActionsFromPlayer(int selectingPlayerID) + { + List<PlayerActions> list = new List<PlayerActions>(); + for (int i = 0; i < players.Count; i++) + { + if (players[i].playerID == selectingPlayerID) + { + list.Add(players[i].data.playerActions); + } + } + return list.ToArray(); + } +} diff --git a/GameCode/PlayerMovement.cs b/GameCode/PlayerMovement.cs new file mode 100644 index 0000000..d3af00e --- /dev/null +++ b/GameCode/PlayerMovement.cs @@ -0,0 +1,71 @@ +using UnityEngine; + +public class PlayerMovement : MonoBehaviour +{ + public float force; + + public float airControl = 0.3f; + + public float extraDrag; + + public float extraAngularDrag; + + public float wallGrabDrag; + + private CharacterData data; + + private CharacterStatModifiers stats; + + private float multiplier = 1f; + + private void Start() + { + data = GetComponent<CharacterData>(); + stats = GetComponent<CharacterStatModifiers>(); + } + + private void FixedUpdate() + { + if (!data.isPlaying) + { + return; + } + Move(data.input.direction); + if (data.isWallGrab && data.wallDistance < 0.7f) + { + Vector2 velocity = data.playerVel.velocity; + if (data.input.direction.y >= 0f) + { + _ = data.input.direction.x; + _ = 0f; + } + data.playerVel.velocity = velocity; + } + data.playerVel.velocity -= data.playerVel.velocity * TimeHandler.timeScale * 0.01f * 0.1f * extraDrag * multiplier; + data.playerVel.angularVelocity -= data.playerVel.angularVelocity * TimeHandler.timeScale * 0.01f * 0.1f * extraAngularDrag * multiplier; + } + + private void Update() + { + } + + public void Move(Vector2 direction) + { + UpdateMultiplier(); + if (!data.isStunned) + { + direction.y = Mathf.Clamp(direction.y, -1f, 0f); + direction.y *= 2f; + data.playerVel.AddForce(direction * TimeHandler.timeScale * (1f - stats.GetSlow()) * stats.movementSpeed * force * data.playerVel.mass * 0.01f * multiplier, ForceMode2D.Force); + } + } + + private void UpdateMultiplier() + { + multiplier = 1f; + if (!data.isGrounded) + { + multiplier = airControl; + } + } +} diff --git a/GameCode/PlayerName.cs b/GameCode/PlayerName.cs new file mode 100644 index 0000000..30fc4cc --- /dev/null +++ b/GameCode/PlayerName.cs @@ -0,0 +1,11 @@ +using Photon.Pun; +using TMPro; +using UnityEngine; + +public class PlayerName : MonoBehaviour +{ + private void Start() + { + GetComponentInParent<TextMeshProUGUI>().text = GetComponentInParent<PhotonView>().Owner.NickName; + } +} diff --git a/GameCode/PlayerSkin.cs b/GameCode/PlayerSkin.cs new file mode 100644 index 0000000..446a0cd --- /dev/null +++ b/GameCode/PlayerSkin.cs @@ -0,0 +1,12 @@ +using UnityEngine; + +public class PlayerSkin : MonoBehaviour +{ + public Color color; + + public Color backgroundColor; + + public Color winText; + + public Color particleEffect; +} diff --git a/GameCode/PlayerSkinBank.cs b/GameCode/PlayerSkinBank.cs new file mode 100644 index 0000000..0a5bcd5 --- /dev/null +++ b/GameCode/PlayerSkinBank.cs @@ -0,0 +1,38 @@ +using System; +using UnityEngine; + +[CreateAssetMenu(fileName = "Skin Bank", menuName = "Custom/Skin Bank", order = 99999)] +public class PlayerSkinBank : ScriptableObject +{ + [Serializable] + public struct PlayerSkinInstance + { + public PlayerSkin currentPlayerSkin; + } + + private static PlayerSkinBank instance; + + public PlayerSkinInstance[] skins = new PlayerSkinInstance[0]; + + private static PlayerSkinBank Instance + { + get + { + if (instance == null) + { + instance = Resources.Load("SkinBank") as PlayerSkinBank; + } + return instance; + } + } + + public static PlayerSkin GetPlayerSkinColors(int team) + { + return Instance.skins[team].currentPlayerSkin; + } + + public static PlayerSkinInstance GetPlayerSkin(int team) + { + return Instance.skins[team]; + } +} diff --git a/GameCode/PlayerSkinHandler.cs b/GameCode/PlayerSkinHandler.cs new file mode 100644 index 0000000..3c23236 --- /dev/null +++ b/GameCode/PlayerSkinHandler.cs @@ -0,0 +1,63 @@ +using UnityEngine; + +public class PlayerSkinHandler : MonoBehaviour +{ + public bool simpleSkin; + + private PlayerSkinParticle[] skins; + + private CharacterData data; + + private bool inited; + + private void Start() + { + Init(); + } + + private void Init() + { + if (!inited) + { + inited = true; + ToggleSimpleSkin(simpleSkin); + data = GetComponentInParent<CharacterData>(); + if (!simpleSkin) + { + GameObject gameObject = Object.Instantiate(PlayerSkinBank.GetPlayerSkinColors(data.player.playerID).gameObject, base.transform.position, base.transform.rotation, base.transform); + skins = gameObject.GetComponentsInChildren<PlayerSkinParticle>(); + } + } + } + + public void TakeDamageBlink(Vector2 damage, bool selfDamage) + { + BlinkColor(Color.white * 0.95f); + } + + public void BlinkColor(Color blinkColor) + { + if (skins != null) + { + for (int i = 0; i < skins.Length; i++) + { + skins[i].BlinkColor(blinkColor); + } + } + } + + public void InitSpriteMask(int spriteLayerID) + { + Init(); + for (int i = 0; i < skins.Length; i++) + { + skins[i].Init(spriteLayerID); + } + } + + public void ToggleSimpleSkin(bool isSimple) + { + simpleSkin = isSimple; + GetComponent<SetPlayerSpriteLayer>().ToggleSimple(isSimple); + } +} diff --git a/GameCode/PlayerSkinParticle.cs b/GameCode/PlayerSkinParticle.cs new file mode 100644 index 0000000..22c2f99 --- /dev/null +++ b/GameCode/PlayerSkinParticle.cs @@ -0,0 +1,54 @@ +using UnityEngine; + +public class PlayerSkinParticle : MonoBehaviour +{ + private Color startColor1; + + private Color startColor2; + + private ParticleSystem.MainModule main; + + private ParticleSystem part; + + private ParticleSystem.Particle[] particles; + + private float counter; + + public void Init(int spriteLayerID) + { + part = GetComponent<ParticleSystem>(); + part.GetComponent<ParticleSystemRenderer>().sortingLayerID = spriteLayerID; + main = part.main; + startColor1 = main.startColor.colorMin; + startColor2 = main.startColor.colorMax; + part.Play(); + } + + private void Update() + { + counter += TimeHandler.deltaTime; + } + + private void OnEnable() + { + if ((bool)part) + { + part.Play(); + } + } + + public void BlinkColor(Color blinkColor) + { + if (!(counter < 0.1f)) + { + counter = 0f; + particles = new ParticleSystem.Particle[part.main.maxParticles]; + int num = part.GetParticles(particles); + for (int i = 0; i < num; i++) + { + particles[i].startColor = blinkColor; + } + part.SetParticles(particles, num); + } + } +} diff --git a/GameCode/PlayerSounds.cs b/GameCode/PlayerSounds.cs new file mode 100644 index 0000000..aeffb32 --- /dev/null +++ b/GameCode/PlayerSounds.cs @@ -0,0 +1,126 @@ +using System; +using System.Collections.Generic; +using Sonigon; +using UnityEngine; + +public class PlayerSounds : MonoBehaviour +{ + [Header("Sounds")] + public SoundEvent soundCharacterJump; + + public SoundEvent soundCharacterJumpBig; + + public SoundEvent soundCharacterJumpEnsnare; + + public SoundEvent soundCharacterLand; + + public SoundEvent soundCharacterLandBig; + + private SoundParameterIntensity parameterIntensityLand = new SoundParameterIntensity(0f); + + public SoundEvent soundCharacterStickWall; + + public SoundEvent soundCharacterStickWallBig; + + private SoundParameterIntensity parameterIntensityStickWall = new SoundParameterIntensity(0f); + + public SoundEvent soundCharacterDamageScreenEdge; + + private CharacterData data; + + private List<EnsnareEffect> ensnareEffectList = new List<EnsnareEffect>(); + + private bool ensnareEnabled; + + public void AddEnsnareEffect(EnsnareEffect ensnareEffect) + { + ensnareEffectList.Add(ensnareEffect); + } + + public void RemoveEnsnareEffect(EnsnareEffect ensnareEffect) + { + ensnareEffectList.Remove(ensnareEffect); + } + + private void Start() + { + data = GetComponent<CharacterData>(); + CharacterData characterData = data; + characterData.TouchGroundAction = (Action<float, Vector3, Vector3, Transform>)Delegate.Combine(characterData.TouchGroundAction, new Action<float, Vector3, Vector3, Transform>(TouchGround)); + CharacterData characterData2 = data; + characterData2.TouchWallAction = (Action<float, Vector3, Vector3>)Delegate.Combine(characterData2.TouchWallAction, new Action<float, Vector3, Vector3>(TouchWall)); + PlayerJump jump = data.jump; + jump.JumpAction = (Action)Delegate.Combine(jump.JumpAction, new Action(Jump)); + } + + public void Jump() + { + ensnareEnabled = false; + for (int num = ensnareEffectList.Count - 1; num >= 0; num--) + { + if (ensnareEffectList[num] == null) + { + ensnareEffectList.RemoveAt(num); + } + } + for (int i = 0; i < ensnareEffectList.Count; i++) + { + if (ensnareEffectList[i].soundEnsnareJumpChange) + { + ensnareEnabled = true; + } + } + if (ensnareEnabled) + { + if (ensnareEnabled) + { + SoundManager.Instance.Play(soundCharacterJumpEnsnare, base.transform); + } + } + else if (data.stats.SoundTransformScaleThresholdReached()) + { + SoundManager.Instance.Play(soundCharacterJumpBig, base.transform); + } + else + { + SoundManager.Instance.Play(soundCharacterJump, base.transform); + } + } + + public void TouchGround(float sinceGrounded, Vector3 pos, Vector3 normal, Transform ground) + { + if (sinceGrounded > 0.05f) + { + parameterIntensityLand.intensity = sinceGrounded; + if (data.stats.SoundTransformScaleThresholdReached()) + { + SoundManager.Instance.Play(soundCharacterLandBig, base.transform, parameterIntensityLand); + } + else + { + SoundManager.Instance.Play(soundCharacterLand, base.transform, parameterIntensityLand); + } + } + } + + public void TouchWall(float sinceWall, Vector3 pos, Vector3 normal) + { + float num = sinceWall; + if (data.sinceGrounded < num) + { + num = data.sinceGrounded; + } + if (num > 0.05f) + { + parameterIntensityStickWall.intensity = num; + if (data.stats.SoundTransformScaleThresholdReached()) + { + SoundManager.Instance.Play(soundCharacterStickWallBig, base.transform, parameterIntensityStickWall); + } + else + { + SoundManager.Instance.Play(soundCharacterStickWall, base.transform, parameterIntensityStickWall); + } + } + } +} diff --git a/GameCode/PlayerSpawnVisualEffect.cs b/GameCode/PlayerSpawnVisualEffect.cs new file mode 100644 index 0000000..a0f86ba --- /dev/null +++ b/GameCode/PlayerSpawnVisualEffect.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; +using UnityEngine; + +public class PlayerSpawnVisualEffect : MonoBehaviour +{ + public Dictionary<string, GameObject> visualEffects; + + public void RPCA_SpawnVisualEffect(string effect) + { + Object.Instantiate(visualEffects[effect], base.transform.position, base.transform.rotation, base.transform); + } +} diff --git a/GameCode/PlayerVelocity.cs b/GameCode/PlayerVelocity.cs new file mode 100644 index 0000000..47822f6 --- /dev/null +++ b/GameCode/PlayerVelocity.cs @@ -0,0 +1,82 @@ +using UnityEngine; + +public class PlayerVelocity : MonoBehaviour +{ + internal bool simulated = true; + + internal bool isKinematic; + + internal Vector2 velocity; + + internal float mass = 100f; + + internal float angularVelocity; + + private CharacterData data; + + public Vector2 position + { + get + { + return base.transform.position; + } + set + { + base.transform.position = value; + } + } + + internal void AddTorque(float v) + { + } + + private void Start() + { + data = GetComponent<CharacterData>(); + } + + private void FixedUpdate() + { + if (data.isPlaying) + { + if (isKinematic) + { + velocity *= 0f; + } + if (simulated && !isKinematic) + { + velocity += Vector2.down * Time.fixedDeltaTime * TimeHandler.timeScale * 20f; + base.transform.position += Time.fixedDeltaTime * TimeHandler.timeScale * (Vector3)velocity; + base.transform.position = new Vector3(base.transform.position.x, base.transform.position.y, 0f); + } + } + } + + internal void AddForce(Vector2 force, ForceMode2D forceMode) + { + if (forceMode == ForceMode2D.Force) + { + force *= 0.02f; + } + else + { + force *= 1f; + } + velocity += force / mass; + } + + internal void AddForce(Vector3 force, ForceMode2D forceMode) + { + AddForce((Vector2)force, forceMode); + } + + internal void AddForce(Vector2 force) + { + AddForce(force, ForceMode2D.Force); + } + + internal void AddForce(Vector3 force) + { + AddForce((Vector2)force, ForceMode2D.Force); + } +} diff --git a/GameCode/PlayerWobblePosition.cs b/GameCode/PlayerWobblePosition.cs new file mode 100644 index 0000000..6d05434 --- /dev/null +++ b/GameCode/PlayerWobblePosition.cs @@ -0,0 +1,38 @@ +using UnityEngine; + +public class PlayerWobblePosition : MonoBehaviour +{ + private Vector3 physicsPos; + + public float drag = 15f; + + public float spring = 1000f; + + public float multiplier = 1f; + + public float prediction; + + private Vector3 velocity; + + private Player player; + + private void Start() + { + physicsPos = base.transform.position; + player = GetComponentInParent<Player>(); + } + + private void Update() + { + float num = Mathf.Clamp(TimeHandler.deltaTime, 0f, 0.03f); + Vector3 position = player.transform.position; + if (prediction > 0f) + { + position += (Vector3)player.data.playerVel.velocity * prediction; + } + velocity += (position - physicsPos) * num * spring; + velocity -= velocity * drag * num; + physicsPos += num * multiplier * velocity; + base.transform.position = physicsPos; + } +} diff --git a/GameCode/Point.cs b/GameCode/Point.cs new file mode 100644 index 0000000..aa901d5 --- /dev/null +++ b/GameCode/Point.cs @@ -0,0 +1,12 @@ +using UnityEngine; + +public class Point : MonoBehaviour +{ + private void Start() + { + } + + private void Update() + { + } +} diff --git a/GameCode/PointVisualizer.cs b/GameCode/PointVisualizer.cs new file mode 100644 index 0000000..dc2e55b --- /dev/null +++ b/GameCode/PointVisualizer.cs @@ -0,0 +1,292 @@ +using System.Collections; +using Sirenix.OdinInspector; +using Sonigon; +using TMPro; +using UnityEngine; +using UnityEngine.UI; + +public class PointVisualizer : MonoBehaviour +{ + public SoundEvent soundWinRound; + + public SoundEvent sound_UI_Arms_Race_A_Ball_Shrink_Go_To_Left_Corner; + + public SoundEvent sound_UI_Arms_Race_B_Ball_Go_Down_Then_Expand; + + public SoundEvent sound_UI_Arms_Race_C_Ball_Pop_Shake; + + public static PointVisualizer instance; + + public AnimationCurve moveCurve; + + public AnimationCurve scaleCurve; + + public float timeBetween; + + public float timeToMove = 0.2f; + + public float timeToScale = 0.2f; + + public TextMeshProUGUI text; + + public GameObject bg; + + public Transform orangeBall; + + public Transform blueBall; + + private RectTransform orangeBallRT; + + private RectTransform blueBallRT; + + public Image orangeFill; + + public Image blueFill; + + private Vector3 orangeVel; + + private Vector3 blueVel; + + private Vector3 orangeSP; + + private Vector3 blueSP; + + private float ballBaseSize = 200f; + + private float ballSmallSize = 20f; + + private float bigBallScale = 900f; + + private void Awake() + { + instance = this; + } + + private void Start() + { + orangeBallRT = orangeBall.GetComponent<RectTransform>(); + blueBallRT = blueBall.GetComponent<RectTransform>(); + orangeSP = orangeBall.GetComponent<RectTransform>().anchoredPosition; + blueSP = blueBall.GetComponent<RectTransform>().anchoredPosition; + Close(); + } + + [Button] + private void TestWinSequence() + { + StartCoroutine(DoWinSequence(2, 1, 2, 1, orangeWinner: true)); + } + + [Button] + private void TestPoint() + { + StartCoroutine(DoSequence(1, 0, orangeWinner: true)); + } + + [Button] + private void Reset() + { + StartCoroutine(DoSequence(0, 0, orangeWinner: true)); + } + + public void ResetPoints() + { + orangeFill.fillAmount = 0f; + blueFill.fillAmount = 0f; + } + + private void ResetBalls() + { + orangeBallRT.sizeDelta = Vector2.one * ballBaseSize; + blueBallRT.sizeDelta = Vector2.one * ballBaseSize; + orangeBall.GetComponent<RectTransform>().anchoredPosition = orangeSP; + blueBall.GetComponent<RectTransform>().anchoredPosition = blueSP; + orangeVel = Vector3.zero; + blueVel = Vector3.zero; + } + + public IEnumerator DoWinSequence(int orangePoints, int bluePoints, int orangeRounds, int blueRounds, bool orangeWinner) + { + yield return new WaitForSecondsRealtime(0.35f); + SoundManager.Instance.Play(soundWinRound, base.transform); + ResetBalls(); + bg.SetActive(value: true); + blueBall.gameObject.SetActive(value: true); + orangeBall.gameObject.SetActive(value: true); + yield return new WaitForSecondsRealtime(0.2f); + GamefeelManager.instance.AddUIGameFeelOverTime(10f, 0.1f); + DoShowPoints(orangePoints, bluePoints, orangeWinner); + yield return new WaitForSecondsRealtime(0.35f); + SoundManager.Instance.Play(sound_UI_Arms_Race_A_Ball_Shrink_Go_To_Left_Corner, base.transform); + float c3 = 0f; + while (c3 < timeToScale) + { + if (orangeWinner) + { + orangeBallRT.sizeDelta = Vector2.LerpUnclamped(orangeBallRT.sizeDelta, Vector2.one * ballSmallSize, scaleCurve.Evaluate(c3 / timeToScale)); + } + else + { + blueBallRT.sizeDelta = Vector2.LerpUnclamped(blueBallRT.sizeDelta, Vector2.one * ballSmallSize, scaleCurve.Evaluate(c3 / timeToScale)); + } + c3 += Time.unscaledDeltaTime; + yield return null; + } + yield return new WaitForSecondsRealtime(timeBetween); + c3 = 0f; + while (c3 < timeToMove) + { + if (orangeWinner) + { + orangeBall.position = Vector3.LerpUnclamped(orangeBall.position, UIHandler.instance.roundCounterSmall.GetPointPos(0), scaleCurve.Evaluate(c3 / timeToMove)); + } + else + { + blueBall.position = Vector3.LerpUnclamped(blueBall.position, UIHandler.instance.roundCounterSmall.GetPointPos(1), scaleCurve.Evaluate(c3 / timeToMove)); + } + c3 += Time.unscaledDeltaTime; + yield return null; + } + SoundManager.Instance.Play(sound_UI_Arms_Race_B_Ball_Go_Down_Then_Expand, base.transform); + if (orangeWinner) + { + orangeBall.position = UIHandler.instance.roundCounterSmall.GetPointPos(0); + } + else + { + blueBall.position = UIHandler.instance.roundCounterSmall.GetPointPos(1); + } + yield return new WaitForSecondsRealtime(timeBetween); + c3 = 0f; + while (c3 < timeToMove) + { + if (!orangeWinner) + { + orangeBall.position = Vector3.LerpUnclamped(orangeBall.position, CardChoiceVisuals.instance.transform.position, scaleCurve.Evaluate(c3 / timeToMove)); + } + else + { + blueBall.position = Vector3.LerpUnclamped(blueBall.position, CardChoiceVisuals.instance.transform.position, scaleCurve.Evaluate(c3 / timeToMove)); + } + c3 += Time.unscaledDeltaTime; + yield return null; + } + if (!orangeWinner) + { + orangeBall.position = CardChoiceVisuals.instance.transform.position; + } + else + { + blueBall.position = CardChoiceVisuals.instance.transform.position; + } + yield return new WaitForSecondsRealtime(timeBetween); + c3 = 0f; + while (c3 < timeToScale) + { + if (!orangeWinner) + { + orangeBallRT.sizeDelta = Vector2.LerpUnclamped(orangeBallRT.sizeDelta, Vector2.one * bigBallScale, scaleCurve.Evaluate(c3 / timeToScale)); + } + else + { + blueBallRT.sizeDelta = Vector2.LerpUnclamped(blueBallRT.sizeDelta, Vector2.one * bigBallScale, scaleCurve.Evaluate(c3 / timeToScale)); + } + c3 += Time.unscaledDeltaTime; + yield return null; + } + SoundManager.Instance.Play(sound_UI_Arms_Race_C_Ball_Pop_Shake, base.transform); + GamefeelManager.instance.AddUIGameFeelOverTime(10f, 0.2f); + CardChoiceVisuals.instance.Show(orangeWinner ? 1 : 0); + UIHandler.instance.roundCounterSmall.UpdateRounds(orangeRounds, blueRounds); + UIHandler.instance.roundCounterSmall.UpdatePoints(0, 0); + DoShowPoints(0, 0, orangeWinner); + Close(); + } + + private void MoveTowards() + { + } + + public IEnumerator DoSequence(int currentOrange, int currentBlue, bool orangeWinner) + { + yield return new WaitForSecondsRealtime(0.45f); + SoundManager.Instance.Play(soundWinRound, base.transform); + ResetBalls(); + bg.SetActive(value: true); + blueBall.gameObject.SetActive(value: true); + orangeBall.gameObject.SetActive(value: true); + yield return new WaitForSecondsRealtime(0.2f); + GamefeelManager.instance.AddUIGameFeelOverTime(10f, 0.1f); + DoShowPoints(currentOrange, currentBlue, orangeWinner); + yield return new WaitForSecondsRealtime(1.8f); + orangeBall.GetComponent<CurveAnimation>().PlayOut(); + blueBall.GetComponent<CurveAnimation>().PlayOut(); + yield return new WaitForSecondsRealtime(0.25f); + Close(); + } + + public void DoShowPoints(int currentOrange, int currentBlue, bool orangeWinner) + { + orangeFill.fillAmount = (float)currentOrange * 0.5f; + blueFill.fillAmount = (float)currentBlue * 0.5f; + if (orangeWinner) + { + text.color = PlayerSkinBank.GetPlayerSkinColors(0).winText; + } + else + { + text.color = PlayerSkinBank.GetPlayerSkinColors(1).winText; + } + if (orangeWinner) + { + if (currentOrange > 1) + { + RoundOrange(); + } + else + { + HalfOrange(); + } + } + else if (currentBlue > 1) + { + RoundOBlue(); + } + else + { + HalfBlue(); + } + } + + private void Close() + { + text.text = ""; + bg.SetActive(value: false); + blueBall.gameObject.SetActive(value: false); + orangeBall.gameObject.SetActive(value: false); + } + + private void HalfOrange() + { + text.text = "HALF ORANGE"; + } + + private void RoundOrange() + { + text.text = "ROUND ORANGE"; + } + + private void HalfBlue() + { + text.text = "HALF BLUE"; + } + + private void RoundOBlue() + { + text.text = "ROUND BLUE"; + } + + private void Update() + { + } +} diff --git a/GameCode/PopUpHandler.cs b/GameCode/PopUpHandler.cs new file mode 100644 index 0000000..198c9b8 --- /dev/null +++ b/GameCode/PopUpHandler.cs @@ -0,0 +1,97 @@ +using System; +using UnityEngine; + +public class PopUpHandler : MonoBehaviour +{ + public enum YesNo + { + Yes, + No + } + + public CurveAnimation yesAnim; + + public CurveAnimation noAnim; + + public bool isPicking; + + public GeneralParticleSystem yesPart; + + public GeneralParticleSystem noPart; + + public GeneralInput playerInput; + + private Action<YesNo> fToCall; + + private YesNo currentYesNo; + + private void Start() + { + } + + public void StartPicking(Player player, Action<YesNo> functionToCall) + { + PlayerManager.instance.RevivePlayers(); + PlayerManager.instance.SetPlayersSimulated(simulated: true); + isPicking = true; + fToCall = functionToCall; + yesPart.particleSettings.color = PlayerManager.instance.GetColorFromTeam(player.teamID).winText; + noPart.particleSettings.color = PlayerManager.instance.GetColorFromTeam(player.teamID).winText; + yesPart.loop = true; + yesPart.Play(); + yesAnim.PlayIn(); + noPart.loop = true; + noPart.Play(); + } + + private void DonePicking() + { + fToCall(currentYesNo); + isPicking = false; + noPart.loop = false; + yesPart.loop = false; + } + + private void Update() + { + if (!isPicking) + { + return; + } + for (int i = 0; i < PlayerManager.instance.players.Count; i++) + { + if (PlayerManager.instance.players[i].data.view.IsMine) + { + playerInput = PlayerManager.instance.players[i].data.input; + if (playerInput.stickPressDir == GeneralInput.StickDirection.Left && currentYesNo != 0) + { + currentYesNo = YesNo.Yes; + UpdateUI(); + } + if (playerInput.stickPressDir == GeneralInput.StickDirection.Right && currentYesNo != YesNo.No) + { + currentYesNo = YesNo.No; + UpdateUI(); + } + if (playerInput.acceptWasPressed) + { + DonePicking(); + } + } + } + } + + private void UpdateUI() + { + if (currentYesNo == YesNo.Yes) + { + yesAnim.PlayIn(); + noAnim.PlayOut(); + } + else + { + yesAnim.PlayOut(); + noAnim.PlayIn(); + } + } +} diff --git a/GameCode/Populate.cs b/GameCode/Populate.cs new file mode 100644 index 0000000..b59ce59 --- /dev/null +++ b/GameCode/Populate.cs @@ -0,0 +1,71 @@ +using System.Collections.Generic; +using UnityEngine; + +public class Populate : MonoBehaviour +{ + public GameObject target; + + public bool setTargetsActive; + + public bool includeTargetInList = true; + + public int times = 5; + + public List<GameObject> DoPopulate() + { + List<GameObject> list = new List<GameObject>(); + if (includeTargetInList) + { + list.Add(target); + } + for (int i = 0; i < times; i++) + { + GameObject gameObject = Object.Instantiate(target, target.transform.position, base.transform.transform.rotation, base.transform); + gameObject.transform.localScale = target.transform.localScale; + list.Add(gameObject); + if (setTargetsActive) + { + gameObject.SetActive(value: true); + } + } + return list; + } + + public List<T> DoPopulate<T>(bool addComponentIfMissing = true) where T : MonoBehaviour + { + List<T> list = new List<T>(); + if (includeTargetInList && target != null) + { + T val = target.GetComponent<T>(); + if ((Object)val == (Object)null && addComponentIfMissing) + { + val = target.AddComponent<T>(); + } + if (!((Object)val != (Object)null)) + { + Debug.LogError("Could not find component"); + return null; + } + list.Add(val); + } + for (int i = 0; i < times; i++) + { + GameObject gameObject = Object.Instantiate(target, target.transform.position, base.transform.transform.rotation, target.transform.transform.parent); + gameObject.transform.localScale = target.transform.localScale; + T val2 = gameObject.GetComponent<T>(); + if ((Object)val2 == (Object)null && addComponentIfMissing) + { + val2 = gameObject.AddComponent<T>(); + } + if ((Object)val2 != (Object)null) + { + list.Add(val2); + } + if (setTargetsActive) + { + gameObject.SetActive(value: true); + } + } + return list; + } +} diff --git a/GameCode/PositionNoise.cs b/GameCode/PositionNoise.cs new file mode 100644 index 0000000..07b6d8a --- /dev/null +++ b/GameCode/PositionNoise.cs @@ -0,0 +1,24 @@ +using UnityEngine; + +public class PositionNoise : CardAnimation +{ + public float amount; + + public float speed = 1f; + + private float startSeed; + + private Vector3 startPos; + + private void Start() + { + startPos = base.transform.localPosition; + startSeed = Random.Range(0f, 100000f); + } + + private void Update() + { + Vector2 vector = new Vector2(Mathf.PerlinNoise(startSeed + Time.unscaledTime * speed, startSeed + Time.unscaledTime * speed - 0.5f), Mathf.PerlinNoise(startSeed + Time.unscaledTime * speed, startSeed + Time.unscaledTime * speed) - 0.5f); + base.transform.localPosition = startPos + (Vector3)vector * amount; + } +} diff --git a/GameCode/PowerUps.cs b/GameCode/PowerUps.cs new file mode 100644 index 0000000..64f3ae7 --- /dev/null +++ b/GameCode/PowerUps.cs @@ -0,0 +1,66 @@ +using UnityEngine; + +public class PowerUps : MonoBehaviour +{ + public GameObject weapon; + + public float damage = 1f; + + public float knockback = 1f; + + public float attackSpeed = 1f; + + public float projectileSpeed = 1f; + + public float spread; + + public float evenSpread; + + public float gravity = 1f; + + public int projectiles = 1; + + public int reflects; + + public int smartBounce; + + public int bulletPortal; + + public int randomBounces; + + public int bursts = 1; + + public float lifeSteal; + + public float projectileSize; + + public float damageAfterDistanceMultiplier = 1f; + + public float distancceForDamageAfterDistanceMultiplier = 5f; + + public float timeToReachFullMovementMultiplier; + + public ObjectsToSpawn[] objectsToSpawn; + + public bool waveMovement; + + public bool teleport; + + public bool spawnSkelletonSquare; + + public float explodeNearEnemyRange; + + public float explodeNearEnemyDamage; + + public float hitMovementMultiplier = 1f; + + private void Start() + { + EffectWeapon(weapon); + } + + private void EffectWeapon(GameObject weapon) + { + weapon.GetComponent<Gun>(); + } +} diff --git a/GameCode/ProjectileCollision.cs b/GameCode/ProjectileCollision.cs new file mode 100644 index 0000000..8833660 --- /dev/null +++ b/GameCode/ProjectileCollision.cs @@ -0,0 +1,86 @@ +using UnityEngine; + +public class ProjectileCollision : ProjectileHitSurface +{ + public bool scaleWithDMG; + + public float health; + + private float deathThreshold; + + private RayHitReflect reflect; + + private ChildRPC rpc; + + private float startDMG; + + private bool hasCollided; + + public GameObject sparkObject; + + private void Start() + { + rpc = GetComponentInParent<ChildRPC>(); + rpc.childRPCs.Add("KillBullet", Die); + reflect = GetComponentInParent<RayHitReflect>(); + ProjectileHit componentInParent = GetComponentInParent<ProjectileHit>(); + if (scaleWithDMG) + { + base.transform.localScale *= (componentInParent.damage / 55f + 1f) * 0.5f; + health = componentInParent.damage; + } + startDMG = componentInParent.damage; + deathThreshold = health * 0.1f; + } + + public override HasToStop HitSurface(HitInfo hit, GameObject projectile) + { + if (Vector2.Angle(base.transform.root.forward, projectile.transform.forward) < 45f) + { + return HasToStop.HasToStop; + } + if ((bool)reflect && reflect.timeOfBounce + 0.5f > Time.time) + { + return HasToStop.HasToStop; + } + ProjectileCollision componentInChildren = projectile.GetComponentInChildren<ProjectileCollision>(); + if ((bool)componentInChildren) + { + reflect = componentInChildren.GetComponentInParent<RayHitReflect>(); + if ((bool)reflect && reflect.timeOfBounce + 0.5f > Time.time) + { + return HasToStop.HasToStop; + } + float dmg = health; + float dmg2 = componentInChildren.health; + componentInChildren.TakeDamage(dmg); + TakeDamage(dmg2); + } + return HasToStop.HasToStop; + } + + public void TakeDamage(float dmg) + { + if (!hasCollided) + { + health -= dmg; + if ((bool)rpc && health < deathThreshold) + { + rpc.CallFunction("KillBullet"); + } + } + } + + public void Die() + { + if (!hasCollided) + { + hasCollided = true; + RaycastHit2D raycastHit2D = default(RaycastHit2D); + raycastHit2D.normal = -base.transform.root.forward; + raycastHit2D.point = base.transform.position; + Object.Instantiate(sparkObject, base.transform.position, base.transform.rotation).transform.localScale = Vector3.one * ((startDMG / 55f + 1f) * 0.5f); + GetComponentInParent<ProjectileHit>().Hit(HitInfo.GetHitInfo(raycastHit2D), forceCall: true); + } + } +} diff --git a/GameCode/ProjectileHit.cs b/GameCode/ProjectileHit.cs new file mode 100644 index 0000000..1bb6175 --- /dev/null +++ b/GameCode/ProjectileHit.cs @@ -0,0 +1,393 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using Photon.Pun; +using Sirenix.OdinInspector; +using UnityEngine; +using UnityEngine.Events; + +public class ProjectileHit : RayHit +{ + [HideInInspector] + public bool canPushBox = true; + + public float force; + + public float damage; + + public float stun; + + public float percentageDamage; + + public float movementSlow; + + public float shake; + + public ObjectsToSpawn[] objectsToSpawn; + + public PlayerSkin team; + + [HideInInspector] + public Player ownPlayer; + + [HideInInspector] + public GameObject ownWeapon; + + public AnimationCurve effectOverTimeCurve; + + [HideInInspector] + public List<RayHitEffect> effects; + + private List<HealthHandler> playersHit = new List<HealthHandler>(); + + public Color projectileColor = Color.black; + + private Action hitAction; + + private Action<HitInfo> hitActionWithData; + + [HideInInspector] + public bool unblockable; + + [HideInInspector] + public bool fullSelfDamage; + + [FoldoutGroup("Special", 0)] + public UnityEvent deathEvent; + + [FoldoutGroup("Special", 0)] + public bool destroyOnBlock; + + [FoldoutGroup("Special", 0)] + public float holdPlayerFor = 0.5f; + + [FoldoutGroup("Special", 0)] + public string bulletImmunity = ""; + + private SpawnedAttack spawnedAttack; + + [HideInInspector] + public float sinceReflect = 10f; + + [HideInInspector] + public float dealDamageMultiplierr = 1f; + + internal bool hasControl; + + [HideInInspector] + public PhotonView view; + + private MoveTransform move; + + [HideInInspector] + public bool bulletCanDealDeamage = true; + + [HideInInspector] + public bool isAllowedToSpawnObjects = true; + + public bool sendCollisions = true; + + public Dictionary<string, Action> customActions = new Dictionary<string, Action>(); + + public Dictionary<string, Action<Vector2, Vector2>> customActionsV2V2 = new Dictionary<string, Action<Vector2, Vector2>>(); + + private void Start() + { + move = GetComponent<MoveTransform>(); + view = GetComponent<PhotonView>(); + effects.AddRange(GetComponentsInChildren<RayHitEffect>()); + effects.Sort((RayHitEffect p1, RayHitEffect p2) => p2.priority.CompareTo(p1.priority)); + spawnedAttack = GetComponent<SpawnedAttack>(); + if ((bool)spawnedAttack && !ownPlayer) + { + ownPlayer = spawnedAttack.spawner; + } + if ((bool)ownPlayer && !fullSelfDamage) + { + StartCoroutine(HoldPlayer(ownPlayer.GetComponent<HealthHandler>())); + } + damage *= base.transform.localScale.x; + force *= Mathf.Pow(damage / 55f, 2f); + } + + public void ResortHitEffects() + { + effects.Sort((RayHitEffect p1, RayHitEffect p2) => p2.priority.CompareTo(p1.priority)); + } + + private IEnumerator HoldPlayer(HealthHandler player) + { + if ((bool)player) + { + playersHit.Add(player); + } + yield return new WaitForSeconds(holdPlayerFor); + if (playersHit.Contains(player)) + { + playersHit.Remove(player); + } + } + + private void Update() + { + sinceReflect += TimeHandler.deltaTime; + } + + public void AddPlayerToHeld(HealthHandler health) + { + StartCoroutine(HoldPlayer(health)); + } + + public void RemoveOwnPlayerFromPlayersHit() + { + if ((bool)ownPlayer && playersHit.Contains(ownPlayer.GetComponent<HealthHandler>())) + { + playersHit.Remove(ownPlayer.GetComponent<HealthHandler>()); + } + } + + public override void Hit(HitInfo hit, bool forceCall = false) + { + int num = -1; + if ((bool)hit.transform) + { + PhotonView component = hit.transform.root.GetComponent<PhotonView>(); + if ((bool)component) + { + num = component.ViewID; + } + } + int num2 = -1; + if (num == -1) + { + Collider2D[] componentsInChildren = MapManager.instance.currentMap.Map.GetComponentsInChildren<Collider2D>(); + for (int i = 0; i < componentsInChildren.Length; i++) + { + if (componentsInChildren[i] == hit.collider) + { + num2 = i; + } + } + } + HealthHandler healthHandler = null; + if ((bool)hit.transform) + { + healthHandler = hit.transform.GetComponent<HealthHandler>(); + } + bool flag = false; + if ((bool)healthHandler) + { + if (playersHit.Contains(healthHandler)) + { + return; + } + if (view.IsMine && healthHandler.GetComponent<Block>().IsBlocking()) + { + flag = true; + } + StartCoroutine(HoldPlayer(healthHandler)); + } + if (view.IsMine || forceCall) + { + if (sendCollisions) + { + view.RPC("RPCA_DoHit", RpcTarget.All, hit.point, hit.normal, (Vector2)move.velocity, num, num2, flag); + } + else + { + RPCA_DoHit(hit.point, hit.normal, move.velocity, num, num2, flag); + } + } + } + + [PunRPC] + public void RPCA_DoHit(Vector2 hitPoint, Vector2 hitNormal, Vector2 vel, int viewID = -1, int colliderID = -1, bool wasBlocked = false) + { + HitInfo hitInfo = new HitInfo(); + if ((bool)move) + { + move.velocity = vel; + } + hitInfo.point = hitPoint; + hitInfo.normal = hitNormal; + hitInfo.collider = null; + if (viewID != -1) + { + PhotonView photonView = PhotonNetwork.GetPhotonView(viewID); + hitInfo.collider = photonView.GetComponentInChildren<Collider2D>(); + hitInfo.transform = photonView.transform; + } + else if (colliderID != -1) + { + hitInfo.collider = MapManager.instance.currentMap.Map.GetComponentsInChildren<Collider2D>()[colliderID]; + hitInfo.transform = hitInfo.collider.transform; + } + HealthHandler healthHandler = null; + if ((bool)hitInfo.transform) + { + healthHandler = hitInfo.transform.GetComponent<HealthHandler>(); + } + if (isAllowedToSpawnObjects) + { + base.transform.position = hitInfo.point; + } + if ((bool)hitInfo.collider) + { + ProjectileHitSurface component = hitInfo.collider.GetComponent<ProjectileHitSurface>(); + if ((bool)component && component.HitSurface(hitInfo, base.gameObject) == ProjectileHitSurface.HasToStop.HasToStop) + { + return; + } + } + if ((bool)healthHandler) + { + Block component2 = healthHandler.GetComponent<Block>(); + if (wasBlocked) + { + component2.DoBlock(base.gameObject, base.transform.forward, hitInfo.point); + if (destroyOnBlock) + { + DestroyMe(); + } + sinceReflect = 0f; + return; + } + CharacterStatModifiers component3 = healthHandler.GetComponent<CharacterStatModifiers>(); + if (movementSlow != 0f && !wasBlocked) + { + component3.RPCA_AddSlow(movementSlow); + } + } + float num = 1f; + PlayerVelocity playerVelocity = null; + if ((bool)hitInfo.transform) + { + playerVelocity = hitInfo.transform.GetComponentInParent<PlayerVelocity>(); + } + if ((bool)hitInfo.collider) + { + Damagable componentInParent = hitInfo.collider.GetComponentInParent<Damagable>(); + if ((bool)componentInParent) + { + if ((bool)healthHandler && percentageDamage != 0f) + { + damage += healthHandler.GetComponent<CharacterData>().maxHealth * percentageDamage; + } + if (hasControl) + { + if (bulletImmunity != "" && (bool)healthHandler) + { + healthHandler.GetComponent<PlayerImmunity>().IsImune(0.1f, (bulletCanDealDeamage ? damage : 1f) * dealDamageMultiplierr, bulletImmunity); + } + if ((bool)componentInParent.GetComponent<DamagableEvent>()) + { + componentInParent.CallTakeDamage(base.transform.forward * damage * dealDamageMultiplierr, hitInfo.point, ownWeapon, ownPlayer); + } + else + { + componentInParent.CallTakeDamage(base.transform.forward * (bulletCanDealDeamage ? damage : 1f) * dealDamageMultiplierr, hitInfo.point, ownWeapon, ownPlayer); + } + } + } + } + if ((bool)playerVelocity) + { + float num2 = 1f; + float num3 = Mathf.Clamp(playerVelocity.mass / 100f * num2, 0f, 1f) * num2; + float num4 = 1f; + playerVelocity.AddForce(-playerVelocity.velocity * 0.1f * playerVelocity.mass, ForceMode2D.Impulse); + if ((bool)healthHandler) + { + num *= 3f; + if (hasControl) + { + healthHandler.CallTakeForce(base.transform.forward * num4 * num3 * force); + } + } + } + if (isAllowedToSpawnObjects && !wasBlocked) + { + GamefeelManager.GameFeel(base.transform.forward * num * shake); + DynamicParticles.instance.PlayBulletHit(damage, base.transform, hitInfo, projectileColor); + for (int i = 0; i < objectsToSpawn.Length; i++) + { + ObjectsToSpawn.SpawnObject(base.transform, hitInfo, objectsToSpawn[i], healthHandler, team, damage, spawnedAttack, wasBlocked); + } + base.transform.position = hitInfo.point + hitInfo.normal * 0.01f; + } + if ((bool)hitInfo.transform) + { + NetworkPhysicsObject component4 = hitInfo.transform.GetComponent<NetworkPhysicsObject>(); + if ((bool)component4 && canPushBox) + { + component4.BulletPush(base.transform.forward * (force * 0.5f + damage * 100f), hitInfo.transform.InverseTransformPoint(hitInfo.point), spawnedAttack.spawner.data); + } + } + bool flag = false; + if (effects != null && effects.Count != 0) + { + for (int j = 0; j < effects.Count; j++) + { + HasToReturn num5 = effects[j].DoHitEffect(hitInfo); + if (num5 == HasToReturn.hasToReturn) + { + flag = true; + } + if (num5 == HasToReturn.hasToReturnNow) + { + return; + } + } + } + if (!flag) + { + if (hitAction != null) + { + hitAction(); + } + if (hitActionWithData != null) + { + hitActionWithData(hitInfo); + } + deathEvent.Invoke(); + DestroyMe(); + } + } + + private void DestroyMe() + { + if ((bool)view) + { + if (view.IsMine) + { + PhotonNetwork.Destroy(base.gameObject); + } + } + else + { + UnityEngine.Object.Destroy(base.gameObject); + } + } + + [PunRPC] + public void RPCA_CallCustomAction(string actionKey) + { + customActions[actionKey](); + } + + [PunRPC] + public void RPCA_CallCustomActionV2V2(string actionKey, Vector2 v1, Vector2 v2) + { + customActionsV2V2[actionKey](v1, v2); + } + + public void AddHitAction(Action action) + { + hitAction = (Action)Delegate.Combine(hitAction, action); + } + + public void AddHitActionWithData(Action<HitInfo> action) + { + hitActionWithData = (Action<HitInfo>)Delegate.Combine(hitActionWithData, action); + } +} diff --git a/GameCode/ProjectileHitEmpower.cs b/GameCode/ProjectileHitEmpower.cs new file mode 100644 index 0000000..3672ce1 --- /dev/null +++ b/GameCode/ProjectileHitEmpower.cs @@ -0,0 +1,17 @@ +using UnityEngine; + +public class ProjectileHitEmpower : RayHitEffect +{ + private bool done; + + public override HasToReturn DoHitEffect(HitInfo hit) + { + if (done) + { + return HasToReturn.canContinue; + } + GetComponentInParent<SpawnedAttack>().spawner.data.block.DoBlockAtPosition(firstBlock: true, dontSetCD: true, BlockTrigger.BlockTriggerType.Empower, hit.point - (Vector2)base.transform.forward * 0.05f, onlyBlockEffects: true); + done = true; + return HasToReturn.canContinue; + } +} diff --git a/GameCode/ProjectileHitSurface.cs b/GameCode/ProjectileHitSurface.cs new file mode 100644 index 0000000..04ae8f6 --- /dev/null +++ b/GameCode/ProjectileHitSurface.cs @@ -0,0 +1,12 @@ +using UnityEngine; + +public abstract class ProjectileHitSurface : MonoBehaviour +{ + public enum HasToStop + { + HasToStop, + CanKeepGoing + } + + public abstract HasToStop HitSurface(HitInfo hit, GameObject projectile); +} diff --git a/GameCode/ProjectileHitSurfaceShield.cs b/GameCode/ProjectileHitSurfaceShield.cs new file mode 100644 index 0000000..1587a0c --- /dev/null +++ b/GameCode/ProjectileHitSurfaceShield.cs @@ -0,0 +1,13 @@ +using UnityEngine; + +public class ProjectileHitSurfaceShield : ProjectileHitSurface +{ + public override HasToStop HitSurface(HitInfo hit, GameObject projectile) + { + if (Vector3.Angle(base.transform.parent.forward, projectile.transform.forward) < 90f) + { + return HasToStop.HasToStop; + } + return HasToStop.CanKeepGoing; + } +} diff --git a/GameCode/ProjectileInit.cs b/GameCode/ProjectileInit.cs new file mode 100644 index 0000000..3200eac --- /dev/null +++ b/GameCode/ProjectileInit.cs @@ -0,0 +1,49 @@ +using Photon.Pun; +using UnityEngine; + +public class ProjectileInit : MonoBehaviour +{ + private Gun[] guns; + + [PunRPC] + internal void RPCA_Init(int senderID, int nrOfProj, float dmgM, float randomSeed) + { + PlayerManager.instance.GetPlayerWithActorID(senderID).data.weaponHandler.gun.BulletInit(base.gameObject, nrOfProj, dmgM, randomSeed); + } + + internal void OFFLINE_Init(int senderID, int nrOfProj, float dmgM, float randomSeed) + { + PlayerManager.instance.players[senderID].data.weaponHandler.gun.BulletInit(base.gameObject, nrOfProj, dmgM, randomSeed); + } + + [PunRPC] + internal void RPCA_Init_SeparateGun(int senderID, int gunID, int nrOfProj, float dmgM, float randomSeed) + { + GetChildGunWithID(gunID, PlayerManager.instance.GetPlayerWithActorID(senderID).gameObject).BulletInit(base.gameObject, nrOfProj, dmgM, randomSeed); + } + + internal void OFFLINE_Init_SeparateGun(int senderID, int gunID, int nrOfProj, float dmgM, float randomSeed) + { + GetChildGunWithID(gunID, PlayerManager.instance.players[senderID].gameObject).BulletInit(base.gameObject, nrOfProj, dmgM, randomSeed); + } + + private Gun GetChildGunWithID(int id, GameObject player) + { + if (guns == null) + { + guns = player.GetComponentsInChildren<Gun>(); + } + return guns[id]; + } + + [PunRPC] + internal void RPCA_Init_noAmmoUse(int senderID, int nrOfProj, float dmgM, float randomSeed) + { + PlayerManager.instance.GetPlayerWithActorID(senderID).data.weaponHandler.gun.BulletInit(base.gameObject, nrOfProj, dmgM, randomSeed, useAmmo: false); + } + + internal void OFFLINE_Init_noAmmoUse(int senderID, int nrOfProj, float dmgM, float randomSeed) + { + PlayerManager.instance.players[senderID].data.weaponHandler.gun.BulletInit(base.gameObject, nrOfProj, dmgM, randomSeed, useAmmo: false); + } +} diff --git a/GameCode/ProjectilesToSpawn.cs b/GameCode/ProjectilesToSpawn.cs new file mode 100644 index 0000000..e92840b --- /dev/null +++ b/GameCode/ProjectilesToSpawn.cs @@ -0,0 +1,10 @@ +using System; +using UnityEngine; + +[Serializable] +public class ProjectilesToSpawn +{ + public GameObject objectToSpawn; + + public int numberOfSpawns = 1; +} diff --git a/GameCode/PublicInt.cs b/GameCode/PublicInt.cs new file mode 100644 index 0000000..98472b9 --- /dev/null +++ b/GameCode/PublicInt.cs @@ -0,0 +1,6 @@ +using UnityEngine; + +public class PublicInt : MonoBehaviour +{ + public int theInt; +} diff --git a/GameCode/QuitButton.cs b/GameCode/QuitButton.cs new file mode 100644 index 0000000..a441c3e --- /dev/null +++ b/GameCode/QuitButton.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +public class QuitButton : MonoBehaviour +{ + public void Quit() + { + Application.Quit(); + } +} diff --git a/GameCode/RadarShot.cs b/GameCode/RadarShot.cs new file mode 100644 index 0000000..ad589db --- /dev/null +++ b/GameCode/RadarShot.cs @@ -0,0 +1,61 @@ +using System.Collections; +using UnityEngine; + +public class RadarShot : MonoBehaviour +{ + private WeaponHandler wh; + + private Player player; + + public ParticleSystem[] boops; + + public float range = 12f; + + private void Start() + { + wh = GetComponentInParent<WeaponHandler>(); + player = GetComponentInParent<Player>(); + } + + public void Go() + { + Player closestPlayerInTeam = PlayerManager.instance.GetClosestPlayerInTeam(base.transform.position, PlayerManager.instance.GetOtherTeam(player.teamID), needVision: true); + if ((bool)closestPlayerInTeam && Vector2.Distance(player.transform.position, closestPlayerInTeam.transform.position) < range) + { + StartCoroutine(FollowTarget(closestPlayerInTeam)); + if (player.data.view.IsMine) + { + StartCoroutine(ShootAttacks(closestPlayerInTeam, GetComponent<AttackLevel>().attackLevel)); + } + } + } + + private IEnumerator ShootAttacks(Player target, int shots) + { + for (int i = 0; i < shots; i++) + { + yield return new WaitForSeconds(0.1f); + wh.gun.forceShootDir = wh.gun.GetRangeCompensation(Vector3.Distance(target.transform.position, player.transform.position)) * Vector3.up + target.transform.position - player.transform.position; + wh.gun.Attack(0f, forceAttack: true, 1f, 1f, useAmmo: false); + wh.gun.forceShootDir = Vector3.zero; + } + } + + private IEnumerator FollowTarget(Player target) + { + for (int i = 0; i < boops.Length; i++) + { + boops[i].Play(); + } + float c = 0f; + while (c < 1f) + { + c += TimeHandler.deltaTime; + for (int j = 0; j < boops.Length; j++) + { + boops[j].transform.position = target.transform.position; + } + yield return null; + } + } +} diff --git a/GameCode/Rage.cs b/GameCode/Rage.cs new file mode 100644 index 0000000..0e514dd --- /dev/null +++ b/GameCode/Rage.cs @@ -0,0 +1,29 @@ +using UnityEngine; + +public class Rage : MonoBehaviour +{ + private Player player; + + private AttackLevel level; + + public AnimationCurve curve; + + public AnimationCurve partCurve; + + private ParticleSystem.EmissionModule part; + + private void Start() + { + player = GetComponentInParent<Player>(); + level = GetComponentInParent<AttackLevel>(); + part = GetComponentInChildren<ParticleSystem>().emission; + player.data.SetWobbleObjectChild(GetComponentInChildren<ParticleSystem>().transform); + } + + private void Update() + { + float healthPercentage = player.data.HealthPercentage; + player.data.stats.rageSpeed = Mathf.Pow(curve.Evaluate(healthPercentage), level.LevelScale()); + part.rateOverTime = partCurve.Evaluate(player.data.stats.rageSpeed); + } +} diff --git a/GameCode/RayCastTrail.cs b/GameCode/RayCastTrail.cs new file mode 100644 index 0000000..4d508bd --- /dev/null +++ b/GameCode/RayCastTrail.cs @@ -0,0 +1,106 @@ +using System.Collections; +using System.Linq; +using UnityEngine; + +public class RayCastTrail : MonoBehaviour +{ + public LayerMask mask; + + public LayerMask playerMask; + + public LayerMask ignoreWallsMask; + + public int teamID = -1; + + private float timeAtSpawn; + + public float size; + + public float extraSize; + + private MoveTransform move; + + private Vector3 lastPos; + + private RayHit rayHit; + + private Rigidbody2D ignoredRig; + + private void Awake() + { + timeAtSpawn = Time.time; + } + + private void Start() + { + rayHit = GetComponent<RayHit>(); + ProjectileHit component = GetComponent<ProjectileHit>(); + if ((bool)component) + { + size = Mathf.Clamp(Mathf.Pow(component.damage, 0.85f) / 400f, 0f, 100f) + 0.3f + extraSize; + } + move = GetComponent<MoveTransform>(); + lastPos = base.transform.position; + } + + private void OnEnable() + { + lastPos = base.transform.position; + } + + private void Update() + { + RaycastHit2D[] first = Physics2D.RaycastAll(lastPos, base.transform.position - lastPos, Vector3.Distance(base.transform.position, lastPos), mask); + RaycastHit2D[] second = Physics2D.CircleCastAll(lastPos, size, base.transform.position - lastPos, Vector3.Distance(base.transform.position, lastPos), playerMask); + RaycastHit2D[] array = first.Concat(second).ToArray(); + RaycastHit2D raycastHit2D = default(RaycastHit2D); + raycastHit2D.distance = float.PositiveInfinity; + for (int i = 0; i < array.Length; i++) + { + if (!array[i] || array[i].transform.root == base.transform.root) + { + continue; + } + Player component = array[i].transform.root.GetComponent<Player>(); + if ((!component || component.playerID != teamID || !(timeAtSpawn + 0.2f >= Time.time)) && (!ignoredRig || !(ignoredRig == array[i].rigidbody))) + { + ProjectileHitSurface component2 = array[i].collider.GetComponent<ProjectileHitSurface>(); + if ((!component2 || component2.HitSurface(HitInfo.GetHitInfo(array[i]), base.gameObject) != 0) && array[i].distance < raycastHit2D.distance) + { + raycastHit2D = array[i]; + } + } + } + if ((bool)raycastHit2D.transform) + { + rayHit.Hit(HitInfo.GetHitInfo(raycastHit2D)); + } + if ((bool)GridVisualizer.instance) + { + GridVisualizer.instance.BulletCall(base.transform.position); + } + lastPos = base.transform.position; + } + + public void WasBlocked() + { + timeAtSpawn = 0f; + } + + public void MoveRay() + { + lastPos = base.transform.position; + } + + public void IgnoreRigFor(Rigidbody2D rig, float time) + { + StartCoroutine(DoIgnoreRigFor(rig, time)); + } + + private IEnumerator DoIgnoreRigFor(Rigidbody2D rig, float time) + { + ignoredRig = rig; + yield return new WaitForSeconds(time); + ignoredRig = null; + } +} diff --git a/GameCode/RayHit.cs b/GameCode/RayHit.cs new file mode 100644 index 0000000..22dce01 --- /dev/null +++ b/GameCode/RayHit.cs @@ -0,0 +1,6 @@ +using UnityEngine; + +public abstract class RayHit : MonoBehaviour +{ + public abstract void Hit(HitInfo hit, bool forceCall = false); +} diff --git a/GameCode/RayHitBash.cs b/GameCode/RayHitBash.cs new file mode 100644 index 0000000..e56603e --- /dev/null +++ b/GameCode/RayHitBash.cs @@ -0,0 +1,80 @@ +using UnityEngine; + +public class RayHitBash : RayHitEffect +{ + public float triggerChancePerTenDamage = 0.1f; + + public float baseTriggerChance = 0.2f; + + [Space(15f)] + public float stunMultiplier = 1f; + + public float stunTimePerTenDamage = 0.1f; + + public float baseStunTime = 1f; + + public bool cannotPermaStun; + + [Space(15f)] + public float stunTimeThreshold = 0.2f; + + public float stunTimeExponent = 1f; + + public float multiplierPerTenMeterTravelled; + + private MoveTransform move; + + private float multiplier = 1f; + + private void Start() + { + move = GetComponentInParent<MoveTransform>(); + multiplier = base.transform.localScale.x; + } + + public override HasToReturn DoHitEffect(HitInfo hit) + { + if (!hit.transform) + { + return HasToReturn.canContinue; + } + StunHandler component = hit.transform.GetComponent<StunHandler>(); + if ((bool)component) + { + ProjectileHit componentInParent = GetComponentInParent<ProjectileHit>(); + float num = 25f; + if ((bool)componentInParent) + { + num = componentInParent.damage; + } + float num2 = triggerChancePerTenDamage * num * 0.1f; + num2 += baseTriggerChance; + if (Random.value < num2) + { + float num3 = baseStunTime + stunTimePerTenDamage * num * 0.1f; + SetMultiplier(); + num3 *= stunMultiplier; + num3 = Mathf.Pow(num3, stunTimeExponent); + num3 *= multiplier; + if (cannotPermaStun) + { + num3 = Mathf.Clamp(num3, 0f, GetComponentInParent<SpawnedAttack>().spawner.data.weaponHandler.gun.attackSpeed * GetComponentInParent<SpawnedAttack>().spawner.data.stats.attackSpeedMultiplier + 0.3f); + } + if (num3 > stunTimeThreshold) + { + component.AddStun(num3); + } + } + } + return HasToReturn.canContinue; + } + + private void SetMultiplier() + { + float distanceTravelled = move.distanceTravelled; + if (multiplierPerTenMeterTravelled != 0f) + { + stunMultiplier = distanceTravelled * multiplierPerTenMeterTravelled * 0.1f; + } + } +} diff --git a/GameCode/RayHitBulletSound.cs b/GameCode/RayHitBulletSound.cs new file mode 100644 index 0000000..0e3d86c --- /dev/null +++ b/GameCode/RayHitBulletSound.cs @@ -0,0 +1,60 @@ +using Sonigon; +using UnityEngine; + +public class RayHitBulletSound : RayHitEffect +{ + [Header("Sound Settings")] + public bool disableImpact; + + public bool playLocalImpact; + + public SoundEvent soundLocalImpact; + + public bool localImpactVelocityToIntensity; + + private ProjectileHit projectileHit; + + private RayHitReflect rayHitReflect; + + private MoveTransform moveTransform; + + private SoundParameterIntensity soundIntensity = new SoundParameterIntensity(); + + private void Start() + { + projectileHit = GetComponent<ProjectileHit>(); + rayHitReflect = GetComponent<RayHitReflect>(); + moveTransform = GetComponent<MoveTransform>(); + } + + public override HasToReturn DoHitEffect(HitInfo hit) + { + if (disableImpact) + { + return HasToReturn.canContinue; + } + if (localImpactVelocityToIntensity) + { + soundIntensity.intensity = moveTransform.velocity.magnitude; + } + if (playLocalImpact) + { + if (soundLocalImpact != null && hit.collider != null && hit.collider.tag != "Player") + { + if (localImpactVelocityToIntensity) + { + SoundManager.Instance.PlayAtPosition(soundLocalImpact, SoundManager.Instance.GetTransform(), hit.point, soundIntensity); + } + else + { + SoundManager.Instance.PlayAtPosition(soundLocalImpact, SoundManager.Instance.GetTransform(), hit.point); + } + } + } + else + { + projectileHit.ownPlayer.data.weaponHandler.gun.soundGun.PlayImpact(hit, rayHitReflect); + } + return HasToReturn.canContinue; + } +} diff --git a/GameCode/RayHitDrill.cs b/GameCode/RayHitDrill.cs new file mode 100644 index 0000000..db2ee90 --- /dev/null +++ b/GameCode/RayHitDrill.cs @@ -0,0 +1,124 @@ +using UnityEngine; + +public class RayHitDrill : RayHitEffect +{ + public float metersOfDrilling = 1f; + + private MoveTransform move; + + private ProjectileHit proj; + + public bool mainDrill; + + private ChildRPC rpc; + + private int sinceDrill = 10; + + public float speedModFlat = 0.5f; + + public float speedMod = 0.1f; + + private bool done; + + private void Start() + { + move = GetComponentInParent<MoveTransform>(); + proj = GetComponentInParent<ProjectileHit>(); + proj.canPushBox = false; + RayHitDrill[] componentsInChildren = base.transform.root.GetComponentsInChildren<RayHitDrill>(); + if (componentsInChildren.Length == 1) + { + mainDrill = true; + } + bool flag = false; + int num = -1; + for (int i = 0; i < componentsInChildren.Length; i++) + { + if (componentsInChildren[i].mainDrill) + { + flag = true; + num = i; + } + } + if (flag) + { + if (componentsInChildren[num] != this) + { + componentsInChildren[num].metersOfDrilling += metersOfDrilling; + } + } + else + { + mainDrill = true; + } + if (mainDrill) + { + rpc = GetComponentInParent<ChildRPC>(); + rpc.childRPCsVector2.Add("DrillStop", RPCA_Deactivate); + } + } + + private void Update() + { + if (mainDrill && proj.view.IsMine) + { + if (sinceDrill > 2 && !proj.isAllowedToSpawnObjects) + { + rpc.CallFunction("DrillStop", base.transform.position); + } + sinceDrill++; + } + } + + public void RPCA_Deactivate(Vector2 tpPos) + { + base.transform.position = tpPos; + proj.isAllowedToSpawnObjects = true; + move.simulationSpeed /= speedModFlat; + move.simulationSpeed *= move.localForce.magnitude * speedMod; + proj.sendCollisions = true; + base.transform.GetChild(0).gameObject.SetActive(value: false); + if (metersOfDrilling < 2f) + { + metersOfDrilling = -1f; + } + } + + private void OnDestroy() + { + if (mainDrill && !proj.isAllowedToSpawnObjects) + { + Object.Instantiate(GetComponentInChildren<ParticleSystem>(includeInactive: true).gameObject, base.transform.position, base.transform.rotation).SetActive(value: true); + } + } + + public override HasToReturn DoHitEffect(HitInfo hit) + { + if (!mainDrill) + { + return HasToReturn.canContinue; + } + if (proj.isAllowedToSpawnObjects) + { + base.transform.root.position = hit.point; + move.simulationSpeed *= speedModFlat; + move.simulationSpeed /= move.localForce.magnitude * speedMod; + base.transform.GetChild(0).gameObject.SetActive(value: true); + base.transform.GetComponentInChildren<TrailRenderer>().Clear(); + } + sinceDrill = 0; + proj.isAllowedToSpawnObjects = false; + proj.sendCollisions = false; + metersOfDrilling -= move.velocity.magnitude * TimeHandler.deltaTime * move.simulationSpeed; + if (metersOfDrilling <= 0f) + { + done = true; + return HasToReturn.canContinue; + } + if (!hit.transform || (bool)hit.transform.root.GetComponent<Player>()) + { + return HasToReturn.canContinue; + } + return HasToReturn.hasToReturnNow; + } +} diff --git a/GameCode/RayHitEffect.cs b/GameCode/RayHitEffect.cs new file mode 100644 index 0000000..647dfa8 --- /dev/null +++ b/GameCode/RayHitEffect.cs @@ -0,0 +1,8 @@ +using UnityEngine; + +public abstract class RayHitEffect : MonoBehaviour +{ + public int priority; + + public abstract HasToReturn DoHitEffect(HitInfo hit); +} diff --git a/GameCode/RayHitPoison.cs b/GameCode/RayHitPoison.cs new file mode 100644 index 0000000..240f2eb --- /dev/null +++ b/GameCode/RayHitPoison.cs @@ -0,0 +1,36 @@ +using Sonigon; +using UnityEngine; + +public class RayHitPoison : RayHitEffect +{ + [Header("Sounds")] + public SoundEvent soundEventDamageOverTime; + + [Header("Settings")] + public float time = 2f; + + public float interval = 0.5f; + + public Color color = Color.red; + + private void Start() + { + GetComponentInParent<ProjectileHit>().bulletCanDealDeamage = false; + } + + public override HasToReturn DoHitEffect(HitInfo hit) + { + if (!hit.transform) + { + return HasToReturn.canContinue; + } + RayHitPoison[] componentsInChildren = base.transform.root.GetComponentsInChildren<RayHitPoison>(); + ProjectileHit componentInParent = GetComponentInParent<ProjectileHit>(); + DamageOverTime component = hit.transform.GetComponent<DamageOverTime>(); + if ((bool)component) + { + component.TakeDamageOverTime(componentInParent.damage * base.transform.forward / componentsInChildren.Length, base.transform.position, time, interval, color, soundEventDamageOverTime, GetComponentInParent<ProjectileHit>().ownWeapon, GetComponentInParent<ProjectileHit>().ownPlayer); + } + return HasToReturn.canContinue; + } +} diff --git a/GameCode/RayHitReflect.cs b/GameCode/RayHitReflect.cs new file mode 100644 index 0000000..182aa73 --- /dev/null +++ b/GameCode/RayHitReflect.cs @@ -0,0 +1,61 @@ +using System; +using UnityEngine; + +public class RayHitReflect : RayHitEffect +{ + private MoveTransform move; + + private ProjectileHit projHit; + + public int reflects = 1; + + public float speedM = 1f; + + public float dmgM = 1f; + + [HideInInspector] + public float timeOfBounce = -10000f; + + public Action<HitInfo> reflectAction; + + private void Start() + { + move = GetComponent<MoveTransform>(); + projHit = GetComponent<ProjectileHit>(); + } + + public override HasToReturn DoHitEffect(HitInfo hit) + { + if ((bool)hit.transform && (bool)hit.transform.GetComponent<Player>()) + { + reflects -= 10; + } + if (reflects <= 0) + { + return HasToReturn.canContinue; + } + if (reflectAction != null) + { + reflectAction(hit); + } + move.velocity = Vector2.Reflect(move.velocity, hit.normal); + move.velocity *= speedM; + projHit.damage *= dmgM; + projHit.shake *= dmgM; + if (dmgM > 1f) + { + float num = dmgM - 1f; + num *= 0.6f; + dmgM = num + 1f; + ScaleTrailFromDamage componentInChildren = GetComponentInChildren<ScaleTrailFromDamage>(); + if ((bool)componentInChildren) + { + componentInChildren.Rescale(); + } + } + timeOfBounce = Time.time; + base.transform.position = (Vector3)hit.point + move.velocity.normalized * 0.1f; + reflects--; + return HasToReturn.hasToReturn; + } +} diff --git a/GameCode/RaycastForward.cs b/GameCode/RaycastForward.cs new file mode 100644 index 0000000..14d176f --- /dev/null +++ b/GameCode/RaycastForward.cs @@ -0,0 +1,15 @@ +using UnityEngine; + +public class RaycastForward : MonoBehaviour +{ + public LayerMask mask; + + public float distance = 100f; + + public RaycastHit2D hit; + + private void LateUpdate() + { + hit = Physics2D.Raycast(base.transform.position, base.transform.forward, distance, mask); + } +} diff --git a/GameCode/RaycastSetScale.cs b/GameCode/RaycastSetScale.cs new file mode 100644 index 0000000..5c60b4c --- /dev/null +++ b/GameCode/RaycastSetScale.cs @@ -0,0 +1,23 @@ +using UnityEngine; + +public class RaycastSetScale : MonoBehaviour +{ + private RaycastForward raycast; + + private void Start() + { + raycast = GetComponent<RaycastForward>(); + } + + private void LateUpdate() + { + if ((bool)raycast.hit.transform) + { + base.transform.localScale = new Vector3(base.transform.localScale.x, base.transform.localScale.y, raycast.hit.distance); + } + else + { + base.transform.localScale = new Vector3(base.transform.localScale.x, base.transform.localScale.y, raycast.distance); + } + } +} diff --git a/GameCode/ReflectEvent.cs b/GameCode/ReflectEvent.cs new file mode 100644 index 0000000..eb3dab6 --- /dev/null +++ b/GameCode/ReflectEvent.cs @@ -0,0 +1,12 @@ +using UnityEngine.Events; + +public class ReflectEvent : RayHitEffect +{ + public UnityEvent bounceEvent; + + public override HasToReturn DoHitEffect(HitInfo hit) + { + bounceEvent.Invoke(); + return HasToReturn.canContinue; + } +} diff --git a/GameCode/RegenerateAfterStandStill.cs b/GameCode/RegenerateAfterStandStill.cs new file mode 100644 index 0000000..471aa10 --- /dev/null +++ b/GameCode/RegenerateAfterStandStill.cs @@ -0,0 +1,24 @@ +using UnityEngine; + +public class RegenerateAfterStandStill : MonoBehaviour +{ + private CharacterData data; + + public float heal = 2f; + + private PlayerInRangeTrigger trigger; + + private void Start() + { + trigger = GetComponent<PlayerInRangeTrigger>(); + data = GetComponentInParent<CharacterData>(); + } + + private void Update() + { + if (trigger.inRange) + { + data.healthHandler.Heal(heal); + } + } +} diff --git a/GameCode/RegionSelector.cs b/GameCode/RegionSelector.cs new file mode 100644 index 0000000..439279d --- /dev/null +++ b/GameCode/RegionSelector.cs @@ -0,0 +1,23 @@ +using TMPro; +using UnityEngine; + +public class RegionSelector : MonoBehaviour +{ + private TMP_Dropdown dropDown; + + public static string region = ""; + + private void Start() + { + dropDown = GetComponent<TMP_Dropdown>(); + region = dropDown.options[PlayerPrefs.GetInt("Region", 0)].text; + dropDown.value = PlayerPrefs.GetInt("Region", 0); + NetworkConnectionHandler.instance.hasRegionSelect = true; + } + + public void OnValueChanged() + { + PlayerPrefs.SetInt("Region", dropDown.value); + region = dropDown.options[dropDown.value].text; + } +} diff --git a/GameCode/ReloadTigger.cs b/GameCode/ReloadTigger.cs new file mode 100644 index 0000000..3a4c093 --- /dev/null +++ b/GameCode/ReloadTigger.cs @@ -0,0 +1,40 @@ +using System; +using UnityEngine; +using UnityEngine.Events; + +public class ReloadTigger : MonoBehaviour +{ + public UnityEvent reloadDoneEvent; + + public UnityEvent outOfAmmoEvent; + + private void Start() + { + CharacterStatModifiers componentInParent = GetComponentInParent<CharacterStatModifiers>(); + componentInParent.OnReloadDoneAction = (Action<int>)Delegate.Combine(componentInParent.OnReloadDoneAction, new Action<int>(OnReloadDone)); + CharacterStatModifiers componentInParent2 = GetComponentInParent<CharacterStatModifiers>(); + componentInParent2.OutOfAmmpAction = (Action<int>)Delegate.Combine(componentInParent2.OutOfAmmpAction, new Action<int>(OnOutOfAmmo)); + } + + private void OnDestroy() + { + CharacterStatModifiers componentInParent = GetComponentInParent<CharacterStatModifiers>(); + componentInParent.OnReloadDoneAction = (Action<int>)Delegate.Remove(componentInParent.OnReloadDoneAction, new Action<int>(OnReloadDone)); + CharacterStatModifiers componentInParent2 = GetComponentInParent<CharacterStatModifiers>(); + componentInParent2.OutOfAmmpAction = (Action<int>)Delegate.Remove(componentInParent2.OutOfAmmpAction, new Action<int>(OnOutOfAmmo)); + } + + private void OnReloadDone(int bulletsReloaded) + { + reloadDoneEvent.Invoke(); + } + + private void OnOutOfAmmo(int bulletsReloaded) + { + outOfAmmoEvent.Invoke(); + } + + private void Update() + { + } +} diff --git a/GameCode/RemoteControl.cs b/GameCode/RemoteControl.cs new file mode 100644 index 0000000..c0049bb --- /dev/null +++ b/GameCode/RemoteControl.cs @@ -0,0 +1,128 @@ +using Photon.Pun; +using Sonigon; +using SoundImplementation; +using UnityEngine; + +public class RemoteControl : MonoBehaviour +{ + [Header("Sound")] + public SoundEvent soundRemoteSteeringLoop; + + private bool soundIsPlaying; + + [Header("Settings")] + public bool snap; + + public float rotateSpeed = 1f; + + private SpawnedAttack spawned; + + private MoveTransform move; + + private float startVelocity; + + private bool isOn; + + private ProjectileHit hit; + + private ParticleSystem part; + + public ParticleSystem boopPart; + + private float c; + + private PhotonView view; + + private ChildRPC childRPC; + + private void OnDestroy() + { + if (soundRemoteSteeringLoop != null && spawned != null && spawned.spawner != null && soundIsPlaying) + { + soundIsPlaying = false; + SoundStaticRemoteControl.remoteControl.AddNumberOf(spawned.spawner.transform, -1); + if (SoundStaticRemoteControl.remoteControl.GetNumberOf(spawned.spawner.transform) <= 0) + { + SoundManager.Instance.Stop(soundRemoteSteeringLoop, spawned.spawner.transform); + } + } + } + + private void Start() + { + childRPC = GetComponentInParent<ChildRPC>(); + view = GetComponentInParent<PhotonView>(); + hit = GetComponentInParent<ProjectileHit>(); + move = GetComponentInParent<MoveTransform>(); + spawned = GetComponentInParent<SpawnedAttack>(); + startVelocity = move.velocity.magnitude; + part = GetComponentInChildren<ParticleSystem>(); + GetComponentInParent<SyncProjectile>().active = true; + if (soundRemoteSteeringLoop != null && spawned != null && spawned.spawner != null && !soundIsPlaying) + { + soundIsPlaying = true; + if (SoundStaticRemoteControl.remoteControl.GetNumberOf(spawned.spawner.transform) <= 0) + { + SoundManager.Instance.Play(soundRemoteSteeringLoop, spawned.spawner.transform); + } + SoundStaticRemoteControl.remoteControl.AddNumberOf(spawned.spawner.transform, 1); + } + } + + public void ToggleOn(bool isOn) + { + } + + private void Update() + { + if (!view.IsMine) + { + return; + } + Vector3 zero = Vector3.zero; + if (spawned.spawner.data.playerActions.Device != null) + { + zero = spawned.spawner.data.input.aimDirection; + } + else + { + zero = MainCam.instance.cam.ScreenToWorldPoint(Input.mousePosition) - base.transform.position; + zero.z = 0f; + zero.Normalize(); + } + zero += Vector3.Cross(Vector3.forward, zero) * move.selectedSpread; + c += TimeHandler.deltaTime; + if (snap) + { + if (spawned.spawner.data.block.blockedThisFrame) + { + part.Play(); + move.velocity *= -1f; + base.enabled = false; + } + } + else if (zero.magnitude > 0.2f && hit.sinceReflect > 2f) + { + move.velocity = Vector3.RotateTowards(move.velocity, zero.normalized * startVelocity, rotateSpeed * TimeHandler.deltaTime, rotateSpeed * TimeHandler.deltaTime * 10f); + if (c > 0.1f) + { + boopPart.transform.parent.rotation = Quaternion.LookRotation(zero); + boopPart?.Emit(1); + c = 0f; + } + if (!isOn) + { + move.simulateGravity++; + } + isOn = true; + } + else + { + if (isOn) + { + move.simulateGravity--; + } + isOn = false; + } + } +} diff --git a/GameCode/RemoveAfterSeconds.cs b/GameCode/RemoveAfterSeconds.cs new file mode 100644 index 0000000..8232562 --- /dev/null +++ b/GameCode/RemoveAfterSeconds.cs @@ -0,0 +1,54 @@ +using UnityEngine; + +public class RemoveAfterSeconds : MonoBehaviour +{ + public float seconds = 3f; + + private float startSeconds; + + public bool shrink; + + public bool scaleWithScale; + + private float shrinkSpeed = 1f; + + private Vector3 startScale; + + private AnimationCurve curve = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f); + + private float counter; + + private void Start() + { + startSeconds = seconds; + startScale = base.transform.localScale; + shrinkSpeed = Random.Range(1.5f, 2.5f); + } + + private void Update() + { + seconds -= TimeHandler.deltaTime * (scaleWithScale ? (1f / base.transform.localScale.x) : 1f); + if (!(seconds < 0f)) + { + return; + } + if (shrink) + { + counter += Time.deltaTime * shrinkSpeed; + base.transform.localScale = Vector3.Lerp(startScale, Vector3.zero, curve.Evaluate(counter)); + if (counter > 1f) + { + Object.Destroy(base.gameObject); + } + } + else + { + Object.Destroy(base.gameObject); + } + } + + public void ResetCounter() + { + seconds = startSeconds; + } +} diff --git a/GameCode/RemoveAfterSecondsScale.cs b/GameCode/RemoveAfterSecondsScale.cs new file mode 100644 index 0000000..967091c --- /dev/null +++ b/GameCode/RemoveAfterSecondsScale.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +public class RemoveAfterSecondsScale : MonoBehaviour +{ + private void Start() + { + GetComponent<RemoveAfterSeconds>().seconds *= base.transform.localScale.x; + } +} diff --git a/GameCode/RescaleFromDamage.cs b/GameCode/RescaleFromDamage.cs new file mode 100644 index 0000000..f9e8a29 --- /dev/null +++ b/GameCode/RescaleFromDamage.cs @@ -0,0 +1,25 @@ +using UnityEngine; + +public class RescaleFromDamage : MonoBehaviour +{ + private ProjectileHit hit; + + private float startScale; + + private void Start() + { + startScale = base.transform.localScale.x; + } + + public void Rescale() + { + if (!hit) + { + hit = GetComponentInParent<ProjectileHit>(); + } + if ((bool)hit) + { + base.transform.localScale = Vector3.one * startScale * (hit.damage / 55f); + } + } +} diff --git a/GameCode/RescaleFromDamagePart.cs b/GameCode/RescaleFromDamagePart.cs new file mode 100644 index 0000000..ebc37f7 --- /dev/null +++ b/GameCode/RescaleFromDamagePart.cs @@ -0,0 +1,28 @@ +using UnityEngine; + +public class RescaleFromDamagePart : MonoBehaviour +{ + private ProjectileHit hit; + + private float startSize; + + private ParticleSystem part; + + private void Start() + { + part = GetComponent<ParticleSystem>(); + startSize = part.startSize; + } + + public void Rescale() + { + if (!hit) + { + hit = GetComponentInParent<ProjectileHit>(); + } + if ((bool)hit) + { + part.startSize = startSize * (hit.damage / 55f); + } + } +} diff --git a/GameCode/ResetBlock.cs b/GameCode/ResetBlock.cs new file mode 100644 index 0000000..9371a2f --- /dev/null +++ b/GameCode/ResetBlock.cs @@ -0,0 +1,16 @@ +using UnityEngine; + +public class ResetBlock : MonoBehaviour +{ + private Block block; + + private void Start() + { + block = base.transform.root.GetComponent<Block>(); + } + + public void Go() + { + block.ResetCD(soundPlay: false); + } +} diff --git a/GameCode/RespawnEvent.cs b/GameCode/RespawnEvent.cs new file mode 100644 index 0000000..7abb88d --- /dev/null +++ b/GameCode/RespawnEvent.cs @@ -0,0 +1,19 @@ +using System; +using UnityEngine; +using UnityEngine.Events; + +public class RespawnEvent : MonoBehaviour +{ + public UnityEvent reviveEvent; + + private void Start() + { + HealthHandler healthHandler = GetComponentInParent<Player>().data.healthHandler; + healthHandler.reviveAction = (Action)Delegate.Combine(healthHandler.reviveAction, new Action(DoEvent)); + } + + public void DoEvent() + { + reviveEvent.Invoke(); + } +} diff --git a/GameCode/RigLookUp.cs b/GameCode/RigLookUp.cs new file mode 100644 index 0000000..2f62a80 --- /dev/null +++ b/GameCode/RigLookUp.cs @@ -0,0 +1,18 @@ +using UnityEngine; + +public class RigLookUp : MonoBehaviour +{ + private Rigidbody2D rig; + + public float force; + + private void Start() + { + rig = GetComponent<Rigidbody2D>(); + } + + private void FixedUpdate() + { + rig.AddTorque(Vector3.Cross(base.transform.up, Vector3.up).normalized.z * force * rig.mass * Vector3.Angle(base.transform.up, Vector3.up), ForceMode2D.Force); + } +} diff --git a/GameCode/RightLeftMirrorSpring.cs b/GameCode/RightLeftMirrorSpring.cs new file mode 100644 index 0000000..b13966c --- /dev/null +++ b/GameCode/RightLeftMirrorSpring.cs @@ -0,0 +1,46 @@ +using UnityEngine; + +public class RightLeftMirrorSpring : MonoBehaviour +{ + public Vector3 leftPos; + + private Vector3 rightPos; + + public float leftRot; + + public float rightRot; + + private Vector3 posVel; + + private float rotVel; + + public float drag = 25f; + + public float spring = 25f; + + private Holdable holdable; + + private float currentRot; + + private void Start() + { + currentRot = base.transform.localEulerAngles.z; + holdable = base.transform.root.GetComponent<Holdable>(); + rightPos = base.transform.localPosition; + } + + private void Update() + { + if ((bool)holdable && (bool)holdable.holder) + { + bool num = base.transform.root.position.x - 0.1f < holdable.holder.transform.position.x; + Vector3 vector = (num ? leftPos : rightPos); + float num2 = (num ? leftRot : rightRot); + posVel = FRILerp.Lerp(posVel, (vector - base.transform.localPosition) * spring, drag); + rotVel = FRILerp.Lerp(rotVel, (num2 - currentRot) * spring, drag); + currentRot += rotVel * TimeHandler.deltaTime; + base.transform.localPosition += posVel * TimeHandler.deltaTime; + base.transform.localEulerAngles = new Vector3(0f, 0f, currentRot); + } + } +} diff --git a/GameCode/RingHandler.cs b/GameCode/RingHandler.cs new file mode 100644 index 0000000..10ac321 --- /dev/null +++ b/GameCode/RingHandler.cs @@ -0,0 +1,52 @@ +using UnityEngine; + +public class RingHandler : MonoBehaviour +{ + public float timeBeforeRing = 30f; + + public static RingHandler instance; + + private CodeAnimation code; + + private float counter; + + private void Awake() + { + instance = this; + } + + private void Start() + { + code = GetComponent<CodeAnimation>(); + } + + private void Update() + { + if (GameManager.instance.isPlaying) + { + if (code.currentState != 0 && counter > timeBeforeRing && !code.isPlaying) + { + code.PlayIn(); + } + counter += TimeHandler.deltaTime; + } + else + { + if (code.currentState != CodeAnimationInstance.AnimationUse.Out && !code.isPlaying) + { + code.PlayOut(); + } + counter = 0f; + } + } + + public Vector2 ClosestPoint(Vector2 pos) + { + return pos.normalized * Radius(); + } + + public float Radius() + { + return base.transform.localScale.x * 95f; + } +} diff --git a/GameCode/RotSpring.cs b/GameCode/RotSpring.cs new file mode 100644 index 0000000..402fa90 --- /dev/null +++ b/GameCode/RotSpring.cs @@ -0,0 +1,43 @@ +using UnityEngine; + +public class RotSpring : MonoBehaviour +{ + public bool x; + + public bool y; + + public bool z; + + public float target; + + public float spring; + + public float damper; + + private float currentValue; + + private float vel; + + private void Start() + { + if (x) + { + currentValue = base.transform.localEulerAngles.x; + } + else if (y) + { + currentValue = base.transform.localEulerAngles.y; + } + else if (z) + { + currentValue = base.transform.localEulerAngles.z; + } + } + + private void Update() + { + vel = FRILerp.Lerp(vel, (target - currentValue) * spring, damper); + currentValue += vel * TimeHandler.deltaTime; + base.transform.localEulerAngles = new Vector3(x ? currentValue : 0f, y ? currentValue : 0f, z ? currentValue : 0f); + } +} diff --git a/GameCode/Rotate.cs b/GameCode/Rotate.cs new file mode 100644 index 0000000..04f9889 --- /dev/null +++ b/GameCode/Rotate.cs @@ -0,0 +1,11 @@ +using UnityEngine; + +public class Rotate : MonoBehaviour +{ + public float speed; + + private void Update() + { + base.transform.Rotate(Vector3.forward * speed * TimeHandler.deltaTime, Space.World); + } +} diff --git a/GameCode/RotatingShooter.cs b/GameCode/RotatingShooter.cs new file mode 100644 index 0000000..cdeef51 --- /dev/null +++ b/GameCode/RotatingShooter.cs @@ -0,0 +1,69 @@ +using System.Collections; +using Sirenix.OdinInspector; +using UnityEngine; + +public class RotatingShooter : MonoBehaviour +{ + private Gun gun; + + [HideInInspector] + public float charge; + + public int bulletsToFire = 10; + + private int currentBulletsToFire = 10; + + private float degreesPerBullet; + + [FoldoutGroup("Weird settings", 0)] + public bool destroyAfterAttack = true; + + [FoldoutGroup("Weird settings", 0)] + public bool disableTrailRenderer = true; + + private AttackLevel level; + + private void Start() + { + level = GetComponentInParent<AttackLevel>(); + gun = GetComponent<Gun>(); + if (disableTrailRenderer) + { + base.transform.root.GetComponentInChildren<TrailRenderer>(includeInactive: true).enabled = false; + } + } + + public void Attack() + { + currentBulletsToFire = bulletsToFire; + if ((bool)level) + { + currentBulletsToFire = bulletsToFire * level.attackLevel; + } + degreesPerBullet = 360f / (float)currentBulletsToFire; + StartCoroutine(RotateAndShoot()); + } + + private IEnumerator RotateAndShoot() + { + int shotsToMake = Mathf.Clamp(Mathf.RoundToInt(0.5f / gun.attackSpeed), 1, 5); + for (int i = 0; i < shotsToMake; i++) + { + for (int num = currentBulletsToFire; num > 0; num--) + { + base.transform.localEulerAngles = new Vector3(0f, (float)num * degreesPerBullet, 0f); + gun.Attack(gun.currentCharge, forceAttack: true); + } + if (shotsToMake > i) + { + yield return new WaitForSeconds(0.1f); + } + } + base.transform.localEulerAngles = new Vector3(0f, 0f, 0f); + yield return null; + if (destroyAfterAttack) + { + Object.Destroy(base.transform.root.gameObject); + } + } +} diff --git a/GameCode/RotationHandler.cs b/GameCode/RotationHandler.cs new file mode 100644 index 0000000..121bda8 --- /dev/null +++ b/GameCode/RotationHandler.cs @@ -0,0 +1,21 @@ +using UnityEngine; + +public class RotationHandler : MonoBehaviour +{ + private CharacterData data; + + private PlayerVelocity rig; + + public float torque; + + private void Start() + { + data = GetComponent<CharacterData>(); + rig = GetComponent<PlayerVelocity>(); + } + + private void FixedUpdate() + { + rig.AddTorque(torque * TimeHandler.timeScale * (Vector3.Angle(Vector3.up, base.transform.up) * Vector3.Cross(Vector3.up, base.transform.up).normalized).z); + } +} diff --git a/GameCode/RoundCounter.cs b/GameCode/RoundCounter.cs new file mode 100644 index 0000000..6666a25 --- /dev/null +++ b/GameCode/RoundCounter.cs @@ -0,0 +1,124 @@ +using UnityEngine; +using UnityEngine.UI; + +public class RoundCounter : MonoBehaviour +{ + public int p1Rounds; + + public int p2Rounds; + + public int p1Points; + + public int p2Points; + + public Transform p1Parent; + + public Transform p2Parent; + + public Color offColor; + + public Populate p1Populate; + + public Populate p2Populate; + + private int roundsNeeded; + + private void Start() + { + p1Parent.gameObject.SetActive(value: true); + p2Parent.gameObject.SetActive(value: true); + } + + public void UpdateRounds(int r1, int r2) + { + p1Rounds = r1; + p2Rounds = r2; + ReDraw(); + } + + private void Clear() + { + for (int i = 0; i < p1Parent.childCount; i++) + { + if (p1Populate.transform.GetChild(i).gameObject.activeSelf) + { + Object.Destroy(p1Populate.transform.GetChild(i).gameObject); + } + } + for (int j = 0; j < p2Parent.childCount; j++) + { + if (p2Populate.transform.GetChild(j).gameObject.activeSelf) + { + Object.Destroy(p2Populate.transform.GetChild(j).gameObject); + } + } + } + + private void Populate() + { + p1Populate.times = roundsNeeded; + p1Populate.DoPopulate(); + p2Populate.times = roundsNeeded; + p2Populate.DoPopulate(); + } + + public void UpdatePoints(int p1, int p2) + { + p1Points = p1; + p2Points = p2; + ReDraw(); + } + + private void ReDraw() + { + for (int i = 0; i < p1Parent.childCount; i++) + { + if (p1Rounds + p1Points > i) + { + p1Parent.GetChild(i).GetComponentInChildren<Image>().color = PlayerSkinBank.GetPlayerSkinColors(0).winText; + if (p1Rounds > i) + { + p1Parent.GetChild(i).localScale = Vector3.one; + } + } + else + { + p1Parent.GetChild(i).GetComponentInChildren<Image>().color = offColor; + p1Parent.GetChild(i).localScale = Vector3.one * 0.3f; + } + } + for (int j = 0; j < p2Parent.childCount; j++) + { + if (p2Rounds + p2Points > j) + { + p2Parent.GetChild(j).GetComponentInChildren<Image>().color = PlayerSkinBank.GetPlayerSkinColors(1).winText; + if (p2Rounds > j) + { + p2Parent.GetChild(j).localScale = Vector3.one; + } + } + else + { + p2Parent.GetChild(j).GetComponentInChildren<Image>().color = offColor; + p2Parent.GetChild(j).localScale = Vector3.one * 0.3f; + } + } + } + + internal Vector3 GetPointPos(int teamID) + { + if (teamID == 0) + { + return p1Parent.GetChild(p1Rounds).transform.position; + } + return p2Parent.GetChild(p2Rounds).transform.position; + } + + internal void SetNumberOfRounds(int roundsToWinGame) + { + roundsNeeded = roundsToWinGame; + Clear(); + Populate(); + ReDraw(); + } +} diff --git a/GameCode/RoundModifier.cs b/GameCode/RoundModifier.cs new file mode 100644 index 0000000..d1c1ac6 --- /dev/null +++ b/GameCode/RoundModifier.cs @@ -0,0 +1,12 @@ +using UnityEngine; +using UnityEngine.UI.ProceduralImage; + +[ModifierID("Round")] +public class RoundModifier : ProceduralImageModifier +{ + public override Vector4 CalculateRadius(Rect imageRect) + { + float num = Mathf.Min(imageRect.width, imageRect.height) * 0.5f; + return new Vector4(num, num, num, num); + } +} diff --git a/GameCode/RunSmoke.cs b/GameCode/RunSmoke.cs new file mode 100644 index 0000000..6e45d62 --- /dev/null +++ b/GameCode/RunSmoke.cs @@ -0,0 +1,62 @@ +using UnityEngine; + +public class RunSmoke : MonoBehaviour +{ + private CharacterData data; + + private ParticleSystem part; + + private float c; + + private bool groundedLastFrame; + + private ParticleSystem.MainModule partVel; + + private bool didTryToEmit; + + private Vector3 vel; + + private void Start() + { + part = GetComponent<ParticleSystem>(); + data = GetComponentInParent<CharacterData>(); + partVel = part.main; + } + + private void Update() + { + didTryToEmit = false; + if (data.isGrounded && Mathf.Abs(data.playerVel.velocity.x) > 5f) + { + base.transform.position = new Vector3(data.transform.position.x, data.groundPos.y, 5f); + Go(); + } + else if (data.isWallGrab && data.wallDistance < 0.7f && data.playerVel.velocity.magnitude > 5f) + { + base.transform.position = new Vector3(data.wallPos.x, data.transform.position.y, 5f); + Go(); + } + if (didTryToEmit) + { + vel = Vector3.Lerp(vel, data.playerVel.velocity, TimeHandler.deltaTime * 2f); + } + else + { + vel = Vector3.Lerp(vel, Vector3.zero, TimeHandler.deltaTime * 10f); + } + } + + private void Go() + { + didTryToEmit = true; + c += TimeHandler.deltaTime; + if (c > 0.02f) + { + c = 0f; + float num = 2f; + part.transform.rotation = Quaternion.LookRotation(vel); + partVel.startSpeedMultiplier = data.playerVel.velocity.magnitude * num; + part.Emit(2); + } + } +} diff --git a/GameCode/SFLight.cs b/GameCode/SFLight.cs new file mode 100644 index 0000000..8ff6e38 --- /dev/null +++ b/GameCode/SFLight.cs @@ -0,0 +1,350 @@ +using System.Collections.Generic; +using UnityEngine; + +[RequireComponent(typeof(RectTransform))] +public class SFLight : MonoBehaviour +{ + private class VertexArray + { + public int capacity; + + public int size; + + public Vector3[] verts; + + public Vector4[] tangents; + + public Vector2[] uvs; + + public int[] tris; + + public VertexArray(int segments) + { + capacity = segments; + size = 0; + verts = new Vector3[segments * 4]; + tangents = new Vector4[segments * 4]; + uvs = new Vector2[segments * 4]; + tris = new int[segments * 6]; + } + } + + [Tooltip("The radius of the light source. Larger lights cast softer shadows.")] + public float _radius = 0.5f; + + [Tooltip("The brightness of the light. (Ignored when using non-linear light blending.) Allows for colors brighter than 1.0 in HDR lighting situations.")] + public float _intensity = 1f; + + [Tooltip("The color of the light.")] + public Color _color = Color.white; + + [Tooltip("The shape of the light.")] + public Texture2D _cookieTexture; + + [Tooltip("Which layers cast shadows.")] + public LayerMask _shadowLayers = -1; + + [Tooltip("Allows the light cookie to move off the light plane. Use gently as it can cause shadows to look weird.")] + public bool _parallaxLight; + + private RectTransform _rt; + + public static List<SFLight> _lights = new List<SFLight>(); + + private Rect _cullBounds; + + private static int GROWTH_NUM = 4; + + private static int GROWTH_DENOM = 3; + + private static VertexArray[] vertexArrays = new VertexArray[40]; + + public float radius + { + get + { + return _radius; + } + set + { + _radius = value; + } + } + + public float intensity + { + get + { + return _intensity; + } + set + { + _intensity = value; + } + } + + public Color color + { + get + { + return _color; + } + set + { + _color = value; + } + } + + public Texture2D cookieTexture + { + get + { + return _cookieTexture; + } + set + { + _cookieTexture = value; + } + } + + public LayerMask shadowLayers + { + get + { + return _shadowLayers; + } + set + { + _shadowLayers = value; + } + } + + public bool parallaxLight + { + get + { + return _parallaxLight; + } + set + { + _parallaxLight = value; + } + } + + public Rect _bounds => _rt.rect; + + public Rect _CullBounds => _cullBounds; + + private void OnEnable() + { + _lights.Add(this); + } + + private void OnDisable() + { + _lights.Remove(this); + } + + public Matrix4x4 _ModelMatrix(bool forceProjection) + { + if (!_rt) + { + _rt = GetComponent<RectTransform>(); + } + Matrix4x4 localToWorldMatrix = _rt.localToWorldMatrix; + if (!_parallaxLight || forceProjection) + { + localToWorldMatrix.SetRow(2, new Vector4(0f, 0f, 1f, 0f)); + } + return localToWorldMatrix; + } + + public Matrix4x4 _CookieMatrix() + { + if (!_rt) + { + _rt = GetComponent<RectTransform>(); + } + Vector2 vector = _rt.sizeDelta / 2f; + Vector2 vector2 = Vector2.one - 2f * _rt.pivot; + Matrix4x4 identity = Matrix4x4.identity; + identity.SetRow(0, new Vector4(vector.x, 0f, 0f, vector2.x * vector.x)); + identity.SetRow(1, new Vector4(0f, vector.y, 0f, vector2.y * vector.y)); + return identity; + } + + private static Rect Union(Rect r1, Rect r2) + { + return Rect.MinMaxRect(Mathf.Min(r1.xMin, r2.xMin), Mathf.Min(r1.yMin, r2.yMin), Mathf.Max(r1.xMax, r2.xMax), Mathf.Max(r1.yMax, r2.yMax)); + } + + private static Rect QuadrantCull(Rect cull, Matrix4x4 mvp, Rect r) + { + if (!SFRenderer._FastCull(mvp, r)) + { + return cull; + } + return Union(cull, r); + } + + public Rect _CalcCullBounds(Matrix4x4 vpMatrix) + { + Matrix4x4 matrix4x = _ModelMatrix(forceProjection: true); + Matrix4x4 mvp = vpMatrix * matrix4x; + Rect rect = new Rect(0f - _radius, 0f - _radius, 2f * _radius, 2f * _radius); + Rect rect2 = _rt.rect; + Rect cull = rect; + cull = QuadrantCull(cull, mvp, Rect.MinMaxRect(rect2.xMin, rect2.yMin, rect.xMax, rect.yMax)); + cull = QuadrantCull(cull, mvp, Rect.MinMaxRect(rect.xMin, rect2.yMin, rect2.xMax, rect.yMax)); + cull = QuadrantCull(cull, mvp, Rect.MinMaxRect(rect2.xMin, rect.yMin, rect.xMax, rect2.yMax)); + cull = QuadrantCull(cull, mvp, Rect.MinMaxRect(rect.xMin, rect.yMin, rect2.xMax, rect2.yMax)); + return _cullBounds = SFRenderer._TransformRect(matrix4x, cull); + } + + private VertexArray GetVertexArray(int segments) + { + int num = 0; + int num2 = 4; + while (segments > num2) + { + num2 = num2 * GROWTH_NUM / GROWTH_DENOM; + num++; + } + if (num >= vertexArrays.Length) + { + Debug.LogError("SFSS: Maximum vertexes per light exceeded. (" + num2 + ")"); + return null; + } + if (vertexArrays[num] == null) + { + vertexArrays[num] = new VertexArray(num2); + } + return vertexArrays[num]; + } + + private void BatchPath(SFPolygon poly, int pathIndex, Matrix4x4 t, ref int j, bool flipped, Vector3 properties, Vector3[] verts, Vector4[] tangents, Vector2[] uvs, int[] tris) + { + Vector2[] path = poly.GetPath(pathIndex); + int num; + Vector2 vector; + if (poly.looped) + { + num = 0; + vector = Transform(t, path[^1]); + } + else + { + num = 1; + vector = Transform(t, path[0]); + } + for (int i = num; i < path.Length; i++) + { + Vector2 vector2 = Transform(t, path[i]); + Vector4 vector3 = (flipped ? new Vector4(vector2.x, vector2.y, vector.x, vector.y) : new Vector4(vector.x, vector.y, vector2.x, vector2.y)); + verts[j * 4] = properties; + tangents[j * 4] = vector3; + uvs[j * 4] = new Vector2(0f, 0f); + verts[j * 4 + 1] = properties; + tangents[j * 4 + 1] = vector3; + uvs[j * 4 + 1] = new Vector2(1f, 0f); + verts[j * 4 + 2] = properties; + tangents[j * 4 + 2] = vector3; + uvs[j * 4 + 2] = new Vector2(0f, 1f); + verts[j * 4 + 3] = properties; + tangents[j * 4 + 3] = vector3; + uvs[j * 4 + 3] = new Vector2(1f, 1f); + tris[j * 6] = j * 4; + tris[j * 6 + 1] = j * 4 + 1; + tris[j * 6 + 2] = j * 4 + 2; + tris[j * 6 + 3] = j * 4 + 1; + tris[j * 6 + 4] = j * 4 + 3; + tris[j * 6 + 5] = j * 4 + 2; + j++; + vector = vector2; + } + } + + public Mesh _BuildShadowMesh(Mesh mesh, List<SFPolygon> polys, float minLightPenetration) + { + int num = 0; + for (int i = 0; i < polys.Count; i++) + { + if (((int)polys[i].shadowLayers & (int)shadowLayers) == 0) + { + continue; + } + SFPolygon sFPolygon = polys[i]; + int activePath = sFPolygon.activePath; + bool looped = sFPolygon.looped; + if (activePath >= 0) + { + num += sFPolygon.GetPath(activePath).Length - ((!looped) ? 1 : 0); + continue; + } + int pathCount = sFPolygon.pathCount; + for (int j = 0; j < pathCount; j++) + { + num += sFPolygon.GetPath(j).Length - ((!looped) ? 1 : 0); + } + } + VertexArray vertexArray = GetVertexArray(num); + Vector3[] verts = vertexArray.verts; + Vector4[] tangents = vertexArray.tangents; + Vector2[] uvs = vertexArray.uvs; + int[] tris = vertexArray.tris; + if (num == 0 || vertexArray.capacity == 0) + { + return null; + } + if (!_rt) + { + _rt = GetComponent<RectTransform>(); + } + Matrix4x4 worldToLocalMatrix = _rt.worldToLocalMatrix; + int j2 = 0; + for (int k = 0; k < polys.Count; k++) + { + SFPolygon sFPolygon2 = polys[k]; + if (((int)sFPolygon2.shadowLayers & (int)shadowLayers) == 0) + { + continue; + } + Matrix4x4 matrix4x = sFPolygon2._GetMatrix(); + Matrix4x4 t = worldToLocalMatrix * matrix4x; + bool flipped = Det2x3(matrix4x) < 0f; + float y = Mathf.Max(sFPolygon2._lightPenetration, minLightPenetration); + Vector3 properties = new Vector3(_radius, y, sFPolygon2._opacity); + int activePath2 = sFPolygon2.activePath; + if (activePath2 >= 0) + { + BatchPath(sFPolygon2, activePath2, t, ref j2, flipped, properties, verts, tangents, uvs, tris); + continue; + } + int pathCount2 = sFPolygon2.pathCount; + for (int l = 0; l < pathCount2; l++) + { + BatchPath(sFPolygon2, l, t, ref j2, flipped, properties, verts, tangents, uvs, tris); + } + } + for (int m = 6 * num; m < 6 * vertexArray.size; m++) + { + vertexArray.tris[m] = 0; + } + mesh.vertices = verts; + mesh.tangents = tangents; + mesh.uv = uvs; + mesh.triangles = tris; + vertexArray.size = num; + return mesh; + } + + private static float Det2x3(Matrix4x4 m) + { + return m[0] * m[5] - m[1] * m[4]; + } + + private static Vector2 Transform(Matrix4x4 m, Vector2 p) + { + return new Vector2(p.x * m[0] + p.y * m[4] + m[12], p.x * m[1] + p.y * m[5] + m[13]); + } +} diff --git a/GameCode/SFPolygon.cs b/GameCode/SFPolygon.cs new file mode 100644 index 0000000..c806c1c --- /dev/null +++ b/GameCode/SFPolygon.cs @@ -0,0 +1,338 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +public class SFPolygon : MonoBehaviour +{ + private Transform _t; + + private Rect _bounds; + + private Rect _worldBounds; + + [SerializeField] + private Vector2[] _verts = new Vector2[3]; + + [SerializeField] + private Vector2[][] _paths; + + public int _activePath; + + public bool _looped; + + public LayerMask _shadowLayers = -1; + + public float _lightPenetration; + + public float _opacity = 1f; + + public static List<SFPolygon> _polygons = new List<SFPolygon>(); + + public Rect _WorldBounds => _worldBounds; + + public int pathCount + { + get + { + if (_paths != null) + { + return _paths.Length + 1; + } + return 1; + } + set + { + int num = value - 1; + if (value == pathCount) + { + return; + } + if (value < 1) + { + Debug.LogError("pathCount must be positive."); + return; + } + if (value == 1) + { + _paths = null; + } + else if (_paths == null) + { + _paths = new Vector2[num][]; + for (int i = 0; i < _paths.Length; i++) + { + _paths[i] = _verts; + } + } + else + { + Vector2[][] paths = _paths; + _paths = new Vector2[num][]; + if (num > paths.Length) + { + int j; + for (j = 0; j < paths.Length; j++) + { + _paths[j] = paths[j]; + } + for (; j < num; j++) + { + _paths[j] = _verts; + } + } + else + { + for (int k = 0; k < num; k++) + { + _paths[k] = paths[k]; + } + } + } + _UpdateBounds(); + } + } + + public Vector2[] verts + { + get + { + return _verts; + } + set + { + _verts = value; + } + } + + public int activePath + { + get + { + return _activePath; + } + set + { + _activePath = value; + } + } + + public bool looped + { + get + { + return _looped; + } + set + { + _looped = value; + } + } + + public LayerMask shadowLayers + { + get + { + return _shadowLayers; + } + set + { + _shadowLayers = value; + } + } + + public float lightPenetration + { + get + { + return _lightPenetration; + } + set + { + _lightPenetration = value; + } + } + + public float opacity + { + get + { + return _opacity; + } + set + { + _opacity = value; + } + } + + public Matrix4x4 _GetMatrix() + { + if (!_t) + { + _t = base.transform; + } + return _t.localToWorldMatrix; + } + + private void PathBounds(Vector2[] path, int i0, ref float l, ref float b, ref float r, ref float t) + { + for (int j = i0; j < path.Length; j++) + { + Vector2 vector = path[j]; + l = Mathf.Min(vector.x, l); + r = Mathf.Max(vector.x, r); + b = Mathf.Min(vector.y, b); + t = Mathf.Max(vector.y, t); + } + } + + public void _UpdateBounds() + { + float l; + float r; + float b; + float t; + if (_activePath > 0) + { + Vector2 vector = GetPath(_activePath)[0]; + l = (r = vector.x); + b = (t = vector.y); + PathBounds(_verts, 1, ref l, ref b, ref r, ref t); + } + else + { + Vector2 vector2 = _verts[0]; + l = (r = vector2.x); + b = (t = vector2.y); + PathBounds(_verts, 1, ref l, ref b, ref r, ref t); + int num = pathCount; + for (int i = 1; i < num; i++) + { + PathBounds(GetPath(i), 0, ref l, ref b, ref r, ref t); + } + } + _bounds = Rect.MinMaxRect(l, b, r, t); + } + + public void _CacheWorldBounds() + { + if (!_t) + { + _t = base.transform; + } + _worldBounds = SFRenderer._TransformRect(_t.localToWorldMatrix, _bounds); + } + + public Vector2[] GetPath(int index) + { + if (index != 0) + { + return _paths[index - 1]; + } + return _verts; + } + + public void SetPath(int index, Vector2[] path) + { + SetPathRaw(index, path); + _UpdateBounds(); + } + + private void SetPathRaw(int index, Vector2[] path) + { + if (index == 0) + { + _verts = path; + } + else + { + _paths[index - 1] = path; + } + } + + private void OnEnable() + { + _polygons.Add(this); + } + + private void OnDisable() + { + _polygons.Remove(this); + } + + private void Start() + { + _UpdateBounds(); + } + + public void CopyFromCollider(Collider2D collider) + { + PolygonCollider2D polygonCollider2D = collider as PolygonCollider2D; + BoxCollider2D boxCollider2D = collider as BoxCollider2D; + if ((bool)polygonCollider2D) + { + looped = true; + int num2 = (pathCount = polygonCollider2D.pathCount); + int num3 = num2; + for (int i = 0; i < num3; i++) + { + Vector2[] path = polygonCollider2D.GetPath(i); + for (int j = 0; j < path.Length; j++) + { + path[j] += polygonCollider2D.offset; + } + Array.Reverse((Array)path); + SetPathRaw(i, path); + } + _UpdateBounds(); + } + else if ((bool)boxCollider2D) + { + SetBoxVerts(boxCollider2D.offset - 0.5f * boxCollider2D.size, boxCollider2D.offset + 0.5f * boxCollider2D.size); + } + else + { + Debug.LogWarning("CopyFromCollider() only works with polygon and box colliders."); + } + } + + public void _CopyFromCollider() + { + Collider2D component = GetComponent<Collider2D>(); + if ((bool)component) + { + CopyFromCollider(component); + return; + } + Debug.LogWarning("GameObject has no polygon or box collider. Adding default SFPolygon shape instead."); + SetBoxVerts(-Vector2.one, Vector2.one); + } + + private void SetBoxVerts(Vector2 min, Vector2 max) + { + looped = true; + pathCount = 1; + verts = new Vector2[4] + { + new Vector2(max.x, max.y), + new Vector2(max.x, min.y), + new Vector2(min.x, min.y), + new Vector2(min.x, max.y) + }; + } + + public void _FlipInsideOut(int index) + { + if (index == -1) + { + int num = pathCount; + for (int i = 0; i < num; i++) + { + Array.Reverse((Array)GetPath(i)); + } + } + else + { + Array.Reverse((Array)GetPath(index)); + } + } +} diff --git a/GameCode/SFRenderer.cs b/GameCode/SFRenderer.cs new file mode 100644 index 0000000..e19e13b --- /dev/null +++ b/GameCode/SFRenderer.cs @@ -0,0 +1,621 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using UnityEngine.Rendering; +using UnityEngine.Serialization; + +[ExecuteInEditMode] +public class SFRenderer : MonoBehaviour +{ + public bool _renderInSceneView = true; + + private RenderTexture _lightMap; + + private RenderTexture _ShadowMap; + + [Tooltip("Blend the lights in linear space rather than gamma space. Nonlinear blending prevents oversaturation, but can cause draw order artifacts.")] + public bool _linearLightBlending = true; + + public bool _shadows = true; + + [Tooltip("The global ambient light color- the ambient light is used to light your scene when no lights are affecting part of it. A darker grey, blue, or yellow is often a good place to start. Alpha unused. ")] + public Color _ambientLight = Color.black; + + [Tooltip("Exposure is a multiplier applied to all lights in this renderer. Use to adjust all your lights at once. Particularly useful if you're using HDR lighting, otherwise it can be used to cause oversaturation.")] + [FormerlySerializedAs("_globalDynamicRange")] + public float _exposure = 1f; + + [Tooltip("Scale of the render texture for the colored lights. Larger numbers will give you blockier lights, but will run faster. Since lighting tends to be pretty diffuse, high numbers like 8 usually look good here. Recommended values are between 8 - 32.")] + public float _lightMapScale = 8f; + + [Tooltip("Scale of the render texture for the colored lights. Larger numbers will give you blockier shadows, but will run faster. Blocky shadows tend to look worse than blocky lights, so this should usually be lower than the light map scale. Recommended values are between 2 - 8. Less if you have a lot of sharp shadows.")] + public float _shadowMapScale = 4f; + + [Tooltip("How far will light penetrate into each shadow casting object. Makes it look like objects that are casting shadows are illuminated by the lights.")] + public float _minLightPenetration = 0.2f; + + [Tooltip("Extra darkening to apply to shadows to hide precision artifacts in the seams.")] + public float _shadowCompensation = 1.01f; + + [Tooltip("The color of the fog color. The alpha controls the fog's strength.")] + public Color _fogColor = new Color(1f, 1f, 1f, 0f); + + [Tooltip("The scatter color is the color that the fog will glow when it is lit. Alpha is unused. Black disables illumination effects on the fog.")] + public Color _scatterColor = new Color(0f, 0f, 0f, 0f); + + [Tooltip("What percentage of unshadowed/shadowed light should apply to the fog. At 1.0, your shadows will be fully applied to the scattered light in your fog.")] + public float _softHardMix; + + private Rect _extents = Rect.MinMaxRect(-1f, -1f, 1f, 1f); + + private Material _shadowMaskMaterial; + + private Material _linearLightMaterial; + + private Material _softLightMaterial; + + private Material _HDRClampMaterial; + + private Material _fogMaterial; + + private Mesh _mesh; + + private bool UV_STARTS_AT_TOP; + + private static Matrix4x4 TEXTURE_FLIP_MATRIX = Matrix4x4.Scale(new Vector3(1f, -1f, 1f)); + + private RenderTextureFormat lightmapFormat = RenderTextureFormat.ARGB1555; + + private RenderTextureFormat lightmapFormatHDR = RenderTextureFormat.ARGB1555; + + private List<SFPolygon> _perLightCulledPolygons = new List<SFPolygon>(); + + private List<SFLight> _culledLights = new List<SFLight>(); + + private List<SFPolygon> _culledPolygons = new List<SFPolygon>(); + + public bool linearLightBlending + { + get + { + return _linearLightBlending; + } + set + { + _linearLightBlending = value; + } + } + + public bool shadows + { + get + { + return _shadows; + } + set + { + _shadows = value; + } + } + + public Color ambientLight + { + get + { + return _ambientLight; + } + set + { + _ambientLight = value; + } + } + + public float exposure + { + get + { + return _exposure; + } + set + { + _exposure = value; + } + } + + public float lightMapScale + { + get + { + return _lightMapScale; + } + set + { + _lightMapScale = value; + } + } + + public float shadowMapScale + { + get + { + return _shadowMapScale; + } + set + { + _shadowMapScale = value; + } + } + + public float minLightPenetration + { + get + { + return _minLightPenetration; + } + set + { + _minLightPenetration = value; + } + } + + public float shadowCompensation + { + get + { + return _shadowCompensation; + } + set + { + _shadowCompensation = Mathf.Clamp(value, 1f, 2f); + } + } + + public Color fogColor + { + get + { + return _fogColor; + } + set + { + _fogColor = value; + } + } + + public Color scatterColor + { + get + { + return _scatterColor; + } + set + { + _scatterColor = value; + } + } + + public float softHardMix + { + get + { + return _softHardMix; + } + set + { + _softHardMix = value; + } + } + + [Obsolete("Please use SFRenderer.exposure instead.")] + public float globalIlluminationScale + { + get + { + return _exposure; + } + set + { + _exposure = value; + } + } + + [Obsolete("Please use SFRenderer.exposure instead.")] + public float globalDynamicRange + { + get + { + return _exposure; + } + set + { + _exposure = value; + } + } + + public Rect extents + { + get + { + return _extents; + } + set + { + _extents = value; + } + } + + private Material shadowMaskMaterial + { + get + { + if (_shadowMaskMaterial == null) + { + _shadowMaskMaterial = new Material(Shader.Find("Hidden/SFSoftShadows/ShadowMask")); + _shadowMaskMaterial.hideFlags = HideFlags.HideAndDontSave; + } + return _shadowMaskMaterial; + } + } + + private Material lightMaterial + { + get + { + if (_linearLightMaterial == null) + { + _linearLightMaterial = new Material(Shader.Find("Hidden/SFSoftShadows/LightBlendLinear")); + _linearLightMaterial.hideFlags = HideFlags.HideAndDontSave; + _softLightMaterial = new Material(Shader.Find("Hidden/SFSoftShadows/LightBlendSoft")); + _softLightMaterial.hideFlags = HideFlags.HideAndDontSave; + } + if (!_linearLightBlending) + { + return _softLightMaterial; + } + return _linearLightMaterial; + } + } + + private Material HDRClampMaterial + { + get + { + if (_HDRClampMaterial == null) + { + _HDRClampMaterial = new Material(Shader.Find("Hidden/SFSoftShadows/HDRClamp")); + _HDRClampMaterial.hideFlags = HideFlags.HideAndDontSave; + } + return _HDRClampMaterial; + } + } + + private Material fogMaterial + { + get + { + if (_fogMaterial == null) + { + _fogMaterial = new Material(Shader.Find("Hidden/SFSoftShadows/FogLayer")); + _fogMaterial.hideFlags = HideFlags.HideAndDontSave; + } + return _fogMaterial; + } + } + + private Mesh sharedMesh + { + get + { + if (_mesh == null) + { + _mesh = new Mesh(); + _mesh.MarkDynamic(); + _mesh.hideFlags = HideFlags.HideAndDontSave; + } + return _mesh; + } + } + + private void ScenePreRender(Camera camera) + { + if (_renderInSceneView && camera.cameraType == CameraType.SceneView) + { + OnPreRender(); + } + } + + private void ScenePostRender(Camera camera) + { + if (_renderInSceneView && camera.cameraType == CameraType.SceneView) + { + OnPostRender(); + } + } + + private void OnEnable() + { + if (Application.isEditor) + { + Camera.onPreRender = (Camera.CameraCallback)Delegate.Combine(Camera.onPreRender, new Camera.CameraCallback(ScenePreRender)); + Camera.onPostRender = (Camera.CameraCallback)Delegate.Combine(Camera.onPostRender, new Camera.CameraCallback(ScenePostRender)); + } + } + + private void OnDisable() + { + if (Application.isEditor) + { + Camera.onPreRender = (Camera.CameraCallback)Delegate.Remove(Camera.onPreRender, new Camera.CameraCallback(ScenePreRender)); + Camera.onPostRender = (Camera.CameraCallback)Delegate.Remove(Camera.onPostRender, new Camera.CameraCallback(ScenePostRender)); + } + } + + private void Start() + { + GraphicsDeviceType graphicsDeviceType = SystemInfo.graphicsDeviceType; + UV_STARTS_AT_TOP = graphicsDeviceType == GraphicsDeviceType.Direct3D9 || graphicsDeviceType == GraphicsDeviceType.Direct3D11 || graphicsDeviceType == GraphicsDeviceType.Direct3D12 || graphicsDeviceType == GraphicsDeviceType.Metal; + if (SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGB32)) + { + lightmapFormat = RenderTextureFormat.ARGB32; + } + else if (SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.BGRA32)) + { + lightmapFormat = RenderTextureFormat.BGRA32; + } + if (SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBHalf)) + { + lightmapFormatHDR = RenderTextureFormat.ARGBHalf; + } + else if (SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBFloat)) + { + lightmapFormatHDR = RenderTextureFormat.ARGBFloat; + } + Debug.Log(string.Concat("SFSS init: ", graphicsDeviceType, ", ", UV_STARTS_AT_TOP ? "UV_STARTS_AT_TOP, " : "", lightmapFormat, ", ", lightmapFormatHDR)); + } + + private void OnDestroy() + { + if ((bool)_mesh) + { + UnityEngine.Object.DestroyImmediate(_mesh); + } + } + + public static Rect _TransformRect(Matrix4x4 m, Rect r) + { + Vector4 vector = m.MultiplyPoint3x4(new Vector4(r.x + 0.5f * r.width, r.y + 0.5f * r.height, 0f, 1f)); + float num = 0.5f * Mathf.Max(Mathf.Abs(r.width * m[0] + r.height * m[4]), Mathf.Abs(r.width * m[0] - r.height * m[4])); + float num2 = 0.5f * Mathf.Max(Mathf.Abs(r.width * m[1] + r.height * m[5]), Mathf.Abs(r.width * m[1] - r.height * m[5])); + return new Rect(vector.x - num, vector.y - num2, 2f * num, 2f * num2); + } + + private static Vector2 ClampedProjection(Matrix4x4 m, float x, float y) + { + float num = Math.Max(0f, x * m[3] + y * m[7] + m[15]); + return new Vector2((x * m[0] + y * m[4] + m[12]) / num, (x * m[1] + y * m[5] + m[13]) / num); + } + + private static Rect ScissorRect(Matrix4x4 mvp, float w, float h) + { + Vector2 vector = ClampedProjection(mvp, -1f, -1f); + Vector2 vector2 = ClampedProjection(mvp, 1f, -1f); + Vector2 vector3 = ClampedProjection(mvp, 1f, 1f); + Vector2 vector4 = ClampedProjection(mvp, -1f, 1f); + float num = Mathf.Min(Mathf.Min(vector.x, vector2.x), Mathf.Min(vector3.x, vector4.x)); + float num2 = Mathf.Min(Mathf.Min(vector.y, vector2.y), Mathf.Min(vector3.y, vector4.y)); + float num3 = Mathf.Max(Mathf.Max(vector.x, vector2.x), Mathf.Max(vector3.x, vector4.x)); + float num4 = Mathf.Max(Mathf.Max(vector.y, vector2.y), Mathf.Max(vector3.y, vector4.y)); + return Rect.MinMaxRect(Mathf.Max(0f, Mathf.Floor((0.5f * num + 0.5f) * w)), Mathf.Max(0f, Mathf.Floor((0.5f * num2 + 0.5f) * h)), Mathf.Min(w, Mathf.Ceil((0.5f * num3 + 0.5f) * w)), Mathf.Min(h, Mathf.Ceil((0.5f * num4 + 0.5f) * h))); + } + + private static Matrix4x4 ClipMatrix(Rect r, float dw, float dh) + { + float num = r.x * dw - 1f; + float num2 = r.y * dh - 1f; + return Matrix4x4.Ortho(num, num + r.width * dw, num2, num2 + r.height * dh, -1f, 1f); + } + + private static void CullPolys(List<SFPolygon> polys, Rect bounds, List<SFPolygon> culledPolygons) + { + for (int i = 0; i < polys.Count; i++) + { + SFPolygon sFPolygon = polys[i]; + if (bounds.Overlaps(sFPolygon._WorldBounds)) + { + culledPolygons.Add(sFPolygon); + } + } + } + + private Matrix4x4 TextureProjectionMatrix(Matrix4x4 m) + { + m.SetRow(2, new Vector4(0f, 0f, 1f, 0f)); + Matrix4x4 matrix4x = m.inverse; + if (UV_STARTS_AT_TOP) + { + matrix4x = TEXTURE_FLIP_MATRIX * matrix4x * TEXTURE_FLIP_MATRIX; + } + return matrix4x; + } + + private void RenderLightMap(Matrix4x4 viewMatrix, Matrix4x4 projection, Matrix4x4 vpMatrix, RenderTexture target, List<SFLight> lights, List<SFPolygon> polys, Color ambient, bool hdr) + { + int width = target.width; + int height = target.height; + Rect screenRect = new Rect(-1f, -1f, 2f, 2f); + Rect sourceRect = new Rect(0f, 0f, 1f, 1f); + Graphics.SetRenderTarget(target); + GL.Clear(clearDepth: false, clearColor: true, ambient); + for (int i = 0; i < lights.Count; i++) + { + SFLight sFLight = lights[i]; + if (!sFLight.enabled) + { + continue; + } + Matrix4x4 matrix4x = sFLight._ModelMatrix(forceProjection: false) * sFLight._CookieMatrix(); + Rect rect = ScissorRect(vpMatrix * matrix4x, width, height); + Matrix4x4 matrix4x2 = ClipMatrix(rect, 2f / (float)width, 2f / (float)height) * projection; + GL.Viewport(rect); + GL.LoadProjectionMatrix(matrix4x2); + if (polys != null && (int)sFLight._shadowLayers != 0) + { + CullPolys(polys, sFLight._CalcCullBounds(vpMatrix), _perLightCulledPolygons); + Mesh mesh = sFLight._BuildShadowMesh(sharedMesh, _perLightCulledPolygons, _minLightPenetration); + _perLightCulledPolygons.Clear(); + if (mesh != null) + { + shadowMaskMaterial.SetPass(0); + Graphics.DrawMeshNow(mesh, sFLight._ModelMatrix(forceProjection: true)); + mesh.Clear(); + } + if (hdr) + { + Graphics.DrawTexture(screenRect, Texture2D.blackTexture, HDRClampMaterial); + } + } + Texture2D texture2D = sFLight._cookieTexture; + if (!texture2D) + { + texture2D = Texture2D.whiteTexture; + } + Material material = lightMaterial; + if (_linearLightBlending) + { + material.SetFloat("_intensity", sFLight._intensity); + } + GL.LoadProjectionMatrix(TextureProjectionMatrix(matrix4x2 * viewMatrix * matrix4x)); + Graphics.DrawTexture(screenRect, texture2D, sourceRect, 0, 0, 0, 0, sFLight._color, material); + } + } + + private RenderTexture GetTexture(Camera cam, Matrix4x4 extensionInv, float downscale) + { + Vector4 vector = extensionInv * cam.pixelRect.size / downscale; + RenderTextureFormat format = (cam.allowHDR ? lightmapFormatHDR : lightmapFormat); + return RenderTexture.GetTemporary((int)vector.x, (int)vector.y, 0, format); + } + + public static bool _FastCull(Matrix4x4 mvp, Rect bounds) + { + Vector2 center = bounds.center; + Vector2 vector = 0.5f * bounds.size; + Vector4 vector2 = mvp * new Vector4(center.x, center.y, 0f, 1f); + float num = vector.x * Mathf.Abs(mvp[0]) + vector.y * Mathf.Abs(mvp[4]); + float num2 = vector.x * Mathf.Abs(mvp[1]) + vector.y * Mathf.Abs(mvp[5]); + float num3 = vector.x * Mathf.Abs(mvp[2]) + vector.y * Mathf.Abs(mvp[6]); + float num4 = Mathf.Max(0f, vector2.w + vector.x * Mathf.Abs(mvp[3]) + vector.y * Mathf.Abs(mvp[7])); + if (Mathf.Abs(vector2.x) - num < num4 && Mathf.Abs(vector2.y) - num2 < num4) + { + return Mathf.Abs(vector2.z) - num3 < num4; + } + return false; + } + + private static Rect CullLights(Matrix4x4 vpMatrix, List<SFLight> lights, List<SFLight> culledLights) + { + float num = float.PositiveInfinity; + float num2 = float.PositiveInfinity; + float num3 = float.NegativeInfinity; + float num4 = float.NegativeInfinity; + for (int i = 0; i < lights.Count; i++) + { + SFLight sFLight = lights[i]; + if (_FastCull(vpMatrix * sFLight._ModelMatrix(forceProjection: false), sFLight._bounds)) + { + culledLights.Add(sFLight); + if ((int)sFLight._shadowLayers != 0) + { + Rect rect = sFLight._CalcCullBounds(vpMatrix); + num = Mathf.Min(num, rect.xMin); + num2 = Mathf.Min(num2, rect.yMin); + num3 = Mathf.Max(num3, rect.xMax); + num4 = Mathf.Max(num4, rect.yMax); + } + } + } + return Rect.MinMaxRect(num, num2, num3, num4); + } + + private void OnPreRender() + { + Color color = _ambientLight; + color.a = 1f; + Matrix4x4 matrix4x = Matrix4x4.Ortho(_extents.xMin, _extents.xMax, _extents.yMin, _extents.yMax, 1f, -1f); + Matrix4x4 inverse = matrix4x.inverse; + RenderBuffer activeColorBuffer = Graphics.activeColorBuffer; + RenderBuffer activeDepthBuffer = Graphics.activeDepthBuffer; + Camera current = Camera.current; + bool allowHDR = current.allowHDR; + Matrix4x4 worldToCameraMatrix = current.worldToCameraMatrix; + Matrix4x4 matrix4x2 = matrix4x * current.projectionMatrix; + Matrix4x4 vpMatrix = matrix4x2 * worldToCameraMatrix; + List<SFLight> lights = SFLight._lights; + List<SFPolygon> list = SFPolygon._polygons; + if (!Application.isPlaying) + { + lights = new List<SFLight>(from o in UnityEngine.Object.FindObjectsOfType<SFLight>() + where o.isActiveAndEnabled + select o); + list = new List<SFPolygon>(from o in UnityEngine.Object.FindObjectsOfType<SFPolygon>() + where o.isActiveAndEnabled + select o); + foreach (SFPolygon item in list) + { + item._UpdateBounds(); + } + } + Rect bounds = CullLights(vpMatrix, lights, _culledLights); + GL.PushMatrix(); + _lightMap = GetTexture(current, inverse, _lightMapScale); + RenderLightMap(worldToCameraMatrix, matrix4x2, vpMatrix, _lightMap, _culledLights, null, color, allowHDR); + if (_shadows) + { + for (int i = 0; i < list.Count; i++) + { + list[i]._CacheWorldBounds(); + } + CullPolys(list, bounds, _culledPolygons); + Shader.SetGlobalFloat("_SFShadowCompensation", _shadowCompensation); + _ShadowMap = GetTexture(current, inverse, _shadowMapScale); + RenderLightMap(worldToCameraMatrix, matrix4x2, vpMatrix, _ShadowMap, _culledLights, _culledPolygons, color, allowHDR); + _culledPolygons.Clear(); + } + GL.PopMatrix(); + _culledLights.Clear(); + Graphics.SetRenderTarget(null); + GL.Viewport(current.pixelRect); + Shader.SetGlobalMatrix("_SFProjection", matrix4x * Camera.current.projectionMatrix); + Shader.SetGlobalColor("_SFAmbientLight", color); + Shader.SetGlobalFloat("_SFExposure", _exposure); + Shader.SetGlobalTexture("_SFLightMap", _lightMap); + Shader.SetGlobalTexture("_SFLightMapWithShadows", _shadows ? _ShadowMap : _lightMap); + Graphics.SetRenderTarget(activeColorBuffer, activeDepthBuffer); + } + + private void OnPostRender() + { + if (_fogColor.a + _scatterColor.r + _scatterColor.g + _scatterColor.b > 0f) + { + GL.PushMatrix(); + GL.LoadProjectionMatrix(Matrix4x4.identity); + Color value = _scatterColor; + value.a = _softHardMix; + Material material = fogMaterial; + material.SetColor("_FogColor", _fogColor); + material.SetColor("_Scatter", value); + material.SetPass(0); + Graphics.DrawTexture(new Rect(-1f, -1f, 2f, 2f), Texture2D.blackTexture, material); + GL.PopMatrix(); + } + Shader.SetGlobalColor("_SFAmbientLight", Color.white); + Shader.SetGlobalFloat("_SFExposure", 1f); + Shader.SetGlobalTexture("_SFLightMap", Texture2D.whiteTexture); + Shader.SetGlobalTexture("_SFLightMapWithShadows", Texture2D.whiteTexture); + RenderTexture.ReleaseTemporary(_lightMap); + _lightMap = null; + RenderTexture.ReleaseTemporary(_ShadowMap); + _ShadowMap = null; + } +} diff --git a/GameCode/SFSample.cs b/GameCode/SFSample.cs new file mode 100644 index 0000000..8a0d194 --- /dev/null +++ b/GameCode/SFSample.cs @@ -0,0 +1,73 @@ +using UnityEngine; + +[RequireComponent(typeof(Renderer))] +public class SFSample : MonoBehaviour +{ + private Material _material; + + public Vector2 _samplePosition = Vector2.zero; + + public bool _lineSample; + + public Vector2 samplePosition + { + get + { + return _samplePosition; + } + set + { + _samplePosition = value; + if ((bool)_material) + { + _material.SetVector("_SamplePosition", _samplePosition); + } + } + } + + public bool lineSample + { + get + { + return _lineSample; + } + set + { + _lineSample = value; + if ((bool)_material) + { + if (value) + { + _material.EnableKeyword("LINESAMPLE_ON"); + _material.DisableKeyword("FIXEDSAMPLEPOINT_ON"); + } + else + { + _material.DisableKeyword("LINESAMPLE_ON"); + _material.EnableKeyword("FIXEDSAMPLEPOINT_ON"); + } + } + } + } + + private void Start() + { + Renderer component = GetComponent<Renderer>(); + Material sharedMaterial = component.sharedMaterial; + if (sharedMaterial == null || sharedMaterial.shader.name != "Sprites/SFSoftShadow") + { + Debug.LogError("SFSample requires the attached renderer to be using the Sprites/SFSoftShadow shader."); + return; + } + _material = new Material(sharedMaterial); + component.material = _material; + _material.SetFloat("_SoftHardMix", sharedMaterial.GetFloat("_SoftHardMix")); + samplePosition = _samplePosition; + lineSample = _lineSample; + } + + private void OnDrawGizmosSelected() + { + Gizmos.DrawIcon(base.transform.TransformPoint(_samplePosition), "SFDotGizmo.psd"); + } +} diff --git a/GameCode/Saw.cs b/GameCode/Saw.cs new file mode 100644 index 0000000..19ebe25 --- /dev/null +++ b/GameCode/Saw.cs @@ -0,0 +1,83 @@ +using UnityEngine; + +public class Saw : MonoBehaviour +{ + public Player owner; + + public float range = 3f; + + public float damage = 10f; + + public float force; + + public float shake = 1f; + + public ParticleSystem[] parts; + + public Transform sparkTransform; + + private Vector3 forceDir; + + private void Start() + { + owner = base.transform.root.GetComponent<SpawnedAttack>().spawner; + } + + private void Update() + { + Player player = null; + for (int i = 0; i < PlayerManager.instance.players.Count; i++) + { + Player player2 = PlayerManager.instance.players[i]; + if (player2 != owner && Vector3.Distance(player2.transform.position, base.transform.transform.position) < range * base.transform.localScale.x) + { + player = player2; + } + } + if ((bool)player && PlayerManager.instance.CanSeePlayer(base.transform.position, player).canSee) + { + Vector3 normalized = (player.transform.position - base.transform.position).normalized; + if (damage != 0f) + { + player.data.healthHandler.TakeDamage(TimeHandler.deltaTime * damage * normalized, base.transform.position, null, owner); + } + if (force != 0f) + { + float num = Mathf.Clamp(1f - Vector2.Distance(base.transform.position, player.transform.position) / range, 0f, 1f); + ForceMultiplier component = player.GetComponent<ForceMultiplier>(); + if ((bool)component) + { + num *= component.multiplier; + } + forceDir = normalized; + forceDir.y *= 0.5f; + player.data.playerVel.AddForce(forceDir * base.transform.localScale.x * num * TimeHandler.deltaTime * force, ForceMode2D.Force); + player.data.healthHandler.TakeForce(forceDir * num * 0.0005f * TimeHandler.deltaTime * force); + } + for (int j = 0; j < parts.Length; j++) + { + if (!parts[j].isPlaying) + { + parts[j].Play(); + } + } + if ((bool)sparkTransform) + { + sparkTransform.transform.position = player.transform.position; + if (normalized != Vector3.zero) + { + sparkTransform.rotation = Quaternion.LookRotation(normalized); + } + } + GamefeelManager.GameFeel((normalized + Random.onUnitSphere).normalized * shake * TimeHandler.deltaTime * 20f); + return; + } + for (int k = 0; k < parts.Length; k++) + { + if (parts[k].isPlaying) + { + parts[k].Stop(); + } + } + } +} diff --git a/GameCode/ScaleEvent.cs b/GameCode/ScaleEvent.cs new file mode 100644 index 0000000..923132d --- /dev/null +++ b/GameCode/ScaleEvent.cs @@ -0,0 +1,21 @@ +using UnityEngine; + +public class ScaleEvent : MonoBehaviour +{ + public ScaleEventInstace[] events; + + private void Start() + { + ScaleEventInstace scaleEventInstace = null; + float num = 0f; + for (int i = 0; i < events.Length; i++) + { + if (base.transform.localScale.x > events[i].threshold && events[i].threshold > num) + { + num = events[i].threshold; + scaleEventInstace = events[i]; + } + } + scaleEventInstace?.scaleEvent.Invoke(); + } +} diff --git a/GameCode/ScaleEventInstace.cs b/GameCode/ScaleEventInstace.cs new file mode 100644 index 0000000..391d8f7 --- /dev/null +++ b/GameCode/ScaleEventInstace.cs @@ -0,0 +1,10 @@ +using System; +using UnityEngine.Events; + +[Serializable] +public class ScaleEventInstace +{ + public UnityEvent scaleEvent; + + public float threshold = 1f; +} diff --git a/GameCode/ScaleShake.cs b/GameCode/ScaleShake.cs new file mode 100644 index 0000000..b2a25b2 --- /dev/null +++ b/GameCode/ScaleShake.cs @@ -0,0 +1,76 @@ +using System.Collections; +using Photon.Pun; +using UnityEngine; + +public class ScaleShake : MonoBehaviour +{ + public bool useTimeScale = true; + + public float targetScale = 1f; + + public float multiplier = 1f; + + private float velocity; + + public float drag = 1f; + + public float spring = 1f; + + public float clampVelocity; + + internal float high; + + internal float low; + + private void Update() + { + float num = Mathf.Clamp(useTimeScale ? TimeHandler.deltaTime : Time.unscaledDeltaTime, 0f, 0.02f); + if (clampVelocity != 0f) + { + velocity = Mathf.Clamp(velocity, 0f - clampVelocity, clampVelocity); + } + velocity += (targetScale - base.transform.localScale.x) * num * 50f * spring; + velocity -= drag * velocity * 20f * num; + base.transform.localScale += Vector3.one * (velocity * 10f * num); + } + + public void AddForce(float force) + { + velocity += force * multiplier * 5f; + } + + public void AddForce() + { + velocity += 1f * multiplier * 5f; + } + + public void SetTarget(float target) + { + targetScale = target; + } + + public void SetHigh() + { + targetScale = high; + } + + public void SetLow() + { + targetScale = low; + } + + public void ScaleOutRootPhoton() + { + StartCoroutine(GoAwayOutRootPhoton()); + } + + private IEnumerator GoAwayOutRootPhoton() + { + while (base.transform.localScale.x > 0f) + { + targetScale = 0f; + yield return null; + } + PhotonNetwork.Destroy(base.transform.root.gameObject); + } +} diff --git a/GameCode/ScaleTrailFromDamage.cs b/GameCode/ScaleTrailFromDamage.cs new file mode 100644 index 0000000..ffe41a8 --- /dev/null +++ b/GameCode/ScaleTrailFromDamage.cs @@ -0,0 +1,61 @@ +using UnityEngine; + +public class ScaleTrailFromDamage : MonoBehaviour +{ + private float startWidth; + + private float startTime; + + private void Start() + { + float num = 55f; + ProjectileHit componentInParent = GetComponentInParent<ProjectileHit>(); + GetComponentInParent<RayCastTrail>(); + if ((bool)componentInParent) + { + num = componentInParent.damage; + } + TrailRenderer componentInChildren = GetComponentInChildren<TrailRenderer>(); + startWidth = componentInChildren.widthMultiplier; + startTime = componentInChildren.time; + if ((bool)componentInChildren) + { + componentInChildren.widthMultiplier *= (1f + num / 55f) / 2f; + componentInChildren.time *= Mathf.Clamp((1f + num / 55f) / 2f, 0f, 25f); + if (num > 100f) + { + componentInChildren.numCapVertices = 5; + } + if (num > 500f) + { + componentInChildren.numCapVertices = 10; + } + } + } + + public void Rescale() + { + float num = 55f; + ProjectileHit componentInParent = GetComponentInParent<ProjectileHit>(); + RayCastTrail componentInParent2 = GetComponentInParent<RayCastTrail>(); + if ((bool)componentInParent) + { + num = componentInParent.damage; + } + TrailRenderer componentInChildren = GetComponentInChildren<TrailRenderer>(); + if ((bool)componentInChildren) + { + _ = componentInParent2.extraSize; + componentInChildren.widthMultiplier = startWidth * ((1f + num / 55f) / 2f); + componentInChildren.time = startTime * Mathf.Clamp((1f + num / 55f) / 2f, 0f, 25f); + if (num > 100f) + { + componentInChildren.numCapVertices = 5; + } + if (num > 100f) + { + componentInChildren.numCapVertices = 10; + } + } + } +} diff --git a/GameCode/ScaleWithHp.cs b/GameCode/ScaleWithHp.cs new file mode 100644 index 0000000..5649021 --- /dev/null +++ b/GameCode/ScaleWithHp.cs @@ -0,0 +1,18 @@ +using UnityEngine; + +public class ScaleWithHp : MonoBehaviour +{ + private DamagableEvent dmg; + + public AnimationCurve curve; + + private void Start() + { + dmg = GetComponentInParent<DamagableEvent>(); + } + + private void Update() + { + base.transform.localScale = Vector3.one * curve.Evaluate(dmg.currentHP); + } +} diff --git a/GameCode/ScreenEdgeBounce.cs b/GameCode/ScreenEdgeBounce.cs new file mode 100644 index 0000000..21c8b69 --- /dev/null +++ b/GameCode/ScreenEdgeBounce.cs @@ -0,0 +1,132 @@ +using Photon.Pun; +using UnityEngine; + +public class ScreenEdgeBounce : MonoBehaviour +{ + private float sinceBounce = 1f; + + private Camera mainCam; + + private RayHitReflect reflect; + + private Vector2 lastNormal; + + private ProjectileHit projHit; + + private bool done; + + private RayHitBulletSound bulletSound; + + private PhotonView view; + + private void Start() + { + GetComponentInParent<ChildRPC>().childRPCsVector2Vector2IntInt.Add("ScreenBounce", DoHit); + view = GetComponentInParent<PhotonView>(); + bulletSound = GetComponentInParent<RayHitBulletSound>(); + projHit = GetComponentInParent<ProjectileHit>(); + ScreenEdgeBounce[] componentsInChildren = base.transform.root.GetComponentsInChildren<ScreenEdgeBounce>(); + for (int i = 0; i < componentsInChildren.Length; i++) + { + if (i > 0) + { + Object.Destroy(componentsInChildren[i]); + } + } + mainCam = MainCam.instance.transform.GetComponent<Camera>(); + reflect = GetComponentInParent<RayHitReflect>(); + } + + private void Update() + { + if (!view.IsMine || done) + { + return; + } + Vector3 vector = mainCam.WorldToScreenPoint(base.transform.position); + vector.x /= Screen.width; + vector.y /= Screen.height; + vector = new Vector3(Mathf.Clamp(vector.x, 0f, 1f), Mathf.Clamp(vector.y, 0f, 1f), vector.z); + if (vector.x != 0f && vector.x != 1f && vector.y != 1f && vector.y != 0f) + { + return; + } + Vector2 vector2 = Vector2.zero; + if (vector.x == 0f) + { + vector2 = Vector2.right; + } + else if (vector.x == 1f) + { + vector2 = -Vector2.right; + } + if (vector.y == 0f) + { + vector2 = Vector2.up; + } + else if (vector.y == 1f) + { + vector2 = -Vector2.up; + } + if (lastNormal == vector2 && Vector2.Angle(vector2, base.transform.forward) < 90f) + { + lastNormal = vector2; + return; + } + lastNormal = vector2; + vector.x *= Screen.width; + vector.y *= Screen.height; + RaycastHit2D raycastHit2D = default(RaycastHit2D); + raycastHit2D.normal = vector2; + raycastHit2D.point = mainCam.ScreenToWorldPoint(vector); + int num = -1; + if ((bool)raycastHit2D.transform) + { + PhotonView component = raycastHit2D.transform.root.GetComponent<PhotonView>(); + if ((bool)component) + { + num = component.ViewID; + } + } + int intData = -1; + if (num == -1) + { + Collider2D[] componentsInChildren = MapManager.instance.currentMap.Map.GetComponentsInChildren<Collider2D>(); + for (int i = 0; i < componentsInChildren.Length; i++) + { + if (componentsInChildren[i] == raycastHit2D.collider) + { + intData = i; + } + } + } + GetComponentInParent<ChildRPC>().CallFunction("ScreenBounce", raycastHit2D.point, raycastHit2D.normal, num, intData); + if (reflect.reflects <= 0) + { + done = true; + } + sinceBounce = 0f; + } + + private void DoHit(Vector2 hitPos, Vector2 hitNormal, int viewID = -1, int colliderID = -1) + { + HitInfo hitInfo = new HitInfo(); + hitInfo.point = hitPos; + hitInfo.normal = hitNormal; + hitInfo.collider = null; + if (viewID != -1) + { + PhotonView photonView = PhotonNetwork.GetPhotonView(viewID); + hitInfo.collider = photonView.GetComponentInChildren<Collider2D>(); + hitInfo.transform = photonView.transform; + } + else if (colliderID != -1) + { + hitInfo.collider = MapManager.instance.currentMap.Map.GetComponentsInChildren<Collider2D>()[colliderID]; + hitInfo.transform = hitInfo.collider.transform; + } + DynamicParticles.instance.PlayBulletHit(projHit.damage, base.transform, hitInfo, projHit.projectileColor); + bulletSound.DoHitEffect(hitInfo); + reflect.DoHitEffect(hitInfo); + } +} diff --git a/GameCode/Screenshaker.cs b/GameCode/Screenshaker.cs new file mode 100644 index 0000000..d845eae --- /dev/null +++ b/GameCode/Screenshaker.cs @@ -0,0 +1,53 @@ +using UnityEngine; + +public class Screenshaker : GameFeeler +{ + public bool ignoreTimeScale; + + public float spring = 100f; + + public float damper = 100f; + + public float shakeforce = 10f; + + public float threshold; + + private Vector2 velocity; + + private float clamp = 100f; + + private void Update() + { + float num = Mathf.Clamp(ignoreTimeScale ? Time.unscaledDeltaTime : TimeHandler.deltaTime, 0f, 0.015f); + velocity -= velocity.normalized * Mathf.Pow(velocity.magnitude, 0.8f) * damper * num; + velocity -= (Vector2)base.transform.localPosition * num * spring; + base.transform.position += (Vector3)velocity * num; + } + + private void ShakeInternal(Vector2 direction) + { + if (!(direction.magnitude < threshold)) + { + direction = Vector2.ClampMagnitude(direction, clamp); + velocity += direction * shakeforce; + } + } + + public override void OnGameFeel(Vector2 feelDirection) + { + if (!ignoreTimeScale) + { + feelDirection = Vector2.ClampMagnitude(feelDirection, clamp); + ShakeInternal(feelDirection); + } + } + + public override void OnUIGameFeel(Vector2 feelDirection) + { + if (ignoreTimeScale) + { + feelDirection = Vector2.ClampMagnitude(feelDirection, clamp); + ShakeInternal(feelDirection); + } + } +} diff --git a/GameCode/ServerMessage.cs b/GameCode/ServerMessage.cs new file mode 100644 index 0000000..71a6921 --- /dev/null +++ b/GameCode/ServerMessage.cs @@ -0,0 +1 @@ +public delegate void ServerMessage(string message); diff --git a/GameCode/SetActive.cs b/GameCode/SetActive.cs new file mode 100644 index 0000000..5856366 --- /dev/null +++ b/GameCode/SetActive.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +public class SetActive : MonoBehaviour +{ + public void DoSetActive(bool active) + { + base.gameObject.SetActive(active); + } +} diff --git a/GameCode/SetColorByBlockCD.cs b/GameCode/SetColorByBlockCD.cs new file mode 100644 index 0000000..05e0083 --- /dev/null +++ b/GameCode/SetColorByBlockCD.cs @@ -0,0 +1,36 @@ +using UnityEngine; + +public class SetColorByBlockCD : MonoBehaviour +{ + private Block block; + + private SpriteRenderer spriteRend; + + public Color onCDColor; + + public Color offCDColor; + + private bool isOnCD; + + private void Start() + { + block = GetComponentInParent<Block>(); + spriteRend = GetComponent<SpriteRenderer>(); + } + + private void Update() + { + if (isOnCD != block.IsOnCD()) + { + isOnCD = block.IsOnCD(); + if (isOnCD) + { + spriteRend.color = onCDColor; + } + else + { + spriteRend.color = offCDColor; + } + } + } +} diff --git a/GameCode/SetEmissionOverTimeByVelocity.cs b/GameCode/SetEmissionOverTimeByVelocity.cs new file mode 100644 index 0000000..f8aa877 --- /dev/null +++ b/GameCode/SetEmissionOverTimeByVelocity.cs @@ -0,0 +1,22 @@ +using UnityEngine; + +public class SetEmissionOverTimeByVelocity : MonoBehaviour +{ + private ParticleSystem part; + + public AnimationCurve curve; + + private PlayerVelocity rig; + + private void Start() + { + rig = GetComponentInParent<PlayerVelocity>(); + part = GetComponent<ParticleSystem>(); + } + + private void Update() + { + ParticleSystem.EmissionModule emission = part.emission; + emission.rateOverDistance = curve.Evaluate(rig.velocity.magnitude); + } +} diff --git a/GameCode/SetLocalScale.cs b/GameCode/SetLocalScale.cs new file mode 100644 index 0000000..4f97804 --- /dev/null +++ b/GameCode/SetLocalScale.cs @@ -0,0 +1,11 @@ +using UnityEngine; + +public class SetLocalScale : MonoBehaviour +{ + public Vector3 localScale = Vector3.one; + + public void Set() + { + base.transform.localScale = localScale; + } +} diff --git a/GameCode/SetOfflineMode.cs b/GameCode/SetOfflineMode.cs new file mode 100644 index 0000000..bc6a98e --- /dev/null +++ b/GameCode/SetOfflineMode.cs @@ -0,0 +1,30 @@ +using Photon.Pun; +using UnityEngine; + +public class SetOfflineMode : MonoBehaviour +{ + public bool doIt = true; + + private void Awake() + { + if (doIt) + { + SetOffline(); + } + } + + public void SetOffline() + { + PhotonNetwork.OfflineMode = true; + PhotonNetwork.JoinRandomRoom(); + } + + public void SetOnline() + { + if (PhotonNetwork.InRoom) + { + PhotonNetwork.LeaveRoom(); + } + PhotonNetwork.OfflineMode = false; + } +} diff --git a/GameCode/SetParticleTimeAfterSecondsToRemove.cs b/GameCode/SetParticleTimeAfterSecondsToRemove.cs new file mode 100644 index 0000000..8229d6a --- /dev/null +++ b/GameCode/SetParticleTimeAfterSecondsToRemove.cs @@ -0,0 +1,13 @@ +using UnityEngine; + +public class SetParticleTimeAfterSecondsToRemove : MonoBehaviour +{ + private void Start() + { + ParticleSystem component = GetComponent<ParticleSystem>(); + component.Stop(); + ParticleSystem.MainModule main = component.main; + main.duration = GetComponentInParent<RemoveAfterSeconds>().seconds - main.startLifetime.constant; + component.Play(); + } +} diff --git a/GameCode/SetPlayerSpriteLayer.cs b/GameCode/SetPlayerSpriteLayer.cs new file mode 100644 index 0000000..cd0ba36 --- /dev/null +++ b/GameCode/SetPlayerSpriteLayer.cs @@ -0,0 +1,44 @@ +using UnityEngine; + +public class SetPlayerSpriteLayer : MonoBehaviour +{ + private SpriteMask[] sprites; + + private bool simpleSkin; + + private void Start() + { + simpleSkin = GetComponent<PlayerSkinHandler>().simpleSkin; + Player componentInParent = GetComponentInParent<Player>(); + int num = SortingLayer.NameToID("Player" + (componentInParent.playerID + 1)); + setSpriteLayerOfChildren(GetComponentInParent<Holding>().holdable.gameObject, num); + setSpriteLayerOfChildren(base.gameObject, num); + if (!simpleSkin) + { + GetComponent<PlayerSkinHandler>().InitSpriteMask(num); + } + } + + private void setSpriteLayerOfChildren(GameObject obj, int layer) + { + sprites = obj.transform.root.GetComponentsInChildren<SpriteMask>(); + for (int i = 0; i < sprites.Length; i++) + { + if (simpleSkin) + { + sprites[i].enabled = false; + sprites[i].GetComponent<SpriteRenderer>().enabled = true; + } + else + { + sprites[i].frontSortingLayerID = layer; + sprites[i].backSortingLayerID = layer; + } + } + } + + public void ToggleSimple(bool isSimple) + { + simpleSkin = isSimple; + } +} diff --git a/GameCode/SetRotation.cs b/GameCode/SetRotation.cs new file mode 100644 index 0000000..284ccf4 --- /dev/null +++ b/GameCode/SetRotation.cs @@ -0,0 +1,38 @@ +using UnityEngine; + +public class SetRotation : MonoBehaviour +{ + public float setRot; + + public float addRot; + + public float extraSetPerLevel; + + private float rot; + + private bool inited; + + private void Init() + { + if (!inited) + { + inited = true; + int attackLevel = GetComponentInParent<AttackLevel>().attackLevel; + setRot += (float)attackLevel * extraSetPerLevel; + } + } + + public void Set() + { + Init(); + rot = setRot; + base.transform.localRotation = Quaternion.Euler(new Vector3(rot, 0f, 0f)); + } + + public void Add() + { + Init(); + rot += addRot; + base.transform.localRotation = Quaternion.Euler(new Vector3(rot, 0f, 0f)); + } +} diff --git a/GameCode/SetScaleFromSizeAndExtraSize.cs b/GameCode/SetScaleFromSizeAndExtraSize.cs new file mode 100644 index 0000000..22b2849 --- /dev/null +++ b/GameCode/SetScaleFromSizeAndExtraSize.cs @@ -0,0 +1,12 @@ +using UnityEngine; + +public class SetScaleFromSizeAndExtraSize : MonoBehaviour +{ + public float scalePerSize; + + private void Start() + { + float size = GetComponentInParent<RayCastTrail>().size; + base.transform.localScale *= size * scalePerSize; + } +} diff --git a/GameCode/SetScaleToZero.cs b/GameCode/SetScaleToZero.cs new file mode 100644 index 0000000..e72085e --- /dev/null +++ b/GameCode/SetScaleToZero.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +public class SetScaleToZero : MonoBehaviour +{ + private void Start() + { + base.transform.localScale = Vector3.zero; + } +} diff --git a/GameCode/SetSpawnedParticleColor.cs b/GameCode/SetSpawnedParticleColor.cs new file mode 100644 index 0000000..fc9052b --- /dev/null +++ b/GameCode/SetSpawnedParticleColor.cs @@ -0,0 +1,30 @@ +using System; +using UnityEngine; + +public class SetSpawnedParticleColor : MonoBehaviour +{ + private Color myColor; + + private void Start() + { + SpawnObjects component = GetComponent<SpawnObjects>(); + component.SpawnedAction = (Action<GameObject>)Delegate.Combine(component.SpawnedAction, new Action<GameObject>(Go)); + myColor = PlayerSkinBank.GetPlayerSkinColors(GetComponentInParent<SpawnedAttack>().spawner.playerID).particleEffect; + } + + private void Go(GameObject spawned) + { + ParticleSystem[] componentsInChildren = spawned.GetComponentsInChildren<ParticleSystem>(); + for (int i = 0; i < componentsInChildren.Length; i++) + { + componentsInChildren[i].startColor = myColor; + } + LineEffect[] componentsInChildren2 = spawned.GetComponentsInChildren<LineEffect>(); + for (int j = 0; j < componentsInChildren2.Length; j++) + { + componentsInChildren2[j].useColorOverTime = false; + componentsInChildren2[j].GetComponent<LineRenderer>().startColor = myColor; + componentsInChildren2[j].GetComponent<LineRenderer>().endColor = myColor; + } + } +} diff --git a/GameCode/SetSpecificArt.cs b/GameCode/SetSpecificArt.cs new file mode 100644 index 0000000..b673df8 --- /dev/null +++ b/GameCode/SetSpecificArt.cs @@ -0,0 +1,38 @@ +using UnityEngine; +using UnityEngine.Rendering.PostProcessing; + +public class SetSpecificArt : MonoBehaviour +{ + public PostProcessProfile profile; + + public string artName; + + public bool playOnStart; + + private void Start() + { + if (playOnStart) + { + if ((bool)profile) + { + ArtHandler.instance.ApplyPost(profile); + } + if (artName != "") + { + ArtHandler.instance.SetSpecificArt(artName); + } + } + } + + public void Go() + { + if ((bool)profile) + { + ArtHandler.instance.ApplyPost(profile); + } + if (artName != "") + { + ArtHandler.instance.SetSpecificArt(artName); + } + } +} diff --git a/GameCode/SetSpriteColor.cs b/GameCode/SetSpriteColor.cs new file mode 100644 index 0000000..8b27d60 --- /dev/null +++ b/GameCode/SetSpriteColor.cs @@ -0,0 +1,18 @@ +using UnityEngine; + +public class SetSpriteColor : MonoBehaviour +{ + private SpriteRenderer sprite; + + public Color[] cols; + + private void Start() + { + sprite = GetComponent<SpriteRenderer>(); + } + + public void SetColor(int id) + { + sprite.color = cols[id]; + } +} diff --git a/GameCode/SetTeamColor.cs b/GameCode/SetTeamColor.cs new file mode 100644 index 0000000..479c1d3 --- /dev/null +++ b/GameCode/SetTeamColor.cs @@ -0,0 +1,84 @@ +using UnityEngine; +using UnityEngine.Events; + +public class SetTeamColor : MonoBehaviour +{ + public enum ColorType + { + Main, + Background, + Particle, + WinText + } + + private SpriteRenderer m_spriteRenderer; + + private ParticleSystem m_particleSystem; + + private LineRenderer m_lineRenderer; + + public UnityEvent SetColorEvent; + + private MeshRenderer meshRend; + + public ColorType colorType; + + private void Awake() + { + m_spriteRenderer = GetComponent<SpriteRenderer>(); + meshRend = GetComponent<MeshRenderer>(); + m_lineRenderer = GetComponent<LineRenderer>(); + } + + public void Set(PlayerSkin teamColor) + { + Color color = teamColor.color; + if (colorType == ColorType.Background) + { + color = teamColor.backgroundColor; + } + if (colorType == ColorType.Particle) + { + color = teamColor.particleEffect; + } + if (colorType == ColorType.WinText) + { + color = teamColor.winText; + } + if ((bool)m_lineRenderer) + { + m_lineRenderer.startColor = color; + m_lineRenderer.endColor = color; + } + else if ((bool)m_spriteRenderer) + { + m_spriteRenderer.color = color; + } + else if ((bool)meshRend) + { + meshRend.material.color = color; + } + else + { + m_particleSystem = GetComponent<ParticleSystem>(); + if ((bool)m_particleSystem) + { + ParticleSystem.MainModule main = m_particleSystem.main; + main.startColor = color; + } + } + SetColorEvent.Invoke(); + } + + public static void TeamColorThis(GameObject go, PlayerSkin teamColor) + { + if (!(teamColor == null)) + { + SetTeamColor[] componentsInChildren = go.GetComponentsInChildren<SetTeamColor>(); + for (int i = 0; i < componentsInChildren.Length; i++) + { + componentsInChildren[i].Set(teamColor); + } + } + } +} diff --git a/GameCode/SetTeamColorFromParentPlayer.cs b/GameCode/SetTeamColorFromParentPlayer.cs new file mode 100644 index 0000000..26e6615 --- /dev/null +++ b/GameCode/SetTeamColorFromParentPlayer.cs @@ -0,0 +1,14 @@ +using UnityEngine; + +public class SetTeamColorFromParentPlayer : MonoBehaviour +{ + private void Start() + { + Player player = GetComponentInParent<Player>(); + if (!player) + { + player = GetComponentInParent<SpawnedAttack>().spawner; + } + GetComponent<SetTeamColor>().Set(PlayerSkinBank.GetPlayerSkinColors(player.playerID)); + } +} diff --git a/GameCode/SetTeamColorFromSpawnedAttack.cs b/GameCode/SetTeamColorFromSpawnedAttack.cs new file mode 100644 index 0000000..6130323 --- /dev/null +++ b/GameCode/SetTeamColorFromSpawnedAttack.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +public class SetTeamColorFromSpawnedAttack : MonoBehaviour +{ + private void Start() + { + GetComponent<SetTeamColor>().Set(PlayerSkinBank.GetPlayerSkinColors(GetComponentInParent<SpawnedAttack>().spawner.playerID)); + } +} diff --git a/GameCode/SetTeamColorSpecific.cs b/GameCode/SetTeamColorSpecific.cs new file mode 100644 index 0000000..d5e9fe8 --- /dev/null +++ b/GameCode/SetTeamColorSpecific.cs @@ -0,0 +1,27 @@ +using UnityEngine; + +public class SetTeamColorSpecific : MonoBehaviour +{ + public Color[] colors; + + private void Start() + { + Player player = GetComponentInParent<Player>(); + if (!player) + { + player = GetComponentInParent<SpawnedAttack>().spawner; + } + ParticleSystem component = GetComponent<ParticleSystem>(); + if ((bool)component) + { + _ = component.main; + component.startColor = colors[player.playerID]; + } + LineRenderer component2 = GetComponent<LineRenderer>(); + if ((bool)component2) + { + component2.startColor = colors[player.playerID]; + component2.endColor = colors[player.playerID]; + } + } +} diff --git a/GameCode/SetTextColor.cs b/GameCode/SetTextColor.cs new file mode 100644 index 0000000..16e8a70 --- /dev/null +++ b/GameCode/SetTextColor.cs @@ -0,0 +1,12 @@ +using TMPro; +using UnityEngine; + +public class SetTextColor : MonoBehaviour +{ + public Color[] colors; + + public void SetColor(int id) + { + GetComponent<TextMeshProUGUI>().color = colors[id]; + } +} diff --git a/GameCode/ShieldCharge.cs b/GameCode/ShieldCharge.cs new file mode 100644 index 0000000..a2860d1 --- /dev/null +++ b/GameCode/ShieldCharge.cs @@ -0,0 +1,168 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using Sonigon; +using UnityEngine; + +public class ShieldCharge : MonoBehaviour +{ + [Header("Sounds")] + public SoundEvent soundShieldCharge; + + [Header("Settings")] + public float damagePerLevel; + + [Header("Settings")] + public float knockBackPerLevel; + + public float forcePerLevel; + + public float timePerLevel; + + public ParticleSystem hitPart; + + public float shake; + + public float damage; + + public float knockBack; + + public float stopForce; + + public AnimationCurve forceCurve; + + public float force; + + public float drag; + + public float time; + + private CharacterData data; + + private AttackLevel level; + + private Vector3 dir; + + private bool cancelForce; + + private List<CharacterData> hitDatas = new List<CharacterData>(); + + private float blockTime; + + private void Start() + { + level = GetComponent<AttackLevel>(); + data = GetComponentInParent<CharacterData>(); + PlayerCollision component = data.GetComponent<PlayerCollision>(); + component.collideWithPlayerAction = (Action<Vector2, Vector2, Player>)Delegate.Combine(component.collideWithPlayerAction, new Action<Vector2, Vector2, Player>(Collide)); + GetComponentInParent<ChildRPC>().childRPCsVector2Vector2Int.Add("ShieldChargeCollide", RPCA_Collide); + Block componentInParent = GetComponentInParent<Block>(); + componentInParent.SuperFirstBlockAction = (Action<BlockTrigger.BlockTriggerType>)Delegate.Combine(componentInParent.SuperFirstBlockAction, new Action<BlockTrigger.BlockTriggerType>(DoBlock)); + } + + private void OnDestroy() + { + PlayerCollision component = data.GetComponent<PlayerCollision>(); + component.collideWithPlayerAction = (Action<Vector2, Vector2, Player>)Delegate.Remove(component.collideWithPlayerAction, new Action<Vector2, Vector2, Player>(Collide)); + GetComponentInParent<ChildRPC>().childRPCsVector2Vector2Int.Remove("ShieldChargeCollide"); + Block componentInParent = GetComponentInParent<Block>(); + componentInParent.SuperFirstBlockAction = (Action<BlockTrigger.BlockTriggerType>)Delegate.Remove(componentInParent.SuperFirstBlockAction, new Action<BlockTrigger.BlockTriggerType>(DoBlock)); + } + + private void Update() + { + blockTime -= TimeHandler.deltaTime; + } + + public void DoBlock(BlockTrigger.BlockTriggerType trigger) + { + if (trigger != BlockTrigger.BlockTriggerType.ShieldCharge) + { + Charge(trigger); + } + } + + public void Charge(BlockTrigger.BlockTriggerType trigger) + { + StartCoroutine(DoCharge(trigger)); + } + + private IEnumerator DoCharge(BlockTrigger.BlockTriggerType trigger) + { + SoundManager.Instance.Play(soundShieldCharge, base.transform); + cancelForce = false; + hitDatas.Clear(); + if (trigger == BlockTrigger.BlockTriggerType.Empower) + { + Vector3 currentPos = base.transform.position; + yield return new WaitForSeconds(0f); + dir = (currentPos - base.transform.position).normalized; + } + else + { + dir = data.aimDirection; + } + float usedTime = (blockTime = time + (float)level.LevelsUp() * timePerLevel); + float num = time * 0.1f + (float)level.LevelsUp() * time * 0.15f; + for (int i = 0; i < level.LevelsUp(); i++) + { + float num2 = time / (float)level.attackLevel; + _ = time; + num += num2; + StartCoroutine(DelayBlock(num)); + } + float c = 0f; + while (c < 1f) + { + c += Time.fixedDeltaTime / usedTime; + if (!cancelForce) + { + data.healthHandler.TakeForce(dir * forceCurve.Evaluate(c) * (force + (float)level.LevelsUp() * forcePerLevel), ForceMode2D.Force, forceIgnoreMass: true, ignoreBlock: true); + data.healthHandler.TakeForce(-data.playerVel.velocity * drag * Time.fixedDeltaTime, ForceMode2D.Force, forceIgnoreMass: true, ignoreBlock: true); + } + data.sinceGrounded = 0f; + yield return new WaitForFixedUpdate(); + } + data.block.RPCA_DoBlock(firstBlock: false, dontSetCD: true, BlockTrigger.BlockTriggerType.ShieldCharge); + } + + private IEnumerator DelayBlock(float delay) + { + yield return new WaitForSeconds(delay); + data.block.RPCA_DoBlock(firstBlock: false, dontSetCD: true, BlockTrigger.BlockTriggerType.ShieldCharge); + } + + public void RPCA_Collide(Vector2 pos, Vector2 colDir, int playerID) + { + CharacterData componentInParent = PlayerManager.instance.GetPlayerWithID(playerID).gameObject.GetComponentInParent<CharacterData>(); + if ((bool)componentInParent) + { + cancelForce = true; + hitPart.transform.rotation = Quaternion.LookRotation(dir); + hitPart.Play(); + componentInParent.healthHandler.TakeDamage(dir * (damage + (float)level.LevelsUp() * damagePerLevel), base.transform.position, null, data.player); + componentInParent.healthHandler.TakeForce(dir * (knockBack + (float)level.LevelsUp() * knockBackPerLevel)); + data.healthHandler.TakeForce(-dir * knockBack, ForceMode2D.Impulse, forceIgnoreMass: false, ignoreBlock: true); + data.healthHandler.TakeForce(-dir * stopForce, ForceMode2D.Impulse, forceIgnoreMass: true, ignoreBlock: true); + data.block.RPCA_DoBlock(firstBlock: false, dontSetCD: true, BlockTrigger.BlockTriggerType.ShieldCharge); + GamefeelManager.GameFeel(dir * shake); + } + } + + public void Collide(Vector2 pos, Vector2 colDir, Player player) + { + if (!data.view.IsMine || blockTime < 0f) + { + return; + } + CharacterData componentInParent = player.gameObject.GetComponentInParent<CharacterData>(); + if (!hitDatas.Contains(componentInParent)) + { + hitDatas.Add(componentInParent); + if ((bool)componentInParent) + { + GetComponentInParent<ChildRPC>().CallFunction("ShieldChargeCollide", pos, colDir, player.playerID); + } + } + } +} diff --git a/GameCode/ShootPos.cs b/GameCode/ShootPos.cs new file mode 100644 index 0000000..ca75170 --- /dev/null +++ b/GameCode/ShootPos.cs @@ -0,0 +1,12 @@ +using UnityEngine; + +public class ShootPos : MonoBehaviour +{ + private void Start() + { + } + + private void Update() + { + } +} diff --git a/GameCode/SilenceHandler.cs b/GameCode/SilenceHandler.cs new file mode 100644 index 0000000..a1cab30 --- /dev/null +++ b/GameCode/SilenceHandler.cs @@ -0,0 +1,70 @@ +using Photon.Pun; +using UnityEngine; + +public class SilenceHandler : MonoBehaviour +{ + [Header("Settings")] + public CodeAnimation codeAnim; + + private Player player; + + private CharacterData data; + + private void Start() + { + player = GetComponent<Player>(); + data = player.data; + } + + private void Update() + { + if (data.silenceTime > 0f) + { + data.silenceTime -= TimeHandler.deltaTime; + if (!data.isSilenced) + { + StartSilence(); + } + } + else if (data.isSilenced) + { + StopSilence(); + } + } + + private void StartSilence() + { + player.data.input.silencedInput = true; + codeAnim.PlayIn(); + data.isSilenced = true; + } + + public void StopSilence() + { + player.data.input.silencedInput = false; + if (codeAnim.currentState == CodeAnimationInstance.AnimationUse.In) + { + codeAnim.PlayOut(); + } + data.isSilenced = false; + data.silenceTime = 0f; + } + + private void OnDisable() + { + codeAnim.transform.localScale = Vector3.zero; + } + + [PunRPC] + public void RPCA_AddSilence(float f) + { + if (f > data.silenceTime) + { + data.silenceTime = f; + } + if (!data.isSilenced) + { + StartSilence(); + } + } +} diff --git a/GameCode/SimulatedSelection.cs b/GameCode/SimulatedSelection.cs new file mode 100644 index 0000000..d80866b --- /dev/null +++ b/GameCode/SimulatedSelection.cs @@ -0,0 +1,33 @@ +using UnityEngine; +using UnityEngine.UI; + +public class SimulatedSelection : MonoBehaviour +{ + private HoverEvent hoverEvent; + + private Button button; + + private void Start() + { + hoverEvent = GetComponent<HoverEvent>(); + button = GetComponent<Button>(); + } + + private void OnDisable() + { + Deselect(); + } + + public void Select() + { + hoverEvent.OnPointerEnter(null); + button.targetGraphic.color = button.colors.highlightedColor; + } + + public void Deselect() + { + hoverEvent.OnPointerExit(null); + button.OnDeselect(null); + button.targetGraphic.color = button.colors.normalColor; + } +} diff --git a/GameCode/SkipIntro.cs b/GameCode/SkipIntro.cs new file mode 100644 index 0000000..809d294 --- /dev/null +++ b/GameCode/SkipIntro.cs @@ -0,0 +1,38 @@ +using InControl; +using UnityEngine; + +public class SkipIntro : MonoBehaviour +{ + public static bool hasShown; + + public ListMenuPage target; + + private void Start() + { + if (hasShown) + { + Skip(); + } + hasShown = true; + } + + private void Update() + { + for (int i = 0; i < InputManager.ActiveDevices.Count; i++) + { + if (InputManager.ActiveDevices[i].AnyButton.WasPressed) + { + Skip(); + } + } + if (Input.GetKeyDown(KeyCode.Escape)) + { + Skip(); + } + } + + private void Skip() + { + target.Open(); + } +} diff --git a/GameCode/SliceEffect.cs b/GameCode/SliceEffect.cs new file mode 100644 index 0000000..e8f1021 --- /dev/null +++ b/GameCode/SliceEffect.cs @@ -0,0 +1,5 @@ +using UnityEngine; + +public class SliceEffect : MonoBehaviour +{ +} diff --git a/GameCode/SoundAudioListenerPosition.cs b/GameCode/SoundAudioListenerPosition.cs new file mode 100644 index 0000000..be8fbd3 --- /dev/null +++ b/GameCode/SoundAudioListenerPosition.cs @@ -0,0 +1,38 @@ +using UnityEngine; + +public class SoundAudioListenerPosition : MonoBehaviour +{ + private float positionZaxis = -50f; + + private AudioListener audioListener; + + private Transform audioListenerTransform; + + private Transform cachedTransform; + + private Vector3 postion; + + private void Awake() + { + audioListener = Object.FindObjectOfType<AudioListener>(); + if (audioListener == null) + { + Debug.LogError("No AudioListener Found"); + } + else + { + audioListenerTransform = audioListener.transform; + } + cachedTransform = base.transform; + } + + private void Update() + { + if (audioListenerTransform != null) + { + postion = cachedTransform.position; + postion.z = positionZaxis; + audioListenerTransform.position = postion; + } + } +} diff --git a/GameCode/SpawnBulletHit.cs b/GameCode/SpawnBulletHit.cs new file mode 100644 index 0000000..27ba4e7 --- /dev/null +++ b/GameCode/SpawnBulletHit.cs @@ -0,0 +1,12 @@ +using UnityEngine; + +public class SpawnBulletHit : MonoBehaviour +{ + private void Start() + { + } + + private void Update() + { + } +} diff --git a/GameCode/SpawnMinion.cs b/GameCode/SpawnMinion.cs new file mode 100644 index 0000000..2b28914 --- /dev/null +++ b/GameCode/SpawnMinion.cs @@ -0,0 +1,36 @@ +using UnityEngine; + +public class SpawnMinion : MonoBehaviour +{ + public GameObject card; + + public GameObject minionAI; + + public GameObject minion; + + private CharacterData data; + + private AttackLevel level; + + private void Start() + { + data = GetComponentInParent<CharacterData>(); + level = GetComponentInParent<AttackLevel>(); + } + + public void Go() + { + for (int i = 0; i < level.attackLevel; i++) + { + GameObject gameObject = Object.Instantiate(minion, base.transform.position + Vector3.up * (((float)i + 1f) * 0.5f), base.transform.rotation); + Object.Instantiate(minionAI, gameObject.transform.position, gameObject.transform.rotation, gameObject.transform); + CharacterData component = gameObject.GetComponent<CharacterData>(); + component.SetAI(data.player); + component.player.playerID = data.player.playerID; + component.isPlaying = true; + card.GetComponent<ApplyCardStats>().Pick(component.player.teamID, forcePick: true); + gameObject.GetComponentInChildren<PlayerSkinHandler>().ToggleSimpleSkin(isSimple: true); + component.healthHandler.DestroyOnDeath = true; + } + } +} diff --git a/GameCode/SpawnObjectEffect.cs b/GameCode/SpawnObjectEffect.cs new file mode 100644 index 0000000..a383ff9 --- /dev/null +++ b/GameCode/SpawnObjectEffect.cs @@ -0,0 +1,101 @@ +using Sirenix.OdinInspector; +using UnityEngine; + +public class SpawnObjectEffect : MonoBehaviour +{ + public enum Dir + { + TowardsEnemy, + DamageDirction, + ReverseDamageDir, + TowardsRecentlyDamaged + } + + public Dir dir; + + [FoldoutGroup("Gun", 0)] + public bool spawnAttack; + + [FoldoutGroup("Gun", 0)] + public float bulletDamageMultiplier = 0.5f; + + [FoldoutGroup("Gun", 0)] + public int numberOfattacks = 1; + + [FoldoutGroup("Gun", 0)] + public float spread; + + [FoldoutGroup("Gun", 0)] + public float gravityMultiplier = 1f; + + [FoldoutGroup("Gun", 0)] + public float speedMultiplier = 1f; + + [FoldoutGroup("Gun", 0)] + public float extraSpread; + + [FoldoutGroup("Gun", 0)] + public float recoilMultiplier = 1f; + + [FoldoutGroup("Gun", 0)] + public int maxBullets = 100; + + private Holding holding; + + private Gun gun; + + private Player player; + + private void Start() + { + holding = GetComponentInParent<Holding>(); + player = GetComponentInParent<Player>(); + } + + public void DoEffect(Vector2 dmg) + { + int num = 0; + if (!spawnAttack) + { + return; + } + for (int i = 0; i < numberOfattacks; i++) + { + if (!gun && (bool)holding && (bool)holding.holdable) + { + gun = holding.holdable.GetComponent<Gun>(); + } + if ((bool)gun) + { + Quaternion rotation = gun.transform.rotation; + Vector3 vector = (PlayerManager.instance.GetOtherPlayer(player).transform.position - base.transform.position).normalized; + if (dir == Dir.DamageDirction) + { + vector = dmg.normalized; + } + if (dir == Dir.ReverseDamageDir) + { + vector = -dmg.normalized; + } + if (dir == Dir.TowardsRecentlyDamaged) + { + vector = (player.data.lastDamagedPlayer.transform.position - base.transform.position).normalized; + } + gun.transform.rotation = Quaternion.LookRotation(Vector3.forward, vector + gun.transform.right * Random.Range(0f - spread, spread)); + gun.projectileSpeed *= speedMultiplier; + gun.gravity *= gravityMultiplier; + gun.spread += extraSpread; + gun.Attack(1f, forceAttack: true, bulletDamageMultiplier, recoilMultiplier); + num += (int)((float)gun.numberOfProjectiles + gun.chargeNumberOfProjectilesTo); + gun.projectileSpeed /= speedMultiplier; + gun.gravity /= gravityMultiplier; + gun.spread -= extraSpread; + gun.transform.rotation = rotation; + if (num > maxBullets) + { + break; + } + } + } + } +} diff --git a/GameCode/SpawnObjectOnDealDamage.cs b/GameCode/SpawnObjectOnDealDamage.cs new file mode 100644 index 0000000..be5b365 --- /dev/null +++ b/GameCode/SpawnObjectOnDealDamage.cs @@ -0,0 +1,50 @@ +using UnityEngine; +using UnityEngine.Events; + +public class SpawnObjectOnDealDamage : DealtDamageEffect +{ + public UnityEvent triggerEvent; + + public float damageNeeded = 25f; + + public float cd = 0.2f; + + private float time; + + private float damageDealt; + + private SpawnObjectEffect spawn; + + private DamageEffect dmgEffect; + + public bool allowSelfDmg; + + private void Start() + { + spawn = GetComponent<SpawnObjectEffect>(); + dmgEffect = GetComponent<DamageEffect>(); + } + + public override void DealtDamage(Vector2 damage, bool selfDamage, Player damagedPlayer = null) + { + if (selfDamage && !allowSelfDmg) + { + return; + } + damageDealt += damage.magnitude; + if (damageDealt > damageNeeded && Time.time > time + cd) + { + time = Time.time; + damageDealt = 0f; + if ((bool)spawn) + { + spawn.DoEffect(damage); + } + if ((bool)dmgEffect) + { + dmgEffect.DoDamageEffect(damage, selfDamage, damagedPlayer); + } + triggerEvent.Invoke(); + } + } +} diff --git a/GameCode/SpawnObjectOnDealtDamage.cs b/GameCode/SpawnObjectOnDealtDamage.cs new file mode 100644 index 0000000..0c4d8cf --- /dev/null +++ b/GameCode/SpawnObjectOnDealtDamage.cs @@ -0,0 +1,35 @@ +using UnityEngine; + +public class SpawnObjectOnDealtDamage : WasDealtDamageEffect +{ + public float damageNeeded = 25f; + + public float cd = 0.2f; + + public bool allowSelfDamage; + + private float time; + + private float damageDealt; + + private SpawnObjectEffect spawn; + + private void Start() + { + spawn = GetComponent<SpawnObjectEffect>(); + } + + public override void WasDealtDamage(Vector2 damage, bool selfDamage) + { + if (!selfDamage || allowSelfDamage) + { + damageDealt += damage.magnitude; + if (damageDealt > damageNeeded && Time.time > time + cd) + { + time = Time.time; + damageDealt = 0f; + spawn.DoEffect(damage); + } + } + } +} diff --git a/GameCode/SpawnObjects.cs b/GameCode/SpawnObjects.cs new file mode 100644 index 0000000..8f00c7a --- /dev/null +++ b/GameCode/SpawnObjects.cs @@ -0,0 +1,83 @@ +using System; +using Photon.Pun; +using UnityEngine; + +public class SpawnObjects : MonoBehaviour +{ + public enum SpawnRot + { + Identity, + TransformRotation + } + + public GameObject[] objectToSpawn; + + public SpawnRot spawnRot; + + public bool inheritScale; + + public bool destroyObject; + + public bool destroyRoot; + + private PhotonView view; + + public Action<GameObject> SpawnedAction; + + [HideInInspector] + public GameObject mostRecentlySpawnedObject; + + private void ConfigureObject(GameObject go) + { + SpawnedAttack spawnedAttack = go.GetComponent<SpawnedAttack>(); + if (!spawnedAttack) + { + spawnedAttack = go.AddComponent<SpawnedAttack>(); + } + spawnedAttack.spawner = base.transform.root.GetComponent<Player>(); + if (!spawnedAttack.spawner) + { + SpawnedAttack componentInParent = base.transform.GetComponentInParent<SpawnedAttack>(); + if ((bool)componentInParent) + { + componentInParent.CopySpawnedAttackTo(go); + } + } + AttackLevel componentInParent2 = GetComponentInParent<AttackLevel>(); + if ((bool)componentInParent2) + { + spawnedAttack.attackLevel = componentInParent2.attackLevel; + } + if (inheritScale) + { + go.transform.localScale *= base.transform.localScale.x; + } + if (SpawnedAction != null) + { + SpawnedAction(go); + } + } + + public void Spawn() + { + for (int i = 0; i < objectToSpawn.Length; i++) + { + Quaternion rotation = Quaternion.identity; + if (spawnRot == SpawnRot.TransformRotation) + { + rotation = base.transform.rotation; + } + GameObject go = UnityEngine.Object.Instantiate(objectToSpawn[i], base.transform.position, rotation); + ConfigureObject(go); + mostRecentlySpawnedObject = go; + } + if (destroyObject) + { + UnityEngine.Object.Destroy(base.gameObject); + } + if (destroyRoot) + { + UnityEngine.Object.Destroy(base.transform.root.gameObject); + } + } +} diff --git a/GameCode/SpawnPoint.cs b/GameCode/SpawnPoint.cs new file mode 100644 index 0000000..5a4a0cf --- /dev/null +++ b/GameCode/SpawnPoint.cs @@ -0,0 +1,15 @@ +using UnityEngine; + +public class SpawnPoint : MonoBehaviour +{ + public int ID; + + public int TEAMID; + + public Vector3 localStartPos; + + private void Awake() + { + localStartPos = base.transform.localPosition; + } +} diff --git a/GameCode/SpawnStaticRemnant.cs b/GameCode/SpawnStaticRemnant.cs new file mode 100644 index 0000000..9e0a67e --- /dev/null +++ b/GameCode/SpawnStaticRemnant.cs @@ -0,0 +1,52 @@ +using UnityEngine; + +public class SpawnStaticRemnant : MonoBehaviour +{ + public GameObject remnantSource; + + private AttackLevel level; + + private Color remnantColor; + + private void Start() + { + remnantColor = PlayerSkinBank.GetPlayerSkinColors(base.transform.GetComponentInParent<Player>().playerID).winText; + level = GetComponent<AttackLevel>(); + } + + public void Go() + { + GameObject gameObject = Object.Instantiate(remnantSource, base.transform.position, base.transform.rotation); + SpriteRenderer[] componentsInChildren = base.transform.root.GetComponentsInChildren<SpriteRenderer>(); + for (int i = 0; i < componentsInChildren.Length; i++) + { + if (componentsInChildren[i].transform.lossyScale.x != 0f && componentsInChildren[i].transform.lossyScale.y != 0f && componentsInChildren[i].transform.lossyScale.z != 0f && (!(componentsInChildren[i].transform.parent.name != "Art") || !(componentsInChildren[i].transform.parent.parent.name != "Face"))) + { + Vector3 lossyScale = componentsInChildren[i].transform.lossyScale; + GameObject gameObject2 = Object.Instantiate(componentsInChildren[i].gameObject, componentsInChildren[i].transform.position, componentsInChildren[i].transform.rotation, gameObject.transform.GetChild(0)); + gameObject2.transform.localScale = lossyScale; + Strip(gameObject2); + SpriteRenderer component = gameObject2.GetComponent<SpriteRenderer>(); + component.enabled = true; + component.color = remnantColor; + SpriteMask component2 = gameObject2.GetComponent<SpriteMask>(); + if ((bool)component2) + { + Object.Destroy(component2); + } + } + } + gameObject.GetComponentInChildren<ParticleSystem>().startColor = PlayerSkinBank.GetPlayerSkinColors(base.transform.GetComponentInParent<Player>().playerID).particleEffect; + gameObject.AddComponent<SpawnedAttack>().spawner = base.transform.root.GetComponent<Player>(); + gameObject.transform.localScale *= 1f + (float)(level.attackLevel - 1) * 0.3f; + } + + private void Strip(GameObject go) + { + MonoBehaviour[] componentsInChildren = go.GetComponentsInChildren<MonoBehaviour>(); + for (int i = 0; i < componentsInChildren.Length; i++) + { + Object.Destroy(componentsInChildren[i]); + } + } +} diff --git a/GameCode/SpawnedAttack.cs b/GameCode/SpawnedAttack.cs new file mode 100644 index 0000000..8a4a096 --- /dev/null +++ b/GameCode/SpawnedAttack.cs @@ -0,0 +1,63 @@ +using Photon.Pun; +using UnityEngine; + +public class SpawnedAttack : MonoBehaviour +{ + public Player spawner; + + public int attackLevel; + + public int attackID; + + public PhotonView view; + + private void Awake() + { + view = GetComponent<PhotonView>(); + } + + [PunRPC] + public void RPCA_SetSpawner(int spawnerID) + { + spawner = PhotonNetwork.GetPhotonView(spawnerID).GetComponent<Player>(); + } + + public void CopySpawnedAttackTo(GameObject to) + { + SpawnedAttack spawnedAttack = to.GetComponent<SpawnedAttack>(); + if (!spawnedAttack) + { + spawnedAttack = to.AddComponent<SpawnedAttack>(); + } + spawnedAttack.spawner = spawner; + spawnedAttack.attackLevel = attackLevel; + } + + public void SetColor(Color color) + { + TrailRenderer[] componentsInChildren = GetComponentsInChildren<TrailRenderer>(); + for (int i = 0; i < componentsInChildren.Length; i++) + { + componentsInChildren[i].startColor = color; + componentsInChildren[i].endColor = color; + } + ProjectileHit component = GetComponent<ProjectileHit>(); + if ((bool)component) + { + component.projectileColor = color; + } + } + + public bool IsMine() + { + if ((bool)view) + { + return view.IsMine; + } + if ((bool)spawner) + { + return spawner.data.view.IsMine; + } + return false; + } +} diff --git a/GameCode/SpawnedAttack_ParentPlayer.cs b/GameCode/SpawnedAttack_ParentPlayer.cs new file mode 100644 index 0000000..f77247f --- /dev/null +++ b/GameCode/SpawnedAttack_ParentPlayer.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +public class SpawnedAttack_ParentPlayer : MonoBehaviour +{ + private void Start() + { + GetComponent<SpawnedAttack>().spawner = GetComponentInParent<Player>(); + } +} diff --git a/GameCode/Spring.cs b/GameCode/Spring.cs new file mode 100644 index 0000000..35cb057 --- /dev/null +++ b/GameCode/Spring.cs @@ -0,0 +1,24 @@ +using UnityEngine; + +public class Spring : MonoBehaviour +{ + public float spring = 1f; + + private Rigidbody2D rig; + + private Vector3 up; + + private void Start() + { + rig = GetComponent<Rigidbody2D>(); + up = base.transform.up; + } + + private void FixedUpdate() + { + if ((bool)rig) + { + rig.AddTorque((Vector3.Cross(base.transform.up, up).normalized * Vector3.Angle(base.transform.up, up)).z * spring * rig.mass); + } + } +} diff --git a/GameCode/StandStillTrigger.cs b/GameCode/StandStillTrigger.cs new file mode 100644 index 0000000..b5dc487 --- /dev/null +++ b/GameCode/StandStillTrigger.cs @@ -0,0 +1,25 @@ +using UnityEngine; + +public class StandStillTrigger : MonoBehaviour +{ + public float sinceStandStill; + + private CharacterData data; + + private void Start() + { + data = base.transform.GetComponentInParent<CharacterData>(); + } + + private void Update() + { + if (data.isGrounded && data.input.direction.magnitude < 0.1f) + { + sinceStandStill += TimeHandler.deltaTime; + } + else + { + sinceStandStill = 0f; + } + } +} diff --git a/GameCode/StartEvent.cs b/GameCode/StartEvent.cs new file mode 100644 index 0000000..b05cd6e --- /dev/null +++ b/GameCode/StartEvent.cs @@ -0,0 +1,12 @@ +using UnityEngine; +using UnityEngine.Events; + +public class StartEvent : MonoBehaviour +{ + public UnityEvent startEvent; + + private void Start() + { + startEvent.Invoke(); + } +} diff --git a/GameCode/StatsAfterDealingDamage.cs b/GameCode/StatsAfterDealingDamage.cs new file mode 100644 index 0000000..d228813 --- /dev/null +++ b/GameCode/StatsAfterDealingDamage.cs @@ -0,0 +1,68 @@ +using UnityEngine; +using UnityEngine.Events; + +public class StatsAfterDealingDamage : MonoBehaviour +{ + public float duration = 3f; + + public float movementSpeedMultiplier = 1f; + + public float jumpMultiplier = 1f; + + public float hpMultiplier = 1f; + + public UnityEvent startEvent; + + public UnityEvent endEvent; + + private bool isOn; + + private CharacterData data; + + private void Start() + { + data = GetComponentInParent<CharacterData>(); + } + + private void Update() + { + bool flag = data.stats.sinceDealtDamage < duration; + if (isOn != flag) + { + isOn = flag; + _ = base.transform.localScale; + if (isOn) + { + data.health *= hpMultiplier; + data.maxHealth *= hpMultiplier; + data.stats.movementSpeed *= movementSpeedMultiplier; + data.stats.jump *= jumpMultiplier; + data.stats.ConfigureMassAndSize(); + startEvent.Invoke(); + } + else + { + data.health /= hpMultiplier; + data.maxHealth /= hpMultiplier; + data.stats.movementSpeed /= movementSpeedMultiplier; + data.stats.jump /= jumpMultiplier; + data.stats.ConfigureMassAndSize(); + endEvent.Invoke(); + } + } + } + + public void Interupt() + { + if (isOn) + { + data.health /= hpMultiplier; + data.maxHealth /= hpMultiplier; + data.stats.movementSpeed /= movementSpeedMultiplier; + data.stats.jump /= jumpMultiplier; + data.stats.ConfigureMassAndSize(); + endEvent.Invoke(); + isOn = false; + } + } +} diff --git a/GameCode/StatsWhenFullHP.cs b/GameCode/StatsWhenFullHP.cs new file mode 100644 index 0000000..21166c7 --- /dev/null +++ b/GameCode/StatsWhenFullHP.cs @@ -0,0 +1,58 @@ +using Sonigon; +using UnityEngine; + +public class StatsWhenFullHP : MonoBehaviour +{ + public bool playSound; + + public SoundEvent soundPristineGrow; + + public SoundEvent soundPristineShrink; + + public float healthMultiplier = 1f; + + public float sizeMultiplier = 1f; + + public float healthThreshold = 0.95f; + + private CharacterData data; + + private bool isOn; + + private void Start() + { + data = GetComponentInParent<CharacterData>(); + } + + private void Update() + { + bool flag = data.health / data.maxHealth >= healthThreshold; + if (flag == isOn) + { + return; + } + isOn = flag; + if (isOn) + { + if (playSound) + { + SoundManager.Instance.PlayAtPosition(soundPristineGrow, SoundManager.Instance.GetTransform(), base.transform); + } + data.health *= healthMultiplier; + data.maxHealth *= healthMultiplier; + data.stats.sizeMultiplier *= sizeMultiplier; + data.stats.ConfigureMassAndSize(); + } + else + { + if (playSound) + { + SoundManager.Instance.PlayAtPosition(soundPristineShrink, SoundManager.Instance.GetTransform(), base.transform); + } + data.health /= healthMultiplier; + data.maxHealth /= healthMultiplier; + data.stats.sizeMultiplier /= sizeMultiplier; + data.stats.ConfigureMassAndSize(); + } + } +} diff --git a/GameCode/SteamManager.cs b/GameCode/SteamManager.cs new file mode 100644 index 0000000..9f30390 --- /dev/null +++ b/GameCode/SteamManager.cs @@ -0,0 +1,99 @@ +using System; +using System.Text; +using Steamworks; +using UnityEngine; + +[DisallowMultipleComponent] +public class SteamManager : MonoBehaviour +{ + protected static bool s_EverInitialized; + + protected static SteamManager s_instance; + + protected bool m_bInitialized; + + protected SteamAPIWarningMessageHook_t m_SteamAPIWarningMessageHook; + + protected static SteamManager Instance + { + get + { + if (s_instance == null) + { + return new GameObject("SteamManager").AddComponent<SteamManager>(); + } + return s_instance; + } + } + + public static bool Initialized => Instance.m_bInitialized; + + protected static void SteamAPIDebugTextHook(int nSeverity, StringBuilder pchDebugText) + { + } + + protected virtual void Awake() + { + if (s_instance != null) + { + UnityEngine.Object.Destroy(base.gameObject); + return; + } + s_instance = this; + if (s_EverInitialized) + { + throw new Exception("Tried to Initialize the SteamAPI twice in one session!"); + } + UnityEngine.Object.DontDestroyOnLoad(base.gameObject); + if (!Packsize.Test()) + { + Debug.LogError("[Steamworks.NET] Packsize Test returned false, the wrong version of Steamworks.NET is being run in this platform.", this); + } + if (!DllCheck.Test()) + { + Debug.LogError("[Steamworks.NET] DllCheck Test returned false, One or more of the Steamworks binaries seems to be the wrong version.", this); + } + m_bInitialized = SteamAPI.Init(); + if (!m_bInitialized) + { + Debug.LogError("[Steamworks.NET] SteamAPI_Init() failed. Refer to Valve's documentation or the comment above this line for more information.", this); + } + else + { + s_EverInitialized = true; + } + } + + protected virtual void OnEnable() + { + if (s_instance == null) + { + s_instance = this; + } + if (m_bInitialized && m_SteamAPIWarningMessageHook == null) + { + m_SteamAPIWarningMessageHook = SteamAPIDebugTextHook; + SteamClient.SetWarningMessageHook(m_SteamAPIWarningMessageHook); + } + } + + protected virtual void OnDestroy() + { + if (!(s_instance != this)) + { + s_instance = null; + if (m_bInitialized) + { + SteamAPI.Shutdown(); + } + } + } + + protected virtual void Update() + { + if (m_bInitialized) + { + SteamAPI.RunCallbacks(); + } + } +} diff --git a/GameCode/StopRecursion.cs b/GameCode/StopRecursion.cs new file mode 100644 index 0000000..e77fbb7 --- /dev/null +++ b/GameCode/StopRecursion.cs @@ -0,0 +1,5 @@ +using UnityEngine; + +public class StopRecursion : MonoBehaviour +{ +} diff --git a/GameCode/StunHandler.cs b/GameCode/StunHandler.cs new file mode 100644 index 0000000..bb3f93e --- /dev/null +++ b/GameCode/StunHandler.cs @@ -0,0 +1,102 @@ +using Sonigon; +using UnityEngine; + +public class StunHandler : MonoBehaviour +{ + [Header("Sounds")] + public SoundEvent soundCharacterStunLoop; + + private bool soundStunIsPlaying; + + [Header("Settings")] + public CodeAnimation codeAnim; + + private Player player; + + private CharacterData data; + + private void Start() + { + player = GetComponent<Player>(); + data = player.data; + } + + private void Update() + { + if (data.stunTime > 0f) + { + data.stunTime -= TimeHandler.deltaTime; + data.sinceGrounded = 0f; + if (!data.isStunned) + { + StartStun(); + } + } + else if (data.isStunned) + { + StopStun(); + } + if (data.isStunned && data.isPlaying && !data.dead) + { + if (!soundStunIsPlaying) + { + soundStunIsPlaying = true; + SoundManager.Instance.Play(soundCharacterStunLoop, base.transform); + } + } + else if (soundStunIsPlaying) + { + soundStunIsPlaying = false; + SoundManager.Instance.Stop(soundCharacterStunLoop, base.transform); + } + } + + private void StartStun() + { + player.data.playerVel.velocity *= 0f; + player.data.playerVel.isKinematic = true; + player.data.input.stunnedInput = true; + codeAnim.PlayIn(); + data.isStunned = true; + } + + public void StopStun() + { + player.data.playerVel.isKinematic = false; + player.data.input.stunnedInput = false; + if (codeAnim.currentState == CodeAnimationInstance.AnimationUse.In) + { + codeAnim.PlayOut(); + } + data.isStunned = false; + data.stunTime = 0f; + } + + private void OnDisable() + { + codeAnim.transform.localScale = Vector3.zero; + soundStunIsPlaying = false; + SoundManager.Instance.Stop(soundCharacterStunLoop, base.transform); + } + + private void OnDestroy() + { + soundStunIsPlaying = false; + SoundManager.Instance.Stop(soundCharacterStunLoop, base.transform); + } + + public void AddStun(float f) + { + if (!data.block.IsBlocking()) + { + if (f > data.stunTime) + { + data.stunTime = f; + } + if (!data.isStunned) + { + StartStun(); + } + } + } +} diff --git a/GameCode/StunPlayer.cs b/GameCode/StunPlayer.cs new file mode 100644 index 0000000..c131626 --- /dev/null +++ b/GameCode/StunPlayer.cs @@ -0,0 +1,29 @@ +using UnityEngine; + +public class StunPlayer : MonoBehaviour +{ + public enum TargetPlayer + { + OtherPlayer, + Self + } + + public TargetPlayer targetPlayer; + + public float time = 0.5f; + + private Player target; + + public void Go() + { + if (!target) + { + target = GetComponentInParent<Player>(); + if (targetPlayer == TargetPlayer.OtherPlayer) + { + target = PlayerManager.instance.GetOtherPlayer(target); + } + } + target.data.stunHandler.AddStun(time); + } +} diff --git a/GameCode/SuperBasicController.cs b/GameCode/SuperBasicController.cs new file mode 100644 index 0000000..6456afc --- /dev/null +++ b/GameCode/SuperBasicController.cs @@ -0,0 +1,327 @@ +using Photon.Pun; +using Photon.Pun.Simple; +using UnityEngine; + +public class SuperBasicController : NetComponent +{ + public bool is2D; + + [Range(0f, 300f)] + public float turnSpeed = 150f; + + [Range(0f, 4f)] + public float moveSpeed = 4f; + + public bool autoMove = true; + + private Vector3 targRotDelta; + + private Vector3 targPosDelta; + + private float appliedDeltaT; + + private Animator animator; + + private SyncAnimator syncAnimator; + + private SyncTransform syncTransform; + + private SyncCannon syncLauncher; + + private SyncContactScan syncHitscan; + + private bool triggerJump; + + private bool triggerFade; + + private bool triggerTurnLeft; + + private bool triggerUpperBodyRun; + + private bool triggerUpperBodyIdle; + + private bool triggerTeleport; + + private bool freakingOut; + + private bool triggerHitscan; + + private bool triggerProjectile; + + private bool triggerBlend; + + public override void OnAwake() + { + base.OnAwake(); + animator = base.transform.GetNestedComponentInChildren<Animator, NetObject>(includeInactive: true); + syncAnimator = base.transform.GetNestedComponentInChildren<SyncAnimator, NetObject>(includeInactive: true); + syncTransform = GetComponent<SyncTransform>(); + syncLauncher = base.transform.GetNestedComponentInChildren<SyncCannon, NetObject>(includeInactive: true); + syncHitscan = base.transform.GetNestedComponentInChildren<SyncContactScan, NetObject>(includeInactive: true); + } + + private void Update() + { + if (!base.IsMine) + { + return; + } + float t = (Time.time - Time.fixedTime) / Time.fixedDeltaTime; + Interpolate(t); + if (Input.GetKeyDown(KeyCode.Space)) + { + triggerJump = true; + } + if (Input.GetKeyDown(KeyCode.Alpha2)) + { + triggerFade = true; + } + if (Input.GetKeyDown(KeyCode.Alpha1)) + { + triggerTurnLeft = true; + } + if (Input.GetKeyDown(KeyCode.Alpha4)) + { + if (freakingOut) + { + triggerUpperBodyIdle = true; + } + else + { + triggerUpperBodyRun = true; + } + freakingOut = !freakingOut; + } + if (Input.GetKeyDown(KeyCode.F)) + { + triggerProjectile = true; + } + if (Input.GetKeyDown(KeyCode.R)) + { + triggerHitscan = true; + } + if (Input.GetKeyDown(KeyCode.T)) + { + triggerTeleport = true; + } + if (Input.GetKeyDown(KeyCode.B)) + { + triggerBlend = true; + } + } + + private void FixedUpdate() + { + if (!base.IsMine) + { + return; + } + Vector3 move = new Vector3(0f, 0f, 0f); + Vector3 turn = new Vector3(0f, 0f, 0f); + if ((bool)animator && animator.isActiveAndEnabled) + { + if (Input.GetKey(KeyCode.W)) + { + animator.SetBool("walking", value: true); + animator.SetFloat("speed", 1f); + } + else if (Input.GetKey(KeyCode.S)) + { + animator.SetBool("walking", value: true); + animator.SetFloat("speed", -0.5f); + } + else + { + animator.SetBool("walking", value: false); + animator.SetFloat("speed", 0f); + } + if (triggerJump) + { + if ((bool)syncAnimator) + { + syncAnimator.SetTrigger("jump"); + } + triggerJump = false; + } + else if (triggerTurnLeft) + { + if ((bool)syncAnimator) + { + syncAnimator.SetTrigger("turnLeft"); + } + triggerTurnLeft = false; + } + if (triggerFade) + { + if ((bool)syncAnimator) + { + syncAnimator.CrossFadeInFixedTime("Jump", 0.25f); + } + triggerFade = false; + } + if (triggerBlend) + { + animator.SetFloat("blender", Mathf.Abs(Mathf.Sin(Time.time))); + } + else + { + animator.SetFloat("blender", -1f); + } + if (triggerUpperBodyRun) + { + if ((bool)syncAnimator) + { + syncAnimator.SetTrigger("upperBodyRun"); + } + triggerUpperBodyRun = false; + } + else if (triggerUpperBodyIdle) + { + if ((bool)syncAnimator) + { + syncAnimator.SetTrigger("upperBodyIdle"); + } + triggerUpperBodyIdle = false; + } + } + if (!animator || !animator.applyRootMotion) + { + if (Input.GetKey(KeyCode.W)) + { + move += Vector3.forward; + } + else if (Input.GetKey(KeyCode.S)) + { + move -= Vector3.forward; + } + } + if (Input.GetKey(KeyCode.A)) + { + move -= Vector3.right; + } + if (Input.GetKey(KeyCode.D)) + { + move += Vector3.right; + } + if (Input.GetKey(KeyCode.E)) + { + turn += Vector3.up; + } + if (Input.GetKey(KeyCode.Q)) + { + turn -= Vector3.up; + } + if (Input.touchCount > 0) + { + Touch touch = Input.GetTouch(0); + Vector2 vector = new Vector2(touch.rawPosition.x / (float)Screen.width, touch.rawPosition.y / (float)Screen.height); + if (vector.y > 0.66f) + { + if (vector.x > 0.66f) + { + triggerHitscan = true; + } + else if (vector.x < 0.33f) + { + triggerJump = true; + } + } + else if (vector.y < 0.33f) + { + if (vector.x > 0.66f) + { + move += Vector3.right; + } + else if (vector.x < 0.33f) + { + move -= Vector3.right; + } + else if ((bool)animator) + { + animator.SetBool("walking", value: true); + animator.SetFloat("speed", -0.5f); + } + } + else if (vector.x > 0.66f) + { + turn += Vector3.up; + } + else if (vector.x < 0.33f) + { + turn -= Vector3.up; + } + else if ((bool)animator) + { + animator.SetBool("walking", value: true); + animator.SetFloat("speed", 1f); + } + } + if (autoMove && !Application.isFocused) + { + turn += new Vector3(0f, Mathf.Sin(Time.time * 0.5f), 0f); + if ((bool)animator) + { + animator.SetBool("walking", value: true); + animator.SetFloat("speed", Mathf.Sin(Time.time) * 0.5f); + } + } + Interpolate(1f); + Move(move, turn); + appliedDeltaT = 0f; + if (triggerHitscan) + { + if ((bool)syncHitscan) + { + syncHitscan.QueueTrigger(); + } + triggerHitscan = false; + } + if (triggerProjectile) + { + if ((bool)syncLauncher) + { + syncLauncher.QueueTrigger(); + } + triggerProjectile = false; + } + if (triggerTeleport) + { + if ((bool)syncTransform) + { + syncTransform.FlagTeleport(); + base.transform.localPosition = default(Vector3); + base.transform.localRotation = default(Quaternion); + } + triggerTeleport = false; + } + } + + private void OnAnimatorMove() + { + if (base.IsMine) + { + animator.ApplyBuiltinRootMotion(); + base.transform.rotation = animator.rootRotation; + base.transform.position = animator.rootPosition; + } + } + + private void Move(Vector3 move, Vector3 turn) + { + if (is2D) + { + move = new Vector3(move.x, move.z, 0f); + turn = new Vector3(0f, 0f, turn.y); + } + targRotDelta = turn * turnSpeed * Time.fixedDeltaTime; + targPosDelta = move * moveSpeed * Time.fixedDeltaTime; + } + + private void Interpolate(float t) + { + t -= appliedDeltaT; + appliedDeltaT += t; + base.transform.rotation = base.transform.rotation * Quaternion.Euler(targRotDelta * t); + base.transform.position += base.transform.rotation * (targPosDelta * t); + } +} diff --git a/GameCode/SwordArtMove.cs b/GameCode/SwordArtMove.cs new file mode 100644 index 0000000..b521e51 --- /dev/null +++ b/GameCode/SwordArtMove.cs @@ -0,0 +1,61 @@ +using UnityEngine; + +public class SwordArtMove : MonoBehaviour +{ + private MoveTransform move; + + public LayerMask mask; + + public AnimationCurve heightCurve; + + public AnimationCurve AwayCurve; + + private Vector3 startUp; + + private Vector3 startForward; + + private Vector3 startPos; + + public float multiplier = 1f; + + public float heightMultiplier = 1f; + + public float awayMultiplier = 1f; + + public float speed = 1f; + + private float counter; + + private ParticleSystem[] parts; + + private void Start() + { + parts = GetComponentsInChildren<ParticleSystem>(); + move = GetComponentInParent<MoveTransform>(); + move.enabled = false; + startForward = base.transform.forward; + startUp = Vector3.Cross(base.transform.forward, Vector3.forward); + startPos = base.transform.position; + awayMultiplier *= Mathf.Pow(move.localForce.magnitude / 40f * 2f, 0.45f); + awayMultiplier /= 1f + move.drag * 0.05f; + speed *= Mathf.Pow(awayMultiplier, 0.3f); + } + + private void Update() + { + counter += TimeHandler.deltaTime * speed; + Vector3 vector = startPos + (heightCurve.Evaluate(counter) * heightMultiplier * startUp + AwayCurve.Evaluate(counter) * awayMultiplier * startForward) * multiplier; + RaycastHit2D raycastHit2D = Physics2D.Raycast(startPos, (vector - startPos).normalized, Vector3.Distance(vector, startPos), mask); + if ((bool)raycastHit2D.transform && !raycastHit2D.collider.GetComponent<Damagable>()) + { + vector = raycastHit2D.point + raycastHit2D.normal * 0.1f; + for (int i = 0; i < parts.Length; i++) + { + parts[i].transform.position = (Vector3)raycastHit2D.point + Vector3.forward * 8f; + parts[i].transform.rotation = Quaternion.LookRotation(raycastHit2D.normal); + parts[i].Emit(1); + } + } + base.transform.root.position = vector; + } +} diff --git a/GameCode/TasteOfBlood.cs b/GameCode/TasteOfBlood.cs new file mode 100644 index 0000000..1a7ed41 --- /dev/null +++ b/GameCode/TasteOfBlood.cs @@ -0,0 +1,66 @@ +using System; +using UnityEngine; + +public class TasteOfBlood : MonoBehaviour +{ + public AnimationCurve attackSpeedCurve; + + public float decaySpeed = 1f; + + private float damageValue; + + private CharacterStatModifiers stats; + + private ParticleSystem part; + + private CharacterData data; + + private bool isOn; + + private void Start() + { + part = GetComponentInChildren<ParticleSystem>(); + stats = GetComponentInParent<CharacterStatModifiers>(); + CharacterStatModifiers characterStatModifiers = stats; + characterStatModifiers.DealtDamageAction = (Action<Vector2, bool>)Delegate.Combine(characterStatModifiers.DealtDamageAction, new Action<Vector2, bool>(DealtDamage)); + data = GetComponentInParent<CharacterData>(); + } + + public void DealtDamage(Vector2 damage, bool selfDamage) + { + if (!selfDamage) + { + damageValue += damage.magnitude; + } + damageValue = Mathf.Clamp(damageValue, 0f, 50f); + } + + private void Update() + { + if (!data.isPlaying) + { + damageValue = 0f; + } + if (damageValue > 0f) + { + damageValue -= TimeHandler.deltaTime * decaySpeed; + isOn = true; + } + else + { + isOn = false; + } + if (damageValue > 10f) + { + if (!part.isPlaying) + { + part.Play(); + } + } + else if (part.isPlaying) + { + part.Stop(); + } + stats.tasteOfBloodSpeed = attackSpeedCurve.Evaluate(damageValue); + } +} diff --git a/GameCode/Teleport.cs b/GameCode/Teleport.cs new file mode 100644 index 0000000..614ccdc --- /dev/null +++ b/GameCode/Teleport.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections; +using UnityEngine; + +public class Teleport : MonoBehaviour +{ + public ParticleSystem[] parts; + + public ParticleSystem[] remainParts; + + public float distance = 10f; + + public LayerMask mask; + + private CharacterData data; + + private AttackLevel level; + + private void Start() + { + parts = GetComponentsInChildren<ParticleSystem>(); + data = GetComponentInParent<CharacterData>(); + level = GetComponentInParent<AttackLevel>(); + Block componentInParent = GetComponentInParent<Block>(); + componentInParent.SuperFirstBlockAction = (Action<BlockTrigger.BlockTriggerType>)Delegate.Combine(componentInParent.SuperFirstBlockAction, new Action<BlockTrigger.BlockTriggerType>(Go)); + } + + private void OnDestroy() + { + Block componentInParent = GetComponentInParent<Block>(); + componentInParent.SuperFirstBlockAction = (Action<BlockTrigger.BlockTriggerType>)Delegate.Remove(componentInParent.SuperFirstBlockAction, new Action<BlockTrigger.BlockTriggerType>(Go)); + } + + public void Go(BlockTrigger.BlockTriggerType triggerType) + { + StartCoroutine(DelayMove(triggerType, base.transform.position)); + } + + private IEnumerator DelayMove(BlockTrigger.BlockTriggerType triggerType, Vector3 beforePos) + { + if (triggerType == BlockTrigger.BlockTriggerType.Empower) + { + yield return new WaitForSeconds(0f); + } + Vector3 position = base.transform.position; + Vector3 position2 = base.transform.position; + int num = 10; + float num2 = distance * (float)level.attackLevel / (float)num; + for (int i = 0; i < num; i++) + { + position += num2 * data.aimDirection; + if (!Physics2D.OverlapCircle(position, 0.5f)) + { + position2 = position; + } + } + for (int j = 0; j < remainParts.Length; j++) + { + remainParts[j].transform.position = base.transform.root.position; + remainParts[j].Play(); + } + GetComponentInParent<PlayerCollision>().IgnoreWallForFrames(2); + if (triggerType == BlockTrigger.BlockTriggerType.Empower) + { + position2 = beforePos; + } + base.transform.root.position = position2; + for (int k = 0; k < parts.Length; k++) + { + parts[k].transform.position = position2; + parts[k].Play(); + } + data.playerVel.velocity *= 0f; + data.sinceGrounded = 0f; + } +} diff --git a/GameCode/TeleportToOpponent.cs b/GameCode/TeleportToOpponent.cs new file mode 100644 index 0000000..193c632 --- /dev/null +++ b/GameCode/TeleportToOpponent.cs @@ -0,0 +1,27 @@ +using UnityEngine; + +public class TeleportToOpponent : MonoBehaviour +{ + public float time = 0.5f; + + public ParticleSystem from; + + public ParticleSystem to; + + private Player target; + + private void Start() + { + } + + public void Go() + { + if (!target) + { + target = PlayerManager.instance.GetOtherPlayer(GetComponentInParent<Player>()); + } + from.Play(); + base.transform.root.transform.position = target.transform.position + (target.transform.position - base.transform.position).normalized; + to.Play(); + } +} diff --git a/GameCode/TextFlicker.cs b/GameCode/TextFlicker.cs new file mode 100644 index 0000000..e710a43 --- /dev/null +++ b/GameCode/TextFlicker.cs @@ -0,0 +1,35 @@ +using TMPro; +using UnityEngine; + +public class TextFlicker : MonoBehaviour +{ + public string[] strings; + + public float rate = 0.2f; + + private float counter; + + private int currentID; + + private TextMeshProUGUI text; + + private void Start() + { + text = GetComponent<TextMeshProUGUI>(); + } + + private void Update() + { + counter += Time.deltaTime; + if (counter > rate) + { + counter = 0f; + currentID++; + if (currentID >= strings.Length) + { + currentID = 0; + } + text.text = strings[currentID]; + } + } +} diff --git a/GameCode/ThereCanOnlyBeOne.cs b/GameCode/ThereCanOnlyBeOne.cs new file mode 100644 index 0000000..78dd68d --- /dev/null +++ b/GameCode/ThereCanOnlyBeOne.cs @@ -0,0 +1,30 @@ +using UnityEngine; +using UnityEngine.Events; + +public class ThereCanOnlyBeOne : MonoBehaviour +{ + public UnityEvent PokeEvent; + + private void Start() + { + bool flag = false; + ThereCanOnlyBeOne[] componentsInChildren = base.transform.root.GetComponentsInChildren<ThereCanOnlyBeOne>(); + for (int i = 0; i < componentsInChildren.Length; i++) + { + if (!(componentsInChildren[i] == this)) + { + flag = true; + componentsInChildren[i].Poke(); + } + } + if (flag) + { + Object.Destroy(base.gameObject); + } + } + + public void Poke() + { + PokeEvent.Invoke(); + } +} diff --git a/GameCode/Thruster.cs b/GameCode/Thruster.cs new file mode 100644 index 0000000..0c595d1 --- /dev/null +++ b/GameCode/Thruster.cs @@ -0,0 +1,84 @@ +using UnityEngine; + +public class Thruster : MonoBehaviour +{ + public float force; + + public float drag; + + public float pow = 1f; + + public float physicsObjectM = 1f; + + private FollowLocalPos follow; + + private Rigidbody2D rig; + + private Vector2 startForward; + + private NetworkPhysicsObject pushed; + + private Player player; + + private bool checkedForPlayer; + + private void Start() + { + force *= Mathf.Pow(base.transform.localScale.x, pow); + drag *= Mathf.Pow(base.transform.localScale.x, pow); + follow = GetComponent<FollowLocalPos>(); + if ((bool)follow.target) + { + pushed = follow.target.gameObject.GetComponent<NetworkPhysicsObject>(); + } + float num = 1f; + if (!follow.targetPlayer) + { + num = 0.2f; + } + else if ((bool)pushed) + { + num = 0.5f; + } + ParticleSystem.MainModule main = GetComponentInChildren<ParticleSystem>().main; + main.duration *= num; + GetComponent<DelayEvent>().time *= num; + GetComponent<RemoveAfterSeconds>().seconds *= num; + startForward = base.transform.forward; + } + + private void FixedUpdate() + { + if (!follow) + { + return; + } + if ((bool)follow.target) + { + if ((bool)player) + { + if ((bool)player) + { + player.data.healthHandler.TakeForce(startForward * force, ForceMode2D.Force); + } + else + { + rig.AddForce(startForward * force, ForceMode2D.Force); + } + } + else if (!checkedForPlayer) + { + player = follow.target.transform.root.GetComponent<Player>(); + checkedForPlayer = true; + if (!player && !pushed) + { + base.enabled = false; + } + } + } + if ((bool)pushed && pushed.photonView.IsMine) + { + pushed.RPCA_SendForce(base.transform.forward * force * physicsObjectM, pushed.transform.InverseTransformPoint(base.transform.position)); + } + } +} diff --git a/GameCode/TickMover.cs b/GameCode/TickMover.cs new file mode 100644 index 0000000..841ffc4 --- /dev/null +++ b/GameCode/TickMover.cs @@ -0,0 +1,41 @@ +using Photon.Pun.Simple; +using UnityEngine; + +public class TickMover : MonoBehaviour, IOnPostSimulate +{ + private Vector3 rotationPerTick; + + private TextMesh tickText; + + private void Awake() + { + NetMasterCallbacks.RegisterCallbackInterfaces(this); + rotationPerTick = new Vector3(0f, 0f, 360f * (Time.fixedDeltaTime * (float)TickEngineSettings.sendEveryXTick)); + tickText = GetComponentInChildren<TextMesh>(); + if (!tickText) + { + tickText = GetComponentInParent<TextMesh>(); + } + if ((bool)tickText) + { + tickText.text = ""; + } + } + + private void OnDestroy() + { + NetMasterCallbacks.RegisterCallbackInterfaces(this, register: false, delay: true); + } + + public void OnPostSimulate(int frameId, int subFrameId, bool isNetTick) + { + if (isNetTick) + { + base.transform.eulerAngles -= rotationPerTick; + if ((bool)tickText) + { + tickText.text = frameId.ToString(); + } + } + } +} diff --git a/GameCode/TimeHandler.cs b/GameCode/TimeHandler.cs new file mode 100644 index 0000000..f038df5 --- /dev/null +++ b/GameCode/TimeHandler.cs @@ -0,0 +1,96 @@ +using System.Collections; +using Photon.Pun; +using UnityEngine; + +public class TimeHandler : MonoBehaviour +{ + public AnimationCurve slowDown; + + public AnimationCurve speedUp; + + public float baseTimeScale = 0.85f; + + public float gameOverTime = 1f; + + public float gameStartTime; + + public float timeStop = 1f; + + public static float timeScale = 1f; + + public static TimeHandler instance; + + public static float deltaTime; + + public static float fixedDeltaTime; + + private void Awake() + { + instance = this; + } + + private void Update() + { + float num = baseTimeScale; + if (gameOverTime < 1f) + { + num *= gameOverTime; + } + if (gameStartTime < 1f) + { + num *= gameStartTime; + } + if (timeStop < 1f) + { + num *= timeStop; + } + if (PhotonNetwork.OfflineMode && EscapeMenuHandler.isEscMenu) + { + num *= 0f; + } + timeScale = num; + deltaTime = Time.deltaTime * timeScale; + fixedDeltaTime = Time.fixedDeltaTime * timeScale; + Time.timeScale = 1f; + } + + public void StartGame() + { + gameStartTime = 1f; + } + + public void DoSpeedUp() + { + StartCoroutine(DoCurve(speedUp)); + } + + public void DoSlowDown() + { + StartCoroutine(DoCurve(slowDown)); + } + + private IEnumerator DoCurve(AnimationCurve curve) + { + float c = 0f; + float t = curve.keys[curve.keys.Length - 1].time; + while (c < t) + { + gameOverTime = curve.Evaluate(c); + c += Time.unscaledDeltaTime; + yield return null; + } + gameOverTime = curve.Evaluate(t); + } + + public void HitStop() + { + StartCoroutine(DoHitStop()); + } + + private IEnumerator DoHitStop() + { + timeStop = 0f; + yield return new WaitForSeconds(0.3f); + timeStop = 1f; + } +} diff --git a/GameCode/ToggleStats.cs b/GameCode/ToggleStats.cs new file mode 100644 index 0000000..726a307 --- /dev/null +++ b/GameCode/ToggleStats.cs @@ -0,0 +1,31 @@ +using UnityEngine; + +public class ToggleStats : MonoBehaviour +{ + public float movementSpeedMultiplier = 1f; + + public float hpMultiplier = 1f; + + private CharacterData data; + + private void Start() + { + data = GetComponentInParent<CharacterData>(); + } + + public void TurnOn() + { + data.health *= hpMultiplier; + data.maxHealth *= hpMultiplier; + data.stats.movementSpeed *= movementSpeedMultiplier; + data.stats.ConfigureMassAndSize(); + } + + public void TurnOff() + { + data.health /= hpMultiplier; + data.maxHealth /= hpMultiplier; + data.stats.movementSpeed /= movementSpeedMultiplier; + data.stats.ConfigureMassAndSize(); + } +} diff --git a/GameCode/ToggleUnparented.cs b/GameCode/ToggleUnparented.cs new file mode 100644 index 0000000..bacb60a --- /dev/null +++ b/GameCode/ToggleUnparented.cs @@ -0,0 +1,29 @@ +using UnityEngine; + +public class ToggleUnparented : MonoBehaviour +{ + private Unparent[] unparents; + + private void Awake() + { + unparents = GetComponentsInChildren<Unparent>(); + } + + private void OnDisable() + { + for (int i = 0; i < unparents.Length; i++) + { + unparents[i].gameObject.SetActive(value: false); + } + GetComponent<Holding>().holdable.gameObject.SetActive(value: false); + } + + private void OnEnable() + { + for (int i = 0; i < unparents.Length; i++) + { + unparents[i].gameObject.SetActive(value: true); + } + GetComponent<Holding>().holdable.gameObject.SetActive(value: false); + } +} diff --git a/GameCode/TracerRound.cs b/GameCode/TracerRound.cs new file mode 100644 index 0000000..201a5f7 --- /dev/null +++ b/GameCode/TracerRound.cs @@ -0,0 +1,48 @@ +using UnityEngine; + +public class TracerRound : MonoBehaviour +{ + public GameObject bullet; + + public GameObject bulletSpawnPos; + + private TracerTarget target; + + private MoveTransform move; + + private bool done; + + private void Start() + { + move = GetComponent<MoveTransform>(); + bullet = Object.Instantiate(bullet, bulletSpawnPos.transform.position, bulletSpawnPos.transform.rotation); + bullet.GetComponent<ProjectileHit>().damage *= base.transform.localScale.x; + GetComponentInParent<SpawnedAttack>().CopySpawnedAttackTo(bullet); + target = bullet.GetComponent<TracerTarget>(); + GetComponentInParent<ProjectileHit>().AddHitActionWithData(Hit); + bullet.GetComponentInParent<ProjectileHit>().AddHitActionWithData(Hit); + } + + public void Hit(HitInfo hit) + { + if ((bool)hit.transform.root.GetComponent<Player>()) + { + base.transform.SetParent(null); + base.gameObject.AddComponent<RemoveAfterSeconds>().seconds = 10f; + base.gameObject.AddComponent<FollowTransform>().target = hit.transform; + } + } + + private void Update() + { + if (target != null) + { + target.SetPos(base.transform.position, Vector3.Cross(Vector3.forward, base.transform.forward), move); + } + if (bullet == null && !done) + { + done = true; + GetComponentInChildren<ParticleSystem>().Stop(); + } + } +} diff --git a/GameCode/TracerTarget.cs b/GameCode/TracerTarget.cs new file mode 100644 index 0000000..19b6b67 --- /dev/null +++ b/GameCode/TracerTarget.cs @@ -0,0 +1,65 @@ +using UnityEngine; + +public class TracerTarget : MonoBehaviour +{ + private MoveTransform move; + + public bool hasPos; + + public float drag; + + public float spring; + + public AnimationCurve curve; + + public float cosScale = 1f; + + public float cosAmount; + + private float random; + + private float c; + + private bool done; + + private Vector3 tPos; + + private Vector3 upDir; + + private MoveTransform mTrans; + + private void Start() + { + move = GetComponent<MoveTransform>(); + random = Random.Range(0f, 1000f); + SetPos(base.transform.forward * 100f, base.transform.up, null); + } + + private void Update() + { + float num = 1f; + if ((bool)mTrans) + { + num += mTrans.velocity.magnitude * 0.1f; + } + if ((bool)mTrans && !done) + { + tPos += base.transform.forward + base.transform.forward * 10f; + } + c += TimeHandler.deltaTime; + if (hasPos) + { + move.velocity += cosAmount * Mathf.Cos((Time.time + random) * cosScale) * upDir * CappedDeltaTime.time / num; + move.velocity += (tPos - base.transform.position).normalized * spring * CappedDeltaTime.time * curve.Evaluate(c) * num; + move.velocity -= move.velocity * CappedDeltaTime.time * drag * curve.Evaluate(c); + } + } + + public void SetPos(Vector3 targetPos, Vector3 up, MoveTransform move) + { + mTrans = move; + hasPos = true; + tPos = targetPos; + upDir = up; + } +} diff --git a/GameCode/TrickShot.cs b/GameCode/TrickShot.cs new file mode 100644 index 0000000..cdb0b0e --- /dev/null +++ b/GameCode/TrickShot.cs @@ -0,0 +1,87 @@ +using Sonigon; +using UnityEngine; + +public class TrickShot : MonoBehaviour +{ + [Header("Sound")] + public SoundEvent soundGrowExplosion; + + public SoundEvent soundGrowWail; + + private bool soundGrowExplosionPlayed; + + private bool soundGrowWailPlayed; + + private SoundParameterIntensity soundIntensity = new SoundParameterIntensity(0f); + + [Header("Settings")] + public float muiltiplier = 1f; + + public float removeAt = 30f; + + private ProjectileHit projectileHit; + + private MoveTransform move; + + private ScaleTrailFromDamage trail; + + private float lastDistanceTravelled; + + private void Awake() + { + trail = base.transform.root.GetComponentInChildren<ScaleTrailFromDamage>(); + } + + private void Start() + { + projectileHit = GetComponentInParent<ProjectileHit>(); + move = GetComponentInParent<MoveTransform>(); + if (projectileHit != null) + { + if (soundGrowExplosion != null) + { + projectileHit.AddHitActionWithData(SoundPlayGrowExplosion); + } + if (soundGrowWail != null) + { + soundGrowWailPlayed = true; + SoundManager.Instance.Play(soundGrowWail, projectileHit.ownPlayer.transform); + } + } + } + + public void SoundPlayGrowExplosion(HitInfo hit) + { + if (!soundGrowExplosionPlayed) + { + soundGrowExplosionPlayed = true; + if (soundGrowExplosion != null) + { + SoundManager.Instance.PlayAtPosition(soundGrowExplosion, projectileHit.ownPlayer.transform, hit.point, soundIntensity); + } + if (soundGrowWailPlayed) + { + SoundManager.Instance.Stop(soundGrowWail, projectileHit.ownPlayer.transform); + } + } + } + + private void Update() + { + if (move.distanceTravelled > removeAt) + { + Object.Destroy(this); + return; + } + soundIntensity.intensity = move.distanceTravelled / removeAt; + float num = move.distanceTravelled - lastDistanceTravelled; + lastDistanceTravelled = move.distanceTravelled; + float num2 = 1f + num * TimeHandler.deltaTime * base.transform.localScale.x * muiltiplier; + projectileHit.damage *= num2; + projectileHit.shake *= num2; + if ((bool)trail) + { + trail.Rescale(); + } + } +} diff --git a/GameCode/TwitchAudienceVisualizer.cs b/GameCode/TwitchAudienceVisualizer.cs new file mode 100644 index 0000000..db00690 --- /dev/null +++ b/GameCode/TwitchAudienceVisualizer.cs @@ -0,0 +1,147 @@ +using System.Collections; +using System.Collections.Generic; +using TMPro; +using UnityEngine; +using UnityEngine.UI.ProceduralImage; + +public class TwitchAudienceVisualizer : MonoBehaviour +{ + private const int MAXIMUM_MSG_PER_PLAYER_IN_AUDIENCE = 100; + + private const int MAXIMUM_MSG_PER_SECOND = 10; + + private float m_RecieveRate; + + private float m_LastRecievedTime; + + public float countDownSpeed = 2f; + + public float totalAmountOfTime = 30f; + + [SerializeField] + private GameObject m_TwitchChatObject; + + public ProceduralImage border; + + public TextMeshProUGUI audioenceText; + + private Screenshaker shake; + + private bool m_IsAudition; + + private bool m_IsReadyToSpawnChatObjects; + + private ListMenuPage m_Page; + + public static TwitchAudienceVisualizer instance; + + private Dictionary<string, int> m_MsgsPerTwitchUser = new Dictionary<string, int>(); + + private int currentViewerScore; + + private void Awake() + { + instance = this; + m_RecieveRate = 0.1f; + } + + private void Start() + { + m_Page = GetComponentInParent<ListMenuPage>(); + shake = GetComponentInChildren<Screenshaker>(); + TwitchUIHandler.Instance.AddMsgAction(Chat); + StartAudition(); + } + + public void Chat(string msg, string from) + { + if (!m_IsAudition) + { + return; + } + if (!m_MsgsPerTwitchUser.ContainsKey(from)) + { + m_MsgsPerTwitchUser.Add(from, 0); + } + if (m_MsgsPerTwitchUser[from] >= 100) + { + return; + } + m_MsgsPerTwitchUser[from]++; + if (Time.unscaledTime >= m_LastRecievedTime + m_RecieveRate) + { + m_LastRecievedTime = Time.unscaledTime; + if (m_IsReadyToSpawnChatObjects) + { + SpawnChatObject(msg, from); + } + } + currentViewerScore += 100; + shake.OnUIGameFeel(Random.insideUnitCircle.normalized); + } + + private void SpawnChatObject(string msg, string from) + { + Object.Instantiate(m_TwitchChatObject).GetComponentInChildren<TextMeshProUGUI>().text = msg; + } + + private void StartAudition() + { + m_IsAudition = true; + m_MsgsPerTwitchUser = new Dictionary<string, int>(); + StartCoroutine(DoAudition()); + } + + private void Shake(float m = 1f) + { + shake.OnUIGameFeel(Random.insideUnitCircle.normalized * m); + } + + private IEnumerator DoAudition() + { + border.fillAmount = 0f; + audioenceText.text = ""; + yield return new WaitForSecondsRealtime(1f / countDownSpeed); + Shake(3f); + audioenceText.text = "3"; + yield return new WaitForSecondsRealtime(1f / countDownSpeed); + Shake(3f); + audioenceText.text = "2"; + yield return new WaitForSecondsRealtime(1f / countDownSpeed); + Shake(3f); + audioenceText.text = "1"; + yield return new WaitForSecondsRealtime(1f / countDownSpeed); + Shake(10f); + audioenceText.text = "CHAT"; + yield return new WaitForSecondsRealtime(2f / countDownSpeed); + Shake(10f); + audioenceText.text = "MAKE"; + yield return new WaitForSecondsRealtime(1f / countDownSpeed); + Shake(10f); + audioenceText.text = "SOME"; + yield return new WaitForSecondsRealtime(1f / countDownSpeed); + Shake(10f); + audioenceText.text = "NOISE"; + float t = 0f; + while (t < 1f) + { + t += Time.unscaledDeltaTime; + Shake(3f - t); + yield return null; + } + yield return new WaitForSecondsRealtime(0.5f / countDownSpeed); + m_IsReadyToSpawnChatObjects = true; + float c = totalAmountOfTime; + while (c > 0f) + { + border.fillAmount = c / totalAmountOfTime; + c -= Time.unscaledDeltaTime; + audioenceText.text = currentViewerScore + "\n<size=50>AUDIENCE RATING</size>"; + yield return null; + } + m_IsAudition = false; + m_IsReadyToSpawnChatObjects = false; + m_Page.Close(); + NetworkConnectionHandler.instance.TwitchJoin(currentViewerScore); + } +} diff --git a/GameCode/TwitchChatMessage.cs b/GameCode/TwitchChatMessage.cs new file mode 100644 index 0000000..e82fb14 --- /dev/null +++ b/GameCode/TwitchChatMessage.cs @@ -0,0 +1,11 @@ +using UnityEngine; + +public class TwitchChatMessage : MonoBehaviour +{ + private void Start() + { + base.transform.SetParent(TwitchAudienceVisualizer.instance.transform); + base.transform.localScale = Vector3.one; + GetComponent<RectTransform>().anchoredPosition = new Vector2(Random.Range(-850, 850), Random.Range(-475, 475)); + } +} diff --git a/GameCode/TwitchIrc.cs b/GameCode/TwitchIrc.cs new file mode 100644 index 0000000..8c062c0 --- /dev/null +++ b/GameCode/TwitchIrc.cs @@ -0,0 +1,217 @@ +using System; +using System.Collections; +using System.IO; +using System.Net.Sockets; +using System.Text.RegularExpressions; +using Irc; +using UnityEngine; + +public class TwitchIrc : MonoBehaviour +{ + public UserJoined OnUserJoined; + + public UserLeft OnUserLeft; + + public ChannelMessage OnChannelMessage; + + public ServerMessage OnServerMessage; + + public Connected OnConnected; + + public ExceptionThrown OnExceptionThrown; + + private const string ServerName = "irc.twitch.tv"; + + private const int ServerPort = 6667; + + public static TwitchIrc Instance; + + public bool ConnectOnAwake; + + public string Username; + + public string OauthToken; + + public string Channel; + + private TcpClient irc; + + private NetworkStream stream; + + private string inputLine; + + private StreamReader reader; + + private StreamWriter writer; + + public void Connect() + { + if (string.IsNullOrEmpty(Username) || string.IsNullOrEmpty(OauthToken)) + { + return; + } + try + { + irc = new TcpClient("irc.twitch.tv", 6667); + stream = irc.GetStream(); + reader = new StreamReader(stream); + writer = new StreamWriter(stream); + Send("USER " + Username + "tmi twitch :" + Username); + Send("PASS " + OauthToken); + Send("NICK " + Username); + StartCoroutine("Listen"); + } + catch (Exception exeption) + { + if (OnExceptionThrown != null) + { + OnExceptionThrown(exeption); + } + } + } + + public void Disconnect() + { + irc = null; + StopCoroutine("Listen"); + if (stream != null) + { + stream.Dispose(); + } + if (writer != null) + { + writer.Dispose(); + } + if (reader != null) + { + reader.Dispose(); + } + } + + public void JoinChannel() + { + if (!string.IsNullOrEmpty(Channel)) + { + if (Channel[0] != '#') + { + Channel = "#" + Channel; + } + if (irc != null && irc.Connected) + { + Send("JOIN " + Channel); + } + } + } + + public void LeaveChannel() + { + Send("PART " + Channel); + } + + public void Message(string message) + { + Send("PRIVMSG " + Channel + " :" + message); + } + + private IEnumerator Listen() + { + while (true) + { + if (stream.DataAvailable && (inputLine = reader.ReadLine()) != null) + { + ParseData(inputLine); + } + yield return null; + } + } + + private void ParseData(string data) + { + string[] array = data.Split(' '); + if (data.Length > 4 && data.Substring(0, 4) == "PING") + { + Send("PONG " + array[1]); + return; + } + switch (array[1]) + { + case "001": + Send("MODE " + Username + " +B"); + OnConnected(); + break; + case "JOIN": + if (Instance.OnUserJoined != null) + { + Instance.OnUserJoined(new UserJoinedEventArgs(array[2], array[0].Substring(1, array[0].IndexOf("!") - 1))); + } + break; + case "PRIVMSG": + if (array[2].ToLower() != Username.ToLower() && OnChannelMessage != null) + { + OnChannelMessage(new ChannelMessageEventArgs(array[2], array[0].Substring(1, array[0].IndexOf('!') - 1), JoinArray(array, 3))); + } + break; + case "PART": + case "QUIT": + if (OnUserLeft != null) + { + OnUserLeft(new UserLeftEventArgs(array[2], array[0].Substring(1, data.IndexOf("!") - 1))); + } + break; + default: + if (array.Length > 3 && OnServerMessage != null) + { + OnServerMessage(JoinArray(array, 3)); + } + break; + } + } + + private string StripMessage(string message) + { + foreach (Match item in new Regex("\u0003(?:\\d{1,2}(?:,\\d{1,2})?)?").Matches(message)) + { + message = message.Replace(item.Value, ""); + } + if (message == "") + { + return ""; + } + if (message.Substring(0, 1) == ":" && message.Length > 2) + { + return message.Substring(1, message.Length - 1); + } + return message; + } + + private string JoinArray(string[] strArray, int startIndex) + { + return StripMessage(string.Join(" ", strArray, startIndex, strArray.Length - startIndex)); + } + + private void Send(string message) + { + writer.WriteLine(message); + writer.Flush(); + } + + private void OnConnectedToServer() + { + JoinChannel(); + } + + private void Awake() + { + Instance = this; + OnConnected = (Connected)Delegate.Combine(OnConnected, new Connected(OnConnectedToServer)); + if (ConnectOnAwake) + { + Connect(); + } + } + + private void OnDisable() + { + Disconnect(); + } +} diff --git a/GameCode/TwitchIrcExample.cs b/GameCode/TwitchIrcExample.cs new file mode 100644 index 0000000..dc08227 --- /dev/null +++ b/GameCode/TwitchIrcExample.cs @@ -0,0 +1,88 @@ +using System; +using Irc; +using UnityEngine; +using UnityEngine.UI; + +public class TwitchIrcExample : MonoBehaviour +{ + public InputField UsernameText; + + public InputField TokenText; + + public InputField ChannelText; + + public Text ChatText; + + public InputField MessageText; + + private void Start() + { + TwitchIrc instance = TwitchIrc.Instance; + instance.OnChannelMessage = (ChannelMessage)Delegate.Combine(instance.OnChannelMessage, new ChannelMessage(OnChannelMessage)); + TwitchIrc instance2 = TwitchIrc.Instance; + instance2.OnUserLeft = (UserLeft)Delegate.Combine(instance2.OnUserLeft, new UserLeft(OnUserLeft)); + TwitchIrc instance3 = TwitchIrc.Instance; + instance3.OnUserJoined = (UserJoined)Delegate.Combine(instance3.OnUserJoined, new UserJoined(OnUserJoined)); + TwitchIrc instance4 = TwitchIrc.Instance; + instance4.OnServerMessage = (ServerMessage)Delegate.Combine(instance4.OnServerMessage, new ServerMessage(OnServerMessage)); + TwitchIrc instance5 = TwitchIrc.Instance; + instance5.OnExceptionThrown = (ExceptionThrown)Delegate.Combine(instance5.OnExceptionThrown, new ExceptionThrown(OnExceptionThrown)); + } + + public void Connect() + { + TwitchIrc.Instance.Username = UsernameText.text; + TwitchIrc.Instance.OauthToken = TokenText.text; + TwitchIrc.Instance.Channel = ChannelText.text; + TwitchIrc.Instance.Connect(); + } + + public void MessageSend() + { + if (!string.IsNullOrEmpty(MessageText.text)) + { + TwitchIrc.Instance.Message(MessageText.text); + Text chatText = ChatText; + chatText.text = chatText.text + "<b>" + TwitchIrc.Instance.Username + "</b>: " + MessageText.text + "\n"; + MessageText.text = ""; + } + } + + public void GoUrl(string url) + { + Application.OpenURL(url); + } + + private void OnServerMessage(string message) + { + Text chatText = ChatText; + chatText.text = chatText.text + "<b>SERVER:</b> " + message + "\n"; + Debug.Log(message); + } + + private void OnChannelMessage(ChannelMessageEventArgs channelMessageArgs) + { + Text chatText = ChatText; + chatText.text = chatText.text + "<b>" + channelMessageArgs.From + ":</b> " + channelMessageArgs.Message + "\n"; + Debug.Log("MESSAGE: " + channelMessageArgs.From + ": " + channelMessageArgs.Message); + } + + private void OnUserJoined(UserJoinedEventArgs userJoinedArgs) + { + Text chatText = ChatText; + chatText.text = chatText.text + "<b>USER JOINED:</b> " + userJoinedArgs.User + "\n"; + Debug.Log("USER JOINED: " + userJoinedArgs.User); + } + + private void OnUserLeft(UserLeftEventArgs userLeftArgs) + { + Text chatText = ChatText; + chatText.text = chatText.text + "<b>USER JOINED:</b> " + userLeftArgs.User + "\n"; + Debug.Log("USER JOINED: " + userLeftArgs.User); + } + + private void OnExceptionThrown(Exception exeption) + { + Debug.Log(exeption); + } +} diff --git a/GameCode/TwitchUIHandler.cs b/GameCode/TwitchUIHandler.cs new file mode 100644 index 0000000..c69fc7a --- /dev/null +++ b/GameCode/TwitchUIHandler.cs @@ -0,0 +1,154 @@ +using System; +using Irc; +using Steamworks; +using TMPro; +using UnityEngine; +using UnityEngine.UI; + +public class TwitchUIHandler : MonoBehaviour +{ + private const string TWITCH_OAUTH_PLAYERPREF_KEY = "TwitchOauth"; + + private const string TWITCH_NAME_PLAYERPREF_KEY = "TwitchName"; + + [SerializeField] + private TMP_InputField m_UserNameText; + + [SerializeField] + private TMP_InputField m_OauthText; + + [SerializeField] + private Button m_GetOAuthButton; + + [SerializeField] + private ListMenuPage m_TwitchBar; + + private Action<string, string> m_OnMsgAction; + + private bool m_Connected; + + public static string OAUTH_KEY + { + get + { + return PlayerPrefs.GetString("TwitchOauth" + SteamUser.GetSteamID().ToString(), string.Empty); + } + private set + { + PlayerPrefs.SetString("TwitchOauth" + SteamUser.GetSteamID().ToString(), value); + } + } + + public static string TWITCH_NAME_KEY + { + get + { + return PlayerPrefs.GetString("TwitchName" + SteamUser.GetSteamID().ToString(), string.Empty); + } + private set + { + PlayerPrefs.SetString("TwitchName" + SteamUser.GetSteamID().ToString(), value); + } + } + + public static TwitchUIHandler Instance { get; private set; } + + private void Awake() + { + Instance = this; + InitListeners(); + } + + private void Start() + { + TwitchIrc instance = TwitchIrc.Instance; + instance.OnChannelMessage = (ChannelMessage)Delegate.Combine(instance.OnChannelMessage, new ChannelMessage(OnChannelMessage)); + TwitchIrc instance2 = TwitchIrc.Instance; + instance2.OnUserLeft = (UserLeft)Delegate.Combine(instance2.OnUserLeft, new UserLeft(OnUserLeft)); + TwitchIrc instance3 = TwitchIrc.Instance; + instance3.OnUserJoined = (UserJoined)Delegate.Combine(instance3.OnUserJoined, new UserJoined(OnUserJoined)); + TwitchIrc instance4 = TwitchIrc.Instance; + instance4.OnServerMessage = (ServerMessage)Delegate.Combine(instance4.OnServerMessage, new ServerMessage(OnServerMessage)); + TwitchIrc instance5 = TwitchIrc.Instance; + instance5.OnExceptionThrown = (ExceptionThrown)Delegate.Combine(instance5.OnExceptionThrown, new ExceptionThrown(OnExceptionThrown)); + if (!string.IsNullOrEmpty(OAUTH_KEY)) + { + m_OauthText.text = OAUTH_KEY; + } + if (!string.IsNullOrEmpty(TWITCH_NAME_KEY)) + { + m_UserNameText.text = TWITCH_NAME_KEY; + } + } + + private void InitListeners() + { + m_GetOAuthButton.onClick.AddListener(GetOauth); + } + + public void AddMsgAction(Action<string, string> a) + { + m_OnMsgAction = (Action<string, string>)Delegate.Combine(m_OnMsgAction, a); + } + + public void OnContinueClick() + { + OAUTH_KEY = m_OauthText.text; + TWITCH_NAME_KEY = m_UserNameText.text.ToLower(); + TwitchIrc.Instance.Username = TWITCH_NAME_KEY; + TwitchIrc.Instance.OauthToken = OAUTH_KEY; + TwitchIrc.Instance.Channel = TWITCH_NAME_KEY; + TwitchIrc.Instance.Connect(); + } + + private void GetOauth() + { + Application.OpenURL("http://twitchapps.com/tmi/"); + } + + public void MessageSend() + { + } + + public void GoUrl(string url) + { + Application.OpenURL(url); + } + + private void OnServerMessage(string message) + { + Debug.Log(message); + } + + private void OnChannelMessage(ChannelMessageEventArgs channelMessageArgs) + { + m_OnMsgAction?.Invoke(channelMessageArgs.Message, channelMessageArgs.From); + } + + private void OnUserJoined(UserJoinedEventArgs userJoinedArgs) + { + if (userJoinedArgs.User.ToUpper() == TwitchIrc.Instance.Username.ToUpper()) + { + Debug.Log("LOCAL USER JOINED!"); + ConnectedToTwitch(); + } + } + + private void ConnectedToTwitch() + { + if (!m_Connected) + { + m_Connected = true; + m_TwitchBar.Open(); + } + } + + private void OnUserLeft(UserLeftEventArgs userLeftArgs) + { + } + + private void OnExceptionThrown(Exception exeption) + { + Debug.Log(exeption); + } +} diff --git a/GameCode/UIHandler.cs b/GameCode/UIHandler.cs new file mode 100644 index 0000000..72d0b63 --- /dev/null +++ b/GameCode/UIHandler.cs @@ -0,0 +1,177 @@ +using System; +using System.Collections; +using Sonigon; +using TMPro; +using UnityEngine; + +public class UIHandler : MonoBehaviour +{ + [Header("Sounds")] + public SoundEvent soundTextAppear; + + public SoundEvent soundTextDisappear; + + public static UIHandler instance; + + [Header("Settings")] + public TextMeshProUGUI gameOverText; + + public GeneralParticleSystem gameOverTextPart; + + public GeneralParticleSystem roundBackgroundPart; + + public GeneralParticleSystem roundTextPart; + + public CodeAnimation roundCounterAnim; + + public RoundCounter roundCounter; + + public RoundCounter roundCounterSmall; + + public CodeAnimation roundCounterAnimSmall; + + public GameObject pickerObject; + + public GeneralParticleSystem pickerPart; + + public GeneralParticleSystem joinGamePart; + + public TextMeshProUGUI jointGameText; + + public PopUpHandler popUpHandler; + + private void Awake() + { + instance = this; + popUpHandler = base.transform.root.GetComponentInChildren<PopUpHandler>(); + } + + public void ShowJoinGameText(string text, Color color) + { + SoundManager.Instance.Play(soundTextAppear, base.transform); + if (text != "") + { + jointGameText.text = text; + } + if (color != Color.black) + { + joinGamePart.particleSettings.color = color; + } + joinGamePart.loop = true; + joinGamePart.Play(); + } + + internal void SetNumberOfRounds(int roundsToWinGame) + { + roundCounter.SetNumberOfRounds(roundsToWinGame); + roundCounterSmall.SetNumberOfRounds(roundsToWinGame); + } + + public void HideJoinGameText() + { + SoundManager.Instance.Play(soundTextDisappear, base.transform); + joinGamePart.Stop(); + } + + public void DisplayScreenText(Color color, string text, float speed) + { + gameOverTextPart.particleSettings.color = color; + gameOverTextPart.duration = 60f / speed; + gameOverTextPart.Play(); + gameOverText.text = text; + } + + public void DisplayScreenTextLoop(string text) + { + gameOverTextPart.duration = 60f; + gameOverTextPart.loop = true; + gameOverTextPart.Play(); + gameOverText.text = text; + } + + public void DisplayScreenTextLoop(Color color, string text) + { + gameOverTextPart.particleSettings.color = color; + gameOverTextPart.duration = 60f; + gameOverTextPart.loop = true; + gameOverTextPart.Play(); + gameOverText.text = text; + } + + public void StopScreenTextLoop() + { + gameOverTextPart.loop = false; + } + + public void ShowAddPoint(Color color, string winTextBefore, string text, float speed) + { + gameOverTextPart.particleSettings.color = color; + gameOverTextPart.duration = 60f / speed; + gameOverTextPart.Play(); + StartCoroutine(DoShowAddPoint(winTextBefore, text)); + } + + private IEnumerator DoShowAddPoint(string winTextBefore, string text) + { + gameOverText.text = winTextBefore; + yield return new WaitForSecondsRealtime(0.7f); + gameOverText.text = text; + } + + public void ShowRoundOver(int p1Rounds, int p2Rounds) + { + roundCounter.gameObject.SetActive(value: true); + roundBackgroundPart.Play(); + roundTextPart.Play(); + roundCounterAnim.PlayIn(); + roundCounter.UpdateRounds(p1Rounds, p2Rounds); + } + + public void ShowRoundCounterSmall(int p1Rounds, int p2Rounds, int p1Points, int p2Points) + { + roundCounterSmall.gameObject.SetActive(value: true); + roundCounterSmall.UpdateRounds(p1Rounds, p2Rounds); + roundCounterSmall.UpdatePoints(p1Points, p2Points); + if (roundCounterAnimSmall.currentState != 0) + { + roundCounterAnimSmall.PlayIn(); + } + } + + public void HideRoundCounterSmall() + { + roundCounterAnimSmall.PlayOut(); + } + + public void ShowPicker(int pickerID, PickerType pickerType = PickerType.Team) + { + pickerObject.SetActive(value: true); + if (pickerType == PickerType.Team) + { + pickerPart.particleSettings.color = PlayerManager.instance.GetColorFromTeam(pickerID).winText; + } + if (pickerType == PickerType.Player) + { + pickerPart.particleSettings.color = PlayerManager.instance.GetColorFromPlayer(pickerID).winText; + } + pickerPart.loop = true; + pickerPart.Play(); + } + + public void StopShowPicker() + { + StartCoroutine(DoStopShowPicker()); + } + + private IEnumerator DoStopShowPicker() + { + pickerPart.loop = false; + yield return new WaitForSeconds(0.3f); + pickerObject.SetActive(value: false); + } + + internal void DisplayYesNoLoop(Player pickingPlayer, Action<PopUpHandler.YesNo> functionToCall) + { + popUpHandler.StartPicking(pickingPlayer, functionToCall); + } +} diff --git a/GameCode/UniformModifier.cs b/GameCode/UniformModifier.cs new file mode 100644 index 0000000..9278ed7 --- /dev/null +++ b/GameCode/UniformModifier.cs @@ -0,0 +1,28 @@ +using UnityEngine; +using UnityEngine.UI.ProceduralImage; + +[ModifierID("Uniform")] +public class UniformModifier : ProceduralImageModifier +{ + [SerializeField] + private float radius; + + public float Radius + { + get + { + return radius; + } + set + { + radius = value; + base._Graphic.SetVerticesDirty(); + } + } + + public override Vector4 CalculateRadius(Rect imageRect) + { + float num = radius; + return new Vector4(num, num, num, num); + } +} diff --git a/GameCode/Unparent.cs b/GameCode/Unparent.cs new file mode 100644 index 0000000..cc69c83 --- /dev/null +++ b/GameCode/Unparent.cs @@ -0,0 +1,44 @@ +using System.Collections; +using UnityEngine; + +public class Unparent : MonoBehaviour +{ + public Transform parent; + + public bool follow; + + public float destroyDelay; + + private bool done; + + private void Start() + { + parent = base.transform.root; + } + + private void LateUpdate() + { + if (!done) + { + if (base.transform.root != null) + { + base.transform.SetParent(null, worldPositionStays: true); + } + if (follow && (bool)parent) + { + base.transform.position = parent.transform.position; + } + if (!parent) + { + StartCoroutine(DelayRemove()); + done = true; + } + } + } + + private IEnumerator DelayRemove() + { + yield return new WaitForSeconds(destroyDelay); + Object.Destroy(base.gameObject); + } +} diff --git a/GameCode/UnparentObject.cs b/GameCode/UnparentObject.cs new file mode 100644 index 0000000..258fafa --- /dev/null +++ b/GameCode/UnparentObject.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +public class UnparentObject : MonoBehaviour +{ + public void Unparent() + { + base.transform.SetParent(base.transform.root); + } +} diff --git a/GameCode/UnparentOnHit.cs b/GameCode/UnparentOnHit.cs new file mode 100644 index 0000000..50266c7 --- /dev/null +++ b/GameCode/UnparentOnHit.cs @@ -0,0 +1,38 @@ +using System.Collections; +using UnityEngine; +using UnityEngine.Events; + +public class UnparentOnHit : MonoBehaviour +{ + public float destroyAfterSeconds = 2f; + + public UnityEvent unparentEvent; + + private bool done; + + private void Start() + { + ProjectileHit componentInParent = GetComponentInParent<ProjectileHit>(); + if ((bool)componentInParent) + { + componentInParent.AddHitAction(Unparent); + } + } + + public void Unparent() + { + if (!done) + { + done = true; + base.transform.SetParent(null, worldPositionStays: true); + StartCoroutine(DelayDestroy()); + unparentEvent.Invoke(); + } + } + + private IEnumerator DelayDestroy() + { + yield return new WaitForSeconds(destroyAfterSeconds); + Object.Destroy(base.gameObject); + } +} diff --git a/GameCode/UserJoined.cs b/GameCode/UserJoined.cs new file mode 100644 index 0000000..8c1335f --- /dev/null +++ b/GameCode/UserJoined.cs @@ -0,0 +1,3 @@ +using Irc; + +public delegate void UserJoined(UserJoinedEventArgs userJoinedArgs); diff --git a/GameCode/UserLeft.cs b/GameCode/UserLeft.cs new file mode 100644 index 0000000..4527020 --- /dev/null +++ b/GameCode/UserLeft.cs @@ -0,0 +1,3 @@ +using Irc; + +public delegate void UserLeft(UserLeftEventArgs userLeftArgs); diff --git a/GameCode/VelocityStretch.cs b/GameCode/VelocityStretch.cs new file mode 100644 index 0000000..2875de5 --- /dev/null +++ b/GameCode/VelocityStretch.cs @@ -0,0 +1,18 @@ +using UnityEngine; + +public class VelocityStretch : MonoBehaviour +{ + private Rigidbody2D rig; + + public float amount = 1f; + + private void Start() + { + rig = GetComponentInParent<Rigidbody2D>(); + } + + private void Update() + { + base.transform.localScale = Vector3.one + new Vector3(Mathf.Abs(rig.velocity.x), Mathf.Abs(rig.velocity.y), 0f) * amount; + } +} diff --git a/GameCode/WallRayCaster.cs b/GameCode/WallRayCaster.cs new file mode 100644 index 0000000..b7d5c52 --- /dev/null +++ b/GameCode/WallRayCaster.cs @@ -0,0 +1,34 @@ +using UnityEngine; + +public class WallRayCaster : MonoBehaviour +{ + public float rayLength = 0.7f; + + public LayerMask mask; + + private GeneralInput input; + + private CharacterData data; + + private Rigidbody2D rig; + + private void Start() + { + input = GetComponent<GeneralInput>(); + data = GetComponent<CharacterData>(); + rig = GetComponent<Rigidbody2D>(); + } + + private void Update() + { + } + + public void RayCast(Vector3 dir, float offset = 0f) + { + RaycastHit2D raycastHit2D = Physics2D.Raycast(base.transform.position + base.transform.up * offset, dir, rayLength * base.transform.localScale.x, mask); + if ((bool)raycastHit2D.transform && !raycastHit2D.collider.GetComponent<DamageBox>() && Vector3.Angle(raycastHit2D.normal, Vector3.up) > 70f && Vector3.Angle(raycastHit2D.normal, Vector3.up) < 110f) + { + data.TouchWall(raycastHit2D.normal, raycastHit2D.point); + } + } +} diff --git a/GameCode/WasDealtDamageEffect.cs b/GameCode/WasDealtDamageEffect.cs new file mode 100644 index 0000000..58d0ea4 --- /dev/null +++ b/GameCode/WasDealtDamageEffect.cs @@ -0,0 +1,6 @@ +using UnityEngine; + +public abstract class WasDealtDamageEffect : MonoBehaviour +{ + public abstract void WasDealtDamage(Vector2 damage, bool selfDamage); +} diff --git a/GameCode/WasDealtDamageTrigger.cs b/GameCode/WasDealtDamageTrigger.cs new file mode 100644 index 0000000..a8fdcd4 --- /dev/null +++ b/GameCode/WasDealtDamageTrigger.cs @@ -0,0 +1,35 @@ +using UnityEngine; +using UnityEngine.Events; + +public class WasDealtDamageTrigger : WasDealtDamageEffect +{ + public float damageNeeded = 25f; + + public float cd = 0.2f; + + public bool allowSelfDamage; + + private float time; + + private float damageDealt; + + public UnityEvent triggerEvent; + + private void Start() + { + } + + public override void WasDealtDamage(Vector2 damage, bool selfDamage) + { + if (!selfDamage || allowSelfDamage) + { + damageDealt += damage.magnitude; + if (damageDealt > damageNeeded && Time.time > time + cd) + { + time = Time.time; + damageDealt = 0f; + triggerEvent.Invoke(); + } + } + } +} diff --git a/GameCode/Weapon.cs b/GameCode/Weapon.cs new file mode 100644 index 0000000..d7b81f2 --- /dev/null +++ b/GameCode/Weapon.cs @@ -0,0 +1,20 @@ +using UnityEngine; + +public abstract class Weapon : MonoBehaviour +{ + public Holdable holdable; + + [HideInInspector] + public float sinceAttack = 10f; + + private void Start() + { + holdable = GetComponent<Holdable>(); + } + + private void Update() + { + } + + public abstract bool Attack(float charge, bool forceAttack = false, float damageM = 1f, float recoilMultiplier = 1f, bool useAmmo = true); +} diff --git a/GameCode/WeaponHandler.cs b/GameCode/WeaponHandler.cs new file mode 100644 index 0000000..35be82f --- /dev/null +++ b/GameCode/WeaponHandler.cs @@ -0,0 +1,173 @@ +using System.Collections; +using Sonigon; +using UnityEngine; + +public class WeaponHandler : MonoBehaviour +{ + [Header("Sounds")] + public SoundEvent soundCharacterCantShoot; + + private bool soundFireHold; + + [Header("Settings")] + public Gun gun; + + private Holding holding; + + private GeneralInput input; + + private CharacterData data; + + private float heatSinceAttack; + + private float heat; + + public float heatPerBullet = 0.1f; + + public float secondsBeforeStartToCool = 0.1f; + + public float coolPerSecond = 0.2f; + + public float overHeatTime = 1f; + + public float resetSpeed = 2f; + + public bool isOverHeated; + + private bool hasBeenHeated; + + public SpriteRenderer heatRenderer; + + private Transform overHeatPivot; + + public Color overHeatColor; + + private Color baseHeatColor; + + internal void DoReload() + { + gun.GetComponentInChildren<GunAmmo>().ReloadAmmo(); + } + + private void Awake() + { + holding = GetComponent<Holding>(); + input = GetComponent<GeneralInput>(); + data = GetComponent<CharacterData>(); + } + + private void Start() + { + overHeatPivot = heatRenderer.transform.parent; + baseHeatColor = heatRenderer.color; + } + + private void Update() + { + if (!gun.holdable.holder && (bool)data) + { + gun.holdable.holder = data; + } + if (data.playerVel.simulated) + { + gun.attackSpeedMultiplier = data.stats.attackSpeedMultiplier; + heatSinceAttack += TimeHandler.deltaTime; + Attack(); + OverHeat(); + } + } + + private void Attack() + { + if (!gun || !gun.IsReady()) + { + return; + } + if (input.shootIsPressed) + { + if (!soundFireHold) + { + soundFireHold = true; + if (gun.isReloading || data.isSilenced) + { + SoundManager.Instance.Play(soundCharacterCantShoot, base.transform); + } + } + } + else + { + soundFireHold = false; + } + if (gun.bursts == 0 && (!soundFireHold || gun.isReloading || data.isSilenced)) + { + gun.soundGun.StopAutoPlayTail(); + } + if ((!input.shootWasPressed || gun.useCharge) && (!input.shootWasReleased || !gun.useCharge) && (!(gun.attackSpeed / data.stats.attackSpeedMultiplier < 0.3f) || !input.shootIsPressed || gun.useCharge || gun.dontAllowAutoFire)) + { + return; + } + if (isOverHeated) + { + heatRenderer.GetComponent<CodeAnimation>().PlayBoop(); + gun.sinceAttack = 0f; + return; + } + gun.Attack(0f); + if (heat >= 1f) + { + StartCoroutine(DoOverHeat()); + isOverHeated = true; + } + heatSinceAttack = 0f; + } + + internal void NewGun() + { + gun.ResetStats(); + gun.soundGun.ClearSoundModifiers(); + } + + private void OverHeat() + { + if (!isOverHeated) + { + if (heatSinceAttack > secondsBeforeStartToCool) + { + heat -= TimeHandler.deltaTime * coolPerSecond; + } + SetOverHeatColor(); + } + } + + private IEnumerator DoOverHeat() + { + SetOverHeatColor(); + yield return new WaitForSeconds(overHeatTime); + while (heat > 0f) + { + heat -= resetSpeed * TimeHandler.deltaTime; + SetOverHeatColor(); + yield return null; + } + isOverHeated = false; + } + + private void SetOverHeatColor() + { + heat = Mathf.Clamp(heat, 0f, 1f); + heatRenderer.color = Color.Lerp(baseHeatColor, overHeatColor, heat); + if (heat > 0.25f || hasBeenHeated) + { + hasBeenHeated = true; + overHeatPivot.transform.localScale = new Vector3(heat, 1f, 1f); + } + else + { + overHeatPivot.transform.localScale = new Vector3(0f, 1f, 1f); + } + if (heat == 0f) + { + hasBeenHeated = false; + } + } +} diff --git a/GameCode/ZapEffect.cs b/GameCode/ZapEffect.cs new file mode 100644 index 0000000..9215e60 --- /dev/null +++ b/GameCode/ZapEffect.cs @@ -0,0 +1,20 @@ +using UnityEngine; + +public class ZapEffect : MonoBehaviour +{ + public float damage; + + public float range = 1f; + + private void Start() + { + damage *= base.transform.localScale.x; + range *= (1f + base.transform.localScale.x) * 0.5f; + Player closestPlayer = PlayerManager.instance.GetClosestPlayer(base.transform.position, needVision: true); + if ((bool)closestPlayer && Vector3.Distance(base.transform.position, closestPlayer.transform.position) < range) + { + closestPlayer.data.healthHandler.TakeDamage(damage * (closestPlayer.transform.position - base.transform.position).normalized, base.transform.position, null, PlayerManager.instance.GetOtherPlayer(closestPlayer)); + GetComponentInChildren<LineEffect>(includeInactive: true).Play(base.transform, closestPlayer.transform, 2f); + } + } +} diff --git a/GameCode/Zip.cs b/GameCode/Zip.cs new file mode 100644 index 0000000..1f2c02c --- /dev/null +++ b/GameCode/Zip.cs @@ -0,0 +1,27 @@ +using UnityEngine; + +public class Zip : MonoBehaviour +{ + public float multiplier = 1f; + + public float turn = 0.2f; + + private float count; + + private int up = 1; + + private void Start() + { + } + + private void Update() + { + count += TimeHandler.deltaTime; + if (count > turn) + { + count = 0f; + up *= -1; + } + base.transform.root.position += base.transform.up * multiplier * up * Time.smoothDeltaTime; + } +} diff --git a/GameCode/Zop.cs b/GameCode/Zop.cs new file mode 100644 index 0000000..b167832 --- /dev/null +++ b/GameCode/Zop.cs @@ -0,0 +1,52 @@ +using UnityEngine; + +public class Zop : MonoBehaviour +{ + public float turn = 0.2f; + + private float count; + + private int sinceSwitch = 1; + + private bool up; + + private MoveTransform move; + + public bool randomZop; + + private void Start() + { + move = GetComponentInParent<MoveTransform>(); + if (base.transform.forward.x < 0f) + { + up = true; + } + } + + private void Update() + { + count += TimeHandler.deltaTime; + if (!(count > turn)) + { + return; + } + if (up) + { + move.velocity = move.velocity.magnitude * Vector3.Cross(base.transform.forward, Vector3.forward); + } + else + { + move.velocity = move.velocity.magnitude * -Vector3.Cross(base.transform.forward, Vector3.forward); + } + count = 0f; + if (!randomZop || !(Random.value > 0.8f)) + { + sinceSwitch++; + if (sinceSwitch == 2) + { + up = !up; + sinceSwitch = 0; + } + } + } +} |