Example #1
0
/**
 * Called when a moving plat needs to be removed.
 *
 * @param plat  Ptr to the plat to remove.
 */
static void stopPlat(plat_t *plat)
{
    DENG2_ASSERT(plat);
    P_ToXSector(plat->sector)->specialData = nullptr;
    P_NotifySectorFinished(P_ToXSector(plat->sector)->tag);
    Thinker_Remove(&plat->thinker);
}
Example #2
0
    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
    }
Example #3
0
/**
 * Called when a moving plat needs to be removed.
 *
 * @param plat          Ptr to the plat to remove.
 */
static void stopPlat(plat_t* plat)
{
    P_ToXSector(plat->sector)->specialData = NULL;
#if __JHEXEN__
    P_TagFinished(P_ToXSector(plat->sector)->tag);
#endif
    Thinker_Remove(&plat->thinker);
}
Example #4
0
void P_CopySector(Sector *dest, Sector *src)
{
    xsector_t *xsrc = P_ToXSector(src);
    xsector_t *xdest = P_ToXSector(dest);

    if(src == dest)
        return; // no point copying self.

    // Copy the built-in properties.
    float ftemp[4];
    coord_t dtemp[2];

    P_SetFloatp  (dest, DMU_LIGHT_LEVEL,                P_GetFloatp(src, DMU_LIGHT_LEVEL));
    P_GetFloatpv (src,  DMU_COLOR,                      ftemp);
    P_SetFloatpv (dest, DMU_COLOR,                      ftemp);

    P_SetDoublep (dest, DMU_FLOOR_HEIGHT,               P_GetDoublep(src, DMU_FLOOR_HEIGHT));
    P_SetPtrp    (dest, DMU_FLOOR_MATERIAL,             P_GetPtrp(src, DMU_FLOOR_MATERIAL));
    P_GetFloatpv (src,  DMU_FLOOR_COLOR,                ftemp);
    P_SetFloatpv (dest, DMU_FLOOR_COLOR,                ftemp);
    P_GetDoublepv(src,  DMU_FLOOR_MATERIAL_OFFSET_XY,   dtemp);
    P_SetDoublepv(dest, DMU_FLOOR_MATERIAL_OFFSET_XY,   dtemp);
    P_SetIntp    (dest, DMU_FLOOR_SPEED,                P_GetIntp(src, DMU_FLOOR_SPEED));
    P_SetDoublep (dest, DMU_FLOOR_TARGET_HEIGHT,        P_GetFloatp(src, DMU_FLOOR_TARGET_HEIGHT));

    P_SetDoublep (dest, DMU_CEILING_HEIGHT,             P_GetDoublep(src, DMU_CEILING_HEIGHT));
    P_SetPtrp    (dest, DMU_CEILING_MATERIAL,           P_GetPtrp(src, DMU_CEILING_MATERIAL));
    P_GetFloatpv (src,  DMU_CEILING_COLOR,              ftemp);
    P_SetFloatpv (dest, DMU_CEILING_COLOR,              ftemp);
    P_GetDoublepv(src,  DMU_CEILING_MATERIAL_OFFSET_XY, dtemp);
    P_SetDoublepv(dest, DMU_CEILING_MATERIAL_OFFSET_XY, dtemp);
    P_SetIntp    (dest, DMU_CEILING_SPEED,              P_GetIntp(src, DMU_CEILING_SPEED));
    P_SetDoublep (dest, DMU_CEILING_TARGET_HEIGHT,      P_GetFloatp(src, DMU_CEILING_TARGET_HEIGHT));

    // Copy the extended properties too
#if __JDOOM__ || __JHERETIC__ || __JDOOM64__
    xdest->special = xsrc->special;
    xdest->soundTraversed = xsrc->soundTraversed;
    xdest->soundTarget = xsrc->soundTarget;
#if __JHERETIC__
    xdest->seqType = xsrc->seqType;
#endif
    xdest->SP_floororigheight = xsrc->SP_floororigheight;
    xdest->SP_ceilorigheight = xsrc->SP_ceilorigheight;
    xdest->origLight = xsrc->origLight;
    std::memcpy(xdest->origRGB, xsrc->origRGB, sizeof(float) * 3);
    if(xsrc->xg && xdest->xg)
        std::memcpy(xdest->xg, xsrc->xg, sizeof(*xdest->xg));
    else
        xdest->xg = 0;
#else
    xdest->special = xsrc->special;
    xdest->soundTraversed = xsrc->soundTraversed;
    xdest->soundTarget = xsrc->soundTarget;
    xdest->seqType = xsrc->seqType;
#endif
}
Example #5
0
/**
 * After the map has been loaded, scan each sector for specials that spawn
 * thinkers.
 */
void P_SpawnStrobeFlash(sector_t *sector, int fastOrSlow, int inSync)
{
    strobe_t   *flash;
    float       lightlevel = P_GetFloatp(sector, DMU_LIGHT_LEVEL);

    flash = Z_Malloc(sizeof(*flash), PU_MAPSPEC, 0);

    P_ThinkerAdd(&flash->thinker);

    flash->sector = sector;
    flash->darkTime = fastOrSlow;
    flash->brightTime = STROBEBRIGHT;
    flash->thinker.function = T_StrobeFlash;
    flash->maxLight = lightlevel;
    flash->minLight = P_FindMinSurroundingLight(sector, lightlevel);

    if(flash->minLight == flash->maxLight)
        flash->minLight = 0;

    // nothing special about it during gameplay
    P_ToXSector(sector)->special = 0;

    if(!inSync)
        flash->count = (P_Random() & 7) + 1;
    else
        flash->count = 1;
}
Example #6
0
coord_t Mobj_Friction(mobj_t const *mo)
{
    if(Mobj_IsAirborne(mo))
    {
        // Airborne "friction".
        return FRICTION_FLY;
    }

#if __JHERETIC__
    if(P_ToXSector(Mobj_Sector(mo))->special == 15) // Low friction.
    {
        return FRICTION_LOW;
    }
#endif

#if __JHEXEN__
    terraintype_t const *tt = P_MobjFloorTerrain(mo);
    if(tt->flags & TTF_FRICTION_LOW)
    {
        return FRICTION_LOW;
    }
#endif

#if LIBCOMMON_HAVE_XG
    // Use the current sector's friction.
    return XS_Friction(Mobj_Sector(mo));
#else
    return FRICTION_NORMAL;
#endif
}
Example #7
0
/**
 * After the map has been loaded, scan each sector for specials that spawn
 * thinkers.
 */
void P_SpawnStrobeFlash(Sector *sector, int fastOrSlow, int inSync)
{
    float lightLevel = P_GetFloatp(sector, DMU_LIGHT_LEVEL);
    float otherLevel = DDMAXFLOAT;

    strobe_t *flash = (strobe_t *)Z_Calloc(sizeof(*flash), PU_MAP, 0);
    flash->thinker.function = (thinkfunc_t) T_StrobeFlash;
    Thinker_Add(&flash->thinker);

    flash->sector = sector;
    flash->darkTime = fastOrSlow;
    flash->brightTime = STROBEBRIGHT;
    flash->maxLight = lightLevel;
    P_FindSectorSurroundingLowestLight(sector, &otherLevel);
    if(otherLevel < lightLevel)
        flash->minLight = otherLevel;
    else
        flash->minLight = lightLevel;

    if(flash->minLight == flash->maxLight)
        flash->minLight = 0;

    // Note that we are resetting sector attributes.
    // Nothing special about it during gameplay.
    P_ToXSector(sector)->special = 0;

    if(!inSync)
    {
        flash->count = (P_Random() & 7) + 1;
    }
    else
    {
        flash->count = 1;
    }
}
Example #8
0
/**
 * After the map has been loaded, scan each sector
 * for specials that spawn thinkers
 */
void P_SpawnLightFlash(Sector *sector)
{
    float lightLevel = P_GetFloatp(sector, DMU_LIGHT_LEVEL);
    float otherLevel = DDMAXFLOAT;

    // Note that we are resetting sector attributes.
    // Nothing special about it during gameplay.
    P_ToXSector(sector)->special = 0;

    lightflash_t *flash = (lightflash_t *)Z_Calloc(sizeof(*flash), PU_MAP, 0);
    flash->thinker.function = (thinkfunc_t) T_LightFlash;
    Thinker_Add(&flash->thinker);

    flash->sector = sector;
    flash->maxLight = lightLevel;

    P_FindSectorSurroundingLowestLight(sector, &otherLevel);
    if(otherLevel < lightLevel)
        flash->minLight = otherLevel;
    else
        flash->minLight = lightLevel;
    flash->maxTime = 64;
    flash->minTime = 7;
    flash->count = (P_Random() & flash->maxTime) + 1;
}
Example #9
0
coord_t Mobj_ThrustMul(mobj_t const *mo)
{
    coord_t mul = 1.0;

#if __JHEXEN__
    if(P_MobjFloorTerrain(mo)->flags & TTF_FRICTION_LOW)
    {
        mul /= 2;
    }
#else // !__JHEXEN__
    Sector *sec = Mobj_Sector(mo);

#if __JHERETIC__
    if(P_ToXSector(sec)->special == 15) // Friction_Low
    {
        mul /= 4;
        return mul; // XG friction ignored.
    }
#endif

    // Use a thrust multiplier based on the sector's friction.
    mul = Mobj_ThrustMulForFriction(XS_Friction(sec));

#endif

    return mul;
}
Example #10
0
void T_BuildPillar(pillar_t *pillar)
{
    DENG2_ASSERT(pillar);

    // First, raise the floor
    result_e res1 = T_MovePlane(pillar->sector, pillar->floorSpeed, pillar->floorDest, pillar->crush, 0, pillar->direction); // floorOrCeiling, direction
    // Then, lower the ceiling
    result_e res2 = T_MovePlane(pillar->sector, pillar->ceilingSpeed, pillar->ceilingDest, pillar->crush, 1, -pillar->direction);
    if(res1 == pastdest && res2 == pastdest)
    {
        P_ToXSector(pillar->sector)->specialData = 0;
        SN_StopSequenceInSec(pillar->sector);
        P_NotifySectorFinished(P_ToXSector(pillar->sector)->tag);
        Thinker_Remove(&pillar->thinker);
    }
}
Example #11
0
/**
 * Called every tic frame that the player origin is in a special sector
 */
void P_PlayerInSpecialSector(player_t *player)
{
    Sector *sector = Mobj_Sector(player->plr->mo);

    if(IS_CLIENT) return;

    // Falling, not all the way down yet?
    if(!FEQUAL(player->plr->mo->origin[VZ], P_GetDoublep(sector, DMU_FLOOR_HEIGHT))) return;

    // Has hitten ground.
    switch(P_ToXSector(sector)->special)
    {
    default:
        break;

    case 5: ///< HELLSLIME DAMAGE
        if(!player->powers[PT_IRONFEET])
            if(!(mapTime & 0x1f))
                P_DamageMobj(player->plr->mo, NULL, NULL, 10, false);
        break;

    case 7: ///< NUKAGE DAMAGE
        if(!player->powers[PT_IRONFEET])
            if(!(mapTime & 0x1f))
                P_DamageMobj(player->plr->mo, NULL, NULL, 5, false);
        break;

    case 16: ///< SUPER HELLSLIME DAMAGE
    case 4:  ///< STROBE HURT
        if(!player->powers[PT_IRONFEET] || (P_Random() < 5))
        {
            if(!(mapTime & 0x1f))
                P_DamageMobj(player->plr->mo, NULL, NULL, 20, false);
        }
        break;

    case 9: ///< SECRET SECTOR
        player->secretCount++;
        P_ToXSector(sector)->special = 0;
        if(cfg.secretMsg)
        {
            P_SetMessage(player, "You've found a secret area!");
            // S_ConsoleSound(SFX_SECRET, 0, player - players); // jd64
        }
        break;
    }
}
Example #12
0
void T_FloorWaggle(waggle_t *waggle)
{
    DENG_ASSERT(waggle != 0);

    switch(waggle->state)
    {
    default:
    case WS_STABLE:
        if(waggle->ticker != -1)
        {
            if(!--waggle->ticker)
            {
                waggle->state = WS_REDUCE;
            }
        }
        break;

    case WS_EXPAND:
        if((waggle->scale += waggle->scaleDelta) >= waggle->targetScale)
        {
            waggle->scale = waggle->targetScale;
            waggle->state = WS_STABLE;
        }
        break;

    case WS_REDUCE:
        if((waggle->scale -= waggle->scaleDelta) <= 0)
        {
            // Remove.
            P_SetDoublep(waggle->sector, DMU_FLOOR_HEIGHT, waggle->originalHeight);
            P_ChangeSector(waggle->sector, 1 /*crush damage*/);
            P_ToXSector(waggle->sector)->specialData = nullptr;
            P_NotifySectorFinished(P_ToXSector(waggle->sector)->tag);
            Thinker_Remove(&waggle->thinker);
            return;
        }
        break;
    }

    waggle->accumulator += waggle->accDelta;
    coord_t fh = waggle->originalHeight +
        FLOATBOBOFFSET(((int) waggle->accumulator) & 63) * waggle->scale;
    P_SetDoublep(waggle->sector, DMU_FLOOR_HEIGHT, fh);
    P_SetDoublep(waggle->sector, DMU_FLOOR_TARGET_HEIGHT, fh);
    P_SetFloatp(waggle->sector, DMU_FLOOR_SPEED, 0);
    P_ChangeSector(waggle->sector, 1 /*crush damage*/);
}
Example #13
0
dd_bool EV_StartFloorWaggle(int tag, int height, int speed, int offset, int timer)
{
    iterlist_t *list = P_GetSectorIterListForTag(tag, false);
    if(!list) return false;

    dd_bool retCode = false;

    IterList_SetIteratorDirection(list, ITERLIST_FORWARD);
    IterList_RewindIterator(list);

    Sector *sec;
    while((sec = (Sector *)IterList_MoveIterator(list)))
    {
        if(P_ToXSector(sec)->specialData)
            continue; // Already moving, so keep going...

        retCode = true;

        waggle_t *waggle = (waggle_t *)Z_Calloc(sizeof(*waggle), PU_MAP, 0);
        waggle->thinker.function = (thinkfunc_t) T_FloorWaggle;
        Thinker_Add(&waggle->thinker);

        P_ToXSector(sec)->specialData = waggle;
        waggle->sector         = sec;
        waggle->originalHeight = P_GetDoublep(sec, DMU_FLOOR_HEIGHT);
        waggle->accumulator    = offset;
        waggle->accDelta       = FIX2FLT(speed << 10);
        waggle->scale          = 0;
        waggle->targetScale    = FIX2FLT(height << 10);
        waggle->scaleDelta     =
            FIX2FLT(FLT2FIX(waggle->targetScale) /
                    (TICSPERSEC + ((3 * TICSPERSEC) * height) / 255));
        waggle->ticker         = timer ? timer * 35 : -1;
        waggle->state          = WS_EXPAND;
    }

    return retCode;
}
Example #14
0
int waggle_s::read(MapStateReader *msr)
{
    Reader1 *reader = msr->reader();
    int mapVersion = msr->mapVersion();

    if(mapVersion >= 4)
    {
        /*int ver =*/ Reader_ReadByte(reader); // version byte.

        // Start of used data members.
        sector          = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader));
        DENG_ASSERT(sector != 0);

        originalHeight  = FIX2FLT((fixed_t) Reader_ReadInt32(reader));
        accumulator     = FIX2FLT((fixed_t) Reader_ReadInt32(reader));
        accDelta        = FIX2FLT((fixed_t) Reader_ReadInt32(reader));
        targetScale     = FIX2FLT((fixed_t) Reader_ReadInt32(reader));
        scale           = FIX2FLT((fixed_t) Reader_ReadInt32(reader));
        scaleDelta      = FIX2FLT((fixed_t) Reader_ReadInt32(reader));
        ticker          = Reader_ReadInt32(reader);
        state           = wagglestate_e(Reader_ReadInt32(reader));
    }
    else
    {
        // Its in the old pre V4 format which serialized waggle_t
        // Padding at the start (an old thinker_t struct)
        byte junk[16]; // sizeof thinker_t
        Reader_Read(reader, junk, 16);

        // Start of used data members.
        // A 32bit pointer to sector, serialized.
        sector          = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader));
        DENG_ASSERT(sector != 0);

        originalHeight  = FIX2FLT((fixed_t) Reader_ReadInt32(reader));
        accumulator     = FIX2FLT((fixed_t) Reader_ReadInt32(reader));
        accDelta        = FIX2FLT((fixed_t) Reader_ReadInt32(reader));
        targetScale     = FIX2FLT((fixed_t) Reader_ReadInt32(reader));
        scale           = FIX2FLT((fixed_t) Reader_ReadInt32(reader));
        scaleDelta      = FIX2FLT((fixed_t) Reader_ReadInt32(reader));
        ticker          = Reader_ReadInt32(reader);
        state           = wagglestate_e(Reader_ReadInt32(reader));
    }

    thinker.function = (thinkfunc_t) T_FloorWaggle;

    P_ToXSector(sector)->specialData = this;

    return true; // Add this thinker.
}
Example #15
0
void P_SpawnLightSequence(Sector* sector, int indexStep)
{
    int                 count;

    {
    findlightsequencesectorparams_t params;

    params.seqSpecial = LIGHT_SEQUENCE; // Look for Light_Sequence, first.
    params.count = 1;
    params.sec = sector;
    do
    {
        // Make sure that the search doesn't back up.
        P_ToXSector(params.sec)->special = LIGHT_SEQUENCE_START;

        params.nextSec = NULL;
        P_Iteratep(params.sec, DMU_LINE, &params,
                   findLightSequenceSector);
        params.sec = params.nextSec;
    } while(params.sec);

    count = params.count;
    }

    {
    findlightsequencestartsectorparams_t params;
    float               base;
    fixed_t             index, indexDelta;

    params.sec = sector;
    count *= indexStep;
    index = 0;
    indexDelta = FixedDiv(64 * FRACUNIT, count * FRACUNIT);
    base = P_SectorLight(sector);
    do
    {
        if(P_SectorLight(params.sec))
        {
            base = P_SectorLight(params.sec);
        }
        P_SpawnPhasedLight(params.sec, base, index >> FRACBITS);
        index += indexDelta;

        params.nextSec = NULL;
        P_Iteratep(params.sec, DMU_LINE, &params,
                   findLightSequenceStartSector);
        params.sec = params.nextSec;
    } while(params.sec);
    }
}
Example #16
0
static int findLightSequenceStartSector(void *p, void *context)
{
    Line *li = (Line *) p;
    findlightsequencestartsectorparams_t *params = (findlightsequencestartsectorparams_t *) context;

    if(Sector *sector = P_GetNextSector(li, params->sec))
    {
        if(P_ToXSector(sector)->special == LIGHT_SEQUENCE_START)
        {
            params->nextSec = sector;
        }
    }

    return false; // Continue iteration.
}
Example #17
0
void P_BuildSectorTagLists()
{
    P_DestroySectorTagLists();

    for(int i = 0; i < numsectors; ++i)
    {
        Sector *sec = (Sector *)P_ToPtr(DMU_SECTOR, i);
        xsector_t *xsec = P_ToXSector(sec);

        if(xsec->tag)
        {
            iterlist_t *list = P_GetSectorIterListForTag(xsec->tag, true);
            IterList_PushBack(list, sec);
        }
    }
}
Example #18
0
int pillar_s::read(MapStateReader *msr)
{
    Reader1 *reader = msr->reader();
    int mapVersion = msr->mapVersion();

    if(mapVersion >= 4)
    {
        // Note: the thinker class byte has already been read.
        /*int ver =*/ Reader_ReadByte(reader); // version byte.

        // Start of used data members.
        sector          = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader));
        DENG_ASSERT(sector != 0);

        ceilingSpeed    = FIX2FLT((fixed_t) Reader_ReadInt32(reader));
        floorSpeed      = FIX2FLT((fixed_t) Reader_ReadInt32(reader));
        floorDest       = FIX2FLT((fixed_t) Reader_ReadInt32(reader));
        ceilingDest     = FIX2FLT((fixed_t) Reader_ReadInt32(reader));
        direction       = Reader_ReadInt32(reader);
        crush           = Reader_ReadInt32(reader);
    }
    else
    {
        // Its in the old pre V4 format which serialized pillar_t
        // Padding at the start (an old thinker_t struct)
        byte junk[16]; // sizeof thinker_t
        Reader_Read(reader, junk, 16);

        // Start of used data members.
        // A 32bit pointer to sector, serialized.
        sector          = (Sector *)P_ToPtr(DMU_SECTOR, (int) Reader_ReadInt32(reader));
        DENG_ASSERT(sector != 0);

        ceilingSpeed    = FIX2FLT((fixed_t) Reader_ReadInt32(reader));
        floorSpeed      = FIX2FLT((fixed_t) Reader_ReadInt32(reader));
        floorDest       = FIX2FLT((fixed_t) Reader_ReadInt32(reader));
        ceilingDest     = FIX2FLT((fixed_t) Reader_ReadInt32(reader));
        direction       = Reader_ReadInt32(reader);
        crush           = Reader_ReadInt32(reader);
    }

    thinker.function = (thinkfunc_t) T_BuildPillar;

    P_ToXSector(sector)->specialData = this;

    return true; // Add this thinker.
}
Example #19
0
static int SV_ReadPlat(plat_t *plat)
{
/* Original Heretic format:
typedef struct {
    thinker_t   thinker;        // was 12 bytes
    Sector     *sector;
    fixed_t     speed;
    fixed_t     low;
    fixed_t     high;
    int         wait;
    int         count;
    platstate_e     status;         // was 32bit int
    platstate_e     oldStatus;      // was 32bit int
    boolean     crush;
    int         tag;
    plattype_e  type;           // was 32bit int
} v13_plat_t;
*/
    byte temp[SIZEOF_V13_THINKER_T];
    // Padding at the start (an old thinker_t struct)
    Reader_Read(svReader, &temp, SIZEOF_V13_THINKER_T);

    // Start of used data members.
    // A 32bit pointer to sector, serialized.
    plat->sector = P_ToPtr(DMU_SECTOR, Reader_ReadInt32(svReader));
    if(!plat->sector)
        Con_Error("tc_plat: bad sector number\n");

    plat->speed = FIX2FLT(Reader_ReadInt32(svReader));
    plat->low = FIX2FLT(Reader_ReadInt32(svReader));
    plat->high = FIX2FLT(Reader_ReadInt32(svReader));
    plat->wait = Reader_ReadInt32(svReader);
    plat->count = Reader_ReadInt32(svReader);
    plat->state = Reader_ReadInt32(svReader);
    plat->oldState = Reader_ReadInt32(svReader);
    plat->crush = Reader_ReadInt32(svReader);
    plat->tag = Reader_ReadInt32(svReader);
    plat->type = Reader_ReadInt32(svReader);

    plat->thinker.function = T_PlatRaise;
    if(!(temp + V13_THINKER_T_FUNC_OFFSET))
        Thinker_SetStasis(&plat->thinker, true);

    P_ToXSector(plat->sector)->specialData = T_PlatRaise;
    return true; // Add this thinker.
}
Example #20
0
/**
 * Start strobing lights (usually from a trigger)
 */
void EV_StartLightStrobing(Line *line)
{
    iterlist_t *list = P_GetSectorIterListForTag(P_ToXLine(line)->tag, false);
    if(!list) return;

    IterList_SetIteratorDirection(list, ITERLIST_FORWARD);
    IterList_RewindIterator(list);

    Sector *sec;
    while((sec = (Sector *)IterList_MoveIterator(list)))
    {
        if(P_ToXSector(sec)->specialData)
            continue;

        P_SpawnStrobeFlash(sec, SLOWDARK, 0);
    }
}
Example #21
0
void P_SpawnGlowingLight(sector_t *sector)
{
    float       lightlevel = P_GetFloatp(sector, DMU_LIGHT_LEVEL);
    glow_t     *g;

    g = Z_Malloc(sizeof(*g), PU_MAPSPEC, 0);

    P_ThinkerAdd(&g->thinker);

    g->sector = sector;
    g->minLight = P_FindMinSurroundingLight(sector, lightlevel);
    g->maxLight = lightlevel;
    g->thinker.function = T_Glow;
    g->direction = -1;

    P_ToXSector(sector)->special = 0;
}
Example #22
0
/**
 * Start strobing lights (usually from a trigger).
 */
void EV_StartLightStrobing(linedef_t *line)
{
    sector_t   *sec = NULL;
    iterlist_t *list;

    list = P_GetSectorIterListForTag(P_ToXLine(line)->tag, false);
    if(!list)
        return;

    P_IterListResetIterator(list, true);
    while((sec = P_IterListIterator(list)) != NULL)
    {
        if(P_ToXSector(sec)->specialData)
            continue;

        P_SpawnStrobeFlash(sec, SLOWDARK, 0);
    }
}
Example #23
0
void P_RecursiveSound(struct mobj_s* soundTarget, Sector* sec, int soundBlocks)
{
    spreadsoundtoneighborsparams_t params;
    xsector_t* xsec = P_ToXSector(sec);

    // Wake up all monsters in this sector.
    if(P_GetIntp(sec, DMU_VALID_COUNT) == VALIDCOUNT && xsec->soundTraversed <= soundBlocks + 1)
        return; // Already flooded.

    P_SetIntp(sec, DMU_VALID_COUNT, VALIDCOUNT);
    xsec->soundTraversed = soundBlocks + 1;
    xsec->soundTarget = soundTarget;

    params.baseSec = sec;
    params.soundBlocks = soundBlocks;
    params.soundTarget = soundTarget;
    P_Iteratep(sec, DMU_LINE, &params, spreadSoundToNeighbors);
}
Example #24
0
static int SV_ReadFloor(floor_t *floor)
{
/* Original Heretic format:
typedef struct {
    thinker_t   thinker;        // was 12 bytes
    floortype_e type;           // was 32bit int
    boolean     crush;
    Sector     *sector;
    int         direction;
    int         newspecial;
    short       texture;
    fixed_t     floordestheight;
    fixed_t     speed;
} v13_floormove_t;
*/
    Uri *newTextureUrn;

    // Padding at the start (an old thinker_t struct)
    Reader_Read(svReader, NULL, SIZEOF_V13_THINKER_T);

    // Start of used data members.
    floor->type = Reader_ReadInt32(svReader);
    floor->crush = Reader_ReadInt32(svReader);

    // A 32bit pointer to sector, serialized.
    floor->sector = P_ToPtr(DMU_SECTOR, Reader_ReadInt32(svReader));
    if(!floor->sector)
        Con_Error("tc_floor: bad sector number\n");

    floor->state = (int) Reader_ReadInt32(svReader);
    floor->newSpecial = Reader_ReadInt32(svReader);

    newTextureUrn = readTextureUrn(svReader, "Flats");
    floor->material = DD_MaterialForTextureUri(newTextureUrn);
    Uri_Delete(newTextureUrn);

    floor->floorDestHeight = FIX2FLT(Reader_ReadInt32(svReader));
    floor->speed = FIX2FLT(Reader_ReadInt32(svReader));

    floor->thinker.function = T_MoveFloor;

    P_ToXSector(floor->sector)->specialData = T_MoveFloor;
    return true; // Add this thinker.
}
Example #25
0
static int SV_ReadCeiling(ceiling_t *ceiling)
{
/* Original Heretic format:
typedef struct {
    thinker_t thinker; ///< 12 bytes
    ceilingtype_e type; ///< 32bit int
    Sector* sector;
    fixed_t bottomheight, topheight;
    fixed_t speed;
    boolean crush;
    int direction; /// 1= up, 0= waiting, -1= down
    int tag'
    int olddirection;
} v13_ceiling_t;
*/
    byte temp[SIZEOF_V13_THINKER_T];

    // Padding at the start (an old thinker_t struct)
    Reader_Read(svReader, &temp, SIZEOF_V13_THINKER_T);

    // Start of used data members.
    ceiling->type = Reader_ReadInt32(svReader);

    // A 32bit pointer to sector, serialized.
    ceiling->sector = P_ToPtr(DMU_SECTOR, Reader_ReadInt32(svReader));
    if(!ceiling->sector)
        Con_Error("tc_ceiling: bad sector number\n");

    ceiling->bottomHeight = FIX2FLT(Reader_ReadInt32(svReader));
    ceiling->topHeight    = FIX2FLT(Reader_ReadInt32(svReader));
    ceiling->speed        = FIX2FLT(Reader_ReadInt32(svReader));
    ceiling->crush        = Reader_ReadInt32(svReader);
    ceiling->state        = (Reader_ReadInt32(svReader) == -1? CS_DOWN : CS_UP);
    ceiling->tag          = Reader_ReadInt32(svReader);
    ceiling->oldState     = (Reader_ReadInt32(svReader) == -1? CS_DOWN : CS_UP);

    ceiling->thinker.function = T_MoveCeiling;
    if(!(temp + V13_THINKER_T_FUNC_OFFSET))
        Thinker_SetStasis(&ceiling->thinker, true);

    P_ToXSector(ceiling->sector)->specialData = T_MoveCeiling;
    return true; // Add this thinker.
}
Example #26
0
void P_SpawnFireFlicker(sector_t *sector)
{
    float       lightlevel = P_GetFloatp(sector, DMU_LIGHT_LEVEL);
    fireflicker_t *flick;

    // Note that we are resetting sector attributes.
    // Nothing special about it during gameplay.
    P_ToXSector(sector)->special = 0;

    flick = Z_Malloc(sizeof(*flick), PU_MAPSPEC, 0);

    P_ThinkerAdd(&flick->thinker);

    flick->thinker.function = T_FireFlicker;
    flick->sector = sector;
    flick->maxLight = lightlevel;
    flick->minLight =
        P_FindMinSurroundingLight(sector, lightlevel) + (16.0f/255.0f);
    flick->count = 4;
}
Example #27
0
/**
 * After the map has been loaded, scan each sector
 * for specials that spawn thinkers
 */
void P_SpawnLightFlash(sector_t *sector)
{
    float       lightlevel = P_GetFloatp(sector, DMU_LIGHT_LEVEL);
    lightflash_t *flash;

    // nothing special about it during gameplay
    P_ToXSector(sector)->special = 0;

    flash = Z_Malloc(sizeof(*flash), PU_MAPSPEC, 0);

    P_ThinkerAdd(&flash->thinker);

    flash->thinker.function = T_LightFlash;
    flash->sector = sector;
    flash->maxLight = lightlevel;

    flash->minLight = P_FindMinSurroundingLight(sector, lightlevel);
    flash->maxTime = 64;
    flash->minTime = 7;
    flash->count = (P_Random() & flash->maxTime) + 1;
}
Example #28
0
void P_SpawnGlowingLight(Sector *sector)
{
    float lightLevel = P_GetFloatp(sector, DMU_LIGHT_LEVEL);
    float otherLevel = DDMAXFLOAT;

    glow_t *g = (glow_t *)Z_Calloc(sizeof(*g), PU_MAP, 0);
    g->thinker.function = (thinkfunc_t) T_Glow;
    Thinker_Add(&g->thinker);

    g->sector = sector;
    P_FindSectorSurroundingLowestLight(sector, &otherLevel);
    if(otherLevel < lightLevel)
        g->minLight = otherLevel;
    else
        g->minLight = lightLevel;
    g->maxLight = lightLevel;
    g->direction = -1;

    // Note that we are resetting sector attributes.
    // Nothing special about it during gameplay.
    P_ToXSector(sector)->special = 0;
}
Example #29
0
static int findLightSequenceSector(void *p, void *context)
{
    Line *li = (Line *) p;
    findlightsequencesectorparams_t *params = (findlightsequencesectorparams_t *) context;
    Sector *tempSec = P_GetNextSector(li, params->sec);

    if(tempSec)
    {
        if(P_ToXSector(tempSec)->special == params->seqSpecial)
        {
            if(params->seqSpecial == LIGHT_SEQUENCE)
                params->seqSpecial = LIGHT_SEQUENCE_ALT;
            else
                params->seqSpecial = LIGHT_SEQUENCE;

            params->nextSec = tempSec;
            params->count++;
        }
    }

    return false; // Continue iteration.
}
Example #30
0
void P_SpawnPhasedLight(Sector *sector, float base, int index)
{
    phase_t *phase = (phase_t *)Z_Calloc(sizeof(*phase), PU_MAP, 0);
    phase->thinker.function = (thinkfunc_t) T_Phase;
    Thinker_Add(&phase->thinker);

    phase->sector = sector;
    if(index == -1)
    {
        // Sector->lightLevel as the index.
        phase->index = (int) (255.0f * P_SectorLight(sector)) & 63;
    }
    else
    {
        phase->index = index & 63;
    }

    phase->baseValue = base;
    P_SectorSetLight(phase->sector,
                     phase->baseValue + phaseTable[phase->index]);

    P_ToXSector(sector)->special = 0;
}