X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;ds=sidebyside;f=qcsrc%2Fcommon%2Fvehicles%2Fsv_vehicles.qc;h=be8d468fa78dca4048312bc69df8fc4c52fe6c6f;hb=913b5501b8eaa7793de54875d4992f23c211b6e0;hp=0c9ff29d913f9d7f306f98618d1f1cafbf4a8f4a;hpb=45e13bf47c14855400cbaa613e087c260dc49343;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/common/vehicles/sv_vehicles.qc b/qcsrc/common/vehicles/sv_vehicles.qc index 0c9ff29d9..be8d468fa 100644 --- a/qcsrc/common/vehicles/sv_vehicles.qc +++ b/qcsrc/common/vehicles/sv_vehicles.qc @@ -9,9 +9,7 @@ bool SendAuxiliaryXhair(entity this, entity to, int sf) if(sf & 2) { - WriteCoord(MSG_ENTITY, this.origin_x); - WriteCoord(MSG_ENTITY, this.origin_y); - WriteCoord(MSG_ENTITY, this.origin_z); + WriteVector(MSG_ENTITY, this.origin); } if(sf & 4) @@ -26,8 +24,8 @@ bool SendAuxiliaryXhair(entity this, entity to, int sf) bool AuxiliaryXhair_customize(entity this, entity client) { - //entity e = WaypointSprite_getviewentity(client); - entity axh = client.(AuxiliaryXhair[this.cnt]); + entity e = WaypointSprite_getviewentity(client); + entity axh = e.(AuxiliaryXhair[this.cnt]); return axh.owner == this.owner; // cheaply check if the client's axh owner is the same as our real owner } @@ -201,15 +199,15 @@ vector vehicles_force_fromtag_maglev(entity this, string tag_name, float spring_ } // projectile handling -void vehicles_projectile_damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force) +void vehicles_projectile_damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force) { // Ignore damage from oterh projectiles from my owner (dont mess up volly's) if(inflictor.owner == this.owner) return; - this.health -= damage; + TakeResource(this, RESOURCE_HEALTH, damage); this.velocity += force; - if(this.health < 1) + if(GetResourceAmount(this, RESOURCE_HEALTH) < 1) { this.takedamage = DAMAGE_NO; this.event_damage = func_null; @@ -232,9 +230,9 @@ void vehicles_projectile_explode(entity this, entity toucher) PROJECTILE_TOUCH(this, toucher); this.event_damage = func_null; - RadiusDamage (this, this.realowner, this.shot_dmg, 0, this.shot_radius, this, NULL, this.shot_force, this.totalfrags, toucher); + RadiusDamage (this, this.realowner, this.shot_dmg, 0, this.shot_radius, this, NULL, this.shot_force, this.totalfrags, DMG_NOWEP, toucher); - delete (this); + delete(this); } void vehicles_projectile_explode_think(entity this) @@ -253,7 +251,7 @@ entity vehicles_projectile(entity this, string _mzlfx, Sound _mzlsound, int _deahtype, float _projtype, float _health, bool _cull, bool _clianim, entity _owner) { - TC(Sound, _mzlsound); + TC(Sound, _mzlsound); entity proj; proj = spawn(); @@ -284,7 +282,7 @@ entity vehicles_projectile(entity this, string _mzlfx, Sound _mzlsound, { proj.takedamage = DAMAGE_AIM; proj.event_damage = vehicles_projectile_damage; - proj.health = _health; + SetResourceAmountExplicit(proj, RESOURCE_HEALTH, _health); } else proj.flags |= FL_NOTARGET; @@ -369,7 +367,7 @@ bool vehicle_addplayerslot( entity _owner, _slot.PlayerPhysplug = _framefunc; _slot.vehicle_exit = _exitfunc; _slot.vehicle_enter = _enterfunc; - _slot.hud = _hud; + STAT(HUD, _slot) = _hud; _slot.vehicle_flags = VHF_PLAYERSLOT; _slot.vehicle_viewport = spawn(); _slot.vehicle_hudmodel = spawn(); @@ -387,7 +385,7 @@ bool vehicle_addplayerslot( entity _owner, vector vehicle_aimturret(entity _vehic, vector _target, entity _turrret, string _tagname, float _pichlimit_min, float _pichlimit_max, - float _rotlimit_min, float _rotlimit_max, float _aimspeed) + float _rotlimit_min, float _rotlimit_max, float _aimspeed, float dt) { vector vtmp, vtag; float ftmp; @@ -395,7 +393,7 @@ vector vehicle_aimturret(entity _vehic, vector _target, entity _turrret, string vtmp = vectoangles(normalize(_target - vtag)); vtmp = AnglesTransform_ToAngles(AnglesTransform_LeftDivide(AnglesTransform_FromAngles(_vehic.angles), AnglesTransform_FromAngles(vtmp))) - _turrret.angles; vtmp = AnglesTransform_Normalize(vtmp, true); - ftmp = _aimspeed * frametime; + ftmp = _aimspeed * dt; vtmp_y = bound(-ftmp, vtmp_y, ftmp); vtmp_x = bound(-ftmp, vtmp_x, ftmp); _turrret.angles_y = bound(_rotlimit_min, _turrret.angles_y + vtmp_y, _rotlimit_max); @@ -403,12 +401,14 @@ vector vehicle_aimturret(entity _vehic, vector _target, entity _turrret, string return vtag; } -void vehicles_reset_colors(entity this) +void vehicles_reset_colors(entity this, entity player) { int eff = 0, cmap; const vector cmod = '0 0 0'; if(this.team && teamplay) cmap = 1024 + (this.team - 1) * 17; + else if(player) + cmap = player.colormap; else cmap = 1024; if(autocvar_g_nodepthtestplayers) @@ -419,25 +419,25 @@ void vehicles_reset_colors(entity this) // Find all ents attacked to main model and setup effects, colormod etc. FOREACH_ENTITY_ENT(tag_entity, this, { - if(it != this.vehicle_shieldent) - { - it.effects = eff; - it.colormod = cmod; - it.colormap = cmap; - it.alpha = 1; - } + if(it == this.vehicle_shieldent) + continue; + + it.effects = eff; + it.colormod = cmod; + it.colormap = cmap; + it.alpha = 1; }); // Also check head tags FOREACH_ENTITY_ENT(tag_entity, this.tur_head, { - if(it != this.vehicle_shieldent) - { - it.effects = eff; - it.colormod = cmod; - it.colormap = cmap; - it.alpha = 1; - } + if(it == this.vehicle_shieldent) + continue; + + it.effects = eff; + it.colormod = cmod; + it.colormap = cmap; + it.alpha = 1; }); this.vehicle_hudmodel.effects = this.effects = eff; // | EF_LOWPRECISION; @@ -449,6 +449,9 @@ void vehicles_reset_colors(entity this) this.avelocity = '0 0 0'; this.velocity = '0 0 0'; this.effects = eff; + + Vehicle info = Vehicles_from(this.vehicleid); + info.vr_setcolors(info, this); } void vehicles_clearreturn(entity veh) @@ -517,6 +520,7 @@ void vehicles_showwp(entity this) else rgb = '1 1 1'; entity wp = WaypointSprite_Spawn(WP_Vehicle, 0, 0, ent, '0 0 64', NULL, 0, ent, waypointsprite_attached, true, RADARICON_Vehicle); + wp.wp_extra = ent.wp00.vehicleid; wp.colormod = rgb; if(ent.waypointsprite_attached) { @@ -572,7 +576,7 @@ void vehicle_use(entity this, entity actor, entity trigger) else { vehicles_setreturn(this); - vehicles_reset_colors(this); + vehicles_reset_colors(this, actor); } } } @@ -583,7 +587,7 @@ void vehicles_regen(entity this, float timer, .float regen_field, float field_ma if(timer + rpause < time) { if(_healthscale) - regen = regen * (this.vehicle_health / this.max_health); + regen = regen * (GetResourceAmount(this, RESOURCE_HEALTH) / this.max_health); this.(regen_field) = min(this.(regen_field) + regen * delta_time, field_max); @@ -592,6 +596,23 @@ void vehicles_regen(entity this, float timer, .float regen_field, float field_ma } } +void vehicles_regen_resource(entity this, float timer, .float regen_field, float field_max, float rpause, float regen, float delta_time, float _healthscale, int resource) +{ + float resource_amount = GetResourceAmount(this, resource); + + if(resource_amount < field_max) + if(timer + rpause < time) + { + if(_healthscale) + regen = regen * (resource_amount / this.max_health); + + SetResourceAmount(this, resource, min(resource_amount + regen * delta_time, field_max)); + + if(this.owner) + this.owner.(regen_field) = (GetResourceAmount(this, resource) / field_max) * 100; + } +} + void shieldhit_think(entity this) { this.alpha -= 0.1; @@ -609,7 +630,7 @@ void shieldhit_think(entity this) void vehicles_painframe(entity this) { - int myhealth = ((this.owner) ? this.owner.vehicle_health : ((this.vehicle_health / this.max_health) * 100)); + int myhealth = ((this.owner) ? this.owner.vehicle_health : ((GetResourceAmount(this, RESOURCE_HEALTH) / this.max_health) * 100)); if(myhealth <= 50) if(this.pain_frame < time) @@ -634,7 +655,7 @@ void vehicles_frame(entity this, entity actor) vehicles_painframe(this); } -void vehicles_damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force) +void vehicles_damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force) { this.dmg_time = time; @@ -680,7 +701,7 @@ void vehicles_damage(entity this, entity inflictor, entity attacker, float damag if(this.vehicle_shield < 0) { - this.vehicle_health -= fabs(this.vehicle_shield); + TakeResource(this, RESOURCE_HEALTH, fabs(this.vehicle_shield)); this.vehicle_shieldent.colormod = '2 0 0'; this.vehicle_shield = 0; this.vehicle_shieldent.alpha = 0.75; @@ -695,7 +716,7 @@ void vehicles_damage(entity this, entity inflictor, entity attacker, float damag } else { - this.vehicle_health -= damage; + TakeResource(this, RESOURCE_HEALTH, damage); if(sound_allowed(MSG_BROADCAST, attacker)) spamsound (this, CH_PAIN, SND_ONS_HIT2, VOL_BASE, ATTEN_NORM); // FIXME: PLACEHOLDER @@ -706,7 +727,7 @@ void vehicles_damage(entity this, entity inflictor, entity attacker, float damag else this.velocity += force; - if(this.vehicle_health <= 0) + if(GetResourceAmount(this, RESOURCE_HEALTH) <= 0) { if(this.owner) if(this.vehicle_flags & VHF_DEATHEJECT) @@ -723,6 +744,18 @@ void vehicles_damage(entity this, entity inflictor, entity attacker, float damag } } +bool vehicles_heal(entity targ, entity inflictor, float amount, float limit) +{ + float true_limit = ((limit != RESOURCE_LIMIT_NONE) ? limit : targ.max_health); + if(GetResourceAmount(targ, RESOURCE_HEALTH) <= 0 || GetResourceAmount(targ, RESOURCE_HEALTH) >= true_limit) + return false; + + GiveResourceWithLimit(targ, RESOURCE_HEALTH, amount, true_limit); + if(targ.owner) + targ.owner.vehicle_health = (GetResourceAmount(targ, RESOURCE_HEALTH) / targ.max_health) * 100; + return true; +} + bool vehicles_crushable(entity e) { if(IS_PLAYER(e) && time >= e.vehicle_enter_delay) @@ -747,7 +780,7 @@ void vehicles_impact(entity this, float _minspeed, float _speedfac, float _maxpa if(_minspeed < wc) { float take = min(_speedfac * wc, _maxpain); - Damage (this, NULL, NULL, take, DEATH_FALL.m_id, this.origin, '0 0 0'); + Damage (this, NULL, NULL, take, DEATH_FALL.m_id, DMG_NOWEP, this.origin, '0 0 0'); this.play_time = time + 0.25; //dprint("wc: ", ftos(wc), "\n"); @@ -780,6 +813,7 @@ vector vehicles_findgoodexit(entity this, entity player, vector prefer_spot) return this.origin; } +.int old_vehicle_flags; void vehicles_exit(entity vehic, bool eject) { entity player = vehic.owner; @@ -792,7 +826,6 @@ void vehicles_exit(entity vehic, bool eject) vehicles_exit_running = true; - // TODO: this was in an IS_CLIENT check, make sure it isn't actually needed! if(vehic.vehicle_flags & VHF_PLAYERSLOT) { vehic.vehicle_exit(vehic, eject); @@ -814,19 +847,19 @@ void vehicles_exit(entity vehic, bool eject) WriteAngle(MSG_ONE, 0); } - setsize(player, STAT(PL_MIN,player), STAT(PL_MAX, player)); + setsize(player, STAT(PL_MIN, player), STAT(PL_MAX, player)); player.takedamage = DAMAGE_AIM; player.solid = SOLID_SLIDEBOX; set_movetype(player, MOVETYPE_WALK); player.effects &= ~EF_NODRAW; - player.teleportable = TELEPORT_NORMAL; + player.teleportable = TELEPORT_NORMAL; player.alpha = 1; player.PlayerPhysplug = func_null; player.vehicle = NULL; - player.view_ofs = STAT(PL_VIEW_OFS, player); - player.event_damage = PlayerDamage; - player.hud = HUD_NORMAL; + player.view_ofs = STAT(PL_VIEW_OFS, player); + player.event_damage = PlayerDamage; + STAT(HUD, player) = HUD_NORMAL; for(int slot = 0; slot < MAX_WEAPONSLOTS; ++ slot) { .entity weaponentity = weaponentities[slot]; @@ -858,6 +891,10 @@ void vehicles_exit(entity vehic, bool eject) vehic.team = vehic.tur_head.team; + if(vehic.old_vehicle_flags & VHF_SHIELDREGEN) + vehic.vehicle_flags |= VHF_SHIELDREGEN; + vehic.old_vehicle_flags = 0; + sound (vehic, CH_TRIGGER_SINGLE, SND_Null, 1, ATTEN_NORM); vehic.vehicle_hudmodel.viewmodelforclient = vehic; vehic.phase = time + 1; @@ -865,7 +902,7 @@ void vehicles_exit(entity vehic, bool eject) vehic.vehicle_exit(vehic, eject); vehicles_setreturn(vehic); - vehicles_reset_colors(vehic); + vehicles_reset_colors(vehic, NULL); vehic.owner = NULL; CSQCMODEL_AUTOINIT(vehic); @@ -890,7 +927,7 @@ void vehicles_touch(entity this, entity toucher) if(vehicles_crushable(toucher)) { if(vdist(this.velocity, >=, 30)) - Damage(toucher, this, this.owner, autocvar_g_vehicles_crush_dmg, DEATH_VH_CRUSH.m_id, '0 0 0', normalize(toucher.origin - this.origin) * autocvar_g_vehicles_crush_force); + Damage(toucher, this, this.owner, autocvar_g_vehicles_crush_dmg, DEATH_VH_CRUSH.m_id, DMG_NOWEP, '0 0 0', normalize(toucher.origin - this.origin) * autocvar_g_vehicles_crush_force); return; // Dont do selfdamage when hitting "soft targets". } @@ -929,7 +966,7 @@ bool vehicle_impulse(entity this, int imp) void vehicles_enter(entity pl, entity veh) { - // Remove this when bots know how to use vehicles + // Remove this when bots know how to use vehicles if((IS_BOT_CLIENT(pl) && !autocvar_g_vehicles_allow_bots)) return; @@ -964,6 +1001,10 @@ void vehicles_enter(entity pl, entity veh) Send_Notification(NOTIF_ONE, pl, MSG_CENTER, CENTER_VEHICLE_STEAL_SELF); + veh.vehicle_shield = 0; + veh.old_vehicle_flags = veh.vehicle_flags; // make a backup just so we're not permanently crippling this vehicle + veh.vehicle_flags &= ~VHF_SHIELDREGEN; + if (autocvar_g_vehicles_steal_show_waypoint) { entity wp = WaypointSprite_Spawn(WP_VehicleIntruder, 0, 0, pl, '0 0 68', NULL, veh.team, veh, wps_intruder, true, RADARICON_DANGER); wp.colormod = Team_ColorRGB(pl.team); @@ -989,9 +1030,10 @@ void vehicles_enter(entity pl, entity veh) pl.crouch = false; pl.view_ofs = STAT(PL_VIEW_OFS, pl); - setsize (pl, STAT(PL_MIN, pl), STAT(PL_MAX, pl)); + setsize(pl, STAT(PL_MIN, pl), STAT(PL_MAX, pl)); veh.event_damage = vehicles_damage; + veh.event_heal = vehicles_heal; veh.nextthink = 0; pl.items &= ~IT_USING_JETPACK; pl.angles = veh.angles; @@ -1012,7 +1054,7 @@ void vehicles_enter(entity pl, entity veh) veh.(weaponentity) = new(temp_wepent); veh.(weaponentity).m_switchweapon = pl.(weaponentity).m_switchweapon; } - pl.hud = veh.vehicleid; + STAT(HUD, pl) = veh.vehicleid; pl.PlayerPhysplug = veh.PlayerPhysplug; pl.vehicle_ammo1 = veh.vehicle_ammo1; @@ -1031,6 +1073,8 @@ void vehicles_enter(entity pl, entity veh) veh.team = pl.team; veh.flags -= FL_NOTARGET; + vehicles_reset_colors(veh, pl); + if (IS_REAL_CLIENT(pl)) { Send_Notification(NOTIF_ONE, pl, MSG_CENTER, CENTER_VEHICLE_ENTER); @@ -1071,7 +1115,7 @@ void vehicles_think(entity this) this.nextthink = time + autocvar_g_vehicles_thinkrate; if(this.owner) - this.owner.vehicle_weapon2mode = this.vehicle_weapon2mode; + STAT(VEHICLESTAT_W2MODE, this.owner) = STAT(VEHICLESTAT_W2MODE, this); Vehicle info = Vehicles_from(this.vehicleid); info.vr_think(info, this); @@ -1103,6 +1147,7 @@ void vehicles_spawn(entity this) this.owner = NULL; settouch(this, vehicles_touch); this.event_damage = vehicles_damage; + this.event_heal = vehicles_heal; this.reset = vehicles_reset; this.iscreature = true; this.teleportable = false; // no teleporting for vehicles, too buggy @@ -1144,11 +1189,12 @@ void vehicles_spawn(entity this) } }); - vehicles_reset_colors(this); Vehicle info = Vehicles_from(this.vehicleid); info.vr_spawn(info, this); + vehicles_reset_colors(this, NULL); + CSQCMODEL_AUTOINIT(this); } @@ -1214,6 +1260,7 @@ bool vehicle_initialize(entity this, Vehicle info, bool nodrop) this.vehicleid = info.vehicleid; this.PlayerPhysplug = info.PlayerPhysplug; this.event_damage = func_null; + this.event_heal = func_null; settouch(this, vehicles_touch); setthink(this, vehicles_spawn); this.nextthink = time; @@ -1246,14 +1293,14 @@ bool vehicle_initialize(entity this, Vehicle info, bool nodrop) setattachment(this.vehicle_viewport, this.vehicle_hudmodel, info.tag_view); } - setsize(this, info.mins, info.maxs); + setsize(this, info.m_mins, info.m_maxs); info.vr_setup(info, this); if(!nodrop) { setorigin(this, this.origin); - tracebox(this.origin + '0 0 100', info.mins, info.maxs, this.origin - '0 0 10000', MOVE_WORLDONLY, this); + tracebox(this.origin + '0 0 100', info.m_mins, info.m_maxs, this.origin - '0 0 10000', MOVE_WORLDONLY, this); setorigin(this, trace_endpos); }