Esempio n. 1
0
 virtual void specialTick(double time, Position position) override {
   if (rottenTime == -1)
     rottenTime = time + rottingTime;
   if (time >= rottenTime && !rotten) {
     setName(rottenName);
     setViewObject(object2);
     corpseInfo.isSkeleton = true;
   } else {
     if (!rotten && getWeight() > 10 && Random.roll(20 + (rottenTime - time) / 10))
       Effect::applyToPosition(position, EffectId::EMIT_POISON_GAS, EffectStrength::WEAK);
     if (getWeight() > 10 && !corpseInfo.isSkeleton && 
         !position.getCoverInfo().covered && Random.roll(35)) {
       for (Position v : position.neighbors8(Random)) {
         PCreature vulture = CreatureFactory::fromId(CreatureId::VULTURE,
             position.getModel()->getPestTribe(), MonsterAIFactory::scavengerBird(v));
         if (v.canEnter(vulture.get())) {
           v.addCreature(std::move(vulture));
           v.globalMessage("A vulture lands near " + getTheName());
           rottenTime -= 40;
           break;
         }
       }
     }
   }
 }
Esempio n. 2
0
variant<AvatarInfo, AvatarMenuOption> getAvatarInfo(View* view, const PlayerCreaturesInfo* creatures, Options* options,
    CreatureFactory* creatureFactory) {
  auto keeperCreatureInfos = creatures->first;
  auto keeperCreatures = keeperCreatureInfos.transform([&](auto& elem) {
    return elem.creatureId.transform([&](auto& id) {
      auto ret = creatureFactory->fromId(id, getPlayerTribeId(elem.tribeAlignment));
      for (auto& trait : elem.specialTraits)
        applySpecialTrait(trait, ret.get());
      return ret;
    });
  });
  auto adventurerCreatureInfos = creatures->second;
  auto adventurerCreatures = adventurerCreatureInfos.transform([&](auto& elem) {
    return elem.creatureId.transform([&](auto& id) {
      return creatureFactory->fromId(id, getPlayerTribeId(elem.tribeAlignment));
    });
  });
  vector<View::AvatarData> keeperAvatarData;
  for (int i : All(keeperCreatures))
    keeperAvatarData.push_back(View::AvatarData {
      keeperCreatures[i].transform([](const auto& c) { return getUpgradedViewId(c.get()); }),
      keeperCreatures[i].transform([](const auto& c) { return c->getName().firstOrBare(); }),
      keeperCreatureInfos[i].tribeAlignment,
      keeperCreatures[i][0]->getName().identify(),
      PlayerRole::KEEPER,
      keeperCreatureInfos[i].description
    });
  vector<View::AvatarData> adventurerAvatarData;
  for (int i : All(adventurerCreatures))
    adventurerAvatarData.push_back(View::AvatarData {
      adventurerCreatures[i].transform([](const auto& c) { return getUpgradedViewId(c.get()); }),
      adventurerCreatures[i].transform([](const auto& c) { return c->getName().firstOrBare(); }),
      adventurerCreatureInfos[i].tribeAlignment,
      adventurerCreatures[i][0]->getName().identify(),
      PlayerRole::ADVENTURER,
      adventurerCreatureInfos[i].description
    });
  auto result1 = view->chooseAvatar(concat(keeperAvatarData, adventurerAvatarData), options);
  if (auto option = result1.getValueMaybe<AvatarMenuOption>())
    return *option;
  auto result = result1.getReferenceMaybe<View::AvatarChoice>();
  variant<KeeperCreatureInfo, AdventurerCreatureInfo> creatureInfo;
  PCreature ret;
  if (result->creatureIndex < keeperCreatures.size()) {
    creatureInfo = creatures->first[result->creatureIndex];
    ret = std::move(keeperCreatures[result->creatureIndex][result->genderIndex]);
    ret->getName().setBare("Keeper");
  } else {
    creatureInfo = creatures->second[result->creatureIndex - keeperCreatures.size()];
    ret = std::move(adventurerCreatures[result->creatureIndex - keeperCreatures.size()][result->genderIndex]);
    ret->getName().setBare("Adventurer");
  }
  auto villains = creatureInfo.visit([](const auto& elem) { return elem.tribeAlignment;});
  return AvatarInfo{std::move(ret), creatureInfo, villains };
}
Esempio n. 3
0
PCreature TimeQueue::removeCreature(Creature* cRef) {
  int ind = -1;
  for (int i : All(creatures))
    if (creatures[i].get() == cRef) {
      ind = i;
      break;
    }
  CHECK(ind > -1) << "Creature not found";
  PCreature ret = std::move(creatures[ind]);
  creatures.erase(creatures.begin() + ind);
  dead.insert(ret.get());
  return ret;
}
Esempio n. 4
0
bool Level::landCreature(vector<Position> landing, PCreature creature) {
  if (landCreature(landing, creature.get())) {
    model->addCreature(std::move(creature));
    return true;
  } else
    return false;
}
Esempio n. 5
0
bool Level::landCreature(StairKey key, PCreature creature) {
  if (landCreature(key, creature.get())) {
    model->addCreature(std::move(creature));
    return true;
  } else
    return false;
}
Esempio n. 6
0
void Level::addCreature(Vec2 position, PCreature c) {
  Creature* ref = c.get();
  model->addCreature(std::move(c));
  putCreature(position, ref);
}
Esempio n. 7
0
Vec2 Level::landCreature(vector<Vec2> landing, PCreature creature) {
  Vec2 pos = landCreature(landing, creature.get());
  model->addCreature(std::move(creature));
  return pos;
}
Esempio n. 8
0
Vec2 Level::landCreature(StairDirection direction, StairKey key, PCreature creature) {
  Vec2 pos = landCreature(direction, key, creature.get());
  model->addCreature(std::move(creature));
  return pos;
}
Esempio n. 9
0
void TimeQueue::addCreature(PCreature c) {
  queue.push({c.get(), c->getTime()});
  creatures.push_back(std::move(c));
}
Esempio n. 10
0
void Level::Builder::putCreature(Vec2 pos, PCreature creature) {
  creature->setPosition(transform(pos));
  creatures.push_back(NOTNULL(std::move(creature)));
}
Esempio n. 11
0
void Deity::onPrayer(Creature* c) {
  bool prayerAnswered = false;
  for (Epithet epithet : randomPermutation(epithets)) {
    if (contains(usedEpithets, epithet))
      continue;
    bool noEffect = false;
    switch (epithet) {
      case Epithet::DEATH: {
          PCreature death = CreatureFactory::fromId(CreatureId::DEATH, Tribes::get(TribeId::KILL_EVERYONE));
          for (Vec2 v : c->getPosition().neighbors8(true))
            if (c->getLevel()->inBounds(v) && c->getLevel()->getSquare(v)->canEnter(death.get())) {
              c->privateMessage("Death appears before you.");
              c->getLevel()->addCreature(v, std::move(death));
              break;
            }
          if (death)
            noEffect = true;
          break; }
      case Epithet::WAR:
          grantGift(c, chooseRandom(
          {ItemId::SPECIAL_SWORD, ItemId::SPECIAL_BATTLE_AXE, ItemId::SPECIAL_WAR_HAMMER}), name); break;
      case Epithet::WISDOM: grantGift(c, 
          chooseRandom({ItemId::MUSHROOM_BOOK, ItemId::POTION_BOOK, ItemId::AMULET_BOOK}), name); break;
      case Epithet::DESTRUCTION: applyEffect(c, EffectType::DESTROY_EQUIPMENT, ""); break;
      case Epithet::SECRETS: grantGift(c, ItemId::INVISIBLE_POTION, name); break;
      case Epithet::LIGHTNING:
          c->bleed(0.9);
          c->you(MsgType::ARE, "struck by a lightning bolt!");
          break;
      case Epithet::FEAR: applyEffect(c, EffectType::PANIC, name + " puts fear in your heart"); break;
      case Epithet::MIND: 
          if (Random.roll(2))
            applyEffect(c, EffectType::RAGE, name + " fills your head with anger");
          else
            applyEffect(c, EffectType::HALLU, "");
          break;
      case Epithet::CHANGE:
          if (Random.roll(2) && c->getEquipment().getItem(EquipmentSlot::WEAPON)) {
            PCreature snake = CreatureFactory::fromId(CreatureId::SNAKE, Tribes::get(TribeId::PEST));
            for (Vec2 v : c->getPosition().neighbors8(true))
              if (c->getLevel()->inBounds(v) && c->getLevel()->getSquare(v)->canEnter(snake.get())) {
                c->getLevel()->addCreature(v, std::move(snake));
                c->steal({c->getEquipment().getItem(EquipmentSlot::WEAPON)});
                c->privateMessage("Ouch!");
                c->you(MsgType::YOUR, "weapon turns into a snake!");
                break;
              }
            if (!snake)
              break;
          }
          for (Item* it : randomPermutation(c->getEquipment().getItems())) {
            if (it->getType() == ItemType::POTION) {
              c->privateMessage("Your " + it->getName() + " changes color!");
              c->steal({it});
              c->take(ItemFactory::potions().random());
              break;
            }
            if (it->getType() == ItemType::SCROLL) {
              c->privateMessage("Your " + it->getName() + " changes label!");
              c->steal({it});
              c->take(ItemFactory::scrolls().random());
              break;
            }
            if (it->getType() == ItemType::AMULET) {
              c->privateMessage("Your " + it->getName() + " changes shape!");
              c->steal({it});
              c->take(ItemFactory::amulets().random());
              break;
            }
          }
          break;
      case Epithet::HEALTH:
          if (c->getHealth() < 1 || c->lostLimbs())
            applyEffect(c, EffectType::HEAL, "You feel a healing power overcoming you");
          else {
            if (Random.roll(4))
              grantGift(c, ItemId::HEALING_AMULET, name);
            else
              grantGift(c, ItemId::HEALING_POTION, name, Random.getRandom(1, 4));
          }
          break;
      case Epithet::NATURE: grantGift(c, ItemId::FRIENDLY_ANIMALS_AMULET, name); break;
//      case Epithet::LOVE: grantGift(c, ItemId::PANIC_MUSHROOM, name); break;
      case Epithet::WEALTH: grantGift(c, ItemId::GOLD_PIECE, name, Random.getRandom(100, 200)); break;
      case Epithet::DEFENSE: grantGift(c, ItemId::DEFENSE_AMULET, name); break;
      case Epithet::DARKNESS: applyEffect(c, EffectType::BLINDNESS, ""); break;
      case Epithet::CRAFTS: applyEffect(c,
          chooseRandom({EffectType::ENHANCE_ARMOR, EffectType::ENHANCE_WEAPON}), ""); break;
//      case Epithet::HUNTING: grantGift(c, ItemId::PANIC_MUSHROOM, name); break;
      default: noEffect = true;
    }
    usedEpithets.push_back(epithet);
    if (!noEffect) {
      prayerAnswered = true;
      break;
    }
  }
  if (!prayerAnswered)
    c->privateMessage("Your prayer is not answered.");
}