June 01, 2023, 02:25:30 pm

The Gang Garrison 2 Forum

Please login or register.

Login with username, password and session length
Advanced search  

News:

NOTICE: Due to a rise in bot activity, new posters need to be approved before posting.

Join the community Discord server!

Pages: [1]

Author Topic: [Plugin] - [MTK5012] - [Server-Sent Plugin] [Versus Heroes]  (Read 5520 times)

MTK5012

  • 2011 Haxxy Finalist
  • *
  • Karma: 0
  • Offline Offline
  • Posts: 773
  • if (ping <= 150) jaw.y += 100;
[Plugin] - [MTK5012] - [Server-Sent Plugin] [Versus Heroes]
« on: August 17, 2013, 08:28:52 pm »

Description: this is a a server-sent plugin which gives GG2 a new game mode and doesn't affect other game modes
It will turn any arena map that starts with "vsh_" into a "Versus Hale Haxton Heroes" mode

How to use:
- The plugin's name is "vsh" (without quotes)
- include the plugin in the ini (how)
- include arena maps that start with "vsh_" in the map rotation
- ONLY HOST VSH MAPS, I made a mistake that "destroyed" other game modes and I will fix it next build

Features:
- there will be only one BLU with a huge hp pool and melee attack, all other REDs will have to fight them
- capture is slower than it is shown
- humiliation slow you down a lot
(click to show/hide)
(click to show/hide)

Notes:
- REMEMBER to include atleast an arena map starts with "vsh_" into the map rotation
- if you are forced to change team in the new round, your class will change to scout (class limit bug?)
- spy stab humiliate longer than intended (bug)
- this plugin is hastily made for haxxy (I went offline for a long time) so it is heavily unbalanced, there will be more bugs
- this is unfinished: no new sprites (that's why i named it vs heroes instead of haxton) nor sound

Code for anyone who wants to look at (give me suggestions if you can)
Code: [Select]
/*VERSUS HAXTON PLUGIN*/
//By MTK5012//

global.vsh = 0;
global.vshBoss = -1;
global.vshBuffer = buffer_create();

//HUD//
object_event_add(ArenaHUD, ev_draw, 0, "
    if (global.vsh > 0) {
        var boss;
        if (ds_list_find_value(global.players,global.vshBoss))
            boss = (ds_list_find_value(global.players,global.vshBoss)).object;
        else
            boss = -1;
        if (boss != -1) {
            draw_healthbar(view_xview+120, view_yview+20, view_xview+240, view_yview+40, boss.hp*100/boss.maxHp, c_black, c_red, c_green, 0, true, false);
            var superJump,canRage;
            superJump = 0;
            canRage = 0;
            with (boss) {
                if (variable_local_exists('vshSuperJump'))
                    if (vshSuperJump == 0)
                        superJump = 1;
                if (player.class == CLASS_SPY or player.class == CLASS_ENGINEER or player.class == CLASS_HEAVY or player.class == CLASS_SNIPER)
                    superJump = 0;
                if (variable_local_exists('vshRage'))
                    if (vshRage >= 700)
                        canRage = 1;
            }
            if (superJump)
                draw_text(view_xview+180, view_yview+60, 'Super jump ready!');
            if (canRage)
                draw_text(view_xview+180, view_yview+80, 'Rage ready!');
        }
    }
");

object_event_add(PlayerControl , ev_step, ev_step_begin, "
    //DETECT VS HALE MAPS//
    if (global.vsh == 0 and string_copy(global.currentMap, 0, 4) == 'vsh_' and instance_exists(ArenaHUD))
        global.vsh = 1;
    if (global.vsh > 0 and (string_copy(global.currentMap, 0, 4) != 'vsh_' or !instance_exists(ArenaHUD)))
        global.vsh = 0;
");

object_event_add(GameServer, ev_step, ev_step_begin, "
    //RESTART//
    if (global.vsh == 2)
        if (ArenaHUD.roundStart == 299)
            global.vsh = 1;

    //PICK BOSS//
    if (!ds_list_find_value(global.players, global.vshBoss) or global.vsh == 1) {
        global.vshBoss = floor(random(ds_list_size(global.players)));
        if (ArenaHUD.roundStart > 0)
            global.vsh = 1;
    }

    //I DONT WANNA BE THE BOSS//
    //not gonna happen but i'll keep it here any way
    if (ds_list_find_value(global.players, global.vshBoss))
        if ((ds_list_find_value(global.players, global.vshBoss)).team == TEAM_RED) {
            global.vshBoss = floor(random(ds_list_size(global.players)));
            if (ArenaHUD.roundStart > 0)
                global.vsh = 1;
        }
    
    //MORE THAN 1 BLUE//
    //after the pick boss to prevent cheaters
    if (global.vsh == 2)
        if (ArenaHUD.roundStart > 0 and ds_list_find_value(global.players, global.vshBoss)) {
            var i,noOfBlu;
            noOfBlu = 0;
            for (i = 0; i < ds_list_size(global.players); i += 1) {
                if ((ds_list_find_value(global.players,i)).team == TEAM_BLUE)
                    noOfBlu += 1;
            }
            if (noOfBlu > 1)
                global.vsh = 1;
        }

    //REARRANGE TEAM//
    if (global.vsh == 1) {
        global.vsh = 2;
        var playerId;
        with (Player) {
            playerId = ds_list_find_index(global.players, id);
            //fighters
            if (team == TEAM_BLUE and global.vshBoss != playerId) {
                if(object != -1) {
                    with(object) {
                        //not sure if i need this
                        sendEventPlayerDeath(player, player, noone, BID_FAREWELL);
                        doEventPlayerDeath(player, player, noone, BID_FAREWELL);
                    }
                    alarm[5] = global.Server_Respawntime;
                }
                else if(alarm[5]<=0)
                    alarm[5] = 1;                    
                var newClass;
                newClass = checkClasslimits(TEAM_RED, class);
                if newClass != class {
                    class = newClass;
                    ServerPlayerChangeclass(playerId, class, global.sendBuffer);
                }
                team = TEAM_RED;
                ServerPlayerChangeteam(playerId, TEAM_RED, global.sendBuffer);
            }

            //boss
            if (team == TEAM_RED and global.vshBoss == playerId) {
                if(object != -1) {
                    with(object) {
                        sendEventPlayerDeath(player, player, noone, BID_FAREWELL);
                        doEventPlayerDeath(player, player, noone, BID_FAREWELL);
                    }
                    alarm[5] = global.Server_Respawntime;
                }
                else if(alarm[5]<=0)
                    alarm[5] = 1;
                var newClass;
                newClass = checkClasslimits(TEAM_BLUE, class);
                if newClass != class {
                    class = newClass;
                    ServerPlayerChangeclass(playerId, class, global.sendBuffer);
                }
                team = TEAM_BLUE;
                ServerPlayerChangeteam(playerId, TEAM_BLUE, global.sendBuffer);
            }

            //increase cap time
            with (ArenaControlPoint)
                capTime = 900;
        }
    }

    //SEND DATA TO CLIENT//
    if (global.vsh > 0)
    {
            write_ubyte(global.vshBuffer, ds_list_size(global.players));
            //humiliated, is boss
            var i,tempbyte;
            for (i = 0; i < ds_list_size(global.players); i += 1) {
                tempbyte = 0;
                if (ds_list_find_value(global.players,i).humiliated)
                    tempbyte |= 1;
                if (global.vshBoss = i)
                    tempbyte |= 2;
                write_ubyte(global.vshBuffer, tempbyte);
            }

            //boss's hp, super jump and rage
            var boss;
            if (ds_list_find_value(global.players,global.vshBoss))
                boss = (ds_list_find_value(global.players,global.vshBoss)).object;
            else
                boss = -1;
            if (boss != -1) {
                with (boss) {
                    write_uint(global.vshBuffer, hp);
                    tempbyte = 0;
                    if (variable_local_exists('vshSuperJump'))
                        if (vshSuperJump == 0)
                            tempbyte |= 1;
                    if (variable_local_exists('vshRage'))
                        if (vshRage >= 700)
                            tempbyte |= 2;
                    write_ubyte(global.vshBuffer, tempbyte);
                }
            }

            PluginPacketSend(argument1, global.vshBuffer);
            buffer_clear(global.vshBuffer);
    }
");

//normal step to override serialize state
//might cause delay for 1 step when a player leave
object_event_add(Client, ev_step, ev_step_normal, "
    //RECEIVE DATA FROM SERVER//
    if (global.vsh > 0) {
        if (PluginPacketGetBuffer(argument1) != -1) {
            global.vshBuffer = PluginPacketGetBuffer(argument1);
            if (read_ubyte(global.vshBuffer) != ds_list_size(global.players)) {
                buffer_clear(global.vshBuffer);
                PluginPacketPop(argument1);
                exit;
            }
            var i,tempbyte;

            //humiliation, isBoss
            for (i = 0; i < ds_list_size(global.players); i += 1) {
                tempbyte = read_ubyte(global.vshBuffer);
                (ds_list_find_value(global.players,i)).humiliated = tempbyte & 1;
                if ((tempbyte & 2) > 0)
                    global.vshBoss = i;
            }

            //boss's hp, super jump and rage
            var boss;
            if (ds_list_find_value(global.players,global.vshBoss))
                boss = (ds_list_find_value(global.players,global.vshBoss)).object;
            else
                boss = -1;
            if (boss != -1) {
                with (boss) {
                    hp = read_uint(global.vshBuffer);
                    tempbyte = read_ubyte(global.vshBuffer);
                    if (variable_local_exists('vshSuperJump')) {
                        if ((tempbyte & 1) > 0)
                            vshSuperJump = 0;
                        else
                            vshSuperJump = 30;
                    }
                    if (variable_local_exists('vshRage')) {
                        if ((tempbyte & 2) > 0)
                            vshRage = 700;
                        else
                            vshRage = 0;
                    }
                }
            }

            buffer_clear(global.vshBuffer);
            PluginPacketPop(argument1);
        }
    }
");

//BOSS//
object_event_add(Character, ev_create, 0, "
    if (global.vsh > 0) {
        if (team = TEAM_BLUE) {
            //hp based on number of players
            var i,noOfRed;
            noOfRed = 0;
            for (i = 0; i < ds_list_size(global.players); i += 1) {
                if (ds_list_find_value(global.players,i).team == TEAM_RED)
                    noOfRed += 1;
            }
            maxHp = 250+200*noOfRed+50*(noOfRed+1)*(noOfRed/2);

            //heavy and quote have metal skin
            if (player.class == CLASS_HEAVY or player.class == CLASS_QUOTE)
                maxHp = floor(maxHp*1.2);

            //engi is fragile
            if (player.class == CLASS_ENGINEER)
                maxHp = floor(maxHp*0.7);

            hp = maxHp;
            runPower = 0.9;
            if (player.class != CLASS_SNIPER)
                currentWeapon.visible = false;
        } else {
            //increase sniper max damage
            if (player.class == CLASS_SNIPER)
                with (currentWeapon)
                    maxDamage = 110;
            
            //nerf quote
            if (player.class == CLASS_QUOTE)
                with (currentWeapon) {
                    bladeLife = 4;
                    maxBubbles = 0;
                }

            //heal 1hp/s if not hurt for 3s
            alarm[11] = 30;
        }
    }
");

//boss's sentry is invulnerable except against spy
object_event_add(Sentry, ev_step, ev_step_begin, "
    if (global.vsh > 0) {
        if (ownerPlayer.team == TEAM_BLUE) {
            hp = maxHp;
        }
    }
");

object_event_add(Character, ev_step, ev_step_begin, "
    if (global.vsh > 0) {
        if (team == TEAM_BLUE) {

            //recharge
            if (!variable_local_exists('vshCoolDown'))
                vshCoolDown = 0;
            if (vshCoolDown > 0)
                vshCoolDown -= 1;
            if (!variable_local_exists('vshSuperJump'))
                vshSuperJump = 0;
            if (vshSuperJump > 0)
                vshSuperJump -= 1;
            if (!variable_local_exists('vshAttack'))
                vshAttack = 0;
            if (vshAttack > 0)
                vshAttack -= 1;
            currentWeapon.readyToShoot = 0;
            currentWeapon.ammoCount = 0;

            //super jump
            if (player.class != CLASS_SPY and player.class != CLASS_ENGINEER and player.class != CLASS_HEAVY and player.class != CLASS_SNIPER
            and !taunting and !omnomnomnom and !player.humiliated and (keyState | pressedKeys) & $08 and vshSuperJump == 0 and place_meeting(x,y+1,Obstacle)) {
                vshSuperJump = 450;
                motion_add(aimDirection, 15);
                moveStatus = 1;
                playsound(x,y,CompressionBlastSnd);
            }

            //attack
            if (!invisible and cloakAlpha == 1 and !taunting and !omnomnomnom and !player.humiliated and (keyState | pressedKeys) & $10 and vshCoolDown == 0) {
                //sniper use bow
                if (player.class == CLASS_SNIPER) {
                    var shot;
                    shot = instance_create(x,y,Shot);
                    shot.direction = aimDirection;
                    shot.speed = 20;
                    shot.owner = id;
                    shot.ownerPlayer = player;
                    shot.team = team;
                    shot.hitDamage = currentWeapon.hitDamage;
                    shot.weapon = WEAPON_RIFLE_CHARGED;
                    with(shot)
                        speed += owner.hspeed*hspeed/15;
                    vshCoolDown = 45;
                    playsound(x,y,RevolverSnd);
                }
                else {
                    vshCoolDown = 30;
                    vshAttack = 4;
                    playsound(x,y,BladeSnd);
                }
            }

            //HAXTON SAAAALLLEEEE!!!
            if (!variable_local_exists('vshRage'))
                vshRage = 0;
            if (taunting and vshRage >= 700) {
                vshRage = 0;
                playsound(x,y,UberStartSnd);
                with (Character) {
                    if ((point_distance(x,y,other.x,other.y) < 400 or (ds_list_find_value(global.players,global.vshBoss)).class == CLASS_SOLDIER) and team = TEAM_RED) {
                        player.humiliated = 1;
                        player.alarm[11] = 5*30+other.tauntlength/other.tauntspeed;
                        if ((ds_list_find_value(global.players,global.vshBoss)).class == CLASS_SOLDIER)
                            player.alarm[11] = 8*30+other.tauntlength/other.tauntspeed;
                    }
                }
            }
        }
    }
");

//melee attack
object_event_add(Character, ev_collision, Character, "
    if (variable_local_exists('vshAttack') and global.vsh > 0) {
        if (vshAttack > 0 and other.team != team and player.class != CLASS_SNIPER and other.ubered == 0) {
            playsound(x,y,choose(DeathSnd1, DeathSnd2));
            vshAttack = 0;
            other.hp -= 75;
            other.timeUnscathed = 0;
            if (other.lastDamageDealer != player && other.lastDamageDealer != other.player) {
                other.secondToLastDamageDealer = other.lastDamageDealer;
                other.alarm[4] = other.alarm[3];
            }
            other.alarm[3] = ASSIST_TIME;
            other.lastDamageDealer = player;
            other.lastDamageSource = 0;
            var blood;
            if(global.gibLevel > 0) {
                blood = instance_create(x,y,Blood);
                blood.direction = direction-180;
            }
            with(other) {
                motion_add(other.direction, other.speed*0.03);
                cloakAlpha = max(cloakAlpha, 0.3);
                cloakFlicker = true;
                alarm[7] = 3;
            }

            //spy weak attack
            if (player.class == CLASS_SPY)
                other.hp += 40;
    
            //pyro burning attack
            if (!object_is_ancestor(other.object_index, Pyro) and player.class == CLASS_PYRO) {
                other.burnDuration += 210;
                other.burnIntensity += 9;
                other.burnDuration = min(other.burnDuration, other.maxDuration);
                other.burnIntensity = min(other.burnIntensity, other.maxIntensity);
                other.burnedBy = player;
                other.afterburnSource = 0;
                other.alarm[0] = other.decayDelay;
            }

            //knock back
            with (other)
                motion_add(other.aimDirection, 12);

            //demoman leech health and gain rage if kill
            if (player.class == CLASS_DEMOMAN) {
                hp += maxHp/50;
            if (!variable_local_exists('vshRage'))
                vshRage = 0;
            if (other.hp <= 0)
                vshRage += 50;
            }
        }
    }
");

//attack sentry
object_event_add(Character, ev_collision, Sentry, "
    if (variable_local_exists('vshAttack') and global.vsh > 0) {
        if (vshAttack > 0 and other.team != team and player.class != CLASS_SNIPER) {
            playsound(x,y,KnifeSnd);
            other.hp -= 75;
            vshAttack = 0;
            //spy weak attack
            if (player.class == CLASS_SPY)
                other.hp += 40;
            other.lastDamageDealer = player;
            other.lastDamageSource = 0;
        }
    }
");

//attack sprite place holder
object_event_add(Character, ev_draw, 0, "
    if (variable_local_exists('vshAttack') and global.vsh > 0) {
        if (vshAttack > 0 and player.class != CLASS_SNIPER) {
            draw_sprite(BladeProjectileS,vshAttack-1,x,y);
        }
    }
");


object_event_add(Character, ev_step, ev_step_end, "
    if (global.vsh > 0) {
        if (!variable_local_exists('oldHp'))
            oldHp = hp;
        if (team == TEAM_BLUE) {
            if (!variable_local_exists('vshRage'))
                vshRage = 0;

            //equalizer
            runPower = 1.5-0.6*(hp/maxHp);

            //scout's speed maxed
            if (player.class == CLASS_SCOUT)
                runPower = 1.5-0.35*(hp/maxHp);

            //spy stabbing
            if (stabbing)
                runPower *= 0.7;

            //sniper zoom
            if (zoomed)
                runPower *= 0.7;

            //heavy eating
            if (omnomnomnom)
                hp = min(maxHp,hp+maxHp/1000-1.6);

            //hurt = slow, build rage
            if (hp < oldHp) {
                vshRage = vshRage+oldHp-hp;
                speed *= 0.9;

                //heavy block damage
                if (player.class == CLASS_HEAVY)
                    hp = min(oldHp,hp+2);
            }

            //it's humiliating to be stabbed
            if (lastDamageSource == WEAPON_BACKSTAB or lastDamageSource == WEAPON_KNIFE) {
                 player.humiliated = true;
                 player.alarm[11] = 45;
                 if (lastDamageDealer.object != -1)
                     lastDamageDealer.object.hp = maxHp; //reward for spy
            }
        }

        oldHp = hp;

        //humiliation slow
        if (player.humiliated)
            hspeed *= 0.8;
    }
");

object_event_add(Character, ev_alarm, 11, "
    if (global.vsh > 0 and team == TEAM_RED and timeUnscathed >= 90)
        hp += 1;
    if (global.vsh > 0 and team == TEAM_BLUE and player.class == CLASS_MEDIC)
        hp += maxHp/400;
    alarm[11] = 30;
");

object_event_add(Player, ev_alarm, 11, "
    humiliated = false;
");

And I know that I'm a messy coder / grammar mistake maker, point out the mistakes if you spot them

I will need suggestions to keep this plugin enjoyable. If there is someone out there who can make good sprites and willing to help, I will need a Haxton Sale sprite and a punching arm animation (length: 4 images) (Haven't decided about other classes though)

sy

  • 2013 Haxxy Award Winner
  • *
  • Karma: 3
  • Offline Offline
  • Posts: 1184
  • sup
Re: [Plugin] - [MTK5012] - [Server-Sent Plugin] [Versus Heroes]
« Reply #1 on: August 17, 2013, 09:13:39 pm »


from bluedragon
also, you know this is already in randomizer

iLegend

  • 2013 Haxxy Award Winner
  • *****
  • Karma: 0
  • Offline Offline
  • Posts: 869
  • Force is always the answer.
    • Mah Resume
Re: [Plugin] - [MTK5012] - [Server-Sent Plugin] [Versus Heroes]
« Reply #2 on: August 17, 2013, 09:33:30 pm »

this... this is cool.
I'd suggest altering the one BLU's stats based on # of reds, as 1v3 is different from 1v13 (if you were on a standard 12-16 player server for instance)
Logged
<SecretMan> do i put BotAim.gml in plugins folder?
i hear los angeles is pretty good for casual sex with minors

MTK5012

  • 2011 Haxxy Finalist
  • *
  • Karma: 0
  • Offline Offline
  • Posts: 773
  • if (ping <= 150) jaw.y += 100;
Re: [Plugin] - [MTK5012] - [Server-Sent Plugin] [Versus Heroes]
« Reply #3 on: August 17, 2013, 10:42:20 pm »


from bluedragon
also, you know this is already in randomizer
yes but randomizer is pretty much dead, I could use the sprites however
I'd suggest altering the one BLU's stats based on # of reds, as 1v3 is different from 1v13 (if you were on a standard 12-16 player server for instance)
already  :z5:, the hp calculation is 250+200*#reds+(#reds+1)*(#reds/2) (for now)

iLegend

  • 2013 Haxxy Award Winner
  • *****
  • Karma: 0
  • Offline Offline
  • Posts: 869
  • Force is always the answer.
    • Mah Resume
Re: [Plugin] - [MTK5012] - [Server-Sent Plugin] [Versus Heroes]
« Reply #4 on: August 17, 2013, 10:50:54 pm »

hrmm is that based off of anything?
I don't get why you have the (r+1)*(r/2)
If you look at the plot
that last bit does almost nothing, it's practically linear anyway.

I also dislike linear, for ex, from the plot, 6 people vs 1500hp is far harder than 14 people vs 3000hp
you could modify the constants but i'd suggest something along n^2 or nlog(n)
Logged
<SecretMan> do i put BotAim.gml in plugins folder?
i hear los angeles is pretty good for casual sex with minors

MTK5012

  • 2011 Haxxy Finalist
  • *
  • Karma: 0
  • Offline Offline
  • Posts: 773
  • if (ping <= 150) jaw.y += 100;
Re: [Plugin] - [MTK5012] - [Server-Sent Plugin] [Versus Heroes]
« Reply #5 on: August 17, 2013, 11:05:51 pm »

the plugin is up and it'll need some testing (anyone?)

hrmm is that based off of anything?
I don't get why you have the (r+1)*(r/2)
If you look at the plot
that last bit does almost nothing, it's practically linear anyway.

I also dislike linear, for ex, from the plot, 6 people vs 1500hp is far harder than 14 people vs 3000hp
you could modify the constants but i'd suggest something along n^2 or nlog(n)

my bad, it's 250+200*#reds+50*(#reds+1)*(#reds/2)
it's basically a less curved parabola
I don't know which curve should I do: 1,2,4,8 or 4,7,9,10 so this is just a place holder

iLegend

  • 2013 Haxxy Award Winner
  • *****
  • Karma: 0
  • Offline Offline
  • Posts: 869
  • Force is always the answer.
    • Mah Resume
Re: [Plugin] - [MTK5012] - [Server-Sent Plugin] [Versus Heroes]
« Reply #6 on: August 17, 2013, 11:10:58 pm »

>it'll need some testing
I thought server sent plugins needed to be verified by ajf?

I have no idea if the hp curve is good right now, no idea how it'll play out.

Also, I recommend recording the highest score player from the previous game, and using that player as the boss. If you randomly picked someone who sucked at the game, it'd just be a pretty quick and stupid game.
Logged
<SecretMan> do i put BotAim.gml in plugins folder?
i hear los angeles is pretty good for casual sex with minors

MTK5012

  • 2011 Haxxy Finalist
  • *
  • Karma: 0
  • Offline Offline
  • Posts: 773
  • if (ping <= 150) jaw.y += 100;
Re: [Plugin] - [MTK5012] - [Server-Sent Plugin] [Versus Heroes]
« Reply #7 on: August 18, 2013, 12:43:28 am »

>it'll need some testing
I thought server sent plugins needed to be verified by ajf?
I mean balance test, which require the pubs
I have no idea if the hp curve is good right now, no idea how it'll play out.
me too
Also, I recommend recording the highest score player from the previous game, and using that player as the boss. If you randomly picked someone who sucked at the game, it'd just be a pretty quick and stupid game.
okay, will add in the future

It looks like I have made a dumb mistake that destroy other game modes, I will fix it next update, in the mean time I will try to host a "vsh_" maps only server to test never mind my ping sucks
Pages: [1]
 

Page created in 0.038 seconds with 36 queries.