Mirage Source

Free ORPG making software.
It is currently Sat Apr 27, 2024 9:18 pm

All times are UTC




Post new topic Reply to topic  [ 44 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Thread of questions
PostPosted: Sat Feb 16, 2008 9:58 pm 
Offline
Knowledgeable
User avatar

Joined: Thu Dec 28, 2006 8:57 pm
Posts: 297
Location: This magical place called 'reality'
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?

_________________
P2B Feed: Custom AI
Image


Top
 Profile  
 
 Post subject: Re: Thread of questions
PostPosted: Sat Feb 16, 2008 10:07 pm 
Offline
Persistant Poster
User avatar

Joined: Thu Aug 17, 2006 5:27 pm
Posts: 866
Location: United Kingdom
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?


Top
 Profile  
 
 Post subject: Re: Thread of questions
PostPosted: Sat Feb 16, 2008 10:29 pm 
Offline
Knowledgeable
User avatar

Joined: Thu Dec 28, 2006 8:57 pm
Posts: 297
Location: This magical place called 'reality'
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...

_________________
P2B Feed: Custom AI
Image


Top
 Profile  
 
 Post subject: Re: Thread of questions
PostPosted: Sun Feb 17, 2008 1:47 am 
Offline
Knowledgeable
User avatar

Joined: Thu Dec 28, 2006 8:57 pm
Posts: 297
Location: This magical place called 'reality'
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.

_________________
P2B Feed: Custom AI
Image


Top
 Profile  
 
 Post subject: Re: Thread of questions
PostPosted: Sun Feb 17, 2008 3:35 am 
Offline
Community Leader
User avatar

Joined: Sun May 28, 2006 10:29 pm
Posts: 1762
Location: Salt Lake City, UT, USA
Google Talk: Darunada@gmail.com
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.

_________________
I'm on Facebook! Google Plus LinkedIn My Youtube Channel Send me an email Call me with Skype Check me out on Bitbucket Yup, I'm an EVE Online player!
Why not try my app, ColorEye, on your Android devlce?
Do you like social gaming? Fight it out in Battle Juice!

I am a professional software developer in Salt Lake City, UT.


Top
 Profile  
 
 Post subject: Re: Thread of questions
PostPosted: Sun Feb 17, 2008 5:01 pm 
Offline
Knowledgeable
User avatar

Joined: Thu Dec 28, 2006 8:57 pm
Posts: 297
Location: This magical place called 'reality'
So CLng is not needed? Wouldn't it be easier to use the Int() function to get its value (truncated)?

_________________
P2B Feed: Custom AI
Image


Top
 Profile  
 
 Post subject: Re: Thread of questions
PostPosted: Sun Feb 17, 2008 10:33 pm 
Offline
Community Leader
User avatar

Joined: Sun May 28, 2006 10:29 pm
Posts: 1762
Location: Salt Lake City, UT, USA
Google Talk: Darunada@gmail.com
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.

_________________
I'm on Facebook! Google Plus LinkedIn My Youtube Channel Send me an email Call me with Skype Check me out on Bitbucket Yup, I'm an EVE Online player!
Why not try my app, ColorEye, on your Android devlce?
Do you like social gaming? Fight it out in Battle Juice!

I am a professional software developer in Salt Lake City, UT.


Top
 Profile  
 
 Post subject: Re: Thread of questions
PostPosted: Mon Feb 18, 2008 3:12 am 
Offline
Knowledgeable
User avatar

Joined: Thu Dec 28, 2006 8:57 pm
Posts: 297
Location: This magical place called 'reality'
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

_________________
P2B Feed: Custom AI
Image


Top
 Profile  
 
 Post subject: Re: Thread of questions
PostPosted: Mon Feb 18, 2008 5:14 am 
Offline
Community Leader
User avatar

Joined: Sun May 28, 2006 10:29 pm
Posts: 1762
Location: Salt Lake City, UT, USA
Google Talk: Darunada@gmail.com
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.

_________________
I'm on Facebook! Google Plus LinkedIn My Youtube Channel Send me an email Call me with Skype Check me out on Bitbucket Yup, I'm an EVE Online player!
Why not try my app, ColorEye, on your Android devlce?
Do you like social gaming? Fight it out in Battle Juice!

I am a professional software developer in Salt Lake City, UT.


Top
 Profile  
 
 Post subject: Re: Thread of questions
PostPosted: Mon Feb 18, 2008 3:10 pm 
Offline
Knowledgeable
User avatar

Joined: Thu Dec 28, 2006 8:57 pm
Posts: 297
Location: This magical place called 'reality'
Um...There is no CharRec anywhere...

_________________
P2B Feed: Custom AI
Image


Top
 Profile  
 
 Post subject: Re: Thread of questions
PostPosted: Mon Feb 18, 2008 3:50 pm 
Offline
Knowledgeable
User avatar

Joined: Tue Feb 06, 2007 9:50 pm
Posts: 180
Location: Bergenfield, New Jersey, US
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


Top
 Profile  
 
 Post subject: Re: Thread of questions
PostPosted: Mon Feb 18, 2008 5:54 pm 
Offline
Knowledgeable
User avatar

Joined: Thu Dec 28, 2006 8:57 pm
Posts: 297
Location: This magical place called 'reality'
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...

_________________
P2B Feed: Custom AI
Image


Top
 Profile  
 
 Post subject: Re: Thread of questions
PostPosted: Mon Feb 18, 2008 7:33 pm 
Offline
Regular
User avatar

Joined: Tue Jan 02, 2007 7:31 pm
Posts: 81
Location: UK
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.


Top
 Profile  
 
 Post subject: Re: Thread of questions
PostPosted: Mon Feb 18, 2008 8:25 pm 
Offline
Knowledgeable
User avatar

Joined: Thu Dec 28, 2006 8:57 pm
Posts: 297
Location: This magical place called 'reality'
After changing it, it still doesn't save or load it...

_________________
P2B Feed: Custom AI
Image


Top
 Profile  
 
 Post subject: Re: Thread of questions
PostPosted: Mon Feb 18, 2008 10:30 pm 
Offline
Regular
User avatar

Joined: Tue Jan 02, 2007 7:31 pm
Posts: 81
Location: UK
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.


Top
 Profile  
 
 Post subject: Re: Thread of questions
PostPosted: Mon Feb 18, 2008 11:34 pm 
Offline
Knowledgeable
User avatar

Joined: Thu Dec 28, 2006 8:57 pm
Posts: 297
Location: This magical place called 'reality'
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.

_________________
P2B Feed: Custom AI
Image


Top
 Profile  
 
 Post subject: Re: Thread of questions
PostPosted: Tue Feb 19, 2008 1:36 pm 
Offline
Regular
User avatar

Joined: Tue Jan 02, 2007 7:31 pm
Posts: 81
Location: UK
Nice one, hope you get it fixed soon. Lemme know how it goes.


Top
 Profile  
 
 Post subject: Re: Thread of questions
PostPosted: Tue Feb 19, 2008 6:44 pm 
Offline
Knowledgeable
User avatar

Joined: Thu Dec 28, 2006 8:57 pm
Posts: 297
Location: This magical place called 'reality'
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!

_________________
P2B Feed: Custom AI
Image


Top
 Profile  
 
 Post subject: Re: Thread of questions
PostPosted: Wed Feb 20, 2008 12:30 am 
Offline
Regular
User avatar

Joined: Tue Jan 02, 2007 7:31 pm
Posts: 81
Location: UK
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. :D


Top
 Profile  
 
 Post subject: Re: Thread of questions
PostPosted: Wed Feb 20, 2008 12:53 am 
Offline
Knowledgeable
User avatar

Joined: Thu Dec 28, 2006 8:57 pm
Posts: 297
Location: This magical place called 'reality'
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. :D

_________________
P2B Feed: Custom AI
Image


Top
 Profile  
 
 Post subject: Re: Thread of questions
PostPosted: Wed Feb 20, 2008 2:42 am 
Offline
Regular
User avatar

Joined: Tue Jan 02, 2007 7:31 pm
Posts: 81
Location: UK
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.


Top
 Profile  
 
 Post subject: Re: Thread of questions
PostPosted: Wed Feb 20, 2008 4:07 am 
Offline
Knowledgeable
User avatar

Joined: Thu Dec 28, 2006 8:57 pm
Posts: 297
Location: This magical place called 'reality'
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...

_________________
P2B Feed: Custom AI
Image


Top
 Profile  
 
 Post subject: Re: Thread of questions
PostPosted: Wed Feb 20, 2008 3:07 pm 
Offline
Regular
User avatar

Joined: Tue Jan 02, 2007 7:31 pm
Posts: 81
Location: UK
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?


Top
 Profile  
 
 Post subject: Re: Thread of questions
PostPosted: Sat Feb 23, 2008 9:43 pm 
Offline
Knowledgeable
User avatar

Joined: Thu Dec 28, 2006 8:57 pm
Posts: 297
Location: This magical place called 'reality'
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...

_________________
P2B Feed: Custom AI
Image


Top
 Profile  
 
 Post subject: Re: Thread of questions
PostPosted: Sun Feb 24, 2008 11:54 pm 
Offline
Knowledgeable
User avatar

Joined: Thu Dec 28, 2006 8:57 pm
Posts: 297
Location: This magical place called 'reality'
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

_________________
P2B Feed: Custom AI
Image


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 44 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 74 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group