survivors: adding new "melee" weapon

This commit is contained in:
Sheldan
2025-09-06 00:50:45 +02:00
parent 71b2afacc4
commit 33310100f7
4 changed files with 142 additions and 4 deletions

View File

@@ -115,6 +115,17 @@ export class World {
}
}
getAllInRange(point: Vector, range: number): Enemy[] {
let found = [];
this._enemies.items.forEach(enemy => {
let distance = point.distanceTo(enemy.getPosition());
if(range && distance < range) {
found.push(enemy)
}
});
return found;
}
get player(): Player {
return this._player;
}

View File

@@ -1,7 +1,7 @@
import type {ChanceEntry, Item} from "./interfaces.ts";
import {Player} from "./Player.ts";
import {randomItem} from "./utils.ts";
import {HomingPistol, Pistol, SpreadWeapon} from "./weapons.ts";
import {Dagger, HomingPistol, Pistol, SpreadWeapon} from "./weapons.ts";
import type {World} from "./World.ts";
export enum Rarity {
@@ -40,6 +40,7 @@ export class ItemManagement {
this.ITEMS.push(new HomingPistolItem())
this.ITEMS.push(new PistolItem())
this.ITEMS.push(new SpreadWeaponItem())
this.ITEMS.push(new DaggerWeaponItem())
}
}
@@ -91,7 +92,7 @@ export class SpeedUp extends BaseItem {
}
getRarity(): Rarity {
return Rarity.COMMON;
return Rarity.LEGENDARY;
}
}
@@ -155,3 +156,19 @@ export class SpreadWeaponItem extends BaseItem {
}
}
export class DaggerWeaponItem extends BaseItem {
pickup(player: Player, world: World) {
player.addWeapon(Dagger.createDagger(world))
super.pickup(player, world)
}
name() {
return 'dagger'
}
getRarity(): Rarity {
return Rarity.EPIC;
}
}

View File

@@ -1,4 +1,4 @@
import type {Acting, Placeable, Healthy} from "./interfaces.ts";
import type {Acting, Placeable, Healthy, Weapon} from "./interfaces.ts";
import type {Vector} from "./base.ts";
import {World} from "./World.ts";
import {Cooldown, DeadPoint, Point, Vector} from "./base.ts";
@@ -12,6 +12,8 @@ import {
toRad
} from "./utils.ts";
import {InstanceOfUtils} from "./instance.ts";
import {MeleeWeapon} from "./weapons.ts";
import type {Enemy} from "./Enemies.ts";
export abstract class Projectile implements Acting, Placeable {
@@ -47,6 +49,7 @@ export abstract class Projectile implements Acting, Placeable {
this.status.collisionCooldown.resetCooldown()
}
} else if(this.parent === this.world.player) {
// TODO think why this was done, why do I need to calculate the newest target on _each_ act?
let closestTargetTo = this.world.getClosestTargetToButNot(this.position, this.lastColliding);
if(closestTargetTo !== undefined && closestTargetTo[1] !== undefined) {
let target: Placeable = closestTargetTo[1]!;
@@ -127,6 +130,62 @@ export class StraightProjectile extends Projectile {
}
}
export class WeaponProjectile 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: MeleeWeapon, target: Vector) {
super(position, speedVec, stats, world, parent);
this.weapon = weapon;
this.target = target.clone()
}
draw(ctx: CanvasRenderingContext2D) {
drawDot(this.position, this.stats.size, 'pink', ctx) // todo render the weapon instead
}
act() {
this.move()
// TODO It seems that the projectile doesnt _quite_ hit the enemy, but is just getting close to it
let hitEnemies = this.world.getAllInRange(this.position, 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;
}
} else {
this.position = moveInDirectionOf(this.position, this.world.player.position, this.speedVec.vecLength())
}
if(this.movingBack && this.position.distanceTo(this.world.player.position) < (this.stats.size + this.world.player.stats.size)) {
this.weapon.reset();
this.die()
}
}
static createWeaponProjectile(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)
projectile.color = color === undefined ? 'red' : color!;
world.addProjectile(projectile)
return projectile;
}
}
export class HomingProjectile extends Projectile {
private target: Placeable;

View File

@@ -1,7 +1,7 @@
import type {Weapon} from "./interfaces.ts";
import {drawDot, toRad} from "./utils.ts";
import {Player} from "./Player.ts";
import {HomingProjectile, Projectile, ProjectileStats, StraightProjectile} from "./projectile.ts";
import {HomingProjectile, Projectile, ProjectileStats, StraightProjectile, WeaponProjectile} from "./projectile.ts";
import {World} from "./World.ts";
import {Vector} from "./base.ts";
@@ -77,6 +77,57 @@ export abstract class RangeWeapon extends BasicWeapon {
}
}
export abstract class MeleeWeapon extends RangeWeapon {
protected launched: boolean;
act() {
if(this.shootCooldown <= 0) {
if(this.createProjectile()) {
this.shootCooldown = 1;
}
}
}
reset() {
this.shootCooldown = 0
}
}
export class Dagger extends MeleeWeapon {
createProjectile(): boolean {
let range = this.calculateRange()
let closestTargetTo = this.world.getClosestTargetTo(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 projectile = WeaponProjectile.createWeaponProjectile(this.world, this.getPosition(), closestTargetTo[1]!.getPosition(), this.player, stats, this)
this.projectiles.push(projectile)
return true
} else {
return false;
}
}
static createDagger(world: World, offset?: Vector) {
if(!offset) {
offset = new Vector(5, 5)
}
let stats = new WeaponStats()
.withProjectileSpeed(3)
.withDamage(15)
.withShootInterval(50)
let pistol = new Dagger(world, stats)
pistol.offset = offset;
pistol.size = 4;
pistol.color = 'gray';
return pistol;
}
}
export class HomingPistol extends RangeWeapon {
draw(ctx: CanvasRenderingContext2D) {