skroton

point pickup working version

May 26th, 2016
127
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #library "point"
  2. #include "zcommon.acs"
  3.  
  4. /* absolute value function because there's not a native abs() acs function */
  5. function int abs (int x)
  6. {
  7.   if (x < 0)
  8.     return -x;
  9.   return x;
  10. }
  11.  
  12. script "pointpickup" enter /* the actual pickup script */
  13. {
  14.  
  15. /* all the variables below are just getting declared right now, they don't have any values (well they do, but it's all 0) and don't do anything yet */  
  16.  
  17.   int actor_tid_old, actor_tid, target_check; /* tid of actor before script, tid to assign to actor being picked up, check for if player is pointing at something */
  18.  
  19.   int a_x, a_y, a_z; /* actor x, y, z coordinates */
  20.   int p_x, p_y, p_z; /* player x, y, z coordinates */
  21.  
  22.   int max_dist, max_xy_dist, max_z_dist; /* maximum total distance, maximum horizontal distance, and maximum vertical height to allow pickup */
  23.  
  24.   str class; /* class name of actor being picked up*/
  25.  
  26.   /* now the distance maximums have their value set, the rest will be set during script; these need to be set in fixed point to work correctly, so make sure the values you set them to use a decimal point */
  27.  
  28.   max_dist = 128.0;
  29.   max_xy_dist = 64.0;
  30.   max_z_dist = 64.0;
  31.  
  32.   /* note that you could set these distance maximums later, and base what they are upon what class the actor being picked up is */
  33.  
  34.   while(true) /* will continually loop */
  35.   {
  36.     if( (GetPlayerInput(0, INPUT_BUTTONS) & BT_USE) /* if one of the buttons the player is pressing this tic is the use button */
  37.     && /* AND */
  38.     !(GetPlayerInput(0, INPUT_OLDBUTTONS) & BT_USE) ) /* none of the buttons the player was pressing last tic were the use button, meaning they just started  pressing the use button this tic */
  39.     { /* then */
  40.  
  41.       actor_tid = UniqueTID(); /* get a unique tid to assign to actor */
  42.      
  43.       /* get old tid of actor by using PICKAF_RETURNTID, shouldn't be an issue for pickups but in case you want to use this for other actor
  44.       types like monsters; not using it to check if there is an actor under the crosshair because if there is but the actor doesn't have atid
  45.       this will return 0 */
  46.       actor_tid_old = PickActor(0, GetActorAngle(0), GetActorPitch(0), 30000.0, actor_tid, MF_SPECIAL, ML_BLOCKEVERYTHING, PICKAF_RETURNTID);
  47.  
  48.       /* pickactor to actor under player crosshair that is a pickup (MF_SPECIAL), change flag for different actor types, sets target_check to 1 if there is such an actor and 0 if not */
  49.       target_check = PickActor(0, GetActorAngle(0), GetActorPitch(0), 30000.0, actor_tid, MF_SPECIAL, ML_BLOCKEVERYTHING, 0);
  50.       if(target_check) /* if there is an acceptable actor under crosshair */
  51.       {
  52.        
  53.         /* now use pickactor with PICKAF_FORCETID to assign that tid to the actor */
  54.         PickActor(0, GetActorAngle(0), GetActorPitch(0), 30000.0, actor_tid, MF_SPECIAL, ML_BLOCKEVERYTHING, PICKAF_FORCETID);
  55.  
  56.         class = GetActorClass(actor_tid); /* get actor class name string for use later */
  57.  
  58.         a_x = GetActorX(actor_tid); /* get actor x position in fixed point */
  59.         a_y = GetActorY(actor_tid); /* get actor y position in fixed point */
  60.         a_z = GetActorZ(actor_tid); /* get actor z position in fixed point */
  61.  
  62.         p_x = GetActorX(0); /* get player x position in fixed point */
  63.         p_y = GetActorY(0); /* get player y position in fixed point */
  64.         p_z = GetActorZ(0); /* get player z position in fixed point */
  65.  
  66.         if( (VectorLength(VectorLength((a_x - p_x), (a_y - p_y)), (a_z - p_z)) <= max_dist) /* if total distance between player and actor is less than or equal to max_dist */
  67.         && /* AND */
  68.         (VectorLength((a_x - p_x), (a_y - p_y)) <= max_xy_dist) /* if horizontal distance between player and actor is less than or equal to max_xy_dist */
  69.         && /* AND */
  70.         (abs(a_z - p_z) <= max_z_dist) ) /* if vertical distance between player and actor is less than or equal to max_z_dist */
  71.         { /* then */
  72.  
  73.           print(s: "You take the ", s:class, s:"." ); /* print class name of actor for debugging; APROP_NAMETAG only works with checkactorproperty,
  74.           and can only be compared, not retrieved. If you want to have a name that's not the decorate class name, recommend 2D string array
  75.           with class name in first part of each set and what you want to print in second part of set, then have loop to compare class to
  76.           each first part of set in array until you get a match, then print corresponding string in second part of set */
  77.  
  78.           if(StrCmp(class, "string to compare")){  }/* this is what you would use to compare the actor class name to in order to make decisions based on that,
  79.           returns 0 if the strings being compared are the same; see: http://zdoom.org/wiki/StrCmp */
  80.  
  81.           GiveInventory(class, 1); /* give the actor to the player, you would probably want to have this be more
  82.           nuanced than this, but here for demonstration purposes */
  83.  
  84.           Thing_Remove(actor_tid); /* remove the actor from the map */
  85.  
  86.         }
  87.        
  88.         Thing_ChangeTID(actor_tid, actor_tid_old); /* this is to set the tid back to it's original tid if you checked what the actor was and then didn't pick it
  89.         up because it's too far away, could also use under other circumstances */
  90.        
  91.       }
  92.     }
  93.  
  94.   delay(1); /* delay for one tic before starting loop again */
  95.  
  96.   }
  97. }
  98.  
  99. /*
  100.  
  101. You'd need to start checking based upon what the calling actor has so use
  102. http://zdoom.org/wiki/CheckInventory
  103. compare that to
  104. http://zdoom.org/wiki/GetMaxInventory
  105. then based upon what that returns, give the player however much of the item, and if you want to drop leftover items use
  106. http://zdoom.org/wiki/DropItem
  107. from the inventory item before it's removed, probably in a loop to spawn however much of the default actor amount the remainder is divisible by, since if you set a single item to have different than normal amount the script if used on it again won't be able to differentiate the shell with 9 shells from a normal 4 shells.
  108. Probably the best way to keep track of how much goes into each item would be to either have a map level 2d string array that has classnames in first part and second is numbers, then use one of the string number parsers (like in commonFuncs.h) to convert to number, or to just write one yourself, or have two separate arrays that have the corresponding data in the same location in each array.
  109.  
  110. So either
  111.  
  112. str ammo[4][2] = {
  113.   { "Clip", "10" },
  114.   { "ClipBox", "50" },
  115.   { "Shell", "4" },
  116.   { "ShellBox", "20" },  };
  117.  
  118. or
  119.  
  120. str ammo_name[4] = { "Clip", "Clipbox", "Shell", "Shellbox" };
  121. str ammo_amt[4] = {10, 50, 4, 20 };
  122.  
  123. Keep in mind you'd also have to account for the skill's DropAmmoFactor, and there's no built in function to do this.
  124. If you're doing this for vanilla or your own mod or whatever then just checking skill with
  125. http://zdoom.org/wiki/GameSkill
  126. and then determining dropammofactor from there should be sufficient, if you're doing it for universal compatibility this gets more complicated.
  127.  
  128. Oh, forgot to mention, to group the actors that give a particular type of ammo, you'd want to use another 2d string array to do so, have all ammo types on one line with the different actors, and compare the actors to the actor names until you find a match, and then you know what the other actors of the same ammo type are, with the ammo type at a particular position in each set. Either have a corresponding int array for amounts, or have the actor names have the inventory amount on the end of the actor separated by some character so when you parse the string you can use that as an indication that what follows afterwards is not an actor name and is a number you need to convert, or add an additional dimension and have some empty/unused values in the array.
  129.  
  130. This might seem complicated but once you get it going it's far, far more manageable than having a million conditional statements to do the same thing. It can reduce something like 200 lines of code to 20.
  131. */
RAW Paste Data