﻿/****************************
 *          SPIEL           *
 ****************************/

var sealBroken;
var player, opponent;

/*
 * Die NPC-Gegner
 */
var robberLeader, robber;

/*
 * Bestimmt zufällig eine Zahl zwischen 0 und w-1
 */
function gamble(w) {
	return Math.floor(w * Math.random());
}

/*
 * Talent- bzw. Glücksprobe.
 *
 * value:	Talent-/Glückswert
 * w	:	Würfel (Seitenzahl)
 * 
 * Gibt true zurück, wenn die Probe gelungen ist
 */
function test(value, w) {
	var msg;

	return (value > gamble(w));
}

/*
 * Gibt die nächste Seite abhängig von einer Talentprobe zurück.
 *
 * skill	:	Das zu testende Talent
 * posIndex	:	Die nächste Seite bei Gelingen der Probe
 * negIndex	:	 "     "      "    "  Scheitern der Probe
 */
function testFor(skill, posIndex, negIndex) {
	var index = 'test(player.' + skill + ', 20) ? ' + posIndex + ' : ' + negIndex;
	
	return new Link(index, 'Probe durchführen…');
}

/*
 * Gibt die nächste Seite zurück, abhängig davon, ob des Siegel gebrochen wurde
 */
function testForSeal() {
	return 'sealBroken ? 49 : 36';
}

/*
 * Wählt zufällig ein Element aus derm Array arr aus
 *
 * Gibt den ausgewählten Wert zurück oder arr, wenn arr kein Array ist
 */
function jump(arr) {
	if (arr.length) {
		return arr[gamble(arr.length)];
	}
	
	return arr;
}

/*
 * Modell einer Waffe.
 *
 * name	:	Bezeichnung der Waffe
 * plus	:	Zusätliche Trefferpunkte der Waffe
 */
function Weapon(name, plus) {
	var name = name;
	var plus = plus;
	
	this.toString = function() {
		return name;
	};
	
	this.getPlus = function() {
		return plus;
	};
}

/*
 * Modell eines Charakters.
 *
 * HP		:	Lebensenergie (Hit Points)
 * AP		:	Attackewert (Attack Points)
 * BP		:	Paradewert (Block Points)
 * weapon	:	Waffe
 * alias	:	Bezeichnung
 */
function Character(HP, AP, BP, weapon, alias, panning) {
	var maxHP = HP;
	var maxAP = AP;
	var maxBP = BP;
	var self = this;
	var pan = panning || 100;
	
	this.sound = {};
	
	this.setSounds = function() {
		var file = [ 'hit', 'miss', 'hurt', 'beaten' ];
		
		for (var key in file) {
			var s = swfsound.loadSound( './music/' + alias + '/' + file[key] + '.mp3', streamAndAutoPlay = false );
			swfsound.setPan(s, pan);
			self.sound[file[key]] = s;
		}
	};
	
	this.getSound = function(sound) {
		return './music/' + alias + '/' + sound + '.mp3'
	};
	
	this.getMaxHP = function() {
		return maxHP;
	};
	
	this.getHP = function() {
		return HP;
	};
	
	this.getAP = function() {
		return AP;
	};

	this.getBP = function() {
		return BP;
	};
	
	this.getWeapon = function() {
		return weapon;
	};

	this.getImage = function() {
		return alias + '.png';
	};
	
	this.addHP = function(val) {
		var newHP = Math.max(0, HP + val);
		HP = Math.min(newHP, maxHP);
		
		//Speichern
		save(alias, HP);
	};
	
	this.reset = function() {
		HP = maxHP;
	};
	
	this.attack = function(opponent) {
		if (!opponent.attack) {
			return false;
		}
	
		//Sie greifen an und Ihr Angriff missglückte!
		var damage = 0;
		
		if (gamble(20) <= AP) {
			if (gamble(20) > opponent.getBP()) {
				//Sie greifen an und haben dem Gegner Schadenspunkte verursacht!
				damage = gamble(5) + weapon.getPlus();
			}
			else {
				//Sie greifen an und Ihr Angriff wurde abgewehr!
				damage = -1;
			} 
		}
		
		return damage;
	};
}

/*
 * Modell des Spielers
 */
function Player() {
	this.constructor(28, 9, 8, new Weapon('Kurzschwert', 2), 'player', -100)
	
	var self = this;
	
	this.luck = 4;			//Glück
	this.agility = 11;		//Gewandtheit
	this.dexterity = 10;	//Fingerfertigkeit
	this.curiosity = 5;		//Neugier
	
	this.isHealthy = function() {
		return self.getHP() >= self.getMaxHP();
	};
	
	this.sleep = function() {
		var gain = gamble(5) + 1;
		self.addHP(gain);
		return gain;
	};
}
Player.prototype = new Character();

/*
 * Initialisiert das Spiel
 */
function start() {
	player = new Player();
	robberLeader = new Character(18, 7, 6, new Weapon('Säbel', 3), 'leader');
	robber = new Character(12, 7, 6, new Weapon('Säbel', 3), 'robber');
}

/*
 * Startet ein neues Spiel
 */
function reset() {
	player.reset();
	robberLeader.reset();
	robber.reset();
	sealBroken = false;
}

/*
 * Initialisiert einen Kampf gegen den Charakter opp
 */
function startFight(opp) {
	//temp:
	playMusic(fighting, 40);
	
	opponent = opp;

	leftFight.setCharacter(player, "");
	rightFight.setCharacter(opp, "");
}

var battleSounds = [],
	playingSounds = false,
	turn = 0;

function playSounds(opt) {
	if (playingSounds === false) {
		turn = 0;
		playingSounds = window.setInterval(function() {
			playSounds(opt);
		}, 200);
	}
	else {
		if (battleSounds.length <= 0) {
			window.clearInterval(playingSounds);
			playingSounds = false;
			linkCon.innerHTML = db[current].getLinks()[0].toListItem(opt);
		}
		else {
			var next = battleSounds.shift();
			
			if (typeof next == 'string') {
				var box = (turn == 0) ? rightFight : leftFight;
				var fighter = (turn == 0) ? opponent : player;
				
				box.setCharacter(fighter, next);
				turn++;
			}
			else {
				playSound(next);
			}
		}
	}
}

/*
 * Löst eine Kampfrunde aus
 */
function fight() {
	//Spieler greift an
	var damage = player.attack(opponent);
	var msg = "Sie haben Ihren Gegner verfehlt.";
	battleSounds = [];
	
	leftFight.setMessage('');
	rightFight.setMessage('');
	linkCon.innerHTML = '<li class="wait">Der Kampf l&auml;uft&hellip;</li>';
	
	if (damage > 0) {
		opponent.addHP(-damage);
		msg = "Sie ha|ben Ih|rem Geg|ner " + damage + " Scha|dens|punk|te zu|ge|fügt.";
		battleSounds.push(player.sound.hit);
		battleSounds.push(hitting);
		battleSounds.push(opponent.sound.hurt);
	}
	else if (damage < 0) {
		msg = "Ihr Angriff wurde abgewehrt.";
		battleSounds.push(player.sound.hit);
		battleSounds.push(blocking);
	}
	else {
		battleSounds.push(player.sound.miss);
	}
	
	battleSounds.push(msg);
	
	if (opponent.getHP() <= 0) {		
		battleSounds.pop();
		battleSounds.push("Sie haben Ihren Gegner besiegt!");
		battleSounds.push(opponent.sound.beaten);
		playSounds(0);

		return;
	}
	
	//Gegner greift an
	battleSounds.push(null);
	battleSounds.push(null);
	
	damage = player.attack(opponent);
	msg = "Ihr Gegner hat Sie verfehlt.";
	
	if (damage > 0) {
		player.addHP(-damage);
		msg = "Ihr Geg|ner hat Ih|nen " + damage + " Scha|dens|punk|te zu|ge|fügt.";
		battleSounds.push(opponent.sound.hit);
		battleSounds.push(hitting);
		battleSounds.push(player.sound.hurt);
	}
	else if (damage < 0) {
		msg = "Sie haben den Angriff abgewehrt.";
		battleSounds.push(opponent.sound.hit);
		battleSounds.push(blocking);
	}
	else {
		battleSounds.push(opponent.sound.miss);
	}
	
	battleSounds.push(msg);

	if (player.getHP() <= 0) {
		battleSounds.pop();
		battleSounds.push("Sie wurden besiegt!");
		battleSounds.push(player.sound.beaten);
		playSounds(1);
		
		return;
	}
	
	playSounds();
}

/*
 * Heilt den Spieler durch Schlaf
 */
function heal() {
	var healthy = player.isHealthy();
	var before, gain;
	var msg = 'Da ihre Le|bens|punk|te noch voll sind, be|kom|men sie au|ßer ei|nem er|hol|sa|men Schlaf nichts da|zu.';
	
	if (!healthy) {
		gain = player.sleep();
		msg = (player.isHealthy())
			? 'Sie re|ge|ne|rie|ren sich wäh|rend der Nacht kom|plett und ha|ben wie|der ' + player.getMaxHP() + ' Le|bens|punk|te.'
			: 'Sie be|kom|men ' + gain + ' Le|bens|punk|te da|zu.';
	}
	
	leftFight.setCharacter(player, msg);
}

/*
 * Bricht das Siegel
 */
function breakSeal() {
	sealBroken = true;
	
	//Speichern
	save('seal', sealBroken);
}

/*
 * Lässt den Spieler vom Pferd fallen
 */
function fallDown() {
	player.addHP(-2);
	leftFight.setCharacter(player, 'Sie haben 2 Lebenspunkte Schaden genommen.');
}
