Mag gen & work towards AI
This commit is contained in:
		@ -6,12 +6,6 @@ var HP: int = 8
 | 
			
		||||
@export
 | 
			
		||||
var color_str: String = "ffff00"
 | 
			
		||||
 | 
			
		||||
func _ready():
 | 
			
		||||
	var tile_map: TileMap = get_node("%tile_map")
 | 
			
		||||
	var tile_pos = tile_map.local_to_map(Vector2i(int(position.x), int(position.y)))
 | 
			
		||||
	if(tile_map.get_cell_source_id(0, tile_pos) != -1):
 | 
			
		||||
		push_error("Enemy placed at tile in use, freeing!")
 | 
			
		||||
		queue_free()
 | 
			
		||||
 | 
			
		||||
func take_damage(dmg):
 | 
			
		||||
	playAudio("Bomb_Drop.wav")
 | 
			
		||||
 | 
			
		||||
@ -50,7 +50,7 @@ func take_damage(dmg):
 | 
			
		||||
func update_angry():
 | 
			
		||||
	if angry && global_position.distance_to(player.global_position) > angry_distance:
 | 
			
		||||
		angry = false
 | 
			
		||||
	elif global_position.distance_to(player.global_position) < active_distance:
 | 
			
		||||
	elif player and global_position.distance_to(player.global_position) < active_distance:
 | 
			
		||||
		angry = true
 | 
			
		||||
	if(TIMER.wait_time <= 0):
 | 
			
		||||
		TIMER.start(UPDATE_ANGRY_TIME)
 | 
			
		||||
@ -65,7 +65,7 @@ func _physics_process(_delta: float) -> void:
 | 
			
		||||
 | 
			
		||||
	if knockback > 0:
 | 
			
		||||
		motion.y -= knockback/2
 | 
			
		||||
		if(player.global_position.x > global_position.x):
 | 
			
		||||
		if(player and player.global_position.x > global_position.x):
 | 
			
		||||
			motion.x -= knockback
 | 
			
		||||
		else:
 | 
			
		||||
			motion.x += knockback
 | 
			
		||||
 | 
			
		||||
@ -155,7 +155,7 @@ func _movement_process(delta: float) -> void:
 | 
			
		||||
		if self.is_on_floor():
 | 
			
		||||
 | 
			
		||||
			if Input.is_action_pressed("move_down"):
 | 
			
		||||
				pass # lmanley: todo reimplement platforms
 | 
			
		||||
				self.position.y += 1
 | 
			
		||||
			else:
 | 
			
		||||
				self.jump()
 | 
			
		||||
				self.current_jumps = self.extra_jumps
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										56
									
								
								scripts/v2/creature.gd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								scripts/v2/creature.gd
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,56 @@
 | 
			
		||||
class_name Creature
 | 
			
		||||
extends Node
 | 
			
		||||
 | 
			
		||||
signal damaged(amount)
 | 
			
		||||
signal healed(amount)
 | 
			
		||||
signal death()
 | 
			
		||||
 | 
			
		||||
@export
 | 
			
		||||
var max_hp: int = 1
 | 
			
		||||
 | 
			
		||||
@export
 | 
			
		||||
var death_sound: AudioStream = null
 | 
			
		||||
 | 
			
		||||
@export
 | 
			
		||||
var free_on_death: bool = true
 | 
			
		||||
 | 
			
		||||
var hp: int :
 | 
			
		||||
	get:
 | 
			
		||||
		return hp
 | 
			
		||||
	set(value):
 | 
			
		||||
		var old_hp = hp
 | 
			
		||||
 | 
			
		||||
		hp = clampi(value, 0, max_hp)
 | 
			
		||||
 | 
			
		||||
		if hp < old_hp:
 | 
			
		||||
			self.damaged.emit(old_hp - hp)
 | 
			
		||||
		elif hp > old_hp:
 | 
			
		||||
			self.healed.emit(hp - old_hp)
 | 
			
		||||
		
 | 
			
		||||
		if hp == 0:
 | 
			
		||||
			self.death.emit()
 | 
			
		||||
 | 
			
		||||
func _ready() -> void:
 | 
			
		||||
	self.hp = self.max_hp
 | 
			
		||||
	self.death.connect(self._creature_on_death)
 | 
			
		||||
 | 
			
		||||
func take_damage(damage: int) -> void:
 | 
			
		||||
	self.hp -= damage
 | 
			
		||||
 | 
			
		||||
func heal(amount: int) -> void:
 | 
			
		||||
	self.hp += amount
 | 
			
		||||
 | 
			
		||||
func _creature_on_death() -> void:
 | 
			
		||||
	
 | 
			
		||||
	# Play a sound on creature death
 | 
			
		||||
	if self.death_sound:
 | 
			
		||||
		var audio_player = AudioStreamPlayer2D.new()
 | 
			
		||||
		self.get_parent().add_child(audio_player)
 | 
			
		||||
		audio_player.stream = self.death_sound
 | 
			
		||||
		audio_player.bus = "Sound Effects"
 | 
			
		||||
		audio_player.finished.connect(audio_player.queue_free)
 | 
			
		||||
		audio_player.play()
 | 
			
		||||
 | 
			
		||||
	# Destroy on death
 | 
			
		||||
	if self.free_on_death:
 | 
			
		||||
		self.queue_free()
 | 
			
		||||
							
								
								
									
										42
									
								
								scripts/v2/enemy.gd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								scripts/v2/enemy.gd
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
			
		||||
class_name Enemy
 | 
			
		||||
extends Creature
 | 
			
		||||
 | 
			
		||||
enum State {
 | 
			
		||||
	IDLE,
 | 
			
		||||
	CHASE,
 | 
			
		||||
	ATTACK
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@export
 | 
			
		||||
var state: State = State.IDLE
 | 
			
		||||
 | 
			
		||||
@export_category("Parts")
 | 
			
		||||
@export
 | 
			
		||||
var animation_player: AnimationPlayer
 | 
			
		||||
 | 
			
		||||
var _chase_target: Node2D
 | 
			
		||||
var _target_is_left: bool = false
 | 
			
		||||
 | 
			
		||||
func _play_animation(animation: String) -> void:
 | 
			
		||||
	if not animation_player:
 | 
			
		||||
		return
 | 
			
		||||
 | 
			
		||||
	if not animation_player.has_animation(animation):
 | 
			
		||||
		return
 | 
			
		||||
	
 | 
			
		||||
	if animation_player.is_playing() and animation_player.current_animation == animation:
 | 
			
		||||
		return
 | 
			
		||||
	
 | 
			
		||||
	animation_player.play(animation)
 | 
			
		||||
 | 
			
		||||
func _process(delta: float) -> void:
 | 
			
		||||
	var animation_name = str(State.keys()[self.state]).to_lower()
 | 
			
		||||
	self._play_animation(animation_name)
 | 
			
		||||
 | 
			
		||||
func _physics_process(delta: float) -> void:
 | 
			
		||||
	match self.state:
 | 
			
		||||
		State.CHASE:
 | 
			
		||||
			if not self._chase_target:
 | 
			
		||||
				self.state = State.IDLE
 | 
			
		||||
			
 | 
			
		||||
			pass
 | 
			
		||||
@ -8,8 +8,3 @@ var map: TileMap
 | 
			
		||||
 | 
			
		||||
func _ready() -> void:
 | 
			
		||||
	self.generator.generate(map)
 | 
			
		||||
 | 
			
		||||
func _process(_delta: float) -> void:
 | 
			
		||||
	if Input.is_action_just_pressed("jump"):
 | 
			
		||||
		map.clear()
 | 
			
		||||
		self.generator.generate(map)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										65
									
								
								scripts/v2/worldgen/standard/entity_marker.gd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								scripts/v2/worldgen/standard/entity_marker.gd
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,65 @@
 | 
			
		||||
class_name StandardEntityMarker
 | 
			
		||||
extends Node2D
 | 
			
		||||
 | 
			
		||||
enum SPAWN_METHOD {
 | 
			
		||||
	ALL,
 | 
			
		||||
	FURTHEST,
 | 
			
		||||
	ONCE,
 | 
			
		||||
	NONE
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
enum ENTITY_SELECTION_METHOD {
 | 
			
		||||
	RANDOM,
 | 
			
		||||
	POP
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@export_category("Entity Spawning")
 | 
			
		||||
@export
 | 
			
		||||
var marker_id: String
 | 
			
		||||
 | 
			
		||||
@export
 | 
			
		||||
var entities: Array[PackedScene] = []
 | 
			
		||||
 | 
			
		||||
@export
 | 
			
		||||
var spawn_method: SPAWN_METHOD
 | 
			
		||||
 | 
			
		||||
@export_range(0, 1.0)
 | 
			
		||||
var spawn_chance: float = 1.0
 | 
			
		||||
 | 
			
		||||
@export
 | 
			
		||||
var entity_selection_method: ENTITY_SELECTION_METHOD
 | 
			
		||||
 | 
			
		||||
@export_category("Marker Debug")
 | 
			
		||||
@export
 | 
			
		||||
var debug_color: Color = Color.WHITE
 | 
			
		||||
 | 
			
		||||
@export
 | 
			
		||||
var marker_size: int = 16
 | 
			
		||||
 | 
			
		||||
func _ready() -> void:
 | 
			
		||||
	self.add_to_group("genv2:entity_marker")
 | 
			
		||||
	
 | 
			
		||||
	var sprite: Sprite2D = self.get_node_or_null("Sprite2D")
 | 
			
		||||
	if not sprite:
 | 
			
		||||
		sprite = Sprite2D.new()
 | 
			
		||||
		sprite.texture = _get_debug_texture()
 | 
			
		||||
		self.add_child(sprite)
 | 
			
		||||
	
 | 
			
		||||
func _register(gen: StandardWorldGenerator) -> void:
 | 
			
		||||
	if self.marker_id == "":
 | 
			
		||||
		push_error("Marker ID is empty, this marker will not be used for spawning entities.")
 | 
			
		||||
		return
 | 
			
		||||
	gen._register_marker("genv2:entity_marker:%s" % self.marker_id, self)
 | 
			
		||||
 | 
			
		||||
func _get_debug_texture() -> Texture2D:
 | 
			
		||||
	var texture = GradientTexture2D.new()
 | 
			
		||||
	
 | 
			
		||||
	var gradient = Gradient.new()
 | 
			
		||||
	gradient.colors = [self.debug_color]
 | 
			
		||||
 | 
			
		||||
	texture.gradient = gradient
 | 
			
		||||
 | 
			
		||||
	texture.width = self.marker_size
 | 
			
		||||
	texture.height = self.marker_size
 | 
			
		||||
	
 | 
			
		||||
	return texture
 | 
			
		||||
@ -62,8 +62,10 @@ func copy_to_map(map: TileMap) -> void:
 | 
			
		||||
	for x in range(0, self.room_size.x):
 | 
			
		||||
		for y in range(0, self.room_size.y):
 | 
			
		||||
			var tile = self.get_cell_source_id(TILEMAP_LAYER, Vector2i(x, y))
 | 
			
		||||
			var alt = self.get_cell_alternative_tile(TILEMAP_LAYER, Vector2i(x, y))
 | 
			
		||||
			
 | 
			
		||||
			if tile != -1:
 | 
			
		||||
				map.set_cell(TILEMAP_LAYER, Vector2i(position.x + x, position.y + y), tile, Vector2i(0, 0))
 | 
			
		||||
				map.set_cell(TILEMAP_LAYER, Vector2i(position.x + x, position.y + y), tile, Vector2i(0, 0), alt)
 | 
			
		||||
			else:
 | 
			
		||||
				map.set_cell(TILEMAP_LAYER, Vector2i(position.x + x, position.y + y), -1, Vector2i(0, 0))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -20,6 +20,8 @@ var _rooms_blocking: Array[PackedScene] = []
 | 
			
		||||
 | 
			
		||||
var _progress_tracker: ProgressTracker
 | 
			
		||||
 | 
			
		||||
var _markers: Dictionary = {}
 | 
			
		||||
 | 
			
		||||
func _generate(map: TileMap) -> void:
 | 
			
		||||
	self._progress_tracker = ProgressTracker.new(1)
 | 
			
		||||
 | 
			
		||||
@ -32,6 +34,9 @@ func _generate(map: TileMap) -> void:
 | 
			
		||||
	# Create rooms
 | 
			
		||||
	self._create_rooms(map, init_room, self.max_room_path_length, _progress_tracker.next_step("Creating Rooms"))
 | 
			
		||||
	map.update_internals()
 | 
			
		||||
	
 | 
			
		||||
	self._spawn_entities(map, _progress_tracker.next_step("Spawning Entities"))
 | 
			
		||||
	map.update_internals()
 | 
			
		||||
 | 
			
		||||
func _sort_rooms(step_tracker: ProgressStepTracker) -> void:
 | 
			
		||||
	step_tracker.complete.call_deferred()
 | 
			
		||||
@ -163,5 +168,95 @@ func _get_rooms(exit: Vector2i) -> Array[PackedScene]:
 | 
			
		||||
		push_error("Invalid exit: " + str(exit))
 | 
			
		||||
		return []
 | 
			
		||||
 | 
			
		||||
func _register_marker(group: String, marker: Node2D) -> void:
 | 
			
		||||
	if not group in self._markers:
 | 
			
		||||
		self._markers[group] = [marker]
 | 
			
		||||
	else:
 | 
			
		||||
		self._markers[group].append(marker)
 | 
			
		||||
 | 
			
		||||
func _spawn_entities(map: TileMap, step_tracker: ProgressStepTracker) -> void:
 | 
			
		||||
	var tree = map.get_tree()
 | 
			
		||||
	
 | 
			
		||||
	# Register entity markers
 | 
			
		||||
	for entity_marker in tree.get_nodes_in_group("genv2:entity_marker"):
 | 
			
		||||
		if entity_marker is StandardEntityMarker:
 | 
			
		||||
			entity_marker._register(self)
 | 
			
		||||
	
 | 
			
		||||
	for marker_id in self._markers:
 | 
			
		||||
		var sample_marker: StandardEntityMarker = self._markers[marker_id][0]
 | 
			
		||||
		
 | 
			
		||||
		match sample_marker.spawn_method:
 | 
			
		||||
			StandardEntityMarker.SPAWN_METHOD.ALL:
 | 
			
		||||
				for marker in self._markers[marker_id]:
 | 
			
		||||
					map.erase_cell.call_deferred(0, map.local_to_map(marker.position))
 | 
			
		||||
					
 | 
			
		||||
					var packed_entity: PackedScene = _select_entity(marker.entity_selection_method, marker.entities)
 | 
			
		||||
					if packed_entity == null:
 | 
			
		||||
						continue
 | 
			
		||||
					
 | 
			
		||||
					var entity: Node2D = packed_entity.instantiate()
 | 
			
		||||
					entity.position = marker.position
 | 
			
		||||
					map.add_child(entity)
 | 
			
		||||
			StandardEntityMarker.SPAWN_METHOD.FURTHEST:
 | 
			
		||||
				var furthest_marker: StandardEntityMarker = self._markers[marker_id].pop_back()
 | 
			
		||||
				var furthest_distance: float = furthest_marker.position.distance_to(Vector2.ZERO)
 | 
			
		||||
				
 | 
			
		||||
				# Calculate furthest marker and destroy others
 | 
			
		||||
				for marker in self._markers[marker_id]:
 | 
			
		||||
					var calc_distance: float = marker.position.distance_to(Vector2.ZERO)
 | 
			
		||||
					if calc_distance > furthest_distance:
 | 
			
		||||
						map.erase_cell(0, map.local_to_map(furthest_marker.position))
 | 
			
		||||
						furthest_marker = marker
 | 
			
		||||
						furthest_distance = calc_distance
 | 
			
		||||
					else:
 | 
			
		||||
						map.erase_cell(0, map.local_to_map(marker.position))
 | 
			
		||||
 | 
			
		||||
				# Erase furthest marker
 | 
			
		||||
				map.erase_cell.call_deferred(0, map.local_to_map(furthest_marker.position))
 | 
			
		||||
 | 
			
		||||
				# Get entity
 | 
			
		||||
				var packed_entity: PackedScene = _select_entity(furthest_marker.entity_selection_method, furthest_marker.entities)
 | 
			
		||||
				if packed_entity == null:
 | 
			
		||||
					continue
 | 
			
		||||
 | 
			
		||||
				var entity: Node2D = packed_entity.instantiate()
 | 
			
		||||
				entity.position = furthest_marker.position
 | 
			
		||||
				map.add_child(entity)
 | 
			
		||||
				
 | 
			
		||||
				
 | 
			
		||||
			StandardEntityMarker.SPAWN_METHOD.ONCE:
 | 
			
		||||
				var i = randi() % len(self._markers[marker_id])
 | 
			
		||||
				var marker = self._markers[marker_id][i]
 | 
			
		||||
				
 | 
			
		||||
				var packed_entity: PackedScene = _select_entity(marker.entity_selection_method, marker.entities)
 | 
			
		||||
				if packed_entity != null:
 | 
			
		||||
					var entity: Node2D = packed_entity.instantiate()
 | 
			
		||||
					entity.position = marker.position
 | 
			
		||||
					map.add_child(entity)
 | 
			
		||||
				
 | 
			
		||||
				for _marker in self._markers[marker_id]:
 | 
			
		||||
					map.erase_cell(0, map.local_to_map(_marker.position))
 | 
			
		||||
				
 | 
			
		||||
			StandardEntityMarker.SPAWN_METHOD.NONE:
 | 
			
		||||
				for marker in self._markers[marker_id]:
 | 
			
		||||
					map.erase_cell(0, map.local_to_map(marker.position))
 | 
			
		||||
			_:
 | 
			
		||||
				push_error("Invalid spawning method!")
 | 
			
		||||
				continue
 | 
			
		||||
 | 
			
		||||
func _select_entity(mode: StandardEntityMarker.ENTITY_SELECTION_METHOD, entities: Array) -> PackedScene:
 | 
			
		||||
	if len(entities) == 0:
 | 
			
		||||
		return null
 | 
			
		||||
	
 | 
			
		||||
	match mode:
 | 
			
		||||
		StandardEntityMarker.ENTITY_SELECTION_METHOD.RANDOM:
 | 
			
		||||
			var i = randi() % len(entities)
 | 
			
		||||
			return entities[i]
 | 
			
		||||
		StandardEntityMarker.ENTITY_SELECTION_METHOD.POP:
 | 
			
		||||
			var i = randi() % len(entities)
 | 
			
		||||
			return entities.pop_at(i)
 | 
			
		||||
 | 
			
		||||
	return null
 | 
			
		||||
 | 
			
		||||
func _get_progress_tracker() -> ProgressTracker:
 | 
			
		||||
	return self._progress_tracker
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user