home *** CD-ROM | disk | FTP | other *** search
/ PC Gamer 5.14 / 2000-11_-_Disc_5.14.iso / Goodies / 3DGameStudio / Mission / weapons.wdl < prev    next >
Text File  |  2000-02-08  |  22KB  |  744 lines

  1. //////////////////////////////////////////////////////////////////////
  2. // WDL prefabs for weapon entities
  3. //////////////////////////////////////////////////////////////////////
  4. // change these sounds and graphics for your weapon
  5. IFNDEF WEAPON_DEFS;
  6.  SOUND gun_click,<empty.wav>;
  7.  SOUND gun_wham,<wham.wav>;
  8.  SOUND explo_wham,<explo.wav>;
  9.  DEFINE hit_wham,explo_wham;
  10.  SOUND gun_fetch,<beamer.wav>;
  11.  DEFINE ammo_fetch,gun_fetch;
  12.  DEFINE health_fetch,gun_fetch;
  13.  
  14.  DEFINE muzzle_flash,<particle.pcx>;
  15.  DEFINE small_flash,<particle.pcx>;
  16.  DEFINE fireball,<blitz.pcx>;
  17.  DEFINE BULLET_EXPLO,<explo+7.pcx>;
  18.  DEFINE EXPLO_FRAMES,7;
  19.  DEFINE WEAPON_AMPL,0.2;    // swaying
  20. ENDIF;
  21.  
  22. //////////////////////////////////////////////////////////////////////
  23. // adapt those skills and strings to your game
  24. // ammo starting and maximum values
  25. SKILL ammo1 { VAL 0; Z 200; }
  26. SKILL ammo2 { VAL 0; Z 100; }
  27. SKILL ammo3 { VAL 0; Z 40; }
  28. SKILL ammo4 { VAL 0; Z 10; }
  29.  
  30. // dynamic light values
  31. SKILL light_explo { RED 50; GREEN 50; BLUE 255; }
  32. SKILL light_flash { RED 200; GREEN 150; BLUE 50; }
  33. SKILL light_muzzle { RED 200; GREEN 20; BLUE 20; }
  34. SKILL light_bullet { RED 200; GREEN 50; BLUE 20; }
  35.  
  36. // you'll probably want to redefine those strings. No problem.
  37. STRING got_ammo1_str,"Got an ammo pack!";
  38. STRING got_ammo2_str,"Got a big ammo pack!";
  39. STRING got_ammo3_str,"Got a grenade pack!";
  40. STRING got_ammo4_str,"Got a rocket pack!";
  41. STRING got_medi_str,"Got a first aid kit!";
  42. STRING got_gun1_str,"Got a small gun!";
  43. STRING got_gun2_str,"Got a medium gun!";
  44. STRING got_gun3_str,"Got a large gun!";
  45. STRING got_gun4_str,"Got a gun no. 4!";
  46. STRING got_gun5_str,"Got a gun no. 5!";
  47. STRING got_gun6_str,"Got a gun no. 6!";
  48. STRING got_gun7_str,"Got a gun no. 7!";
  49.  
  50. //////////////////////////////////////////////////////////////////////
  51. /* Gun Action
  52.  
  53. FLAG1
  54.     If this flag is set, the gun model rotates before being picked up.
  55.  
  56. FLAG2
  57.     If this flag is set, the message on picking up the item will be
  58.     suppressed.
  59.  
  60. FLAG5
  61.    If this flag is marked, the gun sways a little if the camera is
  62.     moving. The sway period is the same as used for head bobbing in the
  63.     movement.wdl. If the flag is not marked, the gun stands still.
  64.  
  65. FLAG7
  66.    If this flag is marked, it's a machine gun. Otherwise, a single
  67.     action gun.
  68.  
  69. SKILL1..SKILL3
  70.     X Y Z position of the gun relative to the camera.
  71.  
  72. SKILL4
  73.     Ammo type (1..4). If 0, the gun doesn't consume ammunition. The part
  74.     after the decimal, times 100, gives the amount of ammo to be added
  75.     on picking up the gun. E.g. 2.30 = Ammo type 2, 30 rounds are
  76.     already in the gun.
  77.  
  78. SKILL5
  79.     Speed of the bullet, default = 200 quants / tick. The part after the
  80.     decimal, times 10, gives the strength of the recoil. If 0, then
  81.     there is no recoil. If SKILL5 is above 0, the recoil is done by
  82.     moving backwards. If SKILL5 is below 0, then the recoil is done by
  83.     swinging upwards.
  84.  
  85. SKILL6
  86.     Weapon number that determines the key (1..7) to be pressed to select
  87.     that gun.
  88.  
  89. SKILL7
  90.    The time (in ticks) the gun needs to reload. Includes the time for
  91.    the gun animation, if any.
  92.  
  93. SKILL8
  94.    Fire mode, can be composed by adding the following numbers:
  95.  
  96.     1 - Damage is applied by a SHOOT instruction, without bullet.
  97.     2 - Damage is applied by IMPACT of the bullet.
  98.     3 - Damage is applied by a SCAN explosion of the bullet.
  99.  
  100.     4 - the gun fires red particles.
  101.     8 - the gun fires dark bullets.
  102.     12 - the gun fires orange fireballs, which radiate light.
  103.  
  104.     32 - the bullets leave smoke trails.
  105.  
  106.     128 - at hit point there will be a light flash.
  107.     256 - at hit point there will be an explosion.
  108.     384 - at hit point there will be a big explosion.
  109.  
  110.     512 - at hit point a cloud of smoke will ascend.
  111.  
  112.     1024 - there will be multiple hit points, as by a shotgun.
  113.  
  114.     2048 - the gun spats out cartridge cases.
  115.  
  116.     4096 - the bullets follow gravity.
  117.  
  118.     Only combinations 133 and 303 are already implemented.
  119.  
  120.     The part after the decimal, times 100, gives the amount of damage
  121.     the bullet produces (default = 10).
  122.  
  123. */
  124. ///////////////////////////////////////////////////////////////////////
  125. DEFINE _OFFS_X,MY.SKILL1;
  126. DEFINE _OFFS_Y,MY.SKILL2;
  127. DEFINE _OFFS_Z,MY.SKILL3;
  128. DEFINE _AMMOTYPE,SKILL4;
  129. DEFINE _BULLETSPEED,SKILL5;
  130. DEFINE _WEAPONNUMBER,SKILL6;
  131. DEFINE _FIRETIME,SKILL7;
  132.  
  133. DEFINE _OFFS_FLASH,SKILL14;
  134. DEFINE _RECOIL,SKILL15;
  135. DEFINE _DAMAGE,SKILL16;
  136. DEFINE _DISPLACEMENT,SKILL17;
  137. DEFINE _FIRE,SKILL18;
  138.  
  139. DEFINE __REPEAT,FLAG7;
  140.  
  141. DEFINE MODE_DAMAGE,3;
  142. DEFINE DAMAGE_SHOOT,1;
  143. DEFINE DAMAGE_EXPLODE,3;
  144.  
  145. DEFINE MODE_FIRE,12;
  146. DEFINE FIRE_PARTICLE,4;
  147. DEFINE FIRE_BALL,12;
  148.  
  149. DEFINE BULLET_SMOKETRAIL,32;
  150.  
  151. DEFINE MODE_HIT,384;
  152. DEFINE HIT_FLASH,128;
  153. DEFINE HIT_EXPLO,256;
  154. ///////////////////////////////////////////////////////////////////////
  155. SYNONYM weapon { TYPE ENTITY; }
  156. // The weapon must be a model pointing into X-direction,
  157. // its center must be inside the barrel.
  158.  
  159. SYNONYM weapon1 { TYPE ENTITY; }
  160. SYNONYM weapon2 { TYPE ENTITY; }
  161. SYNONYM weapon3 { TYPE ENTITY; }
  162. SYNONYM weapon4 { TYPE ENTITY; }
  163. SYNONYM weapon5 { TYPE ENTITY; }
  164. SYNONYM weapon6 { TYPE ENTITY; }
  165. SYNONYM weapon7 { TYPE ENTITY; }
  166.  
  167. SKILL weapon_1 { VAL 0; }    // set to 1 if the player owns that weapon
  168. SKILL weapon_2 { VAL 0; }
  169. SKILL weapon_3 { VAL 0; }
  170. SKILL weapon_4 { VAL 0; }
  171. SKILL weapon_5 { VAL 0; }
  172. SKILL weapon_6 { VAL 0; }
  173. SKILL weapon_7 { VAL 0; }
  174.  
  175. SKILL gun_muzzle {}
  176. SKILL gun_target {}
  177. SKILL gun_loaded { VAL 1; }
  178. SKILL fireball_speed {}
  179.  
  180. SKILL weapon_number { VAL 0; }
  181. SKILL ammo_number { VAL 0; }
  182.  
  183. SKILL damage { VAL 0; }
  184. SKILL range { VAL 0; }
  185. SKILL fire_mode { VAL 0; }
  186. SKILL weapon_firing { VAL 0; }
  187.  
  188. //////////////////////////////////////////////////////////////////////
  189. ACTION testgun {
  190. IFNDEF TEST;
  191.     REMOVE ME;
  192.     RETURN;
  193. ENDIF;
  194.     SET MY.__ROTATE,ON;
  195.     SET MY.__REPEAT,ON;
  196.     SET MY.__BOB,ON;
  197.     MY.SKILL1 = 50;
  198.     MY.SKILL2 = 20;
  199.     MY.SKILL3 = 20;
  200.     MY._AMMOTYPE = 1.50;
  201.     MY._WEAPONNUMBER = 1;
  202.     MY._BULLETSPEED = -500.05;
  203.     MY._FIRETIME = 2;
  204.     MY._FIREMODE = DAMAGE_SHOOT+FIRE_PARTICLE+HIT_FLASH+0.30;
  205.     CALL gun;
  206. }
  207.  
  208. ACTION sparkgun {
  209.     SET MY.__ROTATE,ON;
  210.     SET MY.__REPEAT,ON;
  211.     SET MY.__BOB,ON;
  212.     MY.SKILL1 = 50;
  213.     MY.SKILL2 = 20;
  214.     MY.SKILL3 = 20;
  215.     MY._AMMOTYPE = 1.50;
  216.     MY._WEAPONNUMBER = 1;
  217.     MY._BULLETSPEED = -500.05;
  218.     MY._FIRETIME = 2;
  219.     MY._FIREMODE = DAMAGE_SHOOT+FIRE_PARTICLE+HIT_FLASH+0.30;
  220.     CALL gun;
  221. }
  222.  
  223. ACTION flashgun {
  224.     SET MY.__ROTATE,ON;
  225.     SET MY.__REPEAT,ON;
  226.     SET MY.__BOB,ON;
  227.     MY.SKILL1 = 42;
  228.     MY.SKILL2 = 20;
  229.     MY.SKILL3 = 7;
  230.     MY._AMMOTYPE = 2.15;
  231.     MY._WEAPONNUMBER = 2;
  232.     MY._BULLETSPEED = 150.05;
  233.     MY._FIRETIME = 5;
  234.     MY._FIREMODE = DAMAGE_EXPLODE+FIRE_BALL+HIT_EXPLO+BULLET_SMOKETRAIL+0.50;
  235.     CALL gun;
  236. }
  237.  
  238. //////////////////////////////////////////////////////////////////////
  239. ACTION ammopac {
  240. // default ammo type is 1
  241.     IF (MY._AMMOTYPE == 0) { MY._AMMOTYPE = 1; }
  242. // default ammo amount is a quarter of ammo maximum
  243.     IF (MY.SKILL5 == 0) {
  244.         IF (MY._AMMOTYPE == 1) { MY.SKILL5 = ammo1.Z * 0.25; }
  245.         IF (MY._AMMOTYPE == 2) { MY.SKILL5 = ammo2.Z * 0.25; }
  246.         IF (MY._AMMOTYPE == 3) { MY.SKILL5 = ammo3.Z * 0.25; }
  247.         IF (MY._AMMOTYPE == 4) { MY.SKILL5 = ammo4.Z * 0.25; }
  248.     }
  249.  
  250.     SET MY.EVENT,ammo_pickup;
  251.     CALL item_pickup;
  252. }
  253.  
  254. ACTION medipac {
  255.     IF (MY.SKILL5 == 0) { MY.SKILL5 = 25; }
  256.     SET MY.EVENT,medi_pickup;
  257.     CALL item_pickup;
  258. }
  259.  
  260. ACTION gun {
  261.     IF (MY.SKILL1 == 0) {
  262.         MY.SKILL1 = 50;
  263.         MY.SKILL2 = 20;
  264.         MY.SKILL3 = 20;
  265.     }
  266.  
  267.     IF (MY._WEAPONNUMBER <= 0 || MY._WEAPONNUMBER > 7) { MY._WEAPONNUMBER = 1; }
  268.  
  269.     MY._DAMAGE = FRC(MY._FIREMODE) * 100;
  270.     IF (MY._DAMAGE == 0) { MY._DAMAGE = 20; }
  271.     MY._FIREMODE = INT(MY._FIREMODE);
  272.     IF (MY._FIREMODE == 0) { MY._FIREMODE = DAMAGE_SHOOT+FIRE_PARTICLE+HIT_FLASH; }
  273.  
  274.     MY._RECOIL = FRC(MY._BULLETSPEED) * 100;
  275.     MY._BULLETSPEED = ABS(MY._BULLETSPEED);
  276.     IF (MY._BULLETSPEED < 1) { MY._BULLETSPEED = 200; }
  277.  
  278.     MY._OFFS_FLASH = MY.MAX_X + 1;     // Muzzle flash offset
  279.  
  280.     SET MY.EVENT,gun_pickup;
  281.     CALL item_pickup;
  282.  
  283. // check whether this gun was picked up before in another level,
  284. // and has to be re-created for this level
  285.     IF (MY._WEAPONNUMBER == 1 && weapon_1 == 1 && weapon1 == NULL) {
  286.         weapon1 = ME; GOTO restore; }
  287.     IF (MY._WEAPONNUMBER == 2 && weapon_2 == 1 && weapon2 == NULL) {
  288.         weapon2 = ME; GOTO restore; }
  289.     IF (MY._WEAPONNUMBER == 3 && weapon_3 == 1 && weapon3 == NULL) {
  290.         weapon3 = ME; GOTO restore; }
  291.     IF (MY._WEAPONNUMBER == 4 && weapon_4 == 1 && weapon4 == NULL) {
  292.         weapon4 = ME; GOTO restore; }
  293.     IF (MY._WEAPONNUMBER == 5 && weapon_5 == 1 && weapon5 == NULL) {
  294.         weapon5 = ME; GOTO restore; }
  295.     IF (MY._WEAPONNUMBER == 6 && weapon_6 == 1 && weapon6 == NULL) {
  296.         weapon6 = ME; GOTO restore; }
  297.     IF (MY._WEAPONNUMBER == 7 && weapon_7 == 1 && weapon7 == NULL) {
  298.         weapon7 = ME; GOTO restore; }
  299.  
  300.     RETURN;
  301.  
  302. restore:
  303. // weapon was already picked up by the player
  304.     MY._AMMOTYPE = INT(MY._AMMOTYPE);    // happens on pickup
  305.  
  306.     SET MY.INVISIBLE,ON;
  307.     SET MY.PASSABLE,ON;
  308.     SET MY.ENABLE_SCAN,OFF;
  309.     SET MY.ENABLE_CLICK,OFF;
  310.     SET MY.ENABLE_PUSH,OFF;
  311.     SET MY.EVENT,NULL;
  312. // Was it the last weapon the player carried?
  313.     IF (weapon_number == MY._WEAPONNUMBER) { CALL gun_select; }
  314. }
  315.  
  316. //////////////////////////////////////////////////////////////////////
  317. ACTION medi_pickup {
  318.     IF (EVENT_TYPE == EVENT_SCAN && indicator != _HANDLE) { RETURN; }
  319.     IF (EVENT_TYPE == EVENT_PUSH && YOU != player) { RETURN; }
  320.  
  321.     IF (YOU == NULL) { SET YOU,player; }
  322.     IF (YOU == NULL) { RETURN; }
  323.  
  324.     YOUR._HEALTH += MY.SKILL5;
  325.     IF (YOUR._HEALTH > 100) { YOUR._HEALTH = 100; }
  326.     PLAY_SOUND health_fetch,50;
  327.     SET msg.STRING,got_medi_str;
  328.     IF (MY.__SILENT != ON) { CALL show_message; }
  329.     REMOVE ME;
  330. }
  331.  
  332. ACTION ammo_pickup {
  333.     IF (EVENT_TYPE == EVENT_SCAN && indicator != _HANDLE) { RETURN; }
  334.     IF (EVENT_TYPE == EVENT_PUSH && YOU != player) { RETURN; }
  335.  
  336.     IF (MY._AMMOTYPE == 1) { ammo1 += MY.SKILL5; SET msg.STRING,got_ammo1_str; }
  337.     IF (MY._AMMOTYPE == 2) { ammo2 += MY.SKILL5; SET msg.STRING,got_ammo2_str; }
  338.     IF (MY._AMMOTYPE == 3) { ammo3 += MY.SKILL5; SET msg.STRING,got_ammo3_str; }
  339.     IF (MY._AMMOTYPE == 4) { ammo4 += MY.SKILL5; SET msg.STRING,got_ammo4_str; }
  340.     IF (MY.__SILENT != ON) { CALL show_message; }
  341.     CALL _ammo_limit;
  342.     PLAY_SOUND ammo_fetch,50;
  343.     REMOVE ME;
  344. }
  345.  
  346. ACTION _ammo_limit {    // clip ammo at maximum values
  347.     IF (ammo1 > ammo1.Z) { ammo1 = ammo1.Z; }
  348.     IF (ammo2 > ammo2.Z) { ammo2 = ammo2.Z; }
  349.     IF (ammo3 > ammo3.Z) { ammo3 = ammo3.Z; }
  350.     IF (ammo4 > ammo4.Z) { ammo4 = ammo4.Z; }
  351. }
  352.  
  353. ACTION gun_pickup {
  354.     IF (EVENT_TYPE == EVENT_SCAN && indicator != _HANDLE) { RETURN; }
  355.     IF (EVENT_TYPE == EVENT_PUSH && YOU != player) { RETURN; }
  356.  
  357.     SET MY.ENABLE_SCAN,OFF;
  358.     SET MY.ENABLE_CLICK,OFF;
  359.     SET MY.ENABLE_PUSH,OFF;
  360.  
  361.     IF (INT(MY._AMMOTYPE) == 1) { ammo1 += INT(FRC(MY._AMMOTYPE) * 100 + 0.5); }
  362.     IF (INT(MY._AMMOTYPE) == 2) { ammo2 += INT(FRC(MY._AMMOTYPE) * 100 + 0.5); }
  363.     IF (INT(MY._AMMOTYPE) == 3) { ammo3 += INT(FRC(MY._AMMOTYPE) * 100 + 0.5);    }
  364.     IF (INT(MY._AMMOTYPE) == 4) { ammo4 += INT(FRC(MY._AMMOTYPE) * 100 + 0.5);    }
  365.     MY._AMMOTYPE = INT(MY._AMMOTYPE);    // ammo type
  366.     CALL _ammo_limit;
  367.  
  368.     weapon_number = MY._WEAPONNUMBER;
  369.     IF (weapon_number == 1) { SET weapon1,ME; weapon_1 = 1; SET ON_1,_gun_select1; SET msg.STRING,got_gun1_str; }
  370.     IF (weapon_number == 2) { SET weapon2,ME; weapon_2 = 1; SET ON_2,_gun_select2; SET msg.STRING,got_gun2_str; }
  371.     IF (weapon_number == 3) { SET weapon3,ME; weapon_3 = 1; SET ON_3,_gun_select3; SET msg.STRING,got_gun3_str; }
  372.     IF (weapon_number == 4) { SET weapon4,ME; weapon_4 = 1; SET ON_4,_gun_select4; SET msg.STRING,got_gun4_str; }
  373.     IF (weapon_number == 5) { SET weapon5,ME; weapon_5 = 1; SET ON_5,_gun_select5; SET msg.STRING,got_gun5_str; }
  374.     IF (weapon_number == 6) { SET weapon6,ME; weapon_6 = 1; SET ON_6,_gun_select6; SET msg.STRING,got_gun6_str; }
  375.     IF (weapon_number == 7) { SET weapon7,ME; weapon_7 = 1; SET ON_7,_gun_select7; SET msg.STRING,got_gun7_str; }
  376.  
  377.     IF (MY.__SILENT != ON) { CALL show_message; }
  378.     CALL gun_select;
  379. }
  380.  
  381. ACTION _gun_select1 { weapon_number = 1; CALL gun_select; }
  382. ACTION _gun_select2 { weapon_number = 2; CALL gun_select; }
  383. ACTION _gun_select3 { weapon_number = 3; CALL gun_select; }
  384. ACTION _gun_select4 { weapon_number = 4; CALL gun_select; }
  385. ACTION _gun_select5 { weapon_number = 5; CALL gun_select; }
  386. ACTION _gun_select6 { weapon_number = 6; CALL gun_select; }
  387. ACTION _gun_select7 { weapon_number = 7; CALL gun_select; }
  388.  
  389. ACTION gun_select {
  390.     IF (weapon != NULL) {    // remove old weapon
  391.         SET weapon.INVISIBLE,ON;
  392.         SET weapon.PASSABLE,ON;
  393.     }
  394.  
  395.     IF (weapon_number == 1) { SET ME,weapon1; }
  396.     IF (weapon_number == 2) { SET ME,weapon2; }
  397.     IF (weapon_number == 3) { SET ME,weapon3; }
  398.     IF (weapon_number == 4) { SET ME,weapon4; }
  399.     IF (weapon_number == 5) { SET ME,weapon5; }
  400.     IF (weapon_number == 6) { SET ME,weapon6; }
  401.     IF (ME == NULL) { RETURN; }
  402.  
  403.     ammo_number = MY._AMMOTYPE;
  404.     SET MY.INVISIBLE, OFF;
  405.     SET MY.PASSABLE,ON;    // prevent collision with obstacles
  406.     SET MY.NEAR,ON;    // prevent clipping
  407.     SET weapon,ME;        // I'm the current weapon now
  408.     SET carry,weapon_carry;
  409.  
  410.     EXCLUSIVE_GLOBAL;
  411. // handle firing
  412.     WHILE (weapon == ME) {
  413.         IF (weapon_firing && (gun_loaded > 0) && (MY._FIRE <= 0) ) {
  414.             CALL gun_fire; }
  415.         IF ((weapon_firing == 0) && (gun_loaded == 0) && (MY.__REPEAT == OFF)) {
  416.             gun_loaded = 1; }
  417.         WAIT 1;
  418.     }
  419. }
  420.  
  421. //////////////////////////////////////////////////////////////////////
  422. // Called from player_move action; player must exist here
  423. ACTION weapon_carry {
  424.     IF (weapon == NULL || player == NULL) { RETURN; }
  425.     IF (person_3rd != 0) {
  426.         SET weapon.INVISIBLE,ON;
  427. // if firing in 3rd person mode, calculate the player's attack frame
  428.         IF (weapon._FIRE > 0) {
  429.             temp = (weapon._FIRETIME - weapon._FIRE) / weapon._FIRETIME;
  430.             if (temp < 0) { temp = 0; }
  431.             if (temp > 0.9) { temp = 0.9; }
  432.             player.FRAME = 1 + player._WALKFRAMES + player._RUNFRAMES + 1 + player._ATTACKFRAMES * temp;
  433.         }
  434.     } ELSE {
  435.         SET weapon.INVISIBLE,OFF;
  436.         MY_POS.X = weapon.SKILL1;
  437.         MY_POS.Y = -weapon.SKILL2;
  438.         MY_POS.Z = -weapon.SKILL3;
  439.         IF (weapon._RECOIL > 0) {
  440.             MY_POS.X -= weapon._DISPLACEMENT; }
  441.         IF (player.__BOB == ON) {
  442.             MY_POS.Y += headwave * WEAPON_AMPL;
  443.             MY_POS.X += headwave * WEAPON_AMPL;
  444.             MY_POS.Z -= headwave * WEAPON_AMPL;
  445.         }
  446.  
  447.         CALL _set_pos_ahead_xyz;
  448.         weapon.X = MY_POS.X ;
  449.         weapon.Y = MY_POS.Y;
  450.         weapon.Z = MY_POS.Z;
  451.         weapon.PAN = CAMERA.PAN;
  452.         weapon.TILT = CAMERA.TILT;
  453.         IF (weapon._RECOIL < 0) {
  454.             weapon.TILT -= weapon._DISPLACEMENT; }
  455.     }
  456. }
  457.  
  458. // fire weapon
  459. ACTION weapon_fire {
  460.     weapon_firing = 1;
  461.     WHILE (KEY_CTRL || MOUSE_LEFT) { WAIT 1; }
  462.     weapon_firing = 0;
  463. }
  464.  
  465. // deselect weapon
  466. ACTION weapon_remove {
  467.     IF (weapon != NULL) {
  468.         SET weapon.INVISIBLE,ON;
  469.         SET weapon,NULL;
  470.         weapon_number = 0;
  471.     }
  472. }
  473.  
  474. // put weapons and ammo to inital state
  475. ACTION weapon_init {
  476.     CALL weapon_remove;
  477.     ammo1 = 0;
  478.     ammo2 = 0;
  479.     ammo3 = 0;
  480.     ammo4 = 0;
  481.     weapon_1 = 0;
  482.     weapon_2 = 0;
  483.     weapon_3 = 0;
  484.     weapon_4 = 0;
  485.     weapon_5 = 0;
  486.     weapon_6 = 0;
  487.     weapon_7 = 0;
  488.     weapon_number = 0;
  489. }
  490. //////////////////////////////////////////////////////////////////////
  491. ACTION gun_fire {
  492. // anymore ammo?
  493.     IF (MY._AMMOTYPE == 1) {
  494.         IF (ammo1 > 0) { ammo1 -= 1; }
  495.         ELSE { GOTO no_ammo; }
  496.     }
  497.     IF (MY._AMMOTYPE == 2) {
  498.         IF (ammo2 > 0) { ammo2 -= 1; }
  499.         ELSE { GOTO no_ammo; }
  500.     }
  501.     IF (MY._AMMOTYPE == 3) {
  502.         IF (ammo3 > 0) { ammo3 -= 1; }
  503.         ELSE { GOTO no_ammo; }
  504.     }
  505.     IF (MY._AMMOTYPE == 4) {
  506.         IF (ammo4 > 0) { ammo4 -= 1; }
  507.         ELSE { GOTO no_ammo; }
  508.     }
  509.  
  510.    gun_loaded = 0;
  511. // place muzzle flash
  512.     IF ((person_3rd != 0) && (player != NULL)) {
  513.         MY_POS.X = player.MAX_X - player.MIN_X;
  514.         MY_POS.Y = 0;
  515.         MY_POS.Z = 0;
  516.     } ELSE {
  517.         MY_POS.X = MY.SKILL1 + MY._OFFS_FLASH;
  518.         MY_POS.Y = -MY.SKILL2;
  519.         MY_POS.Z = -MY.SKILL3;
  520.     }
  521.     CALL _set_pos_ahead_xyz;
  522.     gun_muzzle.X = MY_POS.X;
  523.     gun_muzzle.Y = MY_POS.Y;
  524.     gun_muzzle.Z = MY_POS.Z;
  525.     CREATE muzzle_flash,gun_muzzle,_flashup;
  526.  
  527.     MY_POS.X = MY._BULLETSPEED;
  528.     IF ((person_3rd != 0) && (player != NULL)) {
  529.         MY_POS.Y = 0;
  530.         MY_POS.Z = 0;
  531.     } ELSE {
  532.         MY_POS.Y = -MY.SKILL2;
  533.         MY_POS.Z = -MY.SKILL3;
  534.     }
  535.     CALL _set_pos_ahead_xyz;
  536.     gun_target.X = MY_POS.X;
  537.     gun_target.Y = MY_POS.Y;
  538.     gun_target.Z = MY_POS.Z;
  539.  
  540. // emit a bullet or particle
  541.     shot_speed.X = (gun_target.X - gun_muzzle.X);
  542.     shot_speed.Y = (gun_target.Y - gun_muzzle.Y);
  543.     shot_speed.Z = (gun_target.Z - gun_muzzle.Z);
  544.  
  545.     damage = MY._DAMAGE;
  546.     fire_mode = MY._FIREMODE;
  547.     CALL gun_shot;
  548.  
  549.     MY._FIRE = MY._FIRETIME;
  550.     MY._DISPLACEMENT = MY._RECOIL;
  551.     WHILE (MY._FIRE > 0) {
  552.         WAIT 1;
  553.  // rock back into place from recoil
  554.         MY._DISPLACEMENT *= 0.6;
  555.         MY._FIRE -= TIME;
  556.     }
  557.     MY._DISPLACEMENT = 0 ;
  558.     MY._FIRE = 0 ;
  559.  
  560.     IF (MY.__REPEAT == ON) { gun_loaded = 1;}
  561.     RETURN;
  562.  
  563. no_ammo:
  564.     PLAY_ENTSOUND ME,gun_click,50;
  565. }
  566.  
  567. // needs gun_muzzle,shot_speed,damage,fire_mode
  568. ACTION gun_shot {
  569.     IF ((fire_mode & MODE_FIRE) == FIRE_PARTICLE) {
  570.         EMIT 1,gun_muzzle,particle_shot; }
  571.     IF ((fire_mode & MODE_FIRE) == FIRE_BALL) {
  572.         CREATE fireball,gun_muzzle,bullet_shot; }
  573.  
  574. // see what's hit
  575.     IF ((fire_mode & MODE_DAMAGE) == DAMAGE_SHOOT) {
  576.         gun_target.X = 2*shot_speed.X + gun_muzzle.X;
  577.         gun_target.Y = 2*shot_speed.Y + gun_muzzle.Y;
  578.         gun_target.Z = 2*shot_speed.Z + gun_muzzle.Z;
  579.         indicator = _GUNFIRE;    // indicator for the entity that was hit
  580.         SHOOT gun_muzzle,gun_target;
  581.        if (RESULT > 0) { // hit something?
  582.             IF ((fire_mode & MODE_HIT) == HIT_FLASH) {
  583.                 CREATE small_flash,TARGET,_blowup; }
  584.         }
  585.     }
  586. }
  587.  
  588. ///////////////////////////////////////////////////////////////////////
  589. // hit flash
  590. ACTION _blowup
  591. {
  592.     MY.SCALE_X = 2;
  593.     MY.SCALE_Y = 2;
  594.     SET MY.PASSABLE,ON;
  595.     SET MY.FACING,ON;
  596.     SET MY.NEAR,ON;
  597.     SET MY.FLARE,ON;
  598.     MY.AMBIENT = 100;
  599.     MY.LIGHTRED = light_flash.RED;
  600.     MY.LIGHTGREEN = light_flash.GREEN;
  601.     MY.LIGHTBLUE = light_flash.BLUE;
  602.     MY.LIGHTRANGE = 64;
  603.     WAIT 1;
  604.     PLAY_ENTSOUND ME,hit_wham,300;
  605.     REMOVE ME;
  606. }
  607.  
  608. // muzzle flash
  609. ACTION _flashup
  610. {
  611.     MY.SCALE_X = 2;
  612.     MY.SCALE_Y = 2;
  613.     SET MY.PASSABLE,ON;
  614. // Set flare only in D3D mode
  615.     IF (VIDEO_MODE > 8) { SET MY.FLARE,ON; }
  616.     ELSE { SET MY.TRANSPARENT,ON; }
  617.  
  618.     SET MY.FACING,ON;
  619.     MY.AMBIENT = 100;
  620.     MY.LIGHTRED = light_muzzle.RED;
  621.     MY.LIGHTGREEN = light_muzzle.GREEN;
  622.     MY.LIGHTBLUE = light_muzzle.BLUE;
  623.     MY.LIGHTRANGE = 100;
  624.     WAIT 1;
  625.     PLAY_SOUND gun_wham,50;
  626.     REMOVE ME;
  627. }
  628.  
  629. // runs a bullet; requires shot_speed, damage, fire_mode to be set
  630. ACTION bullet_shot
  631. {
  632.     SET MY.ENABLE_BLOCK,ON;
  633.     SET MY.ENABLE_ENTITY,ON;
  634.     SET MY.ENABLE_STUCK,ON;
  635.     SET MY.ENABLE_IMPACT,ON;
  636.     SET MY.ENABLE_PUSH,ON;
  637.     SET MY.EVENT,_fireball_event;
  638.  
  639.     SET MY.FACING,ON;    // in case of fireball
  640.  
  641.     MY.LIGHTRED = light_bullet.RED;
  642.     MY.LIGHTGREEN = light_bullet.GREEN;
  643.     MY.LIGHTBLUE = light_bullet.BLUE;
  644.     MY.LIGHTRANGE = 100;
  645.     MY.AMBIENT = 100;
  646.  
  647.     MY.SKILL2 = shot_speed.x;
  648.     MY.SKILL3 = shot_speed.y;
  649.     MY.SKILL4 = shot_speed.z;
  650.     MY._DAMAGE = damage;
  651.     MY._FIREMODE = fire_mode;
  652.  
  653.       WHILE (MY.NEAR != ON) {    // my.near is set by the explosion
  654.         WAIT 1; // wait at the loop beginning, to let it appear at the start position
  655.  
  656.         temp = TIME;
  657.         IF (temp > 1.5) { temp = 1.5; }    // make bullet slower on slow PCs
  658. // MOVE moves by a distance, so multiply the speed by time.
  659.         fireball_speed.x = MY.SKILL2 * temp;
  660.         fireball_speed.y = MY.SKILL3 * temp;
  661.         fireball_speed.z = MY.SKILL4 * temp;
  662.  
  663.         IF ((MY._FIREMODE & BULLET_SMOKETRAIL) == BULLET_SMOKETRAIL) {
  664.             temp = 3 * TIME;
  665.             IF (temp > 6) { temp = 6; }    // generate max 6 particels
  666.             EMIT temp,MY.POS,particle_fade;     // smoke trail
  667.         }
  668.  
  669.          MOVE ME,nullskill,fireball_speed;
  670.     }
  671. }
  672.  
  673. ACTION actor_explode
  674. {
  675.     SET MY.FACING,ON;    // face the camera
  676.     SET MY.NEAR,ON;
  677.     SET MY.FLARE,ON;
  678.     SET MY.PASSABLE,ON;    // don't push the player through walls
  679.     MY.FRAME = 1;
  680.     WAIT    1;
  681.     PLAY_ENTSOUND ME,explo_wham,1000;
  682.     MY.LIGHTRED = light_explo.RED;
  683.     MY.LIGHTGREEN = light_explo.GREEN;
  684.     MY.LIGHTBLUE = light_explo.BLUE;
  685.     MY.AMBIENT = 100;
  686.     MY.LIGHTRANGE += 50;
  687. // use the new sprite animation
  688.     WHILE (MY.FRAME < MY._DIEFRAMES) {
  689.         WAIT 1;
  690.         MY.LIGHTRANGE += 15;
  691.         MY.LIGHTRED += 20 * TIME;    // fade to red
  692.         MY.LIGHTBLUE -= 20 * TIME;
  693.         MY.FRAME += TIME;
  694.     }
  695.     WAIT 1;
  696.     REMOVE ME;
  697. }
  698.  
  699. ACTION _fireball_event
  700. {
  701. // check for all collision events
  702.     IF (EVENT_TYPE == EVENT_BLOCK
  703.         || EVENT_TYPE == EVENT_ENTITY
  704.         || EVENT_TYPE == EVENT_STUCK
  705.         || EVENT_TYPE == EVENT_IMPACT
  706.         || EVENT_TYPE == EVENT_PUSH)
  707.     {
  708.         EXCLUSIVE_ENTITY;    // terminate other actions, to stop moving
  709.         SET MY.EVENT,NULL;
  710.  
  711.         range = MY._DAMAGE * 3;
  712.         damage = MY._DAMAGE;
  713.         temp.PAN = 360;
  714.         temp.TILT = 180;
  715.         temp.Z = range;
  716.         indicator = _EXPLODE;    // must always be set before scanning
  717.         SCAN    MY.POS,MY_ANGLE,temp;
  718.  
  719.         MORPH BULLET_EXPLO,ME;
  720.         MY._DIEFRAMES = EXPLO_FRAMES;
  721.         CALL actor_explode;
  722.     }
  723. }
  724.  
  725. /////////////////////////////////////////////////////////////
  726. // Calculate a 3d position relative to the camera angles
  727. // Input:  MY_POS
  728. // Output: MY_POS
  729. ACTION _set_pos_ahead_xyz {
  730.     VECROTATE MY_POS,CAMERA.PAN;
  731.     IF (person_3rd != 0) {
  732.         MY_POS.X += player.X;
  733.         MY_POS.Y += player.Y;
  734.         MY_POS.Z += player.Z;
  735.     } ELSE {
  736.         MY_POS.X += CAMERA.X;
  737.         MY_POS.Y += CAMERA.Y;
  738.         MY_POS.Z += CAMERA.Z;
  739.     }
  740. }
  741.  
  742. /////////////////////////////////////////////////////////////
  743. ON_CTRL weapon_fire;
  744. ON_MOUSE_LEFT weapon_fire;