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; }
/* * 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); }
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; }
/* * 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); }
//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; }
/* * 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); }
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; }
/* * 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); }
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; }
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)); }
/* * 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); }
/* * 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"); }
/* * 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; }
/* * 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"); }
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; }
/* * 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); }
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; }
/* * 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"); }
/* * 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; }
/* * 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; }