Project

General

Profile

Feature #277 ยป 0041-Add-Tech_Leakage-enablement-effect.patch

Marko Lindqvist, 02/25/2024 05:26 AM

View differences:

ai/default/daieffects.c
case EFT_TECH_COST_FACTOR:
v -= amount * 50;
break;
case EFT_TECH_LEAKAGE:
{
int leak_val = 0;
switch (game.info.tech_leakage) {
case TECH_LEAKAGE_NONE:
break;
case TECH_LEAKAGE_EMBASSIES:
leak_val = (normal_player_count() - 1) * 2;
break;
case TECH_LEAKAGE_PLAYERS:
leak_val = (normal_player_count() - 1) * 5;
break;
case TECH_LEAKAGE_NO_BARBS:
leak_val = (normal_player_count() - 1) * 5 + 2 * 3;
break;
}
if (amount > 0 && get_player_bonus(pplayer, EFT_TECH_LEAKAGE) <= 0) {
v += leak_val;
} else if (amount < 0) {
v -= leak_val;
}
}
break;
case EFT_IMPR_BUILD_COST_PCT:
case EFT_UNIT_BUILD_COST_PCT:
v -= amount * 30;
common/effects.h
#define SPECENUM_VALUE137NAME "Surplus_Waste_Pct"
#define SPECENUM_VALUE138 EFT_SURPLUS_WASTE_PCT_BY_REL_DISTANCE
#define SPECENUM_VALUE138NAME "Surplus_Waste_Pct_By_Rel_Distance"
#define SPECENUM_VALUE139 EFT_TECH_LEAKAGE
#define SPECENUM_VALUE139NAME "Tech_Leakage"
/* Ruleset specific effects for use from Lua scripts */
#define SPECENUM_VALUE139 EFT_USER_EFFECT_1
#define SPECENUM_VALUE139NAME "User_Effect_1"
#define SPECENUM_VALUE140 EFT_USER_EFFECT_2
#define SPECENUM_VALUE140NAME "User_Effect_2"
#define SPECENUM_VALUE141 EFT_USER_EFFECT_3
#define SPECENUM_VALUE141NAME "User_Effect_3"
#define SPECENUM_VALUE142 EFT_USER_EFFECT_4
#define SPECENUM_VALUE142NAME "User_Effect_4"
#define SPECENUM_VALUE140 EFT_USER_EFFECT_1
#define SPECENUM_VALUE140NAME "User_Effect_1"
#define SPECENUM_VALUE141 EFT_USER_EFFECT_2
#define SPECENUM_VALUE141NAME "User_Effect_2"
#define SPECENUM_VALUE142 EFT_USER_EFFECT_3
#define SPECENUM_VALUE142NAME "User_Effect_3"
#define SPECENUM_VALUE143 EFT_USER_EFFECT_4
#define SPECENUM_VALUE143NAME "User_Effect_4"
/* Keep this last */
#define SPECENUM_COUNT EFT_COUNT
#include "specenum_gen.h"
common/research.c
enum tech_cost_style tech_cost_style = game.info.tech_cost_style;
int members;
double base_cost, total_cost;
double leak = 0.0;
bool leakage = FALSE;
if (valid_advance_by_number(tech) == NULL) {
return 0;
......
members++;
total_cost += (base_cost
* get_player_bonus(pplayer, EFT_TECH_COST_FACTOR));
if (!leakage && get_player_bonus(pplayer, EFT_TECH_LEAKAGE)) {
leakage = TRUE;
}
} research_players_iterate_end;
if (0 == members) {
/* There is no more alive players for this research, no need to apply
......
}
base_cost = total_cost / members;
fc_assert_msg(tech_leakage_style_is_valid(game.info.tech_leakage),
"Invalid tech_leakage %d", game.info.tech_leakage);
switch (game.info.tech_leakage) {
case TECH_LEAKAGE_NONE:
/* no change */
break;
if (leakage) {
double leak = 0.0;
case TECH_LEAKAGE_EMBASSIES:
{
int players = 0, players_with_tech_and_embassy = 0;
fc_assert_msg(tech_leakage_style_is_valid(game.info.tech_leakage),
"Invalid tech_leakage %d", game.info.tech_leakage);
switch (game.info.tech_leakage) {
case TECH_LEAKAGE_NONE:
/* No change */
break;
players_iterate_alive(aplayer) {
const struct research *aresearch = research_get(aplayer);
case TECH_LEAKAGE_EMBASSIES:
{
int players = 0, players_with_tech_and_embassy = 0;
players++;
if (aresearch == presearch
|| (A_FUTURE == tech
? aresearch->future_tech <= presearch->future_tech
: TECH_KNOWN != research_invention_state(aresearch, tech))) {
continue;
}
players_iterate_alive(aplayer) {
const struct research *aresearch = research_get(aplayer);
research_players_iterate(presearch, pplayer) {
if (player_has_embassy(pplayer, aplayer)) {
players_with_tech_and_embassy++;
break;
players++;
if (aresearch == presearch
|| (A_FUTURE == tech
? aresearch->future_tech <= presearch->future_tech
: TECH_KNOWN != research_invention_state(aresearch, tech))) {
continue;
}
} research_players_iterate_end;
} players_iterate_alive_end;
fc_assert_ret_val(0 < players, base_cost);
fc_assert(players >= players_with_tech_and_embassy);
leak = base_cost * players_with_tech_and_embassy
* game.info.tech_leak_pct / players / 100;
}
break;
research_players_iterate(presearch, pplayer) {
if (player_has_embassy(pplayer, aplayer)) {
players_with_tech_and_embassy++;
break;
}
} research_players_iterate_end;
} players_iterate_alive_end;
fc_assert_ret_val(0 < players, base_cost);
fc_assert(players >= players_with_tech_and_embassy);
leak = base_cost * players_with_tech_and_embassy
* game.info.tech_leak_pct / players / 100;
}
break;
case TECH_LEAKAGE_PLAYERS:
{
int players = 0, players_with_tech = 0;
players_iterate_alive(aplayer) {
players++;
if (A_FUTURE == tech
? research_get(aplayer)->future_tech > presearch->future_tech
: TECH_KNOWN == research_invention_state(research_get(aplayer),
tech)) {
players_with_tech++;
}
} players_iterate_alive_end;
case TECH_LEAKAGE_PLAYERS:
{
int players = 0, players_with_tech = 0;
players_iterate_alive(aplayer) {
players++;
if (A_FUTURE == tech
? research_get(aplayer)->future_tech > presearch->future_tech
: TECH_KNOWN == research_invention_state(research_get(aplayer),
tech)) {
players_with_tech++;
}
} players_iterate_alive_end;
fc_assert_ret_val(0 < players, base_cost);
fc_assert(players >= players_with_tech);
leak = base_cost * players_with_tech * game.info.tech_leak_pct
/ players / 100;
}
break;
fc_assert_ret_val(0 < players, base_cost);
fc_assert(players >= players_with_tech);
leak = base_cost * players_with_tech * game.info.tech_leak_pct
/ players / 100;
}
break;
case TECH_LEAKAGE_NO_BARBS:
{
int players = 0, players_with_tech = 0;
case TECH_LEAKAGE_NO_BARBS:
{
int players = 0, players_with_tech = 0;
players_iterate_alive(aplayer) {
if (is_barbarian(aplayer)) {
continue;
}
players++;
if (A_FUTURE == tech
? research_get(aplayer)->future_tech > presearch->future_tech
: TECH_KNOWN == research_invention_state(research_get(aplayer),
tech)) {
players_with_tech++;
}
} players_iterate_alive_end;
players_iterate_alive(aplayer) {
if (is_barbarian(aplayer)) {
continue;
}
players++;
if (A_FUTURE == tech
? research_get(aplayer)->future_tech > presearch->future_tech
: TECH_KNOWN == research_invention_state(research_get(aplayer),
tech)) {
players_with_tech++;
}
} players_iterate_alive_end;
fc_assert_ret_val(0 < players, base_cost);
fc_assert(players >= players_with_tech);
leak = base_cost * players_with_tech * game.info.tech_leak_pct
/ players / 100;
fc_assert_ret_val(0 < players, base_cost);
fc_assert(players >= players_with_tech);
leak = base_cost * players_with_tech * game.info.tech_leak_pct
/ players / 100;
}
break;
}
break;
}
if (leak > base_cost) {
base_cost = 0.0;
} else {
base_cost -= leak;
if (leak > base_cost) {
base_cost = 0.0;
} else {
base_cost -= leak;
}
}
/* Assign a science penalty to the AI at easier skill levels. This code
common/tech.c
}
/**********************************************************************//**
Returns true if the costs for the given technology will stay constant
during the game. False otherwise.
Returns true if the costs for the given technology will stay constant
during the game. False otherwise.
Checking every tech_cost_style with fixed costs seems a waste of system
resources, when we can check that it is not the one style without fixed
costs.
Checking every tech_cost_style with fixed costs seems a waste of system
resources, when we can check that it is not the one style without fixed
costs.
**************************************************************************/
bool techs_have_fixed_costs(void)
{
data/alien/effects.ruleset
type = "Tech_Cost_Factor"
value = 1
[effect_tech_leakage]
type = "Tech_Leakage"
value = 1
[effect_mood_center]
type = "Make_Content"
value = 3
data/civ1/effects.ruleset
"MinYear", "1", "World"
}
[effect_tech_leakage]
type = "Tech_Leakage"
value = 1
; Cities can always work tiles
[effect_tile_workable]
type = "Tile_Workable"
data/civ2/effects.ruleset
"MinYear", "1", "World"
}
[effect_tech_leakage]
type = "Tech_Leakage"
value = 1
; Cities can always work tiles
[effect_tile_workable]
type = "Tile_Workable"
data/civ2civ3/effects.ruleset
type = "Tech_Cost_Factor"
value = 3
[effect_tech_leakage]
type = "Tech_Leakage"
value = 1
; Cities can always work tiles
[effect_tile_workable]
type = "Tile_Workable"
data/classic/effects.ruleset
type = "Tech_Cost_Factor"
value = 1
[effect_tech_leakage]
type = "Tech_Leakage"
value = 1
; Cities can always work tiles
[effect_tile_workable]
type = "Tile_Workable"
data/goldkeep/effects.ruleset
type = "Tech_Cost_Factor"
value = 1
[effect_tech_leakage]
type = "Tech_Leakage"
value = 1
; Cities can always work tiles
[effect_tile_workable]
type = "Tile_Workable"
data/granularity/effects.ruleset
type = "Tech_Cost_Factor"
value = 1
[effect_tech_leakage]
type = "Tech_Leakage"
value = 1
[effect_tile_land_workable]
type = "Tile_Workable"
value = 1
data/multiplayer/effects.ruleset
type = "Tech_Cost_Factor"
value = 1
[effect_tech_leakage]
type = "Tech_Leakage"
value = 1
; Cities can always work tiles
[effect_tile_workable]
type = "Tile_Workable"
data/sandbox/effects.ruleset
type = "Tech_Cost_Factor"
value = 3
[effect_tech_leakage]
type = "Tech_Leakage"
value = 1
; Cities can always work tiles
[effect_tile_workable]
type = "Tile_Workable"
data/webperimental/effects.ruleset
type = "Tech_Cost_Factor"
value = 1
[effect_tech_leakage]
type = "Tech_Leakage"
value = 1
; Cities can always work tiles
[effect_tile_workable]
type = "Tile_Workable"
doc/README.effects
Tech_Cost_Factor
Factor for research costs.
Tech_Leakage
If value is positive, tech leakage towards the player is enabled.
The amount of leakage is controlled by the game.ruleset setting "tech_leakage",
and can be even zero.
Tech_Parasite
Gain any advance known already by amount number of other teams,
if team_pooled_research is enabled, or amount number of other players
server/ruleset/rscompat.c
* the new effects from being upgraded by accident. */
iterate_effect_cache(effect_list_compat_cb, info);
/* Old hardcoded behavior always had tech leakage enabled,
* thought limited by game.info.tech_leakage setting. */
effect_new(EFT_TECH_LEAKAGE, 1, nullptr);
/* Make sure that all action enablers added or modified by the
* compatibility post processing fulfills all hard action requirements. */
rscompat_enablers_add_obligatory_hard_reqs();
    (1-1/1)