mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-21 03:59:59 +01:00
Merge conflict begone
This commit is contained in:
@@ -102,6 +102,10 @@
|
||||
step_towards(M,src)
|
||||
for(var/obj/O in range(0,src))
|
||||
if(!O.anchored)
|
||||
if(isturf(O.loc))
|
||||
var/turf/T = O.loc
|
||||
if(T.intact && HAS_TRAIT(O, TRAIT_T_RAY_VISIBLE))
|
||||
continue
|
||||
var/mob/living/target = locate() in view(4,src)
|
||||
if(target && !target.stat)
|
||||
O.throw_at(target, 5, 10)
|
||||
|
||||
@@ -164,7 +164,7 @@
|
||||
return
|
||||
|
||||
to_chat(user, "<span class='notice'>The poster falls down!</span>")
|
||||
D.roll_and_drop(temp_loc)
|
||||
D.roll_and_drop(get_turf(user))
|
||||
|
||||
// Various possible posters follow
|
||||
|
||||
|
||||
@@ -141,6 +141,10 @@
|
||||
for(var/obj/O in range(0,src))
|
||||
if(O.type == src.type)
|
||||
continue
|
||||
if(isturf(O.loc))
|
||||
var/turf/T = O.loc
|
||||
if(T.intact && HAS_TRAIT(O, TRAIT_T_RAY_VISIBLE))
|
||||
continue
|
||||
if(lifetime % reagent_divisor)
|
||||
reagents.expose(O, VAPOR, fraction)
|
||||
var/hit = 0
|
||||
|
||||
@@ -232,6 +232,8 @@
|
||||
for(var/atom/movable/AM in T)
|
||||
if(AM.type == src.type)
|
||||
continue
|
||||
if(T.intact && HAS_TRAIT(AM, TRAIT_T_RAY_VISIBLE))
|
||||
continue
|
||||
reagents.expose(AM, TOUCH, fraction)
|
||||
|
||||
reagents.expose(T, TOUCH, fraction)
|
||||
|
||||
@@ -45,11 +45,6 @@
|
||||
. = ..()
|
||||
. += "This is a [generation]\th generation [name]!"
|
||||
|
||||
/obj/structure/glowshroom/Destroy()
|
||||
if(myseed)
|
||||
QDEL_NULL(myseed)
|
||||
return ..()
|
||||
|
||||
/**
|
||||
* Creates a new glowshroom structure.
|
||||
*
|
||||
@@ -142,6 +137,8 @@
|
||||
continue
|
||||
|
||||
Decay(TRUE, 2) // Decay before spawning new mushrooms to reduce their endurance
|
||||
if(QDELETED(src)) //Decay can end us
|
||||
return
|
||||
var/obj/structure/glowshroom/child = new type(newLoc, myseed, TRUE, TRUE)
|
||||
child.generation = generation + 1
|
||||
shrooms_planted++
|
||||
|
||||
@@ -154,8 +154,6 @@
|
||||
return FALSE
|
||||
if(!force && (!ismecha(M) && !istype(M, /obj/projectile) && M.anchored && !allow_anchored))
|
||||
return
|
||||
if(ismegafauna(M))
|
||||
message_admins("[M] has used a portal at [ADMIN_VERBOSEJMP(src)] made by [usr].")
|
||||
var/no_effect = FALSE
|
||||
if(last_effect == world.time)
|
||||
no_effect = TRUE
|
||||
|
||||
@@ -45,10 +45,6 @@
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
item_flags = NO_MAT_REDEMPTION
|
||||
|
||||
/obj/item/bodybag/bluespace/Initialize()
|
||||
. = ..()
|
||||
RegisterSignal(src, COMSIG_ATOM_CANREACH, .proc/CanReachReact)
|
||||
|
||||
/obj/item/bodybag/bluespace/examine(mob/user)
|
||||
. = ..()
|
||||
if(contents.len)
|
||||
@@ -62,9 +58,6 @@
|
||||
to_chat(A, "<span class='notice'>You suddenly feel the space around you torn apart! You're free!</span>")
|
||||
return ..()
|
||||
|
||||
/obj/item/bodybag/bluespace/proc/CanReachReact(atom/movable/source, list/next)
|
||||
return COMPONENT_BLOCK_REACH
|
||||
|
||||
/obj/item/bodybag/bluespace/deploy_bodybag(mob/user, atom/location)
|
||||
var/obj/structure/closet/body_bag/R = new unfoldedbag_path(location)
|
||||
for(var/atom/movable/A in contents)
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
var/energy = 10
|
||||
var/max_energy = 10
|
||||
var/effectchance = 30
|
||||
var/recharging = 0
|
||||
var/recharging = FALSE
|
||||
var/recharge_locked = FALSE
|
||||
var/obj/item/stock_parts/micro_laser/diode //used for upgrading!
|
||||
|
||||
@@ -178,7 +178,7 @@
|
||||
energy -= 1
|
||||
if(energy <= max_energy)
|
||||
if(!recharging)
|
||||
recharging = 1
|
||||
recharging = TRUE
|
||||
START_PROCESSING(SSobj, src)
|
||||
if(energy <= 0)
|
||||
to_chat(user, "<span class='warning'>[src]'s battery is overused, it needs time to recharge!</span>")
|
||||
@@ -188,10 +188,13 @@
|
||||
icon_state = "pointer"
|
||||
|
||||
/obj/item/laser_pointer/process()
|
||||
if(!diode)
|
||||
recharging = FALSE
|
||||
return PROCESS_KILL
|
||||
if(prob(20 + diode.rating*20 - recharge_locked*2)) //t1 is 20, 2 40
|
||||
energy += 1
|
||||
if(energy >= max_energy)
|
||||
energy = max_energy
|
||||
recharging = 0
|
||||
recharging = FALSE
|
||||
recharge_locked = FALSE
|
||||
..()
|
||||
return ..()
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
desc = "A portable device that dispenses and mixes chemicals. Requires a vortex anomaly core. All necessary reagents need to be supplied with beakers. A label indicates that a screwdriver is required to open it for refills. This device can be worn on a belt. The letters 'S&T' are imprinted on the side."
|
||||
icon = 'icons/obj/chemical.dmi'
|
||||
icon_state = "portablechemicalmixer_open"
|
||||
worn_icon_state = "portable_chem_mixer"
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
equip_sound = 'sound/items/equip/toolbelt_equip.ogg'
|
||||
|
||||
@@ -67,8 +67,7 @@ GENE SCANNER
|
||||
return
|
||||
var/list/t_ray_images = list()
|
||||
for(var/obj/O in orange(distance, viewer) )
|
||||
|
||||
if(O.invisibility == INVISIBILITY_MAXIMUM || HAS_TRAIT(O, TRAIT_T_RAY_VISIBLE))
|
||||
if(HAS_TRAIT(O, TRAIT_T_RAY_VISIBLE))
|
||||
var/image/I = new(loc = get_turf(O))
|
||||
var/mutable_appearance/MA = new(O)
|
||||
MA.alpha = 128
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
msg = "You hear something crackle in your ears for a moment before a voice speaks. \"Please stand by for a message from Central Command. Message as follows: <span class='bold'>Item request received. Your package is inbound, please stand back from the landing site.</span> Message ends.\""
|
||||
to_chat(M, msg)
|
||||
|
||||
new /obj/effect/dp_target(get_turf(src), pod)
|
||||
new /obj/effect/pod_landingzone(get_turf(src), pod)
|
||||
|
||||
/obj/item/choice_beacon/hero
|
||||
name = "heroic beacon"
|
||||
|
||||
@@ -275,6 +275,17 @@
|
||||
qdel(I)
|
||||
//BubbleWrap END
|
||||
|
||||
/obj/item/stack/vv_edit_var(vname, vval)
|
||||
if(vname == NAMEOF(src, amount))
|
||||
add(clamp(vval, 1-amount, max_amount - amount)) //there must always be one.
|
||||
return TRUE
|
||||
else if(vname == NAMEOF(src, max_amount))
|
||||
max_amount = max(vval, 1)
|
||||
add((max_amount < amount) ? (max_amount - amount) : 0) //update icon, weight, ect
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/item/stack/proc/building_checks(datum/stack_recipe/R, multiplier)
|
||||
if (get_amount() < R.req_amount*multiplier)
|
||||
if (R.req_amount*multiplier>1)
|
||||
|
||||
@@ -102,6 +102,7 @@
|
||||
desc = "This little bugger can be used to store and transport ores."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "satchel"
|
||||
worn_icon_state = "satchel"
|
||||
slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_POCKETS
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
component_type = /datum/component/storage/concrete/stack
|
||||
@@ -188,6 +189,7 @@
|
||||
name = "plant bag"
|
||||
icon = 'icons/obj/hydroponics/equipment.dmi'
|
||||
icon_state = "plantbag"
|
||||
worn_icon_state = "plantbag"
|
||||
resistance_flags = FLAMMABLE
|
||||
|
||||
/obj/item/storage/bag/plants/ComponentInitialize()
|
||||
@@ -230,6 +232,7 @@
|
||||
desc = "A patented Nanotrasen storage system designed for any kind of mineral sheet."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "sheetsnatcher"
|
||||
worn_icon_state = "satchel"
|
||||
|
||||
var/capacity = 300; //the number of sheets it can carry.
|
||||
component_type = /datum/component/storage/concrete/stack
|
||||
@@ -271,6 +274,7 @@
|
||||
desc = "A bag for books."
|
||||
icon = 'icons/obj/library.dmi'
|
||||
icon_state = "bookbag"
|
||||
worn_icon_state = "bookbag"
|
||||
resistance_flags = FLAMMABLE
|
||||
|
||||
/obj/item/storage/bag/books/ComponentInitialize()
|
||||
@@ -361,6 +365,7 @@
|
||||
name = "chemistry bag"
|
||||
icon = 'icons/obj/chemical.dmi'
|
||||
icon_state = "bag"
|
||||
worn_icon_state = "chembag"
|
||||
desc = "A bag for storing pills, patches, and bottles."
|
||||
resistance_flags = FLAMMABLE
|
||||
|
||||
@@ -389,6 +394,7 @@
|
||||
name = "bio bag"
|
||||
icon = 'icons/obj/chemical.dmi'
|
||||
icon_state = "biobag"
|
||||
worn_icon_state = "biobag"
|
||||
desc = "A bag for the safe transportation and disposal of biowaste and other biological materials."
|
||||
resistance_flags = FLAMMABLE
|
||||
|
||||
@@ -420,6 +426,7 @@
|
||||
name = "construction bag"
|
||||
icon = 'icons/obj/tools.dmi'
|
||||
icon_state = "construction_bag"
|
||||
worn_icon_state = "construction_bag"
|
||||
desc = "A bag for storing small construction components."
|
||||
resistance_flags = FLAMMABLE
|
||||
|
||||
|
||||
@@ -0,0 +1,632 @@
|
||||
/**
|
||||
* Mech prizes + MECHA COMBAT!!
|
||||
*/
|
||||
|
||||
/// Mech battle special attack types.
|
||||
#define SPECIAL_ATTACK_HEAL 1
|
||||
#define SPECIAL_ATTACK_DAMAGE 2
|
||||
#define SPECIAL_ATTACK_UTILITY 3
|
||||
#define SPECIAL_ATTACK_OTHER 4
|
||||
|
||||
/// Max length of a mech battle
|
||||
#define MAX_BATTLE_LENGTH 50
|
||||
|
||||
/obj/item/toy/prize
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "ripleytoy"
|
||||
verb_say = "beeps"
|
||||
verb_ask = "beeps"
|
||||
verb_exclaim = "beeps"
|
||||
verb_yell = "beeps"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
/// Timer when it'll be off cooldown
|
||||
var/timer = 0
|
||||
/// Cooldown between play sessions
|
||||
var/cooldown = 1.5 SECONDS
|
||||
/// Cooldown multiplier after a battle (by default: battle cooldowns are 30 seconds)
|
||||
var/cooldown_multiplier = 20
|
||||
/// If it makes noise when played with
|
||||
var/quiet = FALSE
|
||||
/// TRUE = Offering battle to someone || FALSE = Not offering battle
|
||||
var/wants_to_battle = FALSE
|
||||
/// TRUE = in combat currently || FALSE = Not in combat
|
||||
var/in_combat = FALSE
|
||||
/// The mech's health in battle
|
||||
var/combat_health = 0
|
||||
/// The mech's max combat health
|
||||
var/max_combat_health = 0
|
||||
/// TRUE = the special attack is charged || FALSE = not charged
|
||||
var/special_attack_charged = FALSE
|
||||
/// What type of special attack they use - SPECIAL_ATTACK_DAMAGE, SPECIAL_ATTACK_HEAL, SPECIAL_ATTACK_UTILITY, SPECIAL_ATTACK_OTHER
|
||||
var/special_attack_type = 0
|
||||
/// What message their special move gets on examining
|
||||
var/special_attack_type_message = ""
|
||||
/// The battlecry when using the special attack
|
||||
var/special_attack_cry = "*flip"
|
||||
/// Current cooldown of their special attack
|
||||
var/special_attack_cooldown = 0
|
||||
/// This mech's win count in combat
|
||||
var/wins = 0
|
||||
/// ...And their loss count in combat
|
||||
var/losses = 0
|
||||
|
||||
/obj/item/toy/prize/Initialize()
|
||||
. = ..()
|
||||
desc = "Mini-Mecha action figure! Collect them all! Attack your friends or another mech with one to initiate epic mech combat! [desc]."
|
||||
combat_health = max_combat_health
|
||||
switch(special_attack_type)
|
||||
if(SPECIAL_ATTACK_DAMAGE)
|
||||
special_attack_type_message = "an aggressive move, which deals bonus damage."
|
||||
if(SPECIAL_ATTACK_HEAL)
|
||||
special_attack_type_message = "a defensive move, which grants bonus healing."
|
||||
if(SPECIAL_ATTACK_UTILITY)
|
||||
special_attack_type_message = "a utility move, which heals the user and damages the opponent."
|
||||
if(SPECIAL_ATTACK_OTHER)
|
||||
special_attack_type_message = "a special move, which [special_attack_type_message]"
|
||||
else
|
||||
special_attack_type_message = "a mystery move, even I don't know."
|
||||
|
||||
/**
|
||||
* this proc combines "sleep" while also checking for if the battle should continue
|
||||
*
|
||||
* this goes through some of the checks - the toys need to be next to each other to fight!
|
||||
* if it's player vs themself: They need to be able to "control" both mechs (either must be adjacent or using TK)
|
||||
* if it's player vs player: Both players need to be able to "control" their mechs (either must be adjacent or using TK)
|
||||
* if it's player vs mech (suicide): the mech needs to be in range of the player
|
||||
* if all the checks are TRUE, it does the sleeps, and returns TRUE. Otherwise, it returns FALSE.
|
||||
* Arguments:
|
||||
* * delay - the amount of time the sleep at the end of the check will sleep for
|
||||
* * attacker - the attacking toy in the battle.
|
||||
* * attacker_controller - the controller of the attacking toy. there should ALWAYS be an attacker_controller
|
||||
* * opponent - (optional) the defender controller in the battle, for PvP
|
||||
*/
|
||||
/obj/item/toy/prize/proc/combat_sleep(var/delay, obj/item/toy/prize/attacker, mob/living/carbon/attacker_controller, mob/living/carbon/opponent)
|
||||
if(!attacker_controller)
|
||||
return FALSE
|
||||
|
||||
if(!attacker) //if there's no attacker, then attacker_controller IS the attacker
|
||||
if(!in_range(src, attacker_controller))
|
||||
attacker_controller.visible_message("<span class='suicide'>[attacker_controller] is running from [src]! The coward!</span>")
|
||||
return FALSE
|
||||
else // if there's an attacker, we can procede as normal
|
||||
if(!in_range(src, attacker)) //and the two toys aren't next to each other, the battle ends
|
||||
attacker_controller.visible_message("<span class='notice'> [attacker] and [src] separate, ending the battle. </span>", \
|
||||
"<span class='notice'> [attacker] and [src] separate, ending the battle. </span>")
|
||||
return FALSE
|
||||
|
||||
//dead men tell no tales, incapacitated men fight no fights
|
||||
if(attacker_controller.incapacitated())
|
||||
return FALSE
|
||||
//if the attacker_controller isn't next to the attacking toy (and doesn't have telekinesis), the battle ends
|
||||
if(!in_range(attacker, attacker_controller) && !(attacker_controller.dna.check_mutation(TK)))
|
||||
attacker_controller.visible_message("<span class='notice'> [attacker_controller.name] seperates from [attacker], ending the battle.</span>", \
|
||||
"<span class='notice'> You separate from [attacker], ending the battle. </span>")
|
||||
return FALSE
|
||||
|
||||
//if it's PVP and the opponent is not next to the defending(src) toy (and doesn't have telekinesis), the battle ends
|
||||
if(opponent)
|
||||
if(opponent.incapacitated())
|
||||
return FALSE
|
||||
if(!in_range(src, opponent) && !(opponent.dna.check_mutation(TK)))
|
||||
opponent.visible_message("<span class='notice'> [opponent.name] seperates from [src], ending the battle.</span>", \
|
||||
"<span class='notice'> You separate from [src], ending the battle. </span>")
|
||||
return FALSE
|
||||
//if it's not PVP and the attacker_controller isn't next to the defending toy (and doesn't have telekinesis), the battle ends
|
||||
else
|
||||
if (!in_range(src, attacker_controller) && !(attacker_controller.dna.check_mutation(TK)))
|
||||
attacker_controller.visible_message("<span class='notice'> [attacker_controller.name] seperates from [src] and [attacker], ending the battle.</span>", \
|
||||
"<span class='notice'> You separate [attacker] and [src], ending the battle. </span>")
|
||||
return FALSE
|
||||
|
||||
//if all that is good, then we can sleep peacefully
|
||||
sleep(delay)
|
||||
return TRUE
|
||||
|
||||
//all credit to skasi for toy mech fun ideas
|
||||
/obj/item/toy/prize/attack_self(mob/user)
|
||||
if(timer < world.time)
|
||||
to_chat(user, "<span class='notice'>You play with [src].</span>")
|
||||
timer = world.time + cooldown
|
||||
if(!quiet)
|
||||
playsound(user, 'sound/mecha/mechstep.ogg', 20, TRUE)
|
||||
else
|
||||
. = ..()
|
||||
|
||||
/obj/item/toy/prize/attack_hand(mob/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(loc == user)
|
||||
attack_self(user)
|
||||
|
||||
/**
|
||||
* If you attack a mech with a mech, initiate combat between them
|
||||
*/
|
||||
/obj/item/toy/prize/attackby(obj/item/user_toy, mob/living/user)
|
||||
if(istype(user_toy, /obj/item/toy/prize))
|
||||
var/obj/item/toy/prize/P = user_toy
|
||||
if(check_battle_start(user, P))
|
||||
mecha_brawl(P, user)
|
||||
..()
|
||||
|
||||
/**
|
||||
* Attack is called from the user's toy, aimed at target(another human), checking for target's toy.
|
||||
*/
|
||||
/obj/item/toy/prize/attack(mob/living/carbon/human/target, mob/living/carbon/human/user)
|
||||
if(target == user)
|
||||
to_chat(user, "<span class='notice'>Target another toy mech if you want to start a battle with yourself.</span>")
|
||||
return
|
||||
else if(user.a_intent != INTENT_HARM)
|
||||
if(wants_to_battle) //prevent spamming someone with offers
|
||||
to_chat(user, "<span class='notice'>You already are offering battle to someone!</span>")
|
||||
return
|
||||
if(!check_battle_start(user)) //if the user's mech isn't ready, don't bother checking
|
||||
return
|
||||
|
||||
for(var/obj/item/I in target.held_items)
|
||||
if(istype(I, /obj/item/toy/prize)) //if you attack someone with a mech who's also holding a mech, offer to battle them
|
||||
var/obj/item/toy/prize/P = I
|
||||
if(!P.check_battle_start(target, null, user)) //check if the attacker mech is ready
|
||||
break
|
||||
|
||||
//slap them with the metaphorical white glove
|
||||
if(P.wants_to_battle) //if the target mech wants to battle, initiate the battle from their POV
|
||||
mecha_brawl(P, target, user) //P = defender's mech / SRC = attacker's mech / target = defender / user = attacker
|
||||
P.wants_to_battle = FALSE
|
||||
return
|
||||
|
||||
//extend the offer of battle to the other mech
|
||||
to_chat(user, "<span class='notice'>You offer battle to [target.name]!</span>")
|
||||
to_chat(target, "<span class='notice'><b>[user.name] wants to battle with [user.p_their()] [name]!</b> <i>Attack them with a toy mech to initiate combat.</i></span>")
|
||||
wants_to_battle = TRUE
|
||||
addtimer(CALLBACK(src, .proc/withdraw_offer, user), 6 SECONDS)
|
||||
return
|
||||
|
||||
..()
|
||||
|
||||
/**
|
||||
* Overrides attack_tk - Sorry, you have to be face to face to initiate a battle, it's good sportsmanship
|
||||
*/
|
||||
/obj/item/toy/prize/attack_tk(mob/user)
|
||||
if(timer < world.time)
|
||||
to_chat(user, "<span class='notice'>You telekinetically play with [src].</span>")
|
||||
timer = world.time + cooldown
|
||||
if(!quiet)
|
||||
playsound(user, 'sound/mecha/mechstep.ogg', 20, TRUE)
|
||||
|
||||
/**
|
||||
* Resets the request for battle.
|
||||
*
|
||||
* For use in a timer, this proc resets the wants_to_battle variable after a short period.
|
||||
* Arguments:
|
||||
* * user - the user wanting to do battle
|
||||
*/
|
||||
/obj/item/toy/prize/proc/withdraw_offer(mob/living/carbon/user)
|
||||
if(wants_to_battle)
|
||||
wants_to_battle = FALSE
|
||||
to_chat(user, "<span class='notice'>You get the feeling they don't want to battle.</span>")
|
||||
/**
|
||||
* Starts a battle, toy mech vs player. Player... doesn't win.
|
||||
*/
|
||||
/obj/item/toy/prize/suicide_act(mob/living/carbon/user)
|
||||
if(in_combat)
|
||||
to_chat(user, "<span class='notice'>[src] is in battle, let it finish first.</span>")
|
||||
return
|
||||
|
||||
user.visible_message("<span class='suicide'>[user] begins a fight [user.p_they()] can't win with [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
|
||||
in_combat = TRUE
|
||||
sleep(1.5 SECONDS)
|
||||
for(var/i in 1 to 4)
|
||||
switch(i)
|
||||
if(1, 3)
|
||||
SpinAnimation(5, 0)
|
||||
playsound(src, 'sound/mecha/mechstep.ogg', 30, TRUE)
|
||||
user.adjustBruteLoss(25)
|
||||
user.adjustStaminaLoss(50)
|
||||
if(2)
|
||||
user.SpinAnimation(5, 0)
|
||||
playsound(user, 'sound/weapons/smash.ogg', 20, TRUE)
|
||||
combat_health-- //we scratched it!
|
||||
if(4)
|
||||
say(special_attack_cry + "!!")
|
||||
user.adjustStaminaLoss(25)
|
||||
|
||||
if(!combat_sleep(1 SECONDS, null, user))
|
||||
say("PATHETIC.")
|
||||
combat_health = max_combat_health
|
||||
in_combat = FALSE
|
||||
return SHAME
|
||||
|
||||
sleep(0.5 SECONDS)
|
||||
user.adjustBruteLoss(450)
|
||||
|
||||
in_combat = FALSE
|
||||
say("AN EASY WIN. MY POWER INCREASES.") // steal a soul, become swole
|
||||
add_atom_colour(rgb(255, 115, 115), ADMIN_COLOUR_PRIORITY)
|
||||
max_combat_health = round(max_combat_health*1.5 + 0.1)
|
||||
combat_health = max_combat_health
|
||||
wins++
|
||||
return BRUTELOSS
|
||||
|
||||
/obj/item/toy/prize/examine()
|
||||
. = ..()
|
||||
. += "<span class='notice'>This toy's special attack is [special_attack_cry], [special_attack_type_message] </span>"
|
||||
if(in_combat)
|
||||
. += "<span class='notice'>This toy has a maximum health of [max_combat_health]. Currently, it's [combat_health].</span>"
|
||||
. += "<span class='notice'>Its special move light is [special_attack_cooldown? "flashing red." : "green and is ready!"]</span>"
|
||||
else
|
||||
. += "<span class='notice'>This toy has a maximum health of [max_combat_health].</span>"
|
||||
|
||||
if(wins || losses)
|
||||
. += "<span class='notice'>This toy has [wins] wins, and [losses] losses.</span>"
|
||||
|
||||
/**
|
||||
* Override the say proc if they're mute
|
||||
*/
|
||||
/obj/item/toy/prize/say()
|
||||
if(!quiet)
|
||||
. = ..()
|
||||
|
||||
/**
|
||||
* The 'master' proc of the mech battle. Processes the entire battle's events and makes sure it start and finishes correctly.
|
||||
*
|
||||
* src is the defending toy, and the battle proc is called on it to begin the battle.
|
||||
* After going through a few checks at the beginning to ensure the battle can start properly, the battle begins a loop that lasts
|
||||
* until either toy has no more health. During this loop, it also ensures the mechs stay in combat range of each other.
|
||||
* It will then randomly decide attacks for each toy, occasionally making one or the other use their special attack.
|
||||
* When either mech has no more health, the loop ends, and it displays the victor and the loser while updating their stats and resetting them.
|
||||
* Arguments:
|
||||
* * attacker - the attacking toy, the toy in the attacker_controller's hands
|
||||
* * attacker_controller - the user, the one who is holding the toys / controlling the fight
|
||||
* * opponent - optional arg used in Mech PvP battles: the other person who is taking part in the fight (controls src)
|
||||
*/
|
||||
/obj/item/toy/prize/proc/mecha_brawl(obj/item/toy/prize/attacker, mob/living/carbon/attacker_controller, mob/living/carbon/opponent)
|
||||
//A GOOD DAY FOR A SWELL BATTLE!
|
||||
attacker_controller.visible_message("<span class='danger'> [attacker_controller.name] collides [attacker] with [src]! Looks like they're preparing for a brawl! </span>", \
|
||||
"<span class='danger'> You collide [attacker] into [src], sparking a fierce battle! </span>", \
|
||||
"<span class='hear'> You hear hard plastic smacking into hard plastic.</span>", COMBAT_MESSAGE_RANGE)
|
||||
|
||||
/// Who's in control of the defender (src)?
|
||||
var/mob/living/carbon/src_controller = (opponent)? opponent : attacker_controller
|
||||
/// How long has the battle been going?
|
||||
var/battle_length = 0
|
||||
|
||||
in_combat = TRUE
|
||||
attacker.in_combat = TRUE
|
||||
|
||||
//1.5 second cooldown * 20 = 30 second cooldown after a fight
|
||||
timer = world.time + cooldown*cooldown_multiplier
|
||||
attacker.timer = world.time + attacker.cooldown*attacker.cooldown_multiplier
|
||||
|
||||
sleep(1 SECONDS)
|
||||
//--THE BATTLE BEGINS--
|
||||
while(combat_health > 0 && attacker.combat_health > 0 && battle_length < MAX_BATTLE_LENGTH)
|
||||
if(!combat_sleep(0.5 SECONDS, attacker, attacker_controller, opponent)) //combat_sleep checks everything we need to have checked for combat to continue
|
||||
break
|
||||
|
||||
//before we do anything - deal with charged attacks
|
||||
if(special_attack_charged)
|
||||
src_controller.visible_message("<span class='danger'> [src] unleashes its special attack!! </span>", \
|
||||
"<span class='danger'> You unleash [src]'s special attack! </span>")
|
||||
special_attack_move(attacker)
|
||||
else if(attacker.special_attack_charged)
|
||||
|
||||
attacker_controller.visible_message("<span class='danger'> [attacker] unleashes its special attack!! </span>", \
|
||||
"<span class='danger'> You unleash [attacker]'s special attack! </span>")
|
||||
attacker.special_attack_move(src)
|
||||
else
|
||||
//process the cooldowns
|
||||
if(special_attack_cooldown > 0)
|
||||
special_attack_cooldown--
|
||||
if(attacker.special_attack_cooldown > 0)
|
||||
attacker.special_attack_cooldown--
|
||||
|
||||
//combat commences
|
||||
switch(rand(1,8))
|
||||
if(1 to 3) //attacker wins
|
||||
if(attacker.special_attack_cooldown == 0 && attacker.combat_health <= round(attacker.max_combat_health/3)) //if health is less than 1/3 and special off CD, use it
|
||||
attacker.special_attack_charged = TRUE
|
||||
attacker_controller.visible_message("<span class='danger'> [attacker] begins charging its special attack!! </span>", \
|
||||
"<span class='danger'> You begin charging [attacker]'s special attack! </span>")
|
||||
else //just attack
|
||||
attacker.SpinAnimation(5, 0)
|
||||
playsound(attacker, 'sound/mecha/mechstep.ogg', 30, TRUE)
|
||||
combat_health--
|
||||
attacker_controller.visible_message("<span class='danger'> [attacker] devastates [src]! </span>", \
|
||||
"<span class='danger'> You ram [attacker] into [src]! </span>", \
|
||||
"<span class='hear'> You hear hard plastic smacking hard plastic.</span>", COMBAT_MESSAGE_RANGE)
|
||||
if(prob(5))
|
||||
combat_health--
|
||||
playsound(src, 'sound/effects/meteorimpact.ogg', 20, TRUE)
|
||||
attacker_controller.visible_message("<span class='boldwarning'> ...and lands a CRIPPLING BLOW! </span>", \
|
||||
"<span class='boldwarning'> ...and you land a CRIPPLING blow on [src]! </span>", null, COMBAT_MESSAGE_RANGE)
|
||||
|
||||
if(4) //both lose
|
||||
attacker.SpinAnimation(5, 0)
|
||||
SpinAnimation(5, 0)
|
||||
combat_health--
|
||||
attacker.combat_health--
|
||||
do_sparks(2, FALSE, src)
|
||||
do_sparks(2, FALSE, attacker)
|
||||
if(prob(50))
|
||||
attacker_controller.visible_message("<span class='danger'> [attacker] and [src] clash dramatically, causing sparks to fly! </span>", \
|
||||
"<span class='danger'> [attacker] and [src] clash dramatically, causing sparks to fly! </span>", \
|
||||
"<span class='hear'> You hear hard plastic rubbing against hard plastic.</span>", COMBAT_MESSAGE_RANGE)
|
||||
else
|
||||
src_controller.visible_message("<span class='danger'> [src] and [attacker] clash dramatically, causing sparks to fly! </span>", \
|
||||
"<span class='danger'> [src] and [attacker] clash dramatically, causing sparks to fly! </span>", \
|
||||
"<span class='hear'> You hear hard plastic rubbing against hard plastic.</span>", COMBAT_MESSAGE_RANGE)
|
||||
if(5) //both win
|
||||
playsound(attacker, 'sound/weapons/parry.ogg', 20, TRUE)
|
||||
if(prob(50))
|
||||
attacker_controller.visible_message("<span class='danger'> [src]'s attack deflects off of [attacker]. </span>", \
|
||||
"<span class='danger'> [src]'s attack deflects off of [attacker]. </span>", \
|
||||
"<span class='hear'> You hear hard plastic bouncing off hard plastic.</span>", COMBAT_MESSAGE_RANGE)
|
||||
else
|
||||
src_controller.visible_message("<span class='danger'> [attacker]'s attack deflects off of [src]. </span>", \
|
||||
"<span class='danger'> [attacker]'s attack deflects off of [src]. </span>", \
|
||||
"<span class='hear'> You hear hard plastic bouncing off hard plastic.</span>", COMBAT_MESSAGE_RANGE)
|
||||
|
||||
if(6 to 8) //defender wins
|
||||
if(special_attack_cooldown == 0 && combat_health <= round(max_combat_health/3)) //if health is less than 1/3 and special off CD, use it
|
||||
special_attack_charged = TRUE
|
||||
src_controller.visible_message("<span class='danger'> [src] begins charging its special attack!! </span>", \
|
||||
"<span class='danger'> You begin charging [src]'s special attack! </span>")
|
||||
else //just attack
|
||||
SpinAnimation(5, 0)
|
||||
playsound(src, 'sound/mecha/mechstep.ogg', 30, TRUE)
|
||||
attacker.combat_health--
|
||||
src_controller.visible_message("<span class='danger'> [src] smashes [attacker]! </span>", \
|
||||
"<span class='danger'> You smash [src] into [attacker]! </span>", \
|
||||
"<span class='hear'> You hear hard plastic smashing hard plastic.</span>", COMBAT_MESSAGE_RANGE)
|
||||
if(prob(5))
|
||||
attacker.combat_health--
|
||||
playsound(attacker, 'sound/effects/meteorimpact.ogg', 20, TRUE)
|
||||
src_controller.visible_message("<span class='boldwarning'> ...and lands a CRIPPLING BLOW! </span>", \
|
||||
"<span class='boldwarning'> ...and you land a CRIPPLING blow on [attacker]! </span>", null, COMBAT_MESSAGE_RANGE)
|
||||
else
|
||||
attacker_controller.visible_message("<span class='notice'> [src] and [attacker] stand around awkwardly.</span>", \
|
||||
"<span class='notice'> You don't know what to do next.</span>")
|
||||
|
||||
battle_length++
|
||||
sleep(0.5 SECONDS)
|
||||
|
||||
/// Lines chosen for the winning mech
|
||||
var/list/winlines = list("YOU'RE NOTHING BUT SCRAP!", "I'LL YIELD TO NONE!", "GLORY IS MINE!", "AN EASY FIGHT.", "YOU SHOULD HAVE NEVER FACED ME.", "ROCKED AND SOCKED.")
|
||||
|
||||
if(attacker.combat_health <= 0 && combat_health <= 0) //both lose
|
||||
playsound(src, 'sound/machines/warning-buzzer.ogg', 20, TRUE)
|
||||
attacker_controller.visible_message("<span class='boldnotice'> MUTUALLY ASSURED DESTRUCTION!! [src] and [attacker] both end up destroyed!</span>", \
|
||||
"<span class='boldnotice'> Both [src] and [attacker] are destroyed!</span>")
|
||||
else if(attacker.combat_health <= 0) //src wins
|
||||
wins++
|
||||
attacker.losses++
|
||||
playsound(attacker, 'sound/effects/light_flicker.ogg', 20, TRUE)
|
||||
attacker_controller.visible_message("<span class='notice'> [attacker] falls apart!</span>", \
|
||||
"<span class='notice'> [attacker] falls apart!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
say("[pick(winlines)]")
|
||||
src_controller.visible_message("<span class='notice'> [src] destroys [attacker] and walks away victorious!</span>", \
|
||||
"<span class='notice'> You raise up [src] victoriously over [attacker]!</span>")
|
||||
else if (combat_health <= 0) //attacker wins
|
||||
attacker.wins++
|
||||
losses++
|
||||
playsound(src, 'sound/effects/light_flicker.ogg', 20, TRUE)
|
||||
src_controller.visible_message("<span class='notice'> [src] collapses!</span>", \
|
||||
"<span class='notice'> [src] collapses!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
attacker.say("[pick(winlines)]")
|
||||
attacker_controller.visible_message("<span class='notice'> [attacker] demolishes [src] and walks away victorious!</span>", \
|
||||
"<span class='notice'> You raise up [attacker] proudly over [src]</span>!")
|
||||
else //both win?
|
||||
say("NEXT TIME.")
|
||||
//don't want to make this a one sided conversation
|
||||
quiet? attacker.say("I WENT EASY ON YOU.") : attacker.say("OF COURSE.")
|
||||
|
||||
in_combat = FALSE
|
||||
attacker.in_combat = FALSE
|
||||
|
||||
combat_health = max_combat_health
|
||||
attacker.combat_health = attacker.max_combat_health
|
||||
|
||||
return
|
||||
|
||||
/**
|
||||
* This proc checks if a battle can be initiated between src and attacker.
|
||||
*
|
||||
* Both SRC and attacker (if attacker is included) timers are checked if they're on cooldown, and
|
||||
* both SRC and attacker (if attacker is included) are checked if they are in combat already.
|
||||
* If any of the above are true, the proc returns FALSE and sends a message to user (and target, if included) otherwise, it returns TRUE
|
||||
* Arguments:
|
||||
* * user: the user who is initiating the battle
|
||||
* * attacker: optional arg for checking two mechs at once
|
||||
* * target: optional arg used in Mech PvP battles (if used, attacker is target's toy)
|
||||
*/
|
||||
/obj/item/toy/prize/proc/check_battle_start(mob/living/carbon/user, obj/item/toy/prize/attacker, mob/living/carbon/target)
|
||||
if(attacker && attacker.in_combat)
|
||||
to_chat(user, "<span class='notice'>[target?target.p_their() : "Your" ] [attacker.name] is in combat.</span>")
|
||||
target?.to_chat(target, "<span class='notice'>Your [attacker.name] is in combat.</span>")
|
||||
return FALSE
|
||||
if(in_combat)
|
||||
to_chat(user, "<span class='notice'>Your [name] is in combat.</span>")
|
||||
target?.to_chat(target, "<span class='notice'>[target.p_their()] [name] is in combat.</span>")
|
||||
return FALSE
|
||||
if(attacker && attacker.timer > world.time)
|
||||
to_chat(user, "<span class='notice'>[target?target.p_their() : "Your" ] [attacker.name] isn't ready for battle.</span>")
|
||||
target?.to_chat(target, "<span class='notice'>Your [attacker.name] isn't ready for battle.</span>")
|
||||
return FALSE
|
||||
if(timer > world.time)
|
||||
to_chat(user, "<span class='notice'>Your [name] isn't ready for battle.</span>")
|
||||
target?.to_chat(target, "<span class='notice'>[target.p_their()] [name] isn't ready for battle.</span>")
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Processes any special attack moves that happen in the battle (called in the mechaBattle proc).
|
||||
*
|
||||
* Makes the toy shout their special attack cry and updates its cooldown. Then, does the special attack.
|
||||
* Arguments:
|
||||
* * victim - the toy being hit by the special move
|
||||
*/
|
||||
/obj/item/toy/prize/proc/special_attack_move(obj/item/toy/prize/victim)
|
||||
say(special_attack_cry + "!!")
|
||||
|
||||
special_attack_charged = FALSE
|
||||
special_attack_cooldown = 3
|
||||
|
||||
switch(special_attack_type)
|
||||
if(SPECIAL_ATTACK_DAMAGE) //+2 damage
|
||||
victim.combat_health-=2
|
||||
playsound(src, 'sound/weapons/marauder.ogg', 20, TRUE)
|
||||
if(SPECIAL_ATTACK_HEAL) //+2 healing
|
||||
combat_health+=2
|
||||
playsound(src, 'sound/mecha/mech_shield_raise.ogg', 20, TRUE)
|
||||
if(SPECIAL_ATTACK_UTILITY) //+1 heal, +1 damage
|
||||
victim.combat_health--
|
||||
combat_health++
|
||||
playsound(src, 'sound/mecha/mechmove01.ogg', 30, TRUE)
|
||||
if(SPECIAL_ATTACK_OTHER) //other
|
||||
super_special_attack(victim)
|
||||
else
|
||||
say("I FORGOT MY SPECIAL ATTACK...")
|
||||
|
||||
/**
|
||||
* Base proc for 'other' special attack moves.
|
||||
*
|
||||
* This one is only for inheritance, each mech with an 'other' type move has their procs below.
|
||||
* Arguments:
|
||||
* * victim - the toy being hit by the super special move (doesn't necessarily need to be used)
|
||||
*/
|
||||
/obj/item/toy/prize/proc/super_special_attack(obj/item/toy/prize/victim)
|
||||
visible_message("<span class='notice'> [src] does a cool flip.</span>")
|
||||
|
||||
/obj/item/toy/prize/ripley
|
||||
name = "toy Ripley"
|
||||
desc = "1/13"
|
||||
max_combat_health = 4 //200 integrity
|
||||
special_attack_type = SPECIAL_ATTACK_DAMAGE
|
||||
special_attack_cry = "GIGA DRILL BREAK"
|
||||
|
||||
/obj/item/toy/prize/fireripley //rip
|
||||
name = "toy Firefighting Ripley"
|
||||
desc = "2/13"
|
||||
icon_state = "fireripleytoy"
|
||||
max_combat_health = 5 //250 integrity?
|
||||
special_attack_type = SPECIAL_ATTACK_UTILITY
|
||||
special_attack_cry = "FIRE SHIELD"
|
||||
|
||||
/obj/item/toy/prize/deathripley
|
||||
name = "toy Deathsquad Ripley"
|
||||
desc = "3/13"
|
||||
icon_state = "deathripleytoy"
|
||||
max_combat_health = 5 //250 integrity
|
||||
special_attack_type = SPECIAL_ATTACK_OTHER
|
||||
special_attack_type_message = "instantly destroys the opposing mech if its health is less than this mech's health."
|
||||
special_attack_cry = "KILLER CLAMP"
|
||||
|
||||
/obj/item/toy/prize/deathripley/super_special_attack(obj/item/toy/prize/victim)
|
||||
playsound(src, 'sound/weapons/sonic_jackhammer.ogg', 20, TRUE)
|
||||
if(victim.combat_health < combat_health) //Instantly kills the other mech if it's health is below our's.
|
||||
say("EXECUTE!!")
|
||||
victim.combat_health = 0
|
||||
else //Otherwise, just deal one damage.
|
||||
victim.combat_health--
|
||||
|
||||
/obj/item/toy/prize/gygax
|
||||
name = "toy Gygax"
|
||||
desc = "4/13"
|
||||
icon_state = "gygaxtoy"
|
||||
max_combat_health = 5 //250 integrity
|
||||
special_attack_type = SPECIAL_ATTACK_UTILITY
|
||||
special_attack_cry = "SUPER SERVOS"
|
||||
|
||||
/obj/item/toy/prize/durand
|
||||
name = "toy Durand"
|
||||
desc = "5/13"
|
||||
icon_state = "durandtoy"
|
||||
max_combat_health = 6 //400 integrity
|
||||
special_attack_type = SPECIAL_ATTACK_HEAL
|
||||
special_attack_cry = "SHIELD OF PROTECTION"
|
||||
|
||||
/obj/item/toy/prize/honk
|
||||
name = "toy H.O.N.K."
|
||||
desc = "6/13"
|
||||
icon_state = "honktoy"
|
||||
max_combat_health = 4 //140 integrity
|
||||
special_attack_type = SPECIAL_ATTACK_OTHER
|
||||
special_attack_type_message = "puts the opposing mech's special move on cooldown and heals this mech."
|
||||
special_attack_cry = "MEGA HORN"
|
||||
|
||||
/obj/item/toy/prize/honk/super_special_attack(obj/item/toy/prize/victim)
|
||||
playsound(src, 'sound/machines/honkbot_evil_laugh.ogg', 20, TRUE)
|
||||
victim.special_attack_cooldown += 3 //Adds cooldown to the other mech and gives a minor self heal
|
||||
combat_health++
|
||||
|
||||
/obj/item/toy/prize/marauder
|
||||
name = "toy Marauder"
|
||||
desc = "7/13"
|
||||
icon_state = "maraudertoy"
|
||||
max_combat_health = 7 //500 integrity
|
||||
special_attack_type = SPECIAL_ATTACK_DAMAGE
|
||||
special_attack_cry = "BEAM BLAST"
|
||||
|
||||
/obj/item/toy/prize/seraph
|
||||
name = "toy Seraph"
|
||||
desc = "8/13"
|
||||
icon_state = "seraphtoy"
|
||||
max_combat_health = 8 //550 integrity
|
||||
special_attack_type = SPECIAL_ATTACK_DAMAGE
|
||||
special_attack_cry = "ROCKET BARRAGE"
|
||||
|
||||
/obj/item/toy/prize/mauler
|
||||
name = "toy Mauler"
|
||||
desc = "9/13"
|
||||
icon_state = "maulertoy"
|
||||
max_combat_health = 7 //500 integrity
|
||||
special_attack_type = SPECIAL_ATTACK_DAMAGE
|
||||
special_attack_cry = "BULLET STORM"
|
||||
|
||||
/obj/item/toy/prize/odysseus
|
||||
name = "toy Odysseus"
|
||||
desc = "10/13"
|
||||
icon_state = "odysseustoy"
|
||||
max_combat_health = 4 //120 integrity
|
||||
special_attack_type = SPECIAL_ATTACK_HEAL
|
||||
special_attack_cry = "MECHA BEAM"
|
||||
|
||||
/obj/item/toy/prize/phazon
|
||||
name = "toy Phazon"
|
||||
desc = "11/13"
|
||||
icon_state = "phazontoy"
|
||||
max_combat_health = 6 //200 integrity
|
||||
special_attack_type = SPECIAL_ATTACK_UTILITY
|
||||
special_attack_cry = "NO-CLIP"
|
||||
|
||||
/obj/item/toy/prize/reticence
|
||||
name = "toy Reticence"
|
||||
desc = "12/13"
|
||||
icon_state = "reticencetoy"
|
||||
quiet = TRUE
|
||||
max_combat_health = 4 //100 integrity
|
||||
special_attack_type = SPECIAL_ATTACK_OTHER
|
||||
special_attack_type_message = "has a lower cooldown than normal special moves, increases the opponent's cooldown, and deals damage."
|
||||
special_attack_cry = "*wave"
|
||||
|
||||
/obj/item/toy/prize/reticence/super_special_attack(obj/item/toy/prize/victim)
|
||||
special_attack_cooldown-- //Has a lower cooldown...
|
||||
victim.special_attack_cooldown++ //and increases the opponent's cooldown by 1...
|
||||
victim.combat_health-- //and some free damage.
|
||||
|
||||
/obj/item/toy/prize/clarke
|
||||
name = "toy Clarke"
|
||||
desc = "13/13"
|
||||
icon_state = "clarketoy"
|
||||
max_combat_health = 4 //200 integrity
|
||||
special_attack_type = SPECIAL_ATTACK_UTILITY
|
||||
special_attack_cry = "ROLL OUT"
|
||||
|
||||
#undef SPECIAL_ATTACK_HEAL
|
||||
#undef SPECIAL_ATTACK_DAMAGE
|
||||
#undef SPECIAL_ATTACK_UTILITY
|
||||
#undef SPECIAL_ATTACK_OTHER
|
||||
#undef MAX_BATTLE_LENGTH
|
||||
@@ -7,7 +7,6 @@
|
||||
* Toy swords
|
||||
* Crayons
|
||||
* Snap pops
|
||||
* Mech prizes
|
||||
* AI core prizes
|
||||
* Toy codex gigas
|
||||
* Skeleton toys
|
||||
@@ -26,7 +25,6 @@
|
||||
* Broken Radio
|
||||
*/
|
||||
|
||||
|
||||
/obj/item/toy
|
||||
throwforce = 0
|
||||
throw_speed = 3
|
||||
@@ -519,100 +517,6 @@
|
||||
new /obj/item/toy/snappop/phoenix(get_turf(src))
|
||||
qdel(src)
|
||||
|
||||
|
||||
/*
|
||||
* Mech prizes
|
||||
*/
|
||||
/obj/item/toy/prize
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "ripleytoy"
|
||||
var/timer = 0
|
||||
var/cooldown = 30
|
||||
var/quiet = 0
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
|
||||
//all credit to skasi for toy mech fun ideas
|
||||
/obj/item/toy/prize/attack_self(mob/user)
|
||||
if(timer < world.time)
|
||||
to_chat(user, "<span class='notice'>You play with [src].</span>")
|
||||
timer = world.time + cooldown
|
||||
if(!quiet)
|
||||
playsound(user, 'sound/mecha/mechstep.ogg', 20, TRUE)
|
||||
else
|
||||
. = ..()
|
||||
|
||||
/obj/item/toy/prize/attack_hand(mob/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(loc == user)
|
||||
attack_self(user)
|
||||
|
||||
/obj/item/toy/prize/ripley
|
||||
name = "toy Ripley"
|
||||
desc = "Mini-Mecha action figure! Collect them all! 1/13."
|
||||
|
||||
/obj/item/toy/prize/fireripley
|
||||
name = "toy firefighting Ripley"
|
||||
desc = "Mini-Mecha action figure! Collect them all! 2/13."
|
||||
icon_state = "fireripleytoy"
|
||||
|
||||
/obj/item/toy/prize/deathripley
|
||||
name = "toy deathsquad Ripley"
|
||||
desc = "Mini-Mecha action figure! Collect them all! 3/13."
|
||||
icon_state = "deathripleytoy"
|
||||
|
||||
/obj/item/toy/prize/gygax
|
||||
name = "toy Gygax"
|
||||
desc = "Mini-Mecha action figure! Collect them all! 4/13."
|
||||
icon_state = "gygaxtoy"
|
||||
|
||||
/obj/item/toy/prize/durand
|
||||
name = "toy Durand"
|
||||
desc = "Mini-Mecha action figure! Collect them all! 5/13."
|
||||
icon_state = "durandtoy"
|
||||
|
||||
/obj/item/toy/prize/honk
|
||||
name = "toy H.O.N.K."
|
||||
desc = "Mini-Mecha action figure! Collect them all! 6/13."
|
||||
icon_state = "honktoy"
|
||||
|
||||
/obj/item/toy/prize/marauder
|
||||
name = "toy Marauder"
|
||||
desc = "Mini-Mecha action figure! Collect them all! 7/13."
|
||||
icon_state = "maraudertoy"
|
||||
|
||||
/obj/item/toy/prize/seraph
|
||||
name = "toy Seraph"
|
||||
desc = "Mini-Mecha action figure! Collect them all! 8/13."
|
||||
icon_state = "seraphtoy"
|
||||
|
||||
/obj/item/toy/prize/mauler
|
||||
name = "toy Mauler"
|
||||
desc = "Mini-Mecha action figure! Collect them all! 9/13."
|
||||
icon_state = "maulertoy"
|
||||
|
||||
/obj/item/toy/prize/odysseus
|
||||
name = "toy Odysseus"
|
||||
desc = "Mini-Mecha action figure! Collect them all! 10/13."
|
||||
icon_state = "odysseustoy"
|
||||
|
||||
/obj/item/toy/prize/phazon
|
||||
name = "toy Phazon"
|
||||
desc = "Mini-Mecha action figure! Collect them all! 11/13."
|
||||
icon_state = "phazontoy"
|
||||
|
||||
/obj/item/toy/prize/reticence
|
||||
name = "toy Reticence"
|
||||
desc = "Mini-Mecha action figure! Collect them all! 12/13."
|
||||
icon_state = "reticencetoy"
|
||||
quiet = 1
|
||||
|
||||
/obj/item/toy/prize/clarke
|
||||
name = "toy Clarke"
|
||||
desc = "Mini-Mecha action figure! Collect them all! 13/13."
|
||||
icon_state = "clarketoy"
|
||||
|
||||
/obj/item/toy/talking
|
||||
name = "talking action figure"
|
||||
desc = "A generic action figure modeled after nothing in particular."
|
||||
|
||||
@@ -91,6 +91,10 @@
|
||||
return TRUE
|
||||
|
||||
/obj/blob_act(obj/structure/blob/B)
|
||||
if(isturf(loc))
|
||||
var/turf/T = loc
|
||||
if(T.intact && HAS_TRAIT(src, TRAIT_T_RAY_VISIBLE))
|
||||
return
|
||||
take_damage(400, BRUTE, "melee", 0, get_dir(src, B))
|
||||
|
||||
/obj/proc/attack_generic(mob/user, damage_amount = 0, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, armor_penetration = 0) //used by attack_alien, attack_animal, and attack_slime
|
||||
@@ -198,6 +202,10 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
|
||||
|
||||
///Called when the obj is exposed to fire.
|
||||
/obj/fire_act(exposed_temperature, exposed_volume)
|
||||
if(isturf(loc))
|
||||
var/turf/T = loc
|
||||
if(T.intact && HAS_TRAIT(src, TRAIT_T_RAY_VISIBLE))
|
||||
return
|
||||
if(exposed_temperature && !(resistance_flags & FIRE_PROOF))
|
||||
take_damage(clamp(0.02 * exposed_temperature, 0, 20), BURN, "fire", 0)
|
||||
if(!(resistance_flags & ON_FIRE) && (resistance_flags & FLAMMABLE) && !(resistance_flags & FIRE_PROOF))
|
||||
|
||||
@@ -46,11 +46,6 @@
|
||||
update_icon()
|
||||
PopulateContents()
|
||||
|
||||
RegisterSignal(src, COMSIG_ATOM_CANREACH, .proc/canreach_react)
|
||||
|
||||
/obj/structure/closet/proc/canreach_react(datum/source, list/next)
|
||||
return COMPONENT_BLOCK_REACH //closed block, open have nothing inside.
|
||||
|
||||
//USE THIS TO FILL IT, NOT INITIALIZE OR NEW
|
||||
/obj/structure/closet/proc/PopulateContents()
|
||||
return
|
||||
@@ -61,6 +56,8 @@
|
||||
|
||||
/obj/structure/closet/update_icon()
|
||||
. = ..()
|
||||
if (istype(src, /obj/structure/closet/supplypod))
|
||||
return
|
||||
if(!opened)
|
||||
layer = OBJ_LAYER
|
||||
else
|
||||
@@ -337,8 +334,11 @@
|
||||
var/mob/living/L = O
|
||||
if(!issilicon(L))
|
||||
L.Paralyze(40)
|
||||
O.forceMove(T)
|
||||
close()
|
||||
if(istype(src, /obj/structure/closet/supplypod/extractionpod))
|
||||
O.forceMove(src)
|
||||
else
|
||||
O.forceMove(T)
|
||||
close()
|
||||
else
|
||||
O.forceMove(T)
|
||||
return 1
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
/obj/structure/sacrificealtar
|
||||
name = "sacrificial altar"
|
||||
desc = "An altar designed to perform blood sacrifice for a deity."
|
||||
desc = "An altar designed to perform blood sacrifice for a deity. Alt-click it to sacrifice a buckled creature."
|
||||
icon = 'icons/obj/hand_of_god_structures.dmi'
|
||||
icon_state = "sacrificealtar"
|
||||
anchored = TRUE
|
||||
density = FALSE
|
||||
can_buckle = 1
|
||||
|
||||
/obj/structure/sacrificealtar/attack_hand(mob/living/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
/obj/structure/sacrificealtar/AltClick(mob/living/user)
|
||||
..()
|
||||
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE))
|
||||
return
|
||||
if(!has_buckled_mobs())
|
||||
return
|
||||
var/mob/living/L = locate() in buckled_mobs
|
||||
if(!L)
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You attempt to sacrifice [L] by invoking the sacrificial ritual.</span>")
|
||||
to_chat(user, "<span class='notice'>Invoking the sacred ritual, you sacrifice [L].</span>")
|
||||
L.gib()
|
||||
message_admins("[ADMIN_LOOKUPFLW(user)] has sacrificed [key_name_admin(L)] on the sacrificial altar at [AREACOORD(src)].")
|
||||
|
||||
|
||||
@@ -13,15 +13,46 @@
|
||||
icon_state = "headpike-bone"
|
||||
bonespear = TRUE
|
||||
|
||||
/obj/structure/headpike/Initialize(mapload)
|
||||
. = ..()
|
||||
if(mapload)
|
||||
CheckParts()
|
||||
|
||||
/obj/structure/headpike/CheckParts(list/parts_list)
|
||||
..()
|
||||
victim = locate(/obj/item/bodypart/head) in parts_list
|
||||
name = "[victim.name] on a spear"
|
||||
if(!victim) //likely a mapspawned one
|
||||
victim = new(src)
|
||||
victim.real_name = random_unique_name(prob(50))
|
||||
name = "[victim.real_name] on a spear"
|
||||
update_icon()
|
||||
if(bonespear)
|
||||
spear = locate(/obj/item/spear/bonespear) in parts_list
|
||||
else
|
||||
spear = locate(/obj/item/spear) in parts_list
|
||||
spear = locate(bonespear ? /obj/item/spear/bonespear : /obj/item/spear) in parts_list
|
||||
if(!spear)
|
||||
spear = bonespear ? new/obj/item/spear/bonespear(src) : new/obj/item/spear(src)
|
||||
|
||||
/obj/structure/headpike/Destroy()
|
||||
QDEL_NULL(victim)
|
||||
QDEL_NULL(spear)
|
||||
return ..()
|
||||
|
||||
/obj/structure/headpike/handle_atom_del(atom/A)
|
||||
if(A == victim)
|
||||
victim = null
|
||||
if(A == spear)
|
||||
spear = null
|
||||
deconstruct(TRUE)
|
||||
return ..()
|
||||
|
||||
/obj/structure/headpike/deconstruct(disassembled)
|
||||
if(!disassembled)
|
||||
return ..()
|
||||
if(victim)
|
||||
victim.forceMove(drop_location())
|
||||
victim = null
|
||||
if(spear)
|
||||
spear.forceMove(drop_location())
|
||||
spear = null
|
||||
return ..()
|
||||
|
||||
/obj/structure/headpike/Initialize()
|
||||
. = ..()
|
||||
@@ -41,9 +72,4 @@
|
||||
if(.)
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You take down [src].</span>")
|
||||
if(victim)
|
||||
victim.forceMove(drop_location())
|
||||
victim = null
|
||||
spear.forceMove(drop_location())
|
||||
spear = null
|
||||
qdel(src)
|
||||
deconstruct(TRUE)
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
anchored = TRUE
|
||||
var/obj/structure/ladder/down //the ladder below this one
|
||||
var/obj/structure/ladder/up //the ladder above this one
|
||||
obj_flags = CAN_BE_HIT | BLOCK_Z_OUT_DOWN
|
||||
|
||||
/obj/structure/ladder/Initialize(mapload, obj/structure/ladder/up, obj/structure/ladder/down)
|
||||
..()
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
/obj/structure/falsewall)
|
||||
smooth = SMOOTH_MORE
|
||||
// flags = CONDUCT_1
|
||||
obj_flags = CAN_BE_HIT | BLOCK_Z_OUT_DOWN
|
||||
|
||||
/obj/structure/lattice/examine(mob/user)
|
||||
. = ..()
|
||||
@@ -77,7 +78,7 @@
|
||||
number_of_mats = 2
|
||||
smooth = SMOOTH_TRUE
|
||||
canSmoothWith = null
|
||||
obj_flags = CAN_BE_HIT | BLOCK_Z_FALL
|
||||
obj_flags = CAN_BE_HIT | BLOCK_Z_OUT_DOWN | BLOCK_Z_IN_UP
|
||||
|
||||
/obj/structure/lattice/catwalk/deconstruction_hints(mob/user)
|
||||
return "<span class='notice'>The supporting rods look like they could be <b>cut</b>.</span>"
|
||||
@@ -103,7 +104,7 @@
|
||||
color = "#5286b9ff"
|
||||
smooth = SMOOTH_TRUE
|
||||
canSmoothWith = null
|
||||
obj_flags = CAN_BE_HIT | BLOCK_Z_FALL
|
||||
obj_flags = CAN_BE_HIT | BLOCK_Z_OUT_DOWN | BLOCK_Z_IN_UP
|
||||
resistance_flags = FIRE_PROOF | LAVA_PROOF
|
||||
|
||||
/obj/structure/lattice/lava/deconstruction_hints(mob/user)
|
||||
|
||||
@@ -67,20 +67,21 @@
|
||||
return TRUE
|
||||
|
||||
/obj/structure/railing/CanPass(atom/movable/mover, turf/target)
|
||||
..()
|
||||
. = ..()
|
||||
if(get_dir(loc, target) & dir)
|
||||
var/checking = UNSTOPPABLE | FLYING | FLOATING
|
||||
return !density || mover.movement_type & checking
|
||||
var/checking = FLYING | FLOATING
|
||||
return . || mover.movement_type & checking
|
||||
return TRUE
|
||||
|
||||
/obj/structure/railing/corner/CanPass()
|
||||
..()
|
||||
return TRUE
|
||||
|
||||
/obj/structure/railing/CheckExit(atom/movable/O, turf/target)
|
||||
/obj/structure/railing/CheckExit(atom/movable/mover, turf/target)
|
||||
..()
|
||||
if(get_dir(loc, target) & dir)
|
||||
return FALSE
|
||||
var/checking = UNSTOPPABLE | FLYING | FLOATING
|
||||
return !density || mover.movement_type & checking || mover.move_force >= MOVE_FORCE_EXTREMELY_STRONG
|
||||
return TRUE
|
||||
|
||||
/obj/structure/railing/corner/CheckExit()
|
||||
|
||||
Reference in New Issue
Block a user