Jump to content

Recommended Posts

I want to increase the range of the "give" action so that players can give each other items from across the screen. I found this code in actions.lua:

    GIVETOPLAYER = Action({ priority=3, canforce=true, rangecheckfn=DefaultRangeCheck }),
    GIVEALLTOPLAYER = Action({ priority=3, canforce=true, rangecheckfn=DefaultRangeCheck }),

how do I modify it from modmain.lua?

local range = 80
local function NewRangeCheck(doer, target)
    if target == nil then
        return
    end
    local target_x, target_y, target_z = target.Transform:GetWorldPosition()
    local doer_x, doer_y, doer_z = doer.Transform:GetWorldPosition()
    local dst = distsq(target_x, target_z, doer_x, doer_z)
	print(dst)
    return dst <= 80
end

local function _ActionRange(action)
	GLOBAL.ACTIONS[action].rangecheckfn = NewRangeCheck
	GLOBAL.ACTIONS[action].distance = range
end
_ActionRange"GIVE"
_ActionRange"GIVETOPLAYER"
_ActionRange"GIVEALLTOPLAYER"

not confident in this but i think it works.

I think it's since actions are constantly defined (aka they can be accessed from the main menu)  and can be updated dynamically that a AddPost fn was unnecessary and never added to modutil. There's only AddAction and AddComponentAction  (for creating new actions).

Edited by oregu

I've messed around a bit and it looks like "GLOBAL.ACTIONS[action].distance = range" is carrying everything. The function never actually gets called. Here's the code now:

GLOBAL.ACTIONS.GIVETOPLAYER.instant = true
GLOBAL.ACTIONS.GIVEALLTOPLAYER.instant = true

local STRINGS = GLOBAL.STRINGS
local GENERIC = STRINGS.CHARACTERS.GENERIC.DESCRIBE
local WILLOW = STRINGS.CHARACTERS.WILLOW.DESCRIBE
local WOLFGANG = STRINGS.CHARACTERS.WOLFGANG.DESCRIBE
local WENDY = STRINGS.CHARACTERS.WENDY.DESCRIBE
local WX78 = STRINGS.CHARACTERS.WX78.DESCRIBE
local WICKERBOTTOM = STRINGS.CHARACTERS.WICKERBOTTOM.DESCRIBE
local WOODIE = STRINGS.CHARACTERS.WOODIE.DESCRIBE
local MAXWELL = STRINGS.CHARACTERS.WAXWELL.DESCRIBE
local WIGFRID = STRINGS.CHARACTERS.WATHGRITHR.DESCRIBE
local WEBBER = STRINGS.CHARACTERS.WEBBER.DESCRIBE
local WINONA = STRINGS.CHARACTERS.WINONA.DESCRIBE
local WARLY = STRINGS.CHARACTERS.WARLY.DESCRIBE
local WORTOX = STRINGS.CHARACTERS.WORTOX.DESCRIBE
local WORMWOOD = STRINGS.CHARACTERS.WORMWOOD.DESCRIBE
local WURT = STRINGS.CHARACTERS.WURT.DESCRIBE
local WALTER = STRINGS.CHARACTERS.WALTER.DESCRIBE
local WANDA = STRINGS.CHARACTERS.WANDA.DESCRIBE

GENERIC.GOTSOMETHINGFORYOU = "I have something to give you."
WILLOW.GOTSOMETHINGFORYOU = "Hope you like it!"
WOLFGANG.GOTSOMETHINGFORYOU = "Take gift from Wolfgang!"
WENDY.GOTSOMETHINGFORYOU = "Just take it."
WX78.GOTSOMETHINGFORYOU = "DELIVERY RECEIVED"
WICKERBOTTOM.GOTSOMETHINGFORYOU = "Take this, dear."
WOODIE.GOTSOMETHINGFORYOU = "Just be grateful."
MAXWELL.GOTSOMETHINGFORYOU = "Take this."
WIGFRID.GOTSOMETHINGFORYOU = "A gift for you!"
WEBBER.GOTSOMETHINGFORYOU = "We got it just for you."
WINONA.GOTSOMETHINGFORYOU = "You look like you need this."
WARLY.GOTSOMETHINGFORYOU = "Order served!"
WORTOX.GOTSOMETHINGFORYOU = "Would you like a gift?"
WORMWOOD.GOTSOMETHINGFORYOU = "Take gift, friend!"
WURT.GOTSOMETHINGFORYOU = "TAKE PRESENT, GLORP!!"
WALTER.GOTSOMETHINGFORYOU = "Take this!"
WANDA.GOTSOMETHINGFORYOU = "Don't spend it all at once."

local function gotSomethingForYou(speaker)
    return speaker.GOTSOMETHINGFORYOU or GENERIC.GOTSOMETHINGFORYOU
end

GLOBAL.ACTIONS.GIVETOPLAYER.fn = function(act)
    act.doer.components.talker:Say(gotSomethingForYou(string.upper(act.doer.prefab)))
    if act.target ~= nil and
        act.target.components.trader ~= nil and
        act.target.components.inventory ~= nil and
        (act.target.components.inventory:IsOpenedBy(act.target) or act.target:HasTag("playerghost")) then
        if act.target.components.inventory:CanAcceptCount(act.invobject, 1) <= 0 then
            return false, "FULL"
        end
        local able, reason = act.target.components.trader:AbleToAccept(act.invobject, act.doer)
        if not able then
            return false, reason
        end
        act.target.components.trader:AcceptGift(act.doer, act.invobject, 1)
        return true
    end
end

GLOBAL.ACTIONS.GIVEALLTOPLAYER.fn = function(act)
    act.doer.components.talker:Say(gotSomethingForYou(string.upper(act.doer.prefab)))
    if act.target ~= nil and
        act.target.components.trader ~= nil and
        act.target.components.inventory ~= nil and
        act.target.components.inventory:IsOpenedBy(act.target) then
        local count = act.target.components.inventory:CanAcceptCount(act.invobject)
        if count <= 0 then
            return false, "FULL"
        end
        local able, reason = act.target.components.trader:AbleToAccept(act.invobject, act.doer)
        if not able then
            return false, reason
        end
        act.target.components.trader:AcceptGift(act.doer, act.invobject, count)
        return true
    end
end

This makes it instantly give the item, so it doesn't even have to check for range. I also made the characters talk if they successfully give the item.

I think the rangecheckfn is for Non-Player traders (like the pigking).

local range = 80
local function NewRangeCheck(doer, target)
    if target == nil then
        return
    end
    local target_x, target_y, target_z = target.Transform:GetWorldPosition()
    local doer_x, doer_y, doer_z = doer.Transform:GetWorldPosition()
    local dst = GLOBAL.distsq(target_x, target_z, doer_x, doer_z)
	print(dst)
    return dst <= range^2
end

And I corrected the rangecheckfn, use that instead.

Also the formal way to declare and say strings is

Spoiler
local NOUNS =
{
	DEFAULT = "Mx.",
	MALE = "Mr.",
	FEMALE = "Ms.",
	ROBOT = "Mx.",
}

local FRENCH_NOUNS =
{
	DEFAULT = "Monsieur",
	MALE = "Monsieur",
	FEMALE = "Mademoiselle",
	ROBOT = "Monsieur",
}

local function GetLastName(str)
	return type(str) == "string" and str:gsub(".* ", "") or ""
end

for character,str in pairs
{
	generic = "I have something to give you, {noun} {lastname}.", -- wilson
	willow = "Hope you like it {noun} {lastname}, hehe!",
	wendy = "Here you go.",
	wolfgang = "Take gift from Wolfgang!",
	woodie = "Not everyday you recieve something like this, eh {noun} {lastname}?",
	wickerbottom = "Take this, dear.",
	wx78 = "PACKAGE TRANSFER COMPLETED.",
	waxwell = "I hope you appreciate it, {noun} {lastname}.",
	wathgrithr = "Enjoy the spoils, {noun} {lastname}!",
	webber = "We had you in mind when we got it, {noun} {lastname}!",
	winona = "You look like you need this, {noun} {lastname}. Was I right?",
	wortox = "Care for a gift, {noun} {lastname}?",
	wormwood = "Take gift, friend!",
	warly = "It's a pleasure, {noun} {lastname}.",
	wurt = "PRESENT FOR YOU! FLORP!",
	walter = "I hereby award {lastname} a gift!",
	wanda = "Don't spend it all in one place.",
}
do
	GLOBAL.STRINGS.CHARACTERS[character:upper()]["ANNOUNCE_GIFTFORSOMEONE"] = str
end

local function GetGiftString(inst, target)
  local NOUNSET
  if inst.prefab == "warly" then
      NOUN_SET = FRENCH_NOUNS
  else
      NOUN_SET = NOUNS
  end
  TARGET_GENDER = GLOBAL.GetGenderStrings(target.prefab) or "DEFAULT"
  return GLOBAL.subfmt(GLOBAL.GetString(inst, "ANNOUNCE_GIFTFORSOMEONE"), 
  {
      noun = GLOBAL.GetString(inst, TARGET_GENDER, nil, true) or NOUN_SET[TARGET_GENDER],
      lastname = GetLastName(GLOBAL.STRINGS.CHARACTER_NAMES[target.prefab]),
  })
end

 

Edited by oregu

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
  • Create New...