diff --git a/pkg/items/alchSymbol/pkg.cfg b/pkg/items/alchSymbol/pkg.cfg
index f90940561..218c2f9e4 100644
--- a/pkg/items/alchSymbol/pkg.cfg
+++ b/pkg/items/alchSymbol/pkg.cfg
@@ -2,7 +2,7 @@
#
#
-Enabled 1
+Enabled 0
Name alchSymbol
Version 1.0
diff --git a/pkg/items/anvil/config/itemdesc.cfg b/pkg/items/anvil/config/itemdesc.cfg
index 81c088c16..315b05e1d 100644
--- a/pkg/items/anvil/config/itemdesc.cfg
+++ b/pkg/items/anvil/config/itemdesc.cfg
@@ -3,6 +3,7 @@ Item 0x0FAF
Name anvil
Desc Anvil
MethodScript anvil/method
+ Graphic 0x0FAF
}
Item 0x0FB0
@@ -10,6 +11,7 @@ Item 0x0FB0
Name anvil2
Desc Anvil
MethodScript anvil/method
+ Graphic 0x0FB0
}
Item 0x2DD5
@@ -17,6 +19,7 @@ Item 0x2DD5
Name ElvenAnvilSouth
Desc Elven Anvil
MethodScript anvil/method
+ Graphic 0x2DD5
}
Item 0x2DD6
@@ -24,6 +27,7 @@ Item 0x2DD6
Name ElvenAnvilEast
Desc Elven Anvil
MethodScript anvil/method
+ Graphic 0x2DD6
}
Item 0x4254
@@ -31,6 +35,7 @@ Item 0x4254
Name soulforgeanvil1
Desc soul forge anvil
MethodScript anvil/method
+ Graphic 0x4254
}
Item 0x4255
@@ -38,6 +43,7 @@ Item 0x4255
Name soulforgeanvil2
Desc soul forge anvil
MethodScript anvil/method
+ Graphic 0x4255
}
Item 0x4256
@@ -45,6 +51,7 @@ Item 0x4256
Name soulforgeanvil3
Desc soul forge anvil
MethodScript anvil/method
+ Graphic 0x4256
}
Item 0x4257
@@ -52,6 +59,7 @@ Item 0x4257
Name soulforgeanvil4
Desc soul forge anvil
MethodScript anvil/method
+ Graphic 0x4257
}
diff --git a/pkg/items/doors/include/doors.inc b/pkg/items/doors/include/doors.inc
index 29606f2a1..aa8f1668a 100644
--- a/pkg/items/doors/include/doors.inc
+++ b/pkg/items/doors/include/doors.inc
@@ -3,8 +3,11 @@ use uo;
use util;
use cfgfile;
+include "include/client";
include ":keys:key";
+var doordesc := ReadConfigFile (":doors:itemdesc");
+
// New requried functions.....
// Checks to see if the item can be used...
function CanUseDoor( byref mobile, byref door )
@@ -75,3 +78,80 @@ function IsOccupied( item )
return ListMobilesNearLocationEX( x, y, item.z, 0, LISTEX_FLAG_HIDDEN+LISTEX_FLAG_NORMAL, item.realm );
endfunction
+
+///////////////////
+// closes the given door, ignoring locked status
+///////////////////
+
+function CloseDoor (door)
+ if (door.graphic == door.objtype)
+ return;
+ endif
+
+ var xmod := CINT (doordesc[door.objtype].xmod);
+ var ymod := CINT (doordesc[door.objtype].ymod);
+
+ var newx := door.x - xmod;
+ var newy := door.y - ymod;
+ if (GetObjProperty (door, "x"))
+ newx := GetObjProperty (door, "x");
+ newy := GetObjProperty (door, "y");
+ EraseObjProperty (door, "x");
+ EraseObjProperty (door, "y");
+ endif
+
+ var newz := door.z;
+ var newr := door.realm;
+ if (door.graphic != door.objtype)
+ set_critical (1);
+ door.movable := 1;
+ door.graphic := door.objtype;
+ MoveObjectToLocation( door, newx, newy, newz, newr, flags :=MOVEOBJECT_FORCELOCATION );
+ door.movable := 0;
+ set_critical (0);
+ PlayDoorCloseSound (door);
+ endif
+endfunction
+
+///////////////////
+// plays the sound effect for opening the door
+///////////////////
+
+function PlayDoorOpenSound (door)
+ case (doordesc[door.objtype].doortype)
+ "wood":
+ PlaySoundEffect (door, SFX_OPEN_WOODEN_DOOR);
+ "stone":
+ PlaySoundEffect (door, SFX_OPEN_STONE_DOOR);
+ "metal":
+ PlaySoundEffect (door, SFX_OPEN_METAL_DOOR);
+ "sliding":
+ PlaySoundEffect (door, SFX_OPEN_SLIDING_DOOR);
+ default:
+ PlaySoundEffect (door, SFX_OPEN_METAL_DOOR);
+ endcase
+endfunction
+
+
+
+
+///////////////////
+// plays the sound effect for closing the door
+///////////////////
+
+function PlayDoorCloseSound (door)
+ case (doordesc[door.objtype].doortype)
+ "wood":
+ PlaySoundEffect (door, SFX_CLOSE_WOODEN_DOOR);
+ "stone":
+ PlaySoundEffect (door, SFX_CLOSE_STONE_DOOR);
+ "metal":
+ PlaySoundEffect (door, SFX_CLOSE_METAL_DOOR);
+ "sliding":
+ PlaySoundEffect (door, SFX_CLOSE_SLIDING_DOOR);
+ default:
+ PlaySoundEffect (door, SFX_CLOSE_METAL_DOOR);
+ endcase
+endfunction
+
+
diff --git a/pkg/servmgmt/www/script_profiles.src b/pkg/servmgmt/www/script_profiles.src
index 094067bda..a39e873b4 100644
--- a/pkg/servmgmt/www/script_profiles.src
+++ b/pkg/servmgmt/www/script_profiles.src
@@ -43,7 +43,7 @@ program HTMLPage()
foreach profile in ( core.script_profiles )
WriteHTML("
");
- WriteHTML("| "+profile.name+" | "+profile.instr+" | "+profile.invocations+" | "+profile.instr_per_invoc+" | "+profile.instr_percent+"% | ");
+ WriteHTML(""+profile.name+" | "+profile.instr+" | "+profile.invocations+" | "+profile.instr_per_invoc+" | "+cdbl(profile.instr_percent)+"% | ");
WriteHTML("
");
SleepMS(2);
endforeach
diff --git a/pkg/systems/customHousing/config/icp.cfg b/pkg/systems/customHousing/config/icp.cfg
new file mode 100644
index 000000000..fac7094ff
--- /dev/null
+++ b/pkg/systems/customHousing/config/icp.cfg
@@ -0,0 +1,20 @@
+# $Id: icp.cfg 375 2006-06-17 19:26:32Z austinheilman $
+#
+#
+ICP Register
+{
+ Name Custom Housing
+ Version 1.0
+ Description Custom housing scripts that allow for player placed housing to be customized.
+
+ Creator POL Distro Team
+ C_Email poldistro@polserver.com
+
+ Maintainer POL Distro Team
+ M_Email distro@polserver.com
+
+ #Script cmdlevel path
+
+ #TextCmd cmdlevel path
+
+}
diff --git a/pkg/systems/customHousing/config/itemdesc.cfg b/pkg/systems/customHousing/config/itemdesc.cfg
new file mode 100644
index 000000000..9d23a9ca9
--- /dev/null
+++ b/pkg/systems/customHousing/config/itemdesc.cfg
@@ -0,0 +1,740 @@
+Item 0xfbd2
+{
+ Name brasssign
+ Desc house sign
+ Script sign
+ ControlScript signcontrol
+ movable 0
+ Doubleclickrange 6
+ graphic 0x0bd2
+}
+Item 0x16230
+{
+ Name customthreestoryhousedeed
+ Desc deed to a custom three story house
+ Graphic 0x14F0
+ Script scripts/customeHouseDeed
+ VendorSellsFor 1000
+ BuyPrice 1000
+ housetype 0x1147B
+}
+
+Item 0x16231
+{
+ Name customtwostoryhousedeed
+ Desc deed to a custom two story house
+ Graphic 0x14F0
+ Script scripts/customeHouseDeed
+ VendorSellsFor 1000
+ BuyPrice 1000
+ housetype 0x113ec
+}
+
+House 0x113ec
+{
+ Name foundation7x7
+ MultiID 0x13ec
+}
+
+House 0x113ed
+{
+ Name foundation7x8
+ MultiID 0x13ed
+}
+
+House 0x113ee
+{
+ Name foundation7x9
+ MultiID 0x13ee
+}
+
+House 0x113ef
+{
+ Name foundation7x10
+ MultiID 0x13ef
+}
+
+House 0x113f0
+{
+ Name foundation7x11
+ MultiID 0x13f0
+}
+
+House 0x113f1
+{
+ Name foundation7x12
+ MultiID 0x13f1
+}
+
+House 0x113f8
+{
+ Name foundation8x7
+ MultiID 0x13f8
+}
+
+House 0x113f9
+{
+ Name foundation8x8
+ MultiID 0x13f9
+}
+
+House 0x113fa
+{
+ Name foundation8x9
+ MultiID 0x13fa
+}
+
+House 0x113fb
+{
+ Name foundation8x10
+ MultiID 0x13fb
+}
+
+House 0x113fc
+{
+ Name foundation8x11
+ MultiID 0x13fc
+}
+
+House 0x113fd
+{
+ Name foundation8x12
+ MultiID 0x13fd
+}
+
+House 0x113fe
+{
+ Name foundation8x13
+ MultiID 0x13fe
+}
+
+House 0x11404
+{
+ Name foundation9x7
+ MultiID 0x1404
+}
+
+House 0x11405
+{
+ Name foundation9x8
+ MultiID 0x1405
+}
+
+House 0x11406
+{
+ Name foundation9x9
+ MultiID 0x1406
+}
+
+House 0x11407
+{
+ Name foundation9x10
+ MultiID 0x1407
+}
+
+House 0x11408
+{
+ Name foundation9x11
+ MultiID 0x1408
+}
+
+House 0x11409
+{
+ Name foundation9x12
+ MultiID 0x1409
+}
+
+House 0x1140a
+{
+ Name foundation9x13
+ MultiID 0x140a
+}
+
+House 0x1140b
+{
+ Name foundation9x14
+ MultiID 0x140b
+}
+
+House 0x11410
+{
+ Name foundation10x7
+ MultiID 0x1410
+}
+
+House 0x11411
+{
+ Name foundation10x8
+ MultiID 0x1411
+}
+
+House 0x11412
+{
+ Name foundation10x9
+ MultiID 0x1412
+}
+
+House 0x11413
+{
+ Name foundation10x10
+ MultiID 0x1413
+}
+
+House 0x11414
+{
+ Name foundation10x11
+ MultiID 0x1414
+}
+
+House 0x11415
+{
+ Name foundation10x12
+ MultiID 0x1415
+}
+
+House 0x11416
+{
+ Name foundation10x13
+ MultiID 0x1416
+}
+
+House 0x11417
+{
+ Name foundation10x14
+ MultiID 0x1417
+}
+
+House 0x11418
+{
+ Name foundation10x15
+ MultiID 0x1418
+}
+
+House 0x1141c
+{
+ Name foundation11x7
+ MultiID 0x141c
+}
+
+House 0x1141d
+{
+ Name foundation11x8
+ MultiID 0x141d
+}
+
+House 0x1141e
+{
+ Name foundation11x9
+ MultiID 0x141e
+}
+
+House 0x1141f
+{
+ Name foundation11x10
+ MultiID 0x141f
+}
+
+House 0x11420
+{
+ Name foundation11x11
+ MultiID 0x1420
+}
+
+House 0x11421
+{
+ Name foundation11x12
+ MultiID 0x1421
+}
+
+House 0x11422
+{
+ Name foundation11x13
+ MultiID 0x1422
+}
+
+House 0x11423
+{
+ Name foundation11x14
+ MultiID 0x1423
+}
+
+House 0x11424
+{
+ Name foundation11x15
+ MultiID 0x1424
+}
+
+House 0x11425
+{
+ Name foundation11x16
+ MultiID 0x1425
+}
+
+House 0x11428
+{
+ Name foundation12x7
+ MultiID 0x1428
+}
+
+House 0x11429
+{
+ Name foundation12x8
+ MultiID 0x1429
+}
+
+House 0x1142a
+{
+ Name foundation12x9
+ MultiID 0x142a
+}
+
+House 0x1142b
+{
+ Name foundation12x10
+ MultiID 0x142b
+}
+
+House 0x1142c
+{
+ Name foundation12x11
+ MultiID 0x142c
+}
+
+House 0x1142d
+{
+ Name foundation12x12
+ MultiID 0x142d
+}
+
+House 0x1142e
+{
+ Name foundation12x13
+ MultiID 0x142e
+}
+
+House 0x1142f
+{
+ Name foundation12x14
+ MultiID 0x142f
+}
+
+House 0x11430
+{
+ Name foundation12x15
+ MultiID 0x1430
+}
+
+House 0x11431
+{
+ Name foundation12x16
+ MultiID 0x1431
+}
+
+House 0x11432
+{
+ Name foundation12x17
+ MultiID 0x1432
+}
+
+House 0x11435
+{
+ Name foundation13x8
+ MultiID 0x1435
+}
+
+House 0x11436
+{
+ Name foundation13x9
+ MultiID 0x1436
+}
+
+House 0x11437
+{
+ Name foundation13x10
+ MultiID 0x1437
+}
+
+House 0x11438
+{
+ Name foundation13x11
+ MultiID 0x1438
+}
+
+House 0x11439
+{
+ Name foundation13x12
+ MultiID 0x1439
+}
+
+House 0x1143a
+{
+ Name foundation13x13
+ MultiID 0x143a
+}
+
+House 0x1143b
+{
+ Name foundation13x14
+ MultiID 0x143b
+}
+
+House 0x1143c
+{
+ Name foundation13x15
+ MultiID 0x143c
+}
+
+House 0x1143d
+{
+ Name foundation13x16
+ MultiID 0x143d
+}
+
+House 0x1143e
+{
+ Name foundation13x17
+ MultiID 0x143e
+}
+
+House 0x1143f
+{
+ Name foundation13x18
+ MultiID 0x143f
+}
+
+House 0x11442
+{
+ Name foundation14x9
+ MultiID 0x1442
+}
+
+House 0x11443
+{
+ Name foundation14x10
+ MultiID 0x1443
+}
+
+House 0x11444
+{
+ Name foundation14x11
+ MultiID 0x1444
+}
+
+House 0x11445
+{
+ Name foundation14x12
+ MultiID 0x1445
+}
+
+House 0x11446
+{
+ Name foundation14x13
+ MultiID 0x1446
+}
+
+House 0x11447
+{
+ Name foundation14x14
+ MultiID 0x1447
+}
+
+House 0x11448
+{
+ Name foundation14x15
+ MultiID 0x1448
+}
+
+House 0x11449
+{
+ Name foundation14x16
+ MultiID 0x1449
+}
+
+House 0x1144a
+{
+ Name foundation14x17
+ MultiID 0x144a
+}
+
+House 0x1144b
+{
+ Name foundation14x18
+ MultiID 0x144b
+}
+
+House 0x1144f
+{
+ Name foundation15x10
+ MultiID 0x144f
+}
+
+House 0x11450
+{
+ Name foundation15x11
+ MultiID 0x1450
+}
+
+House 0x11451
+{
+ Name foundation15x12
+ MultiID 0x1451
+}
+
+House 0x11452
+{
+ Name foundation15x13
+ MultiID 0x1452
+}
+
+House 0x11453
+{
+ Name foundation15x14
+ MultiID 0x1453
+}
+
+House 0x11454
+{
+ Name foundation15x15
+ MultiID 0x1454
+}
+
+House 0x11455
+{
+ Name foundation15x16
+ MultiID 0x1455
+}
+
+House 0x11456
+{
+ Name foundation15x17
+ MultiID 0x1456
+}
+
+House 0x11457
+{
+ Name foundation15x18
+ MultiID 0x1457
+}
+
+House 0x1145c
+{
+ Name foundation16x11
+ MultiID 0x145c
+}
+
+House 0x1145d
+{
+ Name foundation16x12
+ MultiID 0x145d
+}
+
+House 0x1145e
+{
+ Name foundation16x13
+ MultiID 0x145e
+}
+
+House 0x1145f
+{
+ Name foundation16x14
+ MultiID 0x145f
+}
+
+House 0x11460
+{
+ Name foundation16x15
+ MultiID 0x1460
+}
+
+House 0x11461
+{
+ Name foundation16x16
+ MultiID 0x1461
+}
+
+House 0x11462
+{
+ Name foundation16x17
+ MultiID 0x1462
+}
+
+House 0x11463
+{
+ Name foundation16x18
+ MultiID 0x1463
+}
+
+House 0x11469
+{
+ Name foundation17x12
+ MultiID 0x1469
+}
+
+House 0x1146a
+{
+ Name foundation17x13
+ MultiID 0x146a
+}
+
+House 0x1146b
+{
+ Name foundation17x14
+ MultiID 0x146b
+}
+
+House 0x1146c
+{
+ Name foundation17x15
+ MultiID 0x146c
+}
+
+House 0x1146d
+{
+ Name foundation17x16
+ MultiID 0x146d
+}
+
+House 0x1146e
+{
+ Name foundation17x17
+ MultiID 0x146e
+}
+
+House 0x1146f
+{
+ Name foundation17x18
+ MultiID 0x146f
+}
+
+House 0x11476
+{
+ Name foundation18x13
+ MultiID 0x1476
+}
+
+House 0x11477
+{
+ Name foundation18x14
+ MultiID 0x1477
+}
+
+House 0x11478
+{
+ Name foundation18x15
+ MultiID 0x1478
+}
+
+House 0x11479
+{
+ Name foundation18x16
+ MultiID 0x1479
+}
+
+House 0x1147a
+{
+ Name foundation18x17
+ MultiID 0x147a
+}
+
+House 0x1147b
+{
+ Name foundation18x18
+ MultiID 0x147b
+}
+
+
+Item 0x181d
+{
+ Name housetele1
+ WalkOnScript housetele
+ Weight 1
+// Movable 0
+}
+
+Item 0x181e
+{
+ Name housetele2
+ WalkOnScript housetele
+ Weight 1
+// Movable 0
+}
+
+Item 0x181f
+{
+ Name housetele3
+ WalkOnScript housetele
+ Weight 1
+// Movable 0
+}
+
+Item 0x1820
+{
+ Name housetele4
+ WalkOnScript housetele
+ Weight 1
+// Movable 0
+}
+
+Item 0x1821
+{
+ Name housetele5
+ WalkOnScript housetele
+ Weight 1
+// Movable 0
+}
+
+Item 0x1822
+{
+ Name housetele6
+ WalkOnScript housetele
+ Weight 1
+// Movable 0
+}
+
+Item 0x1823
+{
+ Name housetele7
+ WalkOnScript housetele
+ Weight 1
+// Movable 0
+}
+
+Item 0x1824
+{
+ Name housetele8
+ WalkOnScript housetele
+ Weight 1
+// Movable 0
+}
+
+Item 0x1825
+{
+ Name housetele9
+ WalkOnScript housetele
+ Weight 1
+// Movable 0
+}
+
+Item 0x1826
+{
+ Name housetelea
+ WalkOnScript housetele
+ Weight 1
+// Movable 0
+}
+
+Item 0x1827
+{
+ Name houseteleb
+ WalkOnScript housetele
+ Weight 1
+// Movable 0
+}
+
+Item 0x1828
+{
+ Name housetelec
+ WalkOnScript housetele
+ Weight 1
+// Movable 0
+}
\ No newline at end of file
diff --git a/pkg/systems/customHousing/config/syshook.cfg b/pkg/systems/customHousing/config/syshook.cfg
new file mode 100644
index 000000000..cf9676882
--- /dev/null
+++ b/pkg/systems/customHousing/config/syshook.cfg
@@ -0,0 +1,4 @@
+SystemHookScript syshook/closecustomhouse.ecl
+{
+ CloseCustomHouse CloseCustomHouse
+}
\ No newline at end of file
diff --git a/pkg/systems/customHousing/include/house.inc b/pkg/systems/customHousing/include/house.inc
new file mode 100644
index 000000000..88810c22a
--- /dev/null
+++ b/pkg/systems/customHousing/include/house.inc
@@ -0,0 +1,702 @@
+//include "include/wodinc";
+include ":customhousing:housefriends";
+
+Const HOUSE_LOCKDOWN_ITEM := 1;
+Const HOUSE_RELEASE_ITEM := 2;
+Const HOUSE_SECURE_CONTAINER := 3;
+Const HOUSE_RELEASE_CONTAINER := 4;
+Const HOUSE_RAISE_ITEM := 5;
+Const HOUSE_LOWER_ITEM := 6;
+Const HOUSE_DISPLAY_ITEM := 7;
+
+Const HOUSE_VALUE_LIMIT := 6;
+
+///////////////////
+// gets the housevalue of the given account
+///////////////////
+
+function GetAccountHouseValue (acctname)
+ acctname := Lower (acctname);
+ if (!acctname)
+ return acctname.errortext := ("No accountname supplied");
+ endif
+ var acct := FindAccount (acctname);
+ if (!acct)
+ return acctname.errortext := ("Account " + acctname + " does not exist");
+ endif
+
+ var global_prop_name := "#housing_of_" + acctname;
+ var existing_houses := GetGlobalProperty (global_prop_name);
+ if (!existing_houses or !len (existing_houses))
+ return 0;
+ endif
+
+ var hv_counter := 0;
+ //make sure each sign exists and is still registered to the account
+ foreach sign_serial in existing_houses
+ var sign := SystemFindObjectBySerial (sign_serial);
+ if (sign)
+ var house_owner := Lower (GetObjProperty (sign, "account"));
+ if (house_owner and house_owner == acctname)
+ var sign_hv := GetHouseValueOfSign (sign);
+ if (sign_hv)
+ hv_counter := hv_counter + sign_hv;
+ endif
+ endif
+ endif
+ endforeach
+ return hv_counter;
+endfunction
+
+
+
+
+///////////////////
+// adds the value of the house to the owner's housevalue
+///////////////////
+
+function RecordHouseSignOwner (sign)
+ if (!sign)
+ return sign.errortext := "Sign does not exist!";
+ endif
+
+ var owneraccount := Lower (GetObjProperty (sign, "account"));
+ if (!owneraccount)
+ var try_counter := 0;
+ repeat
+ sleep (1);
+ try_counter := try_counter + 1;
+ owneraccount := Lower (GetObjProperty (sign, "account"));
+ until ((try_counter > 20) or owneraccount);
+ endif
+
+ set_critical (1);
+ var global_prop_name := "";
+ if (owneraccount)
+ var acct := FindAccount (owneraccount);
+ if (acct)
+ global_prop_name := "#housing_of_" + owneraccount;
+ else
+ global_prop_name := "#housing_no_owner";
+ endif
+ else
+ global_prop_name := "#housing_no_owner";
+ endif
+
+ var existing_houses := GetGlobalProperty (global_prop_name);
+ if (!existing_houses)
+ existing_houses := Array {};
+ endif
+
+ if (! (sign.serial in existing_houses))
+ existing_houses.append (sign.serial);
+ SetGlobalProperty (global_prop_name, existing_houses);
+ endif
+
+ set_critical (0);
+ return 1;
+endfunction
+
+
+
+
+///////////////////
+// determines if adding the housevalue will put a character over their limit
+///////////////////
+
+function HouseValueUnderLimit (character, housevalue);
+ var oldhousevalue := GetAccountHouseValue (character.acctname);
+ var newhousevalue := oldhousevalue + housevalue;
+ if (newhousevalue <= HOUSE_VALUE_LIMIT)
+ return 1;
+ else
+ return 0;
+ endif
+endfunction
+
+
+
+
+///////////////////
+// gets a default house price, based on its size
+///////////////////
+
+function GetDefaultHousePrice (housevalue)
+ case (housevalue)
+ 2:
+ return 90000;
+ 3:
+ return 150000;
+ 4:
+ return 400000;
+ 5:
+ return 800000;
+ default:
+ return 40000;
+ endcase
+endfunction
+
+
+
+
+///////////////////
+// determines the housevalue of a given deed
+///////////////////
+
+function GetHouseValueByDeed (deed)
+ case (deed)
+ 0x16023: //tower
+ 0x16230: //customthreestoryhousedeed
+ return 3;
+ 0x16024: //keep
+ 0x16025: //castle
+ return 5;
+ 0x16026: //largepatiohousedeed
+ 0x16020: //largebrickhouse
+ 0x16021: //twostorywood
+ 0x16022: //twostorystone
+ 0x16229: //smalltowerdeed
+ 0x1622A: //sandstonepatiohousedeed
+ 0x1622B: //twostorylogcabindeed
+ 0x1622C: //twostoryvilladeed
+ 0x1622D: //largemarblepatiohousedeed
+ 0x1622E: //ranch house
+ 0x16231: //customtwostoryhousedeed
+ return 2;
+ default:
+ return 1;
+ endcase
+endfunction
+
+
+
+
+///////////////////
+// determines the housevalue of the given sign, whether its one of a static house or deedplaced
+///////////////////
+
+function GetHouseValueOfSign (sign)
+ //static houses:
+ if (sign.objtype == 0x17060)
+ if (GetObjProperty (sign, "housevalue"))
+ return CINT (GetObjProperty (sign, "housevalue"));
+ endif
+ return 1;
+ endif
+
+ if (GetObjProperty (sign, "housevalue"))
+ return CINT (GetObjProperty (sign, "housevalue"));
+ endif
+ //deed-placed houses:
+ var house := SystemFindObjectBySerial (GetObjProperty (sign, "house_serial"));
+ var deed := GetDeedType (house);
+ return GetHouseValueByDeed (deed);
+endfunction
+
+
+
+
+///////////////////
+// determines the deed objtype that corresponds to a given house type
+///////////////////
+
+function GetDeedType (house)
+ var deed := 0;
+ case (house.objtype)
+ 69732: deed := 0x16019;
+ 69734: deed := 0x1601A;
+ 69738: deed := 0x1601B;
+ 69740: deed := 0x1601C;
+ 69742: deed := 0x1601D;
+ 69748: deed := 0x16020;
+ 69750: deed := 0x16021;
+ 69752: deed := 0x16022;
+ 69754: deed := 0x16023;
+ 69756: deed := 0x16024;
+ 69758: deed := 0x16025;
+ 69772: deed := 0x16026;
+ 69792: deed := 0x16227;
+ 69794: deed := 0x16228;
+ 69784: deed := 0x16229;
+ 69788: deed := 0x1622A;
+ 69786: deed := 0x1622B;
+ 69790: deed := 0x1622C;
+ 69782: deed := 0x1622D;
+ 69773: deed := 0x1622E;
+ 69736: deed := 0x1622F;
+ endcase
+ if (house.objtype >= 0x113ec and house.objtype <= 0x1140a)
+ deed := 0x16231;
+ elseif (house.objtype >= 0x11410 and house.objtype <= 0x11416)
+ deed := 0x16231;
+ elseif (house.objtype >= 0x1141c and house.objtype <= 0x11422)
+ deed := 0x16231;
+ elseif (house.objtype >= 0x11428 and house.objtype <= 0x1142e)
+ deed := 0x16231;
+ elseif (house.objtype >= 0x11435 and house.objtype <= 0x1143a)
+ deed := 0x16231;
+ elseif (house.objtype >= 0x1140b and house.objtype <= 0x1147b)
+ deed := 0x16230;
+ endif
+ return deed;
+
+endfunction
+
+
+
+
+///////////////////
+// Determines the maximum number of lockdowns permitted in a house
+///////////////////
+
+function GetMaxLockdowns (sign)
+ var hvalue := GetHouseValueOfSign (sign);
+ return (hvalue * 750);
+endfunction
+
+
+
+
+///////////////////
+// returns the number of items locked down in the house
+///////////////////
+
+function GetLockdowns (sign)
+ var itemlist := dictionary;
+ foreach item in ListObjectsInBox (sign.x-32, sign.y-32, -128, sign.x+32, sign.y+32, +127, sign.realm)
+ if (!item.movable)
+ if ( GetObjProperty( item, "lockeddown" ) == sign.serial )
+ if (!itemlist.exists(item) )
+ itemlist[item] := item;
+ endif
+ endif
+ if ( GetObjProperty( item, "gmlockeddown" ) == sign.serial )
+ if (!itemlist.exists(item) )
+ itemlist[item] := item;
+ endif
+ endif
+ endif
+ endforeach
+
+ Setobjproperty (sign, "lockdowns", itemlist.size() );
+ return itemlist.size();
+endfunction
+
+
+
+
+///////////////////
+// determines the maximum allowed number of secures for the house
+///////////////////
+
+function GetMaxSecures( sign )
+ var hvalue := GetHouseValueOfSign (sign);
+ return (hvalue * 10);
+endfunction
+
+
+///////////////////
+// counts the number of secured items in the house
+///////////////////
+
+function GetSecures (sign)
+ var itemlist := dictionary;
+ foreach item in ListObjectsInBox (sign.x-32, sign.y-32, -128, sign.x+32, sign.y+32, +127, sign.realm)
+ if (!item.movable)
+ if ( GetObjProperty (item, "secured") == sign.serial )
+ if (!itemlist.exists(item) )
+ itemlist[item] := item;
+ endif
+ endif
+ endif
+ endforeach
+
+ Setobjproperty (sign, "secures", itemlist.size() );
+ return itemlist.size();
+endfunction
+
+
+
+
+///////////////////
+// refreshes the house
+///////////////////
+
+function RefreshHouse (sign)
+ var lastvisit := GetObjProperty (sign, "lastvisit");
+ if (!lastvisit)
+ SetObjProperty (sign, "lastvisit", ReadGameClock() );
+ elseif ( lastvisit < ReadGameClock() )
+ SetObjProperty (sign, "lastvisit", ReadGameClock() );
+ endif
+endfunction
+
+
+
+
+///////////////////
+// refreshes the house for a longer period of time
+///////////////////
+
+function LongTermRefresh (sign, owner)
+ var onemonth := 2592000 + ReadGameClock();
+ SetObjProperty (sign, "lastvisit" , onemonth);
+ SendSysMessage (owner, "Your house has been refreshed for one month.");
+endfunction
+
+
+
+
+///////////////////
+// releases all locked down and secured items in the house. Used when the house is destroyed
+///////////////////
+
+function ReleaseAll (owner, sign)
+ var homeinfo := GetObjProperty (sign, "homeinfo");
+// foreach item in ListObjectsInBox (sign.x-32, sign.y-32, -128, sign.x+32, sign.y+32, +127, sign.realm)
+ foreach item in ListObjectsInBox (homeinfo[2], homeinfo[3], -128, homeinfo[4], homeinfo[5], +127, sign.realm)
+ if (!item.movable and item.isa (POLCLASS_ITEM))
+// if ( (item.x >= homeinfo[2] and item.x <= homeinfo[4]) and
+// (item.y >= homeinfo[3] and item.y <= homeinfo[5]) )
+ if (!IsGMLockedDownItem (owner, item))
+ var parms := array{};
+ parms[1] := sign;
+ parms[2] := owner;
+ parms[3] := item;
+ parms[4] := 0;
+ if (GetObjProperty (item, "displaycontainer") == sign.serial)
+ parms[4] := HOUSE_DISPLAY_ITEM;
+ run_script_to_completion (":housing:lockunlock", parms);
+ elseif (GetObjProperty (item, "lockeddown") == sign.serial)
+ parms[4] := HOUSE_LOCKDOWN_ITEM;
+ run_script_to_completion (":housing:lockunlock", parms);
+ elseif (GetObjProperty (item, "secured") == sign.serial)
+ parms[4] := HOUSE_SECURE_CONTAINER;
+ run_script_to_completion (":housing:lockunlock", parms);
+ endif
+ endif
+ endif
+ endforeach
+
+ EraseObjProperty (sign, "lockdowns");
+ EraseObjProperty (sign, "secures" );
+endfunction
+
+
+
+
+///////////////////
+// releases a locked down or secured item
+///////////////////
+
+function ReleaseLockedDownItem (owner, item)
+ if (GetObjProperty (item, "olditem"))
+ if (!ReserveItem (item))
+ return;
+ endif
+ var oldtype := GetObjProperty (item, "olditem");
+ var olditem := CreateItemAtLocation (item.x, item.y, item.z, oldtype, 1, item.realm);
+ olditem.name := item.name;
+ olditem.color := item.color;
+ olditem.graphic := item.graphic;
+ olditem.movable := 1;
+ if (getobjproperty (item, "lockid"))
+ setobjproperty(olditem, "lockid", getobjproperty (item, "lockid") );
+ endif
+ PrinttextAbovePrivate (olditem, "Released!", owner);
+ DestroyItem (item);
+ else
+ item.movable := 1;
+ PrinttextAbovePrivate (item, "Released!", owner );
+ ReleaseItem (item);
+ if (item.decayat)
+ item.decayat := ReadGameClock() + 600;
+ endif
+ endif
+endfunction
+
+
+
+
+///////////////////
+// allows the owner to pick a new owner for the house
+///////////////////
+
+function ChangeOwner (who, sign)
+ SendSysMessage (who, "Transfer ownership to whom?");
+ var newowner := Target (who);
+ if (!newowner or !newowner.acctname)
+ SendSysMessage (who, "Canceled.");
+ return;
+ endif
+
+ if (!HouseValueUnderLimit (newowner, GetHouseValueOfSign (sign)))
+ SendSysMessage (who, "That person owns too many houses!");
+ return;
+ endif
+
+ EraseObjProperty (sign, "housefriends");
+ SetObjProperty (sign, "account", newowner.acctname);
+
+ if (GetObjProperty (sign, "homeinfo"))
+ var homeinfo := GetObjProperty (sign, "homeinfo");
+ homeinfo[1] := newowner.serial;
+ SetObjProperty (sign, "homeinfo", homeinfo);
+ else
+ var house := SystemFindObjectBySerial (GetObjProperty (sign, "house_serial"));
+ SetObjProperty (house, "ownerserial", newowner.serial);
+ endif
+
+ SetObjProperty (sign, "lastownername", newowner.name);
+
+ SendSysMessage (who, "You are no longer the owner of this house!");
+ SendSysMessage (newowner, "You are now the owner of this house!");
+ SendSysMessage (newowner, "You should change the locks soon.");
+endfunction
+
+
+
+
+///////////////////
+// Finds any GM lockeddown items in the house and refunds 1/2 the purchase price to the houseowner
+///////////////////
+
+function IsGMLockedDownItem (owner, item)
+ if (!GetObjProperty (item, "gmlockeddown"))
+ return 0;
+ endif
+
+ var price := GetObjProperty (item, "price");
+ if (!price)
+ DestroyItem (item);
+ return 1;
+ endif
+
+ price := CINT (price/2);
+
+ CreateItemInContainer (owner.backpack, UOBJ_GOLD_COIN, price);
+ SendSysMessage (owner, "You recieve " + price + " gold back for " + item.desc);
+ DestroyItem (item);
+ return 1;
+endfunction
+
+
+
+
+///////////////////
+// handles speech events that the sign hears
+///////////////////
+
+function handle_speech (event, sign)
+ RefreshHouse (sign);
+
+ var text := lower( event.text );
+ if (text["i wish to lock this down"] or text["i wish to release this"])
+ set_critical (1);
+ LockdownItem (sign, event.source);
+ set_critical (0);
+ elseif (text["i wish to secure this"] or text["i wish to unsecure this"])
+ set_critical (1);
+ SecureItem (sign, event.source);
+ set_critical (0);
+ elseif (text["i wish to display this"] or text["i wish to remove this from display"])
+ set_critical (1);
+ DisplayContainer (sign, event.source);
+ set_critical (0);
+ elseif (text["i wish to raise this"])
+ set_critical (1);
+ RaiseItem (sign, event.source);
+ set_critical (0);
+ elseif (text["i wish to lower this"])
+ set_critical (1);
+ LowerItem (sign, event.source);
+ set_critical (0);
+ elseif (text["i wish to refresh this house"])
+ LongTermRefresh (sign, event.source);
+ endif
+
+endfunction
+
+
+
+
+///////////////////
+// allows the character to lock down items
+///////////////////
+
+function LockdownItem (sign, owner)
+ var parms := array{};
+ parms[1] := sign;
+ parms[2] := owner;
+ parms[3] := 0;
+ parms[4] := HOUSE_LOCKDOWN_ITEM;
+ start_script (":housing:lockunlock", parms);
+endfunction
+
+
+
+
+///////////////////
+// allows the player to secure containers
+///////////////////
+
+function SecureItem (sign, owner)
+ var parms := array{};
+ parms[1] := sign;
+ parms[2] := owner;
+ parms[3] := 0;
+ parms[4] := HOUSE_SECURE_CONTAINER;
+ start_script (":housing:lockunlock", parms);
+endfunction
+
+
+
+
+///////////////////
+// allows the house owner to raise the z position of items in the house
+///////////////////
+
+function RaiseItem (sign, owner)
+ var parms := array{};
+ parms[1] := sign;
+ parms[2] := owner;
+ parms[3] := 0;
+ parms[4] := HOUSE_RAISE_ITEM;
+ start_script (":housing:lockunlock", parms);
+endfunction
+
+
+
+
+///////////////////
+// allows the house owner to lower the z position of items in the house
+///////////////////
+
+function LowerItem (sign, owner)
+ var parms := array{};
+ parms[1] := sign;
+ parms[2] := owner;
+ parms[3] := 0;
+ parms[4] := HOUSE_LOWER_ITEM;
+ start_script (":housing:lockunlock", parms);
+
+endfunction
+
+
+
+
+///////////////////
+// Puts a container on display
+///////////////////
+
+function DisplayContainer (sign, owner)
+ var parms := array{};
+ parms[1] := sign;
+ parms[2] := owner;
+ parms[3] := 0;
+ parms[4] := HOUSE_DISPLAY_ITEM;
+ start_script (":housing:lockunlock", parms);
+
+endfunction
+
+
+
+function IsInside (owner, sign, item)
+ var homeinfo := GetObjProperty (sign, "homeinfo");
+ if ( (item.realm == sign.realm) and
+ (item.x >= homeinfo[2] and item.x <= homeinfo[4]) and
+ (item.y >= homeinfo[3] and item.y <= homeinfo[5]) )
+ return 1;
+ else
+ SendSysmessage (owner, "That is not inside your house." );
+ return 0;
+ endif
+endfunction
+
+
+
+
+///////////////////
+// tries to find a house sign near the character that belongs to that character
+///////////////////
+
+function FindHouseSign (character)
+ foreach item in ListObjectsInBox (character.x-32, character.y-32, -128, character.x+32, character.y+32, +127, character.realm)
+ case (item.objtype)
+ 0x17060:
+ 0x0bd2:
+ 0x0bd0:
+ if (IsAFriend (item, character) or character.cmdlevel)
+ if (IsInsideTheHouse (character, item) )
+ return item;
+ endif
+ endif
+ endcase
+ endforeach
+ return 0;
+endfunction
+
+
+
+
+///////////////////
+// determines if the character is within the area the house covers
+///////////////////
+
+function IsInsideTheHouse (character, sign)
+ var homeinfo := GetObjProperty (sign, "homeinfo");
+ if (!homeinfo)
+ return;
+ endif
+
+ if ( (character.realm == sign.realm) and
+ (character.x >= homeinfo[2] and character.x <= homeinfo[4]) and
+ (character.y >= homeinfo[3] and character.y <= homeinfo[5]) )
+ return 1;
+ else
+ return 0;
+ endif
+endfunction
+
+
+
+
+///////////////////
+// tries to find a house sign that covers the given location
+///////////////////
+
+function FindHouseSignAtLocation (x, y, realm)
+ foreach item in ListObjectsInBox (x-32, y-32, -128, x+32, y+32, +127, realm)
+ case (item.objtype)
+ 0x17060:
+ 0x0bd2:
+ 0x0bd0:
+ if (IsLocationWithinHouseSign (item, x, y, realm))
+ return item;
+ endif
+ endcase
+ endforeach
+ return 0;
+endfunction
+
+
+
+
+///////////////////
+// determines if the given sign covers the given X-Y location
+///////////////////
+
+function IsLocationWithinHouseSign (sign, x, y, rlm)
+ var homeinfo := GetObjProperty (sign, "homeinfo");
+ if (!homeinfo)
+ return 0;
+ endif
+
+ if ( (x >= homeinfo[2] and x <= homeinfo[4]) and
+ (y >= homeinfo[3] and y <= homeinfo[5]) and
+ sign.realm == rlm )
+ return 1;
+ else
+ return 0;
+ endif
+endfunction
diff --git a/pkg/systems/customHousing/include/housefriends.inc b/pkg/systems/customHousing/include/housefriends.inc
new file mode 100644
index 000000000..264d45b0c
--- /dev/null
+++ b/pkg/systems/customHousing/include/housefriends.inc
@@ -0,0 +1,178 @@
+
+include ":customhousing:house";
+
+//This was split off from the main house.inc file simply for neatness
+
+
+
+
+///////////////////
+// determines if the given person if a friend of the house
+///////////////////
+
+function IsAFriend (sign, who)
+ if (who.acctname == GetObjProperty (sign, "account"))
+ return 1;
+ endif
+
+ var friends := GetObjProperty (sign, "housefriends");
+ if (!friends)
+ return 0;
+ endif
+
+ foreach key in (friends.keys())
+ if (who.acctname == key)
+ var tempvar := friends[key];
+ if (tempvar[1] == "account" or tempvar[1] == "character")
+ return 1;
+ endif
+ elseif (who.serial == key)
+ var tempvar := friends[key];
+ if (tempvar[1] == "account" or tempvar[1] == "character")
+ return 1;
+ endif
+ endif
+ endforeach
+
+ return 0;
+endfunction
+
+
+
+
+///////////////////
+// Some players aren't really friends, but are allowed to place merchants
+///////////////////
+
+function IsMerchantHouseFriend (sign, theacctname)
+ if (theacctname == GetObjProperty (sign, "account"))
+ return 1;
+ endif
+
+ var friends := GetObjProperty (sign, "housefriends");
+ if (!friends)
+ return 0;
+ endif
+
+ if (theacctname in (friends.keys()))
+ return 1;
+ endif
+
+ return 0;
+endfunction
+
+
+
+
+///////////////////
+// This function really should be in sign.src, but it was messy, so I stuck it here
+///////////////////
+
+function AdjustHouseFriendsFromSign (character, sign, friendnum)
+ if (friendnum > 8)
+ SendSysMessage (character, "Error: invalid gump return/friend number!");
+ return;
+ endif
+
+ var friends := GetObjProperty (sign, "housefriends");
+ if (!friends)
+ friends := dictionary;
+ endif
+
+ var friendkeys := friends.keys();
+
+ //see if they wanted to remove a friend
+ if (friendnum <= friendkeys.size())
+ var chosenkey := friendkeys[friendnum];
+ if (!chosenkey)
+ SendSysmessage (character, "Error! Can't find friend key!");
+ return;
+ endif
+
+ var chosenfriend := friends[chosenkey];
+ if (!chosenfriend)
+ SendSysmessage (character, "Error! Can't find friend from selected key!");
+ return;
+ endif
+
+ SendSysMessage (character, "Are you sure you want to remove " + chosenfriend[2] + " as a house friend?");
+ if (!YesNo (character, "Remove?"))
+ SendSysMessage (character, "Canceled.");
+ return;
+ endif
+
+ friends.erase (chosenkey);
+ SetObjProperty (sign, "housefriends", friends);
+ SendSysMessage (character, "Friend removed.");
+ return;
+ endif
+
+ //Otherwise we're adding a new friend
+ SendSysMessage(character, "Who do you want to add as a friend?");
+ var friend := Target (character);
+ if (!friend)
+ SendSysMessage (character, "Canceled.");
+ return;
+ elseif (!friend.acctname)
+ SendSysMessage (character, "Invalid target! Only players can be house friends");
+ return;
+ endif
+
+ if (friend.acctname in friendkeys)
+ SendSysMessage (character, "That player's account is already a friend of the house.");
+ return;
+ elseif (friend.serial in friendkeys)
+ SendSysMessage (character, "That player is already a friend of the house. If you want to change their options, remove them first.");
+ return;
+ endif
+
+ var friend_gump_layout := array {
+ "page 0",
+ "nodispose",
+ "resizepic 50 50 2620 310 250",
+ "text 70 59 40 0",
+ "page 1",
+
+ "button 70 95 2118 2117 1 1 1",
+ "text 100 90 40 1",
+ "button 70 115 2118 2117 1 1 2",
+ "text 100 110 40 2",
+ "button 70 135 2118 2117 1 1 3",
+ "text 100 130 40 3"
+ };
+
+ var friend_gump_data := array {
+ "Select friend type:", //0
+ "Single character friend",
+ "Set account as friend",
+ "Merchant-only rights"
+ };
+
+ var friend_gump_return := SendDialogGump (character, friend_gump_layout, friend_gump_data);
+ if (!friend_gump_return or !friend_gump_return[0])
+ SendSysMessage (character, "Canceled.");
+ return;
+ endif
+
+ var newfriendentry := Array {};
+ case (friend_gump_return[0])
+ 1: newfriendentry := {"character", friend.name};
+ friends.insert (friend.serial, newfriendentry);
+ SetObjProperty (sign, "housefriends", friends);
+ SendSysMessage (character, "New friend added!");
+ return;
+ 2: newfriendentry := {"account", friend.name};
+ friends.insert (friend.acctname, newfriendentry);
+ SetObjProperty (sign, "housefriends", friends);
+ SendSysMessage (character, "New friend account added!");
+ return;
+ 3: newfriendentry := {"merchant", friend.name};
+ friends.insert (friend.acctname, newfriendentry);
+ SetObjProperty (sign, "housefriends", friends);
+ SendSysMessage (character, "New friend account added!");
+ return;
+ default:
+ SendSysmessage (character, "Error: Invalid gump return");
+ return;
+ endcase
+endfunction
\ No newline at end of file
diff --git a/pkg/systems/customHousing/pkg.cfg b/pkg/systems/customHousing/pkg.cfg
new file mode 100644
index 000000000..4c99363c0
--- /dev/null
+++ b/pkg/systems/customHousing/pkg.cfg
@@ -0,0 +1,6 @@
+Enabled 1
+Name customhousing
+CoreRequired 100
+Maintainer Distro Team
+Email poldistro@polserver.com
+Version 1.0
diff --git a/pkg/systems/customHousing/scripts/customeHouseDeed.src b/pkg/systems/customHousing/scripts/customeHouseDeed.src
new file mode 100644
index 000000000..0f7bbe583
--- /dev/null
+++ b/pkg/systems/customHousing/scripts/customeHouseDeed.src
@@ -0,0 +1,415 @@
+use uo;
+use os;
+use util;
+use cfgfile;
+
+include "include/client";
+include "include/objtype";
+include ":gumps:gumps";
+include ":gumps:gumps_ex";
+include "include/utility";
+include ":containers:storageAreas";
+
+Const UOBJECT_BRASS_SIGN := 0x0bd2;
+Const UOBJECT_WOOD_SIGN := 0x0bd0;
+
+program usehousedeed (character, deed)
+
+ if (!ReserveItem (deed))
+ SendSysMessage (character, "You can't use that right now.");
+ return;
+ endif
+
+ var housecfgfile := ReadConfigFile (":customhousing:itemdesc");
+ var elem := FindConfigElem (housecfgfile, deed.objtype);
+ var housetype := GetConfigInt (elem, "housetype");
+ if (!housetype)
+ PrintTextAbovePrivate (deed, "That house deed appears to be broken.", character);
+ return;
+ endif
+ var multiid := 0;
+ var dims := 0;
+ var extracharges := 0;
+ var gump := 0;
+ var input := 0;
+ if (housetype == 0x113ec)
+ gump := BuildTwoStoryGump();
+ elseif (housetype == 0x1147b)
+ gump := BuildThreeStoryGump();
+ else
+ PrintTextAbovePrivate (deed, "That house deed appears to be broken.", character);
+ return;
+ endif
+ input := GFSendGump( character, gump );
+ if (input[0]!=0x10)
+ SendSysMessage (character, "Canceled.");
+ return;
+ endif
+ housetype := input.keys[3];
+ Broadcast("ht:"+housetype);
+ multiid := housetype - 0x10000;
+ dims := GetMultiDimensions (multiid);
+ extracharges := ((3+dims.xmax-dims.xmin)*(1+dims.ymax-dims.ymin)-3)*500;
+
+ var where := TargetMultiPlacement (character, housetype);
+ if (!where)
+ SendSysMessage (character, "Canceled.");
+ return;
+ endif
+
+ if (!LegalHouseLocation (where.x, where.y, where.realm))
+ SendSysMessage (character, "House placement not allowed there!");
+ return;
+ endif
+
+ set_critical( 1 );
+ var created := CreateHouseAndKeys ( character, housetype, where.x, where.y, where.z, where.realm );
+ if (!created)
+ return;
+ endif
+ if (extracharges > 0 && character.cmdlevel == 0)
+ SendSysMessage (character, "The cost of buying this foundation is " + extracharges + " gold!");
+ if (!YesNo(character, "Buy it?"))
+ SendSysMessage(character, "Canceled.");
+ DestroyItem(created.packkey);
+ DestroyItem(created.bankkey);
+ DestroyMulti(created.house);
+ return;
+ elseif (!character.spendgold (extracharges))
+ SendSysMessage (character, "You don't have enough money");
+ DestroyItem(created.packkey);
+ DestroyItem(created.bankkey);
+ DestroyMulti(created.house);
+ return;
+ endif
+ endif
+
+ DestroyItem(deed);
+ SetObjProperty (created.house, "ownerserial", character.serial);
+ var lockid := created.house.serial;
+ SetObjProperty(created.packkey, "lockid", lockid);
+ SetObjProperty(created.bankkey, "lockid", lockid);
+
+ //now we add some special stuff based on what kind of a house it is
+ var item, sign, component := array { };
+ if (housetype >= 0x113ec && housetype <= 0x1147b) // custom houses
+ created.house.setcustom(1);
+ sign :=CreateItemAtLocation( where.x+dims.xmin, where.y+dims.ymax+1, where.z+7, 0xfbd2, 1, where.realm );
+ SetObjProperty(sign, "house_serial", created.house.serial);
+ sign.movable:=0;
+ component.append (sign.serial);
+ SetObjProperty (sign, "lockid", lockid );
+ SetObjProperty (sign, "account", character.acctname );
+ SetObjProperty (sign, "baseprice", extracharges);
+ SetObjProperty (sign, "houseprice", extracharges);
+ //make bracket
+ item :=CreateItemAtLocation( where.x+dims.xmin, where.y+dims.ymax+1, where.z+7, 0x0b9c, 1, where.realm );
+ SetObjProperty(item, "house_serial", created.house.serial);
+ item.movable:=0;
+ component.append (item.serial);
+ //make pole
+ item :=CreateItemAtLocation( where.x+dims.xmin, where.y+dims.ymax, where.z+7, 0x09, 1, where.realm );
+ SetObjProperty(item, "house_serial", created.house.serial);
+ item.movable:=0;
+ component.append (item.serial);
+ endif
+
+ if (component.size())
+ SetObjProperty (created.house, "components", component);
+ endif
+ foreach item in (created.house.components)
+ if (item.isa (POLCLASS_DOOR))
+ item.locked := 1;
+ SetObjProperty (item, "lockid", lockid);
+ elseif (item.objtype == UOBJECT_BRASS_SIGN or item.objtype == UOBJECT_WOOD_SIGN)
+ SetObjProperty (item, "lockid", lockid );
+ SetObjProperty (item, "account", character.acctname );
+ endif
+ endforeach
+
+
+endprogram
+
+
+
+
+///////////////////
+// builds the house and creates the keys, if possible. If it can't it gives the reason why and return 0;
+// Otherwise, it returns a structure with refrences to the items
+///////////////////
+
+function CreateHouseAndKeys (character, housetype, x, y, z, rlm)
+
+ var packkey := CreateItemInBackpack( character, UOBJ_GOLD_KEY );
+ if (!packkey)
+ PrintTextAbovePrivate (character, "*Your backpack is full!*", character );
+ return 0;
+ endif
+ var bank_region := CP_DEFAULT_AREA;
+ var bankbox := CP_GetStorageContainerForMobile( character, bank_region, CP_CREATE );
+ var bankkey := CreateItemInContainer (bankbox, UOBJ_GOLD_KEY);
+ if (!bankkey)
+ PrintTextAbovePrivate (character, "*Your bankbox is full!*", character );
+ DestroyItem (packkey);
+ return 0;
+ endif
+
+ var house := CreateMultiAtLocation (x, y, z, housetype, 0, rlm);
+ if (!house)
+ PrintTextAbovePrivate (character, "*You can't place the house there!*", character );
+ SendSysMessage (character, house.errortext);
+
+ if (character.cmdlevel)
+ SendSysMessage (character, "Since you're a GM, though, you can cheat");
+ SendSysMessage (character, "Do you wish to place the house here anyway?");
+ if (!YesNo (character, "Continue?"))
+ DestroyItem (packkey);
+ DestroyItem (bankkey);
+ return 0;
+ endif
+ house := CreateMultiAtLocation (x, y, z, housetype, CRMULTI_IGNORE_ALL, rlm);
+ else
+ DestroyItem (packkey);
+ DestroyItem (bankkey);
+ return 0;
+ endif
+ endif
+
+ var result := struct;
+ result.+packkey := packkey;
+ result.+bankkey := bankkey;
+ result.+house := house;
+ return result;
+
+endfunction
+
+
+
+
+///////////////////
+// determines if the area is one where houses can legally be placed
+///////////////////
+
+function LegalHouseLocation (x, y, rlm)
+ //no houses on farmland
+ var maptile := GetMapInfo (x, y, rlm);
+ if (maptile.landtile > 8 and maptile.landtile < 22)
+ return 0;
+ elseif (maptile.landtile >= 0x150 and maptile.landtile <= 0x15c)
+ return 0;
+ elseif (maptile.landtile >= 0x150 and maptile.landtile <= 0x15c)
+ return 0;
+ endif
+
+ if (rlm == _DEFAULT_REALM)
+ //cove
+ if (x > 2192 and x < 2361 and y > 1052 and y < 1271)
+ return 0;
+ //desert
+ elseif (x > 1810 and x < 2060 and y > 800 and y < 890)
+ return 0;
+ //more desert
+ elseif (x > 1810 and x < 1970 and y > 890 and y < 950)
+ return 0;
+ //Despise entrance
+ elseif (x > 1280 and x < 1370 and y > 1040 and y < 1100)
+ return 0;
+ //Britain suburbs teleporter
+ elseif (x > 2080 and x < 2120 and y > 770 and y < 820)
+ return 0;
+ //The heart
+ elseif (x > 750 and x < 850 and y > 1450 and y < 1500)
+ return 0;
+ //Large area with islands south of Trinsic
+ elseif (x > 1550 and x < 2650 and y > 3380 and y < 4080)
+ return 0;
+ //Beach south of Britain
+ elseif (x > 1460 and x < 1530 and y > 1860 and y < 1900)
+ return 0;
+ //The heart
+ elseif (x > 100 and x < 160 and y > 1450 and y < 1490)
+ return 0;
+ //The heart
+ elseif (x > 2700 and x < 2800 and y > 1030 and y < 1130)
+ return 0;
+ //Trinsic and some surrounding land
+ elseif (x > 1780 and x < 2220 and y > 2200 and y < 3000)
+ return 0;
+ //Occlo
+ elseif (x > 3550 and x < 3800 and y > 2350 and y < 2750)
+ return 0;
+ //Magincia
+// elseif (x > 3500 and x < 3820 and y > 2000 and y < 2300)
+// return 0;
+ //N'Julem
+ elseif (x > 3450 and x < 3850 and y > 1030 and y < 1430)
+ return 0;
+ //Fellowship hall
+ elseif (x > 2100 and x < 2150 and y > 750 and y < 820)
+ return 0;
+ //Covetous Entrance
+ elseif (x > 2440 and x < 2540 and y > 900 and y < 950)
+ return 0;
+ //Mountains north of Britain
+ elseif (x > 1420 and x < 1480 and y > 1200 and y < 1250)
+ return 0;
+ //Mountains north of Britain
+ elseif (x > 1600 and x < 1660 and y > 1170 and y < 1220)
+ return 0;
+ endif
+ endif
+
+ return 1;
+
+endfunction
+
+function BuildTwoStoryGump( )
+
+ var gump := GFCreateGump();
+ GFResizePic( gump, 0, 0, GFGetCfgConst( "Defaults", "BackGround" ), 340, 330 );
+ GFResizePic( gump, 15, 15, GFGetCfgConst( "Defaults", "ForeGround" ), 310, 300 );
+
+ GFTextMid( gump, 20, 30, 310, 1720, "Select House Dimensions" );
+ GFAddButton( gump, 35, 250, 2128, 2129, GF_CLOSE_BTN, 0x10 );
+ GFAddButton( gump, 35, 280, 2119, 2120, GF_CLOSE_BTN, 0x0 );
+
+ var y_pos := 60;
+ var page := 2;
+ var widths := array { 7, 8, 9, 10, 11, 12, 13 };
+ foreach housewidth in widths
+ GFAddButton( gump, 30, y_pos+3, 2117, 2118, GF_PAGE_BTN, page );
+ GFTextLine( gump, 50, y_pos, 1720, housewidth + " tiles wide" );
+ y_pos += 20;
+ page += 2;
+ SleepMS(10);
+ endforeach
+ var heights := array { 7, 8, 9, 10, 11, 12 };
+
+ page := 2;
+ var btn_id := 0x113ec;
+ var offsetstep := 6;
+ foreach housewidth in widths
+ y_pos := 60;
+
+ GFPage( gump, page );
+
+ foreach househeight in heights
+ GFRadioButton( gump, 150, y_pos, 210, 211, 0, btn_id );
+ GFTextLine( gump, 173, y_pos, 2100, housewidth + "x" + househeight + " at " + ((((housewidth+2)*househeight)-3)*500) + " gold");
+ y_pos += 20;
+ btn_id += 1;
+ SleepMS(10);
+ endforeach
+ btn_id += offsetstep;
+ SleepMS(10);
+ page += 2;
+ if (housewidth == 7)
+ heights.append(13);
+ offsetstep := 5;
+ endif
+ if (housewidth == 12)
+ heights.erase(1);
+ endif
+ endforeach
+
+ return gump;
+endfunction
+
+function BuildThreeStoryGump( )
+
+ var gump := GFCreateGump();
+ GFResizePic( gump, 0, 0, GFGetCfgConst( "Defaults", "BackGround" ), 340, 330 );
+ GFResizePic( gump, 15, 15, GFGetCfgConst( "Defaults", "ForeGround" ), 310, 300 );
+
+ GFTextMid( gump, 20, 30, 310, 1720, "Select House Dimensions" );
+ GFAddButton( gump, 35, 250, 2128, 2129, GF_CLOSE_BTN, 0x10 );
+ GFAddButton( gump, 35, 280, 2119, 2120, GF_CLOSE_BTN, 0x0 );
+
+ var y_pos := 60;
+ var page := 2;
+ var widths := array { "9-11", "12-13", 14, 15, 16, 17, 18 };
+ foreach housewidth in widths
+ GFAddButton( gump, 30, y_pos+3, 2117, 2118, GF_PAGE_BTN, page );
+ GFTextLine( gump, 50, y_pos, 1720, housewidth + " tiles wide" );
+ y_pos += 20;
+ page += 2;
+ SleepMS(10);
+ endforeach
+ widths.erase(1);
+ widths.erase(1);
+ var heights := array { 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 };
+
+ page := 2;
+ GFPage( gump, page );
+ GFRadioButton( gump, 150, 60, 210, 211, 0, 0x1140b );
+ GFTextLine( gump, 173, 60, 2100, "9x14 at 75500 gold");
+
+ GFRadioButton( gump, 150, 80, 210, 211, 0, 0x11417 );
+ GFTextLine( gump, 173, 80, 2100, "10x14 at 82500 gold");
+
+ GFRadioButton( gump, 150, 100, 210, 211, 0, 0x11418 );
+ GFTextLine( gump, 173, 100, 2100, "10x15 at 88500 gold");
+
+ GFRadioButton( gump, 150, 120, 210, 211, 0, 0x11423 );
+ GFTextLine( gump, 173, 120, 2100, "11x14 at 89500 gold");
+
+ GFRadioButton( gump, 150, 140, 210, 211, 0, 0x11424 );
+ GFTextLine( gump, 173, 140, 2100, "11x15 at 96000 gold");
+
+ GFRadioButton( gump, 150, 160, 210, 211, 0, 0x11425 );
+ GFTextLine( gump, 173, 160, 2100, "11x16 at 102500 gold");
+
+ page := 4;
+ GFPage( gump, page );
+ GFRadioButton( gump, 150, 60, 210, 211, 0, 0x1142f );
+ GFTextLine( gump, 173, 60, 2100, "12x14 at 96500 gold");
+
+ GFRadioButton( gump, 150, 80, 210, 211, 0, 0x11430 );
+ GFTextLine( gump, 173, 80, 2100, "12x15 at 103500 gold");
+
+ GFRadioButton( gump, 150, 100, 210, 211, 0, 0x11431 );
+ GFTextLine( gump, 173, 100, 2100, "12x16 at 110500 gold");
+
+ GFRadioButton( gump, 150, 120, 210, 211, 0, 0x11432 );
+ GFTextLine( gump, 173, 120, 2100, "12x17 at 117500 gold");
+
+ GFRadioButton( gump, 150, 140, 210, 211, 0, 0x1143b );
+ GFTextLine( gump, 173, 140, 2100, "13x14 at 103500 gold");
+
+ GFRadioButton( gump, 150, 160, 210, 211, 0, 0x1143c );
+ GFTextLine( gump, 173, 160, 2100, "13x15 at 111000 gold");
+
+ GFRadioButton( gump, 150, 180, 210, 211, 0, 0x1143d );
+ GFTextLine( gump, 173, 180, 2100, "13x16 at 118500 gold");
+
+ GFRadioButton( gump, 150, 200, 210, 211, 0, 0x1143e );
+ GFTextLine( gump, 173, 200, 2100, "13x17 at 126000 gold");
+
+ GFRadioButton( gump, 150, 220, 210, 211, 0, 0x1143f );
+ GFTextLine( gump, 173, 220, 2100, "13x18 at 133500 gold");
+
+
+ var btn_id := 0x11442;
+ var offsetstep := 3;
+ page := 6;
+ foreach housewidth in widths
+ y_pos := 60;
+
+ GFPage( gump, page );
+
+ foreach househeight in heights
+ GFRadioButton( gump, 150, y_pos, 210, 211, 0, btn_id );
+ GFTextLine( gump, 173, y_pos, 2100, housewidth + "x" + househeight + " at " + ((((housewidth+2)*househeight)-3)*500) + " gold");
+ y_pos += 20;
+ btn_id += 1;
+ SleepMS(10);
+ endforeach
+ btn_id += offsetstep;
+ offsetstep += 1;
+ SleepMS(10);
+ page += 2;
+ heights.erase(1);
+ endforeach
+
+ return gump;
+endfunction
diff --git a/pkg/systems/customHousing/sign.src b/pkg/systems/customHousing/sign.src
new file mode 100644
index 000000000..94719c832
--- /dev/null
+++ b/pkg/systems/customHousing/sign.src
@@ -0,0 +1,632 @@
+use uo;
+use os;
+
+include "include/client";
+include "include/objtype";
+include "include/utility";
+include ":itemutils:itemtypes";
+include ":gumps:gumps";
+include ":customhousing:house";
+include ":doors:doors";
+
+var gump_layout := array{};
+var gump_data := array{};
+
+program use_house_sign (character, sign)
+ broadcast("PING");
+ //If its a deeded house, make sure its house exists...
+ if (sign.objtype != 0x17060)
+ var hserial := GetObjProperty (sign, "house_serial");
+ if (!hserial)
+ return;
+ endif
+ endif
+
+// //Friends don't get the options
+// if (!IsAFriend (sign, character))
+// DisplayNonFriendSign (character, sign);
+// return;
+// endif
+
+ BuildHouseSignGump (character, sign);
+ SendSysMessage (character, "Your current Housevalue is " + GetAccountHouseValue (character.acctname) );
+
+ var result := SendDialogGump (character, gump_layout, gump_data );
+ var accountname := GetObjProperty (sign, "account");
+ if (accountname != character.acctname and character.cmdlevel < 3)
+ SendSysMessage (character, "This is not your house!");
+ return;
+ endif
+
+ case (result[0])
+ 1:
+ //disown or demolish the house, depending on if its static or deeded
+ if (sign.objtype == 0x17060)
+ DisownHouse (character, sign);
+ else
+ var hserial := GetObjProperty (sign, "house_serial");
+ var house := SystemFindObjectBySerial (hserial);
+ if (!MakeADeed (character, house))
+ return;
+ endif
+ var addons := GetObjProperty (house, "components");
+ if (addons.size())
+ foreach item in addons
+ DestroyItem (SystemFindObjectBySerial (item));
+ endforeach
+ endif
+ ReleaseAll (character, sign);
+ DestroyMulti (house);
+ endif
+ 2: RenameHouse (character, sign);
+ 3: ChangeHouseLocks (character, sign);
+ 5:
+ set_critical (1);
+ ChangeOwner (character, sign);
+ set_critical (0);
+ 6:
+ ChangeHouseSign (character, sign);
+ 7:
+ var customhouse := SystemFindObjectBySerial (GetObjProperty (sign, "house_serial"));
+ if (customhouse.custom)
+ var homeinfo := GetObjProperty (sign, "homeinfo");
+ if (!homeinfo)
+ SendSysMessage (character, "Error finding house definition.");
+ return;
+ endif
+ CloseHouseDoors (character, sign);
+ MoveObjectToLocation(character, (homeinfo[4] + homeinfo[2]) / 2, (homeinfo[5] + homeinfo[3]) / 2, sign.z, sign.realm, MOVEOBJECT_FORCELOCATION);
+ SendPacket (character, "B9000F97DF");
+ if (!character.concealed)
+ character.concealed := 1;
+ endif
+ customhouse.acceptcommit(character, 0);
+ var customizehouse := SendHousingTool(character, customhouse);
+ if (!customizehouse)
+ SendSysMessage (character, "Error: " + customizehouse.errortext);
+ endif
+ else
+ SendSysMessage (character, "Your house can't be customized.");
+ endif
+ 101:
+ 102:
+ 103:
+ 104:
+ 105:
+ 106:
+ 107:
+ 108:
+ AdjustHouseFriendsFromSign (character, sign, CINT(result[0])-100 );
+ default:
+ SendSysMessage (character, "Error: Unknown gump return!");
+ return;
+ endcase
+endprogram
+
+
+function CloseHouseDoors (character, sign)
+ var homeinfo := GetObjProperty (sign, "homeinfo");
+ if (!homeinfo)
+ SendSysMessage (character, "Error finding house definition.");
+ return;
+ endif
+ foreach item in ListObjectsInBox (homeinfo[2], homeinfo[3], -127, homeinfo[4], homeinfo[5], 127, sign.realm)
+ if (IsDoor (item))
+ CloseDoor(item);
+ endif
+ endforeach
+
+endfunction
+
+
+///////////////////
+// changes the locks on the doors
+///////////////////
+
+function ChangeHouseLocks (character, sign)
+ var homeinfo := GetObjProperty (sign, "homeinfo");
+ if (!homeinfo)
+ SendSysMessage (character, "Error finding house definition.");
+ return;
+ endif
+
+ SendSysmessage (character, "Target the new master key.");
+ var newkey := Target (character);
+ if (!newkey)
+ SendSysMessage (character, "Canceled.");
+ return;
+ elseif (!IsAKey (newkey))
+ SendSysMessage (character, "That is not a key!");
+ return;
+ elseif (GetObjProperty (newkey, "lockid"))
+ SendSysMessage (character, "That seems to be the key to something else already.");
+ SendSysMessage (character, "If you use that key, it will no longer work on its previous lock.");
+ if (!YesNo (character, "Continue?"))
+ SendSysMessage (character, "Canceled.");
+ return;
+ endif
+ endif
+
+ var lockid := GetObjProperty(sign, "house_serial")+1;
+ SetObjProperty (newkey, "lockid", lockid);
+ SetObjProperty (sign, "lockid", lockid);
+ foreach item in ListObjectsInBox (sign.x - 32, sign.y - 32, -127, sign.x + 32, sign.y + 32, 127, sign.realm)
+ if (IsDoor (item))
+ if ((item.x >= homeinfo[2] and item.x <= homeinfo[4]) and (item.y >= homeinfo[3] and item.y <= homeinfo[5]) )
+ item.locked := 1;
+ SetObjProperty (item, "lockid", lockid);
+ PrintTextAbove (item, "*LOCKED*");
+ endif
+ endif
+ endforeach
+ SendSysmessage (character, "Locks Changed.");
+endfunction
+
+
+
+
+///////////////////
+// called when the character demolishes a house, this function makes a new deed for the house
+///////////////////
+
+function MakeADeed (character, house)
+ var deedtype := GetDeedType (house);
+ if (!deedtype)
+ SendSysMessage (character, "Error finding deed type.");
+ return 0;
+ endif
+
+ if (deedtype == 0x16230 or deedtype == 0x16231)
+ var components := GetObjProperty (house, "components");
+ var sign := 0;
+ var price := 0;
+ foreach compo in (components)
+ sign := SystemFindObjectBySerial(compo);
+ if (sign.objtype == 0x0bd0 or sign.objtype == 0x0bd2)
+ price := GetObjProperty (sign, "houseprice");
+ break;
+ endif
+ endforeach
+ if (price > 0)
+ var discount := CINT (price/10);
+ if (discount > 10000)
+ discount := 10000;
+ endif
+ var theprice := price - discount;
+
+ SendSysMessage (character, "The value of this house is " + theprice + " gold.");
+ if (!YesNo (character, "Sell it?"))
+ SendSysMessage (character, "Canceled.");
+ return 0;
+ endif
+ var newdeed := CreateItemInContainer (character.backpack, deedtype, 1);
+ if (!newdeed)
+ PrintTextAbovePrivate (character, "*Your backpack is full!*", character);
+ return 0;
+ endif
+ while (theprice > 60000)
+ if (CreateItemInContainer (character.backpack, UOBJ_GOLD_COIN, 60000))
+ theprice := theprice - 60000;
+ else
+ SendSysMessage (character, "Error creating gold! You'll have to page a GM...");
+ SetObjProperty (character, "OWEDGOLD", theprice);
+ theprice := 0;
+ endif
+ endwhile
+ CreateItemInContainer (character.backpack, UOBJ_GOLD_COIN, theprice);
+ endif
+ else
+ var newdeed := CreateItemInContainer (character.backpack, deedtype, 1);
+ if (!newdeed)
+ PrintTextAbovePrivate (character, "*Your backpack is full!*", character);
+ return 0;
+ endif
+ endif
+ return 1;
+endfunction
+
+
+
+
+///////////////////
+// When the character disowns a static house, this function refunds their money
+///////////////////
+
+function DisownHouse (character, sign)
+ var housevalue := GetHouseValueOfSign (sign);
+ var price := GetObjProperty (sign, "houseprice");
+ if (!price)
+ price := GetDefaultHousePrice (housevalue);
+ endif
+
+ var discount := CINT (price/10);
+ if (discount > 10000)
+ discount := 10000;
+ endif
+ var theprice := price - discount;
+
+ SendSysMessage (character, "The value of this house is " + theprice + " gold.");
+ if (!YesNo (character, "Sell it?"))
+ SendSysMessage (character, "Canceled.");
+ return;
+ endif
+
+ //make a new forsale sign
+ var newsign := CreateItemAtLocation (sign.x, sign.y, sign.z, 0x1708a, 1, sign.realm);
+ if (!newsign)
+ return;
+ endif
+ newsign.movable := 0;
+
+ SetObjProperty (newsign, "houseprice", price);
+ newsign.name := "For Sale " + price + " gold";
+ while (theprice > 60000)
+ if (CreateItemInContainer (character.backpack, UOBJ_GOLD_COIN, 60000))
+ theprice := theprice - 60000;
+ else
+ SendSysMessage (character, "Error creating gold! You'll have to page a GM...");
+ SetObjProperty (character, "OWEDGOLD", theprice);
+ theprice := 0;
+ endif
+ endwhile
+ CreateItemInContainer (character.backpack, UOBJ_GOLD_COIN, theprice);
+
+ SetObjProperty (newsign, "housevalue", housevalue);
+ if (GetObjProperty (sign, "originalgraphic"))
+ newsign.graphic := GetObjProperty (sign, "originalgraphic");
+ SetObjProperty (newsign, "originalgraphic", newsign.graphic);
+ endif
+
+ var homeinfo := GetObjProperty (sign, "homeinfo");
+ homeinfo[1] := 0;
+ SetObjProperty (newsign, "homeinfo", homeinfo);
+
+ foreach item in ListItemsNearLocation (sign.x, sign.y, sign.z, 32, sign.realm)
+ if(Item.Isa (POLCLASS_DOOR))
+ if ((item.x >= homeinfo[2] and item.x <= homeinfo[4]) and
+ (item.y >= homeinfo[3] and item.y <= homeinfo[5]) )
+ item.locked := 0;
+ EraseObjProperty (item, "lockid");
+ PrintTextAbove (item, "*UNLOCKED*");
+ endif
+ endif
+ endforeach
+
+ ReleaseAll (character, sign);
+ DestroyItem (sign);
+endfunction
+
+
+
+
+///////////////////
+// can change the name of the house
+///////////////////
+
+function RenameHouse (character, sign)
+ var newname := SendTextEntryGump (character, "Name it what?", TE_CANCEL_ENABLE, TE_STYLE_NORMAL, 20);
+ if (!newname)
+ SendSysMessage (character, "Canceled");
+ elseif (len(SplitWords (newname)) > 5)
+ Sendsysmessage (character, "House sign names are limited to 5 words or less.");
+ else
+ SetObjProperty (sign, "housename", newname);
+ sign.name := "A House Sign";
+ endif
+endfunction
+
+
+
+
+///////////////////
+// changes the graphic of the housesign
+///////////////////
+
+function ChangeHouseSign (character, sign)
+ var offset := 0;
+ if (sign.objtype == 0x0bd0 or sign.objtype == 0x0bd2)
+ offset := 1;
+ elseif (GetObjProperty (sign, "originalgraphic") == 0x0bd2)
+ offset := 1;
+ elseif (GetObjProperty (sign, "originalgraphic") == 0x0bd0)
+ offset := 1;
+ endif
+
+ var itemmenu := CreateMenu ("Select a sign:");
+ AddMenuItem (itemmenu, 0x0bcf, "sign");
+ AddMenuItem (itemmenu, 0x0bd1, "sign");
+ AddMenuItem (itemmenu, 0x0b95, "sign");
+ AddMenuItem (itemmenu, 0x0ba3, "sign");
+ AddMenuItem (itemmenu, 0x0ba5, "sign");
+ AddMenuItem (itemmenu, 0x0ba7, "sign");
+ AddMenuItem (itemmenu, 0x0ba9, "sign");
+ AddMenuItem (itemmenu, 0x0bab, "sign");
+ AddMenuItem (itemmenu, 0x0bad, "sign");
+ AddMenuItem (itemmenu, 0x0baf, "sign");
+ AddMenuItem (itemmenu, 0x0bb1, "sign");
+ AddMenuItem (itemmenu, 0x0bb3, "sign");
+ AddMenuItem (itemmenu, 0x0bb5, "sign");
+ AddMenuItem (itemmenu, 0x0bb7, "sign");
+ AddMenuItem (itemmenu, 0x0bb9, "sign");
+ AddMenuItem (itemmenu, 0x0bbb, "sign");
+ AddMenuItem (itemmenu, 0x0bbd, "sign");
+ AddMenuItem (itemmenu, 0x0bbf, "sign");
+ AddMenuItem (itemmenu, 0x0bc1, "sign");
+ AddMenuItem (itemmenu, 0x0bc3, "sign");
+ AddMenuItem (itemmenu, 0x0bc5, "sign");
+ AddMenuItem (itemmenu, 0x0bc7, "sign");
+ AddMenuItem (itemmenu, 0x0bc9, "sign");
+ AddMenuItem (itemmenu, 0x0bcb, "sign");
+ AddMenuItem (itemmenu, 0x0bcd, "sign");
+ AddMenuItem (itemmenu, 0x0bd3, "sign");
+ AddMenuItem (itemmenu, 0x0bd5, "sign");
+ AddMenuItem (itemmenu, 0x0bd7, "sign");
+ AddMenuItem (itemmenu, 0x0bd9, "sign");
+ AddMenuItem (itemmenu, 0x0bdb, "sign");
+ AddMenuItem (itemmenu, 0x0bdd, "sign");
+ AddMenuItem (itemmenu, 0x0bdf, "sign");
+ AddMenuItem (itemmenu, 0x0be1, "sign");
+ AddMenuItem (itemmenu, 0x0be3, "sign");
+ AddMenuItem (itemmenu, 0x0be5, "sign");
+ AddMenuItem (itemmenu, 0x0be7, "sign");
+ AddMenuItem (itemmenu, 0x0be9, "sign");
+ AddMenuItem (itemmenu, 0x0beb, "sign");
+ AddMenuItem (itemmenu, 0x0bed, "sign");
+ AddMenuItem (itemmenu, 0x0bef, "sign");
+ AddMenuItem (itemmenu, 0x0bf1, "sign");
+ AddMenuItem (itemmenu, 0x0bf3, "sign");
+ AddMenuItem (itemmenu, 0x0bf5, "sign");
+ AddMenuItem (itemmenu, 0x0bf7, "sign");
+ AddMenuItem (itemmenu, 0x0bf9, "sign");
+ AddMenuItem (itemmenu, 0x0bfb, "sign");
+ AddMenuItem (itemmenu, 0x0bfd, "sign");
+ AddMenuItem (itemmenu, 0x0bff, "sign");
+ AddMenuItem (itemmenu, 0x0c01, "sign");
+ AddMenuItem (itemmenu, 0x0c03, "sign");
+ AddMenuItem (itemmenu, 0x0c05, "sign");
+ AddMenuItem (itemmenu, 0x0c07, "sign");
+ AddMenuItem (itemmenu, 0x0c09, "sign");
+ AddMenuItem (itemmenu, 0x0c0b, "sign");
+ AddMenuItem (itemmenu, 0x0c0d, "sign");
+ AddMenuItem (itemmenu, 0x0c43, "sign");
+ var selection := SelectMenuItem2 (character, itemmenu);
+ if (!selection.objtype)
+ SendSysMessage (character, "Canceled.");
+ return;
+ endif
+
+ sign.graphic := (selection.objtype + offset);
+endfunction
+
+
+
+
+///////////////////
+// builds the gump to be displayed
+///////////////////
+
+function BuildHouseSignGump (character, sign)
+ gump_layout := array {
+ "page 0",
+ "resizepic 0 50 2620 310 350",
+ "gumppic 83 0 100",
+ "text 100 29 40 0",
+ "text 100 47 40 10",
+ "text 20 108 40 1",
+ "text 100 108 40 2",
+ "text 205 108 40 3",
+ "button 55 105 2640 2641 0 1",
+ "button 160 105 2640 2641 0 2",
+ "button 260 105 2640 2641 0 3",
+ "button 234 68 242 241 1 0 0",
+
+ "page 1",
+ "text 20 150 40 4",
+ "text 140 150 40 7",
+ "text 20 180 40 12",
+ "text 180 180 40 13",
+ "text 20 210 40 14",
+ "text 180 210 40 15",
+
+ "page 2",
+ "text 40 150 40 17",
+ "text 40 170 40 18",
+ "text 40 190 40 19",
+ "text 40 210 40 20",
+ "text 40 230 40 21",
+ "text 40 250 40 22",
+ "text 40 270 40 23",
+ "text 40 290 40 24",
+ "button 20 155 2104 2103 1 0 101",
+ "button 20 175 2104 2103 1 0 102",
+ "button 20 195 2104 2103 1 0 103",
+ "button 20 215 2104 2103 1 0 104",
+ "button 20 235 2104 2103 1 0 105",
+ "button 20 255 2104 2103 1 0 106",
+ "button 20 275 2104 2103 1 0 107",
+ "button 20 295 2104 2103 1 0 108",
+
+ "page 3",
+ "text 20 147 40 6",
+ "text 20 177 40 9",
+ "text 20 207 40 27",
+ "text 20 237 40 11",
+ "text 20 267 40 16",
+ "text 20 297 40 28",
+ "button 200 145 2640 2641 0 4",
+ "button 200 175 2640 2641 1 3 2",
+ "button 200 205 2640 2641 1 3 6",
+ "button 200 235 2640 2641 1 3 3",
+ "button 200 265 2640 2641 1 3 5",
+ "button 200 295 2640 2641 1 3 7",
+
+ "page 4",
+ "text 55 183 40 8",
+ "button 205 180 2640 2641 1 4 1"
+ };
+
+ gump_data := array {
+ "", //0 house name 1
+ "Info", //1
+ "Friends", //2
+ "Options", //3
+ "House Owner :", //4
+ "", //5
+ "Demolish this house", //6
+ "", //7, owner
+ "Are you SURE?", //8
+ "Rename this house", //9
+ "", //10 house name
+ "Change the locks", //11
+ "Lockdowns:", //12
+ "", //13
+ "Secure Containers:", //14
+ "", //15
+ "Change Owners", //16
+ "New Friend", //17 - friend 1
+ "New Friend", //18 - friend 2
+ "New Friend", //19 - friend 3
+ "New Friend", //20 - friend 4
+ "New Friend", //21 - friend 5
+ "New Friend", //22 - friend 6
+ "New Friend", //23 - friend 7
+ "New Friend", //24 - friend 8
+ "New Friend", //25 - friend 9
+ "New Friend", //26 - friend 10
+ "Change Signs", //27
+ "Customize House" //28
+ };
+
+ gump_data[14] := CSTR(GetLockdowns (sign)) + " / " + CSTR(GetMaxLockdowns (sign));
+ gump_data[16] := CSTR(GetSecures (sign))+ " / " + CSTR(GetMaxSecures (sign));
+
+ //a couple of changes for static houses...
+ if (sign.objtype == 0x17060)
+ gump_data[7] := "Disown this House";
+ endif
+
+ if (GetObjProperty (sign, "housefriends"))
+ var friends := GetObjProperty (sign, "housefriends");
+ var counter := 18;
+ foreach key in (friends.keys())
+ var tempvar := friends[key];
+ if (tempvar)
+ var tempname := tempvar[2];
+ if (tempvar[1] == "account")
+ tempname := tempname + " (account)";
+ elseif (tempvar[1] == "merchant")
+ tempname := tempname + " (merchants)";
+ endif
+ gump_data[counter] := tempname;
+ counter := counter + 1;
+ endif
+ endforeach
+ endif
+
+ var accountname := GetObjProperty (sign, "account");
+ SetPlaqueName (sign);
+ if (accountname == character.acctname)
+ RefreshHouse (character);
+ gump_data[8] := character.name;
+ SetObjProperty (sign, "lastownername", character.name);
+ else
+ gump_data[8] := GetObjProperty (sign, "lastownername");
+ if (!gump_data[8])
+ gump_data[8] := FindOwnerName (sign);
+ endif
+ endif
+endfunction
+
+
+
+
+///////////////////
+// splits up the words in the house's name so that it can be displayed
+///////////////////
+
+function SetPlaqueName (sign)
+ var signname := sign.desc;
+ if (!signname)
+ gump_data[1] := "-";
+ return;
+ elseif (len(signname) < 12)
+ gump_data[1] := signname;
+ return;
+ endif
+
+ var splitted := SplitWords (signname);
+ if (!splitted.size())
+ gump_data[1] := "-";
+ return;
+ elseif (splitted.size() == 1)
+ gump_data[1] := signname;
+ return;
+ elseif (splitted.size() == 2)
+ gump_data[1] := splitted[1];
+ gump_data[11] := splitted[2];
+ return;
+ endif
+
+ for j := 1 to 5
+ if (!splitted[j])
+ splitted[j] := "";
+ endif
+ endfor
+
+ if( (len(splitted[1]) + len(splitted[2]) + len(splitted[3]) + 2) <= 12 )
+ gump_data[1] := splitted[1] + " " + splitted[2] + " " + splitted[3];
+ gump_data[11] := splitted[4] + " " + splitted[5];
+ elseif( len(splitted[1]) + len(splitted[2]) + 1 <= 12 )
+ gump_data[1] := splitted[1] + " " + splitted[2];
+ gump_data[11] := splitted[3] + " " + splitted[4] + " " + splitted[5];
+ else
+ gump_data[1] := splitted[1];
+ gump_data[11] := splitted[2] + " " + splitted[3] + " " + splitted[4] + " " + splitted[5];
+ endif
+endfunction
+
+
+
+
+///////////////////
+// if we can't figure out the owner's name any other way, this does it
+///////////////////
+
+function FindOwnerName( sign )
+ var owneraccount := GetObjProperty (sign, "account");
+ if (owneraccount)
+ var acct := FindAccount (owneraccount);
+ if (acct)
+ for i := 1 to 7
+ var char := acct.GetCharacter(i);
+ if (char)
+ SetObjProperty (sign, "lastownername", char.name);
+ return char.name;
+ endif
+ endfor
+ endif
+ endif
+
+ SetObjProperty (sign, "lastownername", "Unknown");
+ return "Unknown";
+endfunction
+
+
+
+
+///////////////////
+// People who are not friends of the house don't get the options, just some random info
+///////////////////
+
+function DisplayNonFriendSign (character, sign)
+
+ return;
+
+
+
+
+endfunction
+
+
+
+
diff --git a/pkg/systems/customHousing/signcontrol.src b/pkg/systems/customHousing/signcontrol.src
new file mode 100644
index 000000000..81e1495df
--- /dev/null
+++ b/pkg/systems/customHousing/signcontrol.src
@@ -0,0 +1,164 @@
+use uo;
+use os;
+use cfgfile;
+
+include "include/eventID";
+include "include/utility";
+//include "include/itemtypes";
+include ":customhousing:house";
+
+program SignListener (sign)
+ if (!GetObjProperty (sign, "house_serial"))
+ sign.controlscript := "";
+ return;
+ endif
+
+ var house := SystemFindObjectBySerial (GetObjProperty (sign, "house_serial"));
+ if (!house)
+ DestroyItem (sign);
+ return;
+ endif
+
+ var homeinfo := GetObjProperty (sign, "homeinfo");
+ if (!homeinfo)
+ BuildHouseLockdownArea (sign, house.objtype);
+ endif
+
+ homeinfo := GetObjProperty (sign, "homeinfo");
+ if (!homeinfo)
+ sign.controlscript := "";
+ return;
+ endif
+
+ RecordHouseSignOwner (sign);
+ RegisterForSpeechEvents (sign, 30);
+
+ var ev;
+ while (sign)
+ ev := wait_for_event (600);
+ if (ev)
+ if (ev.type == EVID_SPEECH)
+ if (ev.source.acctname)
+ handle_speech (ev, sign);
+ endif
+ endif
+ endif
+ endwhile
+endprogram
+
+
+
+
+///////////////////
+// used when the sign is first created to set up the area around the house where items can be locked down
+///////////////////
+
+function BuildHouseLockdownArea (sign, housetype)
+ var homeinfo := array {};
+ homeinfo[1] := 0;
+ case (housetype)
+ 69732: //
+ 69734: //
+ 69736: //
+ 69738: //The small houses
+ 69740: //
+ 69742: //
+ homeinfo[2] := sign.x - 6;
+ homeinfo[3] := sign.y - 8;
+ homeinfo[4] := sign.x + 2;
+ homeinfo[5] := sign.y + 1;
+ 69748: //large brick house
+ homeinfo[2] := sign.x - 11;
+ homeinfo[3] := sign.y - 15;
+ homeinfo[4] := sign.x + 4;
+ homeinfo[5] := sign.y + 1;
+ 69750: //Two story houses
+ 69752:
+ homeinfo[2] := sign.x - 9;
+ homeinfo[3] := sign.y - 15;
+ homeinfo[4] := sign.x + 6;
+ homeinfo[5] := sign.y + 1;
+ 69754: //tower
+ homeinfo[2] := sign.x - 14;
+ homeinfo[3] := sign.y - 15;
+ homeinfo[4] := sign.x + 9;
+ homeinfo[5] := sign.y + 1;
+ 69756: //keep
+ homeinfo[2] := sign.x - 16;
+ homeinfo[3] := sign.y - 23;
+ homeinfo[4] := sign.x + 9;
+ homeinfo[5] := sign.y + 2;
+ 69758: //castle
+ homeinfo[2] := sign.x - 20;
+ homeinfo[3] := sign.y - 32;
+ homeinfo[4] := sign.x + 12;
+ homeinfo[5] := sign.y + 1;
+ 69772: //large patio house
+ 69773: //ranch house
+ homeinfo[2] := sign.x - 8;
+ homeinfo[3] := sign.y - 15;
+ homeinfo[4] := sign.x + 8;
+ homeinfo[5] := sign.y + 1;
+ 69792: //small stone shop
+ 69794: //small marble shop
+ homeinfo[2] := sign.x - 7;
+ homeinfo[3] := sign.y - 8;
+ homeinfo[4] := sign.x + 1;
+ homeinfo[5] := sign.y + 1;
+ 69784: //small tower
+ homeinfo[2] := sign.x - 5;
+ homeinfo[3] := sign.y - 8;
+ homeinfo[4] := sign.x + 4;
+ homeinfo[5] := sign.y + 1;
+ 69788: //sandstone patio house
+ homeinfo[2] := sign.x - 9;
+ homeinfo[3] := sign.y - 10;
+ homeinfo[4] := sign.x + 4;
+ homeinfo[5] := sign.y + 1;
+ 69786: //2 story log cabin
+ homeinfo[2] := sign.x - 8;
+ homeinfo[3] := sign.y - 14;
+ homeinfo[4] := sign.x + 1;
+ homeinfo[5] := sign.y + 1;
+ 69790: //2 story villa
+ homeinfo[2] := sign.x - 7;
+ homeinfo[3] := sign.y - 12;
+ homeinfo[4] := sign.x + 5;
+ homeinfo[5] := sign.y + 1;
+ 69782: //marble patio house
+ homeinfo[2] := sign.x - 8;
+ homeinfo[3] := sign.y - 15;
+ homeinfo[4] := sign.x + 8;
+ homeinfo[5] := sign.y + 1;
+// 0x113ec: //foundation 7x7
+// homeinfo[2] := sign.x - 1;
+// homeinfo[3] := sign.y - 8;
+// homeinfo[4] := sign.x + 7;
+// homeinfo[5] := sign.y;
+// 0x1147b: //foundation 18x18
+// homeinfo[2] := sign.x - 1;
+// homeinfo[3] := sign.y - 19;
+// homeinfo[4] := sign.x + 18;
+// homeinfo[5] := sign.y;
+ default:
+ if (housetype >= 0x113ec and housetype <= 0x1147b)
+ var multiid := housetype - 0x10000;
+ var dims := GetMultiDimensions (multiid);
+ var width := 1+dims.xmax-dims.xmin;
+ var height := 1+dims.ymax-dims.ymin;
+ homeinfo[2] := sign.x - 1;
+ homeinfo[3] := sign.y - (height+1);
+ homeinfo[4] := sign.x + width;
+ homeinfo[5] := sign.y;
+ endif
+
+// //
+// homeinfo[2] := sign.x - ;
+// homeinfo[3] := sign.y - ;
+// homeinfo[4] := sign.x + ;
+// homeinfo[5] := sign.y + ;
+
+ endcase
+ homeinfo[6] := sign.realm;
+ SetObjProperty (sign, "homeinfo", homeinfo);
+endfunction
diff --git a/pkg/systems/customHousing/syshook/closecustomhouse.src b/pkg/systems/customHousing/syshook/closecustomhouse.src
new file mode 100644
index 000000000..787e31c72
--- /dev/null
+++ b/pkg/systems/customHousing/syshook/closecustomhouse.src
@@ -0,0 +1,64 @@
+use os;
+use uo;
+
+Const UOBJECT_BRASS_SIGN := 0x0bd2;
+Const UOBJECT_WOOD_SIGN := 0x0bd0;
+
+exported function CloseCustomHouse ( who, house)
+ if (who.concealed < 2)
+ who.concealed := 0;
+ endif
+ var components := GetObjProperty (house, "components");
+ var lockid := 0;
+ foreach compo in (components)
+ var sign := SystemFindObjectBySerial(compo);
+ if (sign.objtype == UOBJECT_BRASS_SIGN or sign.objtype == UOBJECT_WOOD_SIGN)
+ lockid := GetObjProperty (sign, "lockid");
+ if (lockid)
+ break;
+ endif
+ endif
+ endforeach
+ var teleporters := array{};
+ foreach item in (house.components)
+ if (item.isa (POLCLASS_DOOR))
+ item.locked := 1;
+ SetObjProperty (item, "lockid", lockid);
+ elseif (item.objtype >= 0x181d and item.objtype <= 0x1828)
+ teleporters.append(item);
+ endif
+ endforeach
+ foreach tele in teleporters
+ foreach nexttele in teleporters
+ if (_nexttele_iter <= _tele_iter)
+ continue;
+ endif
+ if (tele.objtype == nexttele.objtype)
+ SetObjProperty (tele, "DestX", nexttele.x);
+ SetObjProperty (tele, "DestY", nexttele.y);
+ SetObjProperty (tele, "DestZ", nexttele.z);
+ SetObjProperty (tele, "DestR", nexttele.realm);
+ break;
+ endif
+ endforeach
+ if (!GetObjProperty (tele, "DestX"))
+ foreach nexttele in teleporters
+ if (_nexttele_iter >= _tele_iter)
+ break;
+ endif
+ if (tele.objtype == nexttele.objtype)
+ SetObjProperty (tele, "DestX", nexttele.x);
+ SetObjProperty (tele, "DestY", nexttele.y);
+ SetObjProperty (tele, "DestZ", nexttele.z);
+ SetObjProperty (tele, "DestR", nexttele.realm);
+ break;
+ endif
+ endforeach
+ endif
+ endforeach
+endfunction
+
+program SyshookCloseCustomHouse ()
+ Syslog ("Installing CloseCustomHouse syshook...");
+ return 1;
+endprogram
\ No newline at end of file
diff --git a/pol.cfg.example b/pol.cfg.example
new file mode 100644
index 000000000..6c17eb5af
--- /dev/null
+++ b/pol.cfg.example
@@ -0,0 +1,518 @@
+#############################################################################
+## Basic Configuration
+#############################################################################
+
+#
+# UoDataFileRoot: where the UO client files are located.
+# Used by UOConvert.exe to find map, multi, tiledata, statics, etc. files.
+#
+# On Windows, the pol.cfg setting UoDataFileRoot will default to the directory of the Ultima Online
+# installation found in the Windows Registry. This setting MUST be set for servers that do not have
+# Ultima Online installed through the operating system, and MAY be set to use custom a client data
+# files directory.
+# On Linux, you MUST set this to the correct Ultima Online client files directory.
+UoDataFileRoot=
+
+#
+# Used to tell POL where to look for the realm data that was made by uoconvert.
+# Defaults to 'realm/' from where pol.exe is started.
+#
+#RealmDataPath=realm/
+
+#
+# Where are the data files stored
+# Defaults to 'data/'
+#
+#WorldDataPath=data/
+
+#
+# Linux only: path to store pidfile
+# Defaults to ./
+#
+#PidFilePath=./
+
+#
+# RetainCleartextPasswords: If you select this, the server will save plain passwords
+# in the accounts.txt file. If you set it to 0, all will be erased. You can get them back
+# by changing this back to 1 and successfully logging into the account (for each account)
+# Default 0
+#
+#RetainCleartextPasswords=0
+
+#############################################################################
+## Logon and Logoff
+#############################################################################
+
+#
+# ClientEncryptionVersion - string
+# Default none
+# Clarification: for ClientEncryptionVersion, the allowable values are 'major.minor.build', '2.0.0x',
+# 'ignition', 'uorice', and 'none'. Here, 'ignition', 'uorice', and 'none' all mean 'no encryption'.
+# Due to autocalculation 'major.minor.build' means setting a listener for client 7.0.4.1 '7.0.4' (no patch)
+#
+#ClientEncryptionVersion=none
+
+#
+# MinCmdlevelToLogin: Only characters with this command level or higher
+# log in. (0=player,5=admin)
+# Default 0
+#
+#MinCmdlevelToLogin=0
+
+#
+# InactivityWarningTimeout: Time in minutes until the user gets a "you are
+# about to be disconnected" message
+# Default 4
+#
+InactivityWarningTimeout=15
+
+#
+# InactivityDisconnectTimeout: Idle Time in minutes before the user is
+# disconnected.
+# Default 5
+#
+InactivityDisconnectTimeout=20
+
+#
+# MinCmdLvlToIgnoreInactivity
+# If the character is this command level or higher they won't get
+# timeout warnings or disconnected after InactivityDisconnectTimeout
+# has been reached.
+# Default is 1
+#
+#MinCmdLvlToIgnoreInactivity=1
+
+#
+# MaximumClients: Sets the total number of clients allowed to connect at
+# one time.
+# Default 300
+#
+#MaximumClients=300
+
+#
+# MaximumClientsBypassCmdLevel: Sets the character command level that bypasses the
+# MaximumClients limiter
+# Default 1
+#
+#MaximumClientsBypassCmdLevel=1
+
+#
+# LoginServerTimeout: maximum time in minutes allowed to connect with the login server
+# (until character is selected)
+# Default 10
+#
+#LoginServerTimeout=10
+
+#
+# When true, allows multiple characters from the same account to be
+# logged in at the same time
+# AllowMultiClientsPerAccount
+# default: is 0
+#
+#AllowMultiClientsPerAccount=0
+
+#############################################################################
+## System Profiling and Performance
+#############################################################################
+
+#
+# LogLevel:
+# Default 0
+#
+#LogLevel=0
+
+#
+# DebugLevel:
+# Default 0
+#
+#DebugLevel=0
+
+#
+# WatchRPM: display the RPM counter to console every minute
+# Default 0
+#
+#WatchRPM=0
+
+#
+# WatchSysLoad: display the Sysload counter to console every minute
+# Default 0
+#
+#WatchSysLoad=0
+
+#
+# LogSysLoad: log sysload to pol.log every minute
+# Default 0
+#
+LogSysLoad=1
+
+#
+# LogScriptCycles: Write profiling information on scripts to pol.log on exit
+# Default 0
+#
+LogScriptCycles=1
+
+#
+# RunawayScriptThreshold: a script executing this many instructions without
+# sleeping will be reported as a runaway script
+# Default 5000
+#
+RunawayScriptThreshold=10000
+
+#
+# ReportRunToCompletionScripts: Print "run to completion" scripts that are running
+# Default 1
+#
+#ReportRunToCompletionScripts=1
+
+#
+# ReportCriticalScripts: Print "critical" scripts that are running
+# Default 1
+#
+#ReportCriticalScripts=1
+
+#
+# MaxCallDepth: Maximum function call depth for scripts
+# Default 100
+#
+#MaxCallDepth=100
+
+#
+# ShowRealmInfo: Reports realms and their number of mobiles, offline chars,
+# top-level items and multis to the console
+# Default 0
+#
+#ShowRealmInfo=0
+
+#
+# ShowWarningGump: will display unexpected gump warning messages on the console if set to 1.
+# ShowWarningGump= (0/1) Default is 1
+#
+#ShowWarningGump=1
+
+#
+# ShowWarningItem: will display equip item and drop item warning messages on the console if set to 1.
+# ShowWarningItem= (0/1) Default is 1
+#
+#ShowWarningItem=1
+
+#
+# ReportMissingConfigs: Handles if Missing Config File - reports are printed
+# to the Debug.Log file.
+# Default 1
+#
+#ReportMissingConfigs=1
+
+#
+# TimestampEveryLine 1/0
+# If set every line in pol.log gets timestamp
+# Default is 0
+#
+TimestampEveryLine=1
+
+
+#
+# UseSingleThreadLogin
+# if set all prelogin clients are handled inside the listener thread and not inside an extra thread
+# this will reduce the amount of thread creates and destroys
+# Default is 0
+#
+UseSingleThreadLogin=1
+
+#
+# SingleThreadDecay
+# In former days or without this setting active each
+# realm has a dedicated thread with the only purpose
+# to iterate over the complete map to find items to
+# destroy. With this setting active it's only one
+# thread for all realms.
+# Default is 0
+#
+SingleThreadDecay=1
+
+#
+# ThreadDecayStatistics
+# (Only used with Single Thread Decay setting also set)
+# Prints statistics per run how many items are able
+# to decay currently and how many items got
+# destroyed to find the best implementation.
+#
+# This also prints to the console.
+# Default is 0
+#
+#ThreadDecayStatistics=0
+
+#
+# DisableNagle -
+# 0 - old style, no changes (Default)
+# 1 - disable Nagle's algorithm, might reduce connection latency
+#
+DisableNagle=1
+
+#############################################################################
+## Debugging
+#############################################################################
+
+#
+# DebugPort: TCP/IP port to listen for debugger connections
+# Default 0
+#
+DebugPort=5001
+
+#
+# DebugPassword: Password for debugging
+# If none is specified, no password is required.
+# Default none
+#
+#DebugPassword=
+
+#
+# DebugLocalOnly: Only allow access from localhost
+# Default 1
+#
+#DebugLocalOnly=1
+
+#
+# CacheInteractiveScripts: if 0, always load interactive scripts from disk
+# Useful for script development
+# Default 1
+#
+#CacheInteractiveScripts=1
+
+#
+# ThreadStacktracesWhenStuck: logs the stack traces of all threads to stdout and
+# stderr when there is no clock movement for more than
+# 30 seconds. Only useful for debugging the core.
+# Default 0
+#
+#ThreadStacktracesWhenStuck=0
+
+#
+# AssertionFailureAction
+# abort/continue/shutdown/shutdown-nosave
+# abort: (like old behavior) aborts immediately, without saving data.
+# continue: allows execution to continue.
+# shutdown: attempts graceful shutdown
+# shutdown-nosave: attempts graceful shutdown, without saving data.
+# Default abort
+#
+AssertionFailureAction=shutdown
+
+#
+# DumpStackOnAssertionFailure: will cause a stack backtrace to be generated when any assertion fails.
+# Default 0
+#
+DumpStackOnAssertionFailure=1
+
+#
+# EnableDebugLog: Enable the script debug log (formerly known as pol.lg2)
+# Default 0
+#
+EnableDebugLog=1
+
+#
+# MiniDumpType: type of crash dump created. values: small, variable (default) or large.
+# Case sensative.
+#
+#MiniDumpType=variable
+
+#
+# DisplayUnknownPackets: If a packet is unknown, it will be reported to the console.
+# Default 0
+#
+DisplayUnknownPackets=1
+
+#
+# Verbose: Reports all incoming packets.
+# Default 0
+#
+#Verbose=0
+
+#
+# ShowSpeechColors: If enabled, reports the speech colors clients are using when they talk.
+# Default 0
+#
+#ShowSpeechColors=0
+
+#
+# CProp profiler: helps detecting unused CProps.
+# polsys.em function LogCPropProfile() can be called to dump
+# the profiling information into cpprofile.log.
+# Default is 0
+#
+#ProfileCProps=0
+
+#############################################################################
+## Reporting System for Program Aborts
+#############################################################################
+#
+# ReportCrashsAutomatically: for Linux build only, enable reporting system
+# Default 0
+#
+#ReportCrashsAutomatically=0
+
+#
+# ReportAdminEmail: the email address which should be used to contact the shard admin
+# Default empty
+#
+#ReportAdminEmail=
+
+#
+# ReportServer: the host name of the bug tracking server
+# Default polserver.com
+#
+#ReportServer=polserver.com
+
+#
+# ReportURL: the URL which is called in case of a program abort
+# Default /pol/report_program_abort.php
+#
+#ReportURL=/pol/report_program_abort.php
+
+#############################################################################
+## Integrated Web Server
+#############################################################################
+
+#
+# WebServer: Run the internal web server
+# Default 0
+#
+WebServer=0
+
+#
+# WebServerPort: What TCP/IP port to listen for web requests
+# Default: 8080
+#
+#WebServerPort=8080
+
+#
+# WebServerLocalOnly: Only allow access from localhost
+# Default 1
+#
+WebServerLocalOnly=1
+
+#
+# WebServerDebug: Print trace information about http requests
+# Default 0
+#
+#WebServerDebug=0
+
+#
+# WebServerPassword: username:password required for access to the web server.
+# username and password must be delimited using a colon ':'.
+# If not specified, no password is required.
+# WebServerPassword=username:password
+# Default empty
+#
+#WebServerPassword=
+
+#############################################################################
+## System Load and Save
+#############################################################################
+
+#
+# IgnoreLoadErrors: force load to continue even if object creations fail
+# or containers cannot be found.
+# Default 0
+#
+#IgnoreLoadErrors=0
+
+#
+# InhibitSaves: Don't ever save world state
+# Default 0
+#
+#InhibitSaves=0
+
+#
+# AccountDataSave:
+# -1 : old behaviour, saves accounts.txt immediately after an account change
+# 0 : saves only during worldsave (if needed)
+# >0 : saves every X seconds and during worldsave (if needed)
+# Default -1
+#
+#AccountDataSave=-1
+
+
+#############################################################################
+## Features
+#############################################################################
+
+#
+# RequireSpellbooks: Require spellbooks for casting (in hand or in pack)
+# Default 1
+#
+#RequireSpellbooks=1
+
+#
+# EnableSecureTrading: if you enable this, see changes.txt regarding an entry
+# that MUST be added to config/itemdesc.cfg
+# Default 0
+#
+EnableSecureTrading=1
+
+#
+# ExpLosChecksMap - prevents stuff like arrows from going through the 'black'
+# areas in dungeons.
+# Default 1
+#
+#ExpLosChecksMap=1
+
+# MaxTileID: accepted values are
+# For clients older than Stygian Abyss Expansion <0x3FFF>
+# For Stygian Abyss Clients <0x7FFF>
+# For High Seas Adventures clients <0xFFFF>
+# Default <0x3FFF>
+#
+MaxTileID=0xFFFF
+
+# MaxObjtype
+# Can be any value between 0x20000 and 0xFFFFFFFF
+# Default is 0x20000
+#
+MaxObjtype=0xFFFFFFFF
+
+# EnforceMountObjtype: ensures that only items with the mount objtype defined
+# in extobj.cfg (default 0x1F021) can be equipped in the
+# character as a mount (Default false)
+#
+#EnforceMountObjtype=0
+
+#
+# CharacterSlots: Number of character per account.
+# Default is 5 (1-7 allowed)
+#
+#CharacterSlots=5
+
+#
+# DiscardOldEvents 1/0
+# if set instead of discarding new event if queue is full it discards oldest event and adds the new event
+# Default is 0
+#
+#DiscardOldEvents=0
+
+#
+# AllowedEnvironmentVariablesAccess or *
+# Enable/Disable os::GetEnvironmentVariable module function
+# When *, all variables are allowed
+# When a list, scripts are only allowed to access these specified variables (case-insensitive).
+# Default is empty, allowing no variable access.
+#
+#AllowedEnvironmentVariablesAccess=
+
+#############################################################################
+## Experimental Options - Modify at your own risk
+#############################################################################
+
+
+
+#############################################################################
+## Treading Settings - Do not modify unless necessary.
+#############################################################################
+
+#
+# SelectTimeout: I/O sleep time
+# Set to 0 for a dedicated server.
+# Set to 10 for a non-dedicated server.
+# Default 10
+#
+#SelectTimeout=10
+
diff --git a/scripts/include/client.inc b/scripts/include/client.inc
index 4a13d412a..d53c4a184 100644
--- a/scripts/include/client.inc
+++ b/scripts/include/client.inc
@@ -717,12 +717,15 @@ const SFX_LUTE_FAIL := SFX_4E;
const SFX_DRUM_FAIL := SFX_3A;
const SFX_TAMB_FAIL := SFX_54;
-
// * doors *
const SFX_OPEN_WOODEN_DOOR := SFX_EB;
const SFX_CLOSE_WOODEN_DOOR := SFX_F2;
+const SFX_OPEN_STONE_DOOR := SFX_EC;
+const SFX_CLOSE_STONE_DOOR := SFX_F3;
const SFX_OPEN_METAL_DOOR := SFX_ED;
const SFX_CLOSE_METAL_DOOR := SFX_F4;
+const SFX_OPEN_SLIDING_DOOR := 0x53a;
+const SFX_CLOSE_SLIDING_DOOR := 0x538;
////
diff --git a/scripts/misc/customhousecommit.src b/scripts/misc/customhousecommit.src
new file mode 100644
index 000000000..06446547d
--- /dev/null
+++ b/scripts/misc/customhousecommit.src
@@ -0,0 +1,7 @@
+// See documentation at https://docs.polserver.com/pol100/scripttypes.php#CustomHouseCommitScript on suggested actions
+program CustomHouseCommitScript(who, house)
+ if (who.concealed)
+ who.concealed := 0;
+ endif
+ house.acceptcommit(who,1);
+endprogram