From c8452fa96b3ad762579d029fa40655438fd4b20e Mon Sep 17 00:00:00 2001 From: "vageyenaman@gmail.com" Date: Wed, 23 Nov 2011 02:00:18 +0000 Subject: [PATCH] =?UTF-8?q?=E2=97=A6=20When=20equipping=20corgis=20with=20?= =?UTF-8?q?objects,=20their=20icons=20immediately=20update.=20Fixes=20a=20?= =?UTF-8?q?bit=20of=20visual=20lag.=20=E2=97=A6=20The=20kitchen=20and=20bo?= =?UTF-8?q?oze=20vending=20machines=20have=20some=20changed=20commodity=20?= =?UTF-8?q?values.=20Most=20importantly,=20kitchen=20has=20more=20eating?= =?UTF-8?q?=20utensils=20and=20trays.=20=E2=97=A6=20Changed=20the=20aftera?= =?UTF-8?q?ttack()=20and=20DblClick()=20to=20have=20the=20(location,contro?= =?UTF-8?q?l,params)=20parameters.=20=E2=97=A6=20Added=20a=20new=20radio?= =?UTF-8?q?=20filter,=20"RADIO=5FMAGNETS".=20=E2=97=A6=20Mucked=20around?= =?UTF-8?q?=20with=20/datum/signal.=20Just=20an=20extra=20variable=20and?= =?UTF-8?q?=20another=20comment.=20=E2=97=A6=20Guns'=20afterattack()=20pro?= =?UTF-8?q?c=20now=20carries=20location,control,params.=20=E2=97=A6=20Proj?= =?UTF-8?q?ectiles=20now=20track=20exactly=20where=20the=20player=20clicke?= =?UTF-8?q?d=20on=20a=20tile.=20Pretty=20neat,=20huh=3F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New stuff: ◦ A new machine has been added: magnetic generators. They fit under floor tiles and can create dyanmic magnetic fields by directing ionized proton/electron beams to another tile. ◦ Another machine/computer was added that can control these magnetic generators. These machines come with their own pseudo-scripting engine for directing the magnetic beams magnetic modules create. They're not really complete yet, but they work for the firing range. I plan on expanding on this maybe sometime in the future, creating more applications for magnets elsewhere. ◦ Firing range things have been added, including target stakes and targets (both sprited by Veyveyr). You can mount targets onto target stakes and shoot them. Pixel-precision aiming has been applied to the targets (ONLY THE TARGETS!) so that you can see where you shot it and whatnot. You can literally blow holes through the targets until they collapse on themselves. ◦ Added a small little manual to the firing range on how to use the new stuff. It hopefully isn't too complicated to use. git-svn-id: http://tgstation13.googlecode.com/svn/trunk@2543 316c924e-a436-60f5-8080-3fe189b3f50e --- code/defines/mob/simple_animal/corgi.dm | 2 + code/defines/obj/vending.dm | 4 +- code/game/atom_procs.dm | 10 +- code/game/communications.dm | 6 +- code/game/machinery/magnet.dm | 417 + code/game/objects/shooting_range.dm | 213 + code/modules/projectiles/gun.dm | 10 +- code/modules/projectiles/projectile.dm | 13 +- html/changelog.html | 9 + icons/effects/effects.dmi | Bin 188742 -> 189307 bytes icons/obj/objects.dmi | Bin 82628 -> 82919 bytes maps/tgstation.2.0.8.dmm | 17084 +++++++++++----------- tgstation.dme | 2 + 13 files changed, 9220 insertions(+), 8550 deletions(-) create mode 100644 code/game/machinery/magnet.dm create mode 100644 code/game/objects/shooting_range.dm diff --git a/code/defines/mob/simple_animal/corgi.dm b/code/defines/mob/simple_animal/corgi.dm index 002d98b7ff5..ed5cf705a4e 100644 --- a/code/defines/mob/simple_animal/corgi.dm +++ b/code/defines/mob/simple_animal/corgi.dm @@ -144,6 +144,7 @@ usr.drop_item() item_to_add.loc = src src.inventory_head = item_to_add + update_clothing() if(inventory_head && inventory_head.type == /obj/item/clothing/head/caphat) name = "Captain "+real_name @@ -171,6 +172,7 @@ usr.drop_item() item_to_add.loc = src src.inventory_back = item_to_add + update_clothing() show_inv(usr) else diff --git a/code/defines/obj/vending.dm b/code/defines/obj/vending.dm index ecbc2b3c119..b04f770a0ad 100644 --- a/code/defines/obj/vending.dm +++ b/code/defines/obj/vending.dm @@ -40,7 +40,7 @@ desc = "A technological marvel, supposedly able to mix just the mixture you'd like to drink the moment you ask for one." icon_state = "boozeomat" //////////////18 drink entities below, plus the glasses, in case someone wants to edit the number of bottles product_paths = "/obj/item/weapon/reagent_containers/food/drinks/bottle/gin;/obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey;/obj/item/weapon/reagent_containers/food/drinks/bottle/tequilla;/obj/item/weapon/reagent_containers/food/drinks/bottle/vodka;/obj/item/weapon/reagent_containers/food/drinks/bottle/vermouth;/obj/item/weapon/reagent_containers/food/drinks/bottle/rum;/obj/item/weapon/reagent_containers/food/drinks/bottle/wine;/obj/item/weapon/reagent_containers/food/drinks/bottle/cognac;/obj/item/weapon/reagent_containers/food/drinks/bottle/kahlua;/obj/item/weapon/reagent_containers/food/drinks/beer;/obj/item/weapon/reagent_containers/food/drinks/ale;/obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice;/obj/item/weapon/reagent_containers/food/drinks/bottle/tomatojuice;/obj/item/weapon/reagent_containers/food/drinks/bottle/limejuice;/obj/item/weapon/reagent_containers/food/drinks/bottle/cream;/obj/item/weapon/reagent_containers/food/drinks/tonic;/obj/item/weapon/reagent_containers/food/drinks/cola;/obj/item/weapon/reagent_containers/food/drinks/sodawater;/obj/item/weapon/reagent_containers/food/drinks/drinkingglass;/obj/item/weapon/reagent_containers/food/drinks/ice" - product_amounts = "5;5;5;5;5;5;5;5;5;6;6;4;4;4;4;8;8;8;30;" + product_amounts = "5;5;5;5;5;5;5;5;5;6;6;4;4;4;4;8;8;15;30;" vend_delay = 15 product_hidden = "/obj/item/weapon/reagent_containers/food/drinks/tea" product_hideamt = "10" @@ -181,7 +181,7 @@ desc = "A kitchen and restaurant equipment vendor" icon_state = "dinnerware" product_paths = "/obj/item/weapon/tray;/obj/item/weapon/kitchen/utensil/fork;/obj/item/weapon/kitchenknife;/obj/item/weapon/reagent_containers/food/drinks/drinkingglass;/obj/item/clothing/suit/chef/classic" - product_amounts = "6;4;2;15;2" + product_amounts = "8;6;3;8;2" //product_amounts = "8;5;4" Old totals product_hidden = "/obj/item/weapon/kitchen/utensil/spoon;/obj/item/weapon/kitchen/utensil/knife;/obj/item/weapon/kitchen/rollingpin;/obj/item/weapon/butch" product_hideamt = "2;2;2;2" diff --git a/code/game/atom_procs.dm b/code/game/atom_procs.dm index b052f56c7fe..94c1ca940ca 100644 --- a/code/game/atom_procs.dm +++ b/code/game/atom_procs.dm @@ -238,12 +238,14 @@ return if(using_new_click_proc) //TODO ERRORAGE (see message below) return DblClickNew() - return DblClick() + return DblClick(location, control, params) var/using_new_click_proc = 0 //TODO ERRORAGE (This is temporary, while the DblClickNew() proc is being tested) /atom/proc/DblClickNew() +// TODO DOOHL: Intergrate params to new proc. Saved for another time because var/valid_place is a fucking brainfuck + //Spamclick server-overloading prevention delay... THING if (world.time <= usr:lastDblClick+1) return @@ -530,7 +532,7 @@ var/using_new_click_proc = 0 //TODO ERRORAGE (This is temporary, while the DblCl if ( !animal.restrained() ) attack_animal(animal) -/atom/DblClick() //TODO: DEFERRED: REWRITE +/atom/DblClick(location, control, params) //TODO: DEFERRED: REWRITE // world << "checking if this shit gets called at all" @@ -732,7 +734,7 @@ var/using_new_click_proc = 0 //TODO ERRORAGE (This is temporary, while the DblCl if (t5) src.attackby(W, usr) if (W) - W.afterattack(src, usr, (t5 ? 1 : 0)) + W.afterattack(src, usr, (t5 ? 1 : 0), params) else // ------- YOU DO NOT HAVE AN ITEM IN YOUR HAND ------- @@ -782,7 +784,7 @@ var/using_new_click_proc = 0 //TODO ERRORAGE (This is temporary, while the DblCl // ------- IT SHOULD NEVER GET TO HERE, DUE TO THE ISTYPE(SRC, /OBJ/SCREEN) FROM PREVIOUS IF-S - I TESTED IT WITH A DEBUG OUTPUT AND I COULDN'T GET THIST TO SHOW UP. ------- src.attackby(W, usr) if (W) - W.afterattack(src, usr) + W.afterattack(src, usr,, params) else // ------- YOU ARE NOT RESTRAINED, AND ARE CLICKING A HUD OBJECT ------- if (istype(usr, /mob/living/carbon/human)) diff --git a/code/game/communications.dm b/code/game/communications.dm index 69ea74a527c..0608c47f703 100644 --- a/code/game/communications.dm +++ b/code/game/communications.dm @@ -91,7 +91,7 @@ On the map: 1443 for atmospherics - distribution loop/mixed air tank 1445 for bot nav beacons 1447 for mulebot, secbot and ed209 control -1449 for airlock controls, electropack +1449 for airlock controls, electropack, magnets 1451 for toxin lab access 1453 for engineering access 1455 for AI access @@ -126,6 +126,7 @@ var/const/RADIO_NAVBEACONS = "5" var/const/RADIO_AIRLOCK = "6" var/const/RADIO_SECBOT = "7" var/const/RADIO_MULEBOT = "8" +var/const/RADIO_MAGNETS = "9" var/global/datum/controller/radio/radio_controller @@ -258,10 +259,13 @@ datum/signal var/transmission_method = 0 //0 = wire //1 = radio transmission + //2 = subspace transmission var/data = list() var/encryption + var/frequency = 0 + proc/copy_from(datum/signal/model) source = model.source transmission_method = model.transmission_method diff --git a/code/game/machinery/magnet.dm b/code/game/machinery/magnet.dm new file mode 100644 index 00000000000..cdc5fe2665e --- /dev/null +++ b/code/game/machinery/magnet.dm @@ -0,0 +1,417 @@ +// Magnetic attractor, creates variable magnetic fields and attraction. +// Can also be used to emit electron/proton beams to create a center of magnetism on another tile + +// tl;dr: it's magnets lol +// This was created for firing ranges, but I suppose this could have other applications - Doohl + +/obj/machinery/magnetic_module + + icon = 'objects.dmi' + icon_state = "floor_magnet-f" + name = "Electromagnetic Generator" + desc = "A device that uses station power to create points of magnetic energy." + level = 1 // underfloor + layer = 2.5 + anchored = 1 + use_power = 1 + idle_power_usage = 50 + + var/freq = 1449 // radio frequency + var/electricity_level = 1 // intensity of the magnetic pull + var/magnetic_field = 1 // the range of magnetic attraction + var/code = 0 // frequency code, they should be different unless you have a group of magnets working together or something + var/turf/center // the center of magnetic attraction + var/on = 0 + var/pulling = 0 + + // x, y modifiers to the center turf; (0, 0) is centered on the magnet, whereas (1, -1) is one tile right, one tile down + var/center_x = 0 + var/center_y = 0 + var/max_dist = 20 // absolute value of center_x,y cannot exceed this integer + + New() + ..() + var/turf/T = loc + hide(T.intact) + center = T + + spawn(10) // must wait for map loading to finish + if(radio_controller) + radio_controller.add_object(src, freq, RADIO_MAGNETS) + + spawn() + magnetic_process() + + // update the invisibility and icon + hide(var/intact) + invisibility = intact ? 101 : 0 + updateicon() + + // update the icon_state + proc/updateicon() + var/state="floor_magnet" + var/onstate="" + if(!on) + onstate="0" + + if(invisibility) + icon_state = "[state][onstate]-f" // if invisible, set icon to faded version + // in case of being revealed by T-scanner + else + icon_state = "[state][onstate]" + + receive_signal(datum/signal/signal) + + var/command = signal.data["command"] + var/modifier = signal.data["modifier"] + var/signal_code = signal.data["code"] + if(command && (signal_code == code)) + + Cmd(command, modifier) + + + + proc/Cmd(var/command, var/modifier) + + if(command) + switch(command) + if("set-electriclevel") + if(modifier) electricity_level = modifier + if("set-magneticfield") + if(modifier) magnetic_field = modifier + + if("add-elec") + electricity_level++ + if(electricity_level > 12) + electricity_level = 12 + if("sub-elec") + electricity_level-- + if(electricity_level <= 0) + electricity_level = 1 + if("add-mag") + magnetic_field++ + if(magnetic_field > 4) + magnetic_field = 4 + if("sub-mag") + magnetic_field-- + if(magnetic_field <= 0) + magnetic_field = 1 + + if("set-x") + if(modifier) center_x = modifier + if("set-y") + if(modifier) center_y = modifier + + if("N") // NORTH + center_y++ + if("S") // SOUTH + center_y-- + if("E") // EAST + center_x++ + if("W") // WEST + center_x-- + if("C") // CENTER + center_x = 0 + center_y = 0 + if("R") // RANDOM + center_x = rand(-max_dist, max_dist) + center_y = rand(-max_dist, max_dist) + + if("set-code") + if(modifier) code = modifier + if("toggle-power") + on = !on + + if(on) + spawn() + magnetic_process() + + + + process() + ..() + if(stat & NOPOWER) + on = 0 + + // Sanity checks: + if(electricity_level <= 0) + electricity_level = 1 + if(magnetic_field <= 0) + magnetic_field = 1 + + + // Limitations: + if(abs(center_x) > max_dist) + center_x = max_dist + if(abs(center_y) > max_dist) + center_y = max_dist + if(magnetic_field > 4) + magnetic_field = 4 + if(electricity_level > 12) + electricity_level = 12 + + // Update power usage: + if(on) + use_power = 2 + active_power_usage = electricity_level*15 + else + use_power = 0 + + + // Overload conditions: + /* // Eeeehhh kinda stupid + if(on) + if(electricity_level > 11) + if(prob(electricity_level)) + explosion(loc, 0, 1, 2, 3) // ooo dat shit EXPLODES son + spawn(2) + del(src) + */ + + updateicon() + + + proc/magnetic_process() // proc that actually does the pulling + if(pulling) return + while(on) + + pulling = 1 + center = locate(x+center_x, y+center_y, z) + if(center) + for(var/obj/M in orange(magnetic_field, center)) + if(!M.anchored && (M.flags & CONDUCT)) + step_towards(M, center) + + for(var/mob/living/silicon/S in orange(magnetic_field, center)) + if(istype(S, /mob/living/silicon/ai)) continue + step_towards(S, center) + + use_power(electricity_level * 5) + sleep(13 - electricity_level) + + pulling = 0 + + + + +/obj/machinery/magnetic_controller + name = "Magnetic Control Console" + icon = 'airlock_machines.dmi' // uses an airlock machine icon, THINK GREEN HELP THE ENVIRONMENT - RECYCLING! + icon_state = "airlock_control_standby" + density = 1 + anchored = 1.0 + use_power = 1 + idle_power_usage = 45 + var/frequency = 1449 + var/code = 0 + var/list/magnets = list() + var/title = "Magnetic Control Console" + var/autolink = 0 // if set to 1, can't probe for other magnets! + + var/pathpos = 1 // position in the path + var/path = "NULL" // text path of the magnet + var/speed = 1 // lowest = 1, highest = 10 + var/list/rpath = list() // real path of the magnet, used in iterator + + var/moving = 0 // 1 if scheduled to loop + var/looping = 0 // 1 if looping + + var/datum/radio_frequency/radio_connection + + + New() + ..() + + if(autolink) + for(var/obj/machinery/magnetic_module/M in world) + if(M.freq == frequency && code == code) + magnets.Add(M) + + + spawn(15) // must wait for map loading to finish + if(radio_controller) + world << "test" + radio_connection = radio_controller.add_object(src, frequency, RADIO_MAGNETS) + + if(!radio_connection) + world << "oh no!" + + + attack_ai(mob/user as mob) + return src.attack_hand(user) + + attack_hand(mob/user as mob) + if(stat & (BROKEN|NOPOWER)) + return + user.machine = src + var/dat = "Magnetic Control Console

" + if(!autolink) + dat += {" + Frequency: [frequency]
+ Code: [code]
+ Probe Generators
+ "} + + if(magnets.len >= 1) + + dat += "Magnets confirmed:
" + var/i = 0 + for(var/obj/machinery/magnetic_module/M in magnets) + i++ + dat += "     < \[[i]\] ([M.on ? "On":"Off"]) | Electricity level: - [M.electricity_level] +; Magnetic field: - [M.magnetic_field] +
" + + dat += "
Speed: - [speed] +
" + dat += "Path: {[path]}
" + dat += "Moving: [moving ? "Enabled":"Disabled"]" + + + user << browse(dat, "window=magnet;size=400x500") + onclose(user, "magnet") + + Topic(href, href_list) + if(stat & (BROKEN|NOPOWER)) + return + usr.machine = src + src.add_fingerprint(usr) + + if(href_list["radio-op"]) + + // Prepare signal beforehand, because this is a radio operation + var/datum/signal/signal = new + signal.transmission_method = 1 // radio transmission + signal.source = src + signal.frequency = frequency + signal.data["code"] = code + + // Apply any necessary commands + switch(href_list["radio-op"]) + if("togglepower") + signal.data["command"] = "toggle-power" + + if("minuselec") + signal.data["command"] = "sub-elec" + if("pluselec") + signal.data["command"] = "add-elec" + + if("minusmag") + signal.data["command"] = "sub-mag" + if("plusmag") + signal.data["command"] = "add-mag" + + + // Broadcast the signal + + radio_connection.post_signal(src, signal, filter = RADIO_MAGNETS) + + spawn(1) + updateUsrDialog() // pretty sure this increases responsiveness + + if(href_list["operation"]) + switch(href_list["operation"]) + if("plusspeed") + speed ++ + if(speed > 10) + speed = 10 + if("minusspeed") + speed -- + if(speed <= 0) + speed = 1 + if("setpath") + var/newpath = input(usr, "Please define a new path!",,path) as text|null + if(newpath && newpath != "") + moving = 0 // stop moving + path = newpath + pathpos = 1 // reset position + filter_path() // renders rpath + + if("togglemoving") + moving = !moving + if(moving) + spawn() MagnetMove() + + + updateUsrDialog() + + proc/MagnetMove() + if(looping) return + + while(moving && rpath.len >= 1) + + if(stat & (BROKEN|NOPOWER)) + break + + looping = 1 + + // Prepare the radio signal + var/datum/signal/signal = new + signal.transmission_method = 1 // radio transmission + signal.source = src + signal.frequency = frequency + signal.data["code"] = code + + if(pathpos > rpath.len) // if the position is greater than the length, we just loop through the list! + pathpos = 1 + + var/nextmove = uppertext(rpath[pathpos]) // makes it un-case-sensitive + + if(!(nextmove in list("N","S","E","W","C","R"))) + // N, S, E, W are directional + // C is center + // R is random (in magnetic field's bounds) + del(signal) + break // break the loop if the character located is invalid + + signal.data["command"] = nextmove + + + pathpos++ // increase iterator + + // Broadcast the signal + spawn() + radio_connection.post_signal(src, signal, filter = RADIO_MAGNETS) + + if(speed == 10) + sleep(1) + else + sleep(12-speed) + + looping = 0 + + + proc/filter_path() + // Generates the rpath variable using the path string, think of this as "string2list" + // Doesn't use params2list() because of the akward way it stacks entities + rpath = list() // clear rpath + var/maximum_character = min( 50, length(path) ) // chooses the maximum length of the iterator. 50 max length + + for(var/i=1, i<=maximum_character, i++) // iterates through all characters in path + + var/nextchar = copytext(path, i, i+1) // find next character + + if(!(nextchar in list(";", "&", "*", " "))) // if char is a separator, ignore + rpath += copytext(path, i, i+1) // else, add to list + + // there doesn't HAVE to be separators but it makes paths syntatically visible + + + + + + + + + + + + + + + + + + + + + + + diff --git a/code/game/objects/shooting_range.dm b/code/game/objects/shooting_range.dm new file mode 100644 index 00000000000..d003c749372 --- /dev/null +++ b/code/game/objects/shooting_range.dm @@ -0,0 +1,213 @@ + +// TARGET STAKE +// TARGET +// Basically they are for the firing range +/obj/structure/target_stake + name = "target stake" + desc = "A thin platform with negatively-magnetized wheels." + icon = 'objects.dmi' + icon_state = "target_stake" + density = 1 + flags = CONDUCT + var/obj/item/target/pinned_target // the current pinned target + + Move() + ..() + // Move the pinned target along with the stake + if(pinned_target in view(3, src)) + pinned_target.loc = loc + + else // Sanity check: if the pinned target can't be found in immediate view + pinned_target = null + density = 1 + + attackby(obj/item/W as obj, mob/user as mob) + // Putting objects on the stake. Most importantly, targets + if(pinned_target) + return // get rid of that pinned target first! + + if(istype(W, /obj/item/target)) + density = 0 + W.density = 1 + W.layer = 3.1 + pinned_target = W + user << "You slide the target into the stake." + + user.drop_item(src) + W.loc = loc + return + + attack_hand(mob/user as mob) + // taking pinned targets off! + if(pinned_target) + density = 1 + pinned_target.density = 0 + pinned_target.layer = OBJ_LAYER + + pinned_target.loc = user.loc + if(ishuman(user)) + if(!user.get_active_hand()) + user.put_in_hand(pinned_target) + user << "You take the target out of the stake." + else + pinned_target.loc = get_turf_loc(user) + user << "You take the target out of the stake." + + pinned_target = null + + + +// Targets, the things that actually get shot! +/obj/item/target + name = "shooting target" + desc = "A shooting target." + icon = 'objects.dmi' + icon_state = "target_h" + density = 0 + var/hp = 1800 + var/icon/virtualIcon + + Del() + // if a target is deleted and associated with a stake, force stake to forget + for(var/obj/structure/target_stake/T in view(3,src)) + if(T.pinned_target == src) + T.pinned_target = null + T.density = 1 + break + ..() // delete target + + Move() + ..() + // After target moves, check for nearby stakes. If associated, move to target + for(var/obj/structure/target_stake/M in view(3,src)) + if(M.density == 0 && M.pinned_target == src) + M.loc = loc + + // This may seem a little counter-intuitive but I assure you that's for a purpose. + // Stakes are the ones that carry targets, yes, but in the stake code we set + // a stake's density to 0 meaning it can't be pushed anymore. Instead of pushing + // the stake now, we have to push the target. + + + + attackby(obj/item/W as obj, mob/user as mob) + if (istype(W, /obj/item/weapon/weldingtool)) + if(W:welding == 1) + overlays = null + usr << "You slice off [src]'s uneven chunks of aluminum and scorch marks." + return + + + attack_hand(mob/user as mob) + // taking pinned targets off! + var/obj/structure/target_stake/stake + for(var/obj/structure/target_stake/T in view(3,src)) + if(T.pinned_target == src) + stake = T + break + + if(stake) + if(stake.pinned_target) + stake.density = 1 + density = 0 + layer = OBJ_LAYER + + loc = user.loc + if(ishuman(user)) + if(!user.get_active_hand()) + user.put_in_hand(src) + user << "You take the target out of the stake." + else + src.loc = get_turf_loc(user) + user << "You take the target out of the stake." + + stake.pinned_target = null + return + + else + ..() + + syndicate + icon_state = "target_s" + desc = "A shooting target that looks like a syndicate scum." + hp = 2000 // i guess syndie targets are sturdier? + alien + icon_state = "target_q" + desc = "A shooting target that looks like a xenomorphic alien." + hp = 2450 // alium ones too + +/obj/item/target/bullet_act(var/obj/item/projectile/Proj) + var/p_x = Proj.p_x + pick(0,0,0,0,0,-1,1) // really ugly way of coding "sometimes offset Proj.p_x!" + var/p_y = Proj.p_y + pick(0,0,0,0,0,-1,1) + var/decaltype = 1 // 1 - scorch, 2 - bullet + + if(istype(/obj/item/projectile/bullet, Proj)) + decaltype = 2 + + + if(!virtualIcon) + virtualIcon = new(icon, icon_state) // if can't locate virtualIcon, make one! + + if( virtualIcon.GetPixel(p_x, p_y) ) // if the located pixel isn't blank (null) + + hp -= Proj.damage + if(hp <= 0) + for(var/mob/O in oviewers()) + if ((O.client && !( O.blinded ))) + O << "\red [src] breaks into tiny pieces and collapses!" + del(src) + + // Create a temporary object to represent the damage + var/obj/bmark = new + bmark.pixel_x = p_x + bmark.pixel_y = p_y + bmark.icon = 'effects.dmi' + bmark.layer = 3.5 + bmark.icon_state = "scorch" + + if(decaltype == 1) + // Energy weapons are hot. they scorch! + + // offset correction + bmark.pixel_x-- + bmark.pixel_y-- + + if(Proj.damage >= 20) + bmark.icon_state = "scorch" + bmark.dir = pick(NORTH,SOUTH,EAST,WEST) // random scorch design + + + else + bmark.icon_state = "light_scorch" + else + + // Bullets are hard. They make dents! + bmark.icon_state = "dent" + + var/bullethole = 0 // 1 if makes bullet hole + + if(Proj.damage >= 10) + if(decaltype == 2) // bullet + if(prob(Proj.damage+30)) // bullets make holes more commonly! + bullethole = 1 + else // Lasers! + if(prob(Proj.damage-10)) // lasers make holes less commonly + bullethole = 1 + + if(bullethole) // draw a simple bullet hole circle thing, not horrendously fancy but it does the job + + virtualIcon.DrawBox(null, bmark.pixel_x-pick(1,1,1,1,1,1,2,3,4), bmark.pixel_y, bmark.pixel_x+pick(1,1,1,1,1,1,2,3,4), bmark.pixel_y) // horizontal line + virtualIcon.DrawBox(null, bmark.pixel_x, bmark.pixel_y+pick(1,1,1,1,1,1,2,3,4), bmark.pixel_x, bmark.pixel_y-pick(1,1,1,1,1,1,2,3,4)) // vertical line + icon = virtualIcon // apply changes + + + + overlays += bmark // add the decal + + return + + return -1 // the bullet/projectile goes through the target! Ie, you missed + + + + diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 326fbeb6166..d94535ec178 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -38,7 +38,7 @@ O.emp_act(severity) - afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag)//TODO: go over this + afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag, params)//TODO: go over this if(flag) return //we're placing gun on a table or in backpack if(istype(target, /obj/machinery/recharger) && istype(src, /obj/item/weapon/gun/energy)) return//Shouldnt flag take care of this? @@ -95,6 +95,14 @@ in_chamber.current = curloc in_chamber.yo = targloc.y - curloc.y in_chamber.xo = targloc.x - curloc.x + + if(params) + var/list/mouse_control = params2list(params) + if(mouse_control["icon-x"]) + in_chamber.p_x = text2num(mouse_control["icon-x"]) + if(mouse_control["icon-y"]) + in_chamber.p_y = text2num(mouse_control["icon-y"]) + spawn() if(in_chamber) in_chamber.process() sleep(1) diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index d952cadeb0c..f23faf6abbe 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -29,6 +29,9 @@ current = null turf/original = null + p_x = 16 + p_y = 16 // the pixel location of the tile that the player clicked. Default is the center + damage = 10 damage_type = BRUTE //BRUTE, BURN, TOX, OXY, CLONE are the only things that should be in here nodamage = 0 //Determines if the projectile will skip any damage inflictions @@ -78,7 +81,15 @@ spawn(0) if(A) - A.bullet_act(src, def_zone) + var/permutation = A.bullet_act(src, def_zone) // searches for return value + if(permutation == -1) // the bullet passes through a dense object! + bumped = 0 // reset bumped variable! + if(istype(A, /turf)) + loc = A + else + loc = A.loc + return + if(istype(A,/turf)) for(var/obj/O in A) O.bullet_act(src) diff --git a/html/changelog.html b/html/changelog.html index b37a1ea4882..5e182e8bfca 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -54,6 +54,15 @@ Stuff which is in development and not yet visible to players or just code relate (ie. code improvements for expandability, etc.) should not be listed here. They should be listed in the changelog upon commit tho. Thanks. --> + +22 November 2011 +