X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fcommon%2Fmutators%2Fmutator%2Fwaypoints%2Fwaypointsprites.qc;h=81f54b1c903807612713536ae6081ca311c77554;hb=5df49bb174887a416ddedd01c7e7202d1ffed964;hp=91869de77062531e76be4f9db6dc783948be642a;hpb=51c4ab5336d3887b618c13e5f566cf19636af951;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/common/mutators/mutator/waypoints/waypointsprites.qc b/qcsrc/common/mutators/mutator/waypoints/waypointsprites.qc index 91869de77..5b8a213bf 100644 --- a/qcsrc/common/mutators/mutator/waypoints/waypointsprites.qc +++ b/qcsrc/common/mutators/mutator/waypoints/waypointsprites.qc @@ -1,7 +1,5 @@ #include "waypointsprites.qh" -#ifdef IMPLEMENTATION - REGISTER_MUTATOR(waypointsprites, true); REGISTER_NET_LINKED(waypointsprites) @@ -18,10 +16,12 @@ bool WaypointSprite_SendEntity(entity this, entity to, float sendflags) sendflags |= 0x80; int f = 0; - if(this.currentammo) + if(this.currentammo == 1) f |= 1; // hideable if(this.exteriormodeltoclient == to) f |= 2; // my own + if(this.currentammo == 2) + f |= 2; // radar only MUTATOR_CALLHOOK(SendWaypoint, this, to, sendflags, f); sendflags = M_ARGV(2, int); @@ -34,7 +34,7 @@ bool WaypointSprite_SendEntity(entity this, entity to, float sendflags) { if (this.max_health) { - WriteByte(MSG_ENTITY, (this.health / this.max_health) * 191.0); + WriteByte(MSG_ENTITY, (GetResourceAmount(this, RESOURCE_HEALTH) / this.max_health) * 191.0); } else { @@ -47,9 +47,7 @@ bool WaypointSprite_SendEntity(entity this, entity to, float sendflags) if (sendflags & 64) { - WriteCoord(MSG_ENTITY, this.origin.x); - WriteCoord(MSG_ENTITY, this.origin.y); - WriteCoord(MSG_ENTITY, this.origin.z); + WriteVector(MSG_ENTITY, this.origin); } if (sendflags & 1) @@ -84,11 +82,7 @@ bool WaypointSprite_SendEntity(entity this, entity to, float sendflags) if (WaypointSprite_isteammate(this.owner, WaypointSprite_getviewentity(to))) { - float dt = (this.waypointsprite_helpmetime - time) / 0.1; - if (dt < 0) - dt = 0; - if (dt > 255) - dt = 255; + float dt = bound(0, (this.waypointsprite_helpmetime - time) / 0.1, 255); WriteByte(MSG_ENTITY, dt); } else @@ -108,9 +102,9 @@ NET_HANDLE(waypointsprites, bool isnew) { void Ent_RemoveWaypointSprite(entity this) { - if (this.netname) strunzone(this.netname); - if (this.netname2) strunzone(this.netname2); - if (this.netname3) strunzone(this.netname3); + strfree(this.netname); + strfree(this.netname2); + strfree(this.netname3); } /** flags origin [team displayrule] [spritename] [spritename2] [spritename3] [lifetime maxdistance hideable] */ @@ -136,7 +130,7 @@ void Ent_WaypointSprite(entity this, bool isnew) int t = ReadByte(); if (t < 192) { - this.health = t / 191.0; + SetResourceAmountExplicit(this, RESOURCE_HEALTH, t / 191.0); this.build_finished = 0; } else @@ -144,7 +138,7 @@ void Ent_WaypointSprite(entity this, bool isnew) t = (t - 192) * 256 + ReadByte(); this.build_started = servertime; if (this.build_finished) - this.build_starthealth = bound(0, this.health, 1); + this.build_starthealth = bound(0, GetResourceAmount(this, RESOURCE_HEALTH), 1); else this.build_starthealth = 0; this.build_finished = servertime + t / 32; @@ -152,16 +146,14 @@ void Ent_WaypointSprite(entity this, bool isnew) } else { - this.health = -1; + SetResourceAmountExplicit(this, RESOURCE_HEALTH, -1); this.build_finished = 0; } if (sendflags & 64) { // unfortunately, this needs to be exact (for the 3D display) - this.origin_x = ReadCoord(); - this.origin_y = ReadCoord(); - this.origin_z = ReadCoord(); + this.origin = ReadVector(); setorigin(this, this.origin); } @@ -173,23 +165,17 @@ void Ent_WaypointSprite(entity this, bool isnew) if (sendflags & 2) { - if (this.netname) - strunzone(this.netname); - this.netname = strzone(ReadString()); + strcpy(this.netname, ReadString()); } if (sendflags & 4) { - if (this.netname2) - strunzone(this.netname2); - this.netname2 = strzone(ReadString()); + strcpy(this.netname2, ReadString()); } if (sendflags & 8) { - if (this.netname3) - strunzone(this.netname3); - this.netname3 = strzone(ReadString()); + strcpy(this.netname3, ReadString()); } if (sendflags & 16) @@ -249,6 +235,8 @@ vector spritelookupcolor(entity this, string s, vector def) string spritelookuptext(entity this, string s) { + if(autocvar_g_waypointsprite_spam && waypointsprite_count >= autocvar_g_waypointsprite_spam) + return "Spam"; // no need to translate this debug string if (s == WP_RaceStartFinish.netname) return (race_checkpointtime || race_mycheckpointtime) ? _("Finish") : _("Start"); if (s == WP_Weapon.netname) return Weapons_from(this.wp_extra).m_name; if (s == WP_Item.netname) return Items_from(this.wp_extra).m_waypoint; @@ -259,9 +247,29 @@ string spritelookuptext(entity this, string s) } // need to loop, as our netname could be one of three - FOREACH(Waypoints, it.netname == s, LAMBDA( + FOREACH(Waypoints, it.netname == s, { return it.m_name; - )); + }); + + return s; +} + +string spritelookupicon(entity this, string s) +{ + // TODO: needs icons! //if (s == WP_RaceStartFinish.netname) return (race_checkpointtime || race_mycheckpointtime) ? _("Finish") : _("Start"); + if (s == WP_Weapon.netname) return Weapons_from(this.wp_extra).model2; + if (s == WP_Item.netname) return Items_from(this.wp_extra).m_icon; + if (s == WP_Vehicle.netname) return Vehicles_from(this.wp_extra).m_icon; + //if (s == WP_Monster.netname) return get_monsterinfo(this.wp_extra).m_icon; + if (MUTATOR_CALLHOOK(WP_Format, this, s)) + { + return M_ARGV(4, string); + } + + // need to loop, as our netname could be one of three + FOREACH(Waypoints, it.netname == s, { + return it.m_icon; + }); return s; } @@ -282,10 +290,10 @@ void drawrotpic(vector org, float rot, string pic, vector sz, vector hotspot, ve // rotate them, and make them absolute rot = -rot; // rotate by the opposite angle, as our coordinate system is reversed - v1 = rotate(v1, rot) + org; - v2 = rotate(v2, rot) + org; - v3 = rotate(v3, rot) + org; - v4 = rotate(v4, rot) + org; + v1 = Rotate(v1, rot) + org; + v2 = Rotate(v2, rot) + org; + v3 = Rotate(v3, rot) + org; + v4 = Rotate(v4, rot) + org; // draw them R_BeginPolygon(pic, f); @@ -319,9 +327,9 @@ void drawhealthbar(vector org, float rot, float h, vector sz, vector hotspot, fl up = '0 1 0'; rot = -rot; // rotate by the opposite angle, as our coordinate system is reversed - o = rotate(o, rot) + org; - ri = rotate(ri, rot); - up = rotate(up, rot); + o = Rotate(o, rot) + org; + ri = Rotate(ri, rot); + up = Rotate(up, rot); owidth = width + 2 * border; o = o - up * (margin + border + theheight) + ri * (sz.x - owidth) * 0.5; @@ -348,34 +356,38 @@ vector drawspritearrow(vector o, float ang, vector rgb, float a, float t) R_BeginPolygon("", DRAWFLAG_NORMAL); R_PolygonVertex(o, '0 0 0', '0 0 0', a); - R_PolygonVertex(o + rotate(arrowY - borderX, ang), '0 0 0', '0 0 0', a); - R_PolygonVertex(o + rotate(borderY - borderX, ang), '0 0 0', '0 0 0', a); - R_PolygonVertex(o + rotate(borderY + borderX, ang), '0 0 0', '0 0 0', a); - R_PolygonVertex(o + rotate(arrowY + borderX, ang), '0 0 0', '0 0 0', a); + R_PolygonVertex(o + Rotate(arrowY - borderX, ang), '0 0 0', '0 0 0', a); + R_PolygonVertex(o + Rotate(borderY - borderX, ang), '0 0 0', '0 0 0', a); + R_PolygonVertex(o + Rotate(borderY + borderX, ang), '0 0 0', '0 0 0', a); + R_PolygonVertex(o + Rotate(arrowY + borderX, ang), '0 0 0', '0 0 0', a); R_EndPolygon(); R_BeginPolygon("", DRAWFLAG_ADDITIVE); - R_PolygonVertex(o + rotate(eY * borderDiag, ang), '0 0 0', rgb, a); - R_PolygonVertex(o + rotate(arrowY - arrowX, ang), '0 0 0', rgb, a); - R_PolygonVertex(o + rotate(arrowY + arrowX, ang), '0 0 0', rgb, a); + R_PolygonVertex(o + Rotate(eY * borderDiag, ang), '0 0 0', rgb, a); + R_PolygonVertex(o + Rotate(arrowY - arrowX, ang), '0 0 0', rgb, a); + R_PolygonVertex(o + Rotate(arrowY + arrowX, ang), '0 0 0', rgb, a); R_EndPolygon(); - return o + rotate(eY * (borderDiag+size+margin), ang); + return o + Rotate(eY * (borderDiag+size+margin), ang); } // returns location of sprite healthbar -vector drawspritetext(vector o, float ang, float minwidth, vector rgb, float a, vector fontsize, string s) +vector drawsprite_TextOrIcon(bool is_text, vector o, float ang, float minwidth, vector rgb, float a, vector sz, string str) { float algnx, algny; float sw, w, h; float aspect, sa, ca; - sw = stringwidth(s, false, fontsize); + if (is_text) + sw = stringwidth(str, false, sz); + else + sw = sz.x; + if (sw > minwidth) w = sw; else w = minwidth; - h = fontsize.y; + h = sz.y; // how do corners work? aspect = vid_conwidth / vid_conheight; @@ -406,11 +418,14 @@ vector drawspritetext(vector o, float ang, float minwidth, vector rgb, float a, if (o.x > vid_conwidth - w) o.x = vid_conwidth - w; if (o.y > vid_conheight - h) - o.x = vid_conheight - h; + o.y = vid_conheight - h; o.x += 0.5 * (w - sw); - drawstring(o, s, fontsize, rgb, a, DRAWFLAG_NORMAL); + if (is_text) + drawstring(o, str, sz, rgb, a, DRAWFLAG_NORMAL); + else + drawpic(o, str, sz, rgb, a, DRAWFLAG_NORMAL); o.x += 0.5 * sw; o.y += 0.5 * h; @@ -459,8 +474,8 @@ vector fixrgbexcess(vector rgb) void Draw_WaypointSprite(entity this) { - if (this.lifetime) - this.alpha = pow(bound(0, (this.fadetime - time) / this.lifetime, 1), waypointsprite_timealphaexponent); + if (this.lifetime > 0) + this.alpha = (bound(0, (this.fadetime - time) / this.lifetime, 1) ** waypointsprite_timealphaexponent); else this.alpha = 1; @@ -470,14 +485,12 @@ void Draw_WaypointSprite(entity this) if (autocvar_cl_hidewaypoints >= 2) return; - if (this.hideflags & 1) - if (autocvar_cl_hidewaypoints) - return; // fixed waypoint + if (this.hideflags & 1 && autocvar_cl_hidewaypoints) + return; // fixed waypoint InterpolateOrigin_Do(this); float t = entcs_GetTeam(player_localnum) + 1; - string spriteimage = ""; // choose the sprite @@ -520,25 +533,24 @@ void Draw_WaypointSprite(entity this) ++waypointsprite_newcount; - float dist; - dist = vlen(this.origin - view_origin); - - float a; - a = this.alpha * autocvar_hud_panel_fg_alpha; + float dist = vlen(this.origin - view_origin); + float a = this.alpha * autocvar_hud_panel_fg_alpha; if (this.maxdistance > waypointsprite_normdistance) - a *= pow(bound(0, (this.maxdistance - dist) / (this.maxdistance - waypointsprite_normdistance), 1), waypointsprite_distancealphaexponent); + a *= (bound(0, (this.maxdistance - dist) / (this.maxdistance - waypointsprite_normdistance), 1) ** waypointsprite_distancealphaexponent); else if (this.maxdistance > 0) - a *= pow(bound(0, (waypointsprite_fadedistance - dist) / (waypointsprite_fadedistance - waypointsprite_normdistance), 1), waypointsprite_distancealphaexponent) * (1 - waypointsprite_minalpha) + waypointsprite_minalpha; + a *= (bound(0, (waypointsprite_fadedistance - dist) / (waypointsprite_fadedistance - waypointsprite_normdistance), 1) ** waypointsprite_distancealphaexponent) * (1 - waypointsprite_minalpha) + waypointsprite_minalpha; vector rgb = spritelookupcolor(this, spriteimage, this.teamradar_color); if (rgb == '0 0 0') { this.teamradar_color = '1 0 1'; - LOG_INFOF("WARNING: sprite of name %s has no color, using pink so you notice it\n", spriteimage); + LOG_INFOF("WARNING: sprite of name %s has no color, using pink so you notice it", spriteimage); } - if (time - floor(time) > 0.5) + float health_val = GetResourceAmount(this, RESOURCE_HEALTH); + float blink_time = (health_val >= 0) ? (health_val * 10) : time; + if (blink_time - floor(blink_time) > 0.5) { if (this.helpme && time < this.helpme) a *= SPRITE_HELPME_BLINK; @@ -569,15 +581,16 @@ void Draw_WaypointSprite(entity this) { // scale it to be just in view vector d; - float f1, f2; d = o - '0.5 0 0' * vid_conwidth - '0 0.5 0' * vid_conheight; ang = atan2(-d.x, -d.y); if (o.z < 0) ang += M_PI; - f1 = d.x / vid_conwidth; - f2 = d.y / vid_conheight; + float f1 = d.x / vid_conwidth; + float f2 = d.y / vid_conheight; + if (f1 == 0) { f1 = 0.000001; } + if (f2 == 0) { f2 = 0.000001; } if (max(f1, -f1) > max(f2, -f2)) { if (d.z * f1 > 0) { @@ -616,11 +629,9 @@ void Draw_WaypointSprite(entity this) (vid_conwidth - (vid_conwidth * waypointsprite_edgeoffset_right)) - o.x, (vid_conheight - (vid_conheight * waypointsprite_edgeoffset_bottom)) - o.y); - float vidscale = max(vid_conwidth / vid_width, vid_conheight / vid_height); + float crosshairdistance = sqrt( ((o.x - vid_conwidth/2) ** 2) + ((o.y - vid_conheight/2) ** 2) ); - float crosshairdistance = sqrt( pow(o.x - vid_conwidth/2, 2) + pow(o.y - vid_conheight/2, 2) ); - - t = waypointsprite_scale * vidscale; + t = waypointsprite_scale; a *= waypointsprite_alpha; { @@ -641,46 +652,79 @@ void Draw_WaypointSprite(entity this) if (time < this.build_finished + 0.25) { if (time < this.build_started) - this.health = this.build_starthealth; + SetResourceAmountExplicit(this, RESOURCE_HEALTH, this.build_starthealth); else if (time < this.build_finished) - this.health = (time - this.build_started) / (this.build_finished - this.build_started) * (1 - this.build_starthealth) + this.build_starthealth; + SetResourceAmountExplicit(this, RESOURCE_HEALTH, (time - this.build_started) / (this.build_finished - this.build_started) * (1 - this.build_starthealth) + this.build_starthealth); else - this.health = 1; + SetResourceAmountExplicit(this, RESOURCE_HEALTH, 1); } else - this.health = -1; + SetResourceAmountExplicit(this, RESOURCE_HEALTH, -1); } o = drawspritearrow(o, ang, rgb, a, SPRITE_ARROW_SCALE * t); - string txt; - if (autocvar_g_waypointsprite_spam && waypointsprite_count >= autocvar_g_waypointsprite_spam) - txt = _("Spam"); - else + string pic = ""; + bool is_text = true; + if (!autocvar_g_waypointsprite_text) + { + string spr_icon = spritelookupicon(this, spriteimage); + pic = spr_icon; + bool icon_found = !(!spr_icon || spr_icon == ""); + if (icon_found) // it's valid, but let's make sure it exists! + { + pic = strcat(hud_skin_path, "/", spr_icon); + if(precache_pic(pic) == "") + { + pic = strcat("gfx/hud/default/", spr_icon); + if(!precache_pic(pic)) + icon_found = false; + } + } + if (icon_found) + is_text = false; + } + + vector sz; + vector txt_color; + string txt = string_null; + if (is_text) + { txt = spritelookuptext(this, spriteimage); - if (this.helpme && time < this.helpme) - txt = sprintf(_("%s needing help!"), txt); - if (autocvar_g_waypointsprite_uppercase) - txt = strtoupper(txt); + if (this.helpme && time < this.helpme) + txt = sprintf(_("%s needing help!"), txt); + if (autocvar_g_waypointsprite_uppercase) + txt = strtoupper(txt); + txt_color = rgb; + sz = waypointsprite_fontsize * '1 1 0'; + } + else + { + // for convenience icon path and color are saved to txt and txt_color + txt = pic; + txt_color = ((autocvar_g_waypointsprite_iconcolor) ? '1 1 1' : rgb); + sz = autocvar_g_waypointsprite_iconsize * '1 1 0'; + } draw_beginBoldFont(); - if (this.health >= 0) + if (GetResourceAmount(this, RESOURCE_HEALTH) >= 0) { - o = drawspritetext(o, ang, (SPRITE_HEALTHBAR_WIDTH + 2 * SPRITE_HEALTHBAR_BORDER) * t, rgb, a, waypointsprite_fontsize * '1 1 0', txt); - - float align, marg; + float align = 0, marg; if (this.build_finished) align = 0.5; else align = 0; if (cos(ang) > 0) - marg = -(SPRITE_HEALTHBAR_MARGIN + SPRITE_HEALTHBAR_HEIGHT + 2 * SPRITE_HEALTHBAR_BORDER) * t - 0.5 * waypointsprite_fontsize; + marg = -(SPRITE_HEALTHBAR_MARGIN + SPRITE_HEALTHBAR_HEIGHT + 2 * SPRITE_HEALTHBAR_BORDER) * t - 0.5 * sz.y; else - marg = SPRITE_HEALTHBAR_MARGIN * t + 0.5 * waypointsprite_fontsize; + marg = SPRITE_HEALTHBAR_MARGIN * t + 0.5 * sz.y; + + float minwidth = (SPRITE_HEALTHBAR_WIDTH + 2 * SPRITE_HEALTHBAR_BORDER) * t; + o = drawsprite_TextOrIcon(is_text, o, ang, minwidth, txt_color, a, sz, txt); drawhealthbar( o, 0, - this.health, + GetResourceAmount(this, RESOURCE_HEALTH), '0 0 0', '0 0 0', SPRITE_HEALTHBAR_WIDTH * t, @@ -697,8 +741,9 @@ void Draw_WaypointSprite(entity this) } else { - o = drawspritetext(o, ang, 0, rgb, a, waypointsprite_fontsize * '1 1 0', txt); + drawsprite_TextOrIcon(is_text, o, ang, 0, txt_color, a, sz, txt); } + draw_endBoldFont(); } @@ -784,9 +829,10 @@ void WaypointSprite_UpdateSprites(entity e, entity _m1, entity _m2, entity _m3) void WaypointSprite_UpdateHealth(entity e, float f) { f = bound(0, f, e.max_health); - if (f != e.health || e.pain_finished) + float step = e.max_health / 40; + if ((floor(f / step) != floor(GetResourceAmount(e, RESOURCE_HEALTH)) / step) || e.pain_finished) { - e.health = f; + SetResourceAmountExplicit(e, RESOURCE_HEALTH, f); e.pain_finished = 0; e.SendFlags |= 0x80; } @@ -868,9 +914,10 @@ void WaypointSprite_FadeOutIn(entity e, float t) // ensure: // (e.teleport_time - time) / wp.fade_time stays // e.teleport_time = time + fadetime - float current_fadetime; - current_fadetime = e.teleport_time - time; + float current_fadetime = e.teleport_time - time; e.teleport_time = time + t; + if (e.fade_time < 0) + e.fade_time = -e.fade_time; e.fade_time = e.fade_time * t / current_fadetime; } @@ -1004,8 +1051,10 @@ entity WaypointSprite_Spawn( ) { entity wp = new(sprite_waypoint); + wp.fade_time = _lifetime; // if negative tells client not to fade it out + if(_lifetime < 0) + _lifetime = -_lifetime; wp.teleport_time = time + _lifetime; - wp.fade_time = _lifetime; wp.exteriormodeltoclient = ref; if (ref) { @@ -1051,7 +1100,7 @@ entity WaypointSprite_SpawnFixed( entity WaypointSprite_DeployFixed( entity spr, - float limited_range, + bool limited_range, entity player, vector ofs, entity icon // initial icon @@ -1083,7 +1132,7 @@ entity WaypointSprite_DeployPersonal( entity WaypointSprite_Attach( entity spr, entity player, - float limited_range, + bool limited_range, entity icon // initial icon ) { @@ -1110,10 +1159,10 @@ entity WaypointSprite_AttachCarrier( { WaypointSprite_Kill(carrier.waypointsprite_attached); // FC overrides attached entity e = WaypointSprite_Spawn(spr, 0, 0, carrier, '0 0 64', NULL, carrier.team, carrier, waypointsprite_attachedforcarrier, false, icon); - if (carrier.health) + if (GetResourceAmount(carrier, RESOURCE_HEALTH)) { - WaypointSprite_UpdateMaxHealth(e, '1 0 0' * healtharmor_maxdamage(start_health, start_armorvalue, autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id) * 2); - WaypointSprite_UpdateHealth(e, '1 0 0' * healtharmor_maxdamage(carrier.health, carrier.armorvalue, autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id)); + WaypointSprite_UpdateMaxHealth(e, 2 * healtharmor_maxdamage(start_health, start_armorvalue, autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id).x); + WaypointSprite_UpdateHealth(e, healtharmor_maxdamage(GetResourceAmount(carrier, RESOURCE_HEALTH), GetResourceAmount(carrier, RESOURCE_ARMOR), autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id).x); } return e; } @@ -1149,4 +1198,3 @@ void WaypointSprite_PlayerGone(entity this) WaypointSprite_DetachCarrier(this); } #endif -#endif