@tool @icon("res://textures/stickers/icon_sticker2.svg") class_name Sticker extends Area2D ## Handle all the sticker-relative gameplay. ## ## Sticker node expect to be a child of a Node2D, who serve as a root for ## all the fonctionnalities. You need to assign nodes for the stickerdetection ## and for the sprites. #region Exported variables @export var Sticker_mode:bool = false @export_group("Nodes") ## The look of the object. If it's multiple sprites, they should be under one main sprite @export var WorldSprite:Sprite2D ## Optional - The look of the object when grabbed. If empty, OutlineMat will be applied to WorldSprite @export var StickerSprite:Sprite2D ## Optional - The detection zone, if not the same as the sticker area @export var DetectionArea:Area2D: set(new_area): if(new_area != self): DetectionArea = new_area else: printerr("DetectionArea cannot be the sticker itself") @export_group("Material") @export var OutlineMat:ShaderMaterial = preload("res://shaders/shaderMaterial_Outline.tres") @export var Foiled:bool #TODO: Foil material and logic @export var CreateShape:bool: set(value): var test = CollisionShape2D.new() test.set_name("StickerShape") add_child(test) test.set_owner(get_tree().get_edited_scene_root()) test = null #endregion var meta:PackedStringArray = ["sticker"] var detected_solids:Array var detected_zones:Array var Grabbed:bool = false ## Emitted when the sticker overlap a blocking body, preventing to be spawned as an asset in the level. Usually received by the cursor to change his sprite signal spawn_mode_changed(can_spawn:bool) #region Functions func _get_configuration_warnings(): if (get_parent() == get_tree().get_edited_scene_root()): return ["This node should have a parent"] return [] func _init(): collision_layer = 2 # TODO: Stickerzone maybe will not need to check everything, and detection will be on the zone detection area only. maybe we want a fallback if sticker area and detection area are the same shape collision_mask = 61 set_meta("tags",meta) monitoring = true if Engine.is_editor_hint(): update_configuration_warnings() func _enter_tree(): set_meta("tags",meta) if (get_parent() is Sprite2D and WorldSprite == null): WorldSprite = get_parent() if Engine.is_editor_hint(): update_configuration_warnings() func _ready(): if (get_parent() == get_tree().root): printerr("stickers should always have a parent") breakpoint if (DetectionArea != null): DetectionArea.area_entered.connect(_on_area_entered) DetectionArea.area_exited.connect(_on_area_exited) DetectionArea.body_entered.connect(_on_body_entered) DetectionArea.body_exited.connect(_on_body_exited) DetectionArea.collision_mask = 61 else: area_entered.connect(_on_area_entered) area_exited.connect(_on_area_exited) body_entered.connect(_on_body_entered) body_exited.connect(_on_body_exited) # TODO : Solids and interactive zone detection area should not be the same as the sticker area. # IDEA: Need to export a child Area2D func _on_body_entered(body:Node2D): print("body entered",body) detected_solids.append(body) spawn_mode_changed.emit(false) func _on_body_exited(body:Node2D): print("body exited",body) detected_solids.erase(body) if(Sticker_mode and Grabbed and detected_solids.size() == 0 ): spawn_mode_changed.emit(true) func _on_area_entered(area:Area2D): print("area entered",area) #TODO:Filter by type detected_zones.append(area) func _on_area_exited(area:Area2D): print("area exited",area) detected_zones.erase(area) func _process(_delta): pass ## When the sticker is released func on_released(_CastResult:Array=[]): print(self," released") Grabbed = false #Need a traceresult to know if it should stay in the stickerstate or be released in the world if(detected_solids.size()==0): get_parent().top_level = false disable_ChildNodes_collisions(false) update_ChildNodes_visibilty(true) Sticker_mode = false on_unhover() #security,but i don't like it get_parent().reparent(MapManager.current_scene.get_child(0)) func on_click(): print(self," clicked") func redraw(): if (StickerSprite != null): StickerSprite.queue_redraw() if (WorldSprite != null): WorldSprite.queue_redraw() func on_hover(): if (Sticker_mode == false): if (StickerSprite != null): WorldSprite.visible = false StickerSprite.visible = true elif (WorldSprite != null): WorldSprite.material = OutlineMat redraw() func on_unhover(): if (Sticker_mode == false): if (StickerSprite != null): StickerSprite.visible = false if (WorldSprite != null): WorldSprite.material = null WorldSprite.visible = true redraw() func on_grab(_offset:Vector2=Vector2(0.0,0.0)): Sticker_mode = true get_parent().top_level = true get_parent().reparent(MapManager) update_ChildNodes_visibilty(false) disable_ChildNodes_collisions(true) Grabbed = true func update_ChildNodes_visibilty(_visible:bool=true): for _childNode in get_parent().get_children(): if(_childNode != WorldSprite and _childNode != StickerSprite): _childNode.visible = _visible func disable_ChildNodes_collisions(_disable:bool=true): for _childNode in get_parent().get_children(): if (_childNode != self): _childNode.process_mode = Node.PROCESS_MODE_DISABLED if _disable else Node.PROCESS_MODE_ALWAYS #endregion