diff --git a/absurd-survivors/src/Enemies.ts b/absurd-survivors/src/Enemies.ts index ff37c50..3a74183 100644 --- a/absurd-survivors/src/Enemies.ts +++ b/absurd-survivors/src/Enemies.ts @@ -6,7 +6,7 @@ import type {Projectile} from "./projectile.ts"; import {StraightProjectile} from "./projectile.ts"; import {HealthPack, ItemDrop, LevelDrop, MoneyDrop} from "./drop.ts"; import {ItemManagement} from "./items.ts"; -import {ProjectileStats} from "./stats.ts"; +import {EnemyStats, ProjectileStats} from "./stats.ts"; import {EnemyStatus} from "./status.ts"; import {NumberDisplayParticle} from "./particles.ts"; @@ -15,13 +15,15 @@ export abstract class Enemy implements Placeable, Drawable, Acting, Healthy { protected speed: number; protected world: World; protected size: number - protected status: EnemyStatus = new EnemyStatus(10); + protected status: EnemyStatus; protected drops: KillChanceTable; - constructor(position: Vector) { + constructor(position: Vector, enemyStats: EnemyStats) { this.drops = new KillChanceTable(); this.drops.addDrop( {chance: 10, creationMethod: this.spawnMoney}) this._position = position.clone(); + let health = enemyStats.getEffectiveHealth() + this.status = new EnemyStatus(health); } draw(ctx: CanvasRenderingContext2D) { @@ -74,8 +76,8 @@ export abstract class Enemy implements Placeable, Drawable, Acting, Healthy { export class BasicEnemy extends Enemy { - constructor(position: Vector) { - super(position); + constructor(position: Vector, enemyStats: EnemyStats) { + super(position, enemyStats); } protected color: string; @@ -109,7 +111,8 @@ export class BasicEnemy extends Enemy { if(position === undefined) { position = world.randomPlace() } - let basicEnemy = new BasicEnemy(position); + let enemyStats = new EnemyStats().withHealthFactor(world.getEnemyHealthFactor()); + let basicEnemy = new BasicEnemy(position, enemyStats); basicEnemy.size = 5; basicEnemy.world = world; basicEnemy.speed = 0.5; @@ -125,8 +128,8 @@ export class ShootingEnemy extends BasicEnemy implements Shooting { private shootInterval: number; private projectiles: Projectile[] = [] - constructor(position: Vector) { - super(position); + constructor(position: Vector, enemyStats: EnemyStats) { + super(position, enemyStats); } removeProjectile(projectile: Projectile) { @@ -161,7 +164,8 @@ export class ShootingEnemy extends BasicEnemy implements Shooting { if(position === undefined) { position = world.randomPlace() } - let shootingEnemy = new ShootingEnemy(position); + let enemyStats = new EnemyStats().withHealthFactor(world.getEnemyHealthFactor());; + let shootingEnemy = new ShootingEnemy(position, enemyStats); shootingEnemy.size = 5; shootingEnemy.world = world; shootingEnemy.speed = 0.5; @@ -174,8 +178,8 @@ export class ShootingEnemy extends BasicEnemy implements Shooting { export class HealthEnemy extends Enemy { - constructor(position: Vector) { - super(position); + constructor(position: Vector, enemyStats: EnemyStats) { + super(position, enemyStats); } protected color: string; @@ -204,7 +208,8 @@ export class HealthEnemy extends Enemy { if(position === undefined) { position = world.randomPlace() } - let basicEnemy = new HealthEnemy(position); + let enemyStats = new EnemyStats().withHealthFactor(world.getEnemyHealthFactor());; + let basicEnemy = new HealthEnemy(position, enemyStats); basicEnemy.size = 5; basicEnemy.world = world; basicEnemy.speed = 0; @@ -221,8 +226,8 @@ export class HealthEnemy extends Enemy { export class ContainerEnemy extends Enemy { private drops: KillChanceTable; - constructor(position: Vector) { - super(position); + constructor(position: Vector, enemyStats: EnemyStats) { + super(position, enemyStats); this.status.health = 5; this.drops = new KillChanceTable(); ItemManagement.getItemsWithRarityFactor().forEach(drop => { @@ -272,7 +277,8 @@ export class ContainerEnemy extends Enemy { if(position === undefined) { position = world.randomPlace() } - let basicEnemy = new ContainerEnemy(position); + let enemyStats = new EnemyStats().withHealthFactor(world.getEnemyHealthFactor());; + let basicEnemy = new ContainerEnemy(position, enemyStats); basicEnemy.size = 5; basicEnemy.world = world; basicEnemy.speed = 0; diff --git a/absurd-survivors/src/World.ts b/absurd-survivors/src/World.ts index 413210e..f4107f6 100644 --- a/absurd-survivors/src/World.ts +++ b/absurd-survivors/src/World.ts @@ -15,12 +15,14 @@ export class World { private _tick: number = 0; private static readonly TICK_INTERVAL = 10; private timeStamp: Date; + private startTimeStamp: Date; constructor(player: Player, ctx: CanvasRenderingContext2D, size: Vector) { this._player = player; this._ctx = ctx; this._size = size; this.timeStamp = new Date(); + this.startTimeStamp = new Date(); } enemiesAct() { @@ -80,7 +82,6 @@ export class World { this._player.position.y = Math.max(this._player.getSize(), this._player.position.y) } - maxValue() { return Math.max(this.size.x, this.size.y) } @@ -89,7 +90,19 @@ export class World { return this._size; } - tick() { + get tick(): number { + return this._tick; + } + + getSecondsPassed() { + return (this.timeStamp.getTime() - this.startTimeStamp.getTime()) / 1000 + } + + getEnemyHealthFactor() { + return this.getSecondsPassed() / 30; + } + + triggerTick() { this._tick += 1; if((this._tick % World.TICK_INTERVAL) == 0) { let currentTimeStamp = new Date(); diff --git a/absurd-survivors/src/items.ts b/absurd-survivors/src/items.ts index ce7d052..0190bb8 100644 --- a/absurd-survivors/src/items.ts +++ b/absurd-survivors/src/items.ts @@ -44,6 +44,10 @@ export class ItemManagement { this.ITEMS.push(new ChainBallWeaponItem()) this.ITEMS.push(new PullRangeUp()) this.ITEMS.push(new SpearWeaponItem()) + this.ITEMS.push(new DamageUpFactor()) + this.ITEMS.push(new DamageFactorUp()) + this.ITEMS.push(new DamageFactorUpFactor()) + this.ITEMS.push(new DamageUp()) } } @@ -206,5 +210,62 @@ export class SpearWeaponItem extends BaseItem { } } +export class DamageFactorUpFactor extends BaseItem { + pickup(player: Player, world: World) { + player.changeBaseStat(1, PlayerStats.factorDamageFactor) + super.pickup(player, world) + } + name() { + return 'damageFactorUpFactor' + } + getRarity(): Rarity { + return Rarity.LEGENDARY; + } +} + +export class DamageUp extends BaseItem { + pickup(player: Player, world: World) { + player.changeBaseStat(1, PlayerStats.increaseDamage) + super.pickup(player, world) + } + + name() { + return 'damageUp' + } + + getRarity(): Rarity { + return Rarity.COMMON; + } +} + +export class DamageUpFactor extends BaseItem { + pickup(player: Player, world: World) { + player.changeBaseStat(1, PlayerStats.factorDamage) + super.pickup(player, world) + } + + name() { + return 'damageUpFactor' + } + + getRarity(): Rarity { + return Rarity.LEGENDARY; + } +} + +export class DamageFactorUp extends BaseItem { + pickup(player: Player, world: World) { + player.changeBaseStat(1, PlayerStats.increaseDamageFactor) + super.pickup(player, world) + } + + name() { + return 'damageFactorUp' + } + + getRarity(): Rarity { + return Rarity.UNCOMMON; + } +} \ No newline at end of file diff --git a/absurd-survivors/src/main.ts b/absurd-survivors/src/main.ts index 1e874cf..c8d5bdc 100644 --- a/absurd-survivors/src/main.ts +++ b/absurd-survivors/src/main.ts @@ -38,7 +38,7 @@ function updateCanvas() { ctx.clearRect(0, 0, world.size.x, world.size.y); hud.draw(ctx) if(!state.ended) { - world.tick() + world.triggerTick() world.enemiesAct() world.player.act() world.draw() diff --git a/absurd-survivors/src/stats.ts b/absurd-survivors/src/stats.ts index a5b7aec..c4c2dfc 100644 --- a/absurd-survivors/src/stats.ts +++ b/absurd-survivors/src/stats.ts @@ -8,6 +8,8 @@ export class PlayerStats { private _weaponRange: number; private _weaponRangeFactor: number; private _healthRegen: number; + private _damage: number; + private _damageFactor: number; constructor() { this._speed = 3; @@ -17,6 +19,8 @@ export class PlayerStats { this._weaponRange = 250; this._weaponRangeFactor = 1; this._healthRegen = 0.001; + this._damage = 0; + this._damageFactor = 0; } resetToBasic() { @@ -25,7 +29,9 @@ export class PlayerStats { this._pullRange = 0; this._weaponRange = 0; this._weaponRangeFactor = 1; - this._healthRegen = 0.1; + this._healthRegen = 0.001; + this._damage = 0; + this._damageFactor = 0; } increaseLevel() { @@ -35,6 +41,8 @@ export class PlayerStats { this._weaponRange *= 1.25 this._weaponRangeFactor += 0.1 this._healthRegen += 0.1 + this._damage += 1; + this._damageFactor += 0.1; } mergeStats(otherStats: PlayerStats) { @@ -44,6 +52,8 @@ export class PlayerStats { this._weaponRange += otherStats._weaponRange this._weaponRangeFactor += otherStats._weaponRangeFactor; this._healthRegen += otherStats._healthRegen; + this._damage += otherStats._damage; + this._damageFactor += otherStats._damageFactor } clone() { @@ -64,6 +74,22 @@ export class PlayerStats { stats._speed *= value } + static factorDamage(stats: PlayerStats, value: number) { + stats._damage *= value + } + + static increaseDamage(stats: PlayerStats, value: number) { + stats._damage += value + } + + static factorDamageFactor(stats: PlayerStats, value: number) { + stats._damageFactor *= value + } + + static increaseDamageFactor(stats: PlayerStats, value: number) { + stats._damageFactor += value + } + static increasePullRange(stats: PlayerStats, value: number) { stats._pullRange += value } @@ -104,6 +130,10 @@ export class PlayerStats { return this._weaponRange * this._weaponRangeFactor; } + get effectiveDamage(): number { + return this._damage * this._damageFactor; + } + public static defaultPlayerStats(): PlayerStats { return new PlayerStats(); } @@ -178,4 +208,28 @@ export class ProjectileStats { get deathSplit(): number { return this._deathSplit; } +} + +export class EnemyStats { + private _healthFactor: number; + private _baseHealth: number; + + constructor() { + this._healthFactor = 1; + this._baseHealth = 10 + } + + withHealthFactor(healthFactor: number) { + this._healthFactor = healthFactor; + return this + } + + withBaseHealth(baseHealth: number) { + this._baseHealth = baseHealth; + return this + } + + getEffectiveHealth() { + return this._baseHealth * this._healthFactor + } } \ No newline at end of file diff --git a/absurd-survivors/src/ui.ts b/absurd-survivors/src/ui.ts index cfa9eed..f3490f2 100644 --- a/absurd-survivors/src/ui.ts +++ b/absurd-survivors/src/ui.ts @@ -127,7 +127,8 @@ export class PlayerInfo implements DrawContainer { new StatLabel(() => 'Level', () => this.world.player.status.level), new StatLabel(() => 'Speed', () => Math.floor(this.world.player.effectiveStats.speed)), new StatLabel(() => 'Pull range', () => Math.floor(this.world.player.effectiveStats.pullRange)), - new StatLabel(() => 'Weapon range', () => Math.floor(this.world.player.effectiveStats.effectiveWeaponRange)) + new StatLabel(() => 'Weapon range', () => Math.floor(this.world.player.effectiveStats.effectiveWeaponRange)), + new StatLabel(() => 'Damage', () => Math.floor(this.world.player.effectiveStats.effectiveDamage)) ] } diff --git a/absurd-survivors/src/weapons.ts b/absurd-survivors/src/weapons.ts index 87e735c..d88664e 100644 --- a/absurd-survivors/src/weapons.ts +++ b/absurd-survivors/src/weapons.ts @@ -50,6 +50,10 @@ export abstract class BasicWeapon implements Weapon { return this.size; } + getDamage() { + return this.stats.damage + this.player.effectiveStats.effectiveDamage; + } + getOffset(): Vector { return this.offset; } @@ -120,7 +124,7 @@ export class Spear extends MeleeWeapon { let stats = new ProjectileStats() .withPiercings(1000) .withSize(3) - .withDamage(this.stats.damage) + .withDamage(this.getDamage()) .withSpeed(this.stats.projectileSpeed); let offsetVector = Vector.createVector(closestTargetTo[1]!.getPosition(), this.player.position).multiply(1.1); if(offsetVector.vecLength() < 15) { @@ -161,7 +165,7 @@ export class ChainBall extends MeleeWeapon { let stats = new ProjectileStats() .withPiercings(1000) .withSize(3) - .withDamage(this.stats.damage) + .withDamage(this.getDamage()) .withSpeed(this.stats.projectileSpeed); let projectile = ChainBallProjectile.createChainBallProjectile(this.world, this.getPosition(), closestTargetTo[1]!.getPosition(), this.player, stats, this) this.projectiles.push(projectile) @@ -201,7 +205,7 @@ export class HomingPistol extends RangeWeapon { let stats = new ProjectileStats() .withPiercings(this.stats.projectilePiercings) .withSize(1) - .withDamage(this.stats.damage) + .withDamage(this.getDamage()) .withSpeed(this.stats.projectileSpeed); let projectile = HomingProjectile.createHomingProjectile(this.world, this.getPosition(), this.player, closestTargetTo[1]!, stats, 'yellow') this.projectiles.push(projectile) @@ -240,7 +244,7 @@ export class Pistol extends RangeWeapon { let stats = new ProjectileStats() .withPiercings(this.stats.projectilePiercings) .withSize(1) - .withDamage(this.stats.damage) + .withDamage(this.getDamage()) .withSpeed(this.stats.projectileSpeed); let projectile = StraightProjectile.createStraightProjectile(this.world, this.getPosition(), closestTargetTo[1]!.getPosition(), this.player, stats, 'pink') this.projectiles.push(projectile) @@ -278,7 +282,7 @@ export class SpreadWeapon extends RangeWeapon { let stats = new ProjectileStats() .withPiercings(this.stats.projectilePiercings) .withSize(1) - .withDamage(this.stats.damage) + .withDamage(this.getDamage()) .withSpeed(this.stats.projectileSpeed); let targetPosition = closestTargetTo[1]!.getPosition(); let weaponPosition = this.getPosition();