Esempio n. 1
0
void CueStack::switchCue(int from, int to, const QList<Universe *> ua)
{
    qDebug() << Q_FUNC_INFO;

    Cue newCue;
    Cue oldCue;
    m_mutex.lock();
    if (to >= 0 && to < m_cues.size())
        newCue = m_cues[to];
    if (from >= 0 && from < m_cues.size())
        oldCue = m_cues[from];
    m_mutex.unlock();

    // Fade out the HTP channels of the previous cue
    QHashIterator <uint,uchar> oldit(oldCue.values());
    while (oldit.hasNext() == true)
    {
        oldit.next();

        FadeChannel fc;
        fc.setFixture(doc(), Fixture::invalidId());
        fc.setChannel(oldit.key());

        if (fc.group(doc()) == QLCChannel::Intensity)
        {
            fc.setElapsed(0);
            fc.setReady(false);
            fc.setTarget(0);
            fc.setFadeTime(oldCue.fadeOutSpeed());
            insertStartValue(fc, ua);
            m_fader->add(fc);
        }
    }

    // Fade in all channels of the new cue
    QHashIterator <uint,uchar> newit(newCue.values());
    while (newit.hasNext() == true)
    {
        newit.next();
        FadeChannel fc;

        fc.setFixture(doc(), Fixture::invalidId());
        fc.setChannel(newit.key());
        fc.setTarget(newit.value());
        fc.setElapsed(0);
        fc.setReady(false);
        fc.setFadeTime(newCue.fadeInSpeed());
        insertStartValue(fc, ua);
        m_fader->add(fc);
    }
}
Esempio n. 2
0
item recipe::create_result() const
{
    item newit( result_, calendar::turn, item::default_charges_tag{} );
    if( charges >= 0 ) {
        newit.charges = charges;
    }

    if( !newit.craft_has_charges() ) {
        newit.charges = 0;
    } else if( result_mult != 1 ) {
        // @todo Make it work for charge-less items
        newit.charges *= result_mult;
    }

    if( newit.has_flag( "VARSIZE" ) ) {
        newit.item_tags.insert( "FIT" );
    }

    if( contained == true ) {
        newit = newit.in_container( container );
    }

    return newit;
}
Esempio n. 3
0
void game::complete_craft()
{
 recipe making = recipes[u.activity.index]; // Which recipe is it?
 std::vector<component> will_use; // List of all items we're using, w/ count

// Up to 5 components / tools
 for (int i = 0; i < 5; i++) {
  if (making.components[i].size() > 0) {
// For each set of components in the recipe, fill you_have with the list of all
// matching ingredients the player has.
   std::vector<component> you_have;
   for (int j = 0; j < making.components[i].size(); j++) {
    if (u.has_amount(making.components[i][j].type,
                     making.components[i][j].count))
     you_have.push_back(making.components[i][j]);
   }

   if (you_have.size() == 1) // Only one, so we'll definitely use it
    will_use.push_back(component(you_have[0].type, you_have[0].count));
   else {	// Let the player pick which component they want to use
    WINDOW* w = newwin(you_have.size() + 2, 30, 10, 25);
    wborder(w, LINE_XOXO, LINE_XOXO, LINE_OXOX, LINE_OXOX,
               LINE_OXXO, LINE_OOXX, LINE_XXOO, LINE_XOOX );
    mvwprintz(w, 0, 5, c_red, "Use which component?");
    for (int j = 0; j < you_have.size(); j++)
     mvwprintz(w, j + 1, 1, c_white, "%d: %s", j + 1,
               itypes[you_have[j].type]->name.c_str());
    wrefresh(w);
    char ch;
    do
     ch = getch();
    while (ch < '1' || ch >= '1' + you_have.size());
    ch -= '1';
    will_use.push_back(component(you_have[ch].type, you_have[ch].count));
    delwin(w);
   }
  } // Done looking at components

// Use charges of any tools that require charges used
  if (making.tools[i].size() > 0) {
   for (int j = 0; j < making.tools[i].size(); j++) {
    if (making.tools[i][j].count > 0)
     u.use_charges(making.tools[i][j].type, making.tools[i][j].count);
   }
  }
 } // Done finding the components/tools needed

// # of dice is 75% primary skill, 25% secondary (unless secondary is null)
 int skill_dice = u.sklevel[making.sk_primary] * 3;
 if (making.sk_secondary == sk_null)
  skill_dice += u.sklevel[making.sk_primary];
 else
  skill_dice += u.sklevel[making.sk_secondary];
// Sides on dice is 16 plus your current intelligence
 int skill_sides = 16 + u.int_cur;

 int diff_dice = making.difficulty * 4; // Since skill level is * 4 also
 int diff_sides = 24;	// 16 + 8 (default intelligence)

 int skill_roll = dice(skill_dice, skill_sides);
 int diff_roll  = dice(diff_dice,  diff_sides);

 if (making.sk_primary != sk_null)
  u.practice(making.sk_primary, making.difficulty * 5 + 20);
 if (making.sk_secondary != sk_null)
  u.practice(making.sk_secondary, 5);

// Messed up badly; waste some components.
 if (making.difficulty != 0 && diff_roll > skill_roll * (1 + 0.1 * rng(1, 5))) {
  add_msg("You fail to make the %s, and waste some materials.",
          itypes[making.result]->name.c_str());
  int num_lost = rng(1, will_use.size());
  for (int i = 0; i < num_lost; i++) {
   int n = rng(0, will_use.size() - 1);
   if (itypes[will_use[n].type]->is_ammo() && will_use[i].type != itm_gasoline)
    u.use_charges(will_use[n].type, will_use[n].count);
   else
    u.use_amount(will_use[n].type, will_use[n].count);
   will_use.erase(will_use.begin() + n);
  }
  u.activity.type = ACT_NULL;
  return;
// Messed up slightly; no components wasted.
 } else if (diff_roll > skill_roll) {
  add_msg("You fail to make the %s, but don't waste any materials.",
          itypes[making.result]->name.c_str());
  u.activity.type = ACT_NULL;
  return;
 }
// If we're here, the craft was a success!
// Use up the items in will_use
 for (int i = 0; i < will_use.size(); i++) {
  if (itypes[will_use[i].type]->is_ammo() && will_use[i].type != itm_gasoline)
   u.use_charges(will_use[i].type, will_use[i].count);
  else
   u.use_amount(will_use[i].type, will_use[i].count);
 }

// Set up the new item, and pick an inventory letter
 int iter = 0;
 item newit(itypes[making.result], turn, nextinv);
 do {
  newit.invlet = nextinv;
  advance_nextinv();
  iter++;
 } while (u.has_item(newit.invlet) && iter < 52);
 newit = newit.in_its_container(&itypes);

// We might not have space for the item
 if (iter == 52 || u.volume_carried()+newit.volume() > u.volume_capacity()) {
  add_msg("There's no room in your inventory for the %s, so you drop it.",
          newit.tname().c_str());
  m.add_item(u.posx, u.posy, newit);
 } else if (u.weight_carried() + newit.volume() > u.weight_capacity()) {
  add_msg("The %s is too heavy to carry, so you drop it.",
          newit.tname().c_str());
  m.add_item(u.posx, u.posy, newit);
 } else {
  u.i_add(newit);
  add_msg("%c - %s", newit.invlet, newit.tname().c_str());
 }
}
Esempio n. 4
0
void player::complete_disassemble( int item_pos, const tripoint &loc,
                                   bool from_ground, const recipe &dis )
{
    // Get the proper recipe - the one for disassembly, not assembly
    const auto dis_requirements = dis.disassembly_requirements();
    item &org_item = get_item_for_uncraft( *this, item_pos, loc, from_ground );
    bool filthy = org_item.is_filthy();
    if( org_item.is_null() ) {
        add_msg( _( "The item has vanished." ) );
        activity.set_to_null();
        return;
    }

    if( org_item.typeId() != dis.result ) {
        add_msg( _( "The item might be gone, at least it is not at the expected position anymore." ) );
        activity.set_to_null();
        return;
    }
    // Make a copy to keep its data (damage/components) even after it
    // has been removed.
    item dis_item = org_item;

    float component_success_chance = std::min( std::pow( 0.8, dis_item.damage() ), 1.0 );

    add_msg( _( "You disassemble the %s into its components." ), dis_item.tname().c_str() );
    // Remove any batteries, ammo and mods first
    remove_ammo( &dis_item, *this );
    remove_radio_mod( dis_item, *this );

    if( dis_item.count_by_charges() ) {
        // remove the charges that one would get from crafting it
        org_item.charges -= dis.create_result().charges;
    }
    // remove the item, except when it's counted by charges and still has some
    if( !org_item.count_by_charges() || org_item.charges <= 0 ) {
        if( from_ground ) {
            g->m.i_rem( loc, item_pos );
        } else {
            i_rem( item_pos );
        }
    }

    // Consume tool charges
    for( const auto &it : dis_requirements.get_tools() ) {
        consume_tools( it );
    }

    // add the components to the map
    // Player skills should determine how many components are returned

    int skill_dice = 2 + get_skill_level( dis.skill_used ) * 3;
    skill_dice += get_skill_level( dis.skill_used );

    // Sides on dice is 16 plus your current intelligence
    ///\EFFECT_INT increases success rate for disassembling items
    int skill_sides = 16 + int_cur;

    int diff_dice = dis.difficulty;
    int diff_sides = 24; // 16 + 8 (default intelligence)

    // disassembly only nets a bit of practice
    if( dis.skill_used ) {
        practice( dis.skill_used, ( dis.difficulty ) * 2, dis.difficulty );
    }

    for( const auto &altercomps : dis_requirements.get_components() ) {
        const item_comp comp = find_component( altercomps, dis_item );
        int compcount = comp.count;
        item newit( comp.type, calendar::turn );
        // Counted-by-charge items that can be disassembled individually
        // have their component count multiplied by the number of charges.
        if( dis_item.count_by_charges() && dis.has_flag( "UNCRAFT_SINGLE_CHARGE" ) ) {
            compcount *= std::min( dis_item.charges, dis.create_result().charges );
        }
        // Compress liquids and counted-by-charges items into one item,
        // they are added together on the map anyway and handle_liquid
        // should only be called once to put it all into a container at once.
        if( newit.count_by_charges() || newit.made_of( LIQUID ) ) {
            newit.charges = compcount;
            compcount = 1;
        } else if( !newit.craft_has_charges() && newit.charges > 0 ) {
            // tools that can be unloaded should be created unloaded,
            // tools that can't be unloaded will keep their default charges.
            newit.charges = 0;
        }

        for( ; compcount > 0; compcount-- ) {
            const bool comp_success = ( dice( skill_dice, skill_sides ) > dice( diff_dice,  diff_sides ) );
            if( dis.difficulty != 0 && !comp_success ) {
                add_msg( m_bad, _( "You fail to recover %s." ), newit.tname().c_str() );
                continue;
            }
            const bool dmg_success = component_success_chance > rng_float( 0, 1 );
            if( !dmg_success ) {
                // Show reason for failure (damaged item, tname contains the damage adjective)
                //~ %1s - material, %2$s - disassembled item
                add_msg( m_bad, _( "You fail to recover %1$s from the %2$s." ), newit.tname().c_str(),
                         dis_item.tname().c_str() );
                continue;
            }
            // Use item from components list, or (if not contained)
            // use newit, the default constructed.
            item act_item = newit;

            if( filthy ) {
                act_item.item_tags.insert( "FILTHY" );
            }

            for( item::t_item_vector::iterator a = dis_item.components.begin(); a != dis_item.components.end();
                 ++a ) {
                if( a->type == newit.type ) {
                    act_item = *a;
                    dis_item.components.erase( a );
                    break;
                }
            }

            int veh_part = -1;
            vehicle *veh = g->m.veh_at( pos(), veh_part );
            if( veh != nullptr ) {
                veh_part = veh->part_with_feature( veh_part, "CARGO" );
            }

            if( act_item.made_of( LIQUID ) ) {
                g->handle_all_liquid( act_item, PICKUP_RANGE );
            } else if( veh_part != -1 && veh->add_item( veh_part, act_item ) ) {
                // add_item did put the items in the vehicle, nothing further to be done
            } else {
                // TODO: For items counted by charges, add as much as we can to the vehicle, and
                // the rest on the ground (see dropping code and @vehicle::add_charges)
                g->m.add_item_or_charges( pos(), act_item );
            }
        }
    }

    if( !dis.learn_by_disassembly.empty() && !knows_recipe( &dis ) ) {
        if( can_decomp_learn( dis ) ) {
            // @todo: make this depend on intelligence
            if( one_in( 4 ) ) {
                learn_recipe( &recipe_dict[ dis.ident() ] );
                add_msg( m_good, _( "You learned a recipe from disassembling it!" ) );
            } else {
                add_msg( m_info, _( "You might be able to learn a recipe if you disassemble another." ) );
            }
        } else {
            add_msg( m_info, _( "If you had better skills, you might learn a recipe next time." ) );
        }
    }
}
Esempio n. 5
0
void player::activate_mutation( const std::string &mut )
{
    const auto &mdata = mutation_branch::get( mut );
    auto &tdata = my_mutations[mut];
    int cost = mdata.cost;
    // You can take yourself halfway to Near Death levels of hunger/thirst.
    // Fatigue can go to Exhausted.
    if ((mdata.hunger && hunger >= 700) || (mdata.thirst && thirst >= 260) ||
      (mdata.fatigue && fatigue >= 575)) {
      // Insufficient Foo to *maintain* operation is handled in player::suffer
        add_msg(m_warning, _("You feel like using your %s would kill you!"), mdata.name.c_str());
        return;
    }
    if (tdata.powered && tdata.charge > 0) {
        // Already-on units just lose a bit of charge
        tdata.charge--;
    } else {
        // Not-on units, or those with zero charge, have to pay the power cost
        if (mdata.cooldown > 0) {
            tdata.charge = mdata.cooldown - 1;
        }
        if (mdata.hunger){
            hunger += cost;
        }
        if (mdata.thirst){
            thirst += cost;
        }
        if (mdata.fatigue){
            fatigue += cost;
        }
        tdata.powered = true;

        // Handle stat changes from activation
        apply_mods(mut, true);
        recalc_sight_limits();
    }

    if( mut == "WEB_WEAVER" ) {
        g->m.add_field(pos(), fd_web, 1, 0);
        add_msg(_("You start spinning web with your spinnerets!"));
    } else if (mut == "BURROW"){
        if (g->u.is_underwater()) {
            add_msg_if_player(m_info, _("You can't do that while underwater."));
            tdata.powered = false;
            return;
        }
        int dirx, diry;
        if (!choose_adjacent(_("Burrow where?"), dirx, diry)) {
            tdata.powered = false;
            return;
        }

        if (dirx == g->u.posx() && diry == g->u.posy()) {
            add_msg_if_player(_("You've got places to go and critters to beat."));
            add_msg_if_player(_("Let the lesser folks eat their hearts out."));
            tdata.powered = false;
            return;
        }
        int turns;
        if (g->m.is_bashable(dirx, diry) && g->m.has_flag("SUPPORTS_ROOF", dirx, diry) &&
            g->m.ter(dirx, diry) != t_tree) {
            // Takes about 100 minutes (not quite two hours) base time.
            // Being better-adapted to the task means that skillful Survivors can do it almost twice as fast.
            turns = (100000 - 5000 * g->u.skillLevel("carpentry"));
        } else if (g->m.move_cost(dirx, diry) == 2 && g->get_levz() == 0 &&
                   g->m.ter(dirx, diry) != t_dirt && g->m.ter(dirx, diry) != t_grass) {
            turns = 18000;
        } else {
            add_msg_if_player(m_info, _("You can't burrow there."));
            tdata.powered = false;
            return;
        }
        g->u.assign_activity(ACT_BURROW, turns, -1, 0);
        g->u.activity.placement = tripoint(dirx, diry,0);
        add_msg_if_player(_("You tear into the %s with your teeth and claws."),
                          g->m.tername(dirx, diry).c_str());
        tdata.powered = false;
        return; // handled when the activity finishes
    } else if (mut == "SLIMESPAWNER") {
        std::vector<tripoint> valid;
        for (int x = posx() - 1; x <= posx() + 1; x++) {
            for (int y = posy() - 1; y <= posy() + 1; y++) {
                tripoint dest(x, y, posz());
                if (g->is_empty(dest)) {
                    valid.push_back( dest );
                }
            }
        }
        // Oops, no room to divide!
        if (valid.size() == 0) {
            add_msg(m_bad, _("You focus, but are too hemmed in to birth a new slimespring!"));
            tdata.powered = false;
            return;
        }
        add_msg(m_good, _("You focus, and with a pleasant splitting feeling, birth a new slimespring!"));
        int numslime = 1;
        for (int i = 0; i < numslime && !valid.empty(); i++) {
            const tripoint target = random_entry_removed( valid );
            if (g->summon_mon("mon_player_blob", target)) {
                monster *slime = g->monster_at( target );
                slime->friendly = -1;
            }
        }
        //~ Usual enthusiastic slimespring small voices! :D
        if (one_in(3)) {
            add_msg(m_good, _("wow! you look just like me! we should look out for each other!"));
        } else if (one_in(2)) {
            add_msg(m_good, _("come on, big me, let's go!"));
        } else {
            add_msg(m_good, _("we're a team, we've got this!"));
        }
        tdata.powered = false;
        return;
    } else if (mut == "SHOUT1") {
        sounds::sound(pos(), 10 + 2 * str_cur, _("You shout loudly!"));
        tdata.powered = false;
        return;
    } else if (mut == "SHOUT2"){
        sounds::sound(pos(), 15 + 3 * str_cur, _("You scream loudly!"));
        tdata.powered = false;
        return;
    } else if (mut == "SHOUT3"){
        sounds::sound(pos(), 20 + 4 * str_cur, _("You let out a piercing howl!"));
        tdata.powered = false;
        return;
    } else if ((mut == "NAUSEA") || (mut == "VOMITOUS") ){
        vomit();
        tdata.powered = false;
        return;
    } else if (mut == "M_FERTILE"){
        spores();
        tdata.powered = false;
        return;
    } else if (mut == "M_BLOOM"){
        blossoms();
        tdata.powered = false;
        return;
    } else if (mut == "VINES3"){
        item newit("vine_30", calendar::turn, false);
        if (!can_pickVolume(newit.volume())) { //Accounts for result_mult
            add_msg(_("You detach a vine but don't have room to carry it, so you drop it."));
            g->m.add_item_or_charges(posx(), posy(), newit);
        } else if (!can_pickWeight(newit.weight(), !OPTIONS["DANGEROUS_PICKUPS"])) {
            add_msg(_("Your freshly-detached vine is too heavy to carry, so you drop it."));
            g->m.add_item_or_charges(posx(), posy(), newit);
        } else {
            inv.assign_empty_invlet(newit);
            newit = i_add(newit);
            add_msg(m_info, "%c - %s", newit.invlet == 0 ? ' ' : newit.invlet, newit.tname().c_str());
        }
        tdata.powered = false;
        return;
    }
}
Esempio n. 6
0
void game::complete_craft()
{
 recipe* making = recipes[u.activity.index]; // Which recipe is it?

// # of dice is 75% primary skill, 25% secondary (unless secondary is null)
 int skill_dice = u.sklevel[making->sk_primary] * 3;
 if (making->sk_secondary == sk_null)
  skill_dice += u.sklevel[making->sk_primary];
 else
  skill_dice += u.sklevel[making->sk_secondary];
// Sides on dice is 16 plus your current intelligence
 int skill_sides = 16 + u.int_cur;

 int diff_dice = making->difficulty * 4; // Since skill level is * 4 also
 int diff_sides = 24;	// 16 + 8 (default intelligence)

 int skill_roll = dice(skill_dice, skill_sides);
 int diff_roll  = dice(diff_dice,  diff_sides);

 if (making->sk_primary != sk_null)
  u.practice(making->sk_primary, making->difficulty * 5 + 20);
 if (making->sk_secondary != sk_null)
  u.practice(making->sk_secondary, 5);

// Messed up badly; waste some components.
 if (making->difficulty != 0 && diff_roll > skill_roll * (1 + 0.1 * rng(1, 5))) {
  add_msg("You fail to make the %s, and waste some materials.",
          itypes[making->result]->name.c_str());
  for (int i = 0; i < 5; i++) {
   if (making->components[i].size() > 0) {
    std::vector<component> copy = making->components[i];
    for (int j = 0; j < copy.size(); j++)
     copy[j].count = rng(0, copy[j].count);
    consume_items(this, copy);
   }
   if (making->tools[i].size() > 0)
    consume_tools(this, making->tools[i]);
  }
  u.activity.type = ACT_NULL;
  return;
  // Messed up slightly; no components wasted.
 } else if (diff_roll > skill_roll) {
  add_msg("You fail to make the %s, but don't waste any materials.",
          itypes[making->result]->name.c_str());
  u.activity.type = ACT_NULL;
  return;
 }
// If we're here, the craft was a success!
// Use up the components and tools
 for (int i = 0; i < 5; i++) {
  if (making->components[i].size() > 0)
   consume_items(this, making->components[i]);
  if (making->tools[i].size() > 0)
   consume_tools(this, making->tools[i]);
 }

  // Set up the new item, and pick an inventory letter
 int iter = 0;
 item newit(itypes[making->result], turn, nextinv);
 if (!newit.craft_has_charges())
  newit.charges = 0;
 do {
  newit.invlet = nextinv;
  advance_nextinv();
  iter++;
 } while (u.has_item(newit.invlet) && iter < 52);
 //newit = newit.in_its_container(&itypes);
 if (newit.made_of(LIQUID))
  handle_liquid(newit, false, false);
 else {
// We might not have space for the item
  if (iter == 52 || u.volume_carried()+newit.volume() > u.volume_capacity()) {
   add_msg("There's no room in your inventory for the %s, so you drop it.",
             newit.tname().c_str());
   m.add_item(u.posx, u.posy, newit);
  } else if (u.weight_carried() + newit.volume() > u.weight_capacity()) {
   add_msg("The %s is too heavy to carry, so you drop it.",
           newit.tname().c_str());
   m.add_item(u.posx, u.posy, newit);
  } else {
   u.i_add(newit);
   add_msg("%c - %s", newit.invlet, newit.tname().c_str());
  }
 }
}