Addendum to: r1655

#Added an icon helper procs library by Lummox Jr.
#Added more icon+overlay functionality by DarkCampainger. Both can be found under icon_procs.dm.
#Added continuous beam code by Gunbuddy to atom.dm. You can now create continuous beams of energy/magic/monkeys/whatever. For instance, pAI cords. It's really awesome.
#Like optical camo? Well I have good news. New stealth "graphic." May need some fine tuning depending on player/coder preference. It's also a little slow to change (due to update_clothing()). With that said, it's a lot cooler than what we had before. Check it out.
#Added the getIconMask() and AddCamoOverlay() procs for the above.
#Added animated satic filter icons by Koil to icons.
#New force wall and shield icons. Shield icons moved to effects.dmi.
#Changed up the abandoned mining station.
#Moved a few carp spawn points closer to the station. Added a few more.

Ninjas:
No longer spawn whoknowswhere like they did at times before.
Get a unique stealth graphic. Yup. Also, small chance of failure.
New energy net icon and effects. Energy net now uses the beam code mentioned above. It will now check for stealth.
Fixed some graphical icon issues with ninja suit. Added a female black jumpsuit to icons for this reason. Added icon directions to ninja effects.
Some more general code cleanup.

git-svn-id: http://tgstation13.googlecode.com/svn/trunk@1664 316c924e-a436-60f5-8080-3fe189b3f50e
This commit is contained in:
noisomehollow@lycos.com
2011-06-05 09:25:15 +00:00
parent d67f72c5db
commit fe889a3e8d
25 changed files with 3136 additions and 2250 deletions

View File

@@ -81,7 +81,7 @@ Not sure why this would be useful (it's not) but whatever. Ninjas need their smo
if(destination&&istype(mobloc, /turf))
spawn(0)
playsound(U.loc, "sparks", 50, 1)
anim(mobloc,src,'mob.dmi',,"phaseout")
anim(mobloc,src,'mob.dmi',,"phaseout",,U.dir)
handle_teleport_grab(destination, U)
U.loc = destination
@@ -90,7 +90,7 @@ Not sure why this would be useful (it's not) but whatever. Ninjas need their smo
spark_system.start()
playsound(U.loc, 'phasein.ogg', 25, 1)
playsound(U.loc, "sparks", 50, 1)
anim(U.loc,U,'mob.dmi',,"phasein")
anim(U.loc,U,'mob.dmi',,"phasein",,U.dir)
spawn(0)
destination.kill_creatures(U)//Any living mobs in teleport area are gibbed. Check turf procs for how it does it.
@@ -115,7 +115,7 @@ Not sure why this would be useful (it's not) but whatever. Ninjas need their smo
if(!T.density&&istype(mobloc, /turf))
spawn(0)
playsound(U.loc, 'sparks4.ogg', 50, 1)
anim(mobloc,src,'mob.dmi',,"phaseout")
anim(mobloc,src,'mob.dmi',,"phaseout",,U.dir)
handle_teleport_grab(T, U)
U.loc = T
@@ -124,7 +124,7 @@ Not sure why this would be useful (it's not) but whatever. Ninjas need their smo
spark_system.start()
playsound(U.loc, 'phasein.ogg', 25, 1)
playsound(U.loc, 'sparks2.ogg', 50, 1)
anim(U.loc,U,'mob.dmi',,"phasein")
anim(U.loc,U,'mob.dmi',,"phasein",,U.dir)
spawn(0)//Any living mobs in teleport area are gibbed.
T.kill_creatures(U)
@@ -228,17 +228,17 @@ Must right click on a mob to activate.*/
set src = usr.contents
var/C = 200
if(!ninjacost(C)&&iscarbon(M))
if(!ninjacost(C,1)&&iscarbon(M))
var/mob/living/carbon/human/U = affecting
if(M.client)//Monkeys without a client can still step_to() and bypass the net. Also, netting inactive people is lame.
//if(M)//DEBUG
if(!locate(/obj/effects/energy_net) in M.loc)//Check if they are already being affected by an energy net.
for(var/turf/T in getline(U.loc, M.loc))
if(T.density)//Don't want them shooting nets through walls. It's kind of cheesy.
U << "You may not use an energy net through solid obstacles!"
return
if(T==U.loc||T==M.loc) continue
spawn(0)
anim(T,M,'projectiles.dmi',"energy",,,get_dir_to(U.loc,M.loc))
spawn(0)
U.Beam(M,"n_beam",,15)
M.anchored = 1//Anchors them so they can't move.
U.say("Get over here!")
var/obj/effects/energy_net/E = new /obj/effects/energy_net(M.loc)
@@ -301,11 +301,9 @@ Or otherwise known as anime mode. Which also happens to be ridiculously powerful
var/mob/living/carbon/human/U = affecting
if(!U.incorporeal_move)
U.incorporeal_move = 2
U.density = 0
U << "\blue You will now phase through solid matter."
else
U.incorporeal_move = 0
U.density = 1
U << "\blue You will no-longer phase through solid matter."
return
@@ -325,7 +323,7 @@ Or otherwise known as anime mode. Which also happens to be ridiculously powerful
U.say("Ai Satsugai!")
spawn(0)
playsound(U.loc, "sparks", 50, 1)
anim(mobloc,U,'mob.dmi',,"phaseout")
anim(mobloc,U,'mob.dmi',,"phaseout",,U.dir)
spawn(0)
for(var/turf/T in getline(mobloc, destination))
@@ -333,7 +331,7 @@ Or otherwise known as anime mode. Which also happens to be ridiculously powerful
T.kill_creatures(U)
if(T==mobloc||T==destination) continue
spawn(0)
anim(T,U,'mob.dmi',,"phasein")
anim(T,U,'mob.dmi',,"phasein",,U.dir)
handle_teleport_grab(destination, U)
U.loc = destination
@@ -342,7 +340,7 @@ Or otherwise known as anime mode. Which also happens to be ridiculously powerful
spark_system.start()
playsound(U.loc, 'phasein.ogg', 25, 1)
playsound(U.loc, "sparks", 50, 1)
anim(U.loc,U,'mob.dmi',,"phasein")
anim(U.loc,U,'mob.dmi',,"phasein",,U.dir)
s_coold = 1
else
U << "\red The VOID-shift device is malfunctioning, <B>teleportation failed</B>."
@@ -397,14 +395,14 @@ This is so anime it hurts. But that's the point.*/
var/turf/picked = locate(locx,locy,mobloc.z)
spawn(0)
playsound(U.loc, "sparks", 50, 1)
anim(mobloc,U,'mob.dmi',,"phaseout")
anim(mobloc,U,'mob.dmi',,"phaseout",,U.dir)
spawn(0)
var/limit = 4
for(var/turf/T in oview(5))
if(prob(20))
spawn(0)
anim(T,U,'mob.dmi',,"phasein")
anim(T,U,'mob.dmi',,"phasein",,U.dir)
limit--
if(limit<=0) break
@@ -416,7 +414,7 @@ This is so anime it hurts. But that's the point.*/
spark_system.start()
playsound(U.loc, 'phasein.ogg', 25, 1)
playsound(U.loc, "sparks", 50, 1)
anim(U.loc,U,'mob.dmi',,"phasein")
anim(U.loc,U,'mob.dmi',,"phasein",,U.dir)
s_coold = 1
else
U << "\red The VOID-shift device is malfunctioning, <B>teleportation failed</B>."

View File

@@ -19,6 +19,7 @@ ________________________________________________________________________________
verbs += /obj/item/clothing/suit/space/space_ninja/proc/init//suit initialize verb
verbs += /obj/item/clothing/suit/space/space_ninja/proc/ai_instruction//for AIs
verbs += /obj/item/clothing/suit/space/space_ninja/proc/ai_holo
//verbs += /obj/item/clothing/suit/space/space_ninja/proc/display_verb_procs//DEBUG. Doesn't work.
spark_system = new /datum/effects/system/spark_spread()//spark initialize
spark_system.set_up(5, 0, src)
spark_system.attach(src)
@@ -147,7 +148,7 @@ ________________________________________________________________________________
/obj/item/clothing/suit/space/space_ninja/proc/ninitialize(delay = s_delay, mob/living/carbon/human/U = loc)
if(U.mind&&U.mind.assigned_role=="MODE"&&!s_initialized&&!s_busy)//Shouldn't be busy... but anything is possible I guess.
s_busy = 1
for(var/i = 0,i<7,i++)
for(var/i,i<7,i++)
switch(i)
if(0)
U << "\blue Now initializing..."
@@ -489,10 +490,7 @@ ________________________________________________________________________________
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:
// var/temp = num2text(spideros)
// var/return_to = copytext(temp, 1, (length(temp)))//length has to be to the length of the thing because by default it's length+1
// spideros = text2num(return_to)//Maximum length here is 6. Use (return_to, X) to specify larger strings if needed.
spideros = round(spideros/10)//Best way to do this, flooring to nearest integer.
if("Stealth")
toggle_stealth()
@@ -563,7 +561,7 @@ ________________________________________________________________________________
if( !(U.stat||U.wear_suit!=src||!s_initialized) )
if( !(cell.charge<=1||s_busy) )
s_busy = 1
for(var/i = 0, i<4, i++)
for(var/i, i<4, i++)
switch(i)
if(0)
U << "\blue Engaging mode...\n\black<b>CODE NAME</b>: \red <b>KAMIKAZE</b>"
@@ -617,7 +615,7 @@ ________________________________________________________________________________
if(confirm == "Yes"&&AI)
if(A.laws.zeroth)//Gives a few seconds to re-upload the AI somewhere before it takes full control.
s_busy = 1
for(var/i=0,i<5,i++)
for(var/i,i<5,i++)
if(AI==A)
switch(i)
if(0)
@@ -681,7 +679,7 @@ ________________________________________________________________________________
if(!hologram)//If there is not already a hologram.
hologram = new(T)//Spawn a blank effect at the location.
hologram.invisibility = 101//So that it doesn't show up, ever. This also means one could attach a number of images to a single obj and display them differently to differnet people.
hologram.dir = get_dir_to(T,affecting.loc)
hologram.dir = get_dir(T,affecting.loc)
var/image/I = image('mob.dmi',hologram,"ai-holo")//Attach an image to object.
hologram.i_attached = I//To attach the image in order to later reference.
AI << I
@@ -772,14 +770,6 @@ ________________________________________________________________________________
var/total_reagent_transfer//Keep track of this stuff.
for(var/reagent_id in reagent_list)
var/datum/reagent/R = I.reagents.has_reagent(reagent_id)//Mostly to pull up the name of the reagent after calculating. Also easier to use than writing long proc paths.
/* if(reagents.get_reagent_amount(reagent_id)<r_maxamount+(reagent_id == "radium"?(a_boost*a_transfer):0)&&I.reagents.get_reagent_amount(reagent_id)>=a_transfer)//Radium is always special.
//Here we determine how much reagent will actually transfer if there is enough to transfer or there is a need of transfer. Minimum of max amount available (using a_transfer) or amount needed.
var/amount_to_transfer = min( (r_maxamount+(reagent_id == "radium"?(a_boost*a_transfer):0)-reagents.get_reagent_amount(reagent_id)) ,(round(I.reagents.get_reagent_amount(reagent_id)/a_transfer))*a_transfer)//In the end here, we round the amount available, then multiply it again.
total_reagent_transfer += amount_to_transfer//Add to total reagent trans.
I.reagents.remove_reagent(reagent_id, amount_to_transfer)//Remove from beaker.
reagents.add_reagent(reagent_id, amount_to_transfer)//Add to suit. Reactions are not important.
U << "Added [amount_to_transfer] units of [reagent_id]."//Fix the id label.
*/
if(R&&reagents.get_reagent_amount(reagent_id)<r_maxamount+(reagent_id == "radium"?(a_boost*a_transfer):0)&&R.volume>=a_transfer)//Radium is always special.
//Here we determine how much reagent will actually transfer if there is enough to transfer or there is a need of transfer. Minimum of max amount available (using a_transfer) or amount needed.
var/amount_to_transfer = min( (r_maxamount+(reagent_id == "radium"?(a_boost*a_transfer):0)-reagents.get_reagent_amount(reagent_id)) ,(round(R.volume/a_transfer))*a_transfer)//In the end here, we round the amount available, then multiply it again.
@@ -795,30 +785,11 @@ ________________________________________________________________________________
/obj/item/clothing/suit/space/space_ninja/proc/toggle_stealth()
var/mob/living/carbon/human/U = affecting
/* This was a test for a new cloaking system. WIP.
if(!s_active)
spawn(0)
anim(U.loc,U,'mob.dmi',,"cloak")
var/image/I = image('mob.dmi',affecting,"ninjatest2")
for(var/mob/O in oviewers(U, null))
O << "[U.name] vanishes into thin air!"
I.override = 1
affecting << I
s_active = !s_active
else
spawn(0)
anim(U.loc,U,'mob.dmi',,"uncloak")
for(var/mob/O in oviewers(U, null))
O << "[U.name] appears from thin air!"
s_active = !s_active
*/
if(s_active)
cancel_stealth()
else
spawn(0)
anim(U.loc,U,'mob.dmi',,"cloak")
anim(U.loc,U,'mob.dmi',,"cloak",,U.dir)
s_active=!s_active
U << "\blue You are now invisible to normal detection."
for(var/mob/O in oviewers(U))
@@ -829,7 +800,7 @@ ________________________________________________________________________________
var/mob/living/carbon/human/U = affecting
if(s_active)
spawn(0)
anim(U.loc,U,'mob.dmi',,"uncloak")
anim(U.loc,U,'mob.dmi',,"uncloak",,U.dir)
s_active=!s_active
U << "\blue You are now visible."
for(var/mob/O in oviewers(U))
@@ -1174,38 +1145,21 @@ ________________________________________________________________________________
var/chance = rand(1,100)
switch(chance)
if(1 to 50)//High chance of a regular name.
var/g = pick(0,1)
var/first = null
var/last = pick(last_names)
if(g==0)
first = pick(first_names_female)
else
first = pick(first_names_male)
voice = "[first] [last]"
voice = "[rand(0,1)==1?pick(first_names_female):pick(first_names_male)] [pick(last_names)]"
if(51 to 80)//Smaller chance of a clown name.
var/first = pick(clown_names)
voice = "[first]"
voice = "[pick(clown_names)]"
if(81 to 90)//Small chance of a wizard name.
var/first = pick(wizard_first)
var/last = pick(wizard_second)
voice = "[first] [last]"
voice = "[pick(wizard_first)] [pick(wizard_second)]"
if(91 to 100)//Small chance of an existing crew name.
var/list/names = new()
var/names[] = new()
for(var/mob/living/carbon/human/M in world)
if(M==U||!M.client||!M.real_name) continue
names.Add(M)
if(!names.len)
voice = "Cuban Pete"//Smallest chance to be the man.
else
var/mob/picked = pick(names)
voice = picked.real_name
names.Add(M.real_name)
voice = !names.len ? "Cuban Pete" : pick(names)
U << "You are now mimicking <B>[voice]</B>."
else
if(voice!="Unknown")
U << "You deactivate the voice synthesizer."
voice = "Unknown"
else
U << "The voice synthesizer is already deactivated."
U << "The voice synthesizer is [voice!="Unknown"?"now":"already"] deactivated."
voice = "Unknown"
return
/obj/item/clothing/mask/gas/voice/space_ninja/proc/switchm()
@@ -1238,7 +1192,6 @@ ________________________________________________________________________________
..()
var/mode
var/voice
switch(mode)
if(0)
mode = "Scouter"
@@ -1248,12 +1201,8 @@ ________________________________________________________________________________
mode = "Thermal Scanner"
if(3)
mode = "Meson Scanner"
if(vchange==0)
voice = "inactive"
else
voice = "active"
usr << "<B>[mode]</B> is active."//Leaving usr here since it may be on the floor or on a person.
usr << "Voice mimicking algorithm is set to <B>[voice]</B>."
usr << "Voice mimicking algorithm is set <B>[!vchange?"inactive":"active"]</B>."
/*
===================================================================================
@@ -1262,11 +1211,8 @@ ________________________________________________________________________________
*/
/*
HerpA:
I'm not really sure what you want this to do.
For now it will teleport people to the prison after 30 seconds. (Check the process() proc to change where teleport goes)
It will teleport people to the prison after 30 seconds. (Check the process() proc to change where teleport goes)
It is possible to destroy the net by the occupant or someone else.
The sprite for the net is kind of ugly but I couldn't come up with a better one.
*/
/obj/effects/energy_net
@@ -1300,6 +1246,7 @@ The sprite for the net is kind of ugly but I couldn't come up with a better one.
process(var/mob/living/carbon/M as mob)
var/check = 30//30 seconds before teleportation. Could be extended I guess.
var/mob_name = affecting.name//Since they will report as null if terminated before teleport.
//The person can still try and attack the net when inside.
while(!isnull(M)&&!isnull(src)&&check>0)//While M and net exist, and 30 seconds have not passed.
check--
@@ -1307,7 +1254,7 @@ The sprite for the net is kind of ugly but I couldn't come up with a better one.
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 <b>ERROR</b>: \black unable to locate [affecting]. Procedure terminated."
master << "\red <b>ERROR</b>: \black unable to locate [mob_name]. Procedure terminated."
del(src)//Get rid of the net.
return
@@ -1315,7 +1262,7 @@ 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,M,'mob.dmi',,"phaseout")
anim(M.loc,M,'mob.dmi',,"phaseout",,M.dir)
density = 0//Make the net pass-through.
invisibility = 101//Make the net invisible so all the animations can play out.
@@ -1326,9 +1273,9 @@ The sprite for the net is kind of ugly but I couldn't come up with a better one.
var/datum/effects/system/spark_spread/spark_system = new /datum/effects/system/spark_spread()
spark_system.set_up(5, 0, M.loc)
spark_system.start()
playsound(M.loc, 'Deconstruct.ogg', 50, 1)
playsound(M.loc, 'phasein.ogg', 25, 1)
playsound(M.loc, 'sparks2.ogg', 50, 1)
anim(M.loc,M,'mob.dmi',,"phasein")
anim(M.loc,M,'mob.dmi',,"phasein",,M.dir)
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))
@@ -1361,10 +1308,7 @@ The sprite for the net is kind of ugly but I couldn't come up with a better one.
if(2.0)
health-=50
if(3.0)
if (prob(50))
health-=50
else
health-=25
health-=prob(50)?50:25
healthcheck()
return

View File

@@ -178,7 +178,10 @@ client/proc/create_space_ninja(obj/spawn_point)
/mob/living/carbon/human/proc/equip_space_ninja()
var/obj/item/device/radio/R = new /obj/item/device/radio/headset(src)
equip_if_possible(R, slot_ears)
equip_if_possible(new /obj/item/clothing/under/color/black(src), slot_w_uniform)
if(gender==FEMALE)
equip_if_possible(new /obj/item/clothing/under/color/blackf(src), slot_w_uniform)
else
equip_if_possible(new /obj/item/clothing/under/color/black(src), slot_w_uniform)
equip_if_possible(new /obj/item/clothing/shoes/space_ninja(src), slot_shoes)
equip_if_possible(new /obj/item/clothing/suit/space/space_ninja(src), slot_wear_suit)
equip_if_possible(new /obj/item/clothing/gloves/space_ninja(src), slot_gloves)
@@ -258,6 +261,35 @@ client/proc/create_space_ninja(obj/spawn_point)
n_gloves.candrain=0
n_gloves.draining=0
//Allows the mob to grab a stealth icon.
/mob/proc/NinjaStealthActive(atom/A)//A is the atom which we are using as the overlay.
invisibility = 2//Set ninja invis to 2.
var/icon/opacity_icon = new(A.icon, A.icon_state)
var/icon/alpha_mask = getIconMask(src)
var/icon/alpha_mask_2 = new('effects.dmi', "wave1")
alpha_mask.AddAlphaMask(alpha_mask_2)
opacity_icon.AddAlphaMask(alpha_mask)
for(var/i=0,i<5,i++)//And now we add it as overlays. It's faster than creating an icon and then merging it.
var/image/I = image("icon" = opacity_icon, "icon_state" = A.icon_state, "layer" = layer+0.8)//So it's above other stuff but below weapons and the like.
switch(i)//Now to determine offset so the result is somewhat blurred.
if(1)
I.pixel_x -= 1
if(2)
I.pixel_x += 1
if(3)
I.pixel_y -= 1
if(4)
I.pixel_y += 1
overlays += I//And finally add the overlay.
overlays += image("icon"='effects.dmi',"icon_state" ="electricity","layer" = layer+0.9)
//When ninja steal malfunctions.
/mob/proc/NinjaStealthMalf()
invisibility = 0//Set ninja invis to 0.
overlays += image("icon"='effects.dmi',"icon_state" ="electricity","layer" = layer+0.9)
playsound(loc, 'stealthoff.ogg', 75, 1)
//=======//GENERIC VERB MODIFIERS//=======//
/obj/item/clothing/suit/space/space_ninja/proc/grant_equip_verbs()
@@ -352,7 +384,6 @@ client/proc/create_space_ninja(obj/spawn_point)
n_gloves.verbs -= /obj/item/clothing/gloves/space_ninja/proc/toggled
U.incorporeal_move = 0
U.density = 1
kamikaze = 0
k_unlock = 0
U << "\blue Disengaging mode...\n\black<b>CODE NAME</b>: \red <b>KAMIKAZE</b>"
@@ -375,6 +406,29 @@ client/proc/create_space_ninja(obj/spawn_point)
//=======//OLD & UNUSED//=======//
/*
Deprecated. get_dir() does the same thing. Still a nice proc.
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(turf/start,turf/end)//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
Alternative and inferior method of calculating spideros.
var/temp = num2text(spideros)
var/return_to = copytext(temp, 1, (length(temp)))//length has to be to the length of the thing because by default it's length+1
spideros = text2num(return_to)//Maximum length here is 6. Use (return_to, X) to specify larger strings if needed.
//Old way of draining from wire.
/obj/item/clothing/gloves/space_ninja/proc/drain_wire()
set name = "Drain From Wire"
@@ -488,6 +542,14 @@ BYOND fixed the verb bugs so this is no longer necessary. I prefer verb panels.
//=======//DEBUG//=======//
/obj/item/clothing/suit/space/space_ninja/proc/display_verb_procs()
//DEBUG
//Does nothing at the moment. I am trying to see if it's possible to mess around with verbs as variables.
//for(var/P in verbs)
// if(P.set.name)
// usr << "[P.set.name], path: [P]"
return
/*
Most of these are at various points of incomplete.

View File

@@ -123,8 +123,8 @@
/obj/forcefield
desc = "A space wizard's magic wall."
name = "FORCEWALL"
icon = 'mob.dmi'
icon_state = "shield"
icon = 'effects.dmi'
icon_state = "m_shield"
anchored = 1.0
opacity = 0
density = 1