forked from Mirrors/openclonk
most of the fire stuff removed from the engine
parent
52c2227cef
commit
3bd3a1fcbb
|
@ -175,23 +175,6 @@ void C4GameObjects::CrossCheck() // Every Tick1 by ExecObjects
|
|||
// AtObject-Check: Checks for first match of obj1 at obj2
|
||||
|
||||
// Checks for this frame
|
||||
focf=tocf=OCF_None;
|
||||
// Very low level: Incineration
|
||||
if (!::Game.iTick35)
|
||||
{ focf|=OCF_OnFire; tocf|=OCF_Inflammable; }
|
||||
|
||||
if (focf && tocf)
|
||||
for (C4ObjectList::iterator iter=begin(); iter != end() && (obj1=*iter); ++iter)
|
||||
if (obj1->Status && !obj1->Contained)
|
||||
if (obj1->OCF & focf)
|
||||
{
|
||||
ocf1=obj1->OCF; ocf2=tocf;
|
||||
if ((obj2=AtObject(obj1->GetX(),obj1->GetY(),ocf2,obj1)))
|
||||
// Incineration
|
||||
if ((ocf1 & OCF_OnFire) && (ocf2 & OCF_Inflammable))
|
||||
if (!Random(obj2->Def->ContactIncinerate))
|
||||
{ obj2->Incinerate(obj1->GetFireCausePlr(), false, obj1); continue; }
|
||||
}
|
||||
|
||||
// Reverse area check: Checks for all obj2 at obj1
|
||||
|
||||
|
@ -228,7 +211,7 @@ void C4GameObjects::CrossCheck() // Every Tick1 by ExecObjects
|
|||
{
|
||||
int32_t iHitEnergy = fixtoi(speed * obj2->Mass / 5 );
|
||||
// Hit energy reduced to 1/3rd, but do not drop to zero because of this division
|
||||
iHitEnergy = Max<int32_t>(iHitEnergy/3, !!iHitEnergy);
|
||||
iHitEnergy = Max<int32_t>(iHitEnergy/3, !!iHitEnergy);
|
||||
obj1->DoEnergy(-iHitEnergy/5, false, C4FxCall_EngObjHit, obj2->Controller);
|
||||
int tmass=Max<int32_t>(obj1->Mass,50);
|
||||
C4PropList* pActionDef = obj1->GetAction();
|
||||
|
|
|
@ -927,43 +927,6 @@ void C4Object::UpdateOCF()
|
|||
#endif
|
||||
}
|
||||
|
||||
bool C4Object::ExecFire(int32_t iFireNumber, int32_t iCausedByPlr)
|
||||
{
|
||||
// Fire Phase
|
||||
FirePhase++; if (FirePhase>=MaxFirePhase) FirePhase=0;
|
||||
// Decay
|
||||
if (!Def->NoBurnDecay)
|
||||
DoCon(-100);
|
||||
// Damage
|
||||
if (!::Game.iTick10) if (!Def->NoBurnDamage) DoDamage(+2,iCausedByPlr,C4FxCall_DmgFire);
|
||||
// Energy
|
||||
if (!::Game.iTick5) DoEnergy(-1,false,C4FxCall_EngFire, iCausedByPlr);
|
||||
// Effects
|
||||
int32_t smoke_level=2*Shape.Wdt/3;
|
||||
int32_t smoke_rate=Def->SmokeRate;
|
||||
if (smoke_rate)
|
||||
{
|
||||
smoke_rate=50*smoke_level/smoke_rate;
|
||||
if (!((Game.FrameCounter+(Number*7))%Max<int32_t>(smoke_rate,3)) || (Abs(xdir)>2))
|
||||
Smoke(GetX(), GetY(),smoke_level);
|
||||
}
|
||||
// Background Effects
|
||||
if (!::Game.iTick5)
|
||||
{
|
||||
int32_t mat;
|
||||
if (MatValid(mat=GBackMat(GetX(), GetY())))
|
||||
{
|
||||
// Extinguish
|
||||
if (::MaterialMap.Map[mat].Extinguisher)
|
||||
{ Extinguish(iFireNumber); if (GBackLiquid(GetX(), GetY())) StartSoundEffect("Pshshsh",false,100,this); }
|
||||
// Inflame
|
||||
if (!Random(3))
|
||||
::Landscape.Incinerate(GetX(), GetY());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool C4Object::ExecLife()
|
||||
{
|
||||
|
@ -1009,8 +972,14 @@ bool C4Object::ExecLife()
|
|||
if (!::Game.iTick10)
|
||||
if (InMat!=MNone)
|
||||
if (::MaterialMap.Map[InMat].Incindiary)
|
||||
if (Def->ContactIncinerate)
|
||||
Incinerate(NO_OWNER);
|
||||
if (Def->ContactIncinerate)
|
||||
{
|
||||
C4AulFunc *pCallFunc = this->Def->Script.GetFuncRecursive(PSF_OnInIncendiaryMaterial);
|
||||
if (pCallFunc)
|
||||
{
|
||||
pCallFunc->Exec(this, &C4AulParSet());
|
||||
}
|
||||
}
|
||||
|
||||
// birthday
|
||||
if (!::Game.iTick255)
|
||||
|
@ -1219,51 +1188,6 @@ bool C4Object::ChangeDef(C4ID idNew)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool C4Object::Incinerate(int32_t iCausedBy, bool fBlasted, C4Object *pIncineratingObject)
|
||||
{
|
||||
// Already on fire
|
||||
if (OnFire) return false;
|
||||
// add effect
|
||||
int32_t iEffNumber;
|
||||
C4Value Par1 = C4VInt(iCausedBy), Par2 = C4VBool(!!fBlasted), Par3 = C4VObj(pIncineratingObject), Par4;
|
||||
new C4Effect(this, C4Fx_Fire, C4Fx_FirePriority, C4Fx_FireTimer, NULL, C4ID::None, Par1, Par2, Par3, Par4, true, iEffNumber);
|
||||
return !!iEffNumber;
|
||||
}
|
||||
|
||||
bool C4Object::Extinguish(int32_t iFireNumber)
|
||||
{
|
||||
// any effects?
|
||||
if (!pEffects) return false;
|
||||
// fire number known: extinguish that fire
|
||||
C4Effect *pEffFire;
|
||||
if (iFireNumber)
|
||||
{
|
||||
pEffFire = pEffects->Get(iFireNumber, false);
|
||||
if (!pEffFire) return false;
|
||||
pEffFire->Kill(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
// otherwise, kill all fires
|
||||
// (keep checking from beginning of pEffects, as Kill might delete or change effects)
|
||||
int32_t iFiresKilled = 0;
|
||||
while (pEffects && (pEffFire = pEffects->Get(C4Fx_AnyFire)))
|
||||
{
|
||||
while (pEffFire && WildcardMatch(C4Fx_Internal, pEffFire->Name))
|
||||
{
|
||||
pEffFire = pEffFire->pNext;
|
||||
if (pEffFire) pEffFire = pEffFire->Get(C4Fx_AnyFire);
|
||||
}
|
||||
if (!pEffFire) break;
|
||||
pEffFire->Kill(this);
|
||||
++iFiresKilled;
|
||||
}
|
||||
if (!iFiresKilled) return false;
|
||||
}
|
||||
// done, success
|
||||
return true;
|
||||
}
|
||||
|
||||
void C4Object::DoDamage(int32_t iChange, int32_t iCausedBy, int32_t iCause)
|
||||
{
|
||||
// non-living: ask effects first
|
||||
|
@ -1326,8 +1250,15 @@ void C4Object::Blast(int32_t iLevel, int32_t iCausedBy)
|
|||
if (Alive) DoEnergy(-iLevel/3,false,C4FxCall_EngBlast, iCausedBy);
|
||||
// Incinerate
|
||||
if (Def->BlastIncinerate)
|
||||
if (Damage>=Def->BlastIncinerate)
|
||||
Incinerate(iCausedBy,true);
|
||||
if (Damage>=Def->BlastIncinerate)
|
||||
{
|
||||
C4AulFunc *pCallFunc = this->Def->Script.GetFuncRecursive(PSF_OnBlastIncinerationDamage);
|
||||
if (pCallFunc)
|
||||
{
|
||||
C4AulParSet Pars(C4VInt(iLevel), C4VInt(iCausedBy));
|
||||
pCallFunc->Exec(this, &Pars);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void C4Object::DoCon(int32_t iChange)
|
||||
|
@ -2522,16 +2453,11 @@ void C4Object::CompileFunc(StdCompiler *pComp)
|
|||
|
||||
if (pMeshInstance)
|
||||
{
|
||||
// Set Action animation by slot 0
|
||||
// Set Action animation by slot 0
|
||||
Action.Animation = pMeshInstance->GetRootAnimationForSlot(0);
|
||||
pMeshInstance->SetFaceOrderingForClrModulation(ColorMod);
|
||||
}
|
||||
|
||||
// if on fire but no effect is present (old-style savegames), re-incinerate
|
||||
int32_t iFireNumber;
|
||||
C4Value Par1, Par2, Par3, Par4;
|
||||
if (OnFire && !pEffects) new C4Effect(this, C4Fx_Fire, C4Fx_FirePriority, C4Fx_FireTimer, NULL, C4ID::None, Par1, Par2, Par3, Par4, false, iFireNumber);
|
||||
|
||||
// blit mode not assigned? use definition default then
|
||||
if (!BlitMode) BlitMode = Def->BlitMode;
|
||||
|
||||
|
@ -5020,18 +4946,6 @@ bool C4Object::CanConcatPictureWith(C4Object *pOtherObject)
|
|||
return true;
|
||||
}
|
||||
|
||||
int32_t C4Object::GetFireCausePlr()
|
||||
{
|
||||
// get fire effect
|
||||
if (!pEffects) return NO_OWNER;
|
||||
C4Effect *pFire = pEffects->Get(C4Fx_Fire);
|
||||
if (!pFire) return NO_OWNER;
|
||||
// get causing player
|
||||
int32_t iFireCausePlr = pFire->GetPropertyInt(P_CausedBy);
|
||||
// return if valid
|
||||
if (ValidPlr(iFireCausePlr)) return iFireCausePlr; else return NO_OWNER;
|
||||
}
|
||||
|
||||
void C4Object::UpdateScriptPointers()
|
||||
{
|
||||
if (pEffects)
|
||||
|
|
|
@ -258,7 +258,6 @@ public:
|
|||
void Execute();
|
||||
void ClearPointers(C4Object *ptr);
|
||||
bool ExecMovement();
|
||||
bool ExecFire(int32_t iIndex, int32_t iCausedByPlr);
|
||||
void ExecAction();
|
||||
bool ExecLife();
|
||||
bool ExecuteCommand();
|
||||
|
@ -303,7 +302,6 @@ public:
|
|||
void DoMotion(int32_t mx, int32_t my);
|
||||
bool ActivateEntrance(int32_t by_plr, C4Object *by_obj);
|
||||
bool Incinerate(int32_t iCausedBy, bool fBlasted=false, C4Object *pIncineratingObject=NULL);
|
||||
bool Extinguish(int32_t iFireNumber);
|
||||
void DoDamage(int32_t iLevel, int32_t iCausedByPlr, int32_t iCause);
|
||||
void DoEnergy(int32_t iChange, bool fExact, int32_t iCause, int32_t iCausedByPlr);
|
||||
void UpdatLastEnergyLossCause(int32_t iNewCausePlr);
|
||||
|
@ -394,8 +392,6 @@ public:
|
|||
|
||||
bool CanConcatPictureWith(C4Object *pOtherObject); // return whether this object should be grouped with the other in activation lists, contents list, etc.
|
||||
|
||||
int32_t GetFireCausePlr();
|
||||
|
||||
bool IsMoveableBySolidMask(int ComparisonPlane)
|
||||
{
|
||||
C4PropList* pActionDef = GetAction();
|
||||
|
|
|
@ -53,12 +53,6 @@ static bool FnIncinerate(C4AulObjectContext *cthr, Nillable<long> causedBy)
|
|||
return !!cthr->Obj->Incinerate(iCausedBy);
|
||||
}
|
||||
|
||||
static bool FnExtinguish(C4AulObjectContext *cthr)
|
||||
{
|
||||
// extinguish all fires
|
||||
return !!cthr->Obj->Extinguish(0);
|
||||
}
|
||||
|
||||
static C4Void FnSetSolidMask(C4AulObjectContext *cthr, long iX, long iY, long iWdt, long iHgt, long iTX, long iTY)
|
||||
{
|
||||
cthr->Obj->SetSolidMask(iX,iY,iWdt,iHgt,iTX,iTY);
|
||||
|
@ -2221,7 +2215,7 @@ static Nillable<C4String*> FnGetMeshMaterial(C4AulObjectContext* ctx, int iSubMe
|
|||
|
||||
StdSubMeshInstance& submesh = ctx->Obj->pMeshInstance->GetSubMesh(iSubMesh);
|
||||
return String(submesh.GetMaterial().Name.getData());
|
||||
}
|
||||
}
|
||||
|
||||
static bool FnSetMeshMaterial(C4AulObjectContext* ctx, C4String* Material, int iSubMesh)
|
||||
{
|
||||
|
@ -2404,7 +2398,7 @@ C4ScriptConstDef C4ScriptObjectConstMap[]=
|
|||
{ "ANIM_Loop" ,C4V_Int, ANIM_Loop },
|
||||
{ "ANIM_Hold" ,C4V_Int, ANIM_Hold },
|
||||
{ "ANIM_Remove" ,C4V_Int, ANIM_Remove },
|
||||
|
||||
|
||||
{ "AM_None" ,C4V_Int, StdMeshInstance::AM_None },
|
||||
{ "AM_DrawBefore" ,C4V_Int, StdMeshInstance::AM_DrawBefore },
|
||||
|
||||
|
@ -2554,10 +2548,6 @@ void InitObjectFunctionMap(C4AulScriptEngine *pEngine)
|
|||
AddFunc(pEngine, "SetObjectStatus", FnSetObjectStatus, false);
|
||||
AddFunc(pEngine, "GetObjectStatus", FnGetObjectStatus, false);
|
||||
AddFunc(pEngine, "AdjustWalkRotation", FnAdjustWalkRotation, false);
|
||||
AddFunc(pEngine, "FxFireStart", FnFxFireStart, false);
|
||||
AddFunc(pEngine, "FxFireTimer", FnFxFireTimer, false);
|
||||
AddFunc(pEngine, "FxFireStop", FnFxFireStop, false);
|
||||
AddFunc(pEngine, "FxFireInfo", FnFxFireInfo, false);
|
||||
AddFunc(pEngine, "GetContact", FnGetContact);
|
||||
AddFunc(pEngine, "SetObjectBlitMode", FnSetObjectBlitMode);
|
||||
AddFunc(pEngine, "GetObjectBlitMode", FnGetObjectBlitMode);
|
||||
|
@ -2582,8 +2572,6 @@ void InitObjectFunctionMap(C4AulScriptEngine *pEngine)
|
|||
AddFunc(pEngine, "GetMeshMaterial", FnGetMeshMaterial);
|
||||
AddFunc(pEngine, "SetMeshMaterial", FnSetMeshMaterial);
|
||||
AddFunc(pEngine, "ChangeDef", FnChangeDef);
|
||||
AddFunc(pEngine, "Incinerate", FnIncinerate);
|
||||
AddFunc(pEngine, "Extinguish", FnExtinguish);
|
||||
AddFunc(pEngine, "GrabContents", FnGrabContents);
|
||||
AddFunc(pEngine, "Punch", FnPunch);
|
||||
AddFunc(pEngine, "Kill", FnKill);
|
||||
|
|
|
@ -610,237 +610,6 @@ bool C4Effect::GetPropertyByS(C4String *k, C4Value *pResult) const
|
|||
return C4PropListNumbered::GetPropertyByS(k, pResult);
|
||||
}
|
||||
|
||||
// Internal fire effect
|
||||
|
||||
int32_t FnFxFireStart(C4AulContext *ctx, C4Object *pObj, C4Effect *pEffect, int32_t iTemp, int32_t iCausedBy, bool fBlasted, C4Object *pIncineratingObject)
|
||||
{
|
||||
// safety
|
||||
if (!pObj) return -1;
|
||||
// temp readd
|
||||
if (iTemp) { return 1; }
|
||||
// fail if already on fire
|
||||
if (pObj->GetOnFire()) return -1;
|
||||
// structures must eject contents now, because DoCon is not guaranteed to be executed!
|
||||
// In extinguishing material
|
||||
bool fFireCaused=true;
|
||||
int32_t iMat;
|
||||
if (MatValid(iMat=GBackMat(pObj->GetX(),pObj->GetY())))
|
||||
if (::MaterialMap.Map[iMat].Extinguisher)
|
||||
{
|
||||
// blasts should changedef in water, too!
|
||||
if (fBlasted) if (pObj->Def->BurnTurnTo!=C4ID::None) pObj->ChangeDef(pObj->Def->BurnTurnTo);
|
||||
// no fire caused
|
||||
fFireCaused = false;
|
||||
}
|
||||
// BurnTurnTo
|
||||
if (fFireCaused) if (pObj->Def->BurnTurnTo!=C4ID::None) pObj->ChangeDef(pObj->Def->BurnTurnTo);
|
||||
// eject contents
|
||||
C4Object *cobj;
|
||||
if (!pObj->Def->IncompleteActivity && !pObj->Def->NoBurnDecay)
|
||||
while ((cobj=pObj->Contents.GetObject()))
|
||||
if (pObj->Contained) cobj->Enter(pObj->Contained);
|
||||
else cobj->Exit(cobj->GetX(),cobj->GetY());
|
||||
// Detach attached objects
|
||||
cobj = 0;
|
||||
if (!pObj->Def->IncompleteActivity && !pObj->Def->NoBurnDecay)
|
||||
while ((cobj = Game.FindObject(C4ID::None, 0, 0, 0, 0, OCF_All, 0, pObj, 0, 0, ANY_OWNER, cobj)))
|
||||
{
|
||||
C4PropList* pActionDef = cobj->GetAction();
|
||||
if (pActionDef && (pActionDef->GetPropertyP(P_Procedure) == DFA_ATTACH))
|
||||
cobj->SetAction(0);
|
||||
}
|
||||
// fire caused?
|
||||
if (!fFireCaused)
|
||||
{
|
||||
// if object was blasted but not incinerated (i.e., inside extinguisher)
|
||||
// do a script callback
|
||||
if (fBlasted) pObj->Call(PSF_IncinerationEx,&C4AulParSet(C4VInt(iCausedBy)));
|
||||
return -1;
|
||||
}
|
||||
// determine fire appearance
|
||||
int32_t iFireMode;
|
||||
if (!(iFireMode=pObj->Call(PSF_FireMode).getInt()))
|
||||
{
|
||||
// set default fire modes
|
||||
DWORD dwCat = pObj->Category;
|
||||
if (dwCat & (C4D_Living | C4D_StaticBack)) // Tiere, Bäume
|
||||
iFireMode = C4Fx_FireMode_LivingVeg;
|
||||
else if (dwCat & (C4D_Structure | C4D_Vehicle)) // Gebäude und Fahrzeuge sind unten meist kantig
|
||||
iFireMode = C4Fx_FireMode_StructVeh;
|
||||
else
|
||||
iFireMode = C4Fx_FireMode_Object;
|
||||
}
|
||||
else if (!Inside<int32_t>(iFireMode, 1, C4Fx_FireMode_Last))
|
||||
{
|
||||
DebugLogF("Warning: FireMode %d of object %s (%s) is invalid!", iFireMode, pObj->GetName(), pObj->Def->GetName());
|
||||
iFireMode = C4Fx_FireMode_Object;
|
||||
}
|
||||
// store causes in effect vars
|
||||
pEffect->SetProperty(P_Mode, C4VInt(iFireMode));
|
||||
pEffect->SetProperty(P_CausedBy, C4VInt(iCausedBy)); // used in C4Object::GetFireCause and timer!
|
||||
pEffect->SetProperty(P_Blasted, C4VBool(fBlasted));
|
||||
pEffect->SetProperty(P_IncineratingObj, C4VObj(pIncineratingObject));
|
||||
// Set values
|
||||
pObj->FirePhase=Random(MaxFirePhase);
|
||||
if (pObj->Shape.Wdt*pObj->Shape.Hgt>500) StartSoundEffect("Inflame",false,100,pObj);
|
||||
if (pObj->Def->Mass>=100) StartSoundEffect("Fire",true,100,pObj);
|
||||
// Engine script call
|
||||
pObj->Call(PSF_Incineration,&C4AulParSet(C4VInt(iCausedBy)));
|
||||
// Done, success
|
||||
return C4Fx_OK;
|
||||
}
|
||||
|
||||
int32_t FnFxFireTimer(C4AulContext *ctx, C4Object *pObj, C4Effect *pEffect, int32_t iTime)
|
||||
{
|
||||
// safety
|
||||
if (!pObj) return C4Fx_Execute_Kill;
|
||||
|
||||
int iNumber = pEffect->iNumber;
|
||||
// get cause
|
||||
int32_t iCausedByPlr = NO_OWNER;
|
||||
iCausedByPlr = pEffect->GetPropertyInt(P_CausedBy);
|
||||
if (!ValidPlr(iCausedByPlr)) iCausedByPlr = NO_OWNER;
|
||||
|
||||
// causes on object
|
||||
pObj->ExecFire(iNumber, iCausedByPlr);
|
||||
|
||||
// special effects only if loaded
|
||||
if (!::Particles.IsFireParticleLoaded()) return C4Fx_OK;
|
||||
|
||||
// get effect: May be NULL after object fire execution, in which case the fire has been extinguished
|
||||
// FIXME: this is bogus
|
||||
if (!pObj->GetOnFire()) return C4Fx_Execute_Kill;
|
||||
if (!(pEffect = pObj->pEffects)) return C4Fx_Execute_Kill;
|
||||
if (!(pEffect = pEffect->Get(iNumber, true))) return C4Fx_Execute_Kill;
|
||||
|
||||
/* Fire execution behaviour transferred from script (FIRE) */
|
||||
|
||||
// get fire mode
|
||||
int32_t iFireMode = pEffect->GetPropertyInt(P_Mode);
|
||||
|
||||
// special effects only each four frames, except for objects (e.g.: Projectiles)
|
||||
if (iTime%4 && iFireMode!=C4Fx_FireMode_Object) return C4Fx_OK;
|
||||
|
||||
// no gfx for contained
|
||||
if (pObj->Contained) return C4Fx_OK;
|
||||
|
||||
// some constant effect parameters for this object
|
||||
int32_t iWidth = Max<int32_t>(pObj->Def->Shape.Wdt, 1),
|
||||
iHeight = pObj->Def->Shape.Hgt,
|
||||
iYOff = iHeight/2-pObj->Def->Shape.FireTop;
|
||||
|
||||
int32_t iCount = int32_t(sqrt(double(iWidth * iHeight))/4); // Number of particles per execution
|
||||
const int32_t iBaseParticleSize = 30; // With of particles in pixels/10, w/o add of values below
|
||||
const int32_t iParticleSizeDiff = 10; // Size variation among particles
|
||||
const int32_t iRelParticleSize = 12; // Influence of object size on particle size
|
||||
|
||||
// some varying effect parameters
|
||||
int32_t iX = pObj->GetX(), iY = pObj->GetY();
|
||||
int32_t iXDir,iYDir,iCon,iWdtCon,iA,iSize;
|
||||
|
||||
// get remainign size (%)
|
||||
iCon=iWdtCon=Max<int32_t>((100*pObj->GetCon())/FullCon, 1);
|
||||
if (!pObj->Def->GrowthType)
|
||||
// fixed width for not-stretched-objects
|
||||
if (iWdtCon<100) iWdtCon=100;
|
||||
|
||||
// regard non-center object offsets
|
||||
iX += pObj->Shape.x + pObj->Shape.Wdt/2;
|
||||
iY += pObj->Shape.y + pObj->Shape.Hgt/2;
|
||||
|
||||
// apply rotation
|
||||
float fRot[4] = { 1.0f, 0.0f, 0.0f, 1.0f };
|
||||
if (pObj->r && pObj->Def->Rotateable)
|
||||
{
|
||||
fRot[0] = (float) cosf((float) (pObj->r * M_PI/180.0));
|
||||
fRot[1] = (float) -sinf((float) (pObj->r * M_PI/180.0));
|
||||
fRot[2] = -fRot[1];
|
||||
fRot[3] = fRot[0];
|
||||
// rotated objects usually better burn from the center
|
||||
if (iYOff>0) iYOff=0;
|
||||
}
|
||||
|
||||
// Adjust particle number by con
|
||||
iCount = Max(2, iCount*iWdtCon/100);
|
||||
|
||||
// calc base for particle size parameter
|
||||
iA=(int32_t) (sqrt(sqrt(double(iWidth * iHeight))*(iCon+20)/120)*iRelParticleSize);
|
||||
|
||||
// create a double set of particles; first quarter normal (Fire); remaining three quarters additive (Fire2)
|
||||
for (int32_t i=0; i<iCount*2; ++i)
|
||||
{
|
||||
// calc actual size to be used in this frame
|
||||
// Using Random instead of SafeRandom would be safe here
|
||||
// However, since it's just affecting particles there's no need to use synchronized random values
|
||||
iSize=SafeRandom(iParticleSizeDiff+1) + iBaseParticleSize-iParticleSizeDiff/2-1 + iA;
|
||||
|
||||
// get particle target list
|
||||
C4ParticleList *pParticleList = SafeRandom(4) ? &(pObj->BackParticles) : &(pObj->FrontParticles);
|
||||
|
||||
// get particle def and color
|
||||
C4ParticleDef *pPartDef; DWORD dwClr;
|
||||
if (i<iCount/2)
|
||||
{
|
||||
dwClr = 0x32004000 + ((SafeRandom(59) + 196) << 16);
|
||||
pPartDef = ::Particles.pFire1;
|
||||
}
|
||||
else
|
||||
{
|
||||
dwClr = 0xffffff;
|
||||
pPartDef = ::Particles.pFire2;
|
||||
}
|
||||
if (iFireMode == C4Fx_FireMode_Object) dwClr += 0x62000000;
|
||||
|
||||
// get particle creation pos...
|
||||
int32_t iRandX = SafeRandom(iWidth+1)-iWidth/2-1;
|
||||
|
||||
int32_t iPx = iRandX*iWdtCon/100;
|
||||
int32_t iPy = iYOff*iCon/100;
|
||||
if (iFireMode==C4Fx_FireMode_LivingVeg) iPy -= iPx*iPx*100/iWidth/iWdtCon; // parable form particle pos on livings
|
||||
|
||||
// ...and movement speed
|
||||
if (iFireMode != C4Fx_FireMode_Object)
|
||||
{
|
||||
// ...for normal fire proc
|
||||
iXDir = iRandX*iCon/400 - int32_t(iPx/3) - int32_t(fixtof(pObj->xdir) * 3);
|
||||
iYDir = -SafeRandom(15 + iHeight*iCon/300)-1 - int32_t(fixtof(pObj->ydir) * 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
// ...for objects
|
||||
iXDir = -int32_t(fixtof(pObj->xdir) * 3);
|
||||
iYDir = -int32_t(fixtof(pObj->ydir) * 3);
|
||||
if (!iYDir) iYDir = -SafeRandom(13+iHeight/4)-1;
|
||||
}
|
||||
|
||||
// OK; create it!
|
||||
::Particles.Create(pPartDef, float(iX)+fRot[0]*iPx+fRot[1]*iPy, float(iY)+fRot[2]*iPx+fRot[3]*iPy, (float) iXDir/10.0f, (float) iYDir/10.0f, (float) iSize/10.0f, dwClr, pParticleList,pObj);
|
||||
}
|
||||
|
||||
return C4Fx_OK;
|
||||
}
|
||||
|
||||
int32_t FnFxFireStop(C4AulContext *ctx, C4Object *pObj, C4Effect * pEffect, int32_t iReason, bool fTemp)
|
||||
{
|
||||
// safety
|
||||
if (!pObj) return false;
|
||||
// only if real removal is done
|
||||
if (fTemp)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// stop sound
|
||||
if (pObj->Def->Mass>=100) StopSoundEffect("Fire",pObj);
|
||||
// done, success
|
||||
return true;
|
||||
}
|
||||
|
||||
C4String *FnFxFireInfo(C4AulContext *ctx, C4Object *pObj, C4Effect * pEffect)
|
||||
{
|
||||
return Strings.RegString(LoadResStr("IDS_OBJ_BURNS"));
|
||||
}
|
||||
|
||||
|
||||
// Some other, internal effects -------------------------------------------------------------
|
||||
|
||||
void Splash(int32_t tx, int32_t ty, int32_t amt, C4Object *pByObj)
|
||||
|
|
|
@ -66,13 +66,6 @@
|
|||
#define C4FxCall_EngStruct 39 // regular structure energy loss (normally not called)
|
||||
#define C4FxCall_EngGetPunched 40 // energy loss from Punch
|
||||
|
||||
// fire drawing modes
|
||||
#define C4Fx_FireMode_Default 0 // determine mode by category
|
||||
#define C4Fx_FireMode_LivingVeg 2 // C4D_Living and C4D_StaticBack
|
||||
#define C4Fx_FireMode_StructVeh 1 // C4D_Structure and C4D_Vehicle
|
||||
#define C4Fx_FireMode_Object 3 // other (C4D_Object and no bit set (magic))
|
||||
#define C4Fx_FireMode_Last 3 // largest valid fire mode
|
||||
|
||||
#define C4Fx_FireParticle1 "Fire"
|
||||
#define C4Fx_FireParticle2 "Fire2"
|
||||
|
||||
|
@ -158,13 +151,6 @@ inline void CompileNewFunc(C4Effect *&pRes, StdCompiler *pComp) { pRes = new C4E
|
|||
#define C4Fx_FirePriority 100
|
||||
#define C4Fx_FireTimer 1
|
||||
|
||||
// fire effect
|
||||
int32_t FnFxFireStart(C4AulContext *ctx, C4Object *pObj, C4Effect * pEffect, int32_t iTemp, int32_t iCausedBy, bool fBlasted, C4Object *pIncineratingObject);
|
||||
int32_t FnFxFireTimer(C4AulContext *ctx, C4Object *pObj, C4Effect * pEffect, int32_t iTime);
|
||||
int32_t FnFxFireStop(C4AulContext *ctx, C4Object *pObj, C4Effect * pEffect, int32_t iReason, bool fTemp);
|
||||
C4String *FnFxFireInfo(C4AulContext *ctx, C4Object *pObj, C4Effect * pEffect);
|
||||
class C4Value &FxFireVarCausedBy(C4Effect *pEffect);
|
||||
|
||||
// some other hardcoded engine effects
|
||||
void Splash(int32_t tx, int32_t ty, int32_t amt, C4Object *pByObj);
|
||||
void Smoke(int32_t tx, int32_t ty, int32_t level, DWORD dwClr=0);
|
||||
|
|
|
@ -1938,7 +1938,7 @@ static C4ValueArray* FnSimFlight(C4AulContext *ctx, int X, int Y, Nillable<int>
|
|||
if (!SimFlight(x, y, xdir, ydir, iDensityMin, iDensityMax, iIter))
|
||||
{
|
||||
iIter *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
// write results to array
|
||||
C4ValueArray *pResults = new C4ValueArray(5);
|
||||
|
@ -2573,10 +2573,6 @@ void InitGameFunctionMap(C4AulScriptEngine *pEngine)
|
|||
AddFunc(pEngine, "RemoveUnusedTexMapEntries", FnRemoveUnusedTexMapEntries);
|
||||
AddFunc(pEngine, "SimFlight", FnSimFlight);
|
||||
AddFunc(pEngine, "LoadScenarioSection", FnLoadScenarioSection);
|
||||
AddFunc(pEngine, "FxFireStart", FnFxFireStart, false);
|
||||
AddFunc(pEngine, "FxFireTimer", FnFxFireTimer, false);
|
||||
AddFunc(pEngine, "FxFireStop", FnFxFireStop, false);
|
||||
AddFunc(pEngine, "FxFireInfo", FnFxFireInfo, false);
|
||||
AddFunc(pEngine, "RemoveEffect", FnRemoveEffect);
|
||||
AddFunc(pEngine, "GetEffect", FnGetEffect);
|
||||
AddFunc(pEngine, "SetViewOffset", FnSetViewOffset);
|
||||
|
@ -2728,7 +2724,7 @@ C4ScriptConstDef C4ScriptGameConstMap[]=
|
|||
{ "DMQ_Sky" ,C4V_Int, DMQ_Sky },
|
||||
{ "DMQ_Sub" ,C4V_Int, DMQ_Sub },
|
||||
{ "DMQ_Bridge" ,C4V_Int, DMQ_Bridge },
|
||||
|
||||
|
||||
{ "PLRZOOM_Direct" ,C4V_Int, PLRZOOM_Direct },
|
||||
{ "PLRZOOM_NoIncrease" ,C4V_Int, PLRZOOM_NoIncrease },
|
||||
{ "PLRZOOM_NoDecrease" ,C4V_Int, PLRZOOM_NoDecrease },
|
||||
|
|
|
@ -138,7 +138,8 @@ bool C4ValueToMatrix(const C4ValueArray& array, StdMeshMatrix* matrix);
|
|||
#define PSF_CalcSellValue "~CalcSellValue" // C4Object *pObj, int iObjValue
|
||||
#define PSF_OnJoinCrew "~Recruitment" // int Player
|
||||
#define PSF_OnRemoveCrew "~DeRecruitment" // int Player
|
||||
|
||||
#define PSF_OnBlastIncinerationDamage "OnBlastIncinerationDamage" // int Level, int Player
|
||||
#define PSF_OnInIncendiaryMaterial "OnInIncendiaryMaterial"
|
||||
|
||||
// Effect callbacks
|
||||
|
||||
|
|
Loading…
Reference in New Issue