Problem with one type of enemy object attacking both player objects + other type of enemy objects

Discussion in 'Programming' started by Makkeonmies, Jul 12, 2019.

  1. Makkeonmies

    Makkeonmies Member

    Joined:
    Oct 25, 2017
    Posts:
    100
    So in my strategy game, there's player units and then there's computer player units. There is also a third party, namely wildlife enemy units, that are also computer controlled and hostile to all (both player AND computer player units). These are supposed to attack the nearest player OR computer player units. However, if there are both of the latter present in the room, the wildlife enemy object's movement/attack code causes it to go crazy. It moves so that it doesn't know where to go, moving all over the place - whereas I only want it to chase and attack the closest units, whether that's the player's or the computer player's units doesn't matter.
    It would be easy to solve with parents, but the player objects and the computer player objects can't have the same parent here. Namely because there's also a split-screen multiplayer with two players, and player 1 and player 2 units already have a common parent. So this parent can't be shared with the computer player, it only messes things up. Obviously would be easy to have the wildlife-enemies just attack a common parent with the player + computer player as children...
    So how can I make this wildlife-type enemy objects just simply attack any player-type units in sight, without going crazy if there are more than one type present?
    Currenly my code for the wildlife enemy is:

    if playerpar > 0
    {
    if distance_to_object(playerpar) < sight
    {
    if distance_to_object(playerpar) > attackdist
    {
    target=instance_nearest(x,y,playerpar)
    image_angle=point_direction(x,y,target.x,target.y)
    mp_potential_step(target.x,target.y,spd,0)
    image_speed=0.6
    }
    }
    }
    }
    if playerpar> 0
    {
    if distance_to_object(playerpar) > attackdist
    {
    speed=0
    }
    }
    if playerpar > 0
    {
    if distance_to_object(playerpar) < attackdist
    {
    if can_atk=true
    {
    audio_play_sound(choose(wolfattack,wolfattack2,wolfattack3),0,0)
    b=instance_create(x,y,obj_wolfattack)
    b.direction=image_angle
    b.image_angle=image_angle
    object_set_sprite(self,spr_wolf_attack)
    image_speed=0.6
    can_atk=false
    }
    }
    }

    Is there anything wrong there.?
    It works, but if I use the same code for the computer enemy (enemypar), and both the player's and the computer enemy's units exist in the same room with the wildlife-enemy objects, then the latter goes ape**** for some reason and doenst know which ones to chase. I just want it to react to the nearest unit, whether it's the player or the computer's ones.
     
  2. Annoyed Grunt

    Annoyed Grunt Member

    Joined:
    Jun 20, 2016
    Posts:
    110
    You can use instance_nearest to find out the closest instance of a specific object, but for you it's a little bit trickier because you have two different object types. The "manual" way to do it would be to find the nearest player and nearest enemy unit, compare their lengths, and pick the closest one, but a smarter (and easily extendible) way is to create an object to act as a parent for both player and enemy units and then to check for that object, which will in turn do all calculations for you automatically.

    EDIT:
    Next time you have an issue please use code tags! They keep the indentation of your code from within the editor and makes it much easier for people to help you. Thanks![/code]
     
    Makkeonmies likes this.
  3. RefresherTowel

    RefresherTowel Member

    Joined:
    Jul 13, 2016
    Posts:
    1,133
    I would recommend something along the lines of what annoyed grunt suggested. Compare the distances between the two objects (parents, in this case) and use the nearest one as a target:
    Code:
    var _player = instance_nearest(x,y,obj_player_parent);
    var _ai = instance_nearest(x,y,obj_ai_parent);
    if (point_distance(x,y,_player.x,_player.y) < point_distance(x,y,_ai.x,_ai.y)) {
       // Target the player
    }
    else {
       // Target the ai
    }
    There are other ways to achieve the same result, but this sounds like the simplest with your non-inheritance-able setup.
     
    Makkeonmies likes this.
  4. Makkeonmies

    Makkeonmies Member

    Joined:
    Oct 25, 2017
    Posts:
    100
    big thanks to both u guys. i shall try these out when i get back to my project
    I'll let you guys know how it turned out!
    also, code tags, got it.
     
    RefresherTowel likes this.
  5. Makkeonmies

    Makkeonmies Member

    Joined:
    Oct 25, 2017
    Posts:
    100
    you mean here to create a common parent obj for both the enemyparent and playerparent object? If so, that would be an easy solution, but I also need to apply this code above to not only the wildlife-enemy units, but also all the players' units and CPU enemy units. So basically:
    -wildlife enemies would attack all players and computer enemies
    -players' units would attack wildlife enemies, computer enemies, and the other player's units
    -computer units would attack wildlife enemies, and all the players' units

    There's quite many different parent-child-relations going on here, so it can easily get confusing... it's just that there are basically 4 parent groups (Player 1, Player 2, Computer Player, and the wildlife enemy) and i want each group of units to be able to attack all the other groups' units, when they get close.
    Hope i understood your idea correct. Yeah the solution must be simpler than I imagine, and probably requires less code...
     
  6. Annoyed Grunt

    Annoyed Grunt Member

    Joined:
    Jun 20, 2016
    Posts:
    110
    Alright, so you will need to simply give each object a list of targetable objects (for wildlife it would be the unit objects for player 1, player 2, and computer player for example) and then have each instance find the closest instance that is one of those types of objects as described previously. Once you have the closest instance you don't care exactly what type it is, as you know it's an enemy type, and you can just execute your code as usual.
     
    Makkeonmies likes this.
  7. Makkeonmies

    Makkeonmies Member

    Joined:
    Oct 25, 2017
    Posts:
    100
    Thank you!!
    Will see how this works out!
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice