PDA

View Full Version : Simple question for script command I cant find



Spacepoet
02-12-2015, 12:10 PM
Ok so im literally just picking up zscript now, and it seems pretty simple and coherent with some scripting ive done previously, but I can't seem to find what im looking for on the std or on any of the wikia pages.

Is there a way to add and remove items from a Dmap's disable list in scripting? or would it be more plausible to perform entirely with script and not rely on the disable page of a dmap? The idea is that i want certain items in links inventory to become active when he activates an item scripted to R (or ex1 whatever it doesnt matter what button), and others will deactivate, but i dont want them to be removed from the inventory completely. the game still needs to know he is in possession of these items even if they are inactive or cant be used. mmm whatcha say?

CJC
02-12-2015, 11:07 PM
I don't know if there's a way to directly change the disabled items in the DMap, but I do have two suggestions to achieve the same effect: one is more dependent on the editor and quest organization and the other is more dependent on global variables. I'll go with the latter first:


1.) The Acquired Item Array
You could store the items Link 'owns' in a global variable (preferably an array to save space) as a collection of binary gates (1 if he has the item, 0 if not). Then, when you activate the button, you remove all of the items you want to disable from his inventory. When you switch the button back, give him items based on the array, which should be the items he owned previously. You could make an array of 0s and set the 1s based on the built-in item constants, which would make putting things into the array and taking them out relatively easy to understand and code.


2.) The DMap abuser
If you arrange your DMaps correctly, you can disable and enable items in scripts by triggering direct warps. Essentially, you warp to the same map screen and increment/decrement the DMap by 1 (or some consistent constant) each time the button is pressed. Then, you build the two DMaps identically except for altering which items are disabled. You COULD even do fun things like change the subscreen with this strategy depending on what you're trying to achieve.
The reason this works is because multiple DMaps can point to the exact same map screen and you can carry over screen states when you warp. If you force a warp with ZScript you can grab all of the screen's information and warp directly to the currently occupied screen, effectively changing only the DMap.


I hope this helps.

Spacepoet
02-13-2015, 10:39 AM
I think ill have to see about using the first method, as my planned quest setup has Link switching between 7 different sets of 3-5 items per set, so having 7 dmaps for each area would be tedious madness D:

ideally im going to want the player to be able to cycle through the sets of items, going from 1 up to 7 and then back to 1, with each of these sets also being controlled by an item, meaning these items would control the swapping via scripts.

So Link would start out not being able to swap, but upon acquiring the first of the items, could then swap to form 1, with different items, and then press again to swap back to base Link, or "form 0". upon acquiring another of the items, he presses once to swap to form 1, then again now swapping to form 2, and a third time to swap back to form 0, ultimately in the end being able to swap to 7 total forms in a cycle.

another thing i foresee being a problem is that his items should be locked into these forms. example:

form 0 contains the sword set to A, and the boomerang set to b
form 1 contains the bow set to A, and the whistle set to b

say if Link had NOT acquired both the boomerang and the whistle, then both of his B slots would be empty, meaning the first item he picks up would automatically go into his current empty B slot, even if it didnt belong to that set, such as picking up the boomerang in form 1, and being equipped with Bow to A and Boomerang to B, which i dont want.

i know thats pretty specific, but theoretically this is all doable with a way to simply change the value of a dmap specific disable with a true or false statement. dont know why the disables page wasnt inculded in some way under the dmap flags or even its own variable section. I dont know if this is specifically possible using arrays, but i will try.

and thanks for the help friend!

CJC
02-13-2015, 05:25 PM
Hmmm, actually if you're locking two items to the two buttons you might be able to do this by another means.
SUCCESSOR is developing a script header to control inventory mechanics. One of his functions forces ZC to set a particular item to a particular button. If you were to run this script every time the Start button is pressed (so it would refresh when the subscreen is opened and closed) and just adjust WHICH item is forced based on which state Link is in (States 1 through 7, set variables ForcedB and ForcedA when switching to that state and then have SUCCESSOR's function equip those items) you could achieve what you're after. It wouldn't work if you want more than two items per state (since there are only two viable item buttons at the moment) but it might be easier than adding and removing the items from the inventory.


Since I've tagged SUCCESSOR in this post, maybe he'll come in and share the current state of his Inventory header so you can do this. Otherwise, you'll need to come up with some safe loop to run that runs Link->SelectAWeapon[DIR_LEFT] and Link->SelectBWeapon[DIR_LEFT] (Or some other direction constant) until GetEquipmentA() ==ForcedA and GetEquipmentB() == ForcedB (I say safe because you need to be careful to avoid infinite loops).

SUCCESSOR
02-13-2015, 08:00 PM
Hmmm, actually if you're locking two items to the two buttons you might be able to do this by another means.
SUCCESSOR is developing a script header to control inventory mechanics. One of his functions forces ZC to set a particular item to a particular button. If you were to run this script every time the Start button is pressed (so it would refresh when the subscreen is opened and closed) and just adjust WHICH item is forced based on which state Link is in (States 1 through 7, set variables ForcedB and ForcedA when switching to that state and then have SUCCESSOR's function equip those items) you could achieve what you're after. It wouldn't work if you want more than two items per state (since there are only two viable item buttons at the moment) but it might be easier than adding and removing the items from the inventory.

Funny I opened this thread to read it before I left then came back home and finished reading it to find you had tagged me.
Spacepoet all of the things you mentioned are possible with Zscript. I can share my header with you but it is not in a state for public consumption yet. If you'd like it I will PM you a link. It sounds like the best solution for you would be a simple array that organizes what items are in each group and whether or not The player actually has that item. You could use the 0 index as an indicator of the current active set. This of course means you need to be comfortable with arrays (some people seem to have trouble grasping them for some reason). such as:

const int NUM_ITEMS_IN_SETS = 2; //however many per set

int itemSets[] = {0,I_SWORD,I_BRANG,I_BOW,I_WHISTLE,I_HOOKSHOT,I_BO MBS...}
const int ITEM_SET_POSITION = 0;//the element that tells what set is in use


Then itemSets[1+ITEM_SET_POSITION * NUM_ITEMS_IN_SET] would be A
itemSets[1+ITEM_SET_POSITION * NUM_ITEM_SET +1] would be B

And youwould script so that any items in inactive sets would be removed from Link->Items[]. Indicating that link has the item whether or not it is in the actual game inventory can be done in another portion of the array or (as I like to do) in the same index as the position for the item with a decimal.


(Sorry this is all probably very sloppy. I am running on very little sleep of poor quality and a few too many cappuccinos)

Spacepoet
02-14-2015, 08:53 AM
SUCCESSOR that sounds about perfect! also, i think i found a simple way to do what im looking at as well. have a variable that keeps track of links form number, and set R to run a function depending on the current form that removes and adds items to link, grabbing the data from an array stating which items are obtained, and then changes his form number. stick pickup scripts onto all your items that changes their value in the array to 'obtained', then checks his form number. if it is incorrect, it removes the item, and if its right, he equips it to his open slot. when you cycle around to the correct form, the R script should pull the items data from the array and put it back on the right button?

SUCCESSOR
02-14-2015, 07:52 PM
SUCCESSOR that sounds about perfect! also, i think i found a simple way to do what im looking at as well. have a variable that keeps track of links form number, and set R to run a function depending on the current form that removes and adds items to link, grabbing the data from an array stating which items are obtained, and then changes his form number. stick pickup scripts onto all your items that changes their value in the array to 'obtained', then checks his form number. if it is incorrect, it removes the item, and if its right, he equips it to his open slot. when you cycle around to the correct form, the R script should pull the items data from the array and put it back on the right button?

The variable and pickup scripts would be superfluous. Though since you pickup items in sets I guess it wouldn't be that many, but still superfluous. The array example I showed you uses the first index of the array exactly as you are intending to use a variable. It is a global array so any script can check what set is active by doing itemSets[0] or more readibly: itemSets[ITEM_SET_POSITION]. Your script can easily tell if the player picked up an item set by looking for changes in Link->Items[]. Since it only has to check for items that are in part of a set and not all the items in the game there is no problem in running that check every frame.

An example look:

//NUM_ITEMS_IN_SETS = 2;
itemSets[1,5.1,23.1,15.1,31.1,52,3,...]

We can see here that the current set in use is Set1 so Link has Bow(15) and the Whistle(31) equipped and we can also see that he has the items of Set0, Sword(5) and Boomerang(23) but not the items of Set3 Hookshot(52) and Bombs(3). If we use the convention that A comes first then B we know that the Bow should be assigned to A and the Whistle should be assigned to B.

itemSets[0,5.1,23.1,15,31,52,3,...]

Now Set0 is active and Link has the Sword and BRang and no other sets to use.


(all these names and items are examples of course. What you name your constants and arrays is obviously up to you.)

To mark as obtained:



for(int i = 1,i<100,i++)//start at 1 because the 0 index is used to mark the current item set; the 100 is irrelevant it just has to be bigger than the amount of items
{ if(!itemSets[i]) break;//we reached an index with a zero value so we end the loop.
if(Link->Item[floor(itemSets[i])] && !(itemSets[i] - floor(itemSets[i]) ) )//if Link has the item but it hasn't been marked as obtain in the array
itemSets[i] = itemSets[i] + .1; //mark it as obtained in the array
}



(once again: just how I would go about it)

Spacepoet
02-15-2015, 12:22 AM
to clarify, the items arent grabbed totally in sets, still one at a time, just organized into sets. im not quite picking up on your use of arrays, but thats just me not wrapping my head around getting back into scripting again since high school, as we as zc since middle school XD ill read and reread that when im less tired, and thanks for being helpful =]

SUCCESSOR
02-16-2015, 03:31 AM
My example uses the array to organize items into sets, to store which set is to be used, and to store which items have been collected so that they can safely be removed from the "Item Inventory". If you do not understand how I am accomplishing this(I explained it above) then please try it your own way. The way I do things can often be a little... well, try it your own way.