rendered paste bodyIndex: 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.