[RELEASE] bouncing betty in mw2
Featured Replies
Сейчас на странице 0
- Нет пользователей, просматривающих эту страницу
A better way to browse. Learn more.
A full-screen app on your home screen with push notifications, badges and more.
Используя этот сайт, вы соглашаетесь Условия использования.
here is the code (_bouncing.gsc)
#include common_scripts\utility; #include maps\mp\_utility; init() { level.mineDetectionGracePeriod = .3; level.mineDetectionRadius = 100; level.mineDetectionHeight = 20; level.mineDamageRadius = 256; level.mineDamageMin = 70; level.mineDamageMax = 210; level.mineDamageHalfHeight = 46; level.mineSelfDestructTime = 120; level.mine_launch = loadfx("impacts/20mm_default_impact"); //level.mine_spin = loadfx( "dust/bouncing_betty_swirl" ); level.mine_explode = loadfx ("explosions/grenadeexp_default"); level.mine_beacon["enemy"] = loadfx( "misc/aircraft_light_red_blink" ); level.mine_beacon["friendly"] = loadfx( "misc/aircraft_light_wingtip_green" ); level.delayMineTime = 3.0; level.mine_model="mil_emergency_flare_mp";//"projectile_concussion_grenade";//"mil_tntbomb_mp";//"projectile_bouncing_betty_grenade";//"projectile_concussion_grenade"; level.mines = []; level thread onPlayerConnect(); } onPlayerConnect() { for(; { level waittill("connected", player); player.bouncing_betty=0; player.hasMine=undefined; player thread onPlayerSpawned(); } } onPlayerSpawned() { self endon("disconnect"); for(; { self waittill("spawned_player"); self thread watchMineUsage(); } } spawnMine( origin, owner, type, angles ) { Assert( isDefined( owner ) ); if ( !isDefined( angles ) ) angles = (0, RandomFloat(360), 0); model = level.mine_model; mine = Spawn( "script_model", origin); mine.angles = angles; mine SetModel( model ); mine.owner = owner; mine.weaponName = "bouncingbetty_mp"; level.mines[level.mines.size] = mine; killCamOrigin = ( mine.origin + ( ( AnglesToForward( mine.angles ) * -150 ) + ( AnglesToRight( mine.angles ) * -150 ) ) ) + ( 0, 0, -50 ); //mine.killCamOffset = ( 0, 0, 4 ); mine.killCamEnt = Spawn( "script_model", killCamOrigin);//mine.origin + mine.killCamOffset); if ( !isDefined( type ) || type == "equipment" ) { owner.equipmentMines = array_removeUndefined( owner.equipmentMines ); if( owner.equipmentMines.size >= level.maxPerPlayerExplosives ) owner.equipmentMines[0] delete(); owner.equipmentMines[ owner.equipmentMines.size ] = mine; } else { owner.killstreakMines[ owner.killstreakMines.size ] = mine; } mine thread mineBeacon(); mine thread setClaymoreTeamHeadIcon( owner.pers[ "team" ] ); mine thread mineDamageMonitor(mine); mine thread mineProximityTrigger(); mine thread mineSelfDestruct(); return mine; } setClaymoreTeamHeadIcon( team ) { self endon( "death" ); wait .05; if ( level.teamBased ) self maps\mp\_entityheadicons::setTeamHeadIcon( team, ( 0, 0, 20 ) ); else if ( isDefined( self.owner ) ) self maps\mp\_entityheadicons::setPlayerHeadIcon( self.owner, (0,0,20) ); } mineDamageMonitor() { self endon( "mine_triggered" ); self endon( "mine_selfdestruct" ); self endon( "death" ); self setcandamage( true ); self.maxhealth = 100000; self.health = self.maxhealth; attacker = undefined; while ( 1 ) { self waittill( "damage", damage, attacker, direction_vec, point, type, modelName, tagName, partName, iDFlags, weapon ); if ( !isPlayer( attacker ) || isDefined( weapon ) && weapon == "bouncingbetty_mp" ) continue; // don't allow people to destroy mines on their team if FF is off if ( !maps\mp\gametypes\_weapons::friendlyFireCheck( self.owner, attacker ) ) continue; if( IsDefined( weapon ) ) { switch( weapon ) { //case "concussion_grenade_mp": //case "flash_grenade_mp": case "smoke_grenade_mp": continue; } } break; } self notify( "mine_destroyed" ); if ( isDefined( type ) && ( isSubStr( type, "MOD_GRENADE" ) || isSubStr( type, "MOD_EXPLOSIVE" ) ) ) self.wasChained = true; if ( isDefined( iDFlags ) && ( iDFlags & level.iDFLAGS_PENETRATION ) ) self.wasDamagedFromBulletPenetration = true; self.wasDamaged = true; if ( level.teamBased ) { // "destroyed_explosive" notify, for challenges if ( isdefined( attacker ) && isdefined( attacker.pers[ "team" ] ) && isdefined( self.owner ) && isdefined( self.owner.pers[ "team" ] ) ) { if ( attacker.pers[ "team" ] != self.owner.pers[ "team" ] ) attacker notify( "destroyed_explosive" ); } } else { // checking isDefined attacker is defensive but it's too late in the project to risk issues by not having it if ( isDefined( self.owner ) && isDefined( attacker ) && attacker != self.owner ) attacker notify( "destroyed_explosive" ); } self thread mineExplode( attacker ); } mineProximityTrigger() { self endon( "mine_destroyed" ); self endon( "mine_selfdestruct" ); self endon( "death" ); // arming time wait( 2 ); trigger = Spawn( "trigger_radius", self.origin, 0, level.mineDetectionRadius, level.mineDetectionHeight ); self thread mineDeleteTrigger( trigger ); player = undefined; while ( 1 ) { trigger waittill( "trigger", player ); if ( getdvarint( "scr_minesKillOwner" ) != 1 ) { if ( isDefined( self.owner ) && player == self.owner ) continue; if ( !maps\mp\gametypes\_weapons::friendlyFireCheck( self.owner, player, 0 ) ) continue; } // if ( lengthsquared( player getEntityVelocity() ) < 10 )//ojo // continue; if ( player damageConeTrace( self.origin, self ) > 0 ) break; } self notify( "mine_triggered" ); self playsound( "claymore_activated" ); if ( IsPlayer( player ) && player _hasPerk( "specialty_delaymine" ) ) { player notify( "triggered_mine" ); wait level.delayMineTime; } else wait level.mineDetectionGracePeriod; self thread mineBounce(); } mineDeleteTrigger( trigger ) { self waittill_any( "mine_triggered", "mine_destroyed", "mine_selfdestruct", "death" ); trigger delete(); } mineSelfDestruct() { self endon( "mine_triggered" ); self endon( "mine_destroyed" ); self endon( "death" ); wait( level.mineSelfDestructTime ); wait RandomFloat( 0.4 ); self notify( "mine_selfdestruct" ); self thread mineExplode(); } // TODO: // Handle a drop outside of a level, like highrise. // Spawn protection against these. "protect players from spawnkill grenades" // Killcam doesn't fly up. Probably needs code. mineBounce() { self playsound ( "sentry_steam" ); self playsound( "sentry_minigun_spinup1" ); playFX( level.mine_launch, self.origin); self notify("jump"); if (isDefined(self.entityHeadIcon)) self.entityHeadIcon destroy(); explodePos = self.origin + (0, 0, 64); self MoveTo( explodePos, 0.7, 0, .65 ); self.killCamEnt MoveTo( explodePos + self.killCamOffset, 0.7, 0, .65 ); self RotateVelocity( (0, 750, 32), 0.7, 0, .65 ); wait( 0.65 ); self thread mineExplode(); } mineExplode( attacker ) { if ( !IsDefined( self ) || !IsDefined(self.owner) ) return; // using a passed in attacker means that the owner wasn't the one who detonated this, this way the correct credit will go to the correct player if( !IsDefined( attacker ) ) attacker = self.owner; self PlaySound( "grenade_explode_metal" ); self notify("mine_explode"); PlayFX( level.mine_explode, self.origin ); wait( 0.05 ); // needed or the effect doesn't play if ( !IsDefined( self ) || !IsDefined(self.owner) ) return; self Hide(); self RadiusDamage( self.origin, level.mineDamageRadius, level.mineDamageMax, level.mineDamageMin, attacker, "MOD_EXPLOSIVE", "bouncingbetty_mp" ); wait( 0.2 ); if ( !IsDefined( self ) || !IsDefined(self.owner) ) return; if ( IsDefined( self.trigger ) ) self.trigger delete(); self.killCamEnt delete(); self delete(); } /*mineDamagePassed( damageCenter, recieverCenter, radiusSq, ignoreEnt ) { damageTop = damageCenter[2] + level.mineDamageHalfHeight; damageBottom = damageCenter[2] - level.mineDamageHalfHeight; if ( recieverCenter[2] > damageTop || recieverCenter[2] < damageBottom ) return false; distSq = distanceSquared( damageCenter, recieverCenter ); if ( distSq > radiusSq ) return false; if ( !weaponDamageTracePassed( damageCenter, recieverCenter, 0, ignoreEnt ) ) return false; return true; } mineDamageHeightPassed( mine, victim ) { if ( isPlayer( victim ) && isAlive( victim ) && victim.sessionstate == "playing" ) victimPos = victim getStanceCenter(); else if ( victim.classname == "misc_turret" ) victimPos = victim.origin + ( 0, 0, 32 ); else victimPos = victim.origin; tempZOffset = 0; //66 damageTop = mine.origin[2] + tempZOffset + level.mineDamageHalfHeight; //46 damageBottom = mine.origin[2] + tempZOffset - level.mineDamageHalfHeight; if ( victimPos[2] > damageTop || victimPos[2] < damageBottom ) return false; return true; } */ watchMineUsage() { self endon( "disconnect" ); self endon( "spawned_player" ); if ( isDefined( self.equipmentMines ) ) { if ( getIntProperty( "scr_deleteexplosivesonspawn", 1 ) == 1 ) { self.equipmentMines = array_removeUndefined( self.equipmentMines ); foreach ( equipmentMine in self.equipmentMines ) { if ( isDefined( equipmentMine.trigger ) ) equipmentMine.trigger delete(); equipmentMine delete(); } } } else { self.equipmentMines = []; } if ( !isDefined( self.killstreakMines ) ) self.killstreakMines = []; thread mineDeleteOnDisconnect(); if (self.bouncing_betty>0) { self equipmentON(); self iprintlnbold("Press ^3[{+frag}] ^7to plant a Bouncing Betty"); } for ( ;; ) { self waittill( "grenade_fire", projectile, weaponName ); if ( self.bouncing_betty>0 && isDefined(self.hasMine) && weaponName == "c4_mp" ) { if( !IsAlive( self ) ) { projectile delete(); return; } self.hasDoneCombat = true; self.bouncing_betty--; projectile hide();//esto sirve para algo??? ojo projectile setmodel(level.mine_model); projectile thread mineThrown( self ); if (self.bouncing_betty==0) { self.hasMine=undefined; self equipmentOFF(projectile); } else { self setWeaponAmmoClip("c4_mp",1); } } } } mineDeleteOnDisconnect() { self endon( "death" ); self waittill( "disconnect" ); equipmentMines = self.equipmentMines; killstreakMines = self.killstreakMines; wait .05; equipmentMines = array_removeUndefined( equipmentMines ); foreach ( equipmentMine in equipmentMines ) { if ( isDefined( equipmentMine.trigger ) ) equipmentMine.trigger delete(); equipmentMine delete(); } killstreakMines = array_removeUndefined( killstreakMines ); foreach ( killstreakMine in killstreakMines ) killstreakMine delete(); } // TODO: need self endon( "death" ); but also need an explosion to still happen // TODO: fix beacon effect lasting through launch // What if we never get "missile_stuck"? Endon death happen automatically after a set lifetime has passed? // Owner may not exist by the time it is used. (maybe make this run on owner instead) // Hitting trigger after respawn on these causes a script error. mineThrown( owner )//self==projectile { self hide(); self.owner = owner; model=spawn("script_model",self.origin); model setmodel(level.mine_model); model build_mine(self,"lanzada"); model linkto(self); self waittill( "missile_stuck" ); if( !isDefined( owner ) ) return; trace = bulletTrace( self.origin + (0, 0, 4), self.origin - (0, 0, 4), false, self ); pos = trace["position"]; if ( trace["fraction"] == 1 ) //wtf, stuck to somthing that trace didnt hit { pos = GetGroundPosition( self.origin, 12, 0, 32); trace["normal"] *= -1; } pos=pos+(0,0,-2);//arreglo mina normal = vectornormalize( trace["normal"] ); plantAngles = vectortoangles( normal ); //plantAngles += ( 90, 0, 0 ); mine = spawnMine( pos, owner, "equipment", plantAngles ); mine build_mine(mine,"plantada"); mine.trigger = spawn( "script_origin", mine.origin + (0,0,25) ); //mine thread equipmentWatchUse( owner ); QUE COГ‘O SERГЃ ESTO??? self delete(); model delete(); } mineBeacon() { effect["friendly"] = SpawnFx( level.mine_beacon["friendly"], self.origin ); effect["enemy"] = SpawnFx( level.mine_beacon["enemy"], self.origin ); self thread mineBeaconTeamUpdater( effect ); self waittill_any( "jump","death" ); effect["friendly"] delete(); effect["enemy"] delete(); } mineBeaconTeamUpdater( effect ) { self endon ( "death" ); ownerTeam = self.owner.team; // PlayFXOnTag fails if run on the same frame the parent entity was created wait ( 0.05 ); TriggerFx( effect["friendly"] ); //? TriggerFx( effect["enemy"] ); //? for ( ;; ) { effect["friendly"] Hide(); effect["enemy"] Hide(); foreach ( player in level.players ) { if ( level.teamBased ) { if ( player.team == ownerTeam ) effect["friendly"] showToPlayer( player ); else effect["enemy"] showToPlayer( player ); } else { if ( player == self.owner ) effect["friendly"] showToPlayer( player ); else effect["enemy"] showToPlayer( player ); } } level waittill_either ( "joined_team", "player_spawned" ); } } build_mine(mina,tipo) { xmodelo="projectile_concussion_grenade"; modelo=[]; for (i=0;i<360;i+=45) { modelo[i] = spawn( "script_model", self.origin); modelo[i].angles = (0,i,0); modelo[i] setModel(xmodelo); if(i==0) modelo[i] linkto(self); else modelo[i] linkto(modelo[i-45]); } self hide();//prueba ojo modelo thread deleteOnExplode(mina); modelo thread deleteOnDisconnect(mina); } deleteOnExplode(mina) { level endon("game_ended"); mina waittill_any("death","mine_explode"); for (i=0;i<360;i+=45) { self[i] delete(); } } deleteOnDisconnect(mina) { level endon("game_ended"); mina.owner waittill("disconnect"); for (i=0;i<360;i+=45) { self[i] delete(); } } equipmentON() { self.pers["copyCatLoadout"] = self maps\mp\gametypes\_class::cloneLoadout(); self.pers["copyCatLoadout"]["inUse"] = true; self.oldLoadout = self.pers["copyCatLoadout"]; self.oldClass = self.curClass; self.pers["copyCatLoadout"]["loadoutEquipment"] = "c4_mp"; self maps\mp\gametypes\_class::giveLoadout( self.team, "copyCatLoadout"); self.pers["copyCatLoadout"] = undefined; self.curClass = self.oldClass; } equipmentOFF(mine) { self endon("death"); mine waittill( "missile_stuck" ); wait 1; self.pers["copyCatLoadout"] = self.oldLoadout; self maps\mp\gametypes\_class::giveLoadout( self.team, "copyCatLoadout"); self.curClass = self.oldClass; self.pers["copyCatLoadout"] = undefined; }