/* * Copyright (C) 2002-2007 The Warp Rogue Team * Part of the Warp Rogue Project * * This software is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License. * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY. * * See the license.txt file for more details. */ /* * Module Name: Random * Description: - */ #include #define Uses_Util #define Uses_DataFile #define Uses_ProgramManager #include "mheader.h" #include "rng.h" #include "shake.h" #include "random.h" /* * name randomiser files */ #define FILE_NAMES_MALE "male.nam" #define FILE_NAMES_FEMALE "female.nam" /* randomiser string size */ #define RANDOMISER_STRING_SIZE 128 /* * randomiser item type */ typedef struct { char string[RANDOMISER_STRING_SIZE]; RVALUE rv; RVALUE rv2; } RANDOMISER_ITEM; static void random_name_init(void); static void random_name_clean_up(void); /* * the randomiser list */ static LIST * RandomiserList = NULL; /* * Random module init */ void random_init(void) { tt_seed(time(NULL)); RandomiserList = list_new(); random_name_init(); } /* * Random module clean up */ void random_clean_up(void) { if (RandomiserList != NULL) { list_free_with(RandomiserList, free); } random_name_clean_up(); } /* * returns a random integer >= a and <= b */ int random_int(int a, int b) { return tt_random_int(a, b); } /* * adds an item to the randomiser list */ void randomiser_add(const char *string, RVALUE rv, RVALUE rv2) { RANDOMISER_ITEM *r_item; r_item = checked_malloc(sizeof *r_item); strcpy(r_item->string, string); r_item->rv = rv; r_item->rv2 = rv2; list_add(RandomiserList, r_item); } /* * clears the randomiser list */ void randomiser_clear(void) { list_clear_with(RandomiserList, free); } /* * returns a randomly chosen item from randomiser list */ const char * randomiser(void) { LIST_NODE_INDEX r; RANDOMISER_ITEM *r_item; /* empty list - return "" */ if (RandomiserList->n_nodes == 0) { return ""; } r = random_int(0, RandomiserList->n_nodes - 1); r_item = list_data_at(RandomiserList, r); return r_item->string; } /* * returns a random character name */ const char * random_name(NAME_SET name_set) { const char *name; name = shake_get_string(name_set); if (name == NULL) { shake_no_duplicates(name_set, false); name = shake_get_string(name_set); if (name == NULL) { die("*** CORE ERROR *** name set %d empty", name_set ); } } return name; } /* * rolls dice and returns the result */ int dice(int n_dice, int n_sides) { int i; int result; result = 0; for (i = 0; i < n_dice; i++) { result += random_int(1, n_sides); } return result; } /* * returns the average result of a dice roll */ int dice_roll_average(const DICE_ROLL *dice_roll) { int result; result = dice_roll->n_sides / 2; result *= dice_roll->n_dice; result += dice_roll->modifier; return result; } /* * D100 test */ int d100_test(int dice_roll, int test_value) { int result; if (test_value < 0) { test_value = -1; } result = test_value - dice_roll; if (dice_roll <= D100_AUTOMATIC_SUCCESS) { if (result >= 0) { return result; } return 0; } else if (dice_roll >= D100_AUTOMATIC_FAILURE) { if (result < 0) { return result; } return -1; } return result; } /* * D100 test against the given test value * returns true if passed */ bool d100_test_passed(int test_value) { int dice_roll; dice_roll = d100(); if (d100_test(dice_roll, test_value) >= 0) { return true; } return false; } /* * name randomiser init */ static void random_name_init(void) { shake_set_rng(random_int); set_data_path(DIR_RACE, FILE_NAMES_MALE); shake_load_set(NAME_SET_HUMAN_MALE, data_path()); shake_no_duplicates(NAME_SET_HUMAN_MALE, true); set_data_path(DIR_RACE, FILE_NAMES_FEMALE); shake_load_set(NAME_SET_HUMAN_FEMALE, data_path()); shake_no_duplicates(NAME_SET_HUMAN_FEMALE, true); } /* * name randomiser clean up */ static void random_name_clean_up(void) { shake_unload_set(NAME_SET_HUMAN_MALE); shake_unload_set(NAME_SET_HUMAN_FEMALE); }