void SaveInfo_Write(SaveInfo *info, Writer *writer) { saveheader_t *hdr; DENG_ASSERT(info != 0); hdr = &info->header; Writer_WriteInt32(writer, hdr->magic); Writer_WriteInt32(writer, hdr->version); Writer_WriteInt32(writer, hdr->gameMode); Str_Write(&info->name, writer); Writer_WriteByte(writer, hdr->skill); Writer_WriteByte(writer, hdr->episode); Writer_WriteByte(writer, hdr->map); Writer_WriteByte(writer, hdr->deathmatch); Writer_WriteByte(writer, hdr->noMonsters); #if __JHEXEN__ Writer_WriteByte(writer, hdr->randomClasses); #else Writer_WriteByte(writer, hdr->respawnMonsters); Writer_WriteInt32(writer, hdr->mapTime); { int i; for(i = 0; i < MAXPLAYERS; ++i) { Writer_WriteByte(writer, hdr->players[i]); }} #endif Writer_WriteInt32(writer, info->gameId); }
void playerheader_s::write(Writer1 *writer) { Writer_WriteByte(writer, 2); // version byte numPowers = NUM_POWER_TYPES; numKeys = NUM_KEY_TYPES; numFrags = MAXPLAYERS; numWeapons = NUM_WEAPON_TYPES; numAmmoTypes = NUM_AMMO_TYPES; numPSprites = NUMPSPRITES; #if __JHERETIC__ || __JHEXEN__ || __JDOOM64__ numInvItemTypes = NUM_INVENTORYITEM_TYPES; #endif #if __JHEXEN__ numArmorTypes = NUMARMOR; #endif Writer_WriteInt32(writer, numPowers); Writer_WriteInt32(writer, numKeys); Writer_WriteInt32(writer, numFrags); Writer_WriteInt32(writer, numWeapons); Writer_WriteInt32(writer, numAmmoTypes); Writer_WriteInt32(writer, numPSprites); #if __JDOOM64__ || __JHERETIC__ || __JHEXEN__ Writer_WriteInt32(writer, numInvItemTypes); #endif #if __JHEXEN__ Writer_WriteInt32(writer, numArmorTypes); #endif }
/** * The actual script is sent to the clients. @a script can be NULL. */ void Sv_Finale(finaleid_t id, int flags, const char* script) { size_t scriptLen = 0; if(isClient) return; // How much memory do we need? if(script) { flags |= FINF_SCRIPT; scriptLen = strlen(script); } // First the flags. Msg_Begin(PSV_FINALE); Writer_WriteByte(msgWriter, flags); Writer_WriteUInt32(msgWriter, id); // serverside Id if(script) { // Then the script itself. Writer_WriteUInt32(msgWriter, scriptLen); Writer_Write(msgWriter, script, scriptLen); } Msg_End(); Net_SendBuffer(NSP_BROADCAST, 0); }
void writePlayers() { beginSegment(ASEG_PLAYER_HEADER); playerheader_t plrHdr; plrHdr.write(writer); beginSegment(ASEG_PLAYERS); { #if __JHEXEN__ for (int i = 0; i < MAXPLAYERS; ++i) { Writer_WriteByte(writer, players[i].plr->inGame); } #endif for (int i = 0; i < MAXPLAYERS; ++i) { player_t *plr = players + i; if (!plr->plr->inGame) continue; Writer_WriteInt32(writer, Net_GetPlayerID(i)); plr->write(writer, plrHdr); } } endSegment(); }
static void NetSv_SendFinaleState(fi_state_t* s) { Writer* writer = D_NetWrite(); // First the flags. Writer_WriteByte(writer, s->mode); Writer_WriteUInt32(writer, s->finaleId); // Then the conditions. Writer_WriteByte(writer, 2); // Number of conditions. Writer_WriteByte(writer, s->conditions.secret); Writer_WriteByte(writer, s->conditions.leave_hub); Net_SendPacket(DDSP_ALL_PLAYERS, GPT_FINALE_STATE, Writer_Data(writer), Writer_Size(writer)); }
void light_s::write(MapStateWriter *msw) const { Writer1 *writer = msw->writer(); Writer_WriteByte(writer, 1); // Write a version byte. // Note we don't bother to save a byte to tell if the function // is present as we ALWAYS add one when loading. Writer_WriteByte(writer, (byte)type); Writer_WriteInt32(writer, P_ToIndex(sector)); Writer_WriteInt32(writer, (int) (255.0f * value1)); Writer_WriteInt32(writer, (int) (255.0f * value2)); Writer_WriteInt32(writer, tics1); Writer_WriteInt32(writer, tics2); Writer_WriteInt32(writer, count); }
void writeMapHeader() { #if __JHEXEN__ // Maps have their own version number. Writer_WriteByte(writer, MY_SAVE_VERSION); // Write the map timer Writer_WriteInt32(writer, mapTime); #endif }
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 fireflicker_s::write(MapStateWriter *msw) const { Writer1 *writer = msw->writer(); Writer_WriteByte(writer, 1); // Write a version byte. // Note we don't bother to save a byte to tell if the function // is present as we ALWAYS add one when loading. Writer_WriteInt32(writer, P_ToIndex(sector)); Writer_WriteInt32(writer, (int) (255.0f * maxLight)); Writer_WriteInt32(writer, (int) (255.0f * minLight)); }
/** * Serializes the specified thinker and writes it to save state. */ static int writeThinkerWorker(thinker_t *th, void *context) { writethinkerworker_params_t const &p = *static_cast<writethinkerworker_params_t *>(context); // We are only concerned with thinkers we have save info for. ThinkerClassInfo *thInfo = SV_ThinkerInfo(*th); if (!thInfo) return false; // Are we excluding players? if (p.excludePlayers) { if (th->function == P_MobjThinker && ((mobj_t *) th)->player) { return false; } } // Only the server saves this class of thinker? if ((thInfo->flags & TSF_SERVERONLY) && IS_CLIENT) { return false; } // Write the header block for this thinker. Writer_WriteByte(p.msw->writer(), thInfo->thinkclass); // Thinker type byte. Writer_WriteByte(p.msw->writer(), Thinker_InStasis(th)? 1 : 0); // In stasis? // Private identifier of the thinker. de::Id::Type const privateId = (th->d? THINKER_DATA(*th, ThinkerData).id().asUInt32() : 0); Writer_WriteUInt32(p.msw->writer(), privateId); // Write the thinker data. thInfo->writeFunc(th, p.msw); return false; }
/** * 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); }
/** * Serializes thinkers for both client and server. * * @note Clients do not save data for all thinkers. In some cases the server will send it * anyway (so saving it would just bloat client save states). * * @note Some thinker classes are NEVER saved by clients. */ void writeThinkers() { beginSegment(ASEG_THINKERS); #if __JHEXEN__ Writer_WriteInt32(writer, thingArchive->size()); // number of mobjs. #endif // Serialize qualifying thinkers. writethinkerworker_params_t parm; de::zap(parm); parm.msw = thisPublic; parm.excludePlayers = thingArchive->excludePlayers(); Thinker_Iterate(0/*all thinkers*/, writeThinkerWorker, &parm); // Mark the end of the thinkers. // endSegment(); Writer_WriteByte(writer, TC_END); }
void pillar_s::write(MapStateWriter *msw) const { Writer1 *writer = msw->writer(); Writer_WriteByte(writer, 1); // Write a version byte. // Note we don't bother to save a byte to tell if the function // is present as we ALWAYS add one when loading. Writer_WriteInt32(writer, P_ToIndex(sector)); Writer_WriteInt32(writer, FLT2FIX(ceilingSpeed)); Writer_WriteInt32(writer, FLT2FIX(floorSpeed)); Writer_WriteInt32(writer, FLT2FIX(floorDest)); Writer_WriteInt32(writer, FLT2FIX(ceilingDest)); Writer_WriteInt32(writer, direction); Writer_WriteInt32(writer, crush); }
void Net_SendPlayerInfo(int srcPlrNum, int destPlrNum) { size_t nameLen; assert(srcPlrNum >= 0 && srcPlrNum < DDMAXPLAYERS); nameLen = strlen(clients[srcPlrNum].name); #ifdef _DEBUG Con_Message("Net_SendPlayerInfo: src=%i dest=%i name=%s", srcPlrNum, destPlrNum, clients[srcPlrNum].name); #endif Msg_Begin(PKT_PLAYER_INFO); Writer_WriteByte(msgWriter, srcPlrNum); Writer_WriteUInt16(msgWriter, nameLen); Writer_Write(msgWriter, clients[srcPlrNum].name, nameLen); Msg_End(); Net_SendBuffer(destPlrNum, 0); }
void waggle_s::write(MapStateWriter *msw) const { Writer1 *writer = msw->writer(); Writer_WriteByte(writer, 1); // Write a version byte. // Note we don't bother to save a byte to tell if the function // is present as we ALWAYS add one when loading. Writer_WriteInt32(writer, P_ToIndex(sector)); Writer_WriteInt32(writer, FLT2FIX(originalHeight)); Writer_WriteInt32(writer, FLT2FIX(accumulator)); Writer_WriteInt32(writer, FLT2FIX(accDelta)); Writer_WriteInt32(writer, FLT2FIX(targetScale)); Writer_WriteInt32(writer, FLT2FIX(scale)); Writer_WriteInt32(writer, FLT2FIX(scaleDelta)); Writer_WriteInt32(writer, ticker); Writer_WriteInt32(writer, state); }
/** * The delta is written to the message buffer. */ void Sv_WriteMobjDelta(const void* deltaPtr) { const mobjdelta_t* delta = reinterpret_cast<mobjdelta_t const *>(deltaPtr); const dt_mobj_t* d = &delta->mo; int df = delta->delta.flags; byte moreFlags = 0; // Do we have fast momentum? if(fabs(d->mom[MX]) >= MOM_FAST_LIMIT || fabs(d->mom[MY]) >= MOM_FAST_LIMIT || fabs(d->mom[MZ]) >= MOM_FAST_LIMIT) { df |= MDF_MORE_FLAGS; moreFlags |= MDFE_FAST_MOM; } // Any translucency? if(df & MDFC_TRANSLUCENCY) { df |= MDF_MORE_FLAGS; moreFlags |= MDFE_TRANSLUCENCY; } // A fade target? if(df & MDFC_FADETARGET) { df |= MDF_MORE_FLAGS; moreFlags |= MDFE_FADETARGET; } // On the floor? if(df & MDFC_ON_FLOOR) { df |= MDF_MORE_FLAGS; moreFlags |= MDFE_Z_FLOOR; } // Mobj type? if(df & MDFC_TYPE) { df |= MDF_MORE_FLAGS; moreFlags |= MDFE_TYPE; } // Flags. What elements are included in the delta? if(d->selector & ~DDMOBJ_SELECTOR_MASK) df |= MDF_SELSPEC; // Omit NULL state. if(!d->state) { df &= ~MDF_STATE; } /* // Floor/ceiling z? if(df & MDF_ORIGIN_Z) { if(d->pos[VZ] == DDMINFLOAT || d->pos[VZ] == DDMAXFLOAT) { df &= ~MDF_ORIGIN_Z; df |= MDF_MORE_FLAGS; moreFlags |= (d->pos[VZ] == DDMINFLOAT ? MDFE_Z_FLOOR : MDFE_Z_CEILING); } } */ DENG_ASSERT(!(df & MDFC_NULL)); // don't write NULL deltas DENG_ASSERT((df & 0xffff) != 0); // don't write empty deltas // First the mobj ID number and flags. Writer_WriteUInt16(msgWriter, delta->delta.id); Writer_WriteUInt16(msgWriter, df & 0xffff); // More flags? if(df & MDF_MORE_FLAGS) { Writer_WriteByte(msgWriter, moreFlags); } // Coordinates with three bytes. if(df & MDF_ORIGIN_X) { fixed_t vx = FLT2FIX(d->origin[VX]); Writer_WriteInt16(msgWriter, vx >> FRACBITS); Writer_WriteByte(msgWriter, vx >> 8); }
void writeConsistencyBytes() { #if !__JHEXEN__ Writer_WriteByte(writer, CONSISTENCY); #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 }
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 }