work on fight system, pass 2
This commit is contained in:
parent
674cfce506
commit
de0381f668
@ -207,6 +207,12 @@ button.btn {
|
||||
background-image: url("/assets/images/overlay.png"), linear-gradient(to bottom, #ffd965, #ffb574);
|
||||
}
|
||||
}
|
||||
|
||||
&.btn-blue {
|
||||
background-color: #00c6ff;
|
||||
background-image: url("/assets/images/overlay.png"), linear-gradient(to bottom, #00c6ff, #0072ff);
|
||||
border-color: #0072ff;
|
||||
}
|
||||
}
|
||||
|
||||
form.standard {
|
||||
@ -402,3 +408,64 @@ img#move-compass-disabled {
|
||||
filter: grayscale();
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
img#monster-image {
|
||||
display: block;
|
||||
max-height: 360px;
|
||||
margin: 1rem auto;
|
||||
}
|
||||
|
||||
div#monster-health {
|
||||
display: flex;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
height: 16px;
|
||||
width: 100%;
|
||||
border: 1px solid rgba(0, 0, 0, 0.6);
|
||||
|
||||
& > div.bar {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #56ab2f;
|
||||
background: linear-gradient(to bottom, #a8e063, #56ab2f);
|
||||
|
||||
&.warning {
|
||||
background: #F2994A;
|
||||
background: linear-gradient(to bottom, #F2C94C, #F2994A);
|
||||
}
|
||||
|
||||
&.danger {
|
||||
background: #cb2d3e;
|
||||
background: linear-gradient(to bottom, #ef473a, #cb2d3e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
select.styled-select {
|
||||
font-family: inherit;
|
||||
font-size: 1rem;
|
||||
appearance: none;
|
||||
outline: none;
|
||||
background-color: #808080;
|
||||
background-image: url("/assets/images/overlay.png");
|
||||
border: 1px solid #808080;
|
||||
padding: 0.25rem 0.5rem;
|
||||
cursor: pointer;
|
||||
color: white;
|
||||
box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.2);
|
||||
text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.1);
|
||||
height: 28px;
|
||||
|
||||
&:hover {
|
||||
background-color: #909090;
|
||||
}
|
||||
}
|
||||
|
||||
div#battle-window {
|
||||
background: url("/assets/images/backgrounds/forest1.jpg");
|
||||
background-size: cover;
|
||||
padding: 0.5rem;
|
||||
|
||||
h2, h3 {
|
||||
color: white;
|
||||
}
|
||||
}
|
BIN
assets/images/backgrounds/forest1.jpg
Normal file
BIN
assets/images/backgrounds/forest1.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 922 KiB |
BIN
assets/images/monsters/Arcane Golem.png
Normal file
BIN
assets/images/monsters/Arcane Golem.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 305 KiB |
BIN
assets/images/monsters/Creature.png
Normal file
BIN
assets/images/monsters/Creature.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 78 KiB |
27
assets/scripts/select_arrows.js
Normal file
27
assets/scripts/select_arrows.js
Normal file
@ -0,0 +1,27 @@
|
||||
function addSelectArrows() {
|
||||
const selects = document.querySelectorAll('select.styled-select')
|
||||
|
||||
selects.forEach(select => {
|
||||
if (select.parentElement.classList.contains('select-wrapper')) return
|
||||
|
||||
select.style.paddingRight = '1.5rem'
|
||||
|
||||
const wrapper = document.createElement('div')
|
||||
wrapper.className = 'select-wrapper'
|
||||
wrapper.style.position = 'relative'
|
||||
wrapper.style.display = 'inline-block'
|
||||
|
||||
select.parentNode.insertBefore(wrapper, select)
|
||||
wrapper.appendChild(select)
|
||||
|
||||
const arrow = document.createElement('div')
|
||||
arrow.innerHTML = `<svg width="16px" height="16px" stroke-width="1.5" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M19 13.5L15.5 17L12 13.5" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M15.5 17V11C15.5 8.79086 13.7091 7 11.5 7H4.5" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg>`
|
||||
arrow.style.position = 'absolute'
|
||||
arrow.style.right = '5px'
|
||||
arrow.style.top = '56%'
|
||||
arrow.style.transform = 'translateY(-50%)'
|
||||
arrow.style.pointerEvents = 'none'
|
||||
|
||||
wrapper.appendChild(arrow)
|
||||
})
|
||||
}
|
@ -61,5 +61,26 @@
|
||||
"actions": [],
|
||||
"created": 1755215777,
|
||||
"updated": 1755215777
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"user_id": 1,
|
||||
"monster_id": 4,
|
||||
"monster_hp": 10,
|
||||
"monster_max_hp": 10,
|
||||
"monster_sleep": 0,
|
||||
"monster_immune": 0,
|
||||
"uber_damage": 0,
|
||||
"uber_defense": 0,
|
||||
"first_strike": false,
|
||||
"turn": 1,
|
||||
"ran_away": false,
|
||||
"victory": false,
|
||||
"won": false,
|
||||
"reward_gold": 0,
|
||||
"reward_exp": 0,
|
||||
"actions": [],
|
||||
"created": 1755222893,
|
||||
"updated": 1755222893
|
||||
}
|
||||
]
|
@ -3,8 +3,11 @@ package routes
|
||||
import (
|
||||
"dk/internal/auth"
|
||||
"dk/internal/components"
|
||||
"dk/internal/helpers"
|
||||
"dk/internal/middleware"
|
||||
"dk/internal/models/fights"
|
||||
"dk/internal/models/monsters"
|
||||
"dk/internal/models/spells"
|
||||
"dk/internal/models/users"
|
||||
"dk/internal/router"
|
||||
"math/rand"
|
||||
@ -28,6 +31,13 @@ func showFight(ctx router.Ctx, _ []string) {
|
||||
return
|
||||
}
|
||||
|
||||
monster, err := monsters.Find(fight.MonsterID)
|
||||
if err != nil {
|
||||
ctx.SetContentType("text/plain")
|
||||
ctx.SetBodyString("Monster not found for fight")
|
||||
return
|
||||
}
|
||||
|
||||
// If turn 0, determine first strike and advance to turn 1
|
||||
if fight.Turn == 0 {
|
||||
// 50% chance user goes first
|
||||
@ -36,8 +46,30 @@ func showFight(ctx router.Ctx, _ []string) {
|
||||
fight.Save()
|
||||
}
|
||||
|
||||
hpPct := helpers.ClampPct(float64(user.HP), float64(user.MaxHP), 0, 100)
|
||||
|
||||
hpColor := ""
|
||||
if hpPct < 35 {
|
||||
hpColor = "danger"
|
||||
} else if hpPct < 75 {
|
||||
hpColor = "warning"
|
||||
}
|
||||
|
||||
spellMap := helpers.NewOrderedMap[int, *spells.Spell]()
|
||||
if user.Spells != "" {
|
||||
for _, id := range user.GetSpellIDs() {
|
||||
if spell, err := spells.Find(id); err == nil {
|
||||
spellMap.Set(id, spell)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
components.RenderPage(ctx, "Fighting", "fight/fight.html", map[string]any{
|
||||
"fight": fight,
|
||||
"user": user,
|
||||
"fight": fight,
|
||||
"user": user,
|
||||
"monster": monster,
|
||||
"mon_hppct": hpPct,
|
||||
"mon_hpcol": hpColor,
|
||||
"spells": spellMap.ToSlice(),
|
||||
})
|
||||
}
|
||||
|
@ -1,5 +1,30 @@
|
||||
{include "layout.html"}
|
||||
|
||||
{block "content"}
|
||||
ITS A FIGHT!
|
||||
<div id="battle-window">
|
||||
<h2>Fighting {monster.Name}</h2>
|
||||
<h3>Level {monster.Level}</h3>
|
||||
|
||||
<img id="monster-image" src="/assets/images/monsters/{monster.Name}.png" alt="{monster.Name}" title="{monster.Name}">
|
||||
</div>
|
||||
|
||||
<span>{fight.MonsterHP}/{fight.MonsterMaxHP}</span>
|
||||
<div id="monster-health" class="mb-1">
|
||||
<div class="bar {mon_hpcol}" style="width: {mon_hppct}%;"></div>
|
||||
</div>
|
||||
|
||||
<form action="/fight" method="post">
|
||||
<div class="mb-05">
|
||||
<button class="btn btn-primary">Attack</button>
|
||||
</div>
|
||||
{if user.Spells != ""}
|
||||
<select id="spell-select" class="styled-select">
|
||||
{for spell in spells}
|
||||
<option value="{spell.ID}">({spell.MP} MP) {spell.Name}</option>
|
||||
{/for}
|
||||
</select>
|
||||
|
||||
<button class="btn btn-blue">Spell</button>
|
||||
{/if}
|
||||
</form>
|
||||
{/block}
|
||||
|
@ -9,6 +9,7 @@
|
||||
<link rel="stylesheet" href="/assets/dk.css">
|
||||
|
||||
<script src="/assets/scripts/confirm_modal.js"></script>
|
||||
<script src="/assets/scripts/select_arrows.js"></script>
|
||||
|
||||
<script>
|
||||
function open_char_popup()
|
||||
@ -65,5 +66,9 @@
|
||||
</div>
|
||||
|
||||
{yield "scripts"}
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', addSelectArrows)
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
Loading…
x
Reference in New Issue
Block a user