/**
 * Parses a textual descriptor of the conditions for triggering an event-command binding.
 * eventparams{+cond}*
 *
 * @param eb  The results of the parsing are stored here.
 * @param desc  Descriptor containing event information and possible additional conditions.
 *
 * @return  @c true, if successful; otherwise @c false.
 */
boolean B_ParseEventDescriptor(evbinding_t* eb, const char* desc)
{
    AutoStr* str = AutoStr_NewStd();

    // The main part, i.e., the first part.
    desc = Str_CopyDelim(str, desc, '+');

    if(!B_ParseEvent(eb, Str_Text(str)))
    {
        // Failure parsing the event.
        return false;
    }

    // Any conditions?
    while(desc)
    {
        statecondition_t *cond;

        // A new condition.
        desc = Str_CopyDelim(str, desc, '+');

        cond = B_AllocCommandBindingCondition(eb);
        if(!B_ParseStateCondition(cond, Str_Text(str)))
        {
            // Failure parsing the condition.
            return false;
        }
    }

    // Success.
    return true;
}
Exemple #2
0
void P_SetYellowMessage(player_t* pl, int flags, const char* msg)
{
#define YELLOW_FMT      "{r=1;g=0.7;b=0.3;}"
#define YELLOW_FMT_LEN  18

    size_t len;
    AutoStr* buf;

    if(!msg || !msg[0]) return;
    len = strlen(msg);

    buf = AutoStr_NewStd();
    Str_Reserve(buf, YELLOW_FMT_LEN + len+1);
    Str_Set(buf, YELLOW_FMT);
    Str_Appendf(buf, "%s", msg);

    ST_LogPost(pl - players, flags, Str_Text(buf));

    if(pl == &players[CONSOLEPLAYER] && cfg.echoMsg)
        Con_FPrintf(CPF_CYAN, "%s\n", msg);

    // Servers are responsible for sending these messages to the clients.
    /// @todo We shouldn't need to send the format string along with every
    /// important game message. Instead flag a bit in the packet and then
    /// reconstruct on the other end.
    NetSv_SendMessage(pl - players, Str_Text(buf));

#undef YELLOW_FMT
}
Exemple #3
0
AutoStr* Uri_Resolved(Uri const* uri)
{
    SELF_CONST(uri);
    try
    {
        return AutoStr_FromTextStd(self->resolved().toUtf8().constData());
    }
    catch(de::Uri::ResolveError const& er)
    {
        LOG_RES_WARNING(er.asText());
    }
    return AutoStr_NewStd();
}
    virtual void invoke(int player, EventSequenceArg* args, int numArgs)
    {
        if(!strchr(Str_Text(&commandTemplate), '%'))
        {
            DD_Execute(true/*silent*/, Str_Text(&commandTemplate));
            return;
        }

        // Compose the command from the template, inserting values for named arguments.
        /// @todo This logic should be extracted and made into an Str method.
        AutoStr* cmd = AutoStr_NewStd();
        // Reserve an estimate of the composed command length.
        Str_Reserve(cmd, Str_Length(&commandTemplate) + numArgs + 1);

        int len = Str_Length(&commandTemplate);
        const char* start = Str_Text(&commandTemplate);
        const char* ch = start, *substart = start;
        while(ch + 1 < start + len)
        {
            if(ch[0] == '%' && ch[1] && ch[1] != '%')
            {
                Str_PartAppend(cmd, substart, 0, ch - substart);

                if(ch[1] == 'p')
                {
                    Str_AppendChar(cmd, '0' + player);
                }
                else
                {
                    int arg = ch[1] - '0' - 1;
                    DENG_ASSERT(arg >= 0 && arg < 9);
                    Str_AppendChar(cmd, char(args[arg]));
                }
                ch += 2;
                substart = ch;
            }
            else
            {
                ch++;
            }
        }
        // Add anything remaining.
        Str_Append(cmd, substart);

        DD_Execute(true/*silent*/, Str_Text(cmd));
    }
Exemple #5
0
static Uri *readTextureUrn(Reader *reader, char const *schemeName)
{
    DENG_ASSERT(reader && schemeName);
    return Uri_NewWithPath2(Str_Text(Str_Appendf(AutoStr_NewStd(), "urn:%s:%i", schemeName, Reader_ReadInt16(svReader))), RC_NULL);
}
Exemple #6
0
AutoStr *AutoStr_FromTextStd(const char *text)
{
    return Str_Set(AutoStr_NewStd(), text);
}
Exemple #7
0
/**
 * Parse a state condition.
 */
boolean B_ParseStateCondition(statecondition_t* cond, const char* desc)
{
    AutoStr* str = AutoStr_NewStd();
    ddeventtype_t type;

    // First, we expect to encounter a device name.
    desc = Str_CopyDelim(str, desc, '-');

    if(!Str_CompareIgnoreCase(str, "multiplayer"))
    {
        // This is only intended for multiplayer games.
        cond->type = SCT_STATE;
        cond->flags.multiplayer = true;
    }
    else if(!Str_CompareIgnoreCase(str, "modifier"))
    {
        cond->device = 0; // not used
        cond->type = SCT_MODIFIER_STATE;

        // Parse the modifier number.
        desc = Str_CopyDelim(str, desc, '-');
        if(!B_ParseModifierId(Str_Text(str), &cond->id))
        {
            return false;
        }

        // The final part of a modifier is the state.
        desc = Str_CopyDelim(str, desc, '-');
        if(!B_ParseToggleState(Str_Text(str), &cond->state))
        {
            return false;
        }
    }
    else if(!Str_CompareIgnoreCase(str, "key"))
    {
        cond->device = IDEV_KEYBOARD;
        cond->type = SCT_TOGGLE_STATE;

        // Parse the key.
        desc = Str_CopyDelim(str, desc, '-');
        if(!B_ParseKeyId(Str_Text(str), &cond->id))
        {
            return false;
        }

        // The final part of a key event is the state of the key toggle.
        desc = Str_CopyDelim(str, desc, '-');
        if(!B_ParseToggleState(Str_Text(str), &cond->state))
        {
            return false;
        }
    }
    else if(!Str_CompareIgnoreCase(str, "mouse"))
    {
        cond->device = IDEV_MOUSE;

        // What is being targeted?
        desc = Str_CopyDelim(str, desc, '-');
        if(!B_ParseMouseTypeAndId(Str_Text(str), &type, &cond->id))
        {
            return false;
        }

        desc = Str_CopyDelim(str, desc, '-');
        if(type == E_TOGGLE)
        {
            cond->type = SCT_TOGGLE_STATE;
            if(!B_ParseToggleState(Str_Text(str), &cond->state))
            {
                return false;
            }
        }
        else if(type == E_AXIS)
        {
            cond->type = SCT_AXIS_BEYOND;
            if(!B_ParseAxisPosition(Str_Text(str), &cond->state, &cond->pos))
            {
                return false;
            }
        }
    }
    else if(!Str_CompareIgnoreCase(str, "joy"))
    {
        cond->device = IDEV_JOY1;

        // What is being targeted?
        desc = Str_CopyDelim(str, desc, '-');
        if(!B_ParseJoystickTypeAndId(cond->device, Str_Text(str), &type, &cond->id))
        {
            return false;
        }

        desc = Str_CopyDelim(str, desc, '-');
        if(type == E_TOGGLE)
        {
            cond->type = SCT_TOGGLE_STATE;
            if(!B_ParseToggleState(Str_Text(str), &cond->state))
            {
                return false;
            }
        }
        else if(type == E_AXIS)
        {
            cond->type = SCT_AXIS_BEYOND;
            if(!B_ParseAxisPosition(Str_Text(str), &cond->state, &cond->pos))
            {
                return false;
            }
        }
        else // Angle.
        {
            cond->type = SCT_ANGLE_AT;
            if(!B_ParseAnglePosition(Str_Text(str), &cond->pos))
            {
                return false;
            }
        }
    }
    else
    {
        Con_Message("B_ParseEvent: Device \"%s\" unknown.", Str_Text(str));
        return false;
    }

    // Check for valid toggle states.
    if(cond->type == SCT_TOGGLE_STATE &&
       cond->state != EBTOG_UP && cond->state != EBTOG_DOWN)
    {
        Con_Message("B_ParseStateCondition: \"%s\": Toggle condition can only be 'up' or 'down'.",
                    desc);
        return false;
    }

    // Finally, there may be the negation at the end.
    desc = Str_CopyDelim(str, desc, '-');
    if(!Str_CompareIgnoreCase(str, "not"))
    {
        cond->flags.negate = true;
    }

    // Anything left that wasn't used?
    if(desc)
    {
        Con_Message("B_ParseStateCondition: Unrecognized \"%s\".", desc);
        return false;
    }

    // No errors detected.
    return true;
}
/**
 * Parse the main part of the event descriptor, with no conditions included.
 */
boolean B_ParseEvent(evbinding_t* eb, const char* desc)
{
    AutoStr* str = AutoStr_NewStd();

    // First, we expect to encounter a device name.
    desc = Str_CopyDelim(str, desc, '-');
    if(!Str_CompareIgnoreCase(str, "key"))
    {
        eb->device = IDEV_KEYBOARD;
        // Keyboards only have toggles (as far as we know).
        eb->type = E_TOGGLE;

        // Parse the key.
        desc = Str_CopyDelim(str, desc, '-');
        if(!B_ParseKeyId(Str_Text(str), &eb->id))
        {
            return false;
        }

        // The final part of a key event is the state of the key toggle.
        desc = Str_CopyDelim(str, desc, '-');
        if(!B_ParseToggleState(Str_Text(str), &eb->state))
        {
            return false;
        }
    }
    else if(!Str_CompareIgnoreCase(str, "mouse"))
    {
        eb->device = IDEV_MOUSE;

        // Next comes a button or axis name.
        desc = Str_CopyDelim(str, desc, '-');
        if(!B_ParseMouseTypeAndId(Str_Text(str), &eb->type, &eb->id))
        {
            return false;
        }

        // The last part determines the toggle state or the axis position.
        desc = Str_CopyDelim(str, desc, '-');
        if(eb->type == E_TOGGLE)
        {
            if(!B_ParseToggleState(Str_Text(str), &eb->state))
            {
                return false;
            }
        }
        else // Axis position.
        {
            if(!B_ParseAxisPosition(Str_Text(str), &eb->state, &eb->pos))
            {
                return false;
            }
        }
    }
    else if(!Str_CompareIgnoreCase(str, "joy"))
    {
        eb->device = IDEV_JOY1;

        // Next part defined button, axis, or hat.
        desc = Str_CopyDelim(str, desc, '-');
        if(!B_ParseJoystickTypeAndId(eb->device, Str_Text(str), &eb->type, &eb->id))
        {
            return false;
        }

        // What is the state of the toggle, axis, or hat?
        desc = Str_CopyDelim(str, desc, '-');
        if(eb->type == E_TOGGLE)
        {
            if(!B_ParseToggleState(Str_Text(str), &eb->state))
            {
                return false;
            }
        }
        else if(eb->type == E_AXIS)
        {
            if(!B_ParseAxisPosition(Str_Text(str), &eb->state, &eb->pos))
            {
                return false;
            }
        }
        else // Angle.
        {
            if(!B_ParseAnglePosition(Str_Text(str), &eb->pos))
            {
                return false;
            }
        }
    }
    else if(!Str_CompareIgnoreCase(str, "sym"))
    {
        // It must be a symbolic event.
        eb->type = E_SYMBOLIC;
        eb->device = 0;
        eb->symbolicName = strdup(desc);
        desc = NULL;
    }
    else
    {
        Con_Message("B_ParseEvent: Device \"%s\" unknown.", Str_Text(str));
        return false;
    }

    // Anything left that wasn't used?
    if(desc)
    {
        Con_Message("B_ParseEvent: Unrecognized \"%s\".", desc);
        return false;
    }

    // No errors detected.
    return true;
}