HeroEngine Forums

HeroEngine Developers => Developer Created Tutorials => Topic started by: LastJudge on Jan 21, 12, 05:17:31 PM

Title: Simple mana system
Post by: LastJudge on Jan 21, 12, 05:17:31 PM
Time for another tutorial :)

I'm only going to make it very simple, you can expand it to fit your needs. I am going to cover adding new attribute to character which will be used to cast spells and also make spells use it, I'm not going to cover adding this new attribute to your status bar (I might do a status bar tutorial later, but I don't think it's needed).

Note: I did not actually test this tutorial. I am using a bit more complex system that is specific to my game. So if something doesn't work as intended, just tell me and I'll try and fix it.

1. Let's add mana to our character
Open DOM Editor: Windows -> DOM Editor
Add new field to the client side. Call it E_manaPoints and make it an integer.
(http://img840.imageshack.us/img840/8509/ms01.jpg)


2. Copy it to server.


3. Go to Server DOM, click on your E_manaPoints field and set Destination Field (client) to "E_manaPoints" and set Delta Priority to 1. Also set Change Callback to true (even though it's not changed to that value in the picture).
(http://img31.imageshack.us/img31/1139/ms02.jpg)
Note: You should have E_manaPoints instead if TS_powerPoints.


4. Now let's add our field to character. Find E_CommonCharacter in client DOM. Add new field and choose E_manaPoints, click the Save button.
(http://img832.imageshack.us/img832/456/ms03d.jpg)


5. Do the same for E_CommonCharacter in server DOM and also check the 'R' checkbox (it indicates that this field is going to be replicated), click the Save button. That's it for clicking, it's time to write some code now.
(http://img192.imageshack.us/img192/4323/ms04g.jpg)
Note: Yours should be named E_manaPoints


6. Open E_CommonCharacterClassMethods server script. In the InitCommonChatacter() method, we will need to add an initial value for mana. Modify this
Code: [Select]
  me.E_hitPoints = 100
  me.E_isDead = false
to
Code: [Select]
  me.E_hitPoints = 100
  me.E_manaPoints = 100
  me.E_isDead = false

We also need to add a method that will allow us to modify mana upon casting a spell.
Code: [Select]
method AdjustMana(manaDelta as Integer, ability as NodeRef of Class E_Ability)
  me.E_manaPoints = MiscUtils:Min(me.E_manaPoints + manaDelta, me.E_manaPoints) 
.

Find the ApplyDeath method and modify it so character won't have mana when dead. Modify this
Code: [Select]
me.E_isDead = true
me.E_hitPoints = 0
to
Code: [Select]
me.E_isDead = true
me.E_hitPoints = 0
me.E_manaPoints = 0

Find ApplyLife method and modify this
Code: [Select]
me.E_hitPoints = 100to this
Code: [Select]
me.E_hitPoints = 100
me.E_manaPoints = 100

Find E_RegenTimer_tick() method and add a new line like this
Code: [Select]
me.E_manaPoints = MiscUtils:Min(me.E_manaPoints + 10, 100)Note: In case you already did the "combat tutorial" you might want to have different regeneration values for when the character is in combat and different when out of combat.

We're done with this script, so click "Compile" and then "Submit" and close the script.


7. Open server script called E_playerCharacterClassMethods, locate the ProcessXPGain() method and modify this
Code: [Select]
me.E_hitPoints = 100to this
Code: [Select]
me.E_hitPoints = 100
me.E_manaPoints = 100

Compile and Submit the script and close it afterwards.


8. Open server script called E_CharacterCreationSystemClassMethods. Find the HE_CCSCharacterActivated method and modify this
Code: [Select]
char.E_hitPoints = 100to this
Code: [Select]
char.E_hitPoints = 100
char.E_manaPoints = 100

Compile, Submit, Close ...


9. Now we are going to modify the ability scripts so they use mana too. I'm not going to write code for each of those scripts as it's pretty much the same for each of them. Now as abWeaponStrike and abSwipe are kinda basic attacks, we won't modify these (but you can of course, it's up to you).

Open abFireball server script (repeat for abHeal and abRubyFire too)
add function for getting a mana cost
Code: [Select]
shared function GetManaCost() as Integer
  return 50
.
Note: replace 50 with any number you see fit as the cost. Remember we have set 100 as maximum mana, so it would be nice to keep this number lower than that.

Now we need to modify ApplyEffects function to look like this
Code: [Select]
shared function ApplyEffects( owner as NodeRef of Class E_CommonCharacter, target as NodeRef, ability as NodeRef of Class E_Ability )
cost as Integer = GetManaCost()
  if (owner.E_manaPoints >= cost)
    abEffects:ApplyDirectDamage( owner, target, ability, GetMinDamage(), GetMaxDamage() )
    owner.AdjustMana(-cost, ability)
  .
.


10. We should have a working mana system now. Just make sure to add a mana gauge to your status bar or otherwise you won't be able to see how much mana you have.
Title: Re: Simple mana system
Post by: runningbird on Jan 21, 12, 10:53:24 PM
Great tutorial now I can add Energy and stamina to my players!

Keep up the good work.

Thanks,
Jason
Title: Re: Simple mana system
Post by: cloudnine on Jan 22, 12, 01:58:50 PM
real cool, you make it look easy, nice

I think i got it to work using 2 mana bars
Code: [Select]
shared function ApplyEffects( owner as NodeRef of Class E_CommonCharacter, target as NodeRef, ability as NodeRef of Class E_Ability )
acost as Integer = GetActionCost()
ecost as Integer = GetEnergyCost()
  if (owner.Action >= acost) and  (owner.Energy >=ecost)
  abEffects:ApplyDirectDamage( owner, target, ability, GetMinDamage(), GetMaxDamage() )
  owner.AdjustAction( -acost, ability )
  owner.AdjustEnergy( -ecost, ability )
  .
.
I set the action cost to 50 energy to 10 and can fire 3 fireballs before they dont do any damage
the fx still plays though -
Title: Re: Simple mana system
Post by: LastJudge on Jan 22, 12, 04:43:50 PM
Well in my game, players will be kinda able to choose what sort of power to use (there are 4 available, so I made 4 different costs for stuff and so :) ). They are not used all together though, so I don't know how it works out for you.

I wondering what to do next ... either some kind of spellbook so I can drag and drop spells and so or inventory system (which is most probably gonna be very similar).
Title: Re: Simple mana system
Post by: runningbird on Jan 23, 12, 09:10:51 AM
Either would be a great start... as all of use are looking to do an inventory or probably some kind of spell system and any example would be a great start.

Title: Re: Simple mana system
Post by: LastJudge on Jan 23, 12, 10:01:01 AM
Yup, I know many of you want an example of that. Dunno when I'll find some time to do it, cause I have like 3 exams this Wednesday so it would be nice to learn too :D Maybe afterwards or during the weekend I might try :)
Title: Re: Simple mana system
Post by: RacerX on Jan 24, 12, 12:30:18 PM
I thank you for this script. I did have one compile error which has had me looking like mad for a solution. this method "AdjustMana" throws a compile error.

method 'AdjustMana' not found.

on this code

shared function ApplyEffects( owner as NodeRef of Class E_CommonCharacter, target as NodeRef, ability as NodeRef of Class E_Ability )
cost as Integer = GetManaCost()
  if (owner.E_manaPoints >= cost)
    abEffects:ApplyDirectDamage( owner, target, ability, GetMinDamage(), GetMaxDamage() )
    owner.AdjustMana(-cost, ability)
  .
.

Any help to solve this problem would be great and thanks for this.
Title: Re: Simple mana system
Post by: LastJudge on Jan 24, 12, 12:42:49 PM
The error means to don't have an 'AdjustMana' method. If you happened to overlook it's creation, it's in step 6. If you are sure you created it, check for any spelling mistakes in it's name :)
Title: Re: Simple mana system
Post by: RacerX on Jan 24, 12, 02:29:12 PM
The error means to don't have an 'AdjustMana' method. If you happened to overlook it's creation, it's in step 6. If you are sure you created it, check for any spelling mistakes in it's name :)

thanks very much. Awesome script works great!
Title: Re: Simple mana system
Post by: LastJudge on Jan 24, 12, 03:50:11 PM
Glad it works :)
Title: Re: Simple mana system
Post by: TheAssassin on Jan 24, 12, 09:32:41 PM
hmmm, can I apply this to other source of cost?(probably like mana only color would be different)
examples:

 <AP bar>(red)
<SP bar>(yellow)
<EP bar>(light green)
Title: Re: Simple mana system
Post by: LastJudge on Jan 25, 12, 12:43:10 AM
I see no reason why you couldn't. It's just cost, you can apply it to mana, energy, life itself too, fury, rage, stamina, force, or however else you want to name your resource. Also the color doesn't matter too. And you can make your spell use all the costs at once.
Title: Re: Simple mana system
Post by: CaSpivey on Jan 25, 12, 10:15:35 AM
Im just having an issue getting the UI to register changes with manaPoints, I know its working correctly because if I set the mana cost higher than the base mana the attack does not truly work it plays the animation but no damage is done.

Any suggestions on where to start looking?
Title: Re: Simple mana system
Post by: LastJudge on Jan 25, 12, 02:48:50 PM
Have you tried adding some println lines to places where the mana change should be triggered from? If it's not triggered from where is should be (on replication or upon receiving a lightweight event), then just try changing Change Callback to yes for E_manaPoints or however you call your field ;)
Title: Re: Simple mana system
Post by: GARDrealms on Feb 06, 12, 09:17:04 PM
During me edits following this tut I got an error compiling so I backed out the edits and now I get errors pointing to the lines below.:

me.name
killer.name
killer.name     me.name

from each line.




  where killer is kindof E_playerCharacter
    msg as String = " You killed " + me.name + "."     <---------------------
    where me is kindof E_nonPlayerCharacter
      // player killed a creature, so give him/her rewards
      xp as Integer = 10 + me.E_level
      killer.E_experiencePoints = killer.E_experiencePoints + xp
      msg = msg + "  You gain " + xp + "xp and "
     
      wealth as Integer = RandomInteger( 12, 22 )
      killer.E_wealth = killer.E_wealth + wealth
      msg = msg + " collect " + wealth + " gold from it!"
    .
   
    // do messaging to the killer
    $CHAT.ChatPlayer( killer, "System", msg )
    add back killer to exclude
  .
 
  // do messaging to target if appropriate
  if me is kindof E_playerCharacter
    $CHAT.ChatPlayer( me, "System", killer.name + " killed you " )      <--------------
    add back me to exclude
  .
 
  // do messaging to everyone else
  $CHAT.ChatExcludeList( exclude, "System", killer.name + " killed " + me.name + "." )         <---------------
Title: Re: Simple mana system
Post by: GARDrealms on Feb 06, 12, 09:49:46 PM
And my labels for my Char and NPCs are blank, and fell free to cal me a moron if you fell like it.
Title: Re: Simple mana system
Post by: LastJudge on Feb 07, 12, 03:02:03 AM
Hmm ... I don't really think that me.name and/or killer.name has something to do with this tutorial.

Next time please post a script name too, so it's easier to find it, but this one should be E_CommonCharacterClassMethods if I remember correctly.

It would be nice if you posted the exact error you are getting, because this way it's hard to guess what's wrong.
Title: Re: Simple mana system
Post by: GARDrealms on Feb 07, 12, 05:37:53 AM
19:51:02: !ERROR!System:Replication error: Replication error with node 9223372058843664358 'field ID: 9223372059023664302 not present in HeroClass(4611686018428887921)::getField on node 9223372058843664358' doing ReplicationGroupBase.cpp(2056):pVar = pNode->getField(mFieldBeingSet)
19:51:02: !ERROR!System:Replication error: Replication error with node 9223372058878664334 'field ID: 9223372059023664302 not present in HeroClass(4611686018428887923)::getField on node 9223372058878664334' doing ReplicationGroupBase.cpp(2056):pVar = pNode->getField(mFieldBeingSet)
19:51:02: !ERROR!HeroScript::HeroMachine::ScriptError:Invalid GUI Layer [1] on control: level (1000000252) layer(1)
19:51:02: !ERROR!System:SCRIPT ERROR: In function ScriptError: Invalid GUI Layer [1] on control: level (1000000252) layer(1)
02/06/2012 19:50:06
Call trace:
  Script GUIControlClassMethods line 73 me[1000000252]
  Script GUIControlClassMethods line 50 me[1000000252]
starting method/function MOVETOGUILAYER
starting me[id=1000000252 class=GUILabel]
19:51:02: System:SCRIPT[E_ExperienceBarClassMethods]:xp: 0
19:51:02: System:SCRIPT[E_ExperienceBarClassMethods]:last: 250
19:51:03: !ERROR!System:Replication error: Replication error with node 9223372058522664480 'field ID: 9223372059023664302 not present in HeroClass(4611686018428887923)::getField on node 9223372058522664480' doing ReplicationGroupBase.cpp(2056):pVar = pNode->getField(mFieldBeingSet)
Title: Re: Simple mana system
Post by: LastJudge on Feb 07, 12, 07:51:54 AM
I meant errors you get when trying to compile it when you were doing this tutorial.
Title: Re: Simple mana system
Post by: GARDrealms on Feb 07, 12, 05:44:53 PM
sorry,
Error is:
Node variable dose not specify a class that contains the field name

E_CommonCharacterClassMethods
Title: Re: Simple mana system
Post by: LastJudge on Feb 08, 12, 01:55:44 AM
You probably forgot to create the E_manaPoints field for E_CommonCharacter in DOM editor.
Title: Re: Simple mana system
Post by: GARDrealms on Feb 08, 12, 04:51:58 PM
did it.. :-\
Title: Re: Simple mana system
Post by: CaSpivey on Feb 08, 12, 11:22:21 PM
Took me three times of doing and redoing this tutorial and working with everything to get it to work, I'm not exactly sure what mistake I made but it did help to start all over from the beginning as a simple typo could mess the whole system up.
Title: Re: Simple mana system
Post by: LastJudge on Feb 09, 12, 12:40:57 AM
Took me three times of doing and redoing this tutorial and working with everything to get it to work, I'm not exactly sure what mistake I made but it did help to start all over from the beginning as a simple typo could mess the whole system up.

Was there any part of the tutorial that caused confusion? Cause if yes, just tell me and I can try to rewrite that part to be more clear.
Title: Re: Simple mana system
Post by: elchettoloco on Mar 04, 12, 11:10:55 PM
Great Tutorial Judge!  All worked perfectly

I did implement the mana gauge on the status bar, however, when using the fireball ability the gauge does not move(it is at the default setting).  I'm taking it there is some association regarding this and I did check the xml and properties and did not find anything that tied the healthPanel and/or slider to any particular script.

Or perhaps I missed it.

Thanks anyway m8!
Title: Re: Simple mana system
Post by: LastJudge on Mar 05, 12, 01:08:14 AM
Well, as I didn't go through adding the mana gauge to your status bar, I didn't change one value for this tutorial, I guess I will update this tutorial when I'm on developer machine.

In the step 3, where you change values for the server side of mana points, you also need to set Change Callback to true.
Title: Re: Simple mana system
Post by: Lattam on Jun 04, 12, 09:51:52 AM
Great Tutorial. 

I was able to setup this up fairly easily.

Keep up the good work.
Title: Re: Simple mana system
Post by: LastJudge on Jun 04, 12, 05:23:29 PM
Thanks, I'm glad you liked it :)
Title: Re: Simple mana system
Post by: Hobbie on Jun 29, 12, 12:05:17 PM
Simple tutorial, but thanks for providing it!
Title: Re: Simple mana system
Post by: SurvivalInstincts04 on Nov 19, 12, 09:56:20 AM
Say if I wanted to have the mana subtract by 10 every second from 100 while sprinting and when at 0 disables sprint, how could this be achieved?
Title: Re: Simple mana system
Post by: LastJudge on Nov 25, 12, 01:56:09 PM
You can make a simple boolean to check whether the character is running or not. If it's running, subtract 10, if not, nothing happens. And after you subtract 10, check if mana is 0, if yes, set boolean for running to false.

I can provide you with some code later, but I'm not at my development machine right now.
Title: Re: Simple mana system
Post by: SurvivalInstincts04 on Nov 26, 12, 11:56:53 AM
your code would be most appreciated, I am not sure where to write the function either. I attempted to code it in both server side; Input_Movement and client side; E_ACCControllerClassMethods, both giving the same error; Node variable does not specify a class that contains the field E_fatiguePoints. (my mana variable's name)
Title: Re: Simple mana system
Post by: LastJudge on Nov 27, 12, 05:05:39 AM
your code would be most appreciated, I am not sure where to write the function either. I attempted to code it in both server side; Input_Movement and client side; E_ACCControllerClassMethods, both giving the same error; Node variable does not specify a class that contains the field E_fatiguePoints. (my mana variable's name)

I might have time to take a look at it during the weekend. Right now I'm very busy with some work for a client and I haven't really done much in HE during last 6 months, but I'll try to provide you with some code. :)
Title: Re: Simple mana system
Post by: Thazager on Dec 17, 12, 06:02:32 AM
I tried to do this a while back before finding this tutorial.
I mostly copied the health bar and added to the client scripts. I saw 2 steps I had not done, so got those done with this tutorial. I also added an E_regenManaTimer and set it up like the health one. Mine, however does not move.

Would that be because of the client side scripts also added in?
One thing that could be overlooked was the "set Change Callback to true". I missed that on the 1st tme, but adding it did not solve the problem.
Title: Re: Simple mana system
Post by: Hobbie on Dec 17, 12, 11:08:06 PM
My health slider works fine.  My mana one does not.  I need to take a peek at it in the next week or so - I'll post what I find if I don't see something else up first.  Busy week up through Christmas!
Title: Re: Simple mana system
Post by: Thazager on Dec 21, 12, 03:15:26 PM
Going through some of more files in search of another subject I found a section that might not have been covered. I added them in, but still the mana bar is not moving. When I target myself using tab, I notice the mana is changing, but the change does not show as you view it.

in cmdCommands on server side

under
      pc.E_hitPoints = 100
add
      pc.E_manaPoints = 100
Title: Re: Simple mana system
Post by: Viper155 on Jan 06, 13, 04:00:08 AM
Can anyone wright a quick tutorial on how to get this below the health status bar?

Thanks!
Title: Re: Simple mana system
Post by: Thazager on Jan 06, 13, 04:29:16 AM
For the GUI addition:

under HeroScript tab open GUIeditor

on the gui editor panel, double click on e_StatusBar to open the gui
on the properties panel, select e_StatusBar  for adding a gui as a child
on the gui editor panel, double click on _panel  to add it to the gui
on the properties panel, select _panel to change its values

" ", change name to manaPanel    hit enter
" ", set position to 6,39     hit enter
" ", set size to 160,7     hit enter
" ", set defaultStatePresentation color  to  0,0,0,1    hit enter

on the gui editor panel, double click on _panel to add it to gui as a child
on the properties panel, select _panel to change its values

" ", change the name to manaSlider    hit enter
" ", set size to 80,7     hit enter
" ", set defaultStatePresentation color  to  0,0,1,1    hit enter

top left side hit the save Icon, then the close Icon.


for diff colors set the rgb of that last field
red = 1,0,0,1
green = 0,1,0,1
blue = 0,0,1,1
yellow = 1,1,0,1
purple = 1,0,1,1
cyan = 0,1,1,1
black = 0,0,0,1
white = 1,1,1,1
Title: Re: Simple mana system
Post by: Viper155 on Jan 06, 13, 05:11:42 AM
wow Thazager, awesome!

One last thing.  Has anyone been able to get the mana to update real time as its used just like the hitpoint bar?
Title: Re: Simple mana system
Post by: Thazager on Jan 06, 13, 05:44:09 AM
yes, there are some lightweightEventRaised() functions that seem to be making the script work. I had to double check everything from the begin of tutorial to end to see if there were any additions to making it work. I basically did a search on all scripts (client and server) and added in the manaPoints where the hitpoints were. Some of the functions were a little different as they did not need a target.

Also make sure the you addeed the values to the DOM class, after declaring as fields.
Title: Re: Simple mana system
Post by: Viper155 on Jan 07, 13, 01:01:05 AM
well i was able get my targets mana bar to update but no such like with my own.

What am i missing?


I have this in there as well
Code: [Select]
is "e_hitpoints"     
      $LightweightEvents.raiseLightweightEvent(updateNode, "hpUpdated", 0)
    .
     is "e_manapoints"     
      $LightweightEvents.raiseLightweightEvent(updateNode, "mpUpdated", 0)
    .
Title: Re: Simple mana system
Post by: Thazager on Jan 07, 13, 04:10:07 AM
Places I added it in script. I also added a E_regenManaTimer with it.

client side:
script = E_nonplayerCharacterClassMethods  in _OnReplicationFieldUpdated()
    is "e_manaPoints"
      $LightweightEvents.raiseLightweightEvent(updateNode, "manaUpdated", 0)
    .

script = E_playerCharacterClassMethods  in _OnReplicationFieldUpdated()
    is "e_manaPoints"     
      $LightweightEvents.raiseLightweightEvent(updateNode, "manaUpdated", 0)
    .

script = E_StatusBarClassMethods  in lightweightEventRaised()
    is "manaUpdated"
      char as NodeRef of Class E_CommonCharacter = subject
      if char != None
        me.SetEND(char.E_manaPoints)
      . 
    .

script = E_StatusBarClassMethods  
Code: [Select]
method SetMana(ma copies Integer)
  if ma < 0
    ma = 0
  .
  manaSlider as NodeRef of Class GUIControl = FindGUIControlByName(me, "manaPanel.manaSlider")
  manaSlider.removeAnimations()
  var size = -1.0 * ma

  animationString as String = "size.x,"
  animationString = animationString + manaSlider.size.x + ","
  animationString = animationString + size +","
  animationString = animationString + .1 + ","
  animationString = animationString + 1 + ","
  animationString = animationString + "false,"
  animationString = animationString + "LINEAR," 
  animationString = animationString + "false,"
  animationString = animationString + "0,"
  animationString = animationString + "slide"
 
  GUIAnimation:addAnimation(manaSlider, "Interpolate", animationString)
.

script = E_TargetCircleClassMEthods  in E_UpdateTargetCircle()
      $LightweightEvents.addLightweightEventListener(realtarget, "manaUpdated", statusbar)
      statusbar.SetMana(realtarget.E_manaPoints)


server side:
script = cmdCommands in HE_ProcessCommandInput()
      pc.E_manaPoints = 100

script = E_characterCreationSystemClassMethods  in HE_CCSIsAlphaCharacter()
  char.E_manaPoints = 100

script = E_CommonCharacterClassMethods  in InitCommonCharacter()
  me.E_manaPoints = 100

  if( me.E_regenManaTimer.timerState == ON )
    me.E_regenManaTimer.stop()
  .
  me.E_regenManaTimer.fireRate = 00:00:01
  me.E_regenManaTimer.start()


method AdjustManaPoints( manaDelta as Integer, ability as NodeRef of Class E_Ability )
  me.E_manaPoints = MiscUtils:Min( me.E_manaPoints + manaDelta, 100 )
.

in ApplyDeath()
  me.E_manaPoints = 0

in ApplyLife()
  me.E_manaPoints = 100

method E_regenManaTimer_tick()
  if me.IsDead()
    return
  .
  me.E_manaPoints = MiscUtils:Min( me.E_manaPoints + 10, 100 )
.

script = E_nonplayerCharacterClassMethods  in InitCommonCharacter()

method AdjustManaPoints( manaDelta as Integer, ability as NodeRef of Class E_Ability )
  parentClass::AdjustManaPoints( manaDelta, ability )         //  Let the parent class handle the actual Adjust mana.
  me.E_manaPoints = MiscUtils:Min( me.E_manaPoints + manaDelta, me.E_manaPoints )
.

script = E_playerCharacterClassMethods  in ProcessXPGain()
    me.E_manaPoints = 100

script = E_characterCreationSystemClassMethods  in HE_CCSCharacterActivated()
  char.E_manaPoints = 100

script = skippy in HE_ProcessCommandInput() near     to "damage"
      pc.AdjustManaPoints(-5, ability)
Title: Re: Simple mana system
Post by: Viper155 on Jan 07, 13, 11:33:54 PM
Got it!!!  Thanks so much, I really appreciate it!
Title: Re: Simple mana system
Post by: Lithis on Feb 07, 13, 06:53:25 PM
Can anyone give me a little help getting the mana bar on gui to update in relation to % of mana, i added

Code: [Select]
method SetMana(ma copies Integer)
  if ma < 0
    ma = 0
  .
  manaSlider as NodeRef of Class GUIControl = FindGUIControlByName(me, "manaPanel.manaSlider")
  manaSlider.removeAnimations()
  var size = -1.0 * ma

  animationString as String = "size.x,"
  animationString = animationString + manaSlider.size.x + ","
  animationString = animationString + size +","
  animationString = animationString + .1 + ","
  animationString = animationString + 1 + ","
  animationString = animationString + "false,"
  animationString = animationString + "LINEAR," 
  animationString = animationString + "false,"
  animationString = animationString + "0,"
  animationString = animationString + "slide"
 
  GUIAnimation:addAnimation(manaSlider, "Interpolate", animationString)
.

To the E_StatusBarClassMethods checked that everything is named correctly etc but the mana bar just sits at 50%.
Title: Re: Simple mana system
Post by: Lithis on Feb 09, 13, 12:13:33 PM
Ive gone through every script that contains anything to do with health, hp etc and added whats needed for stamina and a mana bar. The server side all works it wont let me do stuff if mana or stamina is too low but i still cannot get the bars to update other than when i retab back to myself it updated the mana/stamina bar in target window.

Im pretty new at this but from all the different stuff ive tried im guessing all my server side code is fine its just the client side but ived checked over and over for anywhere that has anything to do with health and ive done everything people have said in this thread

Code: [Select]
script = E_nonplayerCharacterClassMethods in _OnReplicationFieldUpdated()
    is "e_manaPoints"
      $LightweightEvents.raiseLightweightEvent(updateNode, "manaUpdated", 0)
.

Code: [Select]
script = E_playerCharacterClassMethods in _OnReplicationFieldUpdated()
    is "e_manaPoints"     
      $LightweightEvents.raiseLightweightEvent(updateNode, "manaUpdated", 0)
    .

Code: [Select]
script = E_StatusBarClassMethods in lightweightEventRaised()
    is "manaUpdated"
      char as NodeRef of Class E_CommonCharacter = subject
      if char != None
        me.SetMana(char.E_manaPoints)
      . 
    .

Code: [Select]
method SetMana(ma copies Integer)
  if ma < 0
    ma = 0
  .
  manaSlider as NodeRef of Class GUIControl = FindGUIControlByName(me, "manaPanel.manaSlider")
  manaSlider.removeAnimations()
  var size = -1.0 * ma

  animationString as String = "size.x,"
  animationString = animationString + manaSlider.size.x + ","
  animationString = animationString + size +","
  animationString = animationString + .1 + ","
  animationString = animationString + 1 + ","
  animationString = animationString + "false,"
  animationString = animationString + "LINEAR," 
  animationString = animationString + "false,"
  animationString = animationString + "0,"
  animationString = animationString + "slide"
 
  GUIAnimation:addAnimation(manaSlider, "Interpolate", animationString)
.

Code: [Select]
script = E_TargetCircleClassMEthods in E_UpdateTargetCircle()
      $LightweightEvents.addLightweightEventListener(realtarget, "manaUpdated", statusbar)
      statusbar.SetMana(realtarget.E_manaPoints)

Even added

Code: [Select]
$LightweightEvents.addLightweightEventListener(addedNode, "manaUpdated", statusBar)
To the E_PlayerAccountClassMethods which had a lightevent for hp which wasnt mentioned and i just cannot find anything anywhere. Can someone please give some advice.
Title: Re: Simple mana system
Post by: Thazager on Feb 09, 13, 07:07:41 PM
The current manaPoints is set to update the value at 100 mana. If you are raising mana above this, using percent will change the slider to show the actual percent. Take a look at the expBar, it uses the percent in checking how much the bar should show on screen.
Title: Re: Simple mana system
Post by: Lithis on Feb 10, 13, 10:10:57 AM
The current manaPoints is set to update the value at 100 mana. If you are raising mana above this, using percent will change the slider to show the actual percent. Take a look at the expBar, it uses the percent in checking how much the bar should show on screen.

Im only using 100 mana and i cant get the mana bar to change atall, only way it changes is when i retab on myself the bar refreshing in the target gui each time i reselect.
Title: Re: Simple mana system
Post by: LastJudge on Feb 10, 13, 02:37:20 PM
Did you set Change Callback of your mana points to 'true'?
Title: Re: Simple mana system
Post by: Lithis on Feb 11, 13, 11:31:49 AM
Did you set Change Callback of your mana points to 'true'?

Yes still no luck =/
Title: Re: Simple mana system
Post by: Higler on Mar 29, 13, 06:42:26 PM
I have tried redoing this script from scratch three times in the past two days and I can't figure out where im messing up, maybe its really simple but i don't know im new to HSL. im getting two errors when trying to compile the commoncharacterclassmethod script

they are the same errors

 1. field 'manaPoints' not found in database:GOM;;lookupClassDefID (799): definition not found:manaPoints
 2. field 'manaPoints' not found in database:GOM;;lookupClassDefID (799): definition not found:manaPoints

I'm also getting a compile error when adding the mana to spells like abfireball

 1. Method 'AdjustMana' not found.

Title: Re: Simple mana system
Post by: LastJudge on Dec 12, 13, 03:30:17 PM
I had a small error in step 6,
me.manaPoints should've been me.E_manaPoints.

it's fixed now
Title: Re: Simple mana system
Post by: Eagleheart on Feb 25, 14, 01:23:48 PM
btw great tutorial only took me a couple hours to convert to something like what i want.
any ways i saw a few people wanting to know how to stop the function from working if your under the usable amount of mana.

to do this you just have to add these lines to your AbilityClassMethods on the server.
small fix just  in case you have not made  separate type for melee versus spells

Code: [Select]

   if ( me.E_script:GetAbilityType() == "Spell" )and ( me.E_script:GetManaCost() >= owner.E_manaPool)
      return ResultUtils:ErrorWithMessage( "Not Enough Mana to cast." )
  .

then in your abfireball ruby fire or any other spell just add server side
Code: [Select]

shared function GetAbilityType() as String
  return "Spell"
.

this would allow you to use the spells without having any costs setup in your melee abilities then you could add ones that would do the same checks for energy or stamina usage using the same basic setup this tutorial has done for mana
Title: Re: Simple mana system
Post by: xSystems on Mar 14, 14, 07:08:59 AM
Hello, im new here and here is my first question...

How i have to setup the "GUI Bar" for this? Name? Whateva.... the script works without any errors but i dont understand how i have to setup the bar ...
Title: Re: Simple mana system
Post by: Eagleheart on Mar 14, 14, 08:18:28 AM
find the E_Statusbar in the gui controls double click will open it

then do a search for _panel add it to the parent class at the top of the tree
then add another _panel under it

name the first panel manaPanel
name the one under that one manaSlider

set the sizes to match the health one then  you can either set a texture for the mana bar ina gui  texture file or you can do like the base health one and set the color useing the rgba values listed about for what ever color you wish.

use the health bar as a example how to setup the mana
Title: Re: Simple mana system
Post by: xSystems on Mar 14, 14, 10:59:27 AM
Hmmm then I've done right but it don't works :(

The bar is 50% full but don't move...

//Edit: oh i forgot a class :X

//EDIT: ok dont work ... dont understand why ... no errors but the bar don't move...

When i set the ManaCost of 100 then i can use and have to wait. It's for me: it works... (sry for ma bad english ^^)
Title: Re: Simple mana system
Post by: xSystems on Mar 18, 14, 05:23:40 AM
Sorry for new Post but i need help.... the System works, when i set the cost to 100 for fireball then i can cast it and have to wait. But the Manabar.... dont work :(
Title: Re: Simple mana system
Post by: Eagleheart on Mar 18, 14, 05:23:57 PM
post your code snypits from E_common Character(server)  and also status bar client and if you made any of the other suggested changes i made. those will help us help you.
Title: Re: Simple mana system
Post by: xSystems on Mar 19, 14, 03:07:50 PM
Code: [Select]
method InitCommonCharacter()
  // initialize abilities
  clear me.E_abilities destroy 
  foreach abilityGrant in me.GetAbilityGrants()   
    ability as NodeRef of Class E_Ability = MiscUtils:CreateNode( "E_Ability", IsPersistentNode( me ) )
    ability.E_script = abilityGrant
    me.AddAbility( ability )
  .
 
  // initialize stats
  me.E_hitPoints = 100
  me.E_manaPoints = 100
  me.E_isDead = false
 
  // start regen tick
  if( me.E_regenTimer.timerState == ON )
    me.E_regenTimer.stop()
  .
  me.E_regenTimer.fireRate = 00:00:01
  me.E_regenTimer.start()
.

method GetAbilityGrants() as List of ScriptRef
  // override to define ability grants
  abilityGrants as List of ScriptRef
  return abilityGrants
.

method AddAbility( ability as NodeRef of Class E_Ability ) 
  // add ability, association, etc
  add back ability to me.E_abilities
  AddAssociation( me, "base_hard_association", ability )
.

method FindAbilityByScript( script as ScriptRef ) as NodeRef of Class E_Ability
  // find ability by customization script
  foreach ability in me.E_abilities
    if( ability.E_script == script )
      return ability
    .
  .
  return None
.

method IsAttackable() as Boolean
  if me.E_isDead
    return false
  .
  if me.E_IsImmune
    return false
  .
  return true
.

method IsInCombat() as Boolean
  return false
.

method IsDead() as Boolean
  return me.E_isDead
.

method AdjustHealth( healthDelta as Integer, attacker as NodeRef, ability as NodeRef of Class E_Ability, isCritical as Boolean )
 
  // apply damage
  me.E_hitPoints = MiscUtils:Min( me.E_hitPoints + healthDelta, 100 )
 
  // raise remote event 
  interestSet as List of ID
  MiscUtils:QueryRemoteInterestSet( me.GetInterestSetSubjectNode(), interestSet )
  foreach accountID in interestSet   
    call client accountID E_CommonCharacterClassMethods:OnCombatEvent( ability.E_script, attacker, me, healthDelta, isCritical )
  .
 
  // handle death
  if( me.E_hitPoints <= 0 )
    me.ApplyDeath( attacker )   
  .
.

method ApplyDeath( killer as NodeRef of Class E_CommonCharacter ) as Boolean
  if me.E_isDead
    // how do you kill what is already dead?
    return false
  .
 
  me.E_isDead = true
  me.E_hitPoints = 0
  me.E_manaPoints = 0
  // TODO: play death animation
 
  // prep messaging
  exclude as List of ID
 
  where killer is kindof E_playerCharacter
    msg as String = "You killed " + me.name + "."
    where me is kindof E_nonPlayerCharacter
      // player killed a creature, so give him/her rewards
      xp as Integer = 10 + me.E_level
      killer.E_experiencePoints = killer.E_experiencePoints + xp
      msg = msg + "  You gain " + xp + "xp and "
     
      wealth as Integer = RandomInteger( 12, 22 )
      killer.E_wealth = killer.E_wealth + wealth
      msg = msg + " collect " + wealth + " gold from it!"
    .
   
    // do messaging to the killer
    $CHAT.ChatPlayer( killer, "System", msg )
    add back killer to exclude
  .
 
  // do messaging to target if appropriate
  if me is kindof E_playerCharacter
    $CHAT.ChatPlayer( me, "System", killer.name + " killed you!" )
    add back me to exclude
  .
 
  // do messaging to everyone else
  $CHAT.ChatExcludeList( exclude, "System", killer.name + " killed " + me.name + "." )
 
  // check for level up after other messaging is complete
  if killer is kindof E_playerCharacter
    killer.ProcessXPGain()
  .
  me.E_deathTimer.fireRate = me.GetDeathTime()
  me.E_deathTimer.start()
  where me is kindof E_AiAgent
    $E_CharDriver._DriverClearPoints( me, true )
  .
  return true
.

method ApplyLife() as Boolean
  if not me.E_isDead
    return false
  .
  me.E_isDead = false
  me.E_hitPoints = 100
  me.E_manaPoints = 100
  me._TeleportCharacter( me.GetRezzPosition(), me.GetRezzRotation() )
  where me is kindof E_playerCharacter
    target as Class _Target
    target._tgtID = me.GetMyAccount()
    clients as List of ID
    MiscUtils:QueryRemoteInterestSet(me.GetInterestSetSubjectNode(), clients)
    foreach c in clients
      $FXSYSTEM.SendFxToClient(c, 10, target, target)
    .
  .
  return true
.

method GetDeathTime() as TimeInterval
  return 0:0:05
.

method GetRezzPosition() as Vector3
  return me.GetPosition()
.

method GetRezzRotation() as Vector3
  return me.GetRotation()
.

method GetInterestSetSubjectNode() as NodeRef
  // return the subject node used by the spatial awareness system
  return me
.

method E_regenTimer_tick()
  if me.IsDead()
    return
  .
  if me.IsInCombat()
    return
  .
  me.E_hitPoints = MiscUtils:Min( me.E_hitPoints + 10, 100 )
  me.E_manaPoints = MiscUtils:Min(me.E_manaPoints + 10, 100)
.

method E_deathTimer_tick()
  me.ApplyLife()
  me.E_deathTimer.stop()
.

method AdjustMana(manaDelta as Integer, ability as NodeRef of Class E_Ability)
  me.E_manaPoints = MiscUtils:Min(me.E_manaPoints + manaDelta, me.E_manaPoints) 
.

Code: [Select]
method lightweightEventRaised(subject as ID, eventType as String, data as NodeRef)
  when eventType
    is "nameUpdated"
      char as NodeRef of Class E_CommonCharacter = subject
      if char != None
        me.SetName(char.name)
      .     
    .
    is "hpUpdated"
      char as NodeRef of Class E_CommonCharacter = subject
      if char != None
        me.SetHP(char.E_hitPoints)
      . 
    .
    is "mpUpdated"
      char as NodeRef of Class E_CommonCharacter = subject
      if char != None
        me.SetMP(char.E_manaPoints)
      . 
    .
  .
.
method SetName(name as String)
  nameLabel as NodeRef of Class GUILabel = FindGUIControlByName(me,"nameLabel")
  nameLabel.text = name
.
method SetHP(hp copies Integer)
  if hp < 0
    hp = 0
  .
  healthSlider as NodeRef of Class GUIControl = FindGUIControlByName(me, "healthPanel.healthSlider")
  healthSlider.removeAnimations()
  var size = -1.0 * hp
  //1 field(string), the field on the GUIControl to such as size.x or defaultStatePresentation.color.a
  //2 min(float) (this is NOT the start value for the animation. That is the current value of the field to which you are applying the min/max values)
  //3 max(float)
  //4 duration in seconds(float)
  //5 repeat count(integer) (0=repeat infinitely, 1-n do animation that number of times)
  //6 reverse(boolean), forward and backward(true), or just forward(false)
  //7 curve(Enum of type interpolation curve), LINEAR, HOLD, EASE_IN, EASE_OUT, SMOOTH
  //8 restore(boolean), restores the orignal value after the animation is finished
  //9 delay in seconds(float), the amount of time to wait before actually starting the animation
  //10 id(string), the ID of the animation
  animationString as String = "size.x,"
  animationString = animationString + healthSlider.size.x + ","
  animationString = animationString + size +","
  animationString = animationString + .1 + ","
  animationString = animationString + 1 + ","
  animationString = animationString + "false,"
  animationString = animationString + "LINEAR," 
  animationString = animationString + "false,"
  animationString = animationString + "0,"
  animationString = animationString + "slide"
 
  GUIAnimation:addAnimation(healthSlider, "Interpolate", animationString)
.

method SetMP(mp copies Integer)
  if mp < 0
    mp = 0
  .
  manaSlider as NodeRef of Class GUIControl = FindGUIControlByName(me, "manaPanel.manaSlider")
  manaSlider.removeAnimations()
  var size = -1.0 * mp
 
  animationString as String = "size.x,"
  animationString = animationString + manaSlider.size.x + ","
  animationString = animationString + size +","
  animationString = animationString + .1 + ","
  animationString = animationString + 1 + ","
  animationString = animationString + "false,"
  animationString = animationString + "LINEAR," 
  animationString = animationString + "false,"
  animationString = animationString + "0,"
  animationString = animationString + "slide"
 
  GUIAnimation:addAnimation(manaSlider, "Interpolate", animationString)
.

The Manabar is a copy of the Healthbar with name manaPanel and manaSlider.
Title: Re: Simple mana system
Post by: Thazager on Mar 19, 14, 09:02:09 PM
In method InitCommonCharacter()  did you add the E_regenTimer for the mana?

Also might need a method E_regenTimer_tick() for mana there too.

Title: Re: Simple mana system
Post by: xSystems on Mar 20, 14, 06:24:33 AM
Problem is fix, thx for help. :)
Title: Re: Simple mana system
Post by: Jarvis on Apr 10, 14, 03:58:43 PM
@Lithis - Hello had the same issue as you. After a while of freelance coding it all just to see if I could I fixed it myself. This is after duping and adding the manaPanel/manaSlider.

This is what I did:

On the Client Side for scripts, I had to edit: "E_playerAccountClassMethods", "E_playerCharacterClassMethods", "E_StatusBarClassMethods", "E_TargetCircleClassMethods".

In E_playerAccountClassMethod:

Under:

Code: [Select]
$LightweightEvents.addLightweightEventListener(addedNode, "hpUpdated", statusBar)
Add:

Code: [Select]
$LightweightEvents.addLightweightEventListener(addedNode, "mpUpdated", statusBar)
In E_playerCharacterClasMethod:

Under:

Code: [Select]
is "e_hitpoints"     
      $LightweightEvents.raiseLightweightEvent(updateNode, "hpUpdated", 0)
    .

Add:

Code: [Select]
is "e_manapoints"     
      $LightweightEvents.raiseLightweightEvent(updateNode, "mpUpdated", 0)
    .

Note: Notice how e_hitpoints and e_manapoints are all lowercase. Even though it is infact e_manaPoints. it needs to be all lower case for some reason in this case.

In E_StatusBarClassMethods:

Under:

Code: [Select]
is "hpUpdated"
      char as NodeRef of Class E_CommonCharacter = subject
      if char != None
        me.SetHP(char.E_hitPoints)
      . 
    .

Add:

Code: [Select]
is "mpUpdated"
      char as NodeRef of Class E_CommonCharacter = subject
      if char != None
        me.SetMP(char.E_manaPoints)
      . 
    .

AND at the bottom of that class add:

Code: [Select]
method SetMP(mp copies Integer)
  if mp < 0
    mp = 0
  .
  manaSlider as NodeRef of Class GUIControl = FindGUIControlByName(me, "manaPanel.manaSlider")
  manaSlider.removeAnimations()
  var size = -1.0 * mp
  //1 field(string), the field on the GUIControl to such as size.x or defaultStatePresentation.color.a
  //2 min(float) (this is NOT the start value for the animation. That is the current value of the field to which you are applying the min/max values)
  //3 max(float)
  //4 duration in seconds(float)
  //5 repeat count(integer) (0=repeat infinitely, 1-n do animation that number of times)
  //6 reverse(boolean), forward and backward(true), or just forward(false)
  //7 curve(Enum of type interpolation curve), LINEAR, HOLD, EASE_IN, EASE_OUT, SMOOTH
  //8 restore(boolean), restores the orignal value after the animation is finished
  //9 delay in seconds(float), the amount of time to wait before actually starting the animation
  //10 id(string), the ID of the animation
  animationString as String = "size.x," + manaSlider.size.x + "," + size +"," + .1 + "," + 1 + "," + "false," + "LINEAR," + "false," + "0," + "slide"
 
  GUIAnimation:addAnimation(manaSlider, "Interpolate", animationString)
.

In E_TargetCircleClassMethods:

Under:

Code: [Select]
$LightweightEvents.addLightweightEventListener(realtarget, "hpUpdated", statusbar)
Add:

Code: [Select]
$LightweightEvents.addLightweightEventListener(realtarget, "mpUpdated", statusbar)
Under:

Code: [Select]
statusbar.SetHP(realtarget.E_hitPoints)
Add:

Code: [Select]
statusbar.SetMP(realtarget.E_manaPoints)
//Updated to reflect changes. 26-04-14
Title: Re: Simple mana system
Post by: Thazager on Apr 11, 14, 03:19:19 PM
Once you have the output and comments in 1 section, you could save some space by creating the string into 1 long value. Just like C++ a string can be any length, just make sure to keep the values added in, rather than inside the quotes, and a comma between each value.

animationString as String = "size.x,"+ manaSlider.size.x + "," + size +", 0 .1, 1, false, LINEAR, false, 0, slide"