Issue with didhitscript for weapon

mersox

Active member
Hey guys. I'm having a problem with my TMNT mod. Before I get to the problem, let me explain what it is that I am trying to achieve.

I have a couple of weapons scattered in some of the levels of the game. Not every character is able to grab these weapons, though. So in that sense, we have two groups of playable characters: the ones that can carry weapons (A), and the ones that cannot (B).

The way the game plays right now, without any fancy scripts in the way of weapons, if a character from the group "A" punches a weapon, he/she will get it. But if a character of group "B" attemps to grab a weapon, nothing will happen and the weapon will stay on the ground.

This works fine except it's not really user friendly. I have seen some youtube videos where players don't know how to grab a weapon, which is even more confusing if your char can't carry a weapon to begin with.

So i wanted to change this so that:
1. a character type "A" can get a weapon by merely walking to it, no attacks necessary
2. if a char tyoe "B" walks to a weapon, he/she will display a "I can't take this" sign of some sort.

Alright so what I have been trying to do is to add a didhitscript to my weapon. For now I am just focusing on
- getting a char to get weapon by just touch (this I have achieved)
- not letting chars type B to get the weapon (this I am having trouble with)

Forget about the "I can't take this" sign thing for now, as I believe I can accomplish that by myself later. How can I stop chars type B from getting the weapon? This is the didhitscript I am using:

void main()
{

  int iSnd = loadsample("data/sounds/(tmnt2/motor01.wav");
  void self = getlocalvar("self");
  //void opponent = getentityproperty(self, "opponent");
void opponent = getlocalvar("damagetaker");
void oppmodel = getentityproperty(opponent,"model");

if (oppmodel == "leo" || oppmodel == "raph" || oppmodel == "mike" || oppmodel == "don"){

changeentityproperty(opponent, "weapon", 2);
performattack(opponent, openborconstant("ANI_get"));
playsample(iSnd, 0, openborvariant("effectvol"), openborvariant("effectvol"), 120, 0); //itemup sfx
}


}

That "if" part of the script is being ignored by the engine.
 
Who is using this script? The weapon on the floor or the player? It should be on the weapon (but you can put it on the player too, just changing the model name).

What I use is:

Code:
void self = getlocalvar("self"); //get the self var
char Name = getentityproperty(self,"name"); // get target's name

Then I check the "name" of the item and change the animation. In your case, it would be the damagetake (if on the weapon) or the self (if you put this code on the player)

edit: oh, by the way, I think you should use defaultname and not model. Model will track the current name of the model, while defaultmodel will track the original name of the model.

Take a look at my topic here and see if it helps you: http://www.chronocrash.com/forum/index.php?topic=3115.0


Try this:

Code:
void main()
{

  int iSnd = loadsample("data/sounds/(tmnt2/motor01.wav");
  void self = getlocalvar("self");
  //void opponent = getentityproperty(self, "opponent");
void opponent = getlocalvar("damagetaker");
void oppmodel = getentityproperty(opponent,"defaultname");

if (oppmodel == "leo" || oppmodel == "raph" || oppmodel == "mike" || oppmodel == "don"){

changeentityproperty(opponent, "weapon", 2);
performattack(opponent, openborconstant("ANI_get"));
playsample(iSnd, 0, openborvariant("effectvol"), openborvariant("effectvol"), 120, 0); //itemup sfx
}


}

edit: by the way, I forgot to say to you - you should care about what happens if an entity from group B gets the item, because the engine has an internal routine for item get.
 
Thank you for your quick reply. I'll give it a try.

Right now the script is on the weapon, not the character.
 
O Ilusionista said:
I've modified your code with defaultname, try it.

I did, but it's not working still. I am playing as a character other than the four in the script, and it still takes the item.

I have even tried changing the weapon type from "item" to "none", and still no luck.

This is the weapon header:

name mother_mouser
type item
subtype weapon
weapnum 2
shadow 0
typeshot 1
jumpheight  4
nolife        1
noatflash 1
nodieblink 0

didhitscript data/scripts/didhitscriptmouser.c
animationscript data/scripts/script.c

anim spawn
loop 0
offset 19 55
delay 900
bbox 11 12 36 43
itembox 09 10 3 3
frame data/chars/foot/mother_mouser/item.png
 
Maybe because the code only handle the ones who can get it, not the ones who can't ;) I forgot to tell this to you in the first reply.

Include a else and make a code for the ones which can't grab it. They will still grab the item, but you set the default weapon and spawn the item back.
 
Maybe i am wrong but didhit should only activate if they grabbed the weapon right.

I have a idea to tackle this from another angle let any player pick up the weapon then have your did hit script check if the oppmodel is from group B if true them use damage entity script to give them a little slap with 0 damage and drop the weapon.  You could use a non standard attack number so they play a custom animation too.
 
msmalik681 said:
Maybe i am wrong but didhit should only activate if they grabbed the weapon right.

I have a idea to tackle this from another angle let any player pick up the weapon then have your did hit script check if the oppmodel is from group B if true them use damage entity script to give them a little slap with 0 damage and drop the weapon.  You could use a non standard attack number so they play a custom animation too.

Yeah, that was kinda what I said above. He needs to tell the engine what happens if an entity from group B gets the weapon, because the engine has an internal routine for getting itens.

Kinda like this:

Code:
void main()
{

  int iSnd = loadsample("data/sounds/(tmnt2/motor01.wav");
  void self = getlocalvar("self");
  //void opponent = getentityproperty(self, "opponent");
void opponent = getlocalvar("damagetaker");
void oppmodel = getentityproperty(opponent,"defaultname");

if (oppmodel == "leo" || oppmodel == "raph" || oppmodel == "mike" || oppmodel == "don"){

changeentityproperty(opponent, "weapon", 2);
performattack(opponent, openborconstant("ANI_get"));
playsample(iSnd, 0, openborvariant("effectvol"), openborvariant("effectvol"), 120, 0); //itemup sfx
}

else 
{
changeentityproperty(opponent, "weapon", 0);
performattack(opponent, openborconstant("ANI_CANT")); // animation to use if the player cant get the item

}

}

 
By the way, keep in mind this code will destroy the item you gott. If you want to make the item to appear again, you would need to store the item name into a entityvar in damagetaker and spawn it back.
 
O Ilusionista said:
Maybe because the code only handle the ones who can get it, not the ones who can't ;) I forgot to tell this to you in the first reply.

Include a else and make a code for the ones which can't grab it. They will still grab the item, but you set the default weapon and spawn the item back.


msmalik681 said:
Maybe i am wrong but didhit should only activate if they grabbed the weapon right.

I have a idea to tackle this from another angle let any player pick up the weapon then have your did hit script check if the oppmodel is from group B if true them use damage entity script to give them a little slap with 0 damage and drop the weapon.  You could use a non standard attack number so they play a custom animation too.


I tried both of these great ideas, but character still grabs the weapon.
I tried using a damageentity the character doesn't drop the item. Sure I could spawn a new weapon were the previous one was grabbed, but I still have the isue of the character holding an invisible weapon, which he drops when he's attacked.

I think this would be easier if there was a way to PREVENT characters to pick up a weapon with didhitscript.
 
mersox said:
I think this would be easier if there was a way to PREVENT characters to pick up a weapon with didhitscript.

That's not possible, because the event of being "attacked" by an item is what triggers the script in the first place. There are a couple of ways you can handle this. Personally I'd use the didhitscript to play the collecting entity's GET animation, and set an entity var on that entity that has the model's name. That's it - the didhitscript is done.

didhitexample:
Code:
#ifndef DC_PICKUP 

#define DC_PICKUP       1
#define DC_PICKUP_GET   openborconstant("ANI_GET")

#define DC_PICKUP_FALSE 0
#define DC_PICKUP_TRUE  1

#endif // DC_PICKUP

void main()
{
    void    self        = getlocalvar("self");
    void    target      = getlocalvar("damagetaker");
    int     valid       = DC_PICKUP_FALSE;
    char    model       = "";
    
    // Get valid status of target's
    // GET animation.
    valid = getentityproperty(target, "animvalid", DC_PICKUP_GET);
    
    if(valid)
    {
        model = getentityproperty(self, "defaultname");
        
        // Record model name of self onto entity.
        setentityvar(target, "DC_PICKUP_WEAPON", model);
    
        // Force target to play GET animation.
        performattack(target, DC_PICKUP_GET, DC_PICKUP_FALSE);
    }
}

From there, the collecting entity's GET animation would handle behavior via animation script. If the entity could use the weapon, then they'd pick it up and go on. If they couldn't, then the GET would trigger their "I can't do it", respawn the weapon model (you have the weapon model's name from variable we set in the didhitscript) , and set the entity back to whatever model it was before taking the item. In either case, you delete the variable that was set by didhitscript.

This way, not only could you handle all the cases you were talking about, but it wouldn't ever need to be modified if you added more entities, because the entity itself would be the one controlling the reaction behavior.

DC
 
I tried both of these great ideas, but character still grabs the weapon.
I think this would be easier if there was a way to PREVENT characters to pick up a weapon with didhitscript.
No. As DC explained before, the item grab is what triggers internally the script. Check the script DC posted, its follow the same logic I explained but in a better way :)

@DC, what "#ifndef" means? And what, exactyl, trigger the "If the entity could use the weapon, then they'd pick it up and go on. If they couldn't, then the GET would trigger their "I can't do it" ?
 
O Ilusionista said:
@DC, what "#ifndef" means?

#ifndef <marco> means, "If <macro> is not defined, then do everything in this block." You'll notice that in that block, you immediately define said macro. Looks stupid on the surface, but it's utterly invaluable.

Let's say you have a set of macros (#define) that a lot of function libraries depend on, so they all #include the macro file. That's good practice. But what happens if you then #include one more of those libraries in another file? Because the libraries are each including the same set of macros, you now have a conflict. Encapsulating the macros in an #ifndef block handles that because it tells the compiler "no, I already have those macros defined, don't try to do it again". It's a good habit to get into.

For that matter, it's not just macros - you can encapsulate anything you want - but in practice, it usually only matters for macros.

And what, exactyl, trigger the "If the entity could use the weapon, then they'd pick it up and go on. If they couldn't, then the GET would trigger their "I can't do it" ?

The entity itself. That's the beauty of it. All the didhitscript does is trigger the entity's GET animation and store its own name on the entity for use by other scripts. Each individual entity can then behave however you like by setting up its GET animation accordingly. One might pick up the weapon, another puts it down, another, I dunno, commits suicide. And even better, the same entity could behave differently based on a weapon it was already holding, since the weapon it was already holding can have an alternate GET.

DC
 
The entity itself. That's the beauty of it. All the didhitscript does is trigger the entity's GET animation and store its own name on the entity for use by other scripts. Each individual entity can then behave however you like by setting up its GET animation accordingly.
Ahhh, now I get it. And if the entity (damagetaker) doesn't have GET anim, it won't trigger at all, right? Even if the subtype is touch?

 
O Ilusionista said:
The entity itself. That's the beauty of it. All the didhitscript does is trigger the entity's GET animation and store its own name on the entity for use by other scripts. Each individual entity can then behave however you like by setting up its GET animation accordingly.
Ahhh, now I get it. And if the entity (damagetaker) doesn't have GET anim, it won't trigger at all, right? Even if the subtype is touch?

The script won't trigger, but the engine's normal behavior would still occur, so weapon would be collected if the entity has a slot for it. I just put the animation verification in as a safety check so you wouldn't get kicked out with an error if the entity didn't have GET animation.

DC
 
Alright I was able to digest all the information given. I'm a bit slow for this stuff :P

Damon Caskey] ...and set the entity back to whatever model it was before taking the item. [/quote] But you see said:
Each individual entity can then behave however you like by setting up its GET animation accordingly. One might pick up the weapon, another puts it down, another, I dunno, commits suicide.

THIS is what I need! How do you tell the char to but the weapon down? I mean, is there a way?

Sorry for all the confusion.
 
As it is now, a character than is not supposed to grab weapons, grabs it anyway.
As we explained, this is what will happens. You can't nullify this. The character will get the weapon then...

One might pick up the weapon, another puts it down, another,
This. You need to tell the engine what will it should do, because the didhitscript will happens anyway.

THIS is what I need! How do you tell the char to but the weapon down? I mean, is there a way?
Yes. Take a look at DC's code:

Code:
       setentityvar(target, "DC_PICKUP_WEAPON", model);

The character which is getting the weapon (the item's target) has now a entityvar called DC_PICKUP_WEAPON with the value of the model of what it got.

So, you can use spawn01 function with that value on the character GET animation (I am writing this on my phone and I can't check it right now):

@script
void self = getlocalvar("self");
char iWeapon = getentityvar(self, "DC_PICKUP_WEAPON");

if (frame==1)
{
spawn01("DC_PICKUP_WEAPON", 0, 0, 0);
}
@end_script
 
O Ilusionista said:
As it is now, a character than is not supposed to grab weapons, grabs it anyway.
As we explained, this is what will happens. You can't nullify this. The character will get the weapon then...

One might pick up the weapon, another puts it down, another,
This. You need to tell the engine what will it should do, because the didhitscript will happens anyway.

THIS is what I need! How do you tell the char to but the weapon down? I mean, is there a way?
Yes. Take a look at DC's code:

Code:
       setentityvar(target, "DC_PICKUP_WEAPON", model);

The character which is getting the weapon (the item's target) has now a entityvar called DC_PICKUP_WEAPON with the value of the model of what it got.

So, you can use spawn01 function with that value on the character GET animation (I am writing this on my phone and I can't check it right now):

@script
void self = getlocalvar("self");
char iWeapon = getentityvar(self, "DC_PICKUP_WEAPON");

if (frame==1)
{
spawn01("DC_PICKUP_WEAPON", 0, 0, 0);
}
@end_script

OK OK thanks, let me try that. Sorry.

EDIT: Yeah, no, sorry. We're back at the same spot. We are recreating the weapon on the floor, we are not getting rid of the one that "target" picked up.

Unless I'm missing something?

Again, sorry for being such a pain.
 
EDIT: Yeah, no, sorry. We're back at the same spot. We are recreating the weapon on the floor, we are not getting rid of the one that "target" picked up.

In fact, no. We are spawning the weapon close to the target (0,0,0). Have you tried to change this position?
And its okay, we are here to help.
 
Back
Top Bottom