From 37dc118e5dbd7119a31684183253c4aa0945227f Mon Sep 17 00:00:00 2001 From: adapap <19696846+adapap@users.noreply.github.com> Date: Wed, 21 Aug 2019 19:53:25 -0400 Subject: [PATCH 1/7] Initial commit --- Clicker.owpy | 755 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 755 insertions(+) create mode 100644 Clicker.owpy diff --git a/Clicker.owpy b/Clicker.owpy new file mode 100644 index 0000000..5999ffa --- /dev/null +++ b/Clicker.owpy @@ -0,0 +1,755 @@ +%Global + Event + On Global +%Each(team_) + Event + On Each Player + team_ + All +%GameText(who, text, pos, scale) + World Text + Visible_To: who + Header: text + Position: pos + Scale: scale + Clipping: Clip Against Surfaces + Reevaluation: Visible To And String +%CodeText(who, code, pos, scale) + GameText(who, `Save: {} + {} + {} + {} + {}`(code[0], code[1], code[2], code[3], code[4]), pos, scale) +%BigHud(loc, text, color) + Hud + Visible_To: Event Player + Header: text + Subheader: Null + Text: Null + Location: loc + Sort_Order: 0 + Header_Color: color + Subheader_Color: White + Text_Color: White + Reevaluation: Visible To And String +%SmallHud(loc, text, color) + Hud + Visible_To: Event Player + Header: Null + Subheader: Null + Text: text + Location: loc + Sort_Order: 999 + Header_Color: White + Subheader_Color: White + Text_Color: color + Reevaluation: Visible To And String +%Sound(type) + Play Effect + Visible_To: Event Player + Type: type + Color: White + Position: Event Player + Radius: 50 +%SuccessSound + Sound(Buff Explosion Sound) +%FailSound + Sound(Debuff Impact Sound) +%WooshSound + Sound(Ring Explosion Sound) +%BoomSound + Sound(Explosion Sound) +%MissingFunds + Big Msg(Event Player, `Go Find More Money`) +%Warp(player, destination, facing) + Teleport(player, destination) + Set Facing + Player: Event Player + Direction: Vector Towards + Start: Event Player + End: facing + Relative: To World + Wait(0.1s) + Event Player.halt() +%Portal(pos, type, color, text) + Create Effect + Visible_To: Everyone + Type: type + Color: color + Position: pos + Radius: 1.5 + Reevaluation: Visible To + GameText(Everyone, text, (pos + Up), 1.5) +%UpgradePortal(pos) + Portal(pos, Good Aura, Yellow, "Upgrades") +%ShopPortal(pos) + Portal(pos, Good Aura, Purple, `Current Boss`) +%NextBossPortal(pos, text) + Portal(pos, Good Aura, Blue, text) +%UpgradeEffect(pos, color) + Create Effect + Visible_To: Everyone + Type: Orb + Color: color + Position: pos + Radius: 1.5 + Reevaluation: Visible To +%UpgradeText(upg, cost_var) + GameText(Event Player, `{}: {}`(upgrade_names[upg], cost_var), upgrade_positions[upg] + Up * 0.5, 1.5) +%SaveIcon(pos, icon, color) + Create Icon + Visible_To: Filter + Everyone + LOS + pos + Cur Elem + Barriers Do Not Block LOS + Position: pos + Icon: icon + Reevaluation: Visible To + Icon_Color: White + Show_When_Offscreen: False + Create Effect + Visible_To: Everyone + Type: Ring + Color: color + Position: pos + Radius: 1 + Reevaluation: Visible To Position And Radius +%SpawnBoss(boss) + Teleport + boss_player + boss_spawns[Index(boss_heroes, boss)] +%ResetPlayer + pvar location = 0 + pvar cur_boss = 0 + pvar bosses_killed = 0 + pvar money = 0 + pvar damage_scale = 1 + pvar damage_scale_cost = 5 + pvar reload_speed = 2.0 + pvar reload_speed_cost = 15 + pvar money_multiplier = 1 + pvar money_multiplier_cost = 10 + pvar hp = 10 + pvar hp_cost = 100 + pvar defense = 100 + pvar defense_cost = 25 + pvar ability1 = False + pvar ability2 = False + pvar money_cd = 0 + pvar damage_cd = 0 + Set Damage Dealt(Event Player, pvar damage_scale) + Set Damage Received(Event Player, pvar defense) + Set Max Health(Event Player, pvar hp) + Set Primary Fire Enabled(Event Player, True) + Set Ability 1 Enabled(Event Player, False) + Set Ability 2 Enabled(Event Player, False) + +Rule "Initialize Constants" + Global() + Actions + /* Define Player Variables */ + pvar location = 0 + pvar cur_boss = 0 + pvar bosses_killed = 0 + pvar money = 0 + pvar damage_scale = 1 + pvar damage_scale_cost = 5 + pvar reload_speed = 2.0 + pvar reload_speed_cost = 15 + pvar money_multiplier = 1 + pvar money_multiplier_cost = 10 + pvar hp = 10 + pvar hp_cost = 100 + pvar defense = 100 + pvar defense_cost = 25 + pvar ability1 = False + pvar ability2 = False + pvar money_cd = 0 + pvar damage_cd = 0 + /* Global Variables */ + shop_pos = <2.500, 3.500, 75> + player_spawns = [<-40, -1.5, 145.5>, <-29, 8, 56>, <-77.5, 1.5, 65.5>, <-50.5, 1.5, 117>, <43.5, 3.5, 73.5>, <-115, 1.5, 112.5>] + boss_spawns = [<-31.5, 0, 148>, <-22.5, 7.5, 66.5>, <-82.5, 1.5, 61>, <-59, 1, 104>, <53.5, 3.5, 72.5>, <-129, 2.5, 108.5>] + boss_heroes = [Hero(Roadhog), Hero(Soldier: 76), Hero(Mei), Hero(Lucio), Hero(Ana), Hero(Reaper)] + ability2_pos = <12.5, 2.5, 71> + ability1_pos = <12.5, 2.5, 71 + 2.5> + ability1_cost = 25000 + ability2_cost = 10000 + Set Match Time(90min) + +Rule "Initialize Player Stats" + Each(Team 1) + Actions + /* Player Variables */ + ResetPlayer() + pvar credits = 0 + pvar save_code = [] + +Rule "Initialize Effects (Portals / Upgrades / Saves / Boundaries)" + Global() + Actions + portals = [<-50, 1, 137.350>, <-37, 6.5, 48>, <-71, 1.5, 62.5>, <-58, 2, 122>, <41, 3.5, 78.5>, <-118.5, 1.5, 99.5>] + next_boss_portals = [<-55, 1.5, 141.5>, <-25.5, 7.5, 50.5>, <-80, 1.5, 71>, <-63, 2.5, 115.5>, <41, 3.5, 67.5>] + next_boss_cost = [1000, 12.5 * 1000, 75 * 1000, 350 * 1000, 1500 * 1000] + shop_portal = <-7, 3, 75> + upgr_pos = <3, 2.5, 70> + save_pos = <3.5, 6.5, 86> + prestige_pos = <-172, 3, 96> + soldier_temp_pos = <3, 3, 77.5> + x_offset = <2.5, 0, 0> + z_offset = <0, 0, 2.5> + upgrade_names = ["Heal", "Damage", "Faster", "Money", "Defend"] + upgrade_rates = [100, 1.003, 1.04, 1.045, 1.03] + upgrade_positions = [] + for i in range(-2, 3): + upgrade_positions.append(upgr_pos + i * x_offset) + upgrade_colors = [Purple, Red, Yellow, Green, Blue] + // Bosses 1-6 -> Shop + for portal in portals: + UpgradePortal(portal) + ShopPortal(shop_portal) + // HP, Damage, Reload Speed, Money Multiplier, Damage Resistance + for i in range(5): + UpgradeEffect(upgrade_positions[i], upgrade_colors[i]) + // Next Boss + for i in range(5): + NextBossPortal(next_boss_portals[i], `Next Boss: {}`(next_boss_cost[i])) + Portal(prestige_pos, Bad Aura, Red, `Start Over`) + // Saves + SaveIcon(save_pos - z_offset, Arrow: Up, Green) + SaveIcon(save_pos + z_offset, Arrow: Down, Red) + SaveIcon(save_pos - x_offset, Arrow: Left, Blue) + SaveIcon(save_pos + x_offset, Arrow: Right, Yellow) + // Abilities + UpgradeEffect(ability1_pos, White) + UpgradeEffect(ability2_pos, White) + UpgradeEffect(soldier_temp_pos, Blue) + GameText(All Players(Team 1), `Buy Ability 1: {}`(ability1_cost), ability1_pos + Up * 0.5, 1.5) + GameText(All Players(Team 1), `Buy Ability 2: {}`(ability2_cost), ability1_pos + Up * 0.5, 1.5) + GameText(All Players(Team 1), `Unlock {}: {} Credit`(Hero(Soldier: 76), 1), soldier_temp_pos + Up * 0.5, 1.5) + // Secrets + secret2_pos = <31, 2.5, 49.5> + CodeText(Players In Radius(secret2_pos, 5, Team(All), Off), ["Left", "Up", "Down", "Up", "Right"], secret2_pos, 0.75) + +Rule "Initialize Player HUD Stats" + Each(Team 1) + Actions + BigHud(Top, `Money: {}`(pvar money), White) + SmallHud(Top, `{} Credits ({} / {} Boss Kills)`(pvar credits, pvar bosses_killed, 6), Purple) + SmallHud(Top, `{}% Money`(pvar money_multiplier * 100), Green) + SmallHud(Top, `{} Sec`(pvar reload_speed), Yellow) + SmallHud(Top, `Damage: {}% / Defend: {}%`(pvar damage_scale, pvar defense), Red) + // Player Stats Over Head + World Text + Visible_To: All Players(Team 1) + Header: `Damage: {}% - {} sec - {}% Money` + pvar damage_scale + pvar reload_speed + pvar money_multiplier * 100 + Position: Event Player + Scale: 0.750 + Clipping: Clip Against Surfaces + Reevaluation: Visible To Position And String + +Rule "Validate Bosses" + Global() + Conditions + not All True + boss_heroes + Is Hero Being Played + Cur Elem + Team 2 + Actions + Msg + Everyone + `Warning: Bad Bosses` + for boss in boss_heroes: + if not Is Hero Being Played(boss, Team 2): + Msg + Everyone + `No {}`(boss) + Wait(20s) + Loop If Condition Is True + +%BossMovement(hero_, speed) + Set Move Speed(Players On Hero(hero_, Team 2), speed) + Clear Status(Players On Hero(hero_, Team 2), Rooted) +Rule "Initialize Bosses" + Global() + Conditions + All True + boss_heroes + Has Spawned + Players On Hero + Cur Elem + Team 2 + Actions + for boss in boss_heroes: + boss_player = Players On Hero(boss, Team 2) + SpawnBoss(boss) + Set Move Speed(boss_player, 0) + Set Status(boss_player, Null, Rooted, 9999) + GameText(Everyone, `Heal: {}`(Health(Players On Hero(boss, Team 2))), Players On Hero(boss, Team 2), 1) + BossMovement(Hero(Mei), 10) + BossMovement(Hero(Lucio), 100) + BossMovement(Hero(Reaper), 100) + +Rule "Respawn Bosses" + Event + Player Died + Team 2 + All + Actions + Respawn(Event Player) + Wait(0.1s) + Teleport(Event Player, boss_spawns[Index(boss_heroes, Event Player.hero)]) + +Rule "Initialize Upgrade Text" + Each(Team 1) + Actions + UpgradeText(0, pvar hp_cost) + UpgradeText(1, pvar damage_scale_cost) + UpgradeText(2, pvar reload_speed_cost) + UpgradeText(3, pvar money_multiplier_cost) + UpgradeText(4, pvar defense_cost) + +Rule "Teleport to Shop" + Each(Team 1) + Conditions + Any True + Array: portals + Condition: Distance Between + Event Player + Cur Elem + <= 2.0 + Actions + Warp(Event Player, shop_pos, upgr_pos) + WooshSound() + pvar location = -1 + +Rule "Teleport from Shop" + Each(Team 1) + Conditions + Distance Between + Event Player + shop_portal + <= 2.0 + pvar location == -1 + Actions + pvar location = pvar cur_boss + Wait(0.1s) + Warp(Event Player, player_spawns[pvar location], Closest Player To(Event Player, Team 2)) + WooshSound() + +Rule "Shop Boundary & Heal" + Each(Team 1) + Conditions + pvar location == -1 + Actions + while pvar location == -1: + Heal(Event Player, Null, 10000) + Wait(0.1s) + Skip If(Not((Event Player.pos.x <= -12) or (Event Player.pos.z <= 25)), 6) + Warp(Event Player, shop_pos, upgr_pos) + Msg(Event Player, `Avoid Going Here`) + FailSound() + +%BossBoundary(loc, hero_) + if Event Player in All Players(Team 1): + if pvar location == loc: + Teleport(Event Player, player_spawns[pvar cur_boss]) + Msg(Event Player, `Avoid Going Here`) + FailSound() + elif Event Player.hero == hero_: + Teleport(Event Player, boss_spawns[Index(boss_heroes, hero_)]) + +Rule "Boss Boundaries (Soldier: 76)" + Each(All) + Conditions + Event Player.pos.y < 4.5 + Actions + BossBoundary(1, Hero(Soldier: 76)) + Wait(2s) + Loop If Condition Is True +Rule "Boss Boundaries (Mei)" + Each(All) + Conditions + Event Player.pos.x > -72 + Actions + BossBoundary(2, Hero(Mei)) + Wait(2s) + Loop If Condition Is True +Rule "Boss Boundaries (Lucio)" + Each(All) + Conditions + not Event Player in Players In Radius(boss_spawns[3], 20, Team(All), Off) + Actions + BossBoundary(3, Hero(Lucio)) + Wait(2s) + Loop If Condition Is True +Rule "Boss Boundaries (Reaper)" + Each(All) + Conditions + Event Player.pos.x > -94 + Actions + BossBoundary(5, Hero(Reaper)) + Wait(2s) + Loop If Condition Is True + +%ShopCondition(pos) + Conditions + Event Player in Players In Radius(pos, 1.5, Team(All), Surfaces) + Event Player.interacting +%ShopAutobuy + Skip If(Not(Event Player.crouching), 2) + Wait(0.1s) + Loop If Condition Is True +Rule "Buy HP" + Each(Team 1) + ShopCondition(upgrade_positions[0]) + Actions + if pvar money >= pvar hp_cost: + pvar money -= pvar hp_cost + pvar hp_cost = ceil(pvar hp_cost + upgrade_rates[0]) + pvar hp += 10 + Set Max Health(Event Player, pvar hp) + SuccessSound() + ShopAutobuy() + else: + MissingFunds() + FailSound() + +Rule "Buy Damage %" + Each(Team 1) + ShopCondition(upgrade_positions[1]) + Actions + if pvar money >= pvar damage_scale_cost: + pvar money -= pvar damage_scale_cost + Skip If(pvar damage_scale >= 75, 1) + pvar damage_scale += 3 + Skip If(pvar damage_scale < 75, 1) + pvar damage_scale += 2 + Set Damage Dealt(Event Player, pvar damage_scale) + pvar damage_scale_cost = ceil(pvar damage_scale_cost ^ upgrade_rates[1]) + SuccessSound() + ShopAutobuy() + else: + MissingFunds() + FailSound() + +Rule "Buy Reload Speed" + Each(Team 1) + ShopCondition(upgrade_positions[2]) + Actions + if pvar money >= pvar reload_speed_cost: + pvar money -= pvar reload_speed_cost + pvar reload_speed_cost = ceil(pvar reload_speed_cost ^ upgrade_rates[2]) + pvar reload_speed = max(pvar reload_speed * 0.95, 0) + SuccessSound() + ShopAutobuy() + else: + MissingFunds() + FailSound() + +Rule "Buy Money Multiplier" + Each(Team 1) + ShopCondition(upgrade_positions[3]) + Actions + if pvar money >= pvar money_multiplier_cost: + pvar money -= pvar money_multiplier_cost + pvar money_multiplier_cost = ceil(pvar money_multiplier_cost ^ upgrade_rates[3]) + pvar money_multiplier += 0.075 + SuccessSound() + ShopAutobuy() + else: + MissingFunds() + FailSound() + +Rule "Buy Defense" + Each(Team 1) + ShopCondition(upgrade_positions[4]) + Actions + if (pvar money >= pvar defense_cost) and (pvar defense > 5): + pvar money -= pvar defense_cost + pvar defense_cost = ceil(pvar defense_cost ^ upgrade_rates[4]) + pvar defense = Max(pvar defense - 2, 5) + Set Damage Received(Event Player, pvar defense) + SuccessSound() + ShopAutobuy() + elif pvar defense == 5: + Msg(Event Player, `Max Defend`) + FailSound() + else: + MissingFunds() + FailSound() + +Rule "Buy Ability 1" + Each(Team 1) + ShopCondition(ability1_pos) + Actions + if (pvar money >= ability1_cost) and (not pvar ability1): + pvar money -= ability1_cost + pvar ability1 = True + Set Ability 1 Enabled(Event Player, True) + SuccessSound() + elif pvar ability1: + Msg(Event Player, `You Bought Ability 1`) + FailSound() + else: + MissingFunds() + +Rule "Buy Ability 2" + Each(Team 1) + ShopCondition(ability2_pos) + Actions + if (pvar money >= ability2_cost) and (not pvar ability2): + pvar money -= ability2_cost + pvar ability2 = True + Set Ability 2 Enabled(Event Player, True) + SuccessSound() + elif pvar ability2: + Msg(Event Player, `You Bought Ability 2`) + FailSound() + else: + MissingFunds() + +Rule "Teleport Player to Start" + Each(Team 1) + Conditions + Has Spawned(Event Player) + Actions + Teleport + Event Player + player_spawns[pvar cur_boss] + +Rule "Shooting Control" + Each(Team 1) + Conditions + Has Spawned(Event Player) + Is Firing Primary(Event Player) + Actions + Set Primary Fire Enabled(Event Player, False) + Wait(pvar reload_speed) + Set Primary Fire Enabled(Event Player, True) + +Rule "Attack Money" + Event + Player Dealt Damage + Team 1 + All + Actions + pvar money += ceil((Event Damage ^ (1 + pvar cur_boss / 3.5)) * pvar money_multiplier) + +Rule "Boss Kill" + Event + Player Dealt Final Blow + Team 1 + All + Actions + pvar money += (100 ^ (1 + pvar cur_boss / 2)) * pvar money_multiplier + pvar bosses_killed = Max(Index(boss_heroes, Victim.hero) + 1, pvar bosses_killed) + if pvar bosses_killed == 6: + Msg(Event Player, `Find Start Over`) + +Rule "Player Death" + Event + Player Died + Team 1 + All + Actions + Wait(0.1s) + pvar location = -1 + Warp(Event Player, shop_pos, upgr_pos) + +Rule "Next Boss" + Each(Team 1) + Conditions + Event Player in Players In Radius(next_boss_portals[pvar cur_boss], 2, Team(All), Off) + Actions + if (pvar money >= next_boss_cost[pvar cur_boss]) and (pvar bosses_killed > pvar cur_boss): + pvar money -= next_boss_cost[pvar cur_boss] + pvar cur_boss += 1 + Wait(0.1s) + Warp(Event Player, player_spawns[pvar cur_boss], boss_spawns[pvar cur_boss]) + pvar location = pvar cur_boss + WooshSound() + elif pvar money < next_boss_cost[pvar cur_boss]: + MissingFunds() + FailSound() + else: + Big Msg(Event Player, `Go Kill Boss`) + FailSound() + +%SaveInput(name, value, pos) + Rule "Save Input " + name + Each(Team 1) + Conditions + Distance Between(Event Player, pos) <= 1.25 + Event Player.interacting + Actions + Msg(Event Player, name) + pvar save_code.append(value) + BoomSound() + +SaveInput("Up", 0, save_pos - z_offset) +SaveInput("Down", 1, save_pos + z_offset) +SaveInput("Left", 2, save_pos - x_offset) +SaveInput("Right", 3, save_pos + x_offset) + +%UnlockHero(hero_) + pvar save_code_effect = Last Text Id + Destroy In-World Text(pvar save_code_effect) + Set Hero(Event Player, hero_) + Wait(0.5s) + Big Msg(Event Player, `You Unlocked {}`(Hero Icon String(hero_))) + SuccessSound() + Wait(0.25) + +Rule "Buy Prestige Item" + Each(Team 1) + ShopCondition(soldier_temp_pos) + Actions + if pvar credits >= 1: + pvar credits -= 1 + UnlockHero(Hero(Soldier: 76)) + else: + Big Msg(Event Player, `Defeat Final Boss`) + +Rule "Check Save Code" + Each(Team 1) + Conditions + Count Of(pvar save_code) == 5 + Actions + // 0: Up + // 1: Down + // 2: Left + // 3: Right + if pvar save_code == [0, 0, 0, 0, 0]: + UnlockHero(Hero(McCree)) + CodeText(Event Player, ["Up", "Up", "Up", "Up", "Up"], save_pos + Up * 1.25, 2) + elif pvar save_code == [3, 1, 2, 3, 2]: + UnlockHero(Hero(Soldier: 76)) + CodeText(Event Player, ["Right", "Down", "Left", "Right", "Left"], save_pos + Up * 1.25, 2) + elif pvar save_code == [0, 2, 2, 1, 3]: + UnlockHero(Hero(Ashe)) + CodeText(Event Player, ["Up", "Left", "Left", "Down", "Right"], save_pos + Up * 1.25, 2) + elif pvar save_code == [2, 3, 2, 0, 0]: + UnlockHero(Hero(Genji)) + CodeText(Event Player, ["Left", "Right", "Left", "Up", "Up"], save_pos + Up * 1.25, 2) + elif pvar save_code == [1, 1, 3, 1, 2]: + UnlockHero(Hero(Hanzo)) + CodeText(Event Player, ["Down", "Down", "Right", "Down", "Left"], save_pos + Up * 1.25, 2) + elif pvar save_code == [2, 0, 1, 0, 3]: // Secrets + Big Msg(Event Player, "Hacked") + // You Unlocked Hidden Save 2 + else: + Big Msg(Event Player, `Unknown Save`) + pvar save_code = [] + +Rule "Prestige Confirm" + Each(Team 1) + Conditions + Distance Between(Event Player, prestige_pos) <= 1.5 + Actions + Msg(Event Player, `Start Over? (Jump)`) + +Rule "Prestige" + Each(Team 1) + Conditions + Distance Between(Event Player, prestige_pos) <= 1.5 + Event Player.jumping + Actions + if pvar bosses_killed == 6: + ResetPlayer() + pvar credits += 1 + Set Slow Motion(10) + Big Msg(Everyone, `{} Started Over`(Event Player)) + Wait(1.25s) + Set Slow Motion(100) + Warp(Event Player, player_spawns[0], boss_spawns[0]) + Msg(Event Player, `{} Credits`(pvar credits)) + SuccessSound() + else: + Big Msg(Event Player, `Defeat Final Boss`) + + +Rule "Money Bonus (Ability 2 / E)" + Each(Team 1) + Conditions + Is Using Ability 2(Event Player) + Actions + if pvar money_cd == 0: + pvar money_cd = 45 + pvar gain = (5000 ^ (1 + pvar cur_boss / 15)) * pvar money_multiplier + pvar money += pvar gain + Msg(Event Player, `{} + {} Money!`("", pvar gain)) + else: + Msg(Event Player, `Cooldown: {} sec`(pvar money_cd)) + +Rule "Damage Bonus (Ability 1 / Shift)" + Each(Team 1) + Conditions + Is Using Ability 1(Event Player) + Actions + if pvar damage_cd == 0: + pvar damage_cd = 60 + pvar damage_gain = pvar damage_scale / 2 + Set Damage Dealt(Event Player, pvar damage_scale + pvar damage_gain) + Msg(Event Player, `{}% More Damage ({} sec)`(50, 5)) + Wait(5s) + Set Damage Dealt(Event Player, pvar damage_scale - pvar damage_gain) + else: + Msg(Event Player, `Cooldown: {} sec`(pvar damage_cd)) + +Rule "Money/Damage Cooldowns" + Each(Team 1) + Conditions + (pvar damage_cd > 0) or (pvar money_cd > 0) + Actions + if pvar damage_cd > 0: + pvar damage_cd -= 1 + if pvar money_cd > 0: + pvar money_cd -= 1 + Wait(1s) + Loop If Condition Is True + +Rule "Secret 1" // Flight after jumping by statue + Each(Team 1) + +Rule "Secret 2" // Grandma giving passive income every 5s? + Each(Team 1) + +Disabled Rule "Coordinate Viewer" + Each(Team 1) + Conditions + Has Spawned(Event Player) + Event Player.moving + Event Player.crouching + Is Communicating Any Voice Line(Event Player) + Actions + Create Effect + Visible_To: Event Player + Type: Sphere + Color: White + Pos: Event Player.facing + Event Player.eyepos + Radius: 0.20 + Reevaluation: Visible To Position And Radius + Create Hud Text + Visible_To: Event Player + Header: Null + Subheader: Null + Text: Event Player.facing + Event Player.eyepos + Location: Left + Sort_Order: Null + Header_Color: White + Subheader_Color: White + Text_Color: White + Reevaluation: Visible To And String + +Disabled Rule "Cheats" + Each(Team 1) + Conditions + Event Player.jumping + Actions + pvar money += 1000000 + pvar reload_speed = 0.01 + Set Damage Received(Event Player, 0) + Set Damage Dealt(Event Player, 10000) \ No newline at end of file From 7a517520df72c2664d9835aac31aece1ddca4615 Mon Sep 17 00:00:00 2001 From: adapap <19696846+adapap@users.noreply.github.com> Date: Wed, 21 Aug 2019 19:58:37 -0400 Subject: [PATCH 2/7] Remove unnecessary files --- Examples/aimbot.owpy | 34 -- Examples/arithmetic.owpy | 13 - Examples/arrays.owpy | 13 - Examples/attributes.owpy | 10 - Examples/basic.owpy | 19 - Examples/bezier.owpy | 12 - Examples/booleans.owpy | 6 - Examples/chase.owpy | 9 - Examples/comments.owpy | 11 - Examples/conditionals.owpy | 17 - Examples/conditions.owpy | 9 - Examples/const.owpy | 7 - Examples/contains.owpy | 6 - Examples/error_parameter.owpy | 5 - Examples/for.owpy | 18 - Examples/func_args.owpy | 33 -- Examples/functions.owpy | 13 - Examples/imports.owpy | 5 - Examples/lib/child.owpy | 5 - Examples/lib/lib2/child2.owpy | 2 - Examples/nested.owpy | 10 - Examples/optional_args.owpy | 14 - Examples/strings.owpy | 21 - Examples/time.owpy | 5 - Examples/trigonometry.owpy | 3 - Examples/variables.owpy | 6 - Examples/vectors.owpy | 9 - Examples/while.owpy | 7 - Gamemodes/Clicker.owpy | 755 --------------------------------- README.md | 320 -------------- Syntax/Comments.tmPreferences | 34 -- Syntax/OWScript.sublime-syntax | 176 -------- 32 files changed, 1607 deletions(-) delete mode 100644 Examples/aimbot.owpy delete mode 100644 Examples/arithmetic.owpy delete mode 100644 Examples/arrays.owpy delete mode 100644 Examples/attributes.owpy delete mode 100644 Examples/basic.owpy delete mode 100644 Examples/bezier.owpy delete mode 100644 Examples/booleans.owpy delete mode 100644 Examples/chase.owpy delete mode 100644 Examples/comments.owpy delete mode 100644 Examples/conditionals.owpy delete mode 100644 Examples/conditions.owpy delete mode 100644 Examples/const.owpy delete mode 100644 Examples/contains.owpy delete mode 100644 Examples/error_parameter.owpy delete mode 100644 Examples/for.owpy delete mode 100644 Examples/func_args.owpy delete mode 100644 Examples/functions.owpy delete mode 100644 Examples/imports.owpy delete mode 100644 Examples/lib/child.owpy delete mode 100644 Examples/lib/lib2/child2.owpy delete mode 100644 Examples/nested.owpy delete mode 100644 Examples/optional_args.owpy delete mode 100644 Examples/strings.owpy delete mode 100644 Examples/time.owpy delete mode 100644 Examples/trigonometry.owpy delete mode 100644 Examples/variables.owpy delete mode 100644 Examples/vectors.owpy delete mode 100644 Examples/while.owpy delete mode 100644 Gamemodes/Clicker.owpy delete mode 100644 README.md delete mode 100644 Syntax/Comments.tmPreferences delete mode 100644 Syntax/OWScript.sublime-syntax diff --git a/Examples/aimbot.owpy b/Examples/aimbot.owpy deleted file mode 100644 index 45da1c4..0000000 --- a/Examples/aimbot.owpy +++ /dev/null @@ -1,34 +0,0 @@ -Rule "Start Aimbot" - Event - On Each Player - All - All - Conditions - Is Button Held(Event Player, Primary Fire) - Event Player.hero != Hero(Widowmaker) - Event Player.hero != Hero(Soldier: 76) - Is Alive(Player Closest To Reticle(Event Player, Opposite Team Of(Event Player.team))) - Players In Slot(1, All Teams) - Actions - Start Facing - Event Player - Direction Towards - Event Player - Player Closest To Reticle - Event Player - Opposite Team Of(Event Player.team) + <0, 0.240, 0> - 10000 - To World - Direction and Turn Rate - -Rule "Stop Aimbot" - Event - On Each Player - All - All - Conditions - not Event Player.LMB - Event Player.hero != Hero(Widowmaker) - Players In Slot(1, All Teams) - Actions - Stop Facing(Event Player) \ No newline at end of file diff --git a/Examples/arithmetic.owpy b/Examples/arithmetic.owpy deleted file mode 100644 index 6a84cdb..0000000 --- a/Examples/arithmetic.owpy +++ /dev/null @@ -1,13 +0,0 @@ -Rule "Arithmetic Operations" - Actions - z = Count Of(Allowed Heroes(Event Player)) - y = 1 + 1 - y += 2 - 1 - y *= 3 / 3 - y = 2 ^ 2 - y = (3 + 1) % 4 - pvar num_heroes = 3 - pvar formula = \ No newline at end of file diff --git a/Examples/arrays.owpy b/Examples/arrays.owpy deleted file mode 100644 index 637d7ac..0000000 --- a/Examples/arrays.owpy +++ /dev/null @@ -1,13 +0,0 @@ -Rule "Advanced Arrays" - Event - On Global - Actions - array = [] - array2 = [1, 2, 3] - array[0] = 2 - array[1] = array2[1] + array2[2] - array.append(<1, 2, 3>) - array.append(<6, 6, 6>) - array3 = [1, "Rank B", "Rank A"] - for elem in array3: - Msg(Everyone, elem) \ No newline at end of file diff --git a/Examples/attributes.owpy b/Examples/attributes.owpy deleted file mode 100644 index 2277c4d..0000000 --- a/Examples/attributes.owpy +++ /dev/null @@ -1,10 +0,0 @@ -Rule "Attributes" - Event - On Each Player - All - All - - Conditions - Position Of(Event Player).x < 10 - Event Player.moving - Event Player.jumping \ No newline at end of file diff --git a/Examples/basic.owpy b/Examples/basic.owpy deleted file mode 100644 index 9ef1085..0000000 --- a/Examples/basic.owpy +++ /dev/null @@ -1,19 +0,0 @@ -Rule "My First Rule" - Event - On Global - All - All - - Conditions - All True - Array: All Players - Team: Team 2 - Condition: Has Spawned - Element: Current Array Element - == True - - Actions - pvar h@Event Player = 0 - h = 1 - b = h - c = pvar h \ No newline at end of file diff --git a/Examples/bezier.owpy b/Examples/bezier.owpy deleted file mode 100644 index ae0365f..0000000 --- a/Examples/bezier.owpy +++ /dev/null @@ -1,12 +0,0 @@ -Rule "Bezier Curve" - Event - On Global - Actions - a = 0 - b = 1 - c = floor(b) * 3 - Chase Global Variable At Rate - Variable: a - Destination: a[c] * ((1 - b % 1)^3) + (((a[1 + c] * 3) * 3) * b % 1) * ((1 - b % 1)^2) + ((a[2 + c * 3] * 3) * (b % 1)^2 * (1 - b % 1) + a[3 + c * 3]) * (b % 1) * 3 - Rate: 0.2 - Reevaluation: Destination And Rate \ No newline at end of file diff --git a/Examples/booleans.owpy b/Examples/booleans.owpy deleted file mode 100644 index f617052..0000000 --- a/Examples/booleans.owpy +++ /dev/null @@ -1,6 +0,0 @@ -Rule "Boolean Operators" - Event - On Global - - Actions - n = 1 and 2 or 3 and not 4 \ No newline at end of file diff --git a/Examples/chase.owpy b/Examples/chase.owpy deleted file mode 100644 index 888d4ce..0000000 --- a/Examples/chase.owpy +++ /dev/null @@ -1,9 +0,0 @@ -Rule "Chase Test" - Actions - pvar chase_var = 100 - Chase Global Variable At Rate - Variable: chase_var - Destination: 0 - Rate: -1 - Reevaluation: Destination And Rate - Set Move Speed(Event Player, chase_var) \ No newline at end of file diff --git a/Examples/comments.owpy b/Examples/comments.owpy deleted file mode 100644 index edf6821..0000000 --- a/Examples/comments.owpy +++ /dev/null @@ -1,11 +0,0 @@ -Rule "Ton commentaire n'est pas necessaire" - Event - On Global - Actions - /* We should ignore - all dis text */ - // x = 1 - Msg(Event Player, /* even inline comments - should work */ "Hello") - var = 1 // Yes, it is indeed - /* Comments are the best! */ \ No newline at end of file diff --git a/Examples/conditionals.owpy b/Examples/conditionals.owpy deleted file mode 100644 index 1857c0c..0000000 --- a/Examples/conditionals.owpy +++ /dev/null @@ -1,17 +0,0 @@ -Rule "If and Else" - Event - On Global - Actions - z = 1 - h = 2 - if z == 1: - z = 3 - y = 4 - elif h > 1: - h = 2 - y = 3 - y = 4 - elif h < 1: - z = 1 - else: - z = 'yes' \ No newline at end of file diff --git a/Examples/conditions.owpy b/Examples/conditions.owpy deleted file mode 100644 index 1595060..0000000 --- a/Examples/conditions.owpy +++ /dev/null @@ -1,9 +0,0 @@ -Rule "Multiple Conditions" - Event - On Global - Conditions - Distance Between - Event Player - <10, 20, 30> - <= 1.5 - 123 < 456 \ No newline at end of file diff --git a/Examples/const.owpy b/Examples/const.owpy deleted file mode 100644 index 27f2330..0000000 --- a/Examples/const.owpy +++ /dev/null @@ -1,7 +0,0 @@ -Rule "Constants for cleaner code!" - Event - On Each Player - Actions - const speed = 100 - Set Move Speed(Event Player, speed) - // speed = 150 // const is immutable, so this causes an error \ No newline at end of file diff --git a/Examples/contains.owpy b/Examples/contains.owpy deleted file mode 100644 index 414e9bf..0000000 --- a/Examples/contains.owpy +++ /dev/null @@ -1,6 +0,0 @@ -Rule "x in array?" - Event - On Global - Actions - a = Event Player in Everyone - b = 1 not in [1, 2, 3] \ No newline at end of file diff --git a/Examples/error_parameter.owpy b/Examples/error_parameter.owpy deleted file mode 100644 index 3dd4c7c..0000000 --- a/Examples/error_parameter.owpy +++ /dev/null @@ -1,5 +0,0 @@ -Rule "Wrong Parameter!" - Event - On Global - Actions - Set Facing(Event Player, Event Player.eyepos, "No") \ No newline at end of file diff --git a/Examples/for.owpy b/Examples/for.owpy deleted file mode 100644 index f6a69cd..0000000 --- a/Examples/for.owpy +++ /dev/null @@ -1,18 +0,0 @@ -Rule "For Loop" - Event - On Global - Actions - angles = [15, 30, 45, 60, 75, 90] - angles2 = range(15, 91, 15) - for ang in angles: - Set Facing - Event Player - Direction From Angles - horizontal: ang - vertical: 45 - To World - Msg(Everyone, "HEllo") - for i in range(3): - Msg(Everyone, i) - for player in Everyone: - Msg(player, "Hello") \ No newline at end of file diff --git a/Examples/func_args.owpy b/Examples/func_args.owpy deleted file mode 100644 index 10145af..0000000 --- a/Examples/func_args.owpy +++ /dev/null @@ -1,33 +0,0 @@ -// Functions can be used as rule factories -%create_portal(origin, destination, radius) - Rule "Create Portal" - Event - On Each Player - All - All - Actions - Create Effect - Visible: Event Player - Type: Good Aura - Color: Yellow - Position: origin - Radius: radius - Reeval: Visible To, Position, and Radius - Rule "Teleportation" - Event - On Each Player - All - All - Conditions - Event Player in Players In Radius - Center: origin - Radius: radius - Team: All - LOS: Surfaces - == True - Actions - Teleport - Event Player - destination - -create_portal(<0, 1, 2>, <3, 4, 5>, 10) \ No newline at end of file diff --git a/Examples/functions.owpy b/Examples/functions.owpy deleted file mode 100644 index 52edf00..0000000 --- a/Examples/functions.owpy +++ /dev/null @@ -1,13 +0,0 @@ -%event_func - Event - On Each Player - All - All -%add_rule(a, b, name_) - Rule "test" - event_func() - Actions - c = a + b -Rule "Function Demo" - event_func() -add_rule(1, 5, "Add Two") \ No newline at end of file diff --git a/Examples/imports.owpy b/Examples/imports.owpy deleted file mode 100644 index 5e25feb..0000000 --- a/Examples/imports.owpy +++ /dev/null @@ -1,5 +0,0 @@ -#import "lib/child" - -Rule "Debug Import" - Actions - debug_func("Hello!") \ No newline at end of file diff --git a/Examples/lib/child.owpy b/Examples/lib/child.owpy deleted file mode 100644 index 3f951a2..0000000 --- a/Examples/lib/child.owpy +++ /dev/null @@ -1,5 +0,0 @@ -#import 'lib2/child2.owpy' - -%debug_func(text) - Msg(Everyone, text) - nested(Lucio) \ No newline at end of file diff --git a/Examples/lib/lib2/child2.owpy b/Examples/lib/lib2/child2.owpy deleted file mode 100644 index 289b16a..0000000 --- a/Examples/lib/lib2/child2.owpy +++ /dev/null @@ -1,2 +0,0 @@ -%nested(hero_) - Set Hero(Event Player, hero_) \ No newline at end of file diff --git a/Examples/nested.owpy b/Examples/nested.owpy deleted file mode 100644 index ae6ad80..0000000 --- a/Examples/nested.owpy +++ /dev/null @@ -1,10 +0,0 @@ -Rule "Nested Blocks" - Event - On Global - Actions - if a == 1: - b = 2 - for i in range(4): - Msg(Everyone, i) - elif a == 2: - b = 3 \ No newline at end of file diff --git a/Examples/optional_args.owpy b/Examples/optional_args.owpy deleted file mode 100644 index 4158b0f..0000000 --- a/Examples/optional_args.owpy +++ /dev/null @@ -1,14 +0,0 @@ -%CreateEffect(pos, type?=Ring, color?=White) - Create Effect - Visible_To: Everyone - Type: type - Color: color - Position: pos - Radius: 1.5 - Reevaluation: Visible To - -Rule "Optional/Default Arguments" - Event - On Global - Actions - CreateEffect(<0,0,0>) \ No newline at end of file diff --git a/Examples/strings.owpy b/Examples/strings.owpy deleted file mode 100644 index 3077ff3..0000000 --- a/Examples/strings.owpy +++ /dev/null @@ -1,21 +0,0 @@ -Rule "String Builder" - Event - On Each Player - All - All - Actions - pvar money = 100 - test = "Hello" - Msg - Everyone - `Money: {}!` - pvar money - `#use ultimate ability, up` - `{}`(pvar money) - -/*%RuleFactory(name_) - Rule "My Custom " name_ - Event - On Global*/ - -//RuleFactory("Portal") \ No newline at end of file diff --git a/Examples/time.owpy b/Examples/time.owpy deleted file mode 100644 index cbdc554..0000000 --- a/Examples/time.owpy +++ /dev/null @@ -1,5 +0,0 @@ -Rule "Time Shorthands" - Actions - Wait(16ms) - Wait /* It takes a parameter, so indent if you please! */ - 0.35min \ No newline at end of file diff --git a/Examples/trigonometry.owpy b/Examples/trigonometry.owpy deleted file mode 100644 index dde8c85..0000000 --- a/Examples/trigonometry.owpy +++ /dev/null @@ -1,3 +0,0 @@ -Rule "Trigonometry In Vectors" - Actions - pvar vec1 = \ No newline at end of file diff --git a/Examples/variables.owpy b/Examples/variables.owpy deleted file mode 100644 index 36002dd..0000000 --- a/Examples/variables.owpy +++ /dev/null @@ -1,6 +0,0 @@ -Rule "Variables" - Event - On Global - - Actions - pvar h@Event Player = 1 \ No newline at end of file diff --git a/Examples/vectors.owpy b/Examples/vectors.owpy deleted file mode 100644 index b2f0779..0000000 --- a/Examples/vectors.owpy +++ /dev/null @@ -1,9 +0,0 @@ -Rule "Variables & Vectors" - Actions - first_Vector = Vector(1, 2, 3) - gvar vec2 = Vector - X: 1 - 2 - this_is_a_comment_lol_gottem: 3 - pVar CoolV3ctor = <1, 2, 3> - // Vectors can span multiple lines \ No newline at end of file diff --git a/Examples/while.owpy b/Examples/while.owpy deleted file mode 100644 index 1f7b49d..0000000 --- a/Examples/while.owpy +++ /dev/null @@ -1,7 +0,0 @@ -Rule "While Loop" - Event - On Global - Actions - n = 0 - while n < 5: - n += 1 \ No newline at end of file diff --git a/Gamemodes/Clicker.owpy b/Gamemodes/Clicker.owpy deleted file mode 100644 index 5999ffa..0000000 --- a/Gamemodes/Clicker.owpy +++ /dev/null @@ -1,755 +0,0 @@ -%Global - Event - On Global -%Each(team_) - Event - On Each Player - team_ - All -%GameText(who, text, pos, scale) - World Text - Visible_To: who - Header: text - Position: pos - Scale: scale - Clipping: Clip Against Surfaces - Reevaluation: Visible To And String -%CodeText(who, code, pos, scale) - GameText(who, `Save: {} + {} + {} + {} + {}`(code[0], code[1], code[2], code[3], code[4]), pos, scale) -%BigHud(loc, text, color) - Hud - Visible_To: Event Player - Header: text - Subheader: Null - Text: Null - Location: loc - Sort_Order: 0 - Header_Color: color - Subheader_Color: White - Text_Color: White - Reevaluation: Visible To And String -%SmallHud(loc, text, color) - Hud - Visible_To: Event Player - Header: Null - Subheader: Null - Text: text - Location: loc - Sort_Order: 999 - Header_Color: White - Subheader_Color: White - Text_Color: color - Reevaluation: Visible To And String -%Sound(type) - Play Effect - Visible_To: Event Player - Type: type - Color: White - Position: Event Player - Radius: 50 -%SuccessSound - Sound(Buff Explosion Sound) -%FailSound - Sound(Debuff Impact Sound) -%WooshSound - Sound(Ring Explosion Sound) -%BoomSound - Sound(Explosion Sound) -%MissingFunds - Big Msg(Event Player, `Go Find More Money`) -%Warp(player, destination, facing) - Teleport(player, destination) - Set Facing - Player: Event Player - Direction: Vector Towards - Start: Event Player - End: facing - Relative: To World - Wait(0.1s) - Event Player.halt() -%Portal(pos, type, color, text) - Create Effect - Visible_To: Everyone - Type: type - Color: color - Position: pos - Radius: 1.5 - Reevaluation: Visible To - GameText(Everyone, text, (pos + Up), 1.5) -%UpgradePortal(pos) - Portal(pos, Good Aura, Yellow, "Upgrades") -%ShopPortal(pos) - Portal(pos, Good Aura, Purple, `Current Boss`) -%NextBossPortal(pos, text) - Portal(pos, Good Aura, Blue, text) -%UpgradeEffect(pos, color) - Create Effect - Visible_To: Everyone - Type: Orb - Color: color - Position: pos - Radius: 1.5 - Reevaluation: Visible To -%UpgradeText(upg, cost_var) - GameText(Event Player, `{}: {}`(upgrade_names[upg], cost_var), upgrade_positions[upg] + Up * 0.5, 1.5) -%SaveIcon(pos, icon, color) - Create Icon - Visible_To: Filter - Everyone - LOS - pos - Cur Elem - Barriers Do Not Block LOS - Position: pos - Icon: icon - Reevaluation: Visible To - Icon_Color: White - Show_When_Offscreen: False - Create Effect - Visible_To: Everyone - Type: Ring - Color: color - Position: pos - Radius: 1 - Reevaluation: Visible To Position And Radius -%SpawnBoss(boss) - Teleport - boss_player - boss_spawns[Index(boss_heroes, boss)] -%ResetPlayer - pvar location = 0 - pvar cur_boss = 0 - pvar bosses_killed = 0 - pvar money = 0 - pvar damage_scale = 1 - pvar damage_scale_cost = 5 - pvar reload_speed = 2.0 - pvar reload_speed_cost = 15 - pvar money_multiplier = 1 - pvar money_multiplier_cost = 10 - pvar hp = 10 - pvar hp_cost = 100 - pvar defense = 100 - pvar defense_cost = 25 - pvar ability1 = False - pvar ability2 = False - pvar money_cd = 0 - pvar damage_cd = 0 - Set Damage Dealt(Event Player, pvar damage_scale) - Set Damage Received(Event Player, pvar defense) - Set Max Health(Event Player, pvar hp) - Set Primary Fire Enabled(Event Player, True) - Set Ability 1 Enabled(Event Player, False) - Set Ability 2 Enabled(Event Player, False) - -Rule "Initialize Constants" - Global() - Actions - /* Define Player Variables */ - pvar location = 0 - pvar cur_boss = 0 - pvar bosses_killed = 0 - pvar money = 0 - pvar damage_scale = 1 - pvar damage_scale_cost = 5 - pvar reload_speed = 2.0 - pvar reload_speed_cost = 15 - pvar money_multiplier = 1 - pvar money_multiplier_cost = 10 - pvar hp = 10 - pvar hp_cost = 100 - pvar defense = 100 - pvar defense_cost = 25 - pvar ability1 = False - pvar ability2 = False - pvar money_cd = 0 - pvar damage_cd = 0 - /* Global Variables */ - shop_pos = <2.500, 3.500, 75> - player_spawns = [<-40, -1.5, 145.5>, <-29, 8, 56>, <-77.5, 1.5, 65.5>, <-50.5, 1.5, 117>, <43.5, 3.5, 73.5>, <-115, 1.5, 112.5>] - boss_spawns = [<-31.5, 0, 148>, <-22.5, 7.5, 66.5>, <-82.5, 1.5, 61>, <-59, 1, 104>, <53.5, 3.5, 72.5>, <-129, 2.5, 108.5>] - boss_heroes = [Hero(Roadhog), Hero(Soldier: 76), Hero(Mei), Hero(Lucio), Hero(Ana), Hero(Reaper)] - ability2_pos = <12.5, 2.5, 71> - ability1_pos = <12.5, 2.5, 71 + 2.5> - ability1_cost = 25000 - ability2_cost = 10000 - Set Match Time(90min) - -Rule "Initialize Player Stats" - Each(Team 1) - Actions - /* Player Variables */ - ResetPlayer() - pvar credits = 0 - pvar save_code = [] - -Rule "Initialize Effects (Portals / Upgrades / Saves / Boundaries)" - Global() - Actions - portals = [<-50, 1, 137.350>, <-37, 6.5, 48>, <-71, 1.5, 62.5>, <-58, 2, 122>, <41, 3.5, 78.5>, <-118.5, 1.5, 99.5>] - next_boss_portals = [<-55, 1.5, 141.5>, <-25.5, 7.5, 50.5>, <-80, 1.5, 71>, <-63, 2.5, 115.5>, <41, 3.5, 67.5>] - next_boss_cost = [1000, 12.5 * 1000, 75 * 1000, 350 * 1000, 1500 * 1000] - shop_portal = <-7, 3, 75> - upgr_pos = <3, 2.5, 70> - save_pos = <3.5, 6.5, 86> - prestige_pos = <-172, 3, 96> - soldier_temp_pos = <3, 3, 77.5> - x_offset = <2.5, 0, 0> - z_offset = <0, 0, 2.5> - upgrade_names = ["Heal", "Damage", "Faster", "Money", "Defend"] - upgrade_rates = [100, 1.003, 1.04, 1.045, 1.03] - upgrade_positions = [] - for i in range(-2, 3): - upgrade_positions.append(upgr_pos + i * x_offset) - upgrade_colors = [Purple, Red, Yellow, Green, Blue] - // Bosses 1-6 -> Shop - for portal in portals: - UpgradePortal(portal) - ShopPortal(shop_portal) - // HP, Damage, Reload Speed, Money Multiplier, Damage Resistance - for i in range(5): - UpgradeEffect(upgrade_positions[i], upgrade_colors[i]) - // Next Boss - for i in range(5): - NextBossPortal(next_boss_portals[i], `Next Boss: {}`(next_boss_cost[i])) - Portal(prestige_pos, Bad Aura, Red, `Start Over`) - // Saves - SaveIcon(save_pos - z_offset, Arrow: Up, Green) - SaveIcon(save_pos + z_offset, Arrow: Down, Red) - SaveIcon(save_pos - x_offset, Arrow: Left, Blue) - SaveIcon(save_pos + x_offset, Arrow: Right, Yellow) - // Abilities - UpgradeEffect(ability1_pos, White) - UpgradeEffect(ability2_pos, White) - UpgradeEffect(soldier_temp_pos, Blue) - GameText(All Players(Team 1), `Buy Ability 1: {}`(ability1_cost), ability1_pos + Up * 0.5, 1.5) - GameText(All Players(Team 1), `Buy Ability 2: {}`(ability2_cost), ability1_pos + Up * 0.5, 1.5) - GameText(All Players(Team 1), `Unlock {}: {} Credit`(Hero(Soldier: 76), 1), soldier_temp_pos + Up * 0.5, 1.5) - // Secrets - secret2_pos = <31, 2.5, 49.5> - CodeText(Players In Radius(secret2_pos, 5, Team(All), Off), ["Left", "Up", "Down", "Up", "Right"], secret2_pos, 0.75) - -Rule "Initialize Player HUD Stats" - Each(Team 1) - Actions - BigHud(Top, `Money: {}`(pvar money), White) - SmallHud(Top, `{} Credits ({} / {} Boss Kills)`(pvar credits, pvar bosses_killed, 6), Purple) - SmallHud(Top, `{}% Money`(pvar money_multiplier * 100), Green) - SmallHud(Top, `{} Sec`(pvar reload_speed), Yellow) - SmallHud(Top, `Damage: {}% / Defend: {}%`(pvar damage_scale, pvar defense), Red) - // Player Stats Over Head - World Text - Visible_To: All Players(Team 1) - Header: `Damage: {}% - {} sec - {}% Money` - pvar damage_scale - pvar reload_speed - pvar money_multiplier * 100 - Position: Event Player - Scale: 0.750 - Clipping: Clip Against Surfaces - Reevaluation: Visible To Position And String - -Rule "Validate Bosses" - Global() - Conditions - not All True - boss_heroes - Is Hero Being Played - Cur Elem - Team 2 - Actions - Msg - Everyone - `Warning: Bad Bosses` - for boss in boss_heroes: - if not Is Hero Being Played(boss, Team 2): - Msg - Everyone - `No {}`(boss) - Wait(20s) - Loop If Condition Is True - -%BossMovement(hero_, speed) - Set Move Speed(Players On Hero(hero_, Team 2), speed) - Clear Status(Players On Hero(hero_, Team 2), Rooted) -Rule "Initialize Bosses" - Global() - Conditions - All True - boss_heroes - Has Spawned - Players On Hero - Cur Elem - Team 2 - Actions - for boss in boss_heroes: - boss_player = Players On Hero(boss, Team 2) - SpawnBoss(boss) - Set Move Speed(boss_player, 0) - Set Status(boss_player, Null, Rooted, 9999) - GameText(Everyone, `Heal: {}`(Health(Players On Hero(boss, Team 2))), Players On Hero(boss, Team 2), 1) - BossMovement(Hero(Mei), 10) - BossMovement(Hero(Lucio), 100) - BossMovement(Hero(Reaper), 100) - -Rule "Respawn Bosses" - Event - Player Died - Team 2 - All - Actions - Respawn(Event Player) - Wait(0.1s) - Teleport(Event Player, boss_spawns[Index(boss_heroes, Event Player.hero)]) - -Rule "Initialize Upgrade Text" - Each(Team 1) - Actions - UpgradeText(0, pvar hp_cost) - UpgradeText(1, pvar damage_scale_cost) - UpgradeText(2, pvar reload_speed_cost) - UpgradeText(3, pvar money_multiplier_cost) - UpgradeText(4, pvar defense_cost) - -Rule "Teleport to Shop" - Each(Team 1) - Conditions - Any True - Array: portals - Condition: Distance Between - Event Player - Cur Elem - <= 2.0 - Actions - Warp(Event Player, shop_pos, upgr_pos) - WooshSound() - pvar location = -1 - -Rule "Teleport from Shop" - Each(Team 1) - Conditions - Distance Between - Event Player - shop_portal - <= 2.0 - pvar location == -1 - Actions - pvar location = pvar cur_boss - Wait(0.1s) - Warp(Event Player, player_spawns[pvar location], Closest Player To(Event Player, Team 2)) - WooshSound() - -Rule "Shop Boundary & Heal" - Each(Team 1) - Conditions - pvar location == -1 - Actions - while pvar location == -1: - Heal(Event Player, Null, 10000) - Wait(0.1s) - Skip If(Not((Event Player.pos.x <= -12) or (Event Player.pos.z <= 25)), 6) - Warp(Event Player, shop_pos, upgr_pos) - Msg(Event Player, `Avoid Going Here`) - FailSound() - -%BossBoundary(loc, hero_) - if Event Player in All Players(Team 1): - if pvar location == loc: - Teleport(Event Player, player_spawns[pvar cur_boss]) - Msg(Event Player, `Avoid Going Here`) - FailSound() - elif Event Player.hero == hero_: - Teleport(Event Player, boss_spawns[Index(boss_heroes, hero_)]) - -Rule "Boss Boundaries (Soldier: 76)" - Each(All) - Conditions - Event Player.pos.y < 4.5 - Actions - BossBoundary(1, Hero(Soldier: 76)) - Wait(2s) - Loop If Condition Is True -Rule "Boss Boundaries (Mei)" - Each(All) - Conditions - Event Player.pos.x > -72 - Actions - BossBoundary(2, Hero(Mei)) - Wait(2s) - Loop If Condition Is True -Rule "Boss Boundaries (Lucio)" - Each(All) - Conditions - not Event Player in Players In Radius(boss_spawns[3], 20, Team(All), Off) - Actions - BossBoundary(3, Hero(Lucio)) - Wait(2s) - Loop If Condition Is True -Rule "Boss Boundaries (Reaper)" - Each(All) - Conditions - Event Player.pos.x > -94 - Actions - BossBoundary(5, Hero(Reaper)) - Wait(2s) - Loop If Condition Is True - -%ShopCondition(pos) - Conditions - Event Player in Players In Radius(pos, 1.5, Team(All), Surfaces) - Event Player.interacting -%ShopAutobuy - Skip If(Not(Event Player.crouching), 2) - Wait(0.1s) - Loop If Condition Is True -Rule "Buy HP" - Each(Team 1) - ShopCondition(upgrade_positions[0]) - Actions - if pvar money >= pvar hp_cost: - pvar money -= pvar hp_cost - pvar hp_cost = ceil(pvar hp_cost + upgrade_rates[0]) - pvar hp += 10 - Set Max Health(Event Player, pvar hp) - SuccessSound() - ShopAutobuy() - else: - MissingFunds() - FailSound() - -Rule "Buy Damage %" - Each(Team 1) - ShopCondition(upgrade_positions[1]) - Actions - if pvar money >= pvar damage_scale_cost: - pvar money -= pvar damage_scale_cost - Skip If(pvar damage_scale >= 75, 1) - pvar damage_scale += 3 - Skip If(pvar damage_scale < 75, 1) - pvar damage_scale += 2 - Set Damage Dealt(Event Player, pvar damage_scale) - pvar damage_scale_cost = ceil(pvar damage_scale_cost ^ upgrade_rates[1]) - SuccessSound() - ShopAutobuy() - else: - MissingFunds() - FailSound() - -Rule "Buy Reload Speed" - Each(Team 1) - ShopCondition(upgrade_positions[2]) - Actions - if pvar money >= pvar reload_speed_cost: - pvar money -= pvar reload_speed_cost - pvar reload_speed_cost = ceil(pvar reload_speed_cost ^ upgrade_rates[2]) - pvar reload_speed = max(pvar reload_speed * 0.95, 0) - SuccessSound() - ShopAutobuy() - else: - MissingFunds() - FailSound() - -Rule "Buy Money Multiplier" - Each(Team 1) - ShopCondition(upgrade_positions[3]) - Actions - if pvar money >= pvar money_multiplier_cost: - pvar money -= pvar money_multiplier_cost - pvar money_multiplier_cost = ceil(pvar money_multiplier_cost ^ upgrade_rates[3]) - pvar money_multiplier += 0.075 - SuccessSound() - ShopAutobuy() - else: - MissingFunds() - FailSound() - -Rule "Buy Defense" - Each(Team 1) - ShopCondition(upgrade_positions[4]) - Actions - if (pvar money >= pvar defense_cost) and (pvar defense > 5): - pvar money -= pvar defense_cost - pvar defense_cost = ceil(pvar defense_cost ^ upgrade_rates[4]) - pvar defense = Max(pvar defense - 2, 5) - Set Damage Received(Event Player, pvar defense) - SuccessSound() - ShopAutobuy() - elif pvar defense == 5: - Msg(Event Player, `Max Defend`) - FailSound() - else: - MissingFunds() - FailSound() - -Rule "Buy Ability 1" - Each(Team 1) - ShopCondition(ability1_pos) - Actions - if (pvar money >= ability1_cost) and (not pvar ability1): - pvar money -= ability1_cost - pvar ability1 = True - Set Ability 1 Enabled(Event Player, True) - SuccessSound() - elif pvar ability1: - Msg(Event Player, `You Bought Ability 1`) - FailSound() - else: - MissingFunds() - -Rule "Buy Ability 2" - Each(Team 1) - ShopCondition(ability2_pos) - Actions - if (pvar money >= ability2_cost) and (not pvar ability2): - pvar money -= ability2_cost - pvar ability2 = True - Set Ability 2 Enabled(Event Player, True) - SuccessSound() - elif pvar ability2: - Msg(Event Player, `You Bought Ability 2`) - FailSound() - else: - MissingFunds() - -Rule "Teleport Player to Start" - Each(Team 1) - Conditions - Has Spawned(Event Player) - Actions - Teleport - Event Player - player_spawns[pvar cur_boss] - -Rule "Shooting Control" - Each(Team 1) - Conditions - Has Spawned(Event Player) - Is Firing Primary(Event Player) - Actions - Set Primary Fire Enabled(Event Player, False) - Wait(pvar reload_speed) - Set Primary Fire Enabled(Event Player, True) - -Rule "Attack Money" - Event - Player Dealt Damage - Team 1 - All - Actions - pvar money += ceil((Event Damage ^ (1 + pvar cur_boss / 3.5)) * pvar money_multiplier) - -Rule "Boss Kill" - Event - Player Dealt Final Blow - Team 1 - All - Actions - pvar money += (100 ^ (1 + pvar cur_boss / 2)) * pvar money_multiplier - pvar bosses_killed = Max(Index(boss_heroes, Victim.hero) + 1, pvar bosses_killed) - if pvar bosses_killed == 6: - Msg(Event Player, `Find Start Over`) - -Rule "Player Death" - Event - Player Died - Team 1 - All - Actions - Wait(0.1s) - pvar location = -1 - Warp(Event Player, shop_pos, upgr_pos) - -Rule "Next Boss" - Each(Team 1) - Conditions - Event Player in Players In Radius(next_boss_portals[pvar cur_boss], 2, Team(All), Off) - Actions - if (pvar money >= next_boss_cost[pvar cur_boss]) and (pvar bosses_killed > pvar cur_boss): - pvar money -= next_boss_cost[pvar cur_boss] - pvar cur_boss += 1 - Wait(0.1s) - Warp(Event Player, player_spawns[pvar cur_boss], boss_spawns[pvar cur_boss]) - pvar location = pvar cur_boss - WooshSound() - elif pvar money < next_boss_cost[pvar cur_boss]: - MissingFunds() - FailSound() - else: - Big Msg(Event Player, `Go Kill Boss`) - FailSound() - -%SaveInput(name, value, pos) - Rule "Save Input " + name - Each(Team 1) - Conditions - Distance Between(Event Player, pos) <= 1.25 - Event Player.interacting - Actions - Msg(Event Player, name) - pvar save_code.append(value) - BoomSound() - -SaveInput("Up", 0, save_pos - z_offset) -SaveInput("Down", 1, save_pos + z_offset) -SaveInput("Left", 2, save_pos - x_offset) -SaveInput("Right", 3, save_pos + x_offset) - -%UnlockHero(hero_) - pvar save_code_effect = Last Text Id - Destroy In-World Text(pvar save_code_effect) - Set Hero(Event Player, hero_) - Wait(0.5s) - Big Msg(Event Player, `You Unlocked {}`(Hero Icon String(hero_))) - SuccessSound() - Wait(0.25) - -Rule "Buy Prestige Item" - Each(Team 1) - ShopCondition(soldier_temp_pos) - Actions - if pvar credits >= 1: - pvar credits -= 1 - UnlockHero(Hero(Soldier: 76)) - else: - Big Msg(Event Player, `Defeat Final Boss`) - -Rule "Check Save Code" - Each(Team 1) - Conditions - Count Of(pvar save_code) == 5 - Actions - // 0: Up - // 1: Down - // 2: Left - // 3: Right - if pvar save_code == [0, 0, 0, 0, 0]: - UnlockHero(Hero(McCree)) - CodeText(Event Player, ["Up", "Up", "Up", "Up", "Up"], save_pos + Up * 1.25, 2) - elif pvar save_code == [3, 1, 2, 3, 2]: - UnlockHero(Hero(Soldier: 76)) - CodeText(Event Player, ["Right", "Down", "Left", "Right", "Left"], save_pos + Up * 1.25, 2) - elif pvar save_code == [0, 2, 2, 1, 3]: - UnlockHero(Hero(Ashe)) - CodeText(Event Player, ["Up", "Left", "Left", "Down", "Right"], save_pos + Up * 1.25, 2) - elif pvar save_code == [2, 3, 2, 0, 0]: - UnlockHero(Hero(Genji)) - CodeText(Event Player, ["Left", "Right", "Left", "Up", "Up"], save_pos + Up * 1.25, 2) - elif pvar save_code == [1, 1, 3, 1, 2]: - UnlockHero(Hero(Hanzo)) - CodeText(Event Player, ["Down", "Down", "Right", "Down", "Left"], save_pos + Up * 1.25, 2) - elif pvar save_code == [2, 0, 1, 0, 3]: // Secrets - Big Msg(Event Player, "Hacked") - // You Unlocked Hidden Save 2 - else: - Big Msg(Event Player, `Unknown Save`) - pvar save_code = [] - -Rule "Prestige Confirm" - Each(Team 1) - Conditions - Distance Between(Event Player, prestige_pos) <= 1.5 - Actions - Msg(Event Player, `Start Over? (Jump)`) - -Rule "Prestige" - Each(Team 1) - Conditions - Distance Between(Event Player, prestige_pos) <= 1.5 - Event Player.jumping - Actions - if pvar bosses_killed == 6: - ResetPlayer() - pvar credits += 1 - Set Slow Motion(10) - Big Msg(Everyone, `{} Started Over`(Event Player)) - Wait(1.25s) - Set Slow Motion(100) - Warp(Event Player, player_spawns[0], boss_spawns[0]) - Msg(Event Player, `{} Credits`(pvar credits)) - SuccessSound() - else: - Big Msg(Event Player, `Defeat Final Boss`) - - -Rule "Money Bonus (Ability 2 / E)" - Each(Team 1) - Conditions - Is Using Ability 2(Event Player) - Actions - if pvar money_cd == 0: - pvar money_cd = 45 - pvar gain = (5000 ^ (1 + pvar cur_boss / 15)) * pvar money_multiplier - pvar money += pvar gain - Msg(Event Player, `{} + {} Money!`("", pvar gain)) - else: - Msg(Event Player, `Cooldown: {} sec`(pvar money_cd)) - -Rule "Damage Bonus (Ability 1 / Shift)" - Each(Team 1) - Conditions - Is Using Ability 1(Event Player) - Actions - if pvar damage_cd == 0: - pvar damage_cd = 60 - pvar damage_gain = pvar damage_scale / 2 - Set Damage Dealt(Event Player, pvar damage_scale + pvar damage_gain) - Msg(Event Player, `{}% More Damage ({} sec)`(50, 5)) - Wait(5s) - Set Damage Dealt(Event Player, pvar damage_scale - pvar damage_gain) - else: - Msg(Event Player, `Cooldown: {} sec`(pvar damage_cd)) - -Rule "Money/Damage Cooldowns" - Each(Team 1) - Conditions - (pvar damage_cd > 0) or (pvar money_cd > 0) - Actions - if pvar damage_cd > 0: - pvar damage_cd -= 1 - if pvar money_cd > 0: - pvar money_cd -= 1 - Wait(1s) - Loop If Condition Is True - -Rule "Secret 1" // Flight after jumping by statue - Each(Team 1) - -Rule "Secret 2" // Grandma giving passive income every 5s? - Each(Team 1) - -Disabled Rule "Coordinate Viewer" - Each(Team 1) - Conditions - Has Spawned(Event Player) - Event Player.moving - Event Player.crouching - Is Communicating Any Voice Line(Event Player) - Actions - Create Effect - Visible_To: Event Player - Type: Sphere - Color: White - Pos: Event Player.facing + Event Player.eyepos - Radius: 0.20 - Reevaluation: Visible To Position And Radius - Create Hud Text - Visible_To: Event Player - Header: Null - Subheader: Null - Text: Event Player.facing + Event Player.eyepos - Location: Left - Sort_Order: Null - Header_Color: White - Subheader_Color: White - Text_Color: White - Reevaluation: Visible To And String - -Disabled Rule "Cheats" - Each(Team 1) - Conditions - Event Player.jumping - Actions - pvar money += 1000000 - pvar reload_speed = 0.01 - Set Damage Received(Event Player, 0) - Set Damage Dealt(Event Player, 10000) \ No newline at end of file diff --git a/README.md b/README.md deleted file mode 100644 index f02e7d6..0000000 --- a/README.md +++ /dev/null @@ -1,320 +0,0 @@ -# OWScript -Python-like scripting language which transpiles into Overwatch Workshop script rulesets. - -Setup -===== -## Installation & Usage -1. Install Python with `pip` if you have not done so already. -2. Run the command `python OWScript.py` with the following arguments: -- `input` Path to input file, blank for stdin -- `-m | --min` Optional: minifies the output by stripping whitespace -- `-s | --save [FILE]` Optional: saves to the target output file instead of stdout -- `-c | --copy` Optional: copies code to clipboard (must have *pyperclip* installed: `pip install pyperclip`) - -**NPM Integration** by @MatthewSH -[OWScript NPM Package](https://www.npmjs.com/package/owscript) - -## Syntax Highlighting - -**Visual Studio Code** -Download the latest [OWScript extension](https://marketplace.visualstudio.com/items?itemName=adapap.owscript) from the marketplace. - -**Sublime Text 3** -In the `Syntax/` folder, you can find the raw Iro code which I used to generate a Sublime Text file with modifications. You can directly import the `OWScript.sublime-syntax` file by putting it in your ST3 `User` folder. - -Projects -======== -- **Cookie Clicker** [![Discord Shield](https://discordapp.com/api/guilds/572937743114436619/widget.png?style=shield "Made by @adapap")](https://discord.gg/5Nst8g5) -- [**Upgrade Shop**](https://github.com/overwatchworkshop/upgrade-shop) - -Documentation -============= -*See example code in the `Examples/` folder.* - -**Input** `*.owpy` - -**Output** `*.ows` (standard as agreed upon voting results) - -**Semantic** -* [Values / Actions](#values--actions) -* [Annotations / Comments](#annotations--comments) -* [Assignment / Arithmetic](#assignment--arithmetic) -* [Logic](#logic) -* [Functions](#functions) -* [Loops](#loops) -* [Attributes / Methods](#attributes--methods) -* [Imports](#imports) - -**Data Types & Structures** -* [Variables](#variables) -* [Strings](#strings) -* [Vectors](#vectors) -* [Time](#time) -* [Arrays](#arrays) -* [Alias Table](#alias-table) - -## Notes -- Be sure not to conflict variable/function names with built-in functions such as `Add`, `Wait`, or `Damage`. -- Many commonly used values have been aliased in order to reduce verbosity. See the table at the bottom for the list of built-in aliases. -- If you have an unexpected error/suggestion, feel free to submit an issue - - Alternatively, I am open to pull requests if you want to contribute - -## Values / Actions -Values and actions are the main types that come up when working in the Workshop. In general, anything with parameters can be written in two ways (which can be interchanged): - -**Indented Blocks** -``` -Round - Count Of - All Players - Team 2 - Up -``` -**Parenthesized / Literal** -``` -Round(Count Of(All Players(Team 2)), Up) /* Same as output */ -``` - -## Annotations / Comments -Annotations are ways to remind yourself what the type of a variable. It is written as text followed by a colon. Comments are written as most traditional languages (`// line comment`, `/* multiline comment */`). Both are ignored in the code output. -``` -Event - /* Set up event attributes */ - Event_Type: Ongoing - Event Player // Event_Type is an annotation (cannot have spaces!) - Annotation_2: All -``` - -## Assignment / Arithmetic -Assignment (regular and augmented), as well as most arithmetic operators work as they do in Python or other traditional programming languages. Operators include: `+ - * / ^ %` as well as the augmented equivalents: `+= -= *= /= ^= %=` -``` -a = 1 -a += -1 -a *= 3 -a = a ^ (a + a) % 3 -``` - -## Logic -Boolean logic is implemented exactly as in Python. The operators `and`, `or`, and `not` function as C-style `&&`, `| -|`, and `!`. Comparison operators include the traditional `<`, `>`, `<=`, `>=`, `!=`, `==` as well as containment operators `in` and `not in`. -``` -b = True and not True -Count Of - Everyone -== 12 // The reason why == 12 is here is to distinguish between the constant "Everyone" and the value "Count Of". -// You can choose to write this expression inline for less ambiguity: -Count Of(Everyone) == 12 -y = Event Player in Players In Radius(<1, 2, 3>, 15) -``` - -## Variables -Variables are ways to reference values using a name. Their type is stored when they are defined. - -**Global Variables (default)** -``` -gvar hero_index = 1 -global_time = 60s // default type is global -``` -**Player Variables** -``` -pvar score = 2 // pvar is only needed when defining a variable -pvar score@Event Player = 3 // Event Player (default) is the player which the variable will be bound to -score += 1 // modifies the pvar score -``` -**Const** -``` -const cost = 100 -/* const cannot be modified and directly outputs the value, -rather than outputting Value In Array(...) */ -``` - -Using the technique from [@ItsDeltin](https://github.com/ItsDeltin), the limit to -the number of variables that can be created is the maximum length of an array (\~1000 variables). - -## Strings -String literals are enclosed with quotes. Formatted strings are made with enclosing backticks, using `{}` whenever you want to use a variable instead of a string constant. -``` -Rule "String Demo" - Event - On Each Player - All - All - Actions - Msg(Event Player, "Hello") // Alias for Small Message - Big Msg(Event Player, `Money: {}`(pvar money)) // Example formatted string - Small Msg(Event Player, `Unlocked {} / {}: Victory!`(5, 5)) // More advanced formatted string -``` - -## Vectors -Vectors can be created in 3 ways as well: - -**Literal** -``` -Vector(1, 2, 3) -``` -**Block** -``` -Vector - 1 - 2 - 3 -``` -**Idiomatic** -``` -<1, 2, 3> -``` - -## Time -Time can be represented in *ms*, *s*, or *min* as a shorthand for the number value. -``` -Wait(1s + 500ms) -Wait - 0.025min -``` - -## Arrays -Arrays are created, modified, and accessed as in Python notation. Arrays can be nested inside the global/player variables, which allows for more complex operations on arrays. (No slice support yet) - -**Creation** -``` -empty = [] -costs = [5, 15, 30] -``` -**Modification** -``` -costs[1] = 20 -total = costs[0] + costs[1] + costs[2] -``` - -## Functions -Functions allow you to write a block of code once and reuse it many times. They can be used to generate HUDs like a macro or used as a rule factory. All functions must be defined before they are called, and they must be defined at the top level scope (same as where rules are defined). Parameters can be optional, denoted by `?`, which sets the value to `Null` when omitted. Alternatively, specify a default value e.g. `pos?=Event Player.pos`. - -*Note: Functions can access global-scope variables; however, the global scope cannot access variables defined locally in functions* - -``` -%event_func - Event - On Each Player - All - All -%add_rule(a, b, name_) - Rule name_ - event_func() - c = a + b -%say(text, who?=Everyone) // optional parameter, default to Everyone - Msg(who, text) -Rule "Function Demo" - event_func() - Actions - say("Thanks!") -add_rule(1, 5, "Add Two") -``` -**Builtin Functions** - -|Function|Parameters|Description| -|:------:|----------|-----------| -|range|*stop* or *start[, stop[, step]]*|Creates an array of numbers from start to stop (exclusive), counting by step| -|floor|*n*|Rounds a numeric expression down to the nearest integer -|ceil|*n*|Rounds a numeric expression up to the nearest integer -|get_map|Returns the current map ID. This can be compared with map names which alias to their respective ID: `get_map() == Dorado`. For the list of maps and their corresponding IDs, please review [@Xerxes post](https://us.forums.blizzard.com/en/overwatch/t/workshop-resource-map-identifier-map-detection-script-v2-0-only-2-actions/341132). - -## Loops -The while loop is syntactic sugar for using the `Loop` action in the Workshop. At the moment, only use while loops if the purpose of the rule is solely to repeat code until a condition is met. -``` -while pvar life > 10: - Damage(Event Player, Null, 10) -``` -A for loop lets you iterate over custom iterables, such as an array of values, a range, or workshop values such as All Players. -``` -for i in range(1, 10, 2): - Msg(Event Player, i) -for y in [Genji, Tracer, Widowmaker]: - Kill - Players On Hero(y) -``` - -## Attributes / Methods -Attributes are properties of an object that can be accessed using the dot operator `.`, which refers to the value before it in order to access a property. A method is simply an attribute followed by a call, which has parameters. Refer to the table below for builtin attributes and methods. -``` -pvar xpos = Event Player.x // Attribute -y = Victim.jumping and Attacker.moving -scores.append(123) // Method -``` - -**Attribute Table** - -|Name|Description| -|:--:|-----------| -|x|The X component of a vector| -|y|The Y component of a vector| -|z|The Z component of a vector| -|facing|The facing direction of a player| -|pos|The position of a player| -|eyepos|The eye position of a player| -|hero|The hero of a player| -|team|The team of a player| -|jumping|Check if a player is holding the Jump key| -|crouching|Check if a player is holding the Crouch key| -|moving|Check if the speed of a player is non-zero| - -**Method Table** - -|Name|Parameters|Description| -|:--:|:--------:|-----------| -|append|*element*|Appends an element to the given array| -|index|*element*|Returns the numeric index of an array element| -|halt||Mitigates the motion of a player| - -## Alias Table -|Alias|Output| -|-----|------| -|Abs|Absolute Value| -|Any True|Is True For Any| -|All True|Is True For All| -|Chateau Guillard|Château Guillard| -|Cos|Cosine From Degrees| -|Cosr|Cosine From Radians| -|Cur Elem|Current Array Element| -|Filter|Filtered Array| -|Everyone|All Players(Team(All))| -|LOS|Is In Line Of Sight| -|Index|Index Of Array Value| -|Lucio|Lúcio| -|On Each Player|Ongoing - Each Player| -|On Global|Ongoing - Global| -|Players In Radius|Players Within Radius| -|Round|Round To Integer| -|Sin|Sine From Degrees| -|Sinr|Sine From Radians| -|Torbjorn|Torbjörn| - -## Imports -OWScript allows bigger scripts and scripts that use common funcitonality to be broken up into modules and imported into a base file. All the "imported" files are evaluated into a parse tree, which is transpiled to workshop code by the base file. - -You can import a file by using the `#import 'filepath'`. If the file is in a folder, put the relative path to the file as shown in the examples below: - -**Imported File** `lib/functions.owpy` -``` -%CreateEffect(pos, type, color) - Create Effect - Visible_To: Everyone - Type: type - Color: color - Position: pos - Radius: 1.5 - Reevaluation: Visible To -``` - -**Imported File** `src/setup.owpy` -``` -Rule "Setup Effects" - Event - On Global - Actions - CreateEffect(<0,0,0>, Ring, Red) -``` - -**Base File** `src/game.owpy` -``` -#import 'lib/functions' -#import 'src/setup' -``` \ No newline at end of file diff --git a/Syntax/Comments.tmPreferences b/Syntax/Comments.tmPreferences deleted file mode 100644 index 38f1de6..0000000 --- a/Syntax/Comments.tmPreferences +++ /dev/null @@ -1,34 +0,0 @@ - - - - - name - Comments - scope - source.OWScript - settings - - shellVariables - - - name - TM_COMMENT_START - value - // - - - name - TM_COMMENT_START_2 - value - /* - - - name - TM_COMMENT_END_2 - value - */ - - - - - \ No newline at end of file diff --git a/Syntax/OWScript.sublime-syntax b/Syntax/OWScript.sublime-syntax deleted file mode 100644 index 78ae670..0000000 --- a/Syntax/OWScript.sublime-syntax +++ /dev/null @@ -1,176 +0,0 @@ -%YAML 1.2 ---- -name: OWScript -scope: source.OWScript -file_extensions: [ owpy ] - -contexts: - main: - - match: '(\%([_a-zA-Z][_a-zA-Z0-9]*))(?=\()' - push: param_list - captures: - 0: entity.name.function.OWScript - - match: '(\%([_a-zA-Z][_a-zA-Z0-9]*)\b)' - captures: - 0: entity.name.function.OWScript - - match: '(\s+)' - captures: - 0: empty.OWScript - push: - - match: '(?=\S)' - pop: true - captures: - 0: empty.OWScript - - match: '(.)' - captures: - 0: empty.OWScript - - match: '(;)' - captures: - 0: punctuation.OWScript - - match: '(\b([_a-zA-Z][_a-zA-Z0-9]*)\:\s+(?=.))' - push: expr - captures: - 0: comment.annotation.OWScript - - include: rule - param_list: - - match: '(\))' - pop: true - captures: - 0: punctuation.OWScript - - match: '(\()' - captures: - 0: punctuation.OWScript - - match: '(,)' - captures: - 0: punctuation.OWScript - - match: '([_a-zA-Z][_a-zA-Z0-9]*)' - captures: - 0: variable.parameter.OWScript - - include: multiline_comment - rule: - - match: '(?i)(Rule)' - captures: - 0: storage.type.rule.OWScript - - include: expr - expr: - - match: '(\n)' - pop: true - captures: - 0: empty.OWScript - - match: '(\s+)' - captures: - 0: empty.OWScript - push: - - match: '(?=\S)' - pop: true - captures: - 0: empty.OWScript - - match: '(.)' - captures: - 0: empty.OWScript - - match: '(//.*)' - captures: - 0: comment.OWScript - - include: multiline_comment - - match: '([_a-zA-Z][_a-zA-Z0-9]*)(?=\()' - push: arg_list - captures: - 0: variable.function.OWScript - - match: '\b(Team 1|Team 2)\b' - captures: - 0: constant.language.OWScript - - match: '(?i)\b(?=|>|!=|=|\+|\-|\*|\/|\^|%)(?=[^,\)\]]+)' - captures: - 0: keyword.operator.OWScript - vector : - - match: '(>)' - pop: true - captures: - 0: punctuation.vector.OWScript - - match: '(,)' - captures: - 0: punctuation.OWScript - - include: expr - arg_list: - - match: '(\))' - pop: true - captures: - 0: punctuation.OWScript - - match: '(\()' - captures: - 0: punctuation.OWScript - - match: '(,)' - captures: - 0: punctuation.OWScript - - include: expr - fstring: - - match: '(`)' - pop: true - captures: - 0: string.OWScript - - match: '(\{)' - captures: - 0: constant.language.OWScript - push: - - match: '(\})' - pop: true - captures: - 0: constant.language.OWScript - - match: '(.)' - captures: - 0: constant.language.OWScript - - match: '([^\x{007b}\x{007d}\x{0060}]*)' - captures: - 0: string.OWScript - multiline_comment: - - match: '(\s*/\*)' - captures: - 0: comment.OWScript - push: - - match: '(\*/)' - pop: true - captures: - 0: comment.OWScript - - match: '(.)' - captures: - 0: comment.OWScript From a841a5b8759257d6db2fc140bfd83ff3a28f8e45 Mon Sep 17 00:00:00 2001 From: adapap <19696846+adapap@users.noreply.github.com> Date: Thu, 22 Aug 2019 19:48:22 -0400 Subject: [PATCH 3/7] Create lib to reduce function clutter --- Clicker.owpy | 62 +++--------------------------------------- OWScript/Transpiler.py | 5 ++-- lib/events.owpy | 24 ++++++++++++++++ lib/gui.owpy | 34 +++++++++++++++++++++++ 4 files changed, 64 insertions(+), 61 deletions(-) create mode 100644 lib/events.owpy create mode 100644 lib/gui.owpy diff --git a/Clicker.owpy b/Clicker.owpy index 5999ffa..0d17466 100644 --- a/Clicker.owpy +++ b/Clicker.owpy @@ -1,60 +1,6 @@ -%Global - Event - On Global -%Each(team_) - Event - On Each Player - team_ - All -%GameText(who, text, pos, scale) - World Text - Visible_To: who - Header: text - Position: pos - Scale: scale - Clipping: Clip Against Surfaces - Reevaluation: Visible To And String -%CodeText(who, code, pos, scale) - GameText(who, `Save: {} + {} + {} + {} + {}`(code[0], code[1], code[2], code[3], code[4]), pos, scale) -%BigHud(loc, text, color) - Hud - Visible_To: Event Player - Header: text - Subheader: Null - Text: Null - Location: loc - Sort_Order: 0 - Header_Color: color - Subheader_Color: White - Text_Color: White - Reevaluation: Visible To And String -%SmallHud(loc, text, color) - Hud - Visible_To: Event Player - Header: Null - Subheader: Null - Text: text - Location: loc - Sort_Order: 999 - Header_Color: White - Subheader_Color: White - Text_Color: color - Reevaluation: Visible To And String -%Sound(type) - Play Effect - Visible_To: Event Player - Type: type - Color: White - Position: Event Player - Radius: 50 -%SuccessSound - Sound(Buff Explosion Sound) -%FailSound - Sound(Debuff Impact Sound) -%WooshSound - Sound(Ring Explosion Sound) -%BoomSound - Sound(Explosion Sound) +#import "lib/events" +#import "lib/gui" + %MissingFunds Big Msg(Event Player, `Go Find More Money`) %Warp(player, destination, facing) @@ -75,7 +21,7 @@ Position: pos Radius: 1.5 Reevaluation: Visible To - GameText(Everyone, text, (pos + Up), 1.5) + GameText(Everyone, text, pos + Up, 1.5) %UpgradePortal(pos) Portal(pos, Good Aura, Yellow, "Upgrades") %ShopPortal(pos) diff --git a/OWScript/Transpiler.py b/OWScript/Transpiler.py index 345ad62..2d131e5 100644 --- a/OWScript/Transpiler.py +++ b/OWScript/Transpiler.py @@ -194,7 +194,6 @@ def visitImport(self, node, scope): if path not in self.imports: self.imports.add(path) result = Importer.import_file(path) - print(result) else: self.logger.info('Skipping duplicate import {}'.format(path)) result = Script() @@ -736,11 +735,11 @@ def visitCall(self, node, scope): var = Var(name=child.name, type_=Var.METHOD, value=child) scope.assign(var.name, var) obj.env = scope - init = obj.env.get('init').value + init = obj.env.get('init') if init is not None: obj_var = Var(name=obj.name, type_=Var.OBJECT, value=obj) scope.assign('this', obj_var) - init_call = Call(args=node.args, parent=init) + init_call = Call(args=node.args, parent=init.value) self.visit(init_call, scope) return obj elif var.type != Var.BUILTIN: diff --git a/lib/events.owpy b/lib/events.owpy new file mode 100644 index 0000000..e925dba --- /dev/null +++ b/lib/events.owpy @@ -0,0 +1,24 @@ +%Global + Event + On Global +%EachPlayer(team_?=All) + Event + On Each Player + team_ + All +class Sound: + %PlaySound(type) + Play Effect + Visible_To: Event Player + Type: type + Color: White + Position: Event Player + Radius: 50 + %Success() + this.PlaySound(Buff Explosion Sound) + %Fail + this.PlaySound(Debuff Impact Sound) + %Woosh + this.PlaySound(Ring Explosion Sound) + %Boom + this.PlaySound(Explosion Sound) \ No newline at end of file diff --git a/lib/gui.owpy b/lib/gui.owpy new file mode 100644 index 0000000..eeed396 --- /dev/null +++ b/lib/gui.owpy @@ -0,0 +1,34 @@ +%GameText(text, pos, scale?=1.5, who?=Everyone) + World Text + Visible_To: who + Header: text + Position: pos + Scale: scale + Clipping: Clip Against Surfaces + Reevaluation: Visible To And String +%CodeText(code, pos, scale?=1.0, who?=Event Player) + GameText(who, `Save: {} + {} + {} + {} + {}`(code[0], code[1], code[2], code[3], code[4]), pos, scale) +%BigHud(loc, text, color?=White) + Hud + Visible_To: Event Player + Header: text + Subheader: Null + Text: Null + Location: loc + Sort_Order: 0 + Header_Color: color + Subheader_Color: White + Text_Color: White + Reevaluation: Visible To And String +%SmallHud(loc, text, color?=White) + Hud + Visible_To: Event Player + Header: Null + Subheader: Null + Text: text + Location: loc + Sort_Order: 999 + Header_Color: White + Subheader_Color: White + Text_Color: color + Reevaluation: Visible To And String \ No newline at end of file From 3874be0d4bf9f301a2e185fe3a1888c9d1c61d17 Mon Sep 17 00:00:00 2001 From: adapap <19696846+adapap@users.noreply.github.com> Date: Thu, 22 Aug 2019 21:19:18 -0400 Subject: [PATCH 4/7] Move more functions to modules --- Clicker.owpy | 131 +++++++++++++++-------------------------------- lib/effects.owpy | 45 ++++++++++++++++ lib/events.owpy | 18 +------ lib/util.owpy | 31 +++++++++++ 4 files changed, 118 insertions(+), 107 deletions(-) create mode 100644 lib/effects.owpy create mode 100644 lib/util.owpy diff --git a/Clicker.owpy b/Clicker.owpy index 0d17466..ccd2271 100644 --- a/Clicker.owpy +++ b/Clicker.owpy @@ -1,68 +1,14 @@ +#import "lib/effects" #import "lib/events" #import "lib/gui" +#import "lib/util" -%MissingFunds - Big Msg(Event Player, `Go Find More Money`) -%Warp(player, destination, facing) - Teleport(player, destination) - Set Facing - Player: Event Player - Direction: Vector Towards - Start: Event Player - End: facing - Relative: To World - Wait(0.1s) - Event Player.halt() -%Portal(pos, type, color, text) - Create Effect - Visible_To: Everyone - Type: type - Color: color - Position: pos - Radius: 1.5 - Reevaluation: Visible To - GameText(Everyone, text, pos + Up, 1.5) -%UpgradePortal(pos) - Portal(pos, Good Aura, Yellow, "Upgrades") -%ShopPortal(pos) - Portal(pos, Good Aura, Purple, `Current Boss`) -%NextBossPortal(pos, text) - Portal(pos, Good Aura, Blue, text) -%UpgradeEffect(pos, color) - Create Effect - Visible_To: Everyone - Type: Orb - Color: color - Position: pos - Radius: 1.5 - Reevaluation: Visible To -%UpgradeText(upg, cost_var) - GameText(Event Player, `{}: {}`(upgrade_names[upg], cost_var), upgrade_positions[upg] + Up * 0.5, 1.5) -%SaveIcon(pos, icon, color) - Create Icon - Visible_To: Filter - Everyone - LOS - pos - Cur Elem - Barriers Do Not Block LOS - Position: pos - Icon: icon - Reevaluation: Visible To - Icon_Color: White - Show_When_Offscreen: False - Create Effect - Visible_To: Everyone - Type: Ring - Color: color - Position: pos - Radius: 1 - Reevaluation: Visible To Position And Radius %SpawnBoss(boss) Teleport boss_player boss_spawns[Index(boss_heroes, boss)] -%ResetPlayer + +%ResetPlayer() pvar location = 0 pvar cur_boss = 0 pvar bosses_killed = 0 @@ -91,6 +37,8 @@ Rule "Initialize Constants" Global() Actions + sound = Sound() + messager = Messager() /* Define Player Variables */ pvar location = 0 pvar cur_boss = 0 @@ -122,7 +70,7 @@ Rule "Initialize Constants" Set Match Time(90min) Rule "Initialize Player Stats" - Each(Team 1) + EachPlayer(Team 1) Actions /* Player Variables */ ResetPlayer() @@ -176,7 +124,7 @@ Rule "Initialize Effects (Portals / Upgrades / Saves / Boundaries)" CodeText(Players In Radius(secret2_pos, 5, Team(All), Off), ["Left", "Up", "Down", "Up", "Right"], secret2_pos, 0.75) Rule "Initialize Player HUD Stats" - Each(Team 1) + EachPlayer(Team 1) Actions BigHud(Top, `Money: {}`(pvar money), White) SmallHud(Top, `{} Credits ({} / {} Boss Kills)`(pvar credits, pvar bosses_killed, 6), Purple) @@ -249,7 +197,7 @@ Rule "Respawn Bosses" Teleport(Event Player, boss_spawns[Index(boss_heroes, Event Player.hero)]) Rule "Initialize Upgrade Text" - Each(Team 1) + EachPlayer(Team 1) Actions UpgradeText(0, pvar hp_cost) UpgradeText(1, pvar damage_scale_cost) @@ -258,7 +206,7 @@ Rule "Initialize Upgrade Text" UpgradeText(4, pvar defense_cost) Rule "Teleport to Shop" - Each(Team 1) + EachPlayer(Team 1) Conditions Any True Array: portals @@ -272,7 +220,7 @@ Rule "Teleport to Shop" pvar location = -1 Rule "Teleport from Shop" - Each(Team 1) + EachPlayer(Team 1) Conditions Distance Between Event Player @@ -286,7 +234,7 @@ Rule "Teleport from Shop" WooshSound() Rule "Shop Boundary & Heal" - Each(Team 1) + EachPlayer(Team 1) Conditions pvar location == -1 Actions @@ -308,7 +256,7 @@ Rule "Shop Boundary & Heal" Teleport(Event Player, boss_spawns[Index(boss_heroes, hero_)]) Rule "Boss Boundaries (Soldier: 76)" - Each(All) + EachPlayer(All) Conditions Event Player.pos.y < 4.5 Actions @@ -316,7 +264,7 @@ Rule "Boss Boundaries (Soldier: 76)" Wait(2s) Loop If Condition Is True Rule "Boss Boundaries (Mei)" - Each(All) + EachPlayer(All) Conditions Event Player.pos.x > -72 Actions @@ -324,7 +272,7 @@ Rule "Boss Boundaries (Mei)" Wait(2s) Loop If Condition Is True Rule "Boss Boundaries (Lucio)" - Each(All) + EachPlayer(All) Conditions not Event Player in Players In Radius(boss_spawns[3], 20, Team(All), Off) Actions @@ -332,7 +280,7 @@ Rule "Boss Boundaries (Lucio)" Wait(2s) Loop If Condition Is True Rule "Boss Boundaries (Reaper)" - Each(All) + EachPlayer(All) Conditions Event Player.pos.x > -94 Actions @@ -349,7 +297,7 @@ Rule "Boss Boundaries (Reaper)" Wait(0.1s) Loop If Condition Is True Rule "Buy HP" - Each(Team 1) + EachPlayer(Team 1) ShopCondition(upgrade_positions[0]) Actions if pvar money >= pvar hp_cost: @@ -364,7 +312,7 @@ Rule "Buy HP" FailSound() Rule "Buy Damage %" - Each(Team 1) + EachPlayer(Team 1) ShopCondition(upgrade_positions[1]) Actions if pvar money >= pvar damage_scale_cost: @@ -382,7 +330,7 @@ Rule "Buy Damage %" FailSound() Rule "Buy Reload Speed" - Each(Team 1) + EachPlayer(Team 1) ShopCondition(upgrade_positions[2]) Actions if pvar money >= pvar reload_speed_cost: @@ -396,7 +344,7 @@ Rule "Buy Reload Speed" FailSound() Rule "Buy Money Multiplier" - Each(Team 1) + EachPlayer(Team 1) ShopCondition(upgrade_positions[3]) Actions if pvar money >= pvar money_multiplier_cost: @@ -410,7 +358,7 @@ Rule "Buy Money Multiplier" FailSound() Rule "Buy Defense" - Each(Team 1) + EachPlayer(Team 1) ShopCondition(upgrade_positions[4]) Actions if (pvar money >= pvar defense_cost) and (pvar defense > 5): @@ -428,7 +376,7 @@ Rule "Buy Defense" FailSound() Rule "Buy Ability 1" - Each(Team 1) + EachPlayer(Team 1) ShopCondition(ability1_pos) Actions if (pvar money >= ability1_cost) and (not pvar ability1): @@ -443,7 +391,7 @@ Rule "Buy Ability 1" MissingFunds() Rule "Buy Ability 2" - Each(Team 1) + EachPlayer(Team 1) ShopCondition(ability2_pos) Actions if (pvar money >= ability2_cost) and (not pvar ability2): @@ -458,7 +406,7 @@ Rule "Buy Ability 2" MissingFunds() Rule "Teleport Player to Start" - Each(Team 1) + EachPlayer(Team 1) Conditions Has Spawned(Event Player) Actions @@ -467,7 +415,7 @@ Rule "Teleport Player to Start" player_spawns[pvar cur_boss] Rule "Shooting Control" - Each(Team 1) + EachPlayer(Team 1) Conditions Has Spawned(Event Player) Is Firing Primary(Event Player) @@ -506,7 +454,7 @@ Rule "Player Death" Warp(Event Player, shop_pos, upgr_pos) Rule "Next Boss" - Each(Team 1) + EachPlayer(Team 1) Conditions Event Player in Players In Radius(next_boss_portals[pvar cur_boss], 2, Team(All), Off) Actions @@ -526,7 +474,7 @@ Rule "Next Boss" %SaveInput(name, value, pos) Rule "Save Input " + name - Each(Team 1) + EachPlayer(Team 1) Conditions Distance Between(Event Player, pos) <= 1.25 Event Player.interacting @@ -550,7 +498,7 @@ SaveInput("Right", 3, save_pos + x_offset) Wait(0.25) Rule "Buy Prestige Item" - Each(Team 1) + EachPlayer(Team 1) ShopCondition(soldier_temp_pos) Actions if pvar credits >= 1: @@ -560,7 +508,7 @@ Rule "Buy Prestige Item" Big Msg(Event Player, `Defeat Final Boss`) Rule "Check Save Code" - Each(Team 1) + EachPlayer(Team 1) Conditions Count Of(pvar save_code) == 5 Actions @@ -591,14 +539,14 @@ Rule "Check Save Code" pvar save_code = [] Rule "Prestige Confirm" - Each(Team 1) + EachPlayer(Team 1) Conditions Distance Between(Event Player, prestige_pos) <= 1.5 Actions Msg(Event Player, `Start Over? (Jump)`) Rule "Prestige" - Each(Team 1) + EachPlayer(Team 1) Conditions Distance Between(Event Player, prestige_pos) <= 1.5 Event Player.jumping @@ -618,7 +566,7 @@ Rule "Prestige" Rule "Money Bonus (Ability 2 / E)" - Each(Team 1) + EachPlayer(Team 1) Conditions Is Using Ability 2(Event Player) Actions @@ -631,7 +579,7 @@ Rule "Money Bonus (Ability 2 / E)" Msg(Event Player, `Cooldown: {} sec`(pvar money_cd)) Rule "Damage Bonus (Ability 1 / Shift)" - Each(Team 1) + EachPlayer(Team 1) Conditions Is Using Ability 1(Event Player) Actions @@ -646,7 +594,7 @@ Rule "Damage Bonus (Ability 1 / Shift)" Msg(Event Player, `Cooldown: {} sec`(pvar damage_cd)) Rule "Money/Damage Cooldowns" - Each(Team 1) + EachPlayer(Team 1) Conditions (pvar damage_cd > 0) or (pvar money_cd > 0) Actions @@ -658,13 +606,16 @@ Rule "Money/Damage Cooldowns" Loop If Condition Is True Rule "Secret 1" // Flight after jumping by statue - Each(Team 1) + EachPlayer(Team 1) Rule "Secret 2" // Grandma giving passive income every 5s? - Each(Team 1) + EachPlayer(Team 1) + +Rule "Secret 3" // 30% faster ability cooldowns + EachPlayer(Team 1) Disabled Rule "Coordinate Viewer" - Each(Team 1) + EachPlayer(Team 1) Conditions Has Spawned(Event Player) Event Player.moving @@ -691,7 +642,7 @@ Disabled Rule "Coordinate Viewer" Reevaluation: Visible To And String Disabled Rule "Cheats" - Each(Team 1) + EachPlayer(Team 1) Conditions Event Player.jumping Actions diff --git a/lib/effects.owpy b/lib/effects.owpy new file mode 100644 index 0000000..a120f44 --- /dev/null +++ b/lib/effects.owpy @@ -0,0 +1,45 @@ +%Portal(pos, type, color, text) + Create Effect + Visible_To: Everyone + Type: type + Color: color + Position: pos + Radius: 1.5 + Reevaluation: Visible To + GameText(Everyone, text, pos + Up, 1.5) +%UpgradePortal(pos) + Portal(pos, Good Aura, Yellow, "Upgrades") +%ShopPortal(pos) + Portal(pos, Good Aura, Purple, `Current Boss`) +%NextBossPortal(pos, text) + Portal(pos, Good Aura, Blue, text) +%UpgradeEffect(pos, color) + Create Effect + Visible_To: Everyone + Type: Orb + Color: color + Position: pos + Radius: 1.5 + Reevaluation: Visible To +%UpgradeText(upg, cost_var) + GameText(Event Player, `{}: {}`(upgrade_names[upg], cost_var), upgrade_positions[upg] + Up * 0.5, 1.5) +%SaveIcon(pos, icon, color) + Create Icon + Visible_To: Filter + Everyone + LOS + pos + Cur Elem + Barriers Do Not Block LOS + Position: pos + Icon: icon + Reevaluation: Visible To + Icon_Color: White + Show_When_Offscreen: False + Create Effect + Visible_To: Everyone + Type: Ring + Color: color + Position: pos + Radius: 1 + Reevaluation: Visible To Position And Radius \ No newline at end of file diff --git a/lib/events.owpy b/lib/events.owpy index e925dba..ad92041 100644 --- a/lib/events.owpy +++ b/lib/events.owpy @@ -5,20 +5,4 @@ Event On Each Player team_ - All -class Sound: - %PlaySound(type) - Play Effect - Visible_To: Event Player - Type: type - Color: White - Position: Event Player - Radius: 50 - %Success() - this.PlaySound(Buff Explosion Sound) - %Fail - this.PlaySound(Debuff Impact Sound) - %Woosh - this.PlaySound(Ring Explosion Sound) - %Boom - this.PlaySound(Explosion Sound) \ No newline at end of file + All \ No newline at end of file diff --git a/lib/util.owpy b/lib/util.owpy new file mode 100644 index 0000000..b65fea4 --- /dev/null +++ b/lib/util.owpy @@ -0,0 +1,31 @@ +class Sound: + %PlaySound(type) + Play Effect + Visible_To: Event Player + Type: type + Color: White + Position: Event Player + Radius: 50 + %Success() + this.PlaySound(Buff Explosion Sound) + %Fail + this.PlaySound(Debuff Impact Sound) + %Woosh + this.PlaySound(Ring Explosion Sound) + %Boom + this.PlaySound(Explosion Sound) + +class Messager: + %MissingFunds() + Big Msg(Event Player, `Go Find More Money`) + +%Warp(player, destination, facing) + Teleport(player, destination) + Set Facing + Player: Event Player + Direction: Vector Towards + Start: Event Player + End: facing + Relative: To World + Wait(0.1s) + Event Player.halt() \ No newline at end of file From a821b3634d8e65832e0c6508bca767946f2bc8ee Mon Sep 17 00:00:00 2001 From: adapap <19696846+adapap@users.noreply.github.com> Date: Thu, 22 Aug 2019 22:25:39 -0400 Subject: [PATCH 5/7] Error for retrieving properties from array item access --- Clicker.owpy | 86 +++++++++++++++++++++--------------------- OWScript/Importer.py | 5 --- OWScript/Transpiler.py | 35 ++++++++--------- obj.owpy | 10 +++++ 4 files changed, 71 insertions(+), 65 deletions(-) create mode 100644 obj.owpy diff --git a/Clicker.owpy b/Clicker.owpy index ccd2271..fd8ef6c 100644 --- a/Clicker.owpy +++ b/Clicker.owpy @@ -62,7 +62,7 @@ Rule "Initialize Constants" shop_pos = <2.500, 3.500, 75> player_spawns = [<-40, -1.5, 145.5>, <-29, 8, 56>, <-77.5, 1.5, 65.5>, <-50.5, 1.5, 117>, <43.5, 3.5, 73.5>, <-115, 1.5, 112.5>] boss_spawns = [<-31.5, 0, 148>, <-22.5, 7.5, 66.5>, <-82.5, 1.5, 61>, <-59, 1, 104>, <53.5, 3.5, 72.5>, <-129, 2.5, 108.5>] - boss_heroes = [Hero(Roadhog), Hero(Soldier: 76), Hero(Mei), Hero(Lucio), Hero(Ana), Hero(Reaper)] + boss_heroes = [Roadhog, Soldier: 76, Mei, Lucio, Ana, Reaper] ability2_pos = <12.5, 2.5, 71> ability1_pos = <12.5, 2.5, 71 + 2.5> ability1_cost = 25000 @@ -121,7 +121,7 @@ Rule "Initialize Effects (Portals / Upgrades / Saves / Boundaries)" GameText(All Players(Team 1), `Unlock {}: {} Credit`(Hero(Soldier: 76), 1), soldier_temp_pos + Up * 0.5, 1.5) // Secrets secret2_pos = <31, 2.5, 49.5> - CodeText(Players In Radius(secret2_pos, 5, Team(All), Off), ["Left", "Up", "Down", "Up", "Right"], secret2_pos, 0.75) + CodeText(["Left", "Up", "Down", "Up", "Right"], secret2_pos, 0.75, Players In Radius(secret2_pos, 5, Team(All), Off)) Rule "Initialize Player HUD Stats" EachPlayer(Team 1) @@ -216,7 +216,7 @@ Rule "Teleport to Shop" <= 2.0 Actions Warp(Event Player, shop_pos, upgr_pos) - WooshSound() + sound.Woosh() pvar location = -1 Rule "Teleport from Shop" @@ -231,7 +231,7 @@ Rule "Teleport from Shop" pvar location = pvar cur_boss Wait(0.1s) Warp(Event Player, player_spawns[pvar location], Closest Player To(Event Player, Team 2)) - WooshSound() + sound.Woosh() Rule "Shop Boundary & Heal" EachPlayer(Team 1) @@ -244,14 +244,14 @@ Rule "Shop Boundary & Heal" Skip If(Not((Event Player.pos.x <= -12) or (Event Player.pos.z <= 25)), 6) Warp(Event Player, shop_pos, upgr_pos) Msg(Event Player, `Avoid Going Here`) - FailSound() + sound.Fail() %BossBoundary(loc, hero_) if Event Player in All Players(Team 1): if pvar location == loc: Teleport(Event Player, player_spawns[pvar cur_boss]) Msg(Event Player, `Avoid Going Here`) - FailSound() + sound.Fail() elif Event Player.hero == hero_: Teleport(Event Player, boss_spawns[Index(boss_heroes, hero_)]) @@ -305,11 +305,11 @@ Rule "Buy HP" pvar hp_cost = ceil(pvar hp_cost + upgrade_rates[0]) pvar hp += 10 Set Max Health(Event Player, pvar hp) - SuccessSound() + sound.Success() ShopAutobuy() else: - MissingFunds() - FailSound() + messager.messager.MissingFunds() + sound.Fail() Rule "Buy Damage %" EachPlayer(Team 1) @@ -323,11 +323,11 @@ Rule "Buy Damage %" pvar damage_scale += 2 Set Damage Dealt(Event Player, pvar damage_scale) pvar damage_scale_cost = ceil(pvar damage_scale_cost ^ upgrade_rates[1]) - SuccessSound() + sound.Success() ShopAutobuy() else: - MissingFunds() - FailSound() + messager.MissingFunds() + sound.Fail() Rule "Buy Reload Speed" EachPlayer(Team 1) @@ -337,11 +337,11 @@ Rule "Buy Reload Speed" pvar money -= pvar reload_speed_cost pvar reload_speed_cost = ceil(pvar reload_speed_cost ^ upgrade_rates[2]) pvar reload_speed = max(pvar reload_speed * 0.95, 0) - SuccessSound() + sound.Success() ShopAutobuy() else: - MissingFunds() - FailSound() + messager.MissingFunds() + sound.Fail() Rule "Buy Money Multiplier" EachPlayer(Team 1) @@ -351,11 +351,11 @@ Rule "Buy Money Multiplier" pvar money -= pvar money_multiplier_cost pvar money_multiplier_cost = ceil(pvar money_multiplier_cost ^ upgrade_rates[3]) pvar money_multiplier += 0.075 - SuccessSound() + sound.Success() ShopAutobuy() else: - MissingFunds() - FailSound() + messager.MissingFunds() + sound.Fail() Rule "Buy Defense" EachPlayer(Team 1) @@ -366,14 +366,14 @@ Rule "Buy Defense" pvar defense_cost = ceil(pvar defense_cost ^ upgrade_rates[4]) pvar defense = Max(pvar defense - 2, 5) Set Damage Received(Event Player, pvar defense) - SuccessSound() + sound.Success() ShopAutobuy() elif pvar defense == 5: Msg(Event Player, `Max Defend`) - FailSound() + sound.Fail() else: - MissingFunds() - FailSound() + messager.MissingFunds() + sound.Fail() Rule "Buy Ability 1" EachPlayer(Team 1) @@ -383,12 +383,12 @@ Rule "Buy Ability 1" pvar money -= ability1_cost pvar ability1 = True Set Ability 1 Enabled(Event Player, True) - SuccessSound() + sound.Success() elif pvar ability1: Msg(Event Player, `You Bought Ability 1`) - FailSound() + sound.Fail() else: - MissingFunds() + messager.MissingFunds() Rule "Buy Ability 2" EachPlayer(Team 1) @@ -398,12 +398,12 @@ Rule "Buy Ability 2" pvar money -= ability2_cost pvar ability2 = True Set Ability 2 Enabled(Event Player, True) - SuccessSound() + sound.Success() elif pvar ability2: Msg(Event Player, `You Bought Ability 2`) - FailSound() + sound.Fail() else: - MissingFunds() + messager.MissingFunds() Rule "Teleport Player to Start" EachPlayer(Team 1) @@ -464,13 +464,13 @@ Rule "Next Boss" Wait(0.1s) Warp(Event Player, player_spawns[pvar cur_boss], boss_spawns[pvar cur_boss]) pvar location = pvar cur_boss - WooshSound() + sound.Woosh() elif pvar money < next_boss_cost[pvar cur_boss]: - MissingFunds() - FailSound() + messager.MissingFunds() + sound.Fail() else: Big Msg(Event Player, `Go Kill Boss`) - FailSound() + sound.Fail() %SaveInput(name, value, pos) Rule "Save Input " + name @@ -481,7 +481,7 @@ Rule "Next Boss" Actions Msg(Event Player, name) pvar save_code.append(value) - BoomSound() + sound.Boom() SaveInput("Up", 0, save_pos - z_offset) SaveInput("Down", 1, save_pos + z_offset) @@ -494,7 +494,7 @@ SaveInput("Right", 3, save_pos + x_offset) Set Hero(Event Player, hero_) Wait(0.5s) Big Msg(Event Player, `You Unlocked {}`(Hero Icon String(hero_))) - SuccessSound() + sound.Success() Wait(0.25) Rule "Buy Prestige Item" @@ -518,19 +518,19 @@ Rule "Check Save Code" // 3: Right if pvar save_code == [0, 0, 0, 0, 0]: UnlockHero(Hero(McCree)) - CodeText(Event Player, ["Up", "Up", "Up", "Up", "Up"], save_pos + Up * 1.25, 2) + CodeText(["Up", "Up", "Up", "Up", "Up"], save_pos + Up * 1.25, 2) elif pvar save_code == [3, 1, 2, 3, 2]: UnlockHero(Hero(Soldier: 76)) - CodeText(Event Player, ["Right", "Down", "Left", "Right", "Left"], save_pos + Up * 1.25, 2) + CodeText(["Right", "Down", "Left", "Right", "Left"], save_pos + Up * 1.25, 2) elif pvar save_code == [0, 2, 2, 1, 3]: - UnlockHero(Hero(Ashe)) - CodeText(Event Player, ["Up", "Left", "Left", "Down", "Right"], save_pos + Up * 1.25, 2) + UnlockHero(Ashe) + CodeText(["Up", "Left", "Left", "Down", "Right"], save_pos + Up * 1.25, 2) elif pvar save_code == [2, 3, 2, 0, 0]: - UnlockHero(Hero(Genji)) - CodeText(Event Player, ["Left", "Right", "Left", "Up", "Up"], save_pos + Up * 1.25, 2) + UnlockHero(Genji) + CodeText(["Left", "Right", "Left", "Up", "Up"], save_pos + Up * 1.25, 2) elif pvar save_code == [1, 1, 3, 1, 2]: - UnlockHero(Hero(Hanzo)) - CodeText(Event Player, ["Down", "Down", "Right", "Down", "Left"], save_pos + Up * 1.25, 2) + UnlockHero(Hanzo) + CodeText(["Down", "Down", "Right", "Down", "Left"], save_pos + Up * 1.25, 2) elif pvar save_code == [2, 0, 1, 0, 3]: // Secrets Big Msg(Event Player, "Hacked") // You Unlocked Hidden Save 2 @@ -560,7 +560,7 @@ Rule "Prestige" Set Slow Motion(100) Warp(Event Player, player_spawns[0], boss_spawns[0]) Msg(Event Player, `{} Credits`(pvar credits)) - SuccessSound() + sound.Success() else: Big Msg(Event Player, `Defeat Final Boss`) diff --git a/OWScript/Importer.py b/OWScript/Importer.py index 3f97df0..ab34b6d 100644 --- a/OWScript/Importer.py +++ b/OWScript/Importer.py @@ -1,19 +1,14 @@ -from . import Errors from .Lexer import Lexer from .Parser import Parser def import_file(path): - error_text = Errors.TEXT with open(path) as f: text = f.read() + '\n' try: - Errors.TEXT = text lexer = Lexer(text=text) tokens = lexer.lex() parser = Parser(tokens=tokens) tree = parser.script() - Errors.TEXT = error_text return tree except Exception as ex: - Errors.TEXT = error_text raise ex \ No newline at end of file diff --git a/OWScript/Transpiler.py b/OWScript/Transpiler.py index 2d131e5..5c67f32 100644 --- a/OWScript/Transpiler.py +++ b/OWScript/Transpiler.py @@ -622,7 +622,7 @@ def visitArray(self, node, scope): else: elements = [] for elem in node.elements: - if type(elem) in (String, Constant): + if type(elem) in (String, Constant, Var): elements.append(Constant(name='Null')) else: elements.append(elem) @@ -640,22 +640,20 @@ def visitItem(self, node, scope): var = scope.get(node.parent.name) if not var: raise Errors.NameError('\'{}\' is undefined'.format(node.parent.name), pos=node.parent._pos) - try: - index = int(node.index.value) - array = var.value - assert type(array) == Array - if not 0 <= index < len(array): - return self.visit(Number(value='0'), scope) + index = int(node.index.value) + array = var.value + if not type(array) == Array: + raise Errors.SyntaxError('Cannot get item from non-array \'{}\''.format(type(array).__name__), pos=node.parent._pos) + if not 0 <= index < len(array): + return self.visit(Number(value='0'), scope) + else: + if var.type == Var.GLOBAL: + return 'Value In Array(Value In Array(Global Variable({})), {}, {})'.format(var.data.letter, var.data.index, index) + elif var.type == Var.PLAYER: + player = self.visit(var.data.player if node.parent.player is None else node.parent.player, scope) + return 'Value In Array(Value In Array(Player Variable({}, {})), {}, {})'.format(player, var.data.letter, var.data.index, index) else: - if var.type == Var.GLOBAL: - return 'Value In Array(Value In Array(Global Variable({})), {}, {})'.format(var.data.letter, var.data.index, index) - elif var.type == Var.PLAYER: - player = self.visit(var.data.player if node.parent.player is None else node.parent.player, scope) - return 'Value In Array(Value In Array(Player Variable({}, {})), {}, {})'.format(player, var.data.letter, var.data.index, index) - else: - return self.visit(var.value[index], scope) - except AssertionError: - raise Errors.SyntaxError('Cannot get item from non-array type {}'.format(type(var.value)), pos=node.parent._pos) + return self.visit(var.value[index], scope) else: try: index = int(scope.get(node.index.name).value) @@ -673,6 +671,8 @@ def visitAttribute(self, node, scope): parent = scope.get(node.parent.name).value else: parent = node.parent + if type(parent) == Item: + raise Errors.NotImplementedError('Cannot access properties of array elements', pos=node._pos) try: attribute = getattr(parent, attr) except AttributeError: @@ -691,9 +691,10 @@ def visitCall(self, node, scope): parent = node.parent base_node = self.base_node(node) var = scope.get(base_node.name) + is_object = type(var) == Var and var.type == Var.OBJECT lines = [] # Handle method (attribute access followed by a call) - if type(parent) == Attribute and not var.type == Var.OBJECT: + if type(parent) == Attribute and not is_object: if var is not None: method = getattr(var.value, parent.name) else: diff --git a/obj.owpy b/obj.owpy new file mode 100644 index 0000000..89ba653 --- /dev/null +++ b/obj.owpy @@ -0,0 +1,10 @@ +class A: + %init(b, c) + this.b = b + this.c = c + +Rule "Object Test" + Actions + a = A(1, 2) + b = [a] + Msg(Everyone, b[0].b) \ No newline at end of file From 108cf2201ac97b402c990162b6c7b39d37c23058 Mon Sep 17 00:00:00 2001 From: adapap <19696846+adapap@users.noreply.github.com> Date: Fri, 23 Aug 2019 15:07:01 -0400 Subject: [PATCH 6/7] Possible fix for attribute access on array items --- OWScript/Transpiler.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/OWScript/Transpiler.py b/OWScript/Transpiler.py index 5c67f32..7987309 100644 --- a/OWScript/Transpiler.py +++ b/OWScript/Transpiler.py @@ -633,7 +633,7 @@ def visitArray(self, node, scope): code += 'Empty Array, ' + '), '.join(self.visit(elem, scope) for elem in elements) + ')' return code - def visitItem(self, node, scope): + def visitItem(self, node, scope, visit=True): """An item is accessing an element of an array.""" # Try to access an array element by interpreting the number? if type(node.index) == Number and type(node.parent) == Var: @@ -647,6 +647,8 @@ def visitItem(self, node, scope): if not 0 <= index < len(array): return self.visit(Number(value='0'), scope) else: + if not visit: + return var.value[index] if var.type == Var.GLOBAL: return 'Value In Array(Value In Array(Global Variable({})), {}, {})'.format(var.data.letter, var.data.index, index) elif var.type == Var.PLAYER: @@ -658,7 +660,7 @@ def visitItem(self, node, scope): try: index = int(scope.get(node.index.name).value) item = scope.get(node.parent.name).value[index] - return self.visit(item, scope) + return self.visit(item, scope) if visit else item except (ValueError, TypeError, AttributeError): array = self.visit(node.parent, scope) index = self.visit(node.index, scope) @@ -672,7 +674,10 @@ def visitAttribute(self, node, scope): else: parent = node.parent if type(parent) == Item: - raise Errors.NotImplementedError('Cannot access properties of array elements', pos=node._pos) + item = self.visitItem(parent, scope, visit=False) + node.parent = item + result = self.visitAttribute(node, scope) + return result try: attribute = getattr(parent, attr) except AttributeError: From 636881532e7988934f12183ab9e92ccaee223626 Mon Sep 17 00:00:00 2001 From: adapap <19696846+adapap@users.noreply.github.com> Date: Sat, 24 Aug 2019 15:29:50 -0400 Subject: [PATCH 7/7] More object-related bugfixes, allow objects in rule names --- Clicker.owpy | 52 +++++++++++++++++++----------------------- OWScript/AST.py | 19 ++++----------- OWScript/Parser.py | 5 ++++ OWScript/Transpiler.py | 15 ++++++++---- lib/effects.owpy | 14 +++++++++--- obj.owpy | 10 -------- 6 files changed, 53 insertions(+), 62 deletions(-) delete mode 100644 obj.owpy diff --git a/Clicker.owpy b/Clicker.owpy index fd8ef6c..38708c7 100644 --- a/Clicker.owpy +++ b/Clicker.owpy @@ -90,19 +90,22 @@ Rule "Initialize Effects (Portals / Upgrades / Saves / Boundaries)" soldier_temp_pos = <3, 3, 77.5> x_offset = <2.5, 0, 0> z_offset = <0, 0, 2.5> - upgrade_names = ["Heal", "Damage", "Faster", "Money", "Defend"] - upgrade_rates = [100, 1.003, 1.04, 1.045, 1.03] - upgrade_positions = [] - for i in range(-2, 3): - upgrade_positions.append(upgr_pos + i * x_offset) - upgrade_colors = [Purple, Red, Yellow, Green, Blue] + + // Upgrade(name, rate, pos, color) + upgrades = [] + upgrades.append(Upgrade("Heal", 100, hp_cost, upgr_pos - 2 * x_offset, Purple)) + upgrades.append(Upgrade("Damage", 1.003, damage_scale_cost, upgr_pos - x_offset, Red)) + upgrades.append(Upgrade("Faster", 1.04, reload_speed_cost, upgr_pos, Yellow)) + upgrades.append(Upgrade("Money", 1.045, money_multiplier_cost, upgr_pos + x_offset, Green)) + upgrades.append(Upgrade("Defend", 1.03, defense_cost, upgr_pos + 2 * x_offset, Blue)) // Bosses 1-6 -> Shop for portal in portals: UpgradePortal(portal) ShopPortal(shop_portal) // HP, Damage, Reload Speed, Money Multiplier, Damage Resistance - for i in range(5): - UpgradeEffect(upgrade_positions[i], upgrade_colors[i]) + for upgrade in upgrades: + UpgradeEffect(upgrade.pos, upgrade.color) + UpgradeText(upgrade.name, upgrade.pos, upgrade.cost) // Next Boss for i in range(5): NextBossPortal(next_boss_portals[i], `Next Boss: {}`(next_boss_cost[i])) @@ -196,15 +199,6 @@ Rule "Respawn Bosses" Wait(0.1s) Teleport(Event Player, boss_spawns[Index(boss_heroes, Event Player.hero)]) -Rule "Initialize Upgrade Text" - EachPlayer(Team 1) - Actions - UpgradeText(0, pvar hp_cost) - UpgradeText(1, pvar damage_scale_cost) - UpgradeText(2, pvar reload_speed_cost) - UpgradeText(3, pvar money_multiplier_cost) - UpgradeText(4, pvar defense_cost) - Rule "Teleport to Shop" EachPlayer(Team 1) Conditions @@ -298,11 +292,11 @@ Rule "Boss Boundaries (Reaper)" Loop If Condition Is True Rule "Buy HP" EachPlayer(Team 1) - ShopCondition(upgrade_positions[0]) + ShopCondition(upgrades[0].pos) Actions if pvar money >= pvar hp_cost: pvar money -= pvar hp_cost - pvar hp_cost = ceil(pvar hp_cost + upgrade_rates[0]) + pvar hp_cost = ceil(pvar hp_cost + upgrades[0].rate) pvar hp += 10 Set Max Health(Event Player, pvar hp) sound.Success() @@ -313,7 +307,7 @@ Rule "Buy HP" Rule "Buy Damage %" EachPlayer(Team 1) - ShopCondition(upgrade_positions[1]) + ShopCondition(upgrades[1].pos) Actions if pvar money >= pvar damage_scale_cost: pvar money -= pvar damage_scale_cost @@ -322,7 +316,7 @@ Rule "Buy Damage %" Skip If(pvar damage_scale < 75, 1) pvar damage_scale += 2 Set Damage Dealt(Event Player, pvar damage_scale) - pvar damage_scale_cost = ceil(pvar damage_scale_cost ^ upgrade_rates[1]) + pvar damage_scale_cost = ceil(pvar damage_scale_cost ^ upgrades[1].rate) sound.Success() ShopAutobuy() else: @@ -331,11 +325,11 @@ Rule "Buy Damage %" Rule "Buy Reload Speed" EachPlayer(Team 1) - ShopCondition(upgrade_positions[2]) + ShopCondition(upgrades[2].pos) Actions if pvar money >= pvar reload_speed_cost: pvar money -= pvar reload_speed_cost - pvar reload_speed_cost = ceil(pvar reload_speed_cost ^ upgrade_rates[2]) + pvar reload_speed_cost = ceil(pvar reload_speed_cost ^ upgrades[2].rate) pvar reload_speed = max(pvar reload_speed * 0.95, 0) sound.Success() ShopAutobuy() @@ -345,11 +339,11 @@ Rule "Buy Reload Speed" Rule "Buy Money Multiplier" EachPlayer(Team 1) - ShopCondition(upgrade_positions[3]) + ShopCondition(upgrades[3].pos) Actions if pvar money >= pvar money_multiplier_cost: pvar money -= pvar money_multiplier_cost - pvar money_multiplier_cost = ceil(pvar money_multiplier_cost ^ upgrade_rates[3]) + pvar money_multiplier_cost = ceil(pvar money_multiplier_cost ^ upgrades[3].rate) pvar money_multiplier += 0.075 sound.Success() ShopAutobuy() @@ -359,11 +353,11 @@ Rule "Buy Money Multiplier" Rule "Buy Defense" EachPlayer(Team 1) - ShopCondition(upgrade_positions[4]) + ShopCondition(upgrades[4].pos) Actions if (pvar money >= pvar defense_cost) and (pvar defense > 5): pvar money -= pvar defense_cost - pvar defense_cost = ceil(pvar defense_cost ^ upgrade_rates[4]) + pvar defense_cost = ceil(pvar defense_cost ^ upgrades[4].rate) pvar defense = Max(pvar defense - 2, 5) Set Damage Received(Event Player, pvar defense) sound.Success() @@ -375,7 +369,7 @@ Rule "Buy Defense" messager.MissingFunds() sound.Fail() -Rule "Buy Ability 1" +/* Rule "Buy Ability 1" EachPlayer(Team 1) ShopCondition(ability1_pos) Actions @@ -649,4 +643,4 @@ Disabled Rule "Cheats" pvar money += 1000000 pvar reload_speed = 0.01 Set Damage Received(Event Player, 0) - Set Damage Dealt(Event Player, 10000) \ No newline at end of file + Set Damage Dealt(Event Player, 10000) */ \ No newline at end of file diff --git a/OWScript/AST.py b/OWScript/AST.py index d20c1ae..1f37643 100644 --- a/OWScript/AST.py +++ b/OWScript/AST.py @@ -421,7 +421,9 @@ def __init__(self, elements=None): self.elements = elements or [] def append(self, tp, elem): - elem = Raw(code=tp.visit(elem, tp.scope)) + elem = tp.visit(elem, tp.scope) + if type(elem) != Object: + elem = Raw(code=elem) self.elements.append(elem) def index(self, elem): @@ -450,19 +452,6 @@ class Compare(BinaryOp): class Assign(BinaryOp): pass -# class GlobalVar(Data): -# vartype = 'global' - -# class PlayerVar(Data): -# vartype = 'player' -# def __init__(self, name, player=None): -# super().__init__(name) -# self.player = player or Constant(name='Event Player') -# class VarType: -# # Compares whether a value is a GlobalVar or PlayerVar -# def __eq__(self, other): -# return other in (GlobalVar, PlayerVar) - class GlobalVar(AST): def __init__(self, letter, index=None): self.letter = letter @@ -579,7 +568,7 @@ def __init__(self, name, body): def __repr__(self): return 'class {}'.format(self.name) -class Object(AST): +class Object(): def __init__(self, type_): self.type = type_ self.env = {} diff --git a/OWScript/Parser.py b/OWScript/Parser.py index 20bcc5d..0d6e8a3 100644 --- a/OWScript/Parser.py +++ b/OWScript/Parser.py @@ -187,6 +187,11 @@ def ruledef(self): var = Var(self.curvalue, type_=Var.STRING) var._pos = self.curpos name.append(var) + elif self.curtype == 'DOT': + self.eat('DOT') + node = Attribute(name=self.curvalue, parent=name.pop()) + node._pos = self.curpos + name.append(node) else: raise Errors.ParseError('Unexpected token \'{}\' in rule name'.format(self.curvalue), pos=self.curpos) self.eat(self.curtype) diff --git a/OWScript/Transpiler.py b/OWScript/Transpiler.py index 7987309..c1a5e78 100644 --- a/OWScript/Transpiler.py +++ b/OWScript/Transpiler.py @@ -288,6 +288,7 @@ def visitOWID(self, node, scope): if not var: raise Errors.NameError('\'{}\' is undefined'.format(child.name), pos=node._pos) node.children[index] = Raw(code=var.data.letter) + print(var.data.letter) continue values = list(map(lambda x: x.replace(',', ''), flatten(arg.get_values()))) value = self.visit(child, scope).upper() @@ -390,6 +391,8 @@ def visitAssign(self, node, scope): raise Errors.SyntaxError('Cannot assign value to attributes') resolved = self.resolve_name(value, scope) var = Var(name=node.left.name, type_=Var.INTERNAL, value=resolved) + if type(resolved) == String: + var.type = Var.STRING obj.env.assign(node.left.name, var) return code else: @@ -658,10 +661,12 @@ def visitItem(self, node, scope, visit=True): return self.visit(var.value[index], scope) else: try: - index = int(scope.get(node.index.name).value) + index = scope.get(node.index.name) + assert hasattr(index, 'value') + index = int(index.value) item = scope.get(node.parent.name).value[index] return self.visit(item, scope) if visit else item - except (ValueError, TypeError, AttributeError): + except (ValueError, TypeError, AssertionError): array = self.visit(node.parent, scope) index = self.visit(node.index, scope) return 'Value In Array({}, {})'.format(array, index) @@ -681,9 +686,9 @@ def visitAttribute(self, node, scope): try: attribute = getattr(parent, attr) except AttributeError: - name = node.parent.name - if type(parent) != Object: - name = parent.name.title() + name = node.parent + if type(parent) != Object and type(name) == str: + name = name.title() raise Errors.AttributeError('\'{}\' has no attribute \'{}\''.format(name, attr), pos=node._pos) if type(parent) == Object: code = self.visit(attribute, parent.env) diff --git a/lib/effects.owpy b/lib/effects.owpy index a120f44..f696e2d 100644 --- a/lib/effects.owpy +++ b/lib/effects.owpy @@ -21,8 +21,8 @@ Position: pos Radius: 1.5 Reevaluation: Visible To -%UpgradeText(upg, cost_var) - GameText(Event Player, `{}: {}`(upgrade_names[upg], cost_var), upgrade_positions[upg] + Up * 0.5, 1.5) +%UpgradeText(text, pos, cost_var) + GameText(Event Player, `{}: {}`(text, cost_var), pos + Up * 0.5, 1.5) %SaveIcon(pos, icon, color) Create Icon Visible_To: Filter @@ -42,4 +42,12 @@ Color: color Position: pos Radius: 1 - Reevaluation: Visible To Position And Radius \ No newline at end of file + Reevaluation: Visible To Position And Radius + +class Upgrade: + %init(name, rate, cost, pos, color) + this.name = name + this.rate = rate + this.pos = pos + this.color = color + this.cost = cost \ No newline at end of file diff --git a/obj.owpy b/obj.owpy deleted file mode 100644 index 89ba653..0000000 --- a/obj.owpy +++ /dev/null @@ -1,10 +0,0 @@ -class A: - %init(b, c) - this.b = b - this.c = c - -Rule "Object Test" - Actions - a = A(1, 2) - b = [a] - Msg(Everyone, b[0].b) \ No newline at end of file