Issue #4 - Porting resize (micro/macro) systems.

* Instead of "playerscale" we are using pre-existing variable
 "size_multiplier" but we move it to /mob/living
* Added basic mechanics of size changing.
* Mousetraps snap small people even if they have shoes.
* Big people can walk over small people, or stomp them, or capture them
 in foot slot.
* Ported holder for micros, making small people scoopable.
* Tied held micros in with the vore code so they are edible.
* Ported size-altering reagents and recipies.
* Ported size gun along with associated sprites and sounds.
This commit is contained in:
Leshana
2016-05-08 23:11:03 -04:00
parent 6334fe9174
commit abbf0c7fc0
17 changed files with 680 additions and 8 deletions
+12 -4
View File
@@ -65,7 +65,7 @@
//Things we can eat with vore code
var/list/vore_items = list(
/obj/item/weapon/grab,
/obj/item/weapon/holder)
/obj/item/weapon/holder/micro)
if(!(I.type in vore_items))
return 0
@@ -106,11 +106,19 @@
else
log_debug("[attacker] attempted to feed [G.affecting] to [src] ([src.type]) but it failed.")
//Handle case: /obj/item/weapon/holder
if(/obj/item/weapon/holder)
return 1
if(/obj/item/weapon/holder/micro)
var/obj/item/weapon/holder/H = I
if(!isliving(user)) return 0 // Return 0 to continue upper procs
var/mob/living/attacker = user // Typecast to living
if (is_vore_predator(src))
for (var/mob/living/M in H.contents)
attacker.eat_held_mob(attacker, M, src)
return 1 //Return 1 to exit upper procs
else
log_debug("[attacker] attempted to feed [H.contents] to [src] ([src.type]) but it is not predator-capable")
return 0
@@ -0,0 +1,63 @@
//
// Gravity Pull effect which draws in movable objects to its center.
// In this case, "number" refers to the range. directions is ignored.
//
/datum/effect/effect/system/grav_pull
var/pull_radius = 3
var/pull_anchored = 0
var/break_windows = 0
/datum/effect/effect/system/grav_pull/set_up(range, num, loca)
pull_radius = range
number = num
if(istype(loca, /turf/))
location = loca
else
location = get_turf(loca)
/datum/effect/effect/system/grav_pull/start()
spawn(0)
if(holder)
src.location = get_turf(holder)
for(var/i=0, i < number, i++)
do_pull()
sleep(25)
/datum/effect/effect/system/grav_pull/proc/do_pull()
//following is adapted from supermatter and singulo code
if(defer_powernet_rebuild != 2)
defer_powernet_rebuild = 1
// Let's just make this one loop.
for(var/atom/X in orange(pull_radius, location))
// Movable atoms only
if(istype(X, /atom/movable))
if(istype(X, /obj/effect/overlay)) continue
if(X && !istype(X, /mob/living/carbon/human))
if(break_windows && istype(X, /obj/structure/window)) //shatter windows
var/obj/structure/window/W = X
W.ex_act(2.0)
if(istype(X, /obj))
var/obj/O = X
if(O.anchored)
if (!pull_anchored) continue // Don't pull anchored stuff unless configured
step_towards(X, location) // step just once if anchored
continue
step_towards(X, location) // Step twice
step_towards(X, location)
else if(istype(X,/mob/living/carbon/human))
var/mob/living/carbon/human/H = X
if(istype(H.shoes,/obj/item/clothing/shoes/magboots))
var/obj/item/clothing/shoes/magboots/M = H.shoes
if(M.magpulse)
step_towards(H, location) //step just once with magboots
continue
step_towards(H, location) //step twice
step_towards(H, location)
if(defer_powernet_rebuild != 2)
defer_powernet_rebuild = 0
return
@@ -0,0 +1,33 @@
// Micro Holders - Extends /obj/item/weapon/holder
/obj/item/weapon/holder/micro
name = "micro"
desc = "Another crewmember, small enough to fit in your hand."
icon_state = "micro"
slot_flags = SLOT_FEET | SLOT_HEAD | SLOT_ID
w_class = 2
item_icons = null // Override value from parent. We don't have magic sprites.
pixel_y = 0 // Override value from parent.
/obj/item/weapon/holder/micro/examine(var/mob/user)
for(var/mob/living/M in contents)
M.examine(user)
/obj/item/weapon/holder/MouseDrop(mob/M as mob)
..()
if(M != usr) return
if(usr == src) return
if(!Adjacent(usr)) return
if(istype(M,/mob/living/silicon/ai)) return
for(var/mob/living/carbon/human/O in contents)
O.show_inv(usr)
/obj/item/weapon/holder/micro/attack_self(var/mob/living/user)
for(var/mob/living/carbon/human/M in contents)
M.help_shake_act(user)
/obj/item/weapon/holder/micro/update_state()
// If any items have been dropped by contained mob, drop them to floor.
for(var/obj/O in contents)
O.forceMove(get_turf(src))
..()
+191
View File
@@ -0,0 +1,191 @@
//these aren't defines so they can stay in this file
var/const/RESIZE_HUGE = 2
var/const/RESIZE_BIG = 1.5
var/const/RESIZE_NORMAL = 1
var/const/RESIZE_SMALL = 0.5
var/const/RESIZE_TINY = 0.25
//average
var/const/RESIZE_A_HUGEBIG = (RESIZE_HUGE + RESIZE_BIG) / 2
var/const/RESIZE_A_BIGNORMAL = (RESIZE_BIG + RESIZE_NORMAL) / 2
var/const/RESIZE_A_NORMALSMALL = (RESIZE_NORMAL + RESIZE_SMALL) / 2
var/const/RESIZE_A_SMALLTINY = (RESIZE_SMALL + RESIZE_TINY) / 2
// Adding needed defines to /mob/living
// Note: Polaris had this on /mob/living/carbon/human We need it higher up for animals and stuff.
/mob/living
var/size_multiplier = 1 //multiplier for the mob's icon size
// Define holder_type on types we want to be scoop-able
/mob/living/carbon/human
holder_type = /obj/item/weapon/holder/micro
/**
* Scale up the size of a mob's icon by the size_multiplier.
* NOTE: mob/living/carbon/human/update_icons() has a more complicated system and
* is already applying this transform. BUT, it does not call ..()
* as long as that is true, we should be fine. If that changes we need to
* re-evaluate.
*/
/mob/living/update_icons()
ASSERT(!ishuman(src))
var/matrix/M = matrix()
M.Scale(size_multiplier)
M.Translate(0, 16*(size_multiplier-1))
src.transform = M
/**
* Get the effective size of a mob.
* Currently this is based only on size_multiplier for micro/macro stuff,
* but in the future we may also incorporate the "mob_size", so that
* a macro mouse is still only effectively "normal" or a micro dragon is still large etc.
*/
/mob/living/proc/get_effective_size()
return src.size_multiplier
/**
* Resizes the mob immediately to the desired mod, animating it growing/shrinking.
* It can be used by anything that calls it.
*/
/mob/living/proc/resize(var/new_size)
var/matrix/resize = matrix() // Defines the matrix to change the player's size
resize.Scale(new_size) //Change the size of the matrix
if(new_size >= RESIZE_NORMAL)
resize.Translate(0, -1 * (1 - new_size) * 16) //Move the player up in the tile so their feet align with the bottom
animate(src, transform = resize, time = 5) //Animate the player resizing
size_multiplier = new_size //Change size_multiplier so that other items can interact with them
/**
* Verb proc for a command that lets players change their size OOCly.
* Ace was here! Redid this a little so we'd use math for shrinking characters. This is the old code.
*/
/mob/living/proc/set_size()
set name = "Set Character Size"
set category = "Vore"
var/nagmessage = "DO NOT ABUSE THESE COMMANDS. They are not here for you to play with. \
We were originally going to remove them but kept them for popular demand. \
Do not abuse their existence outside of ERP scenes where they apply, \
or reverting OOCly unwanted changes like someone lolshooting the crew with a shrink ray. -Ace"
var/size_name = input(nagmessage, "Pick a Size") in player_sizes_list
if (size_name && player_sizes_list[size_name])
src.resize(player_sizes_list[size_name])
message_admins("[key_name(src)] used the resize command in-game to be [size_name]. \
([src ? "<a href='?_src_=holder;adminplayerobservecoodjump=1;X=[src.x];Y=[src.y];Z=[src.z]'>JMP</a>" : "null"])")
/** Add the set_size() proc to usable verbs. */
/hook/living_new/proc/resize_setup(mob/living/M)
M.verbs += /mob/living/proc/set_size
return 1
/**
* Attempt to scoop up this mob up into M's hands, if the size difference is large enough.
* @return false if normal code should continue, 1 to prevent normal code.
*/
/mob/living/proc/attempt_to_scoop(var/mob/living/carbon/human/M)
if(!istype(M))
return 0;
if(M.get_effective_size() - src.get_effective_size() >= 0.75)
var/obj/item/weapon/holder/m_holder = get_scooped(M)
if (m_holder)
return 1
else
return 0; // Unable to scoop, let other code run
/**
* Handle bumping into someone with helping intent.
* Called from /mob/living/Bump() in the 'brohugs all around' section.
* @return false if normal code should continue, 1 to prevent normal code.
* // TODO - can the now_pushing = 0 be moved up? What does it do anyway?
*/
/mob/living/proc/handle_micro_bump_helping(var/mob/living/tmob)
if(src.get_effective_size() <= RESIZE_A_SMALLTINY && tmob.get_effective_size() <= RESIZE_A_SMALLTINY)
// Both small! Go ahead and
now_pushing = 0
return 1
if(abs(src.get_effective_size() - tmob.get_effective_size()) >= 0.75)
now_pushing = 0
if(src.get_effective_size() > tmob.get_effective_size())
var/mob/living/carbon/human/M = src
if(0) // POLARISTODO istaur(src) && M.taur_style == 2)
src << "You carefully slither around [tmob]."
tmob << "[src]'s huge tail slithers past beside you!"
else
src << "You carefully step over [tmob]."
tmob << "[src] steps over you carefully!"
if(tmob.get_effective_size() > src.get_effective_size())
var/mob/living/carbon/human/M = tmob
if(0) // POLARISTODO istaur(src) && M.taur == 2)
src << "You jump over [tmob]'s thick tail."
tmob << "[src] bounds over your tail."
else
src << "You run between [tmob]'s legs."
tmob << "[src] runs between your legs."
return 1
/**
* Handle bumping into someone without mutual help intent.
* Called from /mob/living/Bump()
* NW was here, adding even more options for stomping!
*
* @return false if normal code should continue, 1 to prevent normal code.
*/
/mob/living/proc/handle_micro_bump_other(var/mob/living/tmob)
ASSERT(istype(tmob)) // Baby don't hurt me
if(src.a_intent == I_DISARM && src.canmove && !src.buckled)
// If bigger than them by at least 0.75, move onto them and print message.
if((src.get_effective_size() - tmob.get_effective_size()) >= 0.75)
now_pushing = 0
src.forceMove(tmob.loc)
tmob.Stun(4)
var/mob/living/carbon/human/M = src
if(0) // POLARISTODO istaur(src) && M.taur_style == 2)
src << "You carefully squish [tmob] under your tail!"
tmob << "[src] pins you under their tail!"
else
src << "You pin [tmob] beneath your foot!"
tmob << "[src] pins you beneath their foot!"
return 1
if(src.a_intent == I_HURT && src.canmove && !src.buckled)
if((src.get_effective_size() - tmob.get_effective_size()) >= 0.75)
now_pushing = 0
src.forceMove(tmob.loc)
tmob.apply_damage(10, HALLOSS)
var/mob/living/carbon/human/M = src
if(0) // POLARISTODO istaur(src) && M.taur_style == 2)
src << "You steamroller over [tmob] with your heavy tail!"
tmob << "[src] ploughs you down mercilessly with their heavy tail!"
else
src << "You bring your foot down heavily upon [tmob]!"
tmob << "[src] steps carelessly on your body!"
return 1
if(src.a_intent == I_GRAB && src.canmove && !src.buckled)
if((src.get_effective_size() - tmob.get_effective_size()) >= 0.75)
now_pushing = 0
src.forceMove(tmob.loc)
var/mob/living/carbon/human/M = src
if(istype(M) && !M.shoes)
// User is a human (capable of scooping) and not wearing shoes! Scoop into foot slot!
equip_to_slot_if_possible(tmob.get_scooped(M), slot_shoes, 0, 1)
if(0) // POLARISTODO M.taur == 2)
src << "You wrap up [tmob] with your powerful tail!"
tmob << "[src] binds you with their powerful tail!"
else
src << "You clench your toes around [tmob]'s body!"
tmob << "[src] grabs your body with their toes!"
else if(0) // POLARISTODO istaur(src) && M.taur_style == 2)
src << "You carefully squish [tmob] under your tail!"
tmob << "[src] pins you under their tail!"
else
src << "You pin [tmob] beneath your foot!"
tmob << "[src] pins you beneath their foot!"
return 1
+76
View File
@@ -0,0 +1,76 @@
//
// Size Gun
//
/obj/item/weapon/gun/energy/sizegun
name = "shrink ray"
desc = "A highly advanced ray gun with two settings: Shrink and Grow. Warning: Do not insert into mouth."
icon = 'icons/obj/gun_vr.dmi'
icon_state = "sizegun-shrink100" // Someone can probably do better. -Ace
item_state = null //so the human update icon uses the icon_state instead
fire_sound = 'sound/weapons/wave.ogg'
charge_cost = 100
projectile_type = /obj/item/projectile/beam/shrinklaser
origin_tech = "redspace=1;bluespace=4"
modifystate = "sizegun-shrink"
self_recharge = 1
firemodes = list(
list(mode_name = "grow",
projectile_type = /obj/item/projectile/beam/growlaser,
modifystate = "sizegun-grow",
fire_sound = 'sound/weapons/pulse3.ogg'
),
list(mode_name = "shrink",
projectile_type = /obj/item/projectile/beam/shrinklaser,
modifystate = "sizegun-shrink",
fire_sound = 'sound/weapons/wave.ogg'
))
//
// Beams for size gun
//
/obj/item/projectile/beam/shrinklaser
name = "shrink beam"
icon_state = "laser"
nodamage = 1
damage = 0
check_armour = "laser"
/obj/item/projectile/beam/shrinklaser/on_hit(var/atom/target, var/blocked = 0)
if(istype(target, /mob/living))
var/mob/living/M = target
switch(M.size_multiplier)
if(RESIZE_HUGE to INFINITY)
M.resize(RESIZE_BIG)
if(RESIZE_BIG to RESIZE_HUGE)
M.resize(RESIZE_NORMAL)
if(RESIZE_NORMAL to RESIZE_BIG)
M.resize(RESIZE_SMALL)
if((0 - INFINITY) to RESIZE_NORMAL)
M.resize(RESIZE_TINY)
M.update_icons()
return 1
/obj/item/projectile/beam/growlaser
name = "growth beam"
icon_state = "bluelaser"
nodamage = 1
damage = 0
check_armour = "laser"
/obj/item/projectile/beam/growlaser/on_hit(var/atom/target, var/blocked = 0)
if(istype(target, /mob/living))
var/mob/living/M = target
switch(M.size_multiplier)
if(RESIZE_BIG to RESIZE_HUGE)
M.resize(RESIZE_HUGE)
if(RESIZE_NORMAL to RESIZE_BIG)
M.resize(RESIZE_BIG)
if(RESIZE_SMALL to RESIZE_NORMAL)
M.resize(RESIZE_NORMAL)
if((0 - INFINITY) to RESIZE_TINY)
M.resize(RESIZE_SMALL)
M.update_icons()
return 1