Throwers - how to they aim when I move? (Why do they hit me?)

I noticed in backwood brawl that I was not able to evade projectiles from throwers.
Even if i moved constantly at 90° angle to the direction to the thrower, all of their arrows seem to hit me.

my direction of movement
^
I
I
X-----------------------x Thrower (at max shooting distance (approx 15 meters +/-)
me

I tried to move with moveXY, about 3…6 meters per movement. After each movement, I re-calculated direction in order to keep 90°-course.

When the arrow was fired, I usually move 2 or 3 meters before it hits me, but it was apparenty fired in an angle that reflected my future position.

So my question is: Is the hit already determined at the time when the arrow was shot and the course is calculated afterward, so that the arrow really does hit?

Or does the thrower look at my velocity & direction at shooting time and calculates that for its shootin-direction?

Is there a way to evade the arrows by moving (irregulary)? Was I too straight to set a course for 3…6 meters?

(I was in fact a little disappointed that I basically needed armor and good weapons in order to succeed)

Is there a way to beat throwers (without just overpowering them?)

Regards!

4 Likes

Yes, throwers predict your future position.
So, if you want to avoid arrow
You should change move direction after shot

4 Likes

Wow, that’s great (should have figured out that myself, but I did not really believe they were that good at such low levels :astonished:) Thank you very much!

Regards

3 Likes

Yup, here’s some of the code from the combat.Missile Component (you can see this in the Components list in the level editor):

  findInterception: (from, to, targetVelocity, speed, useZ) ->
    # http://www.gamedev.net/topic/457840-calculating-target-lead/
    diff = Vector.subtract(to, from)
    a = targetVelocity.dot(targetVelocity) - speed * speed
    b = 2 * targetVelocity.dot(diff)
    c = diff.dot(diff)
    d = b * b - 4 * a * c
    t = 0
    unless d < 0 or a is 0
      t0 = (-b - Math.sqrt(d)) / (2 * a)
      t1 = (-b + Math.sqrt(d)) / (2 * a)
      t = if t0 < 0 then t1 else (if t1 < 0 then t0 else Math.min(t0, t1))
    if t <= 0 then t = @lifespan ? 3 
    {pos: Vector.add(to, Vector.multiply(targetVelocity, t, useZ), useZ), time: t}

  launch: (shooter, launchType='attack') ->
    @launchType = launchType
    @setExists true
    @shooter = shooter
    @pos = Vector.add @shooter.pos, {x: 0, y: 0, z: @pos.z}, true  # Physical pos as offset to shooter pos, but only in z dimension
    @pos.z = Math.min @pos.z, @depth / 2 + 1  # Make sure we start at least a meter off the ground
    targetPos = @shooter.getTargetPos().copy()
    targetPos.z = 0 if @shootsAtGround
    if @leadsShots and @shooter.target?.velocity?.magnitude() > 0
      if @flightTime
        targetPos.add Vector.multiply(@shooter.target.velocity, @flightTime, not @shootsAtGround)
      else
        interception = @findInterception @pos, targetPos, @shooter.target.velocity, @maxSpeed, not @shootsAtGround
        targetPos = interception.pos
        @flightTime = interception.time
      unless @shootsAtGround or @shooter.target.maintainsElevation?()
        # Account for gravity when leading target z. TODO: this doesn't work properly.
        targetPos.z = Math.max((if @shooter.target.depth then @shooter.target.depth / 2 else 0), targetPos.z - @world.gravity * @flightTime * @flightTime / 2)
    @setTargetPos targetPos
    @addCurrentEvent? 'launch'
4 Likes

Hi Nick, thanks for the background information! (Hope I’m geting this not-yet-very-familiar-coffee right:) So the adversary shooter knows my (target’s) velocity (which is fair to assume he can, as long I am in his line of sight)? Great. So I will need to change my direction a little bit more often, as there seems indeed to be no “hindsight adjustment” at all (if I get this.setTargetPos and this.addCurrentEvent ‘launch’ right…

Thanks a lot (especially for directing me to coffee which really seems to be fun)!

Regards!

2 Likes