diff --git a/Data/Assemblies_4_0.cfg b/Data/Assemblies.cfg
similarity index 57%
rename from Data/Assemblies_4_0.cfg
rename to Data/Assemblies.cfg
index b38b50d2d..cb31d8095 100644
--- a/Data/Assemblies_4_0.cfg
+++ b/Data/Assemblies.cfg
@@ -1,7 +1,11 @@
System.dll
System.Core.dll
-System.Web.dll
-System.Xml.dll
System.Data.dll
+System.Data.DataSetExtensions.dll
System.Drawing.dll
+System.Web.dll
System.Windows.Forms.dll
+System.Xml.dll
+System.Xml.Linq.dll
+
+Microsoft.CSharp.dll
\ No newline at end of file
diff --git a/Data/Components/doors.txt b/Data/Components/doors.txt
index e639636ab..4199fce9d 100644
--- a/Data/Components/doors.txt
+++ b/Data/Components/doors.txt
@@ -36,4 +36,4 @@ Category Piece1 Piece2 Piece3 Piece4 Piece5 Piece6 Piece7 Piece8 FeatureMask Com
31 0 0 18141 18143 18145 18147 0 0 65536 Ruined Door
32 0 0 19746 19748 19750 19752 0 0 65536 Gargish Blue Door
33 20680 20682 20688 20690 20684 20686 20692 20694 65536 Gargish Red Doors
-34 0 0 20802 20804 20806 20808 0 0 65536 Gargish Prison Door
+34 0 0 20802 20804 20806 20808 0 0 65536 Gargish Prison Door
\ No newline at end of file
diff --git a/Data/Components/floors.txt b/Data/Components/floors.txt
index 8ba425107..50a727d20 100644
--- a/Data/Components/floors.txt
+++ b/Data/Components/floors.txt
@@ -54,4 +54,8 @@ Category F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 FeatureMask Comm
51 16778 16774 16775 16776 16777 16779 16780 16781 16782 0 0 0 0 0 0 0 65536 Gargish Sun
52 16523 16524 16525 16526 16527 16528 16529 16530 16531 16532 16533 16534 16535 16536 16537 16538 65536 Gargish Green Stone
53 16514 16510 16511 16512 16513 16515 16516 16517 16518 16519 16520 16521 16522 0 0 0 65536 Gargish Green Stone 2
-54 18124 18125 18126 18127 18326 18327 18328 18329 0 0 0 0 0 0 0 0 65536 Gargish Ruins
+54 18124 18125 18126 18127 18326 18327 18328 18329 0 0 0 0 0 0 0 0 65536 Gargish Ruins
+
+55 39629 39632 39635 39634 39633 39630 39627 39628 39631 39636 39637 39638 39817 39818 0 0 1048576 Jungle 1
+56 39730 39733 39736 39735 39734 0 39728 0 39732 39738 0 0 0 0 0 0 1048576 Jungle 2
+57 39897 39731 39898 39729 39899 0 39900 0 39737 39739 0 0 0 0 0 0 1048576 Jungle 3
\ No newline at end of file
diff --git a/Data/Components/misc.txt b/Data/Components/misc.txt
index e3b07b5c9..743a76755 100644
--- a/Data/Components/misc.txt
+++ b/Data/Components/misc.txt
@@ -90,4 +90,9 @@ Category Style TID Piece1 Piece2 Piece3 Piece4 Piece5 Piece6 Piece7 Piece8 Featu
33 0 1112097 18401 18402 18403 18407 18408 18409 0 0 65536 Gargish Ruined Arches
34 0 1112098 18600 18601 18602 18603 18604 18605 0 0 65536 Gargish Stone Heads
35 0 1150613 0 30705 30706 30707 30708 30709 0 30710 524288 Board and Batten Arches
-36 0 1150624 0 19248 19192 19261 19249 19198 0 0 262144 Gothic Arches
+36 0 1150624 0 19248 19192 19261 19249 19198 0 0 262144 Gothic Arches
+
+37 0 1156117 39620 0 39621 39618 39619 0 39622 39603 1048576 Jungle Arches
+38 0 1156117 0 0 39722 39708 39815 0 0 39704 2097152 Shadowguard Arches 3
+38 1 1156117 39721 0 39816 39719 39720 0 39723 0 2097152 Shadowguard Arches 2
+38 2 1156117 39811 0 39812 39814 39810 0 39813 39809 2097152 Shadowguard Arches 3
\ No newline at end of file
diff --git a/Data/Components/roof.txt b/Data/Components/roof.txt
index cda307493..781e924f0 100644
--- a/Data/Components/roof.txt
+++ b/Data/Components/roof.txt
@@ -33,4 +33,7 @@ Category Style TID North East South West NSCrosspiece EWCrosspiece NDent EDent S
18 0 1076718 13762 13759 13760 13761 13762 13763 13764 13765 13776 13777 13766 13767 13768 13769 13770 13771 512 Crystal Roof Tiles 1
18 1 0 13772 13773 13774 13775 0 0 0 0 0 0 0 0 0 0 0 0 512 Crystal Roof Tiles 2
19 0 1076719 13859 13860 13861 13862 13863 13864 13865 13875 13876 13866 13867 13868 13869 13870 13871 13872 512 Shadow Roof Tiles 1
-19 1 0 13873 13874 13877 0 0 0 0 0 0 0 0 0 0 0 0 0 512 Shadow Roof Tiles 2
+19 1 0 13873 13874 13877 0 0 0 0 0 0 0 0 0 0 0 0 0 512 Shadow Roof Tiles 2
+
+20 0 1156123 39694 39689 39692 39691 39690 39693 39682 39681 39683 39680 39684 39688 39685 39687 39686 0 1048576 Jungle Roof Tiles 1
+21 0 1156123 39795 39782 39794 39783 39781 39793 39786 39785 39787 39784 39789 39792 39790 39791 39788 0 2097152 Shadowguard Roof Tiles 1
\ No newline at end of file
diff --git a/Data/Components/stairs.txt b/Data/Components/stairs.txt
index 07982eb77..9d4581472 100644
--- a/Data/Components/stairs.txt
+++ b/Data/Components/stairs.txt
@@ -17,3 +17,6 @@ Category Block North East South West Squared1 Squared2 Rounded1 Rounded2 MultiNo
14 17176 17252 17245 17251 17242 0 0 0 0 7656 7657 7658 7659 65536 Gargish 3
15 19207 19205 19251 19252 19204 19202 19201 19262 19263 7660 7661 7662 7663 262144 Gothic
16 30727 30729 30731 30730 30728 30733 30732 30739 30738 7664 7665 7666 7667 524288 Board and Batten
+
+17 39759 39760 39763 39762 39761 39767 39765 39770 39769 0 0 0 0 1048576 Jungle
+18 39658 39659 39662 39661 39660 39666 39664 39669 39668 0 0 0 0 2097152 Shadowguard
\ No newline at end of file
diff --git a/Data/Components/walls.txt b/Data/Components/walls.txt
index 093f70f33..847a708f9 100644
--- a/Data/Components/walls.txt
+++ b/Data/Components/walls.txt
@@ -170,4 +170,23 @@ Category Style TID South1 South2 South3 Corner East1 East2 East3 Post WindowS Al
43 5 0 0 19222 19223 19224 19225 19226 19227 0 0 0 0 0 0 0 262144 Rose Window 2
44 0 1150630 0 30694 30724 30700 30723 30697 0 30710 0 30703 30704 0 0 0 524288 Board and Batten Walls 1
44 1 0 0 30695 30726 30701 30725 30698 0 30711 0 0 0 0 0 0 524288 Board and Batten Walls 2
-44 2 0 0 30696 30737 30702 30736 30699 0 30712 0 0 0 0 0 0 524288 Board and Batten Walls 3
+44 2 0 0 30696 30737 30702 30736 30699 0 30712 0 0 0 0 0 0 524288 Board and Batten Walls 3
+
+49 0 0 30694 30695 30696 30700 30697 30698 30699 30710 30703 30724 30723 30725 30726 30704 65536 Rustic Wall 1
+49 1 0 30706 30705 30737 30701 30708 30736 30709 30711 0 0 0 0 0 0 65536 Rustic Wall 2
+50 2 0 0 0 0 30702 0 0 0 30712 0 0 0 0 0 0 65536 Rustic Wall Post
+51 3 0 0 0 0 30707 0 0 0 30713 0 0 0 0 0 0 65536 Rustic Wall Post
+52 4 0 0 0 0 0 0 0 0 30714 0 0 0 0 0 0 65536 Rustic Wall Post
+
+53 0 1156115 39601 39604 39606 39600 39602 39605 39607 39603 39608 0 0 39609 0 0 1048576 Jungle Walls 1
+53 1 0 39611 0 0 39610 39612 0 0 39613 0 0 0 0 0 0 1048576 Jungle Walls 2
+53 2 0 39615 0 0 39614 39616 0 0 39617 0 0 0 0 0 0 1048576 Jungle Walls 3
+53 3 0 39623 0 0 39625 39624 0 0 39626 0 0 0 0 0 0 1048576 Jungle Walls 4
+
+54 0 1156116 39702 0 0 39701 39703 0 0 39704 39709 0 0 39710 0 0 2097152 Shadowguard Walls 1
+54 1 0 39705 0 0 39707 39706 0 0 39892 0 0 0 0 0 0 2097152 Shadowguard Walls 2
+54 2 0 0 39807 0 39806 0 39808 0 39809 0 0 0 0 0 0 2097152 Shadowguard Walls 3
+54 3 0 39716 0 0 39715 39717 0 0 39718 0 0 0 0 0 0 2097152 Shadowguard Walls 4
+54 4 0 0 39712 0 39711 0 39713 0 39714 0 0 0 0 0 0 2097152 Shadowguard Walls 5
+54 5 0 39889 0 0 39888 39890 0 0 39891 0 0 0 0 0 0 2097152 Shadowguard Walls 6
+54 6 0 39724 0 0 39726 39725 0 0 39727 0 0 0 0 0 0 2097152 Shadowguard Walls 7
\ No newline at end of file
diff --git a/Data/bodyTable.cfg b/Data/bodyTable.cfg
index 91aaedb57..b1fc1b7f1 100644
--- a/Data/bodyTable.cfg
+++ b/Data/bodyTable.cfg
@@ -1103,58 +1103,58 @@
438 Equipment # Gargoyle Ring - NO ANIMATION - PLACEHOLDER FOR PAPERDOLL
439 Equipment # Gargoyle Necklace - NO ANIMATION - PLACEHOLDER FOR PAPERDOLL
432 Equipment # Ethereal Boura Vet Reward
-433 Equipment # Halloween Mask (Paperdoll Only)
-
-# UOHS Creatures
-1026 Monster # Uber Turkey
-1069 Animal # Ancient Hound
-1244 Monster # Water Spirit
-1245 Monster # Water Spirit Tentacle
-1246 Monster # Jack O Lantern Clown
-1247 Monster # Jack O Lantern Daemon
-1248 Monster # Baddie 01 (Exodus)
-1253 Human # Lord Blackthorne
-1254 Animal # Tiger
-
-# UOHS Wearables
-1255 Equipment # Tiger Ethereal
-
-# TOL Creatures
-1285 Animal # Dino - Dimetrosaur
-1286 Animal # Dino - Gallusaurus
-1287 Animal # Dino - Archaeosaurus
-1288 Animal # Dragon Turtle
-1289 Animal # Dino - Najasaurus
-1290 Animal # Dino - Allosaurus
-1291 Animal # Dino - Saurosaurus
-1292 Animal # Dino - Anchisaur
-1293 Animal # Dino - Myrmidex
-1294 Animal # Dragon Turtle Baby
-
-# TOL Wearables
-1261 Equipment # Human Robe BG (Male)
-1262 Equipment # Human Robe BG (Female)
-1263 Equipment # Vice Shield
-1265 Equipment # Virtua Shield
-1267 Equipment # Jester Shoes
-1269 Equipment # Chef Hat
-1271 Equipment # Kilt
-1273 Equipment # Kilt
-1275 Equipment # Kilt
-1278 Equipment # Red Dress
-1279 Equipment # Gargish Vice Shield
-1281 Equipment # Gargish Virtue Shield
-1284 Equipment # Wedding Dress
-1295 Equipment # Tiger Chest (Male)
-1296 Equipment # Tiger Chest (Female)
-1297 Equipment # Tiger Long Pants
-1298 Equipment # Tiger Short Pants
-1299 Equipment # Tiger Long Skirt
-1300 Equipment # Tiger Short Skirt
-1301 Equipment # Tiger Helm
-1302 Equipment # Tiger Collar (Gorget)
-1303 Equipment # Turtle Chest (Male)
-1304 Equipment # Turtle Chest (Female)
-1305 Equipment # Turtle Long Pants
-1306 Equipment # Turtle Helm
+433 Equipment # Halloween Mask (Paperdoll Only)
+
+# UOHS Creatures
+1026 Monster # Uber Turkey
+1069 Animal # Ancient Hound
+1244 Monster # Water Spirit
+1245 Monster # Water Spirit Tentacle
+1246 Monster # Jack O Lantern Clown
+1247 Monster # Jack O Lantern Daemon
+1248 Monster # Baddie 01 (Exodus)
+1253 Human # Lord Blackthorne
+1254 Animal # Tiger
+
+# UOHS Wearables
+1255 Equipment # Tiger Ethereal
+
+# TOL Creatures
+1285 Animal # Dino - Dimetrosaur
+1286 Animal # Dino - Gallusaurus
+1287 Animal # Dino - Archaeosaurus
+1288 Animal # Dragon Turtle
+1289 Animal # Dino - Najasaurus
+1290 Animal # Dino - Allosaurus
+1291 Animal # Dino - Saurosaurus
+1292 Animal # Dino - Anchisaur
+1293 Animal # Dino - Myrmidex
+1294 Animal # Dragon Turtle Baby
+
+# TOL Wearables
+1261 Equipment # Human Robe BG (Male)
+1262 Equipment # Human Robe BG (Female)
+1263 Equipment # Vice Shield
+1265 Equipment # Virtua Shield
+1267 Equipment # Jester Shoes
+1269 Equipment # Chef Hat
+1271 Equipment # Kilt
+1273 Equipment # Kilt
+1275 Equipment # Kilt
+1278 Equipment # Red Dress
+1279 Equipment # Gargish Vice Shield
+1281 Equipment # Gargish Virtue Shield
+1284 Equipment # Wedding Dress
+1295 Equipment # Tiger Chest (Male)
+1296 Equipment # Tiger Chest (Female)
+1297 Equipment # Tiger Long Pants
+1298 Equipment # Tiger Short Pants
+1299 Equipment # Tiger Long Skirt
+1300 Equipment # Tiger Short Skirt
+1301 Equipment # Tiger Helm
+1302 Equipment # Tiger Collar (Gorget)
+1303 Equipment # Turtle Chest (Male)
+1304 Equipment # Turtle Chest (Female)
+1305 Equipment # Turtle Long Pants
+1306 Equipment # Turtle Helm
1307 Equipment # Turtle Bracers
\ No newline at end of file
diff --git a/Data/models.txt b/Data/models.txt
new file mode 100644
index 000000000..9333b8a3f
--- /dev/null
+++ b/Data/models.txt
@@ -0,0 +1,862 @@
+#Body Type Model
+
+400 Human h_male
+401 Human h_female
+402 Human player_ghost
+403 Human player_ghost
+991 Human character_blackthorn
+994 Human character_dupre
+990 Equipment character_lord_british
+970 Equipment H_Male_Robe_Deathshroud
+1970 Equipment H_Female_Robe_Deathshroud
+183 Human H_Savage_Male
+184 Human H_Savage_Female
+185 Human H_SavageRider_Male
+186 Human H_SavageShaman_Female
+
+##Necromancy Transformed Player Models
+
+#Body Type Model
+
+744 Human h_male
+745 Human h_female
+746 Monsters four_armed_demon
+747 Monsters wailingbanshee
+748 Monsters spirits_ghost
+749 Monsters liche_liche_retro
+
+##Male Wearables
+
+#Body Type Model
+
+750 Human H_Savage_Male
+465 Equipment H_Male_Apron_Full
+466 Equipment H_Male_Apron_Half
+554 Equipment H_Male_Armor_Bone_Breastpiece
+557 Equipment H_Male_Armor_Bone_Gloves
+562 Equipment H_Male_Armor_Bone_Helm
+555 Equipment H_Male_Armor_Bone_Leggings
+556 Equipment H_Male_Armor_Bone_Sleeves
+561 Equipment H_Male_Armor_Chain_Coif
+540 Equipment H_Male_Armor_Chain_Leggings
+538 Equipment H_Male_Armor_Chain_Shirt
+680 Equipment H_Male_Armor_Dragon_Breastpiece
+681 Equipment H_Male_Armor_Dragon_Gloves
+682 Equipment H_Male_Armor_Dragon_Head_Helm
+683 Equipment H_Male_Armor_Dragon_Leggings
+679 Equipment H_Male_Armor_Dragon_Sleeves
+929 Equipment H_Male_Armor_Head_Bascinet
+928 Equipment H_Male_Armor_Head_Close_Helm
+565 Equipment H_Male_Armor_Head_Helmet
+564 Equipment H_Male_Armor_Head_Norse_Helm
+973 Equipment H_Male_Armor_Head_Orc_Helm
+743 Equipment H_Male_Armor_Head_Winged_Helmet
+675 Equipment H_Male_Armor_Japanese_Do-Maru
+694 Equipment H_Male_Armor_Japanese_Hachimaki
+678 Equipment H_Male_Armor_Japanese_Haidate
+695 Equipment H_Male_Armor_Japanese_Haramaki-Do
+672 Equipment H_Male_Armor_Japanese_Kabuto
+674 Equipment H_Male_Armor_Japanese_Kabuto_Mempo
+698 Equipment H_Male_Armor_Japanese_Kobakama
+677 Equipment H_Male_Armor_Japanese_Kote_Gloves
+676 Equipment H_Male_Armor_Japanese_Kote_Sleeves
+697 Equipment H_Male_Armor_Japanese_Kote2_Gloves
+696 Equipment H_Male_Armor_Japanese_Kote2_Sleeves
+699 Equipment H_Male_Armor_Japanese_Waraji
+560 Equipment H_Male_Armor_Leather_Cap
+545 Equipment H_Male_Armor_Leather_Gloves
+546 Equipment H_Male_Armor_Leather_Gorget
+543 Equipment H_Male_Armor_Leather_Leggings
+544 Equipment H_Male_Armor_Leather_Sleeves
+524 Equipment H_Male_Armor_Leather_Studded_Gloves
+525 Equipment H_Male_Armor_Leather_Studded_Gorget
+522 Equipment H_Male_Armor_Leather_Studded_Leggings
+523 Equipment H_Male_Armor_Leather_Studded_Sleeves
+521 Equipment H_Male_Armor_Leather_Studded_Tunic
+542 Equipment H_Male_Armor_Leather_Tunic
+527 Equipment H_Male_Armor_Plate_Breastpiece
+530 Equipment H_Male_Armor_Plate_Gauntlets
+531 Equipment H_Male_Armor_Plate_Gorget
+563 Equipment H_Male_Armor_Plate_Helm
+529 Equipment H_Male_Armor_Plate_Leggings
+528 Equipment H_Male_Armor_Plate_Sleeves
+549 Equipment H_Male_Armor_Ring_Leggings
+550 Equipment H_Male_Armor_Ring_Sleeves
+548 Equipment H_Male_Armor_Ring_Tunic
+477 Equipment H_Male_Boots
+476 Equipment H_Male_Boots_Thigh
+495 Equipment H_Male_Bracelet_Gold
+508 Equipment H_Male_Bracelet_Silver
+468 Equipment H_Male_Cloak
+448 Equipment H_Male_Dress_Fancy
+687 Equipment H_Male_Dress_Fancy_2
+688 Equipment H_Male_Dress_Fancy_3
+447 Equipment H_Male_Dress_Long
+496 Equipment H_Male_Ear_Ring_Gold
+509 Equipment H_Male_Ear_Ring_Silver
+900 Equipment H_Male_Hair_Curly
+800 Equipment H_Male_Hair_Facial_Gotee
+906 Equipment H_Male_Hair_Facial_Gotee_2
+801 Equipment H_Male_Hair_Facial_Long_Beard
+905 Equipment H_Male_Hair_Facial_Long_Beard_2
+803 Equipment H_Male_Hair_Facial_Mustache
+802 Equipment H_Male_Hair_Facial_Short_Beard
+904 Equipment H_Male_Hair_Facial_Short_Beard_2
+701 Equipment H_Male_Hair_Long
+703 Equipment H_Male_Hair_Mohawk
+710 Equipment H_Male_Hair_Pageboy
+902 Equipment H_Male_Hair_Pig_Tails
+702 Equipment H_Male_Hair_Ponytail
+901 Equipment H_Male_Hair_Receding
+700 Equipment H_Male_Hair_Short
+903 Equipment H_Male_Hair_Topknot
+492 Equipment H_Male_Hat_Bandana
+410 Equipment H_Male_Hat_Bonnet
+406 Equipment H_Male_Hat_Cap
+411 Equipment H_Male_Hat_Feathered
+742 Equipment H_Male_Hat_Feathers_Leaves
+404 Equipment H_Male_Hat_Floppy
+413 Equipment H_Male_Hat_Jester
+740 Equipment H_Male_Hat_Robin_Hood
+419 Equipment H_Male_Hat_Skullcap
+408 Equipment H_Male_Hat_Straw
+407 Equipment H_Male_Hat_Straw_Tall
+412 Equipment H_Male_Hat_Tricorner
+405 Equipment H_Male_Hat_Wide_Brim
+409 Equipment H_Male_Hat_Wizard
+455 Equipment H_Male_Kilt
+690 Equipment H_Male_Kimono
+414 Equipment H_Male_Mask_Bear
+415 Equipment H_Male_Mask_Deer
+713 Equipment H_Male_Mask_Feathered
+692 Equipment H_Male_Mask_Ninja
+416 Equipment H_Male_Mask_Orc
+417 Equipment H_Male_Mask_Tribal_1
+418 Equipment H_Male_Mask_Tribal_2
+493 Equipment H_Male_Necklace_Bead
+497 Equipment H_Male_Necklace_Gold
+494 Equipment H_Male_Necklace_Gold_Bead
+510 Equipment H_Male_Necklace_Silver
+507 Equipment H_Male_Necklace_Silver_Bead
+715 Equipment H_Male_Pants_Jester
+431 Equipment H_Male_Pants_Long
+693 Equipment H_Male_Pants_Ninja
+430 Equipment H_Male_Pants_Short
+498 Equipment H_Male_Ring_Gold
+511 Equipment H_Male_Ring_Silver
+469 Equipment H_Male_Robe_CowlDown
+732 Equipment H_Male_Robe_CowlUp
+731 Equipment H_Male_Robe_Deathshroud
+987 Equipment H_Male_Robe_GM
+490 Equipment H_Male_Sash
+733 Equipment H_Male_Shirt_1
+734 Equipment H_Male_Shirt_2
+735 Equipment H_Male_Shirt_5
+736 Equipment H_Male_Shirt_6
+911 Equipment H_Male_Shirt_Checkered
+913 Equipment H_Male_Shirt_Doublet
+435 Equipment H_Male_Shirt_Fancy
+912 Equipment H_Male_Shirt_Jester
+691 Equipment H_Male_Shirt_Ninja
+434 Equipment H_Male_Shirt_Sleeveless
+910 Equipment H_Male_Shirt_Surcoat
+909 Equipment H_Male_Shirt_Tunic
+480 Equipment H_Male_Shoes
+716 Equipment H_Male_Shoes_Jester
+479 Equipment H_Male_Shoes_Sandals
+449 Equipment H_Male_Skirt_Long
+971 Equipment H_Male_Skirt_Medium
+759 Equipment H_Male_Cloak_Arcane
+760 Equipment H_Male_Gloves_Arcane
+761 Equipment H_Male_Robe_Arcane
+762 Equipment H_Male_Boots_Arcane
+
+##Female wearables for polyorph from female to male
+
+#Body Type Model
+
+924 Equipment H_Female_Armor_Female_Bustier_Leather
+925 Equipment H_Female_Armor_Female_Bustier_Studded
+923 Equipment H_Female_Armor_Female_Leather
+922 Equipment H_Female_Armor_Female_Plate
+927 Equipment H_Female_Armor_Female_Shorts_Spiked
+926 Equipment H_Female_Armor_Female_Skirt_Leather
+921 Equipment H_Female_Armor_Female_Studded
+
+##Transition female only armor
+
+#Body Type Model
+
+2604 Equipment H_Female_Armor_Female_Bustier_Leather_OLD
+2605 Equipment H_Female_Armor_Female_Bustier_Studded_OLD
+2603 Equipment H_Female_Armor_Female_Leather_OLD
+2602 Equipment H_Female_Armor_Female_Plate_OLD
+2606 Equipment H_Female_Armor_Female_Skirt_Leather_OLD
+2601 Equipment H_Female_Armor_Female_Studded_OLD
+
+3601 Equipment H_Female_Armor_Female_Studded_OLD
+3602 Equipment H_Female_Armor_Female_Plate_OLD
+3603 Equipment H_Female_Armor_Female_Leather_OLD
+3604 Equipment H_Female_Armor_Female_Bustier_Leather_OLD
+3605 Equipment H_Female_Armor_Female_Bustier_Studded_OLD
+3606 Equipment H_Female_Armor_Female_Skirt_Leather_OLD
+
+##Female Wearables
+
+#Body Type Model
+
+751 Human H_Savage_Female
+1465 Equipment H_Female_Apron_Full
+1466 Equipment H_Female_Apron_Half
+1554 Equipment H_Female_Armor_Bone_Breastpiece
+1557 Equipment H_Female_Armor_Bone_Gloves
+1562 Equipment H_Female_Armor_Bone_Helm
+1555 Equipment H_Female_Armor_Bone_Leggings
+1556 Equipment H_Female_Armor_Bone_Sleeves
+1561 Equipment H_Female_Armor_Chain_Coif
+1540 Equipment H_Female_Armor_Chain_Leggings
+1538 Equipment H_Female_Armor_Chain_Shirt
+1680 Equipment H_Female_Armor_Dragon_Breastpiece
+1681 Equipment H_Female_Armor_Dragon_Gloves
+1682 Equipment H_Female_Armor_Dragon_Head_Helm
+1683 Equipment H_Female_Armor_Dragon_Leggings
+1679 Equipment H_Female_Armor_Dragon_Sleeves
+1924 Equipment H_Female_Armor_Female_Bustier_Leather
+1925 Equipment H_Female_Armor_Female_Bustier_Studded
+1923 Equipment H_Female_Armor_Female_Leather
+1922 Equipment H_Female_Armor_Female_Plate
+1927 Equipment H_Female_Armor_Female_Shorts_Spiked
+1926 Equipment H_Female_Armor_Female_Skirt_Leather
+1921 Equipment H_Female_Armor_Female_Studded
+1929 Equipment H_Female_Armor_Head_Bascinet
+1928 Equipment H_Female_Armor_Head_Close_Helm
+1565 Equipment H_Female_Armor_Head_Helmet
+1564 Equipment H_Female_Armor_Head_Norse_Helm
+1973 Equipment H_Female_Armor_Head_Orc_Helm
+1743 Equipment H_Female_Armor_Head_Winged_Helmet
+1675 Equipment H_Female_Armor_Japanese_Do-Maru
+1694 Equipment H_Female_Armor_Japanese_Hachimaki
+1678 Equipment H_Female_Armor_Japanese_Haidate
+1695 Equipment H_Female_Armor_Japanese_Haramaki-Do
+1672 Equipment H_Female_Armor_Japanese_Kabuto
+1674 Equipment H_Female_Armor_Japanese_Kabuto_Mempo
+1698 Equipment H_Female_Armor_Japanese_Kobakama
+1677 Equipment H_Female_Armor_Japanese_Kote_Gloves
+1676 Equipment H_Female_Armor_Japanese_Kote_Sleeves
+1697 Equipment H_Female_Armor_Japanese_Kote2_Gloves
+1696 Equipment H_Female_Armor_Japanese_Kote2_Sleeves
+1699 Equipment H_Female_Armor_Japanese_Waraji
+1560 Equipment H_Female_Armor_Leather_Cap
+1545 Equipment H_Female_Armor_Leather_Gloves
+1546 Equipment H_Female_Armor_Leather_Gorget
+1543 Equipment H_Female_Armor_Leather_Leggings
+1544 Equipment H_Female_Armor_Leather_Sleeves
+1524 Equipment H_Female_Armor_Leather_Studded_Gloves
+1525 Equipment H_Female_Armor_Leather_Studded_Gorget
+1522 Equipment H_Female_Armor_Leather_Studded_Leggings
+1523 Equipment H_Female_Armor_Leather_Studded_Sleeves
+1521 Equipment H_Female_Armor_Leather_Studded_Tunic
+1542 Equipment H_Female_Armor_Leather_Tunic
+1527 Equipment H_Female_Armor_Plate_Breastpiece
+1530 Equipment H_Female_Armor_Plate_Gauntlets
+1531 Equipment H_Female_Armor_Plate_Gorget
+1563 Equipment H_Female_Armor_Plate_Helm
+1529 Equipment H_Female_Armor_Plate_Leggings
+1528 Equipment H_Female_Armor_Plate_Sleeves
+1549 Equipment H_Female_Armor_Ring_Leggings
+1550 Equipment H_Female_Armor_Ring_Sleeves
+1548 Equipment H_Female_Armor_Ring_Tunic
+1477 Equipment H_Female_Boots
+1476 Equipment H_Female_Boots_Thigh
+1495 Equipment H_Female_Bracelet_Gold
+1508 Equipment H_Female_Bracelet_Silver
+1468 Equipment H_Female_Cloak
+1448 Equipment H_Female_Dress_Fancy
+1687 Equipment H_Female_Dress_Fancy_2
+1688 Equipment H_Female_Dress_Fancy_3
+1447 Equipment H_Female_Dress_Long
+1496 Equipment H_Female_Ear_Ring_Gold
+1509 Equipment H_Female_Ear_Ring_Silver
+1712 Equipment H_Female_Hair_Buns
+1900 Equipment H_Female_Hair_Curly
+1701 Equipment H_Female_Hair_Long
+1703 Equipment H_Female_Hair_Mohawk
+1710 Equipment H_Female_Hair_Pageboy
+1902 Equipment H_Female_Hair_Pig_Tails
+1702 Equipment H_Female_Hair_Ponytail
+1901 Equipment H_Female_Hair_Receding
+1700 Equipment H_Female_Hair_Short
+1903 Equipment H_Female_Hair_Topknot
+1492 Equipment H_Female_Hat_Bandana
+1410 Equipment H_Female_Hat_Bonnet
+1406 Equipment H_Female_Hat_Cap
+1411 Equipment H_Female_Hat_Feathered
+1742 Equipment H_Female_Hat_Feathers_Leaves
+1404 Equipment H_Female_Hat_Floppy
+1413 Equipment H_Female_Hat_Jester
+1740 Equipment H_Female_Hat_Robin_Hood
+1419 Equipment H_Female_Hat_Skullcap
+1408 Equipment H_Female_Hat_Straw
+1407 Equipment H_Female_Hat_Straw_Tall
+1412 Equipment H_Female_Hat_Tricorner
+1405 Equipment H_Female_Hat_Wide_Brim
+1409 Equipment H_Female_Hat_Wizard
+1455 Equipment H_Female_Kilt
+1690 Equipment H_Female_Kimono
+1414 Equipment H_Female_Mask_Bear
+1415 Equipment H_Female_Mask_Deer
+1713 Equipment H_Female_Mask_Feathered
+1692 Equipment H_Female_Mask_Ninja
+1416 Equipment H_Female_Mask_Orc
+1417 Equipment H_Female_Mask_Tribal_1
+1418 Equipment H_Female_Mask_Tribal_2
+1493 Equipment H_Female_Necklace_Bead
+1497 Equipment H_Female_Necklace_Gold
+1494 Equipment H_Female_Necklace_Gold_Bead
+1510 Equipment H_Female_Necklace_Silver
+1507 Equipment H_Female_Necklace_Silver_Bead
+1715 Equipment H_Female_Pants_Jester
+1431 Equipment H_Female_Pants_Long
+1693 Equipment H_Female_Pants_Ninja
+1430 Equipment H_Female_Pants_Short
+1498 Equipment H_Female_Ring_Gold
+1511 Equipment H_Female_Ring_Silver
+1469 Equipment H_Female_Robe_CowlDown
+1732 Equipment H_Female_Robe_CowlUp
+1731 Equipment H_Female_Robe_Deathshroud
+1987 Equipment H_Female_Robe_GM
+1490 Equipment H_Female_Sash
+1733 Equipment H_Female_Shirt_1
+1734 Equipment H_Female_Shirt_2
+1735 Equipment H_Female_Shirt_5
+1736 Equipment H_Female_Shirt_6
+1911 Equipment H_Female_Shirt_Checkered
+1913 Equipment H_Female_Shirt_Doublet
+1435 Equipment H_Female_Shirt_Fancy
+1912 Equipment H_Female_Shirt_Jester
+1691 Equipment H_Female_Shirt_Ninja
+1434 Equipment H_Female_Shirt_Sleeveless
+1910 Equipment H_Female_Shirt_Surcoat
+1909 Equipment H_Female_Shirt_Tunic
+1480 Equipment H_Female_Shoes
+1716 Equipment H_Female_Shoes_Jester
+1479 Equipment H_Female_Shoes_Sandals
+1449 Equipment H_Female_Skirt_Long
+1971 Equipment H_Female_Skirt_Medium
+1759 Equipment H_Female_Cloak_Arcane
+1760 Equipment H_Female_Gloves_Arcane
+1761 Equipment H_Female_Robe_Arcane
+1762 Equipment H_Female_Boots_Arcane
+
+##Carryables
+
+#Body Type Model
+
+584 Equipment Weapon_daemon_sword
+585 Equipment Weapon_ettin_hammer
+586 Equipment Weapon_liche_staff
+587 Equipment Weapon_lizard_man_mace
+588 Equipment Weapon_lizard_man_spear
+589 Equipment Weapon_ogre_club
+590 Equipment Weapon_Ophidian_mage_staff
+591 Equipment Weapon_Ophidian_warrior_bardiche
+592 Equipment Weapon_orc_club
+593 Equipment Weapon_ratman_axe
+594 Equipment Weapon_ratman_sword
+595 Equipment Weapon_skeleton_axe
+596 Equipment Weapon_skeleton_scimitar
+597 Equipment Weapon_Terathen_mage_staff
+744 Equipment Weapon_Terathen_Avenger_mace
+598 Equipment Weapon_Terathen_Avenger_spear
+599 Equipment Weapon_troll_axe
+600 Equipment Weapon_troll_maul
+601 Equipment Weapon_frost_troll_club
+602 Equipment Weapon_orc_lord_battle_axe
+603 Equipment Weapon_orc_shaman_staff
+604 Equipment Weapon_skeleton_mage_staff
+972 Equipment Fishing_Rod
+502 Equipment Light_Candle_Lit
+505 Equipment Light_Candle_Unlit
+500 Equipment Light_Lantern_Lit
+503 Equipment Light_Lantern_Unlit
+501 Equipment Light_Torch_Lit
+504 Equipment Light_Torch_Unlit
+577 Equipment Shield_Bronze
+579 Equipment Shield_Buckler
+993 Equipment Shield_Chaos
+581 Equipment Shield_Heater
+992 Equipment Shield_Order
+582 Equipment Shield_Roman
+576 Equipment Shield_Round
+578 Equipment Shield_Wooden
+580 Equipment Shield_Wooden_Kite
+985 Equipment Spell_book_1
+984 Equipment Spell_book_2
+668 Equipment Staff_Magic_1
+669 Equipment Staff_Magic_2
+670 Equipment Staff_Magic_3
+671 Equipment Staff_Magic_4
+980 Equipment Wand_1
+981 Equipment Wand_2
+982 Equipment Wand_3
+983 Equipment Wand_4
+653 Equipment Weapon_Axe
+611 Equipment Weapon_Axe_2H
+634 Equipment Weapon_Axe_Double
+614 Equipment Weapon_Bardiche
+615 Equipment Weapon_Battle_Axe
+617 Equipment Weapon_Black_Staff
+649 Equipment Weapon_Bow
+629 Equipment Weapon_Butcher_Knife
+619 Equipment Weapon_Cleaver
+620 Equipment Weapon_Club
+621 Equipment Weapon_Crook
+651 Equipment Weapon_Crossbow
+616 Equipment Weapon_Crossbow_Heavy
+623 Equipment Weapon_Cutlass
+622 Equipment Weapon_Dagger
+613 Equipment Weapon_Executioner_Axe
+628 Equipment Weapon_Gnarled_Staff
+624 Equipment Weapon_Halberd
+640 Equipment Weapon_Hammer_Sledge
+745 Equipment Weapon_Hammer_Smyth
+625 Equipment Weapon_Hammer_Pick
+654 Equipment Weapon_Hatchet
+661 Equipment Weapon_Japanese_Longbow
+626 Equipment Weapon_Javelin
+627 Equipment Weapon_Katana
+630 Equipment Weapon_Kryss
+612 Equipment Weapon_Large_Battle_Axe
+631 Equipment Weapon_Mace
+655 Equipment Weapon_Magic_Sword_1
+656 Equipment Weapon_Magic_Sword_2
+657 Equipment Weapon_Magic_Sword_3
+658 Equipment Weapon_Magic_Sword_4
+633 Equipment Weapon_Maul
+659 Equipment Weapon_Naginata
+660 Equipment Weapon_No-Dachi
+662 Equipment Weapon_Pick
+635 Equipment Weapon_Pickaxe
+636 Equipment Weapon_Pitch_Fork
+648 Equipment Weapon_Quarter_Staff
+637 Equipment Weapon_Scimitar
+638 Equipment Weapon_Skinning_Knife
+641 Equipment Weapon_Spear
+663 Equipment Weapon_Spear_2
+639 Equipment Weapon_Spear_Short
+664 Equipment Weapon_Sword
+618 Equipment Weapon_Sword_Broad
+665 Equipment Weapon_Sword_Long
+666 Equipment Weapon_Sword_Short
+643 Equipment Weapon_Sword_Viking
+644 Equipment Weapon_War_Axe
+645 Equipment Weapon_War_Fork
+646 Equipment Weapon_War_Hammer
+642 Equipment Weapon_War_Mace
+
+##Creatures
+
+#Body Type Model
+
+187 Animals ridgeback_ridgeback
+193 Animals ridgeback_ridgeback_ethereal
+188 Animals ridgeback_savage
+787 Monsters ant_lion
+157 Monsters arachnids_spider_black_widow
+173 Monsters arachnids_spider_black_widow
+11 Monsters arachnids_spider_dread
+19 Monsters arachnids_spider_dread
+20 Monsters arachnids_spider_frost
+28 Monsters arachnids_spider_giant
+28 Monsters arachnids_spider_giant
+28 Monsters arachnids_spider_giant
+779 Monsters bogling
+780 Monsters bog_thing
+232 Animals bovines_bull_brown
+233 Animals bovines_bull_spotted
+216 Animals bovines_cow_brown
+231 Animals bovines_cow_spotted
+211 Animals bruins_bear_black
+211 Animals bruins_bear_black
+167 Animals bruins_bear_brown
+212 Animals bruins_bear_grizzly
+212 Animals bruins_bear_grizzly
+213 Animals bruins_bear_polar
+213 Animals bruins_bear_polar
+217 Animals canines_dog_hound
+97 Animals canines_hell_hound
+98 Animals canines_hell_hound
+225 Animals canines_wolf_timber
+99 Animals canines_wolf_dark
+23 Animals canines_wolf_dire
+25 Animals canines_wolf_grey
+27 Animals canines_wolf_grey
+100 Animals canines_wolf_silver
+34 Animals canines_wolf_white
+37 Animals canines_wolf_white
+101 Monsters centaurs_centaur
+792 Monsters chaos_demon
+786 Monsters chariot
+756 Monsters clockwork_overseer
+757 Monsters clockwork_minion
+763 Monsters clockwork_minion
+75 Monsters cyclops_cyclops
+9 Monsters daemons_daemon
+10 Monsters daemons_daemon
+9 Monsters daemons_daemon
+9 Monsters daemons_daemon
+38 Monsters daemons_daemon_black_gate
+40 Monsters daemons_daemon_elder
+102 Monsters daemons_daemon_exodus
+43 Monsters daemons_daemon_ice_fiend
+774 Monsters Dawn_Girl
+237 Animals deer_doe
+237 Animals deer_doe
+234 Animals deer_stag
+234 Animals deer_stag
+151 Sea dolphins_dolphin
+103 Monsters dragons_dragon_asian
+12 Monsters dragons_dragon_retro_grey
+172 Monsters dragons_dragon_retro_red
+59 Monsters dragons_dragon_retro_red
+49 Monsters dragons_wyrm_retro_white
+180 Monsters dragons_wyrm_retro_white
+60 Monsters dragons_dragon_retro_grey
+61 Monsters dragons_dragon_retro_red
+105 Monsters dragons_wyrm_ancient
+46 Monsters Mf_Dragon_Rust
+106 Monsters dragons_wyrm_shadow
+104 Monsters dragons_dragon_skeletal
+62 Monsters dragons_wyvern
+14 Monsters elementals_earth_elemental
+14 Monsters elementals_earth_elemental
+107 Monsters elementals_agapite_elemental
+108 Monsters elementals_bronze_elemental
+109 Monsters elementals_copper_elemental
+110 Monsters elementals_copper_dull_elemental
+166 Monsters elementals_gold_elemental
+111 Monsters elementals_iron_elemental
+112 Monsters elementals_valorite_elemental
+113 Monsters elementals_verite_elemental
+158 Monsters elementals_acid_elemental
+13 Monsters elementals_air_elemental
+13 Monsters elementals_air_elemental
+13 Monsters elementals_air_elemental
+159 Monsters elementals_blood_elemental
+160 Monsters elementals_blood_elemental
+15 Monsters elementals_fire_elemental
+15 Monsters elementals_fire_elemental
+15 Monsters elementals_fire_elemental
+161 Monsters elementals_ice_elemental
+162 Monsters elementals_poison_elemental
+163 Monsters elementals_snow_elemental
+16 Monsters elementals_water_elemental
+16 Monsters elementals_water_elemental
+164 Monsters ethereals_energy_vortex
+165 Monsters ethereals_wisp
+58 Monsters ethereals_wisp
+58 Monsters ethereals_wisp
+200 Animals equines_horse_dappled_brown
+200 Animals equines_horse_dappled_brown
+190 Animals equines_horse_firesteed
+820 Animals equines_horse_dappled_brown
+291 Animals equines_horse_dappled_brown_pack
+226 Animals equines_horse_dappled_grey
+226 Animals equines_horse_dappled_grey
+226 Animals equines_horse_dappled_grey
+846 Animals equines_horse_dappled_grey
+204 Animals equines_horse_dark_brown
+204 Animals equines_horse_dark_brown
+824 Animals equines_horse_dark_brown
+228 Animals equines_horse_tan
+228 Animals equines_horse_tan
+848 Animals equines_horse_tan
+114 Animals equines_horse_dark_steed
+115 Animals equines_horse_ethereal
+116 Animals equines_horse_nightmare
+177 Animals equines_horse_nightmare
+178 Animals equines_horse_nightmare
+179 Animals equines_horse_nightmare
+117 Animals equines_horse_silver_steed
+118 Animals equines_horse_war_brittanian
+119 Animals equines_horse_war_mage_council
+120 Animals equines_horse_war_minax
+121 Animals equines_horse_war_shadowlord
+122 Animals equines_unicorn
+192 Animals equines_unicorn_ethereal
+123 Monsters ethereal_warriors_male
+175 Monsters ethereal_warriors_male
+2 Monsters ettins_ettin
+18 Monsters ettins_ettin
+63 Animals felines_cougar
+64 Animals felines_leopard_snow
+65 Animals felines_leopard_snow
+214 Animals felines_panther
+127 Animals felines_predator_hellcat
+128 Monsters fey_race_pixie
+176 Monsters fey_race_pixie
+781 Monsters fire_ant_worker
+782 Monsters fire_ant_warrior
+783 Monsters fire_ant_queen
+804 Monsters fire_ant_matriarch
+805 Monsters black_ant_worker
+806 Monsters black_ant_warrior
+807 Monsters black_ant_queen
+808 Monsters black_ant_matriarch
+8 Monsters flails_corpser
+47 Monsters flails_reaper
+66 Monsters flails_swamp_tentacles
+129 Monsters flails_swamp_tentacles
+80 Monsters frogs_frog_giant
+4 Monsters gargoyles_gargoyle
+130 Monsters gargoyles_gargoyle_blistering
+67 Monsters gargoyles_gargoyle_stone
+753 Monsters gargoyles_gargoyle_slave
+754 Monsters gargoyles_gargoyle_enforcer
+755 Monsters gargoyles_gargoyle_guard
+758 Monsters gargoyles_gargoyle_shopkeeper
+22 Monsters gazers_gazer
+68 Monsters gazers_gazer_elder
+69 Monsters gazers_gazer_elder
+131 Monsters genies_efreet
+791 Animals giant_beetle
+195 Animals giant_beetle_ethereal
+752 Monsters golem_iron
+29 Animals gorillas_silverback
+29 Animals gorillas_silverback
+30 Monsters harpies_harpy
+73 Monsters harpies_harpy_stone
+31 Monsters headless_headless
+776 Monsters horde_demon
+795 Monsters horde_demon
+796 Monsters horde_demon
+74 Monsters imps_imp
+168 Monsters imps_shadow_fiend
+764 Monsters Juka_Warrior
+765 Monsters Juka_Mage
+768 Monsters Juggernaut
+132 Animals kirin_kirin
+191 Animals kirin_kirin_ethereal
+998 Monsters kirin_kirin
+77 Monsters krakens_kraken
+24 Monsters liche_liche_retro
+24 Monsters liche_liche_retro
+78 Monsters liche_liche_lord_retro
+79 Monsters liche_liche_lord_retro
+82 Monsters liche_liche_lord_retro
+33 Monsters lizard_race_lizardman
+35 Monsters lizard_race_lizardman
+36 Monsters lizard_race_lizardman
+202 Animals lizards_alligator_brown
+202 Animals lizards_alligator_brown
+133 Animals lizards_alligator_small
+134 Animals lizards_komodo_dragon
+206 Monsters lizards_lava_lizard
+220 Animals llamas_llama
+828 Animals llamas_llama
+828 Animals llamas_llama
+828 Animals llamas_llama
+170 Animals llamas_llama_ethereal
+292 Animals llamas_llama_pack
+124 Monsters mages_evil_mage
+125 Monsters mages_evil_mage_master
+126 Monsters mages_evil_mage_master
+770 Monsters Meer_Mage
+771 Monsters Meer_Warrior
+797 Monsters mf_dragon_fire
+798 Monsters mf_dragon_rust
+39 Monsters mongbats_mongbat
+39 Monsters mongbats_mongbat
+39 Monsters mongbats_mongbat
+39 Monsters mongbats_mongbat
+766 Monsters NPC_Kabur
+767 Monsters NPC_Blackthorn_Cohort
+769 Monsters NPC_Blackthorn
+772 Monsters NPC_Adranath
+773 Monsters NPC_Cpt_Dasha
+1 Monsters ogres_ogre
+1 Monsters ogres_ogre
+83 Monsters ogres_ogre_lord
+84 Monsters ogres_ogre_lord
+135 Monsters ogres_ogre_lord_arctic
+136 Monsters ophidians_ophidian_archmage
+137 Monsters ophidians_ophidian_knight
+85 Monsters ophidians_ophidian_mage
+87 Monsters ophidians_ophidian_queen
+86 Monsters ophidians_ophidian_warrior
+17 Monsters orcs_orc
+41 Monsters orcs_orc
+7 Monsters orcs_orc_captain
+7 Monsters orcs_orc_captain
+7 Monsters orcs_orc_captain
+138 Monsters orcs_orc_lord
+139 Monsters orcs_orc_lord
+140 Monsters orcs_orc_shaman
+181 Monsters orcs_orc_scout
+182 Monsters orcs_orc_bomber
+189 Monsters orcs_orc_lord
+210 Animals ostards_ostard_desert
+825 Animals ostards_ostard_desert
+218 Animals ostards_ostard_forest
+826 Animals ostards_ostard_forest
+219 Animals ostards_ostard_frenzied
+827 Animals ostards_ostard_frenzied
+171 Animals ostards_ostard_ethereal
+141 Monsters paladins_paladin
+775 Monsters plague_beast
+290 Animals porcines_boar
+203 Animals porcines_pig
+203 Animals porcines_pig
+42 Monsters rat_race_ratman
+44 Monsters rat_race_ratman
+45 Monsters rat_race_ratman
+142 Monsters rat_race_ratman
+143 Monsters rat_race_shaman
+215 Monsters rodents_rat_giant
+215 Monsters rodents_rat_giant
+839 Animals ridgeback_ridgeback
+840 Animals ridgeback_giant
+841 Animals ridgeback_flame
+842 Animals ridgeback_hatchling
+209 Animals ruminants_goat_billy
+88 Animals ruminants_goat_mountain
+207 Animals ruminants_sheep
+223 Animals ruminants_sheep_shorn
+790 Monsters sand_vortex
+48 Monsters scorpions_giant
+48 Monsters scorpions_giant
+144 Sea sea_horse_sea_horse
+150 Sea sea_serpents_sea_serpent
+145 Sea sea_serpents_sea_serpent
+21 Monsters serpents_snake_giant
+21 Monsters serpents_snake_giant
+89 Monsters serpents_snake_giant_ice
+90 Monsters serpents_snake_giant_lava
+91 Monsters serpents_snake_giant_silver
+92 Monsters serpents_snake_giant_silver
+93 Monsters serpents_snake_giant_silver
+146 Monsters shadowlords_shadowlord
+793 Animals skeletal_mount
+50 Monsters skeletons_skeleton
+56 Monsters skeletons_skeleton
+57 Monsters skeletons_skeleton
+147 Monsters skeletons_skeleton_knight
+148 Monsters skeletons_skeleton_mage
+51 Monsters slimes_slime
+51 Monsters slimes_slime
+94 Monsters slimes_slime_frost
+96 Monsters slimes_slime_frost
+574 Monsters spirits_blade_spirit
+26 Monsters spirits_ghost
+26 Monsters spirits_ghost
+26 Monsters spirits_ghost
+149 Monsters succubi_succubus
+174 Monsters succubi_succubus
+794 Animals swamp_dragon
+194 Animals swamp_dragon_ethereal
+799 Animals swamp_dragon_armor
+778 Monsters swarm
+152 Monsters terathan_terathan_avenger
+71 Monsters terathan_terathan_drone
+72 Monsters terathan_terathan_queen
+70 Monsters terathan_terathan_warrior
+76 Monsters titans_titan
+53 Monsters trolls_troll
+54 Monsters trolls_troll
+55 Monsters trolls_troll_frost
+153 Monsters walking_dead_ghoul
+154 Monsters walking_dead_mummy
+155 Monsters walking_dead_rotting_corpse
+3 Monsters walking_dead_zombie
+3 Monsters walking_dead_zombie
+221 Animals walrus_walrus_male
+221 Animals walrus_walrus_male
+
+##New 3D Critters (Replaces 2D Bitmaps)
+
+#Body Type Model
+
+5 Animals birds_eagle
+5 Animals birds_eagle
+6 Animals birds_generic
+6 Animals birds_generic
+6 Animals birds_generic
+6 Animals birds_generic
+831 Animals birds_parrot
+832 Animals birds_pheonix
+833 Animals birds_turkey
+834 Animals felines_hellcat
+201 Animals felines_housecat
+208 Animals fowl_normal_hen
+208 Animals fowl_normal_hen
+81 Animals frogs_bullfrog
+205 Animals rodents_rabbit_cottontail
+835 Animals rodents_rabbit_jack
+205 Animals rodents_rabbit_cottontail
+238 Animals rodents_rat_sewer
+843 Animals rodents_rat_town
+52 Animals serpents_snake
+837 Animals serpents_snake_ice
+838 Animals serpents_snake_lava
+
+##Age of Shadows Stuff
+
+#Body Type Model
+
+300 Monsters crystal_elemental
+301 Monsters treefellow
+302 Monsters skittering_hopper
+303 Monsters devourer
+304 Monsters flesh_golem
+305 Monsters gore_fiend
+306 Monsters impaler
+307 Monsters gibberling
+308 Monsters bonedemon
+309 Monsters patchskeleton
+310 Monsters wailingbanshee
+311 Monsters shadow_knight
+312 Monsters abysmal_horror
+313 Monsters Darknight_Creeper
+314 Monsters ravager
+315 Monsters flesh_renderer
+316 Monsters wander
+317 Monsters vampire_bat
+318 Monsters demon_knight
+319 Monsters mound_of_maggots
+
+777 Monsters doppleganger
+784 Monsters arcane_demon
+785 Monsters four_armed_demon
+788 Monsters sphinx
+789 Monsters quagmire
+
+930 Equipment Weapon_Scythe
+931 Equipment Weapon_Bone_Harvester
+932 Equipment Weapon_Scepter
+933 Equipment Weapon_Bladed_Staff
+934 Equipment Weapon_Pike
+935 Equipment Weapon_Double_Bladed_Staff
+936 Equipment Weapon_Lance
+937 Equipment Weapon_Crescent_Blade
+938 Equipment Weapon_Composite_Bow
+939 Equipment Weapon_Repeating_Crossbow
+940 Equipment Weapon_Paladin_Sword
+
+
+##Japanese Wearables Contest Stuff
+
+#Body Type Model
+
+481 Equipment H_Male_Hat_Bandana
+482 Equipment H_Male_Boots
+483 Equipment H_Male_Cloak
+484 Equipment H_Male_Kilt
+485 Equipment H_Male_Dress_Fancy
+486 Equipment H_Male_Shirt_Tunic
+
+1481 Equipment H_Female_Hat_Bandana
+1482 Equipment H_Female_Boots
+1483 Equipment H_Female_Cloak
+1484 Equipment H_Female_Kilt
+1485 Equipment H_Female_Dress_Fancy
+1486 Equipment H_Female_Shirt_Tunic
\ No newline at end of file
diff --git a/Data/shrink.cfg b/Data/shrink.cfg
index ea35a785a..c1a9d0988 100644
--- a/Data/shrink.cfg
+++ b/Data/shrink.cfg
@@ -360,4 +360,7 @@
276 0x2D95
277 0x2D96
-1254 0x9844
+#SA Mobiles
+
+1254 0x9844
+1255 0x9844
\ No newline at end of file
diff --git a/README.md b/README.md
index aa84a359a..47dc4136e 100644
--- a/README.md
+++ b/README.md
@@ -9,12 +9,12 @@ RunUO Git Repository
Typical Windows Build
-PS C:\runuo> C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc /optimize /unsafe /t:exe /out:RunUO.exe /win32icon:Server\runuo.ico /recurse:Server\\*.cs
+PS C:\runuo> C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc /optimize /unsafe /t:exe /out:RunUO.exe /win32icon:Server\runuo.ico /d:NEWTIMERS /d:NEWPARENT /recurse:Server\\*.cs
Typical Linux Build (MONO)
-~/runuo$ mcs -optimize+ -unsafe -t:exe -out:RunUO.exe -win32icon:Server/runuo.ico -nowarn:219,414 -d:MONO -recurse:Server/*.cs
+~/runuo$ mcs -optimize+ -unsafe -t:exe -out:RunUO.exe -win32icon:Server/runuo.ico -nowarn:219,414 -d:NEWTIMERS -d:NEWPARENT -d:MONO -recurse:Server/*.cs
zlib is required for certain functionality. Windows zlib builds are packaged with releases and can also be obtained separately here: https://github.com/msturgill/zlib/releases/latest
diff --git a/RunUO.sln b/RunUO.sln
index 97cfc65fa..403fb7556 100644
--- a/RunUO.sln
+++ b/RunUO.sln
@@ -1,21 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2013
-VisualStudioVersion = 12.0.21005.1
-MinimumVisualStudioVersion = 10.0.40219.1
+# Visual Studio 2012
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Server", "Server\Server.csproj", "{0B33CEEB-88E1-49A6-8D7D-AF6A5A357087}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Scripts", "Scripts\Scripts.csproj", "{DAE872E6-6899-427C-A75D-AD52526EBCDA}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Data", "Data", "{1B394627-C6BF-447D-8CBD-4A3B5262C5B4}"
ProjectSection(SolutionItems) = preProject
- Data\Assemblies_4_0.cfg = Data\Assemblies_4_0.cfg
+ Data\Assemblies.cfg = Data\Assemblies.cfg
Data\bodyTable.cfg = Data\bodyTable.cfg
Data\Common.map = Data\Common.map
Data\containers.cfg = Data\containers.cfg
Data\items.cfg = Data\items.cfg
Data\MLQuests.cfg = Data\MLQuests.cfg
Data\mobiles.cfg = Data\mobiles.cfg
+ Data\models.txt = Data\models.txt
Data\names.xml = Data\names.xml
Data\objects.xml = Data\objects.xml
Data\pageresponse.cfg = Data\pageresponse.cfg
diff --git a/RunUO.vshost.exe.config b/RunUO.vshost.exe.config
new file mode 100644
index 000000000..5106eb6a4
--- /dev/null
+++ b/RunUO.vshost.exe.config
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/RunUO.vshost.exe.manifest b/RunUO.vshost.exe.manifest
new file mode 100644
index 000000000..f96b1d6b3
--- /dev/null
+++ b/RunUO.vshost.exe.manifest
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Scripts/Accounting/Account.cs b/Scripts/Accounting/Account.cs
index 7479257fe..f776d3871 100644
--- a/Scripts/Accounting/Account.cs
+++ b/Scripts/Accounting/Account.cs
@@ -1,12 +1,15 @@
using System;
using System.Collections;
using System.Collections.Generic;
+using System.Linq;
using System.Net;
using System.Security;
using System.Security.Cryptography;
using System.Text;
using System.Xml;
using Server;
+using Server.Commands;
+using Server.Items;
using Server.Misc;
using Server.Mobiles;
using Server.Multis;
@@ -19,10 +22,140 @@ namespace Server.Accounting
public static readonly TimeSpan YoungDuration = TimeSpan.FromHours( 40.0 );
public static readonly TimeSpan InactiveDuration = TimeSpan.FromDays( 180.0 );
-
- public static readonly TimeSpan EmptyInactiveDuration = TimeSpan.FromDays( 30.0 );
- private string m_Username, m_PlainPassword, m_CryptPassword, m_NewCryptPassword;
+ public static readonly TimeSpan EmptyInactiveDuration = TimeSpan.FromDays(30.0);
+
+ public static void Configure()
+ {
+ CommandSystem.Register("ConvertCurrency", AccessLevel.Owner, ConvertCurrency);
+ }
+
+ private static void ConvertCurrency(CommandEventArgs e)
+ {
+ e.Mobile.SendMessage(
+ "Converting All Banked Gold from {0} to {1}. Please wait...",
+ AccountGold.Enabled ? "checks and coins" : "account treasury",
+ AccountGold.Enabled ? "account treasury" : "checks and coins");
+
+ NetState.Pause();
+
+ double found = 0.0, converted = 0.0;
+
+ try
+ {
+ BankBox box;
+ List gold;
+ List checks;
+ long share = 0, shared;
+ int diff;
+
+ foreach (var a in Accounts.GetAccounts().OfType().Where(a => a.Count > 0))
+ {
+ try
+ {
+ if (!AccountGold.Enabled)
+ {
+ share = (int)Math.Truncate((a.TotalCurrency / a.Count) * CurrencyThreshold);
+ found += a.TotalCurrency * CurrencyThreshold;
+ }
+
+ foreach (var m in a.m_Mobiles.Where(m => m != null))
+ {
+ box = m.FindBankNoCreate();
+
+ if (box == null)
+ {
+ continue;
+ }
+
+ if (AccountGold.Enabled)
+ {
+ foreach (var o in checks = box.FindItemsByType())
+ {
+ found += o.Worth;
+
+ if (!a.DepositGold(o.Worth))
+ {
+ break;
+ }
+
+ converted += o.Worth;
+ o.Delete();
+ }
+
+ checks.Clear();
+ checks.TrimExcess();
+
+ foreach (var o in gold = box.FindItemsByType())
+ {
+ found += o.Amount;
+
+ if (!a.DepositGold(o.Amount))
+ {
+ break;
+ }
+
+ converted += o.Amount;
+ o.Delete();
+ }
+
+ gold.Clear();
+ gold.TrimExcess();
+ }
+ else
+ {
+ shared = share;
+
+ while (shared > 0)
+ {
+ if (shared > 60000)
+ {
+ diff = (int)Math.Min(10000000, shared);
+
+ if (a.WithdrawGold(diff))
+ {
+ box.DropItem(new BankCheck(diff));
+ }
+ else
+ {
+ break;
+ }
+ }
+ else
+ {
+ diff = (int)Math.Min(60000, shared);
+
+ if (a.WithdrawGold(diff))
+ {
+ box.DropItem(new Gold(diff));
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ converted += diff;
+ shared -= diff;
+ }
+ }
+
+ box.UpdateTotals();
+ }
+ }
+ catch
+ { }
+ }
+ }
+ catch
+ { }
+
+ NetState.Resume();
+
+ e.Mobile.SendMessage("Operation complete: {0:#,0} of {1:#,0} Gold has been converted in total.", converted, found);
+ }
+
+ private string m_Username, m_Email, m_PlainPassword, m_CryptPassword, m_NewCryptPassword;
private AccessLevel m_AccessLevel;
private int m_Flags;
private DateTime m_Created, m_LastLogin;
@@ -115,6 +248,15 @@ namespace Server.Accounting
set { m_Username = value; }
}
+ ///
+ /// Account email address.
+ ///
+ public string Email
+ {
+ get { return m_Email; }
+ set { m_Email = value; }
+ }
+
///
/// Account password. Plain text. Case sensitive validation. May be null.
///
@@ -673,6 +815,8 @@ namespace Server.Accounting
m_Flags = Utility.GetXMLInt32( Utility.GetText( node["flags"], "0" ), 0 );
m_Created = Utility.GetXMLDateTime( Utility.GetText( node["created"], null ), DateTime.UtcNow );
m_LastLogin = Utility.GetXMLDateTime( Utility.GetText( node["lastLogin"], null ), DateTime.UtcNow );
+
+ TotalCurrency = Utility.GetXMLDouble( Utility.GetText(node["totalCurrency"], "0" ), 0 );
m_Mobiles = LoadMobiles( node );
m_Comments = LoadComments( node );
@@ -1100,6 +1244,10 @@ namespace Server.Accounting
xml.WriteEndElement();
}
+ xml.WriteStartElement("totalCurrency");
+ xml.WriteString(XmlConvert.ToString(TotalCurrency));
+ xml.WriteEndElement();
+
xml.WriteEndElement();
}
@@ -1203,5 +1351,242 @@ namespace Server.Accounting
throw new ArgumentException();
}
+
+ #region Gold Account
+ ///
+ /// This amount specifies the value at which point Gold turns to Platinum.
+ /// By default, when 1,000,000,000 Gold is accumulated, it will transform
+ /// into 1 Platinum.
+ ///
+ public static int CurrencyThreshold
+ {
+ get { return AccountGold.CurrencyThreshold; }
+ set { AccountGold.CurrencyThreshold = value; }
+ }
+
+ ///
+ /// This amount represents the total amount of currency owned by the player.
+ /// It is cumulative of both Gold and Platinum, the absolute total amount of
+ /// Gold owned by the player can be found by multiplying this value by the
+ /// CurrencyThreshold value.
+ ///
+ [CommandProperty(AccessLevel.Administrator, true)]
+ public double TotalCurrency { get; private set; }
+
+ ///
+ /// This amount represents the current amount of Gold owned by the player.
+ /// The value does not include the value of Platinum and ranges from
+ /// 0 to 999,999,999 by default.
+ ///
+ [CommandProperty(AccessLevel.Administrator)]
+ public int TotalGold
+ {
+ get { return (int)Math.Floor((TotalCurrency - Math.Truncate(TotalCurrency)) * Math.Max(1.0, CurrencyThreshold)); }
+ }
+
+ ///
+ /// This amount represents the current amount of Platinum owned by the player.
+ /// The value does not include the value of Gold and ranges from
+ /// 0 to 2,147,483,647 by default.
+ /// One Platinum represents the value of CurrencyThreshold in Gold.
+ ///
+ [CommandProperty(AccessLevel.Administrator)]
+ public int TotalPlat { get { return (int)Math.Truncate(TotalCurrency); } }
+
+ ///
+ /// Attempts to deposit the given amount of Gold and Platinum into this account.
+ ///
+ /// Amount to deposit.
+ /// True if successful, false if amount given is less than or equal to zero.
+ public bool DepositCurrency(double amount)
+ {
+ if (amount <= 0)
+ {
+ return false;
+ }
+
+ TotalCurrency += amount;
+ return true;
+ }
+
+ ///
+ /// Attempts to deposit the given amount of Gold into this account.
+ /// If the given amount is greater than the CurrencyThreshold,
+ /// Platinum will be deposited to offset the difference.
+ ///
+ /// Amount to deposit.
+ /// True if successful, false if amount given is less than or equal to zero.
+ public bool DepositGold(int amount)
+ {
+ return DepositCurrency(amount / Math.Max(1.0, CurrencyThreshold));
+ }
+
+ ///
+ /// Attempts to deposit the given amount of Gold into this account.
+ /// If the given amount is greater than the CurrencyThreshold,
+ /// Platinum will be deposited to offset the difference.
+ ///
+ /// Amount to deposit.
+ /// True if successful, false if amount given is less than or equal to zero.
+ public bool DepositGold(long amount)
+ {
+ return DepositCurrency(amount / Math.Max(1.0, CurrencyThreshold));
+ }
+
+ ///
+ /// Attempts to deposit the given amount of Platinum into this account.
+ ///
+ /// Amount to deposit.
+ /// True if successful, false if amount given is less than or equal to zero.
+ public bool DepositPlat(int amount)
+ {
+ return DepositCurrency(amount);
+ }
+
+ ///
+ /// Attempts to deposit the given amount of Platinum into this account.
+ ///
+ /// Amount to deposit.
+ /// True if successful, false if amount given is less than or equal to zero.
+ public bool DepositPlat(long amount)
+ {
+ return DepositCurrency(amount);
+ }
+
+ ///
+ /// Attempts to withdraw the given amount of Platinum and Gold from this account.
+ ///
+ /// Amount to withdraw.
+ /// True if successful, false if balance was too low.
+ public bool WithdrawCurrency(double amount)
+ {
+ if (amount <= 0)
+ {
+ return true;
+ }
+
+ if (amount > TotalCurrency)
+ {
+ return false;
+ }
+
+ TotalCurrency -= amount;
+ return true;
+ }
+
+ ///
+ /// Attempts to withdraw the given amount of Gold from this account.
+ /// If the given amount is greater than the CurrencyThreshold,
+ /// Platinum will be withdrawn to offset the difference.
+ ///
+ /// Amount to withdraw.
+ /// True if successful, false if balance was too low.
+ public bool WithdrawGold(int amount)
+ {
+ return WithdrawCurrency(amount / Math.Max(1.0, CurrencyThreshold));
+ }
+
+ ///
+ /// Attempts to withdraw the given amount of Gold from this account.
+ /// If the given amount is greater than the CurrencyThreshold,
+ /// Platinum will be withdrawn to offset the difference.
+ ///
+ /// Amount to withdraw.
+ /// True if successful, false if balance was too low.
+ public bool WithdrawGold(long amount)
+ {
+ return WithdrawCurrency(amount / Math.Max(1.0, CurrencyThreshold));
+ }
+
+ ///
+ /// Attempts to withdraw the given amount of Platinum from this account.
+ ///
+ /// Amount to withdraw.
+ /// True if successful, false if balance was too low.
+ public bool WithdrawPlat(int amount)
+ {
+ return WithdrawCurrency(amount);
+ }
+
+ ///
+ /// Attempts to withdraw the given amount of Platinum from this account.
+ ///
+ /// Amount to withdraw.
+ /// True if successful, false if balance was too low.
+ public bool WithdrawPlat(long amount)
+ {
+ return WithdrawCurrency(amount);
+ }
+
+ ///
+ /// Gets the total balance of Gold for this account.
+ ///
+ /// Gold value, Platinum exclusive
+ /// Gold value, Platinum inclusive
+ public void GetGoldBalance(out int gold, out double totalGold)
+ {
+ gold = TotalGold;
+ totalGold = TotalCurrency * Math.Max(1.0, CurrencyThreshold);
+ }
+
+ ///
+ /// Gets the total balance of Gold for this account.
+ ///
+ /// Gold value, Platinum exclusive
+ /// Gold value, Platinum inclusive
+ public void GetGoldBalance(out long gold, out double totalGold)
+ {
+ gold = TotalGold;
+ totalGold = TotalCurrency * Math.Max(1.0, CurrencyThreshold);
+ }
+
+ ///
+ /// Gets the total balance of Platinum for this account.
+ ///
+ /// Platinum value, Gold exclusive
+ /// Platinum value, Gold inclusive
+ public void GetPlatBalance(out int plat, out double totalPlat)
+ {
+ plat = TotalPlat;
+ totalPlat = TotalCurrency;
+ }
+
+ ///
+ /// Gets the total balance of Platinum for this account.
+ ///
+ /// Platinum value, Gold exclusive
+ /// Platinum value, Gold inclusive
+ public void GetPlatBalance(out long plat, out double totalPlat)
+ {
+ plat = TotalPlat;
+ totalPlat = TotalCurrency;
+ }
+
+ ///
+ /// Gets the total balance of Gold and Platinum for this account.
+ ///
+ /// Gold value, Platinum exclusive
+ /// Gold value, Platinum inclusive
+ /// Platinum value, Gold exclusive
+ /// Platinum value, Gold inclusive
+ public void GetBalance(out int gold, out double totalGold, out int plat, out double totalPlat)
+ {
+ GetGoldBalance(out gold, out totalGold);
+ GetPlatBalance(out plat, out totalPlat);
+ }
+
+ ///
+ /// Gets the total balance of Gold and Platinum for this account.
+ ///
+ /// Gold value, Platinum exclusive
+ /// Gold value, Platinum inclusive
+ /// Platinum value, Gold exclusive
+ /// Platinum value, Gold inclusive
+ public void GetBalance(out long gold, out double totalGold, out long plat, out double totalPlat)
+ {
+ GetGoldBalance(out gold, out totalGold);
+ GetPlatBalance(out plat, out totalPlat);
+ }
+ #endregion
}
}
\ No newline at end of file
diff --git a/Scripts/Gumps/HouseDemolishGump.cs b/Scripts/Gumps/HouseDemolishGump.cs
index fc459a0f1..327b58890 100644
--- a/Scripts/Gumps/HouseDemolishGump.cs
+++ b/Scripts/Gumps/HouseDemolishGump.cs
@@ -1,5 +1,6 @@
using System;
using Server;
+using Server.Accounting;
using Server.Items;
using Server.Multis;
using Server.Multis.Deeds;
@@ -114,6 +115,23 @@ namespace Server.Gumps
toGive = new BankCheck( m_House.Price );
}
+ if (AccountGold.Enabled && toGive is BankCheck)
+ {
+ var worth = ((BankCheck)toGive).Worth;
+
+ if (m_Mobile.Account != null && m_Mobile.Account.DepositGold(worth))
+ {
+ toGive.Delete();
+
+ m_Mobile.SendLocalizedMessage(1060397, worth.ToString("#,0"));
+ // ~1_AMOUNT~ gold has been deposited into your bank box.
+
+ m_House.RemoveKeys(m_Mobile);
+ m_House.Delete();
+ return;
+ }
+ }
+
if ( toGive != null )
{
BankBox box = m_Mobile.BankBox;
diff --git a/Scripts/Items/Misc/BankCheck.cs b/Scripts/Items/Misc/BankCheck.cs
index 16aa604b0..53a3edd44 100644
--- a/Scripts/Items/Misc/BankCheck.cs
+++ b/Scripts/Items/Misc/BankCheck.cs
@@ -1,6 +1,7 @@
using System;
using System.Globalization;
using Server;
+using Server.Accounting;
using Server.Items;
using Server.Mobiles;
using Server.Network;
@@ -79,30 +80,131 @@ namespace Server.Items
list.Add( 1060738, worth ); // value: ~1_val~
}
- public override void OnSingleClick( Mobile from )
+#if NEWPARENT
+ public override void OnAdded(IEntity parent)
+#else
+ public override void OnAdded(object parent)
+#endif
{
- from.Send( new MessageLocalizedAffix( Serial, ItemID, MessageType.Label, 0x3B2, 3, 1041361, "", AffixType.Append, String.Concat( " ", m_Worth.ToString() ), "" ) ); // A bank check:
+ base.OnAdded(parent);
+
+ if (!AccountGold.Enabled)
+ {
+ return;
+ }
+
+ Mobile owner = null;
+ SecureTradeInfo tradeInfo = null;
+
+ Container root = parent as Container;
+
+ while (root != null && root.Parent is Container)
+ {
+ root = (Container)root.Parent;
+ }
+
+ parent = root ?? parent;
+
+ if (parent is SecureTradeContainer && AccountGold.ConvertOnTrade)
+ {
+ var trade = (SecureTradeContainer)parent;
+
+ if (trade.Trade.From.Container == trade)
+ {
+ tradeInfo = trade.Trade.From;
+ owner = tradeInfo.Mobile;
+ }
+ else if (trade.Trade.To.Container == trade)
+ {
+ tradeInfo = trade.Trade.To;
+ owner = tradeInfo.Mobile;
+ }
+ }
+ else if (parent is BankBox && AccountGold.ConvertOnBank)
+ {
+ owner = ((BankBox)parent).Owner;
+ }
+
+ if (owner == null || owner.Account == null || !owner.Account.DepositGold(Worth))
+ {
+ return;
+ }
+
+ if (tradeInfo != null)
+ {
+ if (owner.NetState != null && !owner.NetState.NewSecureTrading)
+ {
+ var total = Worth / Math.Max(1.0, Account.CurrencyThreshold);
+ var plat = (int)Math.Truncate(total);
+ var gold = (int)((total - plat) * Account.CurrencyThreshold);
+
+ tradeInfo.Plat += plat;
+ tradeInfo.Gold += gold;
+ }
+
+ if (tradeInfo.VirtualCheck != null)
+ {
+ tradeInfo.VirtualCheck.UpdateTrade(tradeInfo.Mobile);
+ }
+ }
+
+ owner.SendLocalizedMessage(1042763, Worth.ToString("#,0"));
+
+ Delete();
+
+ ((Container)parent).UpdateTotals();
}
- public override void OnDoubleClick( Mobile from )
+ public override void OnSingleClick(Mobile from)
{
- BankBox box = from.FindBankNoCreate();
+ from.Send(
+ new MessageLocalizedAffix(
+ Serial,
+ ItemID,
+ MessageType.Label,
+ 0x3B2,
+ 3,
+ 1041361,
+ "",
+ AffixType.Append,
+ String.Concat(" ", m_Worth.ToString()),
+ "")); // A bank check:
+ }
- if ( box != null && IsChildOf( box ) )
+ public override void OnDoubleClick(Mobile from)
+ {
+ // This probably isn't OSI accurate, but we can't just make the quests redundant.
+ // Double-clicking the BankCheck in your pack will now credit your account.
+
+ var box = AccountGold.Enabled ? from.Backpack : from.FindBankNoCreate();
+
+ if (box == null || !IsChildOf(box))
{
- Delete();
+ from.SendLocalizedMessage(AccountGold.Enabled ? 1080058 : 1047026);
+ // This must be in your backpack to use it. : That must be in your bank box to use it.
+ return;
+ }
- int deposited = 0;
+ Delete();
- int toAdd = m_Worth;
+ var deposited = 0;
+ var toAdd = m_Worth;
+ if (AccountGold.Enabled && from.Account != null && from.Account.DepositGold(toAdd))
+ {
+ deposited = toAdd;
+ toAdd = 0;
+ }
+
+ if (toAdd > 0)
+ {
Gold gold;
- while ( toAdd > 60000 )
+ while (toAdd > 60000)
{
- gold = new Gold( 60000 );
+ gold = new Gold(60000);
- if ( box.TryDropItem( from, gold, false ) )
+ if (box.TryDropItem(from, gold, false))
{
toAdd -= 60000;
deposited += 60000;
@@ -111,18 +213,18 @@ namespace Server.Items
{
gold.Delete();
- from.AddToBackpack( new BankCheck( toAdd ) );
+ from.AddToBackpack(new BankCheck(toAdd));
toAdd = 0;
break;
}
}
- if ( toAdd > 0 )
+ if (toAdd > 0)
{
- gold = new Gold( toAdd );
+ gold = new Gold(toAdd);
- if ( box.TryDropItem( from, gold, false ) )
+ if (box.TryDropItem(from, gold, false))
{
deposited += toAdd;
}
@@ -130,39 +232,39 @@ namespace Server.Items
{
gold.Delete();
- from.AddToBackpack( new BankCheck( toAdd ) );
- }
- }
-
- // Gold was deposited in your account:
- from.SendLocalizedMessage( 1042672, true, " " + deposited.ToString() );
-
- PlayerMobile pm = from as PlayerMobile;
-
- if ( pm != null )
- {
- QuestSystem qs = pm.Quest;
-
- if ( qs is Necro.DarkTidesQuest )
- {
- QuestObjective obj = qs.FindObjective( typeof( Necro.CashBankCheckObjective ) );
-
- if ( obj != null && !obj.Completed )
- obj.Complete();
- }
-
- if ( qs is Haven.UzeraanTurmoilQuest )
- {
- QuestObjective obj = qs.FindObjective( typeof( Haven.CashBankCheckObjective ) );
-
- if ( obj != null && !obj.Completed )
- obj.Complete();
+ from.AddToBackpack(new BankCheck(toAdd));
}
}
}
- else
+
+ // Gold was deposited in your account:
+ from.SendLocalizedMessage(1042672, true, deposited.ToString("#,0"));
+
+ var pm = from as PlayerMobile;
+
+ if (pm != null)
{
- from.SendLocalizedMessage( 1047026 ); // That must be in your bank box to use it.
+ var qs = pm.Quest;
+
+ if (qs is Necro.DarkTidesQuest)
+ {
+ var obj = qs.FindObjective(typeof(Necro.CashBankCheckObjective));
+
+ if (obj != null && !obj.Completed)
+ {
+ obj.Complete();
+ }
+ }
+
+ if (qs is Haven.UzeraanTurmoilQuest)
+ {
+ var obj = qs.FindObjective(typeof(Engines.Quests.Haven.CashBankCheckObjective));
+
+ if (obj != null && !obj.Completed)
+ {
+ obj.Complete();
+ }
+ }
}
}
}
diff --git a/Scripts/Items/Misc/Gold.cs b/Scripts/Items/Misc/Gold.cs
index 7464001c3..6bfd04ec5 100644
--- a/Scripts/Items/Misc/Gold.cs
+++ b/Scripts/Items/Misc/Gold.cs
@@ -1,5 +1,7 @@
using System;
+using Server.Accounting;
+
namespace Server.Items
{
public class Gold : Item
@@ -47,6 +49,81 @@ namespace Server.Items
UpdateTotal( this, TotalType.Gold, newValue - oldValue );
}
+#if NEWPARENT
+ public override void OnAdded(IEntity parent)
+#else
+ public override void OnAdded(object parent)
+#endif
+ {
+ base.OnAdded(parent);
+
+ if (!AccountGold.Enabled)
+ {
+ return;
+ }
+
+ Mobile owner = null;
+ SecureTradeInfo tradeInfo = null;
+
+ Container root = parent as Container;
+
+ while (root != null && root.Parent is Container)
+ {
+ root = (Container)root.Parent;
+ }
+
+ parent = root ?? parent;
+
+ if (parent is SecureTradeContainer && AccountGold.ConvertOnTrade)
+ {
+ var trade = (SecureTradeContainer)parent;
+
+ if (trade.Trade.From.Container == trade)
+ {
+ tradeInfo = trade.Trade.From;
+ owner = tradeInfo.Mobile;
+ }
+ else if (trade.Trade.To.Container == trade)
+ {
+ tradeInfo = trade.Trade.To;
+ owner = tradeInfo.Mobile;
+ }
+ }
+ else if (parent is BankBox && AccountGold.ConvertOnBank)
+ {
+ owner = ((BankBox)parent).Owner;
+ }
+
+ if (owner == null || owner.Account == null || !owner.Account.DepositGold(Amount))
+ {
+ return;
+ }
+
+ if (tradeInfo != null)
+ {
+ if (owner.NetState != null && !owner.NetState.NewSecureTrading)
+ {
+ var total = Amount / Math.Max(1.0, Account.CurrencyThreshold);
+ var plat = (int)Math.Truncate(total);
+ var gold = (int)((total - plat) * Account.CurrencyThreshold);
+
+ tradeInfo.Plat += plat;
+ tradeInfo.Gold += gold;
+ }
+
+ if (tradeInfo.VirtualCheck != null)
+ {
+ tradeInfo.VirtualCheck.UpdateTrade(tradeInfo.Mobile);
+ }
+ }
+
+ owner.SendLocalizedMessage(1042763, Amount.ToString("#,0"));
+
+ Delete();
+
+ ((Container)parent).UpdateTotals();
+ }
+
public override int GetTotal( TotalType type )
{
int baseTotal = base.GetTotal( type );
@@ -57,8 +134,6 @@ namespace Server.Items
return baseTotal;
}
-
-
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
diff --git a/Scripts/Misc/CurrentExpansion.cs b/Scripts/Misc/CurrentExpansion.cs
index 58da51c82..27f9a816d 100644
--- a/Scripts/Misc/CurrentExpansion.cs
+++ b/Scripts/Misc/CurrentExpansion.cs
@@ -1,16 +1,23 @@
using System;
+
+using Server.Accounting;
using Server.Network;
namespace Server
{
public class CurrentExpansion
{
- private static readonly Expansion Expansion = Expansion.HS;
+ private static readonly Expansion Expansion = Expansion.TOL;
public static void Configure()
{
Core.Expansion = Expansion;
+ AccountGold.Enabled = Core.TOL;
+ AccountGold.ConvertOnBank = true;
+ AccountGold.ConvertOnTrade = false;
+ VirtualCheck.UseEditGump = true;
+
bool Enabled = Core.AOS;
Mobile.InsuranceEnabled = Enabled;
diff --git a/Scripts/Mobiles/PlayerMobile.cs b/Scripts/Mobiles/PlayerMobile.cs
index 767f593b3..d37da4f71 100644
--- a/Scripts/Mobiles/PlayerMobile.cs
+++ b/Scripts/Mobiles/PlayerMobile.cs
@@ -1695,8 +1695,13 @@ namespace Server.Mobiles
list.Add( new CallbackEntry( RefuseTrades ? 1154112 : 1154113, new ContextCallback( ToggleTrades ) ) ); // Allow Trades / Refuse Trades
}
}
- if ( from != this )
+ else
{
+ if (Core.TOL && from.InRange(this, 2))
+ {
+ list.Add(new CallbackEntry(1077728, () => OpenTrade(from))); // Trade
+ }
+
if ( Alive && Core.Expansion >= Expansion.AOS )
{
Party theirParty = from.Party as Party;
@@ -2397,7 +2402,7 @@ namespace Server.Mobiles
msgNum = 1154111; // ~1_NAME~ is refusing all trades.
}
- if ( msgNum == 0 )
+ if ( msgNum == 0 && item != null )
{
if ( cont != null )
{
diff --git a/Scripts/Mobiles/Townfolk/Banker.cs b/Scripts/Mobiles/Townfolk/Banker.cs
index 86de6fd4c..deae997b9 100644
--- a/Scripts/Mobiles/Townfolk/Banker.cs
+++ b/Scripts/Mobiles/Townfolk/Banker.cs
@@ -1,5 +1,8 @@
using System;
using System.Collections.Generic;
+using System.Linq;
+
+using Server.Accounting;
using Server.Items;
using Server.ContextMenus;
using Server.Misc;
@@ -24,49 +27,88 @@ namespace Server.Mobiles
m_SBInfos.Add( new SBBanker() );
}
- public static int GetBalance( Mobile from )
+ public static int GetBalance(Mobile m)
{
- Item[] gold, checks;
+ double balance = 0;
- return GetBalance( from, out gold, out checks );
+ if (AccountGold.Enabled && m.Account != null)
+ {
+ int goldStub;
+ m.Account.GetGoldBalance(out goldStub, out balance);
+
+ if (balance > Int32.MaxValue)
+ {
+ return Int32.MaxValue;
+ }
+ }
+
+ Container bank = m.FindBankNoCreate();
+
+ if (bank != null)
+ {
+ var gold = bank.FindItemsByType();
+ var checks = bank.FindItemsByType();
+
+ balance += gold.Aggregate(0.0, (c, t) => c + t.Amount);
+ balance += checks.Aggregate(0.0, (c, t) => c + t.Worth);
+ }
+
+ return (int)Math.Max(0, Math.Min(Int32.MaxValue, balance));
}
- public static int GetBalance( Mobile from, out Item[] gold, out Item[] checks )
+ public static int GetBalance(Mobile m, out Item[] gold, out Item[] checks)
{
- int balance = 0;
+ double balance = 0;
- Container bank = from.FindBankNoCreate();
-
- if ( bank != null )
+ if (AccountGold.Enabled && m.Account != null)
{
- gold = bank.FindItemsByType( typeof( Gold ) );
- checks = bank.FindItemsByType( typeof( BankCheck ) );
+ int goldStub;
+ m.Account.GetGoldBalance(out goldStub, out balance);
- for ( int i = 0; i < gold.Length; ++i )
- balance += gold[i].Amount;
+ if (balance > Int32.MaxValue)
+ {
+ gold = checks = new Item[0];
+ return Int32.MaxValue;
+ }
+ }
- for ( int i = 0; i < checks.Length; ++i )
- balance += ((BankCheck)checks[i]).Worth;
+ Container bank = m.FindBankNoCreate();
+
+ if (bank != null)
+ {
+ gold = bank.FindItemsByType(typeof(Gold));
+ checks = bank.FindItemsByType(typeof(BankCheck));
+
+ balance += gold.OfType().Aggregate(0.0, (c, t) => c + t.Amount);
+ balance += checks.OfType().Aggregate(0.0, (c, t) => c + t.Worth);
}
else
{
gold = checks = new Item[0];
}
- return balance;
+ return (int)Math.Max(0, Math.Min(Int32.MaxValue, balance));
}
- public static bool Withdraw( Mobile from, int amount )
+ public static bool Withdraw(Mobile from, int amount)
{
- Item[] gold, checks;
- int balance = GetBalance( from, out gold, out checks );
-
- if ( balance < amount )
- return false;
-
- for ( int i = 0; amount > 0 && i < gold.Length; ++i )
+ // If for whatever reason the TOL checks fail, we should still try old methods for withdrawing currency.
+ if (AccountGold.Enabled && from.Account != null && from.Account.WithdrawGold(amount))
{
- if ( gold[i].Amount <= amount )
+ return true;
+ }
+
+ Item[] gold, checks;
+ var balance = GetBalance(from, out gold, out checks);
+
+ if (balance < amount)
+ {
+ return false;
+ }
+
+ for (var i = 0; amount > 0 && i < gold.Length; ++i)
+ {
+ if (gold[i].Amount <= amount)
{
amount -= gold[i].Amount;
gold[i].Delete();
@@ -78,11 +120,11 @@ namespace Server.Mobiles
}
}
- for ( int i = 0; amount > 0 && i < checks.Length; ++i )
+ for (var i = 0; amount > 0 && i < checks.Length; ++i)
{
- BankCheck check = (BankCheck)checks[i];
+ var check = (BankCheck)checks[i];
- if ( check.Worth <= amount )
+ if (check.Worth <= amount)
{
amount -= check.Worth;
check.Delete();
@@ -97,41 +139,50 @@ namespace Server.Mobiles
return true;
}
- public static bool Deposit( Mobile from, int amount )
+ public static bool Deposit(Mobile from, int amount)
{
- BankBox box = from.FindBankNoCreate();
- if ( box == null )
+ // If for whatever reason the TOL checks fail, we should still try old methods for depositing currency.
+ if (AccountGold.Enabled && from.Account != null && from.Account.DepositGold(amount))
+ {
+ return true;
+ }
+
+ var box = from.FindBankNoCreate();
+
+ if (box == null)
+ {
return false;
+ }
- List- items = new List
- ();
+ var items = new List
- ();
- while ( amount > 0 )
+ while (amount > 0)
{
Item item;
- if ( amount < 5000 )
+ if (amount < 5000)
{
- item = new Gold( amount );
+ item = new Gold(amount);
amount = 0;
}
- else if ( amount <= 1000000 )
+ else if (amount <= 1000000)
{
- item = new BankCheck( amount );
+ item = new BankCheck(amount);
amount = 0;
}
else
{
- item = new BankCheck( 1000000 );
+ item = new BankCheck(1000000);
amount -= 1000000;
}
- if ( box.TryDropItem( from, item, false ) )
+ if (box.TryDropItem(from, item, false))
{
- items.Add( item );
+ items.Add(item);
}
else
{
item.Delete();
- foreach ( Item curItem in items )
+ foreach (var curItem in items)
{
curItem.Delete();
}
@@ -143,35 +194,44 @@ namespace Server.Mobiles
return true;
}
- public static int DepositUpTo( Mobile from, int amount )
+ public static int DepositUpTo(Mobile from, int amount)
{
- BankBox box = from.FindBankNoCreate();
- if ( box == null )
- return 0;
+ // If for whatever reason the TOL checks fail, we should still try old methods for depositing currency.
+ if (AccountGold.Enabled && from.Account != null && from.Account.DepositGold(amount))
+ {
+ return amount;
+ }
- int amountLeft = amount;
- while ( amountLeft > 0 )
+ var box = from.FindBankNoCreate();
+
+ if (box == null)
+ {
+ return 0;
+ }
+
+ var amountLeft = amount;
+ while (amountLeft > 0)
{
Item item;
int amountGiven;
- if ( amountLeft < 5000 )
+ if (amountLeft < 5000)
{
- item = new Gold( amountLeft );
+ item = new Gold(amountLeft);
amountGiven = amountLeft;
}
- else if ( amountLeft <= 1000000 )
+ else if (amountLeft <= 1000000)
{
- item = new BankCheck( amountLeft );
+ item = new BankCheck(amountLeft);
amountGiven = amountLeft;
}
else
{
- item = new BankCheck( 1000000 );
+ item = new BankCheck(1000000);
amountGiven = 1000000;
}
- if ( box.TryDropItem( from, item, false ) )
+ if (box.TryDropItem(from, item, false))
{
amountLeft -= amountGiven;
}
@@ -185,29 +245,29 @@ namespace Server.Mobiles
return amount - amountLeft;
}
- public static void Deposit( Container cont, int amount )
+ public static void Deposit(Container cont, int amount)
{
- while ( amount > 0 )
+ while (amount > 0)
{
Item item;
- if ( amount < 5000 )
+ if (amount < 5000)
{
- item = new Gold( amount );
+ item = new Gold(amount);
amount = 0;
}
- else if ( amount <= 1000000 )
+ else if (amount <= 1000000)
{
- item = new BankCheck( amount );
+ item = new BankCheck(amount);
amount = 0;
}
else
{
- item = new BankCheck( 1000000 );
+ item = new BankCheck(1000000);
amount -= 1000000;
}
- cont.DropItem( item );
+ cont.DropItem(item);
}
}
diff --git a/Scripts/Multis/ComponentVerification.cs b/Scripts/Multis/ComponentVerification.cs
index 04bc06a6f..1face22e6 100644
--- a/Scripts/Multis/ComponentVerification.cs
+++ b/Scripts/Multis/ComponentVerification.cs
@@ -30,12 +30,12 @@ namespace Server.Multis
if ( val == -1 )
return false;
- return ( val == 0 || (ExpansionInfo.CurrentExpansion.CustomHousingFlag & val) != 0 );
+ return ( val == 0 || ((int)ExpansionInfo.CoreExpansion.CustomHousingFlag & val) != 0 );
}
public ComponentVerification()
{
- m_ItemTable = CreateTable( 0x10000 );
+ m_ItemTable = CreateTable( TileData.MaxItemValue );
m_MultiTable = CreateTable( 0x4000 );
LoadItems( "Data/Components/walls.txt", "South1", "South2", "South3", "Corner", "East1", "East2", "East3", "Post", "WindowS", "AltWindowS", "WindowE", "AltWindowE", "SecondAltWindowS", "SecondAltWindowE" );
diff --git a/Scripts/Multis/HouseFoundation.cs b/Scripts/Multis/HouseFoundation.cs
index e9b2f77e3..106c8acd1 100644
--- a/Scripts/Multis/HouseFoundation.cs
+++ b/Scripts/Multis/HouseFoundation.cs
@@ -1882,7 +1882,8 @@ namespace Server.Multis
return true;
else if( itemID >= 0x319C && itemID < 0x31B0 )
return true;
- else if( itemID == 0x2D46 ||itemID == 0x2D48 || itemID == 0x2FE2 || itemID == 0x2FE4 ) //ML doors begin here. Note funkyness.
+ // ML doors
+ else if( itemID == 0x2D46 ||itemID == 0x2D48 || itemID == 0x2FE2 || itemID == 0x2FE4 )
return true;
else if( itemID >= 0x2D63 && itemID < 0x2D70 )
return true;
@@ -1890,7 +1891,7 @@ namespace Server.Multis
return true;
else if( itemID >= 0x367B && itemID < 0x369B )
return true;
- #region SA doors
+ // SA doors
else if( itemID >= 0x409B && itemID < 0x40A3 )
return true;
else if( itemID >= 0x410C && itemID < 0x4114 )
@@ -1909,7 +1910,11 @@ namespace Server.Multis
return true;
else if( itemID >= 0x5142 && itemID < 0x514A )
return true;
- #endregion
+ // TOL doors
+ else if ( itemID >= 0x9AD7 && itemID < 0x9AE7 )
+ return true;
+ else if ( itemID >= 0x9B3C && itemID < 0x9B4C )
+ return true;
return false;
}
diff --git a/Scripts/Properties/AssemblyInfo.cs b/Scripts/Properties/AssemblyInfo.cs
index 2a9303eae..4c9011421 100644
--- a/Scripts/Properties/AssemblyInfo.cs
+++ b/Scripts/Properties/AssemblyInfo.cs
@@ -10,7 +10,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("RunUO")]
[assembly: AssemblyProduct("RunUO")]
-[assembly: AssemblyCopyright("Copyright © 2014")]
+[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
diff --git a/Server/AssemblyInfo.cs b/Server/AssemblyInfo.cs
index 5969c278c..3795fd9ea 100644
--- a/Server/AssemblyInfo.cs
+++ b/Server/AssemblyInfo.cs
@@ -32,7 +32,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("RunUO")]
[assembly: AssemblyProduct("RunUO")]
-[assembly: AssemblyCopyright("Copyright © 2014")]
+[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -47,7 +47,7 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
-[assembly: AssemblyVersion("2.6.0.*")]
+[assembly: AssemblyVersion("2.7.0.*")]
//
// In order to sign your assembly you must specify a key to use. Refer to the
diff --git a/Server/ExpansionInfo.cs b/Server/ExpansionInfo.cs
index 40c93d895..98a70811a 100644
--- a/Server/ExpansionInfo.cs
+++ b/Server/ExpansionInfo.cs
@@ -33,7 +33,8 @@ namespace Server
SE,
ML,
SA,
- HS
+ HS,
+ TOL
}
[Flags]
@@ -54,38 +55,42 @@ namespace Server
[Flags]
public enum FeatureFlags
{
- None = 0x00000000,
- T2A = 0x00000001,
- UOR = 0x00000002,
- UOTD = 0x00000004,
- LBR = 0x00000008,
- AOS = 0x00000010,
- SixthCharacterSlot = 0x00000020,
- SE = 0x00000040,
- ML = 0x00000080,
- EigthAge = 0x00000100,
- NinthAge = 0x00000200, /* Crystal/Shadow Custom House Tiles */
- TenthAge = 0x00000400,
- IncreasedStorage = 0x00000800, /* Increased Housing/Bank Storage */
- SeventhCharacterSlot= 0x00001000,
- RoleplayFaces = 0x00002000,
- TrialAccount = 0x00004000,
- LiveAccount = 0x00008000,
- SA = 0x00010000,
- HS = 0x00020000,
- Gothic = 0x00040000,
- Rustic = 0x00080000,
+ None = 0x00000000,
+ T2A = 0x00000001,
+ UOR = 0x00000002,
+ UOTD = 0x00000004,
+ LBR = 0x00000008,
+ AOS = 0x00000010,
+ SixthCharacterSlot = 0x00000020,
+ SE = 0x00000040,
+ ML = 0x00000080,
+ EigthAge = 0x00000100,
+ NinthAge = 0x00000200, /* Crystal/Shadow Custom House Tiles */
+ TenthAge = 0x00000400,
+ IncreasedStorage = 0x00000800, /* Increased Housing/Bank Storage */
+ SeventhCharacterSlot = 0x00001000,
+ RoleplayFaces = 0x00002000,
+ TrialAccount = 0x00004000,
+ LiveAccount = 0x00008000,
+ SA = 0x00010000,
+ HS = 0x00020000,
+ Gothic = 0x00040000,
+ Rustic = 0x00080000,
+ Jungle = 0x00100000,
+ Shadowguard = 0x00200000,
+ TOL = 0x00400000,
- ExpansionNone = None,
- ExpansionT2A = T2A,
- ExpansionUOR = ExpansionT2A | UOR,
- ExpansionUOTD = ExpansionUOR | UOTD,
- ExpansionLBR = ExpansionUOTD | LBR,
- ExpansionAOS = ExpansionLBR | AOS | LiveAccount,
- ExpansionSE = ExpansionAOS | SE,
- ExpansionML = ExpansionSE | ML | NinthAge,
- ExpansionSA = ExpansionML | SA | Gothic | Rustic,
- ExpansionHS = ExpansionSA | HS
+ ExpansionNone = None,
+ ExpansionT2A = T2A,
+ ExpansionUOR = ExpansionT2A | UOR,
+ ExpansionUOTD = ExpansionUOR | UOTD,
+ ExpansionLBR = ExpansionUOTD | LBR,
+ ExpansionAOS = ExpansionLBR | AOS | LiveAccount,
+ ExpansionSE = ExpansionAOS | SE,
+ ExpansionML = ExpansionSE | ML | NinthAge,
+ ExpansionSA = ExpansionML | SA | Gothic | Rustic,
+ ExpansionHS = ExpansionSA | HS,
+ ExpansionTOL = ExpansionHS | TOL | Jungle | Shadowguard
}
[Flags]
@@ -109,92 +114,239 @@ namespace Server
NewMovementSystem = 0x00004000,
NewFeluccaAreas = 0x00008000,
- ExpansionNone = ContextMenus, //
- ExpansionT2A = ContextMenus, //
- ExpansionUOR = ContextMenus, // None
- ExpansionUOTD = ContextMenus, //
- ExpansionLBR = ContextMenus, //
- ExpansionAOS = ContextMenus | AOS,
- ExpansionSE = ExpansionAOS | SE,
- ExpansionML = ExpansionSE | ML,
- ExpansionSA = ExpansionML,
- ExpansionHS = ExpansionSA
+ ExpansionNone = ContextMenus, //
+ ExpansionT2A = ContextMenus, //
+ ExpansionUOR = ContextMenus, // None
+ ExpansionUOTD = ContextMenus, //
+ ExpansionLBR = ContextMenus, //
+ ExpansionAOS = ContextMenus | AOS,
+ ExpansionSE = ExpansionAOS | SE,
+ ExpansionML = ExpansionSE | ML,
+ ExpansionSA = ExpansionML,
+ ExpansionHS = ExpansionSA,
+ ExpansionTOL = ExpansionHS
+ }
+
+ [Flags]
+ public enum HousingFlags
+ {
+ None = 0x0,
+ AOS = 0x10,
+ SE = 0x40,
+ ML = 0x80,
+ Crystal = 0x200,
+ SA = 0x10000,
+ HS = 0x20000,
+ Gothic = 0x40000,
+ Rustic = 0x80000,
+ Jungle = 0x100000,
+ Shadowguard = 0x200000,
+ TOL = 0x400000,
+
+ HousingAOS = AOS,
+ HousingSE = HousingAOS | SE,
+ HousingML = HousingSE | ML | Crystal,
+ HousingSA = HousingML | SA | Gothic | Rustic,
+ HousingHS = HousingSA | HS,
+ HousingTOL = HousingHS | TOL | Jungle | Shadowguard
}
public class ExpansionInfo
{
- public static ExpansionInfo[] Table { get { return m_Table; } }
- private static ExpansionInfo[] m_Table = new ExpansionInfo[]
+ public static ExpansionInfo CoreExpansion { get { return GetInfo(Core.Expansion); } }
+
+ public static ExpansionInfo[] Table { get; private set; }
+
+ static ExpansionInfo()
+ {
+ Table = new[]
{
- new ExpansionInfo( 0, "None", ClientFlags.None, FeatureFlags.ExpansionNone, CharacterListFlags.ExpansionNone, 0x0000 ),
- new ExpansionInfo( 1, "The Second Age", ClientFlags.Felucca, FeatureFlags.ExpansionT2A, CharacterListFlags.ExpansionT2A, 0x0000 ),
- new ExpansionInfo( 2, "Renaissance", ClientFlags.Trammel, FeatureFlags.ExpansionUOR, CharacterListFlags.ExpansionUOR, 0x0000 ),
- new ExpansionInfo( 3, "Third Dawn", ClientFlags.Ilshenar, FeatureFlags.ExpansionUOTD, CharacterListFlags.ExpansionUOTD, 0x0000 ),
- new ExpansionInfo( 4, "Blackthorn's Revenge", ClientFlags.Ilshenar, FeatureFlags.ExpansionLBR, CharacterListFlags.ExpansionLBR, 0x0000 ),
- new ExpansionInfo( 5, "Age of Shadows", ClientFlags.Malas, FeatureFlags.ExpansionAOS, CharacterListFlags.ExpansionAOS, 0x0000 ),
- new ExpansionInfo( 6, "Samurai Empire", ClientFlags.Tokuno, FeatureFlags.ExpansionSE, CharacterListFlags.ExpansionSE, 0x00C0 ), // 0x20 | 0x80
- new ExpansionInfo( 7, "Mondain's Legacy", new ClientVersion( "5.0.0a" ), FeatureFlags.ExpansionML, CharacterListFlags.ExpansionML, 0x02C0 ), // 0x20 | 0x80 | 0x200
- new ExpansionInfo( 8, "Stygian Abyss", ClientFlags.TerMur, FeatureFlags.ExpansionSA, CharacterListFlags.ExpansionSA, 0xD02C0 ), // 0x20 | 0x80 | 0x200 | 0x10000 | 0x40000 | 0x80000
- new ExpansionInfo( 9, "High Seas", new ClientVersion( "7.0.9.0" ), FeatureFlags.ExpansionHS, CharacterListFlags.ExpansionHS, 0xD02C0 ) // 0x20 | 0x80 | 0x200 | 0x10000 | 0x40000 | 0x80000
+ new ExpansionInfo(
+ 0,
+ "None",
+ ClientFlags.None,
+ FeatureFlags.ExpansionNone,
+ CharacterListFlags.ExpansionNone,
+ HousingFlags.None),
+ new ExpansionInfo(
+ 1,
+ "The Second Age",
+ ClientFlags.Felucca,
+ FeatureFlags.ExpansionT2A,
+ CharacterListFlags.ExpansionT2A,
+ HousingFlags.None),
+ new ExpansionInfo(
+ 2,
+ "Renaissance",
+ ClientFlags.Trammel,
+ FeatureFlags.ExpansionUOR,
+ CharacterListFlags.ExpansionUOR,
+ HousingFlags.None),
+ new ExpansionInfo(
+ 3,
+ "Third Dawn",
+ ClientFlags.Ilshenar,
+ FeatureFlags.ExpansionUOTD,
+ CharacterListFlags.ExpansionUOTD,
+ HousingFlags.None),
+ new ExpansionInfo(
+ 4,
+ "Blackthorn's Revenge",
+ ClientFlags.Ilshenar,
+ FeatureFlags.ExpansionLBR,
+ CharacterListFlags.ExpansionLBR,
+ HousingFlags.None),
+ new ExpansionInfo(
+ 5,
+ "Age of Shadows",
+ ClientFlags.Malas,
+ FeatureFlags.ExpansionAOS,
+ CharacterListFlags.ExpansionAOS,
+ HousingFlags.HousingAOS),
+ new ExpansionInfo(
+ 6,
+ "Samurai Empire",
+ ClientFlags.Tokuno,
+ FeatureFlags.ExpansionSE,
+ CharacterListFlags.ExpansionSE,
+ HousingFlags.HousingSE),
+ new ExpansionInfo(
+ 7,
+ "Mondain's Legacy",
+ new ClientVersion("5.0.0a"),
+ FeatureFlags.ExpansionML,
+ CharacterListFlags.ExpansionML,
+ HousingFlags.HousingML),
+ new ExpansionInfo(
+ 8,
+ "Stygian Abyss",
+ ClientFlags.TerMur,
+ FeatureFlags.ExpansionSA,
+ CharacterListFlags.ExpansionSA,
+ HousingFlags.HousingSA),
+ new ExpansionInfo(
+ 9,
+ "High Seas",
+ new ClientVersion("7.0.9.0"),
+ FeatureFlags.ExpansionHS,
+ CharacterListFlags.ExpansionHS,
+ HousingFlags.HousingHS),
+ new ExpansionInfo(
+ 10,
+ "Time of Legends",
+ new ClientVersion("7.0.45.65"),
+ FeatureFlags.ExpansionTOL,
+ CharacterListFlags.ExpansionTOL,
+ HousingFlags.HousingTOL)
};
-
- private string m_Name;
- private int m_ID, m_CustomHousingFlag;
-
- private ClientFlags m_ClientFlags;
- private FeatureFlags m_SupportedFeatures;
- private CharacterListFlags m_CharListFlags;
-
- private ClientVersion m_RequiredClient; // Used as an alternative to the flags
-
- public string Name{ get{ return m_Name; } }
- public int ID{ get{ return m_ID; } }
- public ClientFlags ClientFlags{ get{ return m_ClientFlags; } }
- public FeatureFlags SupportedFeatures{ get{ return m_SupportedFeatures; } }
- public CharacterListFlags CharacterListFlags { get { return m_CharListFlags; } }
- public int CustomHousingFlag { get{ return m_CustomHousingFlag; } }
- public ClientVersion RequiredClient { get { return m_RequiredClient; } }
-
- public ExpansionInfo( int id, string name, ClientFlags clientFlags, FeatureFlags supportedFeatures, CharacterListFlags charListFlags, int customHousingFlag )
- {
- m_Name = name;
- m_ID = id;
- m_ClientFlags = clientFlags;
- m_SupportedFeatures = supportedFeatures;
- m_CharListFlags = charListFlags;
- m_CustomHousingFlag = customHousingFlag;
}
- public ExpansionInfo( int id, string name, ClientVersion requiredClient, FeatureFlags supportedFeatures, CharacterListFlags charListFlags, int customHousingFlag )
+ public static FeatureFlags GetFeatures(Expansion ex)
{
- m_Name = name;
- m_ID = id;
- m_SupportedFeatures = supportedFeatures;
- m_CharListFlags = charListFlags;
- m_CustomHousingFlag = customHousingFlag;
- m_RequiredClient = requiredClient;
+ var info = GetInfo(ex);
+
+ if (info != null)
+ {
+ return info.SupportedFeatures;
+ }
+
+ switch (ex)
+ {
+ case Expansion.None:
+ return FeatureFlags.ExpansionNone;
+ case Expansion.T2A:
+ return FeatureFlags.ExpansionT2A;
+ case Expansion.UOR:
+ return FeatureFlags.ExpansionUOR;
+ case Expansion.UOTD:
+ return FeatureFlags.ExpansionUOTD;
+ case Expansion.LBR:
+ return FeatureFlags.ExpansionLBR;
+ case Expansion.AOS:
+ return FeatureFlags.ExpansionAOS;
+ case Expansion.SE:
+ return FeatureFlags.ExpansionSE;
+ case Expansion.ML:
+ return FeatureFlags.ExpansionML;
+ case Expansion.SA:
+ return FeatureFlags.ExpansionSA;
+ case Expansion.HS:
+ return FeatureFlags.ExpansionHS;
+ case Expansion.TOL:
+ return FeatureFlags.ExpansionTOL;
+ }
+
+ return FeatureFlags.ExpansionNone;
}
- public static ExpansionInfo GetInfo( Expansion ex )
+ public static ExpansionInfo GetInfo(Expansion ex)
{
- return GetInfo( (int)ex );
+ return GetInfo((int)ex);
}
- public static ExpansionInfo GetInfo( int ex )
+ public static ExpansionInfo GetInfo(int ex)
{
- int v = (int)ex;
+ var v = ex;
- if( v < 0 || v >= m_Table.Length )
+ if (v < 0 || v >= Table.Length)
+ {
v = 0;
+ }
- return m_Table[v];
+ return Table[v];
}
- public static ExpansionInfo CurrentExpansion { get { return GetInfo( Core.Expansion ); } }
+ public int ID { get; private set; }
+ public string Name { get; set; }
+
+ public ClientFlags ClientFlags { get; set; }
+ public FeatureFlags SupportedFeatures { get; set; }
+ public CharacterListFlags CharacterListFlags { get; set; }
+ public ClientVersion RequiredClient { get; set; }
+ public HousingFlags CustomHousingFlag { get; set; }
+
+ public ExpansionInfo(
+ int id,
+ string name,
+ ClientFlags clientFlags,
+ FeatureFlags supportedFeatures,
+ CharacterListFlags charListFlags,
+ HousingFlags customHousingFlag)
+ : this(id, name, supportedFeatures, charListFlags, customHousingFlag)
+ {
+ ClientFlags = clientFlags;
+ }
+
+ public ExpansionInfo(
+ int id,
+ string name,
+ ClientVersion requiredClient,
+ FeatureFlags supportedFeatures,
+ CharacterListFlags charListFlags,
+ HousingFlags customHousingFlag)
+ : this(id, name, supportedFeatures, charListFlags, customHousingFlag)
+ {
+ RequiredClient = requiredClient;
+ }
+
+ private ExpansionInfo(
+ int id,
+ string name,
+ FeatureFlags supportedFeatures,
+ CharacterListFlags charListFlags,
+ HousingFlags customHousingFlag)
+ {
+ ID = id;
+ Name = name;
+
+ SupportedFeatures = supportedFeatures;
+ CharacterListFlags = charListFlags;
+ CustomHousingFlag = customHousingFlag;
+ }
public override string ToString()
{
- return m_Name;
+ return Name;
}
}
}
diff --git a/Server/IAccount.cs b/Server/IAccount.cs
index 1919dcf7b..6ccbd084b 100644
--- a/Server/IAccount.cs
+++ b/Server/IAccount.cs
@@ -22,9 +22,190 @@ using System;
namespace Server.Accounting
{
- public interface IAccount : IComparable
+ public static class AccountGold
+ {
+ public static bool Enabled = false;
+
+ ///
+ /// This amount specifies the value at which point Gold turns to Platinum.
+ /// By default, when 1,000,000,000 Gold is accumulated, it will transform
+ /// into 1 Platinum.
+ /// !!! WARNING !!!
+ /// The client is designed to perceive the currency threashold at 1,000,000,000
+ /// if you change this, it may cause unexpected results when using secure trading.
+ ///
+ public static int CurrencyThreshold = 1000000000;
+
+ ///
+ /// Enables or Disables automatic conversion of Gold and Checks to Bank Currency
+ /// when they are added to a bank box container.
+ ///
+ public static bool ConvertOnBank = true;
+
+ ///
+ /// Enables or Disables automatic conversion of Gold and Checks to Bank Currency
+ /// when they are added to a secure trade container.
+ ///
+ public static bool ConvertOnTrade = false;
+ }
+
+ public interface IGoldAccount
+ {
+ ///
+ /// This amount represents the total amount of currency owned by the player.
+ /// It is cumulative of both Gold and Platinum, the absolute total amount of
+ /// Gold owned by the player can be found by multiplying this value by the
+ /// CurrencyThreshold value.
+ ///
+ [CommandProperty(AccessLevel.Administrator)]
+ double TotalCurrency { get; }
+
+ ///
+ /// This amount represents the current amount of Gold owned by the player.
+ /// The value does not include the value of Platinum and ranges from
+ /// 0 to 999,999,999 by default.
+ ///
+ [CommandProperty(AccessLevel.Administrator)]
+ int TotalGold { get; }
+
+ ///
+ /// This amount represents the current amount of Platinum owned by the player.
+ /// The value does not include the value of Gold and ranges from
+ /// 0 to 2,147,483,647 by default.
+ /// One Platinum represents the value of CurrencyThreshold in Gold.
+ ///
+ [CommandProperty(AccessLevel.Administrator)]
+ int TotalPlat { get; }
+
+ ///
+ /// Attempts to deposit the given amount of Gold and Platinum into this account.
+ ///
+ /// Amount to deposit.
+ /// True if successful, false if amount given is less than or equal to zero.
+ bool DepositCurrency(double amount);
+
+ ///
+ /// Attempts to deposit the given amount of Gold into this account.
+ /// If the given amount is greater than the CurrencyThreshold,
+ /// Platinum will be deposited to offset the difference.
+ ///
+ /// Amount to deposit.
+ /// True if successful, false if amount given is less than or equal to zero.
+ bool DepositGold(int amount);
+
+ ///
+ /// Attempts to deposit the given amount of Gold into this account.
+ /// If the given amount is greater than the CurrencyThreshold,
+ /// Platinum will be deposited to offset the difference.
+ ///
+ /// Amount to deposit.
+ /// True if successful, false if amount given is less than or equal to zero.
+ bool DepositGold(long amount);
+
+ ///
+ /// Attempts to deposit the given amount of Platinum into this account.
+ ///
+ /// Amount to deposit.
+ /// True if successful, false if amount given is less than or equal to zero.
+ bool DepositPlat(int amount);
+
+ ///
+ /// Attempts to deposit the given amount of Platinum into this account.
+ ///
+ /// Amount to deposit.
+ /// True if successful, false if amount given is less than or equal to zero.
+ bool DepositPlat(long amount);
+
+ ///
+ /// Attempts to withdraw the given amount of Platinum and Gold from this account.
+ ///
+ /// Amount to withdraw.
+ /// True if successful, false if balance was too low.
+ bool WithdrawCurrency(double amount);
+
+ ///
+ /// Attempts to withdraw the given amount of Gold from this account.
+ /// If the given amount is greater than the CurrencyThreshold,
+ /// Platinum will be withdrawn to offset the difference.
+ ///
+ /// Amount to withdraw.
+ /// True if successful, false if balance was too low.
+ bool WithdrawGold(int amount);
+
+ ///
+ /// Attempts to withdraw the given amount of Gold from this account.
+ /// If the given amount is greater than the CurrencyThreshold,
+ /// Platinum will be withdrawn to offset the difference.
+ ///
+ /// Amount to withdraw.
+ /// True if successful, false if balance was too low.
+ bool WithdrawGold(long amount);
+
+ ///
+ /// Attempts to withdraw the given amount of Platinum from this account.
+ ///
+ /// Amount to withdraw.
+ /// True if successful, false if balance was too low.
+ bool WithdrawPlat(int amount);
+
+ ///
+ /// Attempts to withdraw the given amount of Platinum from this account.
+ ///
+ /// Amount to withdraw.
+ /// True if successful, false if balance was too low.
+ bool WithdrawPlat(long amount);
+
+ ///
+ /// Gets the total balance of Gold for this account.
+ ///
+ /// Gold value, Platinum exclusive
+ /// Gold value, Platinum inclusive
+ void GetGoldBalance(out int gold, out double totalGold);
+
+ ///
+ /// Gets the total balance of Gold for this account.
+ ///
+ /// Gold value, Platinum exclusive
+ /// Gold value, Platinum inclusive
+ void GetGoldBalance(out long gold, out double totalGold);
+
+ ///
+ /// Gets the total balance of Platinum for this account.
+ ///
+ /// Platinum value, Gold exclusive
+ /// Platinum value, Gold inclusive
+ void GetPlatBalance(out int plat, out double totalPlat);
+
+ ///
+ /// Gets the total balance of Platinum for this account.
+ ///
+ /// Platinum value, Gold exclusive
+ /// Platinum value, Gold inclusive
+ void GetPlatBalance(out long plat, out double totalPlat);
+
+ ///
+ /// Gets the total balance of Gold and Platinum for this account.
+ ///
+ /// Gold value, Platinum exclusive
+ /// Gold value, Platinum inclusive
+ /// Platinum value, Gold exclusive
+ /// Platinum value, Gold inclusive
+ void GetBalance(out int gold, out double totalGold, out int plat, out double totalPlat);
+
+ ///
+ /// Gets the total balance of Gold and Platinum for this account.
+ ///
+ /// Gold value, Platinum exclusive
+ /// Gold value, Platinum inclusive
+ /// Platinum value, Gold exclusive
+ /// Platinum value, Gold inclusive
+ void GetBalance(out long gold, out double totalGold, out long plat, out double totalPlat);
+ }
+
+ public interface IAccount : IGoldAccount, IComparable
{
string Username { get; set; }
+ string Email { get; set; }
AccessLevel AccessLevel { get; set; }
int Length { get; }
diff --git a/Server/Items/Containers.cs b/Server/Items/Containers.cs
index ab806d8bb..171f0d6f2 100644
--- a/Server/Items/Containers.cs
+++ b/Server/Items/Containers.cs
@@ -19,6 +19,8 @@
***************************************************************************/
using System;
+
+using Server.Accounting;
using Server.Network;
namespace Server.Items
@@ -162,5 +164,15 @@ namespace Server.Items
else
return false;
}
+
+ public override int GetTotal(TotalType type)
+ {
+ if (AccountGold.Enabled && Owner != null && Owner.Account != null && type == TotalType.Gold)
+ {
+ return Owner.Account.TotalGold;
+ }
+
+ return base.GetTotal(type);
+ }
}
}
\ No newline at end of file
diff --git a/Server/Items/SecureTradeContainer.cs b/Server/Items/SecureTradeContainer.cs
index 71d483a5b..bb884abd1 100644
--- a/Server/Items/SecureTradeContainer.cs
+++ b/Server/Items/SecureTradeContainer.cs
@@ -19,6 +19,8 @@
***************************************************************************/
using System;
+
+using Server.Accounting;
using Server.Network;
namespace Server.Items
@@ -48,6 +50,11 @@ namespace Server.Items
public override bool CheckHold( Mobile m, Item item, bool message, bool checkItems, int plusItems, int plusWeight )
{
+ if (item == Trade.From.VirtualCheck || item == Trade.To.VirtualCheck)
+ {
+ return true;
+ }
+
Mobile to;
if ( this.Trade.From.Container != this )
@@ -74,34 +81,64 @@ namespace Server.Items
public override void OnItemAdded( Item item )
{
- ClearChecks();
+ if ( !(item is VirtualCheck) )
+ {
+ ClearChecks();
+ }
}
public override void OnItemRemoved( Item item )
{
- ClearChecks();
+ if ( !(item is VirtualCheck) )
+ {
+ ClearChecks();
+ }
}
public override void OnSubItemAdded( Item item )
{
- ClearChecks();
+ if ( !(item is VirtualCheck) )
+ {
+ ClearChecks();
+ }
}
public override void OnSubItemRemoved( Item item )
{
- ClearChecks();
+ if ( !(item is VirtualCheck) )
+ {
+ ClearChecks();
+ }
}
- public void ClearChecks()
+ public void ClearChecks( )
{
if ( m_Trade != null )
{
- m_Trade.From.Accepted = false;
- m_Trade.To.Accepted = false;
+ if ( m_Trade.From != null && !m_Trade.From.IsDisposed )
+ {
+ m_Trade.From.Accepted = false;
+ }
+
+ if ( m_Trade.To != null && !m_Trade.To.IsDisposed )
+ {
+ m_Trade.To.Accepted = false;
+ }
+
m_Trade.Update();
}
}
+ public override bool IsChildVisibleTo( Mobile m, Item child )
+ {
+ if (child is VirtualCheck)
+ {
+ return AccountGold.Enabled && (m.NetState == null || !m.NetState.NewSecureTrading);
+ }
+
+ return base.IsChildVisibleTo(m, child);
+ }
+
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
diff --git a/Server/Items/VirtualCheck.cs b/Server/Items/VirtualCheck.cs
new file mode 100644
index 000000000..3695d605b
--- /dev/null
+++ b/Server/Items/VirtualCheck.cs
@@ -0,0 +1,395 @@
+#region Header
+// **********
+// ServUO - VirtualCheck.cs
+// **********
+#endregion
+
+#region References
+using System;
+using System.Drawing;
+
+using Server.Accounting;
+using Server.Gumps;
+using Server.Network;
+#endregion
+
+namespace Server
+{
+ public sealed class VirtualCheck : Item
+ {
+ public static bool UseEditGump = false;
+
+ public override bool IsVirtualItem { get { return true; } }
+
+ public override bool DisplayWeight { get { return false; } }
+ public override bool DisplayLootType { get { return false; } }
+
+ public override double DefaultWeight { get { return 0; } }
+
+ public override string DefaultName { get { return "Offer Of Currency"; } }
+
+ public EditGump Editor { get; private set; }
+
+ private int _Plat;
+
+ [CommandProperty(AccessLevel.Administrator)]
+ public int Plat
+ {
+ get { return _Plat; }
+ set
+ {
+ _Plat = value;
+ InvalidateProperties();
+ }
+ }
+
+ private int _Gold;
+
+ [CommandProperty(AccessLevel.Administrator)]
+ public int Gold
+ {
+ get { return _Gold; }
+ set
+ {
+ _Gold = value;
+ InvalidateProperties();
+ }
+ }
+
+ public VirtualCheck()
+ : this(0, 0)
+ { }
+
+ public VirtualCheck(int plat, int gold)
+ : base(0x14F0)
+ {
+ Plat = plat;
+ Gold = gold;
+
+ Movable = false;
+ }
+
+ public VirtualCheck(Serial serial)
+ : base(serial)
+ { }
+
+ public override bool IsAccessibleTo(Mobile check)
+ {
+ var c = GetSecureTradeCont();
+
+ if (check == null || c == null)
+ {
+ return base.IsAccessibleTo(check);
+ }
+
+ return c.RootParent == check && IsChildOf(c);
+ }
+
+ public override void OnDoubleClickSecureTrade(Mobile from)
+ {
+ if (UseEditGump && IsAccessibleTo(from))
+ {
+ if (Editor == null || Editor.Check == null || Editor.Check.Deleted)
+ {
+ Editor = new EditGump(from, this);
+ Editor.Send();
+ }
+ else
+ {
+ Editor.Refresh(true);
+ }
+ }
+ else
+ {
+ if (Editor != null)
+ {
+ Editor.Close();
+ Editor = null;
+ }
+
+ base.OnDoubleClickSecureTrade(from);
+ }
+ }
+
+ public override void OnSingleClick(Mobile from)
+ {
+ LabelTo(from, "Offer: {0:#,0} platinum, {1:#,0} gold", Plat, Gold);
+ }
+
+ public override void GetProperties(ObjectPropertyList list)
+ {
+ base.GetProperties(list);
+
+ list.Add(1060738, String.Format("{0:#,0} platinum, {1:#,0} gold", Plat, Gold)); // value: ~1_val~
+ }
+
+ public void UpdateTrade(Mobile user)
+ {
+ var c = GetSecureTradeCont();
+
+ if (c == null || c.Trade == null)
+ {
+ return;
+ }
+
+ if (user == c.Trade.From.Mobile)
+ {
+ c.Trade.UpdateFromCurrency();
+ }
+ else if (user == c.Trade.To.Mobile)
+ {
+ c.Trade.UpdateToCurrency();
+ }
+
+ c.ClearChecks();
+ }
+
+ public override void OnAfterDelete()
+ {
+ base.OnAfterDelete();
+
+ if (Editor != null)
+ {
+ Editor.Close();
+ Editor = null;
+ }
+ }
+
+ public override void Serialize(GenericWriter writer)
+ { }
+
+ public override void Deserialize(GenericReader reader)
+ {
+ Delete();
+ }
+
+ public class EditGump : Gump
+ {
+ public enum Buttons
+ {
+ Close,
+ Clear,
+ Accept,
+ AllPlat,
+ AllGold
+ }
+
+ private int _Plat, _Gold;
+
+ public Mobile User { get; private set; }
+ public VirtualCheck Check { get; private set; }
+
+ public EditGump(Mobile user, VirtualCheck check)
+ : base(50, 50)
+ {
+ User = user;
+ Check = check;
+
+ _Plat = Check.Plat;
+ _Gold = Check.Gold;
+
+ Closable = true;
+ Disposable = true;
+ Dragable = true;
+ Resizable = false;
+
+ User.CloseGump(GetType());
+
+ CompileLayout();
+ }
+
+ public override void OnServerClose(NetState owner)
+ {
+ base.OnServerClose(owner);
+
+ if (Check != null && !Check.Deleted)
+ {
+ Check.UpdateTrade(User);
+ }
+ }
+
+ public void Close()
+ {
+ User.CloseGump(GetType());
+
+ if (Check != null && !Check.Deleted)
+ {
+ Check.UpdateTrade(User);
+ }
+ else
+ {
+ Check = null;
+ }
+ }
+
+ public void Send()
+ {
+ if (Check != null && !Check.Deleted)
+ {
+ User.SendGump(this);
+ }
+ else
+ {
+ Close();
+ }
+ }
+
+ public void Refresh(bool recompile)
+ {
+ if (Check == null || Check.Deleted)
+ {
+ Close();
+ return;
+ }
+
+ if (recompile)
+ {
+ CompileLayout();
+ }
+
+ Close();
+ Send();
+ }
+
+ private void CompileLayout()
+ {
+ if (Check == null || Check.Deleted)
+ {
+ return;
+ }
+
+ Entries.ForEach(e => e.Parent = null);
+ Entries.Clear();
+
+ AddPage(0);
+
+ AddBackground(0, 0, 400, 160, 3500);
+
+ // Title
+ AddImageTiled(25, 35, 350, 3, 96);
+ AddImage(10, 8, 113);
+ AddImage(360, 8, 113);
+
+ var title = String.Format(
+ "BANK OF {1}",
+ Color.DarkSlateGray.ToArgb(),
+ User.RawName.ToUpper());
+
+ AddHtml(40, 15, 320, 20, title, false, false);
+
+ // Platinum Row
+ AddBackground(15, 60, 175, 20, 9300);
+ AddBackground(20, 45, 165, 30, 9350);
+ AddItem(20, 45, 3826); // Plat
+ AddLabel(60, 50, 0, User.Account.TotalPlat.ToString("#,0"));
+
+ AddButton(195, 50, 95, 95, (int)Buttons.AllPlat, GumpButtonType.Reply, 0); // ->
+
+ AddBackground(210, 60, 175, 20, 9300);
+ AddBackground(215, 45, 165, 30, 9350);
+ AddTextEntry(225, 50, 145, 20, 0, 0, _Plat.ToString(), User.Account.TotalPlat.ToString().Length);
+
+ // Gold Row
+ AddBackground(15, 100, 175, 20, 9300);
+ AddBackground(20, 85, 165, 30, 9350);
+ AddItem(20, 85, 3823); // Gold
+ AddLabel(60, 90, 0, User.Account.TotalGold.ToString("#,0"));
+
+ AddButton(195, 90, 95, 95, (int)Buttons.AllGold, GumpButtonType.Reply, 0); // ->
+
+ AddBackground(210, 100, 175, 20, 9300);
+ AddBackground(215, 85, 165, 30, 9350);
+ AddTextEntry(225, 90, 145, 20, 0, 1, _Gold.ToString(), User.Account.TotalGold.ToString().Length);
+
+ // Buttons
+ AddButton(20, 128, 12006, 12007, (int)Buttons.Close, GumpButtonType.Reply, 0);
+ AddButton(215, 128, 12003, 12004, (int)Buttons.Clear, GumpButtonType.Reply, 0);
+ AddButton(305, 128, 12000, 12002, (int)Buttons.Accept, GumpButtonType.Reply, 0);
+ }
+
+ public override void OnResponse(NetState sender, RelayInfo info)
+ {
+ if (Check == null || Check.Deleted || sender.Mobile != User)
+ {
+ Close();
+ return;
+ }
+
+ bool refresh = false, updated = false;
+
+ switch ((Buttons)info.ButtonID)
+ {
+ case Buttons.Close:
+ break;
+ case Buttons.Clear:
+ {
+ _Plat = _Gold = 0;
+ refresh = true;
+ }
+ break;
+ case Buttons.Accept:
+ {
+ var platText = info.GetTextEntry(0).Text;
+ var goldText = info.GetTextEntry(1).Text;
+
+ if (!Int32.TryParse(platText, out _Plat))
+ {
+ User.SendMessage("That is not a valid amount of platinum.");
+ refresh = true;
+ }
+ else if (!Int32.TryParse(goldText, out _Gold))
+ {
+ User.SendMessage("That is not a valid amount of gold.");
+ refresh = true;
+ }
+ else
+ {
+ var cur = User.Account.TotalCurrency;
+ var off = _Plat + (_Gold / Math.Max(1.0, AccountGold.CurrencyThreshold));
+
+ if (off > cur)
+ {
+ _Plat = User.Account.TotalPlat;
+ _Gold = User.Account.TotalGold;
+ User.SendMessage("You do not have that much currency.");
+ refresh = true;
+ }
+ else
+ {
+ Check.Plat = _Plat;
+ Check.Gold = _Gold;
+ updated = true;
+ }
+ }
+ }
+ break;
+ case Buttons.AllPlat:
+ {
+ _Plat = User.Account.TotalPlat;
+ refresh = true;
+ }
+ break;
+ case Buttons.AllGold:
+ {
+ _Gold = User.Account.TotalGold;
+ refresh = true;
+ }
+ break;
+ }
+
+ if (updated)
+ {
+ User.SendMessage("Your offer has been updated.");
+ }
+
+ if (refresh && Check != null && !Check.Deleted)
+ {
+ Refresh(true);
+ return;
+ }
+
+ Close();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Server/Main.cs b/Server/Main.cs
index 14f029207..0babf8c4e 100644
--- a/Server/Main.cs
+++ b/Server/Main.cs
@@ -233,6 +233,11 @@ namespace Server
get { return m_Expansion >= Expansion.HS; }
}
+ public static bool TOL
+ {
+ get { return m_Expansion >= Expansion.TOL; }
+ }
+
#endregion
public static string ExePath
diff --git a/Server/Map.cs b/Server/Map.cs
index 1a0c30b1a..603b29a46 100644
--- a/Server/Map.cs
+++ b/Server/Map.cs
@@ -1725,7 +1725,7 @@ namespace Server
public sealed class PooledEnumerable : IPooledEnumerable, IDisposable
{
- private static readonly Queue> _Buffer = new Queue>(0x200);
+ private static readonly Queue> _Buffer = new Queue>(0x400);
public static PooledEnumerable Instantiate(Map map, Rectangle2D bounds, PooledEnumeration.Selector selector)
{
@@ -1754,11 +1754,12 @@ namespace Server
}
private bool _IsDisposed;
- private List _Pool;
+
+ private List _Pool = new List(0x40);
public PooledEnumerable(IEnumerable pool)
{
- _Pool = new List(pool);
+ _Pool.AddRange(pool);
}
IEnumerator IEnumerable.GetEnumerator()
@@ -1780,6 +1781,11 @@ namespace Server
_Pool.Clear();
+ if (_Pool.Capacity > 0x100)
+ {
+ _Pool.Capacity = 0x100;
+ }
+
lock (((ICollection)_Buffer).SyncRoot)
{
_Buffer.Enqueue(this);
diff --git a/Server/Mobile.cs b/Server/Mobile.cs
index ea7802f9f..e6caf1dba 100644
--- a/Server/Mobile.cs
+++ b/Server/Mobile.cs
@@ -9660,6 +9660,45 @@ namespace Server
{
return true;
}
+ public bool OpenTrade(Mobile from)
+ {
+ return OpenTrade(from, null);
+ }
+
+ public virtual bool OpenTrade(Mobile from, Item offer)
+ {
+ if (!from.Player || !Player || !from.Alive || !Alive)
+ {
+ return false;
+ }
+
+ NetState ourState = m_NetState;
+ NetState theirState = from.m_NetState;
+
+ if (ourState == null || theirState == null)
+ {
+ return false;
+ }
+
+ SecureTradeContainer cont = theirState.FindTradeContainer(this);
+
+ if (!from.CheckTrade(this, offer, cont, true, true, 0, 0))
+ {
+ return false;
+ }
+
+ if (cont == null)
+ {
+ cont = theirState.AddTrade(ourState);
+ }
+
+ if (offer != null)
+ {
+ cont.DropItem(offer);
+ }
+
+ return true;
+ }
///
/// Overridable. Event invoked when a Mobile () drops an onto the Mobile.
@@ -9675,27 +9714,9 @@ namespace Server
return false;
}
- else if( from.Player && this.Player && from.Alive && this.Alive && from.InRange( Location, 2 ) )
+ else if( from.InRange( Location, 2 ) )
{
- NetState ourState = m_NetState;
- NetState theirState = from.m_NetState;
-
- if( ourState != null && theirState != null )
- {
- SecureTradeContainer cont = theirState.FindTradeContainer( this );
-
- if( !from.CheckTrade( this, dropped, cont, true, true, 0, 0 ) )
- return false;
-
- if( cont == null )
- cont = theirState.AddTrade( ourState );
-
- cont.DropItem( dropped );
-
- return true;
- }
-
- return false;
+ return OpenTrade( from, dropped );
}
else
{
diff --git a/Server/Network/NetState.cs b/Server/Network/NetState.cs
index 872f96269..e9cc71656 100644
--- a/Server/Network/NetState.cs
+++ b/Server/Network/NetState.cs
@@ -165,7 +165,9 @@ namespace Server.Network {
set {
m_Version = value;
- if ( value >= m_Version70331 ) {
+ if ( value >= m_Version704565 ) {
+ _ProtocolChanges = ProtocolChanges.Version704565;
+ } else if ( value >= m_Version70331 ) {
_ProtocolChanges = ProtocolChanges.Version70331;
} else if ( value >= m_Version70300 ) {
_ProtocolChanges = ProtocolChanges.Version70300;
@@ -208,6 +210,7 @@ namespace Server.Network {
private static ClientVersion m_Version70160 = new ClientVersion( "7.0.16.0" );
private static ClientVersion m_Version70300 = new ClientVersion( "7.0.30.0" );
private static ClientVersion m_Version70331 = new ClientVersion( "7.0.33.1" );
+ private static ClientVersion m_Version704565 = new ClientVersion( "7.0.45.65" );
private ProtocolChanges _ProtocolChanges;
@@ -225,6 +228,7 @@ namespace Server.Network {
NewCharacterCreation = 0x00000400,
ExtendedStatus = 0x00000800,
NewMobileIncoming = 0x00001000,
+ NewSecureTrading = 0x00002000,
Version400a = NewSpellbook,
Version407a = Version400a | DamagePacket,
@@ -238,7 +242,8 @@ namespace Server.Network {
Version70130 = Version7090 | NewCharacterList,
Version70160 = Version70130 | NewCharacterCreation,
Version70300 = Version70160 | ExtendedStatus,
- Version70331 = Version70300 | NewMobileIncoming
+ Version70331 = Version70300 | NewMobileIncoming,
+ Version704565 = Version70331 | NewSecureTrading
}
public bool NewSpellbook { get { return ((_ProtocolChanges & ProtocolChanges.NewSpellbook) != 0); } }
@@ -254,6 +259,7 @@ namespace Server.Network {
public bool NewCharacterCreation { get { return ((_ProtocolChanges & ProtocolChanges.NewCharacterCreation) != 0); } }
public bool ExtendedStatus { get { return ((_ProtocolChanges & ProtocolChanges.ExtendedStatus) != 0); } }
public bool NewMobileIncoming { get { return ((_ProtocolChanges & ProtocolChanges.NewMobileIncoming) != 0); } }
+ public bool NewSecureTrading { get { return ((_ProtocolChanges & ProtocolChanges.NewSecureTrading) != 0); } }
public bool IsUOTDClient {
get {
diff --git a/Server/Network/PacketHandlers.cs b/Server/Network/PacketHandlers.cs
index 29ab6cb11..ffee43981 100644
--- a/Server/Network/PacketHandlers.cs
+++ b/Server/Network/PacketHandlers.cs
@@ -376,6 +376,37 @@ namespace Server.Network
break;
}
+ case 3: // Update Gold
+ {
+ Serial serial = pvSrc.ReadInt32();
+
+ SecureTradeContainer cont = World.FindItem(serial) as SecureTradeContainer;
+
+ if (cont != null)
+ {
+ int gold = pvSrc.ReadInt32();
+ int plat = pvSrc.ReadInt32();
+
+ SecureTrade trade = cont.Trade;
+
+ if (trade != null)
+ {
+ if (trade.From.Mobile == state.Mobile)
+ {
+ trade.From.Gold = gold;
+ trade.From.Plat = plat;
+ trade.UpdateFromCurrency();
+ }
+ else if (trade.To.Mobile == state.Mobile)
+ {
+ trade.To.Gold = gold;
+ trade.To.Plat = plat;
+ trade.UpdateToCurrency();
+ }
+ }
+ }
+ }
+ break;
}
}
diff --git a/Server/Network/Packets.cs b/Server/Network/Packets.cs
index 1a53af7e0..5444a9afd 100644
--- a/Server/Network/Packets.cs
+++ b/Server/Network/Packets.cs
@@ -162,44 +162,62 @@ namespace Server.Network
public sealed class DisplaySecureTrade : Packet
{
- public DisplaySecureTrade( Mobile them, Container first, Container second, string name ) : base( 0x6F )
+ public DisplaySecureTrade(Mobile them, Container first, Container second, string name)
+ : base(0x6F)
{
- if ( name == null )
+ if (name == null)
+ {
name = "";
+ }
- EnsureCapacity( 18 + name.Length );
+ EnsureCapacity(18 + name.Length);
- m_Stream.Write( (byte) 0 ); // Display
- m_Stream.Write( (int) them.Serial );
- m_Stream.Write( (int) first.Serial );
- m_Stream.Write( (int) second.Serial );
- m_Stream.Write( (bool) true );
+ m_Stream.Write((byte)0); // Display
+ m_Stream.Write(them.Serial);
+ m_Stream.Write(first.Serial);
+ m_Stream.Write(second.Serial);
+ m_Stream.Write(true);
- m_Stream.WriteAsciiFixed( name, 30 );
+ m_Stream.WriteAsciiFixed(name, 30);
}
}
public sealed class CloseSecureTrade : Packet
{
- public CloseSecureTrade( Container cont ) : base( 0x6F )
+ public CloseSecureTrade(Container cont)
+ : base(0x6F)
{
- EnsureCapacity( 8 );
+ EnsureCapacity(8);
- m_Stream.Write( (byte) 1 ); // Close
- m_Stream.Write( (int) cont.Serial );
+ m_Stream.Write((byte)1); // Close
+ m_Stream.Write(cont.Serial);
}
}
+ public enum TradeFlag : byte
+ {
+ Display = 0x0,
+ Close = 0x1,
+ Update = 0x2,
+ UpdateGold = 0x3,
+ UpdateLedger = 0x4
+ }
+
public sealed class UpdateSecureTrade : Packet
{
- public UpdateSecureTrade( Container cont, bool first, bool second ) : base( 0x6F )
- {
- EnsureCapacity( 8 );
+ public UpdateSecureTrade(Container cont, bool first, bool second)
+ : this(cont, TradeFlag.Update, first ? 1 : 0, second ? 1 : 0)
+ { }
- m_Stream.Write( (byte) 2 ); // Update
- m_Stream.Write( (int) cont.Serial );
- m_Stream.Write( (int) (first ? 1 : 0) );
- m_Stream.Write( (int) (second ? 1 : 0) );
+ public UpdateSecureTrade(Container cont, TradeFlag flag, int first, int second)
+ : base(0x6F)
+ {
+ EnsureCapacity(17);
+
+ m_Stream.Write((byte)flag);
+ m_Stream.Write(cont.Serial);
+ m_Stream.Write(first);
+ m_Stream.Write(second);
}
}
@@ -2822,7 +2840,7 @@ namespace Server.Network
public SupportedFeatures( NetState ns ) : base( 0xB9, ns.ExtendedSupportedFeatures ? 5 : 3 )
{
- FeatureFlags flags = ExpansionInfo.CurrentExpansion.SupportedFeatures;
+ FeatureFlags flags = ExpansionInfo.CoreExpansion.SupportedFeatures;
flags |= m_AdditionalFlags;
@@ -4142,7 +4160,7 @@ namespace Server.Network
m_Stream.Write( (int) 0 );
}
- CharacterListFlags flags = ExpansionInfo.CurrentExpansion.CharacterListFlags;
+ CharacterListFlags flags = ExpansionInfo.CoreExpansion.CharacterListFlags;
if ( count > 6 )
flags |= (CharacterListFlags.SeventhCharacterSlot | CharacterListFlags.SixthCharacterSlot); // 7th Character Slot - TODO: Is SixthCharacterSlot Required?
@@ -4237,7 +4255,7 @@ namespace Server.Network
m_Stream.WriteAsciiFixed( ci.Building, 31 );
}
- CharacterListFlags flags = ExpansionInfo.CurrentExpansion.CharacterListFlags;
+ CharacterListFlags flags = ExpansionInfo.CoreExpansion.CharacterListFlags;
if ( count > 6 )
flags |= (CharacterListFlags.SeventhCharacterSlot | CharacterListFlags.SixthCharacterSlot); // 7th Character Slot - TODO: Is SixthCharacterSlot Required?
diff --git a/Server/ScriptCompiler.cs b/Server/ScriptCompiler.cs
index cfc15e5b2..8ae4042d7 100644
--- a/Server/ScriptCompiler.cs
+++ b/Server/ScriptCompiler.cs
@@ -55,7 +55,7 @@ namespace Server
{
List list = new List();
- string path = Path.Combine( Core.BaseDirectory, "Data/Assemblies_4_0.cfg" );
+ string path = Path.Combine( Core.BaseDirectory, "Data/Assemblies.cfg" );
if( File.Exists( path ) )
{
@@ -89,15 +89,16 @@ namespace Server
AppendCompilerOption( ref sb, "/d:MONO" );
#endif
- //These three defines are deprecated
if( Core.Is64Bit )
AppendCompilerOption( ref sb, "/d:x64" );
-
- AppendCompilerOption( ref sb, "/d:Framework_2_0" );
- AppendCompilerOption( ref sb, "/d:Framework_4_0" );
-
+
+#if NEWTIMERS
AppendCompilerOption(ref sb, "/d:NEWTIMERS");
+#endif
+
+#if NEWPARENT
AppendCompilerOption(ref sb, "/d:NEWPARENT");
+#endif
return (sb == null ? null : sb.ToString());
}
diff --git a/Server/SecureTrade.cs b/Server/SecureTrade.cs
index 598fcaa73..dcaea833f 100644
--- a/Server/SecureTrade.cs
+++ b/Server/SecureTrade.cs
@@ -18,75 +18,153 @@
*
***************************************************************************/
+#region References
using System;
-using System.Collections;
-using System.Collections.Generic;
+
+using Server.Accounting;
using Server.Items;
using Server.Network;
+#endregion
namespace Server
{
public class SecureTrade
{
- private SecureTradeInfo m_From, m_To;
+ private readonly SecureTradeInfo m_From;
+ private readonly SecureTradeInfo m_To;
+
private bool m_Valid;
- public SecureTradeInfo From
+ public SecureTrade(Mobile from, Mobile to)
{
- get
+ m_Valid = true;
+
+ m_From = new SecureTradeInfo(this, from, new SecureTradeContainer(this));
+ m_To = new SecureTradeInfo(this, to, new SecureTradeContainer(this));
+
+ var from6017 = (from.NetState != null && from.NetState.ContainerGridLines);
+ var to6017 = (to.NetState != null && to.NetState.ContainerGridLines);
+
+ var from704565 = (from.NetState != null && from.NetState.NewSecureTrading);
+ var to704565 = (to.NetState != null && to.NetState.NewSecureTrading);
+
+ from.Send(new MobileStatus(from, to));
+ from.Send(new UpdateSecureTrade(m_From.Container, false, false));
+
+ if (from6017)
{
- return m_From;
+ from.Send(new SecureTradeEquip6017(m_To.Container, to));
+ }
+ else
+ {
+ from.Send(new SecureTradeEquip(m_To.Container, to));
+ }
+
+ from.Send(new UpdateSecureTrade(m_From.Container, false, false));
+
+ if (from6017)
+ {
+ from.Send(new SecureTradeEquip6017(m_From.Container, from));
+ }
+ else
+ {
+ from.Send(new SecureTradeEquip(m_From.Container, from));
+ }
+
+ from.Send(new DisplaySecureTrade(to, m_From.Container, m_To.Container, to.Name));
+ from.Send(new UpdateSecureTrade(m_From.Container, false, false));
+
+ if (from.Account != null && from704565)
+ {
+ from.Send(
+ new UpdateSecureTrade(m_From.Container, TradeFlag.UpdateLedger, from.Account.TotalGold, from.Account.TotalPlat));
+ }
+
+ to.Send(new MobileStatus(to, from));
+ to.Send(new UpdateSecureTrade(m_To.Container, false, false));
+
+ if (to6017)
+ {
+ to.Send(new SecureTradeEquip6017(m_From.Container, from));
+ }
+ else
+ {
+ to.Send(new SecureTradeEquip(m_From.Container, from));
+ }
+
+ to.Send(new UpdateSecureTrade(m_To.Container, false, false));
+
+ if (to6017)
+ {
+ to.Send(new SecureTradeEquip6017(m_To.Container, to));
+ }
+ else
+ {
+ to.Send(new SecureTradeEquip(m_To.Container, to));
+ }
+
+ to.Send(new DisplaySecureTrade(from, m_To.Container, m_From.Container, from.Name));
+ to.Send(new UpdateSecureTrade(m_To.Container, false, false));
+
+ if (to.Account != null && to704565)
+ {
+ to.Send(new UpdateSecureTrade(m_To.Container, TradeFlag.UpdateLedger, to.Account.TotalGold, to.Account.TotalPlat));
}
}
- public SecureTradeInfo To
- {
- get
- {
- return m_To;
- }
- }
+ public SecureTradeInfo From { get { return m_From; } }
+ public SecureTradeInfo To { get { return m_To; } }
- public bool Valid
- {
- get
- {
- return m_Valid;
- }
- }
+ public bool Valid { get { return m_Valid; } }
public void Cancel()
{
- if ( !m_Valid )
- return;
-
- List
- list = m_From.Container.Items;
-
- for ( int i = list.Count - 1; i >= 0; --i )
+ if (!m_Valid)
{
- if ( i < list.Count )
+ return;
+ }
+
+ var list = m_From.Container.Items;
+
+ for (var i = list.Count - 1; i >= 0; --i)
+ {
+ if (i < list.Count)
{
- Item item = list[i];
+ var item = list[i];
- item.OnSecureTrade( m_From.Mobile, m_To.Mobile, m_From.Mobile, false );
+ if (item == m_From.VirtualCheck)
+ {
+ continue;
+ }
- if ( !item.Deleted )
- m_From.Mobile.AddToBackpack( item );
+ item.OnSecureTrade(m_From.Mobile, m_To.Mobile, m_From.Mobile, false);
+
+ if (!item.Deleted)
+ {
+ m_From.Mobile.AddToBackpack(item);
+ }
}
}
list = m_To.Container.Items;
- for ( int i = list.Count - 1; i >= 0; --i )
+ for (var i = list.Count - 1; i >= 0; --i)
{
- if ( i < list.Count )
+ if (i < list.Count)
{
- Item item = list[i];
+ var item = list[i];
- item.OnSecureTrade( m_To.Mobile, m_From.Mobile, m_To.Mobile, false );
+ if (item == m_To.VirtualCheck)
+ {
+ continue;
+ }
- if ( !item.Deleted )
- m_To.Mobile.AddToBackpack( item );
+ item.OnSecureTrade(m_To.Mobile, m_From.Mobile, m_To.Mobile, false);
+
+ if (!item.Deleted)
+ {
+ m_To.Mobile.AddToBackpack(item);
+ }
}
}
@@ -95,203 +173,336 @@ namespace Server
public void Close()
{
- if ( !m_Valid )
+ if (!m_Valid)
+ {
return;
+ }
- m_From.Mobile.Send( new CloseSecureTrade( m_From.Container ) );
- m_To.Mobile.Send( new CloseSecureTrade( m_To.Container ) );
+ m_From.Mobile.Send(new CloseSecureTrade(m_From.Container));
+ m_To.Mobile.Send(new CloseSecureTrade(m_To.Container));
m_Valid = false;
- NetState ns = m_From.Mobile.NetState;
+ var ns = m_From.Mobile.NetState;
- if ( ns != null )
- ns.RemoveTrade( this );
+ if (ns != null)
+ {
+ ns.RemoveTrade(this);
+ }
ns = m_To.Mobile.NetState;
- if ( ns != null )
- ns.RemoveTrade( this );
+ if (ns != null)
+ {
+ ns.RemoveTrade(this);
+ }
- Timer.DelayCall( TimeSpan.Zero, delegate{ m_From.Container.Delete(); } );
- Timer.DelayCall( TimeSpan.Zero, delegate{ m_To.Container.Delete(); } );
+ Timer.DelayCall(m_From.Dispose);
+ Timer.DelayCall(m_To.Dispose);
+ }
+
+ public void UpdateFromCurrency()
+ {
+ UpdateCurrency(m_From, m_To);
+ }
+
+ public void UpdateToCurrency()
+ {
+ UpdateCurrency(m_To, m_From);
+ }
+
+ private static void UpdateCurrency(SecureTradeInfo left, SecureTradeInfo right)
+ {
+ if (left.Mobile.NetState != null && left.Mobile.NetState.NewSecureTrading)
+ {
+ var plat = left.Mobile.Account.TotalPlat;
+ var gold = left.Mobile.Account.TotalGold;
+
+ left.Mobile.Send(new UpdateSecureTrade(left.Container, TradeFlag.UpdateLedger, gold, plat));
+ }
+
+ if (right.Mobile.NetState != null && right.Mobile.NetState.NewSecureTrading)
+ {
+ right.Mobile.Send(new UpdateSecureTrade(right.Container, TradeFlag.UpdateGold, left.Gold, left.Plat));
+ }
}
public void Update()
{
- if ( !m_Valid )
- return;
-
- if ( m_From.Accepted && m_To.Accepted )
+ if (!m_Valid)
{
- List
- list = m_From.Container.Items;
+ return;
+ }
- bool allowed = true;
+ if (!m_From.IsDisposed && m_From.Accepted && !m_To.IsDisposed && m_To.Accepted)
+ {
+ var list = m_From.Container.Items;
- for ( int i = list.Count - 1; allowed && i >= 0; --i )
+ var allowed = true;
+
+ for (var i = list.Count - 1; allowed && i >= 0; --i)
{
- if ( i < list.Count )
+ if (i < list.Count)
{
- Item item = list[i];
+ var item = list[i];
- if ( !item.AllowSecureTrade( m_From.Mobile, m_To.Mobile, m_To.Mobile, true ) )
+ if (item == m_From.VirtualCheck)
+ {
+ continue;
+ }
+
+ if (!item.AllowSecureTrade(m_From.Mobile, m_To.Mobile, m_To.Mobile, true))
+ {
allowed = false;
+ }
}
}
list = m_To.Container.Items;
- for ( int i = list.Count - 1; allowed && i >= 0; --i )
+ for (var i = list.Count - 1; allowed && i >= 0; --i)
{
- if ( i < list.Count )
+ if (i < list.Count)
{
- Item item = list[i];
+ var item = list[i];
- if ( !item.AllowSecureTrade( m_To.Mobile, m_From.Mobile, m_From.Mobile, true ) )
+ if (item == m_To.VirtualCheck)
+ {
+ continue;
+ }
+
+ if (!item.AllowSecureTrade(m_To.Mobile, m_From.Mobile, m_From.Mobile, true))
+ {
allowed = false;
+ }
}
}
- if ( !allowed )
+ if (AccountGold.Enabled)
+ {
+ if (m_From.Mobile.Account != null)
+ {
+ var cur = m_From.Mobile.Account.TotalCurrency;
+ var off = m_From.Plat + (m_From.Gold / Math.Max(1.0, AccountGold.CurrencyThreshold));
+
+ if (off > cur)
+ {
+ allowed = false;
+ m_From.Mobile.SendMessage("You do not have enough currency to complete this trade.");
+ }
+ }
+
+ if (m_To.Mobile.Account != null)
+ {
+ var cur = m_To.Mobile.Account.TotalCurrency;
+ var off = m_To.Plat + (m_To.Gold / Math.Max(1.0, AccountGold.CurrencyThreshold));
+
+ if (off > cur)
+ {
+ allowed = false;
+ m_To.Mobile.SendMessage("You do not have enough currency to complete this trade.");
+ }
+ }
+ }
+
+ if (!allowed)
{
m_From.Accepted = false;
m_To.Accepted = false;
- m_From.Mobile.Send( new UpdateSecureTrade( m_From.Container, m_From.Accepted, m_To.Accepted ) );
- m_To.Mobile.Send( new UpdateSecureTrade( m_To.Container, m_To.Accepted, m_From.Accepted ) );
+ m_From.Mobile.Send(new UpdateSecureTrade(m_From.Container, m_From.Accepted, m_To.Accepted));
+ m_To.Mobile.Send(new UpdateSecureTrade(m_To.Container, m_To.Accepted, m_From.Accepted));
return;
}
+ if (AccountGold.Enabled && m_From.Mobile.Account != null && m_To.Mobile.Account != null)
+ {
+ HandleAccountGoldTrade();
+ }
+
list = m_From.Container.Items;
- for ( int i = list.Count - 1; i >= 0; --i )
+ for (var i = list.Count - 1; i >= 0; --i)
{
- if ( i < list.Count )
+ if (i < list.Count)
{
- Item item = list[i];
+ var item = list[i];
- item.OnSecureTrade( m_From.Mobile, m_To.Mobile, m_To.Mobile, true );
+ if (item == m_From.VirtualCheck)
+ {
+ continue;
+ }
- if ( !item.Deleted )
- m_To.Mobile.AddToBackpack( item );
+ item.OnSecureTrade(m_From.Mobile, m_To.Mobile, m_To.Mobile, true);
+
+ if (!item.Deleted)
+ {
+ m_To.Mobile.AddToBackpack(item);
+ }
}
}
list = m_To.Container.Items;
- for ( int i = list.Count - 1; i >= 0; --i )
+ for (var i = list.Count - 1; i >= 0; --i)
{
- if ( i < list.Count )
+ if (i < list.Count)
{
- Item item = list[i];
+ var item = list[i];
- item.OnSecureTrade( m_To.Mobile, m_From.Mobile, m_From.Mobile, true );
+ if (item == m_To.VirtualCheck)
+ {
+ continue;
+ }
- if ( !item.Deleted )
- m_From.Mobile.AddToBackpack( item );
+ item.OnSecureTrade(m_To.Mobile, m_From.Mobile, m_From.Mobile, true);
+
+ if (!item.Deleted)
+ {
+ m_From.Mobile.AddToBackpack(item);
+ }
}
}
Close();
}
- else
+ else if (!m_From.IsDisposed && !m_To.IsDisposed)
{
- m_From.Mobile.Send( new UpdateSecureTrade( m_From.Container, m_From.Accepted, m_To.Accepted ) );
- m_To.Mobile.Send( new UpdateSecureTrade( m_To.Container, m_To.Accepted, m_From.Accepted ) );
+ m_From.Mobile.Send(new UpdateSecureTrade(m_From.Container, m_From.Accepted, m_To.Accepted));
+ m_To.Mobile.Send(new UpdateSecureTrade(m_To.Container, m_To.Accepted, m_From.Accepted));
}
}
- public SecureTrade( Mobile from, Mobile to )
+ private void HandleAccountGoldTrade()
{
- m_Valid = true;
+ int fromPlatSend = 0, fromGoldSend = 0, fromPlatRecv = 0, fromGoldRecv = 0;
+ int toPlatSend = 0, toGoldSend = 0, toPlatRecv = 0, toGoldRecv = 0;
- m_From = new SecureTradeInfo( this, from, new SecureTradeContainer( this ) );
- m_To = new SecureTradeInfo( this, to, new SecureTradeContainer( this ) );
+ if (m_From.Plat > 0 & m_From.Mobile.Account.WithdrawPlat(m_From.Plat))
+ {
+ fromPlatSend = m_From.Plat;
- bool from6017 = ( from.NetState == null ? false : from.NetState.ContainerGridLines );
- bool to6017 = ( to.NetState == null ? false : to.NetState.ContainerGridLines );
+ if (m_To.Mobile.Account.DepositPlat(m_From.Plat))
+ {
+ toPlatRecv = fromPlatSend;
+ }
+ }
- from.Send( new MobileStatus( from, to ) );
- from.Send( new UpdateSecureTrade( m_From.Container, false, false ) );
- if ( from6017 )
- from.Send( new SecureTradeEquip6017( m_To.Container, to ) );
- else
- from.Send( new SecureTradeEquip( m_To.Container, to ) );
- from.Send( new UpdateSecureTrade( m_From.Container, false, false ) );
- if ( from6017 )
- from.Send( new SecureTradeEquip6017( m_From.Container, from ) );
- else
- from.Send( new SecureTradeEquip( m_From.Container, from ) );
- from.Send( new DisplaySecureTrade( to, m_From.Container, m_To.Container, to.Name ) );
- from.Send( new UpdateSecureTrade( m_From.Container, false, false ) );
+ if (m_From.Gold > 0 & m_From.Mobile.Account.WithdrawGold(m_From.Gold))
+ {
+ fromGoldSend = m_From.Gold;
- to.Send( new MobileStatus( to, from ) );
- to.Send( new UpdateSecureTrade( m_To.Container, false, false ) );
- if ( to6017 )
- to.Send( new SecureTradeEquip6017( m_From.Container, from ) );
- else
- to.Send( new SecureTradeEquip( m_From.Container, from ) );
- to.Send( new UpdateSecureTrade( m_To.Container, false, false ) );
- if ( to6017 )
- to.Send( new SecureTradeEquip6017( m_To.Container, to ) );
- else
- to.Send( new SecureTradeEquip( m_To.Container, to ) );
- to.Send( new DisplaySecureTrade( from, m_To.Container, m_From.Container, from.Name ) );
- to.Send( new UpdateSecureTrade( m_To.Container, false, false ) );
+ if (m_To.Mobile.Account.DepositGold(m_From.Gold))
+ {
+ toGoldRecv = fromGoldSend;
+ }
+ }
+
+ if (m_To.Plat > 0 & m_To.Mobile.Account.WithdrawPlat(m_To.Plat))
+ {
+ toPlatSend = m_To.Plat;
+
+ if (m_From.Mobile.Account.DepositPlat(m_To.Plat))
+ {
+ fromPlatRecv = toPlatSend;
+ }
+ }
+
+ if (m_To.Gold > 0 & m_To.Mobile.Account.WithdrawGold(m_To.Gold))
+ {
+ toGoldSend = m_To.Gold;
+
+ if (m_From.Mobile.Account.DepositGold(m_To.Gold))
+ {
+ fromGoldRecv = toGoldSend;
+ }
+ }
+
+ HandleAccountGoldTrade(m_From.Mobile, m_To.Mobile, fromPlatSend, fromGoldSend, fromPlatRecv, fromGoldRecv);
+ HandleAccountGoldTrade(m_To.Mobile, m_From.Mobile, toPlatSend, toGoldSend, toPlatRecv, toGoldRecv);
+ }
+
+ private static void HandleAccountGoldTrade(
+ Mobile left,
+ Mobile right,
+ int platSend,
+ int goldSend,
+ int platRecv,
+ int goldRecv)
+ {
+ if (platSend > 0 || goldSend > 0)
+ {
+ if (platSend > 0 && goldSend > 0)
+ {
+ left.SendMessage("You traded {0:#,0} platinum and {1:#,0} gold to {2}.", platSend, goldSend, right.RawName);
+ }
+ else if (platSend > 0)
+ {
+ left.SendMessage("You traded {0:#,0} platinum to {1}.", platSend, right.RawName);
+ }
+ else if (goldSend > 0)
+ {
+ left.SendMessage("You traded {0:#,0} gold to {1}.", goldSend, right.RawName);
+ }
+ }
+
+ if (platRecv > 0 || goldRecv > 0)
+ {
+ if (platRecv > 0 && goldRecv > 0)
+ {
+ left.SendMessage("You received {0:#,0} platinum and {1:#,0} gold from {2}.", platRecv, goldRecv, right.RawName);
+ }
+ else if (platRecv > 0)
+ {
+ left.SendMessage("You received {0:#,0} platinum from {1}.", platRecv, right.RawName);
+ }
+ else if (goldRecv > 0)
+ {
+ left.SendMessage("You received {0:#,0} gold from {1}.", goldRecv, right.RawName);
+ }
+ }
}
}
- public class SecureTradeInfo
+ public class SecureTradeInfo : IDisposable
{
- private SecureTrade m_Owner;
- private Mobile m_Mobile;
- private SecureTradeContainer m_Container;
- private bool m_Accepted;
+ public SecureTrade Owner { get; private set; }
+ public Mobile Mobile { get; private set; }
+ public SecureTradeContainer Container { get; private set; }
+ public VirtualCheck VirtualCheck { get; private set; }
- public SecureTradeInfo( SecureTrade owner, Mobile m, SecureTradeContainer c )
+ public int Gold { get { return VirtualCheck.Gold; } set { VirtualCheck.Gold = value; } }
+ public int Plat { get { return VirtualCheck.Plat; } set { VirtualCheck.Plat = value; } }
+
+ public bool Accepted { get; set; }
+
+ public bool IsDisposed { get; private set; }
+
+ public SecureTradeInfo(SecureTrade owner, Mobile m, SecureTradeContainer c)
{
- m_Owner = owner;
- m_Mobile = m;
- m_Container = c;
+ Owner = owner;
+ Mobile = m;
+ Container = c;
- m_Mobile.AddItem( m_Container );
+ Mobile.AddItem(Container);
+
+ VirtualCheck = new VirtualCheck(0, 0);
+ Container.DropItem(VirtualCheck);
}
- public SecureTrade Owner
+ public void Dispose()
{
- get
- {
- return m_Owner;
- }
- }
+ VirtualCheck.Delete();
+ VirtualCheck = null;
- public Mobile Mobile
- {
- get
- {
- return m_Mobile;
- }
- }
+ Container.Delete();
+ Container = null;
- public SecureTradeContainer Container
- {
- get
- {
- return m_Container;
- }
- }
+ Mobile = null;
+ Owner = null;
- public bool Accepted
- {
- get
- {
- return m_Accepted;
- }
- set
- {
- m_Accepted = value;
- }
+ IsDisposed = true;
}
}
}
\ No newline at end of file
diff --git a/Server/Server.csproj b/Server/Server.csproj
index 62bfacff4..371065101 100644
--- a/Server/Server.csproj
+++ b/Server/Server.csproj
@@ -86,6 +86,8 @@
+
+
@@ -145,6 +147,7 @@
+
diff --git a/Server/Skills.cs b/Server/Skills.cs
index 1da5c4881..e31b40212 100644
--- a/Server/Skills.cs
+++ b/Server/Skills.cs
@@ -22,6 +22,8 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
+using System.Linq;
+
using Server.Network;
namespace Server
@@ -689,7 +691,7 @@ namespace Server
}
[PropertyObject]
- public class Skills : IEnumerable
+ public class Skills : IEnumerable
{
private Mobile m_Owner;
private Skill[] m_Skills;
@@ -1108,9 +1110,14 @@ namespace Server
ns.Send( new SkillChange( skill ) );
}
- public IEnumerator GetEnumerator()
+ public IEnumerator GetEnumerator()
{
- return m_Skills.GetEnumerator();
+ return m_Skills.Where(s => s != null).GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return m_Skills.Where(s => s != null).GetEnumerator();
}
}
}
\ No newline at end of file
diff --git a/Server/Utility.cs b/Server/Utility.cs
index 02f33d9c8..aafd854a8 100644
--- a/Server/Utility.cs
+++ b/Server/Utility.cs
@@ -521,6 +521,22 @@ namespace Server
#endregion
#region Get[Something]
+ public static double GetXMLDouble(string doubleString, double defaultValue)
+ {
+ try
+ {
+ return XmlConvert.ToDouble(doubleString);
+ }
+ catch
+ {
+ double val;
+ if (double.TryParse(doubleString, out val))
+ return val;
+
+ return defaultValue;
+ }
+ }
+
public static int GetXMLInt32( string intString, int defaultValue )
{
try