Merge branch 'master' into upstream-merge-33614

This commit is contained in:
LetterJay
2017-12-21 05:02:21 -06:00
committed by GitHub
522 changed files with 9343 additions and 4611 deletions
+3 -2
View File
@@ -40,6 +40,7 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
* `COMPONENT_DUPE_HIGHLANDER` (default): Old component will be deleted, new component will first have `/datum/component/proc/InheritComponent(datum/component/old, FALSE)` on it
* `COMPONENT_DUPE_ALLOWED`: The components will be treated as separate, `GetComponent()` will return the first added
* `COMPONENT_DUPE_UNIQUE`: New component will be deleted, old component will first have `/datum/component/proc/InheritComponent(datum/component/new, TRUE)` on it
* `COMPONENT_DUPE_UNIQUE_PASSARGS`: New component will never exist and instead its initialization arguments will be passed on to the old component.
1. `/datum/component/var/dupe_type` (protected, type)
* Definition of a duplicate component type
* `null` means exact match on `type` (default)
@@ -66,6 +67,7 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
* All components a datum owns are deleted with the datum
* Returns the component that was created. Or the old component in a dupe situation where `COMPONENT_DUPE_UNIQUE` was set
* If this tries to add an component to an incompatible type, the component will be deleted and the result will be `null`. This is very unperformant, try not to do it
* Properly handles duplicate situations based on the `dupe_mode` var
1. `/datum/proc/LoadComponent(component_type(type), ...) -> datum/component` (public, final)
* Equivalent to calling `GetComponent(component_type)` where, if the result would be `null`, returns `AddComponent(component_type, ...)` instead
1. `/datum/proc/ComponentActivated(datum/component/C)` (abstract, async)
@@ -104,9 +106,8 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo
* Allows the component to react to ownership transfers
1. `/datum/component/proc/_RemoveFromParent()` (private, final)
* Clears `parent` and removes the component from it's component list
1. `/datum/component/proc/_CheckDupesAndJoinParent` (private, final)
1. `/datum/component/proc/_JoinParent` (private, final)
* Tries to add the component to it's `parent`s `datum_components` list
* Properly handles duplicate situations based on the `dupe_mode` var
1. `/datum/component/proc/RegisterSignal(signal(string/list of strings), proc_ref(type), override(boolean))` (protected, final) (Consider removing for performance gainz)
* If signal is a list it will be as if RegisterSignal was called for each of the entries with the same following arguments
* Makes a component listen for the specified `signal` on it's `parent` datum.
+56 -44
View File
@@ -6,54 +6,16 @@
var/datum/parent
/datum/component/New(datum/P, ...)
if(type == /datum/component)
qdel(src)
CRASH("[type] instantiated!")
//check for common mishaps
if(!isnum(dupe_mode))
qdel(src)
CRASH("[type]: Invalid dupe_mode!")
var/dt = dupe_type
if(dt && !ispath(dt))
qdel(src)
CRASH("[type]: Invalid dupe_type!")
parent = P
var/list/arguments = args.Copy(2)
if(Initialize(arglist(arguments)) == COMPONENT_INCOMPATIBLE)
qdel(src, TRUE, TRUE)
return
_CheckDupesAndJoinParent(P)
_JoinParent(P)
/datum/component/proc/_CheckDupesAndJoinParent()
/datum/component/proc/_JoinParent()
var/datum/P = parent
var/dm = dupe_mode
var/datum/component/old
if(dm != COMPONENT_DUPE_ALLOWED)
var/dt = dupe_type
if(!dt)
old = P.GetExactComponent(type)
else
old = P.GetComponent(dt)
if(old)
//One or the other has to die
switch(dm)
if(COMPONENT_DUPE_UNIQUE)
old.InheritComponent(src, TRUE)
qdel(src, TRUE, TRUE)
return
if(COMPONENT_DUPE_HIGHLANDER)
InheritComponent(old, FALSE)
qdel(old, FALSE, TRUE)
//provided we didn't eat someone
if(!old)
//let the others know
P.SendSignal(COMSIG_COMPONENT_ADDED, src)
//lazy init the parent's dc list
var/list/dc = P.datum_components
if(!dc)
@@ -212,10 +174,59 @@
return list(.)
/datum/proc/AddComponent(new_type, ...)
var/nt = new_type
var/datum/component/nt = new_type
var/dm = initial(nt.dupe_mode)
var/dt = initial(nt.dupe_type)
var/datum/component/old_comp
var/datum/component/new_comp
if(ispath(nt))
if(nt == /datum/component)
CRASH("[nt] attempted instantiation!")
if(!isnum(dm))
CRASH("[nt]: Invalid dupe_mode ([dm])!")
if(dt && !ispath(dt))
CRASH("[nt]: Invalid dupe_type ([dt])!")
else
new_comp = nt
args[1] = src
var/datum/component/C = new nt(arglist(args))
return QDELING(C) ? GetExactComponent(new_type) : C
if(dm != COMPONENT_DUPE_ALLOWED)
if(!dt)
old_comp = GetExactComponent(nt)
else
old_comp = GetComponent(dt)
if(old_comp)
switch(dm)
if(COMPONENT_DUPE_UNIQUE)
if(!new_comp)
new_comp = new nt(arglist(args))
if(!QDELETED(new_comp))
old_comp.InheritComponent(new_comp, TRUE)
qdel(new_comp)
if(COMPONENT_DUPE_HIGHLANDER)
if(!new_comp)
new_comp = new nt(arglist(args))
if(!QDELETED(new_comp))
new_comp.InheritComponent(old_comp, FALSE)
qdel(old_comp)
if(COMPONENT_DUPE_UNIQUE_PASSARGS)
if(!new_comp)
var/list/arguments = args.Copy(2)
old_comp.InheritComponent(null, TRUE, arguments)
else
old_comp.InheritComponent(new_comp, TRUE)
else if(!new_comp)
new_comp = new nt(arglist(args)) // There's a valid dupe mode but there's no old component, act like normal
else if(!new_comp)
new_comp = new nt(arglist(args)) // Dupes are allowed, act like normal
if(!old_comp && !QDELETED(new_comp)) // Nothing related to duplicate components happened and the new component is healthy
SendSignal(COMSIG_COMPONENT_ADDED, new_comp)
return new_comp
return old_comp
/datum/proc/LoadComponent(component_type, ...)
. = GetComponent(component_type)
@@ -235,7 +246,8 @@
C._RemoveFromParent()
helicopter.SendSignal(COMSIG_COMPONENT_REMOVING, C)
C.parent = src
C._CheckDupesAndJoinParent()
if(C == AddComponent(C))
C._JoinParent()
/datum/proc/TransferComponents(datum/target)
var/list/dc = datum_components
+1 -1
View File
@@ -6,7 +6,7 @@
var/datum/callback/callback
/datum/component/archaeology/Initialize(_prob2drop, list/_archdrops = list(), datum/callback/_callback)
prob2drop = Clamp(_prob2drop, 0, 100)
prob2drop = CLAMP(_prob2drop, 0, 100)
archdrops = _archdrops
callback = _callback
RegisterSignal(COMSIG_PARENT_ATTACKBY,.proc/Dig)
+81
View File
@@ -0,0 +1,81 @@
/datum/component/jousting
var/current_direction = NONE
var/max_tile_charge = 5
var/min_tile_charge = 2 //tiles before this code gets into effect.
var/current_tile_charge = 0
var/movement_reset_tolerance = 2 //deciseconds
var/unmounted_damage_boost_per_tile = 0
var/unmounted_knockdown_chance_per_tile = 0
var/unmounted_knockdown_time = 0
var/mounted_damage_boost_per_tile = 2
var/mounted_knockdown_chance_per_tile = 20
var/mounted_knockdown_time = 20
var/requires_mob_riding = TRUE //whether this only works if the attacker is riding a mob, rather than anything they can buckle to.
var/requires_mount = TRUE //kinda defeats the point of jousting if you're not mounted but whatever.
var/mob/current_holder
var/datum/component/redirect/listener
var/current_timerid
/datum/component/jousting/Initialize()
if(!isitem(parent))
. = COMPONENT_INCOMPATIBLE
stack_trace("Warning: Jousting component incorrectly applied to invalid parent type [parent.type]")
RegisterSignal(COMSIG_ITEM_EQUIPPED, .proc/on_equip)
RegisterSignal(COMSIG_ITEM_DROPPED, .proc/on_drop)
RegisterSignal(COMSIG_ITEM_ATTACK, .proc/on_attack)
/datum/component/jousting/Destroy()
QDEL_NULL(listener)
return ..()
/datum/component/jousting/proc/on_equip(mob/user, slot)
QDEL_NULL(listener)
current_holder = user
listener = new(user, COMSIG_MOVABLE_MOVED, CALLBACK(src, .proc/mob_move))
/datum/component/jousting/proc/on_drop(mob/user)
QDEL_NULL(listener)
current_holder = null
current_direction = NONE
current_tile_charge = 0
/datum/component/jousting/proc/on_attack(mob/living/target, mob/user)
if(user != current_holder)
return
var/current = current_tile_charge
var/obj/item/I = parent
var/target_buckled = target.buckled ? TRUE : FALSE //we don't need the reference of what they're buckled to, just whether they are.
if((requires_mount && ((requires_mob_riding && !ismob(user.buckled)) || (!user.buckled))) || !current_direction || (current_tile_charge < min_tile_charge))
return
var/turf/target_turf = get_step(user, current_direction)
if(target in range(1, target_turf))
var/knockdown_chance = (target_buckled? mounted_knockdown_chance_per_tile : unmounted_knockdown_chance_per_tile) * current
var/knockdown_time = (target_buckled? mounted_knockdown_time : unmounted_knockdown_time)
var/damage = (target_buckled? mounted_damage_boost_per_tile : unmounted_damage_boost_per_tile) * current
var/sharp = I.is_sharp()
var/msg
if(damage)
msg += "[user] [sharp? "impales" : "slams into"] [target] [sharp? "on" : "with"] their [parent]"
target.apply_damage(damage, BRUTE, user.zone_selected, 0)
if(prob(knockdown_chance))
msg += " and knocks [target] [target_buckled? "off of [target.buckled]" : "down"]"
if(target_buckled)
target.buckled.unbuckle_mob(target)
target.Knockdown(knockdown_time)
if(length(msg))
user.visible_message("<span class='danger'>[msg]!</span>")
/datum/component/jousting/proc/mob_move(newloc, dir)
if(!current_holder || (requires_mount && ((requires_mob_riding && !ismob(current_holder.buckled)) || (!current_holder.buckled))))
return
if(dir != current_direction)
current_tile_charge = 0
current_direction = dir
if(current_tile_charge < max_tile_charge)
current_tile_charge++
if(current_timerid)
deltimer(current_timerid)
current_timerid = addtimer(CALLBACK(src, .proc/reset_charge), movement_reset_tolerance, TIMER_STOPPABLE)
/datum/component/jousting/proc/reset_charge()
current_tile_charge = 0
+53
View File
@@ -0,0 +1,53 @@
//Items with these will have a chance to get knocked off when disarming
/datum/component/knockoff
var/knockoff_chance = 100 //Chance to knockoff
var/list/target_zones //Aiming for these zones will cause the knockoff, null means all zones allowed
var/list/slots_knockoffable //Can be only knocked off from these slots, null means all slots allowed
var/datum/component/redirect/disarm_redirect
/datum/component/knockoff/Initialize(knockoff_chance,zone_override,slots_knockoffable)
if(!isitem(parent))
. = COMPONENT_INCOMPATIBLE
CRASH("Knockoff component misuse")
RegisterSignal(COMSIG_ITEM_EQUIPPED,.proc/OnEquipped)
RegisterSignal(COMSIG_ITEM_DROPPED,.proc/OnDropped)
src.knockoff_chance = knockoff_chance
if(zone_override)
target_zones = zone_override
if(slots_knockoffable)
src.slots_knockoffable = slots_knockoffable
/datum/component/knockoff/proc/Knockoff(mob/living/attacker,zone)
var/obj/item/I = parent
var/mob/living/carbon/human/wearer = I.loc
if(!istype(wearer))
return
if(target_zones && !(zone in target_zones))
return
if(!prob(knockoff_chance))
return
if(!wearer.dropItemToGround(I))
return
wearer.visible_message("<span class='warning'>[attacker] knocks off [wearer]'s [I.name]!</span>","<span class='userdanger'>[attacker] knocks off your [I.name]!</span>")
/datum/component/knockoff/proc/OnEquipped(mob/living/carbon/human/H,slot)
if(!istype(H))
return
if(slots_knockoffable && !(slot in slots_knockoffable))
if(disarm_redirect)
QDEL_NULL(disarm_redirect)
return
if(!disarm_redirect)
disarm_redirect = H.AddComponent(/datum/component/redirect,list(COMSIG_HUMAN_DISARM_HIT),CALLBACK(src,.proc/Knockoff))
/datum/component/knockoff/proc/OnDropped(mob/living/M)
if(disarm_redirect)
QDEL_NULL(disarm_redirect)
/datum/component/knockoff/Destroy()
QDEL_NULL(disarm_redirect)
. = ..()
+7 -4
View File
@@ -4,7 +4,7 @@
#define RAD_AMOUNT_EXTREME 1000
/datum/component/radioactive
dupe_mode = COMPONENT_DUPE_UNIQUE
dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
var/source
@@ -47,13 +47,16 @@
if(strength <= RAD_BACKGROUND_RADIATION)
return PROCESS_KILL
/datum/component/radioactive/InheritComponent(datum/component/C, i_am_original)
/datum/component/radioactive/InheritComponent(datum/component/C, i_am_original, list/arguments)
if(!i_am_original)
return
if(!hl3_release_date) // Permanently radioactive things don't get to grow stronger
return
var/datum/component/radioactive/other = C
strength = max(strength, other.strength)
if(C)
var/datum/component/radioactive/other = C
strength = max(strength, other.strength)
else
strength = max(strength, arguments[1])
/datum/component/radioactive/proc/rad_examine(mob/user, atom/thing)
var/atom/master = parent
+6 -3
View File
@@ -1,5 +1,5 @@
/datum/component/thermite
dupe_mode = COMPONENT_DUPE_UNIQUE
dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
var/amount
var/overlay
@@ -46,10 +46,13 @@
master.cut_overlay(overlay)
return ..()
/datum/component/thermite/InheritComponent(datum/component/thermite/newC, i_am_original)
/datum/component/thermite/InheritComponent(datum/component/thermite/newC, i_am_original, list/arguments)
if(!i_am_original)
return
amount += newC.amount
if(newC)
amount += newC.amount
else
amount += arguments[1]
/datum/component/thermite/proc/thermite_melt(mob/user)
var/turf/master = parent