Complete.Org: Mailing Lists: Archives: freeciv-dev: December 2002:
[Freeciv-Dev] Re: (PR#2521) general effects framework
Home

[Freeciv-Dev] Re: (PR#2521) general effects framework

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: kaufman@xxxxxxxxxxxxxxxxxxxxxx
Cc: freeciv-dev@xxxxxxxxxxx
Subject: [Freeciv-Dev] Re: (PR#2521) general effects framework
From: "Raimar Falke via RT" <rt@xxxxxxxxxxxxxx>
Date: Mon, 9 Dec 2002 01:00:18 -0800
Reply-to: rt@xxxxxxxxxxxxxx

On Sun, Dec 08, 2002 at 04:44:48PM -0800, Mike Kaufman via RT wrote:
> 
> Here is the first draft of the first step toward general-improvements.
> This is the initial framework.
> 
> Current situation (for the uninitiated): 
> 
> improvements have certain "effects" defined in data/default/buildings.ruleset 
> that define what they can do when built. Read the ruleset for for specific 
> info. Except for the spaceship parts effect, these "effects" currently do 
> nothing. Everything is hardcoded by building all throughout the codebase.
> 
> There is an access method to theses effects currently, but it is not 
> complete, 
> and after examining it, I have found it lacking and fairly unintelligable.
> 
> What the patch does (tutorial): 
> 
> This patch gives (what I think) is an improved and complete access method to 
> these effects. In a nutshell, each improvement has an "effect definition" 
> that 
> it gets from the ruleset. on startup, these can be found in:
> 
> struct impr_type {
>  ...
>  struct effect_defn_list effect_defs;
>  ...
> }
> 
> When an improvement is built, an effect [struct effect] is created (which 
> has a pointer to the definition) for each effect definition in the list.
> Each effect is then added to an effect list based on the range of its
> definition. 
> The ranges are: "None", "Local", "City", "Island", "Player", and "World". 
> Each range defines where the effect is felt. For example, if the effect 
> has World range, it will be felt by everything (all cities, improvements, 
> units, etc) by all players. If it has City range, it will be felt by 
> everything in the city (or perhaps on the city tiles) where the improvement 
> is built that is creating the effect. Thus effects created by improvements 
> have a "home" (if an effect survives an improvement's destruction, it
> becomes "homeless").
> 
> Once the effect is added, you can check for the effect by iterating though
> the lists of effects. For example, say, you had a spy attempting to
> sabotage a city's city walls. Now two effects that a given city wall have
> are:
> 
> effect          = 
>     { "type",                "range",  "amount", "cond_bldg"
>       "Spy_Resistant", "Local",  50
>       "Spy_Resistant", "Local",  -50,      "Palace"
>     }
> 
> Local in this context means that this effect _only_ matters for this
> improvement. Let's read the definition:
> 
> "Spy_Resistant" - if a spy specifies a target for sabotage,
>                   then she  has an AMOUNT percent chance to fail
>                   (all Spy_Resistant's are summed before being applied)
> 
> Note that the second effect depends on there being a "Palace" in the same
> city as the walls improvement (that's because it [the palace] confers 
> Spy_Resistance of 50% on the entire city that it's in, and we don't want 
> the wall to double the effect...).
> Now to check to see if the Spy fails to sabotage the walls... For
> motivation, let's say she begins with a 25% chance of failure. To apply
> effects, we need to iterate through all the applicable effects, now we need 
> to check for the Spy_Resistant effect in ALL the lists that affect the

> walls. In this case, we need to look at 2. the Local list (that the

I counted 5.

> improvement has (actually stored as pcity->impr_effects[B_CITY]), the City
> list where the walls are located (pcity->effects), the Island list (on
> which that city is located
> (pplayer->island_effects[map_get_continent(pcity->x, pcity->y)]), the
> Player list for the player who owns the city and its improvement
> (pplayer->effects), and finally the World list (game->effects). Each of
> these lists could possibly have an effect which confers Spy_Resistant.
> 
> Instead of going though each one by hand, fortunately we have an iterator
> function which helps us:
> 
> void effect_iterator_init(struct effect_iter *iter, unsigned int ranges,
>                           struct player *pplayer, struct city *pcity,
>                           int id, enum effect_type type);
> 
> which describes the kind of search to do and:
> 
> struct effect *effect_iterator_get_next_active(struct effect_iter *iter);

Can you also provide a "normal" iterate macro?

> which returns an (active) matching effect.
> 
>   struct effect_iter iter;
>   struct effect *eff;
>   int failure_chance = 25;
>   
>   effect_iterator_init(&iter, EFR_LAST, pplayer, pcity, 
>                        walls_impr_id, EFT_SPY_RESISTANT);
>   while( (eff = effect_iterator_get_next_active(&iter)) ) {
>     failure_chance += eff->defn->amount;
>   }
>  
> my, wasn't that nice? A word on the init function the range EFR_LAST is a
> synonym for iterate through all applicable ranges (as defined by pplayer,
> pcity, and walls_impr_id). If you needed just the World and Island ranges
> for some reason, you would do:
> 
>   effect_iterator_init(&iter, EFR_WORLD|EFR_ISLAND, pplayer, pcity,
>                        walls_impr_id, EFT_SPY_RESISTANT);
> 
> so ranges can be ORed together. If you needed to look for all active
> effects, use EFT_LAST instead of EFT_SPY_RESISTANT.

There should a EFR_ALL. Same for EFT_ALL.

> What else the patch does (the bonus):
> 
> Improvements aren't the only things that can have effects. Nations,
> governments and techs can also have effects (any effects from these must
> be World or Player ranged). Note: non-improvements effects are known to be
> buggy in this version. Beware. Also easily extensible from this framework
> are unit effects (which will be restricted to Local ranged effects).
> 
> What the patch doesn't do (the downside):
> 
> With the exception of the spaceship parts, this patch really does nothing
> yet. Adding zany effects to buildings will do nothing to gameplay. This is
> the framework patch. But as you can see from the above example, it ain't
> hard to actually to the next step.
> 
> Oh, and island effects are not implemented yet. So don't specify anything
> as Island ranged. This is the result of a bit of disagreement as to how to
> proceed with regard to who defines an island.
> 
> There is a lot of debugging information (to be removed when it's committed)
> that will help you see that effects are actually getting added and removed.
> 
> do ser -d 4:effects.c to see it.

While the user documentation is good I miss some developer
documentation. Example: what is an immediate effect and why it is so
special? What is so special about "is effect active except for
cond_bldg" that you create a special condition "pending" for
this. What is EFR_NONE used for?

Why are there no real types in struct effect_defn cond_*.

effects_update_all has an almost unbound while loop. Looks like it
won't return if the giver gives the right input?!

And last but not least: you add 1k lines of code. And you need another
1-5k to make use of all this. How good does the result perform? How
long will effects_update_all take. How much time will an city_update
need?

        Raimar

-- 
 email: rf13@xxxxxxxxxxxxxxxxx
 "Like the ad says, at 300 dpi you can tell she's wearing a
  swimsuit. At 600 dpi you can tell it's wet. At 1200 dpi you
  can tell it's painted on. I suppose at 2400 dpi you can tell
  if the paint is giving her a rash."
    -- Joshua R. Poulson




[Prev in Thread] Current Thread [Next in Thread]