ModernUO/Projects/Scripts/Mobiles/Townfolk/Banker.cs
Kamron Batman 179cb50557 Updates Packets & Randomizer (#43)
* Fixes a bug with the main loop. Removes unnecessary optimizations for RDRand.

* WIP - Rewriting packets.

* Cleanup and updates README

* Converts more packets

* Fixes header

* Converts Effects packets.

* Forgot the send command

* Adds the start of containers packets.

* Adds message packets with caching

* Extends the send methods

* Starts to add Acquire methods

* Converted the packets

* Cleanup

* Cleanup

* Adds more packets

* Adds more packets

* Fixes clearing arrays from pool. Adds Mobile Incoming

* Converts more packets.

* Moves more packets

* Moves more packets

* Test compression

* Merges

* Migrating to an idiomatic syntax that also supports compression, and proxying.

* Optimize the stack alloc. Changes attributes

* Converted container packets

* Visual Studio doesn't auto save files. I am still getting used to subpar IDEs.

* Adds static packet caching. Will profile later. Converts more packets

* Fixes packets and changes how compression is configured

* WIP - Adds basics for Gumps. Not finished though.

* Fix file

* Fixes formatting

* Changed SpanWriter to be more idiomatic.

* Fixes Span vs RawSpan and missing stackallocs

* Converts over some more gumps

* WIP - Deletes 32bit support.

* Drops RDRand32 support.

* Fixes gump compilation

* Converting gump components

* Removes old huffman compression function

* Revert signature for backwards compatibility

* WIP - Converting more gump components

* Creates ArraySet for the strings. Updates AppendTo to reference that.

* Converts the maining gump components

* Cleans up gump components

* Cleans up directives

* Cleans up ArraySet and moves it. Adds null-coalescing-assignment

* Cleanup, Target Packets, and C# 8 changes.

* Removed OPL Packet

* World packets

* Fixing packet uses

* Cleans up code. Fixes packet uses in various places.

* More cleanup for packets

* Code cleanup

* Converts more packet uses and cleans up more code

* More code cleanup

* Finishes fixing the packets in Item

* Updates secure trade packets

* Updates core and gets it to compile.

* Moved packets to scripts. Fixed account handler use of packets

* Code cleanup

* Updates chat packets

* Code cleanuo

* Adds party packets, but need to implement them.

* Party packets WIP

* Finishes party packets

* Rearrange movement namespaces and classes

* Finishes plant packets

* Code Formatting

* Fixes moving effects

* Code cleanup, eliminates equipinfo

* Adds more packets. Fixes bugs with various packets.

* Finishes mahjon packets

* Fixes mahjong packet

* Code cleanup

* Finishes mahjong packets

* Adds Map packets

* Add multifacet maps and charts

* Cleans up some packets with UTF8

* Optimizes packets

* Cleans up more packets. Moves the MessageHelper

* Removes assistant support. Removes extended protocol. Incorporates MapUO packets as normal packets.

* Updates protocol extensions packet receiver

* Fixes a few bugs. Fixes a few more packets.

* Code cleanup and fixing more packets

* Fixes packet effects

* Cleaned up more code

* Buff Icon cleanup

* Removed unused constructors

* Code Cleanup. Adds BoatHS Packets

* Moves house files. Updates house foundation packets.

* Deployment cleanup

* Fixes:

* Code cleanup

* More code cleanup

* More code cleanup

* Cleaned up BaseHouse

* Enforces styling

* Converts foreach to linq where possible.

* Dont need that

* Goals/Readme updates

* Removes 32bit support at the highest level. Turns on HRT by default.

* Code cleanup. Fixes extended features packet.

* Fixes various bugs

* Code cleanup

* Code cleanup

* Code cleanup. Fixes gump X/Y assignment.

* Code cleanup using |= operator

* More code cleanup

* Cleanup

* Fixes spacing issues. Thanks Visual Studio. You suck.

* Compiler error

* Fixes NPE from RunUO 2.7

* Renames ScriptCompiler to AssemblyHandler. Fixes packets. Updates README

* Fixes more packets. Stupid trailing nulls.

* Fixes various bugs.

* Fixes for gumps

* Fixes more gump stuff. Going to split it out later since it is getting insane

* Recoded the gump writing

* WIP

* *Added output path of scripts project to dev branch
*Activated debugging in code
2019-11-11 12:40:16 +01:00

418 lines
11 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using Server.ContextMenus;
using Server.Items;
using Server.Network;
namespace Server.Mobiles
{
public class Banker : BaseVendor
{
private List<SBInfo> m_SBInfos = new List<SBInfo>();
[Constructible]
public Banker() : base("the banker")
{
}
public Banker(Serial serial) : base(serial)
{
}
protected override List<SBInfo> SBInfos => m_SBInfos;
public override NpcGuild NpcGuild => NpcGuild.MerchantsGuild;
public override void InitSBInfo()
{
m_SBInfos.Add(new SBBanker());
}
public static int GetBalance(Mobile m)
{
long balance = 0;
if (AccountGold.Enabled && m.Account != null)
{
balance = m.Account.GetTotalGold();
if (balance >= int.MaxValue) return int.MaxValue;
}
Container bank = m.FindBankNoCreate();
if (bank != null)
{
List<Gold> gold = bank.FindItemsByType<Gold>();
List<BankCheck> checks = bank.FindItemsByType<BankCheck>();
balance += gold.Aggregate(0L, (c, t) => c + t.Amount);
if (balance >= int.MaxValue)
return int.MaxValue;
balance += checks.Aggregate(0L, (c, t) => c + t.Worth);
}
return Math.Max(0, (int)Math.Min(int.MaxValue, balance));
}
public static int GetBalance(Mobile m, out Item[] gold, out Item[] checks)
{
long balance = 0;
if (AccountGold.Enabled && m.Account != null)
{
balance = m.Account.GetTotalGold();
if (balance > int.MaxValue)
{
gold = checks = new Item[0];
return int.MaxValue;
}
}
Container bank = m.FindBankNoCreate();
if (bank != null)
{
gold = bank.FindItemsByType(typeof(Gold));
checks = bank.FindItemsByType(typeof(BankCheck));
balance += gold.OfType<Gold>().Aggregate(0L, (c, t) => c + t.Amount);
if (balance >= int.MaxValue) return int.MaxValue;
balance += checks.OfType<BankCheck>().Aggregate(0L, (c, t) => c + t.Worth);
}
else
{
gold = checks = new Item[0];
}
return Math.Max(0, (int)Math.Min(int.MaxValue, balance));
}
public static bool Withdraw(Mobile from, int amount)
{
// If for whatever reason the TOL checks fail, we should still try old methods for withdrawing currency.
if (AccountGold.Enabled && from.Account?.WithdrawGold(amount) == true) return true;
int balance = GetBalance(from, out Item[] gold, out Item[] checks);
if (balance < amount) return false;
for (int i = 0; amount > 0 && i < gold.Length; ++i)
if (gold[i].Amount <= amount)
{
amount -= gold[i].Amount;
gold[i].Delete();
}
else
{
gold[i].Amount -= amount;
amount = 0;
}
for (int i = 0; amount > 0 && i < checks.Length; ++i)
{
BankCheck check = (BankCheck)checks[i];
if (check.Worth <= amount)
{
amount -= check.Worth;
check.Delete();
}
else
{
check.Worth -= amount;
amount = 0;
}
}
return true;
}
public static bool Deposit(Mobile from, int amount)
{
// If for whatever reason the TOL checks fail, we should still try old methods for depositing currency.
if (AccountGold.Enabled && from.Account?.DepositGold(amount) == true) return true;
BankBox box = from.FindBankNoCreate();
if (box == null) return false;
List<Item> items = new List<Item>();
while (amount > 0)
{
Item item;
if (amount < 5000)
{
item = new Gold(amount);
amount = 0;
}
else if (amount <= 1000000)
{
item = new BankCheck(amount);
amount = 0;
}
else
{
item = new BankCheck(1000000);
amount -= 1000000;
}
if (box.TryDropItem(from, item, false))
{
items.Add(item);
}
else
{
item.Delete();
foreach (Item curItem in items) curItem.Delete();
return false;
}
}
return true;
}
public static int DepositUpTo(Mobile from, int amount)
{
// If for whatever reason the TOL checks fail, we should still try old methods for depositing currency.
if (AccountGold.Enabled && from.Account?.DepositGold(amount) == true) return amount;
BankBox box = from.FindBankNoCreate();
if (box == null) return 0;
int amountLeft = amount;
while (amountLeft > 0)
{
Item item;
int amountGiven;
if (amountLeft < 5000)
{
item = new Gold(amountLeft);
amountGiven = amountLeft;
}
else if (amountLeft <= 1000000)
{
item = new BankCheck(amountLeft);
amountGiven = amountLeft;
}
else
{
item = new BankCheck(1000000);
amountGiven = 1000000;
}
if (box.TryDropItem(from, item, false))
{
amountLeft -= amountGiven;
}
else
{
item.Delete();
break;
}
}
return amount - amountLeft;
}
public static void Deposit(Container cont, int amount)
{
while (amount > 0)
{
Item item;
if (amount < 5000)
{
item = new Gold(amount);
amount = 0;
}
else if (amount <= 1000000)
{
item = new BankCheck(amount);
amount = 0;
}
else
{
item = new BankCheck(1000000);
amount -= 1000000;
}
cont.DropItem(item);
}
}
public override bool HandlesOnSpeech(Mobile from)
{
if (from.InRange(Location, 12))
return true;
return base.HandlesOnSpeech(from);
}
public override void OnSpeech(SpeechEventArgs e)
{
if (!e.Handled && e.Mobile.InRange(Location, 12))
for (int i = 0; i < e.Keywords.Length; ++i)
{
int keyword = e.Keywords[i];
switch (keyword)
{
case 0x0000: // *withdraw*
{
e.Handled = true;
if (e.Mobile.Criminal)
{
Say(500389); // I will not do business with a criminal!
break;
}
string[] split = e.Speech.Split(' ');
if (split.Length >= 2)
{
Container pack = e.Mobile.Backpack;
if (!int.TryParse(split[1], out int amount))
break;
if (!Core.ML && amount > 5000 || Core.ML && amount > 60000)
Say(500381); // Thou canst not withdraw so much at one time!
else if (pack?.Deleted != false || !(pack.TotalWeight < pack.MaxWeight) ||
!(pack.TotalItems < pack.MaxItems))
Say(1048147); // Your backpack can't hold anything else.
else if (amount > 0)
{
BankBox box = e.Mobile.FindBankNoCreate();
if (box == null || !Withdraw(e.Mobile, amount))
Say(500384); // Ah, art thou trying to fool me? Thou hast not so much gold!
else
{
pack.DropItem(new Gold(amount));
Say(1010005); // Thou hast withdrawn gold from thy account.
}
}
}
break;
}
case 0x0001: // *balance*
{
e.Handled = true;
if (e.Mobile.Criminal)
{
Say(500389); // I will not do business with a criminal!
break;
}
if (AccountGold.Enabled && e.Mobile.Account != null)
Say(1155855,
$"{e.Mobile.Account.TotalPlat:#,0}\t{e.Mobile.Account.TotalGold:#,0}"); // Thy current bank balance is ~1_AMOUNT~ platinum and ~2_AMOUNT~ gold.
else
Say(1042759,
GetBalance(e.Mobile).ToString("#,0")); // Thy current bank balance is ~1_AMOUNT~ gold.
break;
}
case 0x0002: // *bank*
{
e.Handled = true;
if (e.Mobile.Criminal)
{
Say(500378); // Thou art a criminal and cannot access thy bank box.
break;
}
e.Mobile.BankBox.Open();
break;
}
case 0x0003: // *check*
{
e.Handled = true;
if (AccountGold.Enabled)
break;
if (e.Mobile.Criminal)
{
Say(500389); // I will not do business with a criminal!
break;
}
string[] split = e.Speech.Split(' ');
if (split.Length >= 2)
{
if (!int.TryParse(split[1], out int amount))
break;
if (amount < 5000)
Say(1010006); // We cannot create checks for such a paltry amount of gold!
else if (amount > 1000000)
Say(1010007); // Our policies prevent us from creating checks worth that much!
else
{
BankCheck check = new BankCheck(amount);
BankBox box = e.Mobile.BankBox;
if (!box.TryDropItem(e.Mobile, check, false))
{
Say(500386); // There's not enough room in your bankbox for the check!
check.Delete();
}
else if (!box.ConsumeTotal(typeof(Gold), amount))
{
Say(500384); // Ah, art thou trying to fool me? Thou hast not so much gold!
check.Delete();
}
else
{
Say(1042673, AffixType.Append, amount.ToString(),
""); // Into your bank box I have placed a check in the amount of:
}
}
}
break;
}
}
}
base.OnSpeech(e);
}
public override void AddCustomContextEntries(Mobile from, List<ContextMenuEntry> list)
{
if (from.Alive)
list.Add(new OpenBankEntry(from, this));
base.AddCustomContextEntries(from, list);
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}