Fall damage

Discussion in 'Mechanics' started by D.M.G., Nov 6, 2016.

?

Whaddya think?

  1. Yeah, I like my monsters flat

    8 vote(s)
    100.0%
  2. Nah, it's fine for me

    0 vote(s)
    0.0%
  1. D.M.G.

    D.M.G. Master Astronaut

    This is something I've been observing since I started making JSON-made weapons: the only entity in the entire game which takes fall damage is the player.

    So
    What I think is to enable fall damage for ground creatures, along with NPCs
    Not only is it not fun to see them landing perfectly fine like nothing happened instead of having a meaty red soup lying on the ground, it's also quit illogical.
     
  2. Sharp(JQ)

    Sharp(JQ) Ketchup Robot

    Then we need also the drowning and death from sand pressure.
     
  3. D.M.G.

    D.M.G. Master Astronaut

    Seems logical, yeah
     
  4. Inf_Wolf14

    Inf_Wolf14 Parsec Taste Tester

    If fall damage is enabled for most other NPCs and monsters, I think an AI rehaul would be also necessary.

    From what I've experienced, monsters are made so that their pathing doesn't have as much of a worry towards vertical platforming.

    I would like fall damage for everything. But I wouldn't like to see monsters randomly falling and dying from the mountains on either side of my valley settlement. :p
     
  5. D.M.G.

    D.M.G. Master Astronaut

    That'd look funny thoX3
     
    DraikNova and Inf_Wolf14 like this.
  6. oinkgamer

    oinkgamer Cosmic Narwhal

    Yeah its really not fair for only the player to experience fall damage.
     
  7. bk3k

    bk3k Oxygen Tank

    I briefly thought about NPCs taking damage as part of a mod (that much would be easy), but yes the AI would need to be redone to account for this so it probably isn't worth it.

    I've thought about this too. The player takes damage from falling only, but not from high speed collisions in any other direction. Well I know in vanilla you don't usually have that problem... with the 1.0+ techs anyhow.

    Also the fall damage takes into account gravity, which doesn't really make sense. The gravity accelerates your fall, but it is the speed times mass that accounts for (almost all) of the force of impact. Neither does a static fall height make sense in the calculation(since the actual speed of impact from a fall would be different based upon gravity, aerodynamics). The gravity itself only adds as much force to the impact when colliding as it does when you're standing there. Your own mass provides the inertia.


    Code:
    local minimumFallDistance = 14
      local fallDistanceDamageFactor = 3
      local minimumFallVel = 40
      local baseGravity = 80
      local gravityDiffFactor = 1 / 30.0
    
      local curYPosition = mcontroller.yPosition()
      local yPosChange = curYPosition - (self.lastYPosition or curYPosition)
    
      if self.fallDistance > minimumFallDistance and -self.lastYVelocity > minimumFallVel and mcontroller.onGround() then
        local damage = (self.fallDistance - minimumFallDistance) * fallDistanceDamageFactor
        damage = damage * (1.0 + (world.gravity(mcontroller.position()) - baseGravity) * gravityDiffFactor)
        damage = damage * status.stat("fallDamageMultiplier")
        status.applySelfDamageRequest({
            damageType = "IgnoresDef",
            damage = damage,
            damageSourceKind = "falling",
            sourceEntityId = entity.id()
          })
      end
    
      if mcontroller.yVelocity() < -minimumFallVel and not mcontroller.onGround() then
        self.fallDistance = self.fallDistance + -yPosChange
      else
        self.fallDistance = 0
      end
    
      self.lastYPosition = curYPosition
      self.lastYVelocity = mcontroller.yVelocity()
    


    You wouldn't really take more damage from a 20mp/h (32.187km/h) collision on a planet that is 2x Earth gravity as compared to Earth. You take just as much damage in an environment lacking gravity(provided what you are colliding with is not going to move/absorb the impact).

    Let me give you an

    Code:
      local pos = mcontroller.position()
      local mass = mcontroller.mass()
      local dist = dist(pos, self.last_pos or pos)
      local deltaSpeed = dist / dt
      local change = deltaSpeed - (self.last_deltaSpeed or deltaSpeed)
      local collisionDamage = 0
      
      elseif (change > 0.3) and mcontroller.isColliding() or mcontroller.isNullColliding() then
        --0.3 is just a numbe I plugged in for example
        collisionDamage = change * mass
      elseif (change > 1) and world.liquidAt(pos) then
        collisionDamage = (change * mass) / 3
          --3 is a plugged number here, perhaps swap (change * mass) - ((change * mass) / viscosity ) etc
          --I don't know the realistic way to calculate off hand but better than nothing
      end
    
      if collisionDamage > (minCollision or 0) then --define this elsewhere, adjust for balance
        status.applySelfDamageRequest({
            damageType = "IgnoresDef",
            damage = collisionDamage * (collisionMultiplier or 1),  --define this elsewhere, adjust for balance
            damageSourceKind = "collision",
            sourceEntityId = entity.id()
          })
      end
      
      self.last_pos = mcontroller.position()
      self.last_deltaSpeed = deltaSpeed
    That code could be made better by considering the hardness of the material you collided with(probably tile "health") and viscosity of liquids, but that's all extra/overkill/OCD. And yes notice that code makes you possibly take collision damage(at higher speeds) from liquid collision too(as you really would). The exact numbers would need tinkered with til it feels right. It could easily be adjusted to not check every update tic, but every 5 tics etc if that is preferable. It might also replace isColliding() with a check for tiles in the collision path based off the previous trajectory... but that might be unacceptably expensive for not much advantage.

    Now that code does reference this added function(obviously you'd need to add it)
    Code:
    function dist(t1, t2)
      return math.sqrt(((t1[1] - t2[1])^2) + ((t1[2] - t2[2])^2))
    end

    Yeah I know... it is a game and I put too much thought into it, but that's how I think.
     
  8. D.M.G.

    D.M.G. Master Astronaut

    I can't read most of it, but it's good to see you that into itX3
     
  9. bk3k

    bk3k Oxygen Tank

    Well I mostly wrote that for the devs in case they're reading the thread. That's a code replacement for /stats/player_primary.lua and I expect they could read it just fine :D

    Although I don't actually know to what degree that happens. I'm sure they do some reading, but if they spent all day reading these forums, combing over Steam forums, twitter, and reddit... they'd never get anything done. So I figure it is a shot in the dark.
     
  10. D.M.G.

    D.M.G. Master Astronaut

    Hey, there's a lightball shot in the assets, if you want a bright shootX3
     

Share This Page