From cced767094d277a331b90cc8bcdb4d6d08736c86 Mon Sep 17 00:00:00 2001 From: Tigercat2000 Date: Fri, 29 May 2015 12:19:27 -0700 Subject: [PATCH] Port Atlas's implementation of -tg-'s canvas art. --- code/__HELPERS/icons.dm | 25 ++- .../items/stacks/sheets/sheet_types.dm | 1 + code/game/objects/structures/artstuff.dm | 151 ++++++++++++++++++ code/modules/client/client defines.dm | 4 +- code/modules/mob/mob_movement.dm | 11 ++ .../research/designs/autolathe_designs.dm | 32 ++++ icons/obj/artstuff.dmi | Bin 0 -> 1847 bytes paradise.dme | 1 + 8 files changed, 223 insertions(+), 2 deletions(-) create mode 100644 code/game/objects/structures/artstuff.dm create mode 100644 icons/obj/artstuff.dmi diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index 3466ec36e95..a9a04a4f621 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -699,7 +699,7 @@ proc // Creates a single icon from a given /atom or /image. Only the first argu while(TRUE) if(curIndex<=process.len) current = process[curIndex] - if(!current) + if(!current) curIndex++ //Skip this bad layer item continue currentLayer = current:layer @@ -857,3 +857,26 @@ proc/sort_atoms_by_layer(var/list/atoms) result.Swap(i, gap + i) swapped = 1 return result + +//Interface for using DrawBox() to draw 1 pixel on a coordinate. +//Returns the same icon specifed in the argument, but with the pixel drawn +/proc/DrawPixel(var/icon/I,var/colour,var/drawX,var/drawY) + if(!I) + return 0 + var/Iwidth = I.Width() + var/Iheight = I.Height() + if(drawX > Iwidth || drawX <= 0) + return 0 + if(drawY > Iheight || drawY <= 0) + return 0 + I.DrawBox(colour,drawX, drawY) + return I + +//Interface for easy drawing of one pixel on an atom. +/atom/proc/DrawPixelOn(var/colour, var/drawX, var/drawY) + var/icon/I = new(icon) + var/icon/J = DrawPixel(I, colour, drawX, drawY) + if(J) //Only set the icon if it succeeded, the icon without the pixel is 1000x better than a black square. + icon = J + return J + return 0 \ No newline at end of file diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 30ac106c1b3..3f7190e90e2 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -155,6 +155,7 @@ var/global/list/datum/stack_recipe/wood_recipes = list ( \ new/datum/stack_recipe("wooden door", /obj/structure/mineral_door/wood, 10, time = 20, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("coffin", /obj/structure/closet/coffin, 5, time = 15, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("apiary", /obj/item/apiary, 10, time = 25, one_per_turf = 0, on_floor = 0), \ + new/datum/stack_recipe("easel", /obj/structure/easel, 3, one_per_turf = 1, on_floor = 1), \ ) /obj/item/stack/sheet/wood diff --git a/code/game/objects/structures/artstuff.dm b/code/game/objects/structures/artstuff.dm new file mode 100644 index 00000000000..64f09d7e803 --- /dev/null +++ b/code/game/objects/structures/artstuff.dm @@ -0,0 +1,151 @@ +///////////////// +// NEW DEFINES // +///////////////// + +/client + var/viewingCanvas = 0 //If this is 1, as soon as client /TRIES/ to move the view resets. + +/////////// +// EASEL // +/////////// + +/obj/structure/easel + name = "easel" + desc = "only for the finest of art!" + icon = 'icons/obj/artstuff.dmi' + icon_state = "easel" + density = 1 + var/obj/item/weapon/canvas/painting = null + + +//Adding canvases +/obj/structure/easel/attackby(var/obj/item/I, var/mob/user, params) + if(istype(I, /obj/item/weapon/canvas)) + var/obj/item/weapon/canvas/C = I + user.unEquip(C) + painting = C + C.loc = get_turf(src) + C.layer = layer+0.1 + user.visible_message("[user] puts \the [C] on \the [src].","You place \the [C] on \the [src].") + return + + ..() + + +//Stick to the easel like glue +/obj/structure/easel/Move() + var/turf/T = get_turf(src) + ..() + if(painting && painting.loc == T) //Only move if it's near us. + painting.loc = get_turf(src) + else + painting = null + + +////////////// +// CANVASES // +////////////// + +#define AMT_OF_CANVASES 4 //Keep this up to date or shit will break. + +//To safe memory on making /icons we cache the blanks.. +var/global/list/globalBlankCanvases[AMT_OF_CANVASES] + +/obj/item/weapon/canvas + name = "11px by 11px canvas" + desc = "Draw out your soul on this canvas! Only crayons can draw on it. Examine it to focus on the canvas." + icon = 'icons/obj/artstuff.dmi' + icon_state = "11x11" + var/whichGlobalBackup = 1 //List index + +/obj/item/weapon/canvas/nineteenXnineteen + name = "19px by 19px canvas" + icon_state = "19x19" + whichGlobalBackup = 2 + +/obj/item/weapon/canvas/twentythreeXnineteen + name = "23px by 19px canvas" + icon_state = "23x19" + whichGlobalBackup = 3 + +/obj/item/weapon/canvas/twentythreeXtwentythree + name = "23px by 23px canvas" + icon_state = "23x23" + whichGlobalBackup = 4 + + +//Find the right size blank canvas +/obj/item/weapon/canvas/proc/getGlobalBackup() + . = null + if(globalBlankCanvases[whichGlobalBackup]) + . = globalBlankCanvases[whichGlobalBackup] + else + var/icon/I = icon(initial(icon),initial(icon_state)) + globalBlankCanvases[whichGlobalBackup] = I + . = I + + + +//One pixel increments +/obj/item/weapon/canvas/attackby(var/obj/item/I, var/mob/user, params) + //Click info + var/list/click_params = params2list(params) + var/pixX = text2num(click_params["icon-x"]) + var/pixY = text2num(click_params["icon-y"]) + + //Should always be true, otherwise you didn't click the object, but let's check because SS13~ + if(!click_params || !click_params["icon-x"] || !click_params["icon-y"]) + return + + var/icon/masterpiece = icon(icon,icon_state) + //Cleaning one pixel with a soap or rag + if(istype(I, /obj/item/weapon/soap) || istype(I, /obj/item/weapon/reagent_containers/glass/rag)) + //Pixel info created only when needed + var/thePix = masterpiece.GetPixel(pixX,pixY) + var/icon/Ico = getGlobalBackup() + if(!Ico) + qdel(masterpiece) + return + + var/theOriginalPix = Ico.GetPixel(pixX,pixY) + if(thePix != theOriginalPix) //colour changed + DrawPixelOn(theOriginalPix,pixX,pixY) + qdel(masterpiece) + return + + //Drawing one pixel with a crayon + if(istype(I, /obj/item/toy/crayon)) + var/obj/item/toy/crayon/C = I + if(masterpiece.GetPixel(pixX, pixY)) // if the located pixel isn't blank (null)) + DrawPixelOn(C.colour, pixX, pixY) + return + + ..() + +//Clean the whole canvas +/obj/item/weapon/canvas/attack_self(var/mob/user) + if(!user) + return + var/icon/blank = getGlobalBackup() + if(blank) + //it's basically a giant etch-a-sketch + icon = blank + user.visible_message("[user] cleans the canvas.","You clean the canvas.") + +//Examine to enlarge +/obj/item/weapon/canvas/examine(var/mob/user = usr) + ..() + if(in_range(user, src) && get_turf(src) && user.client && ishuman(user)) //Let only humans be the robust zoominators. I'm too spooked other mobs trying to use it may get broken huds. + if(src.loc == user || get_turf(src) == get_turf(user)) + user << "[src] has to be on the ground to focus on it!" + return + user << "You focus on \the [src]." + user.client.screen = list() //This is because screen objects go way past the view bounds we set, therefore not allowing stretch to fit to zoom in properly. + user.client.reset_stretch = winget(user.client, "mapwindow.map", "icon-size") //Remember previous icon-size + user.client.view = 3 //Decrease view + winset(user.client, "mapwindow.map", "icon-size=0") //Enable stretch-to-fit + user.client.viewingCanvas = 1 //Reset everything we just changed as soon as client tries to move + else + user << "It is too far away." + +#undef AMT_OF_CANVASES \ No newline at end of file diff --git a/code/modules/client/client defines.dm b/code/modules/client/client defines.dm index 0dfa00ca8cf..cbfa50f0759 100644 --- a/code/modules/client/client defines.dm +++ b/code/modules/client/client defines.dm @@ -70,4 +70,6 @@ "AZERTY" = list( "on" = "AZERTYon", "off" = "AZERTYoff") - ) \ No newline at end of file + ) + + var/reset_stretch = 0 //Used by things that fiddle with client's stretch-to-fit. \ No newline at end of file diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 5afda13a9be..0407a0edc07 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -176,6 +176,17 @@ /client/Move(n, direct) + if(viewingCanvas) + view = world.view //Reset the view + winset(src, "mapwindow.map", "icon-size=[src.reset_stretch]") + viewingCanvas = 0 + mob.reset_view() + mob.button_pressed_F12() + if(!mob.hud_used.hud_shown) + mob.button_pressed_F12() + mob.update_hud() + mob.update_action_buttons() + if(mob.control_object) Move_object(direct) if(world.time < move_delay) return diff --git a/code/modules/research/designs/autolathe_designs.dm b/code/modules/research/designs/autolathe_designs.dm index 970f0b139f9..d58d23f09cf 100644 --- a/code/modules/research/designs/autolathe_designs.dm +++ b/code/modules/research/designs/autolathe_designs.dm @@ -226,6 +226,38 @@ build_path = /obj/item/device/assembly/voice category = list("initial", "Miscellaneous") +/datum/design/canvas + name = "11px by 11px Canvas" + id = "canvas" + build_type = AUTOLATHE + materials = list("$metal" = 50) + build_path = /obj/item/weapon/canvas + category = list("initial", "Miscellaneous") + +/datum/design/canvas/nineteenXnineteen + name = "19px by 19px Canvas" + id = "canvas19x19" + build_type = AUTOLATHE + materials = list("$metal" = 50) + build_path = /obj/item/weapon/canvas/nineteenXnineteen + category = list("initial", "Miscellaneous") + +/datum/design/canvas/twentythreeXnineteen + name = "23px by 19px Canvas" + id = "canvas23x19" + build_type = AUTOLATHE + materials = list("$metal" = 70) + build_path = /obj/item/weapon/canvas/twentythreeXnineteen + category = list("initial", "Miscellaneous") + +/datum/design/canvas/twentythreeXtwentythree + name = "23px by 23px Canvas" + id = "canvas23x23" + build_type = AUTOLATHE + materials = list("$metal" = 100) + build_path = /obj/item/weapon/canvas/twentythreeXtwentythree + category = list("initial", "Miscellaneous") + /datum/design/camera_assembly name = "Camera Assembly" id = "camera_assembly" diff --git a/icons/obj/artstuff.dmi b/icons/obj/artstuff.dmi new file mode 100644 index 0000000000000000000000000000000000000000..a11d1a81d0e16867718bdc8e510d012f3916bb86 GIT binary patch literal 1847 zcmV-72gvw|P)V>ZpryV=>z+}zOJ-O=9O z(ca$D-`~>R-O$|J&)eJ2+S<;LWH*pwHj!pIkz_cKW;l>#JCbEMk!3lNWjM~xyxG~# zgIY3yS~P)LGlN?*f?6|!Tr`1LGlN|-&d$5w;M3vZ)RAU5bx|&NRWXiYHP_e7($c@w z)W6i!z|YUUk7PJ>Q7&{*EzHcj*4E47;?&sK%z|1mc2O;NQ!mxk%7R-oc2X|mKq0*VoI~*v;bN)#2gOgIzRrQZJ8VH-lU?b5AURS~7A^EP`1w zbx|#iVm5ysxHXXuH;-gFkYzZ_%eufFDZ*Bkpc$`yKaB_9`^iy#0_2eo`Eh^5;&r`5fFwryM;w;ZhDainG zjE%TBGg33tGfE(w;*!LYR3K9+HL*A~M~RCwC9|j)$T#HTOe;#vO@*-Gs*H>)jEsp< zWoSuIm7yh3sthX(4RNVbR&e!m0ecq!`G!HBBmm~D000D*Nkltm~^1x2N7(Q19x`qn?#J4v?5GAIdW zkH>T5+aK=D`I7l^A2YdU3x$6R+==v6aUgxg3xX(?%3`@(7Qqn*d4VsL%H>=FL&fw} z<(~AFBqIf>08Q5n(=ah6GBQv;f$H$RBiwx)cR$CS92gxNOLLZNV-pl~fPzeHf`BX| zF_!@Mz=PwJnp2#3=-~;c==2DjB7|U5L0Y}u&{Tv7k>N)Ma|t{$9-7mShNkvdnv-PN zB?wW0I!zL?se)O$%UhNt3=Z;>XQrmglOoRx)7G@bm(pt#W+H*dp9sx~o+3A0&$BVX zkfYhUW*|(64-u5I@*#%iLi6O=&^V(#5x8#P%NV12qtSpEXbFgI^I7>2+_@-4=c5!2 z?T^5P*HR4qso8p6Rgvryf`qI*MfK@tLi_A|Xr8-}?o+F^upryeH>iHGv8bu4LEwEc zpOp^-cs{c8mm)jPrBmd)vg^WIDe6T?vWmkt#X?q|V#$f@`KZW+7e>=5@_gTeEZB;+ z*npjYFqT`cZ)N4f2;z-A|6*j9dm>nH{lN2lTh$@K3SGhWi7#d4LxDJg`IjPFOYbzx z_ky71%EUm1q9GMQk|7ILR-U5za%9i0#1T}}0xj1IeAkC6Vx${zBq0-FS;)#$ys{eE zOR>P(<+K3wITVo=4r4{pR9!>JBtlj`Owp_B!(*3cUaP)7w!VI4rpmpMBAc%3xvmRg z+pvVGLKYNQO32Dn4AfTFmTPYoYtCD9PGzFDd?hVFQ|$Q|_NPn}jSy{h!e`|vMrx6L zJKAW4b3I+;wc8#P(U$#|PYe|!4O+$Iv+@+fS0mfqXz#q67I51e?*%P;fu@>ZsHCAm zFA7=tFoH^CPsbbW{h6K!f{g&$L=OA~I3-nN!iPs!N?Cb8^}=%Gtb7pJtJhLFYPL5w z+nX)ub`P2zBX~i5v96Z0@&GQ*Q1^QP2X?AYx1fma&9)b`VF6!OR7Kb8dSfapPX#`V zot2MbXKg8AEjNG_Ha6NDo1RaTtizcw+t|*^!}=euk1l;OGQ$mUpK@Gvh}*f&T}wic z0J~DNbEDJgNRlwkPtu`fdnzjr$NyLbKKSE%mCqb!@AHat)7krCXSL8rd>Nm0gleO`yR`7lx3Tlx_k9%@or|5@Kg7-}8+)MP@2kKTJKqb3Ka~R#JKy(LV2hpa`zvsY zo$vX>pUMG=o$vcwWQm>crNf`ffhIfO_qoXIe9s6pEkPUrIhgbBj~X6 zJ@b~$gwG$rE<4{dg_IIL|1r{G=le5E1POnXA~W+n6G128k0QX#_uKpLxsmWk*arv9 l_xtZj^SK3%ag6^m{sPtpA*6-R*|h)w002ovPDHLkV1f?eh~xkO literal 0 HcmV?d00001 diff --git a/paradise.dme b/paradise.dme index a4711b96195..9741089c862 100644 --- a/paradise.dme +++ b/paradise.dme @@ -762,6 +762,7 @@ #include "code\game\objects\items\weapons\tanks\tanks.dm" #include "code\game\objects\items\weapons\tanks\watertank.dm" #include "code\game\objects\random\random.dm" +#include "code\game\objects\structures\artstuff.dm" #include "code\game\objects\structures\barsign.dm" #include "code\game\objects\structures\bedsheet_bin.dm" #include "code\game\objects\structures\coathanger.dm"