December 12 2018 07:05:50
Navigation
· Home
· Articles
· Downloads
· FAQ
· Discussion Forum
· Web Links
· News Categories
· Contact Me
· Photo Gallery
· Search
· Gameservers
Languages
Users Online
· Guests Online: 4

· Members Online: 0

· Total Members: 1,057
· Newest Member: Hydrocious
Teamspeak 3
Last Seen Users
· Homi05:28:49
· sonic09:41:50
· Intruder10:46:32
· Confused Master10:50:07
· ceghe13:03:17
· Hoods15:13:00
· VCG john18:12:00
· dRgiGGLeZ 1 day
· luporandagio 1 day
· braddock 1 day
· Virus 1 day
· 420Ninjutsu 1 day
· martyr 1 day
· WEZ 3 days
· Nosek 4 days

View Thread: MP synchronized object/helper scripts
Vietcong.Info » Vietcong General Discussion » Maps & Mapping
Who is here? 1 Guest
Current Rating: (Total: 4 ratings)  
 Print Thread
MP synchronized object/helper scripts
Ando
I start adding here my MP scripts.

This topic is only for scripts.
All discussions related with those scripts will be on another topic:
MP sync. script discussion

Thanks to LDC-78 and KostiCZ for helping me to test those scripts.
Also some objects are created by LDC-78.


NOTE: some links here don't work with Firefox and Netscape!

Automatic global variables:
------------------------------------
- Main idea
- Automatic Global variable in mode script
- Automatic Global variable in object script


Mode scripts:(with automatic sync. support)
------------------------------------
- Coop (simple)
- Coop_us (advanced)
- Coop_vc (advanced)
- ATGCoop (advanced)
- DM (simple) added 2015
- DM (advanced) added 2015
- TDM (simple) added 2015
- TDM (advanced) added 2015
- CTF (advanced)
- SSA - Sharp Shooter Assault
- GG - Gun Game
- HTF - Hold The Flag
- Duel
- Airsoft
- Zombie


Object scripts:
------------------------------------
player:
- wounded _coma_dead
- 3PV_binocular (visible for others when player use binoculars)

supply:
- medic box
- ammo box


objects:
- door
- closet door
- box cover
- elevator

destruction:
- destruction (disappear)
- destruction (with destroyed object and particles)
- old bridge (random parts break when collision with player)

traps:
- punji_pit_trap
- punji_pit_trap_random
- whip_trap
- whip_trap_random
- mace_trap
- mace_trap_random
- tynamic_trap (canceled because dynamic damage don't work in MP)
- booby_trap ()
- tripflare

machines:
- AI_chopper_anm (flying chopper with sync. *.anm file)
- AI_chopper_destr (can shoot down and crash in map)
- AI_MWP_boat
- PC_M151 (will kick from server in MP with high speed - Cheat #2)

light:
- lightning (lightning object with lights on random places)
- light_switch (turn on/off light. With two different light mapped objects)
- light_time (light turn on/off with time interval)
- campfire

birds:
- bird_wings
- eagle_wings
- duck_swimming


Sound script: ( not related with MP sync.)
------------------------------------
- how to create curve sound


AI scripts: ( not related with MP sync.)
------------------------------------
- AI script (with patrolling options)



!! For some mode scripts you might needsome updated files:
Vietcong\dev\compiler\inc\sc_global.h
Vietcong\dev\compiler\inc\mplevel.inc
( attached to this post)
Vietcong\dev\editor\respawn_points.ini
Vietcong\dev\editor\mp_helpers.ini
( attached to this post)
Ando attached the following files:
sc_global.zip [20.95 kB, 164 Downloads]
mp_helpers_and_respawn_points.zip [1.36 kB, 142 Downloads]
Edited by Ando on 27-10-2015 07:46
  x 1  x 1  x 6  x 1  x 4  x 1  x 7  x 1
 
Ando
Main point:
With Automatic global variables map creator don't need to add global variable channels manually for every map and object.
Its created automatically in object script and automatically added synchronization in mode script.

Technical idea:
Object/helper script initialization (SC_OBJ_INFO_EVENT_INIT) is running before than mode script initialization (SC_NET_MES_LEVELINIT).
Every object script adds and remembers its global variable channel number(s).
When mode script is initialized, then on global variable channel 601 already is count of needed Global variables and for those are created synchronization (SC_MP_Gvar_SetSynchro)
Also added variable for server (is or is not server).
Edited by Ando on 02-11-2011 20:20
  x 2  x 3
 
Ando
Automatic Global variable in mode script

New added parts in red.

Download source  Code
// MODE script

// definitions
//________________________________
//global variable system for object synchro  !!!DONT CHANGE THOSE!!!
#define GVAR_SERVER     600 //channel for server  ( dont add SC_MP_Gvar_SetSynchro for that) 0 - not server, 1 - server
#define GVAR_COUNT      601 //channel for count of Global variables (dont add SC_MP_Gvar_SetSynchro for that)
#define GVAR_USE_start  602 //channel for start nr. of Global variable channel
//________________________________

....



....
int ScriptMain(s_SC_NET_info *info)
....
....

   case SC_NET_MES_LEVELINIT:
      //_____________________________________automatic custom global variables_________________
      for (i=GVAR_USE_start;i<GVAR_USE_start+SC_ggi(GVAR_COUNT)+1;i++){   //custom global variables
         SC_MP_Gvar_SetSynchro(i);
      }
      //_______________________________________________________________________________

      ...
      ...


     
      SC_sgi(GVAR_SERVER,0); // 0 = not server. 0 for all now, but server PC changed it later to 1

      if (info->param2){
         if (info->param1){// it's server

            //____________
            SC_sgi(GVAR_SERVER,1);//For object scripts
            //then object script have info is it on server or client machine
            //its not synchronized Global Variable
            //____________


            ....


  x 2  x 1  x 2
 
Ando
Automatic Global variable in object script:

New added parts in red.

Download source  Code

// OBJECT script

// definitions
//___________________________________________________________________
//global variable system for object synchro  !!!DONT CHANGE THOSE!!!
#define GVAR_SERVER            600    // don't edit   //0 - not server . 1 - server
#define GVAR_COUNT            601    // don't edit   //Channel for G-var count
#define GVAR_GPHASE            500      // don't edit // not directly related with Automatic Blobal variables, but help to restart
//___________________________________________________________________


...
...


int         my_gvar_count;
int         my_gvar;



...
...

int ScriptMain(s_SC_OBJ_info *info){
   ...
     
      case SC_OBJ_INFO_EVENT_INIT:
         //creating global variable
         my_gvar_count = SC_ggi(GVAR_COUNT)+1;// get latest gvar count and add 1
         SC_sgi(GVAR_COUNT,my_gvar_count);   // send new gvar count
         my_gvar = my_gvar_count+ 601;      // my gvar channel = my_gvar_count + 601 (601 is just start point for my custom gvars)


         ...



Edited by Ando on 02-10-2011 16:23
  x 1  x 1  x 2
 
Ando
COOP script with automatic global variable system

Simple coop script with added automatic global variable system

Spoiler:
Download source  Code
/*
   Eric multiplayer script - Coop
*/

// added automatic global variable system  by Ando

#include <inc\sc_global.h>
#include <inc\sc_def.h>


//________________________________
//automatic global variable system for object synchro  !!!DONT CHANGE THOSE!!!
#define GVAR_SERVER         600    //   server  ( dont add SC_MP_Gvar_SetSynchro for that) 0 - not server, 1 - server
#define GVAR_COUNT         601    //  count of Global variables ( dont add SC_MP_Gvar_SetSynchro for that)
#define GVAR_USE_start      602       //start nr of   Global variable nr
//________________________________

#define GVAR_GPHASE            500

//#define RECOVER_TIME   15.0f      // time to global recover
#define NORECOV_TIME   3.0f      // disable time of recoverplace after recovering someone there

#define REC_WPNAME_US   "USSpawn_coop_%d"
#define REC_MAX         64

dword gRecs = 0;
s_SC_MP_Recover gRec[REC_MAX];
float gRecTimer[REC_MAX];

float gNextRecover = 0.0f;

dword gEndRule;
dword gEndValue;
float gTime;

#define GPHASE_BEGIN         1
#define GPHASE_GAME            2
#define GPHASE_DONE            3
#define GPHASE_FAILED         4

dword gPhase = GPHASE_BEGIN;
float gPhase_timer = 5.0f;
dword gPhase_send = 0;

BOOL gValidSide0 = FALSE;

dword gRecoverTime = 0;
dword gRecoverLimit = 0;

float gAllNoAiRecover  = 0.0f;

BOOL SRV_CheckEndRule(float time){

   switch(gEndRule){
      case SC_MP_ENDRULE_TIME:         

         if (gValidSide0) gTime += time;
         SC_MP_EndRule_SetTimeLeft(gTime,gValidSide0);

         if (gTime>gEndValue){
            SC_MP_LoadNextMap();
            return TRUE;
         }

         break;

      default:
         SC_message("EndRule unsopported: %d",gEndRule);
         break;

   }// switch(gEndRule)

   return FALSE;

}// void SRV_CheckEndRule(float time)


void SRV_CheckUpdate(void){

   if (gPhase_send!=gPhase){

      gPhase_send = gPhase;

      SC_sgi(GVAR_GPHASE,gPhase);

   }// if (gPhase_send!=gPhase)

}// void SRV_CheckUpdate(void)



int ScriptMain(s_SC_NET_info *info)
{
   s_SC_MP_EnumPlayers      enum_pl[64];
   s_SC_MP_SRV_settings   SRVset;
   s_SC_MP_Recover *precov;
   s_SC_MP_hud      hudinfo;
   s_SC_P_getinfo   plinfo;
   dword   i, j, sideA, sideB, num;
   BOOL   valid[2];
   BOOL   alldeath;
   char   txt[32],*itxt;
   ushort *witxt;
   float   val;


   //
   switch(info->message)
   {
      case SC_NET_MES_SERVER_TICK:   
         
         if (SRV_CheckEndRule(info->elapsed_time)) break;

         for (j=0;j<2;j++)
         for (i=0;i<gRecs;i++)
            gRecTimer[i] -= info->elapsed_time;


         if (gRecoverTime<0xffff){
            gNextRecover -= info->elapsed_time;
            if (gNextRecover<0.0f) gNextRecover = (float)gRecoverTime;
         }// if (gRecoverTime<0xffff)
         

     
         if (gAllNoAiRecover>0.0f){
            gAllNoAiRecover -= info->elapsed_time;           
            if (gAllNoAiRecover<=0.0f)
               SC_MP_RecoverAllNoAiPlayers();     
                       
            break;
         }// if (gAllNoAiRecover>0.0f)
         else{
            gAllNoAiRecover -= info->elapsed_time;
         }


         CLEAR(valid);         
         j = 64;
         alldeath = FALSE;

         if (SC_MP_EnumPlayers(enum_pl,&j,SC_MP_ENUMPLAYER_SIDE_ALL)){           

            alldeath = TRUE;

            for (i=0;i<j;i++){
               if (enum_pl[i].status==SC_MP_P_STATUS_INGAME){
                  if (enum_pl[i].side>1) SC_message("coop script wrong side: %d",enum_pl[i].side);
                  else{
                     valid[enum_pl[i].side] = TRUE;
                  }
               }

               if ((enum_pl[i].side==0)&&(enum_pl[i].status==SC_MP_P_STATUS_INGAME)) alldeath = FALSE;

            }// for (i)

            SC_Log(3,"Enum, v[0]: %d   v[1]: %d  alldeath: %d",valid[0],valid[1],alldeath);
               
         }// if (SC_MP_EnumPlayers(enum_pl,&j,SC_MP_ENUMPLAYER_SIDE_ALL))
         else SC_Log(3,"NoEnum");

     
         if ((gPhase==GPHASE_GAME)&&(alldeath)&&(gPhase_timer<0.0f)){
           
            if (gRecoverLimit==0){
               // mission failed
               SC_Log(2,"Set GPHASE_FAILED");
               gPhase = GPHASE_FAILED;
               gPhase_timer = 5.0f;
            }
            else {
               // recover unlimited
               if ((gRecoverTime>=0xffff)&&(gAllNoAiRecover<-5.0f)){
                  gAllNoAiRecover = 4.0f;               
               }
            }

         }// if ((alldeath)&&(gRecoverTime>=0xffff))
         else gAllNoAiRecover = 0.0f;


         gValidSide0 = valid[0];

         switch(gPhase){
            case GPHASE_BEGIN:
               gPhase_timer -= info->elapsed_time;

               if (gPhase_timer<0.0f)
               if ((valid[0])&&(valid[1])){
                  SC_Log(2,"Set GPHASE_GAME");
                  gPhase_timer = 5.0f;
                  gPhase = GPHASE_GAME;                 
               }
               break;
            case GPHASE_GAME:
               gPhase_timer -= info->elapsed_time;

               if (gPhase_timer<0.0f)
               if (!valid[1]){
                  SC_Log(2,"Set GPHASE_DONE");
                  gPhase = GPHASE_DONE;
                  gPhase_timer = 8.0f;
               }// if (!valid[1])
               break;
            case GPHASE_DONE:
            case GPHASE_FAILED:

               gPhase_timer -= info->elapsed_time;
               if (gPhase_timer<0.0f){
                  SC_Log(2,"SC_MP_RestartMission");
                  SC_MP_RestartMission();               //restart
                  gPhase = GPHASE_BEGIN;
                  gPhase_timer = 5.0f;
               }

               break;
         }// switch(gPhase)

         SRV_CheckUpdate();

         break;

      case SC_NET_MES_CLIENT_TICK:

         break;// SC_NET_MES_CLIENT_TICK


      case SC_NET_MES_LEVELPREINIT:
         SC_sgi(GVAR_MP_MISSIONTYPE,GVAR_MP_MISSIONTYPE_COOP);

         gEndRule = info->param1;
         gEndValue = info->param2;
         gTime = 0.0f;

         SC_MP_EnableBotsFromScene(TRUE);

         break;// SC_NET_MES_LEVELPREINIT

      case SC_NET_MES_LEVELINIT:
         //_____________________________________automatic custom global variables_________________
         for (i=GVAR_USE_start;i<GVAR_USE_start+SC_ggi(GVAR_COUNT)+1;i++){   //custom global variables
            SC_MP_Gvar_SetSynchro(i);
         }
         //_______________________________________________________________________________________
         
         SC_MP_SRV_SetForceSide(0);


         SC_MP_SRV_SetClassLimit(18,0);
         SC_MP_SRV_SetClassLimit(19,0);
         SC_MP_SRV_SetClassLimit(39,0);

         SC_MP_GetSRVsettings(&SRVset);

         for (i=0;i<6;i++){
            SC_MP_SRV_SetClassLimit(i+1,SRVset.atg_class_limit[i]);
            SC_MP_SRV_SetClassLimit(i+21,SRVset.atg_class_limit[i]);
         }// for (i)


         CLEAR(hudinfo);
         hudinfo.title = 1098;

         hudinfo.sort_by[0] = SC_HUD_MP_SORTBY_KILLS;
         hudinfo.sort_by[1] = SC_HUD_MP_SORTBY_DEATHS | SC_HUD_MP_SORT_DOWNUP;
         hudinfo.sort_by[2] = SC_HUD_MP_SORTBY_PINGS | SC_HUD_MP_SORT_DOWNUP;

         hudinfo.pl_mask = SC_HUD_MP_PL_MASK_KILLS | SC_HUD_MP_PL_MASK_DEATHS | SC_HUD_MP_PL_MASK_CLASS;
         hudinfo.use_sides = TRUE;
         hudinfo.side_name[0] = 1010;
         hudinfo.side_color[0] = 0x440000ff;
         hudinfo.side_name[1] = 1011;
         hudinfo.side_color[1] = 0x44ff0000;
         hudinfo.disableVCside = TRUE;

         hudinfo.side_mask = SC_HUD_MP_SIDE_MASK_FRAGS;
         

         SC_MP_HUD_SetTabInfo(&hudinfo);

         SC_MP_AllowStPwD(TRUE);
         SC_MP_AllowFriendlyFireOFF(TRUE);
         SC_MP_SetItemsNoDisappear(FALSE);

         SC_MP_SetChooseValidSides(1);

         //____________
         SC_sgi(GVAR_SERVER,0);
         //____________

         if (info->param2){

            if (info->param1){// it's server     
               //____________
               SC_sgi(GVAR_SERVER,1);//For object scripts
               //____________

               SC_MP_GetSRVsettings(&SRVset);
               gRecoverTime = SRVset.coop_respawn_time;
               gRecoverLimit = SRVset.coop_respawn_limit;

               SC_MP_SRV_InitWeaponsRecovery(-1.0f);
               
               SC_MP_Gvar_SetSynchro(GVAR_GPHASE);               
               
               gRecs = 0;

               for (i=0;i<REC_MAX;i++){     
                  sprintf(txt,REC_WPNAME_US,i);         
                  if (SC_NET_FillRecover(&gRec[gRecs],txt)) gRecs++;               
               }               
#if _GE_VERSION_ >= 133
 
     i = REC_MAX - gRecs;
     SC_MP_GetRecovers(SC_MP_RESPAWN_COOP,&gRec[gRecs],&i);
     gRecs += i;
#endif
               if (gRecs==0) SC_message("no US recover place defined!");

               CLEAR(gRecTimer);

            }// if (info->param1)
         }//if (info->param2)

         if (info->param1)
         {
            //!!! ++ Reinit AI - NEW
            num = 64;
            SC_MP_EnumPlayers(enum_pl, &num, SC_P_SIDE_VC);
            for (i = 0; i < num; i++)
            {
               SC_P_ScriptMessage(enum_pl[i].id, SCM_MP_REINIT, 0);
            }
            //-- Reinit AI - NEW

         }
         break;// SC_NET_MES_LEVELINIT


      case SC_NET_MES_RENDERHUD:

         switch(SC_ggi(GVAR_GPHASE)){

            case GPHASE_DONE:
               j = 1099;
               break;
            case GPHASE_FAILED:
               j = 1049;
               break;

            default:j = 0;break;

         }// switch(SC_ggi(GVAR_GPHASE))

         if (j){
                     
            witxt = SC_Wtxt(j);
            SC_GetScreenRes(&val,NULL);

            val -= SC_Fnt_GetWidthW(witxt,1);

            SC_Fnt_WriteW(val * 0.5f,15,witxt,1,0xffffffff);

         }// if (j)


         break;

      case SC_NET_MES_SERVER_RECOVER_TIME:

         if (info->param2){
               info->fval1 = 0.1f;
         }
         else{
            // killed

            SC_P_GetInfo(info->param1,&plinfo);   
                       
            if (plinfo.side==0){               

               if (gRecoverLimit>0){
                 
                  if (gRecoverTime>=0xffff) info->fval1 = -1.0f;
                  else
                  if (gRecoverTime>0) info->fval1 = gNextRecover;
                     else info->fval1 = 4.0f;                 
               }
               else info->fval1 = -1.0f;
                       
            }
            else info->fval1 = -1.0f;
           
         }

         break;

      case SC_NET_MES_SERVER_RECOVER_PLACE:

         if (info->param1!=0){
            SC_message("No recover for VC");
            break;
         }
         
         precov = (s_SC_MP_Recover*)info->param2;

         i = SC_MP_SRV_GetBestDMrecov(gRec,gRecs,gRecTimer,NORECOV_TIME);
         
         gRecTimer[i] = NORECOV_TIME;
         *precov = gRec[i];
                 
         break;
         

      case SC_NET_MES_SERVER_KILL:


         break;// SC_NET_MES_SERVER_KILL


      case SC_NET_MES_RESTARTMAP:


         CLEAR(gRecTimer);

         gNextRecover = 0.0f;

         gTime = 0;


         gPhase = GPHASE_BEGIN;
         gPhase_timer = 5.0f;
         gPhase_send = 0;

         gValidSide0 = FALSE;

         SC_MP_GetSRVsettings(&SRVset);
         gRecoverTime = SRVset.coop_respawn_time;
         gRecoverLimit = SRVset.coop_respawn_limit;


         gAllNoAiRecover  = 0.0f;
               

         SC_MP_SRV_ClearPlsStats();

         SC_MP_SRV_InitGameAfterInactive();
         SC_MP_RecoverAllAiPlayers();
         SC_MP_RecoverAllNoAiPlayers();         
         

         break;// SC_NET_MES_RESTARTMAP

      case SC_NET_MES_RULESCHANGED:         
         gEndRule = info->param1;
         gEndValue = info->param2;
         gTime = 0.0f;
         break;
         

               
   }// switch(info->message)
   

   return 1;

}// int ScriptMain(void)





Edited by Ando on 02-11-2011 20:17
  x 1  x 1  x 2
 
Ando
Simple destruction script

Simple object destruction script.
When object is hit by bullet/knife/explosion it will disappear with some effects
All is restored after restart.
All you see is synchronized and visible to others.


Spoiler:
Download source  Code
//   VIETCONG 1
//   DESTRUCTION_disapear script v3.0
//   made by Ando



//   OBJECT BEHAVIOUR IN GAME:
//  All you see is synchronised and visible to others.
//  When object is hit by bullet/knife/explosion it will dissapear with some effects
//  All is restored after restart.



//simple destruction. Object disapears

//
//





#include <inc\sc_global.h>
#include <inc\sc_def.h>


//____________________________OBJECT PARAMETERS____________________________

//OBJECT STATES: 0-undestroyed, 1- destruction
       
#define EFFECT_ID_1            14                  // particle id
#define EFFECT_ID_2            14                  // particle id
#define EFFECT_ID_3            105                  // particle id
#define EFFECT_SOUND         117               // sound id
#define HITS_TO_FALL         1         //number of hits when destoyed

//_________________________________________________________________________

#define GVAR_SERVER            600    // don't edit   //0 - not server . 1 - server
#define GVAR_COUNT            601    // don't edit   //Channel for G-var count
#define GVAR_GPHASE            500      // don't edit
//_________________________________________________________________________

void      *orig_obj_id;

s_SC_NOD_transform trans;
s_SC_NOD_transform orig_trans;
s_SC_NOD_transform destr_trans;


int         hit_count = 0;
int         Global_state =   0;      //global object status
int         Local_state =   -1;      //local object status.  -1 = unknown ststus  (for start/restart)
int         Sub_state = 0;      //sub stste of object
int         i;
int         my_gvar_count;
int         my_gvar;
c_Vector3      obj_pos;
char   txt[32];


int ScriptMain(s_SC_OBJ_info *info){
   switch(info->event_type){
      case SC_OBJ_INFO_EVENT_INIT:
         
         //orig_obj_id = SC_NOD_GetNoMessage(info->master_nod, orig_obj_name);
         orig_obj_id = info->master_nod;

         SC_NOD_GetWorldPos(orig_obj_id,&obj_pos);  //sound location
         SC_NOD_GetTransform(orig_obj_id,&orig_trans);
         

         //creating global variable
         my_gvar_count = SC_ggi(GVAR_COUNT)+1;
         SC_sgi(GVAR_COUNT,my_gvar_count);
         my_gvar = my_gvar_count+ 601;
         return TRUE;
      case SC_OBJ_INFO_EVENT_JUSTLOADED:
         break;
      case SC_OBJ_INFO_EVENT_RELEASE:
         SC_NOD_SetTransform(orig_obj_id,&orig_trans);
         //SC_NOD_SetTransform(destr_obj_id,&destr_trans);
         break;
      case SC_OBJ_INFO_EVENT_HIT:
         //if(info->nod == _sub_obj_id){//
            if(Global_state == 0){
               hit_count++;
               if ((hit_count >= HITS_TO_FALL) || (info->hit_by == SC_OBJ_HIT_BY_EXPLOSION)){
                  SC_sgi(my_gvar,1); //
               }
            }
         //}
         break;
      case SC_OBJ_INFO_EVENT_DOTICK:
         if (SC_ggi(GVAR_GPHASE) == 1){//restarting
            Local_state = -1;   //restores unknown state
            return TRUE;
            break;
         }
         if (Local_state == -1){//restores stsrt state
            if (SC_ggi(GVAR_SERVER) == 1){   // its server
               SC_sgi(my_gvar,0); // status on start/restart
            }
         }
         Global_state = SC_ggi(my_gvar);
         //_____________CHANGE OBJECT STATUS________________
         if (Global_state != Local_state){   //global status != Local status
            switch(Global_state){   //
            case 0:   //normal
               SC_NOD_SetTransform(orig_obj_id,&orig_trans);
               hit_count = 0;
               Local_state=0;
               Sub_state=0;
               break;
            case 1:   // destruction
               switch(Sub_state){   //
               case 0:   //destruction
                  #ifdef EFFECT_ID_1
                     SC_CreatePtc(EFFECT_ID_1, &obj_pos);
                  #endif
                  #ifdef EFFECT_ID_2
                     SC_CreatePtc(EFFECT_ID_2, &obj_pos);
                  #endif
                  #ifdef EFFECT_ID_3
                     SC_CreatePtc(EFFECT_ID_3, &obj_pos);
                  #endif

                  #ifdef EFFECT_SOUND
                     SC_SND_PlaySound3D(EFFECT_SOUND,&obj_pos);
                  #endif
                  Sub_state=1;
                  break;
               case 1:   //destroyed
                  trans=orig_trans;
                  trans.loc.z-=1000;
                  SC_NOD_SetTransform(orig_obj_id,&trans);
                  Local_state=1;
                  break;
               }
               break;
            }
         }
            break;
      case SC_OBJ_INFO_EVENT_USED:
        break;
   }// switch(info->event_type)
   return FALSE;
}// int ScriptMain(s_OBJ_info *info)




Edited by Ando on 11-10-2011 11:39
  x 1  x 1  x 2
 
Ando
Door script


Description:
MP synchronized door.
Player can use (open /close) door. Use option appears when player is near door and looking at it.
Door has some kind of collision with player. It means that door don’t move through player, it moves back to last position when player is on its way.
Also bots can use that door. Door open/close automatically when they are near enough.


Max tutorial for custom object:
Door object must be with dummy object on the other side of door rotating point.
You must add some settings to your "door" object in 3DS MAX:
Phy_colshp=2
Phy_misshp=2
Phy_status=0
Script isn't working without those settings!!!


Object
Door object is attached to this post with texture and script.



Script:
Spoiler:
Download source  Code

//   VIETCONG 1
//   DOOR script v3.0
//  Writen for custom object -  DE_door.bes
//   made by Ando


/*
   ______________DESCRIPTION:
MP synchronized door.
Player can use (open /close) door. Use option appears when player is near door and looking at it.
Door has some kind of collision with player. It means that door don’t move through player, it moves back to last position when player is on its way.
Also bots can use that door. Door open/close automatically when they are near enough.



   



   _____________HISTORY:
//2.3 orig trans restored bug fixed
//2.4 completly new and better synchronization
//2.5 AI is using doors automatically
//2.6 created fake collision with player
//2.6 start state option
//2.7 automatic Global variable system
//3.0



*/


#include <inc\sc_global.h>
#include <inc\sc_def.h>



//____________________________OBJECT PARAMETERS____________________________

//OBJECT STATES: 0 - closed, 1 - open, 2 -opening, 3 - closing,         //future: 4-quiet and slow open, 5-quiet and slow close ,6 - locked

#define START_STATE            0         
#define CLOSESTRING            2814        //"USE" text for closeing
#define OPENSTRING            2813      //"USE" text for opening
#define CLOSESOUND            2002        //"close" sound
#define OPENSOUND            2001      //"open" sound
#define COLL_SOUND            1484      //sound for collision with player
#define OPENINGTIME            0.8f      //
#define ROT_ANGLE            -110.0f      //door opening angle in degrees
#define   dum_sub_obj            "Dummy"      //dummy object name


//_________________________________________________________________________
#define GVAR_SERVER            600       // 0 - not server, 1 - server
#define GVAR_COUNT            601       // Channel for G-var count
#define GVAR_GPHASE            500
//_________________________________________________________________________





void      *dum_sub_obj_id;

int use_string = OPENSTRING;



float val = 0.0f;
float timer = 0.0f;
float dist;

c_Vector3      door_vec;
c_Vector3      player_pos;
c_Vector3      dum_pos;

s_sphere      sph2;

s_SC_NOD_transform trans;
s_SC_NOD_transform orig_trans;

int Temp = 0;   //global object status
int Temp2 = -1;   //local object status.  -1 = unknown ststus  (for start/restart)
int         i_items,j;
int my_gvar_count;
int my_gvar;


BOOL startsound = FALSE;

s_SC_P_getinfo   pl_info;

dword       player;
dword       list[32];

int ScriptMain(s_SC_OBJ_info *info){
   switch(info->event_type){
      case SC_OBJ_INFO_EVENT_INIT:
         SC_NOD_GetTransform(info->master_nod,&orig_trans);
         SC_NOD_GetWorldPos(info->master_nod,&door_vec); 
         dum_sub_obj_id  = SC_NOD_GetNoMessage(info->master_nod, dum_sub_obj);


         //creating global variable
         my_gvar_count = SC_ggi(GVAR_COUNT)+1;
         SC_sgi(GVAR_COUNT,my_gvar_count);
         my_gvar = my_gvar_count+ 601;

         return TRUE;
      case SC_OBJ_INFO_EVENT_JUSTLOADED:
         break;
      case SC_OBJ_INFO_EVENT_RELEASE:
         SC_NOD_SetTransform(info->master_nod,&orig_trans);
         break;
      case SC_OBJ_INFO_EVENT_HIT: 
         break;
      case SC_OBJ_INFO_EVENT_DOTICK:
         if (SC_ggi(GVAR_GPHASE) == 1){//restarting
            Temp2 = -1;   //restores unknown state for door
            return TRUE;
            break;
         }//
         //______________start/restart status for server____________
         if (Temp2 == -1){ //restores stsrt state
            if (SC_ggi(GVAR_SERVER) == 1){
               SC_sgi(my_gvar,START_STATE); // status on start/restart
            }
         }
         Temp = SC_ggi(my_gvar);
         //_________________________________________AI is useing a door
            if (SC_ggi(GVAR_SERVER) == 1){
               player = SC_GetNearestPlayer(&door_vec, &dist);
               if (dist < 2.8f){//was 2.5 before
                  SC_P_GetInfo(player, &pl_info);
                  if(pl_info.member_id != 255){
                     switch(Temp){
                     case 0:   //
                        if (dist < 2){
                           SC_sgi(my_gvar,2);//opening
                           Temp =2;
                        }
                        break;
                     case 1:   //
                        if (dist > 2.1){
                           SC_sgi(my_gvar,3);//closeing
                           Temp =3;
                        }
                        break;
                     }
                  }
               }
            }
         //__________________________________________end of AI is useing a door
         //______________use string__________
         val = SC_DOBJ_CameraLooksAt(info->master_nod,2);
         if (val<1.0f){
            if (Temp == 0 || Temp == 3){
               use_string = OPENSTRING;
            }
            if (Temp == 1 || Temp == 2){
               use_string = CLOSESTRING;
            }
            SC_ACTIVE_Add(info->master_nod,2.0f*val,use_string);
         }
         //_____________CHANGE OBJECT STATUS________________
         if (Temp != Temp2){   //temp- Global state    Temp2 - Local state
            switch(Temp){
            case 0:   //set door closed status
               SC_NOD_SetTransform(info->master_nod,&orig_trans);
               startsound = TRUE;//??????
               timer=0;
               Temp2=0;
               break;
            case 1:   //set door opened status
               trans=orig_trans;
               trans.rot.z+= DEG_TO_RAD(ROT_ANGLE);
               SC_NOD_SetTransform(info->master_nod,&trans);
               startsound = TRUE;//?????
               timer=0;
               Temp2=1;
               break;
            case 2:   //door is opening
               if (Temp2==1){               //last state was oposite movement
                  timer = (OPENINGTIME-timer);//reverse movement time
               }
               Temp2=0;
               if (startsound){
                  SC_SND_PlaySound3D(OPENSOUND,&door_vec);
                  startsound = FALSE;
               }
               timer+=info->time;
               trans=orig_trans;
               trans.rot.z+=(DEG_TO_RAD(ROT_ANGLE)*timer/OPENINGTIME);
               SC_NOD_SetTransform(info->master_nod,&trans);
               // ________FAKE COLLISION WITH PLAYER______________________________
               if (SC_ggi(GVAR_SERVER) == 1){// only server
                  sph2.pos=door_vec;
                  sph2.rad=2;
                  i_items=32;
                  SC_GetPls(&sph2,list,&i_items);
                  for (j=0;j<i_items;j++) {
                     SC_P_GetInfo(list[j], &pl_info);
                     if(pl_info.member_id == 255){
                        SC_NOD_GetWorldPos(dum_sub_obj_id, &dum_pos);
                        SC_P_GetPos(list[j], &player_pos);
                        dist=SC_GetLineDist(&player_pos, &dum_pos,&door_vec);
                        if (dist < 0.33f){
                           SC_SND_PlaySound3D(COLL_SOUND,&player_pos); //collision sound
                           SC_sgi(my_gvar,3); //
                        }
                     }
                  }
               }
               //_________end of FAKE COLLISION______________________________________
               if (timer >= OPENINGTIME){
                  if (SC_ggi(GVAR_SERVER) == 1) SC_sgi(my_gvar,1); //
               }
               break;
            case 3:   //door is closing
               if (Temp2==0){               //last state was oposite movement
                  timer = (OPENINGTIME-timer);//reverse movement time
               }
               Temp2=1;
               if (startsound){
                  SC_SND_PlaySound3D(CLOSESOUND,&door_vec);
                  startsound = FALSE;
               }
               timer+=info->time;
               trans=orig_trans;
               trans.rot.z+=(DEG_TO_RAD(ROT_ANGLE)*(OPENINGTIME-timer)/OPENINGTIME);
               SC_NOD_SetTransform(info->master_nod,&trans);

               // ________FAKE COLLISION___________________________________________________
               if (SC_ggi(GVAR_SERVER) == 1){// only server
                  sph2.pos=door_vec;
                  sph2.rad=2;
                  i_items=32;
                  SC_GetPls(&sph2,list,&i_items);
                  for (j=0;j<i_items;j++) {
                     SC_P_GetInfo(list[j], &pl_info);
                     if(pl_info.member_id == 255){
                        SC_NOD_GetWorldPos(dum_sub_obj_id, &dum_pos);
                        SC_P_GetPos(list[j], &player_pos);
                        dist=SC_GetLineDist(&player_pos, &dum_pos,&door_vec);
                        if (dist < 0.33f){
                           SC_SND_PlaySound3D(COLL_SOUND,&player_pos); //collision sound
                           SC_sgi(my_gvar,2); //
                        }
                     }
                  }
               }
               //_________end of FAKE COLLISION______________________________________
               if (timer >= OPENINGTIME){
                  if (SC_ggi(GVAR_SERVER) == 1) SC_sgi(my_gvar,0); //
               }
               break;
            case 5:   //
               break;
            }
         }
            break;
      case SC_OBJ_INFO_EVENT_USED:
         Temp = SC_ggi(my_gvar);
         switch(Temp){
         case 0:      // door is closed    
         case 3:      // door is closing
            SC_sgi(my_gvar,2);      //  start opening
            break;
         case 1:      // door is opened
         case 2:      // door is opening
            SC_sgi(my_gvar,3);      //  start closing
            break;
         }
        break;
   }// switch(info->event_type)
   return FALSE;
}// int ScriptMain(s_OBJ_info *info)



Ando attached the following file:
_door.zip [151.25 kB, 355 Downloads]
Edited by Ando on 02-10-2011 19:14
  x 2
 
Ando
Closet door script

Description:
Player can open/close a "door" sub object.
Object start state is restored after restart.


Max tutorial for custom object:
You must add some settings to your door sub object in 3DS MAX:
Phy_colshp=2
Phy_misshp=2
Object isn't working without those settings!!!


Object
Closet object is attached to this post with script. Object is using official vc1 texture.


Script:
Spoiler:

// VIETCONG 1
// CLOSET_DOOR script v3.0
// Writen for custom object - DE_closet.bes
// made by Ando

/*
______________DESCRIPTION:
All you see is synchronised and visible to others.
Player can open/close a "door" sub object.
Object start state is restored after restart.


______________TUTORIAL FOR EDITOR
This script is writen for custom object "DE_closet.bes"
Place object to scene and assign that script to DE_cabinet object.




______________TUTORIAL FOR 3DS MAX:
You must add some settings to your door sub object in 3DS MAX:
Phy_colshp=2
Phy_misshp=2
Script isn't working without those settings!!!


_____________BUGS:
none


_____________NOTES:
none


______________IDEAS:
none

*/


#include <inc\sc_global.h>
#include <inc\sc_def.h>



//____________________________OBJECT PARAMETERS____________________________

//OBJECT STATES: 0 - closed, 1 - open, 2 -opening, 3 - closing, //future: 4-quiet and slow open, 5-quiet and slow close ,6 - locked



#define START_STATE 0
#define CLOSESTRING 2814
#define OPENSTRING 2813
#define CLOSESOUND 448
#define OPENSOUND 449
#define OPENINGTIME 0.8f
#define ROT_ANGLE 110.0f
#define door_sub_obj "Cabinet_door_Lod1" //door sub object name


//_________________________________________________________________________

#define GVAR_SERVER 600 // 0 - not server, 1 - server
#define GVAR_COUNT 601 // Channel for G-var count
#define GVAR_GPHASE 500



void *door_sub_obj_id;

int use_string = OPENSTRING;

float val = 0.0f;
float timer = 0.0f;

c_Vector3 door_pos;

s_SC_NOD_transform trans;
s_SC_NOD_transform orig_trans;

int Temp = 0; //global object status
int Temp2 = -1; //local object status. -1 = unknown ststus (for start/restart)
int i_items,j;
int my_gvar_count;
int my_gvar;

BOOL startsound = FALSE;


int ScriptMain(s_SC_OBJ_info *info){
switch(info->event_type){
case SC_OBJ_INFO_EVENT_INIT:
door_sub_obj_id = SC_NOD_GetNoMessage(info->master_nod, door_sub_obj);
SC_NOD_GetTransform(door_sub_obj_id,&orig_trans);
SC_NOD_GetWorldPos(door_sub_obj_id,&door_pos); //sound location

//creating global variable
my_gvar_count = SC_ggi(GVAR_COUNT)+1;
SC_sgi(GVAR_COUNT,my_gvar_count);
my_gvar = my_gvar_count+ 601;

return TRUE;
case SC_OBJ_INFO_EVENT_JUSTLOADED:
break;
case SC_OBJ_INFO_EVENT_RELEASE:
SC_NOD_SetTransform(door_sub_obj_id,&orig_trans);
break;
case SC_OBJ_INFO_EVENT_HIT:
break;
case SC_OBJ_INFO_EVENT_DOTICK:
switch(SC_ggi(GVAR_GPHASE)){
case 101: // gphase_begin for nonstandart gamemodes
case 102: // gphase_begin for nonstandart gamemodes
case 1:
Temp2 = -1; //restores unknown state for door
return TRUE;
break;
}//switch(gPhase)
//______________start/restart status for server____________
if (Temp2 == -1){ //restores stsrt state
if (SC_ggi(GVAR_SERVER) == 1){
SC_sgi(my_gvar,START_STATE); // status on start/restart
}
}
Temp = SC_ggi(my_gvar);

//______________use string__________
val = SC_DOBJ_CameraLooksAt(door_sub_obj_id,2);
if (val<1.0f){
if (Temp == 0 || Temp == 3){
use_string = OPENSTRING;
}
if (Temp == 1 || Temp == 2){
use_string = CLOSESTRING;
}
SC_ACTIVE_Add(info->master_nod,2.0f*val,use_string);

}
//_____________CHANGE OBJECT STATUS________________
if (Temp != Temp2){ //temp- Global state Temp2 - Local state
switch(Temp){
case 0: //set door closed status
SC_NOD_SetTransform(door_sub_obj_id,&orig_trans);
startsound = TRUE;//
timer=0;
Temp2=0;
break;
case 1: //set door opened status
trans=orig_trans;
trans.rot.z+= DEG_TO_RAD(ROT_ANGLE);
SC_NOD_SetTransform(door_sub_obj_id,&trans);
startsound = TRUE;//
timer=0;
Temp2=1;
break;
case 2: //door is opening
if (Temp2==1){ //last state was oposite movement
timer = (OPENINGTIME-timer);//reverse movement time
}
Temp2=0;
if (startsound){
SC_SND_PlaySound3D(OPENSOUND,&door_pos);
startsound = FALSE;
}
timer+=info->time;
trans=orig_trans;
trans.rot.z+=(DEG_TO_RAD(ROT_ANGLE)*timer/OPENINGTIME);
SC_NOD_SetTransform(door_sub_obj_id,&trans);
if (timer >= OPENINGTIME){
if (SC_ggi(GVAR_SERVER) == 1) SC_sgi(my_gvar,1); //
}
break;
case 3: //door is closing
if (Temp2==0){ //last state was oposite movement
timer = (OPENINGTIME-timer);//reverse movement time
}
Temp2=1;
if (startsound){
SC_SND_PlaySound3D(CLOSESOUND,&door_pos);
startsound = FALSE;
}
timer+=info->time;
trans=orig_trans;
trans.rot.z+=(DEG_TO_RAD(ROT_ANGLE)*(OPENINGTIME-timer)/OPENINGTIME);
SC_NOD_SetTransform(door_sub_obj_id,&trans);
if (timer >= OPENINGTIME){
if (SC_ggi(GVAR_SERVER) == 1) SC_sgi(my_gvar,0); //
}
break;
case 5: //
break;
}
}
break;
case SC_OBJ_INFO_EVENT_USED:

Temp = SC_ggi(my_gvar);
switch(Temp){
case 0: // door is closed
case 3: // door is closing
SC_sgi(my_gvar,2); // start opening
break;
case 1: // door is opened
case 2: // door is opening
SC_sgi(my_gvar,3); // start closing
break;
}
break;
}// switch(info->event_type)
return FALSE;
}// int ScriptMain(s_OBJ_info *info)
Ando attached the following file:
de_closet.zip [7.62 kB, 332 Downloads]
  x 2
 
Ando
Ammo Box script

Description:
Player can use ammo box to receive ammo.
When player is using it, box cover is moving, one kit is moving up and disappearing from box.Player see message how much kits are left.
DE_AmmoBox.bes contains 16 ammo kit's. When last kit are taken then box stay in open state and player will see message "Box is empty now"
Payer can't use it when he already have ammo full and he receive message "Ammo full".
When ammo boxes are disabled in server settings then box appear in empty state and player see info text "Medic box is disabled by server" when used.
All is restored after restart.


Max tutorial for custom object:
Create objects: box, cover and kit's. Kit's must use same name, except end number is increasing and start with 0.
Example "Kit_0", "Kit_1"... and so on.
Kit's count can be up to 20 and is detected automatically in script.
Fix your cover and kit’s names in this script.
You must add some settings to your "cover" object in 3DS MAX:
Phy_colshp=2
Phy_misshp=2
Phy_status=0
Script isn't working without those settings!!!


Object
Ammo box object is attached to this post with script and textures.

Script:
Spoiler:
Download source  Code
//   VIETCONG 1
//   DE_AmmoBox script v3.3
//  Writen for custom object -  DE_AmmoBox.bes
//   made by Ando


/*

   ______________DESCRIPTION:
All you see is synchronized and visible to others.
Player can use ammo box to receive ammo. 
When player is using it, box cover is moving, one kit is moving up and disappearing from box.Player see message how much kits are left.
DE_AmmoBox.bes contains 16 ammo kit's. When last kit are taken then box stay in open state and player will see message "Box is empty now"
Payer can't use it when he already have ammo full and he receive message "Ammo full".
When ammo boxes are disabled in server settings then box appear in empty state and player see info text  "Medic box is disabled by server" when used.
All is restored after restart.


   ______________TUTORIAL FOR EDITOR
This script is writen for custom object "DE_ammobox.bes"
Place ammobox object to scene and assign script to that object.
This script is synchronized in multiplayer. You only must use mode script with Automatic sync. support.
Synchronization channel is added automatically


   ______________TUTORIAL FOR 3DS MAX:
Create objects: box, cover and kit's. Kit's must use same name, except end number is increasing and start with 0.
Example "Kit_0", "Kit_1"... and so on.
Kit's count can be up to 20 and is detected automatically in script.
Fix your cover and kit’s names in this script.
You must add some settings to your "cover" object in 3DS MAX:
Phy_colshp=2
Phy_misshp=2
Phy_status=0
Script isn't working without those settings!!!   



   _____________HISTORY:
//   1.0 - automatic Global variable system
//   1.2 - cleaned after test
//   2.1 - When ammoboxes are disabled in server then using empty box
//   3.0 - tested with team
//   3.1 - Changed use distance from 0.5 to 0.8   //recommendation by intruder and testers
//  3.1 - added info text "Ammo full"   //recommendation by intruder and testers
//  3.1 - added info text "Box is empty now"   //recommendation by intruder and testers
//  3.2 - added kit movement
//  3.3 - removed kit's when box is disabled in server
//  3.3 - added info text  "Medic box is disabled by server"
*/

#include <inc\sc_global.h>
#include <inc\sc_def.h>



//____________________________OBJECT PARAMETERS____________________________

//OBJECT STATES: 0 - box not used, 1,2,3,.... ammo bags taken         
//-2 = disabled in server

//#define ADD_WEAPON             63  //63 – medikit   //61 – Ammobag
#define USE_STRING            104//#104:    #tee  to take ammo

#define CLOSESOUND            475   //       
#define OPENSOUND            476   //
#define COLL_SOUND            247         //small hit sound when box cover is closing
#define OPENINGTIME            1.0f      //time to move (open/close) box cover     
#define STAY_OPEN_TIME         0.5f   
#define ROT_ANGLE            130.0f      //rotation angle of box cover
#define USE_DISTANCE         0.8f      //
#define MOVE_UP_KIT            0.3f      //
#define   cover_sub_obj         "Cover"      //box cover object
#define   med_sub_obj            "ammo%d"   //ammo kid objects

//___________________________PART OF AUTOMATIC SYNC. CANNEL________________

#define GVAR_SERVER            600       // 0 - not server, 1 - server
#define GVAR_COUNT            601       // Channel for G-var count
#define GVAR_GPHASE            500         // 1 - game is in starting state (reseting object)
//_________________________________________________________________________


void      *cover_sub_obj_id;
void      *med_sub_obj_id;

float val = 0.0f;
float timer = 0.0f;

c_Vector3      door_vec;

s_SC_NOD_transform trans;
s_SC_NOD_transform orig_trans;
s_SC_NOD_transform orig_trans_med;

int         Temp = 0;   //global state of object.
int         Temp2 = -1;   //local state of object.  -1 = unknown ststus  (for start/restart)
int         Temp3 = 0;   //sub stste of object
int         i;
int         my_gvar_count;
int         my_gvar;   //object Gver
int         obj_count=0;
int         curr_obj=0;

dword   net_id;

//BOOL      add_med      =FALSE;
BOOL      startsound   =FALSE;
BOOL      HasShoot   =FALSE;

char   txt[32];


int ScriptMain(s_SC_OBJ_info *info){
   switch(info->event_type){
      case SC_OBJ_INFO_EVENT_INIT:
         obj_count=0;
         for(i= 1; i < 20; i++){//count of objects
            sprintf(txt, med_sub_obj, i);
            if (SC_NOD_GetNoMessage(info->master_nod, txt))obj_count++;

         }
         if (obj_count>0){
            sprintf(txt, med_sub_obj, 1);
            med_sub_obj_id= SC_NOD_GetNoMessage(info->master_nod, txt);
            SC_NOD_GetTransform(med_sub_obj_id,&orig_trans_med);
         }
         cover_sub_obj_id  = SC_NOD_GetNoMessage(info->master_nod, cover_sub_obj);
         SC_NOD_GetTransform(cover_sub_obj_id,&orig_trans);
         SC_NOD_GetWorldPos(cover_sub_obj_id,&door_vec);
         //____________creating global variable
         my_gvar_count = SC_ggi(GVAR_COUNT)+1;
         SC_sgi(GVAR_COUNT,my_gvar_count);
         my_gvar = my_gvar_count+ 601;
         //____________
         return TRUE;
      case SC_OBJ_INFO_EVENT_JUSTLOADED:
         break;
      case SC_OBJ_INFO_EVENT_RELEASE:
         SC_NOD_SetTransform(cover_sub_obj_id,&orig_trans);
         for(i= 1; i < obj_count+1; i++){//count of objects
            sprintf(txt, med_sub_obj, i);
            med_sub_obj_id=SC_NOD_GetNoMessage(info->master_nod, txt);
            if (med_sub_obj_id){// to avoid bugs
               trans=orig_trans_med;
               SC_NOD_SetTransform(med_sub_obj_id,&trans);
            }

         }
         break;
      case SC_OBJ_INFO_EVENT_HIT:

         //if(SC_NOD_GetNoMessage_Entity("Item M16#1")) SC_message("WORKING____Item M16#1");



         //if (SC_NOD_GetNoMessage(NULL,"Default"))SC_message("WORKING_____ Default" );      

         //net_id = SC_Item_Find(21);
         //SC_Osi("item: %d",net_id);
         break;
      case SC_OBJ_INFO_EVENT_DOTICK:
         switch(SC_ggi(GVAR_GPHASE)){
         case 101: // gphase_begin for nonstandart gamemodes
         case 102: // gphase_begin for nonstandart gamemodes
         case 1: 
            Temp2 = -1;   //restores unknown state for door
            return TRUE;
            break;
         }//switch(gPhase)
         //______________start/restart status for server____________
         if (Temp2 == -1){ //restores stsrt state
            if (SC_ggi(GVAR_SERVER) == 1){
               //get server ammobox settings
               if(SC_MP_GetAmmoBoxesEnabled()){
                  SC_sgi(my_gvar,0); // status on start/restart
               }else{
                  SC_sgi(my_gvar,-2);  // status on start/restart
               }
            }
         }
         Temp = SC_ggi(my_gvar);
         //______________use string__________
         if (Temp == Temp2){   
            if (obj_count>Temp){
               val = SC_DOBJ_CameraLooksAt(cover_sub_obj_id,2);
               if (val<USE_DISTANCE){
                  SC_ACTIVE_Add(info->master_nod,2.0f*val,USE_STRING);
               }
            }
         }
         //_____________CHANGE OBJECT STATUS________________
         if (Temp != Temp2){   //temp- Global state    Temp2 - Local state
            if (Temp == -2){//Med box disabled in server
               trans=orig_trans;
               trans.rot.y+= DEG_TO_RAD(ROT_ANGLE);
               SC_NOD_SetTransform(cover_sub_obj_id,&trans);
               startsound = TRUE;//??????
               timer=0;
               Temp2=-2;
               Temp3=0;
               for(i= 1; i < obj_count+1; i++){//count of objects
                  sprintf(txt, med_sub_obj, i);
                  med_sub_obj_id=SC_NOD_GetNoMessage(info->master_nod, txt);
                  if (med_sub_obj_id){// to avoid bugs
                     trans=orig_trans_med;
                     trans.loc.z =-1000;
                     SC_NOD_SetTransform(med_sub_obj_id,&trans);
                  }
               }
               return TRUE;
            }
            
            
            
            
            if (Temp==0){//not used
               SC_NOD_SetTransform(cover_sub_obj_id,&orig_trans);
               startsound = TRUE;//??????
               timer=0;
               Temp2=0;//?????   
               Temp3=0;
               for(i= 1; i < obj_count+1; i++){//count of objects
                  sprintf(txt, med_sub_obj, i);
                  med_sub_obj_id=SC_NOD_GetNoMessage(info->master_nod, txt);
                  if (med_sub_obj_id){// to avoid bugs
                     trans=orig_trans_med;
                     SC_NOD_SetTransform(med_sub_obj_id,&trans);
                  }
               }
               return TRUE;
            }
            //if (Temp>obj_count){//set box empty status
            //   trans=orig_trans;
            //   trans.rot.y+= DEG_TO_RAD(ROT_ANGLE);
            //   SC_NOD_SetTransform(cover_sub_obj_id,&trans);
            //   startsound = TRUE;//?????
            //   timer=0;
            //   Temp2=Temp;
            //   return TRUE;
            //}
            if (Temp>0){//use box
               timer+=info->time;
               switch(Temp3){
               case 0:   //Temp3//opening box
                  if (startsound){
                     SC_SND_PlaySound3D(OPENSOUND,&door_vec);
                     startsound = FALSE;
                  }
                  trans=orig_trans;
                  trans.rot.y+=1*(DEG_TO_RAD(ROT_ANGLE)/2+(DEG_TO_RAD(ROT_ANGLE)/2 *sin((DEG_TO_RAD(180)*timer/OPENINGTIME)- DEG_TO_RAD(90))));
                  SC_NOD_SetTransform(cover_sub_obj_id,&trans);
                  if (timer >= OPENINGTIME){
                     timer=0;
                     Temp3++;
                  }
                  break;
               case 1: //Temp3//stay shortly opened
                  //move kit object
                  //SC_Osi("time %1.1f",timer);
                  for(i= curr_obj; i < Temp; i++){//for - because when 2 players using object in a same time
                     sprintf(txt, med_sub_obj, i+1);
                     med_sub_obj_id=SC_NOD_GetNoMessage(info->master_nod, txt);
                     if (med_sub_obj_id){// to avoid bugs
                        trans=orig_trans_med;
                        trans.loc.z+= MOVE_UP_KIT * timer/STAY_OPEN_TIME;
                        SC_NOD_SetTransform(med_sub_obj_id,&trans);
                     }
                  }
                  if (timer >= (STAY_OPEN_TIME)){
                     if (Temp>=obj_count){
                        trans=orig_trans;
                        trans.rot.y+= DEG_TO_RAD(ROT_ANGLE);
                        SC_NOD_SetTransform(cover_sub_obj_id,&trans);
                        startsound = TRUE;//?????
                        timer=0;
                        Temp2=Temp;
                        return TRUE;
                     }
                     //remove object
                     for(i= curr_obj; i < Temp; i++){//for - because when 2 players using object in a same time
                        sprintf(txt, med_sub_obj, i+1);
                        med_sub_obj_id=SC_NOD_GetNoMessage(info->master_nod, txt);
                        if (med_sub_obj_id){// to avoid bugs
                           trans=orig_trans_med;
                           trans.loc.z=-1000;
                           SC_NOD_SetTransform(med_sub_obj_id,&trans);
                        }
                     }
                     curr_obj=Temp;
                     startsound = TRUE;
                     timer=0;
                     Temp3++;
                  }
                  break;
               case 2: //Temp3//closing box
                  if (startsound){
                     if (HasShoot){//add med to PC who used object
                        SC_P_AddAmmoNoGrenade(SC_PC_Get());
                        HasShoot= FALSE;
                     }
                     SC_SND_PlaySound3D(CLOSESOUND,&door_vec);
                     startsound = FALSE;
                  }
                  trans=orig_trans;
                  trans.rot.y+=-1*(DEG_TO_RAD(ROT_ANGLE)/2+(DEG_TO_RAD(ROT_ANGLE)/2 *sin((DEG_TO_RAD(180)*timer/OPENINGTIME)- DEG_TO_RAD(90))));
                  trans.rot.y+=DEG_TO_RAD(ROT_ANGLE);
                  SC_NOD_SetTransform(cover_sub_obj_id,&trans);
                  if (timer >= OPENINGTIME){
                     SC_SND_PlaySound3D(COLL_SOUND,&door_vec);
                     Temp3++;
                  }
                  break;
               case 3: //Temp3//box closed
                  //BOOL SC_P_GetHasShoot(SC_PC_Get());//for ammo box
                  SC_NOD_SetTransform(cover_sub_obj_id,&orig_trans);
                  startsound = TRUE;//??????
                  timer=0;
                  Temp2=Temp;   
                  Temp3=0;
                  break;
               }
            }
         }
            break;
      case SC_OBJ_INFO_EVENT_USED:

         if (Temp == -2){//ammo/med box disabled in server
            SC_GameInfo(NULL, "Ammo box is disabled by server");
            return TRUE;
         }

         if ((SC_P_GetHasShoot(SC_PC_Get())) || (HasShoot)){
            Temp = SC_ggi(my_gvar);
            SC_sgi(my_gvar,Temp+1);      //  start opening
            HasShoot=TRUE;
            if (Temp>=obj_count-1){
               SC_GameInfo(NULL, "Box is empty now");

            }else{
               sprintf(txt, "%d  kit's left", (obj_count - Temp - 1));
               SC_GameInfo(NULL, txt);
            }
         }else{
            SC_GameInfo(NULL, "Ammo full");
         }
        break;
   }// switch(info->event_type)
   return FALSE;
}// int ScriptMain(s_OBJ_info *info)



Ando attached the following file:
de_ammobox.zip [131.15 kB, 335 Downloads]
  x 1  x 1  x 1  x 2
 
Ando
Box cover script

Description:
Player can open/close a box


Max tutorial for custom object:
You must add some settings to your cover sub object in 3DS MAX:
Phy_colshp=2
Phy_misshp=2
Script isn't working without those settings!!!


Script:
Spoiler:
Download source  Code

//   VIETCONG 1
//   BOX_COVER script v3.0
//   made by Ando


/*
   ______________DESCRIPTION:
Player can open/close a box
This script is synchronized in multiplayer.


   ______________TUTORIAL:
Assign that script to main "box" object and fix "cover" sub object name on that script.
Script is rotating "cover" object on X axis. You can easily change rotation angle and speed.


You must add some settings to your cover sub object in 3DS MAX:
   Phy_colshp=2
   Phy_misshp=2
Script isn't working without those settings!!!
   

   _____________BUGS:
-


   _____________NOTES:
-


   ______________IDEAS:
-

*/

#include <inc\sc_global.h>
#include <inc\sc_def.h>



//____________________________OBJECT PARAMETERS____________________________

//OBJECT STATES: 0 - closed, 1 - open, 2 -opening, 3 - closing,         //future: 4-quiet and slow open, 5-quiet and slow close ,6 - locked



#define START_STATE            0         
#define CLOSESTRING            2814           
#define OPENSTRING            2813
#define CLOSESOUND            2002           
#define OPENSOUND            2001
#define OPENINGTIME            0.8f           
#define ROT_ANGLE            -110.0f
#define   door_sub_obj            "cover"   //cover sub object name


//_________________________________________________________________________

#define GVAR_SERVER            600       // 0 - not server, 1 - server
#define GVAR_COUNT            601       // Channel for G-var count
#define GVAR_GPHASE            500



void      *door_sub_obj_id;

int use_string = OPENSTRING;

float val = 0.0f;
float timer = 0.0f;

c_Vector3      door_pos;

s_SC_NOD_transform trans;
s_SC_NOD_transform orig_trans;

int         Temp = 0;      //global object status
int         Temp2 = -1;      //local object status.  -1 = unknown ststus  (for start/restart)
int         i_items,j;
int         my_gvar_count;
int         my_gvar;

BOOL startsound = FALSE;


int ScriptMain(s_SC_OBJ_info *info){
   switch(info->event_type){
      case SC_OBJ_INFO_EVENT_INIT:
         door_sub_obj_id  = SC_NOD_GetNoMessage(info->master_nod, door_sub_obj);
         SC_NOD_GetTransform(door_sub_obj_id,&orig_trans);
         SC_NOD_GetWorldPos(door_sub_obj_id,&door_pos);  //sound location

         //creating global variable
         my_gvar_count = SC_ggi(GVAR_COUNT)+1;
         SC_sgi(GVAR_COUNT,my_gvar_count);
         my_gvar = my_gvar_count+ 601;

         return TRUE;
      case SC_OBJ_INFO_EVENT_JUSTLOADED:
         break;
      case SC_OBJ_INFO_EVENT_RELEASE:
         SC_NOD_SetTransform(door_sub_obj_id,&orig_trans);
         break;
      case SC_OBJ_INFO_EVENT_HIT: 
      

         break;
      case SC_OBJ_INFO_EVENT_DOTICK:
         switch(SC_ggi(GVAR_GPHASE)){
         case 101: // gphase_begin for nonstandart gamemodes
         case 102: // gphase_begin for nonstandart gamemodes
         case 1: 
            Temp2 = -1;   //restores unknown state for door
            return TRUE;
            break;
         }//switch(gPhase)
         //______________start/restart status for server____________
         if (Temp2 == -1){ //restores stsrt state
            if (SC_ggi(GVAR_SERVER) == 1){
               SC_sgi(my_gvar,START_STATE); // status on start/restart
            }
         }
         Temp = SC_ggi(my_gvar);

         //______________use string__________
         val = SC_DOBJ_CameraLooksAt(door_sub_obj_id,2);
         if (val<1.0f){
            if (Temp == 0 || Temp == 3){
               use_string = OPENSTRING;
            }
            if (Temp == 1 || Temp == 2){
               use_string = CLOSESTRING;
            }
            SC_ACTIVE_Add(info->master_nod,2.0f*val,use_string);

         }
         //_____________CHANGE OBJECT STATUS________________
         if (Temp != Temp2){   //temp- Global state    Temp2 - Local state
            switch(Temp){
            case 0:   //set door closed status
               SC_NOD_SetTransform(door_sub_obj_id,&orig_trans);
               startsound = TRUE;//
               timer=0;
               Temp2=0;
               break;
            case 1:   //set door opened status
               trans=orig_trans;
               trans.rot.x+= DEG_TO_RAD(ROT_ANGLE);
               SC_NOD_SetTransform(door_sub_obj_id,&trans);
               startsound = TRUE;//
               timer=0;
               Temp2=1;
               break;
            case 2:   //door is opening
               if (Temp2==1){               //last state was oposite movement
                  timer = (OPENINGTIME-timer);//reverse movement time
               }
               Temp2=0;
               if (startsound){
                  SC_SND_PlaySound3D(OPENSOUND,&door_pos);
                  startsound = FALSE;
               }
               timer+=info->time;
               trans=orig_trans;
               trans.rot.x+=(DEG_TO_RAD(ROT_ANGLE)*timer/OPENINGTIME);
               SC_NOD_SetTransform(door_sub_obj_id,&trans);
               if (timer >= OPENINGTIME){
                  if (SC_ggi(GVAR_SERVER) == 1) SC_sgi(my_gvar,1); //
               }
               break;
            case 3:   //door is closing
               if (Temp2==0){               //last state was oposite movement
                  timer = (OPENINGTIME-timer);//reverse movement time
               }
               Temp2=1;
               if (startsound){
                  SC_SND_PlaySound3D(CLOSESOUND,&door_pos);
                  startsound = FALSE;
               }
               timer+=info->time;
               trans=orig_trans;
               trans.rot.x+=(DEG_TO_RAD(ROT_ANGLE)*(OPENINGTIME-timer)/OPENINGTIME);
               SC_NOD_SetTransform(door_sub_obj_id,&trans);
               if (timer >= OPENINGTIME){
                  if (SC_ggi(GVAR_SERVER) == 1) SC_sgi(my_gvar,0); //
               }
               break;
            case 5:   //
               break;
            }
         }
            break;
      case SC_OBJ_INFO_EVENT_USED:

         Temp = SC_ggi(my_gvar);
         switch(Temp){
         case 0:      // door is closed    
         case 3:      // door is closing
            SC_sgi(my_gvar,2);      //  start opening
            break;
         case 1:      // door is opened
         case 2:      // door is opening
            SC_sgi(my_gvar,3);      //  start closing
            break;
         }
        break;
   }// switch(info->event_type)
   return FALSE;
}// int ScriptMain(s_OBJ_info *info)



  x 1
 
Ando
Medic box script

Description:
All you see is synchronized and visible to others.
Player can use medic box to receive medic kit to slot 7 (keyboard nr 8).
When player is using it box cover is moving, one kit is lifted up from box and player see message how much kits are left.
DE_first_aid.bes contains 12 medic kits. When last kit are taken then box stay in open state and player will see message "Box is empty now"
Payer can't use it when he already have a medic kit, but he receive message "You already have it"
When ammo boxes are disabled in server settings then box appear in empty state and player see info text "Medic box is disabled by server" when used.
All is restored after restart.


Max tutorial for custom object:
Create box object, cover and kit's. Kits must use same name, except end number is increasing and start with 0.
Example "Kit_0", "Kit_1"... and so on.
Kit's count can be up to 20 and is detected automatically in script.
You must add some settings to your "cover" object in 3DS MAX:
Phy_colshp=2
Phy_misshp=2
Phy_status=0
Script isn't working without those settings!!!


Object
Object is attached to this post with textures.


Script:
Spoiler:
Download source  Code
//   VIETCONG 1
//   FIRST_AID script v3.3
//  Writen for custom object -  DE_first_aid.bes
//   made by Ando

/*
   ______________DESCRIPTION:
All you see is synchronized and visible to others.
Player can use medic box to receive medic kit to slot 7 (keyboard nr 8).
When player is using it  box cover is moving, one kit is lifted up from box and player see message how much kits are left.
DE_first_aid.bes contains 12 medic kits. When last kit are taken then box stay in open state and player will see message "Box is empty now"
Payer can't use it when he already have a medic kit, but he receive message "You already have it"
When ammo boxes are disabled in server settings then box appear in empty state and player see info text "Medic box is disabled by server" when used.
All is restored after restart.


   ______________TUTORIAL FOR EDITOR
This script is written for custom object "DE_first_aid.bes"
Place that object to scene and assign that script to object.

This script is synchronized in multiplayer. You only must use mode script with Automatic sync. support.
Synchronization channel is added automatically


   ______________TUTORIAL FOR 3DS MAX:
Create box object, cover and kit's. Kits must use same name, except end number is increasing and start with 0.
Example "Kit_0", "Kit_1"... and so on.
Kit's count can be up to 20 and is detected automatically in script.
You must add some settings to your "cover" object in 3DS MAX:
Phy_colshp=2
Phy_misshp=2
Phy_status=0
Script isn't working without those settings!!!   


   _____________KNOWN BUGS:
-




   _____________HISTORY:
//   1.0 - automatic Global variable system
//   1.2 - cleaned after test
//   2.1 - When ammoboxes are disabled in server then using empty box
//   3.0 - tested with team
//   3.1 - Changed use distance from 0.5 to 0.8   //recommendation by intruder and testers
//  3.1 - added info text "You already have"   //recommendation by intruder and testers
//  3.2 - added kit movement
//  3.3 - removed kit's when box is disabled in server
//  3.3 - added info text  "Medic box is disabled by server"
*/

#include <inc\sc_global.h>
#include <inc\sc_def.h>



//____________________________OBJECT PARAMETERS____________________________

//OBJECT STATES: 0 - box not used, 1,2,3,.... med bags taken   
//-2 = disabled in server


#define ADD_WEAPON             63  //63 – medikit   //61 – Ammobag
#define USE_STRING            8446//#8446:    #tee Medikit
                           //#105:    #tee  Ammo full
                           //#108:    #tee  You already have

#define CLOSESOUND            475         //         
#define OPENSOUND            476         //
#define COLL_SOUND            247         //small hit sound when box cover is closing
#define OPENINGTIME            1.0f      //time to move (open/close) box cover   
#define STAY_OPEN_TIME         0.5f   
#define ROT_ANGLE            130.0f      //rotation angle of box cover
#define USE_DISTANCE         0.8f      //
#define MOVE_UP_KIT            0.3f      //
#define   cover_sub_obj         "viko"      //box cover object
#define   med_sub_obj            "obal_%d"   //med kid objects

//___________________________PART OF AUTOMATIC SYNC. CANNEL________________

#define GVAR_SERVER            600       // 0 - not server, 1 - server
#define GVAR_COUNT            601       // Channel for G-var count
#define GVAR_GPHASE            500         // 1 - game is in starting state (reseting object)
//_________________________________________________________________________


void      *cover_sub_obj_id;
void      *med_sub_obj_id;

float val = 0.0f;
float timer = 0.0f;

c_Vector3      door_vec;

s_SC_NOD_transform trans;
s_SC_NOD_transform orig_trans;
s_SC_NOD_transform orig_trans_med;

int         Temp = 0;   //global state of object.
int         Temp2 = -1;   //local state of object.  -1 = unknown ststus  (for start/restart)
int         Temp3 = 0;   //sub stste of object
int         i;
int         my_gvar_count;
int         my_gvar;   //object Gver
int         obj_count=0;
int         curr_obj=0;


BOOL add_med = FALSE;
BOOL startsound = FALSE;

char   txt[32];

int ScriptMain(s_SC_OBJ_info *info){
   switch(info->event_type){
      case SC_OBJ_INFO_EVENT_INIT:
         obj_count=0;
         for(i= 1; i < 20; i++){//count of objects
            sprintf(txt, med_sub_obj, i);
            if (SC_NOD_GetNoMessage(info->master_nod, txt))obj_count++;

         }
         if (obj_count>0){
            sprintf(txt, med_sub_obj, 1);
            med_sub_obj_id= SC_NOD_GetNoMessage(info->master_nod, txt);
            SC_NOD_GetTransform(med_sub_obj_id,&orig_trans_med);
         }
         cover_sub_obj_id  = SC_NOD_GetNoMessage(info->master_nod, cover_sub_obj);
         SC_NOD_GetTransform(cover_sub_obj_id,&orig_trans);
         SC_NOD_GetWorldPos(cover_sub_obj_id,&door_vec);
         //____________creating global variable
         my_gvar_count = SC_ggi(GVAR_COUNT)+1;
         SC_sgi(GVAR_COUNT,my_gvar_count);
         my_gvar = my_gvar_count+ 601;
         //____________
         return TRUE;
      case SC_OBJ_INFO_EVENT_JUSTLOADED:
         break;
      case SC_OBJ_INFO_EVENT_RELEASE:
         SC_NOD_SetTransform(cover_sub_obj_id,&orig_trans);
         for(i= 1; i < obj_count+1; i++){//count of objects
            sprintf(txt, med_sub_obj, i);
            med_sub_obj_id=SC_NOD_GetNoMessage(info->master_nod, txt);
            if (med_sub_obj_id){// to avoid bugs
               trans=orig_trans_med;
               SC_NOD_SetTransform(med_sub_obj_id,&trans);
            }

         }
         break;
      case SC_OBJ_INFO_EVENT_HIT: 
         break;
      case SC_OBJ_INFO_EVENT_DOTICK:
         switch(SC_ggi(GVAR_GPHASE)){
         case 101: // gphase_begin for nonstandart gamemodes
         case 102: // gphase_begin for nonstandart gamemodes
         case 1: 
            Temp2 = -1;   //restores unknown state for door
            return TRUE;
            break;
         }//switch(gPhase)
         //______________start/restart status for server____________
         if (Temp2 == -1){ //restores stsrt state
            if (SC_ggi(GVAR_SERVER) == 1){
               //get server ammobox settings
               if(SC_MP_GetAmmoBoxesEnabled()){
                  SC_sgi(my_gvar,0); // status on start/restart
               }else{
                  SC_sgi(my_gvar,-2); //SC_sgi(my_gvar,obj_count+1);
               }
            }
         }
         Temp = SC_ggi(my_gvar);
         //______________use string__________
         if (Temp == Temp2){   
               if (obj_count>Temp){
                  val = SC_DOBJ_CameraLooksAt(cover_sub_obj_id,2);
                  if (val<USE_DISTANCE){
                     SC_ACTIVE_Add(info->master_nod,2.0f*val,USE_STRING);
                  }
               }
         }
         //_____________CHANGE OBJECT STATUS________________
         if (Temp != Temp2){   //temp- Global state    Temp2 - Local state

            if (Temp == -2){//Med box disabled in server

               trans=orig_trans;
               trans.rot.y+= DEG_TO_RAD(ROT_ANGLE);
               SC_NOD_SetTransform(cover_sub_obj_id,&trans);
               startsound = TRUE;//??????
               timer=0;
               Temp2=-2;
               Temp3=0;
               for(i= 1; i < obj_count+1; i++){//count of objects
                  sprintf(txt, med_sub_obj, i);
                  med_sub_obj_id=SC_NOD_GetNoMessage(info->master_nod, txt);
                  if (med_sub_obj_id){// to avoid bugs
                     trans=orig_trans_med;
                     trans.loc.z =-1000;
                     SC_NOD_SetTransform(med_sub_obj_id,&trans);
                  }
               }
               return TRUE;
            }



            if (Temp==0){//not used
               SC_NOD_SetTransform(cover_sub_obj_id,&orig_trans);
               startsound = TRUE;//??????
               timer=0;
               Temp2=0;
               Temp3=0;
               for(i= 1; i < obj_count+1; i++){//count of objects
                  sprintf(txt, med_sub_obj, i);
                  med_sub_obj_id=SC_NOD_GetNoMessage(info->master_nod, txt);
                  if (med_sub_obj_id){// to avoid bugs
                     trans=orig_trans_med;
                     SC_NOD_SetTransform(med_sub_obj_id,&trans);
                  }
               }
               return TRUE;
            }
            //if (Temp>obj_count){//set box empty status
            //   trans=orig_trans;
            //   trans.rot.y+= DEG_TO_RAD(ROT_ANGLE);
            //   SC_NOD_SetTransform(cover_sub_obj_id,&trans);
            //   startsound = TRUE;//?????
            //   timer=0;
            //   Temp2=Temp;
            //   return TRUE;
            //}
            if (Temp>0){//use box
               timer+=info->time;
               switch(Temp3){
               case 0:   //Temp3//opening box
                  if (startsound){
                     SC_SND_PlaySound3D(OPENSOUND,&door_vec);
                     startsound = FALSE;
                  }
                  trans=orig_trans;
                  trans.rot.y+=1*(DEG_TO_RAD(ROT_ANGLE)/2+(DEG_TO_RAD(ROT_ANGLE)/2 *sin((DEG_TO_RAD(180)*timer/OPENINGTIME)- DEG_TO_RAD(90))));
                  SC_NOD_SetTransform(cover_sub_obj_id,&trans);
                  if (timer >= OPENINGTIME){
                     timer=0;
                     Temp3++;
                  }
                  break;
               case 1: //Temp3//stay shortly opened
                  //move kit object
                  for(i= curr_obj; i < Temp; i++){//for - because when 2 players using object in a same time
                     sprintf(txt, med_sub_obj, i+1);
                     med_sub_obj_id=SC_NOD_GetNoMessage(info->master_nod, txt);
                     if (med_sub_obj_id){// to avoid bugs
                        trans=orig_trans_med;
                        trans.loc.z+= MOVE_UP_KIT * timer/STAY_OPEN_TIME;
                        SC_NOD_SetTransform(med_sub_obj_id,&trans);
                     }
                  }
                  if (timer >= (STAY_OPEN_TIME)){
                     if (Temp>obj_count){//set box empty status
                        trans=orig_trans;
                        trans.rot.y+= DEG_TO_RAD(ROT_ANGLE);
                        SC_NOD_SetTransform(cover_sub_obj_id,&trans);
                        startsound = TRUE;//?????
                        timer=0;
                        Temp2=Temp;
                        return TRUE;
                     }
                     //remove object
                     for(i= curr_obj; i < Temp; i++){//for - because when 2 players using object in a same time
                        sprintf(txt, med_sub_obj, i+1);
                        med_sub_obj_id=SC_NOD_GetNoMessage(info->master_nod, txt);
                        if (med_sub_obj_id){// to avoid bugs
                           trans=orig_trans_med;
                           trans.loc.z=-1000;
                           SC_NOD_SetTransform(med_sub_obj_id,&trans);
                        }
                     }
                     curr_obj=Temp;
                     startsound = TRUE;
                     timer=0;
                     Temp3++;
                  }
                  break;
               case 2: //Temp3//closing box
                  if (startsound){
                     if (add_med){//add med to PC who used object
                        SC_P_ChangeWeapon(SC_PC_Get(), 7, ADD_WEAPON);
                        SC_P_SetSelWeapon(SC_PC_Get(), 7);
                        add_med = FALSE;
                     }
                     SC_SND_PlaySound3D(CLOSESOUND,&door_vec);
                     startsound = FALSE;
                  }
                  trans=orig_trans;
                  trans.rot.y+=-1*(DEG_TO_RAD(ROT_ANGLE)/2+(DEG_TO_RAD(ROT_ANGLE)/2 *sin((DEG_TO_RAD(180)*timer/OPENINGTIME)- DEG_TO_RAD(90))));
                  trans.rot.y+=DEG_TO_RAD(ROT_ANGLE);
                  SC_NOD_SetTransform(cover_sub_obj_id,&trans);
                  if (timer >= OPENINGTIME){
                     SC_SND_PlaySound3D(COLL_SOUND,&door_vec);
                     Temp3++;
                  }
                  break;
               case 3: //Temp3//box closed
                  //BOOL SC_P_GetHasShoot(dword pl_id);//for ammo box
                  SC_NOD_SetTransform(cover_sub_obj_id,&orig_trans);
                  startsound = TRUE;//??????
                  timer=0;
                  Temp2=Temp;   
                  Temp3=0;
                  break;
               }
            }
         }
            break;
      case SC_OBJ_INFO_EVENT_USED:            

         if (Temp == -2){//ammo/med box disabled in server
            SC_GameInfo(NULL, "Medic box is disabled by server");
            return TRUE;
         }

         if (SC_P_HasWeapon(SC_PC_Get(),ADD_WEAPON)){//if already have that
            //void SC_GameInfoW(ushort *text);
            SC_GameInfo(NULL, "You already have");
         }
         else{
            Temp = SC_ggi(my_gvar);
            SC_sgi(my_gvar,Temp+1);      //  start opening
            add_med = TRUE;
            
            if (Temp>=obj_count-1){
               SC_GameInfo(NULL, "Box is empty now");

            }else{
               sprintf(txt, "%d  kit's left", (obj_count - Temp - 1));
               SC_GameInfo(NULL, txt);
            }
         }
        break;
   }// switch(info->event_type)
   return FALSE;
}// int ScriptMain(s_OBJ_info *info)



Ando attached the following file:
de_first_aid.rar [311.71 kB, 347 Downloads]
Edited by Ando on 02-10-2011 21:43
  x 1
 
Ando
Whip trap script for random places

Description in reality:
Whip Trap: Bamboo whips are constructed of a length of green bamboo with spikes (normally bamboo) attached to one end. The bamboo pole is bent and held in an arched position by a catch device triggered by a trip wire stretched across the track. When released, the bamboo pole whips back into the straight position impaling the person triggering the trap

Description in game:
If player collides with wire then trap is released and bamboo pole whips back into the straight position and kill the player. Wire goes down also when hit by bullet, knife or explosion. Player can also reactivate that trap in game. After start/restart trap will appear randomly to some predefined position

Tutorial for editor:
-Place one _whip_trap.bes and _whip_trap_tree.bes object to map.
- move "_whip_trap" to exactly same position as is tree object
(copy "tree" transform x,y,z to "trap" transform x,y,x)
(now you will see how trap is located with tree)
- link trap to tree object (now trap will be with tree when you move/rotate tree)
- select tree and place it where you need
for next tree:
- select trap and tree
- copy
- link trap to tree object
- select tree and place it where you need
( continue as long as you need but there cant be more than 20 "trees")
- when "trees" are in right position then you can delete trap objects.
- turn on sub object selector
- select and move "sign_place" dummy where you want a sign to appear.
- do it for every "tree"
- Place one "trap" object somewhere on map (where players cant see it)
- add script to trap object in level.c script

Max tutorial for custom object:
-

Object
Tree object is made by LDC-78.
Objects with textures are attached to this post.


Script:
Spoiler:
Download source  Code

//   VIETCONG 1
//   Whip_Trap_random script v3.3 (Writen for custom objects -  _whip_trap.bes and _whip_trap_tree.bes)
//   made by Ando

/*

   ______________TRAP DESCRIPTION IN REALITY:
Whip Trap: Bamboo whips are constructed of a length of green bamboo with spikes (normally bamboo) attached to one end.
The bamboo pole is bent and held in an arched position by a catch device triggered by a trip wire stretched across the track.
When released, the bamboo pole whips back into the straight position impaling the person triggering the trap


    ______________TRAP BEHAVIOUR IN GAME:
If player collides with wire then trap is released and bamboo pole whips back into the straight position and kill the player.
Wire goes down also when hit by bullet, knife or explosion. Player can also reactivate that trap in game.
After start/restart trap will appear randomly to some predefined position



   ______________TUTORIAL FOR EDITOR
-Place one _whip_trap.bes and _whip_trap_tree.bes object to map.
- move "_whip_trap" to exactly same position as is tree object
   (copy "tree" transform x,y,z to "trap" transform x,y,x)
   (now you will see how trap is located with tree)
- link trap to tree object (now trap will be with tree when you move/rotate tree)
- select tree and place it where you need
 for next tree:
- select trap and tree
- copy
- link trap to tree object
- select tree and place it where you need
( continue as long as you need but there cant be more than 20 "trees")
- when "trees" are in right position then you can delete trap objects.
- turn on sub object selector
- select and move "sign_place" dummy where you want a sign to appear.
- do it for every "tree"
- Place one "trap" object somewhere on map (where players cant see it)
- add script to trap object in level.c script




   ______________MAX TUTORIAL FOR CUSTOM TRAP:
   



   ______________NOTES:

1.1 - added second movement
1.2 - fixed some bugs
1.3 - changed kill player part
1.4 - new killing system - with death count
1.6 - automatic Global variable system
2.0 - tested with 2x editor
2.1 - code improved and cleaned
3.0 - tested with team
3.1 - all 3.1 improvements was recomendations by Intruder and his testing team
3.1 - added option for random places
3.1 - added trap sign
3.2 - added waypoint blocker ( important for random places)
3.3 - changed restart (was bug before when client PC was faster than rerver + netork)
   ______________BUGS:
none

   ______________IDEAS:
maybe its reasonable to add option only for engineer to set up that trap again (now its for all)

*/






//____________________________OBJECT PARAMETERS____________________________

//OBJECT STATES: 0 - trap up , 1 -  move , 2 -  down ,

#define DISARM_STRING         2806   //#2806:    #tee to cut the wire.
#define RESET_STRING         7362   //#7362:    #tee Enable
#define MOVE_SOUND            1869   //1869, 1933
#define CUT_SOUND            1950   //
#define PL_HIT_SOUND         2344//264      // player hit
#define ROT_ANGLE            -115.0f  //
#define MOVE_TIME            0.3f   //trap movement time
#define SWING_TIME            0.2f   //trap movement time
     

#ifndef tree_obj
   #define tree_obj            "_whip_trap_tree#%d"      //tree object for trap places. objects must start with #0
                                                //will found count of objects automatically
#endif


#define   mov_sub_obj            "hrabe_rot"      //moving pendel object
#define   stat_sub_obj         "hrabe_stat"   //static pendel object
#define   wire_sub_obj         "drat"         //wire object
#define   dum_sub_obj            "Dummy_hrabe"   //dummy object
#define   dum_trat_sub_obj      "Dummy_drat"   //dummy for waypoint blocker
#define   sign_sub_obj         "sign"         //sign sub object
#define   sign_place_sub_obj      "sign_place"   //sign place sub object on random tree object


//________________________________________________________________________

#include <inc\sc_global.h>
#include <inc\sc_def.h>


//_________________________FOR AUTOMATIC GLOBAL VARIABLES__________________

#define GVAR_SERVER            600    // don't edit   //"is server" channel //0 - not server . 1 - server
#define GVAR_COUNT            601    // don't edit   //Channel for G-var count ( every new object
#define GVAR_GPHASE            500      // don't edit   //game phase channel // 1 - restarting
//_________________________________________________________________________

void      *mov_sub_obj_id;
void      *stat_sub_obj_id;
void      *wire_sub_obj_id;
void      *dum_sub_obj_id;
void      *sign_sub_obj_id;
void      *cur_tree_id;

s_SC_NOD_transform   trans;
s_SC_NOD_transform   trans_swing;
s_SC_NOD_transform   orig_trans_stat;
s_SC_NOD_transform   orig_trans_move;
s_SC_NOD_transform   orig_trans_wire;
s_SC_NOD_transform   cur_trans_trap;
s_SC_NOD_transform   orig_trans_master;
s_SC_NOD_transform   orig_trans_sign;

c_Vector3      vec2;
c_Vector3      head_pos;
c_Vector3      dum_pos;
s_sphere      sph2;

float      val = 0.0f;
float      timer = 0.0f;
float      cur_rot = 0.0f;


int         Temp =   0;   //global object status
int         Temp2 =   -1;   //local object status.  -1 = unknown ststus  (for start/restart)
int         Temp3 = 0;   //local movement status
int         r_dir = 1;   // rotation direction
int         my_gvar_count;
int         my_gvar;
int         my_gvar_tree;
int         tree_obj_count=0;
int         current_tree;


s_SC_P_getinfo   pl_info;

dword       list[32];
dword       player;
dword       Ai_block;
BOOL      is_block = FALSE;
BOOL      SRV_restart_done = FALSE;
int         i_items,j;


int ScriptMain(s_SC_OBJ_info *info){
   int i;
   char   txt[32];

   switch(info->event_type){
      case SC_OBJ_INFO_EVENT_INIT:

         tree_obj_count=0;

         for(i= 0; i < 20; i++){//count of objects
            sprintf(txt, tree_obj, i);
            if (SC_NOD_GetNoMessage_Entity(txt))tree_obj_count++;
         }
         stat_sub_obj_id = SC_NOD_GetNoMessage(info->master_nod, stat_sub_obj);
         mov_sub_obj_id = SC_NOD_GetNoMessage(info->master_nod, mov_sub_obj);
         wire_sub_obj_id  = SC_NOD_GetNoMessage(info->master_nod, wire_sub_obj);
         dum_sub_obj_id  = SC_NOD_GetNoMessage(info->master_nod, dum_sub_obj);
         sign_sub_obj_id  = SC_NOD_GetNoMessage(info->master_nod, sign_sub_obj);



         SC_NOD_GetTransform(info->master_nod,&orig_trans_master);

         SC_NOD_GetTransform(wire_sub_obj_id,&orig_trans_wire);
         SC_NOD_GetTransform(mov_sub_obj_id,&orig_trans_move);
         SC_NOD_GetTransform(stat_sub_obj_id,&orig_trans_stat);
         SC_NOD_GetTransform(sign_sub_obj_id,&orig_trans_sign);         

         //creating global variable
         my_gvar_count = SC_ggi(GVAR_COUNT)+1;
         my_gvar = my_gvar_count+ 601;
         my_gvar_count++;
         my_gvar_tree = my_gvar_count+ 601;
         SC_sgi(GVAR_COUNT,my_gvar_count);

         
         break;
      case SC_OBJ_INFO_EVENT_JUSTLOADED:
         break;
      case SC_OBJ_INFO_EVENT_RELEASE:
         SC_NOD_SetTransform(info->master_nod,&orig_trans_master);
         SC_NOD_SetTransform(stat_sub_obj_id,&orig_trans_stat);
         SC_NOD_SetTransform(mov_sub_obj_id,&orig_trans_move);
         SC_NOD_SetTransform(wire_sub_obj_id,&orig_trans_wire);
         SC_NOD_SetTransform(sign_sub_obj_id,&orig_trans_sign);   
         Temp2 = -1;   //restores unknown state  (important for restar tmap)
         if (is_block){// remove Ai blocker if exist
            SC_Ai_Blocker_Remove(Ai_block);
            is_block = FALSE;
         }
         break;
      case SC_OBJ_INFO_EVENT_HIT: 
         if(info->nod == wire_sub_obj_id){
            SC_sgi(my_gvar,1); //
         }
         break;
      case SC_OBJ_INFO_EVENT_DOTICK:
         if(SC_ggi(GVAR_GPHASE)==1){//reset after restartmap/gamedone
            if (SC_ggi(GVAR_SERVER) == 1){   // its server
               if (!SRV_restart_done){
                  SC_sgi(my_gvar,0); // status on start/restart
                  current_tree = rand() % tree_obj_count;// choosing current tree where will be trap
                  SC_sgi(my_gvar_tree,current_tree); // status on start/restart
                  if (is_block){// remove Ai blocker if exist
                     SC_Ai_Blocker_Remove(Ai_block);
                     is_block = FALSE;
                  }
                  SRV_restart_done=TRUE;
               }
            }
            Temp2 = -1;   //restores unknown state for trap
            return TRUE;
         }//

         if (Temp2 == -1){//first run after restart
            if (SC_ggi(GVAR_SERVER) == 1){   // its server
               SRV_restart_done=FALSE;   //for next restert , if needed
            }
         }

         Temp = SC_ggi(my_gvar);
         //______________USE OBJECT__________
         if (Temp == Temp2){   //was strange collision bug without it
            switch(Temp){   //
            case 0:   // trap up
               val = SC_DOBJ_CameraLooksAt(wire_sub_obj_id,2);
               if (val<0.5f){
                  SC_ACTIVE_Add(info->master_nod,2.0f*val,DISARM_STRING);
               }
               if (SC_NOD_GetCollision(info->master_nod, wire_sub_obj, TRUE)){//SC_NOD_GetCollision(info->master_nod, wire_sub_obj, TRUE))
                  SC_sgi(my_gvar,1); //___sync
                  Temp = 1;
               }
               break;
            case 2:   // drap down
               val = SC_DOBJ_CameraLooksAt(info->master_nod,2);
               if (val<1.0f){
                  SC_ACTIVE_Add(info->master_nod,2.0f*val,RESET_STRING);//USE string
               }
               break;
            }//switch(Temp)
         }
         //_____________CHANGE OBJECT STATUS________________
         if (Temp != Temp2){   //global status != Local status
            switch(Temp){
            case 0:   // trap up
               //____move trap to random position
               sprintf(txt, tree_obj, SC_ggi(my_gvar_tree));// current tree name
               
               cur_tree_id = SC_NOD_GetNoMessage_Entity(txt);
               SC_NOD_GetTransform(cur_tree_id,&cur_trans_trap);// current tree transform
               SC_NOD_SetTransform(info->master_nod,&cur_trans_trap); //
               SC_NOD_GetTransform(SC_NOD_GetNoMessage(cur_tree_id, sign_place_sub_obj),&trans);
               SC_NOD_SetTransform(sign_sub_obj_id,&trans);
               //____AI blocker
               if (!is_block){//Ai blocker add if not exist
                  SC_NOD_GetWorldPos(SC_NOD_GetNoMessage(info->master_nod, dum_trat_sub_obj), &vec2);
                  sph2.pos = vec2;
                  sph2.rad = 1.6f;
                  Ai_block = SC_Ai_Blocker_Add(&sph2);
                  is_block = TRUE;
               }
               //____
               SC_NOD_SetTransform(stat_sub_obj_id,&orig_trans_stat); //
               trans=orig_trans_move;
               trans.loc.z-=1000;
               SC_NOD_SetTransform(mov_sub_obj_id,&trans); //
               SC_NOD_SetTransform(wire_sub_obj_id,&orig_trans_wire); //
               Temp2=0;
               Temp3=0;
               break;
            case 1:   // drap move
               switch(Temp3){
               case 0:   //start moving
                  SC_NOD_GetWorldPos(wire_sub_obj_id, &vec2);
                  SC_SND_PlaySound3D(CUT_SOUND,&vec2);
                  //SC_NOD_GetWorldPos(mov_sub_obj_id, &vec2);
                  SC_SND_PlaySound3D(MOVE_SOUND,&vec2);

                  trans=orig_trans_wire;
                  trans.loc.z-=1000;
                  SC_NOD_SetTransform(wire_sub_obj_id,&trans); //wire

                  trans=orig_trans_stat;
                  trans.loc.z-=1000;
                  SC_NOD_SetTransform(stat_sub_obj_id,&trans); //static
                  
                  timer = 0;
                  Temp3=1;
                  break;
               case 1:   //normal move
                  if (timer >= MOVE_TIME){//
                     timer = 0;
                     Temp3=2;
                     r_dir=1;
                     cur_rot=20;
                     trans_swing=orig_trans_move;
                     trans_swing.rot.z+=(DEG_TO_RAD(ROT_ANGLE)); // end position of main rotation
                     return TRUE;
                     //break;
                  }
                  timer+=info->time;
                  trans=orig_trans_move;
                  trans.rot.z+=(DEG_TO_RAD(ROT_ANGLE)*timer/MOVE_TIME);
                  SC_NOD_SetTransform(mov_sub_obj_id,&trans);
                  
                  //______________________killing player_________

                  SC_NOD_GetWorldPos(dum_sub_obj_id, &dum_pos);
                  if (SC_ggi(GVAR_SERVER) == 1){// only server can kill players
                     
                     sph2.pos=dum_pos;
                     sph2.rad=2;
                     SC_GetPls(&sph2,list,&i_items);
                     for (j=0;j<i_items;j++) {
                        SC_P_GetHeadPos(list[j], &head_pos);
                        if ((SC_2VectorsDist(&dum_pos, &head_pos)) < 0.85){
                           SC_P_GetInfo(list[j], &pl_info);
                           if((pl_info.cur_hp) > 1){ // player isnt dead
                              SC_SND_PlaySound3D(PL_HIT_SOUND,&head_pos);
                              SC_P_SetHp(list[j], 0.1f);
                              SC_P_GetPos(list[j], &head_pos);
                              head_pos.z+=0.1f;
                              SC_P_SetPos(list[j], &head_pos);
                           }
                        }
                     }
                  }
                  else {
                     player =SC_PC_Get();
                     SC_P_GetHeadPos(player, &head_pos);
                     if ((SC_2VectorsDist(&dum_pos, &head_pos)) < 0.85){
                        SC_P_GetInfo(player, &pl_info);
                        if((pl_info.cur_hp) > 1){ // player isnt dead
                           SC_SND_PlaySound3D(PL_HIT_SOUND,&head_pos);
                           SC_P_SetHp(player, 0.1f);
                           SC_P_GetPos(player, &head_pos);
                           head_pos.z+=0.1f;
                           SC_P_SetPos(player, &head_pos);


                        }
                     }

                  }
                  //_____________________end of killing player________________________
                  break;
               case 2:   //___________________second movement
                  if (cur_rot <= 0){//second movement is over
                     Temp3=3;//movement over for client
                     if (SC_ggi(GVAR_SERVER) == 1){
                        SC_sgi(my_gvar,2); //trap down for server
                     }
                     return TRUE;
                     //break;
                  }
                  timer+=info->time;
                  if (timer >= SWING_TIME){// one swing time is over
                     trans_swing.rot.z+=r_dir*(DEG_TO_RAD(cur_rot));
                     r_dir=-r_dir;   //reverse movement direction
                     timer=0;      //reset time for next swing
                     cur_rot-=((0.2* cur_rot)+0.1);   //degrease angle for next swing

                  }
                  trans=trans_swing;
                  trans.rot.z+=r_dir*(DEG_TO_RAD(cur_rot)/2+(DEG_TO_RAD(cur_rot)/2 *sin((DEG_TO_RAD(180)*timer/SWING_TIME)- DEG_TO_RAD(90))));
                  SC_NOD_SetTransform(mov_sub_obj_id,&trans);

                  break;
               }//switch(Temp3){
               break;
            case 2:   // trap down

               //added here too because when player join after trap starts moving
               sprintf(txt, tree_obj, SC_ggi(my_gvar_tree));// current tree name
               SC_NOD_GetTransform(SC_NOD_GetNoMessage_Entity(txt),&cur_trans_trap);// current tree transform
               SC_NOD_SetTransform(info->master_nod,&cur_trans_trap); //
               //

               trans=orig_trans_stat;
               trans.loc.z-=1000;
               SC_NOD_SetTransform(stat_sub_obj_id,&trans); //
               trans=orig_trans_move;
               trans.rot.z+=(DEG_TO_RAD(ROT_ANGLE+5.2));// 5.2 is working now but its not calculated
               SC_NOD_SetTransform(mov_sub_obj_id,&trans);
               trans=orig_trans_wire;
               trans.loc.z-=1000;
               SC_NOD_SetTransform(wire_sub_obj_id,&trans); //
               Temp2=2;
               break;
            }
         }
            break;
      case SC_OBJ_INFO_EVENT_USED:
         Temp = SC_ggi(my_gvar);
         switch(Temp){
         case 0:   // execute trap
               SC_sgi(my_gvar,1);
            break;
         case 2:   // reset trap
               SC_sgi(my_gvar,0);

            break;
         }
        break;
   }// switch(info->event_type)
   return FALSE;
}// int ScriptMain(s_OBJ_info *info)



Ando attached the following file:
_whip_trap_random.rar [1.25 MB, 334 Downloads]
Edited by Ando on 08-11-2011 08:14
  x 1
 
Ando
Mace trap script for random places

Description in reality:
Mace Trap: Mace traps take various forms, and may consist of a spiked concrete ball, drum, box or log
suspended in a tree on the end of a rope, or cable. When the trip wire is pulled, the mace swings down
along the path striking anyone in its way.

Description in game:
If player collides with wire then trap is released and mace swings down. If player is on its way then he will be killed.
Wire goes down also when hit by bullet, knife or explosion. Player can also reactivate that trap in game, when mace dont move anymore.
After start/restart trap will appear randomly to some predefined position.


Tutorial for editor:
-Place one _mace_trap.bes and _mace_trap_tree.bes object to map.
- move "_mace_trap" to exactly same position as is tree object
(copy "tree" transform x,y,z to "trap" transform x,y,x)
(now you will see how trap is located with tree)
- link trap to tree object (now trap will be with tree when you move/rotate tree)
- select tree and place it where you need
for next tree:
- select trap and tree
- copy
- link trap to tree object
- select tree and place it where you need
( continue as long as you need but there cant be more than 20 "trees")
- when "trees" are in right position then you can delete trap objects.
- turn on sub object selector
- select and move "sign_place" dummy where you want a sign to appear.
- do it for every "tree"
- Place one "trap" object somewhere on map (where players cant see it)
- add script to trap object in level.c script

Max tutorial for custom object:
-

Object
Objects with textures are attached to this post.


Script:
Spoiler:
Download source  Code
//   VIETCONG 1
//   Mace_Trap_Random script v3.3 (Writen for custom objects - _mace_trap.bes and _mace_trap_tree.bes)
//   made by Ando

/*
   ______________TRAP DESCRIPTION IN REALITY:
Mace Trap: Mace traps take various forms, and may consist of a spiked concrete ball, drum, box or log
suspended in a tree on the end of a rope, or cable. When the trip wire is pulled, the mace swings down
along the path striking anyone in its way.



    ______________TRAP BEHAVIOUR IN GAME:
If player collides with wire then trap is released and mace swings down. If player is on its way then he will be killed.
Wire goes down also when hit by bullet, knife or explosion. Player can also reactivate that trap in game, when mace dont move anymore.
After start/restart trap will appear randomly to some predefined position.


   ______________TUTORIAL FOR EDITOR
-Place one _mace_trap.bes and _mace_trap_tree.bes object to map.
- move "_mace_trap" to exactly same position as is tree object
    (copy "tree" transform x,y,z to "trap" transform x,y,x)
    (now you will see how trap is located with tree)
- link trap to tree object (now trap will be with tree when you move/rotate tree)
- select tree and place it where you need
 for next tree:
- select trap and tree
- copy
- link trap to tree object
- select tree and place it where you need
( continue as long as you need but there cant be more than 20 "trees")
- when "trees" are in right position then you can delete trap objects.
- turn on sub object selector
- select and move "sign_place" dummy where you want a sign to appear.
- do it for every "tree"
- Place one "trap" object somewhere on map (where players cant see it)
- add script to trap object in level.c script

   


   _____________NOTES:
1.3 - new sync system
1.4 - Changed movement
1.5 - new killing system - with death count
1.6 - automatic Global variable system
2.0 - tested with 2x editor
3.0 - tested with team
3.1 - all 3.1 improvements was recomendations by Intruder and his testing team
3.1 - "move" sound is decreasing now faster
3.1 - reset text distance appears now from 1.0m(was 0.5)
3.1 - dont kill player when mace rotation angle is smaller than 55 degrees (before was killing as long as it was moveing)
3.1 - added option for random places
3.1 - added trap sign
3.2 - added waypoint blocker (important for random places)
3.3 - changed restart

   _____________CURRENT BUGS:
none


   ______________IDEAS:
maybe its reasonable to add option only for engineer to set up that trap again (now its for all)




*/






#include <inc\sc_global.h>
#include <inc\sc_def.h>

//____________________________OBJECT PARAMETERS____________________________

//OBJECT STATES: 0 - trap up , 1 -  move , 2 -  down ,

#define DISARM_STRING         2806   //#2806:    #tee to cut the wire.
#define RESET_STRING         7362   //#7362:    #tee Enable
#define MOVE_SOUND            1932   //1869, 1933
#define CUT_SOUND            1950   //
#define PL_HIT_SOUND         2344//264      // player hit sound

#define ROT_ANGLE            170.0f  //
#define SWING_TIME            1.5f   //trap movement time

#define tree_obj   "_mace_trap_tree#%d"      //tree object for trap places. objects must start with #0
                        //will found count of objects automatically

#define   mov_sub_obj            "pendel"   //moving pendel object
#define   stat_sub_obj         "lanovis"   //static pendel object
#define   wire_sub_obj         "drat_1"   //
#define   dum_sub_obj            "Dummy_A"   //


#define   dum_trat_sub_obj      "Dummy_drat"   //dummy for waypoint blocker

#define   sign_sub_obj         "sign"      //sign sub object

#define   sign_place_sub_obj      "sign_place"   //sign place sub object on random tree object

//_________________________________________________________________________

#define GVAR_SERVER            600    // don't edit   //0 - not server . 1 - server
#define GVAR_COUNT            601    // don't edit   //Channel for G-var count
#define GVAR_GPHASE            500      // don't edit


void      *mov_sub_obj_id;
void      *stat_sub_obj_id;
void      *wire_sub_obj_id;
void      *dum_sub_obj_id;
void      *sign_sub_obj_id;
void      *cur_tree_id;

s_SC_NOD_transform   trans;
s_SC_NOD_transform   trans_swing;
s_SC_NOD_transform   orig_trans_stat;
s_SC_NOD_transform   orig_trans_move;
s_SC_NOD_transform   orig_trans_wire;
s_SC_NOD_transform   cur_trans_trap;
s_SC_NOD_transform   orig_trans_master;
s_SC_NOD_transform   orig_trans_sign;

c_Vector3   vec2;
c_Vector3   head_pos;
c_Vector3   dum_pos;
s_sphere   sph2;

float      val = 0.0f;
float      timer = 0.0f;
float      cur_rot = 0.0f;
float      sound_h = 0.0f;


int         Temp =   0;   //global object status
int         Temp2 =   -1;   //local object status.  -1 = unknown ststus  (for start/restart)
int         Temp3 = 0;   //local movement status
int         r_dir = 1;   // rotation direction
int         my_gvar_count;
int         my_gvar;
int         my_gvar_tree;
int         tree_obj_count=0;
int         current_tree;

s_SC_P_getinfo   pl_info;

dword       list[32];
dword       player;
dword       Ai_block;
BOOL      is_block = FALSE;
BOOL      SRV_restart_done = FALSE;

int         i_items,j;


int ScriptMain(s_SC_OBJ_info *info){
   int i;
   char   txt[32];

   switch(info->event_type){
      case SC_OBJ_INFO_EVENT_INIT:
         tree_obj_count=0;
         
         for(i= 0; i < 20; i++){//count of objects
            sprintf(txt, tree_obj, i);
            if (SC_NOD_GetNoMessage_Entity(txt))tree_obj_count++;
         }

         stat_sub_obj_id = SC_NOD_GetNoMessage(info->master_nod, stat_sub_obj);
         mov_sub_obj_id = SC_NOD_GetNoMessage(info->master_nod, mov_sub_obj);
         wire_sub_obj_id  = SC_NOD_GetNoMessage(info->master_nod, wire_sub_obj);
         dum_sub_obj_id  = SC_NOD_GetNoMessage(info->master_nod, dum_sub_obj);
         sign_sub_obj_id  = SC_NOD_GetNoMessage(info->master_nod, sign_sub_obj);

         SC_NOD_GetTransform(info->master_nod,&orig_trans_master);

         SC_NOD_GetTransform(stat_sub_obj_id,&orig_trans_stat);
         SC_NOD_GetTransform(mov_sub_obj_id,&orig_trans_move);
         SC_NOD_GetTransform(wire_sub_obj_id,&orig_trans_wire);
         SC_NOD_GetTransform(sign_sub_obj_id,&orig_trans_sign);

         //creating global variable
         my_gvar_count = SC_ggi(GVAR_COUNT)+1;
         my_gvar = my_gvar_count+ 601;
         my_gvar_count++;
         my_gvar_tree = my_gvar_count+ 601;
         SC_sgi(GVAR_COUNT,my_gvar_count);//new count of custom global variables


         break;
      case SC_OBJ_INFO_EVENT_JUSTLOADED:
         break;
      case SC_OBJ_INFO_EVENT_RELEASE:
         SC_NOD_SetTransform(info->master_nod,&orig_trans_master);
         SC_NOD_SetTransform(stat_sub_obj_id,&orig_trans_stat);
         SC_NOD_SetTransform(mov_sub_obj_id,&orig_trans_move);
         SC_NOD_SetTransform(wire_sub_obj_id,&orig_trans_wire);
         SC_NOD_SetTransform(sign_sub_obj_id,&orig_trans_sign);   
         Temp2 = -1;   //restores unknown state for light (important for restar tmap)
         if (is_block){// remove Ai blocker if exist
            SC_Ai_Blocker_Remove(Ai_block);
            is_block = FALSE;
         }
         break;
      case SC_OBJ_INFO_EVENT_HIT: 
         if(info->nod == wire_sub_obj_id){
            SC_sgi(my_gvar,1); //
         }
         break;
      case SC_OBJ_INFO_EVENT_DOTICK:
         if(SC_ggi(GVAR_GPHASE)==1){//reset after restartmap/gamedone
            if (SC_ggi(GVAR_SERVER) == 1){   // its server
               if (!SRV_restart_done){
                  SC_sgi(my_gvar,0); // status on start/restart
                  current_tree = rand() % tree_obj_count;// choosing current tree where will be trap
                  SC_sgi(my_gvar_tree,current_tree); // status on start/restart
                  if (is_block){// remove Ai blocker if exist
                     SC_Ai_Blocker_Remove(Ai_block);
                     is_block = FALSE;
                  }
                  SRV_restart_done=TRUE;
               }
            }
            Temp2 = -1;   //restores unknown state for trap
            return TRUE;
         }//

         if (Temp2 == -1){//first run after restart
            if (SC_ggi(GVAR_SERVER) == 1){   // its server
               SRV_restart_done=FALSE;   //for next restert , if needed
            }
         }
         Temp = SC_ggi(my_gvar);

         //______________use string__________
         if (Temp == Temp2){   //was strange collision bug without it
            switch(Temp){   //
            case 0:   // trap up
               val = SC_DOBJ_CameraLooksAt(wire_sub_obj_id,2);
               if (val<0.5f){
                  SC_ACTIVE_Add(info->master_nod,2.0f*val,DISARM_STRING);
               }
               if (SC_NOD_GetCollision(info->master_nod, wire_sub_obj, TRUE)){
                  SC_sgi(my_gvar,1); //___sync
                  Temp = 1;
               }
               break;
            case 2:   // drap down
               val = SC_DOBJ_CameraLooksAt(info->master_nod,2);
               if (val<1.0f){
                  SC_ACTIVE_Add(info->master_nod,2.0f*val,RESET_STRING);
               }
               break;
            }//switch(Temp)
         }
         //_____________CHANGE OBJECT STATUS________________
         if (Temp != Temp2){   //global status != Local status
            switch(Temp){
            case 0:   // trap up
               //____move trap to random position
               sprintf(txt, tree_obj, SC_ggi(my_gvar_tree));// current tree name
               cur_tree_id = SC_NOD_GetNoMessage_Entity(txt);
               SC_NOD_GetTransform(cur_tree_id,&cur_trans_trap);// current tree transform
               SC_NOD_SetTransform(info->master_nod,&cur_trans_trap); //
               SC_NOD_GetTransform(SC_NOD_GetNoMessage(cur_tree_id, sign_place_sub_obj),&trans);
               SC_NOD_SetTransform(sign_sub_obj_id,&trans);
               //____AI blocker
               if (!is_block){//Ai blocker add if not exist
                  SC_NOD_GetWorldPos(SC_NOD_GetNoMessage(info->master_nod, dum_trat_sub_obj), &vec2);
                  sph2.pos = vec2;
                  sph2.rad = 1.5f;
                  Ai_block = SC_Ai_Blocker_Add(&sph2);
                  is_block = TRUE;
               }
               //____
               SC_NOD_SetTransform(stat_sub_obj_id,&orig_trans_stat); //
               trans=orig_trans_move;
               trans.loc.z-=1000;
               SC_NOD_SetTransform(mov_sub_obj_id,&trans); //
               SC_NOD_SetTransform(wire_sub_obj_id,&orig_trans_wire); //
               Temp2=0;
               Temp3=0;
               break;
            case 1:   // drap move
               switch(Temp3){
               case 0:   //first move time
                  SC_NOD_GetWorldPos(wire_sub_obj_id, &vec2);
                  SC_SND_PlaySound3D(CUT_SOUND,&vec2);
                  //SC_NOD_GetWorldPos(mov_sub_obj_id, &vec2);
                  SC_SND_PlaySound3D(MOVE_SOUND,&vec2);

                  trans=orig_trans_wire;
                  trans.loc.z-=1000;
                  SC_NOD_SetTransform(wire_sub_obj_id,&trans); //wire

                  trans=orig_trans_stat;
                  trans.loc.z-=1000;
                  SC_NOD_SetTransform(stat_sub_obj_id,&trans); //static
                  
                  trans_swing=orig_trans_move;
                  timer = 0;
                  r_dir=1;
                  cur_rot=ROT_ANGLE;
                  sound_h = 0.0f;
                  
                  Temp3=1;
                  break;
               case 1:   //normal move
                  if (cur_rot <= 0){//second movement is over
                     Temp3=2;//movement over for client
                     if (SC_ggi(GVAR_SERVER) == 1){
                        SC_sgi(my_gvar,2); //trap down for server
                     }
                     return TRUE;
                     //break;
                  }
                  timer+=info->time;
                  if (timer >= SWING_TIME){// one swing time is over
                     trans_swing.rot.y+=r_dir*(DEG_TO_RAD(cur_rot));
                     r_dir=-r_dir;   //reverse movement direction
                     timer=0;      //reset time for next swing
                     cur_rot-=((0.11* cur_rot)+0.1);   //degrease angle for next swing
                     sound_h+= 1.4f; //
                     SC_NOD_GetWorldPos(mov_sub_obj_id, &vec2);
                     vec2.z+=sound_h;
                     SC_SND_PlaySound3D(MOVE_SOUND,&vec2);
                  }
                  trans=trans_swing;
                  trans.rot.y+=r_dir*(DEG_TO_RAD(cur_rot)/2+(DEG_TO_RAD(cur_rot)/2 *sin((DEG_TO_RAD(180)*timer/SWING_TIME)- DEG_TO_RAD(90))));
                  SC_NOD_SetTransform(mov_sub_obj_id,&trans);

                  //______________________killing player_________
                  if (cur_rot > 55){
                     SC_NOD_GetWorldPos(dum_sub_obj_id, &dum_pos);
                     if (SC_ggi(GVAR_SERVER) == 1){// only server
                        sph2.pos=dum_pos;
                        sph2.rad=2;
                        SC_GetPls(&sph2,list,&i_items);
                        for (j=0;j<i_items;j++) {
                           SC_P_GetHeadPos(list[j], &head_pos);
                           if ((SC_2VectorsDist(&dum_pos, &head_pos)) < 0.85){
                              SC_P_GetInfo(list[j], &pl_info);
                              if((pl_info.cur_hp) > 1){ // player isnt dead
                                 vec2=head_pos;
                                 vec2.z+=sound_h;
                                 SC_SND_PlaySound3D(PL_HIT_SOUND,&vec2);
                                 SC_P_SetHp(list[j], 0.1f);
                                 SC_P_GetPos(list[j], &head_pos);
                                 head_pos.z+=0.1f;
                                 SC_P_SetPos(list[j], &head_pos);
                              }
                           }
                        }
                     }else {
                        player =SC_PC_Get();
                        SC_P_GetHeadPos(player, &head_pos);
                        if ((SC_2VectorsDist(&dum_pos, &head_pos)) < 0.85){
                           SC_P_GetInfo(player, &pl_info);
                           if((pl_info.cur_hp) > 1){ // player isnt dead
                              vec2=head_pos;
                              vec2.z+=sound_h;
                              SC_SND_PlaySound3D(PL_HIT_SOUND,&vec2);
                              SC_P_SetHp(player, 0.1f);
                              SC_P_GetPos(player, &head_pos);
                              head_pos.z+=0.1f;
                              SC_P_SetPos(player, &head_pos);
                           }
                        }
                     }
                  }
                  //_____________________end of killing player________________________
                  break;
               }//switch(Temp3){
               break;
            case 2:   // drap down
               //added here too because when player join after trap starts moving
               sprintf(txt, tree_obj, SC_ggi(my_gvar_tree));// current tree name
               SC_NOD_GetTransform(SC_NOD_GetNoMessage_Entity(txt),&cur_trans_trap);// current tree transform
               SC_NOD_SetTransform(info->master_nod,&cur_trans_trap); //
               //

               trans=orig_trans_stat;
               trans.loc.z-=1000;
               SC_NOD_SetTransform(stat_sub_obj_id,&trans); //
               
               trans=orig_trans_move;
               trans.rot.y+=(DEG_TO_RAD((ROT_ANGLE-80.0f)));//
               SC_NOD_SetTransform(mov_sub_obj_id,&trans);
               trans=orig_trans_wire;
               trans.loc.z-=1000;
               SC_NOD_SetTransform(wire_sub_obj_id,&trans); //
               Temp2=2;
               break;
            }
         }
            break;
      case SC_OBJ_INFO_EVENT_USED:
         Temp = SC_ggi(my_gvar);
         switch(Temp){
         case 0:   // execute trap
               SC_sgi(my_gvar,1);
            break;
         case 2:   //reset trap
               SC_sgi(my_gvar,0);
            break;
         }
        break;
   }// switch(info->event_type)
   return FALSE;
}// int ScriptMain(s_OBJ_info *info)



Ando attached the following file:
_mace_trap_random.rar [1.75 MB, 323 Downloads]
 
Ando
How to create curve sound

There is two parts
1. Create a camera animation ( for location of curve sound)
2. Add a sound to sounds.c script

1. Create camera animation for curve sound

- open your map
- go to start position of your curve sound
- choose menu command "Editor" > "Camera animation editor"
- add some name to "name:" box
- click "Create"
- click "Create Key" ( some blue mark appear to frame slide bar)
Now first position is created
Down in camera animation editor you can see frame selector. And it will look like this: < 0 / 100 >
- There you choose next frame. Click to ">" button on frame slide bar. Now you should see < 1 / 100 >
- turn on "Move" button
- now move to better position ( where you have some overview for curve sound location)
- click and drag your pink camera to next position
- click "Create Key" ( white mark appear to camera position)
- click to next frame ( ">" button )
- click and drag your camera to next position
- click "Create Key"
- continue as long as you need ( ">" ; drag camera ; "Create Key" )
...
- click "Save"
- choose right folder for your camera animation ( LEVELS\mapname\DATA\subname\snd\ )
- choose file name and click "save"
camera animation file must be in right position then its added to map file, when finalized



2. Add curve sound to sound script

Sound.c file is created automatically during finalization. It's located under scripts folder of your map.
- open sound.c file with some text editing program.

Default sound.c file:
Spoiler:
Download source  Code
#include <inc\sc_global.h>

int ScriptMain(s_SC_SOUND_info *info){

   switch(info->message){

      case SC_SOUND_MESSAGE_INIT:

         //SC_SND_SetHearableRatio(0.85f);
         //SC_SND_Ambient_Play(617);

         break;

   }// switch(info->message)

    return 1;

}// int ScriptMain(s_SC_SOUND_info *info)





For your curve sound you must add one command line.

SC_SND_CreateCurveSound(anm_filename, snd_id, max_play_dist, apply_env_volume);

anm_filename - your camera animation file for curve sound
snd_id - sound id
max_play_dist - distance from camera animation where player can hear that sound
apply_env_volume - TRUE / FALSE option. If true then curve sound will use environment sound volume.

Example line:
Spoiler:
Download source  Code
SC_SND_CreateCurveSound("LEVELS\\mapname\\DATA\\subname\\snd\\my_snd_curve.anm", 1687, 3, FALSE);




that command line must be after SC_SOUND_MESSAGE_INIT:

Example sound.c file with curve sound:
Spoiler:
Download source  Code
#include <inc\sc_global.h>

int ScriptMain(s_SC_SOUND_info *info){

   switch(info->message){

      case SC_SOUND_MESSAGE_INIT:

         SC_SND_CreateCurveSound("LEVELS\\mapname\\DATA\\subname\\snd\\my_snd_curve.anm", 1687, 3, FALSE);

         //SC_SND_SetHearableRatio(0.85f);
         //SC_SND_Ambient_Play(617);
         break;

   }// switch(info->message)

    return 1;
}// int ScriptMain(s_SC_SOUND_info *info)




If you want to add more curve sounds then just add more those command lines with right parameters.
  x 1
 
Ando
Punji pit trap script (appear randomly)

Description in reality:
When a man falls into the Punji Pit, he will be injured by the pointed
bamboo stakes which will cut his thighs and hips, or stab him through
the back, often these spikes are connected to a hand grenade,
designed to explode when the man is pulled out of the pit.

Description in game:
If player walk over trap cover then it fall down with player.
When player collide with spices then he will die.
Trap cover will fall also when hit by gun/knife 2 times or hit by grenade.
When trap cover is down then player can destroy that trap.
After start/restart trap will appear randomly.

Tutorial for editor:
- Trap hole(s) must be added to terrain in MAX.
- add trap object precisely to hole
- for that use: "Settings" > "Snap settings" and turn on "vertex" only
- turn on "Snap translator"
- now you can move cover precisely to right place
- add script to trap object in level.c script

Max tutorial for custom object:
-

Object
Objects with textures are attached to this post.
Script are not included there, because it's easier to update only in that post, if needed.

Script:
Spoiler:
Download source  Code

//   VIETCONG 1
//   Punji_Pit_Trap_random script v3.1 (Writen for custom object -  punji_pit_trap.BES)
//   made by Ando


/*
   ______________TRAP DESCRIPTION IN REALITY:
When a man falls into the Punji Pit, he will be injured by the pointed
bamboo stakes which will cut his thighs and hips, or stab him through
the back, often these spikes are connected to a hand grenade,
designed to explode when the man is pulled out of the pit.


    ______________TRAP BEHAVIOUR IN GAME:
If player walk over trap cover then it fall down with player.
When player collide with spices then he will die.
Trap cover will fall also when hit by gun/knife 2 times or hit by grenade.
When trap cover is down then player can destroy that trap.
After start/restart trap will appear randomly.


   ______________TUTORIAL FOR EDITOR
- Trap hole(s) must be added to terrain in MAX.
- add trap object precisely to hole
- for that use: "Settings" > "Snap settings" and turn on "vertex" only
- turn on "Snap translator"
- now you can move cover precisely to right place
- add script to trap object in level.c script
   

   _____________BUGS:
none


   _____________NOTES:
2.2 - removed one rare bug (dont count shots anymore when moveing)
2.2 - improved code (restart area)
2.2   - added particles
3.0 - tested with team (thanks to Intruder)
3.1   - added more particles when cover is falling
3.1 - trap is randomly on/off
3.1 - added sign
3.1 - added option to disarm trap
   ______________IDEAS:
none

*/


#include <inc\sc_global.h>
#include <inc\sc_def.h>

//____________________________OBJECT PARAMETERS____________________________

//OBJECT STATES: 0 - trap up , 1 - fall down, 2 -  down, 3 - destroyed, 4 - no trap

#define DISARM_STRING         2805      //#7362:    #tee Enable
                                 //#7361:    #tee Disable
                                 //#2805:    #tee to disarm trap.


#define FALL_SOUND            1869      //1869, 1933

#define FALL_TIME            0.3f      //trap cover movement time
#define FALL_DIST            0.3f      //trap cover fall distance
#define HITS_TO_FALL         2         //number of hits when trap cover is falling down
#define   cover_tr_sub_obj      "pit_top_tr"      //trap cover sub object
#define   cover_sub_obj         "pit_top"      //
#define   spices_sub_obj         "spices_1"      //
#define   spices_dstr_sub_obj      "spices_destr"      //


//_________________________________________________________________________

#define GVAR_SERVER            600    // don't edit   //0 - not server . 1 - server
#define GVAR_COUNT            601    // don't edit   //Channel for G-var count
#define GVAR_GPHASE            500      // don't edit
//_________________________________________________________________________

void      *cover_tr_sub_obj_id;
void      *cover_sub_obj_id;
void      *spices_sub_obj_id;
void      *spices_dstr_sub_obj_id;


s_SC_NOD_transform   trans;
s_SC_NOD_transform   trans_swing;
s_SC_NOD_transform   orig_trans_cover_tr;
s_SC_NOD_transform   orig_trans_cover;
s_SC_NOD_transform   orig_trans_spices;
s_SC_NOD_transform   orig_trans_spices_dstr;
c_Vector3      vec2;
c_Vector3      vec3;

float      val = 0.0f;
float      timer = 0.0f;

int         hit_count = 0;
int         Temp =   0;   //global object status
int         Temp2 =   -1;   //local object status.  -1 = unknown ststus  (for start/restart)
int         Temp3 = 0;   //local movement status
//int         r_dir = 1;   // rotation direction
int      my_gvar_count;
int      my_gvar;


BOOL      SRV_restart_done = FALSE;

//s_SC_P_getinfo   pl_info;

//dword       list[32];
//dword       player;
//int         i_items,j;


int ScriptMain(s_SC_OBJ_info *info){
   switch(info->event_type){
      case SC_OBJ_INFO_EVENT_INIT:
         cover_tr_sub_obj_id = SC_NOD_GetNoMessage(info->master_nod, cover_tr_sub_obj);
         cover_sub_obj_id = SC_NOD_GetNoMessage(info->master_nod, cover_sub_obj);
         spices_sub_obj_id = SC_NOD_GetNoMessage(info->master_nod, spices_sub_obj);
         spices_dstr_sub_obj_id = SC_NOD_GetNoMessage(info->master_nod, spices_dstr_sub_obj);


         SC_NOD_GetTransform(cover_tr_sub_obj_id,&orig_trans_cover_tr);   
         SC_NOD_GetTransform(cover_sub_obj_id,&orig_trans_cover);
         SC_NOD_GetTransform(spices_sub_obj_id,&orig_trans_spices);
         SC_NOD_GetTransform(spices_dstr_sub_obj_id,&orig_trans_spices_dstr);



         //creating global variable
         my_gvar_count = SC_ggi(GVAR_COUNT)+1;
         SC_sgi(GVAR_COUNT,my_gvar_count);
         my_gvar = my_gvar_count+ 601;
         break;
      case SC_OBJ_INFO_EVENT_JUSTLOADED:
         break;
      case SC_OBJ_INFO_EVENT_RELEASE:
         SC_NOD_SetTransform(cover_tr_sub_obj_id,&orig_trans_cover_tr);   
         SC_NOD_SetTransform(cover_sub_obj_id,&orig_trans_cover);
         SC_NOD_SetTransform(spices_sub_obj_id,&orig_trans_spices);
         SC_NOD_SetTransform(spices_dstr_sub_obj_id,&orig_trans_spices_dstr);

         Temp2 = -1;   //restores unknown state
         break;
      case SC_OBJ_INFO_EVENT_HIT: 
         //switch(Temp){
         //case 0://trap up
         //   if(info->nod == cover_tr_sub_obj_id){
         //      hit_count++;
         //   }   
         //   break;
         //case 2://trap down
         //   break;
         //}
         if(info->nod == cover_tr_sub_obj_id){
            if(Temp == 0){
               hit_count++;
               if ((hit_count >= HITS_TO_FALL) || (info->hit_by == SC_OBJ_HIT_BY_EXPLOSION)){
                  SC_sgi(my_gvar,1); //
               }
            }
         }
         break;
      case SC_OBJ_INFO_EVENT_DOTICK:
         if (SC_ggi(GVAR_GPHASE) == 1){//restart
            if (SC_ggi(GVAR_SERVER) == 1){   // its server
               if (!SRV_restart_done){//restores start state for trap
                  if((rand() % 2)== 0){
                     SC_sgi(my_gvar,0); // status on start/restart (trap up)
                  }else{
                     SC_sgi(my_gvar,4); // status on start/restart (no trap)
                  }
                  SRV_restart_done=TRUE;
               }
               
            }
            Temp2 = -1;   //restores unknown state for trap
            return TRUE;
         }
         if (Temp2 == -1){//first run after restart
            if (SC_ggi(GVAR_SERVER) == 1){   // its server
               SRV_restart_done=FALSE;   //for next restert , if needed
            }
         }
         Temp = SC_ggi(my_gvar);
         //______________USE OBJECT__________
         if (Temp == Temp2){   //was strange collision bug without it
            switch(Temp){   //
            case 0:   // trap up
               if (SC_NOD_GetCollision(info->master_nod, cover_tr_sub_obj, TRUE)){//SC_NOD_GetCollision(info->master_nod, wire_sub_obj, TRUE))
                  SC_sgi(my_gvar,1); //___sync
                  Temp = 1;
               }
               break;
            case 2:   // drap down
               val = SC_DOBJ_CameraLooksAt(info->master_nod,2);
               if (val<1.0f){
                  SC_ACTIVE_Add(info->master_nod,2.0f*val,DISARM_STRING);//USE string
               }
               break;
            }//switch(Temp)
         }
         //_____________CHANGE OBJECT STATUS________________
         if (Temp != Temp2){   //global status != Local status
            switch(Temp){
            case 0:   // trap up
               SC_NOD_SetTransform(cover_tr_sub_obj_id,&orig_trans_cover_tr); //visible
               trans=orig_trans_cover;
               trans.loc.z-=1000;
               SC_NOD_SetTransform(cover_sub_obj_id,&trans);// not visible
               trans=orig_trans_spices;
               trans.loc.z-=1000;
               SC_NOD_SetTransform(spices_sub_obj_id,&trans);// not

               trans=orig_trans_spices_dstr;
               trans.loc.z-=1000;
               SC_NOD_SetTransform(spices_dstr_sub_obj_id,&trans);
               hit_count = 0;
               Temp2=0;
               Temp3=0;
               SC_NOD_GetCollision(info->master_nod, cover_tr_sub_obj, TRUE);//!!It must be here!!  It will remove collision info related with move
               break;
            case 1:   // drap move
               switch(Temp3){
               case 0:   //start moving

                  SC_NOD_SetTransform(spices_sub_obj_id,&orig_trans_spices);// visible
                  trans=orig_trans_cover;
                  trans.loc.z-=1000;
                  SC_NOD_SetTransform(cover_sub_obj_id,&trans);// not visible

                  SC_NOD_GetWorldPos(cover_tr_sub_obj_id, &vec2);
                  SC_SND_PlaySound3D(FALL_SOUND,&vec2);
                  vec3=vec2;
                  vec3.x+=0.5f;
                  SC_CreatePtc(165,  &vec3);
                  vec3=vec2;
                  vec3.x-=0.5f;
                  SC_CreatePtc(165,  &vec3);
                  vec3=vec2;
                  vec3.y+=0.5f;
                  SC_CreatePtc(165,  &vec3);
                  vec3=vec2;
                  vec3.y-=0.5f;
                  SC_CreatePtc(165,  &vec3);


                  SC_NOD_SetTransform(cover_tr_sub_obj_id,&orig_trans_cover); //
                  timer = 0;
                  Temp3=1;
                  break;
               case 1:   //normal move
                  timer+=info->time;
                  if (timer >= FALL_TIME){//move over
                     Temp3 = 2;
                     if (SC_ggi(GVAR_SERVER) == 1){
                        SC_sgi(my_gvar,2); //trap down for server
                     }
                     return TRUE;
                  }
                  trans=orig_trans_cover;
                  trans.loc.z-=(FALL_DIST*timer/FALL_TIME);
                  SC_NOD_SetTransform(cover_tr_sub_obj_id,&trans);
                  break;
               case 2:   //
                  break;
               }//switch(Temp3){
               break;
            case 2:   // trap down
               timer = 0.0f;
               trans = orig_trans_cover_tr;
               trans.loc.z-=1000;
               SC_NOD_SetTransform(cover_tr_sub_obj_id,&trans);
               trans=orig_trans_cover;
               trans.loc.z-=1000;
               SC_NOD_SetTransform(cover_sub_obj_id,&trans);// not visible
               SC_NOD_SetTransform(spices_sub_obj_id,&orig_trans_spices);
               trans=orig_trans_spices_dstr;
               trans.loc.z-=1000;
               SC_NOD_SetTransform(spices_dstr_sub_obj_id,&trans);
               Temp2=2;
               break;
            case 3:   // trap destroyed
               timer = 0.0f;
               trans = orig_trans_cover_tr;
               trans.loc.z-=1000;
               SC_NOD_SetTransform(cover_tr_sub_obj_id,&trans);
               trans = orig_trans_cover;
               trans.loc.z-=1000;
               SC_NOD_SetTransform(cover_sub_obj_id,&trans);
               trans = orig_trans_spices;
               trans.loc.z-=1000;
               SC_NOD_SetTransform(spices_sub_obj_id,&trans);
               SC_NOD_SetTransform(spices_dstr_sub_obj_id,&orig_trans_spices_dstr);
               Temp2=3;
               break;
            case 4:   // no trap
               trans = orig_trans_cover_tr;
               trans.loc.z-=1000;
               SC_NOD_SetTransform(cover_tr_sub_obj_id,&trans);   //no
               SC_NOD_SetTransform(cover_sub_obj_id,&orig_trans_cover);//vis
               trans = orig_trans_spices;
               trans.loc.z-=1000;
               SC_NOD_SetTransform(spices_sub_obj_id,&trans);//no
               trans = orig_trans_spices_dstr;
               trans.loc.z-=1000;
               SC_NOD_SetTransform(spices_dstr_sub_obj_id,&trans);
               Temp2=4;
               break;
            }
         }
            break;
      case SC_OBJ_INFO_EVENT_USED:
         SC_sgi(my_gvar,3);
        break;
   }// switch(info->event_type)
   return FALSE;
 }// int ScriptMain(s_OBJ_info *info)



Ando attached the following file:
_punji_pit_trap_random.rar [2.15 MB, 334 Downloads]
  x 2
 
Ando
ATGCoop script with automatic global variable system (advanced)

details compared with original ATG:
- added automatic global variable system
- changed mission time for longer missions
- disabled "wait for next round" after join
- added sound for score
- added fade for restart and score respawn

Spoiler:
Download source  Code
//   VIETCONG 1
//   ATG_Coop script (with automatic global variables for synchronized objects)
//   modified by Ando from Eric multiplayer script - ATG - kill the others
//   v3.0


//   NOTES:
// 1.3 - added variable for server (600) to detect server from object scripts
// 1.3 - new G-var system (object scripts counting g-vars to channel 601 )
// 1.4 - SC_MP_RestartMission()command stops all synchro, even if I create new after that
//       I replace it with SC_MP_RecoverAllNoAiPlayers() and SC_MP_RecoverAllAiPlayers()
// 2.0 - added fade for restart and score respawn
// 2.0 - added sound for score
// 3.0 - Created ATGCOOP from ATG
// 3.0 - changed mission time 7200 s (120 min)
// 3.0 - disabled "wait for next round"







#include <inc\sc_global.h>
#include <inc\sc_def.h>

//________________________________
//global variable system for object synchro
#define GVAR_SERVER         600    //   server  ( dont add SC_MP_Gvar_SetSynchro for that) 0 - not server, 1 - server
#define GVAR_COUNT         601    //  count of object variables ( dont add SC_MP_Gvar_SetSynchro for that)
#define GVAR_USE_start      602       //start      Global variable
//________________________________

#define GVAR_GPHASE 500      // important to use  game phase and channel 500 for synchronised objects
//________________________________

#define FADE_TIME         0.8

#define NORECOV_TIME   3.0f      // disable time of recoverplace after recovering someone there

#define REC_WPNAME_US   "USSpawn_atg_%d"
#define REC_WPNAME_VC   "VCSpawn_atg_%d"
#define REC_MAX         64


#define GMISSION_TIME               7200.0f

#define GVAR_SIDE0POINTS            501
#define GVAR_SIDE1POINTS            502
#define GVAR_MISSIONTIME            503
#define GVAR_MISSIONTIME_UPDATE         504

dword gRecs[2] = {0,0};
s_SC_MP_Recover gRec[2][REC_MAX];
float gRecTimer[2][REC_MAX];

int gSidePoints[2] = {0,0};

int gCLN_SidePoints[2] = {0,0};


#define GPHASE_BEGIN            1
#define GPHASE_GAME               2
#define GPHASE_VCKILLED            3
#define GPHASE_USKILLED            4
#define GPHASE_TIMEDONE            5
#define GPHASE_BEFORE_RESTART      6
#define GPHASE_RESTARTING         7   


#define RESTART_TIMER      6   //time before actual restart
#define FAIL_TIMER         5   //time before actual restart



dword gPhase = GPHASE_BEGIN;
float gPhase_timer = 0.0f;
float   client_fade_timer;
dword gSend_Phase;


dword gEndRule;
dword gEndValue;
float gTime;
float gMissionTime = 0;
float gMissionTime_update;

float gCLN_MissionTime;
dword gCLN_MissionTimePrevID;

BOOL    fade_off = TRUE;
BOOL    sound_on = TRUE;

BOOL SRV_CheckEndRule(float time){

   switch(gEndRule){
      case SC_MP_ENDRULE_TIME:
         if (gPhase!=GPHASE_BEGIN) gTime += time;
         SC_MP_EndRule_SetTimeLeft(gTime,gPhase!=GPHASE_BEGIN);
         if (gTime>gEndValue){
            SC_MP_LoadNextMap();
            return TRUE;
         }
         break;
      case SC_MP_ENDRULE_POINTS:
         if ((gSidePoints[0]>=gEndValue)||(gSidePoints[1]>=gEndValue)){
            SC_MP_LoadNextMap();
            return TRUE;
         }
         break;
      default:
         SC_message("EndRule unsopported: %d",gEndRule);
         break;
   }// switch(gEndRule)
   return FALSE;
}// void SRV_CheckEndRule(float time)


void UpdateSidePoints(void){
   SC_sgi(GVAR_SIDE0POINTS,gSidePoints[0]);
   SC_sgi(GVAR_SIDE1POINTS,gSidePoints[1]);
}// void UpdateSidePoints(void)


void SRV_CheckUpdate(void){
   if (gSend_Phase != gPhase){      
      gSend_Phase = gPhase;
      SC_sgi(GVAR_GPHASE,gPhase);      
   }
}// void SRV_CheckUpdate(void)


void SRV_UpdateMissionTime(float time){
   gMissionTime_update -= time;
   if (gMissionTime_update<0.0f){
      gMissionTime_update = 10.0f;
      SC_sgf(GVAR_MISSIONTIME,gMissionTime);
      SC_sgi(GVAR_MISSIONTIME_UPDATE,SC_ggi(GVAR_MISSIONTIME_UPDATE)+1);      
   }// if (gMissionTime_update<0.0f)
}


void Check_ABL(void){
   int val;
   dword side,nr_to_change;
   s_SC_P_getinfo info;
   s_SC_MP_EnumPlayers enum_pl[64];
   dword i,j,k;
   if (!SC_MP_SRV_GetAutoTeamBalance()) return;
   val = SC_MP_SRV_GetTeamsNrDifference(TRUE);
   if ((val<3)&&(val>-3)) return;   // no big difference
   if (val>0){
      side = 0;
      nr_to_change = val/2;
   }
   else{
      side = 1;
      nr_to_change = -val/2;
   }
   // find nr_to_change players of beste players of side 0
   j = 64;
   if (SC_MP_EnumPlayers(enum_pl,&j,side)){            
      if (!j) return;
      while(nr_to_change!=0){
         k = rand()%j;
         i = k;
         while(
            (enum_pl[i].id==0)
            ||(enum_pl[i].status==SC_MP_P_STATUS_NOTINGAME)){
            i++;
            if (i==j) i = 0;
            if (i==k) return;   // no valid found
         }                  
         SC_MP_SRV_P_SetSideClass(enum_pl[i].id,1-side,1 + 20*(1-side));
         enum_pl[i].id = 0;
         nr_to_change--;
      }// while(nr_to_change!=0)            
   }// if (SC_MP_EnumPlayers(enum_pl,&j,SC_MP_ENUMPLAYER_SIDE_ALL))
}// void Check_ABL(dword pl_handle)




int ScriptMain(s_SC_NET_info *info){
   char txt[32],*itxt;
   ushort *witxt;
   dword i,j;
   s_SC_MP_Recover *precov;
   s_SC_MP_hud hudinfo;
   s_SC_P_getinfo plinfo;
   float val,valy;
   void *nod;
   s_SC_MP_EnumPlayers enum_pl[64];
   int valid[2],active;
   dword pilot_pl_id;
   c_Vector3 pl_pos;
   s_SC_MP_SRV_settings SRVset;
   s_SC_HUD_MP_icon icon[3];
   dword icons;
   BOOL in_middle;
   s_SC_MP_SRV_AtgSettings atgset;

   switch(info->message){
      
      case SC_NET_MES_SERVER_TICK:   
         if (SRV_CheckEndRule(info->elapsed_time)) break;
         for (j=0;j<2;j++)
         for (i=0;i<gRecs[j];i++)
            gRecTimer[j][i] -= info->elapsed_time;
         CLEAR(valid);
         j = 64;
         pilot_pl_id = 0;
         if (SC_MP_EnumPlayers(enum_pl,&j,SC_MP_ENUMPLAYER_SIDE_ALL)){            
            if ((j==0)&&((gSidePoints[0]+gSidePoints[1])!=0)){
               gSidePoints[0] = 0;
               gSidePoints[1] = 0;
               UpdateSidePoints();
            }// if ((side[0]+side[1])==0)
            for (i=0;i<j;i++)
               if (enum_pl[i].status==SC_MP_P_STATUS_INGAME){
                  if (enum_pl[i].side<2) valid[enum_pl[i].side] = TRUE;
               }// if (enum_pl[i].status==SC_MP_P_STATUS_INGAME)
         }// if (SC_MP_EnumPlayers(enum_pl,&j,SC_MP_ENUMPLAYER_SIDE_ALL))
         
         
         
         gPhase_timer -= info->elapsed_time;
         switch(gPhase){
            case GPHASE_BEGIN:
               SC_MP_SetInstantRecovery(TRUE);
               //start with gPhase_timer 5
               if (gPhase_timer>2.0f) break;
               if ((valid[0])&&(valid[1])){   
                  if (gPhase_timer<-7.0f){
                     Check_ABL();
                     SC_MP_SRV_InitGameAfterInactive();
                     SC_MP_RecoverAllNoAiPlayers();
                     SC_MP_RecoverAllAiPlayers();
                  }
                  else{   
                     gPhase = GPHASE_GAME;
                     SC_MP_SRV_GetAtgSettings(&atgset);
                     if (atgset.ATG_round_time>29.0f)
                        gMissionTime = atgset.ATG_round_time;                        
                     else
                        gMissionTime = GMISSION_TIME;
                     SRV_UpdateMissionTime(1000);
                  }
                  gPhase_timer = 0.0f;//???????????   for game phase
               }// switch(valid[0])               
               break;// GPHASE_BEGIN
            case GPHASE_GAME:
               SC_MP_SetInstantRecovery(FALSE);
               //gPhase_timer += info->elapsed_time;
               if (gPhase_timer>-4.0f) break;
               if (!valid[0]){
                  gSidePoints[1]++;
                  UpdateSidePoints();
                  gPhase = GPHASE_USKILLED;
                  gPhase_timer = RESTART_TIMER;
               }
               else
               if (!valid[1]){
                  gSidePoints[0]++;
                  UpdateSidePoints();
                  gPhase = GPHASE_VCKILLED;
                  gPhase_timer = RESTART_TIMER;
               }
               else{
                  // check pilot distance
                  gMissionTime -= info->elapsed_time;
                  SRV_UpdateMissionTime(info->elapsed_time);
                  if (gMissionTime<0.0f){                                                
                     gPhase = GPHASE_TIMEDONE;
                     gPhase_timer = 5.0f;
                     gMissionTime = 0.0f;
                     SRV_UpdateMissionTime(1000);
                  }// if (gMissionTime<0.0f)
               }
               break;// GPHASE_GAME
            case GPHASE_BEFORE_RESTART:
               if (gPhase_timer<0.0f){   //wait before restart
                  gPhase = GPHASE_RESTARTING;
               }
               break;
            case GPHASE_RESTARTING:
               gTime = 0;
               gPhase=GPHASE_BEGIN;
               gPhase_timer = 5.0f;
               SC_sgi(GVAR_GPHASE,gPhase);//(1 = begin) For sync. objects.  server restart
               CLEAR(gSidePoints);         
               UpdateSidePoints();
               SC_MP_SetInstantRecovery(TRUE);
               SC_MP_SRV_ClearPlsStats();
               SC_MP_SRV_InitGameAfterInactive();
               SC_MP_RecoverAllNoAiPlayers();   
               break;
            case GPHASE_USKILLED:
            case GPHASE_VCKILLED:
            case GPHASE_TIMEDONE:
            //default:
               SC_MP_SetInstantRecovery(FALSE);
               if (gPhase_timer<0){
                  Check_ABL();
                  //SC_MP_RestartMission();//stops all synchro, even if I create new after that
                  SC_MP_RecoverAllNoAiPlayers();   //replaced SC_MP_RestartMission with it
                  SC_MP_RecoverAllAiPlayers();   //replaced SC_MP_RestartMission with it

                  gPhase = GPHASE_BEGIN;
                  gPhase_timer = 5.0f;
               }
               break;
         }// switch(gPhase)
         SRV_CheckUpdate();
         break;
      case SC_NET_MES_CLIENT_TICK:
         gCLN_SidePoints[0] = SC_ggi(GVAR_SIDE0POINTS);
         gCLN_SidePoints[1] = SC_ggi(GVAR_SIDE1POINTS);
         SC_MP_SetSideStats(0,0,gCLN_SidePoints[0]);
         SC_MP_SetSideStats(1,0,gCLN_SidePoints[1]);
         if (gCLN_MissionTimePrevID!=SC_ggi(GVAR_MISSIONTIME_UPDATE)){
            gCLN_MissionTimePrevID = SC_ggi(GVAR_MISSIONTIME_UPDATE);
            gCLN_MissionTime = SC_ggf(GVAR_MISSIONTIME);
         }
         else{
            gCLN_MissionTime -= info->elapsed_time;
         }
         for (i=0;i<2;i++){
            icon[i].color = 0xbbffffff;            
            icon[i].type = SC_HUD_MP_ICON_TYPE_NUMBER;
            icon[i].icon_id = 3*i;
            icon[i].value = gCLN_SidePoints[i];
         }
         icons = 2;
         if ((gCLN_MissionTime>0.0f)&&(SC_ggi(GVAR_GPHASE)==GPHASE_GAME)){
            icon[icons].color = 0xbbffffff;
            icon[icons].icon_id = 6;
            icon[icons].value = (int)(gCLN_MissionTime+0.99f);               
            icon[icons].type = SC_HUD_MP_ICON_TYPE_TIME;
            icons++;
         }
         SC_MP_SetIconHUD(icon,icons);

         //_____________________________
         switch(SC_ggi(GVAR_GPHASE)){
         case GPHASE_BEGIN:
            if (fade_off == FALSE){
               SC_FadeTo(FALSE, FADE_TIME);
               fade_off=TRUE;
            }
            // score sound
            sound_on = TRUE;

            break;
         case GPHASE_GAME:
            break;
         case GPHASE_VCKILLED:
         case GPHASE_USKILLED:
         case GPHASE_TIMEDONE:
         case GPHASE_BEFORE_RESTART:

            //sound for score
            if (sound_on){
               if (SC_ggi(GVAR_GPHASE)== GPHASE_VCKILLED){
                  SC_SND_PlaySound2D(11117);
               
               }else{
                  SC_SND_PlaySound2D(11116);
               }

            // play sound
            //
               sound_on = FALSE;

            
            }





            client_fade_timer -= info->elapsed_time;

            if (client_fade_timer<FADE_TIME){   
               SC_FadeTo(TRUE, FADE_TIME);
               fade_off=FALSE;
               client_fade_timer=RESTART_TIMER;
            }
            break;
         case GPHASE_RESTARTING:
            break;
         }// switch(gPhase)
         //_____________________________


         break;// SC_NET_MES_CLIENT_TICK



      case SC_NET_MES_LEVELPREINIT:
         client_fade_timer=RESTART_TIMER;
         SC_sgi(GVAR_MP_MISSIONTYPE,GVAR_MP_MISSIONTYPE_ATG);
         gEndRule = info->param1;
         gEndValue = info->param2;
         gTime = 0.0f;
         SC_MP_EnableBotsFromScene(FALSE);
         break;// SC_NET_MES_LEVELPREINIT
      case SC_NET_MES_LEVELINIT:      
         //_____________________________________automatic custom global variables_________________
         for (i=GVAR_USE_start;i<GVAR_USE_start+SC_ggi(GVAR_COUNT)+1;i++){   //custom global variables
            SC_MP_Gvar_SetSynchro(i);
            
         }
         //_______________________________________________________________________________________
         


         SC_MP_GetSRVsettings(&SRVset);
         for (i=0;i<6;i++){
            SC_MP_SRV_SetClassLimit(i+1,SRVset.atg_class_limit[i]);
            SC_MP_SRV_SetClassLimit(i+21,SRVset.atg_class_limit[i]);
         }// for (i)
         SC_MP_SRV_SetForceSide(0xffffffff);
         SC_MP_SetChooseValidSides(3);
         SC_MP_SRV_SetClassLimit(18,0);
         SC_MP_SRV_SetClassLimit(19,0);
         SC_MP_SRV_SetClassLimit(39,0);
         CLEAR(hudinfo);
         hudinfo.title = 1048;
         hudinfo.sort_by[0] = SC_HUD_MP_SORTBY_KILLS;
         hudinfo.sort_by[1] = SC_HUD_MP_SORTBY_DEATHS | SC_HUD_MP_SORT_DOWNUP;
         hudinfo.sort_by[2] = SC_HUD_MP_SORTBY_PINGS | SC_HUD_MP_SORT_DOWNUP;
         hudinfo.pl_mask = SC_HUD_MP_PL_MASK_CLASS | SC_HUD_MP_PL_MASK_KILLS | SC_HUD_MP_PL_MASK_DEATHS;
         hudinfo.use_sides = TRUE;
         hudinfo.side_name[0] = 1010;
         hudinfo.side_color[0] = 0x440000ff;
         hudinfo.side_name[1] = 1011;
         hudinfo.side_color[1] = 0x44ff0000;
         hudinfo.side_mask = SC_HUD_MP_SIDE_MASK_POINTS;
         SC_MP_HUD_SetTabInfo(&hudinfo);   
         SC_MP_AllowStPwD(TRUE);
         SC_MP_AllowFriendlyFireOFF(TRUE);
         SC_MP_SetItemsNoDisappear(TRUE);
         if (info->param2){
            if (info->param1){
               // it's server      

               //_______________________________________________________________________________________
               SC_sgi(GVAR_SERVER,1);
               SC_MP_Gvar_SetSynchro(GVAR_GPHASE);
               SC_sgi(GVAR_GPHASE,gPhase);

               //_______________________________________________________________________________________

               SC_MP_Gvar_SetSynchro(GVAR_SIDE0POINTS);
               SC_MP_Gvar_SetSynchro(GVAR_SIDE1POINTS);
               UpdateSidePoints();
               SC_MP_Gvar_SetSynchro(GVAR_MISSIONTIME);
               SC_MP_Gvar_SetSynchro(GVAR_MISSIONTIME_UPDATE);
               SC_sgf(GVAR_MISSIONTIME,0.0f);
               SC_sgi(GVAR_MISSIONTIME_UPDATE,0);      

               //SC_MP_Gvar_SetSynchro(GVAR_GPHASE);
                                       
               
               CLEAR(gRecs);
            

               for (i=0;i<REC_MAX;i++){      
                  sprintf(txt,REC_WPNAME_US,i);         
                  if (SC_NET_FillRecover(&gRec[0][gRecs[0]],txt)) gRecs[0]++;               
               }               


#if _GE_VERSION_ >= 133
               i = REC_MAX - gRecs[0];
               SC_MP_GetRecovers(SC_MP_RESPAWN_ATG_US,&gRec[0][gRecs[0]],&i);
               gRecs[0] += i;
#endif
               SC_Log(3,"ATG S&D respawns us: %d",gRecs[0]);
   

               if (gRecs[0]==0) SC_message("no US recover place defined!");

               for (i=0;i<REC_MAX;i++){      
                  sprintf(txt,REC_WPNAME_VC,i);         
                  if (SC_NET_FillRecover(&gRec[1][gRecs[1]],txt)) gRecs[1]++;
               }                                       

#if _GE_VERSION_ >= 133
               i = REC_MAX - gRecs[1];
               SC_MP_GetRecovers(SC_MP_RESPAWN_ATG_VC,&gRec[1][gRecs[1]],&i);
               gRecs[1] += i;
#endif
               SC_Log(3,"ATG S&D respawns vc: %d",gRecs[0]);


               if (gRecs[1]==0) SC_message("no VC recover place defined!");                              
                                                      

               CLEAR(gRecTimer);

            }// if (info->param1)

         }//if (info->param2)


         break;// SC_NET_MES_LEVELINIT


      case SC_NET_MES_RENDERHUD:
         i = 0;
         in_middle = FALSE;
         switch(SC_ggi(GVAR_GPHASE)){
            case GPHASE_BEGIN:i = 1076;break;            
            case GPHASE_VCKILLED:i = 1096;in_middle = TRUE;break;
            case GPHASE_USKILLED:i = 1047;in_middle = TRUE;break;
            case GPHASE_TIMEDONE:i = 1046;in_middle = TRUE;break;

         }// switch(SC_ggi(GVAR_GPHASE))
         if (i){
            witxt = SC_Wtxt(i);
            SC_GetScreenRes(&val,&valy);
            val -= SC_Fnt_GetWidthW(witxt,1);
            if (in_middle){
               valy = 0.5f * valy - 40.0f;
            }else{
               valy = 15;
            }


            SC_Fnt_WriteW(val * 0.5f,valy,witxt,1,0xffffffff);
         }//if (i)   
         break;
      case SC_NET_MES_SERVER_RECOVER_TIME:
         SC_MP_SRV_GetAtgSettings(&atgset);
         if ((gPhase==GPHASE_GAME) &&((gMissionTime+10.0f)<atgset.ATG_round_time)){
            if (info->param2){
               info->fval1 = 0.1f;

            }else{
               info->fval1 = SC_NET_SERVER_RECTIME_ENDOFROUND;
            
            }

         }
         else
            if (gPhase==GPHASE_BEGIN){
               info->fval1 = 0.1f;
            }
         else

         if (info->param2){
               info->fval1 = 0.1f;
         }
         else{
            // killed
            info->fval1 = -1.0f;
         }
         break;
      case SC_NET_MES_SERVER_RECOVER_PLACE:
         precov = (s_SC_MP_Recover*)info->param2;
         i = SC_MP_SRV_GetBestDMrecov(gRec[info->param1],gRecs[info->param1],gRecTimer[info->param1],NORECOV_TIME);
         gRecTimer[info->param1][i] = NORECOV_TIME;
         *precov = gRec[info->param1][i];      
         break;
      case SC_NET_MES_SERVER_KILL:
         break;// SC_NET_MES_SERVER_KILL
      case SC_NET_MES_MESSAGE:
         break;
      case SC_NET_MES_RESTARTMAP:
         gPhase_timer = RESTART_TIMER;
         gPhase = GPHASE_BEFORE_RESTART;
         break;// SC_NET_MES_RESTARTMAP
      case SC_NET_MES_RULESCHANGED:         
         gEndRule = info->param1;
         gEndValue = info->param2;
         gTime = 0.0f;
         break;      
   }// switch(info->message)
   return 1;
}// int ScriptMain(void)



Edited by Ando on 25-10-2011 21:38
  x 1
 
Ando
Coop_us script with automatic global variable system (advanced)

details compared with original coop:
- added automatic global variable system
- added civilian option
- mission restart when civilian is killed by US an message appears who killed civilian
- restart with fade
- switch to next map when mission done
- added sound for "mission FAILED"
- added sound for "mission DONE"


Spoiler:
Download source  Code
//   VIETCONG 1
//   COOP_US script (with automatic global variables for synchronized objects)
//   modified by Ando
//   v3.1


//   NOTES:
// 1.1 - added global variables system
// 1.2 - added variable for server (600) to detect server from object scripts
// 1.2 - new G-var system (object scripts counting g-vars to channel 601 )
// 1.4 - added mission objectives test (removed later but was working)
// 2.0 - successfully tested with L|DC-78
// 2.1 - added civilian option
// 2.1 - mission restart when civilian is killed by US an message appears who killed civilian
// 2.1 - "mission fail" restart with fast fade
// 2.1 - fade when mission restarts
// 2.2 - switch to next map when mission done
// 3.0 - TESTED WITH TEAM
// 3.1 - added sound for "mission FAILED"
// 3.1 - added sound for "mission DONE"

// IDEAS

//   show killed civilian before restart    void SC_P_SetLinkedView(dword pl_id, float rz, float rx);





#include <inc\sc_global.h>
#include <inc\sc_def.h>

#define FADE_TIME         0.8

#define      DONE_SOUND      6035   //snd 6035 music\slap25.ogg
#define      FAILED_SOUND   6057   //snd 6057 music\slap47.ogg
//________________________________
//global variable system for object synchro  !!!DONT CHANGE THOSE!!!
#define GVAR_SERVER         600    //   server  ( dont add SC_MP_Gvar_SetSynchro for that) 0 - not server, 1 - server
#define GVAR_COUNT         601    //  count of Global variables ( dont add SC_MP_Gvar_SetSynchro for that)
#define GVAR_USE_start      602       //start nr of   Global variable nr
//________________________________

#define GVAR_GPHASE            500      // important to use  game phase and channel 500 for synchronised objects


#define GVAR_KILLED            501
#define GVAR_KILLER            502



//#define RECOVER_TIME   15.0f      // time to global recover
#define NORECOV_TIME   3.0f      // disable time of recoverplace after recovering someone there

#define REC_WPNAME_US   "USSpawn_coop_%d"
#define REC_MAX         64


s_SC_Objective Objectives [10];
int objective_count=0;
int remaining_time=0;


dword gRecs = 0;
s_SC_MP_Recover gRec[REC_MAX];
float gRecTimer[REC_MAX];

float gNextRecover = 0.0f;

dword gEndRule;
dword gEndValue;
float gTime;

#define GPHASE_BEGIN         1
#define GPHASE_GAME            2
#define GPHASE_DONE            3
#define GPHASE_FAILED         4
#define GPHASE_BEFORE_RESTART   5
#define GPHASE_RESTARTING      6   

#define RESTART_TIMER      3   //time before actual restart
#define FAIL_TIMER         5   //time before actual restart

dword   gPhase = GPHASE_BEGIN;
float   gPhase_timer = 5.0f;
float   client_fade_timer;
dword   gPhase_send = 0;

BOOL gValidSide0 = FALSE;
BOOL    notincar = TRUE;
BOOL    fade_off = TRUE;
BOOL   sound_start=TRUE;

dword gRecoverTime =   0;
dword gRecoverLimit =   0;

float gAllNoAiRecover  = 0.0f;

dword help_txt[3];


BOOL SRV_CheckEndRule(float time){
   switch(gEndRule){
      case SC_MP_ENDRULE_TIME:         
         if (gValidSide0) gTime += time;
         SC_MP_EndRule_SetTimeLeft(gTime,gValidSide0);
         if (gTime>gEndValue){
//            SC_MP_LoadNextMap();
            return TRUE;
         }
         break;
      default:
         SC_message("EndRule unsopported: %d",gEndRule);
         break;
   }// switch(gEndRule)
   return FALSE;
}// void SRV_CheckEndRule(float time)

void SRV_CheckUpdate(void){
   if (gPhase_send!=gPhase){
      gPhase_send = gPhase;
      SC_sgi(GVAR_GPHASE,gPhase);
      //SC_message("SRV_CheckUpdate %d",gPhase);
   }// if (gPhase_send!=gPhase)
}// void SRV_CheckUpdate(void)

int ScriptMain(s_SC_NET_info *info)
{
   s_SC_MP_EnumPlayers enum_pl[64];
   s_SC_MP_SRV_settings SRVset;
   s_SC_MP_Recover *precov;
   s_SC_MP_hud hudinfo;
   s_SC_P_getinfo plinfo;
   s_SC_P_getinfo my_plinfo;
   dword   i, j, sideA, sideB, num;
   BOOL   valid[2];
   BOOL   alldeath;
   char   txt[32],*itxt;
   ushort wtxt[128],wtxt2[64],*witxt,*my_witxt;
   float   sc_width,sc_height,val;


   switch(info->message){
      case SC_NET_MES_SERVER_TICK:   
         if (SRV_CheckEndRule(info->elapsed_time)) break;
         for (j=0;j<4;j++)
         for (i=0;i<gRecs;i++)
            gRecTimer[i] -= info->elapsed_time;
         if (gRecoverTime<0xffff){
            gNextRecover -= info->elapsed_time;
            if (gNextRecover<0.0f) gNextRecover = (float)gRecoverTime;
         }// if (gRecoverTime<0xffff)

         if (gAllNoAiRecover>0.0f){
            gAllNoAiRecover -= info->elapsed_time;            
            if (gAllNoAiRecover<=0.0f)
               SC_MP_RecoverAllNoAiPlayers();            
            break;
         }// if (gAllNoAiRecover>0.0f)
         else{
            gAllNoAiRecover -= info->elapsed_time;
         }
         CLEAR(valid);         
         j = 64;
         alldeath = FALSE;
         if (SC_MP_EnumPlayers(enum_pl,&j,SC_MP_ENUMPLAYER_SIDE_ALL)){
            alldeath = TRUE;
            for (i=0;i<j;i++){
               if (enum_pl[i].status==SC_MP_P_STATUS_INGAME){
                  if (enum_pl[i].side>1);// SC_message("coop script wrong side: %d",enum_pl[i].side);
                  else{
                     valid[enum_pl[i].side] = TRUE;
                  }
               }
               if ((enum_pl[i].side==0)&&(enum_pl[i].status==SC_MP_P_STATUS_INGAME)) alldeath = FALSE;
            }// for (i)
            //SC_message("Enum, v[0]: %d   v[1]: %d  alldeath: %d",valid[0],valid[1],alldeath);
         }// if (SC_MP_EnumPlayers(enum_pl,&j,SC_MP_ENUMPLAYER_SIDE_ALL))
         else SC_message("NoEnum");   
         if ((gPhase==GPHASE_GAME)&&(alldeath)&&(gPhase_timer<0.0f)){
            if (gRecoverLimit==0){
               // mission failed
               //SC_Log(2,"Set GPHASE_FAILED");
               gPhase = GPHASE_FAILED;
               gPhase_timer = 5.0f;
            }
            else {
               // recover unlimited
               //SC_message("recover unlimited");
               if ((gRecoverTime>=0xffff)&&(gAllNoAiRecover<-5.0f)){
                  gAllNoAiRecover = 4.0f;               
               }
            }
         }// if ((alldeath)&&(gRecoverTime>=0xffff))
         else gAllNoAiRecover = 0.0f;
         gValidSide0 = valid[0];
         gPhase_timer -= info->elapsed_time;
         switch(gPhase){
            case GPHASE_BEGIN:
               if (notincar){
                  notincar = FALSE;
               }
               if (gPhase_timer<0.0f)
               if ((valid[0])&&(valid[1])){
                  gPhase_timer = 5.0f;
                  gPhase = GPHASE_GAME;   
               }
               break;
            case GPHASE_GAME:
               if (gPhase_timer<0.0f)
               if (!valid[1]){
                  gPhase = GPHASE_DONE;
                  gPhase_timer = 5.0f;
               }// if (!valid[1])
               break;
            case GPHASE_DONE:
               if (gPhase_timer<0.0f){   //wait before restart

                  SC_MP_LoadNextMap();
               }
               break;
            case GPHASE_FAILED:
               if (gPhase_timer<0.0f){   //wait before restart
                  gPhase_timer = RESTART_TIMER;
                  gPhase = GPHASE_BEFORE_RESTART;
               }
               break;
            case GPHASE_BEFORE_RESTART:
               if (gPhase_timer<0.0f){   //wait before restart
                  gPhase = GPHASE_RESTARTING;
               }
               break;
            case GPHASE_RESTARTING:
               CLEAR(gRecTimer);
               gNextRecover = 0.0f;
               gTime = 0;
               gPhase = GPHASE_BEGIN;
               gPhase_timer = 5.0f;
               gPhase_send = 0;
               gValidSide0 = FALSE;
               SC_MP_GetSRVsettings(&SRVset);
               gRecoverTime = SRVset.coop_respawn_time;
               gRecoverLimit = SRVset.coop_respawn_limit;
               gAllNoAiRecover  = 0.0f;
               SC_MP_SRV_ClearPlsStats();
               SC_MP_SRV_InitGameAfterInactive();
               SC_MP_RecoverAllAiPlayers();
               SC_MP_RecoverAllNoAiPlayers();   

               //SC_MP_RestartMission();               //restart // causing some truoble //using SC_NET_MES_LEVELINIT
                  //_________Reinit AI
                  num = 64;
                  SC_MP_EnumPlayers(enum_pl, &num, SC_MP_ENUMPLAYER_SIDE_ALL);//SC_MP_ENUMPLAYER_SIDE_ALL is for US_AI and civilian_AI
                  for (i = 0; i < num; i++){
                     SC_P_ScriptMessage(enum_pl[i].id, SCM_MP_REINIT, 0);
                  }
                  //_____________________

               break;
         }// switch(gPhase)
         SRV_CheckUpdate();
         break;
      case SC_NET_MES_CLIENT_TICK:
         switch(SC_ggi(GVAR_GPHASE)){
         case GPHASE_BEGIN:
            if (fade_off == FALSE){
               SC_FadeTo(FALSE, FADE_TIME);
               fade_off=TRUE;
            }
            break;
         case GPHASE_GAME:
            break;
         case GPHASE_DONE:
            if (sound_start==TRUE){
               SC_SND_PlaySound2D(DONE_SOUND);
               sound_start=FALSE;
            }
            break;
         case GPHASE_FAILED:
            if (sound_start==TRUE){
               SC_SND_PlaySound2D(FAILED_SOUND);
               sound_start=FALSE;
            }
            break;
         case GPHASE_BEFORE_RESTART:
            client_fade_timer -= info->elapsed_time;
            if (client_fade_timer<FADE_TIME){   
               SC_FadeTo(TRUE, FADE_TIME);
               fade_off=FALSE;
               sound_start=TRUE;
               client_fade_timer=RESTART_TIMER;
            }
            break;
         case GPHASE_RESTARTING:
            break;
         }// switch(gPhase)
         //SC_message(char *txt,...);
         break;// SC_NET_MES_CLIENT_TICK
      case SC_NET_MES_LEVELPREINIT:
         client_fade_timer=RESTART_TIMER;
         SC_sgi(GVAR_MP_MISSIONTYPE,GVAR_MP_MISSIONTYPE_COOP);
         gEndRule = info->param1;
         gEndValue = info->param2;
         gTime = 0.0f;
         SC_MP_EnableBotsFromScene(TRUE);
         //______________________________________objectives________
         Objectives[objective_count].text_id=100;
         Objectives[objective_count].status=SC_OBJECTIVE_STATUS_VALID;
         objective_count++;
         SC_SetObjectives(objective_count,Objectives,100);
         //________________________________________________________
         break;// SC_NET_MES_LEVELPREINIT
      case SC_NET_MES_LEVELINIT:
         //_____________________________________automatic custom global variables_________________
         for (i=GVAR_USE_start;i<GVAR_USE_start+SC_ggi(GVAR_COUNT)+1;i++){   //custom global variables
            SC_MP_Gvar_SetSynchro(i);
         }
         //_______________________________________________________________________________________
         SC_MP_Gvar_SetSynchro(GVAR_KILLED);   
         SC_MP_Gvar_SetSynchro(GVAR_KILLER);   
         SC_MP_SRV_SetForceSide(0);
         SC_MP_SRV_SetClassLimit(18,0);
         SC_MP_SRV_SetClassLimit(19,0);
         SC_MP_SRV_SetClassLimit(39,0);
         SC_MP_GetSRVsettings(&SRVset);
         for (i=0;i<6;i++){
            SC_MP_SRV_SetClassLimit(i+1,SRVset.atg_class_limit[i]);
            SC_MP_SRV_SetClassLimit(i+21,SRVset.atg_class_limit[i]);
         }// for (i)
         CLEAR(hudinfo);         
         hudinfo.title = 1098;
         hudinfo.sort_by[0] = SC_HUD_MP_SORTBY_KILLS;  //untested. reorder to change what takes precidence
         hudinfo.sort_by[1] = SC_HUD_MP_SORTBY_DEATHS | SC_HUD_MP_SORT_DOWNUP;
         hudinfo.sort_by[2] = SC_HUD_MP_SORTBY_PINGS | SC_HUD_MP_SORT_DOWNUP; //untested. remove SC_HUD to show hi pinger at top of list
         hudinfo.pl_mask = SC_HUD_MP_PL_MASK_KILLS | SC_HUD_MP_PL_MASK_DEATHS | SC_HUD_MP_PL_MASK_CLASS;
         hudinfo.use_sides = TRUE;
         hudinfo.side_name[0] = 1010;
         hudinfo.side_color[0] = 0x44008800;      // was --> 0x440000ff; this changes the team HUD colour
         hudinfo.side_name[1] = 1011; //untested. possable place VET variable
         hudinfo.side_color[1] = 0x44ff0000;      // was --> 0x44FFFF00; this changes the team HUD colour
         //hudinfo.disableUSside = TRUE;
         hudinfo.disableVCside = TRUE; //untested. show VC info in HUD
         /*
         switch( SC_ggi(SGI_DIFFICULTY) ){
         case 0:
            break;
         case 3:
            hudinfo.disableUSside = TRUE; // show VC info in HUD
            break;
         }
         */
         //hudinfo.disableUSside = TRUE; //untested. show VC info in HUD
         hudinfo.side_mask = SC_HUD_MP_SIDE_MASK_FRAGS;
         SC_MP_HUD_SetTabInfo(&hudinfo);
         SC_MP_AllowStPwD(TRUE);
         SC_MP_AllowFriendlyFireOFF(TRUE);
         SC_MP_SetItemsNoDisappear(TRUE); // untested. stops dropped items from disapearing.
         SC_MP_SetChooseValidSides(1);
         SC_sgi(GVAR_SERVER,0);
         if (info->param2){
            if (info->param1){// it's server
               //____________
               SC_sgi(GVAR_SERVER,1);//For object scripts
               //____________
               SC_MP_Gvar_SetSynchro(GVAR_GPHASE);   //only server can update gphase now
               SC_MP_GetSRVsettings(&SRVset);
               gRecoverTime = SRVset.coop_respawn_time;
               gRecoverLimit = SRVset.coop_respawn_limit;
               
               if (SC_MP_GetAmmoBoxesEnabled()){
                  SC_MP_SRV_InitWeaponsRecovery(10000.0); // change to allow numbered weapons to be shown like in DM. time based 0.0f =never disapears.
               }else{
                  SC_MP_SRV_InitWeaponsRecovery(-1.0);
               }

               
               gRecs = 0;
               for (i=0;i<REC_MAX;i++){      
                  sprintf(txt,REC_WPNAME_US,i);         
                  if (SC_NET_FillRecover(&gRec[gRecs],txt)) gRecs++;               
               }               
               #if _GE_VERSION_ >= 133
                   i = REC_MAX - gRecs;
                   SC_MP_GetRecovers(SC_MP_RESPAWN_COOP,&gRec[gRecs],&i);
                   gRecs += i;
               #endif
               if (gRecs==0) SC_message("no US recover place defined!");
               CLEAR(gRecTimer);
            }// if (info->param1)
         }//if (info->param2)
         if (info->param1){
            //!!! ++ Reinit AI - NEW
            num = 64;
            SC_MP_EnumPlayers(enum_pl, &num, SC_MP_ENUMPLAYER_SIDE_ALL);//SC_MP_ENUMPLAYER_SIDE_ALL is for US_AI and civilian_AI
            for (i = 0; i < num; i++){
               SC_P_ScriptMessage(enum_pl[i].id, SCM_MP_REINIT, 0);
               //SC_message("SEND_message");
            }
            //-- Reinit AI - NEW
         }
         break;// SC_NET_MES_LEVELINIT
      case SC_NET_MES_RENDERHUD:
         switch(SC_ggi(GVAR_GPHASE)){
            case GPHASE_DONE:
               j = 1099;   //1099 - "US ARMY WIN."      #1096:    #tee US ARMY WIN. ALL VIETCONG ELIMINATED.   #1097:    #tee US ARMY WIN. PILOT REACHED THE LZ.
               witxt = SC_Wtxt(j);
               SC_GetScreenRes(&sc_width,&sc_height);
               val= sc_width - SC_Fnt_GetWidthW(witxt,1);
               SC_Fnt_WriteW(val * 0.5f,15,witxt,1,0xffffffff);//0x44008800//0xffffffff
               if(gPhase_timer > 0){
                  remaining_time=gPhase_timer;
               }
               else{
                  swprintf(wtxt,SC_AnsiToUni("LOADING NEXT MISSION", wtxt2));
               }
               val= sc_width - SC_Fnt_GetWidthW(wtxt,1);
               break;
            case GPHASE_FAILED:
               swprintf(wtxt,SC_AnsiToUni("%S killed by %S", wtxt2),SC_P_GetName(SC_MP_GetPlofHandle(SC_ggi(GVAR_KILLED))),SC_P_GetName(SC_MP_GetPlofHandle(SC_ggi(GVAR_KILLER))));
               //j = 1081;   //1049 - "Vietcong win."   #1095:    #tee VIETCONG WIN. PILOT KILLED.   #1081:    #tee VIETCONG WIN. #2025: #tee Mission failed  #7781:    #tee Status: MISSION FAILED\n
               witxt = SC_Wtxt(2025);
               SC_GetScreenRes(&sc_width,&sc_height);
               val= sc_width - SC_Fnt_GetWidthW(witxt,1);
               SC_Fnt_WriteW(val * 0.5f,25,witxt,1,0xffff0000);
               val= sc_width - SC_Fnt_GetWidthW(wtxt,1);
               SC_Fnt_WriteW(val * 0.5f,50,wtxt,1,0xffff0000);
               
               //#2095:    #tee Restart
               break;
            case GPHASE_BEFORE_RESTART:
               swprintf(wtxt,SC_AnsiToUni("MISSION RESTARTING", wtxt2));
               SC_GetScreenRes(&sc_width,&sc_height);
               val= sc_width - SC_Fnt_GetWidthW(wtxt,1);
               SC_Fnt_WriteW(val * 0.5f,50,wtxt,1,0xffffffff);

               break;   
            default:j = 0;break;
         }// switch(SC_ggi(GVAR_GPHASE))
         break;
      case SC_NET_MES_SERVER_RECOVER_TIME:
         if (info->param2){
               info->fval1 = 0.1f;
         }
         else{
            // killed
            SC_P_GetInfo(info->param1,&plinfo);            
            if (plinfo.side==0){               
               if (gRecoverLimit>0){
                  if (gRecoverTime>=0xffff) info->fval1 = -1.0f;
                  else
                  if (gRecoverTime>0) info->fval1 = gNextRecover;
                     else info->fval1 = 4.0f;                  
               }
               else info->fval1 = -1.0f;      
            }
            else info->fval1 = -1.0f;
         }
         break;
//_______________________________________________________________RECOVER_PLACE____________________
      case SC_NET_MES_SERVER_RECOVER_PLACE:
         if (info->param1!=0){
            SC_message("No recover for VC");
            break;
         }
         precov = (s_SC_MP_Recover*)info->param2;
         i = SC_MP_SRV_GetBestDMrecov(gRec,gRecs,gRecTimer,NORECOV_TIME);
         gRecTimer[i] = NORECOV_TIME;
         *precov = gRec[i];      
         break;
//_______________________________________________________________KILL____________________
      case SC_NET_MES_SERVER_KILL://only server
          //SC_LevScr_Event(1,1);
         SC_P_GetInfo(info->param1,&my_plinfo);            
         if (my_plinfo.side==3){
            gPhase_timer = FAIL_TIMER;
            gPhase=GPHASE_FAILED;
            SC_sgi(GVAR_GPHASE,gPhase);
            if (info->param2){
                    SC_P_GetInfo(info->param2,&my_plinfo); 
               if (my_plinfo.side==0){// killer was US
                  SC_sgi(GVAR_KILLED,SC_MP_GetHandleofPl(info->param1));
                  SC_sgi(GVAR_KILLER,SC_MP_GetHandleofPl(info->param2));
               }
            }
         }
         break;// SC_NET_MES_SERVER_KILL
//_______________________________________________________________RESTARTMAP____________________
      case SC_NET_MES_RESTARTMAP:
         gPhase_timer = RESTART_TIMER;
         gPhase = GPHASE_BEFORE_RESTART;
         break;// SC_NET_MES_RESTARTMAP
      case SC_NET_MES_RULESCHANGED:         
         gEndRule = info->param1;
         gEndValue = info->param2;
         gTime = 0.0f;
         break;   
   }// switch(info->message)
   return 1;
}// int ScriptMain(void)



  x 1
 
Ando
Coop_vc script with automatic global variable system (advanced)

details compared with original coop:
- added automatic global variable system
- added civilian option
- mission restart when civilian is killed by VC an message appears who killed civilian
- restart with fade
- switch to next map when mission done
- added sound for "mission FAILED"
- added sound for "mission DONE"

Spoiler:
Download source  Code
//   VIETCONG 1
//   COOP_VC script (with automatic global variables for synchronized objects)
//   Created by Ando
//   v3.1



//   NOTES:
// 1.1 - added global wariables system
// 1.2 - added variable for server (600) to detect server from object scripts
// 1.2 - new G-var system (object scripts counting g-vars to channel 601 )
// 1.4 - added mission objectives test
// 2.0 - successfully tested with L|DC-78
// 2.1 - added civilian option
// 2.1 - mission restart when civilian is killed by us an message apears who killed civilian
// 2.1 - "mission fail" restart with fast fade
// 2.1 - fade when mission restarts
// 2.2 - switch to next map when mission done
// 3.0 - TESTED WITH TEAM
// 3.1 - added sound for "mission FAILED"
// 3.1 - added sound for "mission DONE"

// IDEAS





#include <inc\sc_global.h>
#include <inc\sc_def.h>

#define FADE_TIME         0.8

#define      DONE_SOUND      6035   //snd 6035 music\slap25.ogg
#define      FAILED_SOUND   6057   //snd 6057 music\slap47.ogg
//________________________________
//global variable system for object synchro  !!!DONT CHANGE THOSE!!!
#define GVAR_SERVER         600    //   server  ( dont add SC_MP_Gvar_SetSynchro for that) 0 - not server, 1 - server
#define GVAR_COUNT         601    //  count of object variables ( dont add SC_MP_Gvar_SetSynchro for that)
#define GVAR_USE_start      602       //start      Global variable
//________________________________

#define GVAR_GPHASE            500

#define GVAR_KILLED            501
#define GVAR_KILLER            502



//#define RECOVER_TIME   15.0f      // time to global recover
#define NORECOV_TIME   3.0f      // disable time of recoverplace after recovering someone there

#define REC_WPNAME_US   "VCSpawn_coop_%d"
#define REC_MAX         64


s_SC_Objective Objectives [10];
int objective_count=0;
int remaining_time=0;


dword gRecs = 0;
s_SC_MP_Recover gRec[REC_MAX];
float gRecTimer[REC_MAX];

float gNextRecover = 0.0f;

dword gEndRule;
dword gEndValue;
float gTime;

#define GPHASE_BEGIN         1
#define GPHASE_GAME            2
#define GPHASE_DONE            3
#define GPHASE_FAILED         4
#define GPHASE_BEFORE_RESTART   5
#define GPHASE_RESTARTING      6   

#define RESTART_TIMER      3   //time before actual restart
#define FAIL_TIMER         7   //time before actual restart

dword   gPhase = GPHASE_BEGIN;
float   gPhase_timer = 5.0f;
float   client_fade_timer;
dword   gPhase_send = 0;

BOOL gValidSide0 = FALSE;
BOOL    notincar = TRUE;
BOOL    fade_off = TRUE;
BOOL   sound_start=TRUE;

dword gRecoverTime =   0;
dword gRecoverLimit =   0;

float gAllNoAiRecover  = 0.0f;

BOOL SRV_CheckEndRule(float time){
   switch(gEndRule){
      case SC_MP_ENDRULE_TIME:         
         if (gValidSide0) gTime += time;
         SC_MP_EndRule_SetTimeLeft(gTime,gValidSide0);
         if (gTime>gEndValue){
            SC_MP_LoadNextMap();
            return TRUE;
         }
         break;
      default:
         SC_message("EndRule unsopported: %d",gEndRule);
         break;
   }// switch(gEndRule)
   return FALSE;
}// void SRV_CheckEndRule(float time)

void SRV_CheckUpdate(void){
   if (gPhase_send!=gPhase){
      gPhase_send = gPhase;
      SC_sgi(GVAR_GPHASE,gPhase);
      //SC_message("SRV_CheckUpdate %d",gPhase);
   }// if (gPhase_send!=gPhase)
}// void SRV_CheckUpdate(void)

int ScriptMain(s_SC_NET_info *info)
{
   s_SC_MP_EnumPlayers      enum_pl[64];
   s_SC_MP_SRV_settings   SRVset;
   s_SC_MP_Recover         *precov;
   s_SC_MP_hud            hudinfo;
   s_SC_P_getinfo         plinfo;
   s_SC_P_getinfo         my_plinfo;
   dword   i, j, sideA, sideB, num;
   BOOL   valid[2];
   BOOL   alldeath;
   char   txt[32],*itxt;
   ushort wtxt[128],wtxt2[64],*witxt,*my_witxt;
   float   sc_width,sc_height,val;

   //
   switch(info->message){
      case SC_NET_MES_SERVER_TICK:   
         if (SRV_CheckEndRule(info->elapsed_time)) break;
         for (j=0;j<4;j++)
         for (i=0;i<gRecs;i++)
            gRecTimer[i] -= info->elapsed_time;
         if (gRecoverTime<0xffff){
            gNextRecover -= info->elapsed_time;
            if (gNextRecover<0.0f) gNextRecover = (float)gRecoverTime;
         }// if (gRecoverTime<0xffff)
         if (gAllNoAiRecover>0.0f){
            gAllNoAiRecover -= info->elapsed_time;            
            if (gAllNoAiRecover<=0.0f)
               SC_MP_RecoverAllNoAiPlayers();         
            break;
         }// if (gAllNoAiRecover>0.0f)
         else{
            gAllNoAiRecover -= info->elapsed_time;
         }
         CLEAR(valid);         
         j = 64;
         alldeath = FALSE;
         if (SC_MP_EnumPlayers(enum_pl,&j,SC_MP_ENUMPLAYER_SIDE_ALL)){
            alldeath = TRUE;
            for (i=0;i<j;i++){
               if (enum_pl[i].status==SC_MP_P_STATUS_INGAME){
                  if (enum_pl[i].side>1); //SC_message("coop script wrong side: %d",enum_pl[i].side);
                  else{
                     valid[enum_pl[i].side] = TRUE;
                  }
               }
               if ((enum_pl[i].side==1)&&(enum_pl[i].status==SC_MP_P_STATUS_INGAME)) alldeath = FALSE;
            }// for (i)
            //SC_message("Enum, v[0]: %d   v[1]: %d  alldeath: %d",valid[0],valid[1],alldeath);   
         }// if (SC_MP_EnumPlayers(enum_pl,&j,SC_MP_ENUMPLAYER_SIDE_ALL))
         else SC_message("NoEnum");   
         if ((gPhase==GPHASE_GAME)&&(alldeath)&&(gPhase_timer<0.0f)){
            if (gRecoverLimit==0){
               // mission failed
               //SC_Log(2,"Set GPHASE_FAILED");
               gPhase = GPHASE_FAILED;
               gPhase_timer = 5.0f;
            }
            else {
               // recover unlimited
               //SC_message("recover unlimited");
               if ((gRecoverTime>=0xffff)&&(gAllNoAiRecover<-5.0f)){
                  gAllNoAiRecover = 4.0f;               
               }
            }
         }// if ((alldeath)&&(gRecoverTime>=0xffff))
         else gAllNoAiRecover = 0.0f;
         gValidSide0 = valid[1];
         gPhase_timer -= info->elapsed_time;
         switch(gPhase){
            case GPHASE_BEGIN:
               if (notincar){
                  notincar = FALSE;
               }
               if (gPhase_timer<0.0f)
               if ((valid[0])&&(valid[1])){
                  gPhase_timer = 5.0f;
                  gPhase = GPHASE_GAME;   
               }
               break;
            case GPHASE_GAME:
               if (gPhase_timer<0.0f)
               if (!valid[0]){
                  gPhase = GPHASE_DONE;
                  gPhase_timer = 5.0f;
               }// if (!valid[0])
               break;
            case GPHASE_DONE:
               if (gPhase_timer<0.0f){   //wait before restart
                  SC_MP_LoadNextMap();
               }
               break;
            case GPHASE_FAILED:
               if (gPhase_timer<0.0f){//wait before restart
                  gPhase_timer = RESTART_TIMER;
                  gPhase = GPHASE_BEFORE_RESTART;
               }
               break;
            case GPHASE_BEFORE_RESTART:
               if (gPhase_timer<0.0f){   //wait before restart
                  gPhase = GPHASE_RESTARTING;
               }
               break;
            case GPHASE_RESTARTING:
               CLEAR(gRecTimer);
               gNextRecover = 0.0f;
               gTime = 0;
               gPhase = GPHASE_BEGIN;
               gPhase_timer = 5.0f;
               gPhase_send = 0;
               gValidSide0 = FALSE;
               SC_MP_GetSRVsettings(&SRVset);
               gRecoverTime = SRVset.coop_respawn_time;
               gRecoverLimit = SRVset.coop_respawn_limit;
               gAllNoAiRecover  = 0.0f;
               SC_MP_SRV_ClearPlsStats();
               SC_MP_SRV_InitGameAfterInactive();
               SC_MP_RecoverAllAiPlayers();
               SC_MP_RecoverAllNoAiPlayers();   

               //SC_MP_RestartMission();               //restart // causing some truoble //using SC_NET_MES_LEVELINIT
                  //_________Reinit AI
                  num = 64;
                  SC_MP_EnumPlayers(enum_pl, &num, SC_MP_ENUMPLAYER_SIDE_ALL);//SC_MP_ENUMPLAYER_SIDE_ALL is for US_AI and civilian_AI
                  for (i = 0; i < num; i++){
                     SC_P_ScriptMessage(enum_pl[i].id, SCM_MP_REINIT, 0);
                  }
                  //_____________________


               break;
         }// switch(gPhase)
         SRV_CheckUpdate();
         break;
      case SC_NET_MES_CLIENT_TICK:
         switch(SC_ggi(GVAR_GPHASE)){
         case GPHASE_BEGIN:
            if (fade_off == FALSE){
               SC_FadeTo(FALSE, FADE_TIME);
               fade_off=TRUE;
            }
            break;
         case GPHASE_GAME:
            break;
         case GPHASE_DONE:
            if (sound_start==TRUE){
               SC_SND_PlaySound2D(DONE_SOUND);
               sound_start=FALSE;
            }
            break;
         case GPHASE_FAILED:
            if (sound_start==TRUE){
               SC_SND_PlaySound2D(FAILED_SOUND);
               sound_start=FALSE;
            }
            break;
         case GPHASE_BEFORE_RESTART:
            client_fade_timer -= info->elapsed_time;
            if (client_fade_timer<FADE_TIME){   
               SC_FadeTo(TRUE, FADE_TIME);
               fade_off=FALSE;
               sound_start=TRUE;
               client_fade_timer=RESTART_TIMER;
            }
            break;
         case GPHASE_RESTARTING:
            break;
         }// switch(gPhase)
         //SC_message(char *txt,...);
         break;// SC_NET_MES_CLIENT_TICK
      case SC_NET_MES_LEVELPREINIT:
         client_fade_timer=RESTART_TIMER;
         SC_sgi(GVAR_MP_MISSIONTYPE,10);//10 is for custom coop_vc
         gEndRule = info->param1;
         gEndValue = info->param2;
         gTime = 0.0f;
         SC_MP_EnableBotsFromScene(TRUE);
         break;// SC_NET_MES_LEVELPREINIT
      case SC_NET_MES_LEVELINIT:
         //_____________________________________automatic custom global variables_________________
         for (i=GVAR_USE_start;i<GVAR_USE_start+SC_ggi(GVAR_COUNT)+1;i++){   //custom global variables
            SC_MP_Gvar_SetSynchro(i);
         }
         //_______________________________________________________________________________________
         SC_MP_Gvar_SetSynchro(GVAR_KILLED);   
         SC_MP_Gvar_SetSynchro(GVAR_KILLER);   
         SC_MP_SRV_SetForceSide(1);
         SC_MP_SetItemsNoDisappear(TRUE);
         SC_MP_SRV_SetClassLimit(18,0);
         SC_MP_SRV_SetClassLimit(19,0);
         SC_MP_SRV_SetClassLimit(39,0);
         SC_MP_GetSRVsettings(&SRVset);
         for (i=0;i<6;i++){
            SC_MP_SRV_SetClassLimit(i+1,SRVset.atg_class_limit[i]);
            SC_MP_SRV_SetClassLimit(i+21,SRVset.atg_class_limit[i]);
         }// for (i)
         CLEAR(hudinfo);
         hudinfo.title = 1098;
         hudinfo.sort_by[0] = SC_HUD_MP_SORTBY_KILLS;
         hudinfo.sort_by[1] = SC_HUD_MP_SORTBY_DEATHS | SC_HUD_MP_SORT_DOWNUP;
         hudinfo.sort_by[2] = SC_HUD_MP_SORTBY_PINGS | SC_HUD_MP_SORT_DOWNUP;
         hudinfo.pl_mask = SC_HUD_MP_PL_MASK_KILLS | SC_HUD_MP_PL_MASK_DEATHS | SC_HUD_MP_PL_MASK_CLASS;
         hudinfo.use_sides = TRUE;
         hudinfo.side_name[0] = 1010;
         hudinfo.side_color[0] = 0x44008800;
         hudinfo.side_name[1] = 1011;
         hudinfo.side_color[1] = 0x44ff0000;
         hudinfo.disableUSside = TRUE;
         //hudinfo.disableVCside = TRUE;





         hudinfo.side_mask = SC_HUD_MP_SIDE_MASK_FRAGS;
         SC_MP_HUD_SetTabInfo(&hudinfo);
         SC_MP_AllowStPwD(TRUE);
         SC_MP_AllowFriendlyFireOFF(TRUE);
         SC_MP_SetItemsNoDisappear(FALSE);
         SC_MP_SetChooseValidSides(2);//This function will set the valid sides for the player to choose from. Use 0 for US only, 2 for VC, 3 for both.
         SC_sgi(GVAR_SERVER,0);
         if (info->param2){
            if (info->param1){// it's server      
               //____________
               SC_sgi(GVAR_SERVER,1);//For object scripts
               //____________
               SC_MP_Gvar_SetSynchro(GVAR_GPHASE);   
               SC_MP_GetSRVsettings(&SRVset);
               gRecoverTime = SRVset.coop_respawn_time;
               gRecoverLimit = SRVset.coop_respawn_limit;


               if (SC_MP_GetAmmoBoxesEnabled()){
                  SC_MP_SRV_InitWeaponsRecovery(10000.0); // change to allow numbered weapons to be shown like in DM. time based 0.0f =never disapears.
               }else{
                  SC_MP_SRV_InitWeaponsRecovery(-1.0);
               }


               gRecs = 0;
               for (i=0;i<REC_MAX;i++){      
                  sprintf(txt,REC_WPNAME_US,i);         
                  if (SC_NET_FillRecover(&gRec[gRecs],txt)) gRecs++;               
               }               
               #if _GE_VERSION_ >= 133
                   i = REC_MAX - gRecs;
                  SC_MP_GetRecovers(100,&gRec[gRecs],&i);
                   gRecs += i;
               #endif
               if (gRecs==0) SC_message("no VC recover place defined!");
               CLEAR(gRecTimer);
            }// if (info->param1)
         }//if (info->param2)
         if (info->param1){
            //!!! ++ Reinit AI - NEW
            num = 64;
            SC_MP_EnumPlayers(enum_pl, &num, SC_MP_ENUMPLAYER_SIDE_ALL);
            for (i = 0; i < num; i++){
               SC_P_ScriptMessage(enum_pl[i].id, SCM_MP_REINIT, 0);
            }
            //-- Reinit AI - NEW
         }
         break;// SC_NET_MES_LEVELINIT
      case SC_NET_MES_RENDERHUD:
         switch(SC_ggi(GVAR_GPHASE)){
            case GPHASE_DONE:
               j = 1049;   //1049 - "Vietcong win."  #1081:    #tee VIETCONG WIN.
               witxt = SC_Wtxt(j);
               SC_GetScreenRes(&sc_width,&sc_height);
               val= sc_width - SC_Fnt_GetWidthW(witxt,1);
               SC_Fnt_WriteW(val * 0.5f,15,witxt,1,0xffffffff);//0x44008800//0xffffffff
               if(gPhase_timer > 0){
                  remaining_time=gPhase_timer;
                  swprintf(wtxt,SC_AnsiToUni("LOAD NEXT MISSION after: %d sec.", wtxt2),(int)(remaining_time));
               }
               else{
                  swprintf(wtxt,SC_AnsiToUni("LOADING NEXT MISSION", wtxt2));
               }
               
               swprintf(wtxt,SC_AnsiToUni("LOAD NEXT MISSION after: %d sec.", wtxt2),(int)(remaining_time));
               val= sc_width - SC_Fnt_GetWidthW(wtxt,1);
               SC_Fnt_WriteW(val * 0.5f,50,wtxt,1,0xffffffff);
               break;
            case GPHASE_FAILED:
               swprintf(wtxt,SC_AnsiToUni("%S killed by %S", wtxt2),SC_P_GetName(SC_MP_GetPlofHandle(SC_ggi(GVAR_KILLED))),SC_P_GetName(SC_MP_GetPlofHandle(SC_ggi(GVAR_KILLER))));
               //j = 1081;   //1049 - "Vietcong win."   #1095:    #tee VIETCONG WIN. PILOT KILLED.   #1081:    #tee VIETCONG WIN. #2025: #tee Mission failed  #7781:    #tee Status: MISSION FAILED\n
               witxt = SC_Wtxt(2025);
               SC_GetScreenRes(&sc_width,&sc_height);
               val= sc_width - SC_Fnt_GetWidthW(witxt,1);
               SC_Fnt_WriteW(val * 0.5f,25,witxt,1,0xffff0000);
               val= sc_width - SC_Fnt_GetWidthW(wtxt,1);
               SC_Fnt_WriteW(val * 0.5f,50,wtxt,1,0xffff0000);
               
               //#2095:    #tee Restart
               break;
            case GPHASE_BEFORE_RESTART:
               swprintf(wtxt,SC_AnsiToUni("MISSION RESTARTING", wtxt2));
               SC_GetScreenRes(&sc_width,&sc_height);
               val= sc_width - SC_Fnt_GetWidthW(wtxt,1);
               SC_Fnt_WriteW(val * 0.5f,50,wtxt,1,0xffffffff);

               break;
            default:j = 0;break;
         }// switch(SC_ggi(GVAR_GPHASE))
         break;
      case SC_NET_MES_SERVER_RECOVER_TIME:
         if (info->param2){
               info->fval1 = 0.1f;
         }
         else{
            // killed
            SC_P_GetInfo(info->param1,&plinfo);         
            if (plinfo.side==1){               
               if (gRecoverLimit>0){
                  if (gRecoverTime>=0xffff) info->fval1 = -1.0f;
                  else
                  if (gRecoverTime>0) info->fval1 = gNextRecover;
                     else info->fval1 = 4.0f;                  
               }
               else info->fval1 = -1.0f;   
            }
            else info->fval1 = -1.0f;
         }
         break;
//_______________________________________________________________RECOVER_PLACE____________________
      case SC_NET_MES_SERVER_RECOVER_PLACE:
         if (info->param1!=1){
            SC_message("No recover for VC");
            break;
         }
         precov = (s_SC_MP_Recover*)info->param2;
         i = SC_MP_SRV_GetBestDMrecov(gRec,gRecs,gRecTimer,NORECOV_TIME);
         gRecTimer[i] = NORECOV_TIME;
         *precov = gRec[i];         
         break;
//_______________________________________________________________KILL____________________
      case SC_NET_MES_SERVER_KILL:
         SC_P_GetInfo(info->param1,&my_plinfo);            
         if (my_plinfo.side==3){
            gPhase_timer = FAIL_TIMER;
            gPhase=GPHASE_FAILED;
            SC_sgi(GVAR_GPHASE,gPhase);
            if (info->param2){
                    SC_P_GetInfo(info->param2,&my_plinfo); 
               if (my_plinfo.side==1){// killer was VC
                  SC_sgi(GVAR_KILLED,SC_MP_GetHandleofPl(info->param1));
                  SC_sgi(GVAR_KILLER,SC_MP_GetHandleofPl(info->param2));
               }
            }
         }
         break;// SC_NET_MES_SERVER_KILL
//_______________________________________________________________RESTARTMAP____________________
      case SC_NET_MES_RESTARTMAP:
         gPhase_timer = RESTART_TIMER;
         gPhase = GPHASE_BEFORE_RESTART;
         break;// SC_NET_MES_RESTARTMAP
      case SC_NET_MES_RULESCHANGED:         
         gEndRule = info->param1;
         gEndValue = info->param2;
         gTime = 0.0f;
         break;      
   }// switch(info->message)
   return 1;
}// int ScriptMain(void)



 
Ando
Wounded /coma / dead script

Description:

When player health is smaller than 10 % then it starts to go slowly worse (small damage after every second)
20 seconds before coma script show and count down seconds (recommendation by testers).
When player health is smaller than 1.5% then he fall down and can’t move (+small damage after every second)
When player health is smaller than 0.23% then he will die.
When player is healed then he will be fine again.

Tutorial for editor:
- add somewhere "killer.bes" object to map. It must use same name in editor ("killer")
- add somewhere dummy object to map and rename it to "view_helper"
- attach this script to "killer" object in level.c
- use only mode script with auto. sync.

Object
Object is attached to this post.


Spoiler:
Download source  Code

//   VIETCONG 1
//   WOUNDED_COMA_DEAD script v3.1 (Writen for custom object -  KILLER.BES)
//   made by Ando



/*
   ______________DESCRIPTION:
MP synchronized player wounded/ coma/dead option.
When player health is smaller than 10 % then it starts to go slowly worse (small damage after every second)
20 seconds before coma script show and count down seconds (recommendation by testers).
When player health is smaller than 1.5% then he fall down and can’t move (+small damage after every second)
When player health is smaller than 0.23% then he will die.



   ______________TUTORIAL FOR EDITOR
This script must be added to custom object  "killer.bes"
Add somewhere "killer.bes" object to map. It must use same name in editor ("killer")
Add somewhere dummy object to map and rename it to "view_helper"
Attach this script to "killer" object in level.c

This script is synchronized in multiplayer. You only must use mode script with Automatic sync. support.
Synchronization channel is added automatically




3.1 -

*/



#include <inc\sc_global.h>


//____________________________OBJECT PARAMETERS____________________________

#define WOUNDED               20.0f   //
#define COMA               3.0f   //
#define DEAD               0.5f
#define WO_DAMAGE            0.15f   //   tamage per second
#define CO_DAMAGE            0.05f   //   tamage per second
#define INF_TIME            20   //   show info when alive time is smaller than

#define   view_obj_name            "view_helper"   //
#define   kill_obj_name            "killer"   //   

#ifndef COMA_ANM
   #define COMA_ANM            "LEVELS\\DEAD_END\\DATA\\MAP_D\\MPANIMS\\COMA.ANM"   //
#endif

//___________________________PART OF AUTOMATIC SYNC. CANNEL________________

#define GVAR_SERVER            600       // 0 - not server, 1 - server
//_________________________________________________________________________



void      *view_obj_id;
void      *kill_obj_id;

s_SC_NOD_transform   trans;
s_SC_NOD_transform   trans_hidden;
s_SC_NOD_transform   orig_trans_kill;
s_SC_NOD_transform   orig_trans_view;
s_SC_NOD_transform   trans_view;

s_SC_P_getinfo pl_info;

c_Vector3 pl_pos;
int w_phase;
int pl_coma[10];

dword       player;

float      timer = 0.0f;
float      pl_hp;
float      time_left;
BOOL start_wounded=TRUE;
BOOL start_coma=TRUE;
BOOL start_dead=TRUE;


BOOL not_in_list=TRUE;
char   txt[32];


int ScriptMain(s_SC_OBJ_info *info){
   ushort wtxt[128],wtxt2[64];



   s_SC_MP_EnumPlayers enum_pl[64];
   int i,j,k,l;

   switch(info->event_type){
      case SC_OBJ_INFO_EVENT_INIT:

         kill_obj_id = SC_NOD_GetNoMessage(info->master_nod, kill_obj_name);
         view_obj_id = SC_NOD_GetNoMessage_Entity(view_obj_name);

         SC_NOD_GetTransform(kill_obj_id,&orig_trans_kill);
         SC_NOD_GetTransform(view_obj_id,&orig_trans_view);
         
         trans_hidden=orig_trans_kill;
         trans_hidden.loc.z-=1000;

         trans=orig_trans_kill;// filling scale and rotation (later will add pos only)
         trans_view=orig_trans_view;// filling scale and rotation (later will add pos only)

         SC_NOD_SetTransform(kill_obj_id,&trans_hidden);
         SC_NOD_SetTransform(view_obj_id,&trans_hidden);
         w_phase=0;
         break;            
      case SC_OBJ_INFO_EVENT_JUSTLOADED:
         break;
      case SC_OBJ_INFO_EVENT_RELEASE:
         SC_NOD_SetTransform(kill_obj_id,&orig_trans_kill);
         SC_NOD_SetTransform(view_obj_id,&orig_trans_view);
         break;
      case SC_OBJ_INFO_EVENT_HIT:         
         break;
      case SC_OBJ_INFO_EVENT_DOTICK:
         timer+=info->time;
         if (start_dead == FALSE){// was killed by "KILL" object
            player = SC_PC_Get();
            SC_P_GetInfo(player,&pl_info);
            if (SC_P_IsReady(player)== FALSE){//(pl_info.cur_hp<0.0f ){
               SC_NOD_SetTransform(kill_obj_id,&trans_hidden); //hide a kill object again
               start_dead = TRUE;
               start_coma = TRUE;
               start_wounded = TRUE;
            }
         }
         if (timer>1){//check it
            timer=0;
            j = 64;
            if (SC_MP_EnumPlayers(enum_pl,&j,SC_MP_ENUMPLAYER_SIDE_ALL)){   
               for (i=0;i<j;i++){
                  SC_P_GetInfo(enum_pl[i].id,&pl_info);
                  if(pl_info.member_id == 255){//PC      //if (enum_pl[i].status==SC_MP_P_STATUS_INGAME){
                     pl_hp = pl_info.cur_hp;
                     player = SC_PC_Get();
                     if (enum_pl[i].id == player) {   
                        if (pl_info.cur_hp < WOUNDED){//PC WOUNDED
                           if (pl_info.cur_hp < COMA ){
                              if (pl_info.cur_hp < 0.7f ){//killed by damage
                                 if (pl_info.cur_hp < 0.0f ){//killed by damage
                                 //_________________________DEAD_____________________________
                                 }else{//_________________________KILL_____________________________
                                    if (start_dead){//start kill state
                                       SC_PC_EnableMovementAndLooking(TRUE);
                                       SC_PC_PlayFpvAnim("g\\WEAPONS\\!DEFAULT\\STATIV_LIE.STG");//stop last looped anim
                                       SC_P_GetPos(player,&pl_pos);
                                       trans.loc=pl_pos;
                                       SC_NOD_SetTransform(kill_obj_id,&trans);
                                       pl_pos.z+=0.1;
                                       SC_P_SetPos(player, &pl_pos);//move player up 0.1 m then he fall dawn and cause collision with "kill" object
                                       SC_SetViewAnim(COMA_ANM, 0, 0, 0);//clear view anim
                                       start_dead=FALSE;
                                    }
                                 }
                              }else{//_________________________PC  COMA_____________________________
                                 if (start_coma){//start coma state
                                    SC_PC_EnableMovementAndLooking(FALSE);
                                    if (SC_P_GetPhase(player)<1){
                                       SC_P_SetPhase(player, 1.0f);
                                    }   
                                    SC_P_SetSelWeapon(player, 0);//select first slot
                                    SC_P_ChangeWeapon(player, 0, NULL);//remove knife//29 – US knife   30 – VC knife
                                    SC_P_DoAnimLooped(player, "g\\characters\\anims\\A550_DEATHMOVE.STG");//A400 M-16 STAT LEH BM.STG // A550_DEATHMOVE.STG
                                    SC_PC_PlayFpvLooped("g\\WEAPONS\\!DEFAULT\\STATIV_LIE.STG"); //STATIV_LIE.STG //HIDE_LIE.STG
                                    start_coma=FALSE;
                                    SC_P_GetPos(player,&pl_pos);
                                    trans_view.loc = pl_pos;
                                    SC_NOD_SetTransform(view_obj_id,&trans_view);
                                    SC_SetViewAnimEx(COMA_ANM, 0, 1000, 0,view_obj_id );
                                    SC_GameInfo(NULL, "You are too weak to move");
                                 }
                                 sprintf(txt, " %2.0f", ((pl_info.cur_hp-DEAD) / CO_DAMAGE));
                                 SC_GameInfo(NULL, txt);
                                 SC_P_SetHp(enum_pl[i].id, (pl_hp-CO_DAMAGE));//server must do a damage
                              }
                           }else{//PC_WOUNDED
                              if (start_wounded){//start coma state
                                 SC_GameInfo(NULL, "Your health is worsening");
                                 start_wounded=FALSE;
                              }else{
                                 time_left=((pl_info.cur_hp - COMA) / WO_DAMAGE);
                                 if (time_left <= INF_TIME ){
                                    sprintf(txt, " %2.0f", time_left);
                                    SC_GameInfo(NULL, txt);
                                 }
                              }
                              SC_P_SetHp(enum_pl[i].id, (pl_hp-WO_DAMAGE));//server must do a damage
                           }
                        }
                        else{//_________________________PC  not in coma
                           if (start_coma == FALSE){ //PC was incoma but now healed
                              SC_PC_EnableMovementAndLooking(TRUE);
                              SC_P_DoAnimLooped(player, NULL);//A400 M-16 STAT LEH BM.STG // A550_DEATHMOVE.STG
                              SC_PC_PlayFpvLooped(NULL);
                              SC_SetViewAnim(COMA_ANM, 0, 0, 0);//clear view anim
                              if (pl_info.side == 0) SC_P_ChangeWeapon(player, 0, 29);//remove knife//29 – US knife   30 – VC knife
                              if (pl_info.side == 1) SC_P_ChangeWeapon(player, 0, 30);//remove knife//29 – US knife   30 – VC knife
                              start_dead = TRUE;
                              start_coma = TRUE;
                              start_wounded = TRUE;
                           }
                        }
                     }
                     //_________________________ALL  PLAYERS
                     if (pl_info.cur_hp < WOUNDED){
                        if (pl_info.cur_hp < COMA ){
                           if (pl_info.cur_hp < 0.7f ){//killed by damage
                           }else{//coma
                              if (SC_ggi(GVAR_SERVER) == 1){// sever
                                 SC_P_SetHp(enum_pl[i].id, (pl_hp-CO_DAMAGE));//server must do a damage
                              }
                              //need do remove repeating it
                              not_in_list=TRUE;
                              for (k=0;k<10;k++){
                                 if (pl_coma[k]==enum_pl[i].id) {//alreadi in list
                                    not_in_list=FALSE;
                                    break;// exit from "for"
                                 }
                              }
                              if (not_in_list){
                                 for (k=0;k<10;k++){
                                    if (pl_coma[k]==0) {//free slot
                                       pl_coma[k] = enum_pl[i].id;
                                       SC_P_DoAnimLooped(enum_pl[i].id, "g\\characters\\anims\\A550_DEATHMOVE.STG");//A400 M-16 STAT LEH BM.STG // A550_DEATHMOVE.STG
                                       break;// exit from "for"
                                    }
                                 }
                              }   
                           }
                        }else{//wounded
                           if (SC_ggi(GVAR_SERVER) == 1){// sever
                              SC_P_SetHp(enum_pl[i].id, (pl_hp-WO_DAMAGE));//server must do a damage
                           }
                        }
                     }else{
                        for (k=0;k<10;k++){
                           if (pl_coma[k]==enum_pl[i].id) {
                              SC_P_DoAnimLooped(enum_pl[i].id, NULL);   // end player animation loop for current PC
                              pl_coma[k]=0;                     //remove coma state for that plyer
                              break;// exit from "for"
                           }
                        }
                     }
                  }
               }
            }
         }
         break;
      case SC_OBJ_INFO_EVENT_USED:
         break;
   }// switch(info->event_type)
   return TRUE;
}// int ScriptMain(s_OBJ_info *info)



Ando attached the following file:
killer.rar [1.32 kB, 195 Downloads]
Edited by Ando on 06-12-2011 19:45
  x 2  x 2  x 1
 
Ando
AI script with extra options
Description:
- random ini file
- random weapon

- patrol ( on/off/follow to other AI PM)
- _move mode (walk, aim, run )
- _stand mode (stand, crouch, lie)
- _patrol loop ( on/off)
- _patrol order between bath waypoints (forward, backward, forward-backward, random )
- _automatically detect path waypoint count
- _waypoint object names

- __patrol follow to other player ( pointman id)
- __distance where AI stop following to PM
- __distance where AI continue following to PM
- __distance where AI run to follow to PM
- __right/left angle to aim (degrees from PM direction)

- _ distance where AI stop and look other AI/PC
- _ time how long AI look AI/PC near him
- _ time how long AI ignore AI/PC near him after look


Tutorial for editor:
AI is patrolling only in peace mode.
in editor rename waypoints what AI will pass during patrol ( it is working with "Dummy" objects to)

First number after name must be "0"

example 1:
"patrol_1#0"
"patrol_1#1"
"patrol_1#2"
"patrol_1#3"
...

in script, name for that way is "patrol_1#%d" ("%d" is for script, to replace it with numbers)
You can use any name.

Tip: Sometimes I double waypoint height, then is easier to find my patrol way objects later.

Add your AI near first point.
In game it will go to waypoint "patrol_1#0" > "patrol_1#1" > ....after last again to "patrol_1#0"
There is more options for points order and you see description behind "PATROL_ORDER"

You can add more players to this defined way.
You can add different way for every AI and don't forget to fix that name in script.



AI C file
copy that file to script folder of your map as much you need.
Spoiler:
Download source  Code
// part of vc1 AI script
// created by Ando
//
#include <inc\sc_global.h>
#include <inc\sc_def.h>



#define P_SIDE         SC_P_SIDE_VC      // SC_P_SIDE_US; SC_P_SIDE_VC; 3 - custom civilian
#define P_GROUP         2               //AI group
#define P_MEMBERID      1               //AI id
//#define P_INIFILENAME   "ini\\players\\vcfighter4.ini"
#define P_NAME_NR      2506   //villager-2510


//____________________________WEAPONS____________________________
#define P_KNIFE         0
#define P_PISTOL      10
//#define P_WEAPON1      2   //random if not defined
#define P_WEAPON2      0
#define P_SLOT1         0


//____________________________AI EXIST IN MODE_______________________________
#define P_EXIST_MODE   7   //      7-COOP,   10-COOP_VC (custom);


//____________________________PATROL______________________________
#define PATROL                  0   // 0 - disabled, 1 - normal patrol, 2- follow to player *
   #define PATROL_MOVEMODE         0   //0-walk, 1-aim, 2- run
   #define PATROL_MOVEMODE_2      0   //0-stand,1-crouch,2-LIE   

   #define PATROL_LOOPED         TRUE
   #define PATROL_ORDER         0         //0-forward, 1-backward, 2-forward-backward, 3-random
   #define PATROL_POINTS         0         //if 0 then detecting automatically max objects with that(PATROL_OBJECTS) name
   #define   PATROL_OBJECTS         "patrol_1#%d"   //waypoint objects (patrol bath waipoint names what must start with end #0( example "patrol_1#0"))

      //_____FOLLOW TO PLAYER___(in peace mode)
      //only if PATROL = 2
      #define PATROL_FOLLOW_TO         10   //player id (must be same side and same group as current player)
      #define PATROL_STOP_DIST         2   //stop when dist is smaller than
      #define PATROL_FOLLOW_DIST         5   //follow when dist is bigger than
      #define PATROL_TOFAR_DIST         8   //run when too far
      #define VIEW_ROT_FROM_PM         65.0f   // angle in degrees( if 65 then AI will aim 65 degree right from pointman bath)


//_____________________________BEHAVIOUR NEAR OTHER PLAYER_________
#define LOOK_NEAREST_DIST            1.0f   // AI will react when somebody is nearer than that ( AI will stop and look other player)
#define LOOK_NEAREST_TIME            3.0f   // time what AI will look other player near him
#define LOOK_NEAREST_IGNORE            10.0f   // ignore time after looking some player
//_________________________________________________________________
//_________________________________________________________________
//_________________________________________________________________
//__________________________________________________________CREATE CXX


#include <inc\ando\AI\Ando_AI_v2.cxx>





AI CXX file
put that file to "Vietcong\dev\compiler\inc\ando\AI\Ando_AI_v2.cxx"
Spoiler:
Download source  Code
// CXX file for VC AI script
// created by Ando




/*
//_________________________C FILE_________________________
// part of vc1 AI script
// created by Ando
//
#include <inc\sc_global.h>
#include <inc\sc_def.h>



#define P_SIDE         SC_P_SIDE_VC      // SC_P_SIDE_US; SC_P_SIDE_VC; 3 - custom civilian
#define P_GROUP         2               //AI group
#define P_MEMBERID      1               //AI id
//#define P_INIFILENAME   "ini\\players\\vcfighter4.ini"
#define P_NAME_NR      2506   //villager-2510


//____________________________WEAPONS____________________________
#define P_KNIFE         0
#define P_PISTOL      10
//#define P_WEAPON1      2   //random if not defined
#define P_WEAPON2      0
#define P_SLOT1         0


//____________________________AI EXIST IN MODE_______________________________
#define P_EXIST_MODE   7   //      7-COOP,   10-COOP_VC (custom);


//____________________________PATROL______________________________
#define PATROL                  0   // 0 - disabled, 1 - normal patrol, 2- follow to player *
   #define PATROL_MOVEMODE         0   //0-walk, 1-aim, 2- run
   #define PATROL_MOVEMODE_2      0   //0-stand,1-crouch,2-LIE   

   #define PATROL_LOOPED         TRUE
   #define PATROL_ORDER         0         //0-forward, 1-backward, 2-forward-backward, 3-random
   #define PATROL_POINTS         0         //if 0 then detecting automatically max objects with that(PATROL_OBJECTS) name
   #define   PATROL_OBJECTS         "patrol_1#%d"   //waypoint objects (patrol bath waipoint names what must start with end #0( example "patrol_1#0"))

      //_____FOLLOW TO PLAYER___(in peace mode)
      //only if PATROL = 2
      #define PATROL_FOLLOW_TO         10   //player id (must be same side and same group as current player)
      #define PATROL_STOP_DIST         2   //stop when dist is smaller than
      #define PATROL_FOLLOW_DIST         5   //follow when dist is bigger than
      #define PATROL_TOFAR_DIST         8   //run when too far
      #define VIEW_ROT_FROM_PM         65.0f   // angle in degrees( if 65 then AI will aim 65 degree right from pointman bath)


//_____________________________BEHAVIOUR NEAR OTHER PLAYER_________
#define LOOK_NEAREST_DIST            1.0f   // AI will react when somebody is nearer than that ( AI will stop and look other player)
#define LOOK_NEAREST_TIME            3.0f   // time what AI will look other player near him
#define LOOK_NEAREST_IGNORE            10.0f   // ignore time after looking some player
//_________________________________________________________________
//_________________________________________________________________
//_________________________________________________________________
//__________________________________________________________CREATE CXX


#include <inc\ando\AI\Ando_AI_v2.cxx>

//_________________________END OF C FILE_________________________
*/





//____________________
#define PVANGLE         3.0f
#define PVANGLENEAR      4.0f


//_______________settings of difficulties
#ifndef D0_SHOOT_PREC
#define   D0_SHOOT_PREC   1.5f
#endif

#ifndef D1_SHOOT_PREC
#define   D1_SHOOT_PREC   1.0f
#endif

#ifndef D2_SHOOT_PREC
#define   D2_SHOOT_PREC   0.3f
#endif

#ifndef D3_SHOOT_PREC
#define   D3_SHOOT_PREC   0.05f
#endif
//________________________________

float         timer = 0.0f;
float         look_timer=0.0;
float         nearest_dist;
float         dist_to_PM;
float         shortest_dist=1000;
float         cur_wp_dist;

int         i_items,j;
int         patrol_obj_count;
int         current_patrol;

dword       list[32];

dword         gPhase = 0;
dword         cur_pendl_point = -1;
dword         Pendl_Phase=0;

dword         nearest_pl;

c_Vector3         Pl_Pos;
c_Vector3         Target_Pos;
c_Vector3         Last_pos;
c_Vector3         look_dir;
c_Vector3         nearest_head_pos;
c_Vector3         new_look;
c_Vector3         rel_x_pos;
c_Vector3         PM_player_pos;
c_Vector3         player_pos;

s_sphere   sph;

char   txt[32];
s_SC_NOD_transform trans;

s_SC_P_SpecAnims  my_anims;




//__________________________________________________________

//______________RANDOM WEAPONS_______________
#define   MAX_US_WEAPS   8
dword us_weap[MAX_US_WEAPS] = {1,4,11,12,17,19,21,25};   //maybe more

#define   MAX_VC_WEAPS   10
dword vc_weap[MAX_VC_WEAPS] = {2,6,8,9,14,15,18,23,26,28}; //maybe more




//______________RANDOM INIS_______________
#define   MAX_US_INIS   6
char *us_ini[MAX_US_INIS] = {   
   "ini\\players\\CIDG.ini",
   "ini\\players\\CIDG2.ini",
   "ini\\players\\lldb.ini",
   "ini\\players\\lldb2.ini",
   "ini\\players\\sf1.ini",    
   "ini\\players\\sf2.ini"   };


#define   MAX_VC_INIS   15
char *vc_ini[MAX_VC_INIS] = {   
   
   "ini\\players\\default_aiviet.ini",
   "ini\\players\\poorvc.ini",
   "ini\\players\\poorvc2.ini",
   "ini\\players\\poorvc3.ini",
   "ini\\players\\vcfighter.ini",
   "ini\\players\\vcfighter2.ini",
   "ini\\players\\vcfighter3.ini",
   "ini\\players\\vcfighter4.ini",
   "ini\\players\\vcuniform1.ini",
   "ini\\players\\vcuniform2.ini",
   "ini\\players\\vcuniform3.ini",
   "ini\\players\\nvasoldier2.ini",
   "ini\\players\\nvasoldier3.ini",
   "ini\\players\\vcgirlpajama.ini",
   "ini\\players\\nvaofficer.ini"};

//"ini\\players\\poorvc4.ini",      //FA
//"ini\\players\\vcfighter5.ini",   //FA
//"ini\\players\\vcuniform4.ini",   //FA
//"ini\\players\\nvasoldier4.ini",   //FA
//"ini\\players\\nvacolonel.ini"   //FA




//______________________________________________________________






void equipplayer(s_SC_P_CreateEqp *eqp, int *count){
   int               my_class;
   
   #ifdef P_CLASS
      my_class = CLASS
   #else
      my_class = rand()%5;
   #endif
   

   switch(my_class){
   case 0://   _______________soldier_______________
         //_________head gear
         eqp[0].bes = "G\\Equipment\\US\\bes\\EOP_hlmt1US_v03.BES";
         eqp[0].eqp = "G\\Equipment\\US\\eqp\\CUP_SFgncsldr01\\velka_polni\\EOP_hlmt1US_v03.eqp";
         *count=1;
      break;
   case 1://   _______________engineer
      break;
   case 2://   _______________medic
      break;
   case 3://   _______________machinegunner
      break;
   case 4://   _______________radioman
      break;
   case 5://   _______________sniper
      break;
   }
}


dword       my_PM_player;
         



int ScriptMain(s_SC_P_info *info){
   s_SC_P_Create      pinfo;
   s_SC_P_CreateEqp   eqp[10];
   s_SC_P_AI_props      props;
   s_SC_P_getinfo      plInfo;
   c_Vector3         plPos;
   dword            i, j;
   int               eqpcount;
   int               patrol_back=1;


   info->next_exe_time = 0.5f;
   switch( info->message ){
   case SC_P_MES_TIME:
      timer+=info->elapsed_time;
      if (SC_ggi(GVAR_MP_MISSIONTYPE)==P_EXIST_MODE){   
         switch( gPhase ){
         case 0:
            CLEAR(pinfo);
            pinfo.type =      SC_P_TYPE_AI;
            pinfo.side =      P_SIDE;
            pinfo.group =      P_GROUP;
            pinfo.member_id =   P_MEMBERID;

            #ifdef P_INIFILENAME
               pinfo.inifile =   P_INIFILENAME;
            #else
               if(SC_P_SIDE_VC== 0){//us
                  pinfo.inifile =   us_ini[ rand()%MAX_US_INIS ];
               }else{   //vc
                  pinfo.inifile =   vc_ini[ rand()%MAX_VC_INIS ];
               }
               
            #endif
            pinfo.name_nr =      P_NAME_NR;
            pinfo.icon_name =   "nhut";
            pinfo.weap_knife =   P_KNIFE;
            pinfo.weap_pistol = P_PISTOL;

            #ifdef P_WEAPON1
               pinfo.weap_main1 =   P_WEAPON1;
            #else
               if(SC_P_SIDE_VC== 0){//us
                  pinfo.weap_main1 = us_weap[ rand()%MAX_US_WEAPS ];
               }else{   //vc
                  pinfo.weap_main1 = vc_weap[ rand()%MAX_VC_WEAPS ];
               }
               
            #endif
            pinfo.weap_main2 =   P_WEAPON2;
            pinfo.weap_slot1 =   P_SLOT1;
            pinfo.debrief_group=SC_P_DEBRIEFGROUP_VC;//SC_P_DEBRIEFGROUP_CIVIL;
            pinfo.recover_pos = info->pos;   

            
            CLEAR(eqp);


            
            //equipplayer(eqp,&eqpcount);

            //pinfo.eqps = eqpcount;
            //pinfo.eqp=eqp;



            if (P_SIDE==3){
               eqpcount=1;
               eqp[0].bes = "G\\ITEMS\\V - PRACOVNI NASTROJE\\IVQ_KOPAC.BES";
               eqp[0].eqp = "G\\EQUIPMENT\\US\\EQP\\IVQ_KOPAC.EQP";

               pinfo.eqps = eqpcount;
               pinfo.eqp = eqp; 
            }





            info->pl_id = SC_P_Create(&pinfo);
            gPhase = 1;
            break;
         case 1:
            if ( !SC_P_IsReady(info->pl_id) )
               return 0;

            Pendl_Phase=0;
            cur_pendl_point = -1;
            if (P_SIDE<=1) SC_P_Ai_EnableShooting(info->pl_id, TRUE);
            else SC_P_Ai_EnableShooting(info->pl_id, FALSE);//disable shooting for civilians

            SC_P_Ai_SetPeaceMode(info->pl_id, SC_P_AI_PEACEMODE_HOLD);

            SC_P_Ai_SetBattleMode(info->pl_id, SC_P_AI_BATTLEMODE_ATTACK);//____________

            SC_P_Ai_SetMode(info->pl_id, SC_P_AI_MODE_BATTLE);//   SC_P_AI_MODE_SCRIPT
            CLEAR(props);
            SC_P_Ai_GetProps(info->pl_id, &props);         
            props.extend_searchway      = FALSE;
            props.shortdistance_fight   = 0.0f;
            props.view_angle         = PVANGLE;
            props.view_angle_near      = PVANGLENEAR;
            props.shoot_imprecision = 0;
            props.shoot_damage_mult = 1.3f;
            props.watchfulness_maxdistance = 1;
            props.reaction_time      = 0.01f;
            props.scout            = 0.1f + frnd(0.1f);
            props.berserk         = 0.1f;
//SC_message("My AI max_vis_distance  %f",props.max_vis_distance);
            props.max_vis_distance = SC_GetVisibility()-2;

            //props.max_vis_distance = 120         // maximum visual distance the AI can see, if not specified, AI uses maximum visual distance specified for the level.
            //props.watchfulness_zerodist = 2      // how good is AI at recognizing the enemy at zero distance.
            //props.watchfulness_maxdistance = 1   // how good is AI at recognizing the enemy at maximum distance.
            //props.boldness = 1               // this is used to determine how bold is the AI when in cover and under fire. 0.5 is very cautious player, 2 is medium, 4 is high. 10 is almost suicidal, the AI will not give a damn if someone is shooting at him.
            //props.coveramount = 0.5            // how far the AI will run for cover compared to the distance to the closest enemy, default is 0.5.
            //props.hear_imprecision = 1         // imprecision of the AI’s hearing. 0 absolute hearing, 1 average, 5 very bad.
            //props.hear_distance_mult = 1         // hear distance multiplier – 0.5 is half, 2 is two times better.
            //props.hear_distance_max = 1000      // maximum hearing distance.

            //props.grenade_min_distance;         // minimal distance to throw grenade at (default: 10.0f)
            //props.grenade_timing_imprecision = 2.5   // this is maximum time (will be randomized) between impact of the grenade and it’s explosion.
            //props.grenade_throw_imprecision = 1   // imprecision of the grenade throwing. 0 perfect, 1 average, 2 quite bad.
            //props.grenade_sure_time = 13.737358   // how long the AI will wait until it’s sure the situation demands a grenade.
            //props.forget_enemy_mult = 1         // how fast will the AI forgot the enemies it has no more contact? 1 is default, 0.5  means two times slower, 2 mean two times faster.
            //disable_peace_crouch = 0;//BOOL      // this disables AI crouching in the peace mode.
            //props.peace_fakeenemy_run = 1;      // this is used to set the movement type under the fake enemy situation.  1 means always run, 0 always walk, 0.5 use run/walk 1:1.
            //props.peace_fakeenemy_phase = 0.5      // same as previous, only for the stand/crouch.
            //props.shoot_while_hidding    = 0.3      // if enabled the AI will shoot even when moving to the hide out.
            //props.aimtime_max = 0.7            // maximum time for AI to take an aim, default 0.7 seconds
            //props.aimtime_canshoot = 0.1         // minimum time for AI to take an aim, default 0.1 seconds.
            //props.aimtime_rotmult = 0.5         // multiplier of the rotation speed when aiming, default 0.5 seconds.
            //props.wounded_start_perc = 0.5      // value of the current hp/max hp when the AI aiming starts to be worse
            //props.wounded_aimtime_mult_max = 2   // multiplier for the maximum aim time when hit points of the AI is zero.
            //props.wounded_shoot_imprec_plus = 0.5   // multiplier for the maximum aim imprecision when hit points of the AI is zero.
            //props.shoot_imprecision = D0_SHOOT_PREC;   //overload previous (default) setting
            //props.shoot_damage_mult = 0.5f;
            //props.grenade_throw_imprecision = 1.5f + frnd(0.5f);


         //set by difficulty
         switch( SC_ggi(SGI_DIFFICULTY) ){
         case 0:
            props.shoot_imprecision      = D0_SHOOT_PREC;      //overload previous (default) setting
            props.shoot_damage_mult      = 0.5f;
            props.grenade_throw_imprecision = 1.5f + frnd(0.5f);
            break;
         case 1:
            props.shoot_imprecision      = D1_SHOOT_PREC;
            props.shoot_damage_mult      = 1.0f;
            props.grenade_throw_imprecision = 1.0f + frnd(0.5f);
            break;
         case 2:
            props.shoot_imprecision      = D2_SHOOT_PREC;
            props.shoot_damage_mult      = 1.1f;
            props.grenade_throw_imprecision = 0.5f + frnd(0.5f);
            break;
         case 3:
            props.shoot_imprecision      = D3_SHOOT_PREC;
            props.shoot_damage_mult      = 1.2f;
            props.grenade_throw_imprecision = 0.3f + frnd(0.3f);
            break;
         }

            SC_P_Ai_SetProps(info->pl_id,&props);
            SC_P_SetSpeachDist(info->pl_id,20);
         

            current_patrol=PATROL;

            switch( current_patrol ){
            case 0://PATROL disabled
               gPhase = 3;
               break;
            case 1://Normal PATROL
               SC_P_Ai_SetMovePos(info->pl_id, PATROL_MOVEMODE_2); // test
               gPhase = 2;
               if (PATROL_POINTS==0){
                  patrol_obj_count=0;
                  for(i= 0; i < 20; i++){//count of objects
                     sprintf(txt, PATROL_OBJECTS, i);
                     if (SC_NOD_GetNoMessage_Entity(txt))patrol_obj_count++;
                  }
               }else{
                  patrol_obj_count=PATROL_POINTS;
               }
               break;
            case 2://Follow to player
               SC_P_Ai_SetMovePos(info->pl_id, PATROL_MOVEMODE_2); // test
               gPhase = 2;
               //
               if (PATROL_POINTS==0){
                  patrol_obj_count=0;
                  for(i= 0; i < 20; i++){//count of objects
                     sprintf(txt, PATROL_OBJECTS, i);
                     if (SC_NOD_GetNoMessage_Entity(txt))patrol_obj_count++;
                  }
               }else{
                  patrol_obj_count=PATROL_POINTS;
               }


               break;
            }
            break;
         case 2://__________________________________PATROL__________________________
            if (SC_P_Ai_GetEnemies(info->pl_id) < 1) {//if (SC_P_Ai_GetDanger(info->pl_id) <= 0.001f) {
               if (timer >= 0){//ready
                  switch( current_patrol ){
                  case 1://Normal PATROL
                     switch( Pendl_Phase ){
                     case 0://give task
                        if (cur_pendl_point== -1){//first start for normal or follower whos PM is dead
                           SC_message("1");
                           //search closest PATROL point
                           SC_P_GetPos(info->pl_id, &Pl_Pos);
                           for(i = 0; i < patrol_obj_count; i++){
                              SC_message("1  %d",i);
                              sprintf(txt, PATROL_OBJECTS, i);
                              SC_NOD_GetTransform(SC_NOD_GetNoMessage_Entity(txt),&trans);
                              Target_Pos=trans.loc;
                              cur_wp_dist = SC_2VectorsDist(&Pl_Pos, &Target_Pos);
                              if (cur_wp_dist < shortest_dist){
                                 shortest_dist=cur_wp_dist;
                                 cur_pendl_point=i;
                              }
                           }
                        }
                        sprintf(txt, PATROL_OBJECTS, cur_pendl_point);
                        SC_P_Ai_SetMode(info->pl_id, SC_P_AI_MODE_SCRIPT);
                        SC_P_Ai_SetMoveMode(info->pl_id, PATROL_MOVEMODE);
                        SC_NOD_GetTransform(SC_NOD_GetNoMessage_Entity(txt),&trans);
                        Target_Pos=trans.loc;
                        SC_P_Ai_Go(info->pl_id, &Target_Pos);
                        info->next_exe_time = 0.5f;//
                        Pendl_Phase=1;
                        break;
                     case 1://going
                        Last_pos=Pl_Pos;
                        SC_P_GetPos(info->pl_id, &Pl_Pos);

                        sph.pos=Pl_Pos;
                        sph.rad=LOOK_NEAREST_DIST;
                        i_items=32;
                        
                        SC_GetPls(&sph,list,&i_items);
                        
                        look_timer+=info->elapsed_time;

                        if((i_items>1)&&(look_timer<0)){//is there nearest player near him && look time isnt over
                           
                           if (list[0]==info->pl_id){
                              j=1;
                           }
                           else{
                              j=0;
                           }
                           SC_P_Ai_Stop(info->pl_id);
                           SC_P_GetHeadPos(list[j], &nearest_head_pos);
                           SC_P_Ai_LookAt(info->pl_id, &nearest_head_pos);// look at nearest player
                           timer=-1;


                        }
                        else{   // no player near him OR ignore him
                           if (look_timer>LOOK_NEAREST_IGNORE){   //ignore is over
                              look_timer=0-LOOK_NEAREST_TIME;
                           }
                           

                           if ((Last_pos.x==Pl_Pos.x) &&(Last_pos.y==Pl_Pos.y)){// player not moveing, need to give task again
                           Pendl_Phase=0;
                           
                           }
                        }
                        if (SC_IsNear3D(&Pl_Pos, &Target_Pos, 1)){//reached to target pos
                           timer=-1;//wait more one sec
                           Pendl_Phase=2;
                        }
                        break;
                     case 2://do something
                        timer=-4;
                        look_dir.x    = trans.loc.x+sin(trans.rot.z)*10;   
                        look_dir.y    = trans.loc.y+cos(trans.rot.z)*10;
                        look_dir.z    = trans.loc.z-sin(trans.rot.x)*10;
                        SC_P_Ai_LookAt(info->pl_id, &look_dir);
                        SC_P_Ai_SetMovePos(info->pl_id, PATROL_MOVEMODE_2);
                        
                        Pendl_Phase=3;
                        break;
                     case 3://loop or finish
                        //SC_P_DoAnim(info->pl_id, NULL);
                        if(PATROL_LOOPED){
                           Pendl_Phase=0;
                        }
                        else{
                           Pendl_Phase=4;
                        }
                        switch( PATROL_ORDER ){
                        case 0://forward
                           cur_pendl_point+=1;
                           if(cur_pendl_point == patrol_obj_count)   cur_pendl_point =0;
                           break;
                        case 1://backward
                           cur_pendl_point-=1;
                           if(cur_pendl_point == -1)cur_pendl_point = patrol_obj_count-1;
                           break;
                        case 2://forward-backward
                           if(cur_pendl_point == 0)   patrol_back=1;
                           if (cur_pendl_point == patrol_obj_count-1)   patrol_back=(-1);
                           cur_pendl_point+=patrol_back;
                           break;
                        case 3://random
                           cur_pendl_point = rand() % patrol_obj_count ;//random target point
                           break;
                        }
                        break;
                     case 4://finished
                        break;
                     }
                     break;
                  case 2://Follow to player
                     my_PM_player = SC_P_GetBySideGroupMember(P_SIDE, P_GROUP, PATROL_FOLLOW_TO);
                     if (my_PM_player){
                        if (SC_P_IsReady(my_PM_player)){
                        
                           SC_P_Ai_SetMode(info->pl_id, SC_P_AI_MODE_SCRIPT);
                           SC_P_Ai_SetMoveMode(info->pl_id, PATROL_MOVEMODE);

                           SC_P_GetPos(my_PM_player, &PM_player_pos);
                           SC_P_GetPos(info->pl_id, &player_pos);
                           dist_to_PM =SC_2VectorsDist(&PM_player_pos, &player_pos);


                           
                           // look TEST__________________
                           rel_x_pos.x = PM_player_pos.x - player_pos.x;
                           rel_x_pos.y = PM_player_pos.y - player_pos.y;
                           rel_x_pos.z = PM_player_pos.z - player_pos.z;
                           new_look.x=player_pos.x +(rel_x_pos.x*cos(VIEW_ROT_FROM_PM*PI/180))+(rel_x_pos.y*sin(VIEW_ROT_FROM_PM*PI/180));
                           new_look.y=player_pos.y -(rel_x_pos.x*sin(VIEW_ROT_FROM_PM*PI/180))+(rel_x_pos.y*cos(VIEW_ROT_FROM_PM*PI/180));
                           new_look.z=player_pos.z;
                           SC_P_Ai_LookAt(info->pl_id, &new_look);// look at nearest player
                           SC_P_Ai_ShouldLookAt(info->pl_id, &new_look, 2.0f);
                           // END OF look TEST__________________
                           if(dist_to_PM > PATROL_FOLLOW_DIST){
                              SC_P_Ai_Go(info->pl_id, &PM_player_pos);
                              SC_P_Ai_SetMoveMode(info->pl_id,SC_P_AI_MOVEMODE_WALK);
                              SC_P_Ai_SetMovePos(info->pl_id, PATROL_MOVEMODE_2); //
                              SC_P_Ai_WalkThruAIs(info->pl_id,FALSE);
                           }
                           if(dist_to_PM > PATROL_TOFAR_DIST){
                              SC_P_Ai_Go(info->pl_id, &PM_player_pos);
                              SC_P_Ai_SetMoveMode(info->pl_id,SC_P_AI_MOVEMODE_RUN);
                              SC_P_Ai_WalkThruAIs(info->pl_id,TRUE);
                           }
                           if(dist_to_PM < PATROL_STOP_DIST){
                              SC_P_Ai_Stop(info->pl_id);
                              SC_P_Ai_SetMoveMode(info->pl_id,SC_P_AI_MOVEMODE_AIM);
                              SC_P_Ai_SetMovePos(info->pl_id,SC_P_AI_MOVEPOS_CROUCH);
                           }



                        }else{//pointman is not alive
                           SC_P_GetInfo(my_PM_player, &plInfo);
                           if (plInfo.cur_hp<=0) {
                              current_patrol=1;//patrol type changed from "follow" to normal patrol. because PM is dead
                              return 1;
                           }
                        }
                     }
                     break;
                  }
               }
            }
            else{
               timer=-15;// switch to script mode after 15 sec of last seen enemy
               SC_P_Ai_SetBattleMode(info->pl_id, SC_P_AI_BATTLEMODE_HOLD);//SC_P_AI_BATTLEMODE_HOLD   SC_P_AI_BATTLEMODE_GOTO
               SC_P_Ai_SetMode(info->pl_id, SC_P_AI_MODE_BATTLE);
            }
            
            break;
         case 3://
            info->next_exe_time = 3.0f;
            break;
         case 4://player killed
            info->next_exe_time = 3.0f;
            break;
         }//switch( gPhase )
         break;   //case SC_P_MES_TIME:
      }
      else{
         info->next_exe_time = 3.0f;//
      }
   case SC_P_MES_KILLED:


      //DEAD_EXIT_HELI  // ifdef
      //
      //SC_P_IsInHeli(dword pl_id);
      //SC_P_ExitShip(dword pl_id, c_Vector3 *new_pos);
      gPhase = 4;
      break;

      
   case SC_P_MES_SHOTAROUNDCALLBACK:

      break;
   case SC_P_MES_EVENT:
      switch(info->param1){
      case SCM_MP_REINIT:
         if (gPhase != 1)
            gPhase = 1;
         break;
      }
      break;
   }
   return 1;
}



Edited by Ando on 25-04-2016 15:06
  x 1  x 2
 
Jump to Forum:
Similar Threads
Thread Forum Replies Last Post
MEXICO SCRIPTS PROBLEM Vietcong Tech Talk 5 19-02-2016 09:58
I don't say to create a object with 3ds max Maps & Mapping 4 24-08-2015 21:19
***New Grass*** Object BES's for editor Maps & Mapping 1 02-04-2012 02:51
3d MAX Object not solid Maps & Mapping 7 14-03-2012 18:06
How to edit a Grow type object? Maps & Mapping 10 24-02-2012 11:35
Login
Username

Password



Forgotten your password?
Request a new one here.
Render time: 1.17 seconds - 132 Queries 2,268,768 unique visits