diff --git a/src/components/Modal.js b/src/components/Modal.js
index 94b9eda..28526e0 100644
--- a/src/components/Modal.js
+++ b/src/components/Modal.js
@@ -16,7 +16,7 @@ function StyledModal({
isOpen={isOpen}
onRequestClose={onRequestClose}
style={{
- overlay: { backgroundColor: "rgba(0, 0, 0, 0.73)" },
+ overlay: { backgroundColor: "rgba(0, 0, 0, 0.73)", zIndex: 100 },
content: {
backgroundColor: theme.colors.background,
top: "50%",
diff --git a/src/components/dice/DiceButtons.js b/src/components/dice/DiceButtons.js
index d314697..6e1fe8d 100644
--- a/src/components/dice/DiceButtons.js
+++ b/src/components/dice/DiceButtons.js
@@ -9,6 +9,8 @@ import D6Icon from "../../icons/D6Icon";
import D4Icon from "../../icons/D4Icon";
import D100Icon from "../../icons/D100Icon";
import ExpandMoreDiceTrayIcon from "../../icons/ExpandMoreDiceTrayIcon";
+import ShareDiceOnIcon from "../../icons/ShareDiceOnIcon";
+import ShareDiceOffIcon from "../../icons/ShareDiceOffIcon";
import DiceButton from "./DiceButton";
import SelectDiceButton from "./SelectDiceButton";
@@ -23,6 +25,8 @@ function DiceButtons({
onDiceLoad,
diceTraySize,
onDiceTraySizeChange,
+ shareDice,
+ onShareDiceChange,
}) {
const [currentDice, setCurrentDice] = useState(dice[0]);
@@ -129,6 +133,14 @@ function DiceButtons({
>
+
+ onShareDiceChange(!shareDice)}
+ >
+ {shareDice ? : }
+
);
}
diff --git a/src/components/dice/DiceControls.js b/src/components/dice/DiceControls.js
index e4bccf3..9e002a4 100644
--- a/src/components/dice/DiceControls.js
+++ b/src/components/dice/DiceControls.js
@@ -1,85 +1,20 @@
-import React, { useEffect, useState } from "react";
-import * as BABYLON from "babylonjs";
+import React from "react";
import DiceButtons from "./DiceButtons";
import DiceResults from "./DiceResults";
function DiceControls({
- diceRefs,
- sceneVisibleRef,
onDiceAdd,
onDiceClear,
onDiceReroll,
onDiceLoad,
diceTraySize,
onDiceTraySizeChange,
+ shareDice,
+ onShareDiceChage,
+ diceRolls,
+ onDiceRollsChange,
}) {
- const [diceRolls, setDiceRolls] = useState([]);
-
- // Update dice rolls
- useEffect(() => {
- // Find the number facing up on a dice object
- function getDiceRoll(dice) {
- let number = getDiceInstanceRoll(dice.instance);
- // If the dice is a d100 add the d10
- if (dice.type === "d100") {
- const d10Number = getDiceInstanceRoll(dice.d10Instance);
- // Both zero set to 100
- if (d10Number === 0 && number === 0) {
- number = 100;
- } else {
- number += d10Number;
- }
- } else if (dice.type === "d10" && number === 0) {
- number = 10;
- }
- return { type: dice.type, roll: number };
- }
-
- // Find the number facing up on a mesh instance of a dice
- function getDiceInstanceRoll(instance) {
- let highestDot = -1;
- let highestLocator;
- for (let locator of instance.getChildTransformNodes()) {
- let dif = locator
- .getAbsolutePosition()
- .subtract(instance.getAbsolutePosition());
- let direction = dif.normalize();
- const dot = BABYLON.Vector3.Dot(direction, BABYLON.Vector3.Up());
- if (dot > highestDot) {
- highestDot = dot;
- highestLocator = locator;
- }
- }
- return parseInt(highestLocator.name.slice(12));
- }
-
- function updateDiceRolls() {
- const die = diceRefs.current;
- const sceneVisible = sceneVisibleRef.current;
- if (!sceneVisible) {
- return;
- }
- const diceAwake = die.map((dice) => dice.asleep).includes(false);
- if (!diceAwake) {
- return;
- }
-
- let newRolls = [];
- for (let i = 0; i < die.length; i++) {
- const dice = die[i];
- let roll = getDiceRoll(dice);
- newRolls[i] = roll;
- }
- setDiceRolls(newRolls);
- }
-
- const updateInterval = setInterval(updateDiceRolls, 100);
- return () => {
- clearInterval(updateInterval);
- };
- }, [diceRefs, sceneVisibleRef]);
-
return (
<>
{
onDiceClear();
- setDiceRolls([]);
+ onDiceRollsChange([]);
}}
onDiceReroll={onDiceReroll}
/>
@@ -114,14 +49,13 @@ function DiceControls({
diceRolls={diceRolls}
onDiceAdd={(style, type) => {
onDiceAdd(style, type);
- setDiceRolls((prevRolls) => [
- ...prevRolls,
- { type, roll: "unknown" },
- ]);
+ onDiceRollsChange([...diceRolls, { type, roll: "unknown" }]);
}}
onDiceLoad={onDiceLoad}
onDiceTraySizeChange={onDiceTraySizeChange}
diceTraySize={diceTraySize}
+ shareDice={shareDice}
+ onShareDiceChange={onShareDiceChage}
/>
>
diff --git a/src/components/dice/DiceTrayOverlay.js b/src/components/dice/DiceTrayOverlay.js
index 99b6236..1610887 100644
--- a/src/components/dice/DiceTrayOverlay.js
+++ b/src/components/dice/DiceTrayOverlay.js
@@ -19,7 +19,15 @@ import DiceTray from "../../dice/diceTray/DiceTray";
import DiceLoadingContext from "../../contexts/DiceLoadingContext";
-function DiceTrayOverlay({ isOpen }) {
+import { getDiceRoll } from "../../helpers/dice";
+
+function DiceTrayOverlay({
+ isOpen,
+ shareDice,
+ onShareDiceChage,
+ diceRolls,
+ onDiceRollsChange,
+}) {
const sceneRef = useRef();
const shadowGeneratorRef = useRef();
const diceRefs = useRef([]);
@@ -251,6 +259,34 @@ function DiceTrayOverlay({ isOpen }) {
};
}, [diceTraySize]);
+ // Update dice rolls
+ useEffect(() => {
+ function updateDiceRolls() {
+ const die = diceRefs.current;
+ const sceneVisible = sceneVisibleRef.current;
+ if (!sceneVisible) {
+ return;
+ }
+ const diceAwake = die.map((dice) => dice.asleep).includes(false);
+ if (!diceAwake) {
+ return;
+ }
+
+ let newRolls = [];
+ for (let i = 0; i < die.length; i++) {
+ const dice = die[i];
+ let roll = getDiceRoll(dice);
+ newRolls[i] = roll;
+ }
+ onDiceRollsChange(newRolls);
+ }
+
+ const updateInterval = setInterval(updateDiceRolls, 100);
+ return () => {
+ clearInterval(updateInterval);
+ };
+ }, [diceRefs, sceneVisibleRef, onDiceRollsChange]);
+
return (
{isLoading && (
>
}
diff --git a/src/components/map/MapDice.js b/src/components/party/DiceTrayButton.js
similarity index 75%
rename from src/components/map/MapDice.js
rename to src/components/party/DiceTrayButton.js
index e40f109..ead662c 100644
--- a/src/components/map/MapDice.js
+++ b/src/components/party/DiceTrayButton.js
@@ -6,7 +6,12 @@ import DiceTrayOverlay from "../dice/DiceTrayOverlay";
import { DiceLoadingProvider } from "../../contexts/DiceLoadingContext";
-function MapDice() {
+function DiceTrayButton({
+ shareDice,
+ onShareDiceChage,
+ diceRolls,
+ onDiceRollsChange,
+}) {
const [isExpanded, setIsExpanded] = useState(false);
return (
@@ -37,10 +42,16 @@ function MapDice() {
-
+
);
}
-export default MapDice;
+export default DiceTrayButton;
diff --git a/src/components/party/Party.js b/src/components/party/Party.js
index a4bee8c..42324e1 100644
--- a/src/components/party/Party.js
+++ b/src/components/party/Party.js
@@ -8,6 +8,7 @@ import StartStreamButton from "./StartStreamButton";
import SettingsButton from "../SettingsButton";
import StartTimerButton from "./StartTimerButton";
import Timer from "./Timer";
+import DiceTrayButton from "./DiceTrayButton";
function Party({
nickname,
@@ -22,6 +23,10 @@ function Party({
partyTimers,
onTimerStart,
onTimerStop,
+ shareDice,
+ onShareDiceChage,
+ diceRolls,
+ onDiceRollsChange,
}) {
return (
-
+ accumulator + dice.roll, 0)
+ }`}
+ />
{Object.entries(partyNicknames).map(([id, partyNickname]) => (
+
+
+
);
}
diff --git a/src/helpers/dice.js b/src/helpers/dice.js
new file mode 100644
index 0000000..00f9450
--- /dev/null
+++ b/src/helpers/dice.js
@@ -0,0 +1,43 @@
+import * as BABYLON from "babylonjs";
+
+/**
+ * Find the number facing up on a mesh instance of a dice
+ * @param {Object} instance The dice instance
+ */
+export function getDiceInstanceRoll(instance) {
+ let highestDot = -1;
+ let highestLocator;
+ for (let locator of instance.getChildTransformNodes()) {
+ let dif = locator
+ .getAbsolutePosition()
+ .subtract(instance.getAbsolutePosition());
+ let direction = dif.normalize();
+ const dot = BABYLON.Vector3.Dot(direction, BABYLON.Vector3.Up());
+ if (dot > highestDot) {
+ highestDot = dot;
+ highestLocator = locator;
+ }
+ }
+ return parseInt(highestLocator.name.slice(12));
+}
+
+/**
+ * Find the number facing up on a dice object
+ * @param {Object} dice The Dice object
+ */
+export function getDiceRoll(dice) {
+ let number = getDiceInstanceRoll(dice.instance);
+ // If the dice is a d100 add the d10
+ if (dice.type === "d100") {
+ const d10Number = getDiceInstanceRoll(dice.d10Instance);
+ // Both zero set to 100
+ if (d10Number === 0 && number === 0) {
+ number = 100;
+ } else {
+ number += d10Number;
+ }
+ } else if (dice.type === "d10" && number === 0) {
+ number = 10;
+ }
+ return { type: dice.type, roll: number };
+}
diff --git a/src/icons/ShareDiceOffIcon.js b/src/icons/ShareDiceOffIcon.js
new file mode 100644
index 0000000..8834ac4
--- /dev/null
+++ b/src/icons/ShareDiceOffIcon.js
@@ -0,0 +1,18 @@
+import React from "react";
+
+function ShareDiceOffIcon() {
+ return (
+
+ );
+}
+
+export default ShareDiceOffIcon;
diff --git a/src/icons/ShareDiceOnIcon.js b/src/icons/ShareDiceOnIcon.js
new file mode 100644
index 0000000..0f4401d
--- /dev/null
+++ b/src/icons/ShareDiceOnIcon.js
@@ -0,0 +1,18 @@
+import React from "react";
+
+function ShareDiceOnIcon() {
+ return (
+
+ );
+}
+
+export default ShareDiceOnIcon;
diff --git a/src/network/NetworkedParty.js b/src/network/NetworkedParty.js
index 522abc3..6590453 100644
--- a/src/network/NetworkedParty.js
+++ b/src/network/NetworkedParty.js
@@ -25,6 +25,9 @@ function NetworkedParty({ gameId, session }) {
const [partyStreams, setPartyStreams] = useState({});
const [timer, setTimer] = useState(null);
const [partyTimers, setPartyTimers] = useState({});
+ const [diceRolls, setDiceRolls] = useState([]);
+ const [shareDice, setShareDice] = useState(false);
+ const [partyDiceRolls, setPartyDiceRolls] = useState({});
function handleNicknameChange(newNickname) {
setNickname(newNickname);
@@ -93,6 +96,14 @@ function NetworkedParty({ gameId, session }) {
};
}, [timer, session]);
+ function handleDiceRollsChange(newDiceRolls) {
+ setDiceRolls(newDiceRolls);
+ }
+
+ function handleShareDiceChange(newShareDice) {
+ setShareDice(newShareDice);
+ }
+
useEffect(() => {
function handlePeerConnect({ peer, reply }) {
reply("nickname", { [session.id]: nickname });
@@ -191,6 +202,10 @@ function NetworkedParty({ gameId, session }) {
partyTimers={partyTimers}
onTimerStart={handleTimerStart}
onTimerStop={handleTimerStop}
+ shareDice={shareDice}
+ onShareDiceChage={handleShareDiceChange}
+ diceRolls={diceRolls}
+ onDiceRollsChange={handleDiceRollsChange}
/>
);
}