Esempio n. 1
0
int quest_change(TBL_PC * sd, int qid1, int qid2)
{

	int i, j;

	if( quest_check(sd, qid2, HAVEQUEST) >= 0 )
	{
		ShowError("quest_change: Character %d already has quest %d.\n", sd->status.char_id, qid2);
		return -1;
	}

	if( quest_check(sd, qid1, HAVEQUEST) < 0 )
	{
		ShowError("quest_change: Character %d doesn't have quest %d.\n", sd->status.char_id, qid1);
		return -1;
	}

	if( (j = quest_search_db(qid2)) < 0 )
	{
		ShowError("quest_change: quest %d not found in DB.\n",qid2);
		return -1;
	}

	ARR_FIND(0, sd->avail_quests, i, sd->quest_log[i].quest_id == qid1);
	if(i == sd->avail_quests)
	{
		ShowError("quest_change: Character %d has completed quests %d.\n", sd->status.char_id, qid1);
		return -1;
	}

	memset(&sd->quest_log[i], 0, sizeof(struct quest));
	sd->quest_log[i].quest_id = quest_db[j].id;
	if( quest_db[j].time )
		sd->quest_log[i].time = (unsigned int)(time(NULL) + quest_db[j].time);
	sd->quest_log[i].state = Q_ACTIVE;

	sd->quest_index[i] = j;
	sd->save_quest = true;

	clif_quest_delete(sd, qid1);
	clif_quest_add(sd, &sd->quest_log[i], sd->quest_index[i]);

	if( save_settings&64 )
		chrif_save(sd,0);

	return 0;
}
Esempio n. 2
0
/**
 * NPC quest/event icon check
 * @author [Kisuka]
 */
void questinfo_update_status(TBL_PC *sd) {
	unsigned short i = 0;

#if PACKETVER >= 20090218
	for( i = 0; i < map[sd->bl.m].qi_count; i++ ) {
		struct questinfo *qi = &map[sd->bl.m].qi_data[i];
		int j = quest_check(sd, qi->id1, HAVEQUEST);
		int k = quest_check(sd, qi->id2, HAVEQUEST);

		j = j + (j < 1);
		k = k + (k < 1);
		if( qi->state1 == j ) {
			if( !qi->id2 ) {
				if( qi->hasJob ) {
					if( (qi->mask && ((qi->class_ == -1 && (sd->class_&qi->mask)) ||
						(qi->class_ != -1 && (sd->class_&qi->mask) == qi->class_))) ||
						(!qi->mask && qi->class_ != -1 && sd->status.class_ == qi->class_) )
						clif_quest_show_event(sd, &qi->nd->bl, qi->icon, qi->color);
				} else
					clif_quest_show_event(sd, &qi->nd->bl, qi->icon, qi->color);
			} else {
				if( qi->state2 == k ) {
					if( qi->hasJob ) {
						if( (qi->mask && ((qi->class_ == -1 && (sd->class_&qi->mask)) ||
							(qi->class_ != -1 && (sd->class_&qi->mask) == qi->class_))) ||
							(!qi->mask && qi->class_ != -1 && sd->status.class_ == qi->class_) )
							clif_quest_show_event(sd, &qi->nd->bl, qi->icon, qi->color);
					} else
						clif_quest_show_event(sd, &qi->nd->bl, qi->icon, qi->color);
				} else {
	#if PACKETVER >= 20120410
					clif_quest_show_event(sd, &qi->nd->bl, 9999, 0);
	#else
					clif_quest_show_event(sd, &qi->nd->bl, 0, 0);
	#endif
				}
			}
		} else {
	#if PACKETVER >= 20120410
					clif_quest_show_event(sd, &qi->nd->bl, 9999, 0);
	#else
					clif_quest_show_event(sd, &qi->nd->bl, 0, 0);
	#endif
		}
	}
#endif
}
Esempio n. 3
0
/**
 * Handles the "death" of a monster.
 *
 * Disperses treasures carried by the monster centered at the monster location.
 * Note that objects dropped may disappear in crowded rooms.
 *
 * Checks for "Quest" completion when a quest monster is killed.
 *
 * Note that only the player can induce "monster_death()" on Uniques.
 * Thus (for now) all Quest monsters should be Uniques.
 *
 * If `stats` is true, then we skip updating the monster memory. This is
 * used by stats-generation code, for efficiency.
 */
void monster_death(struct monster *mon, bool stats)
{
	int dump_item = 0;
	int dump_gold = 0;
	struct object *obj = mon->held_obj;

	bool visible = (mflag_has(mon->mflag, MFLAG_VISIBLE) ||
					rf_has(mon->race->flags, RF_UNIQUE));

	/* Delete any mimicked objects */
	if (mon->mimicked_obj)
		object_delete(&mon->mimicked_obj);

	/* Drop objects being carried */
	while (obj) {
		struct object *next = obj->next;

		/* Object no longer held */
		obj->held_m_idx = 0;
		pile_excise(&mon->held_obj, obj);

		/* Count it and drop it - refactor once origin is a bitflag */
		if (!stats) {
			if (tval_is_money(obj) && (obj->origin != ORIGIN_STOLEN))
				dump_gold++;
			else if (!tval_is_money(obj) && ((obj->origin == ORIGIN_DROP)
					|| (obj->origin == ORIGIN_DROP_PIT)
					|| (obj->origin == ORIGIN_DROP_VAULT)
					|| (obj->origin == ORIGIN_DROP_SUMMON)
					|| (obj->origin == ORIGIN_DROP_SPECIAL)
					|| (obj->origin == ORIGIN_DROP_BREED)
					|| (obj->origin == ORIGIN_DROP_POLY)
					|| (obj->origin == ORIGIN_DROP_WIZARD)))
				dump_item++;
		}

		/* Change origin if monster is invisible, unless we're in stats mode */
		if (!visible && !stats)
			obj->origin = ORIGIN_DROP_UNKNOWN;

		drop_near(cave, obj, 0, mon->fy, mon->fx, true);
		obj = next;
	}

	/* Forget objects */
	mon->held_obj = NULL;

	/* Take note of any dropped treasure */
	if (visible && (dump_item || dump_gold))
		lore_treasure(mon, dump_item, dump_gold);

	/* Update monster list window */
	player->upkeep->redraw |= PR_MONLIST;

	/* Check if we finished a quest */
	quest_check(mon);
}
Esempio n. 4
0
int quest_add(TBL_PC * sd, int quest_id)
{

	int i, j;

	if( sd->num_quests >= MAX_QUEST_DB )
	{
		ShowError("quest_add: Character %d has got all the quests.(max quests: %d)\n", sd->status.char_id, MAX_QUEST_DB);
		return 1;
	}

	if( quest_check(sd, quest_id, HAVEQUEST) >= 0 )
	{
		ShowError("quest_add: Character %d already has quest %d.\n", sd->status.char_id, quest_id);
		return -1;
	}

	if( (j = quest_search_db(quest_id)) < 0 )
	{
		ShowError("quest_add: quest %d not found in DB.\n", quest_id);
		return -1;
	}

	i = sd->avail_quests;
	memmove(&sd->quest_log[i+1], &sd->quest_log[i], sizeof(struct quest)*(sd->num_quests-sd->avail_quests));
	memmove(sd->quest_index+i+1, sd->quest_index+i, sizeof(int)*(sd->num_quests-sd->avail_quests));

	memset(&sd->quest_log[i], 0, sizeof(struct quest));
	sd->quest_log[i].quest_id = quest_db[j].id;
	if( quest_db[j].time )
		sd->quest_log[i].time = (unsigned int)(time(NULL) + quest_db[j].time);
	sd->quest_log[i].state = Q_ACTIVE;

	sd->quest_index[i] = j;
	sd->num_quests++;
	sd->avail_quests++;
	sd->save_quest = true;

	clif_quest_add(sd, &sd->quest_log[i], sd->quest_index[i]);

	if( save_settings&64 )
		chrif_save(sd,0);

	return 0;
}
Esempio n. 5
0
/**
 * Adds a quest to the player's list.
 * New quest will be added as Q_ACTIVE.
 * @param sd : Player's data
 * @param quest_id : ID of the quest to add.
 * @return 0 in case of success, nonzero otherwise
 */
int quest_add(TBL_PC *sd, int quest_id)
{
	int n;
	struct quest_db *qi = quest_db(quest_id);

	if( qi == &quest_dummy ) {
		ShowError("quest_add: quest %d not found in DB.\n", quest_id);
		return -1;
	}

	if( quest_check(sd, quest_id, HAVEQUEST) >= 0 ) {
		ShowError("quest_add: Character %d already has quest %d.\n", sd->status.char_id, quest_id);
		return -1;
	}

	n = sd->avail_quests; //Insertion point

	sd->num_quests++;
	sd->avail_quests++;
	RECREATE(sd->quest_log, struct quest, sd->num_quests);

	//The character has some completed quests, make room before them so that they will stay at the end of the array
	if( sd->avail_quests != sd->num_quests )
		memmove(&sd->quest_log[n + 1], &sd->quest_log[n], sizeof(struct quest) * (sd->num_quests-sd->avail_quests));

	memset(&sd->quest_log[n], 0, sizeof(struct quest));

	sd->quest_log[n].quest_id = qi->id;
	if( qi->time )
		sd->quest_log[n].time = (unsigned int)(time(NULL) + qi->time);
	sd->quest_log[n].state = Q_ACTIVE;

	sd->save_quest = true;

	clif_quest_add(sd, &sd->quest_log[n]);
	clif_quest_update_objective(sd, &sd->quest_log[n]);

	if( save_settings&CHARSAVE_QUEST )
		chrif_save(sd,0);

	return 0;
}
Esempio n. 6
0
/*
 * Note that "feeling" is set to zero unless some time has passed.
 * Note that this is done when the level is GENERATED, not entered.
 */
void do_cmd_feeling(void)
{
    bool is_quest_level = quest_check(p_ptr->depth);

    /* No sensing things in Moria */
    if (game_mode == GAME_NPPMORIA) return;

    /* No useful feeling in town */
    if (!p_ptr->depth)
    {
        message(QString("Looks like a typical town."));
        return;
    }

    /* No useful feelings until enough time has passed */
    if (!do_feeling)
    {
        message(QString("You are still uncertain about this level..."));
        return;
    }

    if (p_ptr->dungeon_type == DUNGEON_TYPE_WILDERNESS)
    {
        if (is_quest_level) 	message(QString("You have entered a wilderness level on the verge of destruction!."));
        else 					message(QString("You have entered an area of near pristine wilderness."));
    }

    else if (p_ptr->dungeon_type == DUNGEON_TYPE_GREATER_VAULT)
    {
        message(QString("You have discovered a gigantic vault of great treasures guarded by dangerous creatures."));
    }

    else if (p_ptr->dungeon_type == DUNGEON_TYPE_LABYRINTH)
    {
        if (is_quest_level) message(QString("You have entered a tiny, closely guarded labyrinth."));
        else message(QString("You have entered a complex labyrinth of dungeon hallways."));
    }

    else if (p_ptr->dungeon_type == DUNGEON_TYPE_ARENA)
    {
        message(QString("You are in an arena fighting for your life."));
    }

    /* Verify the feeling */
    else if (feeling >= LEV_THEME_HEAD)
    {

        /*print out a message about a themed level*/
        QString note;
        QString mon_theme;


        note = (QString("You have entered "));
        mon_theme = (QString(feeling_themed_level[feeling - LEV_THEME_HEAD]));
        if (begins_with_vowel(mon_theme)) note.append(QString("an "));
        else note.append(QString("a "));

        note.append(QString("%1 stronghold.") .arg(mon_theme));

        message(note);
    }

    /* Display the feeling */
    else message(QString(do_cmd_feeling_text[feeling]));

    /* Redraw the feeling indicator */
    p_ptr->redraw |= (PR_SIDEBAR_PL);
}