From f90a17ea59022c369bd580c0536486f513665266 Mon Sep 17 00:00:00 2001
From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com>
Date: Sun, 8 Feb 2026 16:45:55 -0600
Subject: [PATCH 01/12] House Teleporter Item
---
data/dfndata/items/misc/houseteleporters.dfn | 23 +
data/js/item/houseteleporter.js | 732 +++++++++++++++++++
data/js/jse_fileassociations.scp | 1 +
3 files changed, 756 insertions(+)
create mode 100644 data/dfndata/items/misc/houseteleporters.dfn
create mode 100644 data/js/item/houseteleporter.js
diff --git a/data/dfndata/items/misc/houseteleporters.dfn b/data/dfndata/items/misc/houseteleporters.dfn
new file mode 100644
index 000000000..c7f84f62d
--- /dev/null
+++ b/data/dfndata/items/misc/houseteleporters.dfn
@@ -0,0 +1,23 @@
+[houseteleporter]
+{
+get=base_item
+name=a house teleporter
+id=0x40BB
+weight=100
+decay=1
+script=5080
+origin=hs
+movable=1
+}
+
+[chargedhouseteleporter]
+{
+get=base_item
+name=a house teleporter
+id=0x574A
+weight=100
+decay=1
+script=5080
+origin=hs
+movable=1
+}
\ No newline at end of file
diff --git a/data/js/item/houseteleporter.js b/data/js/item/houseteleporter.js
new file mode 100644
index 000000000..f1a8f4c1a
--- /dev/null
+++ b/data/js/item/houseteleporter.js
@@ -0,0 +1,732 @@
+///
+// @ts-check
+
+const coOwnHousesOnSameAccount = GetServerSetting("CoOwnHousesOnSameAccount");
+
+function IsTeleporterItem( item )
+{
+ return ( ValidateObject( item ) && item.isItem && (item.id == 0x40BB || item.id == 0x574A));
+}
+
+function IsScrollItem( item )
+{
+ return( ValidateObject(item) && item.isItem && item.id == 0x1F60 );
+}
+
+function IsInPlayersPack( pUser, item )
+{
+ if( !ValidateObject( pUser ) || !ValidateObject( pUser.pack ) || !IsTeleporterItem( item ) && !IsScrollItem( item ))
+ return false;
+
+ var root = FindRootContainer( item, 0 );
+ return( ValidateObject( root ) && root.isItem && root.serial == pUser.pack.serial );
+}
+
+function ReadIntTag( obj, tagName, defVal )
+{
+ var value = parseInt(obj.GetTag(tagName), 10);
+ if( !isFinite( value ))
+ value = defVal;
+ return value;
+}
+
+function GetSecurityMode( teleItem )
+{
+ var m = ReadIntTag( teleItem, "HT_Security", 0 );
+ if( m != 0 && m != 1 && m != 2 )
+ m = 0;
+ return m;
+}
+
+function SecurityName( mode )
+{
+ if( mode == 1 )
+ return "Friends";
+ if( mode == 2 )
+ return "Anyone";
+ return "Owner/Co-Owners";
+}
+
+function CanManageTeleporter( pChar, teleItem )
+{
+ // Who can change security setting?
+ // (GM OR owner OR co-owner OR same-account-as-owner if enabled)
+ if( !ValidateObject( pChar ) || !ValidateObject( teleItem ))
+ return false;
+
+ if( pChar.isGM )
+ return true;
+
+ var m = teleItem.multi;
+ if( !ValidateObject( m ))
+ return false;
+
+ if( m.IsOwner( pChar ))
+ return true;
+
+ if( m.IsOnOwnerList( pChar ))
+ return true;
+
+ if( coOwnHousesOnSameAccount && ValidateObject( m.owner ))
+ {
+ if( m.owner.accountNum == pChar.accountNum )
+ return true;
+ }
+
+ return false;
+}
+
+function CanUseHouseTeleporter( pChar, teleItem )
+{
+ // Enforces configured security
+ if( !ValidateObject( pChar ) || !ValidateObject( teleItem ))
+ return false;
+
+ if( pChar.isGM )
+ return true;
+
+ var m = teleItem.multi;
+ if( !ValidateObject( m ))
+ return false;
+
+ var mode = GetSecurityMode( teleItem );
+
+ // Owner/coowner always allowed in all modes
+ if( m.IsOwner( pChar ))
+ return true;
+ if( m.IsOnOwnerList( pChar ))
+ return true;
+
+ if( coOwnHousesOnSameAccount && ValidateObject(m.owner ))
+ {
+ if( m.owner.accountNum == pChar.accountNum )
+ return true;
+ }
+
+ // Friends mode
+ if( mode == 1 )
+ {
+ if(m.IsOnFriendList( pChar ))
+ return true;
+ return false;
+ }
+
+ // Anyone mode
+ if( mode == 2 )
+ {
+ return true;
+ }
+
+ // Owner/Co-Owners only
+ return false;
+}
+
+function onContextMenuRequest( socket, targObj )
+{
+ var pUser = socket.currentChar;
+ if( !ValidateObject( pUser ))
+ return true;
+
+ if( !IsTeleporterItem( targObj ))
+ return true;
+
+ var inPack = IsInPlayersPack( pUser, targObj );
+
+ // Show "Set Security" only when it's a house-placed (locked down) teleporter
+ var canShowSecurity = false;
+ if( targObj.movable == 3 && ValidateObject( targObj.multi ) && CanManageTeleporter( pUser, targObj ))
+ canShowSecurity = true;
+
+ // Show "Rename" only when locked down, in house, manageable, AND linked
+ var canShowRename = false;
+ if( targObj.movable == 3 && ValidateObject( targObj.multi ) && CanManageTeleporter( pUser, targObj ))
+ {
+ var linkSerTmp = ReadIntTag( targObj, "HT_LinkSer", 0 );
+ if( linkSerTmp > 0 )
+ {
+ var otherTmp = CalcItemFromSer( linkSerTmp );
+ if( IsTeleporterItem( otherTmp ) && otherTmp.movable == 3 )
+ canShowRename = true;
+ }
+ }
+
+ var numEntries = 1; // Status
+ if( inPack )
+ {
+ numEntries++;
+ }
+
+ if( targObj.id == 0x574A )
+ {
+ numEntries++;
+ }
+
+ if( canShowSecurity )
+ numEntries++;
+
+ if( canShowRename )
+ numEntries++;
+
+ var offset = 12;
+ var toSend = new Packet();
+ var packetLen = 12 + ( numEntries * 8 );
+
+ toSend.ReserveSize( packetLen );
+ toSend.WriteByte( 0, 0xBF );
+ toSend.WriteShort( 1, packetLen );
+ toSend.WriteShort( 3, 0x14 ); // subCmd
+ toSend.WriteShort( 5, 0x0001 ); // 2D client
+ toSend.WriteLong( 7, targObj.serial );
+ toSend.WriteByte( 11, numEntries );
+
+ // Entry: Status
+ toSend.WriteShort( offset, 0x0101 );
+ toSend.WriteShort( offset += 2, 2140 );
+ toSend.WriteShort( offset += 2, 0x0020 );
+ toSend.WriteShort( offset += 2, 0x03E0 );
+ offset += 2;
+
+ // Entry: Link (only if in backpack)
+ if( inPack )
+ {
+ toSend.WriteShort( offset, 0x0102 );
+ toSend.WriteShort( offset += 2, 5119 );
+ toSend.WriteShort( offset += 2, 0x0020 );
+ toSend.WriteShort( offset += 2, 0x03E0 );
+ offset += 2;
+ }
+
+ // Entry: Recharge (pink only)
+ if( targObj.id == 0x574A )
+ {
+ toSend.WriteShort( offset, 0x0103 );
+ toSend.WriteShort( offset += 2, 5042 );
+ toSend.WriteShort( offset += 2, 0x0020 );
+ toSend.WriteShort( offset += 2, 0x03E0 );
+ offset += 2;
+ }
+
+ // Set Security
+ if( canShowSecurity )
+ {
+ toSend.WriteShort( offset, 0x0104 );
+ toSend.WriteShort( offset += 2, 6203 );
+ toSend.WriteShort( offset += 2, 0x0020 );
+ toSend.WriteShort( offset += 2, 0x03E0 );
+ offset += 2;
+ }
+
+ // Rename (linked + placed only)
+ if( canShowRename )
+ {
+ toSend.WriteShort( offset, 0x0105 );
+ toSend.WriteShort( offset += 2, 404 ); // cliloc for name
+ toSend.WriteShort( offset += 2, 0x0020 );
+ toSend.WriteShort( offset += 2, 0x03E0 );
+ offset += 2;
+ }
+
+ socket.Send( toSend );
+ toSend.Free();
+
+ return false;
+}
+
+function onContextMenuSelect( socket, targObj, popupEntry )
+{
+ var pUser = socket.currentChar;
+ if( !ValidateObject( pUser ))
+ return true;
+
+ if( !IsTeleporterItem( targObj ))
+ return true;
+
+ if( popupEntry == 0x0101 )
+ {
+ var linkSer = ReadIntTag( targObj, "HT_LinkSer", 0 );
+
+ var linked = false;
+ if( linkSer > 0 )
+ {
+ var other = CalcItemFromSer( linkSer );
+ if( IsTeleporterItem( other ))
+ linked = true;
+ }
+
+ if( targObj.id == 0x574A )
+ {
+ var charge = ReadIntTag(targObj, "HT_Charges", 0);
+ if( charge < 0 )
+ charge = 0;
+
+ if( charge > 1000 )
+ charge = 1000;
+
+ socket.SysMessage( "Teleporter: " + ( linked ? "Linked" : "Unlinked" ) + " | Charges: " + charge + "/" + 1000 );
+ }
+ else
+ {
+ socket.SysMessage( "Teleporter: " + ( linked ? "Linked" : "Unlinked" ));
+ }
+ return false;
+ }
+
+ if( popupEntry == 0x0102 )
+ {
+ if( !IsInPlayersPack( pUser, targObj ))
+ {
+ socket.SysMessage( "This must be in your backpack to link it." );
+ return false;
+ }
+
+ pUser.SetTempTag( "HT_LinkSrcSer", targObj.serial );
+ socket.CustomTarget( 0, "Target the other teleporter in your backpack to link." );
+ targObj.Refresh();
+ return false;
+ }
+
+ if( popupEntry == 0x0103 )
+ {
+ if( targObj.id != 0x574A )
+ return false;
+
+ var cur = ReadIntTag( targObj, "HT_Charges", 0 );
+ if( cur < 0 )
+ cur = 0;
+
+ if( cur >= 1000 )
+ {
+ socket.SysMessage( "This teleporter is fully charged." );
+ return false;
+ }
+
+ pUser.SetTempTag( "HT_RechargeSer", targObj.serial );
+ socket.CustomTarget( 1, "Target gate travel scrolls in your backpack to recharge." );
+ targObj.Refresh();
+ return false;
+ }
+
+
+ if( popupEntry == 0x0104 )
+ {
+ // Must be allowed to manage
+ if( !( targObj.movable == 3 && ValidateObject( targObj.multi ) && CanManageTeleporter( pUser, targObj )))
+ {
+ socket.SysMessage( "You cannot change this teleporter's security." );
+ return false;
+ }
+
+ var curMode = GetSecurityMode( targObj );
+ var nextMode = curMode + 1;
+ if( nextMode > 2 )
+ nextMode = 0;
+
+ targObj.SetTag( "HT_Security", nextMode );
+ socket.SysMessage( "Teleporter security set to: " + SecurityName( nextMode ));
+ targObj.Refresh();
+ return false;
+ }
+
+ if( popupEntry == 0x0105 )
+ {
+ // Must be placed + manageable
+ if (!(targObj.movable == 3 && ValidateObject(targObj.multi) && CanManageTeleporter(pUser, targObj)))
+ {
+ socket.SysMessage("You cannot rename this teleporter.");
+ return false;
+ }
+
+ // Must be linked
+ var linkSer = ReadIntTag(targObj, "HT_LinkSer", 0);
+ if (linkSer <= 0)
+ {
+ socket.SysMessage("This teleporter must be linked before it can be renamed.");
+ return false;
+ }
+
+ var other = CalcItemFromSer(linkSer);
+ if (!IsTeleporterItem(other))
+ {
+ socket.SysMessage("This teleporter must be linked before it can be renamed.");
+ return false;
+ }
+
+ // Store the serial so onSpeechInput knows what to rename
+ pUser.SetTempTag( "HT_RenameSer", targObj.serial );
+
+ // Prompt for name
+ pUser.SpeechInput( 1, targObj );
+ return false;
+ }
+
+ return false;
+}
+
+function onUseChecked( pUser, iUsed )
+{
+ var pSocket = pUser.socket;
+ if( !pSocket )
+ return false;
+
+ if( !IsTeleporterItem( iUsed ))
+ return false;
+
+ if( !IsInPlayersPack(pUser, iUsed) )
+ {
+ pSocket.SysMessage( "To link, both teleporters must be in your backpack." );
+ return true;
+ }
+
+ pUser.SetTempTag( "HT_LinkSrcSer", iUsed.serial );
+ pSocket.CustomTarget( 0, "Target the other teleporter in your backpack to link." );
+ return true;
+}
+
+function onCallback0( socket, target )
+{
+ var pUser = socket.currentChar;
+ if( !ValidateObject( pUser ))
+ return;
+
+ if( socket.GetWord( 1 ))
+ return;
+
+ var srcSer = parseInt( pUser.GetTempTag( "HT_LinkSrcSer" ), 10 );
+ if( !isFinite(srcSer) || srcSer <= 0 ) return;
+
+ var telporterA = CalcItemFromSer( srcSer );
+ var telporterB = target;
+
+ if( !IsTeleporterItem( telporterA ))
+ {
+ socket.SysMessage( "Source teleporter not found." );
+ return;
+ }
+ if( !IsTeleporterItem( telporterB ))
+ {
+ socket.SysMessage( "That is not a house teleporter." );
+ return;
+ }
+ if( telporterA.serial == telporterB.serial )
+ {
+ socket.SysMessage( "You must target the other teleporter." );
+ return;
+ }
+ if( telporterA.id != telporterB.id )
+ {
+ socket.SysMessage( "These teleporters are different types and cannot be linked." );
+ return;
+ }
+
+ if( !IsInPlayersPack( pUser, telporterA ) || !IsInPlayersPack( pUser, telporterB ))
+ {
+ socket.SysMessage( "Both teleporters must be in your backpack to link." );
+ return;
+ }
+
+ UnlinkOther( telporterA, telporterB.serial );
+ UnlinkOther( telporterB, telporterA.serial );
+
+ telporterA.SetTag( "HT_LinkSer", telporterB.serial );
+ telporterB.SetTag( "HT_LinkSer", telporterA.serial );
+
+ socket.SysMessage( "Teleporters linked." );
+}
+
+function onCallback1( socket, target )
+{
+ var pUser = socket.currentChar;
+ if( !ValidateObject( pUser ))
+ return;
+
+ if( socket.GetWord( 1 ))
+ return;
+
+ var teleporterSerial = parseInt( pUser.GetTempTag( "HT_RechargeSer" ), 10 );
+ if( !isFinite( teleporterSerial ) || teleporterSerial <= 0 )
+ return;
+
+ var teleporter = CalcItemFromSer( teleporterSerial );
+ if( !ValidateObject( teleporter ) || !teleporter.isItem || teleporter.id != 0x574A )
+ return;
+
+ var scroll = target;
+ if( !IsScrollItem( scroll ))
+ {
+ socket.SysMessage("Target gate travel scrolls to recharge the teleporter." );
+ return;
+ }
+
+ if( !IsInPlayersPack( pUser, scroll ))
+ {
+ socket.SysMessage( "This item must be in your backpack." );
+ return;
+ }
+
+ var cur = ReadIntTag( teleporter, "HT_Charges", 0 );
+ if( cur < 0 )
+ cur = 0;
+
+ if( cur >= 1000 )
+ {
+ socket.SysMessage( "The House Teleporter cannot be charged any further." );
+ return;
+ }
+
+ if(( scroll.amount|0 ) > 1 )
+ {
+ scroll.amount = ( scroll.amount|0 ) - 1;
+ }
+ else
+ {
+ scroll.Delete();
+ }
+
+ cur += 5;
+ if( cur > 1000 )
+ cur = 1000;
+
+ teleporter.SetTag( "HT_Charges", cur );
+ socket.SysMessage( "The Gate Travel scroll crumbles to dust as it strengthens the House Teleporter." );
+}
+
+function UnlinkOther( tile, keepSer )
+{
+ var old = ReadIntTag( tile, "HT_LinkSer", 0 );
+ tile.SetTag( "HT_LinkSer", null );
+
+ if( old > 0 && old != keepSer )
+ {
+ var oldtele = CalcItemFromSer( old );
+ if( IsTeleporterItem( oldtele ))
+ oldtele.SetTag( "HT_LinkSer", null );
+ }
+}
+
+function onCollide( trgSock, pColliding, objCollidedWith )
+{
+ if( !ValidateObject( pColliding ) || !pColliding.isChar )
+ return false;
+
+ if( !IsTeleporterItem( objCollidedWith ))
+ return false;
+
+ if( trgSock == null )
+ return false;
+
+ if( objCollidedWith.movable != 3 )
+ {
+ if( trgSock )
+ trgSock.SysMessage( "This must be locked down in a house to function." );
+ return false;
+ }
+
+ if( !IsInBuilding( objCollidedWith.x, objCollidedWith.y, objCollidedWith.z, objCollidedWith.worldnumber, objCollidedWith.instanceID, true ))
+ {
+ if( trgSock )
+ trgSock.SysMessage( "This must be placed inside a house." );
+ return false;
+ }
+
+ // SECURITY: Owner + Co-Owners only
+ if(!CanUseHouseTeleporter(pColliding, objCollidedWith))
+ {
+ if( trgSock )
+ trgSock.SysMessage("Only the house owner and co-owners may use this teleporter.");
+ return false;
+ }
+
+ if( trgSock )
+ {
+ if( pColliding.dead || pColliding.criminal )
+ {
+ trgSock.SysMessage("You cannot use that right now.");
+ return false;
+ }
+ }
+
+ var linkSer = ReadIntTag( objCollidedWith, "HT_LinkSer", 0 );
+ if( linkSer <= 0 )
+ {
+ if( trgSock )
+ trgSock.SysMessage( "This teleporter is not linked." );
+ return false;
+ }
+
+ var other = CalcItemFromSer( linkSer );
+ if( !IsTeleporterItem( other ))
+ {
+ if( trgSock )
+ trgSock.SysMessage( "This teleporter is not linked." );
+ return false;
+ }
+
+ if( other.movable != 3 )
+ {
+ if( trgSock )
+ trgSock.SysMessage( "The destination teleporter is not properly placed." );
+ return false;
+ }
+
+ if( !IsInBuilding( other.x, other.y, other.z, other.worldnumber, other.instanceID, true ))
+ {
+ if( trgSock )
+ trgSock.SysMessage( "The destination teleporter is not properly placed." );
+ return false;
+ }
+
+ if( objCollidedWith.id == 0x574A )
+ {
+ var charge = ReadIntTag( objCollidedWith, "HT_Charges", 0 );
+ if( charge < 0 )
+ charge = 0;
+
+ if( charge <= 0 )
+ {
+ if( trgSock )
+ trgSock.SysMessage( "There are no charges left in this teleporter." );
+ return false;
+ }
+
+ objCollidedWith.SetTag( "HT_Charges", charge - 1 );
+ }
+
+ pColliding.Teleport( other.x, other.y, other.z, other.worldnumber );
+ return false;
+}
+
+function onDropItemOnItem( pUser, iDropped, iOn )
+{
+ var pSocket = pUser.socket;
+ if( !pSocket )
+ return true;
+
+ if( !ValidateObject( iDropped ) || !ValidateObject( iOn ) )
+ return true;
+
+ if( !iOn.isItem || iOn.id != 0x574A )
+ return true;
+
+ if( !iDropped.isItem || iDropped.id != 0x1F60 )
+ return true;
+
+ var cur = ReadIntTag( iOn, "HT_Charges", 0 );
+ if( cur < 0 )
+ cur = 0;
+
+ if( cur >= 1000 )
+ {
+ pSocket.SysMessage( "This teleporter is fully charged." );
+ return false;
+ }
+
+ iDropped.Delete();
+
+ cur += 5;
+ if( cur > 1000 )
+ cur = 1000;
+
+ iOn.SetTag( "HT_Charges", cur );
+ pSocket.SysMessage( "Charges: " + cur + " / " + 1000 );
+ return false;
+}
+
+/** @type { ( pUser: Character, targObj: BaseObject, pSpeech: string, pSpeechID: number ) => void } */
+function onSpeechInput( pUser, targObj, pSpeech, pSpeechID )
+{
+ var sock = pUser.socket;
+ if( !sock )
+ return;
+
+ if( pSpeechID != 1 )
+ return;
+
+ // Basic validation
+ if( pSpeech == null )
+ return;
+
+ pSpeech = ("" + pSpeech);
+
+ // trim (simple ES5)
+ pSpeech = pSpeech.replace(/^\s+|\s+$/g, "");
+ if( pSpeech.length <= 0 )
+ {
+ sock.SysMessage( GetDictionaryEntry( 9270, sock.language )); // too short / none entered
+ return;
+ }
+ if( pSpeech.length > 60 )
+ {
+ sock.SysMessage( GetDictionaryEntry( 9271, sock.language )); // too long (we'll reuse)
+ return;
+ }
+
+ // Resolve which teleporter we are renaming
+ var srcSer = parseInt( pUser.GetTempTag( "HT_RenameSer" ), 10 );
+ if( !isFinite( srcSer ) || srcSer <= 0 )
+ return;
+
+ var teleA = CalcItemFromSer( srcSer );
+ if( !IsTeleporterItem( teleA ))
+ {
+ sock.SysMessage( "Teleporter not found." );
+ return;
+ }
+
+ // Must still be linked
+ var linkSer = ReadIntTag( teleA, "HT_LinkSer", 0 );
+ if( linkSer <= 0 )
+ {
+ sock.SysMessage( "This teleporter must be linked before it can be renamed." );
+ return;
+ }
+
+ var teleB = CalcItemFromSer( linkSer );
+ if( !IsTeleporterItem( teleB ))
+ {
+ sock.SysMessage( "This teleporter must be linked before it can be renamed." );
+ return;
+ }
+
+ // Apply name to BOTH
+ teleA.name = pSpeech;
+ teleB.name = pSpeech;
+
+ teleA.Refresh();
+ teleB.Refresh();
+
+ sock.SysMessage( "Teleporter name set to: " + pSpeech );
+}
+
+/** @type { ( myObj: BaseObject, pSocket: Socket ) => string } */
+function onTooltip( myObj, pSocket )
+{
+ if( !ValidateObject( myObj ) || !myObj.isItem )
+ return "";
+
+ if( !IsTeleporterItem( myObj ))
+ return "";
+
+ var parts = [];
+ var secMode = GetSecurityMode( myObj );
+ parts.push( "Security: " + SecurityName( secMode ));
+
+ if( myObj.id == 0x574A )
+ {
+ var charge = ReadIntTag( myObj, "HT_Charges", 0 );
+ if( charge < 0 ) charge = 0;
+ if( charge > 1000 ) charge = 1000;
+ parts.push( "Charges: " + charge + "/1000" );
+ }
+
+ var linkSer = ReadIntTag( myObj, "HT_LinkSer", 0 );
+ var linked = false;
+ if( linkSer > 0 )
+ {
+ var other = CalcItemFromSer( linkSer );
+ if( IsTeleporterItem( other ))
+ linked = true;
+ }
+ parts.push( "Link: " + ( linked ? "Linked" : "Unlinked" ));
+
+ return parts.join( "
" );
+}
diff --git a/data/js/jse_fileassociations.scp b/data/js/jse_fileassociations.scp
index ecda3b0bc..2361a7665 100644
--- a/data/js/jse_fileassociations.scp
+++ b/data/js/jse_fileassociations.scp
@@ -319,6 +319,7 @@
5062=item/shrines.js
5063=item/recipescroll.js
5070=item/dawns_music_box.js
+5080=item/houseteleporter.js
19100=item/plant_growing/plantsystem.js
19101=item/plant_growing/plantbowl.js
From 551a590ad5bf277978562a58a6b101e39a0e250a Mon Sep 17 00:00:00 2001
From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com>
Date: Sun, 8 Feb 2026 23:02:11 -0600
Subject: [PATCH 02/12] Update houseteleporter.js
---
data/js/item/houseteleporter.js | 52 +++++++++++++++++++++------------
1 file changed, 33 insertions(+), 19 deletions(-)
diff --git a/data/js/item/houseteleporter.js b/data/js/item/houseteleporter.js
index f1a8f4c1a..9d5b3726d 100644
--- a/data/js/item/houseteleporter.js
+++ b/data/js/item/houseteleporter.js
@@ -1,6 +1,11 @@
///
// @ts-check
+const chargeItemIDReq = 0x1f60;
+const chargeItemSectionIDReq = "0x1f60";
+const chargeAmount = 5;
+const chargeMax = 1000;
+
const coOwnHousesOnSameAccount = GetServerSetting("CoOwnHousesOnSameAccount");
function IsTeleporterItem( item )
@@ -10,7 +15,7 @@ function IsTeleporterItem( item )
function IsScrollItem( item )
{
- return( ValidateObject(item) && item.isItem && item.id == 0x1F60 );
+ return( ValidateObject(item) && item.isItem && ( item.id == chargeItemIDReq || item.sectionID == chargeItemSectionIDReq ));
}
function IsInPlayersPack( pUser, item )
@@ -94,6 +99,7 @@ function CanUseHouseTeleporter( pChar, teleItem )
// Owner/coowner always allowed in all modes
if( m.IsOwner( pChar ))
return true;
+
if( m.IsOnOwnerList( pChar ))
return true;
@@ -121,6 +127,7 @@ function CanUseHouseTeleporter( pChar, teleItem )
return false;
}
+/** @type { ( tSock: Socket, baseObj: BaseObject ) => boolean } */
function onContextMenuRequest( socket, targObj )
{
var pUser = socket.currentChar;
@@ -232,6 +239,7 @@ function onContextMenuRequest( socket, targObj )
return false;
}
+/** @type { ( tSock: Socket, baseObj: BaseObject, popupEntry: number ) => boolean } */
function onContextMenuSelect( socket, targObj, popupEntry )
{
var pUser = socket.currentChar;
@@ -255,14 +263,14 @@ function onContextMenuSelect( socket, targObj, popupEntry )
if( targObj.id == 0x574A )
{
- var charge = ReadIntTag(targObj, "HT_Charges", 0);
+ var charge = ReadIntTag( targObj, "HT_Charges", 0 );
if( charge < 0 )
charge = 0;
- if( charge > 1000 )
- charge = 1000;
+ if( charge > chargeMax )
+ charge = chargeMax;
- socket.SysMessage( "Teleporter: " + ( linked ? "Linked" : "Unlinked" ) + " | Charges: " + charge + "/" + 1000 );
+ socket.SysMessage( "Teleporter: " + ( linked ? "Linked" : "Unlinked" ) + " | Charges: " + charge + "/" + chargeMax );
}
else
{
@@ -294,7 +302,7 @@ function onContextMenuSelect( socket, targObj, popupEntry )
if( cur < 0 )
cur = 0;
- if( cur >= 1000 )
+ if( cur >= chargeMax )
{
socket.SysMessage( "This teleporter is fully charged." );
return false;
@@ -362,6 +370,7 @@ function onContextMenuSelect( socket, targObj, popupEntry )
return false;
}
+/** @type { ( user: Character, iUsing: Item ) => boolean } */
function onUseChecked( pUser, iUsed )
{
var pSocket = pUser.socket;
@@ -382,6 +391,7 @@ function onUseChecked( pUser, iUsed )
return true;
}
+/** @type { ( tSock: Socket, target: Character | Item | null ) => void } */
function onCallback0( socket, target )
{
var pUser = socket.currentChar;
@@ -433,6 +443,7 @@ function onCallback0( socket, target )
socket.SysMessage( "Teleporters linked." );
}
+/** @type { ( tSock: Socket, target: Character | Item | null ) => void } */
function onCallback1( socket, target )
{
var pUser = socket.currentChar;
@@ -467,7 +478,7 @@ function onCallback1( socket, target )
if( cur < 0 )
cur = 0;
- if( cur >= 1000 )
+ if( cur >= chargeMax )
{
socket.SysMessage( "The House Teleporter cannot be charged any further." );
return;
@@ -482,12 +493,13 @@ function onCallback1( socket, target )
scroll.Delete();
}
- cur += 5;
- if( cur > 1000 )
- cur = 1000;
+ cur += chargeAmount;
+ if( cur > chargeMax )
+ cur = chargeMax;
teleporter.SetTag( "HT_Charges", cur );
socket.SysMessage( "The Gate Travel scroll crumbles to dust as it strengthens the House Teleporter." );
+ teleporter.Refresh();
}
function UnlinkOther( tile, keepSer )
@@ -503,6 +515,7 @@ function UnlinkOther( tile, keepSer )
}
}
+/** @type { ( targSock: Socket, objColliding: Character, objCollideWith: BaseObject ) => boolean } */
function onCollide( trgSock, pColliding, objCollidedWith )
{
if( !ValidateObject( pColliding ) || !pColliding.isChar )
@@ -595,6 +608,7 @@ function onCollide( trgSock, pColliding, objCollidedWith )
return false;
}
+/** @type { ( item: Item, dropper: Character, dest: Item ) => number } */
function onDropItemOnItem( pUser, iDropped, iOn )
{
var pSocket = pUser.socket;
@@ -607,14 +621,14 @@ function onDropItemOnItem( pUser, iDropped, iOn )
if( !iOn.isItem || iOn.id != 0x574A )
return true;
- if( !iDropped.isItem || iDropped.id != 0x1F60 )
+ if( !iDropped.isItem || !( iDropped.id == chargeItemIDReq || iDropped.sectionID == chargeItemSectionIDReq ))
return true;
var cur = ReadIntTag( iOn, "HT_Charges", 0 );
if( cur < 0 )
cur = 0;
- if( cur >= 1000 )
+ if( cur >= chargeMax )
{
pSocket.SysMessage( "This teleporter is fully charged." );
return false;
@@ -622,16 +636,16 @@ function onDropItemOnItem( pUser, iDropped, iOn )
iDropped.Delete();
- cur += 5;
- if( cur > 1000 )
- cur = 1000;
+ cur += chargeAmount;
+ if( cur > chargeMax )
+ cur = chargeMax;
iOn.SetTag( "HT_Charges", cur );
- pSocket.SysMessage( "Charges: " + cur + " / " + 1000 );
+ pSocket.SysMessage( "Charges: " + cur + " / " + chargeMax );
return false;
}
-/** @type { ( pUser: Character, targObj: BaseObject, pSpeech: string, pSpeechID: number ) => void } */
+/** @type { ( myChar: Character, myItem: Item, mySpeech: string, mySpeechId: number ) => void } */
function onSpeechInput( pUser, targObj, pSpeech, pSpeechID )
{
var sock = pUser.socket;
@@ -714,8 +728,8 @@ function onTooltip( myObj, pSocket )
{
var charge = ReadIntTag( myObj, "HT_Charges", 0 );
if( charge < 0 ) charge = 0;
- if( charge > 1000 ) charge = 1000;
- parts.push( "Charges: " + charge + "/1000" );
+ if( charge > chargeMax ) charge = chargeMax;
+ parts.push( "Charges: " + charge + "/" + chargeMax );
}
var linkSer = ReadIntTag( myObj, "HT_LinkSer", 0 );
From f14763706035288129f9e952956382a91502f79e Mon Sep 17 00:00:00 2001
From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com>
Date: Sun, 8 Feb 2026 23:19:24 -0600
Subject: [PATCH 03/12] small changes
---
data/dfndata/items/misc/houseteleporters.dfn | 18 ++---
data/js/item/houseteleporter.js | 75 ++++++++++++--------
2 files changed, 54 insertions(+), 39 deletions(-)
diff --git a/data/dfndata/items/misc/houseteleporters.dfn b/data/dfndata/items/misc/houseteleporters.dfn
index c7f84f62d..1bf587646 100644
--- a/data/dfndata/items/misc/houseteleporters.dfn
+++ b/data/dfndata/items/misc/houseteleporters.dfn
@@ -1,23 +1,23 @@
-[houseteleporter]
+[base_house_teleporter]
{
get=base_item
name=a house teleporter
-id=0x40BB
weight=100
decay=1
script=5080
origin=hs
movable=1
+sectionid=house_teleporter
+}
+
+[houseteleporter]
+{
+get=base_house_teleporter
+id=0x40BB
}
[chargedhouseteleporter]
{
-get=base_item
-name=a house teleporter
+get=base_house_teleporter
id=0x574A
-weight=100
-decay=1
-script=5080
-origin=hs
-movable=1
}
\ No newline at end of file
diff --git a/data/js/item/houseteleporter.js b/data/js/item/houseteleporter.js
index 9d5b3726d..1b1d72528 100644
--- a/data/js/item/houseteleporter.js
+++ b/data/js/item/houseteleporter.js
@@ -5,22 +5,36 @@ const chargeItemIDReq = 0x1f60;
const chargeItemSectionIDReq = "0x1f60";
const chargeAmount = 5;
const chargeMax = 1000;
-
+const teleporterIDReq = [0x40BB, 0x574A];
+const teleporterSectionIDReq = "house_teleporter";
const coOwnHousesOnSameAccount = GetServerSetting("CoOwnHousesOnSameAccount");
function IsTeleporterItem( item )
{
- return ( ValidateObject( item ) && item.isItem && (item.id == 0x40BB || item.id == 0x574A));
+ if( !ValidateObject( item ) || !item.isItem )
+ return false;
+
+ // allow by sectionid
+ if( item.sectionID == teleporterSectionIDReq )
+ return true;
+
+ // allow by id list
+ for( var i = 0; i < teleporterIDReq.length; i++ )
+ {
+ if( item.id == teleporterIDReq[i] )
+ return true;
+ }
+ return false;
}
-function IsScrollItem( item )
+function IsItemReq( item )
{
return( ValidateObject(item) && item.isItem && ( item.id == chargeItemIDReq || item.sectionID == chargeItemSectionIDReq ));
}
function IsInPlayersPack( pUser, item )
{
- if( !ValidateObject( pUser ) || !ValidateObject( pUser.pack ) || !IsTeleporterItem( item ) && !IsScrollItem( item ))
+ if( !ValidateObject( pUser ) || !ValidateObject( pUser.pack ) || !IsTeleporterItem( item ) && !IsItemReq( item ))
return false;
var root = FindRootContainer( item, 0 );
@@ -29,7 +43,7 @@ function IsInPlayersPack( pUser, item )
function ReadIntTag( obj, tagName, defVal )
{
- var value = parseInt(obj.GetTag(tagName), 10);
+ var value = parseInt( obj.GetTag( tagName ), 10 );
if( !isFinite( value ))
value = defVal;
return value;
@@ -383,12 +397,12 @@ function onUseChecked( pUser, iUsed )
if( !IsInPlayersPack(pUser, iUsed) )
{
pSocket.SysMessage( "To link, both teleporters must be in your backpack." );
- return true;
+ return false;
}
pUser.SetTempTag( "HT_LinkSrcSer", iUsed.serial );
pSocket.CustomTarget( 0, "Target the other teleporter in your backpack to link." );
- return true;
+ return false;
}
/** @type { ( tSock: Socket, target: Character | Item | null ) => void } */
@@ -402,43 +416,44 @@ function onCallback0( socket, target )
return;
var srcSer = parseInt( pUser.GetTempTag( "HT_LinkSrcSer" ), 10 );
- if( !isFinite(srcSer) || srcSer <= 0 ) return;
+ if( !isFinite( srcSer ) || srcSer <= 0 )
+ return;
- var telporterA = CalcItemFromSer( srcSer );
- var telporterB = target;
+ var teleporterA = CalcItemFromSer( srcSer );
+ var teleporterB = target;
- if( !IsTeleporterItem( telporterA ))
+ if( !IsTeleporterItem( teleporterA ))
{
socket.SysMessage( "Source teleporter not found." );
return;
}
- if( !IsTeleporterItem( telporterB ))
+ if( !IsTeleporterItem( teleporterB ))
{
socket.SysMessage( "That is not a house teleporter." );
return;
}
- if( telporterA.serial == telporterB.serial )
+ if( teleporterA.serial == teleporterB.serial )
{
socket.SysMessage( "You must target the other teleporter." );
return;
}
- if( telporterA.id != telporterB.id )
+ if( teleporterA.id != teleporterB.id )
{
socket.SysMessage( "These teleporters are different types and cannot be linked." );
return;
}
- if( !IsInPlayersPack( pUser, telporterA ) || !IsInPlayersPack( pUser, telporterB ))
+ if( !IsInPlayersPack( pUser, teleporterA ) || !IsInPlayersPack( pUser, teleporterB ))
{
socket.SysMessage( "Both teleporters must be in your backpack to link." );
return;
}
- UnlinkOther( telporterA, telporterB.serial );
- UnlinkOther( telporterB, telporterA.serial );
+ UnlinkOther( teleporterA, teleporterB.serial );
+ UnlinkOther( teleporterB, teleporterA.serial );
- telporterA.SetTag( "HT_LinkSer", telporterB.serial );
- telporterB.SetTag( "HT_LinkSer", telporterA.serial );
+ teleporterA.SetTag( "HT_LinkSer", teleporterB.serial );
+ teleporterB.SetTag( "HT_LinkSer", teleporterA.serial );
socket.SysMessage( "Teleporters linked." );
}
@@ -462,9 +477,9 @@ function onCallback1( socket, target )
return;
var scroll = target;
- if( !IsScrollItem( scroll ))
+ if( !IsItemReq( scroll ))
{
- socket.SysMessage("Target gate travel scrolls to recharge the teleporter." );
+ socket.SysMessage( "Target gate travel scrolls to recharge the teleporter." );
return;
}
@@ -541,11 +556,11 @@ function onCollide( trgSock, pColliding, objCollidedWith )
return false;
}
- // SECURITY: Owner + Co-Owners only
+ // SECURITY: Owner + Co-Owners only
if(!CanUseHouseTeleporter(pColliding, objCollidedWith))
{
if( trgSock )
- trgSock.SysMessage("Only the house owner and co-owners may use this teleporter.");
+ trgSock.SysMessage( "Only the house owner and co-owners may use this teleporter." );
return false;
}
@@ -553,7 +568,7 @@ function onCollide( trgSock, pColliding, objCollidedWith )
{
if( pColliding.dead || pColliding.criminal )
{
- trgSock.SysMessage("You cannot use that right now.");
+ trgSock.SysMessage( "You cannot use that right now." );
return false;
}
}
@@ -613,16 +628,16 @@ function onDropItemOnItem( pUser, iDropped, iOn )
{
var pSocket = pUser.socket;
if( !pSocket )
- return true;
+ return 1;
if( !ValidateObject( iDropped ) || !ValidateObject( iOn ) )
- return true;
+ return 1;
if( !iOn.isItem || iOn.id != 0x574A )
- return true;
+ return 1;
if( !iDropped.isItem || !( iDropped.id == chargeItemIDReq || iDropped.sectionID == chargeItemSectionIDReq ))
- return true;
+ return 1;
var cur = ReadIntTag( iOn, "HT_Charges", 0 );
if( cur < 0 )
@@ -631,7 +646,7 @@ function onDropItemOnItem( pUser, iDropped, iOn )
if( cur >= chargeMax )
{
pSocket.SysMessage( "This teleporter is fully charged." );
- return false;
+ return 0;
}
iDropped.Delete();
@@ -642,7 +657,7 @@ function onDropItemOnItem( pUser, iDropped, iOn )
iOn.SetTag( "HT_Charges", cur );
pSocket.SysMessage( "Charges: " + cur + " / " + chargeMax );
- return false;
+ return 0;
}
/** @type { ( myChar: Character, myItem: Item, mySpeech: string, mySpeechId: number ) => void } */
From 52c00cc6718159005ff25e347872dadc93708f1e Mon Sep 17 00:00:00 2001
From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com>
Date: Mon, 9 Feb 2026 00:21:30 -0600
Subject: [PATCH 04/12] Update
---
data/dfndata/items/misc/houseteleporters.dfn | 1 +
data/dictionaries/dictionary.CSY | 32 +++++
data/dictionaries/dictionary.ENG | 32 +++++
data/dictionaries/dictionary.FRE | 31 +++++
data/dictionaries/dictionary.GER | 31 +++++
data/dictionaries/dictionary.ITA | 31 +++++
data/dictionaries/dictionary.POL | 31 +++++
data/dictionaries/dictionary.PTG | 32 +++++
data/dictionaries/dictionary.SPA | 31 +++++
data/dictionaries/dictionary.ZRO | 32 +++++
data/js/item/houseteleporter.js | 118 +++++++++++--------
11 files changed, 352 insertions(+), 50 deletions(-)
diff --git a/data/dfndata/items/misc/houseteleporters.dfn b/data/dfndata/items/misc/houseteleporters.dfn
index 1bf587646..21e6147fb 100644
--- a/data/dfndata/items/misc/houseteleporters.dfn
+++ b/data/dfndata/items/misc/houseteleporters.dfn
@@ -20,4 +20,5 @@ id=0x40BB
{
get=base_house_teleporter
id=0x574A
+custominttag=HT_rechargeFuel 1
}
\ No newline at end of file
diff --git a/data/dictionaries/dictionary.CSY b/data/dictionaries/dictionary.CSY
index 8e5f8cf24..cf7ebd1f1 100644
--- a/data/dictionaries/dictionary.CSY
+++ b/data/dictionaries/dictionary.CSY
@@ -5635,5 +5635,37 @@
19341=Tento recept už znáte.
19342=Naučili jste se nový recept: %i
19343=Musíte se ho naučit ze svitku.
+// [30600-30650] Teleport domu
+30600=Pro propojení musí být tento objekt ve vašem batohu.
+30601=Pro propojení zaměřte druhý teleport v batohu.
+30602=Tento teleport je plně nabitý.
+30603=Pro dobití zaměřte předmět pro dobíjení v batohu.
+30604=Zabezpečení tohoto teleportu nelze změnit.
+30605=Zabezpečení teleportu nastaveno na: %s.
+30606=Tento teleport nelze přejmenovat.
+30607=Tento teleport musí být propojen, než bude možné jej přejmenovat.
+30608=Pro propojení musí být oba teleporty ve vašem batohu.
+30609=Pro propojení zaměřte druhý teleport v batohu.
+30610=Zdrojový teleport nenalezen.
+30611=Toto není teleport domu.
+30612=Musíte zaměřit druhý teleport.
+30613=Tyto teleporty jsou různých typů a nelze je propojit.
+30614=Oba teleporty musí být ve vašem batohu, aby se propojily.
+30615=Teleporty propojené.
+30616=Zaměřte se na dobíjecí předmět pro dobití teleportu.
+30617=Tento předmět musí být ve vašem batohu.
+30618=Teleport domu nelze dále nabíjet.
+30619=Dobíjecí předmět se rozpadne na prach, když posiluje Teleport domu.
+30620=Aby fungoval, musí být uzamčen v domě.
+30621=Musí být umístěn uvnitř domu.
+30622=Tento teleport může používat pouze majitel domu a spolumajitelé.
+30623=Toto nyní nemůžete použít.
+30624=Tento teleport není propojen.
+30625=Cílový teleport není správně umístěn.
+30626=V tomto teleportu nezbývají žádné náboje.
+30627=Tento teleport je plně nabitý.
+30628=Teleport nebyl nalezen.
+30629=Tento teleport musí být propojen, než bude možné jej přejmenovat.
+30630=Název teleportu nastaven na: %s
}
EOF
diff --git a/data/dictionaries/dictionary.ENG b/data/dictionaries/dictionary.ENG
index b2cd6e249..2cf221fa5 100644
--- a/data/dictionaries/dictionary.ENG
+++ b/data/dictionaries/dictionary.ENG
@@ -5635,5 +5635,37 @@
19341=You already know this recipe.
19342=You have learned a new recipe: %i
19343=You must learn that recipe from a scroll.
+// [30600-30650 ] House Teleporter
+30600=This must be in your backpack to link it.
+30601=Target the other teleporter in your backpack to link.
+30602=This teleporter is fully charged.
+30603=Target recharge item in your backpack to recharge
+30604=You cannot change this teleporter's security.
+30605=Teleporter security set to: %s
+30606=You cannot rename this teleporter.
+30607=This teleporter must be linked before it can be renamed.
+30608=To link, both teleporters must be in your backpack.
+30609=Target the other teleporter in your backpack to link.
+30610=Source teleporter not found.
+30611=That is not a house teleporter.
+30612=You must target the other teleporter.
+30613=These teleporters are different types and cannot be linked.
+30614=Both teleporters must be in your backpack to link.
+30615=Teleporters linked.
+30616=Target recharge item to recharge the teleporter.
+30617=This item must be in your backpack.
+30618=The House Teleporter cannot be charged any further.
+30619=The recharge item crumbles to dust as it strengthens the House Teleporter.
+30620=This must be locked down in a house to function.
+30621=This must be placed inside a house.
+30622=Only the house owner and co-owners may use this teleporter.
+30623=You cannot use that right now.
+30624=This teleporter is not linked.
+30625=The destination teleporter is not properly placed.
+30626=There are no charges left in this teleporter.
+30627=This teleporter is fully charged.
+30628=Teleporter not found.
+30629=This teleporter must be linked before it can be renamed.
+30630=Teleporter name set to: %s
}
EOF
diff --git a/data/dictionaries/dictionary.FRE b/data/dictionaries/dictionary.FRE
index 21e9a45a8..fbf71c166 100644
--- a/data/dictionaries/dictionary.FRE
+++ b/data/dictionaries/dictionary.FRE
@@ -5799,5 +5799,36 @@
19341=Vous connaissez déjà cette recette.
19342=Vous avez appris une nouvelle recette : %i
19343=Vous devez apprendre cette recette à partir d'un parchemin.
+// [30600-30650] Téléporteur de maison
+30600=Cet objet doit être dans votre sac à dos pour pouvoir le lier.
+30601=Ciblez l'autre téléporteur dans votre sac à dos pour le lier.
+30602=Ce téléporteur est entièrement chargé.
+30603=Ciblez l'objet de recharge dans votre sac à dos pour le recharger.
+30604=Vous ne pouvez pas modifier la sécurité de ce téléporteur.
+30605=Sécurité du téléporteur définie sur : %s
+30606=Vous ne pouvez pas renommer ce téléporteur.
+30607=Ce téléporteur doit être lié avant de pouvoir être renommé.
+30608=Pour les lier, les deux téléporteurs doivent être dans votre sac à dos.
+30609=Ciblez l'autre téléporteur dans votre sac à dos pour le lier.
+30610=Téléporteur source introuvable.
+30611=Ce n'est pas un téléporteur de maison.
+30612=Vous devez cibler l'autre téléporteur.
+30613=Ces téléporteurs sont de types différents et ne peuvent pas être liés.
+30614=Les deux téléporteurs doivent être dans votre sac à dos pour les lier.
+30615=Téléporteurs liés.
+30616=Ciblez l'objet de recharge pour recharger le téléporteur.
+30617=Cet objet doit être dans votre sac à dos.
+30618=Le téléporteur de maison ne peut pas être chargé davantage.
+30619=L'objet de recharge se désintègre en poussière en renforçant le téléporteur de maison.
+30620=Cet objet doit être verrouillé dans une maison pour fonctionner.
+30621=Cet objet doit être placé à l'intérieur d'une maison.
+30622=Seuls le propriétaire et les copropriétaires de la maison peuvent utiliser ce téléporteur.
+30623=Vous ne pouvez pas utiliser cet objet pour le moment.
+30624=Ce téléporteur n'est pas lié.
+30625=Le téléporteur de destination n'est pas correctement placé.
+30626=Il n'y a plus de charges dans ce téléporteur.
+30627=Ce téléporteur est entièrement chargé.
+30628=Téléporteur introuvable. 30629=Ce téléporteur doit être connecté avant de pouvoir être renommé.
+30630=Nom du téléporteur défini sur : %s
}
EOF
diff --git a/data/dictionaries/dictionary.GER b/data/dictionaries/dictionary.GER
index 4f8861cb5..866899fd4 100644
--- a/data/dictionaries/dictionary.GER
+++ b/data/dictionaries/dictionary.GER
@@ -5635,5 +5635,36 @@
19341=Du kennst dieses Rezept bereits.
19342=Du hast ein neues Rezept gelernt: %i
19343=Du musst dieses Rezept von einer Schriftrolle lernen.
+// [30600-30650] Hausteleporter
+30600=Dieses Objekt muss sich in Ihrem Rucksack befinden, um es zu verknüpfen.
+30601=Wählen Sie den anderen Teleporter in Ihrem Rucksack aus, um ihn zu verknüpfen.
+30602=Dieser Teleporter ist vollständig aufgeladen.
+30603=Wählen Sie ein Aufladeobjekt in Ihrem Rucksack aus, um den Teleporter aufzuladen.
+30604=Sie können die Sicherheitseinstellungen dieses Teleporters nicht ändern.
+30605=Sicherheitseinstellungen des Teleporters: %s
+30606=Sie können diesen Teleporter nicht umbenennen.
+30607=Dieser Teleporter muss verknüpft sein, bevor er umbenannt werden kann.
+30608=Um die Teleporter zu verknüpfen, müssen sich beide in Ihrem Rucksack befinden.
+30609=Wählen Sie den anderen Teleporter in Ihrem Rucksack aus, um ihn zu verknüpfen.
+30610=Quell-Teleporter nicht gefunden.
+30611=Das ist kein Hausteleporter.
+30612=Sie müssen den anderen Teleporter auswählen.
+30613=Diese Teleporter sind unterschiedlichen Typs und können nicht verknüpft werden.
+30614=Beide Teleporter müssen sich in Ihrem Rucksack befinden, um sie zu verknüpfen.
+30615=Teleporter verknüpft.
+30616=Wählen Sie ein Aufladeobjekt aus, um den Teleporter aufzuladen.
+30617=Dieses Objekt muss sich in Ihrem Rucksack befinden.
+30618=Der Hausteleporter kann nicht weiter aufgeladen werden.
+30619=Das Aufladeobjekt zerfällt zu Staub, während es den Hausteleporter verstärkt.
+30620=Dieses Objekt muss in einem Haus platziert und gesichert werden, damit es funktioniert.
+30621=Dieses Objekt muss in einem Haus platziert werden.
+30622=Nur der Hausbesitzer und die Miteigentümer dürfen diesen Teleporter benutzen.
+30623=Sie können das im Moment nicht verwenden.
+30624=Dieser Teleporter ist nicht verknüpft.
+30625=Der Ziel-Teleporter ist nicht richtig platziert.
+30626=Dieser Teleporter hat keine Ladungen mehr.
+30627=Dieser Teleporter ist vollständig aufgeladen.
+30628=Teleporter nicht gefunden. 30629=Dieser Teleporter muss verknüpft werden, bevor er umbenannt werden kann.
+30630=Teleportername festgelegt auf: %s
}
EOF
diff --git a/data/dictionaries/dictionary.ITA b/data/dictionaries/dictionary.ITA
index 371e3de0e..86747fac5 100644
--- a/data/dictionaries/dictionary.ITA
+++ b/data/dictionaries/dictionary.ITA
@@ -5635,5 +5635,36 @@
19341=Conosci già questa ricetta.
19342=Hai imparato una nuova ricetta: %i
19343=Devi imparare quella ricetta da una pergamena.
+// [30600-30650] Teletrasporto per casa
+30600=Questo oggetto deve essere nel tuo zaino per poterlo collegare.
+30601=Seleziona l'altro teletrasporto nel tuo zaino per collegarli.
+30602=Questo teletrasporto è completamente carico.
+30603=Seleziona l'oggetto di ricarica nel tuo zaino per ricaricarlo.
+30604=Non puoi modificare la sicurezza di questo teletrasporto.
+30605=Sicurezza del teletrasporto impostata su: %s
+30606=Non puoi rinominare questo teletrasporto.
+30607=Questo teletrasporto deve essere collegato prima di poter essere rinominato.
+30608=Per il collegamento, entrambi i teletrasporti devono essere nel tuo zaino.
+30609=Seleziona l'altro teletrasporto nel tuo zaino per collegarli.
+30610=Teletrasporto di origine non trovato.
+30611=Questo non è un teletrasporto per casa.
+30612=Devi selezionare l'altro teletrasporto.
+30613=Questi teletrasporti sono di tipi diversi e non possono essere collegati.
+30614=Entrambi i teletrasporti devono essere nel tuo zaino per il collegamento.
+30615=Teletrasporti collegati.
+30616=Seleziona l'oggetto di ricarica per ricaricare il teletrasporto.
+30617=Questo oggetto deve essere nel tuo zaino.
+30618=Il teletrasporto per casa non può essere caricato ulteriormente.
+30619=L'oggetto di ricarica si sbriciola in polvere mentre potenzia il teletrasporto per casa.
+30620=Questo deve essere posizionato all'interno di una casa per funzionare.
+30621=Questo deve essere posizionato all'interno di una casa.
+30622=Solo il proprietario e i comproprietari della casa possono usare questo teletrasporto.
+30623=Non puoi usarlo in questo momento.
+30624=Questo teletrasporto non è collegato.
+30625=Il teletrasporto di destinazione non è posizionato correttamente.
+30626=Non ci sono più cariche in questo teletrasporto.
+30627=Questo teletrasporto è completamente carico.
+30628=Teletrasporto non trovato. 30629=Questo teletrasporto deve essere collegato prima di poter essere rinominato.
+30630=Nome del teletrasporto impostato su: %s
}
EOF
diff --git a/data/dictionaries/dictionary.POL b/data/dictionaries/dictionary.POL
index 3551ad629..e74657327 100644
--- a/data/dictionaries/dictionary.POL
+++ b/data/dictionaries/dictionary.POL
@@ -5635,5 +5635,36 @@
19341=Znasz już ten przepis.
19342=Nauczyłeś się nowego przepisu: %i
19343=Musisz nauczyć się tego przepisu ze zwoju.
+// [30600-30650] Teleporter domowy
+30600=Aby połączyć teleportery, oba muszą znajdować się w twoim plecaku.
+30601=Wybierz drugi teleporter w swoim plecaku, aby go połączyć.
+30602=Ten teleporter jest w pełni naładowany.
+30603=Wybierz przedmiot do ładowania w swoim plecaku, aby naładować teleporter.
+30604=Nie możesz zmienić zabezpieczeń tego teleportera.
+30605=Zabezpieczenia teleportera ustawione na: %s
+30606=Nie możesz zmienić nazwy tego teleportera.
+30607=Ten teleporter musi być połączony, zanim będzie można zmienić jego nazwę.
+30608=Aby połączyć teleportery, oba muszą znajdować się w twoim plecaku.
+30609=Wybierz drugi teleporter w swoim plecaku, aby go połączyć.
+30610=Nie znaleziono teleportera źródłowego.
+30611=To nie jest teleporter domowy.
+30612=Musisz wybrać drugi teleporter.
+30613=Te teleportery są różnych typów i nie można ich połączyć.
+30614=Oba teleportery muszą znajdować się w twoim plecaku, aby je połączyć.
+30615=Teleportery połączone.
+30616=Wybierz przedmiot do ładowania, aby naładować teleporter.
+30617=Ten przedmiot musi znajdować się w twoim plecaku.
+30618=Teleportera domowego nie można już bardziej naładować.
+30619=Przedmiot do ładowania rozpada się w pył, wzmacniając teleporter domowy.
+30620=Aby działał, musi być umieszczony w domu.
+30621=Musi być umieszczony wewnątrz domu.
+30622=Tylko właściciel domu i współwłaściciele mogą korzystać z tego teleportera.
+30623=Nie możesz tego teraz użyć.
+30624=Ten teleporter nie jest połączony.
+30625=Teleporter docelowy nie jest prawidłowo umieszczony.
+30626=W tym teleporterze nie pozostały żadne ładunki.
+30627=Ten teleporter jest w pełni naładowany.
+30628=Nie znaleziono teleportera. 30629=Ten teleport musi zostać połączony, zanim będzie można zmienić jego nazwę.
+30630=Nazwa teleportera została zmieniona na: %s
}
EOF
diff --git a/data/dictionaries/dictionary.PTG b/data/dictionaries/dictionary.PTG
index c48b0f244..f26405894 100644
--- a/data/dictionaries/dictionary.PTG
+++ b/data/dictionaries/dictionary.PTG
@@ -5635,5 +5635,37 @@
19341=Já conhece esta receita.
19342=Aprendeu uma nova receita: %i
19343=Deve aprender esta receita num pergaminho.
+// [30600-30650 ] Teletransportador de Casa
+30600=Este item deve estar na sua mochila para o ligar.
+30601=Selecione o outro teletransportador da sua mochila para o ligar.
+30602=Este teletransportador está totalmente carregado.
+30603=Selecione o item de recarga na sua mochila para o recarregar.
+30604=Não pode alterar a segurança deste teletransportador.
+30605=Segurança do teletransportador definida como: %s
+30606=Não pode renomear este teletransportador.
+30607=Este teletransportador necessita de ser ligado antes de poder ser renomeado.
+30608=Para ligar, ambos os teletransportadores devem estar na sua mochila.
+30609=Selecione o outro teletransportador da sua mochila para o ligar.
+30610=Teletransportador de origem não encontrado.
+30611=Este não é um teletransportador de casa.
+30612=Deve selecionar o outro teletransportador.
+30613=Estes teletransportadores são de tipos diferentes e não podem ser ligados.
+30614=Ambos os teletransportadores têm de estar na sua mochila para serem ligados.
+30615=Teletransportadores ligados.
+30616=Selecione o item de recarga para recarregar o teletransportador.
+30617=Este item deve estar na sua mochila.
+30618=O Teletransportador de Casa não pode ser recarregado.
+30619=O item de recarga desfaz-se em pó ao fortalecer o Teletransportador de Casa.
+30620=Este item deve ser instalado no interior de uma casa para funcionar.
+30621=Este item deve ser colocado dentro de uma casa.
+30622=Apenas o dono da casa e os coproprietários podem utilizar este teletransportador.
+30623=Não pode usar isso agora.
+30624=Este teletransportador não está ligado.
+30625=O teletransportador de destino não está corretamente posicionado.
+30626=Não restam cargas neste teletransportador.
+30627=Este teletransportador está totalmente carregado.
+30628=Teletransportador não encontrado.
+30629=Este teletransportador necessita de ser ligado antes de poder ser renomeado.
+30630=Nome do teletransportador definido como: %s
}
EOF
diff --git a/data/dictionaries/dictionary.SPA b/data/dictionaries/dictionary.SPA
index 7c418b034..308374781 100644
--- a/data/dictionaries/dictionary.SPA
+++ b/data/dictionaries/dictionary.SPA
@@ -5635,5 +5635,36 @@
19341=Ya conoces esta receta.
19342=Has aprendido una nueva receta: %i
19343=Debes aprender esa receta de un pergamino.
+// [30600-30650] Teletransportador de casa
+30600=Esto debe estar en tu mochila para poder vincularlo.
+30601=Selecciona el otro teletransportador en tu mochila para vincularlos.
+30602=Este teletransportador está completamente cargado.
+30603=Selecciona el objeto de recarga en tu mochila para recargarlo.
+30604=No puedes cambiar la seguridad de este teletransportador.
+30605=Seguridad del teletransportador establecida en: %s
+30606=No puedes cambiar el nombre de este teletransportador.
+30607=Este teletransportador debe estar vinculado antes de poder cambiarle el nombre.
+30608=Para vincularlos, ambos teletransportadores deben estar en tu mochila.
+30609=Selecciona el otro teletransportador en tu mochila para vincularlos.
+30610=Teletransportador de origen no encontrado.
+30611=Eso no es un teletransportador de casa.
+30612=Debes seleccionar el otro teletransportador.
+30613=Estos teletransportadores son de tipos diferentes y no se pueden vincular.
+30614=Ambos teletransportadores deben estar en tu mochila para vincularlos.
+30615=Teletransportadores vinculados.
+30616=Selecciona el objeto de recarga para recargar el teletransportador.
+30617=Este objeto debe estar en tu mochila.
+30618=El teletransportador de casa no se puede cargar más.
+30619=El objeto de recarga se desintegra al fortalecer el teletransportador de casa.
+30620=Esto debe estar asegurado en una casa para funcionar.
+30621=Esto debe colocarse dentro de una casa.
+30622=Solo el propietario y los copropietarios de la casa pueden usar este teletransportador.
+30623=No puedes usar eso ahora mismo.
+30624=Este teletransportador no está vinculado.
+30625=El teletransportador de destino no está colocado correctamente.
+30626=No quedan cargas en este teletransportador.
+30627=Este teletransportador está completamente cargado.
+30628=Teletransportador no encontrado. 30629=Este teletransportador debe estar vinculado antes de poder cambiarle el nombre.
+30630=Nombre del teletransportador establecido a: %s
}
EOF
diff --git a/data/dictionaries/dictionary.ZRO b/data/dictionaries/dictionary.ZRO
index d8d2e0a3b..393275598 100644
--- a/data/dictionaries/dictionary.ZRO
+++ b/data/dictionaries/dictionary.ZRO
@@ -5633,5 +5633,37 @@
19341=You already know this recipe.
19342=You have learned a new recipe: %i
19343=You must learn that recipe from a scroll.
+// [30600-30650 ] House Teleporter
+30600=This must be in your backpack to link it.
+30601=Target the other teleporter in your backpack to link.
+30602=This teleporter is fully charged.
+30603=Target recharge item in your backpack to recharge
+30604=You cannot change this teleporter's security.
+30605=Teleporter security set to: %s
+30606=You cannot rename this teleporter.
+30607=This teleporter must be linked before it can be renamed.
+30608=To link, both teleporters must be in your backpack.
+30609=Target the other teleporter in your backpack to link.
+30610=Source teleporter not found.
+30611=That is not a house teleporter.
+30612=You must target the other teleporter.
+30613=These teleporters are different types and cannot be linked.
+30614=Both teleporters must be in your backpack to link.
+30615=Teleporters linked.
+30616=Target recharge item to recharge the teleporter.
+30617=This item must be in your backpack.
+30618=The House Teleporter cannot be charged any further.
+30619=The recharge item crumbles to dust as it strengthens the House Teleporter.
+30620=This must be locked down in a house to function.
+30621=This must be placed inside a house.
+30622=Only the house owner and co-owners may use this teleporter.
+30623=You cannot use that right now.
+30624=This teleporter is not linked.
+30625=The destination teleporter is not properly placed.
+30626=There are no charges left in this teleporter.
+30627=This teleporter is fully charged.
+30628=Teleporter not found.
+30629=This teleporter must be linked before it can be renamed.
+30630=Teleporter name set to: %s
}
EOF
diff --git a/data/js/item/houseteleporter.js b/data/js/item/houseteleporter.js
index 1b1d72528..4be633f92 100644
--- a/data/js/item/houseteleporter.js
+++ b/data/js/item/houseteleporter.js
@@ -7,7 +7,7 @@ const chargeAmount = 5;
const chargeMax = 1000;
const teleporterIDReq = [0x40BB, 0x574A];
const teleporterSectionIDReq = "house_teleporter";
-const coOwnHousesOnSameAccount = GetServerSetting("CoOwnHousesOnSameAccount");
+const coOwnHousesOnSameAccount = GetServerSetting( "CoOwnHousesOnSameAccount" );
function IsTeleporterItem( item )
{
@@ -297,19 +297,21 @@ function onContextMenuSelect( socket, targObj, popupEntry )
{
if( !IsInPlayersPack( pUser, targObj ))
{
- socket.SysMessage( "This must be in your backpack to link it." );
+ if( socket != null )
+ socket.SysMessage( GetDictionaryEntry( 30600, socket.language )); // This must be in your backpack to link it.
return false;
}
pUser.SetTempTag( "HT_LinkSrcSer", targObj.serial );
- socket.CustomTarget( 0, "Target the other teleporter in your backpack to link." );
+ if( socket != null )
+ socket.CustomTarget( 0, GetDictionaryEntry( 30601, socket.language )); // Target the other teleporter in your backpack to link.
targObj.Refresh();
return false;
}
if( popupEntry == 0x0103 )
{
- if( targObj.id != 0x574A )
+ if( targObj.GetTag( "HT_rechargeFuel" ) != 1 )
return false;
var cur = ReadIntTag( targObj, "HT_Charges", 0 );
@@ -318,12 +320,14 @@ function onContextMenuSelect( socket, targObj, popupEntry )
if( cur >= chargeMax )
{
- socket.SysMessage( "This teleporter is fully charged." );
+ if( socket != null )
+ socket.SysMessage( GetDictionaryEntry( 30602, socket.language ));
return false;
}
pUser.SetTempTag( "HT_RechargeSer", targObj.serial );
- socket.CustomTarget( 1, "Target gate travel scrolls in your backpack to recharge." );
+ if( socket != null )
+ socket.CustomTarget( 1, GetDictionaryEntry( 30603, socket.language )); // Target recharge item in your backpack to recharge.
targObj.Refresh();
return false;
}
@@ -334,7 +338,8 @@ function onContextMenuSelect( socket, targObj, popupEntry )
// Must be allowed to manage
if( !( targObj.movable == 3 && ValidateObject( targObj.multi ) && CanManageTeleporter( pUser, targObj )))
{
- socket.SysMessage( "You cannot change this teleporter's security." );
+ if( socket != null )
+ socket.SysMessage( GetDictionaryEntry( 30604, socket.language )); // You cannot change this teleporter's security.
return false;
}
@@ -344,7 +349,8 @@ function onContextMenuSelect( socket, targObj, popupEntry )
nextMode = 0;
targObj.SetTag( "HT_Security", nextMode );
- socket.SysMessage( "Teleporter security set to: " + SecurityName( nextMode ));
+ if( socket != null )
+ socket.SysMessage( "Teleporter security set to: " + SecurityName( nextMode )); // Teleporter security set to: %s
targObj.Refresh();
return false;
}
@@ -352,24 +358,27 @@ function onContextMenuSelect( socket, targObj, popupEntry )
if( popupEntry == 0x0105 )
{
// Must be placed + manageable
- if (!(targObj.movable == 3 && ValidateObject(targObj.multi) && CanManageTeleporter(pUser, targObj)))
+ if(!( targObj.movable == 3 && ValidateObject( targObj.multi ) && CanManageTeleporter( pUser, targObj )))
{
- socket.SysMessage("You cannot rename this teleporter.");
+ if( socket != null )
+ socket.SysMessage( GetDictionaryEntry( 30606, socket.language )); // You cannot rename this teleporter.
return false;
}
// Must be linked
- var linkSer = ReadIntTag(targObj, "HT_LinkSer", 0);
- if (linkSer <= 0)
+ var linkSer = ReadIntTag( targObj, "HT_LinkSer", 0 );
+ if( linkSer <= 0 )
{
- socket.SysMessage("This teleporter must be linked before it can be renamed.");
+ if( socket != null )
+ socket.SysMessage( GetDictionaryEntry( 30607, socket.language )); // This teleporter must be linked before it can be renamed.
return false;
}
- var other = CalcItemFromSer(linkSer);
- if (!IsTeleporterItem(other))
+ var other = CalcItemFromSer( linkSer );
+ if( !IsTeleporterItem( other ))
{
- socket.SysMessage("This teleporter must be linked before it can be renamed.");
+ if( socket != null )
+ socket.SysMessage( GetDictionaryEntry( 30607, socket.language )); // This teleporter must be linked before it can be renamed.
return false;
}
@@ -394,14 +403,14 @@ function onUseChecked( pUser, iUsed )
if( !IsTeleporterItem( iUsed ))
return false;
- if( !IsInPlayersPack(pUser, iUsed) )
+ if( !IsInPlayersPack( pUser, iUsed ))
{
- pSocket.SysMessage( "To link, both teleporters must be in your backpack." );
+ pSocket.SysMessage( GetDictionaryEntry( 30608, pSocket.language )); // To link, both teleporters must be in your backpack.
return false;
}
pUser.SetTempTag( "HT_LinkSrcSer", iUsed.serial );
- pSocket.CustomTarget( 0, "Target the other teleporter in your backpack to link." );
+ pSocket.CustomTarget( 0, GetDictionaryEntry( 30609, pSocket.language )); // Target the other teleporter in your backpack to link.
return false;
}
@@ -424,28 +433,33 @@ function onCallback0( socket, target )
if( !IsTeleporterItem( teleporterA ))
{
- socket.SysMessage( "Source teleporter not found." );
+ if( socket != null )
+ socket.SysMessage( GetDictionaryEntry( 30610, socket.language )); // Source teleporter not found.
return;
}
if( !IsTeleporterItem( teleporterB ))
{
- socket.SysMessage( "That is not a house teleporter." );
+ if( socket != null )
+ socket.SysMessage( GetDictionaryEntry( 30611, socket.language )); // That is not a house teleporter.
return;
}
if( teleporterA.serial == teleporterB.serial )
{
- socket.SysMessage( "You must target the other teleporter." );
+ if( socket != null )
+ socket.SysMessage( GetDictionaryEntry( 30612, socket.language )); // You must target the other teleporter.
return;
}
if( teleporterA.id != teleporterB.id )
{
- socket.SysMessage( "These teleporters are different types and cannot be linked." );
+ if( socket != null )
+ socket.SysMessage( GetDictionaryEntry( 30613, socket.language )); // These teleporters are different types and cannot be linked.
return;
}
if( !IsInPlayersPack( pUser, teleporterA ) || !IsInPlayersPack( pUser, teleporterB ))
{
- socket.SysMessage( "Both teleporters must be in your backpack to link." );
+ if( socket != null )
+ socket.SysMessage( GetDictionaryEntry( 30614, socket.language )); // Both teleporters must be in your backpack to link.
return;
}
@@ -454,8 +468,8 @@ function onCallback0( socket, target )
teleporterA.SetTag( "HT_LinkSer", teleporterB.serial );
teleporterB.SetTag( "HT_LinkSer", teleporterA.serial );
-
- socket.SysMessage( "Teleporters linked." );
+ if( socket != null )
+ socket.SysMessage( GetDictionaryEntry( 30615, socket.language )); // Teleporters linked.
}
/** @type { ( tSock: Socket, target: Character | Item | null ) => void } */
@@ -473,19 +487,21 @@ function onCallback1( socket, target )
return;
var teleporter = CalcItemFromSer( teleporterSerial );
- if( !ValidateObject( teleporter ) || !teleporter.isItem || teleporter.id != 0x574A )
+ if( !ValidateObject( teleporter ) || !teleporter.isItem || teleporter.GetTag( "HT_rechargeFuel" ) != 1 )
return;
var scroll = target;
if( !IsItemReq( scroll ))
{
- socket.SysMessage( "Target gate travel scrolls to recharge the teleporter." );
+ if( socket != null )
+ socket.SysMessage( GetDictionaryEntry( 30616, socket.language )); // Target recharge item to recharge the teleporter.
return;
}
if( !IsInPlayersPack( pUser, scroll ))
{
- socket.SysMessage( "This item must be in your backpack." );
+ if( socket != null )
+ socket.SysMessage( GetDictionaryEntry( 30617, socket.language )); // This item must be in your backpack.
return;
}
@@ -495,7 +511,8 @@ function onCallback1( socket, target )
if( cur >= chargeMax )
{
- socket.SysMessage( "The House Teleporter cannot be charged any further." );
+ if( socket != null )
+ socket.SysMessage( GetDictionaryEntry( 30618, socket.language )); // The House Teleporter cannot be charged any further.
return;
}
@@ -513,7 +530,8 @@ function onCallback1( socket, target )
cur = chargeMax;
teleporter.SetTag( "HT_Charges", cur );
- socket.SysMessage( "The Gate Travel scroll crumbles to dust as it strengthens the House Teleporter." );
+ if( socket != null )
+ socket.SysMessage( GetDictionaryEntry( 30619, socket.language )); // The recharge item crumbles to dust as it strengthens the House Teleporter.
teleporter.Refresh();
}
@@ -545,14 +563,14 @@ function onCollide( trgSock, pColliding, objCollidedWith )
if( objCollidedWith.movable != 3 )
{
if( trgSock )
- trgSock.SysMessage( "This must be locked down in a house to function." );
+ trgSock.SysMessage( GetDictionaryEntry( 30620, trgSock.language )); // This must be locked down in a house to function.
return false;
}
if( !IsInBuilding( objCollidedWith.x, objCollidedWith.y, objCollidedWith.z, objCollidedWith.worldnumber, objCollidedWith.instanceID, true ))
{
if( trgSock )
- trgSock.SysMessage( "This must be placed inside a house." );
+ trgSock.SysMessage( GetDictionaryEntry( 30621, trgSock.language )); // This must be placed inside a house.
return false;
}
@@ -560,7 +578,7 @@ function onCollide( trgSock, pColliding, objCollidedWith )
if(!CanUseHouseTeleporter(pColliding, objCollidedWith))
{
if( trgSock )
- trgSock.SysMessage( "Only the house owner and co-owners may use this teleporter." );
+ trgSock.SysMessage( GetDictionaryEntry( 30622, trgSock.language )); // Only the house owner and co-owners may use this teleporter.
return false;
}
@@ -568,7 +586,7 @@ function onCollide( trgSock, pColliding, objCollidedWith )
{
if( pColliding.dead || pColliding.criminal )
{
- trgSock.SysMessage( "You cannot use that right now." );
+ trgSock.SysMessage( GetDictionaryEntry( 30623, trgSock.language )); // You cannot use that right now.
return false;
}
}
@@ -577,7 +595,7 @@ function onCollide( trgSock, pColliding, objCollidedWith )
if( linkSer <= 0 )
{
if( trgSock )
- trgSock.SysMessage( "This teleporter is not linked." );
+ trgSock.SysMessage( GetDictionaryEntry( 30624, trgSock.language )); // This teleporter is not linked.
return false;
}
@@ -585,21 +603,21 @@ function onCollide( trgSock, pColliding, objCollidedWith )
if( !IsTeleporterItem( other ))
{
if( trgSock )
- trgSock.SysMessage( "This teleporter is not linked." );
+ trgSock.SysMessage( GetDictionaryEntry( 30624, trgSock.language )); // This teleporter is not linked.
return false;
}
if( other.movable != 3 )
{
if( trgSock )
- trgSock.SysMessage( "The destination teleporter is not properly placed." );
+ trgSock.SysMessage( GetDictionaryEntry( 30625, trgSock.language )); // The destination teleporter is not properly placed.
return false;
}
if( !IsInBuilding( other.x, other.y, other.z, other.worldnumber, other.instanceID, true ))
{
if( trgSock )
- trgSock.SysMessage( "The destination teleporter is not properly placed." );
+ trgSock.SysMessage( GetDictionaryEntry( 30625, trgSock.language )); // The destination teleporter is not properly placed.
return false;
}
@@ -612,7 +630,7 @@ function onCollide( trgSock, pColliding, objCollidedWith )
if( charge <= 0 )
{
if( trgSock )
- trgSock.SysMessage( "There are no charges left in this teleporter." );
+ trgSock.SysMessage( GetDictionaryEntry( 30626, trgSock.language )); // There are no charges left in this teleporter.
return false;
}
@@ -633,7 +651,7 @@ function onDropItemOnItem( pUser, iDropped, iOn )
if( !ValidateObject( iDropped ) || !ValidateObject( iOn ) )
return 1;
- if( !iOn.isItem || iOn.id != 0x574A )
+ if( !iOn.isItem || iOn.GetTag( "HT_rechargeFuel" ) != 1 )
return 1;
if( !iDropped.isItem || !( iDropped.id == chargeItemIDReq || iDropped.sectionID == chargeItemSectionIDReq ))
@@ -645,7 +663,7 @@ function onDropItemOnItem( pUser, iDropped, iOn )
if( cur >= chargeMax )
{
- pSocket.SysMessage( "This teleporter is fully charged." );
+ pSocket.SysMessage( GetDictionaryEntry( 30627, pSocket.language )); // This teleporter is fully charged.
return 0;
}
@@ -663,8 +681,8 @@ function onDropItemOnItem( pUser, iDropped, iOn )
/** @type { ( myChar: Character, myItem: Item, mySpeech: string, mySpeechId: number ) => void } */
function onSpeechInput( pUser, targObj, pSpeech, pSpeechID )
{
- var sock = pUser.socket;
- if( !sock )
+ var pSocket = pUser.socket;
+ if( !pSocket )
return;
if( pSpeechID != 1 )
@@ -680,12 +698,12 @@ function onSpeechInput( pUser, targObj, pSpeech, pSpeechID )
pSpeech = pSpeech.replace(/^\s+|\s+$/g, "");
if( pSpeech.length <= 0 )
{
- sock.SysMessage( GetDictionaryEntry( 9270, sock.language )); // too short / none entered
+ pSocket.SysMessage( GetDictionaryEntry( 9270, pSocket.language )); // too short / none entered
return;
}
if( pSpeech.length > 60 )
{
- sock.SysMessage( GetDictionaryEntry( 9271, sock.language )); // too long (we'll reuse)
+ pSocket.SysMessage( GetDictionaryEntry( 9271, pSocket.language )); // too long (we'll reuse)
return;
}
@@ -697,7 +715,7 @@ function onSpeechInput( pUser, targObj, pSpeech, pSpeechID )
var teleA = CalcItemFromSer( srcSer );
if( !IsTeleporterItem( teleA ))
{
- sock.SysMessage( "Teleporter not found." );
+ pSocket.SysMessage( GetDictionaryEntry( 30628, pSocket.language )); // Teleporter not found.
return;
}
@@ -705,14 +723,14 @@ function onSpeechInput( pUser, targObj, pSpeech, pSpeechID )
var linkSer = ReadIntTag( teleA, "HT_LinkSer", 0 );
if( linkSer <= 0 )
{
- sock.SysMessage( "This teleporter must be linked before it can be renamed." );
+ pSocket.SysMessage( GetDictionaryEntry( 30629, pSocket.language )); // This teleporter must be linked before it can be renamed.
return;
}
var teleB = CalcItemFromSer( linkSer );
if( !IsTeleporterItem( teleB ))
{
- sock.SysMessage( "This teleporter must be linked before it can be renamed." );
+ pSocket.SysMessage( GetDictionaryEntry( 30629, pSocket.language )); // This teleporter must be linked before it can be renamed.
return;
}
@@ -723,7 +741,7 @@ function onSpeechInput( pUser, targObj, pSpeech, pSpeechID )
teleA.Refresh();
teleB.Refresh();
- sock.SysMessage( "Teleporter name set to: " + pSpeech );
+ pSocket.SysMessage( "Teleporter name set to: " + pSpeech ); // Teleporter name set to: %s
}
/** @type { ( myObj: BaseObject, pSocket: Socket ) => string } */
From ccc84606a82953fe5532595bdbc82626034f6f62 Mon Sep 17 00:00:00 2001
From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com>
Date: Mon, 9 Feb 2026 09:11:06 -0600
Subject: [PATCH 05/12] removed underscore
---
data/dfndata/items/misc/houseteleporters.dfn | 2 +-
data/js/item/houseteleporter.js | 64 ++++++++++----------
2 files changed, 33 insertions(+), 33 deletions(-)
diff --git a/data/dfndata/items/misc/houseteleporters.dfn b/data/dfndata/items/misc/houseteleporters.dfn
index 21e6147fb..e95ed52a8 100644
--- a/data/dfndata/items/misc/houseteleporters.dfn
+++ b/data/dfndata/items/misc/houseteleporters.dfn
@@ -20,5 +20,5 @@ id=0x40BB
{
get=base_house_teleporter
id=0x574A
-custominttag=HT_rechargeFuel 1
+custominttag=rechargeFuel 1
}
\ No newline at end of file
diff --git a/data/js/item/houseteleporter.js b/data/js/item/houseteleporter.js
index 4be633f92..097bf8dd8 100644
--- a/data/js/item/houseteleporter.js
+++ b/data/js/item/houseteleporter.js
@@ -51,7 +51,7 @@ function ReadIntTag( obj, tagName, defVal )
function GetSecurityMode( teleItem )
{
- var m = ReadIntTag( teleItem, "HT_Security", 0 );
+ var m = ReadIntTag( teleItem, "Security", 0 );
if( m != 0 && m != 1 && m != 2 )
m = 0;
return m;
@@ -162,7 +162,7 @@ function onContextMenuRequest( socket, targObj )
var canShowRename = false;
if( targObj.movable == 3 && ValidateObject( targObj.multi ) && CanManageTeleporter( pUser, targObj ))
{
- var linkSerTmp = ReadIntTag( targObj, "HT_LinkSer", 0 );
+ var linkSerTmp = ReadIntTag( targObj, "LinkSer", 0 );
if( linkSerTmp > 0 )
{
var otherTmp = CalcItemFromSer( linkSerTmp );
@@ -265,7 +265,7 @@ function onContextMenuSelect( socket, targObj, popupEntry )
if( popupEntry == 0x0101 )
{
- var linkSer = ReadIntTag( targObj, "HT_LinkSer", 0 );
+ var linkSer = ReadIntTag( targObj, "LinkSer", 0 );
var linked = false;
if( linkSer > 0 )
@@ -277,7 +277,7 @@ function onContextMenuSelect( socket, targObj, popupEntry )
if( targObj.id == 0x574A )
{
- var charge = ReadIntTag( targObj, "HT_Charges", 0 );
+ var charge = ReadIntTag( targObj, "Charges", 0 );
if( charge < 0 )
charge = 0;
@@ -302,7 +302,7 @@ function onContextMenuSelect( socket, targObj, popupEntry )
return false;
}
- pUser.SetTempTag( "HT_LinkSrcSer", targObj.serial );
+ pUser.SetTempTag( "LinkSrcSer", targObj.serial );
if( socket != null )
socket.CustomTarget( 0, GetDictionaryEntry( 30601, socket.language )); // Target the other teleporter in your backpack to link.
targObj.Refresh();
@@ -311,10 +311,10 @@ function onContextMenuSelect( socket, targObj, popupEntry )
if( popupEntry == 0x0103 )
{
- if( targObj.GetTag( "HT_rechargeFuel" ) != 1 )
+ if( targObj.GetTag( "rechargeFuel" ) != 1 )
return false;
- var cur = ReadIntTag( targObj, "HT_Charges", 0 );
+ var cur = ReadIntTag( targObj, "Charges", 0 );
if( cur < 0 )
cur = 0;
@@ -325,7 +325,7 @@ function onContextMenuSelect( socket, targObj, popupEntry )
return false;
}
- pUser.SetTempTag( "HT_RechargeSer", targObj.serial );
+ pUser.SetTempTag( "RechargeSer", targObj.serial );
if( socket != null )
socket.CustomTarget( 1, GetDictionaryEntry( 30603, socket.language )); // Target recharge item in your backpack to recharge.
targObj.Refresh();
@@ -348,7 +348,7 @@ function onContextMenuSelect( socket, targObj, popupEntry )
if( nextMode > 2 )
nextMode = 0;
- targObj.SetTag( "HT_Security", nextMode );
+ targObj.SetTag( "Security", nextMode );
if( socket != null )
socket.SysMessage( "Teleporter security set to: " + SecurityName( nextMode )); // Teleporter security set to: %s
targObj.Refresh();
@@ -366,7 +366,7 @@ function onContextMenuSelect( socket, targObj, popupEntry )
}
// Must be linked
- var linkSer = ReadIntTag( targObj, "HT_LinkSer", 0 );
+ var linkSer = ReadIntTag( targObj, "LinkSer", 0 );
if( linkSer <= 0 )
{
if( socket != null )
@@ -383,7 +383,7 @@ function onContextMenuSelect( socket, targObj, popupEntry )
}
// Store the serial so onSpeechInput knows what to rename
- pUser.SetTempTag( "HT_RenameSer", targObj.serial );
+ pUser.SetTempTag( "RenameSer", targObj.serial );
// Prompt for name
pUser.SpeechInput( 1, targObj );
@@ -409,7 +409,7 @@ function onUseChecked( pUser, iUsed )
return false;
}
- pUser.SetTempTag( "HT_LinkSrcSer", iUsed.serial );
+ pUser.SetTempTag( "LinkSrcSer", iUsed.serial );
pSocket.CustomTarget( 0, GetDictionaryEntry( 30609, pSocket.language )); // Target the other teleporter in your backpack to link.
return false;
}
@@ -424,7 +424,7 @@ function onCallback0( socket, target )
if( socket.GetWord( 1 ))
return;
- var srcSer = parseInt( pUser.GetTempTag( "HT_LinkSrcSer" ), 10 );
+ var srcSer = parseInt( pUser.GetTempTag( "LinkSrcSer" ), 10 );
if( !isFinite( srcSer ) || srcSer <= 0 )
return;
@@ -466,8 +466,8 @@ function onCallback0( socket, target )
UnlinkOther( teleporterA, teleporterB.serial );
UnlinkOther( teleporterB, teleporterA.serial );
- teleporterA.SetTag( "HT_LinkSer", teleporterB.serial );
- teleporterB.SetTag( "HT_LinkSer", teleporterA.serial );
+ teleporterA.SetTag( "LinkSer", teleporterB.serial );
+ teleporterB.SetTag( "LinkSer", teleporterA.serial );
if( socket != null )
socket.SysMessage( GetDictionaryEntry( 30615, socket.language )); // Teleporters linked.
}
@@ -482,12 +482,12 @@ function onCallback1( socket, target )
if( socket.GetWord( 1 ))
return;
- var teleporterSerial = parseInt( pUser.GetTempTag( "HT_RechargeSer" ), 10 );
+ var teleporterSerial = parseInt( pUser.GetTempTag( "RechargeSer" ), 10 );
if( !isFinite( teleporterSerial ) || teleporterSerial <= 0 )
return;
var teleporter = CalcItemFromSer( teleporterSerial );
- if( !ValidateObject( teleporter ) || !teleporter.isItem || teleporter.GetTag( "HT_rechargeFuel" ) != 1 )
+ if( !ValidateObject( teleporter ) || !teleporter.isItem || teleporter.GetTag( "rechargeFuel" ) != 1 )
return;
var scroll = target;
@@ -505,7 +505,7 @@ function onCallback1( socket, target )
return;
}
- var cur = ReadIntTag( teleporter, "HT_Charges", 0 );
+ var cur = ReadIntTag( teleporter, "Charges", 0 );
if( cur < 0 )
cur = 0;
@@ -529,7 +529,7 @@ function onCallback1( socket, target )
if( cur > chargeMax )
cur = chargeMax;
- teleporter.SetTag( "HT_Charges", cur );
+ teleporter.SetTag( "Charges", cur );
if( socket != null )
socket.SysMessage( GetDictionaryEntry( 30619, socket.language )); // The recharge item crumbles to dust as it strengthens the House Teleporter.
teleporter.Refresh();
@@ -537,14 +537,14 @@ function onCallback1( socket, target )
function UnlinkOther( tile, keepSer )
{
- var old = ReadIntTag( tile, "HT_LinkSer", 0 );
- tile.SetTag( "HT_LinkSer", null );
+ var old = ReadIntTag( tile, "LinkSer", 0 );
+ tile.SetTag( "LinkSer", null );
if( old > 0 && old != keepSer )
{
var oldtele = CalcItemFromSer( old );
if( IsTeleporterItem( oldtele ))
- oldtele.SetTag( "HT_LinkSer", null );
+ oldtele.SetTag( "LinkSer", null );
}
}
@@ -591,7 +591,7 @@ function onCollide( trgSock, pColliding, objCollidedWith )
}
}
- var linkSer = ReadIntTag( objCollidedWith, "HT_LinkSer", 0 );
+ var linkSer = ReadIntTag( objCollidedWith, "LinkSer", 0 );
if( linkSer <= 0 )
{
if( trgSock )
@@ -623,7 +623,7 @@ function onCollide( trgSock, pColliding, objCollidedWith )
if( objCollidedWith.id == 0x574A )
{
- var charge = ReadIntTag( objCollidedWith, "HT_Charges", 0 );
+ var charge = ReadIntTag( objCollidedWith, "Charges", 0 );
if( charge < 0 )
charge = 0;
@@ -634,7 +634,7 @@ function onCollide( trgSock, pColliding, objCollidedWith )
return false;
}
- objCollidedWith.SetTag( "HT_Charges", charge - 1 );
+ objCollidedWith.SetTag( "Charges", charge - 1 );
}
pColliding.Teleport( other.x, other.y, other.z, other.worldnumber );
@@ -651,13 +651,13 @@ function onDropItemOnItem( pUser, iDropped, iOn )
if( !ValidateObject( iDropped ) || !ValidateObject( iOn ) )
return 1;
- if( !iOn.isItem || iOn.GetTag( "HT_rechargeFuel" ) != 1 )
+ if( !iOn.isItem || iOn.GetTag( "rechargeFuel" ) != 1 )
return 1;
if( !iDropped.isItem || !( iDropped.id == chargeItemIDReq || iDropped.sectionID == chargeItemSectionIDReq ))
return 1;
- var cur = ReadIntTag( iOn, "HT_Charges", 0 );
+ var cur = ReadIntTag( iOn, "Charges", 0 );
if( cur < 0 )
cur = 0;
@@ -673,7 +673,7 @@ function onDropItemOnItem( pUser, iDropped, iOn )
if( cur > chargeMax )
cur = chargeMax;
- iOn.SetTag( "HT_Charges", cur );
+ iOn.SetTag( "Charges", cur );
pSocket.SysMessage( "Charges: " + cur + " / " + chargeMax );
return 0;
}
@@ -708,7 +708,7 @@ function onSpeechInput( pUser, targObj, pSpeech, pSpeechID )
}
// Resolve which teleporter we are renaming
- var srcSer = parseInt( pUser.GetTempTag( "HT_RenameSer" ), 10 );
+ var srcSer = parseInt( pUser.GetTempTag( "RenameSer" ), 10 );
if( !isFinite( srcSer ) || srcSer <= 0 )
return;
@@ -720,7 +720,7 @@ function onSpeechInput( pUser, targObj, pSpeech, pSpeechID )
}
// Must still be linked
- var linkSer = ReadIntTag( teleA, "HT_LinkSer", 0 );
+ var linkSer = ReadIntTag( teleA, "LinkSer", 0 );
if( linkSer <= 0 )
{
pSocket.SysMessage( GetDictionaryEntry( 30629, pSocket.language )); // This teleporter must be linked before it can be renamed.
@@ -759,13 +759,13 @@ function onTooltip( myObj, pSocket )
if( myObj.id == 0x574A )
{
- var charge = ReadIntTag( myObj, "HT_Charges", 0 );
+ var charge = ReadIntTag( myObj, "Charges", 0 );
if( charge < 0 ) charge = 0;
if( charge > chargeMax ) charge = chargeMax;
parts.push( "Charges: " + charge + "/" + chargeMax );
}
- var linkSer = ReadIntTag( myObj, "HT_LinkSer", 0 );
+ var linkSer = ReadIntTag( myObj, "LinkSer", 0 );
var linked = false;
if( linkSer > 0 )
{
From 5594c4acce88e34346e068f3e58ae4b0bb076bc1 Mon Sep 17 00:00:00 2001
From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com>
Date: Mon, 9 Feb 2026 11:48:16 -0600
Subject: [PATCH 06/12] removed onDropItemOnItem
doesnt work on non container items
---
data/js/item/houseteleporter.js | 37 ---------------------------------
1 file changed, 37 deletions(-)
diff --git a/data/js/item/houseteleporter.js b/data/js/item/houseteleporter.js
index 097bf8dd8..1c3cfbf41 100644
--- a/data/js/item/houseteleporter.js
+++ b/data/js/item/houseteleporter.js
@@ -641,43 +641,6 @@ function onCollide( trgSock, pColliding, objCollidedWith )
return false;
}
-/** @type { ( item: Item, dropper: Character, dest: Item ) => number } */
-function onDropItemOnItem( pUser, iDropped, iOn )
-{
- var pSocket = pUser.socket;
- if( !pSocket )
- return 1;
-
- if( !ValidateObject( iDropped ) || !ValidateObject( iOn ) )
- return 1;
-
- if( !iOn.isItem || iOn.GetTag( "rechargeFuel" ) != 1 )
- return 1;
-
- if( !iDropped.isItem || !( iDropped.id == chargeItemIDReq || iDropped.sectionID == chargeItemSectionIDReq ))
- return 1;
-
- var cur = ReadIntTag( iOn, "Charges", 0 );
- if( cur < 0 )
- cur = 0;
-
- if( cur >= chargeMax )
- {
- pSocket.SysMessage( GetDictionaryEntry( 30627, pSocket.language )); // This teleporter is fully charged.
- return 0;
- }
-
- iDropped.Delete();
-
- cur += chargeAmount;
- if( cur > chargeMax )
- cur = chargeMax;
-
- iOn.SetTag( "Charges", cur );
- pSocket.SysMessage( "Charges: " + cur + " / " + chargeMax );
- return 0;
-}
-
/** @type { ( myChar: Character, myItem: Item, mySpeech: string, mySpeechId: number ) => void } */
function onSpeechInput( pUser, targObj, pSpeech, pSpeechID )
{
From 7ae1f9de3fcfc81ba58838733aa506c5bb9caf0d Mon Sep 17 00:00:00 2001
From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com>
Date: Mon, 9 Feb 2026 12:04:58 -0600
Subject: [PATCH 07/12] cleanup
cleaned up the tags
---
data/dfndata/items/misc/houseteleporters.dfn | 2 +-
data/js/item/houseteleporter.js | 56 ++++++++------------
2 files changed, 24 insertions(+), 34 deletions(-)
diff --git a/data/dfndata/items/misc/houseteleporters.dfn b/data/dfndata/items/misc/houseteleporters.dfn
index e95ed52a8..c2c3df69d 100644
--- a/data/dfndata/items/misc/houseteleporters.dfn
+++ b/data/dfndata/items/misc/houseteleporters.dfn
@@ -20,5 +20,5 @@ id=0x40BB
{
get=base_house_teleporter
id=0x574A
-custominttag=rechargeFuel 1
+custominttag=chargeable 1
}
\ No newline at end of file
diff --git a/data/js/item/houseteleporter.js b/data/js/item/houseteleporter.js
index 1c3cfbf41..64685d460 100644
--- a/data/js/item/houseteleporter.js
+++ b/data/js/item/houseteleporter.js
@@ -41,17 +41,9 @@ function IsInPlayersPack( pUser, item )
return( ValidateObject( root ) && root.isItem && root.serial == pUser.pack.serial );
}
-function ReadIntTag( obj, tagName, defVal )
-{
- var value = parseInt( obj.GetTag( tagName ), 10 );
- if( !isFinite( value ))
- value = defVal;
- return value;
-}
-
function GetSecurityMode( teleItem )
{
- var m = ReadIntTag( teleItem, "Security", 0 );
+ var m = teleItem.GetTag( "Security" );
if( m != 0 && m != 1 && m != 2 )
m = 0;
return m;
@@ -162,7 +154,7 @@ function onContextMenuRequest( socket, targObj )
var canShowRename = false;
if( targObj.movable == 3 && ValidateObject( targObj.multi ) && CanManageTeleporter( pUser, targObj ))
{
- var linkSerTmp = ReadIntTag( targObj, "LinkSer", 0 );
+ var linkSerTmp = targObj.GetTag( "LinkSer" );
if( linkSerTmp > 0 )
{
var otherTmp = CalcItemFromSer( linkSerTmp );
@@ -265,7 +257,7 @@ function onContextMenuSelect( socket, targObj, popupEntry )
if( popupEntry == 0x0101 )
{
- var linkSer = ReadIntTag( targObj, "LinkSer", 0 );
+ var linkSer = targObj.GetTag( "LinkSer" );
var linked = false;
if( linkSer > 0 )
@@ -277,7 +269,7 @@ function onContextMenuSelect( socket, targObj, popupEntry )
if( targObj.id == 0x574A )
{
- var charge = ReadIntTag( targObj, "Charges", 0 );
+ var charge = targObj.GetTag( "Charges" );
if( charge < 0 )
charge = 0;
@@ -311,10 +303,10 @@ function onContextMenuSelect( socket, targObj, popupEntry )
if( popupEntry == 0x0103 )
{
- if( targObj.GetTag( "rechargeFuel" ) != 1 )
+ if( targObj.GetTag( "chargeable" ) != 1 )
return false;
- var cur = ReadIntTag( targObj, "Charges", 0 );
+ var cur = targObj.GetTag( "Charges" );
if( cur < 0 )
cur = 0;
@@ -366,7 +358,7 @@ function onContextMenuSelect( socket, targObj, popupEntry )
}
// Must be linked
- var linkSer = ReadIntTag( targObj, "LinkSer", 0 );
+ var linkSer = targObj.GetTag( "LinkSer" );
if( linkSer <= 0 )
{
if( socket != null )
@@ -424,10 +416,7 @@ function onCallback0( socket, target )
if( socket.GetWord( 1 ))
return;
- var srcSer = parseInt( pUser.GetTempTag( "LinkSrcSer" ), 10 );
- if( !isFinite( srcSer ) || srcSer <= 0 )
- return;
-
+ var srcSer = pUser.GetTempTag( "LinkSrcSer" );
var teleporterA = CalcItemFromSer( srcSer );
var teleporterB = target;
@@ -487,7 +476,7 @@ function onCallback1( socket, target )
return;
var teleporter = CalcItemFromSer( teleporterSerial );
- if( !ValidateObject( teleporter ) || !teleporter.isItem || teleporter.GetTag( "rechargeFuel" ) != 1 )
+ if( !ValidateObject( teleporter ) || !teleporter.isItem || teleporter.GetTag( "chargeable" ) != 1 )
return;
var scroll = target;
@@ -505,7 +494,7 @@ function onCallback1( socket, target )
return;
}
- var cur = ReadIntTag( teleporter, "Charges", 0 );
+ var cur = teleporter.GetTag( "Charges");
if( cur < 0 )
cur = 0;
@@ -537,7 +526,7 @@ function onCallback1( socket, target )
function UnlinkOther( tile, keepSer )
{
- var old = ReadIntTag( tile, "LinkSer", 0 );
+ var old = tile.GetTag( "LinkSer");
tile.SetTag( "LinkSer", null );
if( old > 0 && old != keepSer )
@@ -591,7 +580,7 @@ function onCollide( trgSock, pColliding, objCollidedWith )
}
}
- var linkSer = ReadIntTag( objCollidedWith, "LinkSer", 0 );
+ var linkSer = objCollidedWith.GetTag( "LinkSer" );
if( linkSer <= 0 )
{
if( trgSock )
@@ -623,7 +612,7 @@ function onCollide( trgSock, pColliding, objCollidedWith )
if( objCollidedWith.id == 0x574A )
{
- var charge = ReadIntTag( objCollidedWith, "Charges", 0 );
+ var charge = objCollidedWith.GetTag( "Charges" );
if( charge < 0 )
charge = 0;
@@ -671,10 +660,7 @@ function onSpeechInput( pUser, targObj, pSpeech, pSpeechID )
}
// Resolve which teleporter we are renaming
- var srcSer = parseInt( pUser.GetTempTag( "RenameSer" ), 10 );
- if( !isFinite( srcSer ) || srcSer <= 0 )
- return;
-
+ var srcSer = pUser.GetTempTag( "RenameSer" );
var teleA = CalcItemFromSer( srcSer );
if( !IsTeleporterItem( teleA ))
{
@@ -683,7 +669,7 @@ function onSpeechInput( pUser, targObj, pSpeech, pSpeechID )
}
// Must still be linked
- var linkSer = ReadIntTag( teleA, "LinkSer", 0 );
+ var linkSer = teleA.GetTag( "LinkSer" );
if( linkSer <= 0 )
{
pSocket.SysMessage( GetDictionaryEntry( 30629, pSocket.language )); // This teleporter must be linked before it can be renamed.
@@ -722,13 +708,17 @@ function onTooltip( myObj, pSocket )
if( myObj.id == 0x574A )
{
- var charge = ReadIntTag( myObj, "Charges", 0 );
- if( charge < 0 ) charge = 0;
- if( charge > chargeMax ) charge = chargeMax;
+ var charge = myObj.GetTag( "Charges" );
+ if( charge < 0 )
+ charge = 0;
+
+ if( charge > chargeMax )
+ charge = chargeMax;
+
parts.push( "Charges: " + charge + "/" + chargeMax );
}
- var linkSer = ReadIntTag( myObj, "LinkSer", 0 );
+ var linkSer = myObj.GetTag( "LinkSer" );
var linked = false;
if( linkSer > 0 )
{
From c498f9a2cfd8ca29cb0ef1a316a9b1ddf3d940c4 Mon Sep 17 00:00:00 2001
From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com>
Date: Mon, 9 Feb 2026 12:54:15 -0600
Subject: [PATCH 08/12] code cleanup
---
data/js/item/houseteleporter.js | 124 ++++++++++++++++++--------------
1 file changed, 72 insertions(+), 52 deletions(-)
diff --git a/data/js/item/houseteleporter.js b/data/js/item/houseteleporter.js
index 64685d460..42d20f91e 100644
--- a/data/js/item/houseteleporter.js
+++ b/data/js/item/houseteleporter.js
@@ -27,28 +27,6 @@ function IsTeleporterItem( item )
return false;
}
-function IsItemReq( item )
-{
- return( ValidateObject(item) && item.isItem && ( item.id == chargeItemIDReq || item.sectionID == chargeItemSectionIDReq ));
-}
-
-function IsInPlayersPack( pUser, item )
-{
- if( !ValidateObject( pUser ) || !ValidateObject( pUser.pack ) || !IsTeleporterItem( item ) && !IsItemReq( item ))
- return false;
-
- var root = FindRootContainer( item, 0 );
- return( ValidateObject( root ) && root.isItem && root.serial == pUser.pack.serial );
-}
-
-function GetSecurityMode( teleItem )
-{
- var m = teleItem.GetTag( "Security" );
- if( m != 0 && m != 1 && m != 2 )
- m = 0;
- return m;
-}
-
function SecurityName( mode )
{
if( mode == 1 )
@@ -68,19 +46,19 @@ function CanManageTeleporter( pChar, teleItem )
if( pChar.isGM )
return true;
- var m = teleItem.multi;
- if( !ValidateObject( m ))
+ var multiHouse = teleItem.multi;
+ if( !ValidateObject( multiHouse ))
return false;
- if( m.IsOwner( pChar ))
+ if( multiHouse.IsOwner( pChar ))
return true;
- if( m.IsOnOwnerList( pChar ))
+ if( multiHouse.IsOnOwnerList( pChar ))
return true;
- if( coOwnHousesOnSameAccount && ValidateObject( m.owner ))
+ if( coOwnHousesOnSameAccount && ValidateObject( multiHouse.owner ))
{
- if( m.owner.accountNum == pChar.accountNum )
+ if( multiHouse.owner.accountNum == pChar.accountNum )
return true;
}
@@ -96,29 +74,31 @@ function CanUseHouseTeleporter( pChar, teleItem )
if( pChar.isGM )
return true;
- var m = teleItem.multi;
- if( !ValidateObject( m ))
+ var multiHouse = teleItem.multi;
+ if( !ValidateObject( multiHouse ))
return false;
- var mode = GetSecurityMode( teleItem );
+ var mode = teleItem.GetTag( "Security" );
+ if( mode != 0 && mode != 1 && mode != 2 )
+ mode = 0;
// Owner/coowner always allowed in all modes
- if( m.IsOwner( pChar ))
+ if( multiHouse.IsOwner( pChar ))
return true;
- if( m.IsOnOwnerList( pChar ))
+ if( multiHouse.IsOnOwnerList( pChar ))
return true;
- if( coOwnHousesOnSameAccount && ValidateObject(m.owner ))
+ if( coOwnHousesOnSameAccount && ValidateObject(multiHouse.owner ))
{
- if( m.owner.accountNum == pChar.accountNum )
+ if( multiHouse.owner.accountNum == pChar.accountNum )
return true;
}
// Friends mode
if( mode == 1 )
{
- if(m.IsOnFriendList( pChar ))
+ if( multiHouse.IsOnFriendList( pChar ))
return true;
return false;
}
@@ -143,7 +123,12 @@ function onContextMenuRequest( socket, targObj )
if( !IsTeleporterItem( targObj ))
return true;
- var inPack = IsInPlayersPack( pUser, targObj );
+ var inPack = false;
+ if( ValidateObject( pUser ) && ValidateObject( pUser.pack ))
+ {
+ var root0 = FindRootContainer( targObj, 0 );
+ inPack = ( ValidateObject( root0 ) && root0.isItem && root0.serial == pUser.pack.serial );
+ }
// Show "Set Security" only when it's a house-placed (locked down) teleporter
var canShowSecurity = false;
@@ -287,10 +272,17 @@ function onContextMenuSelect( socket, targObj, popupEntry )
if( popupEntry == 0x0102 )
{
- if( !IsInPlayersPack( pUser, targObj ))
+ var inPackLink = false;
+ if( ValidateObject( pUser.pack ))
{
- if( socket != null )
- socket.SysMessage( GetDictionaryEntry( 30600, socket.language )); // This must be in your backpack to link it.
+ var root1 = FindRootContainer( targObj, 0 );
+ inPackLink = ( ValidateObject( root1 ) && root1.isItem && root1.serial == pUser.pack.serial );
+ }
+
+ if( !inPackLink )
+ {
+ if (socket != null)
+ socket.SysMessage( GetDictionaryEntry( 30600, socket.language ));
return false;
}
@@ -335,7 +327,9 @@ function onContextMenuSelect( socket, targObj, popupEntry )
return false;
}
- var curMode = GetSecurityMode( targObj );
+ var curMode = targObj.GetTag( "Security" );
+ if( curMode != 0 && curMode != 1 && curMode != 2 )
+ curMode = 0;
var nextMode = curMode + 1;
if( nextMode > 2 )
nextMode = 0;
@@ -395,7 +389,14 @@ function onUseChecked( pUser, iUsed )
if( !IsTeleporterItem( iUsed ))
return false;
- if( !IsInPlayersPack( pUser, iUsed ))
+ var inPackUse = false;
+ if( ValidateObject( pUser ) && ValidateObject( pUser.pack ))
+ {
+ var root2 = FindRootContainer( iUsed, 0 );
+ inPackUse = ( ValidateObject( root2 ) && root2.isItem && root2.serial == pUser.pack.serial );
+ }
+
+ if( !inPackUse )
{
pSocket.SysMessage( GetDictionaryEntry( 30608, pSocket.language )); // To link, both teleporters must be in your backpack.
return false;
@@ -445,7 +446,19 @@ function onCallback0( socket, target )
return;
}
- if( !IsInPlayersPack( pUser, teleporterA ) || !IsInPlayersPack( pUser, teleporterB ))
+ var aInPack = false;
+ var bInPack = false;
+
+ if( ValidateObject( pUser ) && ValidateObject( pUser.pack ))
+ {
+ var rootA = FindRootContainer( teleporterA, 0 );
+ var rootB = FindRootContainer( teleporterB, 0 );
+
+ aInPack = ( ValidateObject( rootA ) && rootA.isItem && rootA.serial == pUser.pack.serial );
+ bInPack = ( ValidateObject( rootB ) && rootB.isItem && rootB.serial == pUser.pack.serial );
+ }
+
+ if( !aInPack || !bInPack )
{
if( socket != null )
socket.SysMessage( GetDictionaryEntry( 30614, socket.language )); // Both teleporters must be in your backpack to link.
@@ -471,23 +484,27 @@ function onCallback1( socket, target )
if( socket.GetWord( 1 ))
return;
- var teleporterSerial = parseInt( pUser.GetTempTag( "RechargeSer" ), 10 );
- if( !isFinite( teleporterSerial ) || teleporterSerial <= 0 )
- return;
-
+ var teleporterSerial = pUser.GetTempTag( "RechargeSer" );
var teleporter = CalcItemFromSer( teleporterSerial );
if( !ValidateObject( teleporter ) || !teleporter.isItem || teleporter.GetTag( "chargeable" ) != 1 )
return;
var scroll = target;
- if( !IsItemReq( scroll ))
+ if( !( ValidateObject( scroll ) && scroll.isItem && ( scroll.id == chargeItemIDReq || scroll.sectionID == chargeItemSectionIDReq )))
{
if( socket != null )
- socket.SysMessage( GetDictionaryEntry( 30616, socket.language )); // Target recharge item to recharge the teleporter.
+ socket.SysMessage(GetDictionaryEntry( 30616, socket.language ));
return;
}
- if( !IsInPlayersPack( pUser, scroll ))
+ var scrollInPack = false;
+ if( ValidateObject( pUser ) && ValidateObject( pUser.pack ))
+ {
+ var root3 = FindRootContainer( scroll, 0 );
+ scrollInPack = ( ValidateObject( root3 ) && root3.isItem && root3.serial == pUser.pack.serial );
+ }
+
+ if( !scrollInPack )
{
if( socket != null )
socket.SysMessage( GetDictionaryEntry( 30617, socket.language )); // This item must be in your backpack.
@@ -703,7 +720,10 @@ function onTooltip( myObj, pSocket )
return "";
var parts = [];
- var secMode = GetSecurityMode( myObj );
+ var secMode = myObj.GetTag( "Security" );
+ if( secMode != 0 && secMode != 1 && secMode != 2 )
+ secMode = 0;
+
parts.push( "Security: " + SecurityName( secMode ));
if( myObj.id == 0x574A )
@@ -729,4 +749,4 @@ function onTooltip( myObj, pSocket )
parts.push( "Link: " + ( linked ? "Linked" : "Unlinked" ));
return parts.join( "
" );
-}
+}
\ No newline at end of file
From 0e9d2c83179a5db51987061323808ddcedf062a2 Mon Sep 17 00:00:00 2001
From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com>
Date: Mon, 9 Feb 2026 22:03:47 -0600
Subject: [PATCH 09/12] Update houseteleporter.js
---
data/js/item/houseteleporter.js | 22 ++++++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)
diff --git a/data/js/item/houseteleporter.js b/data/js/item/houseteleporter.js
index 42d20f91e..07f84b2f0 100644
--- a/data/js/item/houseteleporter.js
+++ b/data/js/item/houseteleporter.js
@@ -515,23 +515,37 @@ function onCallback1( socket, target )
if( cur < 0 )
cur = 0;
- if( cur >= chargeMax )
+ var stackAmt = ( scroll.amount );
+ if( stackAmt < 1 )
+ stackAmt = 1;
+
+ var remaining = chargeMax - cur;
+ if( remaining <= 0 )
{
if( socket != null )
socket.SysMessage( GetDictionaryEntry( 30618, socket.language )); // The House Teleporter cannot be charged any further.
return;
}
- if(( scroll.amount|0 ) > 1 )
+ var needScrolls = Math.ceil( remaining / chargeAmount );
+ var useScrolls = needScrolls;
+
+ if( useScrolls > stackAmt )
+ useScrolls = stackAmt;
+ if( useScrolls < 1 )
+ useScrolls = 1;
+
+ // consume that many from the stack
+ if( stackAmt > useScrolls )
{
- scroll.amount = ( scroll.amount|0 ) - 1;
+ scroll.amount = stackAmt - useScrolls;
}
else
{
scroll.Delete();
}
- cur += chargeAmount;
+ cur += ( useScrolls * chargeAmount );
if( cur > chargeMax )
cur = chargeMax;
From 5b173942d85bbc67146f90d92e1804f344d77de5 Mon Sep 17 00:00:00 2001
From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com>
Date: Sat, 14 Feb 2026 20:00:39 -0600
Subject: [PATCH 10/12] cleanup
Changed isinbuilding to check isinmulti and added couple socket checks
---
data/js/item/houseteleporter.js | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/data/js/item/houseteleporter.js b/data/js/item/houseteleporter.js
index 07f84b2f0..f04d58dc2 100644
--- a/data/js/item/houseteleporter.js
+++ b/data/js/item/houseteleporter.js
@@ -9,9 +9,10 @@ const teleporterIDReq = [0x40BB, 0x574A];
const teleporterSectionIDReq = "house_teleporter";
const coOwnHousesOnSameAccount = GetServerSetting( "CoOwnHousesOnSameAccount" );
+/** @type { ( item: Item | BaseObject ) => boolean } */
function IsTeleporterItem( item )
{
- if( !ValidateObject( item ) || !item.isItem )
+ if( !item || !item.isItem )
return false;
// allow by sectionid
@@ -27,6 +28,7 @@ function IsTeleporterItem( item )
return false;
}
+/** @type { ( mode: number ) => string } */
function SecurityName( mode )
{
if( mode == 1 )
@@ -36,6 +38,7 @@ function SecurityName( mode )
return "Owner/Co-Owners";
}
+/** @type { ( pChar: Character, teleItem: Item ) => boolean } */
function CanManageTeleporter( pChar, teleItem )
{
// Who can change security setting?
@@ -65,6 +68,7 @@ function CanManageTeleporter( pChar, teleItem )
return false;
}
+/** @type { ( pChar: Character, teleItem: Item ) => boolean } */
function CanUseHouseTeleporter( pChar, teleItem )
{
// Enforces configured security
@@ -383,7 +387,7 @@ function onContextMenuSelect( socket, targObj, popupEntry )
function onUseChecked( pUser, iUsed )
{
var pSocket = pUser.socket;
- if( !pSocket )
+ if( pSocket == null )
return false;
if( !IsTeleporterItem( iUsed ))
@@ -555,6 +559,7 @@ function onCallback1( socket, target )
teleporter.Refresh();
}
+/** @type { ( tile: Item, keepSer: number ) => void } */
function UnlinkOther( tile, keepSer )
{
var old = tile.GetTag( "LinkSer");
@@ -587,10 +592,13 @@ function onCollide( trgSock, pColliding, objCollidedWith )
return false;
}
- if( !IsInBuilding( objCollidedWith.x, objCollidedWith.y, objCollidedWith.z, objCollidedWith.worldnumber, objCollidedWith.instanceID, true ))
+ var iMulti = FindMulti( objCollidedWith.x, objCollidedWith.y, objCollidedWith.z, objCollidedWith.worldnumber, objCollidedWith.instanceID );
+ var insideHouse = ( ValidateObject( iMulti ) && iMulti.IsInMulti( objCollidedWith ) );
+
+ if( !insideHouse )
{
if( trgSock )
- trgSock.SysMessage( GetDictionaryEntry( 30621, trgSock.language )); // This must be placed inside a house.
+ trgSock.SysMessage( GetDictionaryEntry( 30621, trgSock.language ) ); // This must be placed inside a house.
return false;
}
From d3091f41e5351b47e794b6f9d5ec372cfa287fad Mon Sep 17 00:00:00 2001
From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com>
Date: Wed, 18 Feb 2026 16:49:03 -0600
Subject: [PATCH 11/12] couple small changes
---
data/js/item/houseteleporter.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/data/js/item/houseteleporter.js b/data/js/item/houseteleporter.js
index f04d58dc2..566208dc6 100644
--- a/data/js/item/houseteleporter.js
+++ b/data/js/item/houseteleporter.js
@@ -593,7 +593,7 @@ function onCollide( trgSock, pColliding, objCollidedWith )
}
var iMulti = FindMulti( objCollidedWith.x, objCollidedWith.y, objCollidedWith.z, objCollidedWith.worldnumber, objCollidedWith.instanceID );
- var insideHouse = ( ValidateObject( iMulti ) && iMulti.IsInMulti( objCollidedWith ) );
+ var insideHouse = ( ValidateObject( iMulti ) && iMulti.IsInMulti( objCollidedWith ));
if( !insideHouse )
{
@@ -603,7 +603,7 @@ function onCollide( trgSock, pColliding, objCollidedWith )
}
// SECURITY: Owner + Co-Owners only
- if(!CanUseHouseTeleporter(pColliding, objCollidedWith))
+ if( !CanUseHouseTeleporter( pColliding, objCollidedWith ))
{
if( trgSock )
trgSock.SysMessage( GetDictionaryEntry( 30622, trgSock.language )); // Only the house owner and co-owners may use this teleporter.
@@ -649,7 +649,7 @@ function onCollide( trgSock, pColliding, objCollidedWith )
return false;
}
- if( objCollidedWith.id == 0x574A )
+ if( objCollidedWith.GetTag( "chargeable" ) == 1 )
{
var charge = objCollidedWith.GetTag( "Charges" );
if( charge < 0 )
From 1d58ec76e789c9afa4a37084acfe98d11bb85660 Mon Sep 17 00:00:00 2001
From: Dragon Slayer <85514184+DragonSlayer62@users.noreply.github.com>
Date: Thu, 5 Mar 2026 20:36:07 -0600
Subject: [PATCH 12/12] Update houseteleporter.js
---
data/js/item/houseteleporter.js | 359 +++++++++++++++++---------------
1 file changed, 196 insertions(+), 163 deletions(-)
diff --git a/data/js/item/houseteleporter.js b/data/js/item/houseteleporter.js
index 566208dc6..bc9572894 100644
--- a/data/js/item/houseteleporter.js
+++ b/data/js/item/houseteleporter.js
@@ -12,14 +12,12 @@ const coOwnHousesOnSameAccount = GetServerSetting( "CoOwnHousesOnSameAccount" );
/** @type { ( item: Item | BaseObject ) => boolean } */
function IsTeleporterItem( item )
{
- if( !item || !item.isItem )
+ if( !item || !item.isItem )
return false;
- // allow by sectionid
if( item.sectionID == teleporterSectionIDReq )
return true;
- // allow by id list
for( var i = 0; i < teleporterIDReq.length; i++ )
{
if( item.id == teleporterIDReq[i] )
@@ -28,6 +26,97 @@ function IsTeleporterItem( item )
return false;
}
+/** @type { ( teleItem: Item ) => Item | null } */
+function GetLinkedTeleporter( teleItem )
+{
+ if( !IsTeleporterItem( teleItem ))
+ return null;
+
+ var linkSer = teleItem.GetTag( "LinkSer" );
+ if( linkSer <= 0 )
+ return null;
+
+ var other = CalcItemFromSer( linkSer );
+ if( !IsTeleporterItem( other ))
+ return null;
+
+ return other;
+}
+
+/** @type { ( teleItem: Item ) => number } */
+function GetSharedCharges( teleItem )
+{
+ if( !IsTeleporterItem( teleItem ))
+ return 0;
+
+ var cur = teleItem.GetTag( "Charges" );
+ if( cur < 0 )
+ cur = 0;
+
+ var other = GetLinkedTeleporter( teleItem );
+ if( IsTeleporterItem( other ))
+ {
+ var otherCur = other.GetTag( "Charges" );
+ if( otherCur < 0 )
+ otherCur = 0;
+
+ if( otherCur > cur )
+ cur = otherCur;
+ }
+
+ if( cur > chargeMax )
+ cur = chargeMax;
+
+ return cur;
+}
+
+/** @type { ( teleItem: Item, newValue: number ) => void } */
+function SetSharedCharges( teleItem, newValue )
+{
+ if( !IsTeleporterItem( teleItem ))
+ return;
+
+ if( newValue < 0 )
+ newValue = 0;
+
+ if( newValue > chargeMax )
+ newValue = chargeMax;
+
+ teleItem.SetTag( "Charges", newValue );
+ teleItem.Refresh();
+
+ var other = GetLinkedTeleporter( teleItem );
+ if( IsTeleporterItem( other ))
+ {
+ other.SetTag( "Charges", newValue );
+ other.Refresh();
+ }
+}
+
+/** @type { ( teleporterA: Item, teleporterB: Item ) => void } */
+function SyncLinkedChargesOnLink( teleporterA, teleporterB )
+{
+ if( !IsTeleporterItem( teleporterA ) || !IsTeleporterItem( teleporterB ))
+ return;
+
+ var aCharge = teleporterA.GetTag( "Charges" );
+ var bCharge = teleporterB.GetTag( "Charges" );
+
+ if( aCharge < 0 )
+ aCharge = 0;
+ if( bCharge < 0 )
+ bCharge = 0;
+
+ var shared = aCharge + bCharge;
+ if( shared > chargeMax )
+ shared = chargeMax;
+
+ teleporterA.SetTag( "Charges", shared );
+ teleporterB.SetTag( "Charges", shared );
+ teleporterA.Refresh();
+ teleporterB.Refresh();
+}
+
/** @type { ( mode: number ) => string } */
function SecurityName( mode )
{
@@ -41,8 +130,6 @@ function SecurityName( mode )
/** @type { ( pChar: Character, teleItem: Item ) => boolean } */
function CanManageTeleporter( pChar, teleItem )
{
- // Who can change security setting?
- // (GM OR owner OR co-owner OR same-account-as-owner if enabled)
if( !ValidateObject( pChar ) || !ValidateObject( teleItem ))
return false;
@@ -71,7 +158,6 @@ function CanManageTeleporter( pChar, teleItem )
/** @type { ( pChar: Character, teleItem: Item ) => boolean } */
function CanUseHouseTeleporter( pChar, teleItem )
{
- // Enforces configured security
if( !ValidateObject( pChar ) || !ValidateObject( teleItem ))
return false;
@@ -86,20 +172,18 @@ function CanUseHouseTeleporter( pChar, teleItem )
if( mode != 0 && mode != 1 && mode != 2 )
mode = 0;
- // Owner/coowner always allowed in all modes
if( multiHouse.IsOwner( pChar ))
return true;
if( multiHouse.IsOnOwnerList( pChar ))
return true;
- if( coOwnHousesOnSameAccount && ValidateObject(multiHouse.owner ))
+ if( coOwnHousesOnSameAccount && ValidateObject( multiHouse.owner ))
{
if( multiHouse.owner.accountNum == pChar.accountNum )
return true;
}
- // Friends mode
if( mode == 1 )
{
if( multiHouse.IsOnFriendList( pChar ))
@@ -107,13 +191,9 @@ function CanUseHouseTeleporter( pChar, teleItem )
return false;
}
- // Anyone mode
if( mode == 2 )
- {
return true;
- }
- // Owner/Co-Owners only
return false;
}
@@ -128,18 +208,16 @@ function onContextMenuRequest( socket, targObj )
return true;
var inPack = false;
- if( ValidateObject( pUser ) && ValidateObject( pUser.pack ))
+ if( ValidateObject( pUser.pack ))
{
var root0 = FindRootContainer( targObj, 0 );
inPack = ( ValidateObject( root0 ) && root0.isItem && root0.serial == pUser.pack.serial );
}
- // Show "Set Security" only when it's a house-placed (locked down) teleporter
var canShowSecurity = false;
if( targObj.movable == 3 && ValidateObject( targObj.multi ) && CanManageTeleporter( pUser, targObj ))
canShowSecurity = true;
- // Show "Rename" only when locked down, in house, manageable, AND linked
var canShowRename = false;
if( targObj.movable == 3 && ValidateObject( targObj.multi ) && CanManageTeleporter( pUser, targObj ))
{
@@ -152,22 +230,18 @@ function onContextMenuRequest( socket, targObj )
}
}
- var numEntries = 1; // Status
+ var numEntries = 1;
if( inPack )
- {
numEntries++;
- }
- if( targObj.id == 0x574A )
- {
+ if( targObj.id == 0x574A && targObj.GetTag( "chargeable" ) == 1 )
numEntries++;
- }
if( canShowSecurity )
numEntries++;
if( canShowRename )
- numEntries++;
+ numEntries++;
var offset = 12;
var toSend = new Packet();
@@ -176,19 +250,17 @@ function onContextMenuRequest( socket, targObj )
toSend.ReserveSize( packetLen );
toSend.WriteByte( 0, 0xBF );
toSend.WriteShort( 1, packetLen );
- toSend.WriteShort( 3, 0x14 ); // subCmd
- toSend.WriteShort( 5, 0x0001 ); // 2D client
+ toSend.WriteShort( 3, 0x14 );
+ toSend.WriteShort( 5, 0x0001 );
toSend.WriteLong( 7, targObj.serial );
toSend.WriteByte( 11, numEntries );
- // Entry: Status
toSend.WriteShort( offset, 0x0101 );
toSend.WriteShort( offset += 2, 2140 );
toSend.WriteShort( offset += 2, 0x0020 );
toSend.WriteShort( offset += 2, 0x03E0 );
offset += 2;
- // Entry: Link (only if in backpack)
if( inPack )
{
toSend.WriteShort( offset, 0x0102 );
@@ -198,8 +270,7 @@ function onContextMenuRequest( socket, targObj )
offset += 2;
}
- // Entry: Recharge (pink only)
- if( targObj.id == 0x574A )
+ if( targObj.id == 0x574A && targObj.GetTag( "chargeable" ) == 1 )
{
toSend.WriteShort( offset, 0x0103 );
toSend.WriteShort( offset += 2, 5042 );
@@ -208,7 +279,6 @@ function onContextMenuRequest( socket, targObj )
offset += 2;
}
- // Set Security
if( canShowSecurity )
{
toSend.WriteShort( offset, 0x0104 );
@@ -218,11 +288,10 @@ function onContextMenuRequest( socket, targObj )
offset += 2;
}
- // Rename (linked + placed only)
if( canShowRename )
{
toSend.WriteShort( offset, 0x0105 );
- toSend.WriteShort( offset += 2, 404 ); // cliloc for name
+ toSend.WriteShort( offset += 2, 404 );
toSend.WriteShort( offset += 2, 0x0020 );
toSend.WriteShort( offset += 2, 0x03E0 );
offset += 2;
@@ -247,7 +316,6 @@ function onContextMenuSelect( socket, targObj, popupEntry )
if( popupEntry == 0x0101 )
{
var linkSer = targObj.GetTag( "LinkSer" );
-
var linked = false;
if( linkSer > 0 )
{
@@ -256,15 +324,9 @@ function onContextMenuSelect( socket, targObj, popupEntry )
linked = true;
}
- if( targObj.id == 0x574A )
+ if( targObj.id == 0x574A && targObj.GetTag( "chargeable" ) == 1 )
{
- var charge = targObj.GetTag( "Charges" );
- if( charge < 0 )
- charge = 0;
-
- if( charge > chargeMax )
- charge = chargeMax;
-
+ var charge = GetSharedCharges( targObj );
socket.SysMessage( "Teleporter: " + ( linked ? "Linked" : "Unlinked" ) + " | Charges: " + charge + "/" + chargeMax );
}
else
@@ -285,14 +347,12 @@ function onContextMenuSelect( socket, targObj, popupEntry )
if( !inPackLink )
{
- if (socket != null)
- socket.SysMessage( GetDictionaryEntry( 30600, socket.language ));
+ socket.SysMessage( GetDictionaryEntry( 30600, socket.language ));
return false;
}
pUser.SetTempTag( "LinkSrcSer", targObj.serial );
- if( socket != null )
- socket.CustomTarget( 0, GetDictionaryEntry( 30601, socket.language )); // Target the other teleporter in your backpack to link.
+ socket.CustomTarget( 0, GetDictionaryEntry( 30601, socket.language )); // Target the other teleporter in your backpack to link.
targObj.Refresh();
return false;
}
@@ -302,80 +362,64 @@ function onContextMenuSelect( socket, targObj, popupEntry )
if( targObj.GetTag( "chargeable" ) != 1 )
return false;
- var cur = targObj.GetTag( "Charges" );
- if( cur < 0 )
- cur = 0;
-
+ var cur = GetSharedCharges( targObj );
if( cur >= chargeMax )
{
- if( socket != null )
- socket.SysMessage( GetDictionaryEntry( 30602, socket.language ));
+ socket.SysMessage( GetDictionaryEntry( 30602, socket.language ));
return false;
}
pUser.SetTempTag( "RechargeSer", targObj.serial );
- if( socket != null )
- socket.CustomTarget( 1, GetDictionaryEntry( 30603, socket.language )); // Target recharge item in your backpack to recharge.
+ socket.CustomTarget( 1, GetDictionaryEntry( 30603, socket.language )); // Target recharge item in your backpack to recharge.
targObj.Refresh();
return false;
}
-
if( popupEntry == 0x0104 )
{
- // Must be allowed to manage
if( !( targObj.movable == 3 && ValidateObject( targObj.multi ) && CanManageTeleporter( pUser, targObj )))
{
- if( socket != null )
- socket.SysMessage( GetDictionaryEntry( 30604, socket.language )); // You cannot change this teleporter's security.
+ socket.SysMessage( GetDictionaryEntry( 30604, socket.language )); // You cannot change this teleporter's security
return false;
}
var curMode = targObj.GetTag( "Security" );
if( curMode != 0 && curMode != 1 && curMode != 2 )
curMode = 0;
+
var nextMode = curMode + 1;
if( nextMode > 2 )
nextMode = 0;
targObj.SetTag( "Security", nextMode );
- if( socket != null )
- socket.SysMessage( "Teleporter security set to: " + SecurityName( nextMode )); // Teleporter security set to: %s
+ socket.SysMessage( "Teleporter security set to: " + SecurityName( nextMode )); // Teleporter security set to: %s
targObj.Refresh();
return false;
}
if( popupEntry == 0x0105 )
{
- // Must be placed + manageable
- if(!( targObj.movable == 3 && ValidateObject( targObj.multi ) && CanManageTeleporter( pUser, targObj )))
+ if( !( targObj.movable == 3 && ValidateObject( targObj.multi ) && CanManageTeleporter( pUser, targObj )))
{
- if( socket != null )
- socket.SysMessage( GetDictionaryEntry( 30606, socket.language )); // You cannot rename this teleporter.
+ socket.SysMessage( GetDictionaryEntry( 30606, socket.language )); // You cannot rename this teleporter.
return false;
}
- // Must be linked
- var linkSer = targObj.GetTag( "LinkSer" );
- if( linkSer <= 0 )
+ var linkSer2 = targObj.GetTag( "LinkSer" );
+ if( linkSer2 <= 0 )
{
- if( socket != null )
- socket.SysMessage( GetDictionaryEntry( 30607, socket.language )); // This teleporter must be linked before it can be renamed.
+ socket.SysMessage( GetDictionaryEntry( 30607, socket.language )); // This teleporter must be linked before it can be renamed.
return false;
}
- var other = CalcItemFromSer( linkSer );
- if( !IsTeleporterItem( other ))
+ var other2 = CalcItemFromSer( linkSer2 );
+ if( !IsTeleporterItem( other2 ))
{
- if( socket != null )
- socket.SysMessage( GetDictionaryEntry( 30607, socket.language )); // This teleporter must be linked before it can be renamed.
+ socket.SysMessage( GetDictionaryEntry( 30607, socket.language )); // This teleporter must be linked before it can be renamed.
return false;
}
- // Store the serial so onSpeechInput knows what to rename
pUser.SetTempTag( "RenameSer", targObj.serial );
-
- // Prompt for name
pUser.SpeechInput( 1, targObj );
return false;
}
@@ -387,14 +431,14 @@ function onContextMenuSelect( socket, targObj, popupEntry )
function onUseChecked( pUser, iUsed )
{
var pSocket = pUser.socket;
- if( pSocket == null )
+ if( pSocket == null )
return false;
if( !IsTeleporterItem( iUsed ))
return false;
var inPackUse = false;
- if( ValidateObject( pUser ) && ValidateObject( pUser.pack ))
+ if( ValidateObject( pUser.pack ))
{
var root2 = FindRootContainer( iUsed, 0 );
inPackUse = ( ValidateObject( root2 ) && root2.isItem && root2.serial == pUser.pack.serial );
@@ -427,33 +471,29 @@ function onCallback0( socket, target )
if( !IsTeleporterItem( teleporterA ))
{
- if( socket != null )
- socket.SysMessage( GetDictionaryEntry( 30610, socket.language )); // Source teleporter not found.
+ socket.SysMessage( GetDictionaryEntry( 30610, socket.language )); // Source teleporter not found.
return;
}
if( !IsTeleporterItem( teleporterB ))
{
- if( socket != null )
- socket.SysMessage( GetDictionaryEntry( 30611, socket.language )); // That is not a house teleporter.
+ socket.SysMessage( GetDictionaryEntry( 30611, socket.language )); // That is not a house teleporter.
return;
}
if( teleporterA.serial == teleporterB.serial )
{
- if( socket != null )
socket.SysMessage( GetDictionaryEntry( 30612, socket.language )); // You must target the other teleporter.
return;
}
if( teleporterA.id != teleporterB.id )
{
- if( socket != null )
- socket.SysMessage( GetDictionaryEntry( 30613, socket.language )); // These teleporters are different types and cannot be linked.
+ socket.SysMessage( GetDictionaryEntry( 30613, socket.language )); // These teleporters are different types and cannot be linked.
return;
}
var aInPack = false;
var bInPack = false;
- if( ValidateObject( pUser ) && ValidateObject( pUser.pack ))
+ if( ValidateObject( pUser.pack ))
{
var rootA = FindRootContainer( teleporterA, 0 );
var rootB = FindRootContainer( teleporterB, 0 );
@@ -464,8 +504,7 @@ function onCallback0( socket, target )
if( !aInPack || !bInPack )
{
- if( socket != null )
- socket.SysMessage( GetDictionaryEntry( 30614, socket.language )); // Both teleporters must be in your backpack to link.
+ socket.SysMessage( GetDictionaryEntry( 30614, socket.language )); // Both teleporters must be in your backpack to link.
return;
}
@@ -474,8 +513,12 @@ function onCallback0( socket, target )
teleporterA.SetTag( "LinkSer", teleporterB.serial );
teleporterB.SetTag( "LinkSer", teleporterA.serial );
- if( socket != null )
- socket.SysMessage( GetDictionaryEntry( 30615, socket.language )); // Teleporters linked.
+
+ // Make both share the same charge pool immediately
+ if( teleporterA.GetTag( "chargeable" ) == 1 && teleporterB.GetTag( "chargeable" ) == 1 )
+ SyncLinkedChargesOnLink( teleporterA, teleporterB );
+
+ socket.SysMessage( GetDictionaryEntry( 30615, socket.language )); // Teleporters linked.
}
/** @type { ( tSock: Socket, target: Character | Item | null ) => void } */
@@ -496,13 +539,12 @@ function onCallback1( socket, target )
var scroll = target;
if( !( ValidateObject( scroll ) && scroll.isItem && ( scroll.id == chargeItemIDReq || scroll.sectionID == chargeItemSectionIDReq )))
{
- if( socket != null )
- socket.SysMessage(GetDictionaryEntry( 30616, socket.language ));
+ socket.SysMessage( GetDictionaryEntry( 30616, socket.language ));
return;
}
var scrollInPack = false;
- if( ValidateObject( pUser ) && ValidateObject( pUser.pack ))
+ if( ValidateObject( pUser.pack ))
{
var root3 = FindRootContainer( scroll, 0 );
scrollInPack = ( ValidateObject( root3 ) && root3.isItem && root3.serial == pUser.pack.serial );
@@ -510,24 +552,19 @@ function onCallback1( socket, target )
if( !scrollInPack )
{
- if( socket != null )
- socket.SysMessage( GetDictionaryEntry( 30617, socket.language )); // This item must be in your backpack.
+ socket.SysMessage( GetDictionaryEntry( 30617, socket.language ));// This item must be in your backpack.
return;
}
- var cur = teleporter.GetTag( "Charges");
- if( cur < 0 )
- cur = 0;
-
- var stackAmt = ( scroll.amount );
+ var cur = GetSharedCharges( teleporter );
+ var stackAmt = scroll.amount;
if( stackAmt < 1 )
stackAmt = 1;
var remaining = chargeMax - cur;
if( remaining <= 0 )
{
- if( socket != null )
- socket.SysMessage( GetDictionaryEntry( 30618, socket.language )); // The House Teleporter cannot be charged any further.
+ socket.SysMessage( GetDictionaryEntry( 30618, socket.language ));// The House Teleporter cannot be charged any further.
return;
}
@@ -539,37 +576,39 @@ function onCallback1( socket, target )
if( useScrolls < 1 )
useScrolls = 1;
- // consume that many from the stack
if( stackAmt > useScrolls )
- {
scroll.amount = stackAmt - useScrolls;
- }
else
- {
scroll.Delete();
- }
cur += ( useScrolls * chargeAmount );
if( cur > chargeMax )
cur = chargeMax;
- teleporter.SetTag( "Charges", cur );
- if( socket != null )
- socket.SysMessage( GetDictionaryEntry( 30619, socket.language )); // The recharge item crumbles to dust as it strengthens the House Teleporter.
- teleporter.Refresh();
+ SetSharedCharges( teleporter, cur );
+
+ socket.SysMessage( GetDictionaryEntry( 30619, socket.language ));// The recharge item crumbles to dust as it strengthens the House Teleporter.
}
/** @type { ( tile: Item, keepSer: number ) => void } */
function UnlinkOther( tile, keepSer )
{
- var old = tile.GetTag( "LinkSer");
+ var old = tile.GetTag( "LinkSer" );
tile.SetTag( "LinkSer", null );
if( old > 0 && old != keepSer )
{
var oldtele = CalcItemFromSer( old );
if( IsTeleporterItem( oldtele ))
+ {
oldtele.SetTag( "LinkSer", null );
+
+ if( oldtele.GetTag( "chargeable" ) == 1 )
+ {
+ oldtele.SetTag( "Charges", 0 );
+ oldtele.Refresh();
+ }
+ }
}
}
@@ -587,8 +626,7 @@ function onCollide( trgSock, pColliding, objCollidedWith )
if( objCollidedWith.movable != 3 )
{
- if( trgSock )
- trgSock.SysMessage( GetDictionaryEntry( 30620, trgSock.language )); // This must be locked down in a house to function.
+ trgSock.SysMessage( GetDictionaryEntry( 30620, trgSock.language )); // This must be locked down in a house to function.
return false;
}
@@ -597,75 +635,83 @@ function onCollide( trgSock, pColliding, objCollidedWith )
if( !insideHouse )
{
- if( trgSock )
- trgSock.SysMessage( GetDictionaryEntry( 30621, trgSock.language ) ); // This must be placed inside a house.
+ trgSock.SysMessage( GetDictionaryEntry( 30621, trgSock.language )); // This must be placed inside a house.
return false;
}
- // SECURITY: Owner + Co-Owners only
if( !CanUseHouseTeleporter( pColliding, objCollidedWith ))
{
- if( trgSock )
- trgSock.SysMessage( GetDictionaryEntry( 30622, trgSock.language )); // Only the house owner and co-owners may use this teleporter.
+ trgSock.SysMessage( GetDictionaryEntry( 30622, trgSock.language )); // Only the house owner and co-owners may use this teleporter.
return false;
}
- if( trgSock )
+ if( pColliding.dead || pColliding.criminal )
{
- if( pColliding.dead || pColliding.criminal )
- {
- trgSock.SysMessage( GetDictionaryEntry( 30623, trgSock.language )); // You cannot use that right now.
- return false;
- }
+ trgSock.SysMessage( GetDictionaryEntry( 30623, trgSock.language )); // You cannot use that right now.
+ return false;
}
-
+
var linkSer = objCollidedWith.GetTag( "LinkSer" );
if( linkSer <= 0 )
{
- if( trgSock )
- trgSock.SysMessage( GetDictionaryEntry( 30624, trgSock.language )); // This teleporter is not linked.
+ trgSock.SysMessage( GetDictionaryEntry( 30624, trgSock.language )); // This teleporter is not linked.
return false;
}
var other = CalcItemFromSer( linkSer );
if( !IsTeleporterItem( other ))
{
- if( trgSock )
- trgSock.SysMessage( GetDictionaryEntry( 30624, trgSock.language )); // This teleporter is not linked.
+ trgSock.SysMessage( GetDictionaryEntry( 30624, trgSock.language )); // This teleporter is not linked.
return false;
}
if( other.movable != 3 )
{
- if( trgSock )
- trgSock.SysMessage( GetDictionaryEntry( 30625, trgSock.language )); // The destination teleporter is not properly placed.
+ trgSock.SysMessage( GetDictionaryEntry( 30625, trgSock.language )); // The destination teleporter is not properly placed.
return false;
}
- if( !IsInBuilding( other.x, other.y, other.z, other.worldnumber, other.instanceID, true ))
+ var destMulti = FindMulti( other.x, other.y, other.z, other.worldnumber, other.instanceID );
+ var destInsideHouse = ( ValidateObject( destMulti ) && destMulti.IsInMulti( other ));
+ if( !destInsideHouse )
{
- if( trgSock )
- trgSock.SysMessage( GetDictionaryEntry( 30625, trgSock.language )); // The destination teleporter is not properly placed.
+ trgSock.SysMessage( GetDictionaryEntry( 30625, trgSock.language ));// The destination teleporter is not properly placed.
return false;
}
if( objCollidedWith.GetTag( "chargeable" ) == 1 )
{
- var charge = objCollidedWith.GetTag( "Charges" );
- if( charge < 0 )
- charge = 0;
-
+ var charge = GetSharedCharges( objCollidedWith );
if( charge <= 0 )
{
- if( trgSock )
- trgSock.SysMessage( GetDictionaryEntry( 30626, trgSock.language )); // There are no charges left in this teleporter.
+ trgSock.SysMessage( GetDictionaryEntry( 30626, trgSock.language )); // There are no charges left in this teleporter.
return false;
}
- objCollidedWith.SetTag( "Charges", charge - 1 );
+ SetSharedCharges( objCollidedWith, charge - 1 );
+ }
+
+ // Collect nearby following pets before teleporting player
+ var petsToMove = [];
+ var followerList = pColliding.GetFollowerList();
+ for( var i = 0; i < followerList.length; i++ )
+ {
+ var tempFollower = followerList[i];
+ if( ValidateObject( tempFollower ) && tempFollower.wandertype == 1 && tempFollower.InRange( pColliding, 24 ))
+ petsToMove.push( tempFollower );
+ }
+
+ pColliding.Teleport( other.x, other.y, other.z, other.worldnumber, other.instanceID );
+
+ for( var j = 0; j < petsToMove.length; j++ )
+ {
+ if( ValidateObject( petsToMove[j] ))
+ {
+ petsToMove[j].Teleport( other.x, other.y, other.z, other.worldnumber, other.instanceID );
+ petsToMove[j].Follow( pColliding );
+ }
}
- pColliding.Teleport( other.x, other.y, other.z, other.worldnumber );
return false;
}
@@ -679,26 +725,21 @@ function onSpeechInput( pUser, targObj, pSpeech, pSpeechID )
if( pSpeechID != 1 )
return;
- // Basic validation
if( pSpeech == null )
return;
- pSpeech = ("" + pSpeech);
-
- // trim (simple ES5)
- pSpeech = pSpeech.replace(/^\s+|\s+$/g, "");
+ pSpeech = ( "" + pSpeech ).replace(/^\s+|\s+$/g, "" );
if( pSpeech.length <= 0 )
{
- pSocket.SysMessage( GetDictionaryEntry( 9270, pSocket.language )); // too short / none entered
+ pSocket.SysMessage( GetDictionaryEntry( 9270, pSocket.language ));// too short / none entered
return;
}
if( pSpeech.length > 60 )
{
- pSocket.SysMessage( GetDictionaryEntry( 9271, pSocket.language )); // too long (we'll reuse)
+ pSocket.SysMessage( GetDictionaryEntry( 9271, pSocket.language ));// too long (we'll reuse)
return;
}
- // Resolve which teleporter we are renaming
var srcSer = pUser.GetTempTag( "RenameSer" );
var teleA = CalcItemFromSer( srcSer );
if( !IsTeleporterItem( teleA ))
@@ -707,29 +748,27 @@ function onSpeechInput( pUser, targObj, pSpeech, pSpeechID )
return;
}
- // Must still be linked
var linkSer = teleA.GetTag( "LinkSer" );
if( linkSer <= 0 )
{
- pSocket.SysMessage( GetDictionaryEntry( 30629, pSocket.language )); // This teleporter must be linked before it can be renamed.
+ pSocket.SysMessage( GetDictionaryEntry( 30629, pSocket.language ));// This teleporter must be linked before it can be renamed.
return;
}
var teleB = CalcItemFromSer( linkSer );
if( !IsTeleporterItem( teleB ))
{
- pSocket.SysMessage( GetDictionaryEntry( 30629, pSocket.language )); // This teleporter must be linked before it can be renamed.
+ pSocket.SysMessage( GetDictionaryEntry( 30629, pSocket.language ));// This teleporter must be linked before it can be renamed.
return;
}
- // Apply name to BOTH
teleA.name = pSpeech;
teleB.name = pSpeech;
teleA.Refresh();
teleB.Refresh();
- pSocket.SysMessage( "Teleporter name set to: " + pSpeech ); // Teleporter name set to: %s
+ pSocket.SysMessage( "Teleporter name set to: " + pSpeech );
}
/** @type { ( myObj: BaseObject, pSocket: Socket ) => string } */
@@ -748,15 +787,9 @@ function onTooltip( myObj, pSocket )
parts.push( "Security: " + SecurityName( secMode ));
- if( myObj.id == 0x574A )
+ if( myObj.id == 0x574A && myObj.GetTag( "chargeable" ) == 1 )
{
- var charge = myObj.GetTag( "Charges" );
- if( charge < 0 )
- charge = 0;
-
- if( charge > chargeMax )
- charge = chargeMax;
-
+ var charge = GetSharedCharges( myObj );
parts.push( "Charges: " + charge + "/" + chargeMax );
}