How can I iterate over the combined parties that are attached to a given center?

Users who are viewing this thread

Mordachai

Squire
I want to improve the script_center_get_food_consumption.

Currently, it stupid and always claims 50 for castles, and 500 for towns.

In order to compute a real food consumption rate, I'd like to see how many actual troops are garrisoned and otherwise there ready to defend the location.

So, if there are 300 troops, then maybe it consumes 600 units of food, and if there are 100 troops, then 200 food, etc..

I can see in game menus that I often have access to p_collective_enemy.  But I'm not quite sure if I can just use:

(party_collect_attachments_to_party, ":center_no", "p_collective_enemy"),

... or am I being an idiot, and I don't need to place anything in p_collective_enemy, but can directly use:

(party_get_num_companions, ":military", ":center_no"),

Is that the way, or is there a better way?
 
you dont need to use that party enemy thing, I don't think it would work in this case anyway, but the basic command is fine.

If you want to do it for all parties, do a try_for_parties or try_for_range, with the proper is_between, etc and then the "party_collect_etc for ":cur_center"

The only thing is that I don't know if this will return the nr of attached parties or actual total troops.

So what you might have to do instead is go through all parties, (try_for_parties, ":cur_party") and then use (party_get_attached_to, ":cur_attached", ":cur_party"), (eq, ":cur_attached", ":cur_center")

Then if that returns true, you count the number of troops in that party, add the number of troops in the center itself and voila..


However on a more general note, there is a flaw in this logic. If I bring my party into a town, the owner of that town is hardly going to pay for my food.
So if you're going to go this route, imo you should also factor in the cost of the food for that party, deduct that money from the owner of the party and add it to the town wealth.
 
During a siege the castle or town owner has no choice but to "pay" for anyone there's food.  Really, they're all eating out of whatever reserves the center laid in ahead of the siege.:smile:

I ended up being satisfied (so far) with just (party_get_num_companions, ":military", ":center_no"), - that seems to work (though I really need to double check that it includes attached parties and not just the garrison).

If it doesn't, I'll go your route and iterate all parties in the game, and look for whether they're in that location or not...
 
yeah I originally put the party_get_num_companions in there but then I took it out again since I wasn't sure if it would count the other stacks that are 'in' that party or not.

Cause the whole 'get attached' thing is a little pointless if stacks of parties not belonging to that town are also counted, plus also, there would be no way to count actual town troops separate from 'outsider' troops if it did work. So my guess would be that it doesn't, but I could be wrong, haven't really delved into the stacked parties thing a lot.
 
It is not necessary to iterate all parties
just use party_get_num_attached_parties and party_get_attached_party_with_rank like

Code:
          (party_get_num_attached_parties, ":num_attached_parties",  ":party_id"),
          (try_for_range, ":attached_party_rank", 0, ":num_attached_parties"),
            (party_get_attached_party_with_rank, ":attached_party", ":party_id", ":attached_party_rank"),
     ...
          (try_end),
 
It's worth it to go through the encounter setup code if you're in that area already.  There's a lot of code there that does a mess of calculations and sets up a ton of globals. 

Another thing to note is that some of the game intrinsic functions/scripts take into account attachments but others don't.  For instance, inflict_casualties_to_party_group does but the strength calculation script does not.  So while you can autoresolve a fight with multiple stacks defending a city, the defenders only actually take into account the city garrison even though damage will be distributed to all defending parties.  Other calculations likely make the same mistake which can lead to unexpected results.  (Sorry for the derail, but I spent a good long while last weekend trying to figure this stuff out which might be useful to someone along the line  :mrgreen:)
 
No - not derailed at all!  Much appreciated. :smile:

For my purpose (initially), I just need to know how many real troops are there in order to give a more accurate account of how  much food they eat during a siege - so that sieges force them to run out of food at a rate proportional to the actual folks consuming said food.

But looking into bug-fixing these other locations sounds like a fine idea!
 
kt0 said:
So while you can autoresolve a fight with multiple stacks defending a city, the defenders only actually take into account the city garrison even though damage will be distributed to all defending parties...
Mmm, I think you're wrong. Lets take a look on script_game_event_simulate_battle.
It has this part,
Code:
(party_collect_attachments_to_party, ":root_defender_party", "p_collective_ally"),
(party_collect_attachments_to_party, ":root_attacker_party", "p_collective_enemy"),
where all attachemnts are gathered into p_collective_ally and p_collective_enemy parties, which are used for strength calculations here:
Code:
(call_script, "script_party_calculate_strength", "p_collective_ally", 0),
(assign, ":defender_strength", reg0),
(call_script, "script_party_calculate_strength", "p_collective_enemy", 0),
(assign, ":attacker_strength", reg0),

So, all parties are taken into account.
 
And the above tells me that I really need to do the same for my food script .... actually gather all of the parties into a combined party (or iterate over them) in order to get accurate results.

Thanks :cool:
 
ConstantA said:
Mmm, I think you're wrong. Lets take a look on script_game_event_simulate_battle.

...

So, all parties are taken into account.
Yes, and you would be correct if game_event_simulate_battle was actually the script used to autoresolve attacking a castle :wink:

Try castle_attack_walls_simulate.  I'm fairly certain it is incorrect but kudos for your skepticism :smile:
If you find out otherwise, please let me know.  I've tested that script pretty thoroughly and if I've made a mistake, I'd like to know where it is. 
 
Yes, kt0, looks like castle_attack_walls_simulate uses only one defending party to calculate defenders stength...

And I must say, it's a mess. I'll need a day or two to understand why in one case script_collect_friendly_parties is used, but in the other - party_collect_attachments_to_party. Any ideas?
 
script_collect_friendly_parties actually calls party_collect_attachments_to_party so in effect, they're both calling party_collect_attachments_to_party.  As far as I can tell, script_collect_friendly_parties is what sets up p_collective_friends and does extra work for $g_ally_party.  It doesn't look like script_collect_friendly_parties is called during encounter init but I'm not sure why. 

To answer your question, one would use script_collect_friendly_parties and another only use party_collect_attachments_to_party if the first cared about allies and the second didn't.  There's probably more to it than that, but that's all I got right now.
 
It doesn't look like script_collect_friendly_parties is called during encounter init but I'm not sure why.
Ok, let's see...
I meet a sieging party.
script_game_event_party_encounter fires, and it jumps us to mnu_join_siege_outside.
If I wish to join the siege, jump to mnu_besiegers_camp_with_allies. There, the script_encounter_calculate_fit is called, which fills the p_collective_ally and p_collective_enemy parties. Then another script, script_encounter_init_variables fires, which uses p_collective_friends. But the script_collect_friendly_parties which fills it, is called long after that part - in castle_attack_walls_(simulate|with_allies_simulate).

What gives?
Or am I missing something?
 
collect_friendly_parties calls the intrinsic party_collect_attachments_to_party on p_main_party which fills out p_collective friends.  collect_friendly_parties is called from encounter_calculate_fit which .  So the call trace looks like this:
- mnu_besiegers_camp_with_allies
  - script_encounter_calculate_fit
      - script_collect_friendly_parties
        - (party_collect_attachments_to_party("p_main_party", "p_collective_friends")),
...
  - script_encounter_init_variables
      - script_encounter_calculate_fit
        - script_collect_friendly_parties
          - (party_collect_attachments_to_party("p_main_party", "p_collective_friends")),
    ...
    - (call_script, "script_party_copy", "p_collective_friends_backup", "p_collective_friends")

The last line of which is what I gather you're asking about.  Does that answer your question?  In this particular case both calls to script_encounter_calculate_fit are necessary since script_encounter_init_variables is only called at the very start of the fight, and we might (through menus) be back here again after a set of other actions (I think).  Later on for autoresolving, we'll call castle_attack_walls_with_allies_simulate.

There are, in fact, six (!) solvers that I've found which has led me to much consternation:
- game_event_simulate_battle for non-player fights (that only actually resolve in the daytime)
- castle_attack_walls_simulate for the player attacking a fortress
- castle_attack_walls_with_allies_simulate for helping a friendly party attack a fortress
- join_order_attack for telling your troops to go on ahead and help a buddy out (non-siege)
- siege_join_defense for helping a friendly defend a fortress
- order_attack_2 for the player autoresolving a non-siege by themselves

There may be more.  Those are the ones I've found and they're all subtly different, mostly in the way they handle damage, parties, strengths, and the like. 

It's a rats' nest if ever there was one.  For me, it is uber bothersome that a method named "calculate_something_or_other" has a side-effect.  I really expect a function that calculates or counts something to just do their maths and return (and ideally be marked as const if that were possible); not file away stuff for later use in a way I'm likely to break while I'm hacking around.  Let the caller file stuff away.  It makes for some very confusing code.  The net often has to be cast pretty wide to catch all the appropriate side effects for this stuff, though, I think we're wading into the deepest part of it.

I dunno if that's at all helpful.  I'm not all here this morning so there's likely logical errors above.
 
Back
Top Bottom