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 ); }