Merge branch 'master' of https://github.com/Fordoxia/CRUNCHParadise
24
.github/workflows/build_milla.yml
vendored
@@ -15,10 +15,18 @@ jobs:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- id: create_token
|
||||
uses: actions/create-github-app-token@v1
|
||||
with:
|
||||
app-id: ${{ secrets.APP_ID }}
|
||||
private-key: ${{ secrets.PRIVATE_KEY }}
|
||||
|
||||
- run: echo "GH_TOKEN=${{ steps.create_token.outputs.token }}" >> "$GITHUB_ENV"
|
||||
- run: echo "FAIL_NOTIFIED=false" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Like the comment
|
||||
env:
|
||||
BASE_REPOSITORY: ${{ github.repository }}
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
gh api \
|
||||
--method POST \
|
||||
@@ -43,13 +51,13 @@ jobs:
|
||||
with:
|
||||
repository: ${{ env.PR_REPO }}
|
||||
ref: ${{ env.PR_BRANCH }}
|
||||
token: ${{ github.token }}
|
||||
token: ${{ env.GH_TOKEN }}
|
||||
|
||||
- name: Build MILLA
|
||||
env:
|
||||
BASE_BRANCH: ${{ github.event.repository.default_branch }}
|
||||
BASE_REPOSITORY: ${{ github.repository }}
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
GH_TOKEN: ${{ env.GH_TOKEN }}
|
||||
run: |
|
||||
# Get the code.
|
||||
git config user.name paradisess13[bot]
|
||||
@@ -74,20 +82,10 @@ jobs:
|
||||
cp target/i686-unknown-linux-gnu/release/libmilla.so ../tools/ci/libmilla_ci.so
|
||||
cp target/i686-pc-windows-gnu/release/milla.dll ../milla.dll
|
||||
|
||||
# Check if a workflow file would be modified by the merge (permissions prevent pushes if so)
|
||||
latest_workflow_commit=$(git log -n 1 --pretty=format:"%H" upstream/$BASE_BRANCH -- .github/workflows)
|
||||
if ! git branch --contains $latest_workflow_commit | grep -q "$(git rev-parse --abbrev-ref HEAD)"; then
|
||||
gh pr comment ${{ github.event.issue.html_url }} --body "GitHub Actions can not push to this branch as workflow files have been changed since your branch was last updated. Please update your branch past https://github.com/$BASE_REPOSITORY/commit/$latest_workflow_commit before using this command again."
|
||||
echo "FAIL_NOTIFIED=true" >> "$GITHUB_ENV"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
git commit -a -m "Build MILLA" --allow-empty
|
||||
git push origin
|
||||
|
||||
- name: Notify Failure
|
||||
if: failure() && env.FAIL_NOTIFIED != 'true'
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
gh pr comment ${{ github.event.issue.html_url }} -b 'Building MILLA failed, see the action run log for details: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}'
|
||||
|
||||
2
.github/workflows/ci.yml
vendored
@@ -49,6 +49,8 @@ jobs:
|
||||
python tools/ci/illegal_dme_files.py ${GITHUB_WORKSPACE}
|
||||
python tools/ci/define_sanity.py
|
||||
python tools/ci/restrict_file_types.py
|
||||
python tools/ci/verify_sql_version.py
|
||||
python tools/ci/no_duplicate_definitions.py
|
||||
python -m tools.ci.check_icon_conflicts
|
||||
python -m tools.ci.check_icon_dupenames
|
||||
python -m tools.maplint.source --github
|
||||
|
||||
4
.github/workflows/merge_upstream_master.yml
vendored
@@ -25,12 +25,14 @@ jobs:
|
||||
- run: echo "FAIL_NOTIFIED=false" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Like the comment
|
||||
env:
|
||||
BASE_REPOSITORY: ${{ github.repository }}
|
||||
run: |
|
||||
gh api \
|
||||
--method POST \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
-H "X-GitHub-Api-Version: 2022-11-28" \
|
||||
/repos/ParadiseSS13/Paradise/issues/comments/${{ github.event.comment.id }}/reactions \
|
||||
/repos/$BASE_REPOSITORY/issues/comments/${{ github.event.comment.id }}/reactions \
|
||||
-f content='+1'
|
||||
|
||||
- name: PR Data
|
||||
|
||||
@@ -528,7 +528,7 @@
|
||||
id = "syndbaseigniter";
|
||||
pixel_y = 20
|
||||
},
|
||||
/turf/simulated/floor/engine/air,
|
||||
/turf/simulated/floor/engine/vacuum,
|
||||
/area/ruin/unpowered/syndicate_space_base/atmos)
|
||||
"de" = (
|
||||
/obj/machinery/light{
|
||||
@@ -1064,7 +1064,7 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction{
|
||||
dir = 4
|
||||
},
|
||||
/turf/simulated/floor/engine/air,
|
||||
/turf/simulated/floor/engine/vacuum,
|
||||
/area/ruin/unpowered/syndicate_space_base/atmos)
|
||||
"fP" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,
|
||||
@@ -1860,7 +1860,7 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/heat_exchanging{
|
||||
dir = 10
|
||||
},
|
||||
/turf/simulated/floor/engine/air,
|
||||
/turf/simulated/floor/engine/vacuum,
|
||||
/area/ruin/unpowered/syndicate_space_base/atmos)
|
||||
"kh" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{
|
||||
@@ -2541,7 +2541,7 @@
|
||||
/obj/machinery/atmospherics/air_sensor{
|
||||
autolink_id = "syndiebase_mix_sensor"
|
||||
},
|
||||
/turf/simulated/floor/engine/air,
|
||||
/turf/simulated/floor/engine/vacuum,
|
||||
/area/ruin/unpowered/syndicate_space_base/atmos)
|
||||
"nI" = (
|
||||
/obj/machinery/atmospherics/binary/pump{
|
||||
@@ -3350,7 +3350,7 @@
|
||||
autolink_id = "syndiebase_mix_out";
|
||||
dir = 8
|
||||
},
|
||||
/turf/simulated/floor/engine/air,
|
||||
/turf/simulated/floor/engine/vacuum,
|
||||
/area/ruin/unpowered/syndicate_space_base/atmos)
|
||||
"sF" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{
|
||||
@@ -7440,7 +7440,7 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/heat_exchanging{
|
||||
dir = 5
|
||||
},
|
||||
/turf/simulated/floor/engine/air,
|
||||
/turf/simulated/floor/engine/vacuum,
|
||||
/area/ruin/unpowered/syndicate_space_base/atmos)
|
||||
"QB" = (
|
||||
/obj/machinery/optable,
|
||||
@@ -7740,7 +7740,7 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/heat_exchanging{
|
||||
dir = 9
|
||||
},
|
||||
/turf/simulated/floor/engine/air,
|
||||
/turf/simulated/floor/engine/vacuum,
|
||||
/area/ruin/unpowered/syndicate_space_base/atmos)
|
||||
"Su" = (
|
||||
/obj/structure/table,
|
||||
@@ -7988,7 +7988,7 @@
|
||||
autolink_id = "syndiebase_mix_in";
|
||||
dir = 8
|
||||
},
|
||||
/turf/simulated/floor/engine/air,
|
||||
/turf/simulated/floor/engine/vacuum,
|
||||
/area/ruin/unpowered/syndicate_space_base/atmos)
|
||||
"Tp" = (
|
||||
/obj/machinery/light{
|
||||
|
||||
@@ -3314,6 +3314,12 @@
|
||||
icon_state = "darkfull"
|
||||
},
|
||||
/area/mine/outpost/airlock)
|
||||
"iU" = (
|
||||
/obj/structure/shuttle/engine/propulsion/burst{
|
||||
dir = 8
|
||||
},
|
||||
/turf/simulated/wall/mineral/titanium/interior,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"iW" = (
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 4;
|
||||
@@ -5760,6 +5766,14 @@
|
||||
icon_state = "darkred"
|
||||
},
|
||||
/area/mine/laborcamp/security)
|
||||
"wb" = (
|
||||
/obj/structure/girder,
|
||||
/turf/simulated/floor/plating{
|
||||
nitrogen = 14;
|
||||
oxygen = 8;
|
||||
temperature = 500
|
||||
},
|
||||
/area/lavaland/surface/outdoors)
|
||||
"wd" = (
|
||||
/obj/structure/stone_tile/cracked{
|
||||
dir = 4
|
||||
@@ -6320,6 +6334,12 @@
|
||||
},
|
||||
/turf/simulated/floor/catwalk,
|
||||
/area/mine/outpost/hallway/west)
|
||||
"zm" = (
|
||||
/obj/structure/closet/walllocker/emerglocker/north,
|
||||
/obj/item/storage/toolbox/mechanical,
|
||||
/obj/item/flashlight/flare,
|
||||
/turf/simulated/floor/mineral/titanium/blue,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"zn" = (
|
||||
/obj/structure/lattice/catwalk/mining,
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
@@ -7819,6 +7839,10 @@
|
||||
"IC" = (
|
||||
/turf/simulated/wall,
|
||||
/area/mine/outpost/hallway/east)
|
||||
"ID" = (
|
||||
/obj/structure/door_assembly/door_assembly_silver,
|
||||
/turf/simulated/floor/mineral/titanium/blue,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"IE" = (
|
||||
/obj/machinery/atmospherics/unary/vent_pump/on,
|
||||
/obj/structure/sign/poster/official/help_others{
|
||||
@@ -7984,6 +8008,18 @@
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"JD" = (
|
||||
/obj/structure/grille/broken,
|
||||
/obj/structure/grille/broken,
|
||||
/obj/effect/mob_spawn/human/corpse/skeleton,
|
||||
/obj/effect/decal/cleanable/glass,
|
||||
/obj/item/shard,
|
||||
/turf/simulated/floor/plating{
|
||||
nitrogen = 14;
|
||||
oxygen = 8;
|
||||
temperature = 500
|
||||
},
|
||||
/area/lavaland/surface/outdoors)
|
||||
"JF" = (
|
||||
/obj/effect/spawner/window/reinforced/grilled,
|
||||
/obj/machinery/door/poddoor/preopen{
|
||||
@@ -8443,6 +8479,14 @@
|
||||
icon_state = "darkyellowcorners"
|
||||
},
|
||||
/area/mine/outpost/hallway/west)
|
||||
"MQ" = (
|
||||
/obj/item/stack/ore/iron,
|
||||
/turf/simulated/floor/plating{
|
||||
nitrogen = 14;
|
||||
oxygen = 8;
|
||||
temperature = 500
|
||||
},
|
||||
/area/lavaland/surface/outdoors)
|
||||
"MS" = (
|
||||
/obj/structure/stone_tile{
|
||||
dir = 1
|
||||
@@ -8952,6 +8996,14 @@
|
||||
icon_state = "darkfull"
|
||||
},
|
||||
/area/mine/laborcamp/security)
|
||||
"PZ" = (
|
||||
/obj/structure/grille/broken,
|
||||
/turf/simulated/floor/plating{
|
||||
nitrogen = 14;
|
||||
oxygen = 8;
|
||||
temperature = 500
|
||||
},
|
||||
/area/lavaland/surface/outdoors)
|
||||
"Qa" = (
|
||||
/obj/structure/closet,
|
||||
/obj/effect/spawner/lootdrop/maintenance,
|
||||
@@ -9759,6 +9811,13 @@
|
||||
icon_state = "tranquillite"
|
||||
},
|
||||
/area/mine/outpost/cafeteria)
|
||||
"VE" = (
|
||||
/obj/item/mounted/frame/intercom,
|
||||
/obj/item/stack/cable_coil{
|
||||
amount = 1
|
||||
},
|
||||
/turf/simulated/floor/mineral/titanium/blue,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"VF" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/visible/cyan{
|
||||
dir = 6
|
||||
@@ -9926,6 +9985,9 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden,
|
||||
/turf/simulated/floor/catwalk,
|
||||
/area/mine/laborcamp/security)
|
||||
"Wy" = (
|
||||
/turf/simulated/wall/mineral/titanium,
|
||||
/area/lavaland/surface/outdoors)
|
||||
"WD" = (
|
||||
/obj/structure/lattice/catwalk/mining,
|
||||
/obj/structure/railing{
|
||||
@@ -12443,9 +12505,9 @@ an
|
||||
an
|
||||
an
|
||||
an
|
||||
an
|
||||
an
|
||||
an
|
||||
KQ
|
||||
Aw
|
||||
Aw
|
||||
an
|
||||
an
|
||||
an
|
||||
@@ -12461,8 +12523,8 @@ an
|
||||
an
|
||||
an
|
||||
an
|
||||
an
|
||||
an
|
||||
Aw
|
||||
Aw
|
||||
an
|
||||
an
|
||||
an
|
||||
@@ -12478,8 +12540,8 @@ an
|
||||
an
|
||||
an
|
||||
an
|
||||
an
|
||||
an
|
||||
Aw
|
||||
Aw
|
||||
an
|
||||
an
|
||||
an
|
||||
@@ -12700,9 +12762,9 @@ an
|
||||
an
|
||||
an
|
||||
an
|
||||
an
|
||||
an
|
||||
an
|
||||
ab
|
||||
ab
|
||||
ab
|
||||
an
|
||||
an
|
||||
an
|
||||
@@ -12957,9 +13019,9 @@ an
|
||||
an
|
||||
an
|
||||
an
|
||||
an
|
||||
an
|
||||
an
|
||||
iU
|
||||
ID
|
||||
iU
|
||||
an
|
||||
an
|
||||
an
|
||||
@@ -13214,9 +13276,9 @@ an
|
||||
an
|
||||
an
|
||||
an
|
||||
an
|
||||
an
|
||||
an
|
||||
Wy
|
||||
zm
|
||||
PZ
|
||||
an
|
||||
an
|
||||
an
|
||||
@@ -13471,9 +13533,9 @@ an
|
||||
an
|
||||
an
|
||||
an
|
||||
an
|
||||
an
|
||||
an
|
||||
MQ
|
||||
VE
|
||||
Wy
|
||||
an
|
||||
an
|
||||
an
|
||||
@@ -13728,8 +13790,8 @@ an
|
||||
an
|
||||
an
|
||||
an
|
||||
an
|
||||
an
|
||||
wb
|
||||
JD
|
||||
an
|
||||
an
|
||||
an
|
||||
|
||||
@@ -725,6 +725,7 @@
|
||||
dir = 6;
|
||||
color = "#63009c"
|
||||
},
|
||||
/obj/effect/landmark/spawner/roundstart_observer,
|
||||
/turf/simulated/floor/wood,
|
||||
/area/wizard_station)
|
||||
"cO" = (
|
||||
@@ -1369,6 +1370,7 @@
|
||||
dir = 4;
|
||||
color = "#63009c"
|
||||
},
|
||||
/obj/effect/landmark/spawner/roundstart_observer,
|
||||
/turf/simulated/floor/wood,
|
||||
/area/wizard_station)
|
||||
"fp" = (
|
||||
@@ -1432,6 +1434,7 @@
|
||||
/obj/structure/chair/sofa/right{
|
||||
color = "#63009c"
|
||||
},
|
||||
/obj/effect/landmark/spawner/roundstart_observer,
|
||||
/turf/simulated/floor/wood,
|
||||
/area/wizard_station)
|
||||
"fx" = (
|
||||
@@ -5407,7 +5410,6 @@
|
||||
/turf/simulated/floor/mineral/plastitanium/red,
|
||||
/area/shuttle/assault_pod)
|
||||
"sh" = (
|
||||
/obj/effect/spawner/window/reinforced,
|
||||
/obj/machinery/door/poddoor/shutters{
|
||||
density = 0;
|
||||
dir = 2;
|
||||
@@ -5416,6 +5418,7 @@
|
||||
name = "Privacy Shutters";
|
||||
opacity = 0
|
||||
},
|
||||
/obj/effect/spawner/window/shuttle,
|
||||
/turf/simulated/floor/mineral/titanium/blue,
|
||||
/area/shuttle/trade/sol)
|
||||
"sj" = (
|
||||
@@ -8159,6 +8162,7 @@
|
||||
name = "wizard council throne";
|
||||
dir = 1
|
||||
},
|
||||
/obj/effect/landmark/spawner/roundstart_observer,
|
||||
/turf/simulated/floor/carpet/red,
|
||||
/area/wizard_station)
|
||||
"CY" = (
|
||||
@@ -12077,6 +12081,7 @@
|
||||
/obj/structure/chair/sofa{
|
||||
color = "#63009c"
|
||||
},
|
||||
/obj/effect/landmark/spawner/roundstart_observer,
|
||||
/turf/simulated/floor/wood,
|
||||
/area/wizard_station)
|
||||
"Qm" = (
|
||||
@@ -14263,6 +14268,7 @@
|
||||
/obj/structure/chair/comfy/purp{
|
||||
name = "wizard council throne"
|
||||
},
|
||||
/obj/effect/landmark/spawner/roundstart_observer,
|
||||
/turf/simulated/floor/carpet/red,
|
||||
/area/wizard_station)
|
||||
"Yp" = (
|
||||
|
||||
@@ -53839,7 +53839,7 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/heat_exchanging{
|
||||
dir = 5
|
||||
},
|
||||
/turf/simulated/floor/engine,
|
||||
/turf/simulated/floor/engine/vacuum,
|
||||
/area/station/science/toxins/mixing)
|
||||
"eiv" = (
|
||||
/obj/effect/spawner/window/reinforced/plasma/grilled,
|
||||
@@ -59935,7 +59935,7 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/heat_exchanging{
|
||||
dir = 4
|
||||
},
|
||||
/turf/simulated/floor/engine,
|
||||
/turf/simulated/floor/engine/vacuum,
|
||||
/area/station/science/toxins/mixing)
|
||||
"gZn" = (
|
||||
/obj/effect/spawner/random_spawners/cobweb_left_rare,
|
||||
@@ -63601,7 +63601,7 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/heat_exchanging{
|
||||
dir = 10
|
||||
},
|
||||
/turf/simulated/floor/engine,
|
||||
/turf/simulated/floor/engine/vacuum,
|
||||
/area/station/science/toxins/mixing)
|
||||
"iUF" = (
|
||||
/obj/structure/cable{
|
||||
@@ -64813,7 +64813,7 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/heat_exchanging{
|
||||
dir = 9
|
||||
},
|
||||
/turf/simulated/floor/engine,
|
||||
/turf/simulated/floor/engine/vacuum,
|
||||
/area/station/science/toxins/mixing)
|
||||
"jzT" = (
|
||||
/obj/machinery/door/airlock/command{
|
||||
@@ -69802,7 +69802,7 @@
|
||||
/area/station/maintenance/apmaint2)
|
||||
"lVB" = (
|
||||
/obj/machinery/atmospherics/unary/passive_vent,
|
||||
/turf/simulated/floor/engine,
|
||||
/turf/simulated/floor/engine/vacuum,
|
||||
/area/station/science/toxins/mixing)
|
||||
"lVK" = (
|
||||
/obj/machinery/door/airlock/maintenance,
|
||||
@@ -73550,7 +73550,7 @@
|
||||
id = "toxinsigniter";
|
||||
pixel_x = -20
|
||||
},
|
||||
/turf/simulated/floor/engine,
|
||||
/turf/simulated/floor/engine/vacuum,
|
||||
/area/station/science/toxins/mixing)
|
||||
"nTm" = (
|
||||
/obj/machinery/sparker{
|
||||
@@ -74563,7 +74563,7 @@
|
||||
dir = 6
|
||||
},
|
||||
/obj/effect/landmark/spawner/nukedisc_respawn,
|
||||
/turf/simulated/floor/engine,
|
||||
/turf/simulated/floor/engine/vacuum,
|
||||
/area/station/science/toxins/mixing)
|
||||
"opg" = (
|
||||
/obj/item/seeds/potato,
|
||||
@@ -76565,7 +76565,7 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction{
|
||||
dir = 1
|
||||
},
|
||||
/turf/simulated/floor/engine,
|
||||
/turf/simulated/floor/engine/vacuum,
|
||||
/area/station/science/toxins/mixing)
|
||||
"plJ" = (
|
||||
/obj/structure/cable{
|
||||
@@ -77521,7 +77521,7 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/heat_exchanging{
|
||||
dir = 6
|
||||
},
|
||||
/turf/simulated/floor/engine,
|
||||
/turf/simulated/floor/engine/vacuum,
|
||||
/area/station/science/toxins/mixing)
|
||||
"pMv" = (
|
||||
/obj/machinery/light_switch{
|
||||
|
||||
@@ -21636,7 +21636,7 @@
|
||||
/obj/machinery/atmospherics/unary/outlet_injector/on{
|
||||
dir = 4
|
||||
},
|
||||
/turf/simulated/floor/engine,
|
||||
/turf/simulated/floor/engine/vacuum,
|
||||
/area/station/science/toxins/mixing)
|
||||
"clR" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/visible{
|
||||
@@ -21840,7 +21840,7 @@
|
||||
/obj/machinery/light{
|
||||
dir = 1
|
||||
},
|
||||
/turf/simulated/floor/engine,
|
||||
/turf/simulated/floor/engine/vacuum,
|
||||
/area/station/science/toxins/mixing)
|
||||
"cnm" = (
|
||||
/obj/structure/sign/poster/random{
|
||||
@@ -62432,7 +62432,7 @@
|
||||
/obj/machinery/atmospherics/unary/vent_pump/siphon/on{
|
||||
dir = 4
|
||||
},
|
||||
/turf/simulated/floor/engine,
|
||||
/turf/simulated/floor/engine/vacuum,
|
||||
/area/station/science/toxins/mixing)
|
||||
"mQh" = (
|
||||
/obj/machinery/firealarm{
|
||||
@@ -64492,7 +64492,7 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/heat_exchanging{
|
||||
dir = 6
|
||||
},
|
||||
/turf/simulated/floor/engine,
|
||||
/turf/simulated/floor/engine/vacuum,
|
||||
/area/station/science/toxins/mixing)
|
||||
"nyv" = (
|
||||
/obj/machinery/door/airlock/maintenance{
|
||||
@@ -70056,7 +70056,7 @@
|
||||
/obj/machinery/igniter{
|
||||
id = "Incinerator"
|
||||
},
|
||||
/turf/simulated/floor/engine,
|
||||
/turf/simulated/floor/engine/vacuum,
|
||||
/area/station/science/toxins/mixing)
|
||||
"pow" = (
|
||||
/obj/machinery/economy/vending/artvend,
|
||||
@@ -83107,7 +83107,7 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/heat_exchanging{
|
||||
dir = 5
|
||||
},
|
||||
/turf/simulated/floor/engine,
|
||||
/turf/simulated/floor/engine/vacuum,
|
||||
/area/station/science/toxins/mixing)
|
||||
"txQ" = (
|
||||
/obj/machinery/atmospherics/unary/vent_pump/on,
|
||||
@@ -95114,7 +95114,7 @@
|
||||
/area/station/maintenance/port)
|
||||
"xbh" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/heat_exchanging,
|
||||
/turf/simulated/floor/engine,
|
||||
/turf/simulated/floor/engine/vacuum,
|
||||
/area/station/science/toxins/mixing)
|
||||
"xbm" = (
|
||||
/obj/structure/disposalpipe/trunk,
|
||||
|
||||
@@ -50104,7 +50104,7 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/heat_exchanging{
|
||||
dir = 6
|
||||
},
|
||||
/turf/simulated/floor/engine,
|
||||
/turf/simulated/floor/engine/vacuum,
|
||||
/area/station/science/toxins/mixing)
|
||||
"cKw" = (
|
||||
/obj/structure/table,
|
||||
@@ -51924,7 +51924,7 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/heat_exchanging{
|
||||
dir = 10
|
||||
},
|
||||
/turf/simulated/floor/engine,
|
||||
/turf/simulated/floor/engine/vacuum,
|
||||
/area/station/science/toxins/mixing)
|
||||
"cRz" = (
|
||||
/obj/structure/girder,
|
||||
@@ -71280,7 +71280,7 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/heat_exchanging{
|
||||
dir = 4
|
||||
},
|
||||
/turf/simulated/floor/engine,
|
||||
/turf/simulated/floor/engine/vacuum,
|
||||
/area/station/science/toxins/mixing)
|
||||
"hsE" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{
|
||||
@@ -72445,7 +72445,7 @@
|
||||
/area/station/engineering/control)
|
||||
"ieu" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction,
|
||||
/turf/simulated/floor/engine,
|
||||
/turf/simulated/floor/engine/vacuum,
|
||||
/area/station/science/toxins/mixing)
|
||||
"iev" = (
|
||||
/obj/machinery/door/window/classic/reversed{
|
||||
@@ -74635,7 +74635,7 @@
|
||||
/obj/machinery/atmospherics/unary/passive_vent{
|
||||
dir = 1
|
||||
},
|
||||
/turf/simulated/floor/engine,
|
||||
/turf/simulated/floor/engine/vacuum,
|
||||
/area/station/science/toxins/mixing)
|
||||
"jAs" = (
|
||||
/obj/machinery/door/firedoor,
|
||||
@@ -79593,19 +79593,6 @@
|
||||
icon_state = "dark"
|
||||
},
|
||||
/area/station/security/prison/cell_block)
|
||||
"mBa" = (
|
||||
/obj/effect/spawner/window/reinforced,
|
||||
/obj/structure/cable{
|
||||
d1 = 4;
|
||||
d2 = 8;
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/obj/structure/cable{
|
||||
d2 = 8;
|
||||
icon_state = "0-8"
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/station/engineering/smes)
|
||||
"mBy" = (
|
||||
/obj/structure/bed,
|
||||
/obj/item/bedsheet/green,
|
||||
@@ -86252,7 +86239,7 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/heat_exchanging{
|
||||
dir = 9
|
||||
},
|
||||
/turf/simulated/floor/engine,
|
||||
/turf/simulated/floor/engine/vacuum,
|
||||
/area/station/science/toxins/mixing)
|
||||
"qwZ" = (
|
||||
/obj/machinery/door/poddoor{
|
||||
@@ -90537,7 +90524,7 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/heat_exchanging{
|
||||
dir = 5
|
||||
},
|
||||
/turf/simulated/floor/engine,
|
||||
/turf/simulated/floor/engine/vacuum,
|
||||
/area/station/science/toxins/mixing)
|
||||
"sMn" = (
|
||||
/obj/structure/table/glass,
|
||||
@@ -95131,7 +95118,7 @@
|
||||
/obj/machinery/atmospherics/air_sensor{
|
||||
autolink_id = "burn_sensor"
|
||||
},
|
||||
/turf/simulated/floor/engine,
|
||||
/turf/simulated/floor/engine/vacuum,
|
||||
/area/station/science/toxins/mixing)
|
||||
"vBT" = (
|
||||
/obj/machinery/door/window/brigdoor{
|
||||
@@ -97380,7 +97367,7 @@
|
||||
autolink_id = "air_in";
|
||||
dir = 1
|
||||
},
|
||||
/turf/simulated/floor/engine,
|
||||
/turf/simulated/floor/engine/vacuum,
|
||||
/area/station/science/toxins/mixing)
|
||||
"wSw" = (
|
||||
/obj/machinery/economy/vending/cola,
|
||||
@@ -127352,7 +127339,7 @@ bwP
|
||||
fsO
|
||||
oNV
|
||||
ucB
|
||||
mBa
|
||||
fsO
|
||||
clv
|
||||
bQr
|
||||
bQr
|
||||
|
||||
7
code/__DEFINES/particle_defines.dm
Normal file
@@ -0,0 +1,7 @@
|
||||
// These are used to convery what kind of debris should spawn from being hit by something
|
||||
#define DEBRIS_SPARKS "spark"
|
||||
#define DEBRIS_WOOD "wood"
|
||||
#define DEBRIS_ROCK "rock"
|
||||
#define DEBRIS_GLASS "glass"
|
||||
#define DEBRIS_LEAF "leaf"
|
||||
#define DEBRIS_SNOW "snow"
|
||||
@@ -445,9 +445,9 @@ GLOBAL_LIST_EMPTY(bicon_cache)
|
||||
* * frame - what frame of the icon_state's animation for the icon being used
|
||||
* * moving - whether or not to use a moving state for the given icon
|
||||
* * sourceonly - if TRUE, only generate the asset and send back the asset url, instead of tags that display the icon to players
|
||||
* * extra_clases - string of extra css classes to use when returning the icon string
|
||||
* * extra_classes - string of extra css classes to use when returning the icon string
|
||||
*/
|
||||
/proc/icon2html(atom/thing, client/target, icon_state, dir = SOUTH, frame = 1, moving = FALSE, sourceonly = FALSE, extra_classes = null)
|
||||
/proc/icon2asset(atom/thing, client/target, icon_state, dir = SOUTH, frame = 1, moving = FALSE, sourceonly = FALSE, extra_classes = null)
|
||||
if(!thing)
|
||||
return
|
||||
|
||||
@@ -516,17 +516,15 @@ GLOBAL_LIST_EMPTY(bicon_cache)
|
||||
SSassets.transport.register_asset(key, rsc_ref, file_hash, icon_path)
|
||||
for(var/client_target in targets)
|
||||
SSassets.transport.send_assets(client_target, key)
|
||||
if(sourceonly)
|
||||
return SSassets.transport.get_asset_url(key)
|
||||
return "<img class='icon icon-[icon_state]' src='[SSassets.transport.get_asset_url(key)]'>"
|
||||
return key
|
||||
|
||||
/// Costlier version of icon2html() that uses getFlatIcon() to account for overlays, underlays, etc. Use with extreme moderation, ESPECIALLY on mobs.
|
||||
/proc/costly_icon2html(thing, target, sourceonly = FALSE)
|
||||
/// Costlier version of icon2asset() that uses getFlatIcon() to account for overlays, underlays, etc. Use with extreme moderation, ESPECIALLY on mobs.
|
||||
/proc/costly_icon2asset(thing, target, sourceonly = FALSE)
|
||||
if(!thing)
|
||||
return
|
||||
|
||||
if(isicon(thing))
|
||||
return icon2html(thing, target)
|
||||
return icon2asset(thing, target)
|
||||
|
||||
var/icon/I = getFlatIcon(thing)
|
||||
return icon2html(I, target, sourceonly = sourceonly)
|
||||
return icon2asset(I, target)
|
||||
|
||||
@@ -346,35 +346,23 @@
|
||||
new_text += copytext(text, i, i+1)
|
||||
return new_text
|
||||
|
||||
//This proc strips html properly, but it's not lazy like the other procs.
|
||||
//This means that it doesn't just remove < and > and call it a day.
|
||||
//Also limit the size of the input, if specified.
|
||||
/proc/strip_html_properly(input, max_length = MAX_MESSAGE_LEN, allow_lines = 0)
|
||||
/// Strips HTML tags (and only tags) from the input.
|
||||
/// The result may still include HTML entities, like ' for '
|
||||
/proc/strip_html_tags(input, max_length = MAX_MESSAGE_LEN, allow_lines = 0)
|
||||
if(!input)
|
||||
return
|
||||
var/opentag = 1 //These store the position of < and > respectively.
|
||||
var/closetag = 1
|
||||
while(1)
|
||||
opentag = findtext(input, "<")
|
||||
closetag = findtext(input, ">")
|
||||
if(closetag && opentag)
|
||||
if(closetag < opentag)
|
||||
input = copytext(input, (closetag + 1))
|
||||
else
|
||||
input = copytext(input, 1, opentag) + copytext(input, (closetag + 1))
|
||||
else if(closetag || opentag)
|
||||
if(opentag)
|
||||
input = copytext(input, 1, opentag)
|
||||
else
|
||||
input = copytext(input, (closetag + 1))
|
||||
else
|
||||
break
|
||||
return ""
|
||||
var/static/regex/tags = regex("<\[^>]*>", "g")
|
||||
if(!tags)
|
||||
tags = regex("<\[^>]*>", "g")
|
||||
input = tags.Replace(input, "")
|
||||
if(max_length)
|
||||
input = copytext_char(input, 1, max_length)
|
||||
return sanitize(input, allow_lines ? list("\t" = " ") : list("\n" = " ", "\t" = " "))
|
||||
if(allow_lines)
|
||||
return sanitize_simple(input, list("\t" = " "))
|
||||
return sanitize_simple(input, list("\n" = " ", "\t" = " "))
|
||||
|
||||
/proc/trim_strip_html_properly(input, max_length = MAX_MESSAGE_LEN, allow_lines = 0)
|
||||
return trim(strip_html_properly(input, max_length, allow_lines))
|
||||
/proc/trim_strip_html_tags(input, max_length = MAX_MESSAGE_LEN, allow_lines = 0)
|
||||
return trim(strip_html_tags(input, max_length, allow_lines))
|
||||
|
||||
//Used in preferences' SetFlavorText and human's set_flavor verb
|
||||
//Previews a string of len or less length
|
||||
@@ -742,11 +730,6 @@
|
||||
return null
|
||||
|
||||
|
||||
// Removes HTML tags, preserving text
|
||||
/proc/strip_html_tags(the_text)
|
||||
var/static/regex/html_replacer = regex("<\[^>]*>", "g")
|
||||
return html_replacer.Replace(the_text, "")
|
||||
|
||||
/proc/starts_with_vowel(text)
|
||||
var/start_char = copytext(text, 1, 2)
|
||||
switch(lowertext(start_char))
|
||||
|
||||
@@ -38,6 +38,7 @@ GLOBAL_LIST_EMPTY(nukedisc_respawn)
|
||||
GLOBAL_LIST_EMPTY(ninjastart)
|
||||
GLOBAL_LIST_EMPTY(carplist) //list of all carp-spawn landmarks
|
||||
GLOBAL_LIST_EMPTY(syndicateofficer)
|
||||
GLOBAL_LIST_EMPTY(roundstart_observer_start)
|
||||
|
||||
//List of preloaded templates
|
||||
GLOBAL_LIST_EMPTY(map_templates)
|
||||
|
||||
@@ -112,11 +112,10 @@ SUBSYSTEM_DEF(statpanels)
|
||||
/// Set the atoms we're meant to display
|
||||
var/datum/object_window_info/obj_window = istype(target.obj_window) ? target.obj_window : new(target)
|
||||
obj_window.atoms_to_show = atoms_to_display
|
||||
START_PROCESSING(SSobj_tab_items, obj_window)
|
||||
refresh_client_obj_view(target)
|
||||
refresh_client_obj_view(target, obj_window.min_index, obj_window.max_index)
|
||||
|
||||
/datum/controller/subsystem/statpanels/proc/refresh_client_obj_view(client/refresh)
|
||||
var/list/turf_items = return_object_images(refresh)
|
||||
/datum/controller/subsystem/statpanels/proc/refresh_client_obj_view(client/refresh, min_index = 0, max_index = 30)
|
||||
var/list/turf_items = return_object_images(refresh, min_index, max_index)
|
||||
if(!length(turf_items) || !refresh.mob?.listed_turf)
|
||||
return
|
||||
refresh.stat_panel.send_message("update_listedturf", turf_items)
|
||||
@@ -125,7 +124,7 @@ SUBSYSTEM_DEF(statpanels)
|
||||
|
||||
/// Returns all our ready object tab images
|
||||
/// Returns a list in the form list(list(object_name, object_ref, loaded_image), ...)
|
||||
/datum/controller/subsystem/statpanels/proc/return_object_images(client/load_from)
|
||||
/datum/controller/subsystem/statpanels/proc/return_object_images(client/load_from, min_index, max_index)
|
||||
// You might be inclined to think that this is a waste of cpu time, since we
|
||||
// A: Double iterate over atoms in the build case, or
|
||||
// B: Generate these lists over and over in the refresh case
|
||||
@@ -137,10 +136,18 @@ SUBSYSTEM_DEF(statpanels)
|
||||
return list()
|
||||
|
||||
var/datum/object_window_info/obj_window = load_from.obj_window
|
||||
if(!obj_window)
|
||||
return list()
|
||||
var/list/already_seen = obj_window.atoms_to_images
|
||||
var/list/to_make = obj_window.atoms_to_imagify
|
||||
var/list/turf_items = list()
|
||||
var/i = 0
|
||||
for(var/atom/turf_item as anything in obj_window.atoms_to_show)
|
||||
// Limit what we send to the client's rendered section.
|
||||
i++
|
||||
if(i <= min_index || i > max_index)
|
||||
continue
|
||||
|
||||
// First, we fill up the list of refs to display
|
||||
// If we already have one, just use that
|
||||
var/existing_image = already_seen[turf_item]
|
||||
@@ -148,12 +155,17 @@ SUBSYSTEM_DEF(statpanels)
|
||||
continue
|
||||
// We already have it. Success!
|
||||
if(existing_image)
|
||||
turf_items[++turf_items.len] = list("[turf_item.name]", turf_item.UID(), existing_image)
|
||||
turf_items["[i]"] = list("[turf_item.name]", turf_item.UID(), SSassets.transport.get_asset_url(existing_image), existing_image)
|
||||
continue
|
||||
// Now, we're gonna queue image generation out of those refs
|
||||
to_make += turf_item
|
||||
already_seen[turf_item] = OBJ_IMAGE_LOADING
|
||||
obj_window.RegisterSignal(turf_item, COMSIG_PARENT_QDELETING, TYPE_PROC_REF(/datum/object_window_info, viewing_atom_deleted), override = TRUE) // we reset cache if anything in it gets deleted
|
||||
turf_items["total"] = i
|
||||
obj_window.min_index = min_index
|
||||
obj_window.max_index = max_index
|
||||
if(length(to_make))
|
||||
START_PROCESSING(SSobj_tab_items, obj_window)
|
||||
return turf_items
|
||||
|
||||
#undef OBJ_IMAGE_LOADING
|
||||
@@ -219,6 +231,10 @@ SUBSYSTEM_DEF(statpanels)
|
||||
var/client/parent
|
||||
/// Are we currently tracking a turf?
|
||||
var/actively_tracking = FALSE
|
||||
/// The minimum index currently sent to the client.
|
||||
var/min_index = 0
|
||||
/// The maximum index currently sent to the client.
|
||||
var/max_index = 30
|
||||
|
||||
/datum/object_window_info/New(client/parent)
|
||||
. = ..()
|
||||
@@ -245,9 +261,9 @@ SUBSYSTEM_DEF(statpanels)
|
||||
|
||||
var/generated_string
|
||||
if(ismob(thing) || length(thing.overlays) > 2)
|
||||
generated_string = costly_icon2html(thing, parent, sourceonly=TRUE)
|
||||
generated_string = costly_icon2asset(thing, parent)
|
||||
else
|
||||
generated_string = icon2html(thing, parent, sourceonly=TRUE)
|
||||
generated_string = icon2asset(thing, parent)
|
||||
|
||||
newly_seen[thing] = generated_string
|
||||
if(TICK_CHECK)
|
||||
@@ -257,7 +273,7 @@ SUBSYSTEM_DEF(statpanels)
|
||||
// If we've not cut yet, do it now
|
||||
if(index)
|
||||
to_make.Cut(1, index + 1)
|
||||
SSstatpanels.refresh_client_obj_view(parent)
|
||||
SSstatpanels.refresh_client_obj_view(parent, min_index, max_index)
|
||||
if(!length(to_make))
|
||||
return PROCESS_KILL
|
||||
|
||||
@@ -302,6 +318,9 @@ SUBSYSTEM_DEF(statpanels)
|
||||
if(listed_turf)
|
||||
client.stat_panel.send_message("create_listedturf", listed_turf.name)
|
||||
client.obj_window.start_turf_tracking()
|
||||
client.obj_window.min_index = 0
|
||||
client.obj_window.max_index = 30
|
||||
SSstatpanels.set_turf_examine_tab(client, src)
|
||||
else
|
||||
client.stat_panel.send_message("remove_listedturf")
|
||||
client.obj_window.stop_turf_tracking()
|
||||
|
||||
@@ -852,17 +852,17 @@ SUBSYSTEM_DEF(ticker)
|
||||
if(length(SSticker.mode.blob_overminds))
|
||||
switch(outcome)
|
||||
if(ROUND_END_NUCLEAR)
|
||||
SSblackbox.record_feedback("tally", "Biohazard nuclear victories", 1, "Blob")
|
||||
SSblackbox.record_feedback("tally", "Blob nuclear victories", 1, "Blob")
|
||||
if(ROUND_END_CREW_TRANSFER)
|
||||
SSblackbox.record_feedback("tally", "Biohazard survives to normal round end", 1, "Blob")
|
||||
SSblackbox.record_feedback("tally", "Blob survives to normal round end", 1, "Blob")
|
||||
if(ROUND_END_FORCED)
|
||||
SSblackbox.record_feedback("tally", "Biohazard survives to admin round end", 1, "Blob")
|
||||
SSblackbox.record_feedback("tally", "Blob survives to admin round end", 1, "Blob")
|
||||
else
|
||||
switch(outcome)
|
||||
if(ROUND_END_NUCLEAR)
|
||||
SSblackbox.record_feedback("tally", "Biohazard dies station nuked", 1, "Blob")
|
||||
SSblackbox.record_feedback("tally", "Blob dies station nuked", 1, "Blob")
|
||||
if(ROUND_END_CREW_TRANSFER)
|
||||
SSblackbox.record_feedback("tally", "Biohazard dies normal end", 1, "Blob")
|
||||
SSblackbox.record_feedback("tally", "Blob dies normal end", 1, "Blob")
|
||||
if(ROUND_END_FORCED)
|
||||
SSblackbox.record_feedback("tally", "Biohazard dies admin round end", 1, "Blob")
|
||||
SSblackbox.record_feedback("tally", "Blob dies admin round end", 1, "Blob")
|
||||
|
||||
|
||||
@@ -738,7 +738,7 @@ UI STUFF
|
||||
for(var/datum/ticket_response/TR in T.ticket_responses)
|
||||
var/list/this_response = list()
|
||||
this_response["ckey"] = TR.response_user
|
||||
this_response["text"] = strip_html_tags(TR.response_text) // Dont want to save HTML tags in the thing
|
||||
this_response["text"] = html_decode(strip_html_tags(TR.response_text)) // Dont want to save HTML stuff to the DB
|
||||
this_response["time"] = TR.response_time
|
||||
|
||||
raw_responses += list(this_response)
|
||||
|
||||
93
code/datums/components/debris.dm
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* In this file you can find the particle component for bullet hits
|
||||
* Originally from https://github.com/tgstation/TerraGov-Marine-Corps/pull/12752
|
||||
*/
|
||||
|
||||
/particles/debris
|
||||
icon = 'icons/effects/particles/generic_particles.dmi'
|
||||
width = 500
|
||||
height = 500
|
||||
count = 10
|
||||
spawning = 10
|
||||
lifespan = 0.5 SECONDS
|
||||
fade = 0.3 SECONDS
|
||||
drift = generator("circle", 0, 7)
|
||||
scale = 0.3
|
||||
velocity = list(50, 0)
|
||||
friction = generator("num", 0.1, 0.15)
|
||||
spin = generator("num", -20, 20)
|
||||
|
||||
/particles/impact_smoke
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "smoke"
|
||||
width = 500
|
||||
height = 500
|
||||
count = 20
|
||||
spawning = 20
|
||||
lifespan = 0.8 SECONDS
|
||||
fade = 10 SECONDS
|
||||
grow = 0.1
|
||||
scale = 0.2
|
||||
spin = generator("num", -20, 20)
|
||||
velocity = list(50, 0)
|
||||
friction = generator("num", 0.1, 0.5)
|
||||
|
||||
/datum/component/debris
|
||||
/// Icon state of debris when impacted by a projectile
|
||||
var/debris
|
||||
/// Velocity of debris particles
|
||||
var/debris_velocity = -15
|
||||
/// Amount of debris particles
|
||||
var/debris_amount = 8
|
||||
/// Scale of particle debris
|
||||
var/debris_scale = 0.7
|
||||
|
||||
/datum/component/debris/Initialize(_debris_icon_state, _debris_velocity = -15, _debris_amount = 8, _debris_scale = 0.7)
|
||||
. = ..()
|
||||
debris = _debris_icon_state
|
||||
debris_velocity = _debris_velocity
|
||||
debris_amount = _debris_amount
|
||||
debris_scale = _debris_scale
|
||||
RegisterSignal(parent, COMSIG_ATOM_BULLET_ACT, PROC_REF(register_for_impact))
|
||||
|
||||
/datum/component/debris/Destroy(force)
|
||||
. = ..()
|
||||
if(parent)
|
||||
UnregisterSignal(parent, COMSIG_ATOM_BULLET_ACT)
|
||||
|
||||
/datum/component/debris/proc/register_for_impact(datum/source, obj/item/projectile/proj)
|
||||
SIGNAL_HANDLER // COMSIG_ATOM_BULLET_ACT
|
||||
INVOKE_ASYNC(src, PROC_REF(on_impact), proj)
|
||||
|
||||
/datum/component/debris/proc/on_impact(obj/item/projectile/P)
|
||||
var/angle = !isnull(P.Angle) ? P.Angle : round(get_angle(P.starting, parent), 1)
|
||||
var/x_component = sin(angle) * debris_velocity
|
||||
var/y_component = cos(angle) * debris_velocity
|
||||
var/x_component_smoke = sin(angle) * -15
|
||||
var/y_component_smoke = cos(angle) * -15
|
||||
|
||||
var/obj/effect/abstract/particle_holder/debris_visuals
|
||||
var/obj/effect/abstract/particle_holder/smoke_visuals
|
||||
var/position_offset = rand(-6, 6)
|
||||
|
||||
smoke_visuals = new(parent, /particles/impact_smoke)
|
||||
smoke_visuals.particles.position = list(position_offset, position_offset)
|
||||
smoke_visuals.particles.velocity = list(x_component_smoke, y_component_smoke)
|
||||
|
||||
if(debris && P.damage_type == BRUTE)
|
||||
debris_visuals = new(parent, /particles/debris)
|
||||
debris_visuals.particles.position = generator("circle", position_offset, position_offset)
|
||||
debris_visuals.particles.velocity = list(x_component, y_component)
|
||||
debris_visuals.layer = ABOVE_OBJ_LAYER + 0.02
|
||||
debris_visuals.particles.icon_state = debris
|
||||
debris_visuals.particles.count = debris_amount
|
||||
debris_visuals.particles.spawning = debris_amount
|
||||
debris_visuals.particles.scale = debris_scale
|
||||
smoke_visuals.layer = ABOVE_OBJ_LAYER + 0.01
|
||||
|
||||
addtimer(CALLBACK(src, PROC_REF(remove_ping), src, smoke_visuals, debris_visuals), 0.5 SECONDS)
|
||||
|
||||
/datum/component/debris/proc/remove_ping(hit, obj/effect/abstract/particle_holder/smoke_visuals, obj/effect/abstract/particle_holder/debris_visuals)
|
||||
QDEL_NULL(smoke_visuals)
|
||||
if(debris_visuals)
|
||||
QDEL_NULL(debris_visuals)
|
||||
@@ -84,7 +84,7 @@ GLOBAL_DATUM_INIT(discord_manager, /datum/discord_manager, new())
|
||||
else
|
||||
alerttext = "| **NO MENTORS ONLINE**"
|
||||
|
||||
var/message = "[content] [alerttext][add_ping ? handle_mentor_ping() : ""]"
|
||||
var/message = "[html_decode(strip_html_tags(content))] [alerttext][add_ping ? handle_mentor_ping() : ""]"
|
||||
|
||||
var/datum/discord_webhook_payload/dwp = new()
|
||||
dwp.webhook_content = "**\[[GLOB.configuration.system.instance_id]]** [message]"
|
||||
|
||||
@@ -42,6 +42,9 @@
|
||||
// Semi-permanent clown mask while in last stage of infection
|
||||
if(locate(/obj/item/clothing/mask/gas/clown_hat) in H)
|
||||
return
|
||||
if(!istype(H)) // Xenos don't have masks. They can still feel silly though
|
||||
return
|
||||
|
||||
if(!H.has_organ_for_slot(SLOT_HUD_WEAR_MASK) || !H.canUnEquip(H.get_item_by_slot(SLOT_HUD_WEAR_MASK)))
|
||||
return
|
||||
|
||||
|
||||
@@ -58,6 +58,8 @@
|
||||
|
||||
/datum/disease/wizarditis/proc/spawn_wizard_clothes()
|
||||
var/mob/living/carbon/human/H = affected_mob
|
||||
if(!istype(H))
|
||||
return // Woe, wizard xeno upon ye
|
||||
|
||||
// Which slots can we replace?
|
||||
var/list/eligible_slot_IDs = new
|
||||
|
||||
@@ -277,6 +277,9 @@
|
||||
/// A lazy list of user mobs to a list of strip menu keys that they're interacting with
|
||||
var/list/interactions
|
||||
|
||||
/// Associated list of "[icon][icon_state]" = base64 representation of icon. Used for PERFORMANCE.
|
||||
var/static/list/base64_cache = list()
|
||||
|
||||
/datum/strip_menu/New(atom/movable/owner, datum/element/strippable/strippable)
|
||||
. = ..()
|
||||
src.owner = owner
|
||||
@@ -341,7 +344,10 @@
|
||||
|
||||
LAZYINITLIST(result)
|
||||
|
||||
result["icon"] = icon2base64(icon(item.icon, item.icon_state, dir = SOUTH, frame = 1, moving = FALSE))
|
||||
var/key = "[item.icon],[item.icon_state]"
|
||||
if(!(key in base64_cache))
|
||||
base64_cache[key] = icon2base64(icon(item.icon, item.icon_state, dir = SOUTH, frame = 1, moving = FALSE))
|
||||
result["icon"] = base64_cache[key]
|
||||
result["name"] = item.name
|
||||
|
||||
var/real_alts = item_data.get_alternate_actions(owner, user)
|
||||
|
||||
@@ -36,8 +36,8 @@
|
||||
return
|
||||
|
||||
var/datum/antagonist/vampire/vampire = user.mind.has_antag_datum(/datum/antagonist/vampire)
|
||||
|
||||
vampire.bloodusable -= calculate_blood_cost(vampire)
|
||||
var/blood_cost = calculate_blood_cost(vampire)
|
||||
vampire.subtract_usable_blood(blood_cost)
|
||||
|
||||
/datum/spell_handler/vampire/proc/calculate_blood_cost(datum/antagonist/vampire/vampire)
|
||||
var/blood_cost_modifier = 1 + vampire.nullified / 100
|
||||
|
||||
@@ -388,7 +388,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
|
||||
/datum/uplink_item/explosives/plastic_explosives
|
||||
name = "Composition C-4"
|
||||
desc = "C-4 is plastic explosive of the common variety Composition C. Reliably destroys the object it's placed on, assuming it isn't bomb resistant. Does not stick to crewmembers. Will only destroy station floors if placed directly on it. It has a modifiable timer with a minimum setting of 10 seconds."
|
||||
desc = "C-4 is plastic explosive of the common variety Composition C. Reliably destroys the object it's placed on, assuming it isn't bomb resistant. Remarkably good for disposing bodies, or tired crewmates. Will only destroy station floors if placed directly on it. It has a modifiable timer with a minimum setting of 10 seconds."
|
||||
reference = "C4"
|
||||
item = /obj/item/grenade/plastic/c4
|
||||
cost = 5
|
||||
|
||||
@@ -663,6 +663,7 @@
|
||||
|
||||
/datum/uplink_item/stealthy_tools/chameleon/nuke
|
||||
reference = "NCHAM"
|
||||
item = /obj/item/storage/box/syndie_kit/chameleon/nuke
|
||||
cost = 30
|
||||
excludefrom = list(UPLINK_TYPE_TRAITOR, UPLINK_TYPE_SIT)
|
||||
|
||||
|
||||
@@ -468,7 +468,16 @@
|
||||
While the mask is active, your voice will sound unrecognizable to others."
|
||||
reference = "CVMM"
|
||||
item = /obj/item/clothing/mask/gas/voice_modulator/chameleon
|
||||
cost = 8
|
||||
cost = 5
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST)
|
||||
|
||||
/datum/uplink_item/stealthy_tools/voice_changer
|
||||
name = "Chameleon Voice Changer Mask"
|
||||
desc = "A syndicate gas mask equipped with chameleon technology and a voice changer for disguising your voice. \
|
||||
Use it to impersonate or obfuscate your identity when talking and make nobody the wiser!"
|
||||
reference = "CVCM"
|
||||
item = /obj/item/clothing/mask/chameleon/voice_change
|
||||
cost = 10
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST)
|
||||
|
||||
/datum/uplink_item/stealthy_tools/silicon_cham_suit
|
||||
@@ -692,10 +701,10 @@
|
||||
/datum/uplink_item/stealthy_tools/chameleon
|
||||
name = "Chameleon Kit"
|
||||
desc = "A set of items that contain chameleon technology allowing you to disguise as pretty much anything on the station, and more! \
|
||||
Due to budget cuts, the shoes don't provide protection against slipping. The set comes with a complementary chameleon stamp."
|
||||
Due to budget cuts, the shoes don't provide protection against slipping."
|
||||
reference = "CHAM"
|
||||
item = /obj/item/storage/box/syndie_kit/chameleon
|
||||
cost = 20
|
||||
cost = 10
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST)
|
||||
|
||||
/datum/uplink_item/stealthy_tools/syndigaloshes
|
||||
|
||||
@@ -45,7 +45,7 @@ GLOBAL_DATUM_INIT(major_announcement, /datum/announcer, new(config_type = /datum
|
||||
var/message_sound2 = new_sound2 ? sound(new_sound2) : null
|
||||
|
||||
if(!msg_sanitized)
|
||||
message = trim_strip_html_properly(message, allow_lines = TRUE)
|
||||
message = html_encode(message)
|
||||
|
||||
var/datum/language/message_language = GLOB.all_languages[msg_language ? msg_language : language]
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
icon_state = "yellow"
|
||||
|
||||
/area/ruin/powered/golem_ship
|
||||
name = "Free Golem Landing"
|
||||
name = "Free Golem Ship"
|
||||
icon_state = "yellow"
|
||||
|
||||
/area/ruin/powered/greed
|
||||
|
||||
@@ -356,6 +356,8 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
|
||||
H.uncuff()
|
||||
H.Silence(6 SECONDS) //Prevent "HALP MAINT CULT" before you realise you're converted
|
||||
if(H.reagents?.has_reagent("holywater"))
|
||||
H.reagents.del_reagent("holywater") // Also prevent fill stomach with holy water and "forgot" about it after converting
|
||||
|
||||
var/obj/item/melee/cultblade/dagger/D = new(get_turf(src))
|
||||
if(H.equip_to_slot_if_possible(D, SLOT_HUD_IN_BACKPACK, FALSE, TRUE))
|
||||
|
||||
@@ -96,15 +96,15 @@
|
||||
|
||||
/obj/item/pinpointer/proc/scandisk()
|
||||
if(!the_disk)
|
||||
the_disk = locate()
|
||||
the_disk = locate() in GLOB.poi_list
|
||||
|
||||
/obj/item/pinpointer/proc/scanbomb()
|
||||
if(!syndicate)
|
||||
if(!the_bomb)
|
||||
the_bomb = locate()
|
||||
the_bomb = locate() in GLOB.poi_list
|
||||
else
|
||||
if(!the_s_bomb)
|
||||
the_s_bomb = locate()
|
||||
the_s_bomb = locate() in GLOB.poi_list
|
||||
|
||||
/obj/item/pinpointer/proc/point_at_target(atom/target)
|
||||
if(!target)
|
||||
|
||||
@@ -65,8 +65,7 @@
|
||||
return FALSE
|
||||
|
||||
/datum/spellbook_entry/proc/Refund(mob/living/carbon/human/user, obj/item/spellbook/book) //return point value or -1 for failure
|
||||
var/area/wizard_station/A = locate()
|
||||
if(!(user in A.contents))
|
||||
if(!istype(get_area(user), /area/wizard_station))
|
||||
to_chat(user, "<span class='warning'>You can only refund spells at the wizard lair.</span>")
|
||||
return -1
|
||||
if(!S) //This happens when the spell's source is from another spellbook, from loadouts, or adminery, this create a new template temporary spell
|
||||
@@ -1152,7 +1151,7 @@
|
||||
|
||||
/obj/item/spellbook/oneuse/random/initialize()
|
||||
. = ..()
|
||||
var/static/banned_spells = list(/obj/item/spellbook/oneuse/mime, /obj/item/spellbook/oneuse/mime/fingergun, /obj/item/spellbook/oneuse/mime/fingergun/fake, /obj/item/spellbook/oneuse/mime/greaterwall)
|
||||
var/static/list/banned_spells = typesof(/obj/item/spellbook/oneuse/mime, /obj/item/spellbook/oneuse/emp)
|
||||
var/real_type = pick(subtypesof(/obj/item/spellbook/oneuse) - banned_spells)
|
||||
new real_type(loc)
|
||||
qdel(src)
|
||||
|
||||
@@ -255,7 +255,7 @@
|
||||
Nuke_request(input, ui.user)
|
||||
to_chat(ui.user, "<span class='notice'>Request sent.</span>")
|
||||
log_game("[key_name(ui.user)] has requested the nuclear codes from Centcomm")
|
||||
GLOB.major_announcement.Announce("The codes for the on-station nuclear self-destruct have been requested by [ui.user]. Confirmation or denial of this request will be sent shortly.", "Nuclear Self Destruct Codes Requested", 'sound/AI/nuke_codes.ogg')
|
||||
GLOB.major_announcement.Announce("The codes for the on-station nuclear self-destruction device have been requested by [ui.user]. Confirmation or denial of this request will be sent shortly.", "Nuclear Self Destruct Codes Requested", 'sound/AI/nuke_codes.ogg')
|
||||
centcomm_message_cooldown = world.time + 6000 // 10 minutes
|
||||
setMenuState(ui.user, COMM_SCREEN_MAIN)
|
||||
|
||||
@@ -562,7 +562,7 @@
|
||||
return
|
||||
|
||||
if(!sanitized)
|
||||
reason = trim_strip_html_properly(reason, allow_lines = TRUE)
|
||||
reason = trim_strip_html_tags(reason, allow_lines = TRUE)
|
||||
|
||||
SSshuttle.requestEvac(user, reason)
|
||||
log_game("[key_name(user)] has called the shuttle.")
|
||||
|
||||
@@ -396,8 +396,7 @@
|
||||
|
||||
//Select Your Name
|
||||
if("Sender")
|
||||
customsender = input("Please enter the sender's name.")
|
||||
customsender = trim_strip_html_properly(customsender)
|
||||
customsender = clean_input("Please enter the sender's name.")
|
||||
|
||||
//Select Receiver
|
||||
if("Recepient")
|
||||
@@ -416,13 +415,11 @@
|
||||
|
||||
//Enter custom job
|
||||
if("RecJob")
|
||||
customjob = input("Please enter the sender's job.")
|
||||
customjob = trim_strip_html_properly(customjob)
|
||||
customjob = clean_input("Please enter the sender's job.")
|
||||
|
||||
//Enter message
|
||||
if("Message")
|
||||
custommessage = input("Please enter your message.")
|
||||
custommessage = trim_strip_html_properly(custommessage)
|
||||
custommessage = clean_input("Please enter your message.")
|
||||
|
||||
//Send message
|
||||
if("Send")
|
||||
|
||||
@@ -27,6 +27,10 @@
|
||||
//The list of directions to block a projectile from
|
||||
var/list/directional_list = list()
|
||||
|
||||
/obj/structure/barricade/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/debris, DEBRIS_WOOD, -20, 10)
|
||||
|
||||
/obj/structure/barricade/deconstruct(disassembled = TRUE)
|
||||
if(!(flags & NODECONSTRUCT))
|
||||
make_debris()
|
||||
|
||||
@@ -45,6 +45,9 @@
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/thrusters
|
||||
ME.attach(src)
|
||||
|
||||
/obj/mecha/combat/marauder/add_cell()
|
||||
cell = new /obj/item/stock_parts/cell/bluespace(src)
|
||||
|
||||
/obj/mecha/combat/marauder/ares
|
||||
name = "Ares"
|
||||
desc = "Heavy-duty, combat exosuit, adapted from rejected early versions of the Marauder to serve as a biohazard containment exosuit. This model, albeit rare, can be found among civilian populations."
|
||||
@@ -85,9 +88,6 @@
|
||||
force = 80
|
||||
max_equip = 8
|
||||
|
||||
/obj/mecha/combat/marauder/seraph/add_cell()
|
||||
cell = new /obj/item/stock_parts/cell/bluespace(src)
|
||||
|
||||
/obj/mecha/combat/marauder/seraph/loaded/Initialize(mapload)
|
||||
. = ..() //Let it equip whatever is needed.
|
||||
var/obj/item/mecha_parts/mecha_equipment/ME
|
||||
|
||||
@@ -148,3 +148,67 @@
|
||||
|
||||
/obj/effect/decal/proc/on_scoop()
|
||||
return
|
||||
|
||||
/// These effects can be added to anything to hold particles, which is useful because Byond only allows a single particle per atom
|
||||
/obj/effect/abstract/particle_holder
|
||||
anchored = TRUE
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
layer = ABOVE_ALL_MOB_LAYER
|
||||
vis_flags = VIS_INHERIT_PLANE
|
||||
invisibility = FALSE
|
||||
///typepath of the last location we're in, if it's different when moved then we need to update vis contents
|
||||
var/last_attached_location_type
|
||||
/// The main item we're attached to at the moment, particle holders hold particles for something
|
||||
var/atom/movable/parent
|
||||
/// The mob that is holding our item
|
||||
var/mob/holding_parent
|
||||
|
||||
/obj/effect/abstract/particle_holder/Initialize(mapload, particle_path = null)
|
||||
. = ..()
|
||||
if(!loc)
|
||||
stack_trace("particle holder was created with no loc!")
|
||||
return INITIALIZE_HINT_QDEL
|
||||
parent = loc
|
||||
|
||||
if(ismovable(parent))
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(on_move))
|
||||
RegisterSignal(parent, COMSIG_PARENT_QDELETING, PROC_REF(on_qdel))
|
||||
|
||||
particles = new particle_path
|
||||
update_visual_contents(parent)
|
||||
|
||||
/obj/effect/abstract/particle_holder/Destroy(force)
|
||||
if(parent)
|
||||
UnregisterSignal(parent, list(COMSIG_MOVABLE_MOVED, COMSIG_PARENT_QDELETING))
|
||||
QDEL_NULL(particles)
|
||||
parent.vis_contents -= src
|
||||
return ..()
|
||||
|
||||
///signal called when parent is moved
|
||||
/obj/effect/abstract/particle_holder/proc/on_move(atom/movable/attached, atom/oldloc, direction)
|
||||
SIGNAL_HANDLER
|
||||
if(parent.loc.type != last_attached_location_type)
|
||||
update_visual_contents(attached)
|
||||
|
||||
///signal called when parent is deleted
|
||||
/obj/effect/abstract/particle_holder/proc/on_qdel(atom/movable/attached, force)
|
||||
SIGNAL_HANDLER
|
||||
attached.vis_contents -= src
|
||||
qdel(src)//our parent is gone and we need to be as well
|
||||
|
||||
///logic proc for particle holders, aka where they move.
|
||||
///subtypes of particle holders can override this for particles that should always be turf level or do special things when repositioning.
|
||||
///this base subtype has some logic for items, as the loc of items becomes mobs very often hiding the particles
|
||||
/obj/effect/abstract/particle_holder/proc/update_visual_contents(atom/movable/attached_to)
|
||||
// Remove old
|
||||
if(holding_parent && !(QDELETED(holding_parent)))
|
||||
holding_parent.vis_contents -= src
|
||||
|
||||
// Add new
|
||||
if(isitem(attached_to) && ismob(attached_to.loc)) //special case we want to also be emitting from the mob
|
||||
var/mob/particle_mob = attached_to.loc
|
||||
last_attached_location_type = attached_to.loc
|
||||
particle_mob.vis_contents += src
|
||||
|
||||
// Readd to ourselves
|
||||
attached_to.vis_contents |= src
|
||||
|
||||
@@ -235,6 +235,14 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/newplayer_start) //Without this you sp
|
||||
/obj/effect/landmark/spawner/nuke_code
|
||||
name = "nukecode"
|
||||
|
||||
/obj/effect/landmark/spawner/roundstart_observer
|
||||
name = "Roundstart Observer"
|
||||
icon_state = "spooky"
|
||||
|
||||
/obj/effect/landmark/spawner/roundstart_observer/Initialize(mapload)
|
||||
spawner_list = GLOB.roundstart_observer_start
|
||||
return ..()
|
||||
|
||||
/obj/effect/landmark/Destroy()
|
||||
GLOB.landmarks_list -= src
|
||||
..()
|
||||
@@ -414,7 +422,6 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/newplayer_start) //Without this you sp
|
||||
name = "Warden"
|
||||
icon_state = "Warden"
|
||||
|
||||
|
||||
/obj/effect/landmark/start/set_tag()
|
||||
tag = "start*[name]"
|
||||
|
||||
|
||||
@@ -149,7 +149,8 @@
|
||||
/obj/item/clothing/under/chameleon = 2,
|
||||
/obj/item/stamp/chameleon = 2,
|
||||
/obj/item/clothing/shoes/chameleon/noslip = 5,
|
||||
/obj/item/clothing/mask/chameleon = 2,
|
||||
/obj/item/clothing/mask/chameleon = 4,
|
||||
/obj/item/clothing/mask/chameleon/voice_change = 2,
|
||||
/obj/item/clothing/mask/gas/voice_modulator = 2,
|
||||
/obj/item/clothing/mask/gas/voice_modulator/chameleon = 2,
|
||||
/obj/item/dnascrambler = 1,
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
* Toy Nuke
|
||||
* Card Deck
|
||||
* Therapy dolls
|
||||
* Toddler doll
|
||||
* Inflatable duck
|
||||
* Foam armblade
|
||||
* Mini Gibber
|
||||
@@ -438,14 +437,6 @@
|
||||
item_state = "egg3" // It's the green egg in items_left/righthand
|
||||
item_color = "green"
|
||||
|
||||
/obj/item/toddler
|
||||
icon_state = "toddler"
|
||||
name = "toddler"
|
||||
desc = "This baby looks almost real. Wait, did it just burp?"
|
||||
force = 5
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
slot_flags = SLOT_FLAG_BACK
|
||||
|
||||
|
||||
//This should really be somewhere else but I don't know where. w/e
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/obj/item/stack/spacecash
|
||||
name = "1 Credit"
|
||||
desc = "Money money money."
|
||||
icon = 'icons/goonstation/objects/money.dmi'
|
||||
icon_state = "cashgreen"
|
||||
icon = 'icons/obj/money.dmi'
|
||||
icon_state = "cash"
|
||||
hitsound = "swing_hit"
|
||||
force = 1
|
||||
throwforce = 1
|
||||
@@ -38,18 +38,18 @@
|
||||
|
||||
/obj/item/stack/spacecash/update_icon_state()
|
||||
name = "[amount] Credit[amount > 1 ? "s" : ""]"
|
||||
if(amount >= 1 && amount < 10)
|
||||
icon_state = "cashgreen"
|
||||
else if(amount >= 10 && amount < 50)
|
||||
icon_state = "spacecash"
|
||||
else if(amount >= 50 && amount < 500)
|
||||
icon_state = "cashblue"
|
||||
if(amount >= 1 && amount < 50)
|
||||
icon_state = "cash"
|
||||
else if(amount >= 50 && amount < 100)
|
||||
icon_state = "cash2"
|
||||
else if(amount >= 100 && amount < 500)
|
||||
icon_state = "cash3"
|
||||
else if(amount >= 500 && amount < 1000)
|
||||
icon_state = "cashindi"
|
||||
else if(amount >= 1000 && amount <= 10000)
|
||||
icon_state = "cashpurp"
|
||||
icon_state = "cash4"
|
||||
else if(amount >= 1000 && amount < 10000)
|
||||
icon_state = "cash5"
|
||||
else
|
||||
icon_state = "cashrbow"
|
||||
icon_state = "cash6"
|
||||
|
||||
/obj/item/stack/spacecash/c5
|
||||
amount = 5
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
if(r)
|
||||
r.droplimb(0, DROPLIMB_SHARP)
|
||||
|
||||
/obj/item/stack/cyborg_mine //Malf module
|
||||
/obj/item/stack/caution/proximity_sign/malf //Malf module
|
||||
name = "proximity mine dispenser"
|
||||
icon = 'icons/obj/janitor.dmi'
|
||||
icon_state = "caution"
|
||||
|
||||
@@ -63,25 +63,25 @@
|
||||
det_time = newtime
|
||||
to_chat(user, "Timer set for [det_time] seconds.")
|
||||
|
||||
/obj/item/grenade/plastic/afterattack(atom/movable/AM, mob/user, flag)
|
||||
/obj/item/grenade/plastic/afterattack(mob/AM, mob/user, flag)
|
||||
if(!flag)
|
||||
return
|
||||
if(iscarbon(AM))
|
||||
to_chat(user, "<span class='warning'>You can't get the [src] to stick to [AM]!</span>")
|
||||
if(ismob(AM) && AM.stat == CONSCIOUS)
|
||||
to_chat(user, "<span class='warning'>You can't get the [src] to stick to [AM]! Perhaps if [AM] was asleep or dead you could attach it?</span>")
|
||||
return
|
||||
if(isobserver(AM))
|
||||
to_chat(user, "<span class='warning'>Your hand just phases through [AM]!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You start planting [src].[isnull(nadeassembly) ? " The timer is set to [det_time]..." : ""]</span>")
|
||||
|
||||
if(do_after(user, 50 * toolspeed, target = AM))
|
||||
if(do_after(user, 5 SECONDS * toolspeed, target = AM))
|
||||
if(!user.unEquip(src))
|
||||
return
|
||||
target = AM
|
||||
loc = null
|
||||
|
||||
if(notify_admins)
|
||||
message_admins("[ADMIN_LOOKUPFLW(user)] planted [src.name] on [target.name] at ([target.x],[target.y],[target.z] - <a href='byond://?_src_=holder;adminplayerobservecoodjump=1;X=[target.x];Y=[target.y];Z=[target.z]'>JMP</a>) with [det_time] second fuse", 0, 1)
|
||||
message_admins("[ADMIN_LOOKUPFLW(user)] planted [name] on [target.name] at ([target.x],[target.y],[target.z] - <a href='byond://?_src_=holder;adminplayerobservecoodjump=1;X=[target.x];Y=[target.y];Z=[target.z]'>JMP</a>) with [det_time] second fuse", 0, 1)
|
||||
log_game("[key_name(user)] planted [name] on [target.name] at ([target.x],[target.y],[target.z]) with [det_time] second fuse")
|
||||
|
||||
AddComponent(/datum/component/persistent_overlay, image_overlay, target)
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
/obj/item/storage/backpack/clown/syndie/populate_contents()
|
||||
new /obj/item/clothing/under/rank/civilian/clown(src)
|
||||
new /obj/item/clothing/shoes/magboots/clown(src)
|
||||
new /obj/item/clothing/mask/chameleon(src)
|
||||
new /obj/item/clothing/mask/chameleon/voice_change(src)
|
||||
new /obj/item/radio/headset/headset_service(src)
|
||||
new /obj/item/pda/clown(src)
|
||||
new /obj/item/storage/box/survival(src)
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
storage_slots = 30
|
||||
max_combined_w_class = 30
|
||||
can_hold = list() // any
|
||||
cant_hold = list(/obj/item/disk/nuclear)
|
||||
cant_hold = list(/obj/item/disk/nuclear, /obj/item/grown/bananapeel/traitorpeel)
|
||||
|
||||
/obj/item/storage/bag/trash/proc/update_weight()
|
||||
if(!length(contents))
|
||||
@@ -213,6 +213,7 @@
|
||||
/obj/item/grown,
|
||||
/obj/item/food/snacks/grown/ash_flora,
|
||||
/obj/item/food/snacks/honeycomb)
|
||||
cant_hold = list(/obj/item/grown/bananapeel/traitorpeel)
|
||||
resistance_flags = FLAMMABLE
|
||||
|
||||
/obj/item/storage/bag/plants/portaseeder
|
||||
|
||||
@@ -144,7 +144,7 @@
|
||||
/obj/item/clothing/gloves/combat, // accounted in belt + toolbox
|
||||
/obj/item/flashlight/emp) // 4TC
|
||||
|
||||
/// 168TC + Telekinesis
|
||||
/// 170TC + Telekinesis
|
||||
/obj/item/storage/box/syndie_kit/bundle/darklord
|
||||
name = "Dark Lord Bundle"
|
||||
desc = "Turn your anger into hate and your hate into suffering with a mix of energy swords and magical powers. DO IT."
|
||||
@@ -155,7 +155,7 @@
|
||||
/obj/item/dnainjector/telemut/darkbundle, // ?TC
|
||||
/obj/item/clothing/suit/hooded/chaplain_hoodie, // 0TC
|
||||
/obj/item/clothing/glasses/meson/engine/tray, // 0TC
|
||||
/obj/item/clothing/mask/chameleon, // 8TC
|
||||
/obj/item/clothing/mask/chameleon/voice_change, // 10TC
|
||||
/obj/item/card/id/syndicate, // 10TC
|
||||
/obj/item/clothing/shoes/chameleon/noslip, // 10TC
|
||||
/obj/item/encryptionkey/syndicate) // 10TC
|
||||
@@ -403,11 +403,26 @@
|
||||
new /obj/item/clothing/shoes/chameleon(src)
|
||||
new /obj/item/clothing/glasses/chameleon(src)
|
||||
new /obj/item/clothing/head/chameleon(src)
|
||||
new /obj/item/clothing/mask/chameleon(src)
|
||||
new /obj/item/storage/backpack/chameleon(src)
|
||||
new /obj/item/radio/headset/chameleon(src)
|
||||
new /obj/item/stamp/chameleon(src)
|
||||
new /obj/item/pda/chameleon(src)
|
||||
new /obj/item/clothing/mask/chameleon(src)
|
||||
|
||||
/obj/item/storage/box/syndie_kit/chameleon/nuke
|
||||
name = "operative's chameleon kit"
|
||||
|
||||
/obj/item/storage/box/syndie_kit/chameleon/nuke/populate_contents()
|
||||
new /obj/item/clothing/under/chameleon(src)
|
||||
new /obj/item/clothing/suit/chameleon(src)
|
||||
new /obj/item/clothing/gloves/chameleon(src)
|
||||
new /obj/item/clothing/shoes/chameleon(src)
|
||||
new /obj/item/clothing/glasses/chameleon(src)
|
||||
new /obj/item/clothing/head/chameleon(src)
|
||||
new /obj/item/storage/backpack/chameleon(src)
|
||||
new /obj/item/radio/headset/chameleon(src)
|
||||
new /obj/item/pda/chameleon(src)
|
||||
new /obj/item/stamp/chameleon(src)
|
||||
new /obj/item/clothing/mask/chameleon/voice_change(src)
|
||||
|
||||
/obj/item/storage/box/syndie_kit/dart_gun
|
||||
name = "dart gun kit"
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
var/metalUsed = 2 //used to determine amount returned in deconstruction
|
||||
var/metal_type = /obj/item/stack/sheet/metal
|
||||
|
||||
/obj/structure/girder/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/debris, DEBRIS_SPARKS, -20, 10)
|
||||
|
||||
/obj/structure/girder/examine(mob/user)
|
||||
. = ..()
|
||||
switch(state)
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
. = ..()
|
||||
initial_state = icon_state
|
||||
air_update_turf(1)
|
||||
AddComponent(/datum/component/debris, DEBRIS_SPARKS, -20, 10)
|
||||
|
||||
/obj/structure/mineral_door/Destroy()
|
||||
density = FALSE
|
||||
@@ -211,3 +212,7 @@
|
||||
resistance_flags = FLAMMABLE
|
||||
max_integrity = 200
|
||||
rad_insulation = RAD_VERY_LIGHT_INSULATION
|
||||
|
||||
/obj/structure/mineral_door/wood/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/debris, DEBRIS_WOOD, -20, 10)
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
var/turf/T = get_step(src, dir)
|
||||
if(istype(T, /turf/simulated/mineral/random))
|
||||
Spread(T)
|
||||
AddComponent(/datum/component/debris, DEBRIS_ROCK, -20, 10, 1)
|
||||
|
||||
/turf/simulated/mineral/proc/Spread(turf/T)
|
||||
T.ChangeTurf(type)
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
underlay_appearance.icon_state = fixed_underlay["icon_state"]
|
||||
fixed_underlay = string_assoc_list(fixed_underlay)
|
||||
underlays += underlay_appearance
|
||||
AddComponent(/datum/component/debris, DEBRIS_SPARKS, -20, 10, 1)
|
||||
|
||||
/turf/simulated/wall/BeforeChange()
|
||||
for(var/obj/effect/overlay/wall_rot/WR in src)
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
name = "mineral wall"
|
||||
desc = "This shouldn't exist"
|
||||
icon_state = ""
|
||||
var/last_event = 0
|
||||
var/active = FALSE
|
||||
smoothing_flags = SMOOTH_BITMASK
|
||||
canSmoothWith = null
|
||||
var/last_event = 0
|
||||
var/active = FALSE
|
||||
|
||||
/turf/simulated/wall/mineral/shuttleRotate(rotation)
|
||||
return //This override is needed to properly rotate the object when on a shuttle that is rotated.
|
||||
|
||||
@@ -104,12 +104,8 @@
|
||||
if(handle_spam_prevention(msg, MUTE_ADMINHELP, OOC_COOLDOWN))
|
||||
return
|
||||
|
||||
//clean the message if it's not sent by a high-rank admin
|
||||
if(!check_rights(R_SERVER|R_DEBUG,0))
|
||||
msg = sanitize_simple(copytext_char(msg, 1, MAX_MESSAGE_LEN))
|
||||
if(!msg)
|
||||
return
|
||||
else
|
||||
// Let high-rank admins use advanced pencode.
|
||||
if(check_rights(R_SERVER|R_DEBUG, 0))
|
||||
msg = admin_pencode_to_html(msg)
|
||||
|
||||
var/send_span
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
venom_per_bite = 3
|
||||
speak_chance = 0
|
||||
wander = 0
|
||||
gold_core_spawnable = NO_SPAWN
|
||||
/// To check and gib the spider when dead, then remove only one of the counter for the changeling owner
|
||||
var/gibbed = FALSE
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
new /obj/item/clothing/under/chameleon(src)
|
||||
new /obj/item/clothing/suit/chameleon(src)
|
||||
new /obj/item/clothing/head/chameleon(src)
|
||||
new /obj/item/clothing/mask/chameleon(src)
|
||||
new /obj/item/clothing/mask/chameleon/voice_change(src)
|
||||
new /obj/item/card/id/syndicate(src)
|
||||
new /obj/item/storage/fancy/cigarettes/cigpack_syndicate(src)
|
||||
new /obj/item/lighter/zippo(src)
|
||||
|
||||
@@ -228,7 +228,7 @@ RESTRICT_TYPE(/datum/antagonist/vampire)
|
||||
return
|
||||
if(bloodusable >= 10) //burn through your blood to tank the light for a little while
|
||||
to_chat(owner.current, "<span class='warning'>The starlight saps your strength!</span>")
|
||||
bloodusable -= 10
|
||||
subtract_usable_blood(10)
|
||||
vamp_burn(10)
|
||||
else //You're in trouble, get out of the sun NOW
|
||||
to_chat(owner.current, "<span class='userdanger'>Your body is turning to ash, get out of the light now!</span>")
|
||||
@@ -278,6 +278,13 @@ RESTRICT_TYPE(/datum/antagonist/vampire)
|
||||
REMOVE_TRAIT(owner.current, TRAIT_GOTTAGONOTSOFAST, VAMPIRE_TRAIT)
|
||||
owner.current.alpha = 204 // 255 * 0.80
|
||||
|
||||
/**
|
||||
* Handles unique drain ID checks and increases vampire's total and usable blood by blood_amount. Checks for ability upgrades.
|
||||
*
|
||||
* Arguments:
|
||||
** C: victim [/mob/living/carbon] that is being drained form.
|
||||
** blood_amount: amount of blood to add to vampire's usable and total pools.
|
||||
*/
|
||||
/datum/antagonist/vampire/proc/adjust_blood(mob/living/carbon/C, blood_amount = 0)
|
||||
if(C)
|
||||
var/unique_suck_id = C.UID()
|
||||
@@ -293,6 +300,15 @@ RESTRICT_TYPE(/datum/antagonist/vampire)
|
||||
if(S.action)
|
||||
S.action.UpdateButtons()
|
||||
|
||||
/**
|
||||
* Safely subtract vampire's bloodusable. Clamped between 0 and bloodtotal.
|
||||
*
|
||||
* Arguments:
|
||||
** blood_amount: amount of blood to subtract.
|
||||
*/
|
||||
/datum/antagonist/vampire/proc/subtract_usable_blood(blood_amount)
|
||||
bloodusable = clamp(bloodusable - blood_amount, 0, bloodtotal)
|
||||
|
||||
/datum/antagonist/vampire/proc/vamp_burn(burn_chance)
|
||||
if(prob(burn_chance) && owner.current.health >= 50)
|
||||
switch(owner.current.health)
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
handle_enthrall(user, target)
|
||||
var/datum/spell_handler/vampire/V = custom_handler
|
||||
var/blood_cost = V.calculate_blood_cost(vampire)
|
||||
vampire.bloodusable -= blood_cost //we take the blood after enthralling, not before
|
||||
vampire.subtract_usable_blood(blood_cost) //we take the blood after enthralling, not before
|
||||
else
|
||||
revert_cast(user)
|
||||
to_chat(user, "<span class='warning'>You or your target moved.</span>")
|
||||
|
||||
@@ -199,7 +199,7 @@
|
||||
var/datum/spell_handler/vampire/V = custom_handler
|
||||
var/datum/antagonist/vampire/vampire = user.mind.has_antag_datum(/datum/antagonist/vampire)
|
||||
var/blood_cost = V.calculate_blood_cost(vampire)
|
||||
vampire.bloodusable -= blood_cost
|
||||
vampire.subtract_usable_blood(blood_cost)
|
||||
start_turf = null
|
||||
should_recharge_after_cast = FALSE
|
||||
|
||||
|
||||
@@ -181,7 +181,7 @@
|
||||
var/datum/spell_handler/vampire/V = custom_handler
|
||||
var/datum/antagonist/vampire/vampire = user.mind.has_antag_datum(/datum/antagonist/vampire)
|
||||
var/blood_cost = V.calculate_blood_cost(vampire)
|
||||
vampire.bloodusable = clamp(vampire.bloodusable - blood_cost, 0, vampire.bloodusable)// Vampires get a coupon if they have less than the normal blood cost
|
||||
vampire.subtract_usable_blood(blood_cost)// Vampires get a coupon if they have less than the normal blood cost
|
||||
|
||||
/proc/shadow_to_animation(turf/start_turf, turf/end_turf, mob/user)
|
||||
var/x_difference = end_turf.x - start_turf.x
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
if(listening)
|
||||
if(findtext(msg, "</span>"))
|
||||
recorded = strip_html_properly(msg)
|
||||
recorded = strip_html_tags(msg)
|
||||
else
|
||||
recorded = msg
|
||||
recorded_type = type
|
||||
|
||||
@@ -1230,6 +1230,18 @@
|
||||
if("Set-Tab")
|
||||
stat_tab = payload["tab"]
|
||||
SSstatpanels.immediate_send_stat_data(src)
|
||||
if("Listedturf-Scroll")
|
||||
if(payload["min"] == payload["max"])
|
||||
// Not properly loaded yet, send the default set.
|
||||
SSstatpanels.refresh_client_obj_view(src)
|
||||
else
|
||||
SSstatpanels.refresh_client_obj_view(src, payload["min"], payload["max"])
|
||||
// Uncomment to enable log_debug in stat panel code.
|
||||
// Disabled normally due to HREF exploit concerns.
|
||||
//if("Statpanel-Debug")
|
||||
// log_debug(payload)
|
||||
if("Resend-Asset")
|
||||
SSassets.transport.send_assets(src, list(payload))
|
||||
if("Debug-Stat-Entry")
|
||||
var/stat_item = locateUID(payload["stat_item_uid"])
|
||||
if(!check_rights(R_DEBUG | R_VIEWRUNTIMES) || !stat_item)
|
||||
|
||||
@@ -301,7 +301,7 @@
|
||||
disable_message = "You will no longer see runechat."
|
||||
blackbox_message = "Toggle Runechat"
|
||||
|
||||
/datum/preference_toggle/toggle_runechat
|
||||
/datum/preference_toggle/toggle_ghost_death_notifs
|
||||
name = "Toggle Ghost Death Notifications"
|
||||
description = "Toggle a notification when a player dies"
|
||||
preftoggle_bitflag = PREFTOGGLE_2_DEATHMESSAGE
|
||||
|
||||
@@ -469,8 +469,6 @@
|
||||
"Grey" = 'icons/mob/clothing/species/grey/mask.dmi'
|
||||
)
|
||||
|
||||
var/obj/item/voice_changer/voice_changer
|
||||
|
||||
var/datum/action/item_action/chameleon/change/chameleon_action
|
||||
|
||||
/obj/item/clothing/mask/chameleon/Initialize(mapload)
|
||||
@@ -482,10 +480,7 @@
|
||||
chameleon_action.chameleon_blacklist = list()
|
||||
chameleon_action.initialize_disguises()
|
||||
|
||||
voice_changer = new(src)
|
||||
|
||||
/obj/item/clothing/mask/chameleon/Destroy()
|
||||
QDEL_NULL(voice_changer)
|
||||
QDEL_NULL(chameleon_action)
|
||||
return ..()
|
||||
|
||||
@@ -497,6 +492,23 @@
|
||||
. = ..()
|
||||
chameleon_action.emp_randomise(INFINITY)
|
||||
|
||||
/obj/item/clothing/mask/chameleon/voice_change
|
||||
name = "gas mask"
|
||||
desc = "A face-covering mask that can be connected to an air supply. While good for concealing your identity, it isn't good for blocking gas flow."
|
||||
icon_state = "swat"
|
||||
item_state = "swat"
|
||||
|
||||
var/obj/item/voice_changer/voice_changer
|
||||
|
||||
/obj/item/clothing/mask/chameleon/voice_change/Destroy()
|
||||
QDEL_NULL(voice_changer)
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/mask/chameleon/voice_change/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
voice_changer = new(src)
|
||||
|
||||
/obj/item/clothing/shoes/chameleon
|
||||
name = "black shoes"
|
||||
icon_state = "black"
|
||||
|
||||
@@ -124,12 +124,6 @@
|
||||
cost = 500
|
||||
category = MERCH_CAT_TOY
|
||||
|
||||
/datum/merch_item/baby
|
||||
name = "Toddler"
|
||||
desc = "This baby looks almost real. Wait, did it just burp?"
|
||||
typepath = /obj/item/toddler
|
||||
cost = 500
|
||||
category = MERCH_CAT_TOY
|
||||
|
||||
/datum/merch_item/flag_slime
|
||||
name = "Slime People Flag"
|
||||
|
||||
@@ -38,6 +38,8 @@
|
||||
|
||||
/obj/structure/blob/core/Destroy()
|
||||
if(overmind)
|
||||
if(overmind.mind)
|
||||
SSticker.mode.blob_overminds -= overmind.mind
|
||||
overmind.blob_core = null
|
||||
overmind = null
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
status_tab_data[++status_tab_data.len] = list("Power Stored:", "[blob_points]/[max_blob_points]")
|
||||
|
||||
/mob/camera/blob/Move(NewLoc, Dir = 0)
|
||||
var/obj/structure/blob/B = locate() in range("3x3", NewLoc)
|
||||
var/obj/structure/blob/B = locate() in range(3, NewLoc)
|
||||
if(B)
|
||||
loc = NewLoc
|
||||
else
|
||||
|
||||
@@ -141,7 +141,7 @@ GLOBAL_LIST_EMPTY(event_last_fired)
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Mundane News", /datum/event/mundane_news, 300),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Vermin Infestation",/datum/event/infestation, 100, list(ASSIGNMENT_JANITOR = 100)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Sentience", /datum/event/sentience, 50),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Wallrot", /datum/event/wallrot, 0, list(ASSIGNMENT_ENGINEER = 30, ASSIGNMENT_GARDENER = 50)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Wallrot", /datum/event/wallrot, 0, list(ASSIGNMENT_ENGINEER = 30)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Fungal Growth", /datum/event/wallrot/fungus, 50, list(ASSIGNMENT_CHEMIST = 50)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Koi School", /datum/event/carp_migration/koi, 80),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Camera Failure", /datum/event/camera_failure, 100, list(ASSIGNMENT_ENGINEER = 10)),
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
active_with_role["Cyborg"] = 0
|
||||
active_with_role["Janitor"] = 0
|
||||
active_with_role["Botanist"] = 0
|
||||
active_with_role["Chemist"] = 0
|
||||
active_with_role["Any"] = length(GLOB.player_list)
|
||||
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
@@ -105,6 +106,9 @@
|
||||
if(M.mind.assigned_role == "Botanist")
|
||||
active_with_role["Botanist"]++
|
||||
|
||||
if(M.mind.assigned_role == "Chemist")
|
||||
active_with_role["Chemist"]++
|
||||
|
||||
return active_with_role
|
||||
|
||||
/datum/event/proc/num_players()
|
||||
|
||||
@@ -27,9 +27,9 @@ GLOBAL_LIST_INIT(unused_trade_stations, list("sol"))
|
||||
/datum/traders/nian)
|
||||
|
||||
if(SSsecurity_level.get_current_level_as_number() >= SEC_LEVEL_RED)
|
||||
GLOB.minor_announcement.Announce("A trading shuttle from [T.trader_location] has been denied docking permission due to the heightened security alert aboard [station_name()].", "Trader Shuttle Docking Request Refused")
|
||||
GLOB.minor_announcement.Announce("A trading shuttle from [T.trader_location] has been denied docking permission due to the heightened security alert aboard [station_name()].", "Trader Shuttle Docking Request Refused", 'sound/AI/traderdeny.ogg')
|
||||
return
|
||||
GLOB.minor_announcement.Announce("A trading shuttle from [T.trader_location] has been granted docking permission at [station_name()] arrivals port 4.", "Trader Shuttle Docking Request Accepted")
|
||||
GLOB.minor_announcement.Announce("A trading shuttle from [T.trader_location] has been granted docking permission at [station_name()] arrivals port 4.", "Trader Shuttle Docking Request Accepted", 'sound/AI/tradergranted.ogg')
|
||||
|
||||
|
||||
/datum/event/traders/start()
|
||||
@@ -48,7 +48,7 @@ GLOBAL_LIST_INIT(unused_trade_stations, list("sol"))
|
||||
/datum/traders/nian)
|
||||
|
||||
if(SSsecurity_level.get_current_level_as_number() >= SEC_LEVEL_RED)
|
||||
GLOB.minor_announcement.Announce("A trading shuttle from [T.trader_location] has been denied docking permission due to the heightened security alert aboard [station_name()].", "Trader Shuttle Docking Request Refused")
|
||||
GLOB.minor_announcement.Announce("A trading shuttle from [T.trader_location] has been denied docking permission due to the heightened security alert aboard [station_name()].", "Trader Shuttle Docking Request Refused", 'sound/AI/traderdeny.ogg')
|
||||
// if the docking request was refused, fire another major event in 60 seconds
|
||||
var/datum/event_container/EC = SSevents.event_containers[EVENT_LEVEL_MAJOR]
|
||||
EC.next_event_time = world.time + (60 * 10)
|
||||
@@ -102,7 +102,7 @@ GLOBAL_LIST_INIT(unused_trade_stations, list("sol"))
|
||||
greet_trader(M, T)
|
||||
success_spawn = TRUE
|
||||
if(success_spawn)
|
||||
GLOB.minor_announcement.Announce("A trading shuttle from [T.trader_location] has been granted docking permission at [station_name()] arrivals port 4.", "Trader Shuttle Docking Request Accepted")
|
||||
GLOB.minor_announcement.Announce("A trading shuttle from [T.trader_location] has been granted docking permission at [station_name()] arrivals port 4.", "Trader Shuttle Docking Request Accepted", 'sound/AI/tradergranted.ogg')
|
||||
else
|
||||
GLOB.unused_trade_stations += station // Return the station to the list of usable stations.
|
||||
|
||||
|
||||
@@ -135,35 +135,43 @@
|
||||
// Middle Eastern //
|
||||
//////////////////////
|
||||
|
||||
/obj/item/food/snacks/human/kabob
|
||||
name = "-kabob"
|
||||
icon_state = "kabob"
|
||||
desc = "Human meat, on a stick."
|
||||
trash = /obj/item/stack/rods
|
||||
filling_color = "#A85340"
|
||||
list_reagents = list("nutriment" = 8)
|
||||
|
||||
/obj/item/food/snacks/monkeykabob
|
||||
name = "meat-kabob"
|
||||
icon_state = "kabob"
|
||||
/obj/item/food/snacks/meatkebab
|
||||
name = "meat-kebab"
|
||||
desc = "Delicious meat, on a stick."
|
||||
icon_state = "kebab"
|
||||
trash = /obj/item/stack/rods
|
||||
filling_color = "#A85340"
|
||||
list_reagents = list("nutriment" = 8)
|
||||
goal_difficulty = FOOD_GOAL_NORMAL
|
||||
|
||||
/obj/item/food/snacks/tofukabob
|
||||
name = "tofu-kabob"
|
||||
icon_state = "kabob"
|
||||
/obj/item/food/snacks/syntikebab
|
||||
name = "synthimeat-kebab"
|
||||
desc = "Delicious synthetic meat, on a stick."
|
||||
icon_state = "kebab"
|
||||
trash = /obj/item/stack/rods
|
||||
filling_color = "#A85340"
|
||||
list_reagents = list("nutriment" = 8)
|
||||
|
||||
/obj/item/food/snacks/human/kebab
|
||||
name = "-kebab"
|
||||
desc = "Human meat, on a stick."
|
||||
icon_state = "kebab"
|
||||
trash = /obj/item/stack/rods
|
||||
filling_color = "#A85340"
|
||||
list_reagents = list("nutriment" = 8)
|
||||
|
||||
/obj/item/food/snacks/tofukebab
|
||||
name = "tofu-kebab"
|
||||
desc = "Vegan meat, on a stick."
|
||||
icon_state = "kebab"
|
||||
trash = /obj/item/stack/rods
|
||||
filling_color = "#FFFEE0"
|
||||
list_reagents = list("nutriment" = 8)
|
||||
goal_difficulty = FOOD_GOAL_NORMAL
|
||||
|
||||
/obj/item/food/snacks/picoss_kabob
|
||||
name = "picoss-kabob"
|
||||
desc = "A popular Moghes streetfood consisting of vinegar-marinated space carp on a skewer with onion and chillis."
|
||||
/obj/item/food/snacks/picoss_kebab
|
||||
name = "picoss-kebab"
|
||||
desc = "A popular Moghes street food consisting of vinegar-marinated space carp on a skewer with onion and chillis."
|
||||
icon_state = "picoss_skewer"
|
||||
trash = /obj/item/stack/rods
|
||||
list_reagents = list("protein" = 8, "vitamin" = 4, "vinegar" = 1, "capsaicin" = 1)
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
reagents = list("psilocybin" = 5, "sugar" = 10)
|
||||
items = list(
|
||||
/obj/item/food/snacks/dough,
|
||||
/obj/item/food/snacks/dough,
|
||||
/obj/item/food/snacks/dough
|
||||
)
|
||||
result = /obj/item/food/snacks/rofflewaffles
|
||||
|
||||
@@ -77,14 +77,14 @@
|
||||
items = list(
|
||||
/obj/item/food/snacks/breadslice,
|
||||
/obj/item/food/snacks/breadslice,
|
||||
/obj/item/food/snacks/cheesewedge,
|
||||
/obj/item/food/snacks/cheesewedge
|
||||
)
|
||||
result = /obj/item/food/snacks/grilledcheese
|
||||
|
||||
/datum/recipe/grill/sausage
|
||||
items = list(
|
||||
/obj/item/food/snacks/meatball,
|
||||
/obj/item/food/snacks/cutlet,
|
||||
/obj/item/food/snacks/cutlet
|
||||
)
|
||||
result = /obj/item/food/snacks/sausage
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
reagents = list("flour" = 10)
|
||||
items = list(
|
||||
/obj/item/food/snacks/egg,
|
||||
/obj/item/food/snacks/carpmeat,
|
||||
/obj/item/food/snacks/carpmeat
|
||||
)
|
||||
result = /obj/item/food/snacks/fishfingers
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
/obj/item/food/snacks/egg,
|
||||
/obj/item/food/snacks/egg,
|
||||
/obj/item/food/snacks/cheesewedge,
|
||||
/obj/item/food/snacks/cheesewedge,
|
||||
/obj/item/food/snacks/cheesewedge
|
||||
)
|
||||
result = /obj/item/food/snacks/omelette
|
||||
|
||||
@@ -124,39 +124,39 @@
|
||||
)
|
||||
result = /obj/item/food/snacks/wingfangchu
|
||||
|
||||
/datum/recipe/grill/human/kabob
|
||||
/datum/recipe/grill/human/kebab
|
||||
items = list(
|
||||
/obj/item/stack/rods,
|
||||
/obj/item/food/snacks/meat/human,
|
||||
/obj/item/food/snacks/meat/human,
|
||||
/obj/item/food/snacks/meat/human
|
||||
)
|
||||
result = /obj/item/food/snacks/human/kabob
|
||||
result = /obj/item/food/snacks/human/kebab
|
||||
|
||||
/datum/recipe/grill/monkeykabob
|
||||
items = list(
|
||||
/obj/item/stack/rods,
|
||||
/obj/item/food/snacks/meat/monkey,
|
||||
/obj/item/food/snacks/meat/monkey,
|
||||
)
|
||||
result = /obj/item/food/snacks/monkeykabob
|
||||
|
||||
/datum/recipe/grill/syntikabob
|
||||
/datum/recipe/grill/syntikebab
|
||||
items = list(
|
||||
/obj/item/stack/rods,
|
||||
/obj/item/food/snacks/meat/syntiflesh,
|
||||
/obj/item/food/snacks/meat/syntiflesh,
|
||||
/obj/item/food/snacks/meat/syntiflesh
|
||||
)
|
||||
result = /obj/item/food/snacks/monkeykabob
|
||||
result = /obj/item/food/snacks/syntikebab
|
||||
|
||||
/datum/recipe/grill/tofukabob
|
||||
/datum/recipe/grill/meatkeb // Do not put this above the other meat kebab variants or it will override them.
|
||||
items = list(
|
||||
/obj/item/stack/rods,
|
||||
/obj/item/food/snacks/meat,
|
||||
/obj/item/food/snacks/meat
|
||||
)
|
||||
result = /obj/item/food/snacks/meatkebab
|
||||
|
||||
/datum/recipe/grill/tofukebab
|
||||
items = list(
|
||||
/obj/item/stack/rods,
|
||||
/obj/item/food/snacks/tofu,
|
||||
/obj/item/food/snacks/tofu,
|
||||
/obj/item/food/snacks/tofu
|
||||
)
|
||||
result = /obj/item/food/snacks/tofukabob
|
||||
result = /obj/item/food/snacks/tofukebab
|
||||
|
||||
/datum/recipe/grill/picoss_kabob
|
||||
/datum/recipe/grill/picoss_kebab
|
||||
reagents = list("vinegar" = 5)
|
||||
items = list(
|
||||
/obj/item/food/snacks/carpmeat,
|
||||
@@ -165,10 +165,10 @@
|
||||
/obj/item/food/snacks/grown/chili,
|
||||
/obj/item/stack/rods
|
||||
)
|
||||
result = /obj/item/food/snacks/picoss_kabob
|
||||
result = /obj/item/food/snacks/picoss_kebab
|
||||
|
||||
/datum/recipe/grill/picoss_kabob/make_food(obj/container)
|
||||
var/obj/item/food/snacks/picoss_kabob/being_cooked = ..()
|
||||
/datum/recipe/grill/picoss_kebab/make_food(obj/container)
|
||||
var/obj/item/food/snacks/picoss_kebab/being_cooked = ..()
|
||||
being_cooked.reagents.del_reagent("carpotoxin")
|
||||
return being_cooked
|
||||
|
||||
@@ -272,7 +272,7 @@
|
||||
/obj/item/food/snacks/shrimp,
|
||||
/obj/item/food/snacks/shrimp,
|
||||
/obj/item/food/snacks/shrimp,
|
||||
/obj/item/stack/rods,
|
||||
/obj/item/stack/rods
|
||||
)
|
||||
result = /obj/item/food/snacks/shrimp_skewer
|
||||
|
||||
@@ -281,7 +281,7 @@
|
||||
items = list(
|
||||
/obj/item/food/snacks/salmonmeat,
|
||||
/obj/item/food/snacks/salmonmeat,
|
||||
/obj/item/stack/rods,
|
||||
/obj/item/stack/rods
|
||||
)
|
||||
result = /obj/item/food/snacks/fish_skewer
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
/obj/structure/fermenting_barrel/Initialize()
|
||||
create_reagents(300) //Bluespace beakers, but without the portability or efficiency in circuits.
|
||||
AddComponent(/datum/component/debris, DEBRIS_WOOD, -20, 10)
|
||||
. = ..()
|
||||
|
||||
/obj/structure/fermenting_barrel/examine(mob/user)
|
||||
|
||||
@@ -205,9 +205,7 @@
|
||||
|
||||
add_attack_logs(user, target, "[what_done] ([reagent_str] | [genes_str])")
|
||||
|
||||
/obj/item/food/snacks/grown/extinguish_light(force = FALSE)
|
||||
if(!force)
|
||||
return
|
||||
/obj/item/food/snacks/grown/extinguish_light(force)
|
||||
if(seed.get_gene(/datum/plant_gene/trait/glow/shadow))
|
||||
return
|
||||
set_light(0)
|
||||
|
||||
@@ -315,6 +315,11 @@
|
||||
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/hydroponics/extinguish_light(force)
|
||||
if(!force)
|
||||
return
|
||||
set_light(0)
|
||||
|
||||
/obj/machinery/hydroponics/update_overlays()
|
||||
. = ..()
|
||||
if(self_sustaining && !istype(src, /obj/machinery/hydroponics/soil))
|
||||
|
||||
@@ -85,8 +85,6 @@
|
||||
desc = "Hostile Environment Cross-Kinetic Helmet: A helmet designed to withstand the wide variety of hazards from Lavaland. It wasn't enough for its last owner."
|
||||
icon_state = "hostile_env"
|
||||
item_state = "hostile_env"
|
||||
body_parts_covered = HEAD
|
||||
flags = BLOCKHAIR
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
|
||||
heat_protection = HEAD
|
||||
|
||||
@@ -167,6 +167,10 @@
|
||||
harvest_message_high = "You finish mining the rock."
|
||||
delete_on_harvest = TRUE
|
||||
|
||||
/obj/structure/flora/ash/rock/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/debris, DEBRIS_ROCK, -20, 10)
|
||||
|
||||
/obj/structure/flora/ash/rock/style_2
|
||||
icon_state = "basalt2"
|
||||
|
||||
|
||||
@@ -174,16 +174,16 @@
|
||||
/mob/proc/hear_sleep(message)
|
||||
var/heard = ""
|
||||
if(prob(15))
|
||||
message = strip_html_properly(message)
|
||||
message = html_decode(strip_html_tags(message))
|
||||
var/list/punctuation = list(",", "!", ".", ";", "?")
|
||||
var/list/messages = splittext(message, " ")
|
||||
if(length(messages) > 0)
|
||||
var/R = rand(1, length(messages))
|
||||
var/heardword = messages[R]
|
||||
if(copytext(heardword,1, 1) in punctuation)
|
||||
heardword = copytext(heardword,2)
|
||||
heardword = html_encode(copytext(heardword, 2))
|
||||
if(copytext(heardword,-1) in punctuation)
|
||||
heardword = copytext(heardword,1,length(heardword))
|
||||
heardword = html_encode(copytext(heardword, 1, length(heardword)))
|
||||
heard = "<span class='game say'>...<i>You hear something about<i>... '[heardword]'...</span>"
|
||||
else
|
||||
heard = "<span class='game say'>...<i>You almost hear something...</i>...</span>"
|
||||
|
||||
@@ -311,7 +311,7 @@ GLOBAL_LIST_EMPTY(channel_to_radio_key)
|
||||
return name
|
||||
|
||||
/mob/living/whisper(message as text)
|
||||
message = trim_strip_html_properly(message)
|
||||
message = trim_strip_html_tags(message)
|
||||
|
||||
//parse the language code and consume it
|
||||
var/list/message_pieces = parse_languages(message)
|
||||
|
||||
@@ -517,7 +517,7 @@
|
||||
)
|
||||
emag_override_modules = list(/obj/item/reagent_containers/spray/cyborg_lube)
|
||||
emag_modules = list(/obj/item/reagent_containers/spray/cyborg_facid, /obj/item/malfbroom)
|
||||
malf_modules = list(/obj/item/stack/cyborg_mine)
|
||||
malf_modules = list(/obj/item/stack/caution/proximity_sign/malf)
|
||||
special_rechargables = list(
|
||||
/obj/item/lightreplacer,
|
||||
/obj/item/reagent_containers/spray/cyborg_lube,
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
light_color = LIGHT_COLOR_LAVA
|
||||
projectiletype = /obj/item/projectile/temp/basilisk/magmawing
|
||||
crusher_loot = /obj/item/crusher_trophy/blaster_tubes/magma_wing
|
||||
crusher_drop_mod = 60
|
||||
crusher_drop_mod = 100 //These things are extremely rare (1/133 per spawner). You shouldn't have to hope for another stroke of luck to get it's trophy after finding it
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/icewing
|
||||
name = "icewing watcher"
|
||||
@@ -110,7 +110,7 @@
|
||||
projectiletype = /obj/item/projectile/temp/basilisk/icewing
|
||||
butcher_results = list(/obj/item/stack/ore/diamond = 5, /obj/item/stack/sheet/bone = 1) //No sinew; the wings are too fragile to be usable
|
||||
crusher_loot = /obj/item/crusher_trophy/watcher_wing/ice_wing
|
||||
crusher_drop_mod = 30
|
||||
crusher_drop_mod = 100 //These things are extremely rare (1/400 per spawner). You shouldn't have to hope for another stroke of luck to get it's trophy after finding it
|
||||
|
||||
/obj/item/projectile/temp/basilisk/magmawing
|
||||
name = "scorching blast"
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
loot = list(/obj/item/stack/sheet/animalhide/goliath_hide) //A throwback to the asteroid days
|
||||
butcher_results = list(/obj/item/food/snacks/monstermeat/goliath= 2, /obj/item/stack/sheet/bone = 2)
|
||||
crusher_loot = /obj/item/crusher_trophy/goliath_tentacle/ancient
|
||||
crusher_drop_mod = 30
|
||||
crusher_drop_mod = 100 //These things are rare (1/100 per spawner). You shouldn't have to hope for another stroke of luck to get it's trophy after finding it
|
||||
wander = FALSE
|
||||
var/list/cached_tentacle_turfs
|
||||
var/turf/last_location
|
||||
|
||||
@@ -185,9 +185,14 @@
|
||||
to_chat(src, "<span class='notice'>As you observed [period_human_readable], you can freely toggle antag-hud without losing respawnability.</span>")
|
||||
observer.started_as_observer = 1
|
||||
close_spawn_windows()
|
||||
var/obj/O = locate("landmark*Observer-Start")
|
||||
var/obj/spawn_point
|
||||
if(SSticker.current_state < GAME_STATE_PLAYING)
|
||||
spawn_point = pick(GLOB.roundstart_observer_start)
|
||||
else
|
||||
spawn_point = locate("landmark*Observer-Start")
|
||||
|
||||
to_chat(src, "<span class='notice'>Now teleporting.</span>")
|
||||
observer.forceMove(O.loc)
|
||||
observer.forceMove(get_turf(spawn_point))
|
||||
observer.timeofdeath = world.time // Set the time of death so that the respawn timer works correctly.
|
||||
client.prefs.active_character.update_preview_icon(1)
|
||||
observer.icon = client.prefs.active_character.preview_icon
|
||||
|
||||
@@ -200,7 +200,7 @@
|
||||
var/obj/item/paper/crumpled/P = new(loc)
|
||||
P.name = name
|
||||
if(info) // Something written on the paper.
|
||||
/*var/new_text = strip_html_properly(info, MAX_PAPER_MESSAGE_LEN, TRUE) // Don't want HTML stuff getting gibberished.
|
||||
/*var/new_text = strip_html_tags(info, MAX_PAPER_MESSAGE_LEN, TRUE) // Don't want HTML stuff getting gibberished.
|
||||
P.info = Gibberish(new_text, 100)*/
|
||||
P.info = "<i>Whatever was once written here has been made completely illegible by a combination of chew marks and saliva.</i>"
|
||||
message_ending = ", the drool making it an unreadable mess!"
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
|
||||
//WT550//
|
||||
/obj/item/gun/projectile/automatic/wt550
|
||||
name = "WT-550 PDW"
|
||||
name = "\improper WT-550 PDW"
|
||||
desc = "An outdated personal defense weapon utilized by law enforcement. Chambered in 4.6x30mm."
|
||||
icon_state = "wt550"
|
||||
item_state = "wt550"
|
||||
|
||||
@@ -1020,7 +1020,10 @@
|
||||
if(ishuman(M) && prob(5))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(!H.get_int_organ(/obj/item/organ/internal/bone_tumor))
|
||||
new/obj/item/organ/internal/bone_tumor(H)
|
||||
if(isslimeperson(H))
|
||||
new /obj/item/organ/internal/bone_tumor/slime_tumor(H)
|
||||
else
|
||||
new /obj/item/organ/internal/bone_tumor(H)
|
||||
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
GLOBAL_LIST_EMPTY(occupants_by_key)
|
||||
|
||||
/obj/effect/mob_spawn/human/alive/ghost_bar
|
||||
name = "ghastly rejuvenator"
|
||||
mob_name = "ghost bar occupant"
|
||||
@@ -83,6 +85,11 @@
|
||||
implant.insert(H)
|
||||
log_game("[ckey] has entered the ghost bar")
|
||||
playsound(src, 'sound/machines/wooden_closet_open.ogg', 50)
|
||||
var/mob/old_mob = GLOB.occupants_by_key["[H.ckey]"]
|
||||
if(old_mob)
|
||||
qdel(old_mob)
|
||||
GLOB.occupants_by_key["[H.ckey]"] = H
|
||||
RegisterSignal(H, COMSIG_PARENT_QDELETING, PROC_REF(clear_references_to_owner))
|
||||
|
||||
/obj/effect/mob_spawn/human/alive/ghost_bar/proc/equip_item(mob/living/carbon/human/H, path, slot)
|
||||
var/obj/item/I = new path(H)
|
||||
@@ -90,6 +97,10 @@
|
||||
H.speaks_ooc = TRUE
|
||||
return I
|
||||
|
||||
/obj/effect/mob_spawn/human/alive/ghost_bar/proc/clear_references_to_owner(mob/mob_to_obliterate)
|
||||
SIGNAL_HANDLER // COMSIG_PARENT_QDELETING
|
||||
GLOB.occupants_by_key -= mob_to_obliterate.ckey
|
||||
|
||||
/obj/structure/ghost_bar_cryopod
|
||||
name = "returning sarcophagus"
|
||||
desc = "Returns you back to the world of the dead."
|
||||
|
||||
@@ -177,11 +177,11 @@
|
||||
return CARGO_PREVENT_SHUTTLE
|
||||
var/sellable = SEND_SIGNAL(src, COMSIG_CARGO_CHECK_SELL, AM)
|
||||
manifest.items_to_sell[AM] = sellable
|
||||
if(top_level && !(sellable & COMSIG_CARGO_IS_SECURED))
|
||||
manifest.loose_cargo = TRUE
|
||||
if(sellable & COMSIG_CARGO_SELL_PRIORITY)
|
||||
if(top_level)
|
||||
return CARGO_OK
|
||||
if(top_level)
|
||||
if(!AM.anchored && !(sellable & COMSIG_CARGO_IS_SECURED))
|
||||
manifest.loose_cargo = TRUE
|
||||
return CARGO_OK
|
||||
if(found_priority || sellable & COMSIG_CARGO_SELL_PRIORITY)
|
||||
return CARGO_HAS_PRIORITY
|
||||
|
||||
return CARGO_OK
|
||||
@@ -220,9 +220,6 @@
|
||||
if(E.is_cleanable())
|
||||
return CARGO_OK
|
||||
|
||||
if(AM.anchored && !istype(AM, /obj/mecha/working))
|
||||
return CARGO_SKIP_ATOM
|
||||
|
||||
return CARGO_OK
|
||||
|
||||
|
||||
@@ -253,7 +250,7 @@
|
||||
SSeconomy.sold_atoms += "[AM.name](mess)"
|
||||
qdel_atoms += AM
|
||||
continue
|
||||
else if(!(sellable & COMSIG_CARGO_SELL_SKIP))
|
||||
else if(!AM.anchored && !(sellable & COMSIG_CARGO_SELL_SKIP))
|
||||
manifest.sent_trash = TRUE
|
||||
|
||||
rescue_atoms += AM
|
||||
@@ -784,7 +781,7 @@
|
||||
|
||||
/datum/economy/simple_seller/mechs/check_sell(obj/docking_port/mobile/supply/S, atom/movable/AM)
|
||||
if(istype(AM, /obj/mecha/working))
|
||||
return COMSIG_CARGO_SELL_NORMAL | COMSIG_CARGO_IS_SECURED
|
||||
return COMSIG_CARGO_SELL_NORMAL
|
||||
|
||||
|
||||
// Skip mech parts to avoid complaining about them.
|
||||
|
||||
@@ -67,16 +67,11 @@
|
||||
return copy
|
||||
|
||||
/datum/secondary_goal_progress/random_bulk_reagent/update(atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest = null)
|
||||
// Not a reagent container? Ignore.
|
||||
if(!istype(AM, /obj/item/reagent_containers))
|
||||
return
|
||||
|
||||
// Not in a matching personal crate? Ignore.
|
||||
if(!check_personal_crate(AM))
|
||||
return
|
||||
|
||||
var/obj/item/reagent_containers/container = AM
|
||||
var/amount = container.reagents?.get_reagent_amount(initial(reagent_type.id))
|
||||
var/amount = AM.reagents?.get_reagent_amount(initial(reagent_type.id))
|
||||
if(!amount)
|
||||
return
|
||||
sent += amount
|
||||
|
||||
@@ -56,9 +56,8 @@
|
||||
return copy
|
||||
|
||||
/datum/secondary_goal_progress/random_ripley/update(atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest = null)
|
||||
var/datum/component/label/goal/label = AM.GetComponent(/datum/component/label/goal)
|
||||
// Not labelled for this goal? Ignore.
|
||||
if(!istype(label) || label.label_name != goal_requester)
|
||||
if(!check_personal_crate(AM))
|
||||
return
|
||||
if(!istype(AM, /obj/mecha/working/ripley))
|
||||
return
|
||||
|
||||
@@ -98,12 +98,16 @@
|
||||
return FALSE
|
||||
|
||||
/datum/secondary_goal_progress/proc/check_personal_crate(atom/movable/AM)
|
||||
// Accept stuff that is properly labelled with a hand labeller.
|
||||
var/datum/component/label/goal/label = AM.GetComponent(/datum/component/label/goal)
|
||||
if(istype(label))
|
||||
return !goal_requester || label.label_name == goal_requester
|
||||
|
||||
// Accept stuff in matching personal crates.
|
||||
var/obj/structure/closet/crate/secure/personal/PC = get_atom_on_turf(AM, /obj/structure/closet/crate/secure/personal)
|
||||
if(!istype(PC))
|
||||
return FALSE
|
||||
if(goal_requester && PC.registered_name != goal_requester)
|
||||
return FALSE
|
||||
return TRUE
|
||||
return !goal_requester || PC.registered_name == goal_requester
|
||||
|
||||
/datum/secondary_goal_progress/proc/three_way_reward(datum/economy/cargo_shuttle_manifest/manifest, department, department_account, reward, message)
|
||||
SSblackbox.record_feedback("nested tally", "secondary goals", 1, list(goal_name, "payments made"))
|
||||
|
||||
@@ -45,27 +45,22 @@
|
||||
return copy
|
||||
|
||||
/datum/secondary_goal_progress/variety_reagent/update(atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest = null)
|
||||
// Not a reagent container? Ignore.
|
||||
if(!istype(AM, /obj/item/reagent_containers))
|
||||
return
|
||||
|
||||
// Not in a matching personal crate? Ignore.
|
||||
if(!check_personal_crate(AM))
|
||||
return
|
||||
|
||||
var/obj/item/reagent_containers/container = AM
|
||||
// No reagents? Ignore.
|
||||
if(!container.reagents.reagent_list)
|
||||
if(!AM.reagents?.reagent_list)
|
||||
return
|
||||
|
||||
var/datum/reagent/reagent = container.reagents?.get_master_reagent()
|
||||
var/datum/reagent/reagent = AM.reagents.get_master_reagent()
|
||||
|
||||
// Make sure it's for our department.
|
||||
if(!reagent || reagent.goal_department != department)
|
||||
return
|
||||
|
||||
// Isolated reagents only, please.
|
||||
if(length(container.reagents.reagent_list) != 1)
|
||||
if(length(AM.reagents.reagent_list) != 1)
|
||||
if(!manifest)
|
||||
return COMSIG_CARGO_SELL_WRONG
|
||||
SSblackbox.record_feedback("nested tally", "secondary goals", 1, list(goal_name, "mixed reagents"))
|
||||
|
||||
@@ -27,3 +27,7 @@
|
||||
|
||||
for(var/obj/item/organ/internal/I in other_groin_organs)
|
||||
I.receive_damage(rand(5, 15) + tumor_damage_modifier)
|
||||
|
||||
/obj/item/organ/internal/bone_tumor/slime_tumor
|
||||
name = "crystalized slime jelly"
|
||||
|
||||
|
||||
@@ -158,19 +158,24 @@ td {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.link {
|
||||
display: inline;
|
||||
.link,
|
||||
.listedturf_link {
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 7px 14px;
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.link {
|
||||
display: inline;
|
||||
padding: 7px 14px;
|
||||
margin: 2px 2px;
|
||||
}
|
||||
|
||||
.link:hover {
|
||||
.link:hover,
|
||||
.listedturf_link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
@@ -225,7 +230,8 @@ body.dark {
|
||||
color: #b2c4dd;
|
||||
}
|
||||
|
||||
.dark .link {
|
||||
.dark .link,
|
||||
.dark .listedturf_link{
|
||||
color: #abc6ec;
|
||||
}
|
||||
|
||||
@@ -268,7 +274,8 @@ body.ntos {
|
||||
color: #b2c4dd;
|
||||
}
|
||||
|
||||
.ntos .link {
|
||||
.ntos .link,
|
||||
.ntos .listedturf_link{
|
||||
color: #abc6ec;
|
||||
}
|
||||
|
||||
@@ -311,7 +318,8 @@ body.paradise {
|
||||
color: #dec5bd;
|
||||
}
|
||||
|
||||
.paradise .link {
|
||||
.paradise .link,
|
||||
.paradise .listedturf_link{
|
||||
color: #edc1b2;
|
||||
}
|
||||
|
||||
@@ -354,6 +362,7 @@ body.syndicate {
|
||||
color: #debdbd;
|
||||
}
|
||||
|
||||
.syndicate .link {
|
||||
.syndicate .link,
|
||||
.syndicate .listedturf_link {
|
||||
color: #edb2b2;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,13 @@ if (!String.prototype.trim) {
|
||||
};
|
||||
}
|
||||
|
||||
// For sending BYOND debug logs -----------------------------------------------
|
||||
// If you use this, you'll need to uncomment the Statpanel-Debug message
|
||||
// handling, currently in code/modules/client/client_procs.dm
|
||||
function log_debug(data) {
|
||||
Byond.sendMessage("Statpanel-Debug", JSON.stringify(data));
|
||||
}
|
||||
|
||||
// Status panel implementation ------------------------------------------------
|
||||
var status_tab_parts = [["Loading...", ""]];
|
||||
var current_tab = null;
|
||||
@@ -22,14 +29,20 @@ var href_token = null;
|
||||
var verb_tabs = [];
|
||||
var verbs = [["", ""]]; // list with a list inside
|
||||
var permanent_tabs = []; // tabs that won't be cleared by wipes
|
||||
var turfcontents = [];
|
||||
var turf_row_inner_height = 33;
|
||||
var turf_row_outer_height = 35;
|
||||
var turf_rows = {};
|
||||
var turf_incomplete_rows = {};
|
||||
var turf_size = 0;
|
||||
var turf_image_errors = {};
|
||||
var turfcontents = {"total": 0};
|
||||
var turfname = "";
|
||||
var imageFirstRetryDelay = 50;
|
||||
var imageRetryDelay = 500;
|
||||
var imageRetryLimit = 50;
|
||||
var menu = document.getElementById('menu');
|
||||
var under_menu = document.getElementById('under_menu');
|
||||
var statcontentdiv = document.getElementById('statcontent');
|
||||
var storedimages = [];
|
||||
var split_admin_tabs = false;
|
||||
|
||||
// Any BYOND commands that could result in the client's focus changing go through this
|
||||
@@ -371,79 +384,217 @@ function draw_mc() {
|
||||
document.getElementById("statcontent").appendChild(table);
|
||||
}
|
||||
|
||||
function iconError(e) {
|
||||
if(current_tab != turfname) {
|
||||
function listedturf_add_row(table, table_index, true_index) {
|
||||
let row = table.insertRow(table_index);
|
||||
row.style.height = turf_row_inner_height + "px"
|
||||
row.style.padding = "0px"
|
||||
row.style.margin = "0px"
|
||||
turf_rows[true_index] = row;
|
||||
turf_incomplete_rows[true_index] = true_index + 1;
|
||||
}
|
||||
|
||||
function listedturf_fill_row(row, item_index) {
|
||||
let object_info = turfcontents["" + item_index];
|
||||
if(!object_info) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let cell = document.createElement("td");
|
||||
cell.style.height = turf_row_inner_height + "px"
|
||||
cell.style.padding = "0px"
|
||||
cell.style.margin = "0px"
|
||||
row.appendChild(cell)
|
||||
|
||||
var button = document.createElement("div");
|
||||
button.className = "listedturf_link";
|
||||
var clickcatcher = "";
|
||||
button.onmousedown = function (object_info) {
|
||||
// The outer function is used to close over a fresh "object_info"
|
||||
// variable, rather than every onmousedown getting the "object_info"
|
||||
// of the last entry.
|
||||
return function (e) {
|
||||
e.preventDefault();
|
||||
clickcatcher = "?src=" + object_info[1];
|
||||
switch (e.button) {
|
||||
case 1:
|
||||
clickcatcher += ";statpanel_item_click=middle"
|
||||
break;
|
||||
case 2:
|
||||
clickcatcher += ";statpanel_item_click=right"
|
||||
break;
|
||||
default:
|
||||
clickcatcher += ";statpanel_item_click=left"
|
||||
}
|
||||
if (e.shiftKey) {
|
||||
clickcatcher += ";statpanel_item_shiftclick=1";
|
||||
}
|
||||
if (e.ctrlKey) {
|
||||
clickcatcher += ";statpanel_item_ctrlclick=1";
|
||||
}
|
||||
if (e.altKey) {
|
||||
clickcatcher += ";statpanel_item_altclick=1";
|
||||
}
|
||||
window.location.href = clickcatcher;
|
||||
}
|
||||
}(object_info);
|
||||
cell.appendChild(button);
|
||||
|
||||
let img = document.createElement("img");
|
||||
img.id = object_info[1];
|
||||
img.src = object_info[2];
|
||||
img.style.verticalAlign = "middle";
|
||||
img.onerror = function (object_info) {
|
||||
return function () {
|
||||
let delay = imageRetryDelay;
|
||||
if (!turf_image_errors[object_info[3]]) {
|
||||
turf_image_errors[object_info[3]] = 0;
|
||||
delay = imageFirstRetryDelay;
|
||||
}
|
||||
turf_image_errors[object_info[3]]++;
|
||||
if (turf_image_errors[object_info[3]] > imageRetryLimit) {
|
||||
return;
|
||||
}
|
||||
|
||||
Byond.sendMessage("Resend-Asset", object_info[3]);
|
||||
setTimeout(function () {
|
||||
// Use the failure count as a cachebreaker to force-reload.
|
||||
let img = document.getElementById(object_info[1]);
|
||||
img.src = object_info[2] + "?" + turf_image_errors[object_info[3]];
|
||||
}, imageRetryDelay);
|
||||
}
|
||||
}(object_info);
|
||||
button.appendChild(img);
|
||||
|
||||
var label = document.createElement("span");
|
||||
label.style.marginLeft = "5px";
|
||||
label.textContent = object_info[0];
|
||||
button.appendChild(label);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function listedturf_fill_all() {
|
||||
for(let i in turf_incomplete_rows) {
|
||||
let item_index = turf_incomplete_rows[i];
|
||||
if(!turf_rows[i] || listedturf_fill_row(turf_rows[i], item_index)) {
|
||||
delete turf_incomplete_rows[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var suppress_next_scroll_message = false;
|
||||
/* We keep a sliding "window" of listedturf items loded. On scroll, we add and
|
||||
* remove table rows to maintain that window, and update the size of the
|
||||
* padding row at the top of the table to keep them in the right spot.
|
||||
*/
|
||||
function listedturf_scrolled() {
|
||||
let top_edge = document.documentElement.scrollTop;
|
||||
let height = document.documentElement.clientHeight;
|
||||
let bottom_edge = top_edge + height;
|
||||
let total = document.documentElement.scrollHeight;
|
||||
let table = document.getElementById("listedturf_table");
|
||||
let padding = document.getElementById("listedturf_padding");
|
||||
|
||||
if (!turf_rows.initialized) {
|
||||
turf_rows = {
|
||||
initialized: true,
|
||||
min_row: 0,
|
||||
max_row: 0,
|
||||
};
|
||||
}
|
||||
|
||||
if (turf_size === 0) {
|
||||
return;
|
||||
}
|
||||
setTimeout(function () {
|
||||
var node = e.target;
|
||||
var current_attempts = Number(node.getAttribute("data-attempts")) || 0
|
||||
if (current_attempts > imageRetryLimit) {
|
||||
return;
|
||||
|
||||
let desired_min_row = Math.min(turf_size, Math.max(0, Math.floor(top_edge / turf_row_outer_height) - 10));
|
||||
let desired_max_row = Math.min(turf_size, desired_min_row + Math.ceil(height / turf_row_outer_height) + 21);
|
||||
padding.style.height = (desired_min_row * turf_row_outer_height) + "px";
|
||||
if(desired_min_row == turf_rows.min_row && desired_max_row == turf_rows.max_row) {
|
||||
listedturf_fill_all();
|
||||
suppress_next_scroll_message = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (desired_min_row < turf_rows.min_row) {
|
||||
for (let i = desired_min_row; i < turf_rows.min_row; i++) {
|
||||
listedturf_add_row(table, i - desired_min_row + 1, i);
|
||||
}
|
||||
var src = node.src;
|
||||
node.src = null;
|
||||
node.src = src + '#' + current_attempts;
|
||||
node.setAttribute("data-attempts", current_attempts + 1)
|
||||
draw_listedturf();
|
||||
}, imageRetryDelay);
|
||||
} else if (desired_min_row > turf_rows.min_row) {
|
||||
for (let i = turf_rows.min_row; i < desired_min_row && i < turf_rows.max_row; i++) {
|
||||
if(turf_rows[i]) {
|
||||
turf_rows[i].remove();
|
||||
delete turf_rows[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
turf_rows.min_row = desired_min_row;
|
||||
|
||||
padding.style.height = turf_rows.min_row * turf_row_outer_height + "px"
|
||||
|
||||
|
||||
if (desired_max_row < turf_rows.max_row) {
|
||||
for (let i = Math.max(desired_max_row, turf_rows.min_row); i < turf_rows.max_row; i++) {
|
||||
if(turf_rows[i]) {
|
||||
turf_rows[i].remove();
|
||||
delete turf_rows[i];
|
||||
}
|
||||
}
|
||||
} else if (desired_max_row > turf_rows.max_row) {
|
||||
for (let i = Math.max(turf_rows.min_row, turf_rows.max_row); i < desired_max_row; i++) {
|
||||
listedturf_add_row(table, i - turf_rows.min_row + 1, i);
|
||||
}
|
||||
}
|
||||
turf_rows.max_row = desired_max_row;
|
||||
|
||||
listedturf_fill_all();
|
||||
|
||||
if (!suppress_next_scroll_message) {
|
||||
Byond.sendMessage("Listedturf-Scroll", {"min": turf_rows.min_row, "max": turf_rows.max_row})
|
||||
}
|
||||
suppress_next_scroll_message = false;
|
||||
}
|
||||
|
||||
function draw_listedturf() {
|
||||
statcontentdiv.textContent = "";
|
||||
var table = document.createElement("table");
|
||||
for (var i = 0; i < turfcontents.length; i++) {
|
||||
var part = turfcontents[i];
|
||||
if (storedimages[part[1]] == null && part[2]) {
|
||||
var img = document.createElement("img");
|
||||
img.src = part[2];
|
||||
img.id = part[1];
|
||||
storedimages[part[1]] = part[2];
|
||||
img.onerror = iconError;
|
||||
table.appendChild(img);
|
||||
} else {
|
||||
var img = document.createElement("img");
|
||||
img.onerror = iconError;
|
||||
img.src = storedimages[part[1]];
|
||||
img.id = part[1];
|
||||
table.appendChild(img);
|
||||
}
|
||||
var b = document.createElement("div");
|
||||
var clickcatcher = "";
|
||||
b.className = "link";
|
||||
b.onmousedown = function (part) {
|
||||
// The outer function is used to close over a fresh "part" variable,
|
||||
// rather than every onmousedown getting the "part" of the last entry.
|
||||
return function (e) {
|
||||
e.preventDefault();
|
||||
clickcatcher = "?src=" + part[1];
|
||||
switch (e.button) {
|
||||
case 1:
|
||||
clickcatcher += ";statpanel_item_click=middle"
|
||||
break;
|
||||
case 2:
|
||||
clickcatcher += ";statpanel_item_click=right"
|
||||
break;
|
||||
default:
|
||||
clickcatcher += ";statpanel_item_click=left"
|
||||
}
|
||||
if (e.shiftKey) {
|
||||
clickcatcher += ";statpanel_item_shiftclick=1";
|
||||
}
|
||||
if (e.ctrlKey) {
|
||||
clickcatcher += ";statpanel_item_ctrlclick=1";
|
||||
}
|
||||
if (e.altKey) {
|
||||
clickcatcher += ";statpanel_item_altclick=1";
|
||||
}
|
||||
window.location.href = clickcatcher;
|
||||
}
|
||||
}(part);
|
||||
b.textContent = part[0];
|
||||
table.appendChild(b);
|
||||
table.appendChild(document.createElement("br"));
|
||||
if(document.getElementById("listedturf_div")) {
|
||||
let div = document.getElementById("listedturf_div");
|
||||
div.style.height = (turf_row_outer_height * turf_size) + "px";
|
||||
suppress_next_scroll_message = true;
|
||||
listedturf_scrolled();
|
||||
return
|
||||
}
|
||||
document.getElementById("statcontent").appendChild(table);
|
||||
|
||||
statcontentdiv.textContent = "";
|
||||
turf_rows = {};
|
||||
window.onscroll = function() { listedturf_scrolled(); };
|
||||
|
||||
let div = document.createElement("div");
|
||||
div.id = "listedturf_div";
|
||||
div.style.height = (turf_row_outer_height * turf_size) + "px";
|
||||
document.getElementById("statcontent").appendChild(div);
|
||||
|
||||
let table = document.createElement("table");
|
||||
table.id = "listedturf_table";
|
||||
table.style.width = "100%"
|
||||
table.style.height = "100%"
|
||||
div.appendChild(table)
|
||||
|
||||
let padding = document.createElement("tr");
|
||||
padding.id = "listedturf_padding";
|
||||
padding.style.height = "0px";
|
||||
padding.style.padding = "0px"
|
||||
padding.style.margin = "0px"
|
||||
table.appendChild(padding);
|
||||
|
||||
let end_flex = document.createElement("tr");
|
||||
end_flex.id = "listedturf_end_flex";
|
||||
end_flex.style.height = "100%";
|
||||
end_flex.style.padding = "0px"
|
||||
end_flex.style.margin = "0px"
|
||||
table.appendChild(end_flex);
|
||||
|
||||
suppress_next_scroll_message = true;
|
||||
listedturf_scrolled();
|
||||
}
|
||||
|
||||
function remove_listedturf() {
|
||||
@@ -452,6 +603,14 @@ function remove_listedturf() {
|
||||
if (current_tab == turfname) {
|
||||
tab_change("Status");
|
||||
}
|
||||
if(document.getElementById("listedturf_div")) {
|
||||
document.getElementById("listedturf_div").remove();
|
||||
}
|
||||
turf_rows = {};
|
||||
turf_incomplete_rows = {};
|
||||
turf_size = 0;
|
||||
turfcontents = {"total": 0};
|
||||
turfname = "";
|
||||
}
|
||||
|
||||
function remove_mc() {
|
||||
@@ -738,6 +897,7 @@ Byond.subscribeTo('remove_mc_tab', function (removeHref) {
|
||||
|
||||
Byond.subscribeTo('update_listedturf', function (TC) {
|
||||
turfcontents = TC;
|
||||
turf_size = TC["total"];
|
||||
if (current_tab == turfname) {
|
||||
draw_listedturf();
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 621 KiB After Width: | Height: | Size: 621 KiB |
BIN
icons/effects/particles/generic_particles.dmi
Normal file
|
After Width: | Height: | Size: 782 B |
|
Before Width: | Height: | Size: 1013 B |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 26 KiB |
BIN
icons/obj/money.dmi
Normal file
|
After Width: | Height: | Size: 776 B |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 31 KiB |
@@ -92,6 +92,7 @@
|
||||
#include "code\__DEFINES\muzzle_flash.dm"
|
||||
#include "code\__DEFINES\nanomob_defines.dm"
|
||||
#include "code\__DEFINES\newscaster_defines.dm"
|
||||
#include "code\__DEFINES\particle_defines.dm"
|
||||
#include "code\__DEFINES\pda.dm"
|
||||
#include "code\__DEFINES\pipes.dm"
|
||||
#include "code\__DEFINES\power_defines.dm"
|
||||
@@ -402,6 +403,7 @@
|
||||
#include "code\datums\components\corpse_description.dm"
|
||||
#include "code\datums\components\cult_held_body.dm"
|
||||
#include "code\datums\components\deadchat_control.dm"
|
||||
#include "code\datums\components\debris.dm"
|
||||
#include "code\datums\components\decal.dm"
|
||||
#include "code\datums\components\defibrillator.dm"
|
||||
#include "code\datums\components\ducttape.dm"
|
||||
|
||||