mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-01-15 03:52:43 +00:00
I have done lots of work to make selecting players for special roles be fair.
- New options preferences: "be traitor", "be changeling" and so on for all special roles.
- Now you can have job of AI/cyborg in preferences and do not lower your chances to become wizard/changeling/etc. And vice-versa: you do not have to select AI in your preferences to have non zero chance to play malf.
- Jobban from syndicate bans player from any special role (including malf AI, cult, etc).
- Fixed bug with changeling round not ending sometimes.
- All special roles were tuned to work better as admin-driven event.
-- All adminmade special characters will be listed at the end of round of any type.
-- All adminmade special characters are fully functional with following exceptions:
--- The ending conditions are determined at round start, i.e. you cannot end revolution by killing wizards and malf AIs (however, with nuke you can end anything).
--- The cultists cannot get their special objectives.
--- The malf AI can hack the APCs but without any profit.
--- The syndicate operatives must obtain the nuke/working code from admins.
--- As before, nuclear explosion ends round. Even if nuke was used in wrong place.
- Fixed thingy like "Not enough players for revolution game mode. Restarting world in 5 seconds."
- Changeling wont get objective "absorb X genomes" when there are less that X players in game.
- proc/equip_if_possible now has return value, procs like equip_revolutionary (giving a flash) should be more reliable.
- There are no fake wizards anymore. The research staff have to kill ALL wizards on order to win, even adminspawned ones. ("give spell" verb works as before, not making a spellcaster to actually be wizard).
- The semi-new game mode: traitor+changeling. Just like regular traitor mode plus one changeling. Round ends when the shuttle reaches centcom. Option for config.txt: "PROBABILITY TRAITORCHAN".
- Successful malf AI now have 60 seconds to choose to explode the station or not (some players still have to rejoin game to have their new verbs shown in Malfunction tab).
- Monkeys mode fixed, monkeys wouldn't randomly cure anymore.
For admins:
- New powerful mind editor oriented to mixed rounds.
-- Setting someone as special character (like wizard) does not equip him/her automatically. You have to do it it next step. Note, that in case of wizards and nuke operatives their old dress will be deleted! If you do not want it you shall use "undress" link.
-- Only operatives, head revs and cultists have their objectives set immediately.
-- You can unemad borgs!
-- You cannot unemag borgs because calling mind editor for nonhumans is blocked atm.
-- many other useful features.
-- you can fix burned out flashes from mind editor.
-- first assign the new malf AI/wizard then demalf/dewizard old one or round will immediately end.
- if delete the nuke bomb during its downcounting round will stuck. Using "edit ticker variables" set ticker.mode.explosion_in_progress = 0.
For coders:
- /datum/game_mode/malfunction/AI_Module renamed to /datum/AI_Module. Reason: What. The. Fuck.
Unrelated fixes:
- Blueprints can create areas up to 300 tiles (was 100).
- Cyborgs wont leave backpacks at spawn point anymore.
- Fixed bug in preferences causing preferences files to be huge.
- Diseases can infect again.
- The option "SQL_ENABLED 0" now works in config.txt.
- fixed critical bug on assassinate objective.
Bugs:
- We have a bug with job distribution for people who haven't any available jobs in their preferences. Players tends to group by jobs.
- For example, if we have 3 players they with hight chances will got same jobs. And probability of having one engineer and one medic _exactly_ equals _zero_.
- I am not sure if my changes made that bug worse. Anyway I MUST do this commit. Bug will be fixed eventually. Maybe.
git-svn-id: http://tgstation13.googlecode.com/svn/trunk@1703 316c924e-a436-60f5-8080-3fe189b3f50e
445 lines
14 KiB
Plaintext
445 lines
14 KiB
Plaintext
/obj/item/proc/process()
|
|
processing_items.Remove(src)
|
|
|
|
return null
|
|
|
|
/obj/item/proc/attack_self()
|
|
return
|
|
|
|
/obj/item/proc/talk_into(mob/M as mob, text)
|
|
return
|
|
|
|
/obj/item/proc/moved(mob/user as mob, old_loc as turf)
|
|
return
|
|
|
|
/obj/item/proc/dropped(mob/user as mob)
|
|
return
|
|
|
|
// called just as an item is picked up (loc is not yet changed)
|
|
/obj/item/proc/pickup(mob/user)
|
|
return
|
|
|
|
// called after an item is placed in an equipment slot
|
|
// user is mob that equipped it
|
|
// slot is text of slot type e.g. "head"
|
|
// for items that can be placed in multiple slots
|
|
// note this isn't called during the initial dressing of a player
|
|
/obj/item/proc/equipped(var/mob/user, var/slot)
|
|
return
|
|
//
|
|
// ***TODO: implement unequipped()
|
|
//
|
|
|
|
/obj/item/proc/afterattack()
|
|
return
|
|
|
|
/obj/item/weapon/dummy/ex_act()
|
|
return
|
|
|
|
/obj/item/weapon/dummy/blob_act()
|
|
return
|
|
|
|
/obj/item/ex_act(severity)
|
|
switch(severity)
|
|
if(1.0)
|
|
del(src)
|
|
return
|
|
if(2.0)
|
|
if (prob(50))
|
|
del(src)
|
|
return
|
|
if(3.0)
|
|
if (prob(5))
|
|
del(src)
|
|
return
|
|
else
|
|
return
|
|
|
|
/obj/item/blob_act()
|
|
return
|
|
|
|
/obj/item/verb/move_to_top()
|
|
set name = "Move To Top"
|
|
set category = "Object"
|
|
set src in oview(1)
|
|
|
|
if(!istype(src.loc, /turf) || usr.stat || usr.restrained() )
|
|
return
|
|
|
|
var/turf/T = src.loc
|
|
|
|
src.loc = null
|
|
|
|
src.loc = T
|
|
|
|
/obj/item/examine()
|
|
set src in view()
|
|
|
|
var/t
|
|
switch(src.w_class)
|
|
if(1.0)
|
|
t = "tiny"
|
|
if(2.0)
|
|
t = "small"
|
|
if(3.0)
|
|
t = "normal-sized"
|
|
if(4.0)
|
|
t = "bulky"
|
|
if(5.0)
|
|
t = "huge"
|
|
else
|
|
if ((usr.mutations & CLOWN) && prob(50)) t = "funny-looking"
|
|
usr << text("This is a []\icon[][]. It is a [] item.", !src.blood_DNA ? "" : "bloody ",src, src.name, t)
|
|
usr << src.desc
|
|
return
|
|
|
|
/obj/item/attack_hand(mob/user as mob)
|
|
if (!user) return
|
|
if (istype(src.loc, /obj/item/weapon/storage))
|
|
for(var/mob/M in range(1, src.loc))
|
|
if (M.s_active == src.loc)
|
|
if (M.client)
|
|
M.client.screen -= src
|
|
src.throwing = 0
|
|
if (src.loc == user)
|
|
//canremove==0 means that object may not be removed. You can still wear it. This only applies to clothing. /N
|
|
if(istype(src, /obj/item/clothing) && !src:canremove)
|
|
return
|
|
else
|
|
user.u_equip(src)
|
|
else
|
|
src.pickup(user)
|
|
|
|
if (user.hand)
|
|
user.l_hand = src
|
|
else
|
|
user.r_hand = src
|
|
src.loc = user
|
|
src.layer = 20
|
|
add_fingerprint(user)
|
|
user.update_clothing()
|
|
return
|
|
|
|
|
|
/obj/item/attack_paw(mob/user as mob)
|
|
|
|
if(isalien(user)) // -- TLE
|
|
if(!user:has_fine_manipulation) // -- defaults to 0, only changes due to badminnery -- Urist
|
|
user << "Your claws aren't capable of such fine manipulation."
|
|
return
|
|
|
|
if (istype(src.loc, /obj/item/weapon/storage))
|
|
for(var/mob/M in range(1, src.loc))
|
|
if (M.s_active == src.loc)
|
|
if (M.client)
|
|
M.client.screen -= src
|
|
src.throwing = 0
|
|
if (src.loc == user)
|
|
//canremove==0 means that object may not be removed. You can still wear it. This only applies to clothing. /N
|
|
if(istype(src, /obj/item/clothing) && !src:canremove)
|
|
return
|
|
else
|
|
user.u_equip(src)
|
|
if (user.hand)
|
|
user.l_hand = src
|
|
else
|
|
user.r_hand = src
|
|
src.loc = user
|
|
src.layer = 20
|
|
user.update_clothing()
|
|
return
|
|
|
|
/obj/item/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
|
if (istype(W, /obj/item/weapon/packageWrap))
|
|
var/obj/item/weapon/packageWrap/O = W
|
|
if (O.amount > 1)
|
|
var/obj/item/smallDelivery/P = new /obj/item/smallDelivery(get_turf(src.loc))
|
|
P.wrapped = src
|
|
|
|
src.loc = P
|
|
O.amount -= 1
|
|
|
|
/obj/item/attack_self(mob/user as mob)
|
|
..()
|
|
if(twohanded)
|
|
if(wielded) //Trying to unwield it
|
|
wielded = 0
|
|
force = force_unwielded
|
|
src.name = "[initial(name)] (Unwielded)"
|
|
src.update_icon() //If needed by the particular item
|
|
user << "\blue You are now carrying the [initial(name)] with one hand."
|
|
|
|
if(istype(user.get_inactive_hand(),/obj/item/weapon/offhand))
|
|
del user.get_inactive_hand()
|
|
return
|
|
else //Trying to wield it
|
|
if(user.get_inactive_hand())
|
|
user << "\red You need your other hand to be empty"
|
|
return
|
|
wielded = 1
|
|
force = force_wielded
|
|
src.name = "[initial(name)] (Wielded)"
|
|
src.update_icon() //If needed by the particular item
|
|
user << "\blue You grab the [initial(name)] with both hands, It is ready for use."
|
|
|
|
var/obj/item/weapon/offhand/O = new /obj/item/weapon/offhand(user) ////Let's reserve his other hand~
|
|
O.name = text("[initial(src.name)] - Offhand")
|
|
O.desc = "Your second grip on the [initial(src.name)]"
|
|
if(user.hand)
|
|
user.r_hand = O ///Place dat offhand in the opposite hand
|
|
else
|
|
user.l_hand = O
|
|
O.layer = 20
|
|
return
|
|
|
|
/obj/item/proc/attack(mob/living/M as mob, mob/living/user as mob, def_zone)
|
|
|
|
if (!istype(M)) // not sure if this is the right thing...
|
|
return
|
|
var/messagesource = M
|
|
|
|
if (istype(M,/mob/living/carbon/brain))
|
|
messagesource = M:container
|
|
if (src.hitsound)
|
|
playsound(src.loc, hitsound, 50, 1, -1)
|
|
/////////////////////////
|
|
user.lastattacked = M
|
|
M.lastattacker = user
|
|
|
|
user.attack_log += "<font color='red'> Attacked [M.name] ([M.ckey]) with [src.name]</font>"
|
|
M.attack_log += "<font color='orange'> Attacked by [user.name] ([user.ckey]) with [src.name]</font>"
|
|
|
|
//spawn(1800) // this wont work right
|
|
// M.lastattacker = null
|
|
/////////////////////////
|
|
if(!istype(M, /mob/living/carbon/human))
|
|
for(var/mob/O in viewers(messagesource, null))
|
|
O.show_message(text("\red <B>[] has been attacked with [][] </B>", M, src, (user ? text(" by [].", user) : ".")), 1)
|
|
var/power = src.force
|
|
if (istype(M, /mob/living/carbon/human))
|
|
var/mob/living/carbon/human/H = M
|
|
if (ishuman(user) || isrobot(user) || ishivebot(user) || ismonkey(user) || isalien(user))
|
|
if (!( def_zone ))
|
|
var/mob/user2 = user
|
|
var/t = user2:zone_sel.selecting
|
|
if ((t in list( "eyes", "mouth" )))
|
|
t = "head"
|
|
def_zone = ran_zone(t)
|
|
var/datum/organ/external/affecting
|
|
if (H.organs[text("[]", def_zone)])
|
|
affecting = H.organs[text("[]", def_zone)]
|
|
var/hit_area = parse_zone(def_zone)
|
|
|
|
var/list/armor = H.getarmor(affecting, "melee")
|
|
//Grabbing the set of clothing that offers the best protective value against melee attacks to that area. --NEO
|
|
|
|
for(var/mob/O in viewers(M, null))
|
|
O.show_message(text("\red <B>[] has been attacked in the [] with [][] </B>", M, hit_area, src, (user ? text(" by [].", user) : ".")), 1)
|
|
if (istype(affecting, /datum/organ/external))
|
|
var/b_dam = (src.damtype == "brute" ? src.force : 0)
|
|
var/f_dam = (src.damtype == "fire" ? src.force : 0)
|
|
if (M.mutations & COLD_RESISTANCE)
|
|
f_dam = 0
|
|
if (def_zone == "head")
|
|
if (b_dam && prob(armor["armor"] - src.force))
|
|
if (prob(20))
|
|
affecting.take_damage(power, 0)
|
|
else
|
|
H.show_message("\red Your [armor["clothes"]] has protected you from a hit to the head.")
|
|
return
|
|
if ((b_dam && prob(src.force + affecting.brute_dam + affecting.burn_dam)))
|
|
var/time = rand(10, 120)
|
|
if (prob(90))
|
|
if (H.paralysis < time)
|
|
H.paralysis = time
|
|
else
|
|
if (H.weakened < time)
|
|
H.weakened = time
|
|
if(H.stat != 2) H.stat = 1
|
|
for(var/mob/O in viewers(M, null))
|
|
O.show_message(text("\red <B>[] has been knocked unconscious!</B>", H), 1, "\red You hear someone fall.", 2)
|
|
if (prob(50))
|
|
if (/*ticker.mode.name == "revolution" && */ M != user)
|
|
ticker.mode.remove_revolutionary(H.mind)
|
|
if (b_dam && prob(25 + (b_dam * 2)))
|
|
src.add_blood(H)
|
|
if (prob(33))
|
|
var/turf/location = H.loc
|
|
if (istype(location, /turf/simulated))
|
|
location.add_blood(H)
|
|
if (H.wear_mask)
|
|
H.wear_mask.add_blood(H)
|
|
if (H.head)
|
|
H.head.add_blood(H)
|
|
if (H.glasses && prob(33))
|
|
H.glasses.add_blood(H)
|
|
if (istype(user, /mob/living/carbon/human))
|
|
var/mob/living/carbon/human/user2 = user
|
|
if (user2.gloves)
|
|
user2.gloves.add_blood(H)
|
|
else
|
|
user2.add_blood(H)
|
|
if (prob(15))
|
|
if (user2.wear_suit)
|
|
user2.wear_suit.add_blood(H)
|
|
else if (user2.w_uniform)
|
|
user2.w_uniform.add_blood(H)
|
|
affecting.take_damage(b_dam, f_dam)
|
|
else if (def_zone == "chest" || def_zone == "groin")
|
|
if (b_dam && prob(armor["armor"] - src.force))
|
|
H.show_message("\red Your [armor["clothes"]] has protected you from a hit to the [affecting.name].")
|
|
return
|
|
if (b_dam && ((istype(H.r_hand, /obj/item/weapon/shield/riot))) && prob(90 - src.force))
|
|
H.show_message("\red You have been protected from a hit to the [affecting.name].")
|
|
return
|
|
if (b_dam && ((istype(H.l_hand, /obj/item/weapon/shield/riot))) && prob(90 - src.force))
|
|
H.show_message("\red You have been protected from a hit to the [affecting.name].")
|
|
return
|
|
if ((b_dam && prob(src.force + affecting.brute_dam + affecting.burn_dam)))
|
|
if (prob(50))
|
|
if (H.weakened < 5)
|
|
H.weakened = 5
|
|
for(var/mob/O in viewers(H, null))
|
|
O.show_message(text("\red <B>[] has been knocked down!</B>", H), 1, "\red You hear someone fall.", 2)
|
|
else
|
|
if (H.stunned < 2)
|
|
H.stunned = 2
|
|
for(var/mob/O in viewers(H, null))
|
|
O.show_message(text("\red <B>[] has been stunned!</B>", H), 1)
|
|
if(H.stat != 2) H.stat = 1
|
|
if (b_dam && prob(25 + (b_dam * 2)))
|
|
src.add_blood(H)
|
|
if (prob(33))
|
|
var/turf/location = H.loc
|
|
if (istype(location, /turf/simulated))
|
|
location.add_blood(H)
|
|
if (H.wear_suit)
|
|
H.wear_suit.add_blood(H)
|
|
if (H.w_uniform)
|
|
H.w_uniform.add_blood(H)
|
|
if (istype(user, /mob/living/carbon/human))
|
|
var/mob/living/carbon/human/user2 = user
|
|
if (user2.gloves)
|
|
user2.gloves.add_blood(H)
|
|
else
|
|
user2.add_blood(H)
|
|
if (prob(15))
|
|
if (user2.wear_suit)
|
|
user2.wear_suit.add_blood(H)
|
|
else if (user2.w_uniform)
|
|
user2.w_uniform.add_blood(H)
|
|
affecting.take_damage(b_dam, f_dam)
|
|
else
|
|
if (b_dam && prob(armor["armor"] - src.force))
|
|
H.show_message("\red Your [armor["clothes"]] has protected you from a hit to the [affecting.name].")
|
|
return
|
|
if (b_dam && prob(25 + (b_dam * 2)))
|
|
src.add_blood(H)
|
|
if (prob(33))
|
|
var/turf/location = H.loc
|
|
if (istype(location, /turf/simulated))
|
|
location.add_blood(H)
|
|
if (H.wear_suit)
|
|
H.wear_suit.add_blood(H)
|
|
if (H.w_uniform)
|
|
H.w_uniform.add_blood(H)
|
|
if (istype(user, /mob/living/carbon/human))
|
|
var/mob/living/carbon/human/user2 = user
|
|
if (user2.gloves)
|
|
user2.gloves.add_blood(H)
|
|
else
|
|
user2.add_blood(H)
|
|
if (prob(15))
|
|
if (user2.wear_suit)
|
|
user2.wear_suit.add_blood(H)
|
|
else if (user2.w_uniform)
|
|
user2.w_uniform.add_blood(H)
|
|
affecting.take_damage(b_dam, f_dam)
|
|
H.UpdateDamageIcon() ///Only reference I can find on the attack() proc actually changing mob icon -Agouri
|
|
else
|
|
switch(src.damtype)
|
|
if("brute")
|
|
M.take_organ_damage(power)
|
|
if (prob(33)) // Added blood for whacking non-humans too
|
|
var/turf/location = M.loc
|
|
if (istype(location, /turf/simulated))
|
|
location.add_blood_floor(M)
|
|
if("fire")
|
|
if (!(M.mutations & COLD_RESISTANCE))
|
|
M.take_organ_damage(0, power)
|
|
M << "Aargh it burns!"
|
|
M.updatehealth()
|
|
src.add_fingerprint(user)
|
|
return 1
|
|
|
|
/obj/item/proc/eyestab(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
|
|
|
|
var/mob/living/carbon/human/H = M
|
|
if(istype(H) && ( \
|
|
(H.head && H.head.flags & HEADCOVERSEYES) || \
|
|
(H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) || \
|
|
(H.glasses && H.glasses.flags & GLASSESCOVERSEYES) \
|
|
))
|
|
// you can't stab someone in the eyes wearing a mask!
|
|
user << "\red You're going to need to remove that mask/helmet/glasses first."
|
|
return
|
|
|
|
var/mob/living/carbon/monkey/Mo = M
|
|
if(istype(Mo) && ( \
|
|
(Mo.wear_mask && Mo.wear_mask.flags & MASKCOVERSEYES) \
|
|
))
|
|
// you can't stab someone in the eyes wearing a mask!
|
|
user << "\red You're going to need to remove that mask/helmet/glasses first."
|
|
return
|
|
|
|
if(istype(M, /mob/living/carbon/alien))//Aliens don't have eyes./N
|
|
user << "\red You cannot locate any eyes on this creature!"
|
|
return
|
|
|
|
src.add_fingerprint(user)
|
|
//if((user.mutations & CLOWN) && prob(50))
|
|
// M = user
|
|
/*
|
|
M << "\red You stab yourself in the eye."
|
|
M.sdisabilities |= 1
|
|
M.weakened += 4
|
|
M.bruteloss += 10
|
|
*/
|
|
|
|
if(M != user)
|
|
for(var/mob/O in (viewers(M) - user - M))
|
|
O.show_message("\red [M] has been stabbed in the eye with [src] by [user].", 1)
|
|
M << "\red [user] stabs you in the eye with [src]!"
|
|
user << "\red You stab [M] in the eye with [src]!"
|
|
else
|
|
user.visible_message( \
|
|
"\red [user] has stabbed themself with [src]!", \
|
|
"\red You stab yourself in the eyes with [src]!" \
|
|
)
|
|
if(istype(M, /mob/living/carbon/human))
|
|
var/datum/organ/external/affecting = M:organs["head"]
|
|
affecting.take_damage(7)
|
|
else
|
|
M.take_organ_damage(7)
|
|
M.eye_blurry += rand(3,4)
|
|
M.eye_stat += rand(2,4)
|
|
if (M.eye_stat >= 10)
|
|
M.eye_blurry += 15+(0.1*M.eye_blurry)
|
|
M.disabilities |= 1
|
|
if(M.stat != 2)
|
|
M << "\red Your eyes start to bleed profusely!"
|
|
if(prob(50))
|
|
if(M.stat != 2)
|
|
M << "\red You drop what you're holding and clutch at your eyes!"
|
|
M.drop_item()
|
|
M.eye_blurry += 10
|
|
M.paralysis += 1
|
|
M.weakened += 4
|
|
if (prob(M.eye_stat - 10 + 1))
|
|
if(M.stat != 2)
|
|
M << "\red You go blind!"
|
|
M.sdisabilities |= 1
|
|
return
|
|
|
|
|