mirror of
https://github.com/Sandstorm-Station/Sandstorm-Station-13.git
synced 2026-08-30 16:56:26 +01:00
Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -231,3 +231,31 @@
|
||||
to_chat(invoker, "<span class='nezbere'>\"Only one of my weapons may exist in this temporal stream!\"</span>")
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/datum/clockwork_scripture/create_object/construct/cogscarab
|
||||
descname = "Building Construct"
|
||||
name = "Cogscarab"
|
||||
desc = "Creates a shell for a cogscarab, a drone that helps build your base!"
|
||||
invocations = list("Arise, drone!", "Create defenses for the true light!")
|
||||
channel_time = 80
|
||||
power_cost = 8000
|
||||
creator_message = "<span class='brass'>Your slab disgorges several chunks of replicant alloy that form into a spiderlike shell.</span>"
|
||||
usage_tip = "These machines will help you get a base built up while you go out to look for more followers."
|
||||
tier = SCRIPTURE_APPLICATION
|
||||
one_per_tile = TRUE
|
||||
primary_component = BELLIGERENT_EYE
|
||||
sort_priority = 9
|
||||
quickbind = TRUE
|
||||
quickbind_desc = "Creates a cogscarab, good for the backline."
|
||||
object_path = /obj/item/clockwork/construct_chassis/cogscarab/
|
||||
construct_type = /mob/living/simple_animal/drone/cogscarab
|
||||
combat_construct = FALSE
|
||||
|
||||
/datum/clockwork_scripture/create_object/construct/cogscarab/update_construct_limit()
|
||||
var/human_servants = 0
|
||||
for(var/V in SSticker.mode.servants_of_ratvar)
|
||||
var/datum/mind/M = V
|
||||
var/mob/living/L = M.current
|
||||
if(ishuman(L) && L.stat != DEAD)
|
||||
human_servants++
|
||||
construct_limit = round(clamp((human_servants / 4), 1, 3)) //1 per 4 human servants, maximum of 3
|
||||
|
||||
@@ -188,6 +188,9 @@
|
||||
/mob/living/simple_animal/drone/cogscarab/update_drone_hack()
|
||||
return //we don't get hacked or give a shit about it
|
||||
|
||||
/mob/living/simple_animal/drone/cogscarab/death(gibbed)
|
||||
. = ..()
|
||||
|
||||
/mob/living/simple_animal/drone/cogscarab/drone_chat(msg)
|
||||
titled_hierophant_message(src, msg, "nezbere", "brass", "Construct") //HIEROPHANT DRONES
|
||||
|
||||
|
||||
@@ -187,23 +187,6 @@
|
||||
/obj/item/stock_parts/cell/get_part_rating()
|
||||
return rating * maxcharge
|
||||
|
||||
// stuff so ipcs and synthlizards can eat power cells, taken from how moths can eat clothing
|
||||
/obj/item/reagent_containers/food/snacks/cell
|
||||
name = "oops"
|
||||
desc = "If you're reading this it means I messed up. This is related to ipcs/synths eating cells and I didn't know a better way to do it than making a new food object."
|
||||
list_reagents = list(/datum/reagent/consumable/nutriment = 0.5)
|
||||
tastes = list("electricity" = 1, "metal" = 1)
|
||||
|
||||
/obj/item/stock_parts/cell/attack(mob/M, mob/user, def_zone)
|
||||
if(user.a_intent != INTENT_HARM && isrobotic(M))
|
||||
var/obj/item/reagent_containers/food/snacks/cell/cell_as_food = new
|
||||
cell_as_food.name = name
|
||||
if(cell_as_food.attack(M, user, def_zone))
|
||||
take_damage(40, sound_effect=FALSE)
|
||||
qdel(cell_as_food)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/* Cell variants*/
|
||||
/obj/item/stock_parts/cell/empty
|
||||
start_charged = FALSE
|
||||
|
||||
@@ -326,49 +326,79 @@
|
||||
desc = "An internal power cord hooked up to a battery. Useful if you run on electricity. Not so much otherwise."
|
||||
icon = 'icons/obj/power.dmi'
|
||||
icon_state = "wire1"
|
||||
var/in_use = FALSE //No stacking doafters
|
||||
|
||||
/obj/item/apc_powercord/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
|
||||
if(!istype(target, /obj/machinery/power/apc) || !ishuman(user) || !proximity_flag)
|
||||
if((!istype(target, /obj/machinery/power/apc) && !istype(target, /obj/item/stock_parts/cell)) || !ishuman(user) || !proximity_flag)
|
||||
return ..()
|
||||
user.DelayNextAction(CLICK_CD_MELEE)
|
||||
var/obj/machinery/power/apc/A = target
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(in_use)
|
||||
to_chat(H, "<span class='warning'>[src] is already connected to something!</span>")
|
||||
return
|
||||
var/obj/item/organ/stomach/ipc/cell = locate(/obj/item/organ/stomach/ipc) in H.internal_organs
|
||||
if(!cell)
|
||||
to_chat(H, "<span class='warning'>You try to siphon energy from the [A], but your power cell is gone!</span>")
|
||||
to_chat(H, "<span class='warning'>You try to siphon energy from [target], but your power cell is gone!</span>")
|
||||
return
|
||||
|
||||
if(A.cell && A.cell.charge > 0)
|
||||
if(H.nutrition >= NUTRITION_LEVEL_WELL_FED)
|
||||
to_chat(user, "<span class='warning'>You are already fully charged!</span>")
|
||||
if(H.nutrition >= NUTRITION_LEVEL_WELL_FED)
|
||||
to_chat(user, "<span class='warning'>You are already fully charged!</span>")
|
||||
return
|
||||
if(istype(target, /obj/machinery/power/apc))
|
||||
var/obj/machinery/power/apc/A = target
|
||||
if(A.cell && A.cell.charge > 0)
|
||||
in_use = TRUE
|
||||
apc_powerdraw_loop(A, H)
|
||||
return
|
||||
else
|
||||
powerdraw_loop(A, H)
|
||||
else //We only let through cells and APCs, so this has to be a cell
|
||||
var/obj/item/stock_parts/cell/C = target
|
||||
if(C.charge > 0)
|
||||
in_use = TRUE
|
||||
cell_powerdraw_loop(C, H)
|
||||
return
|
||||
|
||||
to_chat(user, "<span class='warning'>There is no charge to draw from that APC.</span>")
|
||||
to_chat(user, "<span class='warning'>There is no charge to draw from [target].</span>")
|
||||
|
||||
/obj/item/apc_powercord/proc/powerdraw_loop(obj/machinery/power/apc/A, mob/living/carbon/human/H)
|
||||
H.visible_message("<span class='notice'>[H] inserts a power connector into the [A].</span>", "<span class='notice'>You begin to draw power from the [A].</span>")
|
||||
/obj/item/apc_powercord/proc/apc_powerdraw_loop(obj/machinery/power/apc/A, mob/living/carbon/human/H)
|
||||
H.visible_message("<span class='notice'>[H] inserts a power connector into [A].</span>", "<span class='notice'>You begin to draw power from [A].</span>")
|
||||
while(do_after(H, 10, target = A))
|
||||
if(loc != H)
|
||||
to_chat(H, "<span class='warning'>You must keep your connector out while charging!</span>")
|
||||
break
|
||||
if(A.cell.charge == 0)
|
||||
to_chat(H, "<span class='warning'>The [A] doesn't have enough charge to spare.</span>")
|
||||
to_chat(H, "<span class='warning'>[A] doesn't have enough charge to spare.</span>")
|
||||
break
|
||||
A.charging = 1
|
||||
if(A.cell.charge >= 500)
|
||||
do_sparks(1, FALSE, A)
|
||||
H.nutrition += 50
|
||||
A.cell.charge -= 150
|
||||
H.adjust_nutrition(50)
|
||||
A.cell.use(150)
|
||||
to_chat(H, "<span class='notice'>You siphon off some of the stored charge for your own use.</span>")
|
||||
else
|
||||
H.nutrition += A.cell.charge/10
|
||||
A.cell.charge = 0
|
||||
to_chat(H, "<span class='notice'>You siphon off as much as the [A] can spare.</span>")
|
||||
H.adjust_nutrition(A.cell.charge/10)
|
||||
A.cell.use(A.cell.charge)
|
||||
to_chat(H, "<span class='notice'>You siphon off as much as [A] can spare.</span>")
|
||||
break
|
||||
if(H.nutrition > NUTRITION_LEVEL_WELL_FED)
|
||||
to_chat(H, "<span class='notice'>You are now fully charged.</span>")
|
||||
break
|
||||
H.visible_message("<span class='notice'>[H] unplugs from the [A].</span>", "<span class='notice'>You unplug from the [A].</span>")
|
||||
in_use = FALSE
|
||||
H.visible_message("<span class='notice'>[H] unplugs from [A].</span>", "<span class='notice'>You unplug from [A].</span>")
|
||||
|
||||
/obj/item/apc_powercord/proc/cell_powerdraw_loop(obj/item/stock_parts/cell/C, mob/living/carbon/human/H)
|
||||
H.visible_message("<span class='notice'>[H] connects a power cord to [C]</span>", "<span class='notice'>You begin to draw power from [C].</span>")
|
||||
while(do_after(H, 10, target = C))
|
||||
if(loc != H)
|
||||
to_chat(H, "<span class='warning'>You must keep your connector out while charging!</span>")
|
||||
break
|
||||
if(C.charge == 0)
|
||||
to_chat(H, "<span class='warning'>[C] doesn't have any charge remaining.</span>")
|
||||
break
|
||||
var/siphoned_charge = min(C.charge, 2000)
|
||||
C.use(siphoned_charge)
|
||||
do_sparks(1, FALSE, C)
|
||||
H.adjust_nutrition(siphoned_charge / 100) //Less efficient on a pure power basis than APC recharge. Still a very viable way of gaining nutrition. (100 nutrition / base 10k cell)
|
||||
if(H.nutrition > NUTRITION_LEVEL_WELL_FED)
|
||||
to_chat(H, "<span class='notice'>You are now fully charged.</span>")
|
||||
break
|
||||
in_use = FALSE
|
||||
H.visible_message("<span class='notice'>[H] disconnects [src] from [C].</span>", "<span class='notice'>You disconnect from [C].</span>")
|
||||
|
||||
@@ -51,10 +51,27 @@
|
||||
<div class="commit sansserif">
|
||||
|
||||
<h2 class="date">21 November 2021</h2>
|
||||
<h3 class="author">DeltaFire15 updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">Power cord implants can now also be connected to cells to recharge.</li>
|
||||
<li class="rscdel">Synthetics can no longer bite power cells.</li>
|
||||
</ul>
|
||||
<h3 class="author">LetterN updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">Search option on the cwc slab</li>
|
||||
</ul>
|
||||
<h3 class="author">MrJWhit updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="balance">Reduces the HP from loot piles to 100, from 300.</li>
|
||||
</ul>
|
||||
<h3 class="author">TripleShades updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">(Pubby) Loot piles to maint halls remove: (Pubby) CMO's sex dungeon tweak: (Pubby) Surgery layout is now more open</li>
|
||||
</ul>
|
||||
<h3 class="author">keronshb updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">Adds Cogscarab spell tweak: Cogscarabs gib now because I have no idea how to fix the issue of dead pogscarabs eating up the limit.</li>
|
||||
</ul>
|
||||
|
||||
<h2 class="date">20 November 2021</h2>
|
||||
<h3 class="author">Dexxiol updated:</h3>
|
||||
|
||||
@@ -31004,5 +31004,16 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
|
||||
- code_imp: Updates component Destroy code, might result in less component related
|
||||
runtimes.
|
||||
2021-11-21:
|
||||
DeltaFire15:
|
||||
- rscadd: Power cord implants can now also be connected to cells to recharge.
|
||||
- rscdel: Synthetics can no longer bite power cells.
|
||||
LetterN:
|
||||
- rscadd: Search option on the cwc slab
|
||||
MrJWhit:
|
||||
- balance: Reduces the HP from loot piles to 100, from 300.
|
||||
TripleShades:
|
||||
- rscadd: '(Pubby) Loot piles to maint halls remove: (Pubby) CMO''s sex dungeon
|
||||
tweak: (Pubby) Surgery layout is now more open'
|
||||
keronshb:
|
||||
- rscadd: 'Adds Cogscarab spell tweak: Cogscarabs gib now because I have no idea
|
||||
how to fix the issue of dead pogscarabs eating up the limit.'
|
||||
|
||||
@@ -6,12 +6,14 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { useBackend, useSharedState } from '../backend';
|
||||
import { useBackend, useLocalState, useSharedState } from '../backend';
|
||||
import { createSearch } from 'common/string';
|
||||
import { map } from 'common/collections';
|
||||
import { Section, Tabs, Table, Button, Box, NoticeBox, Divider } from '../components';
|
||||
import { Section, Tabs, Table, Button, Box, NoticeBox, Divider, Input } from '../components';
|
||||
import { Fragment } from 'inferno';
|
||||
import { Window } from '../layouts';
|
||||
|
||||
const MAX_SEARCH_RESULTS = 25;
|
||||
let REC_RATVAR = "";
|
||||
// You may ask "why is this not inside ClockworkSlab"
|
||||
// It's because cslab gets called every time. Lag is bad.
|
||||
@@ -31,13 +33,35 @@ export const ClockworkSlab = (props, context) => {
|
||||
tab,
|
||||
setTab,
|
||||
] = useSharedState(context, 'tab', 'Application');
|
||||
const scriptInTab = scripture
|
||||
&& scripture[tab]
|
||||
|| [];
|
||||
|
||||
const tierInfo = tier_infos
|
||||
&& tier_infos[tab]
|
||||
|| {};
|
||||
|
||||
const [
|
||||
searchText,
|
||||
setSearchText,
|
||||
] = useLocalState(context, 'searchText', '');
|
||||
|
||||
const testSearch = createSearch(searchText, script => {
|
||||
return script.name + script.descname;
|
||||
});
|
||||
|
||||
let bucketOfScriptures = [];
|
||||
// merge it, no need to throw a var.
|
||||
|
||||
const scriptInTab = (searchText.length > 0)
|
||||
// Flatten all categories and apply search to it
|
||||
// truthy because WE DO NOT WANT TO RETURN THIS!
|
||||
&& !!map((v, k) => {
|
||||
bucketOfScriptures = bucketOfScriptures.concat(v);
|
||||
})(scripture)
|
||||
&& bucketOfScriptures.filter(testSearch)
|
||||
.filter((item, i) => i < MAX_SEARCH_RESULTS)
|
||||
// Return the default one
|
||||
|| scripture[tab]
|
||||
|| null; // this is nullable, it's recommended that you null it.
|
||||
|
||||
return (
|
||||
<Window
|
||||
theme="clockcult"
|
||||
@@ -50,13 +74,21 @@ export const ClockworkSlab = (props, context) => {
|
||||
<Section
|
||||
title="Power"
|
||||
buttons={(
|
||||
<Button
|
||||
icon="book"
|
||||
tooltip={"Tutorial"}
|
||||
tooltipPosition={"left"}
|
||||
onClick={() => act('toggle')}>
|
||||
Recollection
|
||||
</Button>
|
||||
<Fragment>
|
||||
Search
|
||||
<Input
|
||||
autoFocus
|
||||
value={searchText}
|
||||
onInput={(e, value) => setSearchText(value)}
|
||||
mx={1} />
|
||||
<Button
|
||||
icon="book"
|
||||
tooltip={"Tutorial"}
|
||||
tooltipPosition={"left"}
|
||||
onClick={() => act('toggle')}>
|
||||
Recollection
|
||||
</Button>
|
||||
</Fragment>
|
||||
)}>
|
||||
<b>{power}</b> power is available for scripture
|
||||
and other consumers.
|
||||
@@ -67,13 +99,13 @@ export const ClockworkSlab = (props, context) => {
|
||||
key={name}
|
||||
selected={tab === name}
|
||||
onClick={() => setTab(name)}>
|
||||
{name}
|
||||
{name} ({scriptures?.length || 0})
|
||||
</Tabs.Tab>
|
||||
))(scripture)}
|
||||
</Tabs>
|
||||
<Box
|
||||
as={'span'}
|
||||
textColor={'#B18B25'}
|
||||
textColor={'#dab44d'}
|
||||
bold={!!tierInfo.ready} // muh booleans
|
||||
italic={!tierInfo.ready}>
|
||||
{tierInfo.ready ? (
|
||||
@@ -125,16 +157,16 @@ export const CSScripture = (props, context) => {
|
||||
power_unformatted = 0,
|
||||
} = data;
|
||||
const {
|
||||
scriptInTab,
|
||||
scriptInTab = [],
|
||||
} = props;
|
||||
|
||||
return (
|
||||
scriptInTab?.map(script => (
|
||||
scriptInTab?.length > 0 ? scriptInTab.map(script => (
|
||||
<Table.Row
|
||||
key={script.name}
|
||||
className="candystripe">
|
||||
<Table.Cell
|
||||
italic={!!script.important}
|
||||
italic={!!script?.important}
|
||||
color={script.fontcolor}>
|
||||
<b>
|
||||
{script.name}
|
||||
@@ -176,7 +208,14 @@ export const CSScripture = (props, context) => {
|
||||
</Button>
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
))
|
||||
)) : (
|
||||
<Box
|
||||
as="span"
|
||||
textColor={'#BE8700'}
|
||||
fontSize={2.3}>
|
||||
Nothing here!
|
||||
</Box>
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
@@ -209,7 +248,7 @@ export const CSTutorial = (props, context) => {
|
||||
{REC_RATVAR}
|
||||
</Box>
|
||||
) : (
|
||||
<Fragment>
|
||||
<>
|
||||
<Box
|
||||
as="span"
|
||||
textColor="#BE8700"
|
||||
@@ -237,7 +276,7 @@ export const CSTutorial = (props, context) => {
|
||||
not let it confuse you! You are free to use the names
|
||||
in pronoun form when speaking in normal languages.
|
||||
</NoticeBox>
|
||||
</Fragment>
|
||||
</>
|
||||
)}
|
||||
</Box>
|
||||
{recollection_categories?.map(cat => (
|
||||
|
||||
Reference in New Issue
Block a user