extends Node

var enemy = preload('res://Enemy.tscn')
export var wave_num = 1
export var spawn_speed = 10
export var limit = 32
export var maxlimit = 1024
export var mod = 1.5
export var mod2 = 1.2

var dict = {
	"arraypos":[],
	"arrayvida":[],
	"arraytype":[],
	"arraytarget":[],
	"arraymotion":[],
	"arraydirtime":[],
	'attacker':[],
	'enabled':[],
	'type':[],
}

var collisions = []
var areas = preload('res://Enemy2.tscn')

func _ready():
	
	yield(get_tree().create_timer(1.0),"timeout")
	
	for x in maxlimit:
		var rot = rand_range(-PI,PI)
		var pos = (Vector2(sin(rot), cos(rot)) * rand_range(400,800)) + Vector2(320,180)
		dict.arraytarget.append(null)
		dict.arraypos.append(pos)
		dict.arrayvida.append(100)
		dict.arraytype.append('goblin')
		dict.attacker.append('')
		dict.arraymotion.append(Vector2.ZERO)
		dict.arraydirtime.append(int(rand_range(60,120)))
		dict.enabled.append(true)
		dict.type.append(randi()%4)
	
var motion = Vector2()
export var speed = 2.3
var tick = 0
export var tickrate = 4

var blockmapenemy = {}

func _physics_process(delta):

#setting tickrate, to reduce executions per second
#	tick += 1
#	if fmod(tick,tickrate) == 0:
	if true:

#dict of aprox positions of players
		var blockmap = {}
		if get_node('../players').get_child_count() == 0: return
		for z in get_node('../players').get_children():
			var x = int(z.global_position.x/20)
			var y = int(z.global_position.y/20)
			blockmap[Vector2(x,y)] = z

#yes this abomination controls the enemies, ECS code looks ugly as fuck in this engine
		for i in dict.arraytarget.size():

# death checking
			if dict.arrayvida[i] > 0 and dict.enabled[i]:

#picking new targets if the last one is invalid
				if dict.arraytarget[i] == null:
					if get_node('../players').get_child_count() == 0: return
					var array = get_node('../players').get_children()
					if array.size() > 0:
						dict.arraytarget[i] = array[randi()%array.size()]

#exclusive movmenet code
				if fmod(tick, dict.arraydirtime[i]) == 0:
					if is_instance_valid(dict.arraytarget[i]):
						dict.arraymotion[i] = (dict.arraytarget[i].global_position - dict.arraypos[i]).normalized() * speed
				dict.arraypos[i] += dict.arraymotion[i]

# enemy attak on players
				var x = int(dict.arraypos[i].x/20)
				var y = int(dict.arraypos[i].y/20)
				if blockmap.has(Vector2(x,y)):
					blockmap[Vector2(x,y)].damage( -enemydmg, '')
#recycling enemies
			elif dict.enabled[i]:
				var rot = rand_range(-PI,PI)
				dict.arraypos[i] = (Vector2(sin(rot), cos(rot)) * rand_range(400,800)) + Vector2(320,180)
				dict.arrayvida[i] = 100
				dict.arraytarget[i] = null
				death_count(dict.attacker[i])
				

func damage_detection(arg,dmg, attacker):
	blockmapenemy = {}
	for i in dict.arraypos.size():
		var x2 = int( (dict.arraypos[i].x -16)/32)
		var y2 = int( (dict.arraypos[i].y -16)/32)
		if blockmapenemy.has(Vector2(x2,y2)):
			blockmapenemy[Vector2(x2,y2)].append(i)
		else:
			blockmapenemy[Vector2(x2,y2)] = [i]
	
	var x = int((arg.x -16)/32)
	var y = int((arg.y -16)/32)
	for x2 in range(-2,2):
		for y2 in range(-2,2):
			if blockmapenemy.has(Vector2(x+x2,y+y2)):
				for i in blockmapenemy[Vector2(x+x2,y+y2)]:
					dict.arrayvida[i] -= dmg
					if dict.arrayvida[i] <= 0:
						dict.attacker[i] = attacker


#unrelated code that takes care of level up, kill counts, xp and etc

var counter = 0
var score = {}
var xp = {}
var nxt = {}
var lv = {}
var maxhp = {}

export var hpgain = 5
export var dmggain = 5
export var xpggain = 10
export var xpnext = 1.2
export var enemydmg = 3.0

func death_count(id):
	if not nxt.has(id):
		nxt[id] = 100
	
	if not maxhp.has(id):
		maxhp[id] = 100
	
	if not lv.has(id):
		lv[id] = 0
	
	if score.has(id):
		score[id] += 1
	else:
		score[id] = 1
	
	if xp.has(id):
		xp[id] += xpggain
		if xp[id] > nxt[id]:
			lv[id] += 1
			var gain = hpgain * lv[id]
			maxhp[id] += gain
			get_parent().level_up(lv[id] , maxhp[id], gain, dmggain, id)
			xp[id] = 0
			nxt[id] *= xpnext
	else:
		xp[id] = xpggain
	get_parent().kill_update(score[id], xp[id], lv[id], nxt[id], id)
