diff --git a/src/commands/messages/game/deathlog.ts b/src/commands/messages/game/deathlog.ts
new file mode 100644
index 0000000..5d45747
--- /dev/null
+++ b/src/commands/messages/game/deathlog.ts
@@ -0,0 +1,49 @@
+import type { CommandMessage } from "../../../core/types/commands";
+import type Amayo from "../../../core/client";
+import { prisma } from "../../../core/database/prisma";
+
+export const command: CommandMessage = {
+ name: "deathlog",
+ aliases: ["muertes"],
+ type: "message",
+ cooldown: 8,
+ category: "Economía",
+ description: "Muestra tus últimas muertes y penalizaciones aplicadas.",
+ usage: "deathlog [cantidad<=20]",
+ run: async (message, args, _client: Amayo) => {
+ const userId = message.author.id;
+ const guildId = message.guild!.id;
+ let take = 10;
+ if (args[0]) {
+ const n = parseInt(args[0], 10);
+ if (!isNaN(n) && n > 0) take = Math.min(20, n);
+ }
+
+ const logs = await prisma.deathLog.findMany({
+ where: { userId, guildId },
+ orderBy: { createdAt: "desc" },
+ take,
+ });
+ if (!logs.length) {
+ await message.reply("No hay registros de muerte.");
+ return;
+ }
+
+ const lines = logs.map((l) => {
+ const pct = Math.round((l.percentApplied || 0) * 100);
+ const parts: string[] = [];
+ parts.push(`💰-${l.goldLost}`);
+ if (pct) parts.push(`${pct}%`);
+ if (l.fatigueMagnitude)
+ parts.push(`Fatiga ${Math.round(l.fatigueMagnitude * 100)}%`);
+ const area = l.areaKey ? l.areaKey : "?";
+ return `${l.createdAt.toISOString().slice(11, 19)} | ${area} L${
+ l.level ?? "-"
+ } | ${parts.join(" | ")}${l.autoDefeatNoWeapon ? " | sin arma" : ""}`;
+ });
+
+ await message.reply(
+ `**DeathLog (últimos ${logs.length})**\n${lines.join("\n")}`
+ );
+ },
+};
diff --git a/src/game/economy/seedPurgePotion.ts b/src/game/economy/seedPurgePotion.ts
new file mode 100644
index 0000000..ef7aa73
--- /dev/null
+++ b/src/game/economy/seedPurgePotion.ts
@@ -0,0 +1,35 @@
+import { prisma } from "../../core/database/prisma";
+
+// Seed para crear el ítem de purga de efectos (potion.purga)
+// Ejecutar manualmente una vez.
+// node -r ts-node/register src/game/economy/seedPurgePotion.ts (según tu setup)
+
+async function main() {
+ const key = "potion.purga";
+ const existing = await prisma.economyItem.findFirst({
+ where: { key, guildId: null },
+ });
+ if (existing) {
+ console.log("Ya existe potion.purga (global)");
+ return;
+ }
+ const item = await prisma.economyItem.create({
+ data: {
+ key,
+ name: "Poción de Purga",
+ description:
+ "Elimina todos tus efectos de estado activos al usar el comando !efectos purgar.",
+ category: "consumable",
+ icon: "🧪",
+ stackable: true,
+ props: { usable: true, purgeAllEffects: true },
+ tags: ["purge", "status", "utility"],
+ },
+ });
+ console.log("Creado:", item.id, item.key);
+}
+
+main().catch((e) => {
+ console.error(e);
+ process.exit(1);
+});
diff --git a/src/game/lib/rpgFormat.ts b/src/game/lib/rpgFormat.ts
index c608c50..98b193b 100644
--- a/src/game/lib/rpgFormat.ts
+++ b/src/game/lib/rpgFormat.ts
@@ -87,6 +87,7 @@ export function combatSummaryRPG(c: {
goldLost?: number;
fatigueAppliedMinutes?: number;
fatigueMagnitude?: number;
+ percentApplied?: number;
};
}) {
const header = `**Combate (${outcomeLabel(c.outcome)})**`;
@@ -112,6 +113,9 @@ export function combatSummaryRPG(c: {
: 15;
parts.push(`Fatiga ${pct}% ${c.deathPenalty.fatigueAppliedMinutes}m`);
}
+ if (typeof c.deathPenalty.percentApplied === "number") {
+ parts.push(`(${Math.round(c.deathPenalty.percentApplied * 100)}% oro)`);
+ }
if (parts.length) lines.push(`• Penalización: ${parts.join(" | ")}`);
}
if (c.playerStartHp != null && c.playerEndHp != null) {
diff --git a/src/game/minigames/service.ts b/src/game/minigames/service.ts
index 6a589d2..17a3387 100644
--- a/src/game/minigames/service.ts
+++ b/src/game/minigames/service.ts
@@ -451,7 +451,19 @@ export async function runMinigame(
});
}
}
- const fatigueMagnitude = 0.15;
+ // Fatiga escalada: base 15%, +1% cada 5 de racha previa (cap +10%)
+ let previousStreak = 0;
+ try {
+ const ps = await prisma.playerStats.findUnique({
+ where: { userId_guildId: { userId, guildId } },
+ });
+ previousStreak = ps?.currentWinStreak || 0;
+ } catch {}
+ const extraFatigue = Math.min(
+ 0.1,
+ Math.floor(previousStreak / 5) * 0.01
+ );
+ const fatigueMagnitude = 0.15 + extraFatigue;
const fatigueMinutes = 5;
await applyDeathFatigue(
userId,
@@ -632,7 +644,19 @@ export async function runMinigame(
});
}
}
- const fatigueMagnitude = 0.15;
+ // Fatiga escalada
+ let previousStreak = 0;
+ try {
+ const ps = await prisma.playerStats.findUnique({
+ where: { userId_guildId: { userId, guildId } },
+ });
+ previousStreak = ps?.currentWinStreak || 0;
+ } catch {}
+ const extraFatigue = Math.min(
+ 0.1,
+ Math.floor(previousStreak / 5) * 0.01
+ );
+ const fatigueMagnitude = 0.15 + extraFatigue;
const fatigueMinutes = 5;
await applyDeathFatigue(
userId,
diff --git a/src/server/views/partials/sections/creacion-contenido.ejs b/src/server/views/partials/sections/creacion-contenido.ejs
index 4ecec3e..d3ae9d1 100644
--- a/src/server/views/partials/sections/creacion-contenido.ejs
+++ b/src/server/views/partials/sections/creacion-contenido.ejs
@@ -1,6 +1,6 @@
Guía técnica paso a paso para crear items, áreas/niveles, mobs y ofertas directamente desde Discord. Requiere permiso Manage Guild o rol de staff. Guía técnica paso a paso para crear items, áreas/niveles, mobs, ofertas y ahora componentes RPG avanzados (durabilidad por instancia, efectos de estado, penalizaciones de muerte, rachas, riskFactor de áreas). Requiere permiso Manage Guild o rol de staff. Usa !item-editar, !item-ver, !items-lista para gestionar. Usa !item-editar, !item-ver, !items-lista. Para herramientas NO apilables la durabilidad se gestiona por instancias dentro de inventory.state.instances. Revisa con !mobs-lista y !mob-eliminar <key> si necesitas limpiar datos de prueba.🎨 Creación de Contenido
-
+
+ { "usable": true, "purgeAllEffects": true } y usarla con !efectos purgar.🧭 Áreas y Niveles (MINE/LAGOON/FIGHT/FARM)
@@ -36,7 +44,8 @@ Prueba: !craftear iron_sword
Config (JSON): {
"cooldownSeconds": 60,
"description": "Caverna rica en hierro",
- "icon": "⛏️"
+ "icon": "⛏️",
+ "riskFactor": 2
}
Guardar → ✅ Área creada
@@ -64,6 +73,7 @@ Guardar → ✅ Nivel guardado
+
+ 🛒 Ofertas de Tienda
@@ -110,6 +128,7 @@ Guardar → ✅ Oferta guardada
+ area.config.riskFactor: 0-3 (aumenta % oro perdido)
+ item.props.breakable.maxDurability / durabilityPerUse
+ item.props.tool { type, tier }
+ item.props.purgeAllEffects = true (ítem purga)
+ status effects: almacenados en DB (PlayerStatusEffect)
+ death penalty: porcentaje dinámico + fatiga escalada
+
# Área con factor de riesgo (aumenta penalización oro al morir)
+!area-crear arena.blood_pit
+Config (JSON): {"cooldownSeconds": 90, "icon": "⚔️", "riskFactor": 3, "description": "La fosa sangrienta"}
+!area-nivel arena.blood_pit 1
+Requisitos (JSON): {"tool": {"required": true, "toolType": "sword", "minTier": 2}}
+Recompensas (JSON): {"draws": 2, "table": [
+ {"type": "coins", "amount": 120, "weight": 10},
+ {"type": "item", "itemKey": "blood_shard", "qty": 1, "weight": 4}
+]}
+Mobs (JSON): {"draws": 2, "table": [
+ {"mobKey": "goblin", "weight": 8},
+ {"mobKey": "cave_spider", "weight": 5}
+]}
+ !item-crear purge_potion
+Props (JSON): {"usable": true, "purgeAllEffects": true, "icon": "🧪"}
+# Se consume al usar: !efectos purgar
+# Para venderla: crear oferta o poner drop en cofre.
+ # (Opcional) Aplicar un efecto custom vía comando admin futuro
+# Ejemplo conceptual JSON (guardado server-side):
+{
+ "type": "BLESSING",
+ "magnitude": 0.10, # +10% daño (interpretación futura)
+ "durationMs": 600000 # 10 min
+}
+# Los efectos actuales: FATIGUE (reduce daño y defensa)
+# Ver activos: !efectos
+ # Ver últimas muertes y penalizaciones +!deathlog # por defecto 10 +!deathlog 20 # máximo 20 + +# Interpreta columnas +# HH:MM:SS | areaKey Lnivel | -oro | % | Fatiga | sin arma? + +# Ajusta balance si ves pérdidas demasiado altas en cierto nivel/riskFactor.+
# 1. Crear arma y área con riesgo
+!item-crear bone_sword
+Props (JSON): {"tool": {"type": "sword", "tier": 1}, "damage": 9, "breakable": {"enabled": true, "maxDurability": 80}}
+!area-crear arena.bone_trial
+Config (JSON): {"cooldownSeconds": 45, "riskFactor": 1, "icon": "🗡️"}
+!area-nivel arena.bone_trial 1
+Requisitos (JSON): {"tool": {"required": true, "toolType": "sword", "minTier": 1}}
+Mobs (JSON): {"draws":1, "table":[{"mobKey":"goblin","weight":10}]}
+
+# 2. Pelear varias veces para subir racha y ver bonus daño (!player)
+# 3. Morir intencionalmente con monedas => verifica !deathlog
+# 4. Aplicar purga de efectos si acumulaste FATIGUE
+!efectos purgar
+
+# Ajusta riskFactor o nivel si la penalización % es muy baja/alta.
+