//equipment public void SetEquipment(Equipable equipable) { if (equipable == null) { Debug.LogWarning("Equipping null equipable!\n\n" + new NullReferenceException().StackTrace); return; } if (this.GetEquipment(equipable.slot) != null) { Unequip(equipable.slot); } if (equipable is Holdable holdable) { //if we're equipping something that requires both hands, unequip other hand if (holdable.requiresBothHands) { Unequip(equipable.slot == EquipSlot.LeftHandItem ? EquipSlot.RightHandItem : EquipSlot.LeftHandItem); } //if we're equipping something that doesn't require both hands, check if we already have something //in the other hand that requires both hands, and unequip it else { Holdable otherHand = (Holdable)GetEquipment(equipable.slot == EquipSlot.LeftHandItem ? EquipSlot.RightHandItem : EquipSlot.LeftHandItem); //if true if (otherHand != null && otherHand.requiresBothHands) { Unequip(otherHand.slot); } } } _equipment[(int)equipable.slot] = equipable; _equipment[(int)equipable.slot]?.OnEquip(); OnEquipped?.Invoke(equipable); }
private void OnHoldable(Holdable h) { if (h.Entity is TheoCrystal) { TheoCrystal theoCrystal = h.Entity as TheoCrystal; theoCrystal.RemoveSelf(); theoCount++; GameData.Instance.minigameStatus[GameData.Instance.realPlayerID] = theoCount; MultiplayerSingleton.Instance.Send(new MinigameStatus { results = theoCount }); if (theoCount >= THEOS_NEEDED && endCoroutine == null) { Add(endCoroutine = new Coroutine(EndMinigame())); } else { level.Add(new TheoCrystal(theoRespawnPoint)); } } }
void OnTriggerExit(Collider c) { var holdableExit = c.GetComponent <Holdable>(); if (holdableExit != null) { holdableExit.ResetColor(); } if (c.transform == holdable.transform) { holdable = null; } if (c.transform == button.transform) { button = null; } if (c.transform == slider.transform) { slider = null; } }
public override void Interact(PlayerOne player) { if (player.heldObject == null) { if (store.gameState.playerMoney >= costOfItem)//need to look at how to get money of item { store.itemPurchased(costOfItem); GameObject realObject = Instantiate(itemPrefab, new Vector3 { x = 0f, y = 0f, z = 0f }, Quaternion.identity); holdable = realObject.GetComponent <Holdable>(); holdable.Interact(player); } else if (store.gameState.playerMoney < costOfItem) { store.notEnoughMoney(); } } else { } }
public List <Item> GetItems() { List <Item> items = new List <Item>(); foreach (var item in Items) { if (item is Netwearable) { Netwearable netWear = item as Netwearable; Wearable wearable = new Wearable(); wearable.Initialize(netWear); items.Add(wearable); } if (item is NetHoldable) { NetHoldable netHold = item as NetHoldable; Holdable holdable = new Holdable(); holdable.Initialize(netHold); items.Add(holdable); } if (item is NetConsumable) { NetConsumable netCons = item as NetConsumable; Consumable consumable = new Consumable(); consumable.Initialize(netCons); items.Add(consumable); } if (item is NetMisc) { NetMisc netMisc = item as NetMisc; Misc misc = new Misc(); misc.Initialize(netMisc); items.Add(misc); } } return(items); }
private void TouchMoved(Touch touch) { if (CastRayFromTouch(touch)) { // Check if the touch hit a holdable Holdable holdable = GetHoldable(raycastHits[touch.fingerId].Value); if (holdable) { heldThisFrame[touch.fingerId] = holdable; if (heldThisFrame[touch.fingerId] != heldLastFrame[touch.fingerId]) { heldThisFrame[touch.fingerId].OnTouchBegin(raycastHits[touch.fingerId].Value); } } CheckSwipe(touch); } if (heldLastFrame[touch.fingerId] && heldLastFrame[touch.fingerId] != heldThisFrame[touch.fingerId]) { heldLastFrame[touch.fingerId].OnTouchReleased(); } }
private void useCharge(Holdable hold) { Player player = hold.Holder; if (player.Speed.Y > BoostLaunchThreshold) { player.Speed.Y = BoostLaunchSpeed; hold.SlowFall = true; HasBoosted = true; boostDuration = 1.2f; Audio.Play("event:/game/01_forsaken_city/birdbros_thrust", Position); launchBeginInfo.Invoke(player, new object[] { }); Charges--; flashOverlaySprite.Color = flashUseColor; updateChargeSpriteVisibility(); showChargeFlash(); Input.Dash.ConsumeBuffer(); } }
public void grab(ref Holdable currentItem) { Holdable item; if (currentItem != null) //already holding something { currentItem.drop(); currentItem = null; return; } item = (Holdable)holdables[0]; if (item == null) { //nothing to pick up return; } //passed checks, let's pick something up item.pickup(transform); currentItem = item; }
private void grab(Transform hand, ref Holdable currentItem) { Holdable item; item = closestHoldable(); if (item == null) { //nothing to pick up return; } if (item.CompareTag("dnp")) { //marked as do not pick up return; } //passed checks, let's pick something up item.pickup(hand); currentItem = item; playSound_pickup(); }
private void TestInteract() { if (currentHolding != null) { //interactable that is holdable is released currentHolding.Drop(); currentHolding = null; return; } var interactables = FindObjectsOfType <Interactable>().Where(a => a.isLocked == false); Interactable closestItem = null; var closestDist = float.MaxValue; foreach (var interactable in interactables) { var dist = Vector3.Distance(interactable.transform.position, gameObject.transform.position); if (dist < interactDistance && dist < closestDist) { closestItem = interactable; closestDist = dist; } } if (closestItem != null) { //Can it be held? var holdable = closestItem.GetComponent <Holdable>(); if (holdable != null) { currentHolding = holdable; currentHolding.Pickup(); } //Todo otherwise interact } }
private void combine() { if (rightHandItem == null || leftHandItem == null) //not holding something in both hands. we're done. { return; } SimpleObject rightSimple; SimpleObject leftSimple; try{ rightSimple = (SimpleObject)rightHandItem; leftSimple = (SimpleObject)leftHandItem; }catch (InvalidCastException) { //one of these things is not a simple object, so not combineable. we're done. playSound_error(); return; } GameObject newObject = rightSimple.combine(leftSimple); if (newObject == null) { playSound_error(); return; } Destroy(leftHandItem.gameObject); Destroy(rightHandItem.gameObject); ComplexObject newItem = (ComplexObject)newObject.GetComponent(typeof(ComplexObject)); newItem.pickup(rightHand); rightHandItem = newItem; playSound_poof(); }
public void SetHolding(Holdable newHoldable) { var previousHoldable = _currentlyHolding; if (Holdable.Wood == newHoldable) { holdingTorch.SetActive(false); holdingWood.SetActive(true); _soundManager.PlayCollectLog(); _currentlyHolding = newHoldable; return; } if (Holdable.Torch == newHoldable) { holdingWood.SetActive(false); holdingTorch.SetActive(true); _currentlyHolding = newHoldable; return; } if (previousHoldable == Holdable.Wood) { _soundManager.PlayDropLog(); } if (previousHoldable == Holdable.Torch) { _soundManager.PlayPlaceTorch(); } holdingTorch.SetActive(false); holdingWood.SetActive(false); _currentlyHolding = newHoldable; }
private void OnMouse() { Vector2 mousePos = Input.mousePosition; if (CastRayFromMousePos(mousePos)) { // Check if the ray hit a holdable Holdable holdable = GetHoldable(raycastHits[0].Value); if (holdable) { heldThisFrame[0] = holdable; if (Input.GetMouseButtonDown(0)) { holdable.OnTouchBegin(raycastHits[0].Value); } foreach (Holdable lastFrameHoldable in heldLastFrame) { if (lastFrameHoldable && !lastFrameHoldable.Equals(holdable)) { lastFrameHoldable.OnTouchReleased(); } } } } else { foreach (Holdable lastFrameHoldable in heldLastFrame) { if (lastFrameHoldable) { lastFrameHoldable.OnTouchReleased(); } } } }
public int takeItem(Holdable h, int amount) { List <UIslot> returnSlots = SlotsWithHoldable(h); if (returnSlots.Count > 0) { foreach (var s in returnSlots) { int left = amount - s.amount; if (left <= 0) { s.amount -= amount; return(0); } else { s.changeHolding(null); amount -= left; } } } return(amount); }
public void Drop() { if (this.Holdable == null) { return; } this.Holdable.transform.SetParent(transform.root); this.Holdable.Unfreeze(); var fwd = m_LookDirection.normalized; var pos = m_HoldableObject.transform.position + fwd * 0.8f; RaycastHit hit; if (Physics.Raycast(m_HoldableObject.transform.position, fwd, out hit, 0.8f)) { pos = hit.point; } this.Holdable.transform.position = pos; m_Holdable = null; }
private void ThrowItem() { if (heldItem == null) { return; } anim.SetBool("HoldingPot", false); anim.SetBool("HoldingItem", false); heldItem.Drop(); // Check if held item is the pot if (heldItem is Crockpot) { // Throw pot Vector3 otherPosition = GameController.Instance.GetOtherPlayer(this).transform.position; heldItem.Rb.AddForce( throwForce.x * direction, throwForce.y, (otherPosition.z - transform.position.z) * throwForce.z, ForceMode.Impulse ); } else if (heldItem is Item) { // Throw the ingredient in front of you heldItem.Rb.AddForce( throwForce.x * direction, throwForce.y, 0, ForceMode.Impulse ); } heldItem = null; throwing = false; // TODO return to idle }
public Battery(Vector2 position, int initalCharge, int maxCharge, int dischargeRate, bool oneUse, bool ignoreBarriers, int onlyFits, EntityID id) : base(position) { previousPosition = position; this.id = id; fresh = true; base.Depth = 100; base.Collider = new Hitbox(8f, 10f, -4f, -10f); Add(sprite = BatteriesModule.SpriteBank.Create("battery")); sprite.Scale.X = -1f; Add(Hold = new Holdable(0.1f)); Hold.PickupCollider = new Hitbox(16f, 22f, -8f, -16f); Hold.SlowFall = false; Hold.SlowRun = false; Hold.OnPickup = OnPickup; Hold.OnRelease = OnRelease; Hold.DangerousCheck = Dangerous; Hold.OnHitSeeker = HitSeeker; Hold.OnSwat = Swat; Hold.OnHitSpring = HitSpring; Hold.OnHitSpinner = HitSpinner; Hold.SpeedGetter = (() => Speed); onCollideH = OnCollideH; onCollideV = OnCollideV; LiftSpeedGraceTime = 0.1f; Add(new VertexLight(base.Collider.Center, Color.White, 1f, 32, 64)); Add(new MirrorReflection()); particle = P_Full; this.MaxCharge = maxCharge; Charge = initalCharge; this.DischargeRate = dischargeRate; this.oneUse = oneUse; this.ignoreBarriers = ignoreBarriers; this.onlyFits = onlyFits; LoadParticles(); }
private void onHoldable(Holdable h) { TurnOn(); }
private extern bool orig_Pickup(Holdable pickup);
private static void UpdatePlayerInfo() { Player player = null; long chapterTime = 0; if (Engine.Scene is Level level) { player = level.Tracker.GetEntity <Player>(); if (player != null) { chapterTime = level.Session.Time; if (chapterTime != lastTimer || lastPos != player.ExactPosition) { string pos = GetAdjustedPos(player.Position, player.PositionRemainder); string speed = $"Speed: {player.Speed.X.ToString("0.00")},{player.Speed.Y.ToString("0.00")}"; Vector2 diff = (player.ExactPosition - lastPos) * 60; string vel = $"Vel: {diff.X.ToString("0.00")},{diff.Y.ToString("0.00")}"; string polarvel = $" {diff.Length().ToString("0.00")},{GetAngle(diff).ToString("0.00")}°"; string miscstats = $"Stamina: {player.Stamina.ToString("0")} Timer: {(chapterTime / 10000000D).ToString("0.000")}"; int dashCooldown = (int)((float)player.GetPrivateField("dashCooldownTimer") * 60f); string statuses = (dashCooldown < 1 && player.Dashes > 0 ? "Dash " : string.Empty) + (player.LoseShards ? "Ground " : string.Empty) + ((bool)player.InvokePrivateMethod("WallJumpCheck", 1) ? "Wall-R " : string.Empty) + ((bool)player.InvokePrivateMethod("WallJumpCheck", -1) ? "Wall-L " : string.Empty) + (!player.LoseShards && (float)player.GetPrivateField("jumpGraceTimer") > 0 ? "Coyote " : string.Empty); statuses = (player.InControl && !level.Transitioning ? statuses : "NoControl ") + (player.TimePaused ? "Paused " : string.Empty) + (level.InCutscene ? "Cutscene " : string.Empty); if (player.Holding == null) { foreach (Component component in level.Tracker.GetComponents <Holdable>()) { Holdable holdable = (Holdable)component; if (holdable.Check(player)) { statuses += "Grab "; break; } } } int berryTimer = -10; Follower firstRedBerryFollower = player.Leader.Followers.Find(follower => follower.Entity is Strawberry berry && !berry.Golden); if (firstRedBerryFollower?.Entity is Strawberry firstRedBerry) { object collectTimer; if (firstRedBerry.GetType() == typeof(Strawberry) || (collectTimer = firstRedBerry.GetPrivateField("collectTimer")) == null) { // if this is a vanilla berry or a mod berry having no collectTimer, use the cached FieldInfo for Strawberry.collectTimer. collectTimer = strawberryCollectTimer.GetValue(firstRedBerry); } berryTimer = (int)Math.Round(60f * (float)collectTimer); } string timers = (berryTimer != -10 ? $"BerryTimer: {berryTimer.ToString()} " : string.Empty) + (dashCooldown != 0 ? $"DashTimer: {(dashCooldown).ToString()} " : string.Empty); string map = $"[{level.Session.Level}]"; StringBuilder sb = new StringBuilder(); sb.AppendLine(pos); sb.AppendLine(speed); sb.AppendLine(vel); if (player.StateMachine.State == Player.StStarFly || SaveData.Instance.Assists.ThreeSixtyDashing || SaveData.Instance.Assists.SuperDashing) { sb.AppendLine(polarvel); } sb.AppendLine(miscstats); if (!string.IsNullOrEmpty(statuses)) { sb.AppendLine(statuses); } sb.Append(timers); sb.Append(map); lastPos = player.ExactPosition; lastTimer = chapterTime; PlayerStatus = sb.ToString().TrimEnd(); } } else { PlayerStatus = level.InCutscene ? "Cutscene" : string.Empty; } } else if (Engine.Scene is SummitVignette summit) { PlayerStatus = "SummitVignette " + summit.GetPrivateField("ready"); } else if (Engine.Scene is Overworld overworld) { PlayerStatus = "Overworld " + overworld.ShowInputUI; } else if (Engine.Scene != null) { PlayerStatus = Engine.Scene.GetType().Name; } }
public static void ExportPlayerInfo() { Player player = null; if (Engine.Scene is Level level) { player = level.Tracker.GetEntity <Player>(); if (player != null) { string inputs = controller.Current.ActionsToString(); if (inputs.Length > 1) { inputs = inputs.Substring(1); } string time = (level.Session.Time / 10000000D).ToString("0.000"); double x = (double)player.X + player.PositionRemainder.X; double y = (double)player.Y + player.PositionRemainder.Y; string pos = x.ToString() + "," + y.ToString(); string speed = player.Speed.X.ToString() + "," + player.Speed.Y.ToString(); int dashCooldown = (int)((float)player.GetPrivateField("dashCooldownTimer") * 60f); string statuses = (dashCooldown < 1 && player.Dashes > 0 ? "Dash " : string.Empty) + (player.LoseShards ? "Ground " : string.Empty) + ((bool)player.InvokePrivateMethod("WallJumpCheck", 1) ? "Wall-R " : string.Empty) + ((bool)player.InvokePrivateMethod("WallJumpCheck", -1) ? "Wall-L " : string.Empty) + (!player.LoseShards && (float)player.GetPrivateField("jumpGraceTimer") > 0 ? "Coyote " : string.Empty); statuses = (player.InControl && !level.Transitioning ? statuses : "NoControl ") + (player.TimePaused ? "Paused " : string.Empty) + (level.InCutscene ? "Cutscene " : string.Empty); if (player.Holding == null) { foreach (Component component in level.Tracker.GetComponents <Holdable>()) { Holdable holdable = (Holdable)component; if (holdable.Check(player)) { statuses += "Grab "; break; } } } string output = string.Join(" ", inputs, controller.CurrentFrame, time, pos, speed, player.StateMachine.State, statuses); foreach (MethodInfo method in trackedEntities) { if (method == null) { continue; } List <Entity> entities = (List <Entity>)method.Invoke(level.Tracker, null); foreach (Entity entity in entities) { Actor actor = entity as Actor; if (actor != null) { x = (double)actor.X + actor.PositionRemainder.X; y = (double)actor.Y + actor.PositionRemainder.Y; pos = x.ToString() + "," + y.ToString(); } else { pos = entity.X.ToString() + "," + entity.Y.ToString(); } output += $" {method.GetGenericArguments()[0].Name}: {pos}"; } } sw.WriteLine(output); } } }
private static void UpdatePlayerInfo() { Player player = null; long chapterTime = 0; if (Engine.Scene is Level level) { player = level.Tracker.GetEntity <Player>(); if (player != null) { chapterTime = level.Session.Time; if (chapterTime != lastTimer || lastPos != player.ExactPosition) { string pos = $"Pos: {player.ExactPosition.X.ToString("0.00", enUS)},{player.ExactPosition.Y.ToString("0.00", enUS)}"; string speed = $"Speed: {player.Speed.X.ToString("0.00", enUS)},{player.Speed.Y.ToString("0.00", enUS)}"; Vector2 diff = (player.ExactPosition - lastPos) * 60; string vel = $"Vel: {diff.X.ToString("0.00", enUS)},{diff.Y.ToString("0.00", enUS)}"; string polarvel = $" {diff.Length().ToString("0.00", enUS)},{GetAngle(diff).ToString("0.00", enUS)}°"; string miscstats = $"Stamina: {player.Stamina.ToString("0")} Timer: {(chapterTime / 10000000D).ToString("0.000", enUS)}"; string statuses = (player.CanDash ? "Dash " : string.Empty) + (player.LoseShards ? "Ground " : string.Empty) + (player.WallJumpCheck(1) ? "Wall-R " : string.Empty) + (player.WallJumpCheck(-1) ? "Wall-L " : string.Empty) + (!player.LoseShards && player.jumpGraceTimer > 0 ? "Coyote " : string.Empty); statuses = ((player.InControl && !level.Transitioning ? statuses : "NoControl ") + (player.TimePaused ? "Paused " : string.Empty) + (level.InCutscene ? "Cutscene " : string.Empty)); if (player.Holding == null) { foreach (Component component in level.Tracker.GetComponents <Holdable>()) { Holdable holdable = (Holdable)component; if (holdable.Check(player)) { statuses += "Grab "; break; } } } int berryTimer = -10; Follower firstRedBerryFollower = player.Leader.Followers.Find(follower => follower.Entity is Strawberry berry && !berry.Golden); if (firstRedBerryFollower?.Entity is Strawberry firstRedBerry) { berryTimer = (int)Math.Round(60f * firstRedBerry.collectTimer); } string timers = (berryTimer != -10 ? $"BerryTimer: {berryTimer.ToString()} " : string.Empty) + ((int)(player.dashCooldownTimer * 60f) != 0 ? $"DashTimer: {((int)Math.Round(player.dashCooldownTimer * 60f) - 1).ToString()} " : string.Empty); StringBuilder sb = new StringBuilder(); sb.AppendLine(pos); sb.AppendLine(speed); sb.AppendLine(vel); if (player.StateMachine.State == 19 || SaveData.Instance.Assists.ThreeSixtyDashing || SaveData.Instance.Assists.SuperDashing) { sb.AppendLine(polarvel); } sb.AppendLine(miscstats); if (!string.IsNullOrEmpty(statuses)) { sb.AppendLine(statuses); } sb.Append(timers); PlayerStatus = sb.ToString().TrimEnd(); lastPos = player.ExactPosition; lastTimer = chapterTime; } } else { PlayerStatus = level.InCutscene ? "Cutscene" : null; } } else if (Engine.Scene is SummitVignette summit) { PlayerStatus = string.Concat("SummitVignette ", summit); } else if (Engine.Scene is Overworld overworld) { PlayerStatus = string.Concat("Overworld ", overworld.ShowInputUI); } else if (Engine.Scene != null) { PlayerStatus = Engine.Scene.GetType().Name; } }
public static void UpdateInputs() { Player player = null; long chapterTime = 0; if (Engine.Scene is Level level) { player = level.Tracker.GetEntity <Player>(); if (player != null) { string statuses = ((int)(player.dashCooldownTimer * 60f) < 1 && player.Dashes > 0 ? "Dash " : string.Empty) + (player.LoseShards ? "Ground " : string.Empty) + (player.WallJumpCheck(1) ? "Wall-R " : string.Empty) + (player.WallJumpCheck(-1) ? "Wall-L " : string.Empty); chapterTime = ((Celeste.Celeste)Engine.Instance).AutoSplitterInfo.ChapterTime; Vector2 diff = (player.ExactPosition - lastPos) * 60; if (player.Holding == null) { foreach (Component component in level.Tracker.GetComponents <Holdable>()) { Holdable holdable = (Holdable)component; if (holdable.Check(player)) { statuses += "Grab "; break; } } } StringBuilder sb = new StringBuilder(); sb.Append("Pos: ").Append(player.ExactPosition.X.ToString("0.0", enUS)).Append(',').AppendLine(player.ExactPosition.Y.ToString("0.0", enUS)); sb.Append("Speed: ").Append(player.Speed.X.ToString("0.00", enUS)).Append(',').Append(player.Speed.Y.ToString("0.00", enUS)).Append(',').AppendLine(player.Speed.Length().ToString("0.00", enUS)); sb.Append("Vel: ").Append(diff.X.ToString("0.00", enUS)).Append(',').Append(diff.Y.ToString("0.00", enUS)).Append(',').AppendLine(diff.Length().ToString("0.00", enUS)); sb.Append("Stamina: ").Append(player.Stamina.ToString("0")).Append(" Timer: ").AppendLine(((double)chapterTime / (double)10000000).ToString("0.000", enUS)); sb.Append(player.InControl && !level.Transitioning ? statuses : "NoControl ").Append(player.TimePaused ? "Paused " : string.Empty).Append(level.InCutscene ? "Cutscene " : string.Empty); PlayerStatus = sb.ToString(); } else { PlayerStatus = level.InCutscene ? "Cutscene" : null; } } else if (Engine.Scene is SummitVignette summit) { PlayerStatus = string.Concat("SummitVignette ", summit.ready); } else if (Engine.Scene is Overworld overworld) { PlayerStatus = string.Concat("Overworld ", overworld.ShowInputUI); } else if (Engine.Scene != null) { PlayerStatus = Engine.Scene.GetType().Name; } kbState = Keyboard.GetState(); GamePadState padState = GetGamePadState(); HandleFrameRates(padState); CheckControls(padState); FrameStepping(padState); if (HasFlag(state, State.Enable)) { Running = true; if (HasFlag(state, State.FrameStep)) { return; } if (HasFlag(state, State.Record)) { controller.RecordPlayer(); } else { bool fastForward = controller.HasFastForward; controller.PlaybackPlayer(); if (fastForward && !controller.HasFastForward) { nextState |= State.FrameStep; FrameLoops = 1; } if (!controller.CanPlayback) { DisableRun(); } } string status = controller.Current.Line + "[" + controller.ToString() + "]"; CurrentStatus = status; } else { Running = false; CurrentStatus = null; if (!Engine.Instance.IsActive) { for (int i = 0; i < 4; i++) { if (MInput.GamePads[i].Attached) { MInput.GamePads[i].CurrentState = padState; } } MInput.UpdateVirtualInputs(); } } if (player != null && chapterTime != lastTimer) { lastPos = player.ExactPosition; lastTimer = chapterTime; } }
private void onHoldPickup(Holdable hold) { Input.Dash.ConsumeBuffer(); }
public void OnGunAttached(Hand hand, Holdable gun) { isGunAttached = true; this.hand = hand; gunRef = hand.GetComponentInChildren <Holdable>(); }
void grab() //hold obj { if (canthrow) { canthrow = false; holding = false; //hands.tele (inuse); grabobj.toss(); } else { if (Physics.Raycast(cam.position, cam.forward, out grabhit, grabrange) && (grabobj = grabhit.transform.GetComponent <Holdable> ())) { Debug.Log("rgab"); holding = true; //hands.tele (inuse); grabobj.grab(); } } }
static public P GetHolder <P>(this Holdable <P> item) { return(item.GetHoldingContainer <P>().IfNotNull(c => c.GetParent())); }
protected abstract void heartBroken(Player player, Holdable holdable, Level level);
private void OnHoldable(Holdable h) { h.HitSpinner(this); }
public static void UpdatePlayerInfo() { if (Engine.Scene is Level level) { Player player = level.Tracker.GetEntity <Player>(); if (player != null) { long chapterTime = level.Session.Time; if (chapterTime != lastTimer || LastPos != player.ExactPosition) { framesPerSecond = 60f / Engine.TimeRateB; string pos = GetAdjustedPos(player.Position, player.PositionRemainder); string speed = $"Speed: {player.Speed.X:F2}, {player.Speed.Y:F2}"; Vector2 diff = (player.ExactPosition - LastPos) * 60f; string vel = $"Vel: {diff.X:F2}, {diff.Y:F2}"; string polarvel = $"Fly: {diff.Length():F2}, {GetAngle(diff):F5}°"; string joystick; if (Running && Controller.Previous is InputFrame inputFrame && inputFrame.HasActions(Actions.Feather)) { joystick = $"Analog: {AnalogHelper.LastDirection.X:F5}, {AnalogHelper.LastDirection.Y:F5}, {GetAngle(new Vector2(AnalogHelper.LastDirection.X, -AnalogHelper.LastDirection.Y)):F5}°"; } else { joystick = string.Empty; } string miscstats = $"Stamina: {player.Stamina:0} " + (WallJumpCheck(player, 1) ? "Wall-R " : string.Empty) + (WallJumpCheck(player, -1) ? "Wall-L " : string.Empty); int dashCooldown = (int)(DashCooldownTimer(player) * framesPerSecond); PlayerSeeker playerSeeker = level.Entities.FindFirst <PlayerSeeker>(); if (playerSeeker != null) { pos = GetAdjustedPos(playerSeeker.Position, playerSeeker.PositionRemainder); speed = $"Speed: {PlayerSeekerSpeed(playerSeeker).X:F2}, {PlayerSeekerSpeed(playerSeeker).Y:F2}"; diff = (playerSeeker.ExactPosition - LastPlayerSeekerPos) * 60f; vel = $"Vel: {diff.X:F2}, {diff.Y:F2}"; polarvel = $"Chase: {diff.Length():F2}, {GetAngle(diff):F2}°"; dashCooldown = (int)(PlayerSeekerDashTimer(playerSeeker) * framesPerSecond); } string statuses = (dashCooldown < 1 && player.Dashes > 0 ? "Dash " : string.Empty) + (player.LoseShards ? "Ground " : string.Empty) + (!player.LoseShards && JumpGraceTimer(player) > 0 ? $"Coyote({(int) (JumpGraceTimer(player) * framesPerSecond)})" : string.Empty); string transitionFrames = PlayerInfo.TransitionFrames > 0 ? $"({PlayerInfo.TransitionFrames})" : string.Empty; statuses = (player.InControl && !level.Transitioning ? statuses : $"NoControl{transitionFrames} ") + (player.TimePaused ? "Paused " : string.Empty) + (level.InCutscene ? "Cutscene " : string.Empty) + (AdditionalStatusInfo ?? string.Empty); if (player.Holding == null) { foreach (Component component in level.Tracker.GetComponents <Holdable>()) { Holdable holdable = (Holdable)component; if (holdable.Check(player)) { statuses += "Grab "; break; } } } int berryTimer = -10; Follower firstRedBerryFollower = player.Leader.Followers.Find(follower => follower.Entity is Strawberry berry && !berry.Golden); if (firstRedBerryFollower?.Entity is Strawberry firstRedBerry) { object collectTimer; if (firstRedBerry.GetType() == typeof(Strawberry) || (collectTimer = StrawberryCollectTimer(firstRedBerry)) == null) { // if this is a vanilla berry or a mod berry having no collectTimer, use the cached FieldInfo for Strawberry.collectTimer. collectTimer = StrawberryCollectTimerFieldInfo.GetValue(firstRedBerry); } berryTimer = 9 - (int)Math.Round((float)collectTimer * framesPerSecond); } string timers = (berryTimer != -10 ? berryTimer <= 9 ? $"BerryTimer: {berryTimer} " : $"BerryTimer: 9+{berryTimer - 9} " : string.Empty) + (dashCooldown != 0 ? $"DashTimer: {(dashCooldown).ToString()} " : string.Empty); string roomNameAndTime = $"[{level.Session.Level}] Timer: {(chapterTime / 10000000D):F3}({chapterTime / TimeSpan.FromSeconds(Engine.RawDeltaTime).Ticks})"; StringBuilder sb = new StringBuilder(); sb.AppendLine(pos); sb.AppendLine(speed); sb.AppendLine(vel); if (player.StateMachine.State == Player.StStarFly || playerSeeker != null || SaveData.Instance.Assists.ThreeSixtyDashing || SaveData.Instance.Assists.SuperDashing) { sb.AppendLine(polarvel); } if (!string.IsNullOrEmpty(joystick)) { sb.AppendLine(joystick); } sb.AppendLine(miscstats); if (!string.IsNullOrEmpty(statuses)) { sb.AppendLine(statuses); } if (!string.IsNullOrEmpty(timers)) { sb.AppendLine(timers); } sb.Append(roomNameAndTime); LastPos = player.ExactPosition; LastPlayerSeekerPos = playerSeeker?.ExactPosition ?? default; lastTimer = chapterTime; PlayerStatus = sb.ToString().TrimEnd(); } } else { PlayerStatus = level.InCutscene ? "Cutscene" : string.Empty; } }