[Freeciv-Dev] Re: (PR#2521) general effects framework
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
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
- [Freeciv-Dev] (PR#2521) general effects framework, Mike Kaufman via RT, 2002/12/08
- Message not available
- [Freeciv-Dev] Re: (PR#2521) general effects framework,
Raimar Falke via RT <=
- [Freeciv-Dev] Re: (PR#2521) general effects framework, Mike Kaufman via RT, 2002/12/09
- [Freeciv-Dev] Re: (PR#2521) general effects framework, Ben Webb via RT, 2002/12/09
- [Freeciv-Dev] Re: (PR#2521) general effects framework, Raimar Falke via RT, 2002/12/09
- [Freeciv-Dev] Re: (PR#2521) general effects framework, Ben Webb via RT, 2002/12/09
- [Freeciv-Dev] Re: (PR#2521) general effects framework, Mike Kaufman via RT, 2002/12/09
- [Freeciv-Dev] Re: (PR#2521) general effects framework, Raimar Falke via RT, 2002/12/09
- [Freeciv-Dev] Re: (PR#2521) general effects framework, Mike Kaufman via RT, 2002/12/09
- [Freeciv-Dev] Re: (PR#2521) general effects framework, Raimar Falke via RT, 2002/12/09
- [Freeciv-Dev] Re: (PR#2521) general effects framework, Mike Kaufman via RT, 2002/12/09
- [Freeciv-Dev] Re: (PR#2521) general effects framework, Raimar Falke via RT, 2002/12/10
|
|