diff --git a/.gitignore b/.gitignore index c7277d5aa..a5a5946bc 100644 --- a/.gitignore +++ b/.gitignore @@ -23,4 +23,5 @@ DDRace_Trunk_d* *.log *.exe *.res -*.dll \ No newline at end of file +*.dll +*.patch \ No newline at end of file diff --git a/data/editor/entities.png b/data/editor/entities.png index 00b4256af..999b4122c 100644 Binary files a/data/editor/entities.png and b/data/editor/entities.png differ diff --git a/data/languages/czech.txt b/data/languages/czech.txt index ad3cc2beb..f8dd7c9b7 100644 --- a/data/languages/czech.txt +++ b/data/languages/czech.txt @@ -190,8 +190,8 @@ Language Lht. == Světel. -Loading -== Nahrávám +Loading DDRace Client +== Nahrávám DDRace Client MOTD == MOTD diff --git a/data/languages/dutch.txt b/data/languages/dutch.txt index bb1f7480f..2d24c6f29 100644 --- a/data/languages/dutch.txt +++ b/data/languages/dutch.txt @@ -200,8 +200,8 @@ Language Lht. == Licht -Loading -== Laden +Loading DDRace Client +== Laden DDRace Client MOTD == MOTD diff --git a/data/languages/french.txt b/data/languages/french.txt index 84be8803c..e6e68f290 100644 --- a/data/languages/french.txt +++ b/data/languages/french.txt @@ -190,8 +190,8 @@ Language Lht. == Lum. -Loading -== Chargement +Loading DDRace Client +== Chargement DDRace Client MOTD == MOTD diff --git a/data/languages/german.txt b/data/languages/german.txt index 81fca2697..ce170bfc6 100644 --- a/data/languages/german.txt +++ b/data/languages/german.txt @@ -190,8 +190,8 @@ Language Lht. == Hell. -Loading -== Laden +Loading DDRace Client +== Laden DDRace Client MOTD == Nachricht des Tages diff --git a/data/languages/italian.txt b/data/languages/italian.txt index 3c84f1fa6..aaf4f7c5a 100644 --- a/data/languages/italian.txt +++ b/data/languages/italian.txt @@ -187,8 +187,8 @@ Language Lht. == Lum. -Loading -== Caricamento +Loading DDRace Client +== Caricamento DDRace Client MOTD == MDG diff --git a/data/languages/portuguese.txt b/data/languages/portuguese.txt index 4ea993b55..6b8e72d44 100644 --- a/data/languages/portuguese.txt +++ b/data/languages/portuguese.txt @@ -201,8 +201,8 @@ Language Lht. == Luz -Loading -== Carregando +Loading DDRace Client +== Carregando DDRace Client MOTD == MOTD diff --git a/data/languages/russian.txt b/data/languages/russian.txt index 75eed393e..819e45570 100644 --- a/data/languages/russian.txt +++ b/data/languages/russian.txt @@ -1,4 +1,4 @@ - + ##### translated strings ##### %d of %d servers, %d players @@ -190,8 +190,8 @@ Language Lht. == L -Loading -== Загрузка +Loading DDRace Client +== Загрузка DDRace Client MOTD == MOTD diff --git a/data/languages/swedish.txt b/data/languages/swedish.txt index 2b557542a..6c5519ee9 100644 --- a/data/languages/swedish.txt +++ b/data/languages/swedish.txt @@ -1,4 +1,4 @@ - + ##### translated strings ##### %d of %d servers, %d players @@ -187,8 +187,8 @@ Language Lht. == Ljusstyrka -Loading -== Laddar +Loading DDRace Client +== Laddar DDRace Client MOTD == Meddelande diff --git a/other/icons/teeworlds.res b/other/icons/teeworlds.res deleted file mode 100644 index 96cf2aa7c..000000000 Binary files a/other/icons/teeworlds.res and /dev/null differ diff --git a/src/engine/shared/config_variables.h b/src/engine/shared/config_variables.h index 2365af26d..732fbc653 100644 --- a/src/engine/shared/config_variables.h +++ b/src/engine/shared/config_variables.h @@ -9,7 +9,6 @@ MACRO_CONFIG_INT(SvShotgunBulletSound, sv_shotgun_bullet_sound, 0, 0, 1, CFGFLAG_SERVER, "Annoying Shotgun sound on/off") MACRO_CONFIG_INT(SvEndlessSuperHook, sv_endless_super_hook, 0, 0, 1, CFGFLAG_SERVER, "Endless hook for super players on/off") MACRO_CONFIG_INT(SvEmotionalTees, sv_emotional_tees, 1, 0, 1, CFGFLAG_SERVER, "Emotional Tees on/off") -MACRO_CONFIG_INT(SvOldShotgun, sv_old_shotgun, 0, 0, 1, CFGFLAG_SERVER, "Makes Shotgun laser pull towards the shooter, rather than the last bounce origin") MACRO_CONFIG_INT(SvReconnectTime,sv_reconnect_time,5,0,9999,CFGFLAG_SERVER,"how much time between leaves and joins") MACRO_CONFIG_INT(SvVoteKickTimeDelay,sv_vote_kick_delay,0,0,9999,CFGFLAG_SERVER,"how much time between kick votes") MACRO_CONFIG_INT(SvVoteKickBanTime,sv_vote_kick_bantime, 300, 0, 9999, CFGFLAG_SERVER," ") diff --git a/src/game/client/components/menus.cpp b/src/game/client/components/menus.cpp index ed05c6da3..30f1c48d4 100644 --- a/src/game/client/components/menus.cpp +++ b/src/game/client/components/menus.cpp @@ -664,7 +664,7 @@ void CMenus::RenderLoading(float Percent) Graphics()->QuadsEnd(); - const char *pCaption = Localize("Loading"); + const char *pCaption = Localize("Loading DDRace Client"); tw = TextRender()->TextWidth(0, 48.0f, pCaption, -1); CUIRect r; diff --git a/src/game/client/render.h b/src/game/client/render.h index e6c03220f..080949569 100644 --- a/src/game/client/render.h +++ b/src/game/client/render.h @@ -73,6 +73,7 @@ public: void RenderTelemap(CTeleTile *pTele, int w, int h, float Scale); void RenderSpeedupmap(CSpeedupTile *pTele, int w, int h, float Scale); void RenderFrontmap(CTile *pTiles, int w, int h, float Scale, vec4 Color, int Flags); + void RenderSwitchmap(CTeleTile *pSwitch, int w, int h, float Scale); // helpers void MapscreenToWorld(float CenterX, float CenterY, float ParallaxX, float ParallaxY, diff --git a/src/game/client/render_map.cpp b/src/game/client/render_map.cpp index 87629ce5a..d41d75fbd 100644 --- a/src/game/client/render_map.cpp +++ b/src/game/client/render_map.cpp @@ -369,4 +369,44 @@ void CRenderTools::RenderSpeedupmap(CSpeedupTile *pSpeedup, int w, int h, float } Graphics()->MapScreen(ScreenX0, ScreenY0, ScreenX1, ScreenY1); -} \ No newline at end of file +} + +void CRenderTools::RenderSwitchmap(CTeleTile *pSwitch, int w, int h, float Scale) +{ + float ScreenX0, ScreenY0, ScreenX1, ScreenY1; + Graphics()->GetScreen(&ScreenX0, &ScreenY0, &ScreenX1, &ScreenY1); + + int StartY = (int)(ScreenY0/Scale)-1; + int StartX = (int)(ScreenX0/Scale)-1; + int EndY = (int)(ScreenY1/Scale)+1; + int EndX = (int)(ScreenX1/Scale)+1; + + for(int y = StartY; y < EndY; y++) + for(int x = StartX; x < EndX; x++) + { + int mx = x; + int my = y; + + + if(mx<0) + continue; // mx = 0; + if(mx>=w) + continue; // mx = w-1; + if(my<0) + continue; // my = 0; + if(my>=h) + continue; // my = h-1; + + int c = mx + my*w; + + unsigned char Index = pSwitch[c].m_Number; + if(Index) + { + char aBuf[16]; + str_format(aBuf, sizeof(aBuf), "%d", Index); + UI()->TextRender()->Text(0, mx*Scale-2, my*Scale-4, Scale-5, aBuf, -1); + } + } + + Graphics()->MapScreen(ScreenX0, ScreenY0, ScreenX1, ScreenY1); +} diff --git a/src/game/collision.cpp b/src/game/collision.cpp index 320b55d08..bce64cfcc 100644 --- a/src/game/collision.cpp +++ b/src/game/collision.cpp @@ -32,6 +32,8 @@ void CCollision::Init(class CLayers *pLayers) m_pTele = static_cast(m_pLayers->Map()->GetData(m_pLayers->TeleLayer()->m_Tele)); if(m_pLayers->SpeedupLayer()) m_pSpeedup = static_cast(m_pLayers->Map()->GetData(m_pLayers->SpeedupLayer()->m_Speedup)); + if(m_pLayers->SwitchLayer()) + m_pSwitch = static_cast(m_pLayers->Map()->GetData(m_pLayers->SwitchLayer()->m_Switch)); if(m_pLayers->FrontLayer()) { m_pFront = static_cast(m_pLayers->Map()->GetData(m_pLayers->FrontLayer()->m_Front)); diff --git a/src/game/collision.h b/src/game/collision.h index 0cddec681..b4f4fe156 100644 --- a/src/game/collision.h +++ b/src/game/collision.h @@ -9,6 +9,10 @@ class CCollision int m_Width; int m_Height; class CLayers *m_pLayers; + class CTeleTile *m_pTele; + class CSpeedupTile *m_pSpeedup; + class CTile *m_pFront; + class CTeleTile *m_pSwitch; public: enum @@ -62,9 +66,10 @@ public: vec2 CpSpeed(int index); - class CTeleTile *m_pTele; - class CSpeedupTile *m_pSpeedup; - class CTile *m_pFront; + class CTeleTile *TeleLayer() { return m_pTele; } + //class CSpeedupTile *SpeedupLayer() { return m_pSpeedup; } + //class CTile *FrontLayer() { m_pFront; } + class CTeleTile *SwitchLayer() { return m_pSwitch; } class CLayers *Layers() { return m_pLayers; } }; diff --git a/src/game/editor/ed_editor.cpp b/src/game/editor/ed_editor.cpp index 9253705e7..2df1ed3f4 100644 --- a/src/game/editor/ed_editor.cpp +++ b/src/game/editor/ed_editor.cpp @@ -788,7 +788,7 @@ void CEditor::DoToolbar(CUIRect ToolBar) CLayerTiles *pT = (CLayerTiles *)GetSelectedLayerType(0, LAYERTYPE_TILES); // no border for tele layer and speedup - if(pT && (pT->m_Tele || pT->m_Speedup)) + if(pT && (pT->m_Tele || pT->m_Speedup || pT->m_Switch || pT->m_Front)) pT = 0; if(DoButton_Editor(&s_BorderBut, "Border", pT?0:-1, &Button, 0, Localize("Border"))) @@ -817,6 +817,15 @@ void CEditor::DoToolbar(CUIRect ToolBar) static int s_SpeedupPopupId = 0; UiInvokePopupMenu(&s_SpeedupPopupId, 0, UI()->MouseX(), UI()->MouseY(), 120, 43, PopupSpeedup); } + + TB_Bottom.VSplitLeft(5.0f, &Button, &TB_Bottom); + TB_Bottom.VSplitLeft(60.0f, &Button, &TB_Bottom); + static int s_SwitchButton = 0; + if(DoButton_Ex(&s_SwitchButton, "Switcher", (pS && pS->m_Switch)?0:-1, &Button, 0, "Switcher", CUI::CORNER_ALL)) + { + static int s_SwitchPopupId = 0; + UiInvokePopupMenu(&s_SwitchPopupId, 0, UI()->MouseX(), UI()->MouseY(), 120, 23, PopupSwitch); + } } TB_Bottom.VSplitLeft(5.0f, 0, &TB_Bottom); @@ -1135,7 +1144,7 @@ void CEditor::DoMapEditor(CUIRect View, CUIRect ToolBar) //UI()->ClipEnable(&view); } - // render the game, tele, speedup and front above everything else + // render the game, tele, speedup, front and switch above everything else if(m_Map.m_pGameGroup->m_Visible) { m_Map.m_pGameGroup->MapScreen(); @@ -1147,6 +1156,8 @@ void CEditor::DoMapEditor(CUIRect View, CUIRect ToolBar) m_Map.m_pTeleLayer->Render(); if(m_Map.m_pSpeedupLayer && m_Map.m_pSpeedupLayer->m_Visible) m_Map.m_pSpeedupLayer->Render(); + if(m_Map.m_pSwitchLayer && m_Map.m_pSwitchLayer->m_Visible) + m_Map.m_pSwitchLayer->Render(); } } @@ -1798,7 +1809,7 @@ void CEditor::RenderLayers(CUIRect ToolBox, CUIRect ToolBar, CUIRect View) if(int Result = DoButton_Ex(m_Map.m_lGroups[g]->m_lLayers[i], aBuf, g==m_SelectedGroup&&i==m_SelectedLayer, &Button, BUTTON_CONTEXT, Localize("Select layer. Right click for properties."), CUI::CORNER_R)) { - if(m_Map.m_lGroups[g]->m_lLayers[i] == m_Map.m_pTeleLayer || m_Map.m_lGroups[g]->m_lLayers[i] == m_Map.m_pSpeedupLayer) + if(m_Map.m_lGroups[g]->m_lLayers[i] == m_Map.m_pTeleLayer || m_Map.m_lGroups[g]->m_lLayers[i] == m_Map.m_pSpeedupLayer || m_Map.m_lGroups[g]->m_lLayers[i] == m_Map.m_pSwitchLayer)//Clear the brush on entering tele/speedup/switch layer m_Brush.Clear(); m_SelectedLayer = i; m_SelectedGroup = g; @@ -3026,6 +3037,13 @@ void CEditorMap::MakeFrontLayer(CLayer *pLayer) m_pFrontLayer->m_TexId = m_pEditor->ms_EntitiesTexture; } +void CEditorMap::MakeSwitchLayer(CLayer *pLayer) +{ + m_pSwitchLayer = (CLayerSwitch *)pLayer; + m_pSwitchLayer->m_pEditor = m_pEditor; + m_pSwitchLayer->m_TexId = m_pEditor->ms_EntitiesTexture; +} + void CEditorMap::MakeGameGroup(CLayerGroup *pGroup) { m_pGameGroup = pGroup; @@ -3045,6 +3063,7 @@ void CEditorMap::Clean() m_pTeleLayer = 0x0; m_pSpeedupLayer = 0x0; m_pFrontLayer = 0x0; + m_pSwitchLayer = 0x0; m_pGameGroup = 0x0; } @@ -3079,6 +3098,7 @@ void CEditorMap::CreateDefault(int EntitiesTexture) m_pGameGroup->AddLayer(m_pFrontLayer); m_pTeleLayer = 0x0; m_pSpeedupLayer = 0x0; + m_pSwitchLayer = 0x0; } void CEditor::Init() diff --git a/src/game/editor/ed_editor.h b/src/game/editor/ed_editor.h index a879edb29..f02d53c1a 100644 --- a/src/game/editor/ed_editor.h +++ b/src/game/editor/ed_editor.h @@ -266,6 +266,7 @@ public: class CLayerTele *m_pTeleLayer; class CLayerSpeedup *m_pSpeedupLayer; class CLayerFront *m_pFrontLayer; + class CLayerSwitch *m_pSwitchLayer; CLayerGroup *m_pGameGroup; CEnvelope *NewEnvelope(int Channels) @@ -323,6 +324,7 @@ public: void MakeTeleLayer(CLayer *pLayer); void MakeSpeedupLayer(CLayer *pLayer); void MakeFrontLayer(CLayer *pLayer); + void MakeSwitchLayer(CLayer *pLayer); }; @@ -390,6 +392,7 @@ public: int m_Tele; int m_Speedup; int m_Front; + int m_Switch; int m_Image; int m_Width; int m_Height; @@ -467,6 +470,20 @@ public: virtual void BrushDraw(CLayer *pBrush, float wx, float wy); }; +class CLayerSwitch : public CLayerTiles +{ +public: + CLayerSwitch(int w, int h); + ~CLayerSwitch(); + + CTeleTile *m_pSwitchTile; + + virtual void Resize(int NewW, int NewH); + virtual void BrushDraw(CLayer *pBrush, float wx, float wy); + virtual void FillSelection(bool Empty, CLayer *pBrush, CUIRect Rect); +}; + + class CEditor : public IEditor { class IInput *m_pInput; @@ -531,6 +548,7 @@ public: ms_pUiGotContext = 0; m_TeleNum = 1; + m_SwitchNum = 1; m_SpeedupForce = 50; m_SpeedupAngle = 0; @@ -636,6 +654,7 @@ public: static int PopupMenuFile(CEditor *pEditor, CUIRect View); static int PopupTele(CEditor *pEditor, CUIRect View); static int PopupSpeedup(CEditor *pEditor, CUIRect View); + static int PopupSwitch(CEditor *pEditor, CUIRect View); void PopupSelectImageInvoke(int Current, float x, float y); @@ -669,6 +688,8 @@ public: unsigned char m_SpeedupForce; short m_SpeedupAngle; + + unsigned char m_SwitchNum; }; // make sure to inline this function diff --git a/src/game/editor/ed_io.cpp b/src/game/editor/ed_io.cpp index be486303a..9d93c33f6 100644 --- a/src/game/editor/ed_io.cpp +++ b/src/game/editor/ed_io.cpp @@ -288,6 +288,8 @@ int CEditorMap::Save(class IStorage *pStorage, const char *pFileName) Item.m_Flags = 4; else if(pLayer->m_Front) Item.m_Flags = 8; + else if(pLayer->m_Switch) + Item.m_Flags = 16; else Item.m_Flags = pLayer->m_Game; Item.m_Image = pLayer->m_Image; @@ -315,6 +317,14 @@ int CEditorMap::Save(class IStorage *pStorage, const char *pFileName) Item.m_Front = df.AddData(pLayer->m_Width*pLayer->m_Height*sizeof(CTile), pLayer->m_pTiles);//Thanks Sushi Tee delete[] Tiles; } + else if(pLayer->m_Switch) + { + CTile *Tiles = new CTile[pLayer->m_Width*pLayer->m_Height]; + mem_zero(Tiles, pLayer->m_Width*pLayer->m_Height*sizeof(CTile)); + Item.m_Data = df.AddData(pLayer->m_Width*pLayer->m_Height*sizeof(CTile), Tiles); + Item.m_Switch = df.AddData(pLayer->m_Width*pLayer->m_Height*sizeof(CTeleTile), ((CLayerSwitch *)pLayer)->m_pSwitchTile); + delete[] Tiles; + } else Item.m_Data = df.AddData(pLayer->m_Width*pLayer->m_Height*sizeof(CTile), pLayer->m_pTiles); df.AddItem(MAPITEMTYPE_LAYER, LayerCount, sizeof(Item), &Item); @@ -537,6 +547,11 @@ int CEditorMap::Load(class IStorage *pStorage, const char *pFileName) pTiles = new CLayerFront(pTilemapItem->m_Width, pTilemapItem->m_Height); MakeFrontLayer(pTiles); } + else if(pTilemapItem->m_Flags&16) + { + pTiles = new CLayerSwitch(pTilemapItem->m_Width, pTilemapItem->m_Height); + MakeSwitchLayer(pTiles); + } else { pTiles = new CLayerTiles(pTilemapItem->m_Width, pTilemapItem->m_Height); @@ -601,6 +616,28 @@ int CEditorMap::Load(class IStorage *pStorage, const char *pFileName) DataFile.UnloadData(pTilemapItem->m_Front); } + else if(pTiles->m_Switch) + { + void *pSwitchData = DataFile.GetData(pTilemapItem->m_Switch); + mem_copy(((CLayerSwitch*)pTiles)->m_pSwitchTile, pSwitchData, pTiles->m_Width*pTiles->m_Height*sizeof(CTeleTile)); + + for(int i = 0; i < pTiles->m_Width*pTiles->m_Height; i++) + { + if(((CLayerSwitch*)pTiles)->m_pSwitchTile[i].m_Type == (ENTITY_TRIGGER + ENTITY_OFFSET)) + ((CLayerTiles*)pTiles)->m_pTiles[i].m_Index = (ENTITY_TRIGGER + ENTITY_OFFSET); + else if(((CLayerSwitch*)pTiles)->m_pSwitchTile[i].m_Type == (ENTITY_DOOR + ENTITY_OFFSET)) + ((CLayerTiles*)pTiles)->m_pTiles[i].m_Index = (ENTITY_DOOR + ENTITY_OFFSET); + else if(((CLayerSwitch*)pTiles)->m_pSwitchTile[i].m_Type == (ENTITY_LASER_SHORT + ENTITY_OFFSET)) + ((CLayerTiles*)pTiles)->m_pTiles[i].m_Index = (ENTITY_LASER_SHORT + ENTITY_OFFSET); + else if(((CLayerSwitch*)pTiles)->m_pSwitchTile[i].m_Type == (ENTITY_LASER_MIDDLE + ENTITY_OFFSET)) + ((CLayerTiles*)pTiles)->m_pTiles[i].m_Index = (ENTITY_LASER_MIDDLE + ENTITY_OFFSET); + else if(((CLayerSwitch*)pTiles)->m_pSwitchTile[i].m_Type == (ENTITY_LASER_LONG + ENTITY_OFFSET)) + ((CLayerTiles*)pTiles)->m_pTiles[i].m_Index = (ENTITY_LASER_LONG + ENTITY_OFFSET); + else + ((CLayerTiles*)pTiles)->m_pTiles[i].m_Index = 0; + } + DataFile.UnloadData(pTilemapItem->m_Switch); + } } else if(pLayerItem->m_Type == LAYERTYPE_QUADS) { diff --git a/src/game/editor/ed_layer_tiles.cpp b/src/game/editor/ed_layer_tiles.cpp index 8111f4876..4f129188f 100644 --- a/src/game/editor/ed_layer_tiles.cpp +++ b/src/game/editor/ed_layer_tiles.cpp @@ -23,6 +23,7 @@ CLayerTiles::CLayerTiles(int w, int h) m_Tele = 0; m_Speedup = 0; m_Front = 0; + m_Switch = 0; m_pTiles = new CTile[m_Width*m_Height]; mem_zero(m_pTiles, m_Width*m_Height*sizeof(CTile)); @@ -64,6 +65,8 @@ void CLayerTiles::Render() m_pEditor->RenderTools()->RenderTelemap(((CLayerTele*)this)->m_pTeleTile, m_Width, m_Height, 32.0f); if(m_Speedup) m_pEditor->RenderTools()->RenderSpeedupmap(((CLayerSpeedup*)this)->m_pSpeedupTile, m_Width, m_Height, 32.0f); + if(m_Switch) + m_pEditor->RenderTools()->RenderSwitchmap(((CLayerSwitch*)this)->m_pSwitchTile, m_Width, m_Height, 32.0f); } int CLayerTiles::ConvertX(float x) const { return (int)(x/32.0f); } @@ -177,6 +180,26 @@ int CLayerTiles::BrushGrab(CLayerGroup *pBrush, CUIRect Rect) for(int x = 0; x < r.w; x++) pGrabbed->m_pSpeedupTile[y*pGrabbed->m_Width+x] = ((CLayerSpeedup*)this)->m_pSpeedupTile[(r.y+y)*m_Width+(r.x+x)]; } + else if(m_pEditor->GetSelectedLayer(0) == m_pEditor->m_Map.m_pSwitchLayer) + { + CLayerSwitch *pGrabbed = new CLayerSwitch(r.w, r.h); + pGrabbed->m_pEditor = m_pEditor; + pGrabbed->m_TexId = m_TexId; + pGrabbed->m_Image = m_Image; + + pBrush->AddLayer(pGrabbed); + + // copy the tiles + for(int y = 0; y < r.h; y++) + for(int x = 0; x < r.w; x++) + pGrabbed->m_pTiles[y*pGrabbed->m_Width+x] = m_pTiles[(r.y+y)*m_Width+(r.x+x)]; + + // copy the switch data + if(!m_pEditor->Input()->KeyPressed(KEY_SPACE)) + for(int y = 0; y < r.h; y++) + for(int x = 0; x < r.w; x++) + pGrabbed->m_pSwitchTile[y*pGrabbed->m_Width+x] = ((CLayerSwitch*)this)->m_pSwitchTile[(r.y+y)*m_Width+(r.x+x)]; + } else { CLayerTiles *pGrabbed = new CLayerTiles(r.w, r.h); @@ -244,7 +267,7 @@ void CLayerTiles::BrushDraw(CLayer *pBrush, float wx, float wy) continue; // dont allow tele in and out tiles... same with speedup tile in game layer - if(m_pEditor->GetSelectedLayer(0) == m_pEditor->m_Map.m_pGameLayer && (l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELEIN || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELEOUT || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_BOOST)) + if(m_pEditor->GetSelectedLayer(0) == m_pEditor->m_Map.m_pGameLayer && (l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELEIN || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELEOUT || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_BOOST || l->m_pTiles[y*l->m_Width+x].m_Index == (ENTITY_TRIGGER + ENTITY_OFFSET)|| l->m_pTiles[y*l->m_Width+x].m_Index == (ENTITY_DOOR + ENTITY_OFFSET))) continue; m_pTiles[fy*m_Width+fx] = l->m_pTiles[y*l->m_Width+x]; @@ -307,6 +330,11 @@ void CLayerTiles::Resize(int NewW, int NewH) // resize front layer if(m_Game && m_pEditor->m_Map.m_pFrontLayer && (m_pEditor->m_Map.m_pFrontLayer->m_Width != NewW || m_pEditor->m_Map.m_pFrontLayer->m_Height != NewH)) m_pEditor->m_Map.m_pFrontLayer->Resize(NewW, NewH); + + // resize switch layer if available + if(m_Game && m_pEditor->m_Map.m_pSwitchLayer && (m_pEditor->m_Map.m_pSwitchLayer->m_Width != NewW || m_pEditor->m_Map.m_pSwitchLayer->m_Height != NewH)) + m_pEditor->m_Map.m_pSwitchLayer->Resize(NewW, NewH); + } @@ -316,7 +344,7 @@ int CLayerTiles::RenderProperties(CUIRect *pToolBox) pToolBox->HSplitBottom(12.0f, pToolBox, &Button); bool InGameGroup = !find_linear(m_pEditor->m_Map.m_pGameGroup->m_lLayers.all(), this).empty(); - if(m_pEditor->m_Map.m_pGameLayer == this || m_pEditor->m_Map.m_pTeleLayer == this || m_pEditor->m_Map.m_pSpeedupLayer == this || m_pEditor->m_Map.m_pFrontLayer == this) + if(m_pEditor->m_Map.m_pGameLayer == this || m_pEditor->m_Map.m_pTeleLayer == this || m_pEditor->m_Map.m_pSpeedupLayer == this || m_pEditor->m_Map.m_pFrontLayer == this || m_pEditor->m_Map.m_pSwitchLayer == this) InGameGroup = false; static int s_ColclButton = 0; if(m_pEditor->DoButton_Editor(&s_ColclButton, Localize("Clear collision"), InGameGroup?0:-1, &Button, 0, Localize("Removes collision from this layer"))) @@ -367,7 +395,7 @@ int CLayerTiles::RenderProperties(CUIRect *pToolBox) {0}, }; - if(m_pEditor->m_Map.m_pGameLayer == this || m_pEditor->m_Map.m_pTeleLayer == this || m_pEditor->m_Map.m_pSpeedupLayer == this || m_pEditor->m_Map.m_pFrontLayer == this) // remove the image from the selection if this is the game/tele/speedup/front layer + if(m_pEditor->m_Map.m_pGameLayer == this || m_pEditor->m_Map.m_pTeleLayer == this || m_pEditor->m_Map.m_pSpeedupLayer == this || m_pEditor->m_Map.m_pFrontLayer == this || m_pEditor->m_Map.m_pSwitchLayer == this) // remove the image from the selection if this is the game/tele/speedup/front/switch layer aProps[2].m_pName = 0; static int s_aIds[NUM_PROPS] = {0}; @@ -684,8 +712,127 @@ void CLayerFront::BrushDraw(CLayer *pBrush, float wx, float wy) continue; // dont allow tele in and out tiles... same with speedup tile in front - if(m_pEditor->GetSelectedLayer(0) == m_pEditor->m_Map.m_pFrontLayer && (l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELEIN || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELEOUT || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_BOOST)) + if(m_pEditor->GetSelectedLayer(0) == m_pEditor->m_Map.m_pFrontLayer && (l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELEIN || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_TELEOUT || l->m_pTiles[y*l->m_Width+x].m_Index == TILE_BOOST || l->m_pTiles[y*l->m_Width+x].m_Index == (ENTITY_TRIGGER + ENTITY_OFFSET)|| l->m_pTiles[y*l->m_Width+x].m_Index == (ENTITY_DOOR + ENTITY_OFFSET))) continue; m_pTiles[fy*m_Width+fx] = l->m_pTiles[y*l->m_Width+x]; } } + +CLayerSwitch::CLayerSwitch(int w, int h) +: CLayerTiles(w, h) +{ + m_pTypeName = "Switch"; + m_Switch = 1; + + m_pSwitchTile = new CTeleTile[w*h]; + mem_zero(m_pSwitchTile, w*h*sizeof(CTeleTile)); +} + +CLayerSwitch::~CLayerSwitch() +{ + delete[] m_pSwitchTile; +} + +void CLayerSwitch::Resize(int NewW, int NewH) +{ + // resize switch data + CTeleTile *pNewSwitchData = new CTeleTile[NewW*NewH]; + mem_zero(pNewSwitchData, NewW*NewH*sizeof(CTeleTile)); + + // copy old data + for(int y = 0; y < min(NewH, m_Height); y++) + mem_copy(&pNewSwitchData[y*NewW], &m_pSwitchTile[y*m_Width], min(m_Width, NewW)*sizeof(CTeleTile)); + + // replace old + delete [] m_pSwitchTile; + m_pSwitchTile = pNewSwitchData; + + // resize tile data + CLayerTiles::Resize(NewW, NewH); + + // resize gamelayer too + if(m_pEditor->m_Map.m_pGameLayer->m_Width != NewW || m_pEditor->m_Map.m_pGameLayer->m_Height != NewH) + m_pEditor->m_Map.m_pGameLayer->Resize(NewW, NewH); +} + +void CLayerSwitch::BrushDraw(CLayer *pBrush, float wx, float wy) +{ + CLayerSwitch *l = (CLayerSwitch *)pBrush; + int sx = ConvertX(wx); + int sy = ConvertY(wy); + + for(int y = 0; y < l->m_Height; y++) + for(int x = 0; x < l->m_Width; x++) + { + int fx = x+sx; + int fy = y+sy; + if(fx<0 || fx >= m_Width || fy < 0 || fy >= m_Height) + continue; + + if(l->m_pTiles[y*l->m_Width+x].m_Index == (ENTITY_DOOR + ENTITY_OFFSET) || l->m_pTiles[y*l->m_Width+x].m_Index == (ENTITY_TRIGGER + ENTITY_OFFSET) || l->m_pTiles[y*l->m_Width+x].m_Index == (ENTITY_LASER_LONG + ENTITY_OFFSET) || l->m_pTiles[y*l->m_Width+x].m_Index == (ENTITY_LASER_MIDDLE + ENTITY_OFFSET) || l->m_pTiles[y*l->m_Width+x].m_Index == (ENTITY_LASER_SHORT + ENTITY_OFFSET)) + { + if(l->m_pSwitchTile[y*l->m_Width+x].m_Number) + m_pSwitchTile[fy*m_Width+fx].m_Number = l->m_pSwitchTile[y*l->m_Width+x].m_Number; + else + { + if(!m_pEditor->m_SwitchNum) + { + m_pSwitchTile[fy*m_Width+fx].m_Number = 0; + m_pSwitchTile[fy*m_Width+fx].m_Type = 0; + m_pTiles[fy*m_Width+fx].m_Index = 0; + continue; + } + else + m_pSwitchTile[fy*m_Width+fx].m_Number = m_pEditor->m_SwitchNum; + } + + m_pSwitchTile[fy*m_Width+fx].m_Type = l->m_pTiles[y*l->m_Width+x].m_Index; + m_pTiles[fy*m_Width+fx].m_Index = l->m_pTiles[y*l->m_Width+x].m_Index; + } + else + { + m_pSwitchTile[fy*m_Width+fx].m_Number = 0; + m_pSwitchTile[fy*m_Width+fx].m_Type = 0; + m_pTiles[fy*m_Width+fx].m_Index = 0; + } + } +} + +void CLayerSwitch::FillSelection(bool Empty, CLayer *pBrush, CUIRect Rect) +{ + if(m_Readonly) + return; + + int sx = ConvertX(Rect.x); + int sy = ConvertY(Rect.y); + int w = ConvertX(Rect.w); + int h = ConvertY(Rect.h); + + CLayerSwitch *pLt = static_cast(pBrush); + + for(int y = 0; y <= h; y++) + { + for(int x = 0; x <= w; x++) + { + int fx = x+sx; + int fy = y+sy; + + if(fx < 0 || fx >= m_Width || fy < 0 || fy >= m_Height) + continue; + + if(Empty) + { + m_pTiles[fy*m_Width+fx].m_Index = 0; + m_pSwitchTile[fy*m_Width+fx].m_Number = 0; + } + else + { + m_pTiles[fy*m_Width+fx] = pLt->m_pTiles[(y*pLt->m_Width + x%pLt->m_Width) % (pLt->m_Width*pLt->m_Height)]; + if(!pLt->m_pSwitchTile[(y*pLt->m_Width + x%pLt->m_Width) % (pLt->m_Width*pLt->m_Height)].m_Number && m_pEditor->m_SwitchNum && m_pTiles[fy*m_Width+fx].m_Index > 0) + m_pSwitchTile[fy*m_Width+fx].m_Number = m_pEditor->m_SwitchNum; + else + m_pSwitchTile[fy*m_Width+fx].m_Number = pLt->m_pSwitchTile[(y*pLt->m_Width + x%pLt->m_Width) % (pLt->m_Width*pLt->m_Height)].m_Number; + } + } + } +} diff --git a/src/game/editor/ed_popups.cpp b/src/game/editor/ed_popups.cpp index a2d3de868..53a19aa38 100644 --- a/src/game/editor/ed_popups.cpp +++ b/src/game/editor/ed_popups.cpp @@ -144,6 +144,23 @@ int CEditor::PopupGroup(CEditor *pEditor, CUIRect View) } } + if(pEditor->GetSelectedGroup()->m_GameGroup && !pEditor->m_Map.m_pSwitchLayer) + { + // new Switch layer + View.HSplitBottom(10.0f, &View, &Button); + View.HSplitBottom(12.0f, &View, &Button); + static int s_NewSwitchLayerButton = 0; + if(pEditor->DoButton_Editor(&s_NewSwitchLayerButton, "Add Switch Layer", 0, &Button, 0, "Creates a new switch layer")) + { + CLayer *l = new CLayerSwitch(pEditor->m_Map.m_pGameLayer->m_Width, pEditor->m_Map.m_pGameLayer->m_Height); + pEditor->m_Map.MakeSwitchLayer(l); + pEditor->m_Map.m_lGroups[pEditor->m_SelectedGroup]->AddLayer(l); + pEditor->m_SelectedLayer = pEditor->m_Map.m_lGroups[pEditor->m_SelectedGroup]->m_lLayers.size()-1; + pEditor->m_Brush.Clear(); + return 1; + } + } + // new tile layer View.HSplitBottom(10.0f, &View, &Button); @@ -244,6 +261,8 @@ int CEditor::PopupLayer(CEditor *pEditor, CUIRect View) pEditor->m_Map.m_pTeleLayer = 0x0; if(pEditor->GetSelectedLayer(0) == pEditor->m_Map.m_pSpeedupLayer) pEditor->m_Map.m_pSpeedupLayer = 0x0; + if(pEditor->GetSelectedLayer(0) == pEditor->m_Map.m_pSwitchLayer) + pEditor->m_Map.m_pSwitchLayer = 0x0; pEditor->m_Map.m_lGroups[pEditor->m_SelectedGroup]->DeleteLayer(pEditor->m_SelectedLayer); return 1; } @@ -268,7 +287,7 @@ int CEditor::PopupLayer(CEditor *pEditor, CUIRect View) {0}, }; - if(pEditor->m_Map.m_pGameLayer == pEditor->GetSelectedLayer(0) || pEditor->m_Map.m_pTeleLayer == pEditor->GetSelectedLayer(0) || pEditor->m_Map.m_pSpeedupLayer == pEditor->GetSelectedLayer(0) || pEditor->m_Map.m_pFrontLayer == pEditor->GetSelectedLayer(0)) // dont use Group and Detail from the selection if this is the game layer + if(pEditor->m_Map.m_pGameLayer == pEditor->GetSelectedLayer(0) || pEditor->m_Map.m_pTeleLayer == pEditor->GetSelectedLayer(0) || pEditor->m_Map.m_pSpeedupLayer == pEditor->GetSelectedLayer(0) || pEditor->m_Map.m_pFrontLayer == pEditor->GetSelectedLayer(0) || pEditor->m_Map.m_pSwitchLayer == pEditor->GetSelectedLayer(0)) // dont use Group and Detail from the selection if this is the game layer { aProps[0].m_Type = PROPTYPE_NULL; aProps[2].m_Type = PROPTYPE_NULL; @@ -547,3 +566,29 @@ int CEditor::PopupSpeedup(CEditor *pEditor, CUIRect View) return 0; } + +int CEditor::PopupSwitch(CEditor *pEditor, CUIRect View) +{ + CUIRect Button; + View.HSplitBottom(12.0f, &View, &Button); + + enum + { + PROP_Switch=0, + NUM_PROPS, + }; + + CProperty aProps[] = { + {"Number", pEditor->m_SwitchNum, PROPTYPE_INT_STEP, 0, 255}, + {0}, + }; + + static int s_aIds[NUM_PROPS] = {0}; + int NewVal = 0; + int Prop = pEditor->DoProperties(&View, aProps, s_aIds, &NewVal); + + if(Prop == PROP_Switch) + pEditor->m_SwitchNum = clamp(NewVal, 0, 255); + + return 0; +} diff --git a/src/game/layers.cpp b/src/game/layers.cpp index 6cbf22c9c..faa3b9a3f 100644 --- a/src/game/layers.cpp +++ b/src/game/layers.cpp @@ -11,6 +11,7 @@ CLayers::CLayers() m_pTeleLayer = 0; m_pSpeedupLayer = 0; m_pFrontLayer = 0; + m_pSwitchLayer = 0; m_pMap = 0; } @@ -54,6 +55,8 @@ void CLayers::Init(class IKernel *pKernel) m_pSpeedupLayer = pTilemap; if(pTilemap->m_Flags&8) m_pFrontLayer = pTilemap; + if(pTilemap->m_Flags&16) + m_pSwitchLayer = pTilemap; } } } diff --git a/src/game/layers.h b/src/game/layers.h index 3b8ae9201..177ceed56 100644 --- a/src/game/layers.h +++ b/src/game/layers.h @@ -15,6 +15,7 @@ class CLayers CMapItemLayerTilemap *m_pTeleLayer; CMapItemLayerTilemap *m_pSpeedupLayer; CMapItemLayerTilemap *m_pFrontLayer; + CMapItemLayerTilemap *m_pSwitchLayer; class IMap *m_pMap; public: @@ -27,6 +28,7 @@ public: CMapItemLayerTilemap *TeleLayer() const { return m_pTeleLayer; } CMapItemLayerTilemap *SpeedupLayer() const { return m_pSpeedupLayer; } CMapItemLayerTilemap *FrontLayer() const { return m_pFrontLayer; } + CMapItemLayerTilemap *SwitchLayer() const { return m_pSwitchLayer; } CMapItemGroup *GetGroup(int Index) const; CMapItemLayer *GetLayer(int Index) const; }; diff --git a/src/game/mapitems.h b/src/game/mapitems.h index 6ec0fe370..ee09809bb 100644 --- a/src/game/mapitems.h +++ b/src/game/mapitems.h @@ -57,8 +57,9 @@ enum ENTITY_LASER_O_NORMAL, ENTITY_LASER_O_FAST, //DDRace - Plasma - ENTITY_PLASMA=29, + ENTITY_PLASMAE=29, ENTITY_PLASMAF, + ENTITY_PLASMA, //DDRace - Shotgun ENTITY_CRAZY_SHOTGUN_U_EX=33, ENTITY_CRAZY_SHOTGUN_R_EX, @@ -139,6 +140,16 @@ enum ENTITY_OFFSET=255-16*4, }; +enum +{ + LAYER_GAME, + LAYER_FRONT, + LAYER_LASER, + LAYER_TELE, + LAYER_SPEEDUP, + NUM_LAYERS +}; + struct CPoint { int x, y; // 22.10 fixed point @@ -245,6 +256,7 @@ struct CMapItemLayerTilemap int m_Tele; int m_Speedup; int m_Front; + int m_Switch; } ; struct CMapItemLayerQuads diff --git a/src/game/server/entities/gun.cpp b/src/game/server/entities/gun.cpp index 6503a418b..209ac1af0 100644 --- a/src/game/server/entities/gun.cpp +++ b/src/game/server/entities/gun.cpp @@ -12,50 +12,52 @@ const int RANGE=700; ////////////////////////////////////////////////// // CGun ////////////////////////////////////////////////// -CGun::CGun(CGameWorld *pGameWorld, vec2 m_Pos) +CGun::CGun(CGameWorld *pGameWorld, vec2 Pos, bool Freeze, bool Explosive) : CEntity(pGameWorld, NETOBJTYPE_LASER) { - DELAY=Server()->TickSpeed()*0.3f; - this->m_Pos = m_Pos; - this->eval_tick=Server()->Tick(); + m_Delay = Server()->TickSpeed()*0.3f; + m_Pos = Pos; + m_EvalTick = Server()->Tick(); + m_Freeze = Freeze; + m_Explosive = Explosive; GameWorld()->InsertEntity(this); } -void CGun::fire() +void CGun::Fire() { - CCharacter *ents[16]; - int num = -1; - num = GameServer()->m_World.FindEntities(m_Pos,RANGE, (CEntity**)ents, 16, NETOBJTYPE_CHARACTER); - int id=-1; - int minlen=0; - for (int i = 0; i < num; i++) + CCharacter *Ents[16]; + int Num = -1; + Num = GameServer()->m_World.FindEntities(m_Pos,RANGE, (CEntity**)Ents, 16, NETOBJTYPE_CHARACTER); + int Id=-1; + int MinLen=0; + for (int i = 0; i < Num; i++) { - CCharacter *target = ents[i]; + CCharacter *Target = Ents[i]; int res=0; vec2 coltile; - res = GameServer()->Collision()->IntersectLine(m_Pos, target->m_Pos,0,0,false); + res = GameServer()->Collision()->IntersectLine(m_Pos, Target->m_Pos,0,0,false); if (!res) { - int len=length(ents[i]->m_Pos - m_Pos); - if (minlen==0) + int Len=length(Ents[i]->m_Pos - m_Pos); + if (MinLen==0) { - minlen=len; - id=i; + MinLen=Len; + Id=i; } - else if(minlen>len) + else if(MinLen>Len) { - minlen=len; - id=i; + MinLen=Len; + Id=i; } } } - if (id!=-1) + if (Id!=-1) { - CCharacter *target = ents[id]; - vec2 fdir = normalize(target->m_Pos - m_Pos); - new CPlasma(&GameServer()->m_World, m_Pos,fdir); + CCharacter *Target = Ents[Id]; + vec2 Fdir = normalize(Target->m_Pos - m_Pos); + new CPlasma(&GameServer()->m_World, m_Pos, Fdir, m_Freeze, m_Explosive); } } @@ -69,14 +71,14 @@ void CGun::Tick() { if (Server()->Tick()%int(Server()->TickSpeed()*0.15f)==0) { - eval_tick=Server()->Tick(); - int index = GameServer()->Collision()->IsCp(m_Pos.x,m_Pos.y); - if (index) + m_EvalTick=Server()->Tick(); + int Index = GameServer()->Collision()->IsCp(m_Pos.x,m_Pos.y); + if (Index) { - core=GameServer()->Collision()->CpSpeed(index); + m_Core=GameServer()->Collision()->CpSpeed(Index); } - m_Pos+=core; - fire(); + m_Pos+=m_Core; + Fire(); } } @@ -91,5 +93,5 @@ void CGun::Snap(int snapping_client) pObj->m_Y = (int)m_Pos.y; pObj->m_FromX = (int)m_Pos.x; pObj->m_FromY = (int)m_Pos.y; - pObj->m_StartTick = eval_tick; + pObj->m_StartTick = m_EvalTick; } diff --git a/src/game/server/entities/gun.h b/src/game/server/entities/gun.h index b6b3a902b..61e39ddc8 100644 --- a/src/game/server/entities/gun.h +++ b/src/game/server/entities/gun.h @@ -10,15 +10,17 @@ class CCharacter; class CGun : public CEntity { - int eval_tick; + int m_EvalTick; - vec2 core; + vec2 m_Core; + bool m_Freeze; + bool m_Explosive; - void fire(); - int DELAY; + void Fire(); + int m_Delay; public: - CGun(CGameWorld *pGameWorld, vec2 pos); + CGun(CGameWorld *pGameWorld, vec2 Pos, bool Freeze, bool Explosive); virtual void Reset(); virtual void Tick(); diff --git a/src/game/server/entities/laser.cpp b/src/game/server/entities/laser.cpp index 480075416..7dbbf425a 100644 --- a/src/game/server/entities/laser.cpp +++ b/src/game/server/entities/laser.cpp @@ -32,11 +32,9 @@ bool CLaser::HitCharacter(vec2 From, vec2 To) m_Energy = -1; if ((m_Type == 1 && g_Config.m_SvHit)) { - if(g_Config.m_SvOldShotgun) - Hit->m_Core.m_Vel+=normalize(OwnerChar->m_Core.m_Pos-Hit->m_Core.m_Pos)*10; - else Hit->m_Core.m_Vel+=normalize(m_PrevPos - Hit->m_Core.m_Pos) * 10; - } else if (m_Type == 0) + } + else if (m_Type == 0) { Hit->UnFreeze(); } diff --git a/src/game/server/entities/plasma.cpp b/src/game/server/entities/plasma.cpp index bfd4ce475..11b8a2d46 100644 --- a/src/game/server/entities/plasma.cpp +++ b/src/game/server/entities/plasma.cpp @@ -11,31 +11,36 @@ const float ACCEL=1.1f; ////////////////////////////////////////////////// // turret ////////////////////////////////////////////////// -CPlasma::CPlasma(CGameWorld *pGameWorld, vec2 pos,vec2 dir) +CPlasma::CPlasma(CGameWorld *pGameWorld, vec2 Pos, vec2 Dir, bool Freeze, bool Explosive) : CEntity(pGameWorld, NETOBJTYPE_LASER) { - this->m_Pos = pos; - this->core = dir; - this->eval_tick=Server()->Tick(); - this->lifetime=Server()->TickSpeed()*1.5; + m_Pos = Pos; + m_Core = Dir; + m_Freeze = Freeze; + m_Explosive = Explosive; + m_EvalTick = Server()->Tick(); + m_LifeTime = Server()->TickSpeed() * 1.5; GameWorld()->InsertEntity(this); } -bool CPlasma::hit_character() +bool CPlasma::HitCharacter() { - vec2 to2; - CCharacter *hit = GameServer()->m_World.IntersectCharacter(m_Pos, m_Pos+core, 0.0f,to2); - if(!hit) + vec2 To2; + CCharacter *Hit = GameServer()->m_World.IntersectCharacter(m_Pos, m_Pos+m_Core, 0.0f,To2); + if(!Hit) return false; - hit->Freeze(Server()->TickSpeed()*3); + if(m_Freeze) + Hit->Freeze(Server()->TickSpeed()*3); + else + GameServer()->CreateExplosion(m_Pos, -1, WEAPON_GRENADE, false); GameServer()->m_World.DestroyEntity(this); return true; } -void CPlasma::move() +void CPlasma::Move() { - m_Pos += core; - core *= ACCEL; + m_Pos += m_Core; + m_Core *= ACCEL; } void CPlasma::Reset() @@ -45,20 +50,21 @@ void CPlasma::Reset() void CPlasma::Tick() { - if (lifetime==0) + if (m_LifeTime==0) { Reset(); return; } - lifetime--; - move(); - hit_character(); + m_LifeTime--; + Move(); + HitCharacter(); - int res=0; - res = GameServer()->Collision()->IntersectNoLaser(m_Pos, m_Pos+core,0, 0); - if(res) + int Res=0; + Res = GameServer()->Collision()->IntersectNoLaser(m_Pos, m_Pos+m_Core,0, 0); + if(Res) { - GameServer()->CreateExplosion(m_Pos, -1, WEAPON_GRENADE, false); + if(m_Explosive) + GameServer()->CreateExplosion(m_Pos, -1, WEAPON_GRENADE, false); Reset(); } @@ -74,5 +80,5 @@ void CPlasma::Snap(int snapping_client) pObj->m_Y = (int)m_Pos.y; pObj->m_FromX = (int)m_Pos.x; pObj->m_FromY = (int)m_Pos.y; - pObj->m_StartTick = eval_tick; + pObj->m_StartTick = m_EvalTick; } diff --git a/src/game/server/entities/plasma.h b/src/game/server/entities/plasma.h index 9cd82a1d4..6a9e2ec66 100644 --- a/src/game/server/entities/plasma.h +++ b/src/game/server/entities/plasma.h @@ -9,14 +9,15 @@ class CGun; class CPlasma : public CEntity { - vec2 core; - int eval_tick; - int lifetime; - - bool hit_character(); - void move(); + vec2 m_Core; + int m_EvalTick; + int m_LifeTime; + bool m_Freeze; + bool m_Explosive; + bool HitCharacter(); + void Move(); public: - CPlasma(CGameWorld *pGameWorld, vec2 pos,vec2 dir); + CPlasma(CGameWorld *pGameWorld, vec2 Pos, vec2 Dir, bool Freeze, bool Explosive); virtual void Reset(); virtual void Tick(); @@ -24,4 +25,4 @@ public: }; -#endif \ No newline at end of file +#endif diff --git a/src/game/server/gamecontext.cpp b/src/game/server/gamecontext.cpp index 8aa81072e..4a7614327 100644 --- a/src/game/server/gamecontext.cpp +++ b/src/game/server/gamecontext.cpp @@ -1920,7 +1920,7 @@ void CGameContext::OnInit(/*class IKernel *pKernel*/) m_pConsole = Kernel()->RequestInterface(); m_World.SetGameServer(this); m_Events.SetGameServer(this); - + m_Size = 0; //if(!data) // only load once //data = load_data_from_memory(internal_data); @@ -1974,12 +1974,67 @@ void CGameContext::OnInit(/*class IKernel *pKernel*/) CTile *pFront=0; if (m_Layers.FrontLayer()) pFront = (CTile *)Kernel()->RequestInterface()->GetData(pTileMap->m_Front); + CTeleTile *pSwitch=0; + if (m_Layers.SwitchLayer()) + pSwitch = (CTeleTile *)Kernel()->RequestInterface()->GetData(pTileMap->m_Switch); + if (pSwitch) + { + if(Collision()->Layers()->SwitchLayer()) + for(int i = 0; i < Collision()->Layers()->SwitchLayer()->m_Width * Collision()->Layers()->SwitchLayer()->m_Height; i++) + if(Collision()->SwitchLayer()[i].m_Type == (ENTITY_DOOR + ENTITY_OFFSET)) + m_Size++; + if(m_Size) + { + m_SDoors = new SDoors[m_Size]; + int num=0; + for(int y = 0; y < pTileMap->m_Height; y++) + for(int x = 0; x < pTileMap->m_Width; x++) + if(Collision()->SwitchLayer()[y*pTileMap->m_Width+x].m_Type == (ENTITY_DOOR + ENTITY_OFFSET)) + { + int sides[8][2]; + sides[0][0]=pSwitch[(x)+pTileMap->m_Width*(y+1)].m_Type - ENTITY_OFFSET; + sides[1][0]=pSwitch[(x+1)+pTileMap->m_Width*(y+1)].m_Type - ENTITY_OFFSET; + sides[2][0]=pSwitch[(x+1)+pTileMap->m_Width*(y)].m_Type - ENTITY_OFFSET; + sides[3][0]=pSwitch[(x+1)+pTileMap->m_Width*(y-1)].m_Type - ENTITY_OFFSET; + sides[4][0]=pSwitch[(x)+pTileMap->m_Width*(y-1)].m_Type - ENTITY_OFFSET; + sides[5][0]=pSwitch[(x-1)+pTileMap->m_Width*(y-1)].m_Type - ENTITY_OFFSET; + sides[6][0]=pSwitch[(x-1)+pTileMap->m_Width*(y)].m_Type - ENTITY_OFFSET; + sides[7][0]=pSwitch[(x-1)+pTileMap->m_Width*(y+1)].m_Type - ENTITY_OFFSET; + sides[0][1]=pSwitch[(x)+pTileMap->m_Width*(y+1)].m_Number; + sides[1][1]=pSwitch[(x+1)+pTileMap->m_Width*(y+1)].m_Number; + sides[2][1]=pSwitch[(x+1)+pTileMap->m_Width*(y)].m_Number; + sides[3][1]=pSwitch[(x+1)+pTileMap->m_Width*(y-1)].m_Number; + sides[4][1]=pSwitch[(x)+pTileMap->m_Width*(y-1)].m_Number; + sides[5][1]=pSwitch[(x-1)+pTileMap->m_Width*(y-1)].m_Number; + sides[6][1]=pSwitch[(x-1)+pTileMap->m_Width*(y)].m_Number; + sides[7][1]=pSwitch[(x-1)+pTileMap->m_Width*(y+1)].m_Number; + for(int i=0; i<8;i++) + if ((sides[i][0] >= ENTITY_LASER_SHORT && sides[i][0] <= ENTITY_LASER_LONG) && Collision()->SwitchLayer()[y*pTileMap->m_Width+x].m_Number == sides[i][1]) + { + vec2 Pos(x*32.0f+16.0f, y*32.0f+16.0f); + m_SDoors[num].m_Address = new CDoor(&m_World, Pos, pi/4*i, (32*3 + 32*(sides[i][0] - ENTITY_LASER_SHORT)*3), false); + m_SDoors[num].m_Pos = Pos; + m_SDoors[num++].m_Number = Collision()->SwitchLayer()[y*pTileMap->m_Width+x].m_Number; + } + } + } + } for(int y = 0; y < pTileMap->m_Height; y++) { for(int x = 0; x < pTileMap->m_Width; x++) { int Index = pTiles[y*pTileMap->m_Width+x].m_Index; + if(Index == TILE_NPC) + g_Config.m_SvNpc = 1; + else if (Index == TILE_EHOOK) + g_Config.m_SvEndlessDrag = 1; + else if (Index == TILE_NOHIT) + g_Config.m_SvHit = 0; + else if (Index == TILE_EHOOK) + g_Config.m_SvEndlessDrag = 1; + else if (Index == TILE_NPH) + g_Config.m_SvPhook = 0; if(Index >= ENTITY_OFFSET) { vec2 Pos(x*32.0f+16.0f, y*32.0f+16.0f); @@ -1987,13 +2042,33 @@ void CGameContext::OnInit(/*class IKernel *pKernel*/) } if (pFront) { - int FIndex = pFront[y*pTileMap->m_Width+x].m_Index; - if(FIndex >= ENTITY_OFFSET) + int Index = pFront[y*pTileMap->m_Width+x].m_Index; + if(Index == TILE_NPC) + g_Config.m_SvNpc = 1; + else if (Index == TILE_EHOOK) + g_Config.m_SvEndlessDrag = 1; + else if (Index == TILE_NOHIT) + g_Config.m_SvHit = 0; + else if (Index == TILE_EHOOK) + g_Config.m_SvEndlessDrag = 1; + else if (Index == TILE_NPH) + g_Config.m_SvPhook = 0; + + if(Index >= ENTITY_OFFSET) { vec2 Pos(x*32.0f+16.0f, y*32.0f+16.0f); - m_pController->OnEntity(FIndex-ENTITY_OFFSET, Pos,true); + m_pController->OnEntity(Index-ENTITY_OFFSET, Pos,true); } } + if (pSwitch) + { + int Index = pSwitch[y*pTileMap->m_Width+x].m_Type - ENTITY_OFFSET; + vec2 Pos(x*32.0f+16.0f, y*32.0f+16.0f); + if(Index == ENTITY_TRIGGER) + for(int i=0;im_Width+x].m_Number) + new CTrigger(&m_World,Pos, m_SDoors[i].m_Address); + } } } diff --git a/src/game/server/gamecontext.h b/src/game/server/gamecontext.h index e082f471d..4045cc446 100644 --- a/src/game/server/gamecontext.h +++ b/src/game/server/gamecontext.h @@ -12,6 +12,8 @@ #include "gameworld.h" #include "player.h" #include "score.h" +#include +#include /* Tick @@ -123,15 +125,20 @@ public: CEventHandler m_Events; CPlayer *m_apPlayers[MAX_CLIENTS]; - - //bool m_Cheats; - //bool m_EndlessDrag; - //bool m_Tunes; - //bool m_PlayersCollision; IGameController *m_pController; CGameWorld m_World; + int m_Size; + struct SDoors + { + int m_Number; + vec2 m_Pos; + CDoor * m_Address; + }; + + SDoors* m_SDoors; + // helper functions class CCharacter *GetPlayerChar(int ClientId); diff --git a/src/game/server/gamecontroller.cpp b/src/game/server/gamecontroller.cpp index 772057c8c..f8575f7e6 100644 --- a/src/game/server/gamecontroller.cpp +++ b/src/game/server/gamecontroller.cpp @@ -156,19 +156,6 @@ bool IGameController::OnEntity(int Index, vec2 Pos, bool Front) else if(Index == ENTITY_SPAWN_BLUE) m_aaSpawnPoints[2][m_aNumSpawnPoints[2]++] = Pos; - if(Index == ENTITY_DOOR) - { - for(int i=0; i<8;i++) - { - if (sides[i] >= ENTITY_LASER_SHORT && sides[i] <= ENTITY_LASER_LONG) - { - CDoor * door = new CDoor(&GameServer()->m_World, Pos, pi/4*i, 32*3 + 32*(sides[i] - ENTITY_LASER_SHORT)*3, false); - //for (int j = 0; j < 8; j++) - // if (j != i) - Connector(vec2(x, y), door, Front); - } - } - } else if(Index >= ENTITY_CRAZY_SHOTGUN_U_EX && Index <= ENTITY_CRAZY_SHOTGUN_L_EX) { for (int i = 0; i < 4; i++) @@ -305,9 +292,17 @@ bool IGameController::OnEntity(int Index, vec2 Pos, bool Front) { new CDragger(&GameServer()->m_World, Pos,Index-ENTITY_DRAGGER_WEAK_NW+1,true); } + else if(Index==ENTITY_PLASMAE) + { + new CGun(&GameServer()->m_World, Pos, false, true); + } + else if(Index==ENTITY_PLASMAF) + { + new CGun(&GameServer()->m_World, Pos, true, false); + } else if(Index==ENTITY_PLASMA) { - new CGun(&GameServer()->m_World, Pos); + new CGun(&GameServer()->m_World, Pos, true, true); } if(Type != -1) { @@ -335,29 +330,6 @@ vec2 GetSidePos(int side) { return vec2(0, 0); } -void IGameController::Connector(vec2 Pos, CDoor* Door, bool Front) { - int sides[8]; - sides[0] = GameServer()->Collision()->Entity(Pos.x, Pos.y + 1, Front); - sides[1] = GameServer()->Collision()->Entity(Pos.x + 1, Pos.y + 1, Front); - sides[2] = GameServer()->Collision()->Entity(Pos.x + 1, Pos.y, Front); - sides[3] = GameServer()->Collision()->Entity(Pos.x + 1, Pos.y - 1, Front); - sides[4] = GameServer()->Collision()->Entity(Pos.x, Pos.y - 1, Front); - sides[5] = GameServer()->Collision()->Entity(Pos.x - 1, Pos.y - 1, Front); - sides[6] = GameServer()->Collision()->Entity(Pos.x - 1, Pos.y, Front); - sides[7] = GameServer()->Collision()->Entity(Pos.x - 1, Pos.y + 1, Front); - for (int i=0;i<8;i++) - { - vec2 shift = GetSidePos(i); - if (sides[i]==ENTITY_CONNECTOR_D+(i+4) % 8) - Connector(Pos + shift, Door, Front); - else if(sides[i]==ENTITY_TRIGGER) - { - vec2 pos((Pos.x + shift.x)*32.0f + 16.0f, (Pos.y + shift.y)*32.0f + 16.0f); - new CTrigger(&GameServer()->m_World,pos, Door); - } - } -} - void IGameController::EndRound() { if(m_Warmup) // game can't end when we are running warmup diff --git a/src/game/server/gamecontroller.h b/src/game/server/gamecontroller.h index 40915d1ac..b7571c8f9 100644 --- a/src/game/server/gamecontroller.h +++ b/src/game/server/gamecontroller.h @@ -108,7 +108,6 @@ public: */ virtual bool OnEntity(int Index, vec2 Pos, bool Front); - virtual void Connector(vec2 Pos, CDoor* Door, bool Front); /* Function: on_CCharacter_spawn diff --git a/src/game/server/gamemodes/DDRace.cpp b/src/game/server/gamemodes/DDRace.cpp index 02e38f69f..4b75f5e09 100644 --- a/src/game/server/gamemodes/DDRace.cpp +++ b/src/game/server/gamemodes/DDRace.cpp @@ -31,8 +31,8 @@ void CGameControllerDDRace::InitTeleporter() for(int i = 0; i < GameServer()->Collision()->Layers()->TeleLayer()->m_Width*GameServer()->Collision()->Layers()->TeleLayer()->m_Height; i++) { // get the array size - if(GameServer()->Collision()->m_pTele[i].m_Number > ArraySize) - ArraySize = GameServer()->Collision()->m_pTele[i].m_Number; + if(GameServer()->Collision()->TeleLayer()[i].m_Number > ArraySize) + ArraySize = GameServer()->Collision()->TeleLayer()[i].m_Number; } } @@ -48,7 +48,7 @@ void CGameControllerDDRace::InitTeleporter() // assign the values for(int i = 0; i < GameServer()->Collision()->Layers()->TeleLayer()->m_Width*GameServer()->Collision()->Layers()->TeleLayer()->m_Height; i++) { - if(GameServer()->Collision()->m_pTele[i].m_Number > 0 && GameServer()->Collision()->m_pTele[i].m_Type == TILE_TELEOUT) - m_pTeleporter[GameServer()->Collision()->m_pTele[i].m_Number-1] = vec2(i%GameServer()->Collision()->Layers()->TeleLayer()->m_Width*32+16, i/GameServer()->Collision()->Layers()->TeleLayer()->m_Width*32+16); + if(GameServer()->Collision()->TeleLayer()[i].m_Number > 0 && GameServer()->Collision()->TeleLayer()[i].m_Type == TILE_TELEOUT) + m_pTeleporter[GameServer()->Collision()->TeleLayer()[i].m_Number-1] = vec2(i%GameServer()->Collision()->Layers()->TeleLayer()->m_Width*32+16, i/GameServer()->Collision()->Layers()->TeleLayer()->m_Width*32+16); } -} \ No newline at end of file +}