public override bool Verify(VM vm, VMAvatar caller) { if (Verified) { return(true); //set internally when transaction succeeds. trust that the verification happened. } if (caller == null || //caller must be on lot, have owner permissions ((VMTSOAvatarState)caller.TSOState).Permissions < VMTSOAvatarPermissions.Owner) { return(false); } var exState = vm.TSOState.Size; var exSize = exState & 255; var exStories = (exState >> 8) & 255; LotSize = Math.Min(LotSize, (byte)(VMBuildableAreaInfo.BuildableSizes.Length - 1)); LotStories = Math.Min(LotStories, (byte)3); if ((exSize == LotSize && exStories == LotStories) || LotSize < exSize || LotStories < exStories) { //cannot size down. cannot stay same size (no-op) return(false); } else { var totalOld = exSize + exStories; var totalTarget = LotSize + LotStories; var baseCost = VMBuildableAreaInfo.CalculateBaseCost(totalOld, totalTarget); var roomieCost = VMBuildableAreaInfo.CalculateRoomieCost(vm.TSOState.Roommates.Count, totalOld, totalTarget); //perform the transaction. If it succeeds, requeue the command vm.GlobalLink.PerformTransaction(vm, false, caller.PersistID, uint.MaxValue, baseCost + roomieCost, (bool success, int transferAmount, uint uid1, uint budget1, uint uid2, uint budget2) => { if (success) { Verified = true; vm.ForwardCommand(this); } vm.SendCommand(new VMNetAsyncResponseCmd(0, new VMTransferFundsState { //update budgets on clients. id of 0 means there is no target thread. Responded = true, Success = success, TransferAmount = transferAmount, UID1 = uid1, Budget1 = budget1, UID2 = uid2, Budget2 = budget2 })); }); return(false); } }
public void UpdateCost() { var lotInfo = LotControl.vm.TSOState; var lotSize = lotInfo.Size & 255; var lotFloors = (lotInfo.Size >> 8) & 255; var lotDir = lotInfo.Size >> 16; OldLotSize = lotInfo.Size; UpdateSizeTarget = Math.Min(Math.Max(lotSize, UpdateSizeTarget), VMBuildableAreaInfo.BuildableSizes.Length - 1); UpdateFloorsTarget = Math.Min(Math.Max(lotFloors, UpdateFloorsTarget), 3); var totalTarget = UpdateFloorsTarget + UpdateSizeTarget; var totalOld = lotSize + lotFloors; AcceptButton.Disabled = totalTarget == totalOld; //no upgrade selected var baseCost = VMBuildableAreaInfo.CalculateBaseCost(totalOld, totalTarget); var roomieCost = VMBuildableAreaInfo.CalculateRoomieCost(lotInfo.Roommates.Count, totalOld, totalTarget); if (baseCost + roomieCost > (LotControl.ActiveEntity?.TSOState.Budget.Value ?? 0)) { AcceptButton.Disabled = true; //can't afford } //TODO: read from uiscript TotalCostLabel.CaptionStyle.Color = AcceptButton.Disabled?new Color(255, 125, 125):TextStyle.DefaultLabel.Color; var targetTiles = VMBuildableAreaInfo.BuildableSizes[UpdateSizeTarget]; string[][] applyText = new string[][] { new string[] { }, new string[] { targetTiles.ToString(), targetTiles.ToString() + "x" + (UpdateFloorsTarget + 2) }, new string[] { baseCost.ToString() }, new string[] { roomieCost.ToString() }, new string[] { (baseCost + roomieCost).ToString() }, new string[] { Math.Min(8, totalTarget + 1).ToString() }, new string[] { UpdateSizeTarget + 1 + "+" + UpdateFloorsTarget } }; for (int i = 0; i < Labels.Count; i++) { Labels[i].Caption = GetArgsString(SavedInitialText[i], applyText[i]); } TargetSize = LotControl.vm.Context.GetTSOBuildableArea(UpdateSizeTarget | (UpdateFloorsTarget << 8) | (lotDir << 16)); RenderPreview(VMBuildableAreaInfo.BuildableSizes[lotSize], lotFloors + 2, targetTiles, UpdateFloorsTarget + 2); }