Author Topic: Simple Character That Attacks baddies  (Read 2123 times)

0 Members and 1 Guest are viewing this topic.

VGames

  • PD3 Beta Testers
  • Hero Member
  • *
  • Posts: 754
  • Karma: +17/-69
    • View Profile
Simple Character That Attacks baddies
« on: June 08, 2015, 08:52:06 PM »
Could somebody please help me write some simple code for a character script file that makes him stand in one spot and shoot monsters that come along. I've tried so hard to modify scripts that belong to characters that do just this but they never attack. I'm not as good as I thought going into this idea. Please help if you can. I got the def stuff figured out but AI is so hard for me.
Get the latest on Perfected Doom 3 here - http://www.moddb.com/mods/perfected-doom-3-version-500

BielBdeLuna

  • Full Member
  • ***
  • Posts: 242
  • Karma: +8/-20
  • Doom Newbie
    • View Profile
    • my Github repositories
Re: Simple Character That Attacks baddies
« Reply #1 on: June 08, 2015, 10:14:22 PM »
you could setup a loop that kept shooting rays from the center to forward inside a triangle, and if one of those rays get a idAI or idPlayer then get it as the target, once you have a target, you need another loop for the shooting mechanic

those two loops could coexist at the same time ,for which you would need the use of threading or you could either have one or the other, in the shooting emchanic then you could develop a way to check if the target is visible to the turret/guy and see if you need to find him again or keep shooting.

if it moves then you need somethign else much more complicated

the rays in d3 (or lines) have a start position and an end position this end position doesn't mean the ray will reach it,only that it will ext the start position and that it will continue towards the end position unless it hits a wall or an entity, since you get a reference of that entity, you can check out it's spawnargs, and in that case you can check it's "spawnclass" spawnarg so you can get what kind of entity it is.

now idtech4 can't make lists in scripting,so you might need to check every one of the rays you casted one after the other inside a loop

you know the origin of the rays but how do you know the end positions? the end positions should be really far away (at least as far as the longest distance the turret/character could see) but since you need to cover a cone of view (or in a simplified version) a triangle of view (in a case of a flat terrain) you could settle on a number of rays (let's say 8 rays) and divide the angle of view by the ammount of rays you want to use (don't get too mad with this number) then start from one side of the angle and keep putting the end position at increments

with this method you could get an entity and store it until you finished all the rays checks and be sure this is the entity you want, and then target it if you need to target it.

motorsep

  • Hero Member
  • *****
  • Posts: 967
  • Karma: +74/-128
  • Artist
    • View Profile
    • Kot in Action Creative Artel
Re: Simple Character That Attacks baddies
« Reply #2 on: June 08, 2015, 11:00:27 PM »
You gotta be kidding me, BielBdeLuna  :o

Look into doom_events.script - it's full of AI higher level script functions where you can find enemy, face it and shoot it. No need to do any tracing/shooting rays!

VGames

  • PD3 Beta Testers
  • Hero Member
  • *
  • Posts: 754
  • Karma: +17/-69
    • View Profile
Re: Simple Character That Attacks baddies
« Reply #3 on: June 08, 2015, 11:17:00 PM »
Ok I'm glad u said that motor I was starting to freak out. Could u please elaborate on what u said a little. I'm really not good at starting from scratch on character AI. I can edit the crap out of stuff that's there but I'm at a loss with freshly made stuff.
Get the latest on Perfected Doom 3 here - http://www.moddb.com/mods/perfected-doom-3-version-500

solarsplace

  • Jr. Member
  • **
  • Posts: 63
  • Karma: +8/-0
  • Mainly a programmer...
    • View Profile
Re: Simple Character That Attacks baddies
« Reply #4 on: June 09, 2015, 04:09:56 AM »
Hi

An idea to potentially save you lots of time could be to use Ivan_the_B's Smart AI mod: http://planetdoom.gamespy.com/View993a.html?view=POTD.Detail&id=616

The Smart AI mod lets you have one or more friendly AI squad mates to fight along side you. All the work you need is already done. They have follow and wait modes and their own set of special path entities to let you configure special behaviors for them.

Trouble is, I can't find a download for it online now, and I don't have the original source, only a highly modified version incorporated into the Arx code that would not work for you.

Perhaps you could PM Ivan and see if he could re-up or send you the files? - http://idtechforums.fuzzylogicinc.com/index.php?action=profile;u=91

Cheers

The Happy Friar

  • Happy Happy Joy Joy
  • Administrator
  • Hero Member
  • *****
  • Posts: 858
  • Karma: +42/-4
  • Semi-Newbie.
    • View Profile
    • EarthQuake
Re: Simple Character That Attacks baddies
« Reply #5 on: June 09, 2015, 08:13:40 AM »
The turret does this currently.  I'd say just use that & replace the model/animations.

VGames

  • PD3 Beta Testers
  • Hero Member
  • *
  • Posts: 754
  • Karma: +17/-69
    • View Profile
Re: Simple Character That Attacks baddies
« Reply #6 on: June 09, 2015, 12:16:08 PM »
Which turret? Monster_turret?
Get the latest on Perfected Doom 3 here - http://www.moddb.com/mods/perfected-doom-3-version-500

oneofthe8devilz

  • Sr. Member
  • ****
  • Posts: 371
  • Karma: +93/-84
  • Doom Newbie
    • View Profile
    • Scared Pixel Studios
Re: Simple Character That Attacks baddies
« Reply #7 on: June 09, 2015, 01:28:19 PM »
I got six little friends and they all run faster than you ;)


Check out our mods at
moddb or the SPS Homepage

motorsep

  • Hero Member
  • *****
  • Posts: 967
  • Karma: +74/-128
  • Artist
    • View Profile
    • Kot in Action Creative Artel
Re: Simple Character That Attacks baddies
« Reply #8 on: June 09, 2015, 01:38:41 PM »

Is that a stock Doom 3 turret or a modified one ?

VGames

  • PD3 Beta Testers
  • Hero Member
  • *
  • Posts: 754
  • Karma: +17/-69
    • View Profile
Re: Simple Character That Attacks baddies
« Reply #9 on: June 09, 2015, 06:58:29 PM »
Monster_turret does nothing. I set him to be on my team and he just sits there. Doesn't react to baddies.
Get the latest on Perfected Doom 3 here - http://www.moddb.com/mods/perfected-doom-3-version-500

The Happy Friar

  • Happy Happy Joy Joy
  • Administrator
  • Hero Member
  • *****
  • Posts: 858
  • Karma: +42/-4
  • Semi-Newbie.
    • View Profile
    • EarthQuake
Re: Simple Character That Attacks baddies
« Reply #10 on: June 09, 2015, 09:54:17 PM »
monster_turret, yes.  In my Last Stand mod I used him to attack monsters.  Here's the def & script.  I'm not 100% what I changed (this was years ago) but he does attack only monsters (download here: http://www.moddb.com/mods/the-happy-friars-last-stand/downloads/the-happy-friars-last-stand-v12-beta-2)
Code: [Select]
/***********************************************************************

    monster_turret.def

***********************************************************************/

export fred {
    options -prefix TURRET_ -keep flash barrel-sourcedir models/mapobjects/turrets/cycles -destdir models/md5/items/turret1
    mesh    idle.mb -dest turret
    anim    idle.mb
}

entityDef monster_turret {
    "inherit"                        "monster_default"
    "scriptobject"                    "monster_turret"
    "model"                            "monster_turret"
    "mins"                            "-12 -12 -24"
    "maxs"                            "12 12 0"
    "team"                            "1"
    "rank"                            "0"
    "health"                        "100"
    "turn_rate"                        "180"        //was blank
    "bleed"                            "0"
    "on_activate"                    ""
    "fov"                            "1"        //was 360
    "aas"                            ""

    "def_projectile"                "projectile_bullet_turret"
    "projectile_spread"                "1"        //was 0
    "num_projectiles"                "1"
    "attack_cone"                    "1"        //was 360
    "attack_accuracy"                "1"
    "smoke_weapon"                    "cgsmoke.smoke"

    "head_focus_rate"                "0.15"

    "bone_focus"                    "barrel"
    "bone_leftEye"                    ""
    "bone_rightEye"                    ""   
   
    "look_min"                        "-180 -180 -180"        //was -12 -180 0
    "look_max"                        "180 180 180"        //was 90 180 0
    "look_joint aim"                "1 1 0"        //was 1 1 0

    "mtr_flashShader"                "muzzleflash"
    "flashTime"                        "0.15"
    "flashColor"                    "1 0.8 0.4"
    "flashRadius"                    "120"

    "snd_wakeup"                    "char_sentry_active"    //TEMP
    "snd_shutdown"                    "char_sentry_destroyed"    //TEMP
    "snd_windup"                    "monster_zombie_commando_windup"
    "snd_winddown"                    "monster_zombie_commando_winddown"
    //"snd_fire"                    "player_chaingun_fire"
    "snd_fire"                        "monster_turret_fire"
}

entityDef monster_turret_light {
    "inherit"                        "monster_turret"
   
    "light"                            "1"
    "light_distance"                "640"
    "mtr_light"                        "lights/flashlight5"
    "skin_light_off"                ""
    "skin_light_on"                    ""
}

model monster_turret {
    mesh                        models/md5/items/turret1/turret.md5mesh
    anim idle                     models/md5/items/turret1/idle.md5anim
}

entityDef damage_bullet_turret {
    "damage"                        "8"        //was 6
    "kickDir"                        "1 0 0"

    "mtr_blob"                        "genericDamage"
    "blob_time"                        "300"
    "blob_size"                        "400"
    "blob_offset_x"                    "400"

    "knockback"                        "1"
   
    "smoke_wound_flesh"                "bloodwound.smoke"
    "mtr_wound_flesh"                "textures/decals/hurt02"
    "mtr_splat_flesh"                "textures/decals/dsplat2"
    "mtr_splat_flesh2"                "textures/decals/dsplat5"
    "mtr_splat_flesh3"                "textures/decals/dsplat7"
    "mtr_splat_flesh4"                "textures/decals/dsplat11"
    "snd_flesh"                        "bullet_impact_flesh"

    "kick_time"                        "400"
    "kick_amplitude"                "1"

    "dv_time"                        "100"
}

entityDef projectile_bullet_turret {
    "spawnclass"                    "idProjectile"
    "mins"                            "-1 -1 -1"
    "maxs"                            "1 1 1"
    "cone"                            "3"
    "scale"                            "0.1"
    "noshadows"                        "1"
//    "tracers"                        "1"
//    "model_tracer"                    "models/particles/tracer/tracer.lwo"
    "snd_tracer"                    "bullet_flight"
    "snd_ricochet"                    "bullet_ricochet"
    "snd_impact"                    "bullet_impact_metal"

    "def_damage"                    "damage_bullet_turret"

    "launchFromBarrel"                "1"
    "health"                        "0"
    "velocity"                        "5000 0 0"    // was 3500 slowed down for tracer effect
    "angular_velocity"                "0 0 0"
    "thrust"                        "0"
    "thrust_start"                    "0"
    "thrust_end"                    "0"
    "linear_friction"                "0"
    "angular_friction"                "0"
    "contact_friction"                "0"
    "bounce"                        "0.6"
    "mass"                            "2"
    "gravity"                        "0"
    "fuse"                            "4"

    "detonate_on_fuse"                "0"
    "detonate_on_death"                "0"
    "detonate_on_world"                "1"
    "detonate_on_actor"                "1"

    "impact_damage_effect"            "1"
    "impact_gib"                    "1"

    "mtr_detonate"                    "textures/decals/bulleth02"
    "decal_size"                    "10"

    "smoke_fly"                        ""
    "smoke_detonate"                "smokeandspark.smoke"
    "smoke_bounce"                    ""    //particles/bullet_sparks.particle"
    "smoke_fuse"                    ""
                                   
    "mtr_light_shader"                ""
    "light_color"                    "0 0 0"
    "light_radius"                    "0"
    "light_offset"                    "0 0 0"

    "mtr_explode_light_shader"        ""
    "explode_light_color"            "0 0 0"
    "explode_light_radius"            "0"
    "explode_light_fadetime"        "0"
}
Code: [Select]
/***********************************************************************

ai_monster_turret.script

monster_turret

***********************************************************************/

#define TURRET_FIRE_RATE        0.01
#define TURRET_MIN_ATTACK_TIME  1.0        //was 1.5
#define TURRET_SHUTDOWN_TIME    4

object monster_turret : monster_base {
    boolean        fire;
    boolean        attack_monsters;
    entity        light;
    boolean        light_is_on;
    float        attackTime;

    //
    // States
    //
    void        state_Begin();
    void        state_Idle();
    void        state_Combat();
    void        state_Killed();
    boolean        checkForEnemy( float use_fov );

    //
    // actions
    //
    void        combat_attack();

    void        init();
    void        destory();

    void        spawn_light();
    void        light_off();
    void        light_on();
   
    // anim states
    void        Torso_Death();
    void        Torso_Idle();
    void        Torso_Attack();
};

/***********************************************************************

    Torso animation control

***********************************************************************/

void monster_turret::Torso_Death() {
    finishAction( "dead" );

    // never exit
    waitUntil( 0 );
}

void monster_turret::Torso_Idle() {
    playCycle( ANIMCHANNEL_TORSO, "idle" );
   
    eachFrame {
        if ( fire ) {
            animState( ANIMCHANNEL_TORSO, "Torso_Attack", 0 );
        }
    }
}

void monster_turret::Torso_Attack() {
    float soundLen;

    playCycle( ANIMCHANNEL_TORSO, "idle" );

    soundLen = startSound( "snd_windup", SND_CHANNEL_BODY, false );
    soundLen += sys.getTime();
    while( sys.getTime() < soundLen ) {
        waitFrame();
    }

    attackTime = sys.getTime() + TURRET_MIN_ATTACK_TIME;
    while( fire || ( sys.getTime() < attackTime ) ) {
        lookAtEnemy( 1 );                //added this line
        if ( sys.influenceActive() ) {
            break;
        }
        startSound( "snd_fire", SND_CHANNEL_WEAPON, false );
        attackMissile( "barrel" );
        sys.wait( TURRET_FIRE_RATE );
    }
   
    soundLen = startSound( "snd_winddown", SND_CHANNEL_BODY2, false );
    soundLen += sys.getTime();
    while( sys.getTime() < soundLen ) {
        lookAtEnemy( 1 );                //added this line
        waitFrame();
    }

    finishAction( "attack" );
    animState( ANIMCHANNEL_TORSO, "Torso_Idle", 0 );
}

/***********************************************************************

    AI

***********************************************************************/

/*
=====================
monster_turret::init
=====================
*/
void monster_turret::init() {
    float team;

    // don't take damage
    //ignoreDamage();                commented out

    // can't move, so only fire on sight
    ambush = true;

    team = getFloatKey( "team" );
    if ( team != 1  ) {
        attack_monsters = true;
    }

    if ( getIntKey( "light" ) ) {
        spawn_light();
    }

    animState( ANIMCHANNEL_TORSO, "Torso_Idle", 0 );
    setState( "state_Begin" );
}

/*
=====================
monster_turret::destory
=====================
*/
void monster_turret::destory() {
    light.remove();
}

/*
=====================
monster_turret::spawn_light
=====================
*/
void monster_turret::spawn_light() {
    string texture;
    float distance;

    distance = getFloatKey( "light_distance" );
    if ( !distance ) {
        distance = 640;
    }
   
    // spot light
    sys.setSpawnArg( "light_target", "1 0 0" );
    sys.setSpawnArg( "light_up", "0 0 .5" );
    sys.setSpawnArg( "light_right", "0 -.5 0" );   
    sys.setSpawnArg( "light_end", distance + " 0 0" );

    texture = getKey( "mtr_light" );
    sys.setSpawnArg( "texture", texture );

    sys.setSpawnArg( "name", getName() + "_light" );
    light = sys.spawn( "light" );
    light.setAngles( getAngles() );
    //light.bindToJoint( self, "light", true );
    light.bindToJoint( self, "flash", true );
    light.setOrigin( '0 0 0' );

    light_off();
}

/*
=====================
monster_turret::light_off
=====================
*/
void monster_turret::light_off() {
    string skin;

    if ( light ) {
        light.Off();
        skin = getKey( "skin_light_off" );
        setSkin( skin );
        light_is_on = false;
    }
}
   
/*
=====================
monster_turret::light_on
=====================
*/
void monster_turret::light_on() {
    string skin;

    if ( light ) {
        light.On();
        skin = getKey( "skin_light_on" );
        setSkin( skin );
        light_is_on = true;
    }
}

/*
=====================
monster_turret::state_Begin
=====================
*/
void monster_turret::state_Begin() {
    setMoveType( MOVETYPE_STATIC );

    if ( getIntKey( "trigger" ) ) {
        setState( "state_Disabled" );
    } else {
        wait_for_enemy();
        setState( "state_Combat" );
    }
}

/*
=====================
monster_turret::state_Idle
=====================
*/
void monster_turret::state_Idle() {
    startSound( "snd_shutdown", SND_CHANNEL_VOICE, false );
    light_off();
    wait_for_enemy();
    setState( "state_Combat" );
}

/*
=====================
monster_turret::state_Disabled
=====================
*/
void monster_turret::state_Disabled() {
    entity enemy;

    startSound( "snd_shutdown", SND_CHANNEL_VOICE, false );

    lookAtEnemy( 0 );

    // wait till we stop firing and bullets are out of the air
    attackTime = 0;
    fire = false;
    while( inAnimState( ANIMCHANNEL_TORSO, "Torso_Attack" ) ) {
        waitFrame();
    }
    sys.wait( 0.2 );

    // tell all enemies to forget about us
    enemy = nextEnemy( $null_entity );
    while( !( !enemy ) ) {
        sys.print( sys.getTime() + ": clear enemy: " + enemy.getName() + "\n" );
        enemy.clearEnemy();
        enemy = nextEnemy( $null_entity );
    }

    // clear our enemy
    clearEnemy();

    // wait for trigger
    AI_ACTIVATED = false;
    while( !AI_ACTIVATED ) {
        waitFrame();
    }
    AI_ACTIVATED = false;

    setState( "state_Combat" );
}

/*
=====================
monster_turret::state_Killed
=====================
*/
void monster_turret::state_Killed() {
    stopMove();

    light_off();

    animState( ANIMCHANNEL_TORSO, "Torso_Death", 0 );
    waitAction( "dead" );
    stopThinking();
}

/*
=====================
monster_turret::checkForEnemy
=====================
*/
boolean    monster_turret::checkForEnemy( float use_fov ) {
    entity enemy;

    enemy = findEnemy( false );
    if ( !enemy ) {
        if ( !attack_monsters ) {
            return false;
        }
       
        enemy = findEnemyAI( false );
        if ( !enemy ) {
            return false;
        }
    }

    setEnemy( enemy );
    return true;
}

/***********************************************************************

    Combat

***********************************************************************/

/*
=====================
monster_turret::state_Combat
=====================
*/
void monster_turret::state_Combat() {
    float shutdownTime;

    startSound( "snd_wakeup", SND_CHANNEL_VOICE, false );
   
    light_on();
    shutdownTime = sys.getTime() + TURRET_SHUTDOWN_TIME;
    eachFrame {
        lookAtEnemy( 1 );
        if ( AI_ENEMY_DEAD ) {
            enemy_dead();
            continue;
        }

        if ( AI_ACTIVATED ) {
            setState( "state_Disabled" );
            break;
        }

        if ( AI_ENEMY_VISIBLE ) {
            if ( canHitEnemyFromJoint( "barrel" ) ) {
                combat_attack();
            } else {
                checkForEnemy( false );
            }
            shutdownTime = sys.getTime() + TURRET_SHUTDOWN_TIME;
        } else if ( !checkForEnemy( false ) ) {
            if ( shutdownTime < sys.getTime() ) {
                lookAtEnemy( 0 );
                clearEnemy();
                setState( "state_Idle" );
            }
        }
    }
}

/*
=====================
monster_turret::combat_attack
=====================
*/
void monster_turret::combat_attack() {
    faceEnemy();

    fire = true;
    while( AI_ENEMY_VISIBLE && canHitEnemyFromJoint( "barrel" ) ) {
        lookAtEnemy( 1 );
        waitFrame();
        if ( sys.influenceActive() ) {
            break;
        }
        if ( AI_ACTIVATED ) {
            setState( "state_Disabled" );
            break;
        }
    }
    fire = false;
}

VGames

  • PD3 Beta Testers
  • Hero Member
  • *
  • Posts: 754
  • Karma: +17/-69
    • View Profile
Re: Simple Character That Attacks baddies
« Reply #11 on: June 10, 2015, 07:50:09 PM »
He shoots the crap out of me but not the monsters. I set his team value to 0 and he does absolutely nothing except follow me until I spawn a monster. Then he just sits there. Am I missing something?
Get the latest on Perfected Doom 3 here - http://www.moddb.com/mods/perfected-doom-3-version-500

The Happy Friar

  • Happy Happy Joy Joy
  • Administrator
  • Hero Member
  • *****
  • Posts: 858
  • Karma: +42/-4
  • Semi-Newbie.
    • View Profile
    • EarthQuake
Re: Simple Character That Attacks baddies
« Reply #12 on: June 10, 2015, 09:36:26 PM »
I checked the map I used them in.  I set the player's team to "0" & their team to "0".  And I see what I did.  I bound a large trigger for the range of the guns to the ship that the guns were bound to.  I set the guns to be triggered.  When a monster would activate the trigger the guns would fire on it.  That was my cheap solution for weapon range.  :)

VGames

  • PD3 Beta Testers
  • Hero Member
  • *
  • Posts: 754
  • Karma: +17/-69
    • View Profile
Re: Simple Character That Attacks baddies
« Reply #13 on: June 10, 2015, 10:44:18 PM »
So what would I do if I'm not editing maps?
Get the latest on Perfected Doom 3 here - http://www.moddb.com/mods/perfected-doom-3-version-500

The Happy Friar

  • Happy Happy Joy Joy
  • Administrator
  • Hero Member
  • *****
  • Posts: 858
  • Karma: +42/-4
  • Semi-Newbie.
    • View Profile
    • EarthQuake
Re: Simple Character That Attacks baddies
« Reply #14 on: June 10, 2015, 11:23:19 PM »
I'd say use the walking turret.  He autofires against monsters.