Cxwh

Veteran
Messages
64
Reaction score
45
Points
793
I recently started remaking all gobblegums from bo3 (not the crazy ones though) and now I got them all to work except for alchemical antithesis, impatient and pop shocks. Some of these are could be wrecks, but I tried to explain what i was thinking

These just make my head hurt... (except for impatient)

-------------------------------------------------------------
Some functions I'm using throughout this
Code:
function waittill_notify(event, event1)
{
    self waittill(event);
    self notify(event1);
}

function waittill_call(event, func, arg1, arg2)
{
    self waittill(event)
    if(areDefined(arg1, arg2))
        self thread [[ func ]](arg1, arg2);

    else if(isDefined(arg1) && !isDefined(arg2))
        self thread [[ func ]](arg1);

    else
        self thread [[ func ]]();
}
function wait_notify(time, event)
{
    self wait(time);
    self notify(event);
}
function waittill_any_notify(notify_event, event1, event2, event3)
{
    if(isDefined(event1) && isDefined(event2) && isDefined(event3))
        self util::waittill_any(event1, event2, event3);

    else if(isDefined(event1) && isDefined(event2))
        self util::waittill_any(event1, event2);

    else
        self waittill(event1);
    self notify(notify_event);
}

function areDefined(arg1, arg2)
{
    return isDefined(arg1) && isDefined(arg2);
}

-------------------------------------------------------------

Pop Shocks

First one:
Code:
function gum_pop_shocks()
{
    self endon("death");
    self endon("bgb_done");
    self endon("killed_5");
    self endon("player_downed");

    //from electric cherry
    n_clip_current = 1;
    n_clip_max = 10;
    n_fraction = n_clip_current/n_clip_max;

    //just a random numbers idk the real stats obv
    min_damage = 1000;
    max_damage = 7000;

    //electric cherry melee radius - ik the radius is high but idk
    min_range = 32;
    max_range = 128;

    //random
    //<player> thread [[level.callbackPlayerDamage]]( <entityThatCausesDamage>, <attacker>, <damageAmount>, <flags>, <meansOfDeath>, <weapon>, <pointTheDamageIsFrom>, <directionOfTheDamage>, <locationOfTheHit>, <timeOffset> );

    self.pop_shock_kills = 0;
    self thread watch_kills();

    for(;;)
    {
        self waittill(/*WE MELEED*/); //idk the name of the event + we can't do self meleebuttonpressed bc you would be able to spam it even when youre not meleeing
 
        perk_radius = math::linear_map(n_fraction, 1.0, 0.0, min_range, max_range);
        perk_dmg = math::linear_map(n_fraction, 1.0, 0.0, min_damage, max_damage);
    
        //electric cherry attack
        if(isDefined(self))
        {
            n_zombie_limit = 2; //amount of zombies we can kill with one melee attack

            self thread zm_perk_electric_cherry::electric_cherry_reload_fx(n_fraction);
            self PlaySound( "zmb_cherry_explode" );
        
            a_zombies = zombie_utility::get_round_enemy_array();
            a_zombies = util::get_array_of_closest(self.origin, a_zombies, undefined, undefined, perk_radius);
            n_zombies_hit = 0;
        
            for(i = 0; i < a_zombies.size; i++)
            {
                if(isAlive(self) && isAlive(a_zombies[i]))
                {
                    if(isDefined(n_zombie_limit)) //if the limit of zombies is undefined, keep going and hit all zombies we can
                    {
                        if(n_zombies_hit < n_zombie_limit) //if the we're under the limit, increment the count of zombies
                            n_zombies_hit++;
                        else
                            break; //if we're at the limit of zombies, don't kill any more zombies
                    }
                    if(a_zombies[i].health <= perk_dmg) //if they died
                    {
                        a_zombies[i] thread zm_perk_electric_cherry::electric_cherry_death_fx();
                    
                        self.pop_shock_kills++;
                        self zm_score::add_to_player_score(40);
                    }
                    else //if they survived
                    {
                        if(!isDefined(a_zombies[ i ].is_brutus)) //if they're not 'a' brutus don't stun them
                            a_zombies[i] thread zm_perk_electric_cherry::electric_cherry_stun();
                        a_zombies[i] thread zm_perk_electric_cherry::electric_cherry_shock_fx();
                    }
                    wait 0.1;
                    if(isDefined(a_zombies[i]) && isAlive(a_zombies[i]))
                        a_zombies[i] doDamage(perk_dmg, self.origin, self, self, "none");
                }
            }
        }
    }
}

function watch_kills()
{
    self endon("bgb_done");
    self endon("killed_5");

    while(self.pop_shock_kills >= 5)
        self notify("killed_5");
}

Second one:
Code:
function gum_pop_shocks()
{
    self endon("death");
    self endon("bgb_done");
    self endon("killed_5");
    self endon("player_downed");
 
    //from electric cherry
    n_clip_current = 1;
    n_clip_max = 10;
    n_fraction = n_clip_current/n_clip_max;

    //electric cherry melee radius - ik the radius is high but idk
    min_range = 32;
    max_range = 128;
    radius = math::linear_map(n_fraction, 1.0, 0.0, min_range, max_range);

    self.pop_shock_kills = 0;
    self.done_meleeing = true;

    self thread trackMeleeAttack();
    self thread watch_kills();

    while(self meleeButtonPressed())
    {
        wait 0.05; //no idea how long it takes to start the melee anim
        if(self isMeleeing() && self.done_meleeing)
        {
            self.done_meleeing = false;
            self thread damageZombies(radius);

            //self SetElectrified(1.0);
//play fx on self for now
            playFxOnTag( level._effect[ "electric_cherry_explode" ], self, "j_head" );
            playFxOnTag( level._effect[ "electric_cherry_explode" ], self, "J_Spine1" );
            playFxOnTag( level._effect[ "electric_cherry_explode" ], self, "J_Spine4" );
            playFxOnTag( level._effect[ "electric_cherry_explode" ], self, "pelvis" );
            self playSound( "zmb_cherry_explode" );
        }
        wait 0.05;
    }
}

function trackMeleeAttack()
{
    self endon("death");
    self endon("bgb_done");
    self endon("killed_5");
    self endon("player_downed");

    while(self isMeleeing() == false)
    {
        self.done_meleeing = true;
        wait 0.05;
    }
}

function damageZombies(radius)
{
    if(isDefined(self))
    {
        a_zombies = zombie_utility::get_round_enemy_array();
        a_zombies = util::get_array_of_closest(self.origin, a_zombies, undefined, undefined, radius);

        n_zombies_hit = 0;
        n_zombie_limit = 1; //amount of zombies we can kill with one melee attack
    
        for(i = 0; i < a_zombies.size; i++)
        {
            if(isAlive(self) && isAlive(a_zombies[i]))
            {
                if(isDefined(n_zombie_limit)) //if the limit of zombies is undefined, keep going and hit all zombies we can
                {
                    if(n_zombies_hit < n_zombie_limit) //if the we're under the limit, increment the count of zombies
                        n_zombies_hit++;
                    else
                        break; //if we're at the limit of zombies, don't kill any more zombies
                }
                if(a_zombies[i].health <= perk_dmg) //if they died
                {
                    a_zombies[i] thread zm_perk_electric_cherry::electric_cherry_death_fx();
                
                    self.pop_shock_kills++;
                    self zm_score::add_to_player_score(40); //points
                }
                else //if they survived
                {
                    if(!isDefined(a_zombies[ i ].is_brutus)) //if they're 'a' brutus don't stun them
                        a_zombies[i] thread zm_perk_electric_cherry::electric_cherry_stun();
                    a_zombies[i] thread zm_perk_electric_cherry::electric_cherry_shock_fx();
                }
                wait 0.1;
                if(isDefined(a_zombies[i]) && isAlive(a_zombies[i]))
                    a_zombies[i] doDamage(7000, self.origin, self, self, "none"); //1045 = zombie health at round 10 and since we only have 5 hits we do 7k
            }
        }
    }
}

function watch_kills()
{
    self endon("bgb_done");
    self endon("killed_5");

    while(self.pop_shock_kills >= 5)
        self notify("killed_5");
}

-------------------------------------------------------------

impatient
Code:
function gum_impatient()
{
    self endon("bgb_done");

    self waittill("death");
    zombies = &GetAIArray("axis"); //if this is false I'll just call it in the loop
    for(;;)
    {
        if(zombies.size <= 1)
        {
            //how do i spawn back in
            break;
        }
        wait 1;
    }
}

-------------------------------------------------------------

Alchemical antithesis
Code:
function gum_alchemical_antithesis()
{
    self endon("gum_done");
    self endon("alchem_done");

    self thread waittill_notify("gum_done", "death", "player_downed"); //idfk what i was thinking
    self thread wait_notify(30, "alchem_done");

    //self thread disableScoring();
    oldScore = self.score;
    max_clip = getWeaponAmmoClip();
    max_stock = getWeaponAmmoStock();

    curWeapon = self getCurrentWeapon();
    curWeapon_alt = getWeapon(curWeapon);

    //could probably waittill weapon fired too but this wouldnt include melee & grenade kills
    for(;;)
    {
        if(self secondaryOffhandButtonPressed())
        {
            wait 0.3; //just to see if he double tapped
            if(curWeapon != self getCurrentWeapon())
            {
                curWeapon = self getCurrentWeapon();
                curWeapon_alt = getWeapon(curWeapon);

                max_clip = getWeaponAmmoClip(curWeapon_alt);
                max_stock = getWeaponAmmoStock(curWeapon_alt);
            }
        }

        if(oldScore != self.score)
        {
            dif = difference(oldScore, self.score);
            amount = int(dif/10);

            curClip = self getAmmoCount(curWeapon_alt);
            curStock = getTotalAmmo(self getLocalClientNumber(), curWeapon_alt);

            if(curStock - max_clip <= 0)
                curStock = max_clip;

            if(curStock - max_clip < max_stock)
                self setWeaponAmmoStock(curWeapon_alt, amount);
            oldScore = self.score;
        }
        wait 0.05;
    }

}

function disableScoring()
{
    self endon("gum_done");

    oldScore = self.score;
    oldScore_alt = self.pers["score"];
    while(self.score != oldScore)
    {
        self.score = oldScore;
        self.pers["score"] = oldScore_alt;
        wait 0.05;
    }
}

function difference(num1, num2)
{
    if(isDefined(num1) && isDefined(num2))
    {
        dif = num1 - num2;
        if(dif < 0)
            dif *= -1;
        return dif;
    }
    return 0;
}
 
Last edited:

CabCon

Head Administrator
Staff member
Head Staff Team
Messages
5,093
Reaction score
2,881
Points
1,103
I recently started remaking all gobblegums from bo3 (not the crazy ones though) and now I got them all to work except for alchemical antithesis, impatient and pop shocks. Some of these are could be wrecks, but I tried to explain what i was thinking

These just make my head hurt... (except for impatient)

-------------------------------------------------------------
Some functions I'm using throughout this
Code:
function waittill_notify(event, event1)
{
    self waittill(event);
    self notify(event1);
}

function waittill_call(event, func, arg1, arg2)
{
    self waittill(event)
    if(areDefined(arg1, arg2))
        self thread [[ func ]](arg1, arg2);

    else if(isDefined(arg1) && !isDefined(arg2))
        self thread [[ func ]](arg1);

    else
        self thread [[ func ]]();
}
function wait_notify(time, event)
{
    self wait(time);
    self notify(event);
}
function waittill_any_notify(notify_event, event1, event2, event3)
{
    if(isDefined(event1) && isDefined(event2) && isDefined(event3))
        self util::waittill_any(event1, event2, event3);

    else if(isDefined(event1) && isDefined(event2))
        self util::waittill_any(event1, event2);

    else
        self waittill(event1);
    self notify(notify_event);
}

function areDefined(arg1, arg2)
{
    return isDefined(arg1) && isDefined(arg2);
}

-------------------------------------------------------------

Pop Shocks

First one:
Code:
function gum_pop_shocks()
{
    self endon("death");
    self endon("bgb_done");
    self endon("killed_5");
    self endon("player_downed");

    //from electric cherry
    n_clip_current = 1;
    n_clip_max = 10;
    n_fraction = n_clip_current/n_clip_max;

    //just a random numbers idk the real stats obv
    min_damage = 1000;
    max_damage = 7000;

    //electric cherry melee radius - ik the radius is high but idk
    min_range = 32;
    max_range = 128;

    //random
    //<player> thread [[level.callbackPlayerDamage]]( <entityThatCausesDamage>, <attacker>, <damageAmount>, <flags>, <meansOfDeath>, <weapon>, <pointTheDamageIsFrom>, <directionOfTheDamage>, <locationOfTheHit>, <timeOffset> );

    self.pop_shock_kills = 0;
    self thread watch_kills();

    for(;;)
    {
        self waittill(/*WE MELEED*/); //idk the name of the event + we can't do self meleebuttonpressed bc you would be able to spam it even when youre not meleeing
 
        perk_radius = math::linear_map(n_fraction, 1.0, 0.0, min_range, max_range);
        perk_dmg = math::linear_map(n_fraction, 1.0, 0.0, min_damage, max_damage);
   
        //electric cherry attack
        if(isDefined(self))
        {
            n_zombie_limit = 2; //amount of zombies we can kill with one melee attack

            self thread zm_perk_electric_cherry::electric_cherry_reload_fx(n_fraction);
            self PlaySound( "zmb_cherry_explode" );
       
            a_zombies = zombie_utility::get_round_enemy_array();
            a_zombies = util::get_array_of_closest(self.origin, a_zombies, undefined, undefined, perk_radius);
            n_zombies_hit = 0;
       
            for(i = 0; i < a_zombies.size; i++)
            {
                if(isAlive(self) && isAlive(a_zombies[i]))
                {
                    if(isDefined(n_zombie_limit)) //if the limit of zombies is undefined, keep going and hit all zombies we can
                    {
                        if(n_zombies_hit < n_zombie_limit) //if the we're under the limit, increment the count of zombies
                            n_zombies_hit++;
                        else
                            break; //if we're at the limit of zombies, don't kill any more zombies
                    }
                    if(a_zombies[i].health <= perk_dmg) //if they died
                    {
                        a_zombies[i] thread zm_perk_electric_cherry::electric_cherry_death_fx();
                   
                        self.pop_shock_kills++;
                        self zm_score::add_to_player_score(40);
                    }
                    else //if they survived
                    {
                        if(!isDefined(a_zombies[ i ].is_brutus)) //if they're not 'a' brutus don't stun them
                            a_zombies[i] thread zm_perk_electric_cherry::electric_cherry_stun();
                        a_zombies[i] thread zm_perk_electric_cherry::electric_cherry_shock_fx();
                    }
                    wait 0.1;
                    if(isDefined(a_zombies[i]) && isAlive(a_zombies[i]))
                        a_zombies[i] doDamage(perk_dmg, self.origin, self, self, "none");
                }
            }
        }
    }
}

function watch_kills()
{
    self endon("bgb_done");
    self endon("killed_5");

    while(self.pop_shock_kills >= 5)
        self notify("killed_5");
}

Second one:
Code:
function gum_pop_shocks()
{
    self endon("death");
    self endon("bgb_done");
    self endon("killed_5");
    self endon("player_downed");
 
    //from electric cherry
    n_clip_current = 1;
    n_clip_max = 10;
    n_fraction = n_clip_current/n_clip_max;

    //electric cherry melee radius - ik the radius is high but idk
    min_range = 32;
    max_range = 128;
    radius = math::linear_map(n_fraction, 1.0, 0.0, min_range, max_range);

    self.pop_shock_kills = 0;
    self.done_meleeing = true;

    self thread trackMeleeAttack();
    self thread watch_kills();

    while(self meleeButtonPressed())
    {
        wait 0.05; //no idea how long it takes to start the melee anim
        if(self isMeleeing() && self.done_meleeing)
        {
            self.done_meleeing = false;
            self thread damageZombies(radius);

            //self SetElectrified(1.0);
//play fx on self for now
            playFxOnTag( level._effect[ "electric_cherry_explode" ], self, "j_head" );
            playFxOnTag( level._effect[ "electric_cherry_explode" ], self, "J_Spine1" );
            playFxOnTag( level._effect[ "electric_cherry_explode" ], self, "J_Spine4" );
            playFxOnTag( level._effect[ "electric_cherry_explode" ], self, "pelvis" );
            self playSound( "zmb_cherry_explode" );
        }
        wait 0.05;
    }
}

function trackMeleeAttack()
{
    self endon("death");
    self endon("bgb_done");
    self endon("killed_5");
    self endon("player_downed");

    while(self isMeleeing() == false)
    {
        self.done_meleeing = true;
        wait 0.05;
    }
}

function damageZombies(radius)
{
    if(isDefined(self))
    {
        a_zombies = zombie_utility::get_round_enemy_array();
        a_zombies = util::get_array_of_closest(self.origin, a_zombies, undefined, undefined, radius);

        n_zombies_hit = 0;
        n_zombie_limit = 1; //amount of zombies we can kill with one melee attack
   
        for(i = 0; i < a_zombies.size; i++)
        {
            if(isAlive(self) && isAlive(a_zombies[i]))
            {
                if(isDefined(n_zombie_limit)) //if the limit of zombies is undefined, keep going and hit all zombies we can
                {
                    if(n_zombies_hit < n_zombie_limit) //if the we're under the limit, increment the count of zombies
                        n_zombies_hit++;
                    else
                        break; //if we're at the limit of zombies, don't kill any more zombies
                }
                if(a_zombies[i].health <= perk_dmg) //if they died
                {
                    a_zombies[i] thread zm_perk_electric_cherry::electric_cherry_death_fx();
               
                    self.pop_shock_kills++;
                    self zm_score::add_to_player_score(40); //points
                }
                else //if they survived
                {
                    if(!isDefined(a_zombies[ i ].is_brutus)) //if they're 'a' brutus don't stun them
                        a_zombies[i] thread zm_perk_electric_cherry::electric_cherry_stun();
                    a_zombies[i] thread zm_perk_electric_cherry::electric_cherry_shock_fx();
                }
                wait 0.1;
                if(isDefined(a_zombies[i]) && isAlive(a_zombies[i]))
                    a_zombies[i] doDamage(7000, self.origin, self, self, "none"); //1045 = zombie health at round 10 and since we only have 5 hits we do 7k
            }
        }
    }
}

function watch_kills()
{
    self endon("bgb_done");
    self endon("killed_5");

    while(self.pop_shock_kills >= 5)
        self notify("killed_5");
}

-------------------------------------------------------------

impatient
Code:
function gum_impatient()
{
    self endon("bgb_done");

    self waittill("death");
    zombies = &GetAIArray("axis"); //if this is false I'll just call it in the loop
    for(;;)
    {
        if(zombies.size <= 1)
        {
            //how do i spawn back in
            break;
        }
        wait 1;
    }
}

-------------------------------------------------------------

Alchemical antithesis
Code:
function gum_alchemical_antithesis()
{
    self endon("gum_done");
    self endon("alchem_done");

    self thread waittill_notify("gum_done", "death", "player_downed"); //idfk what i was thinking
    self thread wait_notify(30, "alchem_done");

    //self thread disableScoring();
    oldScore = self.score;
    max_clip = getWeaponAmmoClip();
    max_stock = getWeaponAmmoStock();

    curWeapon = self getCurrentWeapon();
    curWeapon_alt = getWeapon(curWeapon);

    //could probably waittill weapon fired too but this wouldnt include melee & grenade kills
    for(;;)
    {
        if(self secondaryOffhandButtonPressed())
        {
            wait 0.3; //just to see if he double tapped
            if(curWeapon != self getCurrentWeapon())
            {
                curWeapon = self getCurrentWeapon();
                curWeapon_alt = getWeapon(curWeapon);

                max_clip = getWeaponAmmoClip(curWeapon_alt);
                max_stock = getWeaponAmmoStock(curWeapon_alt);
            }
        }

        if(oldScore != self.score)
        {
            dif = difference(oldScore, self.score);
            amount = int(dif/10);

            curClip = self getAmmoCount(curWeapon_alt);
            curStock = getTotalAmmo(self getLocalClientNumber(), curWeapon_alt);

            if(curStock - max_clip <= 0)
                curStock = max_clip;

            if(curStock - max_clip < max_stock)
                self setWeaponAmmoStock(curWeapon_alt, amount);
            oldScore = self.score;
        }
        wait 0.05;
    }

}

function disableScoring()
{
    self endon("gum_done");

    oldScore = self.score;
    oldScore_alt = self.pers["score"];
    while(self.score != oldScore)
    {
        self.score = oldScore;
        self.pers["score"] = oldScore_alt;
        wait 0.05;
    }
}

function difference(num1, num2)
{
    if(isDefined(num1) && isDefined(num2))
    {
        dif = num1 - num2;
        if(dif < 0)
            dif *= -1;
        return dif;
    }
    return 0;
}
With what do you need actually help? :smile: If you want to share this awesome scripts with us, use Call of Duty: Black Ops 3 Scripts | CabConModding

Regards,
CabCon.
 

Cxwh

Veteran
Messages
64
Reaction score
45
Points
793
I already made the trigger script
Code:
function buyGMashine()
{
    trigger = GetEnt(MASHINE TARGETNAME, "targetname"); //idk MASHINE TARGETNAME have to look it up in radiant
    random_bgb = &get_random_bgb;

    trigger setHintString("Hold ^3&&1^7 to buy Gobblegum [Cost: " + self.mashine_price + "]");  
    trigger setCursorHint("HINT_NOICON");
    //trigger.gmashine_triggered = false;
  
    while(true)
    {
        trigger waittill("trigger", player);
        if(player.score >= self.mashine_price)
        {
            player.has_bgb = true;
            playSoundAtPosition("purchase", trigger.origin); //or the gmashine sound

            bgb = random_bgb;
            player zm_score::minus_to_player_score(self.mashine_price);
            player.current_bgb = bgb.name;

            if(bgb.action == "player activated")
                self thread monitor_activation();

            self thread [[ bgb.func ]]();
            self thread usedMashine();

            /* Only used when player shouldnt be able trigger it again
            if(!trigger.gmashine_triggered)
            {
                model = GetEnt(trigger.target, "targetname");
                trigger.gmashine_triggered = true;
            }
            trigger SetInvisibleToPlayer(player, true);
            */
        }
        wait 0.05;
    }
}
I'd need help with these two

Alchemical Antithesis
Every 10 points earned is instead awarded 1 ammo in the stock of the current weapon.

Pop Shocks
Melee attacks trigger an electrostatic discharge, electrocuting nearby zombies.
 

CabCon

Head Administrator
Staff member
Head Staff Team
Messages
5,093
Reaction score
2,881
Points
1,103
I already made the trigger script
Code:
function buyGMashine()
{
    trigger = GetEnt(MASHINE TARGETNAME, "targetname"); //idk MASHINE TARGETNAME have to look it up in radiant
    random_bgb = &get_random_bgb;

    trigger setHintString("Hold ^3&&1^7 to buy Gobblegum [Cost: " + self.mashine_price + "]"); 
    trigger setCursorHint("HINT_NOICON");
    //trigger.gmashine_triggered = false;
 
    while(true)
    {
        trigger waittill("trigger", player);
        if(player.score >= self.mashine_price)
        {
            player.has_bgb = true;
            playSoundAtPosition("purchase", trigger.origin); //or the gmashine sound

            bgb = random_bgb;
            player zm_score::minus_to_player_score(self.mashine_price);
            player.current_bgb = bgb.name;

            if(bgb.action == "player activated")
                self thread monitor_activation();

            self thread [[ bgb.func ]]();
            self thread usedMashine();

            /* Only used when player shouldnt be able trigger it again
            if(!trigger.gmashine_triggered)
            {
                model = GetEnt(trigger.target, "targetname");
                trigger.gmashine_triggered = true;
            }
            trigger SetInvisibleToPlayer(player, true);
            */
        }
        wait 0.05;
    }
}
I'd need help with these two

Alchemical Antithesis
Every 10 points earned is instead awarded 1 ammo in the stock of the current weapon.

Pop Shocks
Melee attacks trigger an electrostatic discharge, electrocuting nearby zombies.
Awesome, ok I will take a look when I find some time at the weekend into Alchemical Antithesis. :smile:

Regards,
CabCon! Happy Modding!
 
Top