Skip to content

Commit

Permalink
Add flame wheel spell
Browse files Browse the repository at this point in the history
  • Loading branch information
lorgan3 committed Apr 9, 2024
1 parent 9160ef7 commit fde8f5e
Show file tree
Hide file tree
Showing 12 changed files with 218 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,4 @@ Check `package.json`, there are also commands available to run tests and check t
- [Ice](https://freesound.org/people/kyles/sounds/452252/): kyles
- [Rumble](https://freesound.org/people/prozaciswack/sounds/82722/): prozaciswack
- [Drain](https://freesound.org/people/Incarnadine/sounds/17128/): Incarnadine
- [Burn](https://freesound.org/people/magnuswaker/sounds/581078/): magnuswaker
Binary file added public/atlas/spells/wheel_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/atlas/spells/wheel_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/atlas/spells/wheel_3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/atlas/spells/wheel_4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/sound/581078__magnuswaker__flame-loop.mp3
Binary file not shown.
2 changes: 2 additions & 0 deletions src/data/entity/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Bakuretsu } from "../spells/bakuretsu";
import { Bomb } from "../spells/bomb";
import { Catastravia } from "../spells/catastravia";
import { CatastraviaMissile } from "../spells/catastraviaMissile";
import { FireWheel } from "../spells/fireWheel";
import { Fireball } from "../spells/fireball";
import { GateOfBabylon } from "../spells/gateOfBabylon";
import { Hairpin } from "../spells/hairpin";
Expand Down Expand Up @@ -56,6 +57,7 @@ export const ENTITIES: Record<
[EntityType.Excalibur]: Sword,
[EntityType.Bakuretsu]: Bakuretsu,
[EntityType.WindBlast]: WindBlast,
[EntityType.FireWheel]: FireWheel,
};

interface SpawnRateData {
Expand Down
1 change: 1 addition & 0 deletions src/data/entity/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ export enum EntityType {
Excalibur,
Bakuretsu,
WindBlast,
FireWheel,
}

export enum Priority {
Expand Down
193 changes: 193 additions & 0 deletions src/data/spells/fireWheel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
import { AnimatedSprite, Container } from "pixi.js";
import { Level } from "../map/level";
import { AssetsContainer } from "../../util/assets/assetsContainer";

import { circle16x16 } from "../collision/precomputed/circles";
import { ExplosiveDamage } from "../damage/explosiveDamage";
import { Character } from "../entity/character";

import { Explosion } from "../../graphics/explosion";
import { Manager } from "../network/manager";
import { TurnState } from "../network/types";
import { EntityType, Layer, Priority, Syncable } from "../entity/types";
import { Server } from "../network/server";
import { Element } from "./types";

import { StickyBody } from "../collision/stickyBody";
import { ControllableSound } from "../../sound/controllableSound";
import { Sound } from "../../sound";

export class FireWheel extends Container implements Syncable {
public readonly body: StickyBody;
private sprite: AnimatedSprite;
private lifetime = 500;
private sound?: ControllableSound;

public id = -1;
public readonly type = EntityType.FireWheel;
public readonly priority = Priority.High;
public layer = Layer.Background;

constructor(x: number, y: number, speed: number, private direction: number) {
super();

this.body = new StickyBody(Level.instance.terrain.collisionMask, {
mask: circle16x16,
velocity: 2,
});
this.body.move(x, y);
this.body.addAngularVelocity(speed, direction);
this.position.set(x * 6, y * 6);
this.sound = ControllableSound.fromEntity(this, Sound.Fire);

const atlas = AssetsContainer.instance.assets!["atlas"];

this.sprite = new AnimatedSprite(atlas.animations["spells_wheel"]);
this.sprite.animationSpeed = 0.1;
this.sprite.scale.set(3);
this.sprite.play();
this.sprite.anchor.set(0.5);
this.sprite.position.set(3);

// const canvas = new OffscreenCanvas(1, 1);
// const ctx = canvas.getContext("2d")!;

// ctx.fillStyle = "#000000";
// ctx.fillRect(0, 0, 1, 1);

// const sprite = new Sprite(Texture.from(canvas));
// sprite.scale.set(6);

// const sprite2 = new Sprite(
// Texture.fromBuffer(circle16x16Canvas.data, 16, 16)
// );
// sprite2.anchor.set(0);
// sprite2.scale.set(6);
// sprite2.alpha = 0.5;
// sprite2.position.set(-48);

this.addChild(this.sprite);

// When spawning in a wall
if (
Server.instance &&
Level.instance.terrain.collisionMask.collidesWithPoint(
...this.body.position
)
) {
this._die(x, y);
}
}

private _die(x: number, y: number) {
Level.instance.damage(
new ExplosiveDamage(
x,
y,
16,
3,
2 + Manager.instance.getElementValue(Element.Elemental)
)
);
Server.instance.kill(this);
}

die() {
Level.instance.remove(this);
new Explosion(this.position.x, this.position.y);
Manager.instance.setTurnState(TurnState.Ending);
this.sound?.destroy();
}

getCenter(): [number, number] {
return [this.position.x, this.position.y];
}

tick(dt: number) {
this.body.tick(dt);
this.sprite.scale.x = this.body.direction * 3;
const [x, y] = this.body.precisePosition;
this.position.set(x * 6, y * 6);

if (this.body.sticky) {
if (this.sound?.alias !== Sound.Burn) {
this.sound?.destroy();
this.sound = undefined;
}

if (!this.sound) {
this.sound = ControllableSound.fromEntity(this, Sound.Burn, {
loop: true,
});
} else {
this.sound.update(this);
}
}

if (!Server.instance) {
return;
}

this.lifetime -= dt;
if (
this.lifetime <= 0 ||
Level.instance.terrain.killbox.collidesWith(
this.body.mask,
this.position.x - 48,
this.position.y - 48
)
) {
this._die(x, y);
return;
}

Level.instance.withNearbyEntities(
this.position.x,
this.position.y,
10 * 6,
(entity) => {
if (entity instanceof Character) {
this._die(x, y);
return true;
}
}
);
}

serialize() {
return this.body.serialize();
}

deserialize(data: ReturnType<FireWheel["serialize"]>) {
this.body.deserialize(data);
}

serializeCreate() {
return [
...this.body.precisePosition,
this.body.velocity,
this.direction,
] as const;
}

static create(data: ReturnType<FireWheel["serializeCreate"]>) {
return new FireWheel(...data);
}

static cast(
x: number,
y: number,
character: Character,
power: number,
direction: number
) {
if (!Server.instance) {
return;
}

const entity = new FireWheel(x, y, power * 1.5, direction);

Server.instance.create(entity);
return entity;
}
}
17 changes: 17 additions & 0 deletions src/data/spells/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { Hairpin } from "./hairpin";
import { IceWallSpawner } from "./iceWallSpawner";
import { Rock } from "./rock";
import { Meteor } from "./meteor";
import { FireWheel } from "./fireWheel";

export interface Spell<TData = any> {
name: string;
Expand Down Expand Up @@ -331,6 +332,21 @@ const METEOR = spell(Lock, {
},
});

const FIRE_WHEEL = spell(PoweredArcaneCircle, {
name: "Flame wheel",
description: "",
elements: [Element.Elemental],
cost: 20,
data: {
projectile: FireWheel,
xOffset: 14,
yOffset: 17.5,
x: 3,
y: 6.5,
turnState: TurnState.Attacked,
},
});

export const SPELLS: Spell[] = [
MELEE,
FIREBALL,
Expand All @@ -351,4 +367,5 @@ export const SPELLS: Spell[] = [
ICE_WALL,
ROCK,
METEOR,
FIRE_WHEEL,
];
4 changes: 2 additions & 2 deletions src/sound/controllableSound.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class ControllableSound {
}

constructor(
private alias: Sound,
public readonly alias: Sound,
private filter: filters.StereoFilter,
options: PlayOptions
) {
Expand Down Expand Up @@ -116,7 +116,7 @@ class ControllableSound {
);
}

update(entity: HurtableEntity | [number, number]) {
update(entity: Spawnable | [number, number]) {
if (this.ref) {
const { volume, pan } = ControllableSound.getSoundOptions(
...("getCenter" in entity ? entity.getCenter() : entity)
Expand Down
2 changes: 2 additions & 0 deletions src/sound/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export enum Sound {
Ice = "iceSnd",
Rumble = "rumbleSnd",
Drain = "drainSnd",
Burn = "burnSnd",
}

interface SoundData {
Expand Down Expand Up @@ -113,6 +114,7 @@ addSoundData(Sound.Ice, "452252__kyles__ice-cracks-medium7-brittle_2");
addSoundData(Sound.Ice, "452252__kyles__ice-cracks-medium7-brittle_3");
addSoundData(Sound.Rumble, "82722__prozaciswack__digging");
addSoundData(Sound.Drain, "17128__incarnadine__water_go_down_the_hole");
addSoundData(Sound.Burn, "581078__magnuswaker__flame-loop");

export const SOUND_ASSETS = Object.fromEntries(
Object.values(SOUND_DATA).reduce(
Expand Down

0 comments on commit fde8f5e

Please sign in to comment.