Author Topic: Hyrule Exploration!  (Read 3554 times)

0 Members and 1 Guest are viewing this topic.

Offline Cobalt

  • QB64 Developer
  • Forum Resident
  • Posts: 878
  • At 60 I become highly radioactive!
    • View Profile
Hyrule Exploration!
« on: December 29, 2019, 03:26:46 pm »
A little peak at something I've worked on the past 3-4 days now. Collision is a bit extreme, and moving diagonally can cause some issues. but you should be able to explore most of the world. Meet the crazy old man in every cave trying to give you a wooden sword because he thinks its "dangerous to go alone!" I mean EVERY cave! how does he move without you seeing him? 

Anyway,

this REQUIRES QB64 Development Build.

Arrow keys to move, Enter to enter\exit inventory screen, ESC to quit.
You can select different items for hand B but can not use them yet.
And no you cannot accept the Wooden sword as of yet.

Code: QB64: [Select]
  1. 'Zelda peliminary R&D
  2. TYPE Link_Data
  3.  Hearts AS _BYTE 'player health
  4.  HeartContainers AS _BYTE 'players max health
  5.  Hit_level AS _BYTE 'number of hits before losing heart(1-normal, 2-B_Ring, 4-R_Ring)
  6.  Rupies AS _UNSIGNED _BYTE 'players rupies
  7.  Keys AS _BYTE 'number of keys
  8.  Bombs AS _BYTE 'number of bombs
  9.  Sword AS _BYTE 'which sword does player have
  10.  Sheild AS _BYTE 'does player have magical shield
  11.  Items AS LONG 'Arrow,S_Arrow,B_Candle,R_Candle,B_Ring,R_Ring,Bracelet,Recorder,Raft,Ladder
  12.  '              Rod,Book,M_Key,Letter,B_Potion,R_Potion,Food,Boomerang,M_Boomerang
  13.  Hand_A AS _BYTE 'sword equiped
  14.  Hand_B AS _BYTE 'item equiped
  15.  X AS _BYTE 'players world X
  16.  Y AS _BYTE 'players world Y
  17.  Sx AS INTEGER 'Screen X
  18.  Sy AS INTEGER 'Screen Y
  19.  Face AS _BYTE 'which direction is player facing up,down,left,right
  20.  Level AS _BYTE 'is player on 2nd quest
  21.  Dungeon AS _BYTE 'is player in dungeon\which dungeon
  22.  TriForce AS _UNSIGNED _BYTE ' collected triforce pieces
  23.  Frame AS _BYTE
  24.  
  25. TYPE Map_data
  26.  
  27. TYPE Game_Data
  28.  Enter AS _BYTE 'player is entering a cave or dungeon level
  29.  In_Cave AS _BYTE
  30.  Just_Left AS _BYTE 'did player just leave cave or dungeon level
  31.  Ox AS INTEGER
  32.  Oy AS INTEGER
  33.  Mx AS _BYTE
  34.  My AS _BYTE
  35.  State AS _BYTE 'old mans image, if hit
  36.  Text_Done AS _BYTE 'has message been displayed
  37.  
  38. CONST TRUE = -1, FALSE = NOT TRUE
  39. CONST DOWN = 1, UP = 2, RIGHT = 3, LEFT = 4, TOINVENTORY = 1, TOMAP = 2, NORMAL = 0, ANGRY = 1
  40. CONST Key_Up = 18432, Key_Left = 19200, Key_Down = 20480, Key_Right = 19712, Start_Button = 13
  41. CONST Black = _RGB32(0, 0, 0)
  42.  
  43. DIM SHARED L AS Link_Data
  44. DIM SHARED G AS Game_Data
  45. DIM SHARED M(255) AS Map_data
  46. DIM SHARED Layer(16) AS LONG
  47. DIM SHARED MSG$(24), FFX&
  48.  
  49. SCREEN _NEWIMAGE(640, 480, 32)
  50. Layer(0) = _DISPLAY
  51. Layer(1) = _NEWIMAGE(640, 480, 32)
  52. 'Layer(2) = _LOADIMAGE("GFX\119176.bmp", 32)
  53. 'Layer(3) = _LOADIMAGE("GFX\8366.bmp", 32)
  54. 'Layer(4) = _LOADIMAGE("GFX\119278.bmp", 32)
  55. 'Layer(5) = _LOADIMAGE("GFX\Map_Maskb.bmp", 32)
  56. 'Layer(6) = _LOADIMAGE("GFX\21189.bmp", 32) 'npc sheet
  57.  
  58. MFI_Loader "Zelda1.MFI"
  59.  
  60. Layer(8) = _NEWIMAGE(640, 480, 32) 'scrolling overworld item temp layer
  61. Layer(9) = _NEWIMAGE(640, 480, 32) 'scrolling map layer
  62. Layer(10) = _NEWIMAGE(640, 480, 32) 'collision layer
  63. Layer(11) = _NEWIMAGE(640, 480, 32) 'temp inventory layer/map movement layer
  64. Layer(12) = _NEWIMAGE(640, 480, 32) 'text message layer
  65.  
  66. 'FFX& = _LOADFONT("NESfont.otf", 20, "monospace")
  67.  
  68. _CLEARCOLOR _RGB32(116), Layer(3)
  69. _CLEARCOLOR _RGB32(116), Layer(4)
  70. _CLEARCOLOR _RGB32(116), Layer(6)
  71. _CLEARCOLOR _RGB32(0, 128, 0), Layer(4)
  72. _CLEARCOLOR _RGB32(0), Layer(4)
  73. _SOURCE Layer(10) 'collision detection map
  74. _FONT FFX&, Layer(1)
  75. _FONT FFX&, Layer(12)
  76. MSG$(1) = "it's dangerous to go  alone! Take this."
  77. L.X = 7: L.Y = 7: L.Sx = 304: L.Sy = 288: L.Face = UP: L.Hearts = 6: L.HeartContainers = 3
  78. L.Hand_A = 0: L.Hand_B = 1: L.TriForce = 0: L.Items = 75 '767 '2097151
  79. _DEST Layer(1)
  80.  
  81.  Build_Main_Display
  82.  Display_B_Hand L.Hand_B
  83.  Display_A_Hand L.Hand_A
  84.  IF G.In_Cave THEN Fill_Cave 1
  85.  IF G.Text_Done THEN _PUTIMAGE , Layer(12), Layer(1)
  86.  Place_Link L.Sx, L.Sy, L.Frame
  87.  _PRINTSTRING (0, 0), STR$(L.Sy) + STR$(L.Sx), Layer(1)
  88.  _PUTIMAGE , Layer(1), Layer(0)
  89.  _LIMIT 60
  90.  
  91.  IF _KEYDOWN(Key_Up) AND Movement_Collision(L.Sx, L.Sy - 2) = FALSE THEN L.Sy = L.Sy - 2: L.Face = UP: L.Frame = Animate_Link
  92.  IF _KEYDOWN(Key_Down) AND Movement_Collision(L.Sx, L.Sy + 2) = FALSE THEN L.Sy = L.Sy + 2: L.Face = DOWN: L.Frame = Animate_Link
  93.  IF _KEYDOWN(Key_Left) AND Movement_Collision(L.Sx - 2, L.Sy) = FALSE THEN L.Sx = L.Sx - 2: L.Face = LEFT: L.Frame = Animate_Link
  94.  IF _KEYDOWN(Key_Right) AND Movement_Collision(L.Sx + 2, L.Sy) = FALSE THEN L.Sx = L.Sx + 2: L.Face = RIGHT: L.Frame = Animate_Link
  95.  IF _KEYDOWN(Start_Button) THEN Scroll_Overworld_Inventory TOINVENTORY: Run_Overworld_Inventory: Scroll_Overworld_Inventory TOMAP
  96.  IF G.Enter > 0 THEN Play_Entering_Animation L.Sx, L.Sy: Enter_Cave 1
  97.  IF L.Sy = 114 THEN Scroll_Map L.X, L.Y, L.Face
  98.  IF L.Sy = 446 AND (NOT G.In_Cave) THEN
  99.   Scroll_Map L.X, L.Y, L.Face
  100.  ELSEIF G.In_Cave AND L.Sy = 446 THEN
  101.   Exit_Cave 1
  102.  IF L.Sx = 60 THEN Scroll_Map L.X, L.Y, L.Face
  103.  IF L.Sx = 546 THEN Scroll_Map L.X, L.Y, L.Face
  104.  
  105.  IF _KEYHIT = 27 THEN ExitFlag%% = TRUE
  106.  
  107. LOOP UNTIL ExitFlag%%
  108.  
  109. _FONT 16, Layer(1)
  110. '_PUTIMAGE , Layer(10), Layer(0)
  111.  
  112. REM'$include:'DisplayFunctions.BAS'
  113. REM'$include:'OverworldInventory.BAS'
  114. REM'$include:'Core_Function.BAS'
  115. REM'$include:'MFI_Functions.BAS'
  116.  
  117. SUB MFI_Loader (FN$)
  118.  DIM Size(64) AS LONG, FOffset(64) AS LONG
  119.  GET #1, , c~%% 'retrieve number of files
  120.  FOR I~%% = 1 TO c~%%
  121.   GET #1, , FOffset(I~%%)
  122.   GET #1, , Size(I~%%)
  123.   FOffset&(I~%%) = FOffset&(I~%%) + 1
  124.  NEXT I~%%
  125.  'load the files where they go here----------
  126.  Layer(2) = LoadGFX(FOffset(3), Size(3)) '
  127.  Layer(3) = LoadGFX(FOffset(1), Size(1)) '
  128.  Layer(4) = LoadGFX(FOffset(4), Size(4)) '
  129.  Layer(5) = LoadGFX(FOffset(5), Size(5)) '
  130.  Layer(6) = LoadGFX(FOffset(2), Size(2)) '
  131.  FFX& = LoadFFX(FOffset(6), Size(6), 20) '_LOADFONT("NESfont.otf", 20, "monospace")
  132.  '-------------------------------------------
  133.  CLOSE #1
  134.  IF _FILEEXISTS("temp.dat") THEN KILL "temp.dat"
  135.  
  136. SUB Place_Link (X%, Y%, F%%)
  137.  SELECT CASE L.Face
  138.   CASE DOWN
  139.    _PUTIMAGE (X%, Y%)-STEP(31, 31), Layer(3), Layer(1), (1 + F%% * 17, 11)-STEP(15, 15)
  140.   CASE UP
  141.    _PUTIMAGE (X%, Y%)-STEP(31, 31), Layer(3), Layer(1), (69 + F%% * 17, 11)-STEP(15, 15)
  142.   CASE LEFT
  143.    _PUTIMAGE (X% + 32, Y%)-STEP(-31, 31), Layer(3), Layer(1), (35 + F%% * 17, 11)-STEP(15, 15)
  144.   CASE RIGHT
  145.    _PUTIMAGE (X%, Y%)-STEP(31, 31), Layer(3), Layer(1), (35 + F%% * 17, 11)-STEP(15, 15)
  146.  
  147.  
  148. SUB Fill_Cave (ID%%)
  149.  SELECT CASE ID%%
  150.   CASE 1
  151.    Place_Flame 5, 4
  152.    Place_Flame 11, 4
  153.    IF L.Sword = 0 THEN
  154.     Place_Man 8, 4
  155.     Place_Pickup_Item 31, 22, 1
  156.     IF NOT G.Text_Done THEN Write_Text 9, 10, 1
  157.    END IF
  158.  
  159. SUB Place_Man (X%%, Y%%)
  160.  SELECT CASE G.State
  161.   CASE NORMAL
  162.    _PUTIMAGE (48 + 32 * X%%, 128 + 32 * Y%%)-STEP(31, 31), Layer(6), Layer(1), (1, 11)-STEP(15, 15)
  163.   CASE ANGRY
  164.    _PUTIMAGE (48 + 32 * X%%, 128 + 32 * Y%%)-STEP(31, 31), Layer(6), Layer(1), (18, 11)-STEP(15, 15)
  165.  
  166. SUB Place_Pickup_Item (X%%, Y%%, I%%)
  167.  SELECT CASE I%%
  168.   CASE 1 'wood sword
  169.    _PUTIMAGE (64 + 8 * X%%, 128 + 8 * Y%%)-STEP(15, 31), Layer(4), Layer(1), (555, 137)-STEP(7, 15)
  170.  
  171. SUB Write_Text (X%%, Y%%, T%%)
  172.  ClearLayer Layer(11)
  173.  ClearLayer Layer(12)
  174.  _PUTIMAGE , Layer(1), Layer(11)
  175.  L%% = LEN(MSG$(T%%))
  176.  DO
  177.   D%% = D%% + 1
  178.   _PRINTSTRING (64 + 8 * X%% + 16 * D%%, 128 + 8 * Y%% + 17 * Z%%), MID$(MSG$(T%%), D%% + 20 * Z%%, 1), Layer(12)
  179.   _PUTIMAGE , Layer(11), Layer(1)
  180.   _PUTIMAGE , Layer(12), Layer(1)
  181.   Place_Link L.Sx, L.Sy, L.Frame
  182.   _PUTIMAGE , Layer(1), Layer(0)
  183.   _LIMIT 10
  184.   IF D%% = 20 THEN Z%% = Z%% + 1: D%% = 0
  185.   IF D%% + 20 * Z%% = L%% THEN ExitFlag%% = TRUE
  186.  LOOP UNTIL ExitFlag%%
  187.  G.Text_Done = TRUE
  188.  
  189. FUNCTION Movement_Collision%% (X%, Y%)
  190.  DIM Test(10) AS _UNSIGNED LONG
  191.  Result%% = FALSE 'there is no collision by defult
  192.  'get all test points
  193.  Test(1) = POINT(X% + 4, Y% + 15) 'upper left test point
  194.  Test(2) = POINT(X% + 16, Y% + 15) 'upper center test point
  195.  Test(3) = POINT(X% + 28, Y% + 15) 'upper right test point
  196.  Test(4) = POINT(X% + 4, Y% + 32) 'lower left test point
  197.  Test(5) = POINT(X% + 16, Y% + 32) 'lower center test point
  198.  Test(6) = POINT(X% + 28, Y% + 32) 'lower right test point
  199.  FOR i%% = 1 TO 6
  200.   IF Test(i%%) <> Black THEN Result%% = TRUE
  201.  NEXT i%%
  202.  
  203.  IF _RED32(Test(2)) = 4 THEN
  204.   Result%% = FALSE 'player can walk into door way
  205.   IF NOT G.Just_Left THEN
  206.    IF Test(5) <> Black THEN G.Enter = _RED32(Test(2))
  207.   ELSE
  208.    IF Test(5) <> Black THEN Result%% = TRUE
  209.   END IF
  210.  
  211.   G.Just_Left = FALSE
  212.  
  213.  Movement_Collision = Result%%
  214.  
  215. SUB ClearLayer (L&)
  216.  old& = _DEST
  217.  _DEST L&
  218.  CLS , 0
  219.  _DEST old&
  220.  
  221. SUB Enter_Cave (ID%%)
  222.  L.Sx = 284: L.Sy = 440
  223.  SELECT CASE ID%%
  224.   CASE 1
  225.    G.Mx = L.X
  226.    G.My = L.Y
  227.    L.X = 0
  228.    L.Y = 8
  229.    G.Enter = FALSE
  230.    G.In_Cave = TRUE
  231.  
  232. SUB Exit_Cave (ID%%)
  233.  SELECT CASE ID%%
  234.   CASE 1
  235.    L.X = G.Mx
  236.    L.Y = G.My
  237.    G.In_Cave = FALSE
  238.    Play_Exiting_Animation G.Ox, G.Oy
  239.    G.Text_Done = FALSE
  240.  
  241. SUB Place_Cave_Screen
  242.  _PUTIMAGE (64, 128)-STEP(511, 351), Layer(2), Layer(1), (1, 1421)-STEP(255, 175)
  243.  
  244. SUB Build_Cave_Collision_Screen
  245.  _PUTIMAGE (64, 128)-STEP(511, 351), Layer(11), Layer(12), (1, 1421)-STEP(255, 175)
  246.  
  247. SUB Display_Map_Screen (X%%, Y%%)
  248.  _PUTIMAGE (64, 128)-STEP(511, 351), Layer(2), Layer(1), (1 + 257 * X%%, 1 + 177 * Y%%)-STEP(255, 175)
  249.  
  250. SUB Place_Header
  251.  _PUTIMAGE (64, 16)-STEP(511, 111), Layer(4), Layer(1), (258, 11)-STEP(255, 55)
  252.  
  253. SUB Place_Map_Grid
  254.  _PUTIMAGE (96, 32)-STEP(127, 79), Layer(4), Layer(1), (519, 1)-STEP(63, 39)
  255.  
  256. SUB Display_Ruby_Count (X~%%)
  257.  C$ = LTRIM$(STR$(X~%%))
  258.  IF LEN(C$) < 3 THEN
  259.   IF LEN(C$) = 1 THEN C$ = C$ + " "
  260.   C$ = "X" + C$
  261.  _PRINTSTRING (256, 45), C$, Layer(1) 'Rupies
  262.  
  263. SUB Display_Key_Count (X%%)
  264.  C$ = LTRIM$(STR$(X%%))
  265.  IF LEN(C$) = 1 THEN C$ = C$ + " "
  266.  _PRINTSTRING (256, 75), "X" + C$, Layer(1) 'keys
  267.  
  268. SUB Display_Bomb_Count (X%%)
  269.  C$ = LTRIM$(STR$(X%%))
  270.  IF LEN(C$) = 1 THEN C$ = C$ + " "
  271.  _PRINTSTRING (256, 93), "X" + C$, Layer(1) 'bombs
  272.  
  273. SUB Display_Hearts (X%%)
  274.  FOR i%% = 1 TO X%% \ 2
  275.   _PUTIMAGE (416 + (i%% - 1) * 16, 96)-STEP(15, 15), Layer(4), Layer(1), (645, 117)-STEP(7, 7)
  276.  NEXT i%%
  277.  IF X%% MOD 2 = 1 THEN
  278.   _PUTIMAGE (416 + (i%% - 1) * 16, 96)-STEP(15, 15), Layer(4), Layer(1), (636, 117)-STEP(7, 7)
  279.  
  280. SUB Display_Heart_Containers (X%%)
  281.  FOR i%% = 1 TO X%%
  282.   _PUTIMAGE (416 + (i%% - 1) * 16, 96)-STEP(15, 15), Layer(4), Layer(1), (627, 117)-STEP(7, 7)
  283.  NEXT i%%
  284.  
  285. SUB Display_B_Hand (ID%%)
  286.  _PUTIMAGE (320, 64)-STEP(15, 31), Layer(4), Layer(1), (500, 32)-STEP(7, 15) 'blank it
  287.  SELECT CASE ID%%
  288.   CASE 0 'no item
  289.   CASE 1 'Boomerang
  290.    IF _READBIT(L.Items, 8) THEN
  291.     _PUTIMAGE (320, 64)-STEP(15, 31), Layer(4), Layer(1), (592, 137)-STEP(7, 15) '
  292.    ELSEIF _READBIT(L.Items, 0) THEN
  293.     _PUTIMAGE (320, 64)-STEP(15, 31), Layer(4), Layer(1), (584, 137)-STEP(7, 15) 'boomerang
  294.    END IF
  295.   CASE 2 'Bomb
  296.    _PUTIMAGE (320, 64)-STEP(15, 31), Layer(4), Layer(1), (604, 137)-STEP(7, 15) '
  297.   CASE 3 'Bow
  298.    _PUTIMAGE (320, 64)-STEP(15, 31), Layer(4), Layer(1), (633, 137)-STEP(7, 15) '
  299.   CASE 4 'Blue Candle
  300.    IF _READBIT(L.Items, 9) THEN
  301.     _PUTIMAGE (320, 64)-STEP(15, 31), Layer(4), Layer(1), (653, 137)-STEP(7, 15) '
  302.    ELSEIF _READBIT(L.Items, 3) THEN
  303.     _PUTIMAGE (320, 64)-STEP(15, 31), Layer(4), Layer(1), (644, 137)-STEP(7, 15) '
  304.    END IF
  305.   CASE 5 'Recorder
  306.    _PUTIMAGE (320, 64)-STEP(15, 31), Layer(4), Layer(1), (664, 137)-STEP(7, 15) '
  307.   CASE 6 'Meat
  308.    _PUTIMAGE (320, 64)-STEP(15, 31), Layer(4), Layer(1), (675, 137)-STEP(7, 15) '
  309.   CASE 7 'Letter
  310.    IF _READBIT(L.Items, 11) THEN
  311.     _PUTIMAGE (320, 64)-STEP(15, 31), Layer(4), Layer(1), (704, 137)-STEP(7, 15) '
  312.    ELSEIF _READBIT(L.Items, 10) THEN
  313.     _PUTIMAGE (320, 64)-STEP(15, 31), Layer(4), Layer(1), (695, 137)-STEP(7, 15) '
  314.    ELSEIF _READBIT(L.Items, 6) THEN
  315.     _PUTIMAGE (320, 64)-STEP(15, 31), Layer(4), Layer(1), (686, 137)-STEP(7, 15) '
  316.    END IF
  317.   CASE 8 'Magical Rod
  318.    _PUTIMAGE (320, 64)-STEP(15, 31), Layer(4), Layer(1), (715, 137)-STEP(7, 15) '
  319.  
  320. SUB Display_A_Hand (ID%%)
  321.  _PUTIMAGE (368, 64)-STEP(15, 31), Layer(4), Layer(1), (500, 32)-STEP(7, 15) 'blank it
  322.  SELECT CASE ID%%
  323.   CASE 0 'no sword
  324.   CASE 1 'Wooden sword
  325.    _PUTIMAGE (368, 64)-STEP(15, 31), Layer(4), Layer(1), (555, 137)-STEP(7, 15)
  326.   CASE 2 'Silver Sword
  327.    _PUTIMAGE (368, 64)-STEP(15, 31), Layer(4), Layer(1), (564, 137)-STEP(7, 15)
  328.   CASE 3 'Magical Sword
  329.    _PUTIMAGE (368, 64)-STEP(15, 31), Layer(4), Layer(1), (573, 137)-STEP(7, 15)
  330.  
  331. SUB Display_Map_Position (X%%, Y%%)
  332.  _PUTIMAGE (96 + X%% * 8, 48 + Y%% * 8)-STEP(5, 5), Layer(4), Layer(1), (519, 126)-STEP(2, 2) 'over world pos.
  333.  
  334. SUB Build_Main_Display
  335.  Display_Map_Screen L.X, L.Y
  336.  Place_Collision_map L.X, L.Y
  337.  Place_Header
  338.  Place_Map_Grid
  339.  Display_Ruby_Count L.Rupies
  340.  Display_Key_Count L.Keys
  341.  Display_Bomb_Count L.Bombs
  342.  Display_Heart_Containers L.HeartContainers
  343.  Display_Hearts L.Hearts
  344.  Display_Map_Position L.X, L.Y
  345.  
  346. FUNCTION Animate_Link%%
  347.  STATIC Count%%, Result%%
  348.  Count%% = Count%% + 1
  349.  IF Count%% = 10 THEN Result%% = 1
  350.  IF Count%% = 20 THEN Result%% = 0: Count%% = 0
  351.  Animate_Link = Result%%
  352.  
  353. SUB Place_Collision_map (X%%, Y%%)
  354.  _PUTIMAGE (64, 128)-STEP(511, 351), Layer(5), Layer(10), (1 + 257 * X%%, 1 + 177 * Y%%)-STEP(255, 175)
  355.  
  356. SUB Play_Entering_Animation (X%, Y%)
  357.  G.Ox = X%
  358.  G.Oy = Y%
  359.  F%% = 0
  360.  FOR i%% = 0 TO 15
  361.   Build_Main_Display
  362.   _PUTIMAGE (X%, Y% + (i%% * 2) + 2)-STEP(31, 31 - (i%% * 2)), Layer(3), Layer(1), (69 + F%% * 17, 11)-STEP(15, 15 - i%%)
  363.   IF F%% = 0 THEN F%% = 1 ELSE F%% = 0
  364.   _PUTIMAGE , Layer(1), Layer(0)
  365.   _LIMIT 12
  366.  NEXT i%%
  367.  Build_Main_Display
  368.  _PUTIMAGE , Layer(1), Layer(0)
  369.  
  370. SUB Play_Exiting_Animation (X%, Y%)
  371.  F%% = 0
  372.  FOR i%% = 15 TO 0 STEP -1
  373.   Build_Main_Display
  374.   _PUTIMAGE (X%, Y% + (i%% * 2) + 2)-STEP(31, 31 - (i%% * 2)), Layer(3), Layer(1), (1 + F%% * 17, 11)-STEP(15, 15 - i%%)
  375.   IF F%% = 0 THEN F%% = 1 ELSE F%% = 0
  376.   _PUTIMAGE , Layer(1), Layer(0)
  377.   _LIMIT 12
  378.  NEXT i%%
  379.  Build_Main_Display
  380.  _PUTIMAGE , Layer(1), Layer(0)
  381.  L.Sx = X%
  382.  L.Sy = Y% + (i%% * 2) + 4
  383.  L.Face = DOWN
  384.  G.Enter = FALSE
  385.  G.Just_Left = TRUE
  386.  
  387. SUB Scroll_Map (X%%, Y%%, D%%)
  388.  '---------------setup----------------
  389.  Build_Main_Display
  390.  _PUTIMAGE , Layer(1), Layer(9)
  391.  SELECT CASE D%%
  392.   CASE UP
  393.    Display_Map_Screen X%%, Y%% - 1
  394.    _PUTIMAGE , Layer(1), Layer(11)
  395.   CASE DOWN
  396.    Display_Map_Screen X%%, Y%% + 1
  397.    _PUTIMAGE , Layer(1), Layer(11)
  398.   CASE LEFT
  399.    Display_Map_Screen X%% - 1, Y%%
  400.    _PUTIMAGE , Layer(1), Layer(11)
  401.   CASE RIGHT
  402.    Display_Map_Screen X%% + 1, Y%%
  403.    _PUTIMAGE , Layer(1), Layer(11)
  404.  '------------------------------------
  405.  SELECT CASE D%%
  406.   CASE UP
  407.    FOR i% = 0 TO 177 STEP 1
  408.     _PUTIMAGE , Layer(9), Layer(1) 'put base
  409.     _PUTIMAGE (64, 128)-STEP(511, 351), Layer(2), Layer(1), (1 + 257 * X%%, 1 + 177 * Y%% - i%)-STEP(255, 175)
  410.     Place_Link L.Sx, L.Sy, L.Frame
  411.     L.Sy = L.Sy + 2
  412.     IF L.Sy > 444 THEN L.Sy = 444
  413.     L.Frame = Animate_Link
  414.     _PUTIMAGE , Layer(1), Layer(0)
  415.     _LIMIT 110
  416.    NEXT i%
  417.    L.Y = L.Y - 1
  418.   CASE DOWN
  419.    FOR i% = 0 TO 177 STEP 1
  420.     _PUTIMAGE , Layer(9), Layer(1) 'put base
  421.     _PUTIMAGE (64, 128)-STEP(511, 351), Layer(2), Layer(1), (1 + 257 * X%%, 1 + 177 * Y%% + i%)-STEP(255, 175)
  422.     Place_Link L.Sx, L.Sy, L.Frame
  423.     L.Sy = L.Sy - 2
  424.     IF L.Sy < 116 THEN L.Sy = 116
  425.     L.Frame = Animate_Link
  426.     _PUTIMAGE , Layer(1), Layer(0)
  427.     _LIMIT 110
  428.    NEXT i%
  429.    L.Y = L.Y + 1
  430.   CASE LEFT
  431.    FOR i% = 0 TO 257 STEP 1
  432.     _PUTIMAGE , Layer(9), Layer(1) 'put base
  433.     _PUTIMAGE (64, 128)-STEP(511, 351), Layer(2), Layer(1), (1 + 257 * X%% - i%, 1 + 177 * Y%%)-STEP(255, 175)
  434.     Place_Link L.Sx, L.Sy, L.Frame
  435.     L.Sx = L.Sx + 2
  436.     IF L.Sx > 544 THEN L.Sx = 544
  437.     L.Frame = Animate_Link
  438.     _PUTIMAGE , Layer(1), Layer(0)
  439.     _LIMIT 130
  440.    NEXT i%
  441.    L.X = L.X - 1
  442.   CASE RIGHT
  443.    FOR i% = 0 TO 257 STEP 1
  444.     _PUTIMAGE , Layer(9), Layer(1) 'put base
  445.     _PUTIMAGE (64, 128)-STEP(511, 351), Layer(2), Layer(1), (1 + 257 * X%% + i%, 1 + 177 * Y%%)-STEP(255, 175)
  446.     Place_Link L.Sx, L.Sy, L.Frame
  447.     L.Sx = L.Sx - 2
  448.     IF L.Sx < 62 THEN L.Sx = 62
  449.     L.Frame = Animate_Link
  450.     _PUTIMAGE , Layer(1), Layer(0)
  451.     _LIMIT 130
  452.    NEXT i%
  453.    L.X = L.X + 1
  454.  
  455. SUB Place_Flame (X%%, Y%%)
  456.  STATIC Frame%%
  457.  SELECT CASE Frame%%
  458.   CASE 0 TO 9
  459.    _PUTIMAGE (48 + 32 * X%%, 128 + 32 * Y%%)-STEP(31, 31), Layer(3), Layer(1), (191, 185)-STEP(15, 15)
  460.   CASE 10 TO 19
  461.    _PUTIMAGE (80 + 32 * X%%, 128 + 32 * Y%%)-STEP(-31, 31), Layer(3), Layer(1), (191, 185)-STEP(15, 15)
  462.  Frame%% = Frame%% + 1
  463.  IF Frame%% = 20 THEN Frame%% = 0
  464.  
  465. SUB Display_Triforce_Container
  466.  _PUTIMAGE (64, 208)-STEP(511, 175), Layer(4), Layer(1), (1, 112)-STEP(255, 87)
  467.  _PUTIMAGE (224, 240)-STEP(191, 95), Layer(4), Layer(1), (519, 42)-STEP(95, 47)
  468.  
  469. SUB Place_Triforce
  470.  IF _READBIT(L.TriForce, 0) THEN _PUTIMAGE (256, 288)-STEP(31, 31), Layer(4), Layer(1), (519, 91)-STEP(15, 15)
  471.  IF _READBIT(L.TriForce, 1) THEN _PUTIMAGE (352, 288)-STEP(31, 31), Layer(4), Layer(1), (536, 91)-STEP(15, 15)
  472.  IF _READBIT(L.TriForce, 2) THEN _PUTIMAGE (288, 288)-STEP(31, 31), Layer(4), Layer(1), (553, 91)-STEP(15, 15)
  473.  IF _READBIT(L.TriForce, 3) THEN _PUTIMAGE (321, 319)-STEP(-31, -31), Layer(4), Layer(1), (553, 91)-STEP(15, 15)
  474.  IF _READBIT(L.TriForce, 2) AND _READBIT(L.TriForce, 3) THEN _PUTIMAGE (288, 288)-STEP(31, 31), Layer(4), Layer(1), (587, 91)-STEP(15, 15)
  475.  IF _READBIT(L.TriForce, 4) THEN _PUTIMAGE (320, 288)-STEP(31, 31), Layer(4), Layer(1), (553, 91)-STEP(15, 15)
  476.  IF _READBIT(L.TriForce, 5) THEN _PUTIMAGE (353, 319)-STEP(-31, -31), Layer(4), Layer(1), (553, 91)-STEP(15, 15)
  477.  IF _READBIT(L.TriForce, 4) AND _READBIT(L.TriForce, 5) THEN _PUTIMAGE (320, 288)-STEP(31, 31), Layer(4), Layer(1), (587, 91)-STEP(15, 15)
  478.  IF _READBIT(L.TriForce, 6) THEN _PUTIMAGE (288, 256)-STEP(31, 31), Layer(4), Layer(1), (519, 91)-STEP(15, 15)
  479.  IF _READBIT(L.TriForce, 7) THEN _PUTIMAGE (320, 256)-STEP(31, 31), Layer(4), Layer(1), (536, 91)-STEP(15, 15)
  480.  
  481. SUB Place_Invenorty_Container
  482.  _PUTIMAGE (64, 32)-STEP(511, 175), Layer(4), Layer(1), (1, 11)-STEP(255, 87)
  483.  
  484. SUB Display_Inventory
  485.  'Upper Items(non selectable)
  486.  ' Raft,Book,B_Ring,R_Ring,Ladder,M_Key,Bracelet
  487.  IF _READBIT(L.Items, 14) THEN _PUTIMAGE (320, 80)-STEP(31, 31), Layer(4), Layer(1), (519, 156)-STEP(15, 15) ELSE _PUTIMAGE (320, 80)-STEP(31, 31), Layer(4), Layer(1), (500, 32)-STEP(7, 15) 'blank it
  488.  IF _READBIT(L.Items, 15) THEN _PUTIMAGE (368, 80)-STEP(15, 31), Layer(4), Layer(1), (538, 156)-STEP(7, 15) ELSE _PUTIMAGE (368, 80)-STEP(15, 31), Layer(4), Layer(1), (500, 32)-STEP(7, 15) 'blank it
  489.  IF _READBIT(L.Items, 16) THEN _PUTIMAGE (392, 80)-STEP(15, 31), Layer(4), Layer(1), (549, 156)-STEP(7, 15) ELSE _PUTIMAGE (392, 80)-STEP(15, 31), Layer(4), Layer(1), (500, 32)-STEP(7, 15) 'blank it
  490.  IF _READBIT(L.Items, 17) THEN _PUTIMAGE (392, 80)-STEP(15, 31), Layer(4), Layer(1), (560, 156)-STEP(7, 15) ELSE _PUTIMAGE (392, 80)-STEP(15, 31), Layer(4), Layer(1), (500, 32)-STEP(7, 15) 'blank it
  491.  IF _READBIT(L.Items, 18) THEN _PUTIMAGE (416, 80)-STEP(31, 31), Layer(4), Layer(1), (571, 156)-STEP(15, 15) ELSE _PUTIMAGE (416, 80)-STEP(31, 31), Layer(4), Layer(1), (500, 32)-STEP(7, 15) 'blank it
  492.  IF _READBIT(L.Items, 19) THEN _PUTIMAGE (456, 80)-STEP(15, 31), Layer(4), Layer(1), (590, 156)-STEP(7, 15) ELSE _PUTIMAGE (456, 80)-STEP(15, 31), Layer(4), Layer(1), (500, 32)-STEP(7, 15) 'blank it
  493.  IF _READBIT(L.Items, 20) THEN _PUTIMAGE (480, 80)-STEP(15, 31), Layer(4), Layer(1), (601, 156)-STEP(7, 15) ELSE _PUTIMAGE (480, 80)-STEP(15, 31), Layer(4), Layer(1), (500, 32)-STEP(7, 15) 'blank it
  494.  'lower items(selectable)
  495.  'Boomerang,bomb,bow,B_Candle,Recorder,meat,letter,rod,M_Boomerang,R_Candle,B_Potion,R_potion,Arrow,S_Arrow
  496.  IF _READBIT(L.Items, 0) THEN _PUTIMAGE (328, 128)-STEP(15, 31), Layer(4), Layer(1), (584, 137)-STEP(7, 15) ELSE _PUTIMAGE (328, 128)-STEP(15, 31), Layer(4), Layer(1), (500, 32)-STEP(7, 15) 'blank it
  497.  IF _READBIT(L.Items, 1) THEN _PUTIMAGE (376, 128)-STEP(15, 31), Layer(4), Layer(1), (604, 137)-STEP(7, 15) ELSE _PUTIMAGE (376, 128)-STEP(15, 31), Layer(4), Layer(1), (500, 32)-STEP(7, 15) 'blank it
  498.  IF _READBIT(L.Items, 2) THEN _PUTIMAGE (432, 128)-STEP(15, 31), Layer(4), Layer(1), (633, 137)-STEP(7, 15) ELSE _PUTIMAGE (432, 128)-STEP(15, 31), Layer(4), Layer(1), (500, 32)-STEP(7, 15) 'blank it
  499.  IF _READBIT(L.Items, 3) THEN _PUTIMAGE (472, 128)-STEP(15, 31), Layer(4), Layer(1), (644, 137)-STEP(7, 15) ELSE _PUTIMAGE (472, 128)-STEP(15, 31), Layer(4), Layer(1), (500, 32)-STEP(7, 15) 'blank it
  500.  IF _READBIT(L.Items, 4) THEN _PUTIMAGE (328, 160)-STEP(15, 31), Layer(4), Layer(1), (664, 137)-STEP(7, 15) ELSE _PUTIMAGE (328, 160)-STEP(15, 31), Layer(4), Layer(1), (500, 32)-STEP(7, 15) 'blank it
  501.  IF _READBIT(L.Items, 5) THEN _PUTIMAGE (376, 160)-STEP(15, 31), Layer(4), Layer(1), (675, 137)-STEP(7, 15) ELSE _PUTIMAGE (376, 160)-STEP(15, 31), Layer(4), Layer(1), (500, 32)-STEP(7, 15) 'blank it
  502.  IF _READBIT(L.Items, 6) THEN _PUTIMAGE (424, 160)-STEP(15, 31), Layer(4), Layer(1), (686, 137)-STEP(7, 15) ELSE _PUTIMAGE (424, 160)-STEP(15, 31), Layer(4), Layer(1), (500, 32)-STEP(7, 15) 'blank it
  503.  IF _READBIT(L.Items, 7) THEN _PUTIMAGE (472, 160)-STEP(15, 31), Layer(4), Layer(1), (715, 137)-STEP(7, 15) ELSE _PUTIMAGE (472, 160)-STEP(15, 31), Layer(4), Layer(1), (500, 32)-STEP(7, 15) 'blank it
  504.  IF _READBIT(L.Items, 8) THEN _PUTIMAGE (328, 128)-STEP(15, 31), Layer(4), Layer(1), (593, 137)-STEP(7, 15)
  505.  IF _READBIT(L.Items, 9) THEN _PUTIMAGE (472, 128)-STEP(15, 31), Layer(4), Layer(1), (653, 137)-STEP(7, 15)
  506.  IF _READBIT(L.Items, 10) THEN _PUTIMAGE (424, 160)-STEP(15, 31), Layer(4), Layer(1), (695, 137)-STEP(7, 15)
  507.  IF _READBIT(L.Items, 11) THEN _PUTIMAGE (424, 160)-STEP(15, 31), Layer(4), Layer(1), (704, 137)-STEP(7, 15)
  508.  IF _READBIT(L.Items, 12) THEN _PUTIMAGE (416, 128)-STEP(15, 31), Layer(4), Layer(1), (615, 137)-STEP(7, 15) ELSE _PUTIMAGE (416, 128)-STEP(15, 31), Layer(4), Layer(1), (500, 32)-STEP(7, 15) 'blank it
  509.  IF _READBIT(L.Items, 13) THEN _PUTIMAGE (416, 128)-STEP(15, 31), Layer(4), Layer(1), (624, 137)-STEP(7, 15)
  510.  
  511. SUB Display_Selected_Item (ID%%)
  512.  _PUTIMAGE (200, 128)-STEP(15, 31), Layer(4), Layer(1), (500, 32)-STEP(7, 15) 'blank it
  513.  SELECT CASE ID%%
  514.   CASE 0 'no item
  515.   CASE 1 'Boomerang
  516.    IF _READBIT(L.Items, 8) THEN
  517.     _PUTIMAGE (200, 128)-STEP(15, 31), Layer(4), Layer(1), (592, 137)-STEP(7, 15) '
  518.    ELSEIF _READBIT(L.Items, 0) THEN
  519.     _PUTIMAGE (200, 128)-STEP(15, 31), Layer(4), Layer(1), (584, 137)-STEP(7, 15) 'boomerang
  520.    END IF
  521.   CASE 2 'Bomb
  522.    _PUTIMAGE (200, 128)-STEP(15, 31), Layer(4), Layer(1), (604, 137)-STEP(7, 15) '
  523.   CASE 3 'Bow
  524.    _PUTIMAGE (200, 128)-STEP(15, 31), Layer(4), Layer(1), (633, 137)-STEP(7, 15) '
  525.   CASE 4 'Blue Candle
  526.    IF _READBIT(L.Items, 9) THEN
  527.     _PUTIMAGE (200, 128)-STEP(15, 31), Layer(4), Layer(1), (653, 137)-STEP(7, 15) '
  528.    ELSEIF _READBIT(L.Items, 3) THEN
  529.     _PUTIMAGE (200, 128)-STEP(15, 31), Layer(4), Layer(1), (644, 137)-STEP(7, 15) '
  530.    END IF
  531.   CASE 5 'Recorder
  532.    _PUTIMAGE (200, 128)-STEP(15, 31), Layer(4), Layer(1), (664, 137)-STEP(7, 15) '
  533.   CASE 6 'Meat
  534.    _PUTIMAGE (200, 128)-STEP(15, 31), Layer(4), Layer(1), (675, 137)-STEP(7, 15) '
  535.   CASE 7 'Letter
  536.    IF _READBIT(L.Items, 11) THEN
  537.     _PUTIMAGE (200, 128)-STEP(15, 31), Layer(4), Layer(1), (704, 137)-STEP(7, 15) '
  538.    ELSEIF _READBIT(L.Items, 10) THEN
  539.     _PUTIMAGE (200, 128)-STEP(15, 31), Layer(4), Layer(1), (695, 137)-STEP(7, 15) '
  540.    ELSEIF _READBIT(L.Items, 6) THEN
  541.     _PUTIMAGE (200, 128)-STEP(15, 31), Layer(4), Layer(1), (686, 137)-STEP(7, 15) '
  542.    END IF
  543.   CASE 8 'Magical Rod
  544.    _PUTIMAGE (200, 128)-STEP(15, 31), Layer(4), Layer(1), (715, 137)-STEP(7, 15) '
  545.  
  546. SUB Scroll_Overworld_Inventory (Dir%%)
  547.  Build_Overworld_Inventory_Display
  548.  Build_Main_Display
  549.  Place_Link L.Sx, L.Sy, L.Frame
  550.  _PUTIMAGE , Layer(1), Layer(9)
  551.  ClearLayer Layer(1)
  552.  SELECT CASE Dir%%
  553.   CASE TOINVENTORY
  554.    FOR i% = 0 TO 365 STEP 2
  555.     _PUTIMAGE (0, i%), Layer(9), Layer(1)
  556.     _PUTIMAGE (0, 0 - 366 + i%), Layer(8), Layer(1)
  557.     _PUTIMAGE , Layer(1), Layer(0)
  558.     _LIMIT 120
  559.    NEXT
  560.    _PUTIMAGE (0, i%), Layer(9), Layer(1)
  561.    _PUTIMAGE (0, 0 - 366 + i%), Layer(8), Layer(1)
  562.    Display_Inventory
  563.    _PUTIMAGE , Layer(1), Layer(0)
  564.   CASE TOMAP
  565.    FOR i% = 366 TO 0 STEP -2
  566.     _PUTIMAGE (0, i%), Layer(9), Layer(1)
  567.     _PUTIMAGE (0, 0 - 366 + i%), Layer(8), Layer(1)
  568.     _PUTIMAGE , Layer(1), Layer(0)
  569.     _LIMIT 120
  570.    NEXT
  571.  
  572. SUB Build_Overworld_Inventory_Display
  573.  ClearLayer Layer(1)
  574.  Display_Triforce_Container
  575.  Place_Triforce
  576.  Place_Invenorty_Container
  577.  _PUTIMAGE , Layer(1), Layer(8)
  578.  ClearLayer Layer(1)
  579.  
  580. SUB Run_Overworld_Inventory
  581.  ExitFlag%% = FALSE: _KEYCLEAR
  582.  _PUTIMAGE , Layer(0), Layer(11)
  583.  IF L.Items THEN Selection%% = L.Hand_B ELSE Selection%% = 0
  584.  DO
  585.   _PUTIMAGE , Layer(11), Layer(1)
  586.   Display_Inventory_Selection_Box Selection%%
  587.   Display_Selected_Item Selection%%
  588.   _PRINTSTRING (0, 0), STR$(Selection%%), Layer(1)
  589.  
  590.   _PUTIMAGE , Layer(1), Layer(0)
  591.   _LIMIT 30
  592.   IF Selection%% > 0 THEN
  593.  
  594.    IF _KEYDOWN(Key_Right) AND (NOT Key_Lock%%) THEN
  595.     Selection%% = Selection%% + 1: Key_Lock%% = TRUE
  596.     IF Selection%% = 9 THEN Selection%% = 1
  597.     DO
  598.      IF _READBIT(L.Items, Selection%% - 1) THEN
  599.       Good%% = TRUE 'if player has item then allow selection
  600.      ELSE
  601.       Selection%% = Selection%% + 1 'otherwise move to next item
  602.       IF Selection%% = 9 THEN Selection%% = 1
  603.       Good%% = FALSE
  604.      END IF
  605.     LOOP UNTIL Good%%
  606.    END IF
  607.  
  608.    IF _KEYDOWN(Key_Left) AND (NOT Key_Lock%%) THEN
  609.     Selection%% = Selection%% - 1: Key_Lock%% = TRUE
  610.     IF Selection%% = 0 THEN Selection%% = 8
  611.     DO
  612.      IF _READBIT(L.Items, Selection%% - 1) THEN
  613.       Good%% = TRUE 'if player has item then allow selection
  614.      ELSE
  615.       Selection%% = Selection%% - 1 'otherwise move to next item
  616.       IF Selection%% = 0 THEN Selection%% = 8
  617.       Good%% = FALSE
  618.      END IF
  619.     LOOP UNTIL Good%%
  620.    END IF
  621.  
  622.   END IF
  623.   IF _KEYHIT = Start_Button THEN ExitFlag%% = TRUE
  624.   IF NOT _KEYDOWN(Key_Right) AND NOT _KEYDOWN(Key_Left) THEN Key_Lock%% = FALSE
  625.  
  626.  LOOP UNTIL ExitFlag%%
  627.  L.Hand_B = Selection%%
  628.  ClearLayer Layer(11)
  629.  
  630. SUB Display_Inventory_Selection_Box (ID%%)
  631.  STATIC Frame%%
  632.  SELECT CASE Frame%%
  633.   CASE 0 TO 7
  634.    SX% = 519
  635.   CASE 8 TO 15
  636.    SX% = 536
  637.  YO%% = (ID%% - 1) \ 4
  638.  XO%% = (ID%% - 1) MOD 4
  639.  IF ID%% = 0 THEN XO%% = 0
  640.  _PUTIMAGE (320 + (XO%% * 48), 128 + (YO%% * 32))-STEP(31, 31), Layer(4), Layer(1), (SX%, 137)-STEP(15, 15) 'blue
  641.  Frame%% = Frame%% + 1
  642.  IF Frame%% = 16 THEN Frame%% = 0
  643.  
  644. FUNCTION LoadGFX& (Foff&, Size&)
  645.  IF _FILEEXISTS("temp.dat") THEN KILL "temp.dat"
  646.  OPEN "temp.dat" FOR BINARY AS #3
  647.  dat$ = SPACE$(Size&)
  648.  GET #1, Foff&, dat$
  649.  PUT #3, , dat$
  650.  CLOSE #3
  651.  LoadGFX& = _LOADIMAGE("temp.dat", 32)
  652.  
  653. FUNCTION LoadFFX& (Foff&, Size&, Fize%%)
  654.  IF _FILEEXISTS("temp.dat") THEN KILL "temp.dat"
  655.  OPEN "temp.dat" FOR BINARY AS #3
  656.  dat$ = SPACE$(Size&)
  657.  GET #1, Foff&, dat$
  658.  PUT #3, , dat$
  659.  CLOSE #3
  660.  LoadFFX& = _LOADFONT("temp.dat", Fize%%, "monospace")
  661.  
  662. FUNCTION LoadSFX& (Foff&, Size&)
  663.  IF _FILEEXISTS("temp.dat") THEN KILL "temp.dat"
  664.  OPEN "temp.dat" FOR BINARY AS #3
  665.  dat$ = SPACE$(Size&)
  666.  GET #1, Foff&, dat$
  667.  PUT #3, , dat$
  668.  CLOSE #3
  669.  LoadSFX& = _SNDOPEN("temp.dat")
  670.  
  671. SUB LoadData (Foff&, Size&)
  672.  IF _FILEEXISTS("temp.dat") THEN KILL "temp.dat"
  673.  OPEN "temp.dat" FOR BINARY AS #3
  674.  dat$ = SPACE$(Size&)
  675.  GET #1, Foff&, dat$
  676.  PUT #3, , dat$
  677.  CLOSE #3
  678.  
  679.  F1 = FREEFILE
  680.  OPEN "temp.dat" FOR BINARY AS #F1
  681.  CLOSE #F1
  682.  
* Zelda1.MFI (Filesize: 612.94 KB, Downloads: 183)
« Last Edit: April 08, 2020, 09:19:43 pm by Cobalt »
Granted after becoming radioactive I only have a half-life!

Offline 40wattstudio

  • Newbie
  • Posts: 82
    • View Profile
    • 40wattstudio
Re: Hyrule Exploration!
« Reply #1 on: April 11, 2020, 08:31:39 pm »
I'm not familiar with the .mfi extension. Will this program work in Windows 10?

Offline Cobalt

  • QB64 Developer
  • Forum Resident
  • Posts: 878
  • At 60 I become highly radioactive!
    • View Profile
Re: Hyrule Exploration!
« Reply #2 on: April 12, 2020, 10:12:02 am »
What is a MFI file? Look Here.
https://www.qb64.org/forum/index.php?topic=2346.0

if QB64 runs then the demo should run too.
Granted after becoming radioactive I only have a half-life!