X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_map.pas;h=722bd9bb1cdc2a8cf6625a9399795176a29979ea;hb=refs%2Fheads%2Fmaster;hp=95bb1a02fd813f82536e759ee6a2b0cfa1f86f8c;hpb=414f2873efa0cce84499f64774db7000e6268971;p=d2df-sdl.git diff --git a/src/game/g_map.pas b/src/game/g_map.pas index 95bb1a0..722bd9b 100644 --- a/src/game/g_map.pas +++ b/src/game/g_map.pas @@ -54,6 +54,7 @@ type CaptureTime: LongWord; Animation: TAnimation; Direction: TDirection; + NeedSend: Boolean; end; function g_Map_Load(Res: String): Boolean; @@ -89,6 +90,7 @@ function g_Map_IsSpecialTexture(Texture: String): Boolean; function g_Map_GetPoint(PointType: Byte; var RespawnPoint: TRespawnPoint): Boolean; function g_Map_GetPointCount(PointType: Byte): Word; +function g_Map_GetRandomPointType(): Byte; function g_Map_HaveFlagPoints(): Boolean; @@ -900,21 +902,100 @@ begin end; +function extractWadName (resourceName: string): string; +var + posN: Integer; +begin + posN := Pos(':', resourceName); + if posN > 0 then + Result:= Copy(resourceName, 0, posN-1) + else + Result := ''; +end; + + +procedure addResToExternalResList (res: AnsiString); +var + uname: AnsiString; + f: Integer; + fi: TDiskFileInfo; +begin + if g_Game_IsClient or not g_Game_IsNet then exit; + if (length(res) = 0) then exit; // map wad + //res := extractWadName(res); + //if (length(res) = 0) then exit; // map wad + uname := toLowerCase1251(res); + // do not add duplicates + for f := 0 to High(gExternalResources) do + begin + if (gExternalResources[f].userName = uname) then exit; + end; + //writeln('***(000) addResToExternalResList: res=[', res, ']'); + // add new resource + fi.userName := uname; + if not findFileCI(res) then exit; + //writeln('***(001) addResToExternalResList: res=[', res, ']'); + fi.diskName := res; + if (not GetDiskFileInfo(res, fi)) then + begin + fi.tag := -1; + end + else + begin + //writeln('***(002) addResToExternalResList: res=[', res, ']'); + fi.tag := 0; // non-zero means "cannot caclucate hash" + try + fi.hash := MD5File(fi.diskName); + except + fi.tag := -1; + end; + end; + //e_LogWritefln('addext: res=[%s]; uname=[%s]; diskName=[%s]', [res, fi.userName, fi.diskName]); + SetLength(gExternalResources, length(gExternalResources)+1); + gExternalResources[High(gExternalResources)] := fi; +end; + + +procedure compactExtResList (); +var + src, dest: Integer; +begin + src := 0; + dest := 0; + for src := 0 to High(gExternalResources) do + begin + if (gExternalResources[src].tag = 0) then + begin + // copy it + if (dest <> src) then gExternalResources[dest] := gExternalResources[src]; + Inc(dest); + end; + end; + if (dest <> length(gExternalResources)) then SetLength(gExternalResources, dest); +end; + + function GetReplacementWad (WadName: AnsiString): AnsiString; begin result := ''; if WadName <> '' then begin result := WadName; - if g_Game_IsClient then - result := g_Res_FindReplacementWad(WadName); - if (result = WadName) then - result := e_FindWad(WadDirs, result) + if g_Game_IsClient then result := g_Res_FindReplacementWad(WadName); + if (result = WadName) then result := e_FindWad(WadDirs, result) end; end; -function CreateTexture(RecName: AnsiString; Map: string; log: Boolean): Integer; +procedure generateExternalResourcesList (map: TDynRecord); +begin + SetLength(gExternalResources, 0); + addResToExternalResList(GetReplacementWad(g_ExtractWadName(map.MusicName))); + addResToExternalResList(GetReplacementWad(g_ExtractWadName(map.SkyName))); +end; + + +function CreateTexture (RecName: AnsiString; Map: string; log: Boolean): Integer; var WAD: TWADFile; TextureData: Pointer; @@ -973,6 +1054,7 @@ begin // Çàãðóæàåì ðåñóðñ òåêñòóðû â ïàìÿòü èç WAD'à: WADName := GetReplacementWad(g_ExtractWadName(RecName)); + if (WADName <> '') then addResToExternalResList(WADName); if WADName = '' then WADName := Map; //WADName := GameDir+'/wads/'+WADName else WAD := TWADFile.Create(); @@ -1059,6 +1141,7 @@ begin // ×èòàåì WAD-ðåñóðñ àíèì.òåêñòóðû èç WAD'à â ïàìÿòü: WADName := GetReplacementWad(g_ExtractWadName(RecName)); + if (WADName <> '') then addResToExternalResList(WADName); if WADName = '' then WADName := Map; //WADName := GameDir+'/wads/'+WADName else WAD := TWADFile.Create(); @@ -1395,7 +1478,7 @@ begin if g_Game_IsClient then Exit; if (gGameSettings.GameType = GT_SINGLE) - or LongBool(gGameSettings.Options and GAME_OPTION_MONSTERS) then + or (TGameOption.MONSTERS in gGameSettings.Options) then begin mon := g_Monsters_Create(monster.MonsterType, monster.X, monster.Y, TDirection(monster.Direction)); @@ -1449,82 +1532,6 @@ begin g_Mons_ForEach(monsDieTrig); end; -function extractWadName(resourceName: string): string; -var - posN: Integer; -begin - posN := Pos(':', resourceName); - if posN > 0 then - Result:= Copy(resourceName, 0, posN-1) - else - Result := ''; -end; - - -procedure addResToExternalResList (res: AnsiString); -var - uname: AnsiString; - f: Integer; - fi: TDiskFileInfo; -begin - if g_Game_IsClient or not g_Game_IsNet then exit; - if (length(res) = 0) then exit; // map wad - res := extractWadName(res); - if (length(res) = 0) then exit; // map wad - uname := toLowerCase1251(res); - // do not add duplicates - for f := 0 to High(gExternalResources) do - begin - if (gExternalResources[f].userName = uname) then exit; - end; - // add new resource - fi.userName := uname; - if (not GetDiskFileInfo(GameDir+'/wads/'+res, fi)) then - begin - fi.tag := -1; - end - else - begin - fi.tag := 0; // non-zero means "cannot caclucate hash" - try - fi.hash := MD5File(fi.diskName); - except - fi.tag := -1; - end; - end; - //e_LogWritefln('addext: res=[%s]; uname=[%s]; diskName=[%s]', [res, fi.userName, fi.diskName]); - SetLength(gExternalResources, length(gExternalResources)+1); - gExternalResources[High(gExternalResources)] := fi; -end; - - -procedure compactExtResList (); -var - src, dest: Integer; -begin - src := 0; - dest := 0; - for src := 0 to High(gExternalResources) do - begin - if (gExternalResources[src].tag = 0) then - begin - // copy it - if (dest <> src) then gExternalResources[dest] := gExternalResources[src]; - Inc(dest); - end; - end; - if (dest <> length(gExternalResources)) then SetLength(gExternalResources, dest); -end; - - -procedure generateExternalResourcesList (map: TDynRecord); -begin - SetLength(gExternalResources, 0); - addResToExternalResList(map.MusicName); - addResToExternalResList(map.SkyName); -end; - - procedure mapCreateGrid (); var mapX0: Integer = $3fffffff; @@ -1840,7 +1847,7 @@ begin cnt := -1; for rec in mapTextureList do begin - Inc(cnt); + cnt += 1; if not usedTextures.has(toLowerCase1251(rec.Resource)) then begin rec.tagInt := -1; // just in case @@ -1852,26 +1859,41 @@ begin e_LogWritefln(' Loading texture #%d: %s', [cnt, rec.Resource]); {$ENDIF} //if g_Map_IsSpecialTexture(s) then e_WriteLog(' SPECIAL!', MSG_NOTIFY); + // TODO: Unify the texture reader - static textures are a special case of dynamic ones, just with only one frame. if rec.Anim then begin // Àíèìèðîâàííàÿ òåêñòóðà ntn := CreateAnimTexture(rec.Resource, FileName, True); - if (ntn < 0) then g_SimpleError(Format(_lc[I_GAME_ERROR_TEXTURE_ANIM], [rec.Resource])); + if (ntn < 0) then + begin + // FIXME: I think, CreateAnimTexture() will load static textures too, just as animated ones with one frame. + ntn := CreateTexture(rec.Resource, FileName, False); + if (ntn < 0) then + g_SimpleError(Format(_lc[I_GAME_ERROR_TEXTURE_ANIM], [rec.Resource])) + else + begin + rec.user['animated'] := False; + e_LogWritefln(' wrong (outdated?) anim flag hint - texture #%d is actually static: %s', [cnt, rec.Resource]); + end; + end; end else begin // Îáû÷íàÿ òåêñòóðà ntn := CreateTexture(rec.Resource, FileName, True); - if (ntn < 0) then g_SimpleError(Format(_lc[I_GAME_ERROR_TEXTURE_SIMPLE], [rec.Resource])); - end; - if (ntn < 0) then - begin - ntn := CreateNullTexture(rec.Resource); - end - else - begin - addResToExternalResList(rec.Resource); + if (ntn < 0) then + begin + ntn := CreateAnimTexture(rec.Resource, FileName, False); + if (ntn < 0) then + g_SimpleError(Format(_lc[I_GAME_ERROR_TEXTURE_SIMPLE], [rec.Resource])) + else + begin + rec.user['animated'] := True; + e_LogWritefln(' wrong (outdated?) anim flag hint - texture #%d is actually animated: %s', [cnt, rec.Resource]); + end; + end; end; + if (ntn < 0) then ntn := CreateNullTexture(rec.Resource); rec.tagInt := ntn; // remember texture number end; @@ -2568,8 +2590,13 @@ begin begin if gFlags[a].Animation <> nil then gFlags[a].Animation.Update(); + Obj.oldX := Obj.X; + Obj.oldY := Obj.Y; + m := g_Obj_Move(@Obj, True, True); + NeedSend := NeedSend or (Obj.X <> Obj.oldX) or (Obj.Y <> Obj.oldY); + if gTime mod (GAME_TICK*2) <> 0 then Continue; // Ñîïðîòèâëåíèå âîçäóõà @@ -3124,6 +3151,14 @@ begin Result := Result + 1; end; +function g_Map_GetRandomPointType(): Byte; +begin + if RespawnPoints = nil then + Result := 255 + else + Result := RespawnPoints[Random(Length(RespawnPoints))].PointType; +end; + function g_Map_HaveFlagPoints(): Boolean; begin Result := (FlagPoints[FLAG_RED] <> nil) and (FlagPoints[FLAG_BLUE] <> nil); @@ -3146,6 +3181,9 @@ begin Direction := FlagPoints[Flag]^.Direction; State := FLAG_STATE_NORMAL; end; + Obj.oldX := Obj.X; + Obj.oldY := Obj.Y; + NeedSend := False; // the event will take care of this Count := -1; end; end; @@ -3153,6 +3191,7 @@ end; procedure g_Map_DrawFlags(); var i, dx: Integer; + tx, ty: Integer; Mirror: TMirrorType; begin if gGameSettings.GameMode <> GM_CTF then @@ -3165,6 +3204,8 @@ begin if State = FLAG_STATE_NONE then continue; + Obj.lerp(gLerpFactor, tx, ty); + if Direction = TDirection.D_LEFT then begin Mirror := TMirrorType.Horizontal; @@ -3176,7 +3217,7 @@ begin dx := 1; end; - Animation.Draw(Obj.X+dx, Obj.Y+1, Mirror); + Animation.Draw(tx+dx, ty+1, Mirror); if g_debug_Frames then begin @@ -3253,9 +3294,9 @@ begin if gGameSettings.GameMode in [GM_TDM, GM_CTF] then begin // Î÷êè Êðàñíîé êîìàíäû - utils.writeInt(st, SmallInt(gTeamStat[TEAM_RED].Goals)); + utils.writeInt(st, SmallInt(gTeamStat[TEAM_RED].Score)); // Î÷êè Ñèíåé êîìàíäû - utils.writeInt(st, SmallInt(gTeamStat[TEAM_BLUE].Goals)); + utils.writeInt(st, SmallInt(gTeamStat[TEAM_BLUE].Score)); end; ///// ///// end; @@ -3345,9 +3386,9 @@ begin if gGameSettings.GameMode in [GM_TDM, GM_CTF] then begin // Î÷êè Êðàñíîé êîìàíäû - gTeamStat[TEAM_RED].Goals := utils.readSmallInt(st); + gTeamStat[TEAM_RED].Score := utils.readSmallInt(st); // Î÷êè Ñèíåé êîìàíäû - gTeamStat[TEAM_BLUE].Goals := utils.readSmallInt(st); + gTeamStat[TEAM_BLUE].Score := utils.readSmallInt(st); end; ///// ///// end;