test_sv_game:
stage: test
script:
- - export EXPECT=4e959184d76f77e368ab5bf445c63cc9
+ - export EXPECT=ee6d65824c57cb6d83cba31481a21822
- qcsrc/tools/sv_game-hashtest.sh
- exit $?
set g_balance_electro_combo_comboradius 300
set g_balance_electro_combo_comboradius_thruwall 200
set g_balance_electro_combo_damage 50
+set g_balance_electro_combo_duration 1.5
set g_balance_electro_combo_edgedamage 25
set g_balance_electro_combo_force 120
set g_balance_electro_combo_radius 150
set g_balance_electro_combo_comboradius 0
set g_balance_electro_combo_comboradius_thruwall 0
set g_balance_electro_combo_damage 80
+set g_balance_electro_combo_duration 0
set g_balance_electro_combo_edgedamage 0
set g_balance_electro_combo_force 200
set g_balance_electro_combo_radius 250
set g_balance_electro_combo_comboradius 300
set g_balance_electro_combo_comboradius_thruwall 200
set g_balance_electro_combo_damage 50
+set g_balance_electro_combo_duration 0
set g_balance_electro_combo_edgedamage 25
set g_balance_electro_combo_force 120
set g_balance_electro_combo_radius 150
set g_balance_electro_combo_comboradius 275
set g_balance_electro_combo_comboradius_thruwall 200
set g_balance_electro_combo_damage 50
+set g_balance_electro_combo_duration 0
set g_balance_electro_combo_edgedamage 25
set g_balance_electro_combo_force 120
set g_balance_electro_combo_radius 175
set g_balance_electro_combo_comboradius 300
set g_balance_electro_combo_comboradius_thruwall 200
set g_balance_electro_combo_damage 50
+set g_balance_electro_combo_duration 0
set g_balance_electro_combo_edgedamage 25
set g_balance_electro_combo_force 120
set g_balance_electro_combo_radius 150
effect electro_combo
type static
airfriction 6
- alpha 156 156 156
+ alpha 156 156 100
bounce 2
color 0x2030FF 0x80C0FF
count 5
velocityjitter 512 512 512
effect electro_combo
type spark
- alpha 444 512 700
+ alpha 444 512 500
bounce 1.600000
color 0xa9cacf 0x0054ff
count 32
- gravity 0.300000
originjitter 1 1 1
size 2 4
stretchfactor 2
tex 41 41
- velocityjitter 312 312 312
- velocitymultiplier 3
+ velocityjitter 128 128 128
+ velocitymultiplier 0.300000
+ rotate -180 180 4000 -4000
effect electro_combo
type smoke
alpha 256 256 256
velocityjitter 32 32 32
effect electro_combo
type smoke
- alpha 40 40 100
+ alpha 64 64 40
color 0xa9cacf 0x0054ff
countabsolute 1
- sizeincrease 600
- size 30 30
+ size 120 120
tex 33 33
velocitymultiplier 0.300000
effect crylink_muzzleflash
SUB(electro_combo) {
MY(alpha_min) = 444;
MY(alpha_max) = 512;
- MY(alpha_fade) = 700;
+ MY(alpha_fade) = 500;
MY(bounce) = 1.600000;
MY(color_min) = "0xa9cacf";
MY(color_max) = "0x0054ff";
MY(count) = 32;
- MY(gravity) = 0.300000;
MY(originjitter) = '1.0 1.0 1.0';
MY(size_min) = 2;
MY(size_max) = 4;
MY(tex_min) = 41;
MY(tex_max) = 41;
MY(type) = "spark";
- MY(velocityjitter) = '312.0 312.0 312.0';
- MY(velocitymultiplier) = 3;
+ MY(velocityjitter) = '128.0 128.0 128.0';
+ MY(velocitymultiplier) = 0.300000;
}
// inner cloud of smoke
SUB(electro_combo) {
}
// shockwave
SUB(electro_combo) {
- MY(alpha_min) = 40;
- MY(alpha_max) = 40;
- MY(alpha_fade) = 100;
+ MY(alpha_min) = 64;
+ MY(alpha_max) = 64;
+ MY(alpha_fade) = 40;
MY(color_min) = "0xa9cacf";
MY(color_max) = "0x0054ff";
MY(countabsolute) = 1;
- MY(sizeincrease) = 600;
- MY(size_min) = 30;
- MY(size_max) = 30;
+ MY(size_min) = 120;
+ MY(size_max) = 120;
MY(tex_min) = 33;
MY(tex_max) = 33;
MY(type) = "smoke";
#include "electro.qh"
+#ifdef GAMEQC
+
+#ifdef CSQC
+
+.float ltime;
+void electro_orb_draw(entity this)
+{
+ float dt = time - this.move_time;
+ this.move_time = time;
+ if(dt <= 0)
+ return;
+
+ float myscale = bound(0, (this.ltime - time) * 4, 1);
+ this.scale = (WEP_CVAR(WEP_ELECTRO, combo_radius) * 0.05) * myscale;
+ this.angles = this.angles + dt * this.avelocity;
+}
+
+void electro_orb_setup(entity e)
+{
+ setmodel(e, MDL_PROJECTILE_ELECTRO);
+ setsize(e, '-4 -4 -4', '4 4 4');
+
+ setorigin(e, e.origin);
+
+ e.draw = electro_orb_draw;
+ IL_PUSH(g_drawables, e);
+ SetResourceExplicit(e, RES_HEALTH, 255);
+ set_movetype(e, MOVETYPE_NONE);
+ e.solid = SOLID_NOT;
+ e.avelocity = '7 0 11';
+ e.drawmask = MASK_NORMAL;
+ e.alpha = 0.7;
+}
+#endif
+
+REGISTER_NET_LINKED(Electro_Orb)
+
+#ifdef CSQC
+NET_HANDLE(Electro_Orb, bool isNew)
+{
+ Net_Accept(Electro_Orb);
+ int sf = ReadByte();
+ if (sf & 1) {
+ this.origin = ReadVector();
+ setorigin(this, this.origin);
+ this.ltime = time + ReadByte()/10.0;
+ // this.ltime = time + this.orb_lifetime;
+ electro_orb_setup(this);
+ }
+ return true;
+}
+#endif
+
+#ifdef SVQC
+bool electro_orb_send(entity this, entity to, int sf)
+{
+ int channel = MSG_ENTITY;
+ WriteHeader(channel, Electro_Orb);
+ WriteByte(channel, sf);
+ if (sf & 1) {
+ WriteVector(channel, this.origin);
+
+ // round time delta to a 1/10th of a second
+ WriteByte(channel, (this.ltime - time)*10.0+0.5);
+ }
+ return true;
+}
+#endif
+
+#endif
+
#ifdef SVQC
#include <common/effects/qc/_mod.qh>
}
}
+void W_Electro_ExplodeComboThink(entity this)
+{
+ if(time >= this.ltime)
+ {
+ delete(this);
+ return;
+ }
+
+ this.nextthink = time;
+
+ float damage = WEP_CVAR(WEP_ELECTRO, combo_damage) * PHYS_INPUT_TIMELENGTH;
+ float edgedamage = WEP_CVAR(WEP_ELECTRO, combo_edgedamage) * PHYS_INPUT_TIMELENGTH;
+
+ RadiusDamage(this, this.realowner, damage, edgedamage, WEP_CVAR(WEP_ELECTRO, combo_radius), NULL, NULL, 0, this.projectiledeathtype, this.weaponentity_fld, NULL);
+ this.projectiledeathtype |= HITTYPE_SPAM; // ensure it doesn't spam its effect
+}
+
+void W_Electro_Orb_ExplodeOverTime(entity this)
+{
+ entity newproj = spawn();
+ newproj.classname = this.classname;
+ newproj.solid = this.solid;
+ setorigin(newproj, this.origin);
+ setmodel(newproj, MDL_PROJECTILE_ELECTRO);
+ setsize(newproj, this.mins, this.maxs);
+ newproj.owner = this.owner;
+ newproj.realowner = this.realowner;
+ newproj.weaponentity_fld = this.weaponentity_fld;
+ newproj.projectiledeathtype = WEP_ELECTRO.m_id | HITTYPE_BOUNCE; // use THIS type for a combo because primary can't bounce
+
+ setthink(newproj, W_Electro_ExplodeComboThink);
+ newproj.nextthink = time;
+ newproj.ltime = time + WEP_CVAR(WEP_ELECTRO, combo_duration);
+ set_movetype(newproj, MOVETYPE_NONE);
+
+ Net_LinkEntity(newproj, true, 0, electro_orb_send);
+ newproj.SendFlags |= 1;
+
+ // fire the first damage tick immediately
+ getthink(newproj)(newproj);
+}
+
void W_Electro_ExplodeCombo(entity this)
{
W_Electro_TriggerCombo(this.origin, WEP_CVAR(WEP_ELECTRO, combo_comboradius), this.realowner);
if (!this.velocity)
this.velocity = this.movedir; // .velocity must be != '0 0 0' for particle fx and decal to work
+ if(WEP_CVAR(WEP_ELECTRO, combo_duration))
+ {
+ W_Electro_Orb_ExplodeOverTime(this);
+
+ delete(this);
+ return;
+ }
+
RadiusDamage(
this,
this.realowner,
/* spawnfunc */ ATTRIB(Electro, m_canonical_spawnfunc, string, "weapon_electro");
/* ammotype */ ATTRIB(Electro, ammo_type, Resource, RES_CELLS);
/* impulse */ ATTRIB(Electro, impulse, int, 5);
-/* flags */ ATTRIB(Electro, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH);
+/* flags */ ATTRIB(Electro, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH);
/* rating */ ATTRIB(Electro, bot_pickupbasevalue, float, 5000);
/* color */ ATTRIB(Electro, wpcolor, vector, '0 0.5 1');
/* modelname */ ATTRIB(Electro, mdl, string, "electro");
P(class, prefix, combo_comboradius, float, NONE) \
P(class, prefix, combo_comboradius_thruwall, float, NONE) \
P(class, prefix, combo_damage, float, NONE) \
+ P(class, prefix, combo_duration, float, NONE) \
P(class, prefix, combo_edgedamage, float, NONE) \
P(class, prefix, combo_force, float, NONE) \
P(class, prefix, combo_radius, float, NONE) \
alias test_ctf_stalemate90 "settemp g_ctf_stalemate_time 90"
alias test_ctf_stalemate120 "settemp g_ctf_stalemate_time 120"
-alias _testing_list "$1 test_blaster_switch ; $1 test_crylink_sec_horizontal ; $1 test_rocket_flying ; $1 test_ctf_stalemate90 ; $1 test_ctf_stalemate120 ; $1 test_arc_bounce ; $1 test_arc_bounce_burst"
+// https://gitlab.com/xonotic/xonotic-data.pk3dir/-/merge_requests/1067
+alias test_electro_combo_over_time "settemp g_balance_electro_combo_duration 1.5"
+
+alias _testing_list "$1 test_blaster_switch ; $1 test_crylink_sec_horizontal ; $1 test_rocket_flying ; $1 test_ctf_stalemate90 ; $1 test_ctf_stalemate120 ; $1 test_arc_bounce ; $1 test_arc_bounce_burst ; $1 test_electro_combo_over_time"
// defer addvote and delvote execution because program commands can't be executed if testing_disable
// and testing_enable are executed at startup (no program is loaded yet)