Improved Gibbable Corpses Tutorial, and "Semisolid"

Discuss programming in the QuakeC language.
Curt
Posts: 9
Joined: Sat Mar 26, 2011 1:59 pm
Location: Germany

Post by Curt »

Thanks Seven for clearing up, so

1.) competing with Lord Havoc seems not to be an option for me :)

2.) lost blood trails:
Thanks for uploading another version. But I didn't mean the trails ON the gibbed parts. I meant the trails of blood (spray, particles or in german: "Schweif") that "flies" behind them when you kick them. You integrated this in your version, so it works on the resulting gibs when the soldier is gibbed to death after shooting rockets to him, but NOT on the gibs who occur after he WAS dead already (so not on these resulting in this tutorial).

And so we come to the other difference between the two "sorts" of gibs:
I didn't mean that the moster's whole body "sinks" into the floor, only the gibs (mainly the torso) after he was a corpse, not when he gibs while living (rocket, explosive barrel).

Your code for the head seems plausible and logic for me too. It's (like in Lord Havoc's) a way to adapt all the monster .qc's to their belonging head-model and not the world.qc.

So there should be a way to get them working.

Greetings
CurtCocaine
Wazat
Posts: 771
Joined: Fri Oct 15, 2004 9:50 pm
Location: Middle 'o the desert, USA

Post by Wazat »

leileilol: If I remember right, in TF2 allies can walk through each other right? If so, yes you can support this using the semisolid feature. If each player has semisolid = "team1" or "team2", and you modify the find functions to search for self.semisolid instead of "y" (or in addition to it), then allies will pass right through each other as though they did not exist.

Firing weapons inside of or through an ally changes things though... Lightning and axes (and other tracehit weapons) won't work well while inside an ally, because a traceline starting inside an entity it does not ignore will ignore all non-bsp entities... If a player standing inside an ally fires spikes or rockets, then those will collide with the inside of his ally. Likewise firing rockets through an ally in front of you will not end well. :D

So it's sort-of-supported. :D


Seven & Curt:

Regarding throwing heads, you're on the right track. Here's how to do it. I apologize for not testing this first, it may have bugs, but I don't have much time today -- just enough to write this post. :)

You could simply pass the head model into CopyMonsterToBodyQue:
void() army_die10 =[ $death10, army_die10 ] { CopyMonsterToBodyQue(30, "progs/h_guard.mdl"); };

CopyMonsterToBodyQue's params would be modified to this:
void(float hp, string headmdl) CopyMonsterToBodyQue =
{
CopyToBodyQue(self, hp, headmdl);
self.model = ""; // hide real monster
self.think = SUB_Null; // don't repeat the last death frame for eternity (monsters)
};

Then edit CopyToBodyQue to take the head model:
void(entity ent, float hp, string headmdl) CopyToBodyQue =
{
... (snipped for brevity) ...

bodyque_head.solid = SOLID_SLIDEBOX;
bodyque_head.movetype = MOVETYPE_TOSS;
bodyque_head.netname = headmdl;

bodyque_head = bodyque_head.owner;
};

Also update the declarations of these functions in defs.qc to include the headmdl param.

Finally, edit corpse_die's ThrowHead call:
ThrowHead (self.netname, self.health);

That *should* work. Heh... let me know if there's problems. :)



I'm pleased to hear the old version of darkplaces works with axes and lightning. That means this may be a darkplaces issue and not one that necessarily affects all engines. Major load off of my mind! :D It does raise issues with darkplaces support though, and I don't want to cut DP out of the loop. Is LordHavoc still active? It would help to consult with him.

Also: Can anyone recommend a couple other engines (or several) that run happily in WinXP, especially one which simulates vanilla Quake rather well? I want to confirm that this feature works cross-engine and in vanilla Quake (which no longer runs for me). :) I think I'd like to try FTE for the quakeworld end of things.


I'm not familiar with that mod Curt, but I suspect you could still get the gibbable corpses working. If, for example, you called CopyMonsterToBodyQue after or instead of body_nonsolid in army_die10 etc, then that may work properly. I haven't gotten a chance to see the code -- my free time has been restricted lately.

I recommending following tutorials in fresh QC code until you understand how the tutorial works and what it's doing. It's fine to try to implement a tutorial in another mod or combine tutorials, but if you're not familiar with the mod's code then it gets tricky when there's collisions to resolve. :(
When my computer inevitably explodes and kills me, my cat inherits everything I own. He may be the only one capable of continuing my work.
leileilol
Posts: 2783
Joined: Fri Oct 15, 2004 3:23 am

Post by leileilol »

Wazat wrote:Also: Can anyone recommend a couple other engines (or several) that run happily in WinXP, especially one which simulates vanilla Quake rather well?
MH has this really cool 'DirectQ' engine!!!!! It tries to be Quake in DX9. It doesn't try to add modder features. It even has faithful waterwarp done by HLSL SHADER!!!! It's probably the most faithful quake port accellerated, the only things unfaithful about it are the optional options and the sexy new menu system.

There's also qbism's software engine but that stretches a bit out of vanilla territory. I have a software engine as well that's slightly more stable than WinQuake regarding WinXP and 7 because it just forces ddraw-lacking dib.

oh and of course, fitzquake is still updated.

Yeah I realize a 'chocolate quake' is missing. One thing that would help that matter is if anyone poked John Carmack to push out gpled 1.01 engine code (as well as gpled 1.06 progs code :P ). The engine, pre-1.07 has some important changes contrast to the released source, such as sound spatialization, fadescreen, pausable sound buffer, a proper djgpp makefile, etc...
i should not be here
Curt
Posts: 9
Joined: Sat Mar 26, 2011 1:59 pm
Location: Germany

Post by Curt »

Thanks again Wazat!

I included your parameters without errors.

But now no head from soldier is there after gibbing too and even not when dead after hit by rocket (what worked before)
Seven
Posts: 301
Joined: Sat Oct 06, 2007 8:49 pm
Location: Germany

Post by Seven »

Hello Wazat,

everything works like a charm now ! :D
(You can edit your 1st post with the new params).
I am glad, that I could help you a little with the head gib issue.


Curt,
the problem must be on your side.
Be sure to follow every step that Wazat described.
And dont forget to edit/extend your functions in defs.qc with the new params.

Also the gib trail (=Schweif) that you have problems with, works without a problem.
I made some screenshots for you to see the new effects.
Flying kickable gib with blood trail:
Image

Working ThrowHead call:
Image
It is a hell of a blood bath, but you requested bloody gibs... so dont complain ;)

Kind regards,
Seven
ooppee
Posts: 70
Joined: Thu Oct 28, 2010 2:57 am

Post by ooppee »

I will def have to apply this :)

One possible bug did come to mind. Does this set the corpse itself to non-solid if a player is standing in it or just make the player pass through it while still remaining solid?
Reason I ask is a possible bug can be if a player is standing in the entity, it's then non-solid to other players. Which then can cause a issue with the team red/blue walls. A blue could pass through if a Red is standing in the entity.
Curt
Posts: 9
Joined: Sat Mar 26, 2011 1:59 pm
Location: Germany

Post by Curt »

Hi Seven.

Could you please upload your modified files?
Now I have the head again, but without any effects...

I can't get it to work (so few knowledge in programming :()

Thank you all guys!!
Wazat
Posts: 771
Joined: Fri Oct 15, 2004 9:50 pm
Location: Middle 'o the desert, USA

Post by Wazat »

ooppee wrote:I will def have to apply this :)

One possible bug did come to mind. Does this set the corpse itself to non-solid if a player is standing in it or just make the player pass through it while still remaining solid?
Reason I ask is a possible bug can be if a player is standing in the entity, it's then non-solid to other players. Which then can cause a issue with the team red/blue walls. A blue could pass through if a Red is standing in the entity.
That's the great part of this system: the semisolid objects are only non-solid between each player's PlayerPreThink and PlayerPostThink. Each player always runs his pre think before his movement code, and then always follows that with his post think. This means the solid of each semisolid entity switches back and forth once per player per frame. Other players don't get to move or run physics while I'm running my movement, so other players won't be able to move through a semisolid wall even if I'm standing right inside of it.

Seven:
I'm very pleased to hear it worked well. I'll update the main tutorial post soon. I also need to run in some engines other than DP to confirm which bugs occur in each.

BTW, have you tried multiplayer? Load up this mod in dm6 and kill yourself with a rocket. Then go find your corpse and try to shoot it with a shotgun and/or rocket. If it works for you then it must be my version of Darkplaces, which would be a major load off of my mind. :D

Curt:
I have no idea what would cause that. O_o Those changes to the tutorial shouldn't have affected normal gibbing, unless you changed the wrong areas of code.

By effects do you mean the blood trails behind gibs (model flag)? Staining walls (engine feature)?
When my computer inevitably explodes and kills me, my cat inherits everything I own. He may be the only one capable of continuing my work.
Wazat
Posts: 771
Joined: Fri Oct 15, 2004 9:50 pm
Location: Middle 'o the desert, USA

Post by Wazat »

I updated the original post with those changes, for new users of the tutorial. Let me know if you guys have any trouble with it.

New adventure for you advanced coders:
Start a new project with fresh QC. Follow the tutorial, ignoring the corpse stuff (basically we want to call SemisolidPreThink and SemisolidPostThink and have .semisolid and .oldSolid defined). Try changing SemisolidPreThink and post think to this:


void() SemisolidPreThink =
{
if(self.semisolid == "")
return;

local entity e;

e = find (world, semisolid, self.semisolid);
while(e)
{
if(e != self)
{
e.oldSolid = e.solid;
if(e.solid == SOLID_BSP)
e.movetype = MOVETYPE_NONE;
e.solid = SOLID_NOT;
e = find (e, semisolid, self.semisolid);
}
}
};

void() SemisolidPostThink =
{
if(self.semisolid == "")
return;

// Semisolid: Make all semisolid objects solid again, now that the player's move code is done.
local entity e;
e = find (world, semisolid, self.semisolid);
while(e)
{
if(e.oldSolid != -1 && e != self)
{
e.solid = e.oldSolid;
e.oldSolid = -1;
if(e.solid == SOLID_BSP)
e.movetype = MOVETYPE_PUSH;
}
e = find (e, semisolid, self.semisolid);
}
};


This will cause players to move through each other, if you set everyone's semisolid to something similar like "player". What's better? Setting their semisolid to their team. For this test and for the sake of laziness, we could probably do that in SemisolidPreThink, in fact. (normally in a team game like CTF and TF, we would set the player's .semisolid when we set his .team_no).

void() SemisolidPreThink =
{

// Super-lazy team-setting test code
if(self.team == 5)
self.semisolid = "team_red";
else if(self.team == 14)
self.semisolid = "team_blue";
else
self.semisolid = "";

if(self.semisolid == "")
return;

...

Next step? Create or edit a map. If creating, turn some walls into func_wall entities. If editing, turn some existing walls or doors into func_wall entities. Then set their "semisolid" = "team_red" or "team_blue".

Make sure the texture of the wall is red or blue so it's clear to the players they own it and can move through... though you could do some secret areas like this. Remember, if they shoot a shotgun at this wall, that won't give it away the way func_illusion would! You can also build traps for the other team this way, such as a semisolid floor that allies can traverse but enemies fall through.

Compile and try your map in this new mod. Allies will now move through each other, and through their team's walls. Try as they might, enemies are not getting through those walls. And unlike with a team door, a griefer can't hold the door open for enemies -- there's no "open".
Note that in my simple example code, we're using the raw .team (and changing it every frame). Players could change their team back and forth to bypass team walls! Thankfully, in a real teamplay game we would have safer team choosing mechanics and the problem goes away. If I remember right, TF and CTF have .team_no determine the team instead of player colors, and they set the player's .skin so his chosen colors and .team don't matter at all.

Have fun tinkering with this. Once you've got it implemented in stock quake, maybe try grafting it into 3Wave CTF or TF (for advanced modders only, I'm not going to be very available to debug it for you). As I keep saying, this will be a fully-fledged tutorial at some point too. Consider this a deposit. :D
When my computer inevitably explodes and kills me, my cat inherits everything I own. He may be the only one capable of continuing my work.
Curt
Posts: 9
Joined: Sat Mar 26, 2011 1:59 pm
Location: Germany

Post by Curt »

Hello Wazat.

Thanks for upgrading your code you made before.
I tried it, but have the same effect as before:
1. head of "shoot to death by rocket" soldier is kickable,
2. head of soldier who was a corpse before, is not kickable.

And yes by "blood trails" i meant the trails of blood behind gibs. This only works in the above described case 1. and not in 2.

So it works for me like in picture number 2 made by seven when shooting the exposive barrel, but not with the soldier in episode 1, level 1 (picture 1) when only having the shotgun.

Strange for me. The defs.qc I upgraded too like I did before.

The client.qc changes look like theese:

void() PlayerPreThink =
{
local float mspeed, aspeed;
local float r;


...

{
self.weapon = W_BestWeapon ();
W_SetCurrentAmmo ();
}


SemisolidPreThink();
};

and

void() PlayerPostThink =
{


SemisolidPostThink();

local float mspeed, aspeed;
local float r;


Are they correct too?

Greets
CurtCocaine
Curt
Posts: 9
Joined: Sat Mar 26, 2011 1:59 pm
Location: Germany

Post by Curt »

I forgot one thing:

In world.qc inside your upgraded
tutorial, the line

void(entity ent, float hp, hp, headmdl) CopyToBodyQue =

maybe should look like this

void(entity ent, float hp, string headmdl) CopyToBodyQue =

like you wrote before.
Seven
Posts: 301
Joined: Sat Oct 06, 2007 8:49 pm
Location: Germany

Post by Seven »

@ Wazat

I just tried multiplayer, as you requested above.
Unfortunately it does not work (using DP 3rd february 2011 build).



@ Curt

Sorry for my late reply.
Wazats TUT works perfect as it is (for single player ;) )
His TUT has nothing to do with kickable gibs !
The problem, that you encouter at the moment is the fact that you want to implement his gibbable corpse into my mod compilation.
Just like Wazat said in one of his above posts, it is rather difficult to combine two or more features (escpecially when they are dealing with the same code functions).

But dont worry, there is light at the end of the tunnel :)
I already found a solution for keeping the kickable gibs together with Wazats new feature (gibbable corpse).
I am currently fine tuning it and add a couple new enhancements as well:
- Your described problem with the gibs, that are too deep in the floor
- Improve the velocity of the gibs, so its more "realistic"
- ... (suprise)


Because of the fact, that these issues are not directly related to Wazats fantastic code,
I suggest that we continue our discussion in the german forum.
Cause it is off-topic in my opinion.
I will release a "Update.pk3" soon. So please be patient.

Thank you.

Kind regards,
Seven
Curt
Posts: 9
Joined: Sat Mar 26, 2011 1:59 pm
Location: Germany

Post by Curt »

Thank you very much Seven for making this clear to me. So the problem results in combining your's and Wazat's GREATwork.

And yes, I agree, that this becomes off-topic..., sorry for that!

I'm glad that you will have a surpise :D

Greetings
CurtCocaine
Wazat
Posts: 771
Joined: Fri Oct 15, 2004 9:50 pm
Location: Middle 'o the desert, USA

Post by Wazat »

Cool, glad you've got it worked out.

As for multiplayer, I'm just going to have to fight with it for a while until I figure it out. Thank you for testing!
When my computer inevitably explodes and kills me, my cat inherits everything I own. He may be the only one capable of continuing my work.
Seven
Posts: 301
Joined: Sat Oct 06, 2007 8:49 pm
Location: Germany

Post by Seven »

Hello Wazat,

there is one last issue left, which I cannot solve.
May I ask for your support:

The size of the dead bodies are too tall (high).

When you kill a soldier for example and its body lies on the floor.
Now you stay around 2 meters away from him and aim straight forward (look straight forward)
and shoot (lets say with the nailgun, because it has no damage spread) you will hit the soldiers body and it will be gibbed.

You dont aim towards the body as I described. You aim much higher (=straight forward) !
But you still hit the bodys "box" and it will be gibbed.

Big disadvantage is:
You cannot kill other monsters, that are running at you, because your bullets and nails will hit the dead soldiers body on the floor. :(

Please tell me a way to scale your setsize down (only the height). So that you really have to aim DOWN to the dead soldier to gib his body.
And that you still can shoot "over" the dead body and hit other monsters, without gibbing the body.
Lets say, when you look straight forward, you should not hit the body. You should aim down to hit the body.


I tried to edit your: setsize (bodyque_head, min, max);
But wasnt able to change the behaviour.

Thank you very much for your help.

Kind regards,
Seven
Post Reply