]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Move weapon spawning into its own file
authorSamual Lenks <samual@xonotic.org>
Mon, 1 Jul 2013 08:37:36 +0000 (04:37 -0400)
committerSamual Lenks <samual@xonotic.org>
Mon, 1 Jul 2013 08:37:36 +0000 (04:37 -0400)
qcsrc/server/weapons/cl_weapons.qc
qcsrc/server/weapons/spawning.qc [new file with mode: 0644]

index 1091853af5887b959af62f5c97536050479bc296..abb8f3af179c576238c14c355cafcd6ee45fb6af 100644 (file)
@@ -163,157 +163,3 @@ void W_WeaponFrame()
                self.currentammo = 1;
 #endif
 }
-
-string W_Apply_Weaponreplace(string in)
-{
-       float n = tokenize_console(in);
-       string out = "";
-       float i;
-       for(i = 0; i < n; ++i)
-       {
-               string s = argv(i);
-               string r = cvar_string(strcat("g_weaponreplace_", s));
-               if(r == "")
-                       out = strcat(out, " ", s);
-               else if(r != "0")
-                       out = strcat(out, " ", r);
-       }
-       return substring(out, 1, -1);
-}
-
-void weapon_defaultspawnfunc(float wpn)
-{
-       entity e;
-       float t;
-       var .float ammofield;
-       string s;
-       entity oldself;
-       float i, j;
-       float f;
-
-       if(self.classname != "droppedweapon" && self.classname != "replacedweapon")
-       {
-               e = get_weaponinfo(wpn);
-
-               if(e.spawnflags & WEP_FLAG_MUTATORBLOCKED)
-               {
-                       objerror("Attempted to spawn a mutator-blocked weapon rejected");
-                       startitem_failed = TRUE;
-                       return;
-               }
-
-               s = W_Apply_Weaponreplace(e.netname);
-               ret_string = s;
-               other = e;
-               MUTATOR_CALLHOOK(SetWeaponreplace);
-               s = ret_string;
-               if(s == "")
-               {
-                       remove(self);
-                       startitem_failed = TRUE;
-                       return;
-               }
-               t = tokenize_console(s);
-               if(t >= 2)
-               {
-                       self.team = --internalteam;
-                       oldself = self;
-                       for(i = 1; i < t; ++i)
-                       {
-                               s = argv(i);
-                               for(j = WEP_FIRST; j <= WEP_LAST; ++j)
-                               {
-                                       e = get_weaponinfo(j);
-                                       if(e.netname == s)
-                                       {
-                                               self = spawn();
-                                               copyentity(oldself, self);
-                                               self.classname = "replacedweapon";
-                                               weapon_defaultspawnfunc(j);
-                                               break;
-                                       }
-                               }
-                               if(j > WEP_LAST)
-                               {
-                                       print("The weapon replace list for ", oldself.classname, " contains an unknown weapon ", s, ". Skipped.\n");
-                               }
-                       }
-                       self = oldself;
-               }
-               if(t >= 1) // always the case!
-               {
-                       s = argv(0);
-                       wpn = 0;
-                       for(j = WEP_FIRST; j <= WEP_LAST; ++j)
-                       {
-                               e = get_weaponinfo(j);
-                               if(e.netname == s)
-                               {
-                                       wpn = j;
-                                       break;
-                               }
-                       }
-                       if(j > WEP_LAST)
-                       {
-                               print("The weapon replace list for ", self.classname, " contains an unknown weapon ", s, ". Skipped.\n");
-                       }
-               }
-               if(wpn == 0)
-               {
-                       remove(self);
-                       startitem_failed = TRUE;
-                       return;
-               }
-       }
-
-       e = get_weaponinfo(wpn);
-
-       if(!self.respawntime)
-       {
-               if(WEPSET_CONTAINS_ANY_EA(e, WEPBIT_SUPERWEAPONS))
-               {
-                       self.respawntime = g_pickup_respawntime_superweapon;
-                       self.respawntimejitter = g_pickup_respawntimejitter_superweapon;
-               }
-               else
-               {
-                       self.respawntime = g_pickup_respawntime_weapon;
-                       self.respawntimejitter = g_pickup_respawntimejitter_weapon;
-               }
-       }
-
-       if(WEPSET_CONTAINS_ANY_EA(e, WEPBIT_SUPERWEAPONS))
-               if(!self.superweapons_finished)
-                       self.superweapons_finished = autocvar_g_balance_superweapons_time;
-
-       if(e.items)
-       {
-               for(i = 0, j = 1; i < 24; ++i, j *= 2)
-               {
-                       if(e.items & j)
-                       {
-                               ammofield = Item_CounterField(j);
-                               if(!self.ammofield)
-                                       self.ammofield = cvar(strcat("g_pickup_", Item_CounterFieldName(j), "_weapon"));
-                       }
-               }
-       }
-
-       // pickup anyway
-       if(g_pickup_weapons_anyway)
-               self.pickup_anyway = TRUE;
-
-       f = FL_WEAPON;
-
-       // no weapon-stay on superweapons
-       if(WEPSET_CONTAINS_ANY_EA(e, WEPBIT_SUPERWEAPONS))
-               f |= FL_NO_WEAPON_STAY;
-
-       // weapon stay isn't supported for teamed weapons
-       if(self.team)
-               f |= FL_NO_WEAPON_STAY;
-
-       StartItem(e.model, "weapons/weaponpickup.wav", self.respawntime, self.respawntimejitter, e.message, 0, e.weapon, f, weapon_pickupevalfunc, e.bot_pickupbasevalue);
-       if (self.modelindex) // don't precache if self was removed
-               WEP_ACTION(e.weapon, WR_INIT);
-}
diff --git a/qcsrc/server/weapons/spawning.qc b/qcsrc/server/weapons/spawning.qc
new file mode 100644 (file)
index 0000000..1091853
--- /dev/null
@@ -0,0 +1,319 @@
+float forbidWeaponUse()
+{
+       if(time < game_starttime && !autocvar_sv_ready_restart_after_countdown)
+               return 1;
+       if(round_handler_IsActive() && !round_handler_IsRoundStarted())
+               return 1;
+       if(self.player_blocked)
+               return 1;
+       if(self.freezetag_frozen)
+               return 1;
+       return 0;
+}
+
+void W_WeaponFrame()
+{
+       vector fo, ri, up;
+
+       if (frametime)
+               self.weapon_frametime = frametime;
+
+       if (!self.weaponentity || self.health < 1)
+               return; // Dead player can't use weapons and injure impulse commands
+
+       if(forbidWeaponUse())
+       if(self.weaponentity.state != WS_CLEAR)
+       {
+               w_ready();
+               return;
+       }
+
+       if(!self.switchweapon)
+       {
+               self.weapon = 0;
+               self.switchingweapon = 0;
+               self.weaponentity.state = WS_CLEAR;
+               self.weaponname = "";
+               self.items &~= IT_AMMO;
+               return;
+       }
+
+       makevectors(self.v_angle);
+       fo = v_forward; // save them in case the weapon think functions change it
+       ri = v_right;
+       up = v_up;
+
+       // Change weapon
+       if (self.weapon != self.switchweapon)
+       {
+               if (self.weaponentity.state == WS_CLEAR)
+               {
+                       // end switching!
+                       self.switchingweapon = self.switchweapon;
+                       entity newwep = get_weaponinfo(self.switchweapon);
+
+                       self.items &~= IT_AMMO;
+                       self.items = self.items | (newwep.items & IT_AMMO);
+
+                       // the two weapon entities will notice this has changed and update their models
+                       self.weapon = self.switchweapon;
+                       self.weaponname = newwep.mdl;
+                       self.bulletcounter = 0; // WEAPONTODO
+                       WEP_ACTION(self.switchweapon, WR_SETUP);
+                       self.weaponentity.state = WS_RAISE;
+
+                       // set our clip load to the load of the weapon we switched to, if it's reloadable
+                       if(newwep.spawnflags & WEP_FLAG_RELOADABLE && cvar(strcat("g_balance_", newwep.netname, "_reload_ammo"))) // prevent accessing undefined cvars
+                       {
+                               self.clip_load = self.(weapon_load[self.switchweapon]);
+                               self.clip_size = cvar(strcat("g_balance_", newwep.netname, "_reload_ammo"));
+                       }
+                       else
+                               self.clip_load = self.clip_size = 0;
+
+                       // VorteX: add player model weapon select frame here
+                       // setcustomframe(PlayerWeaponRaise);
+                       weapon_thinkf(WFRAME_IDLE, newwep.switchdelay_raise, w_ready);
+                       //print(sprintf("W_WeaponFrame(): cvar: %s, value: %f\n", sprintf("g_balance_%s_switchdelay_raise", newwep.netname), cvar(sprintf("g_balance_%s_switchdelay_raise", newwep.netname))));
+                       weapon_boblayer1(PLAYER_WEAPONSELECTION_SPEED, '0 0 0');
+               }
+               else if (self.weaponentity.state == WS_DROP)
+               {
+                       // in dropping phase we can switch at any time
+                       self.switchingweapon = self.switchweapon;
+               }
+               else if (self.weaponentity.state == WS_READY)
+               {
+                       // start switching!
+                       self.switchingweapon = self.switchweapon;
+
+                       entity oldwep = get_weaponinfo(self.weapon);
+                       
+#ifndef INDEPENDENT_ATTACK_FINISHED
+                       if(ATTACK_FINISHED(self) <= time + self.weapon_frametime * 0.5)
+                       {
+#endif
+                       sound (self, CH_WEAPON_SINGLE, "weapons/weapon_switch.wav", VOL_BASE, ATTN_NORM);
+                       self.weaponentity.state = WS_DROP;
+                       // set up weapon switch think in the future, and start drop anim
+                       weapon_thinkf(WFRAME_DONTCHANGE, oldwep.switchdelay_drop, w_clear);
+                       //print(sprintf("W_WeaponFrame(): cvar: %s, value: %f\n", sprintf("g_balance_%s_switchdelay_drop", oldwep.netname), cvar(sprintf("g_balance_%s_switchdelay_drop", oldwep.netname))));
+                       weapon_boblayer1(PLAYER_WEAPONSELECTION_SPEED, PLAYER_WEAPONSELECTION_RANGE);
+#ifndef INDEPENDENT_ATTACK_FINISHED
+                       }
+#endif
+               }
+       }
+
+       // LordHavoc: network timing test code
+       //if (self.button0)
+       //      print(ftos(frametime), " ", ftos(time), " >= ", ftos(ATTACK_FINISHED(self)), " >= ", ftos(self.weapon_nextthink), "\n");
+
+       float w;
+       w = self.weapon;
+
+       // call the think code which may fire the weapon
+       // and do so multiple times to resolve framerate dependency issues if the
+       // server framerate is very low and the weapon fire rate very high
+       float c;
+       c = 0;
+       while (c < W_TICSPERFRAME)
+       {
+               c = c + 1;
+               if(w && !WEPSET_CONTAINS_EW(self, w))
+               {
+                       if(self.weapon == self.switchweapon)
+                               W_SwitchWeapon_Force(self, w_getbestweapon(self));
+                       w = 0;
+               }
+
+               v_forward = fo;
+               v_right = ri;
+               v_up = up;
+
+               if(w)
+                       WEP_ACTION(self.weapon, WR_THINK);
+               else
+                       WEP_ACTION(self.weapon, WR_GONETHINK);
+
+               if (time + self.weapon_frametime * 0.5 >= self.weapon_nextthink)
+               {
+                       if(self.weapon_think)
+                       {
+                               v_forward = fo;
+                               v_right = ri;
+                               v_up = up;
+                               self.weapon_think();
+                       }
+                       else
+                               bprint("\{1}^1ERROR: undefined weapon think function for ", self.netname, "\n");
+               }
+       }
+
+#if 0
+       if (self.items & IT_CELLS)
+               self.currentammo = self.ammo_cells;
+       else if (self.items & IT_ROCKETS)
+               self.currentammo = self.ammo_rockets;
+       else if (self.items & IT_NAILS)
+               self.currentammo = self.ammo_nails;
+       else if (self.items & IT_SHELLS)
+               self.currentammo = self.ammo_shells;
+       else
+               self.currentammo = 1;
+#endif
+}
+
+string W_Apply_Weaponreplace(string in)
+{
+       float n = tokenize_console(in);
+       string out = "";
+       float i;
+       for(i = 0; i < n; ++i)
+       {
+               string s = argv(i);
+               string r = cvar_string(strcat("g_weaponreplace_", s));
+               if(r == "")
+                       out = strcat(out, " ", s);
+               else if(r != "0")
+                       out = strcat(out, " ", r);
+       }
+       return substring(out, 1, -1);
+}
+
+void weapon_defaultspawnfunc(float wpn)
+{
+       entity e;
+       float t;
+       var .float ammofield;
+       string s;
+       entity oldself;
+       float i, j;
+       float f;
+
+       if(self.classname != "droppedweapon" && self.classname != "replacedweapon")
+       {
+               e = get_weaponinfo(wpn);
+
+               if(e.spawnflags & WEP_FLAG_MUTATORBLOCKED)
+               {
+                       objerror("Attempted to spawn a mutator-blocked weapon rejected");
+                       startitem_failed = TRUE;
+                       return;
+               }
+
+               s = W_Apply_Weaponreplace(e.netname);
+               ret_string = s;
+               other = e;
+               MUTATOR_CALLHOOK(SetWeaponreplace);
+               s = ret_string;
+               if(s == "")
+               {
+                       remove(self);
+                       startitem_failed = TRUE;
+                       return;
+               }
+               t = tokenize_console(s);
+               if(t >= 2)
+               {
+                       self.team = --internalteam;
+                       oldself = self;
+                       for(i = 1; i < t; ++i)
+                       {
+                               s = argv(i);
+                               for(j = WEP_FIRST; j <= WEP_LAST; ++j)
+                               {
+                                       e = get_weaponinfo(j);
+                                       if(e.netname == s)
+                                       {
+                                               self = spawn();
+                                               copyentity(oldself, self);
+                                               self.classname = "replacedweapon";
+                                               weapon_defaultspawnfunc(j);
+                                               break;
+                                       }
+                               }
+                               if(j > WEP_LAST)
+                               {
+                                       print("The weapon replace list for ", oldself.classname, " contains an unknown weapon ", s, ". Skipped.\n");
+                               }
+                       }
+                       self = oldself;
+               }
+               if(t >= 1) // always the case!
+               {
+                       s = argv(0);
+                       wpn = 0;
+                       for(j = WEP_FIRST; j <= WEP_LAST; ++j)
+                       {
+                               e = get_weaponinfo(j);
+                               if(e.netname == s)
+                               {
+                                       wpn = j;
+                                       break;
+                               }
+                       }
+                       if(j > WEP_LAST)
+                       {
+                               print("The weapon replace list for ", self.classname, " contains an unknown weapon ", s, ". Skipped.\n");
+                       }
+               }
+               if(wpn == 0)
+               {
+                       remove(self);
+                       startitem_failed = TRUE;
+                       return;
+               }
+       }
+
+       e = get_weaponinfo(wpn);
+
+       if(!self.respawntime)
+       {
+               if(WEPSET_CONTAINS_ANY_EA(e, WEPBIT_SUPERWEAPONS))
+               {
+                       self.respawntime = g_pickup_respawntime_superweapon;
+                       self.respawntimejitter = g_pickup_respawntimejitter_superweapon;
+               }
+               else
+               {
+                       self.respawntime = g_pickup_respawntime_weapon;
+                       self.respawntimejitter = g_pickup_respawntimejitter_weapon;
+               }
+       }
+
+       if(WEPSET_CONTAINS_ANY_EA(e, WEPBIT_SUPERWEAPONS))
+               if(!self.superweapons_finished)
+                       self.superweapons_finished = autocvar_g_balance_superweapons_time;
+
+       if(e.items)
+       {
+               for(i = 0, j = 1; i < 24; ++i, j *= 2)
+               {
+                       if(e.items & j)
+                       {
+                               ammofield = Item_CounterField(j);
+                               if(!self.ammofield)
+                                       self.ammofield = cvar(strcat("g_pickup_", Item_CounterFieldName(j), "_weapon"));
+                       }
+               }
+       }
+
+       // pickup anyway
+       if(g_pickup_weapons_anyway)
+               self.pickup_anyway = TRUE;
+
+       f = FL_WEAPON;
+
+       // no weapon-stay on superweapons
+       if(WEPSET_CONTAINS_ANY_EA(e, WEPBIT_SUPERWEAPONS))
+               f |= FL_NO_WEAPON_STAY;
+
+       // weapon stay isn't supported for teamed weapons
+       if(self.team)
+               f |= FL_NO_WEAPON_STAY;
+
+       StartItem(e.model, "weapons/weaponpickup.wav", self.respawntime, self.respawntimejitter, e.message, 0, e.weapon, f, weapon_pickupevalfunc, e.bot_pickupbasevalue);
+       if (self.modelindex) // don't precache if self was removed
+               WEP_ACTION(e.weapon, WR_INIT);
+}