diff --git a/Assets/Scripts/Auction/BiddingAI.cs b/Assets/Scripts/Auction/BiddingAI.cs index 6da113518..8915355b5 100644 --- a/Assets/Scripts/Auction/BiddingAI.cs +++ b/Assets/Scripts/Auction/BiddingAI.cs @@ -17,6 +17,7 @@ public class BiddingAI : BiddingPlayer [SerializeField] private Vector3 platformDestinationOffset = Vector3.back * 2; + private int platformsEvaluated = 0; private bool shouldEvaluate = true; void Start() @@ -40,28 +41,41 @@ public void SetIdentity(PlayerIdentity identity) private IEnumerator WaitAndEvaluate() { foreach (BiddingPlatform platform in AuctionDriver.Singleton.BiddingPlatforms) - if (platform.IsActive) - EvaluatePlatformStates(platform); + EvaluatePlatformStates(platform); + ChooseDestination(); yield return new WaitForSeconds(2); StartCoroutine(WaitAndEvaluate()); } private void EvaluatePlatformStates(BiddingPlatform platform) { - if (platform.LeadingBidder == playerManager.id) + var isAlreadyInTheLead = platform.IsActive && platform.LeadingBidder == playerManager.id; + if (isAlreadyInTheLead) return; - if (platform.chips >= playerManager.identity.chips) + var isNotActive = !platform.IsActive; + var isTooExpensive = platform.chips >= playerManager.identity.chips; + if (isNotActive || isTooExpensive) priorities[platform] = -1; + } + private void ChooseDestination() + { currentDestination = priorities.ToList() .OrderByDescending(x => x.Value) .Select(x => x.Key).First(); - if (currentDestination) - agent.SetDestination(currentDestination.transform.position + platformDestinationOffset); + if (!currentDestination) + return; + + var isAlreadyInTheLead = currentDestination.LeadingBidder == playerManager.id; + if (isAlreadyInTheLead) + return; + + agent.SetDestination(currentDestination.transform.position + platformDestinationOffset); - if (currentDestination == playerManager.SelectedBiddingPlatform) + var isAlreadyAtThisPlatform = currentDestination == playerManager.SelectedBiddingPlatform; + if (isAlreadyAtThisPlatform) OnBiddingPlatformChange(currentDestination); } @@ -83,11 +97,11 @@ private void EvaluateItem(BiddingPlatform platform) .Sum((augment) => augment.KillCount); break; } - priorities.Add(platform, priority); - // Move towards a position that does not obscure the cost text (!) - agent.SetDestination(platform.transform.position + platformDestinationOffset); + // (re)set the priority (reassignment in case we have multiple bidding rounds) + priorities[platform] = priority; - if (!shouldEvaluate) + platformsEvaluated++; + if (platformsEvaluated < 3 || !shouldEvaluate) return; StartCoroutine(WaitAndEvaluate()); shouldEvaluate = false; @@ -105,7 +119,7 @@ private void AnimateBid() private void OnBiddingPlatformChange(BiddingPlatform platform) { - if (!platform || !currentDestination || platform != currentDestination || platform.LeadingBidder == playerManager.id) + if (!platform || !currentDestination || platform != currentDestination || platform.LeadingBidder == playerManager.id || platform != playerManager.SelectedBiddingPlatform) return; AnimateBid(); diff --git a/Assets/Scripts/Auction/BiddingPlatform.cs b/Assets/Scripts/Auction/BiddingPlatform.cs index 42f45156d..24f48bea9 100644 --- a/Assets/Scripts/Auction/BiddingPlatform.cs +++ b/Assets/Scripts/Auction/BiddingPlatform.cs @@ -137,6 +137,13 @@ public void PlaceBid(PlayerIdentity playerIdentity) CmdPlaceBid(playerIdentity.id); } + private bool CanBid(PlayerIdentity bidder) + { + bool isLeadingPlayerAndCanIncrement = bidder.id == leadingBidder && bidder.chips > 0; + bool bidderHasEnoughChips = bidder.chips > chips; + return isLeadingPlayerAndCanIncrement || bidderHasEnoughChips; + } + // All players should be able to place bids, thus we ignore authority (for the time being). // TODO verify that the player is on the platform and is from the connection that calls this cmd. [Command(requiresAuthority = false)] @@ -158,8 +165,7 @@ private void CmdPlaceBid(uint playerID) Debug.Log($"Got bidding request from {playerIdentity.ToColorString()} (chips={playerIdentity.chips}) on {item.displayName} (chips={chips}, leader={leadingBidderIdentity?.ToColorString()})"); - bool leadingPlayerCanIncrement = playerIdentity.id == leadingBidder && playerIdentity.chips > 0; - if (playerIdentity.chips > chips || leadingPlayerCanIncrement) + if (CanBid(playerIdentity)) { Debug.Log($"Accepted request from {playerIdentity.ToColorString()} on {item.displayName}"); RpcAcceptBid(playerIdentity.id); @@ -181,6 +187,13 @@ private void RpcAcceptBid(uint playerID) } var playerIdentity = player.identity; + if (!CanBid(playerIdentity)) + { + Debug.LogWarning($"Invalid bid request from {playerIdentity.ToColorString()} for {item.displayName}"); + onBidDenied?.Invoke(this); + return; + } + // TODO consider rewriting some of the following // Refund @@ -197,7 +210,7 @@ private void RpcAcceptBid(uint playerID) chips++; playerIdentity.UpdateChip(-chips); itemCostText.text = chips.ToString() + ""; - leadingBidText.text = playerIdentity.playerName.ToUpper()+":"; + leadingBidText.text = playerIdentity.playerName.ToUpper() + ":"; LeanTween.value( gameObject, (color) => material.SetColor("_BidderColor", color), diff --git a/Assets/Scripts/Gamestate/PlayerIdentity.cs b/Assets/Scripts/Gamestate/PlayerIdentity.cs index e84c22f1e..9f3033c73 100644 --- a/Assets/Scripts/Gamestate/PlayerIdentity.cs +++ b/Assets/Scripts/Gamestate/PlayerIdentity.cs @@ -60,7 +60,16 @@ private void Start() public void UpdateChip(int amount) { if (amount == 0) return; - chips += amount; + if (chips + amount < 0) + { + Debug.LogWarning($"Player {id} {ToColorString()} almost got negative chips {chips + amount}"); + // Safeguard against cheating by locking chip amount to 0 when this sort of bug appears. + chips = 0; + } + else + { + chips += amount; + } onChipChange?.Invoke(chips);