package game import ( "fmt" "sort" "strings" "thehouseoficarus/internal/object" "thehouseoficarus/internal/player" ) type ModCategory string const ( ModCombat ModCategory = "combat" ModUtility ModCategory = "utility" ModEnchant ModCategory = "enchant" ModProcessing ModCategory = "processing" ModTransport ModCategory = "transport" ) type ModDef struct { ID string Name string Level int MaxHit int BaseXP float64 JunkCost map[string]int Category ModCategory Element string TargetType string Destination int } var AllMods []*ModDef var modByID map[string]*ModDef func GetMod(id string) *ModDef { return modByID[id] } func FindMod(input string) *ModDef { if m, ok := modByID[input]; ok { return m } lower := strings.ToLower(strings.ReplaceAll(input, " ", "_")) for _, m := range AllMods { if strings.HasPrefix(m.ID, lower) { return m } } lowerSpace := strings.ToLower(input) for _, m := range AllMods { if strings.HasPrefix(strings.ToLower(m.Name), lowerSpace) { return m } } return nil } type chipEntry struct { Input string Output string Qty int } var enchantMap = map[string]map[string]string{ "enchant_1": { "sapphire_ring": "ring_of_recoil", "sapphire_necklace": "necklace_of_passage", "sapphire_bracelet": "bracelet_of_clay", }, "enchant_2": { "emerald_ring": "ring_of_dueling", "emerald_necklace": "binding_necklace", "emerald_bracelet": "bracelet_of_slaughter", }, "enchant_3": { "ruby_ring": "ring_of_forging", "ruby_necklace": "digsite_pendant", "ruby_bracelet": "inoculation_bracelet", }, "enchant_4": { "diamond_ring": "ring_of_life", "diamond_necklace": "phoenix_necklace", "diamond_bracelet": "abyssal_bracelet", }, } var chipMap = map[string]chipEntry{ "chip_sapphire": {"sapphire_bolts", "sapphire_bolts_e", 10}, "chip_emerald": {"emerald_bolts", "emerald_bolts_e", 10}, "chip_ruby": {"ruby_bolts", "ruby_bolts_e", 10}, "chip_diamond": {"diamond_bolts", "diamond_bolts_e", 10}, } func (g *Game) hasDeckEquipped(p *player.Player) bool { itemID, ok := p.Equipment[object.SlotMainHand] if !ok { return false } def, err := g.ItemStore.Load(itemID) if err != nil { return false } return def.WeaponType == object.WeaponScience } func (g *Game) equippedProvidesJunk(p *player.Player) string { itemID, ok := p.Equipment[object.SlotMainHand] if !ok { return "" } def, err := g.ItemStore.Load(itemID) if err != nil { return "" } return def.ProvidesJunk } func (g *Game) effectiveJunkCost(p *player.Player, mod *ModDef) map[string]int { cost := make(map[string]int) for k, v := range mod.JunkCost { cost[k] = v } hasDeck := g.hasDeckEquipped(p) if hasDeck { delete(cost, "scrap_metal") } providesJunk := g.equippedProvidesJunk(p) if providesJunk != "" { delete(cost, providesJunk) } return cost } func (g *Game) hasJunkCost(p *player.Player, mod *ModDef) bool { cost := g.effectiveJunkCost(p, mod) for itemID, qty := range cost { if p.CountItem(itemID) < qty { return false } } return true } func (g *Game) consumeJunkCost(p *player.Player, mod *ModDef) bool { cost := g.effectiveJunkCost(p, mod) for itemID, qty := range cost { if !p.RemoveItem(itemID, qty) { return false } } g.AccountStore.SaveCharacter(p) return true } func (g *Game) junkCostString(p *player.Player, mod *ModDef) string { cost := g.effectiveJunkCost(p, mod) if len(cost) == 0 { return "free" } var parts []string for itemID, qty := range cost { def, _ := g.ItemStore.Load(itemID) name := itemID if def != nil { name = def.Name } if qty > 1 { parts = append(parts, fmt.Sprintf("%d %s", qty, name)) } else { parts = append(parts, name) } } sort.Strings(parts) return strings.Join(parts, ", ") } func (g *Game) totalEquipScienceAttack(p *player.Player) int { total := 0 for _, itemID := range p.Equipment { def, err := g.ItemStore.Load(itemID) if err == nil { total += def.Stats.ScienceAttack } } return total } func init() { AllMods = []*ModDef{ {ID: "bio_strike", Name: "Bio Strike", Level: 1, MaxHit: 4, BaseXP: 5.5, JunkCost: map[string]int{"biojunk": 2, "scrap_metal": 1}, Category: ModCombat, Element: "bio", TargetType: "mob"}, {ID: "bio_bolt", Name: "Bio Bolt", Level: 17, MaxHit: 9, BaseXP: 13.5, JunkCost: map[string]int{"biojunk": 2, "chaosjunk": 1, "scrap_metal": 1}, Category: ModCombat, Element: "bio", TargetType: "mob"}, {ID: "bio_blast", Name: "Bio Blast", Level: 41, MaxHit: 13, BaseXP: 25.5, JunkCost: map[string]int{"biojunk": 3, "chaosjunk": 1, "deathjunk": 1, "scrap_metal": 1}, Category: ModCombat, Element: "bio", TargetType: "mob"}, {ID: "bio_wave", Name: "Bio Wave", Level: 62, MaxHit: 17, BaseXP: 36.0, JunkCost: map[string]int{"biojunk": 5, "deathjunk": 1, "bloodjunk": 1, "scrap_metal": 1}, Category: ModCombat, Element: "bio", TargetType: "mob"}, {ID: "bio_surge", Name: "Bio Surge", Level: 81, MaxHit: 21, BaseXP: 44.0, JunkCost: map[string]int{"biojunk": 7, "bloodjunk": 1, "scrap_metal": 1}, Category: ModCombat, Element: "bio", TargetType: "mob"}, {ID: "hydro_strike", Name: "Hydro Strike", Level: 5, MaxHit: 6, BaseXP: 7.5, JunkCost: map[string]int{"hydrojunk": 3, "ecojunk": 1, "scrap_metal": 1}, Category: ModCombat, Element: "hydro", TargetType: "mob"}, {ID: "hydro_bolt", Name: "Hydro Bolt", Level: 23, MaxHit: 10, BaseXP: 16.5, JunkCost: map[string]int{"hydrojunk": 3, "ecojunk": 2, "scrap_metal": 1}, Category: ModCombat, Element: "hydro", TargetType: "mob"}, {ID: "hydro_blast", Name: "Hydro Blast", Level: 47, MaxHit: 14, BaseXP: 28.5, JunkCost: map[string]int{"hydrojunk": 5, "ecojunk": 3, "chaosjunk": 1, "scrap_metal": 1}, Category: ModCombat, Element: "hydro", TargetType: "mob"}, {ID: "hydro_wave", Name: "Hydro Wave", Level: 65, MaxHit: 18, BaseXP: 37.5, JunkCost: map[string]int{"hydrojunk": 7, "ecojunk": 5, "deathjunk": 1, "scrap_metal": 1}, Category: ModCombat, Element: "hydro", TargetType: "mob"}, {ID: "hydro_surge", Name: "Hydro Surge", Level: 85, MaxHit: 22, BaseXP: 46.0, JunkCost: map[string]int{"hydrojunk": 10, "ecojunk": 7, "bloodjunk": 1, "scrap_metal": 1}, Category: ModCombat, Element: "hydro", TargetType: "mob"}, {ID: "eco_strike", Name: "Eco Strike", Level: 9, MaxHit: 7, BaseXP: 9.5, JunkCost: map[string]int{"ecojunk": 2, "biojunk": 2, "scrap_metal": 1}, Category: ModCombat, Element: "eco", TargetType: "mob"}, {ID: "eco_bolt", Name: "Eco Bolt", Level: 29, MaxHit: 11, BaseXP: 19.5, JunkCost: map[string]int{"ecojunk": 3, "biojunk": 2, "scrap_metal": 1}, Category: ModCombat, Element: "eco", TargetType: "mob"}, {ID: "eco_blast", Name: "Eco Blast", Level: 53, MaxHit: 15, BaseXP: 31.5, JunkCost: map[string]int{"ecojunk": 4, "biojunk": 3, "chaosjunk": 1, "scrap_metal": 1}, Category: ModCombat, Element: "eco", TargetType: "mob"}, {ID: "eco_wave", Name: "Eco Wave", Level: 70, MaxHit: 19, BaseXP: 40.0, JunkCost: map[string]int{"ecojunk": 7, "biojunk": 5, "deathjunk": 1, "scrap_metal": 1}, Category: ModCombat, Element: "eco", TargetType: "mob"}, {ID: "eco_surge", Name: "Eco Surge", Level: 90, MaxHit: 23, BaseXP: 48.5, JunkCost: map[string]int{"ecojunk": 10, "biojunk": 7, "bloodjunk": 1, "scrap_metal": 1}, Category: ModCombat, Element: "eco", TargetType: "mob"}, {ID: "solar_strike", Name: "Solar Strike", Level: 13, MaxHit: 8, BaseXP: 11.5, JunkCost: map[string]int{"solarjunk": 3, "ecojunk": 2, "scrap_metal": 1}, Category: ModCombat, Element: "solar", TargetType: "mob"}, {ID: "solar_bolt", Name: "Solar Bolt", Level: 35, MaxHit: 12, BaseXP: 22.5, JunkCost: map[string]int{"solarjunk": 4, "ecojunk": 3, "scrap_metal": 1}, Category: ModCombat, Element: "solar", TargetType: "mob"}, {ID: "solar_blast", Name: "Solar Blast", Level: 59, MaxHit: 16, BaseXP: 34.5, JunkCost: map[string]int{"solarjunk": 5, "ecojunk": 4, "chaosjunk": 1, "scrap_metal": 1}, Category: ModCombat, Element: "solar", TargetType: "mob"}, {ID: "solar_wave", Name: "Solar Wave", Level: 75, MaxHit: 20, BaseXP: 42.5, JunkCost: map[string]int{"solarjunk": 7, "ecojunk": 5, "deathjunk": 1, "scrap_metal": 1}, Category: ModCombat, Element: "solar", TargetType: "mob"}, {ID: "solar_surge", Name: "Solar Surge", Level: 95, MaxHit: 24, BaseXP: 51.0, JunkCost: map[string]int{"solarjunk": 10, "ecojunk": 7, "bloodjunk": 1, "scrap_metal": 1}, Category: ModCombat, Element: "solar", TargetType: "mob"}, {ID: "low_process", Name: "Low Level Processing", Level: 21, MaxHit: 0, BaseXP: 31.0, JunkCost: map[string]int{"naturejunk": 3, "solarjunk": 1, "scrap_metal": 1}, Category: ModProcessing, Element: "", TargetType: "inventory"}, {ID: "high_process", Name: "High Level Processing", Level: 55, MaxHit: 0, BaseXP: 65.0, JunkCost: map[string]int{"naturejunk": 5, "solarjunk": 1, "scrap_metal": 1}, Category: ModProcessing, Element: "", TargetType: "inventory"}, {ID: "bones_to_nutrients", Name: "Bones to Nutrients", Level: 15, MaxHit: 0, BaseXP: 25.0, JunkCost: map[string]int{"naturejunk": 2, "ecojunk": 2, "scrap_metal": 1}, Category: ModUtility, Element: "", TargetType: "self"}, {ID: "em_grab", Name: "Electromagnetic Grab", Level: 33, MaxHit: 0, BaseXP: 43.0, JunkCost: map[string]int{"lawjunk": 1, "biojunk": 1, "scrap_metal": 1}, Category: ModUtility, Element: "", TargetType: "ground_item"}, {ID: "superheat", Name: "Superheat Item", Level: 43, MaxHit: 0, BaseXP: 53.0, JunkCost: map[string]int{"naturejunk": 4, "solarjunk": 1, "scrap_metal": 1}, Category: ModUtility, Element: "", TargetType: "inventory"}, {ID: "plank_make", Name: "Plank Make", Level: 86, MaxHit: 0, BaseXP: 90.0, JunkCost: map[string]int{"naturejunk": 5, "solarjunk": 1, "scrap_metal": 1}, Category: ModUtility, Element: "", TargetType: "inventory"}, {ID: "transport_town", Name: "Transport: Town Square", Level: 25, MaxHit: 0, BaseXP: 27.0, JunkCost: map[string]int{"lawjunk": 1, "solarjunk": 1, "biojunk": 1, "scrap_metal": 1}, Category: ModTransport, Element: "", TargetType: "self", Destination: 1}, {ID: "transport_forge", Name: "Transport: Forge", Level: 31, MaxHit: 0, BaseXP: 35.0, JunkCost: map[string]int{"lawjunk": 1, "ecojunk": 1, "scrap_metal": 1}, Category: ModTransport, Element: "", TargetType: "self", Destination: 12}, {ID: "transport_mine", Name: "Transport: Mining Pit", Level: 37, MaxHit: 0, BaseXP: 40.0, JunkCost: map[string]int{"lawjunk": 1, "ecojunk": 1, "solarjunk": 1, "scrap_metal": 1}, Category: ModTransport, Element: "", TargetType: "self", Destination: 6}, {ID: "transport_forest", Name: "Transport: Forest", Level: 45, MaxHit: 0, BaseXP: 48.0, JunkCost: map[string]int{"lawjunk": 1, "ecojunk": 1, "biojunk": 1, "scrap_metal": 1}, Category: ModTransport, Element: "", TargetType: "self", Destination: 22}, {ID: "transport_scavenge", Name: "Transport: Scavenging Post", Level: 51, MaxHit: 0, BaseXP: 52.0, JunkCost: map[string]int{"lawjunk": 1, "naturejunk": 1, "scrap_metal": 1}, Category: ModTransport, Element: "", TargetType: "self", Destination: 9}, {ID: "transport_deep_mine", Name: "Transport: Deep Mine", Level: 61, MaxHit: 0, BaseXP: 60.0, JunkCost: map[string]int{"lawjunk": 2, "ecojunk": 1, "scrap_metal": 1}, Category: ModTransport, Element: "", TargetType: "self", Destination: 7}, {ID: "transport_fishing", Name: "Transport: Fishing Dock", Level: 55, MaxHit: 0, BaseXP: 56.0, JunkCost: map[string]int{"lawjunk": 1, "hydrojunk": 1, "biojunk": 1, "scrap_metal": 1}, Category: ModTransport, Element: "", TargetType: "self", Destination: 10}, {ID: "enchant_1", Name: "Enchant Level 1", Level: 7, MaxHit: 0, BaseXP: 17.5, JunkCost: map[string]int{"cosmicjunk": 1, "hydrojunk": 1, "scrap_metal": 1}, Category: ModEnchant, Element: "", TargetType: "inventory"}, {ID: "enchant_2", Name: "Enchant Level 2", Level: 27, MaxHit: 0, BaseXP: 37.0, JunkCost: map[string]int{"cosmicjunk": 1, "biojunk": 3, "scrap_metal": 1}, Category: ModEnchant, Element: "", TargetType: "inventory"}, {ID: "enchant_3", Name: "Enchant Level 3", Level: 49, MaxHit: 0, BaseXP: 59.0, JunkCost: map[string]int{"cosmicjunk": 1, "solarjunk": 5, "scrap_metal": 1}, Category: ModEnchant, Element: "", TargetType: "inventory"}, {ID: "enchant_4", Name: "Enchant Level 4", Level: 57, MaxHit: 0, BaseXP: 67.0, JunkCost: map[string]int{"cosmicjunk": 1, "ecojunk": 10, "scrap_metal": 1}, Category: ModEnchant, Element: "", TargetType: "inventory"}, {ID: "chip_sapphire", Name: "Chip Sapphire Bolts", Level: 4, MaxHit: 0, BaseXP: 9.0, JunkCost: map[string]int{"cosmicjunk": 1, "hydrojunk": 1, "scrap_metal": 1}, Category: ModEnchant, Element: "", TargetType: "inventory"}, {ID: "chip_emerald", Name: "Chip Emerald Bolts", Level: 27, MaxHit: 0, BaseXP: 37.0, JunkCost: map[string]int{"cosmicjunk": 1, "biojunk": 3, "scrap_metal": 1}, Category: ModEnchant, Element: "", TargetType: "inventory"}, {ID: "chip_ruby", Name: "Chip Ruby Bolts", Level: 49, MaxHit: 0, BaseXP: 59.0, JunkCost: map[string]int{"cosmicjunk": 1, "solarjunk": 5, "bloodjunk": 1, "scrap_metal": 1}, Category: ModEnchant, Element: "", TargetType: "inventory"}, {ID: "chip_diamond", Name: "Chip Diamond Bolts", Level: 57, MaxHit: 0, BaseXP: 67.0, JunkCost: map[string]int{"cosmicjunk": 1, "ecojunk": 10, "scrap_metal": 1}, Category: ModEnchant, Element: "", TargetType: "inventory"}, } modByID = make(map[string]*ModDef, len(AllMods)) for _, m := range AllMods { modByID[m.ID] = m } }