As Always, a Few Questions (New Post Pg. 2)

正在查看此主题的用户

Stonewall382

Knight at Arms
Allo, I've a few questions.

1)  Is it possible to execute a return in Python?  I'm setting slots for a bunch of different castles, and the only way I can do it right now is by setting the value and then executing everything, then changing the value, and copy-pasting all the code again.  I want to just assign the variable "$castle" (as you'll see below) to the next castle in the line, and return to the beginning of the operation--thereby making the code a lot more efficient.  Here's the code I'm using:

插入代码块:
(24, 72, 0), [],
               [(try_begin),
                (assign,"$castle","p_castle1"),# We're dealing with Culmarr's Level 1 Buildings now
                (try_begin),# Begins the operation with the woodcutter
                (party_get_slot,"$building","$castle",200),# We're dealing with the woodcutter here
                (party_get_slot,reg(16),"$castle",499),# Extracting the number of building crews--we subtract one in the dialog if the player decides to build the building
                (eq,"$building",1),#  Checks to see if construction has begun (in the dialog with the NPC)
                (party_set_slot,"$castle","$building",2),# When the building's slot is 1, it's being built.  When it's completed, the slot is changed to 2.
                (val_add,reg(16),1),# We return the building crew to be used again, then reset the slot with the correct value
                (party_set_slot,"$castle",499,reg(16)),# This is where we actually reset the slot with the correct value
                (try_end),# Ends the operation with the woodcutter
                (try_begin),
                (party_get_slot,"$building","$castle",201),
                (party_get_slot,reg(16),"$castle",499),
                (eq,"$building",1),
                (party_set_slot,"$castle","$building",2),
                (val_add,reg(16),1),
                (party_set_slot,"$castle",499,reg(16)),
                (try_end),
                (try_end),
(Shortened for "readibility")

2)  How many slots does a party have?  I thought Winter said once that they only have 500, but I'm not sure.  I'd like to know, so that I can plan how I'm going to use them all.
Thank you to anyone who responds.:smile:
 
Not sure if I fully understand your problem, but seems like all you need to do is to bunch together all the castles in module_parties, and enclose your script in the(try_for_range, reg(x), "$first_castle", "$last_castle") block.
 
Manitas is right. Also, you can make subroutines using scripts.py. Call them using call_script.
 
You need to make sure not to use so many slots.

People here go nuts trying to use registers right and left even though it barely saves anything, but the slots are a big problem when you use them that way.

If you declare slot 500, then every single party will then have 500 slots, ie 500 variables.  So, keep the numbers low.  I use the same slots for multiple purposes, depending what sort of party it is.  No reason not to.

As to first part, define a constant for the beginning and end of all your castles and then use a try_for_range that iterates over that range and executes the code for each one, as manitas said.
 
What the code is supposed to do is this:
For each castle, you can build buildings when you talk to your construction manager at the castle.  However, I don't want the building to be built immediately, so I have a trigger run through and check each castle's (I want to have 25) slots to see if any buildings have been started (when you talk to the manager, he sets the slot to 1.  The trigger sets it to 2, which means that it has been built.).  Right now, I have the code set up just for Culmarr Castle (p_castle_1).  The slots for buildings are the same for every castle.  So, I want to be able to have the trigger start at the top again, next with Radoghir Castle, then with p_castle_3, and so on, but I don't want to have to copy & paste the code in the triggers file, because that's messy.  So, I wanted to be able to, at the end of the try_ statement, just return to the top, change the castle to the next one down the line, and continue on.
However, I think that if I use the 'try_for_range' operation, then at the end of the try_begin statement (the one that checks if the buildings have been started), just add one to the register, and start again, it should do what I want.
So, thank you for your suggestions.

@  fisheye--By subroutines, do you mean something like 'party_set_slot,"p_castle_1",100,reg(42),'--is that what you mean?  Not quite sure I understand.

@  bryce--
People here go nuts trying to use registers right and left even though it barely saves anything
What's the alternative?  Variables?  Using registers saves code, or what?
Also--a)  So I can have as many slots per party as I want?, and b)  What's bad about having 500 slots?  Is it taxing on the system?  Or just inefficient coding?
 
bryce777 说:
You need to make sure not to use so many slots.

People here go nuts trying to use registers right and left even though it barely saves anything, but the slots are a big problem when you use them that way.

If you declare slot 500, then every single party will then have 500 slots, ie 500 variables.

Untruth. As near as I can determine, every slot-capable entry -- parties, troops, scenes and party templates (in the next version) -- has 256 slots, and no more. If you try to use slots with very high numbers, the values will simply not get stored.

Significantly,
Winter
 
Winter 说:
bryce777 说:
You need to make sure not to use so many slots.

People here go nuts trying to use registers right and left even though it barely saves anything, but the slots are a big problem when you use them that way.

If you declare slot 500, then every single party will then have 500 slots, ie 500 variables.

Untruth. As near as I can determine, every slot-capable entry -- parties, troops, scenes and party templates (in the next version) -- has 256 slots, and no more. If you try to use slots with very high numbers, the values will simply not get stored.

Significantly,
Winter

Hmm, that is what armagan says in the docs but I am not too surprised to learn differently.  Maybe the 10000 number was wrong but the other part may be correct.


@stonewall - what I do is just use variables.  If it is a throway value I just use "$temp" "$temp2" etc.  I only use registers when I have to display something in a string using a register.
 
Don't worry, it isn't as much code as you think--a lot of it is repeated.  The code I'm using now is at the bottom.


Winter 说:
bryce777 说:
You need to make sure not to use so many slots.

People here go nuts trying to use registers right and left even though it barely saves anything, but the slots are a big problem when you use them that way.

If you declare slot 500, then every single party will then have 500 slots, ie 500 variables.

Untruth. As near as I can determine, every slot-capable entry -- parties, troops, scenes and party templates (in the next version) -- has 256 slots, and no more. If you try to use slots with very high numbers, the values will simply not get stored.

Significantly,
Winter

Damnation.  Need to consolidate, then.  Thank you though.

@ bryce--Yep, you're right.  I've started replacing a lot of the registers I use time and again with descriptive variables.  Thanks for the tip.:wink:

I tried the try_for_range thing now.  The code now looks like this:
插入代码块:
(ti_once, 0, 0, [], [(try_for_range,reg(12),"p_castle_1","p_castle_25")],
   
  (24, 72, 0), [],
               [(assign,"$castle",reg(12)),
                (try_begin),# Begins the operation with the woodcutter
                (party_get_slot,"$building","$castle",200),# We're dealing with the woodcutter here
                (party_get_slot,reg(16),"$castle",499),# Extracting the number of building crews--we subtract one in the dialog if the player decides to build the building
                (eq,"$building",1),#  Checks to see if construction has begun (in the dialog with the NPC)
                (party_set_slot,"$castle","$building",2),# When the building's slot is 1, it's being built.  When it's completed, the slot is changed to 2.
                (val_add,reg(16),1),# We return the building crew to be used again, then reset the slot with the correct value
                (party_set_slot,"$castle",499,reg(16)),# This is where we actually reset the slot with the correct value
                (try_end),# Ends the operation with the woodcutter
...
(val_add,reg(12),1)

So what I think it should do now is, try_for_range will select a castle from the list of possible castles (1 through 25) as a starting point.  After that, it never fires again.  Then, the trigger picks up starts off.  It reads all the slot values for that particular castle.  Once it's done, it adds one to the ... ****.  That won't work.  I need to make it advance to the next castle in the line.  All I have it doing is adding 1 to the value of p_castle_whatever.  Anyone know how to make it advance to the next castle in the line?




Edit:  Alright, I found a workaround (I think).
插入代码块:
  (1, 72, 0), [],
               [(try_begin),
                    (lt,reg(12),25),# If the castle number is 24 or less, we add 1 to get to the next castle.
                    (val_add,reg(12),1),
                (else_try),# If the castle is not 24 or less, it must be 25, in which case we now reset it to 1.
                    (assign,reg(12),1),
                (try_end),
                (try_begin),
                    (eq,reg(12),1),
                    (assign,"$castle","p_castle_1"),
                (else_try),
                (try_begin),
                    (eq,reg(12),2),
                    (assign,"$castle","p_castle_2"),
...
[code]
                (try_begin),# Begins the operation with the woodcutter
                    (party_get_slot,"$building","$castle",200),# We're dealing with the woodcutter here
                    (party_get_slot,reg(16),"$castle",499),# Extracting the number of building crews--we subtract one in the dialog if the player decides to build the building
                    (eq,"$building",1),#  Checks to see if construction has begun (in the dialog with the NPC)
                    (party_set_slot,"$castle","$building",2),# When the building's slot is 1, it's being built.  When it's completed, the slot is changed to 2.
                    (val_add,reg(16),1),# We return the building crew to be used again, then reset the slot with the correct value
                    (party_set_slot,"$castle",499,reg(16)),# This is where we actually reset the slot with the correct value
                (try_end),# Ends the operation with the woodcutter
                (try_begin),
                    (party_get_slot,"$building","$castle",201),
                    (party_get_slot,reg(16),"$castle",499),
                    (eq,"$building",1),
                    (party_set_slot,"$castle","$building",2),
                    (val_add,reg(16),1),
                    (party_set_slot,"$castle",499,reg(16)),
                (try_end),
Does that look like a) it will work and b) it's the best workaround?[/code]
 
Stonewall382 说:
(ti_once, 0, 0, [], [],
   
  (24, 72, 0), [(try_for_range,reg(12),"p_castle_1","p_castle_25")],
               [(try_for_range,reg(12),"p_castle_1","p_castle_end")
                  (assign,"$castle",reg(12)),
                  (try_begin),# Begins the operation with the woodcutter               
                  (party_get_slot,"$building","$castle",200),# We're dealing with the woodcutter here
                  (party_get_slot,reg(16),"$castle",499),# Extracting the number of building crews--we subtract one in the dialog if the player decides   to build the building
                  (eq,"$building",1),#  Checks to see if construction has begun (in the dialog with the NPC)
                  (party_set_slot,"$castle","$building",2),# When the building's slot is 1, it's being built.  When it's completed, the slot is changed to 2.
                  (val_add,reg(16),1),# We return the building crew to be used again, then reset the slot with the correct value
                  (party_set_slot,"$castle",499,reg(16)),# This is where we actually reset the slot with the correct value
                (try_end),# Ends the try_for_range loop.
(val_add,reg(12),1)

Instead of p_castle_end you can just put whatever party is AFTER p_castle_25.

try_for_range is what programmers call a FOR loop. The statements enclosed between try_for_range and try_end are executed once for each value from p_castle_1 to p_castle_end-1. Reg(12) keeps track of the value.

 
Heh, alright.  That should work better than my workaround.  I wasn't sure if try_for_range went through every value or not.  Thank you.
However, I've a question:
why do you delete the try_begin part there?  I need that for each individual slot value.  The code really looks more like this:
插入代码块:
(try_begin),# Begins the operation with the woodcutter
                    (party_get_slot,"$building","$castle",200),# We're dealing with the woodcutter here
                    (party_get_slot,reg(16),"$castle",499),# Extracting the number of building crews--we subtract one in the dialog if the player decides to build the building
                    (eq,"$building",1),#  Checks to see if construction has begun (in the dialog with the NPC)
                    (party_set_slot,"$castle","$building",2),# When the building's slot is 1, it's being built.  When it's completed, the slot is changed to 2.
                    (val_add,reg(16),1),# We return the building crew to be used again, then reset the slot with the correct value
                    (party_set_slot,"$castle",499,reg(16)),# This is where we actually reset the slot with the correct value
                (try_end),# Ends the operation with the woodcutter
                (try_begin),
                    (party_get_slot,"$building","$castle",201),
                    (party_get_slot,reg(16),"$castle",499),
                    (eq,"$building",1),
                    (party_set_slot,"$castle","$building",2),
                    (val_add,reg(16),1),
                    (party_set_slot,"$castle",499,reg(16)),
                (try_end),
                (try_begin),
                    (party_get_slot,"$building","$castle",202),
                    (party_get_slot,reg(16),"$castle",499),
                    (eq,"$building",1),
                    (party_set_slot,"$castle","$building",2),
                    (val_add,reg(16),1),
                    (party_set_slot,"$castle",499,reg(16)),
                (try_end),
                (try_begin),
                    (party_get_slot,"$building","$castle",203),
                    (party_get_slot,reg(16),"$castle",499),
                    (eq,"$building",1),
                    (party_set_slot,"$castle","$building",2),
                    (val_add,reg(16),1),
                    (party_set_slot,"$castle",499,reg(16)),
                (try_end),
                (try_begin),
                    (party_get_slot,"$building","$castle",204),
                    (party_get_slot,reg(16),"$castle",499),
                    (eq,"$building",1),
                    (party_set_slot,"$castle","$building",2),
                    (val_add,reg(16),1),
                    (party_set_slot,"$castle",499,reg(16)),
                (try_end),
It's the same thing over and over, except that the slot goes up by one.  Ah, could I use try_for_range for that too somehow?

On a side note, I'm taking a programming class this semester (...and every semester to come, as I changed my major to software engineering), and I'm learning about loops in C++ now.  It's cool to actually know what the names are for the things I've been using in these scripts, and to see how best to use them.

Again, thanks for taking the time out to answer my questions.
 
I see. In that case KEEP the try_begin that I struck out, and ADD an EXTRA try_end at the end of the block to mark the end of the try_for_range loop.

P.S. If you keep going in that programming course you will very soon learn what a subroutine (sometimes called a "function") is. It's hard to explain in a single post.
 
Stonewall382 说:
You don't mean an if-statement or while-loop, do you?

Again, thank you.

No, it is just a separate area for code kept for organizational purposes.  When you know one subruotine doex xyz then you can call it from various places without having to duplicate your work.
 
Okay, so here's the new code.  I think it works like it should, and I think I set it up like you guys said:
插入代码块:
  (24, 72, 0), [],[ #We check once a day to see if buildings are under construction.  Because these are level 1 buildings, they take three days (72 hours) to construct.
                (try_for_range,"$castle","p_castle_1","castles_end"),# This does all the things below for the first castle value (p_castle_1), then to the next value (p_castle_2), then the next, and so on, until it reaches right before "castles_end", at which point it resets back to p_castle_1
                    (try_for_range,"$slot",200,217),#  Slots 200 to 217 are the possible industries for each castle
                        (try_begin),
                            (party_get_slot,"$begun?","$castle","$slot"),# Here we're finding the value of the building's slot.
                            (val_mod,"$begun?",2),# Here we divide by two and keep the remainder (val_div gives you the whole number of a quotient; val_mod gives the remainder--more on this in module_dialogs.py), to find if a new building has been constructed
                            (val_add,"$slot",100),# Gets us to the building's level
                            (party_get_slot,"$building_level","$castle","$slot"),# This is here in case people decide to change a given building's level.  Because the woodcutter's tent (for example) might not be level 1 for every castle, we need to make a provision where this trigger only works for level 1 buildings
                            (val_sub,"$slot",100),# Gets us back to the construction slot value
                            (try_begin),
                                (eq,"$building_level",1),# Building level must be 1 for this trigger to work
                                (eq,"$begun",1),# If the building is under construction (if the slot value is odd), then we continue
                                (party_get_slot,"$slot_value","$castle","$slot"),# We find the slot value so that we can add one to it
                                (val_add,"$slot_value",1),# Here we add 1 to complete the construction of the building
                                (party_set_slot,"$castle","$slot","$slot_value"),# Here we actually set the slot to the new value
                                (party_get_slot,"$building_crews","$castle",499),# We find the number of building crews
                                (val_add,"$building_crews",1),# Add one, because the building crew is now available again
                                (party_set_slot,"$castle",499,"$building_crews"),# Again, we need to actually reset the slot to the variable value
                            (try_end),
                    (try_end),
                (try_end)
                ],

The first try_for_range sets up the castles, the second runs through every castle building slot to see which buildings have been started.

I have a question though:  When try_for_range hits the end, does it start again from the beginning?
I suppose it doesn't matter here, because it runs through to the end, then stops, and next time the trigger starts again, it starts from the beginning and does it again.

The try_for_range operation is like a while-loop in C++ that looks roughly like this, right?:
插入代码块:
while (x < 12)
{
    cout << "Hello world!";
   x++;
}
Am I right in that?  It's like a sentinel loop?
 
It's sorta like that.  More like a for loop walking through an array.  But, it has some weirdness to it such as the way the the conditionsals work.  You can put like 10 contionals (like (gt, "$temp", 1) ) in it and as soon as the first one is done it skips to the end.
 
Wait, it just reads down to the first condition that's true and skips the rest?  I don't have any try_else commands in there.  Why would it do that?

Oh, wait.  Now I see what you're saying.  It makes sense.  But once it catches something that's true, it skips to the end, then starts again and bypasses that one, right?
 
Stonewall382 说:
Wait, it just reads down to the first condition that's true and skips the rest?  I don't have any try_else commands in there.  Why would it do that?

Oh, wait.  Now I see what you're saying.  It makes sense.  But once it catches something that's true, it skips to the end, then starts again and bypasses that one, right?

In this example, it executes 1,2, 4, 5, 6

It actually keeps going til it gets to a false.  if ALL the conditions before the else try were true, then not of the ones after the else try would be executed.  Kinda goofy, but hopefully clearer now.

TRY
EXECUTE1
TRUE
EXECUTE2
FALSE
EXECUTE3

ELSE TRY
TRUE
EXECUTE4
TRUE
EXECUTE5
EXECUTE6
FALSE
EXECUTE7

END
 
I think I get it.  Kind of.  Heh.
Thank you.

@  Winter--So does that mean 256 slots total, or just 256 numeric slots?  I see that in the module_constants.py file, there are around 40 values defined with special names (like "slot_castle_exterior").  Do these subtract from that 256-slot limit?  I'd assume they do, but I'd like to make sure before I go back and edit all my work.
 
Just 256 numeric slots. Suppose slot_castle_exterior is slot 10, well you're still free to use slot 10 on towns that are not castles.
 
Really?  So if I were to keep defining my slots, I could have as many as I want?
In the constants file, it says
插入代码块:
#party slots.
slot_town_center        = 10
slot_town_castle        = 11
slot_town_tavern        = 12
slot_town_store         = 13
slot_town_gate          = 14
slot_town_tavernkeeper  = 20
slot_town_weaponsmith   = 21
slot_town_armorer       = 22
slot_town_merchant      = 23
slot_town_mercs         = 40
slot_town_export_good   = 41
slot_town_export_rate   = 42
slot_town_export_good_2 = 43
slot_town_export_rate_2 = 44
slot_town_import_good   = 45
slot_town_import_rate   = 46
slot_town_import_good_2 = 47
slot_town_import_rate_2 = 48


slot_castle_exterior    = 10
slot_castle_interior    = 11
Does this mean that for my castles, I can use every slot except 10 and 11?  Or does it mean that I can use every slot, because "slot_castle_exterior" isn't the same slot as slot 10?
 
后退
顶部 底部