Troll-Brain
You can change this now in User CP.
- Reaction score
- 85
Since creating/removing an unit is the highest operation possible in wc3, recycling projectiles would be good, so i suggest to use the SetUnitLookAt stuff.
function s__vector_createTerrainPoint takes real x,real y returns integer
local integer v= s__vector__allocate()
call MoveLocation(s__vector_loc , x , y)
set s__vector_x[v]=x
set s__vector_y[v]=y
set s__vector_z[v]=GetLocationZ(loc)//This one is causing the error
return v
endfunction
function s__vector_getTerrainPoint takes integer this,real x,real y returns nothing
call MoveLocation(s__vector_loc , x , y)
set s__vector_x[this]=x
set s__vector_y[this]=y
set s__vector_z[this]=GetLocationZ(loc)//This one is causing the error
endfunction
...
static method createTerrainPoint takes real x, real y returns vector
local vector v = vector.allocate()
call MoveLocation(vector.loc,x,y)
set v.x=x
set v.y=y
set v.z=GetLocationZ(loc)
return v
endmethod
method getTerrainPoint takes real x, real y returns nothing
call MoveLocation(vector.loc,x,y)
set this.x=x
set this.y=y
set this.z=GetLocationZ(loc)
endmethod
...
...
static method createTerrainPoint takes real x, real y returns vector
local vector v = vector.allocate()
call MoveLocation(vector.loc,x,y)
set v.x=x
set v.y=y
set v.z=GetLocationZ(vector.loc)
return v
endmethod
method getTerrainPoint takes real x, real y returns nothing
call MoveLocation(vector.loc,x,y)
set this.x=x
set this.y=y
set this.z=GetLocationZ(vector.loc)
endmethod
...
Little bit of an update:
I have implemented [ljass]SetUnitLookAt()[/ljass] into my latest build for the upcoming update, however there is no way for it to work with arcing projectiles.
So that sucks...
I've done projectile systems
local real tempX = xPos - this.pos.x
local real tempY = yPos - this.pos.y
local real tempZ = zPos - this.pos.z
set this.angle = Atan2(tempY,tempX)
set this.pitch = Atan2(SquareRoot(tempX * tempX + tempY * tempY),tempZ)
set this.speed = speed * T32_PERIOD
set this.vel = vector.create(Sin(this.pitch) * Cos(this.angle) * this.speed,Sin(this.pitch) * Sin(this.angle) * this.speed,Cos(this.pitch) * this.speed)
local real tempX = xPos - this.pos.x
local real tempY = yPos - this.pos.y
local real tempZ = zPos - this.pos.z
local real tempDist = SquareRoot(tempX*tempX+tempY*tempY+tempZ*tempZ)
set this.speed = speed * T32_PERIOD
set this.vel = vector.create(tempX/tempDist * this.speed, tempY/tempDist * this.speed, tempZ/tempDist * this.speed)
include "cj_types.j"
//include "cj_typesEx.j"
//include "cj_types_priv.j"
//include "cj_typesEx_priv.j"
//include "cj_order.j"
//include "cj_antibj_base.j"
include "cj_print.j"
library Particle uses T32 {}
//very quick homing demo
//ON_HIT_CODE_REF should refer to a boolexpr var
//PERIODICE_CODE refers to non-static code that goes into a method
//Periodic layout-
//move/align projectile and update vars
//PERIODIC_CODE (if special conditions fail, return false)
//check for collision and run aoe etc
define <Particle.Start>(ON_HIT_CODE_REF, PERIODIC_CODE, DESTROY_CODE) = {
scope PrivateParticle##COUNTER
private module Particle {
private static group particleGroup = CreateGroup()
private unit projectile //projectile unit
private real x //projectile x coord
private real y //projectile y coord
private real facing //projectile facing
private real translationX
private real translationY
private real angle
private real angleOffset
private unit target //target unit
private real targetX
private real targetY
public real speed //projectile speed
public real turnRate //projectile turn rate
public real duration //how long projectile lasts before poofing
public real collision //projectile collision
public real aoe //aoe, will hit more than one unit!
#if ON_HIT_CODE_REF !=
private static thistype triggerProjectile__S
public static thistype operator triggerProjectile() {
return thistype.triggerProjectile__S
}
#endif
public bool periodic() {
real targetX = GetUnitX(.target)
real targetY = GetUnitY(.target)
real distX = targetX - .x
real distY = targetY - .y
real facing
//target moved or alignment necessary
if (targetX != .targetX || targetY != .targetY || .angleOffset != 0) {
.targetX = targetX
.targetY = targetY
.angle = 57.2958279*Atan2(distY, distX)
if (.angle < 0) {
.angle+=360
}
.angleOffset = .angle-.facing
if (.angleOffset < 0) {
if (.angleOffset < -180) {
.angleOffset+=360
if (.turnRate < 0) {.turnRate = -.turnRate}
}
else {
if (.turnRate > 0) {.turnRate = -.turnRate}
}
}
elseif (.angleOffset > 180) {
.angleOffset -= 360
if (turnRate > 0) {.turnRate = -.turnRate}
}
else {
if (turnRate < 0) {.turnRate = -.turnRate}
}
if (RAbsBJ(.angleOffset) <= RAbsBJ(.turnRate)) {
.facing = .angle
.angleOffset = 0
}
else {
.facing+=.turnRate
.angleOffset-=.turnRate
}
if (.facing > 360) {.facing -=360}
elseif (.facing < 0) {.facing += 360}
SetUnitFacing(.projectile, .facing)
facing = .facing*0.01745327
.translationX = Cos(facing)*.speed
.translationY = Sin(facing)*.speed
}
.x+=.translationX
.y+=.translationY
SetUnitX(.projectile, .x)
SetUnitY(.projectile, .y)
.duration-=T32_PERIOD
if (distX < 0) {distX = -distX}
if (distY < 0) {distY = -distY}
PERIODIC_CODE
if (distX <= .collision && distY <= .collision) {
UnitRemoveAbility(.projectile, 039;Aloc039;)
#if ON_HIT_CODE_REF !=
thistype.triggerProjectile__S = this
GroupEnumUnitsInRange(thistype.particleGroup, .x, .y, .aoe, ON_HIT_CODE_REF)
#endif
DESTROY_CODE
thistype.mallocRelease[thistype.mallocReleaseCount++] = this
return true
}
elseif (.duration <= 0) {
DESTROY_CODE
thistype.mallocRelease[thistype.mallocReleaseCount++] = this
return true
}
return false
}
implement T32
private static int mallocCount = 0
private static int mallocRelease[]
private static int mallocReleaseCount = 0
public static thistype create(unit projectile, unit target, real speed, real turnRate, real duration, real collision, real aoe) {
thistype this
if (thistype.mallocReleaseCount > 0) {
this = thistype.mallocRelease[--thistype.mallocReleaseCount]
}
else
{
this = ++thistype.mallocCount
}
.projectile = projectile
.x = GetUnitX(projectile)
.y = GetUnitY(projectile)
.facing = GetUnitFacing(projectile)
if (.facing > 360) {.facing -=360}
elseif (.facing < 0) {.facing +=360}
.target = target
.targetX = GetUnitX(target)-5000 //make sure not equal
.speed = speed * T32_PERIOD
.turnRate = turnRate * T32_PERIOD
.duration = duration
.collision = collision
.aoe = aoe
UnitAddAbility(.projectile, 039;Aloc039;)
UnitAddAbility(.projectile, 039;Avul039;)
.startPeriodic()
return this
}
}
}
define <Particle.End> = endscope
library Tester initializer Ini uses Particle {
private int count = 650
private int iterator
private unit target
Particle.Start(,,PeasantShooter.OnDestroy)
define private <PeasantShooter.OnDestroy> = {
//KillUnit(.projectile)
RemoveUnit(.projectile)
.projectile = null
}
define private <PeasantShooter.OnPeriodic> = {
}
struct PeasantShooter extends array {
private static boolexpr onHit
implement Particle
}
Particle.End
private void Ini() {
target = CreateUnit(Player(0), 039;hfoo039;, -4500, 0, 0)
trigger spawnStuff = CreateTrigger()
//call CreateProjectile(Player(0), 'ewsp', -2000, -2000, 11., projectileTarget, 300, 9000, 180, 500., 70., null)
TriggerAddCondition(spawnStuff, Condition(lambda bool() {
iterator = 60
do {PeasantShooter.create(CreateUnit(Player(0), 039;ewsp039;, -2000, -2000, 11), target, 10, 80, 9000, 30, 31)}
whilenot (--count == 0 || --iterator == 0)
if (count == 0) {return true}
return false
}))
whilenot (TriggerEvaluate(spawnStuff)) {}
}
}
Also: are you sure your projectile on projectile collision works properly like that? From my tests, just removing 'Aloc' from a unit doesn't mean it will be detected by GroupEnums.
private void Ini() {
//.........
//this line here
TriggerAddCondition(spawnStuff, Condition(lambda bool() {
iterator = 60
do {PeasantShooter.create(CreateUnit(Player(0), 039;ewsp039;, -2000, -2000, 11), target, 10, 80, 9000, 30, 31)}
whilenot (--count == 0 || --iterator == 0)
if (count == 0) {return true}
return false
}))
//......
}