Munomario777

RoA Article Template

Mar 23rd, 2020 (edited)
353
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!

What's this?

This is an easy-to-use(ish) template for RoA workshop articles. The template is quite new, so let me know if you encounter any bugs.

Concepts

States, controlled by the state variable, are programmed here to work similarly to character states. States 0-9 are included explicitly, but you can add more should you wish. In articleX_update, setState() is a custom function made to more easily handle state swaps.

Sprites are handled quite simply:

  • articleX_init sets a sprite for each state to use.
  • articleX_init sets an animation style for each state to use.
  • articleX_update sets the article's sprite to whatever its state has listed.
  • articleX_update handles the frame of the sprite based on the animation style of the current state.

articleX_init.gml

//articleX_init - runs once, when the article is created. Template by Muno

//Sprite and direction
sprite_index = sprite_get("your_sprite");           //The sprite that the article will (initially) use. Replace text in quotes with your sprite's name
image_index = 0;                                    //The frame in the animation the article should start at. 0 = beginning of animation
spr_dir = player_id.spr_dir;                        //The direction the article should face when it spawns. Here I have it set to face the same way as the character
uses_shader = true;                                 //Whether or not the article is recolored according to the character's color.gml and costume.

//State
state = 0;                                          //The behavior state the article should start in.
state_timer = 0;                                    //The point in time during that state the article should start in. (0 = beginning)
hitstop = 0;                                        //The frames remaining in hitpause. Hitpause automatically prevents movement
hsp = 0;                                            //The horizontal speed of the article. Multiply by spr_dir to correctly handle forward (+) or backward (-) movement
vsp = 0;                                            //The vertical speed of the article.
exist_timer = 0;                                    //How long the article has existed.

//Terrain behavior
can_be_grounded = false;                            //Determines if the article follows platforms when free == false.
ignores_walls = true;                               //Determines if the article goes through walls.
free = true;                                        //Whether the article is in the air or not.
hit_wall = false;                                   //If the article moves into a wall on its own, this variable will be true.

//Cope with own mortality
should_die = false;                                 //If this is ever set to true, the article will change to state 2 (despawn animation) as soon as it's not busy. This keeps it from despawning in the middle of something

//DEFINE YOUR OWN VARIABLES HERE!

//Sprites (the number in [brackets] is the state)
sprite[0] = sprite_get("article_idle");             //Example sprites
sprite[1] = sprite_get("article_attack");
sprite[2] = sprite_get("article_die");
sprite[3] = sprite_get("article_idle");
sprite[4] = sprite_get("article_idle");
sprite[5] = sprite_get("article_idle");
sprite[6] = sprite_get("article_idle");
sprite[7] = sprite_get("article_idle");
sprite[8] = sprite_get("article_idle");
sprite[9] = sprite_get("article_idle");

anim_type[0] = 0;
anim_type[1] = 1;
anim_type[2] = 0;
anim_type[3] = 0;
anim_type[4] = 0;
anim_type[5] = 0;
anim_type[6] = 0;
anim_type[7] = 0;
anim_type[8] = 0;
anim_type[9] = 0;

articleX_update.gml

//articleX_update - runs every frame the article exists. Template by Muno

/*STATE LIST

- 0 Idle
- 1 Attacking
- 2 Dying
- 3 
- 4 
- 5 
- 6 
- 7 
- 8 
- 9

*/

if (state == 0){ //Idle
    if should_die{
        setState(2);
    }

    //Custom idle behavior goes here
}

if (state == 1){ //Attack
    if (state_timer == 10){ //Make a hitbox 10 frames after entering state 1
        create_hitbox(AT_NSPECIAL, 1, x, y); //Spawns NSPECIAL hitbox 1 at article's position. Hitboxes MUST be projectiles for articles
    }
    if (state_timer == 20){ //This state lasts 20 frames
        setState(0);
    }
}

if (state == 2){ //Dying
    if (state_timer == 30){
        instance_destroy();
        exit; //Stops execution of the script
    }
}

if (state == 3){ //You can add more of these for as many states as you want
    //Behavior goes here or whatever
}

//more states can go here

//Sprite and animation handling

//Increment image_index based on the animation type assigned, in init, to the state. The example 2 are just different anim speeds and frame counts, but you can put any logic you want here
if !hitstop{
    switch(anim_type[state]){
        case 0:
            var frames = 9; //# of frames in animation
            var frame_dur = 6; //duration of each frame
            image_index = round((state_timer mod (frames * frame_dur)) / frame_dur);
            break;
        case 1:
            var frames = 20;
            var frame_dur = 3;
            image_index = round((state_timer mod (frames * frame_dur)) / frame_dur);
            break;
    }
}

//If not already at the sprite it should be, switch to the new sprite
if (sprite_index != sprite[state]){
    sprite_index = sprite[state];
}

//Make time progress
if !hitstop{
    state_timer++;
}

exist_timer++;

#define setState(new_state) //This custom function makes it easier to switch states. You can't use it outside of articleX_update.gml; if you want to do this from the player's update.gml or something, just copy the contents of this to the with statement.

state = new_state;
state_timer = 0;

Optional Modules

Article Count Limit

This module limits the number of articles which can be out at once. Should the player spawn more than the max amount, the oldest existing article is told to die.

//articleX_init.gml

//Limit on number of articles
var total_articles = 0;                             //This gets incremented whenever a new article is created.
var max_articles = 1;                               //The maximum number of this article that should exist at once.
var oldest = -1;                                    //Records the oldest article found's exist_timer. -1 means nothing found yet
var oldest_obj = noone;                             //Records the oldest article found's ID.

with(asset_get("obj_articleX")){ //Change articleX to article1 or etc
    if (player_id == other.player_id){
        total_articles++;
        if (oldest == -1 || exist_timer < oldest){
            oldest = exist_timer;
            oldest_obj = id;
        }
    }
}

if (total_articles > max_articles){
    oldest_obj.should_die = true;
}

State Buffering

This module adds a system for "buffering" states, in the same way that RoA buffers inputs: if you set the article's buffered_state variable to a state's number and set its buffer_timer variable to 1, then the article will accept that buffered state as soon as it is in state 0 (idle). This means it won't interrupt the article's attack prematurely, or etc.

//articleX_init.gml

buffered_state = -1;                                //The state fed to the article by the player. Set this in your character's code, and the article will set itself to the requested state as long as it's available within 20 frames of the input. -1 means no state is buffered
buffer_timer = 0;                                   //The current amount of frames remaining in the buffer window. When this reaches zero, the article will throw away the buffered state request.
max_buffer_timer = 20;                              //How many frames the article is willing to wait before it will throw out the buffered request. Set it to -1 and it will be infinite.

//articleX_update.gml

//State buffering

if (buffer_timer > 0 && (buffer_timer <= max_buffer_timer || max_buffer_timer == -1)){
    buffer_timer++;
}else{
    buffered_state = 0;
    buffer_timer = 0;
}

if (state == 0){
    //Accept buffered state
    if (buffered_state > 0){
        setState(buffered_state);
        buffered_state = 0;
        buffer_timer = 0;
    }
}

Getting Hit

This module detects a hitbox touching the article, then responds differently based on whether or not the hitbox was created by the article's owner. In the example, the article will attack when struck by its owner, or prepare to die when hit by the enemy.

//articleX_update.gml

//Get hit

var got_hit = 0;

with (asset_get("pHitBox")){
    if (place_meeting(x,y,other)){
        if (player_id == other.player_id){ //Owner hit
            got_hit = 1;
        }
        else{ //Enemy hit
            got_hit = 2;
        }
    }
}

switch(got_hit){
    case 1: //Owner hit behavior
        setState(1);
        break;
    case 2: //Enemy hit behavior
        should_die = true;
        break;
}

Plasma Field

This module makes it so that your article dies and makes the appropriate SFX/VFX when touching Clairen's no fun zone.

//articleX_update.gml

//Clairen plasma field will destroy the article

if (place_meeting(x, y, asset_get("plasma_field_obj")) && state != 2) {
    sound_play(asset_get("sfx_clairen_hit_med"));
    spawn_hit_fx(floor(x),floor(y),256)
    should_die = true; //you could replace this with "setState(2);" to make it die INSTANTLY, even if already attacking or etc
}
RAW Paste Data