Пример #1
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;
}
Пример #2
0
/*
 * Retrieve cave table information for the given cave id.
 */
void get_cave_info (db_t *database, int cave_id, struct Cave *cave)
{
  db_result_t *result = db_query(database,
	"SELECT * FROM " DB_TABLE_CAVE " WHERE caveID = %d", cave_id);

  if (!db_result_next_row(result))
    throwf(SQL_EXCEPTION, "get_cave_info: cave %d not found", cave_id);

  cave->result = result;
  cave->cave_id = cave_id;
  cave->xpos = db_result_get_int(result, "xCoord");
  cave->ypos = db_result_get_int(result, "yCoord");
  cave->name = db_result_get_string(result, "name");
  cave->player_id = db_result_get_int(result, "playerID");
  cave->terrain = db_result_get_int(result, "terrain");
  cave->takeoverable = db_result_get_int(result, "takeoverable");
  cave->artefacts = db_result_get_int(result, "artefacts");
  cave->heroID = db_result_get_int(result, "hero");
  cave->monster_id = db_result_get_int(result, "monsterID");
  cave->secure = db_result_get_int(result, "secureCave");
  cave->protect_end = db_result_get_time(result, "protection_end");
  get_resource_list(result, cave->resource);
  get_building_list(result, cave->building);
  get_science_list(result, cave->science);
  get_defense_system_list(result, cave->defense_system);
  get_unit_list(result, cave->unit);
  get_effect_list(result, cave->effect);
}
Пример #3
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;
}
Пример #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
//return 0 falls nicht
static int isVerschiebenAllowed(db_t *database,
                        struct Player *sender,
                        struct Player *reciever,
                        struct Relation *attToDef){
    //einfache Fälle zuerst
    //beide spieler im selben stamm
    if(strcasecmp(sender->tribe, reciever->tribe) == 0)
        return 1;
    //wenn beide im vorkrieg sind dann müsste das in der relation ja schon stehen
    if(attToDef->relationType == RELATION_TYPE_PRE_WAR)
        return 1;
    //wenn beide im krieg sind dann müsste das in der relation ja schon stehen
    if(attToDef->relationType == RELATION_TYPE_WAR)
        return 1;
    //Im Kriegsbuendniss ist es auch möglich
    if(attToDef->relationType == RELATION_TYPE_WAR_TREATMENT)
        return 1;

    if(reciever->player_id==0)
       return 1;

    //nun noch das schwierigere
    //ist einer von beiden im krieg
    db_result_t *result;
    result = db_query(database,
            "SELECT * FROM Relation WHERE relationType = %d AND tribe like '%s'",
            RELATION_TYPE_PRE_WAR, sender->tribe);
    if(db_result_next_row(result))
        return 0;
    result = db_query(database,
            "SELECT * FROM Relation WHERE relationType = %d AND tribe like '%s'",
            RELATION_TYPE_PRE_WAR, reciever->tribe);
    if(db_result_next_row(result))
        return 0;
    result = db_query(database,
            "SELECT * FROM Relation WHERE relationType = %d AND tribe like '%s'",
            RELATION_TYPE_WAR, sender->tribe);
    if(db_result_next_row(result))
        return 0;
    result = db_query(database,
            "SELECT * FROM Relation WHERE relationType = %d AND tribe like '%s'",
            RELATION_TYPE_WAR, reciever->tribe);
    if(db_result_next_row(result))
        return 0;

  return 1;
}
Пример #6
0
/*
 * Retrieve the owner (player id) of the given gave.
 */
int get_cave_owner (db_t *database, int cave_id)
{
  db_result_t *result = db_query(database,
	"SELECT playerID FROM " DB_TABLE_CAVE " WHERE caveID = %d", cave_id);

  if (!db_result_next_row(result))
    throwf(SQL_EXCEPTION, "get_cave_owner: cave %d not found", cave_id);

  return db_result_get_int_at(result, 0);
}
Пример #7
0
static int isTakeoverableCave(db_t *database, int caveID) {
    db_result_t *result;

    result = db_query(database,
	    "SELECT * FROM Cave WHERE playerID=0 AND caveID = %d AND takeoverable=1;",
	    caveID);
    if(db_result_next_row(result))
	return 1;
    return 0;
}
Пример #8
0
/*
 * Retrieve the number of caves owned by player_id.
 */
int get_number_of_caves (db_t *database, int player_id)
{
  db_result_t *result = db_query(database,
	"SELECT COUNT(caveID) AS n FROM " DB_TABLE_CAVE
	" WHERE playerID = %d", player_id);

  db_result_next_row(result);

  return db_result_get_int_at(result, 0);
}
Пример #9
0
static void prepare_battle(db_t *database,
			   Battle          *battle,
			   struct Player   *attacker,
			   struct Player   *defender,
			   struct Cave     *cave_attacker,
			   struct Cave     *cave_defender,
			   const float     *battle_bonus,
			   int             takeover_multiplier,
			   int             *units,
			   int             *resources,
			   int             *attacker_artefact_id,
			   int             *defender_artefact_id,
			   struct Relation *relation_from_attacker,
			   struct Relation *relation_from_defender)
{
  /* initialize defender army */
  army_setup(&battle->defenders[0], cave_defender, battle_bonus,
	     takeover_multiplier,
	     cave_defender->unit, cave_defender->resource,
	     cave_defender->defense_system);

  /* initialize attacker army */
  army_setup(&battle->attackers[0], cave_attacker, battle_bonus, 0,
	     units, resources, NULL);

  /* artefacts */
  debug(DEBUG_BATTLE, "artefacts in target cave: %d", cave_defender->artefacts);

  if (cave_defender->artefacts > 0) {
    db_result_t *result =
      db_query(database, "SELECT artefactID FROM " DB_TABLE_ARTEFACT
			 " WHERE caveID = %d LIMIT 0,1",
	       cave_defender->cave_id);

    if (!db_result_next_row(result))
      throw(SQL_EXCEPTION, "prepare_battle: no artefact in cave");

    /* warum nur das erste Artefakt?? */
    *defender_artefact_id = db_result_get_int_at(result, 0);
  }

  debug(DEBUG_BATTLE, "defender artefact: %d", *defender_artefact_id);
  debug(DEBUG_BATTLE, "attacker artefact: %d", *attacker_artefact_id);

  /* get the relation boni */
  battle->attackers[0].relationMultiplicator =
    relation_from_attacker->attackerMultiplicator;
  battle->defenders[0].relationMultiplicator =
    relation_from_defender->defenderMultiplicator;
}
Пример #10
0
int get_tribe_at_war(db_t *database, const char *tribe)
{
  db_result_t *result = NULL;

  if (tribe)
  {
    debug(DEBUG_BATTLE, "get tribe at war for %s", tribe);
    result = db_query(database,
        "SELECT * FROM " DB_TABLE_RELATION
        " WHERE tribe = '%s' AND relationType = '%i'", tribe, RELATION_TYPE_WAR);
  }

  return (result && db_result_next_row(result));

}
Пример #11
0
/*
 * Retrieve player table information for the given player id.
 */
void get_player_info (db_t *database, int player_id, struct Player *player)
{
  db_result_t *result = db_query(database,
	"SELECT * FROM " DB_TABLE_PLAYER " WHERE playerID = %d", player_id);

  if (!db_result_next_row(result))
    throwf(SQL_EXCEPTION, "get_player_info: player %d not found", player_id);

  player->player_id = player_id;
  player->name = db_result_get_string(result, "name");
  player->tribe = db_result_get_string(result, "tribe");
  player->max_caves = db_result_get_int(result, "takeover_max_caves");
  player->locale = db_result_get_string(result, "language");
  player->locale_id = get_locale_id(player->locale);
  get_science_list(result, player->science);
}
Пример #12
0
/*
 * Retrieve monster table information for the given monster id.
 */
void get_monster_info (db_t *database, int monster_id, struct Monster *monster)
{
  db_result_t *result = db_query(database,
	"SELECT * FROM Monster WHERE monsterID = %d", monster_id);

  if (!db_result_next_row(result))
    throwf(SQL_EXCEPTION, "get_monster_info: monster %d not found", monster_id);

  monster->monster_id = monster_id;
  monster->name = db_result_get_string(result, "name");
  monster->attack = db_result_get_int(result, "angriff");
  monster->defense = db_result_get_int(result, "verteidigung");
  monster->mental = db_result_get_int(result, "mental");
  monster->strength = db_result_get_int(result, "koerperkraft");
  monster->exp_value = db_result_get_int(result, "erfahrung");
  monster->attributes = db_result_get_string(result, "eigenschaft");
}
Пример #13
0
/*
 * Retrieve relation table information for the given tribe and tribe_target.
 */
int get_relation_info (db_t *database, const char *tribe,
		       const char *tribe_target, struct Relation *relation)
{
  db_result_t *result = NULL;

  if (tribe && tribe_target)
  {
    debug(DEBUG_BATTLE, "get relation for tribes %s %s", tribe, tribe_target);
    result = db_query(database,
	"SELECT * FROM " DB_TABLE_RELATION
	" WHERE tribe = '%s' AND tribe_target = '%s'", tribe, tribe_target);
  }

  if (!result || !db_result_next_row(result))
  {
    debug(DEBUG_BATTLE, "filling dummy relation");
    relation->relation_id = 0;
    relation->tribe = tribe;
    relation->tribe_target = tribe_target;
    relation->relationType = RELATION_TYPE_NONE;

    /* FIXME these values should be read from relation types */
    relation->attackerMultiplicator = 0.5;
    relation->defenderMultiplicator = 1.0;
    relation->attackerReceivesFame = 0;
    relation->defenderReceivesFame = 0;

    return 0;	/* no relation entry */
  }

  relation->relation_id = db_result_get_int(result, "relationID");
  relation->tribe = tribe;
  relation->tribe_target = tribe_target;
  relation->relationType = db_result_get_int(result, "relationType");
  relation->defenderMultiplicator =
    db_result_get_double(result, "defenderMultiplicator");
  relation->attackerMultiplicator =
    db_result_get_double(result, "attackerMultiplicator");
  relation->defenderReceivesFame =
    db_result_get_int(result, "defenderReceivesFame");
  relation->attackerReceivesFame =
    db_result_get_int(result, "attackerReceivesFame");

  return 1;
}
Пример #14
0
/*
 * Retrieve artefact for the given id.
 */
void get_artefact_by_id (db_t *database, int artefactID,
			 struct Artefact *artefact)
{
  db_result_t *result =
    db_query(database, "SELECT * FROM " DB_TABLE_ARTEFACT
		       " WHERE artefactID = %d", artefactID);

  /* 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");
}
Пример #15
0
static int map_get_bounds (db_t *database,
         int *minX, int *maxX, int *minY, int *maxY)
{
  db_result_t *result = db_query(database,
    "SELECT MIN(xCoord) AS minX, "
    "       MAX(xCoord) AS maxX, "
    "       MIN(yCoord) AS minY, "
    "       MAX(yCoord) AS maxY  "
    "FROM Cave");

  if (!db_result_next_row(result)) return 0;

  *minX = db_result_get_int(result, "minX");
  *maxX = db_result_get_int(result, "maxX");
  *minY = db_result_get_int(result, "minY");
  *maxY = db_result_get_int(result, "maxY");
  return 1;
}
Пример #16
0
/*
 * Retrieve artefact_class for the given id.
 */
void get_artefact_class_by_id (db_t *database, int artefactClassID,
			       struct Artefact_class *artefact_class)
{
  db_result_t *result =
    db_query(database, "SELECT * FROM Artefact_class"
		       " WHERE artefactClassID = %d", artefactClassID);

  /* Bedingung: Artefaktklasse muss vorhanden sein */
  if (db_result_num_rows(result) != 1)
    throw(SQL_EXCEPTION, "get_artefact_class_by_id: no such artefactClassID");

  db_result_next_row(result);

  artefact_class->artefactClassID       = artefactClassID;
  artefact_class->name                  = db_result_get_string(result, "name");
  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");
  get_effect_list(result, artefact_class->effect);
}
Пример #17
0
static int check_farming (db_t *database,
			  int artefacts,
			  struct Player *attacker,
			  struct Player *defender,
			  struct Relation *attToDef)
{
  if(!STEALOUTSIDEWAR)
      return 0;
  db_result_t *result;

  /*
   * Wann ist es kein Farmen?
   * sie haben eine Beziehung || es gab ein artefakt
   * zu holen || verteidiger hat keinen stamm
   */
  if ( (attToDef->relationType == RELATION_TYPE_WAR)
       || (attToDef->relationType == RELATION_TYPE_PRE_WAR)
          || (defender->tribe == NULL)
	  || (strcmp(defender->tribe,"multi")==0)
	  || (strcmp(defender->tribe, attacker->tribe)==0)
	      || (strlen(defender->tribe) == 0)
          || (artefacts > 0)
          || (defender->player_id) == PLAYER_SYSTEM) {

      return NO_FARMING;
  }

  /* Sind es Missionierungsgegner? */
  result = db_query(database,
	"SELECT c.caveID FROM Cave_takeover c ,Cave_takeover k  "
	"WHERE c.caveID = k.caveID AND c.playerID = %d AND k.playerID = %d "
	"AND k.status > 0 AND c.status > 0",
	defender->player_id, attacker->player_id);

  return db_result_next_row(result) ? NO_FARMING : FARMING;
}
Пример #18
0
/*
 * The event scheduler and resource ticker.
 */
static void run_ticker (db_t *database)
{
  time_t last = time(NULL);
  int events = 0, sleeps = 0;

  debug(DEBUG_TICKER, "running");

  while (!finish) {
    /* set up memory pool */
    struct memory_pool *pool = memory_pool_new();
    time_t now = time(NULL);
    int secs = now - last;

    if (secs >= TICKER_LOADAVG_TIME)
    {
	debug(DEBUG_TICKER, "ticker load: %.2f (%d events/min)",
	      1 - sleep_time / 1000000.0 * sleeps / secs, 60 * events / secs);

	events = sleeps = 0;
	last = now;
#ifdef DEBUG_MALLOC
	CHECK_LEAKS();
#endif
    }

    if (reload)
    {
	debug(DEBUG_TICKER, "reload config");
	reload = 0;

	/* read config file */
	config_read_file(config_file);
	fetch_config_values();
	log_handler_set_file(debug_log, debug_logfile);
	log_handler_set_file(error_log, error_logfile);
	log_handler_set_file(msg_log, msg_logfile);
    }

    try {
      char resource_timestamp[TIMESTAMP_LEN];
      char timestamp[TIMESTAMP_LEN];
      db_result_t *next_result = NULL;
      const char *next_timestamp =
	make_timestamp_gm(resource_timestamp, tick_next_event());
      const char *next_db_eventID;
      int next_eventType;
      int i;

      /* check each event queue to find the next event to process */
      debug(DEBUG_EVENTS, "start loop, next resource event");

      for (i = 0; i < eventTableSize; ++i)
      {
	db_result_t *result;

	/* get only the next non-blocked event, if its timestamp
	   is smaller than the smallest found timestamp */
	debug(DEBUG_EVENTS, "query event table: %s", eventTableList[i].table);
//	debug(DEBUG_TICKER, "query event table: %s", eventTableList[i].table);

	result = db_query(database,
		    "SELECT * FROM %s WHERE blocked = 0 AND end < '%s' "
		    "ORDER BY end ASC, %s ASC LIMIT 0,1",
		    eventTableList[i].table, next_timestamp,
		    eventTableList[i].id_field);

	if (db_result_num_rows(result))	/* is there an earlier event? */
	{
	  /* extract this earlier event's needed data */
	  db_result_next_row(result);

	  next_result = result;		/* remember the earlier one */
	  next_timestamp = db_result_get_string(result, "end");
	  next_db_eventID =
	    db_result_get_string(result, eventTableList[i].id_field);
	  next_eventType = i;
	}
      }

      if (strcmp(next_timestamp, make_timestamp_gm(timestamp, time(NULL))) > 0)
      {
	debug(DEBUG_EVENTS, "no event pending, sleep");
	++sleeps;
	usleep(sleep_time);
      }
      else
      {
	debug(DEBUG_TICKER, "event: scheduled %s, now %s",
	      next_timestamp, timestamp);

	/* check which handler to call (resource ticker or event handler) */
	if (next_result)
	{
	  /* found an event in the event tables: block the event */
	  debug(DEBUG_EVENTS, "block event: %s", next_db_eventID);
	  ++events;

	  db_query(database, "UPDATE %s SET blocked = 1 WHERE %s = %s",
			  eventTableList[next_eventType].table,
			  eventTableList[next_eventType].id_field,
			  next_db_eventID);

	  /* call handler and delete event */
	  eventTableList[next_eventType].handler(database, next_result);

	  debug(DEBUG_EVENTS_DELETE, "delete event: %s", next_db_eventID);

	  db_query(database, "DELETE FROM %s WHERE %s = %s",
			  eventTableList[next_eventType].table,
			  eventTableList[next_eventType].id_field,
			  next_db_eventID);
	}
	else
	{
	  /* next event is resource tick: call resource ticker */
	  debug(DEBUG_TICKER, "resource tick %s", resource_timestamp);

	  resource_ticker(database, tick_advance());
	  debug(DEBUG_TICKER, "resource tick ended");
	  tick_log();			/* log last successful update */
	}
      }
    } catch (BAD_ARGUMENT_EXCEPTION) {
      warning("%s", except_msg);
    } catch (SQL_EXCEPTION) {
      warning("%s", except_msg);
    } catch (GENERIC_EXCEPTION) {
      warning("%s", except_msg);
    } catch (DB_EXCEPTION) {
      block_ticker(except_msg);
    } catch (NULL) {
      error("%s", except_msg);
    } end_try;

    memory_pool_free(pool);
  }

  debug(DEBUG_TICKER, "end");
}
Пример #19
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;
}
Пример #20
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;
}