2 * Copyright (c) 2007-2013, Czirkos Zoltan http://code.google.com/p/gdash/
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 #include "cave/object/caveobjectrandomfill.hpp"
20 #include "cave/elementproperties.hpp"
22 #include <glib/gi18n.h>
24 #include "fileops/bdcffhelper.hpp"
25 #include "cave/caverendered.hpp"
26 #include "misc/printf.hpp"
27 #include "misc/util.hpp"
29 std::string
CaveRandomFill::get_bdcff() const
31 const char *type
=c64_random
?"RandomFillC64":"RandomFill";
35 f
<< seed
[0] << seed
[1] << seed
[2] << seed
[3] << seed
[4];
37 if (random_fill_probability_1
!=0)
38 f
<< random_fill_1
<< random_fill_probability_1
;
39 if (random_fill_probability_2
!=0)
40 f
<< random_fill_2
<< random_fill_probability_2
;
41 if (random_fill_probability_3
!=0)
42 f
<< random_fill_3
<< random_fill_probability_3
;
43 if (random_fill_probability_4
!=0)
44 f
<< random_fill_4
<< random_fill_probability_4
;
45 if (replace_only
!=O_NONE
)
51 CaveRandomFill
* CaveRandomFill::clone_from_bdcff(const std::string
&name
, std::istream
&is
) const
55 GdElementEnum initial_fill
, replace_only
;
56 GdElementEnum random_fill
[4]={O_DIRT
, O_DIRT
, O_DIRT
, O_DIRT
};
57 int random_prob
[4]={0,0,0,0};
61 if (!(is
>> p1
>> p2
>> seed
[0] >> seed
[1] >> seed
[2] >> seed
[3] >> seed
[4] >> initial_fill
))
64 /* now come fill element&probability pairs. read as we find two words */
65 while (j
<4 && (is
>> s1
>> s2
)) {
66 std::istringstream
is1(s1
), is2(s2
);
67 // read two strings - they must be fill & prob
68 if (!(is1
>>random_fill
[j
]))
70 if (!(is2
>>random_prob
[j
]))
77 std::istringstream
is(s1
);
78 // one string left - must be a replace only element
79 if (!(is
>>replace_only
))
85 CaveRandomFill
*r
=new CaveRandomFill(p1
, p2
);
86 r
->set_replace_only(replace_only
);
87 r
->set_seed(seed
[0], seed
[1], seed
[2], seed
[3], seed
[4]);
88 r
->set_random_fill(initial_fill
, random_fill
[0], random_fill
[1], random_fill
[2], random_fill
[3]);
89 r
->set_random_prob(random_prob
[0], random_prob
[1], random_prob
[2], random_prob
[3]);
90 r
->set_c64_random(gd_str_ascii_caseequal(name
, "RandomFillC64"));
95 CaveRandomFill::CaveRandomFill(Coordinate _p1
, Coordinate _p2
)
96 : CaveRectangular(GD_RANDOM_FILL
, _p1
, _p2
),
100 initial_fill
=O_SPACE
;
101 random_fill_1
=O_DIRT
;
102 random_fill_probability_1
=0;
103 random_fill_2
=O_DIRT
;
104 random_fill_probability_2
=0;
105 random_fill_3
=O_DIRT
;
106 random_fill_probability_3
=0;
107 random_fill_4
=O_DIRT
;
108 random_fill_probability_4
=0;
109 for (int j
=0; j
<5; j
++)
113 void CaveRandomFill::set_random_fill(GdElementEnum initial
, GdElementEnum e1
, GdElementEnum e2
, GdElementEnum e3
, GdElementEnum e4
)
115 initial_fill
=initial
;
122 void CaveRandomFill::set_random_prob(int i1
, int i2
, int i3
, int i4
)
124 random_fill_probability_1
=i1
;
125 random_fill_probability_2
=i2
;
126 random_fill_probability_3
=i3
;
127 random_fill_probability_4
=i4
;
130 void CaveRandomFill::set_seed(int s1
, int s2
, int s3
, int s4
, int s5
)
139 void CaveRandomFill::draw(CaveRendered
&cave
) const
141 /* -1 means that it should be different every time played. */
143 if (seed
[cave
.rendered_on
]==-1)
144 s
=cave
.random
.rand_int();
146 s
=seed
[cave
.rendered_on
];
148 RandomGenerator rand
;
150 /* for c64 random, use the 2*8 lsb. */
151 C64RandomGenerator c64rand
;
154 /* change coordinates if not in correct order */
164 for (int y
=y1
; y
<=y2
; y
++)
165 for (int x
=x1
; x
<=x2
; x
++) {
168 if (c64_random
) /* use c64 random generator */
169 randm
=c64rand
.random();
170 else /* use the much better glib random generator */
171 randm
=rand
.rand_int_range(0, 256);
173 GdElementEnum element
=initial_fill
;
174 if (randm
<random_fill_probability_1
)
175 element
=random_fill_1
;
176 if (randm
<random_fill_probability_2
)
177 element
=random_fill_2
;
178 if (randm
<random_fill_probability_3
)
179 element
=random_fill_3
;
180 if (randm
<random_fill_probability_4
)
181 element
=random_fill_4
;
182 if (replace_only
==O_NONE
|| cave
.map(x
, y
)==replace_only
)
183 cave
.store_rc(x
, y
, element
, this);
187 PropertyDescription
const CaveRandomFill::descriptor
[] = {
188 {"", GD_TAB
, 0, N_("Random Fill")},
189 {"", GD_TYPE_BOOLEAN_LEVELS
, 0, N_("Levels"), GetterBase::create_new(&CaveRandomFill::seen_on
), N_("Levels on which this object is visible.")},
190 {"", GD_TYPE_COORDINATE
, 0, N_("Start corner"), GetterBase::create_new(&CaveRandomFill::p1
), N_("Specifies one of the corners of the object."), 0, 127},
191 {"", GD_TYPE_COORDINATE
, 0, N_("End corner"), GetterBase::create_new(&CaveRandomFill::p2
), N_("Specifies one of the corners of the object."), 0, 127},
192 {"", GD_TYPE_ELEMENT
, 0, N_("Replace only"), GetterBase::create_new(&CaveRandomFill::replace_only
), N_("If this setting is set to 'no element' but another one, only that will be replaced when drawing the fill, and other elements will not be overwritten. Otherwise the whole block is filled.")},
193 {"", GD_TAB
, 0, N_("Generator")},
194 {"", GD_TYPE_BOOLEAN
, 0, N_("C64 random"), GetterBase::create_new(&CaveRandomFill::c64_random
), N_("Controls if the C64 random generator is used for the fill, or a more advanced one. By using the C64 generator, you can recreate the patterns of the original game.")},
195 {"", GD_TYPE_INT_LEVELS
, 0, N_("Random seed"), GetterBase::create_new(&CaveRandomFill::seed
), N_("Random seed value controls the predictable random number generator, which fills the cave initially. If set to -1, cave is totally random every time it is played."), -1, GD_CAVE_SEED_MAX
},
196 {"", GD_TYPE_ELEMENT
, 0, N_("Initial fill"), GetterBase::create_new(&CaveRandomFill::initial_fill
), 0},
197 {"", GD_TYPE_INT
, 0, N_("Probability 1"), GetterBase::create_new(&CaveRandomFill::random_fill_probability_1
), 0, 0, 255},
198 {"", GD_TYPE_ELEMENT
, 0, N_("Random fill 1"), GetterBase::create_new(&CaveRandomFill::random_fill_1
), 0},
199 {"", GD_TYPE_INT
, 0, N_("Probability 2"), GetterBase::create_new(&CaveRandomFill::random_fill_probability_2
), 0, 0, 255},
200 {"", GD_TYPE_ELEMENT
, 0, N_("Random fill 2"), GetterBase::create_new(&CaveRandomFill::random_fill_2
), 0},
201 {"", GD_TYPE_INT
, 0, N_("Probability 3"), GetterBase::create_new(&CaveRandomFill::random_fill_probability_3
), 0, 0, 255},
202 {"", GD_TYPE_ELEMENT
, 0, N_("Random fill 3"), GetterBase::create_new(&CaveRandomFill::random_fill_3
), 0},
203 {"", GD_TYPE_INT
, 0, N_("Probability 4"), GetterBase::create_new(&CaveRandomFill::random_fill_probability_4
), 0, 0, 255},
204 {"", GD_TYPE_ELEMENT
, 0, N_("Random fill 4"), GetterBase::create_new(&CaveRandomFill::random_fill_4
), 0},
208 PropertyDescription
const* CaveRandomFill::get_description_array() const
213 std::string
CaveRandomFill::get_description_markup() const
215 if (replace_only
==O_NONE
)
216 return SPrintf(_("Random fill from %d,%d to %d,%d"))
217 % p1
.x
% p1
.y
% p2
.x
% p2
.y
;
219 return SPrintf(_("Random fill from %d,%d to %d,%d, replacing %s"))
220 % p1
.x
% p1
.y
% p2
.x
% p2
.y
% gd_element_properties
[replace_only
].lowercase_name
;