start help pages; fixes broken help links
This commit is contained in:
parent
e3146068bc
commit
c226f6200f
@ -577,3 +577,7 @@ div.bottom-reply {
|
||||
.mt-1 {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
hr {
|
||||
margin: 1rem 0;
|
||||
}
|
BIN
data/dk.db
BIN
data/dk.db
Binary file not shown.
@ -3,6 +3,7 @@ package routes
|
||||
import (
|
||||
"dk/internal/components"
|
||||
"dk/internal/database"
|
||||
"dk/internal/helpers"
|
||||
"dk/internal/helpers/markdown"
|
||||
"dk/internal/models/forum"
|
||||
"dk/internal/models/users"
|
||||
@ -15,8 +16,7 @@ import (
|
||||
"git.sharkk.net/Sharkk/Sushi/auth"
|
||||
)
|
||||
|
||||
// ThreadData flattened struct for template use
|
||||
type ThreadData struct {
|
||||
type threadData struct {
|
||||
ID int
|
||||
Posted int64
|
||||
LastPost int64
|
||||
@ -34,8 +34,7 @@ type ThreadData struct {
|
||||
HasReplies bool
|
||||
}
|
||||
|
||||
// ReplyData flattened struct for template use
|
||||
type ReplyData struct {
|
||||
type replyData struct {
|
||||
ID int
|
||||
Posted int64
|
||||
Author int
|
||||
@ -46,47 +45,18 @@ type ReplyData struct {
|
||||
AuthorClass string
|
||||
}
|
||||
|
||||
// Helper methods for ThreadData
|
||||
func (t *ThreadData) PostedTime() time.Time {
|
||||
func (t *threadData) PostedTime() time.Time {
|
||||
return time.Unix(t.Posted, 0)
|
||||
}
|
||||
|
||||
func (t *ThreadData) LastPostTime() time.Time {
|
||||
func (t *threadData) LastPostTime() time.Time {
|
||||
return time.Unix(t.LastPost, 0)
|
||||
}
|
||||
|
||||
// Helper methods for ReplyData
|
||||
func (r *ReplyData) PostedTime() time.Time {
|
||||
func (r *replyData) PostedTime() time.Time {
|
||||
return time.Unix(r.Posted, 0)
|
||||
}
|
||||
|
||||
// PaginationParams handles common pagination logic
|
||||
type PaginationParams struct {
|
||||
Page int
|
||||
PerPage int
|
||||
Total int
|
||||
}
|
||||
|
||||
func (p PaginationParams) Offset() int {
|
||||
return (p.Page - 1) * p.PerPage
|
||||
}
|
||||
|
||||
func (p PaginationParams) TotalPages() int {
|
||||
pages := (p.Total + p.PerPage - 1) / p.PerPage
|
||||
if pages < 1 {
|
||||
return 1
|
||||
}
|
||||
return pages
|
||||
}
|
||||
|
||||
func (p PaginationParams) HasNext() bool {
|
||||
return p.Page < p.TotalPages()
|
||||
}
|
||||
|
||||
func (p PaginationParams) HasPrev() bool {
|
||||
return p.Page > 1
|
||||
}
|
||||
|
||||
func RegisterForumRoutes(app *sushi.App) {
|
||||
authed := app.Group("/forum")
|
||||
authed.Use(auth.RequireAuth())
|
||||
@ -117,19 +87,19 @@ func validateThread(ctx sushi.Ctx, id int) (*forum.Forum, bool) {
|
||||
}
|
||||
|
||||
// Helper function to get pagination params from request
|
||||
func getPaginationParams(ctx sushi.Ctx, perPage int) PaginationParams {
|
||||
func getPagination(ctx sushi.Ctx, perPage int) helpers.Pagination {
|
||||
page := max(int(ctx.QueryArgs().GetUintOrZero("page")), 1)
|
||||
return PaginationParams{
|
||||
return helpers.Pagination{
|
||||
Page: page,
|
||||
PerPage: perPage,
|
||||
}
|
||||
}
|
||||
|
||||
func index(ctx sushi.Ctx) {
|
||||
pagination := getPaginationParams(ctx, 30)
|
||||
pagination := getPagination(ctx, 30)
|
||||
|
||||
// Get threads with user data
|
||||
var threads []*ThreadData
|
||||
var threads []*threadData
|
||||
query := `
|
||||
SELECT f.id, f.posted, f.last_post, f.author, f.parent, f.replies, f.title, f.content,
|
||||
COALESCE(u.username, '[Deleted]') as author_username,
|
||||
@ -145,7 +115,7 @@ func index(ctx sushi.Ctx) {
|
||||
err := database.Select(&threads, query, pagination.PerPage, pagination.Offset())
|
||||
if err != nil {
|
||||
log.Printf("Error fetching forum threads: %v", err)
|
||||
threads = make([]*ThreadData, 0)
|
||||
threads = make([]*threadData, 0)
|
||||
}
|
||||
|
||||
// Get last reply info for each thread
|
||||
@ -235,11 +205,11 @@ func showThread(ctx sushi.Ctx) {
|
||||
return
|
||||
}
|
||||
|
||||
pagination := getPaginationParams(ctx, 10)
|
||||
pagination := getPagination(ctx, 10)
|
||||
pagination.Total = thread.Replies
|
||||
|
||||
// Get thread with author data
|
||||
var threadData ThreadData
|
||||
var threadData threadData
|
||||
err := database.Get(&threadData, `
|
||||
SELECT f.id, f.posted, f.last_post, f.author, f.parent, f.replies, f.title, f.content,
|
||||
COALESCE(u.username, '[Deleted]') as author_username,
|
||||
@ -259,7 +229,7 @@ func showThread(ctx sushi.Ctx) {
|
||||
}
|
||||
|
||||
// Get replies with user data
|
||||
var replies []*ReplyData
|
||||
var replies []*replyData
|
||||
err = database.Select(&replies, `
|
||||
SELECT f.id, f.posted, f.author, f.title, f.content,
|
||||
COALESCE(u.username, '[Deleted]') as author_username,
|
||||
@ -274,7 +244,7 @@ func showThread(ctx sushi.Ctx) {
|
||||
|
||||
if err != nil {
|
||||
log.Printf("Error loading replies for thread %d: %v", id, err)
|
||||
replies = make([]*ReplyData, 0)
|
||||
replies = make([]*replyData, 0)
|
||||
}
|
||||
|
||||
components.RenderPage(ctx, threadData.Title, "forum/thread.html", map[string]any{
|
||||
|
16
internal/routes/help.go
Normal file
16
internal/routes/help.go
Normal file
@ -0,0 +1,16 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"dk/internal/components"
|
||||
|
||||
sushi "git.sharkk.net/Sharkk/Sushi"
|
||||
)
|
||||
|
||||
func RegisterHelpRoutes(app *sushi.App) {
|
||||
group := app.Group("/help")
|
||||
group.Get("/", guide)
|
||||
}
|
||||
|
||||
func guide(ctx sushi.Ctx) {
|
||||
components.RenderPage(ctx, "Help", "help/guide.html", map[string]any{})
|
||||
}
|
1
main.go
1
main.go
@ -180,6 +180,7 @@ func start(port string) error {
|
||||
routes.RegisterTownRoutes(app)
|
||||
routes.RegisterFightRoutes(app)
|
||||
routes.RegisterForumRoutes(app)
|
||||
routes.RegisterHelpRoutes(app)
|
||||
|
||||
app.Get("/assets/*path", sushi.Static(cwd))
|
||||
|
||||
|
190
templates/help/guide.html
Normal file
190
templates/help/guide.html
Normal file
@ -0,0 +1,190 @@
|
||||
{include "layout.html"}
|
||||
|
||||
{block "content"}
|
||||
<a name="top"></a>
|
||||
<h1>Help</h1>
|
||||
[ <a href="/index.php">Return to the game</a> ]
|
||||
|
||||
<hr>
|
||||
|
||||
<h3>Table of Contents</h3>
|
||||
<ul>
|
||||
<li><a href="#intro">Introduction</a></li>
|
||||
<li><a href="#classes">Character Classes</a></li>
|
||||
<li><a href="#intown">In Town</a></li>
|
||||
<li><a href="#exploring">Exploring & Fighting</a></li>
|
||||
<li><a href="#status">Status Panels</a></li>
|
||||
<li><a href="#items">Items & Drops</a></li>
|
||||
<li><a href="#monsters">Monsters</a></li>
|
||||
<li><a href="#spells">Spells</a></li>
|
||||
<li><a href="#levels">Levels</a></li>
|
||||
<li><a href="#credits">Credits</a></li>
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
|
||||
<h3><a name="intro"></a>Introduction</h3>
|
||||
Firstly, I'd like to say thank you for playing my game. The <i>Dragon Knight</i> game engine is the result of several months of
|
||||
planning, coding and testing. The original idea was to create a web-based tribute to the NES game, <i>Dragon
|
||||
Warrior</i>. In its current iteration, only the underlying fighting system really resembles that game, as almost
|
||||
everything else in DK has been made bigger and better. But you should still recognize bits and pieces as stemming
|
||||
from <i>Dragon Warrior</i> and other RPGs of old.<br><br>
|
||||
This is the first game I've ever written, and it has definitely been a positive experience. It got difficult at
|
||||
times, admittedly, but it was still a lot of fun to write, and even more fun to play. And I hope to use this
|
||||
experience so that if I ever want to create another game it will be even better than this one.<br><br>
|
||||
If you are a site administrator, and would like to install a copy of DK on your own server, you may visit the
|
||||
<a href="http://dragon.se7enet.com/dev.php" target="_new">development site</a> for <i>Dragon Knight</i>. This page
|
||||
includes the downloadable game souce code, as well as some other resources that developers and administrators may
|
||||
find valuable.<br><br>
|
||||
Once again, thanks for playing!<br><br>
|
||||
<i>Jamin Seven</i><br>
|
||||
<i>Dragon Knight creator</i><br>
|
||||
<a href="http://www.se7enet.com" target="_new">My Homepage</a><br>
|
||||
<a href="http://dragon.se7enet.com/dev.php" target="_new">Dragon Knight Homepage</a><br ><br>
|
||||
[ <a href="#top">Top</a> ]
|
||||
|
||||
<hr>
|
||||
|
||||
<h3><a name="classes"></a>Character Classes</h3>
|
||||
There are three character classes in the game. The main differences between the classes are what spells you get
|
||||
access to, the speed with which you level up, and the amount of HP/MP/strength/dexterity you gain per level. Below
|
||||
is a basic outline of each of the character classes. For more detailed information about the characters, please
|
||||
view the Levels table at the bottom of this page. Also, note that the outline below refers to the stock class setup
|
||||
for the game. If your administrator has used his/her own class setup, this information may not be accurate.<br><br>
|
||||
<b>@TODO</b>
|
||||
|
||||
<hr>
|
||||
|
||||
<h3><a name="intown"></a>In Town</h3>
|
||||
When you begin a new game, the first thing you see is the Town screen. Towns serve four primary functions: healing, buying items,
|
||||
buying maps, and displaying game information.<br><br>
|
||||
To heal yourself, click the "Rest at the Inn" link at the top of the town screen. Each town's Inn has a different price - some towns
|
||||
are cheap, others are expensive. No matter what town you're in, the Inns always serve the same function: they restore your current
|
||||
hit points, magic points, and travel points to their maximum amounts. Out in the field, you are free to use healing spells to restore
|
||||
your hit points, but when you run low on magic points, the only way to restore them is at an Inn.<br><br>
|
||||
Buying weapons and armor is accomplished through the appropriately-named "Buy Weapons/Armor" link. Not every item is available in
|
||||
every town, so in order to get the most powerful items, you'll need to explore some of the outer towns. Once you've clicked the link,
|
||||
you are presented with a list of items available in this town's store. To the left of each item is an icon that represents its type:
|
||||
weapon, armor or shield. The amount of attack/defense power, as well as the item's price, are displayed to the right of the item name.
|
||||
You'll notice that some items have a red asterisk (<span class="highlight">*</span>) next to their names. These are items that come
|
||||
with special attributes that modify other parts of your character profile. See the Items & Drops table at the bottom of this page for
|
||||
more information about special items.<br><br>
|
||||
Maps are the third function in towns. Buying a map to a town places the town in your Travel To box in the left status panel. Once
|
||||
you've purchased a town's map, you can click its name from your Travel To box and you will jump to that town. Travelling this way
|
||||
costs travel points, though, and you'll only be able to visit towns if you have enough travel points.<br><br>
|
||||
The final function in towns is displaying game information and statistics. This includes the latest news post made by the game
|
||||
administrator, a list of players who have been online recently, and the Babble Box.<br><br>
|
||||
[ <a href="#top">Top</a> ]
|
||||
|
||||
<hr>
|
||||
|
||||
<h3><a name="exploring"></a>Exploring & Fighting</h3>
|
||||
Once you're done in town, you are free to start exploring the world. Use the compass buttons on the left status panel to move around.
|
||||
The game world is basically a big square, divided into four quadrants. Each quadrant is {control.WorldSize} spaces
|
||||
square. The first town is usually located at (0N,0E). Click the North button from the first town, and now you'll be at (1N,0E).
|
||||
Likewise, if you now click the West button, you'll be at (1N,1W). Monster levels increase with every 5 spaces you move outward
|
||||
from (0N,0E).<br><br>
|
||||
While you're exploring, you will occasionally run into monsters. As in pretty much any other RPG game, you and the monster take turns
|
||||
hitting each other in an attempt to reduce each other's hit points to zero. Once you run into a monster, the Exploring screen changes
|
||||
to the Fighting screen.<br><br>
|
||||
When a fight begins, you'll see the monster's name and hit points, and the game will ask you for your first command. You then get to
|
||||
pick whether you want to fight, use a spell, or run away. Note, though, that sometimes the monster has the chance to hit you
|
||||
first.<br><br>
|
||||
The Fight button is pretty straightforward: you attack the monster, and the amount of damage dealt is based on your attack power and
|
||||
the monster's armor. On top of that, there are two other things that can happen: an Excellent Hit, which doubles your total attack
|
||||
damage; and a monster dodge, which results in you doing no damage to the monster.<br><br>
|
||||
The Spell button allows you to pick an available spell and cast it. See the Spells list at the bottom of this page for more information
|
||||
about spells.<br><br>
|
||||
Finally, there is the Run button, which lets you run away from a fight if the monster is too powerful. Be warned, though: it is
|
||||
possible for the monster to block you from running and attack you. So if your hit points are low, you may fare better by staying
|
||||
around monsters that you know can't do much damage to you.<br><br>
|
||||
Once you've had your turn, the monster also gets his turn. It is also possible for you to dodge the monster's attack and take no
|
||||
damage.<br><br>
|
||||
The end result of a fight is either you or the monster being knocked down to zero hit points. If you win, the monster dies and will
|
||||
give you a certain amount of experience and gold. There is also a chance that the monster will drop an item, which you can put into
|
||||
one of the three inventory slots to give you extra points in your character profile. If you lose and die, half of your gold is taken
|
||||
away - however, you are given back a few hit points to help you make it back to town (for example, if you don't have enough gold to
|
||||
pay for an Inn, and need to kill a couple low-level monsters to get the money).<br><br>
|
||||
When the fight is over, you can continue exploring until you find another monster to beat into submission.<br><br>
|
||||
[ <a href="#top">Top</a> ]
|
||||
|
||||
<hr>
|
||||
|
||||
<h3><a name="status"></a>Status Panels</h3>
|
||||
There are two status panels on the game screen: left and right.<br><br>
|
||||
The left panel inclues your current location and play status (In Town, Exploring, Fighting), compass buttons for movement, and the
|
||||
Travel To list for jumping between towns. At the bottom of the left panel is also a list of game functions.<br><br>
|
||||
The right panel displays some character statistics, your inventory, and quick spells.<br><br>
|
||||
The Character section shows the most important character statistics. It also displays the status bars for your current hit points,
|
||||
magic points and travel points. These status bars are colored either green, yellow or red depending on your current amount of each
|
||||
stat. There is also a link to pop up your list of extended statistics, which shows more detailed character information.<br><br>
|
||||
The Fast Spells section lists any Heal spells you've learned. You may use these links any time you are in town or exploring to cast
|
||||
the heal spell. These may not be used during fights, however - you have to use the Spells box on the fight screen for that.
|
||||
[ <a href="#top">Top</a> ]
|
||||
|
||||
<hr>
|
||||
|
||||
<h3><a name="items"></a>Items & Drops</h3>
|
||||
<a href="help.php?page=items">Click here</a> for the Items & Drops spoiler page.<br><br>
|
||||
[ <a href="#top">Top</a> ]
|
||||
|
||||
<hr>
|
||||
|
||||
<h3><a name="monsters"></a>Monsters</h3>
|
||||
<a href="help.php?page=monsters">Click here</a> for the Monsters spoiler page.<br><br>
|
||||
[ <a href="#top">Top</a> ]
|
||||
|
||||
<hr>
|
||||
|
||||
<h3><a name="spells"></a>Spells</h3>
|
||||
<a href="help.php?page=spells">Click here</a> for the Spells spoiler page.<br><br>
|
||||
[ <a href="#top">Top</a> ]
|
||||
|
||||
<hr>
|
||||
|
||||
<h3><a name="credits"></a>Credits</h3>
|
||||
<ul>
|
||||
<li><b>All program code and stock graphics for the game were created by Jamin Seven</b>.<br><br></li>
|
||||
<li>Major props go to a few people on the PHP manual site, for help with various chunks of code. The specific people are listed in the source code.<br><br></li>
|
||||
<li>Super monkey love goes to Enix and the developers of <i>Dragon Warrior</i>. If it weren't for you guys, my game never would have been made.<br><br></li>
|
||||
<li>Mega props go to Dalez from GameFAQs for his DW3 experience chart, which was where I got my experience levels from.<br><br></li>
|
||||
<li>
|
||||
Mad crazy ninja love goes to the following people for help and support throughout the development process:<br><br>
|
||||
<b>Ideas:</b> (whether they got used or not)
|
||||
<ul>
|
||||
<li>kushet</li>
|
||||
<li>lghtning</li>
|
||||
<li>Ebolamonkey3000</li>
|
||||
<li>Crimson Scythe</li>
|
||||
<li>SilDeath</li>
|
||||
</ul>
|
||||
<b>Beta Testing:</b> (forums name if applicable, character name otherwise)
|
||||
<ul>
|
||||
<li>Ebolamonkey3000</li>
|
||||
<li>lisi</li>
|
||||
<li>Junglist</li>
|
||||
<li>Crimson Scythe</li>
|
||||
<li>Sk8erpunk69</li>
|
||||
<li>lghtning</li>
|
||||
<li>kushet</li>
|
||||
<li>SilDeath</li>
|
||||
<li>lowrider4life</li>
|
||||
<li>dubiin</li>
|
||||
<li>Sam Wise The Great</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
Apologies and lots of happy naked love to anyone I forgot. <br><br>
|
||||
And of course, thanks to <b>you</b> for playing my game! <br><br>
|
||||
<a href="/index.php?do=ninja">NINJA!</a> <br><br>
|
||||
[ <a href="#top">Top</a> ]
|
||||
|
||||
<hr>
|
||||
|
||||
Please visit the following sites for more information:<br>
|
||||
<a href="http://www.se7enet.com" target="_new">Se7enet</a> (Jamin's homepage)<br>
|
||||
<a href="http://dragon.se7enet.com/dev.php" target="_new">Dragon Knight</a> (official DK homepage)<br>
|
||||
<a href="http://se7enet.com/forums" target="_new">Forums</a> (official DK forums)<br><br>
|
||||
All original coding and graphics for the <i>Dragon Knight</i> game engine are © 2003-2005 by Jamin Seven.<br><br>
|
||||
[ <a href="#top">Top</a> ]
|
||||
{/block}
|
Loading…
x
Reference in New Issue
Block a user