Zezombye / overpy

High-level language for the Overwatch Workshop with support for compilation and decompilation.
GNU General Public License v3.0
175 stars 25 forks source link

Suggestion: New macro syntax idea. #368

Open nathan130200 opened 1 month ago

nathan130200 commented 1 month ago

Rework how macros are declared. Add new keyword called macro that will have this syntax:


macro <identifier>(params...):
  pass

Where identifier is macro name.

To fix member macros (that we cannot actually call the value itself, eg we cannot currently declare member macro in overpy and use input value used) we can add extra keyword specific to new macro syntax, self:

macro setPlayerProps(self, timeVal, btnVal):
  self.setAbilityResource(Button.ABILITY_1, btnVal);
  self.setAbilityResource(Button.ABILITY_2, btnVal);
  self.setRespawnTime(timeVal);

self will be a reserved word inside macro, no one can use that name.

New macro can both resolve statements/expressions and annotations.

macro isABot(self):
  @Condition self.isDummyBot()
  @Condition self.hasSpawned()

rule "test if we can teleport bot":
  @Event eachPlayer
  eventPlayer.isABot() // expand both conditions here, using `eventPlayer` as `self` argument.

Another example using vector.

macro vecLen(self): sqrt((self.x * self.x) + (self.y * self.y) + (self.z * self.z))

eventPlayer.getVelocity().vecLen() # expand sqrt(...) expression here.

Macro that return an value from macro, put inline instead newline + indent Or add special check in return inside that macro, to use last line inside the macro as final expanded value. Example:

globalvar v1
globalvar v2
globalvar vf

macro asSafePos(v): nearestWalkablePosition(v)

macro safePos(v):
  v1 = v + vect(-10, 0, -10)
  v2 = v + vect(10, 0, 10)
  return (v1 - v2).asSafePos()

rule "init safe pos":
  vf = safePos(getObjectivePosition(0)) # expand all other actions, vf  = expand all content of `return` line, after the keyword.

  # all macros above will expand to:
  v1 = getObjectivePosition(0) + vect(-10, 0, -10)
  v2 = getObjectivePosition(0) + vect(10, 0, 10)
  vf = nearestWalkablePosition(v1 - v2)

As well "static" macros, that don't use self in first argument:



macro setGameEnd(timeToWait):
  declareDraw()
  wait(timeToWait)
  restartGame()

rule "ops, draw":
  @Event global
  @Condition getMatchTime() == 0
  @Condition winner == null
  setGameEnd(5.56)