last_light/game/model/item.go

251 lines
5.4 KiB
Go

package model
import (
"mvvasilev/last_light/engine"
"github.com/gdamore/tcell/v2"
)
type ItemMetaType int
const (
MetaItemType_Physical_Weapon ItemMetaType = iota
MetaItemType_Magic_Weapon
MetaItemType_Weapon
MetaItemType_Physical_Armour
MetaItemType_Magic_Armour
MetaItemType_Armour
MetaItemType_Consumable
MetaItemType_Projectile
MetaItemType_Potion
)
type ProjectileDirection int
const (
ProjectileDirection_NorthSouth ProjectileDirection = iota
ProjectileDirection_EastWest
ProjectileDirection_NorthEastSouthWest
ProjectileDirection_NorthWestSouthEast
)
type Item interface {
TileIcon() rune
Icon() string
Style() tcell.Style
Type() ItemType
Quantifiable() *Item_QuantifiableComponent
Usable() *Item_UsableComponent
Equippable() *Item_EquippableComponent
Named() *Item_NamedComponent
Described() *Item_DescribedComponent
Damaging() *Item_DamagingComponent
StatModifier() *Item_StatModifierComponent
MetaTypes() *Item_MetaTypesComponent
ProjectileData() *Item_ProjectileComponent
}
type Item_ProjectileComponent struct {
Sprites map[ProjectileDirection]rune
AdditionalDamageRoll func() (dmg int, dmgType DamageType)
}
type Item_QuantifiableComponent struct {
MaxQuantity int
CurrentQuantity int
}
type Item_UsableComponent struct {
IsUsableBy func(Entity) bool
Use func(*engine.GameEventLog, *Dungeon, Entity)
}
type Item_EquippableComponent struct {
Slot EquippedSlot
}
type Item_NamedComponent struct {
Name string
Style tcell.Style
}
type Item_DescribedComponent struct {
Description string
Style tcell.Style
}
type Item_DamagingComponent struct {
IsRanged bool
DamageRoll func() (damage int, dmgType DamageType)
}
type Item_StatModifierComponent struct {
StatModifiers []StatModifier
}
type Item_MetaTypesComponent struct {
Types []ItemMetaType
}
type BaseItem struct {
tileIcon rune
icon string
style tcell.Style
itemType ItemType
quantifiable *Item_QuantifiableComponent
usable *Item_UsableComponent
equippable *Item_EquippableComponent
named *Item_NamedComponent
described *Item_DescribedComponent
damaging *Item_DamagingComponent
statModifier *Item_StatModifierComponent
metaTypes *Item_MetaTypesComponent
projectileData *Item_ProjectileComponent
}
func (i *BaseItem) TileIcon() rune {
return i.tileIcon
}
func (i *BaseItem) Icon() string {
return i.icon
}
func (i *BaseItem) Style() tcell.Style {
return i.style
}
func (i *BaseItem) Type() ItemType {
return i.itemType
}
func (i *BaseItem) Quantifiable() *Item_QuantifiableComponent {
return i.quantifiable
}
func (i *BaseItem) Usable() *Item_UsableComponent {
return i.usable
}
func (i *BaseItem) Equippable() *Item_EquippableComponent {
return i.equippable
}
func (i *BaseItem) Named() *Item_NamedComponent {
return i.named
}
func (i *BaseItem) Described() *Item_DescribedComponent {
return i.described
}
func (i *BaseItem) Damaging() *Item_DamagingComponent {
return i.damaging
}
func (i *BaseItem) StatModifier() *Item_StatModifierComponent {
return i.statModifier
}
func (i *BaseItem) MetaTypes() *Item_MetaTypesComponent {
return i.metaTypes
}
func (i *BaseItem) ProjectileData() *Item_ProjectileComponent {
return i.projectileData
}
func createBaseItem(itemType ItemType, tileIcon rune, icon string, style tcell.Style, components ...func(*BaseItem)) *BaseItem {
i := &BaseItem{
itemType: itemType,
tileIcon: tileIcon,
icon: icon,
style: style,
}
for _, comp := range components {
comp(i)
}
return i
}
func item_WithQuantity(quantity, maxQuantity int) func(*BaseItem) {
return func(bi *BaseItem) {
bi.quantifiable = &Item_QuantifiableComponent{
CurrentQuantity: quantity,
MaxQuantity: maxQuantity,
}
}
}
func item_WithUsable(usabilityCheck func(Entity) bool, useFunc func(*engine.GameEventLog, *Dungeon, Entity)) func(*BaseItem) {
return func(bi *BaseItem) {
bi.usable = &Item_UsableComponent{
IsUsableBy: usabilityCheck,
Use: useFunc,
}
}
}
func item_WithEquippable(slot EquippedSlot) func(*BaseItem) {
return func(bi *BaseItem) {
bi.equippable = &Item_EquippableComponent{
Slot: slot,
}
}
}
func item_WithDamaging(isRanged bool, damageFunc func() (damage int, dmgType DamageType)) func(*BaseItem) {
return func(bi *BaseItem) {
bi.damaging = &Item_DamagingComponent{
IsRanged: isRanged,
DamageRoll: damageFunc,
}
}
}
func item_WithName(name string, style tcell.Style) func(*BaseItem) {
return func(bi *BaseItem) {
bi.named = &Item_NamedComponent{
Name: name,
Style: style,
}
}
}
func item_WithDescription(description string, style tcell.Style) func(*BaseItem) {
return func(bi *BaseItem) {
bi.described = &Item_DescribedComponent{
Description: description,
Style: style,
}
}
}
func item_WithStatModifiers(statModifiers []StatModifier) func(*BaseItem) {
return func(bi *BaseItem) {
bi.statModifier = &Item_StatModifierComponent{
StatModifiers: statModifiers,
}
}
}
func item_WithMetaTypes(metaTypes []ItemMetaType) func(*BaseItem) {
return func(bi *BaseItem) {
bi.metaTypes = &Item_MetaTypesComponent{
Types: metaTypes,
}
}
}
func item_WithProjectileData(sprites map[ProjectileDirection]rune, additionalDamageRoll func() (dmg int, dmgType DamageType)) func(*BaseItem) {
return func(bi *BaseItem) {
bi.projectileData = &Item_ProjectileComponent{
Sprites: sprites,
AdditionalDamageRoll: additionalDamageRoll,
}
}
}