No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

396 líneas
10KB

  1. /* ---------------------------------------------------------------------------|
  2. *
  3. * Distributed under the CC0 public domain license.
  4. * By Alison G. Watson. Attribution is encouraged, though not required.
  5. * See licenses/cc0.txt for more information.
  6. *
  7. * ---------------------------------------------------------------------------|
  8. *
  9. * Weapon information handling.
  10. *
  11. * ---------------------------------------------------------------------------|
  12. */
  13. #include "p_player.h"
  14. #include "w_monster.h"
  15. #include "w_world.h"
  16. #include "p_hudid.h"
  17. /* Static Functions -------------------------------------------------------- */
  18. static void GiveWeaponItem(i32 parm, i32 slot)
  19. {
  20. switch(parm) {
  21. case weapon_c_fist:
  22. case weapon_fist: ServCallI(sm_DieMonster); break;
  23. case weapon_c_spas: InvGive(so_ShellAmmo, 8); break;
  24. case weapon_ssg: InvGive(so_ShellAmmo, 4); break;
  25. case weapon_c_sniper: InvGive(so_RocketAmmo, 6); break;
  26. case weapon_launcher: InvGive(so_RocketAmmo, 2); break;
  27. case weapon_c_plasma:
  28. case weapon_plasma: InvGive(so_PlasmaAmmo, 1500); break;
  29. case weapon_c_shipgun: InvGive(so_CannonAmmo, 5); break;
  30. case weapon_bfg: InvGive(so_CannonAmmo, 4); break;
  31. }
  32. }
  33. static void WeaponGrab(struct player *p, struct weaponinfo const *info)
  34. {
  35. if(!get_bit(p->upgrades[UPGR_7777777].flags, _ug_active))
  36. ACS_LocalAmbientSound(info->pickupsound, 127);
  37. else
  38. ACS_LocalAmbientSound(ss_marathon_pickup, 127);
  39. switch(info->slot) {
  40. default: FadeFlash(255, 255, 255, 0.5, 0.4); break;
  41. case 3: FadeFlash(0, 255, 0, 0.5, 0.5); break;
  42. case 4: FadeFlash(255, 255, 0, 0.5, 0.5); break;
  43. case 5: FadeFlash(255, 64, 0, 0.5, 0.6); break;
  44. case 6: FadeFlash(0, 0, 255, 0.5, 0.6); break;
  45. case 7: FadeFlash(255, 0, 0, 0.5, 0.7); break;
  46. }
  47. }
  48. static void PickupScore(struct player *p, i32 parm)
  49. {
  50. extern void P_Log_SellWeapon(struct player *p, struct weaponinfo const *info, i96 score);
  51. struct weaponinfo const *info = &weaponinfo[parm];
  52. i96 score = 4000 * info->slot;
  53. GiveWeaponItem(parm, info->slot);
  54. score = P_Scr_Give(p, score);
  55. P_Log_SellWeapon(p, info, score);
  56. }
  57. /* Extern Functions -------------------------------------------------------- */
  58. void Wep_GInit(void)
  59. {
  60. for(i32 i = 0; i < weapon_max; i++)
  61. {
  62. struct weaponinfo *info = (struct weaponinfo *)&weaponinfo[i];
  63. info->type = i;
  64. }
  65. }
  66. /* Update information on what weapons we have. */
  67. script
  68. void P_Wep_PTickPre(struct player *p)
  69. {
  70. struct weapondata *w = &p->weapon;
  71. w->prev = w->cur;
  72. /* Reset data temporarily. */
  73. w->cur = nil;
  74. for(i32 i = 0; i < SLOT_MAX; i++) w->slot[i] = 0;
  75. /* Iterate over each weapon setting information on it. */
  76. for(i32 i = weapon_min; i < weapon_max; i++)
  77. {
  78. struct weaponinfo const *info = &weaponinfo[i];
  79. struct invweapon *wep = &w->inv[i];
  80. if(!(p->pclass & info->pclass) || !(wep->owned = InvNum(info->classname)))
  81. continue;
  82. w->slot[info->slot] += wep->owned;
  83. /* Check for currently held weapon. */
  84. if(!w->cur && p->weaponclass == info->classname)
  85. w->cur = wep;
  86. wep->info = info;
  87. wep->ammotype = info->defammotype;
  88. wep->ammoclass = info->defammoclass;
  89. /* Special exceptions. */
  90. switch(i) {
  91. case weapon_shotgun:
  92. if(get_bit(p->upgrades[UPGR_GaussShotty].flags, _ug_active))
  93. wep->ammotype = AT_NMag;
  94. break;
  95. case weapon_c_spas:
  96. if(get_bit(p->upgrades[UPGR_SPAS_B].flags, _ug_active))
  97. wep->ammotype = AT_Ammo;
  98. break;
  99. case weapon_plasma:
  100. if(get_bit(p->upgrades[UPGR_PartBeam].flags, _ug_active))
  101. wep->ammotype = AT_AMag;
  102. break;
  103. }
  104. switch(i)
  105. {
  106. /* For slot 3 weapons that don't take ammo, check if they should. */
  107. case weapon_shotgun:
  108. case weapon_c_rifle:
  109. if(p->getCVarI(sc_weapons_slot3ammo)) {
  110. wep->ammotype |= AT_Ammo;
  111. wep->ammoclass = so_ShellAmmo;
  112. }
  113. }
  114. /* Set magazine and ammo counts. */
  115. if(w->cur == wep)
  116. {
  117. if(wep->ammotype & AT_NMag)
  118. {
  119. wep->magmax = ServCallI(sm_GetMaxMag, p->num, wep->info->classname);
  120. wep->magcur = ServCallI(sm_GetCurMag, p->num, wep->info->classname);
  121. }
  122. if(wep->ammotype & AT_Ammo)
  123. {
  124. wep->ammomax = InvMax(wep->ammoclass);
  125. wep->ammocur = InvNum(wep->ammoclass);
  126. }
  127. }
  128. /* Auto-reload. */
  129. if(p->autoreload && wep->ammotype & AT_NMag && !get_bit(info->flags, wf_magic))
  130. {
  131. if(wep->autoreload >= 35 * 3)
  132. ServCallI(sm_AutoReload, p->num, info->classname);
  133. if(w->cur != wep) wep->autoreload++;
  134. else wep->autoreload = 0;
  135. }
  136. }
  137. if(!w->cur) w->cur = &w->inv[weapon_unknown];
  138. }
  139. script
  140. void P_Wep_PTick(struct player *p)
  141. {
  142. if(!Paused) {
  143. i32 heat = InvNum(so_SMGHeat);
  144. if(heat < 100) InvTake(so_SMGHeat, 5);
  145. else if(heat < 200) InvTake(so_SMGHeat, 4);
  146. else if(heat < 300) InvTake(so_SMGHeat, 3);
  147. else if(heat < 400) InvTake(so_SMGHeat, 2);
  148. else InvTake(so_SMGHeat, 1);
  149. }
  150. if(p->pclass == pcl_cybermage) {
  151. InvGive(so_Blade, 1);
  152. InvGive(so_Delear, 1);
  153. if(cbiupgr[cupg_c_slot3spell]) InvGive(so_Feuer, 1);
  154. if(cbiupgr[cupg_c_slot4spell]) InvGive(so_Rend, 1);
  155. if(cbiupgr[cupg_c_slot5spell]) InvGive(so_Hulgyon, 1);
  156. if(cbiupgr[cupg_c_slot6spell]) InvGive(so_StarShot, 1);
  157. if(cbiupgr[cupg_c_slot7spell]) InvGive(so_Cercle, 1);
  158. }
  159. SetSize(320, 240);
  160. switch(P_Wep_CurType(p))
  161. {
  162. case weapon_c_fist:
  163. Str(mana_charge, sLANG "MANA_CHARGE");
  164. PrintTextA_str(L(mana_charge), s_smallfnt, CR_BRICK, 160,0, 100,0, 0.5);
  165. break;
  166. case weapon_c_delear:
  167. ServCallI(sm_DelearSprite);
  168. break;
  169. case weapon_cfist:
  170. __with(k64 charge = 5 + InvNum(so_FistCharge) / 10.0lk;)
  171. {
  172. PrintTextFmt(LC(LANG "CHARGE_FMT"), charge);
  173. PrintText(s_smallfnt, CR_LIGHTBLUE, 270,2, 200,2);
  174. }
  175. break;
  176. }
  177. }
  178. /* Scripts ----------------------------------------------------------------- */
  179. script_str ext("ACS") addr(OBJ "WeaponPickup")
  180. bool Sc_WeaponPickup(i32 name)
  181. {
  182. extern void P_Log_Weapon(struct player *p, struct weaponinfo const *info);
  183. extern i32 P_Wep_FromName(struct player *p, i32 name);
  184. struct player *p = LocalPlayer;
  185. if(P_None(p)) return false;
  186. Str(sv_weaponstay, s"sv_weaponstay");
  187. bool weaponstay = ACS_GetCVar(sv_weaponstay);
  188. i32 parm = weapon_unknown;
  189. parm = P_Wep_FromName(p, name);
  190. if(parm >= weapon_max || parm < weapon_min)
  191. return true;
  192. struct weaponinfo const *info = &weaponinfo[parm];
  193. if(HasWeapon(p, parm))
  194. {
  195. if(!weaponstay) {
  196. WeaponGrab(p, info);
  197. PickupScore(p, parm);
  198. }
  199. return !weaponstay;
  200. }
  201. else
  202. {
  203. WeaponGrab(p, info);
  204. p->weaponsheld++;
  205. bip_name_t tag; lstrcpy_str(tag, info->name);
  206. P_BIP_Unlock(p, tag);
  207. GiveWeaponItem(parm, info->slot);
  208. P_Log_Weapon(p, info);
  209. InvGive(info->classname, 1);
  210. return !weaponstay;
  211. }
  212. }
  213. script_str ext("ACS") addr(OBJ "CircleSpread")
  214. k32 Sc_CircleSpread(k32 mdx, k32 mdy, bool getpitch)
  215. {
  216. noinit static k32 A;
  217. noinit static k32 P;
  218. if(!getpitch)
  219. {
  220. k32 dx = ACS_RandomFixed(mdx, 0.0);
  221. k32 dy = ACS_RandomFixed(mdy, 0.0);
  222. k32 a = ACS_RandomFixed(1.0, -1.0);
  223. A = ACS_Sin(a) * dx;
  224. P = ACS_Cos(a) * dy;
  225. return A;
  226. }
  227. else
  228. return P;
  229. }
  230. script_str ext("ACS") addr(OBJ "ChargeFistDamage")
  231. i32 Sc_ChargeFistDamage(void)
  232. {
  233. i32 amount = InvNum(so_FistCharge);
  234. InvTake(so_FistCharge, INT32_MAX);
  235. return amount * ACS_Random(1, 3);
  236. }
  237. script_str ext("ACS") addr(OBJ "AmmoRunOut")
  238. k32 Sc_AmmoRunOut(bool ro, k32 mul)
  239. {
  240. with_player(LocalPlayer)
  241. {
  242. struct invweapon const *wep = p->weapon.cur;
  243. k32 inv = wep->magcur / (k32)wep->magmax;
  244. mul = mul ? mul : 1.2;
  245. if(ro) inv = inv * mul;
  246. else inv = mul - inv * 0.4;
  247. if(inv < 0) inv = 0;
  248. else if(inv > 1) inv = 1;
  249. return inv;
  250. }
  251. return 0;
  252. }
  253. script_str ext("ACS") addr(OBJ "GetFinalizerMaxHealth")
  254. i32 Sc_GetFinalizerMaxHealth(void)
  255. {
  256. i32 sh = ServCallI(sm_GetSpawnHealth);
  257. ifauto(dmon_t *, m, DmonSelf())
  258. return sh + (m->maxhealth - sh) * 0.5;
  259. else
  260. return sh;
  261. }
  262. script_str ext("ACS") addr(OBJ "SurgeOfDestiny")
  263. void Sc_SurgeOfDestiny(void)
  264. {
  265. for(i32 i = 0; i < (35 * 17) / 2; i++) {
  266. ServCallI(sm_SurgeOfDestiny);
  267. ACS_Delay(2);
  268. }
  269. }
  270. script_str ext("ACS") addr(OBJ "GetWRF")
  271. i32 Sc_GetWRF(void)
  272. {
  273. enum
  274. {
  275. WRF_NOBOB = 1,
  276. WRF_NOSWITCH = 2,
  277. WRF_NOPRIMARY = 4,
  278. WRF_NOSECONDARY = 8,
  279. WRF_NOFIRE = WRF_NOPRIMARY | WRF_NOSECONDARY,
  280. WRF_ALLOWRELOAD = 16,
  281. WRF_ALLOWZOOM = 32,
  282. WRF_DISABLESWITCH = 64,
  283. WRF_ALLOWUSER1 = 128,
  284. WRF_ALLOWUSER2 = 256,
  285. WRF_ALLOWUSER3 = 512,
  286. WRF_ALLOWUSER4 = 1024
  287. };
  288. i32 flags = 0;
  289. with_player(LocalPlayer)
  290. {
  291. if(p->semifrozen)
  292. flags |= WRF_NOFIRE;
  293. if(p->pclass & (pcl_marine | pcl_darklord))
  294. flags |= WRF_ALLOWUSER4;
  295. }
  296. return flags;
  297. }
  298. script_str ext("ACS") addr(OBJ "PoisonFXTicker")
  299. void Sc_PoisonFXTicker(void)
  300. {
  301. for(i32 i = 0; i < 17; i++)
  302. {
  303. PausableTick();
  304. if(InvNum(so_PoisonFXReset))
  305. {
  306. InvTake(so_PoisonFXReset, INT32_MAX);
  307. InvTake(so_PoisonFXTimer, INT32_MAX);
  308. ServCallI(sm_GivePoison);
  309. return;
  310. }
  311. }
  312. if(GetMembI(0, sm_Health) <= 0)
  313. {
  314. InvTake(so_PoisonFXReset, INT32_MAX);
  315. InvTake(so_PoisonFXTimer, INT32_MAX);
  316. }
  317. else if(InvNum(so_PoisonFXTimer))
  318. {
  319. ServCallI(sm_PoisonFX);
  320. InvTake(so_PoisonFXTimer, 1);
  321. }
  322. }
  323. script_str ext("ACS") addr(OBJ "RecoilUp")
  324. void Sc_RecoilUp(k32 amount)
  325. {
  326. with_player(LocalPlayer) p->extrpitch += amount / 180.0lk;
  327. }
  328. /* EOF */