Example #1
0
File: player.c Project: atrinik/dwc
/**
 * Give initial items to object pl. This is used when player creates a
 * new character.
 * @param pl The player object.
 * @param items Treasure list of items to give. */
void give_initial_items(object *pl, treasurelist *items)
{
	object *op, *next = NULL;

	if (pl->randomitems)
	{
		create_treasure(items, pl, GT_ONLY_GOOD | GT_NO_VALUE, 1, T_STYLE_UNSET, ART_CHANCE_UNSET, 0, NULL);
	}

	for (op = pl->inv; op; op = next)
	{
		next = op->below;

		/* Forces get applied by default */
		if (op->type == FORCE)
		{
			SET_FLAG(op, FLAG_APPLIED);
		}

		/* We never give weapons/armour if they cannot be used by this
		 * player due to race restrictions */
		if (pl->type == PLAYER)
		{
			if ((!QUERY_FLAG(pl, FLAG_USE_ARMOUR) && (op->type == ARMOUR || op->type == BOOTS || op->type == CLOAK || op->type == HELMET || op->type == SHIELD || op->type == GLOVES || op->type == BRACERS || op->type == GIRDLE)) || (!QUERY_FLAG(pl, FLAG_USE_WEAPON) && op->type == WEAPON))
			{
				/* Inventory action */
				remove_ob(op);
				continue;
			}
		}

		/* Give starting characters identified, uncursed, and undamned
		 * items. Just don't identify gold or silver, or it won't be
		 * merged properly. */
		if (need_identify(op))
		{
			SET_FLAG(op, FLAG_IDENTIFIED);
			CLEAR_FLAG(op, FLAG_CURSED);
			CLEAR_FLAG(op, FLAG_DAMNED);
		}

		/* Apply initial armor */
		if (IS_ARMOR(op))
		{
			manual_apply(pl, op, 0);
		}

		if (op->type == ABILITY)
		{
			CONTR(pl)->known_spells[CONTR(pl)->nrofknownspells++] = op->stats.sp;
			remove_ob(op);
			continue;
		}
	}
}
Example #2
0
/**
 * \copydoc Detector::notify_collision(MapEntity&, Sprite&, Sprite&)
 */
void Destructible::notify_collision(
    MapEntity& other_entity,
    Sprite& /* this_sprite */,
    Sprite& other_sprite
) {
  if (get_can_be_cut()
      && !is_being_cut
      && !is_waiting_for_regeneration()
      && !is_regenerating
      && other_entity.is_hero()) {

    Hero& hero = static_cast<Hero&>(other_entity);
    if (other_sprite.get_animation_set_id() == hero.get_hero_sprites().get_sword_sprite_id() &&
        hero.is_striking_with_sword(*this)) {

      play_destroy_animation();
      hero.check_position();  // To update the ground under the hero.
      create_treasure();

      get_lua_context().destructible_on_cut(*this);

      if (get_can_explode()) {
        explode();
      }
    }
  }

  // TODO use dynamic dispatch
  if (other_entity.get_type() == EntityType::EXPLOSION
      && get_can_explode()
      && !is_being_cut
      && !is_waiting_for_regeneration()
      && !is_regenerating) {

    play_destroy_animation();
    create_treasure();
    explode();
  }
}
Example #3
0
/**
 * \copydoc Detector::notify_action_command_pressed
 */
bool Destructible::notify_action_command_pressed() {

  KeysEffect::ActionKeyEffect effect = get_keys_effect().get_action_key_effect();

  if ((effect == KeysEffect::ACTION_KEY_LIFT || effect == KeysEffect::ACTION_KEY_LOOK)
      && get_weight() != -1
      && !is_being_cut
      && !is_waiting_for_regeneration()
      && !is_regenerating) {

    if (get_equipment().has_ability(Ability::LIFT, get_weight())) {

      uint32_t explosion_date = get_can_explode() ? System::now() + 6000 : 0;
      get_hero().start_lifting(std::make_shared<CarriedItem>(
          get_hero(),
          *this,
          get_animation_set_id(),
          get_destruction_sound(),
          get_damage_on_enemies(),
          explosion_date)
      );

      // Play the sound.
      Sound::play("lift");

      // Create the pickable treasure.
      create_treasure();

      if (!get_can_regenerate()) {
        // Remove this destructible from the map.
        remove_from_map();
      }
      else {
        // The item can actually regenerate.
        play_destroy_animation();
      }

      // Notify Lua.
      get_lua_context().destructible_on_lifting(*this);
    }
    else {
      // Cannot lift the object.
      get_hero().start_grabbing();
      get_lua_context().destructible_on_looked(*this);
    }

    return true;
  }

  return false;
}
Example #4
0
/**
 * This function handles those runes which detonate but do not cast
 * spells. Typically, poisoned or diseased runes.
 * @param op Rune.
 * @param victim Victim of the rune. */
static void rune_attack(object *op, object *victim)
{
	int dam = op->stats.dam;

	op->stats.dam = (sint16) ((float) dam * (LEVEL_DAMAGE(op->level) * 0.925f));

	if (victim)
	{
		tag_t tag = victim->count;
		hit_player(victim, op->stats.dam, op, AT_INTERNAL);

		if (was_destroyed(victim, tag))
		{
			op->stats.dam = dam;
			return;
		}

		/* If there's a disease in the needle, put it in the player */
		if (op->randomitems != NULL)
		{
			create_treasure(op->randomitems, op, 0, op->level ? op->level : victim->map->difficulty, T_STYLE_UNSET, ART_CHANCE_UNSET, 0, NULL);
		}

		if (op->inv && op->inv->type == DISEASE)
		{
			object *disease = op->inv;
			infect_object(victim, disease, 1);
			remove_ob(disease);
			check_walk_off(disease, NULL, MOVE_APPLY_VANISHED);
		}
	}
	else
	{
		hit_map(op, 0, 0);
	}

	op->stats.dam = dam;
}