diff --git a/src/actor.h b/src/actor.h index 9f6d00e02..d83446827 100644 --- a/src/actor.h +++ b/src/actor.h @@ -1318,6 +1318,14 @@ public: { return Prev + (ticFrac * (Pos() - Prev)); } + DRotator InterpolatedAngles(double ticFrac) const + { + DRotator result; + result.Yaw = PrevAngles.Yaw + deltaangle(PrevAngles.Yaw, Angles.Yaw) * ticFrac; + result.Pitch = PrevAngles.Pitch + deltaangle(PrevAngles.Pitch, Angles.Pitch) * ticFrac; + result.Roll = PrevAngles.Roll + deltaangle(PrevAngles.Roll, Angles.Roll) * ticFrac; + return result; + } DVector3 PosPlusZ(double zadd) const { return { X(), Y(), Z() + zadd }; diff --git a/src/c_cmds.cpp b/src/c_cmds.cpp index be4944b8c..46ab072f2 100644 --- a/src/c_cmds.cpp +++ b/src/c_cmds.cpp @@ -404,9 +404,9 @@ CCMD (give) Net_WriteByte (DEM_GIVECHEAT); Net_WriteString (argv[1]); if (argv.argc() > 2) - Net_WriteWord (clamp (atoi (argv[2]), 1, 32767)); + Net_WriteLong(atoi(argv[2])); else - Net_WriteWord (0); + Net_WriteLong(0); } CCMD (take) @@ -417,9 +417,9 @@ CCMD (take) Net_WriteByte (DEM_TAKECHEAT); Net_WriteString (argv[1]); if (argv.argc() > 2) - Net_WriteWord (clamp (atoi (argv[2]), 1, 32767)); + Net_WriteLong(atoi (argv[2])); else - Net_WriteWord (0); + Net_WriteLong (0); } CCMD (gameversion) diff --git a/src/d_net.cpp b/src/d_net.cpp index 6e1d4436e..93f6a621b 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -2198,12 +2198,12 @@ void Net_DoCommand (int type, BYTE **stream, int player) case DEM_GIVECHEAT: s = ReadString (stream); - cht_Give (&players[player], s, ReadWord (stream)); + cht_Give (&players[player], s, ReadLong (stream)); break; case DEM_TAKECHEAT: s = ReadString (stream); - cht_Take (&players[player], s, ReadWord (stream)); + cht_Take (&players[player], s, ReadLong (stream)); break; case DEM_WARPCHEAT: @@ -2721,7 +2721,7 @@ void Net_SkipCommand (int type, BYTE **stream) case DEM_GIVECHEAT: case DEM_TAKECHEAT: - skip = strlen ((char *)(*stream)) + 3; + skip = strlen ((char *)(*stream)) + 5; break; case DEM_SUMMON2: diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index 76330867e..313ee7389 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -3194,34 +3194,37 @@ void PClass::Derive(PClass *newclass, FName name) void PClass::InitializeDefaults() { - assert(Defaults == NULL); - Defaults = (BYTE *)M_Malloc(Size); - - // run the constructor on the defaults to set the vtbl pointer which is needed to run class-aware functions on them. - // Temporarily setting bSerialOverride prevents linking into the thinker chains. - auto s = DThinker::bSerialOverride; - DThinker::bSerialOverride = true; - ConstructNative(Defaults); - DThinker::bSerialOverride = s; - // We must unlink the defaults from the class list because it's just a static block of data to the engine. - DObject *optr = (DObject*)Defaults; - GC::Root = optr->ObjNext; - optr->ObjNext = nullptr; - optr->SetClass(this); - - - // Copy the defaults from the parent but leave the DObject part alone because it contains important data. - if (ParentClass->Defaults != NULL) + if (IsKindOf(RUNTIME_CLASS(PClassActor))) { - memcpy(Defaults + sizeof(DObject), ParentClass->Defaults + sizeof(DObject), ParentClass->Size - sizeof(DObject)); - if (Size > ParentClass->Size) + assert(Defaults == NULL); + Defaults = (BYTE *)M_Malloc(Size); + + // run the constructor on the defaults to set the vtbl pointer which is needed to run class-aware functions on them. + // Temporarily setting bSerialOverride prevents linking into the thinker chains. + auto s = DThinker::bSerialOverride; + DThinker::bSerialOverride = true; + ConstructNative(Defaults); + DThinker::bSerialOverride = s; + // We must unlink the defaults from the class list because it's just a static block of data to the engine. + DObject *optr = (DObject*)Defaults; + GC::Root = optr->ObjNext; + optr->ObjNext = nullptr; + optr->SetClass(this); + + + // Copy the defaults from the parent but leave the DObject part alone because it contains important data. + if (ParentClass->Defaults != NULL) { - memset(Defaults + ParentClass->Size, 0, Size - ParentClass->Size); + memcpy(Defaults + sizeof(DObject), ParentClass->Defaults + sizeof(DObject), ParentClass->Size - sizeof(DObject)); + if (Size > ParentClass->Size) + { + memset(Defaults + ParentClass->Size, 0, Size - ParentClass->Size); + } + } + else + { + memset(Defaults + sizeof(DObject), 0, Size - sizeof(DObject)); } - } - else - { - memset(Defaults + sizeof(DObject), 0, Size - sizeof(DObject)); } if (bRuntimeClass) diff --git a/src/dthinker.cpp b/src/dthinker.cpp index ac0abf3c5..7b63d2635 100644 --- a/src/dthinker.cpp +++ b/src/dthinker.cpp @@ -710,8 +710,12 @@ class DThinkerIterator : public DObject, public FThinkerIterator { DECLARE_CLASS(DThinkerIterator, DObject) + DThinkerIterator() + { + } + public: - DThinkerIterator(PClass *cls = nullptr, int statnum = MAX_STATNUM + 1) + DThinkerIterator(PClass *cls, int statnum = MAX_STATNUM + 1) : FThinkerIterator(cls, statnum) { } diff --git a/src/dthinker.h b/src/dthinker.h index fce3e4f7a..e0dcb607f 100644 --- a/src/dthinker.h +++ b/src/dthinker.h @@ -125,6 +125,9 @@ public: FThinkerIterator (const PClass *type, int statnum, DThinker *prev); DThinker *Next (bool exact = false); void Reinit (); + +protected: + FThinkerIterator() {} }; template class TThinkerIterator : public FThinkerIterator diff --git a/src/g_statusbar/sbarinfo.cpp b/src/g_statusbar/sbarinfo.cpp index dadfc0a11..d6e5f6dbf 100644 --- a/src/g_statusbar/sbarinfo.cpp +++ b/src/g_statusbar/sbarinfo.cpp @@ -1597,7 +1597,7 @@ void DSBarInfoWrapper::OnDestroy() void DSBarInfoWrapper::SetScaled(bool scale, bool force) { Super::SetScaled(scale, force); - core->_SetScaled(scale); + core->_SetScaled(Scaled); } void DSBarInfoWrapper::AttachToPlayer(player_t *player) diff --git a/src/gl/dynlights/a_dynlight.cpp b/src/gl/dynlights/a_dynlight.cpp index 30537a4d2..770ea1e50 100644 --- a/src/gl/dynlights/a_dynlight.cpp +++ b/src/gl/dynlights/a_dynlight.cpp @@ -209,7 +209,7 @@ void ADynamicLight::Activate(AActor *activator) m_cycler.SetCycleType(CYCLE_Sin); m_currentRadius = m_cycler.GetVal(); } - assert(m_currentRadius > 0); + if (m_currentRadius <= 0) m_currentRadius = 1; } @@ -334,6 +334,7 @@ void ADynamicLight::Tick() m_currentRadius = float(args[LIGHT_INTENSITY]); break; } + if (m_currentRadius <= 0) m_currentRadius = 1; UpdateLocation(); } diff --git a/src/gl/dynlights/gl_dynlight.cpp b/src/gl/dynlights/gl_dynlight.cpp index a2fb14ff6..c4bef2051 100644 --- a/src/gl/dynlights/gl_dynlight.cpp +++ b/src/gl/dynlights/gl_dynlight.cpp @@ -194,6 +194,7 @@ void FLightDefaults::ApplyProperties(ADynamicLight * light) const light->m_cycler.ShouldCycle(true); light->m_cycler.SetCycleType(CYCLE_Sin); light->m_currentRadius = light->m_cycler.GetVal(); + if (light->m_currentRadius <= 0) light->m_currentRadius = 1; } switch (m_attenuate) @@ -369,7 +370,7 @@ void gl_ParsePointLight(FScanner &sc) defaults->SetOffset(floatTriple); break; case LIGHTTAG_SIZE: - intVal = clamp(gl_ParseInt(sc), 0, 255); + intVal = clamp(gl_ParseInt(sc), 1, 1024); defaults->SetArg(LIGHT_INTENSITY, intVal); break; case LIGHTTAG_SUBTRACTIVE: @@ -446,11 +447,11 @@ void gl_ParsePulseLight(FScanner &sc) defaults->SetOffset(floatTriple); break; case LIGHTTAG_SIZE: - intVal = clamp(gl_ParseInt(sc), 0, 1024); + intVal = clamp(gl_ParseInt(sc), 1, 1024); defaults->SetArg(LIGHT_INTENSITY, intVal); break; case LIGHTTAG_SECSIZE: - intVal = clamp(gl_ParseInt(sc), 0, 1024); + intVal = clamp(gl_ParseInt(sc), 1, 1024); defaults->SetArg(LIGHT_SECONDARY_INTENSITY, intVal); break; case LIGHTTAG_INTERVAL: @@ -536,11 +537,11 @@ void gl_ParseFlickerLight(FScanner &sc) defaults->SetOffset(floatTriple); break; case LIGHTTAG_SIZE: - intVal = clamp(gl_ParseInt(sc), 0, 255); + intVal = clamp(gl_ParseInt(sc), 1, 1024); defaults->SetArg(LIGHT_INTENSITY, intVal); break; case LIGHTTAG_SECSIZE: - intVal = clamp(gl_ParseInt(sc), 0, 255); + intVal = clamp(gl_ParseInt(sc), 1, 1024); defaults->SetArg(LIGHT_SECONDARY_INTENSITY, intVal); break; case LIGHTTAG_CHANCE: @@ -618,11 +619,11 @@ void gl_ParseFlickerLight2(FScanner &sc) defaults->SetOffset(floatTriple); break; case LIGHTTAG_SIZE: - intVal = clamp(gl_ParseInt(sc), 0, 255); + intVal = clamp(gl_ParseInt(sc), 1, 1024); defaults->SetArg(LIGHT_INTENSITY, intVal); break; case LIGHTTAG_SECSIZE: - intVal = clamp(gl_ParseInt(sc), 0, 255); + intVal = clamp(gl_ParseInt(sc), 1, 1024); defaults->SetArg(LIGHT_SECONDARY_INTENSITY, intVal); break; case LIGHTTAG_INTERVAL: @@ -707,7 +708,7 @@ void gl_ParseSectorLight(FScanner &sc) break; case LIGHTTAG_SCALE: floatVal = gl_ParseFloat(sc); - defaults->SetArg(LIGHT_SCALE, (BYTE)(floatVal * 255)); + defaults->SetArg(LIGHT_SCALE, clamp((int)(floatVal * 255), 1, 1024)); break; case LIGHTTAG_SUBTRACTIVE: defaults->SetSubtractive(gl_ParseInt(sc) != 0); diff --git a/src/gl/renderer/gl_lightdata.cpp b/src/gl/renderer/gl_lightdata.cpp index b0dccbcba..ae7f2a80d 100644 --- a/src/gl/renderer/gl_lightdata.cpp +++ b/src/gl/renderer/gl_lightdata.cpp @@ -306,12 +306,12 @@ float gl_GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfogdensity) } else if (sectorfogdensity != 0) { - // case 2: Sector has an explicit fog density set. + // case 1: Sector has an explicit fog density set. density = sectorfogdensity; } else if ((fogcolor.d & 0xffffff) == 0) { - // case 1: black fog + // case 2: black fog if (glset.lightmode != 8) { density = distfogtable[glset.lightmode != 0][gl_ClampLight(lightlevel)]; diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 1ed0fecfa..cfafabb57 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -379,7 +379,8 @@ void GLFlat::Draw(int pass, bool trans) // trans only has meaning for GLPASS_LIG case GLPASS_ALL: // Same, but also creates the dynlight data. gl_SetColor(lightlevel, rel, Colormap,1.0f); gl_SetFog(lightlevel, rel, &Colormap, false); - gl_RenderState.SetObjectColor(FlatColor | 0xff000000); + if (!gltexture->tex->isFullbright()) + gl_RenderState.SetObjectColor(FlatColor | 0xff000000); if (sector->special != GLSector_Skybox) { gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false); @@ -406,7 +407,8 @@ void GLFlat::Draw(int pass, bool trans) // trans only has meaning for GLPASS_LIG if (renderstyle==STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE); gl_SetColor(lightlevel, rel, Colormap, alpha); gl_SetFog(lightlevel, rel, &Colormap, false); - gl_RenderState.SetObjectColor(FlatColor | 0xff000000); + if (!gltexture || !gltexture->tex->isFullbright()) + gl_RenderState.SetObjectColor(FlatColor | 0xff000000); if (!gltexture) { gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index af8cbf18e..2de711398 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -120,11 +120,11 @@ void GLSprite::CalculateVertices(FVector3 *v) // Tilt the actor up or down based on pitch (increase 'somersaults' forward). // Then counteract the roll and DO A BARREL ROLL. - FAngle pitch = (float)-actor->Angles.Pitch.Degrees; + FAngle pitch = (float)-Angles.Pitch.Degrees; pitch.Normalized180(); mat.Translate(x, z, y); - mat.Rotate(0, 1, 0, 270. - actor->Angles.Yaw.Degrees); + mat.Rotate(0, 1, 0, 270. - Angles.Yaw.Degrees); mat.Rotate(1, 0, 0, pitch.Degrees); if (actor->renderflags & RF_ROLLCENTER) @@ -133,12 +133,12 @@ void GLSprite::CalculateVertices(FVector3 *v) float cy = (y1 + y2) * 0.5; mat.Translate(cx - x, 0, cy - y); - mat.Rotate(0, 1, 0, - actor->Angles.Roll.Degrees); + mat.Rotate(0, 1, 0, - Angles.Roll.Degrees); mat.Translate(-cx, -z, -cy); } else { - mat.Rotate(0, 1, 0, - actor->Angles.Roll.Degrees); + mat.Rotate(0, 1, 0, - Angles.Roll.Degrees); mat.Translate(-x, -z, -y); } v[0] = mat * FVector3(x2, z, y2); @@ -200,11 +200,11 @@ void GLSprite::CalculateVertices(FVector3 *v) // [fgsfds] calculate yaw vectors float yawvecX = 0, yawvecY = 0, rollDegrees = 0; float angleRad = (270. - GLRenderer->mAngles.Yaw).Radians(); - if (actor) rollDegrees = actor->Angles.Roll.Degrees; + if (actor) rollDegrees = Angles.Roll.Degrees; if (isFlatSprite) { - yawvecX = actor->Angles.Yaw.Cos(); - yawvecY = actor->Angles.Yaw.Sin(); + yawvecX = Angles.Yaw.Cos(); + yawvecY = Angles.Yaw.Sin(); } // [fgsfds] Rotate the sprite about the sight vector (roll) @@ -327,12 +327,16 @@ void GLSprite::Draw(int pass) { gl_SetDynSpriteLight(gl_light_sprites ? actor : NULL, gl_light_particles ? particle : NULL); } - PalEntry finalcol(ThingColor.a, - ThingColor.r * actor->Sector->SpecialColors[sector_t::sprites].r / 255, - ThingColor.g * actor->Sector->SpecialColors[sector_t::sprites].g / 255, - ThingColor.b * actor->Sector->SpecialColors[sector_t::sprites].b / 255); + sector_t *cursec = actor ? actor->Sector : particle ? particle->subsector->sector : nullptr; + if (cursec != nullptr) + { + PalEntry finalcol(ThingColor.a, + ThingColor.r * cursec->SpecialColors[sector_t::sprites].r / 255, + ThingColor.g * cursec->SpecialColors[sector_t::sprites].g / 255, + ThingColor.b * cursec->SpecialColors[sector_t::sprites].b / 255); - gl_RenderState.SetObjectColor(finalcol); + gl_RenderState.SetObjectColor(finalcol); + } gl_SetColor(lightlevel, rel, Colormap, trans); } @@ -713,10 +717,6 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal) } } } - if (thing == camera) - { - int a = 0; - } // don't draw first frame of a player missile if (thing->flags&MF_MISSILE) @@ -738,6 +738,7 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal) int clipres = GLRenderer->mClipPortal->ClipPoint(thingpos); if (clipres == GLPortal::PClip_InFront) return; } + Angles = thing->InterpolatedAngles(r_TicFracF); player_t *player = &players[consoleplayer]; FloatRect r; @@ -784,7 +785,7 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal) } else if (!(thing->renderflags & RF_FLATSPRITE)) { - patch = gl_GetSpriteFrame(spritenum, thing->frame, -1, (ang - (thing->Angles.Yaw + thing->SpriteRotation)).BAMs(), &mirror); + patch = gl_GetSpriteFrame(spritenum, thing->frame, -1, (ang - (Angles.Yaw + thing->SpriteRotation)).BAMs(), &mirror); } else { @@ -855,8 +856,8 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal) } break; case RF_WALLSPRITE: - viewvecX = thing->Angles.Yaw.Cos(); - viewvecY = thing->Angles.Yaw.Sin(); + viewvecX = Angles.Yaw.Cos(); + viewvecY = Angles.Yaw.Sin(); x1 = x + viewvecY*leftfac; x2 = x + viewvecY*rightfac; diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index 151a5ef71..7206c86c5 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -376,6 +376,7 @@ public: AActor * actor; particle_t * particle; TArray *lightlist; + DRotator Angles; void SplitSprite(sector_t * frontsector, bool translucent); void SetLowerParam(); diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index ea2434b25..5771461bb 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -1177,6 +1177,11 @@ class DBlockThingsIterator : public DObject, public FMultiBlockThingsIterator { DECLARE_CLASS(DBlockThingsIterator, DObject); FPortalGroupArray check; +protected: + DBlockThingsIterator() + :FMultiBlockThingsIterator(check) + { + } public: FMultiBlockThingsIterator::CheckResult cres; @@ -1186,7 +1191,7 @@ public: return FMultiBlockThingsIterator::Next(&cres); } - DBlockThingsIterator(AActor *origin = nullptr, double checkradius = -1, bool ignorerestricted = false) + DBlockThingsIterator(AActor *origin, double checkradius = -1, bool ignorerestricted = false) : FMultiBlockThingsIterator(check, origin, checkradius, ignorerestricted) { cres.thing = nullptr; diff --git a/src/p_maputl.h b/src/p_maputl.h index 81d3c9d13..5e869c4e6 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -327,6 +327,8 @@ class FMultiBlockThingsIterator void startIteratorForGroup(int group); +protected: + FMultiBlockThingsIterator(FPortalGroupArray &check) : checklist(check) {} public: struct CheckResult diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index bd31af4a1..df6223242 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -4602,8 +4602,10 @@ bool AActor::UpdateWaterLevel (bool dosplash) for(auto rover : Sector->e->XFloor.ffloors) { if (!(rover->flags & FF_EXISTS)) continue; - if(!(rover->flags & FF_SWIMMABLE) || rover->flags & FF_SOLID) continue; + if (rover->flags & FF_SOLID) continue; + reset = !(rover->flags & FF_SWIMMABLE); + if (reset && rover->alpha == 0) continue; double ff_bottom=rover->bottom.plane->ZatPoint(this); double ff_top=rover->top.plane->ZatPoint(this); @@ -6251,7 +6253,7 @@ bool P_HitWater (AActor * thing, sector_t * sec, const DVector3 &pos, bool check double planez = rover->top.plane->ZatPoint(pos); if (pos.Z > planez - 0.5 && pos.Z < planez + 0.5) // allow minor imprecisions { - if (rover->flags & (FF_SOLID | FF_SWIMMABLE)) + if ((rover->flags & (FF_SOLID | FF_SWIMMABLE)) || rover->alpha > 0) { terrainnum = rover->model->GetTerrain(rover->top.isceiling); goto foundone; diff --git a/src/p_setup.cpp b/src/p_setup.cpp index e2dee7cf1..df41345f4 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -2093,9 +2093,7 @@ void P_LoadLineDefs (MapData * map) maplinedef_t *mld; int numlines = lumplen / sizeof(maplinedef_t); - level.lines.Alloc(numlines); linemap.Resize(numlines); - memset (&level.lines[0], 0, numlines*sizeof(line_t)); mldf = new char[lumplen]; map->Read(ML_LINEDEFS, mldf); @@ -2140,6 +2138,8 @@ void P_LoadLineDefs (MapData * map) i++; } } + level.lines.Alloc(numlines); + memset(&level.lines[0], 0, numlines * sizeof(line_t)); P_AllocateSideDefs (map, sidecount); @@ -2192,9 +2192,7 @@ void P_LoadLineDefs2 (MapData * map) maplinedef2_t *mld; int numlines = lumplen / sizeof(maplinedef2_t); - level.lines.Alloc(numlines); linemap.Resize(numlines); - memset (&level.lines[0], 0, numlines*sizeof(line_t)); mldf = new char[lumplen]; map->Read(ML_LINEDEFS, mldf); @@ -2233,6 +2231,8 @@ void P_LoadLineDefs2 (MapData * map) { ForceNodeBuild = true; } + level.lines.Alloc(numlines); + memset(&level.lines[0], 0, numlines * sizeof(line_t)); P_AllocateSideDefs (map, sidecount); diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index 6c732d67f..e6ab47c24 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -1461,23 +1461,23 @@ public: continue; case NAME_Color_Floor: - sec->SpecialColors[sector_t::floor] = CheckInt(key) || 0xff000000; + sec->SpecialColors[sector_t::floor] = CheckInt(key) | 0xff000000; break; case NAME_Color_Ceiling: - sec->SpecialColors[sector_t::ceiling] = CheckInt(key) || 0xff000000; + sec->SpecialColors[sector_t::ceiling] = CheckInt(key) | 0xff000000; break; case NAME_Color_Walltop: - sec->SpecialColors[sector_t::walltop] = CheckInt(key) || 0xff000000; + sec->SpecialColors[sector_t::walltop] = CheckInt(key) | 0xff000000; break; case NAME_Color_Wallbottom: - sec->SpecialColors[sector_t::wallbottom] = CheckInt(key) || 0xff000000; + sec->SpecialColors[sector_t::wallbottom] = CheckInt(key) | 0xff000000; break; case NAME_Color_Sprites: - sec->SpecialColors[sector_t::sprites] = CheckInt(key) || 0xff000000; + sec->SpecialColors[sector_t::sprites] = CheckInt(key) | 0xff000000; break; case NAME_Desaturation: diff --git a/src/scripting/zscript/zcc_compile.cpp b/src/scripting/zscript/zcc_compile.cpp index 43f5b6774..610e7554d 100644 --- a/src/scripting/zscript/zcc_compile.cpp +++ b/src/scripting/zscript/zcc_compile.cpp @@ -1874,7 +1874,14 @@ void ZCCCompiler::InitDefaults() if (!c->Type()->IsDescendantOf(RUNTIME_CLASS(AActor))) { if (c->Defaults.Size()) Error(c->cls, "%s: Non-actor classes may not have defaults", c->Type()->TypeName.GetChars()); - if (c->Type()->ParentClass) c->Type()->ParentClass->DeriveData(c->Type()); + if (c->Type()->ParentClass) + { + auto ti = static_cast(c->Type()); + FString mename = ti->TypeName.GetChars(); + + ti->InitializeDefaults(); + ti->ParentClass->DeriveData(ti); + } } else {