시스템 함수
다음 시스템 함수를 사용할 수 있습니다:
print
print(arg1, arg2, arg3, ...);
print명령은 원하는 표현식을 출력할 수 있게 해줍니다.- 출력된 메시지는 뷰어의 Sample 탭에서
user로그 카테고리로 볼 수 있습니다. print에 넘길 수 있는 인수 개수 제한은 없습니다.print자체의 평가값은 항상 0입니다.
예외적으로 print는 숫자와 문자열을 모두 인수로 받을 수 있습니다.
다음 코드는 유효합니다:
print("this is a number: ", 1); // note the space after the :
print는 각 인수를 계산한 뒤 하나의 문자열로 이어 붙여 debug 출력에 표시합니다.
숫자로 계산되는 유효한 표현식도 출력할 수 있습니다. 예를 들면:
print("bennett's current energy is: ", .bennett.energy);
sleep/wait
The syntax wait(arg), while valid, is deprecated in favour of sleep(arg)
sleep(arg);
wait(arg); //deprecated, use sleep(arg)
sleepis a special function that will ask Evilsim to wait a number of frames.sleepwill always evaluate to 0.
arg must be a number or an expression that evaluates to a number and represents the number of frames the simulator will wait for.
Due to how Evilsim handles actions, the current implementation of sleep is not intuitive when trying to extend the duration of actions.
Please use delay for this purpose instead.
예시:
keqing attack; // Keqing N1
sleep(2); // sleeps for 2 frames
keqing attack; // Keqing N2
Many users would expect that Evilsim sleeps for 2 frames after Keqing's N1 action ends.
This is not how sleep works.
sleep makes the sim sleep for 2 frames after Keqing's N1 action has reached its specified CanQueueAfter value.
The duration of sleep counts towards the action length.
- expected:
- N1 starts
- N1 ends after 15 frames
- Evilsim sleeps for 2 frames
- N2 starts after a total of 15 + 2 = 17 frames
- reality:
- N1 starts
- N1
CanQueueAfteris reached after 11 frames - Evilsim sleeps for 2 frames
- now there are 15 - (11 + 2) = 2 frames left in the N1 animation
- N1 continues for 2 more frames until the N1 animation is over
- N2 starts after a total of 11 + 2 + 2 = 15 frames
To make Evilsim sleep for 1 frame after Keqing's N1 action ends, the user would have to insert a sleep(5);.
delay
delay(arg);
delayis a special function that will ask Evilsim to delay the start of the following action by a number of frames.delaywill always evaluate to 0.
arg must be a number or an expression that evaluates to a number and represents the number of frames the simulator will wait for.
delay is executed before the sim checks if the next action is ready.
예시:
keqing burst;
delay(5);
keqing burst;
In this case, the sim would do the following:
- Keqing's 1st 원소폭발 is executed
- Evilsim executes a
delayfor 5 frames at the end of the previous action - Once the delay is over, Evilsim checks if Keqing's 2nd 원소폭발 can be executed
- Since there is not enough energy, the sim will be stuck waiting for energy
- After enough particles were collected from energy drops, Keqing's 2nd 원소폭발 is executed
If the active character is affected by hitlag during the execution of delay, then it will last longer than specified.
예시:
noelle skill;
sleep(700);
delay(50);
noelle attack;
This example uses C4 Noelle to show a source of hitlag that can occur during delay.
The sleep is used so that the C4 shield explosion happens during delay.
- Noelle's 원소전투 스킬 is executed
- Evilsim will sleep for 700 frames after the
CanQueueAfterof the previous action - Evilsim starts executing a
delaythat should last 50 frames - A few frames after
delaystarts, C4 Noelle applies 13 frames of hitlag - Noelle's Attack is executed 50 + 13 = 63 frames after the start of
delay
f
f();
f is function that takes no argument and will evaluate to the current frame number Evilsim is on.
rand
rand();
rand evaluates to an uniformly distributed random number between 0 and 1.
randnorm
randnorm();
randnorm evaluates to a normally distributed random number with mean 0 and std dev of 1.
type
type(arg);
type evaluates to the name of the gcsl type of arg.
execute_action
THIS FUNCTION IS EXPERIMENTAL AND SUBJECT TO CHANGE.
USE AT YOUR OWN RISK.
execute_action(char, action, params);
execute_action evaluates to null and is used by the sim to execute actions.
The intent behind this system function is to allow for proper typing/functional support in the future.
It being exposed here is an unintended side effect which can be used to implement a function that runs before every action.
The following example is subject to breaking in the future!
With that in mind it is possible to add (random) frame delays before each action:
fn rand_delay(mean, stddev) {
let del = randnorm() * stddev + mean;
if del > (mean + mean) {
del = mean + mean;
}
delay(del);
}
let prev_char_id = -1;
let prev_action_id = -1;
let _execute_action = execute_action;
fn execute_action(char_id number, action_id number, p map) {
print(prev_char_id, " ", prev_action_id, " ", char_id, " ", action_id);
if action_id == .action.swap {
# add delay before swap
rand_delay(12, 3);
} else if prev_action_id == .action.attack && action_id != .action.attack && action_id != .action.charge {
# add delay after attack, but only if not followed by another attack or charge
rand_delay(3, 1);
} else if prev_action_id != .action.attack {
# add delay to everything else
rand_delay(3, 1);
}
prev_char_id = char_id;
prev_action_id = action_id;
return _execute_action(char_id, action_id, p);
}
charandactionmust be a number or an expression that evaluates to a number.paramsmust be a map or an expression that evaluates to a map.
set_particle_delay
set_particle_delay(arg1, arg2);
set_particle_delaywill set the 기본값 particle delay for the character supplied inarg1to the value inarg2.- If
arg2evaluates to a number that is less than 0, 0 will be used. set_particle_delaywill always evaluate to 0.
arg1 must be a string (wrapped in double quotes) and arg2 must be a number or an expression that evaluates to a number.
예시:
set_particle_delay("xingqiu", 100);
set_swap_icd
set_swap_icd(arg1);
- This function replicates behavior not found in typical gameplay.
- By 기본값, characters in Genshin cannot swap more than once per second. However, by 'booking' (opening the Adventurer's Handbook mid-combat), the swap timer can continue while other in-game timers (such as the Spiral Abyss timer) remain paused.
- If you use this function, the resulting dps will not represent damage per real time, but will instead represent damage per in-game time.
set_swap_icdwill set the 기본값 swap ICD for all characters equal to the number of frames inarg1.- If
arg1evaluates to a number that is less than 0, an error will be returned. set_swap_icdwill always evaluate to 0.
arg1 must be a number or an expression that evaluates to a number.
예시:
set_swap_icd(0);
set_기본값_target
set_default_target(arg);
set_기본값_targetwill set the 기본값 target to the index supplied byarg.set_기본값_targetwill always evaluate to 0.
arg must be a number or an expression that evaluates to a number.
If arg is an invalid target (i.e. 3 when there are only 2 targets), then Evilsim will exit with an error.
예를 들어, if there are 2 targets, then set_기본값_target(2) will set the 기본값 target to the 2nd one.
Note that it starts at 1 and not 0 because 0 is a special case (target 0 represents the player).
set_player_pos
set_player_pos(x, y);
set_player_poswill set the player's current position to the suppliedxandycoordinate.set_player_poswill always evaluate to 0.
x and y must be a number or an expression that evaluates to a number.
set_target_pos
set_target_pos(arg, x, y);
set_target_poswill set the target with indexargto the suppliedxandycoordinates.set_target_poswill always evaluate to 0.
All arguments must be a number or an expression that evaluates to a number.
If arg is an invalid target (i.e. 3 when there are only 2 targets), then Evilsim will exit with an error.
kill_target
kill_target(arg);
kill_targetwill kill the target with indexarg.kill_targetwill always evaluate to 0.
arg must be a number or an expression that evaluates to a number.
If arg is an invalid target (i.e. 3 when there are only 2 targets), then Evilsim will exit with an error.
is_target_dead
THIS FUNCTION IS EXPERIMENTAL AND SUBJECT TO CHANGE.
USE AT YOUR OWN RISK.
is_target_dead(arg);
is_target_deadwill evaluates to 1 if the target with indexargis dead and 0 otherwise.
arg must be a number or an expression that evaluates to a number.
If arg is an invalid target (i.e. 3 when there are only 2 targets), then Evilsim will exit with an error.
pick_up_crystallize
pick_up_crystallize(element);
pick_up_crystallizewill pick up the oldest crystallize shard with the specifiedelementsupplied as a string.pick_up_crystallizewill not pick up any shard if:- no shard with the specified
elementexists - there is a shard with the specfied
element, but it cannot be picked up yet pick_up_crystallizewill return the number of crystallize shards that were picked up (either 0 or 1).
element can also be "any" to pick up the oldest crystallize shard of any element.
element must be a string or an expression that evaluates to a string.
is_even
is_even(arg);
is_even evaluates if a given number is even or not. If a number is a floating point, the number if floored first.
arg must be a number or an expression that evaluates to a number.
sin
sin(arg);
sin evaluates to the sine of the given arg.
arg must be a number or an expression that evaluates to a number.
cos
cos(arg);
cos evaluates to the cosine of the given arg.
arg must be a number or an expression that evaluates to a number.
asin
asin(arg);
asin evaluates to the arcsine of the given arg.
arg must be a number or an expression that evaluates to a number.
acos
acos(arg);
acos evaluates to the arccos of the given arg.
arg must be a number or an expression that evaluates to a number.
set_on_tick
THIS FUNCTION IS EXPERIMENTAL AND SUBJECT TO CHANGE.
USE AT YOUR OWN RISK.
set_on_tick(func);
set_on_tick evaluates to null and is a way to make the sim execute a user-defined function every frame.
In the following example, the player's stamina will be printed every frame:
fn stam() {
print(.stam);
}
set_on_tick(stam);
func must be a function or an expression that evaluates to a function.