private void DrawBigCursor(float rotation) { Vector2 bigOrigin = new Vector2((float)BigCursor.SourceRect.Value.Width, (float)BigCursor.SourceRect.Value.Height); //origins are offset instead of position so each piece rotates from the center of the overall big circle they create //May need adjusting SpriteRenderer.Instance.Draw(BigCursor.Tex, BigCursorPos, BigCursor.SourceRect, Color.White, rotation, bigOrigin, 1f, false, false, .2f, true); SpriteRenderer.Instance.Draw(BigCursor.Tex, BigCursorPos, BigCursor.SourceRect, Color.White, rotation, new Vector2(-bigOrigin.X, bigOrigin.Y), 1f, true, false, .2f, true); SpriteRenderer.Instance.Draw(BigCursor.Tex, BigCursorPos, BigCursor.SourceRect, Color.White, rotation, new Vector2(bigOrigin.X, 0), 1f, false, true, .2f, true); SpriteRenderer.Instance.Draw(BigCursor.Tex, BigCursorPos, BigCursor.SourceRect, Color.White, rotation, -bigOrigin, 1f, true, true, .2f, true); //Draw the middle cursor indicating the small cursor is near //It gets smaller the closer the small cursor is to the center if (WithinRange == true) { //Cap the scale so it can be seen clearly at all times const float maxScale = .8f; //Get the absolute value of the distance from the cursor to the center //Divide by half the SuccessRect's width since we're scaling based on how close it is to the center float diff = Math.Abs(SmallCursorPos.X - SuccessRect.Center.X) / (SuccessRect.Width / 2f); float scale = UtilityGlobals.Clamp(diff, 0f, maxScale); //Draw the middle cursor SpriteRenderer.Instance.Draw(BigCursor.Tex, BigCursorPos, BigCursor.SourceRect, Color.White, rotation, bigOrigin, scale, false, false, .2f, true); SpriteRenderer.Instance.Draw(BigCursor.Tex, BigCursorPos, BigCursor.SourceRect, Color.White, rotation, new Vector2(-bigOrigin.X, bigOrigin.Y), scale, true, false, .2f, true); SpriteRenderer.Instance.Draw(BigCursor.Tex, BigCursorPos, BigCursor.SourceRect, Color.White, rotation, new Vector2(bigOrigin.X, 0), scale, false, true, .2f, true); SpriteRenderer.Instance.Draw(BigCursor.Tex, BigCursorPos, BigCursor.SourceRect, Color.White, rotation, -bigOrigin, scale, true, true, .2f, true); } }
protected override void SequenceMissBranch() { switch (SequenceStep) { case 0: User.AnimManager.PlayAnimation(AnimationGlobals.RunningName); //When Watt misses Electro Dash, she goes in a downwards arc to around where the next enemy slot would be Vector2 destPos = BattleManager.Instance.GetPositionInFront(EntitiesAffected[0], EntitiesAffected[0].EntityType == Enumerations.EntityTypes.Player); Vector2 curDest = User.Position + new Vector2(UtilityGlobals.DifferenceDivided(destPos.X, User.Position.X, 2f), MissHeight); CurSequenceAction = new MoveToSeqAction(curDest, MissMoveDur, Interpolation.InterpolationTypes.Linear, Interpolation.InterpolationTypes.QuadOut); break; case 1: destPos = BattleManager.Instance.GetPositionInFront(EntitiesAffected[0], EntitiesAffected[0].EntityType == Enumerations.EntityTypes.Player); curDest = User.Position + new Vector2(UtilityGlobals.DifferenceDivided(destPos.X, User.Position.X, 2f), -MissHeight); CurSequenceAction = new MoveToSeqAction(curDest, MissMoveDur, Interpolation.InterpolationTypes.Linear, Interpolation.InterpolationTypes.QuadIn); break; case 2: User.AnimManager.PlayAnimation(AnimationGlobals.IdleName); CurSequenceAction = new WaitSeqAction(MissWaitDur); ChangeSequenceBranch(SequenceBranch.End); break; default: PrintInvalidSequence(); break; } }
/// <summary> /// Gets the origin of a Rectangle /// </summary> /// <param name="rectangle">The Rectangle to get the origin for</param> /// <param name="x">The X ratio of the origin, from 0 to 1</param> /// <param name="y">The Y ratio of the origin, from 0 to 1</param> /// <returns>A Vector2 with the origin</returns> public static Vector2 GetOrigin(this Rectangle rectangle, float x, float y) { int xVal = (int)(rectangle.Width * UtilityGlobals.Clamp(x, 0f, 1f)); int yVal = (int)(rectangle.Height * UtilityGlobals.Clamp(y, 0f, 1f)); return(new Vector2(xVal, yVal)); }
protected override void OnDraw() { //The cursor is drawn on top of the entity being targeted //Only 1/4 of the full cursor is stored as a texture, so we can just draw 3 more versions flipped differently string text = "NO!"; Color color = Color.Red; if (WithinRange == true) { text = "OKAY!"; color = Color.Green; } SpriteRenderer.Instance.DrawText(AssetManager.Instance.TTYDFont, text, new Vector2(300, 100), color, .7f); //Handle rotation float rotation = -ElapsedTime *UtilityGlobals.ToRadians(.1f); DrawBigCursor(rotation); DrawSmallCursor(rotation); //Show success rectangle (comment out if not debugging) //Texture2D DebugBoxTex = AssetManager.Instance.LoadAsset<Texture2D>($"{ContentGlobals.UIRoot}/Box"); //SpriteRenderer.Instance.Draw(DebugBoxTex, new Vector2(SuccessRect.X, SuccessRect.Y), null, Color.Red, 0f, Vector2.Zero, // new Vector2(SuccessRect.Width, SuccessRect.Height), false, false, .21f, true); }
protected override void SequenceStartBranch() { switch (SequenceStep) { case 0: Vector2 frontPos = BattleManagerUtils.GetPositionInFront(User.BManager.GetFrontmostBattleEntity(CurTarget.EntityType, null), User.EntityType != EntityTypes.Enemy); frontPos.Y = User.Position.Y; User.AnimManager.PlayAnimation(AnimationGlobals.RunningName); CurSequenceAction = new MoveToSeqAction(User, frontPos, WalkDuration); break; case 1: User.AnimManager.PlayAnimation(AnimationGlobals.JumpStartName); CurSequenceAction = new WaitForAnimationSeqAction(User, AnimationGlobals.JumpStartName); ChangeSequenceBranch(SequenceBranch.Main); //Store the jump distance XDiffOverTwo = UtilityGlobals.DifferenceDivided(CurTarget.Position.X, User.Position.X, 2f); break; default: PrintInvalidSequence(); break; } }
/// <summary> /// Attempts to afflict the entity with a StatusEffect based on its properties and status percentage for the StatusEffect. /// </summary> /// <param name="inflictionChance">The chance of inflicting the StatusEffect.</param> /// <param name="status">The StatusEffect to afflict the entity with.</param> /// <returns>true if the StatusEffect was successfully afflicted, false otherwise.</returns> public bool TryAfflictStatus(double inflictionChance, StatusEffect status) { //Test for StatusEffect immunity - if the entity is immune to a particular alignment, don't allow the StatusEffect to be inflicted bool positiveStatusImmune = GetAdditionalProperty <bool>(AdditionalProperty.PositiveStatusImmune); bool negativeStatusImmune = GetAdditionalProperty <bool>(AdditionalProperty.NegativeStatusImmune); bool neutralStatusImmune = GetAdditionalProperty <bool>(AdditionalProperty.NeutralStatusImmune); if ((status.Alignment == StatusEffect.StatusAlignments.Positive && positiveStatusImmune == true) || (status.Alignment == StatusEffect.StatusAlignments.Negative && negativeStatusImmune == true) || (status.Alignment == StatusEffect.StatusAlignments.Neutral && neutralStatusImmune == true)) { return(false); } StatusPropertyHolder statusProperty = GetStatusProperty(status.StatusType); //If the entity is immune to this particular StatusEffect, don't allow it to be inflicted if (statusProperty.Immune == true) { Debug.Log($"{Entity.Name} is immune to {status.StatusType}!"); return(false); } //Test the percentage double percentage = statusProperty.StatusPercentage; return(UtilityGlobals.TestRandomCondition(inflictionChance, percentage)); }
public void HealHP(int hp) { BattleStats.HP = UtilityGlobals.Clamp(BattleStats.HP + hp, 0, BattleStats.MaxHP); UpdateHealthState(); Debug.Log($"{Name} healed {hp} HP!"); }
protected void UpdateThrownStars() { //Check if the stars collided with anything for (int i = 0; i < StarsThrown.Count; i++) { StarsThrown[i].Update(); //Make sure the star doesn't go past the designated X value if (StarsThrown[i].Position.X >= StarMaxX) { StarsThrown.RemoveAt(i); i--; continue; } CollisionResponseHolder?collisionResponse = UtilityGlobals.GetCollisionForSet(StarsThrown[i], IconSpawner.RestorationElements); //We have a collision, so handle it if (collisionResponse != null) { //Remove the star and icon IconSpawner.RemoveElement((SweetTreatRestorationElement)collisionResponse.Value.ResponseObj); StarsThrown.RemoveAt(i); i--; //Handle the restore data based on its behavior RestoreBehaviorData restoreData = (RestoreBehaviorData)collisionResponse.Value.CollisionData; HandleRestoreData(restoreData); } } }
//NOTE: For some moves, these only show up when you hit (Ex. Jump, Hammer, Power Shell). //Other moves show them as you perform the command, even if they deal damage (Ex. Mini-Egg, Earth Tremor). //Find a way to define when to show them in each move public void OnCommandRankResult(ActionCommand.CommandRank commandRank) { //Don't bother if the CommandRank is nothing if (commandRank == ActionCommand.CommandRank.None) { return; } //Get how many Simplifiers and Unsimplifiers the entity has equipped int simplifierCount = UtilityGlobals.Clamp(User.GetEquippedBadgeCount(BadgeGlobals.BadgeTypes.Simplifier), 0, BadgeGlobals.MaxSimplifierCount); int unsimplifierCount = UtilityGlobals.Clamp(User.GetEquippedBadgeCount(BadgeGlobals.BadgeTypes.Unsimplifier), 0, BadgeGlobals.MaxUnsimplifierCount); int rankInt = (int)commandRank; //Subtract Simplifier count and add Unsimplifier count to the final rank rankInt -= simplifierCount; rankInt += unsimplifierCount; //Clamp the rank to the final values rankInt = UtilityGlobals.Clamp(rankInt, (int)ActionCommand.CommandRank.NiceM2, (int)ActionCommand.CommandRank.Excellent); ActionCommand.CommandRank finalRank = (ActionCommand.CommandRank)rankInt; //Update the highest command rank if (finalRank > HighestCommandRank) { HighestCommandRank = finalRank; } }
public override void Initialize() { //Check if any of the items can target anyone Mystery mystery = (Mystery)ItemUsed; BattleItem[] mysteryItems = mystery.GetItemSet(); if (mysteryItems != null) { for (int i = 0; i < mysteryItems.Length; i++) { ItemAction itemAction = mysteryItems[i].GetActionAssociated(User); //If the item can target anyone, then add it to the revised set BattleEntity[] entities = itemAction.GetEntitiesMoveAffects(); if (entities != null && entities.Length > 0) { RevisedItemSet.Add(mysteryItems[i]); } else { Debug.Log($"Mystery item: {mysteryItems[i].Name} is excluded from the revised item set because it can't target anyone!"); } } } //If no items in the Mystery can target anyone, disable the Mystery itself if (UtilityGlobals.IListIsNullOrEmpty(RevisedItemSet) == true) { Disabled = true; DisabledString = "There's no one this move can target!"; } }
/// <summary> /// Gets the origin of a Texture2D by ratio instead of specifying width and height /// </summary> /// <param name="texture2D">The texture to get the origin for</param> /// <param name="x">The X ratio of the origin, between 0 and 1</param> /// <param name="y">The Y ratio of the origin, between 0 and 1</param> /// <returns>A Vector2 with the origin</returns> public static Vector2 GetOrigin(this Texture2D texture2D, float x, float y) { int xVal = (int)(texture2D.Width * UtilityGlobals.Clamp(x, 0f, 1f)); int yVal = (int)(texture2D.Height * UtilityGlobals.Clamp(y, 0f, 1f)); return(new Vector2(xVal, yVal)); }
protected override void CommandSuccess() { base.CommandSuccess(); Bounces++; SentRank = (ActionCommand.CommandRank)UtilityGlobals.Clamp((int)HighestCommandRank + 1, (int)ActionCommand.CommandRank.NiceM2, (int)ActionCommand.CommandRank.Excellent); }
/// <summary> /// Draws a line. /// </summary> /// <param name="start">The start point.</param> /// <param name="end">The end point.</param> /// <param name="color">The color of the line.</param> /// <param name="layer">The layer of the line.</param> /// <param name="thickness">The thickness of the line.</param> /// <param name="uiBatch">Whether to draw the line in the UI layer or not.</param> public static void DebugDrawLine(Vector2 start, Vector2 end, Color color, float layer, int thickness, bool uiBatch) { if (DebugEnabled == false) { return; } Texture2D box = AssetManager.Instance.LoadRawTexture2D($"{ContentGlobals.UIRoot}/Box.png"); //Get rotation with the angle between the start and end vectors float lineRotation = (float)UtilityGlobals.TangentAngle(start, end); //Get the scale; use the X as the length and the Y as the width Vector2 diff = end - start; Vector2 lineScale = new Vector2(diff.Length(), thickness); if (uiBatch == false) { SpriteRenderer.Instance.Draw(box, start, null, color, lineRotation, new Vector2(0f, 0f), lineScale, false, false, layer); } else { SpriteRenderer.Instance.DrawUI(box, start, null, color, lineRotation, new Vector2(0f, 0f), lineScale, false, false, layer); } }
public override void Update() { if (CurStarState == StarState.Expanding) { CurScale.X = UtilityGlobals.Clamp(CurScale.X + ScaleRate, 0f, MaxScale.X); CurScale.Y = UtilityGlobals.Clamp(CurScale.Y + ScaleRate, 0f, MaxScale.Y); if (CurScale == MaxScale) { CurStarState = StarState.Waiting; } } else if (CurStarState == StarState.Waiting) { //Increment time and check if it should start shrinking ElapsedTime += Time.ElapsedMilliseconds; if (ElapsedTime >= DisplayTime) { CurStarState = StarState.Shrinking; } } else { //Shrink the star CurScale.X = UtilityGlobals.Clamp(CurScale.X - ScaleRate, 0f, MaxScale.X); CurScale.Y = UtilityGlobals.Clamp(CurScale.Y - ScaleRate, 0f, MaxScale.Y); if (CurScale == Vector2.Zero) { ReadyForRemoval = true; } } }
protected override void OnStart() { base.OnStart(); //In PM, if you're inflicted with Stone, then the Action Command doesn't come up //and the number of attacks is halved, rounding down //Check if the target is immobile if (EntitiesAffected[0].IsImmobile() == true) { //Disable the action command Action.EnableActionCommand = false; //Divide the number of attacks by two, clamping at one //We clamp because if the Action Command is disabled, an infinite attack would softlock //In addition, as the target is immobile, it's not able to Superguard to damage the attacker and end the move MaxAttacks = UtilityGlobals.Clamp(MaxAttacks / 2, 1, MaxAttacks); NumAttacks = MaxAttacks; //Log a message here to indicate it's intentional Debug.Log($"{EntitiesAffected[0].Name} is Immobile; ActionCommand disabled and MaxAttacks halved to {MaxAttacks}. This is PM behavior"); } if (Action.CommandEnabled == true && Action.DrawActionCommandInfo == true) { KissyKissyUI = new FillBarActionCommandUI <MashButtonCommand>(actionCommand as MashButtonCommand, new Vector2(250, 150), new Vector2(100f, 1f), null); User.BManager.battleUIManager.AddUIElement(KissyKissyUI); } }
public override void Update() { if (ActionCmd?.AcceptingInput == false) { return; } //Initialize if not initialized if (Initialized == false) { Initialize(); Initialized = true; } if (MarioHPRestoredVal != ActionCmd.HealingResponse.MarioHPRestored) { MarioHPRestoredVal = ActionCmd.HealingResponse.MarioHPRestored; MarioHPText.Text = MarioHPRestoredVal.ToString(); } if (PartnerHPText != null && PartnerHPRestoredVal != ActionCmd.HealingResponse.PartnerHPRestored) { PartnerHPRestoredVal = ActionCmd.HealingResponse.PartnerHPRestored; PartnerHPText.Text = PartnerHPRestoredVal.ToString(); } if (FPRestoredVal != ActionCmd.HealingResponse.FPRestored) { FPRestoredVal = ActionCmd.HealingResponse.FPRestored; FPText.Text = FPRestoredVal.ToString(); } Cursor.Position = UtilityGlobals.GetPointAroundCircle(new Circle(ActionCmd.StartPosition, ActionCmd.CircleRadius), ActionCmd.CursorAngle, true); Cursor.Rotation = (float)(-ActionCmd.ElapsedTime * UtilityGlobals.ToRadians(ActionCmd.CursorRotSpeed)); }
public override void Update() { ElapsedTime += Time.ElapsedMilliseconds; BigCursor.Rotation = (float)(-ElapsedTime * UtilityGlobals.ToRadians(.1f)); BigCursor.Position = ActionCmd.BigCursorPos; SmallCursor.Position = ActionCmd.SmallCursorPos; }
/// <summary> /// Handles adding/removing the Yux's Status Effect immunities. /// </summary> /// <param name="immune">Whether to add or remove the immunity. /// This should be true when adding the shield and false when removing it.</param> protected void AddRemoveImmunities(bool immune) { //Yuxes become immune to all Status Effects with the shield on StatusTypes[] allStatusTypes = UtilityGlobals.GetEnumValues <StatusTypes>(); for (int i = 0; i < allStatusTypes.Length; i++) { this.AddRemoveStatusImmunity(allStatusTypes[i], immune); } }
private void AddStatusImmunities() { //The Shell is immune to all Status Effects StatusTypes[] statuses = UtilityGlobals.GetEnumValues <StatusTypes>(); for (int i = 0; i < statuses.Length; i++) { this.AddRemoveStatusImmunity(statuses[i], true); } }
private void SetStatusProperties() { //Gulpits' Rocks are immune to all Status Effects StatusTypes[] statustypes = UtilityGlobals.GetEnumValues <StatusTypes>(); for (int i = 0; i < statustypes.Length; i++) { EntityProperties.AddStatusProperty(statustypes[i], new StatusPropertyHolder(0d, 0, 1)); } }
protected override void ReadInput() { //End the Action Command after the command time if (ElapsedCommandTime >= CommandTime) { //Check to see how well the player did and send the appropriate result if (CurBarValue >= SuccessRange.StartBarVal) { SendCommandRank(CommandRank.Nice); OnComplete(CommandResults.Success); } else { OnComplete(CommandResults.Failure); } return; } //Make the bar go down by a certain amount FillBar(-DecelerationRate, true); //Check if you pressed the correct button if (IsBarFull == false) { if (AutoComplete == true || Input.GetKeyDown(CurButton) == true) { //If so, fill up the bar by the correct amount FillBar(AmountPerPress, true); //If the bar is full, the bar flashes color and deceleration no longer applies if (IsBarFull == true) { DecelerationRate = 0d; } } } else { //Interpolate the color of the bar //Interpolate the color of the bar float colorVal = UtilityGlobals.PingPong(ElapsedCommandTime / 300f, .3f, 1f); BarFillColor = new Color(colorVal, colorVal, colorVal, 1f); } ElapsedCommandTime += Time.ElapsedMilliseconds; //Check for switching buttons if (Time.ActiveMilliseconds >= PrevButtonSwitchTime) { //Wrap the button index CurButtonIndex = UtilityGlobals.Wrap(CurButtonIndex + 1, 0, ButtonsToPress.Length - 1); PrevButtonSwitchTime = Time.ActiveMilliseconds + ButtonSwitchTime; } }
/// <summary> /// Handles adding/removing Allergic's Status Effect immunities. /// Allergic makes the entity immune to every Status Effect. /// </summary> /// <param name="immune">Whether to add or remove the immunity.</param> private void HandleStatusImmunities(bool immune) { //Get all statuses and add or remove the immunity StatusTypes[] allStatusTypes = UtilityGlobals.GetEnumValues <StatusTypes>(); for (int i = 0; i < allStatusTypes.Length; i++) { EntityAfflicted.AddRemoveStatusImmunity(allStatusTypes[i], immune); } }
protected void FillBar(double amount, bool clamp) { CurBarValue += amount; //Clamp the bar if (clamp == true) { CurBarValue = UtilityGlobals.Clamp(CurBarValue, 0d, MaxBarValue); } }
protected override void HandleDamageEffects(Enumerations.DamageEffects damageEffects) { base.HandleDamageEffects(damageEffects); if (UtilityGlobals.DamageEffectHasFlag(damageEffects, Enumerations.DamageEffects.RemovesWings) == true && EntityProperties.IsVulnerableToDamageEffect(Enumerations.DamageEffects.RemovesWings) == true) { HandleGrounded(); } }
protected void UpdateCursor() { CursorAngle = UtilityGlobals.Clamp(CursorAngle + CursorMoveSpeed, MinCursorAngle, MaxCursorAngle); //If it reached its limits, reverse the angle if (CursorAngle >= MaxCursorAngle || CursorAngle <= MinCursorAngle) { CursorMoveSpeed = -CursorMoveSpeed; } }
protected override void HandleDamageEffects(Enumerations.DamageEffects damageEffects) { base.HandleDamageEffects(damageEffects); //Check whether any of the flags to flip are here if (UtilityGlobals.DamageEffectHasFlag(FlippedOnEffects, damageEffects) == true) { HandleFlipped(); } }
/// <summary> /// Calculates the amount of Star Power the Audience gives Mario after either he or his Partner use Appeal. /// </summary> /// <param name="activeAudienceMembers">The number of active Audience members.</param> /// <param name="superAppealCount">The number of Super Appeal or Super Appeal P Badges equipped, depending on who's using Appeal.</param> /// <returns>The total amount of Star Power gained from using Appeal.</returns> public float CalculateAppealStarPower(int activeAudienceMembers, int superAppealCount) { int appealValue = 25 * (superAppealCount + 1); int audienceOverFour = activeAudienceMembers / 4; //Cap the amount of SPU you can gain to be your max SPU float totalSPUGained = UtilityGlobals.Clamp(appealValue + audienceOverFour, 0f, MaxSPU); return(totalSPUGained); }
public override void Refresh(StatusEffect newStatus) { ChargedStatus charged = (ChargedStatus)newStatus; TotalChargeDamage += charged.TotalChargeDamage; //Charge damage is capped at the max damage that can be dealt TotalChargeDamage = UtilityGlobals.Clamp(TotalChargeDamage, BattleGlobals.MinDamage, BattleGlobals.MaxDamage); EntityAfflicted.EntityProperties.AddAdditionalProperty(Enumerations.AdditionalProperty.ChargedDamage, TotalChargeDamage); }
public override void Update() { ElapsedTime += Time.ElapsedMilliseconds; //Interpolate the color of the bar if it's full if (ActionCmd.IsBarFull == true) { float colorVal = UtilityGlobals.PingPong(ElapsedTime / 300f, .3f, 1f); BarFillColor = new Color(colorVal, colorVal, colorVal, 1f); } }
protected override void SequenceSuccessBranch() { switch (SequenceStep) { case 0: base.SequenceSuccessBranch(); break; case 1: //Check the damage dealt InteractionResult[] interactions = AttemptDamage(DamageDealt, EntitiesAffected, Action.DamageProperties, true); int damage = 0; if (interactions[0] != null) { damage = interactions[0].VictimResult.TotalDamage; } //Show VFX for the highest command rank if (interactions[0] != null && interactions[0].WasVictimHit == true && interactions[0].WasAttackerHit == false) { ShowCommandRankVFX(HighestCommandRank, CurTarget.Position); } //If the total damage dealt was 1, stop decreasing the damage to keep it doing 1 if (StopDecreasing == false && damage == 1) { StopDecreasing = true; } //Only decrease the value if we're not at 1 damage if (StopDecreasing == false) { DamageValue = UtilityGlobals.Clamp(DamageValue - 1, BattleGlobals.MinDamage, BattleGlobals.MaxDamage); } //Repeat the sequence if the player is under the Power Bounce cap if (Bounces < BattleGlobals.MaxPowerBounces) { ChangeSequenceBranch(SequenceBranch.Main); } else { Debug.Log($"Reached Power Bounce limit with {Bounces} and real max is {BattleGlobals.MaxPowerBounces}!"); ChangeSequenceBranch(SequenceBranch.End); } break; default: PrintInvalidSequence(); break; } }