public String attack(Actor attacker, Actor target) {
    boolean playerAttacking = attacker.type.equals("player");
    boolean playerDefending = target.type.equals("player");
    if (target.status.equals("dead")) {
      assert playerAttacking;
      return "You "+attackMsgPlayer+" the "+target.name+"'s corpse.";
    }
    String returnString = "";
    double damage = (attacker.baseDamage+damageBoost)*damageMultiplier;
    if (Functions.pRand() < critChance) {
      damage *= 1.5;
      if (playerAttacking)
        returnString += "Your attack crits!\n";
      else
        returnString += "The "+attacker.name+"\'s attack crits!\n";
    }
    damage -= target.baseDefense;
    if (damage < 0)
      damage = 0;
    target.hp -= (int)damage;
    if (playerAttacking)
      returnString += "You "+attackMsgPlayer+" the "+target.name+" for "+Integer.toString((int)damage)+" damage.\n";
    else if (playerDefending)
      returnString += "The "+attacker.name+" "+attackMsgOther+" you for "+Integer.toString((int)damage)+" damage.\n";
    if (target.hp <= 0) {
      returnString += target.die();
      returnString += attacker.kill(target);
    }
    else {
      target.hasBeenAttacked = true;
    }
    while (playerAttacking && returnString.charAt(returnString.length()-1) == '\n')
      returnString = returnString.substring(0,returnString.length()-1);
    return returnString;
  }