All pastes #28739 Raw Edit

Anonymous

public text v1 · immutable
#28739 ·published 2005-11-15 02:18 UTC
rendered paste body
Index: common/quest.c
===================================================================
RCS file: /cvsroot/crossfire/crossfire/common/quest.c,v
retrieving revision 1.5
diff -C5 -r1.5 quest.c
*** common/quest.c      13 Oct 2005 07:22:43 -0000      1.5
--- common/quest.c      15 Nov 2005 02:15:00 -0000
***************
*** 35,45 ****
  #include <commands.h>
  #ifndef __CEXTRACT__
  #include <sproto.h>
  #endif
  #include <ctype.h>
- #include "quest.h"

  #define QUEST_NAME( op ) op->name_pl
  #define TASK_NAME( op ) op->custom_name

  #if 0
--- 35,44 ----
***************
*** 69,78 ****
--- 68,167 ----
          return 0;
      return 1;
      }
  #endif

+ /* Called during server startup */
+ void init_questhints() {
+     FILE *fp;
+     char filename[MAX_BUF];
+     int comp;
+
+     if(first_questhint!=NULL) /* Only do this once */
+     return;
+
+     sprintf(filename,create_pathname(QUESTHINT_PATH));
+     LOG(llevDebug,"Reading questhints from %s...", filename);
+     if((fp=open_and_uncompress(filename,0,&comp))==NULL) {
+       LOG(llevError," Can't open questhints file %s in init_questhints.\n", filename);
+       return;
+     }
+     char buf[HUGE_BUF], fields[7][HUGE_BUF];
+     int msgpos=0;
+     questhint *new, *quest;
+
+     while (fgets(buf, HUGE_BUF-1, fp)!=NULL) {
+       if (sscanf(buf,"%[^:]:%[^:]:%[^:]:%[^:]:%[^:]:%[^:]:%[^\n]\n",
+           fields[0], fields[1], fields[2], fields[3], fields[4], fields[5], fields[6])!=7) {
+           LOG(llevError,"Warning - malformed quest hint entry: %s\n", buf);
+           continue;
+       }
+       new = malloc(sizeof(questhint));
+       new->markername = strdup_local(fields[0]);
+       new->minlevel = atoi(fields[1]);
+       new->midlevel = atoi(fields[2]);
+       new->maxlevel = atoi(fields[3]);
+       new->reg = get_region_by_name(fields[4]);
+       new->chance = atoi(fields[5]);
+       new->text = strdup_local(fields[6]);
+       /* find the last questhint in the list, and append to it */
+       for (quest=first_questhint; quest!=NULL && quest->next!=NULL; quest=quest->next);
+       if (!quest) first_questhint=new;
+       else quest->next=new;
+       new = NULL;
+     }
+     close_and_delete(fp, comp);
+     LOG(llevDebug,"done.\n");
+ }
+
+ typedef struct quest_values {
+     questhint *quest;
+     uint8 value;
+ } quest_values;
+
+ /* returns a string pointer to an appropriate quest hint for the given player */
+ const char *get_questhint(object *pl) {
+     questhint *quest;
+     quest_values questvalues[1000];
+     int questhint_value;
+     int questcount=0;
+     int value_total = 0;
+     int quest_result, i;
+     if (!pl || pl->type != PLAYER) return NULL;
+     if (!first_questhint) return NULL;
+     for (quest = first_questhint; quest!=NULL; quest=quest->next) {
+       questhint_value = get_questhint_value(quest, pl);
+       if (questhint_value > 0) {
+           questvalues[questcount].quest = quest;
+           value_total += questhint_value;
+           questvalues[questcount].value =value_total;
+           questcount++;
+       }
+     }
+     quest_result = rndm(1, value_total);
+     for (i = 0; i <questcount; i++) {
+       if (questvalues[i].value >= quest_result)
+           return questvalues[i].quest->text;
+     }
+     return NULL;
+ }
+
+ /* Given a questhint, tells us how good it is that the player should be given this hint.
+  * zero means that it is a bad hint to give the player
+  */
+ uint8 get_questhint_value(questhint *quest, object *pl) {
+     int level;
+     if (!pl || pl->type != PLAYER || !quest) return 0;
+     level = pl->level;
+     if (level < quest->minlevel || level > quest->maxlevel)
+       return 0;
+     if ( region_is_child_of_region(pl->map->region, quest->reg) != 1)
+       return 0;
+     /* Note we aren't yet checking that the player is on the quest already, that should go here eventually */
+     return quest->chance;
+ }
+
  int quest_is_quest_marker( object* marker, int task )
      {
      if ( marker->type != QUEST )
          return 0;
      if ( task && !TASK_NAME(marker) )
Index: include/global.h
===================================================================
RCS file: /cvsroot/crossfire/crossfire/include/global.h,v
retrieving revision 1.61
diff -C5 -r1.61 global.h
*** include/global.h    24 Oct 2005 20:48:15 -0000      1.61
--- include/global.h    15 Nov 2005 02:15:05 -0000
***************
*** 155,164 ****
--- 155,167 ----
  #include "recipe.h"

  /* Now for spells */
  #include "spells.h"

+ /* Now for quests */
+ #include "quest.h"
+
  #include "funcpoint.h"

  /*****************************************************************************
   * GLOBAL VARIABLES:                                                       *
   *****************************************************************************/
***************
*** 175,184 ****
--- 178,188 ----
  EXTERN artifactlist *first_artifactlist;
  EXTERN archetype *first_archetype;
  EXTERN objectlink *first_friendly_object;     /* Objects monsters will go after */
  EXTERN godlink *first_god;
  EXTERN racelink *first_race;
+ EXTERN questhint *first_questhint;

  #define NROF_COMPRESS_METHODS 4
  EXTERN char *uncomp[NROF_COMPRESS_METHODS][3];
  /*
   * The editor uses these (will get them out of here later):
Index: include/libproto.h
===================================================================
RCS file: /cvsroot/crossfire/crossfire/include/libproto.h,v
retrieving revision 1.82
diff -C5 -r1.82 libproto.h
*** include/libproto.h  1 Nov 2005 10:08:17 -0000       1.82
--- include/libproto.h  15 Nov 2005 02:15:05 -0000
***************
*** 274,283 ****
--- 274,286 ----
  /* player.c */
  extern void free_player(player *pl);
  extern int atnr_is_dragon_enabled(int attacknr);
  extern int is_dragon_pl(object *op);
  /* quest.c */
+ extern void init_questhints();
+ extern const char *get_questhint(object *pl);
+ extern uint8 get_questhint_value(questhint *quest, object *pl);
  extern int quest_is_quest_marker(object *marker, int task);
  extern int quest_is_in_progress(object *marker, int task);
  extern int quest_is_completed(object *marker, int task);
  extern const char *quest_get_name(object *marker);
  extern object *quest_get_player_quest(object *pl, const char *name, const char *name_pl);
Index: include/quest.h
===================================================================
RCS file: /cvsroot/crossfire/crossfire/include/quest.h,v
retrieving revision 1.1
diff -C5 -r1.1 quest.h
*** include/quest.h     14 Jul 2005 16:21:32 -0000      1.1
--- include/quest.h     15 Nov 2005 02:15:05 -0000
***************
*** 7,11 ****
--- 7,25 ----
  #define QUEST_START     " start"
  /* End of slaying field of force indicating a completed quest */
  #define QUEST_END       " end"

  #endif /* QUEST_H */
+
+ #define QUESTHINT_PATH "quests/hints"
+
+ /* Quest hint definition */
+ typedef struct quest_hint {
+     const char *markername;
+     uint8 minlevel;
+     uint8 midlevel;
+     uint8 maxlevel;
+     uint8 chance;
+     const region *reg;
+     const char *text;
+     struct quest_hint *next;
+ } questhint;
Index: server/init.c
===================================================================
RCS file: /cvsroot/crossfire/crossfire/server/init.c,v
retrieving revision 1.69
diff -C5 -r1.69 init.c
*** server/init.c       28 Oct 2005 19:08:53 -0000      1.69
--- server/init.c       15 Nov 2005 02:15:12 -0000
***************
*** 769,778 ****
--- 769,779 ----
    init_archetype_pointers(); /* Setup global pointers to archetypes */
    init_races();          /* overwrite race designations using entries in lib/races file */
    init_gods();        /* init linked list of gods from archs*/
    init_readable();    /* inits useful arrays for readable texts */
    init_formulae();  /* If not called before, reads formulae from file */
+   init_questhints(); /* used to lead players vaguely towards quests */

    switch(settings.dumpvalues) {
    case 1:
      print_monsters();
      exit(0);
Index: server/monster.c
===================================================================
RCS file: /cvsroot/crossfire/crossfire/server/monster.c,v
retrieving revision 1.95
diff -C5 -r1.95 monster.c
*** server/monster.c    9 Nov 2005 19:34:17 -0000       1.95
--- server/monster.c    15 Nov 2005 02:15:20 -0000
***************
*** 1505,1519 ****
  {
      const char *cp=msg, *cp1, *cp2;
      char *cp3, regex[MAX_BUF], gotmatch=0;

      while (1) {
!       if (strncmp(cp, "@match ", 7)) {
!           LOG(llevDebug,"find_matching_message: Invalid message %s", msg);
!           return NULL;
!       }
!       else {
            /* Find the end of the line, and copy the regex portion into it */
            cp2 = strchr(cp+7, '\n');
            strncpy(regex, cp+7, (cp2 - cp -7 ));
            regex[cp2 - cp -7] = 0;

--- 1505,1515 ----
  {
      const char *cp=msg, *cp1, *cp2;
      char *cp3, regex[MAX_BUF], gotmatch=0;

      while (1) {
!       if (!strncmp(cp, "@match ", 7)) {
            /* Find the end of the line, and copy the regex portion into it */
            cp2 = strchr(cp+7, '\n');
            strncpy(regex, cp+7, (cp2 - cp -7 ));
            regex[cp2 - cp -7] = 0;

***************
*** 1554,1563 ****
--- 1550,1567 ----
            }
          gotmatch = 0;
            if (cp1) cp = cp1 + 1;
            else return NULL;
        }
+       else if (!strncmp(cp, "@questhint", 10)) {
+           cp3 = strdup_local(get_questhint(pl));
+           return cp3;
+       }
+       else {
+           LOG(llevDebug,"find_matching_message: Invalid message %s", msg);
+           return NULL;
+       }
      }
      /* Should never get reached */
  }

  /* This function looks for an object or creature that is listening.