Refactoring morale into a separate module.

Not all of it yet, because it is inconveniently part of kernel/region.
This commit is contained in:
Enno Rehling 2014-12-10 19:04:02 +01:00
parent 01877f5169
commit 1024dd5c81
7 changed files with 118 additions and 61 deletions

View file

@ -84,6 +84,7 @@ set (ERESSEA_SRC
laws.c
magic.c
market.c
morale.c
monster.c
randenc.c
report.c

View file

@ -29,6 +29,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "spy.h"
#include "move.h"
#include "monster.h"
#include "morale.h"
#include "reports.h"
/* kernel includes */
@ -596,12 +597,8 @@ static void recruit(unit * u, struct order *ord, request ** recruitorders)
static void friendly_takeover(region * r, faction * f)
{
int morale = region_get_morale(r);
region_set_owner(r, f, turn);
if (morale > 0) {
morale = _max(0, morale - MORALE_TRANSFER);
region_set_morale(r, morale, turn);
}
morale_change(r, MORALE_TRANSFER);
}
void give_control(unit * u, unit * u2)

View file

@ -1017,20 +1017,6 @@ int read_unitid(const faction * f, const region * r)
/* exported symbol */
bool getunitpeasants;
unit *getunitg(const region * r, const faction * f)
{
int n = read_unitid(f, r);
if (n == 0) {
getunitpeasants = 1;
return NULL;
}
getunitpeasants = 0;
if (n < 0)
return 0;
return findunit(n);
}
unit *getunit(const region * r, const faction * f)
{

View file

@ -163,7 +163,6 @@ extern "C" {
struct unit *createunit(struct region *r, struct faction *f,
int number, const struct race *rc);
void create_unitid(struct unit *u, int id);
struct unit *getunitg(const struct region *r, const struct faction *f);
struct unit *getunit(const struct region *r, const struct faction *f);
int read_unitid(const struct faction *f, const struct region *r);

View file

@ -28,6 +28,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "economy.h"
#include "keyword.h"
#include "market.h"
#include "morale.h"
#include "monster.h"
#include "move.h"
#include "randenc.h"
@ -857,19 +858,15 @@ int can_contact(const region * r, const unit * u, const unit * u2) {
int contact_cmd(unit * u, order * ord)
{
/* unit u kontaktiert unit u2. Dies setzt den contact einfach auf 1 -
* ein richtiger toggle ist (noch?) nicht noetig. die region als
* parameter ist nur deswegen wichtig, weil er an getunit ()
* weitergegeben wird. dies wird fuer das auffinden von tempunits in
* getnewunit () verwendet! */
unit *u2;
region *r = u->region;
int n;
init_order(ord);
u2 = getunitg(r, u->faction);
n = read_unitid(u->faction, u->region);
u2 = findunit(n);
if (u2 != NULL) {
if (!can_contact(r, u, u2)) {
if (!can_contact(u->region, u, u2)) {
cmistake(u, u->thisorder, 23, MSG_EVENT);
return -1;
}
@ -3160,12 +3157,6 @@ static building *age_building(building * b)
return b;
}
static double rc_popularity(const struct race *rc)
{
int pop = get_param_int(rc->parameters, "morale", MORALE_AVERAGE);
return 1.0 / (pop - MORALE_COOLDOWN); /* 10 turns average */
}
static void age_region(region * r)
{
a_age(&r->attribs);
@ -3174,33 +3165,7 @@ static void age_region(region * r)
if (!r->land)
return;
if (r->land->ownership && r->land->ownership->owner) {
int stability = turn - r->land->ownership->morale_turn;
int maxmorale = MORALE_DEFAULT;
building *b = largestbuilding(r, &cmp_taxes, false);
if (b) {
int bsize = buildingeffsize(b, false);
maxmorale = (int)(0.5 + b->type->taxes(b, bsize + 1) / MORALE_TAX_FACTOR);
}
if (r->land->morale < maxmorale) {
if (stability > MORALE_COOLDOWN && r->land->ownership->owner
&& r->land->morale < MORALE_MAX) {
double ch = rc_popularity(r->land->ownership->owner->race);
if (is_cursed(r->attribs, C_GENEROUS, 0)) {
ch *= 1.2; /* 20% improvement */
}
if (stability >= MORALE_AVERAGE * 2 || chance(ch)) {
region_set_morale(r, r->land->morale + 1, turn);
}
}
}
else if (r->land->morale > maxmorale) {
region_set_morale(r, r->land->morale - 1, turn);
}
}
else if (r->land->morale > MORALE_DEFAULT) {
region_set_morale(r, r->land->morale - 1, turn);
}
morale_update(r);
}
static void ageing(void)

74
src/morale.c Normal file
View file

@ -0,0 +1,74 @@
/*
Copyright (c) 1998-2014,
Enno Rehling <enno@eressea.de>
Katja Zedel <katze@felidae.kn-bremen.de
Christian Schlittchen <corwin@amber.kn-bremen.de>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**/
#include <platform.h>
#include "morale.h"
#include <kernel/config.h>
#include <kernel/curse.h>
#include <kernel/region.h>
#include <kernel/faction.h>
#include <kernel/race.h>
#include <kernel/building.h>
#include <util/rand.h>
static double rc_popularity(const struct race *rc)
{
int pop = get_param_int(rc->parameters, "morale", MORALE_AVERAGE);
return 1.0 / (pop - MORALE_COOLDOWN); /* 10 turns average */
}
void morale_update(region *r) {
if (r->land->ownership && r->land->ownership->owner) {
int stability = turn - r->land->ownership->morale_turn;
int maxmorale = MORALE_DEFAULT;
building *b = largestbuilding(r, &cmp_taxes, false);
if (b) {
int bsize = buildingeffsize(b, false);
maxmorale = (int)(0.5 + b->type->taxes(b, bsize + 1) / MORALE_TAX_FACTOR);
}
if (r->land->morale < maxmorale) {
if (stability > MORALE_COOLDOWN && r->land->ownership->owner
&& r->land->morale < MORALE_MAX) {
double ch = rc_popularity(r->land->ownership->owner->race);
if (is_cursed(r->attribs, C_GENEROUS, 0)) {
ch *= 1.2; /* 20% improvement */
}
if (stability >= MORALE_AVERAGE * 2 || chance(ch)) {
region_set_morale(r, r->land->morale + 1, turn);
}
}
}
else if (r->land->morale > maxmorale) {
region_set_morale(r, r->land->morale - 1, turn);
}
}
else if (r->land->morale > MORALE_DEFAULT) {
region_set_morale(r, r->land->morale - 1, turn);
}
}
void morale_change(region *r, int value) {
int morale = region_get_morale(r);
if (morale > 0) {
morale = _max(0, morale - value);
region_set_morale(r, morale, turn);
}
}

35
src/morale.h Normal file
View file

@ -0,0 +1,35 @@
/*
Copyright (c) 1998-2010, Enno Rehling <enno@eressea.de>
Katja Zedel <katze@felidae.kn-bremen.de
Christian Schlittchen <corwin@amber.kn-bremen.de>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**/
#ifndef H_GC_MORALE
#define H_GC_MORALE
#include <kernel/types.h>
#ifdef __cplusplus
extern "C" {
#endif
struct region;
void morale_update(struct region *r);
void morale_change(struct region *r, int value);
#ifdef __cplusplus
}
#endif
#endif