Ejemplo n.º 1
0
int cmd_pan_init(struct command *cmd)
{
	int	err, mode = 0, i;

	__argv = &__argv[optind];

	if (cmd->cmd == 0)
		mode = AFFIX_PAN_PANU;

	for (i = 0; *__argv; __argv++, i++) {
		if (i == 0) {
			mode = str2role(*__argv);
			if (!mode) {
				fprintf(stderr, "invalid role: %s\n", *__argv);
				return 1;
			}
		} else {
			/* flags */
			if (strcasecmp(*__argv, "auto") == 0)
				mode |= AFFIX_PAN_AUTO;
		}
	}
	err = affix_pan_init(btdev, mode);
	if (err) {
		BTERROR("PAN init/stop failed\n");
		fprintf(stderr, "%s\n", hci_error(err));
		exit(1);
	}
	return err;	
}
Ejemplo n.º 2
0
static void
fill_nh_score_entry(struct toptenentry *in, struct nh_topten_entry *out,
                    int rank, boolean highlight)
{

    int rolenum = str2role(in->plrole);
    int racenum = str2race(in->plrace);
    int gendnum = str2gend(in->plgend);
    int alignnum = str2align(in->plalign);

    if (rolenum == ROLE_NONE || racenum == ROLE_NONE || gendnum == ROLE_NONE ||
        alignnum == ROLE_NONE)
        return;

    out->rank = rank;
    out->points = in->points;
    out->maxlvl = in->maxlvl;
    out->hp = in->hp;
    out->maxhp = in->maxhp;
    out->deaths = in->deaths;
    out->ver_major = in->ver_major;
    out->ver_minor = in->ver_minor;
    out->patchlevel = in->patchlevel;
    out->highlight = highlight;
    out->moves = in->moves;
    out->end_how = in->how;

    strncpy(out->name, in->name, NAMSZ);
    strncpy(out->death, in->death, DTHSZ);

    if (gendnum == 1 && roles[rolenum].name.f)
        strncpy(out->plrole, roles[rolenum].name.f, PLRBUFSZ);
    else
        strncpy(out->plrole, roles[rolenum].name.m, PLRBUFSZ);

    strncpy(out->plrace, races[racenum].noun, PLRBUFSZ);
    strncpy(out->plgend, genders[gendnum].adj, PLRBUFSZ);
    strncpy(out->plalign, aligns[alignnum].adj, PLRBUFSZ);

    topten_death_description(in, out->entrytxt);
}
Ejemplo n.º 3
0
void curses_choose_character()
{
    int n, i, sel, count_off, pick4u;
    int count = 0;
    int cur_character = 0;
    const char** choices;
    int* pickmap;
    char *prompt;
    char pbuf[QBUFSZ];
    char choice[QBUFSZ];
    char tmpchoice[QBUFSZ];
#ifdef TUTORIAL_MODE
	winid win;
	anything any;
	menu_item *selected = 0;
#endif

	prompt = build_plselection_prompt(pbuf, QBUFSZ, flags.initrole,
	 flags.initrace, flags.initgend, flags.initalign);

    /* This part is irritating: we have to strip the choices off of
    the string and put them in a separate string in order to use
    curses_character_input_dialog for this prompt. */

    while (cur_character != '[')
    {
        cur_character = prompt[count];
        count++;
    }
    
    count_off = count;
    
    while (cur_character != ']')
    {
        tmpchoice[count - count_off] = prompt[count];
        count++;
        cur_character = prompt[count];
    }
    
    tmpchoice[count - count_off] = '\0';
    lcase(tmpchoice);
    
    while (!isspace(prompt[count_off]))
    {
        count_off--;
    }
    
    prompt[count_off] = '\0';
    sprintf(choice, "%s%c", tmpchoice, '\033');
    if(strchr(tmpchoice, 't'))  /* Tutorial mode */
    {
        mvaddstr(0, 1, "New? Press t to enter a tutorial.");
    }
    
    /* Add capital letters as choices that aren't displayed */
    
    for (count = 0; tmpchoice[count]; count++)
    {
        tmpchoice[count] = toupper(tmpchoice[count]);
    }
    
    sprintf(choice, "%s%s", choice, tmpchoice);

    /* prevent an unnecessary prompt */
    rigid_role_checks(); 
    
	if (!flags.randomall &&
	    (flags.initrole == ROLE_NONE || flags.initrace == ROLE_NONE ||
	     flags.initgend == ROLE_NONE || flags.initalign == ROLE_NONE))
	{
        pick4u = tolower(curses_character_input_dialog(prompt, choice,
         'y'));
    }
    else
    {
        pick4u = 'y';
    }
    
    if (pick4u == 'q')  /* Quit or cancelled */
    {
	    clearlocks();
	    curses_bail(0);
    }
    
    if (pick4u == 'y')
    {
        flags.randomall = TRUE;
    }
#ifdef TUTORIAL_MODE
    else if (pick4u == 't') /* Tutorial mode in UnNetHack */
    {
	    clear();
        mvaddstr(0, 1, "Choose a character");
        refresh();
	    win = curses_get_wid(NHW_MENU);
        curses_create_nhmenu(win);
	    any.a_int = 1;
	    curses_add_menu(win, NO_GLYPH, &any, 'v', 0, ATR_NONE,
		     "lawful female dwarf Valkyrie (uses melee and thrown weapons)",
		     MENU_UNSELECTED);
	    any.a_int = 2;
	    curses_add_menu(win, NO_GLYPH, &any, 'w', 0, ATR_NONE,
		     "chaotic male elf Wizard (relies mostly on spells)",
		     MENU_UNSELECTED);
	    any.a_int = 3;
	    curses_add_menu(win, NO_GLYPH, &any, 'R', 0, ATR_NONE,
		     "neutral female human Ranger (good with ranged combat)",
		     MENU_UNSELECTED);
	    any.a_int = 4;
	    curses_add_menu(win, NO_GLYPH, &any, 'q', 0, ATR_NONE,
		     "quit", MENU_UNSELECTED);
	    curses_end_menu(win, "What character do you want to try?");
	    n = curses_select_menu(win, PICK_ONE, &selected);
	    destroy_nhwindow(win);
	    if (n != 1 || selected[0].item.a_int == 4)
	    {
    	    clearlocks();
    	    curses_bail(0);
	    }
	    switch (selected[0].item.a_int) {
	    case 1:
		flags.initrole = str2role("Valkyrie");
		flags.initrace = str2race("dwarf");
		flags.initgend = str2gend("female");
		flags.initalign = str2align("lawful");
		break;
	    case 2:
		flags.initrole = str2role("Wizard");
		flags.initrace = str2race("elf");
		flags.initgend = str2gend("male");
		flags.initalign = str2align("chaotic");
		break;
	    case 3:
		flags.initrole = str2role("Ranger");
		flags.initrace = str2race("human");
		flags.initgend = str2gend("female");
		flags.initalign = str2align("neutral");
		break;
	    default: panic("Impossible menu selection"); break;
	    }
	    free((genericptr_t) selected);
	    selected = 0;
	    flags.tutorial = 1;
	}
#endif
    
    clear();
    refresh();

    if (!flags.randomall && flags.initrole < 0) {
	/* select a role */
	for (n = 0; roles[n].name.m; n++) continue;
	choices = (const char **)alloc(sizeof(char *) * (n+1));
	pickmap = (int*)alloc(sizeof(int) * (n+1));
	for (;;) {
	    for (n = 0, i = 0; roles[i].name.m; i++) {
		if (ok_role(i, flags.initrace,
			    flags.initgend, flags.initalign)) {
		    if (flags.initgend >= 0 && flags.female && roles[i].name.f)
			choices[n] = roles[i].name.f;
		    else
			choices[n] = roles[i].name.m;
		    pickmap[n++] = i;
		}
	    }
	    if (n > 0) break;
	    else if (flags.initalign >= 0) flags.initalign = -1;    /* reset */
	    else if (flags.initgend >= 0) flags.initgend = -1;
	    else if (flags.initrace >= 0) flags.initrace = -1;
	    else panic("no available ROLE+race+gender+alignment combinations");
	}
	choices[n] = (const char *) 0;
	if (n > 1)
        sel = curses_character_dialog(choices, "Choose one of the following roles:");
	else sel = 0;
	if (sel >= 0) sel = pickmap[sel];
	else if (sel == ROLE_NONE) {		/* Quit */
	    clearlocks();
	    curses_bail(0);
	}
	free(choices);
	free(pickmap);
    } else if (flags.initrole < 0) sel = ROLE_RANDOM;
    else sel = flags.initrole;
  
    if (sel == ROLE_RANDOM) {	/* Random role */
	sel = pick_role(flags.initrace, flags.initgend,
			  flags.initalign, PICK_RANDOM);
	if (sel < 0) sel = randrole();
    }

    flags.initrole = sel;

    /* Select a race, if necessary */
    /* force compatibility with role, try for compatibility with
     * pre-selected gender/alignment */
    if (flags.initrace < 0 || !validrace(flags.initrole, flags.initrace)) {
	if (flags.initrace == ROLE_RANDOM || flags.randomall) {
	    flags.initrace = pick_race(flags.initrole, flags.initgend,
				       flags.initalign, PICK_RANDOM);
	    if (flags.initrace < 0) flags.initrace = randrace(flags.initrole);
	} else {
	    /* Count the number of valid races */
	    n = 0;	/* number valid */
	    for (i = 0; races[i].noun; i++) {
		if (ok_race(flags.initrole, i, flags.initgend, flags.initalign))
		    n++;
	    }
	    if (n == 0) {
		for (i = 0; races[i].noun; i++) {
		    if (validrace(flags.initrole, i)) n++;
		}
	    }

	    choices = (const char **)alloc(sizeof(char *) * (n+1));
	    pickmap = (int*)alloc(sizeof(int) * (n + 1));
	    for (n = 0, i = 0; races[i].noun; i++) {
		if (ok_race(flags.initrole, i, flags.initgend,
			    flags.initalign)) {
		    choices[n] = races[i].noun;
		    pickmap[n++] = i;
		}
	    }
	    choices[n] = (const char *) 0;
	    /* Permit the user to pick, if there is more than one */
	    if (n > 1)
		sel = curses_character_dialog(choices, "Choose one of the following races:");
	    else sel = 0;
	    if (sel >= 0) sel = pickmap[sel];
	    else if (sel == ROLE_NONE) { /* Quit */
		clearlocks();
		curses_bail(0);
	    }
	    flags.initrace = sel;
	    free(choices);
	    free(pickmap);
	}
	if (flags.initrace == ROLE_RANDOM) {	/* Random role */
	    sel = pick_race(flags.initrole, flags.initgend,
			    flags.initalign, PICK_RANDOM);
	    if (sel < 0) sel = randrace(flags.initrole);
	    flags.initrace = sel;
	}
    }

    /* Select a gender, if necessary */
    /* force compatibility with role/race, try for compatibility with
     * pre-selected alignment */
    if (flags.initgend < 0 ||
	!validgend(flags.initrole, flags.initrace, flags.initgend)) {
	if (flags.initgend == ROLE_RANDOM || flags.randomall) {
	    flags.initgend = pick_gend(flags.initrole, flags.initrace,
				       flags.initalign, PICK_RANDOM);
	    if (flags.initgend < 0)
		flags.initgend = randgend(flags.initrole, flags.initrace);
	} else {
	    /* Count the number of valid genders */
	    n = 0;	/* number valid */
	    for (i = 0; i < ROLE_GENDERS; i++) {
		if (ok_gend(flags.initrole, flags.initrace, i, flags.initalign))
		    n++;
	    }
	    if (n == 0) {
		for (i = 0; i < ROLE_GENDERS; i++) {
		    if (validgend(flags.initrole, flags.initrace, i)) n++;
		}
	    }

	    choices = (const char **)alloc(sizeof(char *) * (n+1));
	    pickmap = (int*)alloc(sizeof(int) * (n + 1));
	    for (n = 0, i = 0; i < ROLE_GENDERS; i++) {
		if (ok_gend(flags.initrole, flags.initrace, i,
				flags.initalign)) {
		    choices[n] = genders[i].adj;
		    pickmap[n++] = i;
		}
	    }
	    choices[n] = (const char *) 0;
	    /* Permit the user to pick, if there is more than one */
	    if (n > 1)
		sel = curses_character_dialog(choices, "Choose one of the following genders:");
	    else sel = 0;
	    if (sel >= 0) sel = pickmap[sel];
	    else if (sel == ROLE_NONE) { /* Quit */
		clearlocks();
		curses_bail(0);
	    }
	    flags.initgend = sel;
	    free(choices);
	    free(pickmap);
	}
	if (flags.initgend == ROLE_RANDOM) {	/* Random gender */
	    sel = pick_gend(flags.initrole, flags.initrace,
			    flags.initalign, PICK_RANDOM);
	    if (sel < 0) sel = randgend(flags.initrole, flags.initrace);
	    flags.initgend = sel;
	}
    }

    /* Select an alignment, if necessary */
    /* force compatibility with role/race/gender */
    if (flags.initalign < 0 ||
	!validalign(flags.initrole, flags.initrace, flags.initalign)) {
	if (flags.initalign == ROLE_RANDOM || flags.randomall) {
	    flags.initalign = pick_align(flags.initrole, flags.initrace,
					 flags.initgend, PICK_RANDOM);
	    if (flags.initalign < 0)
		flags.initalign = randalign(flags.initrole, flags.initrace);
	} else {
	    /* Count the number of valid alignments */
	    n = 0;	/* number valid */
	    for (i = 0; i < ROLE_ALIGNS; i++) {
		if (ok_align(flags.initrole, flags.initrace, flags.initgend, i))
		    n++;
	    }
	    if (n == 0) {
		for (i = 0; i < ROLE_ALIGNS; i++)
		    if (validalign(flags.initrole, flags.initrace, i)) n++;
	    }

	    choices = (const char **)alloc(sizeof(char *) * (n+1));
	    pickmap = (int*)alloc(sizeof(int) * (n + 1));
	    for (n = 0, i = 0; i < ROLE_ALIGNS; i++) {
		if (ok_align(flags.initrole,
			     flags.initrace, flags.initgend, i)) {
		    choices[n] = aligns[i].adj;
		    pickmap[n++] = i;
		}
	    }
	    choices[n] = (const char *) 0;
	    /* Permit the user to pick, if there is more than one */
	    if (n > 1)
		sel = curses_character_dialog(choices, "Choose one of the following alignments:");
	    else sel = 0;
	    if (sel >= 0) sel = pickmap[sel];
	    else if (sel == ROLE_NONE) { /* Quit */
		clearlocks();
		curses_bail(0);
	    }
	    flags.initalign = sel;
	    free(choices);
	    free(pickmap);
	}
	if (flags.initalign == ROLE_RANDOM) {
	    sel = pick_align(flags.initrole, flags.initrace,
			     flags.initgend, PICK_RANDOM);
	    if (sel < 0) sel = randalign(flags.initrole, flags.initrace);
	    flags.initalign = sel;
	}
    }
}
Ejemplo n.º 4
0
int cmd_pan_connect(struct command *cmd)
{
	int		err, role = AFFIX_PAN_NAP;
	BD_ADDR		bda;
	struct sockaddr_affix	saddr;

	__argv = &__argv[optind];

	if (!*__argv) {
		printf("Address missing\n");
		print_usage(cmd);
		return 1;
	}
	err = btdev_get_bda(&bda, *__argv);
	if (err) {
		printf("Incorrect address given\n");
		return 1;
	}
	if (*(++__argv)) {
		/* role */
		role = str2role(*__argv);
		if (!role) {
			fprintf(stderr, "invalid role: %s\n", *__argv);
			return 1;
		}
	}

	saddr.family = PF_AFFIX;
	saddr.bda = bda;
	saddr.devnum = HCIDEV_ANY;

#if defined(CONFIG_AFFIX_SDP)
	if (sdpmode) {
		uint16_t	ServiceID;
		uint16_t	count;
		slist_t		*searchList = NULL;
		slist_t		*attrList = NULL;
		slist_t		*svcList = NULL;
		sdpsvc_t	*svcRec;

		if (role == AFFIX_PAN_NAP)
			ServiceID = SDP_UUID_NAP;
		else if (role == AFFIX_PAN_GN)
			ServiceID = SDP_UUID_GN;
		else
			ServiceID = SDP_UUID_PANU;

		printf("Connecting to host %s ...\n", bda2str(&bda));

		/* search for service ServiceID */
		s_list_append_uuid16(&searchList, ServiceID);
		/* set attributes to find */
		s_list_append_uint(&attrList, SDP_ATTR_SERVICE_RECORD_HANDLE);
		s_list_append_uint(&attrList, SDP_ATTR_PROTO_DESC_LIST);
		err = __sdp_search_attr_req(&saddr, searchList, IndividualAttributes, attrList, 0xffff, &svcList, &count);
		s_list_destroy(&searchList);
		s_list_free(&attrList);
		if (err) {
			fprintf(stderr, "%s\n", sdp_error(err));
			return -1;
		}
		if (count == 0) {
			printf("services [%s] not found\n", val2str(sdp_service_map, ServiceID));
			return -1;
		}
		printf("Service found\n");
		svcRec = s_list_dequeue(&svcList);
		sdp_free_svc(svcRec);
		sdp_free_svclist(&svcList);
	}
#endif
	saddr.devnum = hci_devnum(btdev);
	err = affix_pan_connect(&saddr, role);
	if (err) {
		if (errno == EINVAL)
			fprintf(stderr, "Connection not allowed in this role.\n");
		else
			fprintf(stderr, "failed.\n");
	} else 
		fprintf(stderr, "connected.\n");
	return 0;
}
Ejemplo n.º 5
0
int cmd_pan_discovery(struct command *cmd)
{
	int		role = AFFIX_PAN_NAP;
	int		fd, i, found = 0;
	__u32		length = 8;
	int		err;
	INQUIRY_ITEM	devs[20];
	char		*devnames[20];
	char		name[248];
	__u8		num;
	uint16_t	ServiceID;
	uint16_t	count;
	slist_t		*searchList = NULL;
	slist_t		*attrList = NULL;
	slist_t		*svcList = NULL;
	sdpsvc_t	*svcRec;
	struct sockaddr_affix	saddr;

	__argv = &__argv[optind];

	if (*__argv) {
		role = str2role(*__argv);
		if (!role) {
			fprintf(stderr, "invalid role: %s\n", *__argv);
			return 1;
		}
		if (*(++__argv))
			sscanf(*__argv, "%x", &length);
	}

	fd = hci_open(btdev);
	if (fd < 0) {
		printf("Unable to open device %s: %s\n", btdev, strerror(errno));
		return -1;
	}
	printf("Searching %d sec ...\n", length);
	err = HCI_Inquiry(fd, length, 20, devs, &num);
	if (err) {
		fprintf(stderr, "%s\n", hci_error(err));
		exit(1);
	}
	if (num == 0) {
		printf("done.\nNo devices found.\n");
	} else {
		printf("Searching done. Checking for service %s ...\n", role2str(role));
		btdev_cache_reload();
		btdev_cache_retire();
		for (i = 0; i < num; i++) {
			if (!(devs[i].Class_of_Device & HCI_COD_NETWORKING))
				continue;
			saddr.family = PF_AFFIX;
			saddr.bda = devs[i].bda;
			saddr.devnum = HCIDEV_ANY;
			printf("% 2d: %s ", ++found, bda2str(&saddr.bda));
			devs[i].Clock_Offset |= 0x8000;
			err = HCI_RemoteNameRequest(fd, &devs[i], name);
			if (!err)
				devnames[i] = strdup(name);
			else 
				devnames[i] = NULL;
			printf("(%s)... ", name);
#if defined(CONFIG_AFFIX_SDP)
			if (role == AFFIX_PAN_NAP)
				ServiceID = SDP_UUID_NAP;
			else if (role == AFFIX_PAN_GN)
				ServiceID = SDP_UUID_GN;
			else
				ServiceID = SDP_UUID_PANU;

			/* search for service ServiceID */
			s_list_append_uuid16(&searchList, ServiceID);
			/* set attributes to find */
			s_list_append_uint(&attrList, SDP_ATTR_SERVICE_RECORD_HANDLE);
			s_list_append_uint(&attrList, SDP_ATTR_PROTO_DESC_LIST);
			err = __sdp_search_attr_req(&saddr, searchList, IndividualAttributes, attrList, 0xffff, &svcList, &count);
			s_list_destroy(&searchList);
			s_list_free(&attrList);
			hci_disconnect(&saddr);
			if (err) {
				//fprintf(stderr, "%s\n", sdp_error(err));
				printf("no\n");
				continue;
			}
			if (count == 0) {
				printf("no\n");
				continue;
			}
			printf("yes\n");
			svcRec = s_list_dequeue(&svcList);
			sdp_free_svc(svcRec);
			sdp_free_svclist(&svcList);
			//hci_get_conn();
#else
			fprintf(stderr, "Affix SDP support disabled at compile time!\n");
			break;
#endif
			__btdev_cache_add(devs[i].bda, devs[i].Class_of_Device, devnames[i]);
			if (devnames[i])
				free(devnames[i]);
		}
		btdev_cache_save();
	}
	close(fd);
	return 0;
}
Ejemplo n.º 6
0
static void
process_args(int argc, char *argv[])
{
    int i;
    const struct nh_roles_info *ri = nh_get_roles();

    /*
     * Process options.
     */
    while (argc > 1 && argv[1][0] == '-') {
        argv++;
        argc--;
        switch (argv[0][1]) {
        case '-':
            if (!strcmp(argv[0], "--help")) {
                puts("Usage: nethack4 [--interface PLUGIN] [OPTIONS]");
                puts("");
                puts("-k          connection-only mode");
                puts("-D          start games in wizard mode");
                puts("-X          start games in explore mode");
                puts("-u name     specify player name");
                puts("-p role     specify role");
                puts("-r race     specify race");
                puts("-@          specify a random character");
                puts("-H dir      override the playfield location");
                puts("-U dir      override the user directory");
                puts("-Z          disable suspending the process");
                puts("");
                puts("PLUGIN can be any libuncursed plugin that is installed");
                puts("on your system; examples may include 'tty' and 'sdl'.");
                exit(0);
            } else if (!strcmp(argv[0], "--version")) {
                printf("NetHack 4 version %d.%d.%d\n",
                       VERSION_MAJOR, VERSION_MINOR, PATCHLEVEL);
                exit(0);
            }
            break;

        case 'k':
            ui_flags.connection_only = 1;
            break;

        case 'D':
            ui_flags.playmode = MODE_WIZARD;
            break;

        case 'X':
            ui_flags.playmode = MODE_EXPLORE;
            break;

        case 'u':
            if (argv[0][2])
                strncpy(cmdline_name, argv[0] + 2,
                        sizeof (cmdline_name) - 1);
            else if (argc > 1) {
                argc--;
                argv++;
                strncpy(cmdline_name, argv[0], sizeof (cmdline_name) - 1);
            } else
                printf("Player name expected after -u");
            break;

        case 'p':      /* profession (role) */
            if (argv[0][2]) {
                i = str2role(ri, &argv[0][2]);
                if (i >= 0)
                    cmdline_role = i;
            } else if (argc > 1) {
                argc--;
                argv++;
                i = str2role(ri, argv[0]);
                if (i >= 0)
                    cmdline_role = i;
            }
            break;

        case 'r':      /* race */
            if (argv[0][2]) {
                i = str2race(ri, &argv[0][2]);
                if (i >= 0)
                    cmdline_race = i;
            } else if (argc > 1) {
                argc--;
                argv++;
                i = str2race(ri, argv[0]);
                if (i >= 0)
                    cmdline_race = i;
            }
            break;

        case '@':
            random_player = TRUE;
            break;

        case 'H':
#ifdef UNIX
            if (setregid(getgid(), getgid()) < 0)
                exit(14);
#endif
            if (argv[0][2]) {
                override_hackdir = argv[0] + 2;
            } else if (argc > 1) {
                argc--;
                argv++;
                override_hackdir = argv[0];
            }
            break;

        case 'U':
#ifdef UNIX
            if (setregid(getgid(), getgid()) < 0)
                exit(14);
#endif
            if (argv[0][2]) {
                override_userdir = argv[0] + 2;
            } else if (argc > 1) {
                argc--;
                argv++;
                override_userdir = argv[0];
            }
            break;

        case 'Z':
            ui_flags.no_stop = 1;
            break;

        default:
            i = str2role(ri, argv[0]);
            if (i >= 0)
                cmdline_role = i;
        }
    }
}
Ejemplo n.º 7
0
/*
 *	Special setup modifications here:
 *
 *	Unfortunately, this is going to have to be done
 *	on each newgame or restore, because you lose the permonst mods
 *	across a save/restore.  :-)
 *
 *	1 - The Rogue Leader is the Tourist Nemesis.
 *	2 - Priests start with a random alignment - convert the leader and
 *	    guardians here.
 *	3 - Elves can have one of two different leaders, but can't work it
 *	    out here because it requires hacking the level file data (see
 *	    sp_lev.c).
 *
 * This code also replaces quest_init().
 */
void role_init(void)
{
	int alignmnt;

	/* Check for a valid role.  Try u.initrole first. */
	if (!validrole(u.initrole)) {
	    /* Try the player letter second */
	    if ((u.initrole = str2role(pl_character)) < 0)
	    	/* None specified; pick a random role */
	    	u.initrole = randrole();
	}

	/* We now have a valid role index.  Copy the role name back. */
	/* This should become OBSOLETE */
	strcpy(pl_character, roles[u.initrole].name.m);
	pl_character[PL_CSIZ-1] = '\0';

	/* Check for a valid race */
	if (!validrace(u.initrole, u.initrace))
	    u.initrace = randrace(u.initrole);

	/* Check for a valid gender.  If new game, check both initgend
	 * and female.  On restore, assume flags.female is correct. */
	if (flags.pantheon == -1) {	/* new game */
	    if (!validgend(u.initrole, u.initrace, flags.female))
		flags.female = !flags.female;
	}
	if (!validgend(u.initrole, u.initrace, u.initgend))
	    /* Note that there is no way to check for an unspecified gender. */
	    u.initgend = flags.female;

	/* Check for a valid alignment */
	if (!validalign(u.initrole, u.initrace, u.initalign))
	    /* Pick a random alignment */
	    u.initalign = randalign(u.initrole, u.initrace);
	alignmnt = aligns[u.initalign].value;

	/* Initialize urole and urace */
	urole = roles[u.initrole];
	urace = races[u.initrace];

	/* Fix up the quest leader */
	pm_leader = mons[urole.ldrnum];
	if (urole.ldrnum != NON_PM) {
	    pm_leader.msound = MS_LEADER;
	    pm_leader.mflags2 |= (M2_PEACEFUL);
	    pm_leader.mflags3 |= M3_CLOSE;
	    pm_leader.maligntyp = alignmnt * 3;
	}

	/* Fix up the quest guardians */
	pm_guardian = mons[urole.guardnum];
	if (urole.guardnum != NON_PM) {
	    pm_guardian.mflags2 |= (M2_PEACEFUL);
	    pm_guardian.maligntyp = alignmnt * 3;
	}

	/* Fix up the quest nemesis */
	pm_nemesis = mons[urole.neminum];
	if (urole.neminum != NON_PM) {
	    pm_nemesis.msound = MS_NEMESIS;
	    pm_nemesis.mflags2 &= ~(M2_PEACEFUL);
	    pm_nemesis.mflags2 |= (M2_NASTY|M2_STALK|M2_HOSTILE);
	    pm_nemesis.mflags3 |= M3_WANTSARTI | M3_WAITFORU;
	}

	/* Fix up the god names */
	if (flags.pantheon == -1) {		/* new game */
	    flags.pantheon = u.initrole;	/* use own gods */
	    while (!roles[flags.pantheon].lgod)	/* unless they're missing */
		flags.pantheon = randrole();
	}
	if (!urole.lgod) {
	    urole.lgod = roles[flags.pantheon].lgod;
	    urole.ngod = roles[flags.pantheon].ngod;
	    urole.cgod = roles[flags.pantheon].cgod;
	}

	/* Fix up initial roleplay flags */
	if (Role_if(PM_MONK))
	    flags.vegetarian = TRUE;
	flags.vegan |= flags.ascet;
	flags.vegetarian |= flags.vegan;

	/* Artifacts are fixed in hack_artifacts() */

	/* Success! */
	return;
}