GetCharacterUnit is troubling me and pinging weapon [Solved]
Posted: Sun Jun 22, 2014 9:03 pm
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:
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.
Re: GetCharacterUnit is troubling me
Posted: Sun Jun 22, 2014 9:06 pm
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".
Re: GetCharacterUnit is troubling me
Posted: Sun Jun 22, 2014 9:43 pm
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.
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.
Re: GetCharacterUnit is troubling me
Posted: Sun Jun 22, 2014 9:48 pm
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.
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?
Re: GetCharacterUnit is troubling me
Posted: Sun Jun 22, 2014 11:27 pm
by razac920
Give them all unique names based on an increasing counter, same as the pings. Post what you have now, though
Re: GetCharacterUnit is troubling me
Posted: Mon Jun 23, 2014 12:46 am
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.
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.
Re: GetCharacterUnit is troubling me
Posted: Mon Jun 23, 2014 10:48 am
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.
Re: GetCharacterUnit is troubling me
Posted: Mon Jun 23, 2014 12:15 pm
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?
Re: GetCharacterUnit is troubling me
Posted: Mon Jun 23, 2014 1:00 pm
by LRKfm946
Just give it an absurd damage/push radius like 300 or something.
Re: GetCharacterUnit is troubling me
Posted: Mon Jun 23, 2014 1:10 pm
by Kingpin
Yeah. Look at the nuke on Red Vs Blue
Re: GetCharacterUnit is troubling me
Posted: Mon Jun 23, 2014 10:11 pm
by Noobasaurus
I meant through buildings, sorry.
Re: GetCharacterUnit is troubling me
Posted: Thu Jun 26, 2014 6:03 pm
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.
Re: GetCharacterUnit is troubling me
Posted: Thu Jun 26, 2014 6:33 pm
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.
Re: GetCharacterUnit is troubling me
Posted: Thu Jun 26, 2014 7:05 pm
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.
Re: GetCharacterUnit is troubling me
Posted: Thu Jun 26, 2014 7:11 pm
by [RDH]Zerted
Sounds like checking to see which units get hit by a buff.
Re: GetCharacterUnit is troubling me
Posted: Thu Jun 26, 2014 7:20 pm
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.
Re: GetCharacterUnit is troubling me
Posted: Thu Jun 26, 2014 7:28 pm
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 ), then process all the units within that area.
Re: GetCharacterUnit is troubling me
Posted: Fri Jun 27, 2014 11:58 am
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]
Re: GetCharacterUnit is troubling me
Posted: Fri Jun 27, 2014 12:29 pm
by LRKfm946
Try adding each unit to a list when they spawn (another thing I did in hunger games ). 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.
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