Skip to content

Commit 13b130e

Browse files
authored
Merge pull request #15 from jake-abed/v0.3.0-fixes
V0.3.0 fixes
2 parents e020c6f + eab7956 commit 13b130e

File tree

9 files changed

+243
-137
lines changed

9 files changed

+243
-137
lines changed

README.md

Lines changed: 55 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# Lore
2+
23
A CLI tool for game masters running D&D, Pathfinder, and other tabletop game
34
campaigns. All written in Go. While I still largely run a pen & paper campaign,
45
I always keep a laptop up and running for looking up info and keeping notes.
@@ -10,14 +11,17 @@ Currently a work in progress, but still functional!
1011
## Installing Lore
1112

1213
Prerequisites:
14+
1315
- Go
1416
- SQLite3
1517

16-
Install the Go toolchain [via the docs](https://go.dev/doc/install) or [via webi](https://webinstall.dev/golang/)!
18+
Install the Go toolchain [via the docs](https://go.dev/doc/install) or
19+
[via webi](https://webinstall.dev/golang/)!
1720

1821
Install SQLite3 via your necessary method!
1922

2023
For example:
24+
2125
```bash
2226
# Ubuntu
2327
sudo apt update && sudo apt upgrade && sudo apt install sqlite3
@@ -30,51 +34,73 @@ brew install sqlite3
3034
```
3135

3236
Now simply install Lore via the Go toolchain:
37+
3338
```bash
3439
go install github.com/jake-abed/lore
3540
```
3641

3742
## Commands
3843

3944
### **help**
45+
4046
Lists all available commands
4147

4248
### **dice**
43-
- **-a <dice-expression>** | Rolls a dice expression and returns the result summed up.
44-
- **-i <dice-expression>** | Rolls a dice expression, printing each roll individually, then summing it up.
49+
50+
- **-a <dice-expression>** | Rolls a dice expression and returns the result
51+
summed up.
52+
- **-i <dice-expression>** | Rolls a dice expression, printing each roll
53+
individually, then summing it up.
54+
4555
#### Examples of Dice Expressions
46-
> d20, 1d6, 2d12+1, 1d4-1, 3d6+8, 5d20+12, 80d100-50, etc.
56+
57+
> d20, 1d6, 2d12+1, 1d4-1, 3d6+8, 5d20+12, 80d100-50, etc.
4758
4859
### **monsters**
49-
- **-i <monster name or id>** | Get basic information about a monster from the D&D 5e API.
50-
- **-f <monster-1> <monster-2>** | Simulate a turn-based fight between two monsters.
51-
- - Slightly skewed as it does not factor movement or flying into the battles, so extremely agile or flying monsters will have less of an edge than they normal would.
60+
61+
- **-i <monster name or id>** | Get basic information about a monster from the
62+
D&D 5e API.
63+
- **-f <monster-1> <monster-2>** | Simulate a turn-based fight between two
64+
monsters.
65+
- - Slightly skewed as it does not factor movement or flying into the battles,
66+
so extremely agile or flying monsters will have less of an edge than they
67+
normal would.
68+
- **-va** | View all monsters from the D&D API. Great with grep!
5269

5370
### **npcs**
71+
5472
View, search, edit, and create custom NPCs for your campaign.
5573

56-
- **-a** | Add new NPC via form!
74+
- **-a** | Add new NPC via form!
5775
- **-v <name>** | View an NPC with the provided name (exact match).
76+
- **-d <id>** | Delete an NPC by ID.
5877
- **-s <name>** | Lists all NPCs that partially match the provided name.
5978
- **-e <name>** | Edit an NPC with the provided name (exact match).
6079

6180
### **places**
81+
6282
View, search, edit, and create custom places for your campaign.
63-
- **<place-flag> -a** | Add a new place via form!
64-
- **<place-flag> -d** <id> | Delete a place by ID represented as an integer.
65-
- **<place-flag > -v <name>** | View a place with the provided name (exact match).
66-
- **<place-flag> -s <name>** | Lists all places that partially match the provided name.
67-
- **<place-flag> -e <name>** | Edit a place with the provided name (exact match).
83+
84+
- **<place-flag> -a** | Add a new place via form!
85+
- **<place-flag> -d** <id> | Delete a place by ID represented as an integer.
86+
- **<place-flag > -v <name>** | View a place with the provided name (exact
87+
match).
88+
- **<place-flag> -s <name>** | Lists all places that partially match the
89+
provided name.
90+
- **<place-flag> -e <name>** | Edit a place with the provided name (exact
91+
match).
6892

6993
#### Uses 'place flags' to mark which place type you are operating on.
70-
- --world | Overaching world for a campaign.
71-
- --area | Areas or regions of a world.
72-
- --location | Locations contained within areas.
94+
95+
- --world | Overaching world for a campaign.
96+
- --area | Areas or regions of a world.
97+
- --location | Locations contained within areas.
7398
- --sublocation | Not implemented! Not sure if necessary or overkill?
7499

75100
## Roadmap
76101

77102
While not set in stone, hitting a true v1.0.0 will include:
103+
78104
- [x] ~~Dice Rolls~~
79105
- - ~~`lore dice <dice-arg>` allowing for dynamic dice rolls!~~
80106
- - - ~~For example `lore dice 2d6+1` rolls two six-sided die and adds one!~~
@@ -89,30 +115,38 @@ While not set in stone, hitting a true v1.0.0 will include:
89115
- [ ] Encounters
90116
- - Write encounters and then serve them up randomly to the GM.
91117

92-
I'm also debating adding a custom monsters section or replacing the API with custom monsters. The catch here is that monsters are... complex and require significantly more work to customize. They also require knowledge of the game system being used. Lore is supposed to be game system agnostic for custom info. So, feedback would be nice here.
118+
I'm also debating adding a custom monsters section or replacing the API with
119+
custom monsters. The catch here is that monsters are... complex and require
120+
significantly more work to customize. They also require knowledge of the game
121+
system being used. Lore is supposed to be game system agnostic for custom info.
122+
So, feedback would be nice here.
93123

94124
### NB on Compatibility
95125

96-
Up until v1.0.0 Lore should be considered unstable. The shape of the DB is a work in progress and I cannot promise compatibility.
126+
Up until v1.0.0 Lore should be considered unstable. The shape of the DB is a
127+
work in progress and I cannot promise compatibility.
97128

98-
Starting at v1.0.0, the DB schema will be stable and non-breaking changes only will happen.
129+
Starting at v1.0.0, the DB schema will be stable and non-breaking changes only
130+
will happen.
99131

100132
## Contributing
101133

102134
Want to contribute to Lore at all?
103135

104136
### Clone the repo:
137+
105138
```bash
106139
git clone https://github.com/jake-abed/lore
107140
cd lore
108141
```
109142

110143
### Build it:
144+
111145
```bash
112146
go build
113147
```
114148

115149
### Submit a pull request!
116150

117-
If you want to contribute anything at all, please fork the repository
118-
and open up a pull request to the 'main' branch.
151+
If you want to contribute anything at all, please fork the repository and open
152+
up a pull request to the 'main' branch.

commands/command.go

Lines changed: 5 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
)
77

88
type Command struct {
9-
Flags map[string]string
109
Name string
1110
Description string
1211
Callback func(*State) error
@@ -23,70 +22,32 @@ func BuildCommands() map[string]Command {
2322
"help": {
2423
Name: "help",
2524
Description: "Get information about all available commands.",
26-
Flags: nil,
2725
Callback: commandHelp,
2826
},
2927
"dice": {
3028
Name: "dice",
3129
Description: "Roll dice in the following format: {qtyDice}d{Die}{+/-}{modifier}.",
32-
Flags: map[string]string{
33-
"-a": "Rolls all the dice at once and returns the result.",
34-
"-i": "Rolls individual dice, presenting the result, then returning the total.",
35-
"Examples": "d20, 1d6, 2d12+1, 1d4-1, 3d6+8, 5d20+12, 80d100-50, etc.",
36-
},
37-
Callback: commandDice,
30+
Callback: commandDice,
3831
},
3932
"monsters": {
4033
Name: "monsters",
4134
Description: "Get info about monsters and simulate fights.",
42-
Flags: map[string]string{
43-
"-i": "Looks up info about a particular monster by name or id slug.",
44-
"-f": "Simulate a fight between two monsters. Name or id slug work.",
45-
"-va": "View all monsters on the D&D 5e OpenAPI.",
46-
},
47-
Callback: commandMonsters,
35+
Callback: commandMonsters,
4836
},
4937
"npcs": {
5038
Name: "npcs",
5139
Description: "Add, search, edit, & view info about NPCs.",
52-
Flags: map[string]string{
53-
"-v": "Inspect an NPC and view their info.",
54-
"-a": "Add an NPC to your local database for your campaign.",
55-
"-e": "Edit an NPC's info by name. Case-insensitive.",
56-
"-s": "Search your NPCs by name. Returns all possible matches.",
57-
"-d": "Delete an NPC by name. Case-sensitive.",
58-
},
59-
Callback: commandNpcs,
40+
Callback: commandNpcs,
6041
},
6142
"places": {
6243
Name: "places",
6344
Description: "Add, search, edit, & view worlds, areas, & locations.",
64-
Flags: map[string]string{
65-
"-a": "Add a place.",
66-
"-e": "Edit a place.",
67-
"-s": "Search places by name. Returns all possible matches",
68-
"-d": "Delete a place by name. Case-sensitive.",
69-
"-v": "Inspect a place and it's information by name.",
70-
"-va": "View a short summary of all places by place flag.",
71-
"--world": "Specify an operation on a world.",
72-
"--area": "Specify an operation on an area.",
73-
"--location": "Specify an operation on a location.",
74-
"--sublocation": "Specify an operation on a sublocation.",
75-
},
76-
Callback: commandPlaces,
45+
Callback: commandPlaces,
7746
},
7847
"quests": {
7948
Name: "quests",
8049
Description: "Add, search, edit & view quests & quest steps.",
81-
Flags: map[string]string{
82-
"-a": "Add a quest.",
83-
"-e": "Edit a quest by ID.",
84-
"-v": "View a quest by ID.",
85-
"-d": "Delete a quest by ID.",
86-
"-s": "Search a quest by name.",
87-
"-va": "View all quests, returning most data. Great for grep & piping!",
88-
},
89-
Callback: commandQuests,
50+
Callback: commandQuests,
9051
},
9152
}
9253
}

commands/command_dice.go

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,12 @@ func commandDice(s *State) error {
1212
diceArgs := s.Args[1:]
1313

1414
if len(diceArgs) == 0 {
15-
return fmt.Errorf("The dice command requires at least one argument!")
15+
return fmt.Errorf("the dice command requires at least one argument")
16+
}
17+
18+
if len(diceArgs) == 1 && diceArgs[0] == "help" {
19+
diceHelp()
20+
return nil
1621
}
1722

1823
var flag string
@@ -27,7 +32,7 @@ func commandDice(s *State) error {
2732
}
2833

2934
if !strings.Contains(diceExpression, "d") {
30-
return fmt.Errorf("Invalid Dice Expression: %s", diceExpression)
35+
return fmt.Errorf("nvalid Dice Expression: %s", diceExpression)
3136
}
3237

3338
switch flag {
@@ -53,11 +58,26 @@ func commandDice(s *State) error {
5358
msg = bold.Render(msg)
5459
fmt.Println(msg, roll)
5560
}
56-
msg := fmt.Sprintf("Sum of all rolls & modifier: ")
61+
msg := "Sum of all rolls & modifier: "
5762
msg = bold.Render(msg)
5863
fmt.Println(msg, sum+int(modifier))
5964
default:
60-
return fmt.Errorf("Unknown flag for dice subcommand!")
65+
return fmt.Errorf("unknown flag for dice subcommand")
6166
}
6267
return nil
6368
}
69+
70+
func diceHelp() {
71+
intro := "Lore Dice Help\n"
72+
introTip := "Dice subcommands information"
73+
fmt.Println(header.Render(intro + introTip))
74+
all := bold.Render(" *** dice -a <monster-1> <monster-2> | ")
75+
allMessage := "Roll all the dice of an expression together returning the result."
76+
fmt.Println(all + allMessage)
77+
individual := bold.Render(" *** dice -i <dice-expression> | ")
78+
individualMessage := "Roll each die of an expression one at a time."
79+
fmt.Println(individual + individualMessage)
80+
example := bold.Render(" *** Examples | ")
81+
exampleMessage := "d20, 1d6, 2d12+1, 1d4-1, 3d6+8, 5d20+12, 80d100-50, etc.\n"
82+
fmt.Println(example + exampleMessage)
83+
}

commands/command_help.go

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,26 @@ func commandHelp(s *State) error {
99
commands := BuildCommands()
1010

1111
if len(s.Args) > 1 {
12-
cmd := s.Args[1]
13-
err := SingleCommandHelp(s, commands, cmd)
14-
if err != nil {
15-
return err
12+
cmd := strings.ToLower(s.Args[1])
13+
switch cmd {
14+
case "monsters":
15+
monstersHelp()
16+
return nil
17+
case "npcs":
18+
npcHelp()
19+
return nil
20+
case "quests":
21+
questsHelp()
22+
return nil
23+
case "places":
24+
placesHelp()
25+
return nil
26+
case "dice":
27+
diceHelp()
28+
case "help":
29+
helpHelp()
30+
return nil
1631
}
17-
return nil
1832
}
1933

2034
intro := "Welcome to Lore!\n"
@@ -30,29 +44,10 @@ func commandHelp(s *State) error {
3044
return nil
3145
}
3246

33-
func SingleCommandHelp(
34-
s *State,
35-
commands map[string]Command,
36-
cmdName string,
37-
) error {
47+
func helpHelp() {
3848
intro := "Welcome to Lore!\n"
39-
introMsg := fmt.Sprintf("The %s command has the following flags: ", cmdName)
49+
introMsg := fmt.Sprintf("The %s command has the following flags: ", "help")
4050
fmt.Println(header.Render(intro + introMsg))
41-
commandDiv := ""
42-
cmd, ok := commands[cmdName]
43-
if !ok {
44-
return fmt.Errorf("That command does not exist in Lore!")
45-
}
46-
47-
if cmd.Name == "help" {
48-
commandDiv += "The help subcommand helps you. It's helping right now!"
49-
}
50-
51-
for key, val := range cmd.Flags {
52-
name := bold.Render(fmt.Sprintf("%-13s", key))
53-
desc := italic.Render(val)
54-
commandDiv += fmt.Sprintf("%s <==> %v\n", name, desc)
55-
}
51+
commandDiv := "The help subcommand helps you. It's helping right now!"
5652
fmt.Println(commandBox.Render(strings.TrimRight(commandDiv, "\n")))
57-
return nil
5853
}

commands/command_monsters.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ func simulateFight(monsterOne, monsterTwo dndapi.Monster) {
145145
firstAttacks := first.ParseAttacks()
146146
secondAttacks := second.ParseAttacks()
147147

148+
var winner *dndapi.Monster
149+
148150
for hpOne > 0 && hpTwo > 0 {
149151
firstAttack := dndapi.UseRandomAttack(firstAttacks)
150152
secondAttack := dndapi.UseRandomAttack(secondAttacks)
@@ -169,6 +171,10 @@ func simulateFight(monsterOne, monsterTwo dndapi.Monster) {
169171
)
170172
}
171173
hpTwo -= firstDamage
174+
if hpTwo <= 0 {
175+
hpTwo = 0
176+
winner = &monsterOne
177+
}
172178
fmt.Print(firstMessage)
173179
time.Sleep(time.Millisecond * 800)
174180

@@ -188,13 +194,18 @@ func simulateFight(monsterOne, monsterTwo dndapi.Monster) {
188194
)
189195
}
190196
hpOne -= secondDamage
197+
if hpOne <= 0 {
198+
hpOne = 0
199+
winner = &monsterTwo
200+
}
191201
fmt.Print(secondMessage)
192202
time.Sleep(time.Millisecond * 800)
193203

194204
fmt.Printf("%s HP Remaining: %d, %s HP Remaining: %d\n",
195205
first.Name, hpOne, second.Name, hpTwo)
196206
time.Sleep(time.Millisecond * 1000)
197207
}
208+
fmt.Printf("%s won the battle!\n", winner.Name)
198209
}
199210

200211
func parseDamage(

0 commit comments

Comments
 (0)