import Phaser from "phaser";
//const Bullet = require('./bullet');
const Interact = require('../../actions/interact');
const dataManager = require('../data');
/**
* @memberof ClubCrawler.Objects.Weapon
* @constant
*/
const DEFAULT_WEAPON = {
name: "popper",
description: "Could knock over some soda cans, at least",
duration: 1000,
projectileVelocity: 1000,
spin: 2000,
mass: 0.1,
damage: 20,
fireRate: 300,
spriteKey: "bullet",
audioSpriteKey: "bullet-sound",
audioFireKey: "shot1",
audioBounceKey: "bounce1",
audioHitKey: "bounce1",
bounce: 0.3,
hitEnemies: true,
overlapEnemies: false,
hitWalls: true,
hitPlayer: false,
overlapPlayer: false,
hitDestructibles: true,
overlapDestructibles: false,
destroyOnWallTouch: false,
inventorySprite: "popper-inventory",
itemType: "weapon"
}
/**
* @memberof ClubCrawler.Objects
*
* @classdesc Controls weapon class. Effectively a Projectile Factory.
*
*/
class Weapon {
/**
* @param {ClubCrawler.Types.WeaponConfig} config - A weapon configuration
*/
constructor(config) {
Object.assign(this, DEFAULT_WEAPON);
Object.assign(this, config);
this.scene = config.scene;
this.wielder = config.wielder;
this.target = config.target;
this.lastTimeFired = 0;
}
/**
* Description
* @param {Object} newTarget - the game object to target (must have x and y)
*/
setTarget(newTarget) {
this.target = newTarget;
}
fire(time) {
if(time > this.lastTimeFired + this.fireRate) {
let newBullet = new Projectile(this);
this.lastTimeFired = time;
}
}
}
/**
* @memberof ClubCrawler.Objects.Weapon
*
* @classdesc A projectile, created by a Weapon
* @implements {ClubCrawler.Actions.Interact.DamageDealer}
*/
class Projectile extends Phaser.GameObjects.Image {
/**
* @param {ClubCrawler.Objects.Weapon} config - The firing weapon
*/
constructor(config) {
super(config.scene, config.wielder.x, config.wielder.y, config.spriteKey);
//set props from config
this.config = config;
this.damage = config.damage;
this.duration = config.duration;
this.audioSpriteKey = config.audioSpriteKey;
this.audioBounceKey = config.audioBounceKey;
this.audioFireKey = config.audioFireKey;
this.audioHitKey = config.audioHitKey;
this.projectileVelocity = config.projectileVelocity;
this.destroyOnWallTouch = config.destroyOnWallTouch;
//set physics object from config
this.scene.add.existing(this);
this.scene.physics.add.existing(this);
this.body.setAngularVelocity(config.spin);
this.body.setBounce(config.bounce, config.bounce);
this.body.setMass(config.mass);
//create audiosprites
this.shotFX = this.scene.sound.addAudioSprite(config.audioSpriteKey);
this.bounceFX = this.scene.sound.addAudioSprite(config.audioSpriteKey);
this.hitFX = this.scene.sound.addAudioSprite(config.audioSpriteKey);
//create colliders
if(config.hitWalls) {
this.scene.physics.add.collider(this, this.scene.mapManager.walls, this.hitWall, null, this);
}
if(config.hitEnemies) {
this.scene.physics.add.collider(this, this.scene.mapManager.enemies, Interact.DamageCollisionReversed);
}
if(config.overlapEnemies) {
this.scene.physics.add.overlap(this, this.scene.mapManager.enemies, Interact.DamageCollisionReversed);
}
if(config.hitDestructibles) {
this.scene.physics.add.collider(this, this.scene.mapManager.destructibles, Interact.DamageCollisionReversed);
}
if(config.overlapDestructibles) {
this.scene.physics.add.overlap(this, this.scene.mapManager.destructibles, Interact.DamageCollisionReversed);
}
if(config.hitPlayer) {
this.scene.physics.add.collider(this, this.scene.player, Interact.DamageCollisionReversed);
}
if(config.overlapPlayer) {
this.scene.physics.add.overlap(this, this.scene.player, Interact.DamageCollisionReversed);
}
this.scene.time.delayedCall(this.duration, this.destroy, [], this);
this.fireAt(config.target)
}
/**
* Gives bullet velocity towards target
*
* @param {Object} target with an x and y
*/
fireAt(target) {
let hypoteneuse = Phaser.Math.Distance.Between(this.x, this.y, target.x, target.y);
let adjacent = target.x - this.x;
let opposite = target.y - this.y;
let sine = opposite/hypoteneuse;
let cosine = adjacent/hypoteneuse;
let speedX = this.projectileVelocity * cosine;
let speedY = this.projectileVelocity * sine;
this.body.setVelocityX(speedX);
this.body.setVelocityY(speedY);
if(this.shotFX) {
this.shotFX.play(this.audioFireKey);
}
}
/**
* Called by Interfaces.Interact when damage is dealt
*/
dealDamage() {
if(this.hitFX) {
this.hitFX.play(this.audioHitKey);
}
if(dataManager.debug.weapon.sound == true) {
let hasSound = false;
if(this.hitFX) {
hasSound = true;
}
dataManager.log('hit enemy - is there sfx?' + hasSound);
}
this.destroy();
}
/**
* Called when wall collide occurs
*/
hitWall() {
if(dataManager.debug.weapon.sound) {
let hasSound = false;
if(this.bounceFX) {
hasSound = true;
}
dataManager.log('bounce bullet-sfx? ' + hasSound);
}
if(this.bounceFX) {
this.bounceFX.play(this.audioBounceKey);
}
if(this.destroyOnWallTouch) {
this.destroy();
}
}
}
module.exports = {
Weapon: Weapon,
Projectile: Projectile,
DEFAULT: DEFAULT_WEAPON
}