Implement anti-magic zone.
authorJoe Wreschnig <joe.wreschnig@gmail.com>
Wed, 27 Aug 2014 10:05:08 +0000 (12:05 +0200)
committerJoe Wreschnig <joe.wreschnig@gmail.com>
Wed, 27 Aug 2014 10:05:08 +0000 (12:05 +0200)
heroik.js
scenarios.js

index 401268bdbdf12d9d7eef9cccdee73b5d62001302..bca710e0ef8be74598fdaca363e8d8304f71113c 100644 (file)
--- a/heroik.js
+++ b/heroik.js
@@ -58,6 +58,10 @@ function choice (seq) {
     return seq[(Math.random() * seq.length) | 0];
 }
 
+function not (f) {
+    return function () { return !f.apply(this, arguments); };
+}
+
 function contains (element) {
     return this.indexOf(element) >= 0;
 }
index 035d492262e2947eb0e0a7c266069c1106547086..2b24e6f435bd8eaacf55c283df3a2e4cc5a8b7a9 100644 (file)
@@ -85,16 +85,17 @@ var EVENTS = [
 
     { name: "Psi assault.",
       effect: "You cannot use ultimate powers.",
+      lock: ["ultimates"],
       unique: true },
-/*  TODO: Figure out how to implement this well.
     { name: "Entering an anti-magic zone.",
       effect: "You cannot use ultimate powers.",
-      unique: true,
+      lock: ["ultimates"],
       duration: 3,
       later: { name: "Leaving the anti-magic zone.",
-               effect: "You may use ultimate powers again." }
+               effect: "You may use ultimate powers again.",
+               clear: ["ultimates"] }
     },
-*/
+
     // Events from Sean Allen's random scenario generator.
     // http://boardgamegeek.com/filepage/57107/random-scenario-generator
     { name: "Fire from above.",
@@ -210,13 +211,34 @@ function generate (flags, events, nop) {
     var chosen = [];
     var i;
 
+    var pending = [];
+    var locks = [];
+    var event;
+
+    function pend (event, i) {
+        while (pending[i]) ++i
+        pending[i] = event;
+    }
+
     function canStillHappen (event) {
         return issubset(event.requires || [], flags)
-            && !(event.unique && contains.call(chosen, event));
+            && !(event.unique && contains.call(chosen, event))
+            && !intersects(event.lock || [], locks);
+    }
+
+    for (i = 0; i < events; ++i) {
+        event = pending.shift()
+            || choice(EVENTS.filter(canStillHappen));
+        chosen.push(event);
+        if (event.later)
+            pend(event.later, (Math.random() * chosen[i].duration) | 0);
+        locks = locks.concat(event.lock || [])
+            .filter(not(contains), event.clear || []);
     }
 
-    for (i = 0; i < events; ++i)
-        chosen.push(choice(EVENTS.filter(canStillHappen)));
+    for (i = 0; i < pending.length; ++i)
+        if (pending[i])
+            chosen.push(pending[i]);
 
     
     for (i = 0; i < nop / 2; ++i) {