• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

wurstscript / WurstScript / 228

29 Nov 2023 05:00PM UTC coverage: 62.48% (-0.09%) from 62.574%
228

push

circleci

web-flow
Show dialog for choosing game path, cleanup (#1083)

* show dialog for choosing game path

* cleanup code

* remove logs and refactor

* remove confusing mpq error, make some mpq loads readonly

17295 of 27681 relevant lines covered (62.48%)

0.62 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.18
de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/translation/imoptimizer/UselessFunctionCallsRemover.java
1
package de.peeeq.wurstscript.translation.imoptimizer;
2

3
import de.peeeq.wurstscript.WurstOperator;
4
import de.peeeq.wurstscript.jassIm.*;
5
import de.peeeq.wurstscript.translation.imtranslation.ImHelper;
6
import de.peeeq.wurstscript.translation.imtranslation.ImTranslator;
7
import io.vavr.collection.HashSet;
8
import io.vavr.collection.Set;
9

10
import java.util.ListIterator;
11

12
/**
13
 * this optimization is supposed to remove useless calls like
14
 * <p>
15
 * I2S(5)
16
 * <p>
17
 * when the result is not used
18
 */
19
public class UselessFunctionCallsRemover implements OptimizerPass {
1✔
20
    public int totalCallsRemoved = 0;
1✔
21

22
    public int optimize(ImTranslator trans) {
23
        totalCallsRemoved = 0;
1✔
24
        ImProg prog = trans.getImProg();
1✔
25
        for (ImFunction func : prog.getFunctions()) {
1✔
26
            optimizeFunc(func, trans);
1✔
27
        }
1✔
28
        return totalCallsRemoved;
1✔
29
    }
30

31
    @Override
32
    public String getName() {
33
        return "Useless function calls removed";
1✔
34
    }
35

36
    private void optimizeFunc(ImFunction func, ImTranslator trans) {
37
        optimizeStmts(func.getBody());
1✔
38
        func.flatten(trans);
1✔
39
    }
1✔
40

41
    private void optimizeStmts(ImStmts stmts) {
42
        ListIterator<ImStmt> it = stmts.listIterator();
1✔
43
        while (it.hasNext()) {
1✔
44
            ImStmt s = it.next();
1✔
45

46
            if (s instanceof ImFunctionCall) {
1✔
47
                ImFunctionCall fc = (ImFunctionCall) s;
1✔
48
                if (isNativeWithoutSideEffect(fc.getFunc())) {
1✔
49
                    if (!isWantedError(fc)) {
1✔
50
                        // put arguments into a list of statements
51
                        ImStmts newStmts = JassIm.ImStmts();
1✔
52
                        for (ImExpr arg : fc.getArguments()) {
1✔
53
                            // remove from current call
54
                            arg.setParent(null);
1✔
55
                            // and move to new statements
56
                            newStmts.add(arg);
1✔
57
                        }
1✔
58
                        s = ImHelper.statementExprVoid(newStmts);
1✔
59
                        it.set(s);
1✔
60
                        totalCallsRemoved++;
1✔
61
                    }
62
                }
63
            }
64
            optimizeChildren(s);
1✔
65
        }
1✔
66
    }
1✔
67

68
    /**
69
     * a call like fooo(_ / 0) is considered a wanted error and kept
70
     */
71
    private boolean isWantedError(ImFunctionCall fc) {
72
        if (fc.getArguments().size() != 1) {
1✔
73
            return false;
1✔
74
        }
75
        return isDivisionByZero(fc.getArguments().get(0));
1✔
76
    }
77

78
    private boolean isDivisionByZero(ImExpr e) {
79
        if (e instanceof ImOperatorCall) {
1✔
80
            ImOperatorCall oc = (ImOperatorCall) e;
1✔
81
            if (oc.getOp() == WurstOperator.DIV_INT) {
1✔
82
                ImExpr dividend = oc.getArguments().get(1);
1✔
83
                if (dividend instanceof ImIntVal) {
1✔
84
                    ImIntVal v = (ImIntVal) dividend;
1✔
85
                    return v.getValI() == 0;
1✔
86
                }
87
            }
88
        }
89
        return false;
1✔
90
    }
91

92
    private void optimizeChildren(Element e) {
93
        for (int i = 0; i < e.size(); i++) {
1✔
94
            optimizeElement(e.get(i));
1✔
95
        }
96
    }
1✔
97

98
    private void optimizeElement(Element e) {
99
        if (e instanceof ImStmts) {
1✔
100
            ImStmts stmts = (ImStmts) e;
1✔
101
            optimizeStmts(stmts);
1✔
102
        } else {
1✔
103
            optimizeChildren(e);
1✔
104
        }
105
    }
1✔
106

107
    private boolean isNativeWithoutSideEffect(ImFunction func) {
108
        return func.isNative() && isFunctionWithoutSideEffect(func.getName());
1✔
109
    }
110

111
    /**
112
     * checks if the jass-function with the given name can have no side effects.
113
     * Note that these are not all pure functions, some of these functions depend
114
     * on external state, but they never change it.
115
     */
116
    public static boolean isFunctionWithoutSideEffect(String funcName) {
117
        return functionsWithoutSideEffects.contains(funcName);
1✔
118
    }
119

120
    public static boolean isFunctionPure(String funcName) {
121
        return pureFunctions.contains(funcName);
×
122
    }
123

124
    private static final Set<String> functionsWithoutSideEffects = HashSet.of(
1✔
125
        "AbilityId", "AbilityId2String", "Acos", "And", "Asin", "Atan",
126
        "Atan2", "ConvertAIDifficulty", "ConvertAllianceType", "ConvertAttackType", "ConvertBlendMode",
127
        "ConvertCameraField", "ConvertDamageType", "ConvertDialogEvent", "ConvertEffectType",
128
        "ConvertFGameState", "ConvertFogState", "ConvertGameDifficulty", "ConvertGameEvent",
129
        "ConvertGameSpeed", "ConvertGameType", "ConvertIGameState", "ConvertItemType", "ConvertLimitOp",
130
        "ConvertMapControl", "ConvertMapDensity", "ConvertMapFlag", "ConvertMapSetting",
131
        "ConvertMapVisibility", "ConvertPathingType", "ConvertPlacement", "ConvertPlayerColor",
132
        "ConvertPlayerEvent", "ConvertPlayerGameResult", "ConvertPlayerScore", "ConvertPlayerSlotState",
133
        "ConvertPlayerState", "ConvertPlayerUnitEvent", "ConvertRace", "ConvertRacePref",
134
        "ConvertRarityControl", "ConvertSoundType", "ConvertStartLocPrio", "ConvertTexMapFlags",
135
        "ConvertUnitEvent", "ConvertUnitState", "ConvertUnitType", "ConvertVersion", "ConvertVolumeGroup",
136
        "ConvertWeaponType", "ConvertWidgetEvent", "Cos", "Deg2Rad", "FirstOfGroup", "GetAbilityEffect",
137
        "GetAbilityEffectById", "GetAbilitySound", "GetAbilitySoundById", "GetAllyColorFilterState",
138
        "GetAttacker", "GetBuyingUnit", "GetCameraBoundMaxX", "GetCameraBoundMaxY", "GetCameraBoundMinX",
139
        "GetCameraBoundMinY", "GetCameraEyePositionLoc", "GetCameraEyePositionX", "GetCameraEyePositionY",
140
        "GetCameraEyePositionZ", "GetCameraField", "GetCameraMargin", "GetCameraTargetPositionLoc",
141
        "GetCameraTargetPositionX", "GetCameraTargetPositionY", "GetCameraTargetPositionZ",
142
        "GetCancelledStructure", "GetChangingUnit", "GetChangingUnitPrevOwner", "GetClickedButton",
143
        "GetClickedDialog", "GetConstructedStructure", "GetConstructingStructure", "GetCreatureDensity",
144
        "GetCreepCampFilterState", "GetCustomCampaignButtonVisible", "GetDecayingUnit",
145
        "GetDefaultDifficulty", "GetDestructableLife", "GetDestructableMaxLife", "GetDestructableName",
146
        "GetDestructableOccluderHeight", "GetDestructableTypeId", "GetDestructableX", "GetDestructableY",
147
        "GetDetectedUnit", "GetDyingUnit", "GetEnteringUnit", "GetEnumDestructable", "GetEnumItem",
148
        "GetEnumPlayer", "GetEnumUnit", "GetEventDamage", "GetEventDamageSource", "GetEventDetectingPlayer",
149
        "GetEventGameState", "GetEventPlayerChatString", "GetEventPlayerChatStringMatched",
150
        "GetEventPlayerState", "GetEventTargetUnit", "GetEventUnitState", "GetExpiredTimer",
151
        "GetFilterDestructable", "GetFilterItem", "GetFilterPlayer", "GetFilterUnit", "GetFloatGameState",
152
        "GetFoodMade", "GetFoodUsed", "GetGameDifficulty", "GetGamePlacement", "GetGameSpeed",
153
        "GetGameTypeSelected", "GetHandleId", "GetHeroAgi", "GetHeroInt", "GetHeroLevel",
154
        "GetHeroProperName", "GetHeroSkillPoints", "GetHeroStr", "GetHeroXP", "GetIntegerGameState",
155
        "GetIssuedOrderId", "GetItemCharges", "GetItemLevel", "GetItemName", "GetItemPlayer", "GetItemType",
156
        "GetItemTypeId", "GetItemUserData", "GetItemX", "GetItemY", "GetKillingUnit", "GetLearnedSkill",
157
        "GetLearnedSkillLevel", "GetLearningUnit", "GetLeavingUnit", "GetLevelingUnit",
158
        "GetLightningColorA", "GetLightningColorB", "GetLightningColorG", "GetLightningColorR",
159
        "GetLoadedUnit", "GetLocalizedHotkey", "GetLocalizedString", "GetLocationX", "GetLocationY",
160
        "GetLocationZ", "GetManipulatedItem", "GetManipulatingUnit", "GetObjectName", "GetOrderedUnit",
161
        "GetOrderPointLoc", "GetOrderPointX", "GetOrderPointY", "GetOrderTarget",
162
        "GetOrderTargetDestructable", "GetOrderTargetItem", "GetOrderTargetUnit", "GetOwningPlayer",
163
        "GetPlayerAlliance", "GetPlayerColor", "GetPlayerController", "GetPlayerHandicap",
164
        "GetPlayerHandicapXP", "GetPlayerId", "GetPlayerName", "GetPlayerRace", "GetPlayers",
165
        "GetPlayerScore", "GetPlayerSelectable", "GetPlayerSlotState", "GetPlayerStartLocation",
166
        "GetPlayerState", "GetPlayerStructureCount", "GetPlayerTaxRate", "GetPlayerTeam",
167
        "GetPlayerTechCount", "GetPlayerTechMaxAllowed", "GetPlayerTechResearched",
168
        "GetPlayerTypedUnitCount", "GetPlayerUnitCount", "GetRectCenterX",
169
        "GetRectCenterY", "GetRectMaxX", "GetRectMaxY", "GetRectMinX", "GetRectMinY", "GetRescuer",
170
        "GetResearched", "GetResearchingUnit", "GetResourceAmount", "GetResourceDensity",
171
        "GetRevivableUnit", "GetRevivingUnit", "GetSaveBasicFilename", "GetSelectedUnit", "GetSellingUnit",
172
        "GetSoldItem", "GetSoldUnit", "GetSoundDuration", "GetSoundFileDuration", "GetSoundIsLoading",
173
        "GetSoundIsPlaying", "GetSpellAbility", "GetSpellAbilityId", "GetSpellAbilityUnit",
174
        "GetSpellTargetDestructable", "GetSpellTargetItem", "GetSpellTargetLoc", "GetSpellTargetUnit",
175
        "GetSpellTargetX", "GetSpellTargetY", "GetStartLocationLoc", "GetStartLocationX",
176
        "GetStartLocationY", "GetStartLocPrio", "GetStartLocPrioSlot", "GetStoredBoolean",
177
        "GetStoredInteger", "GetStoredReal", "GetStoredString", "GetSummonedUnit", "GetSummoningUnit",
178
        "GetTeams", "GetTerrainCliffLevel", "GetTerrainType", "GetTerrainVariance",
179
        "GetTournamentFinishNowPlayer", "GetTournamentFinishNowRule",
180
        "GetTournamentFinishSoonTimeRemaining", "GetTournamentScore", "GetTrainedUnit",
181
        "GetTrainedUnitType", "GetTransportUnit", "GetTriggerDestructable", "GetTriggerEvalCount",
182
        "GetTriggerEventId", "GetTriggerExecCount", "GetTriggeringRegion", "GetTriggeringTrackable",
183
        "GetTriggeringTrigger", "GetTriggerPlayer", "GetTriggerUnit", "GetTriggerWidget",
184
        "GetUnitAbilityLevel", "GetUnitAcquireRange", "GetUnitCurrentOrder", "GetUnitDefaultAcquireRange",
185
        "GetUnitDefaultFlyHeight", "GetUnitDefaultMoveSpeed", "GetUnitDefaultPropWindow",
186
        "GetUnitDefaultTurnSpeed", "GetUnitFacing", "GetUnitFlyHeight", "GetUnitFoodMade",
187
        "GetUnitFoodUsed", "GetUnitLevel", "GetUnitLoc", "GetUnitMoveSpeed", "GetUnitName",
188
        "GetUnitPointValue", "GetUnitPointValueByType", "GetUnitPropWindow", "GetUnitRace",
189
        "GetUnitRallyDestructable", "GetUnitRallyPoint", "GetUnitRallyUnit", "GetUnitState",
190
        "GetUnitTurnSpeed", "GetUnitTypeId", "GetUnitUserData", "GetUnitX", "GetUnitY", "GetWidgetLife",
191
        "GetWidgetX", "GetWidgetY", "GetWinningPlayer", "GetWorldBounds", "HaveSavedBoolean",
192
        "HaveSavedHandle", "HaveSavedInteger", "HaveSavedReal", "HaveSavedString", "HaveStoredBoolean",
193
        "HaveStoredInteger", "HaveStoredReal", "HaveStoredString", "HaveStoredUnit", "I2R", "I2S",
194
        "IsCineFilterDisplayed", "IsDestructableInvulnerable", "IsFogEnabled", "IsFoggedToPlayer",
195
        "IsFogMaskEnabled", "IsGameTypeSupported", "IsHeroUnitId", "IsItemIdPawnable", "IsItemIdPowerup",
196
        "IsItemIdSellable", "IsItemInvulnerable", "IsItemOwned", "IsItemPawnable", "IsItemPowerup",
197
        "IsItemSellable", "IsItemVisible", "IsLeaderboardDisplayed", "IsLocationFoggedToPlayer",
198
        "IsLocationInRegion", "IsLocationMaskedToPlayer", "IsLocationVisibleToPlayer", "IsMapFlagSet",
199
        "IsMaskedToPlayer", "IsMultiboardDisplayed", "IsMultiboardMinimized", "IsNoDefeatCheat",
200
        "IsNoVictoryCheat", "IsPlayerAlly", "IsPlayerEnemy", "IsPlayerInForce", "IsPlayerObserver",
201
        "IsPlayerRacePrefSet", "IsPointBlighted", "IsPointInRegion", "IsQuestCompleted",
202
        "IsQuestDiscovered", "IsQuestEnabled", "IsQuestFailed", "IsQuestItemCompleted", "IsQuestRequired",
203
        "IsSuspendedXP", "IsTerrainPathable", "IsTimerDialogDisplayed", "IsTriggerEnabled",
204
        "IsTriggerWaitOnSleeps", "IsUnit", "IsUnitAlly", "IsUnitDetected", "IsUnitEnemy", "IsUnitFogged",
205
        "IsUnitHidden", "IsUnitIdType", "IsUnitIllusion", "IsUnitInForce", "IsUnitInGroup", "IsUnitInRange",
206
        "IsUnitInRangeLoc", "IsUnitInRangeXY", "IsUnitInRegion", "IsUnitInTransport", "IsUnitInvisible",
207
        "IsUnitLoaded", "IsUnitMasked", "IsUnitOwnedByPlayer", "IsUnitPaused", "IsUnitRace",
208
        "IsUnitSelected", "IsUnitType", "IsUnitVisible", "IsVisibleToPlayer", "LoadAbilityHandle",
209
        "LoadBoolean", "LoadBooleanExprHandle", "LoadButtonHandle", "LoadDefeatConditionHandle",
210
        "LoadDestructableHandle", "LoadDialogHandle", "LoadEffectHandle", "LoadFogModifierHandle",
211
        "LoadFogStateHandle", "LoadForceHandle", "LoadGroupHandle", "LoadHashtableHandle",
212
        "LoadImageHandle", "LoadInteger", "LoadItemHandle", "LoadItemPoolHandle", "LoadLeaderboardHandle",
213
        "LoadLightningHandle", "LoadLocationHandle", "LoadMultiboardHandle", "LoadMultiboardItemHandle",
214
        "LoadPlayerHandle", "LoadQuestHandle", "LoadQuestItemHandle", "LoadReal", "LoadRectHandle",
215
        "LoadRegionHandle", "LoadSoundHandle", "LoadStr", "LoadTextTagHandle", "LoadTimerDialogHandle",
216
        "LoadTimerHandle", "LoadTrackableHandle", "LoadTriggerActionHandle", "LoadTriggerConditionHandle",
217
        "LoadTriggerEventHandle", "LoadTriggerHandle", "LoadUbersplatHandle", "LoadUnitHandle",
218
        "LoadUnitPoolHandle", "LoadWidgetHandle", "Not", "Or", "OrderId", "OrderId2String", "Player", "Pow", "R2I",
219
        "R2S", "R2SW", "Rad2Deg", "S2I", "S2R", "Sin", "SquareRoot", "StringCase", "StringHash",
220
        "StringLength", "SubString", "Tan", "TimerGetElapsed", "TimerGetRemaining", "TimerGetTimeout",
221
        "VersionGet", "WaygateGetDestinationX", "WaygateGetDestinationY", "WaygateIsActive",
222
        "BlzGetTriggerPlayerMouseX", "BlzGetTriggerPlayerMouseY", "BlzGetTriggerPlayerMousePosition",
223
        "BlzGetTriggerPlayerMouseButton", "BlzGetAbilityTooltip", "BlzGetAbilityActivatedTooltip",
224
        "BlzGetAbilityExtendedTooltip", "BlzGetAbilityActivatedExtendedTooltip", "BlzGetAbilityResearchTooltip",
225
        "BlzGetAbilityResearchExtendedTooltip", "BlzGetAbilityIcon", "BlzGetAbilityActivatedIcon", "BlzGetAbilityPosX",
226
        "BlzGetAbilityPosY", "BlzGetAbilityActivatedPosX", "BlzGetAbilityActivatedPosY", "BlzGetUnitMaxHP",
227
        "BlzGetUnitMaxMana", "BlzGetItemDescription", "BlzGetItemTooltip", "BlzGetItemExtendedTooltip",
228
        "BlzGetItemIconPath", "BlzGetUnitBaseDamage", "BlzGetUnitDiceNumber", "BlzGetUnitDiceSides",
229
        "BlzGetUnitAttackCooldown", "BlzGetLocalSpecialEffectX", "BlzGetLocalSpecialEffectY",
230
        "BlzGetLocalSpecialEffectZ", "BlzGetAnimName", "BlzGetUnitArmor", "BlzIsUnitSelectable",
231
        "BlzIsUnitInvulnerable", "BlzGetUnitCollisionSize", "BlzGetAbilityManaCost", "BlzGetAbilityCooldown",
232
        "BlzGetUnitAbilityCooldown", "BlzGetUnitAbilityCooldownRemaining", "BlzGetUnitAbilityManaCost",
233
        "BlzGetLocalUnitZ", "BlzGetEventDamageTarget", "BlzGetEventAttackType", "BlzGetEventDamageType",
234
        "BlzGetEventWeaponType", "BlzGetEventIsAttack", "BlzGetUnitZ", "BlzIsSelectionEnabled",
235
        "BlzIsSelectionCircleEnabled", "BlzIsTargetIndicatorEnabled", "BlzGetOriginFrame", "BlzGetFrameByName",
236
        "BlzFrameGetName", "BlzFrameGetText", "BlzFrameGetTextSizeLimit", "BlzFrameGetEnable", "BlzFrameGetAlpha",
237
        "BlzFrameGetValue", "BlzFrameGetParent", "BlzFrameGetHeight", "BlzFrameGetWidth", "BlzGetTriggerFrame",
238
        "BlzGetTriggerFrameEvent", "BlzGetTriggerFrameValue", "BlzGetTriggerFrameText", "BlzGetTriggerSyncPrefix",
239
        "BlzGetTriggerPlayerKey", "BlzGetTriggerPlayerMetaKey", "BlzGetTriggerPlayerIsKeyDown",
240
        "BlzGetLocalClientWidth", "BlzGetLocalClientHeight", "BlzIsLocalClientActive", "BlzGetMouseFocusUnit",
241
        "BlzGetLocale", "BlzGetSpecialEffectScale", "BlzGetUnitAbility", "BlzGetUnitAbilityByIndex", "BlzBitOr",
242
        "BlzBitAnd", "BlzBitXor", "BlzGetAbilityBooleanField", "BlzGetAbilityIntegerField", "BlzGetAbilityRealField",
243
        "BlzGetAbilityStringField", "BlzGetAbilityBooleanLevelField", "BlzGetAbilityIntegerLevelField",
244
        "BlzGetAbilityRealLevelField", "BlzGetAbilityStringLevelField", "BlzGetAbilityBooleanLevelArrayField",
245
        "BlzGetAbilityIntegerLevelArrayField", "BlzGetAbilityRealLevelArrayField", "BlzGetAbilityStringLevelArrayField",
246
        "BlzGetItemAbilityByIndex", "BlzGetItemAbility", "BlzGetItemBooleanField", "BlzGetItemIntegerField",
247
        "BlzGetItemRealField", "BlzGetItemStringField", "BlzGetUnitBooleanField", "BlzGetUnitIntegerField",
248
        "BlzGetUnitRealField", "BlzGetUnitStringField", "BlzGetUnitWeaponBooleanField", "BlzGetUnitWeaponIntegerField",
249
        "BlzGetUnitWeaponRealField", "BlzGetUnitWeaponStringField", "BlzGetUnitSkin", "BlzGetItemSkin",
250
        "BlzGetPlayerTownHallCount"
251
        );
252

253
    private static final Set<String> pureFunctions = HashSet.of(
1✔
254
        "AbilityId", "AbilityId2String", "Acos", "And", "Asin", "Atan",
255
        "Atan2", "ConvertAIDifficulty", "ConvertAllianceType", "ConvertAttackType", "ConvertBlendMode",
256
        "ConvertCameraField", "ConvertDamageType", "ConvertDialogEvent", "ConvertEffectType",
257
        "ConvertFGameState", "ConvertFogState", "ConvertGameDifficulty", "ConvertGameEvent",
258
        "ConvertGameSpeed", "ConvertGameType", "ConvertIGameState", "ConvertItemType", "ConvertLimitOp",
259
        "ConvertMapControl", "ConvertMapDensity", "ConvertMapFlag", "ConvertMapSetting",
260
        "ConvertMapVisibility", "ConvertPathingType", "ConvertPlacement", "ConvertPlayerColor",
261
        "ConvertPlayerEvent", "ConvertPlayerGameResult", "ConvertPlayerScore", "ConvertPlayerSlotState",
262
        "ConvertPlayerState", "ConvertPlayerUnitEvent", "ConvertRace", "ConvertRacePref",
263
        "ConvertRarityControl", "ConvertSoundType", "ConvertStartLocPrio", "ConvertTexMapFlags",
264
        "ConvertUnitEvent", "ConvertUnitState", "ConvertUnitType", "ConvertVersion", "ConvertVolumeGroup",
265
        "ConvertWeaponType", "ConvertWidgetEvent", "Cos", "Deg2Rad", "GetAbilityEffect",
266
        "GetAbilityEffectById", "GetAbilitySound", "GetAbilitySoundById", "GetAllyColorFilterState",
267
        "GetPlayerColor", "GetPlayerController", "GetPlayerId", "GetPlayerRace", "GetPlayerSelectable",
268
        "GetPlayerStartLocation", "GetPlayerTeam", "GetSoundDuration", "GetSoundFileDuration", "GetStartLocationLoc",
269
        "GetStartLocationX", "GetStartLocationY", "GetStartLocPrio", "GetStartLocPrioSlot", "GetSummonedUnit",
270
        "GetSummoningUnit", "GetTeams", "GetUnitDefaultAcquireRange",
271
        "GetUnitDefaultFlyHeight", "GetUnitDefaultMoveSpeed", "GetUnitDefaultPropWindow",
272
        "GetUnitDefaultTurnSpeed", "GetUnitName", "GetWinningPlayer", "GetWorldBounds", "I2R", "I2S",
273
        "Not", "Or", "OrderId", "OrderId2String", "Player", "Pow", "R2I",
274
        "R2S", "R2SW", "Rad2Deg", "S2I", "S2R", "Sin", "SquareRoot", "StringCase", "StringHash",
275
        "StringLength", "SubString", "Tan", "VersionGet", "BlzBitOr", "BlzBitAnd", "BlzBitXor"
276
    );
277
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc