Add random name generator (fixes #135)

Move data files to /data dir
This commit is contained in:
Cong
2014-07-27 00:52:32 +10:00
parent 5165e9d462
commit d33e2ab912
16 changed files with 302 additions and 12 deletions

View File

@@ -169,6 +169,7 @@ endif()
INSTALL(DIRECTORY
${SOURCE_DIRECTORY}/doc
${SOURCE_DIRECTORY}/data
${SOURCE_DIRECTORY}/missions
${SOURCE_DIRECTORY}/dogfights
${SOURCE_DIRECTORY}/graphics
@@ -178,9 +179,6 @@ INSTALL(DIRECTORY
INSTALL(FILES
${SOURCE_DIRECTORY}/cdogs_icon.bmp
${SOURCE_DIRECTORY}/README.md
${SOURCE_DIRECTORY}/particles.json
${SOURCE_DIRECTORY}/bullets.json
${SOURCE_DIRECTORY}/guns.json
DESTINATION ${INSTALL_PREFIX})
IF(UNIX AND NOT APPLE AND NOT BEOS AND NOT HAIKU)
INSTALL(FILES ${SOURCE_DIRECTORY}/build/linux/cdogs-sdl.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications)

36
data/prefixes.txt Normal file
View File

@@ -0,0 +1,36 @@
Alpha
Auto
Black
C-
Con
Cyber
Data
Devi
Digi
Dyna
Electro
Giga
Hyper
Ice
Macro
Mega
Micro
Mono
Neo
Neon
Neuro
Nexus
Omni
Psy
Psycho
Quantum
Robo
Servo
Shadow
Sub
Synchro
Techno
Tetra
Turbo
Ultra
War

38
data/suffixes.txt Normal file
View File

@@ -0,0 +1,38 @@
arc
bot
brid
cat
cell
con
chrome
dex
dog
droid
drome
grid
hax
hex
link
lite
lith
logic
lux
machine
mancer
master
maton
mech
mod
net
next
nexus
ray
spec
sphere
tech
trance
trix
tron
wolf
viper
visor

22
data/suffixnames.txt Normal file
View File

@@ -0,0 +1,22 @@
2000
Agent
Alpha
Assassin
Circuit
DX
Cyborg
Hacker
Jester
Lightning
Matrix
One
Prime
Shadow
Snake
Steel
Stingray
Storm
Synapse
Vector
X
Zero

BIN
graphics/font.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 678 B

View File

@@ -14,6 +14,7 @@ set(CDOGS_SDL_SOURCES
mainmenu.c
menu.c
menu_utils.c
namegen.c
password.c
player_select_menus.c
prep.c
@@ -27,6 +28,7 @@ set(CDOGS_SDL_HEADERS
mainmenu.h
menu.h
menu_utils.h
namegen.h
password.h
player_select_menus.h
prep.h

View File

@@ -1395,11 +1395,11 @@ int main(int argc, char *argv[])
GetDataFilePath(buf, "graphics");
PicManagerLoadDir(&gPicManager, buf);
GetDataFilePath(buf, "particles.json");
GetDataFilePath(buf, "data/particles.json");
ParticleClassesInit(&gParticleClasses, buf);
char buf2[CDOGS_PATH_MAX];
GetDataFilePath(buf, "bullets.json");
GetDataFilePath(buf2, "guns.json");
GetDataFilePath(buf, "data/bullets.json");
GetDataFilePath(buf2, "data/guns.json");
BulletAndWeaponInitialize(
&gBulletClasses, &gGunDescriptions, buf, buf2);
CampaignInit(&gCampaign);

View File

@@ -1176,11 +1176,11 @@ int main(int argc, char *argv[])
GetDataFilePath(buf, "graphics");
PicManagerLoadDir(&gPicManager, buf);
GetDataFilePath(buf, "particles.json");
GetDataFilePath(buf, "data/particles.json");
ParticleClassesInit(&gParticleClasses, buf);
char buf2[CDOGS_PATH_MAX];
GetDataFilePath(buf, "bullets.json");
GetDataFilePath(buf2, "guns.json");
GetDataFilePath(buf, "data/bullets.json");
GetDataFilePath(buf2, "data/guns.json");
BulletAndWeaponInitialize(&gBulletClasses, &gGunDescriptions, buf, buf2);
CampaignInit(&gCampaign);
MissionInit(&lastMission);

133
src/namegen.c Normal file
View File

@@ -0,0 +1,133 @@
/*
Copyright (c) 2014, Cong Xu
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#include "namegen.h"
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void LoadFile(CArray *strings, const char *filename);
void NameGenInit(
NameGen *g,
const char *prefixFile, const char *suffixFile, const char *suffixNameFile)
{
CArrayInit(&g->prefixes, sizeof(char *));
CArrayInit(&g->suffixes, sizeof(char *));
CArrayInit(&g->suffixNames, sizeof(char *));
LoadFile(&g->prefixes, prefixFile);
LoadFile(&g->suffixes, suffixFile);
LoadFile(&g->suffixNames, suffixNameFile);
}
static void LoadFile(CArray *strings, const char *filename)
{
FILE *file = fopen(filename, "r");
char buf[256];
while (fgets(buf, 256, file) != NULL)
{
char *str = malloc(strlen(buf) + 1);
strncpy(str, buf, strlen(buf) - 1);
str[strlen(buf) - 1] = '\0';
CArrayPushBack(strings, &str);
}
fclose(file);
}
static void UnloadStrings(CArray *strings);
void NameGenTerminate(NameGen *g)
{
UnloadStrings(&g->prefixes);
UnloadStrings(&g->suffixes);
UnloadStrings(&g->suffixNames);
}
static void UnloadStrings(CArray *strings)
{
for (int i = 0; i < (int)strings->size; i++)
{
char **str = CArrayGet(strings, i);
free(*str);
}
CArrayTerminate(strings);
}
static bool IsSameWord(const char *l, const char *r);
void NameGenMake(const NameGen *g, char *buf)
{
for (;;)
{
char **prefix = CArrayGet(&g->prefixes, rand() % g->prefixes.size);
int suffixIndex = rand() % (g->suffixes.size + g->suffixNames.size);
char **suffix;
if (suffixIndex < (int)g->suffixes.size)
{
suffix = CArrayGet(&g->suffixes, suffixIndex);
}
else
{
suffix = CArrayGet(
&g->suffixNames, suffixIndex - (int)g->suffixes.size);
}
// Don't generate same prefix/suffix
if (IsSameWord(*prefix, *suffix))
{
continue;
}
strcpy(buf, *prefix);
// Add a space if we're using a suffix name
if (suffixIndex >= (int)g->suffixes.size)
{
strcat(buf, " ");
}
strcat(buf, *suffix);
break;
}
}
static char LowerCase(const char c);
static bool IsSameWord(const char *l, const char *r)
{
while (*l && *r)
{
if (LowerCase(*l) != LowerCase(*r))
{
return false;
}
l++;
r++;
}
if (*l || *r)
{
return false;
}
return true;
}
static char LowerCase(const char c)
{
if (c >= 'A' && c <= 'Z')
{
return c - 32;
}
return c;
}

44
src/namegen.h Normal file
View File

@@ -0,0 +1,44 @@
/*
Copyright (c) 2014, Cong Xu
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __NAMEGEN
#define __NAMEGEN
#include <cdogs/c_array.h>
typedef struct
{
CArray prefixes;
CArray suffixes;
CArray suffixNames;
} NameGen;
void NameGenInit(
NameGen *g,
const char *prefixFile, const char *suffixFile, const char *suffixNameFile);
void NameGenTerminate(NameGen *g);
void NameGenMake(const NameGen *g, char *buf);
#endif

View File

@@ -330,7 +330,7 @@ void PlayerSelectMenusCreate(
PlayerSelectMenu *menu,
int numPlayers, int player, Character *c, struct PlayerData *pData,
EventHandlers *handlers, GraphicsDevice *graphics,
InputConfig *inputConfig)
InputConfig *inputConfig, const NameGen *ng)
{
MenuSystem *ms = &menu->ms;
PlayerSelectMenuData *data = &menu->data;
@@ -346,6 +346,7 @@ void PlayerSelectMenusCreate(
data->display.pData = pData;
data->controls.inputConfig = inputConfig;
data->controls.pData = pData;
data->nameGenerator = ng;
switch (numPlayers)
{
@@ -460,6 +461,10 @@ static void ShuffleOne(AppearanceMenuData *data);
static void ShuffleAppearance(void *data)
{
PlayerSelectMenuData *pData = data;
struct PlayerData *p = pData->display.pData;
char buf[512];
NameGenMake(pData->nameGenerator, buf);
strncpy(p->name, buf, 20);
ShuffleOne(&pData->faceData);
ShuffleOne(&pData->skinData);
ShuffleOne(&pData->hairData);

View File

@@ -33,6 +33,7 @@
#include "menu.h"
#include "menu_utils.h"
#include "namegen.h"
typedef struct
{
@@ -54,6 +55,7 @@ typedef struct
AppearanceMenuData armsData;
AppearanceMenuData bodyData;
AppearanceMenuData legsData;
const NameGen *nameGenerator;
} PlayerSelectMenuData;
typedef struct
{
@@ -65,6 +67,6 @@ void PlayerSelectMenusCreate(
PlayerSelectMenu *menu,
int numPlayers, int player, Character *c, struct PlayerData *pData,
EventHandlers *handlers, GraphicsDevice *graphics,
InputConfig *inputConfig);
InputConfig *inputConfig, const NameGen *ng);
#endif

View File

@@ -72,6 +72,7 @@
#include <cdogs/utils.h>
#include "player_select_menus.h"
#include "namegen.h"
#include "weapon_menu.h"
@@ -241,12 +242,20 @@ int PlayerSelection(int numPlayers, GraphicsDevice *graphics)
{
bool hasInputDevice[MAX_PLAYERS];
PlayerSelectMenu menus[MAX_PLAYERS];
NameGen g;
char prefixes[CDOGS_PATH_MAX];
char suffixes[CDOGS_PATH_MAX];
char suffixnames[CDOGS_PATH_MAX];
GetDataFilePath(prefixes, "data/prefixes.txt");
GetDataFilePath(suffixes, "data/suffixes.txt");
GetDataFilePath(suffixnames, "data/suffixnames.txt");
NameGenInit(&g, prefixes, suffixes, suffixnames);
for (int i = 0; i < numPlayers; i++)
{
PlayerSelectMenusCreate(
&menus[i], numPlayers, i,
&gCampaign.Setting.characters.players[i], &gPlayerDatas[i],
&gEventHandlers, graphics, &gConfig.Input);
&gEventHandlers, graphics, &gConfig.Input, &g);
hasInputDevice[i] = false;
}
@@ -375,6 +384,7 @@ bail:
{
MenuSystemTerminate(&menus[i].ms);
}
NameGenTerminate(&g);
return res;
}