Tune Princess Lima v2 boss balance and Sun Crystal aid
All checks were successful
Build Org Website / build (push) Successful in 37s
0
assets/images/play/princess-lima/actor-atlas-v2.png
Normal file → Executable file
|
Before Width: | Height: | Size: 221 KiB After Width: | Height: | Size: 221 KiB |
0
assets/images/play/princess-lima/effects-atlas-v2.png
Normal file → Executable file
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
0
assets/images/play/princess-lima/portrait-atlas-v2.png
Normal file → Executable file
|
Before Width: | Height: | Size: 2.6 MiB After Width: | Height: | Size: 2.6 MiB |
0
assets/images/play/princess-lima/world-tiles-v2.png
Normal file → Executable file
|
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 6.0 KiB |
0
assets/maps/princess-lima/bossArena.json
Normal file → Executable file
0
assets/maps/princess-lima/camp.json
Normal file → Executable file
0
assets/maps/princess-lima/chamber.json
Normal file → Executable file
0
assets/maps/princess-lima/forest.json
Normal file → Executable file
0
assets/maps/princess-lima/fortressExterior.json
Normal file → Executable file
0
assets/maps/princess-lima/fortressInterior.json
Normal file → Executable file
0
assets/maps/princess-lima/mountain.json
Normal file → Executable file
0
assets/maps/princess-lima/ruins.json
Normal file → Executable file
0
assets/maps/princess-lima/village.json
Normal file → Executable file
0
assets/maps/princess-lima/world-tiles.tsj
Normal file → Executable file
2
assets/scripts/pages/princess-lima-v2-data.js
Normal file → Executable file
@@ -63,7 +63,7 @@
|
|||||||
briar_wolf: { role: "boss", boss: true, phases: 2, health: 30, damage: 14, speed: 118, awareness: 430, attackRange: 56, cooldown: 950, telegraph: 380 },
|
briar_wolf: { role: "boss", boss: true, phases: 2, health: 30, damage: 14, speed: 118, awareness: 430, attackRange: 56, cooldown: 950, telegraph: 380 },
|
||||||
stone_guardian: { role: "boss", boss: true, phases: 3, health: 42, damage: 17, speed: 54, awareness: 430, attackRange: 74, cooldown: 1350, telegraph: 620 },
|
stone_guardian: { role: "boss", boss: true, phases: 3, health: 42, damage: 17, speed: 54, awareness: 430, attackRange: 74, cooldown: 1350, telegraph: 620 },
|
||||||
captain: { role: "boss", boss: true, phases: 2, health: 36, damage: 15, speed: 78, awareness: 430, attackRange: 54, cooldown: 1050, telegraph: 360 },
|
captain: { role: "boss", boss: true, phases: 2, health: 36, damage: 15, speed: 78, awareness: 430, attackRange: 54, cooldown: 1050, telegraph: 360 },
|
||||||
malrec: { role: "boss", boss: true, phases: 3, health: 64, damage: 18, speed: 70, awareness: 520, attackRange: 190, cooldown: 1200, telegraph: 520 }
|
malrec: { role: "boss", boss: true, phases: 3, health: 52, damage: 13, speed: 60, awareness: 520, attackRange: 190, cooldown: 1600, telegraph: 760 }
|
||||||
});
|
});
|
||||||
|
|
||||||
const ITEMS = Object.freeze({
|
const ITEMS = Object.freeze({
|
||||||
|
|||||||
0
assets/scripts/pages/princess-lima-v2-game.js
Normal file → Executable file
0
assets/scripts/pages/princess-lima-v2-maps.js
Normal file → Executable file
26
assets/scripts/pages/princess-lima-v2-scenes.js
Normal file → Executable file
@@ -143,6 +143,7 @@
|
|||||||
this.pathTick = 0;
|
this.pathTick = 0;
|
||||||
this.puzzleProgress = {};
|
this.puzzleProgress = {};
|
||||||
this.spawnedObjects = new Set();
|
this.spawnedObjects = new Set();
|
||||||
|
this.sunAidUsed = false;
|
||||||
}
|
}
|
||||||
create() {
|
create() {
|
||||||
controller.scene = this;
|
controller.scene = this;
|
||||||
@@ -366,10 +367,23 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (action === "boss-mechanic") {
|
if (action === "boss-mechanic") {
|
||||||
|
if (this.sunAidUsed) return controller.status("The Sun Crystal is gathering its light again.");
|
||||||
|
const malrec = this.enemies.getChildren().find((enemy) => enemy.active && enemy.getData("actorId") === "malrec");
|
||||||
|
if (!malrec) return controller.status("The Sun Crystal is warm, but its moment has not come.");
|
||||||
|
this.sunAidUsed = true;
|
||||||
controller.state.flags.sun_veil_broken = true;
|
controller.state.flags.sun_veil_broken = true;
|
||||||
|
controller.state.health = Math.min(controller.state.maxHealth, controller.state.health + 25);
|
||||||
|
malrec.setData("health", Math.max(1, malrec.getData("health") - 12));
|
||||||
|
malrec.setData("stunnedUntil", this.time.now + 2100);
|
||||||
|
malrec.setData("state", "hurt");
|
||||||
|
malrec.setVelocity(0).setTint(0xffe39a).setTintMode(Phaser.TintModes.FILL);
|
||||||
|
this.projectiles.forEach((projectile) => projectile.active && projectile.destroy());
|
||||||
|
this.projectiles = [];
|
||||||
|
this.time.delayedCall(350, () => malrec.active && malrec.clearTint());
|
||||||
controller.save();
|
controller.save();
|
||||||
|
controller.updateHud();
|
||||||
this.cameras.main.flash(200, 255, 230, 150);
|
this.cameras.main.flash(200, 255, 230, 150);
|
||||||
controller.status("The Sun Crystal tears open Malrec's veil.");
|
controller.status("Lima channels the Sun Crystal: Malrec's veil breaks, and your strength returns.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (action === "block-tutorial") return controller.status("Hold Shift to block. Release and strike during an enemy's recovery.");
|
if (action === "block-tutorial") return controller.status("Hold Shift to block. Release and strike during an enemy's recovery.");
|
||||||
@@ -553,11 +567,15 @@
|
|||||||
const id = enemy.getData("actorId");
|
const id = enemy.getData("actorId");
|
||||||
const phase = enemy.getData("phase");
|
const phase = enemy.getData("phase");
|
||||||
if (["ranged", "caster", "support"].includes(spec.role) || id === "malrec") {
|
if (["ranged", "caster", "support"].includes(spec.role) || id === "malrec") {
|
||||||
const count = id === "malrec" ? phase * 2 + 1 : 1;
|
const count = id === "malrec" ? phase + 1 : 1;
|
||||||
|
const preparedReduction = id === "malrec"
|
||||||
|
? (controller.state.flags.defences_disabled ? 2 : 0) + (controller.state.flags.prisoners_freed ? 2 : 0)
|
||||||
|
: 0;
|
||||||
|
const damage = Math.max(8, spec.damage - preparedReduction);
|
||||||
for (let index = 0; index < count; index += 1) {
|
for (let index = 0; index < count; index += 1) {
|
||||||
const base = Phaser.Math.Angle.Between(enemy.x, enemy.y, this.player.x, this.player.y);
|
const base = Phaser.Math.Angle.Between(enemy.x, enemy.y, this.player.x, this.player.y);
|
||||||
const angle = base + (index - (count - 1) / 2) * 0.22;
|
const angle = base + (index - (count - 1) / 2) * (id === "malrec" ? 0.3 : 0.22);
|
||||||
this.spawnProjectile(enemy.x, enemy.y, angle, spec.damage, id === "malrec" ? 185 : 145);
|
this.spawnProjectile(enemy.x, enemy.y, angle, damage, id === "malrec" ? 150 : 145);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
0
assets/scripts/pages/princess-lima-v2-state.js
Normal file → Executable file
0
assets/scripts/pages/princess-lima-v2-systems.js
Normal file → Executable file
0
assets/scripts/pages/princess-lima-v2-ui.js
Normal file → Executable file
0
assets/scripts/vendor/easystar-0.4.4.min.js
vendored
Normal file → Executable file
@@ -816,3 +816,9 @@ at <ScriptBlock>, /home/zaine/master-folder/org-platform/org_web/build-logs/gite
|
|||||||
2026-07-30T13:59:09.5410036+01:00 [INFO] Running authoring server tests with /home/zaine/master-folder/org-platform/authoring-service/.venv/bin/python.
|
2026-07-30T13:59:09.5410036+01:00 [INFO] Running authoring server tests with /home/zaine/master-folder/org-platform/authoring-service/.venv/bin/python.
|
||||||
2026-07-30T13:59:09.6127470+01:00 [INFO] Authoring server tests passed: ran=0, failures=0, errors=0, skipped=0, exit=0
|
2026-07-30T13:59:09.6127470+01:00 [INFO] Authoring server tests passed: ran=0, failures=0, errors=0, skipped=0, exit=0
|
||||||
2026-07-30T13:59:09.8840005+01:00 [INFO] Sent authoring server test notification.
|
2026-07-30T13:59:09.8840005+01:00 [INFO] Sent authoring server test notification.
|
||||||
|
2026-07-30T15:01:49.5468944+01:00 [INFO] Prepared current build status for zaine/org_web: severity=Info, status=success
|
||||||
|
2026-07-30T15:01:49.5644329+01:00 [INFO] Fetching recent Gitea Actions runs for zaine/org_web.
|
||||||
|
2026-07-30T15:01:51.1104245+01:00 [INFO] Sent build status notification with 1 embed(s).
|
||||||
|
2026-07-30T15:01:51.1476262+01:00 [INFO] Running authoring server tests with /home/zaine/master-folder/org-platform/authoring-service/.venv/bin/python.
|
||||||
|
2026-07-30T15:01:51.2921733+01:00 [INFO] Authoring server tests passed: ran=0, failures=0, errors=0, skipped=0, exit=0
|
||||||
|
2026-07-30T15:01:51.6686257+01:00 [INFO] Sent authoring server test notification.
|
||||||
|
|||||||
0
docs/princess-lima-v2-implementation.md
Normal file → Executable file
@@ -4,7 +4,7 @@
|
|||||||
See the categories: @@html:<a href="../home/categories.html">Categories</a>@@
|
See the categories: @@html:<a href="../home/categories.html">Categories</a>@@
|
||||||
|
|
||||||
* Posts:
|
* Posts:
|
||||||
- [[file:career/career-list.org][Career List]] @@html:<span class="post-date">30-07-2026 14:54</span>@@
|
- [[file:career/career-list.org][Career List]] @@html:<span class="post-date">30-07-2026 15:01</span>@@
|
||||||
- [[file:career/cross-site-scripting-xss.org][Cross-Site Scripting (XSS)]] @@html:<span class="post-date">01-06-2026 10:21</span>@@ @@html:<a href="/tags/learning.html"><span class="post-tag">learning</span></a>@@ @@html:<a href="/tags/notes.html"><span class="post-tag">notes</span></a>@@
|
- [[file:career/cross-site-scripting-xss.org][Cross-Site Scripting (XSS)]] @@html:<span class="post-date">01-06-2026 10:21</span>@@ @@html:<a href="/tags/learning.html"><span class="post-tag">learning</span></a>@@ @@html:<a href="/tags/notes.html"><span class="post-tag">notes</span></a>@@
|
||||||
- [[file:career/ha-dr.org][High Availability, Disaster Recovery and Business Continuity]] @@html:<span class="post-date">11-03-2026 17:18</span>@@ @@html:<a href="/tags/learning.html"><span class="post-tag">learning</span></a>@@ @@html:<a href="/tags/notes.html"><span class="post-tag">notes</span></a>@@
|
- [[file:career/ha-dr.org][High Availability, Disaster Recovery and Business Continuity]] @@html:<span class="post-date">11-03-2026 17:18</span>@@ @@html:<a href="/tags/learning.html"><span class="post-tag">learning</span></a>@@ @@html:<a href="/tags/notes.html"><span class="post-tag">notes</span></a>@@
|
||||||
- [[file:career/javascript.org][Understands the Javascript language]] @@html:<span class="post-date">11-03-2026 16:52</span>@@ @@html:<a href="/tags/learning.html"><span class="post-tag">learning</span></a>@@ @@html:<a href="/tags/notes.html"><span class="post-tag">notes</span></a>@@
|
- [[file:career/javascript.org][Understands the Javascript language]] @@html:<span class="post-date">11-03-2026 16:52</span>@@ @@html:<a href="/tags/learning.html"><span class="post-tag">learning</span></a>@@ @@html:<a href="/tags/notes.html"><span class="post-tag">notes</span></a>@@
|
||||||
|
|||||||
30
sitemap.org
@@ -104,17 +104,17 @@ flowchart TD
|
|||||||
n43 --> n49
|
n43 --> n49
|
||||||
n50["Tag: website"]
|
n50["Tag: website"]
|
||||||
n43 --> n50
|
n43 --> n50
|
||||||
n51["Tag: update"]
|
n51["Tag: life"]
|
||||||
n43 --> n51
|
n43 --> n51
|
||||||
n52["Tag: life"]
|
n52["Tag: update"]
|
||||||
n43 --> n52
|
n43 --> n52
|
||||||
n53["Tag: education"]
|
n53["Tag: insights"]
|
||||||
n43 --> n53
|
n43 --> n53
|
||||||
n54["Tag: insights"]
|
n54["Tag: education"]
|
||||||
n43 --> n54
|
n43 --> n54
|
||||||
n55["Tag: emacs"]
|
n55["Tag: reading"]
|
||||||
n43 --> n55
|
n43 --> n55
|
||||||
n56["Tag: reading"]
|
n56["Tag: emacs"]
|
||||||
n43 --> n56
|
n43 --> n56
|
||||||
n57["Tag: maths"]
|
n57["Tag: maths"]
|
||||||
n43 --> n57
|
n43 --> n57
|
||||||
@@ -224,12 +224,12 @@ flowchart TD
|
|||||||
click n48 "tags/notes.html" "Tag: notes"
|
click n48 "tags/notes.html" "Tag: notes"
|
||||||
click n49 "tags/review.html" "Tag: review"
|
click n49 "tags/review.html" "Tag: review"
|
||||||
click n50 "tags/website.html" "Tag: website"
|
click n50 "tags/website.html" "Tag: website"
|
||||||
click n51 "tags/update.html" "Tag: update"
|
click n51 "tags/life.html" "Tag: life"
|
||||||
click n52 "tags/life.html" "Tag: life"
|
click n52 "tags/update.html" "Tag: update"
|
||||||
click n53 "tags/education.html" "Tag: education"
|
click n53 "tags/insights.html" "Tag: insights"
|
||||||
click n54 "tags/insights.html" "Tag: insights"
|
click n54 "tags/education.html" "Tag: education"
|
||||||
click n55 "tags/emacs.html" "Tag: emacs"
|
click n55 "tags/reading.html" "Tag: reading"
|
||||||
click n56 "tags/reading.html" "Tag: reading"
|
click n56 "tags/emacs.html" "Tag: emacs"
|
||||||
click n57 "tags/maths.html" "Tag: maths"
|
click n57 "tags/maths.html" "Tag: maths"
|
||||||
click n59 "posts/posts-intro.html" "Posts Introduction"
|
click n59 "posts/posts-intro.html" "Posts Introduction"
|
||||||
click n60 "posts/posts-list.html" "Posts List"
|
click n60 "posts/posts-list.html" "Posts List"
|
||||||
@@ -318,12 +318,12 @@ flowchart TD
|
|||||||
- [[file:tags/notes.org][Tag: notes]]
|
- [[file:tags/notes.org][Tag: notes]]
|
||||||
- [[file:tags/review.org][Tag: review]]
|
- [[file:tags/review.org][Tag: review]]
|
||||||
- [[file:tags/website.org][Tag: website]]
|
- [[file:tags/website.org][Tag: website]]
|
||||||
- [[file:tags/update.org][Tag: update]]
|
|
||||||
- [[file:tags/life.org][Tag: life]]
|
- [[file:tags/life.org][Tag: life]]
|
||||||
- [[file:tags/education.org][Tag: education]]
|
- [[file:tags/update.org][Tag: update]]
|
||||||
- [[file:tags/insights.org][Tag: insights]]
|
- [[file:tags/insights.org][Tag: insights]]
|
||||||
- [[file:tags/emacs.org][Tag: emacs]]
|
- [[file:tags/education.org][Tag: education]]
|
||||||
- [[file:tags/reading.org][Tag: reading]]
|
- [[file:tags/reading.org][Tag: reading]]
|
||||||
|
- [[file:tags/emacs.org][Tag: emacs]]
|
||||||
- [[file:tags/maths.org][Tag: maths]]
|
- [[file:tags/maths.org][Tag: maths]]
|
||||||
- posts
|
- posts
|
||||||
- [[file:posts/posts-intro.org][Posts Introduction]]
|
- [[file:posts/posts-intro.org][Posts Introduction]]
|
||||||
|
|||||||
@@ -92,3 +92,17 @@ test("combat phases, hitboxes and enemy states are deterministic", () => {
|
|||||||
stunned: false, telegraphDone: true, attackDone: true, cooldownDone: true
|
stunned: false, telegraphDone: true, attackDone: true, cooldownDone: true
|
||||||
}), "telegraph");
|
}), "telegraph");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("Malrec is demanding but leaves readable counterplay", () => {
|
||||||
|
const malrec = data.ENEMIES.malrec;
|
||||||
|
assert.equal(malrec.phases, 3);
|
||||||
|
assert.ok(malrec.health <= 52);
|
||||||
|
assert.ok(malrec.damage <= 13);
|
||||||
|
assert.ok(malrec.telegraph >= 750);
|
||||||
|
assert.ok(malrec.cooldown >= 1500);
|
||||||
|
const scenes = source("assets/scripts/pages/princess-lima-v2-scenes.js");
|
||||||
|
assert.match(scenes, /phase \+ 1/);
|
||||||
|
assert.match(scenes, /state\.health \+ 25/);
|
||||||
|
assert.match(scenes, /defences_disabled/);
|
||||||
|
assert.match(scenes, /prisoners_freed/);
|
||||||
|
});
|
||||||
|
|||||||