System Attribute Increase

T

Twyddli

Guest
I have created a system that allows each player to increase their heroes Strength, Intelligence and Agility manually, so that they can choose what type of hero they want, a strong one a smart one, or a quick one.

Here is how it works.
When your hero levels, it will gain one skill point, and then it adds 3 more. You can use these 4 Skill points to level abilities or stats, I think if you level just abilities with these then when you get to level 10 you will still have many skill points left, that you can put into stats.

When you learn a skill it checks if you have 1 skill point or less, if so it disables the three stat abilities. making it so that you can only put up 3 stat levels per hero level.
I will put up some the triggers and what ever is Red can be changed.

There is one Unit Variable array in this map. Heroes[1-12] You change the array to how many players you have. You will have to set the variable in the game when you get your hero.

This trigger increases your agility when you increase the skill change the green 1 to any number, this is the amount of Agi your hero gets when it levels agility (agi +1) ability. Agility (Agi +1) is a custom ability, based on attribute point, i nulled all its effects though.
Code:
Agi
    Events
        Unit - A unit Learns a skill
    Conditions
        (Learned Hero Skill) Equal to Agility (Agi +1)
    Actions
        Hero - Modify Agility of (Triggering unit): Add [COLOR="Red"]1[/COLOR]
        Unit - Decrease level of Agility (Agi +1) for (Triggering unit)
        Unit - Remove Agility (Agi +1) from (Triggering unit)

This trigger does the exct same as the first one, only for strength
Code:
Str
    Events
        Unit - A unit Learns a skill
    Conditions
        (Learned Hero Skill) Equal to Strength (Str +1)
    Actions
        Hero - Modify Strength of (Triggering unit): Add [COLOR="Red"]1[/COLOR]
        Unit - Decrease level of Strength (Str +1) for (Triggering unit)
        Unit - Remove Strength (Str +1) from (Triggering unit)

Same as this one, but for Intelligence.
Code:
Int
    Events
        Unit - A unit Learns a skill
    Conditions
        (Learned Hero Skill) Equal to Intelligence (Int +1)
    Actions
        Hero - Modify Intelligence of (Triggering unit): Add [COLOR="Red"]1[/COLOR]
        Unit - Decrease level of Intelligence (Int +1) for (Triggering unit)
        Unit - Remove Intelligence (Int +1) from (Triggering unit)

This one is how many attribute points you get when you level. Change the green 3 to what ever you want.
Code:
Hero Levels
    Events
        Unit - A unit Gains a level
    Conditions
    Actions
        Hero - Modify unspent skill points of (Triggering unit): Add [COLOR="Red"]3[/COLOR] points
        Player - Enable Agility (Agi +1) for (Owner of (Triggering unit))
        Player - Enable Intelligence (Int +1) for (Owner of (Triggering unit))
        Player - Enable Strength (Str +1) for (Owner of (Triggering unit))

When you make your unit, and you want it to have these abilities, you have to put them in the hero abilities part of the object editor and then after .01 seconds has passed, it will disable them, until you level.

To test this map, while in the game, type -level and it will increase the level of the hero by 1.

There is only one problem i have found with this system... You can then only have 2 hero abilities.

I would love to hear your feedback, and ideas on how to improve it.
Good luck! Have fun! ;)
Edit: I fixed something in the map, should be better now.
 

Attachments

  • [System] Attribute Increaser.w3x
    19.4 KB · Views: 317

Ghan

Administrator - Servers are fun
Staff member
Reaction score
889
Code:
Unit - Remove Agility (Agi +1) from (Triggering unit)

Won't this prevent you from adding any more agility to the unit? You can't re-add the ability, you know. ;)

> I will put up some the triggers and what ever is Green can be changed.

That's pretty unnoticeable. I would change it to a different color. :D
 

DuckieKing

Elitist Through and Through
Reaction score
51
Code:
        Unit - Decrease level of Agility (Agi +1) for (Triggering unit)
        Unit - Remove Agility (Agi +1) from (Triggering unit)
Did you try doing this without the "Decrease level..."? I'm fairly (100%) sure you don't need it.

edit: A way to get around having only two hero abilities would be to use a spellbook with dummy spells for raising stats. That way you can even disable the spellbook and hide the stat bonus feature when there are no bonus stats to be had. Cons might be either a variable to hold the number of stats a unit has or limiting the system to newgen jass, if you use structs + custom value.

anotheredit: Gonna post a test map? Not that I intend on downloading it. I never download test maps. I'm just too lazy to open WC3/WE.
 
T

Twyddli

Guest
Ghan, I will change the green to red i think, and also I have tested it and it works, even when you remove the ability, all it does is remove it from your learnt skills, but you can still increase it.

DuckieKing, I didn't know that i didn't need that, thanks for telling me though.

Edit: Yeah i just relized it wasn't up, so i put it up then i tested it again to check if Ghan was right, but it doesn't disable the abilities when you have only 1 Attribute point.. Ill see if i can fix it.

Edit2: Ok i think i have fixt up the problem, ill put the fixed one up.
 

Ghan

Administrator - Servers are fun
Staff member
Reaction score
889
> also I have tested it and it works, even when you remove the ability, all it does is remove it from your learnt skills

Interesting. As this is a system, a demo map would help for clarification. And yes, it would help greatly if you could get the system to work without taking up 3 hero abilities.
 
T

Twyddli

Guest
> As this is a system, a demo map would help for clarification.

I accadentally forgot to click uplode, :eek:

Its up there now, and i had to fix it up a tiny bit so that you can only get 3 attributes per hero level, and not 4 ;) it should work now.
 

DuckieKing

Elitist Through and Through
Reaction score
51
AHA! I remembered how to attach a struct to a unit. I didn't think of it's because it's so hilariously simple.
Code:
  call SetUnitUserData(theUnit, unitData)
If you need help with this I'll gladly give it, but basically what I'm suggesting you do is create a new variable type that can hold as many integers, reals, units, etc. that you want to attach to a unit or item. You'd be using this initially to store the number of bonus stats a hero has to apply. The reason you'd need structs to do this, though, is because it's infinitely multiinstanceable, and intuitive, if you understand the language. That might be problem, though, since it's a bit more complex than Jass. :p
 
T

Twyddli

Guest
:eek: I don't even really know JASS, I don't even understand properly what you are suggesting. :O if you can expain it in even more detail, for a really newbie, then maybe ill understand ;)
 

DuckieKing

Elitist Through and Through
Reaction score
51
Crash course in Jass/C! Though technically a struct contains only member data (variables) and no member functions (methods).
JASS:
struct unitData //this is a new variable and is declared like any other: "local real currentHP" turns into "local unitData uD"
  unit subject
  real currentHP
  real maxHP //these are the variables created when you create the struct unitData, and any unitData you create is the combined size of all its variables

  method DamageUnit takes real damage returns nothing  //a method is like the Actions part of a trigger; it "takes" variables like a real or integer so that it does something different every time, otherwise it'd be worthless; returns is not important right now
    call SetUnitState(this.subject, UNIT_STATE_LIFE, GetUnitState(this.subject, UNIT_STATE_LIFE)-damage) //"SetUnitState" is used to change a unit's current life or mana without firing damage triggers; this.subject refers to the unit variable in the struct, named "subject"; "this." is just a pointer to the struct; "GetUnitState" to get the unit's current life, "-damage" to get the unit's current life minus the damage being taken
  endmethod
endstruct

Read it, let it soak in, type in your question but don't hit submit, read it again, then post your questions. It's a lot to take in at once. You might wanna try some of the Jass tutorials floating around in this section to learn the syntax.

edit: You know about custom values, right? You can give a unit an integer, and then you can get the integer from a trigger. It's better than a global.

To make it even BETTER, you can set the unit's custom value to be a struct, which is a user-created variable that can contain other variable types.

For example, the base types in C, the language WC3 was written in, are in short float (real), int (integer), and char (string). From that, Blizzard made the other variable types containing their own variables, or member data: a unit contains max life (real), current life (real), max mana (real), current mana (real), move speed (integer), attack range (integer), attack damage (a whole bunch of integers), etc.

In short, a struct is a variable that holds the values for other variables. This can be used by you to hold custom unit data such as extra stat points, extra spell damage, number of xx ability that has been stacked on a unit, and hold it all by using a unit's custom value, allowing you to do many things to many units without needing massive unit and player arrays.

I did not mean to type a term paper. Oops.
 
T

Twyddli

Guest
Ok i have read it a few times, And i think im gettin gbits of it. I see how this.subject is a unit. But do you have to set unit subject? do you have to set the real values current HP and max HP? Im also not entirely sure on what the struct UnitData is. Like is it kinda like floating information that you can grab just like a variable? And do does your trigger put subject, maxHP and CurrentHP into UnitData?

I can see what is going on in this triggers method i think.
It takes a real (Please Explain, im a little fuzzy what this meens.)
Then it sets the life of Subject(Thats a unit) to its current life - damage.

Also, Does the Struct contain its variables AND the Method? is that why you end struct after the method has happened? And not when the Struct has done every thing.

What exactly does the Struct do in this trigger? is it stting everything up to say that these three things are in this Struct?

and lastly, I will look at some tutorials.
Thanks ;)
 

DuckieKing

Elitist Through and Through
Reaction score
51
You picked it up quite fast. I shall now tower-quote.
What exactly does the Struct do in this trigger? is it stting everything up to say that these three things are in this Struct?
I put the end of your post up here for a reason: This is not a trigger. It has no events and the only action has to be called inside a function. A function is just like a method, except methods are exclusive to structs. Functions are how everything is done in Jass, and I'll show how structs work in functions...

do you have to set unit subject? do you have to set the real values current HP and max HP?
Yes. This is done in a Jass trigger with the following calls:
JASS:
local unit u=CreateUnit(Player(0), 'hfoo', 0, 0, 0) //"native CreateUnit takes player whichPlayer, integer unitTypeId, real x, real y, real facing returns unit"...I assign a newly created unit to "u"; "u" is assigned the "returned" value of "CreateUnit"
local unitData uD=unitData.create() //the struct is created and given the name uD
set uD.subject=u
set uD.maxHP=GetUnitState(uD.subject, UNIT_STATE_MAX_LIFE)
set uD.currentHP=uD.maxHP //you use "uD.", the name of the struct created and a period, to point to the struct, and currentHP/maxHP to point to the specific variables
call uD.DamageUnit(50)
I want it clear, though, that doing this will not actually modify the unit's health as perceived by the health bar or numbers under its icon. The struct's member data and method are only meant to supply an analogy.

It takes a real (Please Explain, im a little fuzzy what this meens.)
Fuzzy on what a real is or what the method does? The method modifies the struct's reals, which are numbers that can be fractional (2.5, 0.75) as opposed to integers, which are whole numbers (2, 0).

Also, Does the Struct contain its variables AND the Method? is that why you end struct after the method has happened? And not when the Struct has done every thing.
Not exactly. Everything between struct and endstruct is the struct declaration. It tells the game engine what to create when create.<structname>() and <structname>.<methodname>() are called.

Im also not entirely sure on what the struct UnitData is. Like is it kinda like floating information that you can grab just like a variable? And do does your trigger put subject, maxHP and CurrentHP into UnitData?
Have these been answered yet?

The struct is your own variable type. It is in essence a variable, which is a block of memory set aside by the program to contain a series of 1's and 0's. The difference between a struct/unit and an integer is purely one of style and implementation. When an integer is created, 4 bytes are set aside. When a struct containing two integers is created, 8 bytes are set aside.
 
T

Twyddli

Guest
Ok, i think i got some more of it. You need one trigger that fires off the Struct like a unit takes damage, then it does everything. But before the Struct is fired, you need to have already set the three (i forgot what they are called) Unit, Real and Real, or it wont work? is that right?

I want it clear, though, that doing this will not actually modify the unit's health as perceived by the health bar or numbers under its icon. The struct's member data and method are only meant to supply an analogy.
What exactly would you use this for? Like could you give me some examples? ;) Thanks heaps for helping
me.

Let me have a quick go at some free hand JASSing, so i can ask if i got it right.

Code:
function Test actions takes nothing returns nothing
    call set subject = Attacked unit
    call set maxHP = max HP of attacked unit
    call set currentHP = current HP of attacked unit
    call uD.DamageUnit(50)
endfunction
//======================
The event stuff create trigger blah blah
the event that says a unit is attacked
So this one up here ^ would set everything, then run this one down bottom.(Your one)
Code:
struct unitData //this is a new variable and is declared like any other: "local real currentHP" turns into "local unitData uD"
  unit subject
  real currentHP
  real maxHP //these are the variables created when you create the struct unitData, and any unitData you create is the combined size of all its variables

  method DamageUnit takes real damage returns nothing //a method is like the Actions part of a trigger; it "takes" variables like a real or integer so that it does something different every time, otherwise it'd be worthless; returns is not important right now
  call SetUnitState(this.subject, UNIT_STATE_LIFE, GetUnitState(this.subject, UNIT_STATE_LIFE)-damage) //"SetUnitState" is used to change a unit's current life or mana without firing damage triggers; this.subject refers to the unit variable in the struct, named "subject"; "this." is just a pointer to the struct; "GetUnitState" to get the unit's current life, "-damage" to get the unit's current life minus the damage being taken

  endmethod
 endstruct

Is that what it basically is? If it isn't please tell me ;)
Thanks a billion! :D :D :D :D
 

DuckieKing

Elitist Through and Through
Reaction score
51
In real programming, the member data are private, meaning they cannot be modified except by member functions, which would be the methods.

It is BAD practice to "set uD.currentHP". Instead, you would have seperate methods to do this, like "call uD.DamageUnit".

The purpose of structs and classes in real programming is encapsulation. Encapsulation is the idea that tasks should be as seperate as possible to make configuration and maintenance of code simpler and clearer.

The purpose of structs in WC3 is attaching multiple variables to one. By doing this you easily increase multiinstanceability of almost any triggered effect you can think of, including this stat system. Example...
JASS:
struct unitData
  unit u //a variable is added to reference the unit whose data is held
  integer statCredits=4 //this variable is initialized to 4, so that a new hero has 4 stats to spend

  method ModifyStatCredits takes integer statBonus returns nothing //takes an integer in case you want to add quests that give different bonus stats than leveling does; also allows removal of credits in case it were ever necessary, note that the credits can be negative so that the spellbook won&#039;t be activated at the next level (or they&#039;ll just have fewer stats)
    if this.statCredits &lt;= 0 and this.statCredits+statBonus &gt; 0 then
      call SetPlayerAbilityAvailable(this.u, &#039;A000&#039;, true) //reactivates the spellbook if it wasn&#039;t active and credits are now positive
    endif
    set this.statCredits=this.statCredits+statBonus
  endmethod
    

  method BuyStat takes integer a returns nothing //this method will remove one stat credit and raise the stat
    set this.statCredits=this.statCredits-1
    if a == &#039;A001&#039; then
      call this.RaiseAgi()
    endif
    if a == &#039;A002&#039; then
      call this.RaiseInt()
    endif
    if a == &#039;A003&#039; then
      call this.RaiseStr()
    endif
    if this.statCredits &lt;= 0 then
      call SetPlayerAbilityAvailable(this.u, &#039;A000&#039;, false) //here we disable the spellbook if there are no more stats to buy, this will close the spellbook like if you run out of hero points in the ability selection screen
    endif
  endmethod

  method RaiseAgi takes nothing returns nothing //encapsulation specifies that we let functions do as little as possible on their own
    call SetHeroAgi(this.u, GetHeroAgi(this.u)+1)
  endmethod
  method RaiseInt takes nothing returns nothing //no need for another empty line, all three of these methods do the same thing
    call SetHeroInt(this.u, GetHeroInt(this.u)+1)
  endmethod
  method RaiseStr takes nothing returns nothing
    call SetHeroStr(this.u, GetHeroStr(this.u)+1)
  endmethod
endstruct


Whew, a lot of work went into that. It was mostly in the comments. You should write comprehensive comments for yourself, too, and make use of whitespace. It makes maintaining code easier, as you might forget the purpose of what you've written before.

edit: I forgot to show how structs work with triggers. x_x An example trigger utilizing this struct would be as follows:
JASS:
function HeroLevelsUp takes nothing returns nothing
  local unitData uD=GetUnitUserData(GetTriggerUnit()) //creates a local struct using the &quot;TriggerUnit&quot;&#039;s custom value; &quot;GetUnitUserData&quot; will return the struct which is assumed to have been attached to the triggering hero when it was created, then assigns it to uD; &quot;TriggerRegisterAnyUnitEventBJ&quot; will allow you to use both &quot;GetTriggerUnit&quot; and &quot;GetTriggerPlayer&quot; with all events
  call uD.ModifyStatCredits(4) //calls the ModifyStatCredits method and sets a=4
  call uD.destroy() //this is important; if you don&#039;t destroy a local struct it wastes the memory it occupies as it can&#039;t be used once the function ends
endfunction

function Init_Trig_Hero_Levels_Up takes nothing returns nothing //this function runs at map initialization and creates the trigger
  set gg_trg_Hero_Levels_Up=CreateTrigger() //&quot;gg_trg_Hero_Levels_Up&quot; would be the variable name of the trigger &quot;Hero Levels Up&quot;
  call TriggerRegisterAnyUnitEventBJ(gg_trg_Hero_Levels_Up, EVENT_PLAYER_HERO_LEVEL) //this tells the trigger to fire when a hero of any player levels up
  call TriggerAddAction(gg_trg_Hero_Levels_Up, function HeroLevelsUp) //this tells the trigger to perform this function when it is fired by any hero leveling
endfunction //all in all a standard trigger init function: function init-&gt;set trigger=create trigger-&gt;call triggerregister-&gt;call triggeraddaction

Well gee, I pretty much just wrote your stat system for you if you choose to use structs. You can do the part that raises the stats and attaches the struct though. :)
I'll link some tools you need to use structs and Jass.
Jass NewGen Pack, to use structs without compile errors
 
T

Twyddli

Guest
Ok, so do the Structs kinda check constantly if something is going on, and if one this is going on it changes something, else it cahnges something else? a bit confusing let me try again.

Structs constantly check, in this instance, what an integer is. If the integer is higher than 0 then it shows an ability, if the integer is 0 or less, it hides the ability?

I think i am beginning to see how this all works. They don't use events, they are just constantly running and checking to see if an integer = 0 or greater than 0. Correct me if i am wrong.
When or where do you set the variable statBonus and the variable a.
I don't see anywhere that you set them?

Could you maybe go through your trigger explaining what each part does? and what each bit of each line does? If its not too much trouble.

I find i understand this slightley but then i look at it again and i don't know whats going on. I'm a little confused.
I will +Rep you! ;)
 

DuckieKing

Elitist Through and Through
Reaction score
51
The variables in a struct are just like variables outside a struct; they can be called in any function the struct is created.

The methods are just functions that can only be called in a function that has this struct. They don't run on their own; they need a trigger to call them.

This struct would check the number of stat credits a hero would have whenever you called ModifyStatCredits, and I did the naming conventions wrong. -.- All the methods should be capitalized. Fixing now.
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • WildTurkey WildTurkey:
    is there a stephen green in the house?
    +1
  • The Helper The Helper:
    What is up WildTurkey?
  • The Helper The Helper:
    Looks like Google fixed whatever mistake that made the recipes on the site go crazy and we are no longer trending towards a recipe site lol - I don't care though because it motivated me to spend alot of time on the site improving it and at least now the content people are looking at is not stupid and embarrassing like it was when I first got back into this like 5 years ago.
  • The Helper The Helper:
    Plus - I have a pretty bad ass recipe collection now! That section of the site is 10 thousand times better than it was before
  • The Helper The Helper:
    We now have a web designer at my job. A legit talented professional! I am going to get him to redesign the site theme. It is time.
  • Varine Varine:
    I got one more day of community service and then I'm free from this nonsense! I polished a cop car today for a funeral or something I guess
  • Varine Varine:
    They also were digging threw old shit at the sheriff's office and I tried to get them to give me the old electronic stuff, but they said no. They can't give it to people because they might use it to impersonate a cop or break into their network or some shit? idk but it was a shame to see them take a whole bunch of radios and shit to get shredded and landfilled
  • The Helper The Helper:
    whatever at least you are free
  • Monovertex Monovertex:
    How are you all? :D
    +1
  • Ghan Ghan:
    Howdy
  • Ghan Ghan:
    Still lurking
    +3
  • The Helper The Helper:
    I am great and it is fantastic to see you my friend!
    +1
  • The Helper The Helper:
    If you are new to the site please check out the Recipe and Food Forum https://www.thehelper.net/forums/recipes-and-food.220/
  • Monovertex Monovertex:
    How come you're so into recipes lately? Never saw this much interest in this topic in the old days of TH.net
  • Monovertex Monovertex:
    Hmm, how do I change my signature?
  • tom_mai78101 tom_mai78101:
    Signatures can be edit in your account profile. As for the old stuffs, I'm thinking it's because Blizzard is now under Microsoft, and because of Microsoft Xbox going the way it is, it's dreadful.
  • The Helper The Helper:
    I am not big on the recipes I am just promoting them - I use the site as a practice place promoting stuff
    +2
  • Monovertex Monovertex:
    @tom_mai78101 I must be blind. If I go on my profile I don't see any area to edit the signature; If I go to account details (settings) I don't see any signature area either.
  • The Helper The Helper:
    You can get there if you click the bell icon (alerts) and choose preferences from the bottom, signature will be in the menu on the left there https://www.thehelper.net/account/preferences
  • The Helper The Helper:
    I think I need to split the Sci/Tech news forum into 2 one for Science and one for Tech but I am hating all the moving of posts I would have to do
  • The Helper The Helper:
    What is up Old Mountain Shadow?

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top