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.
164 lines
4.8 KiB
Go
164 lines
4.8 KiB
Go
package game
|
|
|
|
// ObjectKind is the category of an item. In C this was the o_type byte,
|
|
// which doubled as the character drawn on the map; the port separates the
|
|
// category (ObjectKind) from its display character (Glyph).
|
|
type ObjectKind int
|
|
|
|
const (
|
|
KindNone ObjectKind = iota
|
|
KindPotion
|
|
KindScroll
|
|
KindFood
|
|
KindWeapon
|
|
KindArmor
|
|
KindRing
|
|
KindWand // a "stick": wand or staff
|
|
KindAmulet
|
|
KindGold
|
|
)
|
|
|
|
// Prompt-filter pseudo-kinds for item selection (rogue.h CALLABLE and
|
|
// R_OR_S): they never appear on an Object, only as getItem filters.
|
|
const (
|
|
KindCallable ObjectKind = -1
|
|
KindRingOrStick ObjectKind = -2
|
|
)
|
|
|
|
// kindGlyphs maps each kind to the character Rogue draws for it.
|
|
var kindGlyphs = [...]byte{
|
|
KindNone: ' ',
|
|
KindPotion: Potion,
|
|
KindScroll: Scroll,
|
|
KindFood: Food,
|
|
KindWeapon: Weapon,
|
|
KindArmor: Armor,
|
|
KindRing: Ring,
|
|
KindWand: Stick,
|
|
KindAmulet: Amulet,
|
|
KindGold: Gold,
|
|
}
|
|
|
|
// Glyph returns the map/display character for this kind of object.
|
|
func (k ObjectKind) Glyph() byte {
|
|
if k < 0 || int(k) >= len(kindGlyphs) {
|
|
return ' '
|
|
}
|
|
return kindGlyphs[k]
|
|
}
|
|
|
|
// String names the category the way the C type_name() did.
|
|
func (k ObjectKind) String() string {
|
|
switch k {
|
|
case KindPotion:
|
|
return "potion"
|
|
case KindScroll:
|
|
return "scroll"
|
|
case KindFood:
|
|
return "food"
|
|
case KindWeapon:
|
|
return "weapon"
|
|
case KindArmor:
|
|
return "suit of armor"
|
|
case KindRing:
|
|
return "ring"
|
|
case KindWand:
|
|
return "wand or staff"
|
|
case KindAmulet:
|
|
return "amulet"
|
|
case KindGold:
|
|
return "gold"
|
|
case KindRingOrStick:
|
|
return "ring, wand or staff"
|
|
}
|
|
return "bizarre thing"
|
|
}
|
|
|
|
// objectKindForGlyph is the reverse of Glyph: what category of item does a
|
|
// map character denote. Returns KindNone for non-item characters.
|
|
func objectKindForGlyph(ch byte) ObjectKind {
|
|
for k, g := range kindGlyphs {
|
|
if g == ch && ObjectKind(k) != KindNone {
|
|
return ObjectKind(k)
|
|
}
|
|
}
|
|
return KindNone
|
|
}
|
|
|
|
// MergesInPack reports whether picking up another of this kind merges into
|
|
// an existing pack entry's count (rogue.h ISMULT).
|
|
func (k ObjectKind) MergesInPack() bool {
|
|
return k == KindPotion || k == KindScroll || k == KindFood
|
|
}
|
|
|
|
// Object is the _o arm of the C THING union: anything that can lie on the
|
|
// floor or ride in a pack.
|
|
type Object struct {
|
|
Kind ObjectKind // what kind of object it is (o_type)
|
|
Pos Coord // where it lives on the screen
|
|
Text string // what it says if you read it
|
|
Launch WeaponKind // what you need to launch it (noWeapon if none)
|
|
PackCh byte // what character it is in the pack
|
|
Damage string // damage if used like sword
|
|
HurlDmg string // damage if thrown
|
|
Count int // count for plural objects
|
|
Which int // which object of a type it is (index for the Kind's table)
|
|
HPlus int // plusses to hit
|
|
DPlus int // plusses to damage
|
|
Arm int // armor protection — overloaded as in C (see Charges/GoldVal)
|
|
Flags ObjFlags
|
|
Group int // group number for this object
|
|
Label string // label for object
|
|
}
|
|
|
|
// newObject is list.c new_item() for objects: a zeroed Object with the
|
|
// same non-zero defaults the C code relies on.
|
|
func newObject() *Object {
|
|
return &Object{Launch: noWeapon}
|
|
}
|
|
|
|
// Charges is the o_charges alias for Arm on wands and staffs.
|
|
func (o *Object) Charges() int { return o.Arm }
|
|
|
|
// SetCharges stores a charge count in the overloaded Arm field.
|
|
func (o *Object) SetCharges(n int) { o.Arm = n }
|
|
|
|
// GoldVal is the o_goldval alias for Arm on gold piles.
|
|
func (o *Object) GoldVal() int { return o.Arm }
|
|
|
|
// SetGoldVal stores a gold value in the overloaded Arm field.
|
|
func (o *Object) SetGoldVal(n int) { o.Arm = n }
|
|
|
|
// PotionKind returns Which as a potion kind; valid only for KindPotion.
|
|
func (o *Object) PotionKind() PotionKind { return PotionKind(o.Which) }
|
|
|
|
// ScrollKind returns Which as a scroll kind; valid only for KindScroll.
|
|
func (o *Object) ScrollKind() ScrollKind { return ScrollKind(o.Which) }
|
|
|
|
// RingKind returns Which as a ring kind; valid only for KindRing.
|
|
func (o *Object) RingKind() RingKind { return RingKind(o.Which) }
|
|
|
|
// WandKind returns Which as a wand kind; valid only for KindWand.
|
|
func (o *Object) WandKind() WandKind { return WandKind(o.Which) }
|
|
|
|
// WeaponKind returns Which as a weapon kind; valid only for KindWeapon.
|
|
func (o *Object) WeaponKind() WeaponKind { return WeaponKind(o.Which) }
|
|
|
|
// ArmorKind returns Which as an armor kind; valid only for KindArmor.
|
|
func (o *Object) ArmorKind() ArmorKind { return ArmorKind(o.Which) }
|
|
|
|
// attachObj is list.c attach(): push item onto the front of a list.
|
|
func attachObj(list *[]*Object, item *Object) {
|
|
*list = append([]*Object{item}, *list...)
|
|
}
|
|
|
|
// detachObj is list.c detach(): remove item (by identity) from a list.
|
|
func detachObj(list *[]*Object, item *Object) {
|
|
for i, o := range *list {
|
|
if o == item {
|
|
*list = append((*list)[:i], (*list)[i+1:]...)
|
|
return
|
|
}
|
|
}
|
|
}
|