MediaWiki:Skin/Projekt:Adventure2/lib.js: Unterschied zwischen den Versionen

aus Kamelopedia, der wüsten Enzyklopädie
Zur Navigation springen Zur Suche springen
(Musik nicht neustarten, falls gleich)
Zeile 106: Zeile 106:
 
     for(var i in e)
 
     for(var i in e)
 
       try {
 
       try {
           for(j=0; j<e[i][event].length; j++){
+
           for(j=0; e[i][event] !== undefined && j<e[i][event].length; j++){
 
               a2.log("Event", i, event, j, e[i][event][j]);
 
               a2.log("Event", i, event, j, e[i][event][j]);
 
               e[i][event][j](real);
 
               e[i][event][j](real);

Version vom 22. Juli 2015, 19:40 Uhr

// A2lib

a2 = {};
a2.events = {};
a2.virtuals = {};
a2.errorCount = 0;

a2.EVENT_CHAIN_MAX_LENGTH = 20;
a2.eventChain = [];

a2.clearEventChain = function clearEventChain () {
    a2.eventChain = [];
};

a2.clearScope = function clearScope(sc) {
    delete a2.events[sc];
    delete a2.virtuals[sc];
};

a2.registerEventHandler = function registerEventHandler(e) {
    var sc = e.scope;

    if (!a2.events[sc])
        a2.events[sc]={};

    for(var i=0; i<e.trigger.length; i++){
        var tr = e.trigger[i];
        if (!a2.events[sc][tr])
            a2.events[sc][tr] = [];
    
        a2.events[sc][tr].push(function(real){
            a2.log("run", e.name);
            var cond = e.condition();
            a2.debugEventInstance(e.scope, e.name, cond);
            if (cond)
                e.action(real);
        });
    }
};

a2.log = function () {return;};
if (window.console && window.console.log && window.console.log.apply)
    a2.log = function() { console.log.apply(window.console, arguments) };


a2.virtualTriggerMap = {
    add: [1],
    remove: [1],
    activate: [1],
    apply: [1,0],
    combine: [1,1],
    enter: [1],
    leave: [1]
}

a2.xJoin = function xJoin (z){
    function _xj(arr, vals){
        var ret = [];
        for (var i=0; i<arr.length; i++)
            for (var j=0; j<vals.length; j++)
                ret.push(arr[i].concat(vals[j]));
        return ret;
    }
    var n = [[]];
    for (var i=0; i<z.length; i++)
        n = _xj(n,z[i]);
    return n;
}

a2.createVirtualTriggers = function createVirtualTriggers (tr) {
    var b = tr[0];
    return a2.xJoin($.map(tr, function (val, i) {
        if (i>0 && a2.virtualTriggerMap[b] && a2.virtualTriggerMap[b][i-1] && a2.virtuals[val])
            return [[val].concat(a2.virtuals[val])];
        else
            return [[val]];
    }));
}

a2.fireEvent = function fireEvent(ev) {
    var triggers = a2.createVirtualTriggers(ev);
    for (var i=0; i<triggers.length; i++)
        a2._fireEvent(triggers[i], ev);
}

a2._fireEvent = function _fireEvent (ev, real) {

    if (a2.eventChain.length >= a2.EVENT_CHAIN_MAX_LENGTH) {
        a2.debugError("Abbruch: zu viele Folge-Ereignisse.");
        return; 
    } 
    var evstate = a2.stateEncode() + "|" + ev;
    if (a2.eventChain.indexOf(evstate) > -1) {
        a2.debugError("Abbruch: Ereignis-Rekursion.");
        return; 
    }
    a2.eventChain.push(evstate);

    if ( ev[0] == "enter" || ev[0] == "add" || ev[0] == "remove" )
        a2.updateHash()

    event = ev.join(".");
    a2.log("Fire", event, real);
    a2.debugEvent(event);
    var e = a2.events;
    for(var i in e)
       try {
           for(j=0; e[i][event] !== undefined && j<e[i][event].length; j++){
               a2.log("Event", i, event, j, e[i][event][j]);
               e[i][event][j](real);
           }
       } catch (e) {
           a2.log("Event Exception", e);
       }
};

a2.makeUrl = function makeUrl(p){
    var script = mw.config.get("wgScript");
    var page = mw.config.get("wgPageName");
    return [script, page, p].join("/");
}

a2.updateHash = function updateHash() {
    var hash = "#" + a2.crypt(a2.stateEncode(), true);
    location.hash = hash;
    a2.latestHash = hash;
}

a2.loadPage = function loadPage(n){
    if (isNaN(parseInt(n)) /* || a2.cpage == parseInt(n) */ )
        return;


    var response = $.ajax({
        url: a2.makeUrl(parseInt(n)+"?action=render"),
        async: false
    });

    if (response.status != 200) {
        a2.debugError("Fehler beim Laden von Seite "+n+": "+response.statusText);
        return;
    }

    a2.fireEvent(["leave",a2.cpage]);
    a2.clearScope(":page:");
 
    a2.cpage = n;
    a2.debugPage(n);
    var $content = $(response.responseText)
    $content.append('<scr'+'ipt type="text/javascript">setTimeout(function(){a2.fireEvent(["enter",a2.cpage]); $("#a2loader").hide();}, 100);</scr'+'ipt>');
 
    $("#a2image").empty().append($content);
    console.log($("#a2image a"));

    $("#a2image area").click(function (ev) {
        a2.clearEventChain();
        a2.fireEvent(["click",ev.currentTarget.hash.substr(1)]);
        return false;
    });

    $(".overlay").css("cursor","pointer").click(function (ev) {
        a2.clearEventChain();
        a2.fireEvent(["click",ev.currentTarget.id.split("_")[1]]);
        return false;
    });

    $("#_l, #_r, #_u, #_d").click(function (ev) {
        a2.clearEventChain();
        a2.fireEvent(["click",ev.currentTarget.id]);
        return false;
    });

    $("#a2image img").droppable({
        drop: function (event, ui) {
            var target = a2.ui.getDroparea($(this), ui);
            a2.log("drop", target, event, ui);
            for (var i=0; i<target.length; i++) {
                a2.clearEventChain();
                a2.fireEvent(["apply",ui.draggable.data("item"),target[i].hash.substr(1)]);
            }
        }
    });

   $(".overlay").droppable({
        drop: function (event, ui) {
            a2.clearEventChain();
            a2.fireEvent(["apply",ui.draggable.data("item"),this.id.split("_")[1]]);
    }
  });

};

a2.util = {
    print: function (s, opts) { 
        $("#a2text").text(s);

        // print options for the ask method
        if(opts) {
            var functionBuilder = function (target) {
                return function () {
                    a2.util.print("");
                    a2.fireEvent(["click", target]);
                };
            };

            var ul = $("<ul/>");
            for(var i=0; i<opts.length; i++) {
                var li = $("<li class='pseudolink'/>");
                li.click(functionBuilder(opts[i][0]));
                li.text(opts[i][1]);
                ul.append(li);
            }
            $("#a2text").append(ul);
        }
    },
    goto: function (p) {

        // prevent side effects
        a2.timer.clear();

        // this was for old Widgets!
        //$("audio").each(function (a,b) { b.autoplay = false; b.pause(); });

        // stop background noises, keep music
        a2.audio.stop("background");

        // actually go to page
        a2.loadPage(p);
    },
    timeoutIsSet: function () {
        return ! isNaN(a2.timer.pt);
    }
};


a2.items = {};
a2.loadItem = function loadItem(n){
    a2.log("load", n);

    var response = $.ajax({
        url: a2.makeUrl("item/"+n+"?action=render"),
        async: false
    });

    if (response.status != 200) {
        a2.debugError("Fehler beim Laden von Item "+n+": "+response.statusText);
        return;
    }

    a2.clearScope(n);

    a2.items[n] = response.responseText;
    a2.log(a2.items);
    a2.renderItems();
    a2.fireEvent(["add",n]);
};

a2.renderItems = function renderItems(){
    $("#a2items, #a2pseudoitems").empty()
    a2.debugItems();
    for (var item in a2.items){
        if (item[0] == "_") {
            // skip "virtual" status items
            $("#a2pseudoitems").append(a2.items[item]);
            continue;
        }

        var $flbox=$('<div class="a2itembox" />');
        var $fl=$('<div class="a2item" />');
        $flbox.append($fl);
        $fl.append(a2.items[item]);
        $("#a2items").append($flbox);
        $fl.draggable({
            // cursorAt: {top: -5, left: -5},
            revert: true,
            zIndex: 10000,
            start: function(event, ui) {
                ui.helper.bind("click.prevent", function(event) { event.preventDefault(); });
            },
            stop: function(event, ui) {
                setTimeout(function(){ui.helper.unbind("click.prevent");}, 300);
            }
        });
        $fl.data("item",item);
        $fl.click(function () {
            a2.clearEventChain();
            a2.fireEvent(["activate",$(this).data("item")]);
        });
        $fl.droppable({
            drop: function (event, ui) {
                a2.clearEventChain();
                a2.fireEvent(["combine",ui.draggable.data("item"),$(this).data("item")]);
                return false;
            }
        });
        a2.log($("#a2items"))
    }
}

a2.util.add = function add (i) {
    a2.loadItem(i);
};
a2.util.remove = function remove(i) {
    delete a2.items[i]; 
    delete a2.events[i];
    delete a2.virtuals[i];
    a2.renderItems();
    a2.fireEvent(["remove",i]);
};

a2.util.removeAll = function removeAll(v) {
    for (i in a2.virtuals)
        if( a2.virtuals[i].indexOf(v) > -1 ) {
            delete a2.items[i]; 
            delete a2.events[i];
            delete a2.virtuals[i];
            a2.fireEvent(["remove",i]);
    }
    a2.renderItems();
}

a2.util.hasVirtual = function hasVirtual (v) {
    for (i in a2.virtuals)
        if( a2.virtuals[i].indexOf(v) > -1 )
            return i;
    return false;
}

a2.ui = {};
a2.ui.getAreaBox = function getAreaBox (area) {
    var $area = $(area);
    var shape = $area.attr("shape");
    var p = $area.attr("coords");
    p = p.split(",")
    p = $.map(p, function(x){ return parseInt(x);});

    if (shape == "circle"){
        var x1 = p[0] - p[2];
        var y1 = p[1] - p[2];
        var x2 = p[0] + p[2];
        var y2 = p[1] + p[2];
    } else {
        var x1 = Infinity;
        var y1 = Infinity;
        var x2 = -Infinity;
        var y2 = -Infinity;
        for(var i=0; i<p.length; i=i+2){
            if (p[i] < x1) x1 = p[i];
            if (p[i+1] < y1) y1 = p[i+1];
            if (p[i] > x2) x2 = p[i];
            if (p[i+1] > y2) y2 = p[i+1];
        }
    }

    return {x1:x1, y1:y1, x2:x2, y2:y2};
};

a2.ui.getDroparea = function getDroparea (img, ui) {
    var $areas = $("area");
    return $areas.filter(function () {
        var b = a2.ui.getAreaBox(this);
        var s = 25; // half itemsize

        var xm = (b.x1 + b.x2) / 2;
        var ym = (b.y1 + b.y2) / 2;

        var dx = ui.offset.left - $(img).offset().left + s;
        var dy = ui.offset.top - $(img).offset().top + s;

        return (b.x1 < dx && dx < b.x2 &&
                b.y1 < dy && dy < b.y2) ||
               (dx - s < xm && xm < dx + s &&
                dy - s < ym && ym < dy + s);            
    });
}

a2.stateEncode = function () {
    var s = String(a2.cpage);
    for (var i in a2.items)
        s+="|"+i;
    return s
}

a2.stateDecode = function (s) {
    a2.clearEventChain();
    var c = s.split("|");
    a2.items = {};
    a2.virtuals = {};
    a2.events = {}
    for (var j=1; j<c.length; j++) {
        a2.items[c[j]] = "<img src='/images/a/a6/A2loading.gif' alt='Loading …' />";
    }
    a2.renderItems();
    for (var j=1; j<c.length; j++)
        a2.loadItem(c[j]);
    a2.loadPage(parseInt(c[0]));
}

a2.crypt = function crypt (str, encode) {
    if (encode){
        var n = Math.floor((Math.random()*9))+1;
        out = String(n);
    } else {
        var n = - parseInt(str.substr(0,1));
        var out = "";
        str = str.substr(1);
    }
    var chain = "pwoTä7eGNVk1SAldv0mJ9zIöPE4x8rF|B6ybüjZDC5cqfRhOXsQY23iUngLWuMHatK";
    var mk = function(i){ return i % chain.length };

    for (var i=0; i<str.length; i++) {
        var c = str.substr(i,1);
        var ind = chain.indexOf(c);
        if (ind == -1)
            out += c;
        else
            out += chain.substr(mk(ind + n),1);
    }
    return out;
}

/* DEBUGGER */

a2.debugEvent = function debugEvent (ev) {
    if (!$("#a2dbgBottom").length)
        return;

    $("#a2dbgEventLog").append($("<li/>").text(ev).append("<ul/>"));
    $("#a2dbgBottom:visible").scrollTop($("#a2dbgBottom")[0].scrollHeight);
}

a2.debugEventInstance = function debugEventInstance (sc,n,cond) {
    if (!$("#a2dbgBottom").length)
        return;

    var classname = cond ? "a2fired" : "a2notfired";
    $("#a2dbgEventLog li ul").last().append($("<li/>").text(sc+"->"+n).addClass(classname));
    $("#a2dbgBottom:visible").scrollTop($("#a2dbgBottom")[0].scrollHeight);
}

a2.debugPage = function debugPage (p) {
   $("#a2dbgGoto").val(p);
}

a2.debugItems = function debugItems() {
   var s = [];
   for (i in a2.items)
       s.push(i);
   $("#a2dbgItems").val(s.join("\n"));
}

a2.debugError = function debugError(text) {
    if (!$("#a2dbgBottom").length)
        return;

    a2.errorCount ++;
    $("#a2errorCount").text(a2.errorCount);
    $("#a2dbgEventLog").append($("<li/>").text(text).addClass("a2error"));
    $("#a2dbgBottom:visible").scrollTop($("#a2dbgBottom")[0].scrollHeight);
}

// provide timer functions
a2.timer = {
    time: 0,
    pt: NaN,
    fn: null,
    set: function set(n, fn) {
    
        if (! isNaN(a2.timer.pt)) {
	    // do not set timer if timer already active
            return;
        }
            
        a2.timer.time = n;
        a2.timer.fn = fn;
        
        a2.timer.pt = setInterval(function () {
            a2.timer.time--;
    
            if (a2.timer.time <= 0) {
                clearInterval(a2.timer.pt);
                a2.timer.pt = NaN;
                $("#_t").text("0:00").fadeOut('slow');
                fn();
                return;
            }
        
            var sec = a2.timer.time % 60;
        
            if (sec < 10)
                sec = "0" + sec;
            $("#_t").show().text(String(Math.floor(a2.timer.time / 60)) + ":" + sec );
        }, 1000);
    },
    
    clear: function clear() {
        if (! isNaN(a2.timer.pt)) {
            clearInterval(a2.timer.pt);
            a2.timer.pt = NaN;
            $("#_t").fadeOut();
        }
    }
};

// provide audio functions
a2.audio = {
    cache: {},
    current: [],

    fetch: function fetch(file) {
            var data = $.ajax({
            type: "GET",
            url: "/api.php",
            data: {
                action: "parse",
                format: "xml",
                text: "{{filepath:"+file+"}}"
            }, 
            async: false
        });
        
        var html = $(data.responseText).find("text").text();
        var url = $(html).find("a")[0].href;
        return url;
    },

    getaudio: function getaudio(file) {
        if (a2.audio.cache[file]) {
            return a2.audio.cache[file];
        } else {
            var url = a2.audio.fetch(file);
            a2.audio.cache[file] = url;
            return url;
        }
    },

    play: function play(channel, file) {
        var $player = $("#a2audio_channel_"+channel)[0];
        var audiofile = a2.audio.getaudio(file);

        if (audiofile != a2.audio.current[channel]) {        
            $player.pause();
            $player.src = a2.audio.getaudio(file);
            $player.load();
            $player.play();
            a2.audio.current[channel] = audiofile;
        }
    },

    stop: function stop(channel) {
        var $player = $("#a2audio_channel_"+channel)[0];
        $player.pause();
        a2.audio.current[channel] = null;
    }
}