Age
AS _BYTE 'as player gains experiance levels they age, age negativliy affects stats. WorldX
AS _BYTE 'players location in over world MapX
AS _BYTE 'players location in a castle\town or cave\temple Map
AS _BYTE 'where is player? -1 to 27 (-1 = over world map) Has_Princess
AS _BYTE 'is player carring Princess?
Attk1
AS _BYTE 'special attack 1 - these are additional options to normal physical attack
Sprite_ID
AS _BYTE 'sprite used on tile Is_Town
AS _BYTE 'Town ID/Castle ID Territory
AS _BYTE 'Monster selection ID, determines which monster are picked for battle Has_Special
AS _BYTE 'does search find something here or is special battle here
Sprite_ID
AS _BYTE 'sprite used on tile Is_Stairs
AS _BYTE 'Where Stairs lead(ID) Territory
AS _BYTE 'Monster selection ID, determines which monster are picked for battle Is_Exit
AS _BYTE 'does tile lead out of castle or town Has_Special
AS _BYTE 'does search find something here or is special battle here
Start_X
AS _BYTE 'when Entering where do you start. Is_Lit
AS _BYTE 'is a Torch or Radiant needed to see?
Direction
AS _BYTE 'going up or down Link
AS _BYTE 'links to which other stairs
TYPE Non_Playable_Character
Map
AS _BYTE 'Which town\castle\cave do they live in Lines
AS _BYTE 'What lines do they say Flags
AS _BYTE 'used if they change what they say over time
JustLeft
AS _BYTE 'if player just left town\castle don't reprocess location In_Place
AS _BYTE 'player is in a town\castle LastMove
AS LONG 'timer, if player doesn't press any keys his current stats display Menu
AS _BYTE 'does player have the menu up? Selection
AS _BYTE 'what selection did player make from menu Input_Wait
AS _BYTE 'waiting for player input, after message display Action
AS _BYTE 'what action is player currently performing?(talk,search,stair,take,door,spell,item) Lite_Level
AS _BYTE 'how much light is there 0-none, 1-torch 2&3-Radiant Talk_To
AS _BYTE 'who is the player talking to? Current_BGM
AS _BYTE 'which music is currently in background
Has_Left_Throne_Room
AS _BYTE 'set when Player first leave thrown room after starting game. Just_Started
AS _BYTE 'Set when player first starts game
CONST DOWN
= 0, LEFT
= 1, UP
= 2, RIGHT
= 3 CONST Key_Right
= 19712, Key_Left
= 19200, Key_Up
= 18432, Key_Down
= 20480 CONST A_Button
= 32, B_Button
= 13, Start_Button
= 65, Select_Button
= 66 CONST MoveDown
= 1, MoveLeft
= 2, MoveUp
= 3, MoveRight
= 4 CONST Talking
= 1, Stairs
= 2, Searching
= 3, Spells
= 4, Items
= 5, Doors
= 6, Taking
= 7
DIM SHARED Place
(27, 45, 45) AS Tiles_B
, PD
(-1 TO 27) AS Place_Data
, Stairs
(127) AS Stair_Data
MFI_Loader "DragonW.MFI"
'selection arrows for command window
DATA 13,4,13,6,13,8,13,10,21,4,21,6,21,8,21,10,0,0,0,0 READ SA
(i%%
).X
, SA
(i%%
).Y
'-----------------------------------
Layer
(2) = _NEWIMAGE(255 * 32, 255 * 32, 32) 'world map'Layer(3) = _LOADIMAGE("tilebase2.bmp", 32)
'Layer(4) = _LOADIMAGE("characters.bmp", 32)
Layer
(6) = _NEWIMAGE(640, 128, 32) 'temp layer to scroll textLayer
(7) = _NEWIMAGE(46 * 32, 46 * 32, 32) 'map layerLayer
(8) = _NEWIMAGE(46 * 32, 46 * 32, 32) 'NPC sprite layerLayer
(9) = _NEWIMAGE(640, 480, 32) 'debug info layer'Layer(10) = _LOADIMAGE("controller.bmp", 32)
Layer
(11) = _NEWIMAGE(640, 480, 32) 'light mask for undergroundLayer
(12) = _NEWIMAGE(46 * 32, 46 * 32, 32) 'NPC sprite Clear layer
'DWFont = _LOADFONT("DW1.ttf", 16, "Monospace")
PRINT "Building world..."
Init_Player 0
P(0).Nam = "Newton"
Build_World_Layer Layer(2)
Build_Place_Layer Layer(7), P(0).Map
who%% = 0
'G.Input_Wait = TRUE
'F.Just_Started = TRUE
BGM(13) = BGM(3)
BGM(5) = BGM(3)
BGM(20) = BGM(3)
BGM(25) = BGM(3)
'_SNDVOL BGM(13), .09
Change_BGM 0
IF P
(0).Map
>= 0 THEN L%%
= 7: PMX%%
= P
(0).MapX: PMY%%
= P
(0).MapY
ELSE L%%
= 2: PMX%%
= P
(0).WorldX: PMY%%
= P
(0).WorldY
IF NOT F.Message_Displaying
THEN Result%%
= Controls
(0) IF Result%%
= TRUE
THEN ExitFlag%%
= TRUE
Copy_Map_Layer Layer(L%%), PMX%% + WX%%, PMY%% + WY%%
Draw_NPC_Sprites 0, 117, Layer(8)
Copy_NPC_Layer Layer(8), PMX%% + WX%%, PMY%% + WY%%
Draw_Player_Sprite 0, Layer(1)
IF G.Menu
THEN Draw_Command_Window Layer
(1) IF G.Message
THEN Draw_Info_Window Layer
(1): Message_Handler Layer
(5), "" IF G.Display_Status
THEN Display_Player_Status Layer
(5) ' IF G.Action = Talking THEN TalktoNPC G.Talk_To
Debuginfo
'_DELAY .124
Process_NPC
Frames% = Frames% + 1
G.f = Frames%
Frames% = 0
IF NPC
(i%%
).Can_Move
THEN 'only move NPC that are not stationary IF NPC
(i%%
).Moving
THEN NPC_Move_Cycle i%%
IF Chance
> 250 AND NPC
(i%%
).Moving
= 0 THEN 'start the NPC moving SELECT CASE NPC
(i%%
).Facing
'make sure NPC can move that direction Blocked%% = NPC_Collision(i%%, 0, -1)
Blocked%% = NPC_Collision(i%%, 0, 1)
Blocked%% = NPC_Collision(i%%, -1, 0)
Blocked%% = NPC_Collision(i%%, 1, 0)
IF Chance
< 3 AND NPC
(i%%
).Moving
= 0 THEN Turn_NPC i%%
IF NPC
(i%%
).X
= 0 THEN i%%
= 122 'reached the end of NPC list
SUB NPC_Move_Cycle
(who%%
) NPC(who%%).Moving = NPC(who%%).Moving + 2
IF NPC
(who%%
).Moving
= 32 THEN Move_NPC who%%: NPC
(who%%
).Moving
= 0 NPC(who%%).MY = -NPC(who%%).Moving
NPC(who%%).MX = NPC(who%%).Moving
NPC(who%%).MX = -NPC(who%%).Moving
NPC(who%%).MY = NPC(who%%).Moving
NPC(who%%).Y = NPC(who%%).Y - 1
NPC(who%%).Y = NPC(who%%).Y + 1
NPC(who%%).X = NPC(who%%).X - 1
NPC(who%%).X = NPC(who%%).X + 1
T~%% = Chance
NPC(who%%).Facing = UP
NPC(who%%).Facing = DOWN
NPC(who%%).Facing = LEFT
NPC(who%%).Facing = RIGHT
FUNCTION NPC_Collision%%
(Who%%
, X%%
, Y%%
) Result%% = TRUE
SELECT CASE Place
(NPC
(Who%%
).Map
, NPC
(Who%%
).X
+ X%%
, NPC
(Who%%
).Y
+ Y%%
).Sprite_ID
Result%% = FALSE
'dont let NPC leave map
IF Place
(NPC
(Who%%
).Map
, NPC
(Who%%
).X
+ X%%
, NPC
(Who%%
).Y
+ Y%%
).Is_Exit
THEN Result%%
= TRUE
IF NOT Result%%
THEN 'check for NPC collision FOR i%%
= 0 TO 120 '<--update when actual NPC count is known IF NPC
(Who%%
).X
+ X%%
= NPC
(i%%
).X
AND NPC
(Who%%
).Y
+ Y%%
= NPC
(i%%
).Y
AND NPC
(Who%%
).Map
= NPC
(i%%
).Map
THEN Result%% = TRUE: i%% = 122
IF NPC
(i%%
).X
= 0 THEN i%%
= 122 'no NPC can occupy a 0 location so we know we are past the last NPC
IF NOT Result%%
THEN 'check for collision with player IF NPC
(Who%%
).X
+ X%%
= P
(0).MapX
AND NPC
(Who%%
).Y
+ Y%%
= P
(0).MapY
AND NPC
(Who%%
).Map
= P
(0).Map
THEN Result%%
= TRUE
NPC_Collision = Result%%
Run_Talk
Run_Status
Run_Stairs
Run_search
Run_Spell
Run_Item
Run_Door
Run_Take
Who%% = Find_NPC(P(0).Facing)
G.Message = 15
G.Message = Lines(Who%%, 0, 1)
IF G.Message
= 0 THEN G.Message
= 360 G.Action = FALSE
G.Display_Status = TRUE
G.Input_Wait = TRUE
IF dialog
= 1 THEN G.Message
= 238: G.Action
= FALSE: dialog
= 0 IF dialog
= 0 THEN G.Message
= 237: dialog
= dialog
+ 1
G.Message = 48
G.Message = 60
G.Message = 311 'no door
'g.message = 312 'no keys
G.Message = 242
IF Place
(P
(who%%
).Map
, P
(who%%
).MapX
, P
(who%%
).MapY
).Is_Stairs
THEN IF NOT F.Has_Left_Throne_Room
THEN F.Has_Left_Throne_Room
= TRUE
'if player has just started game
P(who%%).Map = Stairs(Place(P(who%%).Map, P(who%%).MapX, P(who%%).MapY).Is_Stairs).Link
'get location information from the linked stair Record.
P(who%%).MapX = Stairs(P(who%%).Map).X
P(who%%).MapY = Stairs(P(who%%).Map).Y
IF Stairs
(P
(who%%
).Map
).Map
= -1 THEN P
(who%%
).WorldX
= Stairs
(P
(who%%
).Map
).X: P
(who%%
).WorldY
= Stairs
(P
(who%%
).Map
).Y
P(who%%).Map = Stairs(P(who%%).Map).Map
IF P
(who%%
).Map
>= 0 THEN Build_Place_Layer Layer
(7), P
(who%%
).Map
Change_BGM 0
G.Menu = FALSE
G.Message = 13
IF World
(P
(who%%
).WorldX
, P
(who%%
).WorldY
).Is_Stairs
THEN P(who%%).Map = Stairs(World(P(who%%).WorldX, P(who%%).WorldY).Is_Stairs).Link
'get location information from the linked stair Record.
P(who%%).MapX = Stairs(P(who%%).Map).X
P(who%%).MapY = Stairs(P(who%%).Map).Y
P(who%%).Map = Stairs(P(who%%).Map).Map
Build_Place_Layer Layer(7), P(who%%).Map
G.Menu = FALSE
Change_BGM 0
G.Message = 13
SUB Check_Location_World
(who%%
)
IF World
(P
(who%%
).WorldX
, P
(who%%
).WorldY
).Is_Town
AND G.In_Place
= FALSE
THEN P(who%%).Map = World(P(who%%).WorldX, P(who%%).WorldY).Is_Town
IF P
(who%%
).Map
= 1 THEN P
(who%%
).Map
= 0 P(who%%).MapX = PD(P(who%%).Map).Start_X
P(who%%).MapY = PD(P(who%%).Map).Start_Y
Build_Place_Layer Layer(7), P(who%%).Map
Change_BGM 0
G.In_Place = TRUE
IF World
(P
(who%%
).WorldX
, P
(who%%
).WorldY
).Sprite_ID
= 5 THEN _DELAY .05 'slow movement when crossing hills
' IF World(P(who%%).WorldX, P(who%%).WorldY).Is_Cave THEN P(who%%).Map = World(P(who%%).WorldX, P(who%%).WorldY).Is_Town
SUB Check_Location_Place
(who%%
) IF Place
(P
(who%%
).Map
, P
(who%%
).MapX
, P
(who%%
).MapY
).Is_Exit
THEN P
(who%%
).Map
= -1: G.JustLeft
= TRUE: Change_BGM
0
Move = Move + 2
IF Move
= 32 THEN Move
= 0: G.Flag
= FALSE
IF Move
= 30 THEN Move_Player Who%%
G.Y = -Move
G.X = Move
G.X = -Move
G.Y = Move
P(who%%).MapY = P(who%%).MapY - 1
P(who%%).MapY = P(who%%).MapY + 1
P(who%%).MapX = P(who%%).MapX - 1
P(who%%).MapX = P(who%%).MapX + 1
Check_Location_Place who%%
P(who%%).WorldY = P(who%%).WorldY - 1
P(who%%).WorldY = P(who%%).WorldY + 1
P(who%%).WorldX = P(who%%).WorldX - 1
P(who%%).WorldX = P(who%%).WorldX + 1
IF G.JustLeft
THEN G.JustLeft
= FALSE
IF G.In_Place
THEN G.In_Place
= FALSE
Check_Location_World who%%
Result%% = FALSE
IF G.Selection
<> 1 THEN G.Selection
= 1 IF P
(who%%
).Facing
<> RIGHT
THEN P
(who%%
).Facing
= RIGHT
IF NOT Collision
(who%%
, 1, 0) THEN G.Flag
= TRUE
IF P
(who%%
).Facing
<> LEFT
THEN P
(who%%
).Facing
= LEFT
IF NOT Collision
(who%%
, -1, 0) THEN G.Flag
= TRUE
IF P
(who%%
).Facing
<> UP
THEN P
(who%%
).Facing
= UP
IF NOT Collision
(who%%
, 0, -1) THEN G.Flag
= TRUE
IF P
(who%%
).Facing
<> DOWN
THEN P
(who%%
).Facing
= DOWN
IF NOT Collision
(who%%
, 0, 1) THEN G.Flag
= TRUE
IF KBD&
= A_Button
THEN G.Menu
= TRUE: G.LastMove
= G.LastMove
- 2
IF KBD&
= B_Button
OR KBD&
= A_Button
THEN G.Menu
= FALSE: G.Input_Wait
= FALSE: G.Message
= 0: ClearLayer Layer
(5):
_CLEARCOLOR _RGB32(0, 0, 0), Layer
(5) IF G.Display_Status
THEN G.Display_Status
= FALSE
IF KBD&
= Key_Up
AND G.Selection
> 1 AND G.Selection
<> 5 THEN G.Selection
= G.Selection
- 1 IF KBD&
= Key_Down
AND G.Selection
< 8 AND G.Selection
<> 4 THEN G.Selection
= G.Selection
+ 1 IF KBD&
= Key_Left
AND G.Selection
> 4 THEN G.Selection
= G.Selection
- 4 IF KBD&
= Key_Right
AND G.Selection
< 5 THEN G.Selection
= G.Selection
+ 4
IF KBD&
= B_Button
THEN G.Menu
= FALSE
IF KBD&
= A_Button
THEN Process_Command
IF KBD&
= 27 THEN Result%%
= TRUE
Controls = Result%%
'---------------Player starting stats-----------------------
P
(Who%%
).Max_HP
= INT(RND * 8) + 12 'start 12-20hp P(Who%%).HP = P(Who%%).Max_HP
IF INT(RND * 100) = 95 THEN P
(Who%%
).Max_MP
= INT(RND * 3) + 4 '1 in 100 chance of starting with magical powers P(Who%%).MP = P(Who%%).Max_MP
P
(Who%%
).Strength
= INT(RND * 3) + 2 'determines base attack damage P
(Who%%
).Agility
= INT(RND * 2) + 2 'determines base defence\evasion P
(Who%%
).Luck
= INT(RND * 5) 'a "chance" bonus to hits and evasions P(Who%%).Level = 0 'starting at base; first fight elevates to level 1, no xp gain though
P(Who%%).Age = 17 'level adds to age *1.5 (level 10 adds 15 to age, 20 adds 30, 30 adds 45, max age 72!)
' age affects Strength by subtracting INT((-5 + (Age - 20)) * (.15 + ((Age-17)/100))-.49) ; youth gives strength
' age affects Agility by subtracting INT((-8 + (Age - 20)) * (.4 + ((Age-17)/100))-.49) ; youth gives great agility, age loses agility quickly
' age affects Luck by adding (0 + (Age - 25)) * (.4 + ((Age-17)/50)) ; age adds luck
P(Who%%).Weapon = 0 'adds to Attack strength , start with Fists
P(Who%%).Armor = 8 'adds to Defensive strength , start with Loin Cloth
P(Who%%).Shield = 16 'adds to Defensive strength , start with None
P(Who%%).Gold = 0
P(Who%%).WorldX = 44
P(Who%%).WorldY = 44
P(Who%%).MapX = 17 'when starting game player always starts here
P(Who%%).MapY = 18
P(Who%%).Map = 1
'-----------------------------------------------------------
CASE 0 'can only see player CASE 1 'one block around player visable CASE 2 'two blocks around player CASE 3 'three blocks around player
SUB Message_Handler
(L&
, MSG$
)
IF Message_Length
= 0 THEN 'start of new message F.Message_Displaying = TRUE
MYL = 1
Processed
= Process_Message_Coding$
(Script
(G.Message
)): Message_Length
= LEN(Processed
) Message_Length
= LEN(Script
(G.Message
)) Processed = Script(G.Message)
'check message length word wrap if needed
IF Message_Length
> 22 AND LineCount
= 0 THEN LineCount
= Process_Word_Wrap
(Lines
(), Processed
) IF Message_Length
<= 22 THEN LineCount
= 1: Lines
(1) = Processed
Slowit = Slowit + 1
IF Slowit
= 4 THEN Slowit
= 0: Current_Char
= Current_Char
+ 1:
_SNDPLAY SFX
(3)
_PRINTSTRING (80, 288 + 16 * MYL
), MID$(Lines
(MYL
), 1, Current_Char
), L&
'print message 1 character at a time.
IF Current_Char
= LEN(RTRIM$(Lines
(MYL
))) THEN MYL
= MYL
+ 1: Current_Char
= 0 IF MYL
= LineCount
+ 1 THEN 'if the message is done then reset everything and wait for input G.Input_Wait = TRUE: Processed = "": Message_Length = 0
MYL = 0: Lines(1) = "": LineCount = 0
F.Message_Displaying = FALSE
FOR i~%%
= 1 TO LEN(Txt$
) 'check message for formating Result$
= Result$
+ RTRIM$(M
(battle%%
).Nam
) i~%% = i~%% + 1
Result$
= Result$
+ RTRIM$(P
(who%%
).Nam
) i~%% = i~%% + 1
Result$
= Result$
+ RTRIM$(I
(which%%
).Nam
) i~%% = i~%% + 1
'Processed = Processed + MID$(Script(G.Message), i~%%, 1)
G.YES_NO_Input = TRUE
i~%% = i~%% + 1
Result$
= Result$
+ MID$(Txt$
, i~%%
, 1)
Process_Message_Coding = Result$
'up arrow
LINE (128, 128)-(32, 132), _RGB32(255, 127, 0), BF
LINE (32, 460)-(212, 464), _RGB32(255, 127, 0), BF
'left arrow
'down arrow
LINE (128, 212)-(64, 216), _RGB32(0, 127, 255), BF
LINE (64, 372)-(256, 376), _RGB32(0, 127, 255), BF
'right arrow
LINE (176, 184)-(180, 240), _RGB32(0, 64, 160), BF
'select
LINE (264, 212)-(268, 460), _RGB32(255, 64, 0), BF
LINE (264, 460)-(416, 464), _RGB32(255, 64, 0), BF
'start
LINE (328, 212)-(332, 416), _RGB32(212, 0, 16), BF
LINE (328, 416)-(496, 420), _RGB32(212, 0, 16), BF
'B Button
LINE (426, 208)-(430, 256), _RGB32(64, 92, 212), BF
LINE (340, 256)-(430, 260), _RGB32(64, 92, 212), BF
LINE (340, 260)-(344, 376), _RGB32(64, 92, 212), BF
LINE (340, 372)-(496, 376), _RGB32(64, 92, 212), BF
'A Button
LINE (496, 208)-(500, 272), _RGB32(80, 64, 180), BF
LINE (356, 272)-(500, 276), _RGB32(80, 64, 180), BF
LINE (356, 272)-(360, 328), _RGB32(80, 64, 180), BF
LINE (356, 328)-(528, 332), _RGB32(80, 64, 180), BF
GET #1, , c~%%
'retrieve number of files FOffset&(I~%%) = FOffset&(I~%%) + 1
Layer(10) = LoadGFX(FOffset(1), Size(1))
Layer(3) = LoadGFX(FOffset(2), Size(2))
Layer(4) = LoadGFX(FOffset(3), Size(3))
BGM(-1) = LoadSFX(FOffset(4), Size(4))
BGM(0) = LoadSFX(FOffset(10), Size(10))
BGM(1) = LoadSFX(FOffset(12), Size(12))
BGM(3) = LoadSFX(FOffset(12), Size(12))
SFX(0) = LoadSFX(FOffset(5), Size(5))
SFX(1) = LoadSFX(FOffset(8), Size(8))
SFX(2) = LoadSFX(FOffset(9), Size(9))
SFX(3) = LoadSFX(FOffset(11), Size(11))
LoadData FOffset(6), Size(6)
DWFont = LoadFFX(FOffset(7), Size(7), 16)
FUNCTION LoadFFX&
(Foff&
, Size&
, Fize%%
) LoadFFX&
= _LOADFONT("temp.dat", Fize%%
, "monospace")
SUB LoadData
(Foff&
, Size&
)
' OPEN "GameDataV1_1b.dat" FOR BINARY AS #1
IF P
(who%%
).Map
<> G.Current_BGM
THEN _SNDSTOP BGM
(G.Current_BGM
) 'stop the old music _SNDLOOP BGM
(P
(who%%
).Map
) ' start the new music G.Current_BGM = P(who%%).Map ' store which music is now playing
Result%% = -1
X%% = 0: Y%% = 0
Y%% = -1
Y%% = 1
X%% = -1
X%% = 1
IF NPC
(i%%
).Map
= P
(0).Map
THEN IF NPC
(i%%
).X
= P
(0).MapX
+ X%%
AND NPC
(i%%
).Y
= P
(0).MapY
+ Y%%
THEN Result%%
= i%%: i%%
= 127 IF NPC
(i%%
).X
= 0 THEN i%%
= 127 Find_NPC = Result%%
SUB NPC_Monologue
(Who%%
) old%% = NPC(Who%%).Moving
NPC(Who%%).Moving = FALSE 'make sure NPC does not walk away while we are talking to them
G.Message = Lines(Who%%, 0, 1)
' IF INKEY$ = CHR$(27) THEN exitflag%% = TRUE
IF NOT F.Message_Displaying
THEN Result%%
= Controls
(0) IF Result%%
= TRUE
THEN ExitFlag%%
= TRUE
Draw_Info_Window Layer(1): Message_Handler Layer(5), ""
Debuginfo
Process_NPC
Frames% = Frames% + 1
G.Input_Wait = FALSE
ClearLayer Layer(5)
G.Message = 0
NPC(Who%%).Moving = old%%
G.YES_NO_Input = TRUE
REM'$include:'FinishedRoutines.bas' Result%% = TRUE
IF P
(Who%%
).Map
>= 0 THEN 'check place map SELECT CASE Place
(P
(Who%%
).Map
, P
(Who%%
).MapX
+ X%%
, P
(Who%%
).MapY
+ Y%%
).Sprite_ID
Result%% = FALSE
IF NOT Result%%
THEN 'check for NPC collision FOR i%%
= 0 TO 120 '<--update when actual NPC count is known IF P
(Who%%
).MapX
+ X%%
= NPC
(i%%
).X
AND P
(Who%%
).MapY
+ Y%%
= NPC
(i%%
).Y
AND P
(Who%%
).Map
= NPC
(i%%
).Map
THEN Result%% = TRUE: i%% = 122
IF NPC
(i%%
).X
= 0 THEN i%%
= 122 'no NPC can occupy a 0 location so we know we are past the last NPC
SELECT CASE World
(P
(Who%%
).WorldX
+ X%%
, P
(Who%%
).WorldY
+ Y%%
).Sprite_ID
Result%% = FALSE
Collision = Result%%
SUB Copy_Map_Layer
(L&
, MX%%
, MY%%
) _PUTIMAGE (16, 16), L&
, Layer
(1), (MX%%
* 32 - 240 + G.X
, MY%%
* 32 - 208 + G.Y
)-STEP(495, 447) _PUTIMAGE (16, 16), L&
, Layer
(1), (128 + MX%%
* 32 - 240 + G.X
, 128 + MY%%
* 32 - 208 + G.Y
)-STEP(495, 447)
SUB Draw_Window
(X%%
, Y%%
, Xs%%
, Ys%%
, L&
) 'top corners of window
_PUTIMAGE (X%%
* 16 + Xs%%
* 16, Y%%
* 16)-STEP(15, 15), Layer
(3), L&
, (8, 18)-STEP(7, 7) 'bottom corners of window
_PUTIMAGE (X%%
* 16, Y%%
* 16 + Ys%%
* 16)-STEP(15, 15), Layer
(3), L&
, (16, 18)-STEP(7, 7) _PUTIMAGE (X%%
* 16 + Xs%%
* 16, Y%%
* 16 + Ys%%
* 16)-STEP(15, 15), Layer
(3), L&
, (24, 18)-STEP(7, 7) 'top and bottom of window
_PUTIMAGE (X%%
* 16 + i%%
* 16, Y%%
* 16)-STEP(15, 15), Layer
(3), L&
, (56, 18)-STEP(7, 7) _PUTIMAGE (X%%
* 16 + i%%
* 16, Y%%
* 16 + Ys%%
* 16)-STEP(15, 15), Layer
(3), L&
, (48, 18)-STEP(7, 7) 'left and right sides of window
_PUTIMAGE (X%%
* 16, Y%%
* 16 + 16 * i%%
)-STEP(15, 15), Layer
(3), L&
, (32, 18)-STEP(7, 7) _PUTIMAGE (X%%
* 16 + Xs%%
* 16, Y%%
* 16 + 16 * i%%
)-STEP(15, 15), Layer
(3), L&
, (40, 18)-STEP(7, 7) 'fill in window
_PUTIMAGE ((X%%
+ 1) * 16, (Y%%
+ 1) * 16)-STEP((Xs%%
- 1) * 16, (Ys%%
- 1) * 16), Layer
(3), L&
, (307, 1)-STEP(15, 15)
SUB Draw_Command_Window
(L&
) Draw_Window 12, 2, 15, 9, Layer(1)
_PUTIMAGE (16 * 16 - 2, 2 * 16)-STEP(7 * 15 + 4, 1 * 15), Layer
(3), Layer
(1), (205, 35)-STEP(15, 15) Display_Selection_Arrow SA(G.Selection).X, SA(G.Selection).Y, L&
SUB Display_Selection_Arrow
(X%%
, Y%%
, L&
)
SUB Draw_Stat_Window
(L&
, Who%%
) Draw_Window 2, 4, 7, 11, Layer(1)
_PUTIMAGE (4 * 16 - 2, 4 * 16)-STEP(4 * 15 + 4, 1 * 15), Layer
(3), Layer
(1), (205, 35)-STEP(15, 15)
SUB Draw_Info_Window
(L&
) Draw_Window 4, 18, 23, 9, L&
SUB Build_World_Layer
(L&
) _PUTIMAGE (32 * X~%%
, 32 * Y~%%
)-STEP(31, 31), Layer
(3), L&
, (1 + 17 * 14, 1)-STEP(15, 15) _PUTIMAGE (128 + 32 * X%%
, 128 + 32 * Y%%
)-STEP(31, 31), Layer
(3), L&
, (1 + 17 * World
(X%%
, Y%%
).Sprite_ID
, 1)-STEP(15, 15)
SUB Build_Place_Layer
(L&
, ID%%
) _PUTIMAGE (0 + 32 * X%%
, 0 + 32 * Y%%
)-STEP(31, 31), Layer
(3), L&
, (1 + 17 * Place
(ID%%
, X%%
, Y%%
).Sprite_ID
, 1)-STEP(15, 15)
SUB Display_Player_Status
(L&
) Draw_Window 10, 6, 19, 21, L&
V1$
= RTRIM$(I
(P
(who%%
).Weapon
).Nam
) V1$
= MID$(I
(P
(who%%
).Weapon
).Nam
, 1, INSTR(I
(P
(who%%
).Weapon
).Nam
, CHR$(32)))
V1$
= RTRIM$(I
(P
(who%%
).Armor
).Nam
) V1$
= MID$(I
(P
(who%%
).Armor
).Nam
, 1, INSTR(I
(P
(who%%
).Armor
).Nam
, CHR$(32)))
V1$
= RTRIM$(I
(P
(who%%
).Shield
).Nam
) V1$
= MID$(I
(P
(who%%
).Shield
).Nam
, 1, INSTR(I
(P
(who%%
).Shield
).Nam
, CHR$(32)))
SUB Copy_NPC_Layer
(L&
, MX%%
, MY%%
) _PUTIMAGE (16, 16), L&
, Layer
(1), (MX%%
* 32 - 240 + G.X
, MY%%
* 32 - 208 + G.Y
)-STEP(495, 447)
Result%% = 1: I%% = 1
'start on character 22 and work back to a space
x%% = 22: Space%% = FALSE
Lines
(I%%
) = MID$(txt$
, 1, x%%
) txt$
= MID$(txt$
, x%%
+ 1) I%% = I%% + 1
Lines(I%%) = txt$ 'put the last of the text into a line
Result%% = I%%
Process_Word_Wrap = Result%%
SUB Put_Player_In_Place
(Who%%
) 'build map of players location
Build_Place_Layer Layer(7), P(Who%%).Map
'place player at entry point
P(Who%%).MapX = PD(P(Who%%).Map).Start_X
P(Who%%).MapY = PD(P(Who%%).Map).Start_Y
SUB Draw_Player_Sprite
(Who%%
, L&
) IF P
(Who%%
).Weapon
AND P
(Who%%
).Shield
> 16 THEN 'pick which sprite set to use Y1%% = 3 'has a shield and weapon
Y1%% = 1 'only has weapon
Y1%% = 2 'on has shield
Y1%% = 0 'has nothing
IF P
(Who%%
).Armor
> 9 THEN Y1%%
= Y1%%
+ 4 'player has armor
IF P
(Who%%
).Has_Princess
THEN Y1%%
= 8 'if player is returning princess over-ride tile set
SX% = 3 + (Frame%% * 16) + (P(Who%%).Facing * 32)
SY% = 4 + (Y1%% * 18)
SUB Draw_NPC_Sprites
(Who%%
, Count%%
, L&
) ClearLayerADV L&
IF P
(Who%%
).Map
= NPC
(i%%
).Map
THEN SX% = 3 + (Frame%% * 16) + (NPC(i%%).Facing * 32)
SY% = 4 + (NPC(i%%).Sprite_ID * 18)
_PUTIMAGE (NPC
(i%%
).X
* 32 + NPC
(i%%
).MX
, NPC
(i%%
).Y
* 32 + NPC
(i%%
).MY
)-STEP(31, 31), Layer
(4), L&
, (SX%
, SY%
)-STEP(15, 15)
REM'$include:'CoreFunctions.bas' SUB Add_To_Inventory
(Who%%
, Item%%
, Count%%
) STATIC m
AS _MEM 'no need to initialize/free it over and over m
= _MEM(P
(Who%%
)) 'Just change where you want to point it to. Pack = m.OFFSET + 28 'æmove to where P(Who%%).Pack starts at in memory
Match%% = FALSE
_MEMPUT m
, Pack
+ P
(Who%%
).Items
* 2, Item%%
'POKE _MEMPUT m
, Pack
+ P
(Who%%
).Items
* 2 + 1, Count%%
'POKE P(Who%%).Items = P(Who%%).Items + 1
temp%% = temp%% + 1
_MEMPUT m
, Pack
+ Match%%
* 2 + 1, Count%%
'POKE
SUB Remove_Inventory
(who%%
, Item%%
, Count%%
) STATIC m
AS _MEM 'no need to initialize/free it over and over m
= _MEM(P
(who%%
)) 'Just change where you want to point it to. Pack = m.OFFSET + 28 'æmove to where P(Who%%).Pack starts at in memory
Match%% = FALSE
FOR i%%
= 0 TO 15 'find the item 'something went horribly wrong!
temp%% = temp%% - Count%%
IF temp%%
= 0 THEN 'item is out so remove from inventory temp$
= LEFT$(temp$
, Match%%
* 2) + MID$(temp$
, 2 * Match%%
+ 3) P(who%%).Items = P(who%%).Items - 1
FOR i%%
= l%%
TO 31 'pad temp$ to full 32 characters
_MEMPUT m
, Pack
, temp$
'put invetory back _MEMPUT m
, Pack
+ Match%%
* 2 + 1, temp%%
'put adjusted count back
SUB Drop_Inventory
(Who%%
, ID%%
) STATIC m
AS _MEM 'no need to initialize/free it over and over m
= _MEM(P
(Who%%
)) 'Just change where you want to point it to. Pack = m.OFFSET + 28 'æmove to where P(Who%%).Pack starts at in memory
Match%% = FALSE
FOR i%%
= 0 TO 15 'find the item 'something went horribly wrong!
temp$
= LEFT$(temp$
, Match%%
* 2) + MID$(temp$
, 2 * Match%%
+ 3) P(Who%%).Items = P(Who%%).Items - 1
FOR i%%
= l%%
TO 31 'pad temp$ to full 32 characters
_MEMPUT m
, Pack
, temp$
'put invetory back
P(Who%%).Level = P(Who%%).Level + 1
P
(Who%%
).Age
= P
(Who%%
).Age
+ INT(P
(Who%%
).Level
* 1.5 - .49) P
(Who%%
).Strength
= P
(Who%%
).Strength
+ INT(RND * 6) + 1 - INT((-5 + (P
(Who%%
).Age
- 20)) * (.15 + ((P
(Who%%
).Age
- 17) / 100)) - .49) P
(Who%%
).Agility
= P
(Who%%
).Agility
+ INT(RND * 6) + 1 - INT((-8 + (P
(Who%%
).Age
- 20)) * (.4 + ((P
(Who%%
).Age
- 17) / 100)) - .49) P
(Who%%
).Luck
= P
(Who%%
).Luck
+ INT(RND * 3) + INT(0 + (P
(Who%%
).Age
- 25)) * (.4 + ((P
(Who%%
).Age
- 17) / 50) + .49) P
(Who%%
).Max_HP
= P
(Who%%
).Max_HP
+ INT(RND * 10 - (P
(Who%%
).Age
/ 10)) + 1 P
(Who%%
).Max_MP
= P
(Who%%
).Max_MP
+ INT(RND * 5 + (P
(Who%%
).Age
/ 10))
FUNCTION Player_Battle_Defense~%%
(who%%
) 'compute primary Defense value
Result~%% = Player_Defense(who%%)
'now check for luck bonus good or bad
IF INT(RND * 255) <= (P
(who%%
).Luck \
2) THEN 'if random chance is less than half player luck then give luck adjustment Result~%%
= Result~%%
+ INT(RND * (P
(who%%
).Luck
* 2) - (P
(who%%
).Luck
- (P
(who%%
).Age
* 2))) Player_Battle_Defense = Result~%%
'compute defense value to display in status window and to use in battle defense function
Result~%%
= INT(P
(who%%
).Agility
/ 2 - .49) + I
(P
(who%%
).Armor
).Power
+ I
(P
(who%%
).Shield
).Power
Player_Defense = Result~%%
'Compute Attack value to display in status window and to use in battle attack function
Result~%%
= INT(P
(who%%
).Strength
) + I
(P
(who%%
).Weapon
).Power
Player_Attack = Result~%%
FUNCTION Player_Battle_Attack~%%
(who%%
) 'get primary attack value
Result~%% = Player_Attack(who%%)
C~%% = Chance
IF C~%%
< (P
(who%%
).Luck \
2) THEN 'if random chance is less than half player luck then give luck adjustment Result~%%
= Result~%%
+ INT(RND * (P
(who%%
).Luck
* 2) - (P
(who%%
).Luck
- (P
(who%%
).Age
* 2))) ELSEIF C~%%
>= (128 - P
(who%%
).Luck
/ 16) AND C~%%
<= (128 + P
(who%%
).Luck
/ 16) THEN 'critical hit Result~%%
= Result~%%
+ INT(Result~%%
* .25) 'add 25% to hit value Player_Battle_Attack = Result~%%
IF Player_Battle_Defense
(Who%%
) / 2 > M
(ID%%
).Strength
THEN Miss%%
= INT(M
(ID%%
).Strength
+ 4 / 6) ELSE Miss%%
= FALSE
Low~%% = (M(ID%%).Strength - Player_Battle_Defense(Who%%) / 2) / 4
High~%% = (M(ID%%).Strength - Player_Battle_Defense(Who%%) / 2) / 2
IF (Chance
< P
(Who%%
).Luck
/ 4) THEN 'player evades attack(-1) Result%% = TRUE
ELSEIF Miss%%
>= 0 THEN 'not really a miss just a weak hit Result%% = Miss%%
ELSE 'normal attack damage Result%%
= INT(RND * (High~%%
- Low~%%
)) + Low~%%
IF Chance
+ P
(who%%
).Luck
/ 2 > 228 THEN 'critical hit Low~%% = (Player_Battle_Attack(who%%) / 2)
High~%% = (Player_Battle_Attack(who%%))
Low~%% = (Player_Battle_Attack(who%%) - M(ID%%).Agility / 2) / 4
High~%% = (Player_Battle_Attack(who%%) - M(ID%%).Agility / 2) / 2
Result~%%
= INT(RND * (High~%%
- Low~%%
)) + Low~%%
IF Chance
+ (P
(who%%
).Luck
/ 2) > 127 THEN Result~%%
= 1 Player_Damage = Result~%%
IF Player_Attack
(Who%%
) >= M
(ID%%
).Strength
* 2 THEN IF Chance
> 192 THEN Result%%
= TRUE
ELSE Result%%
= FALSE
Enemy_Flee = Result%%
IF P
(Who%%
).Agility
* Chance
< M
(Id%%
).Agility
* Chance
* GF
(M
(Id%%
).Group
) THEN Result%% = FALSE 'player is blocked
Result%% = TRUE 'player evades
Player_Flee = Result%%
FUNCTION Battle_Initiative
(who%%
, ID%%
) 'if false then enemy goes first else player goes first in battle
IF P
(who%%
).Agility
* Chance
< M
(ID%%
).Agility
* Chance
* GF
(1) THEN Result%% = FALSE 'Monster goes first
Result%% = TRUE 'player Goes first
Battle_Initiative = Result%%
'Debugging stuff found below---------------------------------------------------
SUB Print_Inventory
(who%%
) 'check that values in inventory are correct
'DEBUGGING!_-------------------------------
STATIC m
AS _MEM 'no need to initialize/free it over and over m
= _MEM(P
(who%%
)) 'Just change where you want to point it to. Pack = m.OFFSET + 28 '‘move to where P(Who%%).Pack starts at in memory
FOR i%%
= 0 TO P
(who%%
).Items
- 1
_PRINTSTRING (528, 8), "Tile :" + STR$(Place
(P
(who%%
).Map
, P
(who%%
).MapX
, P
(who%%
).MapY
).Sprite_ID
) + " ", Layer
(9) _PRINTSTRING (528, 56), "ExitBlock:" + STR$(Place
(P
(who%%
).Map
, P
(who%%
).MapX
, P
(who%%
).MapY
).Is_Exit
) + " ", Layer
(9) _PRINTSTRING (528, 168), "Stairs:" + STR$(Place
(P
(who%%
).Map
, P
(who%%
).MapX
, P
(who%%
).MapY
).Is_Stairs
) + " ", Layer
(9) _PRINTSTRING (528, 72), "Tile :" + STR$(World
(P
(who%%
).WorldX
, P
(who%%
).WorldY
).Sprite_ID
) + " ", Layer
(9) _PRINTSTRING (528, 168), "Stairs:" + STR$(World
(P
(who%%
).WorldX
, P
(who%%
).WorldY
).Is_Stairs
) + " ", Layer
(9)