Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 144 lines (120 sloc) 4.352 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
package com.programmera.scalaland_immutable3

object CreatureType extends Enumeration{
   val Elf, Dwarf = Value
}

object ProfessionalType extends Enumeration{
   val Thief, Warrior, Wizard = Value
}

class Avatar(
    val name: String,
    optionalFeatures: Option[CreatureFeatureSet],
    optionalItems: Option[MagicalItemList])
  extends Professional {

  // Fields
  val items = optionalItems.getOrElse(new MagicalItemList())

  // Initialize class
  protected val _features: CreatureFeatureSet =
    optionalFeatures.getOrElse(generateCreatureFeatures())

  // Override getters
  override def strength = super.strength +
    items.calculateModifier(CreatureFeature.Strength)
  override def wisdom = super.wisdom +
    items.calculateModifier(CreatureFeature.Wisdom)
  override def charisma = super.charisma +
    items.calculateModifier(CreatureFeature.Charisma)

  // Private helper method used to update a feature
  private def withCreatureFeature(
      newFeatures: CreatureFeatureSet): Avatar =
    Avatar(this.items, newFeatures, this)

  // Setters
  def withStrength(s: Int): Avatar =
    withCreatureFeature(_features.copy(strength = s))
  def withWisdom(w: Int): Avatar =
    withCreatureFeature(_features.copy(wisdom = w))
  def withCharisma(c: Int): Avatar =
    withCreatureFeature(_features.copy(charisma = c))
  def withHitpoints(h: Int): Avatar = {
    println("setHitpoints() old value: " + hitpoints + ", new value: " + h)
    if (h > 0)
      withCreatureFeature(_features.copy(hitpoints = h))
    else
      throw new DeathException(name + " died!")
  }

  // Suffer damage
  def sufferDamage(damage: Int): Avatar = {
    println("Hitpoints before attack: "+ hitpoints)
    println("Damage: "+ damage)
    if (damage > 0) {
      val newHitpoints = hitpoints - damage
      withHitpoints(newHitpoints)
    } else {
      this
    }
  }

  // Handy method
  def addItem(newItem: MagicalItem): Avatar =
    Avatar(this.items.add(newItem), this._features, this)

  // super will call toString in Creature
  override def toString = super.toString + "\n" + items.toString
}

object Avatar {

  // Used first time an avatar is created
  def apply(
      name: String,
      creature: CreatureType.Value,
      profession: ProfessionalType.Value): Avatar = {
    constructor(name, None, None, creature, profession)
  }

  // Used when the avatar already exists
  def apply(
      newItems: MagicalItemList,
      newFeatures: CreatureFeatureSet,
      avatar: Avatar): Avatar = {

    // Warning! Hard to manage this code
    val creatureType = avatar match {
      case e: Elf => CreatureType.Elf
      case d: Dwarf => CreatureType.Dwarf
      case _ => throw new Exception("Unknown creature type: " + avatar.name)
    }

    // Warning! Hard to manage this code
    val professionalType = avatar match {
      case t: Thief => ProfessionalType.Thief
      case w: Warrior => ProfessionalType.Warrior
      case m: Wizard => ProfessionalType.Wizard
      case _ => throw new Exception("Unknown profession: " + avatar.name)
    }

    constructor(avatar.name, Some(newFeatures), Some(newItems),
      creatureType, professionalType)
  }

  // Avatar main factory method
  private def constructor(
      name: String,
      optFeats: Option[CreatureFeatureSet],
      optItems: Option[MagicalItemList],
      creature: CreatureType.Value,
      profession: ProfessionalType.Value): Avatar = {

    // Warning! Hard to manage this code
    creature match {
      case CreatureType.Dwarf => {
        profession match {
          case ProfessionalType.Thief =>
            new Avatar(name, optFeats, optItems) with Dwarf with Thief
          case ProfessionalType.Warrior =>
            new Avatar(name, optFeats, optItems) with Dwarf with Warrior
          case ProfessionalType.Wizard =>
            new Avatar(name, optFeats, optItems) with Dwarf with Wizard
        }
      }
      case CreatureType.Elf => {
        profession match {
          case ProfessionalType.Thief =>
            new Avatar(name, optFeats, optItems) with Elf with Thief
          case ProfessionalType.Warrior =>
            new Avatar(name, optFeats, optItems) with Elf with Warrior
          case ProfessionalType.Wizard =>
            new Avatar(name, optFeats, optItems) with Elf with Wizard
        }
      }
    }
  }
}




Something went wrong with that request. Please try again.