<URL: http://bugs.freeciv.org/Ticket/Display.html?id=39354 >

There is a bug with tech_is_available such that when you have a tech who's
root_req is itself and you assign the tech with a nations init_tech the
server fails on an assert failure.  The problem was two fold in that you
could not simply do a check as the client loved using tech_is_available
while pplayer was null.  Below is a fix for the function, this is in
common/tech.c

bool tech_is_available(const struct player *pplayer, Tech_type_id id)
{
  int i;

  if (!tech_exists(id)) {
    return FALSE;
  }

  if (advances[id].root_req == id) {
    if (pplayer && pplayer->nation) {
      for (i = 0; i < MAX_NUM_TECH_LIST; i++) {
        if (pplayer->nation->init_techs[i] == A_LAST) {
          break;
        }
        if (pplayer->nation->init_techs[i] == id) {
          return TRUE;
        }
      }
      return FALSE;
    } else {
      return TRUE;
    }
  }


  if (advances[id].root_req != A_NONE
      && get_invention(pplayer, advances[id].root_req) != TECH_KNOWN) {
    /* This tech requires knowledge of another tech before being
     * available. Prevents sharing of untransferable techs. */
    return FALSE;
  }
  return TRUE;
}

There is a bug with tech_is_available such that when you have a tech who's root_req is itself and you assign the tech with a nations init_tech the server fails on an assert failure.  The problem was two fold in that you could not simply do a check as the client loved using tech_is_available while pplayer was null.  Below is a fix for the function, this is in common/tech.c

bool tech_is_available(const struct player *pplayer, Tech_type_id id)
{
  int i;

  if (!tech_exists(id)) {
    return FALSE;
  }

  if (advances[id].root_req == id) {
    if (pplayer && pplayer->nation) {
      for (i = 0; i < MAX_NUM_TECH_LIST; i++) {
        if (pplayer->nation->init_techs[i] == A_LAST) {
          break;
        }
        if (pplayer->nation->init_techs[i] == id) {
          return TRUE;
        }
      }
      return FALSE;
    } else {
      return TRUE;
    }
  }
        

  if (advances[id].root_req != A_NONE
      && get_invention(pplayer, advances[id].root_req) != TECH_KNOWN) {
    /* This tech requires knowledge of another tech before being
     * available. Prevents sharing of untransferable techs. */
    return FALSE;
  }
  return TRUE;


_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to