#679 posted by Kinn on 2012/03/04 00:26:36
you could always make your own menu/screen.
Nah that would be huge overkill for what I'd be doing. Besides, I realised what I originally had in mind is probably just a silly gimmick anyway, I'm gonna shove it to one side for now.
Brushmodel Texture Swapping
#680 posted by Kinn on 2012/03/06 16:36:20
So let's say I have a brushmodel and i want the texture it wears to change according to events. From what I understand, all I can do is this:
- have an (optionally) animated looping texture with frames following the +0blah, +1blah etc. convention, then change to a non-animated image with the +ablah naming convention, by setting frame = 1 on the bmodel.
What I'd like to do is have 4 different non-animated textures, and i can just swap between any one of these images.
I assume it's not possible without doing crap like having 4 seperate bmodels and hiding 3 of them (or I guess just using 2 if i abuse +0blah and +ablah).
Or is it?
Also I don't wanna use a .mdl
#681 posted by necros on 2012/03/06 19:40:49
yeah, you'd need multiple bmodels.
the frame stuff is hard coded, unfortunately and treats +0 ... +9 as a frame group, hence frame = 0 and 1 only.
Ok Cheers
#682 posted by Kinn on 2012/03/06 20:06:44
I'll move to plan B which is to do the effect with sprites. Lighting won't be ideal, but i think i can get away with it.
Lightning Bolts
#683 posted by Kinn on 2012/03/07 17:52:54
so, spawning a lightning bolt:
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
WriteEntity (MSG_BROADCAST, self);
WriteCoord (MSG_BROADCAST, org_x);
WriteCoord (MSG_BROADCAST, org_y);
WriteCoord (MSG_BROADCAST, org_z);
WriteCoord (MSG_BROADCAST, self.enemy_pos_x);
WriteCoord (MSG_BROADCAST, self.enemy_pos_y);
WriteCoord (MSG_BROADCAST, self.enemy_pos_z);
no matter what i set the vector org to, it only spawns the bolt starting from the entity origin - basically the calls for setting the starting point are ignored - is that how quake works?
Only If The Given Entity Is A Player, Otherwise It Works As Expected
#684 posted by czg on 2012/03/07 18:40:50
Ah I See
#685 posted by Kinn on 2012/03/07 18:44:17
sneaky, sneeaky quake :}
#686 posted by necros on 2012/03/07 21:10:16
note also that you can only have one lightning bolt per entity.
these days i build my lightning bolts manually out of edicts because every engine besides fq/qs tries to be cute and put in effects. :(
Stealing Weapons
#687 posted by Mike Woodham on 2012/03/10 15:29:42
What do I need to consider when trying to implement something like this:-
void() steal_weapons_use
{
other = activator;
if (self.spawnflags & SPAWNFLAG_SHOTGUN)
{
other.items = self.items - (self.items & IT_SHOTGUN);
other.ammo_shells = 0;
other.weapon = IT_AXE;
}
};
Or am I running in treacle here?
I can see it taking the weapon and the shells, but it breaks with an error in the weapon_cycle command.
Activator's Other Self
#688 posted by Preach on 2012/03/10 16:03:07
There seem to be three entities in this story, and I'm having to guess who is who:
self: presumed to be an entity added to the map as a trigger perhaps?
activator: if the above is correct then activator is whoever set off the trigger called self
other: known to be the same entity as activator
The first thing seems to be that other is unnecessary, which makes the function confusing. If we replace other with activator we get:
void() steal_weapons_use
{
�if (self.spawnflags & SPAWNFLAG_SHOTGUN)
�{
��activator.items = self.items - (self.items & IT_SHOTGUN);
��activator.ammo_shells = 0;
��activator.weapon = IT_AXE;
�}
};
We can then see more easily what might be dangerous. We only act if self has the spawnflag for removing shotguns. On that condition, we then set the activator's items to be equal to self's items with item shotgun removed. I'm pretty sure that this line should be referring to activator all the way through.
Thanks Preach
#689 posted by Mike Woodham on 2012/03/10 16:20:21
I didn't see the wood for the trees.
#690 posted by necros on 2012/03/10 18:36:38
don't know if you trimmed things out for clarity, but you should probably add a quick check:
if (!activator.flags & FL_CLIENT)
return;
just to avoid any possible problems in the case of monsters some how activating it.
Spawn()
#691 posted by necros on 2012/03/10 19:10:01
is spawn() completely reliable? is there any time where it can fail and not create anything? or it creates an entity but the entity somehow gets lost? maybe if you're spawning many entities in the same think?
Invalidation
#692 posted by Preach on 2012/03/10 19:24:36
In the standard implementation spawn only fails if there are no free edicts, which produces a game-ending error. As long as it doesn't error out, it returns some entity and as far as I can see there's no way this entity could fail to be a clean slot. But that entity might be more familiar than it seems.
Edict slots aren't allowed to be reused with 0.5 seconds of an entity being removed from a slot*. However, if a reference to an removed entity persisted longer than that it could end up creating a reference invalidly relating to a newly spawned entity. Could a stale reference be somehow responsible for your issue?
*This is not true for the first two seconds of the map, in order to not waste lots of slots if entities are loaded from the map but removed by the qc straight away.
#693 posted by necros on 2012/03/10 19:39:50
right, i totally forgot about that! i still had that .doNotRemove trick from before and i found that the entity is indeed being removed by something else. thanks, i'm off to track that down. :P
And
#694 posted by necros on 2012/03/10 19:55:18
it's done. thanks! turns out i had some sloppy linked list clean up. i was clearing out the list but forgot to clean up the head link. :P
Not Qc...
#695 posted by necros on 2012/03/17 06:23:27
this is java, but it's more of a conceptual thing...
finally started working on the inheritance aspect of fgd files for my fgd<>def converter thingy...
essentially, i have multiple lists of objects which represent key/val pairs. these lists can have duplicate entries from base classes that an entity inherits from.
eg: you have 'monster_army' which inherits target/targetname fields from the base 'monster' class.
what i'd need to do is, on demand, collapse the multiple lists into a single one.
ie: when i 'get' a list element, i should iterate through a single apparent list:
monster_army has the fields: (inherits from 'monster')
0: B
1: C
2: D
monster has the fields:
0: E
1: C
2: A
should look like:
0: B
1: C
2: D
3: E
4: A
(duplicate C in 'monster' is ignored because 'monster_army' already had that field)
i can work through the logic of building a new list myself, but the problem is that there are many times where i need to iterate through the (final) list, so every time i .get(i), i'll have to rebuild this list which feels wrong.
is there maybe some more complex data structure that would work better for this? i'm thinking maybe trees due to their non-linear nature?
unfortunately, i've never really learnt data structures more complex than a simple linked list. :S
or maybe there's some absurdly easy solution and i'm just not seeing it.
#696 posted by ericw on 2012/03/17 07:13:59
you should be able to get away without building the final list. I'd store the key/value pairs in a hash table instead of a list of key/value pair objects, and have an object for each "quakec class". then set up a recursive get() function which first checks the object-being-called's key/value pair mapping (e.g. Grunt), and if the requested key wasn't found, call the get() method on the superclass (e.g. Monster) (or return null if there is no superclass - so for a key requested that isn't in either Grunt or Monster).
something like this:
class EntityClass {
EntityClass superclass;
HashMap<String, Object> fields;
Object get(String key){
if (fields.containsKey(key)) {
// the requested key is stored directly in our class
return fields.get(key);
} else {
// the requested key is not in our class, try searching
// our superclass.
if (superclass != null) {
return superclass.get(key);
} else {
return null;
}
}
}
}
hope that helps..
btw here's the javadoc for HashMap.
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/HashMap.html
#697 posted by czg on 2012/03/17 08:55:39
If you're only storing the keys and no value with them, I'd recommend using a Set instead of a Map. You should read up on the Java collections framework, as in most cases it already solves a problem for you.
To Lob Or Not To Lob, That Is The Question
#698 posted by Mike Woodham on 2012/03/17 10:30:47
I have a Lavaman in my map (FMB_BDG) and he does a good job except I notice that there is a point where I can stand and the missiles go over my head. If I move closer, they hit me and if I move further away they hit me up to a point where they drop in front of me.
I can see that MOVETYPE_BOUNCE seems to affect the 'lobiness', and velocity_z seems to affect the height of the lob. What is affecting the gap between the hit range and the no-hit range? I am not too worried about the far distance as the missile falling short is not an issue because I can contain the player, but the over-me-'ead-john lob is not good.
If I change to MOVETYPE_MISSILE and ignore velocity_z I get a straight line missile a la roquette, but this is not good where the player is higher or lower than the Lavaman as dodging becomes too easy.
Are there any good web-sites that explain weapon behaviour (in short sentences with no long words, and mathematics that any four year old can understand)?
Ericw++
This is also how I would do it. Note though that the keys will be unordered. If you need them to be sorted in some way, consider a SortedHashMap, e.g. TreeMap.
Hash Maps
#700 posted by Preach on 2012/03/17 13:43:35
I think everyone is right on Necros' problem that using sets/maps is the way to go, but I think that the implimentations so far have been backwards: So far we've had how to check if a specific element is a member of one or more sets, but what necros is looking for is the ability to list all the unique elements in a collection of sets, omitting duplicates.
The key to doing this is set union. Have a set of properties for the monster, a set of properties for the grunt. When it comes time to output the combined list, use the addAll method to create combined lists which omit duplicates.
Lobbed Projectiles
#701 posted by Preach on 2012/03/17 14:15:16
The most important mathematical idea for understanding projectiles is being able to imagine the movement in just one direction, to ignore all the other motion.
In particular imagining just how the height changes is important, but it's also the most difficult. It's also quite hard to deal with the idea of projectiles that can go north-south and east-west.
So lets just fix our boss facing north, and think about the horizontal movement of the projectile first. It turns out that the northwards movement of the projectile is exactly the same for MOVETYPE_MISSILE and MOVETYPE_BOUNCE. We fire it with some speed to the north, and it keeps going at a constant speed. Most importantly it takes the same amount of time to come in line with the player.
Now we can think about how the height changes. The MOVETYPE_BOUNCE has exactly the same behaviour as a falling player. Measure the amount of time the MOVETYPE_MISSILE takes to hit the player. If a player could fall from the height the projectile is thrown at down to the height of the target player in that time then the MOVETYPE_BOUNCE will score a hit, otherwise the shot will sail over his head.
So what can we do if it does sail over his head? Well, one trick is to start the projectile with a negative velocity_z, so it is already moving downwards. This will make it fall further during the flight and hopefully hit the player. Alternatively we can reduce the speed it travels north at. This will give a longer flight time and so longer for it to fall. We could combine these two ideas if needed.
Calculating exactly how much adjustment is needed is where you have an unavoidable level of fairly grizzly maths. I'm sure I wrote something about this particular problems but I can't remember if I finished it and ever posted it. You can probably get a good enough function by just measuring the threshold at which projectiles start going overhead, and applying one of the two above fixes when the player is that close(using trial and improvment to get values that work well).
Thanks Preach
#702 posted by Mike Woodham on 2012/03/17 16:12:46
So, with a zero velocity_z, does the projectile fall from the horizontal at a predetermined and constant rate i.e. no acceleration? And if so, do we (you) know what that rate is?
I'm just thinking that a series of If Thens could adjust the velocity_z and velocity to get to the target in the given time. (Not sure what the player would think of that?)
Basically
#703 posted by JPL on 2012/03/17 16:13:52
z is a parabolic function, depending of initial velocity, the initial direction/angle and the weight of the projectile, so to say gravity...
x and y can be linear it eases calculation, unless you want to add some wind effects, etc..
Wikipedia gives some mathematics clue for this: http://en.wikipedia.org/wiki/Trajectory
Experiment !
|