void writeSoundTargets() { #if !__JHEXEN__ if (!IS_SERVER) return; // Not for us. // Write the total number. int count = 0; for (int i = 0; i < numsectors; ++i) { xsector_t *xsec = P_ToXSector((Sector *)P_ToPtr(DMU_SECTOR, i)); if (xsec->soundTarget) { count += 1; } } // beginSegment(); Writer_WriteInt32(writer, count); // Write the mobj references using the mobj archive. for (int i = 0; i < numsectors; ++i) { xsector_t *xsec = P_ToXSector((Sector *)P_ToPtr(DMU_SECTOR, i)); if (xsec->soundTarget) { Writer_WriteInt32(writer, i); Writer_WriteInt16(writer, thingArchive->serialIdFor(xsec->soundTarget)); } } // endSegment(); #endif }
/** * Writes a view angle and coords packet. Doesn't send the packet outside. */ void Demo_WriteLocalCamera(int plrNum) { player_t* plr = &ddPlayers[plrNum]; ddplayer_t* ddpl = &plr->shared; mobj_t* mo = ddpl->mo; fixed_t x, y, z; byte flags; boolean incfov = (writeInfo[plrNum].fov != fieldOfView); const viewdata_t* viewData = R_ViewData(plrNum); if(!mo) return; Msg_Begin(clients[plrNum].recordPaused ? PKT_DEMOCAM_RESUME : PKT_DEMOCAM); // Flags. flags = (mo->origin[VZ] <= mo->floorZ ? LCAMF_ONGROUND : 0) // On ground? | (incfov ? LCAMF_FOV : 0); if(ddpl->flags & DDPF_CAMERA) { flags &= ~LCAMF_ONGROUND; flags |= LCAMF_CAMERA; } Writer_WriteByte(msgWriter, flags); // Coordinates. x = FLT2FIX(mo->origin[VX]); y = FLT2FIX(mo->origin[VY]); Writer_WriteInt16(msgWriter, x >> 16); Writer_WriteByte(msgWriter, x >> 8); Writer_WriteInt16(msgWriter, y >> 16); Writer_WriteByte(msgWriter, y >> 8); z = FLT2FIX(mo->origin[VZ] + viewData->current.origin[VZ]); Writer_WriteInt16(msgWriter, z >> 16); Writer_WriteByte(msgWriter, z >> 8); Writer_WriteInt16(msgWriter, mo->angle /*ddpl->clAngle*/ >> 16); /* $unifiedangles */ Writer_WriteInt16(msgWriter, ddpl->lookDir / 110 * DDMAXSHORT /* $unifiedangles */); // Field of view is optional. if(incfov) { Writer_WriteInt16(msgWriter, fieldOfView / 180 * DDMAXSHORT); writeInfo[plrNum].fov = fieldOfView; } Msg_End(); Net_SendBuffer(plrNum, SPF_DONT_SEND); }
void plat_t::write(MapStateWriter *msw) const { Writer *writer = msw->writer(); Writer_WriteByte(writer, 1); // Write a version byte. Writer_WriteByte(writer, (byte) type); Writer_WriteInt32(writer, P_ToIndex(sector)); Writer_WriteInt32(writer, FLT2FIX(speed)); Writer_WriteInt16(writer, (int)low); Writer_WriteInt16(writer, (int)high); Writer_WriteInt32(writer, wait); Writer_WriteInt32(writer, count); Writer_WriteByte(writer, (byte) state); Writer_WriteByte(writer, (byte) oldState); Writer_WriteByte(writer, (byte) crush); Writer_WriteInt32(writer, tag); }
void SV_WriteLine(Line *li, MapStateWriter *msw) { xline_t *xli = P_ToXLine(li); Writer1 *writer = msw->writer(); #if !__JHEXEN__ Writer_WriteByte(writer, xli->xg? 1 : 0); /// @c 1= XG data will follow. #else Writer_WriteByte(writer, 0); #endif // Version. // 2: Per surface texture offsets. // 2: Surface colors. // 3: "Mapped by player" values. // 3: Surface flags. // 4: Engine-side line flags. Writer_WriteByte(writer, 4); // Write a version byte Writer_WriteInt16(writer, P_GetIntp(li, DMU_FLAGS)); Writer_WriteInt16(writer, xli->flags); for(int i = 0; i < MAXPLAYERS; ++i) Writer_WriteByte(writer, xli->mapped[i]); #if __JHEXEN__ Writer_WriteByte(writer, xli->special); Writer_WriteByte(writer, xli->arg1); Writer_WriteByte(writer, xli->arg2); Writer_WriteByte(writer, xli->arg3); Writer_WriteByte(writer, xli->arg4); Writer_WriteByte(writer, xli->arg5); #else Writer_WriteInt16(writer, xli->special); Writer_WriteInt16(writer, xli->tag); #endif // For each side float rgba[4]; for(int i = 0; i < 2; ++i) { Side *si = (Side *)P_GetPtrp(li, (i? DMU_BACK:DMU_FRONT)); if(!si) continue; Writer_WriteInt16(writer, P_GetIntp(si, DMU_TOP_MATERIAL_OFFSET_X)); Writer_WriteInt16(writer, P_GetIntp(si, DMU_TOP_MATERIAL_OFFSET_Y)); Writer_WriteInt16(writer, P_GetIntp(si, DMU_MIDDLE_MATERIAL_OFFSET_X)); Writer_WriteInt16(writer, P_GetIntp(si, DMU_MIDDLE_MATERIAL_OFFSET_Y)); Writer_WriteInt16(writer, P_GetIntp(si, DMU_BOTTOM_MATERIAL_OFFSET_X)); Writer_WriteInt16(writer, P_GetIntp(si, DMU_BOTTOM_MATERIAL_OFFSET_Y)); Writer_WriteInt16(writer, P_GetIntp(si, DMU_TOP_FLAGS)); Writer_WriteInt16(writer, P_GetIntp(si, DMU_MIDDLE_FLAGS)); Writer_WriteInt16(writer, P_GetIntp(si, DMU_BOTTOM_FLAGS)); Writer_WriteInt16(writer, msw->serialIdFor((world_Material *)P_GetPtrp(si, DMU_TOP_MATERIAL))); Writer_WriteInt16(writer, msw->serialIdFor((world_Material *)P_GetPtrp(si, DMU_BOTTOM_MATERIAL))); Writer_WriteInt16(writer, msw->serialIdFor((world_Material *)P_GetPtrp(si, DMU_MIDDLE_MATERIAL))); P_GetFloatpv(si, DMU_TOP_COLOR, rgba); for(int k = 0; k < 3; ++k) Writer_WriteByte(writer, (byte)(255 * rgba[k])); P_GetFloatpv(si, DMU_BOTTOM_COLOR, rgba); for(int k = 0; k < 3; ++k) Writer_WriteByte(writer, (byte)(255 * rgba[k])); P_GetFloatpv(si, DMU_MIDDLE_COLOR, rgba); for(int k = 0; k < 4; ++k) Writer_WriteByte(writer, (byte)(255 * rgba[k])); Writer_WriteInt32(writer, P_GetIntp(si, DMU_MIDDLE_BLENDMODE)); Writer_WriteInt16(writer, P_GetIntp(si, DMU_FLAGS)); } #if !__JHEXEN__ // Extended General? if(xli->xg) { SV_WriteXGLine(li, msw); } #endif }
void SV_WriteSector(Sector *sec, MapStateWriter *msw) { Writer1 *writer = msw->writer(); int i, type; float flooroffx = P_GetFloatp(sec, DMU_FLOOR_MATERIAL_OFFSET_X); float flooroffy = P_GetFloatp(sec, DMU_FLOOR_MATERIAL_OFFSET_Y); float ceiloffx = P_GetFloatp(sec, DMU_CEILING_MATERIAL_OFFSET_X); float ceiloffy = P_GetFloatp(sec, DMU_CEILING_MATERIAL_OFFSET_Y); byte lightlevel = (byte) (255.f * P_GetFloatp(sec, DMU_LIGHT_LEVEL)); short floorheight = (short) P_GetIntp(sec, DMU_FLOOR_HEIGHT); short ceilingheight = (short) P_GetIntp(sec, DMU_CEILING_HEIGHT); short floorFlags = (short) P_GetIntp(sec, DMU_FLOOR_FLAGS); short ceilingFlags = (short) P_GetIntp(sec, DMU_CEILING_FLAGS); world_Material *floorMaterial = (world_Material *)P_GetPtrp(sec, DMU_FLOOR_MATERIAL); world_Material *ceilingMaterial = (world_Material *)P_GetPtrp(sec, DMU_CEILING_MATERIAL); xsector_t *xsec = P_ToXSector(sec); #if !__JHEXEN__ // Determine type. if(xsec->xg) type = sc_xg1; else #endif if(NON_ZERO(flooroffx) || NON_ZERO(flooroffy) || NON_ZERO(ceiloffx) || NON_ZERO(ceiloffy)) type = sc_ploff; else type = sc_normal; // Type byte. Writer_WriteByte(writer, type); // Version. // 2: Surface colors. // 3: Surface flags. Writer_WriteByte(writer, 3); // write a version byte. Writer_WriteInt16(writer, floorheight); Writer_WriteInt16(writer, ceilingheight); Writer_WriteInt16(writer, msw->serialIdFor(floorMaterial)); Writer_WriteInt16(writer, msw->serialIdFor(ceilingMaterial)); Writer_WriteInt16(writer, floorFlags); Writer_WriteInt16(writer, ceilingFlags); #if __JHEXEN__ Writer_WriteInt16(writer, (short) lightlevel); #else Writer_WriteByte(writer, lightlevel); #endif float rgb[3]; P_GetFloatpv(sec, DMU_COLOR, rgb); for(i = 0; i < 3; ++i) Writer_WriteByte(writer, (byte)(255.f * rgb[i])); P_GetFloatpv(sec, DMU_FLOOR_COLOR, rgb); for(i = 0; i < 3; ++i) Writer_WriteByte(writer, (byte)(255.f * rgb[i])); P_GetFloatpv(sec, DMU_CEILING_COLOR, rgb); for(i = 0; i < 3; ++i) Writer_WriteByte(writer, (byte)(255.f * rgb[i])); Writer_WriteInt16(writer, xsec->special); Writer_WriteInt16(writer, xsec->tag); #if __JHEXEN__ Writer_WriteInt16(writer, xsec->seqType); #endif if(type == sc_ploff #if !__JHEXEN__ || type == sc_xg1 #endif ) { Writer_WriteFloat(writer, flooroffx); Writer_WriteFloat(writer, flooroffy); Writer_WriteFloat(writer, ceiloffx); Writer_WriteFloat(writer, ceiloffy); } #if !__JHEXEN__ if(xsec->xg) // Extended General? { SV_WriteXGSector(sec, writer); } #endif }
void mobj_s::write(MapStateWriter *msw) const { Writer1 *writer = msw->writer(); mobj_t const *mo = this; // Version. // JHEXEN // 2: Added the 'translucency' byte. // 3: Added byte 'vistarget' // 4: Added long 'tracer' // 4: Added long 'lastenemy' // 5: Added flags3 // 6: Floor material removed. // // JDOOM || JHERETIC || JDOOM64 // 4: Added byte 'translucency' // 5: Added byte 'vistarget' // 5: Added tracer in jDoom // 5: Added dropoff fix in jHeretic // 5: Added long 'floorclip' // 6: Added proper respawn data // 6: Added flags 2 in jDoom // 6: Added damage // 7: Added generator in jHeretic // 7: Added flags3 // // JDOOM // 9: Revised mapspot flag interpretation // // JHERETIC // 8: Added special3 // 9: Revised mapspot flag interpretation // // JHEXEN // 7: Removed superfluous info ptr // 8: Added 'onMobj' Writer_WriteByte(writer, MOBJ_SAVEVERSION); #if !__JHEXEN__ // A version 2 features: archive number and target. Writer_WriteInt16(writer, msw->serialIdFor(mo)); Writer_WriteInt16(writer, msw->serialIdFor(mo->target)); # if __JDOOM__ || __JDOOM64__ // Ver 5 features: Save tracer (fixes Archvile, Revenant bug) Writer_WriteInt16(writer, msw->serialIdFor(mo->tracer)); # endif #endif Writer_WriteInt16(writer, msw->serialIdFor(mo->onMobj)); // Info for drawing: position. Writer_WriteInt32(writer, FLT2FIX(mo->origin[VX])); Writer_WriteInt32(writer, FLT2FIX(mo->origin[VY])); Writer_WriteInt32(writer, FLT2FIX(mo->origin[VZ])); //More drawing info: to determine current sprite. Writer_WriteInt32(writer, mo->angle); // Orientation. Writer_WriteInt32(writer, mo->sprite); // Used to find patch_t and flip value. Writer_WriteInt32(writer, mo->frame); #if !__JHEXEN__ // The closest interval over all contacted Sectors. Writer_WriteInt32(writer, FLT2FIX(mo->floorZ)); Writer_WriteInt32(writer, FLT2FIX(mo->ceilingZ)); #endif // For movement checking. Writer_WriteInt32(writer, FLT2FIX(mo->radius)); Writer_WriteInt32(writer, FLT2FIX(mo->height)); // Momentums, used to update position. Writer_WriteInt32(writer, FLT2FIX(mo->mom[MX])); Writer_WriteInt32(writer, FLT2FIX(mo->mom[MY])); Writer_WriteInt32(writer, FLT2FIX(mo->mom[MZ])); // If == VALIDCOUNT, already checked. Writer_WriteInt32(writer, mo->valid); Writer_WriteInt32(writer, mo->type); Writer_WriteInt32(writer, mo->tics); // State tic counter. Writer_WriteInt32(writer, int(mo->state - STATES) /*PTR2INT(mo->state)*/); #if __JHEXEN__ Writer_WriteInt32(writer, mo->damage); #endif Writer_WriteInt32(writer, mo->flags); #if __JHEXEN__ Writer_WriteInt32(writer, mo->flags2); Writer_WriteInt32(writer, mo->flags3); if(mo->type == MT_KORAX) Writer_WriteInt32(writer, 0); // Searching index. else Writer_WriteInt32(writer, mo->special1); switch(mo->type) { case MT_LIGHTNING_FLOOR: case MT_LIGHTNING_ZAP: case MT_HOLY_TAIL: case MT_LIGHTNING_CEILING: if(mo->flags & MF_CORPSE) Writer_WriteInt32(writer, 0); else Writer_WriteInt32(writer, msw->serialIdFor(INT2PTR(mobj_t, mo->special2))); break; default: Writer_WriteInt32(writer, mo->special2); break; } #endif Writer_WriteInt32(writer, mo->health); // Movement direction, movement generation (zig-zagging). Writer_WriteInt32(writer, mo->moveDir); // 0-7 Writer_WriteInt32(writer, mo->moveCount); // When 0, select a new dir. #if __JHEXEN__ if(mo->flags & MF_CORPSE) Writer_WriteInt32(writer, 0); else Writer_WriteInt32(writer, (int) msw->serialIdFor(mo->target)); #endif // Reaction time: if non 0, don't attack yet. // Used by player to freeze a bit after teleporting. Writer_WriteInt32(writer, mo->reactionTime); // If >0, the target will be chased no matter what (even if shot). Writer_WriteInt32(writer, mo->threshold); // Additional info record for player avatars only (only valid if type is MT_PLAYER). { int const playerNum = (mo->player? int(mo->player - players + 1) : 0); Writer_WriteInt32(writer, playerNum /*PTR2INT(mo->player)*/); } // Player number last looked for. Writer_WriteInt32(writer, mo->lastLook); #if !__JHEXEN__ // For nightmare/multiplayer respawn. Writer_WriteInt32(writer, FLT2FIX(mo->spawnSpot.origin[VX])); Writer_WriteInt32(writer, FLT2FIX(mo->spawnSpot.origin[VY])); Writer_WriteInt32(writer, FLT2FIX(mo->spawnSpot.origin[VZ])); Writer_WriteInt32(writer, mo->spawnSpot.angle); Writer_WriteInt32(writer, mo->spawnSpot.flags); Writer_WriteInt32(writer, mo->intFlags); // $dropoff_fix: internal flags. Writer_WriteInt32(writer, FLT2FIX(mo->dropOffZ)); // $dropoff_fix Writer_WriteInt32(writer, mo->gear); // Used in torque simulation. Writer_WriteInt32(writer, mo->damage); Writer_WriteInt32(writer, mo->flags2); Writer_WriteInt32(writer, mo->flags3); # ifdef __JHERETIC__ Writer_WriteInt32(writer, mo->special1); Writer_WriteInt32(writer, mo->special2); Writer_WriteInt32(writer, mo->special3); # endif Writer_WriteByte(writer, mo->translucency); Writer_WriteByte(writer, (byte)(mo->visTarget + 1)); #endif Writer_WriteInt32(writer, FLT2FIX(mo->floorClip)); #if __JHEXEN__ Writer_WriteInt32(writer, msw->serialIdFor(mo)); Writer_WriteInt32(writer, mo->tid); Writer_WriteInt32(writer, mo->special); Writer_Write(writer, mo->args, sizeof(mo->args)); Writer_WriteByte(writer, mo->translucency); Writer_WriteByte(writer, (byte)(mo->visTarget + 1)); switch(mo->type) { case MT_BISH_FX: case MT_HOLY_FX: case MT_DRAGON: case MT_THRUSTFLOOR_UP: case MT_THRUSTFLOOR_DOWN: case MT_MINOTAUR: case MT_SORCFX1: case MT_MSTAFF_FX2: case MT_HOLY_TAIL: case MT_LIGHTNING_CEILING: if(mo->flags & MF_CORPSE) Writer_WriteInt32(writer, 0); else Writer_WriteInt32(writer, msw->serialIdFor(mo->tracer)); break; default: DENG_ASSERT(mo->tracer == NULL); /// @todo Tracer won't be saved correctly? Writer_WriteInt32(writer, PTR2INT(mo->tracer)); break; } Writer_WriteInt32(writer, PTR2INT(mo->lastEnemy)); #elif __JHERETIC__ Writer_WriteInt16(writer, msw->serialIdFor(mo->generator)); #endif }
static void Net_DoUpdate(void) { static int lastTime = 0; int nowTime, newTics; /** * This timing is only used by the client when it determines if it is * time to send ticcmds or coordinates to the server. */ // Check time. nowTime = Timer_Ticks(); // Clock reset? if(firstNetUpdate) { firstNetUpdate = false; lastTime = nowTime; } newTics = nowTime - lastTime; if(newTics <= 0) return; // Nothing new to update. lastTime = nowTime; // This is as far as dedicated servers go. #ifdef __CLIENT__ /** * Clients will periodically send their coordinates to the server so * any prediction errors can be fixed. Client movement is almost * entirely local. */ #ifdef _DEBUG if(netGame && verbose >= 2) { Con_Message("Net_DoUpdate: coordTimer=%i cl:%i shmo:%p", coordTimer, isClient, ddPlayers[consolePlayer].shared.mo); } #endif coordTimer -= newTics; if(isClient && coordTimer <= 0 && ddPlayers[consolePlayer].shared.mo) { mobj_t *mo = ddPlayers[consolePlayer].shared.mo; coordTimer = 1; //netCoordTime; // 35/2 Msg_Begin(PKT_COORDS); Writer_WriteFloat(msgWriter, gameTime); Writer_WriteFloat(msgWriter, mo->origin[VX]); Writer_WriteFloat(msgWriter, mo->origin[VY]); if(mo->origin[VZ] == mo->floorZ) { // This'll keep us on the floor even in fast moving sectors. Writer_WriteInt32(msgWriter, DDMININT); } else { Writer_WriteInt32(msgWriter, FLT2FIX(mo->origin[VZ])); } // Also include angles. Writer_WriteUInt16(msgWriter, mo->angle >> 16); Writer_WriteInt16(msgWriter, P_LookDirToShort(ddPlayers[consolePlayer].shared.lookDir)); // Control state. Writer_WriteChar(msgWriter, FLT2FIX(ddPlayers[consolePlayer].shared.forwardMove) >> 13); Writer_WriteChar(msgWriter, FLT2FIX(ddPlayers[consolePlayer].shared.sideMove) >> 13); Msg_End(); Net_SendBuffer(0, 0); }