Freeciv21
Develop your civilization from humble roots to a global empire
effects.cpp File Reference
#include <cstring>
#include "astring.h"
#include "fcintl.h"
#include "log.h"
#include "shared.h"
#include "support.h"
#include "city.h"
#include "government.h"
#include "improvement.h"
#include "map.h"
#include "multipliers.h"
#include "packets.h"
#include "player.h"
#include "tech.h"
#include "effects.h"
+ Include dependency graph for effects.cpp:

Go to the source code of this file.

Functions

const effect_list * get_effects ()
 Get a list of all effects. More...
 
struct effect_list * get_effects (enum effect_type effect_type)
 Get a list of effects of this type. More...
 
struct effect_list * get_req_source_effects (struct universal *psource)
 Get a list of effects with this requirement source. More...
 
struct effecteffect_new (enum effect_type type, int value, struct multiplier *pmul)
 Add effect to ruleset cache. More...
 
struct effecteffect_copy (struct effect *old)
 Return new copy of the effect. More...
 
void effect_req_append (struct effect *peffect, struct requirement req)
 Append requirement to effect. More...
 
void ruleset_cache_init ()
 Initialize the ruleset cache. More...
 
void ruleset_cache_free ()
 Free the ruleset cache. More...
 
int effect_cumulative_max (enum effect_type type, struct universal *for_uni)
 Get the maximum effect value in this ruleset for the universal (that is, the sum of all positive effects clauses that apply specifically to this universal – this can be an overestimate in the case of mutually exclusive effects). More...
 
int effect_cumulative_min (enum effect_type type, struct universal *for_uni)
 Get the minimum effect value in this ruleset for the universal (that is, the sum of all negative effects clauses that apply specifically to this universal – this can be an overestimate in the case of mutually exclusive effects). More...
 
int effect_value_from_universals (enum effect_type type, struct universal *unis, size_t n_unis)
 Return the base value of a given effect that can always be expected from just the sources in the list, independent of other factors. More...
 
void recv_ruleset_effect (const struct packet_ruleset_effect *packet)
 Receives a new effect. More...
 
void send_ruleset_cache (struct conn_list *dest)
 Send the ruleset cache data over the network. More...
 
bool building_has_effect (const struct impr_type *pimprove, enum effect_type effect_type)
 Returns TRUE if the building has any effect bonuses of the given type. More...
 
static bool is_effect_prevented (const struct player *target_player, const struct player *other_player, const struct city *target_city, const struct impr_type *target_building, const struct tile *target_tile, const struct unit *target_unit, const struct unit_type *target_unittype, const struct output_type *target_output, const struct specialist *target_specialist, const struct effect *peffect, const enum req_problem_type prob_type)
 Return TRUE iff any of the disabling requirements for this effect are active, which would prevent it from taking effect. More...
 
bool is_building_replaced (const struct city *pcity, const struct impr_type *pimprove, const enum req_problem_type prob_type)
 Returns TRUE if a building is replaced. More...
 
int get_target_bonus_effects (struct effect_list *plist, const struct player *target_player, const struct player *other_player, const struct city *target_city, const struct impr_type *target_building, const struct tile *target_tile, const struct unit *target_unit, const struct unit_type *target_unittype, const struct output_type *target_output, const struct specialist *target_specialist, const struct action *target_action, enum effect_type effect_type, enum vision_layer vision_layer, enum national_intelligence nintel)
 Returns the effect bonus of a given type for any target. More...
 
int get_world_bonus (enum effect_type effect_type)
 Returns the effect bonus for the whole world. More...
 
int get_player_bonus (const struct player *pplayer, enum effect_type effect_type)
 Returns the effect bonus for a player. More...
 
int get_city_bonus (const struct city *pcity, enum effect_type effect_type, enum vision_layer vlayer)
 Returns the effect bonus at a city. More...
 
int get_city_specialist_output_bonus (const struct city *pcity, const struct specialist *pspecialist, const struct output_type *poutput, enum effect_type effect_type)
 Returns the effect bonus of a specialist in a city. More...
 
int get_city_tile_output_bonus (const struct city *pcity, const struct tile *ptile, const struct output_type *poutput, enum effect_type effect_type)
 Returns the effect bonus at a city tile. More...
 
int get_tile_output_bonus (const struct city *pcity, const struct tile *ptile, const struct output_type *poutput, enum effect_type effect_type)
 Returns the effect bonus at a tile for given output type (or nullptr for output-type-independent bonus). More...
 
int get_player_output_bonus (const struct player *pplayer, const struct output_type *poutput, enum effect_type effect_type)
 Returns the player effect bonus of an output. More...
 
int get_player_intel_bonus (const struct player *pplayer, const struct player *pother, enum national_intelligence nintel, enum effect_type effect_type)
 Gets the player effect bonus of a national intelligence. More...
 
int get_city_output_bonus (const struct city *pcity, const struct output_type *poutput, enum effect_type effect_type)
 Returns the player effect bonus of an output. More...
 
int get_building_bonus (const struct city *pcity, const struct impr_type *building, enum effect_type effect_type)
 Returns the effect bonus at a building. More...
 
int get_unittype_bonus (const struct player *pplayer, const struct tile *ptile, const struct unit_type *punittype, enum effect_type effect_type, enum vision_layer vision_layer)
 Returns the effect bonus that applies at a tile for a given unittype. More...
 
int get_unit_bonus (const struct unit *punit, enum effect_type effect_type)
 Returns the effect bonus at a unit. More...
 
int get_player_bonus_effects (struct effect_list *plist, const struct player *pplayer, enum effect_type effect_type)
 Returns the effect sources of this type currently active at the player. More...
 
int get_city_bonus_effects (struct effect_list *plist, const struct city *pcity, const struct output_type *poutput, enum effect_type effect_type)
 Returns the effect sources of this type currently active at the city. More...
 
int get_current_construction_bonus (const struct city *pcity, enum effect_type effect_type, const enum req_problem_type prob_type)
 Returns the effect bonus the currently-in-construction-item will provide. More...
 
int get_potential_improvement_bonus (const struct impr_type *pimprove, const struct city *pcity, enum effect_type effect_type, const enum req_problem_type prob_type)
 Returns the effect bonus the improvement would or does provide if present. More...
 
void get_effect_req_text (const struct effect *peffect, char *buf, size_t buf_len)
 Make user-friendly text for the source. More...
 
QString get_effect_list_req_text (const struct effect_list *plist)
 Make user-friendly text for an effect list. More...
 
QString effect_type_unit_text (effect_type type, int value)
 Returns a string describing an effect value as interpreted in the context of an effect_type, typically as "value [unit]" for some unit. More...
 
bool iterate_effect_cache (iec_cb cb, void *data)
 Iterate through all the effects in cache, and call callback for each. More...
 

Variables

static bool initialized = false
 
struct {
   struct effect_list *   tracker
 
   struct effect_list *   effects [EFT_COUNT]
 
   struct {
      struct effect_list *   buildings [B_LAST]
 
      struct effect_list *   govs [G_LAST]
 
      struct effect_list *   advances [A_LAST]
 
   }   reqs
 
ruleset_cache
 The code creates a ruleset cache on ruleset load. More...
 

Function Documentation

◆ building_has_effect()

bool building_has_effect ( const struct impr_type pimprove,
enum effect_type effect_type effect_type   
)

Returns TRUE if the building has any effect bonuses of the given type.

Note that this function returns a boolean rather than an integer value giving the exact bonus. Finding the exact bonus requires knowing the effect range and may take longer. This function should only be used in situations where the range doesn't matter.

Definition at line 504 of file effects.cpp.

Referenced by building_crucial(), can_player_build_improvement_direct(), helptext_building(), try_to_sell_stuff(), and valid_improvement().

◆ effect_copy()

struct effect* effect_copy ( struct effect old)

Return new copy of the effect.

Definition at line 186 of file effects.cpp.

Referenced by effect_handle_split_universal().

◆ effect_cumulative_max()

int effect_cumulative_max ( enum effect_type  type,
struct universal for_uni 
)

Get the maximum effect value in this ruleset for the universal (that is, the sum of all positive effects clauses that apply specifically to this universal – this can be an overestimate in the case of mutually exclusive effects).

for_uni can be nullptr to get max effect value ignoring requirements.

Definition at line 307 of file effects.cpp.

Referenced by helptext_unit(), rs_common_units(), rs_max_city_radius_sq(), and sanity_check_boolean_effects().

◆ effect_cumulative_min()

int effect_cumulative_min ( enum effect_type  type,
struct universal for_uni 
)

Get the minimum effect value in this ruleset for the universal (that is, the sum of all negative effects clauses that apply specifically to this universal – this can be an overestimate in the case of mutually exclusive effects).

for_uni can be nullptr to get min effect value ignoring requirements.

Definition at line 336 of file effects.cpp.

Referenced by sanity_check_boolean_effects().

◆ effect_new()

struct effect* effect_new ( enum effect_type  type,
int  value,
struct multiplier pmul 
)

◆ effect_req_append()

◆ effect_type_unit_text()

QString effect_type_unit_text ( effect_type  type,
int  value 
)

Returns a string describing an effect value as interpreted in the context of an effect_type, typically as "value [unit]" for some unit.

Definition at line 1058 of file effects.cpp.

Referenced by boot_help_texts().

◆ effect_value_from_universals()

int effect_value_from_universals ( enum effect_type  type,
struct universal unis,
size_t  n_unis 
)

Return the base value of a given effect that can always be expected from just the sources in the list, independent of other factors.

Adds up all the effects that rely only on these universals; effects that have extra conditions are ignored. In effect, 'unis' is a template against which effects are matched. The first universal in the list is special: effects must have a condition that specifically applies to that source to be included (may be a superset requirement, e.g. ExtraFlag for VUT_EXTRA source).

Definition at line 368 of file effects.cpp.

Referenced by extra_bonus_for_terrain(), and helptext_unit().

◆ get_building_bonus()

int get_building_bonus ( const struct city pcity,
const struct impr_type building,
enum effect_type effect_type effect_type   
)

Returns the effect bonus at a building.

Definition at line 819 of file effects.cpp.

Referenced by city_improvement_upkeep(), impr_build_shield_cost(), impr_buy_gold_cost(), and initialize_globals().

◆ get_city_bonus()

int get_city_bonus ( const struct city pcity,
enum effect_type effect_type effect_type  ,
enum vision_layer  vlayer 
)

◆ get_city_bonus_effects()

int get_city_bonus_effects ( struct effect_list *  plist,
const struct city pcity,
const struct output_type poutput,
enum effect_type effect_type effect_type   
)

Returns the effect sources of this type currently active at the city.

The returned vector must be freed (building_vector_free) when the caller is done with it.

Definition at line 909 of file effects.cpp.

Referenced by get_city_dialog_culture_text(), get_city_dialog_illness_text(), and get_city_dialog_output_text().

◆ get_city_output_bonus()

int get_city_output_bonus ( const struct city pcity,
const struct output_type poutput,
enum effect_type effect_type effect_type   
)

Returns the player effect bonus of an output.

Definition at line 800 of file effects.cpp.

Referenced by city_units_upkeep(), city_waste(), and cm_state_init().

◆ get_city_specialist_output_bonus()

int get_city_specialist_output_bonus ( const struct city pcity,
const struct specialist pspecialist,
const struct output_type poutput,
enum effect_type effect_type effect_type   
)

Returns the effect bonus of a specialist in a city.

Definition at line 703 of file effects.cpp.

Referenced by get_specialist_output().

◆ get_city_tile_output_bonus()

int get_city_tile_output_bonus ( const struct city pcity,
const struct tile ptile,
const struct output_type poutput,
enum effect_type effect_type effect_type   
)

Returns the effect bonus at a city tile.

pcity must be supplied.

FIXME: this is now used both for tile bonuses, tile-output bonuses, and city-output bonuses. Thus ptile or poutput may be nullptr for certain callers. This could be changed by adding 2 new functions to the interface but they'd be almost identical and their likely names would conflict with functions already in city.c. It's also very similar to get_tile_output_bonus(); it should be called when the city is mandatory.

Definition at line 728 of file effects.cpp.

Referenced by base_city_can_work_tile(), and get_final_city_output_bonus().

◆ get_current_construction_bonus()

int get_current_construction_bonus ( const struct city pcity,
enum effect_type effect_type effect_type  ,
const enum req_problem_type  prob_type 
)

Returns the effect bonus the currently-in-construction-item will provide.

Note this is not called get_current_production_bonus because that would be confused with EFT_PROD_BONUS.

Problem type tells if we need to be CERTAIN about bonus before counting it or is POSSIBLE bonus enough.

Definition at line 933 of file effects.cpp.

Referenced by city_build_building(), city_increase_size(), and city_turn_notify().

◆ get_effect_list_req_text()

QString get_effect_list_req_text ( const struct effect_list *  plist)

Make user-friendly text for an effect list.

The text is put into a user astring.

Definition at line 1040 of file effects.cpp.

Referenced by do_tech_parasite_effect().

◆ get_effect_req_text()

void get_effect_req_text ( const struct effect peffect,
char *  buf,
size_t  buf_len 
)

Make user-friendly text for the source.

The text is put into a user buffer.

Definition at line 1011 of file effects.cpp.

Referenced by boot_help_texts(), get_city_dialog_culture_text(), get_city_dialog_illness_text(), get_city_dialog_output_text(), and get_effect_list_req_text().

◆ get_effects() [1/2]

◆ get_effects() [2/2]

struct effect_list* get_effects ( enum effect_type effect_type  effect_type)

Get a list of effects of this type.

Definition at line 122 of file effects.cpp.

◆ get_player_bonus()

◆ get_player_bonus_effects()

int get_player_bonus_effects ( struct effect_list *  plist,
const struct player pplayer,
enum effect_type effect_type effect_type   
)

Returns the effect sources of this type currently active at the player.

The returned vector must be freed (building_vector_free) when the caller is done with it.

Definition at line 889 of file effects.cpp.

Referenced by do_tech_parasite_effect().

◆ get_player_intel_bonus()

int get_player_intel_bonus ( const struct player pplayer,
const struct player pother,
enum national_intelligence  nintel,
enum effect_type effect_type effect_type   
)

Gets the player effect bonus of a national intelligence.

Definition at line 779 of file effects.cpp.

Referenced by package_player_diplstate(), package_player_info(), and send_research_info().

◆ get_player_output_bonus()

int get_player_output_bonus ( const struct player pplayer,
const struct output_type poutput,
enum effect_type effect_type effect_type   
)

Returns the player effect bonus of an output.

Definition at line 760 of file effects.cpp.

Referenced by get_tile_output_text(), and utype_upkeep_cost().

◆ get_potential_improvement_bonus()

int get_potential_improvement_bonus ( const struct impr_type pimprove,
const struct city pcity,
enum effect_type effect_type effect_type  ,
const enum req_problem_type  prob_type 
)

Returns the effect bonus the improvement would or does provide if present.

Problem type tells if we need to be CERTAIN about bonus before counting it or is POSSIBLE bonus enough.

Definition at line 954 of file effects.cpp.

Referenced by get_current_construction_bonus(), and improvement_has_effects().

◆ get_req_source_effects()

struct effect_list* get_req_source_effects ( struct universal psource)

Get a list of effects with this requirement source.

Note: currently only buildings and governments are supported.

Definition at line 132 of file effects.cpp.

Referenced by adjust_improvement_wants_by_effects(), adv_data_city_impr_calc(), building_has_effect(), dai_gov_value(), dai_tech_effect_values(), effect_req_append(), get_potential_improvement_bonus(), helptext_government(), improvement_has_effects(), and is_building_replaced().

◆ get_target_bonus_effects()

int get_target_bonus_effects ( struct effect_list *  plist,
const struct player target_player,
const struct player other_player,
const struct city target_city,
const struct impr_type target_building,
const struct tile target_tile,
const struct unit target_unit,
const struct unit_type target_unittype,
const struct output_type target_output,
const struct specialist target_specialist,
const struct action target_action,
enum effect_type effect_type  ,
enum vision_layer vision_layer  ,
enum national_intelligence  nintel 
)

◆ get_tile_output_bonus()

int get_tile_output_bonus ( const struct city pcity,
const struct tile ptile,
const struct output_type poutput,
enum effect_type effect_type effect_type   
)

Returns the effect bonus at a tile for given output type (or nullptr for output-type-independent bonus).

If pcity is supplied, it's the bonus for that particular city, otherwise it's the player/city-independent bonus (and any city on the tile is ignored).

Definition at line 746 of file effects.cpp.

Referenced by city_tile_output().

◆ get_unit_bonus()

int get_unit_bonus ( const struct unit punit,
enum effect_type effect_type effect_type   
)

◆ get_unittype_bonus()

int get_unittype_bonus ( const struct player pplayer,
const struct tile ptile,
const struct unit_type punittype,
enum effect_type effect_type  ,
enum vision_layer vision_layer   
)

Returns the effect bonus that applies at a tile for a given unittype.

For instance with EFT_DEFEND_BONUS the attacker's unittype and the defending tile should be passed in. Slightly counter-intuitive! See doc/README.effects to see how the unittype applies for each effect here.

Definition at line 841 of file effects.cpp.

Referenced by assess_danger_unit(), city_got_defense_effect(), city_production_unit_veteran_level(), dai_choose_defender_versus(), defense_multiplication(), find_nearest_safe_city(), get_modified_firepower(), get_total_attack_power(), get_unit_vision_at(), pft_fill_utype_default_parameter(), unit_type_is_losing_hp(), utype_build_shield_cost(), utype_buy_gold_cost(), utype_move_rate(), and utype_upkeep_cost().

◆ get_world_bonus()

int get_world_bonus ( enum effect_type effect_type effect_type  )

Returns the effect bonus for the whole world.

Definition at line 659 of file effects.cpp.

Referenced by api_effects_world_bonus(), and game_next_year().

◆ is_building_replaced()

bool is_building_replaced ( const struct city pcity,
const struct impr_type pimprove,
const enum req_problem_type  prob_type 
)

Returns TRUE if a building is replaced.

To be replaced, all its effects must be made redundant by groups that it is in. prob_type CERTAIN or POSSIBLE is answer to function name.

Definition at line 566 of file effects.cpp.

Referenced by is_improvement_redundant().

◆ is_effect_prevented()

static bool is_effect_prevented ( const struct player target_player,
const struct player other_player,
const struct city target_city,
const struct impr_type target_building,
const struct tile target_tile,
const struct unit target_unit,
const struct unit_type target_unittype,
const struct output_type target_output,
const struct specialist target_specialist,
const struct effect peffect,
const enum req_problem_type  prob_type 
)
static

Return TRUE iff any of the disabling requirements for this effect are active, which would prevent it from taking effect.

(Assumes that any requirement specified in the ruleset with a negative sense is an impediment.)

Definition at line 535 of file effects.cpp.

Referenced by is_building_replaced().

◆ iterate_effect_cache()

bool iterate_effect_cache ( iec_cb  cb,
void *  data 
)

Iterate through all the effects in cache, and call callback for each.

This is currently not very generic implementation, as we have only one user; ruleset sanity checking. If any callback returns FALSE, there is no further checking and this will return FALSE.

Definition at line 1259 of file effects.cpp.

Referenced by is_multiplier_needed(), is_universal_needed(), effect_edit::refresh(), rscompat_optional_capabilities(), rscompat_postprocess(), sanity_check_ruleset_data(), and save_effects_ruleset().

◆ recv_ruleset_effect()

void recv_ruleset_effect ( const struct packet_ruleset_effect *  packet)

Receives a new effect.

This is called by the client when the packet arrives.

Definition at line 447 of file effects.cpp.

Referenced by handle_ruleset_effect().

◆ ruleset_cache_free()

void ruleset_cache_free ( )

Free the ruleset cache.

This should be called at the end of the game or when the client disconnects from the server. See ruleset_cache_init.

Definition at line 245 of file effects.cpp.

Referenced by game_ruleset_free().

◆ ruleset_cache_init()

void ruleset_cache_init ( )

Initialize the ruleset cache.

The ruleset cache should be empty before this is done (so if it's previously been initialized, it needs to be freed (see ruleset_cache_free) before it can be reused).

Definition at line 219 of file effects.cpp.

Referenced by game_ruleset_init().

◆ send_ruleset_cache()

void send_ruleset_cache ( struct conn_list *  dest)

Send the ruleset cache data over the network.

Definition at line 466 of file effects.cpp.

Referenced by send_rulesets().

Variable Documentation

◆ advances

struct effect_list* advances[A_LAST]

Definition at line 110 of file effects.cpp.

◆ buildings

struct effect_list* buildings[B_LAST]

Definition at line 106 of file effects.cpp.

◆ effects

struct effect_list* effects[EFT_COUNT]

◆ govs

struct effect_list* govs[G_LAST]

Definition at line 108 of file effects.cpp.

◆ initialized

◆ 

◆ 

struct { ... } ruleset_cache

The code creates a ruleset cache on ruleset load.

This constant cache is used to speed up effects queries. After the cache is created it is not modified again (though it may later be freed).

Since the cache is constant, the server only needs to send effects data to the client upon connect. It also means that an AI can do fast searches in the effects space by trying the possible combinations of addition or removal of buildings with the effects it cares about.

To know how much a target is being affected, simply use the convenience functions:

get_player_bonus get_city_bonus get_city_tile_bonus get_building_bonus

These functions require as arguments the target and the effect type to be queried.

Effect sources are unique and at a well known place in the data structures. This allows the above queries to be fast:

  • Look up the possible sources for the effect (O(1) lookup)
  • For each source, find out if it is present (O(1) lookup per source). The first is commonly called the "ruleset cache" and is stored statically in this file. The second is the "sources cache" and is stored all over.

Any type of effect range and "survives" is possible if we have a sources cache for that combination. For instance

  • There is a sources cache of all existing buildings in a city; thus any building effect in a city can have city range.
  • There is a sources cache of all wonders in the world; thus any wonder effect can have world range.
  • There is a sources cache of all wonders for each player; thus any wonder effect can have player range.
  • There is a sources cache of all wonders ever built; thus any wonder effect that survives can have world range. However there is no sources cache for many of the possible sources. For instance non-unique buildings do not have a world-range sources cahce, so you can't have a non-wonder building have a world-ranged effect.

The sources caches could easily be extended by generalizing it to a set of arrays game.buildings[], pplayer->buildings[], pisland->builidngs[], pcity->buildings[] which would store the number of buildings of that type present by game, player, island (continent) or city. This would allow non-surviving effects to come from any building at any range. However to allow surviving effects a second set of arrays would be needed. This should enable basic support for small wonders and satellites.

No matter which sources caches are present, we should always know where to look for a source and so the lookups will always be fast even as the number of possible sources increases. Ruleset cache. The cache is created during ruleset loading and the data is organized to enable fast queries.

Referenced by effect_cumulative_max(), effect_cumulative_min(), effect_new(), get_effects(), get_req_source_effects(), iterate_effect_cache(), ruleset_cache_free(), ruleset_cache_init(), and send_ruleset_cache().

◆ tracker

struct effect_list* tracker

Definition at line 98 of file effects.cpp.