# Duane's Dungeon - a rogue-like game # Copyright (C) 2023 Duane Robertson # status.gd - status effects object # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . extends RefCounted class_name Status var my_parent var status := {} func _init(in_parent): my_parent = in_parent # func add(stat:Dictionary): # status[OS.get_ticks_usec()] = stat # sprite(stat) # stat.start = G.game_turn # scallv(stat, 'on_start', [my_parent, stat]) func add_value(attr_s, default=0.0) -> float: var ret:float = default for stat in status.values(): if stat.get('modifiers'): ret += stat.modifiers.get(attr_s, 0.0) # if my_parent.is_in_group('player') and stat.modifiers.get(attr_s): # print('status adds %0.2f to %s' % [stat.modifiers.get(attr_s), attr_s]) return ret # func at(pos:Vector2): # var ret := [] # for stat in status.values(): # var a = stat.get('area') # if a and a.has_point(pos): # ret.append(stat) # return ret # func auto_move() -> bool: # var ret := true # if not my_parent.is_in_group('entity'): # return ret # for stat in status.values(): # var a = stat.get('area') # if stat.get('auto_move') and (not a \ # or a.has_point(my_parent.grid_position)): # ret = ret and scallv(stat, 'auto_move', [my_parent, stat]) # return ret # func has_attr(attr:String) -> bool: # for stat in status.values(): # if stat.has(attr): # return true # return false func has(st:String) -> bool: for stat in status.values(): if stat.name == st: return true return false # func hide_sprite(stat): # if not my_parent.get('status_sprites') is Dictionary: # return # if stat is Dictionary: # stat = stat.sprite # if my_parent.status_sprites.get(stat): # my_parent.status_sprites[stat].visible = false func multiply_value(attr_s, default=1.0) -> float: var ret:float = default for stat in status.values(): if stat.get('modifiers'): ret *= stat.modifiers.get(attr_s, 1.0) if my_parent.is_in_group('player') and stat.modifiers.get(attr_s): print('status multiplies %0.2f by %s' % [stat.modifiers.get(attr_s), attr_s]) return ret # func on_cast(spell, caster=null, targets=[]) -> bool: # var ret := true # for stat in status.values(): # if not stat.get('on_cast'): # continue # var a = stat.get('area') # var atar = [] # if a: # for targ in targets: # if a.has_point(targ.grid_position): # atar.append(targ) # if not a or not atar.empty() \ # or a.has_point(caster.grid_position): # ret = ret and scallv(stat, 'on_cast', [my_parent, stat, spell, caster, targets]) # return ret # func on_combat(attacker:Node2D, defender:Node2D) -> bool: # var ret := true # for stat in status.values(): # var a = stat.get('area') # if stat.get('on_combat') and (not a \ # or a.has_point(attacker.grid_position) \ # or a.has_point(defender.grid_position)): # ret = ret and scallv(stat, 'on_combat', [my_parent, stat, attacker, defender]) # return ret func on_hit(attacker:Node2D, defender:Node2D, dmg:float) -> bool: var ret := true for stat in status.values(): var a = stat.get('area') if stat.get('on_hit') and (not a \ or a.has_point(attacker.grid_position) \ or a.has_point(defender.grid_position)): ret = ret and stat.callv('on_hit', [my_parent, stat, attacker, defender, dmg]) return ret # func remove_all(): # for i in status.keys(): # rem_key(i) # func rem_key(ms:int): # var stat = status[ms] # scallv(stat, 'on_end', [my_parent, stat]) # if stat.get('sprite'): # hide_sprite(stat) # status.erase(ms) # func remove(nm:String): # for i in status.keys(): # if status[i].name == nm: # rem_key(i) # func resprite(): # for stat in status.values(): # sprite(stat) # func scallv(stat, fname, args) -> bool: # var obj = my_parent # var spi = stat.get('spell_id') # var eni = stat.get('entity_id') # if eni and my_parent.get('is_dungeon'): # obj = my_parent.get_entity(eni) # if spi: # obj = G.spells[spi] # if not (obj and fname and stat.get(fname)): # return false # return obj.callv(stat[fname], args) # func sprite(stat): # if not my_parent.get('status_sprites') is Dictionary: # return # if stat is Vector2: # if my_parent.status_sprites.get(stat): # my_parent.status_sprites[stat].visible = true # return # stat = { sprite = stat } # if not stat.get('sprite'): # return # var spr = my_parent.status_sprites.get(stat.sprite) # if not spr: # var color = stat.get('sprite_color', 'ffffff') # var tex:ImageTexture = G.sprite_sheet.texture(stat.sprite, color) # spr = Sprite.new() # spr.texture = tex # spr.centered = false # my_parent.status_sprites[stat.sprite] = spr # my_parent.add_child(spr) # spr.visible = true # func turn(game_turn:int): # for ms in status.keys(): # var stat = status[ms] # stat.game_turn = game_turn # var dur = stat.get('duration') # if not my_parent.is_in_group('player'): # dur += 1 # # if my_parent.is_in_group('player'): # # print('turn: %d -- status: %s, dur: %d, start: %d' % [G.game_turn, stat.name, stat.get('duration', 0), stat.start]) # if dur and dur + stat.start <= game_turn: # rem_key(ms) # else: # scallv(stat, 'on_turn', [my_parent, stat])