/** * 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; } } }
/** * \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(); } }
/** * \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; }
/** * 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; }