Skip to content

Commit

Permalink
Add deity filtering (but needs more data)
Browse files Browse the repository at this point in the history
  • Loading branch information
MaxWilson committed Nov 26, 2023
1 parent 5490b0b commit 3184397
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 22 deletions.
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!doctype html>
<html>
<head>
<title>RPG Utils</title>
<title>Shining Sword</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="shortcut icon" type="image/png" href="./img/favicon-32x32.png" sizes="32x32" />
Expand Down
35 changes: 33 additions & 2 deletions main.sass
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,23 @@ html
color-scheme: dark light

body
min-height: 100vh
height: 100svh
position: absolute // prevent margin collapse, to prevent unneeded scrollbars
width: 100%

#feliz-app, #feliz-app > div, #feliz-app > div > div
max-height: 100vh

img, picture, svg, video
display: block
max-width: 100%

// ShiningSword-specific logic here
ul
list-style-position: inside
margin-left: 1rem

.slideFromTop
animation: fromTop 0.5s ease-in-out
.slideFromLeft
Expand Down Expand Up @@ -86,6 +95,7 @@ img, picture, svg, video
transform: scale(0)

.hasMargins
box-sizing: border-box
margin: 3px

.header
Expand All @@ -109,9 +119,30 @@ img, picture, svg, video
display: none
.srcLink
max-width: 6rem
float: right
position: absolute
right: 3px
background-color: white

.horizontalStack
display: flex
width: calc(100% - 6px)
gap: 10px
> *
flex: 1
max-height: 100%

.scrollParent
display: flex
flex-direction: column
align-items: flex-start
max-height: 100%

.scrollable
overflow: auto
flex: 1
align-self: stretch

.mainPage // page styling for most pages in ShiningSword: display a basic layout with a header, some data items and links
@extend .fadeIn
@extend .hasMargins
max-height: calc(100vh - 6px)
40 changes: 36 additions & 4 deletions src/UI/Components/PriestSpells.fs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ let consolidateSpells spheres =
let consolidateSpheres (spells: Spell list) spheres =
let spells = spells |> List.map (fun spell -> spell.name, spell) |> Map.ofList
spheres |> List.map (fun sphere -> { sphere with spells = sphere.spells |> List.map (fun spell -> spells.[spell.name]) })
let spheres = """
let spheresData = """
All: Bless 1, Combine 1, Detect Evil 1, Purify Food & Drink 1, Atonement 5
Animal: Animal Friendship 1, Invisibility to Animals 1, Locate Animals or Plants 1, Charm Person or Mammal 2, Messenger 2,
Snake Charm 2, Speak With Animals 2, Hold Animal 3, Summon Insects 3, Animal Summoning I 4, Call Woodland Beings 4,
Expand Down Expand Up @@ -54,6 +54,10 @@ Summoning: Abjure 4, Animal Summoning I 4, Call Woodland Beings 4, Animal Summon
Sun: Light 1, Continual Light 3, Starshine 3, Moonbeam 5, Rainbow 5, Sunray 7
Weather: Faerie Fire 1, Obscurement 2, Call Lightning 3, Control Temperature 10' Radius 4, Protection From Lightning 4, Control Winds 5, Rainbow 5, Weather Summoning 6, Control Weather 7
"""
let deityData = """
Isis: All, Protection, Necromantic*
Osiris: Necromantic, Summoning
"""
module private Parser =
// #load @"c:\code\rpg\src\Core\Common.fs"
// #load @"c:\code\rpg\src\Core\CQRS.fs"
Expand Down Expand Up @@ -88,6 +92,17 @@ module private Parser =
| Sphere(lhs, OWS (Spheres(rhs, rest))) -> Some(lhs::rhs, rest)
| Sphere(v, rest) -> Some([v], rest)
| _ -> None
let (|SphereRef|_|) = function
| Word(name, Char('*', rest)) -> Some({ sphere = name; access = Minor }, rest)
| Word(name, rest) -> Some({ sphere = name; access = Major }, rest)
| _ -> None
let rec (|SphereRefs|_|) = pack <| function
| SphereRef(lhs, OWSStr "," (SphereRefs(rhs, rest))) -> Some(lhs :: rhs, rest)
| SphereRef(v, rest) -> Some([v], rest)
| _ -> None
let rec (|Deity|_|) = function
| NameChunk(name, OWSStr ":" (SphereRefs(spheres, rest))) -> Some({ name = name; spheres = spheres }, rest)
| _ -> None
// let partial (|Recognizer|_|) txt = match ParseArgs.Init txt with | Recognizer(v, _) -> v
// let partialR (|Recognizer|_|) txt = match ParseArgs.Init txt with | Recognizer(v, (input, pos)) -> v, input.input.Substring pos
// partial (|Spheres|_|) spheres |> List.collect _.spells |> List.filter (fun spell -> spell.name = "Chariot of Sustarre")
Expand All @@ -100,7 +115,7 @@ module Storage =
let key = "Spheres"
let cacheRead, cacheInvalidate = Cache.create()
let read (): Sphere list =
cacheRead (thunk2 read key (fun () -> Packrat.parser Parser.(|Spheres|_|) (spheres.Trim()) |> fun spheres -> spheres |> consolidateSpheres (consolidateSpells spheres)))
cacheRead (thunk2 read key (fun () -> Packrat.parser Parser.(|Spheres|_|) (spheresData.Trim()) |> fun spheres -> spheres |> consolidateSpheres (consolidateSpells spheres)))
let write (v: Sphere list) =
write key v
cacheInvalidate()
Expand All @@ -116,7 +131,7 @@ module Storage =
let key = "Deities"
let cacheRead, cacheInvalidate = Cache.create()
let read (): Deity list =
cacheRead (thunk2 read key (thunk []))
cacheRead (thunk2 read key (fun () -> deityData.Trim().Split("\r") |> List.ofArray |> List.map (Packrat.parser Parser.(|Deity|_|))))
let write (v: Deity list) =
write key v
cacheInvalidate()
Expand All @@ -142,5 +157,22 @@ let filteredSpells (filter: string) (model: Model) =
| "" -> model.options.spells
| filter ->
let fragments = filter.Split(' ') |> List.ofArray
model.options.spells |> List.filter (fun spell -> fragments |> List.every (fun fragment -> String.containsIgnoreCase (spell.ToString()) fragment))
let grantorsBySphere =
[
for sphere in model.options.spheres do
let grantors = [
for d in model.options.deities do
match d.spheres |> List.tryFind (fun s -> s.sphere = sphere.name) with
| Some v -> d.name, v.access
| None -> ()
]
sphere.name, grantors
]
|> Map.ofList
let isMatch (spell: Spell) fragment =
if String.containsIgnoreCase(spell.ToString()) fragment then true
else spell.spheres |> List.exists (fun sphere -> grantorsBySphere[sphere] |> List.exists (fun (deity, access) -> String.containsIgnoreCase deity fragment && (spell.level <= 3 || access = Major)))

let matchingDeities spell = model.options.deities |> List.filter (fun deity -> fragments |> List.exists (fun fragment -> String.containsIgnoreCase deity.name fragment))
model.options.spells |> List.filter (fun spell -> fragments |> List.every (isMatch spell))

51 changes: 36 additions & 15 deletions src/UI/Components/PriestSpellsView.fs
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,43 @@ open UI.PriestSpells
let View() =
let model, dispatch = React.useElmishSimple init update
let filter, setFilter = React.useState ""
Html.div [
Html.h1 "Priest Spells"
Html.input [
prop.value filter
prop.placeholder "Spell name, sphere or deity"
prop.onChange (fun txt -> setFilter txt)
class' "mainPage horizontalStack" Html.div [
class' "scrollParent" Html.div [
Html.h1 "Priest Spells"
Html.input [
prop.value filter
prop.placeholder "Spell name, sphere or deity"
prop.onChange (fun txt -> setFilter txt)
]
class' "scrollable" Html.ul [
let spells = filteredSpells filter model |> List.groupBy _.level |> List.sortBy fst
for level, spells in spells do
let ordinalToText = function
| 1 -> "1st"
| 2 -> "2nd"
| 3 -> "3rd"
| n -> sprintf "%dth" n
Html.h2 [prop.text (ordinalToText level)]
for spell in spells do
Html.li [
Html.span [
prop.text ($"""{spell.name} ({spell.spheres |> String.join "/"})""")
]
Html.span [
prop.text (match model.picks.TryFind(spell.name) with Some(n) -> $" ({n})" | None -> "")
]
]
]
]
Html.ul [
for spell in filteredSpells filter model do
Html.li [
Html.span [
prop.text (spell.ToString())
Html.div [
Html.h2 "Gods"
Html.ul [
for deity in model.options.deities do
Html.li [prop.text deity.name]
Html.ul [
for sphere in deity.spheres do
Html.li [prop.text (sphere.sphere + if sphere.access = Minor then "*" else "")]
]
Html.span [
prop.text (match model.picks.TryFind(spell.name) with Some(n) -> $" ({n})" | None -> "")
]
]
]
]
]

0 comments on commit 3184397

Please sign in to comment.