Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #8728 from AnturK/action_button
Generic Action\Action Button System
- Loading branch information
Showing
36 changed files
with
569 additions
and
216 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,247 @@ | ||
#define AB_ITEM 1 | ||
#define AB_SPELL 2 | ||
#define AB_INNATE 3 | ||
#define AB_GENERIC 4 | ||
|
||
#define AB_CHECK_RESTRAINED 1 | ||
#define AB_CHECK_STUNNED 2 | ||
#define AB_CHECK_LYING 4 | ||
#define AB_CHECK_ALIVE 8 | ||
#define AB_CHECK_INSIDE 16 | ||
|
||
|
||
/datum/action | ||
var/name = "Generic Action" | ||
var/action_type = AB_ITEM | ||
var/procname = null | ||
var/atom/movable/target = null | ||
var/check_flags = 0 | ||
var/processing = 0 | ||
var/active = 0 | ||
var/obj/screen/movable/action_button/button = null | ||
var/button_icon = 'icons/mob/actions.dmi' | ||
var/button_icon_state = "default" | ||
var/background_icon_state = "bg_default" | ||
var/mob/living/owner | ||
|
||
/datum/action/New(var/Target) | ||
target = Target | ||
|
||
/datum/action/Destroy() | ||
if(owner) | ||
Remove(owner) | ||
|
||
/datum/action/proc/Grant(mob/living/T) | ||
if(owner) | ||
if(owner == T) | ||
return | ||
Remove(owner) | ||
owner = T | ||
owner.actions.Add(src) | ||
owner.update_action_buttons() | ||
return | ||
|
||
/datum/action/proc/Remove(mob/living/T) | ||
if(button) | ||
if(T.client) | ||
T.client.screen -= button | ||
del(button) | ||
T.actions.Remove(src) | ||
T.update_action_buttons() | ||
owner = null | ||
return | ||
|
||
/datum/action/proc/Trigger() | ||
if(!Checks()) | ||
return | ||
switch(action_type) | ||
if(AB_ITEM) | ||
if(target) | ||
var/obj/item/item = target | ||
item.ui_action_click() | ||
if(AB_SPELL) | ||
if(target) | ||
var/obj/effect/proc_holder/spell = target | ||
spell.Click() | ||
if(AB_INNATE) | ||
if(!active) | ||
Activate() | ||
else | ||
Deactivate() | ||
if(AB_GENERIC) | ||
if(target && procname) | ||
call(target,procname)(usr) | ||
return | ||
|
||
/datum/action/proc/Activate() | ||
return | ||
|
||
/datum/action/proc/Deactivate() | ||
return | ||
|
||
/datum/action/proc/Process() | ||
return | ||
|
||
/datum/action/proc/CheckRemoval(mob/living/user) // 1 if action is no longer valid for this mob and should be removed | ||
return 0 | ||
|
||
/datum/action/proc/IsAvailable() | ||
return Checks() | ||
|
||
/datum/action/proc/Checks()// returns 1 if all checks pass | ||
if(!owner) | ||
return 0 | ||
if(check_flags & AB_CHECK_RESTRAINED) | ||
if(owner.restrained()) | ||
return 0 | ||
if(check_flags & AB_CHECK_STUNNED) | ||
if(owner.stunned) | ||
return 0 | ||
if(check_flags & AB_CHECK_LYING) | ||
if(owner.lying) | ||
return 0 | ||
if(check_flags & AB_CHECK_ALIVE) | ||
if(owner.stat) | ||
return 0 | ||
if(check_flags & AB_CHECK_INSIDE) | ||
if(!(target in owner)) | ||
return 0 | ||
return 1 | ||
|
||
/datum/action/proc/UpdateName() | ||
return name | ||
|
||
/obj/screen/movable/action_button | ||
var/datum/action/owner | ||
screen_loc = "WEST,NORTH" | ||
|
||
/obj/screen/movable/action_button/Click(location,control,params) | ||
var/list/modifiers = params2list(params) | ||
if(modifiers["shift"]) | ||
moved = 0 | ||
return 1 | ||
if(usr.next_move >= world.time) // Is this needed ? | ||
return | ||
owner.Trigger() | ||
return 1 | ||
|
||
/obj/screen/movable/action_button/proc/UpdateIcon() | ||
if(!owner) | ||
return | ||
icon = owner.button_icon | ||
icon_state = owner.background_icon_state | ||
|
||
overlays.Cut() | ||
var/image/img | ||
if(owner.action_type == AB_ITEM && owner.target) | ||
var/obj/item/I = owner.target | ||
img = image(I.icon, src , I.icon_state) | ||
else if(owner.button_icon && owner.button_icon_state) | ||
img = image(owner.button_icon,src,owner.button_icon_state) | ||
img.pixel_x = 0 | ||
img.pixel_y = 0 | ||
overlays += img | ||
|
||
if(!owner.IsAvailable()) | ||
color = rgb(128,0,0,128) | ||
else | ||
color = rgb(255,255,255,255) | ||
|
||
//Hide/Show Action Buttons ... Button | ||
/obj/screen/movable/action_button/hide_toggle | ||
name = "Hide Buttons" | ||
icon = 'icons/mob/actions.dmi' | ||
icon_state = "bg_default" | ||
var/hidden = 0 | ||
|
||
/obj/screen/movable/action_button/hide_toggle/Click() | ||
usr.hud_used.action_buttons_hidden = !usr.hud_used.action_buttons_hidden | ||
|
||
hidden = usr.hud_used.action_buttons_hidden | ||
if(hidden) | ||
name = "Show Buttons" | ||
else | ||
name = "Hide Buttons" | ||
UpdateIcon() | ||
usr.update_action_buttons() | ||
|
||
|
||
/obj/screen/movable/action_button/hide_toggle/proc/InitialiseIcon(var/mob/living/user) | ||
if(isalien(user)) | ||
icon_state = "bg_alien" | ||
else | ||
icon_state = "bg_default" | ||
UpdateIcon() | ||
return | ||
|
||
/obj/screen/movable/action_button/hide_toggle/UpdateIcon() | ||
overlays.Cut() | ||
var/image/img = image(icon,src,hidden?"show":"hide") | ||
overlays += img | ||
return | ||
|
||
//This is the proc used to update all the action buttons. Properly defined in /mob/living/ | ||
/mob/proc/update_action_buttons() | ||
return | ||
|
||
#define AB_WEST_OFFSET 4 | ||
#define AB_NORTH_OFFSET 26 | ||
#define AB_MAX_COLUMNS 10 | ||
|
||
/datum/hud/proc/ButtonNumberToScreenCoords(var/number) // TODO : Make this zero-indexed for readabilty | ||
var/row = round((number-1)/AB_MAX_COLUMNS) | ||
var/col = ((number - 1)%(AB_MAX_COLUMNS)) + 1 | ||
var/coord_col = "+[col-1]" | ||
var/coord_col_offset = 4+2*col | ||
var/coord_row = "[-1 - row]" | ||
var/coord_row_offset = 26 | ||
return "WEST[coord_col]:[coord_col_offset],NORTH[coord_row]:[coord_row_offset]" | ||
|
||
/datum/hud/proc/SetButtonCoords(var/obj/screen/button,var/number) | ||
var/row = round((number-1)/AB_MAX_COLUMNS) | ||
var/col = ((number - 1)%(AB_MAX_COLUMNS)) + 1 | ||
var/x_offset = 32*(col-1) + 4 + 2*col | ||
var/y_offset = -32*(row+1) + 26 | ||
|
||
var/matrix/M = matrix() | ||
M.Translate(x_offset,y_offset) | ||
button.transform = M | ||
|
||
//Presets for item actions | ||
/datum/action/item_action | ||
check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUNNED|AB_CHECK_LYING|AB_CHECK_ALIVE|AB_CHECK_INSIDE | ||
|
||
/datum/action/item_action/CheckRemoval(mob/living/user) | ||
return !(target in user) | ||
|
||
/datum/action/item_action/hands_free | ||
check_flags = AB_CHECK_ALIVE|AB_CHECK_INSIDE | ||
|
||
|
||
//Preset for spells | ||
/datum/action/spell_action | ||
action_type = AB_SPELL | ||
check_flags = 0 | ||
background_icon_state = "bg_spell" | ||
|
||
/datum/action/spell_action/UpdateName() | ||
var/obj/effect/proc_holder/spell/spell = target | ||
return spell.name | ||
|
||
/datum/action/spell_action/IsAvailable() | ||
if(!target) | ||
return 0 | ||
var/obj/effect/proc_holder/spell/spell = target | ||
|
||
if(usr) | ||
return spell.can_cast(usr) | ||
else | ||
if(owner) | ||
return spell.can_cast(owner) | ||
return 1 | ||
|
||
/datum/action/spell_action/CheckRemoval() | ||
if(owner.mind) | ||
if(target in owner.mind.spell_list) | ||
return 0 | ||
return !(target in owner.mob_spell_list) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.