Give item categories and subtypes real types (refactor step 2)
ObjectKind separates what an item is from how it draws: Object.Type (a byte that doubled as the map character) becomes Kind ObjectKind, with Glyph() producing the display character and objectKindForGlyph converting back at the map boundary. KindWand covers the C 'stick' category. The magic-missile bolt uses KindGold, matching C's literal o_type='*' trick, with a comment. PotionKind, ScrollKind, RingKind, WandKind, WeaponKind, ArmorKind and TrapKind are now iota enums with Stringer (names come from the base info tables); Object gains typed accessors (obj.RingKind(), ...) and Launch is typed WeaponKind. beTrapped returns TrapKind. The getItem/inventory/whatis prompt filters take ObjectKind, with KindCallable/KindRingOrStick replacing the C CALLABLE/R_OR_S sentinels; wizard.c's type_name table is subsumed by ObjectKind.String(). IsRing/IsWearing/initWeapon/doPot signatures are typed accordingly. The save format version becomes 5.4.4-go2: the gob field rename would otherwise silently zero Kind when reading old saves. No behavior change; full suite green.
This commit is contained in:
@@ -9,9 +9,9 @@ package game
|
||||
func (g *RogueGame) createObj() {
|
||||
obj := newObject()
|
||||
g.msg("type of item: ")
|
||||
obj.Type = g.readchar()
|
||||
obj.Kind = objectKindForGlyph(g.readchar())
|
||||
g.Msgs.Mpos = 0
|
||||
g.msg("which %c do you want? (0-f)", obj.Type)
|
||||
g.msg("which %c do you want? (0-f)", obj.Kind.Glyph())
|
||||
ch := g.readchar()
|
||||
if isDigit(ch) {
|
||||
obj.Which = int(ch - '0')
|
||||
@@ -22,15 +22,15 @@ func (g *RogueGame) createObj() {
|
||||
obj.Count = 1
|
||||
g.Msgs.Mpos = 0
|
||||
switch {
|
||||
case obj.Type == Weapon || obj.Type == Armor:
|
||||
case obj.Kind == KindWeapon || obj.Kind == KindArmor:
|
||||
g.msg("blessing? (+,-,n)")
|
||||
bless := g.readchar()
|
||||
g.Msgs.Mpos = 0
|
||||
if bless == '-' {
|
||||
obj.Flags.Set(Cursed)
|
||||
}
|
||||
if obj.Type == Weapon {
|
||||
g.initWeapon(obj, obj.Which)
|
||||
if obj.Kind == KindWeapon {
|
||||
g.initWeapon(obj, WeaponKind(obj.Which))
|
||||
if bless == '-' {
|
||||
obj.HPlus -= g.rnd(3) + 1
|
||||
}
|
||||
@@ -46,8 +46,8 @@ func (g *RogueGame) createObj() {
|
||||
obj.Arm -= g.rnd(3) + 1
|
||||
}
|
||||
}
|
||||
case obj.Type == Ring:
|
||||
switch obj.Which {
|
||||
case obj.Kind == KindRing:
|
||||
switch obj.RingKind() {
|
||||
case RingProtection, RingAddStrength, RingDexterity, RingIncreaseDamage:
|
||||
g.msg("blessing? (+,-,n)")
|
||||
bless := g.readchar()
|
||||
@@ -61,9 +61,9 @@ func (g *RogueGame) createObj() {
|
||||
case RingAggravateMonsters, RingTeleportation:
|
||||
obj.Flags.Set(Cursed)
|
||||
}
|
||||
case obj.Type == Stick:
|
||||
case obj.Kind == KindWand:
|
||||
g.fixStick(obj)
|
||||
case obj.Type == Gold:
|
||||
case obj.Kind == KindGold:
|
||||
g.msg("how much?")
|
||||
buf := ""
|
||||
if g.getStr(&buf, g.scr.Std) == Norm {
|
||||
@@ -93,7 +93,7 @@ func (g *RogueGame) showMap() {
|
||||
}
|
||||
|
||||
// whatis identifies what a certain object is (wizard.c whatis).
|
||||
func (g *RogueGame) whatis(insist bool, typ int) {
|
||||
func (g *RogueGame) whatis(insist bool, kind ObjectKind) {
|
||||
p := &g.Player
|
||||
if len(p.Pack) == 0 {
|
||||
g.msg("you don't have anything in your pack to identify")
|
||||
@@ -102,7 +102,7 @@ func (g *RogueGame) whatis(insist bool, typ int) {
|
||||
|
||||
var obj *Object
|
||||
for {
|
||||
obj = g.getItem("identify", typ)
|
||||
obj = g.getItem("identify", kind)
|
||||
if !insist {
|
||||
break
|
||||
}
|
||||
@@ -111,9 +111,10 @@ func (g *RogueGame) whatis(insist bool, typ int) {
|
||||
}
|
||||
if obj == nil {
|
||||
g.msg("you must identify something")
|
||||
} else if typ != 0 && int(obj.Type) != typ &&
|
||||
!(typ == RorS && (obj.Type == Ring || obj.Type == Stick)) {
|
||||
g.msg("you must identify a %s", typeName(typ))
|
||||
} else if kind != KindNone && obj.Kind != kind &&
|
||||
!(kind == KindRingOrStick &&
|
||||
(obj.Kind == KindRing || obj.Kind == KindWand)) {
|
||||
g.msg("you must identify a %s", kind)
|
||||
} else {
|
||||
break
|
||||
}
|
||||
@@ -123,16 +124,16 @@ func (g *RogueGame) whatis(insist bool, typ int) {
|
||||
return
|
||||
}
|
||||
|
||||
switch obj.Type {
|
||||
case Scroll:
|
||||
switch obj.Kind {
|
||||
case KindScroll:
|
||||
setKnow(obj, g.Items.Scrolls[:])
|
||||
case Potion:
|
||||
case KindPotion:
|
||||
setKnow(obj, g.Items.Potions[:])
|
||||
case Stick:
|
||||
case KindWand:
|
||||
setKnow(obj, g.Items.Sticks[:])
|
||||
case Weapon, Armor:
|
||||
case KindWeapon, KindArmor:
|
||||
obj.Flags.Set(Known)
|
||||
case Ring:
|
||||
case KindRing:
|
||||
setKnow(obj, g.Items.Rings[:])
|
||||
}
|
||||
g.msg("%s", g.invName(obj, false))
|
||||
@@ -146,30 +147,8 @@ func setKnow(obj *Object, info []ObjInfo) {
|
||||
info[obj.Which].Guess = ""
|
||||
}
|
||||
|
||||
// typeNameTable is the wizard.c type_name static tlist.
|
||||
var typeNameTable = []struct {
|
||||
ch int
|
||||
desc string
|
||||
}{
|
||||
{int(Potion), "potion"},
|
||||
{int(Scroll), "scroll"},
|
||||
{int(Food), "food"},
|
||||
{RorS, "ring, wand or staff"},
|
||||
{int(Ring), "ring"},
|
||||
{int(Stick), "wand or staff"},
|
||||
{int(Weapon), "weapon"},
|
||||
{int(Armor), "suit of armor"},
|
||||
}
|
||||
|
||||
// typeName returns the name of an object type (wizard.c type_name).
|
||||
func typeName(typ int) string {
|
||||
for _, hp := range typeNameTable {
|
||||
if typ == hp.ch {
|
||||
return hp.desc
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
// The C type_name()/tlist table is gone: ObjectKind.String() carries the
|
||||
// same vocabulary.
|
||||
|
||||
// teleport bamfs the hero someplace else (wizard.c teleport).
|
||||
func (g *RogueGame) teleport() {
|
||||
|
||||
Reference in New Issue
Block a user