X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_netmsg.pas;h=3a2304bb005bca95012c7b85563ee780dddef21e;hb=db4e988645273fe1c11611d84e03f0199cd181f7;hp=f77bdcadd97dbafa8ea20c15c44e4f473ce80806;hpb=923fa980434e55419f35422119af2faae2bf68d7;p=d2df-sdl.git diff --git a/src/game/g_netmsg.pas b/src/game/g_netmsg.pas index f77bdca..3a2304b 100644 --- a/src/game/g_netmsg.pas +++ b/src/game/g_netmsg.pas @@ -52,8 +52,8 @@ const NET_MSG_MSHOT = 134; NET_MSG_MDEL = 135; - NET_MSG_PSTATE = 141; - NET_MSG_PTEX = 142; + NET_MSG_PSTATE = 141; + NET_MSG_PTEX = 142; NET_MSG_TSOUND = 151; NET_MSG_TMUSIC = 152; @@ -168,8 +168,8 @@ procedure MH_SEND_PlayerSettings(PID: Word; Mdl: string = ''; ID: Integer = NET_ procedure MH_SEND_ItemSpawn(Quiet: Boolean; IID: Word; ID: Integer = NET_EVERYONE); procedure MH_SEND_ItemDestroy(Quiet: Boolean; IID: Word; ID: Integer = NET_EVERYONE); // PANEL -procedure MH_SEND_PanelTexture(PType: Word; PID: LongWord; AnimLoop: Byte; ID: Integer = NET_EVERYONE); -procedure MH_SEND_PanelState(PType: Word; PID: LongWord; ID: Integer = NET_EVERYONE); +procedure MH_SEND_PanelTexture(PGUID: Integer; AnimLoop: Byte; ID: Integer = NET_EVERYONE); +procedure MH_SEND_PanelState(PGUID: Integer; ID: Integer = NET_EVERYONE); // MONSTER procedure MH_SEND_MonsterSpawn(UID: Word; ID: Integer = NET_EVERYONE); procedure MH_SEND_MonsterPos(UID: Word; ID: Integer = NET_EVERYONE); @@ -640,6 +640,13 @@ procedure MH_SEND_Everything(CreatePlayers: Boolean = False; ID: Integer = NET_E MH_SEND_MonsterSpawn(mon.UID, ID); end; + function sendPanelState (pan: TPanel): Boolean; + begin + result := false; // don't stop + MH_SEND_PanelState(pan.guid, ID); // anyway, to sync mplats + if (pan.GetTextureCount > 1) then MH_SEND_PanelTexture(pan.guid, pan.LastAnimLoop, ID); + end; + var I: Integer; begin @@ -654,86 +661,38 @@ begin MH_SEND_PlayerStats(gPlayers[I].UID, ID); if (gPlayers[I].Flag <> FLAG_NONE) and (gGameSettings.GameMode = GM_CTF) then + begin MH_SEND_FlagEvent(FLAG_STATE_CAPTURED, gPlayers[I].Flag, gPlayers[I].UID, True, ID); + end; end; end; end; g_Items_ForEachAlive(sendItemRespawn, true); // backwards g_Mons_ForEach(sendMonSpawn); - - if gWalls <> nil then - for I := Low(gWalls) to High(gWalls) do - if gWalls[I] <> nil then - with gWalls[I] do - begin - if Door then - MH_SEND_PanelState(PanelType, I, ID); - - if GetTextureCount > 1 then - MH_SEND_PanelTexture(PanelType, I, LastAnimLoop, ID); - end; - - if gLifts <> nil then - for I := Low(gLifts) to High(gLifts) do - if gLifts[I] <> nil then - with gLifts[I] do - MH_SEND_PanelState(PanelType, I, ID); - - if gRenderForegrounds <> nil then - for I := Low(gRenderForegrounds) to High(gRenderForegrounds) do - if gRenderForegrounds[I] <> nil then - with gRenderForegrounds[I] do - begin - if (GetTextureCount > 1) then - MH_SEND_PanelTexture(PanelType, I, LastAnimLoop, ID); - if Moved then - MH_SEND_PanelState(PanelType, I, ID); - end; - if gRenderBackgrounds <> nil then - for I := Low(gRenderBackgrounds) to High(gRenderBackgrounds) do - if gRenderBackgrounds[I] <> nil then - with gRenderBackgrounds[I] do - begin - if (GetTextureCount > 1) then - MH_SEND_PanelTexture(PanelType, I, LastAnimLoop, ID); - if Moved then - MH_SEND_PanelState(PanelType, I, ID); - end; - if gWater <> nil then - for I := Low(gWater) to High(gWater) do - if gWater[I] <> nil then - with gWater[I] do - if GetTextureCount > 1 then - MH_SEND_PanelTexture(PanelType, I, LastAnimLoop, ID); - if gAcid1 <> nil then - for I := Low(gAcid1) to High(gAcid1) do - if gAcid1[I] <> nil then - with gAcid1[I] do - if GetTextureCount > 1 then - MH_SEND_PanelTexture(PanelType, I, LastAnimLoop, ID); - if gAcid2 <> nil then - for I := Low(gAcid2) to High(gAcid2) do - if gAcid2[I] <> nil then - with gAcid2[I] do - if GetTextureCount > 1 then - MH_SEND_PanelTexture(PanelType, I, LastAnimLoop, ID); - if gSteps <> nil then - for I := Low(gSteps) to High(gSteps) do - if gSteps[I] <> nil then - with gSteps[I] do - if GetTextureCount > 1 then - MH_SEND_PanelTexture(PanelType, I, LastAnimLoop, ID); + g_Map_ForEachPanel(sendPanelState); if gTriggers <> nil then + begin for I := Low(gTriggers) to High(gTriggers) do + begin if gTriggers[I].TriggerType = TRIGGER_SOUND then + begin MH_SEND_TriggerSound(gTriggers[I], ID); + end; + end; + end; if Shots <> nil then + begin for I := Low(Shots) to High(Shots) do + begin if Shots[i].ShotType in [6, 7, 8] then + begin MH_SEND_CreateShot(i, ID); + end; + end; + end; MH_SEND_TriggerMusic(ID); @@ -742,16 +701,16 @@ begin if gGameSettings.GameMode = GM_CTF then begin - if gFlags[FLAG_RED].State <> FLAG_STATE_CAPTURED then - MH_SEND_FlagEvent(gFlags[FLAG_RED].State, FLAG_RED, 0, True, ID); - if gFlags[FLAG_BLUE].State <> FLAG_STATE_CAPTURED then - MH_SEND_FlagEvent(gFlags[FLAG_BLUE].State, FLAG_BLUE, 0, True, ID); + if gFlags[FLAG_RED].State <> FLAG_STATE_CAPTURED then MH_SEND_FlagEvent(gFlags[FLAG_RED].State, FLAG_RED, 0, True, ID); + if gFlags[FLAG_BLUE].State <> FLAG_STATE_CAPTURED then MH_SEND_FlagEvent(gFlags[FLAG_BLUE].State, FLAG_BLUE, 0, True, ID); end; if CreatePlayers and (ID >= 0) then NetClients[ID].State := NET_STATE_GAME; if gLMSRespawn > LMS_RESPAWN_NONE then + begin MH_SEND_GameEvent(NET_EV_LMS_WARMUP, (gLMSRespawnTime - gTime) div 1000, 'N', ID); + end; end; procedure MH_SEND_Info(ID: Byte); @@ -955,7 +914,7 @@ begin NetOut.Write(EvStr); NetOut.Write(Byte(gLastMap)); NetOut.Write(gTime); - if (EvType = NET_EV_MAPSTART) and (Pos(':\', EvStr) > 0) then + if (EvType = NET_EV_MAPSTART) and isWadPath(EvStr) then begin NetOut.Write(Byte(1)); NetOut.Write(gWADHash); @@ -1073,7 +1032,7 @@ begin with P do begin - NetOut.Write(Byte(Live)); + NetOut.Write(Byte(alive)); NetOut.Write(Byte(GodMode)); NetOut.Write(Health); NetOut.Write(Armor); @@ -1217,34 +1176,17 @@ end; // PANEL -procedure MH_SEND_PanelTexture(PType: Word; PID: LongWord; AnimLoop: Byte; ID: Integer = NET_EVERYONE); +procedure MH_SEND_PanelTexture(PGUID: Integer; AnimLoop: Byte; ID: Integer = NET_EVERYONE); var TP: TPanel; begin - case PType of - PANEL_WALL, PANEL_OPENDOOR, PANEL_CLOSEDOOR: - TP := gWalls[PID]; - PANEL_FORE: - TP := gRenderForegrounds[PID]; - PANEL_BACK: - TP := gRenderBackgrounds[PID]; - PANEL_WATER: - TP := gWater[PID]; - PANEL_ACID1: - TP := gAcid1[PID]; - PANEL_ACID2: - TP := gAcid2[PID]; - PANEL_STEP: - TP := gSteps[PID]; - else - Exit; - end; + TP := g_Map_PanelByGUID(PGUID); + if (TP = nil) then exit; with TP do begin NetOut.Write(Byte(NET_MSG_PTEX)); - NetOut.Write(PType); - NetOut.Write(PID); + NetOut.Write(LongWord(PGUID)); NetOut.Write(FCurTexture); NetOut.Write(FCurFrame); NetOut.Write(FCurFrameCount); @@ -1254,36 +1196,36 @@ begin g_Net_Host_Send(ID, True, NET_CHAN_LARGEDATA); end; -procedure MH_SEND_PanelState(PType: Word; PID: LongWord; ID: Integer = NET_EVERYONE); +procedure MH_SEND_PanelState(PGUID: Integer; ID: Integer = NET_EVERYONE); var TP: TPanel; + mpflags: Byte = 0; begin - case PType of - PANEL_WALL, PANEL_OPENDOOR, PANEL_CLOSEDOOR: - TP := gWalls[PID]; - PANEL_LIFTUP, PANEL_LIFTDOWN, PANEL_LIFTLEFT, PANEL_LIFTRIGHT: - TP := gLifts[PID]; - PANEL_BACK: - begin - TP := gRenderBackgrounds[PID]; - TP.Moved := True; - end; - PANEL_FORE: - begin - TP := gRenderForegrounds[PID]; - TP.Moved := True; - end; - else - Exit; - end; + TP := g_Map_PanelByGUID(PGUID); + if (TP = nil) then exit; NetOut.Write(Byte(NET_MSG_PSTATE)); - NetOut.Write(PType); - NetOut.Write(PID); + NetOut.Write(LongWord(PGUID)); NetOut.Write(Byte(TP.Enabled)); NetOut.Write(TP.LiftType); NetOut.Write(TP.X); NetOut.Write(TP.Y); + NetOut.Write(Word(TP.Width)); + NetOut.Write(Word(TP.Height)); + // mplats + NetOut.Write(LongInt(TP.movingSpeedX)); + NetOut.Write(LongInt(TP.movingSpeedY)); + NetOut.Write(LongInt(TP.movingStartX)); + NetOut.Write(LongInt(TP.movingStartY)); + NetOut.Write(LongInt(TP.movingEndX)); + NetOut.Write(LongInt(TP.movingEndY)); + NetOut.Write(LongInt(TP.sizeSpeedX)); + NetOut.Write(LongInt(TP.sizeSpeedY)); + NetOut.Write(LongInt(TP.sizeEndX)); + NetOut.Write(LongInt(TP.sizeEndY)); + if TP.movingActive then mpflags := mpflags or 1; + if TP.moveOnce then mpflags := mpflags or 2; + NetOut.Write(Byte(mpflags)); g_Net_Host_Send(ID, True, NET_CHAN_LARGEDATA); end; @@ -1726,7 +1668,7 @@ begin gWADHash := EvHash; if not g_Game_StartMap(EvStr, True) then begin - if Pos(':\', EvStr) = 0 then + if not isWadPath(EvStr) then g_FatalError(Format(_lc[I_GAME_ERROR_MAP_LOAD], [gGameSettings.WAD + ':\' + EvStr])) else g_FatalError(Format(_lc[I_GAME_ERROR_MAP_LOAD], [EvStr])); @@ -2132,7 +2074,7 @@ begin with Pl do begin - Live := (M.ReadByte() <> 0); + alive := (M.ReadByte() <> 0); GodMode := (M.ReadByte() <> 0); Health := M.ReadLongInt(); Armor := M.ReadLongInt(); @@ -2298,7 +2240,7 @@ begin SHID := M.ReadLongInt(); with Pl do - if Live then NetFire(Weap, X, Y, AX, AY, SHID); + if alive then NetFire(Weap, X, Y, AX, AY, SHID); end; procedure MC_RECV_PlayerSettings(var M: TMsg); @@ -2403,94 +2345,97 @@ end; procedure MC_RECV_PanelTexture(var M: TMsg); var TP: TPanel; - PType: Word; - ID: LongWord; + PGUID: Integer; Tex, Fr: Integer; Loop, Cnt: Byte; begin if not gGameOn then Exit; - PType := M.ReadWord(); - ID := M.ReadLongWord(); + + PGUID := Integer(M.ReadLongWord()); Tex := M.ReadLongInt(); Fr := M.ReadLongInt(); Cnt := M.ReadByte(); Loop := M.ReadByte(); - TP := nil; - - case PType of - PANEL_WALL, PANEL_OPENDOOR, PANEL_CLOSEDOOR: - if gWalls <> nil then - TP := gWalls[ID]; - PANEL_FORE: - if gRenderForegrounds <> nil then - TP := gRenderForegrounds[ID]; - PANEL_BACK: - if gRenderBackgrounds <> nil then - TP := gRenderBackgrounds[ID]; - PANEL_WATER: - if gWater <> nil then - TP := gWater[ID]; - PANEL_ACID1: - if gAcid1 <> nil then - TP := gAcid1[ID]; - PANEL_ACID2: - if gAcid2 <> nil then - TP := gAcid2[ID]; - PANEL_STEP: - if gSteps <> nil then - TP := gSteps[ID]; - else - Exit; - end; - - if TP <> nil then + TP := g_Map_PanelByGUID(PGUID); + if (TP <> nil) then + begin if Loop = 0 then - begin // switch texture + begin + // switch texture TP.SetTexture(Tex, Loop); TP.SetFrame(Fr, Cnt); - end else // looped or non-looped animation + end + else + begin + // looped or non-looped animation TP.NextTexture(Loop); + end; + end; end; procedure MC_RECV_PanelState(var M: TMsg); var - ID: LongWord; + PGUID: Integer; E: Boolean; Lift: Byte; - PType: Word; - X, Y: Integer; + X, Y, W, H: Integer; + TP: TPanel; + speedX, speedY, startX, startY, endX, endY: Integer; + sizeSpX, sizeSpY, sizeEX, sizeEY: Integer; + mpflags: Byte; begin if not gGameOn then Exit; - PType := M.ReadWord(); - ID := M.ReadLongWord(); + + PGUID := Integer(M.ReadLongWord()); E := (M.ReadByte() <> 0); Lift := M.ReadByte(); X := M.ReadLongInt(); Y := M.ReadLongInt(); - - case PType of - PANEL_WALL, PANEL_OPENDOOR, PANEL_CLOSEDOOR: - if E then - g_Map_EnableWall(ID) - else - g_Map_DisableWall(ID); - - PANEL_LIFTUP, PANEL_LIFTDOWN, PANEL_LIFTLEFT, PANEL_LIFTRIGHT: - g_Map_SetLift(ID, Lift); - - PANEL_BACK: - begin - gRenderBackgrounds[ID].X := X; - gRenderBackgrounds[ID].Y := Y; - end; - - PANEL_FORE: - begin - gRenderForegrounds[ID].X := X; - gRenderForegrounds[ID].Y := Y; - end; - end; + W := M.ReadWord(); + H := M.ReadWord(); + // mplats + speedX := M.ReadLongInt(); + speedY := M.ReadLongInt(); + startX := M.ReadLongInt(); + startY := M.ReadLongInt(); + endX := M.ReadLongInt(); + endY := M.ReadLongInt(); + sizeSpX := M.ReadLongInt(); + sizeSpY := M.ReadLongInt(); + sizeEX := M.ReadLongInt(); + sizeEY := M.ReadLongInt(); + mpflags := M.ReadByte(); // bit0: TP.movingActive; bit1: TP.moveOnce + + TP := g_Map_PanelByGUID(PGUID); + if (TP = nil) then exit; + + // update lifts state + if TP.isGLift then g_Map_SetLiftGUID(PGUID, Lift); + + // update enabled/disabled state for all panels + if E then g_Map_EnableWallGUID(PGUID) else g_Map_DisableWallGUID(PGUID); + + // update panel position, as it can be moved (mplat) + TP.X := X; + TP.Y := Y; + TP.Width := W; + TP.Height := H; + // update mplat state + TP.movingSpeedX := speedX; + TP.movingSpeedY := speedY; + TP.movingStartX := startX; + TP.movingStartY := startY; + TP.movingEndX := endX; + TP.movingEndY := endY; + TP.sizeSpeedX := sizeSpX; + TP.sizeSpeedY := sizeSpY; + TP.sizeEndX := sizeEX; + TP.sizeEndY := sizeEY; + TP.movingActive := ((mpflags and 1) <> 0); + TP.moveOnce := ((mpflags and 2) <> 0); + // notify panel of it's position/size change, so it can fix other internal structures + TP.positionChanged(); end; // TRIGGERS @@ -2517,10 +2462,10 @@ begin begin if SPlaying then begin - if trigData.trigLocal then - Sound.PlayVolumeAt(X+(Width div 2), Y+(Height div 2), trigData.trigVolume/255.0) + if tgcLocal then + Sound.PlayVolumeAt(X+(Width div 2), Y+(Height div 2), tgcVolume/255.0) else - Sound.PlayPanVolume((trigData.trigPan-127.0)/128.0, trigData.trigVolume/255.0); + Sound.PlayPanVolume((tgcPan-127.0)/128.0, tgcVolume/255.0); Sound.SetPosition(SPos); end else @@ -2593,10 +2538,6 @@ begin with Mon do begin - GameX := X; - GameY := Y; - GameVelX := VX; - GameVelY := VY; MonsterAnim := MAnim; MonsterTargetUID := MTarg; @@ -2608,7 +2549,9 @@ begin SetState(MState); - positionChanged(); // this updates spatial accelerators + setPosition(X, Y); // this will call positionChanged(); + GameVelX := VX; + GameVelY := VY; end; end; @@ -2616,6 +2559,7 @@ procedure MC_RECV_MonsterPos(var M: TMsg); var Mon: TMonster; ID: Word; + X, Y: Integer; begin ID := M.ReadWord(); Mon := g_Monsters_ByUID(ID); @@ -2624,12 +2568,12 @@ begin with Mon do begin - GameX := M.ReadLongInt(); - GameY := M.ReadLongInt(); + X := M.ReadLongInt(); + Y := M.ReadLongInt(); + Mon.setPosition(X, Y); // this will call `positionChanged()` GameVelX := M.ReadLongInt(); GameVelY := M.ReadLongInt(); GameDirection := TDirection(M.ReadByte()); - positionChanged(); // this updates spatial accelerators end; end; @@ -2661,16 +2605,11 @@ begin if MonsterState <> MState then begin - if (MState = MONSTATE_GO) and (MonsterState = MONSTATE_SLEEP) then - WakeUpSound; - if (MState = MONSTATE_DIE) then - DieSound; - if (MState = MONSTATE_PAIN) then - MakeBloodSimple(Min(200, MonsterPain)); - if (MState = MONSTATE_ATTACK) then - kick(nil); - if (MState = MONSTATE_DEAD) then - SetDeadAnim; + if (MState = MONSTATE_GO) and (MonsterState = MONSTATE_SLEEP) then WakeUpSound(); + if (MState = MONSTATE_DIE) then DieSound(); + if (MState = MONSTATE_PAIN) then MakeBloodSimple(Min(200, MonsterPain)); + if (MState = MONSTATE_ATTACK) then kick(nil); + if (MState = MONSTATE_DEAD) then SetDeadAnim(); SetState(MState, MFAnm); end;