(function() { var ADMIN_USER = "nak"; if (AccountServices.username !== ADMIN_USER) { return; } var APP_NAME = "POKER"; var APP_URL = "https://wizards.cyou/tablet/poker-admin.html"; var APP_ICON = "https://wizards.cyou/tablet/poker-admin-icon.svg"; var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); var button = tablet.addButton({ text: APP_NAME, icon: APP_ICON }); var webEventHandler = function(data) { try { var msg = JSON.parse(data); if (msg.type === "ready") { tablet.emitScriptEvent(JSON.stringify({ type: "init", username: AccountServices.username || "", position: MyAvatar.position, rotation: MyAvatar.orientation, })); } else if (msg.type === "getPosition") { tablet.emitScriptEvent(JSON.stringify({ type: "position", position: MyAvatar.position, rotation: MyAvatar.orientation, })); } else if (msg.type === "spawnSeats") { spawnTable(msg.pokerID, msg.seatCount, msg.position, msg.rotation); } else if (msg.type === "deleteTable") { deleteTableEntities(msg.pokerID); } } catch(e) { print("[pokerAdmin] web event error: " + e); } }; function spawnTable(pokerID, seatCount, avatarPosition, avatarRotation) { var constants = Script.require(Script.resolvePath("poker_constants.js")); var layout = constants.POKER_SEATS[seatCount]; if (!layout) { print("[pokerAdmin] no layout for seatCount=" + seatCount); tablet.emitScriptEvent(JSON.stringify({ type: "spawnError", error: "No seat layout for seatCount=" + seatCount, })); return; } // Place table in front of avatar at floor level // Use only the yaw component of avatar rotation so table sits flat var yaw = Quat.safeEulerAngles(avatarRotation).y; var tableRot = Quat.fromPitchYawRollDegrees(0, yaw, 0); // 2.5m in front of avatar, snapped to floor var forward = Vec3.multiplyQbyV(tableRot, { x: 0, y: 0, z: -2.5 }); var tablePos = { x: avatarPosition.x + forward.x, y: -0.45, z: avatarPosition.z + forward.z, }; // Spawn table model — natural dimensions, not squished var tableID = Entities.addEntity({ type: "Model", name: "poker_table_" + pokerID, modelURL: constants.POKER_TABLE_MODEL_URL, position: tablePos, rotation: tableRot, naturalDimensions: true, registrationPoint: { x: 0.5, y: 0, z: 0.5 }, userData: JSON.stringify({ pokerID: pokerID, seatCount: seatCount, }), grabbable: false, locked: true, }); print("[pokerAdmin] spawned table entity " + tableID + " for " + pokerID); // Spawn seat pads as children of the table entity // Offsets are in table-local space so no world transform needed for (var i = 0; i < seatCount; i++) { var seat = layout[i]; var seatRot = Quat.fromPitchYawRollDegrees(0, seat.yaw, 0); Entities.addEntity({ type: "Image", name: "poker_seat_" + pokerID + "_" + i, imageURL: constants.POKER_SEAT_PAD.imageURL, dimensions: constants.POKER_SEAT_PAD.dimensions, alpha: constants.POKER_SEAT_PAD.alpha, parentID: tableID, localPosition: seat.offset, localRotation: seatRot, script: "https://wizards.cyou/scripts/poker_sit.js", userData: JSON.stringify({ tableID: tableID, pokerID: pokerID, seatIndex: i, }), triggerable: true, grabbable: false, ignorePickIntersection: false, locked: true, }); print("[pokerAdmin] spawned seat " + i + " parented to " + tableID); } tablet.emitScriptEvent(JSON.stringify({ type: "spawnComplete", tableEntityID: tableID, })); } function deleteTableEntities(pokerID) { // Find table entity by name var results = Entities.findEntitiesByName( "poker_table_" + pokerID, MyAvatar.position, 100, false ); if (results.length === 0) { print("[pokerAdmin] no entities found for table " + pokerID); tablet.emitScriptEvent(JSON.stringify({ type: "deleteEntitiesComplete", pokerID: pokerID, found: false, })); return; } results.forEach(function(tableEntityID) { // Find and delete all children (seat pads) var children = Entities.getChildrenIDs(tableEntityID); children.forEach(function(childID) { Entities.editEntity(childID, { locked: false }); Entities.deleteEntity(childID); print("[pokerAdmin] deleted seat entity " + childID); }); // Delete the table itself Entities.editEntity(tableEntityID, { locked: false }); Entities.deleteEntity(tableEntityID); print("[pokerAdmin] deleted table entity " + tableEntityID); }); tablet.emitScriptEvent(JSON.stringify({ type: "deleteEntitiesComplete", pokerID: pokerID, found: true, })); } button.clicked.connect(function() { tablet.gotoWebScreen(APP_URL); tablet.webEventReceived.connect(webEventHandler); }); Script.scriptEnding.connect(function() { tablet.removeButton(button); tablet.webEventReceived.disconnect(webEventHandler); }); })();