Beispiel #1
8
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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
void
Stalactite::collision_solid(const CollisionHit& hit)
{
  if(state == STALACTITE_FALLING) {
    if (hit.bottom) squish();
  }
  if(state == STALACTITE_SQUISHED) {
    physic.set_velocity_y(0);
  }
}
Beispiel #4
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));
}
Beispiel #5
0
/*
 * 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;
}
Beispiel #6
0
/*
 * 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));
}
Beispiel #7
0
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;
  }
Beispiel #8
0
// 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;
}
Beispiel #9
0
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;

    }
}