#[no_std, cache_output]
constants = import "constants.spwn"
extract constants.obj_props
extract constants.comparisons
extract constants.easing_types
extract import "control_flow.spwn"
extract import "util.spwn"
extract import "general_triggers.spwn"
impl @group {
_range_: #[desc("Implementation of the range operator (`..`) for groups") example("
for group in 1g..10g {
-> group.move(10, 0, 0.5)
}
")] create_range_macro(@group),
move: #[desc("Implementation of the move trigger") example("10g.move(100, 0, 0.5, easing = EASE_IN_OUT)")]
(
self,
#[desc("Units to move on the X axis (10 units per grid square)")] x: @number,
#[desc("Units to move on the Y axis (10 units per grid square)")] y: @number,
#[desc("Duration of movement")] duration: @number = 0,
easing: @easing_type = NONE,
easing_rate: @number = 2
) {
$.add( trigger{
OBJ_ID: 901,
TARGET: self,
MOVE_X: x * 3,
MOVE_Y: y * 3,
DURATION: duration,
EASING: easing.id,
EASING_RATE: easing_rate,
})
wait(duration)
},
precise_move: #[desc("Combines a move trigger with a follow trigger to allow for more precise decimal movement (up to 2 decimal places)")
example("10g.precise_move(50.45,-15.23,0.5, easing = EASE_IN_OUT)")]
(
self,
#[desc("Units to move on the X axis (10 units per grid square)")] x: @number,
#[desc("Units to move on the Y axis (10 units per grid square)")] y: @number,
#[desc("Duration of movement")] duration: @number = 0,
easing: @easing_type = NONE,
easing_rate: @number = 2,
#[desc("Saves groups and objects if the group only contains one object")] single: @bool = false,
) {
if single {
self.follow(self,x_mod=-1+x,y_mod=-1+y,duration = duration)
self.move(1,1,duration=duration,easing=easing,easing_rate=easing_rate)
} else {
target = ?g
$.add(obj {
OBJ_ID: 1765,
X: 0,
Y: 80*30,
GROUPS: target,
}, true)
$.add( alpha_trigger(target,0).with(X,0).with(Y,75*30), true )
self.follow(target,x_mod=x,y_mod=y,duration = duration)
target.move(1,1,duration=duration,easing=easing,easing_rate=easing_rate)
}
},
lock_to_player: #[desc("Lock group to player position") example("10g.lock_to_player(lock_x = true, duration = 20)")]
(
self,
#[desc("Lock to player X")] lock_x: @bool = true,
#[desc("Lock to player Y")] lock_y: @bool = true,
#[desc("Duration of lock")] duration: @number = 999,
) {
$.add( trigger{
OBJ_ID: 901,
TARGET: self,
DURATION: duration,
LOCK_TO_PLAYER_X: lock_x,
LOCK_TO_PLAYER_Y: lock_y,
})
},
stop: #[desc("Implementation of the stop trigger") example("
move = !{
10g.move(1000, 0, 10)
}
move!
wait(2)
move.start_group.stop()
")]
(self){
$.add( trigger{
OBJ_ID: 1616,
TARGET: self,
})
},
alpha: #[desc("Implementation of the alpha trigger") example("1g.alpha(0)")]
(self, opacity: @number = 1, duration: @number = 0){
$.add( trigger {
OBJ_ID: 1007,
TARGET: self,
OPACITY: opacity,
DURATION: duration,
})
wait(duration)
},
toggle_on:
#[desc("Toggles the group on") example("10g.toggle_on()")]
(self){
$.add( trigger{
OBJ_ID: 1049,
TARGET: self,
ACTIVATE_GROUP: true,
})
},
toggle_off: #[desc("Toggles the group off") example("10g.toggle_off()")]
(self){
$.add( trigger{
OBJ_ID: 1049,
TARGET: self,
ACTIVATE_GROUP: false,
})
},
rotate: #[desc("Implementation of the rotate trigger") example("
center = 3g
10g.rotate(center, 360, 2, easing = EASE_IN_OUT)
")]
(
self,
#[desc("Group of object to rotate around")] center: @group,
#[desc("Rotation in degrees")] degrees: @number,
#[desc("Duration of rotation")] duration: @number = 0,
#[desc("Easing type")] easing: @easing_type = NONE,
#[desc("Easing rate")] easing_rate: @number = 2,
#[desc("Only rotate positions of the objects, not the textures")] lock_object_rotation: @bool = false
){
$.add( trigger{
OBJ_ID: 1346,
TARGET: self,
CENTER: center,
ROTATE_DEGREES: degrees,
DURATION: duration,
EASING: easing.id,
EASING_RATE: easing_rate,
LOCK_OBJECT_ROTATION: lock_object_rotation
})
wait(duration)
},
follow:
#[desc("Implementation of the follow trigger") example("10g.follow(11g)")]
(
self,
#[desc("Group of object to follow")] other: @group,
#[desc("Multiplier for the movement on the X-axis")] x_mod: @number = 1,
#[desc("Multiplier for the movement on the Y-axis")] y_mod: @number = 1,
#[desc("Duration of following")] duration: @number = 999
){
$.add( trigger{
OBJ_ID: 1347,
X_MOD: x_mod,
Y_MOD: y_mod,
DURATION: duration,
TARGET: self,
FOLLOW: other,
})
//wouldnt make any sense to wait out the duration here
},
follow_lerp:
#[desc("Keeps an object's position proportionally between 2 others")
example("
// Since this function works using follow triggers, objects need to already be in the proper position,
// otherwise they'll be offset.
1g.follow_lerp(2g,3g,0.5) // Keeps group 1 in the middle of groups 2 and 3
1g.follow_lerp(2g,3g,0.25) // Keeps group 1 25% of the way between groups 2 and 3
1g.follow_lerp(2g,3g,-1) // Keeps group 1 as a reflection of group 3 by group 2
")]
(
self,
#[desc("Group of object A to follow")] groupA: @group,
#[desc("Group of object B to follow")] groupB: @group,
#[desc("Group of object B to follow")] weight: @number = 0.5,
#[desc("Duration of following")] duration: @number = 999,
){
self.follow(groupA,x_mod = 1 - weight,y_mod = 1 - weight,duration = duration)
self.follow(groupB,x_mod = weight,y_mod = weight,duration = duration)
},
follow_player_y:
#[desc("Implementation of the follow player Y trigger") example("10g.follow_player_y(delay = 0.5)")]
(
self,
#[desc("Interpolation factor (?)")] speed: @number = 1,
#[desc("Delay of movement")] delay: @number = 0,
#[desc("Offset on the Y-axis")] offset: @number = 0,
#[desc("Maximum speed")] max_speed: @number = 0,
#[desc("Duration of following")] duration: @number = 999
){
$.add( trigger{
OBJ_ID: 1814,
SPEED : speed,
DELAY : delay,
Y_OFFSET : offset,
MAX_SPEED : max_speed,
TARGET: self,
DURATION: duration,
})
//wouldnt make any sense to wait out the duration here
},
move_to:
#[desc("Implementation of the 'Move target' feature of the move trigger. Remember that both groups can only contain one object.") example("10g.move_to(20g)")]
(
self,
#[desc("Group of the object to move to")] target: @group,
#[desc("Duration of movement")] duration: @number = 0,
#[desc("Will move to the object only on the X-axis")] x_only: @bool = false,
#[desc("Will move to the object only on the y-axis")] y_only: @bool = false,
#[desc("Easing type")] easing: @easing_type = NONE,
#[desc("Easing rate")] easing_rate: @number = 2
) {
$.add( trigger{
OBJ_ID: 901,
TARGET: self,
USE_TARGET: true,
TARGET_POS_AXES: (){
if x_only && y_only {
-> return 0
} else if x_only {
-> return 1
} else if y_only {
-> return 2
} else {
-> return 0
}
}(),
TARGET_POS: target,
DURATION: duration,
EASING: easing.id,
EASING_RATE: easing_rate,
})
wait(duration)
},
move_to_xy:
#[desc("Moves group to a specific coordinate") example("
10g.move_to_xy(300, 300)
10g.move_to_xy(x = 300) // does not move on the y axis
10g.move_to_xy(y = 300) // does not move on the x axis
")]
(
self,
#[desc("X position to move to in units (1 grid square is 30 units)")] x: @number | @NULL = null,
#[desc("Y position to move to in units (1 grid square is 30 units)")] y: @number | @NULL = null,
#[desc("Duration of movement")] duration: @number = 0,
#[desc("Easing type")] easing: @easing_type = NONE,
#[desc("Easing rate")] easing_rate: @number = 2,
) {
if x == null && y == null {
throw "At least one coordinate must be specified"
}
target = ?g
$.add(obj {
OBJ_ID: 1765,
X: x if x != null else 0,
Y: y if y != null else 0,
GROUPS: target,
}, true)
$.add( alpha_trigger(target,0).with(X,0).with(Y,75*30), true )
self.move_to(target, duration, y == null, x == null, easing, easing_rate)
},
pulse:
#[desc("Implementation of the pulse trigger for groups") example("10g.pulse(255, 0, 0, fade_out = 0.5)")]
(
self,
#[desc("Red value of pulse color (or hue if HSV is enabled)")] r: @number,
#[desc("Green value of pulse color (or saturation if HSV is enabled)")] g: @number,
#[desc("Blue value of pulse color (or brightness/value if HSV is enabled)")] b: @number,
#[desc("Fade-in duration")] fade_in: @number = 0,
#[desc("Duration to hold the color")] hold: @number = 0,
#[desc("Fade-out duration")] fade_out: @number = 0,
#[desc("Weather to prioritize this pulse over simultaneous pulses")] exclusive: @bool = false,
#[desc("Toggle HSV mode")] hsv: @bool = false,
#[desc("HSV specific: saturation checked")] s_checked: @bool = false,
#[desc("HSV specific: brightness checked")] b_checked: @bool = false
) {
if hsv {
$.add( trigger{
OBJ_ID: 1006,
COPIED_COLOR_HVS:
r as @string + "a" + g as @string + "a" + b as @string + "a"
+ s_checked as @number as @string + "a" + b_checked as @number as @string,
EXCLUSIVE: exclusive,
FADE_IN: fade_in,
HOLD: hold,
FADE_OUT: fade_out,
TARGET: self,
PULSE_HSV: hsv,
TARGET_TYPE: 1 //group
})
} else {
$.add( trigger{
OBJ_ID: 1006,
TRIGGER_RED: r,
TRIGGER_GREEN: g,
TRIGGER_BLUE: b,
EXCLUSIVE: exclusive,
FADE_IN: fade_in,
HOLD: hold,
FADE_OUT: fade_out,
TARGET: self,
PULSE_HSV: hsv,
TARGET_TYPE: 1 //group
})
}
wait(fade_in + hold + fade_out)
}
}