diff options
52 files changed, 181 insertions, 2 deletions
@@ -42,9 +42,9 @@ The combat system needs to be upgraded from single AttackBonus/DefenseBonus to O Small additions that make combat feel complete before building bigger systems on top. -- [ ] **Aggressive Mobs** — Mobs with `aggressive: true` initiate combat when a player enters their room. Add an `AggroTick()` or check in room-enter logic. Respect combat level difference (only aggro if mob's combat level is close to or above player's, or always aggro for certain mobs). Configurable via mob YAML. Some of the new mobs from step 2c should be aggressive. +- [x] **Aggressive Mobs** — Mobs with `aggressive: true` initiate combat when a player enters their room. Add an `AggroTick()` or check in room-enter logic. Respect combat level difference (only aggro if mob's combat level is close to or above player's, or always aggro for certain mobs). Configurable via mob YAML. Some of the new mobs from step 2c should be aggressive. -- [ ] **Equipment Skill Requirements** — Add optional `requirements` map to `ItemDef` (e.g., `requirements: { attack: 20, defense: 10 }`). Check in `cmd_wear.go` before equipping. Display requirements when examining items. This prevents low-level players from wearing rune gear immediately. +- [x] **Equipment Skill Requirements** — Add optional `requirements` map to `ItemDef` (e.g., `requirements: { attack: 20, defense: 10 }`). Check in `cmd_wear.go` before equipping. Display requirements when examining items. This prevents low-level players from wearing rune gear immediately. --- diff --git a/data/items/adamant_axe.yaml b/data/items/adamant_axe.yaml index 4c71f5e..81232fe 100644 --- a/data/items/adamant_axe.yaml +++ b/data/items/adamant_axe.yaml @@ -15,3 +15,5 @@ stats: speed: 5 tool_type: axe tool_speed: 2 +requirements: + attack: 30 diff --git a/data/items/adamant_dagger.yaml b/data/items/adamant_dagger.yaml index 35508a0..d78ecdc 100644 --- a/data/items/adamant_dagger.yaml +++ b/data/items/adamant_dagger.yaml @@ -13,3 +13,5 @@ stats: crush_attack: -1 strength_bonus: 19 speed: 3 +requirements: + attack: 30 diff --git a/data/items/adamant_full_helm.yaml b/data/items/adamant_full_helm.yaml index a62d3aa..3c36c62 100644 --- a/data/items/adamant_full_helm.yaml +++ b/data/items/adamant_full_helm.yaml @@ -11,3 +11,5 @@ stats: crush_defense: 16 science_defense: -8 ranged_defense: 22 +requirements: + defense: 30 diff --git a/data/items/adamant_med_helm.yaml b/data/items/adamant_med_helm.yaml index e5bb561..1fb6785 100644 --- a/data/items/adamant_med_helm.yaml +++ b/data/items/adamant_med_helm.yaml @@ -11,3 +11,5 @@ stats: crush_defense: 10 science_defense: -3 ranged_defense: 14 +requirements: + defense: 30 diff --git a/data/items/adamant_pickaxe.yaml b/data/items/adamant_pickaxe.yaml index ee65b58..4296b0d 100644 --- a/data/items/adamant_pickaxe.yaml +++ b/data/items/adamant_pickaxe.yaml @@ -15,3 +15,5 @@ stats: speed: 5 tool_type: pickaxe tool_speed: 0.75 +requirements: + attack: 30 diff --git a/data/items/adamant_platebody.yaml b/data/items/adamant_platebody.yaml index c13bd82..a37b781 100644 --- a/data/items/adamant_platebody.yaml +++ b/data/items/adamant_platebody.yaml @@ -11,3 +11,5 @@ stats: crush_defense: 40 science_defense: -25 ranged_defense: 49 +requirements: + defense: 30 diff --git a/data/items/adamant_sword.yaml b/data/items/adamant_sword.yaml index 036288e..035b615 100644 --- a/data/items/adamant_sword.yaml +++ b/data/items/adamant_sword.yaml @@ -13,3 +13,5 @@ stats: crush_attack: -2 strength_bonus: 27 speed: 4 +requirements: + attack: 30 diff --git a/data/items/black_axe.yaml b/data/items/black_axe.yaml index a43c1e6..e708645 100644 --- a/data/items/black_axe.yaml +++ b/data/items/black_axe.yaml @@ -15,3 +15,5 @@ stats: speed: 5 tool_type: axe tool_speed: 2.5 +requirements: + attack: 10 diff --git a/data/items/black_pickaxe.yaml b/data/items/black_pickaxe.yaml index ef6ca99..c3df955 100644 --- a/data/items/black_pickaxe.yaml +++ b/data/items/black_pickaxe.yaml @@ -15,3 +15,5 @@ stats: speed: 5 tool_type: pickaxe tool_speed: 1 +requirements: + attack: 10 diff --git a/data/items/coif.yaml b/data/items/coif.yaml index 10c0c55..8d910d7 100644 --- a/data/items/coif.yaml +++ b/data/items/coif.yaml @@ -11,3 +11,6 @@ stats: science_defense: 4 ranged_defense: 6 ranged_attack: 2 +requirements: + defense: 20 + ranged: 20 diff --git a/data/items/dragon_axe.yaml b/data/items/dragon_axe.yaml index e5afe5d..ddc9758 100644 --- a/data/items/dragon_axe.yaml +++ b/data/items/dragon_axe.yaml @@ -15,3 +15,5 @@ stats: speed: 5 tool_type: axe tool_speed: 1 +requirements: + attack: 60 diff --git a/data/items/dragon_pickaxe.yaml b/data/items/dragon_pickaxe.yaml index a51b102..6f187b8 100644 --- a/data/items/dragon_pickaxe.yaml +++ b/data/items/dragon_pickaxe.yaml @@ -15,3 +15,5 @@ stats: speed: 5 tool_type: pickaxe tool_speed: 0.25 +requirements: + attack: 60 diff --git a/data/items/hard_leather_body.yaml b/data/items/hard_leather_body.yaml index 4fe2829..a5fe30f 100644 --- a/data/items/hard_leather_body.yaml +++ b/data/items/hard_leather_body.yaml @@ -10,3 +10,5 @@ stats: crush_defense: 8 science_defense: 6 ranged_defense: 14 +requirements: + defense: 10 diff --git a/data/items/hard_leather_shield.yaml b/data/items/hard_leather_shield.yaml index 26c28de..fd7dabf 100644 --- a/data/items/hard_leather_shield.yaml +++ b/data/items/hard_leather_shield.yaml @@ -10,3 +10,5 @@ stats: crush_defense: 5 science_defense: 4 ranged_defense: 8 +requirements: + defense: 10 diff --git a/data/items/magic_longbow.yaml b/data/items/magic_longbow.yaml index c91eb02..07797fb 100644 --- a/data/items/magic_longbow.yaml +++ b/data/items/magic_longbow.yaml @@ -9,3 +9,5 @@ attack_type: ranged speed: 6 stats: ranged_attack: 69 +requirements: + ranged: 50 diff --git a/data/items/magic_shortbow.yaml b/data/items/magic_shortbow.yaml index b50916b..893b287 100644 --- a/data/items/magic_shortbow.yaml +++ b/data/items/magic_shortbow.yaml @@ -9,3 +9,5 @@ attack_type: ranged speed: 4 stats: ranged_attack: 69 +requirements: + ranged: 50 diff --git a/data/items/maple_longbow.yaml b/data/items/maple_longbow.yaml index 078e72a..1c86128 100644 --- a/data/items/maple_longbow.yaml +++ b/data/items/maple_longbow.yaml @@ -9,3 +9,5 @@ attack_type: ranged speed: 6 stats: ranged_attack: 29 +requirements: + ranged: 30 diff --git a/data/items/maple_shortbow.yaml b/data/items/maple_shortbow.yaml index 5e6ae66..38c27b5 100644 --- a/data/items/maple_shortbow.yaml +++ b/data/items/maple_shortbow.yaml @@ -9,3 +9,5 @@ attack_type: ranged speed: 4 stats: ranged_attack: 29 +requirements: + ranged: 30 diff --git a/data/items/mithril_axe.yaml b/data/items/mithril_axe.yaml index 83cefe9..ca18195 100644 --- a/data/items/mithril_axe.yaml +++ b/data/items/mithril_axe.yaml @@ -15,3 +15,5 @@ stats: speed: 5 tool_type: axe tool_speed: 2.5 +requirements: + attack: 20 diff --git a/data/items/mithril_dagger.yaml b/data/items/mithril_dagger.yaml index 21d99ba..8ffe595 100644 --- a/data/items/mithril_dagger.yaml +++ b/data/items/mithril_dagger.yaml @@ -13,3 +13,5 @@ stats: crush_attack: -1 strength_bonus: 14 speed: 3 +requirements: + attack: 20 diff --git a/data/items/mithril_full_helm.yaml b/data/items/mithril_full_helm.yaml index a8e4f07..d317705 100644 --- a/data/items/mithril_full_helm.yaml +++ b/data/items/mithril_full_helm.yaml @@ -11,3 +11,5 @@ stats: crush_defense: 12 science_defense: -6 ranged_defense: 16 +requirements: + defense: 20 diff --git a/data/items/mithril_med_helm.yaml b/data/items/mithril_med_helm.yaml index 7616a01..f244a7c 100644 --- a/data/items/mithril_med_helm.yaml +++ b/data/items/mithril_med_helm.yaml @@ -11,3 +11,5 @@ stats: crush_defense: 7 science_defense: -3 ranged_defense: 10 +requirements: + defense: 20 diff --git a/data/items/mithril_pickaxe.yaml b/data/items/mithril_pickaxe.yaml index 38fa44f..5da6937 100644 --- a/data/items/mithril_pickaxe.yaml +++ b/data/items/mithril_pickaxe.yaml @@ -15,3 +15,5 @@ stats: speed: 5 tool_type: pickaxe tool_speed: 1 +requirements: + attack: 20 diff --git a/data/items/mithril_platebody.yaml b/data/items/mithril_platebody.yaml index b40a483..50e8ea0 100644 --- a/data/items/mithril_platebody.yaml +++ b/data/items/mithril_platebody.yaml @@ -11,3 +11,5 @@ stats: crush_defense: 30 science_defense: -20 ranged_defense: 36 +requirements: + defense: 20 diff --git a/data/items/mithril_sword.yaml b/data/items/mithril_sword.yaml index f006ab7..1824f5b 100644 --- a/data/items/mithril_sword.yaml +++ b/data/items/mithril_sword.yaml @@ -13,3 +13,5 @@ stats: crush_attack: -2 strength_bonus: 20 speed: 4 +requirements: + attack: 20 diff --git a/data/items/oak_longbow.yaml b/data/items/oak_longbow.yaml index 12c8296..71e7c7c 100644 --- a/data/items/oak_longbow.yaml +++ b/data/items/oak_longbow.yaml @@ -9,3 +9,5 @@ attack_type: ranged speed: 6 stats: ranged_attack: 14 +requirements: + ranged: 5 diff --git a/data/items/oak_shortbow.yaml b/data/items/oak_shortbow.yaml index a77cb2b..30ebbce 100644 --- a/data/items/oak_shortbow.yaml +++ b/data/items/oak_shortbow.yaml @@ -9,3 +9,5 @@ attack_type: ranged speed: 4 stats: ranged_attack: 14 +requirements: + ranged: 5 diff --git a/data/items/rune_axe.yaml b/data/items/rune_axe.yaml index 584b345..a694bdf 100644 --- a/data/items/rune_axe.yaml +++ b/data/items/rune_axe.yaml @@ -15,3 +15,5 @@ stats: speed: 5 tool_type: axe tool_speed: 1.5 +requirements: + attack: 40 diff --git a/data/items/rune_dagger.yaml b/data/items/rune_dagger.yaml index 7904b5a..9e8507b 100644 --- a/data/items/rune_dagger.yaml +++ b/data/items/rune_dagger.yaml @@ -13,3 +13,5 @@ stats: crush_attack: -1 strength_bonus: 24 speed: 3 +requirements: + attack: 40 diff --git a/data/items/rune_full_helm.yaml b/data/items/rune_full_helm.yaml index d8badb7..87d6973 100644 --- a/data/items/rune_full_helm.yaml +++ b/data/items/rune_full_helm.yaml @@ -11,3 +11,5 @@ stats: crush_defense: 22 science_defense: -11 ranged_defense: 30 +requirements: + defense: 40 diff --git a/data/items/rune_med_helm.yaml b/data/items/rune_med_helm.yaml index 39d16ae..895d257 100644 --- a/data/items/rune_med_helm.yaml +++ b/data/items/rune_med_helm.yaml @@ -11,3 +11,5 @@ stats: crush_defense: 13 science_defense: -4 ranged_defense: 19 +requirements: + defense: 40 diff --git a/data/items/rune_pickaxe.yaml b/data/items/rune_pickaxe.yaml index 2b63965..265231d 100644 --- a/data/items/rune_pickaxe.yaml +++ b/data/items/rune_pickaxe.yaml @@ -15,3 +15,5 @@ stats: speed: 5 tool_type: pickaxe tool_speed: 0.5 +requirements: + attack: 40 diff --git a/data/items/rune_platebody.yaml b/data/items/rune_platebody.yaml index 78bdaa1..d1e5fb1 100644 --- a/data/items/rune_platebody.yaml +++ b/data/items/rune_platebody.yaml @@ -11,3 +11,5 @@ stats: crush_defense: 52 science_defense: -30 ranged_defense: 65 +requirements: + defense: 40 diff --git a/data/items/rune_sword.yaml b/data/items/rune_sword.yaml index 21b4c73..e0bfb74 100644 --- a/data/items/rune_sword.yaml +++ b/data/items/rune_sword.yaml @@ -13,3 +13,5 @@ stats: crush_attack: -2 strength_bonus: 36 speed: 4 +requirements: + attack: 40 diff --git a/data/items/steel_axe.yaml b/data/items/steel_axe.yaml index 74075e8..6f2ac99 100644 --- a/data/items/steel_axe.yaml +++ b/data/items/steel_axe.yaml @@ -15,3 +15,5 @@ stats: speed: 5 tool_type: axe tool_speed: 3 +requirements: + attack: 5 diff --git a/data/items/steel_dagger.yaml b/data/items/steel_dagger.yaml index 2aa079b..e52b882 100644 --- a/data/items/steel_dagger.yaml +++ b/data/items/steel_dagger.yaml @@ -13,3 +13,5 @@ stats: crush_attack: -1 strength_bonus: 10 speed: 3 +requirements: + attack: 5 diff --git a/data/items/steel_full_helm.yaml b/data/items/steel_full_helm.yaml index 11ce736..7152ded 100644 --- a/data/items/steel_full_helm.yaml +++ b/data/items/steel_full_helm.yaml @@ -11,3 +11,5 @@ stats: crush_defense: 9 science_defense: -5 ranged_defense: 12 +requirements: + defense: 5 diff --git a/data/items/steel_med_helm.yaml b/data/items/steel_med_helm.yaml index 336020c..9e15fdd 100644 --- a/data/items/steel_med_helm.yaml +++ b/data/items/steel_med_helm.yaml @@ -11,3 +11,5 @@ stats: crush_defense: 5 science_defense: -2 ranged_defense: 7 +requirements: + defense: 5 diff --git a/data/items/steel_pickaxe.yaml b/data/items/steel_pickaxe.yaml index 875a84b..cc048a1 100644 --- a/data/items/steel_pickaxe.yaml +++ b/data/items/steel_pickaxe.yaml @@ -15,3 +15,5 @@ stats: speed: 5 tool_type: pickaxe tool_speed: 1.25 +requirements: + attack: 5 diff --git a/data/items/steel_platebody.yaml b/data/items/steel_platebody.yaml index 22f3747..f44dfa3 100644 --- a/data/items/steel_platebody.yaml +++ b/data/items/steel_platebody.yaml @@ -11,3 +11,5 @@ stats: crush_defense: 22 science_defense: -15 ranged_defense: 27 +requirements: + defense: 5 diff --git a/data/items/steel_sword.yaml b/data/items/steel_sword.yaml index ffc6e31..e096dc9 100644 --- a/data/items/steel_sword.yaml +++ b/data/items/steel_sword.yaml @@ -13,3 +13,5 @@ stats: crush_attack: -2 strength_bonus: 14 speed: 4 +requirements: + attack: 5 diff --git a/data/items/willow_longbow.yaml b/data/items/willow_longbow.yaml index 3a09368..e30528c 100644 --- a/data/items/willow_longbow.yaml +++ b/data/items/willow_longbow.yaml @@ -9,3 +9,5 @@ attack_type: ranged speed: 6 stats: ranged_attack: 20 +requirements: + ranged: 20 diff --git a/data/items/willow_shortbow.yaml b/data/items/willow_shortbow.yaml index 51eb97c..f75cfe9 100644 --- a/data/items/willow_shortbow.yaml +++ b/data/items/willow_shortbow.yaml @@ -9,3 +9,5 @@ attack_type: ranged speed: 4 stats: ranged_attack: 20 +requirements: + ranged: 20 diff --git a/data/items/yew_longbow.yaml b/data/items/yew_longbow.yaml index 53d99da..1e7c0f5 100644 --- a/data/items/yew_longbow.yaml +++ b/data/items/yew_longbow.yaml @@ -9,3 +9,5 @@ attack_type: ranged speed: 6 stats: ranged_attack: 47 +requirements: + ranged: 40 diff --git a/data/items/yew_shortbow.yaml b/data/items/yew_shortbow.yaml index 8856d96..c302a38 100644 --- a/data/items/yew_shortbow.yaml +++ b/data/items/yew_shortbow.yaml @@ -9,3 +9,5 @@ attack_type: ranged speed: 4 stats: ranged_attack: 47 +requirements: + ranged: 40 diff --git a/internal/game/aggro.go b/internal/game/aggro.go new file mode 100644 index 0000000..8f4da42 --- /dev/null +++ b/internal/game/aggro.go @@ -0,0 +1,54 @@ +package game + +import ( + "fmt" + + "thehouseoficarus/internal/combat" + "thehouseoficarus/internal/engine" + "thehouseoficarus/internal/net" + "thehouseoficarus/internal/player" +) + +func (g *Game) checkAggro(sess *net.Session) { + p := sess.Player.(*player.Player) + + if combat.GetCombat(p.Name) != nil { + return + } + + playerLevel := p.CombatLevel() + mobs := g.MobStore.MobsInRoom(p.RoomID) + + for _, mob := range mobs { + if !mob.Aggressive || mob.HP <= 0 || mob.Protected { + continue + } + if combat.IsMobInCombat(mob.InstanceID) { + continue + } + mobLevel := mobCombatLevel(mob) + if playerLevel > mobLevel*2 { + continue + } + aggMob := mob + g.Ticks.Subscribe(engine.ToTicks(1), func() bool { + if combat.GetCombat(p.Name) != nil { + return false + } + if aggMob.HP <= 0 || aggMob.RoomID != p.RoomID { + return false + } + if combat.IsMobInCombat(aggMob.InstanceID) { + return false + } + attacker := aggMob.Name + if !aggMob.Unique { + attacker = "The " + aggMob.Name + } + sess.WriteLine(fmt.Sprintf("\n%s attacks you!", g.colorize(sess, "mob_name", attacker))) + g.startCombat(sess, p, aggMob) + return false + }) + break + } +} diff --git a/internal/game/cmd_look.go b/internal/game/cmd_look.go index 1c9eb9c..14bac11 100644 --- a/internal/game/cmd_look.go +++ b/internal/game/cmd_look.go @@ -770,4 +770,11 @@ func (g *Game) showItemStats(sess *net.Session, def *object.ItemDef) { if def.Speed > 0 { sess.WriteLine(fmt.Sprintf(" Speed: %.0f", def.Speed)) } + if len(def.Requirements) > 0 { + sess.WriteLine("") + sess.WriteLine(" Requirements:") + for skill, level := range def.Requirements { + sess.WriteLine(fmt.Sprintf(" %s: %d", skill, level)) + } + } } diff --git a/internal/game/cmd_move.go b/internal/game/cmd_move.go index 2a3e698..b3fe254 100644 --- a/internal/game/cmd_move.go +++ b/internal/game/cmd_move.go @@ -153,6 +153,7 @@ func (g *Game) completeMove(sess *net.Session, p *player.Player) { } g.RunEnterSteps(sess, targetID) + g.checkAggro(sess) } func (g *Game) seedRoomMobs(roomID int) { diff --git a/internal/game/cmd_wear.go b/internal/game/cmd_wear.go index ddc970b..692a3e4 100644 --- a/internal/game/cmd_wear.go +++ b/internal/game/cmd_wear.go @@ -9,6 +9,22 @@ import ( "thehouseoficarus/internal/player" ) +func (g *Game) checkRequirements(p *player.Player, def *object.ItemDef) string { + if len(def.Requirements) == 0 { + return "" + } + var unmet []string + for skill, level := range def.Requirements { + if p.Level(player.SkillName(skill)) < level { + unmet = append(unmet, fmt.Sprintf("%d %s", level, skill)) + } + } + if len(unmet) == 0 { + return "" + } + return fmt.Sprintf("You need %s to wear %s.", strings.Join(unmet, ", "), def.Name) +} + func (g *Game) doWear(sess *net.Session, input string) { p := sess.Player.(*player.Player) @@ -54,6 +70,11 @@ func (g *Game) doWear(sess *net.Session, input string) { return } + if msg := g.checkRequirements(p, def); msg != "" { + sess.WriteLine(msg) + return + } + if def.EquipSlot == object.SlotAmmo && def.Stackable { g.equipAmmo(sess, p, match.Slot, slot, def, qty) return @@ -165,6 +186,9 @@ func (g *Game) doWearAll(sess *net.Session) { if err != nil || def.EquipSlot == "" { continue } + if g.checkRequirements(p, def) != "" { + continue + } current, exists := bestPerSlot[def.EquipSlot] val := def.Value if def.EquipSlot == object.SlotAmmo && def.Stackable { diff --git a/internal/game/login_char.go b/internal/game/login_char.go index 82065d3..84f146b 100644 --- a/internal/game/login_char.go +++ b/internal/game/login_char.go @@ -98,6 +98,7 @@ func (g *Game) connectCharacter(sess *net.Session, name string) { } g.doLook(sess) + g.checkAggro(sess) sess.Write("\r\n> ") } diff --git a/internal/object/item.go b/internal/object/item.go index 14cb65c..60d9ff9 100644 --- a/internal/object/item.go +++ b/internal/object/item.go @@ -42,6 +42,7 @@ type ItemDef struct { AttackType string `yaml:"attack_type"` Stats ItemStats `yaml:"stats"` Speed float64 `yaml:"speed"` + Requirements map[string]int `yaml:"requirements,omitempty"` ToolType string `yaml:"tool_type"` ToolSpeed float64 `yaml:"tool_speed"` BurnTicks float64 `yaml:"burn_ticks"` |
