HeroEngine Forums
Welcome, Guest. Please login or Register for HeroCloud Account.
Pages: 1 [2]

Author Topic: [Resolved] Adding Endurance Cost to an ability and make it show on status bar  (Read 4036 times)

LastJudge

  • General Accounts
  • *
  • Posts: 215
    • View Profile

I actually had that problem too, I haven't solved it yet though (I was too lazy to attempt - I'm doing other stuff)
Logged

nocake

  • General Accounts
  • *
  • Posts: 404
    • View Profile
    • BlightMMO


server - abEffects
Code: [Select]
shared function ApplyActionCost( owner as NodeRef of Class E_playerCharacter, ActionCost as Integer, ability as NodeRef of Class E_Ability )
  owner.AdjustAction(-ActionCost, owner, ability )    
.

owner is a E_CommonCharacter i think. not E_playerCharacter

LastJudge

  • General Accounts
  • *
  • Posts: 215
    • View Profile

owner is the one who casts the ability / skill so unless NPC characters are supposed to have 'action' or whatever else you use, it should be set to E_playerCharacter.
Logged

nocake

  • General Accounts
  • *
  • Posts: 404
    • View Profile
    • BlightMMO

I get that but i am pretty sure in
Code: [Select]
abEffects:ApplyActionCost( owner, ActionCost() , ability )
owner is a E_CommonCharacter and that is why he is having this error.

LastJudge

  • General Accounts
  • *
  • Posts: 215
    • View Profile

That sounds like that could be it.

So cast E_CommonCharacter to E_PlayerCharacter when you call ApplyActionCost.
Logged

FI-ScottZ

  • General Accounts
  • *
  • Posts: 1407
    • View Profile
    • Forever Interactive, Inc.

That doesn't make much sense, as CommonCharacter is simply the parent class of both playerCharacter and nonPlayerCharacter.  All characters would be one or the other; you wouldn't have something that is simply CommonCharacter.

Do you have any npcs running when you do this?

Did you make a custom playerCharacter class that is being used instead of E_playerCharacter?

When you get the "does not have class E_playerCharacter" error, copy the node id it shows and paste that into the console after \sn to see what classes are on it.
Logged
Scott Zarnke
Lead Programmer, Visions of Zosimos
CTO, Forever Interactive, Inc.

cloudnine

  • General Accounts
  • *
  • Posts: 80
    • View Profile
    • Youtube

i made a character class but it spawns with no armor when i create it
its not linked to the starting character when i create a new character yet
cause ive only found where to preload a prototype and add test to the drop down list
not how to select between two or more different prototypes

I separated the shared function ApplyEffects() and put ApplyActionCost back under AdjustAction
on abWeaponStrike

It got the attack back to a single hit but the Status Bar isnt updating yet
Logged

cloudnine

  • General Accounts
  • *
  • Posts: 80
    • View Profile
    • Youtube

client- abWeaponStrike
Code: [Select]
shared function ActionCost () as Integer
  return 20
.


shared function GetAbilityCooldown() as TimeInterval
  return 00:00:03
.

shared function GetActivationTime() as TimeInterval
  return 00:00:01
.

shared function ApplyEffects( owner as NodeRef of Class E_CommonCharacter, target as NodeRef )
 
.
shared function AdjustAction( owner as NodeRef of Class E_CommonCharacter )
 
.
server - abWeaponStrike
Code: [Select]
shared function ActionCost() as Integer
   
    return 20
.
shared function ApplyEffects ( owner as NodeRef of Class E_CommonCharacter, target as NodeRef, ability as NodeRef of Class E_Ability )
  abEffects:ApplyDirectDamage( owner, target, ability, GetMinDamage(), GetMaxDamage() ) 
  //abEffects:ApplyActionCost( owner, -ActionCost() , ability )
.
shared function AdjustAction ( owner as NodeRef of Class E_CommonCharacter, ability as NodeRef of Class E_Ability )
  abEffects:ApplyActionCost( owner, -ActionCost() , ability )
 
.
server - abEffects
Code: [Select]
shared function ApplyActionCost( owner as NodeRef of Class E_CommonCharacter, ActionCost as Integer, ability as NodeRef of Class E_Ability, Action as NodeRef of Class E_CommonCharacter )
  //if( target == None )
    //return
  //.
   //owner.Action = owner.Action - ActionCost
  //if me.Action < 0.0
   // me.Action = 0.0
  //.
  //where owner is kindof E_playerCharacter
    // calculate action cost
    //owner.Action = owner.Action-ActionCost
   // .
    // apply the action cost
   owner.AdjustAction(-ActionCost, owner, ability  )   
.
Logged

cloudnine

  • General Accounts
  • *
  • Posts: 80
    • View Profile
    • Youtube

I also ended up givine the E_CommonCharacter fields action and energy from the DOM editor
server E_CommonCharacter
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_isDead = false
  me.Action = 100
  me.Energy = 100
  // start regen tick
  if( me.E_regenTimer.timerState == ON )
    me.E_regenTimer.stop()
  .
  me.E_regenTimer.fireRate = 00:00:10
  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 )
    // handle death
  if( me.E_hitPoints <= 0 )
    me.ApplyDeath( attacker )   
  .
  // 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 )
  .
.
method AdjustAction( actionDelta as Integer, owner as NodeRef, Action as NodeRef of Class E_CommonCharacter )
 
  me.Action = MiscUtils:Min( me.Action + actionDelta, 100 )
  .

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
  // 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._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.Action = MiscUtils:Min( me.Action + 10, 100 )
  me.Energy = MiscUtils:Min( me.Energy + 10, 100)
.

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

cloudnine

  • General Accounts
  • *
  • Posts: 80
    • View Profile
    • Youtube

client - E_StatusBar
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 "actionUpdated"
      char as NodeRef of Class E_CommonCharacter = subject
      if char != None
        me.SetAction(char.Action)
      .
    .
     is "energyUpdated"
      char as NodeRef of Class E_CommonCharacter = subject
      if char != None
        me.SetEnergy(char.Energy)
      .
    .
  .
.
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 SetAction(Action copies Integer)
  if Action < 0
    Action = 0
  .
  actionSlider as NodeRef of Class GUIControl = FindGUIControlByName(me, "actionPanel.actionSlider")
  actionSlider.removeAnimations()
  var size = -1.0 * Action
  //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 + actionSlider.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(actionSlider, "Interpolate", animationString)
  .
 method SetEnergy(Energy copies Integer)
  if Energy < 0
    Energy = 0
  .
  energySlider as NodeRef of Class GUIControl = FindGUIControlByName(me, "energyPanel.energySlider")
  energySlider.removeAnimations()
  var size = -1.0 * Energy
  //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 + energySlider.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(energySlider, "Interpolate", animationString)
  .
Logged
Pages: 1 [2]