UGX-Mods Login

or login with an authentication provider below
Sign In with Google
Sign In with Twitter
Sign In with Discord
Sign In with Steam
Sign In with Facebook
Sign In with Twitch

Shootable easter egg

broken avatar :(
Created 7 years ago
by worstgabena
0 Members and 1 Guest are viewing this topic.
6,929 views
broken avatar :(
×
broken avatar :(
Location: usAnywhere but here
Date Registered: 31 October 2016
Last active: 6 years ago
Posts
32
Respect
Forum Rank
Legless Crawler
Primary Group
Member
×
worstgabena's Groups
worstgabena's Contact & Social Links
In Radiant
Set x amount different models as script models with the following targetsname:
Code Snippet
Plaintext
shootable_model_
followed by the number you decide.
Then place a trigger_damage around each of them,
and set the triggers with the following targetname:
Code Snippet
Plaintext
shootable_trig_
followed by the same number as its model.

In the .gsc and .csc
Place the following at the top of your .gsc and .csc files:
Code Snippet
Plaintext
#using scripts\zm\_zm_perks;
#insert scripts\zm\_zm_perks.gsh;
#using scripts\zm\_zm_perk_electric_cherry;

In the .zone
Place the following at the bottom of the zone file:
Code Snippet
Plaintext
scriptparsetree,scripts/zm/_zm_perk_electric_cherry.gsc
scriptparsetree,scripts/zm/_zm_perk_electric_cherry.csc

In the .gsc
Place the following into the main function:
Code Snippet
Plaintext
thread shootableEasterEggInit();

Place this at the bottom of your file:
Code Snippet
Plaintext
function shootableEasterEggInit() {
level.activated = 0;

triggers = [];
models = [];
level.total = 3; //set this number to however many shootables you want

for(i = 1; i <= level.total; i++) {
thread shoot(
GetEnt("shootable_trig_" + i, "targetname"),
GetEnt("shootable_model_" + i, "targetname")
);
}
}

function shoot(trigger, model) {
trigger waittill("trigger", player);
trigger delete();
model delete();

level.activated++;

thread finishedEasterEgg();
}

function finishedEasterEgg() {
if(level.activated >= level.total) {
players = GetPlayers();
for(i = 0; i < players.size; i++) {
players[i] zm_perks::give_perk(PERK_ELECTRIC_CHERRY);
}

IPrintLnBold("You should now have recieved Electric Cherry");
}
}

In root\share\raw\scripts\zm\_zm_perk_electric_cherry.gsc
Replace the contents of the file with:
Code Snippet
Plaintext
#using scripts\codescripts\struct;

#using scripts\shared\array_shared;
#using scripts\shared\clientfield_shared;
#using scripts\shared\math_shared;
#using scripts\shared\system_shared;
#using scripts\shared\util_shared;
#using scripts\shared\visionset_mgr_shared;

#insert scripts\shared\shared.gsh;
#insert scripts\shared\version.gsh;

#using scripts\shared\ai\zombie_utility;

#using scripts\zm\_util;
#using scripts\zm\_zm;
#using scripts\zm\_zm_net;
#using scripts\zm\_zm_perks;
#using scripts\zm\_zm_pers_upgrades;
#using scripts\zm\_zm_pers_upgrades_functions;
#using scripts\zm\_zm_pers_upgrades_system;
#using scripts\zm\_zm_score;
#using scripts\zm\_zm_stats;
#using scripts\zm\_zm_utility;

#insert scripts\zm\_zm_perks.gsh;
#insert scripts\zm\_zm_utility.gsh;

//TODO update these to proper settings
#define ELECTRIC_CHERRY_PERK_COST 2000
#define ELECTRIC_CHERRY_PERK_BOTTLE_WEAPON "zombie_perk_bottle_cherry"
#define ELECTRIC_CHERRY_SHADER "specialty_blue_electric_cherry_zombies"
#define ELECTRIC_CHERRY_MACHINE_DISABLED_MODEL "p6_zm_vending_electric_cherry_off" //Change this to your OFF xmodel
#define ELECTRIC_CHERRY_MACHINE_ACTIVE_MODEL "p6_zm_vending_electric_cherry_on" //Change this to your ON xmodel
#define ELECTRIC_CHERRY_RADIANT_MACHINE_NAME "vending_electriccherry"
#define ELECTRIC_CHERRY_MACHINE_LIGHT_FX "electric_cherry_light"


// Global Attack Variables
#define ELECTRIC_CHERRY_STUN_CYCLES 4
// Last Stand Attack
#define ELECTRIC_CHERRY_DOWNED_ATTACK_RADIUS 500
#define ELECTRIC_CHERRY_DOWNED_ATTACK_DAMAGE 1000
#define ELECTRIC_CHERRY_DOWNED_ATTACK_POINTS 40
// Reload Attack
#define RELOAD_ATTACK_MIN_RADIUS 32
#define RELOAD_ATTACK_MAX_RADIUS 128
#define RELOAD_ATTACK_MIN_DAMAGE 1
#define RELOAD_ATTACK_MAX_DAMAGE 1045 // Max damage = zombie health at round 10
#define RELOAD_ATTACK_POINTS 40
#define RELOAD_ATTACK_COOLDOWN_TIMER 3

#precache( "fx", "_t6/misc/fx_zombie_cola_revive_on" );
#precache( "fx", "dlc1/castle/fx_castle_electric_cherry_down" );

#namespace zm_perk_electric_cherry;

REGISTER_SYSTEM( "zm_perk_electric_cherry", &__init__, undefined )

// ELECTRIC CHERRY ( ELECTRIC CHERRY )

//-----------------------------------------------------------------------------------
// setup
//-----------------------------------------------------------------------------------
function __init__()
{
enable_electric_cherry_perk_for_level();
}

function enable_electric_cherry_perk_for_level()
{
// register ec perk for level
zm_perks::register_perk_basic_info( PERK_ELECTRIC_CHERRY, "electric_cherry", ELECTRIC_CHERRY_PERK_COST, "Hold ^3[{+activate}]^7 for Electric Cherry [Cost: &&1]", GetWeapon( ELECTRIC_CHERRY_PERK_BOTTLE_WEAPON ) );
zm_perks::register_perk_precache_func( PERK_ELECTRIC_CHERRY, &electric_cherry_precache );
zm_perks::register_perk_clientfields( PERK_ELECTRIC_CHERRY, &electric_cherry_register_clientfield, &electric_cherry_set_clientfield );
zm_perks::register_perk_machine( PERK_ELECTRIC_CHERRY, &electric_cherry_perk_machine_setup );
zm_perks::register_perk_host_migration_params( PERK_ELECTRIC_CHERRY, ELECTRIC_CHERRY_RADIANT_MACHINE_NAME, ELECTRIC_CHERRY_MACHINE_LIGHT_FX );

zm_perks::register_perk_threads( PERK_ELECTRIC_CHERRY, &electric_cherry_reload_attack , &electric_cherry_perk_lost  );

if( IS_TRUE( level.custom_electric_cherry_perk_threads ) )
{
level thread [[ level.custom_electric_cherry_perk_threads ]]();
}

init_electric_cherry();
}

function electric_cherry_precache()
{
if( IsDefined(level.electric_cherry_precache_override_func) )
{
[[ level.electric_cherry_precache_override_func ]]();
return;
}

level._effect[ELECTRIC_CHERRY_MACHINE_LIGHT_FX] = "_t6/misc/fx_zombie_cola_revive_on";

level.machine_assets[PERK_ELECTRIC_CHERRY] = SpawnStruct();
level.machine_assets[PERK_ELECTRIC_CHERRY].weapon = GetWeapon( ELECTRIC_CHERRY_PERK_BOTTLE_WEAPON );
level.machine_assets[PERK_ELECTRIC_CHERRY].off_model = ELECTRIC_CHERRY_MACHINE_DISABLED_MODEL;
level.machine_assets[PERK_ELECTRIC_CHERRY].on_model = ELECTRIC_CHERRY_MACHINE_ACTIVE_MODEL;
}

function electric_cherry_register_clientfield()
{
clientfield::register( "clientuimodel", PERK_CLIENTFIELD_ELECTRIC_CHERRY, VERSION_SHIP, 2, "int" );
}

function electric_cherry_set_clientfield( state )
{
self clientfield::set_player_uimodel( PERK_CLIENTFIELD_ELECTRIC_CHERRY, state );
}

function electric_cherry_perk_machine_setup( use_trigger, perk_machine, bump_trigger, collision )
{
use_trigger.script_sound = "mus_perks_ec_jingle";
use_trigger.script_string = "electriccherry_perk";
use_trigger.script_label = "mus_perks_ec_sting";
use_trigger.target = "vending_electriccherry";
perk_machine.script_string = "electriccherry_perk";
perk_machine.targetname = "vending_electriccherry";
if( IsDefined( bump_trigger ) )
{
bump_trigger.script_string = "electriccherry_perk";
}
}

//-----------------------------------------------------------------------------------
// functionality
//-----------------------------------------------------------------------------------
function init_electric_cherry()
{
level._effect[ "electric_cherry_explode" ] = "dlc1/castle/fx_castle_electric_cherry_down";

// Last Stand Attack
level.custom_laststand_func = &electric_cherry_laststand;

zombie_utility::set_zombie_var( "tesla_head_gib_chance", 50 );

// Perk specific Client Fields
clientfield::register( "allplayers", "electric_cherry_reload_fx", VERSION_SHIP, 2, "int" );
clientfield::register( "actor", "tesla_death_fx", VERSION_SHIP, 1, "int" );
clientfield::register( "vehicle", "tesla_death_fx_veh", VERSION_TU10, 1, "int" ); // Leave at VERSION_TU10
clientfield::register( "actor", "tesla_shock_eyes_fx", VERSION_SHIP, 1, "int" );
clientfield::register( "vehicle", "tesla_shock_eyes_fx_veh", VERSION_TU10, 1, "int" ); // Leave at VERSION_TU10
}

function electric_cherry_perk_machine_think()
{
init_electric_cherry();

while ( true )
{
machine = getentarray( "vendingelectric_cherry", "targetname" );
machine_triggers = GetEntArray( "vending_electriccherry", "target" );

// Show "inactive" models
for( i = 0; i < machine.size; i++ )
{
machine[i] SetModel( ELECTRIC_CHERRY_MACHINE_DISABLED_MODEL );
}

level thread zm_perks::do_initial_power_off_callback( machine, "electriccherry" );
array::thread_all( machine_triggers, &zm_perks::set_power_on, false );

level waittill( "electric_cherry_on" );

for( i = 0; i < machine.size; i++ )
{
machine[i] SetModel( ELECTRIC_CHERRY_MACHINE_ACTIVE_MODEL );
machine[i] vibrate( ( 0, -100, 0 ), 0.3, 0.4, 3 );
machine[i] playsound( "zmb_perks_power_on" );
machine[i] thread zm_perks::perk_fx( "electriccherry" );
machine[i] thread zm_perks::play_loop_on_machine();
}

level notify( "specialty_grenadepulldeath_power_on" );

array::thread_all( machine_triggers, &zm_perks::set_power_on, true );

level waittill( "electric_cherry_off" );

array::thread_all( machine_triggers, &zm_perks::turn_perk_off );
}
}

// when host migration occurs, fx don't carry over. If perk machine is on, turn the light back on.
function electric_cherry_host_migration_func()
{
a_electric_cherry_perk_machines = GetEntArray( "vending_electriccherry", "targetname" );

foreach( perk_machine in a_electric_cherry_perk_machines )
{
if( isDefined( perk_machine.model ) && perk_machine.model == ELECTRIC_CHERRY_MACHINE_ACTIVE_MODEL )
{
perk_machine zm_perks::perk_fx( undefined, true );
perk_machine thread zm_perks::perk_fx( "electriccherry" );
}
}
}

//-----------------------------------------------------------------------------------
// downed player releases a boom
//-----------------------------------------------------------------------------------

function electric_cherry_laststand()  //self = player
{
VisionSetLastStand( "zombie_last_stand", 1 );

if ( IsDefined( self ) )
{
PlayFX( level._effect[ "electric_cherry_explode" ], self.origin );
self PlaySound( "zmb_cherry_explode" );
self notify( "electric_cherry_start" );

//time for notify to go out
wait 0.05;

a_zombies = zombie_utility::get_round_enemy_array();
a_zombies = util::get_array_of_closest( self.origin, a_zombies, undefined, undefined, ELECTRIC_CHERRY_DOWNED_ATTACK_RADIUS );

for ( i = 0; i < a_zombies.size; i++ )
{
if ( IsAlive( self ) && IsAlive( a_zombies[ i ] ) )
{
if ( a_zombies[ i ].health <= ELECTRIC_CHERRY_DOWNED_ATTACK_DAMAGE )
{
a_zombies[ i ] thread electric_cherry_death_fx();

//for achievement tracking
if( IsDefined( self.cherry_kills ) )
{
self.cherry_kills++;
}

self zm_score::add_to_player_score( ELECTRIC_CHERRY_DOWNED_ATTACK_POINTS );  //add points only if zombie is killed
}

else
{
a_zombies[ i ] thread electric_cherry_stun();
a_zombies[ i ] thread electric_cherry_shock_fx();
}

wait 0.1;

a_zombies[ i ] DoDamage( ELECTRIC_CHERRY_DOWNED_ATTACK_DAMAGE, self.origin, self, self, "none" );
}
}
self notify( "electric_cherry_end" );
}
}


function electric_cherry_death_fx()  //self = zombie
{
self endon( "death" );

self PlaySound( "zmb_elec_jib_zombie" );

if ( !IS_TRUE( self.head_gibbed ) )
{
if( IsVehicle( self ) )
{
self clientfield::set( "tesla_shock_eyes_fx_veh", 1 );
}
else
{
self clientfield::set( "tesla_shock_eyes_fx", 1 );
}
}
else
{
if( IsVehicle( self ) )
{
self clientfield::set( "tesla_death_fx_veh", 1 );
}
else
{
self clientfield::set( "tesla_death_fx", 1 );
}
}
}


function electric_cherry_shock_fx()  //self = zombie
{
self endon( "death" );

if( IsVehicle( self ) )
{
self clientfield::set( "tesla_shock_eyes_fx_veh", 1 );
}
else
{
self clientfield::set( "tesla_shock_eyes_fx", 1 );
}

self PlaySound( "zmb_elec_jib_zombie" );

self waittill( "stun_fx_end" );

if( IsVehicle( self ) )
{
self clientfield::set( "tesla_shock_eyes_fx_veh", 0 );
}
else
{
self clientfield::set( "tesla_shock_eyes_fx", 0 );
}
}


function electric_cherry_stun()  //self = zombie
{
self endon("death");

self notify( "stun_zombie" );
self endon( "stun_zombie" );

if ( self.health <= 0 )
{
return;
}

//only stun the zombie if they are not in the find_flesh state
if ( self.ai_state !== "zombie_think" )
{
return;
}

// This immobilizes zombies because they're being shocked by electricity
self.zombie_tesla_hit = true;
self.ignoreall = true;

wait ELECTRIC_CHERRY_STUN_CYCLES; // wait time for stun to hold.

if( isdefined( self ) )
{
//set them back on course
self.zombie_tesla_hit = false;
self.ignoreall = false;

self notify( "stun_fx_end" );
}
}

//-----------------------------------------------------------------------------------
// Release an explosion when the player reloads
//-----------------------------------------------------------------------------------

function electric_cherry_reload_attack() // self = player
{
self endon( "death" );
self endon( "disconnect" );
self endon( PERK_ELECTRIC_CHERRY + "_stop" );

self.wait_on_reload = [];
self.consecutive_electric_cherry_attacks = 0;

while( true )
{
// Wait for the player to reload
self waittill("reload_start");

current_weapon = self GetCurrentWeapon();

// Don't use the perk if the weapon is waiting to be reloaded
if( IsInArray( self.wait_on_reload, current_weapon ) )
{
continue;
}

// Add this weapon to the list so we know it needs to be reloaded before the perk can be used for again
self.wait_on_reload[self.wait_on_reload.size] = current_weapon;

self.consecutive_electric_cherry_attacks++;

// Get the percentage of bullets left in the clip at the time the weapon is reloaded
// n_clip_current = self GetWeaponAmmoClip( str_current_weapon );
// n_clip_max = WeaponClipSize( str_current_weapon );
n_clip_current = 1;
n_clip_max = 10;
n_fraction = n_clip_current/n_clip_max;

perk_radius = math::linear_map( n_fraction, 1.0, 0.0, RELOAD_ATTACK_MIN_RADIUS, RELOAD_ATTACK_MAX_RADIUS );
perk_dmg = math::linear_map( n_fraction, 1.0, 0.0, RELOAD_ATTACK_MIN_DAMAGE, RELOAD_ATTACK_MAX_DAMAGE );

// Kick off a thread that will tell us when the weapon has been reloaded.
self thread check_for_reload_complete( current_weapon );

// Do the Electric Cherry Perk attack.  Logic should be the same as the "Laststand" attack.
if ( IsDefined( self ) )
{
// If the attack is being spammed, limit the number of zombies the attack can affect
switch( self.consecutive_electric_cherry_attacks )
{
case 0:
case 1:
n_zombie_limit = undefined;
break;

case 2:
n_zombie_limit = 8;
break;

case 3:
n_zombie_limit = 4;
break;

case 4:
n_zombie_limit = 2;
break;

default:
n_zombie_limit = 0;
}

// Start the Cooldown Timer
self thread electric_cherry_cooldown_timer( current_weapon );

if( IsDefined(n_zombie_limit) && (n_zombie_limit == 0) )
{
// The player has spammed the attack too much
// So don't actually perform the attack
// This prevents us from seeing/hearing the attack when it won't affect any zombies
continue;
}

self thread electric_cherry_reload_fx( n_fraction );
self notify( "electric_cherry_start" );
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 the limit of zombies is undefined, keep going and hit all zombies we can
if( IsDefined( n_zombie_limit ) )
{
// If the we're under the limit, increment the count of zombies
if( n_zombies_hit < n_zombie_limit )
{
n_zombies_hit++;
}
else
{
// If we're at the limit of zombies, don't kill any more zombies
break;
}
}

if ( a_zombies[ i ].health <= perk_dmg )
{
a_zombies[ i ] thread electric_cherry_death_fx();

//for achievement tracking
if( IsDefined( self.cherry_kills ) )
{
self.cherry_kills++;
}

self zm_score::add_to_player_score( RELOAD_ATTACK_POINTS );  //add points only if zombie is killed
}
else
{
if( !IsDefined(a_zombies[ i ].is_brutus) )
{
a_zombies[ i ] thread electric_cherry_stun();
}
a_zombies[ i ] thread electric_cherry_shock_fx();
}

wait 0.1;

if( isdefined( a_zombies[ i ] ) && IsAlive( a_zombies[ i ] ) ) // need to check again since we're post-wait
{
a_zombies[ i ] DoDamage( perk_dmg, self.origin, self, self, "none" );
}
}
}

self notify( "electric_cherry_end" );
}
}
}

function electric_cherry_cooldown_timer( current_weapon ) // self = player
{
self notify( "electric_cherry_cooldown_started" );
self endon( "electric_cherry_cooldown_started" );
self endon( "death" );
self endon( "disconnect" );

// Start the timer when the player reloads (when electric cherry attack starts)
// Cooldown time is equal to the weapon's reload time plus the global cooldown
//n_reload_time = WeaponReloadTime( current_weapon ); // TODO
n_reload_time = 0.25;
if( self HasPerk( "specialty_fastreload" ) )
{
n_reload_time *= GetDvarFloat( "perk_weapReloadMultiplier" );
}

n_cooldown_time = (n_reload_time + RELOAD_ATTACK_COOLDOWN_TIMER);

wait n_cooldown_time;

self.consecutive_electric_cherry_attacks = 0;
}

function check_for_reload_complete( weapon ) // self = player
{
self endon( "death" );
self endon( "disconnect" );
//self endon( "weapon_change_complete" );
self endon( "player_lost_weapon_" + weapon.name );

// Thread to watch for the case where this weapon gets replaced
self thread weapon_replaced_monitor( weapon );

while( 1 )
{
// Wait for the player to complete a reload
self waittill( "reload" );

// If the weapon that just got reloaded is the same as the one that was used for the electric cherry perk
// Kill off this thread and remove this weapon's name from the player's wait_on_reload list
// This allows the player to use the Electric Cherry Reload Attack with this weapon again!
current_weapon = self GetCurrentWeapon();
if( current_weapon == weapon )
{
ArrayRemoveValue( self.wait_on_reload, weapon );
self notify( "weapon_reload_complete_" + weapon.name );
break;
}
}
}

function weapon_replaced_monitor( weapon ) // self = player
{
self endon( "death" );
self endon( "disconnect" );
self endon( "weapon_reload_complete_" + weapon.name );

while( 1 )
{
// Wait for the player to change weapons (swap weapon, wall buy, magic box, etc.)
self waittill( "weapon_change" );

// If the weapon that we previously used for the Electric Cherry Reload Attack is no longer equipped
// Kill off this thread and remove this weapon's name from the player's wait_on_reload list
// This handles the case when a player cancels a reload, then replaces this weapon
// Ensures that when the player re-aquires the weapon, he has a fresh start and can use the Electric Cherry perk immediately.
primaryWeapons = self GetWeaponsListPrimaries();
if( !IsInArray( primaryWeapons, weapon ) )
{
self notify( "player_lost_weapon_" + weapon.name );
ArrayRemoveValue( self.wait_on_reload, weapon );
break;
}
}
}

function electric_cherry_reload_fx( n_fraction )
{
if( n_fraction >= 0.67 )
{
CodeSetClientField( self, "electric_cherry_reload_fx", 1 );
}
else if( (n_fraction >= 0.33) && (n_fraction < 0.67) )
{
CodeSetClientField( self, "electric_cherry_reload_fx", 2 );
}
else
{
CodeSetClientField( self, "electric_cherry_reload_fx", 3 );
}

wait ( 1.0 );

CodeSetClientField( self, "electric_cherry_reload_fx", 0 );
}

//////////////////////////////////////////////////////////////
//Perk lost func
//////////////////////////////////////////////////////////////
function electric_cherry_perk_lost( b_pause, str_perk, str_result )
{
self notify( PERK_ELECTRIC_CHERRY + "_stop" );
}

Last Edit: November 20, 2016, 04:21:31 am by Sidzzz
broken avatar :(
×
broken avatar :(
Location: us
Date Registered: 12 September 2016
Last active: 3 years ago
Posts
306
Respect
Forum Rank
Perk Hacker
Primary Group
Member
My Contact & Social Links
More
×
reckfullies's Groups
reckfullies's Contact & Social LinksReckfulliesReckfullies
Spoiler: click to open...
In Radient

Set three diferent models as script models with the following targetsnames:
Code Snippet
Plaintext
shootable_model
shootable_model_2
shootable_model_3
Then place a trigger_damage around each of them,
and set the triggers with the following targetnames
Code Snippet
Plaintext
shootable_trig_1
shootable_trig_2
shootable_trig_3

In the .gsc and .csc
Place the following at the top of your .gsc and .csc files:
Code Snippet
Plaintext
#using scripts\zm\_zm_perks;
#insert scripts\zm\_zm_perks.gsh;
#using scripts\zm\_zm_perk_electric_cherry;

In the .zone
Place the following at the bottom of the zone file:
Code Snippet
Plaintext
scriptparsetree,scripts/zm/_zm_perk_electric_cherry.gsc
scriptparsetree,scripts/zm/_zm_perk_electric_cherry.csc

In the .gsc
Place the following into the main function:
Code Snippet
Plaintext
thread shootableEasterEggInit();

Place this at the bottom of your file:
Code Snippet
Plaintext
function shootableEasterEggInit()
{
level.shootableEasterEggInit = 0;
level.shootables = 3;

thread shoot1();
thread shoot2();
thread shoot3();
}

function shoot1()
{
shoot_trig1 = GetEnt("shootable_trig_1", "targetname");
shoot_trig1 waittill("trigger", player);
shoot_model1 = GetEnt("shootable_model_1", "targetname");
shoot_model1 delete();
level.shootableEasterEggInit++;
thread finishedEasterEgg();
shoot_trig1 delete();
shoot_model1 delete();
}

function shoot2()
{
shoot_trig2 = GetEnt("shootable_trig_2", "targetname");
shoot_trig2 waittill("trigger", player);
shoot_model2 = GetEnt("shootable_model_2", "targetname");
shoot_model2 delete();
level.shootableEasterEggInit++;
thread finishedEasterEgg();
shoot_trig2 delete();
shoot_model2 delete();
}

function shoot3()
{
shoot_trig3 = GetEnt("shootable_trig_3", "targetname");
shoot_trig3 waittill("trigger", player);
shoot_model3 = GetEnt("shootable_model_3", "targetname");
shoot_model3 delete();
level.shootableEasterEggInit++;
thread finishedEasterEgg();
shoot_trig3 delete();
shoot_model3 delete();
}

function finishedEasterEgg()
{
if(level.shootableEasterEggInit >= level.shootables)
{
IPrintLnBold("You should now have recieved Electric Cherry");

players = GetPlayers();
for (i = 0;i<players.size;i++) {
players[i] zm_perks::give_perk( PERK_ELECTRIC_CHERRY );
}
}
}

In root\share\raw\scripts\zm\_zm_perk_electric_cherry.gsc
Replace the contents of the file with:
Code Snippet
Plaintext
#using scripts\codescripts\struct;

#using scripts\shared\array_shared;
#using scripts\shared\clientfield_shared;
#using scripts\shared\math_shared;
#using scripts\shared\system_shared;
#using scripts\shared\util_shared;
#using scripts\shared\visionset_mgr_shared;

#insert scripts\shared\shared.gsh;
#insert scripts\shared\version.gsh;

#using scripts\shared\ai\zombie_utility;

#using scripts\zm\_util;
#using scripts\zm\_zm;
#using scripts\zm\_zm_net;
#using scripts\zm\_zm_perks;
#using scripts\zm\_zm_pers_upgrades;
#using scripts\zm\_zm_pers_upgrades_functions;
#using scripts\zm\_zm_pers_upgrades_system;
#using scripts\zm\_zm_score;
#using scripts\zm\_zm_stats;
#using scripts\zm\_zm_utility;

#insert scripts\zm\_zm_perks.gsh;
#insert scripts\zm\_zm_utility.gsh;

//TODO update these to proper settings
#define ELECTRIC_CHERRY_PERK_COST 2000
#define ELECTRIC_CHERRY_PERK_BOTTLE_WEAPON "zombie_perk_bottle_cherry"
#define ELECTRIC_CHERRY_SHADER "specialty_blue_electric_cherry_zombies"
#define ELECTRIC_CHERRY_MACHINE_DISABLED_MODEL "p6_zm_vending_electric_cherry_off" //Change this to your OFF xmodel
#define ELECTRIC_CHERRY_MACHINE_ACTIVE_MODEL "p6_zm_vending_electric_cherry_on" //Change this to your ON xmodel
#define ELECTRIC_CHERRY_RADIANT_MACHINE_NAME "vending_electriccherry"
#define ELECTRIC_CHERRY_MACHINE_LIGHT_FX "electric_cherry_light"


// Global Attack Variables
#define ELECTRIC_CHERRY_STUN_CYCLES 4
// Last Stand Attack
#define ELECTRIC_CHERRY_DOWNED_ATTACK_RADIUS 500
#define ELECTRIC_CHERRY_DOWNED_ATTACK_DAMAGE 1000
#define ELECTRIC_CHERRY_DOWNED_ATTACK_POINTS 40
// Reload Attack
#define RELOAD_ATTACK_MIN_RADIUS 32
#define RELOAD_ATTACK_MAX_RADIUS 128
#define RELOAD_ATTACK_MIN_DAMAGE 1
#define RELOAD_ATTACK_MAX_DAMAGE 1045 // Max damage = zombie health at round 10
#define RELOAD_ATTACK_POINTS 40
#define RELOAD_ATTACK_COOLDOWN_TIMER 3

#precache( "fx", "_t6/misc/fx_zombie_cola_revive_on" );
#precache( "fx", "dlc1/castle/fx_castle_electric_cherry_down" );

#namespace zm_perk_electric_cherry;

REGISTER_SYSTEM( "zm_perk_electric_cherry", &__init__, undefined )

// ELECTRIC CHERRY ( ELECTRIC CHERRY )

//-----------------------------------------------------------------------------------
// setup
//-----------------------------------------------------------------------------------
function __init__()
{
enable_electric_cherry_perk_for_level();
}

function enable_electric_cherry_perk_for_level()
{
// register ec perk for level
zm_perks::register_perk_basic_info( PERK_ELECTRIC_CHERRY, "electric_cherry", ELECTRIC_CHERRY_PERK_COST, "Hold ^3[{+activate}]^7 for Electric Cherry [Cost: &&1]", GetWeapon( ELECTRIC_CHERRY_PERK_BOTTLE_WEAPON ) );
zm_perks::register_perk_precache_func( PERK_ELECTRIC_CHERRY, &electric_cherry_precache );
zm_perks::register_perk_clientfields( PERK_ELECTRIC_CHERRY, &electric_cherry_register_clientfield, &electric_cherry_set_clientfield );
zm_perks::register_perk_machine( PERK_ELECTRIC_CHERRY, &electric_cherry_perk_machine_setup );
zm_perks::register_perk_host_migration_params( PERK_ELECTRIC_CHERRY, ELECTRIC_CHERRY_RADIANT_MACHINE_NAME, ELECTRIC_CHERRY_MACHINE_LIGHT_FX );

zm_perks::register_perk_threads( PERK_ELECTRIC_CHERRY, &electric_cherry_reload_attack , &electric_cherry_perk_lost  );

if( IS_TRUE( level.custom_electric_cherry_perk_threads ) )
{
level thread [[ level.custom_electric_cherry_perk_threads ]]();
}

init_electric_cherry();
}

function electric_cherry_precache()
{
if( IsDefined(level.electric_cherry_precache_override_func) )
{
[[ level.electric_cherry_precache_override_func ]]();
return;
}

level._effect[ELECTRIC_CHERRY_MACHINE_LIGHT_FX] = "_t6/misc/fx_zombie_cola_revive_on";

level.machine_assets[PERK_ELECTRIC_CHERRY] = SpawnStruct();
level.machine_assets[PERK_ELECTRIC_CHERRY].weapon = GetWeapon( ELECTRIC_CHERRY_PERK_BOTTLE_WEAPON );
level.machine_assets[PERK_ELECTRIC_CHERRY].off_model = ELECTRIC_CHERRY_MACHINE_DISABLED_MODEL;
level.machine_assets[PERK_ELECTRIC_CHERRY].on_model = ELECTRIC_CHERRY_MACHINE_ACTIVE_MODEL;
}

function electric_cherry_register_clientfield()
{
clientfield::register( "clientuimodel", PERK_CLIENTFIELD_ELECTRIC_CHERRY, VERSION_SHIP, 2, "int" );
}

function electric_cherry_set_clientfield( state )
{
self clientfield::set_player_uimodel( PERK_CLIENTFIELD_ELECTRIC_CHERRY, state );
}

function electric_cherry_perk_machine_setup( use_trigger, perk_machine, bump_trigger, collision )
{
use_trigger.script_sound = "mus_perks_ec_jingle";
use_trigger.script_string = "electriccherry_perk";
use_trigger.script_label = "mus_perks_ec_sting";
use_trigger.target = "vending_electriccherry";
perk_machine.script_string = "electriccherry_perk";
perk_machine.targetname = "vending_electriccherry";
if( IsDefined( bump_trigger ) )
{
bump_trigger.script_string = "electriccherry_perk";
}
}

//-----------------------------------------------------------------------------------
// functionality
//-----------------------------------------------------------------------------------
function init_electric_cherry()
{
level._effect[ "electric_cherry_explode" ] = "dlc1/castle/fx_castle_electric_cherry_down";

// Last Stand Attack
level.custom_laststand_func = &electric_cherry_laststand;

zombie_utility::set_zombie_var( "tesla_head_gib_chance", 50 );

// Perk specific Client Fields
clientfield::register( "allplayers", "electric_cherry_reload_fx", VERSION_SHIP, 2, "int" );
clientfield::register( "actor", "tesla_death_fx", VERSION_SHIP, 1, "int" );
clientfield::register( "vehicle", "tesla_death_fx_veh", VERSION_TU10, 1, "int" ); // Leave at VERSION_TU10
clientfield::register( "actor", "tesla_shock_eyes_fx", VERSION_SHIP, 1, "int" );
clientfield::register( "vehicle", "tesla_shock_eyes_fx_veh", VERSION_TU10, 1, "int" ); // Leave at VERSION_TU10
}

function electric_cherry_perk_machine_think()
{
init_electric_cherry();

while ( true )
{
machine = getentarray( "vendingelectric_cherry", "targetname" );
machine_triggers = GetEntArray( "vending_electriccherry", "target" );

// Show "inactive" models
for( i = 0; i < machine.size; i++ )
{
machine[i] SetModel( ELECTRIC_CHERRY_MACHINE_DISABLED_MODEL );
}

level thread zm_perks::do_initial_power_off_callback( machine, "electriccherry" );
array::thread_all( machine_triggers, &zm_perks::set_power_on, false );

level waittill( "electric_cherry_on" );

for( i = 0; i < machine.size; i++ )
{
machine[i] SetModel( ELECTRIC_CHERRY_MACHINE_ACTIVE_MODEL );
machine[i] vibrate( ( 0, -100, 0 ), 0.3, 0.4, 3 );
machine[i] playsound( "zmb_perks_power_on" );
machine[i] thread zm_perks::perk_fx( "electriccherry" );
machine[i] thread zm_perks::play_loop_on_machine();
}

level notify( "specialty_grenadepulldeath_power_on" );

array::thread_all( machine_triggers, &zm_perks::set_power_on, true );

level waittill( "electric_cherry_off" );

array::thread_all( machine_triggers, &zm_perks::turn_perk_off );
}
}

// when host migration occurs, fx don't carry over. If perk machine is on, turn the light back on.
function electric_cherry_host_migration_func()
{
a_electric_cherry_perk_machines = GetEntArray( "vending_electriccherry", "targetname" );

foreach( perk_machine in a_electric_cherry_perk_machines )
{
if( isDefined( perk_machine.model ) && perk_machine.model == ELECTRIC_CHERRY_MACHINE_ACTIVE_MODEL )
{
perk_machine zm_perks::perk_fx( undefined, true );
perk_machine thread zm_perks::perk_fx( "electriccherry" );
}
}
}

//-----------------------------------------------------------------------------------
// downed player releases a boom
//-----------------------------------------------------------------------------------

function electric_cherry_laststand()  //self = player
{
VisionSetLastStand( "zombie_last_stand", 1 );

if ( IsDefined( self ) )
{
PlayFX( level._effect[ "electric_cherry_explode" ], self.origin );
self PlaySound( "zmb_cherry_explode" );
self notify( "electric_cherry_start" );

//time for notify to go out
wait 0.05;

a_zombies = zombie_utility::get_round_enemy_array();
a_zombies = util::get_array_of_closest( self.origin, a_zombies, undefined, undefined, ELECTRIC_CHERRY_DOWNED_ATTACK_RADIUS );

for ( i = 0; i < a_zombies.size; i++ )
{
if ( IsAlive( self ) && IsAlive( a_zombies[ i ] ) )
{
if ( a_zombies[ i ].health <= ELECTRIC_CHERRY_DOWNED_ATTACK_DAMAGE )
{
a_zombies[ i ] thread electric_cherry_death_fx();

//for achievement tracking
if( IsDefined( self.cherry_kills ) )
{
self.cherry_kills++;
}

self zm_score::add_to_player_score( ELECTRIC_CHERRY_DOWNED_ATTACK_POINTS );  //add points only if zombie is killed
}

else
{
a_zombies[ i ] thread electric_cherry_stun();
a_zombies[ i ] thread electric_cherry_shock_fx();
}

wait 0.1;

a_zombies[ i ] DoDamage( ELECTRIC_CHERRY_DOWNED_ATTACK_DAMAGE, self.origin, self, self, "none" );
}
}
self notify( "electric_cherry_end" );
}
}


function electric_cherry_death_fx()  //self = zombie
{
self endon( "death" );

self PlaySound( "zmb_elec_jib_zombie" );

if ( !IS_TRUE( self.head_gibbed ) )
{
if( IsVehicle( self ) )
{
self clientfield::set( "tesla_shock_eyes_fx_veh", 1 );
}
else
{
self clientfield::set( "tesla_shock_eyes_fx", 1 );
}
}
else
{
if( IsVehicle( self ) )
{
self clientfield::set( "tesla_death_fx_veh", 1 );
}
else
{
self clientfield::set( "tesla_death_fx", 1 );
}
}
}


function electric_cherry_shock_fx()  //self = zombie
{
self endon( "death" );

if( IsVehicle( self ) )
{
self clientfield::set( "tesla_shock_eyes_fx_veh", 1 );
}
else
{
self clientfield::set( "tesla_shock_eyes_fx", 1 );
}

self PlaySound( "zmb_elec_jib_zombie" );

self waittill( "stun_fx_end" );

if( IsVehicle( self ) )
{
self clientfield::set( "tesla_shock_eyes_fx_veh", 0 );
}
else
{
self clientfield::set( "tesla_shock_eyes_fx", 0 );
}
}


function electric_cherry_stun()  //self = zombie
{
self endon("death");

self notify( "stun_zombie" );
self endon( "stun_zombie" );

if ( self.health <= 0 )
{
return;
}

//only stun the zombie if they are not in the find_flesh state
if ( self.ai_state !== "zombie_think" )
{
return;
}

// This immobilizes zombies because they're being shocked by electricity
self.zombie_tesla_hit = true;
self.ignoreall = true;

wait ELECTRIC_CHERRY_STUN_CYCLES; // wait time for stun to hold.

if( isdefined( self ) )
{
//set them back on course
self.zombie_tesla_hit = false;
self.ignoreall = false;

self notify( "stun_fx_end" );
}
}

//-----------------------------------------------------------------------------------
// Release an explosion when the player reloads
//-----------------------------------------------------------------------------------

function electric_cherry_reload_attack() // self = player
{
self endon( "death" );
self endon( "disconnect" );
self endon( PERK_ELECTRIC_CHERRY + "_stop" );

self.wait_on_reload = [];
self.consecutive_electric_cherry_attacks = 0;

while( true )
{
// Wait for the player to reload
self waittill("reload_start");

current_weapon = self GetCurrentWeapon();

// Don't use the perk if the weapon is waiting to be reloaded
if( IsInArray( self.wait_on_reload, current_weapon ) )
{
continue;
}

// Add this weapon to the list so we know it needs to be reloaded before the perk can be used for again
self.wait_on_reload[self.wait_on_reload.size] = current_weapon;

self.consecutive_electric_cherry_attacks++;

// Get the percentage of bullets left in the clip at the time the weapon is reloaded
// n_clip_current = self GetWeaponAmmoClip( str_current_weapon );
// n_clip_max = WeaponClipSize( str_current_weapon );
n_clip_current = 1;
n_clip_max = 10;
n_fraction = n_clip_current/n_clip_max;

perk_radius = math::linear_map( n_fraction, 1.0, 0.0, RELOAD_ATTACK_MIN_RADIUS, RELOAD_ATTACK_MAX_RADIUS );
perk_dmg = math::linear_map( n_fraction, 1.0, 0.0, RELOAD_ATTACK_MIN_DAMAGE, RELOAD_ATTACK_MAX_DAMAGE );

// Kick off a thread that will tell us when the weapon has been reloaded.
self thread check_for_reload_complete( current_weapon );

// Do the Electric Cherry Perk attack.  Logic should be the same as the "Laststand" attack.
if ( IsDefined( self ) )
{
// If the attack is being spammed, limit the number of zombies the attack can affect
switch( self.consecutive_electric_cherry_attacks )
{
case 0:
case 1:
n_zombie_limit = undefined;
break;

case 2:
n_zombie_limit = 8;
break;

case 3:
n_zombie_limit = 4;
break;

case 4:
n_zombie_limit = 2;
break;

default:
n_zombie_limit = 0;
}

// Start the Cooldown Timer
self thread electric_cherry_cooldown_timer( current_weapon );

if( IsDefined(n_zombie_limit) && (n_zombie_limit == 0) )
{
// The player has spammed the attack too much
// So don't actually perform the attack
// This prevents us from seeing/hearing the attack when it won't affect any zombies
continue;
}

self thread electric_cherry_reload_fx( n_fraction );
self notify( "electric_cherry_start" );
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 the limit of zombies is undefined, keep going and hit all zombies we can
if( IsDefined( n_zombie_limit ) )
{
// If the we're under the limit, increment the count of zombies
if( n_zombies_hit < n_zombie_limit )
{
n_zombies_hit++;
}
else
{
// If we're at the limit of zombies, don't kill any more zombies
break;
}
}

if ( a_zombies[ i ].health <= perk_dmg )
{
a_zombies[ i ] thread electric_cherry_death_fx();

//for achievement tracking
if( IsDefined( self.cherry_kills ) )
{
self.cherry_kills++;
}

self zm_score::add_to_player_score( RELOAD_ATTACK_POINTS );  //add points only if zombie is killed
}
else
{
if( !IsDefined(a_zombies[ i ].is_brutus) )
{
a_zombies[ i ] thread electric_cherry_stun();
}
a_zombies[ i ] thread electric_cherry_shock_fx();
}

wait 0.1;

if( isdefined( a_zombies[ i ] ) && IsAlive( a_zombies[ i ] ) ) // need to check again since we're post-wait
{
a_zombies[ i ] DoDamage( perk_dmg, self.origin, self, self, "none" );
}
}
}

self notify( "electric_cherry_end" );
}
}
}

function electric_cherry_cooldown_timer( current_weapon ) // self = player
{
self notify( "electric_cherry_cooldown_started" );
self endon( "electric_cherry_cooldown_started" );
self endon( "death" );
self endon( "disconnect" );

// Start the timer when the player reloads (when electric cherry attack starts)
// Cooldown time is equal to the weapon's reload time plus the global cooldown
//n_reload_time = WeaponReloadTime( current_weapon ); // TODO
n_reload_time = 0.25;
if( self HasPerk( "specialty_fastreload" ) )
{
n_reload_time *= GetDvarFloat( "perk_weapReloadMultiplier" );
}

n_cooldown_time = (n_reload_time + RELOAD_ATTACK_COOLDOWN_TIMER);

wait n_cooldown_time;

self.consecutive_electric_cherry_attacks = 0;
}

function check_for_reload_complete( weapon ) // self = player
{
self endon( "death" );
self endon( "disconnect" );
//self endon( "weapon_change_complete" );
self endon( "player_lost_weapon_" + weapon.name );

// Thread to watch for the case where this weapon gets replaced
self thread weapon_replaced_monitor( weapon );

while( 1 )
{
// Wait for the player to complete a reload
self waittill( "reload" );

// If the weapon that just got reloaded is the same as the one that was used for the electric cherry perk
// Kill off this thread and remove this weapon's name from the player's wait_on_reload list
// This allows the player to use the Electric Cherry Reload Attack with this weapon again!
current_weapon = self GetCurrentWeapon();
if( current_weapon == weapon )
{
ArrayRemoveValue( self.wait_on_reload, weapon );
self notify( "weapon_reload_complete_" + weapon.name );
break;
}
}
}

function weapon_replaced_monitor( weapon ) // self = player
{
self endon( "death" );
self endon( "disconnect" );
self endon( "weapon_reload_complete_" + weapon.name );

while( 1 )
{
// Wait for the player to change weapons (swap weapon, wall buy, magic box, etc.)
self waittill( "weapon_change" );

// If the weapon that we previously used for the Electric Cherry Reload Attack is no longer equipped
// Kill off this thread and remove this weapon's name from the player's wait_on_reload list
// This handles the case when a player cancels a reload, then replaces this weapon
// Ensures that when the player re-aquires the weapon, he has a fresh start and can use the Electric Cherry perk immediately.
primaryWeapons = self GetWeaponsListPrimaries();
if( !IsInArray( primaryWeapons, weapon ) )
{
self notify( "player_lost_weapon_" + weapon.name );
ArrayRemoveValue( self.wait_on_reload, weapon );
break;
}
}
}

function electric_cherry_reload_fx( n_fraction )
{
if( n_fraction >= 0.67 )
{
CodeSetClientField( self, "electric_cherry_reload_fx", 1 );
}
else if( (n_fraction >= 0.33) && (n_fraction < 0.67) )
{
CodeSetClientField( self, "electric_cherry_reload_fx", 2 );
}
else
{
CodeSetClientField( self, "electric_cherry_reload_fx", 3 );
}

wait ( 1.0 );

CodeSetClientField( self, "electric_cherry_reload_fx", 0 );
}

//////////////////////////////////////////////////////////////
//Perk lost func
//////////////////////////////////////////////////////////////
function electric_cherry_perk_lost( b_pause, str_perk, str_result )
{
self notify( PERK_ELECTRIC_CHERRY + "_stop" );
}


Is this really required? Its basically the exact same(Like really) as the script I already posted on here lol.
broken avatar :(
×
broken avatar :(
Location: usAnywhere but here
Date Registered: 31 October 2016
Last active: 6 years ago
Posts
32
Respect
Forum Rank
Legless Crawler
Primary Group
Member
×
worstgabena's Groups
worstgabena's Contact & Social Links
Yeah, Reck, your tutorial didn't work, you were missing a few parts and had weird spacing characters, so I found a similar thing and modified it.
I tried posting this, but I lost connection do idk if it posted.
broken avatar :(
×
broken avatar :(
Location: us
Date Registered: 12 September 2016
Last active: 3 years ago
Posts
306
Respect
Forum Rank
Perk Hacker
Primary Group
Member
My Contact & Social Links
More
×
reckfullies's Groups
reckfullies's Contact & Social LinksReckfulliesReckfullies
Yeah, Reck, your tutorial didn't work, you were missing a few parts and had weird spacing characters, so I found a similar thing and modified it.
I tried posting this, but I lost connection do idk if it posted.

Really? I didn't notice that, guess its something ill need to fix. Also, what do you mean by missing a few parts?
broken avatar :(
×
broken avatar :(
Location: usAnywhere but here
Date Registered: 31 October 2016
Last active: 6 years ago
Posts
32
Respect
Forum Rank
Legless Crawler
Primary Group
Member
×
worstgabena's Groups
worstgabena's Contact & Social Links
I Can't remember all of it, but I know you forgot about the .CSC file, and maybe even the .gsc.i think they're was more.
broken avatar :(
×
broken avatar :(
Location: us
Date Registered: 12 September 2016
Last active: 3 years ago
Posts
306
Respect
Forum Rank
Perk Hacker
Primary Group
Member
My Contact & Social Links
More
×
reckfullies's Groups
reckfullies's Contact & Social LinksReckfulliesReckfullies
I Can't remember all of it, but I know you forgot about the .CSC file, and maybe even the .gsc.i think they're was more.

Are you talking about for perks or something? Nothing was required to be added to csc for my tutorial, mine was just purely for a shootable that can be used for anything not about a shootable giving perks or weapons like yours does.
broken avatar :(
×
broken avatar :(
Location: usAnywhere but here
Date Registered: 31 October 2016
Last active: 6 years ago
Posts
32
Respect
Forum Rank
Legless Crawler
Primary Group
Member
×
worstgabena's Groups
worstgabena's Contact & Social Links
I remember testing it, but it kept on breaking, idk why.


Double Post Merge

New Version
Only difference is the part at the bottom of the .gsc file[/size]
In Radiant
Set x amount different models as script models with the following targetsname:
Code Snippet
Plaintext
shootable_model_
followed by the number you decide.
Then place a trigger_damage around each of them,
and set the triggers with the following targetname:
Code Snippet
Plaintext
shootable_trig_
followed by the same number as its model.[/size]
In the .gsc and .csc
Place the following at the top of your .gsc and .csc files:
Code Snippet
Plaintext
#using scripts\zm\_zm_perks;
#insert scripts\zm\_zm_perks.gsh;
#using scripts\zm\_zm_perk_electric_cherry;
[/size]
In the .zone
Place the following at the bottom of the zone file:
Code Snippet
Plaintext
scriptparsetree,scripts/zm/_zm_perk_electric_cherry.gsc
scriptparsetree,scripts/zm/_zm_perk_electric_cherry.csc
[/size]
In the .gsc
Place the following into the main function:
Code Snippet
Plaintext
thread shootableEasterEggInit();
Place this at the bottom of your file:
Code Snippet
Plaintext
function shootableEasterEggInit() {
level.activated = 0;

triggers = [];
models = [];
level.total = 3; //set this number to however many shootables you want

for(i = 1; i <= level.total; i++) {
thread shoot(
GetEnt("shootable_trig_" + i, "targetname"),
GetEnt("shootable_model_" + i, "targetname")
);
}
}

function shoot(trigger, model) {
trigger waittill("trigger", player);
trigger delete();
model delete();

level.activated++;

thread finishedEasterEgg();
}

function finishedEasterEgg() {
if(level.activated >= level.total) {
players = GetPlayers();
for(i = 0; i < players.size; i++) {
players[i] zm_perks::give_perk(PERK_ELECTRIC_CHERRY);
}

IPrintLnBold("You should now have recieved Electric Cherry");
}
}
In root\share\raw\scripts\zm\_zm_perk_electric_cherry.gsc
Replace the contents of the file with:
Code Snippet
Plaintext
#using scripts\codescripts\struct;

#using scripts\shared\array_shared;
#using scripts\shared\clientfield_shared;
#using scripts\shared\math_shared;
#using scripts\shared\system_shared;
#using scripts\shared\util_shared;
#using scripts\shared\visionset_mgr_shared;

#insert scripts\shared\shared.gsh;
#insert scripts\shared\version.gsh;

#using scripts\shared\ai\zombie_utility;

#using scripts\zm\_util;
#using scripts\zm\_zm;
#using scripts\zm\_zm_net;
#using scripts\zm\_zm_perks;
#using scripts\zm\_zm_pers_upgrades;
#using scripts\zm\_zm_pers_upgrades_functions;
#using scripts\zm\_zm_pers_upgrades_system;
#using scripts\zm\_zm_score;
#using scripts\zm\_zm_stats;
#using scripts\zm\_zm_utility;

#insert scripts\zm\_zm_perks.gsh;
#insert scripts\zm\_zm_utility.gsh;

//TODO update these to proper settings
#define ELECTRIC_CHERRY_PERK_COST 2000
#define ELECTRIC_CHERRY_PERK_BOTTLE_WEAPON "zombie_perk_bottle_cherry"
#define ELECTRIC_CHERRY_SHADER "specialty_blue_electric_cherry_zombies"
#define ELECTRIC_CHERRY_MACHINE_DISABLED_MODEL "p6_zm_vending_electric_cherry_off" //Change this to your OFF xmodel
#define ELECTRIC_CHERRY_MACHINE_ACTIVE_MODEL "p6_zm_vending_electric_cherry_on" //Change this to your ON xmodel
#define ELECTRIC_CHERRY_RADIANT_MACHINE_NAME "vending_electriccherry"
#define ELECTRIC_CHERRY_MACHINE_LIGHT_FX "electric_cherry_light"


// Global Attack Variables
#define ELECTRIC_CHERRY_STUN_CYCLES 4
// Last Stand Attack
#define ELECTRIC_CHERRY_DOWNED_ATTACK_RADIUS 500
#define ELECTRIC_CHERRY_DOWNED_ATTACK_DAMAGE 1000
#define ELECTRIC_CHERRY_DOWNED_ATTACK_POINTS 40
// Reload Attack
#define RELOAD_ATTACK_MIN_RADIUS 32
#define RELOAD_ATTACK_MAX_RADIUS 128
#define RELOAD_ATTACK_MIN_DAMAGE 1
#define RELOAD_ATTACK_MAX_DAMAGE 1045 // Max damage = zombie health at round 10
#define RELOAD_ATTACK_POINTS 40
#define RELOAD_ATTACK_COOLDOWN_TIMER 3

#precache( "fx", "_t6/misc/fx_zombie_cola_revive_on" );
#precache( "fx", "dlc1/castle/fx_castle_electric_cherry_down" );

#namespace zm_perk_electric_cherry;

REGISTER_SYSTEM( "zm_perk_electric_cherry", &__init__, undefined )

// ELECTRIC CHERRY ( ELECTRIC CHERRY )

//-----------------------------------------------------------------------------------
// setup
//-----------------------------------------------------------------------------------
function __init__()
{
enable_electric_cherry_perk_for_level();
}

function enable_electric_cherry_perk_for_level()
{
// register ec perk for level
zm_perks::register_perk_basic_info( PERK_ELECTRIC_CHERRY, "electric_cherry", ELECTRIC_CHERRY_PERK_COST, "Hold ^3[{+activate}]^7 for Electric Cherry [Cost: &&1]", GetWeapon( ELECTRIC_CHERRY_PERK_BOTTLE_WEAPON ) );
zm_perks::register_perk_precache_func( PERK_ELECTRIC_CHERRY, &electric_cherry_precache );
zm_perks::register_perk_clientfields( PERK_ELECTRIC_CHERRY, &electric_cherry_register_clientfield, &electric_cherry_set_clientfield );
zm_perks::register_perk_machine( PERK_ELECTRIC_CHERRY, &electric_cherry_perk_machine_setup );
zm_perks::register_perk_host_migration_params( PERK_ELECTRIC_CHERRY, ELECTRIC_CHERRY_RADIANT_MACHINE_NAME, ELECTRIC_CHERRY_MACHINE_LIGHT_FX );

zm_perks::register_perk_threads( PERK_ELECTRIC_CHERRY, &electric_cherry_reload_attack , &electric_cherry_perk_lost  );

if( IS_TRUE( level.custom_electric_cherry_perk_threads ) )
{
level thread [[ level.custom_electric_cherry_perk_threads ]]();
}

init_electric_cherry();
}

function electric_cherry_precache()
{
if( IsDefined(level.electric_cherry_precache_override_func) )
{
[[ level.electric_cherry_precache_override_func ]]();
return;
}

level._effect[ELECTRIC_CHERRY_MACHINE_LIGHT_FX] = "_t6/misc/fx_zombie_cola_revive_on";

level.machine_assets[PERK_ELECTRIC_CHERRY] = SpawnStruct();
level.machine_assets[PERK_ELECTRIC_CHERRY].weapon = GetWeapon( ELECTRIC_CHERRY_PERK_BOTTLE_WEAPON );
level.machine_assets[PERK_ELECTRIC_CHERRY].off_model = ELECTRIC_CHERRY_MACHINE_DISABLED_MODEL;
level.machine_assets[PERK_ELECTRIC_CHERRY].on_model = ELECTRIC_CHERRY_MACHINE_ACTIVE_MODEL;
}

function electric_cherry_register_clientfield()
{
clientfield::register( "clientuimodel", PERK_CLIENTFIELD_ELECTRIC_CHERRY, VERSION_SHIP, 2, "int" );
}

function electric_cherry_set_clientfield( state )
{
self clientfield::set_player_uimodel( PERK_CLIENTFIELD_ELECTRIC_CHERRY, state );
}

function electric_cherry_perk_machine_setup( use_trigger, perk_machine, bump_trigger, collision )
{
use_trigger.script_sound = "mus_perks_ec_jingle";
use_trigger.script_string = "electriccherry_perk";
use_trigger.script_label = "mus_perks_ec_sting";
use_trigger.target = "vending_electriccherry";
perk_machine.script_string = "electriccherry_perk";
perk_machine.targetname = "vending_electriccherry";
if( IsDefined( bump_trigger ) )
{
bump_trigger.script_string = "electriccherry_perk";
}
}

//-----------------------------------------------------------------------------------
// functionality
//-----------------------------------------------------------------------------------
function init_electric_cherry()
{
level._effect[ "electric_cherry_explode" ] = "dlc1/castle/fx_castle_electric_cherry_down";

// Last Stand Attack
level.custom_laststand_func = &electric_cherry_laststand;

zombie_utility::set_zombie_var( "tesla_head_gib_chance", 50 );

// Perk specific Client Fields
clientfield::register( "allplayers", "electric_cherry_reload_fx", VERSION_SHIP, 2, "int" );
clientfield::register( "actor", "tesla_death_fx", VERSION_SHIP, 1, "int" );
clientfield::register( "vehicle", "tesla_death_fx_veh", VERSION_TU10, 1, "int" ); // Leave at VERSION_TU10
clientfield::register( "actor", "tesla_shock_eyes_fx", VERSION_SHIP, 1, "int" );
clientfield::register( "vehicle", "tesla_shock_eyes_fx_veh", VERSION_TU10, 1, "int" ); // Leave at VERSION_TU10
}

function electric_cherry_perk_machine_think()
{
init_electric_cherry();

while ( true )
{
machine = getentarray( "vendingelectric_cherry", "targetname" );
machine_triggers = GetEntArray( "vending_electriccherry", "target" );

// Show "inactive" models
for( i = 0; i < machine.size; i++ )
{
machine[i] SetModel( ELECTRIC_CHERRY_MACHINE_DISABLED_MODEL );
}

level thread zm_perks::do_initial_power_off_callback( machine, "electriccherry" );
array::thread_all( machine_triggers, &zm_perks::set_power_on, false );

level waittill( "electric_cherry_on" );

for( i = 0; i < machine.size; i++ )
{
machine[i] SetModel( ELECTRIC_CHERRY_MACHINE_ACTIVE_MODEL );
machine[i] vibrate( ( 0, -100, 0 ), 0.3, 0.4, 3 );
machine[i] playsound( "zmb_perks_power_on" );
machine[i] thread zm_perks::perk_fx( "electriccherry" );
machine[i] thread zm_perks::play_loop_on_machine();
}

level notify( "specialty_grenadepulldeath_power_on" );

array::thread_all( machine_triggers, &zm_perks::set_power_on, true );

level waittill( "electric_cherry_off" );

array::thread_all( machine_triggers, &zm_perks::turn_perk_off );
}
}

// when host migration occurs, fx don't carry over. If perk machine is on, turn the light back on.
function electric_cherry_host_migration_func()
{
a_electric_cherry_perk_machines = GetEntArray( "vending_electriccherry", "targetname" );

foreach( perk_machine in a_electric_cherry_perk_machines )
{
if( isDefined( perk_machine.model ) && perk_machine.model == ELECTRIC_CHERRY_MACHINE_ACTIVE_MODEL )
{
perk_machine zm_perks::perk_fx( undefined, true );
perk_machine thread zm_perks::perk_fx( "electriccherry" );
}
}
}

//-----------------------------------------------------------------------------------
// downed player releases a boom
//-----------------------------------------------------------------------------------

function electric_cherry_laststand()  //self = player
{
VisionSetLastStand( "zombie_last_stand", 1 );

if ( IsDefined( self ) )
{
PlayFX( level._effect[ "electric_cherry_explode" ], self.origin );
self PlaySound( "zmb_cherry_explode" );
self notify( "electric_cherry_start" );

//time for notify to go out
wait 0.05;

a_zombies = zombie_utility::get_round_enemy_array();
a_zombies = util::get_array_of_closest( self.origin, a_zombies, undefined, undefined, ELECTRIC_CHERRY_DOWNED_ATTACK_RADIUS );

for ( i = 0; i < a_zombies.size; i++ )
{
if ( IsAlive( self ) && IsAlive( a_zombies[ i ] ) )
{
if ( a_zombies[ i ].health <= ELECTRIC_CHERRY_DOWNED_ATTACK_DAMAGE )
{
a_zombies[ i ] thread electric_cherry_death_fx();

//for achievement tracking
if( IsDefined( self.cherry_kills ) )
{
self.cherry_kills++;
}

self zm_score::add_to_player_score( ELECTRIC_CHERRY_DOWNED_ATTACK_POINTS );  //add points only if zombie is killed
}

else
{
a_zombies[ i ] thread electric_cherry_stun();
a_zombies[ i ] thread electric_cherry_shock_fx();
}

wait 0.1;

a_zombies[ i ] DoDamage( ELECTRIC_CHERRY_DOWNED_ATTACK_DAMAGE, self.origin, self, self, "none" );
}
}
self notify( "electric_cherry_end" );
}
}


function electric_cherry_death_fx()  //self = zombie
{
self endon( "death" );

self PlaySound( "zmb_elec_jib_zombie" );

if ( !IS_TRUE( self.head_gibbed ) )
{
if( IsVehicle( self ) )
{
self clientfield::set( "tesla_shock_eyes_fx_veh", 1 );
}
else
{
self clientfield::set( "tesla_shock_eyes_fx", 1 );
}
}
else
{
if( IsVehicle( self ) )
{
self clientfield::set( "tesla_death_fx_veh", 1 );
}
else
{
self clientfield::set( "tesla_death_fx", 1 );
}
}
}


function electric_cherry_shock_fx()  //self = zombie
{
self endon( "death" );

if( IsVehicle( self ) )
{
self clientfield::set( "tesla_shock_eyes_fx_veh", 1 );
}
else
{
self clientfield::set( "tesla_shock_eyes_fx", 1 );
}

self PlaySound( "zmb_elec_jib_zombie" );

self waittill( "stun_fx_end" );

if( IsVehicle( self ) )
{
self clientfield::set( "tesla_shock_eyes_fx_veh", 0 );
}
else
{
self clientfield::set( "tesla_shock_eyes_fx", 0 );
}
}


function electric_cherry_stun()  //self = zombie
{
self endon("death");

self notify( "stun_zombie" );
self endon( "stun_zombie" );

if ( self.health <= 0 )
{
return;
}

//only stun the zombie if they are not in the find_flesh state
if ( self.ai_state !== "zombie_think" )
{
return;
}

// This immobilizes zombies because they're being shocked by electricity
self.zombie_tesla_hit = true;
self.ignoreall = true;

wait ELECTRIC_CHERRY_STUN_CYCLES; // wait time for stun to hold.

if( isdefined( self ) )
{
//set them back on course
self.zombie_tesla_hit = false;
self.ignoreall = false;

self notify( "stun_fx_end" );
}
}

//-----------------------------------------------------------------------------------
// Release an explosion when the player reloads
//-----------------------------------------------------------------------------------

function electric_cherry_reload_attack() // self = player
{
self endon( "death" );
self endon( "disconnect" );
self endon( PERK_ELECTRIC_CHERRY + "_stop" );

self.wait_on_reload = [];
self.consecutive_electric_cherry_attacks = 0;

while( true )
{
// Wait for the player to reload
self waittill("reload_start");

current_weapon = self GetCurrentWeapon();

// Don't use the perk if the weapon is waiting to be reloaded
if( IsInArray( self.wait_on_reload, current_weapon ) )
{
continue;
}

// Add this weapon to the list so we know it needs to be reloaded before the perk can be used for again
self.wait_on_reload[self.wait_on_reload.size] = current_weapon;

self.consecutive_electric_cherry_attacks++;

// Get the percentage of bullets left in the clip at the time the weapon is reloaded
// n_clip_current = self GetWeaponAmmoClip( str_current_weapon );
// n_clip_max = WeaponClipSize( str_current_weapon );
n_clip_current = 1;
n_clip_max = 10;
n_fraction = n_clip_current/n_clip_max;

perk_radius = math::linear_map( n_fraction, 1.0, 0.0, RELOAD_ATTACK_MIN_RADIUS, RELOAD_ATTACK_MAX_RADIUS );
perk_dmg = math::linear_map( n_fraction, 1.0, 0.0, RELOAD_ATTACK_MIN_DAMAGE, RELOAD_ATTACK_MAX_DAMAGE );

// Kick off a thread that will tell us when the weapon has been reloaded.
self thread check_for_reload_complete( current_weapon );

// Do the Electric Cherry Perk attack.  Logic should be the same as the "Laststand" attack.
if ( IsDefined( self ) )
{
// If the attack is being spammed, limit the number of zombies the attack can affect
switch( self.consecutive_electric_cherry_attacks )
{
case 0:
case 1:
n_zombie_limit = undefined;
break;

case 2:
n_zombie_limit = 8;
break;

case 3:
n_zombie_limit = 4;
break;

case 4:
n_zombie_limit = 2;
break;

default:
n_zombie_limit = 0;
}

// Start the Cooldown Timer
self thread electric_cherry_cooldown_timer( current_weapon );

if( IsDefined(n_zombie_limit) && (n_zombie_limit == 0) )
{
// The player has spammed the attack too much
// So don't actually perform the attack
// This prevents us from seeing/hearing the attack when it won't affect any zombies
continue;
}

self thread electric_cherry_reload_fx( n_fraction );
self notify( "electric_cherry_start" );
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 the limit of zombies is undefined, keep going and hit all zombies we can
if( IsDefined( n_zombie_limit ) )
{
// If the we're under the limit, increment the count of zombies
if( n_zombies_hit < n_zombie_limit )
{
n_zombies_hit++;
}
else
{
// If we're at the limit of zombies, don't kill any more zombies
break;
}
}

if ( a_zombies[ i ].health <= perk_dmg )
{
a_zombies[ i ] thread electric_cherry_death_fx();

//for achievement tracking
if( IsDefined( self.cherry_kills ) )
{
self.cherry_kills++;
}

self zm_score::add_to_player_score( RELOAD_ATTACK_POINTS );  //add points only if zombie is killed
}
else
{
if( !IsDefined(a_zombies[ i ].is_brutus) )
{
a_zombies[ i ] thread electric_cherry_stun();
}
a_zombies[ i ] thread electric_cherry_shock_fx();
}

wait 0.1;

if( isdefined( a_zombies[ i ] ) && IsAlive( a_zombies[ i ] ) ) // need to check again since we're post-wait
{
a_zombies[ i ] DoDamage( perk_dmg, self.origin, self, self, "none" );
}
}
}

self notify( "electric_cherry_end" );
}
}
}

function electric_cherry_cooldown_timer( current_weapon ) // self = player
{
self notify( "electric_cherry_cooldown_started" );
self endon( "electric_cherry_cooldown_started" );
self endon( "death" );
self endon( "disconnect" );

// Start the timer when the player reloads (when electric cherry attack starts)
// Cooldown time is equal to the weapon's reload time plus the global cooldown
//n_reload_time = WeaponReloadTime( current_weapon ); // TODO
n_reload_time = 0.25;
if( self HasPerk( "specialty_fastreload" ) )
{
n_reload_time *= GetDvarFloat( "perk_weapReloadMultiplier" );
}

n_cooldown_time = (n_reload_time + RELOAD_ATTACK_COOLDOWN_TIMER);

wait n_cooldown_time;

self.consecutive_electric_cherry_attacks = 0;
}

function check_for_reload_complete( weapon ) // self = player
{
self endon( "death" );
self endon( "disconnect" );
//self endon( "weapon_change_complete" );
self endon( "player_lost_weapon_" + weapon.name );

// Thread to watch for the case where this weapon gets replaced
self thread weapon_replaced_monitor( weapon );

while( 1 )
{
// Wait for the player to complete a reload
self waittill( "reload" );

// If the weapon that just got reloaded is the same as the one that was used for the electric cherry perk
// Kill off this thread and remove this weapon's name from the player's wait_on_reload list
// This allows the player to use the Electric Cherry Reload Attack with this weapon again!
current_weapon = self GetCurrentWeapon();
if( current_weapon == weapon )
{
ArrayRemoveValue( self.wait_on_reload, weapon );
self notify( "weapon_reload_complete_" + weapon.name );
break;
}
}
}

function weapon_replaced_monitor( weapon ) // self = player
{
self endon( "death" );
self endon( "disconnect" );
self endon( "weapon_reload_complete_" + weapon.name );

while( 1 )
{
// Wait for the player to change weapons (swap weapon, wall buy, magic box, etc.)
self waittill( "weapon_change" );

// If the weapon that we previously used for the Electric Cherry Reload Attack is no longer equipped
// Kill off this thread and remove this weapon's name from the player's wait_on_reload list
// This handles the case when a player cancels a reload, then replaces this weapon
// Ensures that when the player re-aquires the weapon, he has a fresh start and can use the Electric Cherry perk immediately.
primaryWeapons = self GetWeaponsListPrimaries();
if( !IsInArray( primaryWeapons, weapon ) )
{
self notify( "player_lost_weapon_" + weapon.name );
ArrayRemoveValue( self.wait_on_reload, weapon );
break;
}
}
}

function electric_cherry_reload_fx( n_fraction )
{
if( n_fraction >= 0.67 )
{
CodeSetClientField( self, "electric_cherry_reload_fx", 1 );
}
else if( (n_fraction >= 0.33) && (n_fraction < 0.67) )
{
CodeSetClientField( self, "electric_cherry_reload_fx", 2 );
}
else
{
CodeSetClientField( self, "electric_cherry_reload_fx", 3 );
}

wait ( 1.0 );

CodeSetClientField( self, "electric_cherry_reload_fx", 0 );
}

//////////////////////////////////////////////////////////////
//Perk lost func
//////////////////////////////////////////////////////////////
function electric_cherry_perk_lost( b_pause, str_perk, str_result )
{
self notify( PERK_ELECTRIC_CHERRY + "_stop" );
}
[/size][/size][/font]

Oh and new download :P
Last Edit: November 20, 2016, 04:10:46 am by Sidzzz
broken avatar :(
×
broken avatar :(
Pragmatist
Location: in
Date Registered: 9 May 2015
Last active: 7 months ago
Posts
451
Respect
Forum Rank
Perk Hacker
Primary Group
UGX Site Moderator
My Groups
More
My Contact & Social Links
More
Personal Quote
Fish. That is all
Signature
×
Sidzzz's Groups
UGX Site Moderator Has the ability to issue warnings to users, edit and remove posts from the forum and to move topics to other boards. Upholds the rules of the forum. Moderates Chat Rooms.
Sidzzz's Contact & Social LinkssidzzzzzzS1dzzzS1dzzzSidzzzSidTheGamer126
Modified Original Post to include the updated version of the tutorial.
broken avatar :(
×
broken avatar :(
Location: usAnywhere but here
Date Registered: 31 October 2016
Last active: 6 years ago
Posts
32
Respect
Forum Rank
Legless Crawler
Primary Group
Member
×
worstgabena's Groups
worstgabena's Contact & Social Links
Thanks for updating it  :)
broken avatar :(
×
broken avatar :(
Location: us
Date Registered: 9 December 2016
Last active: 3 years ago
Posts
2
Respect
Forum Rank
Fresh Corpse
Primary Group
Member
×
Fantic's Groups
Fantic's Contact & Social Links
How can I make this give more than just Electric Cherry?

 
Loading ...