1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
/*
* Crossfire -- cooperative multi-player graphical RPG and adventure game
*
* Copyright (c) 1999-2013 Mark Wedel and the Crossfire Development Team
* Copyright (c) 1992 Frank Tore Johansen
*
* Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
* welcome to redistribute it under certain conditions. For details, please
* see COPYING and LICENSE.
*
* The authors can be reached via e-mail at <crossfire@metalforge.org>.
*/
/**
* @file
* Those functions handle the decor in the random maps.
*/
#include <assert.h>
#include <stdlib.h>
#include "global.h"
#include "random_map.h"
#include "rproto.h"
/** Number of decor styles that can be chosen if none specified. */
#define NR_DECOR_OPTIONS 1
/**
* Count objects at a spot.
* @param map
* map we want to check
* @param x
* @param y
* coordinates
* @return
* count of objects in the map at x,y.
*/
int obj_count_in_map(mapstruct *map, int x, int y)
{
int count = 0;
FOR_MAP_PREPARE(map, x, y, tmp)
count++;
FOR_MAP_FINISH();
return count;
}
/**
* Put the decor into the map. Right now, it's very primitive.
* @param map
* map to add decor to.
* @param maze
* layout of the map, as was generated.
* @param decorstyle
* style to use. Can be NULL.
* @param decor_option
* how to place decor:
* - 0 means no decor.
* - 1 means to place randomly decor.
* - other means to fill the map with decor.
* @param RP
* parameters of the random map.
*/
void put_decor(mapstruct *map, char **maze, char *decorstyle, int decor_option, RMParms *RP)
{
mapstruct *decor_map;
decor_map = find_style("/styles/decorstyles", decorstyle, -1);
if (decor_map == NULL) {
return;
}
/* pick a random option, only 1 option right now. */
if (decor_option == 0) {
decor_option = RANDOM()%NR_DECOR_OPTIONS+1;
}
assert(decor_option != 0);
switch (decor_option) {
case 1: { /* random placement of decor objects. */
int number_to_place = RANDOM()%((RP->Xsize*RP->Ysize)/5);
int failures = 0;
object *new_decor_object;
while (failures < 100 && number_to_place > 0) {
int x, y;
x = RANDOM()%(RP->Xsize-2)+1;
y = RANDOM()%(RP->Ysize-2)+1;
if (maze[x][y] == 0 && obj_count_in_map(map, x, y) < 2) { /* empty */
object *this_object;
new_decor_object = pick_random_object(decor_map);
this_object = arch_to_object(new_decor_object->arch);
object_copy(new_decor_object, this_object);
/*
* Don't change move_block, this prevents item merging.
* Instead, fix the item on the style map if blocking
* is bad.
*/
/*this_object->move_block = MOVE_BLOCK_DEFAULT;*/
object_insert_in_map_at(this_object, map, NULL, 0, x, y);
number_to_place--;
} else {
failures++;
}
}
break;
}
default: { /* place decor objects everywhere: tile the map. */
int i, j;
for (i = 1; i < RP->Xsize-1; i++)
for (j = 1; j < RP->Ysize-1; j++) {
if (maze[i][j] == 0) {
object *new_decor_object, *this_object;
new_decor_object = pick_random_object(decor_map);
this_object = arch_to_object(new_decor_object->arch);
object_copy(new_decor_object, this_object);
/*
* Don't change move_block, this prevents item merging.
* Instead, fix the item on the style map if blocking
* is bad.
*/
/*this_object->move_block = MOVE_BLOCK_DEFAULT;*/
object_insert_in_map_at(this_object, map, NULL, 0, i, j);
}
}
break;
}
}
}
|