diff --git a/buildtools/ant_modules/dist.xml b/buildtools/ant_modules/dist.xml index 5e65c516b29..e8ded02dd6a 100644 --- a/buildtools/ant_modules/dist.xml +++ b/buildtools/ant_modules/dist.xml @@ -132,6 +132,9 @@ + + + diff --git a/data/maps/effect/lightning.png b/data/maps/effect/lightning.png new file mode 100644 index 00000000000..510f0117462 Binary files /dev/null and b/data/maps/effect/lightning.png differ diff --git a/doc/contributors.md b/doc/contributors.md index 46bc79976bf..8d26c926297 100644 --- a/doc/contributors.md +++ b/doc/contributors.md @@ -998,6 +998,7 @@ The following people released their work to the public with a suitable license f * [Inchadney](http://inchadney.com/sounds.html) * [Gniffelbaf](https://freesound.org/people/Gniffelbaf/) * [Kevin Luce (kevp888)](https://freesound.org/people/kevp888/) +* [Gordon Dylan Johnson (GDJ)](https://openclipart.org/artist/GDJ) diff --git a/doc/contributors/contributors.json b/doc/contributors/contributors.json index 3c14d8f4bc7..dcdff94ebd0 100644 --- a/doc/contributors/contributors.json +++ b/doc/contributors/contributors.json @@ -4772,6 +4772,11 @@ "name": "kevp888", "fullname": "Kevin Luce", "link": "https://freesound.org/people/kevp888/" + }, + { + "name": "GDJ", + "fullname": "Gordon Dylan Johnson", + "link": "https://openclipart.org/artist/GDJ" } ] } diff --git a/doc/sources/graphics-misc.txt b/doc/sources/graphics-misc.txt index 61a8c6789cc..a542471d44d 100644 --- a/doc/sources/graphics-misc.txt +++ b/doc/sources/graphics-misc.txt @@ -63,6 +63,10 @@ rotate* rg1024; CC0; https://openclipart.org/detail/20247 settings* ben; CC0; https://openclipart.org/detail/192629 sound* mightyman; CC0; https://openclipart.org/detail/165992 +data/maps/effect/ + +lightning Gordon Dylan Johnson (GDJ); CC0; https://openclipart.org/detail/268835 + data/sprites/ baby_dragon.png Kimmo Rundelin (kiheru); CC BY-SA 3.0; Stendhal diff --git a/src/js/stendhal/data/Paths.ts b/src/js/stendhal/data/Paths.ts index 15931181eb9..946c63b11e5 100644 --- a/src/js/stendhal/data/Paths.ts +++ b/src/js/stendhal/data/Paths.ts @@ -22,7 +22,8 @@ export class Paths { public static readonly sprites = Paths.data + "/sprites"; public static readonly weather = Paths.sprites + "/weather"; public static readonly achievements = Paths.sprites + "/achievements"; - public static readonly tileset = Paths.data + "/maps/tileset"; + public static readonly maps = Paths.data + "/maps"; + public static readonly tileset = Paths.maps + "/tileset"; public static readonly ws = Paths.extractPath("data-ws"); /** diff --git a/src/js/stendhal/event/generic/KikaPunishmentEvent.ts b/src/js/stendhal/event/generic/KikaPunishmentEvent.ts index 9cf5648f527..49dcf5dd2e8 100644 --- a/src/js/stendhal/event/generic/KikaPunishmentEvent.ts +++ b/src/js/stendhal/event/generic/KikaPunishmentEvent.ts @@ -12,21 +12,65 @@ import { RPEvent } from "../RPEvent"; +import { Paths } from "../../data/Paths"; +import { store } from "../../data/SpriteStore"; + import { SoundLayer } from "../../data/enum/SoundLayer"; +import { SoundID } from "../../data/sound/SoundID"; + import { SoundManager } from "../../ui/SoundManager"; +import { ViewPort } from "../../ui/ViewPort"; +import { Color } from "../../util/Color"; + +/** + * Creates effects for Kika punishment. + * + * TODO: + * - maybe make thunderclap louder + * - add some type of beforehand notice, maybe in travel log, about potential punishment + */ export class KikaPunishmentEvent extends RPEvent { - override execute(entity: any) { - // DEBUG: - console.log("Kika punishment!"); + private startTime = 0; + private image = store.get(Paths.maps + "/effect/lightning.png"); - SoundManager.get().playGlobalizedEffect("event/thunderclap", SoundLayer.SFX.value); - // TODO: - // - lightning flash - // - maybe make thunderclap louder + override execute(entity: any) { + this.startTime = Date.now(); + // thunder sound + SoundManager.get().playGlobalizedEffect(SoundID["thunderclap"], SoundLayer.SFX.value); + // lightning visual effect + const viewport = ViewPort.get(); + viewport.onDrawComplete = (ctx: CanvasRenderingContext2D, offsetX: number, offsetY: number) => { + this.drawLightning(ctx, offsetX, offsetY); + } + window.setTimeout(function() { viewport.onDrawComplete = undefined; }, 300); + } + + /** + * Draws a lighning effect on the viewport. + * + * @param ctx {CanvasRenderingContext2D} + * Canvas drawing context. + * @param offsetX {number} + * Canvas horizontal offset. + * @param offsetY {number} + * Canvas vertical offset. + */ + private drawLightning(ctx: CanvasRenderingContext2D, offsetX: number, offsetY: number) { + const timeDiff = Date.now() - this.startTime; + ctx.save(); + if (timeDiff <= 100 || timeDiff > 200) { + ctx.globalAlpha = 0.75; + } + ctx.fillStyle = Color.WHITE; + ctx.fillRect(offsetX, offsetY, 640, 480); + if (this.image.height) { + ctx.drawImage(this.image, offsetX, offsetY); + } + ctx.restore(); } } diff --git a/src/js/stendhal/ui/ViewPort.ts b/src/js/stendhal/ui/ViewPort.ts index ed23cfd7d03..e2d764384e8 100644 --- a/src/js/stendhal/ui/ViewPort.ts +++ b/src/js/stendhal/ui/ViewPort.ts @@ -74,6 +74,14 @@ export class ViewPort { /** Styles to be applied when chat panel is not floating. */ private readonly initialStyle: {[prop: string]: string}; + /** + * Callback for instructions to execute when a drawing cycle on the viewport is complete. + * + * The function is called with the parameters `ctx` (CanvasRenderingContext2D), `offsetX`, + * and `offsetY`. + */ + public onDrawComplete?: Function; + /** Singleton instance. */ private static instance: ViewPort; @@ -153,6 +161,10 @@ export class ViewPort { // redraw inventory sprites stendhal.ui.equip.update(); (ui.get(UIComponentEnum.PlayerEquipment) as PlayerEquipmentComponent).update(); + + if (this.onDrawComplete) { + this.onDrawComplete(this.ctx, this.offsetX, this.offsetY); + } } } window.setTimeout(function() {