示例#1
0
/*
 * Put artefact into cave after finished movement.
 */
void put_artefact_into_cave (db_t *database, int artefactID, int caveID)
{
  dstring_t *ds;

  ds = dstring_new("UPDATE " DB_TABLE_ARTEFACT " SET caveID = %d "
         "WHERE artefactID = %d "
         "AND caveID = 0 "
         "AND initiated = %d",
     caveID, artefactID, ARTEFACT_UNINITIATED);
  db_query_dstring(database, ds);

  debug(DEBUG_ARTEFACT, "put_artefact_into_cave: %s", dstring_str(ds));

  /* Bedingung: Artefakt muss vorhanden sein; darf in keiner anderen Höhle liegen; */
  /*   muss uninitialisiert sein */
  if (db_affected_rows(database) != 1)
    throw(BAD_ARGUMENT_EXCEPTION, "put_artefact_into_cave: no such artefactID or "
                             "artefact already in another cave or not uninitiated");

  ds = dstring_new("UPDATE Cave SET artefacts = artefacts + 1 "
         "WHERE caveID = %d", caveID);
  db_query_dstring(database, ds);

  debug(DEBUG_ARTEFACT, "put_artefact_into_cave: %s", dstring_str(ds));

  /* Bedingung: Höhle muss vorhanden sein */
  if (db_affected_rows(database) != 1)
    throw(SQL_EXCEPTION, "put_artefact_into_cave: no such caveID");
}
示例#2
0
int new_artefact (db_t *database, int artefactClassID)
{
  db_result_t *result;
  dstring_t *ds;

  /* get artefact class */
  ds = dstring_new("SELECT * FROM " DB_TABLE_ARTEFACT_CLASS
            " WHERE artefactClassID = %d", artefactClassID);
  result = db_query_dstring(database, ds);

  debug(DEBUG_ARTEFACT, "new_artefact: %s", dstring_str(ds));

  /* no such class */
  if (db_affected_rows(database) != 1)
    throw(SQL_EXCEPTION, "new_artefact: no such artefact class");

  ds = dstring_new("INSERT INTO " DB_TABLE_ARTEFACT
         " (artefactClassID, caveID, initiated)"
         " VALUES (%d, 0, 0)", artefactClassID);
  db_query_dstring(database, ds);

  debug(DEBUG_ARTEFACT, "new_artefact: %s", dstring_str(ds));

  /* successfully inserted? */
  if (db_affected_rows(database) != 1)
    throw(SQL_EXCEPTION, "new_artefact: could not insert artefact");

  return db_sequence_value(database, "Artefact_artefactID_seq");
}
示例#3
0
/*
 * Function is called to instantiate a wonder's impact.
 */
void weatherEnd_handler (db_t *database, db_result_t *result)
{
    int region_id;
    int weather_id;
    int impact_id;
    const struct Weather *weather;
    const struct WeatherImpact *impact;
    float effect[MAX_EFFECT];
    dstring_t *query;
    int index, len;

    debug(DEBUG_TICKER, "entering function weatherEnd_handler()");

    /* fetch data from event table */
    region_id   = db_result_get_int(result, "regionID");
    weather_id = db_result_get_int(result, "weatherID");
    impact_id = db_result_get_int(result, "impactID");
    get_effect_list(result, effect);

    debug(DEBUG_TICKER, "regionID = %d, weatherID = %d", region_id, weather_id);
    weather = (struct Weather *) weather_type[weather_id];
    impact = &weather->impacts[impact_id];

    /* prepare update statement */
    query = dstring_new("UPDATE " DB_TABLE_CAVE " SET ");

    for (index = 0; index < MAX_EFFECT; ++index)
    {
	double delta = -effect[index];

	if (delta != 0)
	{
	    const char *dbFieldName = effect_type[index]->dbFieldName;

	    dstring_append(query, "%s = %s + %f,",
			   dbFieldName, dbFieldName, delta);
	}
    }

    /* update the cave */
    len = dstring_len(query) - 1;

    if (dstring_str(query)[len] == ',')
    {
	dstring_truncate(query, len);
	dstring_append(query, " WHERE regionID = %d", region_id);

	debug(DEBUG_SQL, "%s", dstring_str(query));
	db_query_dstring(database, query);
    }

    debug(DEBUG_TICKER, "leaving function weatherEnd_handler()");
}
示例#4
0
/*
 * Retrieve artefact_class for the given id.
 */
void get_artefact_class_by_artefact_id (db_t *database, int artefactID,
             struct Artefact_class *artefact_class)
{
  db_result_t *result;
  dstring_t *ds;

  ds = dstring_new("SELECT ac.* FROM " DB_TABLE_ARTEFACT_CLASS
                    " ac LEFT JOIN " DB_TABLE_ARTEFACT
                    " a ON ac.ArtefactClassID = a.ArtefactClassID "
                    " WHERE a.artefactID = %d "
                    " AND caveID = 0 "
                    " AND initiated = %d", artefactID, ARTEFACT_UNINITIATED);
  result = db_query_dstring(database, ds);
  debug(DEBUG_ARTEFACT, "get_artefact_class_by_artefact_id: %s", dstring_str(ds));

  /* Bedingung: ArtefaktID muss vorhanden sein */
  if (db_result_num_rows(result) != 1)
    throw(SQL_EXCEPTION, "get_artefact_class_by_artefact_id: no such artefactID");

  db_result_next_row(result);

  artefact_class->artefactClassID       = db_result_get_int(result, "artefactClassID");
  artefact_class->name                  = db_result_get_string(result, "name");
  artefact_class->name_initiated        = db_result_get_string(result, "name_initiated");
  artefact_class->resref                = db_result_get_string(result, "resref");
  artefact_class->description           = db_result_get_string(result, "description");
  artefact_class->description_initiated = db_result_get_string(result, "description_initiated");
  artefact_class->initiationID          = db_result_get_int(result, "initiationID");
  artefact_class->noZeroFood            = db_result_get_int(result, "noZeroFood");
  artefact_class->destroyOnMove         = db_result_get_int(result, "destroyOnMove");
  get_effect_list(result, artefact_class->effect);
}
示例#5
0
static int artefact_loose_to_cave (db_t *database, struct Cave *cave)
{
  db_result_t *result;
  dstring_t *query;
  int x, y;
  int minX, minY, maxX, maxY, rangeX, rangeY;

  /* number between -ALR <= n <= ALR */
  x = (int) ((ARTEFACT_LOST_RANGE * 2 + 1) * drand()) - ARTEFACT_LOST_RANGE;
  y = (int) ((ARTEFACT_LOST_RANGE * 2 + 1) * drand()) - ARTEFACT_LOST_RANGE;

  x += cave->xpos;
  y += cave->ypos;   /* these numbers may be out of range */

  if (! map_get_bounds(database, &minX, &maxX, &minY, &maxY)) {
    return 0;
  }
  rangeX = maxX - minX +1;
  rangeY = maxY - minY +1;

  x = ( (x-minX+rangeX) % (rangeX) ) + minX;
  y = ( (y-minY+rangeY) % (rangeY) ) + minY;

  query = dstring_new("SELECT caveID FROM " DB_TABLE_CAVE
          " WHERE xCoord = %d AND yCoord = %d", x, y);

  debug(DEBUG_SQL, "%s", dstring_str(query));

  result = db_query_dstring(database, query);

  return db_result_next_row(result) ? db_result_get_int(result, "caveID") : 0;
}
示例#6
0
static void after_battle_defender_update(db_t *database,
					 int             player_id,
					 const Battle    *battle,
					 int             cave_id,
					 struct Relation *relation)
{
  dstring_t *ds;
  int       update = 0;
  int       i;

  /* construct defender update */
  ds = dstring_new("UPDATE " DB_TABLE_CAVE " SET ");

  /* which units need an update */
  debug(DEBUG_BATTLE, "preparing units update");
  for (i = 0; i < MAX_UNIT; ++i) {
    const struct Army_unit *unit = &battle->defenders[0].units[i];

    if (unit->amount_before != unit->amount_after) {
      dstring_append(ds, "%s%s = %d", update ? "," : "",
		     unit_type[i]->dbFieldName, unit->amount_after);
      update = 1;
    }
  }

  /* which defense systems need an update */
  debug(DEBUG_BATTLE, "preparing defensesystems update");
  for (i = 0; i < MAX_DEFENSESYSTEM; ++i) {
    const struct Army_unit *defense_system =
      &battle->defenders[0].defenseSystems[i];

//    if ((relation->relationType == RELATION_TYPE_WAR) || (((struct DefenseSystem *)defense_system_type[i])->warpoints == 0 )) {
      if (defense_system->amount_before != defense_system->amount_after) {
        dstring_append(ds, "%s%s = %d", update ? "," : "",
  		     defense_system_type[i]->dbFieldName,
  		     defense_system->amount_after);
      update = 1;
      }
//   }  
  }

  /* which resources need an update */
  debug(DEBUG_BATTLE, "preparing resources update");
  for (i = 0; i < MAX_RESOURCE; ++i)
    if (battle->defenders[0].resourcesBefore[i] !=
      battle->defenders[0].resourcesAfter[i]) {
      dstring_append(ds, "%s%s = LEAST(%d, %s)", update ? "," : "",
		     resource_type[i]->dbFieldName,
		     battle->defenders[0].resourcesAfter[i],
		     function_to_sql(resource_type[i]->maxLevel));
      update = 1;
    }
  dstring_append(ds, " WHERE caveID = %d", cave_id);

  if (update) {
    debug(DEBUG_SQL, "%s", dstring_str(ds));
    db_query_dstring(database, ds);
  }

}
示例#7
0
int get_artefact_for_caveID(db_t *database, int caveID, int spyableOnly) {
  dstring_t *ds;
  db_result_t *result;
  int artefactID = 0;

  if (spyableOnly) {
    ds = dstring_new("SELECT a.artefactID FROM " DB_TABLE_ARTEFACT
                         " a LEFT JOIN " DB_TABLE_ARTEFACT_CLASS
                         " ac ON a.ArtefactClassID = ac.ArtefactClassID "
                           " WHERE a.caveID = %d AND ac.getArtefactBySpy = 1 ORDER BY RAND() LIMIT 1", caveID);
  } else {
    ds = dstring_new("SELECT artefactID FROM " DB_TABLE_ARTEFACT
                     " WHERE caveID = %d ORDER BY RAND() LIMIT 1", caveID);
  }
  result = db_query_dstring(database, ds);

  debug(DEBUG_ARTEFACT, "get_artefact_for_caveID: %s", dstring_str(ds));

  if (db_result_num_rows(result) == 0) {
    if (!spyableOnly) {
      debug(DEBUG_ARTEFACT, "get_artefact_for_caveID: fail... no artefact in cave %d", caveID);
    } else {
      debug(DEBUG_ARTEFACT, "get_artefact_for_caveID: no spyable artefact left in cave %d", caveID);
    }
    return artefactID;
  }

  db_result_next_row(result);
  artefactID = db_result_get_int(result, "artefactID");

  return artefactID;
}
示例#8
0
/*
 * User wants to remove the artefact from a cave or another user just robbed
 * that user. Remove the effects (actually same as apply_effects but with a
 * "-" instead of the "+").
 */
void remove_effects_from_cave (db_t *database, int artefactID)
{
  struct Artefact       artefact;
  struct Artefact_class artefact_class;
  dstring_t             *ds = dstring_new("UPDATE Cave SET ");
  int                   i;

  /* get artefact values; throws exception, if that artefact is missing */
  get_artefact_by_id(database, artefactID, &artefact);
  /* get artefactClass; throws exception, if that artefactClass is missing */
  get_artefact_class_by_id(database, artefact.artefactClassID, &artefact_class);

  /* Wenn das Artefakt nicht mehr eingeweiht ist, m�ssen die Effekte nicht mehr entfernt werden. */
  if (artefact.initiated != ARTEFACT_INITIATED) return;

  for (i = 0; i < MAX_EFFECT; ++i)
    dstring_append(ds, "%s %s = %s - %f",
                  (i == 0 ? "" : ","),
                  effect_type[i]->dbFieldName,
                  effect_type[i]->dbFieldName,
                  artefact_class.effect[i]);

  dstring_append(ds, " WHERE caveID = %d", artefact.caveID);

  db_query_dstring(database, ds);
  debug(DEBUG_ARTEFACT, "remove_effects_from_cave: %s", dstring_str(ds));
}
示例#9
0
/*
 * Status already set to ARTEFACT_INITIATED, now apply the effects.
 */
void apply_effects_to_cave (db_t *database, int artefactID)
{
  struct Artefact       artefact;
  struct Artefact_class artefact_class;
  dstring_t             *ds = dstring_new("UPDATE Cave SET ");
  int                   i;

  /* get artefact values; throws exception, if that artefact is missing */
  get_artefact_by_id(database, artefactID, &artefact);
  /* get artefactClass; throws exception, if that artefactClass is missing */
  get_artefact_class_by_id(database, artefact.artefactClassID, &artefact_class);

  /* Bedingung: muss eingeweiht sein */
  if (artefact.initiated != ARTEFACT_INITIATED)
    throw(BAD_ARGUMENT_EXCEPTION, "initiate_artefact: artefact was not initiated");

  for (i = 0; i < MAX_EFFECT; ++i)
    dstring_append(ds, "%s %s = %s + %f",
                  (i == 0 ? "" : ","),
                  effect_type[i]->dbFieldName,
                  effect_type[i]->dbFieldName,
                  artefact_class.effect[i]);

  dstring_append(ds, " WHERE caveID = %d", artefact.caveID);

  db_query_dstring(database, ds);

  debug(DEBUG_ARTEFACT, "apply_effects_to_cave: %s", dstring_str(ds));
}
示例#10
0
/*
 * Initiating finished. Now set the status of the artefact to
 * ARTEFACT_INITIATED.
 */
void initiate_artefact (db_t *database, int artefactID)
{
  struct Artefact artefact;
  dstring_t *ds;

  /* get artefact values; throws exception, if that artefact is missing */
  get_artefact_by_id(database, artefactID, &artefact);

  /* Bedingung: muss gerade eingeweiht werden */
  if (artefact.initiated != ARTEFACT_INITIATING)
    throw(BAD_ARGUMENT_EXCEPTION, "initiate_artefact: artefact was not initiating");

  /* Bedingung: muss in einer Höhle liegen */
  if (artefact.caveID == 0)
    throw(BAD_ARGUMENT_EXCEPTION, "initiate_artefact: artefact was not in a cave");

  ds = dstring_new("UPDATE " DB_TABLE_ARTEFACT " SET initiated = %d WHERE artefactID = %d AND caveID = %d",
     ARTEFACT_INITIATED, artefact.artefactID, artefact.caveID);
  db_query_dstring(database, ds);

  debug(DEBUG_ARTEFACT, "initiate_artefact: %s", dstring_str(ds));

  /* Bedingung: Artefakt und Höhle müssen existieren */
  if (db_affected_rows(database) != 1)
    throw(SQL_EXCEPTION, "initiate_artefact: no such artefactID or caveID");
}
示例#11
0
/*
 * User wants to remove the artefact from a cave or another user just robbed
 * that user. Uninitiate this artefact.
 */
void uninitiate_artefact (db_t *database, int artefactID)
{
  dstring_t *ds;

  ds = dstring_new("UPDATE " DB_TABLE_ARTEFACT " SET initiated = %d "
         "WHERE artefactID = %d",
     ARTEFACT_UNINITIATED, artefactID);
  db_query_dstring(database, ds);

  debug(DEBUG_ARTEFACT, "uninitiate_artefact: %s", dstring_str(ds));

  ds = dstring_new("DELETE FROM Event_artefact WHERE artefactID = %d",
     artefactID);
  db_query_dstring(database, ds);

  debug(DEBUG_ARTEFACT, "uninitiate_artefact: %s", dstring_str(ds));
}
示例#12
0
static void after_battle_attacker_update (
  db_t *database,
  int          player_id,
  const Battle *battle,
  int          source_caveID,
  int          target_caveID,
  const char   *speed_factor,
  const char   *return_start,
  const char   *return_end,
  int          artefact,
  struct Relation *relation
  )
{
  int update = 0;
  int i;

  /* construct attacker update */
  for (i = 0; i < MAX_UNIT; ++i)
    if (battle->attackers[0].units[i].amount_after > 0) {
      update = 1;
      break;
    }

  if (update) {
    dstring_t *ds;

    /* send remaining units back */
    ds = dstring_new("INSERT INTO Event_movement"
		     " (caveID, target_caveID, source_caveID, movementID,"
		     " speedFactor, start, end, artefactID");

    for (i = 0; i < MAX_RESOURCE; ++i)
      dstring_append(ds, ",%s", resource_type[i]->dbFieldName);
    for (i = 0; i < MAX_UNIT; ++i)
      dstring_append(ds, ",%s", unit_type[i]->dbFieldName);

    dstring_append(ds, ") VALUES (%d, %d, %d, %d, %s, '%s', '%s', %d",
		   source_caveID, source_caveID, target_caveID, RUECKKEHR,
		   speed_factor, return_start, return_end, artefact);

    for (i = 0; i < MAX_RESOURCE; ++i)
      dstring_append(ds, ",%d", battle->attackers[0].resourcesAfter[i]);
    for (i = 0; i < MAX_UNIT; ++i)
      dstring_append(ds, ",%d", battle->attackers[0].units[i].amount_after);

    dstring_append(ds, ")");

    debug(DEBUG_SQL, "%s", dstring_str(ds));
    db_query_dstring(database, ds);
  }
}
示例#13
0
/*
 * User wants to remove the artefact from a cave or another user just robbed
 * that user. Remove the artefact from its cave.
 */
void remove_artefact_from_cave (db_t *database, int artefactID)
{
  struct Artefact artefact;
  dstring_t *ds;

  /* save artefact values; throws exception, if that artefact is missing */
  get_artefact_by_id(database, artefactID, &artefact);

  ds = dstring_new("UPDATE " DB_TABLE_ARTEFACT " SET caveID = 0 "
         "WHERE artefactID = %d", artefactID);
  db_query_dstring(database, ds);

  debug(DEBUG_ARTEFACT, "remove_artefact_from_cave: %s", dstring_str(ds));

  ds = dstring_new("UPDATE Cave SET artefacts = artefacts - 1 "
         "WHERE caveID = %d", artefact.caveID);
  db_query_dstring(database, ds);

  debug(DEBUG_ARTEFACT, "remove_artefact_from_cave: %s", dstring_str(ds));

  /* Bedingung: Höhle muss vorhanden sein */
  if (db_affected_rows(database) != 1)
    throw(SQL_EXCEPTION, "remove_artefact_from_cave: no such caveID");
}
示例#14
0
static void after_takeover_attacker_update(db_t *database,
					   int             player_id,
					   const Battle    *battle,
					   int             target_caveID,
					   int             artefact,
					   struct Relation *relation)
{
  int update = 0;
  int i;

  /* construct attacker update */
  for (i = 0; i < MAX_UNIT; ++i)
    if (battle->attackers[0].units[i].amount_after > 0) {
      update = 1;
      break;
    }

  if (update) {
    dstring_t *ds;

    /* put artefact into cave */
    if (artefact > 0)
      put_artefact_into_cave(database, artefact, target_caveID);

    /* put remaining units into target_cave */
    ds = dstring_new("UPDATE " DB_TABLE_CAVE " SET ");

    for (i = 0; i < MAX_RESOURCE; ++i)
      dstring_append(ds, "%s%s = LEAST(%s + %d, %s)", i > 0 ? "," : "",
		     resource_type[i]->dbFieldName,
		     resource_type[i]->dbFieldName,
		     battle->attackers[0].resourcesAfter[i],
		     function_to_sql(resource_type[i]->maxLevel));

    for (i = 0; i < MAX_UNIT; ++i)
      dstring_append(ds, ",%s = %s + %d",
		     unit_type[i]->dbFieldName,
		     unit_type[i]->dbFieldName,
		     battle->attackers[0].units[i].amount_after);

    dstring_append(ds, " WHERE caveID = %d", target_caveID);

    debug(DEBUG_SQL, "%s", dstring_str(ds));
    db_query_dstring(database, ds);
  }
}
示例#15
0
/*
 * Retrieve artefact for the given id.
 */
void get_artefact_by_id (db_t *database, int artefactID,
       struct Artefact *artefact)
{
  dstring_t *ds;
  db_result_t *result;

  ds = dstring_new("SELECT * FROM " DB_TABLE_ARTEFACT
           " WHERE artefactID = %d", artefactID);
  result = db_query_dstring(database, ds);

  debug(DEBUG_ARTEFACT, "get_artefact_by_id: %s", dstring_str(ds));

  /* Bedingung: Artefakt muss vorhanden sein */
  if (db_result_num_rows(result) != 1)
    throw(SQL_EXCEPTION, "get_artefact_by_id: no such artefactID");

  db_result_next_row(result);

  artefact->artefactID      = artefactID;
  artefact->artefactClassID = db_result_get_int(result, "artefactClassID");
  artefact->caveID          = db_result_get_int(result, "caveID");
  artefact->initiated       = db_result_get_int(result, "initiated");
}
示例#16
0
static void takeover_cave(db_t *database,
		   int    cave_id,
		   int    attacker_id,
		   const char   *return_start)
{
  /* change owner of cave */
  db_query(database, "UPDATE " DB_TABLE_CAVE " SET playerID = %d"
		     " WHERE caveID = %d", attacker_id, cave_id);

  dstring_t *ds;
  ds = dstring_new("UPDATE Event_movement SET target_caveID = source_caveID, ");
  dstring_append(ds, "end = addtime('%s',timediff('%s',start)), ",return_start,return_start);
  dstring_append(ds, "start='%s', ",return_start);
  dstring_append(ds, "movementID = 5 where caveID = %d and caveID = source_caveID",cave_id);
  debug(DEBUG_SQL, "Torben %s", dstring_str(ds));
  db_query_dstring(database, ds);


  /* delete research from event table*/
  db_query(database, "DELETE FROM Event_science WHERE caveID = %d", cave_id);

  /* copy sciences from new owner to cave */
  science_update_caves(database, attacker_id);
}
示例#17
0
/*
 * merge_artefacts_general
 * Throws exception if needed conditions are not as they should have been.
 */
int merge_artefacts_general (db_t *database,
           const struct Artefact *key_artefact,
           struct Artefact *lock_artefact,
           struct Artefact *result_artefact)
{
  db_result_t *result;
  db_result_t *temp_result;
  int row;
  dstring_t *ds;

  /* now get possible merging formulas */
  ds = dstring_new("SELECT * FROM Artefact_merge_general "
            "WHERE keyClassID = %d",
        key_artefact->artefactClassID);
  result = db_query_dstring(database, ds);

  debug(DEBUG_ARTEFACT, "merge_artefact_general: %s", dstring_str(ds));

  /* check for a suitable merging */
  while ((row = db_result_next_row(result)))
  {
    /* special rules:
     *
     * lockClassID = 0
     * no lock artefact needed
     *
     * keyClassID = lockClassID
     * unlocks if at least one other initiated artefact
     * of the same class exists
     *
     * resultClassID = 0
     * key artefact and one present instance of the lockClass vanish
     */

    /* lock artefact */
    lock_artefact->artefactClassID =
    db_result_get_int(result, "lockClassID");

    if (lock_artefact->artefactClassID == 0)
      break;

    /* implicit checks:
     * - lock artefact has to be different from the key artefact
     * - lock artefact has to be in the same cave as the key artefact
     * - lock artefact has to be initiated
     * - lock artefact has be of the specified class
     */
    ds = dstring_new("SELECT artefactID FROM " DB_TABLE_ARTEFACT
             " WHERE artefactID != %d"
             " AND artefactClassID = %d"
             " AND caveID = %d"
             " AND initiated = %d",
         key_artefact->artefactID,
         lock_artefact->artefactClassID,
         key_artefact->caveID,
         ARTEFACT_INITIATED);
    temp_result = db_query_dstring(database, ds);

    debug(DEBUG_ARTEFACT, "merge_artefact_general: %s", dstring_str(ds));

    /* is there a suitable lock artefact? */
    if (db_result_next_row(temp_result))
    {
      lock_artefact->artefactID = db_result_get_int(temp_result, "artefactID");
      lock_artefact->caveID     = key_artefact->caveID;
      lock_artefact->initiated  = ARTEFACT_INITIATED;
      break;
    }
  }

  if (row)
  {
    /* result artefact */
    result_artefact->artefactClassID =
    db_result_get_int(result, "resultClassID");

    if (result_artefact->artefactClassID != 0)
      result_artefact->artefactID =
    new_artefact(database, result_artefact->artefactClassID);

    /* now merge them */
    merge_artefacts(database,
                    key_artefact->caveID,
                    key_artefact->artefactID,
                    lock_artefact->artefactID,
                    result_artefact->artefactID);
    return 1;
  }

  return 0;
}
示例#18
0
/*
 * merge_artefacts_special
 * Throws exception if needed conditions are not as they should have been.
 */
int merge_artefacts_special (db_t *database,
           const struct Artefact *key_artefact,
           struct Artefact *lock_artefact,
           struct Artefact *result_artefact)
{
  db_result_t *result;
  db_result_t *temp_result;
  int row;
  dstring_t *ds;

  /* get merging formulas */
  ds = dstring_new("SELECT * FROM Artefact_merge_special "
            "WHERE keyID = %d", key_artefact->artefactID);
  result = db_query_dstring(database, ds);

  debug(DEBUG_ARTEFACT, "merge_artefact_special: %s", dstring_str(ds));

  /* check for a suitable merging formula */
  while ((row = db_result_next_row(result)))
  {
    /* some special cases:
     *
     * lockID == 0 || keyID == lockID
     * no lock artefact needed; key artefact transforms directly
     *
     * resultID == 0
     * key and lock artefacts just vanish
     */

    /* lock artefact */
    lock_artefact->artefactID = db_result_get_int(result, "lockID");

    /* special cases: lockID == 0 || keyID == lockID (no lock required) */
    if (lock_artefact->artefactID == 0 ||
  lock_artefact->artefactID == key_artefact->artefactID)
      break;

    /* get lock_artefact */
    /* throws exception, if that artefact is missing */
    get_artefact_by_id(database, lock_artefact->artefactID, lock_artefact);

    /* check: key and lock have to be in the same cave and initiated */
    if (lock_artefact->caveID == key_artefact->caveID &&
  lock_artefact->initiated == ARTEFACT_INITIATED)
      break;
  }

  if (row)
  {
    /* result artefact */
    result_artefact->artefactID = db_result_get_int(result, "resultID");

    /* special case: resultID == 0 */
    if (result_artefact->artefactID != 0)
    {
      /* get result_artefact */
      /* throws exception, if that artefact is missing */
      get_artefact_by_id(database, result_artefact->artefactID, result_artefact);

      /* check: result_artefact must not be in any cave */
      if (result_artefact->caveID != 0)
        throwf(BAD_ARGUMENT_EXCEPTION,
         "merge_artefacts_special: result artefact %d is in cave %d",
               result_artefact->artefactID, result_artefact->caveID);

      /* result_artefact must not be in any movement */
      temp_result = db_query(database, "SELECT * FROM Event_movement"
               " WHERE artefactID = %d",
           result_artefact->artefactID);

      if (db_result_num_rows(temp_result) != 0)
        throwf(BAD_ARGUMENT_EXCEPTION,
         "merge_artefacts_special: result artefact %d is moving",
               result_artefact->artefactID);

      /* check: result_artefact has to be uninitiated */
      /* XXX can this ever happen (it is not in a cave)? */
      if (result_artefact->initiated != ARTEFACT_UNINITIATED)
        uninitiate_artefact(database, result_artefact->artefactID);
    }

    /* now merge them */
    merge_artefacts(database,
                    key_artefact->caveID,
                    key_artefact->artefactID,
                    lock_artefact->artefactID,
                    result_artefact->artefactID);
    return 1;
  }

  return 0;
}
示例#19
0
/*
 * EdNames widget command
 */
static int NamesWidgetCmd(ClientData clientData, Tcl_Interp *interp,
			  int argc, char **argv) {
    edNames *en = (edNames *)clientData;
    int result = TCL_OK;

    if (argc < 2) {
        Tcl_AppendResult(interp, "wrong # args: should be \"",
                         argv[0], " option ?arg arg ...?\"",
                         (char *) NULL);
        return TCL_ERROR;
    }

    Tcl_Preserve((ClientData)TKSHEET(en));

    if ('c' == *argv[1] && strcmp(argv[1], "configure") == 0) {
	result = SheetWidgetCmdConfig(interp, TKSHEET(en), argc, argv);

    } else if (!en->xx) {
	en->xx = 0; /* Do nothing and flow through to 'success' */

    } else if ('u' == *argv[1] && strcmp(argv[1], "update_brief") == 0) {
	int x, y;

	if (argc != 4) {
	    Tcl_AppendResult(interp, "wrong # args: should be \"",
			     argv[0], " update_brief xpos ypos\"",
			     (char *) NULL);
	    goto fail;
	}
	
	sheet_arg_x(TKSHEET(en), argv[2], &x);
	sheet_arg_y(TKSHEET(en), argv[3], &y); y++;

	edSetBriefNameStatus(en->xx, x, y);

    } else if ('h' == *argv[1] && strcmp(argv[1], "highlight") == 0) {
	int y, x, mode = -1;

	if (argc != 4 && argc != 5) {
	    Tcl_AppendResult(interp, "wrong # args: should be \"",
			     argv[0], " highlight mode ?xpos? ypos\"",
			     (char *) NULL);
	    goto fail;
	}

	Tcl_GetInt(interp, argv[2], &mode);

	if (argc == 5) {
	    sheet_arg_x(TKSHEET(en), argv[3], &x);
	    y = 4; /* argv number of y, rather than y itself */
	} else {
	    x = 2;
	    y = 3;
	}

	if (*argv[y] == '=') {
	    y = get_gel_num(DBI_io(en->xx), &argv[y][1], GGN_ID);
	    y = rnum_to_edseq(en->xx, y);
	} else {
	    sheet_arg_y(TKSHEET(en), argv[y], &y); y++;
	    y = edGetGelNumber(en->xx, 0, y);
	}

	if (-1 != y) {
	    if (x != 0) {
		edSelectRead(en->xx, y, mode);

		vTcl_SetResult(interp, "%d",
			       (DB_Flags(en->xx, y) & DB_FLAG_SELECTED) ?1:0);
	    } else {
		if (y)
		    select_note(DBI_io(en->xx), GT_Readings,
				DB_Number(en->xx,y));
		else
		    select_note(DBI_io(en->xx), GT_Contigs,
				DBI_contigNum(en->xx));
	    }
	}

    } else if ('g' == *argv[1] && strcmp(argv[1], "get_number") == 0) {
	int x, y, num;

	if (argc != 2 && argc != 4) {
	    Tcl_AppendResult(interp, "wrong # args: should be \"",
			     argv[0], " get_number ?xpos ypos?\"",
			     (char *) NULL);
	    goto fail;
	}

	if (argc == 4) {
	    sheet_arg_x(TKSHEET(en), argv[2], &x);
	    sheet_arg_y(TKSHEET(en), argv[3], &y); y++;

	    if (-1 != (num = edGetGelNumber(en->xx, x, y))) {
		vTcl_SetResult(interp, "%d", num);
	    } /* otherwise return a blank */
	} else {
	    vTcl_SetResult(interp, "%d", en->xx->cursorSeq);
	}

    } else if ('g' == *argv[1] && strcmp(argv[1], "get_read_number") == 0) {
	int num;

	if (argc != 2 && argc != 3) {
	    Tcl_AppendResult(interp, "wrong # args: should be \"",
			     argv[0], " get_read_number ?editor_gel_number?\"",
			     (char *) NULL);
	    goto fail;
	}

	if (argc == 3)
	    Tcl_GetInt(interp, argv[2], &num);
	else
	    num = en->xx->cursorSeq;

	vTcl_SetResult(interp, "%d", DB_Number(en->xx, num));

    } else if ('g' == *argv[1] && strcmp(argv[1], "get_contig_number") == 0) {
	if (argc != 2) {
	    Tcl_AppendResult(interp, "wrong # args: should be \"",
			     argv[0], " get_contig_number",
			     (char *) NULL);
	    goto fail;
	}

	vTcl_SetResult(interp, "%d", -DB_Number(en->xx, 0));

    } else if ('g' == *argv[1] && strcmp(argv[1], "get_name") == 0) {
	char *name;
	int num;

	if (argc != 2 && argc != 3) {
	    Tcl_AppendResult(interp, "wrong # args: should be \"",
			     argv[0], " get_name ?editor_gel_number?\"",
			     (char *) NULL);
	    goto fail;
	}

	if (argc == 3)
	    Tcl_GetInt(interp, argv[2], &num);
	else
	    num = en->xx->cursorSeq;

	Tcl_ResetResult(interp);
	if (NULL != (name = edGetGelName(en->xx, num))) {
	    Tcl_AppendResult(interp, name, NULL);
	} /* otherwise return a blank */

    } else if ('g' == *argv[1] && strcmp(argv[1], "get_names_to_right") == 0) {
	int num;
	dstring_t *ds = NULL;

	if (argc != 2 && argc != 3) {
	    Tcl_AppendResult(interp, "wrong # args: should be \"",
			     argv[0], " get_name ?gel_number?\"",
			     (char *) NULL);
	    goto fail;
	}

	if (argc == 3)
	    Tcl_GetInt(interp, argv[2], &num);
	else
	    num = en->xx->cursorSeq;

	if (NULL != (ds = edGetGelNamesToRight(en->xx, num))) {
	    Tcl_SetResult(interp, dstring_str(ds), TCL_VOLATILE);
	    dstring_destroy(ds);
	} else {
	    /* otherwise return a blank */
	    Tcl_ResetResult(interp);
	}

    } else if ('x' == *argv[1] && strcmp(argv[1], "xview") == 0) {
	int offset, count, type;
	double fraction;

	if (argc == 2) {
	    /* query */
	    vTcl_SetResult(interp, "%d", en->xx->names_xpos);
	} else {
	    if (argc == 3) {
		/* old syntax */
		if (Tcl_GetInt(interp, argv[2], &offset) != TCL_OK) {
		    goto fail;
		}
		setNamePos(en->xx, offset);
	    } else {
		/* new syntax */
		type = Tk_GetScrollInfo(interp, argc, argv, &fraction, &count);
		switch (type) {
                case TK_SCROLL_ERROR:
                    goto fail;
                case TK_SCROLL_MOVETO:
                    offset = (int) (fraction*DB_NAMELEN + 0.5);
                    break;
                case TK_SCROLL_PAGES:
		    count *= 4;
                case TK_SCROLL_UNITS:
		    offset = en->xx->names_xpos + count;
                    break;
		}
		if (offset < 0)
		    offset = 0;
		if (offset + (en->sw.columns - (DB_GELNOLEN + 1)) > DB_NAMELEN)
		    offset = DB_NAMELEN - (en->sw.columns - (DB_GELNOLEN + 1));
		setNamePos(en->xx, offset);
	    }
	    
	    /* Update X scrollbar */
	    ed_set_nslider_pos(en->xx, en->xx->names_xpos);
	}

    } else if ('c' == *argv[1] && strcmp(argv[1], "coords") == 0) {
	int x, y;
	if (argc != 4) {
	    Tcl_AppendResult(interp, "wrong # args: should be \"",
			     argv[0], " update_brief xpos ypos\"",
			     (char *) NULL);
	    goto fail;
	}
	
	sheet_arg_x(TKSHEET(en), argv[2], &x);
	sheet_arg_y(TKSHEET(en), argv[3], &y); y++;

	vTcl_SetResult(interp, "%d %d", x, y);

    } else {
	Tcl_AppendResult(interp, "bad option \"", argv[1], "\": must be FIXME",
			 NULL);
	goto fail;
    }

    Tcl_Release((ClientData)TKSHEET(en));
    return result;

 fail:
    Tcl_Release((ClientData)TKSHEET(en));
    return TCL_ERROR;
}