Mirage Source http://web.miragesource.net/forums/ |
|
Thread of questions http://web.miragesource.net/forums/viewtopic.php?f=201&t=3386 |
Page 1 of 2 |
Author: | Stomach Pulser [ Sat Feb 16, 2008 9:58 pm ] |
Post subject: | Thread of questions |
I will use this thread to ask questions about how different pieces of code work. No need in making new topics each time. First off: I am adding a chat box where users input text instead of bltign it to the screen. It works successfully, but i can't make any sense of this code: Code: frmMirage.txtInputChat.Text = MyText If Len(MyText) > 4 Then frmMirage.txtInputChat.SelStart = Len(frmMirage.txtInputChat.Text) + 1 End If I am trying to figure out how it works and what everything in it means. Any tips? |
Author: | Coke [ Sat Feb 16, 2008 10:07 pm ] |
Post subject: | Re: Thread of questions |
Stomach Pulser wrote: I will use this thread to ask questions about how different pieces of code work. No need in making new topics each time. First off: I am adding a chat box where users input text instead of bltign it to the screen. It works successfully, but i can't make any sense of this code: Code: frmMirage.txtInputChat.Text = MyText If Len(MyText) > 4 Then frmMirage.txtInputChat.SelStart = Len(frmMirage.txtInputChat.Text) + 1 End If I am trying to figure out how it works and what everything in it means. Any tips? textinputchat is a control on frmMirage, this is taking that text and setting it as MyText (variable). if Len (being length) is more than 4 characters then the SelStart (cursor position in the text box) is the amount of characters that are being typed +1... I don't see any point to the if statement, what event procedure is this from? |
Author: | Stomach Pulser [ Sat Feb 16, 2008 10:29 pm ] |
Post subject: | Re: Thread of questions |
This replaces the DrawText in the gameloop. I knew that Len means length and such. But I didn't know why the position was set to start after everything after 4... [Edit] I removed the if statement and everything functions as it did before. Weird how dead code was in there... |
Author: | Stomach Pulser [ Sun Feb 17, 2008 1:47 am ] |
Post subject: | Re: Thread of questions |
Newt up on my list of questions involves the following code in modGameLogic: Code: Sub BltMapNPCName(ByVal Index As Long) Dim TextX As Long Dim TextY As Long With Npc(MapNpc(Index).Num) 'Draw name TextX = MapNpc(Index).x * PIC_X + MapNpc(Index).XOffset + CLng(PIC_X / 2) - ((Len(Trim$(.Name)) / 2) * 8) TextY = MapNpc(Index).y * PIC_Y + MapNpc(Index).YOffset - CLng(PIC_Y / 2) - 4 DrawText TexthDC, TextX, TextY, Trim$(.Name), vbWhite End With End Sub and the following code in the gameloop: Code: 'Draw NPC Names For i = LBound(MapNpc) To UBound(MapNpc) If MapNpc(i).Num > 0 Then BltMapNPCName i End If Next i Let's start with what I conclude from this. In the bltNPCName code, sets where the text is to be blted by the following information for X an Y: The NPC's X/Y * PIC_X/Y (32) + the NPC's X/Y offset (from the tiles) + something (CLng) -/* something else. Then, it blts it using those exact pixels. And it blts it so that the middle of the text is at the middle of the NPC (16). CLng converts half of the NPC's width to a long? Why is that called? Then, for something (LBound of the MapNPC) to something else (UBound of the MapNPC) it calls the sub if the NPC exists on a map. I know that LBound is the bottom of some array and that UBound is the top. So, is it calling the array of MapNPC's (for instance, MapNPC(0) to MapNPC(3), assuming there are 4 NPCs on the map)? So, everything in red is what I have in question. Also, if I am wrong about something please tell me. |
Author: | Lea [ Sun Feb 17, 2008 3:35 am ] |
Post subject: | Re: Thread of questions |
The CLng was probably put there to eliminate any remainder. It's not needed, as it is evaluated to a Long data type anyways, which drops the remainder. Correct, it cycles through the entire list of NPCs. |
Author: | Stomach Pulser [ Sun Feb 17, 2008 5:01 pm ] |
Post subject: | Re: Thread of questions |
So CLng is not needed? Wouldn't it be easier to use the Int() function to get its value (truncated)? |
Author: | Lea [ Sun Feb 17, 2008 10:33 pm ] |
Post subject: | Re: Thread of questions |
I would just leave any form of conversion off entirely. There's no point to convert a part of a number to a long, then convert the rest to a long. There's no need to convert part of a number to a int, then convert the rest to a long. Just take it off, and it will convert once. |
Author: | Stomach Pulser [ Mon Feb 18, 2008 3:12 am ] |
Post subject: | Re: Thread of questions |
Ok, thanks1 Next up is about adding a thing for the players that allows them to choose if they want to display there map coordinates. And it saves their choice and and loads it up everytime they play (it is by character, not player). I have it working so that they can either type /pos to switch it to the opposite of what is was before or they can type /pos on or /pos off to set it to that. But, it doesn't save or load it, which is what I want. (Sorry if it is a lot of code - I have been searching through code for hours to find a solution) Peices parts... ::Server Side:: In modHandle Data -> Sub HandleData Code: ' ::::::::::::::::::::::::::::::::: ' :: Update Can Display Position :: ' ::::::::::::::::::::::::::::::::: If LCase(Parse(0)) = "updatecandisplayposition" Then If Val(Parse(1)) = NO Then Call SetPlayerCanUpdateDisplayPosition(Index, NO) If Val(Parse(1)) = YES Then Call SetPlayerCanUpdateDisplayPosition(Index, YES) Call SavePlayer(Index) Exit Sub End If In modDatabase -> SavePlayer Code: Sub SavePlayer(ByVal Index As Long) Dim FileName As String Dim i As Long Dim n As Long FileName = App.Path & "\Accounts\" & Trim(Player(Index).Login) & ".ini" Call PutVar(FileName, "GENERAL", "Login", Trim(Player(Index).Login)) Call PutVar(FileName, "GENERAL", "Password", Trim(Player(Index).Password)) For i = 1 To MAX_CHARS ' General Call PutVar(FileName, "CHAR" & i, "Name", Trim(Player(Index).Char(i).Name)) Call PutVar(FileName, "CHAR" & i, "Class", STR(Player(Index).Char(i).Class)) Call PutVar(FileName, "CHAR" & i, "Sex", STR(Player(Index).Char(i).Sex)) Call PutVar(FileName, "CHAR" & i, "Sprite", STR(Player(Index).Char(i).Sprite)) Call PutVar(FileName, "CHAR" & i, "Level", STR(Player(Index).Char(i).Level)) Call PutVar(FileName, "CHAR" & i, "Exp", STR(Player(Index).Char(i).Exp)) Call PutVar(FileName, "CHAR" & i, "Access", STR(Player(Index).Char(i).Access)) Call PutVar(FileName, "CHAR" & i, "PK", STR(Player(Index).Char(i).PK)) Call PutVar(FileName, "CHAR" & i, "Guild", STR(Player(Index).Char(i).Guild)) ' Vitals Call PutVar(FileName, "CHAR" & i, "HP", STR(Player(Index).Char(i).HP)) Call PutVar(FileName, "CHAR" & i, "MP", STR(Player(Index).Char(i).MP)) Call PutVar(FileName, "CHAR" & i, "SP", STR(Player(Index).Char(i).SP)) ' Stats Call PutVar(FileName, "CHAR" & i, "STR", STR(Player(Index).Char(i).STR)) Call PutVar(FileName, "CHAR" & i, "DEF", STR(Player(Index).Char(i).DEF)) Call PutVar(FileName, "CHAR" & i, "SPEED", STR(Player(Index).Char(i).SPEED)) Call PutVar(FileName, "CHAR" & i, "MAGI", STR(Player(Index).Char(i).MAGI)) Call PutVar(FileName, "CHAR" & i, "POINTS", STR(Player(Index).Char(i).POINTS)) ' Worn equipment Call PutVar(FileName, "CHAR" & i, "ArmorSlot", STR(Player(Index).Char(i).ArmorSlot)) Call PutVar(FileName, "CHAR" & i, "WeaponSlot", STR(Player(Index).Char(i).WeaponSlot)) Call PutVar(FileName, "CHAR" & i, "HelmetSlot", STR(Player(Index).Char(i).HelmetSlot)) Call PutVar(FileName, "CHAR" & i, "ShieldSlot", STR(Player(Index).Char(i).ShieldSlot)) ' Check to make sure that they aren't on map 0, if so reset'm If Player(Index).Char(i).Map = 0 Then Player(Index).Char(i).Map = START_MAP Player(Index).Char(i).x = START_X Player(Index).Char(i).y = START_Y End If ' Position Call PutVar(FileName, "CHAR" & i, "Map", STR(Player(Index).Char(i).Map)) Call PutVar(FileName, "CHAR" & i, "X", STR(Player(Index).Char(i).x)) Call PutVar(FileName, "CHAR" & i, "Y", STR(Player(Index).Char(i).y)) Call PutVar(FileName, "CHAR" & i, "Dir", STR(Player(Index).Char(i).Dir)) ' Inventory For n = 1 To MAX_INV Call PutVar(FileName, "CHAR" & i, "InvItemNum" & n, STR(Player(Index).Char(i).Inv(n).Num)) Call PutVar(FileName, "CHAR" & i, "InvItemVal" & n, STR(Player(Index).Char(i).Inv(n).Value)) Call PutVar(FileName, "CHAR" & i, "InvItemDur" & n, STR(Player(Index).Char(i).Inv(n).Dur)) Next n ' Spells For n = 1 To MAX_PLAYER_SPELLS Call PutVar(FileName, "CHAR" & i, "Spell" & n, STR(Player(Index).Char(i).Spell(n))) Next n ' Options Call PutVar(FileName, "CHAR" & i, "CanUpdateDisplayPosition", STR(Player(Index).Char(i).CanUpdateDisplayPosition)) Next i End Sub In modDatabase -> LoadPlayer Code: Sub LoadPlayer(ByVal Index As Long, ByVal Name As String) Dim FileName As String Dim i As Long Dim n As Long Call ClearPlayer(Index) FileName = App.Path & "\Accounts\" & Trim(Name) & ".ini" Player(Index).Login = GetVar(FileName, "GENERAL", "Login") Player(Index).Password = GetVar(FileName, "GENERAL", "Password") For i = 1 To MAX_CHARS ' General Player(Index).Char(i).Name = GetVar(FileName, "CHAR" & i, "Name") Player(Index).Char(i).Sex = Val(GetVar(FileName, "CHAR" & i, "Sex")) Player(Index).Char(i).Class = Val(GetVar(FileName, "CHAR" & i, "Class")) Player(Index).Char(i).Sprite = Val(GetVar(FileName, "CHAR" & i, "Sprite")) Player(Index).Char(i).Level = Val(GetVar(FileName, "CHAR" & i, "Level")) Player(Index).Char(i).Exp = Val(GetVar(FileName, "CHAR" & i, "Exp")) Player(Index).Char(i).Access = Val(GetVar(FileName, "CHAR" & i, "Access")) Player(Index).Char(i).PK = Val(GetVar(FileName, "CHAR" & i, "PK")) Player(Index).Char(i).Guild = Val(GetVar(FileName, "CHAR" & i, "Guild")) ' Vitals Player(Index).Char(i).HP = Val(GetVar(FileName, "CHAR" & i, "HP")) Player(Index).Char(i).MP = Val(GetVar(FileName, "CHAR" & i, "MP")) Player(Index).Char(i).SP = Val(GetVar(FileName, "CHAR" & i, "SP")) ' Stats Player(Index).Char(i).STR = Val(GetVar(FileName, "CHAR" & i, "STR")) Player(Index).Char(i).DEF = Val(GetVar(FileName, "CHAR" & i, "DEF")) Player(Index).Char(i).SPEED = Val(GetVar(FileName, "CHAR" & i, "SPEED")) Player(Index).Char(i).MAGI = Val(GetVar(FileName, "CHAR" & i, "MAGI")) Player(Index).Char(i).POINTS = Val(GetVar(FileName, "CHAR" & i, "POINTS")) ' Worn equipment Player(Index).Char(i).ArmorSlot = Val(GetVar(FileName, "CHAR" & i, "ArmorSlot")) Player(Index).Char(i).WeaponSlot = Val(GetVar(FileName, "CHAR" & i, "WeaponSlot")) Player(Index).Char(i).HelmetSlot = Val(GetVar(FileName, "CHAR" & i, "HelmetSlot")) Player(Index).Char(i).ShieldSlot = Val(GetVar(FileName, "CHAR" & i, "ShieldSlot")) ' Position Player(Index).Char(i).Map = Val(GetVar(FileName, "CHAR" & i, "Map")) Player(Index).Char(i).x = Val(GetVar(FileName, "CHAR" & i, "X")) Player(Index).Char(i).y = Val(GetVar(FileName, "CHAR" & i, "Y")) Player(Index).Char(i).Dir = Val(GetVar(FileName, "CHAR" & i, "Dir")) ' Check to make sure that they aren't on map 0, if so reset'm If Player(Index).Char(i).Map = 0 Then Player(Index).Char(i).Map = START_MAP Player(Index).Char(i).x = START_X Player(Index).Char(i).y = START_Y End If ' Inventory For n = 1 To MAX_INV Player(Index).Char(i).Inv(n).Num = Val(GetVar(FileName, "CHAR" & i, "InvItemNum" & n)) Player(Index).Char(i).Inv(n).Value = Val(GetVar(FileName, "CHAR" & i, "InvItemVal" & n)) Player(Index).Char(i).Inv(n).Dur = Val(GetVar(FileName, "CHAR" & i, "InvItemDur" & n)) Next n ' Spells For n = 1 To MAX_PLAYER_SPELLS Player(Index).Char(i).Spell(n) = Val(GetVar(FileName, "CHAR" & i, "Spell" & n)) Next n Player(Index).Char(i).CanUpdateDisplayPosition = Val(GetVar(FileName, "CHAR" & i, "CanUpdateDisplayPosition")) Next i End Sub in modGameLogic Code: Function GetPlayerCanUpdateDisplayPosition(ByVal Index As Long) As Byte GetPlayerCanUpdateDisplayPosition = Player(Index).Char(Player(Index).CharNum).CanUpdateDisplayPosition End Function Sub SetPlayerCanUpdateDisplayPosition(ByVal Index As Long, OnOff As Byte) If OnOff = NO Then Player(Index).Char(Player(Index).CharNum).CanUpdateDisplayPosition = NO ElseIf OnOff = YES Then Player(Index).Char(Player(Index).CharNum).CanUpdateDisplayPosition = YES End If End Sub In modGameLogic -> ClearChar Code: Sub ClearChar(ByVal Index As Long, ByVal CharNum As Long) Dim n As Long Player(Index).Char(CharNum).Name = "" Player(Index).Char(CharNum).Class = 0 Player(Index).Char(CharNum).Sprite = 0 Player(Index).Char(CharNum).Level = 0 Player(Index).Char(CharNum).Exp = 0 Player(Index).Char(CharNum).Access = 0 Player(Index).Char(CharNum).PK = NO Player(Index).Char(CharNum).POINTS = 0 Player(Index).Char(CharNum).Guild = 0 Player(Index).Char(CharNum).HP = 0 Player(Index).Char(CharNum).MP = 0 Player(Index).Char(CharNum).SP = 0 Player(Index).Char(CharNum).STR = 0 Player(Index).Char(CharNum).DEF = 0 Player(Index).Char(CharNum).SPEED = 0 Player(Index).Char(CharNum).MAGI = 0 For n = 1 To MAX_INV Player(Index).Char(CharNum).Inv(n).Num = 0 Player(Index).Char(CharNum).Inv(n).Value = 0 Player(Index).Char(CharNum).Inv(n).Dur = 0 Next n For n = 1 To MAX_PLAYER_SPELLS Player(Index).Char(CharNum).Spell(n) = 0 Next n Player(Index).Char(CharNum).ArmorSlot = 0 Player(Index).Char(CharNum).WeaponSlot = 0 Player(Index).Char(CharNum).HelmetSlot = 0 Player(Index).Char(CharNum).ShieldSlot = 0 Player(Index).Char(CharNum).Map = 0 Player(Index).Char(CharNum).x = 0 Player(Index).Char(CharNum).y = 0 Player(Index).Char(CharNum).Dir = 0 ' Options Player(Index).Char(CharNum).CanUpdateDisplayPosition = NO End Sub In modTypes -> PlayerRec Code: CanUpdateDisplayPosition As Byte ::Client Side:: In modClientTCP Code: Sub UpdateCanDisplayPosition(ByVal OnOff As Byte) Dim Packet As String Packet = "CANUPDATEDISPLAYPOSITION" & SEP_CHAR & STR(OnOff) & END_CHAR Call SendData(Packet) End Sub In modGameLogic -> GameLoop Code: ' Blit the player's map coordinates If GetPlayerCanUpdateDisplayPosition(MyIndex) = YES Then Call DrawText(TexthDC, 5, 20, "Map(x,y): " & GetPlayerMap(MyIndex) & "(" & GetPlayerX(MyIndex) & "," & GetPlayerY(MyIndex) & ")", QBColor(White)) End If in modGameLogic -> HandlKeyPresses Code: ' Checking Coordinates If LCase$(Mid$(MyText, 1, 4)) = "/pos" Then ChatText = vbNullString If Len(MyText) > 4 Then ChatText = LCase$(Mid$(MyText, 6, Len(MyText) - 1)) End If If ChatText = vbNullString Then If GetPlayerCanUpdateDisplayPosition(MyIndex) = NO Then Call SetPlayerCanUpdateDisplayPosition(MyIndex, YES) ElseIf GetPlayerCanUpdateDisplayPosition(MyIndex) = YES Then Call SetPlayerCanUpdateDisplayPosition(MyIndex, NO) End If Else If ChatText = "on" Then Call SetPlayerCanUpdateDisplayPosition(MyIndex, YES) ElseIf ChatText = "off" Then Call SetPlayerCanUpdateDisplayPosition(MyIndex, NO) End If End If Call UpdateCanDisplayPosition(GetPlayerCanUpdateDisplayPosition(MyIndex)) MyText = vbNullString ChatText = vbNullString Exit Sub End If In modGameLogic Code: Function GetPlayerCanUpdateDisplayPosition(ByVal Index As Long) As Byte GetPlayerCanUpdateDisplayPosition = Player(Index).CanUpdateDisplayPosition End Function Sub SetPlayerCanUpdateDisplayPosition(ByVal Index As Long, OnOff As Byte) If OnOff = NO Then Player(Index).CanUpdateDisplayPosition = NO ElseIf OnOff = YES Then Player(Index).CanUpdateDisplayPosition = YES End If End Sub In modGameLogic -> ClearPlayer Code: Sub ClearPlayer(ByVal Index As Long) Dim i As Long Dim n As Long Player(Index).Name = "" Player(Index).Class = 0 Player(Index).Level = 0 Player(Index).Sprite = 0 Player(Index).Exp = 0 Player(Index).Access = 0 Player(Index).PK = NO Player(Index).HP = 0 Player(Index).MP = 0 Player(Index).SP = 0 Player(Index).STR = 0 Player(Index).DEF = 0 Player(Index).SPEED = 0 Player(Index).MAGI = 0 For n = 1 To MAX_INV Player(Index).Inv(n).Num = 0 Player(Index).Inv(n).Value = 0 Player(Index).Inv(n).Dur = 0 Next n Player(Index).ArmorSlot = 0 Player(Index).WeaponSlot = 0 Player(Index).HelmetSlot = 0 Player(Index).ShieldSlot = 0 Player(Index).Map = 0 Player(Index).x = 0 Player(Index).y = 0 Player(Index).Dir = 0 ' Client use only Player(Index).MaxHP = 0 Player(Index).MaxMP = 0 Player(Index).MaxSP = 0 Player(Index).XOffset = 0 Player(Index).YOffset = 0 Player(Index).Moving = 0 Player(Index).Attacking = 0 Player(Index).AttackTimer = 0 Player(Index).MapGetTimer = 0 Player(Index).CastedSpell = NO ' Options Player(Index).CanUpdateDisplayPosition = NO End Sub In modTypes -> PlayerRec Code: CanUpdateDisplayPosition As Byte
|
Author: | Lea [ Mon Feb 18, 2008 5:14 am ] |
Post subject: | Re: Thread of questions |
Well if you have a variable in the CharRec type, all you need to do to load and save it is add it to the loadplayer and saveplayer functions. |
Author: | Stomach Pulser [ Mon Feb 18, 2008 3:10 pm ] |
Post subject: | Re: Thread of questions |
Um...There is no CharRec anywhere... |
Author: | Ramsey [ Mon Feb 18, 2008 3:50 pm ] |
Post subject: | Re: Thread of questions |
He may be referring to this: Code: Type PlayerRec
' General Name As String * NAME_LENGTH Sex As Byte Class As Byte Sprite As Integer Level As Byte Exp As Long Access As Byte PK As Byte Guild As Byte ' Vitals HP As Long MP As Long SP As Long ' Stats STR As Byte DEF As Byte SPEED As Byte MAGI As Byte POINTS As Byte ' Worn equipment ArmorSlot As Byte WeaponSlot As Byte HelmetSlot As Byte ShieldSlot As Byte ' Inventory Inv(1 To MAX_INV) As PlayerInvRec Spell(1 To MAX_PLAYER_SPELLS) As Byte ' Position Map As Integer X As Byte Y As Byte Dir As Byte End Type |
Author: | Stomach Pulser [ Mon Feb 18, 2008 5:54 pm ] |
Post subject: | Re: Thread of questions |
Oh, but that is already declared in the PlayerRec and is set to save in Load and SavePlayer, but for some reason it doesn't work... |
Author: | Ambientiger [ Mon Feb 18, 2008 7:33 pm ] |
Post subject: | Re: Thread of questions |
Looking through the code it all looks okay, then I spotted this: Code: ' ::::::::::::::::::::::::::::::::: ' :: Update Can Display Position :: ' ::::::::::::::::::::::::::::::::: If LCase(Parse(0)) = [b]"updatecandisplayposition"[/b] Then If Val(Parse(1)) = NO Then Call SetPlayerCanUpdateDisplayPosition(Index, NO) If Val(Parse(1)) = YES Then Call SetPlayerCanUpdateDisplayPosition(Index, YES) Call SavePlayer(Index) Exit Sub End If Code: Sub UpdateCanDisplayPosition(ByVal OnOff As Byte) Dim Packet As String Packet = [b]"CANUPDATEDISPLAYPOSITION"[/b] & SEP_CHAR & STR(OnOff) & END_CHAR Call SendData(Packet) End Sub Shouldn't the bits in bold be the same, apart from the upper case/lower case thing? I think your server is missing the packet. Okay, my bad, not the bits in bold - the bits in the code quotes marked up to be bold, lol. |
Author: | Stomach Pulser [ Mon Feb 18, 2008 8:25 pm ] |
Post subject: | Re: Thread of questions |
After changing it, it still doesn't save or load it... |
Author: | Ambientiger [ Mon Feb 18, 2008 10:30 pm ] |
Post subject: | Re: Thread of questions |
Hmm, I just copy and pasted the line from your code to PlayerRec and the PutVar line that corresponds to it to the end of my SavePlayer Sub. Then started up the server and client, logged into the first character in the list, logged back out of the game and then shut the server down with the server shutdown command. On checking the .ini file for that account I found an extra value had been added - CanUpdateDisplayPosition = 0 The value was added right at the bottom of each characters information. In a basic MSE the only places in the server code that the player is saved is on account creation, character creation, character deletion, the LeftGame sub and in ServerDestroy when the server is shutdown. Oh, is there a timer that saves players too? I would suggest checking these to make sure that player saving is still intact. Last resort, any chance I can get a look at the source code you've programmed. The code you've posted seems solid enough and I can't see any problems with what's there, especially when it comes to just the saving/loading part. |
Author: | Stomach Pulser [ Mon Feb 18, 2008 11:34 pm ] |
Post subject: | Re: Thread of questions |
Well, what I did is I manually invoked the SavePlayer function when the packet is sent. I will look over everything one more time and I could post the source if needed. [EDIT] I made sure ever variable or call of this is CanUpdateDisplayPosition and now it saves it properly. What it doesn't do, however, is load this. I'm working on it. |
Author: | Ambientiger [ Tue Feb 19, 2008 1:36 pm ] |
Post subject: | Re: Thread of questions |
Nice one, hope you get it fixed soon. Lemme know how it goes. |
Author: | Stomach Pulser [ Tue Feb 19, 2008 6:44 pm ] |
Post subject: | Re: Thread of questions |
Well, I added another packet into the server. The packet is sent when a character is used and it works properly. The packet just sets the players CanUpdateDisplayPoisition value to whatever is in their file. It functions perfectly now! OK, moving along (I'm not keen to stopping). I decided to add HP bars to NPCs, using GSD's tutorial. But, I don't understand parts of it. Let me show you... I understand how the packet is sent from the server to the client. But, I want to confirm something when the client receives the packet. Code: ' ::::::::::::::::::: ' :: Npc hp packet :: ' ::::::::::::::::::: If LCase(Parse(0)) = "npchp" Then n = 1 For i = 1 To MAX_MAP_NPCS MapNpc(i).HP = Val(Parse(n)) MapNpc(i).MaxHP = Val(Parse(n + 1)) n = n + 2 Next i Exit Sub End If Does n = n + 2 mean that the first MapNPC has the 1st and 2nd values in the packet (HP and Max HP) and that the second NPC has the 3rd and 4th and so on. Does it work because every two values are assiagned to different MapNPCs? Next up is the calling of the function that blits the NPCs: Code: ' Blit out NPC hp bars Dim GSD2 As Long If GetTickCount > GSD2 + 500 Then Call SendData("getnpchp" & SEP_CHAR & END_CHAR) GSD2 = GetTickCount End If For i = 1 To MAX_MAP_NPCS If MapNpc(i).Num > 0 Then Call BltNpcBars(i) End If Next i What does the GSD2 variable represent and why does it send data if it is less than the TickCount (still don't know what this is) + 500. Then, why does it increase to the tickcount? I think it has something to do with the amount of actions that can be carried out at once (i.e. the amount of time it takes for a player to wait before his current animation ends and he can start a new one). Last off is with the drawing of the hp bars: Code: Sub BltNpcBars(ByVal Index As Long) Dim x As Long, y As Long x = MapNpc(Index).x * PIC_X + MapNpc(Index).XOffset y = MapNpc(Index).y * PIC_Y + MapNpc(Index).YOffset - 4 If MapNpc(Index).HP = 0 Then Exit Sub Call DD_BackBuffer.SetFillColor(RGB(255, 0, 0)) Call DD_BackBuffer.DrawBox(x, y + 32, x + 32, y + 36) Call DD_BackBuffer.SetFillColor(RGB(0, 255, 0)) Call DD_BackBuffer.DrawBox(x, y + 32, x + ((MapNpc(Index).HP / 100) / (MapNpc(Index).MaxHP / 100) * 32), y + 36) End Sub I don't understand any of this except that it involves DirectX. Could someone clarify what the x/y calculations do and how the BackBuffer draws things to the main surface? Sorry if I my questions seem obvious, this is how I learn. Thanks for previous feedback and future feedback! |
Author: | Ambientiger [ Wed Feb 20, 2008 12:30 am ] |
Post subject: | Re: Thread of questions |
It's all good while your learning, if something like that works go with it. On to the next questions, I know the first two, but I might stumble on the last one this time, my DirectX isn't great either: 1) I suppose the best answer is yes, many of the code operations(correct term?) you'll come across just boil down to being able to write a whole lot of code in the least amount of lines. The For/Next loop as it's called is an excellent way of doing this, let me know if you'd like a better explanation of this one. 2)The TickCount is the representation of a timeframe as measured by the computer, each Tick is the equivalent of approximately 1 millisecond, therefore 1000 Ticks are equivalent to about 1 second. I think I'm right in saying that the computer starts to measure its TickCount right from the time that it boots up, have a look in modDeclares and you'll see that GetTickCount is declared as a function from the "kernel32" library. Now, using that knowledge you can see that GSD2 = GetTickCount takes a single point in time from the computers 'stopwatch' if you like to compare with another point in time somewhere else in the code. I'm pretty sure you understand how the For/Next loop works to actually blit the NPC's hit bars, so I'll just run you through the first section of the code you posted. Dim GSD2 As Long - Create a variable of type Long called GSD2 to hold a value. If GetTickCount > GSD2 + 500 Then - If the (time on the computers 'stopwatch') is greater than (the variable GSD2's value + 500) Then execute the following code. Call SendData("getnpchp" & SEP_CHAR & END_CHAR) - sends a packet to the server asking for all Npc's current HP values. GSD2 = GetTickCount - take the value in the computers 'stopwatch' and enter it into the variable GSD2 put basically what this does, is send a packet to the server every half a second requesting an update to the Npc's HP values, to which the server replies with the packet from your first question. I'm not sure I like this way of doing it personally, seems a bit wasteful, but I'm not willing to rewrite the tutorial so we'll go with it. --------------- Before I go on, how am I doing? Are the bold bits picking out all the relevant stuff properly? Am I going over the top explaining stuff? It'll give me an idea of where your at learning-wise so I can tailor things a little more to your level. ---------------- 3) The BackBuffer is an area that the computer uses offscreen to put together everything before it displays the final 'frame' to the viewable area of the screen. If you've got the fps counter working it'll give you an idea of how many times the computer runs through the gameloop every second! The line Code: ' Blit the backbuffer Call DD_PrimarySurf.Blt(rec_pos, DD_BackBuffer, rec, DDBLT_WAIT) in the gameloop is the bit responsible for taking a rectangle the size of rec from the BackBuffer and showing it on the monitor in the rectangle rec_pos. I love VB's code completion thingie, in the visual basic IDE find and delete the first bracket after .Blt in the line of code above, now type it in again and VB should show you the values that the Sub/Function is expecting. The x/y bit is all about finding where the left side(x) and the top edge(y) of the .DrawBox should be drawn. MapNpc(Index).x * PIC_X - How many tiles from the left side of the screen the Npc is. + MapNpc(Index).XOffset - Plus how far left or right the Npc is if it's walking from one tile to the next. The y value calculates where the top of the tile is that the Npc is on, the -4 bit makes sure the bar is blitted far enough above the Npc's head. Hope that helps a bit. |
Author: | Stomach Pulser [ Wed Feb 20, 2008 12:53 am ] |
Post subject: | Re: Thread of questions |
Thanks for replying. Actually, it blts the bar to below the NPC... And, if you are just blting to the backbuffer, how does DX blt to the surface. Does it always blt to the surface if you blt to the backbuffer? Also, I do have some background in programming, not a great deal though. Just use regular terms and if I don't understand I'll ask. |
Author: | Ambientiger [ Wed Feb 20, 2008 2:42 am ] |
Post subject: | Re: Thread of questions |
np, I've got a bit of spare time right now. Umm, yes, anything you blit to the backbuffer will be sent to the screen on every execution of the gameloop. Ambientiger wrote: The line Code: ' Blit the backbuffer Call DD_PrimarySurf.Blt(rec_pos, DD_BackBuffer, rec, DDBLT_WAIT) in the gameloop is the bit responsible for taking a rectangle the size of rec from the BackBuffer and showing it on the monitor in the rectangle rec_pos. If you follow the code through Sub GameLoop you'll notice calls to each of the Blit Subs (BlitTile, BlitPlayer etc), each of these subs builds up the map layer by layer onto the backbuffer, then the line of code above sort of picks it all up and slaps it on the screen. The main associations with the surface are made in Sub InitDirectX then the code above uses this bit - Code: ' Get the rect to blit to Call DX.GetWindowRect(frmMirage.picScreen.hWnd, rec_pos) With rec_pos .Bottom = .top + ((MAX_MAPY + 1) * PIC_Y) .Right = .Left + ((MAX_MAPX + 1) * PIC_X) End With to know where to put the image from the backbuffer. |
Author: | Stomach Pulser [ Wed Feb 20, 2008 4:07 am ] |
Post subject: | Re: Thread of questions |
So, why does it blt below the player when it says: Code: y = MapNpc(Index).y * PIC_Y + MapNpc(Index).YOffset - 4 which would imply that it blts 4 pixels above the player... |
Author: | Ambientiger [ Wed Feb 20, 2008 3:07 pm ] |
Post subject: | Re: Thread of questions |
Bingo... you had me baffled there for a minute, but check it out.... Code: Call DD_BackBuffer.SetFillColor(RGB(255, 0, 0)) Call DD_BackBuffer.DrawBox(x, y + 32, x + 32, y + 36) Call DD_BackBuffer.SetFillColor(RGB(0, 255, 0)) Call DD_BackBuffer.DrawBox(x, y + 32, x + ((MapNpc(Index).HP / 100) / (MapNpc(Index).MaxHP / 100) * 32), y + 36) the call to blit the .DrawBox to the BackBuffer uses y + 32 to calculate the position of the HP bar. I think the -4 bit is to make up for the slight offset of the sprites on the map, ever noticed that they don't quite fit on the map squares properly? |
Author: | Stomach Pulser [ Sat Feb 23, 2008 9:43 pm ] |
Post subject: | Re: Thread of questions |
I was working on changing my things around in my NPCs (read Portal To Bakaria development logs to see exactly) and after changing the getNpcMaxHP sub, I couldn't attack me NPC's. Looking into it I found this code: Code: ' //////////////////////////////////////////////////////// ' // This is used for checking if an NPC is dead or not // ' //////////////////////////////////////////////////////// ' Check if the npc is dead or not 'If MapNpc(y, x).Num > 0 Then ' If MapNpc(y, x).HP <= 0 And Npc(MapNpc(y, x).Num).STR > 0 And Npc(MapNpc(y, x).Num).DEF > 0 Then ' MapNpc(y, x).Num = 0 ' MapNpc(y, x).SpawnWait = TickCount ' End If 'End If I uncommented it and it worked fine. But why has it been commented out? In a vanilla MSE1 it is commented out to... |
Author: | Stomach Pulser [ Sun Feb 24, 2008 11:54 pm ] |
Post subject: | Re: Thread of questions |
OK. I logged in after changing server code that requires password to be case sensitive. And after clicking cancel under frmChars I get an error in my frmNewChar. I immediatly go wtf because it was in the timer in frmNewChar. This error only happens when I hit cancel on a seperate form. The error is an RTE 9 in: Code: Call BitBlt(picChar.hdc, 0, 0, 32, 32, picSprites.hdc, PIC_X * DIR_DOWN * 3, Int(Class(cmbClass.ListIndex).Sprite) * PIC_Y, SRCCOPY) What doesn't make sense is that this is in a different form. Any help? (also if someone could help me in my above post it would be helpful) Also, this only happens because for some reason, in the DestroyTCP sub it loads the frmNewChars which activates the timer which doesn't work because the frmNewChar isn't initalized yet. Yet, I see no call to load this form only: Code: If frmNewChars.Visible Then frmNewChars.Visible = false
|
Page 1 of 2 | All times are UTC |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |