diff --git a/data.js b/data.js
index 3b12cb1..13fa0e4 100644
--- a/data.js
+++ b/data.js
@@ -98,7 +98,18 @@ module.exports.ROOMS = {
{ file: "likelike-backyard-chairs.png", position: [33, 44] },
]
+ },
+ //just an empty room for testing mods
+ experiments: {
- },
+ bg: "experiments-bg.png",
+ avatarScale: 2,
+ pageBg: "#bfaeae",
+ area: "experiments-areas.png",
+ tint: "#FFFFFF",
+ bubblesY: 50,
+ spawn: [15, 77, 113, 96]
+
+ }
};
\ No newline at end of file
diff --git a/public/assets/experiments-areas.png b/public/assets/experiments-areas.png
new file mode 100755
index 0000000..6683429
Binary files /dev/null and b/public/assets/experiments-areas.png differ
diff --git a/public/assets/experiments-bg.png b/public/assets/experiments-bg.png
new file mode 100755
index 0000000..423c109
Binary files /dev/null and b/public/assets/experiments-bg.png differ
diff --git a/public/client.js b/public/client.js
index 0d4be97..929e176 100644
--- a/public/client.js
+++ b/public/client.js
@@ -136,6 +136,7 @@ var allSheets;
//current room bg and areas
var bg;
var areas;
+var room; //the id
//command quequed for when the destination is reached
var nextCommand;
@@ -620,6 +621,7 @@ function newGame() {
//if it's me///////////
if (socket.id == p.id) {
+ rolledSprite = null;
//the location appears in the url
if (ROOM_LINK && ROOMS[p.room] != null)
@@ -642,6 +644,7 @@ function newGame() {
me.sprite.onMousePressed = function () { socket.emit('emote', { room: me.room, em: true }); };
me.sprite.onMouseReleased = function () { socket.emit('emote', { room: me.room, em: false }); };
+ room = p.room;
//if a page background is specified change it
if (ROOMS[p.room].pageBg != null)
@@ -724,8 +727,12 @@ function newGame() {
}
+ //initialize the mod if any
+ if (window.initMod != null) {
+ window.initMod(p.id, p.room);
+ }
- }
+ }//it me
else {
//
players[p.id] = new Player(p);
@@ -765,6 +772,11 @@ function newGame() {
console.log("There are now " + Object.keys(players).length + " players in this room");
+ //calling a custom function roomnameEnter if it exists
+ if (window[p.room + "Enter"] != null) {
+ window[p.room + "Enter"](p.id, p.room);
+ }
+
}
catch (e) {
console.log("Error on playerJoined");
@@ -814,6 +826,12 @@ function newGame() {
console.log("Player " + p.id + " left");
if (players[p.id] != null) {
+
+ //calling a custom function roomnameEnter if it exists
+ if (window[p.room + "Exit"] != null) {
+ window[p.room + "Exit"](p.id);
+ }
+
if (p.disconnect && players[p.id].nickName != "") {
var spark = createSprite(players[p.id].x, players[p.id].y - AVATAR_H + 1);
spark.addAnimation("spark", disappearEffect);
@@ -861,12 +879,18 @@ function newGame() {
var offY = ROOMS[me.room].bubblesY * ASSET_SCALE;
var newBubble = new Bubble(p.id, p.message, p.color, p.x, p.y, offY);
+ //calling a custom function
+ if (window[me.room + "Talk"] != null) {
+ window[me.room + "Talk"](p.id, newBubble);
+ }
+
pushBubbles(newBubble);
bubbles.push(newBubble);
if (SOUND) {
blips[floor(random(0, blips.length))].play();
}
+
}
}
} catch (e) {
@@ -1017,6 +1041,12 @@ function update() {
text(errorMessage, floor(WIDTH / 8), floor(HEIGHT / 8), WIDTH - floor(WIDTH / 4), HEIGHT - floor(HEIGHT / 4) + 1);
}
else if (screen == "game") {
+
+ //calling a custom function
+ if (window[room + "Update"] != null) {
+ window[room + "Update"]();
+ }
+
//draw a background
background(UI_BG);
imageMode(CORNER);
@@ -1501,6 +1531,7 @@ function Player(p) {
this.sprite.id = this.id;
this.sprite.label = p.nickName;
this.sprite.transparent = false;
+ this.sprite.roomId = p.room; //sure anything goes
//save the dominant color for bubbles and rollover label
var c = color(AVATAR_PALETTES[p.color][2]);
@@ -1563,7 +1594,12 @@ function Player(p) {
if (this.transparent)
tint(255, 100);
- this.originalDraw();
+ if (window[this.roomId + "DrawSprite"] != null) {
+ window[this.roomId + "DrawSprite"](this.id, this, this.originalDraw);
+ }
+ else {
+ this.originalDraw();
+ }
if (this.transparent)
noTint();
@@ -1671,7 +1707,12 @@ function isObstacle(x, y, room, a) {
if (room != null && a != null) {
- var c1 = a.get(x, y);
+ //you know, at this point I'm not sure if you are using assets scaled by 2 for the areas
+ //so I'm just gonna stretch the coordinates ok
+ var px = floor(map(x, 0, WIDTH, 0, a.width));
+ var py = floor(map(y, 0, HEIGHT, 0, a.height));
+
+ var c1 = a.get(px, py);
//if not white check if color is obstacle
if (c1[0] != 255 || c1[1] != 255 || c1[2] != 255) {
@@ -1717,7 +1758,13 @@ function mouseMoved() {
walkIcon.visible = false;
if (areas != null && me != null) {
- var c = areas.get(mouseX, mouseY);
+
+ //you know, at this point I'm not sure if you are using assets scaled by 2 for the areas
+ //so I'm just gonna stretch the coordinates ok
+ var mx = floor(map(mouseX, 0, WIDTH, 0, areas.width));
+ var my = floor(map(mouseY, 0, HEIGHT, 0, areas.height));
+
+ var c = areas.get(mx, my);
areaLabel = "";
if (alpha(c) != 0 && me.room != null) {
@@ -1797,7 +1844,12 @@ function canvasReleased() {
//check the area info
else if (areas != null && me.room != null) {
- var c = areas.get(mouseX, mouseY);
+ //you know, at this point I'm not sure if you are using assets scaled by 2 for the areas
+ //so I'm just gonna stretch the coordinates ok
+ var mx = floor(map(mouseX, 0, WIDTH, 0, areas.width));
+ var my = floor(map(mouseY, 0, HEIGHT, 0, areas.height));
+
+ var c = areas.get(mx, my);
//if transparent or semitransparent do nothing
if (alpha(c) != 255) {
diff --git a/public/index.html b/public/index.html
index 3c94f43..e9f09f9 100644
--- a/public/index.html
+++ b/public/index.html
@@ -34,6 +34,7 @@
+
diff --git a/public/mod.js b/public/mod.js
new file mode 100644
index 0000000..3a85ae5
--- /dev/null
+++ b/public/mod.js
@@ -0,0 +1,84 @@
+/*
+WARNING: THIS IS STILL EXPERIMENTAL STUFF
+I want to have the ability to assign specific behaviors to each room without messing with the main engine
+So this is a file for client-side modifications (mods). There is one for the server side as well.
+Their naming convention is roomIdFunction.
+The functions are called by the engine at crucial points, only if they exist.
+*/
+
+//when my players joins the game for the first time, after everything in the room is initialized
+//called also for lurk mode (nickName == "")
+function initMod(playerId, roomId) {
+ print("Mod: " + players[playerId].nickName + " joined the game at " + roomId)
+}
+
+//roomnameEnter: called when a player enters a room, after all the normal operations
+//called also for lurk mode (nickName == "")
+function experimentsEnter(playerId, roomId) {
+ print("MOD: " + players[playerId].nickName + " entered room " + roomId);
+
+ //a full screen welcome text appears
+ longText = "Welcome " + players[playerId].nickName;
+ longTextLines = -1;
+ longTextAlign = "center";
+}
+
+//roomnameExit: called right before a player exits or disconnects
+function experimentsExit(playerId) {
+ print("MOD: " + players[playerId].nickName + " exited room " + roomId);
+}
+
+//called every frame in a specific room - beware: this is client side, everything non deterministic and non server-driven
+//may misalign the players clients
+function experimentsUpdate() {
+ //print("MOD: updating experiments");
+}
+
+//roomnameTalk: called when somebody in the room talks, passes player object and the new bubble (before it's added to the stack and before the sound is made)
+function experimentsTalk(playerId, bubble) {
+ print("MOD: " + players[playerId].nickName + " said " + bubble.message);
+
+ //overwrites the color
+ bubble.color = color("#FFFFFF");
+ //all bubbles show up in the center and lines are not drawn
+ /*
+ bubble.x = WIDTH / 2 - bubble.w / 2;
+ bubble.y = HEIGHT / 2;
+ bubble.px = 0;
+ bubble.py = 0;
+ */
+}
+
+//this can override or modify the normal player drawing function
+function experimentsDrawSprite(playerId, sprite, drawingFunction) {
+ //print("MOD: " + players[playerId].nickName + " being drawn experimentally " + sprite.width); //let's not call this at every frame
+
+ //the normal drawing function comment this out to see the examples below
+ drawingFunction();
+
+ /*
+ //don't try this
+ tint(random(0, 255), random(0, 255), random(0, 255));
+ drawingFunction();
+ noTint();
+ */
+
+ //draw a square
+ /*
+ fill(0);
+ rect(0, 0, 10, 10);
+ */
+
+ /*
+ //sprites drawn horizontally and 20 pixel above the grund
+ push();
+ translate(0, -20);
+ angleMode(DEGREES);
+ rotate(90);
+ //the original drawing function
+ drawingFunction();
+ pop();
+ */
+
+}
+
diff --git a/server.js b/server.js
index 1f908a2..5df4195 100644
--- a/server.js
+++ b/server.js
@@ -10,6 +10,14 @@ ADMINS=username1|pass1,username2|pass2
PORT = 3000
*/
+var MOD = {};
+//load server side mod file
+try {
+ MOD = require('./serverMod');
+}
+catch (e) {
+}
+
var port = process.env.PORT || 3000;
//number of emits per second allowed for each player, after that ban the IP.
@@ -219,6 +227,12 @@ io.on('connection', function (socket) {
if (playerInfo.nickName != "")
visits++;
+ //check if there is a custom function in the MOD to call at this point
+ if (MOD["joinGame"] != null) {
+ //call it!
+ MOD["joinGame"](newPlayer, playerInfo.room);
+ }
+
//send all players information about the new player
//upon creation destination and position are the same
io.to(playerInfo.room).emit('playerJoined', newPlayer);
@@ -307,7 +321,22 @@ io.on('connection', function (socket) {
console.log(socket.id + " is problematic");
}
else {
- io.to(obj.room).emit('playerTalked', { id: socket.id, color: obj.color, message: obj.message, x: obj.x, y: obj.y });
+
+ //check if there is a custom function in the MOD to call at this point
+ if (MOD[obj.room + "TalkFilter"] != null) {
+
+ //call it!
+ obj.message = MOD[obj.room + "TalkFilter"](gameState.players[socket.id], obj.message);
+
+ if (obj.message == null) {
+ console.log("MOD: Warning - TalkFilter should return a message ");
+ obj.message = "";
+ }
+
+ }
+
+ if (obj.message != "")
+ io.to(obj.room).emit('playerTalked', { id: socket.id, color: obj.color, message: obj.message, x: obj.x, y: obj.y });
}
}
@@ -343,10 +372,10 @@ io.on('connection', function (socket) {
else {
//console.log("Player " + socket.id + " moved from " + obj.from + " to " + obj.to);
-
socket.leave(obj.from);
socket.join(obj.to);
+
//broadcast the change to everybody in the current room
//from the client perspective leaving the room is the same as disconnecting
io.to(obj.from).emit('playerLeft', { id: socket.id, disconnect: false });
@@ -357,6 +386,19 @@ io.on('connection', function (socket) {
playerObject.x = playerObject.destinationX = obj.x;
playerObject.y = playerObject.destinationY = obj.y;
playerObject.new = false;
+
+ //check if there is a custom function in the MOD to call at this point
+ if (MOD[obj.from + "Exit"] != null) {
+ //call it!
+ MOD[obj.from + "Exit"](playerObject, obj.from);
+ }
+
+ //check if there is a custom function in the MOD to call at this point
+ if (MOD[obj.to + "Enter"] != null) {
+ //call it!
+ MOD[obj.to + "Enter"](playerObject, obj.to);
+ }
+
io.to(obj.to).emit('playerJoined', playerObject);
}
} catch (e) {
@@ -667,5 +709,6 @@ let myBadWords = ['chink', 'cunt', 'cunts', "fag", "fagging", "faggitt", "faggot
var filter = new Filter({ emptyList: true });
filter.addWords(...myBadWords);
-
+//p5 style alias
+function print(s) { console.log(s); }
diff --git a/serverMod.js b/serverMod.js
new file mode 100644
index 0000000..445b587
--- /dev/null
+++ b/serverMod.js
@@ -0,0 +1,33 @@
+/*
+WARNING: THIS IS STILL EXPERIMENTAL STUFF
+I want to have the ability to assign specific behaviors to each room without messing with the main engine
+So I'm creating a module for server-side modifications (mods). There is one also for the client.
+Their naming convention is roomIdFunction.
+The functions are called by the engine at crucial points, only if they exist.
+*/
+
+module.exports.joinGame = function (player, roomId) {
+ //console.log("MOD: Player " + player.nickName + " joined the game at room " + roomId);
+
+ //objects are passed by reference so this actually changes the nickname on the server (but not on the client)
+ //player.nickName = "Dude";
+}
+
+//custom function called on the server side when a player successfully enters or exits the room
+//executed before it's broadcast to the other players
+module.exports.experimentsEnter = function (player, roomId) {
+ console.log("MOD: " + player.nickName + " entered room " + roomId);
+}
+
+module.exports.experimentsExit = function (player, roomId) {
+ console.log("MOD: " + player.nickName + " exited room " + roomId);
+}
+
+//wouldn't it be funny if cetain rooms modified your messages?
+module.exports.experimentsTalkFilter = function (player, message) {
+
+ console.log("MOD: " + player.nickName + " said " + message);
+ message = message.replace(/[aeiou]/ig, '');
+ //make sure it returns a message
+ return message;
+}
\ No newline at end of file