Quest Completion Event

  • zusuk
  • zusuk's Avatar Topic Author
  • Offline
  • Gold Boarder
  • Gold Boarder
  • LuminariMUD Developer
More
11 months 1 week ago #6989 by zusuk
Quest Completion Event was created by zusuk
So I noticed when you complete a quest via the auto-quest system (quest.*), when the quest is triggered on finding a room, you will get the quest-complete message before you get the room description, and then the player easily misses that from the spam.

We 'solved' this issue by just attaching a mud-event to the character, and having the quest actually complete a pulse later via the event.

Assuming we save this event to the player-file, can anyone anticipate potential issues with this solution?

-Zusuk

Website
www.luminariMUD.com

Main Game Port
luminariMUD.com:4100

Please Log in or Create an account to join the conversation.

More
11 months 1 week ago #6994 by thomas
Replied by thomas on topic Quest Completion Event
sounds reasonable :)

Please Log in or Create an account to join the conversation.

  • zusuk
  • zusuk's Avatar Topic Author
  • Offline
  • Gold Boarder
  • Gold Boarder
  • LuminariMUD Developer
More
11 months 6 days ago #7019 by zusuk
Replied by zusuk on topic Quest Completion Event
Greetings friends:

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.

Find this function in quest.c:
void generic_complete_quest(struct char_data *ch)

Dump this over it:
/* 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)

Thanks in advance for any testing/feedback!!

-Zusuk

Website
www.luminariMUD.com

Main Game Port
luminariMUD.com:4100

Please Log in or Create an account to join the conversation.

Time to create page: 1.150 seconds