aboutsummaryrefslogtreecommitdiff
path: root/internal/game/sys_technology.go
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-06-24 22:55:35 -0400
committerhistoria <[not public]>2026-06-24 22:55:35 -0400
commit15b7e221b799ef107dec44ecdb294026dfd3d059 (patch)
tree3748e464a77f0f082bea1567e9d6990052054961 /internal/game/sys_technology.go
parent9d4b799db4868bcab291b83599ff088763cd4ed6 (diff)
downloadthehouseoficarus-15b7e221b799ef107dec44ecdb294026dfd3d059.tar.gz
refactor: pulled techs out to yaml files, unified numerous combat functions, broke up game object
Diffstat (limited to 'internal/game/sys_technology.go')
-rw-r--r--internal/game/sys_technology.go116
1 files changed, 53 insertions, 63 deletions
diff --git a/internal/game/sys_technology.go b/internal/game/sys_technology.go
index e673dcb..6afc757 100644
--- a/internal/game/sys_technology.go
+++ b/internal/game/sys_technology.go
@@ -2,80 +2,62 @@ package game
import (
"fmt"
+ "path/filepath"
"strings"
+ "gopkg.in/yaml.v3"
+
+ "thehouseoficarus/internal/action"
"thehouseoficarus/internal/net"
"thehouseoficarus/internal/player"
"thehouseoficarus/internal/world"
)
type TechEffects struct {
- AccuracyPercent int
- StrengthPercent int
- DefensePercent int
- RangedPercent int
- SciencePercent int
- ProtectMelee bool
- ProtectRanged bool
- ProtectScience bool
- DamageReduction float64
- HPRegenMulti float64
- PreserveDrain float64
- RetributionPct float64
+ AccuracyPercent int `yaml:"accuracy_percent"`
+ StrengthPercent int `yaml:"strength_percent"`
+ DefensePercent int `yaml:"defense_percent"`
+ RangedPercent int `yaml:"ranged_percent"`
+ SciencePercent int `yaml:"science_percent"`
+ ProtectMelee bool `yaml:"protect_melee"`
+ ProtectRanged bool `yaml:"protect_ranged"`
+ ProtectScience bool `yaml:"protect_science"`
+ DamageReduction float64 `yaml:"damage_reduction"`
+ HPRegenMulti float64 `yaml:"hp_regen_multi"`
+ PreserveDrain float64 `yaml:"preserve_drain"`
+ RetributionPct float64 `yaml:"retribution_pct"`
}
type TechDef struct {
- ID string
- Name string
- Level int
- DrainRate float64
- Category string
- Group string
- Effects TechEffects
+ ID string `yaml:"id"`
+ Name string `yaml:"name"`
+ Level int `yaml:"level"`
+ DrainRate float64 `yaml:"drain_rate"`
+ Category string `yaml:"category"`
+ Group string `yaml:"group"`
+ Effects TechEffects `yaml:"effects"`
}
-var AllTechs []TechDef
+var AllTechs []*TechDef
var techByID map[string]*TechDef
-func init() {
- AllTechs = []TechDef{
- {ID: "clarity_1", Name: "Clarity", Level: 4, DrainRate: 0.05, Category: "accuracy", Group: "accuracy_tier", Effects: TechEffects{AccuracyPercent: 5}},
- {ID: "clarity_2", Name: "Enhanced Clarity", Level: 16, DrainRate: 0.10, Category: "accuracy", Group: "accuracy_tier", Effects: TechEffects{AccuracyPercent: 10}},
- {ID: "clarity_3", Name: "Superior Clarity", Level: 44, DrainRate: 0.15, Category: "accuracy", Group: "accuracy_tier", Effects: TechEffects{AccuracyPercent: 15}},
-
- {ID: "amplifier_1", Name: "Power Amplifier", Level: 7, DrainRate: 0.05, Category: "strength", Group: "strength_tier", Effects: TechEffects{StrengthPercent: 5}},
- {ID: "amplifier_2", Name: "Enhanced Amplifier", Level: 23, DrainRate: 0.10, Category: "strength", Group: "strength_tier", Effects: TechEffects{StrengthPercent: 10}},
- {ID: "amplifier_3", Name: "Superior Amplifier", Level: 49, DrainRate: 0.15, Category: "strength", Group: "strength_tier", Effects: TechEffects{StrengthPercent: 15}},
-
- {ID: "shield_1", Name: "Energy Shield", Level: 10, DrainRate: 0.05, Category: "defense", Group: "defense_tier", Effects: TechEffects{DefensePercent: 5}},
- {ID: "shield_2", Name: "Enhanced Shield", Level: 28, DrainRate: 0.10, Category: "defense", Group: "defense_tier", Effects: TechEffects{DefensePercent: 10}},
- {ID: "shield_3", Name: "Superior Shield", Level: 52, DrainRate: 0.15, Category: "defense", Group: "defense_tier", Effects: TechEffects{DefensePercent: 15}},
-
- {ID: "targeting_1", Name: "Targeting System", Level: 8, DrainRate: 0.05, Category: "ranged", Group: "ranged_tier", Effects: TechEffects{RangedPercent: 5}},
- {ID: "targeting_2", Name: "Enhanced Targeting", Level: 22, DrainRate: 0.10, Category: "ranged", Group: "ranged_tier", Effects: TechEffects{RangedPercent: 10}},
- {ID: "targeting_3", Name: "Superior Targeting", Level: 46, DrainRate: 0.15, Category: "ranged", Group: "ranged_tier", Effects: TechEffects{RangedPercent: 15}},
-
- {ID: "focus_1", Name: "Neural Focus", Level: 9, DrainRate: 0.05, Category: "science", Group: "science_tier", Effects: TechEffects{SciencePercent: 5}},
- {ID: "focus_2", Name: "Enhanced Focus", Level: 27, DrainRate: 0.10, Category: "science", Group: "science_tier", Effects: TechEffects{SciencePercent: 10}},
- {ID: "focus_3", Name: "Superior Focus", Level: 55, DrainRate: 0.15, Category: "science", Group: "science_tier", Effects: TechEffects{SciencePercent: 15}},
-
- {ID: "protect_melee", Name: "Kinetic Barrier", Level: 37, DrainRate: 0.20, Category: "protection", Group: "protection", Effects: TechEffects{ProtectMelee: true, DamageReduction: 0.4}},
- {ID: "protect_ranged", Name: "Projectile Screen", Level: 40, DrainRate: 0.20, Category: "protection", Group: "protection", Effects: TechEffects{ProtectRanged: true, DamageReduction: 0.4}},
- {ID: "protect_science", Name: "Neural Firewall", Level: 43, DrainRate: 0.20, Category: "protection", Group: "protection", Effects: TechEffects{ProtectScience: true, DamageReduction: 0.4}},
-
- {ID: "regen", Name: "Nano Repair", Level: 22, DrainRate: 0.10, Category: "utility", Group: "regen_tier", Effects: TechEffects{HPRegenMulti: 2.0}},
- {ID: "rapid_heal", Name: "Rapid Repair", Level: 31, DrainRate: 0.15, Category: "utility", Group: "regen_tier", Effects: TechEffects{HPRegenMulti: 4.0}},
- {ID: "preserve", Name: "Power Saver", Level: 55, DrainRate: 0.05, Category: "utility", Group: "", Effects: TechEffects{PreserveDrain: 0.2}},
- {ID: "retribution", Name: "Dead Man's Switch", Level: 46, DrainRate: 0.10, Category: "utility", Group: "", Effects: TechEffects{RetributionPct: 0.25}},
-
- {ID: "overclock", Name: "Overclock", Level: 60, DrainRate: 0.25, Category: "combo", Group: "accuracy_tier", Effects: TechEffects{AccuracyPercent: 15, StrengthPercent: 15}},
- {ID: "fortify", Name: "Fortify", Level: 65, DrainRate: 0.25, Category: "combo", Group: "defense_tier", Effects: TechEffects{DefensePercent: 15, HPRegenMulti: 2.0}},
- }
-
+func (g *Game) LoadTechs() error {
+ dir := filepath.Join(g.DataDir, "techs")
+ AllTechs = nil
+ techByID = make(map[string]*TechDef)
+ action.WalkYAMLDir(dir, func(path, id string, data []byte) error {
+ var t TechDef
+ if err := yaml.Unmarshal(data, &t); err != nil {
+ return nil
+ }
+ AllTechs = append(AllTechs, &t)
+ return nil
+ })
techByID = make(map[string]*TechDef, len(AllTechs))
- for i := range AllTechs {
- techByID[AllTechs[i].ID] = &AllTechs[i]
+ for _, t := range AllTechs {
+ techByID[t.ID] = t
}
+ return nil
}
func GetTechDef(id string) *TechDef {
@@ -86,13 +68,13 @@ func TechByPrefixMatch(input string) []*TechDef {
input = strings.ToLower(input)
var exact []*TechDef
var prefix []*TechDef
- for i := range AllTechs {
- lower := strings.ToLower(AllTechs[i].Name)
- lowerID := strings.ToLower(AllTechs[i].ID)
+ for _, t := range AllTechs {
+ lower := strings.ToLower(t.Name)
+ lowerID := strings.ToLower(t.ID)
if lower == input || lowerID == input {
- exact = append(exact, &AllTechs[i])
+ exact = append(exact, t)
} else if strings.HasPrefix(lower, input) || strings.HasPrefix(lowerID, input) {
- prefix = append(prefix, &AllTechs[i])
+ prefix = append(prefix, t)
}
}
if len(exact) > 0 {
@@ -101,7 +83,7 @@ func TechByPrefixMatch(input string) []*TechDef {
return prefix
}
-func techEffectString(tech TechDef) string {
+func techEffectString(tech *TechDef) string {
var parts []string
e := tech.Effects
if e.AccuracyPercent > 0 {
@@ -223,6 +205,14 @@ func (g *Game) applyTechProtection(p *player.Player, mob *world.MobInstance, dmg
// damageAfterTechProtection reduces incoming damage if the player has the
// protection tech matching the given attack type active. Shared by mob combat
// and room hazards.
+//
+// Reserved tech IDs (must exist in data/techs/):
+//
+// protect_melee — mapped to stab/slash/crush attacks
+// protect_ranged — mapped to ranged attacks
+// protect_science — mapped to science attacks
+//
+// Also retribution — checked by name in killPlayer (cmd_attack.go).
func (g *Game) damageAfterTechProtection(p *player.Player, attackType string, dmg int) int {
if len(p.ActiveTechs) == 0 {
return dmg