Fix first-person view for hiders, fix hitbox/collision and restructure code.

- Moved disguise code into their own methods (setDisguiseModel, deleteDisguiseModel, updateDisguiseView). Thinking about moving into its own file to avoid overly complex GSC file.
- Introducing player.isThirdPerson in order to keep track of the player's view. This allows determining whether the disguiseEntity should be hidden from the player's view or not.
- Make the entity solid and correct the target damage so that players actually have the entity as a hitbox (watchDisguiseDamage). I tried to get hit markers to work properly but it's yet untested.
- Improved tracing code to ignore the disguise entity since that entity is now solid (has collision).
master
Icedream 2016-04-08 19:00:25 +02:00
parent 1e9a663a2e
commit 890c5c0184
1 changed files with 126 additions and 35 deletions

View File

@ -365,13 +365,7 @@ onPlayerKilled(eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHit
player = self;
// If victim was disguised, reset him
if (IsDefined(player.disguiseEntity))
{
player.disguiseEntity Delete();
if (IsDefined(game["hiders_changed_sound"]))
player PlaySound(game["hiders_changed_sound"]);
player Show();
}
player deleteDisguiseModel();
// Update spectator permissions
thread checkAllowSpectating();
@ -683,6 +677,93 @@ handleHider() {
}
}
setDisguiseModel(model, normalHealth)
{
logPrint("setDisguiseModel called");
player = self;
displayName = maps\mp\mods\_modellist::getDisplayName(model);
if (!IsDefined(player.disguiseEntity))
{
player Hide();
//player HideViewModel();
player.disguiseEntity = Spawn("script_model", player.origin);
//player.disguiseEntity LinkTo(player, "j_head", (0,0,0), (0,0,0));
player.disguiseEntity.team = player.team;
//player.disguiseEntity.pers["team"] = player.team;
player.disguiseEntity.owner = player.owner;
player.disguiseEntity Solid();
player.disguiseEntity SetCanDamage(true);
player thread watchDisguise("+melee");
player thread watchDisguiseDamage();
}
player.disguiseEntity SetModel(model);
player PingPlayer(); // flash on minimap for teammates
if (IsDefined(game["hiders_changed_sound"]))
player PlaySound(game["hiders_changed_sound"]);
if (IsDefined(normalHealth))
{
healthfrac = player.health / player.maxhealth;
newhealth = healthfrac * normalHealth;
player.health = newhealth;
player.maxhealth = normalHealth;
}
// Seems like changing model causes weapons to be reloaded
player TakeAllWeapons();
player updateDisguiseView();
//player SayTeam("(changed into " + displayName + ")");
player IPrintLnBold("^2You changed into ^4" + displayName);
}
deleteDisguiseModel()
{
logPrint("deleteDisguiseModel called");
player = self;
if (!IsDefined(player.disguiseEntity))
return;
player.disguiseEntity Delete();
if (IsDefined(game["hiders_changed_sound"]))
player PlaySound(game["hiders_changed_sound"]);
//player ShowViewModel();
player Show();
}
updateDisguiseView()
{
logPrint("updateDisguiseView called");
player = self;
// Do we even have an entity?
if (!IsDefined(player.disguiseEntity))
return;
// Hide from third-person view of player
if (player.isThirdPerson)
{
player.disguiseEntity ShowToPlayer(player);
}
else
{
player.disguiseEntity Hide();
foreach (tplayer in level.players)
{
if (tplayer != player)
player.disguiseEntity ShowToPlayer(tplayer);
}
}
}
/*
* Binds a player command to let the player change between first
* person view and third person view.
@ -696,6 +777,8 @@ enableThirdPersonSwitch(playerCommand, value) {
player endon("death");
player endon("disconnect");
player.isThirdPerson = value;
player notifyOnPlayerCommand("thirdpersonswitch_requested", playerCommand);
for (;;)
@ -705,6 +788,10 @@ enableThirdPersonSwitch(playerCommand, value) {
// toggle third person mode
value = !value;
player SetClientDvar("cg_thirdperson", value);
player.isThirdPerson = value;
player updateDisguiseView();
wait 0.5;
}
}
@ -737,7 +824,10 @@ enableModelChange(playerCommand) {
// Make a trace to the focused object
origin = (player GetOrigin()) + defaultOriginAdd;
trace = BulletTrace(origin, origin + anglestoforward(player getplayerangles()) * 1000000, false, player);
ignore = player;
if (IsDefined(player.disguiseEntity))
ignore = player.disguiseEntity;
trace = BulletTrace(origin, origin + anglestoforward(player getplayerangles()) * 1000000, false, ignore);
if (!IsDefined(trace) || !IsDefined(trace["entity"]) || !IsDefined(trace["entity"].model) || !IsDefined(trace["entity"].classname))
{
player IPrintLnBold("^1Nothing to change into here.");
@ -753,32 +843,9 @@ enableModelChange(playerCommand) {
player IPrintLnBold("^3You can't change into that!");
continue;
}
displayName = maps\mp\mods\_modellist::getDisplayName(trace["entity"].model);
healthfrac = player.health / player.maxhealth;
newhealth = healthfrac * (trace["entity"] GetNormalHealth());
if (!IsDefined(player.disguiseEntity))
{
player Hide();
player.disguiseEntity = Spawn("script_model", player.origin);
player thread watchDisguise("+melee");
}
player.disguiseEntity SetModel(trace["entity"].model);
player PingPlayer(); // flash on minimap for teammates
if (IsDefined(game["hiders_changed_sound"]))
player PlaySound(game["hiders_changed_sound"]);
player.health = newhealth;
player.maxhealth = trace["entity"] GetNormalHealth();
player setDisguiseModel(trace["entity"].model);
player SetClientDvar("cg_thirdpersonrange", 300);
// Seems like changing model causes weapons to be reloaded
player TakeAllWeapons();
//player SayTeam("(changed into " + displayName + ")");
player IPrintLnBold("^2You changed into ^4" + displayName);
}
}
@ -799,9 +866,6 @@ watchDisguise(angleLockingPlayerCommand)
player endon("death");
player endon("disconnect");
//player.disguiseEntity LinkTo(player, "j_head", (0,0,0), (0,0,0));
player.disguiseEntity NotSolid();
player.disguiseAnglesLocked = false;
player thread enableDisguiseModelAngleLocking(angleLockingPlayerCommand);
@ -817,6 +881,33 @@ watchDisguise(angleLockingPlayerCommand)
}
}
watchDisguiseDamage()
{
logPrint("watchDisguiseDamage called");
player = self;
level endon("game_ended");
player endon("death");
player endon("disconnect");
for (;;)
{
player.disguiseEntity waittill("damage", amount, attacker, direction_vec, point, type, modelName, tagName, partName, iDFlags);
attacker maps\mp\gametypes\_damagefeedback::updateDamageFeedback("standard");
// eInflictor = the entity that causes the damage (e.g. a claymore)
// eAttacker = the player that is attacking
// iDamage = the amount of damage to do
// sMeansOfDeath = string specifying the method of death (e.g. "MOD_PROJECTILE_SPLASH")
// sWeapon = string specifying the weapon used (e.g. "claymore_mp")
// damagepos = the position damage is coming from
// damagedir = the direction damage is moving in
player maps\mp\gametypes\_weapons::damageEnt(type, attacker, amount, "", modelName, point, direction_vec);
//player.health = player.disguiseEntity.health;
}
}
/*
* Enables locking the angles of the disguise model using a player
* command.