Beispiel #1
0
static void SV_v13_ReadMobj(void)
{
    coord_t pos[3], mom[3], floorz, ceilingz, radius, height;
    int frame, valid, type, ddflags = 0;
    spritenum_t sprite;
    mobjinfo_t* info;
    angle_t angle;
    mobj_t* mo;

    // The thinker was 3 ints long.
    Reader_ReadInt32(svReader);
    Reader_ReadInt32(svReader);
    Reader_ReadInt32(svReader);

    pos[VX] = FIX2FLT(Reader_ReadInt32(svReader));
    pos[VY] = FIX2FLT(Reader_ReadInt32(svReader));
    pos[VZ] = FIX2FLT(Reader_ReadInt32(svReader));

    // Sector links.
    Reader_ReadInt32(svReader);
    Reader_ReadInt32(svReader);

    angle = (angle_t) (ANG45 * (Reader_ReadInt32(svReader) / 45));
    sprite = Reader_ReadInt32(svReader);
    frame = Reader_ReadInt32(svReader);
    frame &= ~FF_FRAMEMASK; // not used anymore.

    // Block links.
    Reader_ReadInt32(svReader);
    Reader_ReadInt32(svReader);

    // BspLeaf.
    Reader_ReadInt32(svReader);

    floorz   = FIX2FLT(Reader_ReadInt32(svReader));
    ceilingz = FIX2FLT(Reader_ReadInt32(svReader));
    radius   = FIX2FLT(Reader_ReadInt32(svReader));
    height   = FIX2FLT(Reader_ReadInt32(svReader));
    mom[MX]  = FIX2FLT(Reader_ReadInt32(svReader));
    mom[MY]  = FIX2FLT(Reader_ReadInt32(svReader));
    mom[MZ]  = FIX2FLT(Reader_ReadInt32(svReader));
    valid    = Reader_ReadInt32(svReader);
    type     = Reader_ReadInt32(svReader);

    info = &MOBJINFO[type];

    if(info->flags & MF_SOLID)
        ddflags |= DDMF_SOLID;
    if(info->flags2 & MF2_DONTDRAW)
        ddflags |= DDMF_DONTDRAW;

    /**
     * We now have all the information we need to create the mobj.
     */
    mo = P_MobjCreateXYZ(P_MobjThinker, pos[VX], pos[VY], pos[VZ], angle,
                         radius, height, ddflags);

    mo->sprite  = sprite;
    mo->frame   = frame;
    mo->floorZ  = floorz;
    mo->ceilingZ = ceilingz;
    mo->mom[MX] = mom[MX];
    mo->mom[MY] = mom[MY];
    mo->mom[MZ] = mom[MZ];
    mo->valid   = valid;
    mo->type    = type;
    mo->moveDir = DI_NODIR;

    /**
     * Continue reading the mobj data.
     */

    Reader_ReadInt32(svReader); // info

    mo->tics     = Reader_ReadInt32(svReader);
    mo->state    = INT2PTR(state_t, Reader_ReadInt32(svReader));
    mo->damage   = Reader_ReadInt32(svReader);
    mo->flags    = Reader_ReadInt32(svReader);
    mo->flags2   = Reader_ReadInt32(svReader);
    mo->special1 = Reader_ReadInt32(svReader);
    mo->special2 = Reader_ReadInt32(svReader);
    mo->health   = Reader_ReadInt32(svReader);

    // Fix a bunch of kludges in the original Heretic.
    switch(mo->type)
    {
    case MT_MACEFX1:
    case MT_MACEFX2:
    case MT_MACEFX3:
    case MT_HORNRODFX2:
    case MT_HEADFX3:
    case MT_WHIRLWIND:
    case MT_TELEGLITTER:
    case MT_TELEGLITTER2:
        mo->special3 = mo->health;
        mo->health = info->spawnHealth;
        break;

    default: break;
    }

    mo->moveDir      = Reader_ReadInt32(svReader);
    mo->moveCount    = Reader_ReadInt32(svReader);
    Reader_ReadInt32(svReader); // target
    mo->reactionTime = Reader_ReadInt32(svReader);
    mo->threshold    = Reader_ReadInt32(svReader);
    mo->player       = INT2PTR(player_t, Reader_ReadInt32(svReader));
    mo->lastLook     = Reader_ReadInt32(svReader);

    mo->spawnSpot.origin[VX] = (coord_t) Reader_ReadInt32(svReader);
    mo->spawnSpot.origin[VY] = (coord_t) Reader_ReadInt32(svReader);
    mo->spawnSpot.origin[VZ] = 0; // Initialize with "something".
    mo->spawnSpot.angle = (angle_t) (ANG45 * (Reader_ReadInt32(svReader) / 45));
    /*mo->spawnSpot.type = (int)*/ Reader_ReadInt32(svReader);

    {
    int spawnFlags = ((int) Reader_ReadInt32(svReader)) & ~MASK_UNKNOWN_MSF_FLAGS;
    // Spawn on the floor by default unless the mobjtype flags override.
    spawnFlags |= MSF_Z_FLOOR;
    mo->spawnSpot.flags = spawnFlags;
    }

    mo->info = info;
    SV_TranslateLegacyMobjFlags(mo, 0);

    mo->state = &STATES[PTR2INT(mo->state)];
    mo->target = NULL;
    if(mo->player)
    {
        mo->player = &players[PTR2INT(mo->player) - 1];
        mo->player->plr->mo = mo;
        mo->player->plr->mo->dPlayer = mo->player->plr;
    }
    P_MobjSetOrigin(mo);
    mo->floorZ   = P_GetDoublep(mo->bspLeaf, DMU_FLOOR_HEIGHT);
    mo->ceilingZ = P_GetDoublep(mo->bspLeaf, DMU_CEILING_HEIGHT);
}
Beispiel #2
0
int mobj_s::read(MapStateReader *msr)
{
#define FF_FULLBRIGHT 0x8000 ///< Used to be a flag in thing->frame.
#define FF_FRAMEMASK  0x7fff

    Reader1 *reader = msr->reader();

    int ver = Reader_ReadByte(reader);

#if !__JHEXEN__
    if(ver >= 2) // Version 2 has mobj archive numbers.
    {
        msr->addMobjToThingArchive(this, Reader_ReadInt16(reader));
    }
#endif

#if !__JHEXEN__
    target = 0;
    if(ver >= 2)
    {
        target   = INT2PTR(mobj_t, Reader_ReadInt16(reader));
    }
#endif

#if __JDOOM__ || __JDOOM64__
    tracer = 0;
    if(ver >= 5)
    {
        tracer   = INT2PTR(mobj_t, Reader_ReadInt16(reader));
    }
#endif

    onMobj = 0;
#if __JHEXEN__
    if(ver >= 8)
#else
    if(ver >= 5)
#endif
    {
        onMobj   = INT2PTR(mobj_t, Reader_ReadInt16(reader));
    }

    origin[VX]   = FIX2FLT(Reader_ReadInt32(reader));
    origin[VY]   = FIX2FLT(Reader_ReadInt32(reader));
    origin[VZ]   = FIX2FLT(Reader_ReadInt32(reader));
    angle        = Reader_ReadInt32(reader);
    sprite       = Reader_ReadInt32(reader);

    frame        = Reader_ReadInt32(reader); // might be ORed with FF_FULLBRIGHT
    if(frame & FF_FULLBRIGHT)
        frame &= FF_FRAMEMASK; // not used anymore.

#if __JHEXEN__
    if(ver < 6)
    {
        /*floorflat =*/ Reader_ReadInt32(reader);
    }
#else
    floorZ       = FIX2FLT(Reader_ReadInt32(reader));
    ceilingZ     = FIX2FLT(Reader_ReadInt32(reader));
#endif

    radius       = FIX2FLT(Reader_ReadInt32(reader));
    height       = FIX2FLT(Reader_ReadInt32(reader));
    mom[MX]      = FIX2FLT(Reader_ReadInt32(reader));
    mom[MY]      = FIX2FLT(Reader_ReadInt32(reader));
    mom[MZ]      = FIX2FLT(Reader_ReadInt32(reader));
    valid        = Reader_ReadInt32(reader);
    type         = Reader_ReadInt32(reader);

#if __JHEXEN__
    if(ver < 7)
    {
        /*info   = (mobjinfo_t *)*/ Reader_ReadInt32(reader);
    }
#endif
    info = &MOBJINFO[type];

    if(info->flags2 & MF2_FLOATBOB)
        mom[MZ] = 0;

    if(info->flags & MF_SOLID)
        ddFlags |= DDMF_SOLID;
    if(info->flags2 & MF2_DONTDRAW)
        ddFlags |= DDMF_DONTDRAW;

    tics         = Reader_ReadInt32(reader);
    state        = INT2PTR(state_t, Reader_ReadInt32(reader));
#if __JHEXEN__
    damage       = Reader_ReadInt32(reader);
#endif
    flags        = Reader_ReadInt32(reader);
#if __JHEXEN__
    flags2       = Reader_ReadInt32(reader);
    if(ver >= 5)
    {
        flags3   = Reader_ReadInt32(reader);
    }
    special1     = Reader_ReadInt32(reader);
    special2     = Reader_ReadInt32(reader);
#endif
    health       = Reader_ReadInt32(reader);

#if __JHERETIC__
    if(ver < 8)
    {
        // Fix a bunch of kludges in the original Heretic.
        switch(type)
        {
        case MT_MACEFX1:
        case MT_MACEFX2:
        case MT_MACEFX3:
        case MT_HORNRODFX2:
        case MT_HEADFX3:
        case MT_WHIRLWIND:
        case MT_TELEGLITTER:
        case MT_TELEGLITTER2:
            special3 = health;
            if(type == MT_HORNRODFX2 && special3 > 16)
                special3 = 16;
            health = MOBJINFO[type].spawnHealth;
            break;

        default:
            break;
        }
    }
#endif

    moveDir      = Reader_ReadInt32(reader);
    moveCount    = Reader_ReadInt32(reader);
#if __JHEXEN__
    target       = INT2PTR(mobj_t, Reader_ReadInt32(reader));
#endif
    reactionTime = Reader_ReadInt32(reader);
    threshold    = Reader_ReadInt32(reader);
    player       = INT2PTR(player_t, Reader_ReadInt32(reader));
    lastLook     = Reader_ReadInt32(reader);

#if __JHEXEN__
    floorClip    = FIX2FLT(Reader_ReadInt32(reader));
    msr->addMobjToThingArchive(this, Reader_ReadInt32(reader));
    tid          = Reader_ReadInt32(reader);
#else
    // For nightmare respawn.
    if(ver >= 6)
    {
        spawnSpot.origin[VX] = FIX2FLT(Reader_ReadInt32(reader));
        spawnSpot.origin[VY] = FIX2FLT(Reader_ReadInt32(reader));
        spawnSpot.origin[VZ] = FIX2FLT(Reader_ReadInt32(reader));
        spawnSpot.angle      = Reader_ReadInt32(reader);
        if(ver < 10)
        {
            /*spawnSpot.type =*/ Reader_ReadInt32(reader);
        }
        spawnSpot.flags      = Reader_ReadInt32(reader);
    }
    else
    {
        spawnSpot.origin[VX] = (float) Reader_ReadInt16(reader);
        spawnSpot.origin[VY] = (float) Reader_ReadInt16(reader);
        spawnSpot.origin[VZ] = 0; // Initialize with "something".
        spawnSpot.angle      = (angle_t) (ANG45 * (Reader_ReadInt16(reader) / 45));
        /*spawnSpot.type       = (int)*/ Reader_ReadInt16(reader);
        spawnSpot.flags      = (int) Reader_ReadInt16(reader);
    }

# if __JDOOM__ || __JDOOM64__
    if(ver >= 3)
# elif __JHERETIC__
    if(ver >= 5)
# endif
    {
        intFlags = Reader_ReadInt32(reader);
        dropOffZ = FIX2FLT(Reader_ReadInt32(reader));
        gear     = Reader_ReadInt32(reader);
    }

# if __JDOOM__ || __JDOOM64__
    if(ver >= 6)
    {
        damage = Reader_ReadInt32(reader);
        flags2 = Reader_ReadInt32(reader);
    }
    else // flags2 will be applied from the defs.
    {
        damage = DDMAXINT; // Use the value set in mo->info->damage
    }

# elif __JHERETIC__
    damage = Reader_ReadInt32(reader);
    flags2 = Reader_ReadInt32(reader);
# endif

    if(ver >= 7)
    {
        flags3 = Reader_ReadInt32(reader);
    } // Else flags3 will be applied from the defs.
#endif

#if __JHEXEN__
    special = Reader_ReadInt32(reader);
    Reader_Read(reader, args, 1 * 5);
#elif __JHERETIC__
    special1 = Reader_ReadInt32(reader);
    special2 = Reader_ReadInt32(reader);
    if(ver >= 8)
    {
        special3 = Reader_ReadInt32(reader);
    }
#endif

#if __JHEXEN__
    if(ver >= 2)
#else
    if(ver >= 4)
#endif
    {
        translucency = Reader_ReadByte(reader);
    }

#if __JHEXEN__
    if(ver >= 3)
#else
    if(ver >= 5)
#endif
    {
        visTarget = (short) (Reader_ReadByte(reader)) -1;
    }

#if __JHEXEN__
    if(ver >= 4)
    {
        tracer    = INT2PTR(mobj_t, Reader_ReadInt32(reader));
    }

    if(ver >= 4)
    {
        lastEnemy = INT2PTR(mobj_t, Reader_ReadInt32(reader));
    }
#else
    if(ver >= 5)
    {
        floorClip = FIX2FLT(Reader_ReadInt32(reader));
    }
#endif

#if __JHERETIC__
    if(ver >= 7)
    {
        generator = INT2PTR(mobj_t, Reader_ReadInt16(reader));
    }
    else
    {
        generator = 0;
    }
#endif

    /*
     * Restore! (unmangle)
     */
    info = &MOBJINFO[type];

    Mobj_SetState(this, PTR2INT(state));
#if __JHEXEN__
    if(flags2 & MF2_DORMANT)
    {
        tics = -1;
    }
#endif

    if(player)
    {
        // The player number translation table is used to find out the
        // *current* (actual) player number of the referenced player.
        player = msr->player(PTR2INT(player));
#if __JHEXEN__
        if(!player)
        {
            // This saved player does not exist in the current game!
            // Destroy this mobj.
            Mobj_Destroy(this);
            return false;
        }
#endif
        dPlayer = player->plr;

        dPlayer->mo      = this;
        //dPlayer->clAngle = angle; /* $unifiedangles */
        dPlayer->lookDir = 0; /* $unifiedangles */
    }

    visAngle = angle >> 16;

#if !__JHEXEN__
    if(dPlayer && !dPlayer->inGame)
    {
        dPlayer->mo = 0;
        Mobj_Destroy(this);
        return false;
    }
#endif

#if !__JDOOM64__
    // Do we need to update this mobj's flag values?
    if(ver < MOBJ_SAVEVERSION)
    {
        SV_TranslateLegacyMobjFlags(this, ver);
    }
#endif

    P_MobjLink(this);
    floorZ   = P_GetDoublep(Mobj_Sector(this), DMU_FLOOR_HEIGHT);
    ceilingZ = P_GetDoublep(Mobj_Sector(this), DMU_CEILING_HEIGHT);

    return false;

#undef FF_FRAMEMASK
#undef FF_FULLBRIGHT
}