Scorpious2k Posted September 7, 2009 Author Share Posted September 7, 2009 This is a serious change. It changes more than a line or two of code, it changes **how** the client and server deal with player movement. I will give these changes over more than one post and will try to explain what I am doing and why as we go.The first step you should take is to back-up everything. Copy the entire directory (EVERYTHING) and save it. This way you can always go back if there are any problems.This problem occurs because when a player moves, the client sends the server only the direction of the move. In other words, the client says "he moved that way". The server then has to calculate the player's new position. Since packets can be lost, among other things that can go wrong, it is easy for them to get out of sync.My solution is for the client to send the X and Y coordinates with each move. The server than validates this move. If it is OK, the server does nothing - letting the client continue. If the move is not valid, the server sends a corrected position to the client.In my next post I will give the changes to he client.Have you made that back-up copy of your game/source directory yet?? Link to comment Share on other sites More sharing options...
Scorpious2k Posted September 7, 2009 Author Share Posted September 7, 2009 Client ChangesIn **modClientTCP.bas Sub SendPlayerMove()**change``` Call SendData("playermove" & SEP_CHAR & GetPlayerDir(MyIndex) & SEP_CHAR & Player(MyIndex).Moving & END_CHAR)```to``` Call SendData("playermove" & SEP_CHAR & GetPlayerDir(MyIndex) & SEP_CHAR & Player(MyIndex).Moving & SEP_CHAR & GetPlayerX(MyIndex) & SEP_CHAR & GetPlayerY(MyIndex) & END_CHAR)```in **modDatabase.bas Sub SetPlayerX()**change``` If X >= 0 And X <= MAX_MAPX Then Player(Index).X = X End If```to``` Player(Index).X = X```in **modGameLogic.bas Sub CheckMovement()**before``` If Not GettingMap Then```insert``` Dim s2kX As Integer, s2kY As Integer ' used below for temp store of X/Y```change the case statement``` Select Case GetPlayerDir(MyIndex) Case DIR_UP Call SendPlayerMove Player(MyIndex).yOffset = PIC_Y Call SetPlayerY(MyIndex, GetPlayerY(MyIndex) - 1) Case DIR_DOWN Call SendPlayerMove Player(MyIndex).yOffset = PIC_Y * -1 Call SetPlayerY(MyIndex, GetPlayerY(MyIndex) + 1) Case DIR_LEFT Call SendPlayerMove Player(MyIndex).xOffset = PIC_X Call SetPlayerX(MyIndex, GetPlayerX(MyIndex) - 1) Case DIR_RIGHT Call SendPlayerMove Player(MyIndex).xOffset = PIC_X * -1 Call SetPlayerX(MyIndex, GetPlayerX(MyIndex) + 1) End Select```to``` Select Case GetPlayerDir(MyIndex) Case DIR_UP Player(MyIndex).yOffset = PIC_Y Call SetPlayerY(MyIndex, GetPlayerY(MyIndex) - 1) Case DIR_DOWN Player(MyIndex).yOffset = PIC_Y * -1 Call SetPlayerY(MyIndex, GetPlayerY(MyIndex) + 1) Case DIR_LEFT Player(MyIndex).xOffset = PIC_X Call SetPlayerX(MyIndex, GetPlayerX(MyIndex) - 1) Case DIR_RIGHT Player(MyIndex).xOffset = PIC_X * -1 Call SetPlayerX(MyIndex, GetPlayerX(MyIndex) + 1) End Select```put this after that case statement``` Call SendPlayerMove '090829 moved here s2kX = GetPlayerX(MyIndex) '090829 s2kY = GetPlayerY(MyIndex) '090829```after that replace this line (which comes next in the sub)``` If Map(GetPlayerMap(MyIndex)).Tile(GetPlayerX(MyIndex), GetPlayerY(MyIndex)).Type = TILE_TYPE_WARP Then```with``` If Map(GetPlayerMap(MyIndex)).Tile(s2kX, s2kY).Type = TILE_TYPE_WARP Or s2kX < 0 Or s2kX > MAX_MAPX Or s2kY < 0 Or s2kY > MAX_MAPY Then```in **modTypes.bas Type PlayerRec**``` X As Byte y As Byte```to``` X As Integer y As Integer```If you have been paying close attention, we have just broken a lot of things - not the least of which is the player data for all your current players.Don't panic!We will fix it in the server and even make the changes to the player data transparent to your players.Aren't you glad you made that back-up now?Next post: server changes. Link to comment Share on other sites More sharing options...
Scorpious2k Posted September 7, 2009 Author Share Posted September 7, 2009 Server Changesin **modGameLogic.bas Sub PlayerMove()**change```Sub PlayerMove(ByVal index As Long, ByVal Dir As Long, ByVal Movement As Long)```to```Sub PlayerMove(ByVal Index As Long, ByVal Dir As Long, ByVal Movement As Long, Xpos As Integer, Ypos As Integer)```after``` Dim a As Long```insert```' variables we will need Dim pmap As Integer Dim Xold As Integer Dim Yold As Integer```This next step is something of a rewrite of some of the code…remove:``` Select Case Dir Case DIR_UP ' Check to make sure not outside of boundries If GetPlayerY(Index) > 0 Then ' Check to make sure that the tile is walkable If Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index), GetPlayerY(Index) - 1).Type <> TILE_TYPE_BLOCKED Then ' Check to see if the tile is a key and if it is check if its opened If (Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index), GetPlayerY(Index) - 1).Type <> TILE_TYPE_KEY Or Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index), GetPlayerY(Index) - 1).Type <> TILE_TYPE_DOOR) Or ((Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index), GetPlayerY(Index) - 1).Type = TILE_TYPE_DOOR Or Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index), GetPlayerY(Index) - 1).Type = TILE_TYPE_KEY) And TempTile(GetPlayerMap(Index)).DoorOpen(GetPlayerX(Index), GetPlayerY(Index) - 1) = YES) Then Call SetPlayerY(Index, GetPlayerY(Index) - 1) packet = "playermove" & SEP_CHAR & Index & SEP_CHAR & GetPlayerX(Index) & SEP_CHAR & GetPlayerY(Index) & SEP_CHAR & GetPlayerDir(Index) & SEP_CHAR & Movement & END_CHAR Call SendPlayerNewXY(index) Call SendDataToMapBut(Index, GetPlayerMap(Index), packet) Moved = YES End If End If Else ' Check to see if we can move them to the another map If Map(GetPlayerMap(Index)).Up > 0 Then Call PlayerWarp(Index, Map(GetPlayerMap(Index)).Up, GetPlayerX(Index), MAX_MAPY) Moved = YES End If End If Case DIR_DOWN ' Check to make sure not outside of boundries If GetPlayerY(Index) < MAX_MAPY Then ' Check to make sure that the tile is walkable If Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index), GetPlayerY(Index) + 1).Type <> TILE_TYPE_BLOCKED Then ' Check to see if the tile is a key and if it is check if its opened If (Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index), GetPlayerY(Index) + 1).Type <> TILE_TYPE_KEY Or Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index), GetPlayerY(Index) + 1).Type <> TILE_TYPE_DOOR) Or ((Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index), GetPlayerY(Index) + 1).Type = TILE_TYPE_DOOR Or Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index), GetPlayerY(Index) + 1).Type = TILE_TYPE_KEY) And TempTile(GetPlayerMap(Index)).DoorOpen(GetPlayerX(Index), GetPlayerY(Index) + 1) = YES) Then Call SetPlayerY(Index, GetPlayerY(Index) + 1) packet = "playermove" & SEP_CHAR & Index & SEP_CHAR & GetPlayerX(Index) & SEP_CHAR & GetPlayerY(Index) & SEP_CHAR & GetPlayerDir(Index) & SEP_CHAR & Movement & END_CHAR Call SendPlayerNewXY(index) Call SendDataToMapBut(Index, GetPlayerMap(Index), packet) Moved = YES End If End If Else ' Check to see if we can move them to the another map If Map(GetPlayerMap(Index)).Down > 0 Then Call PlayerWarp(Index, Map(GetPlayerMap(Index)).Down, GetPlayerX(Index), 0) Moved = YES End If End If Case DIR_LEFT ' Check to make sure not outside of boundries If GetPlayerX(Index) > 0 Then ' Check to make sure that the tile is walkable If Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index) - 1, GetPlayerY(Index)).Type <> TILE_TYPE_BLOCKED Then ' Check to see if the tile is a key and if it is check if its opened If (Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index) - 1, GetPlayerY(Index)).Type <> TILE_TYPE_KEY Or Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index) - 1, GetPlayerY(Index)).Type <> TILE_TYPE_DOOR) Or ((Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index) - 1, GetPlayerY(Index)).Type = TILE_TYPE_DOOR Or Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index) - 1, GetPlayerY(Index)).Type = TILE_TYPE_KEY) And TempTile(GetPlayerMap(Index)).DoorOpen(GetPlayerX(Index) - 1, GetPlayerY(Index)) = YES) Then Call SetPlayerX(Index, GetPlayerX(Index) - 1) packet = "playermove" & SEP_CHAR & Index & SEP_CHAR & GetPlayerX(Index) & SEP_CHAR & GetPlayerY(Index) & SEP_CHAR & GetPlayerDir(Index) & SEP_CHAR & Movement & END_CHAR Call SendPlayerNewXY(index) Call SendDataToMapBut(Index, GetPlayerMap(Index), packet) Moved = YES End If End If Else ' Check to see if we can move them to the another map If Map(GetPlayerMap(Index)).Left > 0 Then Call PlayerWarp(Index, Map(GetPlayerMap(Index)).Left, MAX_MAPX, GetPlayerY(Index)) Moved = YES End If End If Case DIR_RIGHT ' Check to make sure not outside of boundries If GetPlayerX(Index) < MAX_MAPX Then ' Check to make sure that the tile is walkable If Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index) + 1, GetPlayerY(Index)).Type <> TILE_TYPE_BLOCKED Then ' Check to see if the tile is a key and if it is check if its opened If (Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index) + 1, GetPlayerY(Index)).Type <> TILE_TYPE_KEY Or Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index) + 1, GetPlayerY(Index)).Type <> TILE_TYPE_DOOR) Or ((Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index) + 1, GetPlayerY(Index)).Type = TILE_TYPE_DOOR Or Map(GetPlayerMap(Index)).Tile(GetPlayerX(Index) + 1, GetPlayerY(Index)).Type = TILE_TYPE_KEY) And TempTile(GetPlayerMap(Index)).DoorOpen(GetPlayerX(Index) + 1, GetPlayerY(Index)) = YES) Then Call SetPlayerX(Index, GetPlayerX(Index) + 1) packet = "playermove" & SEP_CHAR & Index & SEP_CHAR & GetPlayerX(Index) & SEP_CHAR & GetPlayerY(Index) & SEP_CHAR & GetPlayerDir(Index) & SEP_CHAR & Movement & END_CHAR Call SendPlayerNewXY(index) Call SendDataToMapBut(Index, GetPlayerMap(Index), packet) Moved = YES End If End If Else ' Check to see if we can move them to the another map If Map(GetPlayerMap(Index)).Right > 0 Then Call PlayerWarp(Index, Map(GetPlayerMap(Index)).Right, 0, GetPlayerY(Index)) Moved = YES End If End If End Select If GetPlayerX(Index) < 0 Or GetPlayerY(Index) < 0 Or GetPlayerX(Index) > MAX_MAPX Or GetPlayerY(Index) > MAX_MAPY Or GetPlayerMap(Index) <= 0 Then Call HackingAttempt(Index, vbNullString) Exit Sub End If```replace it with```' save the current location Xold = GetPlayerX(Index) Yold = GetPlayerY(Index) pmap = GetPlayerMap(Index)' validate map number If pmap <= 0 Or pmap > MAX_MAPS Then Call HackingAttempt(Index, vbNullString) Exit Sub End If' update it to match client - this will be correct 99% of the time Call SetPlayerX(Index, Xpos) Call SetPlayerY(Index, Ypos)' next check to see if we have gone outside of map boundries' if we have, need to try to warp to next map if there is one If Dir = DIR_UP And Ypos < 0 And Map(pmap).Up > 0 Then Call PlayerWarp(Index, Map(pmap).Up, Xpos, MAX_MAPY) Moved = YES ElseIf Dir = DIR_DOWN And Ypos > MAX_MAPY And Map(pmap).Down > 0 Then Call PlayerWarp(Index, Map(pmap).Down, Xpos, 0) Moved = YES ElseIf Dir = DIR_LEFT And Xpos < 0 And Map(pmap).Left > 0 Then Call PlayerWarp(Index, Map(pmap).Left, MAX_MAPX, Ypos) Moved = YES ElseIf Dir = DIR_RIGHT And Xpos > MAX_MAPX And Map(pmap).Right > 0 Then Call PlayerWarp(Index, Map(pmap).Right, 0, Ypos) Moved = YES End If' restore values in case we got warped Xpos = GetPlayerX(Index) Ypos = GetPlayerY(Index) pmap = GetPlayerMap(Index)' check to make sure new position is on the map If Xpos < 0 Or Ypos < 0 Or Xpos > MAX_MAPX Or Ypos > MAX_MAPY Then Call HackingAttempt(Index, vbNullString) Exit Sub End If' Check to make sure that the tile is walkable If Map(pmap).Tile(Xpos, Ypos).Type <> TILE_TYPE_BLOCKED Then' Check to see if the tile is a key and if it is check if its opened If (Map(pmap).Tile(Xpos, Ypos).Type <> TILE_TYPE_KEY And Map(pmap).Tile(Xpos, Ypos).Type <> TILE_TYPE_DOOR) Or ((Map(pmap).Tile(Xpos, Ypos).Type = TILE_TYPE_DOOR Or Map(pmap).Tile(Xpos, Ypos).Type = TILE_TYPE_KEY) And TempTile(pmap).DoorOpen(Xpos, Ypos) = YES) Then packet = "playermove" & SEP_CHAR & Index & SEP_CHAR & Xpos & SEP_CHAR & Ypos & SEP_CHAR & Dir & SEP_CHAR & Movement & END_CHAR Call SendDataToMapBut(Index, pmap, packet) Moved = YES End If End If' at this point we have either moved or there is a problem with the new location' if we didn't move, we need to reset to previous locations and quit If Moved <> YES Then Call SetPlayerX(Index, Xold) Call SetPlayerY(Index, Yold) Call SendPlayerNewXY(Index) Exit Sub End If```in **modHandleData.bas Sub HandleData()**change``` Call Packet_PlayerMove(index, Val(Parse(1)), Val(Parse(2)))```to``` Call Packet_PlayerMove(Index, Val(Parse(1)), Val(Parse(2)), Val(Parse(3)), Val(Parse(4)))```in **Sub Packet_PlayerMove()**change```Public Sub Packet_PlayerMove(ByVal index As Long, ByVal Dir As Long, ByVal Movement As Long)```to```Public Sub Packet_PlayerMove(ByVal Index As Long, ByVal Dir As Long, ByVal Movement As Long, Xpos As Integer, Ypos As Integer)```change```Call PlayerMove(index, Dir, Movement)```to```Call PlayerMove(Index, Dir, Movement, Xpos, Ypos)```in **Sub Packet_RequestNewMap()**after```Public Sub Packet_RequestNewMap(ByVal Index As Long, ByVal Dir As Long)```insert``` Dim x As Integer Dim y As Integer```after``` If Dir < DIR_UP Or Dir > DIR_RIGHT Then Call HackingAttempt(Index, "Invalid Direction") Exit Sub End If```insert``` y = GetPlayerY(Index) x = GetPlayerX(Index) Select Case Dir Case DIR_UP y = y - 1 Case DIR_DOWN y = y + 1 Case DIR_LEFT x = x - 1 Case DIR_RIGHT x = x + 1 End Select```change ``` Call PlayerMove(Index, Dir, 1)```to``` Call PlayerMove(Index, Dir, 1, x, y) Call SendPlayerNewXY(Index)```EDIT: another problem found by Damian666, thanks againin **Sub ClearChar()**after``` Dim n As Long```insert``` ' version info Player(index).Char(CharNum).Vflag = 128 Player(index).Char(CharNum).Ver = 2 Player(index).Char(CharNum).SubVer = 8 Player(index).Char(CharNum).Rel = 0```EDIT: I forgot to include this originally - thanks Damian666in **clsCommands.cls Sub MovePlayer**change``` Call PlayerMove(index, Direction, Movement)```to``` Dim x As Integer Dim y As Integer y = GetPlayerY(Index) x = GetPlayerX(Index) Select Case Direction Case DIR_UP y = y - 1 Case DIR_DOWN y = y + 1 Case DIR_LEFT x = x - 1 Case DIR_RIGHT x = x + 1 End Select Call PlayerMove(Index, Direction, Movement, x, y) Call SendPlayerNewXY(Index)```OK, so all the changes to get rid of the out-of-sync problem are almost in, but we have to change the player data and by changing it, all your player's characters won't work.We will both change it and make sure everyone's character still works - in the next post. Link to comment Share on other sites More sharing options...
Scorpious2k Posted September 7, 2009 Author Share Posted September 7, 2009 The solution for the broken player characters is to automatically fix them by recognizing they are wrong and converting them to the new format when we load them. This will make it totally transparent to players.So, first the break… all of this is in the serverin **modTypes.bas**change```Public Type PlayerRec```to```Type V000PlayerRec```after``` MAXSP As Long End Type```insert```Public Type PlayerRec ' General'090829 Scorpious2k Vflag As Byte ' version flag - always > 127 Ver As Byte SubVer As Byte Rel As Byte'090829 End Name As String * NAME_LENGTH Guild As String GuildAccess As Byte Sex As Byte Class As Integer Sprite As Long LEVEL As Integer Exp As Long Access As Byte PK As Byte ' Vitals HP As Long MP As Long SP As Long ' Stats STR As Long DEF As Long Speed As Long Magi As Long POINTS As Long ' Worn equipment ArmorSlot As Integer WeaponSlot As Integer HelmetSlot As Integer ShieldSlot As Integer LegsSlot As Integer RingSlot As Integer NecklaceSlot As Integer ' Inventory Inv(1 To MAX_INV) As PlayerInvRec Spell(1 To MAX_PLAYER_SPELLS) As Integer Bank(1 To MAX_BANK) As BankRec ' Position and movement Map As Integer'090829 X As Byte'090829 Y As Byte X As Integer Y As Integer Dir As Byte TargetNPC As Integer Head As Integer Body As Integer Leg As Integer PAPERDOLL As Byte MAXHP As Long MAXMP As Long MAXSP As LongEnd Type```What we have done is put in a new PlayerRec and renamed the old one to V000PlayerRec. The change we actually had to make was to change the player X and Y values from byte to integer.With the new code, it is possible to have a position of -1 to the max X/Y value +1\. In other words, one position beyond the edge of the map. This comes from the client and tells us the player is ready to warp to the next map (if possible).Since a byte value can only contain 0-255 (no negative number) and now we **_need_** that negative number, we change them to integers.We also added some other extra values to PlayerRec: Vflag, Ver, SubVer, and Rel. We will use these to identify whether the player data we read from the disk is old or new (in the future this can be used to identify additional changes).The trick we use is that Vflag, which is now the first byte of the player data, which is where the character name used to be. In ASCII, characters have a values < 127\. By making Vflag > 127 we know that if Vflag < 128 it is old player data and we need to convert it. If it is > 127 it is new style and no conversion is required.First we put in our conversion function:In **modDatabase.bas**before```Public Sub LoadPlayer(ByVal Index As Long, ByVal Name As String)```insert```Function ConvertV000(FileName As String) As PlayerRec Dim OldRec As V000PlayerRec Dim NewRec As PlayerRec Dim f As Long Dim n As Integer f = FreeFile Open FileName For Binary As #f Get #f, , OldRec Close #f ' General NewRec.Name = OldRec.Name NewRec.Guild = OldRec.Guild NewRec.GuildAccess = OldRec.GuildAccess NewRec.Sex = OldRec.Sex NewRec.Class = OldRec.Class NewRec.Sprite = OldRec.Sprite NewRec.LEVEL = OldRec.LEVEL NewRec.Exp = OldRec.Exp NewRec.Access = OldRec.Access NewRec.PK = OldRec.PK ' Vitals NewRec.HP = OldRec.HP NewRec.MP = OldRec.MP NewRec.SP = OldRec.SP ' Stats NewRec.STR = OldRec.STR NewRec.DEF = OldRec.DEF NewRec.Speed = OldRec.Speed NewRec.Magi = OldRec.Magi NewRec.POINTS = OldRec.POINTS ' Worn equipment NewRec.ArmorSlot = OldRec.ArmorSlot NewRec.WeaponSlot = OldRec.WeaponSlot NewRec.HelmetSlot = OldRec.HelmetSlot NewRec.ShieldSlot = OldRec.ShieldSlot NewRec.LegsSlot = OldRec.LegsSlot NewRec.RingSlot = OldRec.RingSlot NewRec.NecklaceSlot = OldRec.NecklaceSlot ' Inventory For n = 1 To MAX_INV NewRec.Inv(n) = OldRec.Inv(n) Next n For n = 1 To MAX_PLAYER_SPELLS NewRec.Spell(n) = OldRec.Spell(n) Next n For n = 1 To MAX_BANK NewRec.Bank(n) = OldRec.Bank(n) Next n ' Position NewRec.Map = OldRec.Map NewRec.X = OldRec.X NewRec.Y = OldRec.Y NewRec.Dir = OldRec.Dir NewRec.TargetNPC = OldRec.TargetNPC NewRec.Head = OldRec.Head NewRec.Body = OldRec.Body NewRec.Leg = OldRec.Leg NewRec.PAPERDOLL = OldRec.PAPERDOLL NewRec.MAXHP = OldRec.MAXHP NewRec.MAXMP = OldRec.MAXMP NewRec.MAXSP = OldRec.MAXSP ' *** add new fields *** ' version info NewRec.Vflag = 128 NewRec.Ver = 2 NewRec.SubVer = 8 NewRec.Rel = 0 ConvertV000 = NewRecEnd Function```Next we add code to identify player data that needs to be converted when we read it from the disk and convert it.In **Sub LoadPlayer()**after``` Open FileName For Binary As #f Get #f, , Player(Index).Char(I) Close #f```insert``` If Player(index).Char(I).Vflag <> 128 Then Player(index).Char(I) = ConvertV000(FileName) End If```We have to start making all the new characters the new way so…in **AddChar()**after``` Player(index).Char(CharNum).Head = headc Player(index).Char(CharNum).Body = bodyc Player(index).Char(CharNum).Leg = logc```insert``` ' version info Player(index).Char(CharNum).Vflag = 128 Player(index).Char(CharNum).Ver = 2 Player(index).Char(CharNum).SubVer = 8 Player(index).Char(CharNum).Rel = 0```And we are good! There is one other little thing that will give us problems.In **Sub SetPlayerY()**remove``` If Y >= 0 And Y <= MAX_MAPY Then```and remove``` End If```And if I haven't forgotten anything, the sync problem should now be gone.Don't forget to make that back-up FIRST! It is always a good practice and in cases like this where we are making some pretty extensive changes it is doubly so.If you have problems, be sure to let me know. Link to comment Share on other sites More sharing options...
Robin Posted September 7, 2009 Share Posted September 7, 2009 Do you always name variables after yourself? :Ps2kX. :) Link to comment Share on other sites More sharing options...
Scorpious2k Posted September 7, 2009 Author Share Posted September 7, 2009 @Robin:> Do you always name variables after yourself? :P> > s2kX. :)I could say I was just using something I was sure would be unique… yeah, that's it! Unique. Nothing to do with eqo or anything. Link to comment Share on other sites More sharing options...
Kimimaru Posted September 7, 2009 Share Posted September 7, 2009 Thanks a lot for posting this! Would it work if I just deleted all of my existing characters instead of adding in the conversion? Link to comment Share on other sites More sharing options...
Robin Posted September 7, 2009 Share Posted September 7, 2009 @Kimimaru:> Thanks a lot for posting this! Would it work if I just deleted all of my existing characters instead of adding in the conversion?Yes.Also, it would be simple enough to make an account converter as a separate utility. I have a few programs like this which I use for updating/downdating data files. Link to comment Share on other sites More sharing options...
Scorpious2k Posted September 7, 2009 Author Share Posted September 7, 2009 @Kimimaru:> Thanks a lot for posting this! Would it work if I just deleted all of my existing characters instead of adding in the conversion?It would, but I would recommend the conversion code anyway. It would be handy if you ever need to change PlayerRec in the future. All you do is add code to check the fields and you can handle the changes in the same way.This is one of the reasons I added it. One of the things I am working on are limited duration spells - like buffs that only stay on a player for a given time and wear off or damage-over-time spells (for example, for one minute it takes 5 HP away every 3 seconds then stops).Knowing I have these and other ideas in the works, I wanted a way to be able to add them without any impact on players in the future. Link to comment Share on other sites More sharing options...
Kimimaru Posted September 7, 2009 Share Posted September 7, 2009 Okay, thanks! I'll try to add it in on my convenience because I don't have the time right now. I can't seem to shake off the feeling that this whole thing could've been done in fewer lines of code. Link to comment Share on other sites More sharing options...
Scorpious2k Posted September 7, 2009 Author Share Posted September 7, 2009 @Kimimaru:> Okay, thanks! I'll try to add it in on my convenience because I don't have the time right now. I can't seem to shake off the feeling that this whole thing could've been done in fewer lines of code.Probably. There is always a better way. When changing things at this level, I prefer to be safe and still think I managed to observe the KISS (Keep It Simple Stupid) principle. I replaced some code that might have been modified for the same effect, but I felt the new code was easier to read , easier to follow, and will be easier to maintain. Link to comment Share on other sites More sharing options...
damian666 Posted September 7, 2009 Share Posted September 7, 2009 you do knwo there is a playermove in sadscript too right?because that one breaks this way :Dits fixable of course ^^Damian666Edit:This works great, i just now walked my whole game world, from begin to end, and no hangs, just none, never XDand normally it would hang like, 10 times, its even on my work computer, which lags like hell, and even with the lag it doesnt hang ^^very good job man :) Link to comment Share on other sites More sharing options...
Scorpious2k Posted September 7, 2009 Author Share Posted September 7, 2009 @[SB:> Damian666 link=topic=51502.msg540941#msg540941 date=1252311290]> you do knwo there is a playermove in sadscript too right?> because that one breaks this way :D> > its fixable of course ^^> > Damian666> > Edit:> This works great, i just now walked my whole game world, from begin to end, and no hangs, just none, never XD> > and normally it would hang like, 10 times, its even on my work computer, which lags like hell, and even with the lag it doesnt hang ^^> > very good job man :)Thanks, and thanks for spotting my omission. I had it in my source but overlooked the sadscript one. I edited the above to include it. Link to comment Share on other sites More sharing options...
damian666 Posted September 7, 2009 Share Posted September 7, 2009 no man, thank you :)Damian666 Link to comment Share on other sites More sharing options...
kris_hole Posted September 7, 2009 Share Posted September 7, 2009 why do we need to change it from a byte to an integer? surely it wont be going over 255? Link to comment Share on other sites More sharing options...
Ruins of Hell Posted September 7, 2009 Share Posted September 7, 2009 But he said something about negatives, so a byte doesn't work (I think) Link to comment Share on other sites More sharing options...
Kimimaru Posted September 7, 2009 Share Posted September 7, 2009 Yeah, I believe he made it so that it's possible for a character to have X and Y coordinates of -1 and 31 in order to prepare the player for a map transition. Link to comment Share on other sites More sharing options...
damian666 Posted September 7, 2009 Share Posted September 7, 2009 well… who cares XDit works great , havent got any skipping or misplacement yet with this ^^Damian666 Link to comment Share on other sites More sharing options...
Kimimaru Posted September 7, 2009 Share Posted September 7, 2009 You're not supposed to, lol. Link to comment Share on other sites More sharing options...
Scorpious2k Posted September 7, 2009 Author Share Posted September 7, 2009 @Kimimaru:> Yeah, I believe he made it so that it's possible for a character to have X and Y coordinates of -1 and 31 in order to prepare the player for a map transition.@The:> But he said something about negatives, so a byte doesn't work (I think)You both are absolutely correct. Link to comment Share on other sites More sharing options...
Scorpious2k Posted September 7, 2009 Author Share Posted September 7, 2009 @[SB:> Damian666 link=topic=51502.msg541139#msg541139 date=1252344737]> well… who cares XD> > it works great , havent got any skipping or misplacement yet with this ^^> > Damian666I've been using it for over a week with no problems. :)You mentioned lag earlier, you should notice that you can move smoothly even on a server with lag problems. Link to comment Share on other sites More sharing options...
Kimimaru Posted September 7, 2009 Share Posted September 7, 2009 I've added all of this in, but it's telling me that there's no **Sub SendPlayerNewXY**, since it's saying that there's a Sub or Function not defined in this statement:```Call SendPlayerNewXY(Index)```I looked through your code and didn't seem to miss anything. Are you sure you added that sub in? Link to comment Share on other sites More sharing options...
Scorpious2k Posted September 7, 2009 Author Share Posted September 7, 2009 @Kimimaru:> I've added all of this in, but it's telling me that there's no **Sub SendPlayerNewXY**, since it's saying that there's a Sub or Function not defined in this statement:> > ```> Call SendPlayerNewXY(Index)> ```> I looked through your code and didn't seem to miss anything. Are you sure you added that sub in?It is already in the server, in modServerTCP.bas - forth line (first sub in it):```Sub SendPlayerNewXY(ByVal index As Long) Call SendDataTo(index, "PLAYERNEWXY" & SEP_CHAR & GetPlayerX(index) & SEP_CHAR & GetPlayerY(index) & END_CHAR)End Sub```I didn't add it, it was already there. Link to comment Share on other sites More sharing options...
Kimimaru Posted September 7, 2009 Share Posted September 7, 2009 Oh, okay. Thanks! I'm using **Eclipse Evolution 2.7**, so that's probably why it wasn't there for me. You're probably using a more updated version of Eclipse.EDIT: Wow, this works so well! It's amazing! Thanks so much!A great way to test this would be to go to an area with blocks, open up the mapeditor, remove the blocks, and then try to walk onto the blocked area without saving the map or exiting the map editor. It automatically moves you back to your original spot, since in the map, you're technically not allowed to move onto the blocked areas.Thanks again! Link to comment Share on other sites More sharing options...
Scorpious2k Posted September 7, 2009 Author Share Posted September 7, 2009 @Kimimaru:> Oh, okay. Thanks! I'm using **Eclipse Evolution 2.7**, so that's probably why it wasn't there for me. You're probably using a more updated version of Eclipse.Yes, I am using 2.8 from here: [http://rapidshare.com/files/260780159/Eclipse_2.8_.rar.html](http://rapidshare.com/files/260780159/Eclipse_2.8_.rar.html)There are plenty of good fixes in it that would make it worth the upgrade for you. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now