Exemplo n.º 1
0
void Item_modifier::modify(item &new_item) const
{

    if(new_item.is_null()) {
        return;
    }

    new_item.damage = std::min( std::max( (int) rng( damage.first, damage.second ), MIN_ITEM_DAMAGE ), MAX_ITEM_DAMAGE );

    long ch = (charges.first == charges.second) ? charges.first : rng(charges.first, charges.second);

    if(ch != -1) {
        if( new_item.count_by_charges() || new_item.made_of( LIQUID ) ) {
            // food, ammo
            // count_by_charges requires that charges is at least 1. It makes no sense to
            // spawn a "water (0)" item.
            new_item.charges = std::max( 1l, ch );
        } else if( new_item.is_tool() ) {
            const auto qty = std::min( ch, new_item.ammo_capacity() );
            new_item.charges = qty;
            if( new_item.ammo_type() != "NULL" && qty > 0 ) {
                new_item.ammo_set( new_item.ammo_type(), qty );
            }
        } else if( !new_item.is_gun() ) {
            //not gun, food, ammo or tool. 
            new_item.charges = ch;
        }
    }
    
    if( new_item.is_gun() && ( ammo.get() != nullptr || ch > 0 ) ) {
        if( ammo.get() == nullptr ) {
            // In case there is no explicit ammo item defined, use the default ammo
            if( new_item.ammo_type() != "NULL" ) {
                new_item.charges = ch;
                new_item.set_curammo( new_item.ammo_type() );
            }
        } else {
            const item am = ammo->create_single( new_item.bday );
            new_item.set_curammo( am );
            // Prefer explicit charges of the gun, else take the charges of the ammo item,
            // Gun charges are easier to define: {"item":"gun","charge":10,"ammo-item":"ammo"}
            if( ch > 0 ) {
                new_item.charges = ch;
            } else {
                new_item.charges = am.charges;
            }
        }
        // Make sure the item is in valid state
        if( new_item.ammo_data() && new_item.magazine_integral() ) {
            new_item.charges = std::min( new_item.charges, new_item.ammo_capacity() );
        } else {
            new_item.charges = 0;
        }
    }

    if(container.get() != NULL) {
        item cont = container->create_single(new_item.bday);
        if (!cont.is_null()) {
            if (new_item.made_of(LIQUID)) {
                long rc = cont.get_remaining_capacity_for_liquid(new_item);
                if(rc > 0 && (new_item.charges > rc || ch == -1)) {
                    // make sure the container is not over-full.
                    // fill up the container (if using default charges)
                    new_item.charges = rc;
                }
            }
            cont.put_in(new_item);
            new_item = cont;
        }
    }
    if (contents.get() != NULL) {
        Item_spawn_data::ItemList contentitems = contents->create(new_item.bday);
        new_item.contents.insert(new_item.contents.end(), contentitems.begin(), contentitems.end());
    }
}
Exemplo n.º 2
0
void Item_modifier::modify(item &new_item) const
{

    if(new_item.is_null()) {
        return;
    }

    new_item.damage = std::min( std::max( (int) rng( damage.first, damage.second ), MIN_ITEM_DAMAGE ), MAX_ITEM_DAMAGE );

    long ch = (charges.first == charges.second) ? charges.first : rng(charges.first, charges.second);
    const auto g = new_item.type->gun.get();
    const auto t = dynamic_cast<const it_tool *>(new_item.type);
   
    if(ch != -1) {
        if( new_item.count_by_charges() || new_item.made_of( LIQUID ) ) {
            // food, ammo
            // count_by_charges requires that charges is at least 1. It makes no sense to
            // spawn a "water (0)" item.
            new_item.charges = std::max( 1l, ch );
        } else if(t != NULL) {
            new_item.charges = std::min(ch, t->max_charges);
        } else if (g == nullptr){
            //not gun, food, ammo or tool. 
            new_item.charges = ch;
        }
    }
    
    if( g != nullptr && ( ammo.get() != nullptr || ch > 0 ) ) {
        if( ammo.get() == nullptr ) {
            // In case there is no explicit ammo item defined, use the default ammo
            const auto ammoid = default_ammo( g->ammo );
            if ( !ammoid.empty() ) {
                new_item.set_curammo( ammoid );
                new_item.charges = ch;
            }
        } else {
            const item am = ammo->create_single( new_item.bday );
            new_item.set_curammo( am );
            // Prefer explicit charges of the gun, else take the charges of the ammo item,
            // Gun charges are easier to define: {"item":"gun","charge":10,"ammo-item":"ammo"}
            if( ch > 0 ) {
                new_item.charges = ch;
            } else {
                new_item.charges = am.charges;
            }
        }
        // Make sure the item is in a valid state curammo==0 <=> charges==0 and respect clip size
        if( !new_item.has_curammo() ) {
            new_item.charges = 0;
        } else {
            new_item.charges = std::min<long>( new_item.charges, new_item.clip_size() );
        }
    }
    if(container.get() != NULL) {
        item cont = container->create_single(new_item.bday);
        if (!cont.is_null()) {
            if (new_item.made_of(LIQUID)) {
                long rc = cont.get_remaining_capacity_for_liquid(new_item);
                if(rc > 0 && (new_item.charges > rc || ch == -1)) {
                    // make sure the container is not over-full.
                    // fill up the container (if using default charges)
                    new_item.charges = rc;
                }
            }
            cont.put_in(new_item);
            new_item = cont;
        }
    }
    if (contents.get() != NULL) {
        Item_spawn_data::ItemList contentitems = contents->create(new_item.bday);
        new_item.contents.insert(new_item.contents.end(), contentitems.begin(), contentitems.end());
    }
}