]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/playertemplates.qc
Player templates: Removed obsolete item names.
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / playertemplates.qc
1 /// \file
2 /// \brief Source file that contains implementation of the player templates
3 /// system.
4 /// \author Lyberta
5 /// \copyright GNU GPLv3 or any later version.
6
7 #include <common/items/item.qh>
8 #include "autocvars.qh"
9 #include "resources.qh"
10 #include "mutators/events.qh"
11
12 const string playertemplate_cvar_prefix = "g_player_template_";
13
14 string PlayerTemplate_GetFullCvarName(string template, string variable)
15 {
16         return strcat(playertemplate_cvar_prefix, template, "_", variable);
17 }
18
19 string PlayerTemplate_GetDefaultCvarName(string variable)
20 {
21         switch (variable)
22         {
23                 case "start_health":
24                 {
25                         return "g_balance_health_start";
26                 }
27                 case "start_armor":
28                 {
29                         return "g_balance_armor_start";
30                 }
31                 case "start_ammo_shells":
32                 {
33                         return "g_start_ammo_shells";
34                 }
35                 case "start_ammo_bullets":
36                 {
37                         return "g_start_ammo_nails";
38                 }
39                 case "start_ammo_rockets":
40                 {
41                         return "g_start_ammo_rockets";
42                 }
43                 case "start_ammo_cells":
44                 {
45                         return "g_start_ammo_cells";
46                 }
47                 case "start_ammo_plasma":
48                 {
49                         return "g_start_ammo_plasma";
50                 }
51                 case "start_ammo_fuel":
52                 {
53                         return "g_start_ammo_fuel";
54                 }
55                 case "random_start_weapons_count":
56                 {
57                         return "g_random_start_weapons_count";
58                 }
59                 case "random_start_weapons":
60                 {
61                         return "g_random_start_weapons";
62                 }
63                 case "random_start_shells":
64                 {
65                         return "g_random_start_shells";
66                 }
67                 case "random_start_bullets":
68                 {
69                         return "g_random_start_bullets";
70                 }
71                 case "random_start_rockets":
72                 {
73                         return "g_random_start_rockets";
74                 }
75                 case "random_start_cells":
76                 {
77                         return "g_random_start_cells";
78                 }
79                 case "random_start_plasma":
80                 {
81                         return "g_random_start_plasma";
82                 }
83                 case "start_ammo_vaporizer_cells":
84                 {
85                         return "g_instagib_ammo_start";
86                 }
87                 case "drop_weapons":
88                 {
89                         return "g_weapon_throwable";
90                 }
91                 case "health_regen_factor":
92                 {
93                         return "g_balance_health_regen";
94                 }
95                 case "health_regen_linear":
96                 {
97                         return "g_balance_health_regenlinear";
98                 }
99                 case "health_rot_factor":
100                 {
101                         return "g_balance_health_rot";
102                 }
103                 case "health_rot_linear":
104                 {
105                         return "g_balance_health_rotlinear";
106                 }
107                 case "health_regen_stable":
108                 {
109                         return "g_balance_health_regenstable";
110                 }
111                 case "health_rot_stable":
112                 {
113                         return "g_balance_health_rotstable";
114                 }
115                 default:
116                 {
117                         // TODO: Report error.
118                         return "";
119                 }
120         }
121 }
122
123 float PlayerTemplate_GetDefaultFloatValue(string variable)
124 {
125         switch (variable)
126         {
127                 case "start_health":
128                 case "start_armor":
129                 case "start_ammo_shells":
130                 case "start_ammo_bullets":
131                 case "start_ammo_rockets":
132                 case "start_ammo_cells":
133                 case "start_ammo_plasma":
134                 case "start_ammo_fuel":
135                 case "random_start_weapons_count":
136                 case "random_start_shells":
137                 case "random_start_bullets":
138                 case "random_start_rockets":
139                 case "random_start_cells":
140                 case "random_start_plasma":
141                 case "start_ammo_vaporizer_cells":
142                 case "drop_weapons":
143                 case "health_regen_factor":
144                 case "health_regen_linear":
145                 case "health_rot_factor":
146                 case "health_rot_linear":
147                 case "health_regen_stable":
148                 case "health_rot_stable":
149                 {
150                         return cvar(PlayerTemplate_GetDefaultCvarName(variable));
151                 }
152                 case "unlimited_ammo":
153                 {
154                         return !autocvar_g_use_ammunition;
155                 }
156                 case "default_start_weapons":
157                 {
158                         return 1;
159                 }
160                 case "start_extra_lives":
161                 {
162                         return 0;
163                 }
164                 case "attack_scale":
165                 case "defense_scale":
166                 {
167                         return 1;
168                 }
169                 case "blaster_self_damage":
170                 {
171                         return 1;
172                 }
173                 default:
174                 {
175                         // TODO: Report error.
176                         return 0;
177                 }
178         }
179 }
180
181 string PlayerTemplate_GetDefaultStringValue(string variable)
182 {
183         switch (variable)
184         {
185                 case "random_start_weapons":
186                 {
187                         cvar_string(PlayerTemplate_GetDefaultCvarName(variable));
188                 }
189                 case "start_weapons":
190                 {
191                         return "";
192                 }
193                 default:
194                 {
195                         // TODO: Report error.
196                         return "";
197                 }
198         }
199 }
200
201 float PlayerTemplate_GetFloatValue(string template, string variable)
202 {
203         if (template == "default")
204         {
205                 return PlayerTemplate_GetDefaultFloatValue(variable);
206         }
207         string fullname = PlayerTemplate_GetFullCvarName(template, variable);
208         if (!(cvar_type(fullname) & CVAR_TYPEFLAG_EXISTS))
209         {
210                 return PlayerTemplate_GetDefaultFloatValue(variable);
211         }
212         if (cvar_string(fullname) == "default")
213         {
214                 return PlayerTemplate_GetDefaultFloatValue(variable);
215         }
216         return cvar(fullname);
217 }
218
219 string PlayerTemplate_GetStringValue(string template, string variable)
220 {
221         if (template == "default")
222         {
223                 return PlayerTemplate_GetDefaultStringValue(variable);
224         }
225         string fullname = PlayerTemplate_GetFullCvarName(template, variable);
226         if (!(cvar_type(fullname) & CVAR_TYPEFLAG_EXISTS))
227         {
228                 return PlayerTemplate_GetDefaultStringValue(variable);
229         }
230         if (cvar_string(fullname) == "default")
231         {
232                 return PlayerTemplate_GetDefaultStringValue(variable);
233         }
234         return cvar_string(fullname);
235 }
236
237 float PlayerTemplate_GivePlayerItem(entity player, string template,
238         string variable)
239 {
240         string value = PlayerTemplate_GetStringValue(template, variable);
241         if (value == "default")
242         {
243                 return MUT_ITEMTOUCH_CONTINUE;
244         }
245         int numfields = tokenize_console(PlayerTemplate_GetStringValue(template,
246                 variable));
247         if (numfields == 0)
248         {
249                 return MUT_ITEMTOUCH_CONTINUE;
250         }
251         for (int i = 1; i < numfields; ++i)
252         {
253                 switch (i)
254                 {
255                         case 1:
256                         {
257                                 GiveResource(player, RESOURCE_HEALTH, stof(argv(i)));
258                                 break;
259                         }
260                         case 2:
261                         {
262                                 GiveResource(player, RESOURCE_ARMOR, stof(argv(i)));
263                                 break;
264                         }
265                         case 3:
266                         {
267                                 GiveResource(player, RESOURCE_SHELLS, stof(argv(i)));
268                                 break;
269                         }
270                         case 4:
271                         {
272                                 GiveResource(player, RESOURCE_BULLETS, stof(argv(i)));
273                                 break;
274                         }
275                         case 5:
276                         {
277                                 GiveResource(player, RESOURCE_ROCKETS, stof(argv(i)));
278                                 break;
279                         }
280                         case 6:
281                         {
282                                 GiveResource(player, RESOURCE_CELLS, stof(argv(i)));
283                                 break;
284                         }
285                         case 7:
286                         {
287                                 GiveResource(player, RESOURCE_PLASMA, stof(argv(i)));
288                                 break;
289                         }
290                         case 8:
291                         {
292                                 GiveResource(player, RESOURCE_FUEL, stof(argv(i)));
293                                 break;
294                         }
295                 }
296         }
297         switch (argv(0))
298         {
299                 case "add":
300                 {
301                         return MUT_ITEMTOUCH_CONTINUE;
302                 }
303                 case "override":
304                 {
305                         return MUT_ITEMTOUCH_PICKUP;
306                 }
307                 default:
308                 {
309                         return MUT_ITEMTOUCH_CONTINUE;
310                 }
311         }
312 }
313
314 // =========================== Hook handlers =================================
315
316 void PlayerTemplateHook_PlayerSpawn(entity player, string template)
317 {
318         if (template == "default")
319         {
320                 return;
321         }
322         if (autocvar_g_instagib)
323         {
324                 SetResourceAmount(player, RESOURCE_ARMOR,
325                         PlayerTemplate_GetFloatValue(template, "start_extra_lives"));
326                 SetResourceAmount(player, RESOURCE_CELLS,
327                         PlayerTemplate_GetFloatValue(template,
328                         "start_ammo_vaporizer_cells"));
329                 if (PlayerTemplate_GetFloatValue(template, "unlimited_ammo"))
330                 {
331                         player.items |= IT_UNLIMITED_AMMO;
332                 }
333                 return;
334         }
335         // Give health, armor and ammo.
336         SetResourceAmount(player, RESOURCE_HEALTH,
337                 PlayerTemplate_GetFloatValue(template, "start_health"));
338         SetResourceAmount(player, RESOURCE_ARMOR, 
339                 PlayerTemplate_GetFloatValue(template, "start_armor"));
340         if (PlayerTemplate_GetFloatValue(template, "unlimited_ammo"))
341         {
342                 player.items |= IT_UNLIMITED_AMMO;
343         }
344         else
345         {
346                 SetResourceAmount(player, RESOURCE_SHELLS,
347                         PlayerTemplate_GetFloatValue(template, "start_ammo_shells"));
348                 SetResourceAmount(player, RESOURCE_BULLETS,
349                         PlayerTemplate_GetFloatValue(template, "start_ammo_bullets"));
350                 SetResourceAmount(player, RESOURCE_ROCKETS,
351                         PlayerTemplate_GetFloatValue(template, "start_ammo_rockets"));
352                 SetResourceAmount(player, RESOURCE_CELLS,
353                         PlayerTemplate_GetFloatValue(template, "start_ammo_cells"));
354                 SetResourceAmount(player, RESOURCE_PLASMA,
355                         PlayerTemplate_GetFloatValue(template, "start_ammo_plasma"));
356                 SetResourceAmount(player, RESOURCE_FUEL,
357                         PlayerTemplate_GetFloatValue(template, "start_ammo_fuel"));
358         }
359         // Give weapons.
360         if (PlayerTemplate_GetFloatValue(template, "default_start_weapons"))
361         {
362                 FOREACH(Weapons, it != WEP_Null,
363                 {
364                         if (it.weaponstart)
365                         {
366                                 player.weapons |= it.m_wepset;
367                         }
368                 });
369         }
370         int numweapons = tokenize_console(PlayerTemplate_GetStringValue(template,
371                 "start_weapons"));
372         for (int i = 0; i < numweapons; ++i)
373         {
374                 string weapon = argv(i);
375                 FOREACH(Weapons, it != WEP_Null,
376                 {
377                         if (it.netname == weapon)
378                         {
379                                 player.weapons |= it.m_wepset;
380                                 break;
381                         }
382                 });
383         }
384         if (!warmup_stage)
385         {
386                 entity ammo_entity = spawn();
387                 SetResourceAmount(ammo_entity, RESOURCE_SHELLS,
388                         PlayerTemplate_GetFloatValue(template, "random_start_shells"));
389                 SetResourceAmount(ammo_entity, RESOURCE_BULLETS,
390                         PlayerTemplate_GetFloatValue(template, "random_start_bullets"));
391                 SetResourceAmount(ammo_entity, RESOURCE_ROCKETS,
392                         PlayerTemplate_GetFloatValue(template, "random_start_rockets"));
393                 SetResourceAmount(ammo_entity, RESOURCE_CELLS,
394                         PlayerTemplate_GetFloatValue(template, "random_start_cells"));
395                 SetResourceAmount(ammo_entity, RESOURCE_PLASMA,
396                         PlayerTemplate_GetFloatValue(template, "random_start_plasma"));
397                 GiveRandomWeapons(player, PlayerTemplate_GetFloatValue(template,
398                         "random_start_weapons_count"),
399                         PlayerTemplate_GetStringValue(template, "random_start_weapons"),
400                         ammo_entity);
401                 remove(ammo_entity);
402                 return;
403         }
404         // Give random weapons.
405         numweapons = tokenize_console(PlayerTemplate_GetStringValue(template,
406                 "random_start_weapons"));
407         // Give all weapons during warmup stage.
408         for (int i = 0; i < numweapons; ++i)
409         {
410                 string weapon = argv(i);
411                 FOREACH(Weapons, it != WEP_Null,
412                 {
413                         if (it.netname == weapon)
414                         {
415                                 player.weapons |= it.m_wepset;
416                                 break;
417                         }
418                 });
419         }
420 }
421
422 bool PlayerTemplateHook_ForbidThrowCurrentWeapon(string template)
423 {
424         return !PlayerTemplate_GetFloatValue(template, "drop_weapons");
425 }
426
427 float PlayerTemplateHook_PlayerRegen(entity player, string template)
428 {
429         if (template == "default")
430         {
431                 return false;
432         }
433         M_ARGV(5, float) = PlayerTemplate_GetFloatValue(template,
434                 "health_regen_factor");
435         M_ARGV(6, float) = PlayerTemplate_GetFloatValue(template,
436                 "health_regen_linear");
437         M_ARGV(7, float) = PlayerTemplate_GetFloatValue(template,
438                 "health_rot_factor");
439         M_ARGV(8, float) = PlayerTemplate_GetFloatValue(template,
440                 "health_rot_linear");
441         M_ARGV(9, float) = PlayerTemplate_GetFloatValue(template,
442                 "health_regen_stable");
443         M_ARGV(10, float) = PlayerTemplate_GetFloatValue(template,
444                 "health_rot_stable");
445         return false;
446 }
447
448 float PlayerTemplateHook_ItemTouch(entity player, entity item, string template)
449 {
450         if (template == "default")
451         {
452                 return MUT_ITEMTOUCH_CONTINUE;
453         }
454         switch (item.classname)
455         {
456                 case "item_health_small":
457                 {
458                         return PlayerTemplate_GivePlayerItem(player, template,
459                                 "pickup_health_small");
460                 }
461                 case "item_health_medium":
462                 {
463                         return PlayerTemplate_GivePlayerItem(player, template,
464                                 "pickup_health_medium");
465                 }
466                 case "item_health_big":
467                 {
468                         return PlayerTemplate_GivePlayerItem(player, template,
469                                 "pickup_health_big");
470                 }
471                 case "item_health_mega":
472                 {
473                         return PlayerTemplate_GivePlayerItem(player, template,
474                                 "pickup_health_mega");
475                 }
476                 case "item_armor_small":
477                 {
478                         return PlayerTemplate_GivePlayerItem(player, template,
479                                 "pickup_armor_small");
480                 }
481                 case "item_armor_medium":
482                 {
483                         return PlayerTemplate_GivePlayerItem(player, template,
484                                 "pickup_armor_medium");
485                 }
486                 case "item_armor_big":
487                 {
488                         return PlayerTemplate_GivePlayerItem(player, template,
489                                 "pickup_armor_big");
490                 }
491                 case "item_armor_mega":
492                 {
493                         return PlayerTemplate_GivePlayerItem(player, template,
494                                 "pickup_armor_mega");
495                 }
496                 case "item_shells":
497                 {
498                         return PlayerTemplate_GivePlayerItem(player, template,
499                                 "pickup_item_shells");
500                 }
501                 case "item_bullets":
502                 {
503                         return PlayerTemplate_GivePlayerItem(player, template,
504                                 "pickup_item_bullets");
505                 }
506                 case "item_rockets":
507                 {
508                         return PlayerTemplate_GivePlayerItem(player, template,
509                                 "pickup_item_rockets");
510                 }
511                 case "item_cells":
512                 {
513                         return PlayerTemplate_GivePlayerItem(player, template,
514                                 "pickup_item_cells");
515                 }
516                 case "item_plasma":
517                 {
518                         return PlayerTemplate_GivePlayerItem(player, template,
519                                 "pickup_item_plasma");
520                 }
521                 case "item_fuel":
522                 {
523                         return PlayerTemplate_GivePlayerItem(player, template,
524                                 "pickup_item_fuel");
525                 }
526                 case "weapon_blaster":
527                 {
528                         return PlayerTemplate_GivePlayerItem(player, template,
529                                 "pickup_weapon_blaster");
530                 }
531                 case "weapon_shotgun":
532                 {
533                         return PlayerTemplate_GivePlayerItem(player, template,
534                                 "pickup_weapon_shotgun");
535                 }
536                 case "weapon_machinegun":
537                 {
538                         return PlayerTemplate_GivePlayerItem(player, template,
539                                 "pickup_weapon_machinegun");
540                 }
541                 case "weapon_mortar":
542                 {
543                         return PlayerTemplate_GivePlayerItem(player, template,
544                                 "pickup_weapon_mortar");
545                 }
546                 case "weapon_electro":
547                 {
548                         return PlayerTemplate_GivePlayerItem(player, template,
549                                 "pickup_weapon_electro");
550                 }
551                 case "weapon_crylink":
552                 {
553                         return PlayerTemplate_GivePlayerItem(player, template,
554                                 "pickup_weapon_crylink");
555                 }
556                 case "weapon_vortex":
557                 {
558                         return PlayerTemplate_GivePlayerItem(player, template,
559                                 "pickup_weapon_vortex");
560                 }
561                 case "weapon_hagar":
562                 {
563                         return PlayerTemplate_GivePlayerItem(player, template,
564                                 "pickup_weapon_hagar");
565                 }
566                 case "weapon_devastator":
567                 {
568                         return PlayerTemplate_GivePlayerItem(player, template,
569                                 "pickup_weapon_devastator");
570                 }
571                 case "weapon_shockwave":
572                 {
573                         return PlayerTemplate_GivePlayerItem(player, template,
574                                 "pickup_weapon_shockwave");
575                 }
576                 case "weapon_arc":
577                 {
578                         return PlayerTemplate_GivePlayerItem(player, template,
579                                 "pickup_weapon_arc");
580                 }
581                 case "weapon_hook":
582                 {
583                         return PlayerTemplate_GivePlayerItem(player, template,
584                                 "pickup_weapon_hook");
585                 }
586                 case "weapon_tuba":
587                 {
588                         return PlayerTemplate_GivePlayerItem(player, template,
589                                 "pickup_weapon_tuba");
590                 }
591                 case "weapon_porto":
592                 {
593                         return PlayerTemplate_GivePlayerItem(player, template,
594                                 "pickup_weapon_porto");
595                 }
596                 case "weapon_fireball":
597                 {
598                         return PlayerTemplate_GivePlayerItem(player, template,
599                                 "pickup_weapon_fireball");
600                 }
601                 case "weapon_minelayer":
602                 {
603                         return PlayerTemplate_GivePlayerItem(player, template,
604                                 "pickup_weapon_minelayer");
605                 }
606                 case "weapon_hlac":
607                 {
608                         return PlayerTemplate_GivePlayerItem(player, template,
609                                 "pickup_weapon_hlac");
610                 }
611                 case "weapon_rifle":
612                 {
613                         return PlayerTemplate_GivePlayerItem(player, template,
614                                 "pickup_weapon_rifle");
615                 }
616                 case "weapon_seeker":
617                 {
618                         return PlayerTemplate_GivePlayerItem(player, template,
619                                 "pickup_weapon_seeker");
620                 }
621                 case "weapon_vaporizer":
622                 {
623                         return PlayerTemplate_GivePlayerItem(player, template,
624                                 "pickup_weapon_vaporizer");
625                 }
626                 case "weapon_hmg":
627                 {
628                         return PlayerTemplate_GivePlayerItem(player, template,
629                                 "pickup_weapon_hmg");
630                 }
631                 case "weapon_rpc":
632                 {
633                         return PlayerTemplate_GivePlayerItem(player, template,
634                                 "pickup_weapon_rpc");
635                 }
636                 case "droppedweapon":
637                 {
638                         switch (item.weapon)
639                         {
640                                 case WEP_BLASTER.m_id:
641                                 {
642                                         return PlayerTemplate_GivePlayerItem(player, template,
643                                                 "pickup_weapon_shotgun");
644                                 }
645                                 case WEP_SHOTGUN.m_id:
646                                 {
647                                         return PlayerTemplate_GivePlayerItem(player, template,
648                                                 "pickup_weapon_shotgun");
649                                 }
650                                 case WEP_MACHINEGUN.m_id:
651                                 {
652                                         return PlayerTemplate_GivePlayerItem(player, template,
653                                                 "pickup_weapon_machinegun");
654                                 }
655                                 case WEP_MORTAR.m_id:
656                                 {
657                                         return PlayerTemplate_GivePlayerItem(player, template,
658                                                 "pickup_weapon_mortar");
659                                 }
660                                 case WEP_ELECTRO.m_id:
661                                 {
662                                         return PlayerTemplate_GivePlayerItem(player, template,
663                                                 "pickup_weapon_electro");
664                                 }
665                                 case WEP_CRYLINK.m_id:
666                                 {
667                                         return PlayerTemplate_GivePlayerItem(player, template,
668                                                 "pickup_weapon_crylink");
669                                 }
670                                 case WEP_VORTEX.m_id:
671                                 {
672                                         return PlayerTemplate_GivePlayerItem(player, template,
673                                                 "pickup_weapon_vortex");
674                                 }
675                                 case WEP_HAGAR.m_id:
676                                 {
677                                         return PlayerTemplate_GivePlayerItem(player, template,
678                                                 "pickup_weapon_hagar");
679                                 }
680                                 case WEP_DEVASTATOR.m_id:
681                                 {
682                                         return PlayerTemplate_GivePlayerItem(player, template,
683                                                 "pickup_weapon_devastator");
684                                 }
685                                 case WEP_SHOCKWAVE.m_id:
686                                 {
687                                         return PlayerTemplate_GivePlayerItem(player, template,
688                                                 "pickup_weapon_shockwave");
689                                 }
690                                 case WEP_ARC.m_id:
691                                 {
692                                         return PlayerTemplate_GivePlayerItem(player, template,
693                                                 "pickup_weapon_arc");
694                                 }
695                                 case WEP_HOOK.m_id:
696                                 {
697                                         return PlayerTemplate_GivePlayerItem(player, template,
698                                                 "pickup_weapon_hook");
699                                 }
700                                 case WEP_TUBA.m_id:
701                                 {
702                                         return PlayerTemplate_GivePlayerItem(player, template,
703                                                 "pickup_weapon_tuba");
704                                 }
705                                 case WEP_PORTO.m_id:
706                                 {
707                                         return PlayerTemplate_GivePlayerItem(player, template,
708                                                 "pickup_weapon_porto");
709                                 }
710                                 case WEP_FIREBALL.m_id:
711                                 {
712                                         return PlayerTemplate_GivePlayerItem(player, template,
713                                                 "pickup_weapon_fireball");
714                                 }
715                                 case WEP_MINE_LAYER.m_id:
716                                 {
717                                         return PlayerTemplate_GivePlayerItem(player, template,
718                                                 "pickup_weapon_minelayer");
719                                 }
720                                 case WEP_HLAC.m_id:
721                                 {
722                                         return PlayerTemplate_GivePlayerItem(player, template,
723                                                 "pickup_weapon_hlac");
724                                 }
725                                 case WEP_RIFLE.m_id:
726                                 {
727                                         return PlayerTemplate_GivePlayerItem(player, template,
728                                                 "pickup_weapon_rifle");
729                                 }
730                                 case WEP_SEEKER.m_id:
731                                 {
732                                         return PlayerTemplate_GivePlayerItem(player, template,
733                                                 "pickup_weapon_seeker");
734                                 }
735                                 case WEP_VAPORIZER.m_id:
736                                 {
737                                         return PlayerTemplate_GivePlayerItem(player, template,
738                                                 "pickup_weapon_vaporizer");
739                                 }
740                                 case WEP_HMG.m_id:
741                                 {
742                                         return PlayerTemplate_GivePlayerItem(player, template,
743                                                 "pickup_weapon_hmg");
744                                 }
745                                 case WEP_RPC.m_id:
746                                 {
747                                         return PlayerTemplate_GivePlayerItem(player, template,
748                                                 "pickup_weapon_rpc");
749                                 }
750                                 default:
751                                 {
752                                         PrintToChatAll(strcat("Unrecognized item, classname: ",
753                                                 item.classname, " netname: ", item.netname));
754                                         return MUT_ITEMTOUCH_CONTINUE;
755                                 }
756                         }
757                 }
758                 case "replacedweapon":
759                 {
760                         switch (item.weapon)
761                         {
762                                 case WEP_MINE_LAYER.m_id:
763                                 {
764                                         return PlayerTemplate_GivePlayerItem(player, template,
765                                                 "pickup_weapon_minelayer");
766                                 }
767                                 case WEP_HLAC.m_id:
768                                 {
769                                         return PlayerTemplate_GivePlayerItem(player, template,
770                                                 "pickup_weapon_hlac");
771                                 }
772                                 case WEP_RIFLE.m_id:
773                                 {
774                                         return PlayerTemplate_GivePlayerItem(player, template,
775                                                 "pickup_weapon_rifle");
776                                 }
777                                 case WEP_SEEKER.m_id:
778                                 {
779                                         return PlayerTemplate_GivePlayerItem(player, template,
780                                                 "pickup_weapon_seeker");
781                                 }
782                                 default:
783                                 {
784                                         PrintToChatAll(strcat("Unrecognized item, classname: ",
785                                                 item.classname, " netname: ", item.netname));
786                                         return MUT_ITEMTOUCH_CONTINUE;
787                                 }
788                         }
789                 }
790                 case "item_strength":
791                 {
792                         return PlayerTemplate_GivePlayerItem(player, template,
793                                 "pickup_item_strength");
794                 }
795                 case "item_invincible":
796                 {
797                         return PlayerTemplate_GivePlayerItem(player, template,
798                                 "pickup_item_shield");
799                 }
800                 case "item_fuel_regen":
801                 {
802                         return PlayerTemplate_GivePlayerItem(player, template,
803                                 "pickup_item_fuel_regen");
804                 }
805                 case "item_jetpack":
806                 {
807                         return PlayerTemplate_GivePlayerItem(player, template,
808                                 "pickup_item_jetpack");
809                 }
810                 case "item_vaporizer_cells":
811                 {
812                         return PlayerTemplate_GivePlayerItem(player, template,
813                                 "pickup_item_vaporizer_cells");
814                 }
815                 case "item_invisibility":
816                 {
817                         return PlayerTemplate_GivePlayerItem(player, template,
818                                 "pickup_item_invisibility");
819                 }
820                 case "item_extralife":
821                 {
822                         return PlayerTemplate_GivePlayerItem(player, template,
823                                 "pickup_item_extralife");
824                 }
825                 case "item_speed":
826                 {
827                         return PlayerTemplate_GivePlayerItem(player, template,
828                                 "pickup_item_speed");
829                 }
830                 default:
831                 {
832                         switch (item.netname)
833                         {
834                                 default:
835                                 {
836                                         PrintToChatAll(strcat("Unrecognized item, classname: ",
837                                                 item.classname, " netname: ", item.netname));
838                                         return MUT_ITEMTOUCH_CONTINUE;
839                                 }
840                         }
841                 }
842         }
843         return MUT_ITEMTOUCH_CONTINUE;
844 }
845
846 float PlayerTemplateHook_Damage_Calculate(entity attacker,
847         string attackertemplate, entity victim, string victimtemplate,
848         float deathtype, float damage)
849 {
850         if (autocvar_g_instagib == 1)
851         {
852                 return damage;
853         }
854         if ((attacker == victim) && (DEATH_ISWEAPON(deathtype, WEP_BLASTER)) &&
855                 (PlayerTemplate_GetFloatValue(victimtemplate, "blaster_self_damage") ==
856                 0))
857         {
858                 return 0;
859         }
860         damage *= PlayerTemplate_GetFloatValue(attackertemplate, "attack_scale");
861         damage /= PlayerTemplate_GetFloatValue(victimtemplate, "defense_scale");
862         return damage;
863 }
864
865 void PlayerTemplateHook_PlayerDies(entity player, string template)
866 {
867         if (template == "default")
868         {
869                 return;
870         }
871         if (PlayerTemplate_GetFloatValue(template, "drop_weapons"))
872         {
873                 return;
874         }
875         player.weapons = WEPSET(Null);
876 }