mirror of
https://github.com/Sheldan/canvas.git
synced 2026-01-01 14:58:51 +00:00
survivors: adding spear (kinda)
changed range calculation for melee weapons
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import type {ChanceEntry, Item} from "./interfaces.ts";
|
||||
import {Player} from "./Player.ts";
|
||||
import {randomItem} from "./utils.ts";
|
||||
import {ChainBall, HomingPistol, Pistol, SpreadWeapon} from "./weapons.ts";
|
||||
import {ChainBall, HomingPistol, Pistol, Spear, SpreadWeapon} from "./weapons.ts";
|
||||
import type {World} from "./World.ts";
|
||||
|
||||
export enum Rarity {
|
||||
@@ -42,6 +42,7 @@ export class ItemManagement {
|
||||
this.ITEMS.push(new SpreadWeaponItem())
|
||||
this.ITEMS.push(new ChainBallWeaponItem())
|
||||
this.ITEMS.push(new PullRangeUp())
|
||||
this.ITEMS.push(new SpearWeaponItem())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,4 +188,20 @@ export class ChainBallWeaponItem extends BaseItem {
|
||||
}
|
||||
}
|
||||
|
||||
export class SpearWeaponItem extends BaseItem {
|
||||
pickup(player: Player, world: World) {
|
||||
player.addWeapon(Spear.createSpear(world))
|
||||
super.pickup(player, world)
|
||||
}
|
||||
|
||||
name() {
|
||||
return 'spear'
|
||||
}
|
||||
|
||||
getRarity(): Rarity {
|
||||
return Rarity.EPIC;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
toRad
|
||||
} from "./utils.ts";
|
||||
import {InstanceOfUtils} from "./instance.ts";
|
||||
import {MeleeWeapon} from "./weapons.ts";
|
||||
import {ChainBall, MeleeWeapon} from "./weapons.ts";
|
||||
import type {Enemy} from "./Enemies.ts";
|
||||
|
||||
export abstract class Projectile implements Acting, Placeable {
|
||||
@@ -129,13 +129,13 @@ export class StraightProjectile extends Projectile {
|
||||
}
|
||||
}
|
||||
|
||||
export class WeaponProjectile extends Projectile {
|
||||
private weapon: MeleeWeapon;
|
||||
export class ChainBallProjectile extends Projectile {
|
||||
private weapon: ChainBall;
|
||||
private movingBack: boolean = false;
|
||||
private target: Vector;
|
||||
private lastHit: Enemy[] = []
|
||||
|
||||
constructor(position: Vector, speedVec: Vector, stats: ProjectileStats, world: World, parent: any, weapon: MeleeWeapon, target: Vector) {
|
||||
constructor(position: Vector, speedVec: Vector, stats: ProjectileStats, world: World, parent: any, weapon: ChainBall, target: Vector) {
|
||||
super(position, speedVec, stats, world, parent);
|
||||
this.weapon = weapon;
|
||||
this.target = target.clone()
|
||||
@@ -177,9 +177,71 @@ export class WeaponProjectile extends Projectile {
|
||||
}
|
||||
}
|
||||
|
||||
static createWeaponProjectile(world: World, start: Vector, targetPosition: Vector, parent: any, stats: ProjectileStats, weapon: MeleeWeapon, color?: string) {
|
||||
static createChainBallProjectile(world: World, start: Vector, targetPosition: Vector, parent: any, stats: ProjectileStats, weapon: MeleeWeapon, color?: string) {
|
||||
let dirVector = Vector.createVector(targetPosition, start).normalize().multiply(stats.speed);
|
||||
let projectile = new WeaponProjectile(start, dirVector, stats, world, parent, weapon, targetPosition)
|
||||
let projectile = new ChainBallProjectile(start, dirVector, stats, world, parent, weapon, targetPosition)
|
||||
projectile.color = color === undefined ? 'red' : color!;
|
||||
world.addProjectile(projectile)
|
||||
return projectile;
|
||||
}
|
||||
}
|
||||
|
||||
export class StraightMeleeWeaponProjectile extends Projectile {
|
||||
|
||||
private weapon: MeleeWeapon;
|
||||
private movingBack: boolean = false;
|
||||
private target: Vector;
|
||||
private lastHit: Enemy[] = []
|
||||
|
||||
constructor(position: Vector, speedVec: Vector, stats: ProjectileStats, world: World, parent: any, weapon: ChainBall, target: Vector) {
|
||||
super(position, speedVec, stats, world, parent);
|
||||
this.weapon = weapon;
|
||||
this.target = target.clone()
|
||||
}
|
||||
|
||||
draw(ctx: CanvasRenderingContext2D) {
|
||||
let position = this.getRealPosition();
|
||||
drawDot(position, this.stats.size, 'brown', ctx) // todo render the weapon instead
|
||||
}
|
||||
|
||||
getRealPosition(): Vector {
|
||||
return this.world.player.getPosition().add(this.position)
|
||||
}
|
||||
|
||||
act() {
|
||||
this.move()
|
||||
let hitEnemies = this.world.getAllInRange(this.getRealPosition(), this.stats.size * 2);
|
||||
hitEnemies.forEach(value => {
|
||||
if(this.lastHit.indexOf(value) !== -1) {
|
||||
if(InstanceOfUtils.instanceOfHealthy(value)) {
|
||||
let healthy = value as Healthy;
|
||||
healthy.takeDamage(this.stats.damage)
|
||||
}
|
||||
}
|
||||
})
|
||||
this.lastHit = hitEnemies;
|
||||
}
|
||||
|
||||
move() {
|
||||
super.move()
|
||||
if(!this.movingBack) {
|
||||
this.position = straightMove(this.position, this.speedVec)
|
||||
if(this.position.distanceTo(this.target) < this.stats.size) {
|
||||
this.movingBack = true;
|
||||
this.speedVec = this.speedVec.multiply(3)
|
||||
}
|
||||
} else {
|
||||
this.position = moveInDirectionOf(this.position, new Vector(0, 0), this.speedVec.vecLength())
|
||||
}
|
||||
if(this.movingBack && this.position.distanceTo(new Vector(0, 0)) < (this.stats.size + this.world.player.stats.size)) {
|
||||
this.weapon.reset();
|
||||
this.die()
|
||||
}
|
||||
}
|
||||
|
||||
static createStraightMeleeProjectile(world: World, start: Vector, targetPosition: Vector, parent: any, stats: ProjectileStats, weapon: MeleeWeapon, color?: string) {
|
||||
let dirVector = Vector.createVector(targetPosition, start).normalize().multiply(stats.speed);
|
||||
let projectile = new StraightMeleeWeaponProjectile(start, dirVector, stats, world, parent, weapon, targetPosition)
|
||||
projectile.color = color === undefined ? 'red' : color!;
|
||||
world.addProjectile(projectile)
|
||||
return projectile;
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
import type {Weapon} from "./interfaces.ts";
|
||||
import {drawDot, toRad} from "./utils.ts";
|
||||
import {Player} from "./Player.ts";
|
||||
import {HomingProjectile, Projectile, ProjectileStats, StraightProjectile, WeaponProjectile} from "./projectile.ts";
|
||||
import {
|
||||
HomingProjectile,
|
||||
Projectile,
|
||||
ProjectileStats,
|
||||
StraightProjectile,
|
||||
ChainBallProjectile,
|
||||
StraightMeleeWeaponProjectile
|
||||
} from "./projectile.ts";
|
||||
import {World} from "./World.ts";
|
||||
import {Vector} from "./base.ts";
|
||||
|
||||
@@ -84,15 +91,67 @@ export abstract class MeleeWeapon extends RangeWeapon {
|
||||
act() {
|
||||
if(this.shootCooldown <= 0) {
|
||||
if(this.createProjectile()) {
|
||||
this.launched = true;
|
||||
this.shootCooldown = 1;
|
||||
}
|
||||
}
|
||||
if(!this.launched) {
|
||||
this.shootCooldown -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.shootCooldown = 0
|
||||
this.shootCooldown = this.stats.shootInterval
|
||||
this.launched = false;
|
||||
}
|
||||
|
||||
calculateRange(): number {
|
||||
return this.stats.effectiveWeaponRange;
|
||||
}
|
||||
}
|
||||
|
||||
export class Spear extends MeleeWeapon {
|
||||
protected launched: boolean;
|
||||
|
||||
createProjectile(): boolean {
|
||||
let range = this.calculateRange()
|
||||
let closestTargetTo = this.world.getFarthestTargetButWithin(this.world.player.position, range);
|
||||
if(closestTargetTo !== undefined && closestTargetTo[1] !== undefined) {
|
||||
let stats = new ProjectileStats()
|
||||
.withPiercings(1000)
|
||||
.withSize(3)
|
||||
.withDamage(this.stats.damage)
|
||||
.withSpeed(this.stats.projectileSpeed);
|
||||
let offsetVector = Vector.createVector(closestTargetTo[1]!.getPosition(), this.player.position).multiply(1.1);
|
||||
if(offsetVector.vecLength() < 15) {
|
||||
offsetVector = offsetVector.normalize().multiply(40)
|
||||
}
|
||||
let projectile = StraightMeleeWeaponProjectile.createStraightMeleeProjectile(this.world, new Vector(0, 0), offsetVector, this.player, stats, this)
|
||||
this.projectiles.push(projectile)
|
||||
return true
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static createSpear(world: World, offset?: Vector) {
|
||||
if(!offset) {
|
||||
offset = new Vector(5, 5)
|
||||
}
|
||||
let stats = new WeaponStats()
|
||||
.withProjectileSpeed(5)
|
||||
.withDamage(15)
|
||||
.withWeaponRange(150)
|
||||
.withShootInterval(50)
|
||||
let pistol = new Spear(world, stats)
|
||||
pistol.offset = offset;
|
||||
pistol.size = 7;
|
||||
pistol.color = 'brown';
|
||||
return pistol;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class ChainBall extends MeleeWeapon {
|
||||
|
||||
createProjectile(): boolean {
|
||||
@@ -104,7 +163,7 @@ export class ChainBall extends MeleeWeapon {
|
||||
.withSize(3)
|
||||
.withDamage(this.stats.damage)
|
||||
.withSpeed(this.stats.projectileSpeed);
|
||||
let projectile = WeaponProjectile.createWeaponProjectile(this.world, this.getPosition(), closestTargetTo[1]!.getPosition(), this.player, stats, this)
|
||||
let projectile = ChainBallProjectile.createChainBallProjectile(this.world, this.getPosition(), closestTargetTo[1]!.getPosition(), this.player, stats, this)
|
||||
this.projectiles.push(projectile)
|
||||
return true
|
||||
} else {
|
||||
@@ -119,7 +178,8 @@ export class ChainBall extends MeleeWeapon {
|
||||
let stats = new WeaponStats()
|
||||
.withProjectileSpeed(3)
|
||||
.withDamage(15)
|
||||
.withShootInterval(50)
|
||||
.withWeaponRange(150)
|
||||
.withShootInterval(20)
|
||||
let pistol = new ChainBall(world, stats)
|
||||
pistol.offset = offset;
|
||||
pistol.size = 4;
|
||||
@@ -267,7 +327,7 @@ export class WeaponStats {
|
||||
|
||||
constructor() {
|
||||
this._weaponRangeFactor = 1
|
||||
this._weaponRange = 0
|
||||
this._weaponRange = 50
|
||||
this._projectilePiercings = 0
|
||||
this._projectileSpeed = 100
|
||||
this._damage = 1
|
||||
|
||||
Reference in New Issue
Block a user