Esempio n. 1
0
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);
}
Esempio n. 2
0
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
}
Esempio n. 3
0
/**
 * 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);
}
Esempio n. 4
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();
    }
Esempio n. 5
0
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));
}
Esempio n. 6
0
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);
}
Esempio n. 7
0
    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
    }
Esempio n. 8
0
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);
}
Esempio n. 9
0
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));
}
Esempio n. 10
0
    /**
     * 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;
    }
Esempio n. 11
0
/**
 * 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);
}
Esempio n. 12
0
    /**
     * 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);
    }
Esempio n. 13
0
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);
}
Esempio n. 14
0
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);
}
Esempio n. 15
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);
}
Esempio n. 16
0
/**
 * 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);
    }
Esempio n. 17
0
    void writeConsistencyBytes()
    {
#if !__JHEXEN__
        Writer_WriteByte(writer, CONSISTENCY);
#endif
    }
Esempio n. 18
0
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
}
Esempio n. 19
0
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
}
Esempio n. 20
0
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
}