示例#1
0
文件: tech.c 项目: valisc/freeciv
/**************************************************************************
  Returns state of the tech for current pplayer.
  This can be: TECH_KNOWN, TECH_UNKNOWN, or TECH_PREREQS_KNOWN
  Should be called with existing techs or A_FUTURE

  If pplayer is NULL this checks whether any player knows the tech (used
  by the client).
**************************************************************************/
enum tech_state player_invention_state(const struct player *pplayer,
				       Tech_type_id tech)
{
  fc_assert_ret_val(tech == A_FUTURE
                    || (tech >= 0 && tech < game.control.num_tech_types),
                    -1);

  if (!pplayer) {
    if (tech != A_FUTURE && game.info.global_advances[tech]) {
      return TECH_KNOWN;
    } else {
      return TECH_UNKNOWN;
    }
  } else {
    struct player_research *research = player_research_get(pplayer);

    /* Research can be null in client when looking for tech_leakage
     * from player not yet received. */
    if (research) {
      return research->inventions[tech].state;
    } else {
      return TECH_UNKNOWN;
    }
  }
}
示例#2
0
文件: tech.c 项目: valisc/freeciv
/**************************************************************************
  Marks all techs which are requirements for goal in
  pplayer->research->inventions[goal].required_techs. Works recursive.
**************************************************************************/
static void build_required_techs_helper(struct player *pplayer,
					Tech_type_id tech,
					Tech_type_id goal)
{
  /* The is_tech_a_req_for_goal condition is true if the tech is
   * already marked */
  if (!player_invention_reachable(pplayer, tech, FALSE)
      || player_invention_state(pplayer, tech) == TECH_KNOWN
      || is_tech_a_req_for_goal(pplayer, tech, goal)) {
    return;
  }

  /* Mark the tech as required for the goal */
  BV_SET(player_research_get(pplayer)->inventions[goal].required_techs, tech);

  if (advance_required(tech, AR_ONE) == goal
      || advance_required(tech, AR_TWO) == goal) {
    log_fatal("tech \"%s\": requires itself",
              advance_name_by_player(pplayer, goal));
    exit(EXIT_FAILURE);
  }

  build_required_techs_helper(pplayer, advance_required(tech, AR_ONE), goal);
  build_required_techs_helper(pplayer, advance_required(tech, AR_TWO), goal);
}
示例#3
0
/****************************************************************************
  Player has researched a new technology
****************************************************************************/
static void tech_researched(struct player *plr)
{
  struct player_research *research = player_research_get(plr);
  /* plr will be notified when new tech is chosen */

  if (!is_future_tech(research->researching)) {
    notify_embassies(plr, NULL, NULL, E_TECH_GAIN, ftc_server,
                     _("The %s have researched %s."), 
                     nation_plural_for_player(plr),
                     advance_name_researching(plr));

  } else {
    notify_embassies(plr, NULL, NULL, E_TECH_GAIN, ftc_server,
                     _("The %s have researched Future Tech. %d."), 
                     nation_plural_for_player(plr),
                     research->future_tech);
  
  }

  /* Deduct tech cost */
  research->bulbs_researched = 
      MAX(research->bulbs_researched - total_bulbs_required(plr), 0);

  /* cache researched technology for event signal, because found_new_tech() changes the research goal */
  Tech_type_id researched_tech = research->researching;

  /* do all the updates needed after finding new tech */
  found_new_tech(plr, research->researching, TRUE, TRUE);

  script_server_signal_emit("tech_researched", 3,
                            API_TYPE_TECH_TYPE,
                            advance_by_number(researched_tech),
                            API_TYPE_PLAYER, plr,
                            API_TYPE_STRING, "researched");
}
示例#4
0
/**************************************************************************
  Reduce conquer cost bulbs from player.
**************************************************************************/
void do_conquer_cost(struct player *pplayer, Tech_type_id tech)
{
  struct player_research * research = player_research_get(pplayer);  

  research->bulbs_researched
    -= (base_total_bulbs_required(pplayer, tech) * game.server.conquercost) / 100;
  research->researching_saved = A_UNKNOWN;
}
示例#5
0
文件: tech.c 项目: valisc/freeciv
/**************************************************************************
  Returns if the given tech has to be researched to reach the
  goal. The goal itself isn't a requirement of itself.

  pplayer may be NULL; however the function will always return FALSE in
  that case.
**************************************************************************/
bool is_tech_a_req_for_goal(const struct player *pplayer, Tech_type_id tech,
			    Tech_type_id goal)
{
  if (tech == goal) {
    return FALSE;
  } else if (!pplayer) {
    /* FIXME: We need a proper implementation here! */
    return FALSE;
  } else {
    return
      BV_ISSET(player_research_get(pplayer)->inventions[goal].required_techs,
               tech);
  }
}
示例#6
0
文件: tech.c 项目: valisc/freeciv
/**************************************************************************
  Mark as TECH_PREREQS_KNOWN each tech which is available, not known and
  which has all requirements fullfiled.
  If there is no such a tech mark A_FUTURE as researchable.
  
  Recalculate research->num_known_tech_with_flag
  Should always be called after player_invention_set()
**************************************************************************/
void player_research_update(struct player *pplayer)
{
  enum tech_flag_id flag;
  int researchable = 0;
  struct player_research *research = player_research_get(pplayer);

  /* This is set when the game starts, but not everybody finds out
   * right away. */
  player_invention_set(pplayer, A_NONE, TECH_KNOWN);

  advance_index_iterate(A_FIRST, i) {
    if (!player_invention_reachable(pplayer, i, FALSE)) {
      player_invention_set(pplayer, i, TECH_UNKNOWN);
    } else {
      if (player_invention_state(pplayer, i) == TECH_PREREQS_KNOWN) {
        player_invention_set(pplayer, i, TECH_UNKNOWN);
      }

      if (player_invention_state(pplayer, i) == TECH_UNKNOWN
          && player_invention_state(pplayer, advance_required(i, AR_ONE))
             == TECH_KNOWN
          && player_invention_state(pplayer, advance_required(i, AR_TWO))
             == TECH_KNOWN) {
        player_invention_set(pplayer, i, TECH_PREREQS_KNOWN);
        researchable++;
      }
    }
    build_required_techs(pplayer, i);
  } advance_index_iterate_end;

#ifdef DEBUG_TECH
  advance_index_iterate(A_FIRST, i) {
    char buf[advance_count() + 1];

    advance_index_iterate(A_NONE, j) {
      if (BV_ISSET(research->inventions[i].required_techs, j)) {
        buf[j] = '1';
      } else {
        buf[j] = '0';
      }
    } advance_index_iterate_end;
    buf[advance_count()] = '\0';

    log_debug("%s: [%3d] %-25s => %s", player_name(pplayer), i,
              advance_rule_name(advance_by_number(i)),
              tech_state_name(player_invention_state(pplayer, i)));
    log_debug("%s: [%3d] %s", player_name(pplayer), i, buf);
  } advance_index_iterate_end;
示例#7
0
文件: tech.c 项目: valisc/freeciv
/**************************************************************************
  Set player knowledge about tech to given state.
**************************************************************************/
enum tech_state player_invention_set(struct player *pplayer,
				     Tech_type_id tech,
				     enum tech_state value)
{
  struct player_research *research = player_research_get(pplayer);
  enum tech_state old = research->inventions[tech].state;

  if (old == value) {
    return old;
  }
  research->inventions[tech].state = value;

  if (value == TECH_KNOWN) {
    game.info.global_advances[tech] = TRUE;
  }
  return old;
}
示例#8
0
文件: tech.c 项目: valisc/freeciv
/**************************************************************************
  Updates required_techs, num_required_techs and bulbs_required in
  pplayer->research->inventions[goal].
**************************************************************************/
static void build_required_techs(struct player *pplayer, Tech_type_id goal)
{
  int counter;
  struct player_research *research = player_research_get(pplayer);

  BV_CLR_ALL(research->inventions[goal].required_techs);
  
  if (player_invention_state(pplayer, goal) == TECH_KNOWN) {
    research->inventions[goal].num_required_techs = 0;
    research->inventions[goal].bulbs_required = 0;
    return;
  }
  
  build_required_techs_helper(pplayer, goal, goal);

  /* Include the goal tech */
  research->inventions[goal].bulbs_required =
      base_total_bulbs_required(pplayer, goal);
  research->inventions[goal].num_required_techs = 1;

  counter = 0;
  advance_index_iterate(A_FIRST, i) {
    if (!is_tech_a_req_for_goal(pplayer, i, goal)) {
      continue;
    }

    /* 
     * This is needed to get a correct result for the
     * base_total_bulbs_required call.
     */
    research->techs_researched++;
    counter++;

    research->inventions[goal].num_required_techs++;
    research->inventions[goal].bulbs_required +=
	base_total_bulbs_required(pplayer, i);
  } advance_index_iterate_end;

  /* Undo the changes made above */
  research->techs_researched -= counter;
}
示例#9
0
文件: plrdlg.cpp 项目: valisc/freeciv
/**************************************************************************
  Slot for selecting player/nation
**************************************************************************/
void plr_widget::nation_selected(const QItemSelection &sl,
                                 const QItemSelection &ds)
{
  QModelIndex index;
  QVariant qvar;
  QModelIndexList indexes = sl.indexes();
  struct city *pcity;
  const struct player_diplstate *state;
  struct player_research *research;
  char tbuf[256];
  QString res;
  QString sp = " ";
  QString nl = "<br>";
  struct player *pplayer;
  int a , b;
  bool added;
  bool entry_exist = false;
  struct player *me;
  Tech_type_id tech_id;

  other_player = NULL;
  intel_str.clear();
  tech_str.clear();
  ally_str.clear();
  if (indexes.isEmpty()) {
    plr->update_report();
    return;
  }
  index = indexes.at(0);
  qvar = index.data(Qt::UserRole);
  pplayer = reinterpret_cast<player *>(qvar.value<void *>());
  other_player = pplayer;
  if (pplayer->is_alive == false) {
    plr->update_report();
    return;
  }
  pcity = player_capital(pplayer);
  research = player_research_get(pplayer);

  switch (research->researching) {
  case A_UNKNOWN:
    res = _("(Unknown)");
    break;
  case A_UNSET:
    res = _("(none)");
    break;
  default:
    res = QString(advance_name_researching(pplayer))
          + sp + "(" + QString::number(research->bulbs_researched) + "/"
          + QString::number(total_bulbs_required(pplayer)) + ")";
    break;
  }
  /** Formatting rich text */
  intel_str =
    QString("<table><tr><td><b>") + _("Nation") + QString("</b></td><td>")
    + QString(nation_adjective_for_player(pplayer))
    + QString("</td><tr><td><b>") + N_("Ruler:") + QString("</b></td><td>")
    + QString(ruler_title_for_player(pplayer, tbuf, sizeof(tbuf)))
    + QString("</td></tr><tr><td><b>") + N_("Government:") 
    + QString("</b></td><td>") + QString(government_name_for_player(pplayer))
    + QString("</td></tr><tr><td><b>") + N_("Capital:")
    + QString("</b></td><td>")
    + QString(((!pcity) ? _("(unknown)") : city_name(pcity)))
    + QString("</td></tr><tr><td><b>") + N_("Gold:")
    + QString("</b></td><td>") + QString::number(pplayer->economic.gold)
    + QString("</td></tr><tr><td><b>") + N_("Tax:")
    + QString("</b></td><td>") + QString::number(pplayer->economic.tax)
    + QString("%</td></tr><tr><td><b>") + N_("Science:")
    + QString("</b></td><td>") + QString::number(pplayer->economic.science)
    + QString("%</td></tr><tr><td><b>") + N_("Luxury:")
    + QString("</b></td><td>") + QString::number(pplayer->economic.luxury)
    + QString("%</td></tr><tr><td><b>") + N_("Researching:")
    + QString("</b></td><td>") + res + QString("</td></table>");

  for (int i = 0; i < static_cast<int>(DS_LAST); i++) {
    added = false;
    if (entry_exist) {
      ally_str += "<br>";
    }
    entry_exist = false;
    players_iterate_alive(other) {
      if (other == pplayer) {
        continue;
      }
      state = player_diplstate_get(pplayer, other);
      if (static_cast<int>(state->type) == i) {
        if (added == false) {
          ally_str = ally_str  + QString("<b>")
                     + QString(diplstate_type_translated_name(
                                 static_cast<diplstate_type>(i)))
                     + ": "  + QString("</b>") + nl;
          added = true;
        }
        ally_str = ally_str + nation_plural_for_player(other) + ", ";
        entry_exist = true;
      }
    }
    players_iterate_alive_end;
    if (entry_exist) {
      ally_str.replace(ally_str.lastIndexOf(","), 1, ".");
    }
  }
  me = client_player();
  if ((player_has_embassy(me, pplayer) || client_is_global_observer())
      && me != pplayer) {
    a = 0;
    b = 0;
    techs_known = QString("<b>") + _("Techs unknown by") + sp
                  + QString(nation_adjective_for_player(pplayer)) + sp
                  + QString(_("nation")) + QString("</b> :");
    techs_unknown = QString("<b>") + _("Techs unkown by you") + sp
                    + QString("</b> :");

    advance_iterate(A_FIRST, padvance) {
      tech_id = advance_number(padvance);
      if (player_invention_state(me, tech_id) == TECH_KNOWN
          && (player_invention_state(pplayer, tech_id) == TECH_UNKNOWN)) {
        a++;
        techs_known = techs_known + QString("<i>") 
                      + advance_name_for_player(pplayer, tech_id)
                      + "," + QString("</i>") + sp;
      }
      if (player_invention_state(me, tech_id) == TECH_UNKNOWN
          && (player_invention_state(pplayer, tech_id) == TECH_KNOWN)) {
        b++;
        techs_unknown = techs_unknown + QString("<i>")
                        + advance_name_for_player(pplayer, tech_id)
                        + "," + QString("</i>") + sp;
      }
    } advance_iterate_end;