void Monster_Damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
{SELFPARAM();
- if((self.spawnflags & MONSTERFLAG_INVINCIBLE) && deathtype != DEATH_KILL)
+ if((self.spawnflags & MONSTERFLAG_INVINCIBLE) && deathtype != DEATH_KILL && !ITEM_DAMAGE_NEEDKILL(deathtype))
return;
if(self.frozen && deathtype != DEATH_KILL && deathtype != DEATH_NADE_ICE_FREEZE)
HUD_Panel_DrawProgressBar(p_pos, p_size, autocvar_hud_panel_itemstime_progressbar_name, t/autocvar_hud_panel_itemstime_progressbar_maxtime, 0, autocvar_hud_panel_itemstime_iconalign, color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
}
- if (t > 0 && autocvar_hud_panel_itemstime_text)
- drawstring_aspect(numpos, ftos(t), eX * ((ar - 1)/ar) * mySize_x + eY * mySize_y, color, panel_fg_alpha, DRAWFLAG_NORMAL);
- else
- picpos.x = myPos.x + mySize.x / 2 - mySize.y / 2;
+ if(autocvar_hud_panel_itemstime_text)
+ {
+ if(t > 0)
+ drawstring_aspect(numpos, ftos(t), eX * ((ar - 1)/ar) * mySize_x + eY * mySize_y, color, panel_fg_alpha, DRAWFLAG_NORMAL);
+ else if(precache_pic("gfx/hud/default/checkmark")) // COMPAT: check if this image exists, as 0.8.1 clients lack it
+ drawpic_aspect_skin(numpos, "checkmark", eX * (ar - 1) * mySize_y + eY * mySize_y, '1 1 1', panel_fg_alpha * picalpha, DRAWFLAG_NORMAL);
+ else // legacy code, if the image is missing just center the icon
+ picpos.x = myPos.x + mySize.x / 2 - mySize.y / 2;
+ }
if (item_availableTime)
drawpic_aspect_skin_expanding(picpos, item.m_icon, '1 1 0' * mySize_y, '1 1 1', panel_fg_alpha * picalpha, DRAWFLAG_NORMAL, item_availableTime);
drawpic_aspect_skin(picpos, item.m_icon, '1 1 0' * mySize_y, '1 1 1', panel_fg_alpha * picalpha, DRAWFLAG_NORMAL);
void setterDummy(entity, float);
CLASS(Animation, Object)
METHOD(Animation, configureAnimation, void(entity, entity, void(entity, float), float, float, float, float));
+ METHOD(Animation, update, void(entity, float, float, float));
METHOD(Animation, setTimeStartEnd, void(entity, float, float));
METHOD(Animation, setTimeStartDuration, void(entity, float, float));
METHOD(Animation, setValueStartEnd, void(entity, float, float));
me.setValueStartEnd(me, animStartValue, animEndValue);
}
+void Animation_update(entity me, float animDuration, float animStartValue, float animEndValue)
+{
+ me.setTimeStartDuration(me, time, animDuration);
+ me.setValueStartEnd(me, animStartValue, animEndValue);
+}
+
void Animation_setTimeStartEnd(entity me, float s, float e)
{
me.startTime = s;
METHOD(Slider, mouseRelease, float(entity, vector));
METHOD(Slider, valueToText, string(entity, float));
METHOD(Slider, toString, string(entity));
+ METHOD(Slider, setValue_allowAnim, void(entity, float, bool));
+ METHOD(Slider, setValue_noAnim, void(entity, float));
METHOD(Slider, setValue, void(entity, float));
METHOD(Slider, setSliderValue, void(entity, float));
METHOD(Slider, showNotify, void(entity));
ATTRIB(Slider, value, float, 0)
ATTRIB(Slider, animated, float, 1)
ATTRIB(Slider, sliderValue, float, 0)
+ ATTRIB(Slider, sliderAnim, entity, world)
ATTRIB(Slider, valueMin, float, 0)
ATTRIB(Slider, valueMax, float, 0)
ATTRIB(Slider, valueStep, float, 0)
#endif
#ifdef IMPLEMENTATION
-void Slider_setValue(entity me, float val)
+void Slider_setValue_allowAnim(entity me, float val, bool allowAnim)
{
- if (me.animated) {
- anim.removeObjAnim(anim, me);
- makeHostedEasing(me, Slider_setSliderValue, easingQuadInOut, 1, me.sliderValue, val);
+ if(allowAnim && me.animated) {
+ float t = 0.5;
+ if(!me.sliderAnim)
+ me.sliderAnim = makeHostedEasing(me, Slider_setSliderValue, easingQuadOut, t, me.sliderValue, val);
+ else
+ me.sliderAnim.update(me.sliderAnim, t, me.sliderValue, val);
} else {
me.setSliderValue(me, val);
}
me.value = val;
}
+void Slider_setValue_noAnim(entity me, float val)
+{
+ Slider_setValue_allowAnim(me, val, false);
+}
+void Slider_setValue(entity me, float val)
+{
+ Slider_setValue_allowAnim(me, val, true);
+}
void Slider_setSliderValue(entity me, float val)
{
me.sliderValue = val;
float Slider_mouseDrag(entity me, vector pos)
{
float hit;
- float v, animed;
+ float v;
if(me.disabled)
return 0;
- anim.removeObjAnim(anim, me);
- animed = me.animated;
- me.animated = false;
-
if(me.pressed)
{
hit = 1;
if(pos.y >= 1 + me.tolerance.y) hit = 0;
if(hit)
{
+ // handle dragging
+ me.pressed = 2;
+
v = median(0, (pos.x - me.pressOffset - 0.5 * me.controlWidth) / (1 - me.textSpace - me.controlWidth), 1) * (me.valueMax - me.valueMin) + me.valueMin;
if(me.valueStep)
v = floor(0.5 + v / me.valueStep) * me.valueStep;
- me.setValue(me, v);
+ me.setValue_noAnim(me, v);
}
else
me.setValue(me, me.previousValue);
}
- me.animated = animed;
-
return 1;
}
float Slider_mousePress(entity me, vector pos)
else
draw_Picture(eX * controlLeft, strcat(me.src, "_n"), eX * me.controlWidth + eY, me.color, 1);
}
+
+ if(me.sliderAnim)
+ if(me.sliderAnim.isFinished(me.sliderAnim))
+ {
+ anim.removeObjAnim(anim, me);
+ me.sliderAnim = world;
+ }
+
me.setText(me, me.valueToText(me, me.value));
draw_alpha = save;
SUPER(Slider).draw(me);
CLASS(TextSlider, Slider)
METHOD(TextSlider, valueToText, string(entity, float));
METHOD(TextSlider, valueToIdentifier, string(entity, float));
+ METHOD(TextSlider, setValueFromIdentifier_allowAnim, void(entity, string, bool));
+ METHOD(TextSlider, setValueFromIdentifier_noAnim, void(entity, string));
METHOD(TextSlider, setValueFromIdentifier, void(entity, string));
METHOD(TextSlider, getIdentifier, string(entity));
METHOD(TextSlider, clearValues, void(entity));
return _("Custom");
return me.(valueStrings[val]);
}
-void TextSlider_setValueFromIdentifier(entity me, string id)
+void TextSlider_setValueFromIdentifier_allowAnim(entity me, string id, bool allowAnim)
{
int i;
for(i = 0; i < me.nValues; ++i)
if(me.valueToIdentifier(me, i) == id)
{
- SUPER(TextSlider).setValue( me, i );
+ SUPER(TextSlider).setValue_allowAnim(me, i, allowAnim);
return;
}
- SUPER(TextSlider).setValue( me, -1 );
+ SUPER(TextSlider).setValue_allowAnim(me, -1, allowAnim);
+}
+void TextSlider_setValueFromIdentifier_noAnim(entity me, string id)
+{
+ TextSlider_setValueFromIdentifier_allowAnim(me, id, false);
+}
+void TextSlider_setValueFromIdentifier(entity me, string id)
+{
+ TextSlider_setValueFromIdentifier_allowAnim(me, id, true);
}
string TextSlider_getIdentifier(entity me)
{
void TextSlider_configureTextSliderValues(entity me, string theDefault)
{
me.configureSliderValues(me, 0, 0, me.nValues - 1, 1, 1, 1);
- me.setValueFromIdentifier(me, theDefault);
+ me.setValueFromIdentifier_noAnim(me, theDefault);
}
#endif
void XonoticRadioButton_configureXonoticRadioButton(entity me, float theGroup, string theCvar, string theValue, string theText, string theTooltip)
{
me.cvarName = (theCvar) ? theCvar : string_null;
+ me.cvarValue = theValue;
me.loadCvars(me);
setZonedTooltip(me, theTooltip, theCvar);
me.configureRadioButton(me, theText, me.fontSize, me.image, theGroup, 0);
if (!me.cvarName)
return;
- me.setValue( me, cvar(me.cvarName) );
+ me.setValue_noAnim(me, cvar(me.cvarName));
}
void XonoticSlider_saveCvars(entity me)
{
// snapping
if(v > fromDecibelOfSquare(me.valueMax - 0.5 * me.valueStep, me.valueMin))
- Slider_setValue(me, me.valueMax);
+ Slider_setValue_noAnim(me, me.valueMax);
else
- Slider_setValue(me, me.valueStep * floor(0.5 + toDecibelOfSquare(v, me.valueMin) / me.valueStep) );
+ Slider_setValue_noAnim(me, me.valueStep * floor(0.5 + toDecibelOfSquare(v, me.valueMin) / me.valueStep));
}
void XonoticDecibelsSlider_saveCvars(entity me)
{
}
void XonoticParticlesSlider_loadCvars(entity me)
{
- me.setValueFromIdentifier(me, sprintf("%s %s %s",
+ me.setValueFromIdentifier_noAnim(me, sprintf("%s %s %s",
cvar_string("cl_particles_quality"),
cvar_string("r_drawparticles_drawdistance"),
cvar_string("cl_damageeffect")
}
void XonoticResolutionSlider_loadCvars(entity me)
{
- me.setValueFromIdentifier(me, strcat(cvar_string("_menu_vid_width"), " ", cvar_string("_menu_vid_height"), " ", cvar_string("_menu_vid_pixelheight")));
+ me.setValueFromIdentifier_noAnim(me, strcat(cvar_string("_menu_vid_width"), " ", cvar_string("_menu_vid_height"), " ", cvar_string("_menu_vid_pixelheight")));
}
void XonoticResolutionSlider_saveCvars(entity me)
{
}
void XonoticScoreboardFadeTimeSlider_loadCvars(entity me)
{
- me.setValueFromIdentifier(me, sprintf("%s %s",
+ me.setValueFromIdentifier_noAnim(me, sprintf("%s %s",
cvar_string("scoreboard_fadeinspeed"),
cvar_string("scoreboard_fadeoutspeed")
));
float i;
for(i = 1; i < n; ++i)
s = strcat(s, " ", cvar_string(argv(i)));
- me.setValueFromIdentifier(me, s);
+ me.setValueFromIdentifier_noAnim(me, s);
if(me.value < 0 && n > 1)
{
// if it failed: check if all cvars have the same value
if(cvar_string(argv(i)) != cvar_string(argv(i-1)))
break;
if(i >= n)
- me.setValueFromIdentifier(me, cvar_string(argv(0)));
+ me.setValueFromIdentifier_noAnim(me, cvar_string(argv(0)));
}
}
void XonoticTextSlider_saveCvars(entity me)
void havocbot_chooseenemy()
{SELFPARAM();
entity head, best, head2;
- float rating, bestrating, i, hf;
+ float rating, bestrating, hf;
vector eye, v;
if (autocvar_bot_nofire || IS_INDEPENDENT_PLAYER(self))
{
self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE;
- for(i = 0; ; ++i)
+ bool scan_transparent = false;
+ bool scan_secondary_targets = false;
+ bool have_secondary_targets = false;
+ while(true)
{
- while (head)
+ scan_secondary_targets = false;
+ :scan_targets
+ for( ; head; head = head.chain)
{
+ if(!scan_secondary_targets)
+ {
+ if(head.classname == "misc_breakablemodel")
+ {
+ have_secondary_targets = true;
+ continue;
+ }
+ }
+ else
+ {
+ if(head.classname != "misc_breakablemodel")
+ continue;
+ }
+
v = (head.absmin + head.absmax) * 0.5;
rating = vlen(v - eye);
if (rating<autocvar_bot_ai_enemydetectionradius)
bestrating = rating;
}
}
- head = head.chain;
+ }
+
+ if(!best && have_secondary_targets && !scan_secondary_targets)
+ {
+ scan_secondary_targets = true;
+ // restart the loop
+ head = head2;
+ bestrating = 100000000;
+ goto scan_targets;
}
// I want to do a second scan if no enemy was found or I don't have weapons
// TODO: Perform the scan when using the rifle (requires changes on the rifle code)
if(best || self.weapons) // || self.weapon == WEP_RIFLE.m_id
break;
- if(i)
+ if(scan_transparent)
break;
// Set flags to see through transparent objects
self.dphitcontentsmask |= DPCONTENTS_OPAQUE;
head = head2;
+ scan_transparent = true;
}
// Restore hit flags
self.enemy = best;
self.havocbot_stickenemy = true;
+ if(best && best.classname == "misc_breakablemodel")
+ self.havocbot_stickenemy = false;
}
float havocbot_chooseweapon_checkreload(int new_weapon)
}
self.frags = FRAGS_SPECTATOR;
+ self.bot_attack = false;
MUTATOR_CALLHOOK(MakePlayerObserver);
targ.revive_progress = ((frozen_type == 3) ? 1 : 0);
targ.health = ((frozen_type == 3) ? targ_maxhealth : 1);
targ.revive_speed = freeze_time;
+ self.bot_attack = false;
entity ice, head;
ice = spawn();
void Unfreeze (entity targ)
{
+ if(!targ.frozen)
+ return;
+
if(targ.frozen && targ.frozen != 3) // only reset health if target was frozen
targ.health = ((IS_PLAYER(targ)) ? start_health : targ.max_health);
targ.frozen = 0;
targ.revive_progress = 0;
targ.revival_time = time;
+ self.bot_attack = true;
WaypointSprite_Kill(targ.waypointsprite_attached);