[ ] [1,2,3].exclude([1,3]) -> [2] (only for literals)
[ ] [1,2,3].index(2) -> 1 (only for literals)
Function calculations with literals:
[ ] verticalAngleOfDirection
[ ] angleDifference
[ ] angleBetweenVectors
[ ] angleToDirection
[ ] horizontalAngleFromDirection
[ ] magnitude
[ ] strLen
[ ] strContains
[ ] substring
Function combinations that map to a function already built-in to the workshop:
[ ] distance(vect(0,0,0), A) -> magnitude(A)
[ ] sqrt(dotProduct(A,A)) -> magnitude(A)
Conditions:
[ ] if true -> remove if condition
[ ] if A: action(B); else: action(C) -> action(B if A else C) (if only one argument changes, no goto, and not a reevaluating argument, see #213)
If no usage of RULE_CONDITION or wait, replace in rule conditions:
[ ] hero of(event player) -> "Hero.ANA" if the event hero is "Ana" (check for echo stuff?)
[ ] team of(event player) -> "Team.1" if the event team is "1"
[ ] slot of(event player) -> "1" if the event slot is "1"
Dictionaries:
[ ] {12:34,56:78}[12] -> 34 (only for literals)
Switches:
[ ] All cases are numeric and ascending (no "default"), the interval between the values of the cases is constant, and each case contains the same number of actions -> replace dict by switchVar * caseOffset + firstCaseOffset
Colors:
[ ] rgba(255,255,255,255) -> Color.WHITE (same for all other built-in colors)
[ ] rgba(A,B,C,0) -> rgba(0,0,0,0)
Reevaluation:
[ ] evalOnce(x) in a non-reevaluating field -> x
[ ] updateEveryTick(x) in a non-reevaluating field -> x
Conditional optimizations based on arguments:
[ ] Visibility for Player.startForcingOutlineFor is false -> color is null
[ ] createBeam with Beam.GRAPPLE -> color is null
[ ] createEffect with sound effect -> color is null
[ ] playEffect with sound effect -> color is null
[ ] hudText with null header/subtext/subheader -> null corresponding color
[ ] waitUntil(truthy, X) -> pass (?)
[ ] progressBarHud with no text -> text color is null
[ ] createProgressBarInWorldText with no text -> text color is null
Applied optimizations
Click to show
**Addition:**
- [x] A+0 -> A
- [x] A+A -> A*2
- [x] 1+2 -> 3
- [x] vect(1,1,1)+vect(2,2,2) -> vect(3,3,3)
**Substraction:**
- [x] A-0 -> A
- [x] A-A -> 0
- [x] 1-2 -> -1
- [x] vect(3,3,3)-vect(2,2,2) -> vect(1,1,1)
**Negation:**
- [x] --A -> A
- [x] -vect(1,2,3) -> vect(-1,-2,-3)
**Multiplication:**
- [x] A*1 -> A
- [x] A*0 -> 0
- [x] 1*2 -> 2
- [x] 2*vect(1,1,1) -> vect(2,2,2)
- [x] vect(1,2,3)*vect(4,5,6) -> vect(4,10,18)
**Division:**
- [x] A/1 -> A
- [x] 1/2 -> 0.5
- [x] A/0 -> 0
- [x] 0/A -> 0
- [x] vect(3,3,3)/vect(1,2,3) -> vect(3,1.5,1)
- [x] vect(1,2,3)/2 -> vect(0.5,1,1.5)
**Modulo:**
- [x] A%0 -> 0
- [x] A%A -> 0
- [x] 0%A -> 0
- [x] 5%3 -> 2
**Power:**
- [x] 0**A -> 0
- [x] 1**A -> 1
- [x] [negative number]**A -> 0
- [x] 2**3 -> 8
**And:**
- [x] A and False -> False
- [x] A and True -> A
- [x] A and A -> A
- [x] A and not(A) -> False
**Or:**
- [x] A or False -> A
- [x] A or True -> True
- [x] A or A -> A
- [x] A or not(A) -> True
**Not:**
- [x] Not True -> False
- [x] Not False -> True
- [x] Not Not A -> A if A is bool
**Equality:**
- [x] A == A -> True
- [x] 1 == 2 -> False
- [x] A != A -> False
- [x] 1 != 2 -> True
- [x] A > A -> False
- [x] 1 > 2 -> False
- [x] A >= A -> True
- [x] 1 >= 2 -> False
- [x] A < A -> False
- [x] 1 < 2 -> True
- [x] A <= A -> True
- [x] 1 <= 2 -> True
- [x] A == falsy -> Not A (due to #182, only done if A is a boolean function)
- [x] A == true -> A (if A is boolean)
- [x] A != falsy -> A (if expecting boolean or A is boolean) (due to #182, only done if A is a boolean function)
- [x] A != true -> not A (if A is boolean)
**Assignment:**
- [x] A = A -> nothing
- [x] A = A+B -> A += B
- [x] A = A-B -> A -= B
- [x] A = A*B -> A *= B
- [x] A = A/B -> A /= B
- [x] A = A**B -> A **= B
- [x] A = A%B -> A %= B
- [x] A = max(A,B) -> A max= B
- [x] A = min(A,B) -> A min= B
**Arrays:**
- [x] A[0] -> first of(A)
- [x] [1,2,3][2] -> 3
- [x] [1,2,3][3] -> 0
- [x] [1,2,3].last() -> 3
- [x] [1,2,3].slice(1,2) -> [2,3]
- [x] filtered(A, constant) -> A if constant else [] (if not optimizing for size)
- [x] filtered(A, current array element != B) -> remove from array(A, B)
**Function calculations with literals:**
- [x] sqrt
- [x] cos
- [x] cosDeg
- [x] sin
- [x] sinDeg
- [x] tan
- [x] tanDeg
- [x] atan2
- [x] atan2Deg
- [x] acos
- [x] acosDeg
- [x] asin
- [x] asinDeg
- [x] normalize
- [x] distance
- [x] abs
- [x] len
- [x] crossProduct
- [x] directionTowards
- [x] dotProduct
- [x] max
- [x] min
- [x] getOppositeTeam
- [x] floor
- [x] ceil
- [x] round
- [x] vectorTowards
**Function combinations that map to a function already built-in to the workshop:**
- [x] normalize(vectorTowards(a,b)) -> directionTowards(a,b)
- [x] not B.isAlive() -> is dead(B)
- [x] not B.isDead() -> is alive(B)
- [x] [p for p in getPlayers(B) if p.getCurrentHero() == C] -> getPlayersOnHero(C, B)
- [x] [p for p in getPlayers(B) if p.isOnObjective()] -> getPlayersOnObjective(B)
- [x] [p for p in getPlayers(B) if not p.isOnObjective()] -> getPlayersNotOnObjective(B)
- [x] [p for p in getPlayers(B) if p.isAlive()] -> getLivingPlayers(B)
- [x] [p for p in getPlayers(B) if p.isDead()] -> getDeadPlayers(B)
- [x] len(getPlayers(B)) -> getNumberOfPlayers(B)
- [x] len(getPlayersOnObjective(B)) -> getNumberOfPlayersOnObjective(B)
- [x] len(getPlayersOnHero(B, C)) -> getNumberOfHeroes(B, C)
- [x] len(getLivingPlayers(B)) -> getNumberOfLivingPlayers(B)
- [x] len(getDeadPlayers(B)) -> getNumberOfDeadPlayers(B)
**Vectors:**
- [x] vect(a,b,c).x -> A
- [x] vect(a,b,c).y -> B
- [x] vect(a,b,c).z -> C
- [x] vect(0,1,0) -> Vector.LEFT (and the other 5 constants)
**Conditions:**
- [x] if x: abort -> abort if (x)
- [x] if x: goto RULE_START -> loop if (x)
- [x] if x: goto lbl_0 -> skip if(x, distanceto(lbl_0))
- [x] if false -> remove if block
- [x] A if true else B -> A
- [x] A if false else B -> B
- [x] A if B else A -> A
- [x] A if not B else C -> C if B else A
**Loops:**
- [x] while false -> remove while block
- [x] do/while false -> remove loop instruction
**Rule conditions:**
- [x] if (false) (rule condition) -> remove rule
- [x] if (true) (rule condition) -> remove condition
- [x] A and B -> split in rule conditions
**Rule actions:**
- [x] remove rule if no actions
- [x] remove useless instructions if no dynamic gotos
- [x] remove rule if only control flow actions
**Strings:**
- [x] Replace localized strings by custom strings if the localized strings have no localization
Multiplication:
Power:
*Arrays:
Function calculations with literals:
Function combinations that map to a function already built-in to the workshop:
Conditions:
If no usage of
RULE_CONDITION
orwait
, replace in rule conditions:Dictionaries:
Switches:
switchVar * caseOffset + firstCaseOffset
Colors:
Reevaluation:
Conditional optimizations based on arguments:
Player.startForcingOutlineFor
is false -> color is nullcreateBeam
withBeam.GRAPPLE
-> color is nullcreateEffect
with sound effect -> color is nullplayEffect
with sound effect -> color is nullhudText
with null header/subtext/subheader -> null corresponding colorwaitUntil(truthy, X)
->pass
(?)progressBarHud
with no text -> text color is nullcreateProgressBarInWorldText
with no text -> text color is nullApplied optimizations
Click to show
**Addition:** - [x] A+0 -> A - [x] A+A -> A*2 - [x] 1+2 -> 3 - [x] vect(1,1,1)+vect(2,2,2) -> vect(3,3,3) **Substraction:** - [x] A-0 -> A - [x] A-A -> 0 - [x] 1-2 -> -1 - [x] vect(3,3,3)-vect(2,2,2) -> vect(1,1,1) **Negation:** - [x] --A -> A - [x] -vect(1,2,3) -> vect(-1,-2,-3) **Multiplication:** - [x] A*1 -> A - [x] A*0 -> 0 - [x] 1*2 -> 2 - [x] 2*vect(1,1,1) -> vect(2,2,2) - [x] vect(1,2,3)*vect(4,5,6) -> vect(4,10,18) **Division:** - [x] A/1 -> A - [x] 1/2 -> 0.5 - [x] A/0 -> 0 - [x] 0/A -> 0 - [x] vect(3,3,3)/vect(1,2,3) -> vect(3,1.5,1) - [x] vect(1,2,3)/2 -> vect(0.5,1,1.5) **Modulo:** - [x] A%0 -> 0 - [x] A%A -> 0 - [x] 0%A -> 0 - [x] 5%3 -> 2 **Power:** - [x] 0**A -> 0 - [x] 1**A -> 1 - [x] [negative number]**A -> 0 - [x] 2**3 -> 8 **And:** - [x] A and False -> False - [x] A and True -> A - [x] A and A -> A - [x] A and not(A) -> False **Or:** - [x] A or False -> A - [x] A or True -> True - [x] A or A -> A - [x] A or not(A) -> True **Not:** - [x] Not True -> False - [x] Not False -> True - [x] Not Not A -> A if A is bool **Equality:** - [x] A == A -> True - [x] 1 == 2 -> False - [x] A != A -> False - [x] 1 != 2 -> True - [x] A > A -> False - [x] 1 > 2 -> False - [x] A >= A -> True - [x] 1 >= 2 -> False - [x] A < A -> False - [x] 1 < 2 -> True - [x] A <= A -> True - [x] 1 <= 2 -> True - [x] A == falsy -> Not A (due to #182, only done if A is a boolean function) - [x] A == true -> A (if A is boolean) - [x] A != falsy -> A (if expecting boolean or A is boolean) (due to #182, only done if A is a boolean function) - [x] A != true -> not A (if A is boolean) **Assignment:** - [x] A = A -> nothing - [x] A = A+B -> A += B - [x] A = A-B -> A -= B - [x] A = A*B -> A *= B - [x] A = A/B -> A /= B - [x] A = A**B -> A **= B - [x] A = A%B -> A %= B - [x] A = max(A,B) -> A max= B - [x] A = min(A,B) -> A min= B **Arrays:** - [x] A[0] -> first of(A) - [x] [1,2,3][2] -> 3 - [x] [1,2,3][3] -> 0 - [x] [1,2,3].last() -> 3 - [x] [1,2,3].slice(1,2) -> [2,3] - [x] filtered(A, constant) -> A if constant else [] (if not optimizing for size) - [x] filtered(A, current array element != B) -> remove from array(A, B) **Function calculations with literals:** - [x] sqrt - [x] cos - [x] cosDeg - [x] sin - [x] sinDeg - [x] tan - [x] tanDeg - [x] atan2 - [x] atan2Deg - [x] acos - [x] acosDeg - [x] asin - [x] asinDeg - [x] normalize - [x] distance - [x] abs - [x] len - [x] crossProduct - [x] directionTowards - [x] dotProduct - [x] max - [x] min - [x] getOppositeTeam - [x] floor - [x] ceil - [x] round - [x] vectorTowards **Function combinations that map to a function already built-in to the workshop:** - [x] normalize(vectorTowards(a,b)) -> directionTowards(a,b) - [x] not B.isAlive() -> is dead(B) - [x] not B.isDead() -> is alive(B) - [x] [p for p in getPlayers(B) if p.getCurrentHero() == C] -> getPlayersOnHero(C, B) - [x] [p for p in getPlayers(B) if p.isOnObjective()] -> getPlayersOnObjective(B) - [x] [p for p in getPlayers(B) if not p.isOnObjective()] -> getPlayersNotOnObjective(B) - [x] [p for p in getPlayers(B) if p.isAlive()] -> getLivingPlayers(B) - [x] [p for p in getPlayers(B) if p.isDead()] -> getDeadPlayers(B) - [x] len(getPlayers(B)) -> getNumberOfPlayers(B) - [x] len(getPlayersOnObjective(B)) -> getNumberOfPlayersOnObjective(B) - [x] len(getPlayersOnHero(B, C)) -> getNumberOfHeroes(B, C) - [x] len(getLivingPlayers(B)) -> getNumberOfLivingPlayers(B) - [x] len(getDeadPlayers(B)) -> getNumberOfDeadPlayers(B) **Vectors:** - [x] vect(a,b,c).x -> A - [x] vect(a,b,c).y -> B - [x] vect(a,b,c).z -> C - [x] vect(0,1,0) -> Vector.LEFT (and the other 5 constants) **Conditions:** - [x] if x: abort -> abort if (x) - [x] if x: goto RULE_START -> loop if (x) - [x] if x: goto lbl_0 -> skip if(x, distanceto(lbl_0)) - [x] if false -> remove if block - [x] A if true else B -> A - [x] A if false else B -> B - [x] A if B else A -> A - [x] A if not B else C -> C if B else A **Loops:** - [x] while false -> remove while block - [x] do/while false -> remove loop instruction **Rule conditions:** - [x] if (false) (rule condition) -> remove rule - [x] if (true) (rule condition) -> remove condition - [x] A and B -> split in rule conditions **Rule actions:** - [x] remove rule if no actions - [x] remove useless instructions if no dynamic gotos - [x] remove rule if only control flow actions **Strings:** - [x] Replace localized strings by custom strings if the localized strings have no localization