Ammunation Ready!

Started by habi, Mar 27, 2020, 02:00 PM

Previous topic - Next topic

habi

hi inspired by simple garage system of DMWarrior, i made an ammunation system.
3 days day and night i was working on this. and I had stick to simplicity and tried to avoid lagging methods.

Client Side
1. main.nut
[noae][noae][noae][noae][noae][noae][noae][noae][noae]enum StreamType
{
onammu_marker=0x06,
offammu_marker=0x07,
ammu_left=0x08,
ammu_right=0x09,
ammu_enter=0x10,
ammu_rshift=0x11
}
dofile("ammo.nut"); 
onAmmuScriptLoad();
function KeyBind::OnDown( key )
{
if( ::ammu_state==1 && IsAmmuKey(key) )
{
onAmmuKeyDown(key);
}
}

function Server::ServerData( stream )
{
    local type = stream.ReadByte();
    switch( type )
    {
       
case StreamType.onammu_marker:
{
onAmmuMarker();
}
break;
case StreamType.offammu_marker:
{
offAmmuMarker();
}
break;

        default:
        break;
    }
}
[/noae][/noae][/noae][/noae][/noae][/noae][/noae][/noae][/noae]
2. ammo.nut
[noae][noae][noae][noae][noae][noae][noae][noae][noae]function onAmmuScriptLoad()
{
ammu_left <- KeyBind( 0x25 );
ammu_right <- KeyBind( 0x27 ); //left arrow key and right arrow key respectively
ammu_enter <- KeyBind(0x0D);
ammu_rshift <- KeyBind(0xA1);
ammu_state <-0;
Console.Print("Ammunation script loaded");
}
function onAmmuMarker()
{
::ammu_state=1;
return;
}
function offAmmuMarker()
{
::ammu_state=0;
return;
}
function IsAmmuKey( key )
{
if( key == ammu_left || key == ammu_right || key == ammu_enter || key == ammu_rshift)return true;
return false;
}

function onAmmuKeyDown(key)
{
if(::ammu_state==0)return;
if( key == ammu_left  )SendDataToServer( StreamType.ammu_left );
else if(key == ammu_right)SendDataToServer( StreamType.ammu_right );
else if(key == ammu_enter)SendDataToServer( StreamType.ammu_enter );
else if(key == ammu_rshift)SendDataToServer( StreamType.ammu_rshift );
}
[/noae][/noae][/noae][/noae][/noae][/noae][/noae][/noae][/noae]

Server side
1. main.nut
[noae][noae][noae][noae][noae][noae][noae][noae][noae]enum StreamType
{
onammu_marker=0x06,
offammu_marker=0x07,
ammu_left=0x08,
ammu_right=0x09,
ammu_enterkey=0x10,
ammu_rshift=0x11
}

function onScriptLoad()
{
dofile("scripts/ammunation.nut");onAmmuScriptLoad();
}

function onPlayerJoin( player )
{
Announce("Welcome to the server.", player,1);
player.Cash=5000;
}

function onClientScriptData( player )
{
    // receiving client data
    local stream = Stream.ReadByte();
    switch ( stream )
    {
case StreamType.ammu_enterkey:
{
onAmmuEnterkey( player );
}
break;
case StreamType.ammu_left:
{
onAmmuLeft( player );
}
break;
case StreamType.ammu_right:
{
onAmmuRight( player );
}
break;
case StreamType.ammu_rshift:
{
onAmmuBuy( player );
}
break;
default:
break;

    }
}
function onCheckpointEntered( player, checkpoint )
{
local ammunation=GetAmmunation(checkpoint.ID);
if(ammunation!=null)onAmmunationEntered( player, ammunation );
}
function onCheckpointExited( player, checkpoint )
{
local ammunation=GetAmmunation(checkpoint.ID);
if(ammunation!=null)onAmmuCheckpointExited( player, ammunation );
}
[/noae][/noae][/noae][/noae][/noae][/noae][/noae][/noae][/noae]
2.ammunation.nut
[noae][noae][noae][noae][noae][noae][noae][noae][noae]function onAmmunationEntered( player, store )
{
player.IsFrozen=true;
SendDataToClient( player, StreamType.onammu_marker );
choice[player.ID]=0;
plrarray[player.ID]=store;
showAmmuWep( player, store, 0 )
}

function onAmmuCheckpointExited( player, checkpoint )
{
SendDataToClient( player, StreamType.offammu_marker );
player.IsFrozen=false;
player.RestoreCamera();
plrarray[player.ID]=null;
}

function onAmmuBuy( player )
{
local store = plrarray[ player.ID ];
local index = choice[ player.ID ];
local model = store.Menu[index].Model;
local cost = store.Menu[index].cost;
local ammo = store.Menu[index].ammo;

if( ammo == 0 )return;
if( player.Cash < cost )return;

if( model == 368 )
{
if( player.Armour < 100 )
player.Armour=100;
else return;
}
else if( IsWeapon( model ) )
{
local wep = WeaponID( model );
local slot = GetSlot( wep );
local ammoAtslot = player.GetAmmoAtSlot( slot );// we know, it's bugged
player.SetWeapon( wep, 0 );
player.SetWeapon( wep,  ammoAtslot + ammo  );
}
player.Cash-=cost;
}
function showAmmuWep( player, store, index )
{
player.SetCameraPos( store.CameraPos( index ), store.ItemPos( index ));

Announce( store.Menu[ index ].name, player, 6 );

local announcetext = "~w~Cost: $"+store.Menu[ index ].cost;

local ammo = store.Menu[ index ].ammo;

if( ammo == 0 )announcetext += " ~g~out of stock";

if( IsWeapon( store.Menu[ index ].Model ) )
{
local ammuwep = WeaponID( store.Menu[index].Model );
local slot = GetSlot( ammuwep );
local plrwep = player.GetWeaponAtSlot(slot);

if( plrwep!=0 && plrwep!=ammuwep && ammo!=0)
{
announcetext += " ~g~Buying this weapon will replace your current weapon";
local t = player.GetAmmoAtSlot( slot );
player.SetWeapon( plrwep,0 ); //everything bugged
player.SetWeapon( plrwep, t );
}
}
Announce( announcetext, player, 1 );
Announce( "Press the RSHIFT button to buy. Press RET button to exit", player, 0 );
}
function onAmmuRight( player )
{
local index = choice[ player.ID ];
local store = plrarray[ player.ID ];
        if( store == null )return;
local n = store.n; //n is no:of weapons
if( index < (n-1) ){ choice[player.ID]+=1; index+=1; }
else if( index == (n-1) ){ choice[player.ID]=0; index=0; }

if( store != null )
{
showAmmuWep( player, store, index )
}
}
function onAmmuLeft( player )
{
local index = choice[ player.ID ];
local store=plrarray[ player.ID ];
        if( store == null )return;
local n = store.n;

if( index > 0 ){ choice[player.ID]-=1; index-=1;}
else if( index == 0 ){ choice[player.ID]=(n-1); index=(n-1);}

if(store!=null)
{
showAmmuWep( player, store, index )
}
}
function onAmmuEnterkey( player )
{
SendDataToClient( player, StreamType.offammu_marker );
        player.RestoreCamera();
player.IsFrozen=false;
        plrarray[player.ID]=null;
Announce("",player,6);
Announce("",player,1);
Announce("",player,0);
}

function GetAmmunation( checkpointid )
{
foreach( store in Ammunations )
{
if( store.instance.ID == checkpointid )return store;
}
}

function onAmmuScriptLoad()
{
print("Ammu script loaded");
dofile("scripts/class.nut");
const PI = 3.1415926;
WeaponPrice <- array( 34 );
LoadWeaponPrices();
choice<-array(GetMaxPlayers(),0);

local i=0;
for(i=0;i<choice.len();i++)choice[i]=0;

plrarray<-array(GetMaxPlayers(),null);
// Available Ammunations

Ammunations <- {
Downtown = Ammunation.create("downtown"),
Mall = Ammunation.create("mallAmmu"),
TooledUpMall = Ammunation.create("mallTool"),
OceanBeach = Ammunation.create("oceanbeach"),
TooledUpHavana = Ammunation.create("havana"),
TooledUpWashBeach = Ammunation.create("Wash")
}

// 5 weapons for Tooled Up. 6 for ammunations.

Ammunations.TooledUpWashBeach.addToMenu(MenuItem.FromWeaponID(2));//S.DRIVER
Ammunations.TooledUpWashBeach.addToMenu(MenuItem.FromWeaponID(7));//HAMMER
Ammunations.TooledUpWashBeach.addToMenu(MenuItem.FromWeaponID(8));//M.CLEAVER
Ammunations.TooledUpWashBeach.addToMenu(MenuItem.FromWeaponID(6));//BASEBALL BAT
Ammunations.TooledUpWashBeach.addToMenu(MenuItem.FromWeaponID(9));//MACHETE

Ammunations.TooledUpHavana.addToMenu(MenuItem.FromWeaponID(1));//BRASS KNUCKLES
Ammunations.TooledUpHavana.addToMenu(MenuItem.FromWeaponID(4));//POLICE NITESTICK
Ammunations.TooledUpHavana.addToMenu(MenuItem.FromWeaponID(6));//BASEBALL BAT
Ammunations.TooledUpHavana.addToMenu(MenuItem.FromWeaponID(9));//MACHETE
Ammunations.TooledUpHavana.addToMenu(MenuItem.FromWeaponID(11));//CHAINSAW, U SURE?

Ammunations.OceanBeach.addToMenu(MenuItem.FromWeaponID(18));
Ammunations.OceanBeach.addToMenu(MenuItem.FromWeaponID(25));
Ammunations.OceanBeach.addToMenu(MenuItem.FromWeaponID(21));
Ammunations.OceanBeach.addToMenu(MenuItem.FromWeaponID(26));
Ammunations.OceanBeach.addToMenu(MenuItem.FromWeaponID(29));
Ammunations.OceanBeach.addToMenu(MenuItem(368,200,"Body Armour",1));


Ammunations.TooledUpMall.addToMenu(MenuItem.FromWeaponID(2));//SCREW DRIVER
Ammunations.TooledUpMall.addToMenu(MenuItem.FromWeaponID(7));//HAMMER
Ammunations.TooledUpMall.addToMenu(MenuItem.FromWeaponID(8));//MEAT CLEAVER
Ammunations.TooledUpMall.addToMenu(MenuItem.FromWeaponID(5));
Ammunations.TooledUpMall.addToMenu(MenuItem.FromWeaponID(10));

Ammunations.Mall.addToMenu(MenuItem.FromWeaponID(18));
Ammunations.Mall.addToMenu(MenuItem.FromWeaponID(20));
Ammunations.Mall.addToMenu(MenuItem.FromWeaponID(22));
Ammunations.Mall.addToMenu(MenuItem.FromWeaponID(24));
Ammunations.Mall.addToMenu(MenuItem.FromWeaponID(26));
Ammunations.Mall.addToMenu(MenuItem.FromWeaponID(28));


Ammunations.Downtown.addToMenu(MenuItem.FromWeaponID(17));
Ammunations.Downtown.addToMenu(MenuItem.FromWeaponID(24));
Ammunations.Downtown.addToMenu(MenuItem.FromWeaponID(19));//shotgun
Ammunations.Downtown.addToMenu(MenuItem.FromWeaponID(27));
Ammunations.Downtown.addToMenu(MenuItem.FromWeaponID(12));
Ammunations.Downtown.addToMenu(MenuItem(368,200,"Body Armour",1));//standard way model,cost,name,ammo
}
[/noae][/noae][/noae][/noae][/noae][/noae][/noae][/noae][/noae]
3. class.nut
[noae][noae][noae][noae][noae][noae][noae][noae][noae]/**

 * @class Ammunation
 */
 class Ammunation{

/** Available ammunations. */
static list = {
 
/** Ammunation (Downtown). */
downtown = {
FacingAngle = PI/2,
Pos = Vector(-676.688,1203.87,11.1094),
ItemStart = Vector(-683.728, 1201.16, 13), 
ItemGap = 1.24,
type=1//ammunation 2 for tooled up
},
/** Ammunation North Point Mall. */
mallAmmu = {
FacingAngle = PI, //facing angle of player to weapons
Pos =  Vector(364.599,1056.05,19.2083),
ItemStart = Vector(367.94, 1049.33, 21.0083), 
ItemGap = 1.24,
type=1
},
/** Tooled Up North Point Mall. */
mallTool = {
FacingAngle = PI, //facing angle of player to weapons
Pos =  Vector(364.015,1077.71,19.0685),
ItemStart =  Vector(366.8, 1072.61, 20.68), 
ItemGap = 1.24,
type=2
},
/** Ammunation in Ocean Beach.(appeared in some mission with Lance, i remember) */
oceanbeach = {
FacingAngle = PI,
Pos =   Vector(-63.6898,-1481.95,10.494),
ItemStart =  Vector(-60.65, -1487.85, 12.505), 
ItemGap = 1.24,
type=1
},
/** Tooled Up Havana near police station  */
havana = {
FacingAngle = -PI/2, //facing angle of player to weapons
Pos =  Vector(-967.532,-692.76,11.4307),
ItemStart =  Vector(-961.23, -689.16, 13.102), 
ItemGap = 1.24,
type=2
},
/** Tooled Up Washington  */
Wash = {
FacingAngle = 0,
Pos =  Vector(204.108,-474.388,11.0699),
ItemStart = Vector(201.4, -469.3, 13.85) , 
ItemGap = 1.24,
type=2
}
}

instance=null;
markerID=null;
ItemStart=null;
Menu=null;
ItemInstances=null;
FacingAngle=null;
ItemGap=null;
n=null;
//-----------------------------------------------------------------
constructor(instance,markerID,ItemStart,FacingAngle,ItemGap,n) {
this.instance=instance;
this.markerID=markerID;
this.ItemStart=ItemStart;
this.FacingAngle=FacingAngle;
this.ItemGap=ItemGap;//the distance between the weapons
this.n=n;
this.Menu=array(0);
this.ItemInstances=array(0);
}
//------------------------------------------------------------------

static function create(name) {
if(name in Ammunation.list) {
local ammu = Ammunation.list[name];
local instance =  ::CreateCheckpoint( null, 0, true, ammu.Pos, ARGB(255, 255, 160, 193), 1);
local type=ammu.type;//tooled up or ammunation;
local icon=(type==1)?16:18;
local markerID=::CreateMarker(1, ammu.Pos, 4, RGB(0, 0, 0), icon );
return Ammunation(instance,markerID,ammu.ItemStart,ammu.FacingAngle,
ammu.ItemGap,(7-type));
}
return null;
}
function ItemPos(index)//first weapon pos, 2nd weapon position, etc.
{
return move2(this.ItemStart,this.FacingAngle,this.ItemGap*index,-PI/2)
}
function CameraPos(index)
{
return move2(ItemPos(index),this.FacingAngle,1.9,-PI);
}
function setMenuItem( index, MenuItem )
{
if(this.instance != null )
{
if( index < this.n && index >= 0 )
{
local c = this.ItemInstances[ index ];
if(c)c.Delete();
this.Menu[index]=MenuItem;
local a=::CreateObject(MenuItem.Model,0,this.ItemPos(index),255);
a.RotateTo(t(this.FacingAngle),0);
this.ItemInstances[index]=a;
return true;
}

}
return false;
}
function addToMenu(MenuItem)
{
if(this.instance != null ) {
if( this.Menu.len() < this.n )
{
local index=this.Menu.len();
this.Menu.push(MenuItem);
local a=::CreateObject(MenuItem.Model,0,this.ItemPos(index),255);
a.RotateTo(t(this.FacingAngle),0);
this.ItemInstances.push(a);
}
return true;
}
return false;
}
function OutofStock( index )
{
if(this.instance != null )
{
if( index < this.n && index >= 0 )
{
this.Menu[index].ammo=0;
}
}
}
}

class MenuItem
{
Model=null; //use model id
name=null;
cost=null;
ammo=null;

constructor(Model,cost,name,ammo)
{
this.Model=Model;
this.cost=cost;
this.name=name;
this.ammo=ammo;
}
static function FromWeaponID(wepid)//1-29 16minus
{
if(wepid>0 && wepid!=16 && wepid<=29)
{
local name=::GetWeaponName(wepid);
local model=::GetModel(wepid);
local cost=WeaponPrice[wepid].cost;
local ammo=WeaponPrice[wepid].ammo;
return MenuItem(model,cost,name,ammo);
}
}

}
class Store
{
cost=null;
ammo=null;
constructor(cost,ammo)
{
this.cost=cost;
this.ammo=ammo;
}
}
function LoadWeaponPrices()
{
WeaponPrice[0]=null;
WeaponPrice[1]=Store(10,1);
WeaponPrice[2]=Store(10,1);//screwdriver
WeaponPrice[3]=Store(10,1);//Golfclub
WeaponPrice[4]=Store(10,1);//Nitestick
WeaponPrice[5]=Store(90,1);//Knife
WeaponPrice[6]=Store(80,1);//Baseball bat
WeaponPrice[7]=Store(20,1);//Hammer
WeaponPrice[8]=Store(50,1);//Meat Cleaver
WeaponPrice[9]=Store(100,1);//Machete
WeaponPrice[10]=Store(300,1);//Katana
WeaponPrice[11]=Store(500,1);// Chainsaw
WeaponPrice[12]=Store(300,8);//grenade
WeaponPrice[13]=Store(300,8);//remote control grenade(manual)
WeaponPrice[14]=Store(100,1);//Teargas(manual)
WeaponPrice[15]=Store(500,8);//molotov cocktail (manual)
WeaponPrice[17]=Store(100,68);
WeaponPrice[18]=Store(2000,24);
WeaponPrice[19]=Store(1500,32);
WeaponPrice[20]=Store(4000,28);
WeaponPrice[21]=Store(600,20);
WeaponPrice[22]=Store(400,120);
WeaponPrice[23]=Store(400,120);//uzi
WeaponPrice[24]=Store(300,200);//Mac
WeaponPrice[25]=Store(3000,120);//MP5
WeaponPrice[26]=Store(5000,150);//M4
WeaponPrice[27]=Store(400,120);//Ruger
WeaponPrice[28]=Store(1500,40);//Sniper
WeaponPrice[29]=Store(6000,28);//Laser
WeaponPrice[30]=Store(10000,0);//dangerous weapons. i do not sell them in ammunation
WeaponPrice[31]=Store(12000,0);//
WeaponPrice[32]=Store(15000,0);//
WeaponPrice[33]=Store(20000,0);//
}
function move(pos, distance, angle)
{
local newx = pos.x - sin(angle)*distance;
local 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 r(a){return Quaternion(sin(a/2),0,0,cos(a/2))};
function s(a){return Quaternion(0,sin(a/2),0,cos(a/2))};
function t(a){return Quaternion(0,0,sin(a/2),cos(a/2))};

function GetModel(weaponid)
{
if(weaponid>0)
{
if(weaponid<=12)return weaponid+258;
else if(weaponid==13)return 291;
else if(weaponid<=18)return weaponid+257;
else if(weaponid<=21)return weaponid+258;
else if(weaponid<=25)return weaponid+259;
else if(weaponid==26)return 280;
else if(weaponid==27)return 276;
else if(weaponid<=33)return weaponid+257;//u sure mini gun selling in ammunation. ?
}
}
function IsWeapon( model )
{
if( model >=259 && model <=291 && model!=273 )return true;
return false;
}
function WeaponID( pickupid )
{ //returns 1 to 33
if(pickupid>258)
{
if(pickupid<=270)return pickupid-258;
else if(pickupid<=275)return pickupid-257;
else if(pickupid==276)return 27;
else if(pickupid<=279)return pickupid-258;
else if(pickupid==280)return 26;
else if(pickupid<=284)return pickupid-259;
else if(pickupid<=290)return pickupid-257;
else if(pickupid==291)return 13;
}
}
function GetSlot( wepid )
{
if(O(wepid,0,1))return 0;
if(O(wepid,2,3,4,5,6,7,8,9,10,11))return 1;
if(O(wepid,12,13,14,15,16))return 2;
if(O(wepid,22,23,24,25))return 5;
if(O(wepid,26,27))return 6;
if(O(wepid,19,20,21))return 4;
if(O(wepid,17,18))return 3;
if(O(wepid,30,31,32,33))return 7;
if(O(wepid,28,29))return 8;
return 1;
}
function O(t,...)
{
foreach(val in vargv)
{
if(t==val)return 1;
}
return 0;
}

/* there is a mild bug. i can't fix it. but i state the bug here.
suppose player.SetWeapon(22,100) at some point of time.
or you bought weapon 22 from this ammunation
now you shoot here and there and your ammo gone.
now you go to ammunation and just view the weapon 21 by right arrow key.
you get more ammo.

this is because GetAmmoAtSlot(slot) function is bugged.
this function always returns 100, since we gave 100 ammo to player in beginning

Possible remedies: we can make use of onPlayerShoot of the client to get the ammo of the player
i am stopping here*/
[/noae][/noae][/noae][/noae][/noae][/noae][/noae][/noae][/noae]
Actually, my variables had different name. to help everybody understand, these names such as "Menu", "MenuItem" were given atlast. Hope it works.
No additional plugins used.

How it works?
By script, we can create all the ammunations and all the weapons. There is no problem in doing that. Also all the checkpoints (sphere).
So the player is entering into the checkpoint of ammunation. what happens.
Server is the first one to know that and informs the client. Also server sets the camera focus on the first weapon.
Now client understood that the player is on checkpoint and listens whether he is pressing arrow keys. If he presses right arrow for example, ( which means next weapon). So client informs the server that the player has pressed right arrow key. So what the server do? Server simply focuses camera on second weapon. this way the whole problem is solved.
Q. How do you set up the camera?
See cos and sin are my friends. Let us say, the ammunation has 6 weapons. We only need the position of the first weapon and a certain angle of the particular ammunation. Knowing this, all the remaining positions are calculated. there is a function named 'move2' in the ( ah i forgot. **pastes one more nut file**) class.nut which do the job. the same function is used to set camera position and camera look.
Q. What about the objects. their rotation?
Well, i learned that objects no matter where, is always created at a certain angle from North.
Using the particular angle of the particular ammunation, (mentioned above in first Q) we rotate the objects so that it looks clean.
Video:-https://youtu.be/EGxsLhH-1AM
ah almost forget.
Credits: It goes to all discord members who helped me :)

Sebastian

#1
What important differences do you see ??


None.



This is looking great!
Awesome job, buddy!

Hammam


Abbas_905