Initial commit

This commit is contained in:
2020-12-28 23:30:20 +01:00
commit bb8162e4c1
536 changed files with 6007 additions and 0 deletions

523
static/game.html Normal file
View File

@@ -0,0 +1,523 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>DnD</title>
<link rel="stylesheet" href="/static/main.css">
<style type="text/css">
.pile-counter {
position: absolute;
bottom: 5px;
right: 5px;
color: wheat;
background-color: darkred;
border-radius: 5px;
height: 24px;
width: 35px;
text-align: center;
font-size: 22px;
font-family: sans-serif;
line-height: 24px;
}
.player-area {
display: grid;
grid-template-columns: 100px auto 100px;
border: 1px solid black;
width: 100%;
height: 145px;
position: relative;
box-sizing: border-box;
}
.card {
position: relative;
width: 90px;
margin: 1px;
}
.player-hand {
border: 1px solid red;
height: 100%;
margin: 0;
box-sizing: border-box;
top: 0;
}
.chat-window {
border: 1px solid black;
width: 300px;
position: absolute;
top: 0;
right: 0;
z-index: 100;
}
.supply-area {
position: relative;
padding-left: 30px;
padding-right: 300px;
background-color: dimgray;
box-sizing: border-box;
margin: 5px 0;
display: flex;
flex-flow: wrap;
}
.supply-area h3 {
position: relative;
top: 50px;
left: 0;
transform-origin: 0 0;
transform: rotate(90deg);
padding: 0;
margin: 0;
width: 0;
}
.draw-pile {
width: 90px;
position: relative;
height: 145px;
}
.opponent-hand {
width: 90px;
position: relative;
height: 145px;
}
.setup-screen {
display: none;
}
.discard-pile {
width: 90px;
border: 1px dotted green;
height: 145px;
box-sizing: border-box;
}
.inplay-area {
width: 100%;
height: 180px;
position: relative;
box-sizing: border-box;
transition: height 0.4s ease;
background-color: dimgray;
box-sizing: border-box;
margin: 5px 0;
}
.inplay-area.inactive {
height: 0;
transition: height 0.4s ease;
overflow: hidden;
}
.turn-status {
line-height: 24px;
height: 24px;
position: absolute;
top: 0;
left: 50%;
background-color: rgb(255 255 255 / 34%);
border-radius: 0 0 20px 20px;
padding: 0 20px 0;
transform: translate(-50%, 0);
opacity: 1;
transition: opacity 0.4s ease;
}
.inplay-area.inactive .turn-status {
opacity: 0;
transition: opacity 0.4s ease;
}
.opponent-area {
height: 180px;
display: flex;
}
.opponent-status {
grid-template-rows: 30px auto;
grid-template-columns: auto auto auto;
box-sizing: border-box;
margin: 0 5px;
border: 1px solid saddlebrown;
display: grid;
grid-gap: 2px;
}
.opponent-status.active {
box-shadow: 0 0 10px red;
}
.opponent-status .name {
grid-column-start: 1;
grid-column-end: span 3;
text-align: center;
grid-row-start: 1;
grid-row-end: 1;
}
.opponent-status .discard-pile {
grid-column-start: 1;
grid-column-end: 1;
grid-row-start: 2;
grid-row-end: 2;
}
.opponent-status .draw-pile {
grid-column-start: 2;
grid-column-end: 2;
grid-row-start: 2;
grid-row-end: 2;
}
.opponent-status .opponent-hand {
grid-column-start: 3;
grid-column-end: 3;
grid-row-start: 2;
grid-row-end: 2;
}
.game-screen {
padding: 10px;
}
</style>
<script src="/static/mithril.js"></script>
</head>
<body>
<div id="game"></div>
<script>
function Chat(initialVnode) {
var keyup = function(e) {
if (e.key == "Enter" && e.srcElement.value.length > 0) {
let msg = { type: "Chat", message: e.srcElement.value };
initialVnode.attrs.socket.send(JSON.stringify(msg));
e.srcElement.value = "";
}
}
return {
view: function(vnode) {
return m(".chat-window",
m("h4", "Players"),
m("ul", m("li", "Markus (you)")),
m("h4", "Messages"),
m("ul", {id: "chat"}),
m("input", {
id: "chat_input",
placeholder: "Type to chat...",
onkeyup: keyup
})
)
}
}
}
function SupplyPile(initialVnode) {
return {
view: function(vnode) {
return m(".card",
m("img", {class: "card", src: "/static/images/cards/" + vnode.attrs.name.toLowerCase() + ".jpg"}),
m("span", {class: "pile-counter" }, vnode.attrs.count)
)
}
}
}
function SupplyArea(initialVnode) {
return {
view: function(vnode) {
return m(".supply-area",
m("h3", "Supply"),
vnode.attrs.supply.map(function(pile) {
return m(SupplyPile, pile)
})
)
}
}
}
function DiscardPile(initialVnode) {
return {
view: function(vnode) {
return m(".discard-pile", "Discard Pile")
}
}
}
function DrawPile(initialVnode) {
return {
view: function(vnode) {
return m(".draw-pile",
m("img", {class: "card", src: "/static/images/cards/Card_back.jpg"}),
m("span", {class: "pile-counter" }, vnode.attrs.count)
)
}
}
}
function PlayerHand(initialVnode) {
return {
view: function(vnode) {
return m(".player-hand", "Player Hand",
vnode.attrs.hand.map(function(card) {
return m("img", {class: "card", src: "/static/images/cards/" + card.toLowerCase() + ".jpg"})
})
)
}
}
}
function OpponentHand(initialVnode) {
return {
view: function(vnode) {
return m(".opponent-hand",
m("img", {class: "card", src: "/static/images/cards/Card_back.jpg"}),
m("span", {class: "pile-counter" }, vnode.attrs.count)
)
}
}
}
function InPlayArea(initialVnode) {
return {
view: function(vnode) {
var active = vnode.attrs.active ? "" : "inactive";
return m(".inplay-area", {class: active},
"Player play area",
m(".turn-status",
"Actions: " + vnode.attrs.actions + " | Buys: " + vnode.attrs.buys + " | ",
m("img", {src: "/static/images/64px-Coin.png", style: "height: 16px;"}),
": " + vnode.attrs.coin
)
)
}
}
}
function PlayerArea(initialVnode) {
return {
view: function(vnode) {
return m(".player-area",
m(DrawPile, {count: vnode.attrs.player_drawpile_count}),
m(PlayerHand, vnode.attrs.player),
m(DiscardPile)
)
}
}
}
function OpponentStatus(initialVnode) {
return {
view: function(vnode) {
var active = vnode.attrs.active ? "active" : "";
return m(".opponent-status", {class: active },
m(".name", vnode.attrs.name),
m(DiscardPile),
m(DrawPile, {count: vnode.attrs.draw_pile_count}),
m(OpponentHand, {count: vnode.attrs.hand_count })
)
}
}
}
function OpponentArea(initialVnode) {
return {
view: function(vnode) {
return m(".opponent-area",
vnode.attrs.opponents.map(function(o) {
return m(OpponentStatus, o)
})
)
}
}
}
function GameScreen(initialVnode) {
return {
view: function(vnode) {
return m(".game-screen",
m(OpponentArea, vnode.attrs),
m(InPlayArea, vnode.attrs.opponent_turn_state),
m(SupplyArea, vnode.attrs),
m(InPlayArea, vnode.attrs.player_turn_state),
m(PlayerArea, vnode.attrs)
)
}
}
}
function SetupScreen(initialVnode) {
var start_click = function(e) {
console.log("start_click", e);
let msg = { id: "start_game" };
initialVnode.attrs.socket.send(JSON.stringify(msg));
}
return {
view: function(vnode) {
return m(".setup-screen",
m("h3", "Setup"),
m("h4", "Basic cards"),
m(".basic-cards",
vnode.attrs.basic_cards.map(function(card) {
return m("img", {class: "card", src: "/static/images/cards/" + card.toLowerCase() + ".jpg"})
})
),
m("h4", "Kingdom Cards"),
m(".kingdom-cards",
vnode.attrs.kingdom_cards.map(function(card) {
return m("img", {class: "card", src: "/static/images/cards/" + card.toLowerCase() + ".jpg"})
})
),
m("h4", "Starting Deck"),
m(".start-deck",
vnode.attrs.starting_deck.map(function(card) {
return m("img", {class: "card", src: "/static/images/cards/" + card.toLowerCase() + ".jpg"})
})
),
m("button", {onclick: start_click}, "Start Game")
)
}
}
}
var game_state;
function App(initialVnode) {
if (document.location.protocol == "https:") {
url = document.location.href.replace("https://", "wss://") + "/ws";
} else {
url = document.location.href.replace("http://", "ws://") + "/ws";
}
const webSocket = new WebSocket(url);
var setup_state = {
starting_deck: [],
basic_cards: ["Copper", "Silver", "Gold", "Estate", "Duchery", "Province", "Curse"],
kingdom_cards: ["Cellar", "Moat", "Village", "Merchant", "Workshop", "Smithy", "Remodel", "Militia", "Market", "Mine"],
socket: webSocket
}
var handle_setup = function(data) {
setup_state.starting_deck = data.deck;
}
game_state = {
supply: [
{ name: "Copper", count: 46 },
{ name: "Silver", count: 38 },
{ name: "Gold", count: 30 },
{ name: "Estate", count: 8 },
{ name: "Duchery", count: 8 },
{ name: "Province", count: 8 },
{ name: "Curse", count: 10 },
{ name: "Cellar", count: 10},
{ name: "Moat", count: 10},
{ name: "Village", count: 10},
{ name: "Merchant", count: 10},
{ name: "Workshop", count: 10},
{ name: "Smithy", count: 10},
{ name: "Remodel", count: 10},
{ name: "Militia", count: 10},
{ name: "Market", count: 10},
{ name: "Mine", count: 10}
],
opponent_turn_state: {
actions: 1,
buys: 1,
coin: 0,
active: false
},
player_turn_state: {
actions: 1,
buys: 1,
coin: 0,
active: true
},
player_drawpile_count: 10,
player: {
hand: []
},
opponents: [
{
name: "Alice",
draw_pile_count: 10,
hand_count: 5,
active: true
},
{
name: "Bob",
draw_pile_count: 8,
hand_count: 5
},
{
name: "Mallory",
draw_pile_count: 10,
hand_count: 3
}
]
}
var chat_state = {
socket: webSocket
}
webSocket.onopen = function(event) {
console.log("ws open");
//webSocket.send("HALLO");
};
webSocket.onmessage = function(event) {
var msg = JSON.parse(event.data);
if (msg.type == "Chat") {
let chatDiv = document.getElementById("chat");
let newmsg = document.createElement("li");
newmsg.innerHTML = msg.sender + ": " + msg.message;
chatDiv.append(newmsg);
//newmsg.scrollIntoView();
} else if (msg.type == "PlayerJoined") {
let chatDiv = document.getElementById("chat");
let newmsg = document.createElement("li");
newmsg.innerHTML = msg.player + " joined the game.";
chatDiv.append(newmsg);
//newmsg.scrollIntoView();
} else if (msg.id == "setup") {
handle_setup(msg.setup);
} else {
console.log("event?");
console.log(event.data);
}
m.redraw();
}
return {
view: function(vnode) {
return [
m(SetupScreen, setup_state),
m(GameScreen, game_state),
m(Chat, chat_state)
]
}
}
}
m.mount(document.getElementById("game"), App)
</script>
</body>
</html>

BIN
static/images/64px-Coin.png LFS Normal file

Binary file not shown.

BIN
static/images/cards/Card_back.jpg LFS Normal file

Binary file not shown.

Binary file not shown.

BIN
static/images/cards/academy.jpg LFS Normal file

Binary file not shown.

Binary file not shown.

BIN
static/images/cards/advance.jpg LFS Normal file

Binary file not shown.

Binary file not shown.

BIN
static/images/cards/advisor.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/alchemist.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/alms.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/altar.jpg LFS Normal file

Binary file not shown.

Binary file not shown.

BIN
static/images/cards/amulet.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/annex.jpg LFS Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
static/images/cards/aqueduct.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/archive.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/arena.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/armory.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/artificer.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/artisan.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/avanto.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/bad-omens.jpg LFS Normal file

Binary file not shown.

Binary file not shown.

BIN
static/images/cards/baker.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/ball.jpg LFS Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
static/images/cards/bandit.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/bank.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/banquet.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/bard.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/baron.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/barracks.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/basilica.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/bat.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/baths.jpg LFS Normal file

Binary file not shown.

Binary file not shown.

BIN
static/images/cards/bazaar.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/beggar.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/bishop.jpg LFS Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
static/images/cards/bonfire.jpg LFS Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
static/images/cards/borrow.jpg LFS Normal file

Binary file not shown.

Binary file not shown.

BIN
static/images/cards/bridge.jpg LFS Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
static/images/cards/butcher.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/cache.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/canal.jpg LFS Normal file

Binary file not shown.

Binary file not shown.

BIN
static/images/cards/capital.jpg LFS Normal file

Binary file not shown.

Binary file not shown.

BIN
static/images/cards/captain.jpg LFS Normal file

Binary file not shown.

Binary file not shown.

BIN
static/images/cards/caravan.jpg LFS Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
static/images/cards/castles.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/catacombs.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/catapult.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/cathedral.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/cellar.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/cemetery.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/champion.jpg LFS Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
static/images/cards/chapel.jpg LFS Normal file

Binary file not shown.

Binary file not shown.

BIN
static/images/cards/charm.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/church.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/citadel.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/city-gate.jpg LFS Normal file

Binary file not shown.

Binary file not shown.

BIN
static/images/cards/city.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/cobbler.jpg LFS Normal file

Binary file not shown.

Binary file not shown.

BIN
static/images/cards/colonnade.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/colony.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/conclave.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/conquest.jpg LFS Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
static/images/cards/copper.jpg LFS Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
static/images/cards/count.jpg LFS Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
static/images/cards/courtier.jpg LFS Normal file

Binary file not shown.

BIN
static/images/cards/courtyard.jpg LFS Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More