HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Array - Detecting level abilities.

01-29-2008, 09:14 PM#1
Centreri
I'm working on a.. well, a custom hero map. I'm planning to create a Necromancy spell that basically takes the target 'dead' unit, creates a copy of it (and stopping other necromancy spells from being cast on the unit) and giving it to the caster. For the most part this isn't a huge problem, but one thing I'm not able to implement is the correct level of all abilities for the hero.

I have a variable that stores all five abilities for all ten players efficiently, as well as one for just about anything else. One thing I need to implement for this system to work is a variable which stores the levels of all abilities for all players. After that I'll just add the ability and set the level.

I've looked at it, and the closest event that I found to what I need (hero increases level of ability) is 'Unit - A unit learns a skill'. I haven't been able to verify if that would work for what I need because of problems later on, so if someone would tell me if there's a better way for that.

The real problem is the 'Action'. My Ability array (stores all abilities) is divided into 5 abilities per player. Basic formula is (((Player Number + 1) times five) + # of ability for that player). I need a way, while deciding on the index of the abilitylevel array, to compare the ability that was learned to the Ability array (with the player number available), take that number, and use it while deciding on what index to edit.

I should be able to use this information to also set it to the correct number (the second problem, before I saw this, was that it only allowed me to use 'level of ability being cast', and not 'level of ability learned').

Big thank you in advance - I really wanna get this spell working.

Oh, and on a misc note - What's the relationship between 'within a range of x of point' and 'Area of Effect'? Is Area of Effect the area of that range?

A JASS-based response is fine, since I usually convert GUI spells to JASS to slightly optimize them.
01-30-2008, 09:26 AM#2
tamisrah
There is a native which seems to give you 'level of ability learned'
Collapse JASS:
constant native GetLearnedSkillLevel takes nothing returns integer

To range vs area, yeah you're right there 'within a range of x of point' describes the area by its radius.

I'll try to help you further later, but know I have to go to school ^^
01-30-2008, 08:05 PM#3
Centreri
Thanks. I have virtually no idea how to about solving it. I looked in all the 'integer' detector thingies (for the index of the variable), and I couldn't find any that allows me to compare it to another integer.
01-30-2008, 09:45 PM#4
tamisrah
This seems to be more difficult than I thought, I only found a quite messy way yet. You could use this function to store all levels for all abilities on a unit.

But there should be a less messy way to do what you want.
01-31-2008, 08:18 AM#5
Pyrogasm
Use Gamecache. It makes sense in this situation:
Trigger:
Start
Collapse Events
Map initialization
Conditions
Collapse Actions
Game Cache - Create a game cache from PlayerAbilities.w3v
Set AbilityCache = (Last created game cache)
Trigger:
Actions
-------- Whever you store the abilities --------
Set AbilityId = <However you get the ability>
Custom script: set udg_AbilityIdInteger = udg_AbilityId
Game Cache - Store AbilityIdInteger as Ability1 of (Player + ((String((Player number of (<However you get the player>)))) + Abilities)) in AbilityCache
-------- For the next ability, only changing the "label" field --------
Set AbilityId = AbilityId
Custom script: set udg_AbilityIdInteger = udg_AbilityId
Game Cache - Store AbilityIdInteger as Ability2 of (Player + ((String((Player number of (Triggering player)))) + Abilities)) in AbilityCache
Trigger:
Actions
-------- Whever you get the abilities and their levels --------
Set AbilityIdInteger = (Load Ability1 of (Player + ((String((Player number of (<However you get the player>)))) + Abilities)) from AbilityCache)
Custom script: set udg_AbilityId = udg_AbilityIdInteger
Unit - Add AbilityId to (<Whatever unit>)
Unit - Set level of AbilityId for (<Whatever unit>) to (Load (String(AbilityIdInteger)) of (Player + ((String((Player number of (<However you get the player>)))) + AbilityLevels)) from AbilityCache)
-------- Repeating, again changing only the "label" field --------
Set AbilityIdInteger = (Load Ability2 of (Player + ((String((Player number of (<However you get the player>)))) + Abilities)) from AbilityCache)
Custom script: set udg_AbilityId = udg_AbilityIdInteger
Unit - Add AbilityId to (<Whatever unit>)
Unit - Set level of AbilityId for (<Whatever unit>) to (Load (String(AbilityIdInteger)) of (Player + ((String((Player number of (<However you get the player>)))) + AbilityLevels)) from AbilityCache)
Trigger:
Ability Learn
Collapse Events
Unit - A unit Learns a skill
Conditions
Collapse Actions
Custom script: set udg_AbilityLevel = GetLearnedSkillLevel()
Custom script: set udg_AbilityIdString = I2S(GetLearnedSkill())
Game Cache - Store AbilityLevel as AbilityIdString of (Player + ((String((Player number of (Owner of (Triggering unit))))) + AbilityLevels)) in AbilityCache

I hope you understand what that is supposed to do... the only reason it looks a bit convoluted is because GUI treats abilities and integers as separate variables, when abilities are just integers in JASS. Thus, the fooling of the GUI.

These variables are needed for this:
Table:
NameType
AbilityCacheGame Cache
AbilityIdAbility
AbilityIdIntegerInteger
01-31-2008, 10:06 PM#6
Centreri
Very interesting.. a GameCache tutorial and fixing a big problem in one. Thanks! Working on implementing it.

Was about to post a bug report when I realized that the Ability and AbilityLevels (2 & 4) were actual strings rather then variables.

EDIT: Well, after figuring things out and implementing them, I created the ability, add everything, modified, etc. I got the ability to the correct targetting, and even though I think everything besides that is working, the temporary undead hero version isn't being created. Here's a basic ability-adding trigger. The sub-ultimates and ultimates are almost the same, but without the loop and with a set ability number. The regulars can be 1, 2, or 3, hence the loop:
Trigger:
Delayed Reaction Fireball Add
Collapse Events
Unit - A unit Acquires an item
Collapse Conditions
(Item-type of (Item being manipulated)) Equal to Delayed Reaction fireball
Collapse Actions
Unit - Add Delayed Reaction Fireball - Spellbook to (Triggering unit)
Collapse For each (Integer A) from 1 to 3, do (Actions)
Collapse Loop - Actions
Custom script: if (udg_HeroAbilities[(GetPlayerId(GetTriggerPlayer())*5)+bj_forLoopAIndex] == 0) then
Set HeroAbilities[((((Player number of (Triggering player)) - 1) x 5) + (Integer A))] = Delayed Reaction Fireball
Custom script: set udg_AbilityID = udg_HeroAbilities[(GetPlayerId(GetTriggerPlayer())*5)+bj_forLoopAIndex]
Game Cache - Store AbilityID as (Ability + (String((Integer A)))) of (Player + ((String((Player number of (Owner of (Triggering unit))))) + Abilities)) in AbilityCache
Unit - Set level of Delayed Reaction Fireball - Custom System for (Triggering unit) to (Integer A)
Player - Disable Delayed Reaction Fireball - Spellbook for (Owner of (Triggering unit))
Item - Remove (Item being manipulated)
Custom script: exitwhen true
Custom script: endif
Here's the hero death trigger. This may force some reason mess with the 'resurrection':
Trigger:
Death Heroes
Collapse Events
Unit - A unit Dies
Collapse Conditions
((Triggering unit) is A Hero) Equal to True
((Triggering player) controller) Equal to User
Collapse Actions
Set HeroStatus[(Player number of (Triggering player))] = Dead
Hero - Instantly revive (Dying unit) at (Position of (Dying unit)), Hide revival graphics
Unit - Add classification of An Ancient to (Dying unit)
Collapse If (All Conditions are True) then do (Then Actions) else do (Else Actions)
Collapse If - Conditions
((Unit-type of (Triggering unit)) Equal to Eredar Warrior) or ((Unit-type of (Triggering unit)) Equal to Eredar Warlock)
Collapse Then - Actions
Animation - Play (Dying unit)'s stand animation
Animation - Change (Triggering unit)'s vertex coloring to (30.00%, 30.00%, 30.00%) with 20.00% transparency
Collapse Else - Actions
Animation - Play (Dying unit)'s death animation
Unit - Add Ghost (Visible) to (Dying unit)
Unit - Make (Dying unit) Invulnerable
Unit - Change ownership of (Dying unit) to Neutral Passive and Retain color
Unit - Set the custom value of (Dying unit) to (Player number of (Owner of (Dying unit)))
Here's the skill leveling trigger:
Trigger:
Upgrading Abilities
Collapse Events
Unit - A unit Learns a skill
Conditions
Collapse Actions
Custom script: set udg_AbilityLevel = GetLearnedSkillLevel()
Custom script: set udg_AbilityIdString = I2S(GetLearnedSkill())
Game Cache - Store AbilityLevel as AbilityIdString of (Player + ((String((Player number of (Owner of (Triggering unit))))) + AbilityLevels)) in AbilityCache
And, last but not least, the spell trigger itself:
Trigger:
Undead Conversion
Collapse Events
Unit - A unit Starts the effect of an ability
Collapse Conditions
(Ability being cast) Equal to Undead Conversion
Collapse Actions
Collapse If (All Conditions are True) then do (Then Actions) else do (Else Actions)
Collapse If - Conditions
((Custom value of (Target unit of ability being cast)) Greater than or equal to 1) and ((Custom value of (Target unit of ability being cast)) Less than or equal to 10)
Collapse Then - Actions
Unit - Create 1 (Unit-type of (Target unit of ability being cast)) for (Owner of (Triggering unit)) at (Position of (Target unit of ability being cast)) facing (Position of (Triggering unit))
Hero - Set (Last created unit) Hero-level to (Level of (Target unit of ability being cast)), Hide level-up graphics
-------- AbilitySection --------
Set AbilityID = (Load Ability1 of (Player + ((String((Custom value of (Target unit of ability being cast)))) + Abilities)) from AbilityCache)
Custom script: set udg_AbilityIdAbility = udg_AbilityID
Unit - Add AbilityIdAbility to (Last created unit)
Unit - Set level of AbilityIdAbility for (Last created unit) to (Load (String(AbilityID)) of (Player + ((String((Custom value of (Target unit of ability being cast)))) + AbilityLevels)) from AbilityCache)
Set AbilityID = (Load Ability2 of (Player + ((String((Custom value of (Target unit of ability being cast)))) + Abilities)) from AbilityCache)
Custom script: set udg_AbilityIdAbility = udg_AbilityID
Unit - Add AbilityIdAbility to (Last created unit)
Unit - Set level of AbilityIdAbility for (Last created unit) to (Load (String(AbilityID)) of (Player + ((String((Custom value of (Target unit of ability being cast)))) + AbilityLevels)) from AbilityCache)
Set AbilityID = (Load Ability3 of (Player + ((String((Custom value of (Target unit of ability being cast)))) + Abilities)) from AbilityCache)
Custom script: set udg_AbilityIdAbility = udg_AbilityID
Unit - Add AbilityIdAbility to (Last created unit)
Unit - Set level of AbilityIdAbility for (Last created unit) to (Load (String(AbilityID)) of (Player + ((String((Custom value of (Target unit of ability being cast)))) + AbilityLevels)) from AbilityCache)
Set AbilityID = (Load Ability4 of (Player + ((String((Custom value of (Target unit of ability being cast)))) + Abilities)) from AbilityCache)
Custom script: set udg_AbilityIdAbility = udg_AbilityID
Unit - Add AbilityIdAbility to (Last created unit)
Unit - Set level of AbilityIdAbility for (Last created unit) to (Load (String(AbilityID)) of (Player + ((String((Custom value of (Target unit of ability being cast)))) + AbilityLevels)) from AbilityCache)
Set AbilityID = (Load Ability5 of (Player + ((String((Custom value of (Target unit of ability being cast)))) + Abilities)) from AbilityCache)
Custom script: set udg_AbilityIdAbility = udg_AbilityID
Unit - Add AbilityIdAbility to (Last created unit)
Unit - Set level of AbilityIdAbility for (Last created unit) to (Load (String(AbilityID)) of (Player + ((String((Custom value of (Target unit of ability being cast)))) + AbilityLevels)) from AbilityCache)
-------- AbilitySectionEnd --------
Animation - Change (Last created unit)'s vertex coloring to (70.00%, 100.00%, 70.00%) with 20.00% transparency
Else - Actions
Now, this is a lot of triggers, but so far I haven't gotten further then making the spell take effect (the triggers don't fire, though). The unit doesn't appear, which means that for some reason the condition to the above trigger isn't firing. Probably just a custom value issue, though I have no idea what's wrong. I'm playing as Player One(red). Any help greatly appreciated.

Oh, and here's a list of my variables:
AbilityCache - Game Cache
AbilityID - Integer
AbilityIdAbility - Ability
AbilityIdString - String
AbilityLevel - Integer
02-03-2008, 02:08 PM#7
Centreri
Bump.
02-05-2008, 07:28 PM#8
Blue_Jeans
Well... Centeri, I could try to help you, but I never learned GUI. Ever. It would be entirely in JASS. Do you suppose that would be a problem? If it isn't, I can take a look-see and play with it, but no guarantees.
02-05-2008, 09:31 PM#9
Centreri
Well, I know basic JASS. Use it for optimization. If you find the part that's malfunctioning and give me a JASS replacement, that's great. If all you can do is create a system from scratch in JASS, it would be much harder to replicate and adjust to fit my map, though I suppose it's possible.
02-06-2008, 05:36 AM#10
Blue_Jeans
Where I am kind of jumping in on this, I'd rather not have to pore over every line of each post here. Also, while this is actually a good and legitimate use for the gamecache, preferably I'd rather not use it. The code required for gamecache is long and tedious in my opinion. Where you don't know in-depth JASS, I don't want to use structs, either.

To say it simply, I guess I'd rather not do it. I could do it, but then you don't really learn from it. It would be a lot of learning for someone of your knowledge before it all made sense. When I do things for people, I try to make it on their level with 1 step up, meaning it isn't the most advanced code, but something more advanced than what they have. This way I can teach a quick concept and they get something out of it. I don't believe this particular spell can be done practically without more advanced techniques.

I'm dreadfully sorry for getting your hopes up, mate.

Edit: on second thought, if you attached what you have to a post here, I might be able to sort it out through GUI. Again, no guarantees, but I'll at least give it a look.
02-06-2008, 05:45 AM#11
Strilanc
My current preferred way of doing this is using unit groups. You create an array of them (one per level), find out which group the hero is in (none=0) and move it to the next group. It's not necessarily efficient, but heroes don't pick a new abilities 10 times a second.

I suppose in GUI the unit group arrays would clutter up the variable editor, though.