fairy stuff
fairy quest and attack mode
This commit is contained in:
@@ -30,6 +30,7 @@ Requires Python 3.10+ and `pygame`. Game data (rooms, items, sets, enemies, drop
|
||||
| Shatterstep | R |
|
||||
| Tether | X |
|
||||
| Reality Break | C |
|
||||
| Fairy Mode (once unlocked) | Z |
|
||||
| Toggle Light/Shade | Left Shift |
|
||||
| Interact / Talk / Save | F |
|
||||
| Use Butterfly Jar | G |
|
||||
|
||||
@@ -51,6 +51,7 @@ Proves the core loop is fun before scaling to the full vision.
|
||||
| Region-2 boss + ability pacing | M | Re-align pacing (Ranged already exists). |
|
||||
|
||||
### Stretch / core (post-slice, in order)
|
||||
- Map system (current-room minimap -> world graph -> lantern fast travel) — see below
|
||||
- Fast travel (rune stones)
|
||||
- Fairy scout + bond teleport + fairy holes
|
||||
- Regions 3-5 per pacing notes
|
||||
@@ -59,6 +60,27 @@ Proves the core loop is fun before scaling to the full vision.
|
||||
### Cut
|
||||
- Ascended armor (removed).
|
||||
|
||||
## Map system (deferred — brainstorm, not started)
|
||||
|
||||
Feels huge; split into two independent features rather than one.
|
||||
|
||||
1. **Current-room minimap** — cheap and self-contained: scale `room_bounds` + platform rects + a player arrow into a corner/overlay panel. No new data, no persistence. Good first slice.
|
||||
2. **World map / region graph** — nodes = rooms, edges = `exits[]` (derivable automatically from room JSON rather than hand-authored).
|
||||
|
||||
Design notes
|
||||
- **Layout**: add `meta.map_x` / `meta.map_y` (+ optional `meta.region`) per room and place nodes in the editor; fall back to auto-layout from exit topology if absent.
|
||||
- **Discovery**: persist `visited_rooms` and `discovered_links` alongside the existing lantern-only save data. Undiscovered = "?" / fog.
|
||||
- **Theme hook**: map clear in Light, fogged/faded in Shade, or fog dispelled by lanterns — reinforces the light/shade identity (keep it cosmetic).
|
||||
- **Fairy as cartographer**: she fills in rooms and comments on new ones; reuses her room-aware voice lines and mirrors the Boss Diary UI pattern.
|
||||
- **Fast travel**: discovered lanterns become warp nodes; overlaps with the deferred "rune stones" / "fairy bond teleport" items.
|
||||
- **Edge cases**: one-way exits, boss-refight rooms, the missing `room_town_gloomreach.json`, exits with empty `to` (ignore), multiple entry spawns = one node.
|
||||
|
||||
Phasing
|
||||
1. Current-room minimap overlay.
|
||||
2. `visited_rooms` + world map from auto-derived exit links (auto-positioned).
|
||||
3. Manual `map_x/map_y` layout in the editor.
|
||||
4. Lantern fast travel + fairy-bond teleport.
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Save is the keystone: death penalty, main menu, and any progress feature hang off it.
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
{
|
||||
"talk_range": 80,
|
||||
"bubble_duration": 3.5,
|
||||
"idle_interval": 45.0,
|
||||
"idle_lines": ["idle_1", "idle_2", "idle_3"],
|
||||
"dust_lines": ["dust_1", "dust_2", "dust_3"],
|
||||
"attack_lines": ["attack_1", "attack_2", "attack_3"],
|
||||
"auto": {
|
||||
"room_01.json": { "on_enter": "welcome" }
|
||||
},
|
||||
"lines": {
|
||||
"welcome": {
|
||||
"light": "Wake up, sleepyhead! We have a long way to go.",
|
||||
"shade": "Ooh, you found your dark side already?"
|
||||
},
|
||||
"idle_1": {
|
||||
"light": "The butterflies always know the way.",
|
||||
"shade": "Even in the dark, I can still see you."
|
||||
},
|
||||
"idle_2": {
|
||||
"light": "Rest at a lantern and it will remember this place.",
|
||||
"shade": "Careful - the gloom hides sharp things."
|
||||
},
|
||||
"idle_3": {
|
||||
"light": "I will stay close. I always do.",
|
||||
"shade": "You are not alone down here. I am right here."
|
||||
},
|
||||
"spot_greeting": {
|
||||
"light": "Isn't this place pretty?",
|
||||
"shade": "I can barely make you out in here."
|
||||
},
|
||||
"dust_1": {
|
||||
"light": "Fairy dust! I can feel its sparkle.",
|
||||
"shade": "Ooh, shiny. Even the dark likes this."
|
||||
},
|
||||
"dust_2": {
|
||||
"light": "Another pinch of dust - keep going!",
|
||||
"shade": "The dark tastes sweeter with this."
|
||||
},
|
||||
"dust_3": {
|
||||
"light": "This dust hums when I hold it.",
|
||||
"shade": "Keep collecting; I want all of it."
|
||||
},
|
||||
"quest_intro": {
|
||||
"light": "I scattered my fairy dust across these rooms. Bring me 5 and I will fight beside you!",
|
||||
"shade": "Find my 5 fairy dust. I will lend you my sting."
|
||||
},
|
||||
"quest_reward": {
|
||||
"light": "You found them all! Now I can fight - press the Fairy Mode key!",
|
||||
"shade": "All 5! My sting is yours. Press the Fairy Mode key."
|
||||
},
|
||||
"quest_return": {
|
||||
"light": "That's all 5! Return to me at the fairy spot - I have something to show you!",
|
||||
"shade": "All 5 gathered. Come back to my spot - I am ready to change."
|
||||
},
|
||||
"quest_unlock": {
|
||||
"light": "Watch this - hold still!",
|
||||
"shade": "Observe. I am about to change."
|
||||
},
|
||||
"quest_done": {
|
||||
"light": "I am ready whenever you are!",
|
||||
"shade": "Say the word and I strike."
|
||||
},
|
||||
"combat_on": {
|
||||
"light": "To battle! I will pick off the stragglers.",
|
||||
"shade": "Time to hunt. I like this form of yours."
|
||||
},
|
||||
"combat_off": {
|
||||
"light": "Resting my wings now.",
|
||||
"shade": "Fine, back to lurking."
|
||||
},
|
||||
"combat_empty": {
|
||||
"light": "I am out of charge - I need to rest!",
|
||||
"shade": "Empty. Let me recharge."
|
||||
},
|
||||
"attack_1": {
|
||||
"light": "Huah!",
|
||||
"shade": "Huah!"
|
||||
},
|
||||
"attack_2": {
|
||||
"light": "Take this!",
|
||||
"shade": "Take this!"
|
||||
},
|
||||
"attack_3": {
|
||||
"light": "Hyah!",
|
||||
"shade": "Hyah!"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,5 +6,16 @@
|
||||
"speed": 650.0,
|
||||
"lifetime": 1.2,
|
||||
"size": [14, 6]
|
||||
},
|
||||
"fairy": {
|
||||
"charge_cost": 5.0,
|
||||
"cooldown": 0.7,
|
||||
"range": 560.0,
|
||||
"voice_every": 3,
|
||||
"damage_mult": 0.5,
|
||||
"speed": 520.0,
|
||||
"lifetime": 1.4,
|
||||
"size": [16, 16],
|
||||
"spread_deg": 6.0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,12 @@
|
||||
},
|
||||
"quest_point": {
|
||||
"type": "quest_giver"
|
||||
},
|
||||
"fairy_spot": {
|
||||
"type": "fairy_spot"
|
||||
},
|
||||
"fairy_dust": {
|
||||
"type": "fairy_dust"
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 175 B |
Binary file not shown.
|
After Width: | Height: | Size: 437 B |
@@ -144,6 +144,23 @@
|
||||
"h": 260,
|
||||
"group": "ground",
|
||||
"layer": 0
|
||||
},
|
||||
{
|
||||
"x": 20,
|
||||
"y": 760,
|
||||
"w": 140,
|
||||
"h": 20,
|
||||
"group": "moving",
|
||||
"path": [
|
||||
[
|
||||
20,
|
||||
760
|
||||
],
|
||||
[
|
||||
20,
|
||||
400
|
||||
]
|
||||
]
|
||||
}
|
||||
],
|
||||
"enemies": [
|
||||
@@ -171,7 +188,20 @@
|
||||
"radius": 180,
|
||||
"object_id": "flow_butterfly_jar",
|
||||
"layer": 0,
|
||||
"quest_id": ""
|
||||
"quest_id": "",
|
||||
"dialogue_id": "",
|
||||
"auto": false
|
||||
},
|
||||
{
|
||||
"x": 600,
|
||||
"y": 140,
|
||||
"type": "fairy_dust",
|
||||
"radius": 40,
|
||||
"object_id": "fairy_dust",
|
||||
"layer": 0,
|
||||
"quest_id": "",
|
||||
"dialogue_id": "",
|
||||
"auto": false
|
||||
}
|
||||
],
|
||||
"exits": [
|
||||
|
||||
@@ -277,6 +277,15 @@
|
||||
"object_id": "flow_butterfly",
|
||||
"layer": 0,
|
||||
"quest_id": ""
|
||||
},
|
||||
{
|
||||
"x": 440,
|
||||
"y": 400,
|
||||
"type": "fairy_dust",
|
||||
"radius": 40,
|
||||
"object_id": "fairy_dust",
|
||||
"layer": 0,
|
||||
"quest_id": ""
|
||||
}
|
||||
],
|
||||
"exits": [
|
||||
|
||||
@@ -136,6 +136,15 @@
|
||||
"object_id": "lamp",
|
||||
"layer": 0,
|
||||
"quest_id": ""
|
||||
},
|
||||
{
|
||||
"x": 740,
|
||||
"y": 180,
|
||||
"type": "fairy_dust",
|
||||
"radius": 40,
|
||||
"object_id": "fairy_dust",
|
||||
"layer": 0,
|
||||
"quest_id": ""
|
||||
}
|
||||
],
|
||||
"exits": [
|
||||
|
||||
@@ -79,6 +79,15 @@
|
||||
"object_id": "lamp",
|
||||
"layer": 0,
|
||||
"quest_id": ""
|
||||
},
|
||||
{
|
||||
"x": 1100,
|
||||
"y": 520,
|
||||
"type": "fairy_dust",
|
||||
"radius": 40,
|
||||
"object_id": "fairy_dust",
|
||||
"layer": 0,
|
||||
"quest_id": ""
|
||||
}
|
||||
],
|
||||
"exits": [
|
||||
|
||||
@@ -14,6 +14,14 @@
|
||||
"room9_top_left": [
|
||||
220,
|
||||
300
|
||||
],
|
||||
"room9_top_right": [
|
||||
2660,
|
||||
240
|
||||
],
|
||||
"room9_bottom_right": [
|
||||
2660,
|
||||
600
|
||||
]
|
||||
},
|
||||
"platforms": [
|
||||
@@ -38,42 +46,48 @@
|
||||
"y": 440,
|
||||
"w": 140,
|
||||
"h": 20,
|
||||
"group": "ground"
|
||||
"group": "ground",
|
||||
"layer": 0
|
||||
},
|
||||
{
|
||||
"x": 620,
|
||||
"y": 500,
|
||||
"w": 120,
|
||||
"h": 20,
|
||||
"group": "ground"
|
||||
"group": "ground",
|
||||
"layer": 0
|
||||
},
|
||||
{
|
||||
"x": 800,
|
||||
"y": 560,
|
||||
"w": 80,
|
||||
"h": 20,
|
||||
"group": "ground"
|
||||
"group": "ground",
|
||||
"layer": 0
|
||||
},
|
||||
{
|
||||
"x": 80,
|
||||
"y": 660,
|
||||
"w": 2699,
|
||||
"h": 20,
|
||||
"group": "ground"
|
||||
"group": "ground",
|
||||
"layer": 0
|
||||
},
|
||||
{
|
||||
"x": 1580,
|
||||
"y": 540,
|
||||
"w": 240,
|
||||
"h": 20,
|
||||
"group": "ground"
|
||||
"group": "ground",
|
||||
"layer": 0
|
||||
},
|
||||
{
|
||||
"x": 1980,
|
||||
"y": 540,
|
||||
"w": 100,
|
||||
"h": 20,
|
||||
"group": "ground"
|
||||
"group": "ground",
|
||||
"layer": 0
|
||||
},
|
||||
{
|
||||
"x": 2260,
|
||||
@@ -81,6 +95,7 @@
|
||||
"w": 140,
|
||||
"h": 20,
|
||||
"group": "moving",
|
||||
"layer": 0,
|
||||
"path": [
|
||||
[
|
||||
2260,
|
||||
@@ -97,7 +112,24 @@
|
||||
"y": 300,
|
||||
"w": 320,
|
||||
"h": 20,
|
||||
"group": "ground"
|
||||
"group": "ground",
|
||||
"layer": 0
|
||||
},
|
||||
{
|
||||
"x": 2780,
|
||||
"y": 120,
|
||||
"w": 20,
|
||||
"h": 200,
|
||||
"group": "ground",
|
||||
"layer": 0
|
||||
},
|
||||
{
|
||||
"x": 2780,
|
||||
"y": 480,
|
||||
"w": 20,
|
||||
"h": 200,
|
||||
"group": "ground",
|
||||
"layer": 0
|
||||
}
|
||||
],
|
||||
"enemies": [],
|
||||
@@ -111,30 +143,32 @@
|
||||
{
|
||||
"x": 2012,
|
||||
"y": 486,
|
||||
"type": "combat_master"
|
||||
"type": "combat_master",
|
||||
"layer": 0
|
||||
}
|
||||
],
|
||||
"props": [
|
||||
{
|
||||
"x": 800,
|
||||
"y": 460,
|
||||
"type": "player",
|
||||
"radius": 180,
|
||||
"object_id": "player"
|
||||
},
|
||||
{
|
||||
"x": 1240,
|
||||
"y": 660,
|
||||
"type": "house",
|
||||
"radius": 180,
|
||||
"object_id": "house"
|
||||
"object_id": "house",
|
||||
"layer": 0,
|
||||
"quest_id": "",
|
||||
"dialogue_id": "",
|
||||
"auto": false
|
||||
},
|
||||
{
|
||||
"x": 1660,
|
||||
"y": 540,
|
||||
"type": "house",
|
||||
"radius": 180,
|
||||
"object_id": "house"
|
||||
"object_id": "house",
|
||||
"layer": 0,
|
||||
"quest_id": "",
|
||||
"dialogue_id": "",
|
||||
"auto": false
|
||||
},
|
||||
{
|
||||
"x": 1754,
|
||||
@@ -142,7 +176,26 @@
|
||||
"type": "diary",
|
||||
"radius": 180,
|
||||
"object_id": "diary",
|
||||
"layer": 1
|
||||
"layer": 1,
|
||||
"quest_id": "",
|
||||
"dialogue_id": "",
|
||||
"auto": false
|
||||
},
|
||||
{
|
||||
"x": 1460,
|
||||
"y": 660,
|
||||
"type": "save_point",
|
||||
"radius": 90,
|
||||
"object_id": "lamp"
|
||||
},
|
||||
{
|
||||
"x": 840,
|
||||
"y": 560,
|
||||
"type": "fairy_dust",
|
||||
"radius": 40,
|
||||
"object_id": "fairy_dust",
|
||||
"layer": 0,
|
||||
"quest_id": ""
|
||||
}
|
||||
],
|
||||
"exits": [
|
||||
@@ -160,6 +213,36 @@
|
||||
"hint": "",
|
||||
"layer": 0,
|
||||
"requires_boss_dead": false
|
||||
},
|
||||
{
|
||||
"x": 2700,
|
||||
"y": 560,
|
||||
"w": 80,
|
||||
"h": 100,
|
||||
"to": "",
|
||||
"spawn_id": "",
|
||||
"spawn": [
|
||||
2700,
|
||||
560
|
||||
],
|
||||
"hint": "",
|
||||
"layer": 0,
|
||||
"requires_boss_dead": false
|
||||
},
|
||||
{
|
||||
"x": 2700,
|
||||
"y": 200,
|
||||
"w": 80,
|
||||
"h": 100,
|
||||
"to": "room_10",
|
||||
"spawn_id": "room10_top_left",
|
||||
"spawn": [
|
||||
140,
|
||||
280
|
||||
],
|
||||
"hint": "",
|
||||
"layer": 0,
|
||||
"requires_boss_dead": false
|
||||
}
|
||||
],
|
||||
"ability_doors": [],
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"name": "room_10",
|
||||
"display_name": "room_10",
|
||||
"meta": {
|
||||
"id": "room_10",
|
||||
"name": "room_10"
|
||||
},
|
||||
"bounds": {},
|
||||
"player_spawn": [
|
||||
160,
|
||||
260
|
||||
],
|
||||
"entry_spawns": {
|
||||
"room10_top_left": [
|
||||
140,
|
||||
280
|
||||
]
|
||||
},
|
||||
"platforms": [
|
||||
{
|
||||
"x": 20,
|
||||
"y": 340,
|
||||
"w": 440,
|
||||
"h": 20,
|
||||
"group": "ground",
|
||||
"layer": 0
|
||||
},
|
||||
{
|
||||
"x": 20,
|
||||
"y": 120,
|
||||
"w": 20,
|
||||
"h": 220,
|
||||
"group": "ground",
|
||||
"layer": 0
|
||||
}
|
||||
],
|
||||
"enemies": [],
|
||||
"npcs": [],
|
||||
"props": [
|
||||
{
|
||||
"x": 340,
|
||||
"y": 300,
|
||||
"type": "fairy_spot",
|
||||
"radius": 180,
|
||||
"object_id": "fairy_spot",
|
||||
"dialogue_id": "spot_greeting",
|
||||
"quest_id": "quest_fairy_dust"
|
||||
}
|
||||
],
|
||||
"exits": [
|
||||
{
|
||||
"x": 40,
|
||||
"y": 240,
|
||||
"w": 80,
|
||||
"h": 100,
|
||||
"to": "room_09",
|
||||
"spawn_id": "room9_top_right",
|
||||
"spawn": [
|
||||
2660,
|
||||
240
|
||||
],
|
||||
"hint": "",
|
||||
"layer": 0,
|
||||
"requires_boss_dead": false
|
||||
}
|
||||
],
|
||||
"ability_doors": [],
|
||||
"room_w": 1600,
|
||||
"room_h": 900,
|
||||
"mist": false
|
||||
}
|
||||
@@ -47,17 +47,18 @@
|
||||
"props": [],
|
||||
"exits": [
|
||||
{
|
||||
"x": 1460,
|
||||
"y": 360,
|
||||
"w": 80,
|
||||
"h": 100,
|
||||
"to": "",
|
||||
"spawn_id": "",
|
||||
"spawn": [
|
||||
1460,
|
||||
360
|
||||
]
|
||||
}
|
||||
"x": 1460,
|
||||
"y": 360,
|
||||
"w": 80,
|
||||
"h": 100,
|
||||
"to": "room_09.json",
|
||||
"spawn_id": "",
|
||||
"spawn": [
|
||||
1754,
|
||||
540
|
||||
],
|
||||
"requires_boss_dead": true
|
||||
}
|
||||
],
|
||||
"ability_doors": [],
|
||||
"room_w": 1600,
|
||||
|
||||
@@ -271,6 +271,8 @@
|
||||
diary: { type: "diary" },
|
||||
player: { type: "player" },
|
||||
quest_point: { type: "quest_giver" },
|
||||
fairy_spot: { type: "fairy_spot" },
|
||||
fairy_dust: { type: "fairy_dust" },
|
||||
};
|
||||
// Type fallbacks used when no object def provides a radius.
|
||||
const TYPE_DEFAULT_RADII = { light_source: 180, save_point: 90 };
|
||||
@@ -496,7 +498,7 @@
|
||||
const type = p.type || p.kind || "light_source";
|
||||
const object_id = p.object_id || p.objectId || null;
|
||||
const radius = +p.radius || getDefaultRadiusForType(type, object_id);
|
||||
r.props.push({ x, y, type, radius, object_id, layer: +(p.layer||0), quest_id: p.quest_id || p.questId || "", coins: Array.isArray(p.coins) ? deepClone(p.coins) : undefined });
|
||||
r.props.push({ x, y, type, radius, object_id, layer: +(p.layer||0), quest_id: p.quest_id || p.questId || "", dialogue_id: p.dialogue_id || p.dialogueId || "", auto: !!p.auto, coins: Array.isArray(p.coins) ? deepClone(p.coins) : undefined });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2377,8 +2379,9 @@ Cancel = Choose whether to remove without saving`);
|
||||
if(!p) return "<div class='muted'>Selection missing.</div>";
|
||||
const prDefault = getDefaultRadiusForType(p.type || "light_source", p.object_id || p.objectId || null);
|
||||
const objId = p.object_id || p.objectId || "";
|
||||
const hint = ({light_source:"Butterfly (charge regen 2x)", save_point:"Lantern (save point - press F to save)", butterfly_jar:"Butterfly-in-jar (collectible)", diary:"Boss diary (interact)", house:"Standalone house", player:"Player size reference (no in-game effect)", quest_giver:"Quest point (name it below)"})[p.type||"light_source"] || "";
|
||||
const hint = ({light_source:"Butterfly (charge regen 2x)", save_point:"Lantern (save point - press F to save)", butterfly_jar:"Butterfly-in-jar (collectible)", diary:"Boss diary (interact)", house:"Standalone house", player:"Player size reference (no in-game effect)", quest_giver:"Quest point (name it below)", fairy_spot:"Fairy spot (press F to hear the fairy; set quest id for a quest)", fairy_dust:"Fairy dust (collect with F)"})[p.type||"light_source"] || "";
|
||||
const isQuest = (p.type||"") === "quest_giver";
|
||||
const isFairySpot = (p.type||"") === "fairy_spot";
|
||||
return `
|
||||
<div><b>Prop</b> #${sel.index}${hint ? ` <span class="mini">· ${hint}</span>` : ""}</div>
|
||||
<div class="hr"></div>
|
||||
@@ -2390,10 +2393,19 @@ Cancel = Choose whether to remove without saving`);
|
||||
<div class="mini">type</div>
|
||||
<input id="prtype" type="text" value="${p.type||"light_source"}"/>
|
||||
</div>
|
||||
${isQuest ? `
|
||||
${(isQuest || isFairySpot) ? `
|
||||
<div style="margin-top:8px;">
|
||||
<div class="mini">quest id (name)</div>
|
||||
<input id="prqid" type="text" value="${p.quest_id||""}" placeholder="e.g. quest_save_the_well"/>
|
||||
<input id="prqid" type="text" value="${p.quest_id||""}" placeholder="e.g. quest_fairy_dust"/>
|
||||
</div>` : ""}
|
||||
${isFairySpot ? `
|
||||
<div style="margin-top:8px;">
|
||||
<div class="mini">dialogue id (from data/config/fairy.json)</div>
|
||||
<input id="prdialogue" type="text" value="${p.dialogue_id||""}" placeholder="e.g. spot_greeting"/>
|
||||
</div>
|
||||
<div style="margin-top:8px;">
|
||||
<div class="mini">auto trigger</div>
|
||||
<input id="prauto" type="checkbox" ${p.auto ? "checked" : ""}/>
|
||||
</div>` : ""}
|
||||
<div style="margin-top:8px;">
|
||||
<div class="mini">object id</div>
|
||||
@@ -2648,6 +2660,14 @@ Cancel = Choose whether to remove without saving`);
|
||||
const v = prqid.value.trim();
|
||||
if(v){ p.quest_id = v; } else { delete p.quest_id; }
|
||||
}));
|
||||
const prdialogue=q("prdialogue"), prauto=q("prauto");
|
||||
if(prdialogue) prdialogue.addEventListener("change", ()=>pushAnd(()=>{
|
||||
const v = prdialogue.value.trim();
|
||||
if(v){ p.dialogue_id = v; } else { delete p.dialogue_id; }
|
||||
}));
|
||||
if(prauto) prauto.addEventListener("change", ()=>pushAnd(()=>{
|
||||
if(prauto.checked){ p.auto = true; } else { delete p.auto; }
|
||||
}));
|
||||
if(probjid) probjid.addEventListener("change", ()=>pushAnd(()=>{
|
||||
const v = probjid.value.trim();
|
||||
if(v){ p.object_id = v; } else { delete p.object_id; }
|
||||
@@ -3492,6 +3512,8 @@ Cancel = Choose whether to remove without saving`);
|
||||
if(p.object_id) out.object_id = p.object_id;
|
||||
if(p.layer) out.layer = p.layer;
|
||||
if(p.quest_id) out.quest_id = p.quest_id;
|
||||
if(p.dialogue_id) out.dialogue_id = p.dialogue_id;
|
||||
if(p.auto) out.auto = true;
|
||||
if(Array.isArray(p.coins)) out.coins = p.coins;
|
||||
return out;
|
||||
});
|
||||
|
||||
+1038
-232
File diff suppressed because it is too large
Load Diff
@@ -1,260 +0,0 @@
|
||||
{
|
||||
"version": 1,
|
||||
"saved_at": "2026-10-05T09:57:55",
|
||||
"player": {
|
||||
"room_id": "room_07.json",
|
||||
"x": 680,
|
||||
"y": 520,
|
||||
"health": 10,
|
||||
"charge": 120.0,
|
||||
"shade": false,
|
||||
"coins_light": 40,
|
||||
"coins_dark": 20,
|
||||
"butterfly_jars": 0,
|
||||
"has_ranged": true,
|
||||
"opened_chests": [
|
||||
"room_03.json@90,194",
|
||||
"room_07.json@440,494"
|
||||
],
|
||||
"equipment": {
|
||||
"helmet": {
|
||||
"id": "duskwarrior_helm",
|
||||
"name": "Duskwarrior Helmet",
|
||||
"set": "duskwarrior",
|
||||
"slot": "helmet",
|
||||
"base_stats": {},
|
||||
"rarity_overrides": {
|
||||
"tempered": {
|
||||
"extra_stats": {
|
||||
"charge": 10
|
||||
}
|
||||
},
|
||||
"attuned": {
|
||||
"extra_stats": {
|
||||
"charge": 10,
|
||||
"health": 5
|
||||
}
|
||||
},
|
||||
"awakened": {
|
||||
"extra_stats": {
|
||||
"charge": 15,
|
||||
"health": 5,
|
||||
"charge_regen_pct": 0.1
|
||||
}
|
||||
}
|
||||
},
|
||||
"rarity": "tempered",
|
||||
"tier": 1,
|
||||
"stats": {
|
||||
"charge": 10.0
|
||||
},
|
||||
"abilities": []
|
||||
},
|
||||
"chest": {
|
||||
"id": "vitalweave_chest",
|
||||
"name": "Vitalweave Chestplate",
|
||||
"set": "vitalweave",
|
||||
"slot": "chest",
|
||||
"base_stats": {},
|
||||
"rarity_overrides": {
|
||||
"tempered": {
|
||||
"extra_stats": {
|
||||
"heal_speed_pct": 0.1
|
||||
}
|
||||
},
|
||||
"attuned": {
|
||||
"extra_stats": {
|
||||
"heal_speed_pct": 0.15
|
||||
}
|
||||
},
|
||||
"awakened": {
|
||||
"extra_stats": {
|
||||
"heal_speed_pct": 0.15,
|
||||
"health": 5
|
||||
}
|
||||
}
|
||||
},
|
||||
"rarity": "attuned",
|
||||
"tier": 2,
|
||||
"stats": {
|
||||
"heal_speed_pct": 0.15
|
||||
},
|
||||
"abilities": []
|
||||
},
|
||||
"pants": {
|
||||
"id": "gravemark_greaves",
|
||||
"name": "Gravemark Greaves",
|
||||
"set": "gravemark",
|
||||
"slot": "pants",
|
||||
"base_stats": {},
|
||||
"rarity_overrides": {
|
||||
"tempered": {
|
||||
"extra_stats": {
|
||||
"charge": 10
|
||||
}
|
||||
},
|
||||
"attuned": {
|
||||
"extra_stats": {
|
||||
"charge": 10,
|
||||
"health": 5
|
||||
}
|
||||
},
|
||||
"awakened": {
|
||||
"extra_stats": {
|
||||
"charge": 20,
|
||||
"health": 5
|
||||
}
|
||||
}
|
||||
},
|
||||
"rarity": "tempered",
|
||||
"tier": 1,
|
||||
"stats": {
|
||||
"charge": 10.0
|
||||
},
|
||||
"abilities": []
|
||||
},
|
||||
"necklace": null
|
||||
}
|
||||
},
|
||||
"inventory": [
|
||||
{
|
||||
"id": "dawnrunner_helm",
|
||||
"name": "Dawnrunner Helmet",
|
||||
"set": "dawnrunner",
|
||||
"slot": "helmet",
|
||||
"base_stats": {},
|
||||
"rarity_overrides": {
|
||||
"tempered": {
|
||||
"extra_stats": {
|
||||
"move_speed_light_pct": 0.1
|
||||
}
|
||||
},
|
||||
"attuned": {
|
||||
"extra_stats": {
|
||||
"move_speed_light_pct": 0.1,
|
||||
"heal_speed_pct": 0.1
|
||||
}
|
||||
},
|
||||
"awakened": {
|
||||
"extra_stats": {
|
||||
"move_speed_light_pct": 0.15,
|
||||
"heal_speed_pct": 0.2
|
||||
}
|
||||
}
|
||||
},
|
||||
"rarity": "attuned",
|
||||
"tier": 2,
|
||||
"stats": {
|
||||
"move_speed_light_pct": 0.1,
|
||||
"heal_speed_pct": 0.1
|
||||
},
|
||||
"abilities": []
|
||||
},
|
||||
{
|
||||
"id": "paladin_helm",
|
||||
"name": "Paladin Helmet",
|
||||
"set": "paladin",
|
||||
"slot": "helmet",
|
||||
"base_stats": {},
|
||||
"rarity_overrides": {
|
||||
"tempered": {
|
||||
"extra_stats": {
|
||||
"health": 5
|
||||
}
|
||||
},
|
||||
"attuned": {
|
||||
"extra_stats": {
|
||||
"health": 10,
|
||||
"negate_damage_chance": 0.05
|
||||
}
|
||||
},
|
||||
"awakened": {
|
||||
"extra_stats": {
|
||||
"health": 15,
|
||||
"negate_damage_chance": 0.1,
|
||||
"knockback_resistance": 0.25
|
||||
}
|
||||
}
|
||||
},
|
||||
"rarity": "tempered",
|
||||
"tier": 1,
|
||||
"stats": {
|
||||
"health": 5.0
|
||||
},
|
||||
"abilities": []
|
||||
},
|
||||
{
|
||||
"id": "dawnrunner_chest",
|
||||
"name": "Dawnrunner Chestplate",
|
||||
"set": "dawnrunner",
|
||||
"slot": "chest",
|
||||
"base_stats": {},
|
||||
"rarity_overrides": {
|
||||
"tempered": {
|
||||
"extra_stats": {
|
||||
"charge": 10
|
||||
}
|
||||
},
|
||||
"attuned": {
|
||||
"extra_stats": {
|
||||
"charge": 15,
|
||||
"move_speed_light_pct": 0.05
|
||||
}
|
||||
},
|
||||
"awakened": {
|
||||
"extra_stats": {
|
||||
"charge": 15,
|
||||
"move_speed_light_pct": 0.05,
|
||||
"heal_plus": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"rarity": "attuned",
|
||||
"tier": 2,
|
||||
"stats": {
|
||||
"charge": 15.0,
|
||||
"move_speed_light_pct": 0.05
|
||||
},
|
||||
"abilities": []
|
||||
},
|
||||
{
|
||||
"id": "necklace_flow",
|
||||
"name": "Charm of Flow",
|
||||
"slot": "necklace",
|
||||
"item_type": "necklace",
|
||||
"base_stats": {
|
||||
"charge": 10
|
||||
},
|
||||
"rarity": "",
|
||||
"tier": 0,
|
||||
"abilities": [],
|
||||
"stats": {
|
||||
"charge": 10
|
||||
}
|
||||
}
|
||||
],
|
||||
"quests": {
|
||||
"active": {
|
||||
"first_kills_shade": {
|
||||
"progress": 1
|
||||
}
|
||||
},
|
||||
"completed_one_time": [],
|
||||
"ever_completed": [
|
||||
"quest_first_kills"
|
||||
],
|
||||
"tokens": 0
|
||||
},
|
||||
"boss_diary": {
|
||||
"slotted": {}
|
||||
},
|
||||
"defeated_bosses": [
|
||||
"room_05.json"
|
||||
],
|
||||
"broken_doors": [],
|
||||
"lantern_respawn": {
|
||||
"room_id": "room_07.json",
|
||||
"x": 640,
|
||||
"y": 520
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user