Пример #1
0
void CreatureAttributes::consume(Creature* self, const CreatureAttributes& other) {
  Debug() << name->bare() << " consume " << other.name->bare();
  self->you(MsgType::CONSUME, other.name->the());
  consumeBodyParts(self, other);
  if (other.isHumanoid() && !isHumanoid() && numBodyParts(BodyPart::ARM) >= 2 && numBodyParts(BodyPart::LEG) >= 2
      && numBodyParts(BodyPart::HEAD) >= 1) {
    self->you(MsgType::BECOME, "a humanoid");
    self->addPersonalEvent(getName().the() + " turns into a humanoid");
    humanoid = true;
  }
  vector<string> adjectives;
  for (auto t : ENUM_ALL(AttrType))
    consumeAttr(attr[t], other.attr[t], adjectives, getAttrNameMore(t));
  consumeAttr(*size, *other.size, adjectives, "larger");
  consumeAttr(*weight, *other.weight, adjectives, "");
  consumeAttr(barehandedDamage, other.barehandedDamage, adjectives, "more dangerous");
  consumeAttr(barehandedAttack, other.barehandedAttack, adjectives, "");
  consumeAttr(attackEffect, other.attackEffect, adjectives, "");
  consumeAttr(passiveAttack, other.passiveAttack, adjectives, "");
  consumeAttr(gender, other.gender, adjectives);
  consumeAttr(skills, other.skills, adjectives);
  if (!adjectives.empty()) {
    self->you(MsgType::BECOME, combine(adjectives));
    self->addPersonalEvent(getName().the() + " becomes " + combine(adjectives));
  }
  consumeBodyParts(self,other);
  consumeEffects(other.permanentEffects);
}
Пример #2
0
optional<Sound> CreatureAttributes::getDeathSound() const {
  if (noDyingSound)
    return none;
  else
    return Sound(dyingSound ? *dyingSound : isHumanoid() ? SoundId::HUMANOID_DEATH : SoundId::BEAST_DEATH)
        .setPitch(getDeathSoundPitch(getSize()));
}
Пример #3
0
AttackType CreatureAttributes::getAttackType(const Item* weapon) const {
  if (weapon)
    return weapon->getAttackType();
  else if (barehandedAttack)
    return *barehandedAttack;
  else
    return isHumanoid() ? AttackType::PUNCH : AttackType::BITE;
}
Пример #4
0
string CreatureAttributes::getDescription() const {
  if (!isSpecial)
    return "";
  string attack;
  if (attackEffect)
    attack = " It has a " + Effect::getName(*attackEffect) + " attack.";
  return adjectives(getSize(), isUndead(), notLiving) +
      (isHumanoid() ? " humanoid" : " beast") + (!isCorporal() ? " spirit" : "") +
      bodyDescription() + ". " + attack;
}
Пример #5
0
vector<AttackLevel> CreatureAttributes::getAttackLevels() const {
  if (isHumanoid() && !numGood(BodyPart::ARM))
    return {AttackLevel::LOW};
  switch (getSize()) {
    case CreatureSize::SMALL: return {AttackLevel::LOW};
    case CreatureSize::MEDIUM: return {AttackLevel::LOW, AttackLevel::MIDDLE};
    case CreatureSize::LARGE: return {AttackLevel::LOW, AttackLevel::MIDDLE, AttackLevel::HIGH};
    case CreatureSize::HUGE: return {AttackLevel::MIDDLE, AttackLevel::HIGH};
  }
}
Пример #6
0
string CreatureAttributes::bodyDescription() const {
  vector<string> ret;
  for (BodyPart part : {BodyPart::ARM, BodyPart::LEG, BodyPart::WING})
    if (int num = numBodyParts(part))
      ret.push_back(getPlural(getBodyPartName(part), num));
  if (isHumanoid() && numBodyParts(BodyPart::HEAD) == 0)
    ret.push_back("no head");
  if (ret.size() > 0)
    return " with " + combine(ret);
  else
    return "";
}
Пример #7
0
void draw_monsters() {
	short i,j = 0,k;
	short width,height;
	rectangle source_rect,to_rect;
	location where_draw,store_loc;
	ter_num_t ter;
	rectangle monst_rects[4][4] = {
		{{0,0,36,28}},
		{{0,7,18,21},{18,7,36,21}},
		{{9,0,27,14},{9,14,27,28}},
		{{0,0,18,14},{0,14,18,28},{18,0,36,14},{18,14,36,28}}
	};
	
	if(is_out())
		for(i = 0; i < 10; i++)
			if(univ.party.out_c[i].exists) {
				if((point_onscreen(univ.party.p_loc, univ.party.out_c[i].m_loc)) &&
					(can_see_light(univ.party.p_loc, univ.party.out_c[i].m_loc,sight_obscurity) < 5)) {
					where_draw.x = univ.party.out_c[i].m_loc.x - univ.party.p_loc.x + 4;
					where_draw.y = univ.party.out_c[i].m_loc.y - univ.party.p_loc.y + 4;
					
					for(j = 0; univ.party.out_c[i].what_monst.monst[j] == 0 && j < 7; j++);
					
					short picture_wanted;
					if(j == 7) univ.party.out_c[i].exists = false; // begin watch out
					else {
						picture_wanted = get_monst_picnum(univ.party.out_c[i].what_monst.monst[j]);
					} // end watch out
					
					if(univ.party.out_c[i].exists) {
						get_monst_dims(univ.party.out_c[i].what_monst.monst[j],&width,&height);
						if(picture_wanted >= 1000) {
							for(k = 0; k < width * height; k++) {
								sf::Texture* src_gw;
								graf_pos_ref(src_gw, source_rect) = spec_scen_g.find_graphic(picture_wanted % 1000 +
																							 ((univ.party.out_c[i].direction < 4) ? 0 : (width * height)) + k);
								to_rect = monst_rects[(width - 1) * 2 + height - 1][k];
								to_rect.offset(13 + 28 * where_draw.x,13 + 36 * where_draw.y);
								rect_draw_some_item(*src_gw, source_rect, terrain_screen_gworld,to_rect, sf::BlendAlpha);
							}
						}
						if(picture_wanted < 1000) {
							for(k = 0; k < width * height; k++) {
								source_rect = get_monster_template_rect(picture_wanted,(univ.party.out_c[i].direction < 4) ? 0 : 1,k);
								to_rect = monst_rects[(width - 1) * 2 + height - 1][k];
								to_rect.offset(13 + 28 * where_draw.x,13 + 36 * where_draw.y);
								int which_sheet = m_pic_index[picture_wanted].i / 20;
								sf::Texture& monst_gworld = *ResMgr::get<ImageRsrc>("monst" + std::to_string(1 + which_sheet));
								rect_draw_some_item(monst_gworld, source_rect, terrain_screen_gworld,to_rect, sf::BlendAlpha);
							}
						}
					}
				}
			}
	if(is_town() || is_combat()) {
		for(i = 0; i < univ.town.monst.size(); i++)
			if(univ.town.monst[i].active != 0 && !univ.town.monst[i].invisible && univ.town.monst[i].status[eStatus::INVISIBLE] <= 0)
				if(point_onscreen(center,univ.town.monst[i].cur_loc) && party_can_see_monst(i)) {
					where_draw.x = univ.town.monst[i].cur_loc.x - center.x + 4;
					where_draw.y = univ.town.monst[i].cur_loc.y - center.y + 4;
					get_monst_dims(univ.town.monst[i].number,&width,&height);
					
					for(k = 0; k < width * height; k++) {
						store_loc = where_draw;
						store_loc.x += k % width;
						store_loc.y += k / width;
						ter = univ.town->terrain(univ.town.monst[i].cur_loc.x,univ.town.monst[i].cur_loc.y);
						// in bed?
						if(store_loc.x >= 0 && store_loc.x < 9 && store_loc.y >= 0 && store_loc.y < 9 &&
						   (univ.scenario.ter_types[ter].special == eTerSpec::BED) && isHumanoid(univ.town.monst[i].m_type)
						   && (univ.town.monst[i].active == 1 || univ.town.monst[i].target == 6) &&
						   width == 1 && height == 1)
							draw_one_terrain_spot((short) where_draw.x,(short) where_draw.y,10000 + univ.scenario.ter_types[ter].flag1);
						else if(univ.town.monst[i].picture_num >= 1000) {
							bool isParty = univ.town.monst[i].picture_num >= 10000;
							sf::Texture* src_gw;
							pic_num_t need_pic = (univ.town.monst[i].picture_num % 1000) + k;
							if(univ.town.monst[i].direction >= 4) need_pic += width * height;
							if(combat_posing_monster == i + 100) need_pic += (2 * width * height);
							graf_pos_ref(src_gw, source_rect) = spec_scen_g.find_graphic(need_pic, isParty);
							Draw_Some_Item(*src_gw, source_rect, terrain_screen_gworld, store_loc, 1, 0);
						} else {
							pic_num_t this_monst = univ.town.monst[i].picture_num;
							int pic_mode = (univ.town.monst[i].direction) < 4 ? 0 : 1;
							pic_mode += (combat_posing_monster == i + 100) ? 10 : 0;
							source_rect = get_monster_template_rect(this_monst, pic_mode, k);
							int which_sheet = m_pic_index[this_monst].i / 20;
							sf::Texture& monst_gworld = *ResMgr::get<ImageRsrc>("monst" + std::to_string(1 + which_sheet));
							Draw_Some_Item(monst_gworld, source_rect, terrain_screen_gworld, store_loc, 1, 0);
						}
					}
				}
	}
}