Skip to content

Instantly share code, notes, and snippets.

@MarianoGnu
Created October 20, 2018 02:20
Show Gist options
  • Save MarianoGnu/2f0a555c574a39a3e7bbe6c9308dd1e8 to your computer and use it in GitHub Desktop.
Save MarianoGnu/2f0a555c574a39a3e7bbe6c9308dd1e8 to your computer and use it in GitHub Desktop.
extends "res://singletons/battle_commands/base_command.gd"
var actor = null
var target = null
var punch setget set_punch,get_punch
func set_punch(val):
cmd_id = val
func get_punch():
return cmd_id
func execute():
if actor == null or cmd_id < 0 or cmd_id > 4:
print("Attack Command has some missing arguments")
yield(ProjectSettings.get("battle").get_tree(), "idle_frame")
emit_signal("execution_finished")
return
target = actor.get_target()
if target == null or target.battler_data.is_dead():
yield(ProjectSettings.get("battle").get_tree(), "idle_frame")
emit_signal("execution_finished")
return
var pos = actor.get_translation()
if actor.is_party:
pos = target.translation + Vector3(2,0,0)
else:
pos = target.translation - Vector3(2,0,0)
if pos != actor.translation:
var move = BATTLE_COMMAND.new_cmd_move_to(actor,pos)
move.execute()
yield(move,"execution_finished")
if cmd_id == 1:
actor.battler_node.anim.play("punch_fwd")
elif cmd_id == 2:
actor.battler_node.anim.play("punch_bwd")
elif cmd_id == 3:
actor.battler_node.anim.play("punch_up")
elif cmd_id == 4:
actor.battler_node.anim.play("punch_down")
yield(actor.battler_node,"made_contact")
on_contact()
yield(actor.battler_node.anim,"animation_finished")
emit_signal("execution_finished")
func on_contact():
if target.battler_data.is_dead():
return
var dmg_hud = preload("res://scenes/main_scenes/battle/dmg_hud.tscn").instance()
ProjectSettings.get("battle").add_child(dmg_hud)
var acuracy = actor.battler_data.acuracy * rand_range(0.8,1.2)
var evasion = target.battler_data.evasion * rand_range(0.8,1.2)
var success = (acuracy > evasion)
if success:
# attack was sucessfull
var attack = actor.battler_data.attack * rand_range(0.8,1.2)
var def = target.battler_data.defense * rand_range(0.8,1.2)
var dmg = attack - def
var block_rate = target.battler_data.block_rate * rand_range(0.8,1.2)
var msg = ""
if block_rate > randi() % 100:
msg = "BLOCKED "
dmg /= 2
# TODO: play block animation
dmg = int(dmg)
if dmg < 0: dmg = 0
dmg_hud.popup(target,msg+str(dmg))
target.battler_data.health -= dmg
if target.battler_data.is_dead():
print(target.battler_data.name + " died :(")
pass
else:
# target evaded
dmg_hud.popup(target,"MISS")
# TODO: play evade animation
pass
extends Object
signal execution_finished
var cmd_id = 0
func execute():
print("nothing to execute on base class...")
emit_signal("execution_finished")
extends Spatial
class_name BattleScene
export var actor = preload("res://scenes/main_scenes/battle/battle_actor/battle_actor.tscn")
const RESULT_NONE = 0
const RESULT_WIN = 1
const RESULT_LOSE = 2
onready var party_field = [
[get_node("field/cube1"),get_node("field/cube4"),get_node("field/cube7")],
[get_node("field/cube2"),get_node("field/cube5"),get_node("field/cube8")],
[get_node("field/cube3"),get_node("field/cube6"),get_node("field/cube9")]
]
onready var enemy_field = [
[get_node("field/cube10"),get_node("field/cube13"),get_node("field/cube16")],
[get_node("field/cube11"),get_node("field/cube14"),get_node("field/cube17")],
[get_node("field/cube12"),get_node("field/cube15"),get_node("field/cube18")]
]
var party = Array() # party actor nodes
var enemies = Array() # enemy actor nodes
var actors = Array() # all actors in scene
var battle_result = RESULT_NONE
onready var actor_container = get_node("actor_container")
#onready var dmg_hud = preload("res://scenes/main_scenes/battle/dmg_hud.tscn").instance()
onready var battle_hud = get_node("battle_hud")
signal actor_commands_finished
func _init():
ProjectSettings.set("battle",self)
func _ready():
randomize()
# add_child(dmg_hud)
load_enemy_group(2)
load_party()
battle_loop()
pass
func battle_loop():
battle_result = RESULT_NONE
while battle_result == RESULT_NONE:
# FIRST PHASE: ACTION INPUT
yield(get_tree().create_timer(1.3),"timeout")
for a in party:
if not a.battler_data.is_dead():
battle_hud.set_actor(a)
a.get_battle_commands_from_input()
yield(a, "action_ready")
yield(get_tree().create_timer(1.3),"timeout")
battle_hud.set_actor(null)
for a in enemies:
if not a.battler_data.is_dead():
a.get_battle_commands()
# SECOND PHASE: ACTION IMPLEMENTATION
pass
for a in actors:
a.battler_data.randomize_speed()
actors.sort_custom(self, "sort_actors")
for a in range(actors.size()):
if not actors[a].battler_data.is_dead():
do_action(actors[a])
yield(self,"actor_commands_finished")
print(actors[a].battler_data.name + " ended it's turn")
else:
print(actors[a].battler_data.name + " ended it's turn")
update_battle_result()
yield(get_tree(),"idle_frame")
func sort_actors(actor_a, actor_b):
# must return true if the first argument is less than the second
if actor_b.battler_data.is_dead():
return true
elif actor_a.battler_data.is_dead():
return false
var speed_a = actor_a.battler_data.temp_speed
var speed_b =actor_b.battler_data.temp_speed
return speed_a < speed_b
func do_action(actor_node):
for cmd in actor_node.commands:
cmd.execute()
yield(cmd,"execution_finished")
yield(get_tree().create_timer(0.3),"timeout")
yield(get_tree(),"idle_frame")
actor_node.commands.clear()
emit_signal("actor_commands_finished")
func update_battle_result():
var lose = true
var win = true
for a in party:
if not a.battler_data.is_dead():
lose = false
if lose:
battle_result = RESULT_LOSE
return
for a in enemies:
if not a.battler_data.is_dead():
win = false
if win:
battle_result = RESULT_WIN
func add_actor(battler_id,is_party, row, col):
#PackedScene : actor_scene
#bool : is_party
var a = preload("res://scenes/main_scenes/battle/battle_actor/battle_actor.tscn").instance()
a.set_battler_id(battler_id)
a.row = row
a.col = col
a.set_is_party(is_party)
if is_party:
a.translation = party_field[row][col].translation
party_field[row][col].battler = a
party.push_back(a)
else:
a.translation = enemy_field[row][col].translation
a.rotate(Vector3(0,1,0),deg2rad(180))
enemy_field[row][col].battler = a
enemies.push_back(a)
actors.push_back(a)
actor_container.add_child(a)
func load_enemy_group(group_id):
for enemy in GAME_DATA.persistent_data.enemy_group[group_id].party:
add_actor(enemy.character_id,false,enemy.row,enemy.col)
func load_party():
for member in PLAYER_DATA.party.party:
add_actor(member.character_id,true,member.row,member.col)
extends Node
var move_cmd_class = preload("res://singletons/battle_commands/move_to.gd")
var attack_cmd_class = preload("res://singletons/battle_commands/attack.gd")
export (Texture) var icon_punch_fwd
export (Texture) var icon_punch_bwd
export (Texture) var icon_punch_up
export (Texture) var icon_punch_down
export (Texture) var icon_swich_field
const PUNCH_FWD = 1
const PUNCH_BWD = 2
const PUNCH_UP = 3
const PUNCH_DOWN = 4
const SWICH_field = 5
onready var command_icons = [
null,
icon_punch_fwd,
icon_punch_bwd,
icon_punch_up,
icon_punch_down,
icon_swich_field]
func new_cmd_move_to(actor,destination):
var cmd = move_cmd_class.new()
cmd.actor = actor
cmd.destination = destination
return cmd
func new_cmd_attack(actor,hit_type):
var cmd = attack_cmd_class.new()
cmd.actor = actor
cmd.punch = hit_type
return cmd
extends "res://singletons/battle_commands/base_command.gd"
var actor = null
var destination = Vector2()
const RUN_SPEED = 6;
func execute():
if actor == null or (actor.translation-destination).length_squared() == 0:
print("MoveTo Command has some missing arguments")
yield(ProjectSettings.get("battle").get_tree(), "idle_frame")
emit_signal("execution_finished")
return
if (destination - actor.get_translation()).length_squared() == 0:
yield(ProjectSettings.get("battle").get_tree(), "idle_frame")
emit_signal("execution_finished")
return
var twn = Tween.new()
ProjectSettings.get("battle").add_child(twn)
var time = (destination-actor.get_translation()).length() / RUN_SPEED
twn.interpolate_property(actor,"translation",actor.translation,destination,time,Tween.TRANS_LINEAR,Tween.EASE_IN_OUT)
actor.battler_node.anim.play("run")
twn.start()
yield(twn,"tween_completed")
actor.battler_node.anim.play("idle")
twn.queue_free()
emit_signal("execution_finished")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment