Tile Status, Panel Steal,

Basic attack scaling,
player keeping chips from previous round
This commit is contained in:
Derenash 2021-12-03 14:11:45 -03:00
parent 6808f4d573
commit c672641eea
11 changed files with 209 additions and 33 deletions

View File

@ -24,9 +24,7 @@ App.GG: App<App.GG.State>
// Todos:
// - Organize functions inside files by section (like attributes is in creature)
// App.GG.when needs to be organized and commented
// - Make Basic Attack scale with damage attribute (maybe dealing 2 dmg baseline, that is increased by 1 each 5 points?)
// - Add an animation to basic attack (x key)
// - Create a panel steal Chip
// - Show chips in hand in setup phase
// - Show chips in hand in game phase
// - make poison do damage
@ -40,11 +38,13 @@ App.GG: App<App.GG.State>
// As example: Walk(0, 24) -> (frame % 24) / (24/image_count) -> (frame % 24) / 2 -> for a 12 images animation
// - Create simple AI based on time in front of a slime and time not in front of a slime
// - Create 3 minions
// - Make the player keep the remaining chips from the previous round if no chips are selected
// - Add tile statuses
// - Create customizations for buttons
// - Add comments to everything
// DONE: Add tile statuses
// DONE: Create a panel steal Chip
// DONE: Make Basic Attack scale with damage attribute
// DONE: Make the player keep the remaining chips from the previous round if no chips are selected
// DONE: Fix Projectile running twice in a frame
// DONE: Add higher energy cost for using chips from different types
// DONE: Create simple statuses (stun, invulnerable, root, poison)

View File

@ -27,7 +27,7 @@ type App.GG.Body.Parts {
}
App.GG.Body.Components.upper: App.GG.Body.Components
[App.GG.Components.recursive_gun]
[App.GG.Components.panel_steal]
App.GG.Body.Components.lower: App.GG.Body.Components
[App.GG.Components.pull_sword]

View File

@ -0,0 +1,39 @@
App.GG.Chip.panel_steal: App.GG.Chip
App.GG.Chip.new(
"PSteal"
App.GG.Class.control
App.GG.Chip.panel_steal.Effect
10
App.GG.img.bazooka
)
// App.GG.Chip.panel_steal.Effect: App.GG.Effect<Unit>
// App.GG.Chip.panel_steal.Effect(4, 2)
App.GG.Chip.panel_steal.Effect: App.GG.Effect<Unit>
App.GG.Effect {
get center = App.GG.Effect.coord.get_center
get grid = App.GG.Effect.grid.get
get tile = App.GG.Effect.tile.get
App.GG.Effect.frame.inc // Increases action's frame by 1
without tile: App.GG.Effect.pass
App.GG.Effect {
App.GG.Effect.chip.waste
App.GG.Effect.actions.reset
let enemy_coord = App.GG.Coord.first_enemy_tile(center, tile@owner, grid)
without enemy_coord: App.GG.Effect.pass
App.GG.Effect {
get enemy = App.GG.Effect.creature.get_at(enemy_coord)
without enemy:
App.GG.Effect {
App.GG.Effect.tile.change_owner(tile@owner, enemy_coord)
App.GG.Effect.tile.add_status(App.GG.Tile.Status.stolen(300), enemy_coord)
}
App.GG.Effect.pass
}
}
}

View File

@ -0,0 +1,2 @@
App.GG.Components.panel_steal: App.GG.Body.Component
App.GG.Body.Component.new(App.GG.Chip.panel_steal, App.GG.Creature.Attributes.new(0,0,3,1))

View File

@ -103,4 +103,13 @@ App.GG.Coord.first_enemy_in_front(team: App.GG.Team, grid: App.GG.Grid, coord: A
if App.GG.Team.eql(creature@team, team) then
next(new_coord)
else
some(new_coord)
some(new_coord)
App.GG.Coord.first_enemy_tile(coord: App.GG.Coord, team: App.GG.Team, grid: App.GG.Grid): Maybe<App.GG.Coord>
let front_coord = App.GG.Coord.front(coord, team)
let front_tile = App.GG.Grid.get(front_coord, grid)
without front_tile: none
if App.GG.Team.eql(team, front_tile@owner) then
App.GG.Coord.first_enemy_tile(front_coord, team, grid)
else
some(front_coord)

View File

@ -83,6 +83,7 @@ App.GG.Creature.get(
//===========================================================
//Status Management
type App.GG.Creature.Status {
invulnerable(duration: U64)
poison(duration: U64, damage: I32)
@ -320,12 +321,25 @@ App.GG.Creature.place(creature: App.GG.Creature, coord: App.GG.Coord, grid: App.
App.GG.Grid.update(coord, f, grid)
App.GG.Creature.dmg_with_attribute(creature: App.GG.Creature, dmg: I32): I32
let attributes = App.GG.Creature.Attributes.get(creature)
without attributes: dmg
let destruction = attributes@damage
(dmg * destruction) / 25
App.GG.Creature.basic_attack_dmg(creature: App.GG.Creature): I32
let attributes = App.GG.Creature.Attributes.get(creature)
without attributes: 0 :: I32
let base_dmg = 2 :: I32
let extra_dmg = (attributes@damage - 25) / 5
let total_dmg = base_dmg + extra_dmg
I32.neg(total_dmg)
App.GG.Creature.Attributes.get(creature: App.GG.Creature): Maybe<App.GG.Creature.Attributes>
case creature@category as monster {
minion: dmg
minion: none
slime:
let slime = monster.data
let dna = slime@dna
let attributes = dna@attributes
let destruction = attributes@damage
(dmg * destruction) / 25
}
some(attributes)
}

View File

@ -15,7 +15,8 @@ App.GG.Effect.basic_attack: App.GG.Effect<Unit>
App.GG.Effect.actions.reset
without enemy_coord: App.GG.Effect.pass
App.GG.Effect {
get dmg = App.GG.Effect.creature.change_hp_at(-1, enemy_coord, false)
let dmg = App.GG.Creature.basic_attack_dmg(creature)
get real_dmg = App.GG.Effect.creature.change_hp_at(dmg, enemy_coord, false)
return unit
}
}

View File

@ -1,4 +1,18 @@
App.GG.Effect.tile.get: App.GG.Effect<Maybe<App.GG.Tile>>
(center, origin, grid)
let tile = App.GG.Grid.get(center, grid)
App.GG.Effect.Result.new!(tile, center, origin, grid, (img) img, 0, "")
App.GG.Effect.Result.new!(tile, center, origin, grid, (img) img, 0, "")
App.GG.Effect.tile.add_status(status: App.GG.Tile.Status, coord: App.GG.Coord): App.GG.Effect<Unit>
(center, origin, grid)
let tile = App.GG.Grid.get(coord, grid)
let new_grid =
without tile: grid
App.GG.Grid.update(coord, App.GG.Tile.Status.add(status), grid)
App.GG.Effect.Result.new!(unit, center, origin, new_grid, (img) img, 0, "")
App.GG.Effect.tile.change_owner(team: App.GG.Team, coord: App.GG.Coord): App.GG.Effect<Unit>
(center, origin, grid)
let f = (tile: App.GG.Tile) tile@owner <- team
let new_grid = App.GG.Grid.update(coord, f, grid)
App.GG.Effect.Result.new!(unit, center, origin, new_grid, (img) img, 0, "")

View File

@ -4,9 +4,25 @@ type App.GG.Tile {
projectiles: List<App.GG.Projectile>
creature: Maybe<App.GG.Creature>
owner: App.GG.Team
statuses: App.GG.Tile.Statuses
)
}
type App.GG.Tile.Statuses {
new(
stolen: Maybe<App.GG.Tile.Status>
broken: Maybe<App.GG.Tile.Status>
)
}
App.GG.Tile.Statuses.pure: App.GG.Tile.Statuses
App.GG.Tile.Statuses.new(none, none)
type App.GG.Tile.Status {
stolen(duration: U64)
broken(duration: U64)
}
App.GG.Tile.update_creature(
update: App.GG.Creature -> App.GG.Creature,
tile: App.GG.Tile
@ -18,3 +34,94 @@ App.GG.Tile.update_creature(
let new_tile = tile@creature <- some(new_creature)
new_tile
}
App.GG.Tile.original_owner(coord: App.GG.Coord): App.GG.Team
if coord@fst <? 3 then
App.GG.Team.blue
else if coord@fst <? 6 then
App.GG.Team.red
else
App.GG.Team.neutral
App.GG.Tile.original_owner.update(coord: App.GG.Coord, tile: App.GG.Tile): App.GG.Tile
let new_team = App.GG.Tile.original_owner(coord)
tile@owner <- new_team
App.GG.Tile.Status.del_from_nat(count: Nat, tile: App.GG.Tile): App.GG.Tile
let statuses = tile@statuses
let new_statuses =
switch Nat.eql(count) {
0: statuses@stolen <- none
1: statuses@broken <- none
}default statuses
tile@statuses <- new_statuses
App.GG.Tile.Status.add(status: App.GG.Tile.Status, tile: App.GG.Tile): App.GG.Tile
let statuses = tile@statuses
let new_statuses =
case status {
stolen: statuses@stolen <- some(status)
broken: statuses@broken <- some(status)
}
tile@statuses <- new_statuses
App.GG.Tile.Status.get_from_nat(count: Nat, statuses: App.GG.Tile.Statuses): Maybe<Maybe<App.GG.Tile.Status>>
switch Nat.eql(count) {
0: some(statuses@stolen)
1: some(statuses@broken)
}default none
App.GG.Tile.Status.update_grid(coord: App.GG.Coord, grid: App.GG.Grid): App.GG.Grid
App.GG.Tile.Status.update_grid.go(0, coord, grid)
App.GG.Tile.Status.update_grid.go(count: Nat, coord: App.GG.Coord, grid: App.GG.Grid): App.GG.Grid
let new_grid =
Maybe {
get tile = App.GG.Grid.get(coord, grid)
let statuses = tile@statuses
get status = App.GG.Tile.Status.get_from_nat(count, statuses)
let new_grid =
case status {
none: grid
some:
case status.value {
stolen: App.GG.Tile.Status.update_stolen(status.value, coord, grid)
broken: App.GG.Tile.Status.update_broken(status.value, coord, grid)
}default grid
}
let new_grid = App.GG.Tile.Status.update_grid.go(count +1, coord, new_grid)
return new_grid
} <> grid
new_grid
//App.GG.Tile.Status.update(status: App.GG.Tile.Status, coord: App.GG.Coord, grid: App.GG.Grid): App.GG.Grid
App.GG.Tile.Status.update_stolen(status: App.GG.Tile.Status, coord: App.GG.Coord, grid: App.GG.Grid): App.GG.Grid
case status {
stolen:
log(U64.show(status.duration))
if status.duration =? 0 then
let new_tile = App.GG.Tile.original_owner.update(coord)
let new_grid = App.GG.Grid.update(coord, new_tile, grid)
let new_tile = App.GG.Tile.Status.del_from_nat(0)
let new_grid = App.GG.Grid.update(coord, new_tile, new_grid)
new_grid
else
let new_tile = App.GG.Tile.Status.add(App.GG.Tile.Status.stolen(status.duration - 1))
let new_grid = App.GG.Grid.update(coord, new_tile, grid)
new_grid
}default grid
App.GG.Tile.Status.update_broken(status: App.GG.Tile.Status, coord: App.GG.Coord, grid: App.GG.Grid): App.GG.Grid
case status {
stolen:
if status.duration =? 0 then
let new_tile = App.GG.Tile.Status.del_from_nat(1)
let new_grid = App.GG.Grid.update(coord, new_tile, grid)
new_grid
else
let new_tile = App.GG.Tile.Status.add(App.GG.Tile.Status.stolen(status.duration - 1))
let new_grid = App.GG.Grid.update(coord, new_tile, grid)
new_grid
}default grid
// New Status

View File

@ -29,27 +29,17 @@ App.GG.init: App.Init<App.GG.State>
App.GG.init.grid: App.GG.Grid
let blue = App.GG.Tile.new([], none, App.GG.Team.blue, App.GG.Tile.Statuses.pure)
let red = App.GG.Tile.new([], none, App.GG.Team.red, App.GG.Tile.Statuses.pure)
let list =
[
{{0#32,0#32}, App.GG.Tile.new([], none, App.GG.Team.blue)}
{{0#32,1#32}, App.GG.Tile.new([], none, App.GG.Team.blue)}
{{0#32,2#32}, App.GG.Tile.new([], none, App.GG.Team.blue)}
{{1#32,0#32}, App.GG.Tile.new([], none, App.GG.Team.blue)}
{{1#32,1#32}, App.GG.Tile.new([], none, App.GG.Team.blue)}
{{1#32,2#32}, App.GG.Tile.new([], none, App.GG.Team.blue)}
{{2#32,0#32}, App.GG.Tile.new([], none, App.GG.Team.blue)}
{{2#32,1#32}, App.GG.Tile.new([], none, App.GG.Team.blue)}
{{2#32,2#32}, App.GG.Tile.new([], none, App.GG.Team.blue)}
{{3#32,0#32}, App.GG.Tile.new([], none, App.GG.Team.red)}
{{3#32,1#32}, App.GG.Tile.new([], none, App.GG.Team.red)}
{{3#32,2#32}, App.GG.Tile.new([], none, App.GG.Team.red)}
{{4#32,0#32}, App.GG.Tile.new([], none, App.GG.Team.red)}
{{4#32,1#32}, App.GG.Tile.new([], none, App.GG.Team.red)}
{{4#32,2#32}, App.GG.Tile.new([], none, App.GG.Team.red)}
{{5#32,0#32}, App.GG.Tile.new([], none, App.GG.Team.red)}
{{5#32,1#32}, App.GG.Tile.new([], none, App.GG.Team.red)}
{{5#32,2#32}, App.GG.Tile.new([], none, App.GG.Team.red)}
{{0#32,0#32}, blue} {{1#32,0#32}, blue} {{2#32,0#32}, blue}
{{0#32,1#32}, blue} {{1#32,1#32}, blue} {{2#32,1#32}, blue}
{{0#32,2#32}, blue} {{1#32,2#32}, blue} {{2#32,2#32}, blue}
{{3#32,0#32}, red } {{4#32,0#32}, red } {{5#32,0#32}, red }
{{3#32,1#32}, red } {{4#32,1#32}, red } {{5#32,1#32}, red }
{{3#32,2#32}, red } {{4#32,2#32}, red } {{5#32,2#32}, red }
]
let grid = BBT.from_list<App.GG.Coord, App.GG.Tile>(App.GG.Grid.cmp, list)
let parts = App.GG.Body.Parts.new(0,0,0)

View File

@ -84,7 +84,7 @@ App.GG.when.setup_to_game(local: App.GG.State.local): IO<Maybe<App.State.local<A
minion: none
slime:
let data = monster.data
let hand = List.reverse!(phase.hand)
let hand = if List.is_empty!(phase.hand) then monster.hand else List.reverse!(phase.hand)
let fold = List.somes!(List.map!!((x: App.GG.Table.Slot) x@chip, phase.table@slots)) ++ monster.folder
let enrg = phase.energy
some(App.GG.Monster.slime(data, hand, fold, enrg))
@ -279,7 +279,6 @@ App.GG.when.get_energy_cost.extra(chip: App.GG.Chip, hand: App.GG.Chips): I32
some:
energy
}
// caso não tenha sua classe - verificar quantas outras tem,
App.GG.when.return_chip(local: App.GG.State.local): IO<Maybe<App.State.local<App.GG.State>>>
let new_phase = App.GG.when.return_chip.phase(local@phase)
@ -414,6 +413,7 @@ App.GG.when.update_tile(coord: App.GG.Coord, grid: App.GG.Grid): App.GG.Grid
return pair@snd
} <> new_grid
let new_grid = App.GG.Tile.Status.update_grid(coord, new_grid)
new_grid
App.GG.when.basic_attack(grid: App.GG.Grid): App.GG.Grid