REM RGBRPG, created by Tinkergirl and initially inspired by RiiDii's tutorial REM on the DarkBasicPro Challenge thread. `Create the player type, this is the collection of stats for the player. Type Character Rage as Float Grace as Float Brains as Float MaxHP as Float HP as Float Money as Float Level as Float XP as Float Name as String Object as Integer EndType `Declare our player as a global variable. Global Player as Character `Create our baddie (enemy) type - we'll make several of these. Type Baddie Rage as Float Grace as Float Brains as Float HP as Float XPDrop as Integer MoneyDrop as Integer Name as String Object as Integer Endtype Dim Enemies(10) as Baddie global Fighting as Integer sync on: sync rate 60 randomize timer() FirstTimeThrough = 0 Player.Object = 1 Fighting = 0 global Loopy as integer global Attack as integer Loopy = 400 Global AttackName$ as String global DamageFloat as Integer global Combatant as Integer global damage as Integer global FloatTime as Integer Do if FirstTimeThrough = 0 NameCharacter() `asks player for a name, keeps it. StatCharacter() `creates random stats and either rerolls or keeps. GenerateBaddie() `Might work. MakeCube() `makes our player object, colours it etc. MakeWorld() `creates the floor plain, lights etc. MakeLevel() `generates the buildings/walls of our environment MakeFloater() `Make the plain that shows damage. FirstTimeThrough = 1 sync on endif if Fighting =0 CubeMovement() `controls the movement of our cube character. WASD keys. Endif ThirdPerson() `positions the camera in a 3rd-person style position. DrawStats() if Object Collision(1,0)>49 if Object Collision(1,0)<100 Combatant = Object Collision(1,0)-50 DrawBaddieStats() DoFight() endif endif if Player.XP>100*Player.Level Level() endif if DamageFloat>0 FloatTime=250 DamageFloat = 0 endif DamageFloater() Sync Loop `Ask for a name for the character. This happens only once. Function NameCharacter() sync off `Now, create our character. CLS Set Cursor 0,0 Input "Enter your cube's name:",Player.Name Print Print "Welcome ";Player.Name;" the Cube." Wait 1000 Endfunction `Create initial stats for the character. Currently random. *Something to work on later. Function StatCharacter() do Cls Set Cursor 0,0 Print Player.Name;", press [R] to re-roll stats, or [Y] to accept stats." Print `100 stat points initially. Previous method sometimes resulted in Brains=-1 (ironic, really) `So we've set a 'points left' and made sure each stat is always at least 1. Player.Rage=1 Player.Grace=1 Player.Brains=1 AmountLeft=97 Player.Rage=Player.Rage+rnd(AmountLeft) AmountLeft=AmountLeft-Player.Rage+1 Player.Grace=Player.Grace+rnd(AmountLeft) AmountLeft=AmountLeft-Player.Grace+1 Player.Brains=Player.Brains+AmountLeft Player.HP=Player.Rage+Player.Grace+Player.Brains Player.MaxHP=Player.HP Player.Money=(Player.Brains+Player.Grace)*2 Player.Level=1 `Still not got a good name or system for assigning the main unit of 'barter'. Depends. `Print out the stats - note, Rage, Grace, and Brains correspond to Red, Green and Blue `respectively. This will help people figure out the relative skills of an enemy, etc. Ink RGB(255,0,0),0 Print "(R)age: ";Player.Rage Ink RGB(0,255,0),0 Print "(G)race: ";Player.Grace Ink RGB(0,0,255),0 Print "(B)rains: ";Player.Brains Ink RGB(255,255,255),0 Print "Health: ";Player.HP;"/";Player.MaxHP Print "Monetary Units: ";Player.Money Ink RGB(INT(Player.Rage),INT(Player.Grace),INT(Player.Brains)),0 Box 180,30,260,110 Ink RGB(255,255,255),0 `Let the player choose to keep the stats or re-roll. Do a$=Lower$(Inkey$()) If a$="r" or a$="y" wait 300 Exit endif Loop if a$="y" Then Exit loop Endfunction `Make our cubic avatar Function MakeCube() make object cube Player.Object,Player.HP/10 color object Player.Object, rgb(INT(Player.Rage),INT(Player.Grace),INT(Player.Brains)) color backdrop 0 make object collision box Player.Object,-7,-7,-7,7,7,7,0 EndFunction `This creates our world (currently a plain object - bah) Function MakeWorld() autocam off make object plain 4,800,800 position object 4,0,0,0 rotate object 4,-90,0,0 color object 4,rgb(50,50,50) set object collision off 4 color ambient light rgb(20,20,20) autocam on EndFunction `Move around using the WASD keys Function CubeMovement() `Originally ripped from the monster hunt tutorial, changed most of it to allow vectors and rolling as well as WASD. CubeAngle#= Object Angle Y(Player.Object) PosX#=Object Position X(Player.Object) PosY#=Object Position Y(Player.Object) PosZ#=Object Position Z(Player.Object) `Keys for controlling the object. WASD standard. If Keystate(17)=1 : `"W" key for forward. ` WKey = 1 CubeSpeed# = 1.5 CubeMoveX# = -sin(-Object Angle Y(Player.Object)) * CubeSpeed# CubeMoveZ# = cos(-Object Angle Y(Player.Object)) * CubeSpeed# `Update the positions in the X and Z using the vector. PosX#=PosX#+CubeMoveX# PosZ#=PosZ#+CubeMoveZ# `Put a bit of a 'rolling' tumble on it, so we know the cube's moving. CurrentXRot#=Object Angle X(Player.Object) Xrotate Object Player.Object,CurrentXRot#+5 else WKey = 0 Endif If Keystate(31)=1 : `"S" key for reverse. CubeRevSpeed# = 1.0 CubeRevMoveX# = -sin(-Object Angle Y(Player.Object)) * CubeRevSpeed# CubeRevMoveZ# = cos(-Object Angle Y(Player.Object)) * CubeRevSpeed# `Again, update the X and Z with the reversing vector. PosX#=PosX#-CubeRevMoveX# PosZ#=PosZ#-CubeRevMoveZ# `Put a bit of a 'rolling' tumble on it, so we know the cube's reversing. CurrentXRot#=Object Angle X(Player.Object) Xrotate Object Player.Object,CurrentXRot#-3 Endif If Keystate(30)=1 then Yrotate Object Player.Object, Wrapvalue(CubeAngle#-1.5) :`"A" for left. If Keystate(32)=1 then Yrotate Object Player.Object, Wrapvalue(CubeAngle#+1.5) :`"D" for right. `Object collision (Want's it's own function soon, I believe.) if object collision (1,5) > 0 dec PosX#,get object collision x() dec PosY#,get object collision y() dec PosZ#,get object collision z() endif `Apply all the position changes last, including collision. position object Player.Object, PosX#,4.5+(Player.Level/2),PosZ# EndFunction `TEST function to see what keys are being pressed and print their scancode. Function TestKeys() Set Cursor 0,0 Print SCANCODE() EndFunction `The camera control function to position it above and behind our cube. Function ThirdPerson() `Special thanks to my bf for showing me his DarkSDK code that he wrote for 3rd Person. Needed modifying to work. CameraOffset# = 50 CameraHeight = Object Position Y(Player.Object)+30 OffsetX# = -sin(-Object Angle Y(Player.Object)) * CameraOffset# OffsetZ# = cos(-Object Angle Y(Player.Object)) * CameraOffset# Position Camera 0, Object Position X(Player.Object)-OffsetX#, CameraHeight , Object Position Z(Player.Object)-OffsetZ# Point Camera 0, Object Position X(Player.Object), Object Position Y(Player.Object)+15, Object Position Z(Player.Object) EndFunction `Create the walls of our level/maze/city whatever. Function MakeLevel() make object box 5,100,20,20 make object collision box 5,-50,-10,-10,50,10,10,0 position object 5, 150,0,120 Endfunction `Try to generate some randomised baddies. This will need a lot of work (especially placement). Function GenerateBaddie() for i = 0 to array count(Enemies()) Enemies(i).Rage=rnd(50) Enemies(i).Grace=rnd(50) Enemies(i).Brains=rnd(50) Enemies(i).HP=(Enemies(i).Rage+Enemies(i).Grace+Enemies(i).Brains) Enemies(i).XPDrop=(Enemies(i).Rage+Enemies(i).Grace+Enemies(i).Brains)/3 Enemies(i).MoneyDrop=Enemies(i).XPDrop/2 `Enemies(i).Name="EvilBall" if Enemies(i).Rage>Enemies(i).Grace if Enemies(i).Rage>Enemies(i).Brains Enemies(i).Name="Bezerker Ball" else Enemies(i).Name="Brainy Ball" endif else if Enemies(i).Grace>Enemies(i).Brains Enemies(i).Name="Ninja Ball" else Enemies(i).Name="Brainy Ball" endif endif Enemies(i).Object=50+i Make Object Sphere Enemies(i).Object,(Enemies(i).HP)/6 Set Object Collision to Spheres Enemies(i).Object Set Object Collision on Enemies(i).Object ` Set Shadow Shading on Enemies(i).Object Position Object Enemies(i).Object,rnd(600)-300,Enemies(i).HP/12,rnd(600)-300 Color Object Enemies(i).Object,rgb(Enemies(i).Rage,Enemies(i).Grace,Enemies(i).Brains) next i Endfunction `Draw the players stats in terms of colours in the top left of the screen. Function DrawStats() set cursor 1,1 Print Player.Name," The Lv.",Player.Level," Cube" ink rgb(255,0,0),0 set cursor 1,17 Print "Rage:" box 5,33,Player.Rage+5,43 ink rgb(0,255,0),0 set cursor 1,43 Print "Grace:" box 5,58,Player.Grace+5,68 ink rgb(0,0,255),0 set cursor 1,68 Print "Brains:" box 5,83,Player.Brains+5,93 ink rgb(255,255,255),0 set cursor 1,94 Print "HP:" ink rgb(INT(Player.Rage),INT(Player.Grace),INT(Player.Brains)),0 box 3,108,Player.MaxHP+7,120 ink rgb(255,255,255),0 box 5,109,Player.HP+5,119 if keystate(18)=1 set cursor 1,124 Print "XP: ",Player.XP set cursor 1,138 Print "Money: ",Player.Money endif EndFunction `Draw the stats of the baddies when you collide with them. Hopefully, this will trigger when a fight starts. Function DrawBaddieStats() Collider= Combatant set cursor screen width()-Text Width (Enemies(Collider).Name)-Text Width (" The Enemy!"),1 Print Enemies(Collider).Name," The Enemy!" ink rgb(255,0,0),0 set cursor screen width()-Text Width("Rage:"),17 Print "Rage:" box screen width()-Enemies(Collider).Rage-5,33,screen width()-5,43 ink rgb(0,255,0),0 set cursor screen width()-Text Width ("Grace:"),43 Print "Grace:" box screen width()-Enemies(Collider).Grace-5,58,screen width()-5,68 ink rgb(0,0,255),0 set cursor screen width()-Text Width("Brains:"),69 Print "Brains:" box screen width()-Enemies(Collider).Brains-5,84,screen width()-5,94 ink rgb(255,255,255),0 set cursor screen width()-Text Width("HP:"),95 Print "HP:" box screen width()-Enemies(Collider).HP-5,110,screen width()-5,120 EndFunction `Fight function - this is the meat of the gameplay. Press 1,2 or 3 to choose an attack. Function DoFight() Fighting = 1 ConSystemInk() center Text screen width()/2,screen height()-65,"Fight" ink rgb(255,255,255),0 BattleTimer() CombatCamera() `Some placeholder attack types and names. If Keystate(2) = 1 :`Key 1 if Player.Rage>5 Attack = 1 AttackName$ = "Rage Frenzy" endif endif If Keystate(4) = 1 :`Key 3 if Player.Grace>5 Attack = 2 AttackName$ = "Stealth Stab" endif endif If Keystate(7) = 1 :`Key 6 if Player.Brains>40 Attack = 3 AttackName$ = "Emotional Vampirism" endif endif if Keystate(6) = 1 :`Key 5 if Player.Brains>5 Attack = 4 AttackName$ = "Mind Heal" endif endif if Keystate(5) = 1 :`Key 4 if Player.Grace>40 Attack = 5 AttackName$ = "Reactive Momentum" endif endif if Keystate(3) = 1 :`Key 2 if Player.Rage>40 Attack = 6 AttackName$ = "All Or Nothing" endif endif if Attack > 0 ink 0,0 center Text screen width()/2,screen height()-45,AttackName$ ink rgb(255,255,255),0 endif if Loopy=0 if Attack>0 if object exist(Object Collision(1,0)) eneX=Object Position X(Enemies(Object Collision(1,0)-50).Object) eneY=Object Position Y(Enemies(Object Collision(1,0)-50).Object) eneZ=Object Position Z(Enemies(Object Collision(1,0)-50).Object) endif DamageBaddie() endif endif if DamageFloat=500 show object 300 position object 300,eneX,eneY+5,eneZ point object 300,camera position X(),camera position Y(),camera position Z() DamageFloat=499 endif EndFunction `Kills the baddie and gives goodies to the player. Function KillBaddie() Fighting = 0 Loopy = 400 Player.XP = Player.XP + Enemies(Combatant).XPDrop Player.Money = Player.Money + Enemies(Combatant).MoneyDrop delete object Object Collision(1,0) EndFunction `When in combat, the character (and thus camera) swings around to look at the enemy. Function CombatCamera() XDiff = Object Position X(Object Collision(1,0)) - Object Position X(1) ZDiff = Object Position Z(Object Collision(1,0)) - Object Position Z(1) angle# = ATanFull(XDiff, ZDiff) angle# = WrapValue(angle#) AngleDiff# = Object Angle Y(1) - angle# while (AngleDiff# < -180) AngleDiff# = AngleDiff# + 360 endwhile while (AngleDiff# > 180) AngleDiff# = AngleDiff# - 360 endwhile YRotate Object 1,Object Angle Y(1) - (AngleDiff#/20) EndFunction `Depending on the relative average skill levels of your opponent, change the ink colour. A bit late, but never mind. Function ConSystemInk() BaddieID = Combatant `RED if Enemies(BaddieID).Rage+Enemies(BaddieID).Grace+Enemies(BaddieID).Brains > (Player.Rage+Player.Grace+Player.Brains) ink rgb(255,0,0),0 else `YELLOW if Enemies(BaddieID).Rage+Enemies(BaddieID).Grace+Enemies(BaddieID).Brains > ((Player.Rage+Player.Grace+Player.Brains)*0.6) ink rgb(255,255,0),0 else `BLUE if Enemies(BaddieID).Rage+Enemies(BaddieID).Grace+Enemies(BaddieID).Brains > ((Player.Rage+Player.Grace+Player.Brains)*0.4) ink rgb(0,0,255),0 else `PALE BLUE if Enemies(BaddieID).Rage+Enemies(BaddieID).Grace+Enemies(BaddieID).Brains < ((Player.Rage+Player.Grace+Player.Brains)*0.4) ink rgb(180,180,255),0 endif endif endif endif EndFunction `To increase the characters stats and level when they gain enough XP. Function Level() Player.Level = Player.Level+1 Player.Rage = Player.Rage+rnd(10)+5 Player.Grace = Player.Grace+rnd(10)+5 Player.Brains = Player.Brains+rnd(10)+5 Player.MaxHP = Player.MaxHP+rnd(10)+10 Player.HP = Player.MaxHP Scale Object 1,Player.MaxHP,Player.MaxHP,Player.MaxHP Color Object 1,rgb(Player.Rage,Player.Grace,Player.Brains) Player.XP=Player.XP-(100*(Player.Level-1)) EndFunction `Battle Timer should let the player do one attack over a length of time. Function BattleTimer() if Loopy = 0 Loopy = 400 endif if Loopy>0 Loopy = Loopy - 1 endif if Loopy > 250 ink rgb(0,255,0),0 else if Loopy > 100 ink rgb(255,255,0),0 else if Loopy > 50 ink rgb(255,128,0),0 else if Loopy < 51 ink rgb(255,0,0),0 endif endif endif endif box (screen width()/2)-Loopy/2,screen height()-45,(screen width()/2)+Loopy/2,screen height()-30 ink rgb(255,255,255),0 EndFunction `Instead of killing the baddie in one hit, lets do him some damage. The numbers are unbalanced. Function DamageBaddie() BaddieID = Combatant `Rage Frenzy If Attack = 1 damage = Player.Rage Enemies(BaddieID).HP = Enemies(BaddieID).HP - damage set cursor screen width()/2,screen height()/2 endif `Stealth Stab If Attack = 2 damage = (Player.Grace/2)*rnd(3) if damage <1 then damage=1 Enemies(BaddieID).HP = Enemies(BaddieID).HP - damage set cursor screen width()/2,screen height()/2 endif `Emotional Vampirism If Attack = 3 damage =(Player.Brains)/1.5 if damage <1 then damage=1 Enemies(BaddieID).HP = Enemies(BaddieID).HP - damage Player.HP=Player.HP+damage if Player.HP>Player.MaxHP then Player.HP=Player.MaxHP set cursor screen width()/2,screen height()/2 endif `Mind Heal if Attack = 4 damage = 1 Player.HP = Player.HP + (Player.Brains*2) if Player.HP>Player.MaxHP Player.HP=Player.MaxHP endif endif `Defensive Momentum if Attack = 5 damage = Player.Grace/2+Enemies(BaddieID).Grace Enemies(BaddieID).HP = Enemies(BaddieID).HP - damage endif `All Or Nothing if Attack = 6 chance = rnd(2) if chance <=1 then damage = 0 if chance >1 then damage = Player.Rage*2+10 Enemies(BaddieID).HP = Enemies(BaddieID).HP- damage endif if Attack > 0 TextureFloater() DamageFloat=500 Attack = 0 Player.HP=Player.HP-(Enemies(BaddieID).Rage/2) endif `if Player.HP<1 ` KillPlayer() `endif if Enemies(BaddieID).HP < 1 KillBaddie() endif EndFunction Function MakeFloater() create bitmap 1,32,32 set current bitmap 0 make object plain 300,10,10 set object 300,1,1,0,1,0 hide object 300 EndFunction ` Draw the appropriate number of the damage on plain 400, the floater. Function TextureFloater() set current bitmap 1 ink 0,0 box 0,0,32,32 ink rgb(128,0,0),0 circle 16,16,10 circle 16,16,9 ink rgb(255,0,0),0 center text 17,9,STR$(damage) ink rgb(255,255,255),0 get image 400,0,0,32,32 set current bitmap 0 texture object 300,400 EndFunction Function DamageFloater() if FloatTime > 0 a = object position x(300) b# = object position y(300)+0.3 c = object position z(300) position object 300,a,b#,c point object 300,camera position X(),camera position Y(),camera position Z() FloatTime = FloatTime-1 ` print FloatTime endif if FloatTime = 0 Hide Object 300 endif EndFunction