array not arraying [SOLVED]
Moderator: Forum Moderators
Forum rules
- Please use [code] BBCode tags in your posts for embedding WML snippets.
- To keep your code readable so that others can easily help you, make sure to indent it following our conventions.
Re: array not arraying
When reviewing code we start with more obvious issues. Once those are solved and we still hear code doesnt work, then we might try to run it personally.
But when quick glance already tells that there is no way the code will work, there is no point to set it up in game.
But when quick glance already tells that there is no way the code will work, there is no point to set it up in game.
Re: array not arraying
This is the first time I've heard that the code won't work. I thought beetlenaut had provided a solution that I didn't understand.
So the problem is that
[foreach]
is unable to learn the value of how_frozen
within a petrified unit's array, so it doesn't loop like I expect?And there's no alternative way to test the value of
how_frozen
using FOR or SWITCH or whatever? WML can't do that?
Author of:
DIY Campaign, Confederacy of Swamp Creatures: Big Battle 1, Confederacy of Swamp Creatures: Big Battle 2, Frogfolk Delivery Service, The Pool of Ek.
DIY Campaign, Confederacy of Swamp Creatures: Big Battle 1, Confederacy of Swamp Creatures: Big Battle 2, Frogfolk Delivery Service, The Pool of Ek.
Re: array not arraying
For this example ignore the loop and just think of first unit (target_units[0]).
When asking for $target_units[0].id.how_frozen and wanting to get 0 back, you expect array contains element
[target_units]
[id] - more properly accessed with id[0], but it would probably work without index too and return first tag
how_frozen=0
[/id]
[id] - multiple tags can have same name, they are accessed by index
how_frozen=9
[/id]
[/target_units]
However, target_units is made of units, and instead of [id][/id] they have for example $target_units[0].id=Thug-4
[target_units]
id=Ghost-5 - one tag can only have each key once, last one applies
id=Thug-4
[/target_units]
When asking for $target_units[0].id.how_frozen and wanting to get 0 back, you expect array contains element
[target_units]
[id] - more properly accessed with id[0], but it would probably work without index too and return first tag
how_frozen=0
[/id]
[id] - multiple tags can have same name, they are accessed by index
how_frozen=9
[/id]
[/target_units]
However, target_units is made of units, and instead of [id][/id] they have for example $target_units[0].id=Thug-4
[target_units]
id=Ghost-5 - one tag can only have each key once, last one applies
id=Thug-4
[/target_units]
Re: array not arraying
Thanks. I think arrays are partly the source of my confusion. But your post gave me an idea..
I've used
[foreach]
in the past with hitpoints and it worked. Here it is:Code: Select all
[foreach]
array=target_units
[do]
[if]
[variable]
name=this_item.hitpoints
less_than_equal_to=$harm_damage
[/variable]
[then]
cost=
to hold the how_frozen
value? Once a unit is on the map, cost
is useless. I could use it to hold the frozen values, which are 0-2. Then I could use name=this_item.cost
within the [variable]
of the [foreach]
loop.Is that a viable workaround to circumvent the problem?
Author of:
DIY Campaign, Confederacy of Swamp Creatures: Big Battle 1, Confederacy of Swamp Creatures: Big Battle 2, Frogfolk Delivery Service, The Pool of Ek.
DIY Campaign, Confederacy of Swamp Creatures: Big Battle 1, Confederacy of Swamp Creatures: Big Battle 2, Frogfolk Delivery Service, The Pool of Ek.
- beetlenaut
- Developer
- Posts: 2825
- Joined: December 8th, 2007, 3:21 am
- Location: Washington State
- Contact:
Re: array not arraying
I told you a while ago that, "There may be more problems, but fix the above problems first." You should assume that is true for pretty much every post by one of us.
I don't know what made you think that, but no, the [foreach] loop should do what you want when its errors are fixed.
I realized that you have another large problem though. You have two new_turn events, and you want one to happen after the other. That's not guaranteed, so they might be happening in the reverse order. You need to combine them into one event with one [foreach]. I'm going to tell you how to make it simpler so it's easier to work with.
Right now, THAWING EVENT uses a lot of code to subtract 1 from how_frozen. This is a waste of time considering that computers are purpose-built to subtract! It should work in one event with one [if] statement in your [foreach]: If how_frozen is greater than 0 then subtract one from it, otherwise unpetrify. (The subtract function is in [set_variable]. Look it up if you're not sure you know how it works.)
I don't know. That might work, but it would make the code pretty unintelligible, so I wouldn't do it.
Campaigns: Dead Water,
The Founding of Borstep,
Secrets of the Ancients,
and WML Guide
The Founding of Borstep,
Secrets of the Ancients,
and WML Guide
Re: array not arraying
Ah. I think reverse order happened a few times, because odd things would randomly happen when play-testing.beetlenaut wrote: ↑November 21st, 2022, 6:24 pmI realized that you have another large problem though. You have two new_turn events, and you want one to happen after the other. That's not guaranteed, so they might be happening in the reverse order.
Thanks, beetlenaut. I did what you said and made onebeetlenaut wrote: ↑November 21st, 2022, 6:24 pm You need to combine them into one event with one [foreach]. I'm going to tell you how to make it simpler so it's easier to work with...
new turn
event. The Giant Rat unpetrifies now, but too quickly -- on the next turn, after being frozen.
Look at this code here. See
status=petrified
in the [store_unit]
filter?
Code: Select all
[store_unit]
[filter]
side=2 # This will store all of the side 2 units in an array.
status=petrified
[/filter]
[else]
simple, because no unit who is not petrified should be within this loop. This is correct, right?Code: Select all
[else]
[unpetrify] # any unit that is not frozen or thawing will be unpetrified
id=$this_item.id
[/unpetrify]
[/else]
[/if]
[/do]
Code: Select all
[event] # T H A W I N G E V E N T
name=new turn
first_time_only=no
[store_unit]
[filter]
side=2 # This will store all of the side 2 units in an array.
status=petrified
[/filter]
variable=target_units # "unit" as a variable name is reserved for the unit that triggers an event, so try not to use it for other things. It could get confusing.
[/store_unit]
[foreach]
array=target_units
[do]
[if]
[variable]
name=this_item.how_frozen # how frozen is the unit on a scale of 0-2 0=not frozen 1=thawing 2=frozen
greater_than=0
[/variable]
[then]
[set_variable]
name=this_item.how_frozen
sub=1 # unit was frozen, but is now thawing. Unit will unpetrify next turn.
[/set_variable]
[/then]
[else]
[unpetrify] # any unit that is not frozen or thawing will be unpetrified
id=$this_item.id
[/unpetrify]
[/else]
[/if]
[/do]
[/foreach]
[/event]
[event]
name=attacker hits
first_time_only=no
[filter_attack]
special=freezes
[/filter_attack]
[modify_unit]
[filter]
id=$second_unit.id # an id stores a specific unit in an array.
[/filter]
[set_variable]
name=how_frozen # how frozen is the unit on a scale of 0-2 0=not frozen 1=thawing 2=frozen
value=2
[/set_variable]
[/modify_unit]
# $second_unit is just a copy of the unit, not the actual unit itself. However, when you use [modify_unit] you update the actual unit,
# not the copy, so the copy is now out-of-date. If you want to keep $second_unit accurate you'll need to re-store the unit after modifying it:
[store_unit]
[filter]
id=$second_unit.id
[/filter]
variable=second_unit
id=$second_unit.id
[/store_unit]
[message]
speaker=MyLeader
message="Modify unit just changed a variable to: " + $second_unit.variables.how_frozen + "."
[/message]
[/event]
Author of:
DIY Campaign, Confederacy of Swamp Creatures: Big Battle 1, Confederacy of Swamp Creatures: Big Battle 2, Frogfolk Delivery Service, The Pool of Ek.
DIY Campaign, Confederacy of Swamp Creatures: Big Battle 1, Confederacy of Swamp Creatures: Big Battle 2, Frogfolk Delivery Service, The Pool of Ek.
- beetlenaut
- Developer
- Posts: 2825
- Joined: December 8th, 2007, 3:21 am
- Location: Washington State
- Contact:
Re: array not arraying
My guess is that this is because you are using a new_turn event. You should either use a side_2_turn if it only matters for side 2, or use side_turn but check to make sure you only store the units whose turn it is. That way it could work for any side. (There is an automatically-stored $side_number variable that you would need for the second option.)
It looks that way.
Campaigns: Dead Water,
The Founding of Borstep,
Secrets of the Ancients,
and WML Guide
The Founding of Borstep,
Secrets of the Ancients,
and WML Guide
Re: array not arraying
> name=this_item.how_frozen
Units do not have attribute named how_frozen, you can inspect and see that unit has container
[variables]
how_frozen=2
[/variables]
That is why we have mentioned unit variables, they are exactly for the purpose of storing any kind of WML inside unit. $target_units[0].variables.how_frozen should contain some value.
You can use [inspect][/inspect] as breakpoint in
[foreach]
array=target_units
[do]
[inspect][/inspect]
I think it will let you see what this_item contains.
Units do not have attribute named how_frozen, you can inspect and see that unit has container
[variables]
how_frozen=2
[/variables]
That is why we have mentioned unit variables, they are exactly for the purpose of storing any kind of WML inside unit. $target_units[0].variables.how_frozen should contain some value.
You can use [inspect][/inspect] as breakpoint in
[foreach]
array=target_units
[do]
[inspect][/inspect]
I think it will let you see what this_item contains.
Re: array not arraying
Is this what you mean?
I used
name=$target_units[0].variables.how_frozen
.It didn't work, so I must not be understanding.
Code: Select all
[event] # T H A W I N G E V E N T
name=new turn
first_time_only=no
[store_unit]
[filter]
side=2 # This will store all of the side 2 units in an array.
status=petrified
[/filter]
variable=target_units # "unit" as a variable name is reserved for the unit that triggers an event, so try not to use it for other things. It could get confusing.
[/store_unit]
[foreach]
array=target_units
[do]
[if]
[variable]
name=$target_units[0].variables.how_frozen # how frozen is the unit on a scale of 0-2 0=not frozen 1=thawing 2=frozen
greater_than=0
[/variable]
[then]
[set_variable]
name=$target_units[i].variables.how_frozen
sub=1 # unit was frozen, but is now thawing. Unit will unpetrify next turn.
[/set_variable]
[/then]
[else]
[unpetrify] # any unit that is not frozen or thawing will be unpetrified
id=$this_item.id
[/unpetrify]
[/else]
[/if]
[/do]
[/foreach]
[/event]
[target_units][0]
. It seems to be a copy of everything for the petrified Giant Rat.How does a person get the
0
to change to 1, 2 ,3 and so forth, in the event there are multiple petrified units? Apparently you're not supposed to use the default i.Wiki: index_var: The name of a variable which refers to the index of the current item. Defaults to i. Note that this is just for information purposes and should not be used to access the array from within the loop (any such changes made will not persist).
Author of:
DIY Campaign, Confederacy of Swamp Creatures: Big Battle 1, Confederacy of Swamp Creatures: Big Battle 2, Frogfolk Delivery Service, The Pool of Ek.
DIY Campaign, Confederacy of Swamp Creatures: Big Battle 1, Confederacy of Swamp Creatures: Big Battle 2, Frogfolk Delivery Service, The Pool of Ek.
Re: array not arraying
I mean
[message]
message=$target_units[0].variables.how_frozen
[/message]
It is value of first unit -> unit variable -> how_frozen -> number. So you would get name=2, and variable with name 2 does not exist. Purpose of this line is to show how to access value from unit variable. Once you know what you do works for one unit, you can work on iteration to do it for all units.
[message]
message=$target_units[0].variables.how_frozen
[/message]
It is value of first unit -> unit variable -> how_frozen -> number. So you would get name=2, and variable with name 2 does not exist. Purpose of this line is to show how to access value from unit variable. Once you know what you do works for one unit, you can work on iteration to do it for all units.
Re: array not arraying
That's what I'm trying to do. At one point, I had a small success. This code printed a 2 on the screen:
message="Within the foreach loop the how_frozen variable is " + $target_units[0].variables.how_frozen + "."
I went ahead an inserted the i in place of the 0 in this -->
$target_units[0].variables.how_frozen
, but nothing happened.Latest code attempt:
Code: Select all
[event] # T H A W I N G E V E N T
name=new turn
first_time_only=no
[store_unit]
[filter]
side=2 # This will store all of the side 2 units in an array.
status=petrified
[/filter]
variable=target_units # "unit" as a variable name is reserved for the unit that triggers an event, so try not to use it for other things. It could get confusing.
[/store_unit]
[foreach]
array=target_units
[do]
[if]
[inspect][/inspect]
[variable]
name=$target_units[i].variables.how_frozen # how frozen is the unit on a scale of 0-2 0=not frozen 1=thawing 2=frozen
greater_than=0
[/variable]
[then]
[set_variable]
name=$target_units[i].variables.how_frozen
sub=1 # unit was frozen, but is now thawing. Unit will unpetrify next turn.
[/set_variable]
[/then]
[message]
speaker=MyLeader
message="Within the foreach loop the how_frozen variable is " + $target_units[i].variables.how_frozen + "."
[/message]
[else]
[message]
speaker=MyLeader
message="Within the foreach loop the how_frozen variable is " + $target_units[i].variables.how_frozen + "."
[/message]
[unpetrify] # any unit that is not frozen or thawing will be unpetrified
id=$this_item.id
[/unpetrify]
[/else]
[/if]
[/do]
[/foreach]
[/event]
[event]
name=attacker hits
first_time_only=no
[filter_attack]
special=freezes
[/filter_attack]
[modify_unit]
[filter]
id=$second_unit.id # an id stores a specific unit in an array.
[/filter]
[set_variable]
name=how_frozen # how frozen is the unit on a scale of 0-2 0=not frozen 1=thawing 2=frozen
value=2
[/set_variable]
[/modify_unit]
# $second_unit is just a copy of the unit, not the actual unit itself. However, when you use [modify_unit] you update the actual unit,
# not the copy, so the copy is now out-of-date. If you want to keep $second_unit accurate you'll need to re-store the unit after modifying it:
[store_unit]
[filter]
id=$second_unit.id
[/filter]
variable=second_unit
id=$second_unit.id
[/store_unit]
[message]
speaker=MyLeader
message="Modify unit just changed a variable to: " + $second_unit.variables.how_frozen + "."
[/message]
[/event]
ATTACHMENT DELETED
Last edited by Helmet on November 22nd, 2022, 5:23 pm, edited 1 time in total.
Author of:
DIY Campaign, Confederacy of Swamp Creatures: Big Battle 1, Confederacy of Swamp Creatures: Big Battle 2, Frogfolk Delivery Service, The Pool of Ek.
DIY Campaign, Confederacy of Swamp Creatures: Big Battle 1, Confederacy of Swamp Creatures: Big Battle 2, Frogfolk Delivery Service, The Pool of Ek.
- beetlenaut
- Developer
- Posts: 2825
- Joined: December 8th, 2007, 3:21 am
- Location: Washington State
- Contact:
Re: array not arraying
Maybe you don't realize that Ravana or I could fix the event in a jiffy if we wanted to, but we are purposely not doing that! We are trying to teach you WML and to get you to think about the code. You don't seem to be doing that because you should have realized that
$target_unit[i].variables.how_frozen
is not storing the name of a variable, even if you aren't sure exactly what it does store. (Ravana has told you what's in it now though.)This question does make sense, and tells me that you understand more about arrays than before, so that's good at least. But, the thing is, you have the solution to the question in your code already! You are doing what you need to do in [unpetrify]. Go read [foreach] again if that's still unclear.
You are getting close, and I only counted three changes that you need to make.
Campaigns: Dead Water,
The Founding of Borstep,
Secrets of the Ancients,
and WML Guide
The Founding of Borstep,
Secrets of the Ancients,
and WML Guide
Re: array not arraying
I just realized "unit was frozen, but is now thawing. Unit will unpetrify next turn" part does not work because you set it as if it is normal variable, while it needs to go inside unit like you do with attacker hits event.
Though I am not very confident on my understanding of [foreach] there, I wrote all my code when [while] was the one iteration style used.
Though I am not very confident on my understanding of [foreach] there, I wrote all my code when [while] was the one iteration style used.
Re: array not arraying
:inspect shows thatbeetlenaut wrote: ↑November 21st, 2022, 8:55 pm You are getting close, and I only counted three changes that you need to make.
[this_item][0]
has the value of how_frozen
, which is the value I need to decrease every turn.Here is the latest code. I might have fixed one or two problems, but not three, because it still doesn't work.
Thawing event...
Code: Select all
[event] # T H A W I N G E V E N T
name=new turn
first_time_only=no
[store_unit]
[filter]
side=2 # This will store all of the side 2 units in an array.
status=petrified
[/filter]
variable=target_units # "unit" as a variable name is reserved for the unit that triggers an event, so try not to use it for other things. It could get confusing.
[/store_unit]
[foreach]
array=target_units
[do]
# [inspect][/inspect]
[if]
[variable]
name=this_item.how_frozen # how frozen is the unit on a scale of 0-2 0=not frozen 1=thawing 2=frozen
greater_than=0
[/variable]
[then]
[set_variable]
name=this_item.how_frozen
sub=1 # unit was frozen, but is now thawing. Unit will unpetrify next turn.
[/set_variable]
[/then]
[message]
speaker=MyLeader
message="Location 1."
[/message]
[else]
[unpetrify] # any unit that is not frozen or thawing will be unpetrified
id=$this_item.id
[/unpetrify]
[/else]
[/if]
[/do]
[/foreach]
[/event]
Code: Select all
[event]
name=attacker hits
first_time_only=no
[filter_attack]
special=freezes
[/filter_attack]
[modify_unit]
[filter]
id=$second_unit.id # an id stores a specific unit in an array.
[/filter]
[set_variable]
name=how_frozen # how frozen is the unit on a scale of 0-2 0=not frozen 1=thawing 2=frozen
value=2
[/set_variable]
[/modify_unit]
# $second_unit is just a copy of the unit, not the actual unit itself. However, when you use [modify_unit] you update the actual unit,
# not the copy, so the copy is now out-of-date. If you want to keep $second_unit accurate you'll need to re-store the unit after modifying it:
[store_unit]
[filter]
id=$second_unit.id
[/filter]
variable=second_unit
id=$second_unit.id
[/store_unit]
[message]
speaker=MyLeader
message="Modify unit just changed a variable to: " + $second_unit.variables.how_frozen + "."
[/message]
[/event]
Author of:
DIY Campaign, Confederacy of Swamp Creatures: Big Battle 1, Confederacy of Swamp Creatures: Big Battle 2, Frogfolk Delivery Service, The Pool of Ek.
DIY Campaign, Confederacy of Swamp Creatures: Big Battle 1, Confederacy of Swamp Creatures: Big Battle 2, Frogfolk Delivery Service, The Pool of Ek.
Re: array not arraying
You forgot .variables