[Freeciv-Dev] (PR#12841) city_luxury_need function
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://bugs.freeciv.org/Ticket/Display.html?id=12841 >
This patch adds a function city_luxury_need().
As you may be thinking already, this is taken exactly from Per's patch
in 12734. The only difference is that I added an assertion in
generic_city_refresh to make sure it works.
Oh, and the assertion fails. So either the assertion is wrong (I don't
think so) or the function is.
(gdb) p pcity->ppl_happy
$8 = {0, 1, 1, 1, 1}
(gdb) p pcity->ppl_content
$9 = {0, 0, 0, 0, 0}
(gdb) p pcity->ppl_unhappy
$10 = {2, 1, 1, 1, 1}
(gdb) p pcity->ppl_angry
$11 = {0, 0, 0, 0, 0}
(gdb) p pcity->specialists
$12 = {2, 0, 3, 0 <repeats 17 times>}
Given that there are 5 specialists in the city I'd assume the problem is
as the comment in the function says:
We ignore here the fact that specialists may be taken from unhappy
citizens when we no longer have any content ones left.
Oddly there is one happy citizen.
Unless this problem can be fixed (and I don't see how it can be, without
changing the rules a bit) I don't think this function is useful. To be
useful for the CM (which it would be!) the function has to be 100% correct.
-----
Now, this issue is at the heart of a larger problem. Specialists do not
have happiness status. They are not counted in the
content/happy/unhappy arrays. Aside from being not-quite-logical this
means any sort of all-specialist ruleset would always have content
(never happy or unhappy) cities.
With a MoM ruleset this is particularly a problem. MoM doesn't have
unhappy or happy cities, only *citizens* who are in revolt. A citizen
in revolt produces no output but has no other effects.
At first I thought this could be solved with something like this:
1. All citizens (not just tile workers) get happy/unhappy status.
2. Specialists citizens get a new boolean: can_be_unhappy. Only if the
specialist has this field set can unhappy (or angry) citizens be of this
type. (So for the default ruleset it would be elvises, for the mom
ruleset it would be revolters.)
And the only problem is with the display (it's hard to show that a
citizen is both a taxman happy). However I think this won't work
because it means the number of available specialists depends on the
luxury present - for instance you cannot turn everyone into a scientist
if this means some of the scientists will be unhappy (again, a problem
in MoM ruleset as you cannot toggle unhappy citizens at all). This
won't work with the CM since it precalculates (independent of luxury)
what citizens it can make. But maybe we can work around this problem
inside of generic_city_refresh somehow.
Whatever we do it will be bug-prone. Lots of assertions are needed to
make sure we don't have mistakes somewhere. The CM is ideal for this
since it has a tendancy to go over every impossible combination (so
"unlikely" assertions will be triggered regularly).
-jason
Index: common/city.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/city.c,v
retrieving revision 1.328
diff -u -r1.328 city.c
--- common/city.c 18 Apr 2005 06:52:50 -0000 1.328
+++ common/city.c 19 Apr 2005 04:31:37 -0000
@@ -2253,6 +2253,10 @@
unhappy_city_check(pcity);
set_surpluses(pcity);
+ assert(pcity->surplus[O_LUXURY]
+ >= city_luxury_need(pcity,
+ !city_unhappy(pcity), city_happy(pcity)));
+
if (full_refresh
&& pcity->citizen_base[O_TRADE] != prev_tile_trade) {
int i;
@@ -2620,3 +2624,36 @@
unit_list_free(pcity->units_supported);
free(pcity);
}
+
+/**************************************************************************
+ Calculate necessary luxury to achieve goals for this city.
+
+ We ignore here the fact that specialists may be taken from unhappy
+ citizens when we no longer have any content ones left.
+**************************************************************************/
+int city_luxury_need(struct city *pcity, bool order, bool celebrate)
+{
+ struct player *pplayer = city_owner(pcity);
+ int result = 0;
+ int happy, content, unhappy, angry;
+
+ if (order || celebrate) {
+ /* We need to figure out how much luxuries we need. */
+ citizen_base_mood(pplayer, 0, &happy, &content, &unhappy, &angry,
+ pcity->size);
+ citizen_content_buildings(pcity, &content, &unhappy, &angry);
+ citizen_happy_units(pcity, &happy, &content, &unhappy, &angry);
+ citizen_happy_wonders(pcity, &happy, &content, &unhappy, &angry);
+ }
+ if (order || celebrate) {
+ /* Find out how much luxuries we need to make everyone content. */
+ result = MAX((angry * 2 + unhappy - happy) * HAPPY_COST, 0);
+ }
+ if (celebrate) {
+ /* Find out how much extra luxuries we will need to make enough
+ * citizens happy that we can celebrate. */
+ result += MAX(((pcity->size - happy + 1) / 2) * HAPPY_COST, 0);
+ }
+
+ return result;
+}
Index: common/city.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/city.h,v
retrieving revision 1.205
diff -u -r1.205 city.h
--- common/city.h 18 Apr 2005 06:52:50 -0000 1.205
+++ common/city.h 19 Apr 2005 04:31:37 -0000
@@ -517,6 +517,7 @@
bool is_city_option_set(const struct city *pcity, enum city_options option);
void city_styles_alloc(int num);
void city_styles_free(void);
+int city_luxury_need(struct city *pcity, bool order, bool celebrate);
void get_citizen_output(const struct city *pcity, int *output);
void add_tax_income(const struct player *pplayer, int trade, int *output);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Freeciv-Dev] (PR#12841) city_luxury_need function,
Jason Short <=
|
|