- User definable dynamic lights

This hasn't been tested yet!
This commit is contained in:
Christoph Oelckers 2019-06-28 12:35:42 +02:00
commit 1dcbe43d95
7 changed files with 235 additions and 6 deletions

View file

@ -804,6 +804,144 @@ void AActor::DeleteAttachedLights()
AttachedLights.Clear();
}
//==========================================================================
//
//
//
//==========================================================================
extern TDeletingArray<FLightDefaults *> LightDefaults;
unsigned FindUserLight(AActor *self, FName id, bool create = false)
{
for (unsigned i = 0; i < self->UserLights.Size(); i++ )
{
if (self->UserLights[i]->GetName() == id) return i;
}
if (create)
{
auto li = new FLightDefaults(id);
return self->UserLights.Push(li);
}
return ~0u;
}
//==========================================================================
//
//
//
//==========================================================================
int AttachLightDef(AActor *self, int _lightid, int _lightname)
{
FName lightid = FName(ENamedName(_lightid));
FName lightname = FName(ENamedName(_lightname));
// Todo: Optimize. This may be too slow.
auto lightdef = LightDefaults.FindEx([=](const auto &a) {
return a->GetName() == lightid;
});
if (lightdef < LightDefaults.Size())
{
auto userlight = self->UserLights[FindUserLight(self, lightid, true)];
userlight->CopyFrom(*LightDefaults[lightdef]);
return 1;
}
return 0;
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, A_AttachLightDef, AttachLightDef)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_NAME(lightid);
PARAM_NAME(lightname);
ACTION_RETURN_BOOL(AttachLightDef(self, lightid.GetIndex(), lightname.GetIndex()));
}
//==========================================================================
//
//
//
//==========================================================================
int AttachLightDirect(AActor *self, int _lightid, int type, int color, int radius1, int radius2, int flags, double ofs_x, double ofs_y, double ofs_z, double param, double spoti, double spoto, double spotp)
{
FName lightid = FName(ENamedName(_lightid));
auto userlight = self->UserLights[FindUserLight(self, lightid, true)];
userlight->SetType(ELightType(type));
userlight->SetArg(LIGHT_RED, RPART(color));
userlight->SetArg(LIGHT_GREEN, GPART(color));
userlight->SetArg(LIGHT_BLUE, BPART(color));
userlight->SetArg(LIGHT_INTENSITY, radius1);
userlight->SetArg(LIGHT_SECONDARY_INTENSITY, radius2);
userlight->SetFlags(LightFlags::FromInt(flags));
float of[] = { float(ofs_x), float(ofs_y), float(ofs_z)};
userlight->SetOffset(of);
userlight->SetParameter(type == PulseLight? param*TICRATE : param*360.);
userlight->SetSpotInnerAngle(spoti);
userlight->SetSpotOuterAngle(spoto);
if (spotp >= -90. && spotp <= 90.)
{
userlight->SetSpotPitch(spotp);
}
else
{
userlight->UnsetSpotPitch();
}
return 1;
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, A_AttachLight, AttachLightDirect)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_NAME(lightid);
PARAM_INT(type);
PARAM_INT(color);
PARAM_INT(radius1);
PARAM_INT(radius2);
PARAM_INT(flags);
PARAM_FLOAT(ofs_x);
PARAM_FLOAT(ofs_y);
PARAM_FLOAT(ofs_z);
PARAM_FLOAT(parami);
PARAM_FLOAT(spoti);
PARAM_FLOAT(spoto);
PARAM_FLOAT(spotp);
ACTION_RETURN_BOOL(AttachLightDirect(self, lightid, type, color, radius1, radius2, flags, ofs_x, ofs_y, ofs_z, parami, spoti, spoto, spotp));
}
//==========================================================================
//
//
//
//==========================================================================
int RemoveLight(AActor *self, int _lightid)
{
FName lightid = FName(ENamedName(_lightid));
auto userlight = FindUserLight(self, lightid, false);
if (userlight < self->UserLights.Size())
{
delete self->UserLights[userlight];
self->UserLights.Delete(userlight);
}
return 1;
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, A_RemoveLight, RemoveLight)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_NAME(lightid);
ACTION_RETURN_BOOL(RemoveLight(self, lightid));
}
//==========================================================================
//
//
//
//==========================================================================
//==========================================================================
//
// This is called before saving the game