game.js
// Enemy class, superclass for all enemy types
Enemy class, superclass for all enemy types
Enemy class superclass for all enemy types
function Enemy() {
	Actor.call(this);
	this.specialAttack = function() {
		var usableSpecials = [];
		for (var i=0;i < this.specials.length;i++){
			if(this.specials[i].attackType == "soulSplit") {
				if(this.sp < this.maxSp - 2) {
					usableSpecials.push(this.specials[i]);
				}
			}else if(this.specials[i].cost <= this.sp) {
				usableSpecials.push(this.specials[i]);
			}
		}
		if (usableSpecials.length == 0) {
			this.attack(player);
		} else {
			special = usableSpecials[Math.floor(Math.random() * (usableSpecials.length - 1))];
			updateOutput(this.name + " used " + special.name + "!");
			this.sp -= special.cost;
			var critChancePlaceholder = this.critChance;
			this.critChance = 0;
			switch (special.attackType) {
				case "player":
					var strengthPlaceholder = this.strength;
					this.strength *= special.damageMultiplier;
					this.attack(player);
					this.strength = strengthPlaceholder;
					break;
				case "self":
					var healing = Math.floor(this.maxHealth * special.healPercent / 100);
					this.health += healing;
					if(this.health > this.maxHealth) {
						this.health = this.maxHealth;
					}
					updateOutput(this.name + " recovered " + healing + " HP!");
					break;
				case "partyBuff":
					var target = enemies[Math.floor(Math.random() * (enemies.length - 1))];
					target[special.buffStat] = Math.round(target[special.buffStat] * special.buffMultiplier);
					updateOutput(target.name + "'s " + special.buffStat + " is now " + target[special.buffStat] + "!");
					break;
				case "soulSplit":
					var damage = Math.round(this.strength * special.damageMultiplier);
					if (this.health <= damage) {
						updateOutput(this.name + " was too weak to split its soul!");
					} else {
						this.health -= damage;
						var spRestored = damage;
						if(spRestored > (this.maxSp - this.sp)) {
							spRestored = this.maxSp - this.sp;
						}
						this.sp += spRestored;
						updateOutput(this.name + " split its soul, taking " + damage + " damage and gaining " + spRestored + " SP");
					}
					break;
			}
			this.critChance = critChancePlaceholder;
		}
	}
	this.chooseBehavior = function() {
		var choice = Math.random();
		var actionChoice;
		if (choice <= this.attackChance) {
			actionChoice = this.attack;
		} else if (choice <= this.attackChance + this.defendChance) {
			actionChoice = this.defend;
		} else {
			actionChoice = this.specialAttack;
		}
		return actionChoice;
	}
}
function Enemy ( ) { Actor . call ( this ) ; this . specialAttack = function ( ) { var usableSpecials = [ ] ; for ( var i = 0 ; i < this . specials . length ; i ++ ) { if ( this . specials [ i ] . attackType == "soulSplit" ) { if ( this . sp < this . maxSp - 2 ) { usableSpecials . push ( this . specials [ i ] ) ; } } else if ( this . specials [ i ] . cost <= this . sp ) { usableSpecials . push ( this . specials [ i ] ) ; } } if ( usableSpecials . length == 0 ) { this . attack ( player ) ; } else { special = usableSpecials [ Math . floor ( Math . random ( ) * ( usableSpecials . length - 1 ) ) ] ; updateOutput ( this . name + " used " + special . name + "!" ) ; this . sp -= special . cost ; var critChancePlaceholder = this . critChance ; this . critChance = 0 ; switch ( special . attackType ) { case "player" : var strengthPlaceholder = this . strength ; this . strength *= special . damageMultiplier ; this . attack ( player ) ; this . strength = strengthPlaceholder ; break ; case "self" : var healing = Math . floor ( this . maxHealth * special . healPercent / 100 ) ; this . health += healing ; if ( this . health > this . maxHealth ) { this . health = this . maxHealth ; } updateOutput ( this . name + " recovered " + healing + " HP!" ) ; break ; case "partyBuff" : var target = enemies [ Math . floor ( Math . random ( ) * ( enemies . length - 1 ) ) ] ; target [ special . buffStat ] = Math . round ( target [ special . buffStat ] * special . buffMultiplier ) ; updateOutput ( target . name + "'s " + special . buffStat + " is now " + target [ special . buffStat ] + "!" ) ; break ; case "soulSplit" : var damage = Math . round ( this . strength * special . damageMultiplier ) ; if ( this . health <= damage ) { updateOutput ( this . name + " was too weak to split its soul!" ) ; } else { this . health -= damage ; var spRestored = damage ; if ( spRestored > ( this . maxSp - this . sp ) ) { spRestored = this . maxSp - this . sp ; } this . sp += spRestored ; updateOutput ( this . name + " split its soul, taking " + damage + " damage and gaining " + spRestored + " SP" ) ; } break ; } this . critChance = critChancePlaceholder ; } } this . chooseBehavior = function ( ) { var choice = Math . random ( ) ; var actionChoice ; if ( choice <= this . attackChance ) { actionChoice = this . attack ; } else if ( choice <= this . attackChance + this . defendChance ) { actionChoice = this . defend ; } else { actionChoice = this . specialAttack ; } return actionChoice ; } }
Enemy class, superclass for all enemy types
Enemy class superclass for all enemy types
// Enemies handle special attacks differently than the player // Generate an array of usable specials //console.log(usableSpecials); // If the enemy can't use ANY of its specials // Attack the player instead (probably out of frustration) // Otherwise, randomly pick a special attack from the ones it can use // Disable critical hits until after the attack is finished // Choose a random member of the enemy party (defaults to caster if they're all alone) // Attacks self, damage dealt fills SP //console.log("damage is: " + damage); // Attack fails if it would kill the caster // Enemy use of SP Magnet will be done later, if at all /*case "sp":
					var totalDrained = 0;
					var strengthPlaceholder = this.strength;
					this.strength *= special.damageMultiplier;
					for(var i=0;i<target.length;i++){
						if(target[i].sp > 0) {
							var draining = Math.round(this.strength * (Math.random() + 0.5));
							if(draining > target[i].sp) {
								draining = target[i].sp;
							}
							updateOutput("Drained " + draining + " SP from " + target[i].name);
							totalDrained += draining
						}
					}
					this.sp += totalDrained;
					if(this.sp > this.maxSp) {
						this.sp = this.maxSp;
					}
					updateOutput("...for a total of " + totalDrained + " SP! " + this.name + "'s SP is now " + this.sp);
					this.strength = strengthPlaceholder;
					break;*/ // How the enemy decides which behavior to execute (spoiler: it's random)