(Solved) Script affecting every enemy instance

chefdez

Member
Hello everyone,

My enemy objects are no longer individually firing their ammo, instead if one of them is aware and firing, it will deplete the ammunition of every enemy instance in the room. Maybe someone can help me spot the mistake? I have been implementing "other" more often but removing it from my code doesn't seem to change the issue.

Code:
// Create event:

canShoot = true;
enemypistolReload = 75;
enemyAmmo_p = 6;
inst = instance_nearest(x, y, obj_enemy);

enum EnemyState {
Unaware,
Aware,
};

state = EnemyState.Unaware;
Enemy Aware Script
Code:
var dir = point_direction(x, y, obj_player.x, obj_player.y);
var BulletSpeed = 10;
sprite_index = spr_enemyPistol;
image_speed = 0.2;
image_angle = dir;
shootTimer = 20

if shootTimer > 0 
    shootTimer--;
    if shootTimer <= 0
    {
        if canShoot = true && global.healthPoints > 0
        {
            var bid = instance_create(x, y, obj_EnemyBullet) ;
            bid.direction = dir ;
            bid.speed = BulletSpeed ;
            bid.image_angle = dir ;
            audio_play_sound(snd_glock, 1, false);
            shootTimer = 20
            canShoot = false;
            alarm[0] = 50;
        }
        if enemyAmmo_p = 0 && canShoot = false
            if enemypistolReload > 0
            {
            enemypistolReload--;           
                if enemypistolReload <= 0
                {
                enemyAmmo_p = 6;
                enemypistolReload = 75;
                canShoot = true;
                }
            }
        }
Alarm[0]:
Code:
canShoot = true
enemyAmmo_p -= 1; // On the FIRST shot, it does NOT deplete the ammo by 1. It STAYS at 6 ! Why? Then // goes down to 5, 4, 3, 2, and on the last shot the enemy bullet is not created all while depleting ammo from // all other enemy instances.
   
if enemyAmmo_p <= 0
    canShoot = false;
 

chefdez

Member
As shown in the picture, the enemy on the top left has been firing and reloading, while the instance on the bottom right is losing ammo without being alerted.
 

Attachments

CedSharp

Member
First of all, in the script for aware, when you instanciate a bullet, that would be the best moment to remove 1 from the ammo variable, don't you think? Remove it from the alarm and place it right after you created the bullet. It will make much more sense.

Second, I don't know if this is the result of copy/pasting, but you are missing braces in your code.
The first if() condition does not have braces, so it should be indented as such:
Code:
if shootTimer > 0
   shootTimer--;
if shootTimer <= 0
{
  if(...)
}
And speaking of the second if() it doesn't have a closing brace.
Finally, I don't see what would make decreasing enemyAmmo_p decrease it from all enemies.
Did you set a global variable? How are you calling the aware script, in the step event ?

Please give me more info in order for me to provide you with a better answer :p
 

Fabseven

Member
Hello,
- I donot understand why you donot use alarm for the shoot cooldown ? It may be better to have a realistic waiting time beetween two shoots
- Why not check ammunition after firing and then set canShoot to no if = 0 ?
- I cannot see a loop going on instances of ennemies, i donot see a with() loop either.

My recommendation :
Create and obj ennemi_intelligence, create one of this obj in the room , this object will manage the AI of all ennemies.
So in step event

Code:
with(obj_ennemies)
{
   //do stuff
}
the with loop will do the jobs for all obj_ennemies.
If you have different type of AI you can still manage.

Code:
with(obj_ennemies)
{
   if(ai_type == "FOLLOW_SHOT_AT_RANGE")
   {

   }
}

with(obj_ennemies)
{
   if(ai_type == "PATROL_SHOT_AT_RANGE")
   {

   }
}


....
 

chefdez

Member
And speaking of the second if() it doesn't have a closing brace.
Finally, I don't see what would make decreasing enemyAmmo_p decrease it from all enemies.
Did you set a global variable? How are you calling the aware script, in the step event ?

Please give me more info in order for me to provide you with a better answer :p
Hello again CedSharp! I am so happy to receive your help, after implementing the script you provided last thread, I must have broken some alarms in my enemy objects.

All of this code is a few months old because this is the project I am using to learn GML so some of it is outdated or needs to be cleaned up. :) Really not sure why up until this point, the ammunition was working with the alarm but I took your advice and put it in the step event and it worked like a charm! Each enemy now has their own ammunition when they fire, however they are not reloading.

Hello,
- I donot understand why you donot use alarm for the shoot cooldown ? It may be better to have a realistic waiting time beetween two shoots
- Why not check ammunition after firing and then set canShoot to no if = 0 ?
- I cannot see a loop going on instances of ennemies, i donot see a with() loop either.
Hey! I was learning to use YellowAfterlife alarm code without using the built in alarm in Game Maker. So there are two examples of alarms here, this one and alarm[0]. I wanted more control over the timing between shots (for random_range) and practice with coding my own alarms so here it is!

Create:
Code:
shootTimer = 20;

Step:
Code:
if shootTimer > 0
   shootTimer--;
   if shootTimer <= 0
{
   // Any code here
}
I am very interested in your recommendation with a controller object, I already have one that controls the path of the enemy, maybe I will switch over the weapons / ammo system as well.

Why not check ammunition after firing and then set canShoot to no if = 0 ?

I have tried this and I'm not sure why it would not work? I removed the check from the alarm and put it in the step event instead. This is a cleaner version with the changes @CedSharp @Fabseven

Code:
if shootTimer > 0 {
    shootTimer--;
    if shootTimer <= 0 {
        if canShoot = true && global.healthPoints > 0 
        {
            var bid = instance_create(x, y, obj_EnemyBullet) ;
            enemyAmmo_p -= 1;
            bid.direction = dir ;
            bid.speed = BulletSpeed ;
            bid.image_angle = dir ;
            audio_play_sound(snd_glock, 1, false);
            alarm[0] = 20;
            shootTimer = 30;
           
           
        if enemyAmmo_p <= 0
             {canShoot = false;}
            
       
        if enemyAmmo_p <= 0 && canShoot = false {
            if enemypistolReload > 0 {
                enemypistolReload--;           
               
                if enemypistolReload <= 0 {
                    enemyAmmo_p = 6; // This code is not running 
                    enemypistolReload = 75;
                    canShoot = true;
                   }
                }
            }
        }
    }
}
This check did not work for me, the enemy continued shooting past 0 into the negatives.
Leaving it in the alarm did not work either, the enemy object will shoot to 0 and will not reload.
I feel like it may be the way I arranged the code together, maybe separating the if statements in their own brackets?
 

chefdez

Member
I simplified the code and it works now :)

Enemy Aware Script
Code:
if shootTimer > 0 {
    shootTimer--;
    if shootTimer <= 0 {
        if canShoot = true && global.healthPoints > 0 && !collision_line(x, y, obj_player.x, obj_player.y, obj_fixedwalls, false, false)
        {
            var bid = instance_create(x, y, obj_EnemyBullet) ;
            enemyAmmo_p -= 1;
            bid.direction = dir ;
            bid.speed = BulletSpeed ;
            bid.image_angle = dir ;
            audio_play_sound(snd_glock, 1, false);
            alarm[0] = 20;
            shootTimer = 30;
            }   
        }
    }
     


if enemyAmmo_p <= 0 && canShoot = false {
    if enemypistolReload > 0 {
        enemypistolReload--;}           
            if enemypistolReload <= 0 {
                enemyAmmo_p = 6;
                enemypistolReload = 75;
                canShoot = true;
                shootTimer = 30;}
                }
Alarm 0:
Code:
if enemyAmmo_p <= 0
    canShoot = false;
    else
    canShoot = true;
If anyone has any advice on cleaning code so it appears less confusing, or any general good habits to have please let me know!!!
 

samspade

Member
I simplified the code and it works now :)

Enemy Aware Script
Code:
if shootTimer > 0 {
    shootTimer--;
    if shootTimer <= 0 {
        if canShoot = true && global.healthPoints > 0 && !collision_line(x, y, obj_player.x, obj_player.y, obj_fixedwalls, false, false)
        {
            var bid = instance_create(x, y, obj_EnemyBullet) ;
            enemyAmmo_p -= 1;
            bid.direction = dir ;
            bid.speed = BulletSpeed ;
            bid.image_angle = dir ;
            audio_play_sound(snd_glock, 1, false);
            alarm[0] = 20;
            shootTimer = 30;
            }  
        }
    }
    


if enemyAmmo_p <= 0 && canShoot = false {
    if enemypistolReload > 0 {
        enemypistolReload--;}          
            if enemypistolReload <= 0 {
                enemyAmmo_p = 6;
                enemypistolReload = 75;
                canShoot = true;
                shootTimer = 30;}
                }
Alarm 0:
Code:
if enemyAmmo_p <= 0
    canShoot = false;
    else
    canShoot = true;
If anyone has any advice on cleaning code so it appears less confusing, or any general good habits to have please let me know!!!
Your code is pretty good readability wise. It appears to follow a consistent form (though you're a little inconsistent on camel versus snake case and there seems to be a typo with the bracket placement in the second if statement).

This is also a topic that people have many strong opinions about and is not specifically related to game maker so it is pretty easy to find many resources on line about various ideas and styles. YouTube will have many videos on the subject (try clean code, coding simplicity) you can look up style guides such as those found at the end of this article: https://www.freecodecamp.org/news/the-100-correct-coding-style-guide-5b594a1655f0/.

I also like the book Code Simplicity: The Fundamentals of Software.

Ultimately, as taken from one article I read:

"All style guides are fundamentally opinionated. Some decisions genuinely do make code easier to use (especially matching indenting to programming structure), but many decisions are arbitrary. The most important thing about a style guide is that it provides consistency, making code easier to write because you need to make fewer decisions."
 

chefdez

Member
I had never heard of camel vs snake case before you brought it up, that's really interesting to have a style of naming variables. I will keep that in mind from now on! A big portion of this code is Frankenstein'd together with my own experimental code as well as tutorials from all over YouTube, which may explain why I wasn't very mindful of consistently naming the variables.

Thanks for the book recommendation, someone also suggested Computer Science Distilled: Learn the Art of Solving Computational Problems. Have you read that?

One of the issues I have with books about coding is that I'm not really at all an experienced programmer but I do enjoy messing around with Game Maker. :p
 
Top