diff options
Diffstat (limited to 'internal/game')
| -rw-r--r-- | internal/game/action_agility.go | 4 | ||||
| -rw-r--r-- | internal/game/action_finishing_blow.go | 2 | ||||
| -rw-r--r-- | internal/game/cmd_attack.go | 47 | ||||
| -rw-r--r-- | internal/game/cmd_color.go | 10 | ||||
| -rw-r--r-- | internal/game/cmd_look.go | 14 | ||||
| -rw-r--r-- | internal/game/cmd_score.go | 2 | ||||
| -rw-r--r-- | internal/game/cmd_trigger_combat.go | 12 | ||||
| -rw-r--r-- | internal/game/core_production.go | 2 | ||||
| -rw-r--r-- | internal/game/sys_combat.go | 2 | ||||
| -rw-r--r-- | internal/game/tick.go | 8 | ||||
| -rw-r--r-- | internal/game/ui_combat.go | 59 | ||||
| -rw-r--r-- | internal/game/ui_help.go | 2 |
12 files changed, 116 insertions, 48 deletions
diff --git a/internal/game/action_agility.go b/internal/game/action_agility.go index 43c9cfd..f916a8d 100644 --- a/internal/game/action_agility.go +++ b/internal/game/action_agility.go @@ -140,13 +140,13 @@ func (g *Game) obstacleFail(sess *net.Session, p *player.Player, data map[string damage = failMin + rand.Intn(failMax-failMin+1) } - sess.WriteLine(g.colorize(sess, "damage", "You slip and fall!")) + sess.WriteLine(g.colorize(sess, "damage_taken", "You slip and fall!")) p.HP -= damage if p.HP < 1 { p.HP = 1 } - sess.WriteLine(g.colorize(sess, "damage", + sess.WriteLine(g.colorize(sess, "damage_taken", fmt.Sprintf("You take %d damage. HP: %d/%d", damage, p.HP, p.MaxHP()))) g.AccountStore.SaveCharacter(p) diff --git a/internal/game/action_finishing_blow.go b/internal/game/action_finishing_blow.go index 674c2ef..070559d 100644 --- a/internal/game/action_finishing_blow.go +++ b/internal/game/action_finishing_blow.go @@ -72,7 +72,7 @@ func (g *Game) doFinishingBlow(sess *net.Session, p *player.Player, mob *world.M if consumed { p.RemoveItem(mob.FinishingBlow, 1) } - sess.WriteLine(fmt.Sprintf("\nYou use the %s on %s!", g.itemColorize(sess, fbDef, fbDef.Name), g.colorize(sess, "mob_name", mobDisplayName(mob, true)))) + sess.WriteLine(fmt.Sprintf("\nYou use the %s on %s!", g.itemColorize(sess, fbDef, fbDef.Name), g.colorize(sess, "mob", mobDisplayName(mob, true)))) mob.HP = 0 g.endCombat(sess, p, mob) } diff --git a/internal/game/cmd_attack.go b/internal/game/cmd_attack.go index 89cde46..1ede21f 100644 --- a/internal/game/cmd_attack.go +++ b/internal/game/cmd_attack.go @@ -7,6 +7,7 @@ import ( "strings" "thehouseoficarus/internal/action" + "thehouseoficarus/internal/color" "thehouseoficarus/internal/combat" "thehouseoficarus/internal/engine" "thehouseoficarus/internal/net" @@ -149,7 +150,7 @@ func (g *Game) startCombat(sess *net.Session, p *player.Player, mob *world.MobIn if len(styleParts) > 0 { styleStr = " Style: " + string(p.AttackStyle) + " (" + strings.Join(styleParts, ", ") + ")" } - sess.WriteLine(fmt.Sprintf("\nYou attack %s!%s", g.colorize(sess, "mob_name", mobDisplayName(mob, true)), styleStr)) + sess.WriteLine(fmt.Sprintf("\nYou attack %s!%s", g.colorize(sess, "mob", mobDisplayName(mob, true)), styleStr)) } else { mod := GetMod(p.AutotriggerMod) modName := p.AutotriggerMod @@ -157,7 +158,7 @@ func (g *Game) startCombat(sess *net.Session, p *player.Player, mob *world.MobIn modName = mod.Name } sess.WriteLine(fmt.Sprintf("\nYou attack %s with %s!", - g.colorize(sess, "mob_name", mobDisplayName(mob, true)), + g.colorize(sess, "mob", mobDisplayName(mob, true)), g.colorize(sess, "science_mod", modName))) } p.ActionState = &ActionState{Type: ActionCombating, TargetName: mob.Name} @@ -352,7 +353,7 @@ func (g *Game) applyPlayerHit(sess *net.Session, p *player.Player, mob *world.Mo fbName = fbDef.Name } sess.WriteLine(g.colorize(sess, "warning", - fmt.Sprintf(" %s resists death! Use %s on it to finish it off.", + fmt.Sprintf("%s resists death! Use %s on it to finish it off.", mobDisplayName(mob, false), fbName))) } @@ -373,13 +374,17 @@ func (g *Game) applyPlayerHit(sess *net.Session, p *player.Player, mob *world.Mo if !mob.Unique { attacker = "The " + mob.Name } - w := len(fmt.Sprintf(" You hit %s for %d damage.", mobName, dmg)) - if w2 := len(fmt.Sprintf(" %s hits you for %d damage.", attacker, dmg)); w2 > w { + w := len(fmt.Sprintf("You hit %s for %d damage.", mobName, 999)) + if w2 := len(fmt.Sprintf("%s hits you for %d damage.", attacker, 999)); w2 > w { w = w2 } - prefix := fmt.Sprintf(" You hit %s for %s damage.", g.colorize(sess, "mob_name", mobName), g.colorize(sess, "damage", fmt.Sprint(dmg))) - hpPart := fmt.Sprintf("[%s/%dhp]", g.colorize(sess, "enemy_hp", fmt.Sprint(mob.HP)), mob.MaxHP) - line := fmt.Sprintf("%-*s %s", w, prefix, hpPart) + prefix := fmt.Sprintf("You hit %s for %s damage.", g.colorize(sess, "mob", mobName), g.colorize(sess, "damage_dealt", fmt.Sprint(dmg))) + visLen := color.VisibleLen(prefix) + if visLen < w { + prefix += strings.Repeat(" ", w-visLen+1) + } + hpSuffix := fmt.Sprintf("%s [%2d/%d]", g.hpBar(sess, mob.HP, mob.MaxHP), mob.HP, mob.MaxHP) + line := prefix + hpSuffix if p.OptionBool("xp_drops") && len(gains) > 0 { var parts []string for _, gain := range gains { @@ -396,7 +401,7 @@ func (g *Game) applyPlayerHit(sess *net.Session, p *player.Player, mob *world.Mo } func (g *Game) applyPlayerMiss(sess *net.Session, p *player.Player, mob *world.MobInstance, weaponType object.WeaponType) { - sess.WriteLine(g.colorize(sess, "miss", fmt.Sprintf(" You miss %s.", mobDisplayName(mob, true)))) + sess.WriteLine(g.colorize(sess, "miss", fmt.Sprintf("You miss %s.", mobDisplayName(mob, true)))) if weaponType == object.WeaponRanged { p.AmmoQty-- @@ -487,13 +492,17 @@ func (g *Game) applyMobHit(sess *net.Session, p *player.Player, mob *world.MobIn attacker = "The " + mob.Name } mobName := mobDisplayName(mob, true) - w := len(fmt.Sprintf(" %s hits you for %d damage.", attacker, dmg)) - if w2 := len(fmt.Sprintf(" You hit %s for %d damage.", mobName, dmg)); w2 > w { + w := len(fmt.Sprintf("%s hits you for %d damage.", attacker, 999)) + if w2 := len(fmt.Sprintf("You hit %s for %d damage.", mobName, 999)); w2 > w { w = w2 } - prefix := fmt.Sprintf(" %s hits you for %s damage.", g.colorize(sess, "mob_name", attacker), g.colorize(sess, "damage", fmt.Sprint(dmg))) - hpPart := fmt.Sprintf("[%s/%dhp]", g.colorize(sess, "character_hp", fmt.Sprint(p.HP)), p.MaxHP()) - sess.WriteLine(fmt.Sprintf("%-*s %s", w, prefix, hpPart)) + prefix := fmt.Sprintf("%s hits you for %s damage.", g.colorize(sess, "mob", attacker), g.colorize(sess, "damage_taken", fmt.Sprint(dmg))) + visLen := color.VisibleLen(prefix) + if visLen < w { + prefix += strings.Repeat(" ", w-visLen+1) + } + hpSuffix := fmt.Sprintf("%s [%2d/%d]", g.hpBar(sess, p.HP, p.MaxHP()), p.HP, p.MaxHP()) + sess.WriteLine(prefix + hpSuffix) if p.MoveTicks > 0 { p.ClearMoveState() @@ -507,7 +516,7 @@ func (g *Game) applyMobMiss(sess *net.Session, mob *world.MobInstance) { if !mob.Unique { attacker = "The " + mob.Name } - sess.WriteLine(g.colorize(sess, "miss", fmt.Sprintf(" %s misses you.", attacker))) + sess.WriteLine(g.colorize(sess, "miss", fmt.Sprintf("%s misses you.", attacker))) } func (g *Game) endCombat(sess *net.Session, p *player.Player, mob *world.MobInstance) { @@ -572,7 +581,7 @@ func (g *Game) endCombat(sess *net.Session, p *player.Player, mob *world.MobInst dropper = "The " + mob.Name } coloredName := g.itemColorize(sess, def, name) - sess.WriteLine(fmt.Sprintf(" %s %s", g.colorize(sess, "drop_message", dropper+" drops:"), coloredName)) + sess.WriteLine(fmt.Sprintf("%s %s", g.colorize(sess, "drop_message", dropper+" drops:"), coloredName)) } if len(mob.Drops.Loot) > 0 { @@ -594,9 +603,9 @@ func (g *Game) endCombat(sess *net.Session, p *player.Player, mob *world.MobInst } coloredName := g.itemColorize(sess, def, name) if qty > 1 { - sess.WriteLine(fmt.Sprintf(" %s %d x %s", g.colorize(sess, "drop_message", dropper+" drops:"), qty, coloredName)) + sess.WriteLine(fmt.Sprintf("%s %d x %s", g.colorize(sess, "drop_message", dropper+" drops:"), qty, coloredName)) } else { - sess.WriteLine(fmt.Sprintf(" %s %s", g.colorize(sess, "drop_message", dropper+" drops:"), coloredName)) + sess.WriteLine(fmt.Sprintf("%s %s", g.colorize(sess, "drop_message", dropper+" drops:"), coloredName)) } } } @@ -684,7 +693,7 @@ func (g *Game) respawnMob(instanceID string) { if p := sess.Player; p != nil && p.OptionBool("mob_spawn") { mobLvl := mobCombatLevel(inst) levelStr := g.levelColorize(sess, p.CombatLevel(), mobLvl, fmt.Sprintf("(level %d)", mobLvl)) - sess.WriteLine(fmt.Sprintf("\n%s %s spawns in the area.", g.colorize(sess, "mob_name", mobDisplayName(inst, false)), levelStr)) + sess.WriteLine(fmt.Sprintf("\n%s %s spawns in the area.", g.colorize(sess, "mob", mobDisplayName(inst, false)), levelStr)) } } } diff --git a/internal/game/cmd_color.go b/internal/game/cmd_color.go index 257c965..fe2fe62 100644 --- a/internal/game/cmd_color.go +++ b/internal/game/cmd_color.go @@ -139,12 +139,12 @@ var colorCategoryOrder = []string{ "direction", "exit_direction", "exit_name", - "mob_name", - "friendly_npc", - "hostile_npc", + "protected_mob", + "mob", + "damage_dealt", + "damage_taken", "damage", - "enemy_hp", - "character_hp", + "xp", "level_up", "item", diff --git a/internal/game/cmd_look.go b/internal/game/cmd_look.go index 505f7a6..936a6b0 100644 --- a/internal/game/cmd_look.go +++ b/internal/game/cmd_look.go @@ -81,7 +81,7 @@ func (g *Game) showRoomMobs(sess *net.Session, p *player.Player, room *world.Roo for _, m := range mobs { hp := "" if m.HP < m.MaxHP { - hp = fmt.Sprintf(" [%s/%dhp]", g.colorize(sess, "enemy_hp", fmt.Sprint(m.HP)), m.MaxHP) + hp = fmt.Sprintf(" [%s/%dhp]", color.Render(g.colorMode(sess), color.Parse("167"), fmt.Sprint(m.HP)), m.MaxHP) } var desc string if combat.IsMobInCombat(m.InstanceID) { @@ -98,13 +98,13 @@ func (g *Game) showRoomMobs(sess *net.Session, p *player.Player, room *world.Roo if !m.Unique { displayName = "A " + m.Name } - npcColor := "hostile_npc" + mobColor := "mob" if m.Protected { - npcColor = "friendly_npc" + mobColor = "protected_mob" } mobLevel := mobCombatLevel(m) levelStr := g.levelColorize(sess, playerLevel, mobLevel, fmt.Sprintf("(level %d)", mobLevel)) - sess.WriteLine(fmt.Sprintf(" %s %s%s%s", g.colorize(sess, npcColor, displayName), levelStr, hp, desc)) + sess.WriteLine(fmt.Sprintf(" %s %s%s%s", g.colorize(sess, mobColor, displayName), levelStr, hp, desc)) } } } @@ -466,15 +466,15 @@ func (g *Game) doLookTarget(sess *net.Session, input string) { } } if best != nil { - npcColor := "hostile_npc" + mobColor := "mob" if best.Protected { - npcColor = "friendly_npc" + mobColor = "protected_mob" } mobLevel := mobCombatLevel(best) levelStr := g.levelColorize(sess, p.CombatLevel(), mobLevel, fmt.Sprintf("(level %d)", mobLevel)) sess.WriteLines( "", - fmt.Sprintf("%s %s", g.colorize(sess, npcColor, best.Name), levelStr), + fmt.Sprintf("%s %s", g.colorize(sess, mobColor, best.Name), levelStr), ) if best.IdleDescription != "" { sess.WriteLine(fmt.Sprintf(" %s", best.IdleDescription)) diff --git a/internal/game/cmd_score.go b/internal/game/cmd_score.go index b49fd7f..523dcb9 100644 --- a/internal/game/cmd_score.go +++ b/internal/game/cmd_score.go @@ -20,7 +20,7 @@ func (g *Game) doScore(sess *net.Session) { "", fmt.Sprintf("Name: %s", g.colorize(sess, "player_name", p.Name)), fmt.Sprintf("Combat Level: %s", color.Render(mode, color.Parse("230"), fmt.Sprint(p.CombatLevel()))), - fmt.Sprintf("HP: %s/%s", g.colorize(sess, "character_hp", fmt.Sprint(p.HP)), color.Render(mode, color.Parse("230"), fmt.Sprint(p.MaxHP()))), + fmt.Sprintf("HP: %s/%s", color.Render(mode, color.Parse("84"), fmt.Sprint(p.HP)), color.Render(mode, color.Parse("230"), fmt.Sprint(p.MaxHP()))), fmt.Sprintf("Battery: %s/%s", g.colorize(sess, "battery", fmt.Sprintf("%.1f", p.Battery)), color.Render(mode, color.Parse("230"), fmt.Sprintf("%.0f", p.MaxBattery()))), fmt.Sprintf("Credits: %s", g.colorize(sess, "credits_pickup", fmt.Sprint(p.Credits))), ) diff --git a/internal/game/cmd_trigger_combat.go b/internal/game/cmd_trigger_combat.go index 444f80d..2086235 100644 --- a/internal/game/cmd_trigger_combat.go +++ b/internal/game/cmd_trigger_combat.go @@ -62,12 +62,12 @@ func (g *Game) scienceAttack(sess *net.Session, p *player.Player, mob *world.Mob g.AccountStore.SaveCharacter(p) mobName := mobDisplayName(mob, true) - prefix := fmt.Sprintf(" %s hits %s for %s damage.", + prefix := fmt.Sprintf("%s hits %s for %s damage.", g.colorize(sess, "science_mod", mod.Name), - g.colorize(sess, "mob_name", mobName), - g.colorize(sess, "damage", fmt.Sprint(dmg))) - hpPart := fmt.Sprintf("[%s/%dhp]", g.colorize(sess, "enemy_hp", fmt.Sprint(mob.HP)), mob.MaxHP) - line := prefix + " " + hpPart + g.colorize(sess, "mob", mobName), + g.colorize(sess, "damage_dealt", fmt.Sprint(dmg))) + hpSuffix := fmt.Sprintf("%s [%2d/%d]", g.hpBar(sess, mob.HP, mob.MaxHP), mob.HP, mob.MaxHP) + line := prefix + " " + hpSuffix if p.OptionBool("xp_drops") && len(gains) > 0 { var parts []string for _, gain := range gains { @@ -77,7 +77,7 @@ func (g *Game) scienceAttack(sess *net.Session, p *player.Player, mob *world.Mob } sess.WriteLine(line) } else { - sess.WriteLine(g.colorize(sess, "miss", fmt.Sprintf(" %s fails to connect.", mod.Name))) + sess.WriteLine(g.colorize(sess, "miss", fmt.Sprintf("%s fails to connect.", mod.Name))) } return true } diff --git a/internal/game/core_production.go b/internal/game/core_production.go index 47a164c..b4101a9 100644 --- a/internal/game/core_production.go +++ b/internal/game/core_production.go @@ -286,7 +286,7 @@ func (g *Game) advanceProduction(sess *net.Session, p *player.Player) bool { msg := g.resolveCraftMessage(sess, craft.FailMessage, info.FailMessage, craft, item.ID, nil, p.HasItem) if msg != "" { - sess.WriteLine(g.colorize(sess, "damage", msg)) + sess.WriteLine(g.colorize(sess, "damage_taken", msg)) } } diff --git a/internal/game/sys_combat.go b/internal/game/sys_combat.go index 702871c..81b2c83 100644 --- a/internal/game/sys_combat.go +++ b/internal/game/sys_combat.go @@ -105,7 +105,7 @@ func (g *Game) checkAggro(sess *net.Session) { if !aggMob.Unique { attacker = "The " + aggMob.Name } - sess.WriteLine(fmt.Sprintf("\n%s attacks you!", g.colorize(sess, "mob_name", attacker))) + sess.WriteLine(fmt.Sprintf("\n%s attacks you!", g.colorize(sess, "mob", attacker))) g.startCombat(sess, p, aggMob) return false }) diff --git a/internal/game/tick.go b/internal/game/tick.go index ec7eda9..1402b06 100644 --- a/internal/game/tick.go +++ b/internal/game/tick.go @@ -142,17 +142,17 @@ func (g *Game) WanderTick() { if p.RoomID == m.fromRoom && p.OptionBool("mob_leave") { if m.level > 0 { levelStr := g.levelColorize(sess, p.CombatLevel(), m.level, fmt.Sprintf("(level %d)", m.level)) - sess.WriteLine(fmt.Sprintf("\n%s %s leaves.", g.colorize(sess, "mob_name", m.name), levelStr)) + sess.WriteLine(fmt.Sprintf("\n%s %s leaves.", g.colorize(sess, "mob", m.name), levelStr)) } else { - sess.WriteLine(fmt.Sprintf("\n%s moves away.", g.colorize(sess, "mob_name", m.name))) + sess.WriteLine(fmt.Sprintf("\n%s moves away.", g.colorize(sess, "mob", m.name))) } } if p.RoomID == m.toRoom && p.OptionBool("mob_enter") { if m.level > 0 { levelStr := g.levelColorize(sess, p.CombatLevel(), m.level, fmt.Sprintf("(level %d)", m.level)) - sess.WriteLine(fmt.Sprintf("\n%s %s enters.", g.colorize(sess, "mob_name", m.name), levelStr)) + sess.WriteLine(fmt.Sprintf("\n%s %s enters.", g.colorize(sess, "mob", m.name), levelStr)) } else { - sess.WriteLine(fmt.Sprintf("\n%s drifts in.", g.colorize(sess, "mob_name", m.name))) + sess.WriteLine(fmt.Sprintf("\n%s drifts in.", g.colorize(sess, "mob", m.name))) } } } diff --git a/internal/game/ui_combat.go b/internal/game/ui_combat.go new file mode 100644 index 0000000..56de7e8 --- /dev/null +++ b/internal/game/ui_combat.go @@ -0,0 +1,59 @@ +package game + +import ( + "math" + "strings" + + "thehouseoficarus/internal/color" + "thehouseoficarus/internal/net" +) + +func (g *Game) hpBar(sess *net.Session, current, max int) string { + if max <= 0 { + max = 1 + } + if current < 0 { + current = 0 + } + if current > max { + current = max + } + + pct := float64(current) / float64(max) * 100.0 + filled := int(math.Round(pct / 10.0)) + if filled < 0 { + filled = 0 + } + if filled > 10 { + filled = 10 + } + + mode := g.colorMode(sess) + + var fgColor int + switch { + case pct >= 70: + fgColor = 82 + case pct >= 40: + fgColor = 220 + default: + fgColor = 160 + } + + fillSpec := color.ColorSpec{Fg: fgColor} + emptySpec := color.ColorSpec{Fg: 238, Dim: true} + + fillChar := "█" + emptyChar := "░" + if sess.Player != nil && !sess.Player.OptionBool("unicode") { + fillChar = "#" + emptyChar = "." + } + + var sb strings.Builder + sb.WriteString("[") + sb.WriteString(color.Render(mode, fillSpec, strings.Repeat(fillChar, filled))) + sb.WriteString(color.Render(mode, emptySpec, strings.Repeat(emptyChar, 10-filled))) + sb.WriteString("]") + return sb.String() +} diff --git a/internal/game/ui_help.go b/internal/game/ui_help.go index 151d1ba..ee8ad97 100644 --- a/internal/game/ui_help.go +++ b/internal/game/ui_help.go @@ -70,7 +70,7 @@ var commandList = []cmdEntry{ {"steal", "Active", "Steal from mobs (Thieving)"}, {"stoke", "Active", "Add logs to a fire"}, {"style", "Instant", "Change combat style"}, - {"talk / speak / ask", "Active", "Talk to NPCs"}, + {"talk / speak / ask", "Active", "Talk to mobs"}, {"tech", "Instant", "Toggle technology abilities"}, {"trigger", "Active", "Trigger a science module"}, {"unalias", "Instant", "Remove command shortcuts"}, |
