News | Forum | People | FAQ | Links | Search | Register | Log in
Coding Help
This is a counterpart to the "Mapping Help" thread. If you need help with QuakeC coding, or questions about how to do some engine modification, this is the place for you! We've got a few coders here on the forum and hopefully someone knows the answer.
First | Previous | Next | Last
 
ne_ruins was amazing indeed. Thanks for reminding me. I do wonder why nobody ever followed up using that as a base to make even more content. But indeed individual monster behaviors and reactions to the players and each other. How far was that taken in quake over the years is what I wonder. 
Bots 
Are the most complex, but players complain when enemies have similar behaviours.

Bosses are complex, and the enemies of Nehara had a lot behind how they thought and moved.

Ultimately, ITS is probably the most complex, although that was a pure navigation system to some extent. 
 
I tried a couple of times to write a tutorial to let people integrate the ne_ruins navigation system, but it always ended up being really complicated and needing hooks into a few other places :( 
Ne_ruins 
I only played ne_ruins once, back when it was first released, but I remember those zombies and I still think they are one of best Quake custom monsters ever. 
Necros Must Try Again! :) 
 
QMaster 
I did what you said, and while the BFG orb doesn't crash, this is what happens:

*Picking up the BFG removes from the inventory all shotguns, puts in the nailgun, and all others inventory fuckery.
*The orb still fires at an arbitrary point in the map, probably a monster's waypoint beyond a wall.
*After firing, the upcoming weapon animation don't come up.
*When the orb collides with the world, only the particle explosion happen. No sound, no explosion sprite.
*When the orb collides with a monster, it changes direction.
*The proximity lightning which happens when the orb's active and an enemy is near it, it only happens when both the orb and the player are close to each other, and the lightning comes from the player.
*If the orb collides with an enemy and i'm too close to it, I die.

With all of this stuff happening, I'm just gonna post all of the qc files that mentions the BFG9500, since I just have absolutely no idea what's really going on, nor a single hint on how to fix it.
weapons.qc: http://pastebin.com/gW3P42yr
items.qc: http://pastebin.com/3u1ddwZM
defs.qc: http://pastebin.com/nV7xYWxH
player.qc: http://pastebin.com/DdyRggCm 
Item Erasure 
As someone has already mentioned in the post above, your IT_BFG9500 value is too large, and that's what's removing the other items. Because you've got other weapons you're running out of space. One way out would be to use the slot from IT_SUPERHEALTH instead, it doesn't appear on the HUD when you set that, so you can safely remove it from the megahealth code.

You might also want to look at the mission pack 2 code, which uses an extra field called items2 to store more of the player inventory. There is extra support in the HUD for items2 if you use the mission pack command line switches as well. 
Wrong Direction Of Attack 
The BFG shot goes in the wrong direction because of this line:

BFGShot(org, self.enemy.origin - self.origin);


It's important to know at this point which entity is self. It is the player. The problem is that the player does not have an enemy, because that's for the AI entities. So what's the default value if you don't have AI? The world!

This means that self.enemy.origin - self.origin is calculating the direction to the centre of the world. Instead you want to fire in the direction that the player is facing. When you do makevectors (self.v_angle); the direction the player faces is stored in a global called v_forward. So the fixes are:

1) Replace
makevectors (self.angles);
with
makevectors (self.v_angle);

2) Replace
BFGShot(org, self.enemy.origin - self.origin);
with
BFGShot(org, v_forward); 
One Thought At A Time 
Now we come to

bfgsphere.nextthink = time + 0.1;
bfgsphere.think = bfgshot1;

self.nextthink = time + 0.1;
self.think = bfg_ball_think;

bfgsphere.nextthink = time + 5;
bfgsphere.think = SUB_Remove;

This segment of code is well intentioned but quite confused. The first thing to ask again is which entity is self? It is still the player! So the first step towards getting this working would be to change those from self to bfgsphere:

bfgsphere.nextthink = time + 0.1;
bfgsphere.think = bfgshot1;

bfgsphere.nextthink = time + 0.1;
bfgsphere.think = bfg_ball_think;

bfgsphere.nextthink = time + 5;
bfgsphere.think = SUB_Remove;

Now I ask what is stored in bfgsphere.think at the end of these 6 lines? It is SUB_Remove, because that last line overwrites the previous code which set it to bfg_ball_think, which itself overwrote bfgshot1.

I'm not going to post the solution yet, because this has tripped you up before Daya, and I wanna make sure the problem makes sense before we look at solving it. I fear in the past I've gone too fast over this issue which is why it's recurred... 
The Thinks Must Be In Decreasing Order, Correct? 
This is what I did (and the other stuff too) while changing bfg_ball_think's think back to 0.3.

After all that, the projectile almost works: the orb animates properly, it fires at the direction I want it to fire, it produces the so-called blast after impact.

However the continuous lightning strikes from the orb still doesn't happen, colliding with the world without hitting an enemy don't spawn particles and says this: http://image.noelshack.com/fichiers/2016/05/1454319929-razenkrauft20160201104422-00.jpg , colliding with an enemy that gets gibbed still sends the orb to another direction, none of the explosion sprites (both orb impact and blast) show-up, when the blast happens the particle effect that should appear on the enemy appears instead at the origin point of the blast, and when I'm too close to the impact I get targeted by the blast, even though the code should avoid that.

Here's the code in weapons.qc once again, as I've added some more stuff in addition to yours: http://pastebin.com/EAV4PayU 
 
local entity bfgexpl;
bfgexpl.movetype = MOVETYPE_NONE;

that's an assignment to world.
remember that world is equivelent to null or nothing (and that locals default to nothing, or at least whatever 0 means), thus assignments to its fields are considered a bug - and this case is certainly no exception. 
Did Some Modifications 
Notably for both touch and explosion functions, where I looked at the rocket launcher's touch and explosion functions.

http://pastebin.com/KDRyZmG3

The explosion itself now spawns the particles (and the error messages don't show up this time), but the sprites still don't show up. 
Only One Think 
No, you can only have one think. Just one. When you set the second think, it replaces the first one. The first one will never happen. There is no queue. You can only have one think. The only think which is coming out of your code is SUB_Remove because the others have been replaced before they have a chance to happen. An entity can only have one think, and it is always going to be the one you assigned most recently. Only one. 
SUB_ 
One think to rule them, one think to find them,
one think to bring them and in the dark places bind them. 
So With That 
I removed the thinks except for bfgshot1 which commands the orb's animation. I tried to call bfg_ball_think directly on each frame of the orb's sprite but still no dice.

The reason I'm not hiring a coder is because time zones are a complete bitch and I want to have complete control on the mod. 
Timing 
When you changed it to only call bfgshot1, did you also change it so that the only nextthink line is:

bfgsphere.nextthink = time + 0.1;

If you left the line

bfgsphere.nextthink = time + 5;

in then it'll only kick in 5 seconds later, and it'll collide with a wall first! 
The Only Remaining Next.think And Think Fork Remaining Is 
bfgsphere.nextthink = time + 0.1;
bfgsphere.think = bfgshot1;

But by replacing some code in bfg_ball_think:

org = self.origin + '0 0 16';

head = findradius(self.origin, 250);

The continuous lightning now works on the enemies, but myself as well.
Normally "if(head != self)" should avoid that, but it gets ignored, somehow.

(Also the sprites still don't spawn, and the blast sound effect happens at the orb's impact, not at the enemies targeted, as wanted) 
Issues With Bfg_ball_think 
So there's a bit of explanation to do with the magic entity self which may explain why this code didn't work:

local entity lightcont;
org = lightcont.origin + '0 0 16';

but your modification did, and why if(self != head) is failing to protect you.

self is a variable which stores an entity, but which entity it stores changes as the engine checks different things. When the player is launching attacks, then self is the player. But when other entities are running their think functions, then they become the new self. So we need to always remember who is calling a function to reason about self.

During bfg_ball_think what is self? The ball of death, not the player! Aside: how about lightcont? Well, you never assign anything to it in your function, so it is always equal to the world entity. This is why that wasn't working before you modified it.

Anyway, back to self. The problem is that we want to get back to the player who fired it, but if the ball is self then where is the player? Luckily, all the way back when we created the ball we had a line
bfgsphere.owner = self;
At that time self was the player and bfgsphere was the ball, so now that self is the ball, self.owner is the player we stored! So we change the check to

if(head != self.owner)

and the player will be unharmed.

Can you post a current BFG_Blast and related functions? This had issues in the old incarnation but you may have fixed or changed them... 
This Is All Rather Interesting! 
Back to the IT_BFG9500 issue with messing up the inventory. The way the IT_'s work is by turning bit values on or off (0 or 1) in the single float variable self.items.

So a player with no items has a self.items of 00000000000000000000000 in binary (23 slots {mantissa for you super nerds} because of the way quake stores memory, the other bits are for exponent and a bit for positive/negative) QuakeC sees it as a float of 0 or whatever number the IT_'s add to unless you use the bitwise operator & to see if bit IT_something is turned on.

If you have the axe, shotgun and supershotgun self.items, in binary is 00010000000000011000000 and float is 4099.

This is the conversion of the number 4099 into binary. 4099 = 4096 + 1 + 2 (axe + shotgun + dbshotgun). If you subtract the supershotgun from self.items (4099 - 2) then the binary of self.items is 00010000000000001000000

We turned off one bit. The problem is that 16777216 needs 25 bits to store it. It is too large. So it causes your bits to get all wrong and shifted when you try to add it using the bitwise | operator, hence the inventory loses stuff and gains stuff. I wouldn't even use 8388608 either since it needs 24 bits. I ran into that same problem. If you use 65536 instead, it should work fine, so long as you remove the calls that the megahealth uses in items.qc 
Also, 
Note that by using the set of all integer values that equal powers of 2, the sum of any n values is inherently unique from any other sum of n values. 
Two Things Fixed At Once 
First, the continuous lightning now works properly (even though it should spawn at the center of the sphere) :
http://image.noelshack.com/fichiers/2016/05/1454576771-schlossherr20160204095929-00.jpg

And the BFG doesn't mess with the inventory (I think that was because I assignated it with the Mega Health slot, as previously stated by Preach):
http://image.noelshack.com/fichiers/2016/05/1454576771-schlossherr20160204100351-00.jpg

I'm really happy it functions properly now. All there is to fix now is spawning the explosion and blast sprites properly and make the lightning start from the center of the sphere. 
Forgot To Put It In The Code 
Daya 
Good work man :) 
Lightning Start Pos 
Maybe this line should be changed:
org = self.origin + '0 0 16';

To: org = self.origin; 
That Did It! 
One last thing I forgot to mention before, aside from the sprites problem, how do I make the sphere not change direction when it hits a monster that gets gibbed? 
First | Previous | Next | Last
You must be logged in to post in this thread.
Website copyright © 2002-2024 John Fitzgibbons. All posts are copyright their respective authors.