edit(wip)
This commit is contained in:
parent
8136e91a0f
commit
6fe5da164f
6
.vscode/launch.json
vendored
6
.vscode/launch.json
vendored
@ -16,13 +16,11 @@
|
|||||||
"console": "externalTerminal"
|
"console": "externalTerminal"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "chrome",
|
"type": "firefox",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"name": "Launch ExtinctionOnlineClient",
|
"name": "Launch ExtinctionOnlineClient",
|
||||||
"runtimeExecutable": "/usr/bin/brave",
|
|
||||||
"url": "http://localhost:5500",
|
"url": "http://localhost:5500",
|
||||||
"webRoot": "${workspaceFolder}",
|
"webRoot": "${workspaceFolder}"
|
||||||
"sourceMaps": true
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
202
LICENSE
Normal file
202
LICENSE
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
@ -1,25 +1,50 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
const AsyncFunction = async function () { }.constructor;
|
const AsyncFunction = async function () { }.constructor;
|
||||||
|
class Operation {
|
||||||
|
static #operations = new Map();
|
||||||
|
static #id = 0;
|
||||||
|
static get nextId() {
|
||||||
|
return ++Operation.#id;
|
||||||
|
}
|
||||||
|
static addOperation(id, callback) {
|
||||||
|
Operation.#operations.set(id, callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function discard(target, card) {
|
function discard(target, card) {
|
||||||
console.log("DIS!CAR!D!");
|
console.log("DIS!CAR!D!");
|
||||||
postMessage({ type: "game", game: { command: "discard", target: target, card: card } });
|
postMessage({ type: "game", game: { command: "discard", target: target, card: card } });
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectUser() {
|
/*
|
||||||
|
function selectUser(from, callback) {
|
||||||
|
const opeId = Operation.nextId;
|
||||||
|
postMessage({ type: "game", game: { command: "selectUser", from: from, id: opeId } });
|
||||||
|
Operation.addOperation(opeId, callback);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
function selectCards(count, target, targetStockId, callback) {/*todo*/
|
||||||
|
const opeId = Operation.nextId;
|
||||||
|
postMessage({ type: "game", game: { command: "selectCards", target: target, count: count, targetStockId: targetStockId, id: opeId } });
|
||||||
|
Operation.addOperation(opeId, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectCard(count, target) {
|
function getCard(target, cardId) {
|
||||||
|
return target.cards.find(it => it.cardType.id == cardId);
|
||||||
}
|
}
|
||||||
|
|
||||||
onmessage = e => {
|
async function wait(time) {
|
||||||
|
await new Promise(resolve => {
|
||||||
|
setTimeout(resolve, time);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onmessage = async e => {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
switch (e.data.type) {
|
switch (e.data.type) {
|
||||||
case "run":
|
case "run":
|
||||||
let fun = new AsyncFunction("target", "players", e.data.function);
|
let fun = new AsyncFunction("target", "players", e.data.function);
|
||||||
fun(e.data.target, e.data.players);
|
await fun(e.data.target, e.data.players);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -43,7 +43,8 @@ const cardTypes = {
|
|||||||
rob: {
|
rob: {
|
||||||
id: "rob",
|
id: "rob",
|
||||||
prefix: "J",
|
prefix: "J",
|
||||||
count: 4
|
count: 4,
|
||||||
|
onUse: ""
|
||||||
},
|
},
|
||||||
robKill: {
|
robKill: {
|
||||||
id: "robKill",
|
id: "robKill",
|
||||||
@ -79,13 +80,13 @@ const cardTypes = {
|
|||||||
id: "extinction",
|
id: "extinction",
|
||||||
prefix: "H",
|
prefix: "H",
|
||||||
count: 4,
|
count: 4,
|
||||||
onGet: "target.cards.forEach(it => {discard(target,it);});"
|
onGet: "await wait(700);const lose = getCard(target,\"lose\");if(lose)discard(target,lose);else target.cards.forEach(it => {discard(target,it);});await wait(700);"
|
||||||
},
|
},
|
||||||
annihilation: {
|
annihilation: {
|
||||||
id: "annihilation",
|
id: "annihilation",
|
||||||
prefix: "I",
|
prefix: "I",
|
||||||
count: 1,
|
count: 1,
|
||||||
onGet: "players.forEach(player => {if(player.cards.length <= 5)player.cards.forEach(card => {discard(player,card);})});"
|
onGet: "await wait(700);players.forEach(player => {if(player.cards.length <= 5)player.cards.forEach(card => {discard(player,card);})});await wait(700);"
|
||||||
},
|
},
|
||||||
drop: {
|
drop: {
|
||||||
id: "drop",
|
id: "drop",
|
||||||
@ -110,6 +111,7 @@ const cardTypes = {
|
|||||||
lose: {
|
lose: {
|
||||||
id: "lose",
|
id: "lose",
|
||||||
prefix: "T",
|
prefix: "T",
|
||||||
count: 1
|
count: 1,
|
||||||
|
onGet: "console.log(\"LOSE!!!\");"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -8,6 +8,7 @@ const commands = {
|
|||||||
gameStart: "GameStart", // args: PlayerID(ターン順)...
|
gameStart: "GameStart", // args: PlayerID(ターン順)...
|
||||||
addCard: "AddCard", // target: 追加するPlayerID; args: 追加するカードのID, カードのIndex
|
addCard: "AddCard", // target: 追加するPlayerID; args: 追加するカードのID, カードのIndex
|
||||||
worker: "Worker", //
|
worker: "Worker", //
|
||||||
|
waiting: "Waiting",//
|
||||||
};
|
};
|
||||||
|
|
||||||
const side = {
|
const side = {
|
||||||
@ -42,7 +43,6 @@ function joinToRoom(id, name) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
socket.send(JSON.stringify(obj));
|
socket.send(JSON.stringify(obj));
|
||||||
EXOUtils.init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Card {
|
class Card {
|
||||||
@ -65,14 +65,13 @@ class Player {
|
|||||||
this.clientId = id;
|
this.clientId = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Side: Host
|
||||||
async addCard(card) {
|
async addCard(card) {
|
||||||
this.cards.push(card);
|
this.cards.push(card);
|
||||||
new MessageBuilder(this.clientId).game().addCommand(commands.addCard, this.clientId, card.cardType.id, card.idIndex).send();
|
new MessageBuilder(this.clientId).game().addCommand(commands.addCard, this.clientId, card.cardType.id, card.idIndex).send();
|
||||||
new MessageBuilder().game().addCommand(commands.addCard, this.clientId, cardTypes.unknown.id, -1).send();
|
new MessageBuilder().game().addCommand(commands.addCard, this.clientId, cardTypes.unknown.id, -1).send();
|
||||||
if (card.cardType.onGet) {
|
if (card.cardType.onGet) {
|
||||||
await new Promise(resolve => setTimeout(resolve, 700));
|
|
||||||
EXOUtils.capsuleExecute(card.cardType.onGet, this);
|
EXOUtils.capsuleExecute(card.cardType.onGet, this);
|
||||||
await new Promise(resolve => setTimeout(resolve, 700));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -111,47 +110,6 @@ class MessageBuilder {
|
|||||||
|
|
||||||
send() {
|
send() {
|
||||||
socket.send(JSON.stringify(this.object));
|
socket.send(JSON.stringify(this.object));
|
||||||
}
|
this.object = null;
|
||||||
}
|
|
||||||
|
|
||||||
class EXOUtils {
|
|
||||||
static worker;
|
|
||||||
|
|
||||||
static init() {
|
|
||||||
if (controller instanceof HostController) {
|
|
||||||
this.worker = new Worker("static/js/card-module.js");
|
|
||||||
this.worker.onmessage = this.#onMessage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static shuffleArray(array) {
|
|
||||||
let currentIndex = array.length;
|
|
||||||
while (currentIndex) {
|
|
||||||
let j = Math.floor(Math.random() * currentIndex);
|
|
||||||
let t = array[--currentIndex];
|
|
||||||
array[currentIndex] = array[j];
|
|
||||||
array[j] = t;
|
|
||||||
}
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
|
|
||||||
static capsuleExecute(funText, target, players) {
|
|
||||||
this.worker.postMessage({ type: "run", function: funText, target: target, players: players });
|
|
||||||
}
|
|
||||||
|
|
||||||
// Worker Commands
|
|
||||||
static #onMessage(e) {
|
|
||||||
switch (e.data.type) {
|
|
||||||
case "game":
|
|
||||||
switch (e.data.game.command) {
|
|
||||||
case "discard":
|
|
||||||
controller.cardCommands.remove(e.data.game.target.clientId, e.data.game.card, null, true);
|
|
||||||
break;
|
|
||||||
case "selectCard":
|
|
||||||
controller.cardCommands.selectCard(e.data.game.target.clientId, e.data.game.card, null, true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,15 +4,16 @@ const firstCardCount = 5;
|
|||||||
class HostController {
|
class HostController {
|
||||||
playerController = null;
|
playerController = null;
|
||||||
deck = new Array();
|
deck = new Array();
|
||||||
discarded = new Array();
|
discards = new Array();
|
||||||
players = new Map();
|
players = new Map();
|
||||||
turnOrder;
|
turnOrder;
|
||||||
turn = -1;
|
turn = -1;
|
||||||
latestWaitingId = 0;
|
latestWaitingId = 0;
|
||||||
waiting = new Map();
|
waitings = new Map();
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.playerController = new PlayerController();
|
this.playerController = new PlayerController();
|
||||||
|
EXOUtils.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
async gameStart() {
|
async gameStart() {
|
||||||
@ -32,54 +33,64 @@ class HostController {
|
|||||||
// 山札をシャッフル
|
// 山札をシャッフル
|
||||||
EXOUtils.shuffleArray(this.deck);
|
EXOUtils.shuffleArray(this.deck);
|
||||||
|
|
||||||
|
console.log([...this.deck]);
|
||||||
|
|
||||||
await this.distributionCards();
|
await this.distributionCards();
|
||||||
this.nextTurn();
|
this.nextTurn();
|
||||||
}
|
}
|
||||||
|
|
||||||
async distributionCards() {
|
async distributionCards() {
|
||||||
for (let i = 0; i < firstCardCount; ++i) {
|
for (let i = 0; i < firstCardCount; ++i) {
|
||||||
for (const player of this.players) {
|
for (const playerId of this.turnOrder) {
|
||||||
await player[1].addCard(this.deck[0]);
|
await this.players.get(playerId).addCard(this.deck.splice(0, 1)[0]);
|
||||||
this.deck.splice(0, 1);
|
|
||||||
await new Promise(resolve => setTimeout(resolve, 700));
|
await new Promise(resolve => setTimeout(resolve, 700));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
// プレイヤーに5枚ずつ配布
|
|
||||||
for (const player of this.players) {
|
|
||||||
// 本人通達用
|
|
||||||
let messageBuilder = new MessageBuilder(player[0]).game();
|
|
||||||
// 他人通達用
|
|
||||||
let messageBuilderForRoom = new MessageBuilder().game();
|
|
||||||
for (let j = 0; j < firstCardCount; ++j) {
|
|
||||||
player[1].cards.push(this.deck[0]);
|
|
||||||
messageBuilder.addCommand(commands.addCard, player[0], this.deck[0].cardType.id, this.deck[0].idIndex);
|
|
||||||
messageBuilderForRoom.addCommand(commands.addCard, player[0], cardTypes.unknown.id, -1)
|
|
||||||
this.deck.splice(0, 1);
|
|
||||||
|
|
||||||
}
|
|
||||||
messageBuilder.send();
|
|
||||||
messageBuilderForRoom.send();
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async nextTurn() {
|
async nextTurn() {
|
||||||
// ターンを進める
|
// ターンを進める
|
||||||
++this.turn;
|
++this.turn;
|
||||||
if (this.turnOrder.length >= this.turn) this.turn = 0;
|
if (this.turnOrder.length <= this.turn) this.turn = 0;
|
||||||
|
|
||||||
const turnPlayer = players[this.turnOrder[this.turn]];
|
const turnPlayer = this.players.get(this.turnOrder[this.turn]);
|
||||||
// カードを一枚引く
|
// カードを一枚引く
|
||||||
await turnPlayer.addCard(this.deck[0]);
|
await turnPlayer.addCard(this.deck.splice(0, 1)[0]);
|
||||||
this.deck.splice(0, 1);
|
|
||||||
await new Promise(resolve => setTimeout(resolve, 700));
|
await new Promise(resolve => setTimeout(resolve, 700));
|
||||||
|
|
||||||
// 操作待ち
|
// 操作待ち
|
||||||
|
this.cardCommands.selectCards((selectedBy, targetStockId, ...cardsIndex)=>{
|
||||||
|
const stock = this.cardCommands.getStock(targetStockId);
|
||||||
|
stock[cardsIndex[0]].cardType.onGet;
|
||||||
|
}, turnPlayer.clientId, turnPlayer.clientId, 1);
|
||||||
|
//if (!this.waiting.has(turnPlayer.clientId)) this.waiting.set(turnPlayer.clientId, []);
|
||||||
|
//this.waiting.get(turnPlayer.clientId).push(commands.useCard);
|
||||||
}
|
}
|
||||||
|
|
||||||
onGameMessage(message) {
|
onGameMessage(message) {
|
||||||
if (message.body.side != side.host)
|
if (message.body.side === side.player || message.body.side === side.both)
|
||||||
this.playerController.onGameMessage(message);
|
this.playerController.onGameMessage(message);
|
||||||
|
if (message.body.side === side.host || message.body.side === side.both)
|
||||||
|
message.body.commands.forEach(command => {
|
||||||
|
switch (command.name) {
|
||||||
|
case commands.waiting:
|
||||||
|
if (!this.waitings.has(command.args[0])) return;
|
||||||
|
const waiting = this.waitings.get(command.args[0]);
|
||||||
|
if (message.from !== waiting.args[0]) return;
|
||||||
|
waiting.onOperation(...waiting.args, ...command.args);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
/*
|
||||||
|
if (message.body.side !== side.host && message.body.side !== side.both) return;
|
||||||
|
message.body.commands.forEach(command => {
|
||||||
|
if (!this.waiting.get(message.from)?.includes(command.name)) return;
|
||||||
|
switch (command.name) {
|
||||||
|
case commands.useCard:
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});*/
|
||||||
}
|
}
|
||||||
|
|
||||||
joinNewPlayer(obj) {
|
joinNewPlayer(obj) {
|
||||||
@ -89,29 +100,75 @@ class HostController {
|
|||||||
messageBuilder.send();
|
messageBuilder.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
clientOperations = {
|
|
||||||
selectedCards: () => { }
|
|
||||||
}
|
|
||||||
|
|
||||||
cardCommands = {
|
cardCommands = {
|
||||||
remove: (target, card, index, canRecycle) => {
|
remove: (targetId, card, index, canRecycle) => {
|
||||||
const player = controller.players.get(target);
|
const player = this.players.get(targetId);
|
||||||
index = player.cards.findIndex(it => it.id == card.id && it.cardType.id == card.cardType.id);
|
index = player.cards.findIndex(it => it.id == card.id && it.cardType.id == card.cardType.id);
|
||||||
card = player.cards[index];
|
card = player.cards[index];
|
||||||
if (canRecycle)
|
if (canRecycle)
|
||||||
this.discarded.push(...player.cards.splice(index, 1));
|
this.discards.push(...player.cards.splice(index, 1));
|
||||||
else
|
else
|
||||||
this.cardCommands.backIntoDeck(card);
|
this.cardCommands.backIntoDeck(card);
|
||||||
new MessageBuilder().game().addCommand(commands.worker, target, "remove", [target, { cardType: { id: card.cardType.id }, idIndex: card.idIndex }, index, canRecycle]).send();
|
new MessageBuilder().game().addCommand(commands.worker, targetId, "remove", [targetId, { cardType: { id: card.cardType.id }, idIndex: card.idIndex }, index, canRecycle]).send();
|
||||||
},
|
},
|
||||||
backIntoDeck: (card) => {
|
backIntoDeck: (card) => {
|
||||||
this.deck.splice(Math.floor(Math.random() * (this.deck.length + 1)), 0, card);
|
this.deck.splice(Math.floor(Math.random() * (this.deck.length + 1)), 0, card);
|
||||||
},
|
},
|
||||||
selectCard: (target, count, waitingId) => {
|
selectCards: (callback, targetId, targetStockId, count) => {
|
||||||
const player = controller.players.get(target);
|
const waitingId = ++this.latestWaitingId;
|
||||||
waitingId = ++this.latestWaitingId;
|
this.waitings.set(waitingId, { onOperation: this.clientOperations.useCards, targetId: targetId, args: [callback, targetId, targetStockId, count] });
|
||||||
this.waiting.set(waitingId, this.clientOperations.selectedCards);
|
new MessageBuilder(targetId).game().addCommand(commands.worker, targetId, "selectCards", [targetId, targetStockId, count, waitingId]).send();
|
||||||
new MessageBuilder(target).game().addCommand(commands.worker, target, "selectCard", [target, count, waitingId]).send();
|
},
|
||||||
|
getStock: (stockId) => {
|
||||||
|
if (stockId === "DISCARDS") return this.discards;
|
||||||
|
return this.players?.get(stockId).cards;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
clientOperations = {
|
||||||
|
useCards: (callback, selectedBy, targetStockId, count, waitingId, ...cardsIndex) => {
|
||||||
|
if (cardsIndex.length != Number(count)) { console.log("count missmatch"); return; }
|
||||||
|
callback(selectedBy, targetStockId, ...cardsIndex);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
class EXOUtils {
|
||||||
|
static worker;
|
||||||
|
|
||||||
|
static init() {
|
||||||
|
this.worker = new Worker("static/js/card-module.js");
|
||||||
|
this.worker.onmessage = this.#onMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
static shuffleArray(array) {
|
||||||
|
let currentIndex = array.length;
|
||||||
|
while (currentIndex) {
|
||||||
|
let j = Math.floor(Math.random() * currentIndex);
|
||||||
|
let t = array[--currentIndex];
|
||||||
|
array[currentIndex] = array[j];
|
||||||
|
array[j] = t;
|
||||||
|
}
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
static capsuleExecute(funText, target) {
|
||||||
|
this.worker.postMessage({ type: "run", function: funText, target: target, players: controller.players });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Worker Commands
|
||||||
|
static #onMessage(e) {
|
||||||
|
switch (e.data.type) {
|
||||||
|
case "game":
|
||||||
|
switch (e.data.game.command) {
|
||||||
|
case "discard":
|
||||||
|
controller.cardCommands.remove(e.data.game.target.clientId, e.data.game.card, null, true);
|
||||||
|
break;
|
||||||
|
case "selectCards":
|
||||||
|
controller.cardCommands.selectCards(e.data.game.target.clientId, e.data.game.card, null, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -38,11 +38,18 @@ class PlayerController {
|
|||||||
joinNewPlayer() { }
|
joinNewPlayer() { }
|
||||||
|
|
||||||
cardCommands = {
|
cardCommands = {
|
||||||
remove: (target, card, index, canRecycle) => {
|
remove: (targetId, card, index, canRecycle) => {
|
||||||
const player = this.players.get(target);
|
const player = this.players.get(targetId);
|
||||||
player.cards.splice(index, 1);
|
player.cards.splice(index, 1);
|
||||||
if (canRecycle)
|
if (canRecycle)
|
||||||
this.discarded.push(new Card(cardTypes[card.cardType.id], card.idIndex));
|
this.discarded.push(new Card(cardTypes[card.cardType.id], card.idIndex));
|
||||||
},
|
},
|
||||||
|
selectCards: (targetId, targetStockId, count, waitingId) => {
|
||||||
|
/* TODO */
|
||||||
|
console.log(`selectCards,from: ${targetStockId}, count: ${count}, waitingId: ${waitingId}`);
|
||||||
|
},
|
||||||
|
selectedCards: (waitingId, targetStockId, ...cardsIndex) => {
|
||||||
|
new MessageBuilder(this.hostClientId, side.host).game().addCommand(commands.waiting, clientId, "selectedCards", [waitingId, ...cardsIndex]).send();
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user