So here is what I slapped together... looking for assistance cleaning it up and testing to see if this is not problematic since I lack play-testers ;p I also do not have a keen eye for memory leaks and that kinda jazz.
Code:
/* called when a quest is completed! */
void complete_quest(struct char_data *ch) {
qst_rnum rnum = -1;
qst_vnum vnum = GET_QUEST(ch);
struct obj_data *new_obj = NULL;
int happy_qp = 0, happy_gold = 0, happy_exp = 0;
/* dummy check */
if (GET_QUEST(ch) == NOTHING) {
log("UH OH: complete_quest() called without a quest VNUM!");
return;
}
/* we should NOT be getting this */
if (GET_QUEST_COUNTER(ch) > 0) {
send_to_char(ch, "You still have to achieve \tm%d\tn out of \tM%d\tn goals for the quest.\r\n\r\n",
--GET_QUEST_COUNTER(ch), QST_QUANTITY(rnum));
save_char(ch, 0);
log("UH OH: complete_quest() quest-counter is greater than zero!");
return;
}
rnum = real_quest(vnum);
/* Quest complete! */
/* any quest point reward for this quest? */
if (IS_HAPPYHOUR && IS_HAPPYQP) {
happy_qp = (int) (QST_POINTS(rnum) * (((float) (100 + HAPPY_QP)) / (float) 100));
happy_qp = MAX(happy_qp, 0);
GET_QUESTPOINTS(ch) += happy_qp;
send_to_char(ch,
"%s\r\nYou have been awarded %d \tCquest points\tn for your service.\r\n\r\n",
QST_DONE(rnum), happy_qp);
} else { /* no happy hour bonus :( */
GET_QUESTPOINTS(ch) += QST_POINTS(rnum);
send_to_char(ch,
"%s\r\nYou have been awarded %d \tCquest points\tn for your service.\r\n\r\n",
QST_DONE(rnum), QST_POINTS(rnum));
}
/* any gold reward in this quest? */
if (QST_GOLD(rnum)) {
if ((IS_HAPPYHOUR) && (IS_HAPPYGOLD)) {
happy_gold = (int) (QST_GOLD(rnum) * (((float) (100 + HAPPY_GOLD)) / (float) 100));
happy_gold = MAX(happy_gold, 0);
increase_gold(ch, happy_gold);
send_to_char(ch,
"You have been awarded %d \tYgold coins\tn for your service.\r\n\r\n",
happy_gold);
} else {
increase_gold(ch, QST_GOLD(rnum));
send_to_char(ch,
"You have been awarded %d \tYgold coins\tn for your service.\r\n\r\n",
QST_GOLD(rnum));
}
}
/* any xp points reward in this quest? */
if (QST_EXP(rnum)) {
gain_exp(ch, QST_EXP(rnum));
if ((IS_HAPPYHOUR) && (IS_HAPPYEXP)) {
happy_exp = (int) (QST_EXP(rnum) * (((float) (100 + HAPPY_EXP)) / (float) 100));
happy_exp = MAX(happy_exp, 0);
send_to_char(ch,
"You have been awarded %d \tBexperience\tn for your service.\r\n\r\n",
happy_exp);
} else {
send_to_char(ch,
"You have been awarded %d \tBexperience\tn points for your service.\r\n\r\n",
QST_EXP(rnum));
}
}
/* any object reward from this quest? */
if (QST_OBJ(rnum) && QST_OBJ(rnum) != NOTHING) {
if (real_object(QST_OBJ(rnum)) != NOTHING) {
if ((new_obj = read_object((QST_OBJ(rnum)), VIRTUAL)) != NULL) {
obj_to_char(new_obj, ch);
send_to_char(ch, "You have been presented with %s%s for your service.\r\n\r\n",
GET_OBJ_SHORT(new_obj), CCNRM(ch, C_NRM));
}
}
}
/* end rewards */
/* handle throwing quest in history and repeatable quests */
if (!IS_SET(QST_FLAGS(rnum), AQ_REPEATABLE))
add_completed_quest(ch, vnum);
/* clear the quest data from ch, clean slate */
clear_quest(ch);
/* does this quest have a next step built in? */
if ((real_quest(QST_NEXT(rnum)) != NOTHING) &&
(QST_NEXT(rnum) != vnum) &&
!is_complete(ch, QST_NEXT(rnum))) {
rnum = real_quest(QST_NEXT(rnum));
set_quest(ch, rnum);
send_to_char(ch,
"\tW***The next stage of your quest awaits:\tn\r\n\r\n%s\r\n",
QST_INFO(rnum));
}
}
/* this function is called upon completion of a quest
* or completion of a quest-step
* NOTE: We added the actual completion to an event that
* will call: void complete_quest() above */
void generic_complete_quest(struct char_data *ch) {
/* more work to do on this quest! make sure to decrement counter */
if (GET_QUEST(ch) != NOTHING && --GET_QUEST_COUNTER(ch) > 0) {
qst_rnum rnum = -1;
qst_vnum vnum = GET_QUEST(ch);
rnum = real_quest(vnum);
send_to_char(ch, "You still have to achieve \tm%d\tn out of \tM%d\tn goals for the quest.\r\n\r\n",
GET_QUEST_COUNTER(ch), QST_QUANTITY(rnum));
save_char(ch, 0);
/* the quest is truly complete? */
} else if (GET_QUEST(ch) != NOTHING) {
struct mud_event_data *pMudEvent = NULL;
char buf[128] = { '\0' };
qst_vnum event_quest_num = NOTHING;
if ((pMudEvent = char_has_mud_event(ch, eQUEST_COMPLETE))) {
/* grab vnum of quest that is in event */
event_quest_num = atoi((char *) pMudEvent->sVariables);
/* make sure we do not already have an event for this quest! */
if (event_quest_num == GET_QUEST(ch)) {
/* get out of here, we are already processing this particular
quest completion */
return;
}
}
/* we should be in the clear to tag this player with a completed quest */
sprintf(buf, "%d", GET_QUEST(ch)); /* sending vnum to event of quest */
attach_mud_event(new_mud_event(eQUEST_COMPLETE, ch, buf), 1);
}
}
Also just make sure you add the eQuest_complete as an event cooldown and save the event to your pfile (players.c)