bool GameChat::handle_special_commands(GameState* gs, const std::string& command) { ChatMessage printed; const char* content; PlayerInst* p = gs->local_player(); //Spawn monster if (starts_with(command, "!spawn ", &content)) { const char* rest = content; int amnt = strtol(content, (char**)&rest, 10); if (content == rest) amnt = 1; rest = skip_whitespace(rest); int enemy = get_enemy_by_name(rest, false); if (enemy == -1) { printed.message = "No such monster, '" + std::string(rest) + "'!"; printed.message_colour = Colour(255, 50, 50); } else { printed.message = std::string(rest) + " has spawned !"; generate_enemy_after_level_creation(gs, enemy, amnt); printed.message_colour = Colour(50, 255, 50); } add_message(printed); return true; } //Set game speed if (starts_with(command, "!gamespeed ", &content)) { int gamespeed = squish(atoi(content), 1, 200); gs->game_settings().time_per_step = gamespeed; printed.message = std::string("Game speed set."); printed.message_colour = Colour(50, 255, 50); add_message(printed); return true; } //Gain XP if (starts_with(command, "!gainxp ", &content)) { int xp = atoi(content); if (xp > 0 && xp < 999999) { printed.message = std::string("You have gained ") + content + " experience."; printed.message_colour = Colour(50, 255, 50); add_message(printed); p->gain_xp(gs, xp); } else { printed.message = "Invalid experience amount!"; printed.message_colour = Colour(255, 50, 50); add_message(printed); } return true; } //Create item if (starts_with(command, "!item ", &content)) { const char* rest = content; int amnt = strtol(content, (char**)&rest, 10); if (content == rest) amnt = 1; rest = skip_whitespace(rest); int item = get_item_by_name(rest, false); if (item == -1) { printed.message = "No such item, '" + std::string(rest) + "'!"; printed.message_colour = Colour(255, 50, 50); } else { printed.message = std::string(rest) + " put in your inventory !"; p->stats().equipment.inventory.add(Item(item), amnt); printed.message_colour = Colour(50, 255, 50); } add_message(printed); return true; } //Kill all monsters if (starts_with(command, "!killall", &content)) { MonsterController& mc = gs->monster_controller(); for (int i = 0; i < mc.monster_ids().size(); i++) { EnemyInst* inst = (EnemyInst*)gs->get_instance(mc.monster_ids()[i]); if (inst) { inst->damage(gs, 99999); } } printed.message = "Killed all monsters."; printed.message_colour = Colour(50, 255, 50); add_message(printed); return true; } lua_State* L = gs->get_luastate(); static LuaValue script_globals; if (script_globals.empty()) { script_globals.table_initialize(L); // script_globals.push(L); // int script = lua_gettop(L); // lua_pushvalue(L, LUA_GLOBALSINDEX); // lua_setmetatable(L, script); // lua_pop(L, 1); } lua_push_gameinst(L, p); script_globals.table_pop_value(L, "player"); lua_push_combatstats(L, p); script_globals.table_pop_value(L, "stats"); //Run lua command if (starts_with(command, "!lua ", &content)) { // std::string luafunc = std::string(content); int prior_top = lua_gettop(L); luaL_loadstring(L, content); if (lua_isstring(L, -1)) { const char* val = lua_tostring(L, -1); add_message(val, /*iserr ? Colour(255,50,50) :*/ Colour(120, 120, 255)); return true; } int lfunc = lua_gettop(L); script_globals.push(L); lua_setfenv(L, lfunc); bool iserr = (lua_pcall(L, 0, LUA_MULTRET, 0) != 0); int current_top = lua_gettop(L); for (; prior_top < current_top; prior_top++) { if (lua_isstring(L, -1)) { const char* val = lua_tostring(L, -1); add_message(val, iserr ? Colour(255, 50, 50) : Colour(120, 120, 255)); } lua_pop(L, 1); } return true; } //Run lua file if (starts_with(command, "!luafile ", &content)) { int prior_top = lua_gettop(L); int err_func = luaL_loadfile(L, content); if (err_func) { const char* val = lua_tostring(L, -1); add_message(val, Colour(120, 120, 255)); lua_pop(L, 1); return true; } int lfunc = lua_gettop(L); script_globals.push(L); lua_setfenv(L, lfunc); bool err_call = (lua_pcall(L, 0, 0, 0) != 0); if (err_call) { const char* val = lua_tostring(L, -1); add_message(val, Colour(120, 120, 255)); lua_pop(L, 1); } return true; } return false; }
int GameInstSet::object_radius_test(GameInst* obj, GameInst** objs, int obj_cap, col_filterf f, int x, int y, int radius) { int rad = radius == -1 ? obj->target_radius : radius; x = x == -1 ? obj->x : x; y = y == -1 ? obj->y : y; int mingrid_x = (x - rad) / REGION_SIZE, mingrid_y = (y - rad) / REGION_SIZE; int maxgrid_x = (x + rad) / REGION_SIZE, maxgrid_y = (y + rad) / REGION_SIZE; int minx = squish(mingrid_x, 0, grid_w), miny = squish(mingrid_y, 0, grid_h); int maxx = squish(maxgrid_x, 0, grid_w), maxy = squish(maxgrid_y, 0, grid_h); int obj_n = 0; for (int yy = miny; yy <= maxy; yy++) { int index = yy * grid_w + minx; for (int xx = minx; xx <= maxx; xx++) { InstanceLinkedList& unit_list = unit_grid[index++]; InstanceState* ptr = unit_list.start_of_list; if (!ptr) continue; while (ptr) { GameInst* inst = ptr->inst; if (obj != inst) { int radsqr = (inst->target_radius + rad) * (inst->target_radius + rad); int dx = inst->x - x, dy = inst->y - y; int dsqr = dx * dx + dy * dy; //want to test sqrt(dsqr) < orad+rad //therefore we test dsqr < (orad+rad)*(orad+rad) if (dsqr < radsqr && ((!f && inst->solid) || (f && f(obj, inst)))) { if (obj_cap == 0) return 1; objs[obj_n] = inst; obj_n++; if (obj_n >= obj_cap) return obj_n; } } ptr = ptr->next_in_grid; } } } return obj_n; }
void Stalactite::collision_solid(const CollisionHit& hit) { if(state == STALACTITE_FALLING) { if (hit.bottom) squish(); } if(state == STALACTITE_SQUISHED) { physic.set_velocity_y(0); } }
/* * Common code for middle part of delete * and change operating on parts of lines. */ int vdcMID(void) { register char *cp; squish(); setLAST(); vundkind = VCHNG, CP(vutmp, linebuf); if (wcursor < cursor) cp = wcursor, wcursor = cursor, cursor = cp; vUD1 = vUA1 = vUA2 = cursor; vUD2 = wcursor; return (column(wcursor - 1)); }
/* * Restore a sensible state after a visual/open, moving the saved * stuff back to [unddol,dol], and killing the partial line kill indicators. */ void undvis(void) { if (ruptible) signal(SIGINT, onintr); squish(); pkill[0] = pkill[1] = 0; unddol = truedol; unddel = zero; undap1 = one; undap2 = dol + 1; undkind = UNDALL; if (undadot <= zero || undadot > dol) undadot = zero+1; }
/* * Common code for middle part of delete * and change operating on parts of lines. */ int vdcMID(void) { unsigned char *cp; squish(); setLAST(); if (FIXUNDO) vundkind = VCHNG, CP(vutmp, linebuf); if (wcursor < cursor) cp = wcursor, wcursor = cursor, cursor = cp; vUD1 = vUA1 = vUA2 = cursor; vUD2 = wcursor; /* * XPG6 assertion 273: Set vmcurs so that undo positions the * cursor column correctly when we've moved off the initial line * that was changed, as with the C, c, and s commands, * when G has moved us off the line, or when a * multi-line change was done. */ fixundo(); return (lcolumn(wcursor)); }
static void load_one_catalogue(catalog_file * file) { FILE *src = wfopen(file->file, "r"); ichar buffer[2 * FILENAME_MAX]; ichar base[2 * FILENAME_MAX]; ichar *p; int t; catalogue_item_ptr this_item; int override = 0; if ( !src ) { gripe(NULL, ERC_NO_CATALOGUE, file->file); return; } (void) istrcpy(base, file->file); p = base + istrlen(base); while (p != base && !isDirSep(p[-1])) p--; for (;;) { t = scan(src, buffer, sizeof(buffer), 1); switch (t) { case CAT_BASE: if (scan(src, buffer, sizeof(buffer), 0) == EOF) break; (void) istrcpy(base, buffer); p = base + istrlen(base); if (p != base && !isDirSep(p[-1])) *p++ = '/'; continue; case CAT_OVERRIDE: if (scan(src, buffer, sizeof(buffer), 0) == EOF) break; override = towlower(buffer[0]) == 'y' ? CAT_OVERRIDE : 0; continue; case CAT_PUBLIC: case CAT_SYSTEM: case CAT_ENTITY: case CAT_DOCTYPE: this_item = sgml_malloc(sizeof *this_item); if (scan(src, buffer, sizeof buffer, 0) == EOF) break; if (t == CAT_PUBLIC) squish(buffer); this_item->next = 0; this_item->kind = t == CAT_SYSTEM ? t : t + override; this_item->target = istrdup(buffer); if (scan(src, buffer, sizeof buffer, 0) == EOF) break; if (is_absolute_path(buffer) || p == base) { this_item->replacement = istrdup(buffer); } else { (void) istrcpy(p, buffer); this_item->replacement = istrdup(base); } if (file->first_item == 0) { file->first_item = this_item; } else { file->last_item->next = this_item; } file->last_item = this_item; continue; case EOF: break; default: continue; } break; }
// UpDownWndProc: // LRESULT CALLBACK UpDownWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { RECT rc; int i; PUDSTATE np = (PUDSTATE)GetWindowInt(hwnd, 0); if (np) { if ((uMsg >= WM_MOUSEFIRST) && (uMsg <= WM_MOUSELAST) && (np->ci.style & UDS_HOTTRACK) && !np->fTrackSet) { TRACKMOUSEEVENT tme; np->fTrackSet = TRUE; tme.cbSize = sizeof(tme); tme.hwndTrack = np->ci.hwnd; tme.dwFlags = TME_LEAVE; TrackMouseEvent(&tme); } } switch (uMsg) { case WM_MOUSEMOVE: UD_OnMouseMove(np, lParam); break; case WM_MOUSELEAVE: np->fTrackSet = FALSE; UD_Invalidate(np, np->uHot, FALSE); np->uHot = UD_HITNOWHERE; break; case WM_LBUTTONDOWN: { // Don't set a timer if on the middle border BOOL bTimeIt = TRUE; if (np->hwndBuddy && !IsWindowEnabled(np->hwndBuddy)) break; SetCapture(hwnd); getint(np); switch (np->uClass) { case CLASS_EDIT: case CLASS_LISTBOX: SetFocus(np->hwndBuddy); break; } switch(UD_HitTest(np, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))) { case UD_HITDOWN: np->bDown = TRUE; squish(np, FALSE, TRUE); break; case UD_HITUP: np->bDown = FALSE; squish(np, TRUE, FALSE); break; case UD_HITNOWHERE: bTimeIt = FALSE; break; } if (bTimeIt) { SetTimer(hwnd, 1, GetProfileInt(TEXT("windows"), TEXT("CursorBlinkRate"), 530), NULL); bump(np); } break; } case WM_TIMER: { POINT pt; if (GetCapture() != hwnd) { goto EndScroll; } SetTimer(hwnd, 1, 100, NULL); GetWindowRect(hwnd, &rc); if (np->ci.style & UDS_HORZ) { i = (rc.left + rc.right) / 2; if (np->bDown) { rc.right = i; } else { rc.left = i; } } else { i = (rc.top + rc.bottom) / 2; if (np->bDown) { rc.top = i; } else { rc.bottom = i; } } InflateRect(&rc, (g_cxFrame+1)/2, (g_cyFrame+1)/2); GetCursorPos(&pt); if (PtInRect(&rc, pt)) { squish(np, !np->bDown, np->bDown); bump(np); } else { squish(np, FALSE, FALSE); } break; } case WM_LBUTTONUP: if (np->hwndBuddy && !IsWindowEnabled(np->hwndBuddy)) break; if (GetCapture() == hwnd) { EndScroll: squish(np, FALSE, FALSE); ReleaseCapture(); KillTimer(hwnd, 1); if (np->uClass == CLASS_EDIT) Edit_SetSel(np->hwndBuddy, 0, -1); if (np->ci.style & UDS_HORZ) FORWARD_WM_HSCROLL(np->ci.hwndParent, np->ci.hwnd, SB_ENDSCROLL, np->nPos, SendMessage); else FORWARD_WM_VSCROLL(np->ci.hwndParent, np->ci.hwnd, SB_ENDSCROLL, np->nPos, SendMessage); } break; case WM_ENABLE: InvalidateRect(hwnd, NULL, TRUE); break; case WM_WININICHANGE: if (np && (!wParam || (wParam == SPI_SETNONCLIENTMETRICS) || (wParam == SPI_SETICONTITLELOGFONT))) { InitGlobalMetrics(wParam); unachor(np); anchor(np); } break; case WM_PRINTCLIENT: case WM_PAINT: PaintUpDownControl(np, (HDC)wParam); break; case UDM_SETRANGE: np->nUpper = GET_X_LPARAM(lParam); np->nLower = GET_Y_LPARAM(lParam); nudge(np); break; case UDM_GETRANGE: return MAKELONG(np->nUpper, np->nLower); case UDM_SETBASE: // wParam: new base // lParam: not used // return: 0 if invalid base is specified, // previous base otherwise return (LRESULT)setbase(np, (UINT)wParam); case UDM_GETBASE: return np->nBase; case UDM_SETPOS: { int iNewPos = GET_X_LPARAM(lParam); if (compare(np, np->nLower, np->nUpper, DONTCARE) < 0) { if (compare(np, iNewPos, np->nUpper, DONTCARE) > 0) { iNewPos = np->nUpper; } if (compare(np, iNewPos, np->nLower, DONTCARE) < 0) { iNewPos = np->nLower; } } else { if (compare(np, iNewPos, np->nUpper, DONTCARE) < 0) { iNewPos = np->nUpper; } if (compare(np, iNewPos, np->nLower, DONTCARE) > 0) { iNewPos = np->nLower; } } i = np->nPos; np->nPos = iNewPos; setint(np); #ifdef ACTIVE_ACCESSIBILITY MyNotifyWinEvent(EVENT_OBJECT_VALUECHANGE, np->ci.hwnd, OBJID_CLIENT, 0); #endif return (LRESULT)i; } case UDM_GETPOS: return getint(np); case UDM_SETBUDDY: return setbuddy(np, (HWND)wParam); case UDM_GETBUDDY: return (LRESULT)(int)np->hwndBuddy; case UDM_SETACCEL: if (wParam == 0) return(FALSE); if (wParam >= NUM_UDACCELS) { HANDLE npPrev = (HANDLE)np; np = (PUDSTATE)LocalReAlloc((HLOCAL)np, sizeof(UDSTATE)+(wParam-NUM_UDACCELS)*sizeof(UDACCEL), LMEM_MOVEABLE); if (!np) { return(FALSE); } else { SetWindowInt(hwnd, 0, (int)np); if ((np->ci.style & UDS_ARROWKEYS) && np->hwndBuddy) { SetWindowSubclass(np->hwndBuddy, ArrowKeyProc, 0, (DWORD)np); } } } np->nAccel = wParam; for (i=0; i<(int)wParam; ++i) { np->udAccel[i] = ((LPUDACCEL)lParam)[i]; } return(TRUE); case UDM_GETACCEL: if (wParam > np->nAccel) { wParam = np->nAccel; } for (i=0; i<(int)wParam; ++i) { ((LPUDACCEL)lParam)[i] = np->udAccel[i]; } return(np->nAccel); case WM_NOTIFYFORMAT: return CIHandleNotifyFormat(&np->ci, lParam); case WM_CREATE: // Allocate the instance data space. np = (PUDSTATE)LocalAlloc(LPTR, sizeof(UDSTATE)); if (!np) return -1; SetWindowInt(hwnd, 0, (int)np); #define lpCreate ((CREATESTRUCT FAR *)lParam) CIInitialize(&np->ci, hwnd, lpCreate); // np->fUp = // np->fDown = // np->fUnsigned = // np->fSharedBorder = // np->fSunkenBorder = // FALSE; if (lpCreate->dwExStyle & WS_EX_CLIENTEDGE) np->fSunkenBorder = TRUE; np->nBase = BASE_DECIMAL; np->nUpper = 0; np->nLower = 100; np->nPos = 0; np->hwndBuddy = NULL; np->uClass = CLASS_UNKNOWN; np->nAccel = NUM_UDACCELS; np->udAccel[0].nSec = 0; np->udAccel[0].nInc = 1; np->udAccel[1].nSec = 2; np->udAccel[1].nInc = 5; np->udAccel[2].nSec = 5; np->udAccel[2].nInc = 20; /* This does the pickbuddy and anchor */ setbuddy(np, NULL); setint(np); break; case WM_DESTROY: if (np) { if (np->hwndBuddy) { // Make sure that our buddy is unsubclassed. DebugMsg(DM_ERROR, TEXT("UpDown Destroyed while buddy subclassed")); np->fUpDownDestroyed = TRUE; } else LocalFree((HLOCAL)np); SetWindowInt(hwnd, 0, 0); } break; default: return DefWindowProc(hwnd, uMsg, wParam, lParam); } return 0L; }
LRESULT CALLBACK ArrowKeyProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT uIdSubclass, DWORD dwRefData) { PUDSTATE np = (PUDSTATE)dwRefData; int cDetants; switch (uMsg) { case WM_NCDESTROY: RemoveWindowSubclass(hWnd, ArrowKeyProc, 0); np->hwndBuddy = NULL; if (np->fUpDownDestroyed) { // The buddy was destroyed after updown so free the memory now // And pass off to the message to who we subclassed... LocalFree((HLOCAL)np); } break; case WM_GETDLGCODE: return (DefSubclassProc(hWnd, uMsg, wParam, lParam) | DLGC_WANTARROWS); case WM_KEYDOWN: switch (wParam) { case VK_UP: case VK_DOWN: if (GetCapture() != np->ci.hwnd) { /* Get the value from the buddy if this is the first key down */ if (!(lParam&(1L<<30))) { getint(np); } /* Update the visuals and bump the value */ np->bDown = (wParam == VK_DOWN); squish(np, !np->bDown, np->bDown); bump(np); } return(0L); default: break; } break; case WM_KEYUP: switch (wParam) { case VK_UP: case VK_DOWN: if (GetCapture() != np->ci.hwnd) { squish(np, FALSE, FALSE); } return(0L); default: break; } break; // this is dumb. // wm_char's aren't sent for arrow commands.. // what you're really eating here is & and (. #if 0 case WM_CHAR: switch (wParam) { case VK_UP: case VK_DOWN: return(0L); default: break; } break; #endif case WM_KILLFOCUS: // Reset wheel scroll amount gcWheelDelta = 0; break; case WM_SETFOCUS: Assert(gcWheelDelta == 0); break; default: if (uMsg == g_msgMSWheel && GetCapture() != np->ci.hwnd) { #if defined(WINNT) && defined(WM_MOUSEWHEEL) int iWheelDelta = (int)(short)HIWORD(wParam); #else int iWheelDelta = (int)wParam; #endif // Update count of scroll amount gcWheelDelta -= iWheelDelta; cDetants = gcWheelDelta / WHEEL_DELTA; if (cDetants != 0) { gcWheelDelta %= WHEEL_DELTA; #if defined(WINNT) && defined(WM_MOUSEWHEEL) if (wParam & (MK_SHIFT | MK_CONTROL)) { break; } #else if (GetKeyState(VK_SHIFT) < 0 || GetKeyState(VK_CONTROL) < 0) { break; } #endif getint(np); np->bDown = (cDetants > 0); cDetants = abs(cDetants); while (cDetants-- > 0) { squish(np, !np->bDown, np->bDown); bump(np); } squish(np, FALSE, FALSE); } return 1; } break; } return DefSubclassProc(hWnd, uMsg, wParam, lParam); }
void BadGuy::collision(void *p_c_object, int c_object, CollisionType type) { BadGuy* pbad_c = NULL; if(type == COLLISION_BUMP) { bump(); return; } if(type == COLLISION_SQUISH) { Player* player = static_cast<Player*>(p_c_object); squish(player); return; } /* COLLISION_NORMAL */ switch (c_object) { case CO_BULLET: kill_me(10); break; case CO_BADGUY: pbad_c = (BadGuy*) p_c_object; /* If we're a kicked mriceblock, kill any badguys we hit */ if(kind == BAD_MRICEBLOCK && mode == KICK) { pbad_c->kill_me(25); } // a held mriceblock gets kills the enemy too but falls to ground then else if(kind == BAD_MRICEBLOCK && mode == HELD) { pbad_c->kill_me(25); kill_me(0); } /* Kill badguys that run into exploding bomb */ else if (kind == BAD_BOMB && dying == DYING_NOT) { if (pbad_c->kind == BAD_MRBOMB) { // mrbomb transforms into a bomb now explode(pbad_c); return; } else if (pbad_c->kind != BAD_MRBOMB) { pbad_c->kill_me(50); } } /* Kill any badguys that get hit by stalactite */ else if (kind == BAD_STALACTITE && dying == DYING_NOT) { if (pbad_c->kind == BAD_MRBOMB) { // mrbomb transforms into a bomb now explode(pbad_c); return; } else pbad_c->kill_me(50); } /* When enemies run into eachother, make them change directions */ else { // Jumpy, fish, flame, stalactites are exceptions if (pbad_c->kind == BAD_JUMPY || pbad_c->kind == BAD_FLAME || pbad_c->kind == BAD_STALACTITE || pbad_c->kind == BAD_FISH) break; // Bounce off of other badguy if we land on top of him if (base.y + base.height < pbad_c->base.y + pbad_c->base.height) { if (pbad_c->dir == LEFT) { dir = RIGHT; physic.set_velocity(fabsf(physic.get_velocity_x()), 2); } else if (pbad_c->dir == RIGHT) { dir = LEFT; physic.set_velocity(-fabsf(physic.get_velocity_x()), 2); } break; } else if (base.y + base.height > pbad_c->base.y + pbad_c->base.height) break; if (pbad_c->kind != BAD_FLAME) { if (dir == LEFT) { dir = RIGHT; physic.set_velocity_x(fabsf(physic.get_velocity_x())); } else if (dir == RIGHT) { dir = LEFT; physic.set_velocity_x(-fabsf(physic.get_velocity_x())); } } } break; case CO_PLAYER: Player* player = static_cast<Player*>(p_c_object); /* Get kicked if were flat */ if (mode == FLAT && !dying) { play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER); // Hit from left side if (player->base.x < base.x) { physic.set_velocity_x(5); dir = RIGHT; } // Hit from right side else { physic.set_velocity_x(-5); dir = LEFT; } mode = KICK; player->kick_timer.start(KICKING_TIME); set_sprite(img_mriceblock_flat_left, img_mriceblock_flat_right); } break; } }