diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3adae3a9ab8e..1c5f9e4eb6f8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -91,7 +91,7 @@ jobs: strategy: fail-fast: false # Let all map tests run to completion matrix: - maptype: ['/datum/map/cyberiad', '/datum/map/delta', '/datum/map/metastation', '/datum/map/cerestation'] + maptype: ['/datum/map/boxstation', '/datum/map/deltastation', '/datum/map/metastation', '/datum/map/cerestation'] byondtype: ['STABLE'] services: mariadb: diff --git a/.github/workflows/label_stale.yml b/.github/workflows/label_stale.yml new file mode 100644 index 000000000000..2b643599e0c0 --- /dev/null +++ b/.github/workflows/label_stale.yml @@ -0,0 +1,24 @@ +name: Label and close stale PRs and Issues + +on: + schedule: + - cron: '0 0 * * *' # Runs at midnight UTC every day + +jobs: + stale-prs: + runs-on: ubuntu-latest + steps: + - name: Seek and destroy stale PRs and Issues + uses: actions/stale@v9 + with: + stale-pr-message: 'This pull request seems to be stale as there have been no changes in 14 days, please make changes within 7 days or the PR will be closed. If you believe this is a mistake, please inform a development team member on Discord.' + close-pr-message: 'This pull request has not received any updates since being marked stale, and as such is now being automatically closed. Please feel free to re-open this pull request or open a new one once you have new updates.' + stale-issue-message: 'This issue either requires verification or is unreproducible, but has had no updates for 60 days. Please provide an update within 14 days or this issue will be closed. If you believe this is a mistake, please contact an issue manager on Discord.' + close-issue-message: 'This issue was marked as stale, yet no changes have been observed in the specified time. The issue has been closed.' + days-before-stale: 14 + days-before-issue-stale: 60 + days-before-close: 7 + days-before-issue-close: 14 + exempt-issue-labels: '"Stale Exempt"' + exempt-pr-labels: '"Stale Exempt", "-Status: Awaiting approval", "-Status: Awaiting Merge", "-Status: Awaiting type assignment"' + any-of-issue-labels: '"Need Verification", "Cannot Reproduce", "Not A Bug", "(99% Sure) Not A Bug"' diff --git a/.github/workflows/merge_upstream_master.yml b/.github/workflows/merge_upstream_master.yml index 94cad7e5baeb..fc03ad8cc535 100644 --- a/.github/workflows/merge_upstream_master.yml +++ b/.github/workflows/merge_upstream_master.yml @@ -1,7 +1,7 @@ name: Merge Upstream Master on: issue_comment: - types: [created] + types: created jobs: merge-upstream: @@ -15,13 +15,30 @@ 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 + 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 \ + -f content='+1' + - name: PR Data - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | pr_json=$(curl -L -s --fail-with-body -H "Authorization: token ${{ github.token }}" ${{ github.event.issue.pull_request.url }}) if [ `jq -r '.maintainer_can_modify' <<<$pr_json` == "false" ] ; then gh pr comment ${{ github.event.issue.html_url }} --body 'GitHub Actions can not push to the repository without "Allow edits and access to secrets by maintainers" checked.' + echo "FAIL_NOTIFIED=true" >> "$GITHUB_ENV" exit 1 fi echo "PR_REPO=`jq -r '.head.repo.full_name' <<<$pr_json`" >> $GITHUB_ENV @@ -32,6 +49,7 @@ jobs: with: repository: ${{ env.PR_REPO }} ref: ${{ env.PR_BRANCH }} + token: ${{ env.GH_TOKEN }} - uses: actions/setup-node@v4 with: @@ -73,18 +91,25 @@ jobs: chmod +x tools/hooks/*.merge tgui/bin/tgui # Actual Merge - git config user.name github-actions - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git config user.name paradisess13[bot] + git config user.email "165046124+paradisess13[bot]@users.noreply.github.com" git remote add upstream "https://github.com/$BASE_REPOSITORY.git" git fetch origin "$PR_BRANCH" --depth=$((ahead_by + 1)) git fetch upstream "$BASE_BRANCH" --depth=$((behind_by + 1)) + + # 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/ParadiseSS13/Paradise/commit/$latest_workflow_commit before using this command again."# + echo "FAIL_NOTIFIED=true" >> "$GITHUB_ENV" + exit 1 + fi + git merge FETCH_HEAD git push origin - name: Notify Failure - if: failure() + if: failure() && env.FAIL_NOTIFIED != 'true' run: | - curl -s -H "Authorization: token ${{ github.token }}" \ - -X POST -d '{"body": "Merging upstream failed:\nhttps://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"}' \ - "https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.issue.number }}/comments" + gh pr comment ${{ github.event.issue.html_url }} -b 'Merging upstream failed, see the action run log for details: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}' diff --git a/.github/workflows/render_nanomaps.yml b/.github/workflows/render_nanomaps.yml index 5b348499cde2..7ba495b35401 100644 --- a/.github/workflows/render_nanomaps.yml +++ b/.github/workflows/render_nanomaps.yml @@ -9,19 +9,23 @@ on: - cron: "0 0 * * *" workflow_dispatch: -permissions: - contents: read - jobs: generate_maps: - permissions: - contents: write # for Git to git push - pull-requests: write # for repo-sync/pull-request to create pull requests name: 'Generate NanoMaps' runs-on: ubuntu-22.04 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" + - name: 'Update Branch' uses: actions/checkout@v4 + with: + token: ${{ steps.create_token.outputs.token }} - name: Branch run: | @@ -32,20 +36,11 @@ jobs: - name: 'Generate Maps' run: './tools/github-actions/nanomap-renderer-invoker.sh' - - name: 'Commit Maps' + - name: 'Commit Maps and open PR' run: | git config --local user.email "action@github.com" git config --local user.name "NanoMap Generation" git pull origin master git commit -m "NanoMap Auto-Update (`date`)" -a || true git push -f -u origin nanomap-render - - - name: Create Pull Request - uses: repo-sync/pull-request@v2 - with: - source_branch: "nanomap-render" - destination_branch: "master" - pr_title: "Automatic NanoMap Update" - pr_body: "This pull request updates the server NanoMaps. Please review the diff images before merging." - pr_label: "NanoMaps" - pr_allow_empty: false + gh pr create -t "Automatic NanoMap Update" -b "This pull request updates the server NanoMaps. Please review the diff images before merging." -l "NanoMaps" -H "nanomap-render" -B "master" diff --git a/SQL/paradise_schema.sql b/SQL/paradise_schema.sql index 6855c02dabe0..3e20acae2150 100644 --- a/SQL/paradise_schema.sql +++ b/SQL/paradise_schema.sql @@ -79,6 +79,7 @@ CREATE TABLE `characters` ( `hair_gradient_colour` varchar(7) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '#000000', `hair_gradient_alpha` tinyint(3) UNSIGNED NOT NULL DEFAULT '255', `custom_emotes` LONGTEXT COLLATE 'utf8mb4_unicode_ci' DEFAULT NULL, + `cyborg_brain_type` ENUM('MMI', 'Robobrain', 'Positronic') NOT NULL DEFAULT 'MMI', `tts_seed` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL, PRIMARY KEY (`id`), KEY `ckey` (`ckey`) diff --git a/SQL/updates/53-54.sql b/SQL/updates/53-54.sql new file mode 100644 index 000000000000..303de0b32be3 --- /dev/null +++ b/SQL/updates/53-54.sql @@ -0,0 +1,5 @@ +#Updating SQL from 53 to 54 -Wilk +#Add a choice for what type of brain borgs want to have + +ALTER TABLE `characters` + ADD COLUMN `cyborg_brain_type` VARCHAR(11) NOT NULL DEFAULT 'MMI' AFTER `height`; diff --git a/_maps/map_files/RandomRuins/SpaceRuins/whiteship.dmm b/_maps/map_files/RandomRuins/SpaceRuins/whiteship.dmm index a8fea8ba17c7..bd0783a12996 100644 --- a/_maps/map_files/RandomRuins/SpaceRuins/whiteship.dmm +++ b/_maps/map_files/RandomRuins/SpaceRuins/whiteship.dmm @@ -157,7 +157,9 @@ /turf/simulated/floor/wood, /area/shuttle/abandoned) "tV" = ( -/obj/machinery/door/airlock/titanium/glass, +/obj/machinery/door/airlock/multi_tile/glass{ + dir = 1 + }, /turf/simulated/floor/mineral/plastitanium, /area/shuttle/abandoned) "uo" = ( @@ -461,7 +463,7 @@ zO zO zO zO -tV +wF tV zO zO diff --git a/_maps/map_files/shuttles/emergency_raven.dmm b/_maps/map_files/shuttles/emergency_raven.dmm index 86e5bce7e741..06b94bc0d8a8 100644 --- a/_maps/map_files/shuttles/emergency_raven.dmm +++ b/_maps/map_files/shuttles/emergency_raven.dmm @@ -1328,6 +1328,10 @@ }, /turf/simulated/floor/plasteel/dark, /area/shuttle/escape) +"JM" = ( +/obj/structure/shuttle/engine/large, +/turf/simulated/floor/plating/airless, +/area/shuttle/escape) "JO" = ( /obj/effect/turf_decal/stripes/line{ dir = 10 @@ -1435,6 +1439,9 @@ icon_state = "darkred" }, /area/shuttle/escape) +"So" = ( +/turf/simulated/floor/plating/airless, +/area/shuttle/escape) "Ux" = ( /obj/effect/turf_decal/stripes/white/corner, /obj/effect/decal/cleanable/dirt, @@ -1656,8 +1663,8 @@ dI dE Mm cP -cP -aa +So +JM "} (6,1,1) = {" aa @@ -1690,8 +1697,8 @@ dE dE Nd fn -em -aa +So +So "} (7,1,1) = {" ab @@ -1792,8 +1799,8 @@ dE dE vw fn -em -aa +So +JM "} (10,1,1) = {" ab @@ -1826,8 +1833,8 @@ dE dE cP cP -cP -aa +So +So "} (11,1,1) = {" ab @@ -1860,7 +1867,7 @@ Sa Sa ed cP -aa +cP aa "} (12,1,1) = {" @@ -1894,8 +1901,8 @@ dE dE cP cP -cP -aa +So +JM "} (13,1,1) = {" ab @@ -1928,8 +1935,8 @@ dE dE sr fn -em -aa +So +So "} (14,1,1) = {" ab @@ -2030,8 +2037,8 @@ dE dE NK fn -em -aa +So +JM "} (17,1,1) = {" aa @@ -2064,8 +2071,8 @@ dQ dT qC cP -cP -aa +So +So "} (18,1,1) = {" aa diff --git a/_maps/map_files/cyberiad/cyberiad.dmm b/_maps/map_files/stations/boxstation.dmm similarity index 99% rename from _maps/map_files/cyberiad/cyberiad.dmm rename to _maps/map_files/stations/boxstation.dmm index 4b282b507ae9..f611c8ee6d3e 100644 --- a/_maps/map_files/cyberiad/cyberiad.dmm +++ b/_maps/map_files/stations/boxstation.dmm @@ -19316,6 +19316,11 @@ d2 = 8; icon_state = "1-8" }, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, /turf/simulated/floor/plasteel{ icon_state = "neutral" }, @@ -19330,22 +19335,16 @@ icon_state = "dark" }, /area/station/service/hydroponics) -"bhN" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/turf/simulated/floor/plasteel{ - icon_state = "neutral" - }, -/area/station/hallway/secondary/entry/lounge) "bhO" = ( /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, /turf/simulated/floor/plasteel{ icon_state = "neutral" }, @@ -19368,6 +19367,11 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 10 }, +/obj/structure/cable{ + d1 = 2; + d2 = 8; + icon_state = "2-8" + }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "neutralcorner" @@ -19626,14 +19630,6 @@ icon_state = "grimy" }, /area/station/service/chapel/office) -"biA" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/turf/simulated/floor/plasteel{ - dir = 8; - icon_state = "neutral" - }, -/area/station/hallway/secondary/entry/lounge) "biC" = ( /obj/structure/cable{ d1 = 1; @@ -20686,6 +20682,11 @@ d2 = 4; icon_state = "2-4" }, +/obj/structure/cable{ + d1 = 1; + d2 = 4; + icon_state = "1-4" + }, /turf/simulated/floor/plasteel{ dir = 8; icon_state = "neutral" @@ -25397,7 +25398,7 @@ /area/station/hallway/primary/central/west) "bzN" = ( /obj/effect/spawner/airlock/w_to_e/long{ - req_access_txt = 11 + req_access_txt = 32 }, /turf/simulated/wall/r_wall, /area/station/engineering/ai_transit_tube) @@ -54324,8 +54325,8 @@ /turf/simulated/floor/plating, /area/station/maintenance/disposal) "ejO" = ( -/obj/structure/disposalpipe/segment/corner{ - dir = 4 +/obj/structure/disposalpipe/junction{ + dir = 1 }, /turf/simulated/floor/plasteel{ dir = 4; @@ -62692,6 +62693,8 @@ /turf/simulated/floor/grass/jungle/no_creep, /area/station/command/bridge) "imB" = ( +/obj/machinery/door/firedoor, +/obj/structure/disposalpipe/segment, /turf/simulated/floor/plasteel{ dir = 4; icon_state = "darkblue" @@ -65812,7 +65815,9 @@ /turf/simulated/floor/plating, /area/station/maintenance/port) "jRo" = ( -/obj/effect/spawner/airlock/s_to_n/long/square/engineer, +/obj/effect/spawner/airlock/s_to_n/long/square/engineer{ + req_access_txt = null + }, /turf/simulated/wall, /area/station/maintenance/fpmaint2) "jRx" = ( @@ -75551,7 +75556,9 @@ /area/station/maintenance/asmaint) "oBF" = ( /obj/effect/spawner/window/reinforced/grilled, -/obj/effect/spawner/airlock/s_to_n/long/engineer, +/obj/effect/spawner/airlock/s_to_n/long/engineer{ + req_access_txt = null + }, /turf/simulated/floor/plating, /area/station/maintenance/fpmaint2) "oBJ" = ( @@ -82303,6 +82310,13 @@ icon_state = "whitepurplecorner" }, /area/station/science/hallway) +"rHw" = ( +/obj/structure/disposalpipe/segment, +/turf/simulated/floor/plasteel{ + dir = 4; + icon_state = "whiteblue" + }, +/area/station/medical/medbay) "rHJ" = ( /obj/machinery/atmospherics/unary/vent_pump/siphon/on{ dir = 4 @@ -109262,7 +109276,7 @@ aXD aZf aUt aNu -bhN +bda aSX bhm bhm @@ -109519,7 +109533,7 @@ aXC aZa mNq aNu -bhN +bda aSW bhm bhm @@ -110033,7 +110047,7 @@ aXE aZb aVc bcG -bhN +bda sYL sYL sYL @@ -110290,7 +110304,7 @@ aTu aTu aTu bcM -bhN +bda bgv biv bkd @@ -110548,7 +110562,7 @@ aZj aTu bgC bhQ -biA +blq blh blq blq @@ -131405,8 +131419,8 @@ cjC cjC crY cnw -ure -ure +rHw +rHw imB ejO crt diff --git a/_maps/map_files/cerestation/cerestation.dmm b/_maps/map_files/stations/cerestation.dmm similarity index 99% rename from _maps/map_files/cerestation/cerestation.dmm rename to _maps/map_files/stations/cerestation.dmm index df41cd73f6c1..667b8b21519f 100644 --- a/_maps/map_files/cerestation/cerestation.dmm +++ b/_maps/map_files/stations/cerestation.dmm @@ -18091,9 +18091,6 @@ /turf/simulated/floor/carpet/black, /area/station/command/bridge) "bRZ" = ( -/obj/machinery/computer/supplycomp/public{ - dir = 8 - }, /obj/structure/railing{ dir = 6 }, @@ -18102,6 +18099,9 @@ d2 = 2; icon_state = "1-2" }, +/obj/machinery/computer/supplycomp{ + dir = 8 + }, /turf/simulated/floor/carpet/black, /area/station/command/bridge) "bSg" = ( diff --git a/_maps/map_files/Delta/delta.dmm b/_maps/map_files/stations/deltastation.dmm similarity index 99% rename from _maps/map_files/Delta/delta.dmm rename to _maps/map_files/stations/deltastation.dmm index 77945b2eec25..e349499d4aee 100644 --- a/_maps/map_files/Delta/delta.dmm +++ b/_maps/map_files/stations/deltastation.dmm @@ -1089,7 +1089,7 @@ /turf/simulated/floor/plasteel, /area/station/hallway/secondary/entry/west) "aiL" = ( -/obj/structure/chair/office{ +/obj/structure/chair{ dir = 4 }, /turf/simulated/floor/plasteel/dark, @@ -23130,12 +23130,12 @@ /obj/structure/window/reinforced{ dir = 4 }, -/obj/structure/chair/office{ - dir = 8 - }, /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/structure/chair{ + dir = 8 + }, /turf/simulated/floor/plasteel/white, /area/station/medical/medbay) "bqA" = ( @@ -50607,7 +50607,7 @@ }, /area/station/medical/medbay) "cKP" = ( -/obj/structure/chair/office, +/obj/structure/chair, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "whitebluecorner" @@ -51370,7 +51370,7 @@ /turf/simulated/floor/grass, /area/station/medical/reception) "cNW" = ( -/obj/structure/chair/office{ +/obj/structure/chair{ dir = 8 }, /turf/simulated/floor/plasteel{ @@ -51384,10 +51384,10 @@ d2 = 4; icon_state = "0-4" }, -/obj/structure/chair/office{ +/obj/effect/landmark/start/paramedic, +/obj/structure/chair{ dir = 8 }, -/obj/effect/landmark/start/paramedic, /turf/simulated/floor/plasteel{ dir = 10; icon_state = "whiteblue" @@ -59956,9 +59956,6 @@ dir = 8; pixel_x = -4 }, -/obj/structure/chair/office{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/structure/cable{ @@ -59967,6 +59964,9 @@ icon_state = "1-2" }, /obj/structure/disposalpipe/segment, +/obj/structure/chair{ + dir = 4 + }, /turf/simulated/floor/plasteel/white, /area/station/medical/medbay) "dvZ" = ( @@ -66696,9 +66696,6 @@ dir = 8; pixel_x = -4 }, -/obj/structure/chair/office{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ dir = 4 }, @@ -66711,6 +66708,9 @@ icon_state = "1-2" }, /obj/structure/disposalpipe/segment, +/obj/structure/chair{ + dir = 4 + }, /turf/simulated/floor/plasteel/white, /area/station/medical/medbay) "erk" = ( @@ -70706,7 +70706,7 @@ /obj/structure/window/reinforced{ dir = 4 }, -/obj/structure/chair/office{ +/obj/structure/chair{ dir = 8 }, /turf/simulated/floor/plasteel/white, @@ -86386,12 +86386,12 @@ }, /area/station/hallway/primary/fore/north) "qcs" = ( -/obj/structure/chair/office{ - dir = 1 - }, /obj/structure/sign/poster/official/random{ pixel_x = 32 }, +/obj/structure/chair{ + dir = 1 + }, /obj/effect/landmark/start/doctor, /turf/simulated/floor/plasteel{ icon_state = "redyellowfull" @@ -86701,7 +86701,7 @@ }, /area/station/public/sleep) "qqT" = ( -/obj/structure/chair/office{ +/obj/structure/chair{ dir = 8 }, /turf/simulated/floor/plasteel{ @@ -88486,8 +88486,8 @@ }, /area/station/public/sleep) "rrv" = ( -/obj/structure/chair/office, /obj/effect/landmark/start/coroner, +/obj/structure/chair, /turf/simulated/floor/plasteel/dark, /area/station/medical/morgue) "rrL" = ( @@ -89098,14 +89098,14 @@ /turf/simulated/floor/engine, /area/station/science/explab/chamber) "rMm" = ( -/obj/structure/chair/office{ - dir = 4 - }, /obj/machinery/power/apc/directional/west, /obj/structure/cable{ d2 = 4; icon_state = "0-4" }, +/obj/structure/chair{ + dir = 4 + }, /turf/simulated/floor/plasteel/dark, /area/station/medical/surgery/observation) "rMr" = ( @@ -89737,9 +89737,6 @@ dir = 8; pixel_x = -4 }, -/obj/structure/chair/office{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/structure/cable{ @@ -89752,6 +89749,9 @@ name = "Chemistry"; sort_type_txt = "11" }, +/obj/structure/chair{ + dir = 4 + }, /turf/simulated/floor/plasteel/white, /area/station/medical/medbay) "sbU" = ( @@ -91197,12 +91197,12 @@ /obj/structure/window/reinforced{ dir = 4 }, -/obj/structure/chair/office{ - dir = 8 - }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 }, +/obj/structure/chair{ + dir = 8 + }, /turf/simulated/floor/plasteel/white, /area/station/medical/medbay) "sMA" = ( @@ -94691,9 +94691,6 @@ }, /area/station/medical/sleeper) "uMB" = ( -/obj/structure/chair/office{ - dir = 8 - }, /obj/machinery/alarm{ dir = 8; name = "east bump"; @@ -94702,6 +94699,9 @@ /obj/machinery/light{ dir = 4 }, +/obj/structure/chair{ + dir = 8 + }, /turf/simulated/floor/plasteel/dark, /area/station/medical/surgery/observation) "uMM" = ( @@ -95272,7 +95272,7 @@ name = "east bump"; pixel_x = 24 }, -/obj/structure/chair/office{ +/obj/structure/chair{ dir = 8 }, /turf/simulated/floor/plasteel/dark, diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/stations/metastation.dmm similarity index 100% rename from _maps/map_files/MetaStation/MetaStation.dmm rename to _maps/map_files/stations/metastation.dmm diff --git a/_maps/map_files220/cyberiad/cyberiad.dmm b/_maps/map_files220/stations/boxstation.dmm similarity index 100% rename from _maps/map_files220/cyberiad/cyberiad.dmm rename to _maps/map_files220/stations/boxstation.dmm diff --git a/_maps/map_files220/delta/delta.dmm b/_maps/map_files220/stations/deltastation.dmm similarity index 100% rename from _maps/map_files220/delta/delta.dmm rename to _maps/map_files220/stations/deltastation.dmm diff --git a/_maps/map_files220/MetaStation/MetaStation.dmm b/_maps/map_files220/stations/metastation.dmm similarity index 100% rename from _maps/map_files220/MetaStation/MetaStation.dmm rename to _maps/map_files220/stations/metastation.dmm diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index 66b7ca87f190..0f652808833a 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -600,9 +600,9 @@ #define COMSIG_ITEM_PICKUP "item_pickup" ///from base of mob/living/carbon/attacked_by(): (mob/living/carbon/target, mob/living/user, hit_zone) #define COMSIG_ITEM_ATTACK_ZONE "item_attack_zone" -///return a truthy value to prevent ensouling, checked in /obj/effect/proc_holder/spell/lichdom/cast(): (mob/user) +///return a truthy value to prevent ensouling, checked in /datum/spell/lichdom/cast(): (mob/user) #define COMSIG_ITEM_IMBUE_SOUL "item_imbue_soul" -///called before marking an object for retrieval, checked in /obj/effect/proc_holder/spell/summonitem/cast() : (mob/user) +///called before marking an object for retrieval, checked in /datum/spell/summonitem/cast() : (mob/user) #define COMSIG_ITEM_MARK_RETRIEVAL "item_mark_retrieval" #define COMPONENT_BLOCK_MARK_RETRIEVAL (1<<0) ///from base of obj/item/hit_reaction(): (list/args) @@ -1017,3 +1017,24 @@ /// from /obj/structure/cursed_slot_machine/determine_victor() when someone finally wins. #define COMSIG_GLOB_CURSED_SLOT_MACHINE_WON "cursed_slot_machine_won" + +// Signal types for the cargo shuttle + +// Sent before the shuttle scans its contents. +// Use to initialize data that will be needed during the scan. +#define COMSIG_CARGO_BEGIN_SCAN "begin_scan" +// Sent as the shuttle scans its contents. +// Can return sell flags (see code/__DEFINES/supply_defines.dm). +#define COMSIG_CARGO_CHECK_SELL "check_sell" +// Sent as the shuttle begins selling off its contents. +// Use to initialize data that will be needed during the sale. +#define COMSIG_CARGO_BEGIN_SELL "begin_sell" +// Sent during sales for items marked with COMSIG_CARGO_SELL_PRIORITY. +#define COMSIG_CARGO_DO_PRIORITY_SELL "do_priority_sell" +// Sent during sales for items marked with COMSIG_CARGO_SELL_NORMAL. +#define COMSIG_CARGO_DO_SELL "do_sell" +// Sent during sales for items marked with COMSIG_CARGO_SELL_WRONG. +#define COMSIG_CARGO_SEND_ERROR "send_error" +// Sent when sales are completed. +// Use to send summary messages for items that sell in bulk. +#define COMSIG_CARGO_END_SELL "end_sell" diff --git a/code/__DEFINES/food_defines.dm b/code/__DEFINES/food_defines.dm new file mode 100644 index 000000000000..83d378400e11 --- /dev/null +++ b/code/__DEFINES/food_defines.dm @@ -0,0 +1,5 @@ +// Used for secondary goals. +#define FOOD_GOAL_SKIP 0 +#define FOOD_GOAL_EASY 1 +#define FOOD_GOAL_NORMAL 2 +#define FOOD_GOAL_HARD 3 diff --git a/code/__DEFINES/misc_defines.dm b/code/__DEFINES/misc_defines.dm index 85670ff8205a..12e3b65cedc6 100644 --- a/code/__DEFINES/misc_defines.dm +++ b/code/__DEFINES/misc_defines.dm @@ -392,7 +392,7 @@ #define INVESTIGATE_BOMB "bombs" // The SQL version required by this version of the code -#define SQL_VERSION 532206 // SS220 EDIT +#define SQL_VERSION 542206 // SS220 EDIT // Vending machine stuff #define CAT_NORMAL (1<<0) diff --git a/code/__DEFINES/reagents_defines.dm b/code/__DEFINES/reagents_defines.dm index 3b31509b4c70..45bc2fafd1d2 100644 --- a/code/__DEFINES/reagents_defines.dm +++ b/code/__DEFINES/reagents_defines.dm @@ -32,3 +32,9 @@ /// Like O- blood but doesn't contribute to blood_volume or vampire nutrition #define BLOOD_TYPE_FAKE_BLOOD "Vh Null" + +/// Used for secondary goals. +#define REAGENT_GOAL_SKIP 0 +#define REAGENT_GOAL_EASY 1 +#define REAGENT_GOAL_NORMAL 2 +#define REAGENT_GOAL_HARD 3 diff --git a/code/__DEFINES/station_goals.dm b/code/__DEFINES/station_goals.dm index 0c19da7b5f10..01922b2132c3 100644 --- a/code/__DEFINES/station_goals.dm +++ b/code/__DEFINES/station_goals.dm @@ -1,2 +1,9 @@ #define BSA_SIZE_FRONT 4 #define BSA_SIZE_BACK 6 + +// Secondary goals + +/// How many units can be missing from a reagent and still count to the goal. +/// Prevents floationg point rounding from making you fail even though you +/// seemed to have sent enough. +#define REAGENT_GOAL_FORGIVENESS 0.1 diff --git a/code/__DEFINES/supply_defines.dm b/code/__DEFINES/supply_defines.dm new file mode 100644 index 000000000000..f47fdaf111e1 --- /dev/null +++ b/code/__DEFINES/supply_defines.dm @@ -0,0 +1,14 @@ +// Cargo sell flags + +// Priorities +// Each priority blocks all lower priorities. +// Any priority (even WRONG) prevents items from being considered trash. +#define COMSIG_CARGO_SELL_PRIORITY (1<<0) +#define COMSIG_CARGO_SELL_NORMAL (1<<1) +#define COMSIG_CARGO_SELL_WRONG (1<<2) +#define COMSIG_CARGO_SELL_SKIP (1<<3) +#define COMSIG_CARGO_MESS (1<<4) + +// Functional markers +// Marks the item as safe for the shuttle floor (e.g. crates) +#define COMSIG_CARGO_IS_SECURED (1<<5) diff --git a/code/__DEFINES/tickets_defines.dm b/code/__DEFINES/tickets_defines.dm new file mode 100644 index 000000000000..9fbb25a17d6c --- /dev/null +++ b/code/__DEFINES/tickets_defines.dm @@ -0,0 +1,10 @@ +//Time until ticket becomes stale if unanswered. Alerts admins. +#define TICKET_TIMEOUT (10 MINUTES) +//Time before the user is allowed to open another ticket while their existing one is open. +#define TICKET_DUPLICATE_COOLDOWN (5 MINUTES) + +//Status defines +#define TICKET_OPEN 1 +#define TICKET_CLOSED 2 +#define TICKET_RESOLVED 3 +#define TICKET_STALE 4 diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index cb1bb8d5d27c..f880dcc25dc1 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1596,17 +1596,18 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) closest_atom = A return closest_atom -/proc/pick_closest_path(value, list/matches = get_fancy_list_of_atom_types()) - if(!value) //nothing should be calling us with a number, so this is safe - value = input("Enter type to find (blank for all, cancel to cancel)", "Search for type") as null|text - if(isnull(value)) +/proc/pick_closest_path(value, list/matches = get_fancy_list_of_atom_types(), skip_filter = FALSE) + if(!skip_filter) + if(!value) //nothing should be calling us with a number, so this is safe + value = input("Enter type to find (blank for all, cancel to cancel)", "Search for type") as null|text + if(isnull(value)) + return + value = trim(value) + if(!isnull(value) && value != "") + matches = filter_fancy_list(matches, value) + + if(!length(matches)) return - value = trim(value) - if(!isnull(value) && value != "") - matches = filter_fancy_list(matches, value) - - if(!length(matches)) - return var/chosen if(length(matches) == 1) @@ -1702,6 +1703,8 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) /obj/structure = "STRUCTURE", /obj/vehicle = "VEHICLE", /obj = "O", + /datum/station_goal/secondary = "S_GOAL", + /datum/station_goal = "GOAL", /datum = "D", /turf/simulated/floor = "SIM_FLOOR", /turf/simulated/wall = "SIM_WALL", diff --git a/code/_globalvars/lists/flavor_misc.dm b/code/_globalvars/lists/flavor_misc.dm index 19768711ea14..5d588c4793bd 100644 --- a/code/_globalvars/lists/flavor_misc.dm +++ b/code/_globalvars/lists/flavor_misc.dm @@ -61,3 +61,10 @@ GLOBAL_LIST_INIT(phonetic_alphabet, list("Alpha", "Bravo", "Charlie", #define DSATCHEL "Department Satchel" #define DDUFFLEBAG "Department Dufflebag" GLOBAL_LIST_INIT(backbaglist, list(DBACKPACK, DSATCHEL, DDUFFLEBAG, GBACKPACK, GSATCHEL, GDUFFLEBAG, LSATCHEL)) + +//Chooseable brain types for borgs +#define MMI_BORG "MMI" +#define ROBOBRAIN_BORG "Robobrain" +#define POSITRONIC_BORG "Positronic" +GLOBAL_LIST_INIT(borg_brain_choices, list(MMI_BORG, ROBOBRAIN_BORG, POSITRONIC_BORG)) +GLOBAL_PROTECT(borg_brain_choices) diff --git a/code/_onclick/hud/action_button.dm b/code/_onclick/hud/action_button.dm index b78612c0fbdc..1eacfda42293 100644 --- a/code/_onclick/hud/action_button.dm +++ b/code/_onclick/hud/action_button.dm @@ -16,6 +16,8 @@ var/id /// UID of the last thing we hovered over. Used for managing action button dragging. var/last_hovered_ref + /// Whether or not this button is locked, preventing it from being dragged. + var/locked = FALSE /atom/movable/screen/movable/action_button/Destroy() . = ..() @@ -38,7 +40,7 @@ // Very much byond logic, but I want nice behavior, so we fake it with drag /atom/movable/screen/movable/action_button/MouseDrag(atom/over_object, src_location, over_location, src_control, over_control, params) . = ..() - if(!can_use(usr)) + if(!can_use(usr) || locked) return @@ -64,6 +66,10 @@ last_hovered_ref = null if(!can_use(usr)) return + if(locked) + fire_action() + return + var/datum/hud/our_hud = usr.hud_used if(over_object == src) our_hud.hide_landings() @@ -100,6 +106,12 @@ var/position_info = SCRN_OBJ_DEFAULT user.hud_used.position_action(src, position_info) +/atom/movable/screen/movable/action_button/proc/fire_action(left_click = TRUE) + linked_action.Trigger(TRUE) + transform = transform.Scale(0.8, 0.8) + alpha = 200 + animate(src, transform = matrix(), time = 0.4 SECONDS, alpha = 255) + /atom/movable/screen/movable/action_button/Click(location, control, params) var/list/modifiers = params2list(params) if(modifiers["ctrl"] && modifiers["shift"]) @@ -116,18 +128,23 @@ AltClick(usr) return TRUE if(modifiers["middle"]) - linked_action.Trigger(left_click = FALSE) + fire_action(TRUE) return TRUE if(modifiers["ctrl"]) CtrlClick(usr) return TRUE - linked_action.Trigger(TRUE) - transform = transform.Scale(0.8, 0.8) - alpha = 200 - animate(src, transform = matrix(), time = 0.4 SECONDS, alpha = 255) + + fire_action(TRUE) return TRUE +/atom/movable/screen/movable/action_button/CtrlClick(mob/user) + if(!can_use(user)) + return + locked = !locked + to_chat(user, "[src]'s button has been [locked ? "":"un"]locked.") + + /** * This is a silly proc used in hud code code to determine what icon and icon state we should be using * for hud elements (such as action buttons) that don't have their own icon and icon state set. @@ -215,7 +232,7 @@ /atom/movable/screen/button_palette - desc = "Drag buttons to move them.
Shift-click any button to reset it.
Alt-click this to reset all buttons.
Ctrl-click this to get a detailed explanation of how to use this." + desc = "Drag buttons to move them.
Shift-click any button to reset it.
Alt-click this to reset all buttons.
Ctrl-click action buttons to lock or unlock them.
Ctrl-click this to get a detailed explanation of how to use this." icon = 'icons/hud/64x16_actions.dmi' icon_state = "screen_gen_palette" screen_loc = ui_action_palette diff --git a/code/controllers/subsystem/SSeconomy.dm b/code/controllers/subsystem/SSeconomy.dm index db104e779dc5..c261d7f963a7 100644 --- a/code/controllers/subsystem/SSeconomy.dm +++ b/code/controllers/subsystem/SSeconomy.dm @@ -48,14 +48,34 @@ SUBSYSTEM_DEF(economy) ///Current Order number var/ordernum = 1 - /// points gained per slip returned + /// credits gained per slip returned var/credits_per_manifest = 5 - /// points gained per intel returned + /// credits gained per intel sold var/credits_per_intel = 750 - /// points gained per plasma returned + /// credits gained per plasma sold var/credits_per_plasma = 10 - /// points gained per research design returned + /// credits gained per research design sold var/credits_per_design = 20 + /// credits gained per working mech sold + var/credits_per_mech = 100 + /// credits gained for each secondary goal completed + /// These get split in 3, one part for Cargo, one for the department, + /// and one part for the person who requested the goal. + var/credits_per_easy_reagent_goal = 150 + var/credits_per_normal_reagent_goal = 300 + var/credits_per_hard_reagent_goal = 450 + var/credits_per_variety_reagent_goal = 300 + var/credits_per_easy_food_goal = 300 + var/credits_per_normal_food_goal = 450 + var/credits_per_hard_food_goal = 600 + var/credits_per_ripley_goal = 600 + var/credits_per_kudzu_goal = 600 + /// credits lost for sending unsecured cargo + var/fine_for_loose_cargo = -100 + /// credits lost for sending a messy shuttle + var/fine_for_messy_shuttle = -100 + /// credits lost for sending unwanted items + var/fine_for_selling_trash = -100 /// points gained per virology goal var/credits_per_virology_goal = 200 @@ -150,8 +170,7 @@ SUBSYSTEM_DEF(economy) next_paycheck_delay = 30 MINUTES + world.time next_mail_delay = 15 MINUTES + world.time - for(var/obj/machinery/computer/pandemic/P in GLOB.pandemics) - P.print_goal_orders() + check_total_virology_goals_completion() /datum/controller/subsystem/economy/fire() if(next_paycheck_delay <= world.time) diff --git a/code/controllers/subsystem/SSjobs.dm b/code/controllers/subsystem/SSjobs.dm index 8c5a04e9a2c0..3efc1a1731fa 100644 --- a/code/controllers/subsystem/SSjobs.dm +++ b/code/controllers/subsystem/SSjobs.dm @@ -438,6 +438,9 @@ SUBSYSTEM_DEF(jobs) AssignRole(player, "Assistant") else AssignRole(player, "Assistant") + else if(length(player.mind.restricted_roles)) + stack_trace("A player with `restricted_roles` had no `special_role`. They are likely an antagonist, but failed to spawn in.") // this can be fixed by assigning a special_role in pre_setup of the gamemode + message_admins("A player mind ([player.mind]) is likely an antagonist, but may have failed to spawn in! Please report this to coders.") // Then we assign what we can to everyone else. for(var/mob/new_player/player in unassigned) diff --git a/code/controllers/subsystem/non_firing/SSmapping.dm b/code/controllers/subsystem/non_firing/SSmapping.dm index def0d7fffebc..4d51fd17c655 100644 --- a/code/controllers/subsystem/non_firing/SSmapping.dm +++ b/code/controllers/subsystem/non_firing/SSmapping.dm @@ -29,10 +29,10 @@ SUBSYSTEM_DEF(mapping) map_datum = text2path(lines[1]) map_datum = new map_datum catch - map_datum = new /datum/map/cyberiad // Assume cyberiad if non-existent + map_datum = new /datum/map/boxstation // Assume cyberiad if non-existent fdel("data/next_map.txt") // Remove to avoid the same map existing forever else - map_datum = new /datum/map/cyberiad // Assume cyberiad if non-existent + map_datum = new /datum/map/boxstation // Assume cyberiad if non-existent /datum/controller/subsystem/mapping/Shutdown() if(next_map) // Save map for next round @@ -76,6 +76,7 @@ SUBSYSTEM_DEF(mapping) seedRuins(list(level_name_to_num(MINING)), GLOB.configuration.ruins.lavaland_ruin_budget, /area/lavaland/surface/outdoors/unexplored, GLOB.lava_ruins_templates) if(lavaland_theme) lavaland_theme.setup() + lavaland_theme.setup_caves() var/time_spent = stop_watch(lavaland_setup_timer) log_startup_progress("Successfully populated lavaland in [time_spent]s.") else diff --git a/code/controllers/subsystem/tickets/mentor_tickets.dm b/code/controllers/subsystem/tickets/mentor_tickets.dm index 6b6af90bd7d1..41b5a9522892 100644 --- a/code/controllers/subsystem/tickets/mentor_tickets.dm +++ b/code/controllers/subsystem/tickets/mentor_tickets.dm @@ -26,6 +26,23 @@ GLOBAL_REAL(SSmentor_tickets, /datum/controller/subsystem/tickets/mentor_tickets "Please try to be as descriptive as possible in mentor helps. Mentors do not know the full situation you're in and need more information to give you a helpful response.", "Your [ticket_name] has now been closed.") + response_phrases = list("Known Bug" = "Unfortunately, that's a known bug. Hopefully it gets fixed soon.", + "TM Bug" = "Unfortunately, that's a bug with a current test merge. It should go away when the test merge is removed or fixed.", + "Clear Cache" = "To fix a blank screen, go to the 'Special Verbs' tab and press 'Reload UI Resources'. If that fails, clear your BYOND cache (instructions provided with 'Reload UI Resources'). If that still fails, please ask for help again, stating you have already done these steps.", + "Experiment!" = "Experiment! Part of the joy of this game is trying out various things, and dealing with the consequences if/when they go horribly wrong.", + "How to Objectives" = "There are lots of ways to accomplish your objectives as an antagonist. A direct frontal assault may work, provided you can get in and out before backup arrives. Sneaking in can work, too, as long as you're quick and avoid prying eyes. But don't forget roleplaying methods! Tricking your target into a maze of bear traps is much more interesting than just shooting them with a gun. Even if it fails, you and your target (or its guardians) are likely to have more fun this way, and that's the most important part.", + "MHelp was in Russian" = "Привет! Ты попал на английский Paradise сервер. Возможно, ты ошибся. Русский имеет такое название: SS220\[RU]." + ) + + if(GLOB.configuration.url.github_url) + response_phrases["New Bug"] = "That sounds like a bug! To report it, please go to our Github page. Then go to 'Issues', click 'New Issue', and fill out the report form. If the report would reveal current-round information, file it after the round ends." + + var/unsorted_responses = list() + for(var/key in response_phrases) //build a new list based on the short descriptive keys of the master list so we can send this as the input instead of the full paragraphs to the admin choosing which autoresponse + unsorted_responses += key + sorted_responses = sortTim(unsorted_responses, GLOBAL_PROC_REF(cmp_text_asc)) //use sortTim and cmp_text_asc to sort alphabetically + + /datum/controller/subsystem/tickets/mentor_tickets/message_staff(msg, prefix_type = NONE, important = FALSE) message_mentorTicket(msg, important) @@ -33,4 +50,25 @@ GLOBAL_REAL(SSmentor_tickets, /datum/controller/subsystem/tickets/mentor_tickets SStickets.newTicket(get_client_by_ckey(T.client_ckey), T.first_raw_response, T.title) /datum/controller/subsystem/tickets/mentor_tickets/autoRespond(N) - return + if(!check_rights(rights_needed)) + return + + var/datum/ticket/T = allTickets[N] + var/client/C = usr.client + if((T.staffAssigned && T.staffAssigned != C) || (T.lastStaffResponse && T.lastStaffResponse != C) || ((T.ticketState != TICKET_OPEN) && (T.ticketState != TICKET_STALE))) //if someone took this ticket, is it the same mentor who is autoresponding? if so, then skip the warning + if(alert(usr, "[T.ticketState == TICKET_OPEN ? "Another mentor appears to already be handling this." : "This ticket is already marked as closed or resolved"] Are you sure you want to continue?", "Confirmation", "Yes", "No") != "Yes") + return + T.assignStaff(C) + + var/message_key = input("Select an autoresponse. This will mark the ticket as resolved.", "Autoresponse") as null|anything in sortTim(sorted_responses, GLOBAL_PROC_REF(cmp_text_asc)) //use sortTim and cmp_text_asc to sort alphabetically + var/client/ticket_owner = get_client_by_ckey(T.client_ckey) + if(message_key == null) + T.staffAssigned = null //if they cancel we dont need to hold this ticket anymore + return + + SEND_SOUND(returnClient(N), sound('sound/effects/adminhelp.ogg')) + to_chat_safe(returnClient(N), "[key_name_hidden(C)] is autoresponding with: [response_phrases[message_key]]") //for this we want the full value of whatever key this is to tell the player so we do response_phrases[message_key] + message_staff("[C] has auto responded to [ticket_owner]\'s mentorhelp with: [message_key]") //we want to use the short named keys for this instead of the full sentence which is why we just do message_key + T.lastStaffResponse = "Autoresponse: [message_key]" + resolveTicket(N) + log_game("[C] has auto responded to [ticket_owner]\'s mentorhelp with: [response_phrases[message_key]]") diff --git a/code/controllers/subsystem/tickets/tickets.dm b/code/controllers/subsystem/tickets/tickets.dm index 655f6eda0868..a349ba9acf3d 100644 --- a/code/controllers/subsystem/tickets/tickets.dm +++ b/code/controllers/subsystem/tickets/tickets.dm @@ -1,15 +1,3 @@ -//Defines -//Deciseconds until ticket becomes stale if unanswered. Alerts admins. -#define TICKET_TIMEOUT 6000 // 10 minutes -//Decisecions before the user is allowed to open another ticket while their existing one is open. -#define TICKET_DUPLICATE_COOLDOWN 3000 // 5 minutes - -//Status defines -#define TICKET_OPEN 1 -#define TICKET_CLOSED 2 -#define TICKET_RESOLVED 3 -#define TICKET_STALE 4 - #define TICKET_STAFF_MESSAGE_ADMIN_CHANNEL 1 #define TICKET_STAFF_MESSAGE_PREFIX 2 @@ -44,6 +32,11 @@ SUBSYSTEM_DEF(tickets) /// DB ID for these tickets to be logged with var/db_save_id = "ADMIN" + // Autoresponse phrases. + var/response_phrases + // Autoresponse keys, in sorted order. + var/sorted_responses + /datum/controller/subsystem/tickets/get_metrics() . = ..() var/list/cust = list() @@ -55,6 +48,31 @@ SUBSYSTEM_DEF(tickets) "Please try to be calm, clear, and descriptive in admin helps, do not assume the staff member has seen any related events, and clearly state the names of anybody you are reporting. If you asked a question, please ensure it was clear what you were asking.", "Your [ticket_name] has now been closed.") + response_phrases = list("Thanks" = "Thanks for the ahelp!", + "Handling It" = "The issue is being looked into, thanks.", + "Already Resolved" = "The problem has been resolved already.", + "Mentorhelp" = "Please redirect your question to Mentorhelp, as they are better experienced with these types of questions.", + "Happens Again" = "Thanks, let us know if it continues to happen.", + "Clear Cache" = "To fix a blank screen, go to the 'Special Verbs' tab and press 'Reload UI Resources'. If that fails, clear your BYOND cache (instructions provided with 'Reload UI Resources'). If that still fails, please adminhelp again, stating you have already done the following." , + "IC Issue" = "This is an In Character (IC) issue and will not be handled by admins. You could speak to Security, Internal Affairs, a Departmental Head, Nanotrasen Representative, or any other relevant authority currently on station.", + "Reject" = "Reject", + "Man Up" = "Man Up", + ) + + if(GLOB.configuration.url.banappeals_url) + response_phrases["Appeal on the Forums"] = "Appealing a ban must occur on the forums. Privately messaging, or adminhelping about your ban will not resolve it. To appeal your ban, please head to [GLOB.configuration.url.banappeals_url]" + + if(GLOB.configuration.url.github_url) + response_phrases["Github Issue Report"] = "To report a bug, please go to our Github page. Then go to 'Issues'. Then 'New Issue'. Then fill out the report form. If the report would reveal current-round information, file it after the round ends." + + if(GLOB.configuration.url.exploit_url) + response_phrases["Exploit Report"] = "To report an exploit, please go to our Exploit Report page. Then 'Start New Topic'. Then fill out the topic with as much information about the exploit that you can. If possible, add steps taken to reproduce the exploit. The Development Team will be informed automatically of the post." + + var/unsorted_responses = list() + for(var/key in response_phrases) //build a new list based on the short descriptive keys of the master list so we can send this as the input instead of the full paragraphs to the admin choosing which autoresponse + unsorted_responses += key + sorted_responses = sortTim(unsorted_responses, GLOBAL_PROC_REF(cmp_text_asc)) //use sortTim and cmp_text_asc to sort alphabetically + /datum/controller/subsystem/tickets/fire() var/stales = checkStaleness() if(LAZYLEN(stales)) @@ -242,31 +260,8 @@ SUBSYSTEM_DEF(tickets) return T.assignStaff(C) - var/response_phrases = list("Thanks" = "Thanks for the ahelp!", - "Handling It" = "The issue is being looked into, thanks.", - "Already Resolved" = "The problem has been resolved already.", - "Mentorhelp" = "Please redirect your question to Mentorhelp, as they are better experienced with these types of questions.", - "Happens Again" = "Thanks, let us know if it continues to happen.", - "Clear Cache" = "To fix a blank screen, go to the 'Special Verbs' tab and press 'Reload UI Resources'. If that fails, clear your BYOND cache (instructions provided with 'Reload UI Resources'). If that still fails, please adminhelp again, stating you have already done the following." , - "IC Issue" = "This is an In Character (IC) issue and will not be handled by admins. You could speak to Security, Internal Affairs, a Departmental Head, Nanotrasen Representative, or any other relevant authority currently on station.", - "Reject" = "Reject", - "Man Up" = "Man Up", - ) - - if(GLOB.configuration.url.banappeals_url) - response_phrases["Appeal on the Forums"] = "Appealing a ban must occur on the forums. Privately messaging, or adminhelping about your ban will not resolve it. To appeal your ban, please head to [GLOB.configuration.url.banappeals_url]" - - if(GLOB.configuration.url.github_url) - response_phrases["Github Issue Report"] = "To report a bug, please go to our Github page. Then go to 'Issues'. Then 'New Issue'. Then fill out the report form. If the report would reveal current-round information, file it after the round ends." - - if(GLOB.configuration.url.exploit_url) - response_phrases["Exploit Report"] = "To report an exploit, please go to our Exploit Report page. Then 'Start New Topic'. Then fill out the topic with as much information about the exploit that you can. If possible, add steps taken to reproduce the exploit. The Development Team will be informed automatically of the post." - - var/sorted_responses = list() - for(var/key in response_phrases) //build a new list based on the short descriptive keys of the master list so we can send this as the input instead of the full paragraphs to the admin choosing which autoresponse - sorted_responses += key - var/message_key = input("Select an autoresponse. This will mark the ticket as resolved.", "Autoresponse") as null|anything in sortTim(sorted_responses, GLOBAL_PROC_REF(cmp_text_asc)) //use sortTim and cmp_text_asc to sort alphabetically + var/message_key = input("Select an autoresponse. This will mark the ticket as resolved.", "Autoresponse") as null|anything in sorted_responses var/client/ticket_owner = get_client_by_ckey(T.client_ckey) if(!ticket_owner) to_chat(C, "Can't respond to the ticket of a disconnected user.") diff --git a/code/datums/action.dm b/code/datums/action.dm index 7e1c0752ec85..cace288d1b8b 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -637,7 +637,7 @@ /datum/action/spell_action/New(Target) ..() - var/obj/effect/proc_holder/spell/S = target + var/datum/spell/S = target S.action = src name = S.name desc = S.desc @@ -648,7 +648,7 @@ /datum/action/spell_action/Destroy() - var/obj/effect/proc_holder/spell/S = target + var/datum/spell/S = target S.action = null return ..() @@ -656,27 +656,27 @@ if(!..()) return FALSE if(target) - var/obj/effect/proc_holder/spell = target + var/datum/spell/spell = target spell.Click() return TRUE /datum/action/spell_action/AltTrigger() if(target) - var/obj/effect/proc_holder/spell/spell = target + var/datum/spell/spell = target spell.AltClick(usr) return TRUE /datum/action/spell_action/IsAvailable() if(!target) return FALSE - var/obj/effect/proc_holder/spell/spell = target + var/datum/spell/spell = target if(owner) return spell.can_cast(owner) return FALSE /datum/action/spell_action/apply_unavailable_effect(atom/movable/screen/movable/action_button/button) - var/obj/effect/proc_holder/spell/S = target + var/datum/spell/S = target if(!istype(S)) return ..() diff --git a/code/datums/components/label.dm b/code/datums/components/label.dm index 0a8c50cdf71f..eba55631c5a5 100644 --- a/code/datums/components/label.dm +++ b/code/datums/components/label.dm @@ -52,8 +52,8 @@ * user: The mob who is wielding the attacking object. */ /datum/component/label/proc/OnAttackby(datum/source, obj/item/attacker, mob/user) - // If the attacking object is not a hand labeler or its mode is 1 (has a label ready to apply), return. - // The hand labeler should be off (mode is 0), in order to remove a label. + // If the attacking object is not a hand labeler or it's not off (has a label ready to apply), return. + // The hand labeler should be off in order to remove a label. var/obj/item/hand_labeler/labeler = attacker if(!istype(labeler) || labeler.mode) return @@ -85,3 +85,28 @@ var/atom/owner = parent owner.name = replacetext(owner.name, "([label_name])", "") // Remove the label text from the parent's name, wherever it's located. owner.name = trim(owner.name) // Shave off any white space from the beginning or end of the parent's name. + +/// A verson of the label component specific to labelling goal items. +/datum/component/label/goal + +/datum/component/label/goal/Initialize(_label_name) + if(istype(parent, /obj/item)) + // Can only be attached to things that won't go in a crate. + return COMPONENT_INCOMPATIBLE + return ..() + +/// Adds detailed information to the examine text. +/datum/component/label/goal/Examine(datum/source, mob/user, list/examine_list) + examine_list += "It has a label on it, marking it as part of a secondary goal for [label_name]. Use a hand labeler to remove it." + +/// Applies a static label to the parent's name. +/// We do this instead of using label_name so it's easier to identify goal objects at a glance. +/datum/component/label/goal/apply_label() + var/atom/owner = parent + owner.name += " (Secondary Goal)" + +/// Removes the label from the parent's name +/datum/component/label/goal/remove_label() + var/atom/owner = parent + owner.name = replacetext(owner.name, "(Secondary Goal)", "") // Remove the label text from the parent's name, wherever it's located. + owner.name = trim(owner.name) // Shave off any white space from the beginning or end of the parent's name. diff --git a/code/datums/diseases/_disease.dm b/code/datums/diseases/_disease.dm index 8a97ca442a3d..c296db3f7e20 100644 --- a/code/datums/diseases/_disease.dm +++ b/code/datums/diseases/_disease.dm @@ -108,12 +108,19 @@ GLOBAL_LIST_INIT(diseases, subtypesof(/datum/disease)) if(!(disease_flags & CURABLE)) return 0 - . = cures.len + var/cures_found = 0 for(var/C_id in cures) - if(!affected_mob.reagents.has_reagent(C_id)) - .-- - if(!. || (needs_all_cures && . < cures.len)) - return 0 + if(C_id == "ethanol") + for(var/datum/reagent/consumable/ethanol/booze in affected_mob.reagents.reagent_list) + cures_found++ + break + else if(affected_mob.reagents.has_reagent(C_id)) + cures_found++ + + if(needs_all_cures && cures_found < length(cures)) + return FALSE + + return cures_found /datum/disease/proc/spread(force_spread = 0) if(!affected_mob) diff --git a/code/datums/mind.dm b/code/datums/mind.dm index aeec45ce821f..6e721a5cf81f 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -166,7 +166,7 @@ if(ishuman(new_character)) var/mob/living/carbon/human/H = new_character if(H.mind in SSticker.mode.syndicates) - SSticker.mode.update_synd_icons_added() + SSticker.mode.update_synd_icons_added(H.mind) /datum/mind/proc/store_memory(new_text) memory += "[new_text]
" @@ -1059,7 +1059,7 @@ log_admin("[key_name(usr)] has removed [key_name(current)]'s vampire subclass.") message_admins("[key_name_admin(usr)] has removed [key_name_admin(current)]'s vampire subclass.") else - vamp.upgrade_tiers -= /obj/effect/proc_holder/spell/vampire/self/specialize + vamp.upgrade_tiers -= /datum/spell/vampire/self/specialize vamp.change_subclass(subclass_type) log_admin("[key_name(usr)] has removed [key_name(current)]'s vampire subclass.") message_admins("[key_name_admin(usr)] has removed [key_name_admin(current)]'s vampire subclass.") @@ -1683,14 +1683,14 @@ SEND_SOUND(H, sound('sound/ambience/antag/abductors.ogg')) H.create_log(MISC_LOG, "[H] was made into an abductor") -/datum/mind/proc/AddSpell(obj/effect/proc_holder/spell/S) +/datum/mind/proc/AddSpell(datum/spell/S) spell_list += S S.action.Grant(current) -/datum/mind/proc/RemoveSpell(obj/effect/proc_holder/spell/spell) //To remove a specific spell from a mind +/datum/mind/proc/RemoveSpell(datum/spell/spell) //To remove a specific spell from a mind if(!spell) return - for(var/obj/effect/proc_holder/spell/S in spell_list) + for(var/datum/spell/S in spell_list) if(istype(S, spell)) qdel(S) spell_list -= S @@ -1703,7 +1703,7 @@ /datum/mind/proc/transfer_mindbound_actions(mob/living/new_character) for(var/X in spell_list) - var/obj/effect/proc_holder/spell/S = X + var/datum/spell/S = X if(!S.on_mind_transfer(new_character)) current.RemoveSpell(S) continue diff --git a/code/datums/outfits/outfit_admin.dm b/code/datums/outfits/outfit_admin.dm index be801b2a4094..dd4a79475a68 100644 --- a/code/datums/outfits/outfit_admin.dm +++ b/code/datums/outfits/outfit_admin.dm @@ -1414,8 +1414,8 @@ box = /obj/item/storage/box/wizard //The spells that the enforcer has. - var/list/spell_paths = list(/obj/effect/proc_holder/spell/aoe/conjure/summon_supermatter, - /obj/effect/proc_holder/spell/charge_up/bounce/lightning, /obj/effect/proc_holder/spell/summonitem) + var/list/spell_paths = list(/datum/spell/aoe/conjure/summon_supermatter, + /datum/spell/charge_up/bounce/lightning, /datum/spell/summonitem) /datum/outfit/admin/enforcer/post_equip(mob/living/carbon/human/H) . = ..() diff --git a/code/datums/spell.dm b/code/datums/spell.dm index e20a939e364f..cc6a40a91ad5 100644 --- a/code/datums/spell.dm +++ b/code/datums/spell.dm @@ -1,29 +1,9 @@ -/obj/effect/proc_holder - var/panel = "Debug"//What panel the proc holder needs to go on. - var/active = FALSE //Used by toggle based abilities. - var/ranged_mousepointer - var/mob/ranged_ability_user - -/obj/effect/proc_holder/singularity_act() - return - -/obj/effect/proc_holder/singularity_pull() - return - -GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) - -/obj/effect/proc_holder/proc/InterceptClickOn(mob/user, params, atom/A) - if(user.ranged_ability != src) - to_chat(user, "[user.ranged_ability.name] has been disabled.") - user.ranged_ability.remove_ranged_ability(user) - return TRUE //TRUE for failed, FALSE for passed. - user.face_atom(A) - return FALSE +GLOBAL_LIST_INIT(spells, typesof(/datum/spell)) /datum/click_intercept/proc_holder - var/obj/effect/proc_holder/spell + var/datum/spell/spell -/datum/click_intercept/proc_holder/New(client/C, obj/effect/proc_holder/spell_to_cast) +/datum/click_intercept/proc_holder/New(client/C, datum/spell/spell_to_cast) . = ..() spell = spell_to_cast @@ -34,7 +14,15 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) spell.remove_ranged_ability(spell.ranged_ability_user) return ..() -/obj/effect/proc_holder/proc/add_ranged_ability(mob/user, msg) +/datum/spell/proc/InterceptClickOn(mob/user, params, atom/A) + if(user.ranged_ability != src) + to_chat(user, "[user.ranged_ability.name] has been disabled.") + user.ranged_ability.remove_ranged_ability(user) + return TRUE //TRUE for failed, FALSE for passed. + user.face_atom(A) + return FALSE + +/datum/spell/proc/add_ranged_ability(mob/user, msg) if(!user || !user.client) return if(user.ranged_ability && user.ranged_ability != src) @@ -47,17 +35,20 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) active = TRUE if(msg) to_chat(user, msg) - update_icon() + update_spell_icon() -/obj/effect/proc_holder/proc/add_mousepointer(client/C) +/datum/spell/proc/update_spell_icon() + return + +/datum/spell/proc/add_mousepointer(client/C) if(C && ranged_mousepointer && C.mouse_pointer_icon == initial(C.mouse_pointer_icon)) C.mouse_pointer_icon = ranged_mousepointer -/obj/effect/proc_holder/proc/remove_mousepointer(client/C) +/datum/spell/proc/remove_mousepointer(client/C) if(C && ranged_mousepointer && C.mouse_pointer_icon == ranged_mousepointer) C.mouse_pointer_icon = initial(C.mouse_pointer_icon) -/obj/effect/proc_holder/proc/remove_ranged_ability(mob/user, msg) +/datum/spell/proc/remove_ranged_ability(mob/user, msg) if(!user || (user.ranged_ability && user.ranged_ability != src)) //To avoid removing the wrong ability return user.ranged_ability = null @@ -69,14 +60,12 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) remove_mousepointer(user.client) if(msg) to_chat(user, msg) - update_icon() + update_spell_icon() -/obj/effect/proc_holder/spell - name = "Spell" // Only rename this if the spell you're making is not abstract - desc = "A wizard spell" - panel = "Spells"//What panel the proc holder needs to go on. - density = FALSE - opacity = FALSE +/datum/spell + var/name = "Spell" // Only rename this if the spell you're making is not abstract + var/desc = "A wizard spell" + var/panel = "Spells"//What panel the proc holder needs to go on. var/school = "evocation" //not relevant at now, but may be important later if there are changes to how spells work. the ones I used for now will probably be changed... maybe spell presets? lacking flexibility but with some other benefit? ///recharge time in deciseconds @@ -87,6 +76,9 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) var/holder_var_type = "bruteloss" //only used if charge_type equals to "holder_var" var/holder_var_amount = 20 //same. The amount adjusted with the mob's var when the spell is used + var/active = FALSE //Used by toggle based abilities. + var/ranged_mousepointer + var/mob/ranged_ability_user var/ghost = FALSE // Skip life check. var/clothes_req = TRUE //see if it requires clothes @@ -153,7 +145,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) * @param start_recharge If the proc should set the cooldown * @param user The caster of the spell */ -/obj/effect/proc_holder/spell/proc/cast_check(charge_check = TRUE, start_recharge = TRUE, mob/user = usr) //checks if the spell can be cast based on its settings; skipcharge is used when an additional cast_check is called inside the spell +/datum/spell/proc/cast_check(charge_check = TRUE, start_recharge = TRUE, mob/user = usr) //checks if the spell can be cast based on its settings; skipcharge is used when an additional cast_check is called inside the spell // SHOULD_NOT_OVERRIDE(TRUE) Todo for another refactor if(!can_cast(user, charge_check, TRUE)) return FALSE @@ -178,7 +170,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) * * target - Who is being considered * * user - Who is the user of this spell */ -/obj/effect/proc_holder/spell/proc/valid_target(target, user) +/datum/spell/proc/valid_target(target, user) return TRUE /** @@ -187,7 +179,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) * Arguments: * * user - Who used this spell? */ -/obj/effect/proc_holder/spell/proc/spend_spell_cost(mob/user) +/datum/spell/proc/spend_spell_cost(mob/user) SHOULD_CALL_PARENT(TRUE) custom_handler?.spend_spell_cost(user, src) @@ -195,7 +187,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) if(action) action.UpdateButtons() -/obj/effect/proc_holder/spell/proc/invocation(mob/user) //spelling the spell out and setting it on recharge/reducing charges amount +/datum/spell/proc/invocation(mob/user) //spelling the spell out and setting it on recharge/reducing charges amount switch(invocation_type) if("shout") if(!user.IsVocal() || user.cannot_speak_loudly()) @@ -213,10 +205,10 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) if("emote") user.visible_message(invocation, invocation_emote_self) //same style as in mob/living/emote.dm -/obj/effect/proc_holder/spell/proc/playMagSound() +/datum/spell/proc/playMagSound() playsound(get_turf(usr), sound,50,1) -/obj/effect/proc_holder/spell/New() +/datum/spell/New() ..() action = new(src) still_recharging_msg = "[name] is still recharging." @@ -236,7 +228,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) cooldown_handler = create_new_cooldown() cooldown_handler.cooldown_init(src) -/obj/effect/proc_holder/spell/Destroy() +/datum/spell/Destroy() QDEL_NULL(action) QDEL_NULL(cooldown_handler) return ..() @@ -245,7 +237,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) * Creates and returns the targeting datum for this spell type. Override this! * Should return a value of type [/datum/spell_targeting] */ -/obj/effect/proc_holder/spell/proc/create_new_targeting() +/datum/spell/proc/create_new_targeting() RETURN_TYPE(/datum/spell_targeting) return @@ -254,7 +246,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) * Override this if you want a custom spell handler. * Should return a value of type [/datum/spell_handler] or NONE */ -/obj/effect/proc_holder/spell/proc/create_new_handler() +/datum/spell/proc/create_new_handler() RETURN_TYPE(/datum/spell_handler) return NONE @@ -263,29 +255,30 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) * Override this if you wish to use a different method of cooldown */ -/obj/effect/proc_holder/spell/proc/create_new_cooldown() +/datum/spell/proc/create_new_cooldown() RETURN_TYPE(/datum/spell_cooldown) var/datum/spell_cooldown/S = new S.recharge_duration = base_cooldown S.starts_off_cooldown = starts_charged return S -/obj/effect/proc_holder/spell/Click() +/datum/spell/proc/Click() if(cast_check(TRUE, FALSE, usr)) choose_targets(usr) return 1 -/obj/effect/proc_holder/spell/AltClick(mob/user) +/datum/spell/proc/AltClick(mob/user) return Click() -/obj/effect/proc_holder/spell/InterceptClickOn(mob/user, params, atom/A) +/datum/spell/InterceptClickOn(mob/user, params, atom/A) . = ..() if(.) return - targeting.InterceptClickOn(user, params, A, src) + if(targeting) + targeting.InterceptClickOn(user, params, A, src) ///Lets the spell have a special effect applied to it when upgraded. By default, does nothing. -/obj/effect/proc_holder/spell/proc/on_purchase_upgrade() +/datum/spell/proc/on_purchase_upgrade() return /** @@ -295,7 +288,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) * Arguments: * * user - The caster of the spell */ -/obj/effect/proc_holder/spell/proc/choose_targets(mob/user) +/datum/spell/proc/choose_targets(mob/user) SHOULD_NOT_OVERRIDE(TRUE) if(targeting.use_intercept_click) if(active) @@ -317,7 +310,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) * * targets - The targets the spell is being performed on * * user - The caster of the spell */ -/obj/effect/proc_holder/spell/proc/try_perform(list/targets, mob/user) +/datum/spell/proc/try_perform(list/targets, mob/user) SHOULD_NOT_OVERRIDE(TRUE) if(!length(targets)) to_chat(user, "No suitable target found.") @@ -333,7 +326,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) * Called in `try_perform` before removing the click interceptor. useful to override if you have a spell that requires more than 1 click */ -/obj/effect/proc_holder/spell/proc/should_remove_click_intercept() +/datum/spell/proc/should_remove_click_intercept() return TRUE /** @@ -344,7 +337,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) * * recharge - Whether or not the spell should go recharge * * user - The caster of the spell */ -/obj/effect/proc_holder/spell/proc/perform(list/targets, recharge = TRUE, mob/user = usr) //if recharge is started is important for the trigger spells +/datum/spell/proc/perform(list/targets, recharge = TRUE, mob/user = usr) //if recharge is started is important for the trigger spells SHOULD_NOT_OVERRIDE(TRUE) before_cast(targets, user) invocation(user) @@ -371,11 +364,10 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) * * targets - The targets being targeted by the spell * * user - The user of the spell */ -/obj/effect/proc_holder/spell/proc/write_custom_logs(list/targets, mob/user) +/datum/spell/proc/write_custom_logs(list/targets, mob/user) return - -/obj/effect/proc_holder/spell/proc/before_cast(list/targets, mob/user) +/datum/spell/proc/before_cast(list/targets, mob/user) SHOULD_CALL_PARENT(TRUE) if(overlay) for(var/atom/target in targets) @@ -394,7 +386,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) custom_handler?.before_cast(targets, user, src) -/obj/effect/proc_holder/spell/proc/after_cast(list/targets, mob/user) +/datum/spell/proc/after_cast(list/targets, mob/user) SHOULD_CALL_PARENT(TRUE) for(var/atom/target in targets) var/location @@ -427,21 +419,21 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) * * targets - The targets being targeted by the spell * * user - The caster of the spell */ -/obj/effect/proc_holder/spell/proc/cast(list/targets, mob/user = usr) +/datum/spell/proc/cast(list/targets, mob/user = usr) return -/obj/effect/proc_holder/spell/proc/revert_cast(mob/user = usr) //resets recharge or readds a charge +/datum/spell/proc/revert_cast(mob/user = usr) //resets recharge or readds a charge cooldown_handler.revert_cast() custom_handler?.revert_cast(user, src) if(action) action.UpdateButtons() -/obj/effect/proc_holder/spell/proc/UpdateButtons() +/datum/spell/proc/UpdateButtons() if(action) action.UpdateButtons() -/obj/effect/proc_holder/spell/proc/adjust_var(mob/living/target = usr, type, amount) //handles the adjustment of the var when the spell is used. has some hardcoded types +/datum/spell/proc/adjust_var(mob/living/target = usr, type, amount) //handles the adjustment of the var when the spell is used. has some hardcoded types switch(type) if("bruteloss") target.adjustBruteLoss(amount) @@ -462,10 +454,10 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) return ///This proc is ran when a mind is transfered to a new mob. Tells it if the action should be transfered on return true, and tells it not to remove it on false -/obj/effect/proc_holder/spell/proc/on_mind_transfer(mob/living/L) +/datum/spell/proc/on_mind_transfer(mob/living/L) return TRUE -/obj/effect/proc_holder/spell/aoe +/datum/spell/aoe name = "Spell" create_attack_logs = FALSE create_custom_logs = TRUE @@ -474,10 +466,10 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) // Normally, AoE spells will generate an attack log for every turf they loop over, while searching for targets. // With this override, all /aoe type spells will only generate 1 log, saying that the user has cast the spell. -/obj/effect/proc_holder/spell/aoe/write_custom_logs(list/targets, mob/user) +/datum/spell/aoe/write_custom_logs(list/targets, mob/user) add_attack_logs(user, null, "Cast the AoE spell [name]", ATKLOG_ALL) -/obj/effect/proc_holder/spell/proc/can_cast(mob/user = usr, charge_check = TRUE, show_message = FALSE) +/datum/spell/proc/can_cast(mob/user = usr, charge_check = TRUE, show_message = FALSE) if(((!user.mind) || !(src in user.mind.spell_list)) && !(src in user.mob_spell_list)) if(show_message) to_chat(user, "You shouldn't have this spell! Something's wrong.") @@ -509,8 +501,8 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) if(ishuman(user)) var/mob/living/carbon/human/H = user - var/clothcheck = locate(/obj/effect/proc_holder/spell/noclothes) in user.mob_spell_list - var/clothcheck2 = user.mind && (locate(/obj/effect/proc_holder/spell/noclothes) in user.mind.spell_list) + var/clothcheck = locate(/datum/spell/noclothes) in user.mob_spell_list + var/clothcheck2 = user.mind && (locate(/datum/spell/noclothes) in user.mind.spell_list) if(clothes_req && !clothcheck && !clothcheck2) //clothes check var/obj/item/clothing/robe = H.wear_suit var/obj/item/clothing/hat = H.head @@ -538,7 +530,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) return TRUE -/obj/effect/proc_holder/spell/summonmob +/datum/spell/summonmob name = "Summon Servant" desc = "This spell can be used to call your servant, whenever you need it." base_cooldown = 10 SECONDS @@ -552,10 +544,10 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) action_icon_state = "summons" -/obj/effect/proc_holder/spell/summonmob/create_new_targeting() +/datum/spell/summonmob/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/summonmob/cast(list/targets, mob/user = usr) +/datum/spell/summonmob/cast(list/targets, mob/user = usr) if(!target_mob) return var/turf/Start = get_turf(user) diff --git a/code/datums/spell_cooldown/spell_charges.dm b/code/datums/spell_cooldown/spell_charges.dm index bdbe9230405b..577da557060e 100644 --- a/code/datums/spell_cooldown/spell_charges.dm +++ b/code/datums/spell_cooldown/spell_charges.dm @@ -8,7 +8,7 @@ /// the time at which a spell charge can be used var/charge_time -/datum/spell_cooldown/charges/cooldown_init(obj/effect/proc_holder/spell/new_spell) +/datum/spell_cooldown/charges/cooldown_init(datum/spell/new_spell) . = ..() if(starts_off_cooldown) current_charges = max_charges diff --git a/code/datums/spell_cooldown/spell_cooldown.dm b/code/datums/spell_cooldown/spell_cooldown.dm index 68f935e5f005..14936e893ac3 100644 --- a/code/datums/spell_cooldown/spell_cooldown.dm +++ b/code/datums/spell_cooldown/spell_cooldown.dm @@ -6,13 +6,13 @@ /// does it start off cooldown? var/starts_off_cooldown = TRUE /// holds a ref to the spell - var/obj/effect/proc_holder/spell/spell_parent + var/datum/spell/spell_parent /datum/spell_cooldown/Destroy() spell_parent = null return ..() -/datum/spell_cooldown/proc/cooldown_init(obj/effect/proc_holder/spell/new_spell) +/datum/spell_cooldown/proc/cooldown_init(datum/spell/new_spell) spell_parent = new_spell if(!starts_off_cooldown) start_recharge() diff --git a/code/datums/spell_handler/alien_spell_handler.dm b/code/datums/spell_handler/alien_spell_handler.dm index 2402653e1024..b8aa1e7cbcc2 100644 --- a/code/datums/spell_handler/alien_spell_handler.dm +++ b/code/datums/spell_handler/alien_spell_handler.dm @@ -8,24 +8,24 @@ This was also the case with the verb implementation, it's just much more obvious /// Amount of plasma required to use this ability var/plasma_cost = 0 -/datum/spell_handler/alien/can_cast(mob/living/carbon/user, charge_check, show_message, obj/effect/proc_holder/spell/spell) +/datum/spell_handler/alien/can_cast(mob/living/carbon/user, charge_check, show_message, datum/spell/spell) var/obj/item/organ/internal/alien/plasmavessel/vessel = user.get_int_organ(/obj/item/organ/internal/alien/plasmavessel) if(!vessel) - return 0 + return FALSE if(vessel.stored_plasma < plasma_cost) if(show_message) to_chat(user, "You require at least [plasma_cost] plasma to use this ability!") return FALSE return TRUE -/datum/spell_handler/alien/spend_spell_cost(mob/living/carbon/user, obj/effect/proc_holder/spell/spell) +/datum/spell_handler/alien/spend_spell_cost(mob/living/carbon/user, datum/spell/spell) user.use_plasma_spell(plasma_cost, user) -/datum/spell_handler/alien/before_cast(list/targets, mob/living/carbon/user, obj/effect/proc_holder/spell/spell) +/datum/spell_handler/alien/before_cast(list/targets, mob/living/carbon/user, datum/spell/spell) to_chat(user, "You have [user.get_plasma()] plasma left to use.") user.update_plasma_display(user) -/datum/spell_handler/alien/revert_cast(mob/living/carbon/user, obj/effect/proc_holder/spell/spell) +/datum/spell_handler/alien/revert_cast(mob/living/carbon/user, datum/spell/spell) user.add_plasma(plasma_cost, user) to_chat(user, "You have [user.get_plasma()] plasma left to use.") user.update_plasma_display(user) diff --git a/code/datums/spell_handler/morph_spell_handler.dm b/code/datums/spell_handler/morph_spell_handler.dm index 688c2a62e0d0..36b796583074 100644 --- a/code/datums/spell_handler/morph_spell_handler.dm +++ b/code/datums/spell_handler/morph_spell_handler.dm @@ -2,7 +2,7 @@ /// How much food it costs the morph to use this var/hunger_cost = 0 -/datum/spell_handler/morph/can_cast(mob/living/simple_animal/hostile/morph/user, charge_check, show_message, obj/effect/proc_holder/spell/spell) +/datum/spell_handler/morph/can_cast(mob/living/simple_animal/hostile/morph/user, charge_check, show_message, datum/spell/spell) if(!istype(user)) if(show_message) to_chat(user, "You should not be able to use this abilty! Report this as a bug on github please.") @@ -15,13 +15,13 @@ return TRUE -/datum/spell_handler/morph/spend_spell_cost(mob/living/simple_animal/hostile/morph/user, obj/effect/proc_holder/spell/spell) +/datum/spell_handler/morph/spend_spell_cost(mob/living/simple_animal/hostile/morph/user, datum/spell/spell) user.use_food(hunger_cost) -/datum/spell_handler/morph/before_cast(list/targets, mob/living/simple_animal/hostile/morph/user, obj/effect/proc_holder/spell/spell) +/datum/spell_handler/morph/before_cast(list/targets, mob/living/simple_animal/hostile/morph/user, datum/spell/spell) if(hunger_cost) to_chat(user, "You have [user.gathered_food] left to use.") -/datum/spell_handler/morph/revert_cast(mob/living/simple_animal/hostile/morph/user, obj/effect/proc_holder/spell/spell) +/datum/spell_handler/morph/revert_cast(mob/living/simple_animal/hostile/morph/user, datum/spell/spell) user.add_food(hunger_cost) to_chat(user, "You have [user.gathered_food] left to use.") diff --git a/code/datums/spell_handler/spell_handler.dm b/code/datums/spell_handler/spell_handler.dm index e11aa76f9fdb..d5da3e07d981 100644 --- a/code/datums/spell_handler/spell_handler.dm +++ b/code/datums/spell_handler/spell_handler.dm @@ -6,17 +6,17 @@ /datum/spell_handler -/datum/spell_handler/proc/can_cast(mob/user, charge_check, show_message, obj/effect/proc_holder/spell/spell) +/datum/spell_handler/proc/can_cast(mob/user, charge_check, show_message, datum/spell/spell) return TRUE -/datum/spell_handler/proc/spend_spell_cost(mob/user, obj/effect/proc_holder/spell/spell) +/datum/spell_handler/proc/spend_spell_cost(mob/user, datum/spell/spell) return -/datum/spell_handler/proc/revert_cast(mob/user, obj/effect/proc_holder/spell/spell) +/datum/spell_handler/proc/revert_cast(mob/user, datum/spell/spell) return -/datum/spell_handler/proc/before_cast(list/targets, mob/user, obj/effect/proc_holder/spell/spell) +/datum/spell_handler/proc/before_cast(list/targets, mob/user, datum/spell/spell) return -/datum/spell_handler/proc/after_cast(list/targets, mob/user, obj/effect/proc_holder/spell/spell) +/datum/spell_handler/proc/after_cast(list/targets, mob/user, datum/spell/spell) return diff --git a/code/datums/spell_handler/vampire.dm b/code/datums/spell_handler/vampire.dm index e23275f072e2..d22a4576beed 100644 --- a/code/datums/spell_handler/vampire.dm +++ b/code/datums/spell_handler/vampire.dm @@ -3,7 +3,7 @@ /// If the blood cost should be handled by this handler. Or if the spell will handle it itself var/deduct_blood_on_cast = TRUE -/datum/spell_handler/vampire/can_cast(mob/user, charge_check, show_message, obj/effect/proc_holder/spell/spell) +/datum/spell_handler/vampire/can_cast(mob/user, charge_check, show_message, datum/spell/spell) var/datum/antagonist/vampire/vampire = user.mind.has_antag_datum(/datum/antagonist/vampire) if(!vampire) @@ -31,7 +31,7 @@ return FALSE return TRUE -/datum/spell_handler/vampire/spend_spell_cost(mob/user, obj/effect/proc_holder/spell/spell) +/datum/spell_handler/vampire/spend_spell_cost(mob/user, datum/spell/spell) if(!required_blood || !deduct_blood_on_cast) //don't take the blood yet if this is false! return @@ -44,7 +44,7 @@ var/blood_cost = round(required_blood * blood_cost_modifier) return blood_cost -/datum/spell_handler/vampire/after_cast(list/targets, mob/user, obj/effect/proc_holder/spell/spell) +/datum/spell_handler/vampire/after_cast(list/targets, mob/user, datum/spell/spell) if(!spell.should_recharge_after_cast) return if(!required_blood) diff --git a/code/datums/spell_targeting/alive_mobs.dm b/code/datums/spell_targeting/alive_mobs.dm index da4c01870b95..8a87a86002a1 100644 --- a/code/datums/spell_targeting/alive_mobs.dm +++ b/code/datums/spell_targeting/alive_mobs.dm @@ -4,7 +4,7 @@ /datum/spell_targeting/alive_mob_list allowed_type = /mob/living -/datum/spell_targeting/alive_mob_list/choose_targets(mob/user, obj/effect/proc_holder/spell/spell, params, atom/clicked_atom) +/datum/spell_targeting/alive_mob_list/choose_targets(mob/user, datum/spell/spell, params, atom/clicked_atom) var/list/possible_targets = list() for(var/mob/living/possible_target as anything in GLOB.alive_mob_list) if(valid_target(possible_target, user, spell, FALSE)) diff --git a/code/datums/spell_targeting/aoe.dm b/code/datums/spell_targeting/aoe.dm index 306a59798d14..d5cacf060d9c 100644 --- a/code/datums/spell_targeting/aoe.dm +++ b/code/datums/spell_targeting/aoe.dm @@ -6,7 +6,7 @@ /// The radius of turfs not being affected. -1 is inactive var/inner_radius = -1 -/datum/spell_targeting/aoe/choose_targets(mob/user, obj/effect/proc_holder/spell/spell, params, atom/clicked_atom) +/datum/spell_targeting/aoe/choose_targets(mob/user, datum/spell/spell, params, atom/clicked_atom) var/list/targets = list() var/spell_center = use_turf_of_user ? get_turf(user) : user diff --git a/code/datums/spell_targeting/click_spell_targeting.dm b/code/datums/spell_targeting/click_spell_targeting.dm index 5d8ffcb74e87..6901e65b86f3 100644 --- a/code/datums/spell_targeting/click_spell_targeting.dm +++ b/code/datums/spell_targeting/click_spell_targeting.dm @@ -9,7 +9,7 @@ var/random_target_priority = SPELL_TARGET_CLOSEST -/datum/spell_targeting/click/choose_targets(mob/user, obj/effect/proc_holder/spell/spell, params, atom/clicked_atom) +/datum/spell_targeting/click/choose_targets(mob/user, datum/spell/spell, params, atom/clicked_atom) var/list/targets = list() if(valid_target(clicked_atom, user, spell)) targets.Add(clicked_atom) diff --git a/code/datums/spell_targeting/clicked_atom.dm b/code/datums/spell_targeting/clicked_atom.dm index d851edf993ec..57bdd86df783 100644 --- a/code/datums/spell_targeting/clicked_atom.dm +++ b/code/datums/spell_targeting/clicked_atom.dm @@ -4,11 +4,11 @@ /datum/spell_targeting/clicked_atom use_intercept_click = TRUE -/datum/spell_targeting/clicked_atom/choose_targets(mob/user, obj/effect/proc_holder/spell/spell, params, atom/clicked_atom) +/datum/spell_targeting/clicked_atom/choose_targets(mob/user, datum/spell/spell, params, atom/clicked_atom) if(clicked_atom) return list(clicked_atom) -/datum/spell_targeting/clicked_atom/external/choose_targets(mob/user, obj/effect/proc_holder/spell/spell, params, atom/clicked_atom) +/datum/spell_targeting/clicked_atom/external/choose_targets(mob/user, datum/spell/spell, params, atom/clicked_atom) . = ..() if(!.) return list() diff --git a/code/datums/spell_targeting/matter_eater_targeting.dm b/code/datums/spell_targeting/matter_eater_targeting.dm index d13449812dc9..7592f5a0b23f 100644 --- a/code/datums/spell_targeting/matter_eater_targeting.dm +++ b/code/datums/spell_targeting/matter_eater_targeting.dm @@ -25,7 +25,7 @@ /obj/item/bio_chip ) -/datum/spell_targeting/matter_eater/choose_targets(mob/user, obj/effect/proc_holder/spell/spell, params, atom/clicked_atom) +/datum/spell_targeting/matter_eater/choose_targets(mob/user, datum/spell/spell, params, atom/clicked_atom) var/list/possible_targets = list() for(var/atom/movable/O in view_or_range(range, user, selection_type)) diff --git a/code/datums/spell_targeting/reachable_turfs.dm b/code/datums/spell_targeting/reachable_turfs.dm index df2de0204b9b..3e7c754ccf87 100644 --- a/code/datums/spell_targeting/reachable_turfs.dm +++ b/code/datums/spell_targeting/reachable_turfs.dm @@ -3,7 +3,7 @@ */ /datum/spell_targeting/reachable_turfs -/datum/spell_targeting/reachable_turfs/choose_targets(mob/user, obj/effect/proc_holder/spell/spell, params, atom/clicked_atom) +/datum/spell_targeting/reachable_turfs/choose_targets(mob/user, datum/spell/spell, params, atom/clicked_atom) var/list/turf/locs = list() for(var/direction in GLOB.alldirs) if(length(locs) == max_targets) //we found 2 locations and thats all we need diff --git a/code/datums/spell_targeting/remoteview_targeting.dm b/code/datums/spell_targeting/remoteview_targeting.dm index fce68b121810..78d525ef27fc 100644 --- a/code/datums/spell_targeting/remoteview_targeting.dm +++ b/code/datums/spell_targeting/remoteview_targeting.dm @@ -3,7 +3,7 @@ */ /datum/spell_targeting/remoteview -/datum/spell_targeting/remoteview/choose_targets(mob/user, obj/effect/proc_holder/spell/spell, params, atom/clicked_atom) +/datum/spell_targeting/remoteview/choose_targets(mob/user, datum/spell/spell, params, atom/clicked_atom) var/list/remoteviewers = list() for(var/mob/M in GLOB.alive_mob_list) if(M == user) diff --git a/code/datums/spell_targeting/self_targeting.dm b/code/datums/spell_targeting/self_targeting.dm index a1facb7462f1..15136c2ead0f 100644 --- a/code/datums/spell_targeting/self_targeting.dm +++ b/code/datums/spell_targeting/self_targeting.dm @@ -3,5 +3,5 @@ */ /datum/spell_targeting/self -/datum/spell_targeting/self/choose_targets(mob/user, obj/effect/proc_holder/spell/spell, params, atom/clicked_atom) +/datum/spell_targeting/self/choose_targets(mob/user, datum/spell/spell, params, atom/clicked_atom) return list(user) // That's how simple it is diff --git a/code/datums/spell_targeting/spell_targeting.dm b/code/datums/spell_targeting/spell_targeting.dm index 37a379a8acbd..5183dd73fb4f 100644 --- a/code/datums/spell_targeting/spell_targeting.dm +++ b/code/datums/spell_targeting/spell_targeting.dm @@ -34,14 +34,14 @@ * * params - Params given by the intercept click. Only available if use_intercept_click is TRUE * * clicked_atom - The atom clicked on. Only available if use_intercept_click is TRUE */ -/datum/spell_targeting/proc/choose_targets(mob/user, obj/effect/proc_holder/spell/spell, params, atom/clicked_atom) +/datum/spell_targeting/proc/choose_targets(mob/user, datum/spell/spell, params, atom/clicked_atom) RETURN_TYPE(/list) return /** * Will attempt to auto target the spell. Only works with 1 target currently */ -/datum/spell_targeting/proc/attempt_auto_target(mob/user, obj/effect/proc_holder/spell/spell) +/datum/spell_targeting/proc/attempt_auto_target(mob/user, datum/spell/spell) var/atom/target for(var/atom/A in view_or_range(range, use_turf_of_user ? get_turf(user) : user, selection_type)) if(valid_target(A, user, spell, FALSE)) @@ -64,7 +64,7 @@ * * A - Atom the user clicked on * * spell - The spell being cast */ -/datum/spell_targeting/proc/InterceptClickOn(mob/user, params, atom/A, obj/effect/proc_holder/spell/spell) +/datum/spell_targeting/proc/InterceptClickOn(mob/user, params, atom/A, datum/spell/spell) var/list/targets = choose_targets(user, spell, params, A) spell.try_perform(targets, user) @@ -77,7 +77,7 @@ * * spell - The spell being cast * * check_if_in_range - If a view/range check has to be done to see if the target is valid */ -/datum/spell_targeting/proc/valid_target(target, user, obj/effect/proc_holder/spell/spell, check_if_in_range = TRUE) +/datum/spell_targeting/proc/valid_target(target, user, datum/spell/spell, check_if_in_range = TRUE) SHOULD_CALL_PARENT(TRUE) return istype(target, allowed_type) && (include_user || target != user) && \ spell.valid_target(target, user) && (!check_if_in_range || (target in view_or_range(range, use_turf_of_user ? get_turf(user) : user, selection_type))) \ diff --git a/code/datums/spell_targeting/targeted.dm b/code/datums/spell_targeting/targeted.dm index 2f6871324176..94ae8bd847b5 100644 --- a/code/datums/spell_targeting/targeted.dm +++ b/code/datums/spell_targeting/targeted.dm @@ -9,7 +9,7 @@ /// Who to target when too many targets are found. Only matters when max_targets = 1 var/target_priority = SPELL_TARGET_CLOSEST -/datum/spell_targeting/targeted/choose_targets(mob/user, obj/effect/proc_holder/spell/spell, params, atom/clicked_atom) +/datum/spell_targeting/targeted/choose_targets(mob/user, datum/spell/spell, params, atom/clicked_atom) var/list/targets = list() var/list/possible_targets = list() var/atom/spell_location = use_turf_of_user ? get_turf(user) : user diff --git a/code/datums/spell_targeting/telepathic.dm b/code/datums/spell_targeting/telepathic.dm index c6c739fe0f1a..95ee241e98a5 100644 --- a/code/datums/spell_targeting/telepathic.dm +++ b/code/datums/spell_targeting/telepathic.dm @@ -3,7 +3,7 @@ */ /datum/spell_targeting/telepathic -/datum/spell_targeting/telepathic/choose_targets(mob/user, obj/effect/proc_holder/spell/spell, params, atom/clicked_atom) +/datum/spell_targeting/telepathic/choose_targets(mob/user, datum/spell/spell, params, atom/clicked_atom) var/list/valid_targets = list() var/turf/T = get_turf(user) var/list/mobs_in_view = user.get_visible_mobs() diff --git a/code/datums/spells/alien_spells/basetype_alien_spell.dm b/code/datums/spells/alien_spells/basetype_alien_spell.dm index f192962592ec..547cba3c4389 100644 --- a/code/datums/spells/alien_spells/basetype_alien_spell.dm +++ b/code/datums/spells/alien_spells/basetype_alien_spell.dm @@ -17,7 +17,7 @@ Updates the spell's actions on use as well, so they know when they can or can't for(var/datum/action/spell_action/action in actions) action.UpdateButtons() -/obj/effect/proc_holder/spell/alien_spell +/datum/spell/alien_spell action_background_icon_state = "bg_alien" clothes_req = FALSE base_cooldown = 0 @@ -28,15 +28,15 @@ Updates the spell's actions on use as well, so they know when they can or can't var/plasma_cost = 0 /// Every single alien spell uses a "spell name + plasmacost" format -/obj/effect/proc_holder/spell/alien_spell/Initialize(mapload) - . = ..() +/datum/spell/alien_spell/New() + ..() if(plasma_cost) name = "[name] ([plasma_cost])" -/obj/effect/proc_holder/spell/alien_spell/write_custom_logs(list/targets, mob/user) +/datum/spell/alien_spell/write_custom_logs(list/targets, mob/user) user.create_log(ATTACK_LOG, "Cast the spell [name]") -/obj/effect/proc_holder/spell/alien_spell/create_new_handler() +/datum/spell/alien_spell/create_new_handler() var/datum/spell_handler/alien/handler = new handler.plasma_cost = plasma_cost return handler diff --git a/code/datums/spells/alien_spells/basetype_alien_touch.dm b/code/datums/spells/alien_spells/basetype_alien_touch.dm index 24141fe3a4c2..c58ff15bed29 100644 --- a/code/datums/spells/alien_spells/basetype_alien_touch.dm +++ b/code/datums/spells/alien_spells/basetype_alien_touch.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/touch/alien_spell +/datum/spell/touch/alien_spell name = "Basetype Alien spell" desc = "You should not see this in game, if you do file a github report!" hand_path = "/obj/item/melee/touch_attack/alien" @@ -15,20 +15,20 @@ var/plasma_cost = 0 action_icon_state = "gib" -/obj/effect/proc_holder/spell/touch/alien_spell/Initialize(mapload) - . = ..() +/datum/spell/touch/alien_spell/New() + ..() if(plasma_cost) name = "[name] ([plasma_cost])" -/obj/effect/proc_holder/spell/touch/alien_spell/Click(mob/user = usr) +/datum/spell/touch/alien_spell/Click(mob/user = usr) if(attached_hand) to_chat(user, "You withdraw your [src].") ..() -/obj/effect/proc_holder/spell/touch/alien_spell/write_custom_logs(list/targets, mob/user) +/datum/spell/touch/alien_spell/write_custom_logs(list/targets, mob/user) user.create_log(ATTACK_LOG, "Cast the spell [name]") -/obj/effect/proc_holder/spell/touch/alien_spell/create_new_handler() +/datum/spell/touch/alien_spell/create_new_handler() var/datum/spell_handler/alien/H = new H.plasma_cost = plasma_cost return H diff --git a/code/datums/spells/alien_spells/build_resin_structure.dm b/code/datums/spells/alien_spells/build_resin_structure.dm index 9da55a22ebf1..c38dcceec66d 100644 --- a/code/datums/spells/alien_spells/build_resin_structure.dm +++ b/code/datums/spells/alien_spells/build_resin_structure.dm @@ -1,17 +1,22 @@ -/obj/effect/proc_holder/spell/alien_spell/build_resin +#define RESIN_WALL "Resin Wall" +#define RESIN_NEST "Resin Nest" +#define RESIN_DOOR "Resin Door" +#define REVIVAL_NEST "Revival Nest" + +/datum/spell/alien_spell/build_resin name = "Build Resin Structure" desc = "Allows you to create resin structures. Does not work while in space." plasma_cost = 55 action_icon_state = "alien_resin" -/obj/effect/proc_holder/spell/alien_spell/build_resin/create_new_targeting() +/datum/spell/alien_spell/build_resin/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/alien_spell/build_resin/cast(list/targets, mob/living/carbon/user) - var/static/list/resin_buildings = list("Resin Wall" = image(icon = 'icons/obj/smooth_structures/alien/resin_wall.dmi', icon_state = "resin_wall-0"), - "Resin Nest" = image(icon = 'icons/mob/alien.dmi', icon_state = "nest"), - "Resin Door" = image(icon = 'icons/obj/smooth_structures/alien/resin_door.dmi', icon_state = "resin"), - "Revival Nest" = image(icon = 'icons/mob/alien.dmi', icon_state = "placeholder_rejuv_nest")) +/datum/spell/alien_spell/build_resin/cast(list/targets, mob/living/carbon/user) + var/static/list/resin_buildings = list(RESIN_WALL = image(icon = 'icons/obj/smooth_structures/alien/resin_wall.dmi', icon_state = "resin_wall-0"), + RESIN_NEST = image(icon = 'icons/mob/alien.dmi', icon_state = "nest"), + RESIN_DOOR = image(icon = 'icons/obj/smooth_structures/alien/resin_door.dmi', icon_state = "resin"), + REVIVAL_NEST = image(icon = 'icons/mob/alien.dmi', icon_state = "placeholder_rejuv_nest")) var/choice = show_radial_menu(user, user, resin_buildings, src, radius = 40) var/turf/turf_to_spawn_at = user.loc if(!choice) @@ -29,18 +34,18 @@ to_chat(user, "There is already a resin construction here.") revert_cast(user) return - visible_message("[user] vomits up a thick purple substance and shapes it!") + user.visible_message("[user] vomits up a thick purple substance and shapes it!") switch(choice) - if("Resin Wall") + if(RESIN_WALL) new /obj/structure/alien/resin/wall(turf_to_spawn_at) - if("Resin Nest") + if(RESIN_NEST) new /obj/structure/bed/nest(turf_to_spawn_at) - if("Resin Door") + if(RESIN_DOOR) new /obj/structure/alien/resin/door(turf_to_spawn_at) - if("Revival Nest") + if(REVIVAL_NEST) new /obj/structure/bed/revival_nest(turf_to_spawn_at) -/obj/effect/proc_holder/spell/touch/alien_spell/consume_resin +/datum/spell/touch/alien_spell/consume_resin name = "Consume resin structures" desc = "Allows you to rip and tear straight through resin structures." action_icon_state = "alien_resin" @@ -80,3 +85,8 @@ user.add_plasma(-10) qdel(target) ..() + +#undef RESIN_WALL +#undef RESIN_NEST +#undef RESIN_DOOR +#undef REVIVAL_NEST diff --git a/code/datums/spells/alien_spells/corrosive_acid_spit.dm b/code/datums/spells/alien_spells/corrosive_acid_spit.dm index 17e7756f7c70..2f32c2dcb049 100644 --- a/code/datums/spells/alien_spells/corrosive_acid_spit.dm +++ b/code/datums/spells/alien_spells/corrosive_acid_spit.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/touch/alien_spell/corrosive_acid +/datum/spell/touch/alien_spell/corrosive_acid name = "Corrosive acid" desc = "Spit acid on someone in range, this acid melts through nearly anything and heavily damages anyone lacking proper safety equipment." hand_path = "/obj/item/melee/touch_attack/alien/corrosive_acid" @@ -32,7 +32,7 @@ to_chat(user, "You cannot dissolve this object.") ..() -/obj/effect/proc_holder/spell/touch/alien_spell/burning_touch +/datum/spell/touch/alien_spell/burning_touch name = "Blazing touch" desc = "Boil acid within your hand to burn through anything you touch with it, deals a lot of damage to aliens and destroys resin structures instantly." hand_path = "/obj/item/melee/touch_attack/alien/burning_touch" diff --git a/code/datums/spells/alien_spells/larva_evolve.dm b/code/datums/spells/alien_spells/larva_evolve.dm index bbda1e2e1549..b10f7d1bebed 100644 --- a/code/datums/spells/alien_spells/larva_evolve.dm +++ b/code/datums/spells/alien_spells/larva_evolve.dm @@ -1,13 +1,13 @@ // Make this reflect amount grown, can't do that currently -/obj/effect/proc_holder/spell/alien_spell/evolve_larva +/datum/spell/alien_spell/evolve_larva name = "Evolve." desc = "Evolve into a fully grown Alien." action_icon_state = "alien_evolve_larva" -/obj/effect/proc_holder/spell/alien_spell/evolve_larva/create_new_targeting() +/datum/spell/alien_spell/evolve_larva/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/alien_spell/evolve_larva/cast(list/targets, mob/living/carbon/alien/larva/user) +/datum/spell/alien_spell/evolve_larva/cast(list/targets, mob/living/carbon/alien/larva/user) if(user.stat != CONSCIOUS) return diff --git a/code/datums/spells/alien_spells/lay_alien_eggs.dm b/code/datums/spells/alien_spells/lay_alien_eggs.dm index f2bfc89011f4..75bb9bd170f3 100644 --- a/code/datums/spells/alien_spells/lay_alien_eggs.dm +++ b/code/datums/spells/alien_spells/lay_alien_eggs.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/alien_spell/plant_weeds/eggs +/datum/spell/alien_spell/plant_weeds/eggs name = "Plant alien eggs" desc = "Allows you to plant alien eggs on your current turf, does not work while in space." plasma_cost = 75 @@ -7,17 +7,17 @@ action_icon_state = "alien_egg" requires_do_after = FALSE -/obj/effect/proc_holder/spell/alien_spell/combust_facehuggers +/datum/spell/alien_spell/combust_facehuggers name = "Combust facehuggers and eggs" desc = "Take over the programming of facehuggers and eggs, sending out a shockwave which causes them to combust." plasma_cost = 25 action_icon_state = "alien_egg" base_cooldown = 3 SECONDS -/obj/effect/proc_holder/spell/alien_spell/combust_facehuggers/create_new_targeting() +/datum/spell/alien_spell/combust_facehuggers/create_new_targeting() return new /datum/spell_targeting/clicked_atom -/obj/effect/proc_holder/spell/alien_spell/combust_facehuggers/cast(list/targets, mob/living/carbon/user) +/datum/spell/alien_spell/combust_facehuggers/cast(list/targets, mob/living/carbon/user) var/obj/target = targets[1] var/turf/T = user.loc if(!istype(T) || !istype(target)) @@ -33,7 +33,7 @@ to_chat(user, "[target] will explode in 3 seconds!") return TRUE -/obj/effect/proc_holder/spell/alien_spell/combust_facehuggers/proc/blow_it_up(obj/target, mob/user) +/datum/spell/alien_spell/combust_facehuggers/proc/blow_it_up(obj/target, mob/user) add_attack_logs(user, target, "Caused it to explode") explosion(get_turf(target), 0, 2, 3, 3, cause = user) to_chat(user, "[target] has detonated!") diff --git a/code/datums/spells/alien_spells/neurotoxin_spit.dm b/code/datums/spells/alien_spells/neurotoxin_spit.dm index d3cabc594c0b..1f24877e54ca 100644 --- a/code/datums/spells/alien_spells/neurotoxin_spit.dm +++ b/code/datums/spells/alien_spells/neurotoxin_spit.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/alien_spell/neurotoxin +/datum/spell/alien_spell/neurotoxin name = "Neurotoxin spit" desc = "This ability allows you to fire some neurotoxin. Knocks down anyone you hit, applies a small amount of stamina damage as well." base_cooldown = 3 SECONDS @@ -9,16 +9,16 @@ action_icon_state = "alien_neurotoxin_0" active = FALSE -/obj/effect/proc_holder/spell/alien_spell/neurotoxin/create_new_targeting() +/datum/spell/alien_spell/neurotoxin/create_new_targeting() return new /datum/spell_targeting/clicked_atom -/obj/effect/proc_holder/spell/alien_spell/neurotoxin/update_icon_state() +/datum/spell/alien_spell/neurotoxin/update_spell_icon() if(!action) return action.button_icon_state = "alien_neurotoxin_[active]" action.UpdateButtons() -/obj/effect/proc_holder/spell/alien_spell/neurotoxin/cast(list/targets, mob/living/carbon/user) +/datum/spell/alien_spell/neurotoxin/cast(list/targets, mob/living/carbon/user) var/target = targets[1] var/turf/T = user.loc var/turf/U = get_step(user, user.dir) // A little aimbot is fine @@ -35,7 +35,7 @@ return TRUE -/obj/effect/proc_holder/spell/alien_spell/neurotoxin/death_to_xenos +/datum/spell/alien_spell/neurotoxin/death_to_xenos name = "Neurotoxin spit" desc = "This ability allows you to fire some neurotoxin. Knocks aliens down." neurotoxin_type = /obj/item/projectile/bullet/anti_alien_toxin diff --git a/code/datums/spells/alien_spells/plasma_weeds.dm b/code/datums/spells/alien_spells/plasma_weeds.dm index b254403bc6e2..ae64db97d4f3 100644 --- a/code/datums/spells/alien_spells/plasma_weeds.dm +++ b/code/datums/spells/alien_spells/plasma_weeds.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/alien_spell/plant_weeds +/datum/spell/alien_spell/plant_weeds name = "Plant weeds" desc = "Allows you to plant some alien weeds on the floor below you. Does not work while in space." plasma_cost = 50 @@ -7,10 +7,10 @@ action_icon_state = "alien_plant" var/requires_do_after = TRUE -/obj/effect/proc_holder/spell/alien_spell/plant_weeds/create_new_targeting() +/datum/spell/alien_spell/plant_weeds/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/alien_spell/plant_weeds/cast(list/targets, mob/living/carbon/user) +/datum/spell/alien_spell/plant_weeds/cast(list/targets, mob/living/carbon/user) var/turf/T = user.loc if(locate(weed_type) in T) to_chat(user, "There's already \a [weed_name] here.") diff --git a/code/datums/spells/alien_spells/queen_evolve.dm b/code/datums/spells/alien_spells/queen_evolve.dm index 75502cfcd690..9f2cd550c665 100644 --- a/code/datums/spells/alien_spells/queen_evolve.dm +++ b/code/datums/spells/alien_spells/queen_evolve.dm @@ -1,13 +1,13 @@ -/obj/effect/proc_holder/spell/alien_spell/evolve_queen +/datum/spell/alien_spell/evolve_queen name = "Evolve into an alien queen" desc = "Evolve into an alien queen." plasma_cost = 300 action_icon_state = "alien_evolve_drone" -/obj/effect/proc_holder/spell/alien_spell/evolve_queen/create_new_targeting() +/datum/spell/alien_spell/evolve_queen/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/alien_spell/evolve_queen/cast(list/targets, mob/living/carbon/user) +/datum/spell/alien_spell/evolve_queen/cast(list/targets, mob/living/carbon/user) /// First we check if there is a living queen for(var/mob/living/carbon/alien/humanoid/queen/living_queen in GLOB.alive_mob_list) if(living_queen.key || !living_queen.get_int_organ(/obj/item/organ/internal/brain)) // We do a once over to check the queen didn't end up going away into the magic land of semi-dead diff --git a/code/datums/spells/alien_spells/regurgitate.dm b/code/datums/spells/alien_spells/regurgitate.dm index 02960c88afb3..4e91808e9312 100644 --- a/code/datums/spells/alien_spells/regurgitate.dm +++ b/code/datums/spells/alien_spells/regurgitate.dm @@ -1,18 +1,18 @@ -/obj/effect/proc_holder/spell/alien_spell/regurgitate +/datum/spell/alien_spell/regurgitate name = "Regurgitate" desc = "Empties the contents of your stomach onto the ground." action_icon_state = "alien_barf" -/obj/effect/proc_holder/spell/alien_spell/regurgitate/create_new_targeting() +/datum/spell/alien_spell/regurgitate/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/alien_spell/regurgitate/cast(list/targets, mob/living/carbon/user) +/datum/spell/alien_spell/regurgitate/cast(list/targets, mob/living/carbon/user) for(var/mob/M in user.stomach_contents) var/turf/output_loc = user.loc if(!istype(output_loc)) return user.stomach_contents -= M M.forceMove(output_loc) - visible_message("[user] hurls out the contents of [p_their()] stomach!") + user.visible_message("[user] hurls out the contents of [p_their()] stomach!") return - visible_message("[user] dry heaves!") + user.visible_message("[user] dry heaves!") diff --git a/code/datums/spells/alien_spells/tail_lash.dm b/code/datums/spells/alien_spells/tail_lash.dm index 0daa1e8a6a04..929d0ed95329 100644 --- a/code/datums/spells/alien_spells/tail_lash.dm +++ b/code/datums/spells/alien_spells/tail_lash.dm @@ -1,13 +1,13 @@ -/obj/effect/proc_holder/spell/alien_spell/tail_lash +/datum/spell/alien_spell/tail_lash name = "Tail lash" desc = "Knocks down anyone around you." action_icon_state = "tailsweep" base_cooldown = 10 SECONDS -/obj/effect/proc_holder/spell/alien_spell/tail_lash/create_new_targeting() +/datum/spell/alien_spell/tail_lash/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/alien_spell/tail_lash/cast(list/targets, mob/user) +/datum/spell/alien_spell/tail_lash/cast(list/targets, mob/user) var/turf/T = user.loc var/cast_resolved = FALSE if(!istype(T)) diff --git a/code/datums/spells/alien_spells/transfer_plasma.dm b/code/datums/spells/alien_spells/transfer_plasma.dm index 3ab94da1daf0..1ba29d900814 100644 --- a/code/datums/spells/alien_spells/transfer_plasma.dm +++ b/code/datums/spells/alien_spells/transfer_plasma.dm @@ -1,13 +1,13 @@ -/obj/effect/proc_holder/spell/alien_spell/transfer_plasma +/datum/spell/alien_spell/transfer_plasma name = "Transfer Plasma" desc = "Transfers 50 plasma to a nearby alien" action_icon_state = "alien_transfer" plasma_cost = 50 -/obj/effect/proc_holder/spell/alien_spell/transfer_plasma/create_new_targeting() +/datum/spell/alien_spell/transfer_plasma/create_new_targeting() return new /datum/spell_targeting/clicked_atom -/obj/effect/proc_holder/spell/alien_spell/transfer_plasma/cast(list/targets, mob/living/carbon/user) +/datum/spell/alien_spell/transfer_plasma/cast(list/targets, mob/living/carbon/user) var/mob/living/carbon/alien/target = targets[1] var/turf/T = user.loc if(!istype(T) || !istype(target)) @@ -20,17 +20,17 @@ to_chat(target, "[user] has transfered 50 plasma to you!") return TRUE -/obj/effect/proc_holder/spell/alien_spell/syphon_plasma +/datum/spell/alien_spell/syphon_plasma name = "Syphon plasma" desc = "Syphons 150 plasma from a nearby alien." action_icon_state = "alien_transfer" plasma_cost = 0 base_cooldown = 10 SECONDS -/obj/effect/proc_holder/spell/alien_spell/syphon_plasma/create_new_targeting() +/datum/spell/alien_spell/syphon_plasma/create_new_targeting() return new /datum/spell_targeting/clicked_atom -/obj/effect/proc_holder/spell/alien_spell/syphon_plasma/cast(list/targets, mob/living/carbon/user) +/datum/spell/alien_spell/syphon_plasma/cast(list/targets, mob/living/carbon/user) var/mob/living/carbon/alien/target = targets[1] var/turf/T = user.loc if(!istype(T) || !istype(target)) diff --git a/code/datums/spells/alien_spells/whisper.dm b/code/datums/spells/alien_spells/whisper.dm index 0f5369d04358..a280b63719ac 100644 --- a/code/datums/spells/alien_spells/whisper.dm +++ b/code/datums/spells/alien_spells/whisper.dm @@ -1,11 +1,11 @@ -/obj/effect/proc_holder/spell/alien_spell/whisper +/datum/spell/alien_spell/whisper name = "Whisper" desc = "Whisper into a target's mind." plasma_cost = 10 action_icon_state = "alien_whisper" var/target -/obj/effect/proc_holder/spell/alien_spell/whisper/create_new_targeting() // Yeah this is copy and pasted code from cryoken and it's good enough +/datum/spell/alien_spell/whisper/create_new_targeting() // Yeah this is copy and pasted code from cryoken and it's good enough var/datum/spell_targeting/click/T = new() T.allowed_type = /mob/living T.click_radius = 0 @@ -14,7 +14,7 @@ T.include_user = TRUE return T -/obj/effect/proc_holder/spell/alien_spell/whisper/cast(list/targets, mob/living/carbon/user) +/datum/spell/alien_spell/whisper/cast(list/targets, mob/living/carbon/user) var/mob/living/target = targets[1] var/msg = tgui_input_text(user, "Message:", "Alien Whisper") diff --git a/code/datums/spells/area_teleport.dm b/code/datums/spells/area_teleport.dm index 60502ffbe86a..b7d349b5a32d 100644 --- a/code/datums/spells/area_teleport.dm +++ b/code/datums/spells/area_teleport.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/area_teleport +/datum/spell/area_teleport nonabstract_req = TRUE var/randomise_selection = 0 //if it lets the usr choose the teleport loc or picks it from the list @@ -8,7 +8,7 @@ var/sound2 = 'sound/weapons/zapbang.ogg' var/area/selected_area -/obj/effect/proc_holder/spell/area_teleport/before_cast(list/targets, mob/user) +/datum/spell/area_teleport/before_cast(list/targets, mob/user) ..() selected_area = null // Reset it var/area_name @@ -30,7 +30,7 @@ selected_area = thearea -/obj/effect/proc_holder/spell/area_teleport/cast(list/targets, mob/living/user) +/datum/spell/area_teleport/cast(list/targets, mob/living/user) if(!selected_area) revert_cast(user) return @@ -78,7 +78,7 @@ return -/obj/effect/proc_holder/spell/area_teleport/invocation(mob/user) +/datum/spell/area_teleport/invocation(mob/user) if(!invocation_area || !selected_area) return switch(invocation_type) diff --git a/code/datums/spells/banana_touch.dm b/code/datums/spells/banana_touch.dm index ed44996ce455..6fc3a835313e 100644 --- a/code/datums/spells/banana_touch.dm +++ b/code/datums/spells/banana_touch.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/touch/banana +/datum/spell/touch/banana name = "Banana Touch" desc = "A spell popular at wizard birthday parties, this spell will put on a clown costume on the target, \ stun them with a loud HONK, and mutate them to make them more entertaining! \ @@ -19,7 +19,7 @@ icon_state = "banana_touch" item_state = "banana_touch" -/obj/effect/proc_holder/spell/touch/banana/apprentice +/datum/spell/touch/banana/apprentice hand_path = /obj/item/melee/touch_attack/banana/apprentice /obj/item/melee/touch_attack/banana/apprentice diff --git a/code/datums/spells/bloodcrawl.dm b/code/datums/spells/bloodcrawl.dm index 0175920d82dc..b54ca987de37 100644 --- a/code/datums/spells/bloodcrawl.dm +++ b/code/datums/spells/bloodcrawl.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/bloodcrawl +/datum/spell/bloodcrawl name = "Blood Crawl" desc = "Use pools of blood to phase out of existence." base_cooldown = 1 SECONDS @@ -12,7 +12,7 @@ var/allowed_type = /obj/effect/decal/cleanable var/phased = FALSE -/obj/effect/proc_holder/spell/bloodcrawl/create_new_targeting() +/datum/spell/bloodcrawl/create_new_targeting() var/datum/spell_targeting/targeted/T = new() T.selection_type = SPELL_SELECTION_RANGE T.allowed_type = allowed_type @@ -21,17 +21,17 @@ T.use_turf_of_user = TRUE return T -/obj/effect/proc_holder/spell/bloodcrawl/valid_target(obj/effect/decal/cleanable/target, user) +/datum/spell/bloodcrawl/valid_target(obj/effect/decal/cleanable/target, user) return target.can_bloodcrawl_in() -/obj/effect/proc_holder/spell/bloodcrawl/can_cast(mob/living/user, charge_check, show_message) +/datum/spell/bloodcrawl/can_cast(mob/living/user, charge_check, show_message) . = ..() if(!.) return if(!isliving(user)) return FALSE -/obj/effect/proc_holder/spell/bloodcrawl/cast(list/targets, mob/living/user) +/datum/spell/bloodcrawl/cast(list/targets, mob/living/user) var/atom/target = targets[1] if(!phased) if(phaseout(target, user)) @@ -78,7 +78,7 @@ return -/obj/effect/proc_holder/spell/bloodcrawl/proc/block_hands(mob/living/carbon/C) +/datum/spell/bloodcrawl/proc/block_hands(mob/living/carbon/C) if(C.l_hand || C.r_hand) to_chat(C, "You may not hold items while blood crawling!") return FALSE @@ -101,13 +101,13 @@ . = ..() flick(animation_state, src) // Setting the icon_state to the animation has timing issues and can cause frame skips -/obj/effect/proc_holder/spell/bloodcrawl/proc/sink_animation(atom/A, mob/living/L) +/datum/spell/bloodcrawl/proc/sink_animation(atom/A, mob/living/L) var/turf/mob_loc = get_turf(L) - visible_message("[L] sinks into [A].") - playsound(mob_loc, 'sound/misc/enter_blood.ogg', 100, 1, -1) + mob_loc.visible_message("[L] sinks into [A].") + playsound(mob_loc, 'sound/misc/enter_blood.ogg', 100, TRUE, -1) new /obj/effect/temp_visual/dir_setting/bloodcrawl(mob_loc, L.dir, "jaunt") -/obj/effect/proc_holder/spell/bloodcrawl/proc/handle_consumption(mob/living/L, mob/living/victim, atom/A, obj/effect/dummy/slaughter/holder) +/datum/spell/bloodcrawl/proc/handle_consumption(mob/living/L, mob/living/victim, atom/A, obj/effect/dummy/slaughter/holder) if(!HAS_TRAIT(L, TRAIT_BLOODCRAWL_EAT)) return @@ -176,10 +176,10 @@ victim.ghostize() qdel(victim) -/obj/effect/proc_holder/spell/bloodcrawl/proc/post_phase_in(mob/living/L, obj/effect/dummy/slaughter/holder) +/datum/spell/bloodcrawl/proc/post_phase_in(mob/living/L, obj/effect/dummy/slaughter/holder) L.notransform = FALSE -/obj/effect/proc_holder/spell/bloodcrawl/proc/phaseout(obj/effect/decal/cleanable/B, mob/living/L) +/datum/spell/bloodcrawl/proc/phaseout(obj/effect/decal/cleanable/B, mob/living/L) if(iscarbon(L) && !block_hands(L)) return FALSE @@ -187,7 +187,7 @@ INVOKE_ASYNC(src, PROC_REF(async_phase), B, L) return TRUE -/obj/effect/proc_holder/spell/bloodcrawl/proc/async_phase(obj/effect/decal/cleanable/B, mob/living/L) +/datum/spell/bloodcrawl/proc/async_phase(obj/effect/decal/cleanable/B, mob/living/L) var/turf/mobloc = get_turf(L) sink_animation(B, L) var/obj/effect/dummy/slaughter/holder = new /obj/effect/dummy/slaughter(mobloc) @@ -196,24 +196,24 @@ handle_consumption(L, L.pulling, B, holder) post_phase_in(L, holder) -/obj/effect/proc_holder/spell/bloodcrawl/proc/rise_animation(turf/tele_loc, mob/living/L, atom/A) +/datum/spell/bloodcrawl/proc/rise_animation(turf/tele_loc, mob/living/L, atom/A) new /obj/effect/temp_visual/dir_setting/bloodcrawl(tele_loc, L.dir, "jauntup") if(prob(25) && isdemon(L)) var/list/voice = list('sound/hallucinations/behind_you1.ogg', 'sound/hallucinations/im_here1.ogg', 'sound/hallucinations/turn_around1.ogg', 'sound/hallucinations/i_see_you1.ogg') - playsound(tele_loc, pick(voice),50, 1, -1) - A.visible_message("[L] rises out of [A]!") - playsound(get_turf(tele_loc), 'sound/misc/exit_blood.ogg', 100, 1, -1) + playsound(tele_loc, pick(voice),50, TRUE, -1) + A.visible_message("[L] rises out of [A]!") + playsound(get_turf(tele_loc), 'sound/misc/exit_blood.ogg', 100, TRUE, -1) -/obj/effect/proc_holder/spell/bloodcrawl/proc/unblock_hands(mob/living/carbon/C) +/datum/spell/bloodcrawl/proc/unblock_hands(mob/living/carbon/C) if(!istype(C)) return for(var/obj/item/bloodcrawl/BC in C) qdel(BC) -/obj/effect/proc_holder/spell/bloodcrawl/proc/rise_message(atom/A) +/datum/spell/bloodcrawl/proc/rise_message(atom/A) A.visible_message("[A] starts to bubble...") -/obj/effect/proc_holder/spell/bloodcrawl/proc/post_phase_out(atom/A, mob/living/L) +/datum/spell/bloodcrawl/proc/post_phase_out(atom/A, mob/living/L) if(isslaughterdemon(L)) var/mob/living/simple_animal/demon/slaughter/S = L S.speed = 0 @@ -222,7 +222,7 @@ addtimer(VARSET_CALLBACK(L, color, null), 6 SECONDS) -/obj/effect/proc_holder/spell/bloodcrawl/proc/phasein(atom/A, mob/living/L) +/datum/spell/bloodcrawl/proc/phasein(atom/A, mob/living/L) if(L.notransform) to_chat(L, "Finish eating first!") @@ -246,30 +246,30 @@ post_phase_out(A, L) return TRUE -/obj/effect/proc_holder/spell/bloodcrawl/shadow_crawl +/datum/spell/bloodcrawl/shadow_crawl name = "Shadow Crawl" desc = "Fade into the shadows, increasing your speed and making you incomprehensible. Will not work in brightened terrane." allowed_type = /turf action_background_icon_state = "shadow_demon_bg" action_icon_state = "shadow_crawl" -/obj/effect/proc_holder/spell/bloodcrawl/shadow_crawl/valid_target(turf/target, user) +/datum/spell/bloodcrawl/shadow_crawl/valid_target(turf/target, user) return target.get_lumcount() < 0.2 -/obj/effect/proc_holder/spell/bloodcrawl/shadow_crawl/rise_message(atom/A) +/datum/spell/bloodcrawl/shadow_crawl/rise_message(atom/A) return -/obj/effect/proc_holder/spell/bloodcrawl/shadow_crawl/rise_animation(turf/tele_loc, mob/living/L, atom/A) +/datum/spell/bloodcrawl/shadow_crawl/rise_animation(turf/tele_loc, mob/living/L, atom/A) new /obj/effect/temp_visual/dir_setting/bloodcrawl(get_turf(L), L.dir, "shadowwalk_appear") -/obj/effect/proc_holder/spell/bloodcrawl/shadow_crawl/handle_consumption(mob/living/L, mob/living/victim, atom/A, obj/effect/dummy/slaughter/holder) +/datum/spell/bloodcrawl/shadow_crawl/handle_consumption(mob/living/L, mob/living/victim, atom/A, obj/effect/dummy/slaughter/holder) return -/obj/effect/proc_holder/spell/bloodcrawl/shadow_crawl/sink_animation(atom/A, mob/living/L) +/datum/spell/bloodcrawl/shadow_crawl/sink_animation(atom/A, mob/living/L) A.visible_message("[L] sinks into the shadows...") new /obj/effect/temp_visual/dir_setting/bloodcrawl(get_turf(L), L.dir, "shadowwalk_disappear") -/obj/effect/proc_holder/spell/bloodcrawl/shadow_crawl/post_phase_in(mob/living/L, obj/effect/dummy/slaughter/holder) +/datum/spell/bloodcrawl/shadow_crawl/post_phase_in(mob/living/L, obj/effect/dummy/slaughter/holder) ..() if(!istype(L, /mob/living/simple_animal/demon/shadow)) return diff --git a/code/datums/spells/chaplain_bless.dm b/code/datums/spells/chaplain_bless.dm index 70b8eb8e7082..de9741b53659 100644 --- a/code/datums/spells/chaplain_bless.dm +++ b/code/datums/spells/chaplain_bless.dm @@ -1,5 +1,5 @@ -/obj/effect/proc_holder/spell/chaplain_bless +/datum/spell/chaplain_bless name = "Bless" desc = "Blesses a single person." @@ -14,16 +14,16 @@ cooldown_min = 20 action_icon_state = "shield" -/obj/effect/proc_holder/spell/chaplain_bless/create_new_targeting() +/datum/spell/chaplain_bless/create_new_targeting() var/datum/spell_targeting/click/T = new() T.range = 1 T.click_radius = -1 return T -/obj/effect/proc_holder/spell/chaplain_bless/valid_target(mob/living/carbon/human/target, mob/user) +/datum/spell/chaplain_bless/valid_target(mob/living/carbon/human/target, mob/user) return target.mind && target.ckey && !target.stat -/obj/effect/proc_holder/spell/chaplain_bless/cast(list/targets, mob/living/user = usr) +/datum/spell/chaplain_bless/cast(list/targets, mob/living/user = usr) if(!istype(user)) to_chat(user, "Somehow, you are not a living mob. This should never happen. Report this bug.") revert_cast() diff --git a/code/datums/spells/charge.dm b/code/datums/spells/charge.dm index 806767153a13..be5c5a09b888 100644 --- a/code/datums/spells/charge.dm +++ b/code/datums/spells/charge.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/charge +/datum/spell/charge name = "Charge" desc = "This spell can be used to recharge a variety of things in your hands, from magical artifacts to electrical components. A creative wizard can even use it to grant magical power to a fellow magic user." school = "transmutation" @@ -9,10 +9,10 @@ cooldown_min = 400 //50 deciseconds reduction per rank action_icon_state = "charge" -/obj/effect/proc_holder/spell/charge/create_new_targeting() +/datum/spell/charge/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/charge/cast(list/targets, mob/user = usr) +/datum/spell/charge/cast(list/targets, mob/user = usr) for(var/mob/living/L in targets) var/list/hand_items = list(L.get_active_hand(),L.get_inactive_hand()) var/charged_item = null @@ -21,10 +21,10 @@ if(L.pulling && (isliving(L.pulling))) var/mob/living/M = L.pulling if(M.mob_spell_list.len != 0 || (M.mind && M.mind.spell_list.len != 0)) - for(var/obj/effect/proc_holder/spell/S in M.mob_spell_list) + for(var/datum/spell/S in M.mob_spell_list) S.cooldown_handler.revert_cast() if(M.mind) - for(var/obj/effect/proc_holder/spell/S in M.mind.spell_list) + for(var/datum/spell/S in M.mind.spell_list) S.cooldown_handler.revert_cast() to_chat(M, "You feel raw magical energy flowing through you, it feels good!") else diff --git a/code/datums/spells/charge_up.dm b/code/datums/spells/charge_up.dm index abae667f1a01..1d1d6fad2b05 100644 --- a/code/datums/spells/charge_up.dm +++ b/code/datums/spells/charge_up.dm @@ -2,7 +2,7 @@ * A click-based spell template which starts charging up once you click the action button/verb. Click again on something to activate the actual spell */ -/obj/effect/proc_holder/spell/charge_up +/datum/spell/charge_up var/start_time = 0 /// The overlay used to show that you are charging. Create this in the New of the spell var/image/charge_up_overlay @@ -17,13 +17,13 @@ /// The text shown when you are over the charge limit and thus can't stop. var/stop_charging_fail_text -/obj/effect/proc_holder/spell/charge_up/create_new_targeting() +/datum/spell/charge_up/create_new_targeting() var/datum/spell_targeting/click/T = new() T.allowed_type = /mob/living T.try_auto_target = FALSE return T -/obj/effect/proc_holder/spell/charge_up/Click() +/datum/spell/charge_up/Click() if(cast_check(TRUE, FALSE, usr)) if(!start_time) INVOKE_ASYNC(src, PROC_REF(StartChargeup), usr) @@ -33,7 +33,7 @@ return ..() -/obj/effect/proc_holder/spell/charge_up/proc/try_stop_buildup(mob/user) +/datum/spell/charge_up/proc/try_stop_buildup(mob/user) var/energy_perc = get_energy_charge() / max_charge_time if(energy_perc < 0.5) cooldown_handler.start_recharge((1 - energy_perc) * cooldown_handler.recharge_duration) // Shorten the cooldown based on how long it was charged for. @@ -44,10 +44,10 @@ to_chat(user, "[stop_charging_fail_text]") return FALSE -/obj/effect/proc_holder/spell/charge_up/proc/get_energy_charge() +/datum/spell/charge_up/proc/get_energy_charge() return min(world.time - start_time, max_charge_time) -/obj/effect/proc_holder/spell/charge_up/proc/StartChargeup(mob/user) +/datum/spell/charge_up/proc/StartChargeup(mob/user) to_chat(user, "[start_charging_text]") user.add_overlay(charge_up_overlay) playsound(user, charge_sound, 50, FALSE, channel = charge_sound.channel) @@ -56,25 +56,25 @@ if(start_time) Discharge(user) -/obj/effect/proc_holder/spell/charge_up/proc/stopped_casting() +/datum/spell/charge_up/proc/stopped_casting() return start_time == 0 -/obj/effect/proc_holder/spell/charge_up/proc/Reset(mob/user) +/datum/spell/charge_up/proc/Reset(mob/user) start_time = 0 user.cut_overlay(charge_up_overlay) remove_ranged_ability(user) playsound(user, null, 50, FALSE, channel = charge_sound.channel) -/obj/effect/proc_holder/spell/charge_up/revert_cast(mob/user) +/datum/spell/charge_up/revert_cast(mob/user) Reset(user) ..() -/obj/effect/proc_holder/spell/charge_up/proc/Discharge(mob/user) +/datum/spell/charge_up/proc/Discharge(mob/user) to_chat(user, "You lose control over the spell!") Reset(user) spend_spell_cost(user) cooldown_handler.start_recharge() -/obj/effect/proc_holder/spell/charge_up/after_cast(list/targets, mob/user) +/datum/spell/charge_up/after_cast(list/targets, mob/user) ..() Reset(user) diff --git a/code/datums/spells/charge_up_bounce.dm b/code/datums/spells/charge_up_bounce.dm index a84887258d6e..6555f7646ce8 100644 --- a/code/datums/spells/charge_up_bounce.dm +++ b/code/datums/spells/charge_up_bounce.dm @@ -2,17 +2,17 @@ * A spell template that adds bounces to the charge_up spell template. The spell will bounce between targets once released. * Don't override cast and instead override apply_bounce_effect and the other procs */ -/obj/effect/proc_holder/spell/charge_up/bounce +/datum/spell/charge_up/bounce var/bounce_hit_sound -/obj/effect/proc_holder/spell/charge_up/bounce/create_new_targeting() +/datum/spell/charge_up/bounce/create_new_targeting() var/datum/spell_targeting/click/T = new T.allowed_type = /mob/living T.try_auto_target = FALSE T.use_obstacle_check = TRUE return T -/obj/effect/proc_holder/spell/charge_up/bounce/cast(list/targets, mob/user = usr) +/datum/spell/charge_up/bounce/cast(list/targets, mob/user = usr) var/mob/living/target = targets[1] bounce(user, target, get_bounce_energy(), get_bounce_amount(), user) @@ -20,13 +20,13 @@ /** * How much energy should each bounce have? */ -/obj/effect/proc_holder/spell/charge_up/bounce/proc/get_bounce_energy() +/datum/spell/charge_up/bounce/proc/get_bounce_energy() return /** * How much bounces should there be in total? */ -/obj/effect/proc_holder/spell/charge_up/bounce/proc/get_bounce_amount() +/datum/spell/charge_up/bounce/proc/get_bounce_amount() return /** @@ -36,7 +36,7 @@ * * origin - Where the bounce came from * * target - The mob that got hit */ -/obj/effect/proc_holder/spell/charge_up/bounce/proc/create_beam(mob/origin, mob/target) +/datum/spell/charge_up/bounce/proc/create_beam(mob/origin, mob/target) return /** @@ -49,10 +49,10 @@ * * energy - How much energy the bounce has * * user - The caster of the spell */ -/obj/effect/proc_holder/spell/charge_up/bounce/proc/apply_bounce_effect(mob/origin, mob/target, energy, mob/user) +/datum/spell/charge_up/bounce/proc/apply_bounce_effect(mob/origin, mob/target, energy, mob/user) return -/obj/effect/proc_holder/spell/charge_up/bounce/proc/bounce(mob/origin, mob/target, energy, bounces, mob/user) +/datum/spell/charge_up/bounce/proc/bounce(mob/origin, mob/target, energy, bounces, mob/user) SHOULD_CALL_PARENT(TRUE) create_beam(origin, target) apply_bounce_effect(origin, target, energy, user) diff --git a/code/datums/spells/cluwne.dm b/code/datums/spells/cluwne.dm index eeaed56ac114..b57ea0a531e7 100644 --- a/code/datums/spells/cluwne.dm +++ b/code/datums/spells/cluwne.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/touch/cluwne +/datum/spell/touch/cluwne name = "Curse of the Cluwne" desc = "Turns the target into a fat and cursed monstrosity of a clown." hand_path = /obj/item/melee/touch_attack/cluwne diff --git a/code/datums/spells/conjure.dm b/code/datums/spells/conjure.dm index 380c178688c6..74f4a885e4d8 100644 --- a/code/datums/spells/conjure.dm +++ b/code/datums/spells/conjure.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/aoe/conjure +/datum/spell/aoe/conjure desc = "This spell conjures objs of the specified types in range." var/list/summon_type = list() //determines what exactly will be summoned @@ -15,14 +15,14 @@ var/cast_sound = 'sound/items/welder.ogg' -/obj/effect/proc_holder/spell/aoe/conjure/create_new_targeting() +/datum/spell/aoe/conjure/create_new_targeting() var/datum/spell_targeting/aoe/turf/targeting = new() targeting.range = aoe_range return targeting -/obj/effect/proc_holder/spell/aoe/conjure/cast(list/targets,mob/living/user = usr) +/datum/spell/aoe/conjure/cast(list/targets,mob/living/user = usr) var/list/what_conjure_summoned = list() - playsound(get_turf(user), cast_sound, 50,1) + playsound(get_turf(user), cast_sound, 50, TRUE) for(var/turf/T in targets) if(T.density && !summon_ignore_density) targets -= T @@ -57,8 +57,7 @@ return what_conjure_summoned -/// test purposes -/obj/effect/proc_holder/spell/aoe/conjure/summonEdSwarm +/datum/spell/aoe/conjure/summonEdSwarm name = "Dispense Wizard Justice" desc = "This spell dispenses wizard justice." summon_type = list(/mob/living/simple_animal/bot/ed209) diff --git a/code/datums/spells/conjure_item.dm b/code/datums/spells/conjure_item.dm index d2e77429b870..0aad4922e64b 100644 --- a/code/datums/spells/conjure_item.dm +++ b/code/datums/spells/conjure_item.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/conjure_item +/datum/spell/conjure_item name = "Summon weapon" desc = "A generic spell that should not exist. This summons an instance of a specific type of item, or if one already exists, un-summons it." invocation_type = "none" @@ -9,10 +9,10 @@ base_cooldown = 15 SECONDS cooldown_min = 10 -/obj/effect/proc_holder/spell/conjure_item/create_new_targeting() +/datum/spell/conjure_item/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/conjure_item/cast(list/targets, mob/user = usr) +/datum/spell/conjure_item/cast(list/targets, mob/user = usr) if(item) QDEL_NULL(item) else @@ -21,6 +21,6 @@ item = new item_type C.put_in_hands(item) -/obj/effect/proc_holder/spell/conjure_item/Destroy() +/datum/spell/conjure_item/Destroy() QDEL_NULL(item) return ..() diff --git a/code/datums/spells/construct_spells.dm b/code/datums/spells/construct_spells.dm index de300b929cfa..3afd600fa619 100644 --- a/code/datums/spells/construct_spells.dm +++ b/code/datums/spells/construct_spells.dm @@ -1,14 +1,14 @@ //////////////////////////////Construct Spells///////////////////////// -/obj/effect/proc_holder/spell/aoe/conjure/construct/lesser +/datum/spell/aoe/conjure/construct/lesser base_cooldown = 1800 action_icon_state = "artificer" action_background_icon_state = "bg_cult" -/obj/effect/proc_holder/spell/aoe/conjure/build +/datum/spell/aoe/conjure/build aoe_range = 0 -/obj/effect/proc_holder/spell/aoe/conjure/build/floor +/datum/spell/aoe/conjure/build/floor name = "Summon Cult Floor" desc = "This spell constructs a cult floor" action_icon_state = "floorconstruct" @@ -22,7 +22,7 @@ centcom_cancast = FALSE //Stop crashing the server by spawning turfs on transit tiles holy_area_cancast = FALSE //Stops cult magic from working on holy ground eg: chapel -/obj/effect/proc_holder/spell/aoe/conjure/build/wall +/datum/spell/aoe/conjure/build/wall name = "Summon Cult Wall" desc = "This spell constructs a cult wall" action_icon_state = "cultforcewall" @@ -36,7 +36,7 @@ centcom_cancast = FALSE //Stop crashing the server by spawning turfs on transit tiles holy_area_cancast = FALSE //Stops cult magic from working on holy ground eg: chapel -/obj/effect/proc_holder/spell/aoe/conjure/build/wall/reinforced +/datum/spell/aoe/conjure/build/wall/reinforced name = "Greater Construction" desc = "This spell constructs a reinforced metal wall" school = "conjuration" @@ -50,7 +50,7 @@ summon_type = list(/turf/simulated/wall/r_wall) -/obj/effect/proc_holder/spell/aoe/conjure/build/soulstone +/datum/spell/aoe/conjure/build/soulstone name = "Summon Soulstone" desc = "This spell uses vile sorcery to create a spirit-trapping soulstone." action_icon_state = "summonsoulstone" @@ -64,12 +64,12 @@ summon_type = list(/obj/item/soulstone) -/obj/effect/proc_holder/spell/aoe/conjure/build/soulstone/holy +/datum/spell/aoe/conjure/build/soulstone/holy action_icon_state = "summonsoulstone_holy" summon_type = list(/obj/item/soulstone/anybody/purified) -/obj/effect/proc_holder/spell/aoe/conjure/build/pylon +/datum/spell/aoe/conjure/build/pylon name = "Cult Pylon" desc = "This spell uses dark magic to craft an unholy beacon. Heals cultists, and makes a handy light source." action_icon_state = "pylon" @@ -84,7 +84,7 @@ summon_type = list(/obj/structure/cult/functional/pylon) -/obj/effect/proc_holder/spell/aoe/conjure/build/lesserforcewall +/datum/spell/aoe/conjure/build/lesserforcewall name = "Shield" desc = "This spell creates a temporary forcefield to shield yourself and allies from incoming fire" action_icon_state = "cultforcewall" @@ -105,7 +105,7 @@ icon_state = "m_shield_cult" light_color = LIGHT_COLOR_PURE_RED -/obj/effect/proc_holder/spell/ethereal_jaunt/shift +/datum/spell/ethereal_jaunt/shift name = "Phase Shift" desc = "This spell allows you to pass through walls" action_icon_state = "phaseshift" @@ -119,7 +119,7 @@ jaunt_in_type = /obj/effect/temp_visual/dir_setting/wraith jaunt_out_type = /obj/effect/temp_visual/dir_setting/wraith/out -/obj/effect/proc_holder/spell/ethereal_jaunt/shift/do_jaunt(mob/living/target) +/datum/spell/ethereal_jaunt/shift/do_jaunt(mob/living/target) target.set_light(0) ..() if(isconstruct(target)) @@ -129,10 +129,10 @@ else C.set_light(2, 3, l_color = GET_CULT_DATA(construct_glow, LIGHT_COLOR_BLOOD_MAGIC)) -/obj/effect/proc_holder/spell/ethereal_jaunt/shift/jaunt_steam(mobloc) +/datum/spell/ethereal_jaunt/shift/jaunt_steam(mobloc) return -/obj/effect/proc_holder/spell/projectile/magic_missile/lesser +/datum/spell/projectile/magic_missile/lesser name = "Lesser Magic Missile" desc = "This spell fires several, slow moving, magic projectiles at nearby targets." action_background_icon_state = "bg_cult" @@ -144,20 +144,21 @@ holy_area_cancast = FALSE //Stops cult magic from working on holy ground eg: chapel proj_lifespan = 10 proj_step_delay = 5 - proj_type = "/obj/effect/proc_holder/spell/inflict_handler/magic_missile/lesser" + proj_type = /obj/item/projectile/magic/magic_missile/lesser -/obj/effect/proc_holder/spell/projectile/magic_missile/lesser/create_new_targeting() +/datum/spell/projectile/magic_missile/lesser/create_new_targeting() var/datum/spell_targeting/targeted/T = new() T.allowed_type = /mob/living T.random_target = TRUE T.max_targets = 6 return T -/obj/effect/proc_holder/spell/inflict_handler/magic_missile/lesser - amt_knockdown = 6 SECONDS - amt_weakened = 0 +/obj/item/projectile/magic/magic_missile/lesser + name = "lesser magic missile" + knockdown = 6 SECONDS + weaken = 0 -/obj/effect/proc_holder/spell/smoke/disable +/datum/spell/smoke/disable name = "Paralysing Smoke" desc = "This spell spawns a cloud of paralysing smoke." action_icon_state = "parasmoke" diff --git a/code/datums/spells/disguise_self.dm b/code/datums/spells/disguise_self.dm index f45f3d226546..4ebd86c5398d 100644 --- a/code/datums/spells/disguise_self.dm +++ b/code/datums/spells/disguise_self.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/disguise_self +/datum/spell/disguise_self name = "Disguise Self" desc = "Disguise yourself as a crewmember, based on your current location. Also changes your voice. \ The disguise will not hold up to being examined directly, and will break if you're damaged." @@ -12,10 +12,10 @@ action_icon_state = "disguise_self" sound = null -/obj/effect/proc_holder/spell/disguise_self/create_new_targeting() +/datum/spell/disguise_self/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/disguise_self/cast(list/targets, mob/user = usr) +/datum/spell/disguise_self/cast(list/targets, mob/user = usr) if(!ishuman(user)) return FALSE var/mob/living/carbon/human/H = user diff --git a/code/datums/spells/emplosion.dm b/code/datums/spells/emplosion.dm index 4eba6b127bda..2e8e6bc74303 100644 --- a/code/datums/spells/emplosion.dm +++ b/code/datums/spells/emplosion.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/emplosion +/datum/spell/emplosion name = "Emplosion" desc = "This spell emplodes an area." @@ -7,12 +7,12 @@ action_icon_state = "emp" -/obj/effect/proc_holder/spell/emplosion/create_new_targeting() +/datum/spell/emplosion/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/emplosion/cast(list/targets, mob/user = usr) +/datum/spell/emplosion/cast(list/targets, mob/user = usr) for(var/mob/living/target in targets) - empulse(target.loc, emp_heavy, emp_light, 1) + empulse(target.loc, emp_heavy, emp_light, TRUE) return diff --git a/code/datums/spells/ethereal_jaunt.dm b/code/datums/spells/ethereal_jaunt.dm index d6197b8c2bb6..467527a08748 100644 --- a/code/datums/spells/ethereal_jaunt.dm +++ b/code/datums/spells/ethereal_jaunt.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/ethereal_jaunt +/datum/spell/ethereal_jaunt name = "Ethereal Jaunt" desc = "This spell creates your ethereal form, temporarily making you invisible and able to pass through walls." @@ -20,18 +20,18 @@ action_icon_state = "jaunt" -/obj/effect/proc_holder/spell/ethereal_jaunt/create_new_targeting() +/datum/spell/ethereal_jaunt/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/ethereal_jaunt/cast(list/targets, mob/user = usr) //magnets, so mostly hardcoded - playsound(get_turf(user), sound1, 50, 1, -1) +/datum/spell/ethereal_jaunt/cast(list/targets, mob/user = usr) //magnets, so mostly hardcoded + playsound(get_turf(user), sound1, 50, TRUE, -1) for(var/mob/living/target in targets) if(!target.can_safely_leave_loc()) // No more brainmobs hopping out of their brains to_chat(target, "You are somehow too bound to your current location to abandon it.") continue INVOKE_ASYNC(src, PROC_REF(do_jaunt), target) -/obj/effect/proc_holder/spell/ethereal_jaunt/proc/do_jaunt(mob/living/target) +/datum/spell/ethereal_jaunt/proc/do_jaunt(mob/living/target) target.notransform = TRUE var/turf/mobloc = get_turf(target) var/obj/effect/dummy/spell_jaunt/holder = new jaunt_type_path(mobloc) @@ -74,7 +74,7 @@ REMOVE_TRAIT(target, TRAIT_IMMOBILIZED, "jaunt") target.remove_CC() -/obj/effect/proc_holder/spell/ethereal_jaunt/proc/jaunt_steam(mobloc) +/datum/spell/ethereal_jaunt/proc/jaunt_steam(mobloc) var/datum/effect_system/steam_spread/steam = new /datum/effect_system/steam_spread() steam.set_up(10, 0, mobloc) steam.start() diff --git a/code/datums/spells/fake_gib.dm b/code/datums/spells/fake_gib.dm index 138db2c0c2ac..262a8c9cba9a 100644 --- a/code/datums/spells/fake_gib.dm +++ b/code/datums/spells/fake_gib.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/touch/fake_disintegrate +/datum/spell/touch/fake_disintegrate name = "Disintegrate" desc = "This spell charges your hand with vile energy that can be used to violently explode victims." hand_path = "/obj/item/melee/touch_attack/fake_disintegrate" diff --git a/code/datums/spells/genetic.dm b/code/datums/spells/genetic.dm index cab9a5f381ab..91ae75562018 100644 --- a/code/datums/spells/genetic.dm +++ b/code/datums/spells/genetic.dm @@ -1,12 +1,12 @@ -/obj/effect/proc_holder/spell/genetic +/datum/spell/genetic desc = "This spell inflicts a set of mutations and disabilities upon the target." var/list/active_on = list() var/list/traits = list() // traits var/list/mutations = list() // mutation defines. Set these in Initialize. Refactor this nonsense one day - var/duration = 100 // deciseconds + var/duration = 10 SECONDS -/obj/effect/proc_holder/spell/genetic/cast(list/targets, mob/user = usr) +/datum/spell/genetic/cast(list/targets, mob/user = usr) for(var/mob/living/target in targets) if(!target.dna) continue @@ -17,15 +17,19 @@ ADD_TRAIT(target, A, MAGIC_TRAIT) active_on += target target.regenerate_icons() + do_additional_effects(target) if(duration < base_cooldown) addtimer(CALLBACK(src, PROC_REF(remove), target), duration, TIMER_OVERRIDE|TIMER_UNIQUE) -/obj/effect/proc_holder/spell/genetic/Destroy() +/datum/spell/genetic/proc/do_additional_effects(mob/target) + return + +/datum/spell/genetic/Destroy() for(var/V in active_on) remove(V) return ..() -/obj/effect/proc_holder/spell/genetic/proc/remove(mob/living/carbon/target) +/datum/spell/genetic/proc/remove(mob/living/carbon/target) active_on -= target if(!QDELETED(target)) for(var/A in mutations) diff --git a/code/datums/spells/horsemask.dm b/code/datums/spells/horsemask.dm index 3dd2d35bbe58..8b6baba6772e 100644 --- a/code/datums/spells/horsemask.dm +++ b/code/datums/spells/horsemask.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/horsemask +/datum/spell/horsemask name = "Curse of the Horseman" desc = "This spell triggers a curse on a target, causing them to wield an unremovable horse head mask. They will speak like a horse! Any masks they are wearing will be disintegrated. This spell does not require robes." school = "transmutation" @@ -15,13 +15,13 @@ action_icon_state = "barn" sound = 'sound/magic/HorseHead_curse.ogg' -/obj/effect/proc_holder/spell/horsemask/create_new_targeting() +/datum/spell/horsemask/create_new_targeting() var/datum/spell_targeting/click/T = new() T.selection_type = SPELL_SELECTION_RANGE return T -/obj/effect/proc_holder/spell/horsemask/cast(list/targets, mob/user = usr) +/datum/spell/horsemask/cast(list/targets, mob/user = usr) if(!targets.len) to_chat(user, "No target found in range.") return diff --git a/code/datums/spells/infinite_guns.dm b/code/datums/spells/infinite_guns.dm index 56b0cae5cfdc..b18625a3d5f7 100644 --- a/code/datums/spells/infinite_guns.dm +++ b/code/datums/spells/infinite_guns.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/infinite_guns +/datum/spell/infinite_guns name = "Lesser Summon Guns" desc = "Why reload when you have infinite guns? Summons an unending stream of bolt action rifles. Requires both hands free to use." invocation_type = "none" @@ -10,10 +10,10 @@ action_icon_state = "bolt_action" var/gun_type = /obj/item/gun/projectile/shotgun/boltaction/enchanted -/obj/effect/proc_holder/spell/infinite_guns/create_new_targeting() +/datum/spell/infinite_guns/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/infinite_guns/cast(list/targets, mob/user = usr) +/datum/spell/infinite_guns/cast(list/targets, mob/user = usr) for(var/mob/living/carbon/C in targets) C.drop_item() C.swap_hand() @@ -21,7 +21,7 @@ var/obj/item/gun/projectile/shotgun/boltaction/enchanted/GUN = new gun_type() C.put_in_hands(GUN) -/obj/effect/proc_holder/spell/infinite_guns/fireball +/datum/spell/infinite_guns/fireball name = "Rapid-fire Fireball" desc = "Multiple Fireballs. Need I explain more? Requires both hands free to use." diff --git a/code/datums/spells/inflict_handler.dm b/code/datums/spells/inflict_handler.dm deleted file mode 100644 index d69253f59110..000000000000 --- a/code/datums/spells/inflict_handler.dm +++ /dev/null @@ -1,62 +0,0 @@ -/obj/effect/proc_holder/spell/inflict_handler - name = "Inflict Handler" - desc = "This spell blinds and/or destroys/damages/heals and/or weakens/stuns the target." - - var/amt_weakened = 0 - var/amt_paralysis = 0 - var/amt_stunned = 0 - var/amt_knockdown = 0 - - //set to negatives for healing - var/amt_dam_fire = 0 - var/amt_dam_brute = 0 - var/amt_dam_oxy = 0 - var/amt_dam_tox = 0 - - var/amt_eye_blind = 0 - var/amt_eye_blurry = 0 - - var/destroys = "none" //can be "none", "gib" or "disintegrate" - - var/summon_type = null //this will put an obj at the target's location - -/obj/effect/proc_holder/spell/inflict_handler/create_new_targeting() - return new /datum/spell_targeting/self // Dummy value since it is never used for this spell... why is this even a spell - -/obj/effect/proc_holder/spell/inflict_handler/cast(list/targets, mob/user = usr) - - for(var/mob/living/target in targets) - switch(destroys) - if("gib") - target.gib() - if("disintegrate") - target.dust() - - if(!target) - continue - //damage - if(amt_dam_brute > 0) - if(amt_dam_fire >= 0) - target.take_overall_damage(amt_dam_brute,amt_dam_fire) - else if(amt_dam_fire < 0) - target.take_overall_damage(amt_dam_brute,0) - target.heal_overall_damage(0,amt_dam_fire) - else if(amt_dam_brute < 0) - if(amt_dam_fire > 0) - target.take_overall_damage(0,amt_dam_fire) - target.heal_overall_damage(amt_dam_brute,0) - else if(amt_dam_fire <= 0) - target.heal_overall_damage(amt_dam_brute,amt_dam_fire) - target.adjustToxLoss(amt_dam_tox) - target.adjustOxyLoss(amt_dam_oxy) - //disabling - target.Weaken(amt_weakened) - target.Paralyse(amt_paralysis) - target.Stun(amt_stunned) - target.KnockDown(amt_knockdown) - - target.AdjustEyeBlind(amt_eye_blind) - target.AdjustEyeBlurry(amt_eye_blurry) - //summoning - if(summon_type) - new summon_type(target.loc, target) diff --git a/code/datums/spells/knock.dm b/code/datums/spells/knock.dm index 221ac50196e8..9689858794a2 100644 --- a/code/datums/spells/knock.dm +++ b/code/datums/spells/knock.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/aoe/knock +/datum/spell/aoe/knock name = "Knock" desc = "This spell opens nearby doors and does not require wizard garb." @@ -13,31 +13,31 @@ sound = 'sound/magic/knock.ogg' aoe_range = 3 -/obj/effect/proc_holder/spell/aoe/knock/create_new_targeting() +/datum/spell/aoe/knock/create_new_targeting() var/datum/spell_targeting/aoe/turf/targeting = new() targeting.range = aoe_range return targeting -/obj/effect/proc_holder/spell/aoe/knock/cast(list/targets, mob/user = usr) +/datum/spell/aoe/knock/cast(list/targets, mob/user = usr) for(var/turf/T in targets) for(var/obj/machinery/door/door in T.contents) INVOKE_ASYNC(src, PROC_REF(try_open_airlock), door) for(var/obj/structure/closet/C in T.contents) INVOKE_ASYNC(src, PROC_REF(try_open_closet), C) -/obj/effect/proc_holder/spell/aoe/knock/proc/try_open_airlock(obj/machinery/door/door) +/datum/spell/aoe/knock/proc/try_open_airlock(obj/machinery/door/door) if(istype(door, /obj/machinery/door/airlock)) var/obj/machinery/door/airlock/A = door A.unlock(TRUE) //forced because it's magic! door.open() -/obj/effect/proc_holder/spell/aoe/knock/proc/try_open_closet(obj/structure/closet/C) +/datum/spell/aoe/knock/proc/try_open_closet(obj/structure/closet/C) if(istype(C, /obj/structure/closet/secure_closet)) var/obj/structure/closet/secure_closet/SC = C SC.locked = FALSE C.open() -/obj/effect/proc_holder/spell/aoe/knock/greater +/datum/spell/aoe/knock/greater name = "Greater Knock" desc = "On first cast, will remove access restrictions on all airlocks on the station, and announce this spell's use to the station. On any further cast, will open all doors in sight. Cannot be refunded once bought!" @@ -50,7 +50,7 @@ action_icon_state = "greater_knock" -/obj/effect/proc_holder/spell/aoe/knock/greater/cast(list/targets, mob/user = usr) +/datum/spell/aoe/knock/greater/cast(list/targets, mob/user = usr) if(!used) used = TRUE for(var/obj/machinery/door/airlock/A in GLOB.airlocks) diff --git a/code/datums/spells/lichdom.dm b/code/datums/spells/lichdom.dm index ccdad7e98637..30c0dd39ec4e 100644 --- a/code/datums/spells/lichdom.dm +++ b/code/datums/spells/lichdom.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/lichdom +/datum/spell/lichdom name = "Bind Soul" desc = "A dark necromantic pact that can forever bind your soul to an item of your choosing. So long as both your body and the item remain intact and on the same plane you can revive from death, though the time between reincarnations grows steadily with use." school = "necromancy" @@ -17,26 +17,26 @@ action_icon_state = "skeleton" -/obj/effect/proc_holder/spell/lichdom/create_new_targeting() +/datum/spell/lichdom/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/lichdom/Destroy() +/datum/spell/lichdom/Destroy() for(var/datum/mind/M in SSticker.mode.wizards) //Make sure no other bones are about - for(var/obj/effect/proc_holder/spell/S in M.spell_list) - if(istype(S,/obj/effect/proc_holder/spell/lichdom) && S != src) + for(var/datum/spell/S in M.spell_list) + if(istype(S,/datum/spell/lichdom) && S != src) return ..() if(existence_stops_round_end) GLOB.configuration.gamemode.disable_certain_round_early_end = FALSE return ..() -/obj/effect/proc_holder/spell/lichdom/cast(list/targets, mob/user = usr) +/datum/spell/lichdom/cast(list/targets, mob/user = usr) for(var/mob/M in targets) if(stat_allowed) attempt_revive(M) else if(!marked_item_uid) attempt_mark_item(M) -/obj/effect/proc_holder/spell/lichdom/proc/attempt_revive(mob/user) +/datum/spell/lichdom/proc/attempt_revive(mob/user) // Can only cast when unconscious/dead if(user.stat == CONSCIOUS) to_chat(user, "You aren't dead enough to revive!") @@ -95,7 +95,7 @@ cooldown_handler.recharge_duration += 1 MINUTES to_chat(lich, "Your bones clatter and shudder as they're pulled back into this world!") -/obj/effect/proc_holder/spell/lichdom/proc/attempt_mark_item(mob/user) +/datum/spell/lichdom/proc/attempt_mark_item(mob/user) var/obj/item/target = user.get_active_hand() if(!target) to_chat(user, "You must hold an item you wish to make your phylactery!") @@ -141,7 +141,7 @@ existence_stops_round_end = TRUE GLOB.configuration.gamemode.disable_certain_round_early_end = TRUE -/obj/effect/proc_holder/spell/lichdom/proc/is_revive_possible() +/datum/spell/lichdom/proc/is_revive_possible() var/obj/item/marked_item = locateUID(marked_item_uid) if(QDELETED(marked_item)) return FALSE @@ -153,12 +153,12 @@ return FALSE return TRUE -/obj/effect/proc_holder/spell/lichdom/proc/check_revivability_handler() +/datum/spell/lichdom/proc/check_revivability_handler() SIGNAL_HANDLER // There are other liches about, so round may still continue for(var/datum/mind/M in SSticker.mode.wizards) - for(var/obj/effect/proc_holder/spell/lichdom/S in M.spell_list) + for(var/datum/spell/lichdom/S in M.spell_list) if(S == src) continue // Other lich can still revive @@ -170,7 +170,7 @@ GLOB.configuration.gamemode.disable_certain_round_early_end = is_revive_possible() -/obj/effect/proc_holder/spell/lichdom/proc/equip_lich(mob/living/carbon/human/H) +/datum/spell/lichdom/proc/equip_lich(mob/living/carbon/human/H) H.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe/black(H), SLOT_HUD_OUTER_SUIT) H.equip_to_slot_or_del(new /obj/item/clothing/head/wizard/black(H), SLOT_HUD_HEAD) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(H), SLOT_HUD_SHOES) diff --git a/code/datums/spells/lightning.dm b/code/datums/spells/lightning.dm index 53dfd6818c70..d4a141c1ccb4 100644 --- a/code/datums/spells/lightning.dm +++ b/code/datums/spells/lightning.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/charge_up/bounce/lightning +/datum/spell/charge_up/bounce/lightning name = "Lightning Bolt" desc = "Throws a lightning bolt at your enemies. Classic. When clicked will start to charge in power. Then click on a mob to send the bolt before it overloads with power." base_cooldown = 30 SECONDS @@ -15,29 +15,29 @@ bounce_hit_sound = 'sound/magic/lightningshock.ogg' var/damaging = TRUE -/obj/effect/proc_holder/spell/charge_up/bounce/lightning/New() +/datum/spell/charge_up/bounce/lightning/New() ..() charge_up_overlay = image(icon = 'icons/effects/effects.dmi', icon_state = "electricity", layer = EFFECTS_LAYER) -/obj/effect/proc_holder/spell/charge_up/bounce/lightning/lightnian +/datum/spell/charge_up/bounce/lightning/lightnian clothes_req = FALSE invocation_type = "none" damaging = FALSE -/obj/effect/proc_holder/spell/charge_up/bounce/lightning/get_bounce_energy() +/datum/spell/charge_up/bounce/lightning/get_bounce_energy() if(damaging) return max(15, get_energy_charge() / 2) return 0 -/obj/effect/proc_holder/spell/charge_up/bounce/lightning/get_bounce_amount() +/datum/spell/charge_up/bounce/lightning/get_bounce_amount() if(damaging) return 5 return round(get_energy_charge() / 20) -/obj/effect/proc_holder/spell/charge_up/bounce/lightning/create_beam(mob/origin, mob/target) +/datum/spell/charge_up/bounce/lightning/create_beam(mob/origin, mob/target) origin.Beam(target, icon_state = "lightning[rand(1, 12)]", icon = 'icons/effects/effects.dmi', time = 5) -/obj/effect/proc_holder/spell/charge_up/bounce/lightning/apply_bounce_effect(mob/origin, mob/living/target, energy, mob/user) +/datum/spell/charge_up/bounce/lightning/apply_bounce_effect(mob/origin, mob/living/target, energy, mob/user) if(damaging) target.electrocute_act(energy, "Lightning Bolt", flags = SHOCK_NOGLOVES) else diff --git a/code/datums/spells/magnet.dm b/code/datums/spells/magnet.dm index 681833388688..a559b1062c0c 100644 --- a/code/datums/spells/magnet.dm +++ b/code/datums/spells/magnet.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/charge_up/bounce/magnet +/datum/spell/charge_up/bounce/magnet name = "Magnetic Pull" desc = "Pulls metalic objects from enemies hands with the power of MAGNETS." action_icon_state = "magnet" @@ -14,22 +14,22 @@ start_charging_text = "You start gathering magnetism around you." bounce_hit_sound = 'sound/machines/defib_zap.ogg' -/obj/effect/proc_holder/spell/charge_up/bounce/magnet/New() +/datum/spell/charge_up/bounce/magnet/New() ..() charge_up_overlay = image(icon = 'icons/effects/effects.dmi', icon_state = "electricity", layer = EFFECTS_LAYER) -/obj/effect/proc_holder/spell/charge_up/bounce/magnet/get_bounce_energy() +/datum/spell/charge_up/bounce/magnet/get_bounce_energy() return get_energy_charge() -/obj/effect/proc_holder/spell/charge_up/bounce/magnet/get_bounce_amount() +/datum/spell/charge_up/bounce/magnet/get_bounce_amount() if(get_energy_charge() >= 75) return 5 return 0 -/obj/effect/proc_holder/spell/charge_up/bounce/magnet/create_beam(mob/origin, mob/target) +/datum/spell/charge_up/bounce/magnet/create_beam(mob/origin, mob/target) origin.Beam(target, icon_state = "lightning[rand(1, 12)]", icon = 'icons/effects/effects.dmi', time = 5) -/obj/effect/proc_holder/spell/charge_up/bounce/magnet/apply_bounce_effect(mob/origin, mob/target, energy, mob/user) +/datum/spell/charge_up/bounce/magnet/apply_bounce_effect(mob/origin, mob/target, energy, mob/user) var/list/items_to_throw = list() switch(energy) if(0 to 25) @@ -47,7 +47,7 @@ for(var/I in items_to_throw) try_throw_object(user, target, I) -/obj/effect/proc_holder/spell/charge_up/bounce/magnet/proc/try_throw_object(mob/user, mob/thrower, obj/item/to_throw) +/datum/spell/charge_up/bounce/magnet/proc/try_throw_object(mob/user, mob/thrower, obj/item/to_throw) if(!(to_throw.flags & CONDUCT) || !thrower.unEquip(to_throw, silent = TRUE)) return FALSE thrower.visible_message("[to_throw] gets thrown out of [thrower] [thrower.p_their()] hands!", diff --git a/code/datums/spells/mime.dm b/code/datums/spells/mime.dm index e40dd88df963..9fe9431dc8d4 100644 --- a/code/datums/spells/mime.dm +++ b/code/datums/spells/mime.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/aoe/conjure/build/mime_wall +/datum/spell/aoe/conjure/build/mime_wall name = "Invisible Wall" desc = "The mime's performance transmutates into physical reality." school = "mime" @@ -15,7 +15,7 @@ action_icon_state = "mime" action_background_icon_state = "bg_mime" -/obj/effect/proc_holder/spell/aoe/conjure/build/mime_wall/Click() +/datum/spell/aoe/conjure/build/mime_wall/Click() if(usr && usr.mind) if(!usr.mind.miming) to_chat(usr, "You must dedicate yourself to silence first.") @@ -25,10 +25,10 @@ invocation_type ="none" ..() -/obj/effect/proc_holder/spell/mime/create_new_targeting() +/datum/spell/mime/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/mime/speak +/datum/spell/mime/speak name = "Speech" desc = "Make or break a vow of silence." school = "mime" @@ -40,7 +40,7 @@ action_icon_state = "mime_silence" action_background_icon_state = "bg_mime" -/obj/effect/proc_holder/spell/mime/speak/Click() +/datum/spell/mime/speak/Click() if(!usr) return if(!ishuman(usr)) @@ -52,7 +52,7 @@ still_recharging_msg = "You'll have to wait before you can give your vow of silence again!" ..() -/obj/effect/proc_holder/spell/mime/speak/cast(list/targets,mob/user = usr) +/datum/spell/mime/speak/cast(list/targets,mob/user = usr) for(var/mob/living/carbon/human/H in targets) H.mind.miming=!H.mind.miming if(H.mind.miming) @@ -62,7 +62,7 @@ //Advanced Mimery traitor item spells -/obj/effect/proc_holder/spell/forcewall/mime +/datum/spell/forcewall/mime name = "Invisible Greater Wall" desc = "Form an invisible three tile wide blockade." school = "mime" @@ -77,7 +77,7 @@ action_icon_state = "mime_bigwall" action_background_icon_state = "bg_mime" -/obj/effect/proc_holder/spell/forcewall/mime/Click() +/datum/spell/forcewall/mime/Click() if(usr && usr.mind) if(!usr.mind.miming) to_chat(usr, "You must dedicate yourself to silence first.") @@ -87,7 +87,7 @@ invocation_type ="none" ..() -/obj/effect/proc_holder/spell/mime/fingergun +/datum/spell/mime/fingergun name = "Finger Gun" desc = "Shoot lethal, silencing bullets out of your fingers! 3 bullets available per cast. Use your fingers to holster them manually." school = "mime" @@ -101,7 +101,7 @@ var/gun = /obj/item/gun/projectile/revolver/fingergun var/obj/item/gun/projectile/revolver/fingergun/current_gun -/obj/effect/proc_holder/spell/mime/fingergun/cast(list/targets, mob/user = usr) +/datum/spell/mime/fingergun/cast(list/targets, mob/user = usr) for(var/mob/living/carbon/human/C in targets) if(!current_gun) to_chat(user, "You draw your fingers!") @@ -114,33 +114,33 @@ revert_cast(user) -/obj/effect/proc_holder/spell/mime/fingergun/Destroy() +/datum/spell/mime/fingergun/Destroy() current_gun = null return ..() -/obj/effect/proc_holder/spell/mime/fingergun/proc/holster_hand(atom/target, any=FALSE) +/datum/spell/mime/fingergun/proc/holster_hand(atom/target, any=FALSE) SIGNAL_HANDLER if(!current_gun || !any && action.owner.get_active_hand() != current_gun) return to_chat(action.owner, "You holster your fingers. Another time perhaps...") QDEL_NULL(current_gun) -/obj/effect/proc_holder/spell/mime/fingergun/fake +/datum/spell/mime/fingergun/fake desc = "Pretend you're shooting bullets out of your fingers! 3 bullets available per cast. Use your fingers to holster them manually." gun = /obj/item/gun/projectile/revolver/fingergun/fake // Mime Spellbooks /obj/item/spellbook/oneuse/mime - spell = /obj/effect/proc_holder/spell/aoe/conjure/build/mime_wall + spell = /datum/spell/aoe/conjure/build/mime_wall spellname = "Invisible Wall" name = "Miming Manual : " desc = "It contains various pictures of mimes mid-performance, aswell as some illustrated tutorials." icon_state = "bookmime" /obj/item/spellbook/oneuse/mime/attack_self(mob/user) - var/obj/effect/proc_holder/spell/S = new spell - for(var/obj/effect/proc_holder/spell/knownspell in user.mind.spell_list) + var/datum/spell/S = new spell + for(var/datum/spell/knownspell in user.mind.spell_list) if(knownspell.type == S.type) if(user.mind) to_chat(user, "You've already read this one.") @@ -159,19 +159,19 @@ /obj/item/spellbook/oneuse/mime/onlearned(mob/user) used = TRUE - if(!locate(/obj/effect/proc_holder/spell/mime/speak) in user.mind.spell_list) //add vow of silence if not known by user - user.mind.AddSpell(new /obj/effect/proc_holder/spell/mime/speak) + if(!locate(/datum/spell/mime/speak) in user.mind.spell_list) //add vow of silence if not known by user + user.mind.AddSpell(new /datum/spell/mime/speak) to_chat(user, "You have learned how to use silence to improve your performance.") /obj/item/spellbook/oneuse/mime/fingergun - spell = /obj/effect/proc_holder/spell/mime/fingergun + spell = /datum/spell/mime/fingergun spellname = "Finger Gun" desc = "It contains illustrations of guns and how to mime them." /obj/item/spellbook/oneuse/mime/fingergun/fake - spell = /obj/effect/proc_holder/spell/mime/fingergun/fake + spell = /datum/spell/mime/fingergun/fake /obj/item/spellbook/oneuse/mime/greaterwall - spell = /obj/effect/proc_holder/spell/forcewall/mime + spell = /datum/spell/forcewall/mime spellname = "Invisible Greater Wall" desc = "It contains illustrations of the great walls of human history." diff --git a/code/datums/spells/mime_malaise.dm b/code/datums/spells/mime_malaise.dm index 471ba5cb1c65..6c448b91bd6e 100644 --- a/code/datums/spells/mime_malaise.dm +++ b/code/datums/spells/mime_malaise.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/touch/mime_malaise +/datum/spell/touch/mime_malaise name = "Mime Malaise" desc = "A spell popular with theater nerd wizards and contrarian pranksters, this spell will put on a mime costume on the target, \ stun them so that they may contemplate Art, and silence them. \ diff --git a/code/datums/spells/mimic.dm b/code/datums/spells/mimic.dm index 15c1481c8fef..e601cf553474 100644 --- a/code/datums/spells/mimic.dm +++ b/code/datums/spells/mimic.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/mimic +/datum/spell/mimic name = "Mimic" desc = "Learn a new form to mimic or become one of your known forms" clothes_req = FALSE @@ -32,7 +32,7 @@ ) -/obj/effect/proc_holder/spell/mimic/create_new_targeting() +/datum/spell/mimic/create_new_targeting() var/datum/spell_targeting/click/T = new T.include_user = TRUE // To change forms T.allowed_type = /atom/movable @@ -40,7 +40,7 @@ T.click_radius = -1 return T -/obj/effect/proc_holder/spell/mimic/valid_target(atom/target, user) +/datum/spell/mimic/valid_target(atom/target, user) if(is_type_in_list(target, black_listed_form_types)) return FALSE if(istype(target, /atom/movable)) @@ -51,7 +51,7 @@ return FALSE return ..() -/obj/effect/proc_holder/spell/mimic/cast(list/targets, mob/user) +/datum/spell/mimic/cast(list/targets, mob/user) var/atom/movable/A = targets[1] if(A == user) INVOKE_ASYNC(src, PROC_REF(pick_form), user) @@ -59,7 +59,7 @@ INVOKE_ASYNC(src, PROC_REF(remember_form), A, user) -/obj/effect/proc_holder/spell/mimic/proc/remember_form(atom/movable/A, mob/user) +/datum/spell/mimic/proc/remember_form(atom/movable/A, mob/user) if(A.name in available_forms) to_chat(user, "[A] is already an available form.") revert_cast(user) @@ -83,7 +83,7 @@ available_forms[A.name] = new /datum/mimic_form(A, user) to_chat(user, "You learn the form of [A].") -/obj/effect/proc_holder/spell/mimic/proc/pick_form(mob/user) +/datum/spell/mimic/proc/pick_form(mob/user) if(!length(available_forms) && !selected_form) to_chat(user, "No available forms. Learn more forms by using this spell on other objects first.") revert_cast(user) @@ -109,7 +109,7 @@ return take_form(available_forms[what], user) -/obj/effect/proc_holder/spell/mimic/proc/take_form(datum/mimic_form/form, mob/user) +/datum/spell/mimic/proc/take_form(datum/mimic_form/form, mob/user) var/old_name = "[user]" if(ishuman(user)) // Not fully finished yet @@ -132,10 +132,10 @@ selected_form = form -/obj/effect/proc_holder/spell/mimic/proc/show_change_form_message(mob/user, old_name, new_name) +/datum/spell/mimic/proc/show_change_form_message(mob/user, old_name, new_name) user.visible_message("[old_name] contorts and slowly becomes [new_name]!", "You take form of [new_name].", "You hear loud cracking noises!") -/obj/effect/proc_holder/spell/mimic/proc/restore_form(mob/user, show_message = TRUE) +/datum/spell/mimic/proc/restore_form(mob/user, show_message = TRUE) selected_form = null var/old_name = "[user]" @@ -157,21 +157,21 @@ UnregisterSignal(user, list(COMSIG_PARENT_EXAMINE, COMSIG_MOB_DEATH)) -/obj/effect/proc_holder/spell/mimic/proc/show_restore_form_message(mob/user, old_name, new_name) +/datum/spell/mimic/proc/show_restore_form_message(mob/user, old_name, new_name) user.visible_message("[old_name] shakes and contorts and quickly becomes [new_name]!", "You take return to your normal self.", "You hear loud cracking noises!") -/obj/effect/proc_holder/spell/mimic/proc/examine_override(datum/source, mob/user, list/examine_list) +/datum/spell/mimic/proc/examine_override(datum/source, mob/user, list/examine_list) examine_list.Cut() examine_list += selected_form.examine_text if(!perfect_disguise && get_dist(user, source) <= 3) examine_list += "It doesn't look quite right..." -/obj/effect/proc_holder/spell/mimic/proc/on_death(mob/user, gibbed) +/datum/spell/mimic/proc/on_death(mob/user, gibbed) if(!gibbed) restore_form(user, FALSE) show_death_message(user) -/obj/effect/proc_holder/spell/mimic/proc/show_death_message(mob/user) +/datum/spell/mimic/proc/show_death_message(mob/user) user.visible_message("[user] shakes and contorts as [user.p_they()] die[user.p_s()], returning to [user.p_their()] true form!", "Your disguise fails as your life forces drain away.", "You hear loud cracking noises followed by a thud!") @@ -188,34 +188,34 @@ examine_text = form.examine(user) name = form.name -/obj/effect/proc_holder/spell/mimic/morph +/datum/spell/mimic/morph action_background_icon_state = "bg_morph" -/obj/effect/proc_holder/spell/mimic/morph/create_new_handler() +/datum/spell/mimic/morph/create_new_handler() var/datum/spell_handler/morph/H = new return H -/obj/effect/proc_holder/spell/mimic/morph/valid_target(atom/target, user) +/datum/spell/mimic/morph/valid_target(atom/target, user) if(target != user && ismorph(target)) return FALSE return ..() -/obj/effect/proc_holder/spell/mimic/morph/take_form(datum/mimic_form/form, mob/living/simple_animal/hostile/morph/user) +/datum/spell/mimic/morph/take_form(datum/mimic_form/form, mob/living/simple_animal/hostile/morph/user) ..() user.assume() -/obj/effect/proc_holder/spell/mimic/morph/restore_form(mob/living/simple_animal/hostile/morph/user, show_message = TRUE) +/datum/spell/mimic/morph/restore_form(mob/living/simple_animal/hostile/morph/user, show_message = TRUE) ..() user.restore() -/obj/effect/proc_holder/spell/mimic/morph/show_change_form_message(mob/user, old_name, new_name) +/datum/spell/mimic/morph/show_change_form_message(mob/user, old_name, new_name) user.visible_message("[old_name] suddenly twists and changes shape, becoming a copy of [new_name]!", \ "You twist your body and assume the form of [new_name].") -/obj/effect/proc_holder/spell/mimic/morph/show_restore_form_message(mob/user, old_name, new_name) +/datum/spell/mimic/morph/show_restore_form_message(mob/user, old_name, new_name) user.visible_message("[old_name] suddenly collapses in on itself, dissolving into a pile of green flesh!", \ "You reform to your normal body.") -/obj/effect/proc_holder/spell/mimic/morph/show_death_message(mob/user) +/datum/spell/mimic/morph/show_death_message(mob/user) user.visible_message("[user] twists and dissolves into a pile of green flesh!", \ "Your skin ruptures! Your flesh breaks apart! No disguise can ward off de--") diff --git a/code/datums/spells/mind_transfer.dm b/code/datums/spells/mind_transfer.dm index 8b8f91c3cb00..ffefd1534a17 100644 --- a/code/datums/spells/mind_transfer.dm +++ b/code/datums/spells/mind_transfer.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/mind_transfer +/datum/spell/mind_transfer name = "Mind Transfer" desc = "This spell allows the user to switch bodies with a target." @@ -15,14 +15,14 @@ var/paralysis_amount_victim = 40 SECONDS //how much the victim is paralysed for after the spell action_icon_state = "mindswap" -/obj/effect/proc_holder/spell/mind_transfer/create_new_targeting() +/datum/spell/mind_transfer/create_new_targeting() var/datum/spell_targeting/click/T = new() T.allowed_type = /mob/living T.range = 1 T.click_radius = 0 return T -/obj/effect/proc_holder/spell/mind_transfer/valid_target(mob/living/target, mob/user) +/datum/spell/mind_transfer/valid_target(mob/living/target, mob/user) return target.stat != DEAD && target.key && target.mind /* @@ -30,7 +30,7 @@ Urist: I don't feel like figuring out how you store object spells so I'm leaving Make sure spells that are removed from spell_list are actually removed and deleted when mind transfering. Also, you never added distance checking after target is selected. I've went ahead and did that. */ -/obj/effect/proc_holder/spell/mind_transfer/cast(list/targets, mob/user = usr) +/datum/spell/mind_transfer/cast(list/targets, mob/user = usr) var/mob/living/target = targets[1] diff --git a/code/datums/spells/night_vision.dm b/code/datums/spells/night_vision.dm index ad854eed6014..de085eae1993 100644 --- a/code/datums/spells/night_vision.dm +++ b/code/datums/spells/night_vision.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/night_vision +/datum/spell/night_vision name = "Toggle Nightvision" desc = "Toggle your nightvision mode." @@ -7,10 +7,10 @@ message = "You toggle your night vision!" -/obj/effect/proc_holder/spell/night_vision/create_new_targeting() +/datum/spell/night_vision/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/night_vision/cast(list/targets, mob/user = usr) +/datum/spell/night_vision/cast(list/targets, mob/user = usr) for(var/mob/living/target in targets) switch(target.lighting_alpha) if(LIGHTING_PLANE_ALPHA_VISIBLE) diff --git a/code/datums/spells/projectile_spell.dm b/code/datums/spells/projectile_spell.dm index 168d2660f5a1..fd724b5019b2 100644 --- a/code/datums/spells/projectile_spell.dm +++ b/code/datums/spells/projectile_spell.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/projectile +/datum/spell/projectile desc = "This spell summons projectiles which try to hit the targets." var/proj_icon = 'icons/obj/projectiles.dmi' @@ -10,7 +10,8 @@ var/proj_trail_icon = 'icons/obj/wizard.dmi' var/proj_trail_icon_state = "trail" - var/proj_type = "/obj/effect/proc_holder/spell" //IMPORTANT use only subtypes of this + /// The projectile we spawn. Make sure to override this + var/proj_type var/proj_lingering = 0 //if it lingers or disappears upon hitting an obstacle var/proj_homing = 1 //if it follows the target @@ -20,64 +21,51 @@ var/proj_lifespan = 15 //in deciseconds * proj_step_delay var/proj_step_delay = 1 //lower = faster -/obj/effect/proc_holder/spell/projectile/cast(list/targets, mob/user = usr) +/datum/spell/projectile/cast(list/targets, mob/user = usr) for(var/mob/living/target in targets) spawn(0) - var/obj/effect/proc_holder/spell/projectile - if(istext(proj_type)) - var/projectile_type = text2path(proj_type) - projectile = new projectile_type(user) - if(istype(proj_type,/obj/effect/proc_holder/spell)) - projectile = new /obj/effect/proc_holder/spell/trigger(user) - projectile:linked_spells += proj_type + var/obj/item/projectile/projectile = new proj_type(get_turf(user)) projectile.icon = proj_icon projectile.icon_state = proj_icon_state - projectile.dir = get_dir(target,projectile) + projectile.dir = get_dir(target, projectile) projectile.name = proj_name + var/current_loc = get_turf(projectile) - var/current_loc = user.loc - - projectile.loc = current_loc - - for(var/i = 0,i < proj_lifespan,i++) + for(var/i in 1 to proj_lifespan) if(!projectile) break if(proj_homing) if(proj_insubstantial) projectile.dir = get_dir(projectile,target) - projectile.loc = get_step_to(projectile,target) + projectile.forceMove(get_step_to(projectile, target)) else step_to(projectile,target) else if(proj_insubstantial) - projectile.loc = get_step(projectile,dir) + projectile.forceMove(get_step(projectile, projectile.dir)) else - step(projectile,dir) + step(projectile, projectile.dir) if(!projectile) // step and step_to sleeps so we'll have to check again. break - if(!proj_lingering && projectile.loc == current_loc) //if it didn't move since last time + if(!proj_lingering && (get_turf(projectile) == current_loc)) //if it didn't move since last time qdel(projectile) break if(proj_trail && projectile) spawn(0) if(projectile) - var/obj/effect/overlay/trail = new /obj/effect/overlay(projectile.loc) + var/obj/effect/overlay/trail = new /obj/effect/overlay(get_turf(projectile)) trail.icon = proj_trail_icon trail.icon_state = proj_trail_icon_state trail.density = FALSE spawn(proj_trail_lifespan) qdel(trail) - if(projectile.loc in range(target.loc,proj_trigger_range)) - projectile.perform(list(target), user = user) - break - - current_loc = projectile.loc + current_loc = get_turf(projectile) sleep(proj_step_delay) diff --git a/code/datums/spells/rathens.dm b/code/datums/spells/rathens.dm index eee61832f823..195103244444 100644 --- a/code/datums/spells/rathens.dm +++ b/code/datums/spells/rathens.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/rathens +/datum/spell/rathens name = "Rathen's Secret" desc = "Summons a powerful shockwave around you that tears the appendix out of enemies, and occasionally removes their limbs." base_cooldown = 50 SECONDS @@ -8,12 +8,12 @@ cooldown_min = 20 SECONDS action_icon_state = "lungpunch" -/obj/effect/proc_holder/spell/rathens/create_new_targeting() +/datum/spell/rathens/create_new_targeting() var/datum/spell_targeting/targeted/T = new() T.max_targets = INFINITY return T -/obj/effect/proc_holder/spell/rathens/cast(list/targets, mob/user = usr) +/datum/spell/rathens/cast(list/targets, mob/user = usr) for(var/mob/living/carbon/human/H in targets) var/datum/effect_system/smoke_spread/s = new s.set_up(5, FALSE, H) diff --git a/code/datums/spells/rod_form.dm b/code/datums/spells/rod_form.dm index 3670b320b8eb..5f43e92f232f 100644 --- a/code/datums/spells/rod_form.dm +++ b/code/datums/spells/rod_form.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/rod_form +/datum/spell/rod_form name = "Rod Form" desc = "Take on the form of an immovable rod, destroying all in your path." clothes_req = TRUE @@ -13,10 +13,10 @@ sound = 'sound/effects/whoosh.ogg' var/rod_delay = 2 -/obj/effect/proc_holder/spell/rod_form/create_new_targeting() +/datum/spell/rod_form/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/rod_form/cast(list/targets,mob/user = usr) +/datum/spell/rod_form/cast(list/targets,mob/user = usr) if(get_turf(user) != user.loc) to_chat(user, "You cannot summon a rod in the ether, the spell fizzles out!") revert_cast() diff --git a/code/datums/spells/sentient_sword_lunge.dm b/code/datums/spells/sentient_sword_lunge.dm index c5b0520152b9..725bc77846c4 100644 --- a/code/datums/spells/sentient_sword_lunge.dm +++ b/code/datums/spells/sentient_sword_lunge.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/sentient_sword_lunge +/datum/spell/sentient_sword_lunge name = "Lunge" desc = "Lunge at something in your view range." clothes_req = FALSE @@ -8,10 +8,10 @@ sound = 'sound/magic/repulse.ogg' action_icon_state = "lunge" -/obj/effect/proc_holder/spell/sentient_sword_lunge/create_new_targeting() +/datum/spell/sentient_sword_lunge/create_new_targeting() return new /datum/spell_targeting/clicked_atom -/obj/effect/proc_holder/spell/sentient_sword_lunge/cast(list/targets, mob/user = usr) +/datum/spell/sentient_sword_lunge/cast(list/targets, mob/user = usr) if(!istype(user.loc, /obj/item)) to_chat(user, "You cannot use this ability if you're outside a blade!") return diff --git a/code/datums/spells/shapeshift.dm b/code/datums/spells/shapeshift.dm index 09d1439e951e..4b601beabe7c 100644 --- a/code/datums/spells/shapeshift.dm +++ b/code/datums/spells/shapeshift.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/shapeshift +/datum/spell/shapeshift name = "Shapechange" desc = "Take on the shape of another for a time to use their natural abilities. Once you've made your choice it cannot be changed." clothes_req = FALSE @@ -17,10 +17,10 @@ /mob/living/simple_animal/bot/ed209, /mob/living/simple_animal/hostile/construct/armoured) -/obj/effect/proc_holder/spell/shapeshift/create_new_targeting() +/datum/spell/shapeshift/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/shapeshift/cast(list/targets, mob/user = usr) +/datum/spell/shapeshift/cast(list/targets, mob/user = usr) for(var/mob/living/M in targets) if(!shapeshift_type) var/list/animal_list = list() @@ -36,7 +36,7 @@ else Shapeshift(M) -/obj/effect/proc_holder/spell/shapeshift/proc/Shapeshift(mob/living/caster) +/datum/spell/shapeshift/proc/Shapeshift(mob/living/caster) for(var/mob/living/M in caster) if(M.status_flags & GODMODE) to_chat(caster, "You're already shapeshifted!") @@ -53,7 +53,7 @@ caster.mind.transfer_to(shape) -/obj/effect/proc_holder/spell/shapeshift/proc/Restore(mob/living/shape) +/datum/spell/shapeshift/proc/Restore(mob/living/shape) var/mob/living/caster for(var/mob/living/M in shape) if(M in current_casters) @@ -72,7 +72,7 @@ shape.mind.transfer_to(caster) qdel(shape) //Gib it maybe ? -/obj/effect/proc_holder/spell/shapeshift/dragon +/datum/spell/shapeshift/dragon name = "Dragon Form" desc = "Take on the shape a lesser ash drake after a short delay." invocation = "*scream" @@ -82,7 +82,7 @@ current_casters = list() possible_shapes = list(/mob/living/simple_animal/hostile/megafauna/dragon/lesser) -/obj/effect/proc_holder/spell/shapeshift/dragon/Shapeshift(mob/living/caster) +/datum/spell/shapeshift/dragon/Shapeshift(mob/living/caster) caster.visible_message("[caster] screams in agony as bones and claws erupt out of their flesh!", "You begin channeling the transformation.") if(!do_after(caster, 5 SECONDS, FALSE, caster)) @@ -90,7 +90,7 @@ return return ..() -/obj/effect/proc_holder/spell/shapeshift/bats +/datum/spell/shapeshift/bats name = "Bat Form" desc = "Take on the shape of a swarm of bats." invocation = "none" @@ -103,7 +103,7 @@ current_casters = list() possible_shapes = list(/mob/living/simple_animal/hostile/scarybat/adminvampire) -/obj/effect/proc_holder/spell/shapeshift/hellhound +/datum/spell/shapeshift/hellhound name = "Lesser Hellhound Form" desc = "Take on the shape of a Hellhound." invocation = "none" @@ -117,7 +117,7 @@ current_casters = list() possible_shapes = list(/mob/living/simple_animal/hostile/hellhound) -/obj/effect/proc_holder/spell/shapeshift/hellhound/greater +/datum/spell/shapeshift/hellhound/greater name = "Greater Hellhound Form" shapeshift_type = /mob/living/simple_animal/hostile/hellhound/greater current_shapes = list(/mob/living/simple_animal/hostile/hellhound/greater) diff --git a/code/datums/spells/spacetime_dist.dm b/code/datums/spells/spacetime_dist.dm index 07635e89b910..4070c7a73405 100644 --- a/code/datums/spells/spacetime_dist.dm +++ b/code/datums/spells/spacetime_dist.dm @@ -1,5 +1,5 @@ // This could probably be an aoe spell but it's a little cursed, so I'm not touching it -/obj/effect/proc_holder/spell/spacetime_dist +/datum/spell/spacetime_dist name = "Spacetime Distortion" desc = "Entangle the strings of space-time in an area around you, \ randomizing the layout and making proper movement impossible. The strings vibrate... \ @@ -25,23 +25,23 @@ /// A lazylist of all scramble effects this spell has created. var/list/effects -/obj/effect/proc_holder/spell/spacetime_dist/Destroy() +/datum/spell/spacetime_dist/Destroy() QDEL_LIST_CONTENTS(effects) return ..() -/obj/effect/proc_holder/spell/spacetime_dist/create_new_targeting() +/datum/spell/spacetime_dist/create_new_targeting() var/datum/spell_targeting/spiral/targeting = new() targeting.range = scramble_radius + 3 * spell_level return targeting -/obj/effect/proc_holder/spell/spacetime_dist/on_purchase_upgrade() +/datum/spell/spacetime_dist/on_purchase_upgrade() . = ..() targeting = create_new_targeting() -/obj/effect/proc_holder/spell/spacetime_dist/cast_check(charge_check = TRUE, start_recharge = TRUE, mob/user = usr) +/datum/spell/spacetime_dist/cast_check(charge_check = TRUE, start_recharge = TRUE, mob/user = usr) return ..() && ready -/obj/effect/proc_holder/spell/spacetime_dist/cast(list/targets, mob/user = usr) +/datum/spell/spacetime_dist/cast(list/targets, mob/user = usr) . = ..() var/list/turf/to_switcharoo = targets if(!length(to_switcharoo)) @@ -64,12 +64,12 @@ effects += effect_b -/obj/effect/proc_holder/spell/spacetime_dist/after_cast(list/targets, mob/user) +/datum/spell/spacetime_dist/after_cast(list/targets, mob/user) . = ..() addtimer(CALLBACK(src, PROC_REF(clean_turfs)), duration) /// Callback which cleans up our effects list after the duration expires. -/obj/effect/proc_holder/spell/spacetime_dist/proc/clean_turfs() +/datum/spell/spacetime_dist/proc/clean_turfs() QDEL_LIST_CONTENTS(effects) ready = TRUE diff --git a/code/datums/spells/summon_supermatter.dm b/code/datums/spells/summon_supermatter.dm index bfda8c5d18d8..64ed0cfee858 100644 --- a/code/datums/spells/summon_supermatter.dm +++ b/code/datums/spells/summon_supermatter.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/aoe/conjure/summon_supermatter +/datum/spell/aoe/conjure/summon_supermatter name = "Summon Supermatter Crystal" desc = "Summons an active supermatter crystal. Imbues you with some supermatter, giving you resistance to it's hallucinations and radiation immunity." base_cooldown = 5 MINUTES @@ -8,7 +8,7 @@ summon_amt = 1 aoe_range = 0 -/obj/effect/proc_holder/spell/aoe/conjure/summon_supermatter/cast(list/targets, mob/living/user = usr) +/datum/spell/aoe/conjure/summon_supermatter/cast(list/targets, mob/living/user = usr) var/list/summoned_objects = ..() for(var/obj/machinery/atmospherics/supermatter_crystal/our_crystal in summoned_objects) addtimer(CALLBACK(our_crystal, TYPE_PROC_REF(/obj/machinery/atmospherics/supermatter_crystal, manual_start), 3000), 3 SECONDS) diff --git a/code/datums/spells/summonitem.dm b/code/datums/spells/summonitem.dm index 9ce1d514d2fb..d7b0cf278fab 100644 --- a/code/datums/spells/summonitem.dm +++ b/code/datums/spells/summonitem.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/summonitem +/datum/spell/summonitem name = "Instant Summons" desc = "This spell can be used to recall a previously marked item to your hand from anywhere in the universe." school = "transmutation" @@ -14,10 +14,10 @@ var/static/list/blacklisted_summons = list(/obj/machinery/computer/cryopod = TRUE, /obj/machinery/atmospherics = TRUE, /obj/structure/disposalholder = TRUE, /obj/machinery/disposal = TRUE) action_icon_state = "summons" -/obj/effect/proc_holder/spell/summonitem/create_new_targeting() +/datum/spell/summonitem/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/summonitem/cast(list/targets, mob/user = usr) +/datum/spell/summonitem/cast(list/targets, mob/user = usr) for(var/mob/living/target in targets) var/list/hand_items = list(target.get_active_hand(),target.get_inactive_hand()) var/butterfingers = FALSE diff --git a/code/datums/spells/touch_attacks.dm b/code/datums/spells/touch_attacks.dm index 611ab28fc487..948cfe80ef89 100644 --- a/code/datums/spells/touch_attacks.dm +++ b/code/datums/spells/touch_attacks.dm @@ -1,19 +1,19 @@ -/obj/effect/proc_holder/spell/touch +/datum/spell/touch var/hand_path = /obj/item/melee/touch_attack var/obj/item/melee/touch_attack/attached_hand = null var/on_remove_message = TRUE invocation_type = "none" //you scream on connecting, not summoning -/obj/effect/proc_holder/spell/touch/create_new_targeting() +/datum/spell/touch/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/touch/Click(mob/user = usr) +/datum/spell/touch/Click(mob/user = usr) if(attached_hand) discharge_hand(user, TRUE) return FALSE charge_hand(user) -/obj/effect/proc_holder/spell/touch/proc/charge_hand(mob/living/carbon/user) +/datum/spell/touch/proc/charge_hand(mob/living/carbon/user) var/hand_handled = 1 attached_hand = new hand_path(src) RegisterSignal(user, COMSIG_MOB_WILLINGLY_DROP, PROC_REF(discharge_hand)) @@ -36,7 +36,7 @@ to_chat(user, "You channel the power of the spell to your hand.") return 1 -/obj/effect/proc_holder/spell/touch/proc/discharge_hand(atom/target, any = FALSE) +/datum/spell/touch/proc/discharge_hand(atom/target, any = FALSE) SIGNAL_HANDLER var/mob/living/carbon/user = action.owner if(!istype(attached_hand)) @@ -48,7 +48,7 @@ to_chat(user, "You draw the power out of your hand.") -/obj/effect/proc_holder/spell/touch/disintegrate +/datum/spell/touch/disintegrate name = "Disintegrate" desc = "This spell charges your hand with vile energy that can be used to violently explode victims." hand_path = /obj/item/melee/touch_attack/disintegrate @@ -60,7 +60,7 @@ action_icon_state = "gib" -/obj/effect/proc_holder/spell/touch/flesh_to_stone +/datum/spell/touch/flesh_to_stone name = "Flesh to Stone" desc = "This spell charges your hand with the power to turn victims into inert statues for a long period of time." hand_path = /obj/item/melee/touch_attack/fleshtostone diff --git a/code/datums/spells/trigger.dm b/code/datums/spells/trigger.dm deleted file mode 100644 index 6737afac9532..000000000000 --- a/code/datums/spells/trigger.dm +++ /dev/null @@ -1,28 +0,0 @@ -/obj/effect/proc_holder/spell/trigger - desc = "This spell triggers another spell or a few." - - var/list/linked_spells = list() //those are just referenced by the trigger spell and are unaffected by it directly - var/list/starting_spells = list() //those are added on New() to contents from default spells and are deleted when the trigger spell is deleted to prevent memory leaks - -/obj/effect/proc_holder/spell/trigger/New() - ..() - - for(var/spell in starting_spells) - var/spell_to_add = text2path(spell) - new spell_to_add(src) //should result in adding to contents, needs testing - -/obj/effect/proc_holder/spell/trigger/Destroy() - for(var/spell in contents) - qdel(spell) - linked_spells = null - starting_spells = null - return ..() - -/obj/effect/proc_holder/spell/trigger/cast(list/targets, mob/user = usr) - for(var/mob/living/target in targets) - for(var/obj/effect/proc_holder/spell/spell in contents) - spell.perform(list(target), 0, user = user) - for(var/obj/effect/proc_holder/spell/spell in linked_spells) - spell.perform(list(target), 0, user = user) - - return diff --git a/code/datums/spells/turf_teleport.dm b/code/datums/spells/turf_teleport.dm index 4cbe53e51ca6..936d4c3fda9c 100644 --- a/code/datums/spells/turf_teleport.dm +++ b/code/datums/spells/turf_teleport.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/turf_teleport +/datum/spell/turf_teleport name = "Turf Teleport" desc = "This spell teleports the target to the turf in range." nonabstract_req = TRUE @@ -14,12 +14,12 @@ var/sound1 = 'sound/weapons/zapbang.ogg' var/sound2 = 'sound/weapons/zapbang.ogg' -/obj/effect/proc_holder/spell/turf_teleport/create_new_targeting() +/datum/spell/turf_teleport/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/turf_teleport/cast(list/targets,mob/living/user = usr) +/datum/spell/turf_teleport/cast(list/targets,mob/living/user = usr) if(sound1) - playsound(get_turf(user), sound1, 50,1) + playsound(get_turf(user), sound1, 50, TRUE) for(var/mob/living/target in targets) var/list/turfs = new/list() diff --git a/code/datums/spells/wizard_spells.dm b/code/datums/spells/wizard_spells.dm index c39d4742f348..5317e92dff56 100644 --- a/code/datums/spells/wizard_spells.dm +++ b/code/datums/spells/wizard_spells.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/projectile/magic_missile +/datum/spell/projectile/magic_missile name = "Magic Missile" desc = "This spell fires several, slow moving, magic projectiles at nearby targets." @@ -12,7 +12,7 @@ proj_icon_state = "magicm" proj_name = "a magic missile" proj_lingering = 1 - proj_type = "/obj/effect/proc_holder/spell/inflict_handler/magic_missile" + proj_type = /obj/item/projectile/magic/magic_missile proj_lifespan = 20 proj_step_delay = 2 @@ -25,33 +25,33 @@ sound = 'sound/magic/magic_missile.ogg' -/obj/effect/proc_holder/spell/projectile/magic_missile/create_new_targeting() +/datum/spell/projectile/magic_missile/create_new_targeting() var/datum/spell_targeting/targeted/T = new() T.allowed_type = /mob/living T.max_targets = INFINITY return T -/obj/effect/proc_holder/spell/inflict_handler/magic_missile - amt_weakened = 6 SECONDS - sound = 'sound/magic/mm_hit.ogg' - +/obj/item/projectile/magic/magic_missile + name = "Magic Missile" + hitsound = 'sound/magic/mm_hit.ogg' + weaken = 6 SECONDS -/obj/effect/proc_holder/spell/projectile/honk_missile +/datum/spell/projectile/honk_missile name = "Honk Missile" desc = "This spell fires several, slow moving, magic bikehorns at nearby targets." school = "evocation" - base_cooldown = 60 + base_cooldown = 6 SECONDS clothes_req = FALSE invocation = "HONK GY AMA" invocation_type = "shout" - cooldown_min = 60 //35 deciseconds reduction per rank + cooldown_min = 6 SECONDS proj_icon = 'icons/obj/items.dmi' proj_icon_state = "bike_horn" proj_name = "A bike horn" proj_lingering = 1 - proj_type = "/obj/effect/proc_holder/spell/inflict_handler/honk_missile" + proj_type = /obj/item/projectile/magic/magic_missile/honk_missile proj_lifespan = 20 proj_step_delay = 5 @@ -65,25 +65,25 @@ sound = 'sound/items/bikehorn.ogg' -/obj/effect/proc_holder/spell/projectile/honk_missile/create_new_targeting() +/datum/spell/projectile/honk_missile/create_new_targeting() var/datum/spell_targeting/targeted/T = new() T.allowed_type = /mob/living T.max_targets = INFINITY return T -/obj/effect/proc_holder/spell/inflict_handler/honk_missile - amt_weakened = 6 SECONDS - sound = 'sound/items/bikehorn.ogg' +/obj/item/projectile/magic/magic_missile/honk_missile + name = "Funny Missile" + hitsound = 'sound/items/bikehorn.ogg' -/obj/effect/proc_holder/spell/noclothes +/datum/spell/noclothes name = "No Clothes" desc = "This always-on spell allows you to cast magic without your garments." action_icon_state = "no_clothes" -/obj/effect/proc_holder/spell/noclothes/create_new_targeting() +/datum/spell/noclothes/create_new_targeting() return new /datum/spell_targeting/self // Dummy value -/obj/effect/proc_holder/spell/genetic/mutate +/datum/spell/genetic/mutate name = "Mutate" desc = "This spell causes you to turn into a hulk and gain laser vision for a short while." @@ -102,14 +102,14 @@ action_icon_state = "mutate" sound = 'sound/magic/mutate.ogg' -/obj/effect/proc_holder/spell/genetic/mutate/Initialize(mapload) - . = ..() +/datum/spell/genetic/mutate/New() + ..() mutations = list(GLOB.hulkblock) -/obj/effect/proc_holder/spell/genetic/mutate/create_new_targeting() +/datum/spell/genetic/mutate/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/smoke +/datum/spell/smoke name = "Smoke" desc = "This spell spawns a cloud of choking smoke at your location and does not require wizard garb." @@ -125,13 +125,13 @@ action_icon_state = "smoke" -/obj/effect/proc_holder/spell/smoke/create_new_targeting() +/datum/spell/smoke/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/emplosion/disable_tech +/datum/spell/emplosion/disable_tech name = "Disable Tech" desc = "This spell disables all weapons, cameras and most other technology in range." - base_cooldown = 400 + base_cooldown = 40 SECONDS clothes_req = TRUE invocation = "NEC CANTIO" invocation_type = "shout" @@ -142,7 +142,7 @@ sound = 'sound/magic/disable_tech.ogg' -/obj/effect/proc_holder/spell/turf_teleport/blink +/datum/spell/turf_teleport/blink name = "Blink" desc = "This spell randomly teleports you a short distance." @@ -167,10 +167,10 @@ sound1 = 'sound/magic/blink.ogg' sound2 = 'sound/magic/blink.ogg' -/obj/effect/proc_holder/spell/turf_teleport/blink/create_new_targeting() +/datum/spell/turf_teleport/blink/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/area_teleport/teleport +/datum/spell/area_teleport/teleport name = "Teleport" desc = "This spell teleports you to a type of area of your selection." @@ -187,10 +187,10 @@ sound1 = 'sound/magic/teleport_diss.ogg' sound2 = 'sound/magic/teleport_app.ogg' -/obj/effect/proc_holder/spell/area_teleport/teleport/create_new_targeting() +/datum/spell/area_teleport/teleport/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/return_to_teacher +/datum/spell/return_to_teacher name = "Return to Teacher" desc = "This spell teleports you back to your teacher." @@ -204,16 +204,16 @@ action_icon_state = "spell_teleport" var/datum/mind/teacher -/obj/effect/proc_holder/spell/return_to_teacher/create_new_targeting() +/datum/spell/return_to_teacher/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/return_to_teacher/cast(list/targets, mob/living/user = usr) +/datum/spell/return_to_teacher/cast(list/targets, mob/living/user = usr) if(!(teacher && teacher.current)) to_chat(user, "The link to your teacher is broken!") return do_teleport(user, teacher.current, 1, sound_in = 'sound/magic/blink.ogg', sound_out = 'sound/magic/blink.ogg', safe_turf_pick = TRUE) -/obj/effect/proc_holder/spell/forcewall +/datum/spell/forcewall name = "Force Wall" desc = "This spell creates a 3 tile wide unbreakable wall that only you can pass through, and does not need wizard garb. Lasts 30 seconds." @@ -227,10 +227,10 @@ cooldown_min = 5 SECONDS //25 deciseconds reduction per rank var/wall_type = /obj/effect/forcefield/wizard -/obj/effect/proc_holder/spell/forcewall/create_new_targeting() +/datum/spell/forcewall/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/forcewall/cast(list/targets, mob/user = usr) +/datum/spell/forcewall/cast(list/targets, mob/user = usr) new wall_type(get_turf(user), user) if(user.dir == SOUTH || user.dir == NORTH) new wall_type(get_step(user, EAST), user) @@ -239,10 +239,10 @@ new wall_type(get_step(user, NORTH), user) new wall_type(get_step(user, SOUTH), user) -/obj/effect/proc_holder/spell/aoe/conjure/timestop +/datum/spell/aoe/conjure/timestop name = "Stop Time" desc = "This spell stops time for everyone except for you, allowing you to move freely while your enemies and even projectiles are frozen." - base_cooldown = 500 + base_cooldown = 50 SECONDS clothes_req = TRUE invocation = "TOKI WO TOMARE" invocation_type = "shout" @@ -255,7 +255,7 @@ aoe_range = 0 -/obj/effect/proc_holder/spell/aoe/conjure/carp +/datum/spell/aoe/conjure/carp name = "Summon Carp" desc = "This spell conjures a simple carp." @@ -270,7 +270,7 @@ cast_sound = 'sound/magic/summon_karp.ogg' aoe_range = 1 -/obj/effect/proc_holder/spell/aoe/conjure/construct +/datum/spell/aoe/conjure/construct name = "Artificer" desc = "This spell conjures a construct which may be controlled by Shades" @@ -286,7 +286,7 @@ cast_sound = 'sound/magic/summonitems_generic.ogg' aoe_range = 0 -/obj/effect/proc_holder/spell/aoe/conjure/creature +/datum/spell/aoe/conjure/creature name = "Summon Creature Swarm" desc = "This spell tears the fabric of reality, allowing horrific daemons to spill forth" @@ -301,10 +301,9 @@ cast_sound = 'sound/magic/summonitems_generic.ogg' aoe_range = 3 -/obj/effect/proc_holder/spell/trigger/blind +/datum/spell/genetic/blind name = "Blind" desc = "This spell temporarily blinds a single person and does not require wizard garb." - school = "transmutation" base_cooldown = 10 SECONDS clothes_req = FALSE @@ -312,30 +311,22 @@ invocation_type = "whisper" message = "Your eyes cry out in pain!" cooldown_min = 2 SECONDS + traits = list(TRAIT_BLIND) - starting_spells = list("/obj/effect/proc_holder/spell/inflict_handler/blind","/obj/effect/proc_holder/spell/genetic/blind") - - action_icon_state = "blind" + duration = 30 SECONDS + sound = 'sound/magic/blind.ogg' -/obj/effect/proc_holder/spell/trigger/blind/create_new_targeting() +/datum/spell/genetic/blind/create_new_targeting() var/datum/spell_targeting/click/C = new() C.allowed_type = /mob/living return C -/obj/effect/proc_holder/spell/inflict_handler/blind - amt_eye_blind = 10 - amt_eye_blurry = 20 - sound = 'sound/magic/blind.ogg' - -/obj/effect/proc_holder/spell/genetic/blind - traits = list(TRAIT_BLIND) - duration = 300 - sound = 'sound/magic/blind.ogg' - -/obj/effect/proc_holder/spell/genetic/blind/create_new_targeting() - return new /datum/spell_targeting/self // Dummy value since it is never used by an user directly +/datum/spell/genetic/blind/do_additional_effects(mob/living/target) + target.EyeBlurry(20 SECONDS) + target.EyeBlind(10 SECONDS) + SEND_SOUND(target, sound('sound/magic/blind.ogg')) -/obj/effect/proc_holder/spell/fireball +/datum/spell/fireball name = "Fireball" desc = "This spell fires a fireball at a target and does not require wizard garb." @@ -355,21 +346,21 @@ active = FALSE -/obj/effect/proc_holder/spell/fireball/apprentice +/datum/spell/fireball/apprentice centcom_cancast = FALSE -/obj/effect/proc_holder/spell/fireball/create_new_targeting() +/datum/spell/fireball/create_new_targeting() var/datum/spell_targeting/clicked_atom/external/C = new() C.range = 20 return C -/obj/effect/proc_holder/spell/fireball/update_icon_state() +/datum/spell/fireball/update_spell_icon() if(!action) return action.button_icon_state = "fireball[active]" action.UpdateButtons() -/obj/effect/proc_holder/spell/fireball/cast(list/targets, mob/living/user = usr) +/datum/spell/fireball/cast(list/targets, mob/living/user = usr) var/target = targets[1] //There is only ever one target for fireball var/turf/T = user.loc var/turf/U = get_step(user, user.dir) // Get the tile infront of the move, based on their direction @@ -386,7 +377,7 @@ return TRUE -/obj/effect/proc_holder/spell/fireball/toolbox +/datum/spell/fireball/toolbox name = "Homing Toolbox" desc = "This spell summons and throws a magical homing toolbox at your opponent." sound = 'sound/weapons/smash.ogg' @@ -396,7 +387,7 @@ selection_activated_message = "You prepare to cast your homing toolbox! Left-click to cast at a target!" selection_deactivated_message = "You unrobust your toolbox...for now." -/obj/effect/proc_holder/spell/fireball/homing +/datum/spell/fireball/homing name = "Greater Homing Fireball" desc = "This spell fires a strong homing fireball at a target." invocation = "ZI-ONI SOMA" @@ -405,10 +396,10 @@ selection_activated_message = "You prepare to cast your greater homing fireball spell! Left-click to cast at a target!" base_cooldown = 6 SECONDS -/obj/effect/proc_holder/spell/aoe/repulse +/datum/spell/aoe/repulse name = "Repulse" desc = "This spell throws everything around the user away." - base_cooldown = 400 + base_cooldown = 40 SECONDS clothes_req = TRUE invocation = "GITTAH WEIGH" invocation_type = "shout" @@ -419,12 +410,12 @@ action_icon_state = "repulse" aoe_range = 5 -/obj/effect/proc_holder/spell/aoe/repulse/create_new_targeting() +/datum/spell/aoe/repulse/create_new_targeting() var/datum/spell_targeting/aoe/turf/targeting = new() targeting.range = aoe_range return targeting -/obj/effect/proc_holder/spell/aoe/repulse/cast(list/targets, mob/user = usr, stun_amt = 4 SECONDS) +/datum/spell/aoe/repulse/cast(list/targets, mob/user = usr, stun_amt = 4 SECONDS) var/list/thrownatoms = list() var/atom/throwtarget var/distfromcaster @@ -455,24 +446,24 @@ spawn(0) AM.throw_at(throwtarget, ((clamp((maxthrow - (clamp(distfromcaster - 2, 0, distfromcaster))), 3, maxthrow))), 1)//So stuff gets tossed around at the same time. -/obj/effect/proc_holder/spell/sacred_flame +/datum/spell/sacred_flame name = "Sacred Flame" desc = "Makes everyone around you more flammable, and lights yourself on fire." - base_cooldown = 60 + base_cooldown = 6 SECONDS clothes_req = FALSE invocation = "FI'RAN DADISKO" invocation_type = "shout" action_icon_state = "sacredflame" sound = 'sound/magic/fireball.ogg' -/obj/effect/proc_holder/spell/sacred_flame/create_new_targeting() +/datum/spell/sacred_flame/create_new_targeting() var/datum/spell_targeting/aoe/A = new() A.include_user = TRUE A.range = 6 A.allowed_type = /mob/living return A -/obj/effect/proc_holder/spell/sacred_flame/cast(list/targets, mob/user = usr) +/datum/spell/sacred_flame/cast(list/targets, mob/user = usr) for(var/mob/living/L in targets) L.adjust_fire_stacks(20) if(isliving(user)) diff --git a/code/datums/uplink_items/uplink_general.dm b/code/datums/uplink_items/uplink_general.dm index 162c2e18527b..7f36a7275447 100644 --- a/code/datums/uplink_items/uplink_general.dm +++ b/code/datums/uplink_items/uplink_general.dm @@ -808,6 +808,13 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) item = /obj/item/bio_chip_implanter/traitor cost = 50 +/datum/uplink_item/bio_chips/proto_adrenal + name = "Proto-Adrenal Bio-chip" + desc = "A old prototype of the Adrenalin implant, that grants the user 4 seconds of antistun, getting them back on their feet instantly once, but nothing more. Speed and healing sold seperately." + reference = "PAI" + item = /obj/item/bio_chip_implanter/proto_adrenalin + cost = 18 + /datum/uplink_item/bio_chips/adrenal name = "Adrenal Bio-chip" desc = "A bio-chip injected into the body, and later activated manually to inject a chemical cocktail, which has a mild healing effect along with removing and reducing the time of all stuns and increasing movement speed. Can be activated up to 3 times." @@ -852,6 +859,13 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) category = "(Pointless) Badassery" surplus = 0 +/datum/uplink_item/badass/pen + name = "Syndicate Fountain Pen" + desc = "A slick Syndicate-branded pen, to show everyone at the meeting that you mean business." + reference = "PEN" + item = /obj/item/pen/multi/syndicate + cost = 1 + /datum/uplink_item/badass/syndiecigs name = "Syndicate Smokes" desc = "Strong flavor, dense smoke, infused with omnizine." diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index b0eb9888f12b..71b3b64014e7 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -35,8 +35,6 @@ var/has_gravity = TRUE - var/no_air = null - var/air_doors_activated = FALSE var/tele_proof = FALSE diff --git a/code/game/dna/mutations/disabilities.dm b/code/game/dna/mutations/disabilities.dm index 60c4e85bff4e..f6b570d6f4db 100644 --- a/code/game/dna/mutations/disabilities.dm +++ b/code/game/dna/mutations/disabilities.dm @@ -481,13 +481,13 @@ desc = "The subject becomes able to convert excess cellular energy into thermal energy." activation_messages = list("You suddenly feel rather hot.") deactivation_messages = list("You no longer feel uncomfortably hot.") - spelltype = /obj/effect/proc_holder/spell/immolate + spelltype = /datum/spell/immolate /datum/mutation/grant_spell/immolate/New() ..() block = GLOB.immolateblock -/obj/effect/proc_holder/spell/immolate +/datum/spell/immolate name = "Incendiary Mitochondria" desc = "The subject becomes able to convert excess cellular energy into thermal energy." panel = "Abilities" @@ -501,10 +501,10 @@ action_icon_state = "genetic_incendiary" -/obj/effect/proc_holder/spell/immolate/create_new_targeting() +/datum/spell/immolate/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/immolate/cast(list/targets, mob/living/user = usr) +/datum/spell/immolate/cast(list/targets, mob/living/user = usr) var/mob/living/carbon/L = user L.adjust_fire_stacks(0.5) L.visible_message("[L.name] suddenly bursts into flames!") diff --git a/code/game/dna/mutations/mutation_powers.dm b/code/game/dna/mutations/mutation_powers.dm index d142685d78f7..79fe7d0fa996 100644 --- a/code/game/dna/mutations/mutation_powers.dm +++ b/code/game/dna/mutations/mutation_powers.dm @@ -247,7 +247,7 @@ ///////////////////////////////////////////////////////////////////////////////////////// /datum/mutation/grant_spell - var/obj/effect/proc_holder/spell/spelltype + var/datum/spell/spelltype /datum/mutation/grant_spell/activate(mob/M) M.AddSpell(new spelltype(null)) @@ -255,7 +255,7 @@ return TRUE /datum/mutation/grant_spell/deactivate(mob/M) - for(var/obj/effect/proc_holder/spell/S in M.mob_spell_list) + for(var/datum/spell/S in M.mob_spell_list) if(istype(S, spelltype)) M.RemoveSpell(S) ..() @@ -268,13 +268,13 @@ activation_messages = list("You notice a strange cold tingle in your fingertips.") deactivation_messages = list("Your fingers feel warmer.") instability = GENE_INSTABILITY_MODERATE - spelltype = /obj/effect/proc_holder/spell/cryokinesis + spelltype = /datum/spell/cryokinesis /datum/mutation/grant_spell/cryo/New() ..() block = GLOB.cryoblock -/obj/effect/proc_holder/spell/cryokinesis +/datum/spell/cryokinesis name = "Cryokinesis" desc = "Drops the bodytemperature of another person." panel = "Abilities" @@ -291,7 +291,7 @@ action_icon_state = "genetic_cryo" -/obj/effect/proc_holder/spell/cryokinesis/create_new_targeting() +/datum/spell/cryokinesis/create_new_targeting() var/datum/spell_targeting/click/T = new() T.allowed_type = /mob/living/carbon T.click_radius = 0 @@ -300,7 +300,7 @@ T.include_user = TRUE return T -/obj/effect/proc_holder/spell/cryokinesis/cast(list/targets, mob/user = usr) +/datum/spell/cryokinesis/cast(list/targets, mob/user = usr) var/mob/living/carbon/C = targets[1] @@ -339,13 +339,13 @@ deactivation_messages = list("You don't feel quite so hungry anymore.") instability = GENE_INSTABILITY_MODERATE - spelltype=/obj/effect/proc_holder/spell/eat + spelltype=/datum/spell/eat /datum/mutation/grant_spell/mattereater/New() ..() block = GLOB.eatblock -/obj/effect/proc_holder/spell/eat +/datum/spell/eat name = "Eat" desc = "Eat just about anything!" panel = "Abilities" @@ -358,10 +358,10 @@ action_icon_state = "genetic_eat" -/obj/effect/proc_holder/spell/eat/create_new_targeting() +/datum/spell/eat/create_new_targeting() return new /datum/spell_targeting/matter_eater -/obj/effect/proc_holder/spell/eat/can_cast(mob/user = usr, charge_check = TRUE, show_message = FALSE) +/datum/spell/eat/can_cast(mob/user = usr, charge_check = TRUE, show_message = FALSE) . = ..() if(!.) return @@ -374,7 +374,7 @@ can_eat = FALSE return can_eat -/obj/effect/proc_holder/spell/eat/proc/doHeal(mob/user) +/datum/spell/eat/proc/doHeal(mob/user) if(ishuman(user)) var/mob/living/carbon/human/H = user for(var/name in H.bodyparts_by_name) @@ -390,7 +390,7 @@ -/obj/effect/proc_holder/spell/eat/cast(list/targets, mob/user = usr) +/datum/spell/eat/cast(list/targets, mob/user = usr) if(!targets.len) to_chat(user, "No target found in range.") return @@ -462,13 +462,13 @@ deactivation_messages = list("Your leg muscles shrink back to normal.") instability = GENE_INSTABILITY_MODERATE - spelltype =/obj/effect/proc_holder/spell/leap + spelltype =/datum/spell/leap /datum/mutation/grant_spell/jumpy/New() ..() block = GLOB.jumpblock -/obj/effect/proc_holder/spell/leap +/datum/spell/leap name = "Jump" desc = "Leap great distances!" panel = "Abilities" @@ -481,10 +481,10 @@ action_icon_state = "genetic_jump" -/obj/effect/proc_holder/spell/leap/create_new_targeting() +/datum/spell/leap/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/leap/cast(list/targets, mob/living/user = usr) +/datum/spell/leap/cast(list/targets, mob/living/user = usr) var/failure = FALSE if(ismob(user.loc) || IS_HORIZONTAL(user) || user.IsStunned() || user.buckled || user.stat) to_chat(user, "You can't jump right now!") @@ -551,7 +551,7 @@ name = "Polymorphism" desc = "Enables the subject to reconfigure their appearance to mimic that of others." - spelltype =/obj/effect/proc_holder/spell/polymorph + spelltype =/datum/spell/polymorph //cooldown = 1800 activation_messages = list("You don't feel entirely like yourself somehow.") deactivation_messages = list("You feel secure in your identity.") @@ -561,7 +561,7 @@ ..() block = GLOB.polymorphblock -/obj/effect/proc_holder/spell/polymorph +/datum/spell/polymorph name = "Polymorph" desc = "Mimic the appearance of others!" panel = "Abilities" @@ -577,7 +577,7 @@ action_icon_state = "genetic_poly" -/obj/effect/proc_holder/spell/polymorph/create_new_targeting() +/datum/spell/polymorph/create_new_targeting() var/datum/spell_targeting/click/T = new() T.try_auto_target = FALSE T.click_radius = -1 @@ -585,7 +585,7 @@ T.selection_type = SPELL_SELECTION_RANGE return T -/obj/effect/proc_holder/spell/polymorph/cast(list/targets, mob/user = usr) +/datum/spell/polymorph/cast(list/targets, mob/user = usr) var/mob/living/carbon/human/target = targets[1] user.visible_message("[user]'s body shifts and contorts.") @@ -605,7 +605,7 @@ name = "Empathic Thought" desc = "The subject becomes able to read the minds of others for certain information." - spelltype = /obj/effect/proc_holder/spell/empath + spelltype = /datum/spell/empath activation_messages = list("You suddenly notice more about others than you did before.") deactivation_messages = list("You no longer feel able to sense intentions.") instability = GENE_INSTABILITY_MINOR @@ -614,10 +614,10 @@ ..() block = GLOB.empathblock -/obj/effect/proc_holder/spell/empath +/datum/spell/empath name = "Read Mind" desc = "Read the minds of others for information." - base_cooldown = 180 + base_cooldown = 18 SECONDS clothes_req = FALSE human_req = TRUE stat_allowed = CONSCIOUS @@ -625,13 +625,13 @@ action_icon_state = "genetic_empath" -/obj/effect/proc_holder/spell/empath/create_new_targeting() +/datum/spell/empath/create_new_targeting() var/datum/spell_targeting/targeted/T = new() T.allowed_type = /mob/living/carbon T.selection_type = SPELL_SELECTION_RANGE return T -/obj/effect/proc_holder/spell/empath/cast(list/targets, mob/user = usr) +/datum/spell/empath/cast(list/targets, mob/user = usr) for(var/mob/living/carbon/M in targets) if(!iscarbon(M)) to_chat(user, "You may only use this on other organic beings.") @@ -714,7 +714,7 @@ /datum/mutation/grant_spell/morph name = "Morphism" desc = "Enables the subject to reconfigure their appearance to that of any human." - spelltype =/obj/effect/proc_holder/spell/morph + spelltype =/datum/spell/morph activation_messages = list("Your body feels like it can alter its appearance.") deactivation_messages = list("Your body doesn't feel capable of altering its appearance.") instability = GENE_INSTABILITY_MODERATE @@ -723,7 +723,7 @@ ..() block = GLOB.morphblock -/obj/effect/proc_holder/spell/morph +/datum/spell/morph name = "Morph" desc = "Mimic the appearance of your choice!" panel = "Abilities" @@ -735,10 +735,10 @@ action_icon_state = "genetic_morph" -/obj/effect/proc_holder/spell/morph/create_new_targeting() +/datum/spell/morph/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/morph/cast(list/targets, mob/user = usr) +/datum/spell/morph/cast(list/targets, mob/user = usr) if(!ishuman(user)) return @@ -897,7 +897,7 @@ deactivation_messages = list("You no longer feel you can project your thoughts.") instability = GENE_INSTABILITY_MINOR - spelltype =/obj/effect/proc_holder/spell/remotetalk + spelltype =/datum/spell/remotetalk /datum/mutation/grant_spell/remotetalk/New() ..() @@ -905,15 +905,15 @@ /datum/mutation/grant_spell/remotetalk/activate(mob/living/M) ..() - M.AddSpell(new /obj/effect/proc_holder/spell/mindscan(null)) + M.AddSpell(new /datum/spell/mindscan(null)) /datum/mutation/grant_spell/remotetalk/deactivate(mob/user) ..() - for(var/obj/effect/proc_holder/spell/S in user.mob_spell_list) - if(istype(S, /obj/effect/proc_holder/spell/mindscan)) + for(var/datum/spell/S in user.mob_spell_list) + if(istype(S, /datum/spell/mindscan)) user.RemoveSpell(S) -/obj/effect/proc_holder/spell/remotetalk +/datum/spell/remotetalk name = "Project Mind" desc = "Make people understand your thoughts!" base_cooldown = 0 @@ -924,10 +924,10 @@ action_icon_state = "genetic_project" -/obj/effect/proc_holder/spell/remotetalk/create_new_targeting() +/datum/spell/remotetalk/create_new_targeting() return new /datum/spell_targeting/telepathic -/obj/effect/proc_holder/spell/remotetalk/cast(list/targets, mob/user = usr) +/datum/spell/remotetalk/cast(list/targets, mob/user = usr) if(!ishuman(user)) return if(user.mind?.miming) // Dont let mimes telepathically talk @@ -949,7 +949,7 @@ for(var/mob/dead/observer/G in GLOB.player_list) G.show_message("Telepathic message from [user] ([ghost_follow_link(user, ghost=G)]) to [target] ([ghost_follow_link(target, ghost=G)]): [say]") -/obj/effect/proc_holder/spell/mindscan +/datum/spell/mindscan name = "Scan Mind" desc = "Offer people a chance to share their thoughts!" base_cooldown = 0 @@ -959,10 +959,10 @@ action_icon_state = "genetic_mindscan" var/list/available_targets = list() -/obj/effect/proc_holder/spell/mindscan/create_new_targeting() +/datum/spell/mindscan/create_new_targeting() return new /datum/spell_targeting/telepathic -/obj/effect/proc_holder/spell/mindscan/cast(list/targets, mob/user = usr) +/datum/spell/mindscan/cast(list/targets, mob/user = usr) if(!ishuman(user)) return for(var/mob/living/target in targets) @@ -974,13 +974,13 @@ available_targets += target addtimer(CALLBACK(src, PROC_REF(removeAvailability), target), 100) -/obj/effect/proc_holder/spell/mindscan/proc/removeAvailability(mob/living/target) +/datum/spell/mindscan/proc/removeAvailability(mob/living/target) if(target in available_targets) available_targets -= target if(!(target in available_targets)) target.show_message("You feel the sensation fade...") -/obj/effect/proc_holder/spell/mindscan/Topic(href, href_list) +/datum/spell/mindscan/Topic(href, href_list) var/mob/living/user if(href_list["user"]) user = locateUID(href_list["user"]) @@ -1005,7 +1005,7 @@ for(var/mob/dead/observer/G in GLOB.player_list) G.show_message("Telepathic response from [target] ([ghost_follow_link(target, ghost=G)]) to [user] ([ghost_follow_link(user, ghost=G)]): [say]") -/obj/effect/proc_holder/spell/mindscan/Destroy() +/datum/spell/mindscan/Destroy() available_targets.Cut() return ..() @@ -1015,7 +1015,7 @@ deactivation_messages = list("Your mind can no longer can see things from afar.") instability = GENE_INSTABILITY_MINOR - spelltype =/obj/effect/proc_holder/spell/remoteview + spelltype =/datum/spell/remoteview /datum/mutation/grant_spell/remoteview/New() ..() @@ -1028,10 +1028,10 @@ H.remoteview_target = null H.reset_perspective() -/obj/effect/proc_holder/spell/remoteview +/datum/spell/remoteview name = "Remote View" desc = "Spy on people from any range!" - base_cooldown = 100 + base_cooldown = 10 SECONDS clothes_req = FALSE stat_allowed = CONSCIOUS @@ -1039,10 +1039,10 @@ action_icon_state = "genetic_view" -/obj/effect/proc_holder/spell/remoteview/create_new_targeting() +/datum/spell/remoteview/create_new_targeting() return new /datum/spell_targeting/remoteview -/obj/effect/proc_holder/spell/remoteview/cast(list/targets, mob/user = usr) +/datum/spell/remoteview/cast(list/targets, mob/user = usr) var/mob/living/carbon/human/H if(ishuman(user)) H = user diff --git a/code/game/gamemodes/cult/blood_magic.dm b/code/game/gamemodes/cult/blood_magic.dm index 47ca9460e583..357665e82d91 100644 --- a/code/game/gamemodes/cult/blood_magic.dm +++ b/code/game/gamemodes/cult/blood_magic.dm @@ -265,7 +265,7 @@ name = "Hallucinations" desc = "Gives hallucinations to a target at range. A silent and invisible spell." button_icon_state = "horror" - var/obj/effect/proc_holder/horror/PH + var/datum/spell/horror/PH charges = 4 /datum/action/innate/cult/blood_spell/horror/New() @@ -274,7 +274,7 @@ ..() /datum/action/innate/cult/blood_spell/horror/Destroy() - var/obj/effect/proc_holder/horror/destroy = PH + var/datum/spell/horror/destroy = PH . = ..() if(!QDELETED(destroy)) QDEL_NULL(destroy) @@ -283,24 +283,24 @@ PH.toggle(owner) //the important bit return TRUE -/obj/effect/proc_holder/horror +/datum/spell/horror active = FALSE ranged_mousepointer = 'icons/effects/cult_target.dmi' var/datum/action/innate/cult/blood_spell/attached_action -/obj/effect/proc_holder/horror/Destroy() +/datum/spell/horror/Destroy() var/datum/action/innate/cult/blood_spell/AA = attached_action . = ..() if(!QDELETED(AA)) QDEL_NULL(AA) -/obj/effect/proc_holder/horror/proc/toggle(mob/user) +/datum/spell/horror/proc/toggle(mob/user) if(active) remove_ranged_ability(user, "You dispel the magic...") else add_ranged_ability(user, "You prepare to horrify a target...") -/obj/effect/proc_holder/horror/InterceptClickOn(mob/living/user, params, atom/target) +/datum/spell/horror/InterceptClickOn(mob/living/user, params, atom/target) if(..()) return if(ranged_ability_user.incapacitated() || !IS_CULTIST(user)) diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 6e59cdaf3467..84832aeaabe6 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -40,6 +40,7 @@ var/list/blob_overminds = list() var/list/datum/station_goal/station_goals = list() // A list of all station goals for this game mode + var/list/datum/station_goal/secondary/secondary_goals = list() // A list of all secondary goals issued /// Each item in this list can only be rolled once on average. var/list/single_antag_positions = list("Head of Personnel", "Chief Engineer", "Research Director", "Chief Medical Officer", "Quartermaster") @@ -177,6 +178,8 @@ SSblackbox.record_feedback("nested tally", "round_end_stats", escaped_on_pod_3, list("escapees", "on_pod_3")) if(escaped_on_pod_5) SSblackbox.record_feedback("nested tally", "round_end_stats", escaped_on_pod_5, list("escapees", "on_pod_5")) + for(var/tech_id in SSeconomy.tech_levels) + SSblackbox.record_feedback("tally", "cargo max tech level sold", SSeconomy.tech_levels[tech_id], tech_id) GLOB.discord_manager.send2discord_simple(DISCORD_WEBHOOK_PRIMARY, "A round of [name] has ended - [surviving_total] survivors, [ghosts] ghosts. <@&[GLOB.configuration.discord.new_round_waiting_role]>") // SS220 Addition if(SSredis.connected) @@ -466,12 +469,14 @@ /datum/game_mode/proc/generate_station_goals() var/list/possible = list() for(var/T in subtypesof(/datum/station_goal)) + if(ispath(T, /datum/station_goal/secondary)) + continue var/datum/station_goal/G = T if(config_tag in initial(G.gamemode_blacklist)) continue - possible += T + possible += G var/goal_weights = 0 - while(possible.len && goal_weights < STATION_GOAL_BUDGET) + while(length(possible) && goal_weights < STATION_GOAL_BUDGET) var/datum/station_goal/picked = pick_n_take(possible) goal_weights += initial(picked.weight) station_goals += new picked @@ -492,9 +497,24 @@ print_command_report(message_text, "NAS Trurl Orders", FALSE) /datum/game_mode/proc/declare_station_goal_completion() - for(var/V in station_goals) - var/datum/station_goal/G = V - G.print_result() + for(var/datum/station_goal/goal in station_goals) + goal.print_result() + + var/departments = list() + for(var/datum/station_goal/secondary/goal in secondary_goals) + if(goal.completed) + if(!departments[goal.department]) + departments[goal.department] = 0 + departments[goal.department]++ + + to_chat(world, "Secondary Goals:") + var/any = FALSE + for(var/department in departments) + if(departments[department]) + any = TRUE + to_chat(world, "[department]: [departments[department]] completed!") + if(!any) + to_chat(world, "None completed!") /datum/game_mode/proc/generate_station_trait_report() var/something_to_print = FALSE diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm index 114bc2a24e5e..b399ca1bde46 100644 --- a/code/game/gamemodes/malfunction/Malf_Modules.dm +++ b/code/game/gamemodes/malfunction/Malf_Modules.dm @@ -4,117 +4,91 @@ // crit percent #define MALF_AI_ROLL_CRIT_CHANCE 5 -//The malf AI action subtype. All malf actions are subtypes of this. -/datum/action/innate/ai - name = "AI Action" +//The malf AI spell subtype. All malf actions are subtypes of this. +/datum/spell/ai_spell + name = "AI Spell" desc = "You aren't entirely sure what this does, but it's very beepy and boopy." - background_icon_state = "bg_tech_blue" - var/mob/living/silicon/ai/owner_AI //The owner AI, so we don't have to typecast every time + action_background_icon_state = "bg_tech_blue" + clothes_req = FALSE + base_cooldown = 0 var/uses //If we have multiple uses of the same power var/auto_use_uses = TRUE //If we automatically use up uses on each activation - var/cooldown_period //If applicable, the time in deciseconds we have to wait before using any more modules -/datum/action/innate/ai/Grant(mob/living/L) - . = ..() - if(!isAI(owner)) - WARNING("AI action [name] attempted to grant itself to non-AI mob [L.real_name] ([L.key])!") - qdel(src) - else - owner_AI = owner +/datum/spell/ai_spell/create_new_targeting() + return new /datum/spell_targeting/self -/datum/action/innate/ai/IsAvailable() +/datum/spell/ai_spell/can_cast(mob/living/silicon/ai/user, charge_check, show_message) . = ..() - if(owner_AI && owner_AI.malf_cooldown > world.time) + if(!.) return + if(!istype(user)) + stack_trace("A non ai ([user]) tried to cast an AI spell.") + user.RemoveSpell(src) + return FALSE -/datum/action/innate/ai/Trigger(left_click) +/datum/spell/ai_spell/after_cast(list/targets, mob/user) . = ..() if(auto_use_uses) - adjust_uses(-1) - if(cooldown_period) - owner_AI.malf_cooldown = world.time + cooldown_period + adjust_uses(-1, user) -/datum/action/innate/ai/proc/adjust_uses(amt, silent) +/datum/spell/ai_spell/proc/adjust_uses(amt, mob/living/silicon/ai/owner, silent) uses += amt if(!silent && uses) to_chat(owner, "[name] now has [uses] use[uses > 1 ? "s" : ""] remaining.") if(!uses) if(initial(uses) > 1) //no need to tell 'em if it was one-use anyway! to_chat(owner, "[name] has run out of uses!") - qdel(src) + owner.RemoveSpell(src) if(QDELETED(src) || uses) //Not sure if not having src here would cause a runtime, so it's here to be safe return desc = "[initial(desc)] It has [uses] use\s remaining." UpdateButtons() //Framework for ranged abilities that can have different effects by left-clicking stuff. -/datum/action/innate/ai/ranged +/datum/spell/ai_spell/ranged name = "Ranged AI Action" auto_use_uses = FALSE //This is so we can do the thing and disable/enable freely without having to constantly add uses - var/obj/effect/proc_holder/ranged_ai/linked_ability //The linked proc holder that contains the actual ability code - var/linked_ability_type //The path of our linked ability - -/datum/action/innate/ai/ranged/New() - if(!linked_ability_type) - WARNING("Ranged AI action [name] attempted to spawn without a linked ability!") - qdel(src) //uh oh! - return - linked_ability = new linked_ability_type() - linked_ability.attached_action = src - ..() + selection_activated_message = "Hello World!" + selection_deactivated_message = "Goodbye Cruel World!" -/datum/action/innate/ai/ranged/adjust_uses(amt, silent) +/datum/spell/ai_spell/ranged/adjust_uses(amt, mob/living/silicon/ai/owner, silent) uses += amt if(!silent && uses) to_chat(owner, "[name] now has [uses] use[uses > 1 ? "s" : ""] remaining.") if(!uses) if(initial(uses) > 1) //no need to tell 'em if it was one-use anyway! to_chat(owner, "[name] has run out of uses!") - Remove(owner) - QDEL_IN(src, 100) //let any active timers on us finish up - -/datum/action/innate/ai/ranged/Destroy() - QDEL_NULL(linked_ability) - return ..() - -/datum/action/innate/ai/ranged/Activate() - linked_ability.toggle(owner) - return TRUE - -//The actual ranged proc holder. -/obj/effect/proc_holder/ranged_ai - var/enable_text = "Hello World!" //Appears when the user activates the ability - var/disable_text = "Goodbye Cruel World!" //Context clues! - var/datum/action/innate/ai/ranged/attached_action + owner.mob_spell_list -= src + QDEL_IN(src, 10 SECONDS) //let any active timers on us finish up -/obj/effect/proc_holder/ranged_ai/proc/toggle(mob/user) - if(active) - remove_ranged_ability(user, disable_text) - else - add_ranged_ability(user, enable_text) +/datum/spell/ai_spell/ranged/create_new_targeting() + var/datum/spell_targeting/clicked_atom/external/C = new() + C.range = INFINITY + return C -/datum/action/innate/ai/choose_modules +/datum/spell/ai_spell/choose_modules name = "Choose Modules" desc = "Spend your processing time to gain a variety of different abilities." - button_icon_state = "choose_module" + action_icon_state = "choose_module" auto_use_uses = FALSE // This is an infinite ability. + create_attack_logs = FALSE -/datum/action/innate/ai/choose_modules/Trigger(left_click) +/datum/spell/ai_spell/choose_modules/cast(list/targets, mob/living/silicon/ai/user) . = ..() - owner_AI.malf_picker.use(owner_AI) + user.malf_picker.use(user) -/datum/action/innate/ai/return_to_core +/datum/spell/ai_spell/return_to_core name = "Return to Main Core" desc = "Leave the APC you are shunted to, and return to your core." - icon_icon = 'icons/obj/power.dmi' - button_icon_state = "apcemag" + action_icon = 'icons/obj/power.dmi' + action_icon_state = "apcemag" auto_use_uses = FALSE // Here just to prevent the "You have X uses remaining" from popping up. -/datum/action/innate/ai/return_to_core/Trigger(left_click) +/datum/spell/ai_spell/return_to_core/cast(list/targets, mob/living/silicon/ai/user) . = ..() - var/obj/machinery/power/apc/apc = owner_AI.loc + var/obj/machinery/power/apc/apc = user.loc if(!istype(apc)) // This shouldn't happen but here for safety. - to_chat(src, "You are already in your Main Core.") + to_chat(user, "You are already in your Main Core.") return apc.malfvacate() qdel(src) @@ -127,9 +101,9 @@ /datum/module_picker/New() possible_modules = list() - for(var/type in typesof(/datum/AI_Module)) + for(var/type in subtypesof(/datum/AI_Module)) var/datum/AI_Module/AM = new type - if((AM.power_type && AM.power_type != /datum/action/innate/ai) || AM.upgrade) + if(AM.power_type || AM.upgrade) possible_modules += AM /datum/module_picker/proc/use(mob/user) @@ -167,7 +141,7 @@ temp = "You cannot afford this module." break - var/datum/action/innate/ai/action = locate(AM.power_type) in A.actions + var/datum/spell/ai_spell/action = locate(AM.power_type) in A.mob_spell_list // Give the power and take away the money. if(AM.upgrade) //upgrade and upgrade() are separate, be careful! @@ -178,8 +152,8 @@ else if(AM.power_type) if(!action) //Unlocking for the first time - var/datum/action/AC = new AM.power_type - AC.Grant(A) + var/datum/spell/ai_spell/AC = new AM.power_type + A.AddSpell(AC) A.current_modules += new AM.type temp = AM.description if(AM.one_purchase) @@ -207,7 +181,7 @@ var/description = "" var/cost = 5 var/one_purchase = FALSE //If this module can only be purchased once. This always applies to upgrades, even if the variable is set to false. - var/power_type = /datum/action/innate/ai //If the module gives an active ability, use this. Mutually exclusive with upgrade. + var/power_type = /datum/spell/ai_spell //If the module gives an active ability, use this. Mutually exclusive with upgrade. var/upgrade //If the module gives a passive upgrade, use this. Mutually exclusive with power_type. var/unlock_text = "Hello World!" //Text shown when an ability is unlocked var/unlock_sound //Sound played when an ability is unlocked @@ -223,36 +197,39 @@ description = "Activate a weapon that will disintegrate all organic life on the station after a 450 second delay. Can only be used while on the station, will fail if your core is moved off station or destroyed." cost = 130 one_purchase = TRUE - power_type = /datum/action/innate/ai/nuke_station + power_type = /datum/spell/ai_spell/nuke_station unlock_text = "You slowly, carefully, establish a connection with the on-station self-destruct. You can now activate it at any time." unlock_sound = 'sound/items/timer.ogg' -/datum/action/innate/ai/nuke_station +/datum/spell/ai_spell/nuke_station name = "Doomsday Device" desc = "Activates the doomsday device. This is not reversible." - button_icon_state = "doomsday_device" + action_icon_state = "doomsday_device" auto_use_uses = FALSE + var/in_use -/datum/action/innate/ai/nuke_station/Activate() - var/turf/T = get_turf(owner) +/datum/spell/ai_spell/nuke_station/cast(list/targets, mob/living/silicon/ai/user) + var/turf/T = get_turf(user) if(!istype(T) || !is_station_level(T.z)) - to_chat(owner, "You cannot activate the doomsday device while off-station!") + to_chat(user, "You cannot activate the doomsday device while off-station!") + return + if(tgui_alert(user, "Send arming signal? (true = arm, false = cancel)", "purge_all_life()", list("confirm = TRUE;", "confirm = FALSE;")) != "confirm = TRUE;") return - if(tgui_alert(owner, "Send arming signal? (true = arm, false = cancel)", "purge_all_life()", list("confirm = TRUE;", "confirm = FALSE;")) != "confirm = TRUE;") + if(!istype(user) || QDELETED(user)) return - if(active) + if(in_use) return //prevent the AI from activating an already active doomsday - active = TRUE - set_us_up_the_bomb() + in_use = TRUE + set_us_up_the_bomb(user) -/datum/action/innate/ai/nuke_station/proc/set_us_up_the_bomb() - to_chat(owner_AI, "Nuclear device armed.") +/datum/spell/ai_spell/nuke_station/proc/set_us_up_the_bomb(mob/living/silicon/ai/user) + to_chat(user, "Nuclear device armed.") GLOB.major_announcement.Announce("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert", 'sound/AI/aimalf.ogg') SSsecurity_level.set_level(SEC_LEVEL_DELTA) - owner_AI.nuking = TRUE - var/obj/machinery/doomsday_device/DOOM = new /obj/machinery/doomsday_device(owner_AI) - owner_AI.doomsday_device = DOOM - owner_AI.doomsday_device.start() + user.nuking = TRUE + var/obj/machinery/doomsday_device/DOOM = new /obj/machinery/doomsday_device(user) + user.doomsday_device = DOOM + user.doomsday_device.start() for(var/obj/item/pinpointer/point in GLOB.pinpointer_list) for(var/mob/living/silicon/ai/A in GLOB.ai_list) if((A.stat != DEAD) && A.nuking) @@ -352,17 +329,17 @@ opening all doors on the station." cost = 30 one_purchase = TRUE - power_type = /datum/action/innate/ai/lockdown + power_type = /datum/spell/ai_spell/lockdown unlock_text = "You upload a sleeper trojan into the door control systems. You can send a signal to set it off at any time." -/datum/action/innate/ai/lockdown +/datum/spell/ai_spell/lockdown name = "Lockdown" desc = "Closes, bolts, and depowers every airlock, firelock, and blast door on the station. After 90 seconds, they will reset themselves." - button_icon_state = "lockdown" + action_icon_state = "lockdown" uses = 1 -/datum/action/innate/ai/lockdown/Activate() - to_chat(owner, "Lockdown Initiated. Network reset in 90 seconds.") +/datum/spell/ai_spell/lockdown/cast(list/targets, mob/user) + to_chat(user, "Lockdown Initiated. Network reset in 90 seconds.") new /datum/event/door_runtime() //Destroy RCDs: Detonates all non-cyborg RCDs on the station. @@ -372,17 +349,17 @@ description = "Send a specialised pulse to detonate all hand-held and exosuit Rapid Construction Devices on the station." cost = 25 one_purchase = TRUE - power_type = /datum/action/innate/ai/destroy_rcds + power_type = /datum/spell/ai_spell/destroy_rcds unlock_text = "After some improvisation, you rig your onboard radio to be able to send a signal to detonate all RCDs." -/datum/action/innate/ai/destroy_rcds +/datum/spell/ai_spell/destroy_rcds name = "Destroy RCDs" desc = "Detonate all non-cyborg RCDs on the station." - button_icon_state = "detonate_rcds" + action_icon_state = "detonate_rcds" uses = 1 - cooldown_period = 10 SECONDS + base_cooldown = 10 SECONDS -/datum/action/innate/ai/destroy_rcds/Activate() +/datum/spell/ai_spell/destroy_rcds/cast(list/targets, mob/user) for(var/obj/item/rcd/RCD in GLOB.rcd_list) if(istype(RCD, /obj/item/rcd/borg)) //Ensures that cyborg RCDs are spared. continue @@ -390,8 +367,8 @@ if(is_level_reachable(RCD_turf.z)) RCD.detonate_pulse() - to_chat(owner, "RCD detonation pulse emitted.") - owner.playsound_local(owner, 'sound/machines/twobeep.ogg', 50, FALSE, use_reverb = FALSE) + to_chat(user, "RCD detonation pulse emitted.") + user.playsound_local(user, 'sound/machines/twobeep.ogg', 50, FALSE, use_reverb = FALSE) //Unlock Mech Domination: Unlocks the ability to dominate mechs. Big shocker, right? /datum/AI_Module/mecha_domination @@ -415,22 +392,22 @@ Anyone can check the fire alarm's interface and may be tipped off by its status." one_purchase = TRUE cost = 25 - power_type = /datum/action/innate/ai/break_fire_alarms + power_type = /datum/spell/ai_spell/break_fire_alarms unlock_text = "You replace the thermal sensing capabilities of all fire alarms with a manual override, allowing you to turn them off at will." -/datum/action/innate/ai/break_fire_alarms +/datum/spell/ai_spell/break_fire_alarms name = "Override Thermal Sensors" desc = "Disables the automatic temperature sensing on all fire alarms, making them effectively useless." - button_icon_state = "break_fire_alarms" + action_icon_state = "break_fire_alarms" uses = 1 -/datum/action/innate/ai/break_fire_alarms/Activate() +/datum/spell/ai_spell/break_fire_alarms/cast(list/targets, mob/user) for(var/obj/machinery/firealarm/F in GLOB.machines) if(!is_station_level(F.z)) continue F.emagged = TRUE - to_chat(owner, "All thermal sensors on the station have been disabled. Fire alerts will no longer be recognized.") - owner.playsound_local(owner, 'sound/machines/terminal_off.ogg', 50, FALSE, use_reverb = FALSE) + to_chat(user, "All thermal sensors on the station have been disabled. Fire alerts will no longer be recognized.") + user.playsound_local(user, 'sound/machines/terminal_off.ogg', 50, FALSE, use_reverb = FALSE) //Air Alarm Safety Override: Unlocks the ability to enable flooding on all air alarms. /datum/AI_Module/break_air_alarms @@ -440,23 +417,22 @@ Anyone can check the air alarm's interface and may be tipped off by their nonfunctionality." one_purchase = TRUE cost = 50 - power_type = /datum/action/innate/ai/break_air_alarms + power_type = /datum/spell/ai_spell/break_air_alarms unlock_text = "You remove the safety overrides on all air alarms, but you leave the confirm prompts open. You can hit 'Yes' at any time... you bastard." -/datum/action/innate/ai/break_air_alarms +/datum/spell/ai_spell/break_air_alarms name = "Override Air Alarm Safeties" desc = "Enables the Flood setting on all air alarms." - button_icon_state = "break_air_alarms" + action_icon_state = "break_air_alarms" uses = 1 -/datum/action/innate/ai/break_air_alarms/Activate() +/datum/spell/ai_spell/break_air_alarms/cast(list/targets, mob/user) for(var/obj/machinery/alarm/AA in GLOB.machines) if(!is_station_level(AA.z)) continue AA.emagged = TRUE - to_chat(owner, "All air alarm safeties on the station have been overridden. Air alarms may now use the Flood environmental mode.") - owner.playsound_local(owner, 'sound/machines/terminal_off.ogg', 50, FALSE, use_reverb = FALSE) - + to_chat(user, "All air alarm safeties on the station have been overridden. Air alarms may now use the Flood environmental mode.") + user.playsound_local(user, 'sound/machines/terminal_off.ogg', 50, FALSE, use_reverb = FALSE) //Overload Machine: Allows the AI to overload a machine, detonating it after a delay. Two uses per purchase. /datum/AI_Module/overload_machine @@ -464,48 +440,40 @@ mod_pick_name = "overload" description = "Overheats an electrical machine, causing a moderately-sized explosion and destroying it. Four uses per purchase." cost = 20 - power_type = /datum/action/innate/ai/ranged/overload_machine + power_type = /datum/spell/ai_spell/ranged/overload_machine unlock_text = "You enable the ability for the station's APCs to direct intense energy into machinery." -/datum/action/innate/ai/ranged/overload_machine +/datum/spell/ai_spell/ranged/overload_machine name = "Overload Machine" desc = "Overheats a machine, causing a moderately-sized explosion after a short time." - button_icon_state = "overload_machine" + action_icon_state = "overload_machine" uses = 4 - linked_ability_type = /obj/effect/proc_holder/ranged_ai/overload_machine - -/datum/action/innate/ai/ranged/overload_machine/proc/detonate_machine(obj/machinery/M) - if(M && !QDELETED(M)) - explosion(get_turf(M), 0, 3, 5, 0) - if(M) //to check if the explosion killed it before we try to delete it - qdel(M) - -/obj/effect/proc_holder/ranged_ai/overload_machine active = FALSE ranged_mousepointer = 'icons/effects/cult_target.dmi' - enable_text = "You tap into the station's powernet. Click on a machine to detonate it, or use the ability again to cancel." - disable_text = "You release your hold on the powernet." + selection_activated_message = "You tap into the station's powernet. Click on a machine to detonate it, or use the ability again to cancel." + selection_deactivated_message = "You release your hold on the powernet." -/obj/effect/proc_holder/ranged_ai/overload_machine/InterceptClickOn(mob/living/caller, params, obj/machinery/target) - if(..()) - return - if(ranged_ability_user.incapacitated()) - remove_ranged_ability() - return +/datum/spell/ai_spell/ranged/overload_machine/cast(list/targets, mob/user) + var/obj/machinery/target = targets[1] if(!istype(target)) - to_chat(ranged_ability_user, "You can only overload machines!") + to_chat(user, "You can only overload machines!") return if(target.flags_2 & NO_MALF_EFFECT_2) - to_chat(ranged_ability_user, "That machine can't be overloaded!") + to_chat(user, "That machine can't be overloaded!") return - ranged_ability_user.playsound_local(ranged_ability_user, "sparks", 50, FALSE, use_reverb = FALSE) - attached_action.adjust_uses(-1) + user.playsound_local(user, "sparks", 50, FALSE, use_reverb = FALSE) + adjust_uses(-1, user) target.audible_message("You hear a loud electrical buzzing sound coming from [target]!") - addtimer(CALLBACK(attached_action, TYPE_PROC_REF(/datum/action/innate/ai/ranged/overload_machine, detonate_machine), target), 50) //kaboom! - remove_ranged_ability(ranged_ability_user, "Overloading machine circuitry...") + addtimer(CALLBACK(src, PROC_REF(detonate_machine), target), 5 SECONDS) //kaboom! + to_chat(user, "Overloading machine circuitry...") return TRUE +/datum/spell/ai_spell/ranged/overload_machine/proc/detonate_machine(obj/machinery/M) + if(M && !QDELETED(M)) + explosion(get_turf(M), 0, 3, 5, 0) + if(M) //to check if the explosion killed it before we try to delete it + qdel(M) //Override Machine: Allows the AI to override a machine, animating it into an angry, living version of itself. /datum/AI_Module/override_machine @@ -513,46 +481,37 @@ mod_pick_name = "override" description = "Overrides a machine's programming, causing it to rise up and attack everyone except other machines. Four uses." cost = 30 - power_type = /datum/action/innate/ai/ranged/override_machine + power_type = /datum/spell/ai_spell/ranged/override_machine unlock_text = "You procure a virus from the Space Dark Web and distribute it to the station's machines." -/datum/action/innate/ai/ranged/override_machine +/datum/spell/ai_spell/ranged/override_machine name = "Override Machine" desc = "Animates a targeted machine, causing it to attack anyone nearby." - button_icon_state = "override_machine" + action_icon_state = "override_machine" uses = 4 - linked_ability_type = /obj/effect/proc_holder/ranged_ai/override_machine - -/datum/action/innate/ai/ranged/override_machine/proc/animate_machine(obj/machinery/M) - if(M && !QDELETED(M)) - new/mob/living/simple_animal/hostile/mimic/copy/machine(get_turf(M), M, owner, 1) - -/obj/effect/proc_holder/ranged_ai/override_machine - active = FALSE ranged_mousepointer = 'icons/effects/override_machine_target.dmi' - enable_text = "You tap into the station's powernet. Click on a machine to animate it, or use the ability again to cancel." - disable_text = "You release your hold on the powernet." + selection_activated_message = "You tap into the station's powernet. Click on a machine to animate it, or use the ability again to cancel." + selection_deactivated_message = "You release your hold on the powernet." -/obj/effect/proc_holder/ranged_ai/override_machine/InterceptClickOn(mob/living/caller, params, obj/machinery/target) - if(..()) - return - if(ranged_ability_user.incapacitated()) - remove_ranged_ability() - return +/datum/spell/ai_spell/ranged/override_machine/cast(list/targets, mob/user) + var/obj/machinery/target = targets[1] if(!istype(target)) - to_chat(ranged_ability_user, "You can only animate machines!") + to_chat(user, "You can only animate machines!") return if(target.flags_2 & NO_MALF_EFFECT_2) - to_chat(ranged_ability_user, "That machine can't be overridden!") + to_chat(user, "That machine can't be overridden!") return - ranged_ability_user.playsound_local(ranged_ability_user, 'sound/misc/interference.ogg', 50, FALSE, use_reverb = FALSE) - attached_action.adjust_uses(-1) + user.playsound_local(user, 'sound/misc/interference.ogg', 50, FALSE, use_reverb = FALSE) + adjust_uses(-1, user) target.audible_message("You hear a loud electrical buzzing sound coming from [target]!") - addtimer(CALLBACK(attached_action, TYPE_PROC_REF(/datum/action/innate/ai/ranged/override_machine, animate_machine), target), 50) //kabeep! - remove_ranged_ability(ranged_ability_user, "Sending override signal...") + addtimer(CALLBACK(src, PROC_REF(animate_machine), target), 5 SECONDS) //kabeep! + to_chat(user, "Sending override signal...") return TRUE +/datum/spell/ai_spell/ranged/override_machine/proc/animate_machine(obj/machinery/M, mob/user) + if(M && !QDELETED(M)) + new /mob/living/simple_animal/hostile/mimic/copy/machine(get_turf(M), M, user, 1) //Robotic Factory: Places a large machine that converts humans that go through it into cyborgs. Unlocking this ability removes shunting. /datum/AI_Module/place_cyborg_transformer @@ -561,46 +520,47 @@ description = "Build a machine anywhere, using expensive nanomachines, that can convert a living human into a loyal cyborg slave when placed inside." cost = 100 one_purchase = TRUE - power_type = /datum/action/innate/ai/place_transformer + power_type = /datum/spell/ai_spell/place_transformer unlock_text = "You prepare a robotics factory for deployment." unlock_sound = 'sound/machines/ping.ogg' -/datum/action/innate/ai/place_transformer +/datum/spell/ai_spell/place_transformer name = "Place Robotics Factory" desc = "Places a machine that converts humans into cyborgs. Conveyor belts included!" - button_icon_state = "robotic_factory" + action_icon_state = "robotic_factory" uses = 1 auto_use_uses = FALSE //So we can attempt multiple times var/list/turfOverlays + var/in_use = FALSE -/datum/action/innate/ai/place_transformer/New() +/datum/spell/ai_spell/place_transformer/New() ..() for(var/i in 1 to 3) var/image/I = image("icon"='icons/turf/overlays.dmi') LAZYADD(turfOverlays, I) -/datum/action/innate/ai/place_transformer/Activate() - if(!owner_AI.can_place_transformer(src)) +/datum/spell/ai_spell/place_transformer/cast(list/targets, mob/living/silicon/ai/user) + if(!user.can_place_transformer(src)) return - active = TRUE - if(tgui_alert(owner, "Are you sure you want to place the machine here?", "Are you sure?", list("Yes", "No")) != "Yes") + in_use = TRUE + if(tgui_alert(user, "Are you sure you want to place the machine here?", "Are you sure?", list("Yes", "No")) != "Yes") active = FALSE return - if(!owner_AI.can_place_transformer(src)) + if(!user.can_place_transformer(src)) active = FALSE return - var/turf/T = get_turf(owner_AI.eyeobj) - new /obj/machinery/transformer(T, owner_AI) + var/turf/T = get_turf(user.eyeobj) + new /obj/machinery/transformer(T, user) playsound(T, 'sound/effects/phasein.ogg', 100, 1) - owner_AI.can_shunt = FALSE - to_chat(owner, "You are no longer able to shunt your core to APCs.") - adjust_uses(-1) + user.can_shunt = FALSE + to_chat(user, "You are no longer able to shunt your core to APCs.") + adjust_uses(-1, user) /mob/living/silicon/ai/proc/remove_transformer_image(client/C, image/I, turf/T) if(C && I.loc == T) C.images -= I -/mob/living/silicon/ai/proc/can_place_transformer(datum/action/innate/ai/place_transformer/action) +/mob/living/silicon/ai/proc/can_place_transformer(datum/spell/ai_spell/place_transformer/action) if(!eyeobj || !isturf(loc) || incapacitated() || !action) return var/turf/middle = get_turf(eyeobj) @@ -634,46 +594,46 @@ mod_pick_name = "turretdeployer" description = "Build a turret anywhere that lethally targets organic life in sight." cost = 30 - power_type = /datum/action/innate/ai/place_turret + power_type = /datum/spell/ai_spell/place_turret unlock_text = "You prepare an energy turret for deployment." unlock_sound = 'sound/items/rped.ogg' -/datum/action/innate/ai/place_turret +/datum/spell/ai_spell/place_turret name = "Deploy Turret" desc = "Build a turret anywhere that lethally targets organic life in sight." - button_icon_state = "deploy_turret" + action_icon_state = "deploy_turret" uses = 1 auto_use_uses = FALSE var/image/turf_overlay + var/in_use = FALSE -/datum/action/innate/ai/place_turret/New() +/datum/spell/ai_spell/place_turret/New() ..() turf_overlay = image('icons/turf/overlays.dmi') -/datum/action/innate/ai/place_turret/Activate() - if(active) - to_chat(owner, "Your assemblers can only construct one turret at a time.") +/datum/spell/ai_spell/place_turret/cast(list/targets, mob/living/silicon/ai/user) + if(in_use) + to_chat(user, "Your assemblers can only construct one turret at a time.") return - if(!owner_AI.can_place_turret(src)) + if(!user.can_place_turret(src)) return - active = TRUE - var/response = alert(owner, "Are you sure you want to place a turret here? Deployment will take a few seconds to complete, in which the turret will be vulnerable.", "Are you sure?", "No", "Yes") - if(!response || response == "No") - active = FALSE + in_use = TRUE + if(tgui_alert(user, "Are you sure you want to place a turret here? Deployment will take a few seconds to complete, in which the turret will be vulnerable.", "Are you sure?", list("No", "Yes")) != "Yes") + in_use = FALSE return - if(!owner_AI.can_place_turret(src)) - active = FALSE + if(!user.can_place_turret(src)) + in_use = FALSE return - deploy_turret() - active = FALSE + deploy_turret(user) + in_use = FALSE -/datum/action/innate/ai/place_turret/proc/deploy_turret() - var/turf/T = get_turf(owner_AI.eyeobj) +/datum/spell/ai_spell/place_turret/proc/deploy_turret(mob/living/silicon/ai/user) + var/turf/T = get_turf(user.eyeobj) //Handles the turret construction and configuration playsound(T, 'sound/items/rped.ogg', 100, TRUE) //Plays a sound both at the location of the construction to alert players and to the user as feedback - owner.playsound_local(owner, 'sound/items/rped.ogg', 50, FALSE, use_reverb = FALSE) - to_chat(owner, "You order your electronics to assemble a turret. This will take a few seconds.") + user.playsound_local(user, 'sound/items/rped.ogg', 50, FALSE, use_reverb = FALSE) + to_chat(user, "You order your electronics to assemble a turret. This will take a few seconds.") var/obj/effect/temp_visual/rcd_effect/spawning_effect = new(T) QDEL_IN(spawning_effect, 5 SECONDS) @@ -687,21 +647,21 @@ turret.invisibility = 100 //If turrets are already upgraded, beef it up - if(owner_AI.turrets_upgraded) + if(user.turrets_upgraded) turret.health += 30 turret.eprojectile = /obj/item/projectile/beam/laser/ai_turret/heavylaser //Big gun turret.eshot_sound = 'sound/weapons/lasercannonfire.ogg' - if(do_after_once(owner, 5 SECONDS, target = T, allow_moving = TRUE)) //Once this is done, turret is armed and dangerous + if(do_after_once(user, 5 SECONDS, target = T, allow_moving = TRUE)) //Once this is done, turret is armed and dangerous turret.raised = initial(turret.raised) turret.invisibility = initial(turret.invisibility) turret.disabled = initial(turret.disabled) new /obj/effect/temp_visual/rcd_effect/end(T) playsound(T, 'sound/items/deconstruct.ogg', 100, TRUE) - to_chat(owner, "Turret deployed.") - adjust_uses(-1) + to_chat(user, "Turret deployed.") + adjust_uses(-1, user) -/mob/living/silicon/ai/proc/can_place_turret(datum/action/innate/ai/place_turret/action) +/mob/living/silicon/ai/proc/can_place_turret(datum/spell/ai_spell/place_turret/action) if(!eyeobj || !isturf(eyeobj.loc) || incapacitated() || !action) return @@ -735,26 +695,26 @@ mod_pick_name = "blackout" description = "Attempts to overload the lighting circuits on the station, destroying some bulbs. Three uses." cost = 15 - power_type = /datum/action/innate/ai/blackout + power_type = /datum/spell/ai_spell/blackout unlock_text = "You hook into the powernet and route bonus power towards the station's lighting." -/datum/action/innate/ai/blackout +/datum/spell/ai_spell/blackout name = "Blackout" desc = "Overloads random lights across the station." - button_icon_state = "blackout" + action_icon_state = "blackout" uses = 3 auto_use_uses = FALSE -/datum/action/innate/ai/blackout/Activate() +/datum/spell/ai_spell/blackout/cast(list/targets, mob/user) for(var/thing in GLOB.apcs) var/obj/machinery/power/apc/apc = thing if(prob(30 * apc.overload)) INVOKE_ASYNC(apc, TYPE_PROC_REF(/obj/machinery/power/apc, overload_lighting)) else apc.overload++ - to_chat(owner, "Overcurrent applied to the powernet.") - owner.playsound_local(owner, "sparks", 50, FALSE, use_reverb = FALSE) - adjust_uses(-1) + to_chat(user, "Overcurrent applied to the powernet.") + user.playsound_local(user, "sparks", 50, FALSE, use_reverb = FALSE) + adjust_uses(-1, user) //Reactivate Camera Network: Reactivates up to 30 cameras across the station. /datum/AI_Module/reactivate_cameras @@ -762,19 +722,18 @@ mod_pick_name = "recam" description = "Runs a network-wide diagnostic on the camera network, resetting focus and re-routing power to failed cameras. Can be used to repair up to 30 cameras." cost = 10 - power_type = /datum/action/innate/ai/reactivate_cameras + power_type = /datum/spell/ai_spell/reactivate_cameras unlock_text = "You deploy nanomachines to the cameranet." -/datum/action/innate/ai/reactivate_cameras +/datum/spell/ai_spell/reactivate_cameras name = "Reactivate Cameras" desc = "Reactivates disabled cameras across the station; remaining uses can be used later." - button_icon_state = "reactivate_cameras" + action_icon_state = "reactivate_cameras" uses = 10 auto_use_uses = FALSE - cooldown_period = 3 SECONDS + base_cooldown = 3 SECONDS -/datum/action/innate/ai/reactivate_cameras/Activate() - var/mob/living/silicon/ai/user = usr +/datum/spell/ai_spell/reactivate_cameras/cast(list/targets, mob/living/silicon/ai/user) var/repaired_cameras = 0 if(!istype(user)) return @@ -782,14 +741,14 @@ if(!uses) break if(!camera_to_repair.status || camera_to_repair.view_range != initial(camera_to_repair.view_range)) - camera_to_repair.toggle_cam(owner_AI, 0) + camera_to_repair.toggle_cam(user, 0) camera_to_repair.view_range = initial(camera_to_repair.view_range) camera_to_repair.wires.cut_wires.Cut() repaired_cameras++ uses-- - to_chat(owner, "Diagnostic complete! Cameras reactivated: [repaired_cameras]. Reactivations remaining: [uses].") - owner.playsound_local(owner, 'sound/items/wirecutter.ogg', 50, FALSE, use_reverb = FALSE) - adjust_uses(0, TRUE) + to_chat(user, "Diagnostic complete! Cameras reactivated: [repaired_cameras]. Reactivations remaining: [uses].") + user.playsound_local(user, 'sound/items/wirecutter.ogg', 50, FALSE, use_reverb = FALSE) + adjust_uses(0, user, TRUE) //Upgrade Camera Network: EMP-proofs all cameras, in addition to giving them X-ray vision. /datum/AI_Module/upgrade_cameras @@ -880,124 +839,113 @@ mod_pick_name = "repair_borg" description = "Causes an electrical surge in the targeted cyborg, rebooting and repairing most of its subsystems. Requires two uses on a cyborg with broken armor." cost = 20 - power_type = /datum/action/innate/ai/ranged/repair_cyborg + power_type = /datum/spell/ai_spell/ranged/repair_cyborg unlock_text = "TLB exception on load: Error pointing to address 0000001H, Proceed with execution anywa- SURGE protocols installed, welcome to open APC!" unlock_sound = 'sound/items/rped.ogg' -/datum/action/innate/ai/ranged/repair_cyborg +/datum/spell/ai_spell/ranged/repair_cyborg name = "Repair Cyborg" desc = "Shocks a cyborg back to 'life' after a short delay." - button_icon_state = "overload_machine" + action_icon_state = "overload_machine" uses = 2 - linked_ability_type = /obj/effect/proc_holder/ranged_ai/repair_cyborg - - -/datum/action/innate/ai/ranged/repair_cyborg/proc/fix_borg(mob/living/silicon/robot/to_repair) - for(var/datum/robot_component/component in to_repair.components) - component.brute_damage = 0 - component.electronics_damage = 0 - component.component_disabled = FALSE - to_repair.revive() - -/obj/effect/proc_holder/ranged_ai/repair_cyborg - active = FALSE ranged_mousepointer = 'icons/effects/overload_machine_target.dmi' - enable_text = "Call to address 0FFFFFFF in APC logic thread, awaiting user response." - disable_text = "APC logic thread restarting..." + selection_activated_message = "Call to address 0FFFFFFF in APC logic thread, awaiting user response." + selection_deactivated_message = "APC logic thread restarting..." var/is_active = FALSE -/obj/effect/proc_holder/ranged_ai/repair_cyborg/InterceptClickOn(mob/living/caller, params, mob/living/silicon/robot/robot_target) - if(..()) - return - if(ranged_ability_user.incapacitated()) - remove_ranged_ability() - return +/datum/spell/ai_spell/ranged/repair_cyborg/create_new_targeting() + var/datum/spell_targeting/click/T = new + T.allowed_type = /mob/living/silicon/robot + T.try_auto_target = FALSE + return T + +/datum/spell/ai_spell/ranged/repair_cyborg/cast(list/targets, mob/user) + var/mob/living/silicon/robot/robot_target = targets[1] if(!istype(robot_target)) - to_chat(ranged_ability_user, "You can only repair robots with this ability!") + to_chat(user, "You can only repair robots with this ability!") return if(is_active) - to_chat(ranged_ability_user, "You can only repair one robot at a time!") + to_chat(user, "You can only repair one robot at a time!") return is_active = TRUE - ranged_ability_user.playsound_local(ranged_ability_user, "sparks", 50, FALSE, use_reverb = FALSE) - var/datum/action/innate/ai/ranged/repair_cyborg/actual_action = attached_action - actual_action.adjust_uses(-1) + user.playsound_local(user, "sparks", 50, FALSE, use_reverb = FALSE) + adjust_uses(-1, user) robot_target.audible_message("You hear a loud electrical buzzing sound coming from [robot_target]!") - if(!do_mob(caller, robot_target, 10 SECONDS)) + if(!do_mob(user, robot_target, 10 SECONDS)) is_active = FALSE return is_active = FALSE - actual_action.fix_borg(robot_target) - remove_ranged_ability(ranged_ability_user, "[robot_target] successfully rebooted.") + fix_borg(robot_target) + to_chat(user, "[robot_target] successfully rebooted.") return TRUE +/datum/spell/ai_spell/ranged/repair_cyborg/proc/fix_borg(mob/living/silicon/robot/to_repair) + for(var/datum/robot_component/component in to_repair.components) + component.brute_damage = 0 + component.electronics_damage = 0 + component.component_disabled = FALSE + to_repair.revive() + /datum/AI_Module/core_tilt module_name = "Rolling Servos" mod_pick_name = "watchforrollingcores" description = "Allows you to slowly roll your core around, crushing anything in your path with your bulk." cost = 10 - one_purchase = FALSE - power_type = /datum/action/innate/ai/ranged/core_tilt + one_purchase = TRUE + power_type = /datum/spell/ai_spell/ranged/core_tilt unlock_sound = 'sound/effects/bang.ogg' unlock_text = "You gain the ability to roll over and crush anything in your way." -/datum/action/innate/ai/ranged/core_tilt +/datum/spell/ai_spell/ranged/core_tilt name = "Roll Over" - button_icon_state = "roll_over" + action_icon_state = "roll_over" desc = "Allows you to roll over in the direction of your choosing, crushing anything in your way." auto_use_uses = FALSE - linked_ability_type = /obj/effect/proc_holder/ranged_ai/roll_over - - -/obj/effect/proc_holder/ranged_ai/roll_over - active = FALSE ranged_mousepointer = 'icons/effects/cult_target.dmi' - enable_text = "Your inner servos shift as you prepare to roll around. Click adjacent tiles to roll into them!" - disable_text = "You disengage your rolling protocols." + selection_activated_message = "Your inner servos shift as you prepare to roll around. Click adjacent tiles to roll into them!" + selection_deactivated_message = "You disengage your rolling protocols." COOLDOWN_DECLARE(time_til_next_tilt) /// How long does it take us to roll? var/roll_over_time = MALF_AI_ROLL_TIME /// How long does it take for the ability to cool down, on top of [roll_over_time]? var/roll_over_cooldown = MALF_AI_ROLL_COOLDOWN - -/obj/effect/proc_holder/ranged_ai/roll_over/InterceptClickOn(mob/living/caller, params, atom/target_atom) - if(..()) - return - if(!isAI(ranged_ability_user)) +/datum/spell/ai_spell/ranged/core_tilt/cast(list/targets, mob/living/silicon/ai/user) + var/atom/target_atom = targets[1] + if(!istype(user)) return - if(ranged_ability_user.incapacitated() || !isturf(ranged_ability_user.loc)) - remove_ranged_ability() + if(!isturf(user.loc)) + user.RemoveSpell(src) return if(!COOLDOWN_FINISHED(src, time_til_next_tilt)) - to_chat(ranged_ability_user, "Your rolling capacitors are still powering back up!") + to_chat(user, "Your rolling capacitors are still powering back up!") return var/turf/target = get_turf(target_atom) if(isnull(target)) return - if(target == get_turf(ranged_ability_user)) - to_chat(ranged_ability_user, "You can't roll over on yourself!") + if(target == get_turf(user)) + to_chat(user, "You can't roll over on yourself!") return - var/picked_dir = get_dir(caller, target) + var/picked_dir = get_dir(user, target) if(!picked_dir) return FALSE // we can move during the timer so we cant just pass the ref - var/turf/temp_target = get_step(ranged_ability_user, picked_dir) + var/turf/temp_target = get_step(user, picked_dir) - new /obj/effect/temp_visual/single_user/ai_telegraph(temp_target, ranged_ability_user) - ranged_ability_user.visible_message("[ranged_ability_user] seems to be winding up!") - addtimer(CALLBACK(src, PROC_REF(do_roll_over), caller, picked_dir), MALF_AI_ROLL_TIME) + new /obj/effect/temp_visual/single_user/ai_telegraph(temp_target, user) + user.visible_message("[user] seems to be winding up!") + addtimer(CALLBACK(src, PROC_REF(do_roll_over), user, picked_dir), MALF_AI_ROLL_TIME) - to_chat(ranged_ability_user, "Overloading machine circuitry...") + to_chat(user, "Overloading machine circuitry...") COOLDOWN_START(src, time_til_next_tilt, roll_over_cooldown) return TRUE -/obj/effect/proc_holder/ranged_ai/roll_over/proc/do_roll_over(mob/living/silicon/ai/ai_caller, picked_dir) +/datum/spell/ai_spell/ranged/core_tilt/proc/do_roll_over(mob/living/silicon/ai/ai_caller, picked_dir) var/turf/target = get_step(ai_caller, picked_dir) // in case we moved we pass the dir not the target turf if(isnull(target) || ai_caller.incapacitated() || !isturf(ai_caller.loc)) @@ -1009,7 +957,7 @@ ai_caller.fall_and_crush(target, MALF_AI_ROLL_DAMAGE, prob(MALF_AI_ROLL_CRIT_CHANCE), 2, null, paralyze_time, crush_dir = picked_dir, angle = get_rotation_from_dir(picked_dir)) ai_caller.allow_teleporter = FALSE -/obj/effect/proc_holder/ranged_ai/roll_over/proc/get_rotation_from_dir(dir) +/datum/spell/ai_spell/ranged/core_tilt/proc/get_rotation_from_dir(dir) switch(dir) if(NORTH, NORTHWEST, WEST, SOUTHWEST) return 270 // try our best to not return 180 since it works badly with animate diff --git a/code/game/gamemodes/miniantags/demons/shadow_demon/shadow_demon.dm b/code/game/gamemodes/miniantags/demons/shadow_demon/shadow_demon.dm index 045203e0e47c..5dc9a30ce30f 100644 --- a/code/game/gamemodes/miniantags/demons/shadow_demon/shadow_demon.dm +++ b/code/game/gamemodes/miniantags/demons/shadow_demon/shadow_demon.dm @@ -147,8 +147,8 @@ /mob/living/simple_animal/demon/shadow/Initialize(mapload) . = ..() - AddSpell(new /obj/effect/proc_holder/spell/fireball/shadow_grapple) - var/obj/effect/proc_holder/spell/bloodcrawl/shadow_crawl/S = new + AddSpell(new /datum/spell/fireball/shadow_grapple) + var/datum/spell/bloodcrawl/shadow_crawl/S = new AddSpell(S) whisper_action.button_icon_state = "shadow_whisper" whisper_action.background_icon_state = "shadow_demon_bg" @@ -176,7 +176,7 @@ return lum_count -/obj/effect/proc_holder/spell/fireball/shadow_grapple +/datum/spell/fireball/shadow_grapple name = "Shadow Grapple" desc = "Fire one of your hands, if it hits a person it pulls them in. If you hit a structure you get pulled to the structure. Any light source hit with this will be disabled in a two tile radius." base_cooldown = 10 SECONDS @@ -193,7 +193,7 @@ invocation_type = "none" invocation = null -/obj/effect/proc_holder/spell/fireball/shadow_grapple/update_icon_state() +/datum/spell/fireball/shadow_grapple/update_spell_icon() return /obj/item/projectile/magic/shadow_hand @@ -239,9 +239,9 @@ /obj/item/organ/internal/heart/demon/shadow/insert(mob/living/carbon/M, special = 0) . = ..() if(M.mind) - M.mind.AddSpell(new /obj/effect/proc_holder/spell/fireball/shadow_grapple) + M.mind.AddSpell(new /datum/spell/fireball/shadow_grapple) /obj/item/organ/internal/heart/demon/shadow/remove(mob/living/carbon/M, special = 0) . = ..() if(M.mind) - M.mind.RemoveSpell(/obj/effect/proc_holder/spell/fireball/shadow_grapple) + M.mind.RemoveSpell(/datum/spell/fireball/shadow_grapple) diff --git a/code/game/gamemodes/miniantags/demons/slaughter demon/slaughter.dm b/code/game/gamemodes/miniantags/demons/slaughter demon/slaughter.dm index 6439cd69f34f..0ee8e70ce671 100644 --- a/code/game/gamemodes/miniantags/demons/slaughter demon/slaughter.dm +++ b/code/game/gamemodes/miniantags/demons/slaughter demon/slaughter.dm @@ -32,7 +32,7 @@ ..() remove_from_all_data_huds() ADD_TRAIT(src, TRAIT_BLOODCRAWL_EAT, "bloodcrawl_eat") - var/obj/effect/proc_holder/spell/bloodcrawl/bloodspell = new + var/datum/spell/bloodcrawl/bloodspell = new AddSpell(bloodspell) if(istype(loc, /obj/effect/dummy/slaughter)) bloodspell.phased = TRUE @@ -102,7 +102,7 @@ to emerge from it. You are fast, powerful, and almost invincible. By dragging a dead or unconscious body into a blood pool with you, you will consume it after a time and fully regain \ your health. You may use the ability 'Sense Victims' in your Cultist tab to locate a random, living heretic." -/obj/effect/proc_holder/spell/sense_victims +/datum/spell/sense_victims name = "Sense Victims" desc = "Sense the location of heretics" base_cooldown = 0 @@ -113,13 +113,13 @@ action_background_icon_state = "bg_cult" panel = "Demon" -/obj/effect/proc_holder/spell/sense_victims/create_new_targeting() +/datum/spell/sense_victims/create_new_targeting() return new /datum/spell_targeting/alive_mob_list -/obj/effect/proc_holder/spell/sense_victims/valid_target(mob/living/target, user) +/datum/spell/sense_victims/valid_target(mob/living/target, user) return target.stat == CONSCIOUS && target.key && !IS_CULTIST(target) // Only conscious, non cultist players -/obj/effect/proc_holder/spell/sense_victims/cast(list/targets, mob/user) +/datum/spell/sense_victims/cast(list/targets, mob/user) var/mob/living/victim = targets[1] to_chat(victim, "You feel an awful sense of being watched...") victim.Stun(6 SECONDS) //HUE @@ -153,7 +153,7 @@ S.mind.special_role = "Harbinger of the Slaughter" to_chat(S, playstyle_string) S.mind.add_antag_datum(/datum/antagonist/cultist) - var/obj/effect/proc_holder/spell/sense_victims/SV = new + var/datum/spell/sense_victims/SV = new AddSpell(SV) S.mind.add_mind_objective(/datum/objective/cult_slaughter) @@ -257,14 +257,14 @@ /obj/item/organ/internal/heart/demon/slaughter/insert(mob/living/carbon/M, special = 0) . = ..() if(M.mind) - M.mind.AddSpell(new /obj/effect/proc_holder/spell/bloodcrawl(null)) + M.mind.AddSpell(new /datum/spell/bloodcrawl(null)) /obj/item/organ/internal/heart/demon/slaughter/remove(mob/living/carbon/M, special = 0) . = ..() if(M.mind) REMOVE_TRAIT(M, TRAIT_BLOODCRAWL, "bloodcrawl") REMOVE_TRAIT(M, TRAIT_BLOODCRAWL_EAT, "bloodcrawl_eat") - M.mind.RemoveSpell(/obj/effect/proc_holder/spell/bloodcrawl) + M.mind.RemoveSpell(/datum/spell/bloodcrawl) /mob/living/simple_animal/demon/slaughter/laughter // The laughter demon! It's everyone's best friend! It just wants to hug diff --git a/code/game/gamemodes/miniantags/guardian/host_actions.dm b/code/game/gamemodes/miniantags/guardian/host_actions.dm index 75157f84991b..23ccc02f24bc 100644 --- a/code/game/gamemodes/miniantags/guardian/host_actions.dm +++ b/code/game/gamemodes/miniantags/guardian/host_actions.dm @@ -102,7 +102,7 @@ dust_if_respawnable(new_stand) qdel(src) -/obj/effect/proc_holder/spell/summon_guardian_beacon +/datum/spell/summon_guardian_beacon name = "Place Teleportation Beacon" desc = "Mark a floor as your beacon point, allowing you to warp targets to it. Your beacon requires an anchor, will not work on space tiles." clothes_req = FALSE @@ -111,10 +111,10 @@ action_background_icon_state = "reset" action_icon = 'icons/mob/guardian.dmi' -/obj/effect/proc_holder/spell/summon_guardian_beacon/create_new_targeting() +/datum/spell/summon_guardian_beacon/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/summon_guardian_beacon/cast(list/targets, mob/living/user = usr) +/datum/spell/summon_guardian_beacon/cast(list/targets, mob/living/user = usr) var/target = targets[1] var/mob/living/simple_animal/hostile/guardian/healer/guardian_user = user var/turf/beacon_loc = get_turf(target) @@ -125,7 +125,7 @@ return TRUE -/obj/effect/proc_holder/spell/surveillance_snare +/datum/spell/surveillance_snare name = "Set Surveillance Snare" desc = "Places an invisible Surveillance Snare on the ground, if someone walks over it you'll be alerted. Max of 6 snares active at a time" clothes_req = FALSE @@ -134,10 +134,10 @@ action_background_icon_state = "reset" action_icon = 'icons/mob/guardian.dmi' -/obj/effect/proc_holder/spell/surveillance_snare/create_new_targeting() +/datum/spell/surveillance_snare/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/surveillance_snare/cast(list/targets, mob/living/user = usr) +/datum/spell/surveillance_snare/cast(list/targets, mob/living/user = usr) var/target = targets[1] var/mob/living/simple_animal/hostile/guardian/ranged/guardian_user = user if(length(guardian_user.snares) < 6) @@ -156,7 +156,7 @@ to_chat(user, "Snare disarmed.") revert_cast() -/obj/effect/proc_holder/spell/choose_battlecry +/datum/spell/choose_battlecry name = "Change battlecry" desc = "Changes your battlecry." clothes_req = FALSE @@ -165,10 +165,10 @@ action_background_icon_state = "communicate" action_icon = 'icons/mob/guardian.dmi' -/obj/effect/proc_holder/spell/choose_battlecry/create_new_targeting() +/datum/spell/choose_battlecry/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/choose_battlecry/cast(list/targets, mob/living/user = usr) +/datum/spell/choose_battlecry/cast(list/targets, mob/living/user = usr) var/mob/living/simple_animal/hostile/guardian/punch/guardian_user = user var/input = tgui_input_text(guardian_user, "What do you want your battlecry to be? Max length of 6 characters.", "Change Battlecry", guardian_user.battlecry, 6) if(!input) diff --git a/code/game/gamemodes/miniantags/guardian/types/healer.dm b/code/game/gamemodes/miniantags/guardian/types/healer.dm index 3423233c91d2..f073bd8935da 100644 --- a/code/game/gamemodes/miniantags/guardian/types/healer.dm +++ b/code/game/gamemodes/miniantags/guardian/types/healer.dm @@ -36,7 +36,7 @@ /mob/living/simple_animal/hostile/guardian/healer/Initialize(mapload, mob/living/host) . = ..() - AddSpell(new /obj/effect/proc_holder/spell/summon_guardian_beacon(null)) + AddSpell(new /datum/spell/summon_guardian_beacon(null)) /mob/living/simple_animal/hostile/guardian/healer/Destroy() QDEL_NULL(beacon) diff --git a/code/game/gamemodes/miniantags/guardian/types/ranged.dm b/code/game/gamemodes/miniantags/guardian/types/ranged.dm index 37953ec72dff..1a254c42f77f 100644 --- a/code/game/gamemodes/miniantags/guardian/types/ranged.dm +++ b/code/game/gamemodes/miniantags/guardian/types/ranged.dm @@ -27,7 +27,7 @@ /mob/living/simple_animal/hostile/guardian/ranged/Initialize(mapload, mob/living/host) . = ..() - AddSpell(new /obj/effect/proc_holder/spell/surveillance_snare(null)) + AddSpell(new /datum/spell/surveillance_snare(null)) /mob/living/simple_animal/hostile/guardian/ranged/ToggleMode() if(loc == summoner) diff --git a/code/game/gamemodes/miniantags/guardian/types/standard_guardian.dm b/code/game/gamemodes/miniantags/guardian/types/standard_guardian.dm index d08698bcacd8..d0f7eee819ca 100644 --- a/code/game/gamemodes/miniantags/guardian/types/standard_guardian.dm +++ b/code/game/gamemodes/miniantags/guardian/types/standard_guardian.dm @@ -12,7 +12,7 @@ /mob/living/simple_animal/hostile/guardian/punch/Initialize(mapload, mob/living/host) . = ..() - AddSpell(new /obj/effect/proc_holder/spell/choose_battlecry(null)) + AddSpell(new /datum/spell/choose_battlecry(null)) /mob/living/simple_animal/hostile/guardian/punch/AttackingTarget() . = ..() diff --git a/code/game/gamemodes/miniantags/morph/morph.dm b/code/game/gamemodes/miniantags/morph/morph.dm index 46a2f0af1d23..e65824685188 100644 --- a/code/game/gamemodes/miniantags/morph/morph.dm +++ b/code/game/gamemodes/miniantags/morph/morph.dm @@ -45,11 +45,11 @@ /// How much weaken a successful ambush attack applies var/ambush_weaken = 6 SECONDS /// The spell the morph uses to morph - var/obj/effect/proc_holder/spell/mimic/morph/mimic_spell + var/datum/spell/mimic/morph/mimic_spell /// The ambush action used by the morph - var/obj/effect/proc_holder/spell/morph_spell/ambush/ambush_spell + var/datum/spell/morph_spell/ambush/ambush_spell /// The spell the morph uses to pass through airlocks - var/obj/effect/proc_holder/spell/morph_spell/pass_airlock/pass_airlock_spell + var/datum/spell/morph_spell/pass_airlock/pass_airlock_spell /// How much the morph has gathered in terms of food. Used to reproduce and such var/gathered_food = 20 // Start with a bit to use abilities @@ -60,8 +60,8 @@ AddSpell(mimic_spell) ambush_spell = new AddSpell(ambush_spell) - AddSpell(new /obj/effect/proc_holder/spell/morph_spell/reproduce) - AddSpell(new /obj/effect/proc_holder/spell/morph_spell/open_vent) + AddSpell(new /datum/spell/morph_spell/reproduce) + AddSpell(new /datum/spell/morph_spell/open_vent) pass_airlock_spell = new AddSpell(pass_airlock_spell) @@ -83,8 +83,8 @@ /mob/living/simple_animal/hostile/morph/wizard/Initialize(mapload) . = ..() - AddSpell(new /obj/effect/proc_holder/spell/smoke) - AddSpell(new /obj/effect/proc_holder/spell/forcewall) + AddSpell(new /datum/spell/smoke) + AddSpell(new /datum/spell/forcewall) /mob/living/simple_animal/hostile/morph/proc/try_eat(atom/movable/A) diff --git a/code/game/gamemodes/miniantags/morph/spells/ambush.dm b/code/game/gamemodes/miniantags/morph/spells/ambush.dm index 36da7da9f922..98c79ea1e7a0 100644 --- a/code/game/gamemodes/miniantags/morph/spells/ambush.dm +++ b/code/game/gamemodes/miniantags/morph/spells/ambush.dm @@ -1,16 +1,16 @@ #define MORPH_AMBUSH_PERFECTION_TIME 15 SECONDS -/obj/effect/proc_holder/spell/morph_spell/ambush +/datum/spell/morph_spell/ambush name = "Prepare Ambush" desc = "Prepare an ambush. Dealing significantly more damage on the first hit and you will weaken the target. Only works while morphed. If the target tries to use you with their hands then you will do even more damage. \ Keeping still for another 15 seconds will perfect your disguise." action_icon_state = "morph_ambush" base_cooldown = 8 SECONDS -/obj/effect/proc_holder/spell/morph_spell/ambush/create_new_targeting() +/datum/spell/morph_spell/ambush/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/morph_spell/ambush/can_cast(mob/living/simple_animal/hostile/morph/user, charge_check, show_message) +/datum/spell/morph_spell/ambush/can_cast(mob/living/simple_animal/hostile/morph/user, charge_check, show_message) . = ..() if(!.) return @@ -23,7 +23,7 @@ to_chat(user, "You are already prepared!") return FALSE -/obj/effect/proc_holder/spell/morph_spell/ambush/cast(list/targets, mob/living/simple_animal/hostile/morph/user) +/datum/spell/morph_spell/ambush/cast(list/targets, mob/living/simple_animal/hostile/morph/user) to_chat(user, "You start preparing an ambush.") if(!do_after(user, 6 SECONDS, FALSE, user, TRUE, list(CALLBACK(src, PROC_REF(prepare_check), user)), FALSE)) if(!user.morphed) @@ -33,7 +33,7 @@ return user.prepare_ambush() -/obj/effect/proc_holder/spell/morph_spell/ambush/proc/prepare_check(mob/living/simple_animal/hostile/morph/user) +/datum/spell/morph_spell/ambush/proc/prepare_check(mob/living/simple_animal/hostile/morph/user) return !user.morphed /datum/status_effect/morph_ambush diff --git a/code/game/gamemodes/miniantags/morph/spells/morph_spell.dm b/code/game/gamemodes/miniantags/morph/spells/morph_spell.dm index a4d148660515..d25810208249 100644 --- a/code/game/gamemodes/miniantags/morph/spells/morph_spell.dm +++ b/code/game/gamemodes/miniantags/morph/spells/morph_spell.dm @@ -1,15 +1,15 @@ -/obj/effect/proc_holder/spell/morph_spell +/datum/spell/morph_spell action_background_icon_state = "bg_morph" clothes_req = FALSE /// How much food it costs the morph to use this var/hunger_cost = 0 -/obj/effect/proc_holder/spell/morph_spell/Initialize(mapload) - . = ..() +/datum/spell/morph_spell/New() + ..() if(hunger_cost) name = "[name] ([hunger_cost])" -/obj/effect/proc_holder/spell/morph_spell/create_new_handler() +/datum/spell/morph_spell/create_new_handler() var/datum/spell_handler/morph/H = new H.hunger_cost = hunger_cost return H diff --git a/code/game/gamemodes/miniantags/morph/spells/open_vent.dm b/code/game/gamemodes/miniantags/morph/spells/open_vent.dm index 2b70d6b19c4d..6d198248d03e 100644 --- a/code/game/gamemodes/miniantags/morph/spells/open_vent.dm +++ b/code/game/gamemodes/miniantags/morph/spells/open_vent.dm @@ -1,17 +1,17 @@ -/obj/effect/proc_holder/spell/morph_spell/open_vent +/datum/spell/morph_spell/open_vent name = "Open Vents" desc = "Spit out acidic puke on nearby vents or scrubbers. Will take a little while for the acid to take effect. Not usable from inside a vent." action_icon_state = "acid_vent" base_cooldown = 10 SECONDS hunger_cost = 10 -/obj/effect/proc_holder/spell/morph_spell/open_vent/create_new_targeting() +/datum/spell/morph_spell/open_vent/create_new_targeting() var/datum/spell_targeting/aoe/T = new T.range = 1 T.allowed_type = /obj/machinery/atmospherics/unary return T -/obj/effect/proc_holder/spell/morph_spell/open_vent/valid_target(target, user) +/datum/spell/morph_spell/open_vent/valid_target(target, user) if(istype(target, /obj/machinery/atmospherics/unary/vent_scrubber)) var/obj/machinery/atmospherics/unary/vent_scrubber/S = target return S.welded @@ -20,7 +20,7 @@ return V.welded return FALSE -/obj/effect/proc_holder/spell/morph_spell/open_vent/cast(list/targets, mob/user) +/datum/spell/morph_spell/open_vent/cast(list/targets, mob/user) if(!length(targets)) to_chat(user, "No nearby welded vents found!") revert_cast(user) @@ -36,7 +36,7 @@ addtimer(CALLBACK(src, PROC_REF(unweld_vent), U), 2 SECONDS) playsound(U, 'sound/items/welder.ogg', 100, TRUE) -/obj/effect/proc_holder/spell/morph_spell/open_vent/proc/unweld_vent(obj/machinery/atmospherics/unary/U) +/datum/spell/morph_spell/open_vent/proc/unweld_vent(obj/machinery/atmospherics/unary/U) if(istype(U, /obj/machinery/atmospherics/unary/vent_scrubber)) var/obj/machinery/atmospherics/unary/vent_scrubber/S = U S.welded = FALSE diff --git a/code/game/gamemodes/miniantags/morph/spells/pass_airlock.dm b/code/game/gamemodes/miniantags/morph/spells/pass_airlock.dm index e6cd52148ab8..b8f2f1623bc8 100644 --- a/code/game/gamemodes/miniantags/morph/spells/pass_airlock.dm +++ b/code/game/gamemodes/miniantags/morph/spells/pass_airlock.dm @@ -1,5 +1,5 @@ // TODO refactor when spell code is component based instead of OO based -/obj/effect/proc_holder/spell/morph_spell/pass_airlock +/datum/spell/morph_spell/pass_airlock name = "Pass Airlock" desc = "Reform yourself so you can fit through a non bolted airlock. Takes a while to do and can only be used in a non disguised form." action_background_icon_state = "bg_morph" @@ -8,7 +8,7 @@ base_cooldown = 10 SECONDS selection_activated_message = "Click on an airlock to try pass it." -/obj/effect/proc_holder/spell/morph_spell/pass_airlock/create_new_targeting() +/datum/spell/morph_spell/pass_airlock/create_new_targeting() var/datum/spell_targeting/click/T = new T.range = 1 T.allowed_type = /obj/machinery/door/airlock @@ -16,7 +16,7 @@ return T -/obj/effect/proc_holder/spell/morph_spell/pass_airlock/can_cast(mob/living/simple_animal/hostile/morph/user, charge_check, show_message) +/datum/spell/morph_spell/pass_airlock/can_cast(mob/living/simple_animal/hostile/morph/user, charge_check, show_message) . = ..() if(!.) return @@ -26,7 +26,7 @@ to_chat(user, "You can only pass through airlocks in your true form!") return FALSE -/obj/effect/proc_holder/spell/morph_spell/pass_airlock/cast(list/targets, mob/living/simple_animal/hostile/morph/user) +/datum/spell/morph_spell/pass_airlock/cast(list/targets, mob/living/simple_animal/hostile/morph/user) var/obj/machinery/door/airlock/A = targets[1] if(A.locked) to_chat(user, "[A] is bolted shut! You're unable to create a crack to pass through!") @@ -49,5 +49,5 @@ user.forceMove(A.loc) // Move into the turf of the airlock -/obj/effect/proc_holder/spell/morph_spell/pass_airlock/proc/pass_check(mob/living/simple_animal/hostile/morph/user, obj/machinery/door/airlock/A) +/datum/spell/morph_spell/pass_airlock/proc/pass_check(mob/living/simple_animal/hostile/morph/user, obj/machinery/door/airlock/A) return user.morphed || A.locked diff --git a/code/game/gamemodes/miniantags/morph/spells/reproduce.dm b/code/game/gamemodes/miniantags/morph/spells/reproduce.dm index 814c16cc06a3..d1396646ad7b 100644 --- a/code/game/gamemodes/miniantags/morph/spells/reproduce.dm +++ b/code/game/gamemodes/miniantags/morph/spells/reproduce.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/morph_spell/reproduce +/datum/spell/morph_spell/reproduce name = "Reproduce" desc = "Split yourself in half making a new morph. Can only be used while on a floor. Makes you temporarily unable to vent crawl." hunger_cost = 150 // 5 humans @@ -6,10 +6,10 @@ action_icon_state = "morph_reproduce" create_attack_logs = FALSE -/obj/effect/proc_holder/spell/morph_spell/reproduce/create_new_targeting() +/datum/spell/morph_spell/reproduce/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/morph_spell/reproduce/can_cast(mob/living/simple_animal/hostile/morph/user, charge_check, show_message) +/datum/spell/morph_spell/reproduce/can_cast(mob/living/simple_animal/hostile/morph/user, charge_check, show_message) . = ..() if(!.) return @@ -18,7 +18,7 @@ to_chat(user, "You can only split while on flooring!") return FALSE -/obj/effect/proc_holder/spell/morph_spell/reproduce/cast(list/targets, mob/living/simple_animal/hostile/morph/user) +/datum/spell/morph_spell/reproduce/cast(list/targets, mob/living/simple_animal/hostile/morph/user) to_chat(user, "You prepare to split in two, making you unable to vent crawl!") user.ventcrawler = VENTCRAWLER_NONE // Temporarily disable it var/list/candidates = SSghost_spawns.poll_candidates("Do you want to play as a morph?", ROLE_MORPH, TRUE, poll_time = 10 SECONDS, source = /mob/living/simple_animal/hostile/morph) diff --git a/code/game/gamemodes/miniantags/pulsedemon/pulsedemon.dm b/code/game/gamemodes/miniantags/pulsedemon/pulsedemon.dm index 664ffe97b595..993273c39b75 100644 --- a/code/game/gamemodes/miniantags/pulsedemon/pulsedemon.dm +++ b/code/game/gamemodes/miniantags/pulsedemon/pulsedemon.dm @@ -254,16 +254,16 @@ SSticker.mode.traitors |= mind /mob/living/simple_animal/demon/pulse_demon/proc/give_spells() - AddSpell(new /obj/effect/proc_holder/spell/pulse_demon/cycle_camera) - AddSpell(new /obj/effect/proc_holder/spell/pulse_demon/toggle/do_drain(do_drain)) - AddSpell(new /obj/effect/proc_holder/spell/pulse_demon/toggle/can_exit_cable(can_exit_cable)) - AddSpell(new /obj/effect/proc_holder/spell/pulse_demon/cablehop) - AddSpell(new /obj/effect/proc_holder/spell/pulse_demon/emagtamper) - AddSpell(new /obj/effect/proc_holder/spell/pulse_demon/emp) - AddSpell(new /obj/effect/proc_holder/spell/pulse_demon/overload) - AddSpell(new /obj/effect/proc_holder/spell/pulse_demon/remotehijack) - AddSpell(new /obj/effect/proc_holder/spell/pulse_demon/remotedrain) - AddSpell(new /obj/effect/proc_holder/spell/pulse_demon/open_upgrades) + AddSpell(new /datum/spell/pulse_demon/cycle_camera) + AddSpell(new /datum/spell/pulse_demon/toggle/do_drain(do_drain)) + AddSpell(new /datum/spell/pulse_demon/toggle/can_exit_cable(can_exit_cable)) + AddSpell(new /datum/spell/pulse_demon/cablehop) + AddSpell(new /datum/spell/pulse_demon/emagtamper) + AddSpell(new /datum/spell/pulse_demon/emp) + AddSpell(new /datum/spell/pulse_demon/overload) + AddSpell(new /datum/spell/pulse_demon/remotehijack) + AddSpell(new /datum/spell/pulse_demon/remotedrain) + AddSpell(new /datum/spell/pulse_demon/open_upgrades) /mob/living/simple_animal/demon/pulse_demon/get_status_tab_items() var/list/status_tab_data = ..() @@ -299,7 +299,7 @@ forceMove(T) Move(T) if(!current_cable && !current_power) - var/obj/effect/proc_holder/spell/pulse_demon/toggle/can_exit_cable/S = locate() in mob_spell_list + var/datum/spell/pulse_demon/toggle/can_exit_cable/S = locate() in mob_spell_list if(!S.locked && !can_exit_cable) can_exit_cable = TRUE S.do_toggle(can_exit_cable) @@ -318,7 +318,7 @@ if((!prev && !controlling_area) || (prev && controlling_area)) return // only update icons when we get or no longer have ANY area - for(var/obj/effect/proc_holder/spell/pulse_demon/S in mob_spell_list) + for(var/datum/spell/pulse_demon/S in mob_spell_list) if(!S.action || S.locked) continue if(S.requires_area) @@ -429,7 +429,7 @@ charge_drained += realdelta update_glow() - for(var/obj/effect/proc_holder/spell/pulse_demon/S in mob_spell_list) + for(var/datum/spell/pulse_demon/S in mob_spell_list) if(!S.action || S.locked || !S.cast_cost) continue var/dist = S.cast_cost - orig diff --git a/code/game/gamemodes/miniantags/pulsedemon/pulsedemon_abilities.dm b/code/game/gamemodes/miniantags/pulsedemon/pulsedemon_abilities.dm index 6901e46e7d7b..fb537324b9ab 100644 --- a/code/game/gamemodes/miniantags/pulsedemon/pulsedemon_abilities.dm +++ b/code/game/gamemodes/miniantags/pulsedemon/pulsedemon_abilities.dm @@ -8,7 +8,7 @@ #define PD_UPGRADE_HEALTH_COST "Efficiency" #define PD_UPGRADE_MAX_CHARGE "Capacity" -/obj/effect/proc_holder/spell/pulse_demon +/datum/spell/pulse_demon panel = "Pulse Demon" school = "pulse demon" clothes_req = FALSE @@ -21,11 +21,11 @@ base_cooldown = 20 SECONDS level_max = 4 -/obj/effect/proc_holder/spell/pulse_demon/New() +/datum/spell/pulse_demon/New() . = ..() update_info() -/obj/effect/proc_holder/spell/pulse_demon/proc/update_info() +/datum/spell/pulse_demon/proc/update_info() if(locked) name = "[initial(name)] (Locked) ([format_si_suffix(unlock_cost)]W)" desc = "[initial(desc)] It costs [format_si_suffix(unlock_cost)]W to unlock." @@ -36,7 +36,7 @@ action.desc = desc action.UpdateButtons() -/obj/effect/proc_holder/spell/pulse_demon/can_cast(mob/living/simple_animal/demon/pulse_demon/user, charge_check, show_message) +/datum/spell/pulse_demon/can_cast(mob/living/simple_animal/demon/pulse_demon/user, charge_check, show_message) if(!..()) return FALSE if(!istype(user)) @@ -57,7 +57,7 @@ return FALSE return TRUE -/obj/effect/proc_holder/spell/pulse_demon/cast(list/targets, mob/living/simple_animal/demon/pulse_demon/user) +/datum/spell/pulse_demon/cast(list/targets, mob/living/simple_animal/demon/pulse_demon/user) if(!istype(user) || locked || user.charge < cast_cost || !length(targets)) return FALSE if(requires_area && !user.controlling_area) @@ -72,14 +72,14 @@ revert_cast(user) return FALSE -/obj/effect/proc_holder/spell/pulse_demon/create_new_targeting() +/datum/spell/pulse_demon/create_new_targeting() return new /datum/spell_targeting/clicked_atom -/obj/effect/proc_holder/spell/pulse_demon/proc/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target) +/datum/spell/pulse_demon/proc/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target) return FALSE // handles purchasing and upgrading abilities -/obj/effect/proc_holder/spell/pulse_demon/AltClick(mob/living/simple_animal/demon/pulse_demon/user) +/datum/spell/pulse_demon/AltClick(mob/living/simple_animal/demon/pulse_demon/user) if(!istype(user)) return @@ -115,11 +115,11 @@ else to_chat(user, "You cannot afford to upgrade this ability! It costs [format_si_suffix(upgrade_cost)]W to upgrade.") -/obj/effect/proc_holder/spell/pulse_demon/proc/do_upgrade(mob/living/simple_animal/demon/pulse_demon/user) +/datum/spell/pulse_demon/proc/do_upgrade(mob/living/simple_animal/demon/pulse_demon/user) cooldown_handler.recharge_duration = round(base_cooldown / (1.5 ** spell_level)) to_chat(user, "You have upgraded [initial(name)] to level [spell_level + 1], it now takes [cooldown_handler.recharge_duration / 10] seconds to recharge.") -/obj/effect/proc_holder/spell/pulse_demon/cablehop +/datum/spell/pulse_demon/cablehop name = "Cable Hop" desc = "Jump to another cable in view." action_icon_state = "pd_cablehop" @@ -127,7 +127,7 @@ cast_cost = 5 KW upgrade_cost = 75 KW -/obj/effect/proc_holder/spell/pulse_demon/cablehop/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target) +/datum/spell/pulse_demon/cablehop/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target) var/turf/O = get_turf(user) var/turf/T = get_turf(target) var/obj/structure/cable/C = locate(/obj/structure/cable) in T @@ -145,7 +145,7 @@ user.Move(T) return TRUE -/obj/effect/proc_holder/spell/pulse_demon/emagtamper +/datum/spell/pulse_demon/emagtamper name = "Electromagnetic Tamper" desc = "Unlocks hidden programming in machines. Must be inside a hijacked APC to use." action_icon_state = "pd_emag" @@ -154,12 +154,12 @@ upgrade_cost = 200 KW requires_area = TRUE -/obj/effect/proc_holder/spell/pulse_demon/emagtamper/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target) +/datum/spell/pulse_demon/emagtamper/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target) to_chat(user, "You attempt to tamper with [target]!") target.emag_act(user) return TRUE -/obj/effect/proc_holder/spell/pulse_demon/emp +/datum/spell/pulse_demon/emp name = "Electromagnetic Pulse" desc = "Creates an EMP where you click. Be careful not to use it on yourself!" action_icon_state = "pd_emp" @@ -168,12 +168,12 @@ upgrade_cost = 200 KW requires_area = TRUE -/obj/effect/proc_holder/spell/pulse_demon/emp/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target) +/datum/spell/pulse_demon/emp/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target) to_chat(user, "You attempt to EMP [target]!") empulse(get_turf(target), 1, 1) return TRUE -/obj/effect/proc_holder/spell/pulse_demon/overload +/datum/spell/pulse_demon/overload name = "Overload Machine" desc = "Overloads a machine, causing it to explode." action_icon_state = "pd_overload" @@ -182,7 +182,7 @@ upgrade_cost = 500 KW requires_area = TRUE -/obj/effect/proc_holder/spell/pulse_demon/overload/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target) +/datum/spell/pulse_demon/overload/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target) var/obj/machinery/M = target if(!istype(M)) to_chat(user, "That is not a machine.") @@ -194,13 +194,13 @@ addtimer(CALLBACK(src, PROC_REF(detonate), M), 5 SECONDS) return TRUE -/obj/effect/proc_holder/spell/pulse_demon/overload/proc/detonate(obj/machinery/target) +/datum/spell/pulse_demon/overload/proc/detonate(obj/machinery/target) if(!QDELETED(target)) explosion(get_turf(target), 0, 1, 1, 0) if(!QDELETED(target)) qdel(target) -/obj/effect/proc_holder/spell/pulse_demon/remotehijack +/datum/spell/pulse_demon/remotehijack name = "Remote Hijack" desc = "Remotely hijacks an APC." action_icon_state = "pd_remotehack" @@ -209,7 +209,7 @@ level_max = 0 base_cooldown = 3 SECONDS // you have to wait for the regular hijack time anyway -/obj/effect/proc_holder/spell/pulse_demon/remotehijack/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target) +/datum/spell/pulse_demon/remotehijack/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target) var/obj/machinery/power/apc/A = target if(!istype(A)) to_chat(user, "That is not an APC.") @@ -218,7 +218,7 @@ to_chat(user, "You cannot hijack that APC right now!") return TRUE -/obj/effect/proc_holder/spell/pulse_demon/remotedrain +/datum/spell/pulse_demon/remotedrain name = "Remote Drain" desc = "Remotely drains a power source." action_icon_state = "pd_remotedrain" @@ -226,7 +226,7 @@ cast_cost = 100 upgrade_cost = 100 KW -/obj/effect/proc_holder/spell/pulse_demon/remotedrain/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target) +/datum/spell/pulse_demon/remotedrain/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target) if(isapc(target)) var/drained = user.drain_APC(target, PULSEDEMON_REMOTE_DRAIN_MULTIPLIER) if(drained == PULSEDEMON_SOURCE_DRAIN_INVALID) @@ -241,20 +241,20 @@ return FALSE return TRUE -/obj/effect/proc_holder/spell/pulse_demon/toggle +/datum/spell/pulse_demon/toggle base_cooldown = 0 cast_cost = 0 create_attack_logs = FALSE var/base_message = "see messages you shouldn't!" -/obj/effect/proc_holder/spell/pulse_demon/toggle/New(initstate = FALSE) +/datum/spell/pulse_demon/toggle/New(initstate = FALSE) . = ..() do_toggle(initstate, null) -/obj/effect/proc_holder/spell/pulse_demon/toggle/create_new_targeting() +/datum/spell/pulse_demon/toggle/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/pulse_demon/toggle/proc/do_toggle(varstate, mob/user) +/datum/spell/pulse_demon/toggle/proc/do_toggle(varstate, mob/user) if(action) action.background_icon_state = varstate ? action_background_icon_state : "[action_background_icon_state]_disabled" action.UpdateButtons() @@ -262,7 +262,7 @@ to_chat(user, "You will [varstate ? "now" : "no longer"] [base_message]") return varstate -/obj/effect/proc_holder/spell/pulse_demon/toggle/do_drain +/datum/spell/pulse_demon/toggle/do_drain name = "Toggle Draining" desc = "Toggle whether you drain charge from power sources." base_message = "drain charge from power sources." @@ -270,11 +270,11 @@ locked = FALSE level_max = 0 -/obj/effect/proc_holder/spell/pulse_demon/toggle/do_drain/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target) +/datum/spell/pulse_demon/toggle/do_drain/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target) user.do_drain = do_toggle(!user.do_drain, user) return TRUE -/obj/effect/proc_holder/spell/pulse_demon/toggle/do_drain/AltClick(mob/living/simple_animal/demon/pulse_demon/user) +/datum/spell/pulse_demon/toggle/do_drain/AltClick(mob/living/simple_animal/demon/pulse_demon/user) if(!istype(user)) return @@ -288,7 +288,7 @@ user.power_drain_rate = amount to_chat(user, "Drain speed has been set to [format_si_suffix(user.power_drain_rate)]W per second.") -/obj/effect/proc_holder/spell/pulse_demon/toggle/can_exit_cable +/datum/spell/pulse_demon/toggle/can_exit_cable name = "Toggle Self-Sustaining" desc = "Toggle whether you can move outside of cables or power sources." base_message = "move outside of cables." @@ -297,18 +297,18 @@ upgrade_cost = 300 KW level_max = 3 -/obj/effect/proc_holder/spell/pulse_demon/toggle/can_exit_cable/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target) +/datum/spell/pulse_demon/toggle/can_exit_cable/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target) if(user.can_exit_cable && !(user.current_cable || user.current_power)) to_chat(user, "Enter a cable or power source first!") return FALSE user.can_exit_cable = do_toggle(!user.can_exit_cable, user) return TRUE -/obj/effect/proc_holder/spell/pulse_demon/toggle/can_exit_cable/do_upgrade(mob/living/simple_animal/demon/pulse_demon/user) +/datum/spell/pulse_demon/toggle/can_exit_cable/do_upgrade(mob/living/simple_animal/demon/pulse_demon/user) user.outside_cable_speed = max(initial(user.outside_cable_speed) - spell_level, 1) to_chat(user, "You have upgraded [initial(name)] to level [spell_level + 1], you will now move faster outside of cables.") -/obj/effect/proc_holder/spell/pulse_demon/cycle_camera +/datum/spell/pulse_demon/cycle_camera name = "Cycle Camera View" desc = "Jump between the cameras in your APC's area. Alt-click to return to the APC." action_icon_state = "pd_camera_view" @@ -320,10 +320,10 @@ requires_area = TRUE var/current_camera = 0 -/obj/effect/proc_holder/spell/pulse_demon/cycle_camera/create_new_targeting() +/datum/spell/pulse_demon/cycle_camera/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/pulse_demon/cycle_camera/AltClick(mob/living/simple_animal/demon/pulse_demon/user) +/datum/spell/pulse_demon/cycle_camera/AltClick(mob/living/simple_animal/demon/pulse_demon/user) if(!istype(user)) return current_camera = 0 @@ -334,7 +334,7 @@ return user.forceMove(user.current_power) -/obj/effect/proc_holder/spell/pulse_demon/cycle_camera/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target) +/datum/spell/pulse_demon/cycle_camera/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target) if(!length(user.controlling_area.cameras)) return FALSE @@ -352,7 +352,7 @@ user.forceMove(locateUID(user.controlling_area.cameras[current_camera + 1])) return TRUE -/obj/effect/proc_holder/spell/pulse_demon/open_upgrades +/datum/spell/pulse_demon/open_upgrades name = "Open Upgrade Menu" desc = "Open the upgrades menu. Alt-click for descriptions and costs." action_icon_state = "pd_upgrade" @@ -380,10 +380,10 @@ PD_UPGRADE_MAX_CHARGE = "Increase the total amount of charge you can have at once." ) -/obj/effect/proc_holder/spell/pulse_demon/open_upgrades/create_new_targeting() +/datum/spell/pulse_demon/open_upgrades/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/pulse_demon/open_upgrades/proc/calc_cost(mob/living/simple_animal/demon/pulse_demon/user, upgrade) +/datum/spell/pulse_demon/open_upgrades/proc/calc_cost(mob/living/simple_animal/demon/pulse_demon/user, upgrade) var/cost switch(upgrade) if(PD_UPGRADE_HIJACK_SPEED) @@ -416,7 +416,7 @@ return -1 return round(cost) -/obj/effect/proc_holder/spell/pulse_demon/open_upgrades/proc/get_upgrades(mob/living/simple_animal/demon/pulse_demon/user) +/datum/spell/pulse_demon/open_upgrades/proc/get_upgrades(mob/living/simple_animal/demon/pulse_demon/user) var/upgrades = list() for(var/upgrade in upgrade_icons) var/cost = calc_cost(user, upgrade) @@ -425,7 +425,7 @@ upgrades["[upgrade] ([format_si_suffix(cost)]W)"] = upgrade_icons[upgrade] return upgrades -/obj/effect/proc_holder/spell/pulse_demon/open_upgrades/AltClick(mob/living/simple_animal/demon/pulse_demon/user) +/datum/spell/pulse_demon/open_upgrades/AltClick(mob/living/simple_animal/demon/pulse_demon/user) if(!istype(user)) return @@ -434,7 +434,7 @@ var/cost = calc_cost(user, upgrade) to_chat(user, "[upgrade] ([cost == -1 ? "Fully Upgraded" : "[format_si_suffix(cost)]W"]) - [upgrade_descs[upgrade]]") -/obj/effect/proc_holder/spell/pulse_demon/open_upgrades/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target) +/datum/spell/pulse_demon/open_upgrades/try_cast_action(mob/living/simple_animal/demon/pulse_demon/user, atom/target) var/upgrades = get_upgrades(user) if(!length(upgrades)) to_chat(user, "You have already fully upgraded everything available!") diff --git a/code/game/gamemodes/miniantags/revenant/revenant.dm b/code/game/gamemodes/miniantags/revenant/revenant.dm index bd3959475574..790fa4ee4478 100644 --- a/code/game/gamemodes/miniantags/revenant/revenant.dm +++ b/code/game/gamemodes/miniantags/revenant/revenant.dm @@ -192,13 +192,13 @@ to_chat(src, chat_box_red(messages.Join("
"))) /mob/living/simple_animal/revenant/proc/giveSpells() - mind.AddSpell(new /obj/effect/proc_holder/spell/night_vision/revenant(null)) - mind.AddSpell(new /obj/effect/proc_holder/spell/revenant_transmit(null)) - mind.AddSpell(new /obj/effect/proc_holder/spell/aoe/revenant/defile(null)) - mind.AddSpell(new /obj/effect/proc_holder/spell/aoe/revenant/malfunction(null)) - mind.AddSpell(new /obj/effect/proc_holder/spell/aoe/revenant/overload(null)) - mind.AddSpell(new /obj/effect/proc_holder/spell/aoe/revenant/haunt_object(null)) - mind.AddSpell(new /obj/effect/proc_holder/spell/aoe/revenant/hallucinations(null)) + mind.AddSpell(new /datum/spell/night_vision/revenant(null)) + mind.AddSpell(new /datum/spell/revenant_transmit(null)) + mind.AddSpell(new /datum/spell/aoe/revenant/defile(null)) + mind.AddSpell(new /datum/spell/aoe/revenant/malfunction(null)) + mind.AddSpell(new /datum/spell/aoe/revenant/overload(null)) + mind.AddSpell(new /datum/spell/aoe/revenant/haunt_object(null)) + mind.AddSpell(new /datum/spell/aoe/revenant/hallucinations(null)) return TRUE diff --git a/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm b/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm index bc3b622ad25f..0bb6122c1b22 100644 --- a/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm +++ b/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm @@ -108,7 +108,7 @@ return //Toggle night vision: lets the revenant toggle its night vision -/obj/effect/proc_holder/spell/night_vision/revenant +/datum/spell/night_vision/revenant base_cooldown = 0 panel = "Revenant Abilities" message = "You toggle your night vision." @@ -116,7 +116,7 @@ action_background_icon_state = "bg_revenant" //Transmit: the revemant's only direct way to communicate. Sends a single message silently to a single mob -/obj/effect/proc_holder/spell/revenant_transmit +/datum/spell/revenant_transmit name = "Transmit" desc = "Telepathically transmits a message to the target." panel = "Revenant Abilities" @@ -125,12 +125,12 @@ action_icon_state = "r_transmit" action_background_icon_state = "bg_revenant" -/obj/effect/proc_holder/spell/revenant_transmit/create_new_targeting() +/datum/spell/revenant_transmit/create_new_targeting() var/datum/spell_targeting/targeted/T = new() T.allowed_type = /mob/living return T -/obj/effect/proc_holder/spell/revenant_transmit/cast(list/targets, mob/living/simple_animal/revenant/user = usr) +/datum/spell/revenant_transmit/cast(list/targets, mob/living/simple_animal/revenant/user = usr) for(var/mob/living/M in targets) spawn(0) var/msg = tgui_input_text(user, "What do you wish to tell [M]?", "Transmit") @@ -141,7 +141,7 @@ to_chat(user, "You transmit to [M]: [msg]") to_chat(M, "An alien voice resonates from all around... [msg]") -/obj/effect/proc_holder/spell/aoe/revenant +/datum/spell/aoe/revenant name = "Spell" clothes_req = FALSE action_background_icon_state = "bg_revenant" @@ -157,20 +157,20 @@ /// How much essence it costs to use var/cast_amount = 50 -/obj/effect/proc_holder/spell/aoe/revenant/New() +/datum/spell/aoe/revenant/New() ..() if(locked) name = "[initial(name)] ([unlock_amount]E)" else name = "[initial(name)] ([cast_amount]E)" -/obj/effect/proc_holder/spell/aoe/revenant/revert_cast(mob/user) +/datum/spell/aoe/revenant/revert_cast(mob/user) . = ..() to_chat(user, "Your ability wavers and fails!") var/mob/living/simple_animal/revenant/R = user R?.essence += cast_amount //refund the spell and reset -/obj/effect/proc_holder/spell/aoe/revenant/can_cast(mob/living/simple_animal/revenant/user = usr, charge_check = TRUE, show_message = FALSE) +/datum/spell/aoe/revenant/can_cast(mob/living/simple_animal/revenant/user = usr, charge_check = TRUE, show_message = FALSE) if(user.inhibited) return FALSE if(cooldown_handler.is_on_cooldown()) @@ -182,7 +182,7 @@ return FALSE return TRUE -/obj/effect/proc_holder/spell/aoe/revenant/proc/attempt_cast(mob/living/simple_animal/revenant/user = usr) +/datum/spell/aoe/revenant/proc/attempt_cast(mob/living/simple_animal/revenant/user = usr) if(locked) if(!user.castcheck(-unlock_amount)) cooldown_handler.revert_cast() @@ -204,7 +204,7 @@ return TRUE //Overload Light: Breaks a light that's online and sends out lightning bolts to all nearby people. -/obj/effect/proc_holder/spell/aoe/revenant/overload +/datum/spell/aoe/revenant/overload name = "Overload Lights" desc = "Directs a large amount of essence into nearby electrical lights, causing lights to shock those nearby." base_cooldown = 20 SECONDS @@ -215,21 +215,21 @@ action_icon_state = "overload_lights" aoe_range = 5 -/obj/effect/proc_holder/spell/aoe/revenant/overload/create_new_targeting() +/datum/spell/aoe/revenant/overload/create_new_targeting() var/datum/spell_targeting/aoe/targeting = new() targeting.range = aoe_range targeting.allowed_type = /obj/machinery/light return targeting -/obj/effect/proc_holder/spell/aoe/revenant/overload/cast(list/targets, mob/living/simple_animal/revenant/user = usr) +/datum/spell/aoe/revenant/overload/cast(list/targets, mob/living/simple_animal/revenant/user = usr) if(attempt_cast(user)) for(var/obj/machinery/light/L as anything in targets) INVOKE_ASYNC(src, PROC_REF(shock_lights), L, user) -/obj/effect/proc_holder/spell/aoe/revenant/overload/proc/shock_lights(obj/machinery/light/L, mob/living/simple_animal/revenant/user) +/datum/spell/aoe/revenant/overload/proc/shock_lights(obj/machinery/light/L, mob/living/simple_animal/revenant/user) if(!L.on) return - L.visible_message("\The [L] suddenly flares brightly and begins to spark!") + L.visible_message("\The [L] suddenly flares brightly and begins to spark!") do_sparks(4, 0, L) new /obj/effect/temp_visual/revenant(L.loc) sleep(2 SECONDS) @@ -246,7 +246,7 @@ playsound(M, 'sound/machines/defib_zap.ogg', 50, TRUE, -1) //Defile: Corrupts nearby stuff, unblesses floor tiles. -/obj/effect/proc_holder/spell/aoe/revenant/defile +/datum/spell/aoe/revenant/defile name = "Defile" desc = "Twists and corrupts the nearby area as well as dispelling holy auras on floors." base_cooldown = 15 SECONDS @@ -257,12 +257,12 @@ action_icon_state = "defile" aoe_range = 4 -/obj/effect/proc_holder/spell/aoe/revenant/defile/create_new_targeting() +/datum/spell/aoe/revenant/defile/create_new_targeting() var/datum/spell_targeting/aoe/turf/targeting = new() targeting.range = aoe_range return targeting -/obj/effect/proc_holder/spell/aoe/revenant/defile/cast(list/targets, mob/living/simple_animal/revenant/user = usr) +/datum/spell/aoe/revenant/defile/cast(list/targets, mob/living/simple_animal/revenant/user = usr) if(!attempt_cast(user)) return for(var/turf/T in targets) @@ -271,7 +271,7 @@ A.defile() //Malfunction: Makes bad stuff happen to robots and machines. -/obj/effect/proc_holder/spell/aoe/revenant/malfunction +/datum/spell/aoe/revenant/malfunction name = "Malfunction" desc = "Corrupts and damages nearby machines and mechanical objects." base_cooldown = 200 @@ -280,18 +280,18 @@ action_icon_state = "malfunction" aoe_range = 2 -/obj/effect/proc_holder/spell/aoe/revenant/malfunction/create_new_targeting() +/datum/spell/aoe/revenant/malfunction/create_new_targeting() var/datum/spell_targeting/aoe/turf/targeting = new() targeting.range = aoe_range return targeting //A note to future coders: do not replace this with an EMP because it will wreck malf AIs and gang dominators and everyone will hate you. -/obj/effect/proc_holder/spell/aoe/revenant/malfunction/cast(list/targets, mob/living/simple_animal/revenant/user = usr) +/datum/spell/aoe/revenant/malfunction/cast(list/targets, mob/living/simple_animal/revenant/user = usr) if(attempt_cast(user)) for(var/turf/T in targets) INVOKE_ASYNC(src, PROC_REF(effect), user, T) -/obj/effect/proc_holder/spell/aoe/revenant/malfunction/proc/effect(mob/living/simple_animal/revenant/user, turf/T) +/datum/spell/aoe/revenant/malfunction/proc/effect(mob/living/simple_animal/revenant/user, turf/T) T.rev_malfunction(TRUE) for(var/atom/A in T.contents) A.rev_malfunction(TRUE) @@ -299,7 +299,7 @@ /** * Makes objects be haunted and then throws them at conscious people to do damage, spooky! */ -/obj/effect/proc_holder/spell/aoe/revenant/haunt_object +/datum/spell/aoe/revenant/haunt_object name = "Haunt Objects" desc = "Empower nearby objects to you with ghostly energy, causing them to attack nearby mortals. \ Items closer to you are more likely to be haunted." @@ -315,13 +315,13 @@ /// A list of all attack timers started by this spell being cast var/list/attack_timers = list() -/obj/effect/proc_holder/spell/aoe/revenant/haunt_object/create_new_targeting() +/datum/spell/aoe/revenant/haunt_object/create_new_targeting() var/datum/spell_targeting/aoe/targeting = new() targeting.range = aoe_range targeting.allowed_type = /obj/item return targeting -/obj/effect/proc_holder/spell/aoe/revenant/haunt_object/cast(list/targets, mob/living/simple_animal/revenant/user = usr) +/datum/spell/aoe/revenant/haunt_object/cast(list/targets, mob/living/simple_animal/revenant/user = usr) if(!attempt_cast(user)) return @@ -357,7 +357,7 @@ addtimer(CALLBACK(src, PROC_REF(stop_timers)), 65 SECONDS, TIMER_UNIQUE) /// Handles making an object haunted and setting it up to attack -/obj/effect/proc_holder/spell/aoe/revenant/haunt_object/proc/make_spooky(obj/item/item_to_possess, mob/living/simple_animal/revenant/user) +/datum/spell/aoe/revenant/haunt_object/proc/make_spooky(obj/item/item_to_possess, mob/living/simple_animal/revenant/user) new /obj/effect/temp_visual/revenant(get_turf(item_to_possess)) // Thematic spooky visuals var/mob/living/simple_animal/possessed_object/possessed_object = new(item_to_possess) // Begin haunting object item_to_possess.throwforce = min(item_to_possess.throwforce + 5, 15) // Damage it should do? throwforce+5 or 15, whichever is lower @@ -372,7 +372,7 @@ addtimer(CALLBACK(possessed_object, TYPE_PROC_REF(/mob/living/simple_animal/possessed_object, death)), 70 SECONDS, TIMER_UNIQUE) // De-haunt the object /// Handles finding a valid target and throwing us at it -/obj/effect/proc_holder/spell/aoe/revenant/haunt_object/proc/attack(mob/living/simple_animal/possessed_object/possessed_object, mob/living/simple_animal/revenant/user) +/datum/spell/aoe/revenant/haunt_object/proc/attack(mob/living/simple_animal/possessed_object/possessed_object, mob/living/simple_animal/revenant/user) var/list/potential_victims = list() for(var/turf/turf_to_search in spiral_range_turfs(aoe_range, get_turf(possessed_object))) for(var/mob/living/carbon/potential_victim in turf_to_search) @@ -393,20 +393,20 @@ possessed_object.throw_at(victim, aoe_range, 2, user, dodgeable = FALSE) /// Sets the glow on the haunted object, scales up based on throwforce -/obj/effect/proc_holder/spell/aoe/revenant/haunt_object/proc/set_outline(mob/living/simple_animal/possessed_object/possessed_object) +/datum/spell/aoe/revenant/haunt_object/proc/set_outline(mob/living/simple_animal/possessed_object/possessed_object) possessed_object.remove_filter("haunt_glow") var/outline_size = min((possessed_object.possessed_item.throwforce / 15) * 3, 3) possessed_object.add_filter("haunt_glow", 2, list("type" = "outline", "color" = "#7A4FA9", "size" = outline_size)) // Give it spooky purple outline /// Stop all attack timers cast by the previous spell use -/obj/effect/proc_holder/spell/aoe/revenant/haunt_object/proc/stop_timers() +/datum/spell/aoe/revenant/haunt_object/proc/stop_timers() for(var/I in attack_timers) deltimer(I) /** * Gives everyone in a 7 tile radius 2 minutes of hallucinations */ -/obj/effect/proc_holder/spell/aoe/revenant/hallucinations +/datum/spell/aoe/revenant/hallucinations name = "Hallucination Aura" desc = "Toy with the living nearby, giving them glimpses of things that could be or once were." action_icon_state = "hallucinations" @@ -416,13 +416,13 @@ stun = 1 SECONDS reveal = 3 SECONDS -/obj/effect/proc_holder/spell/aoe/revenant/hallucinations/create_new_targeting() +/datum/spell/aoe/revenant/hallucinations/create_new_targeting() var/datum/spell_targeting/aoe/targeting = new() targeting.range = aoe_range targeting.allowed_type = /mob/living/carbon return targeting -/obj/effect/proc_holder/spell/aoe/revenant/hallucinations/cast(list/targets, mob/living/simple_animal/revenant/user = usr) +/datum/spell/aoe/revenant/hallucinations/cast(list/targets, mob/living/simple_animal/revenant/user = usr) if(!attempt_cast(user)) return diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm index 93c6eaec86d5..9583e0e849f5 100644 --- a/code/game/gamemodes/revolution/revolution.dm +++ b/code/game/gamemodes/revolution/revolution.dm @@ -44,6 +44,7 @@ var/datum/mind/new_headrev = pick_n_take(possible_revolutionaries) pre_revolutionaries |= new_headrev new_headrev.restricted_roles = restricted_jobs + new_headrev.special_role = SPECIAL_ROLE_HEAD_REV if(length(pre_revolutionaries) < required_enemies) return FALSE diff --git a/code/game/gamemodes/wizard/godhand.dm b/code/game/gamemodes/wizard/godhand.dm index 47c24e01b488..77e4f3cbb7b4 100644 --- a/code/game/gamemodes/wizard/godhand.dm +++ b/code/game/gamemodes/wizard/godhand.dm @@ -3,7 +3,7 @@ desc = "High Five?" var/catchphrase = "High Five!" var/on_use_sound = null - var/obj/effect/proc_holder/spell/touch/attached_spell + var/datum/spell/touch/attached_spell icon = 'icons/obj/weapons/magical_weapons.dmi' icon_state = "disintegrate" item_state = null diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm index 713904da0d14..2190b08c3e15 100644 --- a/code/game/gamemodes/wizard/soulstone.dm +++ b/code/game/gamemodes/wizard/soulstone.dm @@ -400,9 +400,9 @@ if(SS.purified) make_holy() // Replace regular soulstone summoning with purified soulstones - if(is_type_in_list(/obj/effect/proc_holder/spell/aoe/conjure/build/soulstone, mob_spell_list)) - RemoveSpell(/obj/effect/proc_holder/spell/aoe/conjure/build/soulstone) - AddSpell(new /obj/effect/proc_holder/spell/aoe/conjure/build/soulstone/holy) + if(is_type_in_list(/datum/spell/aoe/conjure/build/soulstone, mob_spell_list)) + RemoveSpell(/datum/spell/aoe/conjure/build/soulstone) + AddSpell(new /datum/spell/aoe/conjure/build/soulstone/holy) else if(mind.has_antag_datum(/datum/antagonist/cultist)) // Re-grant cult actions, lost in the transfer var/datum/action/innate/cult/comm/CC = new diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm index c35fb06081a4..049dd42d21d0 100644 --- a/code/game/gamemodes/wizard/spellbook.dm +++ b/code/game/gamemodes/wizard/spellbook.dm @@ -6,7 +6,7 @@ var/category = "Offensive" var/cost = 2 var/refundable = TRUE - var/obj/effect/proc_holder/spell/S = null //Since spellbooks can be used by only one person anyway we can track the actual spell + var/datum/spell/S = null //Since spellbooks can be used by only one person anyway we can track the actual spell var/buy_word = "Learn" var/limit //used to prevent a spellbook_entry from being bought more than X times with one wizard spellbook @@ -21,8 +21,8 @@ return LearnSpell(user, book, S) -/datum/spellbook_entry/proc/LearnSpell(mob/living/carbon/human/user, obj/item/spellbook/book, obj/effect/proc_holder/spell/newspell) - for(var/obj/effect/proc_holder/spell/aspell in user.mind.spell_list) +/datum/spellbook_entry/proc/LearnSpell(mob/living/carbon/human/user, obj/item/spellbook/book, datum/spell/newspell) + for(var/datum/spell/aspell in user.mind.spell_list) if(initial(newspell.name) == initial(aspell.name)) // Not using directly in case it was learned from one spellbook then upgraded in another if(aspell.spell_level >= aspell.level_max) to_chat(user, "This spell cannot be improved further.") @@ -59,7 +59,7 @@ return FALSE if(!S) S = new spell_type() - for(var/obj/effect/proc_holder/spell/aspell in user.mind.spell_list) + for(var/datum/spell/aspell in user.mind.spell_list) if(initial(S.name) == initial(aspell.name)) return TRUE return FALSE @@ -72,7 +72,7 @@ if(!S) //This happens when the spell's source is from another spellbook, from loadouts, or adminery, this create a new template temporary spell S = new spell_type() var/spell_levels = 0 - for(var/obj/effect/proc_holder/spell/aspell in user.mind.spell_list) + for(var/datum/spell/aspell in user.mind.spell_list) if(initial(S.name) == initial(aspell.name)) spell_levels = aspell.spell_level user.mind.spell_list.Remove(aspell) @@ -97,126 +97,126 @@ //Offensive /datum/spellbook_entry/blind name = "Blind" - spell_type = /obj/effect/proc_holder/spell/trigger/blind + spell_type = /datum/spell/genetic/blind category = "Offensive" cost = 1 /datum/spellbook_entry/lightningbolt name = "Lightning Bolt" - spell_type = /obj/effect/proc_holder/spell/charge_up/bounce/lightning + spell_type = /datum/spell/charge_up/bounce/lightning category = "Offensive" cost = 1 /datum/spellbook_entry/cluwne name = "Curse of the Cluwne" - spell_type = /obj/effect/proc_holder/spell/touch/cluwne + spell_type = /datum/spell/touch/cluwne category = "Offensive" /datum/spellbook_entry/banana_touch name = "Banana Touch" - spell_type = /obj/effect/proc_holder/spell/touch/banana + spell_type = /datum/spell/touch/banana cost = 1 /datum/spellbook_entry/mime_malaise name = "Mime Malaise" - spell_type = /obj/effect/proc_holder/spell/touch/mime_malaise + spell_type = /datum/spell/touch/mime_malaise cost = 1 /datum/spellbook_entry/horseman name = "Curse of the Horseman" - spell_type = /obj/effect/proc_holder/spell/horsemask + spell_type = /datum/spell/horsemask category = "Offensive" /datum/spellbook_entry/disintegrate name = "Disintegrate" - spell_type = /obj/effect/proc_holder/spell/touch/disintegrate + spell_type = /datum/spell/touch/disintegrate category = "Offensive" /datum/spellbook_entry/fireball name = "Fireball" - spell_type = /obj/effect/proc_holder/spell/fireball + spell_type = /datum/spell/fireball category = "Offensive" /datum/spellbook_entry/summon_toolbox name = "Homing Toolbox" - spell_type = /obj/effect/proc_holder/spell/fireball/toolbox + spell_type = /datum/spell/fireball/toolbox category = "Offensive" cost = 1 /datum/spellbook_entry/fleshtostone name = "Flesh to Stone" - spell_type = /obj/effect/proc_holder/spell/touch/flesh_to_stone + spell_type = /datum/spell/touch/flesh_to_stone category = "Offensive" /datum/spellbook_entry/mutate name = "Mutate" - spell_type = /obj/effect/proc_holder/spell/genetic/mutate + spell_type = /datum/spell/genetic/mutate category = "Offensive" /datum/spellbook_entry/rod_form name = "Rod Form" - spell_type = /obj/effect/proc_holder/spell/rod_form + spell_type = /datum/spell/rod_form category = "Offensive" /datum/spellbook_entry/infinite_guns name = "Lesser Summon Guns" - spell_type = /obj/effect/proc_holder/spell/infinite_guns + spell_type = /datum/spell/infinite_guns category = "Offensive" //Defensive /datum/spellbook_entry/disabletech name = "Disable Tech" - spell_type = /obj/effect/proc_holder/spell/emplosion/disable_tech + spell_type = /datum/spell/emplosion/disable_tech category = "Defensive" cost = 1 /datum/spellbook_entry/forcewall name = "Force Wall" - spell_type = /obj/effect/proc_holder/spell/forcewall + spell_type = /datum/spell/forcewall category = "Defensive" cost = 1 /datum/spellbook_entry/rathens name = "Rathen's Secret" - spell_type = /obj/effect/proc_holder/spell/rathens + spell_type = /datum/spell/rathens category = "Defensive" cost = 2 /datum/spellbook_entry/repulse name = "Repulse" - spell_type = /obj/effect/proc_holder/spell/aoe/repulse + spell_type = /datum/spell/aoe/repulse category = "Defensive" cost = 1 /datum/spellbook_entry/smoke name = "Smoke" - spell_type = /obj/effect/proc_holder/spell/smoke + spell_type = /datum/spell/smoke category = "Defensive" cost = 1 /datum/spellbook_entry/lichdom name = "Bind Soul" - spell_type = /obj/effect/proc_holder/spell/lichdom + spell_type = /datum/spell/lichdom category = "Defensive" is_ragin_restricted = TRUE /datum/spellbook_entry/magicm name = "Magic Missile" - spell_type = /obj/effect/proc_holder/spell/projectile/magic_missile + spell_type = /datum/spell/projectile/magic_missile category = "Defensive" /datum/spellbook_entry/timestop name = "Time Stop" - spell_type = /obj/effect/proc_holder/spell/aoe/conjure/timestop + spell_type = /datum/spell/aoe/conjure/timestop category = "Defensive" /datum/spellbook_entry/sacred_flame name = "Sacred Flame and Fire Immunity" - spell_type = /obj/effect/proc_holder/spell/sacred_flame + spell_type = /datum/spell/sacred_flame cost = 1 category = "Defensive" -/datum/spellbook_entry/sacred_flame/LearnSpell(mob/living/carbon/human/user, obj/item/spellbook/book, obj/effect/proc_holder/spell/newspell) +/datum/spellbook_entry/sacred_flame/LearnSpell(mob/living/carbon/human/user, obj/item/spellbook/book, datum/spell/newspell) to_chat(user, "You feel fireproof.") ADD_TRAIT(user, TRAIT_RESISTHEAT, MAGIC_TRAIT) ADD_TRAIT(user, TRAIT_RESISTHIGHPRESSURE, MAGIC_TRAIT) @@ -230,11 +230,11 @@ /datum/spellbook_entry/summon_supermatter name = "Summon Supermatter Crystal" - spell_type = /obj/effect/proc_holder/spell/aoe/conjure/summon_supermatter + spell_type = /datum/spell/aoe/conjure/summon_supermatter cost = 3 category = "Defensive" -/datum/spellbook_entry/summon_supermatter/LearnSpell(mob/living/carbon/human/user, obj/item/spellbook/book, obj/effect/proc_holder/spell/newspell) +/datum/spellbook_entry/summon_supermatter/LearnSpell(mob/living/carbon/human/user, obj/item/spellbook/book, datum/spell/newspell) to_chat(user, "You feel a little bit of supermatter enter your body.") ADD_TRAIT(user, TRAIT_RADIMMUNE, MAGIC_TRAIT) ADD_TRAIT(user, SM_HALLUCINATION_IMMUNE, MAGIC_TRAIT) @@ -249,64 +249,64 @@ //Mobility /datum/spellbook_entry/knock name = "Knock" - spell_type = /obj/effect/proc_holder/spell/aoe/knock + spell_type = /datum/spell/aoe/knock category = "Mobility" cost = 1 /datum/spellbook_entry/blink name = "Blink" - spell_type = /obj/effect/proc_holder/spell/turf_teleport/blink + spell_type = /datum/spell/turf_teleport/blink category = "Mobility" /datum/spellbook_entry/jaunt name = "Ethereal Jaunt" - spell_type = /obj/effect/proc_holder/spell/ethereal_jaunt + spell_type = /datum/spell/ethereal_jaunt category = "Mobility" /datum/spellbook_entry/spacetime_dist name = "Spacetime Distortion" - spell_type = /obj/effect/proc_holder/spell/spacetime_dist + spell_type = /datum/spell/spacetime_dist cost = 1 //Better defence than greater forcewall (maybe) but good luck hitting anyone, so 1 point. category = "Mobility" /datum/spellbook_entry/greaterknock name = "Greater Knock" - spell_type = /obj/effect/proc_holder/spell/aoe/knock/greater + spell_type = /datum/spell/aoe/knock/greater category = "Mobility" refundable = 0 //global effect on cast /datum/spellbook_entry/mindswap name = "Mindswap" - spell_type = /obj/effect/proc_holder/spell/mind_transfer + spell_type = /datum/spell/mind_transfer category = "Mobility" /datum/spellbook_entry/teleport name = "Teleport" - spell_type = /obj/effect/proc_holder/spell/area_teleport/teleport + spell_type = /datum/spell/area_teleport/teleport category = "Mobility" //Assistance /datum/spellbook_entry/charge name = "Charge" - spell_type = /obj/effect/proc_holder/spell/charge + spell_type = /datum/spell/charge category = "Assistance" cost = 1 /datum/spellbook_entry/summonitem name = "Summon Item" - spell_type = /obj/effect/proc_holder/spell/summonitem + spell_type = /datum/spell/summonitem category = "Assistance" cost = 1 /datum/spellbook_entry/disguiseself name = "Disguise Self" - spell_type = /obj/effect/proc_holder/spell/disguise_self + spell_type = /datum/spell/disguise_self category = "Assistance" cost = 1 /datum/spellbook_entry/noclothes name = "Remove Clothes Requirement" - spell_type = /obj/effect/proc_holder/spell/noclothes + spell_type = /datum/spell/noclothes category = "Assistance" cost = 1 @@ -433,7 +433,7 @@ /datum/spellbook_entry/item/soulstones/Buy(mob/living/carbon/human/user, obj/item/spellbook/book) . = ..() if(.) - user.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe/conjure/construct(null)) + user.mind.AddSpell(new /datum/spell/aoe/conjure/construct(null)) return . /datum/spellbook_entry/item/wands @@ -676,7 +676,7 @@ new path(B) user.put_in_hands(B) for(var/path in spells_path) - var/obj/effect/proc_holder/spell/S = new path() + var/datum/spell/S = new path() LearnSpell(user, book, S) OnBuy(user, book) return TRUE @@ -946,7 +946,7 @@ //Single Use Spellbooks /obj/item/spellbook/oneuse - var/spell = /obj/effect/proc_holder/spell/projectile/magic_missile //just a placeholder to avoid runtimes if someone spawned the generic + var/spell = /datum/spell/projectile/magic_missile //just a placeholder to avoid runtimes if someone spawned the generic var/spellname = "sandbox" var/used = FALSE name = "spellbook of " @@ -961,8 +961,8 @@ return /obj/item/spellbook/oneuse/attack_self(mob/user) - var/obj/effect/proc_holder/spell/S = new spell - for(var/obj/effect/proc_holder/spell/knownspell in user.mind.spell_list) + var/datum/spell/S = new spell + for(var/datum/spell/knownspell in user.mind.spell_list) if(knownspell.type == S.type) if(user.mind) if(user.mind.special_role == SPECIAL_ROLE_WIZARD_APPRENTICE || user.mind.special_role == SPECIAL_ROLE_WIZARD) @@ -990,7 +990,7 @@ return /obj/item/spellbook/oneuse/fireball - spell = /obj/effect/proc_holder/spell/fireball + spell = /datum/spell/fireball spellname = "fireball" icon_state = "bookfireball" desc = "This book feels warm to the touch." @@ -1001,7 +1001,7 @@ qdel(src) /obj/item/spellbook/oneuse/smoke - spell = /obj/effect/proc_holder/spell/smoke + spell = /datum/spell/smoke spellname = "smoke" icon_state = "booksmoke" desc = "This book is overflowing with the dank arts." @@ -1012,7 +1012,7 @@ user.adjust_nutrition(-200) /obj/item/spellbook/oneuse/blind - spell = /obj/effect/proc_holder/spell/trigger/blind + spell = /datum/spell/genetic/blind spellname = "blind" icon_state = "bookblind" desc = "This book looks blurry, no matter how you look at it." @@ -1025,7 +1025,7 @@ L.EyeBlind(20 SECONDS) /obj/item/spellbook/oneuse/mindswap - spell = /obj/effect/proc_holder/spell/mind_transfer + spell = /datum/spell/mind_transfer spellname = "mindswap" icon_state = "bookmindswap" desc = "This book's cover is pristine, though its pages look ragged and torn." @@ -1049,7 +1049,7 @@ to_chat(user, "You stare at the book some more, but there doesn't seem to be anything else to learn...") return - var/obj/effect/proc_holder/spell/mind_transfer/swapper = new + var/datum/spell/mind_transfer/swapper = new swapper.cast(user, stored_swap) to_chat(stored_swap, "You're suddenly somewhere else... and someone else?!") @@ -1057,7 +1057,7 @@ stored_swap = null /obj/item/spellbook/oneuse/forcewall - spell = /obj/effect/proc_holder/spell/forcewall + spell = /datum/spell/forcewall spellname = "forcewall" icon_state = "bookforcewall" desc = "This book has a dedication to mimes everywhere inside the front cover." @@ -1070,7 +1070,7 @@ user.drop_item() /obj/item/spellbook/oneuse/knock - spell = /obj/effect/proc_holder/spell/aoe/knock + spell = /datum/spell/aoe/knock spellname = "knock" icon_state = "bookknock" desc = "This book is hard to hold closed properly." @@ -1081,7 +1081,7 @@ user.Weaken(40 SECONDS) /obj/item/spellbook/oneuse/horsemask - spell = /obj/effect/proc_holder/spell/horsemask + spell = /datum/spell/horsemask spellname = "horses" icon_state = "bookhorses" desc = "This book is more horse than your mind has room for." @@ -1101,7 +1101,7 @@ to_chat(user, "I say thee neigh") /obj/item/spellbook/oneuse/charge - spell = /obj/effect/proc_holder/spell/charge + spell = /datum/spell/charge spellname = "charging" icon_state = "bookcharge" desc = "This book is made of 100% post-consumer wizard." @@ -1112,7 +1112,7 @@ empulse(src, 1, 1) /obj/item/spellbook/oneuse/summonitem - spell = /obj/effect/proc_holder/spell/summonitem + spell = /datum/spell/summonitem spellname = "instant summons" icon_state = "booksummons" desc = "This book is bright and garish, very hard to miss." @@ -1123,13 +1123,13 @@ qdel(src) /obj/item/spellbook/oneuse/fake_gib - spell = /obj/effect/proc_holder/spell/touch/fake_disintegrate + spell = /datum/spell/touch/fake_disintegrate spellname = "disintegrate" icon_state = "bookfireball" desc = "This book feels like it will rip stuff apart." /obj/item/spellbook/oneuse/sacredflame - spell = /obj/effect/proc_holder/spell/sacred_flame + spell = /datum/spell/sacred_flame spellname = "sacred flame" icon_state = "booksacredflame" desc = "Become one with the flames that burn within... and invite others to do so as well." diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm index 6c20df34f165..c0aacd4cf8ef 100644 --- a/code/game/gamemodes/wizard/wizard.dm +++ b/code/game/gamemodes/wizard/wizard.dm @@ -122,13 +122,13 @@ /mob/proc/spellremove() if(!mind) return - for(var/obj/effect/proc_holder/spell/spell_to_remove in mind.spell_list) + for(var/datum/spell/spell_to_remove in mind.spell_list) qdel(spell_to_remove) mind.spell_list -= spell_to_remove //To batch-remove mob spells. /mob/proc/mobspellremove() - for(var/obj/effect/proc_holder/spell/spell_to_remove in mob_spell_list) + for(var/datum/spell/spell_to_remove in mob_spell_list) qdel(spell_to_remove) mob_spell_list -= spell_to_remove diff --git a/code/game/gamemodes/wizard/wizloadouts.dm b/code/game/gamemodes/wizard/wizloadouts.dm index 836fb7b988be..8608d9132777 100644 --- a/code/game/gamemodes/wizard/wizloadouts.dm +++ b/code/game/gamemodes/wizard/wizloadouts.dm @@ -7,8 +7,8 @@ Ethereal Jaunt and Blink provide escape and mobility, while Magic Missile and Disintegrate can be used together for dangerous or key targets.
\ As this set lacks any form of healing or resurrection, healing items should be acquired from the station, and you should be careful to avoid being hurt in the first place.

\ Provides Mutate, Ethereal Jaunt, Blink, Magic Missile, and Disintegrate." - spells_path = list(/obj/effect/proc_holder/spell/genetic/mutate, /obj/effect/proc_holder/spell/ethereal_jaunt, /obj/effect/proc_holder/spell/turf_teleport/blink, \ - /obj/effect/proc_holder/spell/projectile/magic_missile, /obj/effect/proc_holder/spell/touch/disintegrate) + spells_path = list(/datum/spell/genetic/mutate, /datum/spell/ethereal_jaunt, /datum/spell/turf_teleport/blink, \ + /datum/spell/projectile/magic_missile, /datum/spell/touch/disintegrate) /datum/spellbook_entry/loadout/lich name = "Defense Focus - Lich" @@ -16,8 +16,8 @@ Ethereal Jaunt provides escape, Fireball and Rod Form are your offensive spells, and Disable Tech and Forcewall provides utility in disabling sec equipment or blocking their path.
\ Care should be taken in hiding the item you choose as your phylactery after using Bind Soul, as you cannot revive if it destroyed or too far from your body!

\
Provides Bind Soul, Ethereal Jaunt, Fireball, Rod Form, Disable Tech, and Greater Forcewall." - spells_path = list(/obj/effect/proc_holder/spell/lichdom, /obj/effect/proc_holder/spell/ethereal_jaunt, /obj/effect/proc_holder/spell/fireball, \ - /obj/effect/proc_holder/spell/rod_form, /obj/effect/proc_holder/spell/emplosion/disable_tech, /obj/effect/proc_holder/spell/forcewall) + spells_path = list(/datum/spell/lichdom, /datum/spell/ethereal_jaunt, /datum/spell/fireball, \ + /datum/spell/rod_form, /datum/spell/emplosion/disable_tech, /datum/spell/forcewall) is_ragin_restricted = TRUE /datum/spellbook_entry/loadout/wands @@ -27,8 +27,8 @@ Do not lose any of your wands to the station's crew, as they are extremely deadly even in their hands. Remember that the Revive wand can be used on yourself for a full heal!

\
Provides a Belt of Wands, Charge, Ethereal Jaunt, Blink, Repulse, and Disintegrate." items_path = list(/obj/item/storage/belt/wands/full) - spells_path = list(/obj/effect/proc_holder/spell/charge, /obj/effect/proc_holder/spell/ethereal_jaunt, /obj/effect/proc_holder/spell/turf_teleport/blink, \ - /obj/effect/proc_holder/spell/aoe/repulse, /obj/effect/proc_holder/spell/touch/disintegrate) + spells_path = list(/datum/spell/charge, /datum/spell/ethereal_jaunt, /datum/spell/turf_teleport/blink, \ + /datum/spell/aoe/repulse, /datum/spell/touch/disintegrate) //Unique loadouts, which are more gimmicky. Should contain some unique spell or item that separates it from just buying standard wiz spells, and be balanced around a 10 spell point cost. /datum/spellbook_entry/loadout/mimewiz @@ -37,14 +37,14 @@ Provides Finger Gun and Invisible Greater Wall manuals, Mime Robes, a Cane and Duct Tape, Ethereal Jaunt, Blink, Teleport, Mime Malaise, Knock, and Stop Time." items_path = list(/obj/item/spellbook/oneuse/mime/fingergun, /obj/item/spellbook/oneuse/mime/greaterwall, /obj/item/clothing/suit/wizrobe/mime, /obj/item/clothing/head/wizard/mime, \ /obj/item/clothing/mask/gas/mime/wizard, /obj/item/clothing/shoes/sandal/marisa, /obj/item/cane, /obj/item/stack/tape_roll) - spells_path = list(/obj/effect/proc_holder/spell/ethereal_jaunt, /obj/effect/proc_holder/spell/turf_teleport/blink, /obj/effect/proc_holder/spell/area_teleport/teleport, \ - /obj/effect/proc_holder/spell/touch/mime_malaise, /obj/effect/proc_holder/spell/aoe/knock, /obj/effect/proc_holder/spell/aoe/conjure/timestop) + spells_path = list(/datum/spell/ethereal_jaunt, /datum/spell/turf_teleport/blink, /datum/spell/area_teleport/teleport, \ + /datum/spell/touch/mime_malaise, /datum/spell/aoe/knock, /datum/spell/aoe/conjure/timestop) category = "Unique" destroy_spellbook = TRUE /datum/spellbook_entry/loadout/mimewiz/OnBuy(mob/living/carbon/human/user, obj/item/spellbook/book) if(user.mind) - user.mind.AddSpell(new /obj/effect/proc_holder/spell/mime/speak(null)) + user.mind.AddSpell(new /datum/spell/mime/speak(null)) user.mind.miming = TRUE /datum/spellbook_entry/loadout/gunreaper @@ -54,13 +54,13 @@ You will likely need to scavenge additional ammo or weapons aboard the station.

\
Provides a .357 Revolver, 4 speedloaders of ammo, Ethereal Jaunt, Blink, Summon Item, No Clothes, and Bind Soul, with a unique outfit." items_path = list(/obj/item/gun/projectile/revolver, /obj/item/ammo_box/a357, /obj/item/ammo_box/a357, /obj/item/ammo_box/a357, /obj/item/ammo_box/a357, /obj/item/clothing/under/syndicate) - spells_path = list(/obj/effect/proc_holder/spell/ethereal_jaunt, /obj/effect/proc_holder/spell/turf_teleport/blink, \ - /obj/effect/proc_holder/spell/summonitem, /obj/effect/proc_holder/spell/noclothes, /obj/effect/proc_holder/spell/lichdom/gunslinger) + spells_path = list(/datum/spell/ethereal_jaunt, /datum/spell/turf_teleport/blink, \ + /datum/spell/summonitem, /datum/spell/noclothes, /datum/spell/lichdom/gunslinger) category = "Unique" destroy_spellbook = TRUE is_ragin_restricted = TRUE -/obj/effect/proc_holder/spell/lichdom/gunslinger/equip_lich(mob/living/carbon/human/H) +/datum/spell/lichdom/gunslinger/equip_lich(mob/living/carbon/human/H) H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/det_suit(H), SLOT_HUD_OUTER_SUIT) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(H), SLOT_HUD_SHOES) H.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(H), SLOT_HUD_GLOVES) @@ -74,8 +74,8 @@ Provides His Grace, an Ancient Jumpsuit, an Assistant ID, a Gas Mask and Shoes, Insulated Gloves, a full Toolbelt, Ethereal Jaunt, Force Wall, Homing Toolbox, Knock and No Clothes." items_path = list(/obj/item/his_grace, /obj/item/clothing/under/color/grey/glorf, /obj/item/clothing/mask/gas, /obj/item/clothing/shoes/black, \ /obj/item/clothing/gloves/color/yellow, /obj/item/storage/belt/utility/full/multitool) - spells_path = list(/obj/effect/proc_holder/spell/ethereal_jaunt, /obj/effect/proc_holder/spell/forcewall, \ - /obj/effect/proc_holder/spell/aoe/knock, /obj/effect/proc_holder/spell/noclothes, /obj/effect/proc_holder/spell/fireball/toolbox) + spells_path = list(/datum/spell/ethereal_jaunt, /datum/spell/forcewall, \ + /datum/spell/aoe/knock, /datum/spell/noclothes, /datum/spell/fireball/toolbox) category = "Unique" destroy_spellbook = TRUE @@ -111,8 +111,8 @@ items_path = list(/obj/item/supermatter_halberd, /obj/item/clothing/gloves/color/white/supermatter_immune, \ /obj/item/clothing/suit/hooded/oblivion, /obj/item/clothing/mask/gas/voice_modulator/oblivion, /obj/item/tank/internals/emergency_oxygen/double, \ /obj/item/clothing/under/color/white/enforcer, /obj/item/clothing/shoes/white/enforcer) - spells_path = list(/obj/effect/proc_holder/spell/summonitem, /obj/effect/proc_holder/spell/charge_up/bounce/lightning, \ - /obj/effect/proc_holder/spell/aoe/conjure/summon_supermatter) + spells_path = list(/datum/spell/summonitem, /datum/spell/charge_up/bounce/lightning, \ + /datum/spell/aoe/conjure/summon_supermatter) category = "Unique" destroy_spellbook = TRUE @@ -125,7 +125,7 @@ name = "Fireball. Fireball. Fireball." desc = "Who cares about the rest of the spells. Become an expert in fire magic. Devote yourself to the craft. The only spell you need anyways is Fireball.
\
Provides fire immunity, homing fireballs, rapid-fire fireballs, and some fireball wands. Provides no mobility spells. Replaces your robes with infernal versions." - spells_path = list(/obj/effect/proc_holder/spell/sacred_flame, /obj/effect/proc_holder/spell/fireball/homing, /obj/effect/proc_holder/spell/infinite_guns/fireball) + spells_path = list(/datum/spell/sacred_flame, /datum/spell/fireball/homing, /datum/spell/infinite_guns/fireball) category = "Unique" destroy_spellbook = TRUE diff --git a/code/game/jobs/access.dm b/code/game/jobs/access.dm index 8f8ebaa110e6..560c136d45e3 100644 --- a/code/game/jobs/access.dm +++ b/code/game/jobs/access.dm @@ -246,7 +246,7 @@ if(ACCESS_CAPTAIN) return "Captain" if(ACCESS_ALL_PERSONAL_LOCKERS) - return "Personal Lockers" + return "Personal Lockers/Crates" if(ACCESS_CHAPEL_OFFICE) return "Chapel Office" if(ACCESS_TECH_STORAGE) diff --git a/code/game/jobs/job/support.dm b/code/game/jobs/job/support.dm index 5d636d988f33..820b12c9a101 100644 --- a/code/game/jobs/job/support.dm +++ b/code/game/jobs/job/support.dm @@ -420,8 +420,8 @@ return if(H.mind) - H.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe/conjure/build/mime_wall(null)) - H.mind.AddSpell(new /obj/effect/proc_holder/spell/mime/speak(null)) + H.mind.AddSpell(new /datum/spell/aoe/conjure/build/mime_wall(null)) + H.mind.AddSpell(new /datum/spell/mime/speak(null)) H.mind.miming = 1 qdel(H.GetComponent(/datum/component/footstep)) diff --git a/code/game/jobs/job/support_chaplain.dm b/code/game/jobs/job/support_chaplain.dm index 514e85bdc67b..f97ccfb5422b 100644 --- a/code/game/jobs/job/support_chaplain.dm +++ b/code/game/jobs/job/support_chaplain.dm @@ -79,7 +79,7 @@ B.deity_name = new_deity SSblackbox.record_feedback("text", "religion_deity", 1, "[new_deity]", 1) - user.AddSpell(new /obj/effect/proc_holder/spell/chaplain_bless(null)) + user.AddSpell(new /datum/spell/chaplain_bless(null)) if(SSticker) SSticker.Bible_deity_name = B.deity_name diff --git a/code/game/jobs/job_globals.dm b/code/game/jobs/job_globals.dm index 5f922af3975b..b469381bbfe9 100644 --- a/code/game/jobs/job_globals.dm +++ b/code/game/jobs/job_globals.dm @@ -55,8 +55,7 @@ GLOBAL_LIST_INIT(science_positions, list( "Roboticist", )) -//BS12 EDIT -GLOBAL_LIST_INIT(support_positions, list( +GLOBAL_LIST_INIT(service_positions, list( "Head of Personnel", "Bartender", "Botanist", @@ -76,8 +75,6 @@ GLOBAL_LIST_INIT(supply_positions, list( "Shaft Miner" )) -GLOBAL_LIST_INIT(service_positions, (list("Head of Personnel") + (support_positions - supply_positions))) - /// Roles that include any semblence of security, mostly for jobbans GLOBAL_LIST_INIT(security_positions, list( "Head of Security", @@ -133,7 +130,7 @@ GLOBAL_LIST_INIT(nonhuman_positions, list( GLOBAL_LIST_INIT(exp_jobsmap, list( EXP_TYPE_LIVING = list(), // all living mobs - EXP_TYPE_CREW = list(titles = command_positions | engineering_positions | medical_positions | science_positions | support_positions | supply_positions | security_positions | assistant_positions | list("AI","Cyborg")), // crew positions + EXP_TYPE_CREW = list(titles = command_positions | engineering_positions | medical_positions | science_positions | service_positions | supply_positions | security_positions | assistant_positions | list("AI","Cyborg")), // crew positions EXP_TYPE_SPECIAL = list(), // antags, ERT, etc EXP_TYPE_GHOST = list(), // dead people, observers EXP_TYPE_COMMAND = list(titles = command_head_positions), diff --git a/code/game/machinery/clonepod.dm b/code/game/machinery/clonepod.dm index 050b7b816e76..9dad2b6ea368 100644 --- a/code/game/machinery/clonepod.dm +++ b/code/game/machinery/clonepod.dm @@ -385,7 +385,7 @@ return FALSE clone.forceMove(loc) - new /obj/effect/gibspawner/generic(get_turf(src), clone) + new /obj/effect/gibspawner/generic(get_turf(src), clone.dna) playsound(loc, 'sound/effects/splat.ogg', 50, TRUE) var/datum/mind/patient_mind = locateUID(patient_data.mindUID) diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm index 63f3814b358f..ba6682cb042d 100644 --- a/code/game/machinery/requests_console.dm +++ b/code/game/machinery/requests_console.dm @@ -8,17 +8,18 @@ #define RC_INFO (1<<2) //Relay Info //Request Console Screens -#define RCS_MAINMENU 0 // Main menu -#define RCS_RQSUPPLY 1 // Request supplies -#define RCS_RQASSIST 2 // Request assistance -#define RCS_SENDINFO 3 // Relay information -#define RCS_SENTPASS 4 // Message sent successfully -#define RCS_SENTFAIL 5 // Message sent unsuccessfully -#define RCS_VIEWMSGS 6 // View messages -#define RCS_MESSAUTH 7 // Authentication before sending -#define RCS_ANNOUNCE 8 // Send announcement -#define RCS_SHIPPING 9 // Print Shipping Labels/Packages -#define RCS_SHIP_LOG 10 // View Shipping Label Log +#define RCS_MAINMENU 0 // Main menu +#define RCS_RQSUPPLY 1 // Request supplies +#define RCS_RQASSIST 2 // Request assistance +#define RCS_SENDINFO 3 // Relay information +#define RCS_SENTPASS 4 // Message sent successfully +#define RCS_SENTFAIL 5 // Message sent unsuccessfully +#define RCS_VIEWMSGS 6 // View messages +#define RCS_MESSAUTH 7 // Authentication before sending +#define RCS_ANNOUNCE 8 // Send announcement +#define RCS_SHIPPING 9 // Print Shipping Labels/Packages +#define RCS_SHIP_LOG 10 // View Shipping Label Log +#define RCS_SECONDARY 11 // Request secodary goal //Radio list. For a console to announce messages on a specific radio, it's "department" variable must be in the list below. #define ENGI_ROLES list("Atmospherics", "Engineering", "Chief Engineer's Desk") @@ -51,21 +52,28 @@ GLOBAL_LIST_EMPTY(allRequestConsoles) var/announcementConsole = FALSE // FALSE = This console cannot be used to send department announcements // TRUE = This console can send department announcementsf - var/announceAuth = 0 //Will be set to 1 when you authenticate yourself for announcements - var/msgVerified = "" //Will contain the name of the person who varified it - var/msgStamped = "" //If a message is stamped, this will contain the stamp name + /// Will be set to TRUE when you authenticate yourself for announcements + var/announceAuth = FALSE + /// Will be set to TRUE when you authenticate yourself for requesting a secondary goal + var/secondaryGoalAuth = FALSE + /// Will contain the name of the person who verified it + var/msgVerified = "Not verified" + /// If a message is stamped, this will contain the stamp name + var/msgStamped = "Not stamped" var/message = "" var/recipient = ""; //the department which will be receiving the message var/priority = -1 ; //Priority of the message being sent light_range = 0 var/datum/announcer/announcer = new(config_type = /datum/announcement_configuration/requests_console) + /// The ID card of the person requesting a secondary goal. + var/goalRequester var/list/shipping_log = list() var/ship_tag_name = "" var/ship_tag_index = 0 var/print_cooldown = 0 //cooldown on shipping label printer, stores the in-game time of when the printer will next be ready var/obj/item/radio/Radio - var/radiochannel = "" var/reminder_timer_id = TIMER_ID_NULL + var/has_active_secondary_goal = FALSE /obj/machinery/requests_console/power_change() if(!..()) @@ -168,6 +176,8 @@ GLOBAL_LIST_EMPTY(allRequestConsoles) data["msgStamped"] = msgStamped data["msgVerified"] = msgVerified data["announceAuth"] = announceAuth + data["secondaryGoalAuth"] = secondaryGoalAuth + data["secondaryGoalEnabled"] = !has_active_secondary_goal data["shipDest"] = ship_tag_name data["shipping_log"] = shipping_log @@ -213,58 +223,34 @@ GLOBAL_LIST_EMPTY(allRequestConsoles) announcer.Announce(message) reset_message(TRUE) - if("department") - if(!message) + if("requestSecondaryGoal") + has_active_secondary_goal = check_for_active_secondary_goal(goalRequester) + if(has_active_secondary_goal || !secondaryGoalAuth) return - var/log_msg = message - var/pass = FALSE - screen = RCS_SENTFAIL - for(var/M in GLOB.message_servers) - var/obj/machinery/message_server/MS = M - if(!MS.active) - continue - MS.send_rc_message(ckey(params["department"]), department, log_msg, msgStamped, msgVerified, priority) - pass = TRUE - if(pass) + generate_secondary_goal(department, goalRequester, usr) + reset_message(FALSE) + view_messages() + screen = RCS_VIEWMSGS + + if("department") + if(send_requests_console_message(message, department, recipient, msgStamped, msgVerified, priority, Radio)) screen = RCS_SENTPASS - if(recipient in ENGI_ROLES) - radiochannel = "Engineering" - else if(recipient in SEC_ROLES) - radiochannel = "Security" - else if(recipient in MISC_ROLES) - radiochannel = "Service" - else if(recipient in MED_ROLES) - radiochannel = "Medical" - else if(recipient in COM_ROLES) - radiochannel = "Command" - else if(recipient in SCI_ROLES) - radiochannel = "Science" - else if(recipient == "AI") - radiochannel = "AI Private" - else if(recipient in SUPPLY_ROLES) - radiochannel = "Supply" - message_log.Add(list(list("Message sent to [recipient] at [station_time_timestamp()]", "[message]"))) - Radio.autosay("Alert; a new message has been received from [department]", "[recipient] Requests Console", "[radiochannel]") else + screen = RCS_SENTFAIL atom_say("No server detected!") //Handle screen switching if("setScreen") // Ensures screen cant be set higher or lower than it should be - var/tempScreen = round(clamp(text2num(params["setScreen"]), 0, 10), 1) + var/tempScreen = round(clamp(text2num(params["setScreen"]), 0, 11), 1) if(tempScreen == RCS_ANNOUNCE && !announcementConsole) return if(tempScreen == RCS_VIEWMSGS) - for(var/obj/machinery/requests_console/Console in GLOB.allRequestConsoles) - if(Console.department == department) - Console.newmessagepriority = RQ_NONEW_MESSAGES - Console.update_icon(UPDATE_OVERLAYS) - Console.set_light(1) - if(reminder_timer_id != TIMER_ID_NULL) - deltimer(reminder_timer_id) - reminder_timer_id = TIMER_ID_NULL + view_messages() if(tempScreen == RCS_MAINMENU) reset_message() + if(tempScreen == RCS_SECONDARY) + has_active_secondary_goal = check_for_active_secondary_goal(goalRequester) screen = tempScreen if("shipSelect") @@ -303,12 +289,18 @@ GLOBAL_LIST_EMPTY(allRequestConsoles) if(screen == RCS_ANNOUNCE) var/obj/item/card/id/ID = I if(ACCESS_RC_ANNOUNCE in ID.GetAccess()) - announceAuth = 1 + announceAuth = TRUE announcer.author = ID.assignment ? "[ID.assignment] [ID.registered_name]" : ID.registered_name else reset_message() to_chat(user, "You are not authorized to send announcements.") SStgui.update_uis(src) + if(screen == RCS_SECONDARY) + var/obj/item/card/id/ID = I + if(ID) + secondaryGoalAuth = TRUE + goalRequester = ID + has_active_secondary_goal = check_for_active_secondary_goal(goalRequester) if(screen == RCS_SHIPPING) var/obj/item/card/id/T = I msgVerified = "Sender verified as [T.registered_name] ([T.assignment])" @@ -327,16 +319,18 @@ GLOBAL_LIST_EMPTY(allRequestConsoles) message = "" recipient = "" priority = RQ_NONEW_MESSAGES - msgVerified = "" - msgStamped = "" + msgVerified = "Not verified" + msgStamped = "Not stamped" announceAuth = FALSE + secondaryGoalAuth = FALSE announcer.author = "" + goalRequester = "" ship_tag_name = "" ship_tag_index = FALSE if(mainmenu) screen = RCS_MAINMENU -/obj/machinery/requests_console/proc/createMessage(source, title, message, priority, forced = FALSE) +/obj/machinery/requests_console/proc/createMessage(source, title, message, priority, forced = FALSE, verified = "", stamped = "") var/linkedSender if(inoperable() && !forced) message_log.Add(list(list("Message lost due to console failure. Please contact [station_name()]'s system administrator or AI for technical assistance."))) @@ -357,9 +351,9 @@ GLOBAL_LIST_EMPTY(allRequestConsoles) switch(priority) if(RQ_HIGHPRIORITY) // High - message_log.Add(list(list("High Priority - From: [linkedSender]", message))) // List in a list for passing into TGUI + message_log.Add(list(list("High Priority - From: [linkedSender]") + message + list(verified, stamped))) // List in a list for passing into TGUI else // Normal - message_log.Add(list(list("From: [linkedSender]", message))) // List in a list for passing into TGUI + message_log.Add(list(list("From: [linkedSender]") + message + list(verified, stamped))) // List in a list for passing into TGUI set_light(2) /obj/machinery/requests_console/proc/remind_unread_messages() @@ -379,6 +373,62 @@ GLOBAL_LIST_EMPTY(allRequestConsoles) sp.update_desc() print_cooldown = world.time + 600 //1 minute cooldown before you can print another label, but you can still configure the next one during this time +/obj/machinery/requests_console/proc/view_messages() + for(var/obj/machinery/requests_console/Console in GLOB.allRequestConsoles) + if(Console.department == department) + Console.newmessagepriority = RQ_NONEW_MESSAGES + Console.update_icon(UPDATE_OVERLAYS) + Console.set_light(1) + if(reminder_timer_id != TIMER_ID_NULL) + deltimer(reminder_timer_id) + reminder_timer_id = TIMER_ID_NULL + +/obj/machinery/requests_console/proc/check_for_active_secondary_goal(obj/item/card/id/id) + if(!istype(id)) + return FALSE + for(var/datum/station_goal/secondary/goal in SSticker.mode.secondary_goals) + if(goal.requester_name == id.registered_name && !goal.completed) + return TRUE + return FALSE + +/proc/send_requests_console_message(message, sender, recipient, stamped, verified, priority, obj/item/radio/radio) + if(!message) + return + var/found_message_server = FALSE + for(var/M in GLOB.message_servers) + var/obj/machinery/message_server/MS = M + if(!MS.active) + continue + MS.send_rc_message(ckey(recipient), sender, message, stamped, verified, priority) + found_message_server = TRUE + + if(!found_message_server) + return FALSE + + if(!radio) + return TRUE + + var/radiochannel = "" + if(recipient in ENGI_ROLES) + radiochannel = "Engineering" + else if(recipient in SEC_ROLES) + radiochannel = "Security" + else if(recipient in MISC_ROLES) + radiochannel = "Service" + else if(recipient in MED_ROLES) + radiochannel = "Medical" + else if(recipient in COM_ROLES) + radiochannel = "Command" + else if(recipient in SCI_ROLES) + radiochannel = "Science" + else if(recipient == "AI") + radiochannel = "AI Private" + else if(recipient in SUPPLY_ROLES) + radiochannel = "Supply" + radio.autosay("Alert; a new message has been received from [sender]", "[recipient] Requests Console", "[radiochannel]") + + return TRUE + #undef RC_ASSIST #undef RC_SUPPLY #undef RC_INFO @@ -393,6 +443,7 @@ GLOBAL_LIST_EMPTY(allRequestConsoles) #undef RCS_ANNOUNCE #undef RCS_SHIPPING #undef RCS_SHIP_LOG +#undef RCS_SECONDARY #undef ENGI_ROLES #undef SEC_ROLES #undef MISC_ROLES diff --git a/code/game/objects/items/granters/_granters.dm b/code/game/objects/items/granters/_granters.dm index cd1c4fa196c3..6978f29064c8 100644 --- a/code/game/objects/items/granters/_granters.dm +++ b/code/game/objects/items/granters/_granters.dm @@ -108,7 +108,7 @@ // Generic action giver /obj/item/book/granter/spell /// The typepath of spell that is given - var/obj/effect/proc_holder/spell/granted_spell + var/datum/spell/granted_spell /// The name of the spell, formatted in a more text-friendly way var/spell_name = "" diff --git a/code/game/objects/items/granters/action_granters/summon_cheese.dm b/code/game/objects/items/granters/action_granters/summon_cheese.dm index 62645a34def7..f86c89c86364 100644 --- a/code/game/objects/items/granters/action_granters/summon_cheese.dm +++ b/code/game/objects/items/granters/action_granters/summon_cheese.dm @@ -3,7 +3,7 @@ desc = "Wonderful! Time for a celebration... Cheese for everyone!" icon_state = "cheese_book" spell_name = "summon cheese" - granted_spell = /obj/effect/proc_holder/spell/aoe/conjure/summon_cheese + granted_spell = /datum/spell/aoe/conjure/summon_cheese remarks = list( "Always forward, never back...", "Are these pages... cheese slices?..", @@ -27,7 +27,7 @@ user.put_in_hands(book_cheese) qdel(src) -/obj/effect/proc_holder/spell/aoe/conjure/summon_cheese +/datum/spell/aoe/conjure/summon_cheese name = "Summon Cheese" desc = "Summon cheesy goodness around you!" base_cooldown = 1 MINUTES diff --git a/code/game/objects/items/stacks/medical_packs.dm b/code/game/objects/items/stacks/medical_packs.dm index 4680b1f9a1cc..92d5ffed73fa 100644 --- a/code/game/objects/items/stacks/medical_packs.dm +++ b/code/game/objects/items/stacks/medical_packs.dm @@ -155,20 +155,20 @@ if(ishuman(M)) var/mob/living/carbon/human/H = M var/obj/item/organ/external/affecting = H.get_organ(user.zone_selected) + for(var/obj/item/organ/external/E in H.bodyparts) + if(E.open == ORGAN_ORGANIC_OPEN) + to_chat(user, "[E] is cut open, you'll need more than a bandage!") + return + affecting.germ_level = 0 - if(affecting.open == ORGAN_CLOSED) - affecting.germ_level = 0 + if(stop_bleeding) + if(!H.bleedsuppress) //so you can't stack bleed suppression + H.suppress_bloodloss(stop_bleeding) - if(stop_bleeding) - if(!H.bleedsuppress) //so you can't stack bleed suppression - H.suppress_bloodloss(stop_bleeding) - - heal(H, user) + heal(H, user) - H.UpdateDamageIcon() - use(1) - else - to_chat(user, "[affecting] is cut open, you'll need more than a bandage!") + H.UpdateDamageIcon() + use(1) /obj/item/stack/medical/bruise_pack/improvised name = "improvised gauze" diff --git a/code/game/objects/items/weapons/bio_chips/bio_chip_adrenalin.dm b/code/game/objects/items/weapons/bio_chips/bio_chip_adrenalin.dm index 7623f39ed668..67e06aad5990 100644 --- a/code/game/objects/items/weapons/bio_chips/bio_chip_adrenalin.dm +++ b/code/game/objects/items/weapons/bio_chips/bio_chip_adrenalin.dm @@ -32,3 +32,35 @@ name = "bio-chip case - 'Adrenaline'" desc = "A glass case containing an adrenaline bio-chip." implant_type = /obj/item/bio_chip/adrenalin + +/obj/item/bio_chip/proto_adrenalin + name = "proto-adrenal bio-chip" + desc = "Removes all stuns and knockdowns." + icon_state = "adrenal" + origin_tech = "materials=2;biotech=4;combat=3;syndicate=2" + uses = 1 + implant_data = /datum/implant_fluff/proto_adrenaline + implant_state = "implant-syndicate" + +/obj/item/bio_chip/proto_adrenalin/activate() + uses-- + to_chat(imp_in, "You feel a sudden surge of energy!") + imp_in.SetStunned(0) + imp_in.SetWeakened(0) + imp_in.SetKnockDown(0) + imp_in.SetParalysis(0) + imp_in.setStaminaLoss(0) //Since it doesn't have a good followup like adrenals, and getting batoned the moment after triggering it will stamina crit you, will set to zero over - 75 + imp_in.stand_up(TRUE) + SEND_SIGNAL(imp_in, COMSIG_LIVING_CLEAR_STUNS) + imp_in.reagents.add_reagent("stimulative_cling", 1) + if(!uses) + qdel(src) + +/obj/item/bio_chip_implanter/proto_adrenalin + name = "bio-chip implanter (proto-adrenalin)" + implant_type = /obj/item/bio_chip/proto_adrenalin + +/obj/item/bio_chip_case/proto_adrenalin + name = "bio-chip case - 'proto-adrenalin'" + desc = "A glass case containing an proto-adrenalin bio-chip." + implant_type = /obj/item/bio_chip/proto_adrenalin diff --git a/code/game/objects/items/weapons/bio_chips/bio_chip_fluff.dm b/code/game/objects/items/weapons/bio_chips/bio_chip_fluff.dm index 336f74465d1e..96f4de6aa72e 100644 --- a/code/game/objects/items/weapons/bio_chips/bio_chip_fluff.dm +++ b/code/game/objects/items/weapons/bio_chips/bio_chip_fluff.dm @@ -22,6 +22,12 @@ notes = "One of Cybersun Industries oldest and simplest implants, even in its simplicity it is rumoured to be one of Cybersun Industries best-selling products." function = "Subjects injected with this bio-chip can activate an injection of medical cocktails that removes stuns, increases speed, and has mild healing effects." +/datum/implant_fluff/proto_adrenaline + name = "Cybersun Industries FX-1 Proto-Adrenaline Bio-chip" + life = "Destroyed after 1 use." + notes = "Originally developed as part of Cybersun's medical line for preventing high-G sickness during space travel, but today it is sold for less legal uses." + function = "Subjects injected with this bio-chip can activate an injection of medical cocktails that gets them back up on their feet." + /datum/implant_fluff/supercharge name = "Cybersun Industries RX-4 Synthetic Supercharge Bio-chip" life = "Known to last for up to a year." diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm index aa53d533db2a..64940e3e2d6d 100644 --- a/code/game/objects/items/weapons/cards_ids.dm +++ b/code/game/objects/items/weapons/cards_ids.dm @@ -512,7 +512,7 @@ "Medical" = GLOB.medical_positions, "Science" = GLOB.science_positions, "Security" = GLOB.security_positions, - "Support" = GLOB.support_positions, + "Service" = GLOB.service_positions, "Supply" = GLOB.supply_positions, "Command" = GLOB.command_positions, "Custom" = null, diff --git a/code/game/objects/items/weapons/dice.dm b/code/game/objects/items/weapons/dice.dm index d3495458b8f5..f5679c0ad1ef 100644 --- a/code/game/objects/items/weapons/dice.dm +++ b/code/game/objects/items/weapons/dice.dm @@ -302,7 +302,7 @@ dust_if_respawnable(C) to_chat(H, "You are a servant of [user.real_name]. You must do everything in your power to follow their orders.") - var/obj/effect/proc_holder/spell/summonmob/S = new + var/datum/spell/summonmob/S = new S.target_mob = H user.mind.AddSpell(S) if(17) diff --git a/code/game/objects/items/weapons/powerfist.dm b/code/game/objects/items/weapons/powerfist.dm index 87f48d7b799a..c2b33e300830 100644 --- a/code/game/objects/items/weapons/powerfist.dm +++ b/code/game/objects/items/weapons/powerfist.dm @@ -31,6 +31,9 @@ /obj/item/melee/powerfist/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/tank/internals)) + if(!iscarbon(loc)) + to_chat(user, "You have to hold the powerfist in your hand!") + return if(!tank) var/obj/item/tank/internals/IT = W if(IT.volume <= 3) diff --git a/code/game/objects/items/weapons/soap.dm b/code/game/objects/items/weapons/soap.dm index 5a23face976d..e7c486d5a40d 100644 --- a/code/game/objects/items/weapons/soap.dm +++ b/code/game/objects/items/weapons/soap.dm @@ -102,7 +102,7 @@ return /obj/item/soap/deluxe - desc = "A deluxe Waffle Co. brand bar of soap. Smells of comdoms." + desc = "A luxury bar of soap. Smells of honey." icon_state = "soapdeluxe" cleanspeed = 40 //slightly better because deluxe -- captain gets one of these diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm index 8d5fcf7c5c3c..e6aa76550813 100644 --- a/code/game/objects/items/weapons/weaponry.dm +++ b/code/game/objects/items/weapons/weaponry.dm @@ -28,10 +28,10 @@ /obj/item/sord name = "\improper SORD" desc = "This thing is so unspeakably shitty you are having a hard time even holding it." + icon = 'icons/obj/weapons/magical_weapons.dmi' + icon_state = "sord" lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons_righthand.dmi' - icon_state = "sord" - item_state = "sord" slot_flags = SLOT_FLAG_BELT force = 2 throwforce = 1 diff --git a/code/game/objects/structures/crates_lockers/closets/secure/miscjobs.dm b/code/game/objects/structures/crates_lockers/closets/secure/miscjobs.dm index ee2c5e262ea6..abcc17d19198 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/miscjobs.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/miscjobs.dm @@ -29,6 +29,9 @@ req_access = list(ACCESS_MIME) icon_state = "mime" open_door_sprite = "mime_door" + // It's silent! + open_sound = null + close_sound = null /obj/structure/closet/secure_closet/mime/populate_contents() new /obj/item/clothing/head/beret(src) diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index d2d3050e71f9..361d4d9fbd66 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -281,6 +281,58 @@ req_access += pick(get_all_accesses()) ..() +/obj/structure/closet/crate/secure/personal + name = "personal crate" + desc = "The crate version of Nanotrasen's famous personal locker, ideal for shipping booze, food, or drugs to CC without letting Cargo consume it. This one has not been configured by CC, and the first card swiped gains control." + req_access = list(ACCESS_ALL_PERSONAL_LOCKERS) + /// The name of the person this crate is registered to. + var/registered_name = null + // Unlike most secure crates, personal crates are easily obtained. + crate_value = DEFAULT_CRATE_VALUE + +/obj/structure/closet/crate/secure/personal/allowed(mob/user) + if(..()) + return TRUE + var/obj/item/card/id/id = user.get_id_card() + if(is_usable_id(id)) + return id.registered_name == registered_name + return FALSE + +/// Returns whether the object is a usable ID card (not guest pass, has name). +/obj/structure/closet/crate/secure/personal/proc/is_usable_id(obj/item/card/id/id) + if(!istype(id)) + return FALSE + if(istype(id, /obj/item/card/id/guest) || !id.registered_name) + return FALSE + return TRUE + +/obj/structure/closet/crate/secure/personal/attackby(obj/item/I, mob/user, params) + if(opened || !istype(I, /obj/item/card/id)) + return ..() + + if(broken) + to_chat(user, "It appears to be broken.") + return FALSE + + var/obj/item/card/id/id = I + if(!is_usable_id(id)) + to_chat(user, "Invalid identification card.") + return FALSE + + if(registered_name && allowed(user)) + return ..() + + if(!registered_name) + registered_name = id.registered_name + desc = "Owned by [id.registered_name]." + to_chat(user, "Crate reserved") + return TRUE + + if(registered_name == id.registered_name) + return ..() + + return FALSE + /obj/structure/closet/crate/plastic name = "plastic crate" desc = "A rectangular plastic crate." diff --git a/code/game/objects/structures/grey_autocloner.dm b/code/game/objects/structures/grey_autocloner.dm index 5178e6eadcfe..d2bba365c31d 100644 --- a/code/game/objects/structures/grey_autocloner.dm +++ b/code/game/objects/structures/grey_autocloner.dm @@ -65,7 +65,7 @@ H.dna = R.dna.Clone() - H.set_species(/datum/species/grey) //This is a grey cloner after all. Funnier this way tbh + H.set_species(/datum/species/grey, skip_same_check = TRUE) //This is a grey cloner after all. Funnier this way tbh for(var/datum/language/L in R.languages) H.add_language(L.name) diff --git a/code/game/shuttle_engines.dm b/code/game/shuttle_engines.dm index 86ca6f8468b9..9f0325ba7f57 100644 --- a/code/game/shuttle_engines.dm +++ b/code/game/shuttle_engines.dm @@ -5,9 +5,6 @@ max_integrity = 500 armor = list(melee = 100, bullet = 10, laser = 10, energy = 0, bomb = 0, rad = 0, fire = 50, acid = 70) //default + ignores melee -/obj/structure/shuttle/shuttleRotate(rotation) - return //This override is needed to properly rotate the object when on a shuttle that is rotated. - /obj/structure/shuttle/engine name = "engine" density = TRUE diff --git a/code/game/turfs/simulated/minerals.dm b/code/game/turfs/simulated/minerals.dm index c221da9adcf2..232389712800 100644 --- a/code/game/turfs/simulated/minerals.dm +++ b/code/game/turfs/simulated/minerals.dm @@ -306,9 +306,16 @@ mineralChance = 10 mineralSpawnChanceList = list( - /turf/simulated/mineral/uranium/volcanic = 5, /turf/simulated/mineral/diamond/volcanic = 1, /turf/simulated/mineral/gold/volcanic = 10, /turf/simulated/mineral/titanium/volcanic = 11, - /turf/simulated/mineral/silver/volcanic = 12, /turf/simulated/mineral/plasma/volcanic = 20, /turf/simulated/mineral/iron/volcanic = 40, - /turf/simulated/mineral/gibtonite/volcanic = 4, /turf/simulated/floor/plating/asteroid/airless/cave/volcanic = 1, /turf/simulated/mineral/bscrystal/volcanic = 1) + /turf/simulated/mineral/uranium/volcanic = 5, + /turf/simulated/mineral/diamond/volcanic = 1, + /turf/simulated/mineral/gold/volcanic = 10, + /turf/simulated/mineral/titanium/volcanic = 11, + /turf/simulated/mineral/silver/volcanic = 12, + /turf/simulated/mineral/plasma/volcanic = 20, + /turf/simulated/mineral/iron/volcanic = 40, + /turf/simulated/mineral/gibtonite/volcanic = 4, + /turf/simulated/mineral/bscrystal/volcanic = 1 + ) /turf/simulated/mineral/random/labormineral mineralSpawnChanceList = list( diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 8cf86712c077..c1e98e501944 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -571,10 +571,10 @@ GLOBAL_LIST_INIT(view_runtimes_verbs, list( return var/list/spell_list = list() - var/type_length = length("/obj/effect/proc_holder/spell") + 2 + var/type_length = length("/datum/spell") + 2 for(var/A in GLOB.spells) spell_list[copytext("[A]", type_length)] = A - var/obj/effect/proc_holder/spell/S = input("Choose the spell to give to that guy", "ABRAKADABRA") as null|anything in spell_list + var/datum/spell/S = input("Choose the spell to give to that guy", "ABRAKADABRA") as null|anything in spell_list if(!S) return S = spell_list[S] diff --git a/code/modules/admin/db_ban/functions.dm b/code/modules/admin/db_ban/functions.dm index ee6b850f2c81..7d42d9005781 100644 --- a/code/modules/admin/db_ban/functions.dm +++ b/code/modules/admin/db_ban/functions.dm @@ -160,10 +160,10 @@ "rounds" = (rounds ? "[rounds]" : "0"), // And here "ckey" = ckey, "computerid" = computerid, - "ip" = ip, + "ip" = "[ip ? ip : ""]", // This is important. NULL is not the same as "", and if you directly open the `.dmb` file, you get a NULL IP. "a_ckey" = a_ckey, "a_computerid" = a_computerid, - "a_ip" = a_ip, + "a_ip" = "[a_ip ? a_ip : ""]", "who" = who, "adminwho" = adminwho, "roundid" = GLOB.round_id, @@ -490,7 +490,7 @@ output += "" for(var/j in GLOB.other_roles) output += "" - for(var/j in list("commanddept","securitydept","engineeringdept","medicaldept","sciencedept","supportdept","nonhumandept")) + for(var/j in list("commanddept","securitydept","engineeringdept","medicaldept","sciencedept","servicedept","nonhumandept")) output += "" for(var/j in list("Syndicate") + GLOB.antag_roles) output += "" diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index c9538c22c093..d70c4ab8ae12 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -161,7 +161,7 @@ message_admins("Ban process: A mob matching [playermob.ckey] was found at location [playermob.x], [playermob.y], [playermob.z]. Custom IP and computer id fields replaced with the IP and computer id from the located mob") if(job_ban) - if(banjob in list("commanddept","securitydept","engineeringdept","medicaldept","sciencedept","supportdept","nonhumandept")) + if(banjob in list("commanddept","securitydept","engineeringdept","medicaldept","sciencedept","servicedept","supplydept","nonhumandept")) multi_job = TRUE switch(banjob) if("commanddept") @@ -194,8 +194,14 @@ var/datum/job/temp = SSjobs.GetJob(jobPos) if(!temp) continue jobs_to_ban += temp.title - if("supportdept") - for(var/jobPos in GLOB.support_positions) + if("servicedept") + for(var/jobPos in GLOB.service_positions) + if(!jobPos) continue + var/datum/job/temp = SSjobs.GetJob(jobPos) + if(!temp) continue + jobs_to_ban += temp.title + if("supplydept") + for(var/jobPos in GLOB.supply_positions) if(!jobPos) continue var/datum/job/temp = SSjobs.GetJob(jobPos) if(!temp) continue @@ -553,11 +559,32 @@ counter = 0 jobs += "" - //Support (Grey) + //Service (Grey) counter = 0 jobs += "" - jobs += "" - for(var/jobPos in GLOB.support_positions) + jobs += "" + for(var/jobPos in GLOB.service_positions) + if(!jobPos) continue + var/datum/job/job = SSjobs.GetJob(jobPos) + if(!job) continue + + if(jobban_isbanned(M, job.title)) + jobs += "" + counter++ + else + jobs += "" + counter++ + + if(counter >= 5) //So things dont get squiiiiished! + jobs += "" + counter = 0 + jobs += "
Support Positions
Service Positions
[replacetext(job.title, " ", " ")][replacetext(job.title, " ", " ")]
" + + //Supply (Brown) + counter = 0 + jobs += "" + jobs += "" + for(var/jobPos in GLOB.supply_positions) if(!jobPos) continue var/datum/job/job = SSjobs.GetJob(jobPos) if(!job) continue @@ -668,7 +695,7 @@ to_chat(usr, "SSjobs has not been setup!") return - //get jobs for department if specified, otherwise just returnt he one job in a list. + //get jobs for department if specified, otherwise just return the one job in a list. var/list/joblist = list() switch(href_list["jobban3"]) if("commanddept") @@ -701,8 +728,14 @@ var/datum/job/temp = SSjobs.GetJob(jobPos) if(!temp) continue joblist += temp.title - if("supportdept") - for(var/jobPos in GLOB.support_positions) + if("servicedept") + for(var/jobPos in GLOB.service_positions) + if(!jobPos) continue + var/datum/job/temp = SSjobs.GetJob(jobPos) + if(!temp) continue + joblist += temp.title + if("supplydept") + for(var/jobPos in GLOB.supply_positions) if(!jobPos) continue var/datum/job/temp = SSjobs.GetJob(jobPos) if(!temp) continue @@ -1695,13 +1728,16 @@ SStickets.resolveTicket(index) else if(href_list["autorespond"]) + var/datum/controller/subsystem/tickets/ticketSystem if(href_list["is_mhelp"]) - to_chat(usr, "Auto responses are not available for mentor helps.") + ticketSystem = SSmentor_tickets + else //Ahelp + ticketSystem = SStickets + + if(!check_rights(ticketSystem.rights_needed)) return var/index = text2num(href_list["autorespond"]) - if(!check_rights(R_ADMIN|R_MOD)) - return - SStickets.autoRespond(index) + ticketSystem.autoRespond(index) if(href_list["convert_ticket"]) var/indexNum = text2num(href_list["convert_ticket"]) @@ -3281,7 +3317,7 @@ else if(href_list["add_station_goal"]) if(!check_rights(R_EVENT)) return - var/list/type_choices = typesof(/datum/station_goal) + var/list/type_choices = typesof(/datum/station_goal) - typesof(/datum/station_goal/secondary) var/picked = input("Choose goal type") in type_choices|null if(!picked) return @@ -3299,6 +3335,46 @@ SSticker.mode.station_goals += G modify_goals() + else if(href_list["add_secondary_goal"]) + if(!check_rights(R_EVENT)) + return + var/list/type_choices = typesof(/datum/station_goal/secondary) + for(var/T in type_choices) + if(T == /datum/station_goal/secondary) + continue + var/datum/station_goal/secondary/SG = T + if(initial(SG.abstract)) + type_choices -= SG + var/picked = pick_closest_path(FALSE, make_types_fancy(type_choices), skip_filter = TRUE) + if(!picked) + return + var/datum/station_goal/secondary/G = new picked() + if(picked == /datum/station_goal/secondary) + var/newname = clean_input("Enter goal name:") + if(!newname) + return + G.name = newname + var/description = input("Enter A.L.I.C.E message contents:") as message|null + if(!description) + return + G.report_message = description + var/admin_description = input("Enter description for admins:") as message|null + if(!admin_description) + return + G.admin_desc = admin_description + var/department_choices = list() + for(var/obj/machinery/requests_console/RC in GLOB.allRequestConsoles) + department_choices |= RC.department + var/department = input("Choose goal department") in department_choices|null + if(!department) + return + G.department = department + G.should_send_crate = alert("Send a personal crate?","Send crate","Yes","No") == "Yes" + G.Initialize() + message_admins("[key_name_admin(usr)] created \"[G.name]\" station goal. Description: [G.admin_desc]") + SSticker.mode.secondary_goals += G + modify_goals() + else if(href_list["showdetails"]) if(!check_rights(R_ADMIN)) return diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2.dm b/code/modules/admin/verbs/SDQL2/SDQL_2.dm index b53e871063b9..c920a38ba552 100644 --- a/code/modules/admin/verbs/SDQL2/SDQL_2.dm +++ b/code/modules/admin/verbs/SDQL2/SDQL_2.dm @@ -21,6 +21,7 @@ if(!check_rights(R_PROCCALL)) //Shouldn't happen... but just to be safe. message_admins("ERROR: Non-admin [key_name_admin(usr)] attempted to execute a SDQL query!") log_admin("Non-admin [key_name(usr)] attempted to execute a SDQL query!") + return var/query_text = input("SDQL2 query") as message diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 335b6bd6ea2c..e14ecac59107 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -1147,11 +1147,18 @@ Traitors and the like can also be revived with the previous role mostly intact. to_chat(usr, "This verb can only be used if the round has started.") return - var/dat = "" + var/list/dat = list() for(var/datum/station_goal/S in SSticker.mode.station_goals) - dat += "[S.name] - Announce | Remove
" - dat += "
Add New Goal" - usr << browse(dat, "window=goals;size=400x400") + dat += "[S.name][S.completed ? " (C)" : ""] - Announce | Remove" + dat += "" + dat += "Add New Goal" + dat += "" + dat += "Secondary goals" + for(var/datum/station_goal/secondary/SG in SSticker.mode.secondary_goals) + dat += "[SG.admin_desc][SG.completed ? " (C)" : ""] for [SG.requester_name || SG.department] - Announce | Remove | Mark complete | Reset progress" + dat += "Add New Secondary Goal" + + usr << browse(dat.Join("
"), "window=goals;size=400x400") /// Allow admin to add or remove traits of datum /datum/admins/proc/modify_traits(datum/D) diff --git a/code/modules/antagonists/changeling/powers/fakedeath.dm b/code/modules/antagonists/changeling/powers/fakedeath.dm index b8c7389ca42f..d826b4712e77 100644 --- a/code/modules/antagonists/changeling/powers/fakedeath.dm +++ b/code/modules/antagonists/changeling/powers/fakedeath.dm @@ -23,7 +23,7 @@ return TRUE /datum/action/changeling/fakedeath/proc/ready_to_regenerate(mob/user) - if(user?.mind && cling?.acquired_powers) + if(!QDELETED(user) && user.mind && cling?.acquired_powers) to_chat(user, "We are ready to regenerate.") cling.give_power(new /datum/action/changeling/revive) diff --git a/code/modules/antagonists/vampire/vamp_datum.dm b/code/modules/antagonists/vampire/vamp_datum.dm index 65625b191a51..7ad89d6ef865 100644 --- a/code/modules/antagonists/vampire/vamp_datum.dm +++ b/code/modules/antagonists/vampire/vamp_datum.dm @@ -17,10 +17,10 @@ /// Nullrods and holywater make their abilities cost more var/nullified = 0 /// a list of powers that all vampires unlock and at what blood level they unlock them, the rest of their powers are found in the vampire_subclass datum - var/list/upgrade_tiers = list(/obj/effect/proc_holder/spell/vampire/self/rejuvenate = 0, - /obj/effect/proc_holder/spell/vampire/glare = 0, + var/list/upgrade_tiers = list(/datum/spell/vampire/self/rejuvenate = 0, + /datum/spell/vampire/glare = 0, /datum/vampire_passive/vision = 100, - /obj/effect/proc_holder/spell/vampire/self/specialize = 150, + /datum/spell/vampire/self/specialize = 150, /datum/vampire_passive/regen = 200, /datum/vampire_passive/vision/advanced = 500) @@ -47,12 +47,12 @@ /datum/antagonist/mindslave/thrall/apply_innate_effects(mob/living/mob_override) mob_override = ..() var/datum/mind/M = mob_override.mind - M.AddSpell(new /obj/effect/proc_holder/spell/vampire/thrall_commune) + M.AddSpell(new /datum/spell/vampire/thrall_commune) /datum/antagonist/mindslave/thrall/remove_innate_effects(mob/living/mob_override) mob_override = ..() var/datum/mind/M = mob_override.mind - M.RemoveSpell(/obj/effect/proc_holder/spell/vampire/thrall_commune) + M.RemoveSpell(/datum/spell/vampire/thrall_commune) /datum/antagonist/vampire/Destroy(force, ...) owner.current.create_log(CONVERSION_LOG, "De-vampired") @@ -73,7 +73,7 @@ /datum/antagonist/vampire/proc/force_add_ability(path) var/spell = new path(owner) powers += spell - if(istype(spell, /obj/effect/proc_holder/spell)) + if(istype(spell, /datum/spell)) owner.AddSpell(spell) if(istype(spell, /datum/vampire_passive)) var/datum/vampire_passive/passive = spell @@ -177,12 +177,12 @@ * Remove and delete the vampire's current subclass and all associated abilities. * * Arguments: - * * give_specialize_power - if the [specialize][/obj/effect/proc_holder/spell/vampire/self/specialize] power should be given back or not + * * give_specialize_power - if the [specialize][/datum/spell/vampire/self/specialize] power should be given back or not */ /datum/antagonist/vampire/proc/clear_subclass(give_specialize_power = TRUE) if(give_specialize_power) // Choosing a subclass in the first place removes this from `upgrade_tiers`, so add it back if needed. - upgrade_tiers[/obj/effect/proc_holder/spell/vampire/self/specialize] = 150 + upgrade_tiers[/datum/spell/vampire/self/specialize] = 150 remove_all_powers() QDEL_NULL(subclass) check_vampire_upgrade() @@ -220,8 +220,8 @@ /datum/antagonist/vampire/proc/announce_new_power(list/old_powers) for(var/p in powers) if(!(p in old_powers)) - if(istype(p, /obj/effect/proc_holder/spell)) - var/obj/effect/proc_holder/spell/power = p + if(istype(p, /datum/spell)) + var/datum/spell/power = p to_chat(owner.current, "[power.gain_desc]") else if(istype(p, /datum/vampire_passive)) var/datum/vampire_passive/power = p @@ -308,7 +308,7 @@ bloodtotal += blood_amount bloodusable += blood_amount check_vampire_upgrade(TRUE) - for(var/obj/effect/proc_holder/spell/S in powers) + for(var/datum/spell/S in powers) if(S.action) S.action.UpdateButtons() diff --git a/code/modules/antagonists/vampire/vampire_powers/dantalion_powers.dm b/code/modules/antagonists/vampire/vampire_powers/dantalion_powers.dm index c9dc978e2e2b..e078349bf7e9 100644 --- a/code/modules/antagonists/vampire/vampire_powers/dantalion_powers.dm +++ b/code/modules/antagonists/vampire/vampire_powers/dantalion_powers.dm @@ -9,7 +9,7 @@ /datum/vampire_passive/increment_thrall_cap/three -/obj/effect/proc_holder/spell/vampire/enthrall +/datum/spell/vampire/enthrall name = "Enthrall (150)" desc = "You use a large portion of your power to sway those loyal to none to be loyal to you only." gain_desc = "You have gained the ability to thrall people to your will." @@ -17,13 +17,13 @@ required_blood = 150 deduct_blood_on_cast = FALSE -/obj/effect/proc_holder/spell/vampire/enthrall/create_new_targeting() +/datum/spell/vampire/enthrall/create_new_targeting() var/datum/spell_targeting/click/T = new T.range = 1 T.click_radius = 0 return T -/obj/effect/proc_holder/spell/vampire/enthrall/cast(list/targets, mob/user = usr) +/datum/spell/vampire/enthrall/cast(list/targets, mob/user = usr) var/datum/antagonist/vampire/vampire = user.mind.has_antag_datum(/datum/antagonist/vampire) var/mob/living/target = targets[1] user.visible_message("[user] bites [target]'s neck!", "You bite [target]'s neck and begin the flow of power.") @@ -38,7 +38,7 @@ revert_cast(user) to_chat(user, "You or your target moved.") -/obj/effect/proc_holder/spell/vampire/enthrall/proc/can_enthrall(mob/living/user, mob/living/carbon/C) +/datum/spell/vampire/enthrall/proc/can_enthrall(mob/living/user, mob/living/carbon/C) . = FALSE if(!C) CRASH("target was null while trying to vampire enthrall, attacker is [user] [user.key] \ref[user]") @@ -63,7 +63,7 @@ return return TRUE -/obj/effect/proc_holder/spell/vampire/enthrall/proc/handle_enthrall(mob/living/user, mob/living/carbon/human/H) +/datum/spell/vampire/enthrall/proc/handle_enthrall(mob/living/user, mob/living/carbon/human/H) if(!istype(H)) return FALSE @@ -75,17 +75,17 @@ user.create_log(CONVERSION_LOG, "vampire enthralled", H) H.create_log(CONVERSION_LOG, "was vampire enthralled", user) -/obj/effect/proc_holder/spell/vampire/thrall_commune +/datum/spell/vampire/thrall_commune name = "Commune" desc = "Talk to your thralls telepathically." gain_desc = "You have gained the ability to commune with your thralls." action_icon_state = "vamp_communication" base_cooldown = 2 SECONDS -/obj/effect/proc_holder/spell/vampire/thrall_commune/create_new_handler() //so thralls can use it +/datum/spell/vampire/thrall_commune/create_new_handler() //so thralls can use it return -/datum/spell_targeting/select_vampire_network/choose_targets(mob/user, obj/effect/proc_holder/spell/spell, params, atom/clicked_atom) // Returns the vampire and their thralls. If user is a thrall then it will look up their master's network +/datum/spell_targeting/select_vampire_network/choose_targets(mob/user, datum/spell/spell, params, atom/clicked_atom) // Returns the vampire and their thralls. If user is a thrall then it will look up their master's network var/list/mob/living/targets = list() var/datum/antagonist/vampire/V = user.mind.has_antag_datum(/datum/antagonist/vampire) // if the user is a vampire @@ -106,11 +106,11 @@ targets += V.owner.current return targets -/obj/effect/proc_holder/spell/vampire/thrall_commune/create_new_targeting() +/datum/spell/vampire/thrall_commune/create_new_targeting() var/datum/spell_targeting/select_vampire_network/T = new return T -/obj/effect/proc_holder/spell/vampire/thrall_commune/cast(list/targets, mob/user) +/datum/spell/vampire/thrall_commune/cast(list/targets, mob/user) var/input = tgui_input_text(user, "Enter a message to relay to the other thralls", "Thrall Commune") if(!input) revert_cast(user) @@ -124,7 +124,7 @@ log_say("(DANTALION) [input]", user) user.create_log(SAY_LOG, "(DANTALION) [input]") -/obj/effect/proc_holder/spell/vampire/pacify +/datum/spell/vampire/pacify name = "Pacify (10)" desc = "Pacify a target temporarily, making them unable to cause harm." gain_desc = "You have gained the ability to pacify someone's harmful tendencies, preventing them from doing any physical harm to anyone." @@ -132,18 +132,18 @@ base_cooldown = 30 SECONDS required_blood = 10 -/obj/effect/proc_holder/spell/vampire/pacify/create_new_targeting() +/datum/spell/vampire/pacify/create_new_targeting() var/datum/spell_targeting/click/T = new T.range = 7 T.click_radius = 1 T.allowed_type = /mob/living/carbon/human return T -/obj/effect/proc_holder/spell/vampire/pacify/cast(list/targets, mob/user) +/datum/spell/vampire/pacify/cast(list/targets, mob/user) for(var/mob/living/carbon/human/H as anything in targets) H.apply_status_effect(STATUS_EFFECT_PACIFIED) -/obj/effect/proc_holder/spell/vampire/switch_places +/datum/spell/vampire/switch_places name = "Subspace Swap (30)" desc = "Switch positions with a target." gain_desc = "You have gained the ability to switch positions with a targeted mob." @@ -152,7 +152,7 @@ base_cooldown = 30 SECONDS required_blood = 30 -/obj/effect/proc_holder/spell/vampire/switch_places/create_new_targeting() +/datum/spell/vampire/switch_places/create_new_targeting() var/datum/spell_targeting/click/T = new T.range = 7 T.click_radius = 1 @@ -160,14 +160,14 @@ T.allowed_type = /mob/living return T -/obj/effect/proc_holder/spell/vampire/switch_places/cast(list/targets, mob/user) +/datum/spell/vampire/switch_places/cast(list/targets, mob/user) var/mob/living/target = targets[1] var/turf/user_turf = get_turf(user) var/turf/target_turf = get_turf(target) target.forceMove(user_turf) user.forceMove(target_turf) -/obj/effect/proc_holder/spell/vampire/self/decoy +/datum/spell/vampire/self/decoy name = "Deploy Decoy (30)" desc = "Briefly turn invisible and deploy a decoy illusion to fool your prey." gain_desc = "You have gained the ability to turn invisible and create decoy illusions." @@ -175,7 +175,7 @@ required_blood = 30 base_cooldown = 40 SECONDS -/obj/effect/proc_holder/spell/vampire/self/decoy/cast(list/targets, mob/user) +/datum/spell/vampire/self/decoy/cast(list/targets, mob/user) var/mob/living/simple_animal/hostile/illusion/escape/E = new(get_turf(user)) E.Copy_Parent(user, 20, 20) E.GiveTarget(user) //so it starts running right away @@ -183,7 +183,7 @@ user.make_invisible() addtimer(CALLBACK(user, TYPE_PROC_REF(/mob/living, reset_visibility)), 6 SECONDS) -/obj/effect/proc_holder/spell/vampire/rally_thralls +/datum/spell/vampire/rally_thralls name = "Rally Thralls (100)" desc = "Removes all incapacitating effects from your nearby thralls." gain_desc = "You have gained the ability to remove all incapacitating effects from nearby thralls." @@ -191,18 +191,18 @@ required_blood = 100 base_cooldown = 100 SECONDS -/obj/effect/proc_holder/spell/vampire/rally_thralls/create_new_targeting() +/datum/spell/vampire/rally_thralls/create_new_targeting() var/datum/spell_targeting/aoe/thralls/A = new A.allowed_type = /mob/living/carbon/human A.range = 7 return A -/datum/spell_targeting/aoe/thralls/valid_target(target, user, obj/effect/proc_holder/spell/spell, check_if_in_range) +/datum/spell_targeting/aoe/thralls/valid_target(target, user, datum/spell/spell, check_if_in_range) if(!isvampirethrall(target)) return FALSE return ..() -/obj/effect/proc_holder/spell/vampire/rally_thralls/cast(list/targets, mob/user) +/datum/spell/vampire/rally_thralls/cast(list/targets, mob/user) for(var/mob/living/carbon/human/H as anything in targets) var/image/I = image('icons/effects/vampire_effects.dmi', "rallyoverlay", layer = EFFECTS_LAYER) playsound(H, 'sound/magic/staff_healing.ogg', 30) @@ -210,21 +210,21 @@ H.add_overlay(I) addtimer(CALLBACK(H, TYPE_PROC_REF(/atom, cut_overlay), I), 6 SECONDS) // this makes it obvious who your thralls are for a while. -/obj/effect/proc_holder/spell/vampire/self/share_damage +/datum/spell/vampire/self/share_damage name = "Blood Bond" desc = "Creates a net between you and your nearby thralls that evenly shares all damage received." gain_desc = "You have gained the ability to share damage between you and your thralls." action_icon_state = "blood_bond" required_blood = 5 -/obj/effect/proc_holder/spell/vampire/self/share_damage/cast(list/targets, mob/living/user) +/datum/spell/vampire/self/share_damage/cast(list/targets, mob/living/user) var/datum/status_effect/thrall_net/T = user.has_status_effect(STATUS_EFFECT_THRALL_NET) if(!T) user.apply_status_effect(STATUS_EFFECT_THRALL_NET, user.mind.has_antag_datum(/datum/antagonist/vampire)) return qdel(T) -/obj/effect/proc_holder/spell/vampire/hysteria +/datum/spell/vampire/hysteria name = "Mass Hysteria (70)" desc = "Casts a powerful illusion to make everyone nearby perceive others to looks like random animals after briefly blinding them." gain_desc = "You have gained the ability to make everyone nearby perceive others to looks like random animals after briefly blinding them." @@ -232,13 +232,13 @@ required_blood = 70 base_cooldown = 180 SECONDS -/obj/effect/proc_holder/spell/vampire/hysteria/create_new_targeting() +/datum/spell/vampire/hysteria/create_new_targeting() var/datum/spell_targeting/aoe/A = new A.range = 8 A.allowed_type = /mob/living/carbon/human return A -/obj/effect/proc_holder/spell/vampire/hysteria/cast(list/targets, mob/user) +/datum/spell/vampire/hysteria/cast(list/targets, mob/user) for(var/mob/living/carbon/human/H as anything in targets) if(!H.affects_vampire(user)) continue diff --git a/code/modules/antagonists/vampire/vampire_powers/gargantua_powers.dm b/code/modules/antagonists/vampire/vampire_powers/gargantua_powers.dm index 336ddf3ef7d0..ee34ccebd815 100644 --- a/code/modules/antagonists/vampire/vampire_powers/gargantua_powers.dm +++ b/code/modules/antagonists/vampire/vampire_powers/gargantua_powers.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/vampire/self/blood_swell +/datum/spell/vampire/self/blood_swell name = "Blood Swell (30)" desc = "You infuse your body with blood, making you highly resistant to stuns and physical damage. However, this makes you unable to fire ranged weapons while it is active." gain_desc = "You have gained the ability to temporarly resist large amounts of stuns and physical damage." @@ -6,13 +6,13 @@ required_blood = 30 action_icon_state = "blood_swell" -/obj/effect/proc_holder/spell/vampire/self/blood_swell/cast(list/targets, mob/user) +/datum/spell/vampire/self/blood_swell/cast(list/targets, mob/user) var/mob/living/target = targets[1] if(ishuman(target)) var/mob/living/carbon/human/H = target H.apply_status_effect(STATUS_EFFECT_BLOOD_SWELL) -/obj/effect/proc_holder/spell/vampire/self/stomp +/datum/spell/vampire/self/stomp name = "Seismic Stomp (30)" desc = "You slam your foot into the ground sending a powerful shockwave through the station's hull, sending people flying away. Cannot be cast if you legs are impared by a bola or similar." gain_desc = "You have gained the ability to knock people back using a powerful stomp." @@ -21,18 +21,18 @@ required_blood = 30 var/max_range = 4 -/obj/effect/proc_holder/spell/vampire/self/stomp/can_cast(mob/living/carbon/user, charge_check, show_message) +/datum/spell/vampire/self/stomp/can_cast(mob/living/carbon/user, charge_check, show_message) if(user.legcuffed) return FALSE return ..() -/obj/effect/proc_holder/spell/vampire/self/stomp/cast(list/targets, mob/user) +/datum/spell/vampire/self/stomp/cast(list/targets, mob/user) var/turf/T = get_turf(user) playsound(T, 'sound/effects/meteorimpact.ogg', 100, TRUE) addtimer(CALLBACK(src, PROC_REF(hit_check), 1, T, user), 0.2 SECONDS) new /obj/effect/temp_visual/stomp(T) -/obj/effect/proc_holder/spell/vampire/self/stomp/proc/hit_check(range, turf/start_turf, mob/user, safe_targets = list()) +/datum/spell/vampire/self/stomp/proc/hit_check(range, turf/start_turf, mob/user, safe_targets = list()) // gets the two outermost turfs in a ring, we get two so people cannot "walk over" the shockwave var/list/targets = view(range, start_turf) - view(range - 2, start_turf) for(var/turf/simulated/floor/flooring in targets) @@ -72,14 +72,14 @@ /datum/vampire_passive/blood_swell_upgrade gain_desc = "While blood swell is active all of your melee attacks deal increased damage." -/obj/effect/proc_holder/spell/vampire/self/overwhelming_force +/datum/spell/vampire/self/overwhelming_force name = "Overwhelming Force" desc = "When toggled you will automatically pry open doors that you bump into if you do not have access." gain_desc = "You have gained the ability to force open doors at a small blood cost." base_cooldown = 2 SECONDS action_icon_state = "OH_YEAAAAH" -/obj/effect/proc_holder/spell/vampire/self/overwhelming_force/cast(list/targets, mob/user) +/datum/spell/vampire/self/overwhelming_force/cast(list/targets, mob/user) if(!HAS_TRAIT_FROM(user, TRAIT_FORCE_DOORS, VAMPIRE_TRAIT)) to_chat(user, "You feel MIGHTY!") ADD_TRAIT(user, TRAIT_FORCE_DOORS, VAMPIRE_TRAIT) @@ -90,7 +90,7 @@ user.move_resist = MOVE_FORCE_DEFAULT user.status_flags |= CANPUSH -/obj/effect/proc_holder/spell/vampire/self/blood_rush +/datum/spell/vampire/self/blood_rush name = "Blood Rush (30)" desc = "Infuse yourself with blood magic to boost your movement speed." gain_desc = "You have gained the ability to temporarily move at high speeds." @@ -98,14 +98,14 @@ required_blood = 30 action_icon_state = "blood_rush" -/obj/effect/proc_holder/spell/vampire/self/blood_rush/cast(list/targets, mob/user) +/datum/spell/vampire/self/blood_rush/cast(list/targets, mob/user) var/mob/living/target = targets[1] if(ishuman(target)) var/mob/living/carbon/human/H = target to_chat(H, "You feel a rush of energy!") H.apply_status_effect(STATUS_EFFECT_BLOOD_RUSH) -/obj/effect/proc_holder/spell/fireball/demonic_grasp +/datum/spell/fireball/demonic_grasp name = "Demonic Grasp (20)" desc = "Fire a hand of demonic energy, snaring and throwing its target around, based on your intent. Disarm pushes, grab pulls." gain_desc = "You have gained the ability to snare and disrupt people with demonic apendages." @@ -124,10 +124,10 @@ invocation_type = "none" invocation = null -/obj/effect/proc_holder/spell/fireball/demonic_grasp/update_icon_state() +/datum/spell/fireball/demonic_grasp/update_spell_icon() return -/obj/effect/proc_holder/spell/fireball/demonic_grasp/create_new_handler() +/datum/spell/fireball/demonic_grasp/create_new_handler() var/datum/spell_handler/vampire/V = new() V.required_blood = 20 return V @@ -178,7 +178,7 @@ icon_state = "immobilized" duration = 1 SECONDS -/obj/effect/proc_holder/spell/vampire/charge +/datum/spell/vampire/charge name = "Charge (30)" desc = "You charge at wherever you click on screen, dealing large amounts of damage, stunning and destroying walls and other objects." gain_desc = "You can now charge at a target on screen, dealing massive damage and destroying structures." @@ -186,16 +186,16 @@ base_cooldown = 30 SECONDS action_icon_state = "vampire_charge" -/obj/effect/proc_holder/spell/vampire/charge/create_new_targeting() +/datum/spell/vampire/charge/create_new_targeting() return new /datum/spell_targeting/clicked_atom -/obj/effect/proc_holder/spell/vampire/charge/can_cast(mob/user, charge_check, show_message) +/datum/spell/vampire/charge/can_cast(mob/user, charge_check, show_message) var/mob/living/L = user if(IS_HORIZONTAL(L)) return FALSE return ..() -/obj/effect/proc_holder/spell/vampire/charge/cast(list/targets, mob/user) +/datum/spell/vampire/charge/cast(list/targets, mob/user) var/target = targets[1] if(isliving(user)) var/mob/living/L = user @@ -204,7 +204,7 @@ #define ARENA_SIZE 3 -/obj/effect/proc_holder/spell/vampire/arena +/datum/spell/vampire/arena name = "Desecrated Duel (150)" desc = "You leap towards someone. Upon landing, you conjure an arena, and within it you will heal brute and burn damage, recover from fatigue faster, and be strengthened against lasting damages. Can be recasted to end the spell early." gain_desc = "You can now leap to a target and trap them in a conjured arena." @@ -218,13 +218,13 @@ /// Holds a reference to all arena walls so we can qdel them easily with dispel() var/list/all_temp_walls = list() -/obj/effect/proc_holder/spell/vampire/arena/create_new_targeting() +/datum/spell/vampire/arena/create_new_targeting() var/datum/spell_targeting/click/T = new T.click_radius = 0 T.allowed_type = /mob/living/carbon/human return T -/obj/effect/proc_holder/spell/vampire/arena/cast(list/targets, mob/living/user) +/datum/spell/vampire/arena/cast(list/targets, mob/living/user) var/target = targets[1] // We only want to dash towards the first mob in our targeting list, if somehow multiple ended up in there if(!targets) return @@ -262,24 +262,24 @@ RegisterSignal(user, COMSIG_PARENT_QDELETING, PROC_REF(dispel)) arena_checks(get_turf(target), user) -/obj/effect/proc_holder/spell/vampire/arena/proc/arena_checks(turf/target_turf, mob/living/user) +/datum/spell/vampire/arena/proc/arena_checks(turf/target_turf, mob/living/user) if(!spell_active || QDELETED(src)) return INVOKE_ASYNC(src, PROC_REF(fighters_check), user) //Checks to see if our fighters died. INVOKE_ASYNC(src, PROC_REF(arena_trap), target_turf) //Gets another arena trap queued up for when this one runs out. addtimer(CALLBACK(src, PROC_REF(arena_checks), target_turf, user), 5 SECONDS) -/obj/effect/proc_holder/spell/vampire/arena/proc/arena_trap(turf/target_turf) +/datum/spell/vampire/arena/proc/arena_trap(turf/target_turf) for(var/tumor_range_turfs in circle_edge_turfs(target_turf, ARENA_SIZE)) tumor_range_turfs = new /obj/effect/temp_visual/elite_tumor_wall/gargantua(tumor_range_turfs, src) all_temp_walls += tumor_range_turfs -/obj/effect/proc_holder/spell/vampire/arena/proc/fighters_check(mob/living/user) +/datum/spell/vampire/arena/proc/fighters_check(mob/living/user) if(QDELETED(user) || user.stat == DEAD) dispel(user) return -/obj/effect/proc_holder/spell/vampire/arena/proc/dispel(mob/living/user) +/datum/spell/vampire/arena/proc/dispel(mob/living/user) spell_active = FALSE if(timer) deltimer(timer) diff --git a/code/modules/antagonists/vampire/vampire_powers/hemomancer_powers.dm b/code/modules/antagonists/vampire/vampire_powers/hemomancer_powers.dm index 185725490562..f086ac67f57f 100644 --- a/code/modules/antagonists/vampire/vampire_powers/hemomancer_powers.dm +++ b/code/modules/antagonists/vampire/vampire_powers/hemomancer_powers.dm @@ -1,4 +1,4 @@ -/obj/effect/proc_holder/spell/vampire/self/vamp_claws +/datum/spell/vampire/self/vamp_claws name = "Vampiric Claws (30)" desc = "You channel blood magics to forge deadly vampiric claws that leech blood and strike rapidly. Cannot be used if you are holding something that cannot be dropped." gain_desc = "You have gained the ability to forge your hands into vampiric claws." @@ -6,7 +6,7 @@ required_blood = 30 action_icon_state = "vampire_claws" -/obj/effect/proc_holder/spell/vampire/self/vamp_claws/cast(mob/user) +/datum/spell/vampire/self/vamp_claws/cast(mob/user) if(user.l_hand || user.r_hand) to_chat(user, "You drop what was in your hands as large blades spring from your fingers!") user.drop_l_hand() @@ -17,7 +17,7 @@ RegisterSignal(user, COMSIG_MOB_WILLINGLY_DROP, PROC_REF(dispel)) user.put_in_hands(claws) -/obj/effect/proc_holder/spell/vampire/self/vamp_claws/proc/dispel() +/datum/spell/vampire/self/vamp_claws/proc/dispel() SIGNAL_HANDLER var/mob/living/carbon/human/user = action.owner if(user.mind.has_antag_datum(/datum/antagonist/vampire)) @@ -31,7 +31,7 @@ qdel(current) to_chat(user, "You dispel your claws!") -/obj/effect/proc_holder/spell/vampire/self/vamp_claws/can_cast(mob/user, charge_check, show_message) +/datum/spell/vampire/self/vamp_claws/can_cast(mob/user, charge_check, show_message) var/mob/living/L = user if(L.canUnEquip(L.l_hand) && L.canUnEquip(L.r_hand)) return ..() @@ -55,7 +55,7 @@ var/durability = 15 var/blood_drain_amount = 15 var/blood_absorbed_amount = 5 - var/obj/effect/proc_holder/spell/vampire/self/vamp_claws/parent_spell + var/datum/spell/vampire/self/vamp_claws/parent_spell /obj/item/vamp_claws/Initialize(mapload, new_parent_spell) . = ..() @@ -104,7 +104,7 @@ qdel(src) to_chat(user, "You dispel your claws!") -/obj/effect/proc_holder/spell/vampire/blood_tendrils +/datum/spell/vampire/blood_tendrils name = "Blood Tendrils (10)" desc = "You summon blood tendrils from bluespace after a delay to ensnare people in an area, slowing them down." gain_desc = "You have gained the ability to summon blood tendrils to slow people down in an area that you target." @@ -115,16 +115,16 @@ sound = 'sound/misc/enter_blood.ogg' var/area_of_affect = 1 - selection_activated_message = "You channel blood magics to weaken the bluespace veil. Left-click to cast at a target area!" + selection_activated_message = "You channel blood magics to weaken the bluespace veil. Left-click to cast at a target area!" selection_deactivated_message = "Your magics subside." -/obj/effect/proc_holder/spell/vampire/blood_tendrils/create_new_targeting() +/datum/spell/vampire/blood_tendrils/create_new_targeting() var/datum/spell_targeting/click/T = new T.allowed_type = /atom T.try_auto_target = FALSE return T -/obj/effect/proc_holder/spell/vampire/blood_tendrils/cast(list/targets, mob/user) +/datum/spell/vampire/blood_tendrils/cast(list/targets, mob/user) var/turf/T = get_turf(targets[1]) // there should only ever be one entry in targets for this spell for(var/turf/simulated/blood_turf in view(area_of_affect, T)) @@ -134,7 +134,7 @@ addtimer(CALLBACK(src, PROC_REF(apply_slowdown), T, area_of_affect, 6 SECONDS, user), 0.5 SECONDS) -/obj/effect/proc_holder/spell/vampire/blood_tendrils/proc/apply_slowdown(turf/T, distance, slowed_amount, mob/user) +/datum/spell/vampire/blood_tendrils/proc/apply_slowdown(turf/T, distance, slowed_amount, mob/user) for(var/mob/living/L in range(distance, T)) if(L.affects_vampire(user)) L.Slowed(slowed_amount) @@ -149,7 +149,7 @@ /obj/effect/temp_visual/blood_tendril/long duration = 2 SECONDS -/obj/effect/proc_holder/spell/vampire/blood_barrier +/datum/spell/vampire/blood_barrier name = "Blood Barrier (40)" desc = "Select two points within 3 tiles of each other and make a barrier between them." gain_desc = "You have gained the ability to summon a crystaline wall of blood between two points, the barrier is easily destructable, however you can walk freely through it." @@ -162,24 +162,24 @@ var/max_walls = 3 var/turf/start_turf = null -/obj/effect/proc_holder/spell/vampire/blood_barrier/create_new_targeting() +/datum/spell/vampire/blood_barrier/create_new_targeting() var/datum/spell_targeting/click/T = new T.allowed_type = /atom T.try_auto_target = FALSE return T -/obj/effect/proc_holder/spell/vampire/blood_barrier/remove_ranged_ability(mob/user, msg) +/datum/spell/vampire/blood_barrier/remove_ranged_ability(mob/user, msg) . = ..() if(msg) // this is only true if the user intentionally turned off the spell start_turf = null should_recharge_after_cast = FALSE -/obj/effect/proc_holder/spell/vampire/blood_barrier/should_remove_click_intercept() +/datum/spell/vampire/blood_barrier/should_remove_click_intercept() if(start_turf) return TRUE return FALSE -/obj/effect/proc_holder/spell/vampire/blood_barrier/cast(list/targets, mob/user) +/datum/spell/vampire/blood_barrier/cast(list/targets, mob/user) var/turf/target_turf = get_turf(targets[1]) if(target_turf == start_turf) to_chat(user, "You deselect the targeted turf.") @@ -244,7 +244,7 @@ -/obj/effect/proc_holder/spell/ethereal_jaunt/blood_pool +/datum/spell/ethereal_jaunt/blood_pool name = "Sanguine Pool (50)" desc = "You shift your form into a pool of blood, making you invulnerable and able to move through anything that's not a wall or space. You leave a trail of blood behind you when you do this." gain_desc = "You have gained the ability to shift into a pool of blood, allowing you to evade pursuers with great mobility." @@ -261,12 +261,12 @@ jaunt_in_time = 0 sound1 = 'sound/misc/enter_blood.ogg' -/obj/effect/proc_holder/spell/ethereal_jaunt/blood_pool/create_new_handler() +/datum/spell/ethereal_jaunt/blood_pool/create_new_handler() var/datum/spell_handler/vampire/H = new H.required_blood = 50 return H -/obj/effect/proc_holder/spell/vampire/predator_senses +/datum/spell/vampire/predator_senses name = "Predator Senses" desc = "Hunt down your prey, there's nowhere to hide..." gain_desc = "Your senses are heightened, nobody can hide from you now." @@ -274,16 +274,16 @@ base_cooldown = 20 SECONDS create_attack_logs = FALSE -/obj/effect/proc_holder/spell/vampire/predator_senses/create_new_targeting() +/datum/spell/vampire/predator_senses/create_new_targeting() var/datum/spell_targeting/alive_mob_list/A = new() A.allowed_type = /mob/living/carbon/human A.max_targets = 300 // hopefully we never hit this number return A -/obj/effect/proc_holder/spell/vampire/predator_senses/valid_target(mob/target, mob/user) +/datum/spell/vampire/predator_senses/valid_target(mob/target, mob/user) return target.z == user.z && target.mind -/obj/effect/proc_holder/spell/vampire/predator_senses/cast(list/targets, mob/user) +/datum/spell/vampire/predator_senses/cast(list/targets, mob/user) var/targets_by_name = list() for(var/mob/living/carbon/human/H as anything in targets) targets_by_name[H.real_name] = H @@ -297,7 +297,7 @@ message += " They are wounded..." to_chat(user, "[message]") -/obj/effect/proc_holder/spell/vampire/blood_eruption +/datum/spell/vampire/blood_eruption name = "Blood Eruption (100)" desc = "Every pool of blood in 4 tiles erupts with a spike of living blood, damaging anyone stood on it." gain_desc = "You have gained the ability to weaponise pools of blood to damage those stood on them." @@ -305,13 +305,13 @@ base_cooldown = 200 SECONDS action_icon_state = "blood_spikes" -/obj/effect/proc_holder/spell/vampire/blood_eruption/create_new_targeting() +/datum/spell/vampire/blood_eruption/create_new_targeting() var/datum/spell_targeting/aoe/T = new T.range = 4 T.allowed_type = /mob/living return T -/obj/effect/proc_holder/spell/vampire/blood_eruption/valid_target(mob/living/target, user) +/datum/spell/vampire/blood_eruption/valid_target(mob/living/target, user) var/turf/T = get_turf(target) if(locate(/obj/effect/decal/cleanable/blood) in T) if(target.affects_vampire(user) && !isLivingSSD(target)) @@ -319,7 +319,7 @@ return FALSE -/obj/effect/proc_holder/spell/vampire/blood_eruption/cast(list/targets, mob/user) +/datum/spell/vampire/blood_eruption/cast(list/targets, mob/user) for(var/mob/living/L in targets) var/turf/T = get_turf(L) var/obj/effect/decal/cleanable/blood/B = locate(/obj/effect/decal/cleanable/blood) in T @@ -334,7 +334,7 @@ icon_state = "bloodspike_white" duration = 0.3 SECONDS -/obj/effect/proc_holder/spell/vampire/self/blood_spill +/datum/spell/vampire/self/blood_spill name = "The Blood Bringers Rite" desc = "When toggled, everyone around you begins to bleed profusely. You will drain their blood and rejuvenate yourself with it." gain_desc = "You have gained the ability to rip the very life force out of people and absorb it, healing you." @@ -342,7 +342,7 @@ action_icon_state = "blood_bringers_rite" required_blood = 10 -/obj/effect/proc_holder/spell/vampire/self/blood_spill/cast(list/targets, mob/user) +/datum/spell/vampire/self/blood_spill/cast(list/targets, mob/user) var/datum/antagonist/vampire/V = user.mind.has_antag_datum(/datum/antagonist/vampire) if(!V.get_ability(/datum/vampire_passive/blood_spill)) V.force_add_ability(/datum/vampire_passive/blood_spill) diff --git a/code/modules/antagonists/vampire/vampire_powers/umbrae_powers.dm b/code/modules/antagonists/vampire/vampire_powers/umbrae_powers.dm index 5d75d682faf9..0b1473ee8d88 100644 --- a/code/modules/antagonists/vampire/vampire_powers/umbrae_powers.dm +++ b/code/modules/antagonists/vampire/vampire_powers/umbrae_powers.dm @@ -1,17 +1,11 @@ -/obj/effect/proc_holder/spell/vampire/self/cloak +/datum/spell/vampire/self/cloak name = "Cloak of Darkness" desc = "Toggles whether you are currently cloaking yourself in darkness. When in darkness and toggled on, you move at increased speeds." gain_desc = "You have gained the Cloak of Darkness ability, which when toggled makes you nearly invisible and highly agile in the shroud of darkness." action_icon_state = "vampire_cloak" base_cooldown = 2 SECONDS -/obj/effect/proc_holder/spell/vampire/self/cloak/New() - ..() - update_name() - -/obj/effect/proc_holder/spell/vampire/self/cloak/update_name() - . = ..() - var/mob/living/user = loc +/datum/spell/vampire/self/cloak/proc/update_spell_name(mob/living/user) if(!ishuman(user) || !user.mind) return var/datum/antagonist/vampire/V = user.mind.has_antag_datum(/datum/antagonist/vampire) @@ -19,9 +13,10 @@ return action.name = "[initial(name)] ([V.iscloaking ? "Deactivate" : "Activate"])" + SEND_SIGNAL(src, COMSIG_ATOM_UPDATE_NAME) UpdateButtons() -/obj/effect/proc_holder/spell/vampire/self/cloak/cast(list/targets, mob/user = usr) +/datum/spell/vampire/self/cloak/cast(list/targets, mob/user = usr) var/datum/antagonist/vampire/V = user.mind.has_antag_datum(/datum/antagonist/vampire) V.iscloaking = !V.iscloaking if(ishuman(user)) @@ -32,7 +27,7 @@ else user.UnregisterSignal(user, COMSIG_LIVING_IGNITED) H.physiology.burn_mod /= 1.1 - update_name() + update_spell_name(user) to_chat(user, "You will now be [V.iscloaking ? "hidden" : "seen"] in darkness.") /mob/living/proc/update_vampire_cloak() @@ -40,7 +35,7 @@ var/datum/antagonist/vampire/V = mind.has_antag_datum(/datum/antagonist/vampire) V.handle_vampire_cloak() -/obj/effect/proc_holder/spell/vampire/shadow_snare +/datum/spell/vampire/shadow_snare name = "Shadow Snare (20)" desc = "You summon a trap on the ground. When crossed it will blind the target, extinguish any lights they may have, and ensnare them." gain_desc = "You have gained the ability to summon a trap that will blind, ensnare, and turn off the lights of anyone who crosses it." @@ -48,13 +43,13 @@ required_blood = 20 action_icon_state = "shadow_snare" -/obj/effect/proc_holder/spell/vampire/shadow_snare/create_new_targeting() +/datum/spell/vampire/shadow_snare/create_new_targeting() var/datum/spell_targeting/click/T = new T.allowed_type = /turf/simulated T.click_radius = -1 return T -/obj/effect/proc_holder/spell/vampire/shadow_snare/cast(list/targets, mob/user) +/datum/spell/vampire/shadow_snare/cast(list/targets, mob/user) var/turf/target = targets[1] new /obj/item/restraints/legcuffs/beartrap/shadow_snare(target) @@ -116,7 +111,7 @@ STOP_PROCESSING(SSobj, src) return ..() -/obj/effect/proc_holder/spell/vampire/soul_anchor +/datum/spell/vampire/soul_anchor name = "Soul Anchor (30)" desc = "You summon a dimenional anchor after a delay, casting again will teleport you back to the anchor. You will fake a recall after 2 minutes." gain_desc = "You have gained the ability to save a point in space and teleport back to it at will. Unless you willingly teleport back to that point within 2 minutes, you will fake a recall." @@ -132,10 +127,10 @@ /// Holds a reference to the timer until the caster fake recalls var/timer -/obj/effect/proc_holder/spell/vampire/soul_anchor/create_new_targeting() +/datum/spell/vampire/soul_anchor/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/vampire/soul_anchor/cast(list/targets, mob/user) +/datum/spell/vampire/soul_anchor/cast(list/targets, mob/user) if(making_anchor) // second cast, but we are impatient to_chat(user, "Your anchor isn't ready yet!") return @@ -152,11 +147,11 @@ recall(user) -/obj/effect/proc_holder/spell/vampire/soul_anchor/proc/make_anchor(mob/user, turf/anchor_turf) +/datum/spell/vampire/soul_anchor/proc/make_anchor(mob/user, turf/anchor_turf) anchor = new(anchor_turf) timer = addtimer(CALLBACK(src, PROC_REF(recall), user, TRUE), 2 MINUTES, TIMER_STOPPABLE) -/obj/effect/proc_holder/spell/vampire/soul_anchor/proc/recall(mob/user, fake = FALSE) +/datum/spell/vampire/soul_anchor/proc/recall(mob/user, fake = FALSE) cooldown_handler.start_recharge() if(timer) deltimer(timer) @@ -214,7 +209,7 @@ anchored = TRUE resistance_flags = INDESTRUCTIBLE -/obj/effect/proc_holder/spell/vampire/dark_passage +/datum/spell/vampire/dark_passage name = "Dark Passage (30)" desc = "You teleport to a targeted turf." gain_desc = "You have gained the ability to blink a short distance towards a targeted turf." @@ -223,13 +218,13 @@ centcom_cancast = FALSE action_icon_state = "dark_passage" -/obj/effect/proc_holder/spell/vampire/dark_passage/create_new_targeting() +/datum/spell/vampire/dark_passage/create_new_targeting() var/datum/spell_targeting/click/T = new T.click_radius = 0 T.allowed_type = /turf/simulated return T -/obj/effect/proc_holder/spell/vampire/dark_passage/cast(list/targets, mob/user) +/datum/spell/vampire/dark_passage/cast(list/targets, mob/user) var/turf/target = get_turf(targets[1]) new /obj/effect/temp_visual/vamp_mist_out(get_turf(user)) @@ -241,7 +236,7 @@ icon = 'icons/mob/mob.dmi' icon_state = "mist" -/obj/effect/proc_holder/spell/vampire/vamp_extinguish +/datum/spell/vampire/vamp_extinguish name = "Extinguish" desc = "You extinguish any light source in an area around you." gain_desc = "You have gained the ability to extinguish nearby light sources." @@ -250,17 +245,17 @@ create_attack_logs = FALSE create_custom_logs = TRUE -/obj/effect/proc_holder/spell/vampire/vamp_extinguish/create_new_targeting() +/datum/spell/vampire/vamp_extinguish/create_new_targeting() var/datum/spell_targeting/aoe/turf/T = new return T -/obj/effect/proc_holder/spell/vampire/vamp_extinguish/cast(list/targets, mob/user = usr) +/datum/spell/vampire/vamp_extinguish/cast(list/targets, mob/user = usr) for(var/turf/T in targets) T.extinguish_light() for(var/atom/A in T.contents) A.extinguish_light() -/obj/effect/proc_holder/spell/vampire/shadow_boxing +/datum/spell/vampire/shadow_boxing name = "Shadow Boxing (50)" desc = "Target someone to have your shadow beat them up. You must stay within 2 tiles for this to work." gain_desc = "You have gained the ability to make your shadow fight for you." @@ -269,18 +264,18 @@ required_blood = 50 var/target_UID -/obj/effect/proc_holder/spell/vampire/shadow_boxing/create_new_targeting() +/datum/spell/vampire/shadow_boxing/create_new_targeting() var/datum/spell_targeting/click/C = new C.allowed_type = /mob/living C.range = 2 C.try_auto_target = FALSE return C -/obj/effect/proc_holder/spell/vampire/shadow_boxing/cast(list/targets, mob/user) +/datum/spell/vampire/shadow_boxing/cast(list/targets, mob/user) var/mob/living/target = targets[1] target.apply_status_effect(STATUS_EFFECT_SHADOW_BOXING, user) -/obj/effect/proc_holder/spell/vampire/self/eternal_darkness +/datum/spell/vampire/self/eternal_darkness name = "Eternal Darkness" desc = "When toggled, you shroud the area around you in darkness and slowly lower the body temperature of people nearby. Energy projectiles will dim in its radius." gain_desc = "You have gained the ability to shroud the area around you in darkness, only the strongest of lights can pierce your unholy powers." @@ -289,7 +284,7 @@ required_blood = 5 var/shroud_power = -6 -/obj/effect/proc_holder/spell/vampire/self/eternal_darkness/cast(list/targets, mob/user) +/datum/spell/vampire/self/eternal_darkness/cast(list/targets, mob/user) var/datum/antagonist/vampire/V = user.mind.has_antag_datum(/datum/antagonist/vampire) var/mob/target = targets[1] if(!V.get_ability(/datum/vampire_passive/eternal_darkness)) diff --git a/code/modules/antagonists/vampire/vampire_powers/vampire_powers.dm b/code/modules/antagonists/vampire/vampire_powers/vampire_powers.dm index ed1c9723aff9..668baada797e 100644 --- a/code/modules/antagonists/vampire/vampire_powers/vampire_powers.dm +++ b/code/modules/antagonists/vampire/vampire_powers/vampire_powers.dm @@ -12,7 +12,7 @@ return FALSE return TRUE -/obj/effect/proc_holder/spell/vampire +/datum/spell/vampire panel = "Vampire" school = "vampire" action_background_icon_state = "bg_vampire" @@ -22,13 +22,13 @@ var/required_blood var/deduct_blood_on_cast = TRUE -/obj/effect/proc_holder/spell/vampire/create_new_handler() +/datum/spell/vampire/create_new_handler() var/datum/spell_handler/vampire/H = new H.required_blood = required_blood H.deduct_blood_on_cast = deduct_blood_on_cast return H -/obj/effect/proc_holder/spell/vampire/self/create_new_targeting() +/datum/spell/vampire/self/create_new_targeting() return new /datum/spell_targeting/self /datum/vampire_passive @@ -48,14 +48,14 @@ owner.update_sight() // Life updates conditionally, so we need to update sight here in case the vamp gets new vision based on his powers. Maybe one day refactor to be more OOP and on the vampire's ability datum. return -/obj/effect/proc_holder/spell/vampire/self/rejuvenate +/datum/spell/vampire/self/rejuvenate name = "Rejuvenate" desc = "Use reserve blood to enliven your body, removing any incapacitating effects." action_icon_state = "vampire_rejuvinate" base_cooldown = 20 SECONDS stat_allowed = UNCONSCIOUS -/obj/effect/proc_holder/spell/vampire/self/rejuvenate/cast(list/targets, mob/user = usr) +/datum/spell/vampire/self/rejuvenate/cast(list/targets, mob/user = usr) var/mob/living/U = user U.SetWeakened(0) @@ -73,7 +73,7 @@ if(rejuv_bonus) INVOKE_ASYNC(src, PROC_REF(heal), U, rejuv_bonus) -/obj/effect/proc_holder/spell/vampire/self/rejuvenate/proc/heal(mob/living/user, rejuv_bonus) +/datum/spell/vampire/self/rejuvenate/proc/heal(mob/living/user, rejuv_bonus) for(var/i in 1 to 5) user.adjustBruteLoss(-2 * rejuv_bonus) user.adjustOxyLoss(-5 * rejuv_bonus) @@ -93,35 +93,35 @@ rejuv_multiplier = clamp((100 - owner.current.health) / 20, 1, 5) // brute and burn healing between 5 and 50 return rejuv_multiplier - return 1 + return TRUE -/obj/effect/proc_holder/spell/vampire/self/specialize +/datum/spell/vampire/self/specialize name = "Choose Specialization" desc = "Choose what sub-class of vampire you want to evolve into." gain_desc = "You can now choose what specialization of vampire you want to evolve into." base_cooldown = 2 SECONDS action_icon_state = "select_class" -/obj/effect/proc_holder/spell/vampire/self/specialize/cast(mob/user) +/datum/spell/vampire/self/specialize/cast(mob/user) ui_interact(user) -/obj/effect/proc_holder/spell/vampire/self/specialize/ui_state(mob/user) +/datum/spell/vampire/self/specialize/ui_state(mob/user) return GLOB.always_state -/obj/effect/proc_holder/spell/vampire/self/specialize/ui_interact(mob/user, datum/tgui/ui = null) +/datum/spell/vampire/self/specialize/ui_interact(mob/user, datum/tgui/ui = null) ui = SStgui.try_update_ui(user, src, ui) if(!ui) ui = new(user, src, "SpecMenu", "Specialisation Menu") ui.set_autoupdate(FALSE) ui.open() -/obj/effect/proc_holder/spell/vampire/self/specialize/ui_data(mob/user) +/datum/spell/vampire/self/specialize/ui_data(mob/user) var/datum/antagonist/vampire/vamp = user.mind.has_antag_datum(/datum/antagonist/vampire) var/list/data = list("subclasses" = vamp.subclass) return data -/obj/effect/proc_holder/spell/vampire/self/specialize/ui_act(action, list/params) +/datum/spell/vampire/self/specialize/ui_act(action, list/params) if(..()) return var/datum/antagonist/vampire/vamp = usr.mind.has_antag_datum(/datum/antagonist/vampire) @@ -157,20 +157,20 @@ if(log_choice) SSblackbox.record_feedback("nested tally", "vampire_subclasses", 1, list("[new_subclass.name]")) -/obj/effect/proc_holder/spell/vampire/glare +/datum/spell/vampire/glare name = "Glare" desc = "Your eyes flash, stunning and silencing anyone in front of you. It has lesser effects for those around you." action_icon_state = "vampire_glare" base_cooldown = 30 SECONDS stat_allowed = UNCONSCIOUS -/obj/effect/proc_holder/spell/vampire/glare/create_new_targeting() +/datum/spell/vampire/glare/create_new_targeting() var/datum/spell_targeting/aoe/T = new T.allowed_type = /mob/living T.range = 1 return T -/obj/effect/proc_holder/spell/vampire/glare/create_new_cooldown() +/datum/spell/vampire/glare/create_new_cooldown() var/datum/spell_cooldown/charges/C = new C.max_charges = 2 C.recharge_duration = base_cooldown @@ -184,7 +184,7 @@ /// Full deviation. Flashed from directly behind or behind-left/behind-rack. Not flashed at all. #define DEVIATION_FULL 1 -/obj/effect/proc_holder/spell/vampire/glare/cast(list/targets, mob/living/user = usr) +/datum/spell/vampire/glare/cast(list/targets, mob/living/user = usr) if(ishuman(user)) var/mob/living/carbon/human/H = user if(istype(H.glasses, /obj/item/clothing/glasses/sunglasses/blindfold)) @@ -221,7 +221,7 @@ to_chat(target, "You are blinded by [user]'s glare.") add_attack_logs(user, target, "(Vampire) Glared at") -/obj/effect/proc_holder/spell/vampire/glare/proc/calculate_deviation(mob/victim, mob/attacker) +/datum/spell/vampire/glare/proc/calculate_deviation(mob/victim, mob/attacker) // Are they on the same tile? We'll return partial deviation. This may be someone flashing while lying down if(victim.loc == attacker.loc) return DEVIATION_PARTIAL @@ -279,7 +279,7 @@ /datum/vampire_passive/full gain_desc = "You have reached your full potential. You are no longer weak to the effects of anything holy." -/obj/effect/proc_holder/spell/vampire/raise_vampires +/datum/spell/vampire/raise_vampires name = "Raise Vampires" desc = "Summons deadly vampires from bluespace." school = "transmutation" @@ -293,12 +293,12 @@ sound = 'sound/magic/wandodeath.ogg' gain_desc = "You have gained the ability to Raise Vampires. This extremely powerful AOE ability affects all humans near you. Vampires/thralls are healed. Corpses are raised as vampires. Others are stunned, then brain damaged, then killed." -/obj/effect/proc_holder/spell/vampire/raise_vampires/create_new_targeting() +/datum/spell/vampire/raise_vampires/create_new_targeting() var/datum/spell_targeting/aoe/T = new T.range = 3 return T -/obj/effect/proc_holder/spell/vampire/raise_vampires/cast(list/targets, mob/user = usr) +/datum/spell/vampire/raise_vampires/cast(list/targets, mob/user = usr) new /obj/effect/temp_visual/cult/sparks(user.loc) var/turf/T = get_turf(user) to_chat(user, "You call out within bluespace, summoning more vampiric spirits to aid you!") @@ -308,17 +308,17 @@ raise_vampire(user, H) -/obj/effect/proc_holder/spell/vampire/raise_vampires/proc/raise_vampire(mob/M, mob/living/carbon/human/H) +/datum/spell/vampire/raise_vampires/proc/raise_vampire(mob/M, mob/living/carbon/human/H) if(!istype(M) || !istype(H)) return if(!H.mind) - visible_message("[H] looks to be too stupid to understand what is going on.") + H.visible_message("[H] looks to be too stupid to understand what is going on.") return if(H.dna && (NO_BLOOD in H.dna.species.species_traits) || H.dna.species.exotic_blood || !H.blood_volume) - visible_message("[H] looks unfazed!") + H.visible_message("[H] looks unfazed!") return if(H.mind.has_antag_datum(/datum/antagonist/vampire) || H.mind.special_role == SPECIAL_ROLE_VAMPIRE || H.mind.special_role == SPECIAL_ROLE_VAMPIRE_THRALL) - visible_message("[H] looks refreshed!") + H.visible_message("[H] looks refreshed!") H.adjustBruteLoss(-60) H.adjustFireLoss(-60) for(var/obj/item/organ/external/E in H.bodyparts) @@ -330,10 +330,10 @@ return if(H.stat != DEAD) if(H.IsWeakened()) - visible_message("[H] looks to be in pain!") + H.visible_message("[H] looks to be in pain!") H.adjustBrainLoss(60) else - visible_message("[H] looks to be stunned by the energy!") + H.visible_message("[H] looks to be stunned by the energy!") H.Weaken(40 SECONDS) return for(var/obj/item/bio_chip/mindshield/L in H) @@ -342,7 +342,7 @@ for(var/obj/item/bio_chip/traitor/T in H) if(T && T.implanted) qdel(T) - visible_message("[H] gets an eerie red glow in their eyes!") + H.visible_message("[H] gets an eerie red glow in their eyes!") var/datum/objective/protect/protect_objective = new protect_objective.target = M.mind diff --git a/code/modules/antagonists/vampire/vampire_subclasses.dm b/code/modules/antagonists/vampire/vampire_subclasses.dm index 250287927463..bddff6daeeab 100644 --- a/code/modules/antagonists/vampire/vampire_subclasses.dm +++ b/code/modules/antagonists/vampire/vampire_subclasses.dm @@ -23,95 +23,95 @@ /datum/vampire_subclass/umbrae name = "umbrae" - standard_powers = list(/obj/effect/proc_holder/spell/vampire/self/cloak = 150, - /obj/effect/proc_holder/spell/vampire/shadow_snare = 250, - /obj/effect/proc_holder/spell/vampire/soul_anchor = 250, - /obj/effect/proc_holder/spell/vampire/dark_passage = 400, - /obj/effect/proc_holder/spell/vampire/vamp_extinguish = 600, - /obj/effect/proc_holder/spell/vampire/shadow_boxing = 800) + standard_powers = list(/datum/spell/vampire/self/cloak = 150, + /datum/spell/vampire/shadow_snare = 250, + /datum/spell/vampire/soul_anchor = 250, + /datum/spell/vampire/dark_passage = 400, + /datum/spell/vampire/vamp_extinguish = 600, + /datum/spell/vampire/shadow_boxing = 800) fully_powered_abilities = list(/datum/vampire_passive/full, /datum/vampire_passive/vision/full, - /obj/effect/proc_holder/spell/vampire/self/eternal_darkness, + /datum/spell/vampire/self/eternal_darkness, /datum/vampire_passive/vision/xray) /datum/vampire_subclass/hemomancer name = "hemomancer" - standard_powers = list(/obj/effect/proc_holder/spell/vampire/self/vamp_claws = 150, - /obj/effect/proc_holder/spell/vampire/blood_tendrils = 250, - /obj/effect/proc_holder/spell/vampire/blood_barrier = 250, - /obj/effect/proc_holder/spell/ethereal_jaunt/blood_pool = 400, - /obj/effect/proc_holder/spell/vampire/predator_senses = 600, - /obj/effect/proc_holder/spell/vampire/blood_eruption = 800) + standard_powers = list(/datum/spell/vampire/self/vamp_claws = 150, + /datum/spell/vampire/blood_tendrils = 250, + /datum/spell/vampire/blood_barrier = 250, + /datum/spell/ethereal_jaunt/blood_pool = 400, + /datum/spell/vampire/predator_senses = 600, + /datum/spell/vampire/blood_eruption = 800) fully_powered_abilities = list(/datum/vampire_passive/full, /datum/vampire_passive/vision/full, - /obj/effect/proc_holder/spell/vampire/self/blood_spill) + /datum/spell/vampire/self/blood_spill) /datum/vampire_subclass/gargantua name = "gargantua" - standard_powers = list(/obj/effect/proc_holder/spell/vampire/self/blood_swell = 150, - /obj/effect/proc_holder/spell/vampire/self/blood_rush = 250, - /obj/effect/proc_holder/spell/vampire/self/stomp = 250, + standard_powers = list(/datum/spell/vampire/self/blood_swell = 150, + /datum/spell/vampire/self/blood_rush = 250, + /datum/spell/vampire/self/stomp = 250, /datum/vampire_passive/blood_swell_upgrade = 400, - /obj/effect/proc_holder/spell/vampire/self/overwhelming_force = 600, - /obj/effect/proc_holder/spell/vampire/charge = 800, - /obj/effect/proc_holder/spell/fireball/demonic_grasp = 800) + /datum/spell/vampire/self/overwhelming_force = 600, + /datum/spell/vampire/charge = 800, + /datum/spell/fireball/demonic_grasp = 800) fully_powered_abilities = list(/datum/vampire_passive/full, /datum/vampire_passive/vision/full, - /obj/effect/proc_holder/spell/vampire/arena) + /datum/spell/vampire/arena) improved_rejuv_healing = TRUE /datum/vampire_subclass/dantalion name = "dantalion" - standard_powers = list(/obj/effect/proc_holder/spell/vampire/enthrall = 150, - /obj/effect/proc_holder/spell/vampire/thrall_commune = 150, - /obj/effect/proc_holder/spell/vampire/pacify = 250, - /obj/effect/proc_holder/spell/vampire/switch_places = 250, - /obj/effect/proc_holder/spell/vampire/self/decoy = 400, + standard_powers = list(/datum/spell/vampire/enthrall = 150, + /datum/spell/vampire/thrall_commune = 150, + /datum/spell/vampire/pacify = 250, + /datum/spell/vampire/switch_places = 250, + /datum/spell/vampire/self/decoy = 400, /datum/vampire_passive/increment_thrall_cap = 400, - /obj/effect/proc_holder/spell/vampire/rally_thralls = 600, + /datum/spell/vampire/rally_thralls = 600, /datum/vampire_passive/increment_thrall_cap/two = 600, - /obj/effect/proc_holder/spell/vampire/self/share_damage = 800) + /datum/spell/vampire/self/share_damage = 800) fully_powered_abilities = list(/datum/vampire_passive/full, - /obj/effect/proc_holder/spell/vampire/hysteria, + /datum/spell/vampire/hysteria, /datum/vampire_passive/vision/full, /datum/vampire_passive/increment_thrall_cap/three) /datum/vampire_subclass/ancient name = "ancient" - standard_powers = list(/obj/effect/proc_holder/spell/vampire/self/vamp_claws, - /obj/effect/proc_holder/spell/vampire/self/blood_swell, - /obj/effect/proc_holder/spell/vampire/self/cloak, - /obj/effect/proc_holder/spell/vampire/enthrall, - /obj/effect/proc_holder/spell/vampire/thrall_commune, - /obj/effect/proc_holder/spell/vampire/blood_tendrils, - /obj/effect/proc_holder/spell/vampire/blood_barrier, - /obj/effect/proc_holder/spell/vampire/self/blood_rush, - /obj/effect/proc_holder/spell/vampire/self/stomp, - /obj/effect/proc_holder/spell/vampire/charge, - /obj/effect/proc_holder/spell/vampire/shadow_snare, - /obj/effect/proc_holder/spell/vampire/soul_anchor, - /obj/effect/proc_holder/spell/vampire/pacify, - /obj/effect/proc_holder/spell/vampire/switch_places, - /obj/effect/proc_holder/spell/ethereal_jaunt/blood_pool, + standard_powers = list(/datum/spell/vampire/self/vamp_claws, + /datum/spell/vampire/self/blood_swell, + /datum/spell/vampire/self/cloak, + /datum/spell/vampire/enthrall, + /datum/spell/vampire/thrall_commune, + /datum/spell/vampire/blood_tendrils, + /datum/spell/vampire/blood_barrier, + /datum/spell/vampire/self/blood_rush, + /datum/spell/vampire/self/stomp, + /datum/spell/vampire/charge, + /datum/spell/vampire/shadow_snare, + /datum/spell/vampire/soul_anchor, + /datum/spell/vampire/pacify, + /datum/spell/vampire/switch_places, + /datum/spell/ethereal_jaunt/blood_pool, /datum/vampire_passive/blood_swell_upgrade, - /obj/effect/proc_holder/spell/vampire/dark_passage, - /obj/effect/proc_holder/spell/vampire/self/decoy, - /obj/effect/proc_holder/spell/vampire/blood_eruption, - /obj/effect/proc_holder/spell/vampire/predator_senses, - /obj/effect/proc_holder/spell/vampire/self/overwhelming_force, - /obj/effect/proc_holder/spell/vampire/vamp_extinguish, - /obj/effect/proc_holder/spell/vampire/rally_thralls, - /obj/effect/proc_holder/spell/vampire/self/share_damage, - /obj/effect/proc_holder/spell/fireball/demonic_grasp, - /obj/effect/proc_holder/spell/vampire/shadow_boxing, + /datum/spell/vampire/dark_passage, + /datum/spell/vampire/self/decoy, + /datum/spell/vampire/blood_eruption, + /datum/spell/vampire/predator_senses, + /datum/spell/vampire/self/overwhelming_force, + /datum/spell/vampire/vamp_extinguish, + /datum/spell/vampire/rally_thralls, + /datum/spell/vampire/self/share_damage, + /datum/spell/fireball/demonic_grasp, + /datum/spell/vampire/shadow_boxing, /datum/vampire_passive/full, /datum/vampire_passive/vision/full, - /obj/effect/proc_holder/spell/vampire/self/blood_spill, - /obj/effect/proc_holder/spell/vampire/arena, - /obj/effect/proc_holder/spell/vampire/self/eternal_darkness, - /obj/effect/proc_holder/spell/vampire/hysteria, - /obj/effect/proc_holder/spell/vampire/raise_vampires, + /datum/spell/vampire/self/blood_spill, + /datum/spell/vampire/arena, + /datum/spell/vampire/self/eternal_darkness, + /datum/spell/vampire/hysteria, + /datum/spell/vampire/raise_vampires, /datum/vampire_passive/vision/xray) improved_rejuv_healing = TRUE thrall_cap = 150 // can thrall high pop diff --git a/code/modules/antagonists/wizard/datum_apprentice.dm b/code/modules/antagonists/wizard/datum_apprentice.dm index a638a34c2da9..3935e7d9e820 100644 --- a/code/modules/antagonists/wizard/datum_apprentice.dm +++ b/code/modules/antagonists/wizard/datum_apprentice.dm @@ -45,28 +45,28 @@ var/list/messages = list() switch(class_type) if("fire") - new_wiz.mind.AddSpell(new /obj/effect/proc_holder/spell/fireball/apprentice(null)) - new_wiz.mind.AddSpell(new /obj/effect/proc_holder/spell/sacred_flame(null)) + new_wiz.mind.AddSpell(new /datum/spell/fireball/apprentice(null)) + new_wiz.mind.AddSpell(new /datum/spell/sacred_flame(null)) ADD_TRAIT(new_wiz, TRAIT_RESISTHEAT, MAGIC_TRAIT) ADD_TRAIT(new_wiz, TRAIT_RESISTHIGHPRESSURE, MAGIC_TRAIT) - new_wiz.mind.AddSpell(new /obj/effect/proc_holder/spell/ethereal_jaunt(null)) + new_wiz.mind.AddSpell(new /datum/spell/ethereal_jaunt(null)) new_wiz.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(new_wiz), SLOT_HUD_SHOES) new_wiz.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe/red(new_wiz), SLOT_HUD_OUTER_SUIT) new_wiz.equip_to_slot_or_del(new /obj/item/clothing/head/wizard/red(new_wiz), SLOT_HUD_HEAD) messages += "Your service has not gone unrewarded. Under the tutelage of [my_teacher.real_name], you've acquired proficiency in the fundamentals of Firebending, enabling you to cast spells like Fireball, Sacred Flame, and Ethereal Jaunt." messages += "You are immune to fire, but you are NOT immune to the explosions caused by your fireballs. Neither is your teacher, for that matter. Be careful!" if("translocation") - new_wiz.mind.AddSpell(new /obj/effect/proc_holder/spell/area_teleport/teleport(null)) - new_wiz.mind.AddSpell(new /obj/effect/proc_holder/spell/turf_teleport/blink(null)) - new_wiz.mind.AddSpell(new /obj/effect/proc_holder/spell/ethereal_jaunt(null)) + new_wiz.mind.AddSpell(new /datum/spell/area_teleport/teleport(null)) + new_wiz.mind.AddSpell(new /datum/spell/turf_teleport/blink(null)) + new_wiz.mind.AddSpell(new /datum/spell/ethereal_jaunt(null)) new_wiz.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(new_wiz), SLOT_HUD_SHOES) new_wiz.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(new_wiz), SLOT_HUD_OUTER_SUIT) new_wiz.equip_to_slot_or_del(new /obj/item/clothing/head/wizard(new_wiz), SLOT_HUD_HEAD) messages += "Your service has not gone unrewarded. While studying under [my_teacher.real_name], you mastered reality-bending mobility spells, allowing you to cast Teleport, Blink, and Ethereal Jaunt." if("restoration") - new_wiz.mind.AddSpell(new /obj/effect/proc_holder/spell/charge(null)) - new_wiz.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe/knock(null)) - var/obj/effect/proc_holder/spell/return_to_teacher/S = new /obj/effect/proc_holder/spell/return_to_teacher(null) + new_wiz.mind.AddSpell(new /datum/spell/charge(null)) + new_wiz.mind.AddSpell(new /datum/spell/aoe/knock(null)) + var/datum/spell/return_to_teacher/S = new /datum/spell/return_to_teacher(null) S.teacher = my_teacher.mind new_wiz.mind.AddSpell(S) new_wiz.equip_to_slot_or_del(new /obj/item/gun/magic/staff/healing(new_wiz), SLOT_HUD_RIGHT_HAND) @@ -76,19 +76,19 @@ messages += "Your service has not gone unrewarded. Under the guidance of [my_teacher.real_name], you've acquired life-saving survival spells. You can now cast Charge and Knock, and possess the ability to teleport back to your mentor." messages += "Your Charge spell can be used to recharge your Staff of Healing or reduce the cooldowns of your teacher, if you are grabbing them with empty hands." if("stealth") - new_wiz.mind.AddSpell(new /obj/effect/proc_holder/spell/mind_transfer(null)) - new_wiz.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe/knock(null)) - new_wiz.mind.AddSpell(new /obj/effect/proc_holder/spell/fireball/toolbox(null)) - new_wiz.mind.AddSpell(new /obj/effect/proc_holder/spell/disguise_self(null)) + new_wiz.mind.AddSpell(new /datum/spell/mind_transfer(null)) + new_wiz.mind.AddSpell(new /datum/spell/aoe/knock(null)) + new_wiz.mind.AddSpell(new /datum/spell/fireball/toolbox(null)) + new_wiz.mind.AddSpell(new /datum/spell/disguise_self(null)) new_wiz.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(new_wiz), SLOT_HUD_SHOES) new_wiz.equip_to_slot_or_del(new /obj/item/clothing/mask/gas(new_wiz), SLOT_HUD_WEAR_MASK) new_wiz.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/yellow(new_wiz), SLOT_HUD_GLOVES) new_wiz.equip_to_slot_or_del(new /obj/item/storage/belt/utility/full(new_wiz), SLOT_HUD_BELT) messages += "Your service has not gone unrewarded. Under the mentorship of [my_teacher.real_name], you've mastered stealthy, robeless spells. You can now cast Mindswap, Knock, Homing Toolbox, and Disguise Self without the need for wizard robes." if("honk") - new_wiz.mind.AddSpell(new /obj/effect/proc_holder/spell/touch/banana/apprentice(null)) - new_wiz.mind.AddSpell(new /obj/effect/proc_holder/spell/ethereal_jaunt(null)) - new_wiz.mind.AddSpell(new /obj/effect/proc_holder/spell/summonitem(null)) + new_wiz.mind.AddSpell(new /datum/spell/touch/banana/apprentice(null)) + new_wiz.mind.AddSpell(new /datum/spell/ethereal_jaunt(null)) + new_wiz.mind.AddSpell(new /datum/spell/summonitem(null)) new_wiz.equip_to_slot_or_del(new /obj/item/gun/magic/staff/slipping(new_wiz), SLOT_HUD_RIGHT_HAND) new_wiz.equip_to_slot_or_del(new /obj/item/clothing/shoes/clown_shoes/magical/nodrop(new_wiz), SLOT_HUD_SHOES) new_wiz.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe/clown(new_wiz), SLOT_HUD_OUTER_SUIT) diff --git a/code/modules/awaymissions/mission_code/ghost_role_spawners/golems.dm b/code/modules/awaymissions/mission_code/ghost_role_spawners/golems.dm index eec5f0faa7af..6ca240ac99e2 100644 --- a/code/modules/awaymissions/mission_code/ghost_role_spawners/golems.dm +++ b/code/modules/awaymissions/mission_code/ghost_role_spawners/golems.dm @@ -135,8 +135,8 @@ else H.rename_character(null, name) if(is_species(H, /datum/species/golem/tranquillite) && H.mind) - H.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe/conjure/build/mime_wall(null)) - H.mind.AddSpell(new /obj/effect/proc_holder/spell/mime/speak(null)) + H.mind.AddSpell(new /datum/spell/aoe/conjure/build/mime_wall(null)) + H.mind.AddSpell(new /datum/spell/mime/speak(null)) H.mind.miming = TRUE if(has_owner) diff --git a/code/modules/awaymissions/mission_code/ruins/oldstation.dm b/code/modules/awaymissions/mission_code/ruins/oldstation.dm index ce6a367de24a..6561f0bc5fe2 100644 --- a/code/modules/awaymissions/mission_code/ruins/oldstation.dm +++ b/code/modules/awaymissions/mission_code/ruins/oldstation.dm @@ -299,7 +299,7 @@ desc = "A very large bluespace engine used to propel very large ships." bound_width = 64 bound_height = 64 - appearance_flags = 0 + appearance_flags = LONG_GLIDE // areas //Ruin of ancient Space Station diff --git a/code/modules/awaymissions/mission_code/ruins/wizardcrash.dm b/code/modules/awaymissions/mission_code/ruins/wizardcrash.dm index e39220515d8f..c872499557dc 100644 --- a/code/modules/awaymissions/mission_code/ruins/wizardcrash.dm +++ b/code/modules/awaymissions/mission_code/ruins/wizardcrash.dm @@ -2,10 +2,10 @@ /obj/item/paper/fluff/ruins/wizardcrash name = "Mission Briefing" - info = "To the Magnificent Z.A.P.
A small mining base has been created within our territory by wandless scum. Send them a message from the wizard federation they will not forget. I know your kind is rather fragile, but a group of lightly armed miners should not pose any threat to you at all. Just be warned they have a security cyborg for self defence, you might want to tune your spells to that threat. I look forward to hearing of your success.
Grand Magus Abra the Wonderous" + info = "To the Magnificent Z.A.P.
A small mining base has been created within our territory by wandless scum. Send them a message from the wizard federation they will not forget. I know your kind is rather fragile, but a group of lightly armed miners should not pose any threat to you at all. Just be warned they have a security cyborg for self defence, you might want to tune your spells to that threat. I look forward to hearing of your success.
Grand Magus Abra the Wonderous" /obj/item/spellbook/oneuse/emp - spell = /obj/effect/proc_holder/spell/emplosion/disable_tech + spell = /datum/spell/emplosion/disable_tech spellname = "Disable Technology" icon_state = "bookcharge" //it's a lightning bolt, seems appropriate enough desc = "For the tech-hating wizard on the go." diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index bc0de582ba83..d2412ed6d547 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -590,6 +590,9 @@ if(check_randomizer(connectiontopic)) return + var/client_address = address + if(!client_address) // Localhost can sometimes have no address set + client_address = "127.0.0.1" if(sql_id) //Just the standard check to see if it's actually a number @@ -598,10 +601,6 @@ if(!isnum(sql_id)) return // Return here because if we somehow didnt pull a number from an INT column, EVERYTHING is breaking - var/client_address = address - if(!client_address) // Localhost can sometimes have no address set - client_address = "127.0.0.1" - //Player already identified previously, we need to just update the 'lastseen', 'ip' and 'computer_id' variables var/datum/db_query/query_update = SSdbcore.NewQuery("UPDATE player SET lastseen=NOW(), ip=:sql_ip, computerid=:sql_cid, lastadminrank=:sql_ar WHERE id=:sql_id", list( "sql_ip" = client_address, @@ -622,7 +621,7 @@ //New player!! Need to insert all the stuff var/datum/db_query/query_insert = SSdbcore.NewQuery("INSERT INTO player (id, ckey, firstseen, lastseen, ip, computerid, lastadminrank) VALUES (null, :ckey, Now(), Now(), :ip, :cid, :rank)", list( "ckey" = ckey, - "ip" = address, + "ip" = client_address, "cid" = computer_id, "rank" = admin_rank )) diff --git a/code/modules/client/login_processing/20-load_characters.dm b/code/modules/client/login_processing/20-load_characters.dm index e3508aecbbe2..96bcf98df40a 100644 --- a/code/modules/client/login_processing/20-load_characters.dm +++ b/code/modules/client/login_processing/20-load_characters.dm @@ -61,6 +61,7 @@ custom_emotes, physique, height, + cyborg_brain_type, tts_seed FROM characters WHERE ckey=:ckey"}, list( "ckey" = C.ckey diff --git a/code/modules/client/preference/character.dm b/code/modules/client/preference/character.dm index f4a8f1fc7055..7557b051e87a 100644 --- a/code/modules/client/preference/character.dm +++ b/code/modules/client/preference/character.dm @@ -38,7 +38,8 @@ var/species = "Human" var/language = "None" //Secondary language var/autohiss_mode = AUTOHISS_OFF //Species autohiss level. OFF, BASIC, FULL. - + /// If a spawned cyborg should have an MMI, a positronic, or a robobrain. MMI by default + var/cyborg_brain_type = MMI_BORG /// The body accessory name of the mob (e.g. wings, tail). var/body_accessory = null @@ -192,6 +193,7 @@ hair_gradient_colour=:h_grad_colour, hair_gradient_alpha=:h_grad_alpha, custom_emotes=:custom_emotes, + cyborg_brain_type=:cyborg_brain_type, tts_seed=:tts_seed WHERE ckey=:ckey AND slot=:slot"}, list( @@ -252,6 +254,7 @@ "h_grad_colour" = h_grad_colour, "h_grad_alpha" = h_grad_alpha, "custom_emotes" = json_encode(custom_emotes), + "cyborg_brain_type" = cyborg_brain_type, "tts_seed" = tts_seed, // SS220 EDIT ADDITION - TTS220 "ckey" = C.ckey, "slot" = slot_number @@ -293,7 +296,7 @@ player_alt_titles, disabilities, organ_data, rlimb_data, nanotrasen_relation, physique, height, speciesprefs, socks, body_accessory, gear, autohiss, - hair_gradient, hair_gradient_offset, hair_gradient_colour, hair_gradient_alpha, custom_emotes, tts_seed) + hair_gradient, hair_gradient_offset, hair_gradient_colour, hair_gradient_alpha, custom_emotes, cyborg_brain_type, tts_seed) VALUES (:ckey, :slot, :metadata, :name, :be_random_name, :gender, :age, :species, :language, @@ -320,7 +323,7 @@ :playertitlelist, :disabilities, :organ_list, :rlimb_list, :nanotrasen_relation, :physique, :height, :speciesprefs, :socks, :body_accessory, :gearlist, :autohiss_mode, - :h_grad_style, :h_grad_offset, :h_grad_colour, :h_grad_alpha, :custom_emotes, :tts_seed) + :h_grad_style, :h_grad_offset, :h_grad_colour, :h_grad_alpha, :custom_emotes, :cyborg_brain_type, :tts_seed) "}, list( // This has too many params for anyone to look at this without going insae "ckey" = C.ckey, @@ -381,6 +384,7 @@ "h_grad_colour" = h_grad_colour, "h_grad_alpha" = h_grad_alpha, "custom_emotes" = json_encode(custom_emotes), + "cyborg_brain_type" = cyborg_brain_type, "tts_seed" = tts_seed // SS220 EDIT ADDITION - TTS220 )) @@ -469,7 +473,8 @@ var/custom_emotes_tmp = query.item[55] physique = query.item[56] height = query.item[57] - tts_seed = query.item[58] // SS220 EDIT ADDITION - TTS220 + cyborg_brain_type = query.item[58] + tts_seed = query.item[59] // SS220 EDIT ADDITION - TTS220 //Sanitize var/datum/species/SP = GLOB.all_species[species] @@ -555,7 +560,7 @@ loadout_gear = sanitize_json(loadout_gear) custom_emotes_tmp = sanitize_json(custom_emotes_tmp) custom_emotes = init_custom_emotes(custom_emotes_tmp) - + cyborg_brain_type = sanitize_inlist(cyborg_brain_type, GLOB.borg_brain_choices, initial(cyborg_brain_type)) if(!player_alt_titles) player_alt_titles = new() if(!organ_data) diff --git a/code/modules/client/preference/link_processing.dm b/code/modules/client/preference/link_processing.dm index f17152617019..0bcf09cfcfa3 100644 --- a/code/modules/client/preference/link_processing.dm +++ b/code/modules/client/preference/link_processing.dm @@ -872,7 +872,9 @@ active_character.organ_data[organ] = null if("Cybernetic") active_character.organ_data[organ] = "cybernetic" - + if("cyborg_brain_type") + var/brain_type = tgui_input_list(user, "What type of brain would you like to have as a cyborg?", "Cyborg Brain Type", GLOB.borg_brain_choices) + active_character.cyborg_brain_type = brain_type if("clientfps") var/version_message if(user.client && user.client.byond_version < 511) diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm index 13e9591e3155..929826a87625 100644 --- a/code/modules/client/preference/preferences.dm +++ b/code/modules/client/preference/preferences.dm @@ -381,6 +381,8 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts if(!ind) dat += "\[...\]
" else dat += "
" + dat += "

Cyborg Brain Type

" + dat += "[active_character.cyborg_brain_type]
" dat += "

Clothing

" if(S.clothing_flags & HAS_UNDERWEAR) dat += "Underwear:[active_character.underwear]
" diff --git a/code/modules/clothing/head/collectable.dm b/code/modules/clothing/head/collectable.dm index 0e8e7476e5f0..76450a01cac4 100644 --- a/code/modules/clothing/head/collectable.dm +++ b/code/modules/clothing/head/collectable.dm @@ -47,7 +47,7 @@ /obj/item/clothing/head/collectable/captain name = "collectable captain's hat" - desc = "A Collectable Hat that'll make you look just like a real comdom!" + desc = "A Collectable Hat that'll make you look just like a real captain!" icon_state = "captain_hat" item_state = "captain_hat" dog_fashion = /datum/dog_fashion/head/captain diff --git a/code/modules/clothing/shoes/misc_shoes.dm b/code/modules/clothing/shoes/misc_shoes.dm index 064c1ceeed58..a7707bb00622 100644 --- a/code/modules/clothing/shoes/misc_shoes.dm +++ b/code/modules/clothing/shoes/misc_shoes.dm @@ -85,6 +85,10 @@ slowdown = SHOES_SLOWDOWN+1 item_color = "clown" var/enabled_waddle = TRUE + // "Dyeable" in this case is a bit of an understatement, washing these + // with a crayon will give them the appearance and name of normal + // shoes, but the functionality of clown shoes. + dyeable = TRUE /obj/item/clothing/shoes/clown_shoes/Initialize(mapload) . = ..() @@ -116,11 +120,13 @@ enabled_waddle = FALSE /obj/item/clothing/shoes/clown_shoes/nodrop + dyeable = FALSE flags = NODROP /obj/item/clothing/shoes/clown_shoes/magical name = "magical clown shoes" desc = "Standard-issue shoes of the wizarding class clown. Damn they're huge! And powerful! Somehow." + dyeable = FALSE magical = TRUE /obj/item/clothing/shoes/clown_shoes/magical/nodrop @@ -131,6 +137,7 @@ actions_types = list(/datum/action/item_action/slipping) enabled_waddle = FALSE slowdown = 0 + dyeable = FALSE var/slide_distance = 6 var/recharging_rate = 8 SECONDS var/recharging_time = 0 @@ -332,6 +339,7 @@ icon_override = 'icons/goonstation/mob/clothing/feet.dmi' lefthand_file = 'icons/goonstation/mob/inhands/clothing_lefthand.dmi' righthand_file = 'icons/goonstation/mob/inhands/clothing_righthand.dmi' + dyeable = FALSE /obj/item/clothing/shoes/singery name = "yellow performer's boots" diff --git a/code/modules/error_handler/error_handler.dm b/code/modules/error_handler/error_handler.dm index e0615f0a46cb..2ecb9e20e863 100644 --- a/code/modules/error_handler/error_handler.dm +++ b/code/modules/error_handler/error_handler.dm @@ -72,13 +72,13 @@ GLOBAL_VAR_INIT(total_runtimes_skipped, 0) var/skipcount = abs(GLOB.error_cooldown[erroruid]) - 1 GLOB.error_cooldown[erroruid] = 0 if(skipcount > 0) - log_world("\[[time_stamp()]] Skipped [skipcount] runtimes in [e.file],[e.line].") + log_world("\[[time_stamp()]] Skipped [skipcount] runtimes in [e.file]:[e.line].") GLOB.error_cache.logError(e, skipCount = skipcount) GLOB.error_last_seen[erroruid] = world.time GLOB.error_cooldown[erroruid] = cooldown // This line will log a runtime summary to a file which can be publicly distributed without sending player data - log_runtime_summary("Runtime in [e.file],[e.line]: [e]") + log_runtime_summary("Runtime in [e.file]:[e.line]: [e]") // The detailed error info needs some tweaking to make it look nice var/list/srcinfo = null @@ -131,8 +131,8 @@ GLOBAL_VAR_INIT(total_runtimes_skipped, 0) desclines += " (This error will now be silenced for [ERROR_SILENCE_TIME / 600] minutes)" // Now to actually output the error info... - log_world("\[[time_stamp()]] Runtime in [e.file],[e.line]: [e]") - log_runtime_txt("Runtime in [e.file],[e.line]: [e]") + log_world("\[[time_stamp()]] Runtime in [e.file]:[e.line]: [e]") + log_runtime_txt("Runtime in [e.file],[e.line]: [e]") // All other runtimes show as [e.file]:[e.line] except this one to prevent fuckery with analyzing both old and new runtimes. runtime.log should stay in the [e.file],[e.line] format. for(var/line in desclines) log_world(line) log_runtime_txt(line) diff --git a/code/modules/error_handler/error_viewer.dm b/code/modules/error_handler/error_viewer.dm index a6a0a7276656..63dd60a8b806 100644 --- a/code/modules/error_handler/error_viewer.dm +++ b/code/modules/error_handler/error_viewer.dm @@ -117,7 +117,7 @@ GLOBAL_DATUM(error_cache, /datum/ErrorViewer/ErrorCache) // from the same source hasn't been shown too recently if(error_source.next_message_at <= world.time) var/const/viewtext = "\[view]" // Nesting these in other brackets went poorly - log_debug("Runtime in [e.file],[e.line]: [html_encode(e.name)] [error_entry.makeLink(viewtext)]") + log_debug("Runtime in [e.file]:[e.line]: [html_encode(e.name)] [error_entry.makeLink(viewtext)]") error_source.next_message_at = world.time + ERROR_MSG_DELAY /datum/ErrorViewer/ErrorSource @@ -128,7 +128,7 @@ GLOBAL_DATUM(error_cache, /datum/ErrorViewer/ErrorCache) if(!istype(e)) name = "\[[time_stamp()]] Uncaught exceptions" return - name = "\[[time_stamp()]] Runtime in [e.file],[e.line]: [e]" + name = "\[[time_stamp()]] Runtime in [e.file]:[e.line]: [e]" /datum/ErrorViewer/ErrorSource/showTo(user, datum/ErrorViewer/back_to, linear) if(!istype(back_to)) @@ -156,10 +156,10 @@ GLOBAL_DATUM(error_cache, /datum/ErrorViewer/ErrorCache) name = "\[[time_stamp()]] Uncaught exception: [e]" return if(skipCount) - name = "\[[time_stamp()]] Skipped [skipCount] runtimes in [e.file],[e.line]." + name = "\[[time_stamp()]] Skipped [skipCount] runtimes in [e.file]:[e.line]." isSkipCount = TRUE return - name = "\[[time_stamp()]] Runtime in [e.file],[e.line]: [e]" + name = "\[[time_stamp()]] Runtime in [e.file]:[e.line]: [e]" exc = e if(istype(desclines)) for(var/line in desclines) diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm index 0a1ff431e21b..61f9b450ed53 100644 --- a/code/modules/events/spacevine.dm +++ b/code/modules/events/spacevine.dm @@ -17,11 +17,11 @@ // Make the event start fun - give the vine a random hostile mutation if(SC.vines.len) SV = SC.vines[1] - var/list/mutations = SC.mutations_list.Copy() - while(mutations.len) + var/list/mutations = subtypesof(/datum/spacevine_mutation) + while(mutations) var/datum/spacevine_mutation/SM = pick_n_take(mutations) - if(SM.quality == SPACEVINE_MUTATION_NEGATIVE && !SM.nofun) - SM.add_mutation_to_vinepiece(SV) + if(initial(SM.quality) == SPACEVINE_MUTATION_NEGATIVE && !initial(SM.nofun)) + SV.add_mutation(SM) break mutations.Cut() mutations = null @@ -35,19 +35,6 @@ // For stuff that isn't fun as a random-event vine var/nofun = FALSE -/datum/spacevine_mutation/proc/add_mutation_to_vinepiece(obj/structure/spacevine/holder) - holder.mutations |= src - holder.color = hue - -/datum/spacevine_mutation/proc/remove_mutation_from_vinepiece(obj/structure/spacevine/holder) - holder.mutations -= src - var/datum/spacevine_mutation/oldmutation - if(holder.mutations.len) - oldmutation = pick(holder.mutations) - holder.color = oldmutation.hue - else - holder.color = "" - /datum/spacevine_mutation/proc/process_mutation(obj/structure/spacevine/holder) return @@ -91,11 +78,6 @@ return -/datum/spacevine_mutation/space_covering - name = "space protective" - hue = "#aa77aa" - quality = SPACEVINE_MUTATION_POSITIVE - /turf/simulated/floor/vines color = "#aa77aa" icon_state = "vinefloor" @@ -139,6 +121,9 @@ SV.wither() /datum/spacevine_mutation/space_covering + name = "space protective" + hue = "#aa77aa" + quality = SPACEVINE_MUTATION_POSITIVE var/static/list/coverable_turfs /datum/spacevine_mutation/space_covering/New() @@ -181,7 +166,7 @@ // Lose bluespace upon piercing a single tile, and drop it from our own mutations too // Representing a loss in "high potential" // also conveniently prevents this from spreading too crazily - remove_mutation_from_vinepiece(holder) + holder.remove_mutation(src.type) holder.master.spawn_spacevine_piece(target, holder) playsound(holder, 'sound/misc/interference.ogg', 50, 1) . = TRUE @@ -421,9 +406,9 @@ /obj/structure/spacevine/examine(mob/user) . = ..() var/text = "This one is a" - if(mutations.len) + if(length(mutations)) for(var/A in mutations) - var/datum/spacevine_mutation/SM = A + var/datum/spacevine_mutation/SM = mutations[A] text += " [SM.name]" else text += " normal" @@ -431,20 +416,23 @@ . += text /obj/structure/spacevine/proc/wither() - for(var/datum/spacevine_mutation/SM in mutations) + for(var/SM_type in mutations) + var/datum/spacevine_mutation/SM = mutations[SM_type] SM.on_death(src) qdel(src) /obj/structure/spacevine/Destroy() - for(var/datum/spacevine_mutation/SM in mutations) + for(var/SM_type in mutations) + var/datum/spacevine_mutation/SM = mutations[SM_type] SM.on_deletion(src) if(master) master.vines -= src master.growth_queue -= src if(!master.vines.len) var/obj/item/seeds/kudzu/KZ = new(loc) - KZ.mutations |= mutations + for(var/mutation in mutations) + KZ.mutations += mutation KZ.set_potency(10 ** sqrt(master.mutativeness)) KZ.set_production(10 - (master.spread_cap / 10)) qdel(master) @@ -456,12 +444,21 @@ return ..() /obj/structure/spacevine/proc/add_mutation(datum/spacevine_mutation/mutation) - mutations |= mutation - color = mutation.hue + if(!mutations[mutation]) + mutations[mutation] = new mutation + color = mutation.hue + +/obj/structure/spacevine/proc/remove_mutation(datum/spacevine_mutation/mutation) + mutations -= mutation + if(length(mutations)) + var/oldmutation_type = pick(mutations) + var/datum/spacevine_mutation/oldmutation = mutations[oldmutation_type] + color = oldmutation.hue /obj/structure/spacevine/proc/on_chem_effect(datum/reagent/R) var/override = 0 - for(var/datum/spacevine_mutation/SM in mutations) + for(var/SM_type in mutations) + var/datum/spacevine_mutation/SM = mutations[SM_type] override += SM.on_chem(src, R) if(!override && istype(R, /datum/reagent/glyphosate)) if(prob(50)) @@ -469,7 +466,8 @@ /obj/structure/spacevine/proc/eat(mob/eater) var/override = 0 - for(var/datum/spacevine_mutation/SM in mutations) + for(var/SM_type in mutations) + var/datum/spacevine_mutation/SM = mutations[SM_type] override += SM.on_eat(src, eater) if(!override) if(prob(10)) @@ -493,7 +491,8 @@ if(I.damtype == BURN) damage_dealt *= 4 - for(var/datum/spacevine_mutation/SM in mutations) + for(var/SM_type in mutations) + var/datum/spacevine_mutation/SM = mutations[SM_type] damage_dealt = SM.on_hit(src, user, I, damage_dealt) //on_hit now takes override damage as arg and returns new value for other mutations to permutate further take_damage(damage_dealt, I.damtype, MELEE, 1) @@ -512,11 +511,13 @@ /obj/structure/spacevine/Crossed(mob/crosser, oldloc) if(isliving(crosser)) - for(var/datum/spacevine_mutation/SM in mutations) + for(var/SM_type in mutations) + var/datum/spacevine_mutation/SM = mutations[SM_type] SM.on_cross(src, crosser) /obj/structure/spacevine/attack_hand(mob/user) - for(var/datum/spacevine_mutation/SM in mutations) + for(var/SM_type in mutations) + var/datum/spacevine_mutation/SM = mutations[SM_type] SM.on_hit(src, user) user_unbuckle_mob(user, user) @@ -529,14 +530,12 @@ var/list/growth_queue = list() var/spread_multiplier = 5 var/spread_cap = 30 - var/list/mutations_list = list() var/mutativeness = 1 /obj/structure/spacevine_controller/New(loc, list/muts, potency, production) color = "#ffffff" spawn_spacevine_piece(loc, null, muts) START_PROCESSING(SSobj, src) - init_subtypes(/datum/spacevine_mutation/, mutations_list) if(potency != null && potency > 0) // 1 mutativeness at 10 potency // 4 mutativeness at 100 potency @@ -571,20 +570,21 @@ growth_queue += SV vines += SV SV.master = src - if(muts && muts.len) - for(var/datum/spacevine_mutation/M in muts) - M.add_mutation_to_vinepiece(SV) + if(length(muts)) + for(var/M in muts) + SV.add_mutation(M) return if(parent) SV.mutations |= parent.mutations SV.color = parent.color if(prob(mutativeness)) - var/list/random_mutations_picked = mutations_list - SV.mutations - if(random_mutations_picked.len) - var/datum/spacevine_mutation/randmut = pick(random_mutations_picked) - randmut.add_mutation_to_vinepiece(SV) + var/list/random_mutation_candidates = subtypesof(/datum/spacevine_mutation) - SV.mutations + if(length(random_mutation_candidates)) + var/datum/spacevine_mutation/randmut = pick(random_mutation_candidates) + SV.add_mutation(randmut) - for(var/datum/spacevine_mutation/SM in SV.mutations) + for(var/SM_type in SV.mutations) + var/datum/spacevine_mutation/SM = SV.mutations[SM_type] SM.on_birth(SV) /obj/structure/spacevine_controller/process() @@ -607,7 +607,8 @@ i++ queue_end += SV growth_queue -= SV - for(var/datum/spacevine_mutation/SM in SV.mutations) + for(var/SM_type in SV.mutations) + var/datum/spacevine_mutation/SM = SV.mutations[SM_type] SM.process_mutation(SV) if(SV.energy < 2) //If tile isn't fully grown if(prob(20)) @@ -631,7 +632,8 @@ icon_state = pick("Hvy1", "Hvy2", "Hvy3") energy = 2 - for(var/datum/spacevine_mutation/SM in mutations) + for(var/SM_type in mutations) + var/datum/spacevine_mutation/SM = mutations[SM_type] SM.on_grow(src) /obj/structure/spacevine/proc/entangle_mob() @@ -645,7 +647,8 @@ /obj/structure/spacevine/proc/entangle(mob/living/V) if(!V || isvineimmune(V)) return - for(var/datum/spacevine_mutation/SM in mutations) + for(var/SM_type in mutations) + var/datum/spacevine_mutation/SM = mutations[SM_type] SM.on_buckle(src, V) if((V.stat != DEAD) && (V.buckled != src)) //not dead or captured to_chat(V, "The vines [pick("wind", "tangle", "tighten")] around you!") @@ -654,14 +657,16 @@ /obj/structure/spacevine/proc/spread() var/list/dir_list = GLOB.cardinal.Copy() var/spread_search = FALSE // Whether to exhaustive search all 4 cardinal dirs for an open direction - for(var/datum/spacevine_mutation/SM in mutations) + for(var/SM_type in mutations) + var/datum/spacevine_mutation/SM = mutations[SM_type] spread_search |= SM.on_search(src) while(dir_list.len) var/direction = pick(dir_list) dir_list -= direction var/turf/stepturf = get_step(src,direction) var/spread_success = FALSE - for(var/datum/spacevine_mutation/SM in mutations) + for(var/SM_type in mutations) + var/datum/spacevine_mutation/SM = mutations[SM_type] spread_success |= SM.on_spread(src, stepturf) // If this returns 1, spreading succeeded if(!locate(/obj/structure/spacevine, stepturf)) // snowflake for space turf, but space turf is super common and a big deal @@ -674,7 +679,8 @@ /obj/structure/spacevine/ex_act(severity) var/i - for(var/datum/spacevine_mutation/SM in mutations) + for(var/SM_type in mutations) + var/datum/spacevine_mutation/SM = mutations[SM_type] i += SM.on_explosion(severity, src) if(!i && prob(100/severity)) wither() @@ -682,7 +688,8 @@ /obj/structure/spacevine/temperature_expose(null, temp, volume) ..() var/override = 0 - for(var/datum/spacevine_mutation/SM in mutations) + for(var/SM_type in mutations) + var/datum/spacevine_mutation/SM = mutations[SM_type] override += SM.process_temperature(src, temp, volume) if(!override) wither() diff --git a/code/modules/food_and_drinks/food/foods/baked_goods.dm b/code/modules/food_and_drinks/food/foods/baked_goods.dm index a4ab2d626ba3..903e25d32db8 100644 --- a/code/modules/food_and_drinks/food/foods/baked_goods.dm +++ b/code/modules/food_and_drinks/food/foods/baked_goods.dm @@ -25,6 +25,7 @@ trash = /obj/item/trash/plate filling_color = "#FFD675" tastes = list("cake" = 5, "sweetness" = 2, "carrot" = 1) + goal_difficulty = FOOD_GOAL_EASY /obj/item/food/snacks/sliceable/braincake @@ -47,6 +48,7 @@ trash = /obj/item/trash/plate filling_color = "#E6AEDB" tastes = list("cake" = 5, "sweetness" = 2, "brains" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/sliceable/cheesecake name = "cheese cake" @@ -68,6 +70,7 @@ trash = /obj/item/trash/plate filling_color = "#FAF7AF" tastes = list("cake" = 4, "cream cheese" = 3) + goal_difficulty = FOOD_GOAL_EASY /obj/item/food/snacks/sliceable/plaincake name = "vanilla cake" @@ -89,6 +92,7 @@ trash = /obj/item/trash/plate filling_color = "#F7EDD5" tastes = list("cake" = 5, "vanilla" = 1, "sweetness" = 2) + goal_difficulty = FOOD_GOAL_EASY /obj/item/food/snacks/sliceable/orangecake name = "orange cake" @@ -110,6 +114,7 @@ trash = /obj/item/trash/plate filling_color = "#FADA8E" tastes = list("cake" = 5, "sweetness" = 2, "oranges" = 2) + goal_difficulty = FOOD_GOAL_EASY /obj/item/food/snacks/sliceable/bananacake name = "banana cake" @@ -131,6 +136,7 @@ trash = /obj/item/trash/plate filling_color = "#FADA8E" tastes = list("cake" = 5, "sweetness" = 2, "banana" = 2) + goal_difficulty = FOOD_GOAL_EASY /obj/item/food/snacks/sliceable/limecake name = "lime cake" @@ -152,6 +158,7 @@ trash = /obj/item/trash/plate filling_color = "#CBFA8E" tastes = list("cake" = 5, "sweetness" = 2, "unbearable sourness" = 2) + goal_difficulty = FOOD_GOAL_EASY /obj/item/food/snacks/sliceable/lemoncake name = "lemon cake" @@ -173,6 +180,7 @@ trash = /obj/item/trash/plate filling_color = "#FAFA8E" tastes = list("cake" = 5, "sweetness" = 2, "sourness" = 2) + goal_difficulty = FOOD_GOAL_EASY /obj/item/food/snacks/sliceable/chocolatecake name = "chocolate cake" @@ -194,6 +202,7 @@ trash = /obj/item/trash/plate filling_color = "#805930" tastes = list("cake" = 5, "sweetness" = 1, "chocolate" = 4) + goal_difficulty = FOOD_GOAL_EASY /obj/item/food/snacks/sliceable/birthdaycake name = "birthday cake" @@ -215,6 +224,7 @@ trash = /obj/item/trash/plate filling_color = "#FFD6D6" tastes = list("cake" = 5, "sweetness" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/sliceable/applecake name = "apple cake" @@ -236,6 +246,7 @@ trash = /obj/item/trash/plate filling_color = "#EBF5B8" tastes = list("cake" = 5, "sweetness" = 1, "apple" = 1) + goal_difficulty = FOOD_GOAL_EASY ////////////////////// @@ -251,6 +262,7 @@ filling_color = "#DBC94F" list_reagents = list("nutriment" = 1, "sugar" = 3, "hot_coco" = 5 ) tastes = list("cookie" = 1, "crunchy chocolate" = 1) + goal_difficulty = FOOD_GOAL_EASY /obj/item/food/snacks/fortunecookie name = "fortune cookie" @@ -261,6 +273,7 @@ list_reagents = list("nutriment" = 3) trash = /obj/item/paper/fortune tastes = list("cookie" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/sugarcookie name = "sugar cookie" @@ -269,6 +282,7 @@ icon_state = "sugarcookie" list_reagents = list("nutriment" = 1, "sugar" = 3) tastes = list("sweetness" = 1) + goal_difficulty = FOOD_GOAL_EASY ////////////////////// @@ -285,6 +299,7 @@ bitesize = 3 list_reagents = list("nutriment" = 6, "banana" = 5, "vitamin" = 2) tastes = list("pie" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/pie/throw_impact(atom/hit_atom) ..() @@ -302,6 +317,7 @@ bitesize = 3 list_reagents = list("nutriment" = 10, "vitamin" = 2) tastes = list("pie" = 1, "meat" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/tofupie name = "tofu-pie" @@ -313,6 +329,7 @@ bitesize = 3 list_reagents = list("nutriment" = 10, "vitamin" = 2) tastes = list("pie" = 1, "tofu" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/amanita_pie name = "amanita pie" @@ -323,6 +340,7 @@ bitesize = 4 list_reagents = list("nutriment" = 6, "amanitin" = 3, "psilocybin" = 1, "vitamin" = 4) tastes = list("pie" = 1, "mushroom" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/plump_pie name = "plump pie" @@ -333,6 +351,7 @@ bitesize = 3 list_reagents = list("nutriment" = 10, "vitamin" = 2) tastes = list("pie" = 1, "mushroom" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/plump_pie/Initialize(mapload) . = ..() @@ -361,6 +380,7 @@ bitesize = 3 list_reagents = list("nutriment" = 10, "vitamin" = 2) tastes = list("pie" = 1, "apple" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/cherrypie @@ -372,6 +392,7 @@ bitesize = 3 list_reagents = list("nutriment" = 10, "vitamin" = 2) tastes = list("pie" = 1, "cherries" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/sliceable/pumpkinpie name = "pumpkin pie" @@ -384,6 +405,7 @@ filling_color = "#F5B951" list_reagents = list("nutriment" = 20, "vitamin" = 5) tastes = list("pie" = 1, "pumpkin" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/pumpkinpieslice name = "pumpkin pie slice" @@ -393,6 +415,7 @@ trash = /obj/item/trash/plate filling_color = "#F5B951" tastes = list("pie" = 1, "pumpkin" = 1) + goal_difficulty = FOOD_GOAL_NORMAL ////////////////////// // Donuts // @@ -433,6 +456,7 @@ desc = "Like life, it never quite tastes the same." bitesize = 10 tastes = list("donut" = 3, "chaos" = 1) + goal_difficulty = FOOD_GOAL_HARD /obj/item/food/snacks/donut/chaos/Initialize(mapload) . = ..() @@ -450,6 +474,7 @@ icon_state = "jdonut1" extra_reagent = "berryjuice" tastes = list("jelly" = 1, "donut" = 3) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/donut/jelly/Initialize(mapload) . = ..() @@ -467,6 +492,7 @@ desc = "You jelly?" icon_state = "jdonut1" extra_reagent = "slimejelly" + goal_difficulty = FOOD_GOAL_HARD /obj/item/food/snacks/donut/jelly/cherryjelly name = "jelly donut" @@ -487,6 +513,7 @@ bitesize = 2 list_reagents = list("nutriment" = 3, "sugar" = 3) tastes = list("sweet cake" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/pancake/attack_tk(mob/user) if(src in user.tkgrabbed_objects) @@ -509,6 +536,7 @@ icon_state = "berry_pancake" list_reagents = list("nutriment" = 3, "sugar" = 3, "berryjuice" = 3) tastes = list("sweet cake" = 2, "berries" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/pancake/choc_chip_pancake name = "choc-chip pancake" @@ -516,6 +544,7 @@ icon_state = "choc_chip_pancake" list_reagents = list("nutriment" = 3, "sugar" = 3, "cocoa" = 3) tastes = list("sweet cake" = 2, "chocolate" = 3) + goal_difficulty = FOOD_GOAL_NORMAL ////////////////////// // Misc // @@ -529,6 +558,7 @@ filling_color = "#E0CF9B" list_reagents = list("nutriment" = 6) tastes = list("muffin" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/berryclafoutis name = "berry clafoutis" @@ -539,6 +569,7 @@ bitesize = 3 list_reagents = list("nutriment" = 10, "berryjuice" = 5, "vitamin" = 2) tastes = list("pie" = 1, "blackberries" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/poppypretzel @@ -549,6 +580,7 @@ filling_color = "#916E36" list_reagents = list("nutriment" = 5) tastes = list("pretzel" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/plumphelmetbiscuit name = "plump helmet biscuit" @@ -558,6 +590,7 @@ filling_color = "#CFB4C4" list_reagents = list("nutriment" = 5) tastes = list("mushroom" = 1, "biscuit" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/plumphelmetbiscuit/Initialize(mapload) . = ..() @@ -576,6 +609,7 @@ bitesize = 3 list_reagents = list("nutriment" = 8, "gold" = 5, "vitamin" = 4) tastes = list("pie" = 1, "apple" = 1, "expensive metal" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/cracker @@ -587,6 +621,7 @@ filling_color = "#F5DEB8" list_reagents = list("nutriment" = 1) tastes = list("cracker" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/croissant name = "croissant" @@ -597,6 +632,7 @@ filling_color = "#ecb54f" list_reagents = list("nutriment" = 4, "sugar" = 2) tastes = list("croissant" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/croissant/throwing throwforce = 20 diff --git a/code/modules/food_and_drinks/food/foods/bread.dm b/code/modules/food_and_drinks/food/foods/bread.dm index c2cfd50226b8..e81ee938ff9c 100644 --- a/code/modules/food_and_drinks/food/foods/bread.dm +++ b/code/modules/food_and_drinks/food/foods/bread.dm @@ -20,6 +20,7 @@ icon = 'icons/obj/food/burgerbread.dmi' icon_state = "meatbreadslice" filling_color = "#FF7575" + goal_difficulty = FOOD_GOAL_EASY /obj/item/food/snacks/sliceable/xenomeatbread name = "xenomeatbread loaf" @@ -75,6 +76,7 @@ icon_state = "bananabreadslice" filling_color = "#EDE5AD" tastes = list("bread" = 10, "banana" = 5) + goal_difficulty = FOOD_GOAL_EASY /obj/item/food/snacks/sliceable/tofubread name = "tofubread" @@ -93,6 +95,7 @@ icon = 'icons/obj/food/burgerbread.dmi' icon_state = "tofubreadslice" filling_color = "#F7FFE0" + goal_difficulty = FOOD_GOAL_EASY /obj/item/food/snacks/sliceable/bread name = "bread" @@ -113,6 +116,7 @@ filling_color = "#D27332" list_reagents = list("nutriment" = 2, "bread" = 5) tastes = list("bread" = 1) + goal_difficulty = FOOD_GOAL_EASY /obj/item/food/snacks/sliceable/creamcheesebread name = "cream cheese bread" @@ -133,6 +137,7 @@ filling_color = "#FFF896" list_reagents = list("nutriment" = 4, "vitamin" = 1) tastes = list("bread" = 10, "cheese" = 10) + goal_difficulty = FOOD_GOAL_EASY /obj/item/food/snacks/sliceable/banarnarbread name = "banarnarbread loaf" @@ -153,6 +158,7 @@ filling_color = "#6F0000" list_reagents = list("nutriment" = 4, "vitamin" = 1) tastes = list("heresy" = 10, "banana" = 10) + goal_difficulty = FOOD_GOAL_EASY ////////////////////// @@ -166,6 +172,7 @@ icon_state = "bun" list_reagents = list("nutriment" = 1) tastes = list("bun" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/flatbread @@ -175,6 +182,7 @@ icon_state = "flatbread" list_reagents = list("nutriment" = 6, "vitamin" = 1) tastes = list("bread" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/baguette name = "baguette" @@ -187,6 +195,7 @@ bitesize = 3 list_reagents = list("nutriment" = 6, "vitamin" = 1) tastes = list("bread" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/baguette/combat sharp = TRUE @@ -205,6 +214,7 @@ bitesize = 3 list_reagents = list("nutriment" = 2, "vitamin" = 2) tastes = list("bread" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/toast name = "toast" @@ -227,9 +237,11 @@ /obj/item/food/snacks/jelliedtoast/cherry list_reagents = list("nutriment" = 1, "cherryjelly" = 5, "vitamin" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/jelliedtoast/slime list_reagents = list("nutriment" = 1, "slimejelly" = 5, "vitamin" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/rofflewaffles name = "roffle waffles" @@ -241,6 +253,7 @@ bitesize = 4 list_reagents = list("nutriment" = 8, "psilocybin" = 2, "vitamin" = 2) tastes = list("waffle" = 1, "mushrooms" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/waffles name = "waffles" @@ -250,3 +263,4 @@ trash = /obj/item/trash/waffles filling_color = "#E6DEB5" list_reagents = list("nutriment" = 8, "vitamin" = 1) + goal_difficulty = FOOD_GOAL_NORMAL diff --git a/code/modules/food_and_drinks/food/foods/candy.dm b/code/modules/food_and_drinks/food/foods/candy.dm index fe3fe0ac48a6..80cbfc5ee20b 100644 --- a/code/modules/food_and_drinks/food/foods/candy.dm +++ b/code/modules/food_and_drinks/food/foods/candy.dm @@ -13,25 +13,19 @@ icon = 'icons/obj/food/candy.dmi' icon_state = "candy" tastes = list("candy" = 1) + goal_difficulty = FOOD_GOAL_NORMAL // *********************************************************** // Candy Ingredients / Flavorings / Byproduct // *********************************************************** -/obj/item/food/snacks/chocolatebar - name = "chocolate bar" - desc = "Such sweet, fattening food." - icon_state = "chocolatebar" - filling_color = "#7D5F46" - list_reagents = list("nutriment" = 2, "chocolate" = 4) - tastes = list("chocolate" = 1) - /obj/item/food/snacks/candy/caramel name = "caramel" desc = "Chewy and dense, yet it practically melts in your mouth!" icon_state = "caramel" filling_color = "#DB944D" list_reagents = list("cream" = 2, "sugar" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/toffee @@ -40,6 +34,7 @@ icon_state = "toffee" filling_color = "#7D5F46" list_reagents = list("nutriment" = 3, "sugar" = 3) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/nougat name = "nougat" @@ -47,6 +42,7 @@ icon_state = "nougat" filling_color = "#7D5F46" list_reagents = list("nutriment" = 3, "sugar" = 3) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/taffy name = "saltwater taffy" @@ -54,6 +50,7 @@ icon_state = "candy1" filling_color = "#7D5F46" list_reagents = list("nutriment" = 3, "sugar" = 3) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/taffy/Initialize(mapload) . = ..() @@ -66,18 +63,21 @@ filling_color = "#7D5F46" bitesize = 3 list_reagents = list("cream" = 3, "chocolate" = 6) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/fudge/peanut name = "peanut fudge" desc = "Chocolate fudge, with bits of peanuts mixed in. People with nut allergies shouldn't eat this." icon_state = "fudge_peanut" filling_color = "#7D5F46" + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/fudge/cherry name = "chocolate cherry fudge" desc = "Chocolate fudge surrounding sweet cherries. Good for tricking kids into eating some fruit." icon_state = "fudge_cherry" filling_color = "#7D5F46" + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/fudge/cookies_n_cream name = "cookies 'n' cream fudge" @@ -85,12 +85,14 @@ icon_state = "fudge_cookies_n_cream" filling_color = "#7D5F46" list_reagents = list("cream" = 6, "chocolate" = 6) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/fudge/turtle name = "turtle fudge" desc = "Chocolate fudge with caramel and nuts. It doesn't contain real turtles, thankfully." icon_state = "fudge_turtle" filling_color = "#7D5F46" + goal_difficulty = FOOD_GOAL_NORMAL // *********************************************************** // Candy Products (Pre-existing) @@ -135,6 +137,7 @@ antable = FALSE list_reagents = list("nutriment" = 1, "chocolate" = 1) tastes = list("chocolate" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/candycane @@ -143,6 +146,7 @@ icon_state = "candycane" filling_color = "#F2F2F2" list_reagents = list("minttoxin" = 1, "sugar" = 5) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/gummybear name = "gummy bear" @@ -175,6 +179,7 @@ filling_color = "#ED0758" bitesize = 0.1 //this is gonna take a while, you'll be working at this all shift. list_reagents = list("sugar" = 10) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/cash name = "candy cash" @@ -183,6 +188,7 @@ filling_color = "#302000" list_reagents = list("nutriment" = 2, "chocolate" = 4) tastes = list("chocolate" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/coin @@ -193,6 +199,7 @@ bitesize = 3 list_reagents = list("nutriment" = 2, "chocolate" = 4) tastes = list("chocolate" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/gum @@ -203,6 +210,7 @@ filling_color = "#FF7495" bitesize = 0.2 list_reagents = list("sugar" = 5) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/sucker name = "sucker" @@ -210,244 +218,273 @@ icon_state = "sucker" filling_color = "#FFFFFF" list_reagents = list("sugar" = 10) + goal_difficulty = FOOD_GOAL_NORMAL // *********************************************************** // Gummy Bear Flavors // *********************************************************** /obj/item/food/snacks/candy/gummybear/red - name = "gummy bear" + name = "red gummy bear" desc = "A small edible bear. It's red!" icon_state = "gbear_red" filling_color = "#801E28" list_reagents = list("sugar" = 10, "cherryjelly" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/gummybear/blue - name = "gummy bear" + name = "blue gummy bear" desc = "A small edible bear. It's blue!" icon_state = "gbear_blue" filling_color = "#863333" list_reagents = list("sugar" = 10, "berryjuice" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/gummybear/poison - name = "gummy bear" + name = "blue gummy bear" desc = "A small edible bear. It's blue!" icon_state = "gbear_blue" filling_color = "#863353" list_reagents = list("poisonberryjuice" = 12) /obj/item/food/snacks/candy/gummybear/green - name = "gummy bear" + name = "green gummy bear" desc = "A small edible bear. It's green!" icon_state = "gbear_green" filling_color = "#365E30" list_reagents = list("sugar" = 10, "limejuice" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/gummybear/yellow - name = "gummy bear" + name = "yellow gummy bear" desc = "A small edible bear. It's yellow!" icon_state = "gbear_yellow" filling_color = "#863333" list_reagents = list("sugar" = 10, "lemonjuice" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/gummybear/orange - name = "gummy bear" + name = "orange gummy bear" desc = "A small edible bear. It's orange!" icon_state = "gbear_orange" filling_color = "#E78108" list_reagents = list("sugar" = 10, "orangejuice" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/gummybear/purple - name = "gummy bear" + name = "purple gummy bear" desc = "A small edible bear. It's purple!" icon_state = "gbear_purple" filling_color = "#993399" list_reagents = list("sugar" = 10, "grapejuice" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/gummybear/wtf - name = "gummy bear" + name = "rainbow gummy bear" desc = "A small bear. Wait... what?" icon_state = "gbear_rainbow" filling_color = "#60A584" list_reagents = list("sugar" = 10, "space_drugs" = 2) + goal_difficulty = FOOD_GOAL_NORMAL // *********************************************************** // Gummy Worm Flavors // *********************************************************** /obj/item/food/snacks/candy/gummyworm/red - name = "gummy worm" + name = "red gummy worm" desc = "An edible worm, made from gelatin. It's red!" icon_state = "gworm_red" filling_color = "#801E28" list_reagents = list("sugar" = 10, "cherryjelly" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/gummyworm/blue - name = "gummy worm" + name = "blue gummy worm" desc = "An edible worm, made from gelatin. It's blue!" icon_state = "gworm_blue" filling_color = "#863333" list_reagents = list("sugar" = 10, "berryjuice" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/gummyworm/poison - name = "gummy worm" + name = "blue gummy worm" desc = "An edible worm, made from gelatin. It's blue!" icon_state = "gworm_blue" filling_color = "#863353" list_reagents = list("poisonberryjuice" = 12) /obj/item/food/snacks/candy/gummyworm/green - name = "gummy worm" + name = "green gummy worm" desc = "An edible worm, made from gelatin. It's green!" icon_state = "gworm_green" filling_color = "#365E30" list_reagents = list("sugar" = 10, "limejuice" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/gummyworm/yellow - name = "gummy worm" + name = "yellow gummy worm" desc = "An edible worm, made from gelatin. It's yellow!" icon_state = "gworm_yellow" filling_color = "#863333" list_reagents = list("sugar" = 10, "lemonjuice" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/gummyworm/orange - name = "gummy worm" + name = "orange gummy worm" desc = "An edible worm, made from gelatin. It's orange!" icon_state = "gworm_orange" filling_color = "#E78108" list_reagents = list("sugar" = 10, "orangejuice" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/gummyworm/purple - name = "gummy worm" + name = "purple gummy worm" desc = "An edible worm, made from gelatin. It's purple!" icon_state = "gworm_purple" filling_color = "#993399" list_reagents = list("sugar" = 10, "grapejuice" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/gummyworm/wtf - name = "gummy worm" + name = "rainbow gummy worm" desc = "An edible worm. Did it just move?" icon_state = "gworm_rainbow" filling_color = "#60A584" list_reagents = list("sugar" = 10, "space_drugs" = 2) + goal_difficulty = FOOD_GOAL_NORMAL // *********************************************************** // Jelly Bean Flavors // *********************************************************** /obj/item/food/snacks/candy/jellybean/red - name = "jelly bean" + name = "red jelly bean" desc = "A candy bean, guaranteed to not give you gas. It's red!" icon_state = "jbean_red" filling_color = "#801E28" list_reagents = list("sugar" = 10, "cherryjelly" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/jellybean/blue - name = "jelly bean" + name = "blue jelly bean" desc = "A candy bean, guaranteed to not give you gas. It's blue!" icon_state = "jbean_blue" filling_color = "#863333" list_reagents = list("sugar" = 10, "berryjuice" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/jellybean/poison - name = "jelly bean" + name = "blue jelly bean" desc = "A candy bean, guaranteed to not give you gas. It's blue!" icon_state = "jbean_blue" filling_color = "#863353" list_reagents = list("poisonberryjuice" = 12) /obj/item/food/snacks/candy/jellybean/green - name = "jelly bean" + name = "green jelly bean" desc = "A candy bean, guaranteed to not give you gas. It's green!" icon_state = "jbean_green" filling_color = "#365E30" list_reagents = list("sugar" = 10, "limejuice" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/jellybean/yellow - name = "jelly bean" + name = "yellow jelly bean" desc = "A candy bean, guaranteed to not give you gas. It's yellow!" icon_state = "jbean_yellow" filling_color = "#863333" list_reagents = list("sugar" = 10, "lemonjuice" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/jellybean/orange - name = "jelly bean" + name = "orange jelly bean" desc = "A candy bean, guaranteed to not give you gas. It's orange!" icon_state = "jbean_orange" filling_color = "#E78108" list_reagents = list("sugar" = 10, "orangejuice" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/jellybean/purple - name = "jelly bean" + name = "purple jelly bean" desc = "A candy bean, guaranteed to not give you gas. It's purple!" icon_state = "jbean_purple" filling_color = "#993399" list_reagents = list("sugar" = 10, "grapejuice" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/jellybean/chocolate - name = "jelly bean" + name = "chocolate jelly bean" desc = "A candy bean, guaranteed to not give you gas. It's chocolate!" icon_state = "jbean_choc" filling_color = "#302000" list_reagents = list("sugar" = 10, "chocolate" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/jellybean/popcorn - name = "jelly bean" + name = "popcorn jelly bean" desc = "A candy bean, guaranteed to not give you gas. It's popcorn flavored!" icon_state = "jbean_popcorn" filling_color = "#664330" list_reagents = list("sugar" = 10, "nutriment" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/jellybean/cola - name = "jelly bean" + name = "cola jelly bean" desc = "A candy bean, guaranteed to not give you gas. It's Cola flavored!" icon_state = "jbean_cola" filling_color = "#102000" list_reagents = list("sugar" = 10, "cola" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/jellybean/drgibb - name = "jelly bean" + name = "\improper Dr. Gibb jelly bean" desc = "A candy bean, guaranteed to not give you gas. It's Dr. Gibb flavored!" icon_state = "jbean_cola" filling_color = "#102000" list_reagents = list("sugar" = 10, "dr_gibb" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/jellybean/coffee - name = "jelly bean" + name = "coffee jelly bean" desc = "A candy bean, guaranteed to not give you gas. It's Coffee flavored!" icon_state = "jbean_choc" filling_color = "#482000" list_reagents = list("sugar" = 10, "coffee" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/jellybean/wtf - name = "jelly bean" + name = "rainbow jelly bean" desc = "A candy bean, guaranteed to not give you gas. You aren't sure what color it is." icon_state = "jbean_rainbow" filling_color = "#60A584" list_reagents = list("sugar" = 10, "space_drugs" = 2) + goal_difficulty = FOOD_GOAL_NORMAL // *********************************************************** // Cotton Candy Flavors // *********************************************************** /obj/item/food/snacks/candy/cotton/red - name = "cotton candy" + name = "red cotton candy" desc = "Light and fluffy, it's like eating a cloud made from sugar!" icon_state = "cottoncandy_red" trash = /obj/item/c_tube filling_color = "#801E28" list_reagents = list("sugar" = 15, "cherryjelly" = 5) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/cotton/blue - name = "cotton candy" + name = "blue cotton candy" desc = "Light and fluffy, it's like eating a cloud made from sugar!" icon_state = "cottoncandy_blue" trash = /obj/item/c_tube filling_color = "#863333" list_reagents = list("sugar" = 15, "berryjuice" = 5) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/cotton/poison - name = "cotton candy" + name = "blue cotton candy" desc = "Light and fluffy, it's like eating a cloud made from sugar!" icon_state = "cottoncandy_blue" trash = /obj/item/c_tube @@ -455,55 +492,61 @@ list_reagents = list("poisonberryjuice" = 20) /obj/item/food/snacks/candy/cotton/green - name = "cotton candy" + name = "green cotton candy" desc = "Light and fluffy, it's like eating a cloud made from sugar!" icon_state = "cottoncandy_green" trash = /obj/item/c_tube filling_color = "#365E30" list_reagents = list("sugar" = 15, "limejuice" = 5) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/cotton/yellow - name = "cotton candy" + name = "yellow cotton candy" desc = "Light and fluffy, it's like eating a cloud made from sugar!" icon_state = "cottoncandy_yellow" trash = /obj/item/c_tube filling_color = "#863333" list_reagents = list("sugar" = 15, "lemonjuice" = 5) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/cotton/orange - name = "cotton candy" + name = "orange cotton candy" desc = "Light and fluffy, it's like eating a cloud made from sugar!" icon_state = "cottoncandy_orange" trash = /obj/item/c_tube filling_color = "#E78108" list_reagents = list("sugar" = 15, "orangejuice" = 5) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/cotton/purple - name = "cotton candy" + name = "purple cotton candy" desc = "Light and fluffy, it's like eating a cloud made from sugar!" icon_state = "cottoncandy_purple" trash = /obj/item/c_tube filling_color = "#993399" list_reagents = list("sugar" = 15, "grapejuice" = 5) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/cotton/pink - name = "cotton candy" + name = "pink cotton candy" desc = "Light and fluffy, it's like eating a cloud made from sugar!" icon_state = "cottoncandy_pink" trash = /obj/item/c_tube filling_color = "#863333" list_reagents = list("sugar" = 15, "watermelonjuice" = 5) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/cotton/rainbow - name = "cotton candy" + name = "rainbow cotton candy" desc = "Light and fluffy, it's like eating a cloud made from sugar!" icon_state = "cottoncandy_rainbow" trash = /obj/item/c_tube filling_color = "#C8A5DC" list_reagents = list("omnizine" = 20) + goal_difficulty = FOOD_GOAL_HARD /obj/item/food/snacks/candy/cotton/bad_rainbow - name = "cotton candy" + name = "rainbow cotton candy" desc = "Light and fluffy, it's like eating a cloud made from sugar!" icon_state = "cottoncandy_rainbow" trash = /obj/item/c_tube @@ -523,27 +566,32 @@ icon_state = "asteroidcrunch" trash = /obj/item/trash/candy filling_color = "#7D5F46" + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/confectionery/toffee name = "Yum-Baton Bar" desc = "Chocolate and toffee in the shape of a baton. Security sure knows how to pound these down!" icon_state = "yumbaton" filling_color = "#7D5F46" + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/confectionery/caramel name = "Malper Bar" desc = "A chocolate syringe filled with a caramel injection. Just what the doctor ordered!" icon_state = "malper" filling_color = "#7D5F46" + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/confectionery/caramel_nougat name = "Toxins Test Bar" desc = "An explosive combination of chocolate, caramel, and nougat. Research has never been so tasty!" icon_state = "toxinstest" filling_color = "#7D5F46" + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candy/confectionery/nougat name = "Tool-erone Bar" desc = "Chocolate-covered nougat, shaped like a wrench. Great for an engineer on the go!" icon_state = "toolerone" filling_color = "#7D5F46" + goal_difficulty = FOOD_GOAL_NORMAL diff --git a/code/modules/food_and_drinks/food/foods/desserts.dm b/code/modules/food_and_drinks/food/foods/desserts.dm index c68b8bc55f17..8c3517c8c66c 100644 --- a/code/modules/food_and_drinks/food/foods/desserts.dm +++ b/code/modules/food_and_drinks/food/foods/desserts.dm @@ -7,6 +7,7 @@ desc = "Goreng Pisang, also known as fried bananas." icon_state = "friedbanana" list_reagents = list("sugar" = 5, "nutriment" = 8, "cornoil" = 4) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/ricepudding name = "rice pudding" @@ -16,6 +17,7 @@ filling_color = "#FFFBDB" list_reagents = list("nutriment" = 7, "vitamin" = 2) tastes = list("rice" = 1, "sweetness" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/spacylibertyduff name = "spacy liberty duff" @@ -26,6 +28,7 @@ bitesize = 3 list_reagents = list("nutriment" = 6, "psilocybin" = 6) tastes = list("jelly" = 1, "mushroom" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/amanitajelly name = "amanita jelly" @@ -36,6 +39,7 @@ bitesize = 3 list_reagents = list("nutriment" = 6, "amanitin" = 6, "psilocybin" = 3) tastes = list("jelly" = 1, "mushroom" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/candiedapple name = "candied apple" @@ -45,6 +49,7 @@ bitesize = 3 list_reagents = list("nutriment" = 3, "sugar" = 2) tastes = list("apple" = 2, "sweetness" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/mint name = "mint" @@ -53,3 +58,4 @@ bitesize = 1 filling_color = "#F2F2F2" list_reagents = list("minttoxin" = 1) + goal_difficulty = FOOD_GOAL_NORMAL diff --git a/code/modules/food_and_drinks/food/foods/ethnic.dm b/code/modules/food_and_drinks/food/foods/ethnic.dm index 153dc2b7407c..b620811936b3 100644 --- a/code/modules/food_and_drinks/food/foods/ethnic.dm +++ b/code/modules/food_and_drinks/food/foods/ethnic.dm @@ -10,6 +10,7 @@ bitesize = 3 list_reagents = list("nutriment" = 7, "vitamin" = 1) tastes = list("taco" = 4, "meat" = 2, "cheese" = 2, "lettuce" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/burrito name = "burrito" @@ -19,6 +20,7 @@ filling_color = "#A36A1F" list_reagents = list("nutriment" = 4, "vitamin" = 1) tastes = list("torilla" = 2, "meat" = 3) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/chimichanga @@ -28,6 +30,7 @@ trash = /obj/item/trash/plate filling_color = "#A36A1F" list_reagents = list("omnizine" = 4, "cheese" = 2) //Deadpool reference. Deal with it. + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/enchiladas name = "enchiladas" @@ -38,6 +41,7 @@ bitesize = 4 list_reagents = list("nutriment" = 8, "capsaicin" = 6) tastes = list("hot peppers" = 1, "meat" = 3, "cheese" = 1, "sour cream" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/cornchips name = "corn chips" @@ -47,6 +51,7 @@ trash = /obj/item/trash/chips filling_color = "#E8C31E" list_reagents = list("nutriment" = 3) + goal_difficulty = FOOD_GOAL_NORMAL ////////////////////// @@ -113,6 +118,7 @@ filling_color = "#F0F2E4" list_reagents = list("nutriment" = 5) tastes = list("custard" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/yakiimo name = "yaki imo" @@ -122,6 +128,7 @@ list_reagents = list("nutriment" = 5, "vitamin" = 4) filling_color = "#8B1105" tastes = list("sweet potato" = 1) + goal_difficulty = FOOD_GOAL_NORMAL ////////////////////// @@ -143,6 +150,7 @@ 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" @@ -151,6 +159,7 @@ 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" @@ -160,3 +169,4 @@ list_reagents = list("protein" = 8, "vitamin" = 4, "vinegar" = 1, "capsaicin" = 1) filling_color = "#A85340" tastes = list("fish" = 4, "acid" = 1, "onion" = 1, "heat" = 1) + goal_difficulty = FOOD_GOAL_NORMAL diff --git a/code/modules/food_and_drinks/food/foods/frozen.dm b/code/modules/food_and_drinks/food/foods/frozen.dm index d00db915ed0a..dd117fbaecb1 100644 --- a/code/modules/food_and_drinks/food/foods/frozen.dm +++ b/code/modules/food_and_drinks/food/foods/frozen.dm @@ -30,13 +30,7 @@ filling_color = "#FFD675" list_reagents = list("nutriment" = 4, "sugar" = 1, "vitamin" = 1, "banana" = 3) tastes = list("cake" = 5, "sweetness" = 2, "sad clowns" = 1, "ice-cream" = 1) - -/obj/item/food/snacks/frozen/sundae - name = "sundae" - desc = "Portable ice cream in its own packaging." - icon_state = "sundae" - list_reagents = list("nutriment" = 2, "ice" = 2) - tastes = list("ice cream" = 1, "banana" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /////////////////// // Ice Cream // @@ -100,6 +94,7 @@ icon_state = "icecreamsandwich" list_reagents = list("nutriment" = 2, "ice" = 2) tastes = list("ice cream" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/frozen/berryicecreamsandwich name = "strawberry icecream sandwich" @@ -107,6 +102,7 @@ icon_state = "strawberryicecreamsandwich" list_reagents = list("nutriment" = 2, "ice" = 2) tastes = list("ice cream" = 1, "strawberry" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/frozen/sundae name = "sundae" @@ -114,6 +110,7 @@ icon_state = "sundae" list_reagents = list("nutriment" = 6, "banana" = 5, "vitamin" = 2) tastes = list("ice cream" = 1, "banana" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/frozen/honkdae name = "honkdae" @@ -121,6 +118,7 @@ icon_state = "honkdae" list_reagents = list("nutriment" = 6, "banana" = 10, "vitamin" = 4) tastes = list("ice cream" = 1, "banana" = 1, "a bad joke" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/frozen/cornuto name = "cornuto" @@ -128,6 +126,7 @@ icon_state = "cornuto" list_reagents = list("nutriment" = 6, "hot_coco" = 4, "cream" = 2, "vanilla" = 4, "sugar" = 2) tastes = list("chopped hazelnuts" = 3, "waffle" = 5) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/frozen/peanutbuttermochi name = "peanut butter ice cream mochi" @@ -135,6 +134,7 @@ icon_state = "pb_ice_cream_mochi" list_reagents = list("nutriment" = 4, "sugar" = 6, "peanutbutter" = 4, "milk" = 2) tastes = list("peanut butter" = 1, "mochi" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/frozen/spacefreezy name = "spacefreezy" @@ -142,6 +142,7 @@ icon_state = "spacefreezy" list_reagents = list("nutriment" = 8, "vitamin" = 5, "bluecherryjelly" = 5) tastes = list("blue cherries" = 2, "ice cream" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /////////////////// // Snow Cones // @@ -161,6 +162,7 @@ icon_state = "amber_sc" list_reagents = list("water" = 10, "ice" = 5, "nutriment" = 1, "applejuice" = 5) tastes = list("ice" = 1, "water" = 1, "apples" = 5) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/frozen/snowcone/berry name = "berry snowcone" @@ -168,6 +170,7 @@ icon_state = "berry_sc" list_reagents = list("water" = 10, "ice" = 5, "nutriment" = 1, "berryjuice" = 5) tastes = list("ice" = 1, "water" = 1, "berries" = 5) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/frozen/snowcone/bluecherry name = "bluecherry snowcone" @@ -175,6 +178,7 @@ icon_state = "blue_sc" list_reagents = list("water" = 10, "ice" = 5, "nutriment" = 1, "bluecherryjelly" = 5) tastes = list("ice" = 1, "water" = 1, "bluecherries" = 5) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/frozen/snowcone/cherry name = "cherry snowcone" @@ -182,6 +186,7 @@ icon_state = "red_sc" list_reagents = list("water" = 10, "ice" = 5, "nutriment" = 1, "cherryjelly" = 5) tastes = list("ice" = 1, "water" = 1, "cherries" = 5) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/frozen/snowcone/fruitsalad name = "fruit salad snowcone" @@ -189,6 +194,7 @@ icon_state = "fruitsalad_sc" list_reagents = list("water" = 10, "ice" = 5, "nutriment" = 1, "limejuice" = 5, "lemonjuice" = 5, "orangejuice" = 5) tastes = list("ice" = 1, "water" = 1, "oranges" = 5, "lemons" = 5, "limes" = 5) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/frozen/snowcone/grape name = "grape snowcone" @@ -196,6 +202,7 @@ icon_state = "grape_sc" list_reagents = list("water" = 10, "ice" = 5, "nutriment" = 1, "grapejuice" = 5) tastes = list("ice" = 1, "water" = 1, "grapes" = 5) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/frozen/snowcone/honey name = "honey snowcone" @@ -203,6 +210,7 @@ icon_state = "amber_sc" list_reagents = list("water" = 10, "ice" = 5, "nutriment" = 1, "honey" = 5) tastes = list("ice" = 1, "water" = 1, "honey" = 5) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/frozen/snowcone/lemon name = "lemon snowcone" @@ -210,6 +218,7 @@ icon_state = "lemon_sc" list_reagents = list("water" = 10, "ice" = 5, "nutriment" = 1, "lemonjuice" = 5) tastes = list("ice" = 1, "water" = 1, "lemons" = 5) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/frozen/snowcone/lime name = "lime snowcone" @@ -217,6 +226,7 @@ icon_state = "lime_sc" list_reagents = list("water" = 10, "ice" = 5, "nutriment" = 1, "limejuice" = 5) tastes = list("ice" = 1, "water" = 1, "limes" = 5) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/frozen/snowcone/mime name = "mime snowcone" @@ -224,6 +234,7 @@ icon_state = "mime_sc" list_reagents = list("water" = 10, "ice" = 5, "nutriment" = 1, "nothing" = 5) tastes = list("ice" = 1, "water" = 1, "silence" = 5) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/frozen/snowcone/orange name = "orange snowcone" @@ -231,6 +242,7 @@ icon_state = "orange_sc" list_reagents = list("water" = 10, "ice" = 5, "nutriment" = 1, "orangejuice" = 5) tastes = list("ice" = 1, "water" = 1, "oranges" = 5) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/frozen/snowcone/pineapple name = "pineapple snowcone" @@ -238,6 +250,7 @@ icon_state = "pineapple_sc" list_reagents = list("water" = 10, "ice" = 5, "nutriment" = 1, "pineapplejuice" = 5) tastes = list("ice" = 1, "water" = 1, "pineapple" = 5) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/frozen/snowcone/rainbow name = "rainbow snowcone" @@ -245,6 +258,7 @@ icon_state = "rainbow_sc" list_reagents = list("water" = 10, "ice" = 5, "colorful_reagent" = 5) tastes = list("ice" = 1, "water" = 1, "rainbows" = 5) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/frozen/snowcone/cola name = "space cola snowcone" @@ -252,6 +266,7 @@ icon_state = "soda_sc" list_reagents = list("water" = 10, "ice" = 5, "nutriment" = 1, "cola" = 5) tastes = list("ice" = 1, "water" = 1, "soda" = 5) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/frozen/snowcone/spacemountain name = "space mountain wind snowcone" @@ -259,6 +274,7 @@ icon_state = "mountainwind_sc" list_reagents = list("water" = 10, "ice" = 5, "nutriment" = 1, "spacemountainwind" = 5) tastes = list("ice" = 1, "water" = 1, "mountain wind" = 5) + goal_difficulty = FOOD_GOAL_NORMAL /////////////////// // Popsicles // @@ -271,6 +287,7 @@ trash = /obj/item/trash/popsicle_stick list_reagents = list("nutriment" = 4, "sugar" = 4, "chocolate" = 3) tastes = list("ice cream" = 1, "chocolate" = 1, "vanilla" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/frozen/popsicle/bananatop name = "banana topsicle" @@ -278,6 +295,7 @@ icon_state = "topsicle_banana" list_reagents = list("vitamin" = 4, "sugar" = 6, "banana" = 4) tastes = list("bananas" = 1, "tofu" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/frozen/popsicle/berrytop name = "berry topsicle" @@ -285,6 +303,7 @@ icon_state = "topsicle_berry" list_reagents = list("vitamin" = 4, "sugar" = 6, "berryjuice" = 4) tastes = list("berries" = 1, "tofu" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/frozen/popsicle/pineappletop name = "pineapple topsicle" @@ -292,6 +311,7 @@ icon_state = "topsicle_pineapple" list_reagents = list("vitamin" = 4, "sugar" = 6, "pineapplejuice" = 4) tastes = list("pineapples" = 1, "tofu" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/frozen/popsicle/licoricecream name = "licorice creamsicle" @@ -299,6 +319,7 @@ icon_state = "licorice_creamsicle" list_reagents = list("nutriment" = 4, "cream" = 2, "vanilla" = 1, "sugar" = 4, "salt" = 1) tastes = list("salty licorice" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/frozen/popsicle/orangecream name = "orange creamsicle" @@ -306,6 +327,7 @@ icon_state = "creamsicle_o" list_reagents = list("orangejuice" = 4, "cream" = 2, "vanilla" = 2, "sugar" = 4) tastes = list("ice cream" = 1, "oranges" = 1, "vanilla" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/frozen/popsicle/berrycream name = "berry creamsicle" @@ -313,6 +335,7 @@ icon_state = "creamsicle_m" list_reagents = list("berryjuice" = 4, "cream" = 2, "vanilla" = 2, "sugar" = 4) tastes = list("ice cream" = 1, "berries" = 1, "vanilla" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/frozen/popsicle/frozenpineapple name = "frozen pineapple pop" @@ -320,6 +343,7 @@ icon_state = "pineapple_pop" list_reagents = list("pineapplejuice" = 4, "sugar" = 4, "nutriment" = 2, "vitamin" = 2) tastes = list("cold pineapple" = 1, "chocolate" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/frozen/popsicle/sea_salt name = "sea salt ice-cream bar" @@ -327,6 +351,7 @@ icon_state = "sea_salt_pop" list_reagents = list("salt" = 1, "nutriment" = 2, "cream" = 2, "vanilla" = 2, "sugar"= 4,) tastes = list("salt" = 1, "sweet" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/frozen/popsicle/ant name = "ant popsicle" diff --git a/code/modules/food_and_drinks/food/foods/ingredients.dm b/code/modules/food_and_drinks/food/foods/ingredients.dm index d6331119b2c4..ffb42057fad6 100644 --- a/code/modules/food_and_drinks/food/foods/ingredients.dm +++ b/code/modules/food_and_drinks/food/foods/ingredients.dm @@ -21,6 +21,7 @@ bitesize = 3 list_reagents = list("plantmatter" = 3) tastes = list("tofu" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/soydope name = "soy dope" @@ -230,6 +231,7 @@ filling_color = "#7D5F46" list_reagents = list("nutriment" = 2, "sugar" = 2, "cocoa" = 2) tastes = list("chocolate" = 1) + goal_difficulty = FOOD_GOAL_EASY ///Chocolate crumbles/pile /obj/item/food/snacks/chocolatebar/attackby(obj/item/I, mob/user, params) diff --git a/code/modules/food_and_drinks/food/foods/meat.dm b/code/modules/food_and_drinks/food/foods/meat.dm index 0a0a410807bb..5cc637ba2d66 100644 --- a/code/modules/food_and_drinks/food/foods/meat.dm +++ b/code/modules/food_and_drinks/food/foods/meat.dm @@ -201,6 +201,7 @@ bitesize = 3 list_reagents = list("nutriment" = 5) tastes = list("meat" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/bacon name = "bacon" @@ -209,6 +210,7 @@ icon_state = "bacon" list_reagents = list("nutriment" = 4, "porktonium" = 10, "msg" = 4) tastes = list("bacon" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/telebacon name = "tele bacon" @@ -218,6 +220,7 @@ var/obj/item/radio/beacon/bacon/baconbeacon list_reagents = list("nutriment" = 4, "porktonium" = 10) tastes = list("bacon" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/telebacon/Initialize(mapload) . = ..() @@ -250,6 +253,7 @@ filling_color = "#DB0000" list_reagents = list("protein" = 6, "vitamin" = 1, "porktonium" = 10) tastes = list("meat" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/cutlet name = "cutlet" @@ -258,6 +262,7 @@ icon_state = "cutlet" list_reagents = list("protein" = 2) tastes = list("meat" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/spidereggsham name = "green eggs and ham" @@ -461,6 +466,7 @@ bitesize = 1 list_reagents = list("nutriment" = 3, "egg" = 5) tastes = list("egg" = 1, "salt" = 1, "pepper" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/boiledegg name = "boiled egg" @@ -469,6 +475,7 @@ icon_state = "egg" filling_color = "#FFFFFF" list_reagents = list("nutriment" = 2, "egg" = 5, "vitamin" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/chocolateegg name = "chocolate egg" @@ -477,6 +484,7 @@ icon_state = "chocolateegg" filling_color = "#7D5F46" list_reagents = list("nutriment" = 4, "sugar" = 2, "cocoa" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/omelette name = "omelette du fromage" @@ -488,6 +496,7 @@ list_reagents = list("nutriment" = 8, "vitamin" = 1) bitesize = 1 tastes = list("egg" = 1, "cheese" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/benedict name = "eggs benedict" @@ -497,6 +506,7 @@ bitesize = 3 list_reagents = list("nutriment" = 6, "egg" = 3, "vitamin" = 4) tastes = list("egg" = 1, "bacon" = 1, "bun" = 1) + goal_difficulty = FOOD_GOAL_NORMAL ////////////////////// @@ -511,6 +521,7 @@ bitesize = 3 list_reagents = list("nutriment" = 6, "ketchup" = 3, "vitamin" = 3) tastes = list("bun" = 3, "meat" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/meatbun name = "meat bun" @@ -520,6 +531,7 @@ bitesize = 6 list_reagents = list("nutriment" = 6, "vitamin" = 2) tastes = list("bun" = 3, "meat" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/sliceable/turkey name = "turkey" @@ -539,6 +551,7 @@ trash = /obj/item/trash/plate filling_color = "#B97A57" tastes = list("turkey" = 1) + goal_difficulty = FOOD_GOAL_EASY /obj/item/food/snacks/organ name = "organ" @@ -573,3 +586,4 @@ list_reagents = list("nutriment" = 3, "protein" = 10, "bbqsauce" = 10) filling_color = "#FF1C1C" bitesize = 3 + goal_difficulty = FOOD_GOAL_NORMAL diff --git a/code/modules/food_and_drinks/food/foods/misc_food.dm b/code/modules/food_and_drinks/food/foods/misc_food.dm index 26624dbd595e..d9189b03aa36 100644 --- a/code/modules/food_and_drinks/food/foods/misc_food.dm +++ b/code/modules/food_and_drinks/food/foods/misc_food.dm @@ -11,6 +11,7 @@ filling_color = "#4D2F5E" list_reagents = list("nutriment" = 6, "vitamin" = 2) tastes = list("eggplant" = 2, "cheese" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/soylentgreen name = "soylent green" @@ -29,6 +30,7 @@ filling_color = "#E6FA61" list_reagents = list("nutriment" = 10, "vitamin" = 1) tastes = list("waffles" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/monkeysdelight name = "monkey's delight" @@ -39,6 +41,7 @@ bitesize = 6 list_reagents = list("nutriment" = 10, "banana" = 5, "vitamin" = 5) tastes = list("banana" = 1, "the jungle" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/dionaroast name = "roast diona" @@ -48,6 +51,7 @@ filling_color = "#75754B" list_reagents = list("plantmatter" = 4, "nutriment" = 2, "radium" = 2, "vitamin" = 4) tastes = list("chewy vegetables" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/tofurkey name = "tofurkey" @@ -57,6 +61,7 @@ bitesize = 3 list_reagents = list("nutriment" = 12, "ether" = 3) tastes = list("tofu" = 1) + goal_difficulty = FOOD_GOAL_NORMAL ////////////////////// @@ -73,6 +78,7 @@ bitesize = 3 list_reagents = list("nutriment" = 6,"vitamin" = 4) tastes = list("lettuce" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/salad/aesir name = "aesir salad" @@ -80,6 +86,7 @@ icon_state = "aesirsalad" list_reagents = list("nutriment" = 8, "omnizine" = 8, "vitamin" = 6) tastes = list("divinity" = 1, "lettuce" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/salad/antipasto name = "antipasto salad" @@ -87,6 +94,7 @@ icon_state = "antipasto_salad" list_reagents = list("nutriment" = 12, "protein" = 6, "vitamin" = 6) tastes = list("lettuce" = 2, "salami" = 2, "mozzarella cheese" = 2, "tomatoes" = 2, "dressing" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/salad/caesar name = "Caesar salad" @@ -94,6 +102,7 @@ icon_state = "caesar_salad" list_reagents = list("nutriment" = 12, "vitamin" = 6) tastes = list("healthy greens" = 2, "olive dressing" = 2, "feta cheese" = 2, "pita bread" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/salad/fruit name = "fruit salad" @@ -101,6 +110,7 @@ icon_state = "fruitsalad" list_reagents = list("nutriment" = 9, "vitamin" = 4) tastes = list("fruit" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/salad/greek name = "Greek salad" @@ -108,6 +118,7 @@ icon_state = "greek_salad" list_reagents = list("nutriment" = 13, "vitamin" = 14) tastes = list("healthy greens" = 2, "olive dressing" = 1, "feta cheese" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/salad/citrusdelight name = "citrus delight" @@ -115,6 +126,7 @@ icon_state = "citrusdelight" list_reagents = list("nutriment" = 11, "vitamin" = 7) tastes = list("sourness" = 1, "leaves" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/salad/jungle name = "jungle salad" @@ -122,6 +134,7 @@ icon_state = "junglesalad" list_reagents = list("banana" = 5, "nutriment" = 11, "vitamin" = 7) tastes = list("fruit" = 1, "the jungle" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/salad/kale name = "kale salad" @@ -129,6 +142,7 @@ icon_state = "kale_salad" list_reagents = list("nutriment" = 12, "vitamin" = 12) tastes = list("healthy greens" = 2, "olive dressing" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/salad/potato name = "potato salad" @@ -136,6 +150,7 @@ icon_state = "potato_salad" list_reagents = list("nutriment" = 10, "protein" = 4) tastes = list("potato" = 2, "egg" = 2, "mayonnaise" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/salad/melonfruitbowl name = "melon fruit bowl" @@ -144,6 +159,7 @@ trash = null list_reagents = list("nutriment" = 6, "vitamin" = 4) tastes = list("melon" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/salad/herb name = "herb salad" @@ -152,6 +168,7 @@ filling_color = "#76B87F" list_reagents = list("nutriment" = 8, "vitamin" = 2) tastes = list("lettuce" = 1, "apple" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/salad/valid name = "valid salad" @@ -160,6 +177,7 @@ filling_color = "#76B87F" list_reagents = list("nutriment" = 8, "salglu_solution" = 5, "vitamin" = 2) tastes = list("fried potato" = 1, "lettuce" = 1, "meat" = 1, "valids" = 1) + goal_difficulty = FOOD_GOAL_NORMAL ////////////////////// @@ -270,6 +288,7 @@ bitesize = 0.1 //this snack is supposed to be eating during looooong time. And this it not dinner food! --rastaf0 list_reagents = list("nutriment" = 2) tastes = list("popcorn" = 3, "butter" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/popcorn/Initialize(mapload) . = ..() diff --git a/code/modules/food_and_drinks/food/foods/pasta.dm b/code/modules/food_and_drinks/food/foods/pasta.dm index 984fb60c1a8e..e8aadb6ce29d 100644 --- a/code/modules/food_and_drinks/food/foods/pasta.dm +++ b/code/modules/food_and_drinks/food/foods/pasta.dm @@ -35,6 +35,7 @@ filling_color = "#FCEE81" list_reagents = list("nutriment" = 2, "vitamin" = 1) tastes = list("pasta" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/pastatomato name = "spaghetti" @@ -46,6 +47,7 @@ bitesize = 4 list_reagents = list("nutriment" = 6, "tomatojuice" = 10, "vitamin" = 4) tastes = list("pasta" = 1, "tomato" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/meatballspaghetti name = "spaghetti & meatballs" @@ -56,6 +58,7 @@ filling_color = "#DE4545" list_reagents = list("nutriment" = 8, "synaptizine" = 5, "vitamin" = 4) tastes = list("pasta" = 1, "tomato" = 1, "meat" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/spesslaw name = "spesslaw" @@ -65,6 +68,7 @@ filling_color = "#DE4545" list_reagents = list("nutriment" = 8, "synaptizine" = 10, "vitamin" = 6) tastes = list("pasta" = 1, "tomato" = 1, "meat" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/macncheese name = "mac 'n' cheese" @@ -75,6 +79,7 @@ filling_color = "#ffe45d" list_reagents = list("nutriment" = 5, "vitamin" = 2, "cheese" = 4) tastes = list("pasta" = 1, "cheese" = 1, "comfort" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/lasagna name = "lasagna" @@ -84,3 +89,4 @@ filling_color = "#E18712" list_reagents = list("nutriment" = 10, "msg" = 3, "vitamin" = 4, "tomatojuice" = 10) tastes = list("pasta" = 1, "cheese" = 1, "tomato" = 1, "meat" = 1) + goal_difficulty = FOOD_GOAL_NORMAL diff --git a/code/modules/food_and_drinks/food/foods/pizza.dm b/code/modules/food_and_drinks/food/foods/pizza.dm index d37e3f058435..8e7a92050457 100644 --- a/code/modules/food_and_drinks/food/foods/pizza.dm +++ b/code/modules/food_and_drinks/food/foods/pizza.dm @@ -24,6 +24,7 @@ icon_state = "margheritapizzaslice" filling_color = "#BAA14C" tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1) + goal_difficulty = FOOD_GOAL_EASY // Meat Pizza /obj/item/food/snacks/sliceable/pizza/meatpizza @@ -41,6 +42,7 @@ icon_state = "meatpizzaslice" filling_color = "#BAA14C" tastes = list("crust" = 1, "cheese" = 1, "meat" = 1) + goal_difficulty = FOOD_GOAL_EASY // Mushroom Pizza /obj/item/food/snacks/sliceable/pizza/mushroompizza @@ -58,6 +60,7 @@ icon_state = "mushroompizzaslice" filling_color = "#BAA14C" tastes = list("crust" = 1, "cheese" = 1, "mushroom" = 1) + goal_difficulty = FOOD_GOAL_EASY // Vegetable Pizza /obj/item/food/snacks/sliceable/pizza/vegetablepizza @@ -75,6 +78,7 @@ icon_state = "vegetablepizzaslice" filling_color = "#BAA14C" tastes = list("crust" = 1, "tomato" = 1, "carrot" = 1, "vegetables" = 1) + goal_difficulty = FOOD_GOAL_EASY // Hawaiian Pizza /obj/item/food/snacks/sliceable/pizza/hawaiianpizza @@ -92,6 +96,7 @@ icon_state = "hawaiianpizzaslice" filling_color = "#e5b437" tastes = list("crust" = 1, "cheese" = 1, "pineapple" = 1) + goal_difficulty = FOOD_GOAL_EASY // Mac 'n' Cheese Pizza /obj/item/food/snacks/sliceable/pizza/macpizza @@ -110,6 +115,7 @@ icon_state = "macpizzaslice" filling_color = "#ffe45d" tastes = list("crust" = 1, "tomato" = 1, "cheese" = 2, "pasta" = 1) + goal_difficulty = FOOD_GOAL_EASY // Pepperoni Pizza /obj/item/food/snacks/sliceable/pizza/pepperonipizza @@ -128,6 +134,7 @@ icon_state = "pepperonipizzaslice" filling_color = "#ffe45d" tastes = list("cheese" = 3, "pepperoni" = 3, "grease" = 1) + goal_difficulty = FOOD_GOAL_EASY // Cheese Pizza /obj/item/food/snacks/sliceable/pizza/cheesepizza @@ -144,6 +151,7 @@ icon_state = "cheesepizzaslice" filling_color = "#BAA14C" tastes = list("crust" = 1, "tomato" = 1, "cheese" = 3) + goal_difficulty = FOOD_GOAL_EASY // Donk-pocket Pizza /obj/item/food/snacks/sliceable/pizza/donkpocketpizza @@ -161,6 +169,7 @@ icon_state = "donkpocketpizzaslice" filling_color = "#BAA14C" tastes = list("crust" = 1, "meat" = 1, "laziness" = 1) + goal_difficulty = FOOD_GOAL_EASY // Dank Pizza /obj/item/food/snacks/sliceable/pizza/dankpizza @@ -178,6 +187,7 @@ icon_state = "dankpizzaslice" filling_color = "#BAA14C" tastes = list("crust" = 1, "cheese" = 1, "special herbs" = 2) + goal_difficulty = FOOD_GOAL_EASY // Firecracker Pizza /obj/item/food/snacks/sliceable/pizza/firecrackerpizza @@ -195,6 +205,7 @@ icon_state = "firecrackerpizzaslice" filling_color = "#BAA14C" tastes = list("crust" = 1, "cheese" = 1, "HOTNESS" = 1) + goal_difficulty = FOOD_GOAL_EASY // "Pesto" Pizza /obj/item/food/snacks/sliceable/pizza/pestopizza @@ -212,6 +223,7 @@ icon_state = "pestopizzaslice" filling_color = "#BAA14C" tastes = list("tomato" = 1, "cheese" = 1, "wasabi" = 1) + goal_difficulty = FOOD_GOAL_EASY // Garlic Pizza /obj/item/food/snacks/sliceable/pizza/garlicpizza @@ -229,6 +241,7 @@ icon_state = "garlicpizzaslice" filling_color = "#BAA14C" tastes = list("crust" = 1, "cheese" = 1, "garlic" = 1) + goal_difficulty = FOOD_GOAL_EASY ////////////////////// diff --git a/code/modules/food_and_drinks/food/foods/sandwiches.dm b/code/modules/food_and_drinks/food/foods/sandwiches.dm index 05d584229845..42a9a4d0b694 100644 --- a/code/modules/food_and_drinks/food/foods/sandwiches.dm +++ b/code/modules/food_and_drinks/food/foods/sandwiches.dm @@ -19,6 +19,7 @@ bitesize = 3 list_reagents = list("nutriment" = 6, "vitamin" = 1) tastes = list("bun" = 4, "meat" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/burger/brain name = "brainburger" @@ -59,6 +60,7 @@ bitesize = 3 list_reagents = list("nutriment" = 6, "vitamin" = 1) tastes = list("bun" = 4, "meat" = 1, "cheese" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/burger/tofu name = "tofu burger" @@ -68,6 +70,7 @@ bitesize = 3 list_reagents = list("nutriment" = 6, "vitamin" = 1) tastes = list("bun" = 4, "tofu" = 4) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/burger/hamborger name = "hamborger" @@ -135,6 +138,7 @@ bitesize = 3 list_reagents = list("nutriment" = 10, "vitamin" = 2) tastes = list("bun" = 4, "meat" = 2, "cheese" = 2, "type two diabetes" = 10) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/burger/superbite name = "SuperBite burger" @@ -162,6 +166,7 @@ bitesize = 2 list_reagents = list("nutriment" = 7, "protein" = 1) tastes = list("bun" = 2, "meat" = 2, "white" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/burger/ppatty/red name = "red pretty patty" @@ -171,6 +176,7 @@ bitesize = 2 list_reagents = list("nutriment" = 7, "protein" = 1) tastes = list("bun" = 2, "meat" = 2, "red" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/burger/ppatty/orange name = "orange pretty patty" @@ -180,6 +186,7 @@ bitesize = 2 list_reagents = list("nutriment" = 7, "protein" = 1) tastes = list("bun" = 2, "meat" = 2, "orange" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/burger/ppatty/yellow name = "yellow pretty patty" @@ -189,6 +196,7 @@ bitesize = 2 list_reagents = list("nutriment" = 7, "protein" = 1) tastes = list("bun" = 2, "meat" = 2, "yellow" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/burger/ppatty/green name = "green pretty patty" @@ -198,6 +206,7 @@ bitesize = 2 list_reagents = list("nutriment" = 7, "protein" = 1) tastes = list("bun" = 2, "meat" = 2, "green" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/burger/ppatty/blue name = "blue pretty patty" @@ -207,6 +216,7 @@ bitesize = 2 list_reagents = list("nutriment" = 7, "protein" = 1) tastes = list("bun" = 2, "meat" = 2, "blue" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/burger/ppatty/purple name = "purple pretty patty" @@ -216,6 +226,7 @@ bitesize = 2 list_reagents = list("nutriment" = 7, "protein" = 1) tastes = list("bun" = 2, "meat" = 2, "purple" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/burger/ppatty/rainbow name = "rainbow pretty patty" @@ -225,6 +236,7 @@ bitesize = 4 list_reagents = list("nutriment" = 14, "protein" = 5, "omnizine" = 10) tastes = list("bun" = 2, "meat" = 2, "rainbow" = 5) + goal_difficulty = FOOD_GOAL_HARD /obj/item/food/snacks/burger/elec name = "empowered burger" @@ -234,6 +246,7 @@ bitesize = 2 list_reagents = list("nutriment" = 5, "protein" = 1, "plasma" = 2) tastes = list("bun" = 2, "pure electricity" = 5) + goal_difficulty = FOOD_GOAL_HARD /obj/item/food/snacks/burger/rat name = "mouse burger" @@ -261,6 +274,7 @@ bitesize = 3 list_reagents = list("nutriment" = 3, "vitamin" = 2, "protein" = 6) tastes = list("bun" = 1, "bacon" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/burger/bearger @@ -280,6 +294,7 @@ filling_color = "#F2B6EA" list_reagents = list("nutriment" = 4, "protein" = 6, "condensedcapsaicin" = 5, "capsaicin" = 5) tastes = list("bun" = 1, "extreme heat" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/burger/mcguffin name = "mcGuffin" @@ -289,6 +304,7 @@ filling_color = "#F2B6EA" list_reagents = list("nutriment" = 2, "protein" = 7, "vitamin" = 1) tastes = list("muffin" = 1, "bacon" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/burger/mcrib name = "mcRib" @@ -298,6 +314,7 @@ filling_color = "#F2B6EA" list_reagents = list("nutriment" = 2, "protein" = 7, "vitamin" = 4, "bbqsauce" = 1) tastes = list("bun" = 1, "pork" = 1, "patty" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/burger/jelly name = "jelly burger" @@ -308,10 +325,13 @@ tastes = list("bun" = 4, "jelly" = 2) /obj/item/food/snacks/burger/jelly/slime + name = "slime burger" list_reagents = list("nutriment" = 6, "slimejelly" = 5, "vitamin" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/burger/jelly/cherry list_reagents = list("nutriment" = 6, "cherryjelly" = 5, "vitamin" = 1) + goal_difficulty = FOOD_GOAL_NORMAL ////////////////////// @@ -326,6 +346,7 @@ filling_color = "#D9BE29" list_reagents = list("nutriment" = 6, "vitamin" = 1) tastes = list("meat" = 2, "cheese" = 1, "bread" = 2, "lettuce" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/toastedsandwich name = "toasted sandwich" @@ -335,6 +356,7 @@ filling_color = "#D9BE29" list_reagents = list("nutriment" = 6, "carbon" = 2) tastes = list("toast" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/grilledcheese name = "grilled cheese sandwich" @@ -344,6 +366,7 @@ filling_color = "#D9BE29" list_reagents = list("nutriment" = 7, "vitamin" = 1) //why make a regualr sandwhich when you can make grilled cheese, with this nutriment value? tastes = list("toast" = 1, "grilled cheese" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/jellysandwich name = "jelly sandwich" @@ -356,9 +379,12 @@ /obj/item/food/snacks/jellysandwich/slime list_reagents = list("nutriment" = 2, "slimejelly" = 5, "vitamin" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/jellysandwich/cherry + name = "slime sandwich" list_reagents = list("nutriment" = 2, "cherryjelly" = 5, "vitamin" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/notasandwich name = "not-a-sandwich" @@ -375,6 +401,7 @@ icon_state = "wrap" list_reagents = list("nutriment" = 5) tastes = list("egg" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/blt name = "\improper BLT" @@ -385,6 +412,7 @@ bitesize = 4 list_reagents = list("nutriment" = 5, "protein" = 2) tastes = list("bacon" = 3, "lettuce" = 2, "tomato" = 2, "bread" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/peanut_butter_jelly name = "peanut butter and jelly sandwich" @@ -396,10 +424,14 @@ tastes = list("peanut butter" = 3, "jelly" = 3, "bread" = 2) /obj/item/food/snacks/peanut_butter_jelly/slime + name = "peanut butter and slime sandwich" + desc = "A classic PB&J sandwich, just like your mom used to make?" list_reagents = list("peanutbutter" = 2, "slimejelly" = 5, "nutriment" = 5, "protein" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/peanut_butter_jelly/cherry list_reagents = list("peanutbutter" = 2, "cherryjelly" = 5, "nutriment" = 5, "protein" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/philly_cheesesteak name = "Philly cheesesteak" @@ -410,6 +442,7 @@ bitesize = 4 list_reagents = list("nutriment" = 10, "protein" = 4) tastes = list("steak" = 3, "melted cheese" = 3, "onions" = 2, "bread" = 2) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/peanut_butter_banana name = "peanut butter and banana sandwich" @@ -420,3 +453,4 @@ bitesize = 2 list_reagents = list("nutriment" = 5, "protein" = 2) tastes = list("peanutbutter" = 3, "banana" = 3, "bread" = 2) + goal_difficulty = FOOD_GOAL_NORMAL diff --git a/code/modules/food_and_drinks/food/foods/seafood.dm b/code/modules/food_and_drinks/food/foods/seafood.dm index 629886de6b54..69f88b307ecd 100644 --- a/code/modules/food_and_drinks/food/foods/seafood.dm +++ b/code/modules/food_and_drinks/food/foods/seafood.dm @@ -51,6 +51,7 @@ bitesize = 1 list_reagents = list("nutriment" = 4) tastes = list("fish" = 1, "bread" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/fishburger name = "Fillet-O-Carp sandwich" @@ -61,6 +62,7 @@ bitesize = 3 list_reagents = list("nutriment" = 6, "vitamin" = 1) tastes = list("bun" = 4, "fish" = 4) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/cubancarp name = "cuban carp" @@ -72,6 +74,7 @@ bitesize = 3 list_reagents = list("nutriment" = 6, "capsaicin" = 1) tastes = list("fish" = 4, "batter" = 1, "hot peppers" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/fishandchips name = "fish and chips" @@ -82,6 +85,7 @@ bitesize = 3 list_reagents = list("nutriment" = 6) tastes = list("fish" = 1, "chips" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/sashimi name = "carp sashimi" @@ -91,6 +95,7 @@ bitesize = 3 list_reagents = list("nutriment" = 6, "capsaicin" = 5) tastes = list("raw carp" = 1, "hot peppers" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/fried_shrimp name = "fried shrimp" @@ -100,6 +105,7 @@ bitesize = 3 list_reagents = list("nutriment" = 2) tastes = list("shrimp" = 1, "bread crumbs" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/boiled_shrimp name = "boiled shrimp" @@ -109,6 +115,7 @@ bitesize = 3 list_reagents = list("nutriment" = 2) tastes = list("shrimp" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/shrimp_skewer name = "shrimp skewer" @@ -119,6 +126,7 @@ bitesize = 3 list_reagents = list("nutriment" = 8) tastes = list("shrimp" = 4) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/fish_skewer name = "fish skewer" @@ -129,6 +137,7 @@ bitesize = 3 list_reagents = list("protein" = 6, "vitamin" = 4) tastes = list("shrimp" = 1, "batter" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/sliceable/Ebi_maki name = "ebi maki roll" @@ -149,6 +158,7 @@ bitesize = 3 list_reagents = list("nutriment" = 2) tastes = list("shrimp" = 1, "rice" = 1, "seaweed" = 1) + goal_difficulty = FOOD_GOAL_EASY /obj/item/food/snacks/sliceable/Ikura_maki name = "ikura maki roll" @@ -169,6 +179,7 @@ bitesize = 3 list_reagents = list("nutriment" = 2, "protein" = 1) tastes = list("salmon roe" = 1, "rice" = 1, "seaweed" = 1) + goal_difficulty = FOOD_GOAL_EASY /obj/item/food/snacks/sliceable/Sake_maki name = "sake maki roll" @@ -189,6 +200,7 @@ bitesize = 3 list_reagents = list("nutriment" = 2) tastes = list("raw salmon" = 1, "rice" = 1, "seaweed" = 1) + goal_difficulty = FOOD_GOAL_EASY /obj/item/food/snacks/sliceable/SmokedSalmon_maki name = "smoked salmon maki roll" @@ -209,6 +221,7 @@ bitesize = 3 list_reagents = list("nutriment" = 2) tastes = list("smoked salmon" = 1, "rice" = 1, "seaweed" = 1) + goal_difficulty = FOOD_GOAL_EASY /obj/item/food/snacks/sliceable/Tamago_maki name = "tamago maki roll" @@ -229,6 +242,7 @@ bitesize = 3 list_reagents = list("nutriment" = 2) tastes = list("egg" = 1, "rice" = 1, "seaweed" = 1) + goal_difficulty = FOOD_GOAL_EASY /obj/item/food/snacks/sliceable/Inari_maki name = "inari maki roll" @@ -249,6 +263,7 @@ bitesize = 3 list_reagents = list("nutriment" = 2) tastes = list("fried tofu" = 1, "rice" = 1, "seaweed" = 1) + goal_difficulty = FOOD_GOAL_EASY /obj/item/food/snacks/sliceable/Masago_maki name = "masago maki roll" @@ -269,6 +284,7 @@ bitesize = 3 list_reagents = list("nutriment" = 2, "protein" = 1) tastes = list("goldfish roe" = 1, "rice" = 1, "seaweed" = 1) + goal_difficulty = FOOD_GOAL_EASY /obj/item/food/snacks/sliceable/Tobiko_maki name = "tobiko maki roll" @@ -289,6 +305,7 @@ bitesize = 3 list_reagents = list("nutriment" = 2, "protein" = 1) tastes = list("shark roe" = 1, "rice" = 1, "seaweed" = 1) + goal_difficulty = FOOD_GOAL_EASY /obj/item/food/snacks/sliceable/TobikoEgg_maki name = "tobiko and egg maki roll" @@ -309,6 +326,7 @@ bitesize = 3 list_reagents = list("nutriment" = 2, "protein" = 1) tastes = list("shark roe" = 1, "rice" = 1, "egg" = 1, "seaweed" = 1) + goal_difficulty = FOOD_GOAL_EASY /obj/item/food/snacks/sliceable/Tai_maki name = "tai maki roll" @@ -329,6 +347,7 @@ bitesize = 3 list_reagents = list("nutriment" = 2) tastes = list("catfish" = 1, "rice" = 1, "seaweed" = 1) + goal_difficulty = FOOD_GOAL_EASY /obj/item/food/snacks/sushi_Unagi name = "unagi sushi" @@ -338,3 +357,4 @@ bitesize = 3 list_reagents = list("nutriment" = 2) tastes = list("grilled eel" = 1, "seaweed" = 1) + goal_difficulty = FOOD_GOAL_NORMAL diff --git a/code/modules/food_and_drinks/food/foods/side_dishes.dm b/code/modules/food_and_drinks/food/foods/side_dishes.dm index 648fd6f1038d..31e7aec36703 100644 --- a/code/modules/food_and_drinks/food/foods/side_dishes.dm +++ b/code/modules/food_and_drinks/food/foods/side_dishes.dm @@ -24,6 +24,7 @@ filling_color = "#EDDD00" list_reagents = list("nutriment" = 4) tastes = list("fries" = 3, "salt" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/cheesyfries name = "cheesy fries" @@ -33,6 +34,7 @@ filling_color = "#EDDD00" list_reagents = list("nutriment" = 6) tastes = list("fries" = 3, "cheese" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/tatortot name = "tator tot" @@ -41,6 +43,7 @@ list_reagents = list("nutriment" = 4) filling_color = "FFD700" tastes = list("fried potato" = 3, "valids" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/onionrings name = "onion rings" @@ -50,6 +53,7 @@ filling_color = "#C0C9A0" gender = PLURAL tastes = list("onion" = 3, "batter" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/carrotfries name = "carrot fries" @@ -59,6 +63,7 @@ filling_color = "#FAA005" list_reagents = list("plantmatter" = 3, "oculine" = 3, "vitamin" = 2) tastes = list("carrots" = 3, "salt" = 1) + goal_difficulty = FOOD_GOAL_NORMAL ////////////////////// @@ -71,6 +76,7 @@ icon_state = "beans" list_reagents = list("nutriment" = 10, "beans" = 10, "vitamin" = 3) tastes = list("beans" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /// mashed taters /obj/item/food/snacks/mashed_potatoes @@ -81,6 +87,7 @@ filling_color = "#D6D9C1" list_reagents = list("nutriment" = 5, "gravy" = 5, "mashedpotatoes" = 10, "vitamin" = 2) tastes = list("mashed potato" = 3, "gravy" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/stuffing name = "stuffing" @@ -89,6 +96,7 @@ filling_color = "#C9AC83" list_reagents = list("nutriment" = 3) tastes = list("bread crumbs" = 1, "herbs" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/loadedbakedpotato name = "loaded baked potato" @@ -97,6 +105,7 @@ filling_color = "#9C7A68" list_reagents = list("nutriment" = 6) tastes = list("potato" = 1, "cheese" = 1, "herbs" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/boiledrice name = "boiled rice" @@ -106,6 +115,7 @@ filling_color = "#FFFBDB" list_reagents = list("nutriment" = 5, "vitamin" = 1) tastes = list("rice" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/roastparsnip @@ -116,3 +126,4 @@ list_reagents = list("nutriment" = 3, "vitamin" = 4) filling_color = "#FF5500" tastes = list("parsnip" = 1) + goal_difficulty = FOOD_GOAL_NORMAL diff --git a/code/modules/food_and_drinks/food/foods/soups.dm b/code/modules/food_and_drinks/food/foods/soups.dm index d60b10a0d6e8..e2c4df37a92a 100644 --- a/code/modules/food_and_drinks/food/foods/soups.dm +++ b/code/modules/food_and_drinks/food/foods/soups.dm @@ -20,6 +20,7 @@ filling_color = "#785210" list_reagents = list("nutriment" = 8, "water" = 5, "vitamin" = 4) tastes = list("meatball" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/soup/slimesoup name = "slime soup" @@ -28,6 +29,7 @@ filling_color = "#C4DBA0" list_reagents = list("nutriment" = 5, "slimejelly" = 5, "water" = 5, "vitamin" = 4) tastes = list("slime" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/soup/bloodsoup name = "tomato soup" @@ -36,6 +38,7 @@ filling_color = "#FF0000" list_reagents = list("nutriment" = 2, "blood" = 10, "water" = 5, "vitamin" = 4) tastes = list("iron" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/soup/clownstears name = "clown's tears" @@ -52,6 +55,7 @@ filling_color = "#AFC4B5" list_reagents = list("nutriment" = 8, "water" = 5, "vitamin" = 4) tastes = list("vegetables" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/soup/nettlesoup name = "nettle soup" @@ -60,6 +64,7 @@ filling_color = "#AFC4B5" list_reagents = list("nutriment" = 8, "water" = 5, "vitamin" = 4) tastes = list("nettles" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/soup/mysterysoup name = "mystery soup" @@ -68,6 +73,7 @@ var/extra_reagent = null list_reagents = list("nutriment" = 6) tastes = list("chaos" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/soup/mysterysoup/Initialize(mapload) . = ..() @@ -96,6 +102,7 @@ filling_color = "#D92929" list_reagents = list("nutriment" = 5, "tomatojuice" = 10, "vitamin" = 3) tastes = list("tomato" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/soup/misosoup name = "miso soup" @@ -103,6 +110,7 @@ icon_state = "misosoup" list_reagents = list("nutriment" = 7, "vitamin" = 2) tastes = list("miso" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/soup/mushroomsoup name = "chantrelle soup" @@ -111,6 +119,7 @@ filling_color = "#E386BF" list_reagents = list("nutriment" = 8, "vitamin" = 4) tastes = list("mushroom" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/soup/beetsoup name = "beet soup" @@ -119,6 +128,7 @@ filling_color = "#FAC9FF" list_reagents = list("nutriment" = 7, "vitamin" = 2) tastes = list("beet" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/soup/beetsoup/Initialize(mapload) . = ..() @@ -131,6 +141,7 @@ filling_color = "#E386BF" list_reagents = list("nutriment" = 7, "protein" = 2) tastes = list("squirming" = 2, "tomato" = 2) + goal_difficulty = FOOD_GOAL_HARD /obj/item/food/snacks/soup/sweetpotatosoup name = "sweet potato soup" @@ -138,6 +149,7 @@ icon_state = "sweetpotatosoup" list_reagents = list("nutriment" = 5) tastes = list("sweet potato" = 1) + goal_difficulty = FOOD_GOAL_NORMAL /obj/item/food/snacks/soup/redbeetsoup name = "red beet soup" @@ -145,6 +157,8 @@ icon_state = "redbeetsoup" list_reagents = list("nutriment" = 5) tastes = list("red beet" = 1) + goal_difficulty = FOOD_GOAL_NORMAL + /obj/item/food/snacks/soup/frenchonionsoup name = "french onion soup" @@ -152,6 +166,8 @@ icon_state = "onionsoup" list_reagents = list("nutriment" = 8) tastes = list("caramelized onions" = 3, "cheese" = 1) + goal_difficulty = FOOD_GOAL_NORMAL + /obj/item/food/snacks/soup/zurek name = "zurek" @@ -159,6 +175,8 @@ icon_state = "zurek" list_reagents = list("nutriment" = 10, "protein" = 4) tastes = list("creamy vegetables" = 3, "sausage" = 2) + goal_difficulty = FOOD_GOAL_NORMAL + /obj/item/food/snacks/soup/cullenskink name = "cullen skink" @@ -166,6 +184,8 @@ icon_state = "cullen_skink" list_reagents = list("nutriment" = 10, "protein" = 4) tastes = list("creamy broth" = 2, "fish" = 2, "vegetables" = 2) + goal_difficulty = FOOD_GOAL_NORMAL + /obj/item/food/snacks/soup/chicken_noodle_soup name = "chicken noodle soup" @@ -173,6 +193,8 @@ icon_state = "chicken_noodle_soup" list_reagents = list("nutriment" = 10, "protein" = 4) tastes = list("broth" = 1, "chicken" = 1, "carrots" = 1, "noodles" = 1) + goal_difficulty = FOOD_GOAL_NORMAL + /obj/item/food/snacks/soup/cornchowder name = "corn chowder" @@ -180,6 +202,8 @@ icon_state = "corn_chowder" list_reagents = list("nutriment" = 10, "protein" = 4) tastes = list("creamy broth" = 1, "bacon" = 1, "mixed vegetables" = 1) + goal_difficulty = FOOD_GOAL_NORMAL + /obj/item/food/snacks/soup/meatball_noodles name = "meatball noodle soup" @@ -187,6 +211,8 @@ icon_state = "meatball_noodles" list_reagents = list("nutriment" = 10, "protein" = 4) tastes = list("bone broth" = 1, "meat" = 1, "gnocchi" = 1, "peanuts" = 1) + goal_difficulty = FOOD_GOAL_NORMAL + /obj/item/food/snacks/soup/seedsoup name = "Misklmæsch" //miskl = seed, mæsch = soup @@ -195,6 +221,8 @@ icon_state = "moth_seed_soup" list_reagents = list("nutriment" = 6) tastes = list("bitterness" = 1, "sourness" = 1, "nature" = 1) + goal_difficulty = FOOD_GOAL_NORMAL + ////////////////////// // Stews // @@ -208,6 +236,8 @@ bitesize = 7 list_reagents = list("nutriment" = 10, "oculine" = 5, "tomatojuice" = 5, "vitamin" = 5) tastes = list("tomato" = 1, "carrot" = 1) + goal_difficulty = FOOD_GOAL_NORMAL + /obj/item/food/snacks/stewedsoymeat name = "stewed soy meat" @@ -217,6 +247,8 @@ trash = /obj/item/trash/plate list_reagents = list("nutriment" = 8) tastes = list("soy" = 1, "vegetables" = 1) + goal_difficulty = FOOD_GOAL_NORMAL + /obj/item/food/snacks/soup/beanstew name = "Prickeldröndolhaskl" //prickeld = spicy, röndol = bean, haskl = stew @@ -224,6 +256,8 @@ icon_state = "moth_bean_stew" list_reagents = list("nutriment" = 10) tastes = list("beans" = 1, "cabbage" = 1, "spicy sauce" = 1) + goal_difficulty = FOOD_GOAL_NORMAL + /obj/item/food/snacks/soup/oatstew name = "Häfmisklhaskl" //häfmiskl = oat (häf from German hafer meaning oat, miskl meaning seed), haskl = stew @@ -231,6 +265,8 @@ icon_state = "moth_oat_stew" list_reagents = list("nutriment" = 10) tastes = list("oats" = 1, "sweet potato" = 1, "carrot" = 1, "pumpkin" = 1, "parsnip" = 1) + goal_difficulty = FOOD_GOAL_NORMAL + /obj/item/food/snacks/soup/hong_kong_borscht name = "hong kong borscht" @@ -238,6 +274,8 @@ icon_state = "hong_kong_borscht" list_reagents = list("nutriment" = 10, "protein" = 2) tastes = list("tomato" = 1, "cabbage" = 1, "meat" = 1) + goal_difficulty = FOOD_GOAL_NORMAL + /obj/item/food/snacks/soup/hong_kong_macaroni name = "hong kong macaroni" @@ -245,6 +283,8 @@ icon_state = "hong_kong_macaroni" list_reagents = list("nutriment" = 8, "protein" = 2) tastes = list("cream" = 1, "chicken" = 1, "pasta" = 1, "ham" =1) + goal_difficulty = FOOD_GOAL_NORMAL + ////////////////////// // Chili // @@ -257,6 +297,8 @@ filling_color = "#FF3C00" list_reagents = list("nutriment" = 5, "capsaicin" = 1, "tomatojuice" = 2, "vitamin" = 2) tastes = list("hot peppers" = 1, "tomato" = 1) + goal_difficulty = FOOD_GOAL_NORMAL + /obj/item/food/snacks/soup/coldchili name = "cold chili" @@ -265,6 +307,8 @@ filling_color = "#2B00FF" list_reagents = list("nutriment" = 5, "frostoil" = 1, "tomatojuice" = 2, "vitamin" = 2) tastes = list("tomato" = 1, "mint" = 1) + goal_difficulty = FOOD_GOAL_NORMAL + /obj/item/food/snacks/soup/clownchili name = "chili con carnival" diff --git a/code/modules/food_and_drinks/food_base.dm b/code/modules/food_and_drinks/food_base.dm index 64facc6b031f..d748c00e5bd8 100644 --- a/code/modules/food_and_drinks/food_base.dm +++ b/code/modules/food_and_drinks/food_base.dm @@ -29,6 +29,10 @@ var/temperature_min = 0 // To limit the temperature of a reagent container can attain when exposed to heat/cold var/temperature_max = 10000 + // How difficult is this food for the kitchen to make? + // Affects the quantity of food that is requested by CC. + var/goal_difficulty = REAGENT_GOAL_SKIP + /obj/item/food/Initialize(mapload) . = ..() diff --git a/code/modules/food_and_drinks/kitchen_machinery/kitchen_machine.dm b/code/modules/food_and_drinks/kitchen_machinery/kitchen_machine.dm index 8db5fa8e3199..06597129b2e6 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/kitchen_machine.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/kitchen_machine.dm @@ -83,7 +83,7 @@ default_deconstruction_crowbar(user, O) if(dirty == MAX_DIRT) // The machine is all dirty so can't be used! - if(istype(O, /obj/item/reagent_containers/spray/cleaner) || istype(O, /obj/item/soap)) // If they're trying to clean it then let them + if(istype(O, /obj/item/reagent_containers/spray/cleaner) || istype(O, /obj/item/soap) || istype(O, /obj/item/reagent_containers/glass/rag)) // If they're trying to clean it then let them user.visible_message("[user] starts to clean [src].", "You start to clean [src].") if(do_after(user, 20 * O.toolspeed, target = src)) user.visible_message("[user] has cleaned [src].", "You have cleaned [src].") diff --git a/code/modules/hydroponics/grown/kudzu.dm b/code/modules/hydroponics/grown/kudzu.dm index 6eb13e46ead0..1f08ff6b3473 100644 --- a/code/modules/hydroponics/grown/kudzu.dm +++ b/code/modules/hydroponics/grown/kudzu.dm @@ -44,7 +44,7 @@ var/text = ..() var/text_string = "" for(var/datum/spacevine_mutation/SM in mutations) - text_string += "[(text_string == "") ? "" : ", "][SM.name]" + text_string += "[(text_string == "") ? "" : ", "][initial(SM.name)]" text += "\n- Plant Mutations: [(text_string == "") ? "None" : text_string]" return text @@ -53,7 +53,7 @@ if(S.has_reagent("sterilizine", 5)) for(var/datum/spacevine_mutation/SM in mutations) - if(SM.quality == SPACEVINE_MUTATION_NEGATIVE) + if(initial(SM.quality) == SPACEVINE_MUTATION_NEGATIVE) temp_mut_list += SM if(prob(20) && temp_mut_list.len) mutations.Remove(pick(temp_mut_list)) @@ -61,7 +61,7 @@ if(S.has_reagent("fuel", 5)) for(var/datum/spacevine_mutation/SM in mutations) - if(SM.quality == SPACEVINE_MUTATION_POSITIVE) + if(initial(SM.quality) == SPACEVINE_MUTATION_POSITIVE) temp_mut_list += SM if(prob(20) && temp_mut_list.len) mutations.Remove(pick(temp_mut_list)) @@ -69,7 +69,7 @@ if(S.has_reagent("phenol", 5)) for(var/datum/spacevine_mutation/SM in mutations) - if(SM.quality == SPACEVINE_MUTATION_MINOR_NEGATIVE) + if(initial(SM.quality) == SPACEVINE_MUTATION_MINOR_NEGATIVE) temp_mut_list += SM if(prob(20) && temp_mut_list.len) mutations.Remove(pick(temp_mut_list)) diff --git a/code/modules/lavaland/lavaland_theme.dm b/code/modules/lavaland/lavaland_theme.dm index 7fa5a9088fa6..20dfdecb38ae 100644 --- a/code/modules/lavaland/lavaland_theme.dm +++ b/code/modules/lavaland/lavaland_theme.dm @@ -1,3 +1,8 @@ +/// Approximate lower bound of the walkable land area on Lavaland, north of the southern lava border. +#define LAVALAND_MIN_CAVE_Y 10 +/// Approximate upper bound of the walkable land area on Lavaland, south of the Legion entrance. +#define LAVALAND_MAX_CAVE_Y 222 + /datum/lavaland_theme /// Name of lavaland theme var/name = "Not Specified" @@ -12,6 +17,20 @@ else if(!ispath(primary_turf_type)) stack_trace("Wrong turf type `[primary_turf_type.type]` in `[type]` lavaland theme") +/datum/lavaland_theme/proc/setup_caves() + var/max_attempts = 100 + var/max_cave_spawns = 40 + var/z = level_name_to_num(MINING) + while(max_attempts > 0 && max_cave_spawns > 0) + var/x = rand(1, world.maxx) + var/y = rand(LAVALAND_MIN_CAVE_Y, LAVALAND_MAX_CAVE_Y) + var/turf/next_turf = locate(x, y, z) + var/area/next_area = get_area(next_turf) + if(istype(next_turf, /turf/simulated/mineral/random/volcanic) && istype(next_area, /area/lavaland/surface/outdoors/unexplored/danger)) + next_turf.ChangeTurf(/turf/simulated/floor/plating/asteroid/airless/cave/volcanic, FALSE, TRUE, TRUE) + max_cave_spawns-- + max_attempts-- + /** * This proc should do all theme specific thing. * Now it only generates rivers, but it can do all stuff you desire. @@ -46,3 +65,6 @@ /datum/lavaland_theme/chasm/setup() var/datum/river_spawner/spawner = new(level_name_to_num(MINING), spread_prob_ = 10, spread_prob_loss_ = 5) spawner.generate(nodes = 6, min_x = 50, min_y = 7, max_x = 250, max_y = 225) + +#undef LAVALAND_MIN_CAVE_Y +#undef LAVALAND_MAX_CAVE_Y diff --git a/code/modules/mapping/cerestation.dm b/code/modules/mapping/cerestation.dm deleted file mode 100644 index 20c533338da2..000000000000 --- a/code/modules/mapping/cerestation.dm +++ /dev/null @@ -1,6 +0,0 @@ -/datum/map/cerestation - fluff_name = "NSS Farragus" - technical_name = "CereStation" - map_path = "_maps/map_files/cerestation/cerestation.dmm" - webmap_url = "https://webmap.affectedarc07.co.uk/maps/paradise/cerestation/" - min_players_random = 60 diff --git a/code/modules/mapping/cyberiad.dm b/code/modules/mapping/cyberiad.dm deleted file mode 100644 index bc6496192d87..000000000000 --- a/code/modules/mapping/cyberiad.dm +++ /dev/null @@ -1,5 +0,0 @@ -/datum/map/cyberiad - fluff_name = "NSS Cyberiad" - technical_name = "Cyberiad" - map_path = "_maps/map_files/cyberiad/cyberiad.dmm" - webmap_url = "https://webmap.affectedarc07.co.uk/maps/paradise/cyberiad/" diff --git a/code/modules/mapping/delta.dm b/code/modules/mapping/delta.dm deleted file mode 100644 index ed0d91dc0bae..000000000000 --- a/code/modules/mapping/delta.dm +++ /dev/null @@ -1,5 +0,0 @@ -/datum/map/delta - fluff_name = "NSS Kerberos" - technical_name = "Delta" - map_path = "_maps/map_files/Delta/delta.dmm" - webmap_url = "https://webmap.affectedarc07.co.uk/maps/paradise/deltastation/" diff --git a/code/modules/mapping/metastation.dm b/code/modules/mapping/metastation.dm deleted file mode 100644 index d1a486bfc666..000000000000 --- a/code/modules/mapping/metastation.dm +++ /dev/null @@ -1,5 +0,0 @@ -/datum/map/metastation - fluff_name = "NSS Cerebron" - technical_name = "MetaStation" - map_path = "_maps/map_files/MetaStation/MetaStation.dmm" - webmap_url = "https://webmap.affectedarc07.co.uk/maps/paradise/metastation/" diff --git a/code/modules/mapping/station_datums.dm b/code/modules/mapping/station_datums.dm new file mode 100644 index 000000000000..1f0356abc464 --- /dev/null +++ b/code/modules/mapping/station_datums.dm @@ -0,0 +1,30 @@ +/datum/map/boxstation + fluff_name = "NSS Cyberiad" + technical_name = "Cyberiad" + map_path = "_maps/map_files/stations/boxstation.dmm" + webmap_url = "https://webmap.affectedarc07.co.uk/maps/paradise/cyberiad/" + +/datum/map/metastation + fluff_name = "NSS Cerebron" + technical_name = "MetaStation" + map_path = "_maps/map_files/stations/metastation.dmm" + webmap_url = "https://webmap.affectedarc07.co.uk/maps/paradise/metastation/" + +/datum/map/deltastation + fluff_name = "NSS Kerberos" + technical_name = "Delta" + map_path = "_maps/map_files/stations/deltastation.dmm" + webmap_url = "https://webmap.affectedarc07.co.uk/maps/paradise/deltastation/" + +/datum/map/cerestation + fluff_name = "NSS Farragus" + technical_name = "CereStation" + map_path = "_maps/map_files/stations/cerestation.dmm" + webmap_url = "https://webmap.affectedarc07.co.uk/maps/paradise/cerestation/" + min_players_random = 60 + +/datum/map/test_tiny + fluff_name = "test_tiny" + technical_name = "test_tiny" + map_path = "_maps/map_files/test_tiny/test_tiny.dmm" + voteable = FALSE diff --git a/code/modules/mapping/test_tiny.dm b/code/modules/mapping/test_tiny.dm deleted file mode 100644 index 0c6294c15d0f..000000000000 --- a/code/modules/mapping/test_tiny.dm +++ /dev/null @@ -1,5 +0,0 @@ -/datum/map/test_tiny - fluff_name = "test_tiny" - technical_name = "test_tiny" - map_path = "_maps/map_files/test_tiny/test_tiny.dmm" - voteable = FALSE diff --git a/code/modules/martial_arts/combos/plasma_fist/tornado_sweep.dm b/code/modules/martial_arts/combos/plasma_fist/tornado_sweep.dm index a3e948a21f1c..bc1d44bebfc7 100644 --- a/code/modules/martial_arts/combos/plasma_fist/tornado_sweep.dm +++ b/code/modules/martial_arts/combos/plasma_fist/tornado_sweep.dm @@ -6,7 +6,7 @@ /datum/martial_combo/plasma_fist/tornado_sweep/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) user.say("TORNADO SWEEP!") INVOKE_ASYNC(src, PROC_REF(do_tornado_effect), user) - var/obj/effect/proc_holder/spell/aoe/repulse/R = new(null) + var/datum/spell/aoe/repulse/R = new(null) var/list/turfs = list() for(var/turf/T in range(1,user)) turfs.Add(T) diff --git a/code/modules/mining/lavaland/loot/ashdragon_loot.dm b/code/modules/mining/lavaland/loot/ashdragon_loot.dm index c5b852393cc9..594db13d7aff 100644 --- a/code/modules/mining/lavaland/loot/ashdragon_loot.dm +++ b/code/modules/mining/lavaland/loot/ashdragon_loot.dm @@ -217,7 +217,7 @@ if(2) to_chat(user, "Power courses through you! You can now shift your form at will.") if(user.mind) - var/obj/effect/proc_holder/spell/shapeshift/dragon/D = new + var/datum/spell/shapeshift/dragon/D = new user.mind.AddSpell(D) if(3) to_chat(user, "You feel like you could walk straight through lava now.") diff --git a/code/modules/mining/lavaland/loot/colossus_loot.dm b/code/modules/mining/lavaland/loot/colossus_loot.dm index 64b6b1241dce..fb45849581f2 100644 --- a/code/modules/mining/lavaland/loot/colossus_loot.dm +++ b/code/modules/mining/lavaland/loot/colossus_loot.dm @@ -350,7 +350,7 @@ ADD_TRAIT(L, TRAIT_MUTE, STASIS_MUTE) L.status_flags |= GODMODE L.mind.transfer_to(holder_animal) - var/obj/effect/proc_holder/spell/exit_possession/P = new /obj/effect/proc_holder/spell/exit_possession + var/datum/spell/exit_possession/P = new /datum/spell/exit_possession holder_animal.mind.AddSpell(P) remove_verb(holder_animal, /mob/living/verb/pulled) @@ -362,7 +362,7 @@ L.notransform = FALSE if(holder_animal && !QDELETED(holder_animal)) holder_animal.mind.transfer_to(L) - L.mind.RemoveSpell(/obj/effect/proc_holder/spell/exit_possession) + L.mind.RemoveSpell(/datum/spell/exit_possession) if(kill || !isanimal(loc)) L.death(0) ..() @@ -373,7 +373,7 @@ /obj/structure/closet/stasis/ex_act() return -/obj/effect/proc_holder/spell/exit_possession +/datum/spell/exit_possession name = "Exit Possession" desc = "Exits the body you are possessing" base_cooldown = 60 @@ -382,10 +382,10 @@ action_icon_state = "exit_possession" sound = null -/obj/effect/proc_holder/spell/exit_possession/create_new_targeting() +/datum/spell/exit_possession/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/exit_possession/cast(list/targets, mob/user = usr) +/datum/spell/exit_possession/cast(list/targets, mob/user = usr) if(!isfloorturf(user.loc)) return var/datum/mind/target_mind = user.mind @@ -397,4 +397,4 @@ qdel(S) break current.gib() - target_mind.RemoveSpell(/obj/effect/proc_holder/spell/exit_possession) + target_mind.RemoveSpell(/datum/spell/exit_possession) diff --git a/code/modules/mob/dead/observer/observer_base.dm b/code/modules/mob/dead/observer/observer_base.dm index 9bf21554c174..d1c642334ed3 100644 --- a/code/modules/mob/dead/observer/observer_base.dm +++ b/code/modules/mob/dead/observer/observer_base.dm @@ -53,7 +53,7 @@ GLOBAL_DATUM_INIT(ghost_crew_monitor, /datum/ui_module/crew_monitor/ghost, new) /mob/dead/observer/proc/open_spawners_menu)) // Our new boo spell. - AddSpell(new /obj/effect/proc_holder/spell/boo(null)) + AddSpell(new /datum/spell/boo(null)) can_reenter_corpse = flags & GHOST_CAN_REENTER started_as_observer = flags & GHOST_IS_OBSERVER diff --git a/code/modules/mob/dead/observer/spells.dm b/code/modules/mob/dead/observer/spells.dm index 46f0f4342d66..5128f8a9bb2f 100644 --- a/code/modules/mob/dead/observer/spells.dm +++ b/code/modules/mob/dead/observer/spells.dm @@ -9,7 +9,7 @@ GLOBAL_LIST_INIT(boo_phrases, list( "It feels like someone's standing behind you.", )) -/obj/effect/proc_holder/spell/boo +/datum/spell/boo name = "Boo!" desc = "Fuck with the living." selection_deactivated_message = "Your presence will not be known. For now." @@ -29,13 +29,13 @@ GLOBAL_LIST_INIT(boo_phrases, list( create_attack_logs = FALSE -/obj/effect/proc_holder/spell/boo/create_new_targeting() +/datum/spell/boo/create_new_targeting() var/datum/spell_targeting/click/T = new() T.allowed_type = /atom T.try_auto_target = FALSE return T -/obj/effect/proc_holder/spell/boo/cast(list/targets, mob/user = usr) +/datum/spell/boo/cast(list/targets, mob/user = usr) var/atom/target = targets[1] ASSERT(istype(target)) diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/alien_drone.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/alien_drone.dm index 35c75e4931a4..a9b25613ae63 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/caste/alien_drone.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/caste/alien_drone.dm @@ -9,7 +9,7 @@ . = ..() name = "alien drone ([rand(1, 1000)])" real_name = name - AddSpell(new /obj/effect/proc_holder/spell/alien_spell/evolve_queen) + AddSpell(new /datum/spell/alien_spell/evolve_queen) /mob/living/carbon/alien/humanoid/drone/get_caste_organs() . = ..() diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm index f952bfe2797c..fcb649ab9b4b 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm @@ -23,7 +23,7 @@ real_name = name add_language("Xenomorph") add_language("Hivemind") - AddSpell(new /obj/effect/proc_holder/spell/alien_spell/regurgitate) + AddSpell(new /datum/spell/alien_spell/regurgitate) . = ..() AddComponent(/datum/component/footstep, FOOTSTEP_MOB_CLAW, 0.5, -11) diff --git a/code/modules/mob/living/carbon/alien/humanoid/queen.dm b/code/modules/mob/living/carbon/alien/humanoid/queen.dm index 1d0e6e931de6..84a31d4d7a43 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/queen.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/queen.dm @@ -16,7 +16,7 @@ /mob/living/carbon/alien/humanoid/queen/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_FORCE_DOORS, UNIQUE_TRAIT_SOURCE(src)) - AddSpell(new /obj/effect/proc_holder/spell/alien_spell/tail_lash) + AddSpell(new /datum/spell/alien_spell/tail_lash) /mob/living/carbon/alien/humanoid/queen/get_caste_organs() . = ..() diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm index 7f9bb302712f..3d0e6508cc51 100644 --- a/code/modules/mob/living/carbon/alien/larva/larva.dm +++ b/code/modules/mob/living/carbon/alien/larva/larva.dm @@ -25,7 +25,7 @@ regenerate_icons() add_language("Xenomorph") add_language("Hivemind") - AddSpell(new /obj/effect/proc_holder/spell/alien_spell/evolve_larva) + AddSpell(new /datum/spell/alien_spell/evolve_larva) var/datum/action/innate/hide/alien_larva_hide/hide = new() hide.Grant(src) diff --git a/code/modules/mob/living/carbon/human/npcs.dm b/code/modules/mob/living/carbon/human/npcs.dm index bfb37b40a4a8..6974075c918f 100644 --- a/code/modules/mob/living/carbon/human/npcs.dm +++ b/code/modules/mob/living/carbon/human/npcs.dm @@ -107,5 +107,5 @@ /mob/living/carbon/human/monkey/magic/mind_checks() if(!..()) return FALSE - mind.AddSpell(new /obj/effect/proc_holder/spell/turf_teleport/blink(null)) + mind.AddSpell(new /datum/spell/turf_teleport/blink(null)) mind.special_role = SPECIAL_ROLE_WIZARD diff --git a/code/modules/mob/living/carbon/human/species/golem.dm b/code/modules/mob/living/carbon/human/species/golem.dm index 2c1426512eaf..eb8f49a44142 100644 --- a/code/modules/mob/living/carbon/human/species/golem.dm +++ b/code/modules/mob/living/carbon/human/species/golem.dm @@ -654,8 +654,8 @@ H.equip_to_slot_or_del(new /obj/item/reagent_containers/drinks/bottle/bottleofnothing(H), SLOT_HUD_RIGHT_STORE) H.equip_to_slot_or_del(new /obj/item/cane(H), SLOT_HUD_LEFT_HAND) if(H.mind) - H.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe/conjure/build/mime_wall(null)) - H.mind.AddSpell(new /obj/effect/proc_holder/spell/mime/speak(null)) + H.mind.AddSpell(new /datum/spell/aoe/conjure/build/mime_wall(null)) + H.mind.AddSpell(new /datum/spell/mime/speak(null)) H.mind.miming = TRUE /datum/unarmed_attack/golem/tranquillite diff --git a/code/modules/mob/living/carbon/superheroes.dm b/code/modules/mob/living/carbon/superheroes.dm index 85528b51b87a..e3bc02451f17 100644 --- a/code/modules/mob/living/carbon/superheroes.dm +++ b/code/modules/mob/living/carbon/superheroes.dm @@ -36,7 +36,7 @@ /datum/superheroes/proc/assign_spells(mob/living/carbon/human/H) if(default_spells.len) for(var/spell in default_spells) - var/obj/effect/proc_holder/spell/S = spell + var/datum/spell/S = spell if(!S) return H.mind.AddSpell(new S(null)) @@ -82,7 +82,7 @@ /datum/superheroes/griffin name = "The Griffin" - default_spells = list(/obj/effect/proc_holder/spell/recruit) + default_spells = list(/datum/spell/recruit) class = "Supervillain" desc = "You are The Griffin, the ultimate supervillain. You thrive on chaos and have no respect for the supposed authority \ of the command staff of this station. Along with your gang of dim-witted yet trusty henchmen, you will be able to execute \ @@ -106,7 +106,7 @@ desc = "You are LightnIan, the lord of lightning! A freak electrical accident while working in the station's kennel \ has given you mastery over lightning and a peculiar desire to sniff butts. Although you are a recent addition to the \ station's hero roster, you intend to leave your mark." - default_spells = list(/obj/effect/proc_holder/spell/charge_up/bounce/lightning/lightnian) + default_spells = list(/datum/spell/charge_up/bounce/lightning/lightnian) /datum/superheroes/lightnian/equip(mob/living/carbon/human/H) ..() @@ -125,7 +125,7 @@ desc = "You were a roboticist, once. Now you are Electro-Negmatic, a name this station will learn to fear. You designed \ your costume to resemble E-N, your faithful dog that some callous RD destroyed because it was sparking up the plasma. You \ intend to take your revenge and make them all pay thanks to your magnetic powers." - default_spells = list(/obj/effect/proc_holder/spell/charge_up/bounce/magnet) + default_spells = list(/datum/spell/charge_up/bounce/magnet) /datum/superheroes/electro/equip(mob/living/carbon/human/H) ..() @@ -143,7 +143,7 @@ //The Griffin's special recruit abilitiy -/obj/effect/proc_holder/spell/recruit +/datum/spell/recruit name = "Recruit Greyshirt" desc = "Allows you to recruit a conscious, non-braindead, non-catatonic human to be part of the Greyshirts, your personal henchmen. This works on Assistants only and you can recruit a maximum of 3!." base_cooldown = 450 @@ -151,16 +151,16 @@ action_icon_state = "spell_greytide" var/recruiting = 0 - selection_activated_message = "You start preparing a mindblowing monologue. Left-click to cast at a target!" + selection_activated_message = "You start preparing a mindblowing monologue. Left-click to cast at a target!" selection_deactivated_message = "You decide to save your brilliance for another day." -/obj/effect/proc_holder/spell/recruit/create_new_targeting() +/datum/spell/recruit/create_new_targeting() var/datum/spell_targeting/click/T = new() T.click_radius = -1 T.range = 1 return T -/obj/effect/proc_holder/spell/recruit/can_cast(mob/user = usr, charge_check = TRUE, show_message = FALSE) +/datum/spell/recruit/can_cast(mob/user = usr, charge_check = TRUE, show_message = FALSE) if(SSticker.mode.greyshirts.len >= 3) if(show_message) to_chat(user, "You have already recruited the maximum number of henchmen.") @@ -171,10 +171,10 @@ return FALSE return ..() -/obj/effect/proc_holder/spell/recruit/valid_target(mob/living/carbon/human/target, user) +/datum/spell/recruit/valid_target(mob/living/carbon/human/target, user) return target.ckey && !target.stat -/obj/effect/proc_holder/spell/recruit/cast(list/targets,mob/living/user = usr) +/datum/spell/recruit/cast(list/targets,mob/living/user = usr) var/mob/living/carbon/human/target = targets[1] if(target.mind.assigned_role != "Assistant") to_chat(user, "You can only recruit Assistants.") diff --git a/code/modules/mob/living/silicon/ai/ai_mob.dm b/code/modules/mob/living/silicon/ai/ai_mob.dm index f660e415f72a..1fcd822f3838 100644 --- a/code/modules/mob/living/silicon/ai/ai_mob.dm +++ b/code/modules/mob/living/silicon/ai/ai_mob.dm @@ -69,7 +69,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list( //MALFUNCTION var/datum/module_picker/malf_picker - var/datum/action/innate/ai/choose_modules/modules_action + var/datum/spell/ai_spell/choose_modules/modules_action var/list/datum/AI_Module/current_modules = list() var/can_dominate_mechs = FALSE var/shunted = FALSE // TRUE if the AI is currently shunted. Used to differentiate between shunted and ghosted/braindead @@ -1422,7 +1422,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list( view_core() //A BYOND bug requires you to be viewing your core before your verbs update malf_picker = new /datum/module_picker modules_action = new(malf_picker) - modules_action.Grant(src) + AddSpell(modules_action) ///Removes all malfunction-related /datum/action's from the target AI. /mob/living/silicon/ai/proc/remove_malf_abilities() diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 4513504e42d1..3f160ea41516 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -103,8 +103,8 @@ add_language("Gutter") add_language("Trinary") - AddSpell(new /obj/effect/proc_holder/spell/access_software_pai) - AddSpell(new /obj/effect/proc_holder/spell/unfold_chassis_pai) + AddSpell(new /datum/spell/access_software_pai) + AddSpell(new /datum/spell/unfold_chassis_pai) //PDA pda = new(src) @@ -241,7 +241,7 @@ // mobile pai mob. This also includes handling some of the general shit that can occur // to it. Really this deserves its own file, but for the moment it can sit here. ~ Z -/obj/effect/proc_holder/spell/unfold_chassis_pai +/datum/spell/unfold_chassis_pai name = "Unfold/Fold Chassis" desc = "Allows you to fold in/out of your mobile form." clothes_req = FALSE @@ -249,10 +249,10 @@ action_icon_state = "repairbot" action_background_icon_state = "bg_tech_blue" -/obj/effect/proc_holder/spell/unfold_chassis_pai/create_new_targeting() +/datum/spell/unfold_chassis_pai/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/unfold_chassis_pai/cast(list/targets, mob/living/user = usr) +/datum/spell/unfold_chassis_pai/cast(list/targets, mob/living/user = usr) var/mob/living/silicon/pai/pai_user = user if(pai_user.loc != pai_user.card) diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm index be46669274a0..57de621d475a 100644 --- a/code/modules/mob/living/silicon/pai/software.dm +++ b/code/modules/mob/living/silicon/pai/software.dm @@ -12,7 +12,7 @@ GLOBAL_LIST_INIT(pai_emotions, list( GLOBAL_LIST_EMPTY(pai_software_by_key) -/obj/effect/proc_holder/spell/access_software_pai +/datum/spell/access_software_pai name = "Software interface" desc = "Allows you to access your downloaded software." clothes_req = FALSE @@ -20,10 +20,10 @@ GLOBAL_LIST_EMPTY(pai_software_by_key) action_icon_state = "choose_module" action_background_icon_state = "bg_tech_blue" -/obj/effect/proc_holder/spell/access_software_pai/create_new_targeting() +/datum/spell/access_software_pai/create_new_targeting() return new /datum/spell_targeting/self -/obj/effect/proc_holder/spell/access_software_pai/cast(list/targets, mob/living/user = usr) +/datum/spell/access_software_pai/cast(list/targets, mob/living/user = usr) var/mob/living/silicon/pai/pai_user = user pai_user.ui_interact(pai_user) diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm index 1540c3aaf069..7a51a6bc812d 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -155,7 +155,7 @@ construct_type = "juggernaut" mob_size = MOB_SIZE_LARGE move_resist = MOVE_FORCE_STRONG - construct_spells = list(/obj/effect/proc_holder/spell/night_vision, /obj/effect/proc_holder/spell/aoe/conjure/build/lesserforcewall) + construct_spells = list(/datum/spell/night_vision, /datum/spell/aoe/conjure/build/lesserforcewall) force_threshold = 11 playstyle_string = "You are a Juggernaut. Though slow, your shell can withstand extreme punishment, \ create shield walls, rip apart enemies and walls." @@ -191,7 +191,7 @@ attacktext = "slashes" attack_sound = 'sound/weapons/bladeslice.ogg' construct_type = "wraith" - construct_spells = list(/obj/effect/proc_holder/spell/night_vision, /obj/effect/proc_holder/spell/ethereal_jaunt/shift) + construct_spells = list(/datum/spell/night_vision, /datum/spell/ethereal_jaunt/shift) retreat_distance = 2 //AI wraiths will move in and out of combat playstyle_string = "You are a Wraith. Though relatively fragile, you are fast, deadly, and even able to phase through walls." @@ -227,13 +227,13 @@ minimum_distance = 10 //AI artificers will flee like fuck attack_sound = 'sound/weapons/punch2.ogg' construct_type = "builder" - construct_spells = list(/obj/effect/proc_holder/spell/night_vision, - /obj/effect/proc_holder/spell/projectile/magic_missile/lesser, - /obj/effect/proc_holder/spell/aoe/conjure/construct/lesser, - /obj/effect/proc_holder/spell/aoe/conjure/build/wall, - /obj/effect/proc_holder/spell/aoe/conjure/build/floor, - /obj/effect/proc_holder/spell/aoe/conjure/build/pylon, - /obj/effect/proc_holder/spell/aoe/conjure/build/soulstone) + construct_spells = list(/datum/spell/night_vision, + /datum/spell/projectile/magic_missile/lesser, + /datum/spell/aoe/conjure/construct/lesser, + /datum/spell/aoe/conjure/build/wall, + /datum/spell/aoe/conjure/build/floor, + /datum/spell/aoe/conjure/build/pylon, + /datum/spell/aoe/conjure/build/soulstone) playstyle_string = "You are an Artificer. You are incredibly weak and fragile, but you are able to construct fortifications, \ use magic missile, repair allied constructs (by clicking on them), \ @@ -334,10 +334,10 @@ environment_smash = ENVIRONMENT_SMASH_RWALLS attack_sound = 'sound/weapons/tap.ogg' construct_type = "harvester" - construct_spells = list(/obj/effect/proc_holder/spell/night_vision, - /obj/effect/proc_holder/spell/aoe/conjure/build/wall, - /obj/effect/proc_holder/spell/aoe/conjure/build/floor, - /obj/effect/proc_holder/spell/smoke/disable) + construct_spells = list(/datum/spell/night_vision, + /datum/spell/aoe/conjure/build/wall, + /datum/spell/aoe/conjure/build/floor, + /datum/spell/smoke/disable) retreat_distance = 2 //AI harvesters will move in and out of combat, like wraiths, but shittier playstyle_string = "You are a Harvester. You are not strong, but your powers of domination will assist you in your role: \ Bring those who still cling to this world of illusion back to the master so they may know Truth." diff --git a/code/modules/mob/living/simple_animal/hostile/angel_statue.dm b/code/modules/mob/living/simple_animal/hostile/angel_statue.dm index f112f4102544..9f09935dba55 100644 --- a/code/modules/mob/living/simple_animal/hostile/angel_statue.dm +++ b/code/modules/mob/living/simple_animal/hostile/angel_statue.dm @@ -56,9 +56,9 @@ /mob/living/simple_animal/hostile/statue/Initialize(mapload, mob/living/creator) . = ..() // Give spells - AddSpell(new /obj/effect/proc_holder/spell/aoe/flicker_lights(null)) - AddSpell(new /obj/effect/proc_holder/spell/aoe/blindness(null)) - AddSpell(new /obj/effect/proc_holder/spell/night_vision(null)) + AddSpell(new /datum/spell/aoe/flicker_lights(null)) + AddSpell(new /datum/spell/aoe/blindness(null)) + AddSpell(new /datum/spell/night_vision(null)) // Set creator if(creator) @@ -160,7 +160,7 @@ // Statue powers // Flicker lights -/obj/effect/proc_holder/spell/aoe/flicker_lights +/datum/spell/aoe/flicker_lights name = "Flicker Lights" desc = "You will trigger a large amount of lights around you to flicker." @@ -168,18 +168,18 @@ clothes_req = FALSE aoe_range = 14 -/obj/effect/proc_holder/spell/aoe/flicker_lights/create_new_targeting() +/datum/spell/aoe/flicker_lights/create_new_targeting() var/datum/spell_targeting/aoe/turf/targeting = new() targeting.range = aoe_range return targeting -/obj/effect/proc_holder/spell/aoe/flicker_lights/cast(list/targets, mob/user = usr) +/datum/spell/aoe/flicker_lights/cast(list/targets, mob/user = usr) for(var/turf/T in targets) for(var/obj/machinery/light/L in T) L.forced_flicker() //Blind AOE -/obj/effect/proc_holder/spell/aoe/blindness +/datum/spell/aoe/blindness name = "Blindness" desc = "Your prey will be momentarily blind for you to advance on them." @@ -188,13 +188,13 @@ clothes_req = FALSE aoe_range = 10 -/obj/effect/proc_holder/spell/aoe/blindness/create_new_targeting() +/datum/spell/aoe/blindness/create_new_targeting() var/datum/spell_targeting/aoe/targeting = new() targeting.range = aoe_range targeting.allowed_type = /mob/living return targeting -/obj/effect/proc_holder/spell/aoe/blindness/cast(list/targets, mob/user = usr) +/datum/spell/aoe/blindness/cast(list/targets, mob/user = usr) for(var/mob/living/L in targets) if(istype(L, /mob/living/simple_animal/hostile/statue)) continue diff --git a/code/modules/mob/living/simple_animal/hostile/hellhound.dm b/code/modules/mob/living/simple_animal/hostile/hellhound.dm index c50b49221419..16078c0187c5 100644 --- a/code/modules/mob/living/simple_animal/hostile/hellhound.dm +++ b/code/modules/mob/living/simple_animal/hostile/hellhound.dm @@ -118,21 +118,21 @@ /mob/living/simple_animal/hostile/hellhound/greater/Initialize(mapload) . = ..() // Movement - AddSpell(new /obj/effect/proc_holder/spell/ethereal_jaunt/shift) - var/obj/effect/proc_holder/spell/area_teleport/teleport/telespell = new + AddSpell(new /datum/spell/ethereal_jaunt/shift) + var/datum/spell/area_teleport/teleport/telespell = new telespell.clothes_req = FALSE telespell.invocation_type = "none" AddSpell(telespell) - var/obj/effect/proc_holder/spell/aoe/knock/knockspell = new + var/datum/spell/aoe/knock/knockspell = new knockspell.invocation_type = "none" AddSpell(knockspell) // Defense - var/obj/effect/proc_holder/spell/forcewall/wallspell = new + var/datum/spell/forcewall/wallspell = new wallspell.clothes_req = FALSE wallspell.invocation_type = "none" AddSpell(wallspell) // Offense - var/obj/effect/proc_holder/spell/aoe/conjure/creature/summonspell = new + var/datum/spell/aoe/conjure/creature/summonspell = new summonspell.base_cooldown = 1 summonspell.invocation_type = "none" summonspell.summon_type = list(/mob/living/simple_animal/hostile/hellhound) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm index 0a72200d9655..69ea8e7a312d 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm @@ -619,7 +619,7 @@ Difficulty: Medium attack_action_types = list() /mob/living/simple_animal/hostile/megafauna/dragon/space_dragon/Initialize(mapload) - var/obj/effect/proc_holder/spell/aoe/repulse/spacedragon/repulse_action = new /obj/effect/proc_holder/spell/aoe/repulse/spacedragon(src) + var/datum/spell/aoe/repulse/spacedragon/repulse_action = new /datum/spell/aoe/repulse/spacedragon(src) repulse_action.action.Grant(src) mob_spell_list += repulse_action . = ..() @@ -638,7 +638,7 @@ Difficulty: Medium ranged_cooldown = world.time + ranged_cooldown_time fire_stream() -/obj/effect/proc_holder/spell/aoe/repulse/spacedragon +/datum/spell/aoe/repulse/spacedragon name = "Tail Sweep" desc = "Throw back attackers with a sweep of your tail." sound = 'sound/magic/tail_swing.ogg' @@ -651,7 +651,7 @@ Difficulty: Medium action_background_icon_state = "bg_alien" aoe_range = 1 -/obj/effect/proc_holder/spell/aoe/repulse/spacedragon/cast(list/targets, mob/user = usr) +/datum/spell/aoe/repulse/spacedragon/cast(list/targets, mob/user = usr) if(iscarbon(user)) var/mob/living/carbon/C = user playsound(C.loc, 'sound/effects/hit_punch.ogg', 80, TRUE, TRUE) diff --git a/code/modules/mob/living/simple_animal/hostile/mining/elites/elite.dm b/code/modules/mob/living/simple_animal/hostile/mining/elites/elite.dm index 5c6f883a02e8..b3260be8952c 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining/elites/elite.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining/elites/elite.dm @@ -125,13 +125,15 @@ While using this makes the system rely on OnFire, it still gives options for tim STOP_PROCESSING(SSfastprocess, src) qdel(src) return - UpdateButton() + UpdateButtons() /datum/action/innate/elite_attack/UpdateButton(atom/movable/screen/movable/action_button/button, status_only = FALSE, force = FALSE) + . = ..() if(status_only) return var/mob/living/simple_animal/hostile/asteroid/elite/elite_owner = owner var/timeleft = max(elite_owner.ranged_cooldown - world.time, 0) + if(timeleft == 0) button.maptext = "" else diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/kangaroo.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/kangaroo.dm index 86079485cb46..79e1145eee3c 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/kangaroo.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/kangaroo.dm @@ -28,7 +28,7 @@ /mob/living/simple_animal/hostile/retaliate/kangaroo/Initialize(mapload) . = ..() // Leap spell, player-only usage - AddSpell(new /obj/effect/proc_holder/spell/leap) + AddSpell(new /datum/spell/leap) /mob/living/simple_animal/hostile/retaliate/kangaroo/AttackingTarget() if(client && a_intent != INTENT_HARM) diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/prince.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/prince.dm index 6af2eade5624..05f9e655b733 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/prince.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/prince.dm @@ -23,7 +23,7 @@ maxHealth = 600 // 30 laser shots health = 600 regen_points_per_hp = 6 // double the normal - IE halved regen speed - move_to_delay = 3 + move_to_delay = 3.5 speed = 0.5 melee_damage_lower = 30 melee_damage_upper = 40 @@ -46,18 +46,18 @@ /mob/living/simple_animal/hostile/poison/terror_spider/prince/Initialize(mapload) . = ..() if(mind) - var/obj/effect/proc_holder/spell/spell = new /obj/effect/proc_holder/spell/princely_charge() + var/datum/spell/spell = new /datum/spell/princely_charge() mind.AddSpell(spell) else RegisterSignal(src, COMSIG_MOB_LOGIN, TYPE_PROC_REF(/mob/living/simple_animal/hostile/poison/terror_spider/prince, give_spell)) /mob/living/simple_animal/hostile/poison/terror_spider/prince/proc/give_spell() SIGNAL_HANDLER - var/obj/effect/proc_holder/spell/spell = new /obj/effect/proc_holder/spell/princely_charge() + var/datum/spell/spell = new /datum/spell/princely_charge() mind.AddSpell(spell) UnregisterSignal(src, COMSIG_MOB_LOGIN) -/obj/effect/proc_holder/spell/princely_charge +/datum/spell/princely_charge name = "Princely Charge" desc = "You charge at wherever you click on screen, dealing large amounts of damage, stunning and destroying walls and other objects." gain_desc = "You can now charge at a target on screen, dealing massive damage and destroying structures." @@ -65,10 +65,10 @@ clothes_req = FALSE action_icon_state = "terror_prince" -/obj/effect/proc_holder/spell/princely_charge/create_new_targeting() +/datum/spell/princely_charge/create_new_targeting() return new /datum/spell_targeting/clicked_atom -/obj/effect/proc_holder/spell/princely_charge/cast(list/targets, mob/user) +/datum/spell/princely_charge/cast(list/targets, mob/user) var/target = targets[1] if(isliving(user)) var/mob/living/L = user diff --git a/code/modules/mob/living/simple_animal/shade.dm b/code/modules/mob/living/simple_animal/shade.dm index bd5b9b270d37..d89aed14643b 100644 --- a/code/modules/mob/living/simple_animal/shade.dm +++ b/code/modules/mob/living/simple_animal/shade.dm @@ -70,7 +70,7 @@ /mob/living/simple_animal/shade/sword/Initialize(mapload) .=..() - AddSpell(new /obj/effect/proc_holder/spell/sentient_sword_lunge) + AddSpell(new /datum/spell/sentient_sword_lunge) var/obj/item/nullrod/scythe/talking/host_sword = loc if(istype(host_sword)) health = host_sword.obj_integrity diff --git a/code/modules/mob/living/stat_states.dm b/code/modules/mob/living/stat_states.dm index e46e0aac96c8..8048e4cb75a3 100644 --- a/code/modules/mob/living/stat_states.dm +++ b/code/modules/mob/living/stat_states.dm @@ -64,7 +64,9 @@ GLOB.alive_mob_list |= src REMOVE_TRAIT(src, TRAIT_RESPAWNABLE, GHOSTED) + last_words = null timeofdeath = null + if(updating) update_blind_effects() update_sight() @@ -75,7 +77,7 @@ if(mind) for(var/S in mind.spell_list) - var/obj/effect/proc_holder/spell/spell = S + var/datum/spell/spell = S spell.UpdateButtons() return TRUE diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index b37a300e54ce..63f9134f5d72 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1158,14 +1158,14 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \ visible_message("[src] pukes all over [p_themselves()]!","You puke all over yourself!") add_vomit_floor(TRUE) -/mob/proc/AddSpell(obj/effect/proc_holder/spell/S) +/mob/proc/AddSpell(datum/spell/S) mob_spell_list += S S.action.Grant(src) -/mob/proc/RemoveSpell(obj/effect/proc_holder/spell/spell) //To remove a specific spell from a mind +/mob/proc/RemoveSpell(datum/spell/spell) //To remove a specific spell from a mind if(!spell) return - for(var/obj/effect/proc_holder/spell/S in mob_spell_list) + for(var/datum/spell/S in mob_spell_list) if(istype(S, spell)) qdel(S) mob_spell_list -= S diff --git a/code/modules/mob/mob_vars.dm b/code/modules/mob/mob_vars.dm index 2b3e4cc88e1f..d22ef54752b1 100644 --- a/code/modules/mob/mob_vars.dm +++ b/code/modules/mob/mob_vars.dm @@ -197,7 +197,7 @@ var/registered_z - var/obj/effect/proc_holder/ranged_ability //Any ranged ability the mob has, as a click override + var/datum/spell/ranged_ability //Any ranged ability the mob has, as a click override /// Overrides the health HUD element state if set. var/health_hud_override = HEALTH_HUD_OVERRIDE_NONE diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index d29f82eac76e..f5529fab46ed 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -92,13 +92,17 @@ if(O.mind && O.mind.assigned_role == "Cyborg") var/obj/item/mmi/new_mmi - switch(O.mind.role_alt_title) - if("Robot") + switch(O.client.prefs.active_character.cyborg_brain_type) + if(ROBOBRAIN_BORG) new_mmi = new /obj/item/mmi/robotic_brain(O) if(new_mmi.brainmob) new_mmi.brainmob.name = O.name - if("Cyborg") + if(MMI_BORG) new_mmi = new /obj/item/mmi(O) + if(POSITRONIC_BORG) + new_mmi = new /obj/item/mmi/robotic_brain/positronic(O) + if(new_mmi.brainmob) + new_mmi.brainmob.name = O.name else // This should never happen, but oh well new_mmi = new /obj/item/mmi(O) diff --git a/code/modules/paperwork/handlabeler.dm b/code/modules/paperwork/handlabeler.dm index 11726195d055..72fae016821b 100644 --- a/code/modules/paperwork/handlabeler.dm +++ b/code/modules/paperwork/handlabeler.dm @@ -1,3 +1,7 @@ +#define LABEL_MODE_OFF 0 +#define LABEL_MODE_NORMAL 1 +#define LABEL_MODE_GOAL 2 + /obj/item/hand_labeler name = "hand labeler" desc = "A combined label printer, applicator, and remover, all in a single portable device. Designed to be easy to operate and use." @@ -6,12 +10,12 @@ item_state = "flight" var/label = null var/labels_left = 30 - var/mode = 0 + var/mode = LABEL_MODE_OFF /obj/item/hand_labeler/afterattack(atom/A, mob/user, proximity) if(!proximity) return - if(!mode) //if it's off, give up. + if(mode == LABEL_MODE_OFF) //if it's off, give up. return if(!labels_left) @@ -20,13 +24,23 @@ if(!label || !length(label)) to_chat(user, "No text set!") return - if(length(A.name) + length(label) > 64) - to_chat(user, "Label too big!") - return if(ismob(A)) to_chat(user, "You can't label creatures!") // use a collar return + if(mode == LABEL_MODE_GOAL) + if(istype(A, /obj/item)) + to_chat(user, "Put it in a personal crate instead!") + return + user.visible_message("[user] labels [A] as part of a secondary goal for [label].", \ + "You label [A] as part of a secondary goal for [label].") + A.AddComponent(/datum/component/label/goal, label) + return + + if(length(A.name) + length(label) > 64) + to_chat(user, "Label too big!") + return + user.visible_message("[user] labels [A] as [label].", \ "You label [A] as [label].") investigate_log("[key_name(user)] ([ADMIN_FLW(user,"FLW")]) labelled \"[A]\" ([ADMIN_VV(A, "VV")]) with \"[label]\" at [COORD(A.loc)] [ADMIN_JMP(A)].", INVESTIGATE_RENAME) // Investigate goes BEFORE rename so the original name is preserved in the log @@ -35,6 +49,8 @@ labels_left-- /obj/item/hand_labeler/attack_self(mob/user as mob) + // off -> normal + // normal or goal -> off mode = !mode icon_state = "labeler[mode]" if(mode) @@ -55,8 +71,16 @@ user.drop_item() qdel(I) labels_left = initial(labels_left) //Yes, it's capped at its initial value - else - return ..() + else if(istype(I, /obj/item/card/id)) + var/obj/item/card/id/id = I + if(istype(id, /obj/item/card/id/guest) || !id.registered_name) + to_chat(user, "Invalid ID card.") + return + label = id.registered_name + mode = LABEL_MODE_GOAL + to_chat(user, "You configure the hand labeler with [I].") + icon_state = "labeler1" + /obj/item/hand_labeler_refill name = "hand labeler paper roll" @@ -65,3 +89,7 @@ icon_state = "labeler_refill" item_state = "electropack" w_class = WEIGHT_CLASS_TINY + +#undef LABEL_MODE_OFF +#undef LABEL_MODE_NORMAL +#undef LABEL_MODE_GOAL diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm index 1c54633e47e4..6a3d492555a9 100644 --- a/code/modules/paperwork/pen.dm +++ b/code/modules/paperwork/pen.dm @@ -62,7 +62,6 @@ "blue" = list(0.5, 0.5, 1), "yellow" = list(1, 1, 0)) var/pen_colour_iconstate = "pencolor" - var/pen_colour_shift = 3 /obj/item/pen/multi/Initialize(mapload) ..() @@ -83,8 +82,6 @@ var/icon/colour_overlay = new(icon, pen_colour_iconstate) var/list/colours = colour_choices[colour] colour_overlay.SetIntensity(colours[1], colours[2], colours[3]) - if(pen_colour_shift) - colour_overlay.Shift(SOUTH, pen_colour_shift) . += colour_overlay /obj/item/pen/fancy @@ -93,16 +90,54 @@ icon_state = "fancypen" /obj/item/pen/multi/gold - name = "Gilded Pen" + name = "gilded pen" desc = "A golden pen that is gilded with a meager amount of gold material. The word 'Nanotrasen' is etched on the clip of the pen." icon_state = "goldpen" - pen_colour_shift = 0 /obj/item/pen/multi/fountain - name = "Engraved Fountain Pen" - desc = "An expensive looking pen." + name = "engraved fountain pen" + desc = "An expensive-looking pen typically issued to Nanotrasen employees." icon_state = "fountainpen" - pen_colour_shift = 0 + +/obj/item/pen/multi/syndicate + name = "syndicate fountain pen" + desc = "A suspicious-looking pen issued to Syndicate staff." + icon_state = "pen_syndie" + +/obj/item/pen/cap + name = "captain's fountain pen" + desc = "An expensive pen only issued to station captains." + icon_state = "pen_cap" + +/obj/item/pen/hop + name = "head of personnel's fountain pen" + desc = "An expensive-looking pen only issued to heads of service." + icon_state = "pen_hop" + +/obj/item/pen/hos + name = "head of security's fountain pen" + desc = "An expensive-looking pen only issued to heads of security." + icon_state = "pen_hos" + +/obj/item/pen/cmo + name = "chief medical officer's fountain pen" + desc = "An expensive-looking pen only issued to heads of medical." + icon_state = "pen_cmo" + +/obj/item/pen/ce + name = "chief engineer's fountain pen" + desc = "An expensive-looking pen only issued to heads of engineering." + icon_state = "pen_ce" + +/obj/item/pen/rd + name = "research director's fountain pen" + desc = "An expensive-looking pen only issued to heads of research." + icon_state = "pen_rd" + +/obj/item/pen/qm + name = "quartermaster's fountain pen" + desc = "An expensive-looking pen only issued to heads of cargo." + icon_state = "pen_qm" /* * Sleepypens diff --git a/code/modules/pda/PDA.dm b/code/modules/pda/PDA.dm index 294cfabd43e6..231dafbef73b 100644 --- a/code/modules/pda/PDA.dm +++ b/code/modules/pda/PDA.dm @@ -76,7 +76,8 @@ GLOBAL_LIST_EMPTY(PDAs) // The slot where you can store a pen var/obj/item/held_pen var/retro_mode = 0 - + /// What pen is loaded in the PDA + var/obj/item/pen/default_pen = /obj/item/pen /* * The Actual PDA @@ -90,7 +91,7 @@ GLOBAL_LIST_EMPTY(PDAs) if(default_cartridge) cartridge = new default_cartridge(src) cartridge.update_programs(src) - add_pen(new /obj/item/pen(src)) + add_pen(new default_pen(src)) start_program(find_program(/datum/data/pda/app/main_menu)) silent = initial(silent) diff --git a/code/modules/pda/pdas.dm b/code/modules/pda/pdas.dm index 8d568b0f1454..9d290e709cbe 100644 --- a/code/modules/pda/pdas.dm +++ b/code/modules/pda/pdas.dm @@ -17,10 +17,12 @@ /obj/item/pda/detective default_cartridge = /obj/item/cartridge/detective icon_state = "pda-security" + default_pen = /obj/item/pen/multi /obj/item/pda/warden default_cartridge = /obj/item/cartridge/security icon_state = "pda-warden" + default_pen = /obj/item/pen/multi /obj/item/pda/janitor default_cartridge = /obj/item/cartridge/janitor @@ -55,44 +57,54 @@ /obj/item/pda/heads/hop default_cartridge = /obj/item/cartridge/hop icon_state = "pda-hop" + default_pen = /obj/item/pen/hop /obj/item/pda/heads/hos default_cartridge = /obj/item/cartridge/hos icon_state = "pda-hos" + default_pen = /obj/item/pen/hos /obj/item/pda/heads/ce default_cartridge = /obj/item/cartridge/ce icon_state = "pda-ce" + default_pen = /obj/item/pen/ce /obj/item/pda/heads/cmo default_cartridge = /obj/item/cartridge/cmo icon_state = "pda-cmo" + default_pen = /obj/item/pen/cmo /obj/item/pda/heads/rd default_cartridge = /obj/item/cartridge/rd icon_state = "pda-rd" + default_pen = /obj/item/pen/rd /obj/item/pda/captain default_cartridge = /obj/item/cartridge/captain icon_state = "pda-captain" detonate = FALSE + default_pen = /obj/item/pen/cap //toff = 1 /obj/item/pda/heads/ntrep default_cartridge = /obj/item/cartridge/supervisor icon_state = "pda-h" + default_pen = /obj/item/pen/multi/fountain /obj/item/pda/heads/magistrate default_cartridge = /obj/item/cartridge/supervisor icon_state = "pda-h" + default_pen = /obj/item/pen/multi/gold /obj/item/pda/heads/blueshield default_cartridge = /obj/item/cartridge/hos icon_state = "pda-h" + default_pen = /obj/item/pen/fancy /obj/item/pda/heads/ert default_cartridge = /obj/item/cartridge/centcom detonate = FALSE + default_pen = /obj/item/pen/multi/fountain /obj/item/pda/heads/ert/engineering icon_state = "pda-engineer" @@ -116,6 +128,7 @@ /obj/item/pda/quartermaster default_cartridge = /obj/item/cartridge/qm icon_state = "pda-qm" + default_pen = /obj/item/pen/qm /obj/item/pda/shaftminer icon_state = "pda-miner" @@ -125,6 +138,7 @@ icon_state = "pda-syndi" name = "Military PDA" owner = "John Doe" + default_pen = /obj/item/pen/multi/syndicate /obj/item/pda/syndicate/New() ..() @@ -140,6 +154,7 @@ default_cartridge = /obj/item/cartridge/lawyer icon_state = "pda-lawyer" ttone = "..." + default_pen = /obj/item/pen/multi /obj/item/pda/botanist //default_cartridge = /obj/item/cartridge/botanist @@ -153,6 +168,7 @@ desc = "A portable microcomputer by Thinktronic Systems, LTD. This is model is a WGW-11 series e-reader." model_name = "Thinktronic 5290 WGW-11 Series E-reader and Personal Data Assistant" silent = TRUE + default_pen = /obj/item/pen/multi /obj/item/pda/clear icon_state = "pda-transp" @@ -180,6 +196,7 @@ /obj/item/pda/centcom default_cartridge = /obj/item/cartridge/centcom icon_state = "pda-h" + default_pen = /obj/item/pen/multi/gold /obj/item/pda/centcom/New() ..() diff --git a/code/modules/power/apc/apc_malfunction.dm b/code/modules/power/apc/apc_malfunction.dm index b0d892b51fe6..fbf859daa708 100644 --- a/code/modules/power/apc/apc_malfunction.dm +++ b/code/modules/power/apc/apc_malfunction.dm @@ -46,8 +46,8 @@ occupier.eyeobj.name = "[occupier.name] (AI Eye)" if(malf.parent) qdel(malf) - var/datum/action/innate/ai/return_to_core/R = new - R.Grant(occupier) + var/datum/spell/ai_spell/return_to_core/R = new + occupier.AddSpell(R) occupier.cancel_camera() if((SSsecurity_level.get_current_level_as_number() == SEC_LEVEL_DELTA) && malf.nuking) for(var/obj/item/pinpointer/point in GLOB.pinpointer_list) diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm index 04f4aafbd50b..25e1e1164d07 100644 --- a/code/modules/projectiles/guns/projectile/revolver.dm +++ b/code/modules/projectiles/guns/projectile/revolver.dm @@ -130,7 +130,7 @@ trigger_guard = TRIGGER_GUARD_ALLOW_ALL clumsy_check = FALSE //Stole your uplink! Honk! needs_permit = FALSE //go away beepsky - var/obj/effect/proc_holder/spell/mime/fingergun/parent_spell + var/datum/spell/mime/fingergun/parent_spell /obj/item/gun/projectile/revolver/fingergun/Destroy() if(parent_spell) diff --git a/code/modules/reagents/chemistry/reagents/alcohol.dm b/code/modules/reagents/chemistry/reagents/alcohol.dm index 9ef0f6fac0a1..e72a81a8a684 100644 --- a/code/modules/reagents/chemistry/reagents/alcohol.dm +++ b/code/modules/reagents/chemistry/reagents/alcohol.dm @@ -9,6 +9,7 @@ var/dizzy_adj = 6 SECONDS var/alcohol_perc = 1 //percentage of ethanol in a beverage 0.0 - 1.0 taste_description = "liquid fire" + goal_department = "Bar" /datum/reagent/consumable/ethanol/on_mob_life(mob/living/M) M.AdjustDrunk(alcohol_perc STATUS_EFFECT_CONSTANT) @@ -125,6 +126,7 @@ drink_name = "Hooch" drink_desc = "You've really hit rock bottom now... your liver packed its bags and left last night." taste_description = "pure resignation" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/consumable/ethanol/hooch/on_mob_life(mob/living/carbon/M) if(M.mind && M.mind.assigned_role == "Assistant") @@ -161,6 +163,7 @@ drink_name = "Glass of Mojito" drink_desc = "Fresh from Spesscuba." taste_description = "mojito" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/vodka name = "Vodka" @@ -242,6 +245,7 @@ drink_name = "Suicider" drink_desc = "You've really hit rock bottom now... your liver packed its bags and left last night." taste_description = "approaching death" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/consumable/ethanol/ale name = "Ale" @@ -291,6 +295,7 @@ drink_name = "Glass of bilk" drink_desc = "A brew of milk and beer. For those alcoholics who fear osteoporosis." taste_description = "bilk" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/atomicbomb name = "Atomic Bomb" @@ -303,6 +308,7 @@ drink_name = "Atomic Bomb" drink_desc = "Nanotrasen cannot take legal responsibility for your actions after imbibing." taste_description = "a long, fiery burn" + goal_difficulty = REAGENT_GOAL_HARD /datum/reagent/consumable/ethanol/threemileisland name = "Three Mile Island Iced Tea" @@ -315,6 +321,7 @@ drink_name = "Three Mile Island Ice Tea" drink_desc = "A glass of this is sure to prevent a meltdown." taste_description = "a creeping heat" + goal_difficulty = REAGENT_GOAL_HARD /datum/reagent/consumable/ethanol/goldschlager name = "Goldschlager" @@ -351,6 +358,7 @@ drink_name = "Gin and Tonic" drink_desc = "A mild but still great cocktail. Drink up, like a true Englishman." taste_description = "bitter medicine" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/cuba_libre name = "Cuba Libre" @@ -363,6 +371,7 @@ drink_name = "Cuba Libre" drink_desc = "A classic mix of rum and cola." taste_description = "liberation" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/whiskey_cola name = "Whiskey Cola" @@ -375,6 +384,7 @@ drink_name = "Whiskey Cola" drink_desc = "An innocent-looking mixture of cola and Whiskey. Delicious." taste_description = "whiskey and coke" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/daiquiri name = "Daiquiri" @@ -387,6 +397,7 @@ drink_name = "Daiquiri" drink_desc = "When Botany gives you limes, make daiquiris." taste_description = "sweetened lime juice and rum" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/martini name = "Classic Martini" @@ -399,6 +410,7 @@ drink_name = "Classic Martini" drink_desc = "Damn, the bartender even stirred it, not shook it." taste_description = "class" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/vodkamartini name = "Vodka Martini" @@ -411,6 +423,7 @@ drink_name = "Vodka martini" drink_desc ="A bastardisation of the classic martini. Still great." taste_description = "class and potatoes" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/white_russian name = "White Russian" @@ -423,6 +436,7 @@ drink_name = "White Russian" drink_desc = "A very nice looking drink. But that's just, like, your opinion, man." taste_description = "very creamy alcohol" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/screwdrivercocktail name = "Screwdriver" @@ -435,6 +449,7 @@ drink_name = "Screwdriver" drink_desc = "A simple, yet superb mixture of Vodka and orange juice. Just the thing for the tired engineer." taste_description = "a naughty secret" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/booger name = "Booger" @@ -447,6 +462,7 @@ drink_name = "Booger" drink_desc = "Eww..." taste_description = "a fruity mess" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/bloody_mary name = "Bloody Mary" @@ -459,6 +475,7 @@ drink_name = "Bloody Mary" drink_desc = "Tomato juice, mixed with Vodka and a lil' bit of lime. Tastes like liquid murder." taste_description = "tomatoes with booze" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/gargle_blaster name = "Pan-Galactic Gargle Blaster" @@ -471,6 +488,7 @@ drink_name = "Pan-Galactic Gargle Blaster" drink_desc = "Does... does this mean that Arthur and Ford are on the station? Oh joy." taste_description = "the number fourty two" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/flaming_homer name = "Flaming Moe" @@ -483,6 +501,7 @@ drink_name = "Flaming Moe" drink_desc = "Happiness is just a Flaming Moe away!" taste_description = "caramelised booze and sweet, salty medicine" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/consumable/ethanol/brave_bull name = "Brave Bull" @@ -507,6 +526,7 @@ drink_name = "Tequila Sunrise" drink_desc = "Oh great, now you feel nostalgic about sunrises back on Terra..." taste_description = "fruity alcohol" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/toxins_special name = "Toxins Special" @@ -519,6 +539,7 @@ drink_name = "Toxins Special" drink_desc = "Whoah, this thing is on FIRE" taste_description = "FIRE" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/consumable/ethanol/toxins_special/on_mob_life(mob/living/M) if(M.bodytemperature < 330) @@ -536,6 +557,7 @@ drink_name = "Beepsky Smash" drink_desc = "Heavy, hot and strong. Just like the Iron fist of the LAW." taste_description = "THE LAW" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/consumable/ethanol/irish_cream name = "Irish Cream" @@ -560,6 +582,7 @@ drink_name = "The Manly Dorf" drink_desc = "A manly concotion made from Ale and Beer. Intended for true men only." taste_description = "manliness" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/longislandicedtea name = "Long Island Iced Tea" @@ -572,6 +595,7 @@ drink_name = "Long Island Iced Tea" drink_desc = "The liquor cabinet, brought together in a delicious mix. Intended for middle-aged alcoholic women only." taste_description = "fruity alcohol" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/moonshine name = "Moonshine" @@ -584,6 +608,7 @@ drink_name = "Moonshine" drink_desc = "You've really hit rock bottom now... your liver packed its bags and left last night." taste_description = "prohibition" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/consumable/ethanol/b52 name = "B-52" @@ -596,6 +621,7 @@ drink_name = "B-52" drink_desc = "Kahlua, Irish Cream, and congac. You will get bombed." taste_description = "destruction" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/irishcoffee name = "Irish Coffee" @@ -608,6 +634,7 @@ drink_name = "Irish Coffee" drink_desc = "Coffee and alcohol. More fun than a Mimosa to drink in the morning." taste_description = "coffee and booze" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/margarita name = "Margarita" @@ -620,6 +647,7 @@ drink_name = "Margarita" drink_desc = "On the rocks with salt on the rim. Arriba~!" taste_description = "daisies" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/black_russian name = "Black Russian" @@ -632,6 +660,7 @@ drink_name = "Black Russian" drink_desc = "For the lactose-intolerant. Still as classy as a White Russian." taste_description = "sweet alcohol" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/manhattan name = "Manhattan" @@ -656,6 +685,7 @@ drink_name = "Manhattan Project" drink_desc = "A scientist's drink of choice, for thinking how to blow up the station." taste_description = "the apocalypse" + goal_difficulty = REAGENT_GOAL_HARD /datum/reagent/consumable/ethanol/whiskeysoda name = "Whiskey Soda" @@ -668,6 +698,7 @@ drink_name = "Whiskey Soda" drink_desc = "Ultimate refreshment." taste_description = "mediocrity" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/antifreeze name = "Anti-freeze" @@ -680,6 +711,7 @@ drink_name = "Anti-freeze" drink_desc = "The ultimate refreshment." taste_description = "poor life choices" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/antifreeze/on_mob_life(mob/living/M) if(M.bodytemperature < 330) @@ -698,6 +730,7 @@ drink_name = "Admin Freeze" drink_desc = "The ultimate punishment." taste_description = "a series of bad decisions" + goal_difficulty = REAGENT_GOAL_HARD /datum/reagent/consumable/ethanol/adminfreeze/reaction_mob(mob/living/M, method = REAGENT_INGEST, volume) ..() @@ -716,6 +749,7 @@ drink_name = "Barefoot" drink_desc = "Barefoot and pregnant" taste_description = "pregnancy" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/snowwhite name = "Snow White" @@ -728,6 +762,7 @@ drink_name = "Snow White" drink_desc = "A cold refreshment." taste_description = "a poisoned apple" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/demonsblood name = "Demons Blood" @@ -741,6 +776,7 @@ drink_name = "Demons Blood" drink_desc = "Just looking at this thing makes the hair at the back of your neck stand up." taste_description = "evil" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/vodkatonic name = "Vodka and Tonic" @@ -754,6 +790,7 @@ drink_name = "Vodka and Tonic" drink_desc = "For when a gin and tonic isn't russian enough." taste_description = "bitter medicine" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/ginfizz name = "Gin Fizz" @@ -767,6 +804,7 @@ drink_name = "Gin Fizz" drink_desc = "Refreshingly lemony, deliciously dry." taste_description = "fizzy alcohol" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/bahama_mama name = "Bahama mama" @@ -779,6 +817,7 @@ drink_name = "Bahama Mama" drink_desc = "Tropic cocktail" taste_description = "HONK" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/singulo name = "Singulo" @@ -792,6 +831,7 @@ drink_name = "Singulo" drink_desc = "A bluespace beverage." taste_description = "infinity" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/consumable/ethanol/sbiten name = "Sbiten" @@ -804,6 +844,7 @@ drink_name = "Sbiten" drink_desc = "A spicy mix of Vodka and Spice. Very hot." taste_description = "comforting warmth" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/consumable/ethanol/sbiten/on_mob_life(mob/living/M) if(M.bodytemperature < 360) @@ -821,6 +862,7 @@ drink_name = "Devils Kiss" drink_desc = "Creepy time!" taste_description = "naughtiness" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/red_mead name = "Red Mead" @@ -833,6 +875,7 @@ drink_name = "Red Mead" drink_desc = "A True Vikings Beverage, though its color is strange." taste_description = "blood" + goal_difficulty = REAGENT_GOAL_HARD /datum/reagent/consumable/ethanol/mead name = "Mead" @@ -875,6 +918,7 @@ drink_name = "Grog" drink_desc = "A fine and cepa drink for Space." taste_description = "strongly diluted rum" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/aloe name = "Aloe" @@ -887,6 +931,7 @@ drink_name = "Aloe" drink_desc = "Very, very, very good." taste_description = "healthy skin" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/andalusia name = "Andalusia" @@ -899,6 +944,7 @@ drink_name = "Andalusia" drink_desc = "A nice, strange named drink." taste_description = "sweet alcohol" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/alliescocktail name = "Allies Cocktail" @@ -911,6 +957,7 @@ drink_name = "Allies cocktail" drink_desc = "A drink made from your allies." taste_description = "victory" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/acid_spit name = "Acid Spit" @@ -923,6 +970,7 @@ drink_name = "Acid Spit" drink_desc = "A drink from Nanotrasen. Made from live aliens." taste_description = "PAIN" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/consumable/ethanol/amasec name = "Amasec" @@ -935,6 +983,7 @@ drink_name = "Amasec" drink_desc = "Always handy before COMBAT!!!" taste_description = "a stunbaton" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/consumable/ethanol/neurotoxin name = "Neuro-toxin" @@ -949,6 +998,7 @@ drink_name = "Neurotoxin" drink_desc = "A drink that is guaranteed to knock you silly." taste_description = "brain damageeeEEeee" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/consumable/ethanol/neurotoxin/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -971,6 +1021,7 @@ drink_name = "Hippie's Delight" drink_desc = "A drink enjoyed by people during the 1960's." taste_description = "colors" + goal_difficulty = REAGENT_GOAL_HARD /datum/reagent/consumable/ethanol/hippies_delight/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -1009,6 +1060,7 @@ drink_name = "Changeling Sting" drink_desc = "A stingy drink." taste_description = "a tiny prick" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/dublindrop name = "Dublin Drop" @@ -1022,6 +1074,7 @@ drink_name = "Dublin Drop" drink_desc = "A Dublin drop. Pub legends say one of the ingredients can bring back the dead." taste_description = "a belt in the gob" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/syndicatebomb name = "Syndicate Bomb" @@ -1034,6 +1087,7 @@ drink_name = "Syndicate Bomb" drink_desc = "A syndicate bomb." taste_description = "a job offer" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/erikasurprise name = "Erika Surprise" @@ -1046,6 +1100,7 @@ drink_name = "Erika Surprise" drink_desc = "The surprise is, it's green!" taste_description = "disappointment" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/driestmartini name = "Driest Martini" @@ -1059,6 +1114,7 @@ drink_name = "Driest Martini" drink_desc = "Only for the experienced. You think you see sand floating in the glass." taste_description = "dust and ashes" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/driestmartini/on_mob_life(mob/living/M) if(current_cycle >= 55 && current_cycle < 115) @@ -1093,6 +1149,7 @@ drink_name = "Gin and Sonic" drink_desc = "An extremely high amperage drink. Absolutely not for the true Englishman." taste_description = "SPEED" + goal_difficulty = REAGENT_GOAL_HARD /datum/reagent/ginsonic/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -1121,6 +1178,7 @@ drink_name = "Glass of applejack" drink_desc = "When cider isn't strong enough, you gotta jack it." taste_description = "strong cider" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/consumable/ethanol/jackrose name = "Jack Rose" @@ -1132,6 +1190,7 @@ drink_name = "Jack Rose" drink_desc = "Drinking this makes you feel like you belong in a luxury hotel bar during the 1920s." taste_description = "style" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/consumable/ethanol/drunkenblumpkin name = "Drunken Blumpkin" @@ -1143,6 +1202,7 @@ drink_name = "Drunken Blumpkin" drink_desc = "A drink for the drunks" taste_description = "weirdness" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/consumable/ethanol/eggnog name = "Eggnog" @@ -1155,6 +1215,7 @@ drink_name = "Eggnog" drink_desc = "For enjoying the most wonderful time of the year." taste_description = "christmas spirit" + goal_difficulty = REAGENT_GOAL_HARD /// inaccessible to players, but here for admin shennanigans /datum/reagent/consumable/ethanol/dragons_breath @@ -1256,6 +1317,7 @@ drink_name = "Glass of Trinary" drink_desc = "Colorful drink made for synthetic crewmembers. It doesn't seem like it would taste well." taste_description = "modem static" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/synthanol/servo name = "Servo" @@ -1268,6 +1330,7 @@ drink_name = "Glass of Servo" drink_desc = "Chocolate - based drink made for IPCs. Not sure if anyone's actually tried out the recipe." taste_description = "motor oil and cocoa" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/synthanol/uplink name = "Uplink" @@ -1280,6 +1343,7 @@ drink_name = "Glass of Uplink" drink_desc = "An exquisite mix of the finest liquoirs and synthanol. Meant only for synthetics." taste_description = "a GUI in visual basic" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/synthanol/synthnsoda name = "Synth 'n Soda" @@ -1292,6 +1356,7 @@ drink_name = "Glass of Synth 'n Soda" drink_desc = "Classic drink altered to fit the tastes of a robot. Bad idea to drink if you're made of carbon." taste_description = "fizzy motor oil" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/synthanol/synthignon name = "Synthignon" @@ -1464,6 +1529,7 @@ drink_desc = "A sawed-off cola bottle filled with Fernet Cola. You can hear cuarteto music coming from the inside." taste_description = "low class heaven" remove_nutrition = 1 + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/gimlet name = "Gimlet" @@ -1475,6 +1541,7 @@ drink_name = "Gimlet" drink_desc = "There are debates on whether this drink should be half gin and half lime, or three parts gin and one part lime. All you know is, it's alcohol." taste_description = "sharpness" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/sidecar name = "Sidecar" @@ -1486,6 +1553,7 @@ drink_name = "Sidecar" drink_desc = "You can smell the citrus from here!" taste_description = "smooth cognac and tart citrus" + goal_difficulty = REAGENT_GOAL_HARD /datum/reagent/consumable/ethanol/whiskey_sour name = "Whiskey Sour" @@ -1497,6 +1565,7 @@ drink_name = "Whiskey Sour" drink_desc = "Lemon and whiskey, with a cute foamy head!" taste_description = "warm whiskey and sweetness" + goal_difficulty = REAGENT_GOAL_HARD /datum/reagent/consumable/ethanol/mint_julep name = "Mint Julep" @@ -1508,6 +1577,7 @@ drink_name = "Mint Julep" drink_desc = "A dainty glass of whiskey and mint on the rocks. Perfect for summer!" taste_description = "sweet and cooling mint" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/pina_colada name = "Pina Colada" @@ -1519,6 +1589,7 @@ drink_name = "Pina Colada" drink_desc = "After taking a sip, you feel contractually obligated to start singing a certain song of the same name." taste_description = "tart and tropical pineapple" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/bilkshake name = "Bilkshake" @@ -1531,6 +1602,7 @@ drink_name = "Bilkshake" drink_desc = "Your mind bubbles and oozes as it tries to comprehend what it's seeing. What the HELL is this?" taste_description = "bilk, cream, and cold tears" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/sontse name = "Sontse" @@ -1543,6 +1615,7 @@ drink_desc = "The Sun, The Sun, The Sun, The Sun, The Sun, THE SUN!" taste_description = "warmth and brightness" var/light_activated = FALSE + goal_difficulty = REAGENT_GOAL_HARD /datum/reagent/consumable/ethanol/sontse/on_mob_life(mob/living/M) if(current_cycle != 5 || !ismoth(M)) @@ -1571,6 +1644,7 @@ drink_desc = "Blizzard in a glass. Tajaran signature drink!" taste_description = "ice" var/min_achievable_temp = 250 + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/consumable/ethanol/ahdomai_eclipse/on_mob_life(mob/living/M) . = ..() @@ -1587,6 +1661,7 @@ drink_name = "Feast by the Beach" drink_desc = "A classic Unathi drink. You can spot sand sediment at the bottom of the glass. The drink is hot as hell and more." taste_description = "sand" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/consumable/ethanol/beach_feast/on_mob_life(mob/living/M) if(!isunathi(M)) @@ -1605,6 +1680,7 @@ drink_name = "Jungle Vox" drink_desc = "Classy drink in a glass vox head with a bit of liquid nitrogen added on." taste_description = "bubbles" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/consumable/ethanol/jungle_vox/on_mob_life(mob/living/M) if(current_cycle <= 5 || !isvox(M)) @@ -1624,6 +1700,7 @@ drink_name = "Slime Mold" drink_desc = "You can swear that this jelly looks alive." taste_description = "jelly" + goal_difficulty = REAGENT_GOAL_HARD /datum/reagent/consumable/ethanol/slime_mold/on_mob_life(mob/living/M) if(!isslimeperson(M)) @@ -1644,6 +1721,7 @@ drink_name = "Die Seife" drink_desc = "There is a piece of soap at the bottom of the glass and it is slowly melting." taste_description = "soap" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/consumable/ethanol/die_seife/on_mob_life(mob/living/M) if(current_cycle % 10 != 0 || !isdrask(M)) @@ -1664,6 +1742,7 @@ drink_name = "Acid Dreams" drink_desc = "This one looks just weird and reeks of acid." taste_description = "acid" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/consumable/ethanol/acid_dreams/on_mob_life(mob/living/M) if(current_cycle % 10 != 0 || !isgrey(M)) @@ -1689,6 +1768,7 @@ drink_name = "Islay Whiskey" drink_desc = "Named in honor of one of the most gritty and earth smelling types of Whiskey of Earth, this drink is a treat for any Diona." taste_description = "soil" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/consumable/ethanol/islay_whiskey/on_mob_life(mob/living/M) if(current_cycle <=5 || !isdiona(M)) @@ -1715,6 +1795,7 @@ drink_desc = "In the triangle of fire, this is apex of fuel." taste_description = "fire" var/on_fire = FALSE + goal_difficulty = REAGENT_GOAL_HARD /datum/reagent/consumable/ethanol/ultramatter/on_mob_life(mob/living/M) // species agnostic as it is DRINKS on_fire, so only plasmaman can get it @@ -1747,6 +1828,7 @@ drink_name = "Howler" drink_desc = "Old classic human drink that was adopted by Vulpkanin." taste_description = "citrus" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/consumable/ethanol/howler/on_mob_life(mob/living/M) if(!isvulpkanin(M)) @@ -1769,6 +1851,7 @@ drink_desc = "Fake Diona is floating carelessly in the middle of this drink." taste_description = "the crunch" var/mutated = FALSE + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/consumable/ethanol/diona_smash/on_mob_life(mob/living/M) if(mutated || !iskidan(M)) diff --git a/code/modules/reagents/chemistry/reagents/drugs.dm b/code/modules/reagents/chemistry/reagents/drugs.dm index 9854ebec5c26..f2a1442f275a 100644 --- a/code/modules/reagents/chemistry/reagents/drugs.dm +++ b/code/modules/reagents/chemistry/reagents/drugs.dm @@ -28,6 +28,8 @@ reagent_state = LIQUID color = "#0000D8" taste_description = "a magical journey" + goal_department = "Science" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/lsd/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -46,6 +48,8 @@ addiction_threshold = 10 heart_rate_decrease = 1 taste_description = "a synthetic high" + goal_department = "Science" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/space_drugs/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -171,6 +175,8 @@ addiction_threshold = 5 addiction_decay_rate = 0.2 // half the metabolism rate taste_description = "bitterness" + goal_department = "Science" + goal_difficulty = REAGENT_GOAL_HARD /datum/reagent/crank/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -249,6 +255,8 @@ overdose_threshold = 20 addiction_chance = 10 addiction_threshold = 5 + goal_department = "Science" + goal_difficulty = REAGENT_GOAL_HARD /datum/reagent/pump_up/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -290,6 +298,8 @@ addiction_threshold = 10 taste_description = "very poor life choices" allowed_overdose_process = TRUE + goal_department = "Science" + goal_difficulty = REAGENT_GOAL_HARD /datum/reagent/krokodil/on_mob_life(mob/living/M) @@ -370,6 +380,8 @@ allowed_overdose_process = TRUE //Requested by balance. /// modifier to the stun time of the mob taking the drug var/tenacity = 1.5 + goal_department = "Science" + goal_difficulty = REAGENT_GOAL_HARD /datum/reagent/methamphetamine/on_mob_add(mob/living/L) ADD_TRAIT(L, TRAIT_GOTTAGOFAST, id) @@ -440,6 +452,8 @@ addiction_decay_rate = 0.2 taste_description = "WAAAAGH" var/bonus_damage = 2 + goal_department = "Science" + goal_difficulty = REAGENT_GOAL_HARD /datum/reagent/bath_salts/on_mob_add(mob/living/L) if(ishuman(L)) @@ -541,6 +555,8 @@ addiction_chance = 5 addiction_threshold = 5 taste_description = "the inside of a toilet... or worse" + goal_department = "Science" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/jenkem/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -563,6 +579,8 @@ addiction_decay_rate = 0.2 /// how much do we edit the stun and stamina mods? lower is more resistance var/tenacity = 0.5 + goal_department = "Science" + goal_difficulty = REAGENT_GOAL_HARD /datum/reagent/aranesp/on_mob_add(mob/living/L) if(ishuman(L)) @@ -610,6 +628,8 @@ addiction_chance_additional = 20 addiction_threshold = 20 minor_addiction = TRUE + goal_department = "Science" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/happiness/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -718,6 +738,8 @@ addiction_chance_additional = 20 addiction_threshold = 10 taste_description = "flips" + goal_department = "Science" + goal_difficulty = REAGENT_GOAL_HARD /datum/reagent/fliptonium/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -784,6 +806,8 @@ color = "#AC88CA" //RGB: 172, 136, 202 metabolization_rate = 0.6 * REAGENTS_METABOLISM taste_description = "spinning" + goal_department = "Science" + goal_difficulty = REAGENT_GOAL_HARD /datum/reagent/rotatium/on_mob_life(mob/living/carbon/M) if(M.hud_used) @@ -834,6 +858,8 @@ var/constant_dose_time = 0 /// Keeps track of how many chemicals we are delaying the changeling by. var/changeling_chemical_tracker = 0 + goal_department = "Science" + goal_difficulty = REAGENT_GOAL_HARD /datum/reagent/mephedrone/on_mob_add(mob/living/carbon/L) @@ -1121,6 +1147,8 @@ addiction_decay_rate = 0.1 //very low to force them to take time off of meth taste_description = "wiper fluid" var/tenacity = 1.5 // higher is worse + goal_department = "Science" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/lube/ultra/on_mob_add(mob/living/L) ADD_TRAIT(L, TRAIT_GOTTAGOFAST, id) @@ -1184,6 +1212,8 @@ addiction_threshold = 5 addiction_decay_rate = 0.2 taste_description = "silicon" + goal_department = "Science" + goal_difficulty = REAGENT_GOAL_HARD /datum/reagent/surge/on_mob_life(mob/living/M) diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm index 1db066db7dc0..28e66a573fd2 100644 --- a/code/modules/reagents/chemistry/reagents/food_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm @@ -133,6 +133,8 @@ nutriment_factor = 2 * REAGENTS_METABOLISM color = "#792300" // rgb: 121, 35, 0 taste_description = "soy" + goal_department = "Kitchen" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/consumable/ketchup name = "Ketchup" @@ -150,6 +152,8 @@ reagent_state = LIQUID color = "#DFDFDF" // rgb: 223, 223, 223 taste_description = "mayonnaise" + goal_department = "Kitchen" + goal_difficulty = REAGENT_GOAL_HARD /datum/reagent/consumable/peanutbutter name = "Peanut Butter" @@ -169,6 +173,8 @@ color = "#78280A" // rbg: 120, 40, 10 taste_mult = 2.5 taste_description = "smokey sweetness" + goal_department = "Kitchen" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/consumable/capsaicin name = "Capsaicin Oil" @@ -372,6 +378,8 @@ nutriment_factor = 10 * REAGENTS_METABOLISM color = "#DBCF5C" //rgb: 219, 207, 92 taste_description = "olive oil" + goal_department = "Kitchen" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/consumable/cornoil/reaction_turf(turf/simulated/T, volume) if(!istype(T)) @@ -393,6 +401,8 @@ reagent_state = LIQUID color = "#282314" // rgb: 54, 94, 48 taste_description = "sweetness" + goal_department = "Kitchen" + goal_difficulty = REAGENT_GOAL_HARD /datum/reagent/consumable/dry_ramen name = "Dry Ramen" @@ -778,6 +788,8 @@ reagent_state = LIQUID color = "#B4641B" taste_description = "gravy" + goal_department = "Kitchen" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/consumable/wasabi name = "Wasabi" @@ -1014,3 +1026,5 @@ description = "Useful for pickling, or putting on chips." taste_description = "vinegar" color = "#ffffff" + goal_department = "Kitchen" + goal_difficulty = REAGENT_GOAL_NORMAL diff --git a/code/modules/reagents/chemistry/reagents/medicine.dm b/code/modules/reagents/chemistry/reagents/medicine.dm index 9ba2163d191a..5e779a760704 100644 --- a/code/modules/reagents/chemistry/reagents/medicine.dm +++ b/code/modules/reagents/chemistry/reagents/medicine.dm @@ -3,6 +3,7 @@ id = "medicine" taste_description = "bitterness" harmless = TRUE + goal_department = "Medbay" /datum/reagent/medicine/on_mob_life(mob/living/M) current_cycle++ @@ -22,6 +23,7 @@ metabolization_rate = 0.3 // Lasts 1.5 minutes for 15 units shock_reduction = 200 taste_description = "numbness" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/medicine/hydrocodone/on_mob_life(mob/living/M) //Needed so the hud updates when injested / removed from system var/update_flags = STATUS_UPDATE_HEALTH @@ -34,6 +36,7 @@ reagent_state = LIQUID color = "#C8A5DC" // rgb: 200, 165, 220 taste_description = "antiseptic" + goal_difficulty = REAGENT_GOAL_EASY //makes you squeaky clean /datum/reagent/medicine/sterilizine/reaction_mob(mob/living/M, method=REAGENT_TOUCH, volume) @@ -97,6 +100,7 @@ reagent_state = LIQUID color = "#C8A5DC" // rgb: 200, 165, 220 taste_description = "nurturing" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/medicine/mitocholide/on_mob_life(mob/living/M) if(ishuman(M)) @@ -124,6 +128,7 @@ color = "#0000C8" // rgb: 200, 165, 220 heart_rate_decrease = 1 taste_description = "a safe refuge" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/medicine/cryoxadone/reaction_mob(mob/living/M, method = REAGENT_TOUCH, volume, show_message = TRUE) if(iscarbon(M)) @@ -161,6 +166,7 @@ overdose_threshold = 30 harmless = FALSE taste_description = "reformation" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/medicine/rezadone/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -190,6 +196,7 @@ color = "#0AB478" metabolization_rate = 0.2 taste_description = "antibiotics" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/medicine/spaceacillin/on_mob_life(mob/living/M) var/list/organs_list = list() @@ -223,6 +230,7 @@ penetrates_skin = TRUE metabolization_rate = 0.15 taste_description = "salt" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/medicine/salglu_solution/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -286,6 +294,7 @@ color = "#FFEBEB" penetrates_skin = TRUE taste_description = "blood" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/medicine/heal_on_apply/synthflesh/reaction_mob(mob/living/M, method = REAGENT_TOUCH, volume, show_message = 1) var/mob/living/carbon/human/H = M @@ -320,6 +329,7 @@ metabolization_rate = 3 harmless = FALSE taste_description = "wound cream" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/medicine/heal_on_apply/styptic_powder/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -353,6 +363,7 @@ metabolization_rate = 3 harmless = FALSE //toxic if ingested, and I am NOT going to account for the difference taste_description = "burn cream" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/medicine/heal_on_apply/silver_sulfadiazine/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -383,6 +394,7 @@ reagent_state = LIQUID color = "#000000" taste_description = "dust" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/medicine/charcoal/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -464,6 +476,7 @@ metabolization_rate = 0.8 harmless = FALSE taste_description = "a painful cleansing" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/medicine/calomel/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -483,6 +496,7 @@ reagent_state = LIQUID color = "#B4DCBE" taste_description = "cleansing" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/medicine/potass_iodide/on_mob_life(mob/living/M) M.radiation = max(0, M.radiation - 25) @@ -496,6 +510,7 @@ color = "#C8A5DC" harmless = FALSE taste_description = "a purge" + goal_difficulty = REAGENT_GOAL_HARD /datum/reagent/medicine/pen_acid/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -521,6 +536,7 @@ overdose_threshold = 25 harmless = FALSE taste_description = "relief" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/medicine/sal_acid/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -555,6 +571,7 @@ color = "#00FFFF" metabolization_rate = 0.2 taste_description = "safety" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/medicine/salbutamol/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -576,6 +593,7 @@ addiction_threshold = 10 harmless = FALSE taste_description = "oxygenation" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/medicine/perfluorodecalin/on_mob_life(mob/living/carbon/human/M) var/update_flags = STATUS_UPDATE_NONE @@ -601,6 +619,7 @@ overdose_threshold = 35 harmless = FALSE taste_description = "stimulation" + goal_difficulty = REAGENT_GOAL_HARD //super weak antistun chem, barely any downside /datum/reagent/medicine/ephedrine/on_mob_life(mob/living/M) @@ -656,6 +675,7 @@ overdose_threshold = 35 harmless = FALSE taste_description = "antihistamine" + goal_difficulty = REAGENT_GOAL_HARD /datum/reagent/medicine/diphenhydramine/on_mob_life(mob/living/M) M.AdjustJitter(-40 SECONDS) @@ -743,6 +763,7 @@ reagent_state = LIQUID color = "#C8A5DC" taste_description = "clarity" + goal_difficulty = REAGENT_GOAL_HARD /datum/reagent/medicine/oculine/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -775,6 +796,7 @@ overdose_threshold = 25 harmless = FALSE taste_description = "a moment of respite" + goal_difficulty = REAGENT_GOAL_HARD /datum/reagent/medicine/atropine/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -804,6 +826,7 @@ overdose_threshold = 20 harmless = FALSE taste_description = "borrowed time" + goal_difficulty = REAGENT_GOAL_HARD /datum/reagent/medicine/epinephrine/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -856,6 +879,7 @@ taste_description = "life" harmless = FALSE var/revive_type = SENTIENCE_ORGANIC //So you can't revive boss monsters or robots with it + goal_difficulty = REAGENT_GOAL_HARD /datum/reagent/medicine/lazarus_reagent/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -926,6 +950,7 @@ taste_description = "coppery fuel" harmless = FALSE overdose_threshold = 15 + goal_difficulty = REAGENT_GOAL_HARD /datum/reagent/medicine/sanguine_reagent/on_mob_life(mob/living/M) if(!ishuman(M)) @@ -981,6 +1006,7 @@ taste_description = "chunky marrow" harmless = FALSE overdose_threshold = 30 //so a single shotgun dart can't cause the tumor effect + goal_difficulty = REAGENT_GOAL_HARD /datum/reagent/medicine/osseous_reagent/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -1004,6 +1030,7 @@ description = "Mannitol is a sugar alcohol that can help alleviate cranial swelling." color = "#D1D1F1" taste_description = "sweetness" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/medicine/mannitol/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -1016,6 +1043,7 @@ description = "Mutadone is an experimental bromide that can cure genetic abnomalities." color = "#5096C8" taste_description = "cleanliness" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/medicine/mutadone/on_mob_life(mob/living/carbon/human/M) if(M.mind && M.mind.assigned_role == "Cluwne") // HUNKE @@ -1045,6 +1073,7 @@ description = "A medicine which quickly eliminates alcohol in the body." color = "#009CA8" taste_description = "sobriety" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/medicine/antihol/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -1160,6 +1189,7 @@ color = "#eee6da" overdose_threshold = 20 taste_description = "bitterness" + goal_difficulty = REAGENT_GOAL_HARD /datum/reagent/heparin/on_mob_life(mob/living/M) M.reagents.remove_reagent("cholesterol", 2) @@ -1200,6 +1230,7 @@ addiction_threshold = 10 overdose_threshold = 50 taste_description = "warmth and stability" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/medicine/teporone/on_mob_life(mob/living/M) if(M.bodytemperature > 310) @@ -1217,6 +1248,7 @@ taste_description = "stability" harmless = FALSE var/list/drug_list = list("crank", "methamphetamine", "space_drugs", "synaptizine", "psilocybin", "ephedrine", "epinephrine", "stimulants", "stimulative_agent", "bath_salts", "lsd", "thc", "mephedrone") + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/medicine/haloperidol/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -1246,6 +1278,7 @@ metabolization_rate = 0.1 harmless = FALSE taste_description = "sleepiness" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/medicine/ether/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -1326,6 +1359,7 @@ color = "#CC7A00" process_flags = SYNTHETIC taste_description = "overclocking" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/medicine/degreaser/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -1354,6 +1388,7 @@ color = "#D7B395" process_flags = SYNTHETIC taste_description = "heavy metals" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/medicine/liquid_solder/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE diff --git a/code/modules/reagents/chemistry/reagents/toxins.dm b/code/modules/reagents/chemistry/reagents/toxins.dm index 8e0d0b7f3ff8..5b2d97525360 100644 --- a/code/modules/reagents/chemistry/reagents/toxins.dm +++ b/code/modules/reagents/chemistry/reagents/toxins.dm @@ -182,6 +182,8 @@ metabolization_rate = 0.3 taste_mult = 0.9 taste_description = "slime" + goal_department = "Science" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/mutagen/reaction_mob(mob/living/M, method=REAGENT_TOUCH, volume) if(!M || !M.dna || HAS_TRAIT(M, TRAIT_BADDNA) || HAS_TRAIT(M, TRAIT_GENELESS)) @@ -279,6 +281,8 @@ process_flags = ORGANIC | SYNTHETIC taste_description = "ACID" var/acidpwr = 10 //the amount of protection removed from the armour + goal_department = "Science" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/acid/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -336,6 +340,8 @@ description = "Fluorosulfuric acid is a an extremely corrosive super-acid." color = "#5050FF" acidpwr = 42 + goal_department = "Science" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/acid/facid/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -389,6 +395,8 @@ color = "#0080ff" reagent_state = LIQUID taste_description = "vinegar" + goal_department = "Science" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/acetic_acid/reaction_mob(mob/living/carbon/human/H, method = REAGENT_TOUCH, volume) if(method != REAGENT_TOUCH) @@ -588,6 +596,8 @@ color = "#B44B00" penetrates_skin = TRUE taste_description = "bitterness" + goal_department = "Science" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/formaldehyde/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -604,6 +614,8 @@ color = "#B44B00" penetrates_skin = TRUE taste_description = "apples" + goal_department = "Science" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/acetaldehyde/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -645,6 +657,8 @@ color = "#60A584" metabolization_rate = 1 taste_mult = 0 + goal_department = "Science" + goal_difficulty = REAGENT_GOAL_EASY /datum/reagent/neurotoxin2/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -685,6 +699,8 @@ metabolization_rate = 0.1 penetrates_skin = TRUE taste_description = "almonds" + goal_department = "Science" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/cyanide/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_NONE @@ -710,6 +726,8 @@ metabolization_rate = 0.3 penetrates_skin = TRUE taste_description = "prickliness" + goal_department = "Science" + goal_difficulty = REAGENT_GOAL_NORMAL /datum/reagent/itching_powder/on_mob_life(mob/living/M) var/update_flags = STATUS_UPDATE_STAT @@ -1083,6 +1101,8 @@ reagent_state = LIQUID color = "#773E73" //RGB: 47 24 45 lethality = 2 //Atrazine, however, is definitely toxic + goal_department = "Science" + goal_difficulty = REAGENT_GOAL_EASY /// To-Do; make this more realistic. diff --git a/code/modules/reagents/chemistry/reagents_datum.dm b/code/modules/reagents/chemistry/reagents_datum.dm index 90cb9a79e576..2b4fbe56263d 100644 --- a/code/modules/reagents/chemistry/reagents_datum.dm +++ b/code/modules/reagents/chemistry/reagents_datum.dm @@ -38,6 +38,13 @@ /// how quickly the addiction threshold var decays var/addiction_decay_rate = 0.01 + // Which department's (if any) reagent goals this is eligible for. + // Must match the values used by request consoles. + var/goal_department = "Unknown" + // How difficult is this chemical for the department to make? + // Affects the quantity of the reagent that is requested by CC. + var/goal_difficulty = REAGENT_GOAL_SKIP + /datum/reagent/Destroy() . = ..() holder = null diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index 7a70db39f578..b598241f1cb2 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -15,19 +15,43 @@ var/temperature_min = 0 // To limit the temperature of a reagent container can atain when exposed to heat/cold var/temperature_max = 10000 +/obj/item/reagent_containers/proc/can_set_transfer_amount(mob/user) + if(!length(possible_transfer_amounts)) + // Nothing to configure. + return FALSE + if(isrobot(user) && src.loc == user) + // Borgs can configure their modules. + return TRUE + if(!Adjacent(user)) + // No configuring the beaker across the room. + return FALSE + if(!ishuman(user)) + // Although a funny idea, station pets changing transfer + // amounts on random conatiners would probably be frustrating + // for the crew. + return FALSE + if(HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) + // I guess there's, like, a switch or a dial or something? + // Whatever, you need to use your hands for this. + return FALSE + return TRUE + /obj/item/reagent_containers/AltClick(mob/user) - if(!Adjacent(user) || !length(possible_transfer_amounts) || !ishuman(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) + if(!can_set_transfer_amount(user)) return var/new_transfer_rate = tgui_input_list(user, "Amount per transfer from this:", "[src]", possible_transfer_amounts, "[amount_per_transfer_from_this]") if(!new_transfer_rate) return - if(!Adjacent(user)) - to_chat(user, "You have moved too far away!") - return - if(!ishuman(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) - to_chat(user, "You can't use your hands!") + // This looks redundant, but it's not. Time elapsed while the input + // list was open, so we need to re-check our conditions and give an + // error if they changed. + if(!can_set_transfer_amount(user)) + if(!Adjacent(user)) + to_chat(user, "You have moved too far away!") + if(!ishuman(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) + to_chat(user, "You can't use your hands!") return amount_per_transfer_from_this = new_transfer_rate diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index 6a7f760a61e0..fe802e47b968 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -28,9 +28,6 @@ || istype(A, /obj/item/reagent_containers) || istype(A, /obj/structure/sink) || istype(A, /obj/structure/janitorialcart) || istype(A, /obj/machinery/hydroponics)) return - if(istype(A, /obj/effect/proc_holder/spell)) - return - if(istype(A, /obj/structure/reagent_dispensers) && get_dist(src,A) <= 1) //this block copypasted from reagent_containers/glass, for lack of a better solution if(!A.reagents.total_volume && A.reagents) to_chat(user, "[A] is empty.") diff --git a/code/modules/research/message_server.dm b/code/modules/research/message_server.dm index 1299016a5a7d..0777506e95e0 100644 --- a/code/modules/research/message_server.dm +++ b/code/modules/research/message_server.dm @@ -82,23 +82,20 @@ GLOBAL_LIST_EMPTY(message_servers) /obj/machinery/message_server/proc/send_pda_message(recipient = "", sender = "", message = "") pda_msgs += new/datum/data_pda_msg(recipient,sender,message) -/obj/machinery/message_server/proc/send_rc_message(recipient = "", sender = "", message = "", stamp = "", id_auth = "", priority = 1) +/obj/machinery/message_server/proc/send_rc_message(recipient = "", sender = "", message = list(), stamp = "Not stamped", id_auth = "Not verified", priority = 1) + if(!islist(message)) + message = list(message) rc_msgs += new/datum/data_rc_msg(recipient,sender,message,stamp,id_auth) - var/authmsg = "[message]" - if(id_auth) - authmsg += " - [id_auth]" - if(stamp) - authmsg += " - [stamp]" for(var/C in GLOB.allRequestConsoles) var/obj/machinery/requests_console/RC = C if(ckey(RC.department) == ckey(recipient)) var/title switch(priority) if(2) - title = "PRIORITY Alert in [sender]" + title = "PRIORITY Alert from [sender]" else title = "Message from [sender]" - RC.createMessage(sender, title, authmsg, priority) + RC.createMessage(sender, title, message, priority, verified = id_auth, stamped = stamp) /obj/machinery/message_server/attack_hand(user as mob) to_chat(user, "You toggle PDA message passing from [active ? "On" : "Off"] to [active ? "Off" : "On"]") diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index e2f0acd79923..dd0ba0dcc732 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -521,12 +521,11 @@ /obj/effect/timestop/New() ..() for(var/mob/living/M in GLOB.player_list) - for(var/obj/effect/proc_holder/spell/aoe/conjure/timestop/T in M.mind.spell_list) //People who can stop time are immune to timestop + for(var/datum/spell/aoe/conjure/timestop/T in M.mind.spell_list) //People who can stop time are immune to timestop immune |= M - /obj/effect/timestop/proc/timestop() - playsound(get_turf(src), 'sound/magic/timeparadox2.ogg', 100, 1, -1) + playsound(get_turf(src), 'sound/magic/timeparadox2.ogg', 100, TRUE, -1) for(var/i in 1 to duration-1) for(var/A in orange (freezerange, loc)) if(isliving(A)) diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index a11c6174ed47..12f768c91af2 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -284,7 +284,7 @@ //this is a hook for custom behaviour. Maybe at some point we could add checks to see if engines are intact /obj/docking_port/mobile/proc/canMove() - return 0 //0 means we can move + return TRUE // TRUE means we can move. Why would it ever be otherwise? //this is to check if this shuttle can physically dock at dock S /obj/docking_port/mobile/proc/canDock(obj/docking_port/stationary/S) @@ -450,7 +450,7 @@ if(!check_dock(S1)) return -1 - if(canMove()) + if(!canMove()) return -1 var/obj/docking_port/stationary/S0 = get_docked() @@ -508,6 +508,8 @@ //move mobile to new location for(var/atom/movable/AM in T0) + if(AM.loc != T0) //fix for multi-tile objects + continue AM.onShuttleMove(T0, T1, rotation, last_caller) if(rotation) diff --git a/code/modules/shuttle/shuttle_rotate.dm b/code/modules/shuttle/shuttle_rotate.dm index e8b72452e6f9..1c1694069298 100644 --- a/code/modules/shuttle/shuttle_rotate.dm +++ b/code/modules/shuttle/shuttle_rotate.dm @@ -24,6 +24,19 @@ If ever any of these procs are useful for non-shuttles, rename it to proc/rotate pixel_x = oldPY pixel_y = (oldPX*(-1)) + +/atom/movable/shuttleRotate(rotation, params) + . = ..() + //rotate the physical bounds and offsets for multitile atoms too. Override base "rotate the pixel offsets" for multitile atoms. + //Override non zero bound_x, bound_y, pixel_x, pixel_y to zero. + //Dont take in account starting bound_x, bound_y, pixel_x, pixel_y. + //So it can unintentionally shift physical bounds of things that starts with non zero bound_x, bound_y. + if((bound_height != world.icon_size || bound_width != world.icon_size) && (bound_x == 0) && (bound_y == 0)) //Dont shift things that have non zero bound_x and bound_y, or it move somewhere. + pixel_x = dir & (NORTH|EAST) ? (world.icon_size - bound_width) : 0 + pixel_y = dir & (NORTH|WEST) ? (world.icon_size - bound_width) : 0 + bound_x = pixel_x + bound_y = pixel_y + /************************************Turf rotate procs************************************/ /************************************Mob rotate procs************************************/ @@ -56,9 +69,6 @@ If ever any of these procs are useful for non-shuttles, rename it to proc/rotate d2 = temp update_icon(UPDATE_ICON_STATE) -/obj/structure/shuttle/engine/shuttleRotate(rotation, params) - setDir(angle2dir(rotation+dir2angle(dir))) - //Fixes dpdir on shuttle rotation /obj/structure/disposalpipe/shuttleRotate(rotation, params) . = ..() diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm index a15863a3866b..9fcc73e6fc6d 100644 --- a/code/modules/shuttle/supply.dm +++ b/code/modules/shuttle/supply.dm @@ -1,5 +1,12 @@ #define MAX_CRATE_DELIVERY 40 +#define CARGO_OK 0 +#define CARGO_PREVENT_SHUTTLE 1 +#define CARGO_SKIP_ATOM 2 +#define CARGO_REQUIRE_PRIORITY 3 +#define CARGO_HAS_PRIORITY 4 + + /obj/docking_port/mobile/supply name = "supply shuttle" id = "supply" @@ -10,45 +17,57 @@ dwidth = 5 height = 7 + // The list of things that can't be sent to CC. + var/list/blacklist = list( + "living creatures" = list( + /mob/living, + /obj/structure/blob, + /obj/structure/spider/spiderling, + /obj/machinery/clonepod, + /obj/item/paicard), + "classified nuclear weaponry" = list( + /obj/item/disk/nuclear, + /obj/machinery/nuclearbomb), + "homing beacons" = list( + /obj/item/radio/beacon, + /obj/machinery/quantumpad, + /obj/machinery/teleport/station, + /obj/machinery/teleport/hub, + /obj/machinery/telepad, + /obj/machinery/telepad_cargo, + /obj/structure/extraction_point), + "high-energy objects" = list( + /obj/singularity, + /obj/machinery/the_singularitygen, + /obj/effect/hierophant, + /obj/item/warp_cube), + "undelivered mail" = list(/obj/item/envelope)) + + // The current manifest of what's on the shuttle. + var/datum/economy/cargo_shuttle_manifest/manifest = new + + // The auto-registered simple_seller instances. + var/list/simple_sellers = list() + + // The item preventing this shuttle from going to CC. + var/blocking_item = "ERR_UNKNOWN" + +/obj/docking_port/mobile/supply/Initialize() + ..() + for(var/T in subtypesof(/datum/economy/simple_seller)) + var/datum/economy/simple_seller/seller = new T + simple_sellers += seller + seller.register(src) + /obj/docking_port/mobile/supply/register() if(!..()) return FALSE SSshuttle.supply = src return TRUE -/obj/docking_port/mobile/supply/proc/forbidden_atoms_check(atom/A) - var/list/blacklist = list( - /mob/living, - /obj/structure/blob, - /obj/structure/spider/spiderling, - /obj/item/disk/nuclear, - /obj/machinery/nuclearbomb, - /obj/item/radio/beacon, - /obj/machinery/the_singularitygen, - /obj/singularity, - /obj/machinery/teleport/station, - /obj/machinery/teleport/hub, - /obj/machinery/telepad, - /obj/machinery/telepad_cargo, - /obj/machinery/clonepod, - /obj/effect/hierophant, - /obj/item/warp_cube, - /obj/machinery/quantumpad, - /obj/structure/extraction_point, - /obj/item/envelope, - /obj/item/paicard) - if(A) - if(is_type_in_list(A, blacklist)) - return TRUE - for(var/thing in A) - if(.(thing)) - return TRUE - - return FALSE - /obj/docking_port/mobile/supply/canMove() if(is_station_level(z)) - return forbidden_atoms_check(areaInstance) + return scan_cargo() return ..() /obj/docking_port/mobile/supply/request(obj/docking_port/stationary/S) @@ -56,27 +75,30 @@ return 2 return ..() -/obj/docking_port/mobile/supply/dock() +/obj/docking_port/mobile/supply/dock(port) . = ..() if(.) return - buy() - sell() + if(istype(port, /obj/docking_port/stationary/transit)) + // Ignore transit ports. + return -/obj/docking_port/mobile/supply/proc/buy() - if(!is_station_level(z)) //we only buy when we are -at- the station - return 1 + if(is_station_level(z)) + // Buy when arriving at the station. + buy() + if(z == level_name_to_num(CENTCOMM)) + // Sell when arriving at CentComm. + sell() + +/obj/docking_port/mobile/supply/proc/buy() for(var/datum/supply_order/order as anything in SSeconomy.shopping_list) if(length(SSeconomy.delivery_list) >= MAX_CRATE_DELIVERY) break SSeconomy.delivery_list += order SSeconomy.shopping_list -= order - if(!length(SSeconomy.delivery_list)) - return 2 - var/list/emptyTurfs = list() for(var/turf/simulated/T in areaInstance) if(T.density) @@ -108,151 +130,673 @@ SSeconomy.delivery_list.Cut() -/obj/docking_port/mobile/supply/proc/sell() - if(z != level_name_to_num(CENTCOMM)) //we only sell when we are -at- centcomm - return 1 + for(var/datum/station_goal/secondary/SG in SSticker.mode.secondary_goals) + if(!SG.should_send_crate) + continue + + var/turf/T = pick_n_take(emptyTurfs) //turf we will place it in + if(!T) + break - var/plasma_count = 0 - var/intel_count = 0 - var/crate_count = 0 - var/total_crate_value = 0 + var/obj/structure/closet/crate/secure/personal/PC = new(T) + if(SG.requester_name) + PC.name = "goal crate ([SG.requester_name] in [SG.department])" + PC.desc = "This personal crate has been configured by CC for [SG.requester_name]'s use in completing the secondary goal [SG.name]." + PC.registered_name = SG.requester_name + else + PC.name = "goal crate (Unknown in [SG.department])" + PC.locked = FALSE + PC.update_icon() + + SG.should_send_crate = FALSE + +/obj/docking_port/mobile/supply/proc/scan_cargo() + manifest = new + SEND_SIGNAL(src, COMSIG_CARGO_BEGIN_SCAN) + for(var/atom/movable/AM in areaInstance) + if(deep_scan(AM, TRUE) == CARGO_PREVENT_SHUTTLE) + return FALSE + return TRUE - var/msg = "
---[station_time_timestamp()]---

" - var/credits_to_deposit = 0 - var/research_credits = 0 - var/service_credits = 0 - var/medical_credits = 0 +/obj/docking_port/mobile/supply/proc/deep_scan(atom/movable/AM, top_level = FALSE) + var/handling = prefilter_atom(AM) + if(handling == CARGO_PREVENT_SHUTTLE) + return CARGO_PREVENT_SHUTTLE + + var/found_priority = FALSE + for(var/atom/movable/child in AM) + var/child_handling = deep_scan(child) + if(child_handling == CARGO_PREVENT_SHUTTLE) + return CARGO_PREVENT_SHUTTLE + if(child_handling == CARGO_HAS_PRIORITY) + found_priority = TRUE + + if(handling != CARGO_SKIP_ATOM) + if(handling == CARGO_REQUIRE_PRIORITY && !found_priority) + blocking_item = "locked containers that don't contain goal items ([AM])" + 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 + return CARGO_HAS_PRIORITY + + return CARGO_OK + +/obj/docking_port/mobile/supply/proc/prefilter_atom(atom/movable/AM) + for(var/reason in blacklist) + if(is_type_in_list(AM, blacklist[reason])) + blocking_item = "[reason] ([AM])" + return CARGO_PREVENT_SHUTTLE + + if(istype(AM, /obj/structure/largecrate)) + blocking_item = "unopened large crates ([AM])" + return CARGO_PREVENT_SHUTTLE + + if(istype(AM, /obj/structure/closet/crate)) + var/obj/structure/closet/crate/C = AM + if(C.manifest) + blocking_item = "crates with their manifest still attached ([AM])" + return CARGO_PREVENT_SHUTTLE + + if(istype(AM, /obj/structure/closet/crate/secure)) + var/obj/structure/closet/crate/secure/SC = AM + if(SC.locked) + return CARGO_REQUIRE_PRIORITY + else if(istype(SC, /obj/structure/closet/crate/secure/personal)) + blocking_item = "unlocked personal crates ([AM])" + return CARGO_PREVENT_SHUTTLE + + if(istype(AM, /obj/item/storage/lockbox)) + var/obj/item/storage/lockbox/LB = AM + if(LB.locked) + return CARGO_REQUIRE_PRIORITY + + if(istype(AM, /obj/effect)) + var/obj/effect/E = AM + if(E.is_cleanable()) + return CARGO_OK + + if(AM.anchored && !istype(AM, /obj/mecha/working)) + return CARGO_SKIP_ATOM + + return CARGO_OK - for(var/atom/movable/MA in areaInstance) - if(MA.anchored) + +/obj/docking_port/mobile/supply/proc/sell() + SEND_SIGNAL(src, COMSIG_CARGO_BEGIN_SELL) + SSeconomy.sold_atoms = list() + var/list/qdel_atoms = list() + var/list/rescue_atoms = list() + for(var/atom/movable/AM in manifest.items_to_sell) + var/sellable = manifest.items_to_sell[AM] + if(sellable & COMSIG_CARGO_SELL_PRIORITY) + SEND_SIGNAL(src, COMSIG_CARGO_DO_PRIORITY_SELL, AM, manifest) + SSeconomy.sold_atoms += "[AM.name](priority)" + qdel_atoms += AM + continue + else if(sellable & COMSIG_CARGO_SELL_NORMAL) + SEND_SIGNAL(src, COMSIG_CARGO_DO_SELL, AM, manifest) + SSeconomy.sold_atoms += "[AM.name](normal)" + qdel_atoms += AM continue - if(istype(MA, /mob/dead)) + else if(sellable & COMSIG_CARGO_SELL_WRONG) + SEND_SIGNAL(src, COMSIG_CARGO_SEND_ERROR, AM, manifest) + SSeconomy.sold_atoms += "[AM.name](error)" + qdel_atoms += AM continue - if(istype(MA, /obj/structure/closet/crate/mail)) + else if(sellable & COMSIG_CARGO_MESS) + manifest.messy_shuttle = TRUE + SSeconomy.sold_atoms += "[AM.name](mess)" + qdel_atoms += AM continue - SSeconomy.sold_atoms += " [MA.name]" - - // Must be in a crate (or a critter crate)! - if(istype(MA, /obj/structure/closet/crate) || istype(MA, /obj/structure/closet/critter)) - SSeconomy.sold_atoms += ":" - if(!length(MA.contents)) - SSeconomy.sold_atoms += " (empty)" - if(istype(MA, /obj/structure/closet/crate)) - var/obj/structure/closet/crate/exported_crate = MA - total_crate_value += exported_crate.crate_value - else - total_crate_value += DEFAULT_CRATE_VALUE - crate_count++ - - var/find_slip = TRUE - for(var/thing in MA) - // Sell manifests - SSeconomy.sold_atoms += " [thing:name]" - if(find_slip && istype(thing,/obj/item/paper/manifest)) - var/obj/item/paper/manifest/slip = thing - credits_to_deposit += SSeconomy.credits_per_manifest - msg += "+[SSeconomy.credits_per_manifest]: Package [slip.ordernumber] accorded.
" - - // Sell plasma - if(istype(thing, /obj/item/stack/sheet/mineral/plasma)) - var/obj/item/stack/sheet/mineral/plasma/P = thing - plasma_count += P.amount - - // Sell syndicate intel - if(istype(thing, /obj/item/documents/syndicate)) - ++intel_count - - // Sell tech levels - if(istype(thing, /obj/item/disk/tech_disk)) - var/obj/item/disk/tech_disk/disk = thing - if(!disk.stored) - continue - var/datum/tech/tech = disk.stored - - var/cost = tech.getCost(SSeconomy.tech_levels[tech.id]) - if(cost) - SSeconomy.tech_levels[tech.id] = tech.level - research_credits += cost / 2 - credits_to_deposit += cost / 2 - msg += "+[cost]: [tech.name] - new data.
" - - // Sell designs - if(istype(thing, /obj/item/disk/design_disk)) - var/obj/item/disk/design_disk/disk = thing - if(!disk.blueprint) - continue - var/datum/design/design = disk.blueprint - if(design.id in SSeconomy.research_designs) - continue - credits_to_deposit += SSeconomy.credits_per_design - SSeconomy.research_designs += design.id - msg += "+[SSeconomy.credits_per_design]: [design.name] design.
" - - // Sell viral sample virology goals, those in vial lockboxes included - if(istype(thing, /obj/item/reagent_containers) || istype(thing, /obj/item/storage/lockbox/vials)) - var/list/sold_containers = list() - if(istype(thing, /obj/item/reagent_containers)) - sold_containers += thing - if(istype(thing, /obj/item/storage/lockbox/vials)) - for(var/obj/item/reagent_containers/C in thing) - sold_containers += C - for(var/obj/item/reagent_containers/C in sold_containers) - if(C.reagents?.reagent_list) - for(var/datum/virology_goal/G in GLOB.virology_goals) - if(G.completed) - continue - if(G.check_completion(C.reagents.reagent_list)) - medical_credits += SSeconomy.credits_per_virology_goal - msg += "+[SSeconomy.credits_per_virology_goal]: [G.name] completion.
" - - // Sell exotic plants - if(istype(thing, /obj/item/seeds)) - var/obj/item/seeds/S = thing - if(S.rarity == 0) // Mundane species - msg += "+0: We don't need samples of mundane species \"[capitalize(S.species)]\".
" - else if(SSeconomy.discovered_plants[S.type]) // This species has already been sent to CentComm - var/potDiff = S.potency - SSeconomy.discovered_plants[S.type] // Compare it to the previous best - if(potDiff > 0) // This sample is better - SSeconomy.discovered_plants[S.type] = S.potency - msg += "+[potDiff]: New sample of \"[capitalize(S.species)]\" is superior. Good work.
" - service_credits += potDiff / 2 - credits_to_deposit += potDiff / 2 - else // This sample is worthless - msg += "+0: New sample of \"[capitalize(S.species)]\" is not more potent than existing sample ([SSeconomy.discovered_plants[S.type]] potency).
" - else // This is a new discovery! - SSeconomy.discovered_plants[S.type] = S.potency - msg += "[S.rarity]: New species discovered: \"[capitalize(S.species)]\". Excellent work.
" - service_credits += S.rarity / 2 // That's right, no bonus for potency. Send a crappy sample first to "show improvement" later - credits_to_deposit += S.rarity / 2 - - if(istype(thing, /obj/item/organ/internal/alien)) - var/obj/item/organ/internal/alien/organ = thing - credits_to_deposit += organ.cargo_profit - qdel(MA) - SSeconomy.sold_atoms += "." - - if(plasma_count > 0) - var/credits_from_plasma = plasma_count * SSeconomy.credits_per_plasma - msg += "+[credits_from_plasma]: Received [plasma_count] unit(s) of exotic material.
" - credits_to_deposit += credits_from_plasma - - if(intel_count > 0) - var/credits_from_intel = intel_count * SSeconomy.credits_per_intel - msg += "+[credits_from_intel]: Received [intel_count] article(s) of enemy intelligence.
" - credits_to_deposit += credits_from_intel - - if(crate_count > 0) - msg += "+[total_crate_value]: Received [crate_count] crate(s).
" - credits_to_deposit += total_crate_value + else if(!(sellable & COMSIG_CARGO_SELL_SKIP)) + manifest.sent_trash = TRUE + + rescue_atoms += AM + + for(var/atom/movable/AM in rescue_atoms) + if(AM.loc in qdel_atoms) + AM.forceMove(get_turf(AM)) + + for(var/AM in qdel_atoms) + qdel(AM) + + SEND_SIGNAL(src, COMSIG_CARGO_END_SELL, manifest) + + SSblackbox.record_feedback("amount", "cargo shipments", 1) + + if(manifest.loose_cargo) + var/datum/economy/line_item/item = new + item.account = SSeconomy.cargo_account + item.credits = SSeconomy.fine_for_loose_cargo + item.reason = "Please remember to secure all items in crates." + manifest.line_items += item + SSblackbox.record_feedback("nested tally", "cargo fines", 1, list("loose cargo", "amount")) + SSblackbox.record_feedback("nested tally", "cargo fines", SSeconomy.fine_for_loose_cargo, list("loose cargo", "credits")) + if(manifest.messy_shuttle) + var/datum/economy/line_item/item = new + item.account = SSeconomy.cargo_account + item.credits = SSeconomy.fine_for_messy_shuttle + item.reason = "Shuttle cleaning fee." + manifest.line_items += item + SSblackbox.record_feedback("nested tally", "cargo fines", 1, list("messy shuttle", "amount")) + SSblackbox.record_feedback("nested tally", "cargo fines", SSeconomy.fine_for_messy_shuttle, list("messy shuttle", "credits")) + if(manifest.sent_trash) + var/datum/economy/line_item/item = new + item.account = SSeconomy.cargo_account + item.credits = SSeconomy.fine_for_selling_trash + item.reason = "Don't send us random junk." + manifest.line_items += item + SSblackbox.record_feedback("nested tally", "cargo fines", 1, list("sent trash", "amount")) + SSblackbox.record_feedback("nested tally", "cargo fines", SSeconomy.fine_for_selling_trash, list("sent trash", "credits")) + + var/msg = "
---[station_time_timestamp()]---

" + + var/list/credit_changes = list() + for(var/datum/economy/line_item/item in manifest.line_items) + if(!credit_changes[item.account]) + credit_changes[item.account] = 0 + credit_changes[item.account] += item.credits + + if(item.credits > 0) + msg += "[item.account.account_name] +[item.credits]: [item.reason]
" + else if(item.credits == 0) + msg += "[item.account.account_name] Notice: [item.reason]
" + else + msg += "[item.account.account_name] [item.credits]: [item.reason]
" + + for(var/datum/money_account/account in credit_changes) + if(account.account_type == ACCOUNT_TYPE_DEPARTMENT) + SSblackbox.record_feedback("tally", "cargo profits", credit_changes[account], "[account.account_name]") + else + SSblackbox.record_feedback("tally", "cargo profits", credit_changes[account], "All personal accounts") + + if(credit_changes[account] > 0) + GLOB.station_money_database.credit_account(account, credit_changes[account], "Supply Shuttle Exports Payment", "Central Command Supply Master", supress_log = FALSE) + else + GLOB.station_money_database.charge_account(account, -credit_changes[account], "Supply Shuttle Fine", "Central Command Supply Master", allow_overdraft = TRUE, supress_log = FALSE) SSeconomy.centcom_message += "[msg]
" - if(credits_to_deposit > 0) - GLOB.station_money_database.credit_account(SSeconomy.cargo_account, credits_to_deposit, "Supply Shuttle Exports Payment", "Central Command Supply Master", supress_log = FALSE) - if(research_credits) - GLOB.station_money_database.credit_account(GLOB.station_money_database.get_account_by_department(DEPARTMENT_SCIENCE), research_credits, "Supply Shuttle Exports Payment", "Central Command Supply Master", supress_log = FALSE) - if(service_credits) - GLOB.station_money_database.credit_account(GLOB.station_money_database.get_account_by_department(DEPARTMENT_SERVICE), service_credits, "Supply Shuttle Exports Payment", "Central Command Supply Master", supress_log = FALSE) - if(medical_credits) - GLOB.station_money_database.credit_account(GLOB.station_money_database.get_account_by_department(DEPARTMENT_MEDICAL), medical_credits, "Supply Shuttle Exports Payment", "Central Command Supply Master", supress_log = FALSE) + manifest = new + + +// Convenience object that registers itself with the supply shuttle and provides +// methods for you to override. +/datum/economy/simple_seller + +/datum/economy/simple_seller/proc/register(obj/docking_port/mobile/supply/S) + RegisterSignal(S, COMSIG_CARGO_BEGIN_SCAN, PROC_REF(begin_scan)) + RegisterSignal(S, COMSIG_CARGO_CHECK_SELL, PROC_REF(check_sell)) + RegisterSignal(S, COMSIG_CARGO_BEGIN_SELL, PROC_REF(begin_sell)) + RegisterSignal(S, COMSIG_CARGO_DO_PRIORITY_SELL, PROC_REF(sell_priority)) + RegisterSignal(S, COMSIG_CARGO_DO_SELL, PROC_REF(sell_normal)) + RegisterSignal(S, COMSIG_CARGO_SEND_ERROR, PROC_REF(sell_wrong)) + RegisterSignal(S, COMSIG_CARGO_END_SELL, PROC_REF(end_sell)) + +/datum/economy/simple_seller/proc/begin_scan(obj/docking_port/mobile/supply/S) + SIGNAL_HANDLER // COMSIG_CARGO_BEGIN_SCAN + return + +/datum/economy/simple_seller/proc/check_sell(obj/docking_port/mobile/supply/S, atom/movable/AM) + SIGNAL_HANDLER // COMSIG_CARGO_CHECK_SELL + return NONE + +/datum/economy/simple_seller/proc/begin_sell(obj/docking_port/mobile/supply/S) + SIGNAL_HANDLER // COMSIG_CARGO_BEGIN_SELL + return + +/datum/economy/simple_seller/proc/sell_priority(obj/docking_port/mobile/supply/S, atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest) + SIGNAL_HANDLER // COMSIG_CARGO_DO_PRIORITY_SELL + return check_sell(S, AM) & COMSIG_CARGO_SELL_PRIORITY + +/datum/economy/simple_seller/proc/sell_normal(obj/docking_port/mobile/supply/S, atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest) + SIGNAL_HANDLER // COMSIG_CARGO_DO_SELL + return check_sell(S, AM) & COMSIG_CARGO_SELL_NORMAL + +/datum/economy/simple_seller/proc/sell_wrong(obj/docking_port/mobile/supply/S, atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest) + SIGNAL_HANDLER // COMSIG_CARGO_SEND_ERROR + return check_sell(S, AM) & COMSIG_CARGO_SELL_WRONG + +/datum/economy/simple_seller/proc/end_sell(obj/docking_port/mobile/supply/S, datum/economy/cargo_shuttle_manifest/manifest) + SIGNAL_HANDLER // COMSIG_CARGO_END_SELL + return + + +/datum/economy/simple_seller/crates + var/crates = 0 + var/credits = 0 + +/datum/economy/simple_seller/crates/begin_sell(obj/docking_port/mobile/supply/S) + crates = 0 + credits = 0 + +/datum/economy/simple_seller/crates/check_sell(obj/docking_port/mobile/supply/S, AM) + if(istype(AM, /obj/structure/closet/crate) || istype(AM, /obj/structure/closet/critter) || istype(AM, /obj/structure/closet/crate/mail)) + return COMSIG_CARGO_SELL_NORMAL | COMSIG_CARGO_IS_SECURED + +/datum/economy/simple_seller/crates/sell_normal(obj/docking_port/mobile/supply/S, atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest) + if(!..()) + return + + crates += 1 + if(istype(AM, /obj/structure/closet/crate)) + var/obj/structure/closet/crate/exported_crate = AM + credits += exported_crate.crate_value + else + credits += DEFAULT_CRATE_VALUE + +/datum/economy/simple_seller/crates/end_sell(obj/docking_port/mobile/supply/S, datum/economy/cargo_shuttle_manifest/manifest) + if(!credits) + return + var/datum/economy/line_item/item = new + item.account = SSeconomy.cargo_account + item.credits = credits + item.reason = "Returned [crates] crate(s)." + manifest.line_items += item + SSblackbox.record_feedback("tally", "cargo crates sold", crates, "amount") + SSblackbox.record_feedback("tally", "cargo crates sold", item.credits, "credits") + + +/datum/economy/simple_seller/plasma + var/plasma = 0 + +/datum/economy/simple_seller/plasma/begin_sell(obj/docking_port/mobile/supply/S) + plasma = 0 + +/datum/economy/simple_seller/plasma/check_sell(obj/docking_port/mobile/supply/S, atom/movable/AM) + if(istype(AM, /obj/item/stack/sheet/mineral/plasma)) + return COMSIG_CARGO_SELL_NORMAL + +/datum/economy/simple_seller/plasma/sell_normal(obj/docking_port/mobile/supply/S, atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest) + if(!..()) + return + + var/obj/item/stack/sheet/mineral/plasma/P = AM + plasma += P.amount + +/datum/economy/simple_seller/plasma/end_sell(obj/docking_port/mobile/supply/S, datum/economy/cargo_shuttle_manifest/manifest) + if(!plasma) + return + var/datum/economy/line_item/item = new + item.account = SSeconomy.cargo_account + item.credits = plasma * SSeconomy.credits_per_plasma + item.reason = "Received [plasma] unit(s) of exotic material." + manifest.line_items += item + SSblackbox.record_feedback("tally", "cargo plasma sold", plasma, "amount") + SSblackbox.record_feedback("tally", "cargo plasma sold", item.credits, "credits") + + +/datum/economy/simple_seller/intel + var/intel = 0 + +/datum/economy/simple_seller/intel/begin_sell(obj/docking_port/mobile/supply/S) + intel = 0 + +/datum/economy/simple_seller/intel/check_sell(obj/docking_port/mobile/supply/S, atom/movable/AM) + if(istype(AM, /obj/item/documents/syndicate)) + return COMSIG_CARGO_SELL_NORMAL + +/datum/economy/simple_seller/intel/sell_normal(obj/docking_port/mobile/supply/S, atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest) + if(!..()) + return + + intel++ + +/datum/economy/simple_seller/intel/end_sell(obj/docking_port/mobile/supply/S, datum/economy/cargo_shuttle_manifest/manifest) + if(!intel) + return + var/datum/economy/line_item/item = new + item.account = SSeconomy.cargo_account + item.credits = intel * SSeconomy.credits_per_intel + item.reason = "Received [intel] article(s) of enemy intelligence." + manifest.line_items += item + SSblackbox.record_feedback("tally", "cargo intel sold", intel, "amount") + SSblackbox.record_feedback("tally", "cargo intel sold", item.credits, "credits") + + +/datum/economy/simple_seller/alien_organs + +/datum/economy/simple_seller/alien_organs/check_sell(obj/docking_port/mobile/supply/S, atom/movable/AM) + if(istype(AM, /obj/item/organ/internal/alien)) + return COMSIG_CARGO_SELL_NORMAL + +/datum/economy/simple_seller/alien_organs/sell_normal(obj/docking_port/mobile/supply/S, atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest) + if(!..()) + return + + var/obj/item/organ/internal/alien/organ = AM + var/datum/economy/line_item/item = new + item.account = SSeconomy.cargo_account + item.credits = organ.cargo_profit + item.reason = "Received a sample of exotic biological tissue." + manifest.line_items += item + SSblackbox.record_feedback("tally", "cargo alien organs sold", 1, "amount") + SSblackbox.record_feedback("tally", "cargo alien organs sold", item.credits, "credits") + + +/datum/economy/simple_seller/shipping_manifests + +/datum/economy/simple_seller/shipping_manifests/check_sell(obj/docking_port/mobile/supply/S, atom/movable/AM) + if(istype(AM,/obj/item/paper/manifest)) + return COMSIG_CARGO_SELL_NORMAL + +/datum/economy/simple_seller/shipping_manifests/sell_normal(obj/docking_port/mobile/supply/S, atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest) + if(!..()) + return + + var/obj/item/paper/manifest/slip = AM + + var/datum/economy/line_item/item = new + item.account = SSeconomy.cargo_account + item.credits = SSeconomy.credits_per_manifest + item.reason = "Package [slip.ordernumber] accorded." + manifest.line_items += item + SSblackbox.record_feedback("tally", "cargo manifests sold", 1, "amount") + SSblackbox.record_feedback("tally", "cargo manifests sold", item.credits, "credits") + + +/datum/economy/simple_seller/tech_levels + var/list/temp_tech_levels + +/datum/economy/simple_seller/tech_levels/begin_scan(obj/docking_port/mobile/supply/S) + temp_tech_levels = SSeconomy.tech_levels.Copy() + +/datum/economy/simple_seller/tech_levels/begin_sell(obj/docking_port/mobile/supply/S) + temp_tech_levels = SSeconomy.tech_levels.Copy() + +/datum/economy/simple_seller/tech_levels/check_sell(obj/docking_port/mobile/supply/S, atom/movable/AM) + if(istype(AM, /obj/item/disk/tech_disk)) + var/obj/item/disk/tech_disk/disk = AM + if(!disk.stored) + return COMSIG_CARGO_SELL_WRONG + var/datum/tech/tech = disk.stored + + var/cost = tech.getCost(temp_tech_levels[tech.id]) + if(cost) + temp_tech_levels[tech.id] = tech.level + return COMSIG_CARGO_SELL_NORMAL + return COMSIG_CARGO_SELL_WRONG + +/datum/economy/simple_seller/tech_levels/sell_normal(obj/docking_port/mobile/supply/S, atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest) + if(!..()) + return + + var/obj/item/disk/tech_disk/disk = AM + if(!disk.stored) + return + var/datum/tech/tech = disk.stored + + var/cost = tech.getCost(SSeconomy.tech_levels[tech.id]) + if(!cost) + return + + SSeconomy.tech_levels[tech.id] = tech.level + SSblackbox.record_feedback("tally", "cargo tech disks sold", 1, "amount") + SSblackbox.record_feedback("tally", "cargo tech disks sold", cost, "credits") + + var/datum/economy/line_item/cargo_item = new + cargo_item.account = SSeconomy.cargo_account + cargo_item.credits = cost / 2 + cargo_item.reason = "[tech.name] - new data." + manifest.line_items += cargo_item + + var/datum/economy/line_item/science_item = new + science_item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_SCIENCE) + science_item.credits = cost / 2 + science_item.reason = "[tech.name] - new data." + manifest.line_items += science_item + +/datum/economy/simple_seller/tech_levels/sell_wrong(obj/docking_port/mobile/supply/S, atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest) + if(!..()) + return + + var/datum/economy/line_item/item = new + item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_SCIENCE) + item.credits = 0 + + var/obj/item/disk/tech_disk/disk = AM + if(!disk.stored) + item.reason = "Blank tech disk." + manifest.line_items += item + SSblackbox.record_feedback("tally", "cargo tech disks sold", 1, "blank") + return + + var/datum/tech/tech = disk.stored + var/cost = tech.getCost(SSeconomy.tech_levels[tech.id]) + if(!cost) + item.reason = "[tech.name] - no new data." + manifest.line_items += item + SSblackbox.record_feedback("tally", "cargo tech disks sold", 1, "repeat") + + +/datum/economy/simple_seller/designs + var/list/temp_designs + +/datum/economy/simple_seller/designs/begin_scan(obj/docking_port/mobile/supply/S) + temp_designs = SSeconomy.research_designs.Copy() + +/datum/economy/simple_seller/designs/begin_sell(obj/docking_port/mobile/supply/S) + temp_designs = SSeconomy.research_designs.Copy() + +/datum/economy/simple_seller/designs/check_sell(obj/docking_port/mobile/supply/S, atom/movable/AM) + if(istype(AM, /obj/item/disk/design_disk)) + var/obj/item/disk/design_disk/disk = AM + if(!disk.blueprint) + return COMSIG_CARGO_SELL_WRONG + var/datum/design/design = disk.blueprint + if(design.id in temp_designs) + return COMSIG_CARGO_SELL_WRONG + temp_designs += design.id + return COMSIG_CARGO_SELL_NORMAL + +/datum/economy/simple_seller/designs/sell_normal(obj/docking_port/mobile/supply/S, atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest) + if(!..()) + return + + var/obj/item/disk/design_disk/disk = AM + if(!disk.blueprint) + return + var/datum/design/design = disk.blueprint + if(design.id in SSeconomy.research_designs) + return + SSeconomy.research_designs += design.id + SSblackbox.record_feedback("tally", "cargo design disks sold", 1, "amount") + SSblackbox.record_feedback("tally", "cargo design disks sold", SSeconomy.credits_per_design, "credits") + + var/datum/economy/line_item/cargo_item = new + cargo_item.account = SSeconomy.cargo_account + cargo_item.credits = SSeconomy.credits_per_design / 2 + cargo_item.reason = "[design.name] design." + manifest.line_items += cargo_item + + var/datum/economy/line_item/science_item = new + science_item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_SCIENCE) + science_item.credits = SSeconomy.credits_per_design / 2 + science_item.reason = "[design.name] design." + manifest.line_items += science_item + +/datum/economy/simple_seller/designs/sell_wrong(obj/docking_port/mobile/supply/S, atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest) + if(!..()) + return + + var/datum/economy/line_item/item = new + item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_SCIENCE) + item.credits = 0 + + var/obj/item/disk/design_disk/disk = AM + if(!disk.blueprint) + item.reason = "Blank design disk." + manifest.line_items += item + SSblackbox.record_feedback("tally", "cargo design disks sold", 1, "blank") + return + var/datum/design/design = disk.blueprint + if(design.id in SSeconomy.research_designs) + item.reason = "Duplicate design for [design.name]." + manifest.line_items += item + SSblackbox.record_feedback("tally", "cargo design disks sold", 1, "repeat") + return + + +/datum/economy/simple_seller/seeds + var/list/temp_discovered + +/datum/economy/simple_seller/seeds/begin_scan(obj/docking_port/mobile/supply/S) + temp_discovered = SSeconomy.discovered_plants.Copy() + +/datum/economy/simple_seller/seeds/begin_sell(obj/docking_port/mobile/supply/S) + temp_discovered = SSeconomy.discovered_plants.Copy() + +/datum/economy/simple_seller/seeds/check_sell(obj/docking_port/mobile/supply/S, atom/movable/AM) + if(istype(AM, /obj/item/seeds)) + var/obj/item/seeds/seed = AM + if(seed.rarity == 0) // Mundane species + return COMSIG_CARGO_SELL_WRONG + if(!temp_discovered[seed.type] || temp_discovered[seed.type] < seed.potency) + temp_discovered[seed.type] = seed.potency + return COMSIG_CARGO_SELL_NORMAL + return COMSIG_CARGO_SELL_WRONG + +/datum/economy/simple_seller/seeds/sell_normal(obj/docking_port/mobile/supply/S, atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest) + if(!..()) + return + + var/msg = "" + var/credits = 0 + var/obj/item/seeds/seed = AM + if(seed.rarity == 0) // Mundane species + return + else if(SSeconomy.discovered_plants[seed.type]) + // This species has already been sent to CentComm + // Compare it to the previous best + var/potDiff = seed.potency - SSeconomy.discovered_plants[seed.type] + if(potDiff > 0) + SSeconomy.discovered_plants[seed.type] = seed.potency + credits = potDiff + msg = "New sample of \"[capitalize(seed.species)]\" is superior. Good work." + SSblackbox.record_feedback("tally", "cargo seeds sold", 1, "improved") + else + // This is a new discovery! + SSeconomy.discovered_plants[seed.type] = seed.potency + credits = seed.rarity + seed.potency + msg = "New species discovered: \"[capitalize(seed.species)]\". Excellent work." + SSblackbox.record_feedback("tally", "cargo seeds sold", 1, "new") + + if(credits == 0) + return + + SSblackbox.record_feedback("tally", "cargo seeds sold", 1, "amount") + SSblackbox.record_feedback("tally", "cargo seeds sold", credits, "credits") + + var/datum/economy/line_item/cargo_item = new + cargo_item.account = SSeconomy.cargo_account + cargo_item.credits = credits / 2 + cargo_item.reason = msg + manifest.line_items += cargo_item + + var/datum/economy/line_item/service_item = new + service_item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_SERVICE) + service_item.credits = credits / 2 + service_item.reason = msg + manifest.line_items += service_item + +/datum/economy/simple_seller/seeds/sell_wrong(obj/docking_port/mobile/supply/S, atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest) + if(!..()) + return + + var/datum/economy/line_item/item = new + item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_SERVICE) + item.credits = 0 + + var/obj/item/seeds/seed = AM + if(seed.rarity == 0) + item.reason = "We don't need samples of mundane species \"[capitalize(seed.species)]\"." + manifest.line_items += item + SSblackbox.record_feedback("tally", "cargo seeds sold", 1, "boring") + else if(SSeconomy.discovered_plants[seed.type] && SSeconomy.discovered_plants[seed.type] < seed.potency) + item.reason = "New sample of \"[capitalize(seed.species)]\" is not more potent than existing sample ([SSeconomy.discovered_plants[seed.type]] potency)." + manifest.line_items += item + SSblackbox.record_feedback("tally", "cargo seeds sold", 1, "repeat") + // If neither succeeds, this seed was declared wrong by a different + // seller, so we should be quiet. + + +/datum/economy/simple_seller/messes + +/datum/economy/simple_seller/messes/check_sell(obj/docking_port/mobile/supply/S, atom/movable/AM) + if(istype(AM, /obj/effect)) + var/obj/effect/E = AM + if(E.is_cleanable()) + return COMSIG_CARGO_MESS | COMSIG_CARGO_IS_SECURED + + +/datum/economy/simple_seller/containers + +/datum/economy/simple_seller/containers/check_sell(obj/docking_port/mobile/supply/S, atom/movable/AM) + if(istype(AM, /obj/item/storage)) + return COMSIG_CARGO_SELL_NORMAL + +/datum/economy/simple_seller/containers/sell_normal(obj/docking_port/mobile/supply/S, atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest) + if(!..()) + return + SSblackbox.record_feedback("amount", "cargo containers sold", 1) + + +/datum/economy/simple_seller/mechs + +/datum/economy/simple_seller/mechs/sell_normal(obj/docking_port/mobile/supply/S, atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest) + if(!..()) + return + SSblackbox.record_feedback("tally", "cargo basic mechs sold", 1, "amount") + SSblackbox.record_feedback("tally", "cargo basic mechs sold", SSeconomy.credits_per_mech, "credits") + + var/datum/economy/line_item/cargo_item = new + cargo_item.account = SSeconomy.cargo_account + cargo_item.credits = SSeconomy.credits_per_mech / 2 + cargo_item.reason = "Received a working [AM.name], great job!" + manifest.line_items += cargo_item + + var/datum/economy/line_item/science_item = new + science_item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_SCIENCE) + science_item.credits = SSeconomy.credits_per_mech / 2 + science_item.reason = "Received a working [AM.name], great job!" + manifest.line_items += science_item + + +/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 + + +// Skip mech parts to avoid complaining about them. +/datum/economy/simple_seller/mech_parts + +/datum/economy/simple_seller/mech_parts/check_sell(obj/docking_port/mobile/supply/S, atom/movable/AM) + if(istype(AM.loc, /obj/mecha/working)) + return COMSIG_CARGO_SELL_SKIP + + +/datum/economy/cargo_shuttle_manifest + var/list/items_to_sell = list() + var/list/line_items = list() + var/loose_cargo = FALSE + var/messy_shuttle = FALSE + var/sent_trash = FALSE + + +/datum/economy/line_item + var/datum/money_account/account + var/credits + var/reason + var/zero_is_good = FALSE #undef MAX_CRATE_DELIVERY + +#undef CARGO_OK +#undef CARGO_PREVENT_SHUTTLE +#undef CARGO_SKIP_ATOM +#undef CARGO_REQUIRE_PRIORITY +#undef CARGO_HAS_PRIORITY diff --git a/code/modules/station_goals/secondary/bar/random_bulk_drink.dm b/code/modules/station_goals/secondary/bar/random_bulk_drink.dm new file mode 100644 index 000000000000..016e9e74b3b0 --- /dev/null +++ b/code/modules/station_goals/secondary/bar/random_bulk_drink.dm @@ -0,0 +1,9 @@ +/datum/station_goal/secondary/random_bulk_reagent/bar + name = "Random Bulk Drink" + department = "Bar" + abstract = FALSE + +/datum/station_goal/secondary/random_bulk_reagent/bar/randomize_params() + ..() + department_account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_SERVICE) + report_message = "A visiting dignitary loves [initial(reagent_type.name)]. Please send us at least [amount] units of it." diff --git a/code/modules/station_goals/secondary/bar/variety_drinks.dm b/code/modules/station_goals/secondary/bar/variety_drinks.dm new file mode 100644 index 000000000000..fe11f919de37 --- /dev/null +++ b/code/modules/station_goals/secondary/bar/variety_drinks.dm @@ -0,0 +1,11 @@ +/datum/station_goal/secondary/variety_reagent/bar + name = "Variety of Drinks" + progress_type = /datum/secondary_goal_progress/variety_reagent + department = "Bar" + generic_name_plural = "alcoholic drinks" + abstract = FALSE + +/datum/station_goal/secondary/variety_reagent/bar/randomize_params() + ..() + department_account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_SERVICE) + report_message = "We're hosting a party, and need a variety of alcoholic drinks. Send us at least [amount_per] units each of [different_types] different ones. Keep them separate, and don't include anything too simple; we have our own booze dispenser." diff --git a/code/modules/station_goals/secondary/botany/kudzu_goal.dm b/code/modules/station_goals/secondary/botany/kudzu_goal.dm new file mode 100644 index 000000000000..68387c00754d --- /dev/null +++ b/code/modules/station_goals/secondary/botany/kudzu_goal.dm @@ -0,0 +1,105 @@ +/datum/station_goal/secondary/random_kudzu + name = "Random Kudzu" + department = "Hydroponics" + progress_type = /datum/secondary_goal_progress/random_kudzu + abstract = FALSE + var/list/traits = list() + var/amount = 5 + +/datum/station_goal/secondary/random_kudzu/randomize_params() + var/list/valid_traits = subtypesof(/datum/spacevine_mutation) + + traits += pick(valid_traits) + + var/list/trait_names = list() + for(var/dumb_trait in traits) + var/datum/spacevine_mutation/trait = dumb_trait + trait_names += initial(trait.name) + + report_message = "The NSV Watney is studying kudzu, and needs some samples with [english_list(trait_names)], but no other mutations. [amount] packs of seeds should do." + admin_desc = "Kudzu with [trait_names.Join(",")]" + +/datum/secondary_goal_progress/random_kudzu + var/list/traits + var/needed + var/sent = 0 + var/sent_this_shipment = 0 + +/datum/secondary_goal_progress/random_kudzu/configure(datum/station_goal/secondary/random_kudzu/goal) + ..() + traits = goal.traits + needed = goal.amount + +/datum/secondary_goal_progress/random_kudzu/Copy() + var/datum/secondary_goal_progress/random_kudzu/copy = ..() + copy.traits = traits + copy.needed = needed + copy.sent = sent + return copy + +/datum/secondary_goal_progress/random_kudzu/start_shipment() + sent_this_shipment = 0 + +/datum/secondary_goal_progress/random_kudzu/proc/check_mutations(obj/item/seeds/kudzu/seed) + if(length(seed.mutations) != length(traits)) + // Wrong number of traits. + return FALSE + if(length(seed.mutations - traits)) + // Different traits. + return FALSE + return TRUE + + +/datum/secondary_goal_progress/random_kudzu/update(atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest = null) + // Not in a matching personal crate? Ignore. + if(!check_personal_crate(AM)) + return + + if(!istype(AM, /obj/item/seeds/kudzu)) + return + + if(!check_mutations(AM)) + if(!manifest) + return COMSIG_CARGO_SELL_WRONG + var/datum/economy/line_item/item = new + item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_SERVICE) + item.credits = 0 + item.reason = "[AM] does not have the right traits." + manifest.line_items += item + return COMSIG_CARGO_SELL_WRONG + + sent++ + sent_this_shipment++ + return COMSIG_CARGO_SELL_PRIORITY + +/datum/secondary_goal_progress/random_kudzu/check_complete(datum/economy/cargo_shuttle_manifest/manifest) + if(sent_this_shipment > 0) + var/datum/economy/line_item/update_item = new + update_item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_SERVICE) + update_item.credits = 0 + update_item.zero_is_good = TRUE + update_item.reason = "Received [sent_this_shipment] useful samples of kudzu seeds." + manifest.line_items += update_item + + if(sent < needed) + return + + var/datum/economy/line_item/supply_item = new + supply_item.account = SSeconomy.cargo_account + supply_item.credits = SSeconomy.credits_per_kudzu_goal / 3 + supply_item.reason = "Secondary goal complete: [needed] samples of kudzu seeds." + manifest.line_items += supply_item + + var/datum/economy/line_item/department_item = new + department_item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_SERVICE) + department_item.credits = SSeconomy.credits_per_kudzu_goal / 3 + department_item.reason = "Secondary goal complete: [needed] samples of kudzu seeds." + manifest.line_items += department_item + + var/datum/economy/line_item/personal_item = new + personal_item.account = personal_account || department_item.account + personal_item.credits = SSeconomy.credits_per_kudzu_goal / 3 + personal_item.reason = "Secondary goal complete: [needed] samples of kudzu seeds." + manifest.line_items += personal_item + + return TRUE diff --git a/code/modules/station_goals/secondary/kitchen/random_bulk_condiment.dm b/code/modules/station_goals/secondary/kitchen/random_bulk_condiment.dm new file mode 100644 index 000000000000..a92d3fae94bb --- /dev/null +++ b/code/modules/station_goals/secondary/kitchen/random_bulk_condiment.dm @@ -0,0 +1,9 @@ +/datum/station_goal/secondary/random_bulk_reagent/kitchen + name = "Random Bulk Condiment" + department = "Kitchen" + abstract = FALSE + +/datum/station_goal/secondary/random_bulk_reagent/kitchen/randomize_params() + ..() + department_account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_SERVICE) + report_message = "Steve drank all of our [initial(reagent_type.name)]. Please send us another [amount] units of it." diff --git a/code/modules/station_goals/secondary/kitchen/random_bulk_food.dm b/code/modules/station_goals/secondary/kitchen/random_bulk_food.dm new file mode 100644 index 000000000000..7580945d7113 --- /dev/null +++ b/code/modules/station_goals/secondary/kitchen/random_bulk_food.dm @@ -0,0 +1,92 @@ +/datum/station_goal/secondary/random_bulk_food + name = "Random Bulk Food" + department = "Kitchen" + progress_type = /datum/secondary_goal_progress/random_bulk_food + abstract = FALSE + var/obj/item/food/snacks/food_type + var/amount + var/reward + +/datum/station_goal/secondary/random_bulk_food/randomize_params() + var/list/valid_food = list() + for(var/S in subtypesof(/obj/item/food/snacks)) + var/obj/item/food/snacks/candidate = S + if(initial(candidate.goal_difficulty) == FOOD_GOAL_SKIP) + continue + valid_food += candidate + + if(!valid_food) + food_type = /obj/item/food/snacks/cheesewedge + amount = 50 + return + + food_type = pick(valid_food) + switch(initial(food_type.goal_difficulty)) + if(FOOD_GOAL_EASY) + amount = 35 + reward = SSeconomy.credits_per_easy_food_goal + if(FOOD_GOAL_NORMAL) + amount = 15 + reward = SSeconomy.credits_per_normal_food_goal + else // FOOD_GOAL_HARD + amount = 5 + reward = SSeconomy.credits_per_hard_food_goal + + report_message = "Someone spiked the water cooler at CC with Space Drugs again, and we all have a craving for [initial(food_type.name)]. Please send us [amount] servings of it." + admin_desc = "[amount] servings of [initial(food_type.name)]" + + +/datum/secondary_goal_progress/random_bulk_food + var/obj/item/food/snacks/food_type + var/needed + var/sent = 0 + var/sent_this_shipment = 0 + var/reward + +/datum/secondary_goal_progress/random_bulk_food/configure(datum/station_goal/secondary/random_bulk_food/goal) + ..() + food_type = goal.food_type + needed = goal.amount + reward = goal.reward + +/datum/secondary_goal_progress/random_bulk_food/Copy() + var/datum/secondary_goal_progress/random_bulk_food/copy = ..() + copy.food_type = food_type + copy.needed = needed + copy.sent = sent + // These ones aren't really needed in the intended use case, they're + // just here in case someone uses this method somewhere else. + copy.reward = reward + return copy + +/datum/secondary_goal_progress/random_bulk_food/start_shipment() + sent_this_shipment = 0 + +/datum/secondary_goal_progress/random_bulk_food/update(atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest = null) + // Not in a matching personal crate? Ignore. + if(!check_personal_crate(AM)) + return + + if(!istype(AM, food_type)) + return + + sent++ + sent_this_shipment++ + return COMSIG_CARGO_SELL_PRIORITY + +/datum/secondary_goal_progress/random_bulk_food/check_complete(datum/economy/cargo_shuttle_manifest/manifest) + if(sent_this_shipment > 0) + SSblackbox.record_feedback("nested tally", "secondary goals", 1, list(goal_name, "food shipments", initial(food_type.name))) + SSblackbox.record_feedback("nested tally", "secondary goals", sent_this_shipment, list(goal_name, "food servings", initial(food_type.name))) + var/datum/economy/line_item/update_item = new + update_item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_SERVICE) + update_item.credits = 0 + update_item.zero_is_good = TRUE + update_item.reason = "Received [sent_this_shipment] servings of [initial(food_type.name)]." + manifest.line_items += update_item + + if(sent < needed) + return + + three_way_reward(manifest, "Kitchen", GLOB.station_money_database.get_account_by_department(DEPARTMENT_SERVICE), reward, "Secondary goal complete: [needed] units of [initial(food_type.name)].") + return TRUE diff --git a/code/modules/station_goals/secondary/medical/random_bulk_medicine.dm b/code/modules/station_goals/secondary/medical/random_bulk_medicine.dm new file mode 100644 index 000000000000..67f4ecba4025 --- /dev/null +++ b/code/modules/station_goals/secondary/medical/random_bulk_medicine.dm @@ -0,0 +1,9 @@ +/datum/station_goal/secondary/random_bulk_reagent/medchem + name = "Random Bulk Medicine" + department = "Medbay" + abstract = FALSE + +/datum/station_goal/secondary/random_bulk_reagent/medchem/randomize_params() + ..() + department_account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_MEDICAL) + report_message = "Doctor, I've got a fever, and the only prescription, is more [initial(reagent_type.name)]. No, really, send us [amount] units of it, please." diff --git a/code/modules/station_goals/secondary/medical/variety_medicine.dm b/code/modules/station_goals/secondary/medical/variety_medicine.dm new file mode 100644 index 000000000000..4344004fa352 --- /dev/null +++ b/code/modules/station_goals/secondary/medical/variety_medicine.dm @@ -0,0 +1,11 @@ +/datum/station_goal/secondary/variety_reagent/medchem + name = "Variety of Medicine" + progress_type = /datum/secondary_goal_progress/variety_reagent + department = "Medbay" + generic_name_plural = "medicines" + abstract = FALSE + +/datum/station_goal/secondary/variety_reagent/medchem/randomize_params() + ..() + department_account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_MEDICAL) + report_message = "A refrigiration failure on a smaller station has left them critically low on supplies. Please send us at least [amount_per] units each of [different_types] different medicines. Pills, patches, bottles, however you can send them, just keep the medicines from mixing." diff --git a/code/modules/station_goals/secondary/random_bulk_reagent.dm b/code/modules/station_goals/secondary/random_bulk_reagent.dm new file mode 100644 index 000000000000..62585e95e4c4 --- /dev/null +++ b/code/modules/station_goals/secondary/random_bulk_reagent.dm @@ -0,0 +1,102 @@ +/datum/station_goal/secondary/random_bulk_reagent + name = "Random Bulk Reagent" + progress_type = /datum/secondary_goal_progress/random_bulk_reagent + var/datum/reagent/reagent_type + var/amount + var/department_account + var/reward + +/datum/station_goal/secondary/random_bulk_reagent/Initialize(requester_account) + ..() + admin_desc = "[amount] units of [initial(reagent_type.name)]" + +/datum/station_goal/secondary/random_bulk_reagent/randomize_params() + var/list/valid_reagents = list() + for(var/R in subtypesof(/datum/reagent)) + var/datum/reagent/candidate = R + if(initial(candidate.goal_department) != department) + continue + if(initial(candidate.goal_difficulty) == REAGENT_GOAL_SKIP) + continue + valid_reagents += candidate + + if(!valid_reagents) + reagent_type = /datum/reagent/water + amount = 100 + return + + reagent_type = pick(valid_reagents) + switch(initial(reagent_type.goal_difficulty)) + if(REAGENT_GOAL_EASY) + amount = 600 + reward = SSeconomy.credits_per_easy_reagent_goal + if(REAGENT_GOAL_NORMAL) + amount = 300 + reward = SSeconomy.credits_per_normal_reagent_goal + else // REAGENT_GOAL_HARD + amount = 50 + reward = SSeconomy.credits_per_hard_reagent_goal + + +/datum/secondary_goal_progress/random_bulk_reagent + var/datum/reagent/reagent_type + var/needed + var/sent = 0 + var/department + var/department_account + var/reward + +/datum/secondary_goal_progress/random_bulk_reagent/configure(datum/station_goal/secondary/random_bulk_reagent/goal) + ..(goal) + reagent_type = goal.reagent_type + needed = goal.amount + department = goal.department + department_account = goal.department_account + reward = goal.reward + +/datum/secondary_goal_progress/random_bulk_reagent/Copy() + var/datum/secondary_goal_progress/random_bulk_reagent/copy = ..() + copy.reagent_type = reagent_type + copy.needed = needed + copy.sent = sent + // These ones aren't really needed in the intended use case, they're + // just here in case someone uses this method somewhere else. + copy.department = department + copy.department_account = department_account + copy.reward = reward + 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)) + if(!amount) + return + sent += amount + if(!manifest) + return COMSIG_CARGO_SELL_PRIORITY + + SSblackbox.record_feedback("nested tally", "secondary goals", 1, list(goal_name, "reagents", initial(reagent_type.id), "containers")) + SSblackbox.record_feedback("nested tally", "secondary goals", amount, list(goal_name, "reagents", initial(reagent_type.id), "units")) + var/datum/economy/line_item/item = new + item.account = department_account + item.credits = 0 + item.reason = "Received [amount] units of [initial(reagent_type.name)]." + item.zero_is_good = TRUE + manifest.line_items += item + + return COMSIG_CARGO_SELL_PRIORITY + +/datum/secondary_goal_progress/random_bulk_reagent/check_complete(datum/economy/cargo_shuttle_manifest/manifest) + if(sent < needed - REAGENT_GOAL_FORGIVENESS) + return + + three_way_reward(manifest, department, department_account, reward, "Secondary goal complete: [needed] units of [initial(reagent_type.name)].") + return TRUE diff --git a/code/modules/station_goals/secondary/science/random_bulk_chemical.dm b/code/modules/station_goals/secondary/science/random_bulk_chemical.dm new file mode 100644 index 000000000000..ce20898ed20e --- /dev/null +++ b/code/modules/station_goals/secondary/science/random_bulk_chemical.dm @@ -0,0 +1,9 @@ +/datum/station_goal/secondary/random_bulk_reagent/scichem + name = "Random Bulk Chemical" + department = "Science" + abstract = FALSE + +/datum/station_goal/secondary/random_bulk_reagent/scichem/randomize_params() + ..() + department_account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_SCIENCE) + report_message = "We're running an experiment with [initial(reagent_type.name)] and need more. Please send us [amount] units of it." diff --git a/code/modules/station_goals/secondary/science/random_ripley.dm b/code/modules/station_goals/secondary/science/random_ripley.dm new file mode 100644 index 000000000000..8398a523fbff --- /dev/null +++ b/code/modules/station_goals/secondary/science/random_ripley.dm @@ -0,0 +1,105 @@ +/datum/station_goal/secondary/random_ripley + name = "Random Ripley" + department = "Robotics" + progress_type = /datum/secondary_goal_progress/random_ripley + should_send_crate = FALSE + abstract = FALSE + var/list/modules = list() + var/static/list/general_modules = list( + /obj/item/mecha_parts/mecha_equipment/repair_droid, + /obj/item/mecha_parts/mecha_equipment/generator/nuclear, + /obj/item/mecha_parts/mecha_equipment/generator, + /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay, + /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster, + /obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster, + /obj/item/mecha_parts/mecha_equipment/thrusters, + /obj/item/mecha_parts/mecha_equipment/gravcatapult + ) + var/static/list/engineering_modules = list( + /obj/item/mecha_parts/mecha_equipment/cable_layer, + /obj/item/mecha_parts/mecha_equipment/hydraulic_clamp, + /obj/item/mecha_parts/mecha_equipment/weapon/energy/plasma, + /obj/item/mecha_parts/mecha_equipment/drill, + /obj/item/mecha_parts/mecha_equipment/drill/diamonddrill, + /obj/item/mecha_parts/mecha_equipment/rcd, + /obj/item/mecha_parts/mecha_equipment/mining_scanner, + /obj/item/mecha_parts/mecha_equipment/extinguisher + ) + +/datum/station_goal/secondary/random_ripley/randomize_params() + var/obj/item/mecha_parts/general_module = pick(general_modules) + modules += general_module + var/obj/item/mecha_parts/engineering_module = pick(engineering_modules) + modules += engineering_module + + report_message = list("One of our rapid-response teams lost a mech, and needs a replacement Ripley with \a [initial(general_module.name)] and \a [initial(engineering_module.name)].", + "You must label the mech properly. Use your ID card on a hand labeller to configure it.") + admin_desc = "Ripley with [initial(general_module.name)] and [initial(engineering_module.name)]" + + +/datum/secondary_goal_progress/random_ripley + var/obj/item/food/snacks/food_type + var/list/modules + var/sent = FALSE + +/datum/secondary_goal_progress/random_ripley/configure(datum/station_goal/secondary/random_ripley/goal) + ..() + modules = goal.modules + +/datum/secondary_goal_progress/random_ripley/Copy() + var/datum/secondary_goal_progress/random_ripley/copy = ..() + copy.modules = modules + copy.sent = sent + // These ones aren't really needed in the intended use case, they're + // just here in case someone uses this method somewhere else. + copy.personal_account = personal_account + 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) + return + if(!istype(AM, /obj/mecha/working/ripley)) + return + if(!manifest) + return COMSIG_CARGO_SELL_PRIORITY | COMSIG_CARGO_IS_SECURED + if(sent) + SSblackbox.record_feedback("nested tally", "secondary goals", 1, list(goal_name, "extra mech")) + SSblackbox.record_feedback("nested tally", "secondary goals", SSeconomy.credits_per_mech, list(goal_name, "extra mech credits")) + var/datum/economy/line_item/extra_item = new + extra_item.account = SSeconomy.cargo_account + extra_item.credits = SSeconomy.credits_per_mech + extra_item.reason = "We already got the mech we needed, but we'll take this one at the usual price." + manifest.line_items += extra_item + send_requests_console_message(extra_item.reason, "Central Command", "Robotics", "Stamped with the Central Command rubber stamp.", null, RQ_NORMALPRIORITY) + return COMSIG_CARGO_SELL_PRIORITY | COMSIG_CARGO_IS_SECURED + + var/remaining_needs = modules.Copy() + for(var/component in AM) + for(var/need in remaining_needs) + if(istype(component, need)) + remaining_needs -= need + break + // We sell or skip all of these, so we can delete it. + qdel(component) + if(length(remaining_needs)) + if(manifest) + SSblackbox.record_feedback("nested tally", "secondary goals", 1, list(goal_name, "incorrect mech")) + SSblackbox.record_feedback("nested tally", "secondary goals", SSeconomy.credits_per_mech, list(goal_name, "incorrect mech credits")) + var/datum/economy/line_item/wrong_item = new + wrong_item.account = SSeconomy.cargo_account + wrong_item.credits = SSeconomy.credits_per_mech + wrong_item.reason = "That's not the equipment we needed, but it's still a mech" + manifest.line_items += wrong_item + send_requests_console_message(wrong_item.reason + ", so we sent the usual amount to your supply account.", "Central Command", "Robotics", "Stamped with the Central Command rubber stamp.", null, RQ_NORMALPRIORITY) + return COMSIG_CARGO_SELL_PRIORITY | COMSIG_CARGO_IS_SECURED + + sent = TRUE + return COMSIG_CARGO_SELL_PRIORITY | COMSIG_CARGO_IS_SECURED + +/datum/secondary_goal_progress/random_ripley/check_complete(datum/economy/cargo_shuttle_manifest/manifest) + if(sent) + SSblackbox.record_feedback("nested tally", "secondary goals", 1, list(goal_name, "correct mech")) + three_way_reward(manifest, "Robotics", GLOB.station_money_database.get_account_by_department(DEPARTMENT_SCIENCE), SSeconomy.credits_per_ripley_goal, "Secondary goal complete: Customized Ripley.") + return sent diff --git a/code/modules/station_goals/secondary/science/variety_chemicals.dm b/code/modules/station_goals/secondary/science/variety_chemicals.dm new file mode 100644 index 000000000000..68080f0641e1 --- /dev/null +++ b/code/modules/station_goals/secondary/science/variety_chemicals.dm @@ -0,0 +1,12 @@ +/datum/station_goal/secondary/variety_reagent/scichem + name = "Variety of Chemicals" + progress_type = /datum/secondary_goal_progress/variety_reagent + different_types = 5 + department = "Science" + generic_name_plural = "chemicals" + abstract = FALSE + +/datum/station_goal/secondary/variety_reagent/scichem/randomize_params() + ..() + department_account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_SCIENCE) + report_message = "We're training a drug moose, and need some samples of drugs. Send us at least [amount_per] units each of [different_types] different ones. --Not Steve" diff --git a/code/modules/station_goals/secondary/secondary_goal.dm b/code/modules/station_goals/secondary/secondary_goal.dm new file mode 100644 index 000000000000..ae5df8807c91 --- /dev/null +++ b/code/modules/station_goals/secondary/secondary_goal.dm @@ -0,0 +1,104 @@ +/datum/station_goal/secondary + name = "Generic Secondary Goal" + required_crew = 1 + /// Admin-only shor description of the goal. + var/admin_desc = "No description" + /// Assigned department. Should match the values used for requests consoles. + var/department = "Unknown" + /// The person who requested the goal. + var/requester_name + /// The money account of the person who requested the goal. + var/personal_account + /// Should we (still) send a personal crate on the next shipment? + var/should_send_crate = TRUE + /// Type path of the progress tracker used. + var/progress_type = /datum/secondary_goal_progress + /// Progress type of this goal. + var/datum/secondary_goal_progress/progress + /// Tracker that manages the goal progress, permanent and temporary. + var/datum/secondary_goal_tracker/tracker + /// Abstract goals can't be used directly. + var/abstract = TRUE + +/datum/station_goal/secondary/proc/Initialize(requester_name_in, requester_account) + SHOULD_CALL_PARENT(TRUE) + requester_name = requester_name_in + personal_account = requester_account + randomize_params() + progress = new progress_type + progress.configure(src) + tracker = new(src, progress) + tracker.register(SSshuttle.supply) + +// Override this to randomly configure the goal before generating a progress +// tracker. +/datum/station_goal/secondary/proc/randomize_params() + return + +/datum/station_goal/secondary/send_report(requester, intro_override = FALSE) + var/list/message_parts = list() + if(intro_override) + message_parts += intro_override + else + message_parts += "Received secondary goal request from [requester] for [department]." + message_parts += "Querying master task list...." + message_parts += "Suitable task found. Task details:" + message_parts += "" + message_parts += report_message + if(should_send_crate) + message_parts += "You must submit this in a locked personal crate. One will be sent to your Cargo department. More can be ordered if needed." + send_requests_console_message(message_parts, "Central Command", department, "Stamped with the Central Command rubber stamp.", "Verified by A.L.I.C.E (CentCom AI)", RQ_HIGHPRIORITY) + if(department != "Captain's Desk") + send_requests_console_message(message_parts, "Central Command", "Captain's Desk", "Stamped with the Central Command rubber stamp.", "Verified by A.L.I.C.E (CentCom AI)", RQ_NORMALPRIORITY) + if(department != "Bridge") + send_requests_console_message(message_parts, "Central Command", "Bridge", "Stamped with the Central Command rubber stamp.", "Verified by A.L.I.C.E (CentCom AI)", RQ_NORMALPRIORITY) + +/proc/generate_secondary_goal(department, requester = null, mob/user = null) + var/list/possible = list() + var/list/departments = list() + for(var/T in subtypesof(/datum/station_goal/secondary)) + var/datum/station_goal/secondary/G = T + if(!initial(G.abstract) && !departments[initial(G.department)]) + departments[initial(G.department)] = TRUE + if(initial(G.department) != department || initial(G.abstract)) + continue + possible += G + + if(!length(possible)) + if(user) + to_chat(user, "No goals available for [department]. Goals are currently available for [english_list(departments)].") + return + + var/datum/station_goal/secondary/picked = pick(possible) + var/datum/station_goal/secondary/built = new picked + + var/requester_name = null + var/requester_account = null + var/obj/item/card/id/ID = requester + if(ID) + requester_name = ID.registered_name + requester_account = GLOB.station_money_database.find_user_account(ID.associated_account_number) + built.Initialize(requester_name, requester_account) + if(!ID) + built.send_report("CentCom") + else + built.send_report(ID.assignment ? "[ID.assignment] [ID.registered_name]" : ID.registered_name) + SSticker.mode.secondary_goals += built + +/datum/station_goal/secondary/Topic(href, href_list) + if(!check_rights(R_EVENT)) + return + + if(href_list["announce"]) + send_report("CentCom", "A task for [department] has been issued by Central Command:") + else if(href_list["remove"]) + SSticker.mode.secondary_goals -= src + qdel(src) + usr.client.modify_goals() + else if(href_list["mark_complete"]) + completed = 1 + usr.client.modify_goals() + else if(href_list["reset_progress"]) + completed = 0 + tracker.reset() + usr.client.modify_goals() diff --git a/code/modules/station_goals/secondary/secondary_goal_tracker.dm b/code/modules/station_goals/secondary/secondary_goal_tracker.dm new file mode 100644 index 000000000000..db31ce322bfb --- /dev/null +++ b/code/modules/station_goals/secondary/secondary_goal_tracker.dm @@ -0,0 +1,125 @@ +/datum/secondary_goal_tracker + var/datum/secondary_goal_progress/real_progress + var/datum/secondary_goal_progress/temporary_progress + var/datum/station_goal/secondary/goal + +/datum/secondary_goal_tracker/New(datum/station_goal/secondary/goal_in, datum/secondary_goal_progress/progress) + goal = goal_in + real_progress = progress + temporary_progress = progress.Copy() + +/datum/secondary_goal_tracker/proc/reset() + real_progress = new real_progress.type(goal) + temporary_progress = real_progress.Copy() + +/datum/secondary_goal_tracker/proc/register(shuttle) + RegisterSignal(shuttle, COMSIG_CARGO_BEGIN_SCAN, PROC_REF(reset_tempporary_progress)) + RegisterSignal(shuttle, COMSIG_CARGO_BEGIN_SELL, PROC_REF(reset_tempporary_progress)) + RegisterSignal(shuttle, COMSIG_CARGO_CHECK_SELL, PROC_REF(check_for_progress)) + RegisterSignal(shuttle, COMSIG_CARGO_DO_PRIORITY_SELL, PROC_REF(update_progress)) + RegisterSignal(shuttle, COMSIG_CARGO_SEND_ERROR, PROC_REF(update_progress)) + RegisterSignal(shuttle, COMSIG_CARGO_END_SELL, PROC_REF(check_for_completion)) + +/datum/secondary_goal_tracker/proc/unregister(shuttle) + UnregisterSignal(shuttle, COMSIG_CARGO_BEGIN_SCAN) + UnregisterSignal(shuttle, COMSIG_CARGO_BEGIN_SELL) + UnregisterSignal(shuttle, COMSIG_CARGO_CHECK_SELL) + UnregisterSignal(shuttle, COMSIG_CARGO_DO_PRIORITY_SELL) + UnregisterSignal(shuttle, COMSIG_CARGO_SEND_ERROR) + UnregisterSignal(shuttle, COMSIG_CARGO_END_SELL) + +// Resets the temporary porgress to match the real progress. +/datum/secondary_goal_tracker/proc/reset_tempporary_progress(obj/docking_port/mobile/supply/shuttle) + SIGNAL_HANDLER // COMSIG_CARGO_BEGIN_SCAN, COMSIG_CARGO_BEGIN_SELL + temporary_progress = real_progress.Copy() + real_progress.start_shipment() + +// Checks for temporary goal progress when selling a cargo item. +/datum/secondary_goal_tracker/proc/check_for_progress(obj/docking_port/mobile/supply/shuttle, atom/movable/thing) + SIGNAL_HANDLER // COMSIG_CARGO_CHECK_SELL + return temporary_progress.update(thing) + +// Update real goal progress when selling a cargo item. +/datum/secondary_goal_tracker/proc/update_progress(obj/docking_port/mobile/supply/shuttle, atom/movable/thing, datum/economy/cargo_shuttle_manifest/manifest) + SIGNAL_HANDLER // COMSIG_CARGO_DO_PRIORITY_SELL, COMSIG_CARGO_DO_SELL, COMSIG_CARGO_SEND_ERROR + . = real_progress.update(thing, manifest) + if(. & COMSIG_CARGO_SELL_PRIORITY) + SSblackbox.record_feedback("nested tally", "secondary goals", 1, list(goal.name, "items sold")) + +/datum/secondary_goal_tracker/proc/check_for_completion(obj/docking_port/mobile/supply/shuttle, datum/economy/cargo_shuttle_manifest/manifest) + SIGNAL_HANDLER // COMSIG_CARGO_END_SELL + if(real_progress.check_complete(manifest)) + goal.completed = TRUE + SSblackbox.record_feedback("nested tally", "secondary goals", 1, list(goal.name, "times completed")) + unregister(SSshuttle.supply) + + +/datum/secondary_goal_progress + var/personal_account + var/goal_requester + var/goal_name + +/datum/secondary_goal_progress/proc/configure(datum/station_goal/secondary/goal) + SHOULD_CALL_PARENT(TRUE) + goal_requester = goal.requester_name + personal_account = goal.personal_account + goal_name = goal.name + +/datum/secondary_goal_progress/proc/Copy() + SHOULD_CALL_PARENT(TRUE) + var/datum/secondary_goal_progress/copy = new type + copy.personal_account = personal_account + copy.goal_requester = goal_requester + copy.goal_name = goal_name + return copy + +// Override for custom shipment start behavior +// (e.g. ampount-per-shipment tracking) +// Only called on the real progress tracker. +/datum/secondary_goal_progress/proc/start_shipment() + return + +// Check the item to see if it belongs to this goal. +// Update the manifest accodingly, if provided. +// Return values from code/__DEFINES/supply_defines.dm. +// Use COMSIG_CARGO_SELL_PRIORITY, not COMSIG_CARGO_SELL_NORMAL. +/datum/secondary_goal_progress/proc/update(atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest = null) + return + +// Check to see if this goal has been completed. +// Update the manifest accordingly. +// Returns whether the goal was completed. +/datum/secondary_goal_progress/proc/check_complete(datum/economy/cargo_shuttle_manifest/manifest) + return FALSE + +/datum/secondary_goal_progress/proc/check_personal_crate(atom/movable/AM) + 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 + +/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")) + SSblackbox.record_feedback("nested tally", "secondary goals", reward, list(goal_name, "credits")) + + var/datum/economy/line_item/supply_item = new + supply_item.account = SSeconomy.cargo_account + supply_item.credits = reward / 3 + supply_item.reason = message + manifest.line_items += supply_item + + var/datum/economy/line_item/department_item = new + department_item.account = department_account + department_item.credits = reward / 3 + department_item.reason = message + manifest.line_items += department_item + + var/datum/economy/line_item/personal_item = new + personal_item.account = personal_account || department_account + personal_item.credits = reward / 3 + personal_item.reason = message + manifest.line_items += personal_item + + send_requests_console_message(message, "Central Command", department, "Stamped with the Central Command rubber stamp.", null, RQ_NORMALPRIORITY) diff --git a/code/modules/station_goals/secondary/variety_reagent.dm b/code/modules/station_goals/secondary/variety_reagent.dm new file mode 100644 index 000000000000..ffccf8c8912f --- /dev/null +++ b/code/modules/station_goals/secondary/variety_reagent.dm @@ -0,0 +1,138 @@ +/datum/station_goal/secondary/variety_reagent + name = "Variety of Reagent" + progress_type = /datum/secondary_goal_progress/variety_reagent + var/different_types = 10 + var/amount_per = 50 + var/department_account + var/generic_name_plural = "reagents" + var/reward + +/datum/station_goal/secondary/variety_reagent/Initialize(requester_account) + reward = SSeconomy.credits_per_variety_reagent_goal + ..() + admin_desc = "[amount_per] units of [different_types] [generic_name_plural]" + + +/datum/secondary_goal_progress/variety_reagent + var/list/reagents_sent = list() + var/department + var/needed + var/amount_per + var/department_account + var/reward + var/generic_name_plural + +/datum/secondary_goal_progress/variety_reagent/configure(datum/station_goal/secondary/variety_reagent/goal) + ..() + department = goal.department + needed = goal.different_types + amount_per = goal.amount_per + department_account = goal.department_account + reward = goal.reward + generic_name_plural = goal.generic_name_plural + +/datum/secondary_goal_progress/variety_reagent/Copy() + var/datum/secondary_goal_progress/variety_reagent/copy = ..() + copy.reagents_sent = reagents_sent.Copy() + copy.department = department + copy.needed = needed + copy.amount_per = amount_per + // These ones aren't really needed in the intended use case, they're + // just here in case someone uses this method somewhere else. + copy.department_account = department_account + copy.reward = reward + copy.generic_name_plural = generic_name_plural + 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) + return + + var/datum/reagent/reagent = container.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(!manifest) + return COMSIG_CARGO_SELL_WRONG + SSblackbox.record_feedback("nested tally", "secondary goals", 1, list(goal_name, "mixed reagents")) + var/datum/economy/line_item/item = new + item.account = department_account + item.credits = 0 + item.reason = "That [reagent.name] seems to be mixed with something else. Send it by itself, please." + manifest.line_items += item + send_requests_console_message(item.reason, "Central Command", department, "Stamped with the Central Command rubber stamp.", null, RQ_NORMALPRIORITY) + return COMSIG_CARGO_SELL_WRONG + + // No easy reagents allowed. + if(reagent.goal_difficulty == REAGENT_GOAL_SKIP) + if(!manifest) + return COMSIG_CARGO_SELL_WRONG + SSblackbox.record_feedback("nested tally", "secondary goals", 1, list(goal_name, "boring reagents")) + var/datum/economy/line_item/item = new + item.account = department_account + item.credits = 0 + item.reason = "We don't need [reagent.name]. Send something better." + manifest.line_items += item + send_requests_console_message(item.reason, "Central Command", department, "Stamped with the Central Command rubber stamp.", null, RQ_NORMALPRIORITY) + return COMSIG_CARGO_SELL_WRONG + + // Make sure there's enough. + if(reagent.volume < amount_per - REAGENT_GOAL_FORGIVENESS) + if(!manifest) + return COMSIG_CARGO_SELL_WRONG + SSblackbox.record_feedback("nested tally", "secondary goals", 1, list(goal_name, "insufficient quantity of reagents")) + var/datum/economy/line_item/item = new + item.account = department_account + item.credits = 0 + item.reason = "That batch of [reagent.name] was too small; send at least [amount_per] units." + manifest.line_items += item + send_requests_console_message(item.reason, "Central Command", department, "Stamped with the Central Command rubber stamp.", null, RQ_NORMALPRIORITY) + return COMSIG_CARGO_SELL_WRONG + + if(reagents_sent[reagent.id]) + if(!manifest) + return COMSIG_CARGO_SELL_WRONG + SSblackbox.record_feedback("nested tally", "secondary goals", 1, list(goal_name, "repeat reagents")) + var/datum/economy/line_item/item = new + item.account = department_account + item.credits = 0 + item.reason = "You already sent us [reagent.name]." + manifest.line_items += item + send_requests_console_message(item.reason, "Central Command", department, "Stamped with the Central Command rubber stamp.", null, RQ_NORMALPRIORITY) + return COMSIG_CARGO_SELL_WRONG + + reagents_sent[reagent.id] = TRUE + + if(!manifest) + return COMSIG_CARGO_SELL_PRIORITY + SSblackbox.record_feedback("nested tally", "secondary goals", 1, list(goal_name, "valid reagents")) + SSblackbox.record_feedback("nested tally", "secondary goals", 1, list(goal_name, "reagents", reagent.id)) + var/datum/economy/line_item/item = new + item.account = department_account + item.credits = 0 + item.reason = "Received [initial(reagent.name)]." + item.zero_is_good = TRUE + manifest.line_items += item + send_requests_console_message(item.reason, "Central Command", department, "Stamped with the Central Command rubber stamp.", null, RQ_NORMALPRIORITY) + return COMSIG_CARGO_SELL_PRIORITY + +/datum/secondary_goal_progress/variety_reagent/check_complete(datum/economy/cargo_shuttle_manifest/manifest) + if(length(reagents_sent) < needed) + return + + three_way_reward(manifest, department, department_account, reward, "Secondary goal complete: [needed] different [generic_name_plural].") + return TRUE diff --git a/code/modules/station_goals/station_goal.dm b/code/modules/station_goals/station_goal.dm index 683c1bdc35d0..5cf4c0b67d63 100644 --- a/code/modules/station_goals/station_goal.dm +++ b/code/modules/station_goals/station_goal.dm @@ -46,4 +46,6 @@ on_report() send_report() else if(href_list["remove"]) + SSticker.mode.station_goals -= src qdel(src) + usr.client.modify_goals() diff --git a/code/modules/station_goals/task_backlog.dm b/code/modules/station_goals/task_backlog.dm new file mode 100644 index 000000000000..3850adbe84fe --- /dev/null +++ b/code/modules/station_goals/task_backlog.dm @@ -0,0 +1,23 @@ +/datum/station_goal/clear_task_backlog + name = "Clear Task Backlog" + var/goal = 10 + +/datum/station_goal/clear_task_backlog/get_report() + return {"Clear Task Backlog
+ The last few weeks have been extremely profitable for Nanotrasen, but + we've got so many things to do that we're getting a bit overwhelmed.
+
+ We need you to pick up the slack. Use the Request Consoles on your + station to get Secondary Goals, and complete at least [goal] of them. +
+
+ -Nanotrasen Accounting"} + +/datum/station_goal/clear_task_backlog/check_completion() + if(..()) + return TRUE + var/count = 0 + for(var/datum/station_goal/secondary/S in SSticker.mode.secondary_goals) + if(S.completed) + count++ + return count >= goal diff --git a/code/modules/supply/supply_console.dm b/code/modules/supply/supply_console.dm index f24d0693b148..a70e43223b1b 100644 --- a/code/modules/supply/supply_console.dm +++ b/code/modules/supply/supply_console.dm @@ -441,8 +441,8 @@ /obj/machinery/computer/supplycomp/proc/move_shuttle(mob/user) if(is_public) // Public consoles cant move the shuttle. Dont allow exploiters. return - if(SSshuttle.supply.canMove()) - to_chat(user, "For safety reasons the automated supply shuttle cannot transport live organisms, undelivered mail, classified nuclear weaponry or homing beacons.") + if(!SSshuttle.supply.canMove()) + to_chat(user, "For safety reasons, the automated supply shuttle cannot transport [SSshuttle.supply.blocking_item].") else if(SSshuttle.supply.getDockedId() == "supply_home") SSshuttle.toggleShuttle("supply", "supply_home", "supply_away", 1) investigate_log("| [key_name(user)] has sent the supply shuttle away. Shuttle contents: [SSeconomy.sold_atoms]", "cargo") diff --git a/code/modules/supply/supply_packs/pack_miscellaneous.dm b/code/modules/supply/supply_packs/pack_miscellaneous.dm index 80dfa802b469..66b1ef894d69 100644 --- a/code/modules/supply/supply_packs/pack_miscellaneous.dm +++ b/code/modules/supply/supply_packs/pack_miscellaneous.dm @@ -82,6 +82,18 @@ contains = list(/obj/item/stack/tile/carpet/twenty) containername = "carpet crate" +/datum/supply_packs/misc/personal_crates + name = "Personal Crates Pack" + cost = 100 + containertype = /obj/structure/largecrate + contains = list(/obj/structure/closet/crate/secure/personal, + /obj/structure/closet/crate/secure/personal, + /obj/structure/closet/crate/secure/personal, + /obj/structure/closet/crate/secure/personal, + /obj/structure/closet/crate/secure/personal, + /obj/structure/closet/crate/secure/personal) + containername = "personal crates pack" + ///////////// Paper Work diff --git a/code/modules/surgery/generic.dm b/code/modules/surgery/generic.dm index 7a411bb967b3..8c8a29066807 100644 --- a/code/modules/surgery/generic.dm +++ b/code/modules/surgery/generic.dm @@ -39,6 +39,7 @@ " You have made an incision on [target]'s [affected.name] with \the [tool]." ) affected.open = ORGAN_ORGANIC_OPEN + target.resume_bleeding() return SURGERY_STEP_CONTINUE /datum/surgery_step/generic/cut_open/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery) diff --git a/code/modules/surgery/organs/augments_internal.dm b/code/modules/surgery/organs/augments_internal.dm index c110a5c76932..b366926e5032 100644 --- a/code/modules/surgery/organs/augments_internal.dm +++ b/code/modules/surgery/organs/augments_internal.dm @@ -472,7 +472,7 @@ /obj/item/organ/internal/cyberimp/brain/hackerman_deck/remove(mob/living/carbon/M, special = 0) . = ..() if(M.mind) - M.mind.RemoveSpell(/obj/effect/proc_holder/spell/hackerman_deck) + M.mind.RemoveSpell(/datum/spell/hackerman_deck) UnregisterSignal(M, COMSIG_BODY_TRANSFER_TO) /obj/item/organ/internal/cyberimp/brain/hackerman_deck/proc/on_body_transfer() @@ -485,8 +485,8 @@ /obj/item/organ/internal/cyberimp/brain/hackerman_deck/proc/add_spell() if(owner.mind) - owner.mind.RemoveSpell(/obj/effect/proc_holder/spell/hackerman_deck) //Just to be sure. - owner.mind.AddSpell(new /obj/effect/proc_holder/spell/hackerman_deck(null)) + owner.mind.RemoveSpell(/datum/spell/hackerman_deck) //Just to be sure. + owner.mind.AddSpell(new /datum/spell/hackerman_deck(null)) /obj/item/organ/internal/cyberimp/brain/hackerman_deck/emp_act(severity) owner.adjustStaminaLoss(40 / severity) @@ -494,7 +494,7 @@ to_chat(owner, "Your [name] heats up drastically!") return TRUE -/obj/effect/proc_holder/spell/hackerman_deck +/datum/spell/hackerman_deck name = "Activate Ranged Hacking" desc = "Click on any machine to hack them. Has a short range of only three tiles." base_cooldown = 10 SECONDS @@ -508,13 +508,13 @@ /// How many times have we successfully hacked in the last minute? Increases burn damage by 3 for each value above 0. var/recent_hacking = 0 -/obj/effect/proc_holder/spell/hackerman_deck/create_new_targeting() +/datum/spell/hackerman_deck/create_new_targeting() var/datum/spell_targeting/clicked_atom/C = new() C.range = 3 C.try_auto_target = FALSE return C -/obj/effect/proc_holder/spell/hackerman_deck/on_mind_transfer(mob/living/L) +/datum/spell/hackerman_deck/on_mind_transfer(mob/living/L) if(!ishuman(L)) return FALSE var/mob/living/carbon/human/H = L @@ -523,7 +523,7 @@ return FALSE return TRUE -/obj/effect/proc_holder/spell/hackerman_deck/cast(list/targets, mob/user) +/datum/spell/hackerman_deck/cast(list/targets, mob/user) var/atom/target = targets[1] if(get_dist(user, target) > 3) //fucking cameras holy shit to_chat(user, "Your implant is not robust enough to hack at that distance!") @@ -557,7 +557,7 @@ recent_hacking++ addtimer(CALLBACK(src, PROC_REF(lower_recent_hacking)), 1 MINUTES) -/obj/effect/proc_holder/spell/hackerman_deck/proc/lower_recent_hacking() +/datum/spell/hackerman_deck/proc/lower_recent_hacking() recent_hacking-- //[[[[MOUTH]]]] diff --git a/code/modules/surgery/organs/blood.dm b/code/modules/surgery/organs/blood.dm index e3353fb6b811..c3b4c13111f9 100644 --- a/code/modules/surgery/organs/blood.dm +++ b/code/modules/surgery/organs/blood.dm @@ -12,9 +12,9 @@ addtimer(CALLBACK(src, PROC_REF(resume_bleeding)), amount) /mob/living/carbon/human/proc/resume_bleeding() - bleedsuppress = FALSE - if(stat != DEAD && bleed_rate) + if(stat != DEAD && bleed_rate && bleedsuppress) to_chat(src, "The blood soaks through your bandage.") + bleedsuppress = FALSE // Takes care blood loss and regeneration /mob/living/carbon/human/handle_blood() diff --git a/code/modules/surgery/organs/ears.dm b/code/modules/surgery/organs/ears.dm index 182bb3f1eb1d..c9c145dcefa4 100644 --- a/code/modules/surgery/organs/ears.dm +++ b/code/modules/surgery/organs/ears.dm @@ -4,6 +4,7 @@ gender = PLURAL organ_tag = "ears" parent_organ = "head" + slot = "ears" /obj/item/organ/internal/ears/on_life() if(!iscarbon(owner)) diff --git a/code/modules/surgery/organs/subtypes/xenos.dm b/code/modules/surgery/organs/subtypes/xenos.dm index 98960fdd4b55..6512d934cedd 100644 --- a/code/modules/surgery/organs/subtypes/xenos.dm +++ b/code/modules/surgery/organs/subtypes/xenos.dm @@ -60,8 +60,8 @@ w_class = WEIGHT_CLASS_NORMAL origin_tech = "biotech=5;plasmatech=4" slot = "plasmavessel" - alien_powers = list(/obj/effect/proc_holder/spell/alien_spell/plant_weeds, /obj/effect/proc_holder/spell/alien_spell/transfer_plasma) - human_powers = list(/obj/effect/proc_holder/spell/alien_spell/syphon_plasma) + alien_powers = list(/datum/spell/alien_spell/plant_weeds, /datum/spell/alien_spell/transfer_plasma) + human_powers = list(/datum/spell/alien_spell/syphon_plasma) var/stored_plasma = 100 var/max_plasma = 300 @@ -130,8 +130,8 @@ icon_state = "acid" slot = "acid" origin_tech = "biotech=5;materials=2;combat=2" - alien_powers = list(/obj/effect/proc_holder/spell/touch/alien_spell/corrosive_acid) - human_powers = list(/obj/effect/proc_holder/spell/touch/alien_spell/burning_touch) + alien_powers = list(/datum/spell/touch/alien_spell/corrosive_acid) + human_powers = list(/datum/spell/touch/alien_spell/burning_touch) /obj/item/organ/internal/alien/hivenode name = "xeno hive node" @@ -139,7 +139,7 @@ slot = "hivenode" origin_tech = "biotech=5;magnets=4;bluespace=3" w_class = WEIGHT_CLASS_TINY - alien_powers = list(/obj/effect/proc_holder/spell/alien_spell/whisper) + alien_powers = list(/datum/spell/alien_spell/whisper) /obj/item/organ/internal/alien/hivenode/insert(mob/living/carbon/M, special = 0) ..() @@ -160,16 +160,16 @@ icon_state = "neurotox" slot = "neurotox" origin_tech = "biotech=5;combat=5" - alien_powers = list(/obj/effect/proc_holder/spell/alien_spell/neurotoxin) - human_powers = list(/obj/effect/proc_holder/spell/alien_spell/neurotoxin/death_to_xenos) + alien_powers = list(/datum/spell/alien_spell/neurotoxin) + human_powers = list(/datum/spell/alien_spell/neurotoxin/death_to_xenos) /obj/item/organ/internal/alien/resinspinner name = "xeno resin organ" icon_state = "liver-x" slot = "spinner" origin_tech = "biotech=5;materials=4" - alien_powers = list(/obj/effect/proc_holder/spell/alien_spell/build_resin) - human_powers = list(/obj/effect/proc_holder/spell/touch/alien_spell/consume_resin) + alien_powers = list(/datum/spell/alien_spell/build_resin) + human_powers = list(/datum/spell/touch/alien_spell/consume_resin) /obj/item/organ/internal/alien/eggsac name = "xeno egg sac" @@ -177,6 +177,6 @@ slot = "eggsac" w_class = WEIGHT_CLASS_BULKY origin_tech = "biotech=6" - alien_powers = list(/obj/effect/proc_holder/spell/alien_spell/plant_weeds/eggs) - human_powers = list(/obj/effect/proc_holder/spell/alien_spell/combust_facehuggers) + alien_powers = list(/datum/spell/alien_spell/plant_weeds/eggs) + human_powers = list(/datum/spell/alien_spell/combust_facehuggers) cargo_profit = 1000 diff --git a/code/modules/tgui/modules/crew_monitor.dm b/code/modules/tgui/modules/crew_monitor.dm index d57e9612da3a..65dc8e2ef869 100644 --- a/code/modules/tgui/modules/crew_monitor.dm +++ b/code/modules/tgui/modules/crew_monitor.dm @@ -70,8 +70,8 @@ data["is_advanced"] = is_advanced data["possible_levels"] = list() - for(var/z in 1 to world.maxz) - data["possible_levels"] |= z + for(var/zl in GLOB.space_manager.z_list) + data["possible_levels"] |= zl return data @@ -79,3 +79,6 @@ name = "Crew monitor (Observer)" is_advanced = TRUE ignore_sensors = TRUE + +/datum/ui_module/crew_monitor/ghost/ui_state(mob/user) + return GLOB.observer_state diff --git a/code/modules/tgui/tgui_input/alert_input.dm b/code/modules/tgui/tgui_input/alert_input.dm index 5f9abd1de10f..ef1afd04630d 100644 --- a/code/modules/tgui/tgui_input/alert_input.dm +++ b/code/modules/tgui/tgui_input/alert_input.dm @@ -84,7 +84,6 @@ /datum/tgui_alert/Destroy(force) SStgui.close_uis(src) state = null - QDEL_NULL(buttons) return ..() /** diff --git a/code/modules/tgui/tgui_input/list_input.dm b/code/modules/tgui/tgui_input/list_input.dm index f5bee6cb551f..dd642861baf4 100644 --- a/code/modules/tgui/tgui_input/list_input.dm +++ b/code/modules/tgui/tgui_input/list_input.dm @@ -103,7 +103,6 @@ /datum/tgui_list_input/Destroy(force) SStgui.close_uis(src) state = null - QDEL_NULL(items) return ..() /** diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm index 11434dea3193..7f234307d411 100644 --- a/code/modules/unit_tests/_unit_tests.dm +++ b/code/modules/unit_tests/_unit_tests.dm @@ -2,6 +2,7 @@ //Keep this sorted alphabetically #ifdef UNIT_TESTS +#include "jobs\test_job_globals.dm" #include "aicard_icons.dm" #include "announcements.dm" #include "areas_apcs.dm" diff --git a/code/modules/unit_tests/jobs/test_job_globals.dm b/code/modules/unit_tests/jobs/test_job_globals.dm new file mode 100644 index 000000000000..7ed56ff99800 --- /dev/null +++ b/code/modules/unit_tests/jobs/test_job_globals.dm @@ -0,0 +1,26 @@ +/datum/unit_test/job_globals/Run() + return + +/datum/unit_test/job_globals/proc/is_list_unique(list/L) + var/list_length = length(L) + var/unique_list = uniqueList(L) + var/unique_list_length = length(unique_list) + return list_length == unique_list_length + +/datum/unit_test/job_globals/proc/validate_list(list/L, list_name) + if(!is_list_unique(L)) + Fail("job_globals list '[list_name]' contains duplicate values.") + +/datum/unit_test/job_globals/no_duplicates/Run() + validate_list(GLOB.station_departments, "station_departments") + validate_list(GLOB.command_positions, "command_positions") + validate_list(GLOB.command_head_positions, "command_head_positions") + validate_list(GLOB.engineering_positions, "engineering_positions") + validate_list(GLOB.medical_positions, "medical_positions") + validate_list(GLOB.science_positions, "science_positions") + validate_list(GLOB.supply_positions, "supply_positions") + validate_list(GLOB.service_positions, "service_positions") + validate_list(GLOB.security_positions, "security_positions") + validate_list(GLOB.active_security_positions, "active_security_positions") + validate_list(GLOB.assistant_positions, "assistant_positions") + validate_list(GLOB.nonhuman_positions, "nonhuman_positions") diff --git a/code/modules/unit_tests/spell_targeting_test.dm b/code/modules/unit_tests/spell_targeting_test.dm index 250a66458f90..e1a189774390 100644 --- a/code/modules/unit_tests/spell_targeting_test.dm +++ b/code/modules/unit_tests/spell_targeting_test.dm @@ -1,6 +1,6 @@ /datum/unit_test/spell_targeting/Run() var/list/bad_spells = list() - for(var/obj/effect/proc_holder/spell/S as anything in typesof(/obj/effect/proc_holder/spell)) + for(var/datum/spell/S as anything in typesof(/datum/spell)) if(initial(S.name) == "Spell") continue // Skip abstract spells S = new S diff --git a/code/modules/virology/virology_goals.dm b/code/modules/virology/virology_goals.dm index 4306ec9093f5..805e1c232963 100644 --- a/code/modules/virology/virology_goals.dm +++ b/code/modules/virology/virology_goals.dm @@ -1,4 +1,4 @@ -GLOBAL_LIST_INIT(virology_goals, list(new /datum/virology_goal/property_symptom, new /datum/virology_goal/virus, new /datum/virology_goal/virus/stealth)) +GLOBAL_LIST_EMPTY(virology_goals) GLOBAL_LIST_EMPTY(archived_virology_goals) #define MAX_LOOPS 30 @@ -10,10 +10,62 @@ GLOBAL_LIST_EMPTY(archived_virology_goals) var/delivery_goal = 15 var/completed = FALSE +/datum/virology_goal/proc/register() + RegisterSignal(SSshuttle.supply, COMSIG_CARGO_CHECK_SELL, PROC_REF(check_for_virus)) + RegisterSignal(SSshuttle.supply, COMSIG_CARGO_DO_PRIORITY_SELL, PROC_REF(sell_virus)) + RegisterSignal(SSshuttle.supply, COMSIG_CARGO_SEND_ERROR, PROC_REF(complain_about_virus)) + +/datum/virology_goal/proc/unregister() + UnregisterSignal(SSshuttle.supply, COMSIG_CARGO_CHECK_SELL) + UnregisterSignal(SSshuttle.supply, COMSIG_CARGO_DO_PRIORITY_SELL) + UnregisterSignal(SSshuttle.supply, COMSIG_CARGO_SEND_ERROR) + +/datum/virology_goal/proc/check_for_virus(shuttle, atom/movable/thing) + SIGNAL_HANDLER // COMSIG_CARGO_CHECK_SELL + if(istype(thing, /obj/item/reagent_containers)) + var/obj/item/reagent_containers/C = thing + if(check_viruses(C.reagents.reagent_list)) + return COMSIG_CARGO_SELL_PRIORITY + return COMSIG_CARGO_SELL_WRONG + +/datum/virology_goal/proc/sell_virus(shuttle, atom/movable/thing, datum/economy/cargo_shuttle_manifest/manifest, complain = FALSE) + SIGNAL_HANDLER // COMSIG_CARGO_DO_PRIORITY_SELL + // Ignore everything after we're done. + if(completed) + return + + // Look for reagent containers, those in vial lockboxes included + if(!istype(thing, /obj/item/reagent_containers)) + return + + var/obj/item/reagent_containers/C = thing + if(!length(C.reagents?.reagent_list)) + // Nothing to look at. + return + + check_viruses(C.reagents.reagent_list, manifest, complain, complain) + + if(!completed) + // Didn't finish yet. + return + + // Report and give credits for the goal. + var/datum/economy/line_item/item = new + item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_MEDICAL) + item.credits = SSeconomy.credits_per_virology_goal + item.reason = "[name] completed." + manifest.line_items += item + + // Stop listening. + unregister() + +/datum/virology_goal/proc/complain_about_virus(shuttle, atom/movable/thing, datum/economy/cargo_shuttle_manifest/manifest) + sell_virus(shuttle, thing, manifest, TRUE) + /datum/virology_goal/proc/get_report() return "Complete this goal." -/datum/virology_goal/proc/check_completion(list/reagent_list) +/datum/virology_goal/proc/check_viruses(list/reagent_list) check_total_virology_goals_completion() return TRUE @@ -45,12 +97,13 @@ GLOBAL_LIST_EMPTY(archived_virology_goals) /datum/virology_goal/property_symptom name = "Symptom With Properties Viral Sample Request" - var/goal_symptom //Type path of the symptom + var/datum/symptom/goal_symptom //Type path of the symptom var/goal_symptom_name var/goal_property var/goal_property_value /datum/virology_goal/property_symptom/New() + register() var/times_looped = 0 //The chance for this to make a infinite loop that lags the server is astronomically small but its still a chance do var/type = pick(subtypesof(/datum/symptom)) @@ -87,7 +140,7 @@ GLOBAL_LIST_EMPTY(archived_virology_goals) return_text += "Viral samples with a specific symptom and properties are required to study the effects of this symptom in various conditions. We need you to deliver [delivery_goal]u of viral samples containing the [goal_symptom_name] symptom and with the [goal_property] property at level [goal_property_value] along with 3 other symptoms to us through the cargo shuttle." return return_text -/datum/virology_goal/property_symptom/check_completion(list/datum/reagent/reagent_list) +/datum/virology_goal/property_symptom/check_viruses(list/datum/reagent/reagent_list, datum/economy/cargo_shuttle_manifest/manifest, simulate = TRUE, complain = FALSE) . = FALSE var/datum/reagent/blood/BL = locate() in reagent_list if(!BL) @@ -95,27 +148,54 @@ GLOBAL_LIST_EMPTY(archived_virology_goals) if(!BL.data || !BL.data["viruses"]) return for(var/datum/disease/advance/D in BL.data["viruses"]) - if(length(D.symptoms) < 4) //We want 3 other symptoms alongside the requested one + //We want 3 other symptoms alongside the requested one + var/required_symptoms = 4 + if(length(D.symptoms) < required_symptoms) + if(simulate || !manifest || !complain) + continue + var/datum/economy/line_item/item = new + item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_MEDICAL) + item.credits = 0 + item.reason = "Virus [D.name] has too few symptoms for [name] ([length(D.symptoms)] is less than [required_symptoms])." + manifest.line_items += item continue var/properties = D.GenerateProperties() var/property = properties[goal_property] if(property != goal_property_value) + if(simulate || !manifest || !complain) + continue + var/datum/economy/line_item/item = new + item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_MEDICAL) + item.credits = 0 + item.reason = "Virus [D.name] has the wrong [goal_property] for [name] ([property] is not [goal_property_value])." + manifest.line_items += item continue - var/found_goal_symptom = FALSE for(var/datum/symptom/S in D.symptoms) if(!goal_symptom) return if(S.type != goal_symptom) continue - found_goal_symptom = TRUE - break - if(!found_goal_symptom) - return - delivered_amount += BL.volume - if(delivered_amount >= delivery_goal) - completed = TRUE - check_total_virology_goals_completion() - return TRUE + if(simulate) + return TRUE + if(manifest) + var/datum/economy/line_item/item = new + item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_MEDICAL) + item.credits = 0 + item.zero_is_good = TRUE + item.reason = "Received [BL.volume] units of usable virus [D.name] for [name]." + manifest.line_items += item + delivered_amount += BL.volume + if(delivered_amount >= delivery_goal) + completed = TRUE + check_total_virology_goals_completion() + return TRUE + if(simulate || !manifest || !complain) + continue + var/datum/economy/line_item/item = new + item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_MEDICAL) + item.credits = 0 + item.reason = "Virus [D.name] is missing the required symptom [initial(goal_symptom.name)] for [name]." + manifest.line_items += item /datum/virology_goal/virus name = "Specific Viral Sample Request (Non-Stealth)" @@ -123,6 +203,7 @@ GLOBAL_LIST_EMPTY(archived_virology_goals) var/symptoms_amount = 5 /datum/virology_goal/virus/New() + register() var/times_looped = 0 //The chance for this to make a infinite loop that lags the server is astronomically small but its still a chance do goal_symptoms = list() @@ -165,7 +246,7 @@ GLOBAL_LIST_EMPTY(archived_virology_goals) msg += initial(S.name) return english_list(msg, ", ") -/datum/virology_goal/virus/check_completion(list/datum/reagent/reagent_list) +/datum/virology_goal/virus/check_viruses(list/datum/reagent/reagent_list, datum/economy/cargo_shuttle_manifest/manifest, simulate = TRUE, complain = FALSE) . = FALSE var/datum/reagent/blood/BL = locate() in reagent_list if(!BL) @@ -173,12 +254,35 @@ GLOBAL_LIST_EMPTY(archived_virology_goals) if(!BL.data || !BL.data["viruses"]) return for(var/datum/disease/advance/D in BL.data["viruses"]) - if(length(D.symptoms) != length(goal_symptoms)) //This is here so viruses with extra symptoms dont get approved - return + if(length(D.symptoms) != length(goal_symptoms)) + if(simulate || !manifest || !complain) + continue + var/datum/economy/line_item/item = new + item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_MEDICAL) + item.credits = 0 + item.reason = "Virus [D.name] has the wrong number of symptoms for [name] ([length(D.symptoms)] is not [length(goal_symptoms)])." + manifest.line_items += item + continue for(var/S in goal_symptoms) var/datum/symptom/SY = locate(S) in D.symptoms if(!SY) + if(simulate || !manifest || !complain) + continue + var/datum/economy/line_item/item = new + item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_MEDICAL) + item.credits = 0 + item.reason = "Virus [D.name] is missing symptom [initial(SY.name)] for [name]." + manifest.line_items += item return + if(simulate) + return TRUE + if(manifest) + var/datum/economy/line_item/item = new + item.account = GLOB.station_money_database.get_account_by_department(DEPARTMENT_MEDICAL) + item.credits = 0 + item.zero_is_good = TRUE + item.reason = "Received [BL.volume] units of usable virus [D.name] for [name]." + manifest.line_items += item delivered_amount += BL.volume if(delivered_amount >= delivery_goal) completed = TRUE diff --git a/config/example/config.toml b/config/example/config.toml index 357ef25d2435..27c295868fe1 100644 --- a/config/example/config.toml +++ b/config/example/config.toml @@ -149,7 +149,7 @@ ipc_screens = [ # Enable/disable the database on a whole sql_enabled = false # SQL version. If this is a mismatch, round start will be delayed -sql_version = 532206 +sql_version = 542206 # SQL server address. Can be an IP or DNS name sql_address = "127.0.0.1" # SQL server port diff --git a/icons/_nanomaps/CereStation_nanomap_z1.png b/icons/_nanomaps/CereStation_nanomap_z1.png index 44eb8e20ec02..61e992f4ba58 100644 Binary files a/icons/_nanomaps/CereStation_nanomap_z1.png and b/icons/_nanomaps/CereStation_nanomap_z1.png differ diff --git a/icons/_nanomaps/Delta_nanomap_z1.png b/icons/_nanomaps/Delta_nanomap_z1.png index 5427c5aa32ad..ee38cd41a770 100644 Binary files a/icons/_nanomaps/Delta_nanomap_z1.png and b/icons/_nanomaps/Delta_nanomap_z1.png differ diff --git a/icons/obj/bureaucracy.dmi b/icons/obj/bureaucracy.dmi index 599237fdadfa..30a7fc4f7323 100644 Binary files a/icons/obj/bureaucracy.dmi and b/icons/obj/bureaucracy.dmi differ diff --git a/icons/obj/radio.dmi b/icons/obj/radio.dmi index 8a7c97021f68..af0cf5eb2529 100644 Binary files a/icons/obj/radio.dmi and b/icons/obj/radio.dmi differ diff --git a/modular_ss220/agent_id_tgui/code/agent_id_tgui.dm b/modular_ss220/agent_id_tgui/code/agent_id_tgui.dm index 6f9a00563cc0..e180834b231c 100644 --- a/modular_ss220/agent_id_tgui/code/agent_id_tgui.dm +++ b/modular_ss220/agent_id_tgui/code/agent_id_tgui.dm @@ -245,7 +245,7 @@ if("Security") new_rank = tgui_input_list(registered_human, "What job would you like to be shown on this card (for SecHUDs)?\nChanging occupation will not grant or remove any access levels.", "Agent Card Occupation", GLOB.security_positions) if("Support") - new_rank = tgui_input_list(registered_human, "What job would you like to be shown on this card (for SecHUDs)?\nChanging occupation will not grant or remove any access levels.", "Agent Card Occupation", GLOB.support_positions) + new_rank = tgui_input_list(registered_human, "What job would you like to be shown on this card (for SecHUDs)?\nChanging occupation will not grant or remove any access levels.", "Agent Card Occupation", GLOB.service_positions) if("Command") new_rank = tgui_input_list(registered_human, "What job would you like to be shown on this card (for SecHUDs)?\nChanging occupation will not grant or remove any access levels.", "Agent Card Occupation", GLOB.command_positions) if("Special") @@ -263,7 +263,7 @@ if("Security") new_job = tgui_input_list(registered_human, "What job would you like to put on this card?\nChanging occupation will not grant or remove any access levels.", "Agent Card Occupation", GLOB.security_positions) if("Support") - new_job = tgui_input_list(registered_human, "What job would you like to put on this card?\nChanging occupation will not grant or remove any access levels.", "Agent Card Occupation", GLOB.support_positions) + new_job = tgui_input_list(registered_human, "What job would you like to put on this card?\nChanging occupation will not grant or remove any access levels.", "Agent Card Occupation", GLOB.service_positions) if("Command") new_job = tgui_input_list(registered_human, "What job would you like to put on this card?\nChanging occupation will not grant or remove any access levels.", "Agent Card Occupation", GLOB.command_positions) if("Special") diff --git a/modular_ss220/maps220/_maps220.dme b/modular_ss220/maps220/_maps220.dme index 943f0900f154..ac7fb4ecb282 100644 --- a/modular_ss220/maps220/_maps220.dme +++ b/modular_ss220/maps220/_maps220.dme @@ -5,10 +5,7 @@ #include "code/Areas/gateway.dm" #include "code/RandomRuins/lavaland_ruins.dm" #include "code/RandomRuins/space_ruins.dm" -#include "code/Station/cyberiad.dm" -#include "code/Station/delta.dm" -#include "code/Station/metastation.dm" -#include "code/Station/cerestation.dm" +#include "code/Station/station_datums.dm" #include "code/corpses.dm" #include "code/directions.dm" #include "code/helpers.dm" diff --git a/modular_ss220/maps220/code/Station/cerestation.dm b/modular_ss220/maps220/code/Station/cerestation.dm deleted file mode 100644 index aa86c4387186..000000000000 --- a/modular_ss220/maps220/code/Station/cerestation.dm +++ /dev/null @@ -1,2 +0,0 @@ -/datum/map/cerestation - voteable = FALSE diff --git a/modular_ss220/maps220/code/Station/cyberiad.dm b/modular_ss220/maps220/code/Station/cyberiad.dm deleted file mode 100644 index b9b1042c128e..000000000000 --- a/modular_ss220/maps220/code/Station/cyberiad.dm +++ /dev/null @@ -1,5 +0,0 @@ -/datum/map/cyberiad - fluff_name = "ИСН Кибериада" - technical_name = "Cyberiad220" - map_path = "_maps/map_files220/cyberiad/cyberiad.dmm" - webmap_url = "https://affectedarc07.github.io/SS13WebMap/Paradise/Cyberiad/" diff --git a/modular_ss220/maps220/code/Station/delta.dm b/modular_ss220/maps220/code/Station/delta.dm deleted file mode 100644 index 91930695ae49..000000000000 --- a/modular_ss220/maps220/code/Station/delta.dm +++ /dev/null @@ -1,5 +0,0 @@ -/datum/map/delta - fluff_name = "ИСН Керберос" - technical_name = "Delta220" - map_path = "_maps/map_files220/delta/delta.dmm" - webmap_url = "https://affectedarc07.github.io/SS13WebMap/Paradise/Delta/" diff --git a/modular_ss220/maps220/code/Station/metastation.dm b/modular_ss220/maps220/code/Station/metastation.dm deleted file mode 100644 index 247716c6063f..000000000000 --- a/modular_ss220/maps220/code/Station/metastation.dm +++ /dev/null @@ -1,5 +0,0 @@ -/datum/map/metastation - fluff_name = "ИСН Цереброн" - technical_name = "MetaStation220" - map_path = "_maps/map_files220/MetaStation/MetaStation.dmm" - webmap_url = "https://affectedarc07.github.io/SS13WebMap/Paradise/MetaStation/" diff --git a/modular_ss220/maps220/code/Station/station_datums.dm b/modular_ss220/maps220/code/Station/station_datums.dm new file mode 100644 index 000000000000..a2448ba738d5 --- /dev/null +++ b/modular_ss220/maps220/code/Station/station_datums.dm @@ -0,0 +1,20 @@ +/datum/map/boxstation + fluff_name = "ИСН Кибериада" + technical_name = "Cyberiad220" + map_path = "_maps/map_files220/stations/boxstation.dmm" + webmap_url = "https://discord.com/channels/1097181193939730453/1097543419586428989/1178708893128478873/" + +/datum/map/deltastation + fluff_name = "ИСН Керберос" + technical_name = "Delta220" + map_path = "_maps/map_files220/stations/deltastation.dmm" + webmap_url = "https://discord.com/channels/1097181193939730453/1097543419586428989/1178708969389293648/" + +/datum/map/metastation + fluff_name = "ИСН Цереброн" + technical_name = "MetaStation220" + map_path = "_maps/map_files220/stations/metastation.dmm" + webmap_url = "https://discord.com/channels/1097181193939730453/1097543419586428989/1178709032974950460/" + +/datum/map/cerestation + voteable = FALSE diff --git a/paradise.dme b/paradise.dme index 01bb41c8b695..1e6bae53fb20 100644 --- a/paradise.dme +++ b/paradise.dme @@ -62,6 +62,7 @@ #include "code\__DEFINES\emotes_defines.dm" #include "code\__DEFINES\error_handler_defines.dm" #include "code\__DEFINES\flags.dm" +#include "code\__DEFINES\food_defines.dm" #include "code\__DEFINES\footstep_defines.dm" #include "code\__DEFINES\game_defines.dm" #include "code\__DEFINES\gamemode.dm" @@ -118,11 +119,13 @@ #include "code\__DEFINES\status_effects.dm" #include "code\__DEFINES\subsystems.dm" #include "code\__DEFINES\supermatter_defines.dm" +#include "code\__DEFINES\supply_defines.dm" #include "code\__DEFINES\surgery_defines.dm" #include "code\__DEFINES\text_defines.dm" #include "code\__DEFINES\tg_cooldowns.dm" #include "code\__DEFINES\tgs.dm" #include "code\__DEFINES\tgui_defines.dm" +#include "code\__DEFINES\tickets_defines.dm" #include "code\__DEFINES\tools_defines.dm" #include "code\__DEFINES\turfs.dm" #include "code\__DEFINES\typeids.dm" @@ -557,7 +560,6 @@ #include "code\datums\spells\genetic.dm" #include "code\datums\spells\horsemask.dm" #include "code\datums\spells\infinite_guns.dm" -#include "code\datums\spells\inflict_handler.dm" #include "code\datums\spells\knock.dm" #include "code\datums\spells\lichdom.dm" #include "code\datums\spells\lightning.dm" @@ -576,7 +578,6 @@ #include "code\datums\spells\summon_supermatter.dm" #include "code\datums\spells\summonitem.dm" #include "code\datums\spells\touch_attacks.dm" -#include "code\datums\spells\trigger.dm" #include "code\datums\spells\turf_teleport.dm" #include "code\datums\spells\wizard_spells.dm" #include "code\datums\spells\alien_spells\basetype_alien_spell.dm" @@ -1965,13 +1966,9 @@ #include "code\modules\lighting\lighting_turf.dm" #include "code\modules\mapping\access_helpers.dm" #include "code\modules\mapping\base_map_datum.dm" -#include "code\modules\mapping\cerestation.dm" -#include "code\modules\mapping\cyberiad.dm" -#include "code\modules\mapping\delta.dm" #include "code\modules\mapping\mapping_helpers.dm" #include "code\modules\mapping\merge_conflicts.dm" -#include "code\modules\mapping\metastation.dm" -#include "code\modules\mapping\test_tiny.dm" +#include "code\modules\mapping\station_datums.dm" #include "code\modules\mapping\windoor_access_helpers.dm" #include "code\modules\maptext_alerts\location_blurbs.dm" #include "code\modules\maptext_alerts\text_blurbs.dm" @@ -2720,6 +2717,21 @@ #include "code\modules\station_goals\dna_vault.dm" #include "code\modules\station_goals\shield.dm" #include "code\modules\station_goals\station_goal.dm" +#include "code\modules\station_goals\task_backlog.dm" +#include "code\modules\station_goals\secondary\random_bulk_reagent.dm" +#include "code\modules\station_goals\secondary\secondary_goal.dm" +#include "code\modules\station_goals\secondary\secondary_goal_tracker.dm" +#include "code\modules\station_goals\secondary\variety_reagent.dm" +#include "code\modules\station_goals\secondary\bar\random_bulk_drink.dm" +#include "code\modules\station_goals\secondary\bar\variety_drinks.dm" +#include "code\modules\station_goals\secondary\botany\kudzu_goal.dm" +#include "code\modules\station_goals\secondary\kitchen\random_bulk_condiment.dm" +#include "code\modules\station_goals\secondary\kitchen\random_bulk_food.dm" +#include "code\modules\station_goals\secondary\medical\random_bulk_medicine.dm" +#include "code\modules\station_goals\secondary\medical\variety_medicine.dm" +#include "code\modules\station_goals\secondary\science\random_bulk_chemical.dm" +#include "code\modules\station_goals\secondary\science\random_ripley.dm" +#include "code\modules\station_goals\secondary\science\variety_chemicals.dm" #include "code\modules\supply\supply_console.dm" #include "code\modules\supply\supply_order.dm" #include "code\modules\supply\supply_pack.dm" diff --git a/tgui/packages/tgui/interfaces/RequestConsole.js b/tgui/packages/tgui/interfaces/RequestConsole.js index 2001a7014b79..b1cd113399c8 100644 --- a/tgui/packages/tgui/interfaces/RequestConsole.js +++ b/tgui/packages/tgui/interfaces/RequestConsole.js @@ -30,13 +30,15 @@ export const RequestConsole = (props, context) => { return ; case 10: return ; + case 11: + return ; default: return "WE SHOULDN'T BE HERE!"; } }; return ( - + {pickPage(screen)} @@ -116,6 +118,14 @@ const MainMenu = (props, context) => { icon="box" onClick={() => act('setScreen', { setScreen: 2 })} /> +
Supply Positions