diff --git a/index.html b/index.html
index f239eed..84ac370 100644
--- a/index.html
+++ b/index.html
@@ -20,17 +20,19 @@
+
-
-
+
+
+
diff --git a/js/common/being.js b/js/common/being.js
index cc38855..53bf5fa 100644
--- a/js/common/being.js
+++ b/js/common/being.js
@@ -112,10 +112,14 @@ Game.Being.prototype.getMaxHP = function() {
Game.Being.prototype.adjustHP = function(diff) {
this._hp = Math.max(0, this._hp + diff);
- if (!this._hp) { this._die(); }
+ if (!this._hp) { this.die(); }
return this;
}
+Game.Being.prototype.getWeapon = function() {
+ return this._weapon;
+}
+
Game.Being.prototype.attack = function(target) {
/* FIXME probably refactor to a dedicated attack logic? */
@@ -151,7 +155,7 @@ Game.Being.prototype.attack = function(target) {
Game.status.show(str);
}
-Game.Being.prototype._die = function() {
+Game.Being.prototype.die = function() {
var corpse = Game.Items.create("corpse", {color:this._color, name:this._name+" corpse"});
this._level.setItem(corpse, this._position[0], this._position[1]);
this._level.removeBeing(this);
diff --git a/js/common/level.js b/js/common/level.js
index 781dfba..f34c06e 100644
--- a/js/common/level.js
+++ b/js/common/level.js
@@ -3,7 +3,7 @@ Game.Level = function() {
this.beings = {};
this.items = {};
- this._display = new ROT.Display({fontFamily:"droid sans mono, monospace"});
+ this._display = new Game.Display({fontFamily:"droid sans mono, monospace"});
this._ambientLight = [130, 130, 130];
this._sightRange = 8;
@@ -290,7 +290,10 @@ Game.Level.prototype._draw = function(x, y) {
if (!(key in this._visibleArea)) { return; }
var entity = this.beings[key] || this.items[key] || this.cells[key];
- if (entity) { this._display.draw(x, y, entity.getChar(), ROT.Color.toRGB(entity.getColor())); }
+ if (entity) {
+ this._display.draw(x, y, entity.getChar(), ROT.Color.toRGB(entity.getColor()));
+ if (entity == Game.player) { this._display.setCursor(x, y); }
+ }
}
Game.Level.prototype._drawFog = function(x, y) {
@@ -309,7 +312,6 @@ Game.Level.prototype._drawFog = function(x, y) {
/* 3. average */
var gray = (color[0]+color[1]+color[2])/3;
-
var c1 = 0.4;
var c2 = 1-c1;
diff --git a/js/common/lib/beings.js b/js/common/lib/beings.js
index 588c716..531e944 100644
--- a/js/common/lib/beings.js
+++ b/js/common/lib/beings.js
@@ -4,6 +4,11 @@ Game.Beings.define("animal", {
tasks: ["wander"]
});
+Game.Beings.define("humanoid", {
+ tasks: ["wander"],
+ "char": "@"
+});
+
Game.Beings.define("dog", {
extend: "animal",
name: "dog",
@@ -11,10 +16,6 @@ Game.Beings.define("dog", {
"char": "d"
});
-Game.Beings.define("humanoid", {
- tasks: ["wander"],
-});
-
Game.Beings.define("rat", {
extend: "animal",
name: "rat",
@@ -24,7 +25,6 @@ Game.Beings.define("rat", {
Game.Beings.define("mugger", {
extend: "humanoid",
- "char": "M",
name: "mugger",
color: [160, 100, 100],
chats: [
diff --git a/js/common/lib/cells.js b/js/common/lib/cells.js
index 27020d2..0467827 100644
--- a/js/common/lib/cells.js
+++ b/js/common/lib/cells.js
@@ -77,20 +77,6 @@ Game.Cells.define("tree", {
name: "tree"
});
-Game.Cells.define("flower", {
- "char": "*",
- colors: [
- [240, 60, 60],
- [60, 60, 240],
- [240, 120, 30],
- [240, 120, 120],
- [240, 240, 30],
- [240, 30, 240],
- [240, 240, 240],
- ],
- name: "flower"
-});
-
/* features */
Game.Cells.define("staircase-up", {
diff --git a/js/common/repository.js b/js/common/repository.js
index 9c47e93..525fc36 100644
--- a/js/common/repository.js
+++ b/js/common/repository.js
@@ -15,7 +15,7 @@ Game.Repository.prototype.is = function(type, parent) {
}
Game.Repository.prototype.define = function(type, template) {
- if (template.extend) { /* create prototype link to parent definition */
+ if ("extend" in template) { /* create prototype link to parent definition */
if (!(template.extend in this._storage)) {
throw new Error("Repository type '"+type+"' cannot extend '"+template.extend+"'");
}
@@ -34,7 +34,8 @@ Game.Repository.prototype.create = function(type, template) {
var finalTemplate = Object.create(this._storage[type]);
for (var p in template) { finalTemplate[p] = template[p]; }
- var ctor = finalTemplate.ctor || this._defaultCtor; /* constructor function */
+ /* constructor function; ternary operator guarantees crash instead of wrong ctor */
+ var ctor = ("ctor" in finalTemplate ? finalTemplate.ctor : this._defaultCtor);
return new ctor(type).fromTemplate(finalTemplate);
}
diff --git a/js/display.js b/js/display.js
new file mode 100644
index 0000000..2b30f9a
--- /dev/null
+++ b/js/display.js
@@ -0,0 +1,30 @@
+Game.Display = function(options) {
+ var o = options || {};
+ o.layout = "rectCursor";
+ ROT.Display.call(this, o);
+ this._cursor = "";
+}
+Game.Display.extend(ROT.Display);
+
+Game.Display.prototype.setCursor = function(x, y) {
+ this._cursor = x+","+y;
+}
+
+Game.Display.prototype._draw = function(key, clearBefore) {
+ ROT.Display.prototype._draw.call(this, key, clearBefore);
+ if (key == this._cursor) {
+ var parts = this._cursor.split(",");
+ this._backend.drawCursor(parseInt(parts[0]), parseInt(parts[1]), this._data[key][3]);
+ }
+}
+
+ROT.Display.RectCursor = function(context) {
+ ROT.Display.Rect.call(this, context);
+}
+ROT.Display.RectCursor.extend(ROT.Display.Rect);
+
+ROT.Display.RectCursor.prototype.drawCursor = function(x, y, color) {
+ var height = Math.round(this._spacingY / 10);
+ this._context.fillStyle = color;
+ this._context.fillRect(x*this._spacingX, (y+1)*this._spacingY - height, this._spacingX, height);
+}
diff --git a/js/game.js b/js/game.js
index 80ad82b..09b60dc 100644
--- a/js/game.js
+++ b/js/game.js
@@ -3,6 +3,9 @@ var Game = {
player: null,
level: null,
story: null,
+ storyFlags: {
+ wantsFlower: false
+ },
init: function() {
window.addEventListener("load", this);
diff --git a/js/lib/beings.js b/js/lib/beings.js
index 16fa413..24057a9 100644
--- a/js/lib/beings.js
+++ b/js/lib/beings.js
@@ -1,6 +1,5 @@
Game.Beings.define("player", {
extend: "humanoid",
- "char": "@",
pv: 3,
hp: 10,
damage: 3,
@@ -11,23 +10,43 @@ Game.Beings.define("player", {
Game.Beings.define("guard", {
extend: "humanoid",
name: "guard",
- "char": "G",
tasks: [],
color: [220, 140, 140]
});
Game.Beings.define("jester", {
extend: "humanoid",
- "char": "J",
- ctor: Game.Being.Jester,
+ chats: ["There is a secret passage to the kitchen, hidden in the throne room. But only the King shall know about it!"],
name: "jester",
color: [240, 100, 100]
});
Game.Beings.define("gardener", {
extend: "humanoid",
- "char": "G",
name: "gardener",
chats: ["Good day to you, sir!", "Watch these flowers blossom!", "This garden needs my attention."],
color: [100, 240, 100],
});
+
+Game.Beings.define("bride", {
+ extend: "humanoid",
+ ctor: Game.Being.Bride,
+ tasks: [],
+ name: "bride",
+ color: [240, 240, 240]
+});
+
+Game.Beings.define("groom", {
+ extend: "humanoid",
+ tasks: [],
+ name: "groom",
+ color: [80, 80, 80]
+});
+
+Game.Beings.define("priest", {
+ extend: "humanoid",
+ tasks: [],
+ chats: ["You would like to talk to the bride - and you brought her nothing? Shame on you!"],
+ name: "priest",
+ color: [200, 30, 200]
+});
diff --git a/js/lib/bride.js b/js/lib/bride.js
new file mode 100644
index 0000000..9c49777
--- /dev/null
+++ b/js/lib/bride.js
@@ -0,0 +1,5 @@
+Game.Being.Bride = function(type) {
+ Game.Being.call(this, type);
+}
+Game.Being.Bride.extend(Game.Being);
+
diff --git a/js/gate.js b/js/lib/gate.js
similarity index 100%
rename from js/gate.js
rename to js/lib/gate.js
diff --git a/js/lib/items.js b/js/lib/items.js
new file mode 100644
index 0000000..b7b2859
--- /dev/null
+++ b/js/lib/items.js
@@ -0,0 +1,15 @@
+Game.Items.define("flower", {
+ extend: "weapon",
+ damage: 0,
+ "char": "*",
+ colors: [
+ [240, 60, 60],
+ [60, 60, 240],
+ [240, 120, 30],
+ [240, 120, 120],
+ [240, 240, 30],
+ [240, 30, 240],
+ [240, 240, 240],
+ ],
+ name: "flower"
+});
diff --git a/js/jester.js b/js/lib/jester.js
similarity index 100%
rename from js/jester.js
rename to js/lib/jester.js
diff --git a/js/player.js b/js/player.js
index f3fa852..9ae0796 100644
--- a/js/player.js
+++ b/js/player.js
@@ -1,4 +1,5 @@
Game.Player = function(type) {
+ this._debug = true;
Game.Being.call(this, type);
this._light = [30, 30, 30];
@@ -90,7 +91,7 @@ Game.Player.prototype.setPosition = function(x, y, level) {
Game.Player.prototype.updateVisibility = function() {
var visibility = this._getVisibleArea();
- this._level.setVisibility(/*true ||*/ visibility);
+ this._level.setVisibility(this._debug || visibility);
}
Game.Player.prototype._getVisibleArea = function() {
@@ -166,7 +167,7 @@ Game.Player.prototype._pickItem = function(x, y) {
return;
}
- if (Game.Items.is(type, "weapon")) {
+ if (Game.Items.is(type, "weapon") && (type != "flower" || Game.storyFlags.wantsFlower)) {
this._level.removeItem(item);
if (this._weapon) {
@@ -194,8 +195,8 @@ Game.Player.prototype.adjustHP = function(diff) {
this._updateStats();
}
-Game.Player.prototype._die = function() {
- Game.Being.prototype._die.call(this);
+Game.Player.prototype.die = function() {
+ Game.Being.prototype.die.call(this);
this._char = "☠";
this._color = [255, 255, 255];
Game.over();
diff --git a/levels/castle.js b/levels/castle.js
index 2e9367d..d83e4b8 100644
--- a/levels/castle.js
+++ b/levels/castle.js
@@ -6,6 +6,7 @@ Game.Level.Castle = function() {
this._gates = [];
this._guards = [];
this._jester = null;
+ this._gardener = null;
this._rats = [];
}
Game.Level.Castle.extend(Game.Level);
@@ -23,6 +24,7 @@ Game.Level.Castle.prototype.fromTemplate = function(map, def) {
if (being.getType() == "guard") { this._guards.push(being); }
if (being.getType() == "jester") { this._jester = being; }
if (being.getType() == "rat") { this._rats.push(being); }
+ if (being.getType() == "gardener") { this._gardener = being; }
}
this._initStory();
@@ -114,4 +116,12 @@ Game.Level.Castle.prototype._initStory = function() {
Game.story.newChapter("Me versus rats – 3:0. Nice. Now let's get to that chapel before the wedding is over!");
return true;
});
+
+ this._addRule(function() {
+ return Game.storyFlags.wantsFlower;
+ }, function() {
+ this.removeBeing(this._gardener);
+ Game.engine.removeActor(this._gardener);
+ return true;
+ });
}
diff --git a/levels/castle.txt b/levels/castle.txt
index e725438..deb69bb 100644
--- a/levels/castle.txt
+++ b/levels/castle.txt
@@ -74,7 +74,8 @@ T==========w# ##################5####
"item": "gold"
},
"f": {
- "cell": "flower"
+ "cell": "grass",
+ "item": "flower"
},
"W": {
"cell": "well"
diff --git a/levels/chapel.js b/levels/chapel.js
index a4b0393..d5d02f7 100644
--- a/levels/chapel.js
+++ b/levels/chapel.js
@@ -1,13 +1,27 @@
Game.Level.Chapel = function() {
+ /* FIXME druhy blocker krom priesta; konverzace a AI guestu */
Game.Level.call(this);
this._lighting.setOptions({range:8});
+
+ this._priest = null;
+ this._bride = null;
+ this._groom = null;
+ this._guests = [];
}
Game.Level.Chapel.extend(Game.Level);
Game.Level.Chapel.prototype.fromTemplate = function(map, def) {
Game.Level.prototype.fromTemplate.call(this, map, def);
+ for (var key in this.beings) {
+ var being = this.beings[key];
+ if (being.getType() == "guest") { this._guests.push(being); }
+ if (being.getType() == "priest") { this._priest = being; }
+ if (being.getType() == "bride") { this._bride = being; }
+ if (being.getType() == "groom") { this._groom = being; }
+ }
+
this._initStory();
return this;
}
@@ -19,4 +33,31 @@ Game.Level.Chapel.prototype._initStory = function() {
Game.story.newChapter("I finally arrived at the chapel. By this time the wedding ceremony is probably already over, so I should at least get in and give my congratulations. I guess a lot of people are attending...");
return true; /* remove from rule list */
});
+
+ this._addRule(function() {
+ return this._priest.chattedWith();
+ }, function() {
+ Game.story.addChapter("Indeed, it would be polite to bring some gift to the bride. I was in a hurry, so I brought nothing. Fortunately, I noticed some beautifully blossoming flowers in the castle garden.");
+ Game.story.setTask("Get back to castle garden and bring a flower.");
+ Game.storyFlags.wantsFlower = 1;
+ return true;
+ });
+
+ this._addRule(function() {
+ var weapon = Game.player.getWeapon();
+ return (weapon && weapon.getType() == "flower");
+ }, function() {
+ this._groom.die(); /* :-/ */
+
+ var pos = this.getCellById("window").getPosition();
+ var floor = Game.Cells.create("floor");
+ this.setCell(floor, pos[0], pos[1]);
+
+ var pos = this.getCellById("exit").getPosition();
+ var staircase = Game.Cells.create("staircase-down");
+ this.setCell(staircase, pos[0], pos[1]);
+
+
+ return true;
+ });
}
diff --git a/levels/chapel.txt b/levels/chapel.txt
index 7a3ad44..04e0637 100644
--- a/levels/chapel.txt
+++ b/levels/chapel.txt
@@ -8,9 +8,9 @@
=--====#....................................±..#=============
=--====#..............................#........#$============
=--====#....##..##..##..##..##..##..######//##########=======
-==---==#.............................................###=====
-===----/.........|G|.|G|.|G|.|G|.|G|.|G|.|.....±.......##====
-=====--/.........|G|.|G|.|G|.|G|.|G|.|G|.|.....±.......##====
+==---==#.......................................P.....###=====
+===----/.........|g|.|g|.|g|.|g|.|g|.|g|.|.....±B......##====
+=====--/.........|g|.|g|.|g|.|g|.|g|.|g|.|.....±G......##====
=======#.............................................###=====
=======#....##..##..##..##..##..##..######//##########=======
=======#..............................#........#======+======
@@ -20,7 +20,7 @@
=====================================+=========+=============
===============================+===+======+=========+===+====
=============================+==================+=========+==
-=================================+===========+=======+=======
+=================================+========>==+=======+=======
=====================================+=====================+=
=============================================================
@@ -60,6 +60,12 @@
"+": {
"cell": "tombstone"
},
+ ">": {
+ "cell": {
+ "type": "grass",
+ "id": "exit"
+ }
+ },
"±": {
"cell": "altar"
},
@@ -90,16 +96,27 @@
"name": "stained glass window"
}
},
- "G": {
+ "g": {
"cell": "floor",
"being": {
"type": "humanoid",
"name": "wedding guest",
- "char": "G",
"color": [140, 140, 140],
"colorVariation": [30, 30, 30]
}
},
+ "B": {
+ "cell": "floor",
+ "being": "bride"
+ },
+ "G": {
+ "cell": "floor",
+ "being": "groom"
+ },
+ "P": {
+ "cell": "floor",
+ "being": "priest"
+ },
"1": {
"cell": {
"type": "path",