From bbd3be907a210cdbd90765218b81a5b78de9e5be Mon Sep 17 00:00:00 2001 From: "noisomehollow@lycos.com" Date: Wed, 8 Jun 2011 04:12:05 +0000 Subject: [PATCH] Fixed and improved object mind transfer. It will work properly now. Fixed teleporting randomly on clown planet z level (with hand tele). Probably won't work on extended but who cares. Some misc improvements to code words. Cut down on the amount of chloralhydrate in the sleepypen since it was fatal, apparently. Fixed observing. Entry shuttle starts with less sleepers than before. Some more wip stuff. git-svn-id: http://tgstation13.googlecode.com/svn/trunk@1670 316c924e-a436-60f5-8080-3fe189b3f50e --- code/datums/spells/mind_transfer.dm | 115 +- code/defines/procs/syndicate_name.dm | 39 +- code/game/gamemodes/extra/ninja_equipment.dm | 130 +- code/game/gamemodes/extra/space_ninja.dm | 62 +- code/game/objects/devices/PDA/PDA.dm | 6 +- code/game/objects/devices/PDA/cart.dm | 12 +- code/game/objects/items.dm | 2 +- .../objects/items/weapons/teleportation.dm | 4 +- maps/tgstation.2.0.7.dmm | 14443 ++++++++-------- 9 files changed, 7452 insertions(+), 7361 deletions(-) diff --git a/code/datums/spells/mind_transfer.dm b/code/datums/spells/mind_transfer.dm index 2f0598b0c69..32b5272fff7 100644 --- a/code/datums/spells/mind_transfer.dm +++ b/code/datums/spells/mind_transfer.dm @@ -9,34 +9,35 @@ invocation_type = "whisper" range = 7 var/list/protected_roles = list("Wizard","Fake Wizard","Changeling","Cultist") //which roles are immune to the spell - var/list/compatible_mobs = list("/mob/living/carbon/human","/mob/living/carbon/monkey") //which types of mobs are affected by the spell. NOTE: change at your own risk - var/base_spell_loss_chance = 5 //base probability of the wizard losing a spell in the process + var/list/compatible_mobs = list(/mob/living/carbon/human,/mob/living/carbon/monkey) //which types of mobs are affected by the spell. NOTE: change at your own risk + var/base_spell_loss_chance = 20 //base probability of the wizard losing a spell in the process var/spell_loss_chance_modifier = 7 //amount of probability of losing a spell added per spell (mind_transfer included) var/spell_loss_amount = 1 //the maximum amount of spells possible to lose during a single transfer var/msg_wait = 500 //how long in deciseconds it waits before telling that body doesn't feel right or mind swap robbed of a spell 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/proc_holder/spell/targeted/mind_transfer/cast(list/targets,mob/user = usr) //magnets, so mostly hardcoded +/* +Urist: I don't feel like figuring out how you store object spells so I'm leaving this for you to do. +Make sure spells that are removed from spell_list are actually removed and deleted when mind transfering. +Also, you never added distance checking after target is selected. I've went ahead and did that. +*/ +/obj/proc_holder/spell/targeted/mind_transfer/cast(list/targets,mob/user = usr) if(!targets.len) - user << "No mind found" + user << "No mind found." return if(targets.len > 1) - user << "Too many minds! You're not a hive damnit!" + user << "Too many minds! You're not a hive damnit!"//Whaa...aat? return var/mob/target = targets[1] - if(!target.client || !target.mind) - user << "They appear to be brain-dead." + if(!(target in oview(range)))//If they are not in overview after selection. Do note that !() is necessary for in to work because ! takes precedence over it. + user << "They are too far away!" return - if(target.mind.special_role in protected_roles) - user << "Their mind is resisting your spell." - return - - if(!target.type in compatible_mobs) + if(!(target.type in compatible_mobs)) user << "Their mind isn't compatible with yours." return @@ -44,59 +45,81 @@ user << "You didn't study necromancy back at the Space Wizard Federation academy." return - var/mob/victim = target //mostly copypastaed, I have little idea how this works - var/mob/caster = user - //losing spells + if(!target.client || !target.mind) + //if(!target.mind)//Good for testing. + user << "They appear to be brain-dead." + return - if(usr.spell_list.len) - for(var/i=1,i<=spell_loss_amount,i++) - var/spell_loss_chance = base_spell_loss_chance - var/list/checked_spells = usr.spell_list - checked_spells -= src //MT can't be lost //doesn't work + if(target.mind.special_role in protected_roles) + user << "Their mind is resisting your spell." + return - for(var/j=1,j<=checked_spells.len,j++) - if(prob(spell_loss_chance)) - if(checked_spells.len) - usr.spell_list -= pick(checked_spells) - spawn(msg_wait) - victim << "The mind transfer has robbed you of a spell." - break - else - spell_loss_chance += spell_loss_chance_modifier + var/mob/victim = target//The target of the spell whos body will be transferred to. + var/mob/caster = user//The wizard/whomever doing the body transferring. + //To properly transfer clients so no-one gets kicked off the game, we need a host mob. + var/mob/dead/observer/temp_ghost = new(victim) - var/mob/dead/observer/temp_ghost = new /mob/dead/observer(target) //To properly transfer clients so no-one gets kicked off the game. + //SPELL LOSS BEGIN + //NOTE: The caster must ALWAYS keep mind transfer, even when other spells are lost. + var/obj/proc_holder/spell/targeted/mind_transfer/m_transfer = locate() in user.spell_list//Find mind transfer directly. + var/list/checked_spells = user.spell_list + checked_spells -= m_transfer //Remove Mind Transfer from the list. - if(caster.mind.special_verbs.len)//Removes any special verbs from the original caster. - for(var/V in caster.mind.special_verbs) - caster.verbs -= V - victim.client.mob = temp_ghost - if(victim.mind.special_verbs.len)//Removes any special verbs from the original target. + if(caster.spell_list.len)//If they have any spells left over after mind transfer is taken out. If they don't, we don't need this. + for(var/i=spell_loss_amount,(i>0&&checked_spells.len),i--)//While spell loss amount is greater than zero and checked_spells has spells in it, run this proc. + for(var/j=checked_spells.len,(j>0&&checked_spells.len),j--)//While the spell list to check is greater than zero and has spells in it, run this proc. + if(prob(base_spell_loss_chance)) + checked_spells -= pick(checked_spells)//Pick a random spell to remove. + spawn(msg_wait) + victim << "The mind transfer has robbed you of a spell." + break//Spell lost. Break loop, going back to the previous for() statement. + else//Or keep checking, adding spell chance modifier to increase chance of losing a spell. + base_spell_loss_chance += spell_loss_chance_modifier + + checked_spells += m_transfer//Add back Mind Transfer. + user.spell_list = checked_spells//Set user spell list to whatever the new list is. + //SPELL LOSS END + + //MIND TRANSFER BEGIN + if(caster.mind.special_verbs.len)//If the caster had any special verbs, remove them from the mob verb list. + for(var/V in caster.mind.special_verbs)//Since the caster is using an object spell system, this is mostly moot. + caster.verbs -= V//But a safety nontheless. + + if(victim.mind.special_verbs.len)//Now remove all of the victim's verbs. for(var/V in victim.mind.special_verbs) victim.verbs -= V - temp_ghost.spell_list = victim.spell_list - temp_ghost.mind = victim.mind + temp_ghost.key = victim.key//Throw the victim into the ghost temporarily. + temp_ghost.mind = victim.mind//Tranfer the victim's mind into the ghost. + temp_ghost.spell_list = victim.spell_list//If they have spells, transfer them. Now we basically have a backup mob. - caster.client.mob = victim - victim.spell_list = caster.spell_list - victim.mind = caster.mind - if(victim.mind.special_verbs.len)//Adds verbs for the original caster if needed. - for(var/V in caster.mind.special_verbs) + victim.key = caster.key//Now we throw the caste into the victim's body. + victim.mind = caster.mind//Do the same for their mind and spell list. + victim.spell_list = caster.spell_list//Now they are inside the victim's body. + + if(victim.mind.special_verbs.len)//To add all the special verbs for the original caster. + for(var/V in caster.mind.special_verbs)//Not too important but could come into play. caster.verbs += V - temp_ghost.client.mob = caster + caster.key = temp_ghost.key//Tranfer the original victim, now in a ghost, into the caster's body. + caster.mind = temp_ghost.mind//Along with their mind and spell list. caster.spell_list = temp_ghost.spell_list - caster.mind = temp_ghost.mind - if(caster.mind.special_verbs.len)//Adds verbs for original target if needed. + + if(caster.mind.special_verbs.len)//If they had any special verbs, we add them here. for(var/V in caster.mind.special_verbs) caster.verbs += V + //MIND TRANSFER END + + //Now we update mind current mob so we know what body they are in for end round reporting. caster.mind.current = caster victim.mind.current = victim + //Here we paralyze both mobs and knock them out for a time. caster.paralysis += paralysis_amount_caster victim.paralysis += paralysis_amount_victim + //After a certain amount of time the victim gets a message about being in a different body. spawn(msg_wait) - caster << "Your body doesn't feel like itself." + caster << "\red You feel woozy and lightheaded. Your body doesn't seem like your own." del(temp_ghost) \ No newline at end of file diff --git a/code/defines/procs/syndicate_name.dm b/code/defines/procs/syndicate_name.dm index e3f56acb64a..b4ea7e65eaa 100644 --- a/code/defines/procs/syndicate_name.dm +++ b/code/defines/procs/syndicate_name.dm @@ -28,8 +28,8 @@ var/syndicate_name = null syndicate_name = name return name -//This is referenced in equip_traitor() so it's fairly easy to remove if needed. -//Added this to traitor AIs. + +//Traitors and traitor silicons will get these. Revs will not. var/syndicate_code_phrase//Code phrase for traitors. var/syndicate_code_response//Code response for traitors. @@ -57,14 +57,20 @@ var/syndicate_code_response//Code response for traitors. 25; 5 ) - var/safety[] = new() - safety = list(1,2,3)//Tells the proc which options to remove later on. + var/safety[] = list(1,2,3)//Tells the proc which options to remove later on. + var/nouns[] = list("love","hate","anger","peace","pride","sympathy","bravery","loyalty","honesty","integrity","compassion","charity","success","courage","deceit","skill","beauty","brilliance","pain","misery","beliefs","dreams","justice","truth","faith","liberty","knowledge","thought","information","culture","trust","dedication","progress","education","hospitality","leisure","trouble","friendships", "relaxation") + var/drinks[] = list("vodka and tonic","gin fizz","bahama mama","manhattan","black Russian","whiskey soda","long island tea","margarita","Irish coffee"," manly dwarf","Irish cream","doctor's delight","Beepksy Smash","tequilla sunrise","brave bull","gargle blaster","bloody mary","whiskey cola","white Russian","vodka martini","martini","Cuba libre","kahlua","vodka","wine","moonshine") + var/locations[] = teleportlocs.len ? teleportlocs : drinks//if null, defaults to drinks instead. + + var/names[] = list() + for(var/datum/data/record/t in data_core.general)//Picks from crew manifest. + names += t.fields["name"] var/maxwords = words//Extra var to check for duplicates. - while(words)//Randomly picks from one of the choices below. + for(words,words>0,words--)//Randomly picks from one of the choices below. - if(words==1&&safety.Find(1)&&safety.Find(2))//If there is only one word remaining and choice 1 or 2 have not been selected. + if(words==1&&(1 in safety)&&(2 in safety))//If there is only one word remaining and choice 1 or 2 have not been selected. safety = list(pick(1,2))//Select choice 1 or 2. else if(words==1&&maxwords==2)//Else if there is only one word remaining (and there were two originally), and 1 or 2 were chosen, safety = list(3)//Default to list 3 @@ -73,32 +79,26 @@ var/syndicate_code_response//Code response for traitors. if(1)//1 and 2 can only be selected once each to prevent more than two specific names/places/etc. switch(rand(1,2))//Mainly to add more options later. if(1) - var/name_list[] = list() - for(var/datum/data/record/t in data_core.general)//Picks from crew manifest. - name_list.Add(t.fields["name"]) - if(name_list.len&&prob(70)) - code_phrase += pick(name_list) + if(names.len&&prob(70)) + code_phrase += pick(names) else code_phrase += pick(pick(first_names_male,first_names_female)) code_phrase += " " code_phrase += pick(last_names) if(2) code_phrase += pick(get_all_jobs())//Returns a job. - safety.Remove(1) + safety -= 1 if(2) switch(rand(1,2))//Places or things. if(1) - code_phrase += pick("vodka and tonic","gin fizz","bahama mama","manhattan","black Russian","whiskey soda","long island tea","margarita","Irish coffee"," manly dwarf","Irish cream","doctor's delight","Beepksy Smash","tequilla sunrise","brave bull","gargle blaster","bloody mary","whiskey cola","white Russian","vodka martini","martini","Cuba libre","kahlua","vodka","wine","moonshine") + code_phrase += pick(drinks) if(2) - if(teleportlocs.len) //tired of those runtime errors -- Urist - code_phrase += "[pick(teleportlocs)]"//Returns a place. - else - code_phrase += pick("vodka and tonic","gin fizz","bahama mama","manhattan","black Russian","whiskey soda","long island tea","margarita","Irish coffee"," manly dwarf","Irish cream","doctor's delight","Beepksy Smash","tequilla sunrise","brave bull","gargle blaster","bloody mary","whiskey cola","white Russian","vodka martini","martini","Cuba libre","kahlua","vodka","wine","moonshine") - safety.Remove(2) + code_phrase += pick(locations) + safety -= 2 if(3) switch(rand(1,3))//Nouns, adjectives, verbs. Can be selected more than once. if(1) - code_phrase += pick("love","hate","anger","peace","pride","sympathy","bravery","loyalty","honesty","integrity","compassion","charity","success","courage","deceit","skill","beauty","brilliance","pain","misery","beliefs","dreams","justice","truth","faith","liberty","knowledge","thought","information","culture","trust","dedication","progress","education","hospitality","leisure","trouble","friendships", "relaxation") + code_phrase += pick(nouns) if(2) code_phrase += pick(adjectives) if(3) @@ -107,7 +107,6 @@ var/syndicate_code_response//Code response for traitors. code_phrase += "." else code_phrase += ", " - words-- return code_phrase diff --git a/code/game/gamemodes/extra/ninja_equipment.dm b/code/game/gamemodes/extra/ninja_equipment.dm index 69842c80acb..e294c1e3757 100644 --- a/code/game/gamemodes/extra/ninja_equipment.dm +++ b/code/game/gamemodes/extra/ninja_equipment.dm @@ -252,7 +252,7 @@ ________________________________________________________________________________ dat += "
" dat += " Current Time: [round(world.time / 36000)+12]:[(world.time / 600 % 60) < 10 ? add_zero(world.time / 600 % 60, 1) : world.time / 600 % 60]
" dat += " Battery Life: [round(cell.charge/100)]%
" - dat += " Smoke Bombs: [s_bombs]
" + dat += " Smoke Bombs: \Roman [s_bombs]
" dat += " pai Device: " if(pai) dat += "Configure" @@ -358,48 +358,50 @@ ________________________________________________________________________________ dat += "WARNING: Hostile runtime intrusion detected: operation locked. The Spider Clan is watching you, INTRUDER." dat += "ERROR: TARANTULA.v.4.77.12 encryption algorithm detected. Unable to decrypt archive.
" if(4) - dat += "

Ninja Manual:

" - dat += "
Who they are:
" - dat += "Space ninjas are a special type of ninja, specifically one of the space-faring type. The vast majority of space ninjas belong to the Spider Clan, a cult-like sect, which has existed for several hundred years. The Spider Clan practice a sort of augmentation of human flesh in order to achieve a more perfect state of being and follow Postmodern Space Bushido. They also kill people for money. Their leaders are chosen from the oldest of the grand-masters, people that have lived a lot longer than any mortal man should.
Being a sect of technology-loving fanatics, the Spider Clan have the very best to choose from in terms of hardware--cybernetic implants, exoskeleton rigs, hyper-capacity batteries, and you get the idea. Some believe that much of the Spider Clan equipment is based on reverse-engineered alien technology while others doubt such claims.
Whatever the case, their technology is absolutely superb." - dat += "
How they relate to other SS13 organizations:
" - dat += "" - dat += "
The reason they (you) are here:
" - dat += "Space ninjas are renowned throughout the known controlled space as fearless spies, infiltrators, and assassins. They are sent on missions of varying nature by Nanotrasen, the Syndicate, and other shady organizations and people. To hire a space ninja means serious business." - dat += "
Their playstyle:
" - dat += "A mix of traitor, changeling, and wizard. Ninjas rely on energy, or electricity to be precise, to keep their suits running (when out of energy, a suit hibernates). Suits gain energy from objects or creatures that contain electrical charge. APCs, cell batteries, rechargers, SMES batteries, cyborgs, mechs, and exposed wires are currently supported. Through energy ninjas gain access to special powers--while all powers are tied to the ninja suit, the most useful of them are verb activated--to help them in their mission.
It is a constant struggle for a ninja to remain hidden long enough to recharge the suit and accomplish their objective; despite their arsenal of abilities, ninjas can die like any other. Unlike wizards, ninjas do not possess good crowd control and are typically forced to play more subdued in order to achieve their goals. Some of their abilities are specifically designed to confuse and disorient others.
With that said, it should be perfectly possible to completely flip the fuck out and rampage as a ninja." - dat += "
Their powers:
" - dat += "There are two primary types: Equipment and Abilties. Passive effects are always on. Active effects must be turned on and remain active only when there is energy to do so. Ability costs are listed next to them." - dat += "Equipment: cannot be tracked by AI (passive), faster speed (passive), stealth (active), vision switch (passive if toggled), voice masking (passive), SpiderOS (passive if toggled), energy drain (passive if toggled)." - dat += "" - dat += "Abilities:" - dat += "