Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
d42608c
Guild Creation
DragonSlayer62 Aug 18, 2025
a0d14d7
Update jse_fileassociations.scp
DragonSlayer62 Aug 18, 2025
f562b48
adjustments
DragonSlayer62 Aug 18, 2025
6b975ee
Update guildmenu.js
DragonSlayer62 Aug 18, 2025
0a82eab
Update guildmenu.js
DragonSlayer62 Aug 19, 2025
3157576
Added Code
DragonSlayer62 Aug 19, 2025
3f81928
guild invites
DragonSlayer62 Aug 20, 2025
64132a7
more support for guilds
DragonSlayer62 Aug 21, 2025
dd002a4
updates
DragonSlayer62 Aug 22, 2025
f3fa940
Merge branch 'develop' into Guild-System
DragonSlayer62 Sep 7, 2025
09fd79d
Merge branch 'develop' into Guild-System
DragonSlayer62 Sep 21, 2025
9bb3ad9
Merge branch 'develop' into Guild-System
DragonSlayer62 Oct 22, 2025
ca55834
Merge branch 'develop' into Guild-System
DragonSlayer62 Oct 25, 2025
cafb9c9
Merge branch 'develop' into Guild-System
DragonSlayer62 Oct 27, 2025
69f21fd
Merge branch 'develop' into Guild-System
DragonSlayer62 Nov 2, 2025
e6a89c0
Merge branch 'develop' into Guild-System
DragonSlayer62 Nov 11, 2025
8e41c8d
Merge branch 'develop' into Guild-System
DragonSlayer62 Nov 12, 2025
eec5c95
Merge branch 'develop' into Guild-System
DragonSlayer62 Nov 17, 2025
48c8950
cleanup
DragonSlayer62 Dec 6, 2025
3289226
Cleanup
DragonSlayer62 Dec 7, 2025
be68c1f
Update SEFunctions.cpp
DragonSlayer62 Dec 7, 2025
61ec1e9
update
DragonSlayer62 Dec 7, 2025
8567e47
Document Update
DragonSlayer62 Dec 7, 2025
49f12da
Merge branch 'develop' into Guild-System
DragonSlayer62 Dec 17, 2025
03031df
cleanup
DragonSlayer62 Dec 20, 2025
0ea6a82
Merge branch 'develop' into Guild-System
DragonSlayer62 Jan 20, 2026
036e51e
Merge branch 'develop' into Guild-System
DragonSlayer62 Mar 25, 2026
ee0bb1c
Update jse_fileassociations.scp
DragonSlayer62 Mar 25, 2026
433ac32
Update global.js
DragonSlayer62 Mar 25, 2026
cba0e17
Guild Update
DragonSlayer62 Jun 30, 2026
07f2f21
remove guild menu
DragonSlayer62 Jun 30, 2026
dce5028
update
DragonSlayer62 Jun 30, 2026
32a8322
guild update
DragonSlayer62 Jun 30, 2026
905783f
update
DragonSlayer62 Jul 1, 2026
608cfbe
fixed
DragonSlayer62 Jul 1, 2026
ca9c9dd
small fix
DragonSlayer62 Jul 1, 2026
530fc27
update
DragonSlayer62 Jul 1, 2026
fd9c7ba
update
DragonSlayer62 Jul 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion data/js/coreDefinitions.json
Original file line number Diff line number Diff line change
Expand Up @@ -3600,6 +3600,12 @@
"cppType": "JSPROP_ENUMANDPERM",
"type": "string"
},
{
"name": "guildToggle",
"cppName": "CCP_GUILDTOGGLE",
"cppType": "JSPROP_ENUMANDPERM",
"type": "boolean"
},
{
"name": "hairColor",
"cppName": "CCP_HAIRCOLOUR",
Expand Down Expand Up @@ -9403,4 +9409,4 @@
"type": "boolean"
}
]
}
}
1 change: 1 addition & 0 deletions data/js/definitions.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ declare global {
guarding: BaseOrNull;
guild: GuildOrNull;
guildTitle: string;
guildToggle: boolean;
hairColor: number;
hairColour: number;
hairStyle: number;
Expand Down
263 changes: 229 additions & 34 deletions data/js/item/guildstone.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
/// <reference path="../definitions.d.ts" />
// @ts-check
// Guildstone Deed/Stone

const pendingGuildstoneDeedTag = "pendingGuildstoneDeed";
const defaultGuildCharter = "UOX3 Guildstone";
const defaultGuildWebpage = "http://www.uox3.org/";

/** @type { ( user: Character, iUsing: Item ) => boolean } */
function onUseChecked( pUser, iUsed )
{
// Check if object is in player's backpack
var pSocket = pUser.socket;
if ( pUser.visible == 1 || pUser.visible == 2 )
{
Expand All @@ -21,61 +25,252 @@ function onUseChecked( pUser, iUsed )
return false;
}

// Check if player is actually in a house
var iMulti = pUser.multi;
if( !ValidateObject( iMulti ) || !iMulti.IsInMulti( pUser ))
if( iUsed.id == 0x14F0 )
{
// Player vendors can only be placed in houses!
pSocket.SysMessage( GetDictionaryEntry( 2723, pSocket.language )); // Guildstones can only be placed in houses!
return false;
}
var deedGuildMenuSystem = parseInt( GetServerSetting( "GuildMenuSystem" ), 10 );
if( isNaN( deedGuildMenuSystem ))
deedGuildMenuSystem = GetServerSetting( "ClassicOSIGuildMenu" ) ? 1 : 0;

// Make sure player has access to actually placing a guildstone in the house
if( !iMulti.IsOwner( pUser ))
{
// Only the house owner can guildstones in a house!
pSocket.SysMessage( GetDictionaryEntry( 2724, pSocket.language )); // Only the house owner can place a guildstone in a house!
return false;
}
if( deedGuildMenuSystem == 2 )
{
pSocket.SysMessage( "Use the guild button on your paperdoll to create or access a guild." );
return false;
}

// Check that the player is not already in a guild
if( iUsed.id == 0x14F0 && pUser.guild != null )
{
pSocket.SysMessage( GetDictionaryEntry( 173, pSocket.language )); // You are already in a guild!
if( !ValidateGuildstonePlacement( pUser, iUsed, true ))
return false;

if( pUser.SetTag )
pUser.SetTag( pendingGuildstoneDeedTag, iUsed.serial );

TriggerEvent( 8020, "GuildCreation", pUser );
return false;
}

// Check that the house doesn't already have a guildstone in it
var tempItem;
for( tempItem = iMulti.FirstItem(); !iMulti.FinishedItems(); tempItem = iMulti.NextItem() )
if( iUsed.id == 0x1869 )
{
if( !ValidateObject( tempItem ))
continue;
if( !pUser.guild )
{
pSocket.SysMessage( "You don't appear to be in a guild" );
return false;
}

if( tempItem.type == 202 && tempItem.id == 0x0ED5 )
var deedGuild = FindGuildById( iUsed.more );
if( !deedGuild )
{
pSocket.SysMessage( GetDictionaryEntry( 2725, pSocket.language )); // You cannot place any additional guildstones in this house!
pSocket.SysMessage( GetDictionaryEntry( 174, pSocket.language )); // Critical error adding guildstone, please contact a GM!
return false;
}

PlaceGuildStoneFromDeed( pUser, iUsed, deedGuild );
return false;
}
}

// Make sure player is not trying to place the guildstone too close to a door!
// Check for nearby doors
var foundDoor = AreaItemFunction( "checkForNearbyDoors", pUser, 3, pSocket );
if( foundDoor )
if( iUsed.id == 0x0ED5 )
{
var stoneGuild = FindGuildById( iUsed.more );
if( !stoneGuild || !pUser.guild || pUser.guild.id != stoneGuild.id )
{
pSocket.SysMessage( GetDictionaryEntry( 2726, pSocket.language )); // You cannot place a guildstone adjacent to a door!
pSocket.SysMessage( GetDictionaryEntry( 1984, pSocket.language )); // You are not a member of this guild!
return false;
}

// TODO - Move actual creation of guild and guildstone to this script as well.
var guildMenuSystem = parseInt( GetServerSetting( "GuildMenuSystem" ), 10 );
if( isNaN( guildMenuSystem ))
guildMenuSystem = GetServerSetting( "ClassicOSIGuildMenu" ) ? 1 : 0;

if( guildMenuSystem == 1 )
TriggerEvent( 8020, "ClassicGuildMenu", pUser );
else if( guildMenuSystem == 2 )
pSocket.SysMessage( "Use the guild button on your paperdoll to access the guild menu." );
else
TriggerEvent( 8020, "GuildMenu", pUser );
return false;
}
}

return false;
}

function PlacePendingGuildstone( pUser, guild )
{
if( !ValidateObject( pUser ) || !guild || !pUser.GetTag )
return false;

var deedSerial = parseInt( pUser.GetTag( pendingGuildstoneDeedTag ), 10 );
pUser.SetTag( pendingGuildstoneDeedTag, null );
if( isNaN( deedSerial ) || deedSerial <= 0 )
return false;

var deed = CalcItemFromSer( deedSerial );
if( !ValidateObject( deed ) || !deed.isItem )
return false;

return PlaceGuildStoneFromDeed( pUser, deed, guild );
}

// All good. Handle guild creation/guildstone menu in code for now
function CanPlacePendingGuildstone( pUser )
{
if( !ValidateObject( pUser ) || !pUser.GetTag )
return true;

var deedSerial = parseInt( pUser.GetTag( pendingGuildstoneDeedTag ), 10 );
if( isNaN( deedSerial ) || deedSerial <= 0 )
return true;

var deed = CalcItemFromSer( deedSerial );
if( !ValidateObject( deed ) || !deed.isItem )
{
if( pUser.SetTag )
pUser.SetTag( pendingGuildstoneDeedTag, null );
return false;
}

return false;
return ValidateGuildstonePlacement( pUser, deed, true );
}

function ValidateGuildstonePlacement( pUser, iUsed, requireNoGuild )
{
var pSocket = pUser.socket;
if( pSocket == null || !ValidateObject( iUsed ) || !iUsed.isItem )
return false;

var itemOwner = GetPackOwner( iUsed, 0 );
if( itemOwner == null || itemOwner.serial != pUser.serial )
{
pSocket.SysMessage( GetDictionaryEntry( 1763, pSocket.language )); // That item must be in your backpack before it can be used.
return false;
}

var iMulti = pUser.multi;
if( !ValidateObject( iMulti ) || !iMulti.IsInMulti( pUser ))
{
pSocket.SysMessage( GetDictionaryEntry( 2723, pSocket.language )); // Guildstones can only be placed in houses!
return false;
}

if( !iMulti.IsOwner( pUser ))
{
pSocket.SysMessage( GetDictionaryEntry( 2724, pSocket.language )); // Only the house owner can place a guildstone in a house!
return false;
}

if( requireNoGuild && pUser.guild != null )
{
pSocket.SysMessage( GetDictionaryEntry( 173, pSocket.language )); // You are already in a guild!
return false;
}

var tempItem;
for( tempItem = iMulti.FirstItem(); !iMulti.FinishedItems(); tempItem = iMulti.NextItem() )
{
if( !ValidateObject( tempItem ))
continue;

if( tempItem.type == 202 && tempItem.id == 0x0ED5 )
{
pSocket.SysMessage( GetDictionaryEntry( 2725, pSocket.language )); // You cannot place any additional guildstones in this house!
return false;
}
}

var foundDoor = AreaItemFunction( "checkForNearbyDoors", pUser, 3, pSocket );
if( foundDoor )
{
pSocket.SysMessage( GetDictionaryEntry( 2726, pSocket.language )); // You cannot place a guildstone adjacent to a door!
return false;
}

return true;
}

function PlaceGuildStoneFromDeed( pUser, deed, guild )
{
if( !ValidateGuildstonePlacement( pUser, deed, false ))
return false;

var pSocket = pUser.socket;
if( !guild )
{
pSocket.SysMessage( GetDictionaryEntry( 174, pSocket.language )); // Critical error adding guildstone, please contact a GM!
return false;
}

var stoneName = guild.name ? ( "A guildstone for " + guild.name ) : "Guildstone for an unnamed guild";
var stone = CreateBlankItem( pSocket, pUser, 1, stoneName, 0x0ED5, 0, "ITEM", false );
if( !ValidateObject( stone ))
{
pSocket.SysMessage( GetDictionaryEntry( 176, pSocket.language )); // Critical error, unable to spawn guildstone, please contact a GM!
return false;
}

stone.SetLocation( pUser );
stone.type = 202;
stone.more = guild.id;
stone.wipable = false;
stone.decayable = false;
guild.charter = defaultGuildCharter;
guild.webPage = defaultGuildWebpage;
guild.stone = stone;
deed.Delete();
return true;
}

function PackGuildstone( pUser, guild )
{
if( !ValidateObject( pUser ) || !guild || !pUser.socket )
return false;

var pSocket = pUser.socket;
if( !pUser.guild || pUser.guild.id != guild.id )
{
pSocket.SysMessage( GetDictionaryEntry( 1984, pSocket.language )); // You are not a member of this guild!
return false;
}

if( !guild.master || guild.master.serial != pUser.serial )
{
pSocket.SysMessage( "Only the guild master can move the guildstone." );
return false;
}

var stone = guild.stone;
if( !ValidateObject( stone ) || !stone.isItem )
{
pSocket.SysMessage( "This guild does not have a placed guildstone." );
return false;
}

var deed = CreateBlankItem( pSocket, pUser, 1, "guildstone transporter", 0x1869, 0, "ITEM", true );
if( !ValidateObject( deed ) || !deed.isItem )
{
pSocket.SysMessage( "Unable to create a guildstone transporter deed." );
return false;
}

deed.type = 202;
deed.more = guild.id;
deed.decayable = false;
guild.stone = null;
stone.Delete();
pSocket.SysMessage( "The guildstone has been packed into a transporter deed." );
return true;
}

function FindGuildById( guildId )
{
var allGuilds = GetAllGuilds();
if( !allGuilds )
return null;

for( var i = 0; i < allGuilds.length; i++ )
{
if( allGuilds[i] && allGuilds[i].id == guildId )
return allGuilds[i];
}

return null;
}

function checkForNearbyDoors( pUser, itemToCheck, pSocket )
Expand Down
1 change: 1 addition & 0 deletions data/js/jse_fileassociations.scp
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,7 @@
8000=player/death/return_stolen_items.js
8001=player/young_player.js
8002=player/death/resurrectpenalty.js
8020=player/guildmenu.js

// House Scripts [15000-15500]
15000=server/house/house.js
Expand Down
Loading