[Beta] Realistic Bullet Holes

Sebastian

  • VC:MP Beta Tester
  • Something like this: hga hga hga
  • Posts: 1,082
[Beta] Realistic Bullet Holes
«  »Last edited

https://www.youtube.com/watch?v=WixAU9OWt8w

Sorry for being late, but I've faced a surprise which is just amazing!
The Bullet Holes I told you about, won't be just local, but synced on everybody's screen !!
What ?? Yes!  And all just by client-side. (no data is sent to server)

(onPlayerShoot is called for everybody, not just for the local player)

I've set a limit for bullet holes, as we don't want to use too many resources.
(even if I'm not sure how hard will this hit some low-end pc)
So, if you face lag when playing alongside other players, reply to this post with your pc details, and according to the replies I get, I will try to find a way around to fix it.



How does it work ?
Well, it creates a sprite on the hit position, in client side.
With help from habi, sprites are rotated to be facing the player in the moment of shooting, so they won't look like ugly dots around.
Every player has a limit of 10 bullet holes that can create, so once the limit is touched, the first one created will be removed, and so on.

Sprites won't be removed, because:
Quote from MEGAMIND on October 14th, 07:24 AM
Suggestion : Donot let the holes fade away, it will bring more realism,  if anyone passes by he/she may see that someone here fought here before
But, as I said, if some players will start facing lag using this script, then I will rethink it and solve it out.
Meanwhile, big thanks goes to @habi for his math skills which I Iack alot !



That's all I guess, so I will just post the code which you need to use CLIENT-SIDE
Also, better save the "hole.png" and place it in server/store/sprites


TOP
Code: [Select]
const MAX_PLAYERS = 100;
llplayer <- World.FindLocalPlayer();

/* per player */
const MAX_HOLES = 10; // -1 for never removing holes, 0 for turning off the effect

local bulletTable = array( MAX_PLAYERS ),
holes = array( MAX_PLAYERS ),
last_hole_picked = array( MAX_PLAYERS );

bulletTable[ llplayer.ID ] = {};
holes[ llplayer.ID ] = 0;
last_hole_picked[ llplayer.ID ] = 0;

class leHole
{
    inst = null;
    ID = null;
}

Code: [Select]
function Player::PlayerShoot( player, weapon, hitEntity, hitPosition )
{
    if( hitEntity && hitEntity.Type == OBJ_BUILDING )
    {
CreateBulletHole( player, hitPosition );
    }
}

Code: [Select]
function CreateBulletHole( player, pos )
{
local ppos = player.Position;
if( MAX_HOLES == 0 ) return 0;
else if( !bulletTable[ player.ID ] )
{
// this means the 'player' was not registered by this client, yet
bulletTable[ player.ID ] = null;
bulletTable[ player.ID ] = {};
holes[ player.ID ] = 0;
last_hole_picked[ player.ID ] = 0;
}

local   hole,
id = holes[ player.ID ],
angle = atan2( pos.X - ppos.X, pos.Y - ppos.Y );

if( MAX_HOLES != -1 && holes[ player.ID ] == MAX_HOLES )
{
if( bulletTable[ player.ID ].rawin( last_hole_picked[ player.ID ] ) )
{
id = last_hole_picked[ player.ID ];
local lhp = id + 1;

hole = bulletTable[ player.ID ].rawget( id );
hole.inst = null;
bulletTable[ player.ID ].rawdelete( id );
holes[ player.ID ]--;

if( last_hole_picked[ player.ID ] == MAX_HOLES-1 ) lhp = 0;

last_hole_picked[ player.ID ] = lhp;
}
}

bulletTable[ player.ID ].rawset( id, leHole() );
hole = bulletTable[ player.ID ].rawget( id );
hole.ID = id;

hole.inst = GUISprite( "hole.png", VectorScreen( 0, 0 ) );
hole.inst.Alpha = 90;

hole.inst.AddFlags( GUI_FLAG_3D_ENTITY );
hole.inst.Set3DTransform( Vector( pos.X, pos.Y, pos.Z ),  Vector( -PI/2, 0, -angle ), Vector( 0.35, 0.35, 0.0 ) );
fixsprite( hole.inst );
centersprite( hole.inst );
holes[ player.ID ]++;
}

@habi 's magic
Code: [Select]
// habi's magic
function move( pos, distance, angle )
{
local newx = pos.X - sin( angle ) * distance,
newy = pos.Y + cos( angle ) * distance;
return Vector( newx, newy, pos.Z ); //assuming z more or less same.
}

function move2( pos, pangle, dis, angle )
{
return move( pos, dis, pangle + angle )
}
function fixsprite( sp )
{
local x = sp.Position3D,
rot = sp.Rotation3D,
size = sp.Size3D, //(pos,pangle,dis,angle)
newPos = move2( x, rot.Z, 1, PI );

sp.Position3D = newPos;
}
function centersprite( sp )
{
local x = sp.Position3D,
rot = sp.Rotation3D,
size = sp.Size3D, //(pos,pangle,dis,angle)
newPos = move2( x, rot.Z, size.X / 2, PI / 2 );

newPos.Z += 1.15;
sp.Position3D = newPos;
}

PS: If you find bugs, let me know!

Inferno

  • Newbie
  • Posts: 24
Viva la VU
VFS Developer
VCCNR Administrator

habi

  • Sr. Member
  • Posts: 280
[Beta] Re: Realistic Bullet Holes
« Reply #2,  »
it is a very cool feature.

You have to download the client side script, put it in your store folder and go ingame to see the beauty of it..

the beauty of the bullet holes..





Sebastian

  • VC:MP Beta Tester
  • Something like this: hga hga hga
  • Posts: 1,082
[Beta] Re: Realistic Bullet Holes
« Reply #3,  »
Quote from habi on October 17th, 01:45 AM
it is very cool feature
Also customizable,  which makes it funny,  but you need to play with the script a bit.
You can get different holes' sprite for different types of weapons,  or personalized for different teams (red holes for the red team,  blue for the blue team,  etc)

Athanatos

  • Hero Member
  • sin^2(x)+cos^2(x) = 1
  • Posts: 930
[Beta] Re: Realistic Bullet Holes
« Reply #4,  »
Ery nice. Never thought this was ever possible in VCMP. (I didn't even think about implementing anything like that in VCMP).
Infected City Survival Main Dev

Shafin

  • Newbie
  • Posts: 9

ressam

  • Newbie
  • Decay
  • Posts: 9