move wages and related functionality to buildin.c

This commit is contained in:
Enno Rehling 2016-11-23 17:36:39 +01:00
parent 09f22ba0bc
commit 88f5bfaf47
4 changed files with 244 additions and 262 deletions

View File

@ -22,12 +22,14 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "building.h"
/* kernel includes */
#include "curse.h"
#include "item.h"
#include "unit.h"
#include "faction.h"
#include "race.h"
#include "region.h"
#include "skill.h"
#include "terrain.h"
#include "lighthouse.h"
/* util includes */
@ -52,6 +54,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <limits.h>
/* attributes includes */
#include <attributes/reduceproduction.h>
#include <attributes/matmod.h>
typedef struct building_typelist {
@ -359,16 +362,6 @@ static int building_protection(const building * b, const unit * u, building_bonu
}
}
void register_buildings(void)
{
register_function((pf_generic)building_protection,
"building_protection");
register_function((pf_generic)init_smithy, "init_smithy");
register_function((pf_generic)castle_name, "castle_name");
register_function((pf_generic)castle_name_2, "castle_name_2");
register_function((pf_generic)fort_name, "fort_name");
}
void write_building_reference(const struct building *b, struct storage *store)
{
WRITE_INT(store, (b && b->region) ? b->no : 0);
@ -456,8 +449,8 @@ void remove_building(building ** blist, building * b)
update_lighthouse(b);
bunhash(b);
/* Falls Karawanserei, Damm oder Tunnel einstürzen, wird die schon
* gebaute Straße zur lfte vernichtet */
/* Falls Karawanserei, Damm oder Tunnel einst<EFBFBD>rzen, wird die schon
* gebaute Stra<EFBFBD>e zur H<EFBFBD>lfte vernichtet */
// TODO: caravan, tunnel, dam modularization ? is_building_type ?
if (b->type == bt_caravan || b->type == bt_dam || b->type == bt_tunnel) {
region *r = b->region;
@ -570,7 +563,7 @@ void building_set_owner(struct unit * owner)
static unit *building_owner_ex(const building * bld, const struct faction * last_owner)
{
unit *u, *heir = 0;
/* Eigentümer tot oder kein Eigentümer vorhanden. Erste lebende Einheit
/* Eigent<EFBFBD>mer tot oder kein Eigent<6E>mer vorhanden. Erste lebende Einheit
* nehmen. */
for (u = bld->region->units; u; u = u->next) {
if (u->building == bld) {
@ -702,3 +695,228 @@ bool is_building_type(const struct building_type *btype, const char *name) {
assert(btype);
return name && strcmp(btype->_name, name)==0;
}
building *largestbuilding(const region * r, cmp_building_cb cmp_gt,
bool imaginary)
{
building *b, *best = NULL;
for (b = rbuildings(r); b; b = b->next) {
if (cmp_gt(b, best) <= 0)
continue;
if (!imaginary) {
const attrib *a = a_find(b->attribs, &at_icastle);
if (a)
continue;
}
best = b;
}
return best;
}
/* Lohn bei den einzelnen Burgstufen f<>r Normale Typen, Orks, Bauern,
* Modifikation f<EFBFBD>r St<EFBFBD>dter. */
static const int wagetable[7][4] = {
{ 10, 10, 11, -7 }, /* Baustelle */
{ 10, 10, 11, -5 }, /* Handelsposten */
{ 11, 11, 12, -3 }, /* Befestigung */
{ 12, 11, 13, -1 }, /* Turm */
{ 13, 12, 14, 0 }, /* Burg */
{ 14, 12, 15, 1 }, /* Festung */
{ 15, 13, 16, 2 } /* Zitadelle */
};
static int
default_wage(const region * r, const faction * f, const race * rc, int in_turn)
{
building *b = largestbuilding(r, &cmp_wage, false);
int esize = 0;
double wage;
static int ct_cache;
static const struct curse_type *drought_ct;
if (ct_changed(&ct_cache)) {
drought_ct = ct_find("drought");
}
if (b != NULL) {
/* TODO: this reveals imaginary castles */
esize = buildingeffsize(b, false);
}
if (f != NULL) {
int index = 0;
if (rc == get_race(RC_ORC) || rc == get_race(RC_SNOTLING)) {
index = 1;
}
wage = wagetable[esize][index];
}
else {
if (is_mourning(r, in_turn)) {
wage = 10;
}
else if (fval(r->terrain, SEA_REGION)) {
wage = 11;
}
else {
wage = wagetable[esize][2];
}
if (rule_blessed_harvest() == HARVEST_WORK) {
/* E1 rules */
wage += curse_geteffect(get_curse(r->attribs, ct_find("blessedharvest")));
}
}
/* Artsculpture: Income +5 */
for (b = r->buildings; b; b = b->next) {
if (is_building_type(b->type, "artsculpture")) {
wage += 5;
}
}
if (r->attribs) {
attrib *a;
const struct curse_type *ctype;
/* Godcurse: Income -10 */
ctype = ct_find("godcursezone");
if (ctype && curse_active(get_curse(r->attribs, ctype))) {
wage = _max(0, wage - 10);
}
/* Bei einer D<>rre verdient man nur noch ein Viertel */
if (drought_ct) {
curse *c = get_curse(r->attribs, drought_ct);
if (curse_active(c))
wage /= curse_geteffect(c);
}
a = a_find(r->attribs, &at_reduceproduction);
if (a) {
wage = (wage * a->data.sa[0]) / 100;
}
}
return (int)wage;
}
static int
minimum_wage(const region * r, const faction * f, const race * rc, int in_turn)
{
if (f && rc) {
return rc->maintenance;
}
return default_wage(r, f, rc, in_turn);
}
/* Gibt Arbeitslohn f<>r entsprechende Rasse zur<75>ck, oder f<>r
* die Bauern wenn f == NULL. */
int wage(const region * r, const faction * f, const race * rc, int in_turn)
{
if (global.functions.wage) {
return global.functions.wage(r, f, rc, in_turn);
}
return default_wage(r, f, rc, in_turn);
}
int cmp_wage(const struct building *b, const building * a)
{
if (is_building_type(b->type, "castle")) {
if (!a)
return 1;
if (b->size > a->size)
return 1;
if (b->size == a->size)
return 0;
}
return -1;
}
bool is_owner_building(const struct building * b)
{
region *r = b->region;
if (b->type->taxes && r->land && r->land->ownership) {
unit *u = building_owner(b);
return u && u->faction == r->land->ownership->owner;
}
return false;
}
int cmp_taxes(const building * b, const building * a)
{
faction *f = region_get_owner(b->region);
if (b->type->taxes) {
unit *u = building_owner(b);
if (!u) {
return -1;
}
else if (a) {
int newsize = buildingeffsize(b, false);
double newtaxes = b->type->taxes(b, newsize);
int oldsize = buildingeffsize(a, false);
double oldtaxes = a->type->taxes(a, oldsize);
if (newtaxes < oldtaxes)
return -1;
else if (newtaxes > oldtaxes)
return 1;
else if (b->size < a->size)
return -1;
else if (b->size > a->size)
return 1;
else {
if (u && u->faction == f) {
u = building_owner(a);
if (u && u->faction == f)
return -1;
return 1;
}
}
}
else {
return 1;
}
}
return -1;
}
int cmp_current_owner(const building * b, const building * a)
{
faction *f = region_get_owner(b->region);
assert(rule_region_owners());
if (f && b->type->taxes) {
unit *u = building_owner(b);
if (!u || u->faction != f)
return -1;
if (a) {
int newsize = buildingeffsize(b, false);
double newtaxes = b->type->taxes(b, newsize);
int oldsize = buildingeffsize(a, false);
double oldtaxes = a->type->taxes(a, oldsize);
if (newtaxes > oldtaxes) {
return 1;
}
if (newtaxes < oldtaxes) {
return -1;
}
if (newsize != oldsize) {
return newsize - oldsize;
}
return (b->size - a->size);
}
else {
return 1;
}
}
return -1;
}
void register_buildings(void)
{
register_function((pf_generic)minimum_wage, "minimum_wage");
register_function((pf_generic)building_protection,
"building_protection");
register_function((pf_generic)init_smithy, "init_smithy");
register_function((pf_generic)castle_name, "castle_name");
register_function((pf_generic)castle_name_2, "castle_name_2");
register_function((pf_generic)fort_name, "fort_name");
}

View File

@ -60,8 +60,8 @@ extern "C" {
char *_name;
int flags; /* flags */
int capacity; /* Kapazität pro Größenpunkt */
int maxcapacity; /* Max. Kapazität */
int capacity; /* Kapazit<EFBFBD>t pro Gr<47><72>enpunkt */
int maxcapacity; /* Max. Kapazit<EFBFBD>t */
int maxsize; /* how big can it get, with all the extensions? */
int magres; /* how well it resists against spells */
int magresbonus; /* bonus it gives the target against spells */
@ -131,7 +131,17 @@ extern "C" {
int id, int size, struct order *ord);
bool building_finished(const struct building *b);
/* Alte Gebäudetypen: */
int wage(const struct region *r, const struct faction *f,
const struct race *rc, int in_turn);
typedef int(*cmp_building_cb) (const struct building * b,
const struct building * a);
struct building *largestbuilding(const struct region *r, cmp_building_cb,
bool imaginary);
int cmp_wage(const struct building *b, const struct building *bother);
int cmp_taxes(const struct building *b, const struct building *bother);
int cmp_current_owner(const struct building *b,
const struct building *bother);
/* old functions, still in build.c: */
int buildingeffsize(const building * b, int imaginary);

View File

@ -19,9 +19,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <platform.h>
#include <kernel/config.h>
/* attributes includes */
#include <attributes/reduceproduction.h>
/* kernel includes */
#include "alliance.h"
#include "ally.h"
@ -253,37 +250,6 @@ unit *getnewunit(const region * r, const faction * f)
return findnewunit(r, f, n);
}
/* - Namen der Strukturen -------------------------------------- */
char *untilde(char *ibuf)
{
char *p = ibuf;
while (*p) {
if (*p == '~') {
*p = ' ';
}
++p;
}
return ibuf;
}
building *largestbuilding(const region * r, cmp_building_cb cmp_gt,
bool imaginary)
{
building *b, *best = NULL;
for (b = rbuildings(r); b; b = b->next) {
if (cmp_gt(b, best) <= 0)
continue;
if (!imaginary) {
const attrib *a = a_find(b->attribs, &at_icastle);
if (a)
continue;
}
best = b;
}
return best;
}
/* -- Erschaffung neuer Einheiten ------------------------------ */
@ -640,113 +606,6 @@ char *_strdup(const char *s)
}
#endif
/* Lohn bei den einzelnen Burgstufen f<>r Normale Typen, Orks, Bauern,
* Modifikation f<EFBFBD>r St<EFBFBD>dter. */
static const int wagetable[7][4] = {
{ 10, 10, 11, -7 }, /* Baustelle */
{ 10, 10, 11, -5 }, /* Handelsposten */
{ 11, 11, 12, -3 }, /* Befestigung */
{ 12, 11, 13, -1 }, /* Turm */
{ 13, 12, 14, 0 }, /* Burg */
{ 14, 12, 15, 1 }, /* Festung */
{ 15, 13, 16, 2 } /* Zitadelle */
};
int cmp_wage(const struct building *b, const building * a)
{
if (is_building_type(b->type, "castle")) {
if (!a)
return 1;
if (b->size > a->size)
return 1;
if (b->size == a->size)
return 0;
}
return -1;
}
bool is_owner_building(const struct building * b)
{
region *r = b->region;
if (b->type->taxes && r->land && r->land->ownership) {
unit *u = building_owner(b);
return u && u->faction == r->land->ownership->owner;
}
return false;
}
int cmp_taxes(const building * b, const building * a)
{
faction *f = region_get_owner(b->region);
if (b->type->taxes) {
unit *u = building_owner(b);
if (!u) {
return -1;
}
else if (a) {
int newsize = buildingeffsize(b, false);
double newtaxes = b->type->taxes(b, newsize);
int oldsize = buildingeffsize(a, false);
double oldtaxes = a->type->taxes(a, oldsize);
if (newtaxes < oldtaxes)
return -1;
else if (newtaxes > oldtaxes)
return 1;
else if (b->size < a->size)
return -1;
else if (b->size > a->size)
return 1;
else {
if (u && u->faction == f) {
u = building_owner(a);
if (u && u->faction == f)
return -1;
return 1;
}
}
}
else {
return 1;
}
}
return -1;
}
int cmp_current_owner(const building * b, const building * a)
{
faction *f = region_get_owner(b->region);
assert(rule_region_owners());
if (f && b->type->taxes) {
unit *u = building_owner(b);
if (!u || u->faction != f)
return -1;
if (a) {
int newsize = buildingeffsize(b, false);
double newtaxes = b->type->taxes(b, newsize);
int oldsize = buildingeffsize(a, false);
double oldtaxes = a->type->taxes(a, oldsize);
if (newtaxes > oldtaxes) {
return 1;
}
if (newtaxes < oldtaxes) {
return -1;
}
if (newsize != oldsize) {
return newsize - oldsize;
}
return (b->size - a->size);
}
else {
return 1;
}
}
return -1;
}
bool rule_stealth_other(void)
{
static int rule, config;
@ -807,102 +666,11 @@ int rule_faction_limit(void)
return rule;
}
static int
default_wage(const region * r, const faction * f, const race * rc, int in_turn)
{
building *b = largestbuilding(r, &cmp_wage, false);
int esize = 0;
double wage;
static int ct_cache;
static const struct curse_type *drought_ct;
if (ct_changed(&ct_cache)) {
drought_ct = ct_find("drought");
}
if (b != NULL) {
/* TODO: this reveals imaginary castles */
esize = buildingeffsize(b, false);
}
if (f != NULL) {
int index = 0;
if (rc == get_race(RC_ORC) || rc == get_race(RC_SNOTLING)) {
index = 1;
}
wage = wagetable[esize][index];
}
else {
if (is_mourning(r, in_turn)) {
wage = 10;
}
else if (fval(r->terrain, SEA_REGION)) {
wage = 11;
}
else {
wage = wagetable[esize][2];
}
if (rule_blessed_harvest() == HARVEST_WORK) {
/* E1 rules */
wage += curse_geteffect(get_curse(r->attribs, ct_find("blessedharvest")));
}
}
/* Artsculpture: Income +5 */
for (b = r->buildings; b; b = b->next) {
if (is_building_type(b->type, "artsculpture")) {
wage += 5;
}
}
if (r->attribs) {
attrib *a;
const struct curse_type *ctype;
/* Godcurse: Income -10 */
ctype = ct_find("godcursezone");
if (ctype && curse_active(get_curse(r->attribs, ctype))) {
wage = _max(0, wage - 10);
}
/* Bei einer D<>rre verdient man nur noch ein Viertel */
if (drought_ct) {
curse *c = get_curse(r->attribs, drought_ct);
if (curse_active(c))
wage /= curse_geteffect(c);
}
a = a_find(r->attribs, &at_reduceproduction);
if (a) {
wage = (wage * a->data.sa[0]) / 100;
}
}
return (int)wage;
}
static int
minimum_wage(const region * r, const faction * f, const race * rc, int in_turn)
{
if (f && rc) {
return rc->maintenance;
}
return default_wage(r, f, rc, in_turn);
}
/* Gibt Arbeitslohn f<>r entsprechende Rasse zur<75>ck, oder f<>r
* die Bauern wenn f == NULL. */
int wage(const region * r, const faction * f, const race * rc, int in_turn)
{
if (global.functions.wage) {
return global.functions.wage(r, f, rc, in_turn);
}
return default_wage(r, f, rc, in_turn);
}
void kernel_init(void)
{
register_reports();
mt_clear();
translation_init();
register_function((pf_generic)minimum_wage, "minimum_wage");
}
static order * defaults[MAXLOCALES];

View File

@ -54,17 +54,6 @@ struct param;
int forbiddenid(int id);
int newcontainerid(void);
char *untilde(char *s);
typedef int(*cmp_building_cb) (const struct building * b,
const struct building * a);
struct building *largestbuilding(const struct region *r, cmp_building_cb,
bool imaginary);
int cmp_wage(const struct building *b, const struct building *bother);
int cmp_taxes(const struct building *b, const struct building *bother);
int cmp_current_owner(const struct building *b,
const struct building *bother);
bool rule_region_owners(void);
bool rule_stealth_other(void); // units can pretend to be another faction, TARNE PARTEI <no>
bool rule_stealth_anon(void); // units can anonymize their faction, TARNE PARTEI [NICHT]
@ -97,9 +86,6 @@ struct param;
#define GF_PURE 64
/* untranslated */
int wage(const struct region *r, const struct faction *f,
const struct race *rc, int in_turn);
const char *datapath(void);
void set_datapath(const char *path);