Skip to content

Commit 0a5c4c1

Browse files
author
thomasmckay
authored
Working first implementation (#2)
1 parent c26f727 commit 0a5c4c1

12 files changed

+8753
-8701
lines changed

.eslintrc.js

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
module.exports = {
2+
"env": {
3+
"browser": true
4+
},
5+
"extends": "eslint:recommended",
6+
"parser": "babel-eslint",
7+
"parserOptions": {
8+
"ecmaVersion": 5
9+
},
10+
"rules": {
11+
"indent": [
12+
"error",
13+
4,
14+
{
15+
"CallExpression": {
16+
"arguments": "first"
17+
}
18+
}
19+
],
20+
"linebreak-style": [
21+
"error",
22+
"unix"
23+
],
24+
"quotes": [
25+
"error",
26+
"double"
27+
],
28+
"semi": [
29+
"error",
30+
"always"
31+
]
32+
},
33+
"globals": {
34+
"GloomhavenMonsterStats": false,
35+
"GloomhavenModule": false,
36+
"on": false,
37+
"sendChat": false,
38+
"Shell": false,
39+
"getObj": false,
40+
"findObjs": false,
41+
"createObj": false,
42+
}
43+
};

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
node_modules
2+
package-lock.json
3+
build/**
4+

Makefile

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
BUILD_DIR=build
2+
3+
GLOOMHAVEN_FILES = \
4+
gloomhaven.js \
5+
gloomhaven_cards.js \
6+
gloomhaven_deck_builder.js \
7+
gloomhaven_monster_card.js \
8+
gloomhaven_monster_stats.js \
9+
gloomhaven_set_level.js
10+
11+
#BUILD_FILES := $(addprefix $(BUILD_DIR)/, $(GLOOMHAVEN_FILES))
12+
13+
all: build
14+
15+
build: $(BUILD_DIR)/build.js upload
16+
17+
$(BUILD_DIR)/build.js: $(GLOOMHAVEN_FILES)
18+
mkdir -p $(@D)
19+
$(RM) $@
20+
cat $^ >> $@
21+
22+
GAME=3922546
23+
SCRIPT=313710
24+
upload:
25+
cd build && \
26+
rm -f roll20*.cookies && \
27+
curl \
28+
--verbose \
29+
-c roll20.cookies \
30+
-H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' \
31+
-H 'Accept-Encoding: br, gzip, deflate' \
32+
-H 'Host: app.roll20.net' \
33+
-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Safari/605.1.15' \
34+
-H 'Accept-Language: en-us' \
35+
-d @login.txt \
36+
-o roll20_login.response https://app.roll20.net/sessions/create \
37+
--next \
38+
--verbose \
39+
-H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' \
40+
-H 'Host: app.roll20.net' \
41+
-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Safari/605.1.15' \
42+
-H 'Accept-Language: en-us' \
43+
-H 'Referer: https://app.roll20.net/sessions/create' \
44+
https://app.roll20.net/campaigns/save_script/$(GAME)/$(SCRIPT) \
45+
--data-urlencode 'name=build.js' \
46+
--data-urlencode [email protected] \
47+
2> /dev/null
48+

README.md

+16
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,18 @@
11
# roll20-gloomhaven
22
Roll20.net scripts to setup Gloomhaven tabletop scenarios and play
3+
4+
## !GH build-deck
5+
6+
To easily create custom card decks, follow these steps.
7+
8+
First, create a page dedicated to your deck. All *graphic* objects on the page will be considered during deck building. (*Note:* This means you can add *text* or other object types to the page if desired for readability or other reasons.)
9+
10+
Next, create the card deck back by placing an image token on the page. This image will be used when the deck is shown through *roll20.net*. In addition, both the name attribute of the token as well as the size are used during deck creation and play.
11+
12+
The *name* attribute will be used to find an existing deck to update, or the name of a new deck to create. (*Note:* To quickly make multiple decks consisting of the same cards, simply change the *name* and re-run the *build-deck* command.)
13+
14+
The *size* of the image token will determine the size of the cards when played. This deck attribute, along with other standard deck options, may be edited after creation normally; it is there for convenience.
15+
16+
All other graphic objects on the page without the *name* attribute equal to the deck name will be used as the cards in the deck. (*Note:* Since running *build-deck* updates existing decks, adding or removing cards during game play is simply a matter of changing the images on the page.)
17+
18+
![Card deck page](/documentation/build-deck.png)

documentation/build-deck.png

403 KB
Loading

gloomhaven.js

+156
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
//var Gloomhaven = Gloomhaven || (function() {
2+
var Gloomhaven = (function () {
3+
var GLOOMHAVEN_COMMAND = "!GH";
4+
5+
var GLOOMHAVEN_COMMANDS = {};
6+
7+
function numify(x){
8+
var xNum = x;
9+
if (typeof(x) == typeof("")){
10+
if (x.charAt(0) == "+"){ x = x.substring(1); }
11+
xNum = parseFloat(x);
12+
}
13+
if ("" + xNum == "" + x){ return xNum; }
14+
return x;
15+
}
16+
17+
function getCleanImgsrc(imgsrc) {
18+
var parts = imgsrc.match(/(.*\/images\/.*)(thumb|med|original|max)([^?]*)(\?[^?]+)?$/);
19+
if(parts) {
20+
return parts[1]+"thumb"+parts[3]+(parts[4]?parts[4]:`?${Math.round(Math.random()*9999999)}`);
21+
}
22+
return;
23+
}
24+
25+
function rawWrite(s, who, style, from) {
26+
if (who) {
27+
who = "/w " + who.split(" ", 1)[0] + " ";
28+
}
29+
sendChat(from, who + s.replace(/\n/g, "<br>"));
30+
}
31+
32+
function write(s, who, style, from) {
33+
return rawWrite(s.replace(/</g, "&lt;").replace(/>/g, "&gt;"), who, style, from);
34+
}
35+
36+
// https://gist.github.com/kkragenbrink/5499147
37+
function sprintf(f) {
38+
var formatRegexp = /%[sdj%]/g;
39+
var args = Array.prototype.slice.call(arguments, 0);
40+
var argl = args.length;
41+
42+
if (typeof f !== 'string') {
43+
var objects = [];
44+
while (argl--) {
45+
objects.unshift(args[i].toString());
46+
}
47+
48+
return objects.join(' ');
49+
}
50+
51+
var i = 1;
52+
var str = String(f).replace(formatRegexp, function (x) {
53+
if (x === '%%') {
54+
return '%';
55+
}
56+
if (i >= args) {
57+
return x;
58+
}
59+
switch (x) {
60+
case '%s' : return String(args[i++]);
61+
case '%d' : return Number(args[i++]);
62+
case '%j' : return JSON.stringify(args[i++]);
63+
default:
64+
return x;
65+
}
66+
});
67+
68+
var x;
69+
while (i++ < argl) {
70+
x = args[i];
71+
if (x === null || typeof x !== 'object') {
72+
str = [str, x].join(' ')
73+
} else {
74+
str += [str, x.toString()].join();
75+
}
76+
}
77+
78+
return str;
79+
}
80+
81+
function showHelp(who) {
82+
var helpMsg = "";
83+
helpMsg += "TODO: print out allowed commands";
84+
write(helpMsg, who, "", "GH");
85+
}
86+
87+
function handleGloomhavenMessage(tokens, msg) {
88+
var command = tokens[1];
89+
var args = tokens.slice(2);
90+
91+
write("Command: " + command, msg.who, "", "OP");
92+
write("Args: " + args, msg.who, "", "OP");
93+
94+
if (command === undefined) {
95+
showHelp(msg.who);
96+
return;
97+
}
98+
99+
if (GLOOMHAVEN_COMMANDS[command] === undefined) {
100+
write("Unrecognized command '" + command + "'", msg.who, "", "OP");
101+
showHelp(msg.who);
102+
return;
103+
}
104+
105+
GLOOMHAVEN_COMMANDS[command].run(msg, args);
106+
107+
return;
108+
}
109+
110+
function handleChatMessage(msg) {
111+
if ((msg.type !== "api") || msg.content.indexOf(GLOOMHAVEN_COMMAND) !== 0) {
112+
return;
113+
}
114+
115+
return handleGloomhavenMessage(msg.content.split(" "), msg);
116+
}
117+
118+
function registerCommands() {
119+
/* eslint-disable no-undef */
120+
GLOOMHAVEN_COMMANDS["set-level"] = GloomhavenSetLevelCommand;
121+
GLOOMHAVEN_COMMANDS["monster-card"] = GloomhavenMonsterCardCommand;
122+
GLOOMHAVEN_COMMANDS["build-deck"] = GloomhavenDeckBuilderCommand;
123+
/* eslint-enable no-undef */
124+
if ((typeof(Shell) != "undefined") && (Shell) && (Shell.registerCommand)) {
125+
Shell.registerCommand(GLOOMHAVEN_COMMAND, "!GH command", "Gloomhaven command",
126+
handleGloomhavenMessage);
127+
/* eslint-disable no-func-assign */
128+
if (Shell.rawWrite) {
129+
rawWrite = Shell.rawWrite;
130+
}
131+
if (Shell.write) {
132+
write = Shell.write;
133+
}
134+
/* eslint-enable no-func-assign */
135+
}
136+
else{
137+
on("chat:message", handleChatMessage);
138+
}
139+
}
140+
141+
var scenarioLevel = 1;
142+
143+
return {
144+
scenarioLevel: scenarioLevel,
145+
registerCommands: registerCommands,
146+
numify: numify,
147+
sprintf: sprintf,
148+
write: write,
149+
rawWrite: rawWrite,
150+
getCleanImgsrc: getCleanImgsrc
151+
};
152+
}());
153+
154+
on("ready", function () {
155+
Gloomhaven.registerCommands();
156+
});

0 commit comments

Comments
 (0)