Restore Kaelin

This commit is contained in:
Vitor 2021-07-15 09:20:53 -03:00
parent b468f2f1e6
commit da7cf85d3f
133 changed files with 1449 additions and 649 deletions

View File

@ -41,6 +41,9 @@ App.KL.Constants.room : String
"4b4c494e01010101"
App.KL.Constants.z_index.terrain: I32 // I32 because of the sum with coord@j
50 // allows j coordinate of terrains to go from -50 to 50
App.KL.Constants.z_index.grid: U32
100

View File

@ -8,6 +8,7 @@ type App.KL.Game.State.Local {
user: String
room: String
tab: String
info: Hexagonal.Axial
preview: App.KL.Game.Cast.Preview
mouse: Pair<U32, U32>
)
@ -17,7 +18,8 @@ App.KL.Game.State.Local.init(user: String, room: String): App.KL.Game.State.Loca
let preview = App.KL.Game.Cast.Preview.new(none, Hexagonal.Axial.Map.new!)
let mouse = {0,0}
let tab = "D"
App.KL.Game.State.Local.new(user, room, tab, preview, mouse)
let info = Hexagonal.Axial.new(0,0)
App.KL.Game.State.Local.new(user, room, tab, info, preview, mouse)
// Global State
// ============
@ -58,7 +60,11 @@ App.KL.Game.start: App.KL.Game
// ===============
App.KL.Game.draw(img: VoxBox, local: App.KL.Game.State.Local, global: App.KL.Global.State): DOM
<div>{
let style = {
"cursor": "url("|App.KL.Game.Cursor.get_img(App.KL.Game.Cursor.default)|"), auto"
}
<div style=style>{
let game = global@game
case game {
none: <div>"Not ingame."</div>

View File

@ -0,0 +1,14 @@
App.KL.Game.Areas.triangle(start: Hexagonal.Axial, direction: Hexagonal.Axial): List<Hexagonal.Axial>
let p1 = start
let p2 = Hexagonal.Axial.clamp(1, start, direction)
let left = Hexagonal.Axial.rotate_left(p2, p1)
let right = Hexagonal.Axial.rotate_right(p2, p1)
let p3 =
if Hexagonal.Axial.eql(p2, direction) then
left
else
if Hexagonal.Axial.shorter_in_xy(direction, left, right, App.KL.Constants.hexagon_radius, App.KL.Constants.center_x, App.KL.Constants.center_y) then
left
else
right
[p1, p2, p3]

View File

@ -1,7 +0,0 @@
type App.KL.Game.Asset {
new(
vbox : VoxBox
base64: String
)
}

View File

@ -34,4 +34,4 @@ App.KL.Game.Board.Boards.arena.terrains: List<Pair<Pair<I32, I32>, Nat>>
{{i, j}, field_id} & result
result
result
result

View File

@ -5,7 +5,7 @@ App.KL.Game.Board.apply_status(
let result = {game@board, game@cemetery}
for coord:tile in game@board with result:
let effect_tile = App.KL.Game.Tile.effect.get(tile)
let effect_tile_result = effect_tile(coord, coord, result@fst)
let effect_tile_result = effect_tile(coord, [coord], result@fst)
let result = case effect_tile_result {
err: result
new: {effect_tile_result.board, result@snd ++ effect_tile_result.cemetery}
@ -15,7 +15,7 @@ App.KL.Game.Board.apply_status(
let status = new_creature@status
for dots in status with result:
let effect = App.KL.Game.Creature.Status.get_effect(dots)
let effect_result = effect(coord, coord, coord, result@fst)
let effect_result = effect(coord, coord, [coord], result@fst)
case effect_result {
err: result
new: {effect_result.board, result@snd ++ effect_result.cemetery}

View File

@ -1,10 +1,7 @@
// TODO: optimize
// Returns a map with the player Address as the key to its respective coordinate
App.KL.Game.Board.find_players(board: App.KL.Game.Board): Map<Hexagonal.Axial>
let tile_list = Hexagonal.Axial.Map.to_list!(board)
let players = []
for coord_tile in tile_list with players:
let {coord,tile} = coord_tile
for coord:tile in board with players:
let creature = tile@creature
case creature {
none: players

View File

@ -1,14 +1,14 @@
type App.KL.Game.Cast {
new(
player: String
target: Hexagonal.Axial
target: List<Hexagonal.Axial>
letter: Char
)
}
type App.KL.Game.Cast.Preview {
new(
skill: Maybe<Char>
skill: Maybe<Pair<Char, Nat>>
picks: App.KL.Game.Picks
)
}

View File

@ -0,0 +1,9 @@
App.KL.Game.Cast.cancel_casts(user: String, casts: List<App.KL.Game.Cast>): List<App.KL.Game.Cast>
log("cancel_all")
let list = []
for cast in casts with list:
if String.eql(cast@player, user) then
list
else
cast & list
list

View File

@ -0,0 +1,8 @@
App.KL.Game.Cast.cancel_skill(user: String, skill_key: Char, casts: List<App.KL.Game.Cast>): List<App.KL.Game.Cast>
let list = []
for cast in casts with list:
if (user =? cast@player) && (cast@letter =? skill_key) then
list
else
cast & list
list

View File

@ -7,16 +7,35 @@ App.KL.Game.Cast.picks_of(
let casts = game@casts
for cast in casts with result:
open cast
open cast
let {seen, map} = result
if player =? cast.player then
let skill = App.KL.Game.Cast.get_skill(cast, game)
let letter = Char.to_string(cast.letter)
case skill seen{letter} {
some none:
{ seen{letter} <- unit, Hexagonal.Axial.Map.set!(cast.target, cast.letter, map) }
} default {seen, map}
case skill {
some:
let coords_max = App.KL.Game.Skill.get_pattern(skill.value)
let letter = Char.to_string(cast.letter)
for i from 0 to coords_max with result:
let target = App.KL.Game.Cast.picks_of.aux(cast.target, i, skill.value@pattern)
case target {
some: { seen{letter} <- unit, Hexagonal.Axial.Map.set!(target.value, cast.letter, result@snd)}
none: result
}
result
none: result
}
else
result
result@snd
App.KL.Game.Cast.picks_of.aux(targets: List<Hexagonal.Axial>, idx: Nat, pattern: App.KL.Game.Skill.Pattern): Maybe<Hexagonal.Axial>
case pattern {
vector:
target = targets[1]
case target {
none: targets[0]
some: target
}
}default targets[idx]

View File

@ -5,4 +5,16 @@ App.KL.Game.Cast.push(
letter: Char
casts: List<App.KL.Game.Cast>
): List<App.KL.Game.Cast>
App.KL.Game.Cast.new(player, target, letter) & casts
let pair = {[], false}
for cast in casts with pair:
let {cast, bool} =
if (cast@player =? player) && (cast@letter =? letter) then
{cast@target <- target & cast@target, true}
else
{cast, pair@snd}
{cast & pair@fst, bool}
if pair@snd then
pair@fst
else
App.KL.Game.Cast.new(player, [target], letter) & casts

View File

@ -10,7 +10,10 @@ App.KL.Game.Cast.sort(game: App.KL.Game): List<App.KL.Game.Cast>
let seen = seen{key} <- unit
case App.KL.Game.Cast.get_skill(cast, game) as got_skill {
none: {seen, casts}
some: {seen, {cast, got_skill.value@delay} & casts}
some:
pattern = App.KL.Game.Skill.get_pattern(got_skill.value)
cast = cast@target <- List.take!(pattern, cast@target)
{seen, {cast, got_skill.value@delay} & casts}
}
some: {seen, casts}
}

View File

@ -19,7 +19,6 @@ App.KL.Game.Cemetery.revive(
App.KL.Game.Board.PLayer.set(id, player, board)
board
// TODO use comprehension
App.KL.Game.Cemetery.update(
cemetery: App.KL.Game.Cemetery
): App.KL.Game.Cemetery

View File

@ -11,38 +11,20 @@ type App.KL.Game.Creature {
type App.KL.Game.Creature.Status {
burn(
id: String
duration: I32
amount: I32
)
haste(
duration : I32
amount: I32
)
poison(
id: String
duration: I32
amount: I32
)
root(
duration: I32
)
silence(
duration: I32
)
stun(
duration: I32
)
shield(
id: String
duration: I32
amount: I32
)
weaken(
duration : I32
amount: I32
)
block(id: String, duration: I32, caster: String)
//Damage Over Time
dot(id: String, duration: I32, stack: I32, amount: I32)
dampen(duration: I32, tick: I32)
haste(duration : I32, amount: I32)
//Heal Over Time
hot(id: String, duration: I32, stack: I32, amount: I32)
invulnerable(id: String, duration: I32)
root(duration: I32)
shield(id: String, duration: I32, amount: I32)
silence(duration: I32)
slow(duration: I32, amount: I32)
stun(duration: I32)
weaken(duration : I32, amount: I32)
}
@ -51,6 +33,6 @@ App.KL.Game.Creature.Status.get_effect(
): App.KL.Game.Effect.At<I32>
case status {
burn: App.KL.Game.Effect.status.burn.apply(status.id, status.duration, status.amount)
poison: App.KL.Game.Effect.status.poison.apply(status.id, status.duration, status.amount)
dot: App.KL.Game.Effect.status.dot.apply(status.id, status.duration, status.amount)
hot: App.KL.Game.Effect.status.hot.apply(status.id, status.duration, status.amount)
} default (pos)App.KL.Game.Effect { return +0#32 }

View File

@ -0,0 +1,33 @@
App.KL.Game.Creature.Status.add(
creature: App.KL.Game.Creature
status: App.KL.Game.Creature.Status
): App.KL.Game.Creature
let invulnerable = App.KL.Game.Creature.Status.invulnerable.check(creature)
let positive_effect = App.KL.Game.Creature.Status.positive(status)
if invulnerable then
if positive_effect then
case status {
haste: App.KL.Game.Creature.Status.haste.add(creature, status.duration, status.amount)
hot: App.KL.Game.Creature.Status.hot.add(creature, status.id, status.duration, status.amount)
invulnerable: App.KL.Game.Creature.Status.invulnerable.add(creature, status.id, status.duration)
shield: App.KL.Game.Creature.Status.shield.add(creature, status.id, status.duration, status.amount)
}default creature
else
creature
else
case status {
block: App.KL.Game.Creature.Status.block.add(creature, status.id, status.duration, status.caster)
dampen: creature
dot: App.KL.Game.Creature.Status.dot.add(creature, status.id, status.duration, status.amount)
haste: App.KL.Game.Creature.Status.haste.add(creature, status.duration, status.amount)
hot: App.KL.Game.Creature.Status.hot.add(creature, status.id, status.duration, status.amount)
invulnerable: App.KL.Game.Creature.Status.invulnerable.add(creature, status.id, status.duration)
root: App.KL.Game.Creature.Status.root.add(creature, status.duration)
shield: App.KL.Game.Creature.Status.shield.add(creature, status.id, status.duration, status.amount)
silence: App.KL.Game.Creature.Status.silence.add(creature, status.duration)
slow: App.KL.Game.Creature.Status.slow.add(creature, status.duration, status.amount)
stun: App.KL.Game.Creature.Status.stun.add(creature, status.duration)
weaken: App.KL.Game.Creature.Status.weaken.add(creature, status.duration, status.amount)
}

View File

@ -0,0 +1,31 @@
App.KL.Game.Creature.Status.block.add(
creature: App.KL.Game.Creature
id: String
duration: I32
caster: String
): App.KL.Game.Creature
let block_added = App.KL.Game.Creature.Status.block.add.aux(id, duration, caster, creature@status)
creature@status <- block_added
App.KL.Game.Creature.Status.block.add.aux(
id: String
duration: I32
caster: String
status: List<App.KL.Game.Creature.Status>
): List<App.KL.Game.Creature.Status>
new_block = App.KL.Game.Creature.Status.block(id, duration, caster)
case status {
nil:
new_block & status
cons:
case status.head {
block:
is_same = String.eql(id, status.head.id)
if is_same then
new_block & status.tail
else
status.head & App.KL.Game.Creature.Status.block.add.aux(id, duration, caster, status.tail)
}default status.head & App.KL.Game.Creature.Status.block.add.aux(id, duration, caster, status.tail)
}

View File

@ -0,0 +1,11 @@
App.KL.Game.Creature.Status.block.check(
creature: App.KL.Game.Creature
): List<Pair<Bool, String>> //Has_effect / Caster_ID
let status = creature@status
let result = [{false, ""}]
for block in status with result:
case block {
block: [{true, block.caster}]
}default result
result

View File

@ -0,0 +1,16 @@
App.KL.Game.Creature.Status.block.verifier(
denied: App.KL.Game.Creature // Target
hero_name: String
): Bool
denied = App.KL.Game.Creature.Status.block.check(denied)
let result = false
for target in denied with result:
let affected = target@fst // Verifies if the Target is affected by block
let skill_caster_id = target@snd
let same_id = String.eql(skill_caster_id, hero_name)
if affected && same_id then
true
else
result
result

View File

@ -1,31 +0,0 @@
App.KL.Game.Creature.Status.burn.add(
creature: App.KL.Game.Creature
id: String
duration: I32
amount: I32
): App.KL.Game.Creature
let burn_added = App.KL.Game.Creature.Status.burn.add.aux(id, duration, amount, creature@status)
creature@status <- burn_added
App.KL.Game.Creature.Status.burn.add.aux(
id: String
duration: I32
dmg: I32
status: List<App.KL.Game.Creature.Status>
): List<App.KL.Game.Creature.Status>
new_burn = App.KL.Game.Creature.Status.burn(id, duration, dmg)
case status {
nil:
new_burn & status
cons:
case status.head {
burn:
is_same = String.eql(id, status.head.id)
if is_same then
new_burn & status.tail
else
status.head & App.KL.Game.Creature.Status.burn.add.aux(id, duration, dmg, status.tail)
}default status.head & App.KL.Game.Creature.Status.burn.add.aux(id, duration, dmg, status.tail)
}

View File

@ -1,12 +0,0 @@
App.KL.Game.Creature.Status.burn.total(
creature: App.KL.Game.Creature
): I32
total_burn = +0#32
for burn in creature@status with total_burn:
case burn {
burn:
burn.amount + total_burn
}default +0#32
total_burn

View File

@ -1,12 +0,0 @@
App.KL.Game.Creature.Status.cast_impedment_show(
creature: App.KL.Game.Creature
): String
let stun = App.KL.Game.Creature.Status.stun.check(creature)
let silence = App.KL.Game.Creature.Status.silence.check(creature)
if stun && silence then
"but was stunned and silenced"
else if stun then
"but was stunned"
else
"but was silenced"

View File

@ -0,0 +1,23 @@
App.KL.Game.Creature.Status.check(
creature: App.KL.Game.Creature
status: App.KL.Game.Creature.Status
): Bool
let creature_status = creature@status
let result = false
for verify in creature_status with result:
case verify status {
block block : true
dot dot: true
dampen dampen: true
haste haste: true
hot hot: true
invulnerable invulnerable: true
root root: true
shield shield: true
silence silence: true
slow slow: true
stun stun: true
weaken weaken: true
}default result
result

View File

@ -0,0 +1,16 @@
//removes negative effects from a creature
App.KL.Game.Creature.Status.cleanse(
status: List<App.KL.Game.Creature.Status>
): List<App.KL.Game.Creature.Status>
case status {
nil:
status
cons:
case status.head {
haste: status.head & App.KL.Game.Creature.Status.cleanse(status.tail)
hot: status.head & App.KL.Game.Creature.Status.cleanse(status.tail)
invulnerable: status.head & App.KL.Game.Creature.Status.cleanse(status.tail)
shield: status.head & App.KL.Game.Creature.Status.cleanse(status.tail)
}default App.KL.Game.Creature.Status.cleanse(status.tail)
}

View File

@ -0,0 +1,37 @@
App.KL.Game.Creature.Status.dot.add(
creature: App.KL.Game.Creature
id: String
duration: I32
amount: I32
): App.KL.Game.Creature
let dot_added = App.KL.Game.Creature.Status.dot.add.aux(id, duration, amount, creature@status)
creature@status <- dot_added
App.KL.Game.Creature.Status.dot.add.aux(
id: String
duration: I32
amount: I32
status: List<App.KL.Game.Creature.Status>
): List<App.KL.Game.Creature.Status>
new_dot = App.KL.Game.Creature.Status.dot(id, duration, 1, amount)
case status {
nil:
new_dot & status
cons:
case status.head {
dot:
is_same = String.eql(id, status.head.id)
if is_same then
let dot_duration = status.head.duration + 1
let dot_stacks = status.head.stack + 1
let dot_damage = status.head.amount * 2
if I32.gtn(dot_stacks, 3) then
App.KL.Game.Creature.Status.dot("final_apply", 1, 0, status.head.amount + 2) & status.tail
else
App.KL.Game.Creature.Status.dot(status.head.id, dot_duration, dot_stacks, dot_damage) & status.tail
else
status.head & App.KL.Game.Creature.Status.dot.add.aux(id, duration, amount, status.tail)
}default status.head & App.KL.Game.Creature.Status.dot.add.aux(id, duration, amount, status.tail)
}

View File

@ -0,0 +1,12 @@
App.KL.Game.Creature.Status.dot.total(
creature: App.KL.Game.Creature
): I32
total_dot = +0#32
for status in creature@status with total_dot:
case status {
dot:
status.amount + total_dot
}default +0#32
total_dot

View File

@ -1,32 +0,0 @@
//Placeholder for Status drawing
App.KL.Game.Creature.Status.draw(
cx: U32
cy: U32
creature: App.KL.Game.Creature
img: VoxBox
): VoxBox
let list = App.KL.Game.Creature.Status.draw.aux(creature)
let list = List.show!(Function.id!, list)
VoxBox.Draw.text(list, PixelFont.small_black, Pos32.new(cx, cy, 0), img)
App.KL.Game.Creature.Status.draw.aux(
creature: App.KL.Game.Creature
): List<String>
let statuses = []
open creature
for status in creature.status with statuses:
case status {
burn: "B" & statuses
haste: "H" & statuses
poison: "P" & statuses
root: "R" & statuses
silence: "SI" & statuses
stun: "S" & statuses
shield: statuses
weaken: "W" & statuses
}
statuses

View File

@ -19,7 +19,7 @@ App.KL.Game.Creature.Status.haste.add.aux(
new_haste & status
cons:
case status.head {
root:
haste:
let old_duration = status.head.duration
let next_haste = I32.cmp(old_duration, duration)
case next_haste {

View File

@ -9,4 +9,3 @@ App.KL.Game.Creature.Status.haste.total(
haste.amount + total_haste
}default +0#32
total_haste

View File

@ -0,0 +1,38 @@
App.KL.Game.Creature.Status.hot.add(
creature: App.KL.Game.Creature
id: String
duration: I32
amount: I32
): App.KL.Game.Creature
//HOT = Heal Over Time
let hot_added = App.KL.Game.Creature.Status.hot.add.aux(id, duration, amount, creature@status)
creature@status <- hot_added
App.KL.Game.Creature.Status.hot.add.aux(
id: String
duration: I32
amount: I32
status: List<App.KL.Game.Creature.Status>
): List<App.KL.Game.Creature.Status>
new_hot = App.KL.Game.Creature.Status.hot(id, duration, 1, amount)
case status {
nil:
new_hot & status
cons:
case status.head {
hot:
is_same = String.eql(id, status.head.id)
if is_same then
let hot_duration = status.head.duration + 1
let hot_stacks = status.head.stack + 1
let hot_heal = status.head.amount * 2
if I32.gtn(hot_stacks, 3) then
App.KL.Game.Creature.Status.hot("final_apply", 1, 0, status.head.amount + 2) & status.tail
else
App.KL.Game.Creature.Status.hot(status.head.id, hot_duration, hot_stacks, hot_heal) & status.tail
else
status.head & App.KL.Game.Creature.Status.hot.add.aux(id, duration, amount, status.tail)
}default status.head & App.KL.Game.Creature.Status.hot.add.aux(id, duration, amount, status.tail)
}

View File

@ -0,0 +1,11 @@
App.KL.Game.Creature.Status.hot.check(
creature: App.KL.Game.Creature
): Bool
let status = creature@status
let result = false
for hot in status with result:
case hot {
hot: true
}default result
result

View File

@ -0,0 +1,12 @@
App.KL.Game.Creature.Status.hot.total(
creature: App.KL.Game.Creature
): I32
total_hot = +0#32
for status in creature@status with total_hot:
case status {
hot:
status.amount + total_hot
}default +0#32
total_hot

View File

@ -0,0 +1,29 @@
App.KL.Game.Creature.Status.invulnerable.add(
creature: App.KL.Game.Creature
id: String
duration: I32
): App.KL.Game.Creature
let invulnerability_added = App.KL.Game.Creature.Status.invulnerable.add.aux(id, duration, creature@status)
creature@status <- invulnerability_added
App.KL.Game.Creature.Status.invulnerable.add.aux(
id: String
duration: I32
status: List<App.KL.Game.Creature.Status>
): List<App.KL.Game.Creature.Status>
new_invulnerable = App.KL.Game.Creature.Status.invulnerable(id, duration)
case status {
nil:
new_invulnerable & status
cons:
case status.head {
invulnerable:
is_same = String.eql(id, status.head.id)
if is_same then
new_invulnerable & status.tail
else
status.head & App.KL.Game.Creature.Status.invulnerable.add.aux(id, duration, status.tail)
}default status.head & App.KL.Game.Creature.Status.invulnerable.add.aux(id, duration, status.tail)
}

View File

@ -0,0 +1,11 @@
App.KL.Game.Creature.Status.invulnerable.check(
creature: App.KL.Game.Creature
): Bool
let status = creature@status
let result = false
for invul in status with result:
case invul {
invulnerable: true
}default result
result

View File

@ -1,13 +0,0 @@
App.KL.Game.Creature.Status.movement_impairment_show(
creature: App.KL.Game.Creature
): String
let stun = App.KL.Game.Creature.Status.stun.check(creature)
let root = App.KL.Game.Creature.Status.root.check(creature)
if stun && root then
"but was stunned and rooted"
else if stun then
"but was stunned"
else
"but was rooted"

View File

@ -1,31 +0,0 @@
App.KL.Game.Creature.Status.poison.add(
creature: App.KL.Game.Creature
id: String
duration: I32
amount: I32
): App.KL.Game.Creature
let poison_added = App.KL.Game.Creature.Status.poison.add.aux(id, duration, amount, creature@status)
creature@status <- poison_added
App.KL.Game.Creature.Status.poison.add.aux(
id: String
duration: I32
dmg: I32
status: List<App.KL.Game.Creature.Status>
): List<App.KL.Game.Creature.Status>
new_poison = App.KL.Game.Creature.Status.poison(id, duration, dmg)
case status {
nil:
new_poison & status
cons:
case status.head {
poison:
is_same = String.eql(id, status.head.id)
if is_same then
new_poison & status.tail
else
status.head & App.KL.Game.Creature.Status.poison.add.aux(id, duration, dmg, status.tail)
}default status.head & App.KL.Game.Creature.Status.poison.add.aux(id, duration, dmg, status.tail)
}

View File

@ -1,14 +0,0 @@
App.KL.Game.Creature.Status.poison.total(
creature: App.KL.Game.Creature
): I32
total_poison = +0#32
for poison in creature@status with total_poison:
case poison {
poison:
poison.amount + total_poison
}default +0#32
total_poison

View File

@ -0,0 +1,11 @@
//Verifies if a status is positive or negative
App.KL.Game.Creature.Status.positive(
status: App.KL.Game.Creature.Status
): Bool
case status {
haste: true
hot: true
invulnerable: true
shield: true
}default false

View File

@ -0,0 +1,15 @@
//removes positive effects from a creature
App.KL.Game.Creature.Status.purge(
status: List<App.KL.Game.Creature.Status>
): List<App.KL.Game.Creature.Status>
case status {
nil:
status
cons:
case status.head {
haste: App.KL.Game.Creature.Status.purge(status.tail)
hot: App.KL.Game.Creature.Status.purge(status.tail)
shield: App.KL.Game.Creature.Status.purge(status.tail)
}default status.head & App.KL.Game.Creature.Status.purge(status.tail)
}

View File

@ -2,13 +2,18 @@ App.KL.Game.Creature.Status.show(
status: App.KL.Game.Creature.Status
): String
let turn = case status{}default if I32.gtn(status.duration, 1) then " turns" else " turn"
case status {
burn: "burn: "| status.id | ", duration: " | I32.show(status.duration) | ", dmg: " | I32.show(status.amount)
haste: "haste duration: " | I32.show(status.duration) | ", amount: " | I32.show(status.amount)
poison: "poison: "| status.id | ", duration: " | I32.show(status.duration) | ", dmg: " | I32.show(status.amount)
root: "root duration: " | I32.show(status.duration)
silence: "silence duration: " | I32.show(status.duration)
stun: "stun duration: " | I32.show(status.duration)
shield: "shield: "| status.id | ", duration: " | I32.show(status.duration) | ", shield ammount " | I32.show(status.amount)
weaken: "weaken duration: " | I32.show(status.duration) | ", dmg reduction: " | I32.show(status.amount)
block: "Denied for:"| String.show_clean(I32.show(status.duration))|turn| ", caster: "| status.caster
dampen: ""
dot: "Hurting for" | String.show_clean(I32.show(status.duration)) |turn| ", Damage: " | String.show_clean(I32.show(status.amount))|"."
haste: "Hasted for "| I32.show(status.duration) |turn| ", extra distance:" | String.show_clean(I32.show(status.amount))|"."
hot: "Healing for: "|String.show_clean(I32.show(status.duration)) |turn| ", heal amount:" | String.show_clean(I32.show(status.amount)) | ", stacks:" | String.show_clean(I32.show(status.stack))|"."
invulnerable: "Invulnerable for:" | String.show_clean(I32.show(status.duration)) |turn|"."
root: "Rooted for: " | String.show_clean(I32.show(status.duration))|turn| "."
silence: "Silenced for: " | String.show_clean(I32.show(status.duration))|turn|"."
stun: "Stunned for: " | String.show_clean(I32.show(status.duration))|turn|"."
slow: "Slowed for: " | String.show_clean(I32.show(status.duration))|turn | ", Slow amount: " | String.show_clean(I32.show(status.amount))
shield: "Shielded for:"| String.show_clean(I32.show(status.duration))|turn | ", Shield ammount " | String.show_clean(I32.show(status.amount))
weaken: "Weakened for:" | String.show_clean(I32.show(status.duration))|turn| ", Damage reducted by: " | String.show_clean(I32.show(status.amount))
}

View File

@ -17,7 +17,7 @@ App.KL.Game.Creature.Status.silence.add.aux(
new_silence & status
cons:
case status.head {
root:
silence:
let old_duration = status.head.duration
let next_silence = I32.cmp(old_duration, duration)
case next_silence {

View File

@ -0,0 +1,30 @@
App.KL.Game.Creature.Status.slow.add(
creature: App.KL.Game.Creature
duration: I32
amount: I32
): App.KL.Game.Creature
let slow_added = App.KL.Game.Creature.Status.slow.add.aux(duration, amount, creature@status)
creature@status <- slow_added
App.KL.Game.Creature.Status.slow.add.aux(
duration: I32
amount: I32
status: List<App.KL.Game.Creature.Status>
): List<App.KL.Game.Creature.Status>
let new_slow = App.KL.Game.Creature.Status.slow(duration, amount)
case status {
nil:
new_slow & status
cons:
case status.head {
slow:
let old_duration = status.head.duration
let next_slow = I32.cmp(old_duration, duration)
case next_slow {
gtn:
new_slow & status.tail
}default status.head & App.KL.Game.Creature.Status.slow.add.aux(duration, amount, status.tail)
}default status.head & App.KL.Game.Creature.Status.slow.add.aux(duration, amount, status.tail)
}

View File

@ -0,0 +1,11 @@
App.KL.Game.Creature.Status.slow.check(
creature: App.KL.Game.Creature
): Bool
let status = creature@status
let result = false
for slow in status with result:
case slow {
slow: true
}default result
result

View File

@ -0,0 +1,11 @@
App.KL.Game.Creature.Status.slow.total(
creature: App.KL.Game.Creature
): I32
total_slow = +0#32
for slow in creature@status with total_slow:
case slow {
slow:
slow.amount + total_slow
}default +0#32
total_slow

View File

@ -17,7 +17,7 @@ App.KL.Game.Creature.Status.stun.add.aux(
new_stun & status
cons:
case status.head {
root:
stun:
let old_duration = status.head.duration
let next_stun = I32.cmp(old_duration, duration)
case next_stun {

View File

@ -17,24 +17,34 @@ App.KL.Game.Creature.Status.update.aux(
[]
cons:
let head = case status.head {
burn : App.KL.Game.Creature.Status.burn(status.head.id, I32.sub(status.head.duration, 1), status.head.amount)
block : App.KL.Game.Creature.Status.block(status.head.id, I32.sub(status.head.duration, 1), status.head.caster)
dampen : App.KL.Game.Creature.Status.dampen(I32.sub(status.head.duration, 1), status.head.tick)
dot : App.KL.Game.Creature.Status.dot(status.head.id, I32.sub(status.head.duration, 1), status.head.stack, status.head.amount)
haste : App.KL.Game.Creature.Status.haste(I32.sub(status.head.duration, 1), status.head.amount)
poison : App.KL.Game.Creature.Status.poison(status.head.id, I32.sub(status.head.duration, 1), status.head.amount)
//heal over time(hot)
hot : App.KL.Game.Creature.Status.hot(status.head.id, I32.sub(status.head.duration, 1), status.head.stack, status.head.amount)
invulnerable: App.KL.Game.Creature.Status.invulnerable(status.head.id, I32.sub(status.head.duration ,1))
root: App.KL.Game.Creature.Status.root(I32.sub(status.head.duration, 1))
silence: App.KL.Game.Creature.Status.silence(I32.sub(status.head.duration, 1))
stun: App.KL.Game.Creature.Status.stun(I32.sub(status.head.duration, 1))
shield: App.KL.Game.Creature.Status.shield(status.head.id, I32.sub(status.head.duration, 1), status.head.amount)
silence: App.KL.Game.Creature.Status.silence(I32.sub(status.head.duration, 1))
slow : App.KL.Game.Creature.Status.slow(I32.sub(status.head.duration, 1), status.head.amount)
stun: App.KL.Game.Creature.Status.stun(I32.sub(status.head.duration, 1))
weaken : App.KL.Game.Creature.Status.weaken(I32.sub(status.head.duration, 1), status.head.amount)
}
let tail = App.KL.Game.Creature.Status.update.aux(status.tail)
case head {
burn : if I32.gtn(head.duration,0) then head & tail else tail
block : if I32.gtn(head.duration,0) then head & tail else tail
dampen : if I32.gtn(head.duration,0) then head & tail else tail
dot : if I32.gtn(head.duration,0) then head & tail else tail
haste : if I32.gtn(head.duration,0) then head & tail else tail
poison : if I32.gtn(head.duration,0) then head & tail else tail
//heal over time(hot)
hot : if I32.gtn(head.duration,0) then head & tail else tail
invulnerable : if I32.gtn(head.duration,0) then head & tail else tail
root : if I32.gtn(head.duration,0) then head & tail else tail
silence: if I32.gtn(head.duration,0) then head & tail else tail
stun: if I32.gtn(head.duration,0) then head & tail else tail
shield: if I32.gtn(head.duration,0) then head & tail else tail
silence: if I32.gtn(head.duration,0) then head & tail else tail
slow: if I32.gtn(head.duration,0) then head & tail else tail
stun: if I32.gtn(head.duration,0) then head & tail else tail
weaken : if I32.gtn(head.duration,0) then head & tail else tail
}
}

View File

@ -19,7 +19,7 @@ App.KL.Game.Creature.Status.weaken.add.aux(
new_weaken & status
cons:
case status.head {
root:
weaken:
let old_duration = status.head.duration
let next_weaken = I32.cmp(old_duration, duration)
case next_weaken {

View File

@ -6,5 +6,7 @@ App.KL.Game.Creature.create(
let hero = App.KL.Game.Hero.get_by_id(U8.to_nat(hero_id))
case hero {
none: none
some: some(App.KL.Game.Creature.new(player_addr, hero.value, team, [], hero.value@max_hp, hero.value@max_ap - 1))
}
some:
let new_creature = App.KL.Game.Creature.new(player_addr, hero.value, team, [], hero.value@max_hp, hero.value@max_ap - 1)
some(App.KL.Game.Creature.Status.invulnerable.add(new_creature, "begin_game", 1))
}

View File

@ -0,0 +1,8 @@
type App.KL.Game.Cursor {
default
attack
heal
move
// pointer
}

View File

@ -0,0 +1,2 @@
App.KL.Game.Cursor.Assets.attack: String
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAx0lEQVR42u3ZwQnCQBBAURuwBiuwEkuxSXuwDC9eRSQeNAeHbDaCIJl5D+bkKR9n3eBmuzsMc7PJToD3g94f18lJH0KAEOB2+pz0IQToBEgfonwAIQSYD3E5DpNT5ptQLsC3IcbViCFWf7UuH2BpiPP+NTFEPDwFWPtZER9sfPA48XMBsgTohWitRtp7QtkArRBLfx4FyLoC8dBLG0KAzkWntRpp7wNlA/ReclqrkubdoGyAX6+MAFWU/fNVAAAAAAAAAADg357OpqZ5IQsZlgAAAABJRU5ErkJggg=="

View File

@ -0,0 +1,2 @@
App.KL.Game.Cursor.Assets.default: String
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAy0lEQVR42u3YsQnCUBCA4SzgDE7gJI7iVG7iDo5hY2MhIgkkuebwoWCVe98HV2nzfnKJZtjtj+OnGXohwHrg1/s+z+M8ztNNEAHWA8bBI0TM87JM2SDdB/i2CjlIa0U2H0aA9QBxyceBr4dxnttpmfx5a1UEqLIKcfAIEROrkIOUuRK6D5APmAPk1Yjv55ukANUei7+GEKBagFiF1k2x/C/DbgPkx1xc4hGi/J+jbgO0QsSUudkJ8OfLUwF6e4sMAAAAAAAAAAAAbMYEBJ27tshb6RwAAAAASUVORK5CYII="

View File

@ -0,0 +1,2 @@
App.KL.Game.Cursor.Assets.heal: String
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAyklEQVR42u3ZvQ3CMBCA0SzADEzAJIzCkuzAGDRpEUJBQriIJWNcRIrP70lXUd2HHfEzTZnD8by0zBSNAN/Fnq/55wgQJUDpaKdFb6dlNXmA7q+EAJUjXwoQ5koIUDnytRFAAAE8BAWIEGCrD0K7DzN8gK2+DKXXH9f5M92EEKDxB5F8sXzxdHW6CTF8gNZQpcW6vQICNC5+vyyrKYUI+84PFyBfrLR4eMMHqB3x8H+gCPBnmPRBaNhnxLABXAUBAAAAAAAAAICdeAP34Y89QaelHQAAAABJRU5ErkJggg=="

View File

@ -0,0 +1,2 @@
App.KL.Game.Cursor.Assets.move: String
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAA2ElEQVR42u2ZsQ3CQAxFbwFmYIJMwigsyQ6MkSYtQihIgAuss0xDYf/3JFfRFf8pvjh3YyQcjqd9VkMFWQEW9P7YptVehKwAH/y67F91u2yvaisCAYkAq/X8rnYiEPAJYkEzEb41yotAgBt4vAh79dtujrICosHHAkbPLbgXUk6ErIDssxeJ+HUdAqoLyAJFrVG29+UFRJtaNvqWPTCRFxCJiAYemd9gOQEciCBgLsICt5n5EfCnURkBqhcl8ldl8pelQw15AQAAAAAAAAAAAAAAAAAAAFCOJ89PQ8x5ds2JAAAAAElFTkSuQmCC"

View File

@ -0,0 +1,6 @@
App.KL.Game.Cursor.get_img(cursor: App.KL.Game.Cursor): String // Base64 img
case cursor {
attack: App.KL.Game.Cursor.Assets.attack
heal : App.KL.Game.Cursor.Assets.heal
move : App.KL.Game.Cursor.Assets.move
} default App.KL.Game.Cursor.Assets.default // while we have only one

View File

@ -1,5 +1,5 @@
App.KL.Game.Effect(A: Type): Type
((center: Hexagonal.Axial) ->
(target: Hexagonal.Axial) ->
(targets: List<Hexagonal.Axial>) ->
(board: App.KL.Game.Board) ->
App.KL.Game.Effect.Result(A))

View File

@ -2,5 +2,5 @@ App.KL.Game.Effect.ap.add(
ap_used: I32
): App.KL.Game.Effect<Unit>
(center, target, board)
(center, targets, board)
App.KL.Game.Effect.Result.new!(unit, center, board, Hexagonal.Axial.Map.new!, ap_used, [], "")

View File

@ -4,10 +4,10 @@ App.KL.Game.Effect.bind<A: Type, B: Type>(
): App.KL.Game.Effect<B>
//TODO: Verify problem with error result A and B
(center, target, board)
case effect(center, target, board) as result_a {
(center, targets, board)
case effect(center, targets, board) as result_a {
err: App.KL.Game.Effect.Result.err<B>(result_a.message)
new: case next(result_a.value)(result_a.center, target, result_a.board) as result_b {
new: case next(result_a.value)(result_a.center, targets, result_a.board) as result_b {
err: App.KL.Game.Effect.Result.err<B>(result_b.message)
new:
center = result_b.center

View File

@ -1,4 +1,4 @@
App.KL.Game.Effect.board.get: App.KL.Game.Effect<App.KL.Game.Board>
(center, target, board)
(center, targets, board)
App.KL.Game.Effect.Result.new!(board, center, board, Hexagonal.Axial.Map.new!, 0, [], "")

View File

@ -2,5 +2,5 @@ App.KL.Game.Effect.board.set(
new_board: App.KL.Game.Board
): App.KL.Game.Effect<Unit>
(center, target, board)
(center, targets, board)
App.KL.Game.Effect.Result.new!(unit, center, new_board, Hexagonal.Axial.Map.new!, 0, [], "")

View File

@ -1,8 +1,18 @@
//Changed, not sure if i could, but i did hehe
App.KL.Game.Effect.board.summon(
coord: Hexagonal.Axial
creature: App.KL.Game.Creature
): App.KL.Game.Effect<Unit>
(center, target, board)
): App.KL.Game.Effect.At<Unit>
//(center, targets, board)
(pos)
let board = App.KL.Game.Board.push(coord, App.KL.Game.Entity.creature(creature), board)
App.KL.Game.Effect.Result.new!(unit, center, board, Hexagonal.Axial.Map.new!, 0, [], "Summon a creature on the map")
App.KL.Game.Effect {
get board = App.KL.Game.Effect.board.get
get center = App.KL.Game.Effect.coord.get_center
let summoned_board = App.KL.Game.Board.push(pos, App.KL.Game.Entity.creature(creature), board)
if App.KL.Game.Board.is_occupied(pos, board) then
App.KL.Game.Effect.pass
else
App.KL.Game.Effect.board.set(summoned_board)
//App.KL.Game.Effect.Result.new!(unit, center, board, Hexagonal.Axial.Map.new!, 0, [])
}

View File

@ -1,3 +1,3 @@
App.KL.Game.Effect.cancel<A: Type>: App.KL.Game.Effect<A>
(center, target, board)
(center, targets, board)
App.KL.Game.Effect.Result.err<A>

View File

@ -1,6 +1,6 @@
App.KL.Game.Effect.cemetery.add(
player_id: String
): App.KL.Game.Effect<Unit>
(center, target, board)
(center, targets, board)
App.KL.Game.Effect.Result.new!(unit, center, board, Hexagonal.Axial.Map.new!, 0, [{player_id, App.KL.Constants.turns_dead }], "")

View File

@ -1,3 +1,3 @@
App.KL.Game.Effect.coord.get_center: App.KL.Game.Effect<Hexagonal.Axial>
(center, target, map)
(center, targets, map)
App.KL.Game.Effect.Result.new!(center, center, map, Hexagonal.Axial.Map.new!, 0, [], "")

View File

@ -1,3 +1,5 @@
App.KL.Game.Effect.coord.get_target: App.KL.Game.Effect<Hexagonal.Axial>
(center, target, map)
(center, targets, map)
let target = List.head!(targets) <> center
App.KL.Game.Effect.Result.new!(target, center, map, Hexagonal.Axial.Map.new!, 0, [], "")

View File

@ -0,0 +1,3 @@
App.KL.Game.Effect.coord.get_targets: App.KL.Game.Effect<List<Hexagonal.Axial>>
(center, targets, map)
App.KL.Game.Effect.Result.new!(targets, center, map, Hexagonal.Axial.Map.new!, 0, [], "")

View File

@ -0,0 +1,10 @@
App.KL.Game.Effect.coord.get_vector: App.KL.Game.Effect<Pair<Hexagonal.Axial, Maybe<Hexagonal.Axial>>>
(center, targets, map)
let vector =
case targets[1] as direction {
none: {targets[0] <> center, none}
some: {direction.value, targets[0]}
}
App.KL.Game.Effect.Result.new!(vector, center, map, Hexagonal.Axial.Map.new!, 0, [], "")

View File

@ -2,5 +2,5 @@ App.KL.Game.Effect.coord.set_center(
new_center: Hexagonal.Axial
): App.KL.Game.Effect<Unit>
(center, target, map)
(center, targets, map)
App.KL.Game.Effect.Result.new!(unit, new_center, map, Hexagonal.Axial.Map.new!, 0, [], "")

View File

@ -4,18 +4,44 @@ App.KL.Game.Effect.hp.damage_at(
(pos)
App.KL.Game.Effect {
get center = App.KL.Game.Effect.coord.get_center
get creature = App.KL.Game.Effect.board.creature.get(center)
get creature = App.KL.Game.Effect.board.creature.get(pos)
//Verifies if a creature is set to be denied
get block = App.KL.Game.Effect {
get caster = App.KL.Game.Effect.board.creature.caster
case creature {
none:
App.KL.Game.Effect { return false }
some:
let hero_name = creature.value@hero
let hero_name = hero_name@name
case caster {
none:
App.KL.Game.Effect { return false }
some:
App.KL.Game.Effect { return App.KL.Game.Creature.Status.block.verifier(caster.value, hero_name) }
}
}
}
case creature {
none:
App.KL.Game.Effect { return +0#32 }
some:
App.KL.Game.Effect {
let debuffer = App.KL.Game.Creature.Status.weaken.total(creature.value)
get real_dmg = App.KL.Game.Effect.hp.change_at(I32.neg(dmg - debuffer), pos)
let damage = String.show_clean(I32.show(I32.neg(real_dmg)))
App.KL.Game.Effect.description.add("Deal "| damage | " damage")
return real_dmg
}
let invul = App.KL.Game.Creature.Status.invulnerable.check(creature.value)
if invul then
App.KL.Game.Effect { return +0#32 }
else
App.KL.Game.Effect {
if block then
App.KL.Game.Effect { return +0#32 }
else
App.KL.Game.Effect {
let debuffer = App.KL.Game.Creature.Status.weaken.total(creature.value)
get real_dmg = App.KL.Game.Effect.hp.change_at(I32.neg(dmg - debuffer), pos)
let damage = String.show_clean(I32.show(I32.neg(real_dmg)))
App.KL.Game.Effect.description.add("Deal "| damage | " damage")
return real_dmg
}
}
}
}

View File

@ -2,5 +2,5 @@ App.KL.Game.Effect.indicators.add(
indicators: Hexagonal.Axial.Map(App.KL.Game.Indicator)
): App.KL.Game.Effect<Unit>
(center, target, board)
(center, targets, board)
App.KL.Game.Effect.Result.new!(unit, center, board, indicators, 0, [], "")

View File

@ -2,7 +2,7 @@
App.KL.Game.Effect.indicators.get_indicators(
hero_pos: Hexagonal.Axial
skill: App.KL.Game.Skill
mouse_coord: Hexagonal.Axial
mouse_coord: List<Hexagonal.Axial>
map: App.KL.Game.Board
): Hexagonal.Axial.Map<App.KL.Game.Indicator>

View File

@ -2,7 +2,8 @@ App.KL.Game.Effect.indicators.remove<A: Type>
(eff: App.KL.Game.Effect<A>
): App.KL.Game.Effect<A>
(center, target, board)
case eff(center, target, board) as result {
(center, targets, board)
case eff(center, targets, board) as result {
new: App.KL.Game.Effect.Result.new<A>(result.value, result.center, result.board, Hexagonal.Axial.Map.new!, 0, [], "")
err: App.KL.Game.Effect.Result.err<A>(result.message)
}

View File

@ -1,6 +1,10 @@
App.KL.Game.Effect.limit_range(range: I32): App.KL.Game.Effect<Unit>
(center, target, board)
if I32.gtn(Hexagonal.Axial.distance(center, target), range) then
App.KL.Game.Effect.Result.err<Unit>("out of range.")
(center, targets, board)
in_range = true
for target in targets with in_range:
in_range && I32.lte(Hexagonal.Axial.distance(center, target), range)
if in_range then
App.KL.Game.Effect.Result.new<Unit>(unit, center, board, Hexagonal.Axial.Map.new!, 0, [] "")
else
App.KL.Game.Effect.Result.new<Unit>(unit, center, board, Hexagonal.Axial.Map.new!, 0, [], "")
App.KL.Game.Effect.Result.err<Unit>("out of range.")

View File

@ -0,0 +1,8 @@
App.KL.Game.Effect.limit_range_vector(range: I32): App.KL.Game.Effect<Unit>
(center, targets, board)
direction = targets[0] <> center
start = targets[1] <> direction
if I32.gtn(Hexagonal.Axial.distance(center, start), range) then
App.KL.Game.Effect.Result.err<Unit>("out of range.")
else
App.KL.Game.Effect.Result.new<Unit>(unit, center, board, Hexagonal.Axial.Map.new!, 0, [], "")

View File

@ -5,10 +5,17 @@ App.KL.Game.Effect.movement.pull_at(
App.KL.Game.Effect {
get center = App.KL.Game.Effect.coord.get_center
get creature = App.KL.Game.Effect.board.creature.get(target)
without creature: App.KL.Game.Effect.pass
let distance = Hexagonal.Axial.distance(center, target)
let x = 1.0 / I32.to_f64(distance)
let goal = Hexagonal.Axial.lerp(x, center, target)
App.KL.Game.Effect.movement.move_to(target, goal, ignore)
return unit
let invul = App.KL.Game.Creature.Status.invulnerable.check(creature)
if invul && not(ignore) then
App.KL.Game.Effect.pass
else
App.KL.Game.Effect {
App.KL.Game.Effect.movement.move_to(target, goal, ignore)
return unit
}
}

View File

@ -5,10 +5,17 @@ App.KL.Game.Effect.movement.push_at(
App.KL.Game.Effect {
get center = App.KL.Game.Effect.coord.get_center
get creature = App.KL.Game.Effect.board.creature.get(target)
without creature: App.KL.Game.Effect.pass
let distance = Hexagonal.Axial.distance(center, target)
let x = 1.0 / I32.to_f64(distance)
let goal = Hexagonal.Axial.lerp(x, target, center)
App.KL.Game.Effect.movement.move_to(target, goal, ignore)
return unit
let invul = App.KL.Game.Creature.Status.invulnerable.check(creature)
if invul && not(ignore) then
App.KL.Game.Effect.pass
else
App.KL.Game.Effect {
App.KL.Game.Effect.movement.move_to(target, goal, ignore)
return unit
}
}

View File

@ -1,3 +1,3 @@
App.KL.Game.Effect.pure<A: Type>(value: A): App.KL.Game.Effect<A>
(center, target, board)
(center, targets, board)
App.KL.Game.Effect.Result.new<A>(value, center, board, Hexagonal.Axial.Map.new!, 0, [], "")

View File

@ -4,7 +4,7 @@ App.KL.Game.Effect.run<A: Type>(
target: Hexagonal.Axial
game: App.KL.Game
): App.KL.Game
case effect(center, target, game@board) as result {
case effect(center, targets, game@board) as result {
err: game
new: game@board <- result.board
}

View File

@ -0,0 +1,18 @@
App.KL.Game.Effect.status.add(
creature: App.KL.Game.Creature
status: App.KL.Game.Creature.Status
): App.KL.Game.Effect.At<Unit>
(pos)
App.KL.Game.Effect {
get board = App.KL.Game.Effect.board.get
get creature = App.KL.Game.Effect.board.creature.get(pos)
without creature: App.KL.Game.Effect { return unit }
let status_add = App.KL.Game.Creature.Status.add(creature, status)
let new_board = App.KL.Game.Board.Creature.set(pos, status_add, board)
App.KL.Game.Effect {
//Adds the description for the effect
App.KL.Game.Effect.status.description(status)
App.KL.Game.Effect.board.set(new_board)
}
}

View File

@ -0,0 +1,19 @@
App.KL.Game.Effect.status.block.add(
id: String
duration: I32
): App.KL.Game.Effect.At<I32>
(pos)
App.KL.Game.Effect {
get creature = App.KL.Game.Effect.board.creature.get(pos)
get caster = App.KL.Game.Effect.board.creature.caster
without caster: App.KL.Game.Effect { return +0#32 }
without creature: App.KL.Game.Effect { return +0#32 }
let hero_name = caster@hero
let hero_name = hero_name@name
let block = App.KL.Game.Creature.Status.block(id, duration, hero_name)
App.KL.Game.Effect {
App.KL.Game.Effect.status.add(creature, block, pos)
return duration
}
}

View File

@ -1,22 +0,0 @@
App.KL.Game.Effect.status.burn.add(
id: String
duration: I32
amount: I32
): App.KL.Game.Effect.At<I32>
(pos)
App.KL.Game.Effect {
get board = App.KL.Game.Effect.board.get
let duration_show = String.show_clean(I32.show(duration))
let amount_show = String.show_clean(I32.show(amount))
let turn = if I32.gtn(duration, 1) then " turns " else " turn "
App.KL.Game.Effect.description.add("Burn a creature for"|duration_show|turn| "dealing"|amount_show|" damage")
get creature = App.KL.Game.Effect.board.creature.get(pos)
without creature: App.KL.Game.Effect { return +0#32 }
let burn = App.KL.Game.Creature.Status.burn.add(creature, id, duration, amount)
let new_board = App.KL.Game.Board.Creature.set(pos, burn, board)
App.KL.Game.Effect {
App.KL.Game.Effect.board.set(new_board)
return amount
}
}

View File

@ -0,0 +1,33 @@
App.KL.Game.Effect.status.description(
status: App.KL.Game.Creature.Status
): App.KL.Game.Effect<Unit>
let duration_show = case status{block: String.show_clean(I32.show(status.duration))}default String.show_clean(I32.show(status.duration))
let turn = case status {block: if I32.gtn(status.duration, 1) then " turns " else " turn "
}default if I32.gtn(status.duration, 1) then " turns " else " turn "
let amount_show = case status {
block: ""
dampen:""
invulnerable:""
root: ""
silence:""
stun:""
}default String.show_clean(I32.show(status.amount))
let distance = case status { haste: if I32.gtn(status.amount, 1) then " tiles " else " tile " }default ""
case status {
block: App.KL.Game.Effect.description.add("Denies a creature from dealing damage for"|duration_show|turn)
dampen: App.KL.Game.Effect { return unit } //TODO
dot: App.KL.Game.Effect.description.add("Adds a damage over time effect for"|duration_show|turn| "dealing"|amount_show|" damage")
haste: App.KL.Game.Effect.description.add("Set Haste in a creature for"|duration_show| turn | "increasing movement distance by"|amount_show|distance)
hot: App.KL.Game.Effect.description.add("Add a heal over time status for"|duration_show|turn| " healing for"|amount_show)
invulnerable: App.KL.Game.Effect.description.add("Makes a creature invulnerable for"|duration_show|turn| " protecting it from any negative effects")
root: App.KL.Game.Effect.description.add("Root a creature for"|duration_show|turn)
shield: App.KL.Game.Effect.description.add("Give Shield to a creature for"|duration_show|turn| " protecting it from taking "|amount_show|" damage")
silence: App.KL.Game.Effect.description.add("Silence a creature for"|duration_show|turn)
slow: App.KL.Game.Effect { return unit } // TODO
stun: App.KL.Game.Effect.description.add("Stun a creature for"|duration_show|turn)
weaken: App.KL.Game.Effect.description.add("Weaken a creature for"|duration_show| turn | " reducing the damage it deals by"|amount_show)
}

View File

@ -0,0 +1,16 @@
App.KL.Game.Effect.status.dot.add(
id: String
duration: I32
amount: I32
): App.KL.Game.Effect.At<I32>
(pos)
App.KL.Game.Effect {
get creature = App.KL.Game.Effect.board.creature.get(pos)
without creature: App.KL.Game.Effect { return +0#32 }
let dot = App.KL.Game.Creature.Status.dot(id, duration, 0, amount)
App.KL.Game.Effect {
App.KL.Game.Effect.status.add(creature, dot, pos)
return amount
}
}

View File

@ -1,4 +1,4 @@
App.KL.Game.Effect.status.burn.apply(
App.KL.Game.Effect.status.dot.apply(
id: String
duration: I32
amount: I32

View File

@ -5,10 +5,11 @@ App.KL.Game.Effect.status.haste.add(
(pos)
App.KL.Game.Effect {
let duration_show = String.show_clean(I32.show(duration))
let amount_show = String.show_clean(I32.show(amount))
let turn = if I32.gtn(duration, 1) then " turns " else " turn "
let distance = if I32.gtn(amount, 1) then " tiles " else " tile "
App.KL.Game.Effect.description.add("Set Haste in a creature for"|duration_show| turn | "increasing movement distance by"|amount_show|distance)
App.KL.Game.Effect.status.haste.change_at(duration, amount, pos)
get creature = App.KL.Game.Effect.board.creature.get(pos)
without creature: App.KL.Game.Effect { return +0#32 }
let haste = App.KL.Game.Creature.Status.haste(duration, amount)
App.KL.Game.Effect {
App.KL.Game.Effect.status.add(creature, haste, pos)
return amount
}
}

View File

@ -1,17 +0,0 @@
App.KL.Game.Effect.status.haste.change_at(
duration: I32
amount: I32
): App.KL.Game.Effect.At<I32>
(pos)
App.KL.Game.Effect {
get board = App.KL.Game.Effect.board.get
get creature = App.KL.Game.Effect.board.creature.get(pos)
without creature: App.KL.Game.Effect { return +0#32 }
let haste = App.KL.Game.Creature.Status.haste.add(creature, duration, amount)
let new_board = App.KL.Game.Board.Creature.set(pos, haste, board)
App.KL.Game.Effect {
App.KL.Game.Effect.board.set(new_board)
return amount
}
}

View File

@ -0,0 +1,17 @@
App.KL.Game.Effect.status.hot.add(
id: String
duration: I32
amount: I32
): App.KL.Game.Effect.At<I32>
(pos)
App.KL.Game.Effect {
get creature = App.KL.Game.Effect.board.creature.get(pos)
without creature: App.KL.Game.Effect { return +0#32 }
let hot = App.KL.Game.Creature.Status.hot(id, duration, 0, amount)
let total_hot = App.KL.Game.Creature.Status.hot.total(creature)
App.KL.Game.Effect {
App.KL.Game.Effect.status.add(creature, hot, pos)
return total_hot
}
}

View File

@ -1,4 +1,4 @@
App.KL.Game.Effect.status.poison.apply(
App.KL.Game.Effect.status.hot.apply(
id: String
duration: I32
amount: I32
@ -6,6 +6,6 @@ App.KL.Game.Effect.status.poison.apply(
(pos)
if duration >? 0 then
App.KL.Game.Effect.hp.damage_at(amount, pos)
App.KL.Game.Effect.hp.heal_at(amount, pos)
else
App.KL.Game.Effect {return +0#32}

View File

@ -0,0 +1,15 @@
App.KL.Game.Effect.status.invulnerable.add(
id: String
duration: I32
): App.KL.Game.Effect.At<I32>
(pos)
App.KL.Game.Effect {
get creature = App.KL.Game.Effect.board.creature.get(pos)
without creature: App.KL.Game.Effect { return +0#32 }
let invul = App.KL.Game.Creature.Status.invulnerable(id, duration)
App.KL.Game.Effect {
App.KL.Game.Effect.status.add(creature, invul, pos)
return duration
}
}

View File

@ -1,22 +0,0 @@
App.KL.Game.Effect.status.poison.add(
id: String
duration: I32
amount: I32
): App.KL.Game.Effect.At<I32>
(pos)
App.KL.Game.Effect {
get board = App.KL.Game.Effect.board.get
get creature = App.KL.Game.Effect.board.creature.get(pos)
let duration_show = String.show_clean(I32.show(duration))
let amount_show = String.show_clean(I32.show(amount))
let turn = if I32.gtn(duration, 1) then " turns " else " turn "
App.KL.Game.Effect.description.add("Set Poison to a creature for"|duration_show|turn| "dealing "|amount_show|" damage")
without creature: App.KL.Game.Effect { return +0#32 }
let poison = App.KL.Game.Creature.Status.poison.add(creature, id, duration, amount)
let new_board = App.KL.Game.Board.Creature.set(pos, poison, board)
App.KL.Game.Effect {
App.KL.Game.Effect.board.set(new_board)
return amount
}
}

View File

@ -4,8 +4,11 @@ App.KL.Game.Effect.status.root.add(
(pos)
App.KL.Game.Effect {
let duration_show = String.show_clean(I32.show(duration))
let turn = if I32.gtn(duration, 1) then " turns" else " turn"
App.KL.Game.Effect.description.add("Root a creature for"|duration_show|turn)
App.KL.Game.Effect.status.root.change_at(duration, pos)
get creature = App.KL.Game.Effect.board.creature.get(pos)
without creature: App.KL.Game.Effect { return +0#32 }
let root = App.KL.Game.Creature.Status.root(duration)
App.KL.Game.Effect {
App.KL.Game.Effect.status.add(creature, root, pos)
return duration
}
}

View File

@ -1,16 +0,0 @@
App.KL.Game.Effect.status.root.change_at(
duration: I32
): App.KL.Game.Effect.At<I32>
(pos)
App.KL.Game.Effect {
get board = App.KL.Game.Effect.board.get
get creature = App.KL.Game.Effect.board.creature.get(pos)
without creature: App.KL.Game.Effect { return +0#32 }
let root = App.KL.Game.Creature.Status.root.add(creature, duration)
let new_board = App.KL.Game.Board.Creature.set(pos, root, board)
App.KL.Game.Effect {
App.KL.Game.Effect.board.set(new_board)
return duration
}
}

View File

@ -6,9 +6,12 @@ App.KL.Game.Effect.status.shield.add(
(pos)
App.KL.Game.Effect {
let duration_show = String.show_clean(I32.show(duration))
let amount_show = String.show_clean(I32.show(amount))
let turn = if I32.gtn(duration, 1) then " turns" else " turn"
App.KL.Game.Effect.description.add("Give Shield to a creature for"|duration_show|turn| " protecting it from taking "|amount_show|" damage")
App.KL.Game.Effect.status.shield.change_at(id, duration, amount, pos)
get creature = App.KL.Game.Effect.board.creature.get(pos)
without creature: App.KL.Game.Effect { return +0#32 }
let shield = App.KL.Game.Creature.Status.shield(id, duration, amount)
let total_shield = App.KL.Game.Creature.Status.shield.total(creature)
App.KL.Game.Effect {
App.KL.Game.Effect.status.add(creature, shield, pos)
return total_shield
}
}

View File

@ -1,19 +0,0 @@
App.KL.Game.Effect.status.shield.change_at(
id: String
duration: I32
amount: I32
): App.KL.Game.Effect.At<I32>
(pos)
App.KL.Game.Effect {
get board = App.KL.Game.Effect.board.get
get creature = App.KL.Game.Effect.board.creature.get(pos)
without creature: App.KL.Game.Effect { return +0#32 }
let shield = App.KL.Game.Creature.Status.shield.add(creature, id, duration, amount)
let new_board = App.KL.Game.Board.Creature.set(pos, shield, board)
let total_shield = App.KL.Game.Creature.Status.shield.total(shield)
App.KL.Game.Effect {
App.KL.Game.Effect.board.set(new_board)
return total_shield
}
}

View File

@ -4,8 +4,11 @@ App.KL.Game.Effect.status.silence.add(
(pos)
App.KL.Game.Effect {
let duration_show = String.show_clean(I32.show(duration))
let turn = if I32.gtn(duration, 1) then " turns" else " turn"
App.KL.Game.Effect.description.add("Silence a creature for"|duration_show|turn)
App.KL.Game.Effect.status.silence.change_at(duration, pos)
get creature = App.KL.Game.Effect.board.creature.get(pos)
without creature: App.KL.Game.Effect { return +0#32 }
let silence = App.KL.Game.Creature.Status.silence(duration)
App.KL.Game.Effect {
App.KL.Game.Effect.status.add(creature, silence, pos)
return duration
}
}

View File

@ -1,16 +0,0 @@
App.KL.Game.Effect.status.silence.change_at(
duration: I32
): App.KL.Game.Effect.At<I32>
(pos)
App.KL.Game.Effect {
get board = App.KL.Game.Effect.board.get
get creature = App.KL.Game.Effect.board.creature.get(pos)
without creature: App.KL.Game.Effect { return +0#32 }
let silence = App.KL.Game.Creature.Status.silence.add(creature, duration)
let new_board = App.KL.Game.Board.Creature.set(pos, silence, board)
App.KL.Game.Effect {
App.KL.Game.Effect.board.set(new_board)
return duration
}
}

View File

@ -4,8 +4,11 @@ App.KL.Game.Effect.status.stun.add(
(pos)
App.KL.Game.Effect {
let duration_show = String.show_clean(I32.show(duration))
let turn = if I32.gtn(duration, 1) then " turns" else " turn"
App.KL.Game.Effect.description.add("Stun a creature for"|duration_show|turn)
App.KL.Game.Effect.status.stun.change_at(duration, pos)
get creature = App.KL.Game.Effect.board.creature.get(pos)
without creature: App.KL.Game.Effect { return +0#32 }
let stun = App.KL.Game.Creature.Status.stun(duration)
App.KL.Game.Effect {
App.KL.Game.Effect.status.add(creature, stun, pos)
return duration
}
}

View File

@ -1,16 +0,0 @@
App.KL.Game.Effect.status.stun.change_at(
duration: I32
): App.KL.Game.Effect.At<I32>
(pos)
App.KL.Game.Effect {
get board = App.KL.Game.Effect.board.get
get creature = App.KL.Game.Effect.board.creature.get(pos)
without creature: App.KL.Game.Effect { return +0#32 }
let stun = App.KL.Game.Creature.Status.stun.add(creature, duration)
let new_board = App.KL.Game.Board.Creature.set(pos, stun, board)
App.KL.Game.Effect {
App.KL.Game.Effect.board.set(new_board)
return duration
}
}

View File

@ -5,9 +5,12 @@ App.KL.Game.Effect.status.weaken.add(
(pos)
App.KL.Game.Effect {
let duration_show = String.show_clean(I32.show(duration))
let amount_show = String.show_clean(I32.show(amount))
let turn = if I32.gtn(duration, 1) then " turns" else " turn"
App.KL.Game.Effect.description.add("Weaken a creature for"|duration_show| turn | " reducing the damage it deals by"|amount_show)
App.KL.Game.Effect.status.weaken.change_at(duration, amount, pos)
get creature = App.KL.Game.Effect.board.creature.get(pos)
without creature: App.KL.Game.Effect { return +0#32 }
let weaken = App.KL.Game.Creature.Status.weaken(duration, amount)
App.KL.Game.Effect {
App.KL.Game.Effect.status.add(creature, weaken, pos)
return amount
}
}

View File

@ -1,17 +0,0 @@
App.KL.Game.Effect.status.weaken.change_at(
duration: I32
amount: I32
): App.KL.Game.Effect.At<I32>
(pos)
App.KL.Game.Effect {
get board = App.KL.Game.Effect.board.get
get creature = App.KL.Game.Effect.board.creature.get(pos)
without creature: App.KL.Game.Effect { return +0#32 }
let weaken = App.KL.Game.Creature.Status.weaken.add(creature, duration, amount)
let new_board = App.KL.Game.Board.Creature.set(pos, weaken, board)
App.KL.Game.Effect {
App.KL.Game.Effect.board.set(new_board)
return amount
}
}

View File

@ -3,6 +3,7 @@ type App.KL.Game.Hero {
name: String
draw: App.KL.Game.Hero.Draw.Pose -> App.KL.Game.Hero.Draw.Result
picture: Bool -> U64 -> String // rename to portrait?
height: I32
max_hp: I32
max_ap: I32
skills: Map<App.KL.Game.Skill> // letter -> skill
@ -17,7 +18,7 @@ type App.KL.Game.Hero.Draw.Pose {
cast(
frame: U64
center: Hexagonal.Axial
target: Hexagonal.Axial
target: List<Hexagonal.Axial>
letter: Char
skill: App.KL.Game.Skill
creature: App.KL.Game.Creature

Some files were not shown because too many files have changed in this diff Show More