diff --git a/code/datums/spell.dm b/code/datums/spell.dm index 37571f35e44..251e401a957 100644 --- a/code/datums/spell.dm +++ b/code/datums/spell.dm @@ -1,6 +1,9 @@ -var/list/spells = typesof(/obj/spell) //needed for the badmin verb for now +/obj/proc_holder + var/panel = "Debug"//What panel the proc holder needs to go on. -/obj/spell +var/list/spells = typesof(/obj/proc_holder/spell) //needed for the badmin verb for now + +/obj/proc_holder/spell name = "Spell" desc = "A wizard spell" density = 0 @@ -28,7 +31,7 @@ var/list/spells = typesof(/obj/spell) //needed for the badmin verb for now var/smoke_spread = 0 //1 - harmless, 2 - harmful var/smoke_amt = 0 //cropped at 10 -/obj/spell/proc/cast_check(skipcharge = 0,mob/user = usr) //checks if the spell can be cast based on its settings; skipcharge is used when an additional cast_check is called inside the spell +/obj/proc_holder/spell/proc/cast_check(skipcharge = 0,mob/user = usr) //checks if the spell can be cast based on its settings; skipcharge is used when an additional cast_check is called inside the spell if(!(src in usr.spell_list)) usr << "\red You shouldn't have this spell! Something's wrong." @@ -69,7 +72,7 @@ var/list/spells = typesof(/obj/spell) //needed for the badmin verb for now return 1 -/obj/spell/proc/invocation(mob/user = usr) //spelling the spell out and setting it on recharge/reducing charges amount +/obj/proc_holder/spell/proc/invocation(mob/user = usr) //spelling the spell out and setting it on recharge/reducing charges amount switch(invocation_type) if("shout") @@ -81,12 +84,12 @@ var/list/spells = typesof(/obj/spell) //needed for the badmin verb for now if("whisper") usr.whisper(invocation) -/obj/spell/New() +/obj/proc_holder/spell/New() ..() charge_counter = charge_max -/obj/spell/Click() +/obj/proc_holder/spell/Click() ..() if(!cast_check()) @@ -94,15 +97,15 @@ var/list/spells = typesof(/obj/spell) //needed for the badmin verb for now choose_targets() -/obj/spell/proc/choose_targets(mob/user = usr) //depends on subtype - /targeted or /aoe_turf +/obj/proc_holder/spell/proc/choose_targets(mob/user = usr) //depends on subtype - /targeted or /aoe_turf return -/obj/spell/proc/start_recharge() +/obj/proc_holder/spell/proc/start_recharge() while(charge_counter < charge_max) sleep(1) charge_counter++ -/obj/spell/proc/perform(list/targets, recharge = 1) //if recharge is started is important for the trigger spells +/obj/proc_holder/spell/proc/perform(list/targets, recharge = 1) //if recharge is started is important for the trigger spells before_cast(targets) invocation() spawn(0) @@ -111,7 +114,7 @@ var/list/spells = typesof(/obj/spell) //needed for the badmin verb for now cast(targets) after_cast(targets) -/obj/spell/proc/before_cast(list/targets) +/obj/proc_holder/spell/proc/before_cast(list/targets) if(overlay) for(var/atom/target in targets) var/location @@ -127,7 +130,7 @@ var/list/spells = typesof(/obj/spell) //needed for the badmin verb for now spawn(overlay_lifespan) del(spell) -/obj/spell/proc/after_cast(list/targets) +/obj/proc_holder/spell/proc/after_cast(list/targets) for(var/atom/target in targets) var/location if(istype(target,/mob)) @@ -150,10 +153,10 @@ var/list/spells = typesof(/obj/spell) //needed for the badmin verb for now smoke.set_up(smoke_amt, 0, location) //no idea what the 0 is smoke.start() -/obj/spell/proc/cast(list/targets) +/obj/proc_holder/spell/proc/cast(list/targets) return -/obj/spell/proc/revert_cast() //resets recharge or readds a charge +/obj/proc_holder/spell/proc/revert_cast() //resets recharge or readds a charge switch(charge_type) if("recharge") charge_counter = charge_max @@ -163,15 +166,15 @@ var/list/spells = typesof(/obj/spell) //needed for the badmin verb for now return -/obj/spell/targeted //can mean aoe for mobs (limited/unlimited number) or one target mob +/obj/proc_holder/spell/targeted //can mean aoe for mobs (limited/unlimited number) or one target mob var/max_targets = 1 //leave 0 for unlimited targets in range, 1 for one selectable target in range, more for limited number of casts (can all target one guy, depends on target_ignore_prev) in range var/target_ignore_prev = 1 //only important if max_targets > 1, affects if the spell can be cast multiple times at one person from one cast var/include_user = 0 //if it includes usr in the target list -/obj/spell/aoe_turf //affects all turfs in view or range (depends) +/obj/proc_holder/spell/aoe_turf //affects all turfs in view or range (depends) var/inner_radius = -1 //for all your ring spell needs -/obj/spell/targeted/choose_targets(mob/user = usr) +/obj/proc_holder/spell/targeted/choose_targets(mob/user = usr) var/list/targets = list() switch(selection_type) @@ -239,7 +242,7 @@ var/list/spells = typesof(/obj/spell) //needed for the badmin verb for now return -/obj/spell/aoe_turf/choose_targets(mob/user = usr) +/obj/proc_holder/spell/aoe_turf/choose_targets(mob/user = usr) var/list/targets = list() switch(selection_type) diff --git a/code/datums/spells/area_teleport.dm b/code/datums/spells/area_teleport.dm index 138a02ed5bc..cda227aa7a8 100644 --- a/code/datums/spells/area_teleport.dm +++ b/code/datums/spells/area_teleport.dm @@ -1,11 +1,11 @@ -/obj/spell/targeted/area_teleport +/obj/proc_holder/spell/targeted/area_teleport name = "Area teleport" desc = "This spell teleports you to a type of area of your selection." var/randomise_selection = 0 //if it lets the usr choose the teleport loc or picks it from the list var/invocation_area = 1 //if the invocation appends the selected area -/obj/spell/targeted/area_teleport/perform(list/targets, recharge = 1) +/obj/proc_holder/spell/targeted/area_teleport/perform(list/targets, recharge = 1) var/thearea = before_cast(targets) if(!thearea || !cast_check(1)) revert_cast() @@ -17,7 +17,7 @@ cast(targets,thearea) after_cast(targets) -/obj/spell/targeted/area_teleport/before_cast(list/targets) +/obj/proc_holder/spell/targeted/area_teleport/before_cast(list/targets) var/A = null if(!randomise_selection) @@ -29,7 +29,7 @@ return thearea -/obj/spell/targeted/area_teleport/cast(list/targets,area/thearea) +/obj/proc_holder/spell/targeted/area_teleport/cast(list/targets,area/thearea) for(var/mob/target in targets) var/list/L = list() for(var/turf/T in get_area_turfs(thearea.type)) @@ -46,7 +46,7 @@ return -/obj/spell/targeted/area_teleport/invocation(area/chosenarea = null) +/obj/proc_holder/spell/targeted/area_teleport/invocation(area/chosenarea = null) if(!invocation_area || !chosenarea) ..() else diff --git a/code/datums/spells/conjure.dm b/code/datums/spells/conjure.dm index 731521e4c6b..ce3fb01fbf0 100644 --- a/code/datums/spells/conjure.dm +++ b/code/datums/spells/conjure.dm @@ -1,4 +1,4 @@ -/obj/spell/aoe_turf/conjure +/obj/proc_holder/spell/aoe_turf/conjure name = "Conjure" desc = "This spell conjures objs of the specified types in range." @@ -9,7 +9,7 @@ var/summon_ignore_prev_spawn_points = 0 //if set to 1, each new object is summoned on a new spawn point /* -/obj/spell/conjure +/obj/proc_holder/spell/conjure name = "Summon Bigger Carp" desc = "This spell conjures an elite carp." @@ -25,7 +25,7 @@ var/summon_ignore_density = 0 //if set to 1, adds dense tiles to possible spawn places var/summon_ignore_prev_spawn_points = 0 //if set to 1, each new object is summoned on a new spawn point */ -/obj/spell/aoe_turf/conjure/cast(list/targets) +/obj/proc_holder/spell/aoe_turf/conjure/cast(list/targets) for(var/turf/T in targets) if(T.density && !summon_ignore_density) diff --git a/code/datums/spells/emplosion.dm b/code/datums/spells/emplosion.dm index 1d358865caa..794df4f78d7 100644 --- a/code/datums/spells/emplosion.dm +++ b/code/datums/spells/emplosion.dm @@ -1,11 +1,11 @@ -/obj/spell/targeted/emplosion +/obj/proc_holder/spell/targeted/emplosion name = "Emplosion" desc = "This spell emplodes an area." var/emp_heavy = 2 var/emp_light = 3 -/obj/spell/targeted/emplosion/cast(list/targets) +/obj/proc_holder/spell/targeted/emplosion/cast(list/targets) for(var/mob/target in targets) empulse(target.loc, emp_heavy, emp_light) diff --git a/code/datums/spells/ethereal_jaunt.dm b/code/datums/spells/ethereal_jaunt.dm index 1a5c47370a9..9d543f69d0c 100644 --- a/code/datums/spells/ethereal_jaunt.dm +++ b/code/datums/spells/ethereal_jaunt.dm @@ -1,4 +1,4 @@ -/obj/spell/targeted/ethereal_jaunt +/obj/proc_holder/spell/targeted/ethereal_jaunt name = "Ethereal Jaunt" desc = "This spell creates your ethereal form, temporarily making you invisible and able to pass through walls." @@ -12,7 +12,7 @@ var/jaunt_duration = 50 //in deciseconds -/obj/spell/targeted/ethereal_jaunt/cast(list/targets) //magnets, so mostly hardcoded +/obj/proc_holder/spell/targeted/ethereal_jaunt/cast(list/targets) //magnets, so mostly hardcoded for(var/mob/target in targets) spawn(0) var/mobloc = get_turf(target.loc) diff --git a/code/datums/spells/explosion.dm b/code/datums/spells/explosion.dm index 96e02e6899a..a6d20291f25 100644 --- a/code/datums/spells/explosion.dm +++ b/code/datums/spells/explosion.dm @@ -1,4 +1,4 @@ -/obj/spell/targeted/explosion +/obj/proc_holder/spell/targeted/explosion name = "Explosion" desc = "This spell explodes an area." @@ -7,7 +7,7 @@ var/ex_light = 3 var/ex_flash = 4 -/obj/spell/targeted/explosion/cast(list/targets) +/obj/proc_holder/spell/targeted/explosion/cast(list/targets) for(var/mob/target in targets) explosion(target.loc,ex_severe,ex_heavy,ex_light,ex_flash) diff --git a/code/datums/spells/genetic.dm b/code/datums/spells/genetic.dm index 394c4797c04..94950fcc66d 100644 --- a/code/datums/spells/genetic.dm +++ b/code/datums/spells/genetic.dm @@ -1,4 +1,4 @@ -/obj/spell/targeted/genetic +/obj/proc_holder/spell/targeted/genetic name = "Genetic" desc = "This spell inflicts a set of mutations and disabilities upon the target." @@ -22,7 +22,7 @@ 6th bit - fat */ -/obj/spell/targeted/genetic/cast(list/targets) +/obj/proc_holder/spell/targeted/genetic/cast(list/targets) for(var/mob/target in targets) target.mutations |= mutations diff --git a/code/datums/spells/inflict_handler.dm b/code/datums/spells/inflict_handler.dm index 072e3720832..e2e5e0cf1cc 100644 --- a/code/datums/spells/inflict_handler.dm +++ b/code/datums/spells/inflict_handler.dm @@ -1,4 +1,4 @@ -/obj/spell/targeted/inflict_handler +/obj/proc_holder/spell/targeted/inflict_handler name = "Inflict Handler" desc = "This spell blinds and/or destroys/damages/heals and/or weakens/stuns the target." @@ -16,7 +16,7 @@ var/destroys = "none" //can be "none", "gib" or "disintegrate" -/obj/spell/targeted/inflict_handler/cast(list/targets) +/obj/proc_holder/spell/targeted/inflict_handler/cast(list/targets) for(var/mob/living/target in targets) switch(destroys) diff --git a/code/datums/spells/knock.dm b/code/datums/spells/knock.dm index dafa286f919..b1da996e174 100644 --- a/code/datums/spells/knock.dm +++ b/code/datums/spells/knock.dm @@ -1,4 +1,4 @@ -/obj/spell/aoe_turf/knock +/obj/proc_holder/spell/aoe_turf/knock name = "Knock" desc = "This spell opens nearby doors and does not require wizard garb." @@ -9,7 +9,7 @@ invocation_type = "whisper" range = 3 -/obj/spell/aoe_turf/knock/cast(list/targets) +/obj/proc_holder/spell/aoe_turf/knock/cast(list/targets) for(var/turf/T in targets) for(var/obj/machinery/door/door in T.contents) spawn(1) diff --git a/code/datums/spells/mind_transfer.dm b/code/datums/spells/mind_transfer.dm index 6f175562211..93369b568cb 100644 --- a/code/datums/spells/mind_transfer.dm +++ b/code/datums/spells/mind_transfer.dm @@ -1,4 +1,4 @@ -/obj/spell/targeted/mind_transfer +/obj/proc_holder/spell/targeted/mind_transfer name = "Mind Transfer" desc = "This spell allows the user to switch bodies with a target." @@ -17,7 +17,7 @@ var/paralysis_amount_caster = 20 //how much the caster is paralysed for after the spell var/paralysis_amount_victim = 20 //how much the victim is paralysed for after the spell -/obj/spell/targeted/mind_transfer/cast(list/targets,mob/user = usr) //magnets, so mostly hardcoded +/obj/proc_holder/spell/targeted/mind_transfer/cast(list/targets,mob/user = usr) //magnets, so mostly hardcoded if(!targets.len) user << "No mind found" return diff --git a/code/datums/spells/projectile.dm b/code/datums/spells/projectile.dm index 1f6fd42800d..efcfca2f3c9 100644 --- a/code/datums/spells/projectile.dm +++ b/code/datums/spells/projectile.dm @@ -1,4 +1,4 @@ -/obj/spell/targeted/projectile +/obj/proc_holder/spell/targeted/projectile name = "Projectile" desc = "This spell summons projectiles which try to hit the targets." @@ -11,7 +11,7 @@ var/proj_trail_icon = 'wizard.dmi' var/proj_trail_icon_state = "trail" - var/proj_type = "/obj/spell/targeted" //IMPORTANT use only subtypes of this + var/proj_type = "/obj/proc_holder/spell/targeted" //IMPORTANT use only subtypes of this var/proj_lingering = 0 //if it lingers or disappears upon hitting an obstacle var/proj_homing = 1 //if it follows the target @@ -21,16 +21,16 @@ var/proj_lifespan = 15 //in deciseconds * proj_step_delay var/proj_step_delay = 1 //lower = faster -/obj/spell/targeted/projectile/cast(list/targets, mob/user = usr) +/obj/proc_holder/spell/targeted/projectile/cast(list/targets, mob/user = usr) for(var/mob/target in targets) spawn(0) - var/obj/spell/targeted/projectile + var/obj/proc_holder/spell/targeted/projectile if(istext(proj_type)) var/projectile_type = text2path(proj_type) projectile = new projectile_type(user) - if(istype(proj_type,/obj/spell)) - projectile = new /obj/spell/targeted/trigger(user) + if(istype(proj_type,/obj/proc_holder/spell)) + projectile = new /obj/proc_holder/spell/targeted/trigger(user) projectile:linked_spells += proj_type projectile.icon = proj_icon projectile.icon_state = proj_icon_state diff --git a/code/datums/spells/trigger.dm b/code/datums/spells/trigger.dm index 6aed5cb2a56..232e2f5603f 100644 --- a/code/datums/spells/trigger.dm +++ b/code/datums/spells/trigger.dm @@ -1,28 +1,28 @@ -/obj/spell/targeted/trigger +/obj/proc_holder/spell/targeted/trigger name = "Trigger" desc = "This spell triggers another spell or a few." var/list/linked_spells = list() //those are just referenced by the trigger spell and are unaffected by it directly var/list/starting_spells = list() //those are added on New() to contents from default spells and are deleted when the trigger spell is deleted to prevent memory leaks -/obj/spell/targeted/trigger/New() +/obj/proc_holder/spell/targeted/trigger/New() ..() for(var/spell in starting_spells) var/spell_to_add = text2path(spell) new spell_to_add(src) //should result in adding to contents, needs testing -/obj/spell/targeted/trigger/Del() +/obj/proc_holder/spell/targeted/trigger/Del() for(var/spell in contents) del(spell) ..() -/obj/spell/targeted/trigger/cast(list/targets) +/obj/proc_holder/spell/targeted/trigger/cast(list/targets) for(var/mob/target in targets) - for(var/obj/spell/spell in contents) + for(var/obj/proc_holder/spell/spell in contents) spell.perform(list(target),0) - for(var/obj/spell/spell in linked_spells) + for(var/obj/proc_holder/spell/spell in linked_spells) spell.perform(list(target),0) return \ No newline at end of file diff --git a/code/datums/spells/turf_teleport.dm b/code/datums/spells/turf_teleport.dm index 49d3d6a5952..bfa6ddd5d93 100644 --- a/code/datums/spells/turf_teleport.dm +++ b/code/datums/spells/turf_teleport.dm @@ -1,4 +1,4 @@ -/obj/spell/targeted/turf_teleport +/obj/proc_holder/spell/targeted/turf_teleport name = "Turf Teleport" desc = "This spell teleports the target to the turf in range." @@ -8,7 +8,7 @@ var/include_space = 0 //whether it includes space tiles in possible teleport locations var/include_dense = 0 //whether it includes dense tiles in possible teleport locations -/obj/spell/targeted/turf_teleport/cast(list/targets) +/obj/proc_holder/spell/targeted/turf_teleport/cast(list/targets) for(var/mob/target in targets) var/list/turfs = new/list() for(var/turf/T in range(target,outer_tele_radius)) diff --git a/code/datums/spells/wizard.dm b/code/datums/spells/wizard.dm index ec504dac74c..cbf223e2ee0 100644 --- a/code/datums/spells/wizard.dm +++ b/code/datums/spells/wizard.dm @@ -1,4 +1,4 @@ -/obj/spell/targeted/projectile/magic_missile +/obj/proc_holder/spell/targeted/projectile/magic_missile name = "Magic Missile" desc = "This spell fires several, slow moving, magic projectiles at nearby targets." @@ -14,7 +14,7 @@ proj_icon_state = "magicm" proj_name = "a magic missile" proj_lingering = 1 - proj_type = "/obj/spell/targeted/inflict_handler/magic_missile" + proj_type = "/obj/proc_holder/spell/targeted/inflict_handler/magic_missile" proj_lifespan = 20 proj_step_delay = 5 @@ -23,11 +23,11 @@ proj_trail_lifespan = 5 proj_trail_icon_state = "magicmd" -/obj/spell/targeted/inflict_handler/magic_missile +/obj/proc_holder/spell/targeted/inflict_handler/magic_missile amt_weaken = 5 amt_dam_fire = 10 -/obj/spell/targeted/genetic/mutate +/obj/proc_holder/spell/targeted/genetic/mutate name = "Mutate" desc = "This spell causes you to turn into a hulk and gain telekinesis for a short while." @@ -43,7 +43,7 @@ mutations = 9 duration = 300 -/obj/spell/targeted/inflict_handler/disintegrate +/obj/proc_holder/spell/targeted/inflict_handler/disintegrate name = "Disintegrate" desc = "This spell instantly kills somebody adjacent to you with the vilest of magick." @@ -59,7 +59,7 @@ sparks_spread = 1 sparks_amt = 4 -/obj/spell/targeted/smoke +/obj/proc_holder/spell/targeted/smoke name = "Smoke" desc = "This spell spawns a cloud of choking smoke at your location and does not require wizard garb." @@ -74,7 +74,7 @@ smoke_spread = 2 smoke_amt = 10 -/obj/spell/targeted/emplosion/disable_tech +/obj/proc_holder/spell/targeted/emplosion/disable_tech name = "Disable Tech" desc = "This spell disables all weapons, cameras and most other technology in range." charge_max = 400 @@ -87,7 +87,7 @@ emp_heavy = 5 emp_light = 7 -/obj/spell/targeted/turf_teleport/blink +/obj/proc_holder/spell/targeted/turf_teleport/blink name = "Blink" desc = "This spell randomly teleports you a short distance." @@ -105,7 +105,7 @@ inner_tele_radius = 0 outer_tele_radius = 6 -/obj/spell/targeted/area_teleport/teleport +/obj/proc_holder/spell/targeted/area_teleport/teleport name = "Teleport" desc = "This spell teleports you to a type of area of your selection." @@ -120,7 +120,7 @@ smoke_spread = 1 smoke_amt = 5 -/obj/spell/aoe_turf/conjure/forcewall +/obj/proc_holder/spell/aoe_turf/conjure/forcewall name = "Forcewall" desc = "This spell creates an unbreakable wall that lasts for 30 seconds and does not need wizard garb." @@ -134,7 +134,7 @@ summon_type = list("/obj/forcefield") summon_lifespan = 300 -/obj/spell/aoe_turf/conjure/carp +/obj/proc_holder/spell/aoe_turf/conjure/carp name = "Summon Bigger Carp" desc = "This spell conjures an elite carp." @@ -147,7 +147,7 @@ summon_type = list("/obj/livestock/spesscarp/elite") -/obj/spell/targeted/trigger/blind +/obj/proc_holder/spell/targeted/trigger/blind name = "Blind" desc = "This spell temporarily blinds a single person and does not require wizard garb." @@ -158,17 +158,17 @@ invocation_type = "whisper" message = "\blue Your eyes cry out in pain!" - starting_spells = list("/obj/spell/targeted/inflict_handler/blind","/obj/spell/targeted/genetic/blind") + starting_spells = list("/obj/proc_holder/spell/targeted/inflict_handler/blind","/obj/proc_holder/spell/targeted/genetic/blind") -/obj/spell/targeted/inflict_handler/blind +/obj/proc_holder/spell/targeted/inflict_handler/blind amt_eye_blind = 10 amt_eye_blurry = 20 -/obj/spell/targeted/genetic/blind +/obj/proc_holder/spell/targeted/genetic/blind disabilities = 1 duration = 300 -/obj/spell/targeted/projectile/fireball +/obj/proc_holder/spell/targeted/projectile/fireball name = "Fireball" desc = "This spell fires a fireball at a target and does not require wizard garb." @@ -181,19 +181,19 @@ proj_icon_state = "fireball" proj_name = "a fireball" proj_lingering = 1 - proj_type = "/obj/spell/targeted/trigger/fireball" + proj_type = "/obj/proc_holder/spell/targeted/trigger/fireball" proj_lifespan = 200 proj_step_delay = 1 -/obj/spell/targeted/trigger/fireball - starting_spells = list("/obj/spell/targeted/inflict_handler/fireball","/obj/spell/targeted/explosion/fireball") +/obj/proc_holder/spell/targeted/trigger/fireball + starting_spells = list("/obj/proc_holder/spell/targeted/inflict_handler/fireball","/obj/proc_holder/spell/targeted/explosion/fireball") -/obj/spell/targeted/inflict_handler/fireball +/obj/proc_holder/spell/targeted/inflict_handler/fireball amt_dam_brute = 20 amt_dam_fire = 25 -/obj/spell/targeted/explosion/fireball +/obj/proc_holder/spell/targeted/explosion/fireball ex_severe = -1 ex_heavy = -1 ex_light = 2 diff --git a/code/defines/mob/mob.dm b/code/defines/mob/mob.dm index 16b5039c4ea..282753e90ef 100644 --- a/code/defines/mob/mob.dm +++ b/code/defines/mob/mob.dm @@ -162,8 +162,12 @@ var/voice_message = null // When you are not understood by others (replaced with just screeches, hisses, chimpers etc.) var/say_message = null // When you are understood by others. Currently only used by aliens and monkeys in their say_quote procs +//Generic list for proc holders. Only way I can see to enable certain verbs/procs. Should be modified if needed. + var/proc_holder_list[] = list()//Right now only displays for the AI. + //Also unlike the spell list, this would only store the object in contents, not an object in itself. + //Wizard mode, but can be used in other modes thanks to the brand new "Give Spell" badmin button - var/obj/spell/list/spell_list = list() + var/obj/proc_holder/spell/list/spell_list = list() //Monkey/infected mode var/list/resistances = list() diff --git a/code/defines/procs/helpers.dm b/code/defines/procs/helpers.dm index 8b425c6f886..5f1bed407dd 100644 --- a/code/defines/procs/helpers.dm +++ b/code/defines/procs/helpers.dm @@ -365,6 +365,22 @@ if(degree < 315) return WEST return NORTH|WEST +//Returns direction that the mob or whomever should be facing in relation to the target. +//This proc does not grant absolute direction and is mostly useful for 8dir sprite positioning. +//I personally used it with getline() to great effect. +/proc/get_dir_to(var/turf/start as turf,var/turf/end as turf)//N + var/xdiff = start.x - end.x//The sign is important. + var/ydiff = start.y - end.y + + var/direction_x = xdiff<1 ? 4:8//East - west + var/direction_y = ydiff<1 ? 1:2//North - south + var/direction_xy = xdiff==0 ? -4:0//If x is the same, subtract 4. + var/direction_yx = ydiff==0 ? -1:0//If y is the same, subtract 1. + var/direction_f = direction_x+direction_y+direction_xy+direction_yx//Finally direction tally. + direction_f = direction_f==0 ? 1:direction_f//If direction is 0(same spot), return north. Otherwise, direction. + + return direction_f + /proc/angle2text(var/degree) return dir2text(angle2dir(degree)) @@ -519,7 +535,11 @@ /proc/ainame(var/mob/M as mob) var/randomname = M.name + var/time_passed = world.time//Pretty basic but it'll do. It's still possible to bypass this by return ainame(). var/newname = input(M,"You are the AI. Would you like to change your name to something else?", "Name change",randomname) + if((world.time-time_passed)>200)//If more than 20 game seconds passed. + M << "You took too long to decide. Default name selected." + return if (length(newname) == 0) newname = randomname @@ -885,22 +905,23 @@ proc/GaussRand(var/sigma) proc/GaussRandRound(var/sigma,var/roundto) return round(GaussRand(sigma),roundto) -proc/anim(a,b,c,d,e) -//a is location, b is animation icon, c is the layer, d is the flick animation, e is sleep time (optional). -//Make sure that c actually has a layer or the game will run time error. - var/atom/movable/overlay/animation = new(a) - animation.icon = b - animation.icon_state = "blank" - animation.layer = c:layer+1//++ won't work right here. - animation.master = a - flick(d, animation) - if(e) - sleep(e) +proc/anim(turf/location as turf,target as mob|obj,a_icon,a_icon_state as text,flick_anim as text,sleeptime = 0,direction as num) +//This proc throws up either an icon or an animation for a specified amount of time. +//The variables should be apparent enough. + var/atom/movable/overlay/animation = new(location) + if(direction) + animation.dir = direction + animation.icon = a_icon + animation.layer = target:layer+1 + if(a_icon_state) + animation.icon_state = a_icon_state else - sleep(15) + animation.icon_state = "blank" + animation.master = target + flick(flick_anim, animation) + sleep(max(sleeptime, 15)) del(animation) - //returns list element or null. Should prevent "index out of bounds" error. proc/listgetindex(var/list/list,index) if(istype(list) && list.len) diff --git a/code/game/gamemodes/extra/ninja_abilities.dm b/code/game/gamemodes/extra/ninja_abilities.dm index 1001b8d0781..a401a0d9957 100644 --- a/code/game/gamemodes/extra/ninja_abilities.dm +++ b/code/game/gamemodes/extra/ninja_abilities.dm @@ -13,13 +13,13 @@ In the case that they are not, I imagine the game will run-time error like crazy */ //Cooldown ticks off each second based on the suit recharge proc, in seconds. Default of 1 seconds. Some abilities have no cool down. -/mob/proc/ninjacost(var/C as num,var/X as num) +/mob/proc/ninjacost(var/C = 0,var/X = 0) var/mob/living/carbon/human/U = src var/obj/item/clothing/suit/space/space_ninja/S = src:wear_suit - if(U.stat||U.incorporeal_move) - U << "\red You must be conscious and solid to do this." + if(U.stat||U.incorporeal_move&&X!=3)//Will not return if user is using an adrenaline booster since you can use them when stat==1. + U << "\red You must be conscious and solid to do this."//It's not a problem of stat==2 since the ninja will explode anyway if they die. return 1 - else if(C&&S.cell.chargeteleportation failed." @@ -385,7 +433,7 @@ Allows to gib up to five squares in a straight line. Seriously.*/ /mob/proc/ninjamirage() set name = "Spider Mirage" set desc = "Utilizes the internal VOID-shift device to create decoys and teleport behind a random target." - set category = "Ninja" + set category = "Ninja Ability" if(!ninjacost())//Simply checks for stat. var/obj/item/clothing/suit/space/space_ninja/S = src:wear_suit @@ -428,14 +476,14 @@ Allows to gib up to five squares in a straight line. Seriously.*/ var/turf/picked = locate(locx,locy,mobloc.z) spawn(0) playsound(loc, "sparks", 50, 1) - anim(mobloc,'mob.dmi',src,"phaseout") + anim(mobloc,src,'mob.dmi',,"phaseout") spawn(0) var/limit = 4 for(var/turf/T in oview(5)) if(prob(20)) spawn(0) - anim(T,'mob.dmi',src,"phasein") + anim(T,src,'mob.dmi',,"phasein") limit-- if(limit<=0) break @@ -446,7 +494,7 @@ Allows to gib up to five squares in a straight line. Seriously.*/ S.spark_system.start() playsound(loc, 'Deconstruct.ogg', 50, 1) playsound(loc, "sparks", 50, 1) - anim(loc,'mob.dmi',src,"phasein") + anim(loc,src,'mob.dmi',,"phasein") S.coold = 1 else src << "\red The VOID-shift device is malfunctioning, teleportation failed." diff --git a/code/game/gamemodes/extra/ninja_equipment.dm b/code/game/gamemodes/extra/ninja_equipment.dm index 39cdbe0b3b4..c0697dfa804 100644 --- a/code/game/gamemodes/extra/ninja_equipment.dm +++ b/code/game/gamemodes/extra/ninja_equipment.dm @@ -34,6 +34,7 @@ ________________________________________________________________________________ /obj/item/clothing/suit/space/space_ninja/proc/killai(var/mob/living/silicon/ai/A as mob) A << "\red Self-destruct protocol dete-- *bzzzzz*" + A << browse(null, "window=hack spideros") A.death()//Kill A.ghostize()//Turn into ghost del(AI) @@ -72,19 +73,23 @@ ________________________________________________________________________________ U.bruteloss += 1 A = 200 cell.charge-=A + if(U.stat)//If the ninja falls down, + active=0 if(cell.charge<0) if(kamikaze) U.say("I DIE TO LIVE AGAIN!") + U << browse(null, "window=spideros")//Just in case. U.death() return cell.charge=0 active=0 sleep(10)//Checks every second. + /obj/item/clothing/suit/space/space_ninja/proc/init() set name = "Initialize Suit" set desc = "Initializes the suit for field operation." - set category = "Object" + set category = "Ninja Equip" var/mob/living/carbon/human/U = usr if(U.mind&&U.mind.special_role=="Space Ninja"&&U:wear_suit==src&&!initialize) @@ -170,15 +175,13 @@ ________________________________________________________________________________ /obj/item/clothing/suit/space/space_ninja/proc/deinit() set name = "De-Initialize Suit" set desc = "Begins procedure to remove the suit." - set category = "Object" + set category = "Ninja Equip" if(!initialize) usr << "\red The suit is not initialized." return if(alert("Are you certain you wish to remove the suit? This will take time and remove all abilities.",,"Yes","No")=="No") return - if(!verbs.Find(/obj/item/clothing/suit/space/space_ninja/proc/spideros))//If the guy engaged kamikaze after clicking on deinit. - return var/mob/living/carbon/human/U = affecting verbs -= /obj/item/clothing/suit/space/space_ninja/proc/deinit @@ -269,7 +272,8 @@ ________________________________________________________________________________ /obj/item/clothing/suit/space/space_ninja/proc/spideros() set name = "Display SpiderOS" set desc = "Utilize built-in computer system." - set category = "Object" + set category = "Ninja Equip" + //set src in view()//To have it show up after AI gives back control. if(!affecting) return//If no mob is wearing the suit. I almost forgot about this variable. var/mob/living/carbon/human/U = affecting @@ -520,14 +524,14 @@ ________________________________________________________________________________ if("Stealth") if(active) spawn(0) - anim(U.loc,'mob.dmi',U,"uncloak") + anim(U.loc,U,'mob.dmi',,"uncloak") active=0 U << "\blue You are now visible." for(var/mob/O in oviewers(U, null)) O << "[U.name] appears from thin air!" else spawn(0) - anim(U.loc,'mob.dmi',U,"cloak") + anim(U.loc,U,'mob.dmi',,"cloak") active=1 U << "\blue You are now invisible to normal detection." for(var/mob/O in oviewers(U, null)) @@ -566,7 +570,7 @@ ________________________________________________________________________________ P.overlays += image('pda.dmi', "pda-r") if("Unlock Kamikaze") if(input(U)=="Divine Wind") - if( !(U.stat||U.wear_suit!=src||!initialize) ) + if( !(U.stat||U.wear_suit!=src||!initialize||cell.charge<=1) ) U << "\blue Engaging mode...\n\blackCODE NAME: \red KAMIKAZE" verbs -= /obj/item/clothing/suit/space/space_ninja/proc/spideros sleep(40) @@ -663,39 +667,74 @@ ________________________________________________________________________________ U << browse(null, "window=spideros") return if(confirm == "Yes") - if(A.laws_object.zeroth) - A << "\red WARNING: \black purge procedure detected. \n Now hacking host..." - A.control_disabled = 0 + if(A.laws_object.zeroth)//Gives a few seconds to re-upload the AI somewhere before it takes full control. + A << "\red WARNING: \black purge procedure detected. \nNow hacking host..." U << "\red WARNING: HACKING ATT--TEMPT IN PR0GRESsS!" spideros = 0 unlock = 0 - active = 0 - control = 0 - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/deinit - verbs -= /obj/item/clothing/suit/space/space_ninja/proc/spideros - A.verbs += /mob/living/silicon/ai/proc/ninja_spideros - A.verbs += /mob/living/silicon/ai/proc/ninja_return_control U << browse(null, "window=spideros") + spawn(40)//Unlimited window spawn works! + if(AI==A) + A << "Disconnecting neural interface..." + U << "\red WARNING: PRO0GRE--S 2&3%" + verbs -= /obj/item/clothing/suit/space/space_ninja/proc/deinit + verbs -= /obj/item/clothing/suit/space/space_ninja/proc/spideros + spawn(40) + if(AI==A) + A << "Shutting down external protocol..." + U << "\red WARNING: PPPFRRROGrESS 677^%" + active = 0 + spawn(40) + if(AI==A) + A << "Connecting to kernel..." + U << "\red WARNING: ER-RR04" + A.control_disabled = 0 + spawn(40) + A << "Connection established and secured. Menu updated." + U << "\red WARNING: #%@!!WEL4P54@" + control = 0 + var/obj/proc_holder/ai_return_control/A_C = new(A) + var/obj/proc_holder/ai_hack_ninja/B_C = new(A) + A.proc_holder_list += A_C + A.proc_holder_list += B_C + else + U << "\blue Hacking attempt disconnected. Resuming normal operation." + verbs += /obj/item/clothing/suit/space/space_ninja/proc/deinit + verbs += /obj/item/clothing/suit/space/space_ninja/proc/spideros + else + U << "\blue Hacking attempt disconnected. Resuming normal operation." + verbs += /obj/item/clothing/suit/space/space_ninja/proc/deinit + verbs += /obj/item/clothing/suit/space/space_ninja/proc/spideros + else + U << "\blue Hacking attempt disconnected. Resuming normal operation." return else flush = 1 A.suiciding = 1 A << "Your core files are being purged! This is the end..." + spawn(0) + spideros()//To refresh the screen and let this finish. while (A.stat != 2) A.oxyloss += 2 A.updatehealth() sleep(10) killai(A) + flush = 0 if("Wireless AI") var/mob/living/silicon/ai/A = locate(href_list["target"]) A.control_disabled = !A.control_disabled A << "AI wireless has been [A.control_disabled ? "disabled" : "enabled"]." spideros()//Refreshes the screen by calling it again (which replaces current screen with new screen). + else//If they are not in control. var/mob/living/silicon/ai/AI = usr - //While AI has control, the person can't take off the suit so checking here would be moot. + if(isnull(src))//If they AI dies/suit destroyed. + AI << browse(null, "window=hack spideros") + return + + var/obj/proc_holder/ai_hack_ninja/ninja_spideros = locate() in AI//What is the object granting access to proc? Find it. switch(href_list["choice"]) if("Close") @@ -706,13 +745,13 @@ ________________________________________________________________________________ if(spideros<=9) spideros=0 else - spideros = round(spideros/10)//Best way to do this, flooring to nearest integer. As an example, another way of doing it is attached below: - if("Shock") + spideros = round(spideros/10) + if("Shock")//DEBUG TEST var/damage = min(cell.charge, rand(50,150))//Uses either the current energy left over or between 50 and 150. - cell.charge -= damage if(damage>1)//So they don't spam it when energy is a factor. spark_system.start()//SPARKS THERE SHALL BE SPARKS - U.electrocute_act(damage, src, 0.1) + U.electrocute_act(damage, src,0.1,1)//The last argument is a safety for the human proc that checks for gloves. + cell.charge -= damage else AI << "\red ERROR: \black Not enough energy remaining." if("0")//Menus are numbers, see note above. 0 is the hub. @@ -734,7 +773,7 @@ ________________________________________________________________________________ return if(isnull(P)||P.toff)//So it doesn't freak out if the object no-longer exists. AI << "\red Error: unable to deliver message." - AI.ninja_spideros() + ninja_spideros.Click() return P.tnote += "← From [AI]:
[t]
"//Oh ai, u so silly if (!P.silent) @@ -779,10 +818,10 @@ ________________________________________________________________________________ U << "You feel a tiny prick and a sudden rush of liquid in to your veins." if("Radium") if((reagents.get_reagent_amount("radium"))<=60)//Special case. If there are only 60 radium units left. - AI << "\red Error: the suit cannot perform this function. Out of spaceacillin." + AI << "\red Error: the suit cannot perform this function. Out of radium." else reagents.reaction(U, 2) - reagents.trans_id_to(U, "spaceacillin", transfera) + reagents.trans_id_to(U, "radium", transfera) AI << "Injecting..." U << "You feel a tiny prick and a sudden rush of liquid in to your veins." if("Nutriment") @@ -793,7 +832,7 @@ ________________________________________________________________________________ reagents.trans_id_to(U, "nutriment", 5) AI << "Injecting..." U << "You feel a tiny prick and a sudden rush of substance in to your veins." - AI.ninja_spideros()//Calls spideros for AI. + ninja_spideros.Click()//Calls spideros for AI. return /obj/item/clothing/suit/space/space_ninja/examine() @@ -819,7 +858,7 @@ ________________________________________________________________________________ /obj/item/clothing/gloves/space_ninja/proc/toggled() set name = "Toggle Interaction" set desc = "Toggles special interaction on or off." - set category = "Object" + set category = "Ninja Equip" if(!candrain) candrain=1 usr << "You enable special interaction." @@ -832,7 +871,7 @@ ________________________________________________________________________________ /obj/item/clothing/gloves/space_ninja/proc/drain_wire() set name = "Drain From Wire" set desc = "Drain energy directly from an exposed wire." - set category = "Object" + set category = "Ninja Equip" var/obj/cable/attached var/mob/living/carbon/human/U = usr @@ -1089,7 +1128,7 @@ ________________________________________________________________________________ /obj/item/clothing/mask/gas/voice/space_ninja/proc/togglev() set name = "Toggle Voice" set desc = "Toggles the voice synthesizer on or off." - set category = "Object" + set category = "Ninja Equip" var/vchange = (alert("Would you like to synthesize a new name or turn off the voice synthesizer?",,"New Name","Turn Off")) if(vchange=="New Name") var/chance = rand(1,100) @@ -1132,7 +1171,7 @@ ________________________________________________________________________________ /obj/item/clothing/mask/gas/voice/space_ninja/proc/switchm() set name = "Switch Mode" set desc = "Switches between Night Vision, Meson, or Thermal vision modes." - set category = "Object" + set category = "Ninja Equip" //Have to reset these manually since life.dm is retarded like that. Go figure. switch(mode) if(1) @@ -1299,7 +1338,7 @@ The sprite for the net is kind of ugly but I couldn't come up with a better one. check-- sleep(10) - if(isnull(M))//If mob is gone. + if(isnull(M)||M.loc!=loc)//If mob is gone or not at the location. if(!isnull(master))//As long as they still exist. master << "\red ERROR: \black unable to locate [affecting]. Procedure terminated." del(src)//Get rid of the net. @@ -1309,9 +1348,11 @@ The sprite for the net is kind of ugly but I couldn't come up with a better one. //No need to check for countdown here since while() broke, it's implicit that it finished. spawn(0) playsound(M.loc, 'sparks4.ogg', 50, 1) - anim(M.loc,'mob.dmi',M,"phaseout") + anim(M.loc,M,'mob.dmi',,"phaseout") M.loc = pick(prisonwarp)//Throw mob in prison. + invisibility = 101//Make the net invisible so all the animations can play out. + health = INFINITY//Make the net invincible so that an explosion/something else won't kill it while, while() is running. spawn(0) var/datum/effects/system/spark_spread/spark_system = new /datum/effects/system/spark_spread() @@ -1319,7 +1360,7 @@ The sprite for the net is kind of ugly but I couldn't come up with a better one. spark_system.start() playsound(M.loc, 'Deconstruct.ogg', 50, 1) playsound(M.loc, 'sparks2.ogg', 50, 1) - anim(M.loc,'mob.dmi',M,"phasein") + anim(M.loc,M,'mob.dmi',,"phasein") del(src)//Wait for everything to finish, delete the net. Else it will stop everything once net is deleted, including the spawn(0). for(var/mob/O in viewers(src, 3)) diff --git a/code/game/gamemodes/extra/space_ninja.dm b/code/game/gamemodes/extra/space_ninja.dm index 85e654a1ba8..96cf70f30b6 100644 --- a/code/game/gamemodes/extra/space_ninja.dm +++ b/code/game/gamemodes/extra/space_ninja.dm @@ -95,25 +95,43 @@ mob/proc/create_ninja() //AI COUNTER HACKING=================================== -/mob/living/silicon/ai/proc/ninja_spideros() - set name = "Hack SpiderOS" - set desc = "Hack directly into the Black Widow(tm) neuro-interface." - set category = "AI Commands" +//I've tried a lot of stuff but adding verbs to the AI while inside an object, inside another object, did not want to work properly. +//This the best work-around I could come up with. Uses objects to then display to panel, based on the object spell system. +/obj/proc_holder/ai_hack_ninja//Generic proc holder to make sure the two verbs below work propely. + name = "Hack SpiderOS" + desc = "Hack directly into the Black Widow(tm) neuro-interface." + panel = "AI Hacking" + density = 0 + opacity = 0 - loc.loc:hack_spideros()//ninjasuit:hack_spideros() +/obj/proc_holder/ai_hack_ninja/Click()//When you click on it. + var/obj/item/clothing/suit/space/space_ninja/S = loc.loc//This is so stupid but makes sure certain things work. AI.SUIT + S.hack_spideros() + return -/mob/living/silicon/ai/proc/ninja_return_control() - set name = "Relinquish Control" - set desc = "Return control to the user." - set category = "AI Commands" +/obj/proc_holder/ai_return_control + name = "Relinquish Control" + desc = "Return control to the user." + panel = "AI Hacking" + density = 0 + opacity = 0 - src << browse(null, "window=hack spideros")//Close window - loc:control = 0//Return control - loc:affecting:verbs += /obj/item/clothing/suit/space/space_ninja/proc/deinit//Add back verbs - loc:affecting:verbs += /obj/item/clothing/suit/space/space_ninja/proc/spideros - verbs -= /mob/living/silicon/ai/proc/ninja_spideros - verbs -= /mob/living/silicon/ai/proc/ninja_return_control - loc:affecting << "UPDATE: [real_name] has seized hacking attempt. All systems clear." +/obj/proc_holder/ai_return_control/Click() + var/mob/living/silicon/ai/A = loc + var/obj/item/clothing/suit/space/space_ninja/S = A.loc + A << browse(null, "window=hack spideros")//Close window + S.control = 1//Return control + A << "You have seized your hacking attempt. [S.affecting] has regained control." + S.affecting << "UPDATE: [A.real_name] has seized hacking attempt. All systems clear." + var/obj/proc_holder/ai_return_control/A_C = locate() in A + var/obj/proc_holder/ai_hack_ninja/B_C = locate() in A + A.proc_holder_list -= A_C + A.proc_holder_list -= B_C + S.verbs += /obj/item/clothing/suit/space/space_ninja/proc/deinit + S.verbs += /obj/item/clothing/suit/space/space_ninja/proc/spideros + del(A_C)//First. + del(B_C)//Second, to keep the proc going. + return /obj/item/clothing/suit/space/space_ninja/proc/hack_spideros() @@ -144,7 +162,6 @@ mob/proc/create_ninja() dat += "
  • Medical Screen
  • " dat += "
  • Atmos Scan
  • " dat += "
  • Messenger
  • " - dat += "
  • Other
  • " dat += "" if(1) dat += "

    Medical Report:

    " @@ -165,7 +182,7 @@ mob/proc/create_ninja() dat += "
  • Inject Dexalin Plus: [reagents.get_reagent_amount("dexalinp")/20] left
  • " dat += "
  • Inject Tricordazine: [reagents.get_reagent_amount("tricordrazine")/20] left
  • " dat += "
  • Inject Spacelin: [reagents.get_reagent_amount("spaceacillin")/20] left
  • " - dat += "
  • Inject Radium: [(reagents.get_reagent_amount("radium")/20)-60] left
  • "//There is 120 radium at start. -60 for adrenaline boosts. + dat += "
  • Inject Radium: [(reagents.get_reagent_amount("radium")-60)/20] left
  • "//There is 120 radium at start. -60 for adrenaline boosts. dat += "
  • Inject Nutriment: [reagents.get_reagent_amount("nutriment")/5] left
  • "//Special case since it's so freaking potent. dat += "" if(2) @@ -221,8 +238,61 @@ mob/proc/create_ninja() //DEBUG=================================== -//Switches keys with AI stored inside suit. Useful for quickly testing things. +//Apparently you cannot grant verbs to objects within objects. That is, the verbs won't be recognized. +//That object/mob won't be able to grant/remove verbs either. /* +/mob/verb/grant_object_panel() + set name = "Grant AI Ninja Verbs Debug" + set category = "Ninja Debug" + var/obj/proc_holder/ai_return_control/A_C = new(src) + var/obj/proc_holder/ai_hack_ninja/B_C = new(src) + usr:proc_holder_list += A_C + usr:proc_holder_list += B_C + +mob/verb/remove_object_panel() + set name = "Remove AI Ninja Verbs Debug" + set category = "Ninja Debug" + var/obj/proc_holder/ai_return_control/A = locate() in src + var/obj/proc_holder/ai_hack_ninja/B = locate() in src + usr:proc_holder_list -= A + usr:proc_holder_list -= B + del(A)//First. + del(B)//Second, to keep the proc going. + return + +/client/verb/grant_verb_ninja_debug1(var/mob/M in view()) + set name = "Grant AI Ninja Verbs Debug" + set category = "Ninja Debug" + + M.verbs += /mob/living/silicon/ai/verb/ninja_return_control + M.verbs += /mob/living/silicon/ai/verb/ninja_spideros + return + +/client/verb/grant_verb_ninja_debug2(var/mob/living/carbon/human/M in view()) + set name = "Grant Back Ninja Verbs" + set category = "Ninja Debug" + + M.wear_suit.verbs += /obj/item/clothing/suit/space/space_ninja/proc/deinit + M.wear_suit.verbs += /obj/item/clothing/suit/space/space_ninja/proc/spideros + return + +/obj/proc/grant_verb_ninja_debug3(var/mob/living/silicon/ai/A as mob) + set name = "Grant AI Ninja Verbs" + set category = "null" + set hidden = 1 + A.verbs -= /obj/item/clothing/suit/space/space_ninja/proc/deinit + A.verbs -= /obj/item/clothing/suit/space/space_ninja/proc/spideros + return + +/mob/verb/get_dir_to_target(var/mob/M in oview()) + set name = "Get Direction to Target" + set category = "Ninja Debug" + + world << "DIR: [get_dir_to(src.loc,M.loc)]" + return + +//Switches keys with AI stored inside suit. Useful for quickly testing things. + var/ninja_debug_target//Easiest way to do this. The proc below sets this variable to your mob. /mob/verb/possess_mob(var/mob/M in oview()) @@ -264,10 +334,10 @@ var/ninja_debug_target//Easiest way to do this. The proc below sets this variabl spawn(0)//Parallel processing. E.process(src) return -*/ -/* + I made this as a test for a possible ninja ability (or perhaps more) for a certain mob to see hallucinations. The thing here is that these guys have to be coded to do stuff as they are simply images that you can't even click on. +Their movement is also awkward and overlaps. /mob/verb/TestNinjaShadow() set name = "Test Ninja Ability" set category = "Ninja Debug" diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm index a2ea312857d..65a1aecf00b 100644 --- a/code/game/gamemodes/wizard/wizard.dm +++ b/code/game/gamemodes/wizard/wizard.dm @@ -175,7 +175,7 @@ wizard_mob.verbs += /client/proc/jaunt wizard_mob.mind.special_verbs += /client/proc/jaunt else - wizard_mob.spell_list += new /obj/spell/targeted/ethereal_jaunt(usr) + wizard_mob.spell_list += new /obj/proc_holder/spell/targeted/ethereal_jaunt(usr) //So zards properly get their items when they are admin-made. del(wizard_mob.wear_suit) @@ -385,7 +385,7 @@ else if(spell_type == "object") var/list/available_spells = list("Magic Missile","Fireball","Disintegrate","Disable Tech","Smoke","Blind","Mind Transfer","Forcewall","Blink","Teleport","Mutate","Ethereal Jaunt","Knock") var/already_knows = 0 - for(var/obj/spell/aspell in usr.spell_list) + for(var/obj/proc_holder/spell/aspell in usr.spell_list) if(available_spells[text2num(href_list["spell_choice"])] == aspell.name) already_knows = 1 src.temp = "You already know that spell." @@ -394,43 +394,43 @@ if(!already_knows) switch(href_list["spell_choice"]) if ("1") - usr.spell_list += new /obj/spell/targeted/projectile/magic_missile(usr) + usr.spell_list += new /obj/proc_holder/spell/targeted/projectile/magic_missile(usr) src.temp = "This spell fires several, slow moving, magic projectiles at nearby targets. If they hit a target, it is paralyzed and takes minor damage." if ("2") - usr.spell_list += new /obj/spell/targeted/projectile/fireball(usr) + usr.spell_list += new /obj/proc_holder/spell/targeted/projectile/fireball(usr) src.temp = "This spell fires a fireball at a target and does not require wizard garb. Be careful not to fire it at people that are standing next to you." if ("3") - usr.spell_list += new /obj/spell/targeted/inflict_handler/disintegrate(usr) + usr.spell_list += new /obj/proc_holder/spell/targeted/inflict_handler/disintegrate(usr) src.temp = "This spell instantly kills somebody adjacent to you with the vilest of magick. It has a long cooldown." if ("4") - usr.spell_list += new /obj/spell/targeted/emplosion/disable_tech(usr) + usr.spell_list += new /obj/proc_holder/spell/targeted/emplosion/disable_tech(usr) src.temp = "This spell disables all weapons, cameras and most other technology in range." if ("5") - usr.spell_list += new /obj/spell/targeted/smoke(usr) + usr.spell_list += new /obj/proc_holder/spell/targeted/smoke(usr) src.temp = "This spell spawns a cloud of choking smoke at your location and does not require wizard garb." if ("6") - usr.spell_list += new /obj/spell/targeted/trigger/blind(usr) + usr.spell_list += new /obj/proc_holder/spell/targeted/trigger/blind(usr) src.temp = "This spell temporarly blinds a single person and does not require wizard garb." if ("7") - usr.spell_list += new /obj/spell/targeted/mind_transfer(usr) + usr.spell_list += new /obj/proc_holder/spell/targeted/mind_transfer(usr) src.temp = "This spell allows the user to switch bodies with a target. Careful to not lose your memory in the process." if ("8") - usr.spell_list += new /obj/spell/aoe_turf/conjure/forcewall(usr) + usr.spell_list += new /obj/proc_holder/spell/aoe_turf/conjure/forcewall(usr) src.temp = "This spell creates an unbreakable wall that lasts for 30 seconds and does not need wizard garb." if ("9") - usr.spell_list += new /obj/spell/targeted/turf_teleport/blink(usr) + usr.spell_list += new /obj/proc_holder/spell/targeted/turf_teleport/blink(usr) src.temp = "This spell randomly teleports you a short distance. Useful for evasion or getting into areas if you have patience." if ("10") - usr.spell_list += new /obj/spell/targeted/area_teleport/teleport(usr) + usr.spell_list += new /obj/proc_holder/spell/targeted/area_teleport/teleport(usr) src.temp = "This spell teleports you to a type of area of your selection. Very useful if you are in danger, but has a decent cooldown, and is unpredictable." if ("11") - usr.spell_list += new /obj/spell/targeted/genetic/mutate(usr) + usr.spell_list += new /obj/proc_holder/spell/targeted/genetic/mutate(usr) src.temp = "This spell causes you to turn into a hulk and gain telekinesis for a short while." if ("12") - usr.spell_list += new /obj/spell/targeted/ethereal_jaunt(usr) + usr.spell_list += new /obj/proc_holder/spell/targeted/ethereal_jaunt(usr) src.temp = "This spell creates your ethereal form, temporarily making you invisible and able to pass through walls." if ("13") - usr.spell_list += new /obj/spell/aoe_turf/knock(usr) + usr.spell_list += new /obj/proc_holder/spell/aoe_turf/knock(usr) src.temp = "This spell opens nearby doors and does not require wizard garb." if (href_list["spell_choice"] == "14") var/area/wizard_station/A = locate() @@ -660,7 +660,7 @@ M.mind.special_verbs -= /mob/proc/swap M.mind.special_verbs -= /client/proc/blink else if(spell_type == "object") - for(var/obj/spell/spell_to_remove in src.spell_list) + for(var/obj/proc_holder/spell/spell_to_remove in src.spell_list) del(spell_to_remove) /*Checks if the wizard can cast spells. diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index f8a9090d60e..a258e9e19c0 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -1409,7 +1409,7 @@ set category = "Fun" set name = "Give Spell" set desc = "Gives a spell to a mob." - var/obj/spell/S = input("Choose the spell to give to that guy", "ABRAKADABRA") in spells + var/obj/proc_holder/spell/S = input("Choose the spell to give to that guy", "ABRAKADABRA") in spells T.spell_list += new S /client/proc/make_sound(var/obj/O in world) // -- TLE diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index a1a907cce00..2056d260e34 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -12,6 +12,7 @@ //For ninjas exploding when they die./N if (istype(wear_suit, /obj/item/clothing/suit/space/space_ninja)&&wear_suit:initialize) + src << browse(null, "window=spideros")//Just in case. var/location = loc explosion(location, 1, 2, 3, 4) //src.flags = 0 diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 99a5185eb82..ac5a14f9c50 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -2745,10 +2745,12 @@ It can still be worn/put on as normal. if (istype(id)) return id -/mob/living/carbon/human/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0) - if(src.gloves) - var/obj/item/clothing/gloves/G = src.gloves - siemens_coeff = G.siemens_coefficient +//Added a safety check in case you want to shock a human mob directly through electrocute_act. +/mob/living/carbon/human/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0, var/safety = 0) + if(!safety) + if(gloves) + var/obj/item/clothing/gloves/G = src.gloves + siemens_coeff = G.siemens_coefficient return ..(shock_damage,source,siemens_coeff) diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 9884d7482b0..af34a3a2f91 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -8,6 +8,9 @@ anchored = 1 canmove = 0 src.loc = loc + + proc_holder_list = new() + if(L) if (istype(L, /datum/ai_laws)) laws_object = L @@ -69,6 +72,10 @@ else stat(null, text("Systems nonfunctional")) + if (proc_holder_list.len)//Generic list for proc_holder objects. + for(var/obj/proc_holder/P in proc_holder_list) + statpanel("[P.panel]","",P) + /mob/living/silicon/ai/proc/ai_alerts() set category = "AI Commands" set name = "Show Alerts" diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 88b3796ec32..3c8597a22ae 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1744,12 +1744,12 @@ proc/isobserver(A) var/limit = 2//For only two trailing shadows. for(var/turf/T in getline(mobloc, mob.loc)) spawn(0) - anim(T,'mob.dmi',mob,"shadow") + anim(T,mob,'mob.dmi',,"shadow") limit-- if(limit<=0) break else spawn(0) - anim(mobloc,'mob.dmi',mob,"shadow") + anim(mobloc,mob,'mob.dmi',,"shadow") mob.loc = get_step(mob, direct) mob.dir = direct return @@ -2131,9 +2131,9 @@ note dizziness decrements automatically in the mob's Life() proc. //if (master_controller) // stat(null, "Loop: [master_controller.loop_freq]") - if (src.spell_list.len) + if (spell_list.len) - for(var/obj/spell/S in src.spell_list) + for(var/obj/proc_holder/spell/S in src.spell_list) switch(S.charge_type) if("recharge") statpanel("Spells","[S.charge_counter/10.0]/[S.charge_max/10]",S) diff --git a/config/names/ninjaname.txt b/config/names/ninjaname.txt index 59611610297..b41271dbe10 100644 --- a/config/names/ninjaname.txt +++ b/config/names/ninjaname.txt @@ -40,4 +40,5 @@ Bro Fox Null Raiden -Samurai \ No newline at end of file +Samurai +Eater \ No newline at end of file diff --git a/config/names/ninjatitle.txt b/config/names/ninjatitle.txt index 397dcc0d383..2c7f9e7f73c 100644 --- a/config/names/ninjatitle.txt +++ b/config/names/ninjatitle.txt @@ -42,4 +42,5 @@ Solidus Steel Nickel Silver -Singing \ No newline at end of file +Singing +Snake \ No newline at end of file diff --git a/icons/obj/projectiles.dmi b/icons/obj/projectiles.dmi index 390b4229dd6..2b7c9a96871 100644 Binary files a/icons/obj/projectiles.dmi and b/icons/obj/projectiles.dmi differ diff --git a/icons/obj/wizard.dmi b/icons/obj/wizard.dmi index 0da3af3005d..d34d0d0050d 100644 Binary files a/icons/obj/wizard.dmi and b/icons/obj/wizard.dmi differ