diff --git a/src/p_polyobj.c b/src/p_polyobj.c index fd3237c9d..d943a0bfe 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -2853,6 +2853,71 @@ INT32 EV_DoPolyObjFlag(line_t *pfdata) return 1; } +void T_PolyObjFade(polyfade_t *th) +{ + polyobj_t *po = Polyobj_GetForNum(th->polyObjNum); + size_t i; + + if (!po) +#ifdef RANGECHECK + I_Error("T_PolyObjFade: thinker has invalid id %d\n", th->polyObjNum); +#else + { + CONS_Debug(DBG_POLYOBJ, "T_PolyObjFade: thinker with invalid id %d removed.\n", th->polyObjNum); + P_RemoveThinkerDelayed(&th->thinker); + return; + } +#endif + + // check for displacement due to override and reattach when possible + if (po->thinker == NULL) + po->thinker = &th->thinker; + + // \todo logic +} + +INT32 EV_DoPolyObjFade(polyfadedata_t *pfdata) +{ + polyobj_t *po; + polyobj_t *oldpo; + polyfade_t *th; + INT32 start; + + if (!(po = Polyobj_GetForNum(prdata->polyObjNum))) + { + CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjRotate: bad polyobj %d\n", prdata->polyObjNum); + return 0; + } + + // don't allow line actions to affect bad polyobjects + if (po->isBad) + return 0; + + // create a new thinker + th = Z_Malloc(sizeof(polyfade_t), PU_LEVSPEC, NULL); + th->thinker.function.acp1 = (actionf_p1)T_PolyObjFade; + PolyObj_AddThinker(&th->thinker); + po->thinker = &th->thinker; + + // set fields + th->polyObjNum = pfdata->tag; + + // \todo polyfade fields + + oldpo = po; + + // apply action to mirroring polyobjects as well + start = 0; + while ((po = Polyobj_GetChild(oldpo, &start))) + { + pfdata->tag = po->id; + EV_DoPolyObjFade(pfdata); + } + + // action was successful + return 1; +} + #endif // ifdef POLYOBJECTS // EOF diff --git a/src/p_polyobj.h b/src/p_polyobj.h index c9838a922..0bd94a636 100644 --- a/src/p_polyobj.h +++ b/src/p_polyobj.h @@ -207,6 +207,15 @@ typedef struct polydisplace_s fixed_t oldHeights; } polydisplace_t; +typedef struct polyfade_s +{ + thinker_t thinker; // must be first + + INT32 polyObjNum; + + // \todo polyfade fields +} polyfade_t; + // // Line Activation Data Structures // @@ -266,6 +275,12 @@ typedef struct polydisplacedata_s fixed_t dy; } polydisplacedata_t; +typedef struct polyfadedata_s +{ + INT32 polyObjNum; + // \todo polyfadedata fields +} polyfadedata_t; + // // Functions // @@ -287,6 +302,7 @@ void T_PolyDoorSlide(polyslidedoor_t *); void T_PolyDoorSwing(polyswingdoor_t *); void T_PolyObjDisplace (polydisplace_t *); void T_PolyObjFlag (polymove_t *); +void T_PolyObjFade (polyfade_t *); INT32 EV_DoPolyDoor(polydoordata_t *); INT32 EV_DoPolyObjMove(polymovedata_t *); @@ -294,6 +310,7 @@ INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *); INT32 EV_DoPolyObjRotate(polyrotdata_t *); INT32 EV_DoPolyObjDisplace(polydisplacedata_t *); INT32 EV_DoPolyObjFlag(struct line_s *); +INT32 EV_DoPolyObjFade(polyfadedata_t *); // diff --git a/src/p_saveg.c b/src/p_saveg.c index 22d43f358..3cc061ebb 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1019,6 +1019,7 @@ typedef enum tc_polyswingdoor, tc_polyflag, tc_polydisplace, + tc_polyfade, #endif tc_end } specials_e; @@ -1918,6 +1919,11 @@ static void P_NetArchiveThinkers(void) SavePolydisplaceThinker(th, tc_polydisplace); continue; } + else if (th->function.acp1 == (actionf_p1)T_PolyObjFade) + { + SavePolyfadeThinker(th, tc_polyfade); + continue; + } #endif #ifdef PARANOIA else if (th->function.acv != P_RemoveThinkerDelayed) // wait garbage collection @@ -2689,6 +2695,20 @@ static inline void LoadPolydisplaceThinker(actionf_p1 thinker) ht->oldHeights = READFIXED(save_p); P_AddThinker(&ht->thinker); } + +// +// LoadPolyfadeThinker +// +// Loads a polyfadet_t thinker +// +static void LoadPolyfadeThinker(actionf_p1 thinker) +{ + polyfade_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht->thinker.function.acp1 = thinker; + ht->polyObjNum = READINT32(save_p); + // \todo polyfade thinker fields + P_AddThinker(&ht->thinker); +} #endif /* @@ -2886,6 +2906,10 @@ static void P_NetUnArchiveThinkers(void) case tc_polydisplace: LoadPolydisplaceThinker((actionf_p1)T_PolyObjDisplace); break; + + case tc_polyfade: + LoadPolyfadeThinker((actionf_p1)T_PolyObjFade); + break; #endif case tc_scroll: LoadScrollThinker((actionf_p1)T_Scroll); diff --git a/src/p_spec.c b/src/p_spec.c index 6c359c9cc..fd2c312fb 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1245,6 +1245,35 @@ static void PolyTranslucency(line_t *line) po->translucency = (line->frontsector->floorheight >> FRACBITS) / 100; } +// +// PolyFade +// +// Makes a polyobject translucency fade and applies tangibility +// +static void PolyFade(line_t *line) +{ + INT32 polyObjNum = line->tag; + polyobj_t *po; + + if (!(po = Polyobj_GetForNum(polyObjNum))) + { + CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjWaypoint: bad polyobj %d\n", polyObjNum); + return; + } + + // don't allow line actions to affect bad polyobjects + if (po->isBad) + return; + + polyfadedata_t pfd; + + pfd.polyObjNum = line->tag; + + // \todo polyfadedata fields + + return EV_DoPolyObjFade(&pfd); +} + // // PolyWaypoint // @@ -3337,6 +3366,9 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 491: PolyTranslucency(line); break; + case 492: + PolyFade(line); + break; #endif default: