# Feedback: Bombing run

**URL:** <https://discourse.codecombat.com/t/feedback-bombing-run/6900>\
**Category:** Adventurer\
**Created:** [March 2, 2016, 7:59pm UTC](https://discourse.codecombat.com/t/feedback-bombing-run/6900 "2016-03-02T19:59:44Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![XAPOH](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.codecombat.com/xapoh/32/3608_2.png) [@XAPOH](https://discourse.codecombat.com/u/XAPOH)\
**Post date:** [March 2, 2016, 7:59pm UTC](https://discourse.codecombat.com/t/feedback-bombing-run/6900/1 "2016-03-02T19:59:44Z")

</div>

Very nice level! I’ve finished it without cheating and it was very pleasant.  
Still, may be it would be nice to add to the description that the answer must be the number of degrees.

---

<div class="post-metadata">

**Author:** ![AdrianCgw](https://avatars.discourse-cdn.com/v4/letter/a/ac8455/32.png) [@AdrianCgw](https://discourse.codecombat.com/u/AdrianCgw)\
**Post date:** [March 3, 2016, 1:51am UTC](https://discourse.codecombat.com/t/feedback-bombing-run/6900/2 "2016-03-03T01:51:14Z")

</div>

Also, even if the line containing Vector.heading() is commented, the level code still detects it and considers it an error.

---

<div class="post-metadata">

**Author:** ![UltCombo](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.codecombat.com/ultcombo/32/3822_2.png) [@UltCombo](https://discourse.codecombat.com/u/UltCombo)\
**Post date:** [March 3, 2016, 3:17am UTC](https://discourse.codecombat.com/t/feedback-bombing-run/6900/3 "2016-03-03T03:17:33Z")

</div>

> [@AdrianCgw](#):
>
> Also, even if the line containing Vector.heading() is commented, the level code still detects it and considers it an error.

I’m not sure what you mean, I can use `Vector.heading()` without problem.

---

<div class="post-metadata">

**Author:** ![AdrianCgw](https://avatars.discourse-cdn.com/v4/letter/a/ac8455/32.png) [@AdrianCgw](https://discourse.codecombat.com/u/AdrianCgw)\
**Post date:** [March 3, 2016, 8:42am UTC](https://discourse.codecombat.com/t/feedback-bombing-run/6900/4 "2016-03-03T08:42:00Z")

</div>

![](https://us1.discourse-cdn.com/flex016/uploads/codecombat/original/2X/2/2fefec6f4e9842de4335346fb946200b0388b0ff.jpg)

---

<div class="post-metadata">

**Author:** ![ant](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.codecombat.com/ant/32/3362_2.png) [@ant](https://discourse.codecombat.com/u/ant)\
**Post date:** [March 3, 2016, 12:56pm UTC](https://discourse.codecombat.com/t/feedback-bombing-run/6900/5 "2016-03-03T12:56:39Z")

</div>

Copying my comments from slack, for reference:

- it’s not specified if the angle should be in degrees or radians
- put some blocking terrain around the level, because you can walk off the screen
- ban boss stars, hammers, gold wand, summon burl, summon skeleton, etc.
- unnecessary `;` in python sample code + `# Find the vector of attack` is written twice
- nice twist: _“using the vector class’s heading() is not allowed”_ 🙂

---

<div class="post-metadata">

**Author:** ![Serg](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.codecombat.com/serg/32/3260_2.png) [@Serg](https://discourse.codecombat.com/u/Serg)\
**Post date:** [March 3, 2016, 6:16pm UTC](https://discourse.codecombat.com/t/feedback-bombing-run/6900/6 "2016-03-03T18:16:44Z")

</div>

Can you show me how you’re able to use .heading()?

---

<div class="post-metadata">

**Author:** ![UltCombo](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.codecombat.com/ultcombo/32/3822_2.png) [@UltCombo](https://discourse.codecombat.com/u/UltCombo)\
**Post date:** [March 3, 2016, 8:57pm UTC](https://discourse.codecombat.com/t/feedback-bombing-run/6900/7 "2016-03-03T20:57:23Z")

</div>

Sure, here it is:

```python
    if enemy:
        # Find the vector of attack
        diff = enemy.pos.subtract(self.pos)
        
        # Say the angle!
        self.say(Vector.heading(diff) * 180 / Math.PI)

```

And yeah, I guess I was supposed to do some more math in this level, right? This feels a bit like cheating, but good programmers make use of the tools they have at their disposal. 😄

Perhaps you could replace the `Vector.heading` (static and instance methods) with a no-op or a function that throws when called in this level?

---

<div class="post-metadata">

**Author:** ![BarnZarn](https://avatars.discourse-cdn.com/v4/letter/b/35a633/32.png) [@BarnZarn](https://discourse.codecombat.com/u/BarnZarn)\
**Post date:** [March 4, 2016, 4:00pm UTC](https://discourse.codecombat.com/t/feedback-bombing-run/6900/8 "2016-03-04T16:00:24Z")

</div>

I can’t do anything because it’s in glacier and I’m in dessert right now. But maybe you should temporarily give adventurers the items they need and an explanation. And yes, I’m an adventurer. How do i know its in glacier? the ice

---

<div class="post-metadata">

**Author:** ![zuf](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.codecombat.com/zuf/32/34897_2.png) [@zuf](https://discourse.codecombat.com/u/zuf)\
**Post date:** [March 5, 2016, 11:20am UTC](https://discourse.codecombat.com/t/feedback-bombing-run/6900/9 "2016-03-05T11:20:43Z")

</div>

Got around to trying the level:  
It was possible to slay the ogres and pass by using conventional fighting tactics (sword, bash, summon soldiers). Disabling item gold might help.

I got stuck while trying to find a legitimate solution. Then I checked this thread and realised that it was supposed to be in degrees. Definitely specify that unit (some people in some contexts use radians as default). I was also wondering if I had the wrong angle of attack. (Do I need to ‘calculate their angle of attack’ from my perspective, or is it their perspective or what?)

I also noticed:  
`vector.heading()` results in a failure, but `vector.heading( )` does not and can be used to pass the level. I’m guessing the code for that goal checks for an exact match of ‘heading()’ because commented out also triggers it.

The swooping griffin riders seems new and looks nice though.

Edit – My suggestions:  
As of posting, nothing happens when you say the wrong angle. This makes it harder for the user to figure out what might be wrong.

- The griffins should bomb for any angle. Saying the incorrect angle wastes time and won’t hit all the ogres, so they’ll be able to reach the player.
- The ogres behind the brawler should be replaced with tougher ones.
- Disable item gold to prevent summoning troops.
- Add a picture to the guide that shows where the angle starts and the unit. For example:  
 ![](https://cdck-file-uploads-us1.s3.dualstack.us-west-2.amazonaws.com/flex016/uploads/codecombat/original/2X/8/89ea719770a57b1ad78d2bc4f599d2209d9c5f50.png)

---

<div class="post-metadata">

**Author:** ![XAPOH](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.codecombat.com/xapoh/32/3608_2.png) [@XAPOH](https://discourse.codecombat.com/u/XAPOH)\
**Post date:** [March 6, 2016, 1:35pm UTC](https://discourse.codecombat.com/t/feedback-bombing-run/6900/10 "2016-03-06T13:35:38Z")

</div>

Just keep playing. If you can not reach the glacier then don’t test this level. You must be useful as an adventurer.  
IMHO

---

<div class="post-metadata">

**Author:** ![Tom\_H](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.codecombat.com/tom_h/32/3918_2.png) [@Tom\_H](https://discourse.codecombat.com/u/Tom_H)\
**Post date:** [March 7, 2016, 7:40pm UTC](https://discourse.codecombat.com/t/feedback-bombing-run/6900/11 "2016-03-07T19:40:43Z")

</div>

this is my code  
`# Incoming oscars! (That's military speak for ogres). # You will need to calculate their angle of attack. # Use that angle to command your Griffin Bombers! loop: enemy = self.findNearest(self.findEnemies()); flag = self.findFlag() if flag: self.pickUpFlag(flag) if self.canCast("raise-dead"): self.cast("raise-dead") elif enemy: distance = self.distanceTo(enemy) if self.canCast("drain-life", enemy) and distance <= 15: self.cast("drain-life", enemy) if self.canCast("summon-undead"): self.cast("summon-undead") if self.canCast("poison-cloud", enemy) and distance < 30: self.cast("poison-cloud", enemy) if self.canCast("fear", enemy) and distance < 25: self.cast("fear", enemy) if distance < self.throwRange - 5: self.attack(enemy) else: self.moveXY(50, 5) while True: enemy = self.findNearest(self.findEnemies()); if enemy: # Find the vector of attack vector = Math.atan2(enemy.pos.y, enemy.pos.x) # Find the vector of attack # Say the angle! self.say(vector)`  
i was using omarn with unholy tome V  
and had 530 hp

is there any way that you can stop people from using weapons tomes, etc.

---

<div class="post-metadata">

**Author:** ![Serg](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.codecombat.com/serg/32/3260_2.png) [@Serg](https://discourse.codecombat.com/u/Serg)\
**Post date:** [March 8, 2016, 11:47pm UTC](https://discourse.codecombat.com/t/feedback-bombing-run/6900/12 "2016-03-08T23:47:40Z")

</div>

Hey everyone,

I appreciate the feedback as always. It took a bit longer to get some time to work on the level, but, I’ve improved some things:

1. The griffins will now attack any angle angle you say, to help with debugging. This will help guide players that aren’t using radians or using the wrong Math operation.
2. Made it more clear that we want the answer in degrees. I wasn’t sure if I wanted the answer in degrees or radians, but degrees are more human-readable so I included some hints on how to do that.
3. Added some collision boxes around the edges of the level (but not the top, as thats where ogres spawn.)
4. Made all ogres into Brawlers, for those that want to brute force it with might (tsk, tsk.)
5. Removed hammers and gold wand and similar weapons, also removed boss stars. We’re trying to teach you new concepts! Can’t have you just attacking your way through lessons.
6. Included a diagram in the guide. I would’ve used yours, zuf, but negative y results in a negative angle, not a 180+ angle.
7. Improved the check for heading(), but, it’s still very hacky. I hope to get an engine hook to disable heading natively (but that’s not in the cards atm.)

As always, thanks adventurers! You all contribute a lot to making sure the levels are great.

---

<div class="post-metadata">

**Author:** ![UltCombo](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.codecombat.com/ultcombo/32/3822_2.png) [@UltCombo](https://discourse.codecombat.com/u/UltCombo)\
**Post date:** [March 9, 2016, 3:46am UTC](https://discourse.codecombat.com/t/feedback-bombing-run/6900/13 "2016-03-09T03:46:09Z")

</div>

Very nice work! 😄

> [@Serg](#):
>
> Improved the check for heading(), but, it’s still very hacky. I hope to get an engine hook to disable heading natively (but that’s not in the cards atm.)

I see, it is possible to bypass the check using some uncommon code style—e.g. putting a space before the function call’s opening parenthesis: `vector.heading ()`. Now you could think about not checking the parentheses at all and just look for a “heading” substring, but that is not enough either as one can do `vector['head' + 'ing']()` or `vector['\150eading']()` (both equivalent to `vector.heading()` in JavaScript). And this is still not accounting for false positives (`heading()` inside commented out code).

Isn’t it possible/viable to just replace the heading function in this level? I believe this should do the trick:

```coffeescript
  onFirstFrame: ->
    Vector::heading = =>
      error = "Using the Vector class's heading() is not allowed on this level."
      hint = "Figure out the math behind heading() instead of using the prepackaged method!"
      aether = @hero.getAetherForMethod("plan")
      problem = aether.createUserCodeProblem type: 'runtime', error: {name: "used_vector_heading", message:error, hint:hint, toString: -> "heading()"}
      @hero.addAetherProblemForMethod problem, "plan"
      @world.setGoalState "no-heading", "failure"

```

This will make invoking the Vector class’s `heading` method just set the fail condition. As far as I can see, the `Vector.heading(vectorInstance)` static method internally calls `vectorInstance.heading()`, so my code above should take care of both method variants.

I believe a new worker is spawned every time you load a level, so replacing the global Vector method as I suggested shouldn’t be a problem. Correct me if I’m mistaken.

---

<div class="post-metadata">

**Author:** ![Serg](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.codecombat.com/serg/32/3260_2.png) [@Serg](https://discourse.codecombat.com/u/Serg)\
**Post date:** [March 9, 2016, 5:34pm UTC](https://discourse.codecombat.com/t/feedback-bombing-run/6900/14 "2016-03-09T17:34:33Z")

</div>

Thanks UltCombo,

My first naive attempt was `Vector.heading = -> return null`, but that didn’t work.

I didn’t think, (or know) about :: being a way of accessing a object’s prototypes. Thanks for your help!

The level has been updated and calling Vector.heading in any manner now tosses an error.

Edit: Doesn’t work, whoops, gonna keep experimenting, but Vector.heading() is relied on all of the units as they move around (to get which direction they should face,) lemme debug further.

---

<div class="post-metadata">

**Author:** ![UltCombo](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.codecombat.com/ultcombo/32/3822_2.png) [@UltCombo](https://discourse.codecombat.com/u/UltCombo)\
**Post date:** [March 9, 2016, 5:45pm UTC](https://discourse.codecombat.com/t/feedback-bombing-run/6900/15 "2016-03-09T17:45:11Z")

</div>

Aw whoops, I forgot to test a working level solution before proposing that fix, my bad. 😅

I’m not sure if we can discern whether it is user code or internal game code that is calling `Vector.heading`, can we? I will probably have some time to investigate it tonight.

---

<div class="post-metadata">

**Author:** ![UltCombo](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.codecombat.com/ultcombo/32/3822_2.png) [@UltCombo](https://discourse.codecombat.com/u/UltCombo)\
**Post date:** [March 10, 2016, 5:41am UTC](https://discourse.codecombat.com/t/feedback-bombing-run/6900/16 "2016-03-10T05:41:42Z")

</div>

I’m wondering, isn’t there a way to hook into Aether’s compile step from the referee code? I was thinking about inserting a `Vector` class scoped inside the compiled code’s `plan` function (the function that wraps the entire user code), this way we could patch the user code’s Vector class’ `heading` method without messing with the global Vector methods.

Another way would be to use something similar to `aether.replaceBuiltin`, but I’m not entirely sure how that works—would it be possible/make sense to perform this operation from referee code, or do we need to hook into a pre-compile step for this to work?  
/cc @nick

By the way, I see @Serg has updated the check for the `heading` function and now it uses a regex that catches the vast majority of exploit attempts, so it should good enough to ship. 😄

---

<div class="post-metadata">

**Author:** ![nick](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.codecombat.com/nick/32/784_2.png) [@nick](https://discourse.codecombat.com/u/nick)\
**Post date:** [March 10, 2016, 7:21pm UTC](https://discourse.codecombat.com/t/feedback-bombing-run/6900/17 "2016-03-10T19:21:02Z")

</div>

I like allowing your clever hacks to access the “disabled” property, and it’s much simpler to just have a decent regex to catch the obvious things, so even if we could make it work in Aether, I don’t think it would help much!

---

<div class="post-metadata">

**Author:** ![sir-sonic-Destroyer](https://avatars.discourse-cdn.com/v4/letter/s/838e76/32.png) [@sir-sonic-Destroyer](https://discourse.codecombat.com/u/sir-sonic-Destroyer)\
**Post date:** [March 18, 2016, 3:26pm UTC](https://discourse.codecombat.com/t/feedback-bombing-run/6900/19 "2016-03-18T15:26:40Z")

</div>

can some one help me?  
i can’t figure out how to say the angle and to divide the angle?  
any help would be delightful.  
😁
