Visit the wiki (https://knucklecracker.com/wiki/doku.php?id=particle:start) to learn more!
Want to add this to your maps? The guide is right here (http://knucklecracker.com/wiki/doku.php?id=particle:how). It's almost literally plug-in-and-play!
The latest version should be listed below.
Current Version: 1.1.0Changelogs are here:
Spoiler
V1.0.0:
- Added Particles
- Added Particle Emitters
- Added Attractive forces between particles using a gravitational model
- Added Repulsive forces between particles using an elastic model
- Removed Herobrine
Code:
Particle.crpl:
Spoiler
# Particle.crpl
# Created: 2016.02.04 at 17:02:30 by GameGibu
# Version 1.0.0
# ------------------------------------------
#ShowTraceLog
#ClearTraceLog
once
CurrentPixelCoords asfloat ->RealY asfloat ->RealX
SetCurrentCoords(<-RealX asint <-RealY asint PixelToCell)
SetImagePosition(Self "main" <-RealX asint CurrentPixelCoords pop 1 sub sub <-RealY asint CurrentPixelCoords swap pop sub 1.0)
SetTargetOffsetX(<-RealX asint CurrentPixelCoords pop 1 sub sub)
SetTargetOffsetY(<-RealY asint CurrentPixelCoords swap pop sub)
0 ->myRealTime
0 ->myTime
0 ->IsEmitter
1 ->IsParticle
OperateWhilePaused(1)
"
" ->newline
1.0 ->UGC
0.1 ->Ks
SetUnitAttribute(Self CONST_TAKEMAPSPACE 0)
SetUnitAttribute(Self CONST_CELLWIDTH 1)
SetUnitAttribute(Self CONST_CELLHEIGHT 1)
SetUnitAttribute(Self CONST_COUNTSFORVICTORY 0)
SetUnitAttribute(Self CONST_NULLIFIERDAMAGES 0)
SetUnitAttribute(Self CONST_CREATEPZ 0)
SetUnitAttribute(Self CONST_BEAMTARGET 1)
SetUnitAttribute(Self CONST_MAXHEALTH 0.5)
SetUnitAttribute(Self CONST_HEALTH 0.5)
SetUnitAttribute(Self CONST_HEALRATE 0.0)
SetUnitAttribute(Self CONST_SHOWHEALTHBAR 0)
SetUnitAttribute(Self CONST_SUPPORTSDIGITALIS 0)
SetImage(Self "main" <-ImageSlot)
SetImageScale(Self "main" 0.75 0.75)
endonce
#SetPopupText(CurrentPixelCoords " " swap concat concat concat(<-newline) concat(CurrentX) concat(" ") concat(CurrentY) concat(<-newline) concat("Mass: ") concat(<-Mass))
<-myRealTime add(1) ->myRealTime
if(not(IsPaused))
<-myTime add(1) ->myTime
SetImage(Self "main" <-ImageSlot)
SetImageScale(Self "main" 0.75 0.75)
@run
endif
if(IsPaused and(IsEditMode))
if(GetKey("Alpha1"))
destroy(Self 0)
endif
endif
:buildList
->bui_LIM
if(<-bui_LIM 1 lt)
CreateList
else
0 ->bui_ILOOP
CreateList ->bui_LIST
while <-bui_ILOOP <-bui_LIM lt repeat
->unit
AppendToList(<-bui_LIST <-unit)
<-bui_ILOOP add(1) ->bui_ILOOP
endwhile
CopyList(<-bui_LIST)
endif
:createVector
->cre_ANGLE
->cre_MAGNITUDE
CreateList ->cre_LIST
AppendToList(<-cre_LIST <-cre_MAGNITUDE)
AppendToList(<-cre_LIST <-cre_ANGLE)
CopyList(<-cre_LIST)
:sumVectors
->sum_V1
->sum_V0
GetListElement(<-sum_V0 0) GetListElement(<-sum_V0 1) cos mul GetListElement(<-sum_V1 0) GetListElement(<-sum_V1 1) cos mul add ->sum_X
GetListElement(<-sum_V0 0) GetListElement(<-sum_V0 1) sin mul GetListElement(<-sum_V1 0) GetListElement(<-sum_V1 1) sin mul add ->sum_Y
sqrt(<-sum_X <-sum_X mul <-sum_Y <-sum_Y mul add) ->sum_MAG
atan2(<-sum_Y <-sum_X) ->sum_ANG
@createVector(<-sum_MAG <-sum_ANG)
:run
Trace(Self concat(":")) Trace("XVel: " concat(<-XVel) concat(", YVel: ") concat(<-YVel) concat(", Mass: ") concat(<-Mass))
<-RealX <-XVel add ->RealX
<-RealY <-YVel add ->RealY
SetCurrentCoords(<-RealX asint <-RealY asint PixelToCell)
SetImagePosition(Self "main" <-RealX asint CurrentPixelCoords pop 1 sub sub <-RealY asint CurrentPixelCoords swap pop sub 1.0)
SetTargetOffsetX(<-RealX asint CurrentPixelCoords pop 1 sub sub)
SetTargetOffsetY(<-RealY asint CurrentPixelCoords swap pop sub)
if(<-RealX 0.0 lte or(<-RealX MapWidth MapHeight add(1) CellToPixel pop gte)) <-XVel mul(-1.0) ->XVel endif
if(<-RealY 0.0 lte or(<-RealY MapWidth 0 CellToPixel swap pop gte)) <-YVel mul(-1.0) ->YVel endif
if(GetVoid(CurrentCoords) not) AddCreeper(CurrentCoords <-PayLoad) destroy(Self 0) endif
if(<-myTime mod(15) eq0 and(GetEnemyUnitsInRange(CurrentCoords 2) @buildList GetListCount Trace(dup) gte(5)) or(GetEnemyUnitsInRange(CurrentCoords 2) @buildList GetListCount gte(1)) or(<-myTime mod(30) eq0))
@createVector(0.0 0.0) ->totalForce
GetCoresWithVar("IsParticle" "1") @buildList ->particles
0 ->run_I
while <-run_I GetListCount(<-particles) lt repeat
GetListElement(<-particles <-run_I) ->unit
if(not(<-unit Self eq))
GetScriptVar(<-unit "Particle.crpl" "RealX") sub(<-RealX) ->OffsetX
GetScriptVar(<-unit "Particle.crpl" "RealY") sub(<-RealY) ->OffsetY
GetScriptVar(<-unit "Particle.crpl" "Mass") asfloat <-M2
sqrt(<-OffsetX dup mul <-OffsetY dup mul add) ->dist Trace("dist to " concat(<-unit) concat(": ") concat(<-dist))
atan2(<-OffsetY <-OffsetX) ->angle Trace("angle to " concat(<-unit) concat(": ") concat(<-angle))
#@createVector(<-UGC mul(<-Mass asfloat mul(<-M2 asfloat)) div(<-dist asfloat dup mul) <-angle) ->GravForce Trace("GravForce: " <-GravForce concat concat(<-newline) concat("Current totalForce: " <-totalForce concat))
@createVector(<-UGC div(<-dist asfloat dup mul) <-angle) ->GravForce Trace("GravForce: " <-GravForce concat concat(<-newline) concat("Current totalForce: " <-totalForce concat))
@sumvectors(<-totalForce <-GravForce) ->totalForce
if(<-dist 6.0 lt)
@sumVectors(<-totalForce @createvector(<-Ks mul(-6.0 add(<-dist)) <-angle)) ->totalForce
endif
endif
<-run_I add(1) ->run_I
endwhile
Trace("totalForce: " concat(<-totalForce))
GetListElement(<-totalForce 0) ->magnitude
GetListElement(<-totalForce 1) ->angle
sin(<-angle) mul(<-magnitude) div(<-Mass asfloat) ->YAccel
cos(<-angle) mul(<-magnitude) div(<-Mass asfloat) ->XAccel
<-XVel add(<-XAccel) ->XVel
<-YVel add(<-YAccel) ->YVel
if(sqrt(<-XVel dup mul <-YVel dup mul add) gt(8.0)) @createVector(8.0 atan2(<-YVel <-XVel)) ->modifyVel GetListElement(<-modifyVel 1) dup sin <-YVel mul ->YVel cos <-XVel mul ->XVel endif
if(<-RealX -20.0 lte or(<-RealX MapWidth MapHeight add(1) CellToPixel pop add(20.0) gte)) destroy(Self 0) endif
if(<-RealY -20.0 lte or(<-RealY MapWidth 0 CellToPixel swap pop add(20.0) gte)) destroy(Self 0) endif
endif
ParticleEmitter.crpl:
Spoiler
# ParticleEmitter.crpl
# Created: 2016.01.25 at 19:27:39 by GameGibu
# Version 1.0.0
# ------------------------------------------
#ShowTraceLog
once
#$Emit_Amt:1
$StartDelay:0
$Emit_Interval:15
$Emit_Payload:20
$Emit_MinVel:1.0
$Emit_MaxVel:1.0
$Emit_MinMass:1
$Emit_MaxMass:1
$EmitterImageSlot:"Custom0"
$ParticleImageSlot:"Custom0"
if(<-Emit_Amt 1 lt) 1 ->Emit_Amt endif
if(<-Emit_MinVel lt(0.125)) 0.125 ->Emit_MinVel endif
if(<-Emit_MinMass lt(1)) 1 ->Emit_MinMass endif
if(<-Emit_MaxVel lt(<-Emit_MinVel)) <-Emit_MinVel ->Emit_MaxVel endif
if(<-Emit_MaxMass lt(<-Emit_MinMass)) <-Emit_MinMass ->Emit_MaxMass endif
0 ->myTime
0 ->myRealTime
1 ->IsEmitter
0 ->IsParticle
CreateList ->Particles
SetImage(Self "main" <-EmitterImageSlot)
SetUnitAttribute(Self CONST_CREATEPZ 0)
SetUnitAttribute(Self CONST_SUPPORTSDIGITALIS 0)
SetUnitAttribute(Self CONST_BEAMTARGET 1)
#OperateWhilePaused(1)
"
" ->newline
endonce
#SetText("MousePixel: x=" GetMousePosition ", y=" swap concat concat concat concat(<-newline) concat("MouseCell: x=") GetMouseCell ", y=" swap concat concat concat)
<-myRealTime add(1) ->myRealTime
if(IsEditMode)
if(IsPaused)
SetPopupText("Press Alpha1 to remove all particles. Only works in edit mode. (Sorry!)")
else
SetPopupText("Amt: " concat(<-Emit_Amt) concat(<-newline) concat("Interval: ") concat(<-Emit_Interval asfloat 30.0 div 1 round) concat("s"))
endif
else
SetPopupText("Amt: " concat(<-Emit_Amt) concat(<-newline) concat("Interval: ") concat(<-Emit_Interval asfloat 30.0 div 1 round) concat("s"))
endif
<-myTime add(1) ->myTime
@run
:awake
SetImage(Self "main" <-EmitterImageSlot)
:intersect
Trace("@intersect, Args:") TraceStack
->L1
->L0
CreateList ->int_LIST
GetListCount(<-L0) ->int_LIM0
GetListCount(<-L1) ->int_LIM1
0 ->int_ILOOP
0 ->int_JLOOP
while <-int_ILOOP <-int_LIM0 lt repeat
while <-int_JLOOP <-int_LIM1 lt repeat
if(GetListElement(<-L0 <-int_ILOOP) GetListElement(<-L1 <-int_JLOOP) eq)
AppendToList(<-int_LIST GetListElement(<-L0 <-int_ILOOP))
endif
<-int_JLOOP add(1) ->int_JLOOP
endwhile
0 ->int_JLOOP
<-int_ILOOP add(1) ->int_ILOOP
endwhile
Trace("int_LIST: " concat(<-int_LIST))
CopyList(<-int_LIST)
:buildList
->bui_LIM
if(<-bui_LIM 1 lt)
CreateList
else
0 ->bui_ILOOP
CreateList ->bui_LIST
while <-bui_ILOOP <-bui_LIM lt repeat
->unit
AppendToList(<-bui_LIST <-unit)
<-bui_ILOOP add(1) ->bui_ILOOP
endwhile
CopyList(<-bui_LIST)
endif
:merge
->mer_L1
->mer_L0
0 ->mer_I
0 ->mer_J
0 ->mer_RESET
while <-mer_I GetListCount(<-mer_L1) lt repeat
while <-mer_J GetListCount(<-mer_L0) lt repeat
if(GetListElement(<-mer_L1 <-mer_I) GetListElement(<-mer_L0 <-mer_J) eq)
0 ->mer_J
1 ->mer_RESET
break
endif
<-mer_J add(1) ->mer_J
endwhile
if(not(<-mer_RESET)) AppendToList(<-mer_L0 GetListElement(<-mer_L1 <-mer_I)) endif
0 ->mer_RESET
0 ->mer_J
<-mer_I add(1) ->mer_I
endwhile
:purge
->pur_KEY
->pur_LIST
0 ->pur_I
while <-pur_I GetListCount(<-pur_LIST) lt repeat
if(GetListElement(<-pur_LIST <-pur_I) <-pur_KEY eq)
RemoveListElement(<-pur_LIST <-pur_I)
break
endif
<-pur_I add(1) ->pur_I
endwhile
:spawnParticles
->spa_LIM
0 ->spa_I
while <-spa_I <-spa_LIM lt repeat
CreateUnit("CRPLCore" CurrentCoords) ->unit
AddScriptToUnit(<-unit "Particle.crpl")
RandFloat mul(<-Emit_MaxVel sub(<-Emit_MinVel)) add(<-Emit_MinVel) ->newVel
RandFloat 2 PI mul mul PI sub <-newVel swap dup2 cos mul ->newXVel sin mul ->newYVel
#RandFloat mul(<-Emit_MaxVel sub(<-Emit_MinVel)) add(<-Emit_MinVel) mul(RandInt(0 2) mul(2) sub(1)) ->newXVel
#RandFloat mul(<-Emit_MaxVel sub(<-Emit_MinVel)) add(<-Emit_MinVel) mul(RandInt(0 2) mul(2) sub(1)) ->newYVel
SetScriptVar(<-unit "Particle.crpl" "XVel" <-newXVel)
SetScriptVar(<-unit "Particle.crpl" "YVel" <-newYVel)
SetScriptVar(<-unit "Particle.crpl" "Mass" RandInt(<-Emit_MinMass <-Emit_MaxMass add(1)))
SetScriptVar(<-unit "Particle.crpl" "ImageSlot" <-ParticleImageSlot)
SetScriptVar(<-unit "Particle.crpl" "PayLoad" <-Emit_Payload)
<-spa_I add(1) ->spa_I
endwhile
:run
if(<-myTime <-StartDelay gte)
if(<-myTime mod(<-Emit_Interval) eq0)
PlaySound("Misc14")
@spawnParticles(1)
endif
endif
V1.1.0:
- Decreased Lag
- Improved performance with higher particle Count
- Fixed emitters dying from beams really fast
- reverse-implemented Herobrine
- Removed Herobrine
Code:
Particle.crpl:
Spoiler
# Particle.crpl
# Created: 2016.02.04 at 17:02:30 by GameGibu
# Version 1.1.0
# ------------------------------------------
#ShowTraceLog
if(not(IsPaused)) ClearTraceLog endif
once
CurrentPixelCoords asfloat ->RealY asfloat ->RealX
SetCurrentCoords(<-RealX asint <-RealY asint PixelToCell)
SetImagePosition(Self "main" <-RealX asint CurrentPixelCoords pop 1 sub sub <-RealY asint CurrentPixelCoords swap pop sub 1.0)
SetTargetOffsetX(<-RealX asint CurrentPixelCoords pop 1 sub sub)
SetTargetOffsetY(<-RealY asint CurrentPixelCoords swap pop sub)
0 ->myRealTime
0 ->myTime
0 ->IsEmitter
1 ->IsParticle
OperateWhilePaused(1)
"
" ->newline
1.0 ->UGC
0.1 ->Ks
SetUnitAttribute(Self CONST_TAKEMAPSPACE 0)
SetUnitAttribute(Self CONST_CELLWIDTH 1)
SetUnitAttribute(Self CONST_CELLHEIGHT 1)
SetUnitAttribute(Self CONST_COUNTSFORVICTORY 0)
SetUnitAttribute(Self CONST_NULLIFIERDAMAGES 0)
SetUnitAttribute(Self CONST_CREATEPZ 0)
SetUnitAttribute(Self CONST_BEAMTARGET 1)
SetUnitAttribute(Self CONST_MAXHEALTH 0.25)
SetUnitAttribute(Self CONST_HEALTH 0.25)
SetUnitAttribute(Self CONST_HEALRATE 0.0)
SetUnitAttribute(Self CONST_SHOWHEALTHBAR 0)
SetUnitAttribute(Self CONST_SUPPORTSDIGITALIS 0)
SetUnitAttribute(Self CONST_DESTROYMODE 1)
SetImage(Self "main" <-ImageSlot)
SetImageScale(Self "main" 0.75 0.75)
endonce
#SetPopupText(CurrentPixelCoords " " swap concat concat concat(<-newline) concat(CurrentX) concat(" ") concat(CurrentY) concat(<-newline) concat("Mass: ") concat(<-Mass))
<-myRealTime add(1) ->myRealTime
if(not(IsPaused))
<-myTime add(1) ->myTime
SetImage(Self "main" <-ImageSlot)
SetImageScale(Self "main" 0.75 0.75)
@run
endif
if(IsPaused and(IsEditMode))
if(GetKey("Alpha1"))
destroy(Self 0)
endif
endif
ClearStack
:buildList
->bui_LIM
if(<-bui_LIM 1 lt)
CreateList
else
0 ->bui_ILOOP
CreateList ->bui_LIST
while <-bui_ILOOP <-bui_LIM lt repeat
->unit
AppendToList(<-bui_LIST <-unit)
<-bui_ILOOP add(1) ->bui_ILOOP
endwhile
CopyList(<-bui_LIST)
endif
:createVector
->cre_ANGLE
->cre_MAGNITUDE
CreateList ->cre_LIST
AppendToList(<-cre_LIST <-cre_MAGNITUDE)
AppendToList(<-cre_LIST <-cre_ANGLE)
CopyList(<-cre_LIST)
:sumVectors
->sum_V1
->sum_V0
GetListElement(<-sum_V0 0) GetListElement(<-sum_V0 1) cos mul GetListElement(<-sum_V1 0) GetListElement(<-sum_V1 1) cos mul add ->sum_X
GetListElement(<-sum_V0 0) GetListElement(<-sum_V0 1) sin mul GetListElement(<-sum_V1 0) GetListElement(<-sum_V1 1) sin mul add ->sum_Y
sqrt(<-sum_X <-sum_X mul <-sum_Y <-sum_Y mul add) ->sum_MAG
atan2(<-sum_Y <-sum_X) ->sum_ANG
@createVector(<-sum_MAG <-sum_ANG)
:run
Trace(Self concat(":")) Trace("XVel: " concat(<-XVel) concat(", YVel: ") concat(<-YVel) concat(", Mass: ") concat(<-Mass))
<-RealX <-XVel add ->RealX
<-RealY <-YVel add ->RealY
SetCurrentCoords(<-RealX asint <-RealY asint PixelToCell)
SetImagePosition(Self "main" <-RealX asint CurrentPixelCoords pop 1 sub sub <-RealY asint CurrentPixelCoords swap pop sub 1.0)
SetTargetOffsetX(<-RealX asint CurrentPixelCoords pop 1 sub sub)
SetTargetOffsetY(<-RealY asint CurrentPixelCoords swap pop sub)
if(<-RealX 0.0 lte or(<-RealX MapWidth MapHeight add(1) CellToPixel pop gte)) <-XVel mul(-1.0) ->XVel endif
if(<-RealY 0.0 lte or(<-RealY MapWidth 0 CellToPixel swap pop gte)) <-YVel mul(-1.0) ->YVel endif
if(GetVoid(CurrentCoords) not) AddCreeper(CurrentCoords <-PayLoad) destroy(Self 0) endif
if(GetEnemyUnitsInRange(CurrentCoords 5) @buildList ->list <-list GetListCount gte(2))
@createVector(0.0 0.0) ->totalForce
0 ->run_I
while <-run_I GetListCount(<-list) lt repeat
GetListElement(<-list <-run_I) ->unit
if(<-unit GetUnitType "CRPLCORE" eq)
if(<-unit "Particle.crpl" "IsParticle" GetScriptVar 1 eq)
if(not(<-unit Self eq))
GetScriptVar(<-unit "Particle.crpl" "RealX") sub(<-RealX) ->OffsetX
GetScriptVar(<-unit "Particle.crpl" "RealY") sub(<-RealY) ->OffsetY
GetScriptVar(<-unit "Particle.crpl" "Mass") asfloat <-M2
sqrt(<-OffsetX dup mul <-OffsetY dup mul add) ->dist #Trace("dist to " concat(<-unit) concat(": ") concat(<-dist))
atan2(<-OffsetY <-OffsetX) ->angle #Trace("angle to " concat(<-unit) concat(": ") concat(<-angle))
@createVector(<-UGC div(<-dist asfloat dup mul) <-angle) ->GravForce #Trace("GravForce: " <-GravForce concat concat(<-newline) concat("Current totalForce: " <-totalForce concat))
@sumvectors(<-totalForce <-GravForce) ->totalForce
if(<-dist 6.0 lt)
@sumVectors(<-totalForce @createvector(<-Ks mul(-6.0 add(<-dist)) <-angle)) ->totalForce
endif
endif
endif
endif
<-run_I 1 add ->run_I
endwhile
#Trace("totalForce: " concat(<-totalForce))
GetListElement(<-totalForce 0) ->magnitude
GetListElement(<-totalForce 1) ->angle
sin(<-angle) mul(<-magnitude) div(<-Mass asfloat) ->YAccel
cos(<-angle) mul(<-magnitude) div(<-Mass asfloat) ->XAccel
<-XVel add(<-XAccel) ->XVel
<-YVel add(<-YAccel) ->YVel
endif
if(sqrt(<-XVel dup mul <-YVel dup mul add) gt(4.0)) @createVector(4.0 atan2(<-YVel <-XVel)) ->modifyVel GetListElement(<-modifyVel 1) dup sin <-YVel mul ->YVel cos <-XVel mul ->XVel endif
if(<-RealX -20.0 lte or(<-RealX MapWidth MapHeight add(1) CellToPixel pop add(20.0) gte)) destroy(Self 0) endif
if(<-RealY -20.0 lte or(<-RealY MapWidth 0 CellToPixel swap pop add(20.0) gte)) destroy(Self 0) endif
TraceStack
:deprecated
if(<-myTime mod(15) eq0 and(GetEnemyUnitsInRange(CurrentCoords 2) @buildList GetListCount Trace(dup) gte(5)) or(GetEnemyUnitsInRange(CurrentCoords 2) @buildList GetListCount gte(1)) or(<-myTime mod(30) eq0))
@createVector(0.0 0.0) ->totalForce
GetCoresWithVar("IsParticle" "1") @buildList ->particles
0 ->run_I
while <-run_I GetListCount(<-particles) lt repeat
GetListElement(<-particles <-run_I) ->unit
if(not(<-unit Self eq))
GetScriptVar(<-unit "Particle.crpl" "RealX") sub(<-RealX) ->OffsetX
GetScriptVar(<-unit "Particle.crpl" "RealY") sub(<-RealY) ->OffsetY
GetScriptVar(<-unit "Particle.crpl" "Mass") asfloat <-M2
sqrt(<-OffsetX dup mul <-OffsetY dup mul add) ->dist Trace("dist to " concat(<-unit) concat(": ") concat(<-dist))
atan2(<-OffsetY <-OffsetX) ->angle Trace("angle to " concat(<-unit) concat(": ") concat(<-angle))
#@createVector(<-UGC mul(<-Mass asfloat mul(<-M2 asfloat)) div(<-dist asfloat dup mul) <-angle) ->GravForce Trace("GravForce: " <-GravForce concat concat(<-newline) concat("Current totalForce: " <-totalForce concat))
@createVector(<-UGC div(<-dist asfloat dup mul) <-angle) ->GravForce Trace("GravForce: " <-GravForce concat concat(<-newline) concat("Current totalForce: " <-totalForce concat))
@sumvectors(<-totalForce <-GravForce) ->totalForce
if(<-dist 6.0 lt)
@sumVectors(<-totalForce @createvector(<-Ks mul(-6.0 add(<-dist)) <-angle)) ->totalForce
endif
endif
<-run_I add(1) ->run_I
endwhile
Trace("totalForce: " concat(<-totalForce))
GetListElement(<-totalForce 0) ->magnitude
GetListElement(<-totalForce 1) ->angle
sin(<-angle) mul(<-magnitude) div(<-Mass asfloat) ->YAccel
cos(<-angle) mul(<-magnitude) div(<-Mass asfloat) ->XAccel
<-XVel add(<-XAccel) ->XVel
<-YVel add(<-YAccel) ->YVel
if(sqrt(<-XVel dup mul <-YVel dup mul add) gt(8.0)) @createVector(8.0 atan2(<-YVel <-XVel)) ->modifyVel GetListElement(<-modifyVel 1) dup sin <-YVel mul ->YVel cos <-XVel mul ->XVel endif
if(<-RealX -20.0 lte or(<-RealX MapWidth MapHeight add(1) CellToPixel pop add(20.0) gte)) destroy(Self 0) endif
if(<-RealY -20.0 lte or(<-RealY MapWidth 0 CellToPixel swap pop add(20.0) gte)) destroy(Self 0) endif
endif
ParticleEmitter.crpl:
Spoiler
# ParticleEmitter.crpl
# Created: 2016.01.25 at 19:27:39 by GameGibu
# Version 1.1.0
# ------------------------------------------
#ShowTraceLog
once
#$Emit_Amt:1
$StartDelay:0
$Emit_Interval:15
$Emit_Payload:20
$Emit_MinVel:1.0
$Emit_MaxVel:1.0
$Emit_MinMass:1
$Emit_MaxMass:1
$EmitterImageSlot:"Custom0"
$ParticleImageSlot:"Custom0"
if(<-Emit_Amt 1 lt) 1 ->Emit_Amt endif
if(<-Emit_MinVel lt(0.125)) 0.125 ->Emit_MinVel endif
if(<-Emit_MinMass lt(1)) 1 ->Emit_MinMass endif
if(<-Emit_MaxVel lt(<-Emit_MinVel)) <-Emit_MinVel ->Emit_MaxVel endif
if(<-Emit_MaxMass lt(<-Emit_MinMass)) <-Emit_MinMass ->Emit_MaxMass endif
0 ->myTime
0 ->myRealTime
1 ->IsEmitter
0 ->IsParticle
CreateList ->Particles
SetImage(Self "main" <-EmitterImageSlot)
SetUnitAttribute(Self CONST_CREATEPZ 0)
SetUnitAttribute(Self CONST_SUPPORTSDIGITALIS 0)
SetUnitAttribute(Self CONST_BEAMTARGET 1)
SetUnitAttribute(Self CONST_MAXHEALTH 10.0)
SetUnitAttribute(Self CONST_HEALTH 10.0)
SetUnitAttribute(Self CONST_SHOWHEALTHBAR 1)
SetUnitAttribute(Self CONST_HEALRATE 0.0)
SetUnitAttribute(Self CONST_NULLIFIERDAMAGES 1)
SetUnitAttribute(Self CONST_NULLIFIERDAMAGEAMT 5.0)
#OperateWhilePaused(1)
"
" ->newline
endonce
#SetText("MousePixel: x=" GetMousePosition ", y=" swap concat concat concat concat(<-newline) concat("MouseCell: x=") GetMouseCell ", y=" swap concat concat concat)
<-myRealTime add(1) ->myRealTime
if(IsEditMode)
if(IsPaused)
SetPopupText("Press Alpha1 to remove all particles. Only works in edit mode. (Sorry!)")
else
SetPopupText("Amt: " concat(<-Emit_Amt) concat(<-newline) concat("Interval: ") concat(<-Emit_Interval asfloat 30.0 div 1 round) concat("s"))
endif
else
SetPopupText("Amt: " concat(<-Emit_Amt) concat(<-newline) concat("Interval: ") concat(<-Emit_Interval asfloat 30.0 div 1 round) concat("s"))
endif
<-myTime add(1) ->myTime
@run
:awake
SetImage(Self "main" <-EmitterImageSlot)
:intersect
Trace("@intersect, Args:") TraceStack
->L1
->L0
CreateList ->int_LIST
GetListCount(<-L0) ->int_LIM0
GetListCount(<-L1) ->int_LIM1
0 ->int_ILOOP
0 ->int_JLOOP
while <-int_ILOOP <-int_LIM0 lt repeat
while <-int_JLOOP <-int_LIM1 lt repeat
if(GetListElement(<-L0 <-int_ILOOP) GetListElement(<-L1 <-int_JLOOP) eq)
AppendToList(<-int_LIST GetListElement(<-L0 <-int_ILOOP))
endif
<-int_JLOOP add(1) ->int_JLOOP
endwhile
0 ->int_JLOOP
<-int_ILOOP add(1) ->int_ILOOP
endwhile
Trace("int_LIST: " concat(<-int_LIST))
CopyList(<-int_LIST)
:buildList
->bui_LIM
if(<-bui_LIM 1 lt)
CreateList
else
0 ->bui_ILOOP
CreateList ->bui_LIST
while <-bui_ILOOP <-bui_LIM lt repeat
->unit
AppendToList(<-bui_LIST <-unit)
<-bui_ILOOP add(1) ->bui_ILOOP
endwhile
CopyList(<-bui_LIST)
endif
:merge
->mer_L1
->mer_L0
0 ->mer_I
0 ->mer_J
0 ->mer_RESET
while <-mer_I GetListCount(<-mer_L1) lt repeat
while <-mer_J GetListCount(<-mer_L0) lt repeat
if(GetListElement(<-mer_L1 <-mer_I) GetListElement(<-mer_L0 <-mer_J) eq)
0 ->mer_J
1 ->mer_RESET
break
endif
<-mer_J add(1) ->mer_J
endwhile
if(not(<-mer_RESET)) AppendToList(<-mer_L0 GetListElement(<-mer_L1 <-mer_I)) endif
0 ->mer_RESET
0 ->mer_J
<-mer_I add(1) ->mer_I
endwhile
:purge
->pur_KEY
->pur_LIST
0 ->pur_I
while <-pur_I GetListCount(<-pur_LIST) lt repeat
if(GetListElement(<-pur_LIST <-pur_I) <-pur_KEY eq)
RemoveListElement(<-pur_LIST <-pur_I)
break
endif
<-pur_I add(1) ->pur_I
endwhile
:spawnParticles
->spa_LIM
0 ->spa_I
while <-spa_I <-spa_LIM lt repeat
CreateUnit("CRPLCore" CurrentCoords) ->unit
AddScriptToUnit(<-unit "Particle.crpl")
RandFloat mul(<-Emit_MaxVel sub(<-Emit_MinVel)) add(<-Emit_MinVel) ->newVel
RandFloat 2 PI mul mul PI sub <-newVel swap dup2 cos mul ->newXVel sin mul ->newYVel
#RandFloat mul(<-Emit_MaxVel sub(<-Emit_MinVel)) add(<-Emit_MinVel) mul(RandInt(0 2) mul(2) sub(1)) ->newXVel
#RandFloat mul(<-Emit_MaxVel sub(<-Emit_MinVel)) add(<-Emit_MinVel) mul(RandInt(0 2) mul(2) sub(1)) ->newYVel
SetScriptVar(<-unit "Particle.crpl" "XVel" <-newXVel)
SetScriptVar(<-unit "Particle.crpl" "YVel" <-newYVel)
SetScriptVar(<-unit "Particle.crpl" "Mass" RandInt(<-Emit_MinMass <-Emit_MaxMass add(1)))
SetScriptVar(<-unit "Particle.crpl" "ImageSlot" <-ParticleImageSlot)
SetScriptVar(<-unit "Particle.crpl" "PayLoad" <-Emit_Payload)
<-spa_I add(1) ->spa_I
endwhile
:run
if(<-myTime <-StartDelay gte)
if(<-myTime mod(<-Emit_Interval) eq0)
PlaySound("Misc14")
@spawnParticles(1)
endif
endif
What image slots do i put the images? Wait nvm i found out that there is a special thing in the emitter code to set the textures.
Quote from: Nicant on February 09, 2016, 07:39:35 PM
What image slots do i put the images? Wait nvm i found out that there is a special thing in the emitter code to set the textures.
Lovin' the portability, eh?
Make an awesome map!
-GameGibu
Either put code in code tags without spoilers or in a spoiler with Teletype, spoiler+code tags don't work together.
I think I found the lag. If you recompile the scripts while there are particles floating in void they will all go to the lower left corner and if there is no terrain in the corner stack up and stick there causing LAG. Here's the screenshot.
Okay, question: WHY ARE YOU RECOMPILING MY SCRIPTS? :o :o Even more curious is why do so mid-game. :-\
But seriously, I coded these to be entirely portable. All the settings you would need are accessable from the editor without opening the scripts up. There is no reason on this planet or yours to recompile these scripts.
-GameGibu
By the way I've got version 1.1.0 ready to upload, with some revisions for strategicalness and major lag fixes. Pushed it up to about 1200 opcodes but it runs faster than before and only starts choking when the particle count reaches about 200+ (gotta have an essentially empty map for that).
Quote from: GameGibu on February 10, 2016, 02:53:42 PM
Okay, question: WHY ARE YOU RECOMPILING MY SCRIPTS? :o :o Even more curious is why do so mid-game. :-\
But seriously, I coded these to be entirely portable. All the settings you would need are accessable from the editor without opening the scripts up. There is no reason on this planet or yours to recompile these scripts.
-GameGibu
By the way I've got version 1.1.0 ready to upload, with some revisions for strategicalness and major lag fixes. Pushed it up to about 1200 opcodes but it runs faster than before and only starts choking when the particle count reaches about 200+ (gotta have an essentially empty map for that).
Usually if I add scripts I have to recompile everything, not just the new script cause there's no option for that. And if I'm testing to see where particles go and then if I change things with custom stuff then I recompile. I just reported this bug because people sometimes have a round world and don't notice things. They usually notice "Hey, I just recompiled my new custom thing. Wow, it erases all particles too! That's a time saver!" and don't notice the lag causing particles stuck in the corner.
As a rule of thumb I only hit "COMPILE ALL" after hitting "Load", then I save, then I test. After every test, I hit" Load" again to reset everything back to its totally initial state.
I try to avoid using the time reset and erase creeper/AC buttons.
-GameGibu
Quote from: GameGibu on February 10, 2016, 05:42:25 PM
As a rule of thumb I only hit "COMPILE ALL" after hitting "Load", then I save, then I test. After every test, I hit" Load" again to reset everything back to its totally initial state.
I try to avoid using the time reset and erase creeper/AC buttons.
-GameGibu
I usually try to make a map, then I see if there are bugs in the gameplay. If there are bugs, test, test, test. Then do a informative bug report. If the person knows about it, the world goes on. If not, then it'll be fixed and future users won't have the same problem.
The first foto is taken the frame that emitters spawn their first particles.
The second is a few momments later, where there it lags very much.
How to remove those menus?
Whups, I forgot to turn off the debug mode I guess. I'll roll out version 1.1.1 hopefully by tomorrow. Sorry! :-[
-GameGibu
Menus are possible to remove by commenting it from code with # and recompiling.
I just found a bug:
If you select a tower, pause, and press 1, all particles get destroyed.
Was this in a finalized map? If so, then it's a bug. :(
If you're in the editor however, this is an intentional but unrefined feature. Maybe I should have mentioned it earlier somewhere.
Hope that clears it up!
-GameGibu
It actually was in editor mode, but i haven't checked the bug on finallized maps yet...
Last one (probably):
If you set min (and max) velocity to 5 or more, particles go to the right only, and not up, down or left.
Can you fix that?
Quote from: Qwerty Quazo on February 12, 2016, 04:16:50 PM
Last one (probably):
If you set min (and max) velocity to 5 or more, particles go to the right only, and not up, down or left.
Can you fix that?
That's probably a side-effect of the speed limit that keeps hyperspace particles from materializing inside your base. I guess I'll just have it max starting velocity must be under 5, which is still a good speed considering the limit is 4 pixels per 1/30 of a second, or 120 pixels/second.
-GameGibu
Hey guys, I would love to see some maps you can make using this plugin!
It would also spruce up colonial space a bit, since there seem to be too many achievement maps floating around recently.
-GameGibu
How about emulating particle fleet ships?
I'm going to make a particle map soon! :) (I need to take a break from sleeper stuff :P ) http://knucklecracker.com/forums/index.php?topic=19605.msg137398#msg137398 (http://knucklecracker.com/forums/index.php?topic=19605.msg137398#msg137398)
I have a suggestion for the particles! You should have an option on an emitter that decides if the particles can bounce off of walls and or certain terrain levels!
Waiting for the update to upload the map...
Any ideas for story?
It's story-telling. But the story for my next map should introduce the next game mechanic I'll add.
-GameGibu
So... Who wants to guess the next (small-ish) game mechanic I've added to the particles?
Chance to win an appearance/easter egg reference in one of my maps!
Closes 2016.02.20 23:59 Earth Standard Time, posts will be disqualified if edited after deadline.
Best of luck! ;D ;D
-GameGibu
Quote from: GameGibu on February 19, 2016, 10:11:53 AM
So... Who wants to guess the next (small-ish) game mechanic I've added to the particles?
Chance to win an appearance/easter egg reference in one of my maps!
Closes 2016.02.20 23:59 Earth Standard Time, posts will be disqualified if edited after deadline.
Best of luck! ;D ;D
-GameGibu
Blue particles, and/or particle fields would be my guess. :D
I said small, not huge... Just large enough to warrant a new map to introduce the mechanic.
-GameGibu
Maybe ship to fight particles?
I have that planned for FAR future version, that'll take a lot of coding and that's a truly MASSIVE change in gameplay... So, no.
That's not to say you shouldn't look forward to that feature, but it's way off in the future... ;)
-GameGibu
Ships should appear in Particles V2.
That way, a lighter version of particles could be implemented. Ship control would have to use the focus transfer algorithm I have yet to translate to CRPL from my other applications.
Quote from: GameGibu on February 19, 2016, 10:56:02 AM
I have that planned for FAR future version, that'll take a lot of coding and that's a truly MASSIVE change in gameplay... So, no.
That's not to say you shouldn't look forward to that feature, but it's way off in the future... ;)
-GameGibu
Ships should appear in Particles V2.
That way, a lighter version of particles could be implemented. Ship control would have to use the focus transfer algorithm I have yet to translate to CRPL from my other applications.
The emitters can move?
Quote from: TheLongFellowPLAYER on February 19, 2016, 12:25:29 PMThe emitters are limited on how many particles can be in the map at once?
No, but keep guessing. Some of your Ideas I could include in a future version!
-GameGibu
Quote from: GameGibu on February 19, 2016, 12:50:45 PM
Quote from: TheLongFellowPLAYER on February 19, 2016, 12:25:29 PMThe emitters are limited on how many particles can be in the map at once?
No, but keep guessing. Some of your Ideas I could include in a future version!
-GameGibu
They can be specified to what terrain they land. For example, a particle on level 1 terrain turns into creeper, another lands on level 10 terrain and bounces off.
Particles are attracted to another structure on the map, or even towards player units.
Quote from: J on February 19, 2016, 02:03:14 PM
Particles are attracted to another structure on the map, or even towards player units.
You are getting a little closer. ;)
-GameGibu
Don't any of you delete your posts. I want to add some of your ideas! ;D
Quote from: GameGibu on February 19, 2016, 02:49:43 PM
Quote from: J on February 19, 2016, 02:03:14 PM
Particles are attracted to another structure on the map, or even towards player units.
You are getting a little closer. ;)
-GameGibu
Don't any of you delete your posts. I want to add some of your ideas! ;D
Particle gravity? Frozen particles that go towards your closest (like within 15 cells) unit?
Quote from: TheLongFellowPLAYER on February 19, 2016, 03:10:55 PM
Particle gravity? Frozen particles that go towards your closest (like within 15 cells) unit?
Particles already gravitate towards each other... Adding other unit attractions may happen in a different future release.
-GameGibu
Here's my two! Another particle destroying weapon or the idea i suggested that particles bounce off walls.
Quote from: Nicant on February 19, 2016, 03:40:49 PM
Here's my two! Another particle destroying weapon or the idea i suggested that particles bounce off walls.
Well you got half of it. Snipers will now target particles.
Guess the more interesting half and you win! (That goes for everyone else too!) :D :D
-GameGibu
Quote from: GameGibu on February 19, 2016, 04:16:23 PM
Quote from: Nicant on February 19, 2016, 03:40:49 PM
Here's my two! Another particle destroying weapon or the idea i suggested that particles bounce off walls.
Well you got half of it. Snipers will now target particles.
Guess the more interesting half and you win! (That goes for everyone else too!) :D :D
-GameGibu
Snipers will cause the particle to release AC?
nothing else is new with snipers, just that they target particles.
Keep trying! ;D ;D ;D ;D ;D ;D ;D ;D ;D
-GameGibu
Oh, and just in case anyone was doubting I'm working on the scripts, here's a sample of my debugging runs:
You made energy sources the particles can capture to get another particle emitter.
Anti-particles.
Sleeper+particles.
PAC+(anti-)particles.
Particles can hit something (each other?) in space causing their payload to be dropped on void.
Quote from: J on February 19, 2016, 06:00:43 PM
You made energy sources the particles can capture to get another particle emitter.
Anti-particles.
Sleeper+particles.
PAC+(anti-)particles.
Particles can hit something (each other?) in space causing their payload to be dropped on void.
Hope it's Energy sources more than any thing!
Quote from: J on February 19, 2016, 06:00:43 PM
You made energy sources the particles can capture to get another particle emitter.
Anti-particles.
Sleeper+particles.
PAC+(anti-)particles.
Particles can hit something (each other?) in space causing their payload to be dropped on void.
Amazing ideas! But still no.
Also, this script can plug in around any other existing scripts and should work flawlessly unless someone is trying to break it.
-GameGibu
Quote from: GameGibu on February 19, 2016, 06:57:18 PM
Quote from: J on February 19, 2016, 06:00:43 PM
You made energy sources the particles can capture to get another particle emitter.
Anti-particles.
Sleeper+particles.
PAC+(anti-)particles.
Particles can hit something (each other?) in space causing their payload to be dropped on void.
Amazing ideas! But still no.
Also, this script can plug in around any other existing scripts and should work flawlessly unless someone is trying to break it.
-GameGibu
Is it particle struct?
Quote from: TheLongFellowPLAYER on February 19, 2016, 09:06:10 PMIs it particle struct?
I wish. But again, that'll probably be in V2.
-GameGibu
I think i got it! It's the white emitter from the "industrial Complex" video! The white emitter attracts particles and slowly build up a normal emitter!
Quote from: Nicant on February 19, 2016, 10:09:12 PM
I think i got it! It's the white emitter from the "industrial Complex" video! The white emitter attracts particles and slowly build up a normal emitter!
You guys are great and all, but you're thinking
way too far ahead. I said a
small game mechanic.
-GameGibu
It is amazing feedback, and I can tell you all really want to be featured in one of my maps. Rock on!
Quote from: GameGibu on February 19, 2016, 10:19:18 PM
Quote from: Nicant on February 19, 2016, 10:09:12 PM
I think i got it! It's the white emitter from the "industrial Complex" video! The white emitter attracts particles and slowly build up a normal emitter!
You guys are great and all, but you're thinking way too far ahead. I said a small game mechanic.
-GameGibu
It is amazing feedback, and I can tell you all really want to be featured in one of my maps. Rock on!
Then i have officially ran out of ideas on what it could be. And BTW i don't think little, My Motto is go big or go home. :)
The version number is going from 1.1.0 to 1.2.0. A small but powerful change is underway.
Keep guessing! This also is a great collection of Ideas.
-GameGibu
Continuing development of map and script:
Invisible core what changes particles collided into it into creeper?
no, just floating terrain that reached a depth of 500 rather quickly...
Quote from: GameGibu on February 20, 2016, 12:16:51 AM
no, just floating terrain that reached a depth of 500 rather quickly...
Is it a increasing difficulty level?
It's a consequence of me trying to physically limit which way particles go by putting terrain om certain sides of the emitter.
-GameGibu
Is it terrain attraction? Or maybe shields push them away?
Quote from: TheLongFellowPLAYER on February 20, 2016, 07:49:22 AM
Or maybe shields push them away?
Bingo, you win again!
Great job!
-GameGibu
Is this somehow related into particles?
https://knucklecracker.com/forums/index.php?topic=20180.0
Edit:I asked because I wasn't sure. :)
Quote from: Builder17 on February 20, 2016, 08:09:34 AM
Is this (http://knucklecracker.com/forums/index.php?topic=20180.0) somehow related into particles?
Yes... Why do you ask?
-GameGibu
Quote from: GameGibu on February 12, 2016, 09:06:41 AM
Whups, I forgot to turn off the debug mode I guess. I'll roll out version 1.1.1 hopefully by tomorrow. Sorry! :-[
-GameGibu
Really? It's been over 2 months now...
Quote from: Qwerty Quazo on April 14, 2016, 02:53:49 PM
Quote from: GameGibu on February 12, 2016, 09:06:41 AM
Whups, I forgot to turn off the debug mode I guess. I'll roll out version 1.1.1 hopefully by tomorrow. Sorry! :-[
-GameGibu
Really? It's been over 2 months now...
It has also been a while since he was ever active.
Found a bug, guys!
Playing particle accelerator, just destroyed a particle emmiter.
When it had low life, it lost its image and when it got destroyed this happened.
Can you help?
EDIT: Happened again.
EDIT: Another bug, pz showed up before i destroyed the emmiter.
https://knucklecracker.com/forums/index.php?topic=20175.msg140711#msg140711
Quote#Somewhatbrokencodeontheright
Quote from map description.
Quote from: Qwerty Quazo on April 24, 2016, 02:22:29 PM
Found a bug, guys!
Playing particle accelerator, just destroyed a particle emmiter.
When it had low life, it lost its image and when it got destroyed this happened.
Can you help?
EDIT: Happened again.
EDIT: Another bug, pz showed up before i destroyed the emmiter.
Quote from: Builder17 on April 24, 2016, 03:33:45 PM
https://knucklecracker.com/forums/index.php?topic=20175.msg140711#msg140711
Quote#Somewhatbrokencodeontheright
Quote from map description.
Yep, I noticed that AFTER I won, and since it took like over 2+ hours of coding and playthrough I added that tag as a little thing for people to know in case that happens as there are two cores there. One will be the emitter, the other spawns land (and a PZ) in a three by three cell spot. And I messed the right side up.
How does exactly amt and mass work? I noticed references to them in the script in #, I deleted the # but no difference.
I believe it's (amt) amount of Creeper in the particle, but mass I have no idea about.
Anything on a line after the hash (#) symbol is a comment, and is not run as code, but ignored. If the variables don't turn up outside comments, it's probably a removed feature.
Eventually, I'll look at the particle script again... probably.
Amt means how many particles particle emitter creates each interval , IDK about mass. 8)
Mass can affect moving somehow? :-\
Setting amt higher than one and removing # in front of it can cause lag.
Quote from: Builder17 on July 10, 2016, 04:55:16 AM
Amt means how many particles particle emitter creates each interval.
Setting amt higher than one and removing # in front of it can cause lag.
It doesn't lag, nothing changes.
Should be like Particle fleet