spawnAndUse()
{
self.hassentry = true;
base = spawn("script_model", self.origin);
middle = spawn("script_model", self.origin + (0,0,24));
head = spawn("script_model", self.origin + (0,0,31));
arm = spawn("script_model", self.origin + (-5,0,29));
wait .05;
base setModel("xmodel/sentry_base");
middle setModel("xmodel/sentry_middle");
head setModel("xmodel/sentry_head");
arm setModel("xmodel/sentry_arm");
base.destroy = 0;
head linkto(base);
arm linkto(base);
middle linkto(base);
self disableWeapon();
self iprintlnbold("Press ^1[{+attack}]^7 to place the sentry");
base.origin = self.origin + maps\mp\_utility::vectorScale(anglestoforward(self.angles), 25);
base.angles = self.angles;
base linkto(self);
while(!self attackButtonPressed() && !base.destroy)
{
trace = bullettrace(base.origin + (0,0,100), base.origin + (0,0,-100000), true, self);
if(distancesquared(trace["position"], base.origin) > 10 * 10)
{
base unlink();
orig = self.origin + maps\mp\_utility::vectorScale(anglestoforward(self.angles), 25);
base.origin = (orig[0], orig[1], trace["position"][2]);
base.angles = self.angles;
base linkto(self);
}
if(self.sessionstate != "playing")
base.destroy = 1;
wait .05;
}
self enableWeapon();
base unlink();
trace = bullettrace(base.origin + (0,0,10), base.origin + (0,0,-1000), false, base);
if(trace["surfacetype"] != "default")
base.origin = trace["position"];
head unlink();
middle unlink();
arm unlink();
head.origin = base.origin + (0,0,31);
middle.origin = base.origin + (0,0,24);
arm.origin = base.origin + (-5,0,29);
base setContents(1);
head setContents(1);
middle setContents(1);
head.startangles = head.angles;
arm.startangles = arm.angles;
middle.startangles = middle.angles;
arm thread followHead(head, middle);
degrees_per_second = 300;
range = 1000;
players = getentarray("player","classname");
allies = [];
for(i=0;i<players.size;i++)
{
if(players[i].pers["team"] == game["attackers"])
allies[allies.size] = players[i];
}
sentry_angle = cos(80); // 80 degrees to both sides
sentry_angle_turnback = cos(90); // if there is no one here - rotate back
if(!base.destroy)
{
hiderobj = maps\mp\gametypes\hns::getObjectiveNumber("hiders");
level.objectives_hiders[hiderobj] = "filled";
objective_add(hiderobj, "current", base.origin, "gfx/hud/hud@neutralobjective.dds");
objective_icon(hiderobj,"gfx/hud/hud@neutralobjective.dds");
objective_team(hiderobj, self.pers["team"]);
}
while(!base.destroy)
{
targets = []; // list of possible targets
while(!isDefined(target))
{
wait .05;
players = getentarray("player","classname");
targetsnear = true; // check if there is anyone close to being near the target
for(i=0;i<players.size;i++)
{
if(!isDefined(players[i]) || players[i].sessionstate != "playing" || players[i].health > players[i].maxhealth)
continue;
if((vectorDot(vectorNormalize(players[i].origin - head.origin), anglesToForward(head.startangles)) > sentry_angle)
&& distancesquared(head.origin, players[i].origin) < range * range
&& (vectortoangles(players[i].origin + (0,0,20) - middle.origin)[0] < 25
&& vectortoangles(players[i].origin + (0,0,20) - middle.origin)[0] > -25))
{
trace = bulletTrace(players[i].origin + (0,0,40), head.origin + (0,0,6), false, base);
if(distancesquared(trace["position"], head.origin + (0,0,6)) < 5 * 5)
targets[targets.size] = players[i];
}
//iprintlnbold(vectorDot(vectorNormalize(players[i].origin - head.origin), anglesToForward(head.startangles)));
if(vectorDot(vectorNormalize(players[i].origin - head.origin), anglesToForward(head.startangles)) < sentry_angle_turnback)
// no one near -- rotate target to startangles
targetsnear = false;
}
if(!targetsnear && head.angles != head.startangles)
{
if(head.angles[1] - head.startangles[1] > 300)
angles = 360 - (head.angles[1] - head.startangles[1]);
if(head.angles[1] - head.startangles[1] < 0)
angles = (head.angles[1] - head.startangles[1]) * -1;
else
angles = (head.angles[1] - head.startangles[1]);
time = angles / degrees_per_second;
middle rotateTo(middle.startangles, time);
head rotateTo(head.startangles, time);
head waittill("rotatedone");
}
if(targets.size >= 1)
health = 100;
for(i=0;i<targets.size;i++)
{
if(targets[i].health < health)
{
target = targets[i];
health = targets[i].health;
// iprintln("picked " + target.name + " ^7new hp: " + health);
}
}
}
while(isDefined(target) && target.sessionstate == "playing"
&& vectorDot(vectorNormalize(target.origin - head.origin), anglesToForward(head.startangles)) > sentry_angle && distancesquared(head.origin, target.origin) < range * range
&& ((!isDefined(oldtarget) && target.health < target.maxhealth) || (isDefined(oldtarget) && oldtarget.health <= oldtarget.maxhealth)))
{
if(!isDefined(oldtarget))
{
for(i=0;i<allies.size;i++)
{
if(isDefined(allies[i]) && allies[i].sessionstate == "playing" && distancesquared(allies[i].origin, target.origin) < 250 * 250)
{
oldtarget = target;
target = allies[i];
break;
}
}
}
else if((isDefined(oldtarget) && !isDefined(target)) || (isDefined(oldtarget) && distancesquared(target.origin, oldtarget.origin) > 250 * 250))
{
target = oldtarget;
oldtarget = undefined;
}
rotateAngles = vectortoangles(target.origin + (0,0,30) - middle.origin);
if(head.angles[1] - rotateAngles[1] > 300)
angles = 360 - (head.angles[1] - rotateAngles[1]);
if(head.angles[1] - rotateAngles[1] < 0)
angles = (head.angles[1] - rotateAngles[1]) * -1;
else
angles = (head.angles[1] - rotateAngles[1]);
if(angles > 300)
angles = 360 - angles;
time = angles / degrees_per_second;
if(time < .05)
time = 0.05;
middle rotateTo((0,rotateAngles[1],0), time);
head rotateTo((rotateAngles[0],rotateAngles[1],0), time);
head waittill("rotatedone");
traceorig = head.origin + maps\mp\_utility::vectorScale(anglestoforward(head.angles), range);
trace = bulletTrace(head.origin, traceorig, true, head);
if(isDefined(trace["entity"]) && trace["entity"] == target)
head thread Shoot(target);
else if(!isDefined(trace["entity"]) && (distancesquared(trace["position"], target.origin + (0,0,20)) < 10 * 10
|| distancesquared(trace["position"], target.origin + (0,0,40)) < 10 * 10
|| distancesquared(trace["position"], target.origin + (0,0,60)) < 10 * 10))
head thread Shoot(target);
if(head.angles[0] > 30 || head.angles[0] < -30)
{
angles = head.angles[1];
if(angles >= 360)
angles = 360 - angles;
time = (angles / degrees_per_second) + .1;
middle rotateTo((0,0,0), time);
head rotateTo((0,0,0), time);
head waittill("rotatedone");
target = undefined;
}
}
oldtarget = undefined;
target = undefined;
wait .05;
}
arm notify("stop following head");
head unlink();
if(isDefined(head.projectile))
head.projectile delete();
middle unlink();
playfx(level._fx_sntry_expl, base.origin);
base playSound("sentry_explode");
base hide();
middle delete();
arm delete();
head delete();
wait 3;
base delete();
self.hassentry = false;
}
Shoot(target)
{
head = self;
if(!isDefined(head.sentry_cooldown))
head.sentry_cooldown = 0;
if(!isDefined(head.projectile))
{
head.projectile = spawn("script_model",head.origin + (2,0,6));
wait .05;
head.projectile setModel("xmodel/health_small");
head.projectile.angles += (90,0,0);
}
if(head.sentry_cooldown == 0)
{
head.sentry_cooldown = 1;
if(target.pers["team"] == game["attackers"] && head.projectile.model == "xmodel/health_small")
head.projectile setModel("xmodel/bottle_medicine");
else if(target.pers["team"] == game["defenders"] && head.projectile.model == "xmodel/bottle_medicine")
head.projectile setModel("xmodel/health_small");
head.projectile show();
head.projectile.origin = head.origin + (2,0,6);
head.projectile moveTo(target.origin + (0,0,20), 0.1);
head.projectile show();
head.projectile.origin = head.origin + (2,0,6);
head.projectile moveTo(target.origin + (0,0,30), 0.1);
head playSound("thud1");
head playSound("thud2");
playFxOnTag(level._fx_orgnchck, head, "tag_flash");
head.projectile waittill("movedone");
if(target.pers["team"] == game["attackers"])
{
head.projectile playsound("sentry_glass_break");
playFx(level._fx_sntry_splsh, head.projectile.origin);
playFx(level._fx_sntry_glss, head.projectile.origin);
//iprintlnbold("derp");
oldhealth = target.health;
oldmaxhealth = target.maxhealth;
dir = target.origin + maps\mp\_utility::vectorScale(anglestoforward(vectortoangles(head.origin - target.origin)), 1);
dmg = 75;
for(a=0;a<13;a++)
{
target.health += dmg;
target doDamageMod(dmg, dir, "MOD_WATER");
}
target.health = oldhealth;
target.maxhealth = oldmaxhealth;
head.projectile hide();
wait .05;
head.sentry_cooldown = 0;
}
else if(target.pers["team"] == game["defenders"])
{
if((target.health + 6) > target.maxhealth)
target.health = target.maxhealth;
else
target.health += 6;
target iprintln("^2Current health: ^5" + target.health);
// iprintlnbold(target.name + "^7.health = " + target.health);
head.projectile playsound("health_pickup_small");
head.projectile hide();
wait .5;
head.sentry_cooldown = 0;
}
}
}
followHead(head, middle)
{
arm = self;
// iprintlnbold("follow head called");
arm endon("stop following head");
while(1)
{
wait .05;
arm.origin = middle.origin + maps\mp\_utility::vectorScale(anglestoforward(middle.angles), -6) + (0,0,5);
arm.angles = ((head.angles[0] + head.angles[0] * .7),head.angles[1],0);
}
}