GetCharacterUnit is troubling me and pinging weapon [Solved]

In this forum you will find and post information regarding the modding of Star Wars Battlefront 2. DO NOT POST MOD IDEAS/REQUESTS.

Moderator: Moderators

Noobasaurus
Droid Pilot Assassin
Droid Pilot Assassin
Posts: 2006
Joined: Tue Aug 17, 2010 5:56 pm

GetCharacterUnit is troubling me and pinging weapon [Solved]

Post by Noobasaurus »

Basically what the title says. I've been trying a ton of stuff but nothing is working. When the person is hit by the weapon, I want an invisible entity to spawn and then a marker to appear on that entity. Here's what I have:

Code: Select all

	ping = OnObjectDamage(function(object, damager)
		if GetObjectLastHitWeaponClass(object) == "cis_weap_inf_wrist_rocket" then
			CreateEntity("com_item_null", CreateMatrix(3.14159,0,1,0,0,0,1,GetEntityMatrix(GetCharacterUnit(object))), "ping")
			MapAddEntityMarker(ping, "hud_objective_icon", 5.0, 1, "BLUE", true, true, true)
		end
    end)
    
    
With the code above I get the error below:

Code: Select all

Message Severity: 3
C:\Battlefront2\main\Battlefront2\Source\LuaHelper.cpp(312)
CallProc failed: bad argument #1 to `GetCharacterUnit' (number expected, got userdata)
stack traceback:
	[C]: in function `GetCharacterUnit'
	(none): in function <(none):25>

I realize that it doesn't recognize the data from the object. I just need to know how to get it into a format that it likes and get it all working. Thanks in advance.
Last edited by Noobasaurus on Mon Jun 30, 2014 2:35 am, edited 3 times in total.
razac920
2nd Lieutenant
2nd Lieutenant
Posts: 365
Joined: Sun Jan 16, 2011 12:42 am

Re: GetCharacterUnit is troubling me

Post by razac920 »

GetCharacterUnit inputs a character (i.e. number) and outputs an object. You are trying to give it an object when you already have what you want. Just replace GetCharacterUnit(object) with "object".
Noobasaurus
Droid Pilot Assassin
Droid Pilot Assassin
Posts: 2006
Joined: Tue Aug 17, 2010 5:56 pm

Re: GetCharacterUnit is troubling me

Post by Noobasaurus »

That makes a ton of sense! Thank you! That will help me a ton.

After I did that, it crashed after freezing for a few seconds. I changed a few things around and came up with this.

Code: Select all

	ping = OnObjectDamage(function(object, damager)
		if GetObjectLastHitWeaponClass(object) == "cis_weap_inf_wrist_rocket" then
			if GetObjectTeam(object) == 2 then
				CreateEntity("com_item_null", GetEntityMatrix(object), "ping")
				MapAddEntityMarker(ping, "hud_objective_icon", 5.0, 1, "YELLOW", true, true, true)
			end
		end
    end)
    
There aren't any errors but no results either.
razac920
2nd Lieutenant
2nd Lieutenant
Posts: 365
Joined: Sun Jan 16, 2011 12:42 am

Re: GetCharacterUnit is troubling me

Post by razac920 »

Try putting ping in quotation marks in MapAddEntityMarker, also I think you should number these pings in case you want more than one going simultaneously.

Code: Select all

   pingcount = 0;
   pingmaker = OnObjectDamage(function(object, damager)
      if object and GetObjectLastHitWeaponClass(object) == "cis_weap_inf_wrist_rocket" and GetObjectTeam(object) == 2 then
          pingcount = pingcount + 1;
          CreateEntity("com_item_null", GetEntityMatrix(object), "ping"..pingcount)
          MapAddEntityMarker("ping"..pingcount, "hud_objective_icon", 5.0, 1, "YELLOW", true, true, true)
      end
    end)
Noobasaurus
Droid Pilot Assassin
Droid Pilot Assassin
Posts: 2006
Joined: Tue Aug 17, 2010 5:56 pm

Re: GetCharacterUnit is troubling me

Post by Noobasaurus »

I got this error:

Code: Select all

Message Severity: 2
C:\Battlefront2\main\Battlefront2\Source\LuaCallbacks_Mission.cpp(642)
Entity "ping1" is EntityProp, but need GameObject
EDIT: Got it working. Looked it up, com_item_null needed to be something other than a prop. Thank you so much!

EDIT2: I'm trying to make it so each marker lasts 15 seconds until disappearing. I tried doing it with some timers but I got confused on how to make unique timers every time the event happens. Any ideas?
razac920
2nd Lieutenant
2nd Lieutenant
Posts: 365
Joined: Sun Jan 16, 2011 12:42 am

Re: GetCharacterUnit is troubling me

Post by razac920 »

Give them all unique names based on an increasing counter, same as the pings. Post what you have now, though
Noobasaurus
Droid Pilot Assassin
Droid Pilot Assassin
Posts: 2006
Joined: Tue Aug 17, 2010 5:56 pm

Re: GetCharacterUnit is troubling me

Post by Noobasaurus »

Well, I was trying to rename the timer every time the pingcount increased, but that doesn't seem like it'll work. I want it to make a new timer and run it every time the event happens. After each timer is over, it removes the corresponding marker.

Code: Select all

	pingtimer = nil
    pingcount = 0;
	pingmaker = OnObjectDamage(function(object, damager)
		if object and GetObjectLastHitWeaponClass(object) == "cis_weap_inf_wrist_rocket" then
			if GetObjectTeam(object) == 2 then
				ShowMessageText("level.0CW.ping")
				ShowMessageText("level.0CW.pong")
				pingcount = pingcount + 1;
				CreateEntity("com_item_null", GetEntityMatrix(object), "ping"..pingcount)
				MapAddEntityMarker("ping"..pingcount, "hud_objective_icon1", 5.0, 1, "BLUE", true, true, true)
				if pingcount == 1 then
					pingtimer = CreateTimer("pingtimer"..pingcount)
					SetTimerValue("pingtimer"..pingcount, 15)
					StartTimer("pingtimer"..pingcount)
				end
				OnTimerElapse(
					function(timer)
						MapRemoveEntityMarker("ping"..pingcount)
					end,
				"pingtimer"..pingcount
				)
					
			end
		end
    end)
	
I get an error from the OnTimerElapse. I'm assuming it's because it doesn't like how I ended it, with the "ping"..pingcount. I'm trying to make a new timer called "pingtimer" with a number after it every time the event happens. Or do I have to create all of the timers beforehand and then have each of them start when the pingcount reaches a certain number? I can do that, but I'm thinking that there's a better way.
User avatar
Locutus
1st Lieutenant
1st Lieutenant
Posts: 420
Joined: Fri Jun 04, 2010 10:08 am
Projects :: Stargate Battlefront Pegasus
Location: Germany
Contact:

Re: GetCharacterUnit is troubling me

Post by Locutus »

Just thinking out loud here but maybe you can solve this differently:
Make a looping timer that occurs every second. Additionally create a list that contains the seconds left for each object.
Decrement the value for every object every cycle and remove the marker if one of the values reaches zero.
Noobasaurus
Droid Pilot Assassin
Droid Pilot Assassin
Posts: 2006
Joined: Tue Aug 17, 2010 5:56 pm

Re: GetCharacterUnit is troubling me

Post by Noobasaurus »

I got it working with a giant list of timer and stuff. Multiple markers work at once too so that's nice.

One last question so I don't make a new topic. Is there any way to make an explosion hit everyone on the map?
LRKfm946
Master Sergeant
Master Sergeant
Posts: 163
Joined: Sun Feb 02, 2014 6:13 pm
Projects :: Battlefront II Hunger Games
Games I'm Playing :: SWBF2 BF3
Contact:

Re: GetCharacterUnit is troubling me

Post by LRKfm946 »

Just give it an absurd damage/push radius like 300 or something.
User avatar
Kingpin
Jedi
Jedi
Posts: 1096
Joined: Fri Sep 13, 2013 7:09 pm
Projects :: The Sith Wars II
Location: Denver, CO
Contact:

Re: GetCharacterUnit is troubling me

Post by Kingpin »

Yeah. Look at the nuke on Red Vs Blue :P
Noobasaurus
Droid Pilot Assassin
Droid Pilot Assassin
Posts: 2006
Joined: Tue Aug 17, 2010 5:56 pm

Re: GetCharacterUnit is troubling me

Post by Noobasaurus »

I meant through buildings, sorry.
User avatar
[RDH]Zerted
Gametoast Staff
Gametoast Staff
Posts: 2982
Joined: Sun Feb 26, 2006 7:36 am
Projects :: Bos Wars AI - a RTS game
Games I'm Playing :: SWBF2 and Bos Wars
xbox live or psn: No gamertag set
Location: USA
Contact:

Re: GetCharacterUnit is troubling me

Post by [RDH]Zerted »

Locutus wrote:Just thinking out loud here but maybe you can solve this differently:
Make a looping timer that occurs every second. Additionally create a list that contains the seconds left for each object.
Decrement the value for every object every cycle and remove the marker if one of the values reaches zero.
That is the better way to do it, but there's one more optimization you can make to make it optimal. Instead of running the timer every second, reset the timer to the time of the next expiring marker. When you're out of markers you stop the timer. When you add a marker, you start the timer if it isn't already running. There's no need to worry about the timer waiting too long because any markers you add to the list will expire after whatever marker was already in there and the timer will trigger for the earlier marker.
LRKfm946
Master Sergeant
Master Sergeant
Posts: 163
Joined: Sun Feb 02, 2014 6:13 pm
Projects :: Battlefront II Hunger Games
Games I'm Playing :: SWBF2 BF3
Contact:

Re: GetCharacterUnit is troubling me

Post by LRKfm946 »

Noobasaurus wrote:I meant through buildings, sorry.
Not with the explosion itself, but you could do it via LUA. Idk if you're planning on making it a weapon for units to use, or a planted bomb, but you could have some object(s) in a place(s) where it will always get hit by the explosion, and give it 1 health, and when that object is destroyed, kill all the units that need to be killed via LUA.
Noobasaurus
Droid Pilot Assassin
Droid Pilot Assassin
Posts: 2006
Joined: Tue Aug 17, 2010 5:56 pm

Re: GetCharacterUnit is troubling me

Post by Noobasaurus »

Basically when I fire the weapon I want to get the information of all the units nearby. If they're on a certain team then stuff happens.
User avatar
[RDH]Zerted
Gametoast Staff
Gametoast Staff
Posts: 2982
Joined: Sun Feb 26, 2006 7:36 am
Projects :: Bos Wars AI - a RTS game
Games I'm Playing :: SWBF2 and Bos Wars
xbox live or psn: No gamertag set
Location: USA
Contact:

Re: GetCharacterUnit is troubling me

Post by [RDH]Zerted »

Sounds like checking to see which units get hit by a buff.
Noobasaurus
Droid Pilot Assassin
Droid Pilot Assassin
Posts: 2006
Joined: Tue Aug 17, 2010 5:56 pm

Re: GetCharacterUnit is troubling me

Post by Noobasaurus »

An explosion, yes. I just need it to hit everyone.

Or an alternative solution to somehow check all the units around the explosion. I don't know about that, though.
LRKfm946
Master Sergeant
Master Sergeant
Posts: 163
Joined: Sun Feb 02, 2014 6:13 pm
Projects :: Battlefront II Hunger Games
Games I'm Playing :: SWBF2 BF3
Contact:

Re: GetCharacterUnit is troubling me

Post by LRKfm946 »

You could try checking through each unit alive and seeing if it's within a certain distance from you using GetWorldPosition() (that's what I used for the camper killer :P), then process all the units within that area.
Noobasaurus
Droid Pilot Assassin
Droid Pilot Assassin
Posts: 2006
Joined: Tue Aug 17, 2010 5:56 pm

Re: GetCharacterUnit is troubling me

Post by Noobasaurus »

I'll do that (and maybe take a peek at your camper killer)!

Although how would you trigger it? Is there an event that checks if a weapon is used?

EDIT: Nevermind, I can do the same thing as before.
EDIT2: I tried to make it so if a person on team 2 is within 300 units of the person who shot the weapon then the stuff happens. I'm having trouble getting the data of the people on team 2 who are alive. Here's what I have currently:
Hidden/Spoiler:
[code]
pingcount = 0;
pingmaker = OnObjectDamage(function(object, damager)
-- if GetObjectLastHitWeaponClass(object) == "imp_weap_inf_wrist_rocket" and GetObjectTeam(object) == 2 then
if GetObjectLastHitWeaponClass(object) == "imp_weap_inf_wrist_rocket" and GetWorldPosition(damager) and GetWorldPosition(object) then
sender = GetWorldPosition(damager)
receiver = GetWorldPosition(GetTeamMember(2, 5))
if sender[1] < (receiver[1]+150) and sender[1] > (receiver[1]-150) and sender[2] > (receiver[2]-150) and sender[2] < (receiver[2]+150) and sender[3] > (receiver[3]-150) and sender[3] < (receiver[3]+150) then
print(GetWorldPosition(damager))
print(GetWorldPosition(object))
ShowMessageText("level.0CW.ping")
pingcount = pingcount + 1;
CreateEntity("com_item_null", GetEntityMatrix(object), "ping"..pingcount)
MapAddEntityMarker("ping"..pingcount, "hud_objective_icon1", 5.0, 1, "BLUE", true, true, true)
if pingcount == 1 then
StartTimer(ping1)
end
...more repetitive stuff below...[/code]
LRKfm946
Master Sergeant
Master Sergeant
Posts: 163
Joined: Sun Feb 02, 2014 6:13 pm
Projects :: Battlefront II Hunger Games
Games I'm Playing :: SWBF2 BF3
Contact:

Re: GetCharacterUnit is troubling me

Post by LRKfm946 »

Try adding each unit to a list when they spawn (another thing I did in hunger games :P). Then when you use the weapon, iterate through the list and find which units are within 300 units of you. You may also want to remove them when they die.

Code: Select all

unitsAlive = {}

unitSpawn = OnCharacterSpawn(
    function(character)
        playerInfo = {playerUnit = GetCharacterUnit(character) --, this comma is only necessary if you add more info
                           --any other info you want to record
                         }
        unitsAlive[character] = playerInfo
    end
)


--When the weapon is fired: 
minChange = 300 --or whatever distance you want to search
x, y, z = GetWorldPosition(characterThatFiredTheWeapon)
playerPos = {x, y, z}

for i, v in pairs(unitsAlive) do

    local x, y, z = GetWorldPosition(unit)
    searchingPos = {x, y, z}

    if math.abs(searchingPos[1] - playerPos[1]) < minChange
	and math.abs(searchingPos[2] - playerPos[2]) < minChange
	and math.abs(searchingPos[3] - playerPos[3]) < minChange then

        --Process the unit however you wish
    end
end
Post Reply