示例#1
0
static void NET_SV_SendWaitingData(net_client_t *client)
{
    net_waitdata_t wait_data;
    net_packet_t *packet;
    net_client_t *controller;
    int i;

    NET_SV_AssignPlayers();

    controller = NET_SV_Controller();

    wait_data.num_players = NET_SV_NumPlayers();
    wait_data.num_drones = NET_SV_NumDrones();
    wait_data.ready_players = NET_SV_NumReadyPlayers();
    wait_data.max_players = NET_SV_MaxPlayers();
    wait_data.is_controller = (client == controller);
    wait_data.consoleplayer = client->player_number;

    // Send the WAD and dehacked checksums of the controlling client.
    // If no controller found (?), send the details that the client
    // is expecting anyway.

    if (controller == NULL)
    {
        controller = client;
    }

    memcpy(&wait_data.wad_sha1sum, &controller->wad_sha1sum,
           sizeof(sha1_digest_t));
    memcpy(&wait_data.deh_sha1sum, &controller->deh_sha1sum,
           sizeof(sha1_digest_t));
    wait_data.is_freedoom = controller->is_freedoom;

    // set name and address of each player:

    for (i = 0; i < wait_data.num_players; ++i)
    {
        M_StringCopy(wait_data.player_names[i],
                     sv_players[i]->name,
                     MAXPLAYERNAME);
        M_StringCopy(wait_data.player_addrs[i],
                     NET_AddrToString(sv_players[i]->addr),
                     MAXPLAYERNAME);
    }

    // Construct packet:

    packet = NET_NewPacket(10);
    NET_WriteInt16(packet, NET_PACKET_TYPE_WAITING_DATA);
    NET_WriteWaitData(packet, &wait_data);

    // Send packet to client and free

    NET_Conn_SendPacket(&client->connection, packet);
    NET_FreePacket(packet);
}
示例#2
0
//
// Read the header for a savegame
//
dboolean P_ReadSaveGameHeader(char *description)
{
    byte    a, b, c;
    char    vcheck[VERSIONSIZE];
    char    read_vcheck[VERSIONSIZE];

    for (int i = 0; i < SAVESTRINGSIZE; i++)
        description[i] = saveg_read8();

    for (int i = 0; i < VERSIONSIZE; i++)
        read_vcheck[i] = saveg_read8();

    memset(vcheck, 0, sizeof(vcheck));
    strcpy(vcheck, PACKAGE_SAVEGAMEVERSIONSTRING);

    if (strcmp(read_vcheck, vcheck))
    {
        menuactive = false;
        C_ShowConsole();
        C_Warning("This savegame requires <i>%s</i>.", read_vcheck);
        return false;   // bad version
    }

    gameskill = (skill_t)saveg_read8();
    gameepisode = saveg_read8();
    gamemap = saveg_read8();

    if (gamemode != commercial)
    {
        if (gamemap == 10)
        {
            gamemap = 4;
            M_StringCopy(speciallumpname, "E1M4B", 6);
        }
        else if (gamemap == 11)
        {
            gamemap = 8;
            M_StringCopy(speciallumpname, "E1M8B", 6);
        }
    }

    saveg_read8();

    // get the times
    a = saveg_read8();
    b = saveg_read8();
    c = saveg_read8();
    leveltime = (a << 16) + (b << 8) + c;

    return true;
}
示例#3
0
static void TXT_KeyInputDrawer(TXT_UNCAST_ARG(key_input))
{
    TXT_CAST_ARG(txt_key_input_t, key_input);
    char buf[20];
    int i;

    if (*key_input->variable == 0)
    {
        M_StringCopy(buf, "(none)", sizeof(buf));
    }
    else
    {
        TXT_GetKeyDescription(*key_input->variable, buf, sizeof(buf));
    }

    TXT_SetWidgetBG(key_input);
    TXT_FGColor(TXT_COLOR_BRIGHT_WHITE);
    
    TXT_DrawString(buf);
    
    for (i=strlen(buf); i<KEY_INPUT_WIDTH; ++i)
    {
        TXT_DrawString(" ");
    }
}
示例#4
0
boolean DEH_SetStringMapping(deh_context_t *context, deh_mapping_t *mapping,
                             void *structptr, char *name, char *value)
{
    deh_mapping_entry_t *entry;
    void *location;

    entry = GetMappingEntryByName(context, mapping, name);

    if (entry == NULL)
    {
        return false;
    }

    // Sanity check:

    if (!entry->is_string)
    {
        DEH_Error(context, "Tried to set '%s' as string (BUG)", name);
        return false;
    }

    location = GetStructField(structptr, mapping, entry);

    // Copy value into field:

    M_StringCopy(location, value, entry->size);

    return true;
}
示例#5
0
static void PlayerQuitGame(player_t *player)
{
    static char exitmsg[80];
    unsigned int player_num;

    player_num = player - players;

    // Note:
    // The Heretic source code does this, which doesn't actually work.
    // As a result, the exit message is never seen.

    M_StringCopy(exitmsg, "PLAYER 1 LEFT THE GAME", sizeof(exitmsg));
    exitmsg[7] += player_num;
    players[consoleplayer].message = exitmsg;

    playeringame[player_num] = false;
    players[consoleplayer].message = exitmsg;

    // TODO: check if it is sensible to do this:

    if (demorecording) 
    {
        G_CheckDemoStatus ();
    }
}
示例#6
0
static char *GetFullExePath(const char *program)
{
    char *result;
    char *sep;
    size_t result_len;
    unsigned int path_len;

    sep = strrchr(myargv[0], DIR_SEPARATOR);

    if (sep == NULL)
    {
        result = strdup(program);
    }
    else
    {
        path_len = sep - myargv[0] + 1;
        result_len = strlen(program) + path_len + 1;
        result = malloc(result_len);

        M_StringCopy(result, myargv[0], result_len);
        result[path_len] = '\0';

        M_StringConcat(result, program, result_len);
    }

    return result;
}
static void TXT_JoystickInputDrawer(TXT_UNCAST_ARG(joystick_input))
{
    TXT_CAST_ARG(txt_joystick_input_t, joystick_input);
    char buf[20];
    int i;

    if (*joystick_input->variable < 0)
    {
        M_StringCopy(buf, "(none)", sizeof(buf));
    }
    else
    {
        GetJoystickButtonDescription(*joystick_input->variable,
                                     buf, sizeof(buf));
    }

    TXT_SetWidgetBG(joystick_input);
    TXT_FGColor(TXT_COLOR_BRIGHT_WHITE);

    TXT_DrawString(buf);

    for (i=strlen(buf); i<JOYSTICK_INPUT_WIDTH; ++i)
    {
        TXT_DrawString(" ");
    }
}
示例#8
0
static void PlayerQuitGame(player_t *player)
{
    static char exitmsg[80];
    unsigned int player_num;

    player_num = player - players;

    // Do this the same way as Vanilla Doom does, to allow dehacked
    // replacements of this message

    M_StringCopy(exitmsg, DEH_String("Player 1 left the game"),
                 sizeof(exitmsg));

    exitmsg[7] += player_num;

    playeringame[player_num] = false;
    players[consoleplayer].message = exitmsg;
    // [crispy] don't interpolate players who left the game
    player->mo->interp = false;

    // TODO: check if it is sensible to do this:

    if (demorecording) 
    {
        G_CheckDemoStatus ();
    }
}
示例#9
0
static void TXT_MouseInputDrawer(TXT_UNCAST_ARG(mouse_input))
{
    TXT_CAST_ARG(txt_mouse_input_t, mouse_input);
    char buf[20];
    int i;

    if (*mouse_input->variable < 0)
    {
        M_StringCopy(buf, "(none)", sizeof(buf));
    }
    else
    {
        GetMouseButtonDescription(*mouse_input->variable, buf, sizeof(buf));
    }

    TXT_SetWidgetBG(mouse_input);
    TXT_FGColor(TXT_COLOR_BRIGHT_WHITE);
    
    TXT_DrawString(buf);
    
    for (i=strlen(buf); i<MOUSE_INPUT_WIDTH; ++i)
    {
        TXT_DrawString(" ");
    }
}
示例#10
0
char *M_StringReplace(const char *haystack, const char *needle,
                      const char *replacement)
{
    char *result, *dst;
    const char *p;
    size_t needle_len = strlen(needle);
    size_t result_len, dst_len;

    // Iterate through occurrences of 'needle' and calculate the size of
    // the new string.
    result_len = strlen(haystack) + 1;
    p = haystack;

    for (;;)
    {
        p = strstr(p, needle);
        if (p == NULL)
        {
            break;
        }

        p += needle_len;
        result_len += strlen(replacement) - needle_len;
    }

    // Construct new string.

    result = malloc(result_len);
    if (result == NULL)
    {
        I_Error("M_StringReplace: Failed to allocate new string");
        return NULL;
    }

    dst = result; dst_len = result_len;
    p = haystack;

    while (*p != '\0')
    {
        if (!strncmp(p, needle, needle_len))
        {
            M_StringCopy(dst, replacement, dst_len);
            p += needle_len;
            dst += strlen(replacement);
            dst_len -= strlen(replacement);
        }
        else
        {
            *dst = *p;
            ++dst; --dst_len;
            ++p;
        }
    }

    *dst = '\0';

    return result;
}
示例#11
0
static void GetMouseButtonDescription(int button, char *buf, size_t buf_len)
{
    switch (button)
    {
        case 0:
            M_StringCopy(buf, "LEFT", buf_len);
            break;
        case 1:
            M_StringCopy(buf, "RIGHT", buf_len);
            break;
        case 2:
            M_StringCopy(buf, "MID", buf_len);
            break;
        default:
            snprintf(buf, buf_len, "BUTTON #%i", button + 1);
            break;
    }
}
示例#12
0
boolean M_StringConcat(char *dest, const char *src, size_t dest_size)
{
    size_t offset;

    offset = strlen(dest);
    if (offset > dest_size)
    {
        offset = dest_size;
    }

    return M_StringCopy(dest + offset, src, dest_size - offset);
}
示例#13
0
static boolean SCSaveGame(int option)
{
#ifdef USE_VIRTUALKEYBOARD
	int hour, minute, second;
#endif
    char *ptr;

    if (!FileMenuKeySteal)
    {
        FileMenuKeySteal = true;
        M_StringCopy(oldSlotText, SlotText[option], sizeof(oldSlotText));

#ifdef USE_VIRTUALKEYBOARD
        hour = leveltime / (TICRATE * 360);
        minute = leveltime / (TICRATE * 60);
        second = leveltime / TICRATE;

        if (hour)
            snprintf(SlotText[option], SLOTTEXTLEN + 2, "E%iM%i %02i:%02iH", gameepisode, gamemap, hour, minute % 60);
        else
            snprintf(SlotText[option], SLOTTEXTLEN + 2, "E%iM%i %02i:%02iM", gameepisode, gamemap, minute, second % 60);
#endif

        ptr = SlotText[option];
        while (*ptr)
        {
            ptr++;
        }
        *ptr = '[';
        *(ptr + 1) = 0;
        SlotStatus[option]++;
        currentSlot = option;
        slotptr = ptr - SlotText[option];
        return false;
    }
    else
    {
        G_SaveGame(option, SlotText[option]);
        FileMenuKeySteal = false;
        MN_DeactivateMenu();
    }
    BorderNeedRefresh = true;
    if (quicksave == -1)
    {
        quicksave = option + 1;
        players[consoleplayer].message = NULL;
        players[consoleplayer].messageTics = 1;
    }
    return true;
}
示例#14
0
static void LoadChexDeh(void)
{
    char *chex_deh = NULL;
    char *sep;

    if (gameversion == exe_chex)
    {
        // Look for chex.deh in the same directory as the IWAD file.

        sep = strrchr(iwadfile, DIR_SEPARATOR);

        if (sep != NULL)
        {
            size_t chex_deh_len = strlen(iwadfile) + 9;
            chex_deh = malloc(chex_deh_len);
            M_StringCopy(chex_deh, iwadfile, chex_deh_len);
            chex_deh[sep - iwadfile + 1] = '\0';
            M_StringConcat(chex_deh, "chex.deh", chex_deh_len);
        }
        else
        {
            chex_deh = strdup("chex.deh");
        }

        // If the dehacked patch isn't found, try searching the WAD
        // search path instead.  We might find it...

        if (!M_FileExists(chex_deh))
        {
            free(chex_deh);
            chex_deh = D_FindWADByName("chex.deh");
        }

        // Still not found?

        if (chex_deh == NULL)
        {
            I_Error("Unable to find Chex Quest dehacked file (chex.deh).\n"
                    "The dehacked file is required in order to emulate\n"
                    "chex.exe correctly.  It can be found in your nearest\n"
                    "/idgames repository mirror at:\n\n"
                    "   utils/exe_edit/patches/chexdeh.zip");
        }

        if (!DEH_LoadFile(chex_deh))
        {
            I_Error("Failed to load chex.deh needed for emulating chex.exe.");
        }
    }
}
示例#15
0
void W_NWTDashMerge(char *filename)
{
    wad_file_t *wad_file;
    int old_numlumps;
    int i;

    old_numlumps = numlumps;

    // Load PWAD

    wad_file = W_AddFile(filename);

    if (wad_file == NULL)
    {
        return;
    }

    // IWAD is at the start, PWAD was appended to the end

    iwad.lumps = lumpinfo;
    iwad.numlumps = old_numlumps;

    pwad.lumps = lumpinfo + old_numlumps;
    pwad.numlumps = numlumps - old_numlumps;

    // Setup sprite/flat lists

    SetupLists();

    // Search through the IWAD sprites list.

    for (i=0; i<iwad_sprites.numlumps; ++i)
    {
        if (FindInList(&pwad, iwad_sprites.lumps[i]->name) >= 0)
        {
            // Replace this entry with an empty string.  This is what
            // nwt -merge does.

            M_StringCopy(iwad_sprites.lumps[i]->name, "", 8);
        }
    }

    // Discard PWAD
    // The PWAD must now be added in again with -file.

    numlumps = old_numlumps;

    W_CloseFile(wad_file);
}
示例#16
0
void SC_Open(char *name)
{
    static char StringBuffer[MAX_STRING_SIZE];

    SC_Close();
    ScriptLumpNum = W_GetNumForName(name);
    ScriptBuffer = W_CacheLumpNum(ScriptLumpNum);
    M_StringCopy(ScriptName, name, sizeof(ScriptName));
    ScriptPtr = ScriptBuffer;
    ScriptEndPtr = ScriptPtr + W_LumpLength(ScriptLumpNum);
    sc_Line = 1;
    sc_End = false;
    ScriptOpen = true;
    sc_String = StringBuffer;
    AlreadyGot = false;
}
示例#17
0
char *M_StringJoin(const char *s, ...)
{
    char *result;
    const char *v;
    va_list args;
    size_t result_len;

    result_len = strlen(s) + 1;

    va_start(args, s);
    for (;;)
    {
        v = va_arg(args, const char *);
        if (v == NULL)
        {
            break;
        }

        result_len += strlen(v);
    }
    va_end(args);

    result = malloc(result_len);

    if (result == NULL)
    {
        I_Error("M_StringJoin: Failed to allocate new string.");
        return NULL;
    }

    M_StringCopy(result, s, result_len);

    va_start(args, s);
    for (;;)
    {
        v = va_arg(args, const char *);
        if (v == NULL)
        {
            break;
        }

        M_StringConcat(result, v, result_len);
    }
    va_end(args);

    return result;
}
示例#18
0
static void QueryResponseCallback(net_addr_t *addr,
                                  net_querydata_t *querydata,
                                  unsigned int ping_time,
                                  TXT_UNCAST_ARG(results_table))
{
    TXT_CAST_ARG(txt_table_t, results_table);
    char ping_time_str[16];
    char description[47];

    // When we connect we'll have to negotiate a common protocol that we
    // can agree upon between the client and server. If we can't then we
    // won't be able to connect, so it's pointless to include it in the
    // results list. If protocol==NET_PROTOCOL_UNKNOWN then this may be
    // an old, pre-3.0 Chocolate Doom server that doesn't support the new
    // protocol negotiation mechanism, or it may be an incompatible fork.
    if (querydata->protocol == NET_PROTOCOL_UNKNOWN)
    {
        return;
    }

    M_snprintf(ping_time_str, sizeof(ping_time_str), "%ims", ping_time);

    // Build description from server name field. Because there is limited
    // space, we only include the player count if there are already players
    // connected to the server.
    if (querydata->num_players > 0)
    {
        M_snprintf(description, sizeof(description), "(%d/%d) ",
                   querydata->num_players, querydata->max_players);
    }
    else
    {
        M_StringCopy(description, "", sizeof(description));
    }

    M_StringConcat(description, querydata->description, sizeof(description));

    TXT_AddWidgets(results_table,
                   TXT_NewLabel(ping_time_str),
                   TXT_NewButton2(NET_AddrToString(addr),
                                  SelectQueryAddress, querydata),
                   TXT_NewLabel(description),
                   NULL);

    ++query_servers_found;
}
示例#19
0
//
// Draw character quit prompt
//
void FE_DrawChar(void)
{
    char msg[128];

    if(!curCharacter)
        return;

    V_DrawPatch(0, 0, W_CacheLumpName(curCharacter->pic, PU_CACHE));
    M_WriteText(12, 18, curCharacter->name);

    M_StringCopy(msg, curCharacter->text, sizeof(msg));
    M_DialogDimMsg(20, 28, msg, false);
    M_WriteText(20, 28, msg);

    FE_WriteSmallTextCentered(160, "Are you sure you want to quit?");
    FE_WriteSmallTextCentered(172, "(Press Y or confirm to quit)");
}
示例#20
0
static boolean SCSaveGame(int option)
{
    char *ptr;

    if (!FileMenuKeySteal)
    {
        int x, y;

        FileMenuKeySteal = true;
        // We need to activate the text input interface to type the save
        // game name:
        x = SaveMenu.x + 1;
        y = SaveMenu.y + 1 + option * ITEM_HEIGHT;
        I_StartTextInput(x, y, x + 190, y + ITEM_HEIGHT - 2);

        M_StringCopy(oldSlotText, SlotText[option], sizeof(oldSlotText));
        ptr = SlotText[option];
        while (*ptr)
        {
            ptr++;
        }
        *ptr = '[';
        *(ptr + 1) = 0;
        SlotStatus[option]++;
        currentSlot = option;
        slotptr = ptr - SlotText[option];
        return false;
    }
    else
    {
        G_SaveGame(option, SlotText[option]);
        FileMenuKeySteal = false;
        I_StopTextInput();
        MN_DeactivateMenu();
    }
    BorderNeedRefresh = true;
    if (quicksave == -1)
    {
        quicksave = option + 1;
        players[consoleplayer].message = NULL;
        players[consoleplayer].messageTics = 1;
    }
    return true;
}
示例#21
0
static void TXT_JoystickAxisDrawer(TXT_UNCAST_ARG(joystick_axis))
{
    TXT_CAST_ARG(txt_joystick_axis_t, joystick_axis);
    char buf[JOYSTICK_AXIS_WIDTH + 1];
    int i;

    if (*joystick_axis->axis < 0)
    {
        M_StringCopy(buf, "(none)", sizeof(buf));
    }
    else if (IS_BUTTON_AXIS(*joystick_axis->axis))
    {
        int neg, pos;

        neg = BUTTON_AXIS_NEG(*joystick_axis->axis);
        pos = BUTTON_AXIS_POS(*joystick_axis->axis);
        M_snprintf(buf, sizeof(buf), "BUTTONS #%i+#%i", neg, pos);
    }
    else if (IS_HAT_AXIS(*joystick_axis->axis))
    {
        int hat, dir;

        hat = HAT_AXIS_HAT(*joystick_axis->axis);
        dir = HAT_AXIS_DIRECTION(*joystick_axis->axis);

        M_snprintf(buf, sizeof(buf), "HAT #%i (%s)", hat,
                   dir == HAT_AXIS_HORIZONTAL ? "horizontal" : "vertical");
    }
    else
    {
        M_snprintf(buf, sizeof(buf), "AXIS #%i", *joystick_axis->axis);
    }

    TXT_SetWidgetBG(joystick_axis);
    TXT_FGColor(TXT_COLOR_BRIGHT_WHITE);

    TXT_DrawString(buf);

    for (i = TXT_UTF8_Strlen(buf); i < joystick_axis->widget.w; ++i)
    {
        TXT_DrawString(" ");
    }
}
示例#22
0
deh_context_t *DEH_OpenLump(int lumpnum)
{
    deh_context_t *context;
    void *lump;

    lump = W_CacheLumpNum(lumpnum, PU_STATIC);

    context = DEH_NewContext();

    context->type = DEH_INPUT_LUMP;
    context->lumpnum = lumpnum;
    context->input_buffer = lump;
    context->input_buffer_len = W_LumpLength(lumpnum);
    context->input_buffer_pos = 0;

    context->filename = malloc(9);
    M_StringCopy(context->filename, lumpinfo[lumpnum].name, 9);

    return context;
}
示例#23
0
static void PlayerQuitGame(player_t *player)
{
    static char exitmsg[80];
    unsigned int player_num;

    player_num = player - players;

    M_StringCopy(exitmsg, "PLAYER 1 LEFT THE GAME", sizeof(exitmsg));
    exitmsg[7] += player_num;
    P_SetMessage(&players[consoleplayer], exitmsg, true);
    S_StartSound(NULL, SFX_CHAT);

    playeringame[player_num] = false;

    // TODO: check if it is sensible to do this:

    if (demorecording) 
    {
        G_CheckDemoStatus ();
    }
}
示例#24
0
static void GetSfxLumpName(sfxinfo_t *sfx, char *buf, size_t buf_len)
{
    // Linked sfx lumps? Get the lump number for the sound linked to.

    if (sfx->link != NULL)
    {
        sfx = sfx->link;
    }

    // Doom adds a DS* prefix to sound lumps; Heretic and Hexen don't
    // do this.

    if (use_sfx_prefix)
    {
        M_snprintf(buf, buf_len, "ds%s", DEH_String(sfx->name));
    }
    else
    {
        M_StringCopy(buf, DEH_String(sfx->name), buf_len);
    }
}
示例#25
0
static void QueryResponseCallback(net_addr_t *addr,
                                  net_querydata_t *querydata,
                                  unsigned int ping_time,
                                  TXT_UNCAST_ARG(results_table))
{
    TXT_CAST_ARG(txt_table_t, results_table);
    char ping_time_str[16];
    char description[47];

    M_snprintf(ping_time_str, sizeof(ping_time_str), "%ims", ping_time);
    M_StringCopy(description, querydata->description,
                 sizeof(description));

    TXT_AddWidgets(results_table,
                   TXT_NewLabel(ping_time_str),
                   TXT_NewButton2(NET_AddrToString(addr),
                                  SelectQueryAddress, querydata),
                   TXT_NewLabel(description),
                   NULL);

    ++query_servers_found;
}
示例#26
0
static void OpenScript(char *name, int type)
{
	SC_Close();
	if (type == LUMP_SCRIPT)
	{                           // Lump script
		ScriptLumpNum = W_GetNumForName(name);
		ScriptBuffer = (char *) W_CacheLumpNum(ScriptLumpNum, PU_STATIC);
		ScriptSize = W_LumpLength(ScriptLumpNum);
		M_StringCopy(ScriptName, name, sizeof(ScriptName));
	}
	else if (type == FILE_ZONE_SCRIPT)
	{                           // File script - zone
		ScriptLumpNum = -1;
		ScriptSize = M_ReadFile(name, (byte **) & ScriptBuffer);
		M_ExtractFileBase(name, ScriptName);
	}
	ScriptPtr = ScriptBuffer;
	ScriptEndPtr = ScriptPtr + ScriptSize;
	sc_Line = 1;
	sc_End = false;
	ScriptOpen = true;
	sc_String = StringBuffer;
	AlreadyGot = false;
}
示例#27
0
文件: p_dialog.c 项目: derek57/WIP
//
// P_GiveItemToPlayer
//
// [STRIFE] New function
// haleyjd 09/03/10: Sorts out how to give something to the player.
// Not strictly just for inventory items.
// villsa 09/09/10: Fleshed out function
//
boolean P_GiveItemToPlayer(player_t *player, int sprnum, mobjtype_t type)
{
    int i = 0;
    line_t junk;
    int sound = sfx_itemup; // haleyjd 09/21/10: different sounds for items

    // set quest if mf_givequest flag is set
    if(mobjinfo[type].flags & MF_GIVEQUEST)
        player->questflags |= 1 << (mobjinfo[type].speed - 1);

    // check for keys
    if(type >= MT_KEY_BASE && type <= MT_NEWKEY5)
    {
        P_GiveCard(player, type - MT_KEY_BASE);
        return true;
    }

    // check for quest tokens
    if(type >= MT_TOKEN_QUEST1 && type <= MT_TOKEN_QUEST31)
    {
        if(mobjinfo[type].name)
        {
            M_StringCopy(pickupstring, DEH_String(mobjinfo[type].name), 39);
            player->message = pickupstring;
        }
        player->questflags |= 1 << (type - MT_TOKEN_QUEST1);

        if(player == &players[consoleplayer])
            S_StartSound(NULL, sound);
        return true;
    }

    // haleyjd 09/22/10: Refactored to give sprites higher priority than
    // mobjtypes and to implement missing logic.
    switch(sprnum)
    {
    case SPR_HELT: // This is given only by the "DONNYTRUMP" cheat (aka Midas)
        P_GiveInventoryItem(player, SPR_HELT, MT_TOKEN_TOUGHNESS);
        P_GiveInventoryItem(player, SPR_GUNT, MT_TOKEN_ACCURACY);

        // [STRIFE] Bizarre...
        for(i = 0; i < 5 * player->accuracy + 300; i++)
            P_GiveInventoryItem(player, SPR_COIN, MT_MONY_1);
        break;

    case SPR_ARM1: // Armor 1
        if(!P_GiveArmor(player, -2))
            P_GiveInventoryItem(player, sprnum, type);
        break;

    case SPR_ARM2: // Armor 2
        if(!P_GiveArmor(player, -1))
            P_GiveInventoryItem(player, sprnum, type);
        break;

    case SPR_COIN: // 1 Gold
        P_GiveInventoryItem(player, SPR_COIN, MT_MONY_1);
        break;

    case SPR_CRED: // 10 Gold
        for(i = 0; i < 10; i++)
            P_GiveInventoryItem(player, SPR_COIN, MT_MONY_1);
        break;

    case SPR_SACK: // 25 gold
        for(i = 0; i < 25; i++)
            P_GiveInventoryItem(player, SPR_COIN, MT_MONY_1);
        break;

    case SPR_CHST: // 50 gold
        for(i = 0; i < 50; i++)
            P_GiveInventoryItem(player, SPR_COIN, MT_MONY_1);

    case SPR_BBOX: // Box of Bullets
        if(!P_GiveAmmo(player, am_bullets, 5))
            return false;
        break;

    case SPR_BLIT: // Bullet Clip
        if(!P_GiveAmmo(player, am_bullets, 1))
            return false;
        break;

    case SPR_PMAP: // Map powerup
        if(!P_GivePower(player, pw_allmap))
            return false;
        sound = sfx_yeah; // bluh-doop!
        break;

    case SPR_COMM: // Communicator
        if(!P_GivePower(player, pw_communicator))
            return false;
        sound = sfx_yeah; // bluh-doop!
        break;

    case SPR_MSSL: // Mini-missile
        if(!P_GiveAmmo(player, am_missiles, 1))
            return false;
        break;

    case SPR_ROKT: // Crate of missiles
        if(!P_GiveAmmo(player, am_missiles, 5))
            return false;
        break;

    case SPR_BRY1: // Battery cell
        if(!P_GiveAmmo(player, am_cell, 1))
            return false;
        break;

    case SPR_CPAC: // Cell pack
        if(!P_GiveAmmo(player, am_cell, 5))
            return false;
        break;

    case SPR_PQRL: // Poison bolts
        if(!P_GiveAmmo(player, am_poisonbolts, 5))
            return false;
        break;

    case SPR_XQRL: // Electric bolts
        if(!P_GiveAmmo(player, am_elecbolts, 5))
            return false;
        break;

    case SPR_GRN1: // HE Grenades
        if(!P_GiveAmmo(player, am_hegrenades, 1))
            return false;
        break;

    case SPR_GRN2: // WP Grenades
        if(!P_GiveAmmo(player, am_wpgrenades, 1))
            return false;
        break;

    case SPR_BKPK: // Backpack (aka Ammo Satchel)
        if(!player->backpack)
        {
            for(i = 0; i < NUMAMMO; i++)
                player->maxammo[i] *= 2;

            player->backpack = true;
        }
        for(i = 0; i < NUMAMMO; i++)
            P_GiveAmmo(player, i, 1);
        break;

    case SPR_RIFL: // Assault Rifle
        if(player->weaponowned[wp_rifle])
            return false;

        if(!P_GiveWeapon(player, wp_rifle, false))
            return false;
        
        sound = sfx_wpnup; // SHK-CHK!
        break;

    case SPR_FLAM: // Flamethrower
        if(player->weaponowned[wp_flame])
            return false;

        if(!P_GiveWeapon(player, wp_flame, false))
            return false;

        sound = sfx_wpnup; // SHK-CHK!
        break;

    case SPR_MMSL: // Mini-missile Launcher
        if(player->weaponowned[wp_missile])
            return false;

        if(!P_GiveWeapon(player, wp_missile, false))
            return false;

        sound = sfx_wpnup; // SHK-CHK!
        break;

    case SPR_TRPD: // Mauler
        if(player->weaponowned[wp_mauler])
            return false;

        if(!P_GiveWeapon(player, wp_mauler, false))
            return false;

        sound = sfx_wpnup; // SHK-CHK!
        break;

    case SPR_CBOW: // Here's a crossbow. Just aim straight, and *SPLAT!*
        if(player->weaponowned[wp_elecbow])
            return false;

        if(!P_GiveWeapon(player, wp_elecbow, false))
            return false;

        sound = sfx_wpnup; // SHK-CHK!
        break;

    case SPR_TOKN: // Miscellaneous items - These are determined by thingtype.
        switch(type)
        {
        case MT_KEY_HAND: // Severed hand
            P_GiveCard(player, key_SeveredHand);
            break;

        case MT_MONY_300: // 300 Gold (this is the only way to get it, in fact)
            for(i = 0; i < 300; i++)
                P_GiveInventoryItem(player, SPR_COIN, MT_MONY_1);
            break;

        case MT_TOKEN_AMMO: // Ammo token - you get this from the Weapons Trainer
            if(player->ammo[am_bullets] >= 50)
                return false;

            player->ammo[am_bullets] = 50;
            break;

        case MT_TOKEN_HEALTH: // Health token - from the Front's doctor
            if(!P_GiveBody(player, healthamounts[gameskill]))
                return false;
            break;

        case MT_TOKEN_ALARM: // Alarm token - particularly from the Oracle.
            P_NoiseAlert(player->mo, player->mo);
            A_AlertSpectreC(dialogtalker); // BUG: assumes in a dialog o_O
            break;

        case MT_TOKEN_DOOR1: // Door special 1
            junk.tag = 222;
            EV_DoDoor(&junk, vld_open);
            break;

        case MT_TOKEN_PRISON_PASS: // Door special 1 - Prison pass
            junk.tag = 223;
            EV_DoDoor(&junk, vld_open);
            if(gamemap == 2) // If on Tarnhill, give Prison pass object
                P_GiveInventoryItem(player, sprnum, type);
            break;

        case MT_TOKEN_SHOPCLOSE: // Door special 3 - "Shop close" - unused?
            junk.tag = 222;
            EV_DoDoor(&junk, vld_close);
            break;

        case MT_TOKEN_DOOR3: // Door special 4 (or 3? :P ) 
            junk.tag = 224;
            EV_DoDoor(&junk, vld_close);
            break;

        case MT_TOKEN_STAMINA: // Stamina upgrade
            if(player->stamina >= 100)
                return false;

            player->stamina += 10;
            P_GiveBody(player, 200); // full healing
            break;

        case MT_TOKEN_NEW_ACCURACY: // Accuracy upgrade
            if(player->accuracy >= 100)
                return false;

            player->accuracy += 10;
            break;

        case MT_SLIDESHOW: // Slideshow (start a finale)
            gameaction = ga_victory;
            if(gamemap == 10)
                P_GiveItemToPlayer(player, SPR_TOKN, MT_TOKEN_QUEST17);
            break;
        
        default: // The default is to just give it as an inventory item.
            P_GiveInventoryItem(player, sprnum, type);
            break;
        }
        break;

    default: // The ultimate default: Give it as an inventory item.
        if(!P_GiveInventoryItem(player, sprnum, type))
            return false;
        break;
    }

    // Play sound.
    if(player == &players[consoleplayer])
        S_StartSound(NULL, sound);

    return true;
}
示例#28
0
文件: p_dialog.c 项目: derek57/WIP
//
// P_DialogDoChoice
//
// [STRIFE] New function
// haleyjd 09/05/10: Handles making a choice in a dialog. Installed as the
// callback for all items in the dialogmenu structure.
//
void P_DialogDoChoice(int choice)
{
    int i = 0, nextdialog = 0;
    boolean candochoice = true;
    char *message = NULL;
    mapdlgchoice_t *currentchoice;

    if(choice == -1)
        choice = dialogmenu.numitems - 1;

    currentchoice = &(currentdialog->choices[choice]);

    I_StartVoice(NULL); // STRIFE-TODO: verify (should stop previous voice I believe)

    // villsa 09/08/10: converted into for loop
    for(i = 0; i < MDLG_MAXITEMS; i++)
    {
        if(P_PlayerHasItem(dialogplayer, currentchoice->needitems[i]) <
                                         currentchoice->needamounts[i])
        {
            candochoice = false; // nope, missing something
        }
    }

    if(choice != dialogmenu.numitems - 1 && candochoice)
    {
        int item;

        message = currentchoice->textok;
        if(dialogtalkerstates->yes)
            P_SetMobjState(dialogtalker, dialogtalkerstates->yes);

        item = currentchoice->giveitem;
        if(item < 0 || 
           P_GiveItemToPlayer(dialogplayer, 
                              states[mobjinfo[item].spawnstate].sprite, 
                              item))
        {
            // if successful, take needed items
            int count = 0;
            // villsa 09/08/10: converted into for loop
            for(count = 0; count < MDLG_MAXITEMS; count++)
            {
                P_TakeDialogItem(dialogplayer, 
                                 currentchoice->needitems[count],
                                 currentchoice->needamounts[count]);
            }
        }
        else
            message = DEH_String("You seem to have enough!");

        // store next dialog into the talking actor
        nextdialog = currentchoice->next;
        if(nextdialog != 0)
            dialogtalker->miscdata = (byte)(abs(nextdialog));
    }
    else
    {
        // not successful
        message = currentchoice->textno;
        if(dialogtalkerstates->no)
            P_SetMobjState(dialogtalker, dialogtalkerstates->no);
    }
    
    if(choice != dialogmenu.numitems - 1)
    {
        int objective;
        char *objlump;

        if((objective = currentchoice->objective))
        {
            DEH_snprintf(mission_objective, OBJECTIVE_LEN, "log%i", objective);
            objlump = W_CacheLumpName(mission_objective, PU_CACHE);
            M_StringCopy(mission_objective, objlump, OBJECTIVE_LEN);
        }
        // haleyjd 20130301: v1.31 hack: if first char of message is a period,
        // clear the player's message. Is this actually used anywhere?
        if(gameversion == exe_strife_1_31 && message[0] == '.')
            message = NULL;
        dialogplayer->message = message;
    }

    dialogtalker->angle = dialogtalkerangle;
    dialogplayer->st_update = true;
    M_ClearMenus(0);

    if(nextdialog >= 0 || gameaction == ga_victory) // Macil hack
        menuindialog = false;
    else
        P_DialogStart(dialogplayer);
}
示例#29
0
文件: p_dialog.c 项目: derek57/WIP
//
// P_DialogDrawer
//
// This function is set as the drawer callback for the dialog menu.
//
static void P_DialogDrawer(void)
{
    angle_t angle;
    int y;
    int i;
    int height;
    int finaly;
    char choicetext[64];
    char choicetext2[64];

    // Run down bonuscount faster than usual so that flashes from being given
    // items are less obvious.
    if(dialogplayer->bonuscount)
    {
        dialogplayer->bonuscount -= 3;
        if(dialogplayer->bonuscount < 0)
            dialogplayer->bonuscount = 0;
    }

    angle = R_PointToAngle2(dialogplayer->mo->x,
                            dialogplayer->mo->y,
                            dialogtalker->x,
                            dialogtalker->y);
    angle -= dialogplayer->mo->angle;

    // Dismiss the dialog if the player is out of alignment, or the thing he was
    // talking to is now engaged in battle.
    if ((angle > ANG45 && angle < (ANG270+ANG45))
     || (dialogtalker->flags & MF_NODIALOG) != 0)
    {
        P_DialogDoChoice(dialogmenu.numitems - 1);
    }

    dialogtalker->reactiontime = 2;

    // draw background
    if(dialogbgpiclumpnum != -1)
    {
        patch_t *patch = W_CacheLumpNum(dialogbgpiclumpnum, PU_CACHE);
        V_DrawPatchDirect(0, 0, patch);
    }

    // if there's a valid background pic, delay drawing the rest of the menu 
    // for a while; otherwise, it will appear immediately
    if(dialogbgpiclumpnum == -1 || menupausetime <= gametic)
    {
        if(menuindialog)
        {
            // time to pause the game?
            if(menupausetime + 3 < gametic)
                menupause = true;
        }

        // draw character name
        M_WriteText(12, 18, dialogname);
        y = 28;

        // show text (optional for dialogs with voices)
        if(dialogshowtext || currentdialog->voice[0] == '\0')
            y = M_WriteText(20, 28, dialogtext);

        height = 20 * dialogmenu.numitems;

        finaly = 175 - height;     // preferred height
        if(y > finaly)
            finaly = 199 - height; // height it will bump down to if necessary.

        // draw divider
        M_WriteText(42, finaly - 6, DEH_String("______________________________"));

        dialogmenu.y = finaly + 6;
        y = 0;

        // draw the menu items
        for(i = 0; i < dialogmenu.numitems - 1; i++)
        {
            DEH_snprintf(choicetext, sizeof(choicetext),
                         "%d) %s", i + 1, currentdialog->choices[i].text);
            
            // alternate text for items that need money
            if(currentdialog->choices[i].needamounts[0] > 0)
            {
                // haleyjd 20120401: necessary to avoid undefined behavior:
                M_StringCopy(choicetext2, choicetext, sizeof(choicetext2));
                DEH_snprintf(choicetext, sizeof(choicetext),
                             "%s for %d", choicetext2,
                             currentdialog->choices[i].needamounts[0]);
            }

            M_WriteText(dialogmenu.x, dialogmenu.y + 3 + y, choicetext);
            y += 19;
        }

        // draw the final item for dismissing the dialog
        M_WriteText(dialogmenu.x, 19 * i + dialogmenu.y + 3, dialoglastmsgbuffer);
    }
}
示例#30
0
void CT_Ticker(void)
{
    int i;
    int j;
    char c;
    int numplayers;

    for (i = 0; i < maxplayers; i++)
    {
        if (!playeringame[i])
        {
            continue;
        }
        if ((c = players[i].cmd.chatchar) != 0)
        {
            if (c <= CT_PLR_ALL)
            {
                chat_dest[i] = c;
                continue;
            }
            else if (c == CT_ESCAPE)
            {
                CT_ClearChatMessage(i);
            }
            else if (c == KEY_ENTER)
            {
                numplayers = 0;
                for (j = 0; j < maxplayers; j++)
                {
                    numplayers += playeringame[j];
                }
                CT_AddChar(i, 0);       // set the end of message character
                if (numplayers > 2)
                {
                    M_StringCopy(plr_lastmsg[i], CT_FromPlrText[i],
                                 sizeof(plr_lastmsg[i]));
                    M_StringConcat(plr_lastmsg[i], chat_msg[i],
                                   sizeof(plr_lastmsg[i]));
                }
                else
                {
                    M_StringCopy(plr_lastmsg[i], chat_msg[i],
                                 sizeof(plr_lastmsg[i]));
                }
                if (i != consoleplayer && (chat_dest[i] == consoleplayer + 1
                                           || chat_dest[i] == CT_PLR_ALL)
                    && *chat_msg[i])
                {
                    P_SetMessage(&players[consoleplayer], plr_lastmsg[i],
                                 true);
                    S_StartSound(NULL, SFX_CHAT);
                }
                else if (i == consoleplayer && (*chat_msg[i]))
                {
                    if (numplayers <= 1)
                    {
                        P_SetMessage(&players[consoleplayer],
                                     "THERE ARE NO OTHER PLAYERS IN THE GAME!",
                                     true);
                        S_StartSound(NULL, SFX_CHAT);
                    }
                }
                CT_ClearChatMessage(i);
            }
            else if (c == KEY_BACKSPACE)
            {
                CT_BackSpace(i);
            }
            else
            {
                CT_AddChar(i, c);
            }
        }
    }
    return;
}