mirror of
https://github.com/vgstation-coders/vgstation13.git
synced 2025-12-10 02:16:05 +00:00
* Beginning work on these
* Area set
* Including
* Indent fix
* Should fix
* Tweaks
* Go through walls hopefully now
* Properly
* Now they can leave
* Indent
* Actual indent
* More stuff
* Moving this out
* How
* Living checks too so it doesn't get ghosts
* Somehow I forget ..()
* Tweaks, hopefully makes powernet visible
* Some new stuff and tweaks
* Role and objectives, plus moving this to role anyways
* Attempt at the ruleset now
* Moving update here, might help
* Indent
* Proper path
* Better logic
* Sanity
* Fixes?
* Proper logo and formatting
* Making this less of a fixed amount
!
* Typo
* Adding the actual ability to hijack an APC instead of automatically getting it
* Fixing format
* Reordering
* Maybe this?
* Placeholder health bar and etc.
* Beginning work on spells
* Actual file
* Actually spawns the lightning, plus weaker version of overload for the pulse demon to use
* Do it some other time
* No need for machines honestly
* Make these immune to environmental stuff
* Basis of a fun proc with fun ideas
* Bunch of fixes, no longer die in APC
* Fix for this last thing probably
* More sanity
* Move down to machine level for more fun
* Testing it with cameras
* Indentation doing it again
* Vision tweaks, bones of arcade fun
* Adding actual threat
* More arcade support
* Link it up
* Indents again
* Fix
* Actual spell icons
* Sanity
* Indenting AGAIN
* Maybe this
* Another try
* Bracket fix
* Bracket fix
* Maybe it's this
* More fixes and tidies
* Spell info
* Spell master for this
* Adds charge to HUD
* Max charge too
* Typo
* Now actually adds it
* Nicer format
* Stat panel
* Battery sucking in practice
* Typo fix and trailing return removed
* APC cells too
* Weapon possession
* Robot possession
* Robot possession actions
* Makes repossessing easier, TODO: Some method to de-compromise them
* Visible hijack feedback and sanity
* Emagging pulse demon spell
* More checks and clarification
* 2 new ones
* Type fix
* Draining tweaks
* More of them
* Makes spells drain charge on use, and unusable without enough charge
* Bones of spell purchasing, probably mostly finished by now
* More sanity and cleanliness
* Spell menu now works, some upgrades
* More stuff, tweaks
* Power buying now fully works
* Tile checking, nerfs shocking mobs
* Moving this back
* Two new powers
* Fixing icon states
* Compile fix
* Better icons
* Compile
* Basis for upgrades
* Neater menu
* This in here too
* Some functionality tweaks
* Nicer role location
* Reordering
* Icons for power menu
* Ability upgrades, better UI later
* Remove these for now, better system than this some other time
* Readding these, in better form
* Readding their descriptions too
* Max health one too
* Adds feedback on purchase
* Attempting fixing spells not being cast
* Proper icon
* Health UI updating
* Now all spells target properly
* Makes this show up right
* The rest too
* Typo
* Better user feedback
* Getting scoreboard
* Patching these out
* These hotkeys too
* Lot of fixes
* Should let them use doors too
* Gives this an objective
* Fixes the lightning
* Better sound
* Pulse demons can now hijack robot speech
* Old way again
* Making usr into user
* Logic fix
* Cut down lines
* Invert since now true
* Cuts down line length
* Syntax
* Health icon updating
* Proper indent
* This too
* Polishing attack, some nerfs
* Last tweaks
* Maybe now?
* Adds new role objective
* Proper client pref
* Latejoin ruleset too
* Adding admin role panel buttons for ease of use
* Nicer movement procs, and only on z1 cables spawned
* forceMove instead of forceEnter
* Makes these not a magic number
* Fixing runtime on latejoin and actually closes these windows
* Revert "Fixing runtime on latejoin and actually closes these windows"
This reverts commit 640b1a65ae.
* Fixing runtime
* This too
* Better like this
* Cell charger hijacking
* And it rigs the cell too!
* Just in case
* Fixes var type
* The basis of this
* Slows down if not on cable if can leave too
* Actual spell now
* Probably better
* Capitalises
* Period
* Spell icon for this
* Nicer system
* Removing last remnants of old one
* And this
* Disabling this for now, won't compile
* This goes too
* Makes this power actually work
* Converts these to a datum, easier to maintain
* Nicer system
* Usr lets us have this again I guess
* Comments and finishing touches
* Adds some pulse demon wail sounds
* And REMOVES the ones reaper generated in place to base these on
* More obvious death
* Last fix
Co-authored-by: kanef <kanef9x@protonmail.com>
371 lines
11 KiB
Plaintext
371 lines
11 KiB
Plaintext
/obj/abstract/screen/movable/spell_master
|
|
name = "Spells"
|
|
icon = 'icons/mob/screen_spells.dmi'
|
|
var/icon/override_icon
|
|
icon_state = "wiz_spell_ready"
|
|
var/list/obj/abstract/screen/spell/spell_objects = list()
|
|
var/showing = 0
|
|
globalscreen = 1
|
|
var/open_state = "master_open"
|
|
var/closed_state = "master_closed"
|
|
|
|
screen_loc = ui_spell_master
|
|
|
|
var/mob/spell_holder
|
|
var/length = 9
|
|
|
|
/obj/abstract/screen/movable/spell_master/Destroy()
|
|
..()
|
|
for(var/obj/abstract/screen/spell/spells in spell_objects)
|
|
spells.spellmaster = null
|
|
spell_objects = null
|
|
if(spell_holder)
|
|
spell_holder.spell_masters -= src
|
|
if(spell_holder.client && spell_holder.client.screen)
|
|
spell_holder.client.screen -= src
|
|
spell_holder = null
|
|
|
|
/obj/abstract/screen/movable/spell_master/MouseDrop()
|
|
if(showing)
|
|
return
|
|
|
|
return ..()
|
|
|
|
/obj/abstract/screen/movable/spell_master/MouseEntered(location,control,params)
|
|
openToolTip(usr,src,params,title = name,content = "Click and drag while closed to move this around the screen")
|
|
|
|
/obj/abstract/screen/movable/spell_master/MouseExited()
|
|
closeToolTip(usr)
|
|
|
|
/obj/abstract/screen/movable/spell_master/Click()
|
|
if(!spell_objects.len)
|
|
qdel(src)
|
|
return
|
|
|
|
toggle_open()
|
|
|
|
/obj/abstract/screen/movable/spell_master/proc/toggle_open(var/forced_state = 0)
|
|
if(showing && (forced_state != 2))
|
|
for(var/obj/abstract/screen/spell/O in spell_objects)
|
|
if(spell_holder && spell_holder.client)
|
|
spell_holder.client.screen -= O
|
|
O.handle_icon_updates = 0
|
|
showing = 0
|
|
overlays.len = 0
|
|
else if(forced_state != 1)
|
|
open_spellmaster()
|
|
update_spells(1)
|
|
showing = 1
|
|
overlays.len = 0
|
|
var/spellmaster_icon = null
|
|
if(override_icon && (override_icon != icon))
|
|
spellmaster_icon = image(icon = override_icon, icon_state = (showing ? open_state : closed_state))
|
|
else
|
|
spellmaster_icon = showing ? open_state : closed_state
|
|
overlays.Add(spellmaster_icon)
|
|
|
|
/obj/abstract/screen/movable/spell_master/proc/open_spellmaster()
|
|
var/list/screen_loc_xy = splittext(screen_loc,",")
|
|
|
|
//Create list of X offsets
|
|
var/list/screen_loc_X = splittext(screen_loc_xy[1],":")
|
|
var/x_position = decode_screen_X(screen_loc_X[1])
|
|
var/x_pix = screen_loc_X[2]
|
|
|
|
//Create list of Y offsets
|
|
var/list/screen_loc_Y = splittext(screen_loc_xy[2],":")
|
|
var/y_position = decode_screen_Y(screen_loc_Y[1])
|
|
var/y_pix = screen_loc_Y[2]
|
|
|
|
for(var/i = 1; i <= spell_objects.len; i++)
|
|
var/obj/abstract/screen/spell/S = spell_objects[i]
|
|
var/xpos = x_position + (x_position < (world.view+1) ? 1 : -1)*(i%length)
|
|
var/ypos = y_position + (y_position < (world.view+1) ? round(i/length) : -round(i/length))
|
|
S.screen_loc = "[encode_screen_X(xpos)]:[x_pix],[encode_screen_Y(ypos)]:[y_pix]"
|
|
if(spell_holder && spell_holder.client)
|
|
spell_holder.client.screen += S
|
|
S.handle_icon_updates = 1
|
|
|
|
/obj/abstract/screen/movable/spell_master/proc/add_spell(var/spell/spell)
|
|
if(!spell)
|
|
return
|
|
|
|
if(spell.connected_button) //we have one already, for some reason
|
|
if(spell.connected_button in spell_objects)
|
|
return
|
|
else
|
|
spell_objects.Add(spell.connected_button)
|
|
toggle_open(2)
|
|
return
|
|
|
|
if(spell.spell_flags & NO_BUTTON) //no button to add if we don't get one
|
|
return
|
|
|
|
var/obj/abstract/screen/spell/newscreen = new /obj/abstract/screen/spell
|
|
newscreen.spellmaster = src
|
|
newscreen.spell = spell
|
|
newscreen.icon = src.icon
|
|
newscreen.icon_state = src.icon_state
|
|
|
|
spell.connected_button = newscreen
|
|
|
|
if(!spell.override_base) //if it's not set, we do basic checks
|
|
if(spell.spell_flags & CONSTRUCT_CHECK)
|
|
newscreen.spell_base = "const" //construct spells
|
|
else
|
|
newscreen.spell_base = "wiz" //wizard spells
|
|
else
|
|
newscreen.spell_base = spell.override_base
|
|
newscreen.name = spell.name
|
|
newscreen.update_charge(1)
|
|
spell_objects.Add(newscreen)
|
|
toggle_open(2) //forces the icons to refresh on screen
|
|
|
|
/obj/abstract/screen/movable/spell_master/mech/add_spell(var/spell/mech/MS)
|
|
..()
|
|
var/mechaIcon = MS.linked_mech.initial_icon
|
|
open_state = "[mechaIcon]-open"
|
|
closed_state = "[mechaIcon]"
|
|
//Force it to be open
|
|
toggle_open(2)
|
|
|
|
/obj/abstract/screen/movable/spell_master/proc/remove_spell(var/spell/spell)
|
|
qdel(spell.connected_button)
|
|
|
|
spell.connected_button = null
|
|
|
|
if(spell_objects?.len)
|
|
toggle_open(showing + 1)
|
|
else
|
|
qdel(src)
|
|
|
|
/obj/abstract/screen/movable/spell_master/proc/silence_spells(var/amount)
|
|
for(var/obj/abstract/screen/spell/spell in spell_objects)
|
|
spell.spell.silenced = amount
|
|
spell.update_charge(1)
|
|
|
|
/obj/abstract/screen/movable/spell_master/proc/update_spells(forced = 0, mob/user)
|
|
if(user && user.client)
|
|
if(!(src in user.client.screen))
|
|
user.client.screen += src
|
|
for(var/obj/abstract/screen/spell/spell in spell_objects)
|
|
spell.update_charge(forced)
|
|
|
|
/obj/abstract/screen/movable/spell_master/proc/on_holder_death(mob/user)
|
|
for(var/obj/abstract/screen/spell/spell in spell_objects)
|
|
spell.spell.on_holder_death(user)
|
|
|
|
|
|
/obj/abstract/screen/movable/spell_master/genetic
|
|
name = "Mutant Powers"
|
|
icon_state = "genetic_spell_ready"
|
|
|
|
open_state = "genetics_open"
|
|
closed_state = "genetics_closed"
|
|
|
|
screen_loc = ui_genetic_master
|
|
|
|
/obj/abstract/screen/movable/spell_master/alien
|
|
name = "Alien Abilities"
|
|
icon_state = "alien_spell_ready"
|
|
|
|
open_state = "alien_open"
|
|
closed_state = "alien_closed"
|
|
|
|
screen_loc = ui_alien_master
|
|
length = 9
|
|
|
|
/obj/abstract/screen/movable/spell_master/malf
|
|
name = "Malfunction Modules"
|
|
icon_state = "malf_spell_ready"
|
|
|
|
open_state = "malf_open"
|
|
closed_state = "malf_closed"
|
|
|
|
screen_loc = ui_alien_master
|
|
|
|
/obj/abstract/screen/movable/spell_master/racial
|
|
name = "Racial Abilities"
|
|
icon_state = "racial_spell_ready"
|
|
|
|
open_state = "genetics_open"
|
|
closed_state = "genetics_closed"
|
|
|
|
screen_loc = ui_racial_master
|
|
|
|
/obj/abstract/screen/movable/spell_master/time
|
|
name = "Time Powers"
|
|
icon_state = "time_spell_ready"
|
|
|
|
open_state = "time_open"
|
|
closed_state = "time_closed"
|
|
|
|
screen_loc = ui_alien_master
|
|
|
|
/obj/abstract/screen/movable/spell_master/bloodcult
|
|
name = "Blood Magic"
|
|
icon_state = "cult_spell_ready"
|
|
|
|
open_state = "cult_open"
|
|
closed_state = "cult_closed"
|
|
|
|
/obj/abstract/screen/movable/spell_master/spider
|
|
name = "Spider"
|
|
icon_state = "spider_spell_ready"
|
|
|
|
open_state = "spider_open"
|
|
closed_state = "spider_closed"
|
|
|
|
/obj/abstract/screen/movable/spell_master/mech
|
|
name = "Mech Modules"
|
|
icon_state = "mech_spell_ready"
|
|
icon = 'icons/mecha/mecha_equipment.dmi'
|
|
|
|
//open and close states are defined later
|
|
override_icon = 'icons/mecha/mecha.dmi'
|
|
screen_loc = ui_alien_master
|
|
|
|
/obj/abstract/screen/movable/spell_master/changeling
|
|
name = "Changeling Abilities"
|
|
icon_state = "changeling_spell_ready"
|
|
|
|
open_state = "ling-open"
|
|
closed_state = "ling-closed"
|
|
|
|
screen_loc = ui_alien_master
|
|
|
|
/obj/abstract/screen/movable/spell_master/pulse_demon
|
|
name = "Pulse Demon Abilities"
|
|
icon_state = "pulsedemon_spell_ready"
|
|
|
|
open_state = "pd_open"
|
|
closed_state = "pd_closed"
|
|
|
|
screen_loc = ui_alien_master
|
|
|
|
//////////////ACTUAL SPELLS//////////////
|
|
//This is what you click to cast things//
|
|
/////////////////////////////////////////
|
|
/obj/abstract/screen/spell
|
|
icon = 'icons/mob/screen_spells.dmi'
|
|
icon_state = "wiz_spell_base"
|
|
var/spell_base = "wiz"
|
|
var/last_charge = 0 //not a time, but the last remembered charge value
|
|
globalscreen = 1
|
|
var/spell/spell = null
|
|
var/handle_icon_updates = 0
|
|
var/obj/abstract/screen/movable/spell_master/spellmaster
|
|
|
|
var/icon/last_charged_icon
|
|
var/channeling_image
|
|
|
|
/obj/abstract/screen/spell/MouseEntered(location,control,params)
|
|
if(!spell)
|
|
return
|
|
var/dat = ""
|
|
if(spell.charge_type & Sp_RECHARGE)
|
|
dat += "<br>Cooldown: [spell.charge_max/10] second\s"
|
|
if(spell.charge_type & Sp_CHARGES)
|
|
dat += "<br>Has [spell.charge_counter] charge\s left"
|
|
if(spell.charge_type & Sp_HOLDVAR)
|
|
dat += "<br>Requires [spell.holder_var_amount] [spell.holder_var_type]"
|
|
switch(spell.range)
|
|
if(1)
|
|
dat += "<br>Range: Adjacency"
|
|
if(2 to INFINITY)
|
|
dat += "<br>Range: [spell.range]"
|
|
if(GLOBALCAST)
|
|
dat += "<br>Range: Global"
|
|
if(SELFCAST)
|
|
dat += "<br>Range: Self"
|
|
if(spell.desc)
|
|
dat += "<br>Desc: [spell.desc]"
|
|
openToolTip(usr,src,params,title = name,content = dat)
|
|
|
|
/obj/abstract/screen/spell/MouseExited()
|
|
closeToolTip(usr)
|
|
|
|
/obj/abstract/screen/spell/Destroy()
|
|
..()
|
|
spell = null
|
|
last_charged_icon = null
|
|
if(spellmaster)
|
|
spellmaster.spell_objects -= src
|
|
if(spellmaster.spell_holder && spellmaster.spell_holder.client)
|
|
spellmaster.spell_holder.client.screen -= src
|
|
remove_channeling()
|
|
if(spellmaster && !spellmaster.spell_objects.len)
|
|
qdel(spellmaster)
|
|
spellmaster = null
|
|
|
|
/obj/abstract/screen/spell/proc/update_charge(var/forced_update = 0)
|
|
if(!spell)
|
|
qdel(src)
|
|
return
|
|
|
|
if((last_charge == spell.charge_counter || !handle_icon_updates) && !forced_update)
|
|
return //nothing to see here
|
|
|
|
var/spell_icon = null
|
|
if(spell.override_icon && (spell.override_icon != icon))
|
|
spell_icon = image(icon = spell.override_icon, icon_state = spell.hud_state, dir = spell.icon_direction)
|
|
else
|
|
spell_icon = spell.hud_state
|
|
overlays -= spell_icon
|
|
|
|
if((spell.charge_type & Sp_RECHARGE) || (spell.charge_type & Sp_CHARGES) || (spell.charge_type & Sp_GRADUAL))
|
|
if(spell.charge_counter < spell.charge_max)
|
|
icon_state = "[spell_base]_spell_base"
|
|
if(spell.charge_counter > 0)
|
|
var/icon/partial_charge = icon(src.icon, "[spell_base]_spell_ready")
|
|
partial_charge.Crop(1, 1, partial_charge.Width(), round(partial_charge.Height() * spell.charge_counter / spell.charge_max))
|
|
overlays += partial_charge
|
|
if(last_charged_icon)
|
|
overlays -= last_charged_icon
|
|
last_charged_icon = partial_charge
|
|
else if(last_charged_icon)
|
|
overlays -= last_charged_icon
|
|
last_charged_icon = null
|
|
else
|
|
icon_state = "[spell_base]_spell_ready"
|
|
if(last_charged_icon)
|
|
overlays -= last_charged_icon
|
|
else
|
|
icon_state = "[spell_base]_spell_ready"
|
|
overlays += spell_icon
|
|
|
|
last_charge = spell.charge_counter
|
|
|
|
overlays -= image(icon = icon, icon_state = "silence")
|
|
if(spell.silenced)
|
|
overlays += image(icon = icon, icon_state = "silence")
|
|
|
|
/obj/abstract/screen/spell/Click(location, control, params)
|
|
if(!usr || !spell)
|
|
qdel(src)
|
|
return
|
|
|
|
if(usr.is_pacified() && (spell.spell_flags & IS_HARMFUL))
|
|
to_chat(usr, "<span class='notice'>You really don't feel like casting that spell right now...</span>")
|
|
return
|
|
|
|
var/list/param_list = params2list(params)
|
|
if(param_list["middle"])
|
|
if(spell.on_right_click(usr))
|
|
return
|
|
|
|
spell.perform(usr)
|
|
update_charge(1)
|
|
|
|
//Helper proc, does not remove channeling
|
|
/obj/abstract/screen/spell/proc/add_channeling()
|
|
var/image/channel = image(icon = icon, loc = src, icon_state = "channeled", layer = src.layer + 1)
|
|
channeling_image = channel
|
|
if(spellmaster && spellmaster.spell_holder && spellmaster.spell_holder.client)
|
|
spellmaster.spell_holder.client.images += channeling_image
|
|
|
|
/obj/abstract/screen/spell/proc/remove_channeling()
|
|
if(spellmaster && spellmaster.spell_holder && spellmaster.spell_holder.client)
|
|
spellmaster.spell_holder.client.images -= channeling_image
|
|
channeling_image = null
|