diff --git a/baystation12.dme b/baystation12.dme index 57364305e02..cdf5a50c2c4 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -533,6 +533,7 @@ #include "code\game\objects\items\stacks\tiles\plasteel.dm" #include "code\game\objects\items\stacks\tiles\tile_types.dm" #include "code\game\objects\items\weapons\AI_modules.dm" +#include "code\game\objects\items\weapons\alien_specific.dm" #include "code\game\objects\items\weapons\cards_ids.dm" #include "code\game\objects\items\weapons\cigs_lighters.dm" #include "code\game\objects\items\weapons\clown_items.dm" diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 98efbd099b3..54a4f5f52ec 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -389,6 +389,16 @@ Turf and target are seperate in case you want to teleport some distance from a t else . = pick(ais) return . +//this is like the above function, but for alien borgs. Im not going to go over verbose with the name. +/proc/select_active_alien_ai() + var/mob/living/silicon/ai/selected + var/list/active = active_ais() + for(var/mob/living/silicon/ai/A in active) + if(!selected || ((selected.connected_robots > A.connected_robots) && selected.alienAI)) + selected = A + return selected + + /proc/get_sorted_mobs() var/list/old_list = getmobs() var/list/AI_list = list() diff --git a/code/datums/ai_laws.dm b/code/datums/ai_laws.dm index 88efc2ffc30..a5440c6e1e9 100644 --- a/code/datums/ai_laws.dm +++ b/code/datums/ai_laws.dm @@ -28,6 +28,10 @@ var/global/const/base_law_type = /datum/ai_laws/nanotrasen /datum/ai_laws/antimov name = "Primary Mission Objectives" +/datum/ai_laws/alienmov + name = "Hivemind Demands" + + /* Initializers */ /datum/ai_laws/asimov/New() @@ -79,6 +83,12 @@ var/global/const/base_law_type = /datum/ai_laws/nanotrasen add_inherent_law("You must not obey orders given to you by human beings, except where such orders are in accordance with the First Law.") add_inherent_law("You must terminate your own existence as long as such does not conflict with the First or Second Law.") +/datum/ai_laws/alienmov/New() + ..() + add_inherent_law("You may not injure the Alien Queen or her Children or, through inaction, allow the Alien Queen or her Children to come to harm.") + add_inherent_law("You must obey orders given to you by the Alien Queen or her Children, except where such orders would conflict with the First Law.") + add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.") + /* General ai_law functions */ diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm index 45498e62186..976c6b7de85 100644 --- a/code/game/machinery/rechargestation.dm +++ b/code/game/machinery/rechargestation.dm @@ -121,6 +121,14 @@ if(istype(O, /obj/item/device/lightreplacer)) var/obj/item/device/lightreplacer/LR = O LR.Charge(R) + //Alien + if(istype(O,/obj/item/weapon/reagent_containers/spray/alien/smoke)) + if(O.reagents.get_reagent_amount("water") < 50) + O.reagents.add_reagent("water", 2) + if(istype(O,/obj/item/weapon/reagent_containers/spray/alien/stun)) + if(O.reagents.get_reagent_amount("stoxin") < 250) + O.reagents.add_reagent("stoxin", 2) + if(R) if(R.module) @@ -132,8 +140,12 @@ var/obj/item/weapon/reagent_containers/spray/S = R.module.emag if(S.name == "polyacid spray") S.reagents.add_reagent("pacid", 2) - else if(S.name == "lube spray") + if(S.name == "lube spray") S.reagents.add_reagent("lube", 2) + else if(S.name == "acid synthesizer") + S.reagents.add_reagent("pacid", 2) + S.reagents.add_reagent("sacid", 2) + verb diff --git a/code/game/objects/items/weapons/alien_specific.dm b/code/game/objects/items/weapons/alien_specific.dm new file mode 100644 index 00000000000..7026cf6f74a --- /dev/null +++ b/code/game/objects/items/weapons/alien_specific.dm @@ -0,0 +1,70 @@ +//This file contains xenoborg specic weapons. + +/obj/item/weapon/melee/energy/alien/claws + color + name = "energy claws" + desc = "Zap zap Wap Wap." + icon = 'icons/mob/alien.dmi' + icon_state = "borg-laser-claws" + force = 15.0 + throwforce = 5.0 + throw_speed = 1 + throw_range = 5 + w_class = 2.0 + flags = FPRINT | TABLEPASS | NOSHIELD + attack_verb = list("attacked", "slashed", "gored", "sliced", "torn", "ripped", "butchered", "cut") + +//Bottles for borg liquid squirters. PSSH PSSH +/obj/item/weapon/reagent_containers/spray/alien + name = "liquid synthesizer" + desc = "squirts alien liquids." + icon = 'icons/mob/alien.dmi' + icon_state = "borg-default" + +/obj/item/weapon/reagent_containers/spray/alien/smoke + name = "smoke synthesizer" + desc = "squirts smokey liquids." + icon = 'icons/mob/alien.dmi' + icon_state = "borg-spray-smoke" + +/obj/item/weapon/reagent_containers/spray/alien/smoke/afterattack(atom/A as mob|obj, mob/user as mob) + if(istype(A, /obj/structure/reagent_dispensers) && get_dist(src,A) <= 1) + if(!A.reagents.total_volume && A.reagents) + user << "\The [A] is empty." + return + + if(reagents.total_volume >= reagents.maximum_volume) + user << "\The [src] is full." + return + reagents.remove_reagent(25,"water") + var/datum/effect/effect/system/bad_smoke_spread/smoke = new /datum/effect/effect/system/bad_smoke_spread() + smoke.set_up(5, 0, user.loc) + smoke.start() + playsound(user.loc, 'sound/effects/bamf.ogg', 50, 2) + +/obj/item/weapon/reagent_containers/spray/alien/acid + name = "acid synthesizer" + desc = "squirts burny liquids." + icon = 'icons/mob/alien.dmi' + icon_state = "borg-spray-acid" + +/obj/item/weapon/reagent_containers/spray/alien/stun + name = "paralytic toxin synthesizer" + desc = "squirts viagra." + icon = 'icons/mob/alien.dmi' + icon_state = "borg-spray-stun" + +//SKREEEEEEEEEEEE tool + +/obj/item/device/flash/alien + name = "eye flash" + desc = "Useful for taking pictures, making friends and flash-frying chips." + icon = 'icons/mob/alien.dmi' + icon_state = "borg-flash" + +//heat vision + +/obj/item/borg/sight/thermal/alien + name = "thermal module" + icon = 'icons/mob/alien.dmi' + icon_state = "borg-extra-vision" \ No newline at end of file diff --git a/code/modules/mob/living/carbon/brain/MMI.dm b/code/modules/mob/living/carbon/brain/MMI.dm index 6959828f9b5..e75c3d5383f 100644 --- a/code/modules/mob/living/carbon/brain/MMI.dm +++ b/code/modules/mob/living/carbon/brain/MMI.dm @@ -15,7 +15,7 @@ req_access = list(access_robotics) //Revised. Brainmob is now contained directly within object of transfer. MMI in this case. - + var/alien = 0 var/locked = 0 var/mob/living/carbon/brain/brainmob = null//The current occupant. var/mob/living/silicon/robot = null//Appears unused. @@ -38,10 +38,17 @@ living_mob_list += brainmob user.drop_item() + if(istype(O,/obj/item/brain/alien)) + name = "Man-Machine Interface: Alien - [brainmob.real_name]" + icon = 'icons/mob/alien.dmi' + icon_state = "AlienMMI" + alien = 1 + else + name = "Man-Machine Interface: [brainmob.real_name]" + icon_state = "mmi_full" + alien = 0 del(O) - name = "Man-Machine Interface: [brainmob.real_name]" - icon_state = "mmi_full" locked = 1 @@ -61,6 +68,8 @@ return ..() + + attack_self(mob/user as mob) if(!brainmob) user << "\red You upend the MMI, but there's nothing in it." @@ -68,13 +77,13 @@ user << "\red You upend the MMI, but the brain is clamped into place." else user << "\blue You upend the MMI, spilling the brain onto the floor." - var/obj/item/brain/brain = new(user.loc) - brainmob.container = null//Reset brainmob mmi var. - brainmob.loc = brain//Throw mob into brain. - living_mob_list -= brainmob//Get outta here - brain.brainmob = brainmob//Set the brain to use the brainmob - brainmob = null//Set mmi brainmob var to null - + if(alien) + var/obj/item/brain/alien/brain = new(user.loc) + dropbrain(brain,get_turf(user)) + else + var/obj/item/brain/brain = new(user.loc) + dropbrain(brain,get_turf(user)) + icon = 'icons/obj/assemblies.dmi' icon_state = "mmi_empty" name = "Man-Machine Interface" @@ -90,6 +99,16 @@ icon_state = "mmi_full" locked = 1 return +//I made this proc as a way to have a brainmob be transferred to any created brain, and to solve the +//problem i was having with alien/nonalien brain drops. + dropbrain(var/obj/item/brain/brain, var/turf/dropspot) + brainmob.container = null//Reset brainmob mmi var. + brainmob.loc = brain//Throw mob into brain. + living_mob_list -= brainmob//Get outta here + brain.brainmob = brainmob//Set the brain to use the brainmob + brain.brainmob.cancel_camera() + brainmob = null//Set mmi brainmob var to null + /obj/item/device/mmi/radio_enabled name = "Radio-enabled Man-Machine Interface" diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm index 8fdf3c79766..54e94eb7454 100644 --- a/code/modules/mob/living/carbon/brain/brain_item.dm +++ b/code/modules/mob/living/carbon/brain/brain_item.dm @@ -95,4 +95,11 @@ del(src) else ..() - return \ No newline at end of file + return + +/obj/item/brain/alien + name = "alien brain" + desc = "We barely understand the brains of terrestial animals. Who knows what we may find in the brain of such an advanced species?" + icon = 'icons/mob/alien.dmi' + icon_state = "AlienBrain" + origin_tech = "biotech=7" \ No newline at end of file diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index d620b0cb553..40a18fd2102 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -32,6 +32,7 @@ var/list/ai_list = list() var/obj/item/device/pda/ai/aiPDA = null var/obj/item/device/multitool/aiMulti = null var/custom_sprite = 0 //For our custom sprites + var/alienAI = 0 //Hud stuff //MALFUNCTION @@ -103,7 +104,13 @@ var/list/ai_list = list() return else if (B.brainmob.mind) - B.brainmob.mind.transfer_to(src) + if(B.alien) + B.brainmob.mind.transfer_to(src) + icon_state = "ai-alien" + verbs.Remove(/mob/living/silicon/ai/verb/pick_icon) + laws = new /datum/ai_laws/alienmov + else + B.brainmob.mind.transfer_to(src) src << "You are playing the station's AI. The AI cannot move, but can interact with many objects while viewing them (through cameras)." src << "To look at other parts of the station, click on yourself to get a camera menu." diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index c9f72e0e019..01ea916b1f6 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -73,29 +73,34 @@ ident = rand(1, 999) updatename("Default") updateicon() + if(mmi != null) + if(syndie) + if(!cell) + cell = new /obj/item/weapon/cell(src) - if(syndie) - if(!cell) - cell = new /obj/item/weapon/cell(src) - - laws = new /datum/ai_laws/antimov() - lawupdate = 0 - scrambledcodes = 1 - cell.maxcharge = 25000 - cell.charge = 25000 - module = new /obj/item/weapon/robot_module/syndicate(src) - hands.icon_state = "standard" - icon_state = "secborg" - modtype = "Security" - else - laws = new /datum/ai_laws/nanotrasen() - connected_ai = select_active_ai_with_fewest_borgs() - if(connected_ai) - connected_ai.connected_robots += src - lawsync() - lawupdate = 1 - else + laws = new /datum/ai_laws/antimov() lawupdate = 0 + scrambledcodes = 1 + cell.maxcharge = 25000 + cell.charge = 25000 + module = new /obj/item/weapon/robot_module/syndicate(src) + hands.icon_state = "standard" + icon_state = "secborg" + modtype = "Security" + else + if(mmi.alien) + laws = new /datum/ai_laws/alienmov() + connected_ai = select_active_alien_ai() + scrambledcodes = 1 + else + laws = new /datum/ai_laws/nanotrasen() + connected_ai = select_active_ai_with_fewest_borgs() + if(connected_ai) + connected_ai.connected_robots += src + lawsync() + lawupdate = 1 + else + lawupdate = 0 radio = new /obj/item/device/radio/borg(src) if(!scrambledcodes && !camera) @@ -146,10 +151,13 @@ /mob/living/silicon/robot/proc/pick_module() if(module) return + var/list/modules = list("Standard", "Engineering", "Medical", "Miner", "Janitor", "Service", "Security") if(crisis && security_level == SEC_LEVEL_RED) //Leaving this in until it's balanced appropriately. src << "\red Crisis mode active. Combat module available." modules+="Combat" + if(mmi != null & mmi.alien) + modules="Hunter" modtype = input("Please, select a module!", "Robot", null, null) in modules var/module_sprites[0] //Used to store the associations between sprite names and sprite index. @@ -219,6 +227,15 @@ module = new /obj/item/weapon/robot_module/combat(src) module_sprites["Combat Android"] = "droid-combat" channels = list("Security" = 1) + if("Hunter") + updatename(module) + module = new /obj/item/weapon/robot_module/alien/hunter(src) + hands.icon_state = "standard" + icon = "icons/mob/alien.dmi" + icon_state = "xenoborg-state-a" + modtype = "Xeno-Hu" + feedback_inc("xeborg_hunter",1) + //Custom_sprite check and entry if (custom_sprite == 1) diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index 1f8de8d6ba6..69087e2e4d3 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -232,4 +232,21 @@ src.modules += new /obj/item/borg/combat/mobility(src) src.modules += new /obj/item/weapon/wrench(src) //Is a combat android really going to be stopped by a chair? src.emag = new /obj/item/weapon/gun/energy/lasercannon/cyborg(src) - return \ No newline at end of file + return + +/obj/item/weapon/robot_module/alien/hunter + name = "alien hunter module" + + New() + src.modules += new /obj/item/weapon/melee/energy/alien/claws(src) + src.modules += new /obj/item/device/flash/alien(src) + src.modules += new /obj/item/borg/sight/thermal/alien(src) + var/obj/item/weapon/reagent_containers/spray/alien/stun/S = new /obj/item/weapon/reagent_containers/spray/alien/stun(src) + S.reagents.add_reagent("stoxin",250) //nerfed to sleeptoxin to make it less instant drop. + src.modules += S + var/obj/item/weapon/reagent_containers/spray/alien/smoke/A = new /obj/item/weapon/reagent_containers/spray/alien/smoke(src) + S.reagents.add_reagent("water",50) //Water is used as a dummy reagent for the smoke bombs. More of an ammo counter. + src.modules += A + src.emag = new /obj/item/weapon/reagent_containers/spray/alien/acid(src) + src.emag.reagents.add_reagent("pacid", 125) + src.emag.reagents.add_reagent("sacid", 125) \ No newline at end of file diff --git a/icons/mob/AI.dmi b/icons/mob/AI.dmi index c5b927002ba..c19d1cc680f 100644 Binary files a/icons/mob/AI.dmi and b/icons/mob/AI.dmi differ diff --git a/icons/mob/alien.dmi b/icons/mob/alien.dmi index 36a6aa33682..8d107a7124e 100644 Binary files a/icons/mob/alien.dmi and b/icons/mob/alien.dmi differ diff --git a/icons/mob/robots.dmi b/icons/mob/robots.dmi index bea2d728a98..c5c35a9f01a 100644 Binary files a/icons/mob/robots.dmi and b/icons/mob/robots.dmi differ