Crossfire Server, Trunk  R20513
main.c
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2013 Mark Wedel and the Crossfire Development Team
5  * Copyright (c) 1992 Frank Tore Johansen
6  *
7  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8  * welcome to redistribute it under certain conditions. For details, please
9  * see COPYING and LICENSE.
10  *
11  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
12  */
13 
19 #include "global.h"
20 
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <time.h>
25 
26 #include "maze_gen.h"
27 #include "random_map.h"
28 #include "room_gen.h"
29 #include "rproto.h"
30 #include "sproto.h"
31 
32 #define LO_NEWFILE 2
33 
34 static void generate_map(char *OutFileName) {
35  RMParms rp;
36  mapstruct *newMap;
37 
38  fprintf(stderr, "Reading parameters from stdin...\n");
39 
40  /* Initialize parameters and set initial settings. */
41  memset(&rp, 0, sizeof(RMParms));
42  rp.Xsize = -1;
43  rp.Ysize = -1;
44 
45  /* Initialize Crossfire library. */
46  init_globals();
47  init_library();
50  init_formulae();
51  init_readable();
52  init_gods();
53 
54  load_parameters(stdin, LO_NEWFILE, &rp);
55  fclose(stdin);
56 
57  newMap = generate_random_map(OutFileName, &rp, NULL);
58  save_map(newMap, SAVE_MODE_INPLACE);
59 }
60 
64 static void print_map(char **layout, int width, int height) {
65  int i, j;
66 
67  for (j = 0; j < height; ++j) {
68  for (i = 0; i < width; ++i) {
69  char display_char;
70  display_char = layout[i][j];
71 
72  switch (display_char) {
73  case 0:
74  display_char = '.';
75  break;
76  case 'D':
77  display_char = '+';
78  break;
79  }
80 
81  putchar(display_char);
82  }
83 
84  putchar('\n');
85  }
86 }
87 
88 typedef struct {
89  char *name;
90  char **(*func)(int, int, int, int);
91 } layout;
92 
94  // Most of these need to be cast to silence warnings.
95  // The fourth paramter (and sometimes the third) is ignored in most cases.
96  { "rogue", (char **(*)(int, int, int, int))&roguelike_layout_gen },
97  { "snake", (char **(*)(int, int, int, int))&make_snake_layout },
98  { "sspiral", (char **(*)(int, int, int, int))&make_square_spiral_layout },
99  { "spiral", (char **(*)(int, int, int, int))&map_gen_spiral },
100  { "maze", (char **(*)(int, int, int, int))&maze_gen },
101  { "onion", &map_gen_onion }
102 };
103 
116 static void test_layout(int width, int height, char **(*layout_func)(int, int, int, int)) {
117  char **layout;
118  SRANDOM(time(0));
119 
120  // Bail if no layout -- shouldn't occur, but just to be safe
121  if (layout_func == NULL)
122  return;
123 
124  layout = layout_func(width, height, 0, 0);
125 
126  print_map(layout, width, height);
127  free(layout);
128 }
129 
131 static void print_quickhelp(void) {
132  fprintf(stderr, "Type 'random_map -h' for usage instructions.\n");
133 }
134 
136 static void print_usage(void) {
137  printf(
138  "Usage: random_map [options]\n"
139  "\n"
140  "Options:\n"
141  " -h display this help message\n"
142  " -g <file> randomly generate the specified map file\n"
143  " -l <layout> layout to use. See Layouts for valid layouts.\n"
144  " (overridden by -g)\n"
145  " -t test map layout (overriden by -g)\n"
146  " -x <width> specify map width\n"
147  " -y <height> specify map height\n"
148  "\n"
149  "Layouts:\n"
150  " rogue -- roguelike map generator\n"
151  " snake -- snake map generator\n"
152  " sspiral -- square spiral map generator\n"
153  " spiral -- spiral map generator\n"
154  " maze -- maze map generator\n"
155  " onion -- onion map generator\n"
156  );
157 }
158 
159 int main(int argc, char *argv[]) {
160  int flag, mode = 0, width = 80, height = 23;
161  char *filename_out;
162  // Make default behavior be roguelike generation, like old behavior
163  // NOTE: The ugly function pointer cast silences compiler warnings.
164  char **(*func)(int, int, int, int) = (char **(*)(int, int, int, int))&roguelike_layout_gen;
165 
166  /* Parse command-line arguments. */
167  while ((flag = getopt(argc, argv, "g:hl:tx:y:")) != -1) {
168  switch (flag) {
169  case 'g':
170  mode = 2;
171  filename_out = optarg;
172  break;
173  case 'h':
174  print_usage();
175  exit(EXIT_SUCCESS);
176  break;
177  case 'l':
178  for (int i = 0; i < NROFLAYOUTS; ++i)
179  {
180  if (strcmp(optarg, layout_list[i].name) == 0)
181  func = layout_list[i].func;
182  }
183  break;
184  case 't':
185  mode = 1;
186  break;
187  case 'x':
188  width = atoi(optarg);
189  break;
190  case 'y':
191  height = atoi(optarg);
192  break;
193  case '?':
194  print_quickhelp();
195  exit(EXIT_FAILURE);
196  break;
197  }
198  }
199 
200  if (mode == 1) {
201  test_layout(width, height, func);
202  exit(EXIT_SUCCESS);
203  } else if (mode == 2) {
204  generate_map(filename_out);
205  exit(EXIT_SUCCESS);
206  } else {
207  print_quickhelp();
208  exit(EXIT_FAILURE);
209  }
210 }
211 
212 /* some plagarized code from apply.c--I needed just these two functions
213 without all the rest of the junk, so.... */
214 int apply_auto(object *op)
215 {
216  object *tmp = NULL;
217  int i;
218 
219  switch (op->type) {
220  case SHOP_FLOOR:
221  if (!HAS_RANDOM_ITEMS(op)) {
222  return 0;
223  }
224  do {
225  i = 10; /* let's give it 10 tries */
226  while ((tmp = generate_treasure(op->randomitems, op->stats.exp ? op->stats.exp : 5)) == NULL && --i)
227  ;
228  if (tmp == NULL) {
229  return 0;
230  }
231  if (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED)) {
233  tmp = NULL;
234  }
235  } while (!tmp);
236 
237  SET_FLAG(tmp, FLAG_UNPAID);
238  object_insert_in_map_at(tmp, op->map, NULL, 0, op->x, op->y);
240  tmp = identify(tmp);
241  break;
242 
243  case TREASURE:
244  if (HAS_RANDOM_ITEMS(op))
245  while ((op->stats.hp--) > 0) {
246  create_treasure(op->randomitems, op, GT_ENVIRONMENT, op->stats.exp ? op->stats.exp : op->map == NULL ? 14 : op->map->difficulty, 0);
247  }
248  object_remove(op);
250  break;
251  }
252 
253  return tmp ? 1 : 0;
254 }
255 
256 /* apply_auto_fix goes through the entire map (only the first time
257  * when an original map is loaded) and performs special actions for
258  * certain objects (most initialization of chests and creation of
259  * treasures and stuff). Calls apply_auto if appropriate.
260  */
262 {
263  int x, y;
264 
265  for (x = 0; x < MAP_WIDTH(m); x++)
266  for (y = 0; y < MAP_HEIGHT(m); y++)
267  FOR_MAP_PREPARE(m, x, y, tmp) {
268  if (QUERY_FLAG(tmp, FLAG_AUTO_APPLY)) {
269  apply_auto(tmp);
270  } else if (tmp->type == TREASURE) {
271  if (HAS_RANDOM_ITEMS(tmp))
272  while ((tmp->stats.hp--) > 0) {
273  create_treasure(tmp->randomitems, tmp, 0, m->difficulty, 0);
274  }
275  }
276  if (tmp && tmp->arch
277  && tmp->type != PLAYER
278  && tmp->type != TREASURE
279  && tmp->randomitems) {
280  if (tmp->type == CONTAINER) {
281  if (HAS_RANDOM_ITEMS(tmp))
282  while ((tmp->stats.hp--) > 0) {
283  create_treasure(tmp->randomitems, tmp, 0, m->difficulty, 0);
284  }
285  } else if (HAS_RANDOM_ITEMS(tmp)) {
286  create_treasure(tmp->randomitems, tmp, 0, m->difficulty, 0);
287  }
288  }
289  }
290  FOR_MAP_FINISH();
291  for (x = 0; x < MAP_WIDTH(m); x++)
292  for (y = 0; y < MAP_HEIGHT(m); y++)
293  FOR_MAP_PREPARE(m, x, y, tmp) {
294  if (tmp->above
295  && (tmp->type == TRIGGER_BUTTON || tmp->type == TRIGGER_PEDESTAL)) {
296  check_trigger(tmp, tmp->above);
297  }
298  }
299  FOR_MAP_FINISH();
300 }
301 
302 /*
303  * The following dummy variables are only used to resolve symbols at compile
304  * time. They don't actually do anything useful.
305  */
306 
307 void set_map_timeout(mapstruct *oldmap) {
308 }
309 
310 void draw_ext_info(int flags, int pri, const object *pl, uint8_t type,
311  uint8_t subtype, const char *message) {
312  fprintf(logfile, "%s\n", message);
313 }
314 
315 void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type,
316  uint8_t subtype, const char *format, ...) {
317  va_list ap;
318 
319  va_start(ap, format);
320  vfprintf(logfile, format, ap);
321  va_end(ap);
322 }
323 
324 
325 void ext_info_map(int color, const mapstruct *map, uint8_t type, uint8_t subtype,
326  const char *str1) {
327  fprintf(logfile, "ext_info_map: %s\n", str1);
328 }
329 
330 void move_firewall(object *ob) {
331 }
332 
333 void emergency_save(int x) {
334 }
335 
336 void clean_tmp_files(void) {
337 }
338 
339 void esrv_send_item(object *ob, object *obx) {
340 }
341 
342 void esrv_update_item(int flags, object *pl, object *op) {
343 }
344 
345 void dragon_ability_gain(object *ob, int x, int y) {
346 }
347 
349 }
350 
351 object *find_skill_by_number(object *who, int skillno) {
352  return NULL;
353 }
354 
355 void esrv_del_item(player *pl, object *ob) {
356 }
357 
359 }
360 
361 void rod_adjust(object *rod) {
362 }
363 
364 int execute_event(object *op, int eventcode, object *activator, object *third,
365  const char *message, int fix) {
366  return 0;
367 }
368 
369 int execute_global_event(int eventcode, ...) {
370  return 0;
371 }
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...)
Definition: main.c:315
char ** roguelike_layout_gen(int xsize, int ysize, int options)
Actually make the rogue layout.
Definition: rogue_layout.c:332
EXTERN FILE * logfile
Used by server/daemon.c.
Definition: global.h:144
void apply_auto_fix(mapstruct *m)
Definition: main.c:261
One player.
Definition: player.h:92
Random map parameters.
Definition: random_map.h:14
#define FLAG_DAMNED
The object is very cursed.
Definition: define.h:318
mapstruct * generate_random_map(const char *OutFileName, RMParms *RP, char **use_layout)
Main random map routine.
Definition: random_map.c:74
#define FLAG_UNPAID
Object hasn&#39;t been paid for yet.
Definition: define.h:236
PyObject * third
Definition: cfpython.h:118
static void print_usage(void)
Print out usage information.
Definition: main.c:136
static void test_layout(int width, int height, char **(*layout_func)(int, int, int, int))
Test the map layout produced by the specified generator.
Definition: main.c:116
#define SET_FLAG(xyz, p)
Definition: define.h:223
unsigned char uint8_t
Definition: win32.h:161
static void print_quickhelp(void)
Print a message stating how to get help.
Definition: main.c:131
PyObject * activator
Definition: cfpython.h:117
void esrv_send_item(object *ob, object *obx)
Definition: main.c:339
char ** make_snake_layout(int xsize, int ysize)
Generate a snake-like layout.
Definition: snake.c:34
void set_map_timeout(mapstruct *oldmap)
Definition: main.c:307
struct treasureliststruct * randomitems
Items to be generated.
Definition: object.h:385
Random map related variables.
#define MAP_HEIGHT(m)
Map height.
Definition: map.h:80
void init_archetypes(void)
Initialises the internal linked list of archetypes (read from file).
Definition: arch.c:182
void init_globals(void)
Initialises all global variables.
Definition: init.c:272
static layout layout_list[NROFLAYOUTS]
Definition: main.c:93
int64_t exp
Experience.
Definition: living.h:46
int execute_global_event(int eventcode,...)
Definition: main.c:369
char message[1024]
Definition: cfpython.h:120
void init_library(void)
It is vital that init_library() is called by any functions using this library.
Definition: init.c:201
See Button Trigger.
Definition: object.h:132
int main(int argc, char *argv[])
Definition: main.c:159
void rod_adjust(object *rod)
Definition: main.c:361
Global type definitions and header inclusions.
#define SRANDOM(seed)
Definition: define.h:680
int16_t hp
Hit Points.
Definition: living.h:39
void init_formulae(void)
Builds up the lists of formula from the file in the libdir.
Definition: recipe.c:161
static void generate_map(char *OutFileName)
Definition: main.c:34
void create_treasure(treasurelist *t, object *op, int flag, int difficulty, int tries)
This calls the appropriate treasure creation function.
Definition: treasure.c:490
void set_darkness_map(mapstruct *m)
Definition: main.c:348
char ** make_square_spiral_layout(int xsize, int ysize)
Generates a square-spiral layout.
Definition: square_spiral.c:78
void object_free_drop_inventory(object *ob)
Frees everything allocated by an object, removes it from the list of used objects, and puts it on the list of free objects.
Definition: object.c:1368
int16_t y
Position in the map for this object.
Definition: object.h:326
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
Same as object_insert_in_map() except it handle separate coordinates and do a clean job preparing mul...
Definition: object.c:1921
void ext_info_map(int color, const mapstruct *map, uint8_t type, uint8_t subtype, const char *str1)
Definition: main.c:325
#define NROFLAYOUTS
Definition: random_map.h:111
See Treasure.
Definition: object.h:110
void esrv_update_item(int flags, object *pl, object *op)
Definition: main.c:342
struct mapdef * map
Pointer to the map in which this object is present.
Definition: object.h:297
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
Definition: main.c:310
void esrv_update_spells(player *pl)
Definition: main.c:358
char ** map_gen_spiral(int xsize, int ysize, int option)
Generates a spiral layout.
#define QUERY_FLAG(xyz, p)
Definition: define.h:225
#define CLEAR_FLAG(xyz, p)
Definition: define.h:224
object * find_skill_by_number(object *who, int skillno)
Definition: main.c:351
void init_readable(void)
Initialize linked lists utilized by message functions in tailor_readable_ob()
Definition: readable.c:1005
int apply_auto(object *op)
Definition: main.c:214
#define SAVE_MODE_INPLACE
Map is saved from where it was loaded.
Definition: map.h:121
char ** maze_gen(int xsize, int ysize, int option)
This function generates a random blocked maze with the property that there is only one path from one ...
Definition: maze_gen.c:58
int16_t x
Definition: object.h:326
PyObject * who
Definition: cfpython.h:116
int Ysize
Definition: random_map.h:70
See Container.
Definition: object.h:231
uint16_t difficulty
What level the player should be to play here.
Definition: map.h:343
static const flag_definition flags[]
Flag mapping.
void clean_tmp_files(void)
Definition: main.c:336
#define FOR_MAP_FINISH()
Finishes FOR_MAP_PREPARE().
Definition: define.h:765
int Xsize
Definition: random_map.h:69
int save_map(mapstruct *m, int flag)
Saves a map to file.
Definition: map.c:1436
#define FLAG_CURSED
The object is cursed.
Definition: define.h:317
See Player.
Definition: object.h:107
int execute_event(object *op, int eventcode, object *activator, object *third, const char *message, int fix)
Definition: main.c:364
#define FLAG_AUTO_APPLY
Will be applied when created.
Definition: define.h:250
int load_parameters(FILE *fp, int bufstate, RMParms *RP)
living stats
Str, Con, Dex, etc.
Definition: object.h:368
See Shop Floor.
Definition: object.h:183
#define MAP_WIDTH(m)
Map width.
Definition: map.h:78
static void print_map(char **layout, int width, int height)
Print the human-readable layout of a map.
Definition: main.c:64
uint8_t type
PLAYER, BULLET, etc.
Definition: object.h:338
void init_gods(void)
This takes a look at all of the archetypes to find the objects which correspond to the GODS (type GOD...
Definition: holy.c:53
object * identify(object *op)
Identifies an item.
Definition: item.c:1437
void move_firewall(object *ob)
Definition: main.c:330
char ** map_gen_onion(int xsize, int ysize, int option, int layers)
Generates an onion layout.
void emergency_save(int x)
Definition: main.c:333
#define FOR_MAP_PREPARE(map_, mx_, my_, it_)
Constructs a loop iterating over all objects of a map tile.
Definition: define.h:758
int check_trigger(object *op, object *cause)
Definition: button.c:523
void esrv_del_item(player *pl, object *ob)
Definition: main.c:355
object * generate_treasure(treasurelist *t, int difficulty)
Generate a treasure from a list generating a single item.
Definition: treasure.c:518
This is a game-map.
Definition: map.h:325
char **(* func)(int, int, int, int)
Definition: main.c:90
#define LO_NEWFILE
Definition: main.c:32
void dragon_ability_gain(object *ob, int x, int y)
Definition: main.c:345
void init_artifacts(void)
Builds up the lists of artifacts from the file in the libdir.
Definition: artifact.c:513
#define HAS_RANDOM_ITEMS(op)
This return TRUE if object has still randomitems which could be expanded.
Definition: define.h:183
void object_remove(object *op)
This function removes the object op from the linked list of objects which it is currently tied to...
Definition: object.c:1654
Definition: main.c:88
char * name
Definition: main.c:89